hueget 0.7.6 → 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.
- package/CHANGELOG.md +3 -0
- package/README.md +125 -29
- package/hueget.js +56 -47
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,9 @@ See the [Readme file](https://github.com/jsiegenthaler/hueget/blob/master/README
|
|
|
4
4
|
|
|
5
5
|
# Bug Fixes and Improvements
|
|
6
6
|
|
|
7
|
+
## 1.0.0 (2025-01-01)
|
|
8
|
+
* Added support for further controllable api endpoints: schedules,scenes,sensors,rules,resourcelinks,capabilities
|
|
9
|
+
|
|
7
10
|
|
|
8
11
|
## 0.7.6 (2024-12-13)
|
|
9
12
|
* Added Docker config (thanks @Yannis4444)
|
package/README.md
CHANGED
|
@@ -9,13 +9,11 @@
|
|
|
9
9
|
A simple API to control Philips Hue lamps with http GET requests.
|
|
10
10
|
|
|
11
11
|
# Background
|
|
12
|
-
The existing Philips Hue REST API requires a PUT request to control the Hue lights and
|
|
12
|
+
The existing Philips Hue REST API requires a PUT request to control the Hue lights, groups, sensors and other resources of the Hue system.
|
|
13
13
|
|
|
14
|
-
I
|
|
14
|
+
I had a specific use case where I could only use GET requests, so I made a simple API to translate from GET to PUT. It also supports the standard GET command so you can use hueget for both GET and PUT.
|
|
15
15
|
|
|
16
|
-
hueget
|
|
17
|
-
|
|
18
|
-
This is my first ever API javascript program, so if you see any way it can be improved, I'd be happy to receive your suggestions.
|
|
16
|
+
hueget supports controlling lights, groups, sensors and more. A group is a collection of a number of lights, which in the Philips Hue app appears as a room. Sensors are devices such as the daylight sensor, the geofence sensor, motion sensors (which include light level and temperature) and switch sensors.
|
|
19
17
|
|
|
20
18
|
If you like this tool, consider buying me a coffee!<br>
|
|
21
19
|
<a target="blank" href="https://ko-fi.com/jsiegenthaler"><img src="https://img.shields.io/badge/Ko--Fi-Buy%20me%20a%20coffee-29abe0.svg?logo=ko-fi"/></a>
|
|
@@ -23,16 +21,16 @@ If you like this tool, consider buying me a coffee!<br>
|
|
|
23
21
|
# Creative Ways to use hueget
|
|
24
22
|
|
|
25
23
|
## Visual Door Bell
|
|
26
|
-
Flash your lights in the entire house when the doorbell rings. I have a Shelly1 as my doorbell. The doorbell connects to the Shelly1 SW input using a relay on the doorbell buzzer. Thus when the doorbell button is pressed, the Shelly1 sees an input, and calls a url, which flashes a group of lights for 15 seconds using the
|
|
24
|
+
Flash your lights in the entire house when the doorbell rings. I have a Shelly1 as my doorbell. The doorbell connects to the Shelly1 SW input using a relay on the doorbell buzzer. Thus when the doorbell button is pressed, the Shelly1 sees an input, and calls a url, which flashes a group of lights for 15 seconds using the `alert=lselect` command. I use the Philips Hue app to determine what lights should be in the group.
|
|
27
25
|
|
|
28
26
|
## Control Hue Lights directly from Shelly Motion Sensors
|
|
29
27
|
Anything that can call a url when triggered - such as a Shelly Motion Sensor - can be used to turn the lights on and off again. Make sure the motion sensor calls a url to turn lights on, and a url to turn lights off. The Shelly Motion Sensor is ideal for this, as you can activate call urls for different motion triggers.
|
|
30
28
|
|
|
31
29
|
## Toggle lights from a Shelly Button 1
|
|
32
|
-
Toggle a light or group of lights from a button that sends a non-changing URL. The
|
|
30
|
+
Toggle a light or group of lights from a button that sends a non-changing URL. The `toggle` command is perfect for any pushbutton controller that does not know (or can not know) the current light state, and only sends a non-changing static URL, such as a Shelly Button 1.
|
|
33
31
|
|
|
34
32
|
## Be Home Soon Alert
|
|
35
|
-
Flash lights in a room or in any group (zone, room) when someone comes home. The
|
|
33
|
+
Flash lights in a room or in any group (zone, room) when someone comes home. The `alert=lselect` command is perfect to generate a 15 second long flash without any extra programming. Just call the URL from Apple HomeKit automations when a person arrives in your geofence.
|
|
36
34
|
|
|
37
35
|
|
|
38
36
|
# Installing hueget
|
|
@@ -84,7 +82,7 @@ $ node /home/pi/node_modules/hueget/hueget.js -i 192.168.0.101 -u UBxWZChHseyjeF
|
|
|
84
82
|
```
|
|
85
83
|
A successful start of hueget (using the above command to specify ip address 192.168.0.100 and port 1234) will show:
|
|
86
84
|
```
|
|
87
|
-
hueget
|
|
85
|
+
hueget v1.0.0
|
|
88
86
|
commands will be sent to 192.168.0.101 with username UBxWZChHseyjeFwAkwgbdQ08x9XASWpanZZVg-mj
|
|
89
87
|
listening on port 1234
|
|
90
88
|
```
|
|
@@ -121,7 +119,7 @@ For more information about pm2, see https://github.com/Unitech/pm2
|
|
|
121
119
|
|
|
122
120
|
|
|
123
121
|
# Getting your Philips Hue Bridge API Username
|
|
124
|
-
If you have [Homebridge](https://homebridge.io/), and the [homebridge-hue](https://github.com/ebaauw/homebridge-hue) plugin, look at the **users** section of the hue config. You will see the Hue bridge MAC address
|
|
122
|
+
If you have [Homebridge](https://homebridge.io/), and the [homebridge-hue](https://github.com/ebaauw/homebridge-hue) plugin, look at the **users** section of the hue config. You will see the Hue bridge MAC address followed by the Hue bridge api username
|
|
125
123
|
```
|
|
126
124
|
"users": {
|
|
127
125
|
"ECB5FAFFFEFFFFFF": "yourPhilipsHueBridgeUsername"
|
|
@@ -132,6 +130,9 @@ The username will look something like this:
|
|
|
132
130
|
UBxWZChHseyjeFwAkwgbdQ08x9XASWpanZZVg-mj
|
|
133
131
|
```
|
|
134
132
|
|
|
133
|
+
Otherwise, if you do not have the homebridge-hue plugin installed, you need to create a new api username using the instructions shown here: https://developers.meethue.com/develop/get-started-2/ (this page does not require a Hue Developer Account).
|
|
134
|
+
|
|
135
|
+
|
|
135
136
|
# Running hueget with Docker (optional, only if you use a Docker environment)
|
|
136
137
|
You can run hueget easily using Docker and Docker Compose. This approach simplifies the setup in a Docker environment and ensures hueget is isolated and always running reliably.
|
|
137
138
|
|
|
@@ -145,17 +146,25 @@ You can run hueget easily using Docker and Docker Compose. This approach simplif
|
|
|
145
146
|
```bash
|
|
146
147
|
docker compose up -d
|
|
147
148
|
```
|
|
149
|
+
|
|
148
150
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
Enter a URL (in the format shown below) into your browser and press Enter. The ip address is the ip address of the device running hueget, eg: a raspberry pi.
|
|
151
|
+
# Reading the Status of your Hue Lights, Groups, Sensors and other Resources with hueget
|
|
152
|
+
Enter a URL (in the format shown below) into your browser and press Enter. The ip address is the ip address of the device running hueget, e.g.: a raspberry pi.
|
|
152
153
|
Examples:
|
|
153
154
|
|
|
154
155
|
* Get status of light 31: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/lights/31
|
|
155
156
|
* Get status of group 2: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/2
|
|
157
|
+
* Get status of sensor 1: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/sensors/1
|
|
158
|
+
* Get status of resourcename 1: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/resourcename/1
|
|
159
|
+
|
|
160
|
+
# Get the Capabilities of your Hue Bridge with hueget
|
|
161
|
+
The capabilities api endpoint shows how many lights, sensors, groups, scenes, schedules, rules, resourcelinks and other resources are available and how many exist in total. This is very useful to determine how many resources are configured and being used.
|
|
162
|
+
Example:
|
|
163
|
+
|
|
164
|
+
* Get capabilities of the Hue bridge: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/capabilities
|
|
156
165
|
|
|
157
|
-
# Controlling your Hue Lights or
|
|
158
|
-
Enter a URL (in the format shown below) into your browser and press Enter. The ip address is the ip address of the device running hueget,
|
|
166
|
+
# Controlling your Hue Lights, Groups or Sensors with hueget
|
|
167
|
+
Enter a URL (in the format shown below) into your browser and press Enter. The ip address is the ip address of the device running hueget, e.g.: a raspberry pi.
|
|
159
168
|
Examples:
|
|
160
169
|
## Lights
|
|
161
170
|
### Light 31 (example)
|
|
@@ -188,29 +197,101 @@ Examples:
|
|
|
188
197
|
|
|
189
198
|
Groups are collections of lights, and are used for Rooms and Zones in the Hue app.
|
|
190
199
|
|
|
191
|
-
|
|
192
|
-
|
|
200
|
+
|
|
201
|
+
## Sensors
|
|
202
|
+
### Sensor 1 (the daylight sensor)
|
|
203
|
+
* Turn sensor 1 on: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/sensors/1/config?on=true
|
|
204
|
+
* Turn sensor 1 off: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/sensors/1/config?on=false
|
|
205
|
+
* Toggle sensor 1: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/sensors/1/toggle
|
|
206
|
+
|
|
207
|
+
### Sensor 15 (example, a Hue motion sensor)
|
|
208
|
+
* Turn sensor 15 on: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/sensors/15/config?on=true
|
|
209
|
+
* Turn sensor 15 off: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/sensors/15/config?on=false
|
|
210
|
+
* Toggle sensor 15: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/sensors/15/toggle
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
## Special Toggle Command for Lights, Groups and Sensors
|
|
214
|
+
The hueget server supports a special `toggle` command, which does not exist natively in the Philips Hue bridge. This toggles (changes the state) of a specified light or group or sensor, allowing you to toggle the light/group/sensor state with a single URL. Toggling only makes sense for items that have an on and off state, which is why it is currently restricted to lights, groups and sensors.
|
|
215
|
+
|
|
216
|
+
The toggling of a light, group or sensor is the same as turning it on or off in the Hue app, and thus applies to the `on` parameter of the relevant `state` (lights), `action` (groups) or `config` (sensors).
|
|
193
217
|
|
|
194
218
|
Syntax:
|
|
195
219
|
* Toggle light 1: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/lights/1/toggle
|
|
196
220
|
* Toggle group 2: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/2/toggle
|
|
221
|
+
* Toggle sensor 15: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/sensors/15/toggle
|
|
222
|
+
|
|
197
223
|
|
|
224
|
+
## Supported Command Keywords and Parameters
|
|
225
|
+
The API is transparent to all Philips Hue command keywords and parameters. It expects all parameter name=value pairs to be separated by a comma. If any comma is required inside a value, e.g.: for the xy command which expects a value array, then you must url encode the comma to %2c.
|
|
198
226
|
|
|
199
|
-
|
|
200
|
-
The API is transparent to all Philips Hue keywords. It expects all name=value pairs to be separated by a comma. If any comma is required inside a value, eg: for the xy command which expects a value array, then you must url encode the comma to %2c.
|
|
227
|
+
If you include a parameter that the Hue bridge does not understand, an error message will be returned from the Hue bridge. Example:
|
|
201
228
|
|
|
229
|
+
url: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/sensors/15/config?xxxx=on
|
|
230
|
+
|
|
231
|
+
Response:
|
|
232
|
+
```
|
|
233
|
+
[{"error":{"type":6,"address":"/sensors/15/config/xxxx","description":"parameter, xxxx, not available"}}]
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
## Example JSON Responses
|
|
238
|
+
### Lights
|
|
202
239
|
The full JSON response for a light looks like this:
|
|
203
240
|
```
|
|
204
241
|
{"1":{"state":{"on":false,"bri":198,"hue":5360,"sat":192,"effect":"none","xy":[0.5330,0.3870],"ct":500,"alert":"select","colormode":"xy","mode":"homeautomation","reachable":true},"swupdate":{"state":"noupdates","lastinstall":"2021-08-21T01:50:00"},"type":"Extended color light","name":"Standard Lamp","modelid":"LCA001","manufacturername":"Signify Netherlands B.V.","productname":"Hue color lamp","capabilities":{"certified":true,"control":{"mindimlevel":200,"maxlumen":800,"colorgamuttype":"C","colorgamut":[[0.6915,0.3083],[0.1700,0.7000],[0.1532,0.0475]],"ct":{"min":153,"max":500}},"streaming":{"renderer":true,"proxy":true}},"config":{"archetype":"floorshade","function":"mixed","direction":"omnidirectional","startup":{"mode":"safety","configured":true}},"uniqueid":"00:17:88:01:08:ff:ff:ff-0b","swversion":"1.90.1","swconfigid":"35F80D40","productid":"Philips-LCA001-4-A19ECLv6"}}
|
|
205
242
|
```
|
|
206
243
|
|
|
244
|
+
### Groups
|
|
207
245
|
The full JSON response for a group looks like this:
|
|
208
246
|
```
|
|
209
247
|
{"name":"Lounge","lights":["9","1","2"],"sensors":[],"type":"Room","state":{"all_on":false,"any_on":false},"recycle":false,"class":"Lounge","action":{"on":false,"bri":0,"hue":7800,"sat":138,"effect":"none","xy":[0.5302,0.392],"ct":153,"alert":"select","colormode":"xy"}}
|
|
210
248
|
```
|
|
249
|
+
|
|
250
|
+
### Sensors
|
|
251
|
+
The full JSON response for a sensor varies according to the sensor type. A few types are shown below:
|
|
252
|
+
|
|
253
|
+
#### Daylight
|
|
254
|
+
A Daylight sensor is a built-in sensor used for sunrise and sunset functions
|
|
255
|
+
```
|
|
256
|
+
{"1":{"state":{"daylight":true,"lastupdated":"2025-01-01T07:12:00"},"config":{"on":true,"configured":true,"sunriseoffset":0,"sunsetoffset":0},"name":"Daylight","type":"Daylight","modelid":"PHDL00","manufacturername":"Signify Netherlands B.V.","swversion":"1.0"}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### Geofence
|
|
260
|
+
A Geofence sensor is a built-in sensor used for coming and leaving home functions
|
|
261
|
+
```
|
|
262
|
+
"4":{"state":{"presence":true,"lastupdated":"2021-05-27T17:54:43"},"config":{"on":true,"reachable":true},"name":"John's iPhone","type":"Geofence","modelid":"HA_GEOFENCE","manufacturername":"Philips","swversion":"1.0","uniqueid":"L_02_AaRRM","recycle":false}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
#### ZLLPresence
|
|
266
|
+
A ZLLPresence sensor is the motion sensor component of a Hue Motion Sensor
|
|
267
|
+
```
|
|
268
|
+
"15":{"state":{"presence":false,"lastupdated":"2025-01-01T09:09:13"},"swupdate":{"state":"noupdates","lastinstall":"2019-12-31T21:39:06"},"config":{"on":true,"battery":70,"reachable":true,"alert":"lselect","sensitivity":2,"sensitivitymax":2,"ledindication":false,"usertest":false,"pending":[]},"name":"Motion sensor 1","type":"ZLLPresence","modelid":"SML001","manufacturername":"Signify Netherlands B.V.","productname":"Hue motion sensor","swversion":"6.1.1.27575","uniqueid":"00:17:88:01:06:f5:1f:36-02-0406","capabilities":{"certified":true,"primary":true}},
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### ZLLLightLevel
|
|
272
|
+
A ZLLLightLevel sensor is the ambient light sensor component of a Hue Motion Sensor
|
|
273
|
+
```
|
|
274
|
+
"16":{"state":{"lightlevel":11427,"dark":false,"daylight":true,"lastupdated":"2025-01-01T09:10:17"},"swupdate":{"state":"noupdates","lastinstall":"2019-12-31T21:39:06"},"config":{"on":true,"battery":70,"reachable":true,"alert":"none","tholddark":2702,"tholdoffset":7000,"ledindication":false,"usertest":false,"pending":[]},"name":"Hue ambient light sensor 1","type":"ZLLLightLevel","modelid":"SML001","manufacturername":"Signify Netherlands B.V.","productname":"Hue ambient light sensor","swversion":"6.1.1.27575","uniqueid":"00:17:88:01:06:f5:1f:36-02-0400","capabilities":{"certified":true,"primary":false}},
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
#### ZLLTemperature
|
|
278
|
+
A ZLLTemperature sensor is the temperature sensor component of a Hue Motion Sensor
|
|
279
|
+
```
|
|
280
|
+
"17":{"state":{"temperature":2030,"lastupdated":"2025-01-01T09:08:13"},"swupdate":{"state":"noupdates","lastinstall":"2019-12-31T21:39:06"},"config":{"on":true,"battery":70,"reachable":true,"alert":"none","ledindication":false,"usertest":false,"pending":[]},"name":"Hue temperature sensor 1","type":"ZLLTemperature","modelid":"SML001","manufacturername":"Signify Netherlands B.V.","productname":"Hue temperature sensor","swversion":"6.1.1.27575","uniqueid":"00:17:88:01:06:f5:1f:36-02-0402","capabilities":{"certified":true,"primary":false}}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
#### ZLLSwitch
|
|
284
|
+
A ZLLSwitch sensor is the dimmer switch buttons of a Hue dimmer switch (original version)
|
|
285
|
+
```
|
|
286
|
+
"79":{"state":{"buttonevent":1002,"lastupdated":"2024-12-31T21:19:34"},"swupdate":{"state":"noupdates","lastinstall":"2020-07-18T12:47:52"},"config":{"on":true,"battery":15,"reachable":true,"pending":[]},"name":"Hue dimmer switch","type":"ZLLSwitch","modelid":"RWL021","manufacturername":"Signify Netherlands B.V.","productname":"Hue dimmer switch","diversityid":"73bbabea-3420-499a-9856-46bf437e119b","swversion":"6.1.1.28573","uniqueid":"00:17:88:01:08:09:d4:cd-02-fc00","capabilities":{"certified":true,"primary":true,"inputs":[{"repeatintervals":[800],"events":[{"buttonevent":1000,"eventtype":"initial_press"},{"buttonevent":1001,"eventtype":"repeat"},{"buttonevent":1002,"eventtype":"short_release"},{"buttonevent":1003,"eventtype":"long_release"},{"buttonevent":1004,"eventtype":"long_press"}]},{"repeatintervals":[800],"events":[{"buttonevent":2000,"eventtype":"initial_press"},{"buttonevent":2001,"eventtype":"repeat"},{"buttonevent":2002,"eventtype":"short_release"},{"buttonevent":2003,"eventtype":"long_release"},{"buttonevent":2004,"eventtype":"long_press"}]},{"repeatintervals":[800],"events":[{"buttonevent":3000,"eventtype":"initial_press"},{"buttonevent":3001,"eventtype":"repeat"},{"buttonevent":3002,"eventtype":"short_release"},{"buttonevent":3003,"eventtype":"long_release"},{"buttonevent":3004,"eventtype":"long_press"}]},{"repeatintervals":[800],"events":[{"buttonevent":4000,"eventtype":"initial_press"},{"buttonevent":4001,"eventtype":"repeat"},{"buttonevent":4002,"eventtype":"short_release"},{"buttonevent":4003,"eventtype":"long_release"},{"buttonevent":4004,"eventtype":"long_press"}]}]}}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Common Action Keywords for Lights and Groups
|
|
211
290
|
The most common action keywords for state or group are:
|
|
291
|
+
|
|
212
292
|
on, bri, hue, sat, effect, xy, ct, alert, colormode, mode (lights only).
|
|
213
|
-
|
|
293
|
+
|
|
294
|
+
For the full documentation of all keywords, see the [API documentation for lights](https://developers.meethue.com/develop/hue-api/lights-api/) and the [API documentation for groups](https://developers.meethue.com/develop/hue-api/groupds-api/).
|
|
214
295
|
|
|
215
296
|
## on (get and set)
|
|
216
297
|
Turn a light on or off. On=true, Off=false.
|
|
@@ -226,7 +307,7 @@ The hue value to set the light to. The hue value is a wrapping value between 0 a
|
|
|
226
307
|
Saturation of the light. 254 is the most saturated (colored) and 0 is the least saturated (white).
|
|
227
308
|
|
|
228
309
|
## xy (get and set)
|
|
229
|
-
The xy values represent x and y coordinates of a color in CIE color space. The first value is the x coordinate and the second value is the y coordinate. Both x and y must be between 0 and 1, and will be rounded to 4 decimal places by the Hue bridge,
|
|
310
|
+
The xy values represent x and y coordinates of a color in CIE color space. The first value is the x coordinate and the second value is the y coordinate. Both x and y must be between 0 and 1, and will be rounded to 4 decimal places by the Hue bridge, e.g.: 0.666666 becomes 0.6667.
|
|
230
311
|
If the specified coordinates are not in the CIE color space, the closest color to the coordinates will be chosen.
|
|
231
312
|
|
|
232
313
|
When sending the xy array, you **must** url encode the comma to %2c (or %2C). Here is an example for "xy":\[0.25,0.52\] :
|
|
@@ -273,17 +354,32 @@ Increments or decrements the value of the xy. xy_inc is ignored if the xy attri
|
|
|
273
354
|
Exact use unknown. Looks like it reflects an operating mode. Observed values are: homeautomation
|
|
274
355
|
|
|
275
356
|
|
|
276
|
-
##
|
|
277
|
-
|
|
357
|
+
## Common Config Keywords for Sensors
|
|
358
|
+
Sensors can have their state and config updated by the api. You can also update other parameters.
|
|
359
|
+
|
|
360
|
+
The state and config capabilities are dependent on the sensor type. The most common config keywords for sensors are:
|
|
361
|
+
|
|
362
|
+
on, battery, reachable, alert, tholddark, tholdoffset, sensitivity, sensitivitymax, ledindication, usertest
|
|
363
|
+
|
|
364
|
+
For the full documentation of all keywords, see the [API documentation for sensors](https://developers.meethue.com/develop/hue-api/5-sensors-api/).
|
|
365
|
+
|
|
366
|
+
## on (get and set)
|
|
367
|
+
Turn a sensor on or off. On=true, Off=false. This is the same as enabling or disabling the sensor in the Hue app.
|
|
368
|
+
Valid for Daylight, Geofence, ZLLPresence, ZLLLightLevel, ZLLTemperature, ZLLSwitch and likely more.
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
|
|
278
372
|
|
|
279
373
|
## API Documentation
|
|
280
374
|
For full details of the control capabilities, please see the [official Philips Hue API reference](https://developers.meethue.com/develop/hue-api/).
|
|
281
|
-
|
|
375
|
+
|
|
376
|
+
An [alternative unofficial reference](http://www.burgestrand.se/hue-api/), somewhat outdated, also exists.
|
|
282
377
|
|
|
283
378
|
|
|
284
|
-
# Finding your Light or
|
|
285
|
-
You need to know the
|
|
286
|
-
|
|
379
|
+
# Finding your Light, Group, Sensor or other Resource ids
|
|
380
|
+
You need to know the id of the resource (light, group, sensor etc) that you wish to control.
|
|
381
|
+
Ids can be either a numeric integer (generally starting at 0) or a string, depending on the resource.
|
|
382
|
+
Go to http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/resourcename. The resourcename is lights, groups, sensors, etc. You will see a JSON response that looks like this (truncated here for brevity, only lights is shown. Groups is similar):
|
|
287
383
|
```
|
|
288
384
|
{"1":{"state":{"on":false,"bri":198,"hue":5360,"sat":192,"effect":"none","xy":[0.5330,0.3870],"ct":500," ...
|
|
289
385
|
```
|
|
@@ -291,11 +387,11 @@ Copy and paste the response into a text editor and format as JSON (or use an onl
|
|
|
291
387
|
```
|
|
292
388
|
... ,"type":"Extended color light","name":"Desk lamp","modelid":"LCT012", ...
|
|
293
389
|
```
|
|
294
|
-
Go backwards in the text until you find the keyword **state**, this is at the start of the JSON text for the light. The light id is the
|
|
390
|
+
Go backwards in the text until you find the keyword **state**, this is at the start of the JSON text for the light. The light id is the value immediately before state. In this case, my light id is 31:
|
|
295
391
|
```
|
|
296
392
|
... ,"31":{"state":{"on":true,"bri":100,"hue":65396 ...
|
|
297
393
|
```
|
|
298
394
|
|
|
299
|
-
Use the same method for groups to find the group id of the room you wish to control. Note that group id 0 is a special group containing all lights in the system, and is not returned by the ‘get all groups’ command. Group 0 is not visible, and cannot be created, modified or deleted using the API, but group 0 can be controlled by the API.
|
|
395
|
+
Use the same method for other resources groups to find the group id of the room you wish to control. Note that group id 0 is a special group containing all lights in the system, and is not returned by the ‘get all groups’ command. Group 0 is not visible, and cannot be created, modified or deleted using the API, but group 0 can be controlled by the API.
|
|
300
396
|
|
|
301
397
|
|
package/hueget.js
CHANGED
|
@@ -61,19 +61,35 @@ app.use('/api/' + options.username, (req, res) => {
|
|
|
61
61
|
const resource = (urlPathParts[1] || '').toLowerCase();
|
|
62
62
|
const id = urlPathParts[2];
|
|
63
63
|
const command = (urlPathParts[3] || '').toLowerCase();
|
|
64
|
-
|
|
65
|
-
//
|
|
66
|
-
|
|
64
|
+
var commandParts = command.split('?'); // split on ? if exists, the put command is the first array index
|
|
65
|
+
var putCommand = commandParts[0]; // the possible PUT command
|
|
66
|
+
/*
|
|
67
|
+
// Debug:
|
|
68
|
+
console.log('commandParts[0]', commandParts[0] );
|
|
69
|
+
console.log('commandParts[1]', commandParts[1] );
|
|
70
|
+
console.log('resource', resource );
|
|
71
|
+
console.log('id', id );
|
|
72
|
+
console.log('command', command );
|
|
73
|
+
console.log('putCommand', putCommand );
|
|
74
|
+
*/
|
|
67
75
|
|
|
68
76
|
// throw error if resource is not supported
|
|
69
|
-
|
|
70
|
-
|
|
77
|
+
// more resources added in v1.0.0
|
|
78
|
+
const supportedResources = ['lights','groups','schedules','scenes','sensors','rules','resourcelinks','capabilities'];
|
|
79
|
+
//console.log(JSON.stringify(supportedResources));
|
|
80
|
+
//console.log(resource, supportedResources.indexOf(resource));
|
|
81
|
+
if (supportedResources.indexOf(resource) < 0) {
|
|
82
|
+
throw errPrefix + 'unknown resource "' + resource + '", expecting one of ' + JSON.stringify(supportedResources).replace('[', '').replace(']', '').replace('"', '') + ': "' + req.url + '"';
|
|
71
83
|
}
|
|
72
84
|
|
|
73
|
-
// get the id, throw error if not a number
|
|
74
|
-
|
|
85
|
+
// get the id, throw error if not a number only for resources that need a numeric id
|
|
86
|
+
const resourcesWithIdInteger = ['lights','groups','sensors','rules','schedules'];
|
|
87
|
+
if (resourcesWithIdInteger.indexOf(resource) > 0) {
|
|
88
|
+
if ( (isNaN((id || '')) || (id == '')) ){ throw errPrefix + 'id "' + id + '" is not an integer: "' + req.url + '"';}
|
|
89
|
+
}
|
|
75
90
|
|
|
76
91
|
// throw error if unexpected quantity of url components
|
|
92
|
+
// supported quantity of url components: up to 3
|
|
77
93
|
// allowed:
|
|
78
94
|
// /<resource>
|
|
79
95
|
// /<resource>/<id>
|
|
@@ -82,45 +98,27 @@ app.use('/api/' + options.username, (req, res) => {
|
|
|
82
98
|
throw errPrefix + (urlPathParts.length - 1).toString() + ' url path components found, expecting maximum 3: "' + req.url + '"';
|
|
83
99
|
}
|
|
84
100
|
|
|
85
|
-
// throw error if unexpected command
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
var expectedCommand;
|
|
89
|
-
if (urlPathParts.length > 3) {
|
|
90
|
-
switch(resource) {
|
|
91
|
-
case 'lights':
|
|
92
|
-
expectedCommand = 'state'
|
|
93
|
-
break;
|
|
94
|
-
case 'groups':
|
|
95
|
-
expectedCommand = 'action'
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
//console.log('expectedCommand', expectedCommand );
|
|
99
|
-
// toggle is a special case, raise error for anything else that does not fit the syntax
|
|
100
|
-
if (command != 'toggle') {
|
|
101
|
-
if (!command.startsWith(expectedCommand)) { throw errPrefix + 'unknown command "' + command + '", expecting "' + expectedCommand + '": "' + req.url + '"'; }
|
|
102
|
-
if (!command.includes(expectedCommand + '?')) { throw errPrefix + 'query character "?" missing in "' + command + '", expecting "' + expectedCommand + '?<query>": "' + req.url + '"'; }
|
|
103
|
-
if (command.endsWith(expectedCommand + '?')) { throw errPrefix + 'query missing in "' + command + '", expecting "' + expectedCommand + '?<query>": "' + req.url + '"'; }
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
101
|
+
// DEPRECATED throw error if unexpected command DEPRECATED
|
|
102
|
+
// as of 1.0.0, do not test the commands, as they vary a lot.
|
|
103
|
+
// So allow the hue bridge to reject a command if incorrect.
|
|
107
104
|
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
if (
|
|
111
|
-
|
|
105
|
+
// throw error if unexpected quantity of ? delimiters
|
|
106
|
+
// get the commandParts parts, identified by the presence of a ? delimiter, throw error if unexpected quantity of delimiters exist
|
|
107
|
+
if ((commandParts.length > 1) && (commandParts.length != 2) ) {
|
|
108
|
+
throw errPrefix + (commandParts.length - 1).toString() + ' "?" delimiters found, expecting 1: "' + req.url + '"';
|
|
112
109
|
}
|
|
113
110
|
|
|
114
111
|
|
|
115
112
|
|
|
116
|
-
// if a
|
|
113
|
+
// if a commandParts[1] (the parameters) exists, split the parameters into name-value pairs on &, loop and construct a json result
|
|
114
|
+
// the existance of a query part generates a dataObj, which determines whether a PUT or a GEt is used
|
|
117
115
|
var dataObj;
|
|
118
|
-
if (
|
|
116
|
+
if (commandParts.length > 1){
|
|
119
117
|
var result = '{';
|
|
120
118
|
errPrefix = 'url query syntax error, ';
|
|
121
|
-
|
|
119
|
+
commandParts[1].split('&').forEach(function(nameValuePair) {
|
|
122
120
|
|
|
123
|
-
//console.log('nameValuePair', nameValuePair );
|
|
121
|
+
//console.log('nameValuePair', nameValuePair );}
|
|
124
122
|
|
|
125
123
|
const pair = nameValuePair.split('=');
|
|
126
124
|
if (pair.length != 2){ throw errPrefix + (pair.length - 1).toString() + ' "=" delimiters found, expecting 1: "' + nameValuePair + '"';}
|
|
@@ -152,34 +150,45 @@ app.use('/api/' + options.username, (req, res) => {
|
|
|
152
150
|
// PUT http://192.168.0.101/api/<username>/lights/31/state --data "{""on"":true}"
|
|
153
151
|
var url = 'http://' + options.ip + '/api/' + options.username + '/' + resource;
|
|
154
152
|
if (id) { url = url + '/' + id; } // add id if supplied
|
|
153
|
+
|
|
155
154
|
|
|
156
155
|
|
|
157
156
|
// special handling for toggle command, this toggles a light or group state
|
|
157
|
+
// lights: http://localhost:3000/api/<username>/lights/31/toggle
|
|
158
|
+
// groups: http://localhost:3000/api/<username>/groups/0/toggle
|
|
159
|
+
// sensors: http://localhost:3000/api/<username>/sensors/15/toggle
|
|
158
160
|
if (command == 'toggle') {
|
|
159
161
|
console.log('toggling current state')
|
|
160
162
|
// Get actual state
|
|
161
163
|
console.log('sending GET: %s', url);
|
|
162
164
|
axios.get(url)
|
|
163
165
|
.then(response => {
|
|
164
|
-
// for lights
|
|
165
|
-
// for groups,
|
|
166
|
+
// for lights /lights/<id> state = on true/false
|
|
167
|
+
// for groups, /groups/<id> state = all_on true/false
|
|
168
|
+
// for sensors, /sensors/<id> config = on true/false
|
|
166
169
|
switch(resource) {
|
|
167
170
|
case 'lights':
|
|
168
171
|
console.log('GET response:', response.status, response.statusText, "state:on="+response.data["state"]["on"] );
|
|
169
172
|
state = !response.data["state"]["on"] // get the current on state , as a boolean, and invert it
|
|
170
|
-
|
|
173
|
+
toggleCommand = 'state'
|
|
171
174
|
break;
|
|
172
175
|
case 'groups':
|
|
173
176
|
console.log('GET response:', response.status, response.statusText, "state:all_on="+response.data["state"]["all_on"] );
|
|
174
177
|
state = !response.data["state"]["all_on"] // get the current all_on state, as a boolean, and invert it
|
|
175
|
-
|
|
178
|
+
toggleCommand = 'action'
|
|
179
|
+
break;
|
|
180
|
+
case 'sensors':
|
|
181
|
+
console.log('GET response:', response.status, response.statusText, "config:on="+response.data["config"]["on"] );
|
|
182
|
+
state = !response.data["config"]["on"] // get the current on state, as a boolean, and invert it
|
|
183
|
+
toggleCommand = 'config'
|
|
176
184
|
break;
|
|
177
|
-
|
|
185
|
+
}
|
|
178
186
|
// toggle light or group state
|
|
179
|
-
// lights:
|
|
180
|
-
// groups:
|
|
187
|
+
// lights: http://localhost:3000/api/<username>/lights/31/state?on=true
|
|
188
|
+
// groups: http://localhost:3000/api/<username>/groups/0/action?on=true
|
|
189
|
+
// sensors: http://localhost:3000/api/<username>/sensors/15/config?on=true
|
|
181
190
|
console.log('sending PUT: %s%s', url + '/' + "state?on=", state.toString() || '');
|
|
182
|
-
axios.put(url + '/' +
|
|
191
|
+
axios.put(url + '/' + toggleCommand,'{"on":' + state.toString() + '}')
|
|
183
192
|
.then(response => {
|
|
184
193
|
console.log('PUT response:', response.status, response.statusText, JSON.stringify(response.data) );
|
|
185
194
|
res.json(response.data);
|
|
@@ -200,8 +209,8 @@ app.use('/api/' + options.username, (req, res) => {
|
|
|
200
209
|
// normal handling for non-toggle commands
|
|
201
210
|
} else {
|
|
202
211
|
if (dataObj){
|
|
203
|
-
console.log('sending PUT: %s %s', url + '/' +
|
|
204
|
-
axios.put(url + '/' +
|
|
212
|
+
console.log('sending PUT: %s %s', url + '/' + putCommand, dataObj || '');
|
|
213
|
+
axios.put(url + '/' + putCommand, dataObj)
|
|
205
214
|
.then(response => {
|
|
206
215
|
console.log('PUT response:', response.status, response.statusText, JSON.stringify(response.data) );
|
|
207
216
|
res.json(response.data);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hueget",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A simple API that converts the Philips Hue API PUT to GET requests, allowing control of Philips Hue lights via http GET requests",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A simple API that converts the Philips Hue API PUT to GET requests, allowing control of Philips Hue lights, groups, sensors and more via http GET requests",
|
|
5
5
|
"main": "hueget.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "echo \"Error: no test specified\" && exit 1"
|