lifx 0.4.8 → 0.4.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c4d3a3b49f4182b136607335b3439a6d8c475af4
4
- data.tar.gz: 5119e5d44ca2c1649a9f4226678dc1c3c04900c3
3
+ metadata.gz: 86bc4e0b28d94c9b3d1d0bf22b5f550988c5cab3
4
+ data.tar.gz: ffc2b6c71d1f4efd5a6bd9732403599b6b357c69
5
5
  SHA512:
6
- metadata.gz: 76282a8c2b04cf4f0c0b199532d2847b97eacf7f8313c246c9aedafbf1cf6d35b02d9c75e75d472bb4f41a278988b92aae63cace417e5902a9e84095161f62f2
7
- data.tar.gz: 0b81b9d0165ce833a8436bb597a5f6398ebf4cebee892f02116a6af9a7450b851c782639c9c077b8672bd3b836cf1f6be03e7dfb219ca02f3255165b12311355
6
+ metadata.gz: f580ff26c0612fa04dff785c06f770b0bcbd262c463f826dc0795e2339ed61d5ef28a0bd13563b592b636e6ad57086a0d2702147b4b07430a7c910550ea91fc5
7
+ data.tar.gz: b6a20e239ac5a9b97fc2f8fad4f794937438b6b07439aabcb4c9bf28295b3eec5c3c8b35c973cb023f4a0c787a3ea2f0e8f811fb10b09f10690895b2aa025b0a
data/CHANGES.md CHANGED
@@ -1,3 +1,12 @@
1
+ ### 0.4.10
2
+
3
+ - Fix `message_rate` visibility bug
4
+
5
+ ### 0.4.9
6
+
7
+ - Message rate checker only runs when connection is idle
8
+ - Now uses `LIFX::TimeoutError` rather than `Timeout::Error` for internal timeout exceptions
9
+
1
10
  ### 0.4.8
2
11
 
3
12
  - Routing table is only updated from State messages
data/Rakefile CHANGED
@@ -7,6 +7,7 @@ end
7
7
  task :default => :spec
8
8
 
9
9
  task :console do
10
+ $LOAD_PATH << "lib"
10
11
  require "lifx"
11
12
  require "pry"
12
13
  if ENV['DEBUG']
@@ -20,4 +20,6 @@ require "lifx/client"
20
20
 
21
21
  module LIFX
22
22
  NULL_SITE_ID = "000000000000"
23
+
24
+ class TimeoutError < StandardError; end
23
25
  end
@@ -39,13 +39,13 @@ module LIFX
39
39
  @context.discover
40
40
  end
41
41
 
42
- class DiscoveryTimeout < Timeout::Error; end
42
+ class DiscoveryTimeout < TimeoutError; end
43
43
  # This method tells the {NetworkContext} to look for devices, and will block
44
44
  # until there's at least one device.
45
45
  #
46
46
  # @example Wait until at least three lights have been found
47
47
  # client.discover! { |c| c.lights.count >= 3 }
48
- #
48
+ #
49
49
  # @param timeout: [Numeric] How long to try to wait for before returning
50
50
  # @param condition_interval: [Numeric] Seconds between evaluating the block
51
51
  # @yield [Client] This block is evaluated every `condition_interval` seconds. If true, method returns. If no block is supplied, it will block until it finds at least one light.
@@ -75,7 +75,7 @@ module LIFX
75
75
  #
76
76
  # You cannot nest `sync` calls, nor call synchronous methods inside a `sync` block.
77
77
  #
78
- # Due to messaging rate constraints, the amount of messages determine the delay before
78
+ # Due to messaging rate constraints, the amount of messages determine the delay before
79
79
  # the commands are executed. This method also assumes all the lights have the same time.
80
80
  # @example This example sets all the lights to a random colour at the same time.
81
81
  # client.sync do
@@ -128,7 +128,7 @@ module LIFX
128
128
 
129
129
  # Blocks until all messages have been sent to the gateways
130
130
  # @param timeout: [Numeric] When specified, flush will wait `timeout:` seconds before throwing `Timeout::Error`
