node-red-contrib-huemagic 3.0.0 → 4.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/README.md +764 -603
  2. package/examples/Hue Bridge.json +189 -35
  3. package/examples/Hue Brightness.json +124 -14
  4. package/examples/Hue Buttons.json +88 -0
  5. package/examples/Hue Group.json +575 -63
  6. package/examples/Hue Light.json +805 -58
  7. package/examples/Hue Magic.json +69 -24
  8. package/examples/Hue Motion.json +110 -42
  9. package/examples/Hue Rules.json +105 -37
  10. package/examples/Hue Scene.json +145 -28
  11. package/examples/Hue Temperature.json +124 -14
  12. package/huemagic/animations/019-christmas.json +30 -0
  13. package/huemagic/animations/020-superhero.json +56 -0
  14. package/huemagic/animations/021-neoncity.json +52 -0
  15. package/huemagic/animations/previews/006-fireplace.gif +0 -0
  16. package/huemagic/animations/previews/013-strobo.gif +0 -0
  17. package/huemagic/animations/previews/014-randomrainbow.gif +0 -0
  18. package/huemagic/animations/previews/016-milkyway.gif +0 -0
  19. package/huemagic/animations/previews/018-forest.gif +0 -0
  20. package/huemagic/animations/previews/019-christmas.gif +0 -0
  21. package/huemagic/animations/previews/020-superhero.gif +0 -0
  22. package/huemagic/animations/previews/021-neoncity.gif +0 -0
  23. package/huemagic/hue-bridge-config.html +105 -61
  24. package/huemagic/hue-bridge-config.js +631 -319
  25. package/huemagic/hue-bridge.html +41 -21
  26. package/huemagic/hue-bridge.js +190 -396
  27. package/huemagic/hue-brightness.html +127 -59
  28. package/huemagic/hue-brightness.js +111 -55
  29. package/huemagic/hue-buttons.html +197 -0
  30. package/huemagic/hue-buttons.js +158 -0
  31. package/huemagic/hue-group.html +137 -66
  32. package/huemagic/hue-group.js +387 -403
  33. package/huemagic/hue-light.html +132 -64
  34. package/huemagic/hue-light.js +544 -378
  35. package/huemagic/hue-magic.html +36 -20
  36. package/huemagic/hue-magic.js +49 -27
  37. package/huemagic/hue-motion.html +127 -59
  38. package/huemagic/hue-motion.js +105 -101
  39. package/huemagic/hue-rules.html +121 -50
  40. package/huemagic/hue-rules.js +89 -63
  41. package/huemagic/hue-scene.html +95 -114
  42. package/huemagic/hue-scene.js +64 -95
  43. package/huemagic/hue-temperature.html +127 -59
  44. package/huemagic/hue-temperature.js +120 -56
  45. package/huemagic/icons/hue-bridge.png +0 -0
  46. package/huemagic/icons/hue-bridge.svg +3 -0
  47. package/huemagic/icons/hue-brightness.png +0 -0
  48. package/huemagic/icons/hue-brightness.svg +11 -0
  49. package/huemagic/icons/hue-buttons.png +0 -0
  50. package/huemagic/icons/hue-buttons.svg +4 -0
  51. package/huemagic/icons/hue-group.png +0 -0
  52. package/huemagic/icons/hue-group.svg +12 -0
  53. package/huemagic/icons/hue-light.png +0 -0
  54. package/huemagic/icons/hue-light.svg +3 -0
  55. package/huemagic/icons/hue-magic.png +0 -0
  56. package/huemagic/icons/hue-magic.svg +3 -0
  57. package/huemagic/icons/hue-motion.png +0 -0
  58. package/huemagic/icons/hue-motion.svg +9 -0
  59. package/huemagic/icons/hue-rules.png +0 -0
  60. package/huemagic/icons/hue-rules.svg +4 -0
  61. package/huemagic/icons/hue-scene.png +0 -0
  62. package/huemagic/icons/hue-scene.svg +5 -0
  63. package/huemagic/icons/hue-temperature.png +0 -0
  64. package/huemagic/icons/hue-temperature.svg +7 -0
  65. package/huemagic/locales/de/hue-bridge-config.html +17 -12
  66. package/huemagic/locales/de/hue-bridge-config.json +7 -5
  67. package/huemagic/locales/de/hue-bridge.html +64 -145
  68. package/huemagic/locales/de/hue-bridge.json +6 -17
  69. package/huemagic/locales/de/hue-brightness.html +50 -50
  70. package/huemagic/locales/de/hue-brightness.json +6 -5
  71. package/huemagic/locales/de/hue-buttons.html +58 -0
  72. package/huemagic/locales/de/{hue-button.json → hue-buttons.json} +7 -11
  73. package/huemagic/locales/de/hue-group.html +46 -122
  74. package/huemagic/locales/de/hue-group.json +5 -5
  75. package/huemagic/locales/de/hue-light.html +68 -116
  76. package/huemagic/locales/de/hue-light.json +5 -5
  77. package/huemagic/locales/de/hue-magic.html +65 -57
  78. package/huemagic/locales/de/hue-magic.json +2 -1
  79. package/huemagic/locales/de/hue-motion.html +47 -50
  80. package/huemagic/locales/de/hue-motion.json +5 -5
  81. package/huemagic/locales/de/hue-rules.html +68 -73
  82. package/huemagic/locales/de/hue-rules.json +5 -2
  83. package/huemagic/locales/de/hue-scene.html +23 -32
  84. package/huemagic/locales/de/hue-scene.json +5 -2
  85. package/huemagic/locales/de/hue-temperature.html +51 -48
  86. package/huemagic/locales/de/hue-temperature.json +6 -5
  87. package/huemagic/locales/en-US/hue-bridge-config.html +17 -12
  88. package/huemagic/locales/en-US/hue-bridge-config.json +5 -3
  89. package/huemagic/locales/en-US/hue-bridge.html +64 -145
  90. package/huemagic/locales/en-US/hue-bridge.json +5 -16
  91. package/huemagic/locales/en-US/hue-brightness.html +50 -50
  92. package/huemagic/locales/en-US/hue-brightness.json +5 -2
  93. package/huemagic/locales/en-US/hue-buttons.html +58 -0
  94. package/huemagic/locales/en-US/{hue-button.json → hue-buttons.json} +6 -4
  95. package/huemagic/locales/en-US/hue-group.html +46 -122
  96. package/huemagic/locales/en-US/hue-group.json +4 -2
  97. package/huemagic/locales/en-US/hue-light.html +68 -116
  98. package/huemagic/locales/en-US/hue-light.json +4 -2
  99. package/huemagic/locales/en-US/hue-magic.html +65 -57
  100. package/huemagic/locales/en-US/hue-magic.json +3 -1
  101. package/huemagic/locales/en-US/hue-motion.html +47 -50
  102. package/huemagic/locales/en-US/hue-motion.json +4 -2
  103. package/huemagic/locales/en-US/hue-rules.html +68 -73
  104. package/huemagic/locales/en-US/hue-rules.json +5 -2
  105. package/huemagic/locales/en-US/hue-scene.html +23 -32
  106. package/huemagic/locales/en-US/hue-scene.json +5 -2
  107. package/huemagic/locales/en-US/hue-temperature.html +51 -48
  108. package/huemagic/locales/en-US/hue-temperature.json +5 -2
  109. package/huemagic/utils/api.js +290 -0
  110. package/huemagic/utils/color.js +382 -0
  111. package/{utils → huemagic/utils}/merge.js +4 -6
  112. package/huemagic/utils/messages.js +447 -0
  113. package/package.json +9 -15
  114. package/examples/Hue Button.json +0 -40
  115. package/examples/Hue Switch.json +0 -40
  116. package/examples/Hue Tap.json +0 -40
  117. package/huemagic/hue-button.html +0 -132
  118. package/huemagic/hue-button.js +0 -143
  119. package/huemagic/hue-switch.html +0 -132
  120. package/huemagic/hue-switch.js +0 -163
  121. package/huemagic/hue-tap.html +0 -132
  122. package/huemagic/hue-tap.js +0 -123
  123. package/huemagic/icons/hue-button.png +0 -0
  124. package/huemagic/icons/hue-switch.png +0 -0
  125. package/huemagic/icons/hue-tap.png +0 -0
  126. package/huemagic/locales/de/hue-button.html +0 -64
  127. package/huemagic/locales/de/hue-switch.html +0 -64
  128. package/huemagic/locales/de/hue-switch.json +0 -35
  129. package/huemagic/locales/de/hue-tap.html +0 -55
  130. package/huemagic/locales/de/hue-tap.json +0 -27
  131. package/huemagic/locales/en-US/hue-button.html +0 -64
  132. package/huemagic/locales/en-US/hue-switch.html +0 -64
  133. package/huemagic/locales/en-US/hue-switch.json +0 -35
  134. package/huemagic/locales/en-US/hue-tap.html +0 -55
  135. package/huemagic/locales/en-US/hue-tap.json +0 -27
  136. package/utils/color.js +0 -9
  137. package/utils/messages.js +0 -658
  138. package/utils/rgb.js +0 -188
