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 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