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
package/huemagic/hue-button.html
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
<script type="text/x-red" data-template-name="hue-button">
|
|
2
|
-
<div class="form-row">
|
|
3
|
-
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="hue-button.config.name"></span></label>
|
|
4
|
-
<input type="text" id="node-input-name" data-i18n="[placeholder]hue-button.config.input-name">
|
|
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">
|
|
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-button.config.button"></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-sensorid" placeholder="1" style="width: 100%"/>
|
|
15
|
-
</div>
|
|
16
|
-
<a id="node-config-input-scan-buttons-sensors" class="editor-button" style="position: absolute; right: 0px; top: 0px;">
|
|
17
|
-
<i class="fa fa-search"></i>
|
|
18
|
-
</a>
|
|
19
|
-
</div>
|
|
20
|
-
</div>
|
|
21
|
-
<div class="form-row">
|
|
22
|
-
<label for="node-input-skipevents"><i class="fa fa-sign-out"></i> <span data-i18n="hue-button.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-button.config.skipevents-node"></span>
|
|
24
|
-
</label>
|
|
25
|
-
</div>
|
|
26
|
-
<div class="form-row">
|
|
27
|
-
<label for="node-input-universalevents"><i class="fa fa-bullhorn"></i> <span data-i18n="hue-button.config.universalevents"></span></label>
|
|
28
|
-
<input type="checkbox" id="node-input-universalevents" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="hue-button.config.universalevents-node"></span>
|
|
29
|
-
</label>
|
|
30
|
-
</div>
|
|
31
|
-
</script>
|
|
32
|
-
|
|
33
|
-
<script type="text/javascript">
|
|
34
|
-
RED.nodes.registerType('hue-button',{
|
|
35
|
-
category: 'HueMagic',
|
|
36
|
-
color: '#347aeb',
|
|
37
|
-
defaults: {
|
|
38
|
-
name: {value:""},
|
|
39
|
-
bridge: {type: "hue-bridge", required: true},
|
|
40
|
-
sensorid: {value:"", required: false, validate: function(id) {
|
|
41
|
-
if(id.length < 1) { return true; }
|
|
42
|
-
else if(!isNaN(id)) { return true; }
|
|
43
|
-
else { return false; }
|
|
44
|
-
}},
|
|
45
|
-
skipevents: {value: false},
|
|
46
|
-
universalevents: {value: false}
|
|
47
|
-
},
|
|
48
|
-
inputs: 1,
|
|
49
|
-
outputs: 1,
|
|
50
|
-
inputLabels: function() {
|
|
51
|
-
return this._("hue-button.node.input");
|
|
52
|
-
},
|
|
53
|
-
outputLabels: function() {
|
|
54
|
-
return this._("hue-button.node.output");
|
|
55
|
-
},
|
|
56
|
-
align: 'right',
|
|
57
|
-
icon: "hue-button.png",
|
|
58
|
-
paletteLabel: function() {
|
|
59
|
-
return this._("hue-button.node.title");
|
|
60
|
-
},
|
|
61
|
-
label: function() {
|
|
62
|
-
return this.name || this._("hue-button.node.title");
|
|
63
|
-
},
|
|
64
|
-
oneditprepare: function()
|
|
65
|
-
{
|
|
66
|
-
var scope = this;
|
|
67
|
-
|
|
68
|
-
function manualButtonID()
|
|
69
|
-
{
|
|
70
|
-
var current = $('#node-input-sensorid').val();
|
|
71
|
-
$('#node-input-sensorid').replaceWith('<input type="text" id="node-input-sensorid" style="width: 100%"/>');
|
|
72
|
-
$('#node-input-sensorid').val(current);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function searchAndSelectHueButtonID()
|
|
76
|
-
{
|
|
77
|
-
var current = $('#node-input-sensorid').val();
|
|
78
|
-
$('#node-input-sensorid').replaceWith('<select id="node-input-sensorid" style="width: 100%"></select>');
|
|
79
|
-
$('#node-input-sensorid').append('<option selected="selected" value="null">'+scope._("hue-button.config.searching")+'</option>');
|
|
80
|
-
|
|
81
|
-
var bridgeConfig = RED.nodes.node($('#node-input-bridge option:selected').val());
|
|
82
|
-
$.get('hue/sensors', {bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "ZLLSwitch"})
|
|
83
|
-
.done( function(data) {
|
|
84
|
-
var hueButtons = JSON.parse(data);
|
|
85
|
-
|
|
86
|
-
if(hueButtons.length <= 0)
|
|
87
|
-
{
|
|
88
|
-
RED.notify(scope._("hue-button.config.none-found"), "error");
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// RESET OPTIONS
|
|
92
|
-
$('#node-input-sensorid').empty();
|
|
93
|
-
|
|
94
|
-
// SET BUTTONS AS OPTIONS
|
|
95
|
-
hueButtons.forEach(function(sensor)
|
|
96
|
-
{
|
|
97
|
-
if(sensor.model_id == "ROM001") //to make sure it is a Smart Button
|
|
98
|
-
{
|
|
99
|
-
$('#node-input-sensorid').append('<option value="' + sensor.id + '">' + sensor.name + '</option>');
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// SELECT CURRENT VALUE
|
|
104
|
-
$('#node-input-sensorid').val(current);
|
|
105
|
-
})
|
|
106
|
-
.fail(function()
|
|
107
|
-
{
|
|
108
|
-
RED.notify("Something went wrong. Please retry.", "error");
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
$(document).on('change', '#node-input-sensorid', function()
|
|
113
|
-
{
|
|
114
|
-
var sensorName = $('#node-input-sensorid option:selected').text();
|
|
115
|
-
if(sensorName.length > 0)
|
|
116
|
-
{
|
|
117
|
-
$('#node-input-name').val(sensorName);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
$('#node-config-input-scan-buttons-sensors').click(function()
|
|
122
|
-
{
|
|
123
|
-
if($('#node-input-sensorid').prop("tagName") === "INPUT")
|
|
124
|
-
{
|
|
125
|
-
searchAndSelectHueButtonID();
|
|
126
|
-
} else {
|
|
127
|
-
manualButtonID();
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
</script>
|
package/huemagic/hue-button.js
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
module.exports = function(RED)
|
|
2
|
-
{
|
|
3
|
-
"use strict";
|
|
4
|
-
|
|
5
|
-
function HueButton(config)
|
|
6
|
-
{
|
|
7
|
-
RED.nodes.createNode(this, config);
|
|
8
|
-
|
|
9
|
-
var scope = this;
|
|
10
|
-
let bridge = RED.nodes.getNode(config.bridge);
|
|
11
|
-
let { HueButtonMessage } = require('../utils/messages');
|
|
12
|
-
var universalMode = false;
|
|
13
|
-
|
|
14
|
-
// SAVE LAST STATE
|
|
15
|
-
var lastState = false;
|
|
16
|
-
|
|
17
|
-
//
|
|
18
|
-
// MEMORY
|
|
19
|
-
this.lastUpdated = false;
|
|
20
|
-
|
|
21
|
-
//
|
|
22
|
-
// CHECK CONFIG
|
|
23
|
-
if(!config.sensorid || bridge == null)
|
|
24
|
-
{
|
|
25
|
-
this.status({fill: "red", shape: "ring", text: "hue-button.node.not-configured"});
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
//
|
|
30
|
-
// UNIVERSAL MODE?
|
|
31
|
-
if(!config.sensorid)
|
|
32
|
-
{
|
|
33
|
-
universalMode = true;
|
|
34
|
-
this.status({fill: "grey", shape: "dot", text: "hue-button.node.universal"});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
//
|
|
38
|
-
// UPDATE STATE
|
|
39
|
-
if(config.sensorid)
|
|
40
|
-
{
|
|
41
|
-
scope.status({fill: "grey", shape: "dot", text: "hue-button.node.waiting"});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
// ON UPDATE
|
|
46
|
-
if(config.sensorid) { bridge.events.on('sensor' + config.sensorid, function(sensor) { scope.receivedUpdates(sensor) }); }
|
|
47
|
-
if(!config.sensorid && config.universalevents && config.universalevents == true) { bridge.events.on('sensor', function(sensor) { scope.receivedUpdates(sensor) }); }
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
// RECEIVED UPDATES
|
|
51
|
-
this.receivedUpdates = function(sensor)
|
|
52
|
-
{
|
|
53
|
-
var lastUpdated = scope.lastUpdated || false;
|
|
54
|
-
if(sensor.state.lastUpdated != lastUpdated)
|
|
55
|
-
{
|
|
56
|
-
scope.lastUpdated = sensor.state.lastUpdated;
|
|
57
|
-
|
|
58
|
-
// RETURN ON FIRST DEPLOY
|
|
59
|
-
if (lastUpdated === false) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// DEFINE HUMAN READABLE BUTTON ACTION
|
|
64
|
-
if(universalMode == false)
|
|
65
|
-
{
|
|
66
|
-
var buttonActionLocalized = "";
|
|
67
|
-
var buttonActionRaw = parseInt(sensor.state.buttonEvent.toString().substring(3));
|
|
68
|
-
if(buttonActionRaw == 0)
|
|
69
|
-
{
|
|
70
|
-
buttonActionLocalized = RED._("hue-button.node.action-pressed");
|
|
71
|
-
}
|
|
72
|
-
else if(buttonActionRaw == 1)
|
|
73
|
-
{
|
|
74
|
-
buttonActionLocalized = RED._("hue-button.node.action-holded");
|
|
75
|
-
}
|
|
76
|
-
else if(buttonActionRaw == 2)
|
|
77
|
-
{
|
|
78
|
-
buttonActionLocalized = RED._("hue-button.node.action-shortreleased");
|
|
79
|
-
}
|
|
80
|
-
else
|
|
81
|
-
{
|
|
82
|
-
buttonActionLocalized = RED._("hue-button.node.action-longreleased");
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// SEND STATUS
|
|
86
|
-
scope.status({fill: "green", shape: "dot", text: buttonActionLocalized});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// SEND MESSAGE
|
|
90
|
-
if(!config.skipevents)
|
|
91
|
-
{
|
|
92
|
-
var hueButton = new HueButtonMessage(sensor, (universalMode == false) ? lastState : false);
|
|
93
|
-
scope.send(hueButton.msg);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// SAVE LAST STATE
|
|
97
|
-
lastState = sensor;
|
|
98
|
-
}
|
|
99
|
-
else
|
|
100
|
-
{
|
|
101
|
-
if(universalMode == false)
|
|
102
|
-
{
|
|
103
|
-
scope.status({fill: "grey", shape: "dot", text: "hue-button.node.waiting"});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
//
|
|
109
|
-
// ON COMMAND
|
|
110
|
-
this.on('input', function(msg, send, done)
|
|
111
|
-
{
|
|
112
|
-
// Node-RED < 1.0
|
|
113
|
-
send = send || function() { scope.send.apply(scope,arguments); }
|
|
114
|
-
|
|
115
|
-
// DEFINE SENSOR ID
|
|
116
|
-
var tempSensorID = (msg.topic != null && isNaN(msg.topic) == false && msg.topic.length > 0) ? parseInt(msg.topic) : config.sensorid;
|
|
117
|
-
|
|
118
|
-
// GET CURRENT STATE
|
|
119
|
-
if(typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined')
|
|
120
|
-
{
|
|
121
|
-
bridge.client.sensors.getById(tempSensorID)
|
|
122
|
-
.then(sensor => {
|
|
123
|
-
var hueButton = new HueButtonMessage(sensor, lastState);
|
|
124
|
-
send(hueButton.msg);
|
|
125
|
-
|
|
126
|
-
return true;
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
return true;
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
//
|
|
134
|
-
// CLOSE NODE / REMOVE EVENT LISTENER
|
|
135
|
-
this.on('close', function()
|
|
136
|
-
{
|
|
137
|
-
bridge.events.removeAllListeners('sensor' + config.sensorid);
|
|
138
|
-
bridge.events.removeAllListeners('sensor');
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
RED.nodes.registerType("hue-button", HueButton);
|
|
143
|
-
}
|
package/huemagic/hue-switch.html
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
<script type="text/x-red" data-template-name="hue-switch">
|
|
2
|
-
<div class="form-row">
|
|
3
|
-
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="hue-switch.config.name"></span></label>
|
|
4
|
-
<input type="text" id="node-input-name" data-i18n="[placeholder]hue-switch.config.input-name">
|
|
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">
|
|
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-switch.config.switch"></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-sensorid" placeholder="1" style="width: 100%"/>
|
|
15
|
-
</div>
|
|
16
|
-
<a id="node-config-input-scan-switches-sensors" class="editor-button" style="position: absolute; right: 0px; top: 0px;">
|
|
17
|
-
<i class="fa fa-search"></i>
|
|
18
|
-
</a>
|
|
19
|
-
</div>
|
|
20
|
-
</div>
|
|
21
|
-
<div class="form-row">
|
|
22
|
-
<label for="node-input-skipevents"><i class="fa fa-sign-out"></i> <span data-i18n="hue-switch.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-switch.config.skipevents-node"></span>
|
|
24
|
-
</label>
|
|
25
|
-
</div>
|
|
26
|
-
<div class="form-row">
|
|
27
|
-
<label for="node-input-universalevents"><i class="fa fa-bullhorn"></i> <span data-i18n="hue-switch.config.universalevents"></span></label>
|
|
28
|
-
<input type="checkbox" id="node-input-universalevents" style="display:inline-block; width:22px; vertical-align:baseline;"><span data-i18n="hue-switch.config.universalevents-node"></span>
|
|
29
|
-
</label>
|
|
30
|
-
</div>
|
|
31
|
-
</script>
|
|
32
|
-
|
|
33
|
-
<script type="text/javascript">
|
|
34
|
-
RED.nodes.registerType('hue-switch',{
|
|
35
|
-
category: 'HueMagic',
|
|
36
|
-
color: '#65bff7',
|
|
37
|
-
defaults: {
|
|
38
|
-
name: {value:""},
|
|
39
|
-
bridge: {type: "hue-bridge", required: true},
|
|
40
|
-
sensorid: {value:"", required: false, validate: function(id) {
|
|
41
|
-
if(id.length < 1) { return true; }
|
|
42
|
-
else if(!isNaN(id)) { return true; }
|
|
43
|
-
else { return false; }
|
|
44
|
-
}},
|
|
45
|
-
skipevents: {value: false},
|
|
46
|
-
universalevents: {value: false}
|
|
47
|
-
},
|
|
48
|
-
inputs: 1,
|
|
49
|
-
outputs: 1,
|
|
50
|
-
inputLabels: function() {
|
|
51
|
-
return this._("hue-switch.node.input");
|
|
52
|
-
},
|
|
53
|
-
outputLabels: function() {
|
|
54
|
-
return this._("hue-switch.node.output");
|
|
55
|
-
},
|
|
56
|
-
align: 'right',
|
|
57
|
-
icon: "hue-switch.png",
|
|
58
|
-
paletteLabel: function() {
|
|
59
|
-
return this._("hue-switch.node.title");
|
|
60
|
-
},
|
|
61
|
-
label: function() {
|
|
62
|
-
return this.name || this._("hue-switch.node.title");
|
|
63
|
-
},
|
|
64
|
-
oneditprepare: function()
|
|
65
|
-
{
|
|
66
|
-
var scope = this;
|
|
67
|
-
|
|
68
|
-
function manualSwitchID()
|
|
69
|
-
{
|
|
70
|
-
var current = $('#node-input-sensorid').val();
|
|
71
|
-
$('#node-input-sensorid').replaceWith('<input type="text" id="node-input-sensorid" style="width: 100%"/>');
|
|
72
|
-
$('#node-input-sensorid').val(current);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function searchAndSelectHueSwitchID()
|
|
76
|
-
{
|
|
77
|
-
var current = $('#node-input-sensorid').val();
|
|
78
|
-
$('#node-input-sensorid').replaceWith('<select id="node-input-sensorid" style="width: 100%"></select>');
|
|
79
|
-
$('#node-input-sensorid').append('<option selected="selected" value="null">'+scope._("hue-switch.config.searching")+'</option>');
|
|
80
|
-
|
|
81
|
-
var bridgeConfig = RED.nodes.node($('#node-input-bridge option:selected').val());
|
|
82
|
-
$.get('hue/sensors', {bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "ZLLSwitch"})
|
|
83
|
-
.done( function(data) {
|
|
84
|
-
var hueSwitches = JSON.parse(data);
|
|
85
|
-
|
|
86
|
-
if(hueSwitches.length <= 0)
|
|
87
|
-
{
|
|
88
|
-
RED.notify(scope._("hue-switch.config.none-found"), "error");
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// RESET OPTIONS
|
|
92
|
-
$('#node-input-sensorid').empty();
|
|
93
|
-
|
|
94
|
-
// SET SWITCHES AS OPTIONS
|
|
95
|
-
hueSwitches.forEach(function(sensor)
|
|
96
|
-
{
|
|
97
|
-
if(sensor.model == "Hue Wireless Dimmer Switch")
|
|
98
|
-
{
|
|
99
|
-
$('#node-input-sensorid').append('<option value="' + sensor.id + '">' + sensor.name + '</option>');
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// SELECT CURRENT VALUE
|
|
104
|
-
$('#node-input-sensorid').val(current);
|
|
105
|
-
})
|
|
106
|
-
.fail(function()
|
|
107
|
-
{
|
|
108
|
-
RED.notify("Something went wrong. Please retry.", "error");
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
$(document).on('change', '#node-input-sensorid', function()
|
|
113
|
-
{
|
|
114
|
-
var sensorName = $('#node-input-sensorid option:selected').text();
|
|
115
|
-
if(sensorName.length > 0)
|
|
116
|
-
{
|
|
117
|
-
$('#node-input-name').val(sensorName);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
$('#node-config-input-scan-switches-sensors').click(function()
|
|
122
|
-
{
|
|
123
|
-
if($('#node-input-sensorid').prop("tagName") === "INPUT")
|
|
124
|
-
{
|
|
125
|
-
searchAndSelectHueSwitchID();
|
|
126
|
-
} else {
|
|
127
|
-
manualSwitchID();
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
</script>
|
package/huemagic/hue-switch.js
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
module.exports = function(RED)
|
|
2
|
-
{
|
|
3
|
-
"use strict";
|
|
4
|
-
|
|
5
|
-
function HueSwitch(config)
|
|
6
|
-
{
|
|
7
|
-
RED.nodes.createNode(this, config);
|
|
8
|
-
|
|
9
|
-
var scope = this;
|
|
10
|
-
let bridge = RED.nodes.getNode(config.bridge);
|
|
11
|
-
let { HueSwitchMessage } = require('../utils/messages');
|
|
12
|
-
var universalMode = false;
|
|
13
|
-
|
|
14
|
-
// SAVE LAST STATE
|
|
15
|
-
var lastState = false;
|
|
16
|
-
|
|
17
|
-
//
|
|
18
|
-
// MEMORY
|
|
19
|
-
this.lastUpdated = false;
|
|
20
|
-
|
|
21
|
-
//
|
|
22
|
-
// CHECK CONFIG
|
|
23
|
-
if(bridge == null)
|
|
24
|
-
{
|
|
25
|
-
this.status({fill: "red", shape: "ring", text: "hue-switch.node.not-configured"});
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
//
|
|
30
|
-
// UNIVERSAL MODE?
|
|
31
|
-
if(!config.sensorid)
|
|
32
|
-
{
|
|
33
|
-
universalMode = true;
|
|
34
|
-
this.status({fill: "grey", shape: "dot", text: "hue-switch.node.universal"});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
//
|
|
38
|
-
// UPDATE STATE
|
|
39
|
-
if(config.sensorid)
|
|
40
|
-
{
|
|
41
|
-
this.status({fill: "grey", shape: "dot", text: "hue-switch.node.waiting"});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
// ON UPDATE
|
|
46
|
-
if(config.sensorid) { bridge.events.on('sensor' + config.sensorid, function(sensor) { scope.receivedUpdates(sensor) }); }
|
|
47
|
-
if(!config.sensorid && config.universalevents && config.universalevents == true) { bridge.events.on('sensor', function(sensor) { scope.receivedUpdates(sensor) }); }
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
// RECEIVED UPDATES
|
|
51
|
-
this.receivedUpdates = function(sensor)
|
|
52
|
-
{
|
|
53
|
-
var lastUpdated = scope.lastUpdated || false;
|
|
54
|
-
if(sensor.state.lastUpdated != lastUpdated)
|
|
55
|
-
{
|
|
56
|
-
scope.lastUpdated = sensor.state.lastUpdated;
|
|
57
|
-
|
|
58
|
-
// RETURN ON FIRST DEPLOY
|
|
59
|
-
if (lastUpdated === false) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// STATUS MESSAGE
|
|
64
|
-
if(universalMode == false)
|
|
65
|
-
{
|
|
66
|
-
// DEFINE HUMAN READABLE BUTTON NAME
|
|
67
|
-
var buttonNameLocalized = "";
|
|
68
|
-
if(sensor.state.buttonEvent < 2000)
|
|
69
|
-
{
|
|
70
|
-
buttonNameLocalized = RED._("hue-switch.node.button-on");
|
|
71
|
-
}
|
|
72
|
-
else if(sensor.state.buttonEvent < 3000)
|
|
73
|
-
{
|
|
74
|
-
buttonNameLocalized = RED._("hue-switch.node.button-dimup");
|
|
75
|
-
}
|
|
76
|
-
else if(sensor.state.buttonEvent < 4000)
|
|
77
|
-
{
|
|
78
|
-
buttonNameLocalized = RED._("hue-switch.node.button-dimdown");
|
|
79
|
-
}
|
|
80
|
-
else
|
|
81
|
-
{
|
|
82
|
-
buttonNameLocalized = RED._("hue-switch.node.button-off");
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// DEFINE HUMAN READABLE BUTTON ACTION
|
|
86
|
-
var buttonActionLocalized = "";
|
|
87
|
-
var buttonActionRaw = parseInt(sensor.state.buttonEvent.toString().substring(3));
|
|
88
|
-
if(buttonActionRaw == 0)
|
|
89
|
-
{
|
|
90
|
-
buttonActionLocalized = RED._("hue-switch.node.action-pressed");
|
|
91
|
-
}
|
|
92
|
-
else if(buttonActionRaw == 1)
|
|
93
|
-
{
|
|
94
|
-
buttonActionLocalized = RED._("hue-switch.node.action-holded");
|
|
95
|
-
}
|
|
96
|
-
else if(buttonActionRaw == 2)
|
|
97
|
-
{
|
|
98
|
-
buttonActionLocalized = RED._("hue-switch.node.action-shortreleased");
|
|
99
|
-
}
|
|
100
|
-
else
|
|
101
|
-
{
|
|
102
|
-
buttonActionLocalized = RED._("hue-switch.node.action-longreleased");
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// SEND STATUS
|
|
106
|
-
scope.status({fill: "green", shape: "dot", text: buttonNameLocalized + " " + buttonActionLocalized});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// SEND MESSAGE
|
|
110
|
-
if(!config.skipevents)
|
|
111
|
-
{
|
|
112
|
-
var hueSwitch = new HueSwitchMessage(sensor, (universalMode == false) ? lastState : false);
|
|
113
|
-
scope.send(hueSwitch.msg);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// SAVE LAST STATE
|
|
117
|
-
lastState = sensor;
|
|
118
|
-
}
|
|
119
|
-
else
|
|
120
|
-
{
|
|
121
|
-
if(universalMode == false)
|
|
122
|
-
{
|
|
123
|
-
scope.status({fill: "grey", shape: "dot", text: "hue-switch.node.waiting"});
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
//
|
|
129
|
-
// ON COMMAND
|
|
130
|
-
this.on('input', function(msg, send, done)
|
|
131
|
-
{
|
|
132
|
-
// Node-RED < 1.0
|
|
133
|
-
send = send || function() { scope.send.apply(scope,arguments); }
|
|
134
|
-
|
|
135
|
-
// DEFINE SENSOR ID
|
|
136
|
-
var tempSensorID = (msg.topic != null && isNaN(msg.topic) == false && msg.topic.length > 0) ? parseInt(msg.topic) : config.sensorid;
|
|
137
|
-
|
|
138
|
-
// GET CURRENT STATE
|
|
139
|
-
if(typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined')
|
|
140
|
-
{
|
|
141
|
-
bridge.client.sensors.getById(tempSensorID)
|
|
142
|
-
.then(sensor => {
|
|
143
|
-
var hueSwitch = new HueSwitchMessage(sensor, (universalMode == false) ? lastState : false);
|
|
144
|
-
send(hueSwitch.msg);
|
|
145
|
-
|
|
146
|
-
return true;
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
return true;
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
//
|
|
154
|
-
// CLOSE NODE / REMOVE EVENT LISTENER
|
|
155
|
-
this.on('close', function()
|
|
156
|
-
{
|
|
157
|
-
bridge.events.removeAllListeners('sensor' + config.sensorid);
|
|
158
|
-
bridge.events.removeAllListeners('sensor');
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
RED.nodes.registerType("hue-switch", HueSwitch);
|
|
163
|
-
}
|