@@ -1,32 +1,34 @@
1
1
  <script type="text/x-red" data-template-name="hue-brightness">
2
2
  <div class="form-row">
3
3
  <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="hue-brightness.config.name"></span></label>
4
- <input type="text" id="node-input-name" data-i18n="[placeholder]hue-brightness.config.input-name">
4
+ <input type="text" id="node-input-name" data-i18n="[placeholder]hue-brightness.config.input-name" style="width: calc(100% - 105px)">
5
5
  </div>
6
6
  <div class="form-row">
7
7
  <label for="node-input-bridge"><i class="fa fa-server"></i> Bridge</label>
8
- <input type="text" id="node-input-bridge">
8
+ <input type="text" id="node-input-bridge" style="width: calc(100% - 105px)">
9
9
  </div>
10
10
  <div class="form-row">
11
11
  <label for="node-input-sensorid"><i class="fa fa-sun-o"></i> <span data-i18n="hue-brightness.config.sensor"></span></label>
12
- <div style="display: inline-block; position: relative; width: 70%; height: 20px;">
13
- <div style="position: absolute; left: 0px; right: 40px;">
14
- <input type="text" id="node-input-sensorid" placeholder="1" style="width: 100%"/>
12
+ <div style="display: inline-flex; width: calc(100% - 105px)">
13
+ <div id="input-select-toggle" style="flex-grow: 1;">
14
+ <input type="text" id="node-input-sensorid" placeholder="00000000-0000-0000-0000-000000000000" style="width: 100%"/>
15
15
  </div>
