node-red-contrib-huemagic 3.0.0 → 4.0.3
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/README.md +764 -603
- package/examples/Hue Bridge.json +189 -35
- package/examples/Hue Brightness.json +124 -14
- package/examples/Hue Buttons.json +88 -0
- package/examples/Hue Group.json +575 -63
- package/examples/Hue Light.json +805 -58
- package/examples/Hue Magic.json +69 -24
- package/examples/Hue Motion.json +110 -42
- package/examples/Hue Rules.json +105 -37
- package/examples/Hue Scene.json +145 -28
- package/examples/Hue Temperature.json +124 -14
- package/huemagic/animations/019-christmas.json +30 -0
- package/huemagic/animations/020-superhero.json +56 -0
- package/huemagic/animations/021-neoncity.json +52 -0
- package/huemagic/animations/previews/006-fireplace.gif +0 -0
- package/huemagic/animations/previews/013-strobo.gif +0 -0
- package/huemagic/animations/previews/014-randomrainbow.gif +0 -0
- package/huemagic/animations/previews/016-milkyway.gif +0 -0
- package/huemagic/animations/previews/018-forest.gif +0 -0
- package/huemagic/animations/previews/019-christmas.gif +0 -0
- package/huemagic/animations/previews/020-superhero.gif +0 -0
- package/huemagic/animations/previews/021-neoncity.gif +0 -0
- package/huemagic/hue-bridge-config.html +105 -61
- package/huemagic/hue-bridge-config.js +631 -319
- package/huemagic/hue-bridge.html +41 -21
- package/huemagic/hue-bridge.js +190 -396
- package/huemagic/hue-brightness.html +127 -59
- package/huemagic/hue-brightness.js +111 -55
- package/huemagic/hue-buttons.html +197 -0
- package/huemagic/hue-buttons.js +158 -0
- package/huemagic/hue-group.html +137 -66
- package/huemagic/hue-group.js +387 -403
- package/huemagic/hue-light.html +132 -64
- package/huemagic/hue-light.js +544 -378
- package/huemagic/hue-magic.html +36 -20
- package/huemagic/hue-magic.js +49 -27
- package/huemagic/hue-motion.html +127 -59
- package/huemagic/hue-motion.js +105 -101
- package/huemagic/hue-rules.html +121 -50
- package/huemagic/hue-rules.js +89 -63
- package/huemagic/hue-scene.html +95 -114
- package/huemagic/hue-scene.js +64 -95
- package/huemagic/hue-temperature.html +127 -59
- package/huemagic/hue-temperature.js +120 -56
- package/huemagic/icons/hue-bridge.png +0 -0
- package/huemagic/icons/hue-bridge.svg +3 -0
- package/huemagic/icons/hue-brightness.png +0 -0
- package/huemagic/icons/hue-brightness.svg +11 -0
- package/huemagic/icons/hue-buttons.png +0 -0
- package/huemagic/icons/hue-buttons.svg +4 -0
- package/huemagic/icons/hue-group.png +0 -0
- package/huemagic/icons/hue-group.svg +12 -0
- package/huemagic/icons/hue-light.png +0 -0
- package/huemagic/icons/hue-light.svg +3 -0
- package/huemagic/icons/hue-magic.png +0 -0
- package/huemagic/icons/hue-magic.svg +3 -0
- package/huemagic/icons/hue-motion.png +0 -0
- package/huemagic/icons/hue-motion.svg +9 -0
- package/huemagic/icons/hue-rules.png +0 -0
- package/huemagic/icons/hue-rules.svg +4 -0
- package/huemagic/icons/hue-scene.png +0 -0
- package/huemagic/icons/hue-scene.svg +5 -0
- package/huemagic/icons/hue-temperature.png +0 -0
- package/huemagic/icons/hue-temperature.svg +7 -0
- package/huemagic/locales/de/hue-bridge-config.html +17 -12
- package/huemagic/locales/de/hue-bridge-config.json +7 -5
- package/huemagic/locales/de/hue-bridge.html +64 -145
- package/huemagic/locales/de/hue-bridge.json +6 -17
- package/huemagic/locales/de/hue-brightness.html +50 -50
- package/huemagic/locales/de/hue-brightness.json +6 -5
- package/huemagic/locales/de/hue-buttons.html +58 -0
- package/huemagic/locales/de/{hue-button.json → hue-buttons.json} +7 -11
- package/huemagic/locales/de/hue-group.html +46 -122
- package/huemagic/locales/de/hue-group.json +5 -5
- package/huemagic/locales/de/hue-light.html +68 -116
- package/huemagic/locales/de/hue-light.json +5 -5
- package/huemagic/locales/de/hue-magic.html +65 -57
- package/huemagic/locales/de/hue-magic.json +2 -1
- package/huemagic/locales/de/hue-motion.html +47 -50
- package/huemagic/locales/de/hue-motion.json +5 -5
- package/huemagic/locales/de/hue-rules.html +68 -73
- package/huemagic/locales/de/hue-rules.json +5 -2
- package/huemagic/locales/de/hue-scene.html +23 -32
- package/huemagic/locales/de/hue-scene.json +5 -2
- package/huemagic/locales/de/hue-temperature.html +51 -48
- package/huemagic/locales/de/hue-temperature.json +6 -5
- package/huemagic/locales/en-US/hue-bridge-config.html +17 -12
- package/huemagic/locales/en-US/hue-bridge-config.json +5 -3
- package/huemagic/locales/en-US/hue-bridge.html +64 -145
- package/huemagic/locales/en-US/hue-bridge.json +5 -16
- package/huemagic/locales/en-US/hue-brightness.html +50 -50
- package/huemagic/locales/en-US/hue-brightness.json +5 -2
- package/huemagic/locales/en-US/hue-buttons.html +58 -0
- package/huemagic/locales/en-US/{hue-button.json → hue-buttons.json} +6 -4
- package/huemagic/locales/en-US/hue-group.html +46 -122
- package/huemagic/locales/en-US/hue-group.json +4 -2
- package/huemagic/locales/en-US/hue-light.html +68 -116
- package/huemagic/locales/en-US/hue-light.json +4 -2
- package/huemagic/locales/en-US/hue-magic.html +65 -57
- package/huemagic/locales/en-US/hue-magic.json +3 -1
- package/huemagic/locales/en-US/hue-motion.html +47 -50
- package/huemagic/locales/en-US/hue-motion.json +4 -2
- package/huemagic/locales/en-US/hue-rules.html +68 -73
- package/huemagic/locales/en-US/hue-rules.json +5 -2
- package/huemagic/locales/en-US/hue-scene.html +23 -32
- package/huemagic/locales/en-US/hue-scene.json +5 -2
- package/huemagic/locales/en-US/hue-temperature.html +51 -48
- package/huemagic/locales/en-US/hue-temperature.json +5 -2
- package/huemagic/utils/api.js +290 -0
- package/huemagic/utils/color.js +382 -0
- package/{utils → huemagic/utils}/merge.js +4 -6
- package/huemagic/utils/messages.js +447 -0
- package/package.json +9 -15
- package/examples/Hue Button.json +0 -40
- package/examples/Hue Switch.json +0 -40
- package/examples/Hue Tap.json +0 -40
- package/huemagic/hue-button.html +0 -132
- package/huemagic/hue-button.js +0 -143
- package/huemagic/hue-switch.html +0 -132
- package/huemagic/hue-switch.js +0 -163
- package/huemagic/hue-tap.html +0 -132
- package/huemagic/hue-tap.js +0 -123
- package/huemagic/icons/hue-button.png +0 -0
- package/huemagic/icons/hue-switch.png +0 -0
- package/huemagic/icons/hue-tap.png +0 -0
- package/huemagic/locales/de/hue-button.html +0 -64
- package/huemagic/locales/de/hue-switch.html +0 -64
- package/huemagic/locales/de/hue-switch.json +0 -35
- package/huemagic/locales/de/hue-tap.html +0 -55
- package/huemagic/locales/de/hue-tap.json +0 -27
- package/huemagic/locales/en-US/hue-button.html +0 -64
- package/huemagic/locales/en-US/hue-switch.html +0 -64
- package/huemagic/locales/en-US/hue-switch.json +0 -35
- package/huemagic/locales/en-US/hue-tap.html +0 -55
- package/huemagic/locales/en-US/hue-tap.json +0 -27
- package/utils/color.js +0 -9
- package/utils/messages.js +0 -658
- package/utils/rgb.js +0 -188
package/huemagic/hue-group.js
CHANGED
|
@@ -6,23 +6,21 @@ module.exports = function(RED)
|
|
|
6
6
|
{
|
|
7
7
|
RED.nodes.createNode(this, config);
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
let path = require('path');
|
|
12
|
-
let { HueGroupMessage } = require('../utils/messages');
|
|
13
|
-
var universalMode = false;
|
|
9
|
+
const scope = this;
|
|
10
|
+
const bridge = RED.nodes.getNode(config.bridge);
|
|
14
11
|
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
// EXPORT CONFIG
|
|
13
|
+
this.exportedConfig = config;
|
|
14
|
+
|
|
15
|
+
// SAVE FUTURE PATCH
|
|
16
|
+
this.futurePatchState = {};
|
|
17
|
+
|
|
18
|
+
// SAVE LAST COMMAND
|
|
19
|
+
this.lastCommand = null;
|
|
18
20
|
|
|
19
21
|
// HELPER
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
let hexRGB = require('hex-rgb');
|
|
23
|
-
let colornames = require("colornames");
|
|
24
|
-
let getColors = require('get-image-colors');
|
|
25
|
-
let {randomHexColor} = require('../utils/color');
|
|
22
|
+
const colorUtils = require('./utils/color');
|
|
23
|
+
const merge = require('./utils/merge');
|
|
26
24
|
|
|
27
25
|
//
|
|
28
26
|
// CHECK CONFIG
|
|
@@ -36,7 +34,6 @@ module.exports = function(RED)
|
|
|
36
34
|
// UNIVERSAL MODE?
|
|
37
35
|
if(!config.groupid)
|
|
38
36
|
{
|
|
39
|
-
universalMode = true;
|
|
40
37
|
this.status({fill: "grey", shape: "dot", text: "hue-group.node.universal"});
|
|
41
38
|
}
|
|
42
39
|
|
|
@@ -48,163 +45,230 @@ module.exports = function(RED)
|
|
|
48
45
|
}
|
|
49
46
|
|
|
50
47
|
//
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
if(!config.groupid && config.universalevents && config.universalevents == true) { bridge.events.on('group', function(group) { scope.receivedUpdates(group) }); }
|
|
54
|
-
|
|
55
|
-
//
|
|
56
|
-
// RECEIVED UPDATES
|
|
57
|
-
this.receivedUpdates = function(group)
|
|
48
|
+
// SUBSCRIBE TO UPDATES FROM THE BRIDGE
|
|
49
|
+
bridge.subscribe("group", config.groupid, function(info)
|
|
58
50
|
{
|
|
59
|
-
|
|
60
|
-
var brightnessNotice = (hueGroup.msg.payload.brightness > -1) ? RED._("hue-group.node.brightness",{percent: hueGroup.msg.payload.brightness}) : "";
|
|
61
|
-
|
|
62
|
-
// HAS FUTURE STATE?
|
|
63
|
-
if(futureState != null && group.anyOn)
|
|
64
|
-
{
|
|
65
|
-
scope.applyCommands(futureState, null, null);
|
|
66
|
-
}
|
|
51
|
+
let currentState = bridge.get("group", info.id, { colornames: config.colornamer ? true : false });
|
|
67
52
|
|
|
68
|
-
|
|
53
|
+
// RESOURCE FOUND?
|
|
54
|
+
if(currentState !== false)
|
|
69
55
|
{
|
|
70
|
-
|
|
56
|
+
// NOT IN UNIVERAL MODE? -> CHANGE UI STATES
|
|
57
|
+
if(config.groupid)
|
|
71
58
|
{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
59
|
+
// APPLY FUTURE STATE COMMANDS
|
|
60
|
+
if(Object.values(scope.futurePatchState).length > 0)
|
|
61
|
+
{
|
|
62
|
+
scope.applyCommands({}, null, null);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if(currentState.payload.on === true)
|
|
66
|
+
{
|
|
67
|
+
scope.status({fill: "yellow", shape: "dot", text: "hue-group.node.turned-on"});
|
|
68
|
+
}
|
|
69
|
+
else
|
|
70
|
+
{
|
|
71
|
+
scope.status({fill: "grey", shape: "dot", text: "hue-group.node.all-off"});
|
|
72
|
+
}
|
|
81
73
|
}
|
|
82
|
-
|
|
74
|
+
|
|
75
|
+
// SEND MESSAGE
|
|
76
|
+
if(!config.skipevents && (config.initevents || info.suppressMessage == false))
|
|
83
77
|
{
|
|
84
|
-
|
|
78
|
+
// SET LAST COMMAND
|
|
79
|
+
if(scope.lastCommand !== null)
|
|
80
|
+
{
|
|
81
|
+
currentState.command = scope.lastCommand;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// SEND STATE
|
|
85
|
+
scope.send(currentState);
|
|
86
|
+
|
|
87
|
+
// RESET LAST COMMAND
|
|
88
|
+
scope.lastCommand = null;
|
|
85
89
|
}
|
|
86
90
|
}
|
|
91
|
+
});
|
|
87
92
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// SAVE LAST STATE
|
|
92
|
-
lastState = group;
|
|
93
|
-
}
|
|
93
|
+
//
|
|
94
|
+
// CONTROL GROUP
|
|
95
|
+
this.on('input', function(msg, send, done) { scope.applyCommands(msg, send, done); });
|
|
94
96
|
|
|
95
97
|
//
|
|
96
|
-
//
|
|
97
|
-
this.
|
|
98
|
+
// APPLY COMMANDS (API v1 because CLIP/v2 does not yet support all features)
|
|
99
|
+
this.applyCommands = async function(msg, send = null, done = null)
|
|
98
100
|
{
|
|
99
|
-
//
|
|
101
|
+
// SET SEND
|
|
100
102
|
send = send || function() { scope.send.apply(scope,arguments); }
|
|
101
|
-
scope.applyCommands(msg, send, done);
|
|
102
|
-
});
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
var tempGroupID = (msg.topic != null && isNaN(msg.topic) == false && msg.topic.length > 0) ? parseInt(msg.topic) : config.groupid;
|
|
104
|
+
// SAVE LAST COMMAND
|
|
105
|
+
scope.lastCommand = RED.util.cloneMessage(msg);
|
|
106
|
+
|
|
107
|
+
// CREATE PATCH
|
|
108
|
+
let patchObject = {};
|
|
110
109
|
|
|
111
|
-
//
|
|
112
|
-
|
|
110
|
+
// DEFINE SENSOR ID & CURRENT STATE
|
|
111
|
+
const tempGroupID = (!config.groupid && typeof msg.topic != 'undefined' && bridge.validResourceID.test(msg.topic) === true) ? msg.topic : config.groupid;
|
|
112
|
+
let currentState = bridge.get("group", tempGroupID, { colornames: config.colornamer ? true : false });
|
|
113
|
+
|
|
114
|
+
// CHECK IF LIGHT ID IS SET
|
|
115
|
+
if(!tempGroupID)
|
|
113
116
|
{
|
|
114
117
|
scope.error(RED._("hue-group.node.error-no-id"));
|
|
115
118
|
return false;
|
|
116
119
|
}
|
|
117
120
|
|
|
121
|
+
// GET FUTURE STATE
|
|
122
|
+
if(Object.values(scope.futurePatchState).length > 0)
|
|
123
|
+
{
|
|
124
|
+
patchObject = Object.assign({}, scope.futurePatchState);
|
|
125
|
+
scope.futurePatchState = {};
|
|
126
|
+
}
|
|
127
|
+
|
|
118
128
|
// GET CURRENT STATE
|
|
119
|
-
if(typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined')
|
|
129
|
+
if( (typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined') || (typeof msg.__user_inject_props__ != 'undefined' && msg.__user_inject_props__ == "status") )
|
|
120
130
|
{
|
|
121
|
-
|
|
122
|
-
.
|
|
123
|
-
|
|
124
|
-
|
|
131
|
+
// SET LAST COMMAND
|
|
132
|
+
if(scope.lastCommand !== null)
|
|
133
|
+
{
|
|
134
|
+
currentState.command = scope.lastCommand;
|
|
135
|
+
}
|
|
125
136
|
|
|
137
|
+
// SEND STATE
|
|
138
|
+
scope.send(currentState);
|
|
139
|
+
|
|
140
|
+
// RESET LAST COMMAND
|
|
141
|
+
scope.lastCommand = null;
|
|
142
|
+
|
|
143
|
+
if(done) { done(); }
|
|
126
144
|
return true;
|
|
127
145
|
}
|
|
128
146
|
|
|
147
|
+
// COLORLOOP EFFECT
|
|
148
|
+
if(typeof msg.payload != 'undefined' && typeof msg.payload.colorloop != 'undefined' && msg.payload.colorloop > 0)
|
|
149
|
+
{
|
|
150
|
+
patchObject = {
|
|
151
|
+
"on": true,
|
|
152
|
+
"effect": "colorloop",
|
|
153
|
+
"bri": msg.payload.brightness ? Math.round((254/100)*msg.payload.brightness) : 254
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
|
|
157
|
+
.then(function(status) {
|
|
158
|
+
// RESET COLORLOOP ANIMATION AFTER X SECONDS
|
|
159
|
+
setTimeout(function()
|
|
160
|
+
{
|
|
161
|
+
bridge.patch("group", currentState.info.idV1 + "/action", { "effect": "none" }, 1)
|
|
162
|
+
.then(function() { if(done) { done(); }});
|
|
163
|
+
}, parseInt(msg.payload.colorloop) * 1000);
|
|
164
|
+
})
|
|
165
|
+
.catch(function(errors) {
|
|
166
|
+
scope.error(errors);
|
|
167
|
+
scope.status({fill: "red", shape: "ring", text: "hue-group.node.error-input"});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
|
|
129
173
|
// ALERT EFFECT
|
|
130
174
|
if(typeof msg.payload != 'undefined' && typeof msg.payload.alert != 'undefined' && msg.payload.alert > 0)
|
|
131
175
|
{
|
|
132
|
-
|
|
133
|
-
.
|
|
134
|
-
|
|
176
|
+
// SAVE PREVIOUS STATE
|
|
177
|
+
scope.context().set('groupPreviousState', currentState);
|
|
178
|
+
|
|
179
|
+
// TURN ON LIGHT
|
|
180
|
+
if(currentState.payload.on === false)
|
|
181
|
+
{
|
|
182
|
+
patchObject["on"] = true;
|
|
183
|
+
}
|
|
135
184
|
|
|
136
|
-
|
|
137
|
-
|
|
185
|
+
// SET BRIGHTNESS
|
|
186
|
+
if(!msg.payload.brightness && currentState.payload.brightness != 100)
|
|
187
|
+
{
|
|
188
|
+
patchObject["bri"] = 254;
|
|
189
|
+
}
|
|
190
|
+
else if(msg.payload.brightness)
|
|
191
|
+
{
|
|
192
|
+
patchObject["bri"] = Math.round((254/100)*msg.payload.brightness);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// SET TRANSITION
|
|
196
|
+
patchObject["transitiontime"] = 0;
|
|
197
|
+
|
|
198
|
+
// CAN CHANGE COLOR?
|
|
199
|
+
let XYAlertColor = {};
|
|
200
|
+
|
|
201
|
+
if(typeof msg.payload.rgb != 'undefined')
|
|
202
|
+
{
|
|
203
|
+
XYAlertColor = colorUtils.rgbToXy(msg.payload.rgb[0], msg.payload.rgb[1], msg.payload.rgb[2] );
|
|
204
|
+
}
|
|
205
|
+
else if(typeof msg.payload.hex != 'undefined')
|
|
206
|
+
{
|
|
207
|
+
let rgbFromHex = colorUtils.hexRgb((msg.payload.hex).toString());
|
|
208
|
+
XYAlertColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2] );
|
|
209
|
+
}
|
|
210
|
+
else if(typeof msg.payload.color != 'undefined')
|
|
211
|
+
{
|
|
212
|
+
if(new RegExp("random|any|whatever").test(msg.payload.color))
|
|
138
213
|
{
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
214
|
+
const randomColor = colorUtils.randomHexColor();
|
|
215
|
+
let rgbFromHex = colorUtils.hexRgb(rgbFromHex);
|
|
216
|
+
XYAlertColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2] );
|
|
217
|
+
}
|
|
218
|
+
else
|
|
219
|
+
{
|
|
220
|
+
var colorHex = colorUtils.colornames(msg.payload.color);
|
|
221
|
+
if(colorHex)
|
|
144
222
|
{
|
|
145
|
-
|
|
146
|
-
|
|
223
|
+
let rgbFromHex = colorUtils.hexRgb(colorHex);
|
|
224
|
+
XYAlertColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2] );
|
|
147
225
|
}
|
|
148
|
-
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else
|
|
229
|
+
{
|
|
230
|
+
XYAlertColor = colorUtils.rgbToXy(255, 0, 0 );
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
patchObject["xy"] = [XYAlertColor.x, XYAlertColor.y];
|
|
234
|
+
|
|
235
|
+
// SET ALERT EFFECT
|
|
236
|
+
patchObject["alert"] = "lselect";
|
|
237
|
+
|
|
238
|
+
// 1. TURN ON THE LIGHT BULB
|
|
239
|
+
bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
|
|
240
|
+
.then(function(status) {
|
|
241
|
+
setTimeout(function()
|
|
242
|
+
{
|
|
243
|
+
const tempPreviousState = scope.context().get('groupPreviousState');
|
|
244
|
+
var tempPreviousStatePatch = {};
|
|
245
|
+
|
|
246
|
+
tempPreviousStatePatch.dimming = { brightness: tempPreviousState.payload.brightness };
|
|
247
|
+
if(tempPreviousState.payload.xyColor)
|
|
149
248
|
{
|
|
150
|
-
|
|
151
|
-
{
|
|
152
|
-
var randomColor = randomHexColor();
|
|
153
|
-
var rgbResult = hexRGB(randomColor);
|
|
154
|
-
group.xy = rgb.convertRGBtoXY([rgbResult.red, rgbResult.green, rgbResult.blue], false);
|
|
155
|
-
}
|
|
156
|
-
else
|
|
157
|
-
{
|
|
158
|
-
var colorHex = colornames(msg.payload.color);
|
|
159
|
-
if(colorHex)
|
|
160
|
-
{
|
|
161
|
-
var rgbResult = hexRGB(colorHex);
|
|
162
|
-
group.xy = rgb.convertRGBtoXY([rgbResult.red, rgbResult.green, rgbResult.blue], false);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
249
|
+
tempPreviousStatePatch.xy = [tempPreviousState.payload.xyColor.x, tempPreviousState.payload.xyColor.y];
|
|
165
250
|
}
|
|
166
|
-
else
|
|
251
|
+
else if(tempPreviousState.payload.colorTemp)
|
|
167
252
|
{
|
|
168
|
-
|
|
253
|
+
tempPreviousStatePatch.ct = tempPreviousState.payload.colorTemp;
|
|
169
254
|
}
|
|
170
|
-
}
|
|
171
255
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
group.brightness = 254;
|
|
175
|
-
group.transitionTime = 0;
|
|
176
|
-
return bridge.client.groups.save(group);
|
|
177
|
-
})
|
|
178
|
-
.then(group => {
|
|
179
|
-
// ACTIVATE ALERT
|
|
180
|
-
group.alert = 'lselect';
|
|
181
|
-
return bridge.client.groups.save(group);
|
|
182
|
-
})
|
|
183
|
-
.then(group => {
|
|
184
|
-
if(!config.groupid) { scope.sendGroupStatus(group, send, done); }
|
|
185
|
-
return group;
|
|
186
|
-
})
|
|
187
|
-
.then(group => {
|
|
188
|
-
// TURN OFF ALERT
|
|
189
|
-
var groupPreviousState = context.get('groupPreviousState');
|
|
190
|
-
var alertSeconds = parseInt(msg.payload.alert);
|
|
191
|
-
|
|
192
|
-
setTimeout(function() {
|
|
193
|
-
group.on = groupPreviousState[0];
|
|
194
|
-
group.alert = 'none';
|
|
195
|
-
group.brightness = groupPreviousState[1];
|
|
196
|
-
group.transitionTime = 2;
|
|
197
|
-
|
|
198
|
-
if(groupPreviousState[2] != false)
|
|
256
|
+
bridge.patch("group", currentState.info.idV1 + "/action", tempPreviousStatePatch, 1)
|
|
257
|
+
.then(function(status)
|
|
199
258
|
{
|
|
200
|
-
group.
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
259
|
+
return bridge.patch("group", currentState.info.idV1 + "/action", { on: false }, 1);
|
|
260
|
+
})
|
|
261
|
+
.then(function(status) {
|
|
262
|
+
if(done) { done(); }
|
|
263
|
+
if(tempPreviousState.payload.on === true)
|
|
264
|
+
{
|
|
265
|
+
bridge.patch("group", currentState.info.idV1, { on: true }, 1);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
}, parseInt(msg.payload.alert) * 1000);
|
|
205
269
|
})
|
|
206
|
-
.catch(
|
|
207
|
-
scope.error(
|
|
270
|
+
.catch(function(errors) {
|
|
271
|
+
scope.error(errors);
|
|
208
272
|
scope.status({fill: "red", shape: "ring", text: "hue-group.node.error-input"});
|
|
209
273
|
if(done) { done(error); }
|
|
210
274
|
});
|
|
@@ -212,342 +276,262 @@ module.exports = function(RED)
|
|
|
212
276
|
// ANIMATION STARTED?
|
|
213
277
|
else if(typeof msg.animation != 'undefined' && msg.animation.status == true && msg.animation.restore == true)
|
|
214
278
|
{
|
|
215
|
-
|
|
216
|
-
.
|
|
217
|
-
context.set('groupPreviousState', [group.on ? true : false, group.brightness, group.xy ? group.xy : false]);
|
|
218
|
-
})
|
|
219
|
-
.catch(error => {
|
|
220
|
-
scope.error(error, msg);
|
|
221
|
-
scope.status({fill: "red", shape: "ring", text: "hue-group.node.error-input"});
|
|
222
|
-
if(done) { done(error); }
|
|
223
|
-
});
|
|
279
|
+
// SAVE PREVIOUS STATE
|
|
280
|
+
scope.context().set('groupPreviousState', currentState);
|
|
224
281
|
}
|
|
225
282
|
// ANIMATION STOPPED AND RESTORE ACTIVE?
|
|
226
283
|
else if(typeof msg.animation != 'undefined' && msg.animation.status == false && msg.animation.restore == true)
|
|
227
284
|
{
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
var groupPreviousState = context.get('groupPreviousState');
|
|
285
|
+
const tempPreviousState = scope.context().get('groupPreviousState');
|
|
286
|
+
var tempPreviousStatePatch = {};
|
|
231
287
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
288
|
+
tempPreviousStatePatch.dimming = { brightness: tempPreviousState.payload.brightness };
|
|
289
|
+
if(tempPreviousState.payload.xyColor)
|
|
290
|
+
{
|
|
291
|
+
tempPreviousStatePatch.xy = [tempPreviousState.payload.xyColor.x, tempPreviousState.payload.xyColor.y];
|
|
292
|
+
}
|
|
293
|
+
else if(tempPreviousState.payload.colorTemp)
|
|
294
|
+
{
|
|
295
|
+
tempPreviousStatePatch.ct = tempPreviousState.payload.colorTemp;
|
|
296
|
+
}
|
|
236
297
|
|
|
237
|
-
|
|
298
|
+
bridge.patch("light", currentState.info.lightIds[l], tempPreviousStatePatch).
|
|
299
|
+
then(function(status)
|
|
300
|
+
{
|
|
301
|
+
if(tempPreviousState.payload.on === false)
|
|
238
302
|
{
|
|
239
|
-
|
|
303
|
+
bridge.patch("light", currentState.info.lightIds[l], { on: { on: false } })
|
|
304
|
+
}
|
|
305
|
+
else
|
|
306
|
+
{
|
|
307
|
+
bridge.patch("light", currentState.info.lightIds[l], { on: { on: false } })
|
|
308
|
+
.then(function(status) {
|
|
309
|
+
return bridge.patch("light", currentState.info.lightIds[l], { on: { on: true } })
|
|
310
|
+
});
|
|
240
311
|
}
|
|
241
|
-
|
|
242
|
-
bridge.client.groups.save(group);
|
|
243
|
-
})
|
|
244
|
-
.catch(error => {
|
|
245
|
-
scope.error(error, msg);
|
|
246
|
-
scope.status({fill: "red", shape: "ring", text: "hue-group.node.error-input"});
|
|
247
|
-
if(done) { done(error); }
|
|
248
312
|
});
|
|
249
313
|
}
|
|
250
|
-
// EXTENDED
|
|
314
|
+
// EXTENDED COMMANDS
|
|
251
315
|
else
|
|
252
316
|
{
|
|
253
|
-
|
|
254
|
-
.
|
|
317
|
+
// SET LIGHT STATE SIMPLE MODE
|
|
318
|
+
if(msg.payload === true||msg.payload === false)
|
|
255
319
|
{
|
|
256
|
-
|
|
257
|
-
var isCurrentlyOn = group.on;
|
|
258
|
-
|
|
259
|
-
// SET GROUP STATE SIMPLE MODE
|
|
260
|
-
if(msg.payload === true||msg.payload === false)
|
|
320
|
+
if(msg.payload !== currentState.payload.on)
|
|
261
321
|
{
|
|
262
|
-
|
|
263
|
-
msg.payload = {
|
|
264
|
-
on: command
|
|
265
|
-
};
|
|
322
|
+
patchObject["on"] = msg.payload;
|
|
266
323
|
}
|
|
324
|
+
}
|
|
267
325
|
|
|
268
|
-
|
|
269
|
-
|
|
326
|
+
// SET LIGHT STATE
|
|
327
|
+
if(typeof msg.payload != 'undefined' && typeof msg.payload.on != 'undefined' && (msg.payload.on === true || msg.payload.on === false))
|
|
328
|
+
{
|
|
329
|
+
if(msg.payload.on !== currentState.payload.on)
|
|
270
330
|
{
|
|
271
|
-
|
|
272
|
-
msg = merge.deep(futureState, msg);
|
|
273
|
-
|
|
274
|
-
// RESET
|
|
275
|
-
futureState = null;
|
|
331
|
+
patchObject["on"] = msg.payload.on;
|
|
276
332
|
}
|
|
333
|
+
}
|
|
277
334
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
// SET BRIGHTNESS
|
|
291
|
-
if (typeof msg.payload != 'undefined' && typeof msg.payload.brightness != 'undefined')
|
|
292
|
-
{
|
|
293
|
-
if(msg.payload.brightness > 100 || msg.payload.brightness < 0) {
|
|
294
|
-
scope.error("Invalid brightness setting. Only 0 - 100 percent allowed");
|
|
295
|
-
return false;
|
|
296
|
-
}
|
|
297
|
-
else if (msg.payload.brightness == 0)
|
|
298
|
-
{
|
|
299
|
-
group.on = false;
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
group.on = true;
|
|
303
|
-
group.brightness = Math.round((254 / 100) * parseInt(msg.payload.brightness));
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
else if(typeof msg.payload != 'undefined' && typeof msg.payload.brightnessLevel != 'undefined')
|
|
307
|
-
{
|
|
308
|
-
if(msg.payload.brightnessLevel > 254 || msg.payload.brightnessLevel < 0)
|
|
309
|
-
{
|
|
310
|
-
scope.error("Invalid brightness setting. Only 0 - 254 allowed");
|
|
311
|
-
return false;
|
|
312
|
-
}
|
|
313
|
-
else if(msg.payload.brightness == 0)
|
|
314
|
-
{
|
|
315
|
-
group.on = false;
|
|
316
|
-
}
|
|
317
|
-
else
|
|
318
|
-
{
|
|
319
|
-
group.on = true;
|
|
320
|
-
group.brightness = parseInt(msg.payload.brightnessLevel);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
else if (typeof msg.payload != 'undefined' && typeof msg.payload.incrementBrightness != 'undefined')
|
|
324
|
-
{
|
|
325
|
-
if(msg.payload.incrementBrightness > 0 && typeof msg.payload.ignoreOffLights == 'undefined')
|
|
326
|
-
{
|
|
327
|
-
group.on = true;
|
|
328
|
-
}
|
|
329
|
-
group.incrementBrightness = Math.round((254/100)*parseInt(msg.payload.incrementBrightness));
|
|
330
|
-
}
|
|
331
|
-
else if (typeof msg.payload != 'undefined' && typeof msg.payload.decrementBrightness != 'undefined')
|
|
335
|
+
// TOGGLE ON / OFF
|
|
336
|
+
if(typeof msg.payload != 'undefined' && typeof msg.payload.toggle != 'undefined')
|
|
337
|
+
{
|
|
338
|
+
patchObject["on"] = !currentState.payload.on;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// SET BRIGHTNESS
|
|
342
|
+
if(typeof msg.payload != 'undefined' && typeof msg.payload.brightness != 'undefined')
|
|
343
|
+
{
|
|
344
|
+
// AUTO BRIGHTNESS BASED ON DAY TIME
|
|
345
|
+
if(new RegExp("auto|automatic").test(msg.payload.brightness))
|
|
332
346
|
{
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
group.incrementBrightness = Math.round((254/100)*parseInt(msg.payload.decrementBrightness))*-1;
|
|
338
|
-
}
|
|
347
|
+
let ct = colorUtils.colorTemperature();
|
|
348
|
+
let autoBrightness = ((300-ct)/2)+100;
|
|
349
|
+
autoBrightness = (autoBrightness > 100) ? 100 : autoBrightness;
|
|
350
|
+
autoBrightness = (autoBrightness < 20) ? 20 : autoBrightness;
|
|
339
351
|
|
|
340
|
-
|
|
341
|
-
|
|
352
|
+
// SET CALCULATED BRIGHTNESS
|
|
353
|
+
patchObject["bri"] = Math.round((254/100)*autoBrightness);
|
|
354
|
+
}
|
|
355
|
+
else
|
|
342
356
|
{
|
|
343
|
-
if(
|
|
357
|
+
if(msg.payload.brightness > 100 || msg.payload.brightness < 0)
|
|
358
|
+
{
|
|
359
|
+
scope.error("Invalid brightness setting. Only 0 - 100 percent allowed");
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
else if(msg.payload.brightness == 0)
|
|
344
363
|
{
|
|
345
|
-
|
|
346
|
-
var rgbResult = hexRGB(randomColor);
|
|
347
|
-
group.xy = rgb.convertRGBtoXY([rgbResult.red, rgbResult.green, rgbResult.blue], false);
|
|
364
|
+
patchObject["on"] = false;
|
|
348
365
|
}
|
|
349
366
|
else
|
|
350
367
|
{
|
|
351
|
-
|
|
352
|
-
if(colorHex)
|
|
353
|
-
{
|
|
354
|
-
var rgbResult = hexRGB(colorHex);
|
|
355
|
-
group.xy = rgb.convertRGBtoXY([rgbResult.red, rgbResult.green, rgbResult.blue], false);
|
|
356
|
-
}
|
|
368
|
+
patchObject["bri"] = Math.round((254/100)*msg.payload.brightness);
|
|
357
369
|
}
|
|
358
370
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
371
|
+
}
|
|
372
|
+
else if(typeof msg.payload != 'undefined' && typeof msg.payload.brightnessLevel != 'undefined')
|
|
373
|
+
{
|
|
374
|
+
if(msg.payload.brightnessLevel > 254 || msg.payload.brightnessLevel < 0)
|
|
362
375
|
{
|
|
363
|
-
|
|
376
|
+
scope.error("Invalid brightness setting. Only 0 - 254 allowed");
|
|
377
|
+
return false;
|
|
364
378
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
379
|
+
else if(msg.payload.brightness == 0)
|
|
380
|
+
{
|
|
381
|
+
patchObject["on"] = false;
|
|
382
|
+
}
|
|
383
|
+
else
|
|
368
384
|
{
|
|
369
|
-
|
|
370
|
-
group.xy = rgb.convertRGBtoXY([rgbResult.red, rgbResult.green, rgbResult.blue], false);
|
|
385
|
+
patchObject["bri"] = msg.payload.brightnessLevel;
|
|
371
386
|
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// SET HUMAN READABLE COLOR OR RANDOM
|
|
390
|
+
if(typeof msg.payload != 'undefined' && typeof msg.payload.color != 'undefined')
|
|
391
|
+
{
|
|
392
|
+
let XYAlertColor = {};
|
|
372
393
|
|
|
373
|
-
|
|
374
|
-
if(typeof msg.payload != 'undefined' && typeof msg.payload.saturation != 'undefined' && typeof group.saturation != 'undefined')
|
|
394
|
+
if(new RegExp("random|any|whatever").test(msg.payload.color))
|
|
375
395
|
{
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
396
|
+
const randomColor = colorUtils.randomHexColor();
|
|
397
|
+
let rgbFromHex = colorUtils.hexRgb(randomColor);
|
|
398
|
+
XYAlertColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2] );
|
|
399
|
+
}
|
|
400
|
+
else
|
|
401
|
+
{
|
|
402
|
+
var colorHex = colorUtils.colornames(msg.payload.color);
|
|
403
|
+
if(colorHex)
|
|
382
404
|
{
|
|
383
|
-
|
|
405
|
+
let rgbFromHex = colorUtils.hexRgb(colorHex);
|
|
406
|
+
XYAlertColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2] );
|
|
384
407
|
}
|
|
385
408
|
}
|
|
386
409
|
|
|
387
|
-
|
|
388
|
-
|
|
410
|
+
patchObject["xy"] = [XYAlertColor.x, XYAlertColor.y];
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// SET HEX COLOR
|
|
414
|
+
if(typeof msg.payload != 'undefined' && typeof msg.payload.hex != 'undefined')
|
|
415
|
+
{
|
|
416
|
+
let rgbFromHex = colorUtils.hexRgb((msg.payload.hex).toString());
|
|
417
|
+
let xyColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2])
|
|
418
|
+
|
|
419
|
+
patchObject["xy"] = [xyColor.x, xyColor.y];
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// SET RGB COLOR
|
|
423
|
+
if(typeof msg.payload != 'undefined' && typeof msg.payload.rgb != 'undefined' && msg.payload.rgb.length === 3)
|
|
424
|
+
{
|
|
425
|
+
let xyColor = colorUtils.rgbToXy(msg.payload.rgb[0], msg.payload.rgb[1], msg.payload.rgb[2] )
|
|
426
|
+
patchObject["xy"] = [xyColor.x, xyColor.y];
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// SET XY COLOR
|
|
430
|
+
if(typeof msg.payload != 'undefined' && typeof msg.payload.xyColor != 'undefined')
|
|
431
|
+
{
|
|
432
|
+
patchObject["xy"] = [msg.payload.xyColor.x, msg.payload.xyColor.y];
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// SET COLOR TEMPERATURE
|
|
436
|
+
if(typeof msg.payload != 'undefined' && typeof msg.payload.colorTemp != 'undefined')
|
|
437
|
+
{
|
|
438
|
+
// DETERMINE IF AUTOMATIC, WARM, COLD, INT
|
|
439
|
+
if(!isNaN(msg.payload.colorTemp))
|
|
389
440
|
{
|
|
390
|
-
|
|
391
|
-
if(
|
|
441
|
+
let colorTemp = parseInt(msg.payload.colorTemp);
|
|
442
|
+
if(colorTemp >= 153 && colorTemp <= 500)
|
|
392
443
|
{
|
|
393
|
-
|
|
394
|
-
if(colorTemp >= 153 && colorTemp <= 500)
|
|
395
|
-
{
|
|
396
|
-
group.colorTemp = parseInt(msg.payload.colorTemp);
|
|
397
|
-
}
|
|
398
|
-
else
|
|
399
|
-
{
|
|
400
|
-
scope.error(RED._("error-invalid-temp"), msg);
|
|
401
|
-
return false;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
else if(msg.payload.colorTemp == "cold")
|
|
405
|
-
{
|
|
406
|
-
group.colorTemp = 153;
|
|
407
|
-
}
|
|
408
|
-
else if(msg.payload.colorTemp == "normal")
|
|
409
|
-
{
|
|
410
|
-
group.colorTemp = 240;
|
|
411
|
-
}
|
|
412
|
-
else if(msg.payload.colorTemp == "warm")
|
|
413
|
-
{
|
|
414
|
-
group.colorTemp = 400;
|
|
444
|
+
patchObject["ct"] = colorTemp;
|
|
415
445
|
}
|
|
416
446
|
else
|
|
417
447
|
{
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
var minute = (new Date()).getMinutes();
|
|
421
|
-
var time = hour + minute * 0.01667;
|
|
422
|
-
|
|
423
|
-
var autoTemperature = Math.floor(3.125 * time ** 2 - 87.5 * time + 812);
|
|
424
|
-
autoTemperature = (autoTemperature < 153) ? 153 : autoTemperature;
|
|
425
|
-
autoTemperature = (autoTemperature > 400) ? 400 : autoTemperature;
|
|
426
|
-
|
|
427
|
-
// SET TEMPERATURE
|
|
428
|
-
group.colorTemp = autoTemperature;
|
|
448
|
+
scope.error("Invalid color temprature. Only 153 - 500 allowed");
|
|
449
|
+
return false;
|
|
429
450
|
}
|
|
430
451
|
}
|
|
431
|
-
|
|
432
|
-
{
|
|
433
|
-
group.incrementColorTemp = parseInt(msg.payload.incrementColorTemp, 10) || 0;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// SET TRANSITION TIME
|
|
437
|
-
if(typeof msg.payload != 'undefined' && typeof msg.payload.transitionTime != 'undefined')
|
|
452
|
+
else if(msg.payload.colorTemp == "cold")
|
|
438
453
|
{
|
|
439
|
-
|
|
454
|
+
patchObject["ct"] = 153;
|
|
440
455
|
}
|
|
441
|
-
|
|
442
|
-
// SET COLORLOOP EFFECT
|
|
443
|
-
if(typeof msg.payload != 'undefined' && typeof msg.payload.colorloop != 'undefined' && typeof group.xy != 'undefined')
|
|
456
|
+
else if(msg.payload.colorTemp == "normal")
|
|
444
457
|
{
|
|
445
|
-
|
|
446
|
-
group.effect = 'colorloop';
|
|
447
|
-
}
|
|
448
|
-
else if(msg.payload.colorloop === false) {
|
|
449
|
-
group.effect = 'none';
|
|
450
|
-
}
|
|
451
|
-
// ENABLE FOR TIME INTERVAL
|
|
452
|
-
else if(msg.payload.colorloop > 0) {
|
|
453
|
-
group.effect = 'colorloop';
|
|
454
|
-
|
|
455
|
-
// DISABLE AFTER
|
|
456
|
-
setTimeout(function() {
|
|
457
|
-
group.effect = 'none';
|
|
458
|
-
bridge.client.lights.save(light);
|
|
459
|
-
}, parseFloat(msg.payload.colorloop)*1000);
|
|
460
|
-
}
|
|
458
|
+
patchObject["ct"] = 240;
|
|
461
459
|
}
|
|
462
|
-
|
|
463
|
-
// SET DOMINANT COLORS FROM IMAGE
|
|
464
|
-
if(typeof msg.payload != 'undefined' && typeof msg.payload.image != 'undefined' && typeof group.xy != 'undefined')
|
|
460
|
+
else if(msg.payload.colorTemp == "warm")
|
|
465
461
|
{
|
|
466
|
-
|
|
467
|
-
if(colors.length > 0)
|
|
468
|
-
{
|
|
469
|
-
var colorsHEX = colors.map(color => color.hex());
|
|
470
|
-
var rgbResult = hexRGB(colorsHEX[0]);
|
|
471
|
-
group.xy = rgb.convertRGBtoXY([rgbResult.red, rgbResult.green, rgbResult.blue], false);
|
|
472
|
-
}
|
|
462
|
+
patchObject["ct"] = 400;
|
|
473
463
|
}
|
|
474
|
-
|
|
475
|
-
// SAVE FOR LATER MODE?
|
|
476
|
-
if(!group.on&&isCurrentlyOn==false)
|
|
464
|
+
else if(msg.payload.colorTemp == "hot")
|
|
477
465
|
{
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
// IGNORE ON/OFF & TOGGLE
|
|
481
|
-
if(typeof futureState.payload != 'undefined')
|
|
482
|
-
{
|
|
483
|
-
delete futureState.payload.on;
|
|
484
|
-
delete futureState.payload.toggle;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// ANY OTHER COMMANDS?
|
|
488
|
-
if(typeof futureState.payload != 'undefined' && Object.keys(futureState.payload).length > 0)
|
|
489
|
-
{
|
|
490
|
-
return group;
|
|
491
|
-
}
|
|
466
|
+
patchObject["ct"] = 500;
|
|
492
467
|
}
|
|
468
|
+
else
|
|
469
|
+
{
|
|
470
|
+
// SET TEMPERATURE
|
|
471
|
+
patchObject["ct"] = colorUtils.colorTemperature();
|
|
472
|
+
}
|
|
473
|
+
}
|
|
493
474
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
.then(group => {
|
|
497
|
-
scope.sendGroupStatus(group, send, done);
|
|
498
|
-
return group;
|
|
499
|
-
})
|
|
500
|
-
.catch(error => {
|
|
501
|
-
scope.error(error, msg);
|
|
502
|
-
scope.status({fill: "red", shape: "ring", text: "hue-group.node.error-input"});
|
|
503
|
-
if(done) { done(error); }
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
//
|
|
509
|
-
// SEND GROUP STATUS
|
|
510
|
-
this.sendGroupStatus = function(group, send, done)
|
|
511
|
-
{
|
|
512
|
-
var hueGroup = new HueGroupMessage(group, config, (universalMode == false) ? lastState : false);
|
|
513
|
-
var brightnessNotice = (hueGroup.msg.payload.brightness > -1) ? RED._("hue-group.node.brightness",{percent: hueGroup.msg.payload.brightness}) : "";
|
|
514
|
-
|
|
515
|
-
// SEND STATUS
|
|
516
|
-
if(universalMode == false)
|
|
517
|
-
{
|
|
518
|
-
if(group.allOn)
|
|
475
|
+
// SET TRANSITION TIME
|
|
476
|
+
if(typeof msg.payload != 'undefined' && typeof msg.payload.transitionTime != 'undefined')
|
|
519
477
|
{
|
|
520
|
-
|
|
478
|
+
let targetTransitionTime = parseFloat(msg.payload.transitionTime)*1000;
|
|
479
|
+
targetTransitionTime = (targetTransitionTime > 6000000) ? 6000000 : targetTransitionTime;
|
|
480
|
+
targetTransitionTime = (targetTransitionTime < 0) ? 0 : targetTransitionTime;
|
|
481
|
+
|
|
482
|
+
patchObject["transitiontime"] = targetTransitionTime/100;
|
|
521
483
|
}
|
|
522
|
-
|
|
484
|
+
|
|
485
|
+
// SET DOMINANT COLORS FROM IMAGE
|
|
486
|
+
if(typeof msg.payload != 'undefined' && typeof msg.payload.image != 'undefined')
|
|
523
487
|
{
|
|
524
|
-
|
|
488
|
+
var colors = await colorUtils.getColors(msg.payload.image);
|
|
489
|
+
if(colors.length > 0)
|
|
490
|
+
{
|
|
491
|
+
var colorsHEX = colors.map(color => color.hex());
|
|
492
|
+
let rgbFromHex = colorUtils.hexRgb(colorsHEX[0]);
|
|
493
|
+
let xyColor = colorUtils.rgbToXy(rgbFromHex[0], rgbFromHex[1], rgbFromHex[2]);
|
|
494
|
+
|
|
495
|
+
patchObject["xy"] = [xyColor.x, xyColor.y];
|
|
496
|
+
}
|
|
525
497
|
}
|
|
526
|
-
|
|
498
|
+
|
|
499
|
+
//
|
|
500
|
+
// SHOULD PATCH?
|
|
501
|
+
if(Object.values(patchObject).length > 0)
|
|
527
502
|
{
|
|
528
|
-
|
|
503
|
+
// IS FOR LATER?
|
|
504
|
+
if(currentState.payload.on === false)
|
|
505
|
+
{
|
|
506
|
+
if(!patchObject["on"])
|
|
507
|
+
{
|
|
508
|
+
scope.futurePatchState = merge.deep(scope.futurePatchState, patchObject);
|
|
509
|
+
return false;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// PATCH!
|
|
514
|
+
bridge.patch("group", currentState.info.idV1 + "/action", patchObject, 1)
|
|
515
|
+
.then(function() { if(done) { done(); }})
|
|
516
|
+
.catch(function(errors) { scope.error(errors); });
|
|
529
517
|
}
|
|
530
518
|
else
|
|
531
519
|
{
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
520
|
+
// SET LAST COMMAND
|
|
521
|
+
if(scope.lastCommand !== null)
|
|
522
|
+
{
|
|
523
|
+
currentState.command = scope.lastCommand;
|
|
524
|
+
}
|
|
535
525
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
if(done) { done(); }
|
|
526
|
+
// SEND STATE
|
|
527
|
+
scope.send(currentState);
|
|
539
528
|
|
|
540
|
-
|
|
541
|
-
|
|
529
|
+
// RESET LAST COMMAND
|
|
530
|
+
scope.lastCommand = null;
|
|
531
|
+
if(done) { done(); }
|
|
532
|
+
}
|
|
533
|
+
}
|
|
542
534
|
}
|
|
543
|
-
|
|
544
|
-
//
|
|
545
|
-
// CLOSE NODE / REMOVE EVENT LISTENER
|
|
546
|
-
this.on('close', function()
|
|
547
|
-
{
|
|
548
|
-
bridge.events.removeAllListeners('group' + config.groupid);
|
|
549
|
-
bridge.events.removeAllListeners('group');
|
|
550
|
-
});
|
|
551
535
|
}
|
|
552
536
|
|
|
553
537
|
RED.nodes.registerType("hue-group", HueGroup);
|