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