16
- <a id="node-config-input-scan-temp-sensors" class="editor-button" style="position: absolute; right: 0px; top: 0px;">
16
+ <button id="node-config-input-scan-temp-sensors" type="button" class="red-ui-button" style="margin-left: 10px;">
17
17
  <i class="fa fa-search"></i>
18
- </a>
18
+ </button>
19
19
  </div>
20
20
  </div>
21
- <div class="form-row">
22
- <label for="node-input-skipevents"><i class="fa fa-sign-out"></i> <span data-i18n="hue-brightness.config.skipevents"></span></label>
23
- <input type="checkbox" id="node-input-skipevents" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="hue-brightness.config.skipevents-node"></span>
24
- </label>
21
+ <div class="form-row" style="margin-top: 30px">
22
+ <div style="display: inline-flex; width: calc(100% - 105px)">
23
+ <input type="checkbox" id="node-input-skipevents" style="flex: 15px;">
24
+ <span data-i18n="hue-brightness.config.skipevents-node" style="width: 100%; margin-left: 10px;"></span>
25
+ </div>
25
26
  </div>
26
27
  <div class="form-row">
27
- <label for="node-input-universalevents"><i class="fa fa-bullhorn"></i> <span data-i18n="hue-brightness.config.universalevents"></span></label>
28
- <input type="checkbox" id="node-input-universalevents" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="hue-brightness.config.universalevents-node"></span>
29
- </label>
28
+ <div style="display: inline-flex; width: calc(100% - 105px)">
29
+ <input type="checkbox" id="node-input-initevents" style="flex: 15px;">
30
+ <span data-i18n="hue-brightness.config.sendinitevents-node" style="width: 100%; margin-left: 10px;"></span>
31
+ </div>
30
32
  </div>
31
33
  </script>
32
34
 
@@ -35,95 +37,161 @@
35
37
  category: 'HueMagic',
36
38
  color: '#f1c40f',
