huebot 0.4.0 → 1.0.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.
- checksums.yaml +4 -4
- data/README.md +101 -31
- data/bin/huebot +60 -27
- data/lib/huebot/bot.rb +82 -39
- data/lib/huebot/bridge.rb +24 -0
- data/lib/huebot/cli/helpers.rb +170 -0
- data/lib/huebot/cli/runner.rb +78 -0
- data/lib/huebot/cli.rb +2 -107
- data/lib/huebot/client.rb +132 -0
- data/lib/huebot/compiler/api_v1.rb +285 -0
- data/lib/huebot/compiler.rb +12 -148
- data/lib/huebot/config.rb +41 -0
- data/lib/huebot/device_mapper.rb +40 -26
- data/lib/huebot/device_state.rb +11 -0
- data/lib/huebot/group.rb +30 -0
- data/lib/huebot/light.rb +30 -0
- data/lib/huebot/program.rb +71 -21
- data/lib/huebot/version.rb +1 -1
- data/lib/huebot.rb +9 -24
- metadata +44 -18
- data/lib/hue/LICENSE +0 -22
- data/lib/hue/bridge.rb +0 -140
- data/lib/hue/client.rb +0 -141
- data/lib/hue/editable_state.rb +0 -27
- data/lib/hue/errors.rb +0 -38
- data/lib/hue/group.rb +0 -181
- data/lib/hue/light.rb +0 -177
- data/lib/hue/scene.rb +0 -50
- data/lib/hue/translate_keys.rb +0 -21
- data/lib/hue/version.rb +0 -3
- data/lib/hue.rb +0 -13
data/lib/hue/client.rb
DELETED
@@ -1,141 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'json'
|
3
|
-
|
4
|
-
module Hue
|
5
|
-
class Client
|
6
|
-
attr_reader :username
|
7
|
-
|
8
|
-
def initialize(username = nil)
|
9
|
-
@bridge_id = nil
|
10
|
-
@username = username || find_username
|
11
|
-
|
12
|
-
if @username
|
13
|
-
begin
|
14
|
-
validate_user
|
15
|
-
rescue Hue::UnauthorizedUser
|
16
|
-
register_user
|
17
|
-
end
|
18
|
-
else
|
19
|
-
register_user
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def bridge
|
24
|
-
@bridge_id = find_bridge_id unless @bridge_id
|
25
|
-
if @bridge_id
|
26
|
-
bridge = bridges.select { |b| b.id == @bridge_id }.first
|
27
|
-
else
|
28
|
-
bridge = bridges.first
|
29
|
-
end
|
30
|
-
raise NoBridgeFound unless bridge
|
31
|
-
bridge
|
32
|
-
end
|
33
|
-
|
34
|
-
# Patched by Jordan Hollinger to remove use of "curb" gem
|
35
|
-
# TODO handle redirects? That's what curb was used for.
|
36
|
-
def bridges
|
37
|
-
req = Net::HTTP::Get.new(URI(ENV["HUE_DISCOVERY_API"] || "https://discovery.meethue.com/"))
|
38
|
-
resp = Net::HTTP.start req.uri.host, req.uri.port, {use_ssl: true} do |http|
|
39
|
-
http.request req
|
40
|
-
end
|
41
|
-
|
42
|
-
JSON(resp.body).lazy.map { |x|
|
43
|
-
Bridge.new(self, x)
|
44
|
-
}
|
45
|
-
|
46
|
-
rescue Net::OpenTimeout, Net::ReadTimeout, JSON::ParserError
|
47
|
-
[]
|
48
|
-
end
|
49
|
-
|
50
|
-
def lights
|
51
|
-
bridge.lights
|
52
|
-
end
|
53
|
-
|
54
|
-
def add_lights
|
55
|
-
bridge.add_lights
|
56
|
-
end
|
57
|
-
|
58
|
-
def light(id)
|
59
|
-
id = id.to_s
|
60
|
-
lights.select { |l| l.id == id }.first
|
61
|
-
end
|
62
|
-
|
63
|
-
def groups
|
64
|
-
bridge.groups
|
65
|
-
end
|
66
|
-
|
67
|
-
def group(id = nil)
|
68
|
-
return Group.new(self, bridge) if id.nil?
|
69
|
-
|
70
|
-
id = id.to_s
|
71
|
-
groups.select { |g| g.id == id }.first
|
72
|
-
end
|
73
|
-
|
74
|
-
def scenes
|
75
|
-
bridge.scenes
|
76
|
-
end
|
77
|
-
|
78
|
-
def scene(id)
|
79
|
-
id = id.to_s
|
80
|
-
scenes.select { |s| s.id == id }.first
|
81
|
-
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
def find_username
|
86
|
-
return ENV['HUE_USERNAME'] if ENV['HUE_USERNAME']
|
87
|
-
|
88
|
-
json = JSON(File.read(File.expand_path('~/.hue')))
|
89
|
-
json['username']
|
90
|
-
rescue
|
91
|
-
return nil
|
92
|
-
end
|
93
|
-
|
94
|
-
def validate_user
|
95
|
-
response = JSON(Net::HTTP.get(URI.parse("http://#{bridge.ip}/api/#{@username}")))
|
96
|
-
|
97
|
-
if response.is_a? Array
|
98
|
-
response = response.first
|
99
|
-
end
|
100
|
-
|
101
|
-
if error = response['error']
|
102
|
-
raise get_error(error)
|
103
|
-
end
|
104
|
-
|
105
|
-
response['success']
|
106
|
-
end
|
107
|
-
|
108
|
-
def register_user
|
109
|
-
body = JSON.dump({
|
110
|
-
devicetype: 'Ruby'
|
111
|
-
})
|
112
|
-
|
113
|
-
uri = URI.parse("http://#{bridge.ip}/api")
|
114
|
-
http = Net::HTTP.new(uri.host)
|
115
|
-
response = JSON(http.request_post(uri.path, body).body).first
|
116
|
-
|
117
|
-
if error = response['error']
|
118
|
-
raise get_error(error)
|
119
|
-
end
|
120
|
-
|
121
|
-
if @username = response['success']['username']
|
122
|
-
File.write(File.expand_path('~/.hue'), JSON.dump({username: @username}))
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def find_bridge_id
|
127
|
-
return ENV['HUE_BRIDGE_ID'] if ENV['HUE_BRIDGE_ID']
|
128
|
-
|
129
|
-
json = JSON(File.read(File.expand_path('~/.hue')))
|
130
|
-
json['bridge_id']
|
131
|
-
rescue
|
132
|
-
return nil
|
133
|
-
end
|
134
|
-
|
135
|
-
def get_error(error)
|
136
|
-
# Find error class and return instance
|
137
|
-
klass = Hue::ERROR_MAP[error['type']] || UnknownError unless klass
|
138
|
-
klass.new(error['description'])
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
data/lib/hue/editable_state.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
module Hue
|
2
|
-
module EditableState
|
3
|
-
def on?
|
4
|
-
@state['on']
|
5
|
-
end
|
6
|
-
|
7
|
-
def on!
|
8
|
-
self.on = true
|
9
|
-
end
|
10
|
-
|
11
|
-
def off!
|
12
|
-
self.on = false
|
13
|
-
end
|
14
|
-
|
15
|
-
%w{on hue saturation brightness color_temperature alert effect}.each do |key|
|
16
|
-
define_method "#{key}=".to_sym do |value|
|
17
|
-
set_state({key.to_sym => value})
|
18
|
-
instance_variable_set("@#{key}".to_sym, value)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def set_xy(x, y)
|
23
|
-
set_state({:xy => [x, y]})
|
24
|
-
@x, @y = x, y
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
data/lib/hue/errors.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
module Hue
|
2
|
-
class Error < StandardError; end
|
3
|
-
|
4
|
-
class UnauthorizedUser < Error; end
|
5
|
-
class InvalidJSON < Error; end
|
6
|
-
class ResourceNotAvailable < Error; end
|
7
|
-
class MethodNotAvailable < Error; end
|
8
|
-
class MissingBody < Error; end
|
9
|
-
class ParameterNotAvailable < Error; end
|
10
|
-
class InvalidValueForParameter < Error; end
|
11
|
-
class ParameterNotModifiable < Error; end
|
12
|
-
class InternalError < Error; end
|
13
|
-
class LinkButtonNotPressed < Error; end
|
14
|
-
class ParameterNotModifiableWhileOff < ParameterNotModifiable; end
|
15
|
-
class TooManyGroups < Error; end
|
16
|
-
class GroupTooFull < Error; end
|
17
|
-
|
18
|
-
class InvalidUsername < Error; end
|
19
|
-
class UnknownError < Error; end
|
20
|
-
class NoBridgeFound < Error; end
|
21
|
-
|
22
|
-
# Status code to exception map
|
23
|
-
ERROR_MAP = {
|
24
|
-
1 => Hue::UnauthorizedUser,
|
25
|
-
2 => Hue::InvalidJSON,
|
26
|
-
3 => Hue::ResourceNotAvailable,
|
27
|
-
4 => Hue::MethodNotAvailable,
|
28
|
-
5 => Hue::MissingBody,
|
29
|
-
6 => Hue::ParameterNotAvailable,
|
30
|
-
7 => Hue::InvalidValueForParameter,
|
31
|
-
8 => Hue::ParameterNotModifiable,
|
32
|
-
901 => Hue::InternalError,
|
33
|
-
101 => Hue::LinkButtonNotPressed,
|
34
|
-
201 => Hue::ParameterNotModifiableWhileOff,
|
35
|
-
301 => Hue::TooManyGroups,
|
36
|
-
302 => Hue::GroupTooFull
|
37
|
-
}
|
38
|
-
end
|
data/lib/hue/group.rb
DELETED
@@ -1,181 +0,0 @@
|
|
1
|
-
module Hue
|
2
|
-
class Group
|
3
|
-
include Enumerable
|
4
|
-
include TranslateKeys
|
5
|
-
include EditableState
|
6
|
-
|
7
|
-
# Unique identification number.
|
8
|
-
attr_reader :id
|
9
|
-
|
10
|
-
# Bridge the group is associated with
|
11
|
-
attr_reader :bridge
|
12
|
-
|
13
|
-
# A unique, editable name given to the group.
|
14
|
-
attr_accessor :name
|
15
|
-
|
16
|
-
# Hue of the group. This is a wrapping value between 0 and 65535.
|
17
|
-
# Both 0 and 65535 are red, 25500 is green and 46920 is blue.
|
18
|
-
attr_accessor :hue
|
19
|
-
|
20
|
-
# Saturation of the group. 255 is the most saturated (colored)
|
21
|
-
# and 0 is the least saturated (white).
|
22
|
-
attr_accessor :saturation
|
23
|
-
|
24
|
-
# Brightness of the group. This is a scale from the minimum
|
25
|
-
# brightness the group is capable of, 0, to the maximum capable
|
26
|
-
# brightness, 255. Note a brightness of 0 is not off.
|
27
|
-
attr_accessor :brightness
|
28
|
-
|
29
|
-
# The x coordinate of a color in CIE color space. Between 0 and 1.
|
30
|
-
#
|
31
|
-
# @see http://developers.meethue.com/coreconcepts.html#color_gets_more_complicated
|
32
|
-
attr_reader :x
|
33
|
-
|
34
|
-
# The y coordinate of a color in CIE color space. Between 0 and 1.
|
35
|
-
#
|
36
|
-
# @see http://developers.meethue.com/coreconcepts.html#color_gets_more_complicated
|
37
|
-
attr_reader :y
|
38
|
-
|
39
|
-
# The Mired Color temperature of the light. 2012 connected lights
|
40
|
-
# are capable of 153 (6500K) to 500 (2000K).
|
41
|
-
#
|
42
|
-
# @see http://en.wikipedia.org/wiki/Mired
|
43
|
-
attr_accessor :color_temperature
|
44
|
-
|
45
|
-
# A fixed name describing the type of group.
|
46
|
-
attr_reader :type
|
47
|
-
|
48
|
-
def initialize(client, bridge, id = nil, data = {})
|
49
|
-
@client = client
|
50
|
-
@bridge = bridge
|
51
|
-
@id = id
|
52
|
-
|
53
|
-
unpack(data)
|
54
|
-
end
|
55
|
-
|
56
|
-
def each(&block)
|
57
|
-
lights.each(&block)
|
58
|
-
end
|
59
|
-
|
60
|
-
def lights
|
61
|
-
@lights ||= begin
|
62
|
-
@light_ids.map do |light_id|
|
63
|
-
@client.light(light_id)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def name=(name)
|
69
|
-
resp = set_group_state({:name => name})
|
70
|
-
@name = new? ? name : resp[0]['success']["/groups/#{id}/name"]
|
71
|
-
end
|
72
|
-
|
73
|
-
def lights=(light_ids)
|
74
|
-
light_ids.map! do |light_id|
|
75
|
-
light_id.is_a?(Light) ? light_id.id : light_id.to_s
|
76
|
-
end
|
77
|
-
|
78
|
-
@light_ids = light_ids.uniq
|
79
|
-
@lights = nil # resets the memoization
|
80
|
-
|
81
|
-
set_group_state({:lights => @light_ids})
|
82
|
-
end
|
83
|
-
|
84
|
-
def scene=(scene)
|
85
|
-
scene_id = scene.is_a?(Scene) ? scene.id : scene
|
86
|
-
set_group_state({:scene => scene_id})
|
87
|
-
end
|
88
|
-
|
89
|
-
def <<(light_id)
|
90
|
-
@light_ids << light_id
|
91
|
-
set_group_state({:lights => @light_ids})
|
92
|
-
end
|
93
|
-
alias_method :add_light, :<<
|
94
|
-
|
95
|
-
def set_group_state(attributes)
|
96
|
-
return if new?
|
97
|
-
body = translate_keys(attributes, GROUP_KEYS_MAP)
|
98
|
-
|
99
|
-
uri = URI.parse(base_url)
|
100
|
-
http = Net::HTTP.new(uri.host)
|
101
|
-
response = http.request_put(uri.path, JSON.dump(body))
|
102
|
-
JSON(response.body)
|
103
|
-
end
|
104
|
-
|
105
|
-
def set_state(attributes)
|
106
|
-
return if new?
|
107
|
-
body = translate_keys(attributes, STATE_KEYS_MAP)
|
108
|
-
|
109
|
-
uri = URI.parse("#{base_url}/action")
|
110
|
-
http = Net::HTTP.new(uri.host)
|
111
|
-
response = http.request_put(uri.path, JSON.dump(body))
|
112
|
-
JSON(response.body)
|
113
|
-
end
|
114
|
-
|
115
|
-
def refresh
|
116
|
-
json = JSON(Net::HTTP.get(URI.parse(base_url)))
|
117
|
-
unpack(json)
|
118
|
-
@lights = nil
|
119
|
-
end
|
120
|
-
|
121
|
-
def create!
|
122
|
-
body = {
|
123
|
-
:name => @name,
|
124
|
-
:lights => @light_ids,
|
125
|
-
}
|
126
|
-
|
127
|
-
uri = URI.parse("http://#{@bridge.ip}/api/#{@client.username}/groups")
|
128
|
-
http = Net::HTTP.new(uri.host)
|
129
|
-
response = http.request_post(uri.path, JSON.dump(body))
|
130
|
-
json = JSON(response.body)
|
131
|
-
|
132
|
-
@id = json[0]['success']['id']
|
133
|
-
end
|
134
|
-
|
135
|
-
def destroy!
|
136
|
-
uri = URI.parse(base_url)
|
137
|
-
http = Net::HTTP.new(uri.host)
|
138
|
-
response = http.delete(uri.path)
|
139
|
-
json = JSON(response.body)
|
140
|
-
@id = nil if json[0]['success']
|
141
|
-
end
|
142
|
-
|
143
|
-
def new?
|
144
|
-
@id.nil?
|
145
|
-
end
|
146
|
-
|
147
|
-
private
|
148
|
-
|
149
|
-
GROUP_KEYS_MAP = {
|
150
|
-
:name => :name,
|
151
|
-
:light_ids => :lights,
|
152
|
-
:type => :type,
|
153
|
-
:state => :action
|
154
|
-
}
|
155
|
-
|
156
|
-
STATE_KEYS_MAP = {
|
157
|
-
:on => :on,
|
158
|
-
:brightness => :bri,
|
159
|
-
:hue => :hue,
|
160
|
-
:saturation => :sat,
|
161
|
-
:xy => :xy,
|
162
|
-
:color_temperature => :ct,
|
163
|
-
:alert => :alert,
|
164
|
-
:effect => :effect,
|
165
|
-
:color_mode => :colormode,
|
166
|
-
}
|
167
|
-
|
168
|
-
def unpack(data)
|
169
|
-
unpack_hash(data, GROUP_KEYS_MAP)
|
170
|
-
|
171
|
-
unless new?
|
172
|
-
unpack_hash(@state, STATE_KEYS_MAP)
|
173
|
-
@x, @y = @state['xy']
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
def base_url
|
178
|
-
"http://#{@bridge.ip}/api/#{@client.username}/groups/#{id}"
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
data/lib/hue/light.rb
DELETED
@@ -1,177 +0,0 @@
|
|
1
|
-
module Hue
|
2
|
-
class Light
|
3
|
-
include TranslateKeys
|
4
|
-
include EditableState
|
5
|
-
|
6
|
-
HUE_RANGE = 0..65535
|
7
|
-
SATURATION_RANGE = 0..255
|
8
|
-
BRIGHTNESS_RANGE = 0..255
|
9
|
-
COLOR_TEMPERATURE_RANGE = 153..500
|
10
|
-
|
11
|
-
# Unique identification number.
|
12
|
-
attr_reader :id
|
13
|
-
|
14
|
-
# Bridge the light is associated with
|
15
|
-
attr_reader :bridge
|
16
|
-
|
17
|
-
# A unique, editable name given to the light.
|
18
|
-
attr_accessor :name
|
19
|
-
|
20
|
-
# Hue of the light. This is a wrapping value between 0 and 65535.
|
21
|
-
# Both 0 and 65535 are red, 25500 is green and 46920 is blue.
|
22
|
-
attr_reader :hue
|
23
|
-
|
24
|
-
# Saturation of the light. 255 is the most saturated (colored)
|
25
|
-
# and 0 is the least saturated (white).
|
26
|
-
attr_reader :saturation
|
27
|
-
|
28
|
-
# Brightness of the light. This is a scale from the minimum
|
29
|
-
# brightness the light is capable of, 0, to the maximum capable
|
30
|
-
# brightness, 255. Note a brightness of 0 is not off.
|
31
|
-
attr_reader :brightness
|
32
|
-
|
33
|
-
# The x coordinate of a color in CIE color space. Between 0 and 1.
|
34
|
-
#
|
35
|
-
# @see http://developers.meethue.com/coreconcepts.html#color_gets_more_complicated
|
36
|
-
attr_reader :x
|
37
|
-
|
38
|
-
# The y coordinate of a color in CIE color space. Between 0 and 1.
|
39
|
-
#
|
40
|
-
# @see http://developers.meethue.com/coreconcepts.html#color_gets_more_complicated
|
41
|
-
attr_reader :y
|
42
|
-
|
43
|
-
# The Mired Color temperature of the light. 2012 connected lights
|
44
|
-
# are capable of 153 (6500K) to 500 (2000K).
|
45
|
-
#
|
46
|
-
# @see http://en.wikipedia.org/wiki/Mired
|
47
|
-
attr_reader :color_temperature
|
48
|
-
|
49
|
-
# The alert effect, which is a temporary change to the bulb’s state.
|
50
|
-
# This can take one of the following values:
|
51
|
-
# * `none` – The light is not performing an alert effect.
|
52
|
-
# * `select` – The light is performing one breathe cycle.
|
53
|
-
# * `lselect` – The light is performing breathe cycles for 30 seconds
|
54
|
-
# or until an "alert": "none" command is received.
|
55
|
-
#
|
56
|
-
# Note that in version 1.0 this contains the last alert sent to the
|
57
|
-
# light and not its current state. This will be changed to contain the
|
58
|
-
# current state in an upcoming patch.
|
59
|
-
#
|
60
|
-
# @see http://developers.meethue.com/coreconcepts.html#some_extra_fun_stuff
|
61
|
-
attr_reader :alert
|
62
|
-
|
63
|
-
# The dynamic effect of the light, can either be `none` or
|
64
|
-
# `colorloop`. If set to colorloop, the light will cycle through
|
65
|
-
# all hues using the current brightness and saturation settings.
|
66
|
-
attr_reader :effect
|
67
|
-
|
68
|
-
# Indicates the color mode in which the light is working, this is
|
69
|
-
# the last command type it received. Values are `hs` for Hue and
|
70
|
-
# Saturation, `xy` for XY and `ct` for Color Temperature. This
|
71
|
-
# parameter is only present when the light supports at least one
|
72
|
-
# of the values.
|
73
|
-
attr_reader :color_mode
|
74
|
-
|
75
|
-
# A fixed name describing the type of light.
|
76
|
-
attr_reader :type
|
77
|
-
|
78
|
-
# The hardware model of the light.
|
79
|
-
attr_reader :model
|
80
|
-
|
81
|
-
# An identifier for the software version running on the light.
|
82
|
-
attr_reader :software_version
|
83
|
-
|
84
|
-
# Reserved for future functionality.
|
85
|
-
attr_reader :point_symbol
|
86
|
-
|
87
|
-
def initialize(client, bridge, id, hash)
|
88
|
-
@client = client
|
89
|
-
@bridge = bridge
|
90
|
-
@id = id
|
91
|
-
unpack(hash)
|
92
|
-
end
|
93
|
-
|
94
|
-
def name=(new_name)
|
95
|
-
unless (1..32).include?(new_name.length)
|
96
|
-
raise InvalidValueForParameter, 'name must be between 1 and 32 characters.'
|
97
|
-
end
|
98
|
-
|
99
|
-
body = {
|
100
|
-
:name => new_name
|
101
|
-
}
|
102
|
-
|
103
|
-
uri = URI.parse(base_url)
|
104
|
-
http = Net::HTTP.new(uri.host)
|
105
|
-
response = http.request_put(uri.path, JSON.dump(body))
|
106
|
-
response = JSON(response.body).first
|
107
|
-
if response['success']
|
108
|
-
@name = new_name
|
109
|
-
# else
|
110
|
-
# TODO: Error
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# Indicates if a light can be reached by the bridge. Currently
|
115
|
-
# always returns true, functionality will be added in a future
|
116
|
-
# patch.
|
117
|
-
def reachable?
|
118
|
-
@state['reachable']
|
119
|
-
end
|
120
|
-
|
121
|
-
# @param transition The duration of the transition from the light’s current
|
122
|
-
# state to the new state. This is given as a multiple of 100ms and
|
123
|
-
# defaults to 4 (400ms). For example, setting transistiontime:10 will
|
124
|
-
# make the transition last 1 second.
|
125
|
-
def set_state(attributes, transition = nil)
|
126
|
-
body = translate_keys(attributes, STATE_KEYS_MAP)
|
127
|
-
|
128
|
-
# Add transition
|
129
|
-
body.merge!({:transitiontime => transition}) if transition
|
130
|
-
|
131
|
-
uri = URI.parse("#{base_url}/state")
|
132
|
-
http = Net::HTTP.new(uri.host)
|
133
|
-
response = http.request_put(uri.path, JSON.dump(body))
|
134
|
-
JSON(response.body)
|
135
|
-
end
|
136
|
-
|
137
|
-
# Refresh the state of the lamp
|
138
|
-
def refresh
|
139
|
-
json = JSON(Net::HTTP.get(URI.parse(base_url)))
|
140
|
-
unpack(json)
|
141
|
-
end
|
142
|
-
|
143
|
-
private
|
144
|
-
|
145
|
-
KEYS_MAP = {
|
146
|
-
:state => :state,
|
147
|
-
:type => :type,
|
148
|
-
:name => :name,
|
149
|
-
:model => :modelid,
|
150
|
-
:software_version => :swversion,
|
151
|
-
:point_symbol => :pointsymbol
|
152
|
-
}
|
153
|
-
|
154
|
-
STATE_KEYS_MAP = {
|
155
|
-
:on => :on,
|
156
|
-
:brightness => :bri,
|
157
|
-
:hue => :hue,
|
158
|
-
:saturation => :sat,
|
159
|
-
:xy => :xy,
|
160
|
-
:color_temperature => :ct,
|
161
|
-
:alert => :alert,
|
162
|
-
:effect => :effect,
|
163
|
-
:color_mode => :colormode,
|
164
|
-
:reachable => :reachable,
|
165
|
-
}
|
166
|
-
|
167
|
-
def unpack(hash)
|
168
|
-
unpack_hash(hash, KEYS_MAP)
|
169
|
-
unpack_hash(@state, STATE_KEYS_MAP)
|
170
|
-
@x, @y = @state['xy']
|
171
|
-
end
|
172
|
-
|
173
|
-
def base_url
|
174
|
-
"http://#{@bridge.ip}/api/#{@client.username}/lights/#{id}"
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
data/lib/hue/scene.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
module Hue
|
2
|
-
class Scene
|
3
|
-
include Enumerable
|
4
|
-
include TranslateKeys
|
5
|
-
|
6
|
-
# Unique identification number.
|
7
|
-
attr_reader :id
|
8
|
-
|
9
|
-
# Bridge the scene is associated with
|
10
|
-
attr_reader :bridge
|
11
|
-
|
12
|
-
# A unique, editable name given to the scene.
|
13
|
-
attr_accessor :name
|
14
|
-
|
15
|
-
# Whether or not the scene is active on a group.
|
16
|
-
attr_reader :active
|
17
|
-
|
18
|
-
def initialize(client, bridge, id, data)
|
19
|
-
@client = client
|
20
|
-
@bridge = bridge
|
21
|
-
@id = id
|
22
|
-
|
23
|
-
unpack(data)
|
24
|
-
end
|
25
|
-
|
26
|
-
def lights
|
27
|
-
@lights ||= begin
|
28
|
-
@light_ids.map do |light_id|
|
29
|
-
@client.light(light_id)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
SCENE_KEYS_MAP = {
|
37
|
-
:name => :name,
|
38
|
-
:light_ids => :lights,
|
39
|
-
:active => :active,
|
40
|
-
}
|
41
|
-
|
42
|
-
def unpack(data)
|
43
|
-
unpack_hash(data, SCENE_KEYS_MAP)
|
44
|
-
end
|
45
|
-
|
46
|
-
def base_url
|
47
|
-
"http://#{@bridge.ip}/api/#{@client.username}/scenes/#{id}"
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
data/lib/hue/translate_keys.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
module Hue
|
2
|
-
module TranslateKeys
|
3
|
-
def translate_keys(hash, map)
|
4
|
-
new_hash = {}
|
5
|
-
hash.each do |key, value|
|
6
|
-
new_key = map[key.to_sym]
|
7
|
-
key = new_key if new_key
|
8
|
-
new_hash[key] = value
|
9
|
-
end
|
10
|
-
new_hash
|
11
|
-
end
|
12
|
-
|
13
|
-
def unpack_hash(hash, map)
|
14
|
-
map.each do |local_key, remote_key|
|
15
|
-
value = hash[remote_key.to_s]
|
16
|
-
next unless value
|
17
|
-
instance_variable_set("@#{local_key}", value)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/lib/hue/version.rb
DELETED
data/lib/hue.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'hue/version'
|
2
|
-
require 'hue/errors'
|
3
|
-
require 'hue/client'
|
4
|
-
require 'hue/bridge'
|
5
|
-
require 'hue/editable_state'
|
6
|
-
require 'hue/translate_keys'
|
7
|
-
require 'hue/light'
|
8
|
-
require 'hue/group'
|
9
|
-
require 'hue/scene'
|
10
|
-
|
11
|
-
module Hue
|
12
|
-
USERNAME_RANGE = 10..40
|
13
|
-
end
|