1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 | hue = require("node-hue-api")
|
50 | HueApi = hue.HueApi
|
51 | lightState = hue.lightState
|
52 |
|
53 | module.exports = (robot) ->
|
54 | base_url = process.env.PHILIPS_HUE_IP
|
55 | hash = process.env.PHILIPS_HUE_HASH
|
56 | api = new HueApi(base_url, hash)
|
57 | state = lightState.create();
|
58 |
|
59 |
|
60 | robot.respond /hue (?:ls )?groups/i, (msg) ->
|
61 | api.groups (err, groups) ->
|
62 | return handleError msg, err if err
|
63 | robot.logger.debug groups
|
64 | msg.send "Light groups:"
|
65 | for group in groups
|
66 | if group.id == '0'
|
67 | msg.send "- #{group.id}: '#{group.name}' (All)"
|
68 | else
|
69 | msg.send "- #{group.id}: '#{group.name}' (#{group.lights.join(', ')})"
|
70 |
|
71 | robot.respond /hue group (\w+)=(\[((\d)+,)*((\d)+)\])/i, (msg) ->
|
72 | group_name = msg.match[1]
|
73 | group_lights = JSON.parse(msg.match[2])
|
74 | msg.send "Setting #{group_name} to #{group_lights.join(', ')}"
|
75 | api.createGroup group_name, group_lights, (err, response) ->
|
76 | return handleError msg, err if err
|
77 | robot.logger.debug response
|
78 | msg.send "Group created!"
|
79 |
|
80 | robot.respond /hue rm group (\d)/i, (msg) ->
|
81 | group_id = msg.match[1]
|
82 | msg.send "Deleting #{group_id}"
|
83 | api.deleteGroup group_id, (err, response) ->
|
84 | return handleError msg, err if err
|
85 | robot.logger.debug response
|
86 | msg.send "Group deleted!"
|
87 |
|
88 |
|
89 | robot.respond /hue lights/i, (msg) ->
|
90 | api.lights (err, lights) ->
|
91 | return handleError msg, err if err
|
92 | robot.logger.debug lights
|
93 | msg.send "Connected hue lights:"
|
94 | for light in lights.lights
|
95 | msg.send "- #{light.id}: '#{light.name}'"
|
96 |
|
97 | robot.respond /hue light (.*)/i, (msg) ->
|
98 | light = msg.match[1]
|
99 | api.lightStatus light, (err, light) ->
|
100 | return handleError msg, err if err
|
101 | robot.logger.debug light
|
102 | msg.send "Light Status:"
|
103 | msg.send "- On: #{light.state.on}"
|
104 | msg.send "- Reachable: #{light.state.reachable}"
|
105 | msg.send "- Name: '#{light.name}'"
|
106 | msg.send "- Model: #{light.modelid} - #{light.type}"
|
107 | msg.send "- Unique ID: #{light.uniqueid}"
|
108 | msg.send "- Software Version: #{light.swversion}"
|
109 |
|
110 | robot.respond /hue @(\w+) hsb=\((\d+),(\d+),(\d+)\)/i, (msg) ->
|
111 | [group_name, vHue, vSat, vBri] = msg.match[1..4]
|
112 | groupMap group_name, (group) ->
|
113 | return msg.send "Could not find '#{group_name}' in list of groups" unless group
|
114 | msg.send "Setting light group #{group} to: Hue=#{vHue}, Saturation=#{vSat}, Brightness=#{vBri}"
|
115 | state = lightState.create().on(true).bri(vBri).hue(vHue).sat(vSat)
|
116 | api.setGroupLightState group, state, (err, status) ->
|
117 | return handleError msg, err if err
|
118 | robot.logger.debug status
|
119 |
|
120 | robot.respond /hue hsb light (\d+) (\d+) (\d+) (\d+)/i, (msg) ->
|
121 | [light, vHue, vSat, vBri] = msg.match[1..4]
|
122 | msg.send "Setting light #{light} to: Hue=#{vHue}, Saturation=#{vSat}, Brightness=#{vBri}"
|
123 | state = lightState.create().on(true).bri(vBri).hue(vHue).sat(vSat)
|
124 | api.setLightState light, state, (err, status) ->
|
125 | return handleError msg, err if err
|
126 | robot.logger.debug status
|
127 |
|
128 | robot.respond /hue @(\w+) xy=\(([0-9]*[.][0-9]+),([0-9]*[.][0-9]+)\)/i, (msg) ->
|
129 | [group_name,x,y] = msg.match[1..3]
|
130 | groupMap group_name, (group) ->
|
131 | return msg.send "Could not find '#{group_name}' in list of groups" unless group
|
132 | msg.send "Setting light group #{group} to: X=#{x}, Y=#{y}"
|
133 | state = lightState.create().on(true).xy(x, y)
|
134 | api.setGroupLightState group, state, (err, status) ->
|
135 | return handleError msg, err if err
|
136 | robot.logger.debug status
|
137 |
|
138 | robot.respond /hue xy light (.*) ([0-9]*[.][0-9]+) ([0-9]*[.][0-9]+)/i, (msg) ->
|
139 | [light,x,y] = msg.match[1..3]
|
140 | msg.send "Setting light #{light} to: X=#{x}, Y=#{y}"
|
141 | state = lightState.create().on(true).xy(x, y)
|
142 | api.setLightState light, state, (err, status) ->
|
143 | return handleError msg, err if err
|
144 | robot.logger.debug status
|
145 |
|
146 | robot.respond /hue @(\w+) ct=(\d{3})/i, (msg) ->
|
147 | [group_name,ct] = msg.match[1..2]
|
148 | groupMap group_name, (group) ->
|
149 | return msg.send "Could not find '#{group_name}' in list of groups" unless group
|
150 | msg.send "Setting light group #{group} to: CT=#{ct}"
|
151 | state = lightState.create().on(true).ct(ct)
|
152 | api.setGroupLightState group, state, (err, status) ->
|
153 | return handleError msg, err if err
|
154 | robot.logger.debug status
|
155 |
|
156 | robot.respond /hue ct light (.*) (\d{3})/i, (msg) ->
|
157 | [light,ct] = msg.match[1..2]
|
158 | msg.send "Setting light #{light} to: CT=#{ct}"
|
159 | state = lightState.create().on(true).ct(ct)
|
160 | api.setLightState light, state, (err, status) ->
|
161 | return handleError msg, err if err
|
162 | robot.logger.debug status
|
163 |
|
164 | robot.respond /hue @(\w+) (on|off)/i, (msg) ->
|
165 | [group_name, state] = msg.match[1..2]
|
166 | groupMap group_name, (group) ->
|
167 | return msg.send "Could not find '#{group_name}' in list of groups" unless group
|
168 | msg.send "Setting light group #{group} to #{state}"
|
169 | state = lightState.create().on(state=='on')
|
170 | api.setGroupLightState group, state, (err, status) ->
|
171 | return handleError msg, err if err
|
172 | robot.logger.debug status
|
173 |
|
174 | robot.respond /hue turn light (\d+) (on|off)/i, (msg) ->
|
175 | [light, state] = msg.match[1..2]
|
176 | msg.send "Setting light #{light} to #{state}"
|
177 | state = lightState.create().on(state=='on')
|
178 | api.setLightState light, state, (err, status) ->
|
179 | return handleError msg, err if err
|
180 | robot.logger.debug status
|
181 |
|
182 | robot.respond /hue (alert|alerts) light (.+)/i, (msg) ->
|
183 | [alert_length,light] = msg.match[1..2]
|
184 | if alert_length == 'alert'
|
185 | alert_text = 'short alert'
|
186 | state = lightState.create().alertShort()
|
187 | else
|
188 | alert_text = 'long alert'
|
189 | state = lightState.create().alertLong()
|
190 | msg.send "Setting light #{light} to #{alert_text}"
|
191 | api.setLightState light, state, (err, status) ->
|
192 | return handleError msg, err if err
|
193 | robot.logger.debug status
|
194 |
|
195 | robot.respond /hue (?:colors|colorloop|loop) (on|off) light (.+)/i, (msg) ->
|
196 | [loop_status,light] = msg.match[1..2]
|
197 | if loop_status == 'on'
|
198 | colorloop_text = 'on'
|
199 | state = lightState.create().effect('colorloop')
|
200 | else
|
201 | colorloop_text = 'off'
|
202 | state = lightState.create().effect('none')
|
203 | msg.send "Setting light #{light} colorloop to #{colorloop_text}"
|
204 | api.setLightState light, state, (err, status) ->
|
205 | return handleError msg, err if err
|
206 | robot.logger.debug status
|
207 |
|
208 |
|
209 | robot.respond /hue config/i, (msg) ->
|
210 | api.config (err, config) ->
|
211 | return handleError msg, err if err
|
212 | robot.logger.debug config
|
213 | msg.send "Base Station: '#{config.name}'"
|
214 | msg.send "IP: #{config.ipaddress} / MAC: #{config.mac} / ZigBee Channel: #{config.zigbeechannel}"
|
215 | msg.send "Software: #{config.swversion} / API: #{config.apiversion} / Update Available: #{config.swupdate.updatestate}"
|
216 |
|
217 |
|
218 | groupMap = (group_name, callback) ->
|
219 | robot.logger.debug "mapping group names to group ids"
|
220 | api.groups (err, groups) ->
|
221 | return handleError msg, err if err
|
222 | group_map = {}
|
223 | for group in groups
|
224 | robot.logger.debug group
|
225 | if group.id == '0'
|
226 | group_map['all'] = '0'
|
227 | else
|
228 | group_map[group.name.toLowerCase()] = group.id
|
229 | match = group_map[group_name.toLowerCase()]
|
230 | callback match
|
231 |
|
232 | handleError = (msg, err) ->
|
233 | msg.send err
|