37
39
  defaults: {
38
- name: {value:""},
39
- bridge: {type: "hue-bridge", required: true},
40
- sensorid: {value:"", required: false, validate: function(id) {
41
- if(id.length < 1) { return true; }
42
- else if(!isNaN(id)) { return true; }
43
- else { return false; }
44
- }},
45
- skipevents: {value: false},
46
- universalevents: {value: false}
40
+ name: { value:"" },
41
+ bridge: { type: "hue-bridge", required: true },
42
+ sensorid: { value:"", required: false },
43
+ skipevents: { value: false },
44
+ initevents: { value: false }
47
45
  },
46
+ align: 'left',
47
+ icon: "hue-brightness.png",
48
48
  inputs: 1,
49
49
  outputs: 1,
50
+ label: function() {
51
+ return this.name || this._("hue-brightness.node.title");
52
+ },
53
+ paletteLabel: function() {
54
+ return this._("hue-brightness.node.title");
55
+ },
50
56
  inputLabels: function() {
51
57
  return this._("hue-brightness.node.input");
52
58
  },
53
59
  outputLabels: function() {
54
60
  return this._("hue-brightness.node.output");
55
61
  },
56
- align: 'right',
57
- icon: "hue-brightness.png",
58
- paletteLabel: function() {
59
- return this._("hue-brightness.node.title");
60
- },
61
- label: function() {
62
- return this.name || this._("hue-brightness.node.title");
63
- },
64
62
  oneditprepare: function()
