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
@@ -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
+ // RESOURCE 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
+ }
51
58
 
52
- // SAVE LAST STATE
53
- lastState = rule;
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);
70
+
71
+ // RESET LAST COMMAND
72
+ scope.lastCommand = null;
73
+ }
74
+ }
54
75
  });
55
76
 
56
77
 
@@ -58,51 +79,56 @@ 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 = RED.util.cloneMessage(msg);
63
88
 
64
- // CONTROL
65
- if(msg.payload == true || msg.payload == false)
89
+ // CREATE PATCH
90
+ let patchObject = {};
91
+
92
+ // DEFINE SENSOR ID & CURRENT STATE
93
+ const tempRuleID = (!config.ruleid && typeof msg.topic != 'undefined' && isNaN(msg.topic) == false) ? msg.topic : config.ruleid;
94
+ if(!tempRuleID)
66
95
  {
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
- }
96
+ scope.error("Please submit a valid rule ID.");
97
+ return false;
98
+ }
82
99
 
83
- // SEND MESSAGE
84
- if(!config.skipevents)
85
- {
86
- var hueRule = new HueRulesMessage(rule, lastState);
87
- send(hueRule.msg);
100
+ let currentState = bridge.get("rule", "rule_" + tempRuleID);
88
101
 
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
- });
102
+ // CONTROL RULE
103
+ if(msg.payload === true || msg.payload === false)
104
+ {
105
+ if(msg.payload === currentState.payload.enabled) { return false; }
106
+ patchObject["status"] = (msg.payload == true) ? 'enabled' : 'disabled';
107
+
108
+ // PATCH!
109
+ bridge.patch("rules", "/rules/"+tempRuleID, patchObject, 1)
110
+ .then(function(response) { bridge.refetchRule(tempRuleID); })
111
+ .catch(function(errors) { scope.error(errors); });
112
+
113
+ // DONE?
114
+ if(done) { done(); }
98
115
  }
99
- });
116
+ else
117
+ {
118
+ // SET LAST COMMAND
119
+ if(scope.lastCommand !== null)
120
+ {
121
+ currentState.command = scope.lastCommand;
122
+ }
100
123
 
101
- //
102
- // CLOSE NODE / REMOVE EVENT LISTENER
103
- this.on('close', function()
104
- {
105
- bridge.events.removeAllListeners('rule' + config.ruleid);
124
+ // SEND STATE
125
+ scope.send(currentState);
126
+
127
+ // RESET LAST COMMAND
128
+ scope.lastCommand = null;
129
+
130
+ if(done) {done();}
131
+ }
106
132
  });
107
133
  }
108
134
 
@@ -1,39 +1,23 @@
1
1
  <script type="text/x-red" data-template-name="hue-scene">
2
2
  <div class="form-row">
3
3
  <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="hue-scene.config.name"></span></label>
4
- <input type="text" id="node-input-name" data-i18n="[placeholder]hue-scene.config.input-name">
4
+ <input type="text" id="node-input-name" data-i18n="[placeholder]hue-scene.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
- <label for="node-input-sceneid"><i class="fa fa-eye"></i> Scene</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-sceneid" placeholder="1" style="width: 100%"/>
11
+ <label for="node-input-sceneid"><i class="fa fa-eye"></i> <span data-i18n="hue-scene.config.scene"></span></label>
12
+ <div style="display: inline-flex; width: calc(100% - 105px)">
13
+ <div id="input-scene-select-toggle" style="flex-grow: 1;">
14
+ <input type="text" id="node-input-sceneid" placeholder="00000000-0000-0000-0000-000000000000" style="width: 100%"/>
15
15
  </div>
16
- <a id="node-config-input-scan-scenes" class="editor-button" style="position: absolute; right: 0px; top: 0px;">
16
+ <button id="node-config-input-scan-scenes" 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-groupid"><i class="fa fa-lightbulb-o"></i> <span data-i18n="hue-scene.config.group"></span></label>
23
- <div style="display: inline-block; position: relative; width: 70%; height: 20px;">
24
- <div style="position: absolute; left: 0px; right: 40px;">
25
- <input type="text" id="node-input-groupid" placeholder="1" style="width: 100%"/>
26
- </div>
27
- <a id="node-config-input-scan-groups" class="editor-button" style="position: absolute; right: 0px; top: 0px;">
28
- <i class="fa fa-search"></i>
29
- </a>
30
- </div>
31
- </div>
32
- <div class="form-row">
33
- <label for="node-input-skipevents"><i class="fa fa-sign-out"></i> <span data-i18n="hue-scene.config.skipevents"></span></label>
34
- <input type="checkbox" id="node-input-skipevents" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="hue-scene.config.skipevents-node"></span>
35
- </label>
36
- </div>
37
21
  </script>
38
22
 
39
23
  <script type="text/javascript">
@@ -41,149 +25,146 @@
41
25
  category: 'HueMagic',