131
- # @raise [Timeout::Error] if `timeout:` was exceeded while waiting for send queue to flush
131
+ # @raise [TimeoutError] if `timeout:` was exceeded while waiting for send queue to flush
132
132
  # @return [void]
133
133
  def flush(timeout: nil)
134
134
  context.flush(timeout: timeout)
@@ -90,7 +90,7 @@ module LIFX
90
90
  end
91
91
  end
92
92
  if timeout
93
- Timeout.timeout(timeout) do
93
+ Timeout.timeout(timeout, TimeoutError) do
94
94
  proc.call
95
95
  end
96
96
  else
@@ -332,6 +332,12 @@ module LIFX
332
332
  context.tags_for_device(self)
333
333
  end
334
334
 
335
+ # Returns whether the light is a gateway
336
+ # @api private
337
+ def gateway?
338
+ context.transport_manager.gateways.include?(self)
339
+ end
340
+
335
341
  # Returns a nice string representation of the Light
336
342
  # @return [String]
337
343
  def to_s
@@ -356,7 +362,9 @@ module LIFX
356
362
  end
357
363
 
358
364
  # An exception for when synchronous messages take too long to receive a response
359
- class MessageTimeout < StandardError; end
365
+ class MessageTimeout < TimeoutError
366
+ attr_accessor :device
367
+ end
360
368
 
361
369
  # Queues a message to be sent to the Light and waits for a response
362
370
  # @param payload [Protocol::Payload] the payload to send
@@ -381,10 +389,11 @@ module LIFX
381
389
  send_message(payload)
382
390
  end
383
391
  result
384
- rescue Timeout::Error
392
+ rescue TimeoutError
385
393
  backtrace = caller_locations(2).map { |c| c.to_s }
386
394
  caller_method = caller_locations(2, 1).first.label
387
395
  ex = MessageTimeout.new("#{caller_method}: Timeout exceeded waiting for response from #{self}")
396
+ ex.device = self
388
397
  ex.set_backtrace(backtrace)
389
398
  raise ex
390
399
  ensure
@@ -41,7 +41,7 @@ module LIFX
41
41
 
42
42
  # Attempts to make the light(s) pulse `color` and then back to its original color. Asynchronous.
43
43
  # @param color [Color] Color to pulse
44
- # @param duty_cycle: [Float] Percentage of a cycle the light(s) is set to `color`
44
+ # @param duty_cycle: [Float] Ratio of a cycle the light(s) is set to `color`
45
45
  # @param cycles: [Integer] Number of cycles
46
46
  # @param transient: [Boolean] If false, the light will remain at the color the waveform is at when it ends
47
47
  # @param period: [Integer] Number of seconds a cycle. Must be above 1.0 (?)
@@ -64,6 +64,7 @@ module LIFX
64
64
  # Attempts to make the light(s) transition to `color` and back in a smooth sine wave. Asynchronous.
65
65
  # @param color [Color] Color
66
66
  # @param cycles: [Integer] Number of cycles
67
+ # @param peak: [Float] Defines the peak point of the wave. Defaults to 0.5 which is a standard sine
67
68
  # @param transient: [Boolean] If false, the light will remain at the color the waveform is at when it ends
68
69
  # @param period: [Integer] Number of seconds a cycle. Must be above 1.0 (?)
69
70
  # @param stream: [Integer] Unused
@@ -71,11 +72,12 @@ module LIFX
71
72
  # @note Marked as private pending bug fixes in firmware
72
73
  def sine(color, cycles: 1,
73
74
  period: 1.0,
75
+ peak: 0.5,
74
76
  transient: true,
75
77
  stream: 0)
76
78
  set_waveform(color, waveform: Protocol::Light::Waveform::SINE,
77
79
  cycles: cycles,
78
- duty_cycle: 0,
80
+ duty_cycle: peak,
79
81
  stream: stream,
80
82
  transient: transient,
81
83
  period: period)
@@ -140,7 +142,7 @@ module LIFX
140
142
 
