node-red-contrib-huemagic 2.8.6 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/CHANGELOG.md +229 -0
  2. package/README.md +807 -766
  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 -320
  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 -368
  65. package/huemagic/hue-light.html +133 -59
  66. package/huemagic/hue-light.js +551 -337
  67. package/huemagic/hue-magic.html +91 -240
  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-button.json → hue-buttons.json} +8 -8
  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-button.json → hue-buttons.json} +11 -5
  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 +11 -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-button.html +0 -119
  150. package/huemagic/hue-button.js +0 -94
  151. package/huemagic/hue-switch.html +0 -119
  152. package/huemagic/hue-switch.js +0 -113
  153. package/huemagic/hue-tap.html +0 -119
  154. package/huemagic/hue-tap.js +0 -74
  155. package/huemagic/icons/hue-button.png +0 -0
  156. package/huemagic/icons/hue-switch.png +0 -0
  157. package/huemagic/icons/hue-tap.png +0 -0
  158. package/huemagic/locales/de/hue-button.html +0 -50
  159. package/huemagic/locales/de/hue-switch.html +0 -50
  160. package/huemagic/locales/de/hue-switch.json +0 -31
  161. package/huemagic/locales/de/hue-tap.html +0 -41
  162. package/huemagic/locales/de/hue-tap.json +0 -23
  163. package/huemagic/locales/en-US/hue-button.html +0 -50
  164. package/huemagic/locales/en-US/hue-switch.html +0 -50
  165. package/huemagic/locales/en-US/hue-switch.json +0 -31
  166. package/huemagic/locales/en-US/hue-tap.html +0 -41
  167. package/huemagic/locales/en-US/hue-tap.json +0 -23
  168. package/utils/color.js +0 -9
  169. package/utils/messages.js +0 -658
  170. package/utils/rgb.js +0 -188