42
26
  color: '#ff823a',
43
27
  defaults: {
44
- name: {value:""},
45
- bridge: {type: "hue-bridge", required: true},
46
- sceneid: {value: null},
47
- groupid: {value:"", required: false, validate: function(id) {
48
- if(id.length < 1) { return true; }
49
- else if(!isNaN(id)) { return true; }
50
- else { return false; }
51
- }},
52
- skipevents: {value: false}
28
+ name: { value:"" },
29
+ bridge: { type: "hue-bridge", required: true },
30
+ sceneid: { value: null }
53
31
  },
32
+ align: 'left',
33
+ icon: "hue-scene.png",
54
34
  inputs: 1,
55
35
  outputs: 1,
36
+ label: function() {
37
+ return this.name || this._("hue-scene.node.title");
38
+ },
39
+ paletteLabel: function() {
40
+ return this._("hue-scene.node.title");
41
+ },
56
42
  inputLabels: function() {
57
43
  return this._("hue-scene.node.input");
58
44
  },
59
45
  outputLabels: function() {
60
46
  return this._("hue-scene.node.output");
61
47
  },
62
- align: 'right',
63
- icon: "hue-scene.png",
64
- paletteLabel: function() {
65
- return this._("hue-scene.node.title");
66
- },
67
- label: function() {
68
- return this.name || this._("hue-scene.node.title");
69
- },
70
48
  oneditprepare: function()
