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.
Files changed (165) hide show
  1. package/CHANGELOG.md +229 -0
  2. package/README.md +806 -729
  3. package/examples/Hue Bridge.json +189 -35
  4. package/examples/Hue Brightness.json +124 -14
  5. package/examples/Hue Buttons.json +88 -0
  6. package/examples/Hue Group.json +575 -63
  7. package/examples/Hue Light.json +805 -58
  8. package/examples/Hue Magic.json +69 -24
  9. package/examples/Hue Motion.json +110 -42
  10. package/examples/Hue Rules.json +105 -37
  11. package/examples/Hue Scene.json +145 -28
  12. package/examples/Hue Temperature.json +124 -14
  13. package/huemagic/animations/001-sunny.json +22 -22
  14. package/huemagic/animations/002-cloudy.json +46 -46
  15. package/huemagic/animations/003-nightsky.json +20 -20
  16. package/huemagic/animations/004-sunrise.json +54 -54
  17. package/huemagic/animations/005-sunset.json +46 -46
  18. package/huemagic/animations/006-fireplace.json +74 -74
  19. package/huemagic/animations/007-spring.json +31 -31
  20. package/huemagic/animations/008-autmn.json +23 -23
  21. package/huemagic/animations/009-winter.json +23 -23
  22. package/huemagic/animations/010-dirtyfog.json +23 -23
  23. package/huemagic/animations/011-lgbt.json +49 -50
  24. package/huemagic/animations/012-rasta.json +28 -29
  25. package/huemagic/animations/013-strobo.json +30 -31
  26. package/huemagic/animations/014-randomrainbow.json +30 -31
  27. package/huemagic/animations/015-sos.json +158 -159
  28. package/huemagic/animations/016-milkyway.json +83 -0
  29. package/huemagic/animations/017-beach.json +40 -0
  30. package/huemagic/animations/018-forest.json +43 -0
  31. package/huemagic/animations/019-christmas.json +30 -0
  32. package/huemagic/animations/020-superhero.json +56 -0
  33. package/huemagic/animations/021-neoncity.json +52 -0
  34. package/huemagic/animations/previews/001-sunny.gif +0 -0
  35. package/huemagic/animations/previews/002-cloudy.gif +0 -0
  36. package/huemagic/animations/previews/003-nightsky.gif +0 -0
  37. package/huemagic/animations/previews/004-sunrise.gif +0 -0
  38. package/huemagic/animations/previews/005-sunset.gif +0 -0
  39. package/huemagic/animations/previews/006-fireplace.gif +0 -0
  40. package/huemagic/animations/previews/007-spring.gif +0 -0
  41. package/huemagic/animations/previews/008-autmn.gif +0 -0
  42. package/huemagic/animations/previews/009-winter.gif +0 -0
  43. package/huemagic/animations/previews/010-dirtyfog.gif +0 -0
  44. package/huemagic/animations/previews/011-lgbt.gif +0 -0
  45. package/huemagic/animations/previews/012-rasta.gif +0 -0
  46. package/huemagic/animations/previews/013-strobo.gif +0 -0
  47. package/huemagic/animations/previews/014-randomrainbow.gif +0 -0
  48. package/huemagic/animations/previews/015-sos.gif +0 -0
  49. package/huemagic/animations/previews/016-milkyway.gif +0 -0
  50. package/huemagic/animations/previews/017-beach.gif +0 -0
  51. package/huemagic/animations/previews/018-forest.gif +0 -0
  52. package/huemagic/animations/previews/019-christmas.gif +0 -0
  53. package/huemagic/animations/previews/020-superhero.gif +0 -0
  54. package/huemagic/animations/previews/021-neoncity.gif +0 -0
  55. package/huemagic/hue-bridge-config.html +105 -61
  56. package/huemagic/hue-bridge-config.js +629 -319
  57. package/huemagic/hue-bridge.html +41 -21
  58. package/huemagic/hue-bridge.js +191 -398
  59. package/huemagic/hue-brightness.html +130 -49
  60. package/huemagic/hue-brightness.js +131 -35
  61. package/huemagic/hue-buttons.html +197 -0
  62. package/huemagic/hue-buttons.js +152 -0
  63. package/huemagic/hue-group.html +137 -60
  64. package/huemagic/hue-group.js +394 -367
  65. package/huemagic/hue-light.html +133 -59
  66. package/huemagic/hue-light.js +551 -336
  67. package/huemagic/hue-magic.html +91 -237
  68. package/huemagic/hue-magic.js +57 -27
  69. package/huemagic/hue-motion.html +128 -50
  70. package/huemagic/hue-motion.js +116 -87
  71. package/huemagic/hue-rules.html +121 -50
  72. package/huemagic/hue-rules.js +84 -64
  73. package/huemagic/hue-scene.html +96 -115
  74. package/huemagic/hue-scene.js +65 -96
  75. package/huemagic/hue-temperature.html +130 -49
  76. package/huemagic/hue-temperature.js +136 -32
  77. package/huemagic/icons/hue-bridge.png +0 -0
  78. package/huemagic/icons/hue-bridge.svg +3 -0
  79. package/huemagic/icons/hue-brightness.png +0 -0
  80. package/huemagic/icons/hue-brightness.svg +11 -0
  81. package/huemagic/icons/hue-buttons.png +0 -0
  82. package/huemagic/icons/hue-buttons.svg +4 -0
  83. package/huemagic/icons/hue-group.png +0 -0
  84. package/huemagic/icons/hue-group.svg +12 -0
  85. package/huemagic/icons/hue-light.png +0 -0
  86. package/huemagic/icons/hue-light.svg +3 -0
  87. package/huemagic/icons/hue-magic.png +0 -0
  88. package/huemagic/icons/hue-magic.svg +3 -0
  89. package/huemagic/icons/hue-motion.png +0 -0
  90. package/huemagic/icons/hue-motion.svg +9 -0
  91. package/huemagic/icons/hue-rules.png +0 -0
  92. package/huemagic/icons/hue-rules.svg +4 -0
  93. package/huemagic/icons/hue-scene.png +0 -0
  94. package/huemagic/icons/hue-scene.svg +5 -0
  95. package/huemagic/icons/hue-temperature.png +0 -0
  96. package/huemagic/icons/hue-temperature.svg +7 -0
  97. package/huemagic/locales/de/hue-bridge-config.html +17 -12
  98. package/huemagic/locales/de/hue-bridge-config.json +7 -5
  99. package/huemagic/locales/de/hue-bridge.html +64 -145
  100. package/huemagic/locales/de/hue-bridge.json +6 -17
  101. package/huemagic/locales/de/hue-brightness.html +52 -38
  102. package/huemagic/locales/de/hue-brightness.json +7 -2
  103. package/huemagic/locales/de/hue-buttons.html +58 -0
  104. package/huemagic/locales/de/hue-buttons.json +28 -0
  105. package/huemagic/locales/de/hue-group.html +46 -122
  106. package/huemagic/locales/de/hue-group.json +4 -2
  107. package/huemagic/locales/de/hue-light.html +68 -116
  108. package/huemagic/locales/de/hue-light.json +5 -2
  109. package/huemagic/locales/de/hue-magic.html +65 -57
  110. package/huemagic/locales/de/hue-magic.json +2 -1
  111. package/huemagic/locales/de/hue-motion.html +48 -44
  112. package/huemagic/locales/de/hue-motion.json +6 -3
  113. package/huemagic/locales/de/hue-rules.html +68 -73
  114. package/huemagic/locales/de/hue-rules.json +5 -2
  115. package/huemagic/locales/de/hue-scene.html +23 -32
  116. package/huemagic/locales/de/hue-scene.json +5 -2
  117. package/huemagic/locales/de/hue-temperature.html +53 -36
  118. package/huemagic/locales/de/hue-temperature.json +7 -2
  119. package/huemagic/locales/en-US/hue-bridge-config.html +17 -12
  120. package/huemagic/locales/en-US/hue-bridge-config.json +5 -3
  121. package/huemagic/locales/en-US/hue-bridge.html +64 -145
  122. package/huemagic/locales/en-US/hue-bridge.json +5 -16
  123. package/huemagic/locales/en-US/hue-brightness.html +52 -38
  124. package/huemagic/locales/en-US/hue-brightness.json +10 -3
  125. package/huemagic/locales/en-US/hue-buttons.html +58 -0
  126. package/huemagic/locales/en-US/hue-buttons.json +34 -0
  127. package/huemagic/locales/en-US/hue-group.html +46 -122
  128. package/huemagic/locales/en-US/hue-group.json +7 -3
  129. package/huemagic/locales/en-US/hue-light.html +68 -116
  130. package/huemagic/locales/en-US/hue-light.json +8 -3
  131. package/huemagic/locales/en-US/hue-magic.html +65 -57
  132. package/huemagic/locales/en-US/hue-magic.json +3 -1
  133. package/huemagic/locales/en-US/hue-motion.html +48 -44
  134. package/huemagic/locales/en-US/hue-motion.json +9 -4
  135. package/huemagic/locales/en-US/hue-rules.html +68 -73
  136. package/huemagic/locales/en-US/hue-rules.json +5 -2
  137. package/huemagic/locales/en-US/hue-scene.html +23 -32
  138. package/huemagic/locales/en-US/hue-scene.json +5 -2
  139. package/huemagic/locales/en-US/hue-temperature.html +53 -36
  140. package/huemagic/locales/en-US/hue-temperature.json +10 -3
  141. package/huemagic/utils/api.js +290 -0
  142. package/huemagic/utils/color.js +382 -0
  143. package/{utils → huemagic/utils}/merge.js +9 -6
  144. package/huemagic/utils/messages.js +447 -0
  145. package/package.json +12 -12
  146. package/examples/Hue Switch.json +0 -40
  147. package/examples/Hue Tap.json +0 -40
  148. package/huemagic/assets/anime.js +0 -8
  149. package/huemagic/hue-switch.html +0 -119
  150. package/huemagic/hue-switch.js +0 -113
  151. package/huemagic/hue-tap.html +0 -119
  152. package/huemagic/hue-tap.js +0 -74
  153. package/huemagic/icons/hue-button.png +0 -0
  154. package/huemagic/icons/hue-switch.png +0 -0
  155. package/huemagic/icons/hue-tap.png +0 -0
  156. package/huemagic/locales/de/hue-switch.html +0 -50
  157. package/huemagic/locales/de/hue-switch.json +0 -31
  158. package/huemagic/locales/de/hue-tap.html +0 -41
  159. package/huemagic/locales/de/hue-tap.json +0 -23
  160. package/huemagic/locales/en-US/hue-switch.html +0 -50
  161. package/huemagic/locales/en-US/hue-switch.json +0 -31
  162. package/huemagic/locales/en-US/hue-tap.html +0 -41
  163. package/huemagic/locales/en-US/hue-tap.json +0 -23
  164. package/utils/messages.js +0 -571
  165. package/utils/rgb.js +0 -188
