open_lighting 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ vendor
@@ -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, :test_mode
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.test_mode = true
20
- self.read_pipe, self.write_pipe = IO.pipe
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
- @devices.each {|device| device.set(options.dup)}
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
- set(options)
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
- set(options)
83
- count = ticks(options[:seconds])
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.test_mode==true
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 + device.points.keys}.flatten.uniq
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
- if capabilities.include? meth.to_sym
106
- set :point => meth.to_sym
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
- set points[pt]
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
- if points[meth.to_sym]
45
- set points[meth.to_sym]
46
- else
47
- super # You *must* call super if you don't handle the
48
- # method, otherwise you'll mess up Ruby's method
49
- # lookup.
50
- end
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
+
@@ -1,3 +1,3 @@
1
1
  module OpenLighting
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -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, :center]
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.set(:pan => 255)
87
+ @controller.buffer(:pan => 255)
83
88
  @controller.to_dmx.should == "255,0,0,255,0,0"
84
- @controller.set(:point => :center)
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.set(:pan => 127)
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.set(:pan => 127)
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 ".transition!" do
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.transition!(:seconds => 5, :pan => 25)
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 ".set" do
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.set(:pan => 127)
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.set(:some_junk => 127)
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.set(:pan => 127)
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.set(:point => :off)
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.set(:point => :center)
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.set(:point => :center)
112
- @device.set(:point => :on)
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
@@ -3,7 +3,9 @@ Bundler.setup
3
3
 
4
4
  if RUBY_VERSION.to_f == 1.9
5
5
  require 'simplecov'
6
- SimpleCov.start
6
+ SimpleCov.start do
7
+ add_filter "vendor"
8
+ end
7
9
  end
8
10
 
9
11
  require "open_lighting"
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.2
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-27 00:00:00.000000000 Z
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.24
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