open_lighting 0.0.2 → 0.1.0
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.
- data/.gitignore +1 -0
- data/lib/open_lighting/devices/comscan_led.rb +8 -0
- data/lib/open_lighting/dmx_controller.rb +41 -12
- data/lib/open_lighting/dmx_device.rb +32 -12
- data/lib/open_lighting/version.rb +1 -1
- data/spec/open_lighting/dmx_controller_spec.rb +36 -7
- data/spec/open_lighting/dmx_device_spec.rb +13 -8
- data/spec/spec_helper.rb +3 -1
- metadata +3 -3
data/.gitignore
CHANGED
@@ -7,13 +7,17 @@ module OpenLighting
|
|
7
7
|
def initialize(options = {})
|
8
8
|
options[:points] ||= {}
|
9
9
|
options[:points][:center] ||= {:pan => 127, :tilt => 127}
|
10
|
+
options[:points][:origin] ||= {:pan => 127, :tilt => 127, :strobe => 8, :gobo => 0, :dimmer => 0}
|
10
11
|
|
12
|
+
options[:points][:strobe_blackout] ||= {:strobe => 0}
|
13
|
+
options[:points][:strobe_open] ||= {:strobe => 8}
|
11
14
|
options[:points][:strobe_slow] ||= {:strobe => 16}
|
12
15
|
options[:points][:strobe_fast] ||= {:strobe => 131}
|
13
16
|
options[:points][:strobe_slow_fast] ||= {:strobe => 140}
|
14
17
|
options[:points][:strobe_fast_slow] ||= {:strobe => 190}
|
15
18
|
options[:points][:strobe_random] ||= {:strobe => 247}
|
16
19
|
|
20
|
+
options[:points][:nocolor] ||= {:gobo => 0}
|
17
21
|
options[:points][:yellow] ||= {:gobo => 8}
|
18
22
|
options[:points][:red] ||= {:gobo => 15}
|
19
23
|
options[:points][:green] ||= {:gobo => 22}
|
@@ -23,7 +27,11 @@ module OpenLighting
|
|
23
27
|
options[:points][:teal] ||= {:gobo => 50}
|
24
28
|
options[:points][:rings] ||= {:gobo => 57}
|
25
29
|
|
30
|
+
options[:points][:on] ||= {:dimmer => 255}
|
31
|
+
options[:points][:off] ||= {:dimmer => 0}
|
32
|
+
|
26
33
|
options[:capabilities] ||= [:pan, :tilt, :strobe, :gobo, :dimmer]
|
34
|
+
options[:defaults] ||= {:pan => 127, :tilt => 127, :strobe => 8, :gobo => 0, :dimmer => 0}
|
27
35
|
|
28
36
|
super(options)
|
29
37
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
1
3
|
module OpenLighting
|
2
4
|
# The DmxController class is responsible for sending control messages across
|
3
5
|
# the DMX bus.
|
@@ -7,7 +9,7 @@ module OpenLighting
|
|
7
9
|
# control signal. The DmxController class is responsible for aggregating this
|
8
10
|
# information from the DmxDevice instances and sending it down the bus.
|
9
11
|
class DmxController
|
10
|
-
attr_accessor :fps, :devices, :universe, :cmd, :read_pipe, :write_pipe, :
|
12
|
+
attr_accessor :fps, :devices, :universe, :cmd, :read_pipe, :write_pipe, :do_not_sleep
|
11
13
|
def initialize(options = {})
|
12
14
|
@devices = []
|
13
15
|
(options[:devices] || []).each {|dev| @devices << dev}
|
@@ -16,11 +18,15 @@ module OpenLighting
|
|
16
18
|
self.cmd = options[:cmd] || "ola_streaming_client -u #{universe}"
|
17
19
|
|
18
20
|
if options[:test]
|
19
|
-
self.
|
20
|
-
self.
|
21
|
+
self.do_not_sleep = true
|
22
|
+
self.connect_test_pipe
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
26
|
+
def connect_test_pipe
|
27
|
+
self.read_pipe, self.write_pipe = IO.pipe
|
28
|
+
end
|
29
|
+
|
24
30
|
def devices
|
25
31
|
@devices
|
26
32
|
end
|
@@ -32,7 +38,11 @@ module OpenLighting
|
|
32
38
|
end
|
33
39
|
|
34
40
|
def set(options = {})
|
35
|
-
|
41
|
+
warn "[DEPRECATION] `set` is deprecated. Use `buffer` instead."
|
42
|
+
end
|
43
|
+
|
44
|
+
def buffer(options = {})
|
45
|
+
@devices.each {|device| device.buffer(options.dup)}
|
36
46
|
end
|
37
47
|
|
38
48
|
def write!(values=current_values)
|
@@ -51,7 +61,7 @@ module OpenLighting
|
|
51
61
|
end
|
52
62
|
|
53
63
|
def instant!(options = {})
|
54
|
-
|
64
|
+
buffer(options)
|
55
65
|
write!
|
56
66
|
end
|
57
67
|
|
@@ -77,15 +87,21 @@ module OpenLighting
|
|
77
87
|
1.0 / self.fps.to_f
|
78
88
|
end
|
79
89
|
|
80
|
-
def transition!(options = {})
|
90
|
+
def transition!(options = {}, &block)
|
91
|
+
warn "[DEPRECATION] `transition!` is deprecated. Use `begin_animation!` instead."
|
92
|
+
end
|
93
|
+
|
94
|
+
def begin_animation!(options = {}, &block)
|
81
95
|
previous = current_values
|
82
|
-
|
83
|
-
|
96
|
+
buffer(options)
|
97
|
+
|
98
|
+
block.call(@devices) if block
|
84
99
|
|
100
|
+
count = ticks(options[:seconds])
|
85
101
|
count.times do |i|
|
86
102
|
# interpolate previous to current
|
87
103
|
write! interpolate(previous, current_values, count, i+1)
|
88
|
-
sleep(wait_time) unless self.
|
104
|
+
sleep(wait_time) unless self.do_not_sleep
|
89
105
|
end
|
90
106
|
end
|
91
107
|
|
@@ -98,12 +114,25 @@ module OpenLighting
|
|
98
114
|
end
|
99
115
|
|
100
116
|
def capabilities
|
101
|
-
@devices.map{|device| device.capabilities
|
117
|
+
@devices.map{|device| device.capabilities}.flatten.uniq
|
118
|
+
end
|
119
|
+
|
120
|
+
def points
|
121
|
+
@devices.map{|device| device.points.keys}.flatten.uniq
|
102
122
|
end
|
103
123
|
|
104
124
|
def method_missing(meth, *args, &block)
|
105
|
-
|
106
|
-
|
125
|
+
meth_without_bang = meth.to_s.gsub(/!\Z/, "").to_sym
|
126
|
+
|
127
|
+
if points.include? meth
|
128
|
+
buffer :point => meth
|
129
|
+
elsif points.include? meth_without_bang
|
130
|
+
# causes controller.center! to convert to controller.instant!(:point => :center)
|
131
|
+
instant! :point => meth_without_bang
|
132
|
+
elsif capabilities.include? meth
|
133
|
+
buffer meth => args
|
134
|
+
elsif capabilities.include? meth_without_bang
|
135
|
+
instant! meth_without_bang => args.first
|
107
136
|
else
|
108
137
|
super # You *must* call super if you don't handle the
|
109
138
|
# method, otherwise you'll mess up Ruby's method
|
@@ -9,17 +9,22 @@ module OpenLighting
|
|
9
9
|
attr_accessor :controller, :start_address, :capabilities, :points, :current_values, :defaults
|
10
10
|
def initialize(options = {})
|
11
11
|
self.start_address = options[:start_address]
|
12
|
-
self.capabilities = options[:capabilities]
|
12
|
+
self.capabilities = (options[:capabilities] || []).map{|i| i.to_sym}
|
13
13
|
self.defaults = options[:defaults] || {}
|
14
14
|
self.current_values = capabilities.map{|c| defaults[c] || 0 }
|
15
15
|
self.points = options[:points] || {}
|
16
16
|
end
|
17
17
|
|
18
18
|
def set(options)
|
19
|
+
warn "[DEPRECATION] `set` is deprecated. Use `buffer` instead."
|
20
|
+
buffer(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def buffer(options)
|
19
24
|
return if options.nil?
|
20
25
|
|
21
26
|
if pt = options.delete(:point)
|
22
|
-
|
27
|
+
buffer points[pt]
|
23
28
|
end
|
24
29
|
|
25
30
|
capabilities.each_with_index do |c, i|
|
@@ -30,24 +35,39 @@ module OpenLighting
|
|
30
35
|
end
|
31
36
|
|
32
37
|
def point(key)
|
33
|
-
# d { key }
|
34
|
-
# d { self.points }
|
35
|
-
|
36
38
|
self.points[key]
|
37
39
|
end
|
38
40
|
|
41
|
+
def add_points(options)
|
42
|
+
options ||= {}
|
43
|
+
options.values.each{|opt| opt.symbolize_keys!}
|
44
|
+
self.points.merge!(options.symbolize_keys!)
|
45
|
+
end
|
46
|
+
|
39
47
|
def to_dmx
|
40
48
|
current_values.join ","
|
41
49
|
end
|
42
50
|
|
43
51
|
def method_missing(meth, *args, &block)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
52
|
+
if points[meth]
|
53
|
+
buffer points[meth]
|
54
|
+
elsif capabilities.include? meth
|
55
|
+
buffer meth => args.first
|
56
|
+
else
|
57
|
+
super # You *must* call super if you don't handle the
|
58
|
+
# method, otherwise you'll mess up Ruby's method
|
59
|
+
# lookup.
|
51
60
|
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Hash
|
66
|
+
def symbolize_keys!
|
67
|
+
keys.each do |key|
|
68
|
+
self[(key.to_sym rescue key) || key] = delete(key)
|
69
|
+
end
|
70
|
+
self
|
52
71
|
end
|
53
72
|
end
|
73
|
+
|
@@ -17,6 +17,7 @@ module OpenLighting
|
|
17
17
|
c.cmd.should == "ola_streaming_client -u 2"
|
18
18
|
end
|
19
19
|
end
|
20
|
+
|
20
21
|
context 'given updated values' do
|
21
22
|
it 'updates fps value' do
|
22
23
|
c = DmxController.new(:fps => 20)
|
@@ -74,14 +75,18 @@ module OpenLighting
|
|
74
75
|
end
|
75
76
|
|
76
77
|
it "should report correct capabilities" do
|
77
|
-
@controller.capabilities.should == [:pan, :tilt, :dimmer
|
78
|
+
@controller.capabilities.should == [:pan, :tilt, :dimmer]
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should report correct points" do
|
82
|
+
@controller.points.should == [:center]
|
78
83
|
end
|
79
84
|
|
80
85
|
it "should serialize all DmxDevices" do
|
81
86
|
@controller.to_dmx.should == "0,0,0,0,0,0"
|
82
|
-
@controller.
|
87
|
+
@controller.buffer(:pan => 255)
|
83
88
|
@controller.to_dmx.should == "255,0,0,255,0,0"
|
84
|
-
@controller.
|
89
|
+
@controller.buffer(:point => :center)
|
85
90
|
@controller.to_dmx.should == "127,127,0,127,127,0"
|
86
91
|
end
|
87
92
|
|
@@ -89,6 +94,17 @@ module OpenLighting
|
|
89
94
|
@controller.to_dmx.should == "0,0,0,0,0,0"
|
90
95
|
@controller.center
|
91
96
|
@controller.to_dmx.should == "127,127,0,127,127,0"
|
97
|
+
@controller.dimmer(80)
|
98
|
+
@controller.to_dmx.should == "127,127,80,127,127,80"
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should do method_missing magics" do
|
102
|
+
@controller.connect_test_pipe
|
103
|
+
@controller.center!
|
104
|
+
@controller.read_pipe.gets.should == "127,127,0,127,127,0\n"
|
105
|
+
@controller.dimmer!(80)
|
106
|
+
@controller.read_pipe.gets.should == "127,127,80,127,127,80\n"
|
107
|
+
@controller.close!
|
92
108
|
end
|
93
109
|
|
94
110
|
it "but not for incorrect names" do
|
@@ -97,13 +113,13 @@ module OpenLighting
|
|
97
113
|
|
98
114
|
it "should honor overlapping start_address" do
|
99
115
|
@controller << DmxDevice.new(:start_address => 5, :capabilities => [:pan, :tilt, :dimmer])
|
100
|
-
@controller.
|
116
|
+
@controller.buffer(:pan => 127)
|
101
117
|
@controller.to_dmx.should == "127,0,0,127,127,0,0"
|
102
118
|
end
|
103
119
|
|
104
120
|
it "should insert zeros for missing data points" do
|
105
121
|
@controller << DmxDevice.new(:start_address => 9, :capabilities => [:pan, :tilt, :dimmer])
|
106
|
-
@controller.
|
122
|
+
@controller.buffer(:pan => 127)
|
107
123
|
@controller.to_dmx.should == "127,0,0,127,0,0,0,0,127,0,0"
|
108
124
|
end
|
109
125
|
end
|
@@ -163,7 +179,7 @@ module OpenLighting
|
|
163
179
|
end
|
164
180
|
end
|
165
181
|
|
166
|
-
describe ".
|
182
|
+
describe ".begin_animation!" do
|
167
183
|
before(:each) do
|
168
184
|
@controller = DmxController.new(:fps => 1, :test => true)
|
169
185
|
@controller << DmxDevice.new(:start_address => 1, :capabilities => [:pan, :tilt, :dimmer])
|
@@ -171,7 +187,7 @@ module OpenLighting
|
|
171
187
|
end
|
172
188
|
|
173
189
|
it "should write interpolated values to the pipe" do
|
174
|
-
@controller.
|
190
|
+
@controller.begin_animation!(:seconds => 5, :pan => 25)
|
175
191
|
@controller.read_pipe.gets.should == "5,0,0,5,0,0\n"
|
176
192
|
@controller.read_pipe.gets.should == "10,0,0,10,0,0\n"
|
177
193
|
@controller.read_pipe.gets.should == "15,0,0,15,0,0\n"
|
@@ -179,6 +195,19 @@ module OpenLighting
|
|
179
195
|
@controller.read_pipe.gets.should == "25,0,0,25,0,0\n"
|
180
196
|
@controller.write_pipe.close
|
181
197
|
end
|
198
|
+
|
199
|
+
it "should allow block syntax" do
|
200
|
+
@controller.begin_animation!(:seconds => 5) do |devices|
|
201
|
+
devices[0].pan(25)
|
202
|
+
devices[1].pan(50)
|
203
|
+
end
|
204
|
+
@controller.read_pipe.gets.should == "5,0,0,10,0,0\n"
|
205
|
+
@controller.read_pipe.gets.should == "10,0,0,20,0,0\n"
|
206
|
+
@controller.read_pipe.gets.should == "15,0,0,30,0,0\n"
|
207
|
+
@controller.read_pipe.gets.should == "20,0,0,40,0,0\n"
|
208
|
+
@controller.read_pipe.gets.should == "25,0,0,50,0,0\n"
|
209
|
+
@controller.write_pipe.close
|
210
|
+
end
|
182
211
|
end
|
183
212
|
end
|
184
213
|
end
|
@@ -36,7 +36,7 @@ module OpenLighting
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
context ".
|
39
|
+
context ".buffer" do
|
40
40
|
before(:each) do
|
41
41
|
@device = DmxDevice.new(:capabilities => [:pan, :tilt, :dimmer])
|
42
42
|
end
|
@@ -44,7 +44,7 @@ module OpenLighting
|
|
44
44
|
context "when setting correct capabilities" do
|
45
45
|
it "should update current_values" do
|
46
46
|
@device.current_values.should == [0, 0, 0]
|
47
|
-
@device.
|
47
|
+
@device.buffer(:pan => 127)
|
48
48
|
@device.current_values.should == [127, 0, 0]
|
49
49
|
end
|
50
50
|
end
|
@@ -52,7 +52,7 @@ module OpenLighting
|
|
52
52
|
context "when setting incorrect capabilities" do
|
53
53
|
it "should not update current_values" do
|
54
54
|
@device.current_values.should == [0, 0, 0]
|
55
|
-
@device.
|
55
|
+
@device.buffer(:some_junk => 127)
|
56
56
|
@device.current_values.should == [0, 0, 0]
|
57
57
|
end
|
58
58
|
end
|
@@ -62,7 +62,7 @@ module OpenLighting
|
|
62
62
|
it "should make comma laden magics" do
|
63
63
|
@device = DmxDevice.new(:capabilities => [:pan, :tilt, :dimmer])
|
64
64
|
@device.to_dmx.should == "0,0,0"
|
65
|
-
@device.
|
65
|
+
@device.buffer(:pan => 127)
|
66
66
|
@device.to_dmx.should == "127,0,0"
|
67
67
|
end
|
68
68
|
end
|
@@ -87,12 +87,17 @@ module OpenLighting
|
|
87
87
|
|
88
88
|
context "when setting a point" do
|
89
89
|
it "should fail silently for incorrect point" do
|
90
|
-
@device.
|
90
|
+
@device.buffer(:point => :off)
|
91
91
|
@device.current_values.should == [0, 0, 0]
|
92
92
|
end
|
93
93
|
|
94
94
|
it "should update current_values" do
|
95
|
-
@device.
|
95
|
+
@device.buffer(:point => :center)
|
96
|
+
@device.current_values.should == [127, 127, 0]
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should do method_missing magics" do
|
100
|
+
@device.center
|
96
101
|
@device.current_values.should == [127, 127, 0]
|
97
102
|
end
|
98
103
|
|
@@ -108,8 +113,8 @@ module OpenLighting
|
|
108
113
|
|
109
114
|
context "when setting multiple points" do
|
110
115
|
it "should update current_values" do
|
111
|
-
@device.
|
112
|
-
@device.
|
116
|
+
@device.buffer(:point => :center)
|
117
|
+
@device.buffer(:point => :on)
|
113
118
|
@device.current_values.should == [127, 127, 255]
|
114
119
|
end
|
115
120
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: open_lighting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: simplecov
|
@@ -152,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
152
152
|
version: '0'
|
153
153
|
requirements: []
|
154
154
|
rubyforge_project:
|
155
|
-
rubygems_version: 1.8.
|
155
|
+
rubygems_version: 1.8.23
|
156
156
|
signing_key:
|
157
157
|
specification_version: 3
|
158
158
|
summary: A ruby gem wrapper for the Open Lighting Architecture project
|