diff --git a/hue.gemspec b/hue.gemspec index 9bb6c89..2a8f920 100644 --- a/hue.gemspec +++ b/hue.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |spec| spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ['lib'] - spec.required_ruby_version = '>= 1.9.3' + spec.required_ruby_version = '>= 2.1.0' spec.add_dependency 'thor' spec.add_dependency 'json' spec.add_dependency 'log_switch', '0.4.0' diff --git a/lib/hue/client.rb b/lib/hue/client.rb index 46bd1cc..17dc893 100644 --- a/lib/hue/client.rb +++ b/lib/hue/client.rb @@ -1,14 +1,16 @@ require 'net/http' require 'json' +require 'resolv' require 'curb' module Hue class Client attr_reader :username - def initialize(username = nil) + def initialize(username = nil, use_mdns: true) @bridge_id = nil @username = username || find_username + @use_mdns = use_mdns if @username begin @@ -35,14 +37,8 @@ def bridge def bridges @bridges ||= begin bs = [] - easy = Curl::Easy.new - easy.follow_location = true - easy.max_redirects = 10 - easy.url = 'https://discovery.meethue.com/' - easy.perform - JSON(easy.body).each do |hash| - bs << Bridge.new(self, hash) - end + discovery_mdns(bs) if @use_mdns + discovery_meethue(bs) if bs.empty? bs end end @@ -132,6 +128,33 @@ def find_bridge_id return nil end + def discovery_mdns(bs) + resolver = Resolv::MDNS.new + resolver.timeouts = 10 + + resolver.each_resource("_hue._tcp.local", Resolv::DNS::Resource::IN::PTR) do |bridge_ptr| + bridge_target = resolver.getresource(bridge_ptr.name, Resolv::DNS::Resource::IN::SRV).target + + bridge_hash = { + 'id' => resolver.getresource(bridge_ptr.name, Resolv::DNS::Resource::IN::TXT).strings[0].split('=')[1], + 'internalipaddress' => resolver.getresource(bridge_target, Resolv::DNS::Resource::IN::A).address + } + + bs << Bridge.new(self, bridge_hash) + end + end + + def discovery_meethue(bs) + easy = Curl::Easy.new + easy.follow_location = true + easy.max_redirects = 10 + easy.url = 'https://discovery.meethue.com/' + easy.perform + JSON(easy.body).each do |hash| + bs << Bridge.new(self, hash) + end + end + def get_error(error) # Find error class and return instance klass = Hue::ERROR_MAP[error['type']] || UnknownError unless klass diff --git a/test/hue/client_test.rb b/test/hue/client_test.rb index f3485fa..678a725 100644 --- a/test/hue/client_test.rb +++ b/test/hue/client_test.rb @@ -12,14 +12,14 @@ def before_setup end def test_with_bridge_id - client = Hue::Client.new + client = Hue::Client.new(use_mdns: false) client.stub :find_bridge_id, '63c2fc01391276a319f9' do assert_equal '63c2fc01391276a319f9', client.bridge.id end end def test_without_bridge_id - client = Hue::Client.new + client = Hue::Client.new(use_mdns: false) assert_equal 'ffa57b3b257200065704', client.bridge.id end end diff --git a/test/hue/light_test.rb b/test/hue/light_test.rb index 3591749..8d06418 100644 --- a/test/hue/light_test.rb +++ b/test/hue/light_test.rb @@ -14,7 +14,7 @@ def before_setup %w{on hue saturation brightness color_temperature alert effect}.each do |attribute| define_method "test_setting_#{attribute}" do - client = Hue::Client.new + client = Hue::Client.new(use_mdns: false) light = Hue::Light.new(client, client.bridge, 0, {"state" => {}}) light.send("#{attribute}=", 24)