65
63
  {
66
- var scope = this;
64
+ const scope = this;
65
+ let options = [];
67
66
 
68
- function manualLightSensorID()
67
+ function manualInput()
69
68
  {
69
+ // GET CURRENT SELECTED VALUE
70
70
  var current = $('#node-input-sensorid').val();
71
- $('#node-input-sensorid').replaceWith('<input type="text" id="node-input-sensorid" style="width: 100%"/>');
72
- $('#node-input-sensorid').val(current);
71
+
72
+ // REMOVE SELECT FIELD
73
+ $('#input-select-toggle').empty();
74
+
75
+ // CREATE NEW INPUT FIELD
76
+ $('#input-select-toggle').append('<input type="text" id="node-input-sensorid" placeholder="00000000-0000-0000-0000-000000000000" style="width: 100%" value="'+current+'" />');
77
+
78
+ // CHANGE BUTTON ICON
79
+ var button = $("#node-config-input-scan-temp-sensors");
80
+ var buttonIcon = button.find("i");
81
+ buttonIcon.removeClass("fa-pencil");
82
+ buttonIcon.addClass("fa-search");
73
83
  }
74
84
 
75
- function searchAndSelectLightSensorID()
85
+ function searchAndSelect()
76
86
  {
87
+ // GET CURRENT BRIDGE CONFIGURATION
88
+ var bridgeConfig = RED.nodes.node($('#node-input-bridge option:selected').val());
89
+ if(!bridgeConfig) { return false; }
90
+
91
+ // GET CURRENT SELECTED VALUE
77
92
  var current = $('#node-input-sensorid').val();
78
- $('#node-input-sensorid').replaceWith('<select id="node-input-sensorid" style="width: 100%"></select>');
79
- $('#node-input-sensorid').append('<option selected="selected" value="null">'+scope._("hue-brightness.config.searching")+'</option>');
80
93
 
81
- var bridgeConfig = RED.nodes.node($('#node-input-bridge option:selected').val());
82
- $.get('hue/sensors', {bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "ZLLLightLevel"})
83
- .done( function(data) {
84
- var lightSensors = JSON.parse(data);
94
+ // TRIGGER SEARCHING NOTIFICATION
95
+ var notification = RED.notify(scope._("hue-brightness.config.searching"), { type: "compact", modal: true, fixed: true });
85
96
 
86
- if(lightSensors.length <= 0)
97
+ // GET THE SENSORS
98
+ $.get('hue/resources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "motion" })
99
+ .done( function(data) {
100
+ var allResources = JSON.parse(data);
101
+ if(allResources.length <= 0)
87
102
  {
88
- RED.notify(scope._("hue-brightness.config.none-found"), "error");
103
+ notification.close();
104
+ RED.notify(scope._("hue-brightness.config.none-found"), { type: "light_level" });
105
+ return false;
89
106
  }
90
107
 
91
- // RESET OPTIONS
92
- $('#node-input-sensorid').empty();
93
-
94
- // SET TEMPERATURE SENSORS AS OPTIONS
95
- lightSensors.forEach(function(sensor)
108
+ // SET OPTIONS
109
+ allResources.forEach(function(resource)
96
110
  {
97
- $('#node-input-sensorid').append('<option value="' + sensor.id + '">' + sensor.name + '</option>');
111
+ if(resource.model)
112
+ {
113
+ options[resource.id] = { value: resource.id, label: resource.name + " ("+resource.model+")" };
114
+ }
115
+ else
116
+ {
117
+ options[resource.id] = { value: resource.id, label: resource.name };
118
+ }
98
119
  });
99
120
 
100
121
  // SELECT CURRENT VALUE
101
- $('#node-input-sensorid').val(current);
122
+ $("#node-input-sensorid").typedInput({
123
+ types: [
124
+ {
125
+ value: current,
126
+ options: Object.values(options)
127
+ }
128
+ ]
129
+ });
130
+
131
+ // CHANGE BUTTON ICON
132
+ var button = $("#node-config-input-scan-temp-sensors");
133
+ var buttonIcon = button.find("i");
134
+ buttonIcon.removeClass("fa-search");
135
+ buttonIcon.addClass("fa-pencil");
136
+
137
+ // CLOSE SEARCH NOTIFICATION
138
+ notification.close();
102
139
  })
103
140
  .fail(function()
104
141
  {
142
+ notification.close();
105
143
  RED.notify(scope._("hue-brightness.config.unknown-error"), "error");
106
144
  });
107
145
  }
108
146
 
109
- $(document).on('change', '#node-input-sensorid', function()
147
+ // CHANGED SENSOR ID? -> REPLACE NAME (IF POSSIBLE)
148
+ $(document).on('change', '#node-input-sensorid', function(e)
110
149
  {
111
- var sensorName = $('#node-input-sensorid option:selected').text();
112
- if(sensorName.length > 0)
150
+ let currentSelectedOptionID = $(e.currentTarget).val();
151
+ let currentSelectedOptionValue = (currentSelectedOptionID.length > 0 && options[currentSelectedOptionID]) ? options[currentSelectedOptionID].label : false;
152
+
153
+ if(currentSelectedOptionValue !== false)
113
154
  {
114
- $('#node-input-name').val(sensorName);
155
+ $('#node-input-name').val(currentSelectedOptionValue.split(" (")[0]);
115
156
  }
116
157
  });
117
158
 
159
+ // TOGGLE SELECT/INPUT FIELD
118
160
  $('#node-config-input-scan-temp-sensors').click(function()
119
161
  {
120
- if($('#node-input-sensorid').prop("tagName") === "INPUT")
162
+ if($('#input-select-toggle').find(".red-ui-typedInput-container").length > 0)
163
+ {
164
+ manualInput();
165
+ }
166
+ else
121
167
  {
122
- searchAndSelectLightSensorID();
123
- } else {
124
- manualLightSensorID();
168
+ searchAndSelect();
125
169
  }
126
170
  });
171
+ },
172
+ button: {
173
+ enabled: function() {
174
+ return (this.sensorid && this.sensorid.length > 1)
175
+ },
176
+ visible: function() {
177
+ return (this.sensorid && this.sensorid.length > 1)
178
+ },
179
+ onclick: function()
180
+ {
181
+ const node = this;
182
+ if(node.bridge)
183
+ {
184
+ $.ajax({
185
+ url: "inject/" + node.id,
186
+ type: "POST",
187
+ data: JSON.stringify({ __user_inject_props__: "status"}),
188
+ contentType: "application/json; charset=utf-8",
189
+ success: function (resp) {
190
+ RED.notify(node.name + ": " + node._("hue-brightness.node.statusmsg"), { type: "success", id: "status", timeout: 2000 });
191
+ }
192
+ });
193
+ }
194
+ }
127
195
  }
128
196
  });
129
197
  </script>
@@ -6,13 +6,11 @@ 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 { HueBrightnessMessage } = require('../utils/messages');
12
- var universalMode = false;
9
+ const scope = this;
10
+ const bridge = RED.nodes.getNode(config.bridge);
13
11
 
14
- // SAVE LAST STATE
15
- var lastState = false;
12
+ // SAVE LAST COMMAND
13
+ this.lastCommand = null;
16
14
 
17
15
  //
18
16
  // CHECK CONFIG
@@ -26,94 +24,152 @@ module.exports = function(RED)
26
24
  // UNIVERSAL MODE?
27
25
  if(!config.sensorid)
28
26
  {
29
- universalMode = true;
30
27
  this.status({fill: "grey", shape: "dot", text: "hue-brightness.node.universal"});
31
28
  }
32
29
 
33
30
  //
34
31
  // UPDATE STATE
35
- if(typeof bridge.disableupdates != 'undefined'||bridge.disableupdates == false)
32
+ if(typeof bridge.disableupdates != 'undefined' || bridge.disableupdates == false)
36
33
  {
37
34
  this.status({fill: "grey", shape: "dot", text: "hue-brightness.node.init"});
38
35
  }
39
36
 
40
37
  //
41
- // ON UPDATE
42
- if(config.sensorid) { bridge.events.on('sensor' + config.sensorid, function(sensor) { scope.receivedUpdates(sensor) }); }
43
- if(!config.sensorid && config.universalevents && config.universalevents == true) { bridge.events.on('sensor', function(sensor) { scope.receivedUpdates(sensor) }); }
44
-
45
- //
46
- // RECEIVED UPDATES
47
- this.receivedUpdates = function(sensor)
38
+ // SUBSCRIBE TO UPDATES FROM THE BRIDGE
39
+ bridge.subscribe("light_level", config.sensorid, function(info)
48
40
  {
49
- if(sensor.config.reachable == false)
41
+ let currentState = bridge.get("light_level", info.id);
42
+
43
+ // RESOURCE FOUND?
44
+ if(currentState !== false)
50
45
  {
51
- if(universalMode == false)
46
+ // SEND MESSAGE
47
+ if(!config.skipevents && (config.initevents || info.suppressMessage == false))
52
48
  {
53
- scope.status({fill: "red", shape: "ring", text: "hue-brightness.node.not-reachable"});
54
- }
55
- }
56
- else
57
- {
58
- var hueBrightness = new HueBrightnessMessage(sensor, (universalMode == false) ? lastState : false);
59
- var realLUX = hueBrightness.msg.payload.lux;
60
- if(!config.skipevents) { scope.send(hueBrightness.msg); }
49
+ // SET LAST COMMAND
50
+ if(scope.lastCommand !== null)
51
+ {
52
+ currentState.command = scope.lastCommand;
53
+ }
54
+
55
+ scope.send(currentState);
61
56
 
62
- // SAVE LAST STATE
63
- lastState = sensor;
57
+ // RESET LAST COMMAND
58
+ scope.lastCommand = null;
59
+ }
64
60
 
65
- if(universalMode == false)
61
+ // NOT IN UNIVERAL MODE? -> CHANGE UI STATES
62
+ if(config.sensorid)
66
63
  {
67
- if(sensor.state.dark)
64
+ if(currentState.payload.reachable == false)
68
65
  {
69
- var statusMessage = RED._("hue-brightness.node.lux-dark",{lux: realLUX});
70
- scope.status({fill: "blue", shape: "dot", text: statusMessage });
66
+ scope.status({fill: "red", shape: "ring", text: "hue-brightness.node.not-reachable"});
71
67
  }
72
- else if(sensor.state.daylight)
68
+ else if(currentState.payload.active == true)
73
69
  {
74
- var statusMessage = RED._("hue-brightness.node.lux-daylight",{lux: realLUX});
75
- scope.status({fill: "yellow", shape: "dot", text: statusMessage });
70
+ if(currentState.payload.dark)
71
+ {
72
+ var statusMessage = RED._("hue-brightness.node.lux-dark", { lux: currentState.payload.lux });
73
+ scope.status({fill: "blue", shape: "dot", text: statusMessage });
74
+ }
75
+ else if(currentState.payload.daylight)
76
+ {
77
+ var statusMessage = RED._("hue-brightness.node.lux-daylight", { lux: currentState.payload.lux });
78
+ scope.status({fill: "yellow", shape: "dot", text: statusMessage });
79
+ }
80
+ else
81
+ {
82
+ var statusMessage = RED._("hue-brightness.node.lux", { lux: currentState.payload.lux });
83
+ scope.status({fill: "grey", shape: "dot", text: statusMessage });
84
+ }
76
85
  }
77
- else
86
+ else if(currentState.payload.active == false)
78
87
  {
79
- var statusMessage = RED._("hue-brightness.node.lux",{lux: realLUX});
80
- scope.status({fill: "grey", shape: "dot", text: statusMessage });
88
+ scope.status({fill: "red", shape: "ring", text: "hue-brightness.node.deactivated"});
81
89
  }
82
90
  }
83
91
  }
84
- }
92
+ });
85
93
 
86
94
  //
87
95
  // ON COMMAND
88
96
  this.on('input', function(msg, send, done)
89
97
  {
90
- // Node-RED < 1.0
98
+ // REDEFINE SEND AND DONE IF NOT AVAILABLE
91
99
  send = send || function() { scope.send.apply(scope,arguments); }
100
+ done = done || function() { scope.done.apply(scope,arguments); }
101
+
102
+ // SET LAST COMMAND
103
+ scope.lastCommand = RED.util.cloneMessage(msg);
104
+
105
+ // CREATE PATCH
106
+ let patchObject = {};
92
107
 
93
- // DEFINE SENSOR ID
94
- var tempSensorID = (msg.topic != null && isNaN(msg.topic) == false && msg.topic.length > 0) ? parseInt(msg.topic) : config.sensorid;
108
+ // DEFINE SENSOR ID & CURRENT STATE
109
+ const tempSensorID = (!config.sensorid && typeof msg.topic != 'undefined' && bridge.validResourceID.test(msg.topic) === true) ? msg.topic : config.sensorid;
110
+ if(!tempSensorID)
111
+ {
112
+ scope.error("Please submit a valid sensor ID.");
113
+ return false;
114
+ }
115
+
116
+ let currentState = bridge.get("light_level", tempSensorID);
95
117
 
96
118
  // GET CURRENT STATE
97
- if(typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined')
119
+ if( (typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined') || (typeof msg.__user_inject_props__ != 'undefined' && msg.__user_inject_props__ == "status") )
98
120
  {
99
- bridge.client.sensors.getById(tempSensorID)
100
- .then(sensor => {
101
- var hueBrightness = new HueBrightnessMessage(sensor, lastState);
102
- send(hueBrightness.msg);
121
+ // SET LAST COMMAND
122
+ if(scope.lastCommand !== null)
123
+ {
124
+ currentState.command = scope.lastCommand;
125
+ }
103
126
 
104
- return true;
105
- });
127
+ // SEND STATE
128
+ scope.send(currentState);
106
129
 
130
+ // RESET LAST COMMAND
131
+ scope.lastCommand = null;
132
+
133
+ if(done) { done(); }
107
134
  return true;
108
135
  }
109
- });
110
136
 
111
- //
112
- // CLOSE NODE / REMOVE EVENT LISTENER
113
- this.on('close', function()
114
- {
115
- bridge.events.removeAllListeners('sensor' + config.sensorid);
116
- bridge.events.removeAllListeners('sensor');
137
+ // TURN ON / OFF
138
+ if((msg.payload === true || msg.payload === false) && (msg.payload != currentState.payload.active))
139
+ {
140
+ // PREPARE PATCH
141
+ patchObject["enabled"] = (msg.payload == true);
142
+ }
143
+
144
+ //
145
+ // SHOULD PATCH?
146
+ if(Object.values(patchObject).length > 0)
147
+ {
148
+ // CHANGE NODE UI STATE
149
+ if(config.sensorid)
150
+ {
151
+ scope.status({fill: "grey", shape: "ring", text: "hue-brightness.node.command"});
152
+ }
153
+
154
+ // PATCH!
155
+ bridge.patch("light_level", tempSensorID, patchObject)
156
+ .then(function() { if(done) { done(); }})
157
+ .catch(function(errors) { scope.error(errors); });
158
+ }
159
+ else
160
+ {
161
+ // SET LAST COMMAND
162
+ if(scope.lastCommand !== null)
163
+ {
164
+ currentState.command = scope.lastCommand;
165
+ }
166
+
167
+ // SEND STATE
168
+ scope.send(currentState);
169
+
170
+ // RESET LAST COMMAND
171
+ scope.lastCommand = null;
172
+ }
117
173
  });
118
174
  }
119
175