71
49
  {
72
- var scope = this;
50
+ const scope = this;
51
+ let sceneOptions = [];
73
52
 
74
53
  function manualSceneID()
75
54
  {
55
+ // GET CURRENT SELECTED VALUE
76
56
  var current = $('#node-input-sceneid').val();
77
- $('#node-input-sceneid').replaceWith('<input type="text" id="node-input-sceneid" style="width: 100%"/>');
78
- $('#node-input-sceneid').val(current);
79
- }
80
57
 
81
- function manualGroupID()
82
- {
83
- var current = $('#node-input-groupid').val();
84
- $('#node-input-groupid').replaceWith('<input type="text" id="node-input-groupid" style="width: 100%"/>');
85
- $('#node-input-groupid').val(current);
58
+ // REMOVE SELECT FIELD
59
+ $('#input-scene-select-toggle').empty();
60
+
61
+ // CREATE NEW INPUT FIELD
62
+ $('#input-scene-select-toggle').append('<input type="text" id="node-input-sceneid" placeholder="00000000-0000-0000-0000-000000000000" style="width: 100%" value="'+current+'" />');
63
+
64
+ // CHANGE BUTTON ICON
65
+ var button = $("#node-config-input-scan-scenes");
66
+ var buttonIcon = button.find("i");
67
+ buttonIcon.removeClass("fa-pencil");
68
+ buttonIcon.addClass("fa-search");
86
69
  }
87
70
 
88
71
  function searchAndSelectScenes()
89
72
  {
73
+ // GET CURRENT BRIDGE CONFIGURATION
74
+ var bridgeConfig = RED.nodes.node($('#node-input-bridge option:selected').val());
75
+ if(!bridgeConfig) { return false; }
76
+
77
+ // GET CURRENT SELECTED VALUE
90
78
  var current = $('#node-input-sceneid').val();
91
- $('#node-input-sceneid').replaceWith('<select id="node-input-sceneid" style="width: 100%"></select>');
92
- $('#node-input-sceneid').append('<option selected="selected" value="null">'+scope._("hue-scene.config.searching")+'</option>');
93
79
 
94
- var bridgeConfig = RED.nodes.node($('#node-input-bridge option:selected').val());
95
- $.get('hue/scenes', {bridge: bridgeConfig.bridge, key: bridgeConfig.key})
96
- .done(function(data) {
97
- var scenes = JSON.parse(data);
80
+ // TRIGGER SEARCHING NOTIFICATION
81
+ var notification = RED.notify(scope._("hue-rules.config.searching"), { type: "compact", modal: true, fixed: true });
98
82
 
99
- if(scenes.length <= 0)
83
+ // GET THE SCENES
84
+ $.get('hue/resources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "scene" })
85
+ .done( function(data) {
86
+ var allResources = JSON.parse(data);
87
+ if(allResources.length <= 0)
100
88
  {
101
- RED.notify(scope._("hue-scene.config.none-found"), "error");
89
+ notification.close();
90
+ RED.notify(scope._("hue-scene.config.none-found"), { type: "error" });
91
+ return false;
102
92
  }
103
93
 
104
- // RESET OPTIONS
105
- $('#node-input-sceneid').empty();
106
-
107
- // SET MOTION SENSORS AS OPTIONS
108
- scenes.forEach(function(scene)
94
+ // SET OPTIONS
95
+ allResources.forEach(function(resource)
109
96
  {
110
- $('#node-input-sceneid').append('<option value="' + scene.id + '">' + scene.name + '</option>');
97
+ sceneOptions[resource.id] = { value: resource.id, label: resource.name + " ("+resource.group+")" };
111
98
  });
112
99
 
113
100
  // SELECT CURRENT VALUE
114
- $('#node-input-sceneid').val(current);
115
- })
116
- .fail(function()
117
- {
118
- RED.notify(scope._("hue-scene.config.unknown-error"), "error");
119
- });
120
- }
121
-
122
- function searchAndSelectGroupID()
123
- {
124
- var current = $('#node-input-groupid').val();
125
- $('#node-input-groupid').replaceWith('<select id="node-input-groupid" style="width: 100%"></select>');
126
- $('#node-input-groupid').append('<option selected="selected" value="null">'+scope._("hue-scene.config.group-searching")+'</option>');
127
-
128
- var bridgeConfig = RED.nodes.node($('#node-input-bridge option:selected').val());
129
- $.get('hue/groups', {bridge: bridgeConfig.bridge, key: bridgeConfig.key})
130
- .done(function(data) {
131
- var groups = JSON.parse(data);
132
-
133
- if(groups.length <= 0)
134
- {
135
- RED.notify(scope._("hue-scene.config.group-none-found"), "error");
136
- }
137
-
138
- // RESET OPTIONS
139
- $('#node-input-groupid').empty();
140
-
141
- // SET GROUPS AS OPTIONS
142
- $('#node-input-groupid').append('<option value="0">'+scope._("hue-scene.config.groups-all")+'</option>');
143
- groups.forEach(function(group)
144
- {
145
- $('#node-input-groupid').append('<option value="' + group.id + '">' + group.name + '</option>');
101
+ $("#node-input-sceneid").typedInput({
102
+ types: [
103
+ {
104
+ value: current,
105
+ options: Object.values(sceneOptions)
106
+ }
107
+ ]
146
108
  });
147
109
 
148
- // SELECT CURRENT VALUE
149
- $('#node-input-groupid').val(current);
110
+ // CHANGE BUTTON ICON
111
+ var button = $("#node-config-input-scan-scenes");
112
+ var buttonIcon = button.find("i");
113
+ buttonIcon.removeClass("fa-search");
114
+ buttonIcon.addClass("fa-pencil");
115
+
116
+ // CLOSE SEARCH NOTIFICATION
117
+ notification.close();
150
118
  })
151
119
  .fail(function()
152
120
  {
121
+ notification.close();
153
122
  RED.notify(scope._("hue-scene.config.unknown-error"), "error");
154
123
  });
155
124
  }
156
125
 
157
-
158
- $(document).on('change', '#node-input-sceneid', function()
126
+ // CHANGED SCENE ID? -> REPLACE NAME (IF POSSIBLE)
127
+ $(document).on('change', '#node-input-sceneid', function(e)
159
128
  {
160
- var sceneName = $('#node-input-sceneid option:selected').text();
161
- if(sceneName.length > 0)
129
+ let currentSelectedOptionID = $(e.currentTarget).val();
130
+ let currentSelectedOptionValue = (currentSelectedOptionID.length > 0 && sceneOptions[currentSelectedOptionID]) ? sceneOptions[currentSelectedOptionID].label : false;
131
+
132
+ if(currentSelectedOptionValue !== false)
162
133
  {
163
- $('#node-input-name').val(sceneName);
134
+ $('#node-input-name').val(currentSelectedOptionValue.split(" (")[0]);
164
135
  }
165
136
  });
166
137
 
167
- // SCAN
138
+ // TOGGLE SELECT/INPUT FIELD
168
139
  $('#node-config-input-scan-scenes').click(function()
169
140
  {
170
- if($('#node-input-sceneid').prop("tagName") === "INPUT")
141
+ if($('#input-scene-select-toggle').find(".red-ui-typedInput-container").length > 0)
171
142
  {
172
- searchAndSelectScenes();
173
- } else {
174
143
  manualSceneID();
175
144
  }
145
+ else
146
+ {
147
+ searchAndSelectScenes();
148
+ }
176
149
  });
177
-
178
- $('#node-config-input-scan-groups').click(function()
150
+ },
151
+ button: {
152
+ onclick: function()
179
153
  {
180
- if($('#node-input-groupid').prop("tagName") === "INPUT")
154
+ const node = this;
155
+ if(node.bridge)
181
156
  {
182
- searchAndSelectGroupID();
183
- } else {
184
- manualGroupID();
157
+ $.ajax({
158
+ url: "inject/" + node.id,
159
+ type: "POST",
160
+ data: JSON.stringify({ __user_inject_props__: "status"}),
161
+ contentType: "application/json; charset=utf-8",
162
+ success: function (resp) {
163
+ RED.notify(node.name + ": " + node._("hue-scene.node.statusmsg"), { type: "success", id: "status", timeout: 2000 });
164
+ }
165
+ });
185
166
  }
186
- });
167
+ }
187
168
  }
188
169
  });
189
170
  </script>