hueget 0.6.6 → 0.7.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.
- package/CHANGELOG.md +10 -0
- package/README.md +20 -6
- package/hueget.js +69 -16
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ See the [Readme file](https://github.com/jsiegenthaler/hueget/blob/master/README
|
|
|
4
4
|
|
|
5
5
|
# Bug Fixes and Improvements
|
|
6
6
|
|
|
7
|
+
## 0.7.1 (2024-04-06)
|
|
8
|
+
* Bumped dependencies: "axios": "^1.6.8"
|
|
9
|
+
* Bumped dependencies: "express": "^4.19.2"
|
|
10
|
+
* Bumped dependencies: "stdio": "^2.1.3"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## 0.7.0 (2024-01-06)
|
|
14
|
+
* Added toggle capability for lights and groups
|
|
15
|
+
* Bumped dependencies: "axios": "^1.6.5"
|
|
16
|
+
|
|
7
17
|
## 0.6.6 (2023-11-27)
|
|
8
18
|
* Added some more README.md improvements
|
|
9
19
|
|
package/README.md
CHANGED
|
@@ -28,6 +28,9 @@ Flash your lights in the entire house when the doorbell rings. I have a Shelly1
|
|
|
28
28
|
## Control Hue Lights directly from Shelly Motion Sensors
|
|
29
29
|
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
30
|
|
|
31
|
+
## 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 ```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
|
## Be Home Soon Alert
|
|
32
35
|
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.
|
|
33
36
|
|
|
@@ -81,7 +84,7 @@ $ node /home/pi/node_modules/hueget/hueget.js -i 192.168.0.101 -u UBxWZChHseyjeF
|
|
|
81
84
|
```
|
|
82
85
|
A successful start of hueget (using the above command to specify ip address 192.168.0.100 and port 1234) will show:
|
|
83
86
|
```
|
|
84
|
-
hueget v0.
|
|
87
|
+
hueget v0.7.0
|
|
85
88
|
commands will be sent to 192.168.0.101 with username UBxWZChHseyjeFwAkwgbdQ08x9XASWpanZZVg-mj
|
|
86
89
|
listening on port 1234
|
|
87
90
|
```
|
|
@@ -144,6 +147,7 @@ Examples:
|
|
|
144
147
|
* Turn light 31 on at 50% brightness: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/lights/31/state?on=true&bri=50
|
|
145
148
|
* Turn light 31 on at 100% brightness: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/lights/31/state?on=true&bri=100
|
|
146
149
|
* Turn light 31 on at 100% brightness, 0.5,0.6 xy: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/lights/31/state?on=true&bri=100&xy=[0.5%2c0.6]
|
|
150
|
+
* Toggle light 31: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/lights/31/toggle
|
|
147
151
|
* Identify light 31 with a single blink: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/lights/31/state?alert=select
|
|
148
152
|
* Identify light 31 with 15 seconds of blinking: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/lights/31/state?alert=lselect
|
|
149
153
|
|
|
@@ -151,12 +155,14 @@ Examples:
|
|
|
151
155
|
### Group 0 (a special group for all lights in your home)
|
|
152
156
|
* Turn group 0 on: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/0/action?on=true
|
|
153
157
|
* Turn group 0 off: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/0/action?on=false
|
|
158
|
+
* Toggle group 0: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/0/toggle
|
|
154
159
|
* Identify group 0 with 15 seconds of blinking: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/0/action?alert=lselect
|
|
155
160
|
|
|
156
161
|
|
|
157
162
|
### Group 2 (example)
|
|
158
163
|
* Turn group 2 on: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/2/action?on=true
|
|
159
164
|
* Turn group 2 off: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/2/action?on=false
|
|
165
|
+
* Toggle group 2: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/2/toggle
|
|
160
166
|
* Turn group 2 on at 50% brightness: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/2/action?on=true&bri=50
|
|
161
167
|
* Turn group 2 on at 100% brightness: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/2/action?on=true&bri=100
|
|
162
168
|
* Turn group 2 on at 100% brightness, 0.5,0.6 xy: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/2/state?on=true&bri=100&xy=[0.5%2c0.6]
|
|
@@ -165,7 +171,15 @@ Examples:
|
|
|
165
171
|
|
|
166
172
|
Groups are collections of lights, and are used for Rooms and Zones in the Hue app.
|
|
167
173
|
|
|
168
|
-
|
|
174
|
+
## Special Commands
|
|
175
|
+
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 a group, allowing you to toggle the light/group state with a single URL.
|
|
176
|
+
|
|
177
|
+
Syntax:
|
|
178
|
+
* Toggle light 1: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/lights/1/toggle
|
|
179
|
+
* Toggle group 2: http://192.168.0.101:3000/api/yourPhilipsHueBridgeUsername/groups/2/toggle
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
## Supported Keywords
|
|
169
183
|
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.
|
|
170
184
|
|
|
171
185
|
The full JSON response for a light looks like this:
|
|
@@ -178,12 +192,12 @@ The full JSON response for a group looks like this:
|
|
|
178
192
|
{"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"}}
|
|
179
193
|
```
|
|
180
194
|
The most common action keywords for state or group are:
|
|
181
|
-
on, bri, hue, sat, effect, xy, ct, alert, colormode, mode (lights only)
|
|
195
|
+
on, bri, hue, sat, effect, xy, ct, alert, colormode, mode (lights only).
|
|
182
196
|
More keywords exist, see the [API documentation](#api-documentation).
|
|
183
197
|
|
|
184
198
|
## on (get and set)
|
|
185
199
|
Turn a light on or off. On=true, Off=false.
|
|
186
|
-
Valid for light or group.
|
|
200
|
+
Valid for light or group. A group also supports all_on and any_on.
|
|
187
201
|
|
|
188
202
|
## bri (get and set)
|
|
189
203
|
The brightness value to set the light to. Brightness is a scale from 1 (the minimum the light is capable of) to 254 (the maximum).
|
|
@@ -247,7 +261,7 @@ See the [API documentation](#api-documentation).
|
|
|
247
261
|
|
|
248
262
|
## API Documentation
|
|
249
263
|
For full details of the control capabilities, please see the [official Philips Hue API reference](https://developers.meethue.com/develop/hue-api/).
|
|
250
|
-
An [alternative unoffical reference](http://www.burgestrand.se/hue-api/), somewhat outdated also exists.
|
|
264
|
+
An [alternative unoffical reference](http://www.burgestrand.se/hue-api/), somewhat outdated, also exists.
|
|
251
265
|
|
|
252
266
|
|
|
253
267
|
# Finding your Light or Group ids
|
|
@@ -265,6 +279,6 @@ Go backwards in the text until you find the keyword **state**, this is at the st
|
|
|
265
279
|
... ,"31":{"state":{"on":true,"bri":100,"hue":65396 ...
|
|
266
280
|
```
|
|
267
281
|
|
|
268
|
-
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.
|
|
282
|
+
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.
|
|
269
283
|
|
|
270
284
|
|
package/hueget.js
CHANGED
|
@@ -96,9 +96,12 @@ app.use('/api/' + options.username, (req, res) => {
|
|
|
96
96
|
break;
|
|
97
97
|
}
|
|
98
98
|
//console.log('expectedCommand', expectedCommand );
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
|
|
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
|
+
}
|
|
102
105
|
}
|
|
103
106
|
|
|
104
107
|
|
|
@@ -137,41 +140,91 @@ app.use('/api/' + options.username, (req, res) => {
|
|
|
137
140
|
result = result + ',"' + pair[0] + '":' + pairValue;
|
|
138
141
|
});
|
|
139
142
|
result = result.replace('{,','{') + '}'; // clean up, add brackets
|
|
140
|
-
|
|
143
|
+
console.log('result', result );
|
|
141
144
|
dataObj = JSON.parse(result);
|
|
142
145
|
}
|
|
143
146
|
|
|
144
147
|
|
|
148
|
+
|
|
149
|
+
|
|
145
150
|
// if a dataObj exists, send PUT; otherwise, send a GET
|
|
146
151
|
// GET http://192.168.0.101/api/<username>/lights/31
|
|
147
152
|
// PUT http://192.168.0.101/api/<username>/lights/31/state --data "{""on"":true}"
|
|
148
153
|
var url = 'http://' + options.ip + '/api/' + options.username + '/' + resource;
|
|
149
154
|
if (id) { url = url + '/' + id; } // add id if supplied
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
// special handling for toggle command, this toggles a light or group state
|
|
158
|
+
if (command == 'toggle') {
|
|
159
|
+
console.log('toggling current state')
|
|
160
|
+
// Get actual state
|
|
161
|
+
console.log('sending GET: %s', url);
|
|
162
|
+
axios.get(url)
|
|
153
163
|
.then(response => {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
164
|
+
// for lights /lights/<id> state = on true/false
|
|
165
|
+
// for groups, /groups/<id> state = all_on true/false
|
|
166
|
+
switch(resource) {
|
|
167
|
+
case 'lights':
|
|
168
|
+
console.log('GET response:', response.status, response.statusText, "state:on="+response.data["state"]["on"] );
|
|
169
|
+
state = !response.data["state"]["on"] // get the current on state , as a boolean, and invert it
|
|
170
|
+
expectedCommand = 'state'
|
|
171
|
+
break;
|
|
172
|
+
case 'groups':
|
|
173
|
+
console.log('GET response:', response.status, response.statusText, "state:all_on="+response.data["state"]["all_on"] );
|
|
174
|
+
state = !response.data["state"]["all_on"] // get the current all_on state, as a boolean, and invert it
|
|
175
|
+
expectedCommand = 'action'
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
// toggle light or group state
|
|
179
|
+
// lights: http://localhost:3000/api/<username>/lights/31/state?on=true
|
|
180
|
+
// groups: http://localhost:3000/api/<username>/groups/0/action?on=true
|
|
181
|
+
console.log('sending PUT: %s%s', url + '/' + "state?on=", state.toString() || '');
|
|
182
|
+
axios.put(url + '/' + expectedCommand,'{"on":' + state.toString() + '}')
|
|
183
|
+
.then(response => {
|
|
184
|
+
console.log('PUT response:', response.status, response.statusText, JSON.stringify(response.data) );
|
|
185
|
+
res.json(response.data);
|
|
186
|
+
})
|
|
187
|
+
.catch(error => {
|
|
188
|
+
const errText = error.syscall + ' ' + error.code + ' ' + error.address + ':' + error.port;
|
|
189
|
+
console.log('PUT error:', errText);
|
|
190
|
+
res.json({ error: errText });
|
|
191
|
+
});
|
|
192
|
+
})
|
|
157
193
|
.catch(error => {
|
|
158
194
|
const errText = error.syscall + ' ' + error.code + ' ' + error.address + ':' + error.port;
|
|
159
|
-
console.log('
|
|
195
|
+
console.log('GET error:', errText);
|
|
160
196
|
res.json({ error: errText });
|
|
161
197
|
});
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
// normal handling for non-toggle commands
|
|
201
|
+
} else {
|
|
202
|
+
if (dataObj){
|
|
203
|
+
console.log('sending PUT: %s %s', url + '/' + expectedCommand, dataObj || '');
|
|
204
|
+
axios.put(url + '/' + expectedCommand, dataObj)
|
|
165
205
|
.then(response => {
|
|
166
|
-
console.log('
|
|
206
|
+
console.log('PUT response:', response.status, response.statusText, JSON.stringify(response.data) );
|
|
167
207
|
res.json(response.data);
|
|
168
208
|
})
|
|
169
209
|
.catch(error => {
|
|
170
210
|
const errText = error.syscall + ' ' + error.code + ' ' + error.address + ':' + error.port;
|
|
171
|
-
console.log('
|
|
211
|
+
console.log('PUT error:', errText);
|
|
172
212
|
res.json({ error: errText });
|
|
173
213
|
});
|
|
214
|
+
} else {
|
|
215
|
+
console.log('sending GET: %s', url);
|
|
216
|
+
axios.get(url)
|
|
217
|
+
.then(response => {
|
|
218
|
+
console.log('GET response:', response.status, response.statusText, JSON.stringify(response.data) );
|
|
219
|
+
res.json(response.data);
|
|
220
|
+
})
|
|
221
|
+
.catch(error => {
|
|
222
|
+
const errText = error.syscall + ' ' + error.code + ' ' + error.address + ':' + error.port;
|
|
223
|
+
console.log('GET error:', errText);
|
|
224
|
+
res.json({ error: errText });
|
|
225
|
+
});
|
|
174
226
|
}
|
|
227
|
+
}
|
|
175
228
|
return;
|
|
176
229
|
|
|
177
230
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hueget",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
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",
|
|
5
5
|
"main": "hueget.js",
|
|
6
6
|
"scripts": {
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"author": "Jochen Siegenthaler (https://github.com/jsiegenthaler)",
|
|
26
26
|
"license": "ISC",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"axios": "^1.6.
|
|
29
|
-
"express": "^4.
|
|
30
|
-
"stdio": "^2.1.
|
|
28
|
+
"axios": "^1.6.8",
|
|
29
|
+
"express": "^4.19.2",
|
|
30
|
+
"stdio": "^2.1.3"
|
|
31
31
|
},
|
|
32
32
|
"engines": {
|
|
33
33
|
"node": "^20"
|