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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e413317b0ac40abc57bdf3699b8373451b86614c
4
- data.tar.gz: 39852a66321e7352078e56e4b8073c4cb98f067b
3
+ metadata.gz: a0d7ac636c1a3c658b1859dbf7074fd845cd41e1
4
+ data.tar.gz: 112e36f614f01183d57d322d83d07807b58fe398
5
5
  SHA512:
6
- metadata.gz: c75b51ea1267b7605c5bcaf74bc0daf4c298143aed8e7155f9969231fdc7658ed3ec018bcec9cea0a483fc0b327366db72ab7f2fe17a8ac1f45a7f49efc8eef7
7
- data.tar.gz: 7b1b3274a505d44b2e793e1a616058bb4feb96054ea39ebbaf320c79e873f3550686c2a6c35ece2ec6cc0d99dd266fd96bf2b01fdf6e94c3b91b21b42dd03706
6
+ metadata.gz: 3693b61a7c84222e379dd535e6ccdb80f5e5381f4ac4f0893c0821f8c5ef4a269b19e0f76837158e1a4b5b42bff4b22c988e4b0d0ddf62f749b770a15eaacd90
7
+ data.tar.gz: 48a3b388801194eccccf878097c8f60ae83bab085e2e6dfa3d291baa6fb31780dcc6dacfd1b9f86214d7cda0e7a7e71e25ac66cae89af088e291a8718e727da2
data/CHANGES.md CHANGED
@@ -1,14 +1,26 @@
1
- # 0.4.5
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
- # 0.4.4
20
+ ### 0.4.4
9
21
 
10
22
  - Fix SO_REUSEPORT issue on older Linux kernels.
11
23
 
12
- # 0.4.3
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.1.1
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
@@ -10,7 +10,7 @@ task :console do
10
10
  require "lifx"
11
11
  require "pry"
12
12
  if ENV['DEBUG']
13
- LIFX::Config.logger = Yell.new(STDERR)
13
+ LIFX::Config.logger.level = Logger::DEBUG
14
14
  end
15
15
  LIFX::Client.lan.discover! do |c|
16
16
  c.lights.count > 0
@@ -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:, ip:, transport:|
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:, ip:, transport:|
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
@@ -17,5 +17,5 @@ require "lifx/config"
17
17
  require "lifx/client"
18
18
 
19
19
  module LIFX
20
-
20
+ NULL_SITE_ID = "000000000000"
21
21
  end
@@ -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 do
59
+ condition_interval: condition_interval,
60
+ action_interval: 1 do
61
61
  discover
62
+ refresh
62
63
  end
63
64
  self
64
65
  end
@@ -174,16 +174,23 @@ module LIFX
174
174
  [hue, saturation, brightness, kelvin]
175
175
  end
176
176
 
177
- EQUALITY_THRESHOLD = 0.001 # 0.1% variance
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 ==(other)
182
+ def similar_to?(other, threshold: DEFAULT_SIMILAR_THRESHOLD)
182
183
  return false unless other.is_a?(Color)
183
184
  conditions = []
184
- conditions << ((hue - other.hue).abs < (EQUALITY_THRESHOLD * 360))
185
- conditions << ((saturation - other.saturation).abs < EQUALITY_THRESHOLD)
186
- conditions << ((brightness - other.brightness).abs < EQUALITY_THRESHOLD)
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
@@ -1,12 +1,13 @@
1
1
  require 'configatron/core'
2
- require 'yell'
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.logger = Yell.new do |logger|
9
- logger.level = 'gte.warn'
10
- logger.adapter STDERR, format: '%d [%5L] %p/%t : %m'
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
@@ -1,3 +1,5 @@
1
+ require 'time'
2
+
1
3
  module LIFX
2
4
  # LIFX::Firmware handles decoding firmware payloads
3
5
  # @private
@@ -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 [Timeout::Error]
367
- def send_message!(payload, wait_for: wait_for, wait_timeout: 3, timeout_exception: Timeout::Error, &block)
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, timeout_exception: timeout_exception do
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
@@ -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 self.log_invalid_messages
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 self.log_invalid_messages
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 self.log_invalid_messages
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
@@ -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
@@ -2,6 +2,9 @@ module LIFX
2
2
  # @api private
3
3
  module Protocol
4
4
  class Payload < BinData::Record
5
+ def to_s
6
+ "#<#{self.class} #{super}>"
7
+ end
5
8
  end
6
9
  end
7
10
  end
@@ -54,6 +54,7 @@ module LIFX
54
54
  end
55
55
 
56
56
  def update_from_message(message)
57
+ return if message.site_id == NULL_SITE_ID
57
58
  if message.tagged?
58
59
  case message.payload
59
60
  when Protocol::Light::Get
@@ -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 !@ignore_unpackable_messages
56
- logger.warn("#{self}: Exception occured - #{ex}")
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}")
@@ -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 !@ignore_unpackable_messages
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: '255.255.255.255', port: 56700, peer_port: 56750)
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
@@ -1,3 +1,3 @@
1
1
  module LIFX
2
- VERSION = "0.4.5"
2
+ VERSION = "0.4.6.1"
3
3
  end
@@ -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"
@@ -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
@@ -27,7 +27,7 @@ module LIFX
27
27
  light.set_color(color, duration: 0)
28
28
  sleep 1
29
29
  light.refresh
30
- wait { expect(light.color).to eq color }
30
+ wait { expect(light.color).to be_similar_to(color) }
31
31
  end
32
32
  end
33
33
 
@@ -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 eq color }
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') }
@@ -1,39 +1,42 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe LIFX::Transport::UDP, integration: true do
4
- subject(:udp) { LIFX::Transport::UDP.new(host, port) }
3
+ module LIFX
4
+ describe Transport::UDP, integration: true do
5
+ subject(:udp) { Transport::UDP.new(host, port) }
5
6
 
6
- let(:host) { 'localhost' }
7
- let(:message) { double }
8
- let(:port) { 45_828 }
7
+ let(:host) { 'localhost' }
8
+ let(:message) { double }
9
+ let(:port) { 45_828 }
9
10
 
10
- describe '#write' do
11
- let(:payload) { double }
11
+ describe '#write' do
12
+ let(:payload) { double }
12
13
 
13
- it 'writes a Message to specified host' do
14
- expect(message).to receive(:pack).and_return(payload)
15
- expect_any_instance_of(UDPSocket).to receive(:send)
16
- .with(payload, 0, host, port)
17
- udp.write(message)
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
- describe '#listen' do
22
- let(:raw_message) { 'some binary data' }
23
- let(:socket) { UDPSocket.new }
24
-
25
- it 'listens to the specified socket data, unpacks it and notifies observers' do
26
- messages = []
27
- udp.add_observer(self) do |message: nil, ip: nil, transport: nil|
28
- messages << message
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
- expect(LIFX::Message).to receive(:unpack)
33
- .with(raw_message)
34
- .and_return(message)
35
- socket.send(raw_message, 0, host, port)
36
- wait { expect(messages).to include(message) }
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.5
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-03-28 00:00:00.000000000 Z
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.0.3
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,