lifx 0.4.5 → 0.4.6.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.
- checksums.yaml +4 -4
- data/CHANGES.md +15 -3
- data/README.md +2 -3
- data/Rakefile +1 -1
- data/bin/lifx-snoop +2 -2
- data/lib/lifx.rb +1 -1
- data/lib/lifx/client.rb +3 -2
- data/lib/lifx/color.rb +12 -5
- data/lib/lifx/config.rb +5 -4
- data/lib/lifx/firmware.rb +2 -0
- data/lib/lifx/light.rb +18 -5
- data/lib/lifx/message.rb +3 -5
- data/lib/lifx/network_context.rb +2 -0
- data/lib/lifx/protocol/payload.rb +3 -0
- data/lib/lifx/routing_manager.rb +1 -0
- data/lib/lifx/transport/tcp.rb +3 -2
- data/lib/lifx/transport/udp.rb +1 -1
- data/lib/lifx/transport_manager/lan.rb +3 -2
- data/lib/lifx/version.rb +1 -1
- data/lifx.gemspec +0 -1
- data/spec/color_spec.rb +15 -0
- data/spec/integration/light_spec.rb +1 -1
- data/spec/integration/tags_spec.rb +1 -1
- data/spec/transport/udp_spec.rb +30 -27
- metadata +20 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0d7ac636c1a3c658b1859dbf7074fd845cd41e1
|
4
|
+
data.tar.gz: 112e36f614f01183d57d322d83d07807b58fe398
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3693b61a7c84222e379dd535e6ccdb80f5e5381f4ac4f0893c0821f8c5ef4a269b19e0f76837158e1a4b5b42bff4b22c988e4b0d0ddf62f749b770a15eaacd90
|
7
|
+
data.tar.gz: 48a3b388801194eccccf878097c8f60ae83bab085e2e6dfa3d291baa6fb31780dcc6dacfd1b9f86214d7cda0e7a7e71e25ac66cae89af088e291a8718e727da2
|
data/CHANGES.md
CHANGED
@@ -1,14 +1,26 @@
|
|
1
|
-
|
1
|
+
### 0.4.6.1
|
2
|
+
|
3
|
+
- Fix `Time.parse` issue
|
4
|
+
|
5
|
+
### 0.4.6
|
6
|
+
|
7
|
+
- `Color#==` has been renamed to `Color#similar_to?`
|
8
|
+
- Broadcast IP configurable through `LIFX::Config.broadcast_ip`
|
9
|
+
- Removed Yell gem. Use stdlib Logger instead
|
10
|
+
- Uninitialized lights no longer shows up in `Client#lights`
|
11
|
+
- Handle Rubies that don't have IPv6 enabled
|
12
|
+
|
13
|
+
### 0.4.5
|
2
14
|
|
3
15
|
- Now supports Ruby 2.0
|
4
16
|
- Light#label can be nil
|
5
17
|
- Light#set_power and Light#set_power! now take :on and :off rather than magic number
|
6
18
|
- Use timers 1.x so no compilation is required
|
7
19
|
|
8
|
-
|
20
|
+
### 0.4.4
|
9
21
|
|
10
22
|
- Fix SO_REUSEPORT issue on older Linux kernels.
|
11
23
|
|
12
|
-
|
24
|
+
### 0.4.3
|
13
25
|
|
14
26
|
- Initial public release
|
data/README.md
CHANGED
@@ -13,8 +13,7 @@ This gem is in an early beta state. Expect breaking API changes.
|
|
13
13
|
|
14
14
|
## Requirements
|
15
15
|
|
16
|
-
* Ruby 2.
|
17
|
-
* Bundler
|
16
|
+
* Ruby 2.0+
|
18
17
|
* Tested on OS X Mavericks, but should work other *nix platforms. Please file an issue if you have any problems.
|
19
18
|
|
20
19
|
## Installation
|
@@ -34,7 +33,7 @@ $ bundle
|
|
34
33
|
Or install the gem with:
|
35
34
|
|
36
35
|
```shell
|
37
|
-
gem install lifx
|
36
|
+
gem install lifx # Add sudo if required.
|
38
37
|
```
|
39
38
|
|
40
39
|
## Usage
|
data/Rakefile
CHANGED
data/bin/lifx-snoop
CHANGED
@@ -27,7 +27,7 @@ end
|
|
27
27
|
|
28
28
|
begin
|
29
29
|
light_udp = LIFX::Transport::UDP.new('0.0.0.0', 56700)
|
30
|
-
light_udp.add_observer(self) do |message
|
30
|
+
light_udp.add_observer(self) do |message: nil, ip: nil, transport: nil|
|
31
31
|
if matchers.all? { |m| message.to_s =~ m }
|
32
32
|
puts "#{Time.now.iso8601(5)} BROADCAST: #{ip} #{message}"
|
33
33
|
end
|
@@ -35,7 +35,7 @@ begin
|
|
35
35
|
light_udp.listen
|
36
36
|
|
37
37
|
peer_udp = LIFX::Transport::UDP.new('0.0.0.0', 56750)
|
38
|
-
peer_udp.add_observer(self) do |message
|
38
|
+
peer_udp.add_observer(self) do |message: nil, ip: nil, transport: nil|
|
39
39
|
if matchers.all? { |m| message.to_s =~ m }
|
40
40
|
puts "#{Time.now.iso8601(5)} PEER: #{ip} #{message}"
|
41
41
|
end
|
data/lib/lifx.rb
CHANGED
data/lib/lifx/client.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'timeout'
|
3
|
-
require 'yell'
|
4
3
|
|
5
4
|
require 'lifx/network_context'
|
6
5
|
require 'lifx/light_collection'
|
@@ -57,8 +56,10 @@ module LIFX
|
|
57
56
|
try_until -> { block.arity == 1 ? block.call(self) : block.call },
|
58
57
|
timeout: timeout,
|
59
58
|
timeout_exception: DiscoveryTimeout,
|
60
|
-
condition_interval: condition_interval
|
59
|
+
condition_interval: condition_interval,
|
60
|
+
action_interval: 1 do
|
61
61
|
discover
|
62
|
+
refresh
|
62
63
|
end
|
63
64
|
self
|
64
65
|
end
|
data/lib/lifx/color.rb
CHANGED
@@ -174,16 +174,23 @@ module LIFX
|
|
174
174
|
[hue, saturation, brightness, kelvin]
|
175
175
|
end
|
176
176
|
|
177
|
-
|
177
|
+
DEFAULT_SIMILAR_THRESHOLD = 0.001 # 0.1% variance
|
178
178
|
# Checks if colours are equal to 0.1% variance
|
179
179
|
# @param other [Color] Color to compare to
|
180
|
+
# @param threshold: [Float] 0..1. Threshold to consider it similar
|
180
181
|
# @return [Boolean]
|
181
|
-
def
|
182
|
+
def similar_to?(other, threshold: DEFAULT_SIMILAR_THRESHOLD)
|
182
183
|
return false unless other.is_a?(Color)
|
183
184
|
conditions = []
|
184
|
-
|
185
|
-
conditions << ((
|
186
|
-
|
185
|
+
|
186
|
+
conditions << (((hue - other.hue).abs < (threshold * 360)) || begin
|
187
|
+
# FIXME: Surely there's a better way.
|
188
|
+
hues = [hue, other.hue].sort
|
189
|
+
hues[0] += 360
|
190
|
+
(hues[0] - hues[1]).abs < (threshold * 360)
|
191
|
+
end)
|
192
|
+
conditions << ((saturation - other.saturation).abs < threshold)
|
193
|
+
conditions << ((brightness - other.brightness).abs < threshold)
|
187
194
|
conditions.all?
|
188
195
|
end
|
189
196
|
end
|
data/lib/lifx/config.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'configatron/core'
|
2
|
-
require '
|
2
|
+
require 'logger'
|
3
3
|
module LIFX
|
4
4
|
Config = Configatron::Store.new
|
5
5
|
|
6
6
|
Config.default_duration = 1
|
7
|
+
Config.broadcast_ip = '255.255.255.255'
|
7
8
|
Config.allowed_transports = [:udp, :tcp]
|
8
|
-
Config.
|
9
|
-
|
10
|
-
logger.
|
9
|
+
Config.log_invalid_messages = false
|
10
|
+
Config.logger = Logger.new(STDERR).tap do |logger|
|
11
|
+
logger.level = Logger::WARN
|
11
12
|
end
|
12
13
|
end
|
data/lib/lifx/firmware.rb
CHANGED
data/lib/lifx/light.rb
CHANGED
@@ -46,7 +46,6 @@ module LIFX
|
|
46
46
|
hook.call(payload)
|
47
47
|
end
|
48
48
|
@message_signal.broadcast
|
49
|
-
seen!
|
50
49
|
end
|
51
50
|
|
52
51
|
# Adds a block to be run when a payload of class `payload_class` is received
|
@@ -354,17 +353,19 @@ module LIFX
|
|
354
353
|
# @return [Light] returns self for chaining
|
355
354
|
def send_message(payload, acknowledge: true)
|
356
355
|
context.send_message(target: Target.new(device_id: id, site_id: @site_id), payload: payload, acknowledge: acknowledge)
|
357
|
-
self
|
358
356
|
end
|
359
357
|
|
358
|
+
# An exception for when synchronous messages take too long to receive a response
|
359
|
+
class MessageTimeout < StandardError; end
|
360
|
+
|
360
361
|
# Queues a message to be sent to the Light and waits for a response
|
361
362
|
# @param payload [Protocol::Payload] the payload to send
|
362
363
|
# @param wait_for: [Class] the payload class to wait for
|
363
364
|
# @param wait_timeout: [Numeric] wait timeout
|
364
365
|
# @param block: [Proc] the block that is executed when the expected `wait_for` payload comes back. If the return value is false or nil, it will try to send the message again.
|
365
366
|
# @return [Object] the truthy result of `block` is returned.
|
366
|
-
# @raise [
|
367
|
-
def send_message!(payload, wait_for: wait_for, wait_timeout: 3,
|
367
|
+
# @raise [MessageTimeout] if the device doesn't respond in time
|
368
|
+
def send_message!(payload, wait_for: wait_for, wait_timeout: 3, &block)
|
368
369
|
if Thread.current[:sync_enabled]
|
369
370
|
raise "Cannot use synchronous methods inside a sync block"
|
370
371
|
end
|
@@ -376,10 +377,16 @@ module LIFX
|
|
376
377
|
result = block.call(payload)
|
377
378
|
}
|
378
379
|
add_hook(wait_for, proc)
|
379
|
-
try_until -> { result }, signal: @message_signal
|
380
|
+
try_until -> { result }, signal: @message_signal do
|
380
381
|
send_message(payload)
|
381
382
|
end
|
382
383
|
result
|
384
|
+
rescue Timeout::Error
|
385
|
+
backtrace = caller_locations(2).map { |c| c.to_s }
|
386
|
+
caller_method = caller_locations(2, 1).first.label
|
387
|
+
ex = MessageTimeout.new("#{caller_method}: Timeout exceeded waiting for response from #{self}")
|
388
|
+
ex.set_backtrace(backtrace)
|
389
|
+
raise ex
|
383
390
|
ensure
|
384
391
|
remove_hook(wait_for, proc)
|
385
392
|
end
|
@@ -390,6 +397,7 @@ module LIFX
|
|
390
397
|
def add_hooks
|
391
398
|
add_hook(Protocol::Device::StateLabel) do |payload|
|
392
399
|
@label = payload.label.to_s
|
400
|
+
seen!
|
393
401
|
end
|
394
402
|
|
395
403
|
add_hook(Protocol::Light::State) do |payload|
|
@@ -397,22 +405,27 @@ module LIFX
|
|
397
405
|
@color = Color.from_struct(payload.color.snapshot)
|
398
406
|
@power = payload.power.to_i
|
399
407
|
@tags_field = payload.tags
|
408
|
+
seen!
|
400
409
|
end
|
401
410
|
|
402
411
|
add_hook(Protocol::Device::StateTags) do |payload|
|
403
412
|
@tags_field = payload.tags
|
413
|
+
seen!
|
404
414
|
end
|
405
415
|
|
406
416
|
add_hook(Protocol::Device::StatePower) do |payload|
|
407
417
|
@power = payload.level.to_i
|
418
|
+
seen!
|
408
419
|
end
|
409
420
|
|
410
421
|
add_hook(Protocol::Device::StateMeshFirmware) do |payload|
|
411
422
|
@mesh_firmware = Firmware.new(payload)
|
423
|
+
seen!
|
412
424
|
end
|
413
425
|
|
414
426
|
add_hook(Protocol::Device::StateWifiFirmware) do |payload|
|
415
427
|
@wifi_firmware = Firmware.new(payload)
|
428
|
+
seen!
|
416
429
|
end
|
417
430
|
end
|
418
431
|
end
|
data/lib/lifx/message.rb
CHANGED
@@ -22,8 +22,6 @@ module LIFX
|
|
22
22
|
PROTOCOL_VERSION = 1024
|
23
23
|
|
24
24
|
class << self
|
25
|
-
attr_accessor :log_invalid_messages
|
26
|
-
|
27
25
|
def unpack(data)
|
28
26
|
raise InvalidFrame if data.length < 2
|
29
27
|
|
@@ -35,7 +33,7 @@ module LIFX
|
|
35
33
|
path = ProtocolPath.new(raw_site: message.raw_site, raw_target: message.raw_target, tagged: message.tagged)
|
36
34
|
payload_class = message_type_for_id(message.type.snapshot)
|
37
35
|
if payload_class.nil?
|
38
|
-
if
|
36
|
+
if Config.log_invalid_messages
|
39
37
|
logger.error("Message.unpack: Unrecognised payload ID: #{message.type}")
|
40
38
|
logger.error("Message.unpack: Message: #{message}")
|
41
39
|
end
|
@@ -48,7 +46,7 @@ module LIFX
|
|
48
46
|
if message.raw_site == "\x00" * 6
|
49
47
|
logger.info("Message.unpack: Ignoring malformed message from virgin bulb")
|
50
48
|
else
|
51
|
-
if
|
49
|
+
if Config.log_invalid_messages
|
52
50
|
logger.error("Message.unpack: Exception while unpacking payload of type #{payload_class}: #{ex}")
|
53
51
|
logger.error("Message.unpack: Data: #{data.inspect}")
|
54
52
|
end
|
@@ -56,7 +54,7 @@ module LIFX
|
|
56
54
|
end
|
57
55
|
new(path, message, payload)
|
58
56
|
rescue => ex
|
59
|
-
if
|
57
|
+
if Config.log_invalid_messages
|
60
58
|
logger.debug("Message.unpack: Exception while unpacking #{data.inspect}")
|
61
59
|
logger.debug("Message.unpack: #{ex} - #{ex.backtrace.join("\n")}")
|
62
60
|
end
|
data/lib/lifx/network_context.rb
CHANGED
@@ -121,6 +121,7 @@ module LIFX
|
|
121
121
|
end
|
122
122
|
|
123
123
|
def register_device(device)
|
124
|
+
return if device.site_id == NULL_SITE_ID
|
124
125
|
device_id = device.id
|
125
126
|
@devices[device_id] = device # What happens when there's already one registered?
|
126
127
|
end
|
@@ -170,6 +171,7 @@ module LIFX
|
|
170
171
|
register_device(device)
|
171
172
|
end
|
172
173
|
device = @devices[message.device_id]
|
174
|
+
return if !device # Virgin bulb
|
173
175
|
device.handle_message(message, ip, transport)
|
174
176
|
end
|
175
177
|
end
|
data/lib/lifx/routing_manager.rb
CHANGED
data/lib/lifx/transport/tcp.rb
CHANGED
@@ -52,8 +52,9 @@ module LIFX
|
|
52
52
|
|
53
53
|
notify_observers(message: message, ip: host, transport: self)
|
54
54
|
rescue Message::UnpackError
|
55
|
-
if
|
56
|
-
logger.
|
55
|
+
if Config.log_invalid_messages
|
56
|
+
logger.info("#{self}: Exception occured while decoding message - #{ex}")
|
57
|
+
logger.info("Data: #{data.inspect}")
|
57
58
|
end
|
58
59
|
rescue => ex
|
59
60
|
logger.warn("#{self}: Exception occured in #listen - #{ex}")
|
data/lib/lifx/transport/udp.rb
CHANGED
@@ -41,7 +41,7 @@ module LIFX
|
|
41
41
|
message = Message.unpack(bytes)
|
42
42
|
notify_observers(message: message, ip: ip, transport: self)
|
43
43
|
rescue Message::UnpackError
|
44
|
-
if
|
44
|
+
if Config.log_invalid_messages
|
45
45
|
logger.warn("#{self}: Unrecognised bytes: #{bytes.bytes.map { |b| '%02x ' % b }.join}")
|
46
46
|
end
|
47
47
|
end
|
@@ -3,7 +3,7 @@ require 'lifx/site'
|
|
3
3
|
module LIFX
|
4
4
|
module TransportManager
|
5
5
|
class LAN < Base
|
6
|
-
def initialize(bind_ip: '0.0.0.0', send_ip:
|
6
|
+
def initialize(bind_ip: '0.0.0.0', send_ip: Config.broadcast_ip, port: 56700, peer_port: 56750)
|
7
7
|
super
|
8
8
|
@bind_ip = bind_ip
|
9
9
|
@send_ip = send_ip
|
@@ -76,7 +76,7 @@ module LIFX
|
|
76
76
|
else # Ruby 2.0
|
77
77
|
Socket.ip_address_list.any? do |addrinfo|
|
78
78
|
# Not entirely sure how to check if on a LAN with IPv6
|
79
|
-
addrinfo.ipv4_private? || addrinfo.ipv6_unique_local?
|
79
|
+
addrinfo.ipv4_private? || (addrinfo.respond_to?(:ipv6_unique_local?) && addrinfo.ipv6_unique_local?)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -128,6 +128,7 @@ module LIFX
|
|
128
128
|
end
|
129
129
|
|
130
130
|
def handle_broadcast_message(message, ip, transport)
|
131
|
+
return if message.nil?
|
131
132
|
payload = message.payload
|
132
133
|
case payload
|
133
134
|
when Protocol::Device::StatePanGateway
|
data/lib/lifx/version.rb
CHANGED
data/lifx.gemspec
CHANGED
@@ -20,7 +20,6 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.required_ruby_version = ">= 2.0"
|
21
21
|
|
22
22
|
spec.add_dependency "bindata", "~> 2.0"
|
23
|
-
spec.add_dependency "yell", "~> 2.0"
|
24
23
|
spec.add_dependency "timers", "~> 1.0"
|
25
24
|
spec.add_dependency "configatron", "~> 3.0"
|
26
25
|
spec.add_development_dependency "bundler", "~> 1.3"
|
data/spec/color_spec.rb
CHANGED
@@ -22,5 +22,20 @@ module LIFX
|
|
22
22
|
it_behaves_like 'translating color', 'black', [0, 0, 0], [0, 0, 0]
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
describe '#similar_to?' do
|
27
|
+
it 'matches reds on on either end of hue spectrums' do
|
28
|
+
expect(Color.hsb(359.9, 1, 1)).to be_similar_to(Color.hsb(0, 1, 1))
|
29
|
+
expect(Color.hsb(0, 1, 1)).to be_similar_to(Color.hsb(359.9, 1, 1))
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'does not match different colours' do
|
33
|
+
expect(Color.hsb(120, 1, 1)).to_not be_similar_to(Color.hsb(0, 1, 1))
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'matches similar colours' do
|
37
|
+
expect(Color.hsb(120, 1, 1)).to be_similar_to(Color.hsb(120.3, 1, 1))
|
38
|
+
end
|
39
|
+
end
|
25
40
|
end
|
26
41
|
end
|
@@ -16,7 +16,7 @@ module LIFX
|
|
16
16
|
# It also returns the current light state rather than the
|
17
17
|
# final state
|
18
18
|
light.refresh
|
19
|
-
wait { expect(light.color).to
|
19
|
+
wait { expect(light.color).to be_similar_to(color) }
|
20
20
|
|
21
21
|
light.remove_tag('Foo')
|
22
22
|
wait { expect(light.tags).not_to include('Foo') }
|
data/spec/transport/udp_spec.rb
CHANGED
@@ -1,39 +1,42 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
module LIFX
|
4
|
+
describe Transport::UDP, integration: true do
|
5
|
+
subject(:udp) { Transport::UDP.new(host, port) }
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
let(:host) { 'localhost' }
|
8
|
+
let(:message) { double }
|
9
|
+
let(:port) { 45_828 }
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
describe '#write' do
|
12
|
+
let(:payload) { double }
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
it 'writes a Message to specified host' do
|
15
|
+
expect(message).to receive(:pack).and_return(payload)
|
16
|
+
expect_any_instance_of(UDPSocket).to receive(:send)
|
17
|
+
.with(payload, 0, host, port)
|
18
|
+
udp.write(message)
|
19
|
+
end
|
18
20
|
end
|
19
|
-
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
describe '#listen' do
|
23
|
+
let(:raw_message) { 'some binary data' }
|
24
|
+
let(:socket) { UDPSocket.new }
|
25
|
+
let(:messages) { [] }
|
26
|
+
before do
|
27
|
+
udp.add_observer(self) do |message: nil, ip: nil, transport: nil|
|
28
|
+
messages << message
|
29
|
+
end
|
30
|
+
udp.listen
|
29
31
|
end
|
30
|
-
udp.listen
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
it 'listens to the specified socket data, unpacks it and notifies observers' do
|
34
|
+
expect(Message).to receive(:unpack)
|
35
|
+
.with(raw_message)
|
36
|
+
.and_return(message)
|
37
|
+
socket.send(raw_message, 0, host, port)
|
38
|
+
wait { expect(messages).to include(message) }
|
39
|
+
end
|
37
40
|
end
|
38
41
|
end
|
39
42
|
end
|
metadata
CHANGED
@@ -1,111 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lifx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.6.1
|
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-
|
11
|
+
date: 2014-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bindata
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '2.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '2.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: yell
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ~>
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '2.0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ~>
|
24
|
+
- - "~>"
|
39
25
|
- !ruby/object:Gem::Version
|
40
26
|
version: '2.0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: timers
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
|
-
- - ~>
|
31
|
+
- - "~>"
|
46
32
|
- !ruby/object:Gem::Version
|
47
33
|
version: '1.0'
|
48
34
|
type: :runtime
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
|
-
- - ~>
|
38
|
+
- - "~>"
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '1.0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: configatron
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
|
-
- - ~>
|
45
|
+
- - "~>"
|
60
46
|
- !ruby/object:Gem::Version
|
61
47
|
version: '3.0'
|
62
48
|
type: :runtime
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
|
-
- - ~>
|
52
|
+
- - "~>"
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '3.0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: bundler
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
|
-
- - ~>
|
59
|
+
- - "~>"
|
74
60
|
- !ruby/object:Gem::Version
|
75
61
|
version: '1.3'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
|
-
- - ~>
|
66
|
+
- - "~>"
|
81
67
|
- !ruby/object:Gem::Version
|
82
68
|
version: '1.3'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: rake
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
|
-
- - ~>
|
73
|
+
- - "~>"
|
88
74
|
- !ruby/object:Gem::Version
|
89
75
|
version: '10.1'
|
90
76
|
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
|
-
- - ~>
|
80
|
+
- - "~>"
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '10.1'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: rspec
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
|
-
- - ~>
|
87
|
+
- - "~>"
|
102
88
|
- !ruby/object:Gem::Version
|
103
89
|
version: '2.14'
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
|
-
- - ~>
|
94
|
+
- - "~>"
|
109
95
|
- !ruby/object:Gem::Version
|
110
96
|
version: '2.14'
|
111
97
|
description: A Ruby gem that allows easy interaction with LIFX devices.
|
@@ -116,9 +102,9 @@ executables:
|
|
116
102
|
extensions: []
|
117
103
|
extra_rdoc_files: []
|
118
104
|
files:
|
119
|
-
- .gitignore
|
120
|
-
- .travis.yml
|
121
|
-
- .yardopts
|
105
|
+
- ".gitignore"
|
106
|
+
- ".travis.yml"
|
107
|
+
- ".yardopts"
|
122
108
|
- CHANGES.md
|
123
109
|
- Gemfile
|
124
110
|
- LICENSE.txt
|
@@ -197,17 +183,17 @@ require_paths:
|
|
197
183
|
- lib
|
198
184
|
required_ruby_version: !ruby/object:Gem::Requirement
|
199
185
|
requirements:
|
200
|
-
- -
|
186
|
+
- - ">="
|
201
187
|
- !ruby/object:Gem::Version
|
202
188
|
version: '2.0'
|
203
189
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
204
190
|
requirements:
|
205
|
-
- -
|
191
|
+
- - ">="
|
206
192
|
- !ruby/object:Gem::Version
|
207
193
|
version: '0'
|
208
194
|
requirements: []
|
209
195
|
rubyforge_project:
|
210
|
-
rubygems_version: 2.
|
196
|
+
rubygems_version: 2.2.2
|
211
197
|
signing_key:
|
212
198
|
specification_version: 4
|
213
199
|
summary: A Ruby gem that allows easy interaction with LIFX devices. Handles discovery,
|