141
143
  # Attempts to set the power state to `state` asynchronously.
142
144
  # This method cannot guarantee the message was received.
143
- # @param state [:on, :off]
145
+ # @param state [:on, :off]
144
146
  # @return [Light, LightCollection] self for chaining
145
147
  def set_power(state)
146
148
  level = case state
@@ -38,8 +38,8 @@ module LIFX
38
38
  @transport_manager.discover
39
39
  end
40
40
 
41
- def refresh
42
- @routing_manager.refresh
41
+ def refresh(force: true)
42
+ @routing_manager.refresh(force: force)
43
43
  end
44
44
 
45
45
  def reset!
@@ -86,9 +86,10 @@ module LIFX
86
86
  # Synchronize asynchronous set_color, set_waveform and set_power messages to multiple devices.
87
87
  # You cannot use synchronous methods in the block
88
88
  # @note This is alpha
89
+ # @param delay: [Float] The delay to add to sync commands when dealing with latency.
89
90
  # @yield Block to synchronize commands in
90
91
  # @return [Float] Delay before messages are executed
91
- def sync(&block)
92
+ def sync(delay: 0, &block)
92
93
  if within_sync?
93
94
  raise "You cannot nest sync"
94
95
  end
@@ -106,7 +107,7 @@ module LIFX
106
107
  time = light && light.time
107
108
  end
108
109
 
109
- delay = (messages.count + 1) * (1.0 / @transport_manager.message_rate)
110
+ delay += (messages.count + 1) * (1.0 / @transport_manager.message_rate)
110
111
  at_time = ((time.to_f + delay) * 1_000_000_000).to_i
111
112
  messages.each do |m|
112
113
  m.at_time = at_time
@@ -8,7 +8,7 @@ module LIFX
8
8
 
9
9
  def add_observer(obj, type, &callback)
10
10
  if !callback_type_exists?(type)
11
- raise ObserverCallbackNotFound.new
11
+ raise ObserverCallbackNotFound.new("Callback #{type} not found in #{observer_callback_definition.keys}")
12
12
  end
13
13
  if !callback_has_required_keys?(type, callback)
14
14
  raise ObserverCallbackMismatch.new
@@ -25,6 +25,9 @@ module LIFX
25
25
  end
26
26
 
27
27
  def notify_observers(type, **args)
28
+ if !callback_type_exists?(type)
29
+ raise ObserverCallbackNotFound.new("Callback #{type} not found in #{observer_callback_definition.keys}")
30
+ end
28
31
  observers[type].each do |_, callback|
29
32
  callback.call(**args)
30
33
  end
@@ -96,10 +96,10 @@ module LIFX
96
96
  end
97
97
  end
98
98
 
99
- MINIMUM_REFRESH_INTERVAL = 20
100
- def refresh
99
+ MINIMUM_REFRESH_INTERVAL = 15
100
+ def refresh(force: false)
101
101
  @routing_table.site_ids.each do |site_id|
102
- next if (seen = @last_refresh_seen[site_id]) && Time.now - seen < MINIMUM_REFRESH_INTERVAL
102
+ next if (seen = @last_refresh_seen[site_id]) && Time.now - seen < MINIMUM_REFRESH_INTERVAL && !force
103
103
  refresh_site(site_id)
104
104
  end
105
105
  end
@@ -30,7 +30,8 @@ module LIFX
30
30
 
31
31
  def observer_callback_definition
32
32
  {
33
- message_received: -> (message: nil, ip: nil, transport: nil) {}
33
+ message_received: -> (message: nil, ip: nil, transport: nil) {},
34
+ disconnected: -> {}
34
35
  }
35
36
  end
36
37
  end
@@ -80,6 +80,7 @@ module LIFX
80
80
  end
81
81
  end
82
82
  broadcast_to_peers(message)
83
+ @message_rate_timer.reset
83
84
  end
84
85
 
85
86
  def on_network?
@@ -112,23 +113,29 @@ module LIFX
112
113
  end
113
114
 
