ambient-orb 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MzNhZjNlNGY3MDc5ZTA0YTNjMTZkM2Y4Yjc1M2U3MGRhYWMzMzQyYw==
5
+ data.tar.gz: !binary |-
6
+ ODhlYTcyNTM2NGYwNjBlOTgzMmNiNDQyNjc4OTEyMTNjYjc1MWIyYQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ ZGNiN2IwNTkwNGFkNWE2MmM1MDQ3Njk0MTFjOTY1MjZlNjg0Y2EzNjg4MTJl
10
+ NDNlM2MxNjVmYzhjYzkzNGFkZGM1NzgxZDUzMzQ0YjBlMDY2Y2M2NmE5Zjcw
11
+ ZjcwN2UzMzJiOGVhZWNkM2FhY2M0Nzg2MjQ2ZTViOGUzZmFhYzE=
12
+ data.tar.gz: !binary |-
13
+ NmZjNDRlZmZmNGExMjBjNTZhODQ0MGUyMGMzNjIwNTcxNzU1MWUzY2JiNmM3
14
+ NWI2MDc0OGVhYzlkZDU3NGMxMDIyMGYzODVkNDk2OWU5YTA2MzIyZWM5ZDVm
15
+ NmJiMjI5YWNmY2EzNzI3N2YyYWQ3M2VjMWNiOGUzYTczYTdkNDA=
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ Gemfile.lock
3
+ .rvmrc
4
+ .DS_Store
5
+ /coverage
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ group :test do
5
+ gem 'rspec', '~> 3.4.0'
6
+ gem 'rspec-instafail', '~> 0.4'
7
+ gem 'simplecov', :require => false
8
+ end
@@ -0,0 +1,31 @@
1
+ AmbientOrb
2
+ ===========
3
+
4
+ Ruby code to interface with ambientdevices Ambient Orb. Only supports the
5
+ serial interface as ambientdevices' service no longer exists.
6
+
7
+ ```ruby
8
+ require 'ambient-orb'
9
+
10
+ # device is automatically detected on OS X
11
+ orb = AmbientOrb.new
12
+
13
+ # a device can be passed manually
14
+ #orb = AmbientOrb.new(:device => '/dev/ttyS0')
15
+
16
+ # a logger can also be passed
17
+ #orb = AmbientOrb.new(:logger => Logger.new(STDOUT))
18
+ #orb.logger.level = Logger::DEBUG
19
+
20
+ [
21
+ [ AmbientOrb::COLOR_GREEN, AmbientOrb::ANIMATION_VERY_SLOW ],
22
+ [ AmbientOrb::COLOR_BLUE, AmbientOrb::ANIMATION_SLOW ],
23
+ [ AmbientOrb::COLOR_PURPLE, AmbientOrb::ANIMATION_MEDIUM_SLOW ],
24
+ [ AmbientOrb::COLOR_YELLOW, AmbientOrb::ANIMATION_MEDIUM ],
25
+ [ AmbientOrb::COLOR_ORANGE, AmbientOrb::ANIMATION_FAST ],
26
+ [ AmbientOrb::COLOR_RED, AmbientOrb::ANIMATION_VERY_FAST ],
27
+ ].each do |(color, animation)|
28
+ orb.update(color, animation)
29
+ sleep(10)
30
+ end
31
+ ```
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require 'ambient-orb/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "ambient-orb"
8
+ s.version = AmbientOrb::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Jon Tai"]
11
+ s.email = ["jon.tai@gmail.com"]
12
+ s.homepage = "https://github.com/jtai/ambient-orb"
13
+ s.summary = "Ruby code to interface with ambientdevices Ambient Orb"
14
+ s.description = "Only supports the serial interface as ambientdevices' service no longer exists"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- spec/*`.split("\n")
18
+ s.require_path = 'lib'
19
+
20
+ s.add_runtime_dependency 'serialport', '>= 1.3.1'
21
+ end
@@ -0,0 +1,101 @@
1
+ require 'ambient-orb/version'
2
+ require 'logger'
3
+ require 'serialport'
4
+
5
+ class AmbientOrb
6
+
7
+ # These are fixed characteristics of the orb.
8
+ SERIAL_PORT_BAUD_RATE = 19200
9
+ SERIAL_PORT_DATA_BITS = 8
10
+ SERIAL_PORT_STOP_BITS = 1
11
+ SERIAL_PORT_PARITY = SerialPort::NONE
12
+
13
+ # Colors are specified as an integer from 0 to 36, inclusive. Common colors
14
+ # are assigned constants for convenience.
15
+ COLOR_RED = 0
16
+ COLOR_ORANGE = 3
17
+ COLOR_YELLOW = 6
18
+ COLOR_GREEN = 12
19
+ COLOR_BLUE = 24
20
+ COLOR_PURPLE = 27
21
+
22
+ # Animation is specified as an integer from 0 to 9, inclusive.
23
+ ANIMATION_NONE = 0
24
+ ANIMATION_VERY_SLOW = 1
25
+ ANIMATION_SLOW = 2
26
+ ANIMATION_MEDIUM_SLOW = 3
27
+ ANIMATION_MEDIUM = 4
28
+ ANIMATION_MEDIUM_FAST = 5
29
+ ANIMATION_FAST = 6
30
+ ANIMATION_VERY_FAST = 7
31
+ ANIMATION_CRESCENDO = 8
32
+ ANIMATION_HEARTBEAT = 9
33
+
34
+ def initialize(options = {})
35
+ @opts = options
36
+ end
37
+
38
+ def device
39
+ @device ||= begin
40
+ dev = @opts[:device] || autodetect_device
41
+
42
+ unless dev && File.exist?(dev) && File.stat(dev).chardev?
43
+ raise ArgumentError, 'invalid device'
44
+ end
45
+
46
+ logger.info("selected device #{dev}")
47
+
48
+ dev
49
+ end
50
+ end
51
+
52
+ def logger
53
+ @logger ||= begin
54
+ @opts[:logger] || Logger.new(nil)
55
+ end
56
+ end
57
+
58
+ def update(color, animation)
59
+ if (color < 0 || color > 36)
60
+ raise ArgumentError, 'color must be between 0 and 36'
61
+ end
62
+
63
+ if (animation < 0 || animation > 9)
64
+ raise ArgumentError, 'animation must be between 0 and 9'
65
+ end
66
+
67
+ logger.info("updating with color=#{color}, animation=#{animation}")
68
+
69
+ color_ord = (color + (37 * animation)) / 94 + 32
70
+ animation_ord = (color + (37 * animation)) % 94 + 32
71
+
72
+ send("~A#{color_ord.chr}#{animation_ord.chr}")
73
+ end
74
+
75
+ private
76
+
77
+ def autodetect_device
78
+ devices = Dir.glob('/dev/*.usbmodem*')
79
+
80
+ devices.each do |dev|
81
+ logger.debug("autodetect_device found #{dev}")
82
+ end
83
+
84
+ devices.first
85
+ end
86
+
87
+ def send(command)
88
+ SerialPort.open(device,
89
+ SERIAL_PORT_BAUD_RATE,
90
+ SERIAL_PORT_DATA_BITS,
91
+ SERIAL_PORT_STOP_BITS,
92
+ SERIAL_PORT_PARITY) do |serial_port|
93
+ logger.debug('send "~GT"')
94
+ serial_port.puts '~GT'
95
+
96
+ logger.debug("send \"#{command}\"")
97
+ serial_port.puts command
98
+ end
99
+ end
100
+
101
+ end
@@ -0,0 +1,3 @@
1
+ class AmbientOrb
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+
3
+ describe AmbientOrb do
4
+
5
+ let (:options) { {} }
6
+ let (:orb) { AmbientOrb.new(options) }
7
+
8
+ describe '#device' do
9
+
10
+ context 'with valid device option' do
11
+ let (:options) { { :device => '/dev/zero' } }
12
+
13
+ it 'returns device' do
14
+ expect(orb.device).to eq('/dev/zero')
15
+ end
16
+ end
17
+
18
+ context 'with non-existent device' do
19
+ let (:options) { { :device => '/dev/nosuchdevice' } }
20
+
21
+ it 'raises ArgumentError' do
22
+ expect {
23
+ orb.device
24
+ }.to raise_error(ArgumentError)
25
+ end
26
+ end
27
+
28
+ context 'with block device' do
29
+ let (:options) { { :device => `df #{__FILE__} | tail -1 | cut -d ' ' -f 1` } }
30
+
31
+ it 'raises ArgumentError' do
32
+ expect {
33
+ orb.device
34
+ }.to raise_error(ArgumentError)
35
+ end
36
+ end
37
+
38
+ context 'with autodetected device' do
39
+ it 'returns first device matching pattern' do
40
+ expect(Dir).to receive(:glob).and_return(['/dev/urandom', '/dev/random'])
41
+ expect(orb.device).to eq('/dev/urandom')
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ describe '#update' do
48
+
49
+ let (:color) { AmbientOrb::COLOR_RED }
50
+ let (:animation) { AmbientOrb::ANIMATION_NONE }
51
+
52
+ context 'with out of range color' do
53
+ let (:color) { 37 }
54
+
55
+ it 'raises ArgumentError' do
56
+ expect {
57
+ orb.update(color, animation)
58
+ }.to raise_error(ArgumentError)
59
+ end
60
+ end
61
+
62
+ context 'with out of range animation' do
63
+ let (:animation) { 10 }
64
+
65
+ it 'raises ArgumentError' do
66
+ expect {
67
+ orb.update(color, animation)
68
+ }.to raise_error(ArgumentError)
69
+ end
70
+ end
71
+
72
+ context 'with valid arguments' do
73
+ it 'sends correct update' do
74
+ expect(orb).to receive(:send).with('~A ')
75
+ orb.update(color, animation)
76
+ end
77
+ end
78
+
79
+ context 'with purple color' do
80
+ let (:color) { AmbientOrb::COLOR_PURPLE }
81
+
82
+ it 'sends correct update' do
83
+ expect(orb).to receive(:send).with('~A ;')
84
+ orb.update(color, animation)
85
+ end
86
+ end
87
+
88
+ context 'with fast animation' do
89
+ let (:animation) { AmbientOrb::ANIMATION_FAST }
90
+
91
+ it 'sends correct update' do
92
+ expect(orb).to receive(:send).with('~A"B')
93
+ orb.update(color, animation)
94
+ end
95
+ end
96
+
97
+ end
98
+
99
+ describe '#send' do
100
+
101
+ let (:options) { { :device => '/dev/zero' } }
102
+ let (:io) { IO.new }
103
+
104
+ it 'sends commands' do
105
+ io = double('serial_port')
106
+ expect(io).to receive(:puts).with('~GT')
107
+ expect(io).to receive(:puts).with('~A ')
108
+ expect(SerialPort).to receive(:open).and_yield(io)
109
+ orb.update(AmbientOrb::COLOR_RED, AmbientOrb::ANIMATION_NONE)
110
+ end
111
+
112
+ end
113
+
114
+ end
@@ -0,0 +1,13 @@
1
+ require 'simplecov'
2
+
3
+ SimpleCov.start do
4
+ add_filter 'spec'
5
+ end
6
+
7
+ SimpleCov.use_merging false
8
+
9
+ require 'ambient-orb'
10
+
11
+ RSpec.configure do |config|
12
+ config.color = true
13
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ambient-orb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jon Tai
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: serialport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.3.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.3.1
27
+ description: Only supports the serial interface as ambientdevices' service no longer
28
+ exists
29
+ email:
30
+ - jon.tai@gmail.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - .gitignore
36
+ - Gemfile
37
+ - README.md
38
+ - ambient-orb.gemspec
39
+ - lib/ambient-orb.rb
40
+ - lib/ambient-orb/version.rb
41
+ - spec/lib/ambient-orb_spec.rb
42
+ - spec/spec_helper.rb
43
+ homepage: https://github.com/jtai/ambient-orb
44
+ licenses: []
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 2.0.0
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: Ruby code to interface with ambientdevices Ambient Orb
66
+ test_files:
67
+ - spec/lib/ambient-orb_spec.rb
68
+ - spec/spec_helper.rb