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.
- package/README.md +764 -603
- package/examples/Hue Bridge.json +189 -35
- package/examples/Hue Brightness.json +124 -14
- package/examples/Hue Buttons.json +88 -0
- package/examples/Hue Group.json +575 -63
- package/examples/Hue Light.json +805 -58
- package/examples/Hue Magic.json +69 -24
- package/examples/Hue Motion.json +110 -42
- package/examples/Hue Rules.json +105 -37
- package/examples/Hue Scene.json +145 -28
- package/examples/Hue Temperature.json +124 -14
- package/huemagic/animations/019-christmas.json +30 -0
- package/huemagic/animations/020-superhero.json +56 -0
- package/huemagic/animations/021-neoncity.json +52 -0
- package/huemagic/animations/previews/006-fireplace.gif +0 -0
- package/huemagic/animations/previews/013-strobo.gif +0 -0
- package/huemagic/animations/previews/014-randomrainbow.gif +0 -0
- package/huemagic/animations/previews/016-milkyway.gif +0 -0
- package/huemagic/animations/previews/018-forest.gif +0 -0
- package/huemagic/animations/previews/019-christmas.gif +0 -0
- package/huemagic/animations/previews/020-superhero.gif +0 -0
- package/huemagic/animations/previews/021-neoncity.gif +0 -0
- package/huemagic/hue-bridge-config.html +105 -61
- package/huemagic/hue-bridge-config.js +631 -319
- package/huemagic/hue-bridge.html +41 -21
- package/huemagic/hue-bridge.js +190 -396
- package/huemagic/hue-brightness.html +127 -59
- package/huemagic/hue-brightness.js +111 -55
- package/huemagic/hue-buttons.html +197 -0
- package/huemagic/hue-buttons.js +158 -0
- package/huemagic/hue-group.html +137 -66
- package/huemagic/hue-group.js +387 -403
- package/huemagic/hue-light.html +132 -64
- package/huemagic/hue-light.js +544 -378
- package/huemagic/hue-magic.html +36 -20
- package/huemagic/hue-magic.js +49 -27
- package/huemagic/hue-motion.html +127 -59
- package/huemagic/hue-motion.js +105 -101
- package/huemagic/hue-rules.html +121 -50
- package/huemagic/hue-rules.js +89 -63
- package/huemagic/hue-scene.html +95 -114
- package/huemagic/hue-scene.js +64 -95
- package/huemagic/hue-temperature.html +127 -59
- package/huemagic/hue-temperature.js +120 -56
- package/huemagic/icons/hue-bridge.png +0 -0
- package/huemagic/icons/hue-bridge.svg +3 -0
- package/huemagic/icons/hue-brightness.png +0 -0
- package/huemagic/icons/hue-brightness.svg +11 -0
- package/huemagic/icons/hue-buttons.png +0 -0
- package/huemagic/icons/hue-buttons.svg +4 -0
- package/huemagic/icons/hue-group.png +0 -0
- package/huemagic/icons/hue-group.svg +12 -0
- package/huemagic/icons/hue-light.png +0 -0
- package/huemagic/icons/hue-light.svg +3 -0
- package/huemagic/icons/hue-magic.png +0 -0
- package/huemagic/icons/hue-magic.svg +3 -0
- package/huemagic/icons/hue-motion.png +0 -0
- package/huemagic/icons/hue-motion.svg +9 -0
- package/huemagic/icons/hue-rules.png +0 -0
- package/huemagic/icons/hue-rules.svg +4 -0
- package/huemagic/icons/hue-scene.png +0 -0
- package/huemagic/icons/hue-scene.svg +5 -0
- package/huemagic/icons/hue-temperature.png +0 -0
- package/huemagic/icons/hue-temperature.svg +7 -0
- package/huemagic/locales/de/hue-bridge-config.html +17 -12
- package/huemagic/locales/de/hue-bridge-config.json +7 -5
- package/huemagic/locales/de/hue-bridge.html +64 -145
- package/huemagic/locales/de/hue-bridge.json +6 -17
- package/huemagic/locales/de/hue-brightness.html +50 -50
- package/huemagic/locales/de/hue-brightness.json +6 -5
- package/huemagic/locales/de/hue-buttons.html +58 -0
- package/huemagic/locales/de/{hue-button.json → hue-buttons.json} +7 -11
- package/huemagic/locales/de/hue-group.html +46 -122
- package/huemagic/locales/de/hue-group.json +5 -5
- package/huemagic/locales/de/hue-light.html +68 -116
- package/huemagic/locales/de/hue-light.json +5 -5
- package/huemagic/locales/de/hue-magic.html +65 -57
- package/huemagic/locales/de/hue-magic.json +2 -1
- package/huemagic/locales/de/hue-motion.html +47 -50
- package/huemagic/locales/de/hue-motion.json +5 -5
- package/huemagic/locales/de/hue-rules.html +68 -73
- package/huemagic/locales/de/hue-rules.json +5 -2
- package/huemagic/locales/de/hue-scene.html +23 -32
- package/huemagic/locales/de/hue-scene.json +5 -2
- package/huemagic/locales/de/hue-temperature.html +51 -48
- package/huemagic/locales/de/hue-temperature.json +6 -5
- package/huemagic/locales/en-US/hue-bridge-config.html +17 -12
- package/huemagic/locales/en-US/hue-bridge-config.json +5 -3
- package/huemagic/locales/en-US/hue-bridge.html +64 -145
- package/huemagic/locales/en-US/hue-bridge.json +5 -16
- package/huemagic/locales/en-US/hue-brightness.html +50 -50
- package/huemagic/locales/en-US/hue-brightness.json +5 -2
- package/huemagic/locales/en-US/hue-buttons.html +58 -0
- package/huemagic/locales/en-US/{hue-button.json → hue-buttons.json} +6 -4
- package/huemagic/locales/en-US/hue-group.html +46 -122
- package/huemagic/locales/en-US/hue-group.json +4 -2
- package/huemagic/locales/en-US/hue-light.html +68 -116
- package/huemagic/locales/en-US/hue-light.json +4 -2
- package/huemagic/locales/en-US/hue-magic.html +65 -57
- package/huemagic/locales/en-US/hue-magic.json +3 -1
- package/huemagic/locales/en-US/hue-motion.html +47 -50
- package/huemagic/locales/en-US/hue-motion.json +4 -2
- package/huemagic/locales/en-US/hue-rules.html +68 -73
- package/huemagic/locales/en-US/hue-rules.json +5 -2
- package/huemagic/locales/en-US/hue-scene.html +23 -32
- package/huemagic/locales/en-US/hue-scene.json +5 -2
- package/huemagic/locales/en-US/hue-temperature.html +51 -48
- package/huemagic/locales/en-US/hue-temperature.json +5 -2
- package/huemagic/utils/api.js +290 -0
- package/huemagic/utils/color.js +382 -0
- package/{utils → huemagic/utils}/merge.js +4 -6
- package/huemagic/utils/messages.js +447 -0
- package/package.json +9 -15
- package/examples/Hue Button.json +0 -40
- package/examples/Hue Switch.json +0 -40
- package/examples/Hue Tap.json +0 -40
- package/huemagic/hue-button.html +0 -132
- package/huemagic/hue-button.js +0 -143
- package/huemagic/hue-switch.html +0 -132
- package/huemagic/hue-switch.js +0 -163
- package/huemagic/hue-tap.html +0 -132
- package/huemagic/hue-tap.js +0 -123
- package/huemagic/icons/hue-button.png +0 -0
- package/huemagic/icons/hue-switch.png +0 -0
- package/huemagic/icons/hue-tap.png +0 -0
- package/huemagic/locales/de/hue-button.html +0 -64
- package/huemagic/locales/de/hue-switch.html +0 -64
- package/huemagic/locales/de/hue-switch.json +0 -35
- package/huemagic/locales/de/hue-tap.html +0 -55
- package/huemagic/locales/de/hue-tap.json +0 -27
- package/huemagic/locales/en-US/hue-button.html +0 -64
- package/huemagic/locales/en-US/hue-switch.html +0 -64
- package/huemagic/locales/en-US/hue-switch.json +0 -35
- package/huemagic/locales/en-US/hue-tap.html +0 -55
- package/huemagic/locales/en-US/hue-tap.json +0 -27
- package/utils/color.js +0 -9
- package/utils/messages.js +0 -658
- package/utils/rgb.js +0 -188
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
<script type="text/x-red" data-template-name="hue-buttons">
|
|
2
|
+
<div class="form-row">
|
|
3
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="hue-buttons.config.name"></span></label>
|
|
4
|
+
<input type="text" id="node-input-name" data-i18n="[placeholder]hue-buttons.config.input-name" style="width: calc(100% - 105px)">
|
|
5
|
+
</div>
|
|
6
|
+
<div class="form-row">
|
|
7
|
+
<label for="node-input-bridge"><i class="fa fa-server"></i> Bridge</label>
|
|
8
|
+
<input type="text" id="node-input-bridge" style="width: calc(100% - 105px)">
|
|
9
|
+
</div>
|
|
10
|
+
<div class="form-row">
|
|
11
|
+
<label for="node-input-sensorid"><i class="fa fa-hand-pointer-o"></i> <span data-i18n="hue-buttons.config.button"></span></label>
|
|
12
|
+
<div style="display: inline-flex; width: calc(100% - 105px)">
|
|
13
|
+
<div id="input-select-toggle" style="flex-grow: 1;">
|
|
14
|
+
<input type="text" id="node-input-sensorid" placeholder="00000000-0000-0000-0000-000000000000" style="width: 100%"/>
|
|
15
|
+
</div>
|
|
16
|
+
<button id="node-config-input-scan-buttons-sensors" type="button" class="red-ui-button" style="margin-left: 10px;">
|
|
17
|
+
<i class="fa fa-search"></i>
|
|
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-buttons.config.skipevents-node" style="width: 100%; margin-left: 10px;"></span>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="form-row">
|
|
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-buttons.config.sendinitevents-node" style="width: 100%; margin-left: 10px;"></span>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<script type="text/javascript">
|
|
36
|
+
RED.nodes.registerType('hue-buttons',{
|
|
37
|
+
category: 'HueMagic',
|
|
38
|
+
color: '#347aeb',
|
|
39
|
+
defaults: {
|
|
40
|
+
name: { value:"" },
|
|
41
|
+
bridge: { type: "hue-bridge", required: true },
|
|
42
|
+
sensorid: { value:"", required: false },
|
|
43
|
+
skipevents: { value: false },
|
|
44
|
+
initevents: { value: false }
|
|
45
|
+
},
|
|
46
|
+
align: 'left',
|
|
47
|
+
icon: "hue-buttons.png",
|
|
48
|
+
inputs: 1,
|
|
49
|
+
outputs: 1,
|
|
50
|
+
label: function() {
|
|
51
|
+
return this.name || this._("hue-buttons.node.title");
|
|
52
|
+
},
|
|
53
|
+
paletteLabel: function() {
|
|
54
|
+
return this._("hue-buttons.node.title");
|
|
55
|
+
},
|
|
56
|
+
inputLabels: function() {
|
|
57
|
+
return this._("hue-buttons.node.input");
|
|
58
|
+
},
|
|
59
|
+
outputLabels: function() {
|
|
60
|
+
return this._("hue-buttons.node.output");
|
|
61
|
+
},
|
|
62
|
+
oneditprepare: function()
|
|
63
|
+
{
|
|
64
|
+
const scope = this;
|
|
65
|
+
let options = [];
|
|
66
|
+
|
|
67
|
+
function manualInput()
|
|
68
|
+
{
|
|
69
|
+
// GET CURRENT SELECTED VALUE
|
|
70
|
+
var current = $('#node-input-sensorid').val();
|
|
71
|
+
|
|
72
|
+
// REMOVE SELECT FIELD
|
|
73
|
+
$('#input-select-toggle').empty();
|
|
74
|
+
|
|
75
|
+
// CREATE NEW INPUT FIELD
|
|
76
|
+
$('#input-select-toggle').append('<input type="text" id="node-input-sensorid" placeholder="00000000-0000-0000-0000-000000000000" style="width: 100%" value="'+current+'" />');
|
|
77
|
+
|
|
78
|
+
// CHANGE BUTTON ICON
|
|
79
|
+
var button = $("#node-config-input-scan-buttons-sensors");
|
|
80
|
+
var buttonIcon = button.find("i");
|
|
81
|
+
buttonIcon.removeClass("fa-pencil");
|
|
82
|
+
buttonIcon.addClass("fa-search");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function searchAndSelect()
|
|
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
|
|
92
|
+
var current = $('#node-input-sensorid').val();
|
|
93
|
+
|
|
94
|
+
// TRIGGER SEARCHING NOTIFICATION
|
|
95
|
+
var notification = RED.notify(scope._("hue-buttons.config.searching"), { type: "compact", modal: true, fixed: true });
|
|
96
|
+
|
|
97
|
+
// GET THE SENSORS
|
|
98
|
+
$.get('hue/resources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "button" })
|
|
99
|
+
.done( function(data) {
|
|
100
|
+
var allResources = JSON.parse(data);
|
|
101
|
+
if(allResources.length <= 0)
|
|
102
|
+
{
|
|
103
|
+
notification.close();
|
|
104
|
+
RED.notify(scope._("hue-buttons.config.none-found"), { type: "error" });
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// SET OPTIONS
|
|
109
|
+
allResources.forEach(function(resource)
|
|
110
|
+
{
|
|
111
|
+
if(resource.model)
|
|
112
|
+
{
|
|
113
|
+
options[resource.id] = { value: resource.id, label: resource.name + " ("+resource.model+")" };
|
|
114
|
+
}
|
|
115
|
+
else
|
|
116
|
+
{
|
|
117
|
+
options[resource.id] = { value: resource.id, label: resource.name };
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// SELECT CURRENT VALUE
|
|
122
|
+
$("#node-input-sensorid").typedInput({
|
|
123
|
+
types: [
|
|
124
|
+
{
|
|
125
|
+
value: current,
|
|
126
|
+
options: Object.values(options)
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// CHANGE BUTTON ICON
|
|
132
|
+
var button = $("#node-config-input-scan-buttons-sensors");
|
|
133
|
+
var buttonIcon = button.find("i");
|
|
134
|
+
buttonIcon.removeClass("fa-search");
|
|
135
|
+
buttonIcon.addClass("fa-pencil");
|
|
136
|
+
|
|
137
|
+
// CLOSE SEARCH NOTIFICATION
|
|
138
|
+
notification.close();
|
|
139
|
+
})
|
|
140
|
+
.fail(function()
|
|
141
|
+
{
|
|
142
|
+
notification.close();
|
|
143
|
+
RED.notify(scope._("hue-buttons.config.unknown-error"), "error");
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// CHANGED SENSOR ID? -> REPLACE NAME (IF POSSIBLE)
|
|
148
|
+
$(document).on('change', '#node-input-sensorid', function(e)
|
|
149
|
+
{
|
|
150
|
+
let currentSelectedOptionID = $(e.currentTarget).val();
|
|
151
|
+
let currentSelectedOptionValue = (currentSelectedOptionID.length > 0 && options[currentSelectedOptionID]) ? options[currentSelectedOptionID].label : false;
|
|
152
|
+
|
|
153
|
+
if(currentSelectedOptionValue !== false)
|
|
154
|
+
{
|
|
155
|
+
$('#node-input-name').val(currentSelectedOptionValue.split(" (")[0]);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// TOGGLE SELECT/INPUT FIELD
|
|
160
|
+
$('#node-config-input-scan-buttons-sensors').click(function()
|
|
161
|
+
{
|
|
162
|
+
if($('#input-select-toggle').find(".red-ui-typedInput-container").length > 0)
|
|
163
|
+
{
|
|
164
|
+
manualInput();
|
|
165
|
+
}
|
|
166
|
+
else
|
|
167
|
+
{
|
|
168
|
+
searchAndSelect();
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
},
|
|
172
|
+
button: {
|
|
173
|
+
enabled: function() {
|
|
174
|
+
return (this.sensorid && this.sensorid.length > 1)
|
|
175
|
+
},
|
|
176
|
+
visible: function() {
|
|
177
|
+
return (this.sensorid && this.sensorid.length > 1)
|
|
178
|
+
},
|
|
179
|
+
onclick: function()
|
|
180
|
+
{
|
|
181
|
+
const node = this;
|
|
182
|
+
if(node.bridge)
|
|
183
|
+
{
|
|
184
|
+
$.ajax({
|
|
185
|
+
url: "inject/" + node.id,
|
|
186
|
+
type: "POST",
|
|
187
|
+
data: JSON.stringify({ __user_inject_props__: "status"}),
|
|
188
|
+
contentType: "application/json; charset=utf-8",
|
|
189
|
+
success: function (resp) {
|
|
190
|
+
RED.notify(node.name + ": " + node._("hue-buttons.node.statusmsg"), { type: "success", id: "status", timeout: 2000 });
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
</script>
|
|
@@ -0,0 +1,158 @@
|
|
|
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
|
+
// RESOURCE 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.resources[config.sensorid]["services"]["button"]))
|
|
106
|
+
{
|
|
107
|
+
delete bridge.resources[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 = RED.util.cloneMessage(msg);
|
|
125
|
+
|
|
126
|
+
// DEFINE SENSOR ID
|
|
127
|
+
const tempSensorID = (!config.sensorid && typeof msg.topic != 'undefined' && bridge.validResourceID.test(msg.topic) === true) ? msg.topic : config.sensorid;
|
|
128
|
+
if(!tempSensorID)
|
|
129
|
+
{
|
|
130
|
+
scope.error("Please submit a valid button ID.");
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
let currentState = bridge.get("button", tempSensorID);
|
|
135
|
+
|
|
136
|
+
// GET CURRENT STATE
|
|
137
|
+
if( (typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined') || (typeof msg.__user_inject_props__ != 'undefined' && msg.__user_inject_props__ == "status") )
|
|
138
|
+
{
|
|
139
|
+
// SET LAST COMMAND
|
|
140
|
+
if(scope.lastCommand !== null)
|
|
141
|
+
{
|
|
142
|
+
currentState.command = scope.lastCommand;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// SEND STATE
|
|
146
|
+
scope.send(currentState);
|
|
147
|
+
|
|
148
|
+
// RESET LAST COMMAND
|
|
149
|
+
scope.lastCommand = null;
|
|
150
|
+
|
|
151
|
+
if(done) { done(); }
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
RED.nodes.registerType("hue-buttons", HueButtons);
|
|
158
|
+
}
|
package/huemagic/hue-group.html
CHANGED
|
@@ -1,38 +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-
|
|
13
|
-
<div style="
|
|
14
|
-
<input type="text" id="node-input-groupid" placeholder="
|
|
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
|
-
<
|
|
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
|
-
</
|
|
18
|
+
</button>
|
|
19
19
|
</div>
|
|
20
20
|
</div>
|
|
21
|
-
<div class="form-row">
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
</
|
|
26
|
-
</div>
|
|
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>
|
|
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>
|
|
31
26
|
</div>
|
|
32
27
|
<div class="form-row">
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
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>
|
|
36
32
|
</div>
|
|
37
33
|
</script>
|
|
38
34
|
|
|
@@ -41,97 +37,172 @@
|
|
|
41
37
|
category: 'HueMagic',
|
|
42
38
|
color: '#f94f8b',
|
|
43
39
|
defaults: {
|
|
44
|
-
name: {value:""},
|
|
45
|
-
bridge: {type: "hue-bridge", required: true},
|
|
46
|
-
groupid: {value:"", required: false,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
else { return false; }
|
|
50
|
-
}},
|
|
51
|
-
colornamer: {value: true},
|
|
52
|
-
skipevents: {value: false},
|
|
53
|
-
universalevents: {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 }
|
|
54
45
|
},
|
|
46
|
+
align: 'left',
|
|
47
|
+
icon: "hue-group.png",
|
|
55
48
|
inputs: 1,
|
|
56
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
|
+
},
|
|
57
56
|
inputLabels: function() {
|
|
58
57
|
return this._("hue-group.node.input");
|
|
59
58
|
},
|
|
60
59
|
outputLabels: function() {
|
|
61
60
|
return this._("hue-group.node.output");
|
|
62
61
|
},
|
|
63
|
-
align: 'right',
|
|
64
|
-
icon: "hue-group.png",
|
|
65
|
-
paletteLabel: function() {
|
|
66
|
-
return this._("hue-group.node.title");
|
|
67
|
-
},
|
|
68
|
-
label: function() {
|
|
69
|
-
return this.name || this._("hue-group.node.title");
|
|
70
|
-
},
|
|
71
62
|
oneditprepare: function()
|
|
72
63
|
{
|
|
73
|
-
|
|
64
|
+
const scope = this;
|
|
65
|
+
let options = [];
|
|
74
66
|
|
|
75
|
-
function
|
|
67
|
+
function manualInput()
|
|
76
68
|
{
|
|
69
|
+
// GET CURRENT SELECTED VALUE
|
|
77
70
|
var current = $('#node-input-groupid').val();
|
|
78
|
-
|
|
79
|
-
|
|
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");
|
|
80
83
|
}
|
|
81
84
|
|
|
82
|
-
function
|
|
85
|
+
function searchAndSelect()
|
|
83
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
|
|
84
92
|
var current = $('#node-input-groupid').val();
|
|
85
|
-
$('#node-input-groupid').replaceWith('<select id="node-input-groupid" style="width: 100%"></select>');
|
|
86
|
-
$('#node-input-groupid').append('<option selected="selected" value="null">'+scope._("hue-group.config.searching")+'</option>');
|
|
87
93
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
.done(function(data) {
|
|
91
|
-
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 });
|
|
92
96
|
|
|
93
|
-
|
|
97
|
+
// GET THE GROUPS
|
|
98
|
+
$.get('hue/resources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "group" })
|
|
99
|
+
.done( function(data) {
|
|
100
|
+
var allResources = JSON.parse(data);
|
|
101
|
+
if(allResources.length <= 0)
|
|
94
102
|
{
|
|
95
|
-
|
|
103
|
+
notification.close();
|
|
104
|
+
RED.notify(scope._("hue-group.config.none-found"), { type: "error" });
|
|
105
|
+
return false;
|
|
96
106
|
}
|
|
97
107
|
|
|
98
|
-
// RESET OPTIONS
|
|
99
|
-
$('#node-input-groupid').empty();
|
|
100
|
-
|
|
101
108
|
// SET GROUPS AS OPTIONS
|
|
102
|
-
|
|
103
|
-
groups.forEach(function(group)
|
|
109
|
+
allResources.forEach(function(resource)
|
|
104
110
|
{
|
|
105
|
-
|
|
111
|
+
if(!resource.name) // ALL SPECIAL
|
|
112
|
+
{
|
|
113
|
+
options[resource.id] = { value: resource.id, label: "● "+scope._("hue-group.config.all") };
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
allResources.forEach(function(resource)
|
|
118
|
+
{
|
|
119
|
+
if(resource.name) // REGULAR GROUPS
|
|
120
|
+
{
|
|
121
|
+
if(resource.model)
|
|
122
|
+
{
|
|
123
|
+
options[resource.id] = { value: resource.id, label: resource.name + " ("+resource.model+")" };
|
|
124
|
+
}
|
|
125
|
+
else
|
|
126
|
+
{
|
|
127
|
+
options[resource.id] = { value: resource.id, label: resource.name };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
106
130
|
});
|
|
107
131
|
|
|
108
132
|
// SELECT CURRENT VALUE
|
|
109
|
-
$(
|
|
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();
|
|
110
150
|
})
|
|
111
151
|
.fail(function()
|
|
112
152
|
{
|
|
153
|
+
notification.close();
|
|
113
154
|
RED.notify(scope._("hue-group.config.unknown-error"), "error");
|
|
114
155
|
});
|
|
115
156
|
}
|
|
116
157
|
|
|
117
|
-
|
|
158
|
+
// CHANGED GROUP ID? -> REPLACE NAME (IF POSSIBLE)
|
|
159
|
+
$(document).on('change', '#node-input-groupid', function(e)
|
|
118
160
|
{
|
|
119
|
-
|
|
120
|
-
|
|
161
|
+
let currentSelectedOptionID = $(e.currentTarget).val();
|
|
162
|
+
let currentSelectedOptionValue = (currentSelectedOptionID.length > 0 && options[currentSelectedOptionID]) ? options[currentSelectedOptionID].label : false;
|
|
163
|
+
|
|
164
|
+
if(currentSelectedOptionValue !== false)
|
|
121
165
|
{
|
|
122
|
-
$('#node-input-name').val(
|
|
166
|
+
$('#node-input-name').val(currentSelectedOptionValue.split(" (")[0]);
|
|
123
167
|
}
|
|
124
168
|
});
|
|
125
169
|
|
|
170
|
+
// TOGGLE SELECT/INPUT FIELD
|
|
126
171
|
$('#node-config-input-scan-groups').click(function()
|
|
127
172
|
{
|
|
128
|
-
if($('#
|
|
173
|
+
if($('#input-select-toggle').find(".red-ui-typedInput-container").length > 0)
|
|
129
174
|
{
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
175
|
+
manualInput();
|
|
176
|
+
}
|
|
177
|
+
else
|
|
178
|
+
{
|
|
179
|
+
searchAndSelect();
|
|
133
180
|
}
|
|
134
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
|
+
}
|
|
135
206
|
}
|
|
136
207
|
});
|
|
137
208
|
</script>
|