@@ -6,23 +6,25 @@ module.exports = function(RED)
6
6
  {
7
7
  RED.nodes.createNode(this, config);
8
8
 
9
- var scope = this;
10
- let bridge = RED.nodes.getNode(config.bridge);
11
- let { HueBridgeMessage, HueBrightnessMessage, HueGroupMessage, HueLightMessage, HueMotionMessage, HueRulesMessage, HueSwitchMessage, HueTapMessage, HueTemperatureMessage } = require('../utils/messages');
9
+ const scope = this;
10
+ const bridge = RED.nodes.getNode(config.bridge);
12
11
 
13
- // PREVENT DEVICE MESSAGES IN FIRST 5 SECONDS
14
- this.deviceUpdates = false;
15
- setTimeout(function(){ scope.deviceUpdates = true; }, 5000);
12
+ // IS CONNECTED?
13
+ this.connected = false;
14
+
15
+ // GET BRIDGE INFORMATION INITIALLY
16
+ this.lastBridgeInformation = null;
17
+
18
+ // SAVE LAST COMMAND
19
+ this.lastCommand = null;
20
+
21
+ // NODE UI STATUS TIMEOUT
22
+ this.timeout = null;
16
23
 
17
24
  //
18
25
  // ACTIVE STATE
19
26
  this.nodeActive = true;
20
27
 
21
- //
22
- // BRIDGE INFORMATION
23
- this.bridgeInformation = {};
24
-
25
-
26
28
  //
27
29
  // CHECK CONFIG
28
30
  if(bridge == null)
@@ -33,479 +35,270 @@ module.exports = function(RED)
33
35
 
34
36
  //
35
37
  // UPDATE STATE
36
- this.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connecting"});
38
+ scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connecting"});
37
39
 
38
- //
39
- // GET INFORMATION
40
- this.getBridgeInformation = function()
40
+ this.setInitialState = function()
41
41
  {
42
- bridge.client.bridge.get()
43
- .then(bridgeInformation => {
44
- var hueBridge = new HueBridgeMessage(bridgeInformation, config);
45
- scope.send(hueBridge.msg);
46
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connected" });
47
-
48
- // SAVE BRIDGE INFORMATION
49
- scope.bridgeInformation = hueBridge.msg.payload;
50
- })
51
- .catch(error => {
52
- scope.error(error);
53
- if(scope.nodeActive == true)
54
- {
55
- setTimeout(function(){ scope.getBridgeInformation(); }, 3000);
56
- }
57
- });
42
+ scope.status({fill: "green", shape: "dot", text: "hue-bridge.node.connected"});
58
43
  }
59
44
 
60
- //
61
- // INITIAL START
62
- this.getBridgeInformation();
63
45
 
64
46
  //
65
- // AUTO UPDATES?
66
- this.autoUpdateHueBridge = function()
47
+ // GET BRIDGE INFORMATION
48
+ this.getBridgeInformation = async function(forceReload = false)
67
49
  {
68
- if(config.autoupdates == true)
50
+ return new Promise(function(resolve, reject)
69
51
  {
70
- bridge.client.softwareUpdate.check()
71
- .then(() => {
72
- return bridge.client.softwareUpdate.get();
73
- })
74
- .then(softwareUpdate => {
75
- return bridge.client.softwareUpdate.install();
76
- })
77
- .then(() => {
78
- // UPDATING // CHECK STATUS IN 5 MINUTES
79
- if(scope.nodeActive == true)
52
+ if(forceReload === true)
53
+ {
54
+ // REFRESH INFORMATION
55
+ bridge.getBridgeInformation(true)
56
+ .then(function(updated)
80
57
  {
81
- setTimeout(function(){ scope.getBridgeInformation(); }, 60000 * 5);
82
- }
83
- })
84
- .catch(error => {
85
- // NO UPDATES AVAILABLE // TRY AGAIN IN 3H
86
- if(scope.nodeActive == true)
58
+ return scope.getBridgeInformation();
59
+ })
60
+ .then(function(bridgeInformation)
87
61
  {
88
- setTimeout(function(){ scope.autoUpdateHueBridge(); }, 60000 * 180);
89
- }
90
- });
91
- }
92
- }
93
-
94
- this.autoUpdateHueBridge();
95
-
96
- //
97
- // DEVICE UPDATES
98
- if(!config.skipglobalevents)
99
- {
100
- bridge.events.on('globalDeviceUpdates', function(message)
101
- {
102
- if(scope.deviceUpdates == false) { return; }
103
-
104
- let type = message.type;
105
- let payload = message.payload;
106
- var detType = type;
107
-
108
- // CONSTRUCT MESSAGE
109
- var message = {};
110
- message.updated = {};
111
-
112
- // ADD PAYLOAD
113
- if(type == "light")
114
- {
115
- let hueLight = new HueLightMessage(payload, {colornamer: true});
116
- message.updated = hueLight.msg;
117
- }
118
- else if(type == "group")
119
- {
120
- let hueGroup = new HueGroupMessage(payload, {colornamer: true});
121
- message.updated = hueGroup.msg;
62
+ resolve(bridgeInformation);
63
+ });
122
64
  }
123
- else if(type == "rule")
65
+ else if(scope.lastBridgeInformation !== null)
124
66
  {
125
- let hueRules = new HueRulesMessage(payload);
126
- message.updated = hueRules.msg;
67
+ let bridgeInformationCopy = Object.assign({}, scope.lastBridgeInformation);
68
+ resolve(bridgeInformationCopy);
127
69
  }
128
- else if(type == "sensor")
70
+ else
129
71
  {
130
- // DETERMINE TYPE
131
- if(payload.type == "ZLLPresence")
132
- {
133
- let hueMotion = new HueMotionMessage(payload);
134
- message.updated = hueMotion.msg;
135
-
136
- detType = "motion";
137
- }
138
- else if(payload.type == "ZLLLightLevel")
139
- {
140
- let hueBrightness = new HueBrightnessMessage(payload);
141
- message.updated = hueBrightness.msg;
142
-
143
- detType = "brightness";
144
- }
145
- else if(payload.type == "ZLLTemperature")
146
- {
147
- let hueTemperature = new HueTemperatureMessage(payload);
148
- message.updated = hueTemperature.msg;
149
-
150
- detType = "temperature";
151
- }
152
- else if(payload.type == "ZLLSwitch")
153
- {
154
- let hueSwitch = new HueSwitchMessage(payload);
155
- message.updated = hueSwitch.msg;
156
-
157
- detType = "switch";
158
- }
159
- else if(payload.type == "ZGPSwitch")
160
- {
161
- let hueTap = new HueTapMessage(sensor);
162
- message.updated = hueTap.msg;
72
+ let bridgeInformation = bridge.get("bridge", "bridge", { autoupdate: ((bridge.config.autoupdates && bridge.config.autoupdates == true) || typeof bridge.config.autoupdates == 'undefined') });
73
+ scope.lastBridgeInformation = Object.assign({}, bridgeInformation);
163
74
 
164
- detType = "tap";
165
- }
75
+ resolve(bridgeInformation);
166
76
  }
167
-
168
- // ADD TYPE
169
- message.updated.type = detType;
170
-
171
- // ADD BRIDGE INFORMATION
172
- message.info = scope.bridgeInformation;
173
-
174
- // SEND MESSAGE
175
- scope.send(message);
176
77
  });
177
78
  }
178
79
 
179
-
180
80
  //
181
- // COMMANDS
182
- this.on('input', function(msg, send, done)
81
+ // SUBSCRIBE TO UPDATES FROM THE BRIDGE
82
+ bridge.subscribe("bridge", "globalRessourceUpdates", async function(info)
183
83
  {
184
- // Node-RED < 1.0
185
- send = send || function() { scope.send.apply(scope,arguments); }
84
+ let currentState = bridge.get(info.updatedType, info.id);
186
85
 
187
- var commandSent = false;
188
-
189
- // STARTING TOUCHLINK
190
- if(typeof msg.payload.touchLink != 'undefined')
191
- {
192
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.starting-tl" });
193
- bridge.client.bridge.touchlink()
194
- .then(() => {
195
- scope.status({fill: "blue", shape: "ring", text: "hue-bridge.node.started-tl" });
196
- if(done) { done(); }
197
- setTimeout(function(){ scope.getBridgeInformation(); }, 30000);
198
- })
199
- .catch(error => {
200
- scope.error(error);
201
- if(done) { done(error); }
202
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
203
- });
204
-
205
- // COMMAND SENT
206
- commandSent = true;
207
- }
208
-
209
- // GET DEVICES
210
- if(typeof msg.payload.fetch != 'undefined')
86
+ // RESSOURCE FOUND?
87
+ if(currentState !== false)
211
88
  {
212
- if(msg.payload.fetch == "users")
89
+ // UPDATE COUNTER
90
+ if(info.suppressMessage === false)
213
91
  {
214
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.f-users" });
215
- bridge.client.users.getAll()
216
- .then(users => {
217
- setTimeout(function(){ scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connected" }); }, 2000);
92
+ scope.status({fill: "blue", shape: "dot", text: "hue-bridge.node.connected"});
218
93
 
219
- var message = {};
220
- message.users = users;
221
- message.info = scope.bridgeInformation;
222
-
223
- send(message);
224
- if(done) { done(); }
225
- })
226
- .catch(error => {
227
- scope.error(error);
228
- if(done) { done(error); }
229
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
230
- });
94
+ if(scope.timeout !== null) { clearTimeout(scope.timeout); }
95
+ scope.timeout = setTimeout(function() {
96
+ scope.setInitialState();
97
+ }, 1000);
231
98
  }
232
- else if(msg.payload.fetch == "lights")
233
- {
234
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.f-lights" });
235
- bridge.client.lights.getAll()
236
- .then(lights => {
237
- setTimeout(function(){ scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connected" }); }, 2000);
238
-
239
- var message = {};
240
- message.lights = lights;
241
- message.info = scope.bridgeInformation;
242
99
 
243
- send(message);
244
- if(done) { done(); }
245
- })
246
- .catch(error => {
247
- scope.error(error);
248
- if(done) { done(error); }
249
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
250
- });
251
- }
252
- else if(msg.payload.fetch == "groups")
100
+ // SEND MESSAGE
101
+ if(!config.skipglobalevents && (config.initevents || info.suppressMessage == false))
253
102
  {
254
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.f-groups" });
255
- bridge.client.groups.getAll()
256
- .then(groups => {
257
- setTimeout(function(){ scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connected" }); }, 2000);
258
-
259
- var message = {};
260
- message.groups = groups;
261
- message.info = scope.bridgeInformation;
103
+ scope.getBridgeInformation()
104
+ .then(function(info)
105
+ {
106
+ // ADD DEVICE UPDATE TO RESPONSE
107
+ info.updated = currentState;
262
108
 
263
- send(message);
264
- if(done) { done(); }
265
- })
266
- .catch(error => {
267
- scope.error(error);
268
- if(done) { done(error); }
269
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
270
- });
271
- }
272
- else if(msg.payload.fetch == "sensors")
273
- {
274
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.f-sensors" });
275
- bridge.client.sensors.getAll()
276
- .then(sensors => {
277
- setTimeout(function(){ scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connected" }); }, 2000);
109
+ // SET LAST COMMAND
110
+ if(scope.lastCommand !== null)
111
+ {
112
+ info.command = scope.lastCommand;
113
+ }
278
114
 
279
- var message = {};
280
- message.sensors = sensors;
281
- message.info = scope.bridgeInformation;
115
+ // SEND MESSAGE
116
+ scope.send(info);
282
117
 
283
- send(message);
284
- if(done) { done(); }
285
- })
286
- .catch(error => {
287
- scope.error(error);
288
- if(done) { done(error); }
289
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
118
+ // RESET LAST COMMAND
119
+ scope.lastCommand = null;
290
120
  });
291
121
  }
292
- else if(msg.payload.fetch == "scenes")
293
- {
294
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.f-scenes" });
295
- bridge.client.scenes.getAll()
296
- .then(scenes => {
297
- setTimeout(function(){ scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connected" }); }, 2000);
122
+ }
298
123
 
299
- var message = {};
300
- message.scenes = scenes;
301
- message.info = scope.bridgeInformation;
124
+ // CONNECTED?
125
+ if(scope.connected == false)
126
+ {
127
+ scope.connected = true;
128
+ scope.setInitialState();
129
+ }
130
+ });
302
131
 
303
- send(message);
304
- if(done) { done(); }
305
- })
306
- .catch(error => {
307
- scope.error(error);
308
- if(done) { done(error); }
309
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
310
- });
311
- }
312
- else if(msg.payload.fetch == "rules")
313
- {
314
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.f-rules" });
315
- bridge.client.rules.getAll()
316
- .then(rules => {
317
- setTimeout(function(){ scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connected" }); }, 2000);
132
+ //
133
+ // ON COMMAND
134
+ this.on('input', function(msg, send, done)
135
+ {
136
+ // REDEFINE SEND AND DONE IF NOT AVAILABLE
137
+ send = send || function() { scope.send.apply(scope,arguments); }
138
+ done = done || function() { scope.done.apply(scope,arguments); }
318
139
 
319
- var message = {};
320
- message.rules = rules;
321
- message.info = scope.bridgeInformation;
140
+ // SET LAST COMMAND
141
+ scope.lastCommand = msg;
322
142
 
323
- send(message);
324
- if(done) { done(); }
325
- })
326
- .catch(error => {
327
- scope.error(error);
328
- if(done) { done(error); }
329
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
330
- });
331
- }
332
- else if(msg.payload.fetch == "schedules")
143
+ // GET BRIDGE INFORMATION
144
+ scope.getBridgeInformation()
145
+ .then(function(bridgeInformation)
146
+ {
147
+ // START TOUCHLINK
148
+ if(typeof msg.payload != 'undefined' && typeof msg.payload.touchLink != 'undefined')
333
149
  {
334
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.f-schedules" });
335
- bridge.client.schedules.getAll()
336
- .then(schedules => {
337
- setTimeout(function(){ scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connected" }); }, 2000);
338
-
339
- var message = {};
340
- message.schedules = schedules;
341
- message.info = scope.bridgeInformation;
150
+ // SET STATUS
151
+ scope.status({fill: "yellow", shape: "dot", text: "hue-bridge.node.starting-tl" });
342
152
 
343
- send(message);
153
+ // ENABLE TOUCHLINK
154
+ bridge.patch("bridge", "/config", { touchlink: true }, 1)
155
+ .then(function(status)
156
+ {
157
+ // SET STATUS
158
+ scope.status({fill: "blue", shape: "ring", text: "hue-bridge.node.started-tl" });
344
159
  if(done) { done(); }
345
- })
346
- .catch(error => {
347
- scope.error(error);
348
- if(done) { done(error); }
349
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
350
- });
351
- }
352
- else if(msg.payload.fetch == "resourceLinks")
353
- {
354
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.f-rlinks" });
355
- bridge.client.resourceLinks.getAll()
356
- .then(resourceLinks => {
357
- setTimeout(function(){ scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connected" }); }, 2000);
358
-
359
- var message = {};
360
- message.resourceLinks = resourceLinks;
361
- message.info = scope.bridgeInformation;
362
160
 
363
- send(message);
364
- if(done) { done(); }
161
+ // RESET STATUS AFTER 30 SECONDS
162
+ setTimeout(function()
163
+ {
164
+ scope.setInitialState();
165
+ scope.getBridgeInformation(true);
166
+ }, 30000);
365
167
  })
366
- .catch(error => {
168
+ .catch(function(error)
169
+ {
367
170
  scope.error(error);
368
171
  if(done) { done(error); }
369
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
370
172
  });
371
173
  }
372
- else if(msg.payload.fetch == "timeZones")
174
+ // FETCH RESSOURCES
175
+ else if(typeof msg.payload != 'undefined' && typeof msg.payload.fetch != 'undefined')
373
176
  {
374
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.f-timezones" });
375
- bridge.client.timeZones.getAll()
376
- .then(timeZones => {
377
- setTimeout(function(){ scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connected" }); }, 2000);
177
+ let fetchTypes = [];
178
+ if(typeof msg.payload.fetch == 'string') { fetchTypes.push(msg.payload.fetch); }
179
+ else if(typeof msg.payload.fetch == 'object') { fetchTypes = msg.payload.fetch; }
180
+ else { return false; }
378
181
 
379
- var message = {};
380
- message.timeZones = timeZones;
381
- message.info = scope.bridgeInformation;
182
+ scope.status({fill: "blue", shape: "dot", text: "hue-bridge.node.f-ressources" });
382
183
 
383
- send(message);
384
- if(done) { done(); }
385
- })
386
- .catch(error => {
387
- scope.error(error);
388
- if(done) { done(error); }
389
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
184
+ // FETCH
185
+ bridgeInformation.results = {};
186
+ fetchTypes.forEach(function(fetch)
187
+ {
188
+ bridgeInformation.results[fetch] = bridge.get(fetch);
390
189
  });
391
- }
392
- else if(msg.payload.fetch == "internetServices")
393
- {
394
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.f-internet" });
395
- bridge.client.internetServices.get()
396
- .then(internetServices => {
397
- setTimeout(function(){ scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connected" }); }, 2000);
398
190
 
399
- var message = {};
400
- message.internetServices = internetServices;
401
- message.info = scope.bridgeInformation;
191
+ // SEND RESULTS
192
+ if(scope.lastCommand !== null)
193
+ {
194
+ bridgeInformation.command = scope.lastCommand;
195
+ }
402
196
 
403
- send(message);
404
- if(done) { done(); }
405
- })
406
- .catch(error => {
407
- scope.error(error);
408
- if(done) { done(error); }
409
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
410
- });
411
- }
412
- else if(msg.payload.fetch == "portal")
413
- {
414
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.f-portal" });
415
- bridge.client.portal.get()
416
- .then(portal => {
417
- setTimeout(function(){ scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.connected" }); }, 2000);
197
+ send(bridgeInformation);
418
198
 
419
- var message = {};
420
- message.portal = portal;
421
- message.info = scope.bridgeInformation;
199
+ // RESET LAST COMMAND
200
+ scope.lastCommand = null;
201
+ if(done) { done(); }
422
202
 
423
- send(message);
424
- if(done) { done(); }
425
- })
426
- .catch(error => {
427
- scope.error(error);
428
- if(done) { done(error); }
429
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
430
- });
203
+ // RESET STATUS
204
+ setTimeout(function(){ scope.setInitialState(); }, 2000);
431
205
  }
206
+ // UPDATE SETTINGS
207
+ else if(typeof msg.payload != 'undefined' && typeof msg.payload.settings != 'undefined')
208
+ {
209
+ let patchObject = {};
432
210
 
433
- commandSent = true;
434
- }
435
-
436
- // UPDATING SETTINGS
437
- if(typeof msg.payload.settings != 'undefined')
438
- {
439
- scope.status({fill: "grey", shape: "dot", text: "hue-bridge.node.updating-settings" });
440
- bridge.client.bridge.get()
441
- .then(bridgeConfig => {
442
211
  if(typeof msg.payload.settings.name != 'undefined')
443
212
  {
444
- bridgeConfig.name = msg.payload.settings.name;
213
+ patchObject.name = msg.payload.settings.name;
445
214
  }
446
215
  if(typeof msg.payload.settings.zigbeeChannel != 'undefined')
447
216
  {
448
- bridgeConfig.zigbeeChannel = msg.payload.settings.zigbeeChannel;
217
+ patchObject.zigbeechannel = msg.payload.settings.zigbeeChannel;
449
218
  }
450
219
  if(typeof msg.payload.settings.ipAddress != 'undefined')
451
220
  {
452
- bridgeConfig.ipAddress = msg.payload.settings.ipAddress;
221
+ patchObject.ipaddress = msg.payload.settings.ipAddress;
453
222
  }
454
223
  if(typeof msg.payload.settings.dhcpEnabled != 'undefined')
455
224
  {
456
- bridgeConfig.dhcpEnabled = msg.payload.settings.dhcpEnabled;
225
+ patchObject.dhcp = msg.payload.settings.dhcpEnabled;
457
226
  }
458
227
  if(typeof msg.payload.settings.netmask != 'undefined')
459
228
  {
460
- bridgeConfig.netmask = msg.payload.settings.netmask;
229
+ patchObject.netmask = msg.payload.settings.netmask;
461
230
  }
462
231
  if(typeof msg.payload.settings.gateway != 'undefined')
463
232
  {
464
- bridgeConfig.gateway = msg.payload.settings.gateway;
233
+ patchObject.gateway = msg.payload.settings.gateway;
465
234
  }
466
235
  if(typeof msg.payload.settings.proxyPort != 'undefined')
467
236
  {
468
- bridgeConfig.proxyPort = msg.payload.settings.proxyPort;
237
+ patchObject.proxyport = msg.payload.settings.proxyPort;
469
238
  }
470
239
  if(typeof msg.payload.settings.proxyAddress != 'undefined')
471
240
  {
472
- bridgeConfig.proxyAddress = msg.payload.settings.proxyAddress;
241
+ patchObject.proxyaddress = msg.payload.settings.proxyAddress;
473
242
  }
474
243
  if(typeof msg.payload.settings.timeZone != 'undefined')
475
244
  {
476
- bridgeConfig.timeZone = msg.payload.settings.timeZone;
245
+ patchObject.timezone = msg.payload.settings.timeZone;
477
246
  }
478
- return bridge.client.bridge.save(bridgeConfig);
479
- })
480
- .then(bridgeInformation => {
481
- scope.status({fill: "green", shape: "dot", text: "hue-bridge.node.settings-updated" });
482
- if(done) { done(); }
483
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
484
- })
485
- .catch(error => {
486
- scope.error(error);
487
- if(done) { done(error); }
488
- setTimeout(function(){ scope.getBridgeInformation(); }, 2000);
489
- });
490
-
491
- // COMMAND SENT
492
- commandSent = true;
493
- }
494
247
 
495
- // GET INFORMATION // FALLBACK
496
- if(commandSent == false)
497
- {
498
- scope.getBridgeInformation();
499
- }
500
- });
248
+ // PATCH BRIDGE!
249
+ if(Object.values(patchObject).length > 0)
250
+ {
251
+ // SET UPDATING STATUS
252
+ scope.status({fill: "yellow", shape: "dot", text: "hue-bridge.node.updating-settings" });
253
+
254
+ // PATCH BRIDGE
255
+ bridge.patch("bridge", "/config", patchObject, 1)
256
+ .then(function(patched)
257
+ {
258
+ // GET RELOADED BRIDGE INFORMATION
259
+ return scope.getBridgeInformation(true);
260
+ })
261
+ .then(function(bridgeInformation)
262
+ {
263
+ scope.status({fill: "blue", shape: "dot", text: "hue-bridge.node.settings-updated" });
264
+
265
+ // SET LAST COMMAND
266
+ if(scope.lastCommand !== null)
267
+ {
268
+ bridgeInformation.command = scope.lastCommand;
269
+ }
270
+
271
+ scope.send(bridgeInformation);
272
+
273
+ // RESET LAST COMMAND
274
+ scope.lastCommand = null;
275
+
276
+ if(done) { done(); }
277
+ setTimeout(function(){ scope.setInitialState(); }, 3000);
278
+ })
279
+ .catch(function(error) {
280
+ scope.error(error);
281
+ if(done) { done(error); }
282
+ });
283
+ }
284
+ }
285
+ // GIVE BACK CURRENT STATE
286
+ else
287
+ {
288
+ // SEND MESSAGE
289
+ if(scope.lastCommand !== null)
290
+ {
291
+ bridgeInformation.command = scope.lastCommand;
292
+ }
501
293
 
502
- //
503
- // CLOSE NODE
504
- this.on('close', function()
505
- {
506
- scope.nodeActive = false;
294
+ scope.send(bridgeInformation);
295
+
296
+ // RESET LAST COMMAND
297
+ scope.lastCommand = null;
298
+ }
299
+ });
507
300
  });
508
301
  }
509
302
 
510
303
  RED.nodes.registerType("hue-bridge-node", HueBridgeNode);
511
- }
304
+ }