node-red-contrib-homebridge-automation 0.1.12-beta.27 → 0.1.12-beta.28
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/package.json +1 -1
- package/src/HAP-NodeRed.js +0 -24
- package/src/HapDeviceRoutes.js +2 -2
- package/src/hbBaseNode.js +14 -110
- package/src/hbControlNode.js +1 -2
- package/src/hbResumeNode.js +13 -17
- package/src/hbStatusNode.js +1 -2
- package/test/node-red/flows.json +56 -62
package/package.json
CHANGED
package/src/HAP-NodeRed.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
var debug = require('debug')('hapNodeRed');
|
|
2
2
|
|
|
3
|
-
// var register = require('./lib/register.js');
|
|
4
|
-
|
|
5
3
|
const HBConfigNode = require('./hbConfigNode.js');
|
|
6
4
|
const HbEventNode = require('./hbEventNode'); // Import the class
|
|
7
5
|
const HbResumeNode = require('./hbResumeNode'); // Import the class
|
|
@@ -13,13 +11,6 @@ const HapDeviceRoutes = require('./HapDeviceRoutes');
|
|
|
13
11
|
module.exports = function (RED) {
|
|
14
12
|
var hbDevices;
|
|
15
13
|
|
|
16
|
-
/**
|
|
17
|
-
* hbConf - Configuration
|
|
18
|
-
*
|
|
19
|
-
* @param {type} n description
|
|
20
|
-
* @return {type} description
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
14
|
class hbConfigNode extends HBConfigNode {
|
|
24
15
|
constructor(config) {
|
|
25
16
|
debug('hbConfigNode', config);
|
|
@@ -27,7 +18,6 @@ module.exports = function (RED) {
|
|
|
27
18
|
}
|
|
28
19
|
}
|
|
29
20
|
|
|
30
|
-
// console.log('Registering node types', "hb-conf", hbConfigNode);
|
|
31
21
|
RED.nodes.registerType("hb-conf", hbConfigNode, {
|
|
32
22
|
credentials: {
|
|
33
23
|
password: {
|
|
@@ -36,11 +26,6 @@ module.exports = function (RED) {
|
|
|
36
26
|
}
|
|
37
27
|
});
|
|
38
28
|
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* hbEventNode - description
|
|
42
|
-
* @param {*} n
|
|
43
|
-
*/
|
|
44
29
|
class hbEventNode extends HbEventNode {
|
|
45
30
|
constructor(config) {
|
|
46
31
|
debug('hbEventNode', config);
|
|
@@ -50,9 +35,6 @@ module.exports = function (RED) {
|
|
|
50
35
|
|
|
51
36
|
RED.nodes.registerType("hb-event", hbEventNode);
|
|
52
37
|
|
|
53
|
-
/**
|
|
54
|
-
* hbResumeNode - description
|
|
55
|
-
*/
|
|
56
38
|
class hbResumeNode extends HbResumeNode {
|
|
57
39
|
constructor(config) {
|
|
58
40
|
debug('hbResumeNode', config);
|
|
@@ -71,12 +53,6 @@ module.exports = function (RED) {
|
|
|
71
53
|
|
|
72
54
|
RED.nodes.registerType("hb-control", hbControlNode);
|
|
73
55
|
|
|
74
|
-
/**
|
|
75
|
-
* hbStatus - description
|
|
76
|
-
*
|
|
77
|
-
* @param {type} n description
|
|
78
|
-
* @return {type} description
|
|
79
|
-
*/
|
|
80
56
|
class hbStatusNode extends HbStatusNode {
|
|
81
57
|
constructor(config) {
|
|
82
58
|
debug('hbStatusNode', config);
|
package/src/HapDeviceRoutes.js
CHANGED
|
@@ -33,7 +33,7 @@ class HapDeviceRoutes {
|
|
|
33
33
|
getEvDeviceById(req, res) {
|
|
34
34
|
debug('req', req.params.id);
|
|
35
35
|
var evDevices = this.RED.nodes.getNode(req.params.id).evDevices;
|
|
36
|
-
debug('hbDevices', evDevices);
|
|
36
|
+
// debug('hbDevices', evDevices);
|
|
37
37
|
debug("evDevices", evDevices.length);
|
|
38
38
|
if (evDevices) {
|
|
39
39
|
res.send(evDevices);
|
|
@@ -76,7 +76,7 @@ class HapDeviceRoutes {
|
|
|
76
76
|
|
|
77
77
|
// GET /hap-device/ctDevices/
|
|
78
78
|
getCtDevices(req, res) {
|
|
79
|
-
debug("ctDevices", this.hbDevices.toList({ perms: 'pw' }).length);
|
|
79
|
+
// debug("ctDevices", this.hbDevices.toList({ perms: 'pw' }).length);
|
|
80
80
|
if (this.hbDevices) {
|
|
81
81
|
res.send(this.hbDevices.toList({ perms: 'pw' }));
|
|
82
82
|
} else {
|
package/src/hbBaseNode.js
CHANGED
|
@@ -58,116 +58,20 @@ class HbBaseNode {
|
|
|
58
58
|
done();
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
callback();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
_convertHBcharacteristicToNode(hbMessage, node) {
|
|
79
|
-
let payload = {};
|
|
80
|
-
if (!hbMessage.payload) {
|
|
81
|
-
const device = hbDevices.findDevice(node.device);
|
|
82
|
-
if (device) {
|
|
83
|
-
hbMessage.forEach(characteristic => {
|
|
84
|
-
const charKey = `${characteristic.aid}.${characteristic.iid}`;
|
|
85
|
-
if (device.characteristics[charKey]) {
|
|
86
|
-
payload[device.characteristics[charKey].characteristic] = characteristic.value;
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
} else {
|
|
91
|
-
payload = hbMessage.payload;
|
|
92
|
-
}
|
|
93
|
-
return payload;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
_createControlMessage(payload, node, device) {
|
|
97
|
-
const response = [];
|
|
98
|
-
for (const key in payload) {
|
|
99
|
-
const characteristic = this._getKey(device.characteristics, key);
|
|
100
|
-
if (characteristic) {
|
|
101
|
-
response.push({
|
|
102
|
-
aid: device.aid,
|
|
103
|
-
iid: characteristic.iid,
|
|
104
|
-
value: payload[key],
|
|
105
|
-
});
|
|
106
|
-
} else {
|
|
107
|
-
this.warn(`Invalid characteristic: '${key}'. Available: ${device.descriptions}`);
|
|
108
|
-
node.status({ text: `Invalid characteristic: ${key}`, shape: 'ring', fill: 'yellow' });
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return { characteristics: response };
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async _status(nrDevice, node, perms) {
|
|
115
|
-
try {
|
|
116
|
-
const device = hbDevices.findDevice(node.device, perms);
|
|
117
|
-
if (!device) throw new Error(`Device not found: ${nrDevice}`);
|
|
118
|
-
|
|
119
|
-
const message = device.type === "00000110" || device.type === "00000111"
|
|
120
|
-
? { "resource-type": "image", "image-width": 1920, "image-height": 1080 }
|
|
121
|
-
: `?id=${device.getCharacteristics}`;
|
|
122
|
-
|
|
123
|
-
const status = device.type === "00000110" || device.type === "00000111"
|
|
124
|
-
? await this.HAPresourceByDeviceIDAsync(device.id, JSON.stringify(message))
|
|
125
|
-
: await this.HAPstatusByDeviceIDAsync(device.id, message);
|
|
126
|
-
|
|
127
|
-
node.status({ text: 'Success', shape: 'dot', fill: 'green' });
|
|
128
|
-
return device.type === "00000110" || device.type === "00000111"
|
|
129
|
-
? { characteristics: { payload: this.btoa(status) } }
|
|
130
|
-
: status;
|
|
131
|
-
} catch (err) {
|
|
132
|
-
debug("Error in _status:", err);
|
|
133
|
-
node.status({ text: 'Error retrieving status', shape: 'ring', fill: 'red' });
|
|
134
|
-
throw err;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
async _register(node) {
|
|
139
|
-
try {
|
|
140
|
-
const device = hbDevices.findDevice(node.device, { perms: 'ev' });
|
|
141
|
-
if (device) {
|
|
142
|
-
const message = { characteristics: device.eventRegisters };
|
|
143
|
-
await hapEventByDeviceIDAsync(device.id, JSON.stringify(message));
|
|
144
|
-
}
|
|
145
|
-
} catch (err) {
|
|
146
|
-
debug("Error in _register:", err);
|
|
147
|
-
node.status({ text: 'Register error', shape: 'ring', fill: 'red' });
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
_getKey(obj, value) {
|
|
152
|
-
return Object.values(obj).find(char => char.characteristic.toLowerCase() === value.toLowerCase()) || null;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
btoa(str) {
|
|
156
|
-
return Buffer.from(str.toString(), 'binary').toString('base64');
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
async HAPresourceByDeviceIDAsync(deviceId, message) {
|
|
160
|
-
return new Promise((resolve, reject) => {
|
|
161
|
-
homebridge.HAPresourceByDeviceID(deviceId, message, (err, status) => err ? reject(err) : resolve(status));
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
async HAPstatusByDeviceIDAsync(deviceId, message) {
|
|
166
|
-
return new Promise((resolve, reject) => {
|
|
167
|
-
homebridge.HAPstatusByDeviceID(deviceId, message, (err, status) => err ? reject(err) : resolve(status));
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
*/
|
|
61
|
+
/**
|
|
62
|
+
*
|
|
63
|
+
* @param {*} warning - Message to log and display in debug panel
|
|
64
|
+
* @param {*} statusText - Message to display under Node ( If not present, uses warning message text)
|
|
65
|
+
*/
|
|
66
|
+
handleError(warning, statusText) {
|
|
67
|
+
this.warn(warning);
|
|
68
|
+
this.status({
|
|
69
|
+
text: (statusText ? statusText : warning),
|
|
70
|
+
shape: 'ring',
|
|
71
|
+
fill: 'red',
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
171
75
|
}
|
|
172
76
|
|
|
173
77
|
module.exports = HbBaseNode;
|
package/src/hbControlNode.js
CHANGED
|
@@ -9,8 +9,7 @@ class HbControlNode extends hbBaseNode {
|
|
|
9
9
|
async handleInput(message, send) {
|
|
10
10
|
debug('handleInput', message.payload, this.name);
|
|
11
11
|
if (!this.hbDevice) {
|
|
12
|
-
this.
|
|
13
|
-
this.status({ text: 'HB not initialized', shape: 'ring', fill: 'red' });
|
|
12
|
+
this.handleError('HB not initialized');
|
|
14
13
|
return;
|
|
15
14
|
}
|
|
16
15
|
|
package/src/hbResumeNode.js
CHANGED
|
@@ -6,30 +6,24 @@ class HbResumeNode extends HbBaseNode {
|
|
|
6
6
|
super(config, RED);
|
|
7
7
|
|
|
8
8
|
this.storedState = null;
|
|
9
|
-
|
|
10
|
-
// Set up input and command handlers
|
|
11
|
-
// this.on('input', this.handleInput.bind(this));
|
|
12
|
-
this.command = this.handleCommand.bind(this);
|
|
13
|
-
|
|
14
|
-
// Handle device registration
|
|
15
|
-
debug('hbResume - hbConfigNode', this.hbConfigNode);
|
|
16
9
|
}
|
|
17
10
|
|
|
18
11
|
handleInput(message, send) {
|
|
19
12
|
debug('handleInput', message.payload, this.name);
|
|
20
13
|
|
|
21
14
|
if (!this.hbDevice) {
|
|
22
|
-
this.
|
|
23
|
-
this.status({ text: 'HB not initialized', shape: 'ring', fill: 'red' });
|
|
15
|
+
this.handleError('HB not initialized');
|
|
24
16
|
return;
|
|
25
17
|
}
|
|
26
18
|
|
|
27
|
-
if (typeof message.payload !== 'object') {
|
|
19
|
+
if (typeof message.payload !== 'object' || typeof message.payload.On !== 'boolean') {
|
|
28
20
|
const validNames = Object.keys(this.hbDevice.values)
|
|
29
21
|
.filter(key => key !== 'ConfiguredName')
|
|
30
22
|
.join(', ');
|
|
31
|
-
this.
|
|
32
|
-
|
|
23
|
+
this.handleError(
|
|
24
|
+
`Invalid payload. Expected: {"On": false, "Brightness": 0}. Valid values: ${validNames}`,
|
|
25
|
+
'Invalid payload'
|
|
26
|
+
);
|
|
33
27
|
return;
|
|
34
28
|
}
|
|
35
29
|
|
|
@@ -37,18 +31,20 @@ class HbResumeNode extends HbBaseNode {
|
|
|
37
31
|
// if off, if storedState, then send stored state else passthru
|
|
38
32
|
|
|
39
33
|
if (message.payload.On) {
|
|
40
|
-
this.storedState = this.hbDevice.values;
|
|
41
|
-
debug('Storing', this.storedState);
|
|
42
|
-
} else if (
|
|
43
|
-
debug('Restoring', this.storedState)
|
|
44
|
-
message.payload = { ...
|
|
34
|
+
this.storedState = JSON.parse(JSON.stringify(this.hbDevice.values));
|
|
35
|
+
debug('Storing state', this.storedState);
|
|
36
|
+
} else if (this.storedState) {
|
|
37
|
+
debug('Restoring state', this.storedState);
|
|
38
|
+
message.payload = { ...this.storedState, ...message.payload };
|
|
45
39
|
this.storedState = null;
|
|
46
40
|
}
|
|
41
|
+
|
|
47
42
|
this.status({
|
|
48
43
|
text: JSON.stringify(message.payload),
|
|
49
44
|
shape: 'dot',
|
|
50
45
|
fill: 'green',
|
|
51
46
|
});
|
|
47
|
+
|
|
52
48
|
send(message);
|
|
53
49
|
}
|
|
54
50
|
|
package/src/hbStatusNode.js
CHANGED
|
@@ -10,8 +10,7 @@ class HbStatusNode extends HbBaseNode {
|
|
|
10
10
|
debug('handleInput', message.payload, this.name);
|
|
11
11
|
|
|
12
12
|
if (!this.hbDevice) {
|
|
13
|
-
this.
|
|
14
|
-
this.status({ text: 'HB not initialized', shape: 'ring', fill: 'red' });
|
|
13
|
+
this.handleError('HB not initialized');
|
|
15
14
|
return;
|
|
16
15
|
}
|
|
17
16
|
|
package/test/node-red/flows.json
CHANGED
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"targetType": "full",
|
|
27
27
|
"statusVal": "payload",
|
|
28
28
|
"statusType": "auto",
|
|
29
|
-
"x":
|
|
30
|
-
"y":
|
|
29
|
+
"x": 820,
|
|
30
|
+
"y": 40,
|
|
31
31
|
"wires": []
|
|
32
32
|
},
|
|
33
33
|
{
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"targetType": "full",
|
|
44
44
|
"statusVal": "payload",
|
|
45
45
|
"statusType": "auto",
|
|
46
|
-
"x":
|
|
47
|
-
"y":
|
|
46
|
+
"x": 820,
|
|
47
|
+
"y": 100,
|
|
48
48
|
"wires": []
|
|
49
49
|
},
|
|
50
50
|
{
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"topic": "",
|
|
69
69
|
"payload": "",
|
|
70
70
|
"payloadType": "date",
|
|
71
|
-
"x":
|
|
72
|
-
"y":
|
|
71
|
+
"x": 270,
|
|
72
|
+
"y": 40,
|
|
73
73
|
"wires": [
|
|
74
74
|
[
|
|
75
75
|
"3d7babac3a298e60"
|
|
@@ -86,8 +86,8 @@
|
|
|
86
86
|
"Service": "Lightbulb",
|
|
87
87
|
"device": "homebridge1C:22:3D:E3:CF:34TasmotaWest Bedroom00000043",
|
|
88
88
|
"conf": "557aec8e8c47e61e",
|
|
89
|
-
"x":
|
|
90
|
-
"y":
|
|
89
|
+
"x": 500,
|
|
90
|
+
"y": 40,
|
|
91
91
|
"wires": [
|
|
92
92
|
[
|
|
93
93
|
"902c5887b6877df6"
|
|
@@ -104,8 +104,8 @@
|
|
|
104
104
|
"Service": "Lightbulb",
|
|
105
105
|
"device": "homebridge1C:22:3D:E3:CF:34TasmotaWest Bedroom00000043",
|
|
106
106
|
"conf": "557aec8e8c47e61e",
|
|
107
|
-
"x":
|
|
108
|
-
"y":
|
|
107
|
+
"x": 500,
|
|
108
|
+
"y": 160,
|
|
109
109
|
"wires": [
|
|
110
110
|
[
|
|
111
111
|
"1093ab38b01fd39f"
|
|
@@ -125,8 +125,8 @@
|
|
|
125
125
|
"targetType": "msg",
|
|
126
126
|
"statusVal": "payload",
|
|
127
127
|
"statusType": "auto",
|
|
128
|
-
"x":
|
|
129
|
-
"y":
|
|
128
|
+
"x": 820,
|
|
129
|
+
"y": 160,
|
|
130
130
|
"wires": []
|
|
131
131
|
},
|
|
132
132
|
{
|
|
@@ -140,37 +140,10 @@
|
|
|
140
140
|
"device": "homebridge1C:22:3D:E3:CF:34TasmotaWest Bedroom Fan00000040",
|
|
141
141
|
"conf": "557aec8e8c47e61e",
|
|
142
142
|
"outputs": 0,
|
|
143
|
-
"x":
|
|
144
|
-
"y":
|
|
143
|
+
"x": 510,
|
|
144
|
+
"y": 220,
|
|
145
145
|
"wires": []
|
|
146
146
|
},
|
|
147
|
-
{
|
|
148
|
-
"id": "d9f8181e9e6b3cfd",
|
|
149
|
-
"type": "inject",
|
|
150
|
-
"z": "caef1e7b5b399e80",
|
|
151
|
-
"name": "",
|
|
152
|
-
"props": [
|
|
153
|
-
{
|
|
154
|
-
"p": "payload"
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
"p": "topic",
|
|
158
|
-
"vt": "str"
|
|
159
|
-
}
|
|
160
|
-
],
|
|
161
|
-
"repeat": "60",
|
|
162
|
-
"crontab": "",
|
|
163
|
-
"once": true,
|
|
164
|
-
"onceDelay": "60",
|
|
165
|
-
"topic": "",
|
|
166
|
-
"payload": "",
|
|
167
|
-
"payloadType": "date",
|
|
168
|
-
"x": 210,
|
|
169
|
-
"y": 460,
|
|
170
|
-
"wires": [
|
|
171
|
-
[]
|
|
172
|
-
]
|
|
173
|
-
},
|
|
174
147
|
{
|
|
175
148
|
"id": "6703815a8874b156",
|
|
176
149
|
"type": "hb-control",
|
|
@@ -181,10 +154,14 @@
|
|
|
181
154
|
"Service": "Lightbulb",
|
|
182
155
|
"device": "homebridge1C:22:3D:E3:CF:34TasmotaWest Bedroom00000043",
|
|
183
156
|
"conf": "557aec8e8c47e61e",
|
|
184
|
-
"outputs":
|
|
185
|
-
"x":
|
|
186
|
-
"y":
|
|
187
|
-
"wires": [
|
|
157
|
+
"outputs": 1,
|
|
158
|
+
"x": 500,
|
|
159
|
+
"y": 300,
|
|
160
|
+
"wires": [
|
|
161
|
+
[
|
|
162
|
+
"f194fc4bcb1997a9"
|
|
163
|
+
]
|
|
164
|
+
]
|
|
188
165
|
},
|
|
189
166
|
{
|
|
190
167
|
"id": "24660f9d2862cee9",
|
|
@@ -207,8 +184,8 @@
|
|
|
207
184
|
"topic": "",
|
|
208
185
|
"payload": "{\"On\": true, \"RotationSpeed\": 33}",
|
|
209
186
|
"payloadType": "json",
|
|
210
|
-
"x":
|
|
211
|
-
"y":
|
|
187
|
+
"x": 90,
|
|
188
|
+
"y": 180,
|
|
212
189
|
"wires": [
|
|
213
190
|
[
|
|
214
191
|
"0ed3cd7e0d60beda"
|
|
@@ -236,8 +213,8 @@
|
|
|
236
213
|
"topic": "",
|
|
237
214
|
"payload": "{\"On\": false}",
|
|
238
215
|
"payloadType": "json",
|
|
239
|
-
"x":
|
|
240
|
-
"y":
|
|
216
|
+
"x": 110,
|
|
217
|
+
"y": 240,
|
|
241
218
|
"wires": [
|
|
242
219
|
[
|
|
243
220
|
"0ed3cd7e0d60beda"
|
|
@@ -265,8 +242,8 @@
|
|
|
265
242
|
"topic": "",
|
|
266
243
|
"payload": "{\"On\": true}",
|
|
267
244
|
"payloadType": "json",
|
|
268
|
-
"x":
|
|
269
|
-
"y":
|
|
245
|
+
"x": 110,
|
|
246
|
+
"y": 280,
|
|
270
247
|
"wires": [
|
|
271
248
|
[
|
|
272
249
|
"6703815a8874b156"
|
|
@@ -294,8 +271,8 @@
|
|
|
294
271
|
"topic": "",
|
|
295
272
|
"payload": "{\"On\": false}",
|
|
296
273
|
"payloadType": "json",
|
|
297
|
-
"x":
|
|
298
|
-
"y":
|
|
274
|
+
"x": 110,
|
|
275
|
+
"y": 340,
|
|
299
276
|
"wires": [
|
|
300
277
|
[
|
|
301
278
|
"6703815a8874b156"
|
|
@@ -323,8 +300,8 @@
|
|
|
323
300
|
"topic": "",
|
|
324
301
|
"payload": "",
|
|
325
302
|
"payloadType": "date",
|
|
326
|
-
"x":
|
|
327
|
-
"y":
|
|
303
|
+
"x": 320,
|
|
304
|
+
"y": 260,
|
|
328
305
|
"wires": [
|
|
329
306
|
[
|
|
330
307
|
"6703815a8874b156",
|
|
@@ -353,8 +330,8 @@
|
|
|
353
330
|
"topic": "",
|
|
354
331
|
"payload": "{\"Off\": false}",
|
|
355
332
|
"payloadType": "json",
|
|
356
|
-
"x":
|
|
357
|
-
"y":
|
|
333
|
+
"x": 110,
|
|
334
|
+
"y": 380,
|
|
358
335
|
"wires": [
|
|
359
336
|
[
|
|
360
337
|
"6703815a8874b156"
|
|
@@ -382,8 +359,8 @@
|
|
|
382
359
|
"topic": "",
|
|
383
360
|
"payload": "{\"On\": true}",
|
|
384
361
|
"payloadType": "json",
|
|
385
|
-
"x":
|
|
386
|
-
"y":
|
|
362
|
+
"x": 110,
|
|
363
|
+
"y": 80,
|
|
387
364
|
"wires": [
|
|
388
365
|
[
|
|
389
366
|
"452e3e6171aa7a25"
|
|
@@ -411,8 +388,8 @@
|
|
|
411
388
|
"topic": "",
|
|
412
389
|
"payload": "{\"On\": false}",
|
|
413
390
|
"payloadType": "json",
|
|
414
|
-
"x":
|
|
415
|
-
"y":
|
|
391
|
+
"x": 110,
|
|
392
|
+
"y": 140,
|
|
416
393
|
"wires": [
|
|
417
394
|
[
|
|
418
395
|
"452e3e6171aa7a25"
|
|
@@ -431,11 +408,28 @@
|
|
|
431
408
|
"conf": "557aec8e8c47e61e",
|
|
432
409
|
"sendInitialState": true,
|
|
433
410
|
"x": 500,
|
|
434
|
-
"y":
|
|
411
|
+
"y": 100,
|
|
435
412
|
"wires": [
|
|
436
413
|
[
|
|
437
414
|
"a866ae0bb24ce682"
|
|
438
415
|
]
|
|
439
416
|
]
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
"id": "f194fc4bcb1997a9",
|
|
420
|
+
"type": "debug",
|
|
421
|
+
"z": "caef1e7b5b399e80",
|
|
422
|
+
"name": "debug 4",
|
|
423
|
+
"active": true,
|
|
424
|
+
"tosidebar": true,
|
|
425
|
+
"console": false,
|
|
426
|
+
"tostatus": true,
|
|
427
|
+
"complete": "payload",
|
|
428
|
+
"targetType": "msg",
|
|
429
|
+
"statusVal": "payload",
|
|
430
|
+
"statusType": "auto",
|
|
431
|
+
"x": 800,
|
|
432
|
+
"y": 300,
|
|
433
|
+
"wires": []
|
|
440
434
|
}
|
|
441
435
|
]
|