node-red-contrib-huemagic 3.0.0 → 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 (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 +628 -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 +105 -55
  29. package/huemagic/hue-buttons.html +197 -0
  30. package/huemagic/hue-buttons.js +152 -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 +99 -101
  39. package/huemagic/hue-rules.html +121 -50
  40. package/huemagic/hue-rules.js +83 -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 +114 -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
@@ -5,13 +5,12 @@ module.exports = function(RED)
5
5
  function HueMotion(config)
6
6
  {
7
7
  RED.nodes.createNode(this, config);
8
- var scope = this;
9
- let bridge = RED.nodes.getNode(config.bridge);
10
- let { HueMotionMessage } = require('../utils/messages');
11
- var universalMode = false;
12
8
 
13
- // SAVE LAST STATE
14
- var lastState = false;
9
+ const scope = this;
10
+ const bridge = RED.nodes.getNode(config.bridge);
11
+
12
+ // SAVE LAST COMMAND
13
+ this.lastCommand = null;
15
14
 
16
15
  //
17
16
  // CHECK CONFIG
@@ -25,7 +24,6 @@ module.exports = function(RED)
25
24
  // UNIVERSAL MODE?
26
25
  if(!config.sensorid)
27
26
  {
28
- universalMode = true;
29
27
  this.status({fill: "grey", shape: "dot", text: "hue-motion.node.universal"});
30
28
  }
31
29
 
@@ -37,131 +35,131 @@ module.exports = function(RED)
37
35
  }
38
36
 
39
37
  //
40
- // ON UPDATE
41
- if(config.sensorid) { bridge.events.on('sensor' + config.sensorid, function(sensor) { scope.receivedUpdates(sensor) }); }
42
- if(!config.sensorid && config.universalevents && config.universalevents == true) { bridge.events.on('sensor', function(sensor) { scope.receivedUpdates(sensor) }); }
43
-
44
- //
45
- // RECEIVED UPDATES
46
- this.receivedUpdates = function(sensor)
38
+ // SUBSCRIBE TO UPDATES FROM THE BRIDGE
39
+ bridge.subscribe("motion", config.sensorid, function(info)
47
40
  {
48
- if(sensor.config.reachable == false)
41
+ let currentState = bridge.get("motion", info.id);
42
+
43
+ // RESSOURCE FOUND?
44
+ if(currentState !== false)
49
45
  {
50
- // SEND STATUS
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-motion.node.not-reachable"});
49
+ // SET LAST COMMAND
50
+ if(scope.lastCommand !== null)
51
+ {
52
+ currentState.command = scope.lastCommand;
53
+ }
54
+
55
+ // SEND STATE
56
+ scope.send(currentState);
57
+
58
+ // RESET LAST COMMAND
59
+ scope.lastCommand = null;
54
60
  }
55
- }
56
- else if(sensor.config.on == true)
57
- {
58
- // SEND STATUS
59
- if(universalMode == false)
61
+
62
+ // NOT IN UNIVERAL MODE? -> CHANGE UI STATES
63
+ if(config.sensorid)
60
64
  {
61
- if(sensor.state.presence)
65
+ if(currentState.payload.reachable == false)
66
+ {
67
+ scope.status({fill: "red", shape: "ring", text: "hue-motion.node.not-reachable"});
68
+ }
69
+ else if(currentState.payload.active == true)
62
70
  {
63
- scope.status({fill: "green", shape: "dot", text: "hue-motion.node.motion"});
71
+ if(currentState.payload.motion)
72
+ {
73
+ scope.status({fill: "green", shape: "dot", text: "hue-motion.node.motion"});
74
+ }
75
+ else
76
+ {
77
+ scope.status({fill: "grey", shape: "dot", text: "hue-motion.node.activated"});
78
+ }
64
79
  }
65
- else
80
+ else if(currentState.payload.active == false)
66
81
  {
67
- scope.status({fill: "grey", shape: "dot", text: "hue-motion.node.activated"});
82
+ scope.status({fill: "red", shape: "ring", text: "hue-motion.node.deactivated"});
68
83
  }
69
84
  }
70
-
71
- // SEND MESSAGE
72
- var hueMotion = new HueMotionMessage(sensor, true, (universalMode == false) ? lastState : false);
73
- if(!config.skipevents) { scope.send(hueMotion.msg); }
74
-
75
- // SAVE LAST STATE
76
- lastState = sensor;
77
85
  }
78
- else if(sensor.config.on == false)
79
- {
80
- // SEND STATUS
81
- if(universalMode == false)
82
- {
83
- scope.status({fill: "red", shape: "ring", text: "hue-motion.node.deactivated"});
84
- }
85
-
86
- // SEND MESSAGE
87
- var hueMotion = new HueMotionMessage(sensor, false, (universalMode == false) ? lastState : false);
88
- if(!config.skipevents) { scope.send(hueMotion.msg); }
89
-
90
- // SAVE LAST STATE
91
- lastState = sensor;
92
- }
93
- }
86
+ });
94
87
 
