node-red-contrib-huemagic 4.0.2 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -14
- package/examples/Hue Bridge.json +1 -1
- package/huemagic/hue-bridge-config.html +11 -4
- package/huemagic/hue-bridge-config.js +180 -154
- package/huemagic/hue-bridge.js +5 -5
- package/huemagic/hue-brightness.html +22 -8
- package/huemagic/hue-brightness.js +16 -5
- package/huemagic/hue-buttons.html +21 -7
- package/huemagic/hue-buttons.js +16 -5
- package/huemagic/hue-group.html +26 -12
- package/huemagic/hue-group.js +8 -3
- package/huemagic/hue-light.html +22 -8
- package/huemagic/hue-light.js +8 -3
- package/huemagic/hue-motion.html +22 -8
- package/huemagic/hue-motion.js +16 -5
- package/huemagic/hue-rules.html +20 -6
- package/huemagic/hue-rules.js +15 -4
- package/huemagic/hue-scene.html +20 -6
- package/huemagic/hue-scene.js +1 -1
- package/huemagic/hue-temperature.html +22 -8
- package/huemagic/hue-temperature.js +16 -5
- package/huemagic/locales/de/hue-bridge-config.html +8 -0
- package/huemagic/locales/de/hue-bridge.json +1 -1
- package/huemagic/locales/de/hue-group.html +1 -0
- package/huemagic/locales/en-US/hue-bridge-config.html +8 -0
- package/huemagic/locales/en-US/hue-bridge.html +1 -1
- package/huemagic/locales/en-US/hue-bridge.json +1 -1
- package/huemagic/locales/en-US/hue-buttons.html +1 -1
- package/huemagic/locales/en-US/hue-group.html +1 -0
- package/huemagic/locales/en-US/hue-light.html +1 -1
- package/huemagic/locales/en-US/hue-magic.html +3 -3
- package/huemagic/locales/en-US/hue-motion.html +1 -1
- package/huemagic/locales/en-US/hue-temperature.html +1 -1
- package/huemagic/utils/api.js +88 -94
- package/huemagic/utils/messages.js +134 -126
- package/package.json +2 -1
package/huemagic/hue-bridge.js
CHANGED
|
@@ -79,11 +79,11 @@ module.exports = function(RED)
|
|
|
79
79
|
|
|
80
80
|
//
|
|
81
81
|
// SUBSCRIBE TO UPDATES FROM THE BRIDGE
|
|
82
|
-
bridge.subscribe("bridge", "
|
|
82
|
+
bridge.subscribe("bridge", "globalResourceUpdates", async function(info)
|
|
83
83
|
{
|
|
84
84
|
let currentState = bridge.get(info.updatedType, info.id);
|
|
85
85
|
|
|
86
|
-
//
|
|
86
|
+
// RESOURCE FOUND?
|
|
87
87
|
if(currentState !== false)
|
|
88
88
|
{
|
|
89
89
|
// UPDATE COUNTER
|
|
@@ -138,7 +138,7 @@ module.exports = function(RED)
|
|
|
138
138
|
done = done || function() { scope.done.apply(scope,arguments); }
|
|
139
139
|
|
|
140
140
|
// SET LAST COMMAND
|
|
141
|
-
scope.lastCommand = msg;
|
|
141
|
+
scope.lastCommand = RED.util.cloneMessage(msg);
|
|
142
142
|
|
|
143
143
|
// GET BRIDGE INFORMATION
|
|
144
144
|
scope.getBridgeInformation()
|
|
@@ -171,7 +171,7 @@ module.exports = function(RED)
|
|
|
171
171
|
if(done) { done(error); }
|
|
172
172
|
});
|
|
173
173
|
}
|
|
174
|
-
// FETCH
|
|
174
|
+
// FETCH RESOURCES
|
|
175
175
|
else if(typeof msg.payload != 'undefined' && typeof msg.payload.fetch != 'undefined')
|
|
176
176
|
{
|
|
177
177
|
let fetchTypes = [];
|
|
@@ -179,7 +179,7 @@ module.exports = function(RED)
|
|
|
179
179
|
else if(typeof msg.payload.fetch == 'object') { fetchTypes = msg.payload.fetch; }
|
|
180
180
|
else { return false; }
|
|
181
181
|
|
|
182
|
-
scope.status({fill: "blue", shape: "dot", text: "hue-bridge.node.f-
|
|
182
|
+
scope.status({fill: "blue", shape: "dot", text: "hue-bridge.node.f-resources" });
|
|
183
183
|
|
|
184
184
|
// FETCH
|
|
185
185
|
bridgeInformation.results = {};
|
|
@@ -81,6 +81,19 @@
|
|
|
81
81
|
buttonIcon.removeClass("fa-pencil");
|
|
82
82
|
buttonIcon.addClass("fa-search");
|
|
83
83
|
}
|
|
84
|
+
|
|
85
|
+
function sortResourcesBy(prop, resources)
|
|
86
|
+
{
|
|
87
|
+
return resources.sort((a, b) => {
|
|
88
|
+
if ( a[prop] < b[prop] ){
|
|
89
|
+
return -1;
|
|
90
|
+
}
|
|
91
|
+
if ( a[prop] > b[prop] ){
|
|
92
|
+
return 1;
|
|
93
|
+
}
|
|
94
|
+
return 0;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
84
97
|
|
|
85
98
|
function searchAndSelect()
|
|
86
99
|
{
|
|
@@ -95,10 +108,11 @@
|
|
|
95
108
|
var notification = RED.notify(scope._("hue-brightness.config.searching"), { type: "compact", modal: true, fixed: true });
|
|
96
109
|
|
|
97
110
|
// GET THE SENSORS
|
|
98
|
-
$.get('hue/
|
|
111
|
+
$.get('hue/resources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "motion" })
|
|
99
112
|
.done( function(data) {
|
|
100
|
-
var
|
|
101
|
-
|
|
113
|
+
var allResources = JSON.parse(data);
|
|
114
|
+
allResources = sortResourcesBy('name', allResources);
|
|
115
|
+
if(allResources.length <= 0)
|
|
102
116
|
{
|
|
103
117
|
notification.close();
|
|
104
118
|
RED.notify(scope._("hue-brightness.config.none-found"), { type: "light_level" });
|
|
@@ -106,15 +120,15 @@
|
|
|
106
120
|
}
|
|
107
121
|
|
|
108
122
|
// SET OPTIONS
|
|
109
|
-
|
|
123
|
+
allResources.forEach(function(resource)
|
|
110
124
|
{
|
|
111
|
-
if(
|
|
125
|
+
if(resource.model)
|
|
112
126
|
{
|
|
113
|
-
options[
|
|
127
|
+
options[resource.id] = { value: resource.id, label: resource.name + " ("+resource.model+")" };
|
|
114
128
|
}
|
|
115
129
|
else
|
|
116
130
|
{
|
|
117
|
-
options[
|
|
131
|
+
options[resource.id] = { value: resource.id, label: resource.name };
|
|
118
132
|
}
|
|
119
133
|
});
|
|
120
134
|
|
|
@@ -194,4 +208,4 @@
|
|
|
194
208
|
}
|
|
195
209
|
}
|
|
196
210
|
});
|
|
197
|
-
</script>
|
|
211
|
+
</script>
|
|
@@ -40,7 +40,7 @@ module.exports = function(RED)
|
|
|
40
40
|
{
|
|
41
41
|
let currentState = bridge.get("light_level", info.id);
|
|
42
42
|
|
|
43
|
-
//
|
|
43
|
+
// RESOURCE FOUND?
|
|
44
44
|
if(currentState !== false)
|
|
45
45
|
{
|
|
46
46
|
// SEND MESSAGE
|
|
@@ -100,14 +100,25 @@ module.exports = function(RED)
|
|
|
100
100
|
done = done || function() { scope.done.apply(scope,arguments); }
|
|
101
101
|
|
|
102
102
|
// SET LAST COMMAND
|
|
103
|
-
scope.lastCommand = msg;
|
|
103
|
+
scope.lastCommand = RED.util.cloneMessage(msg);
|
|
104
104
|
|
|
105
105
|
// CREATE PATCH
|
|
106
106
|
let patchObject = {};
|
|
107
107
|
|
|
108
108
|
// DEFINE SENSOR ID & CURRENT STATE
|
|
109
|
-
const tempSensorID = (typeof msg.topic != 'undefined' && msg.topic
|
|
109
|
+
const tempSensorID = (!config.sensorid && typeof msg.topic != 'undefined' && bridge.validResourceID.test(msg.topic) === true) ? msg.topic : config.sensorid;
|
|
110
|
+
if(!tempSensorID)
|
|
111
|
+
{
|
|
112
|
+
scope.error("Please submit a valid sensor ID.");
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
|
|
110
116
|
let currentState = bridge.get("light_level", tempSensorID);
|
|
117
|
+
if(!currentState)
|
|
118
|
+
{
|
|
119
|
+
scope.error("The sensor in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid..");
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
111
122
|
|
|
112
123
|
// GET CURRENT STATE
|
|
113
124
|
if( (typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined') || (typeof msg.__user_inject_props__ != 'undefined' && msg.__user_inject_props__ == "status") )
|
|
@@ -129,10 +140,10 @@ module.exports = function(RED)
|
|
|
129
140
|
}
|
|
130
141
|
|
|
131
142
|
// TURN ON / OFF
|
|
132
|
-
if((msg.payload === true || msg.payload === false) && (msg.payload
|
|
143
|
+
if((msg.payload === true || msg.payload === false) && (msg.payload != currentState.payload.active))
|
|
133
144
|
{
|
|
134
145
|
// PREPARE PATCH
|
|
135
|
-
patchObject
|
|
146
|
+
patchObject["enabled"] = (msg.payload == true);
|
|
136
147
|
}
|
|
137
148
|
|
|
138
149
|
//
|
|
@@ -81,6 +81,19 @@
|
|
|
81
81
|
buttonIcon.removeClass("fa-pencil");
|
|
82
82
|
buttonIcon.addClass("fa-search");
|
|
83
83
|
}
|
|
84
|
+
|
|
85
|
+
function sortResourcesBy(prop, resources)
|
|
86
|
+
{
|
|
87
|
+
return resources.sort((a, b) => {
|
|
88
|
+
if ( a[prop] < b[prop] ){
|
|
89
|
+
return -1;
|
|
90
|
+
}
|
|
91
|
+
if ( a[prop] > b[prop] ){
|
|
92
|
+
return 1;
|
|
93
|
+
}
|
|
94
|
+
return 0;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
84
97
|
|
|
85
98
|
function searchAndSelect()
|
|
86
99
|
{
|
|
@@ -95,10 +108,11 @@
|
|
|
95
108
|
var notification = RED.notify(scope._("hue-buttons.config.searching"), { type: "compact", modal: true, fixed: true });
|
|
96
109
|
|
|
97
110
|
// GET THE SENSORS
|
|
98
|
-
$.get('hue/
|
|
111
|
+
$.get('hue/resources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "button" })
|
|
99
112
|
.done( function(data) {
|
|
100
|
-
var
|
|
101
|
-
|
|
113
|
+
var allResources = JSON.parse(data);
|
|
114
|
+
allResources = sortResourcesBy('name', allResources);
|
|
115
|
+
if(allResources.length <= 0)
|
|
102
116
|
{
|
|
103
117
|
notification.close();
|
|
104
118
|
RED.notify(scope._("hue-buttons.config.none-found"), { type: "error" });
|
|
@@ -106,15 +120,15 @@
|
|
|
106
120
|
}
|
|
107
121
|
|
|
108
122
|
// SET OPTIONS
|
|
109
|
-
|
|
123
|
+
allResources.forEach(function(resource)
|
|
110
124
|
{
|
|
111
|
-
if(
|
|
125
|
+
if(resource.model)
|
|
112
126
|
{
|
|
113
|
-
options[
|
|
127
|
+
options[resource.id] = { value: resource.id, label: resource.name + " ("+resource.model+")" };
|
|
114
128
|
}
|
|
115
129
|
else
|
|
116
130
|
{
|
|
117
|
-
options[
|
|
131
|
+
options[resource.id] = { value: resource.id, label: resource.name };
|
|
118
132
|
}
|
|
119
133
|
});
|
|
120
134
|
|
package/huemagic/hue-buttons.js
CHANGED
|
@@ -43,7 +43,7 @@ module.exports = function(RED)
|
|
|
43
43
|
{
|
|
44
44
|
let currentState = bridge.get("button", info.id);
|
|
45
45
|
|
|
46
|
-
//
|
|
46
|
+
// RESOURCE FOUND?
|
|
47
47
|
if(currentState !== false)
|
|
48
48
|
{
|
|
49
49
|
// SEND MESSAGE
|
|
@@ -102,9 +102,9 @@ module.exports = function(RED)
|
|
|
102
102
|
scope.status({fill: "grey", shape: "dot", text: "hue-buttons.node.waiting"});
|
|
103
103
|
|
|
104
104
|
// REMOVE OLD BUTTON STATES
|
|
105
|
-
for (const [oneButtonID, oneButton] of Object.entries(bridge.
|
|
105
|
+
for (const [oneButtonID, oneButton] of Object.entries(bridge.resources[config.sensorid]["services"]["button"]))
|
|
106
106
|
{
|
|
107
|
-
delete bridge.
|
|
107
|
+
delete bridge.resources[config.sensorid]["services"]["button"][oneButtonID]["button"];
|
|
108
108
|
}
|
|
109
109
|
}, 3000);
|
|
110
110
|
}
|
|
@@ -121,11 +121,22 @@ module.exports = function(RED)
|
|
|
121
121
|
done = done || function() { scope.done.apply(scope,arguments); }
|
|
122
122
|
|
|
123
123
|
// SAVE LAST COMMAND
|
|
124
|
-
scope.lastCommand = msg;
|
|
124
|
+
scope.lastCommand = RED.util.cloneMessage(msg);
|
|
125
125
|
|
|
126
126
|
// DEFINE SENSOR ID
|
|
127
|
-
const tempSensorID = (typeof msg.topic != 'undefined' && msg.topic
|
|
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
|
+
|
|
128
134
|
let currentState = bridge.get("button", tempSensorID);
|
|
135
|
+
if(!currentState)
|
|
136
|
+
{
|
|
137
|
+
scope.error("The button/switch in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid..");
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
129
140
|
|
|
130
141
|
// GET CURRENT STATE
|
|
131
142
|
if( (typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined') || (typeof msg.__user_inject_props__ != 'undefined' && msg.__user_inject_props__ == "status") )
|
package/huemagic/hue-group.html
CHANGED
|
@@ -81,6 +81,19 @@
|
|
|
81
81
|
buttonIcon.removeClass("fa-pencil");
|
|
82
82
|
buttonIcon.addClass("fa-search");
|
|
83
83
|
}
|
|
84
|
+
|
|
85
|
+
function sortResourcesBy(prop, resources)
|
|
86
|
+
{
|
|
87
|
+
return resources.sort((a, b) => {
|
|
88
|
+
if ( a[prop] < b[prop] ){
|
|
89
|
+
return -1;
|
|
90
|
+
}
|
|
91
|
+
if ( a[prop] > b[prop] ){
|
|
92
|
+
return 1;
|
|
93
|
+
}
|
|
94
|
+
return 0;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
84
97
|
|
|
85
98
|
function searchAndSelect()
|
|
86
99
|
{
|
|
@@ -95,10 +108,11 @@
|
|
|
95
108
|
var notification = RED.notify(scope._("hue-group.config.searching"), { type: "compact", modal: true, fixed: true });
|
|
96
109
|
|
|
97
110
|
// GET THE GROUPS
|
|
98
|
-
$.get('hue/
|
|
111
|
+
$.get('hue/resources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "group" })
|
|
99
112
|
.done( function(data) {
|
|
100
|
-
var
|
|
101
|
-
|
|
113
|
+
var allResources = JSON.parse(data);
|
|
114
|
+
allResources = sortResourcesBy('name', allResources);
|
|
115
|
+
if(allResources.length <= 0)
|
|
102
116
|
{
|
|
103
117
|
notification.close();
|
|
104
118
|
RED.notify(scope._("hue-group.config.none-found"), { type: "error" });
|
|
@@ -106,25 +120,25 @@
|
|
|
106
120
|
}
|
|
107
121
|
|
|
108
122
|
// SET GROUPS AS OPTIONS
|
|
109
|
-
|
|
123
|
+
allResources.forEach(function(resource)
|
|
110
124
|
{
|
|
111
|
-
if(!
|
|
125
|
+
if(!resource.name) // ALL SPECIAL
|
|
112
126
|
{
|
|
113
|
-
options[
|
|
127
|
+
options[resource.id] = { value: resource.id, label: "● "+scope._("hue-group.config.all") };
|
|
114
128
|
}
|
|
115
129
|
});
|
|
116
130
|
|
|
117
|
-
|
|
131
|
+
allResources.forEach(function(resource)
|
|
118
132
|
{
|
|
119
|
-
if(
|
|
133
|
+
if(resource.name) // REGULAR GROUPS
|
|
120
134
|
{
|
|
121
|
-
if(
|
|
135
|
+
if(resource.model)
|
|
122
136
|
{
|
|
123
|
-
options[
|
|
137
|
+
options[resource.id] = { value: resource.id, label: resource.name + " ("+resource.model+")" };
|
|
124
138
|
}
|
|
125
139
|
else
|
|
126
140
|
{
|
|
127
|
-
options[
|
|
141
|
+
options[resource.id] = { value: resource.id, label: resource.name };
|
|
128
142
|
}
|
|
129
143
|
}
|
|
130
144
|
});
|
|
@@ -205,4 +219,4 @@
|
|
|
205
219
|
}
|
|
206
220
|
}
|
|
207
221
|
});
|
|
208
|
-
</script>
|
|
222
|
+
</script>
|
package/huemagic/hue-group.js
CHANGED
|
@@ -50,7 +50,7 @@ module.exports = function(RED)
|
|
|
50
50
|
{
|
|
51
51
|
let currentState = bridge.get("group", info.id, { colornames: config.colornamer ? true : false });
|
|
52
52
|
|
|
53
|
-
//
|
|
53
|
+
// RESOURCE FOUND?
|
|
54
54
|
if(currentState !== false)
|
|
55
55
|
{
|
|
56
56
|
// NOT IN UNIVERAL MODE? -> CHANGE UI STATES
|
|
@@ -102,14 +102,19 @@ module.exports = function(RED)
|
|
|
102
102
|
send = send || function() { scope.send.apply(scope,arguments); }
|
|
103
103
|
|
|
104
104
|
// SAVE LAST COMMAND
|
|
105
|
-
scope.lastCommand = msg;
|
|
105
|
+
scope.lastCommand = RED.util.cloneMessage(msg);
|
|
106
106
|
|
|
107
107
|
// CREATE PATCH
|
|
108
108
|
let patchObject = {};
|
|
109
109
|
|
|
110
110
|
// DEFINE SENSOR ID & CURRENT STATE
|
|
111
|
-
const tempGroupID = (typeof msg.topic != 'undefined' && msg.topic
|
|
111
|
+
const tempGroupID = (!config.groupid && typeof msg.topic != 'undefined' && bridge.validResourceID.test(msg.topic) === true) ? msg.topic : config.groupid;
|
|
112
112
|
let currentState = bridge.get("group", tempGroupID, { colornames: config.colornamer ? true : false });
|
|
113
|
+
if(!currentState)
|
|
114
|
+
{
|
|
115
|
+
scope.error("The group in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid..");
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
113
118
|
|
|
114
119
|
// CHECK IF LIGHT ID IS SET
|
|
115
120
|
if(!tempGroupID)
|
package/huemagic/hue-light.html
CHANGED
|
@@ -88,6 +88,19 @@
|
|
|
88
88
|
buttonIcon.removeClass("fa-pencil");
|
|
89
89
|
buttonIcon.addClass("fa-search");
|
|
90
90
|
}
|
|
91
|
+
|
|
92
|
+
function sortResourcesBy(prop, resources)
|
|
93
|
+
{
|
|
94
|
+
return resources.sort((a, b) => {
|
|
95
|
+
if ( a[prop] < b[prop] ){
|
|
96
|
+
return -1;
|
|
97
|
+
}
|
|
98
|
+
if ( a[prop] > b[prop] ){
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
return 0;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
91
104
|
|
|
92
105
|
function searchAndSelect()
|
|
93
106
|
{
|
|
@@ -102,10 +115,11 @@
|
|
|
102
115
|
var notification = RED.notify(scope._("hue-light.config.searching"), { type: "compact", modal: true, fixed: true });
|
|
103
116
|
|
|
104
117
|
// GET THE LIGHTS
|
|
105
|
-
$.get('hue/
|
|
118
|
+
$.get('hue/resources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "light" })
|
|
106
119
|
.done( function(data) {
|
|
107
|
-
var
|
|
108
|
-
|
|
120
|
+
var allResources = JSON.parse(data);
|
|
121
|
+
allResources = sortResourcesBy('name', allResources);
|
|
122
|
+
if(allResources.length <= 0)
|
|
109
123
|
{
|
|
110
124
|
notification.close();
|
|
111
125
|
RED.notify(scope._("hue-light.config.none-found"), { type: "error" });
|
|
@@ -113,15 +127,15 @@
|
|
|
113
127
|
}
|
|
114
128
|
|
|
115
129
|
// SET OPTIONS
|
|
116
|
-
|
|
130
|
+
allResources.forEach(function(resource)
|
|
117
131
|
{
|
|
118
|
-
if(
|
|
132
|
+
if(resource.model)
|
|
119
133
|
{
|
|
120
|
-
options[
|
|
134
|
+
options[resource.id] = { value: resource.id, label: resource.name + " ("+resource.model+")" };
|
|
121
135
|
}
|
|
122
136
|
else
|
|
123
137
|
{
|
|
124
|
-
options[
|
|
138
|
+
options[resource.id] = { value: resource.id, label: resource.name };
|
|
125
139
|
}
|
|
126
140
|
});
|
|
127
141
|
|
|
@@ -201,4 +215,4 @@
|
|
|
201
215
|
}
|
|
202
216
|
}
|
|
203
217
|
});
|
|
204
|
-
</script>
|
|
218
|
+
</script>
|
package/huemagic/hue-light.js
CHANGED
|
@@ -47,7 +47,7 @@ module.exports = function(RED)
|
|
|
47
47
|
{
|
|
48
48
|
let currentState = bridge.get("light", info.id, { colornames: config.colornamer ? true : false });
|
|
49
49
|
|
|
50
|
-
//
|
|
50
|
+
// RESOURCE FOUND?
|
|
51
51
|
if(currentState !== false)
|
|
52
52
|
{
|
|
53
53
|
// SEND MESSAGE
|
|
@@ -115,14 +115,19 @@ module.exports = function(RED)
|
|
|
115
115
|
done = done || function() { scope.done.apply(scope,arguments); }
|
|
116
116
|
|
|
117
117
|
// SAVE LAST COMMAND
|
|
118
|
-
scope.lastCommand = msg;
|
|
118
|
+
scope.lastCommand = RED.util.cloneMessage(msg);
|
|
119
119
|
|
|
120
120
|
// CREATE PATCH
|
|
121
121
|
let patchObject = {};
|
|
122
122
|
|
|
123
123
|
// DEFINE SENSOR ID & CURRENT STATE
|
|
124
|
-
const tempLightID = (typeof msg.topic != 'undefined' && msg.topic
|
|
124
|
+
const tempLightID = (!config.lightid && typeof msg.topic != 'undefined' && bridge.validResourceID.test(msg.topic) === true) ? msg.topic : config.lightid;
|
|
125
125
|
let currentState = bridge.get("light", tempLightID, { colornames: config.colornamer ? true : false });
|
|
126
|
+
if(!currentState)
|
|
127
|
+
{
|
|
128
|
+
scope.error("The light in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid..");
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
126
131
|
|
|
127
132
|
// CHECK IF LIGHT ID IS SET
|
|
128
133
|
if(!tempLightID)
|
package/huemagic/hue-motion.html
CHANGED
|
@@ -81,6 +81,19 @@
|
|
|
81
81
|
buttonIcon.removeClass("fa-pencil");
|
|
82
82
|
buttonIcon.addClass("fa-search");
|
|
83
83
|
}
|
|
84
|
+
|
|
85
|
+
function sortResourcesBy(prop, resources)
|
|
86
|
+
{
|
|
87
|
+
return resources.sort((a, b) => {
|
|
88
|
+
if ( a[prop] < b[prop] ){
|
|
89
|
+
return -1;
|
|
90
|
+
}
|
|
91
|
+
if ( a[prop] > b[prop] ){
|
|
92
|
+
return 1;
|
|
93
|
+
}
|
|
94
|
+
return 0;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
84
97
|
|
|
85
98
|
function searchAndSelect()
|
|
86
99
|
{
|
|
@@ -95,10 +108,11 @@
|
|
|
95
108
|
var notification = RED.notify(scope._("hue-motion.config.searching"), { type: "compact", modal: true, fixed: true });
|
|
96
109
|
|
|
97
110
|
// GET THE SENSORS
|
|
98
|
-
$.get('hue/
|
|
111
|
+
$.get('hue/resources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "motion" })
|
|
99
112
|
.done( function(data) {
|
|
100
|
-
var
|
|
101
|
-
|
|
113
|
+
var allResources = JSON.parse(data);
|
|
114
|
+
allResources = sortResourcesBy('name', allResources);
|
|
115
|
+
if(allResources.length <= 0)
|
|
102
116
|
{
|
|
103
117
|
notification.close();
|
|
104
118
|
RED.notify(scope._("hue-motion.config.none-found"), { type: "error" });
|
|
@@ -106,15 +120,15 @@
|
|
|
106
120
|
}
|
|
107
121
|
|
|
108
122
|
// SET OPTIONS
|
|
109
|
-
|
|
123
|
+
allResources.forEach(function(resource)
|
|
110
124
|
{
|
|
111
|
-
if(
|
|
125
|
+
if(resource.model)
|
|
112
126
|
{
|
|
113
|
-
options[
|
|
127
|
+
options[resource.id] = { value: resource.id, label: resource.name + " ("+resource.model+")" };
|
|
114
128
|
}
|
|
115
129
|
else
|
|
116
130
|
{
|
|
117
|
-
options[
|
|
131
|
+
options[resource.id] = { value: resource.id, label: resource.name };
|
|
118
132
|
}
|
|
119
133
|
});
|
|
120
134
|
|
|
@@ -194,4 +208,4 @@
|
|
|
194
208
|
}
|
|
195
209
|
}
|
|
196
210
|
});
|
|
197
|
-
</script>
|
|
211
|
+
</script>
|
package/huemagic/hue-motion.js
CHANGED
|
@@ -40,7 +40,7 @@ module.exports = function(RED)
|
|
|
40
40
|
{
|
|
41
41
|
let currentState = bridge.get("motion", info.id);
|
|
42
42
|
|
|
43
|
-
//
|
|
43
|
+
// RESOURCE FOUND?
|
|
44
44
|
if(currentState !== false)
|
|
45
45
|
{
|
|
46
46
|
// SEND MESSAGE
|
|
@@ -94,14 +94,25 @@ module.exports = function(RED)
|
|
|
94
94
|
done = done || function() { scope.done.apply(scope,arguments); }
|
|
95
95
|
|
|
96
96
|
// SAVE LAST COMMAND
|
|
97
|
-
scope.lastCommand = msg;
|
|
97
|
+
scope.lastCommand = RED.util.cloneMessage(msg);
|
|
98
98
|
|
|
99
99
|
// CREATE PATCH
|
|
100
100
|
let patchObject = {};
|
|
101
101
|
|
|
102
102
|
// DEFINE SENSOR ID & CURRENT STATE
|
|
103
|
-
const tempSensorID = (typeof msg.topic != 'undefined' && msg.topic
|
|
103
|
+
const tempSensorID = (!config.sensorid && typeof msg.topic != 'undefined' && bridge.validResourceID.test(msg.topic) === true) ? msg.topic : config.sensorid;
|
|
104
|
+
if(!tempSensorID)
|
|
105
|
+
{
|
|
106
|
+
scope.error("Please submit a valid sensor ID.");
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
104
110
|
let currentState = bridge.get("motion", tempSensorID);
|
|
111
|
+
if(!currentState)
|
|
112
|
+
{
|
|
113
|
+
scope.error("The sensor in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid..");
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
105
116
|
|
|
106
117
|
// GET CURRENT STATE
|
|
107
118
|
if( (typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined') || (typeof msg.__user_inject_props__ != 'undefined' && msg.__user_inject_props__ == "status") )
|
|
@@ -123,10 +134,10 @@ module.exports = function(RED)
|
|
|
123
134
|
}
|
|
124
135
|
|
|
125
136
|
// TURN ON / OFF
|
|
126
|
-
if((msg.payload === true || msg.payload === false) && (msg.payload
|
|
137
|
+
if((msg.payload === true || msg.payload === false) && (msg.payload != currentState.payload.active))
|
|
127
138
|
{
|
|
128
139
|
// PREPARE PATCH
|
|
129
|
-
patchObject
|
|
140
|
+
patchObject["enabled"] = (msg.payload == true);
|
|
130
141
|
}
|
|
131
142
|
|
|
132
143
|
//
|
package/huemagic/hue-rules.html
CHANGED
|
@@ -81,6 +81,19 @@
|
|
|
81
81
|
buttonIcon.removeClass("fa-pencil");
|
|
82
82
|
buttonIcon.addClass("fa-search");
|
|
83
83
|
}
|
|
84
|
+
|
|
85
|
+
function sortResourcesBy(prop, resources)
|
|
86
|
+
{
|
|
87
|
+
return resources.sort((a, b) => {
|
|
88
|
+
if ( a[prop] < b[prop] ){
|
|
89
|
+
return -1;
|
|
90
|
+
}
|
|
91
|
+
if ( a[prop] > b[prop] ){
|
|
92
|
+
return 1;
|
|
93
|
+
}
|
|
94
|
+
return 0;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
84
97
|
|
|
85
98
|
function searchAndSelect()
|
|
86
99
|
{
|
|
@@ -95,10 +108,11 @@
|
|
|
95
108
|
var notification = RED.notify(scope._("hue-rules.config.searching"), { type: "compact", modal: true, fixed: true });
|
|
96
109
|
|
|
97
110
|
// GET THE SENSORS
|
|
98
|
-
$.get('hue/
|
|
111
|
+
$.get('hue/resources', { bridge: bridgeConfig.bridge, key: bridgeConfig.key, type: "rule" })
|
|
99
112
|
.done( function(data) {
|
|
100
|
-
var
|
|
101
|
-
|
|
113
|
+
var allResources = JSON.parse(data);
|
|
114
|
+
allResources = sortResourcesBy('name', allResources);
|
|
115
|
+
if(allResources.length <= 0)
|
|
102
116
|
{
|
|
103
117
|
notification.close();
|
|
104
118
|
RED.notify(scope._("hue-rules.config.none-found"), { type: "error" });
|
|
@@ -106,9 +120,9 @@
|
|
|
106
120
|
}
|
|
107
121
|
|
|
108
122
|
// SET OPTIONS
|
|
109
|
-
|
|
123
|
+
allResources.forEach(function(resource)
|
|
110
124
|
{
|
|
111
|
-
options[
|
|
125
|
+
options[resource.id] = { value: resource.id, label: resource.name };
|
|
112
126
|
});
|
|
113
127
|
|
|
114
128
|
// SELECT CURRENT VALUE
|
|
@@ -187,4 +201,4 @@
|
|
|
187
201
|
}
|
|
188
202
|
}
|
|
189
203
|
});
|
|
190
|
-
</script>
|
|
204
|
+
</script>
|
package/huemagic/hue-rules.js
CHANGED
|
@@ -40,7 +40,7 @@ module.exports = function(RED)
|
|
|
40
40
|
{
|
|
41
41
|
let currentState = bridge.get("rule", info.id);
|
|
42
42
|
|
|
43
|
-
//
|
|
43
|
+
// RESOURCE FOUND?
|
|
44
44
|
if(currentState !== false)
|
|
45
45
|
{
|
|
46
46
|
// NOT IN UNIVERAL MODE? -> CHANGE UI STATES
|
|
@@ -84,14 +84,25 @@ module.exports = function(RED)
|
|
|
84
84
|
done = done || function() { scope.done.apply(scope,arguments); }
|
|
85
85
|
|
|
86
86
|
// SAVE LAST COMMAND
|
|
87
|
-
scope.lastCommand = msg;
|
|
87
|
+
scope.lastCommand = RED.util.cloneMessage(msg);
|
|
88
88
|
|
|
89
89
|
// CREATE PATCH
|
|
90
90
|
let patchObject = {};
|
|
91
91
|
|
|
92
92
|
// DEFINE SENSOR ID & CURRENT STATE
|
|
93
|
-
const tempRuleID = (typeof msg.topic != 'undefined' && msg.topic
|
|
93
|
+
const tempRuleID = (!config.ruleid && typeof msg.topic != 'undefined' && isNaN(msg.topic) == false) ? msg.topic : config.ruleid;
|
|
94
|
+
if(!tempRuleID)
|
|
95
|
+
{
|
|
96
|
+
scope.error("Please submit a valid rule ID.");
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
94
100
|
let currentState = bridge.get("rule", "rule_" + tempRuleID);
|
|
101
|
+
if(!currentState)
|
|
102
|
+
{
|
|
103
|
+
scope.error("The rule in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid..");
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
95
106
|
|
|
96
107
|
// CONTROL RULE
|
|
97
108
|
if(msg.payload === true || msg.payload === false)
|
|
@@ -100,7 +111,7 @@ module.exports = function(RED)
|
|
|
100
111
|
patchObject["status"] = (msg.payload == true) ? 'enabled' : 'disabled';
|
|
101
112
|
|
|
102
113
|
// PATCH!
|
|
103
|
-
bridge.patch("rules", "/rules/"+
|
|
114
|
+
bridge.patch("rules", "/rules/"+tempRuleID, patchObject, 1)
|
|
104
115
|
.then(function(response) { bridge.refetchRule(tempRuleID); })
|
|
105
116
|
.catch(function(errors) { scope.error(errors); });
|
|
106
117
|
|