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
@@ -1,27 +1,34 @@
1
1
  <script type="text/x-red" data-template-name="hue-rules">
2
2
  <div class="form-row">
3
3
  <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="hue-rules.config.name"></span></label>
4
- <input type="text" id="node-input-name" data-i18n="[placeholder]hue-rules.config.input-name">
4
+ <input type="text" id="node-input-name" data-i18n="[placeholder]hue-rules.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-ruleid"><i class="fa fa-tasks"></i> <span data-i18n="hue-rules.config.rule"></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-ruleid" 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-ruleid" placeholder="0" style="width: 100%"/>
15
15
  </div>
16
- <a id="node-config-input-scan-rules" class="editor-button" style="position: absolute; right: 0px; top: 0px;">
16
+ <button id="node-config-input-scan-rules" type="button" class="red-ui-button" style="margin-left: 10px;">
17
17
  <i class="fa fa-search"></i>
18
- </a>
18
+ </button>
19
+ </div>
20
+ </div>
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-rules.config.skipevents-node" style="width: 100%; margin-left: 10px;"></span>
19
25
  </div>
20
26
  </div>
21
27
  <div class="form-row">
22
- <label for="node-input-skipevents"><i class="fa fa-sign-out"></i> <span data-i18n="hue-rules.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-rules.config.skipevents-node"></span>
24
- </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-rules.config.sendinitevents-node" style="width: 100%; margin-left: 10px;"></span>
31
+ </div>
25
32
  </div>
26
33
  </script>
27
34
 
@@ -30,90 +37,154 @@
30
37
  category: 'HueMagic',
31
38
  color: '#bddb37',
32
39
  defaults: {
33
- name: {value:""},
34
- bridge: {type: "hue-bridge", required: true},
35
- ruleid: {value:"", required: true, validate: RED.validators.number()},
36
- skipevents: {value: false}
40
+ name: { value:"" },
41
+ bridge: { type: "hue-bridge", required: true },
42
+ ruleid: { value:"", required: false },
43
+ skipevents: { value: false },
44
+ initevents: { value: false }
37
45
  },
46
+ align: 'left',
47
+ icon: "hue-rules.png",
38
48
  inputs: 1,
39
49
  outputs: 1,
50
+ label: function() {
51
+ return this.name || this._("hue-rules.node.title");
52
+ },
53
+ paletteLabel: function() {
54
+ return this._("hue-rules.node.title");
55
+ },
40
56
  inputLabels: function() {
41
57
  return this._("hue-rules.node.input");
42
58
  },
43
59
  outputLabels: function() {
44
60
  return this._("hue-rules.node.output");
45
61
  },
46
- align: 'right',
47
- icon: "hue-rules.png",
48
- paletteLabel: function() {
49
- return this._("hue-rules.node.title");
50
- },
51
- label: function() {
52
- return this.name || this._("hue-rules.node.title");
53
- },
54
62
  oneditprepare: function()
55
63
  {
56
- var scope = this;
64
+ const scope = this;
65
+ let options = [];
57
66
 
58
- function manualRuleID()
67
+ function manualInput()
59
68
  {
69
+ // GET CURRENT SELECTED VALUE
60
70
  var current = $('#node-input-ruleid').val();
61
- $('#node-input-ruleid').replaceWith('<input type="text" id="node-input-ruleid" style="width: 100%"/>');
62
- $('#node-input-ruleid').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-ruleid" placeholder="0" style="width: 100%" value="'+current+'" />');
77
+
78
+ // CHANGE BUTTON ICON
79
+ var button = $("#node-config-input-scan-rules");
80
+ var buttonIcon = button.find("i");
81
+ buttonIcon.removeClass("fa-pencil");
82
+ buttonIcon.addClass("fa-search");
63
83
  }
64
84
 
65
- function searchAndSelectRuleID()
85
+ function searchAndSelect()
66
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
67
92
  var current = $('#node-input-ruleid').val();
68
- $('#node-input-ruleid').replaceWith('<select id="node-input-ruleid" style="width: 100%"></select>');
69
- $('#node-input-ruleid').append('<option selected="selected" value="null">'+scope._("hue-rules.config.searching")+'</option>');
70
93
 
71
- var bridgeConfig = RED.nodes.node($('#node-input-bridge option:selected').val());
72
- $.get('hue/rules', {bridge: bridgeConfig.bridge, key: bridgeConfig.key})
73
- .done( function(data) {
74
- var rules = JSON.parse(data);
94
+ // TRIGGER SEARCHING NOTIFICATION
95
+ var notification = RED.notify(scope._("hue-rules.config.searching"), { type: "compact", modal: true, fixed: true });
75
96
 
76
- if(rules.length <= 0)
97
+ // GET THE SENSORS
98
+ $.get('hue/ressources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "rule" })
99
+ .done( function(data) {
100
+ var allRessources = JSON.parse(data);
101
+ if(allRessources.length <= 0)
77
102
  {
78
- RED.notify(scope._("hue-rules.config.none-found"), "error");
103
+ notification.close();
104
+ RED.notify(scope._("hue-rules.config.none-found"), { type: "error" });
105
+ return false;
79
106
  }
80
107
 
81
- // RESET OPTIONS
82
- $('#node-input-ruleid').empty();
83
-
84
- // SET TEMPERATURE SENSORS AS OPTIONS
85
- rules.forEach(function(rule)
108
+ // SET OPTIONS
109
+ allRessources.forEach(function(ressource)
86
110
  {
87
- $('#node-input-ruleid').append('<option value="' + rule.id + '">' + rule.name + '</option>');
111
+ options[ressource.id] = { value: ressource.id, label: ressource.name };
88
112
  });
89
113
 
90
114
  // SELECT CURRENT VALUE
91
- $('#node-input-ruleid').val(current);
115
+ $("#node-input-ruleid").typedInput({
116
+ types: [
117
+ {
118
+ value: current,
119
+ options: Object.values(options)
120
+ }
121
+ ]
122
+ });
123
+
124
+ // CHANGE BUTTON ICON
125
+ var button = $("#node-config-input-scan-rules");
126
+ var buttonIcon = button.find("i");
127
+ buttonIcon.removeClass("fa-search");
128
+ buttonIcon.addClass("fa-pencil");
129
+
130
+ // CLOSE SEARCH NOTIFICATION
131
+ notification.close();
92
132
  })
93
133
  .fail(function()
94
134
  {
135
+ notification.close();
95
136
  RED.notify(scope._("hue-rules.config.unknown-error"), "error");
96
137
  });
97
138
  }
98
139
 
99
- $(document).on('change', '#node-input-ruleid', function()
140
+ // CHANGED RULE ID? -> REPLACE NAME (IF POSSIBLE)
141
+ $(document).on('change', '#node-input-ruleid', function(e)
100
142
  {
101
- var sensorName = $('#node-input-ruleid option:selected').text();
102
- if(sensorName.length > 0)
143
+ let currentSelectedOptionID = $(e.currentTarget).val();
144
+ let currentSelectedOptionValue = (currentSelectedOptionID.length > 0 && options[currentSelectedOptionID]) ? options[currentSelectedOptionID].label : false;
145
+
146
+ if(currentSelectedOptionValue !== false)
103
147
  {
104
- $('#node-input-name').val(sensorName);
148
+ $('#node-input-name').val(currentSelectedOptionValue.split(" (")[0]);
105
149
  }
106
150
  });
107
151
 
152
+ // TOGGLE SELECT/INPUT FIELD
108
153
  $('#node-config-input-scan-rules').click(function()
109
154
  {
110
- if($('#node-input-ruleid').prop("tagName") === "INPUT")
155
+ if($('#input-select-toggle').find(".red-ui-typedInput-container").length > 0)
156
+ {
157
+ manualInput();
158
+ }
159
+ else
111
160
  {
112
- searchAndSelectRuleID();
113
- } else {
114
- manualRuleID();
161
+ searchAndSelect();
115
162
  }
116
163
  });
164
+ },
165
+ button: {
166
+ enabled: function() {
167
+ return (this.ruleid && (this.ruleid == 0 || this.ruleid.length > 0 || this.ruleid > -1))
168
+ },
169
+ visible: function() {
170
+ return (this.ruleid && (this.ruleid == 0 || this.ruleid.length > 0 || this.ruleid > -1))
171
+ },
172
+ onclick: function()
173
+ {
174
+ const node = this;
175
+ if(node.bridge)
176
+ {
177
+ $.ajax({
178
+ url: "inject/" + node.id,
179
+ type: "POST",
180
+ data: JSON.stringify({ __user_inject_props__: "status"}),
181
+ contentType: "application/json; charset=utf-8",
182
+ success: function (resp) {
183
+ RED.notify(node.name + ": " + node._("hue-rules.node.statusmsg"), { type: "success", id: "status", timeout: 2000 });
184
+ }
185
+ });
186
+ }
187
+ }
117
188
  }
118
189
  });
119
190
  </script>
@@ -6,51 +6,72 @@ 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 { HueRulesMessage } = require('../utils/messages');
9
+ const scope = this;
10
+ const bridge = RED.nodes.getNode(config.bridge);
12
11
 
13
- // SAVE LAST STATE
14
- var lastState = false;
12
+ // SAVE LAST COMMAND
13
+ this.lastCommand = null;
15
14
 
16
15
  //
17
16
  // CHECK CONFIG
18
- if(!config.ruleid || bridge == null)
17
+ if(bridge == null)
19
18
  {
20
19
  this.status({fill: "red", shape: "ring", text: "hue-rules.node.no-rule"});
21
20
  return false;
22
21
  }
23
22
 
23
+ //
24
+ // UNIVERSAL MODE?
25
+ if(!config.ruleid)
26
+ {
27
+ this.status({fill: "grey", shape: "dot", text: "hue-rules.node.universal"});
28
+ }
29
+
24
30
  //
25
31
  // UPDATE STATE
26
- if(typeof bridge.disableupdates != 'undefined'||bridge.disableupdates == false)
32
+ if(typeof bridge.disableupdates != 'undefined' || bridge.disableupdates == false)
27
33
  {
28
34
  this.status({fill: "grey", shape: "dot", text: "hue-rules.node.init"});
29
35
  }
30
36
 
31
37
  //
32
- // ON UPDATE
33
- bridge.events.on('rule' + config.ruleid, function(rule)
38
+ // SUBSCRIBE TO UPDATES FROM THE BRIDGE
39
+ bridge.subscribe("rule", config.ruleid, function(info)
34
40
  {
35
- // SEND STATUS
36
- if(rule.status == "enabled")
37
- {
38
- scope.status({fill: "green", shape: "dot", text: "hue-rules.node.enabled"});
39
- }
40
- else
41
- {
42
- scope.status({fill: "red", shape: "ring", text: "hue-rules.node.disabled"});
43
- }
41
+ let currentState = bridge.get("rule", info.id);
44
42
 
45
- // SEND MESSAGE
46
- if(!config.skipevents)
43
+ // RESSOURCE FOUND?
44
+ if(currentState !== false)
47
45
  {
48
- var hueRule = new HueRulesMessage(rule, lastState);
49
- scope.send(hueRule.msg);
50
- }
46
+ // NOT IN UNIVERAL MODE? -> CHANGE UI STATES
47
+ if(config.ruleid)
48
+ {
49
+ if(currentState.payload.enabled == true)
50
+ {
51
+ scope.status({fill: "green", shape: "dot", text: "hue-rules.node.enabled"});
52
+ }
53
+ else
54
+ {
55
+ scope.status({fill: "red", shape: "ring", text: "hue-rules.node.disabled"});
56
+ }
57
+ }
58
+
59
+ // SEND MESSAGE
60
+ if(!config.skipevents && (config.initevents || info.suppressMessage == false))
61
+ {
62
+ // SET LAST COMMAND
63
+ if(scope.lastCommand !== null)
64
+ {
65
+ currentState.command = scope.lastCommand;
66
+ }
67
+
68
+ // SEND STATE
69
+ scope.send(currentState);
51
70
 
52
- // SAVE LAST STATE
53
- lastState = rule;
71
+ // RESET LAST COMMAND
72
+ scope.lastCommand = null;
73
+ }
74
+ }
54
75
  });
55
76
 
56
77
 
@@ -58,53 +79,52 @@ module.exports = function(RED)
58
79
  // DISABLE / ENABLE RULE
59
80
  this.on('input', function(msg, send, done)
60
81
  {
61
- // Node-RED < 1.0
82
+ // REDEFINE SEND AND DONE IF NOT AVAILABLE
62
83
  send = send || function() { scope.send.apply(scope,arguments); }
84
+ done = done || function() { scope.done.apply(scope,arguments); }
85
+
86
+ // SAVE LAST COMMAND
87
+ scope.lastCommand = msg;
88
+
89
+ // CREATE PATCH
90
+ let patchObject = {};
63
91
 
64
- // CONTROL
65
- if(msg.payload == true || msg.payload == false)
92
+ // DEFINE SENSOR ID & CURRENT STATE
93
+ const tempRuleID = (msg.topic != null) ? msg.topic : config.ruleid;
94
+ let currentState = bridge.get("rule", "rule_" + tempRuleID);
95
+
96
+ // CONTROL RULE
97
+ if(msg.payload === true || msg.payload === false)
66
98
  {
67
- bridge.client.rules.getById(config.ruleid)
68
- .then(rule => {
69
- rule.status = (msg.payload == true) ? 'enabled' : 'disabled';
70
- return bridge.client.rules.save(rule);
71
- })
72
- .then(rule => {
73
- // SEND STATUS
74
- if(msg.payload == false)
75
- {
76
- scope.status({fill: "red", shape: "ring", text: "hue-rules.node.disabled"});
77
- }
78
- else
79
- {
80
- scope.status({fill: "green", shape: "dot", text: "hue-rules.node.enabled"});
81
- }
99
+ if(msg.payload === currentState.payload.enabled) { return false; }
100
+ patchObject["status"] = (msg.payload == true) ? 'enabled' : 'disabled';
82
101
 
83
- // SEND MESSAGE
84
- if(!config.skipevents)
85
- {
86
- var hueRule = new HueRulesMessage(rule, lastState);
87
- send(hueRule.msg);
102
+ // PATCH!
103
+ bridge.patch("rules", "/rules/"+config.ruleid, patchObject, 1)
104
+ .then(function(response) { bridge.refetchRule(tempRuleID); })
105
+ .catch(function(errors) { scope.error(errors); });
88
106
 
89
- // SAVE LAST STATE
90
- lastState = rule;
91
- }
92
- if(done) { done(); }
93
- })
94
- .catch(error => {
95
- scope.error(error, msg);
96
- if(done) { done(error); }
97
- });
107
+ // DONE?
108
+ if(done) { done(); }
98
109
  }
99
- });
110
+ else
111
+ {
112
+ // SET LAST COMMAND
113
+ if(scope.lastCommand !== null)
114
+ {
115
+ currentState.command = scope.lastCommand;
116
+ }
100
117
 
101
- //
102
- // CLOSE NODE / REMOVE EVENT LISTENER
103
- this.on('close', function()
104
- {
105
- bridge.events.removeAllListeners('rule' + config.ruleid);
118
+ // SEND STATE
119
+ scope.send(currentState);
120
+
121
+ // RESET LAST COMMAND
122
+ scope.lastCommand = null;
123
+
124
+ if(done) {done();}
125
+ }
106
126
  });
107
127
  }
108
128
 
109
129
  RED.nodes.registerType("hue-rules", HueRules);
110
- }
130
+ }