95
88
  //
96
- // DISABLE / ENABLE SENSOR
89
+ // CONTROL SENSOR
97
90
  this.on('input', function(msg, send, done)
98
91
  {
99
- // Node-RED < 1.0
92
+ // REDEFINE SEND AND DONE IF NOT AVAILABLE
100
93
  send = send || function() { scope.send.apply(scope,arguments); }
94
+ done = done || function() { scope.done.apply(scope,arguments); }
95
+
96
+ // SAVE LAST COMMAND
97
+ scope.lastCommand = msg;
101
98
 
102
- // DEFINE SENSOR ID
103
- var tempSensorID = (msg.topic != null && isNaN(msg.topic) == false && msg.topic.length > 0) ? parseInt(msg.topic) : config.sensorid;
99
+ // CREATE PATCH
100
+ let patchObject = {};
101
+
102
+ // DEFINE SENSOR ID & CURRENT STATE
103
+ const tempSensorID = (msg.topic != null) ? msg.topic : config.sensorid;
104
+ let currentState = bridge.get("motion", tempSensorID);
104
105
 
105
106
  // GET CURRENT STATE
106
- if(typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined')
107
+ if( (typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined') || (typeof msg.__user_inject_props__ != 'undefined' && msg.__user_inject_props__ == "status") )
107
108
  {
108
- bridge.client.sensors.getById(tempSensorID)
109
- .then(sensor => {
110
- var hueMotion = new HueMotionMessage(sensor, (sensor.config.on) ? true : false, (universalMode == false) ? lastState : false);
109
+ // SET LAST COMMAND
110
+ if(scope.lastCommand !== null)
111
+ {
112
+ currentState.command = scope.lastCommand;
113
+ }
111
114
 
112
- // SAVE LAST STATE
113
- lastState = sensor;
115
+ // SEND STATE
116
+ scope.send(currentState);
114
117
 
115
- return send(hueMotion.msg);
116
- });
118
+ // RESET LAST COMMAND
119
+ scope.lastCommand = null;
117
120
 
121
+ if(done) { done(); }
118
122
  return true;
119
123
  }
120
124
 
121
- // CONTROL
122
- if(msg.payload == true || msg.payload == false)
125
+ // TURN ON / OFF
126
+ if((msg.payload === true || msg.payload === false) && (msg.payload !== currentState.payload.active))
123
127
  {
124
- bridge.client.sensors.getById(tempSensorID)
125
- .then(sensor => {
126
- sensor.config.on = msg.payload;
127
- return bridge.client.sensors.save(sensor);
128
- })
129
- .then(sensor => {
130
- var hueMotion = new HueMotionMessage(sensor, msg.payload, lastState);
131
-
132
- // SEND STATUS
133
- if(universalMode == false)
134
- {
135
- if(msg.payload == false)
136
- {
137
- scope.status({fill: "red", shape: "ring", text: "hue-motion.node.deactivated"});
138
- }
139
- else
140
- {
141
- scope.status({fill: "green", shape: "dot", text: "hue-motion.node.activated"});
142
- }
143
- }
128
+ // PREPARE PATCH
129
+ patchObject.enabled = msg.payload;
130
+ }
144
131
 
145
- // SEND MESSAGE
146
- if(!config.skipevents) { send(hueMotion.msg); }
147
- if(done) { done(); }
148
-
149
- // SAVE LAST STATE
150
- lastState = sensor;
151
- })
152
- .catch(error => {
153
- scope.error(error, msg);
154
- if(done) { done(error); }
155
- });
132
+ //
133
+ // SHOULD PATCH?
134
+ if(Object.values(patchObject).length > 0)
135
+ {
136
+ // CHANGE NODE UI STATE
137
+ if(config.sensorid)
138
+ {
139
+ scope.status({fill: "grey", shape: "ring", text: "hue-motion.node.command"});
140
+ }
141
+
142
+ // PATCH!
143
+ bridge.patch("motion", tempSensorID, patchObject)
144
+ .then(function() { if(done) { done(); }})
145
+ .catch(function(errors) { scope.error(errors); });
156
146
  }
157
- });
147
+ else
148
+ {
149
+ // SET LAST COMMAND
150
+ if(scope.lastCommand !== null)
151
+ {
152
+ currentState.command = scope.lastCommand;
153
+ }
158
154
 
155
+ // SEND STATE
156
+ scope.send(currentState);
159
157
 
160
- //
161
- // CLOSE NODE / REMOVE EVENT LISTENER
162
- this.on('close', function()
163
- {
164
- bridge.events.removeAllListeners('sensor' + config.sensorid);
158
+ // RESET LAST COMMAND
159
+ scope.lastCommand = null;
160
+
161
+ if(done) { done(); }
162
+ }
165
163
  });
166
164
  }
167
165
 
@@ -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>