114
115
  def gateways
115
- @sites.values.map(&:gateways)
116
+ @sites.values.map(&:gateways).map(&:keys).flatten.uniq.map { |id| context.lights.with_id(id) }.compact
116
117
  end
117
118
 
118
119
  def gateway_connections
119
- gateways.map(&:values).flatten
120
+ @sites.values.map(&:gateways).map(&:values).flatten
121
+ end
122
+
123
+ def message_rate
124
+ @message_rate || DEFAULT_MESSAGE_RATE
120
125
  end
121
126
 
122
127
  protected
123
128
 
124
129
  def initialize_periodic_refresh
125
130
  timers.every(10) do
126
- context.refresh
131
+ context.refresh(force: false)
127
132
  end
128
133
  end
129
134
 
135
+ DEFAULT_MESSAGE_RATE = 5 # per second
136
+ MESSAGE_RATE_1_2 = 20
130
137
  def initialize_message_rate_updater
131
- timers.every(5) do
138
+ @message_rate_timer = timers.every(2) do
132
139
  missing_mesh_firmware = context.lights.alive.select { |l| l.mesh_firmware(fetch: false).nil? }
133
140
  if missing_mesh_firmware.count > 10
134
141
  context.send_message(target: Target.new(broadcast: true), payload: Protocol::Device::GetMeshFirmware.new)
@@ -138,7 +145,7 @@ module LIFX
138
145
  @message_rate = context.lights.alive.all? do |light|
139
146
  m = light.mesh_firmware(fetch: false)
140
147
  m && m >= '1.2'
141
- end ? 20 : 5
148
+ end ? MESSAGE_RATE_1_2 : DEFAULT_MESSAGE_RATE
142
149
  gateway_connections.each do |connection|
143
150
  connection.set_message_rate(@message_rate)
144
151
  end
@@ -146,11 +153,6 @@ module LIFX
146
153
  end
147
154
  end
148
155
 
149
- DEFAULT_MESSAGING_RATE = 5 # per second
150
- def message_rate
151
- @message_rate || 5
152
- end
153
-
154
156
  def initialize_transports
155
157
  create_broadcast_transport
156
158
  create_peer_transport
@@ -1,7 +1,7 @@
1
1
  module LIFX
2
2
  # @private
3
3
  module Utilities
4
- def try_until(condition_proc, timeout_exception: Timeout::Error,
4
+ def try_until(condition_proc, timeout_exception: TimeoutError,
5
5
  timeout: 3,
6
6
  condition_interval: 0.1,
7
7
  action_interval: 0.5,
@@ -1,3 +1,3 @@
1
1
  module LIFX
2
- VERSION = "0.4.8"
2
+ VERSION = "0.4.10"
3
3
  end
@@ -14,7 +14,7 @@ module LIFX
14
14
  it 'does not send if there is no available connection' do
15
15
  expect(gateway).to_not receive(:actually_write)
16
16
  gateway.write(message)
17
- expect { gateway.flush(timeout: 0.5) }.to raise_error(Timeout::Error)
17
+ expect { gateway.flush(timeout: 0.5) }.to raise_error(TimeoutError)
18
18
  end
19
19
 
20
20
  it 'pushes message back into queue if unable to write' do
@@ -16,7 +16,7 @@ shared_context 'integration', integration: true do
16
16
  c.discover! do
17
17
  c.tags.include?('_Test') && c.lights.with_tag('_Test').count > 0
18
18
  end
19
- rescue Timeout::Error
19
+ rescue DiscoveryTimeout
20
20
  raise "Could not find any lights with tag _Test in #{c.lights.inspect}"
21
21
  end
22
22
  c
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lifx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.8
4
+ version: 0.4.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jack Chen (chendo)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-05 00:00:00.000000000 Z
11
+ date: 2014-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bindata
@@ -215,4 +215,3 @@ test_files:
215
215
  - spec/spec_helper.rb
216
216
  - spec/transport/udp_spec.rb
217
217
  - spec/transport_spec.rb
218
- has_rdoc: