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