@@ -0,0 +1,152 @@
1
+ module.exports = function(RED)
2
+ {
3
+ "use strict";
4
+
5
+ function HueButtons(config)
6
+ {
7
+ RED.nodes.createNode(this, config);
8
+
9
+ const scope = this;
10
+ const bridge = RED.nodes.getNode(config.bridge);
11
+
12
+ // NODE UI STATUS TIMEOUT
13
+ this.timeout = null;
14
+
15
+ // SAVE LAST COMMAND
16
+ this.lastCommand = null;
17
+
18
+ //
19
+ // CHECK CONFIG
20
+ if(bridge == null)
21
+ {
22
+ this.status({fill: "red", shape: "ring", text: "hue-buttons.node.not-configured"});
23
+ return false;
24
+ }
25
+
26
+ //
27
+ // UNIVERSAL MODE?
28
+ if(!config.sensorid)
29
+ {
30
+ this.status({fill: "grey", shape: "dot", text: "hue-buttons.node.universal"});
31
+ }
32
+
33
+ //
34
+ // UPDATE STATE
35
+ if(config.sensorid)
36
+ {
37
+ scope.status({fill: "grey", shape: "dot", text: "hue-buttons.node.waiting"});
38
+ }
39
+
40
+ //
41
+ // SUBSCRIBE TO UPDATES FROM THE BRIDGE
42
+ bridge.subscribe("button", config.sensorid, function(info)
43
+ {
44
+ let currentState = bridge.get("button", info.id);
45
+
46
+ // RESSOURCE FOUND?
47
+ if(currentState !== false)
48
+ {
49
+ // SEND MESSAGE
50
+ if(!config.skipevents && currentState.payload.button !== false && (config.initevents || info.suppressMessage == false))
51
+ {
52
+ // SET LAST COMMAND
53
+ if(scope.lastCommand !== null)
54
+ {
55
+ currentState.command = scope.lastCommand;
56
+ }
57
+
58
+ // SEND STATE
59
+ scope.send(currentState);
60
+
61
+ // RESET LAST COMMAND
62
+ scope.lastCommand = null;
63
+ }
64
+
65
+ // NOT IN UNIVERAL MODE? -> CHANGE UI STATES
66
+ if(config.sensorid)
67
+ {
68
+ if(currentState.payload.button === false)
69
+ {
70
+ scope.status({fill: "grey", shape: "dot", text: "hue-buttons.node.waiting"});
71
+ }
72
+ else
73
+ {
74
+ var action = "";
75
+ switch (currentState.payload.action)
76
+ {
77
+ case "initial_press":
78
+ action = "(pressed)";
79
+ break;
80
+ case "repeat":
81
+ action = "(repeated)";
82
+ break;
83
+ case "short_release":
84
+ action = "(short press)";
85
+ break;
86
+ case "long_release":
87
+ action = "(long press)";
88
+ break;
89
+ case "double_short_release":
90
+ action = "(double pressed)";
91
+ break;
92
+ default:
93
+ action = "(pressed)";
94
+ }
95
+
96
+ scope.status({fill: "blue", shape: "dot", text: "Button #"+ currentState.payload.button + " " + action });
97
+
98
+ // RESET TO WAITING AFTER 3 SECONDS
99
+ if(scope.timeout !== null) { clearTimeout(scope.timeout); };
100
+ scope.timeout = setTimeout(function()
101
+ {
102
+ scope.status({fill: "grey", shape: "dot", text: "hue-buttons.node.waiting"});
103
+
104
+ // REMOVE OLD BUTTON STATES
105
+ for (const [oneButtonID, oneButton] of Object.entries(bridge.ressources[config.sensorid]["services"]["button"]))
106
+ {
107
+ delete bridge.ressources[config.sensorid]["services"]["button"][oneButtonID]["button"];
108
+ }
109
+ }, 3000);
110
+ }
111
+ }
112
+ }
113
+ });
114
+
115
+ //
116
+ // ON COMMAND
117
+ this.on('input', function(msg, send, done)
118
+ {
119
+ // REDEFINE SEND AND DONE IF NOT AVAILABLE
120
+ send = send || function() { scope.send.apply(scope,arguments); }
121
+ done = done || function() { scope.done.apply(scope,arguments); }
122
+
123
+ // SAVE LAST COMMAND
124
+ scope.lastCommand = msg;
125
+
126
+ // DEFINE SENSOR ID
127
+ const tempSensorID = (typeof msg.topic != 'undefined' && msg.topic.length > 0) ? msg.topic : config.sensorid;
128
+ let currentState = bridge.get("button", tempSensorID);
129
+
130
+ // GET CURRENT STATE
131
+ if( (typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined') || (typeof msg.__user_inject_props__ != 'undefined' && msg.__user_inject_props__ == "status") )
132
+ {
133
+ // SET LAST COMMAND
134
+ if(scope.lastCommand !== null)
135
+ {
136
+ currentState.command = scope.lastCommand;
137
+ }
138
+
139
+ // SEND STATE
140
+ scope.send(currentState);
141
+
142
+ // RESET LAST COMMAND
143
+ scope.lastCommand = null;
144
+
145
+ if(done) { done(); }
146
+ return true;
147
+ }
148
+ });
149
+ }
150
+
151
+ RED.nodes.registerType("hue-buttons", HueButtons);
152
+ }
@@ -1,33 +1,34 @@
1
1
  <script type="text/x-red" data-template-name="hue-group">
2
2
  <div class="form-row">
3
3
  <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="hue-group.config.name"></span></label>
4
- <input type="text" id="node-input-name" data-i18n="[placeholder]hue-group.config.input-name">
4
+ <input type="text" id="node-input-name" data-i18n="[placeholder]hue-group.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-groupid"><i class="fa fa-lightbulb-o"></i> <span data-i18n="hue-group.config.group"></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-groupid" 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-groupid" placeholder="00000000-0000-0000-0000-000000000000" style="width: 100%"/>
15
15
  </div>
16
- <a id="node-config-input-scan-groups" class="editor-button" style="position: absolute; right: 0px; top: 0px;">
16
+ <button id="node-config-input-scan-groups" 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-colornamer"><i class="fa fa-check-circle"></i> <span data-i18n="hue-group.config.colornamer"></span></label>
23
- <label for="node-input-colornamer" style="width:70%">
24
- <input type="checkbox" id="node-input-colornamer" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="hue-group.config.colornamer-info"></span>
25
- </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-group.config.skipevents-node" style="width: 100%; margin-left: 10px;"></span>
25
+ </div>
26
26
  </div>
27
27
  <div class="form-row">
28
- <label for="node-input-skipevents"><i class="fa fa-sign-out"></i> <span data-i18n="hue-group.config.skipevents"></span></label>
29
- <input type="checkbox" id="node-input-skipevents" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="hue-group.config.skipevents-node"></span>
30
- </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-group.config.sendinitevents-node" style="width: 100%; margin-left: 10px;"></span>
31
+ </div>
31
32
  </div>
32
33
  </script>
33
34
 
@@ -36,96 +37,172 @@
36
37
  category: 'HueMagic',
37
38
  color: '#f94f8b',
38
39
  defaults: {
39
- name: {value:""},
40
- bridge: {type: "hue-bridge", required: true},
41
- groupid: {value:"", required: false, validate: function(id) {
42
- if(id.length < 1) { return true; }
43
- else if(!isNaN(id)) { return true; }
44
- else { return false; }
45
- }},
46
- colornamer: {value: true},
47
- skipevents: {value: false}
40
+ name: { value:"" },
41
+ bridge: { type: "hue-bridge", required: true },
42
+ groupid: { value:"", required: false },
43
+ skipevents: { value: false },
44
+ initevents: { value: false }
48
45
  },
46
+ align: 'left',
47
+ icon: "hue-group.png",
49
48
  inputs: 1,
50
49
  outputs: 1,
50
+ label: function() {
51
+ return this.name || this._("hue-group.node.title");
52
+ },
53
+ paletteLabel: function() {
54
+ return this._("hue-group.node.title");
55
+ },
51
56
  inputLabels: function() {
52
57
  return this._("hue-group.node.input");
53
58
  },
54
59
  outputLabels: function() {
55
60
  return this._("hue-group.node.output");
56
61
  },
57
- align: 'right',
58
- icon: "hue-group.png",
59
- paletteLabel: function() {
60
- return this._("hue-group.node.title");
61
- },
62
- label: function() {
63
- return this.name || this._("hue-group.node.title");
64
- },
65
62
  oneditprepare: function()
66
63
  {
67
- var scope = this;
64
+ const scope = this;
65
+ let options = [];
68
66
 
69
- function manualGroupID()
67
+ function manualInput()
70
68
  {
69
+ // GET CURRENT SELECTED VALUE
71
70
  var current = $('#node-input-groupid').val();
72
- $('#node-input-groupid').replaceWith('<input type="text" id="node-input-groupid" style="width: 100%"/>');
73
- $('#node-input-groupid').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-groupid" placeholder="00000000-0000-0000-0000-000000000000" style="width: 100%" value="'+current+'" />');
77
+
78
+ // CHANGE BUTTON ICON
79
+ var button = $("#node-config-input-scan-groups");
80
+ var buttonIcon = button.find("i");
81
+ buttonIcon.removeClass("fa-pencil");
82
+ buttonIcon.addClass("fa-search");
74
83
  }
75
84
 
76
- function searchAndSelectGroupID()
85
+ function searchAndSelect()
77
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
78
92
  var current = $('#node-input-groupid').val();
79
- $('#node-input-groupid').replaceWith('<select id="node-input-groupid" style="width: 100%"></select>');
80
- $('#node-input-groupid').append('<option selected="selected" value="null">'+scope._("hue-group.config.searching")+'</option>');
81
93
 
82
- var bridgeConfig = RED.nodes.node($('#node-input-bridge option:selected').val());
83
- $.get('hue/groups', {bridge: bridgeConfig.bridge, key: bridgeConfig.key})
84
- .done(function(data) {
85
- var groups = JSON.parse(data);
94
+ // TRIGGER SEARCHING NOTIFICATION
95
+ var notification = RED.notify(scope._("hue-group.config.searching"), { type: "compact", modal: true, fixed: true });
86
96
 
87
- if(groups.length <= 0)
97
+ // GET THE GROUPS
98
+ $.get('hue/ressources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "group" })
99
+ .done( function(data) {
100
+ var allRessources = JSON.parse(data);
101
+ if(allRessources.length <= 0)
88
102
  {
89
- RED.notify(scope._("hue-group.config.none-found"), "error");
103
+ notification.close();
104
+ RED.notify(scope._("hue-group.config.none-found"), { type: "error" });
105
+ return false;
90
106
  }
91
107
 
92
- // RESET OPTIONS
93
- $('#node-input-groupid').empty();
94
-
95
108
  // SET GROUPS AS OPTIONS
96
- $('#node-input-groupid').append('<option value="0">'+scope._("hue-group.config.all")+'</option>');
97
- groups.forEach(function(group)
109
+ allRessources.forEach(function(ressource)
110
+ {
111
+ if(!ressource.name) // ALL SPECIAL
112
+ {
113
+ options[ressource.id] = { value: ressource.id, label: "● "+scope._("hue-group.config.all") };
114
+ }
115
+ });
116
+
117
+ allRessources.forEach(function(ressource)
98
118
  {
99
- $('#node-input-groupid').append('<option value="' + group.id + '">' + group.name + '</option>');
119
+ if(ressource.name) // REGULAR GROUPS
120
+ {
121
+ if(ressource.model)
122
+ {
123
+ options[ressource.id] = { value: ressource.id, label: ressource.name + " ("+ressource.model+")" };
124
+ }
125
+ else
126
+ {
127
+ options[ressource.id] = { value: ressource.id, label: ressource.name };
128
+ }
129
+ }
100
130
  });
101
131
 
102
132
  // SELECT CURRENT VALUE
103
- $('#node-input-groupid').val(current);
133
+ $("#node-input-groupid").typedInput({
134
+ types: [
135
+ {
136
+ value: current,
137
+ options: Object.values(options)
138
+ }
139
+ ]
140
+ });
141
+
142
+ // CHANGE BUTTON ICON
143
+ var button = $("#node-config-input-scan-groups");
144
+ var buttonIcon = button.find("i");
145
+ buttonIcon.removeClass("fa-search");
146
+ buttonIcon.addClass("fa-pencil");
147
+
148
+ // CLOSE SEARCH NOTIFICATION
149
+ notification.close();
104
150
  })
105
151
  .fail(function()
106
152
  {
153
+ notification.close();
107
154
  RED.notify(scope._("hue-group.config.unknown-error"), "error");
108
155
  });
109
156
  }
110
157
 
111
- $(document).on('change', '#node-input-groupid', function()
158
+ // CHANGED GROUP ID? -> REPLACE NAME (IF POSSIBLE)
159
+ $(document).on('change', '#node-input-groupid', function(e)
112
160
  {
113
- var groupName = $('#node-input-groupid option:selected').text();
114
- if(groupName.length > 0)
161
+ let currentSelectedOptionID = $(e.currentTarget).val();
162
+ let currentSelectedOptionValue = (currentSelectedOptionID.length > 0 && options[currentSelectedOptionID]) ? options[currentSelectedOptionID].label : false;
163
+
164
+ if(currentSelectedOptionValue !== false)
115
165
  {
116
- $('#node-input-name').val(groupName);
166
+ $('#node-input-name').val(currentSelectedOptionValue.split(" (")[0]);
117
167
  }
118
168
  });
119
169
 
170
+ // TOGGLE SELECT/INPUT FIELD
120
171
  $('#node-config-input-scan-groups').click(function()
121
172
  {
122
- if($('#node-input-groupid').prop("tagName") === "INPUT")
173
+ if($('#input-select-toggle').find(".red-ui-typedInput-container").length > 0)
174
+ {
175
+ manualInput();
176
+ }
177
+ else
123
178
  {
124
- searchAndSelectGroupID();
125
- } else {
126
- manualGroupID();
179
+ searchAndSelect();
127
180
  }
128
181
  });
182
+ },
183
+ button: {
184
+ enabled: function() {
185
+ return (this.groupid && this.groupid.length > 1)
186
+ },
187
+ visible: function() {
188
+ return (this.groupid && this.groupid.length > 1)
189
+ },
190
+ onclick: function()
191
+ {
192
+ const node = this;
193
+ if(node.bridge)
194
+ {
195
+ $.ajax({
196
+ url: "inject/" + node.id,
197
+ type: "POST",
198
+ data: JSON.stringify({ __user_inject_props__: "status"}),
199
+ contentType: "application/json; charset=utf-8",
200
+ success: function (resp) {
201
+ RED.notify(node.name + ": " + node._("hue-group.node.statusmsg"), { type: "success", id: "status", timeout: 2000 });
202
+ }
203
+ });
204
+ }
205
+ }
129
206
  }
130
207
  });
131
208
  </script>