node-red-contrib-homebridge-automation 0.1.12-beta.24 → 0.1.12-beta.26
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 -3
- package/src/hbBaseNode.js +116 -98
- package/src/hbConfigNode.js +12 -8
- package/src/hbEventNode.js +10 -75
- package/src/hbResumeNode.js +14 -3
- package/src/hbStatusNode.js +1 -2
- package/test/node-red/flows.json +114 -47
- package/src/hbDevices.js +0 -10
- package/src/lib/Accessory.js +0 -126
- package/src/lib/Characteristic.js +0 -30
- package/src/lib/HbAccessories.js +0 -167
- package/src/lib/Homebridge.js +0 -71
- package/src/lib/Homebridges.js +0 -68
- package/src/lib/Service.js +0 -307
- package/src/lib/register.js +0 -156
package/package.json
CHANGED
package/src/HAP-NodeRed.js
CHANGED
|
@@ -11,10 +11,7 @@ const HbStatusNode = require('./hbStatusNode');
|
|
|
11
11
|
const HapDeviceRoutes = require('./HapDeviceRoutes');
|
|
12
12
|
|
|
13
13
|
module.exports = function (RED) {
|
|
14
|
-
var evDevices = [];
|
|
15
|
-
var ctDevices = [];
|
|
16
14
|
var hbDevices;
|
|
17
|
-
var homebridge;
|
|
18
15
|
|
|
19
16
|
/**
|
|
20
17
|
* hbConf - Configuration
|
package/src/hbBaseNode.js
CHANGED
|
@@ -24,11 +24,11 @@ class HbBaseNode {
|
|
|
24
24
|
this.on('input', this.handleInput.bind(this));
|
|
25
25
|
}
|
|
26
26
|
this.on('close', this.handleClose.bind(this));
|
|
27
|
-
this.on('
|
|
27
|
+
this.on('hbEvent', this.handleHBEventMessage.bind(this));
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
handleHBEventMessage(service) {
|
|
31
|
-
debug('
|
|
31
|
+
debug('hbEvent for', this.id, service.serviceName, service.values);
|
|
32
32
|
|
|
33
33
|
this.status({
|
|
34
34
|
text: JSON.stringify(service.values),
|
|
@@ -38,115 +38,133 @@ class HbBaseNode {
|
|
|
38
38
|
this.send({ payload: service.values });
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
41
|
+
createMessage(service) {
|
|
42
|
+
return {
|
|
43
|
+
name: this.name,
|
|
44
|
+
payload: service.values,
|
|
45
|
+
Homebridge: service.instance.name,
|
|
46
|
+
Manufacturer: service.accessoryInformation.Manufacturer,
|
|
47
|
+
Service: service.type,
|
|
48
|
+
_device: this.device,
|
|
49
|
+
_confId: this.confId,
|
|
50
|
+
};
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
handleClose(
|
|
53
|
+
handleClose(removed, done) {
|
|
54
54
|
debug('close', this.name);
|
|
55
|
-
|
|
55
|
+
done();
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
});
|
|
58
|
+
/*
|
|
59
|
+
registerNode() {
|
|
60
|
+
debug("Registering node:", this.fullName);
|
|
61
|
+
this.hbDevice = hbDevices.findDevice(this.device);
|
|
62
|
+
|
|
63
|
+
if (!this.hbDevice) {
|
|
64
|
+
this.error(`Device not found: ${this.device}`);
|
|
65
|
+
} else {
|
|
66
|
+
this.deviceType = this.hbDevice.deviceType;
|
|
69
67
|
}
|
|
70
|
-
} else {
|
|
71
|
-
payload = hbMessage.payload;
|
|
72
68
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
69
|
+
|
|
70
|
+
handleClose(callback) {
|
|
71
|
+
debug('close', this.name);
|
|
72
|
+
callback();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
_convertHBcharacteristicToNode(hbMessage, node) {
|
|
76
|
+
let payload = {};
|
|
77
|
+
if (!hbMessage.payload) {
|
|
78
|
+
const device = hbDevices.findDevice(node.device);
|
|
79
|
+
if (device) {
|
|
80
|
+
hbMessage.forEach(characteristic => {
|
|
81
|
+
const charKey = `${characteristic.aid}.${characteristic.iid}`;
|
|
82
|
+
if (device.characteristics[charKey]) {
|
|
83
|
+
payload[device.characteristics[charKey].characteristic] = characteristic.value;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
86
87
|
} else {
|
|
87
|
-
|
|
88
|
-
node.status({ text: `Invalid characteristic: ${key}`, shape: 'ring', fill: 'yellow' });
|
|
88
|
+
payload = hbMessage.payload;
|
|
89
89
|
}
|
|
90
|
+
return payload;
|
|
90
91
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
return device.type === "00000110" || device.type === "00000111"
|
|
109
|
-
? { characteristics: { payload: this.btoa(status) } }
|
|
110
|
-
: status;
|
|
111
|
-
} catch (err) {
|
|
112
|
-
debug("Error in _status:", err);
|
|
113
|
-
node.status({ text: 'Error retrieving status', shape: 'ring', fill: 'red' });
|
|
114
|
-
throw err;
|
|
92
|
+
|
|
93
|
+
_createControlMessage(payload, node, device) {
|
|
94
|
+
const response = [];
|
|
95
|
+
for (const key in payload) {
|
|
96
|
+
const characteristic = this._getKey(device.characteristics, key);
|
|
97
|
+
if (characteristic) {
|
|
98
|
+
response.push({
|
|
99
|
+
aid: device.aid,
|
|
100
|
+
iid: characteristic.iid,
|
|
101
|
+
value: payload[key],
|
|
102
|
+
});
|
|
103
|
+
} else {
|
|
104
|
+
this.warn(`Invalid characteristic: '${key}'. Available: ${device.descriptions}`);
|
|
105
|
+
node.status({ text: `Invalid characteristic: ${key}`, shape: 'ring', fill: 'yellow' });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return { characteristics: response };
|
|
115
109
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const message =
|
|
123
|
-
|
|
110
|
+
|
|
111
|
+
async _status(nrDevice, node, perms) {
|
|
112
|
+
try {
|
|
113
|
+
const device = hbDevices.findDevice(node.device, perms);
|
|
114
|
+
if (!device) throw new Error(`Device not found: ${nrDevice}`);
|
|
115
|
+
|
|
116
|
+
const message = device.type === "00000110" || device.type === "00000111"
|
|
117
|
+
? { "resource-type": "image", "image-width": 1920, "image-height": 1080 }
|
|
118
|
+
: `?id=${device.getCharacteristics}`;
|
|
119
|
+
|
|
120
|
+
const status = device.type === "00000110" || device.type === "00000111"
|
|
121
|
+
? await this.HAPresourceByDeviceIDAsync(device.id, JSON.stringify(message))
|
|
122
|
+
: await this.HAPstatusByDeviceIDAsync(device.id, message);
|
|
123
|
+
|
|
124
|
+
node.status({ text: 'Success', shape: 'dot', fill: 'green' });
|
|
125
|
+
return device.type === "00000110" || device.type === "00000111"
|
|
126
|
+
? { characteristics: { payload: this.btoa(status) } }
|
|
127
|
+
: status;
|
|
128
|
+
} catch (err) {
|
|
129
|
+
debug("Error in _status:", err);
|
|
130
|
+
node.status({ text: 'Error retrieving status', shape: 'ring', fill: 'red' });
|
|
131
|
+
throw err;
|
|
124
132
|
}
|
|
125
|
-
} catch (err) {
|
|
126
|
-
debug("Error in _register:", err);
|
|
127
|
-
node.status({ text: 'Register error', shape: 'ring', fill: 'red' });
|
|
128
133
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
134
|
+
|
|
135
|
+
async _register(node) {
|
|
136
|
+
try {
|
|
137
|
+
const device = hbDevices.findDevice(node.device, { perms: 'ev' });
|
|
138
|
+
if (device) {
|
|
139
|
+
const message = { characteristics: device.eventRegisters };
|
|
140
|
+
await hapEventByDeviceIDAsync(device.id, JSON.stringify(message));
|
|
141
|
+
}
|
|
142
|
+
} catch (err) {
|
|
143
|
+
debug("Error in _register:", err);
|
|
144
|
+
node.status({ text: 'Register error', shape: 'ring', fill: 'red' });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
_getKey(obj, value) {
|
|
149
|
+
return Object.values(obj).find(char => char.characteristic.toLowerCase() === value.toLowerCase()) || null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
btoa(str) {
|
|
153
|
+
return Buffer.from(str.toString(), 'binary').toString('base64');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async HAPresourceByDeviceIDAsync(deviceId, message) {
|
|
157
|
+
return new Promise((resolve, reject) => {
|
|
158
|
+
homebridge.HAPresourceByDeviceID(deviceId, message, (err, status) => err ? reject(err) : resolve(status));
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async HAPstatusByDeviceIDAsync(deviceId, message) {
|
|
163
|
+
return new Promise((resolve, reject) => {
|
|
164
|
+
homebridge.HAPstatusByDeviceID(deviceId, message, (err, status) => err ? reject(err) : resolve(status));
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
*/
|
|
150
168
|
}
|
|
151
169
|
|
|
152
170
|
module.exports = HbBaseNode;
|
package/src/hbConfigNode.js
CHANGED
|
@@ -117,7 +117,10 @@ class HBConfigNode {
|
|
|
117
117
|
debug('_Register %s -> %s', clientNode.type, clientNode.name);
|
|
118
118
|
clientNode.hbDevice = this.hbDevices.find(service => {
|
|
119
119
|
const deviceUnique = `${service.instance.name}${service.instance.username}${service.accessoryInformation.Manufacturer}${service.serviceName}${service.uuid.slice(0, 8)}`;
|
|
120
|
-
clientNode.
|
|
120
|
+
if (clientNode.device === deviceUnique) {
|
|
121
|
+
clientNode.status({ fill: 'green', shape: 'dot', text: 'connected' });
|
|
122
|
+
clientNode.emit('hbReady', service);
|
|
123
|
+
}
|
|
121
124
|
return clientNode.device === deviceUnique;
|
|
122
125
|
});
|
|
123
126
|
|
|
@@ -141,7 +144,7 @@ class HBConfigNode {
|
|
|
141
144
|
|
|
142
145
|
eventNodes.forEach((eventNode) => {
|
|
143
146
|
if (eventNode._events && typeof eventNode.emit === 'function') {
|
|
144
|
-
eventNode.emit('
|
|
147
|
+
eventNode.emit('hbEvent', service);
|
|
145
148
|
}
|
|
146
149
|
});
|
|
147
150
|
}
|
|
@@ -149,17 +152,18 @@ class HBConfigNode {
|
|
|
149
152
|
}
|
|
150
153
|
cb(null);
|
|
151
154
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
/*
|
|
156
|
+
deregister(clientNode) {
|
|
157
|
+
clientNode.status({ text: 'disconnected', shape: 'ring', fill: 'red' });
|
|
158
|
+
delete this.clientNodes[clientNode.id];
|
|
159
|
+
}
|
|
160
|
+
*/
|
|
158
161
|
close() {
|
|
159
162
|
if (this.hapClient) {
|
|
160
163
|
this.hapClient.destroy();
|
|
161
164
|
}
|
|
162
165
|
}
|
|
166
|
+
|
|
163
167
|
}
|
|
164
168
|
|
|
165
169
|
module.exports = HBConfigNode;
|
package/src/hbEventNode.js
CHANGED
|
@@ -3,87 +3,22 @@ const debug = require('debug')('hapNodeRed:hbEventNode');
|
|
|
3
3
|
|
|
4
4
|
class HbEventNode extends hbBaseNode {
|
|
5
5
|
constructor(config, RED) {
|
|
6
|
-
// console.log('HbEventNode', config);
|
|
7
6
|
super(config, RED);
|
|
8
7
|
this.sendInitialState = config.sendInitialState === true;
|
|
9
|
-
this.
|
|
8
|
+
this.on('hbReady', this.handleHbReady.bind(this))
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
if (
|
|
15
|
-
this.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
this.
|
|
21
|
-
} else {
|
|
22
|
-
this.updateStatus({ text: `disconnected: ${event.status}`, shape: 'ring', fill: 'red' });
|
|
11
|
+
handleHbReady(service) {
|
|
12
|
+
debug('handleHbReady', this.id, this.name, service.values)
|
|
13
|
+
if (this.sendInitialState) {
|
|
14
|
+
this.status({
|
|
15
|
+
text: JSON.stringify(service.values),
|
|
16
|
+
shape: 'dot',
|
|
17
|
+
fill: 'green',
|
|
18
|
+
});
|
|
19
|
+
this.send({ ...this.createMessage(service) });
|
|
23
20
|
}
|
|
24
21
|
}
|
|
25
|
-
|
|
26
|
-
// Handle device registration logic
|
|
27
|
-
handleDeviceRegistration() {
|
|
28
|
-
debug('hbEvent.register', this);
|
|
29
|
-
this.node.hbDevice = this.findDevice(this.node.device, { perms: 'pr' });
|
|
30
|
-
|
|
31
|
-
if (this.node.hbDevice) {
|
|
32
|
-
this.registerEventHandlers();
|
|
33
|
-
this.fetchInitialState();
|
|
34
|
-
} else {
|
|
35
|
-
this.node.error(`Can't find device ${this.node.device}`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Register for device events
|
|
40
|
-
registerEventHandlers() {
|
|
41
|
-
this.node.deviceType = this.node.hbDevice.deviceType;
|
|
42
|
-
this.node.listener = this.command;
|
|
43
|
-
this.node.eventName = [];
|
|
44
|
-
|
|
45
|
-
this.node.hbDevice.eventRegisters.forEach((event) => {
|
|
46
|
-
this.registerEvent(this.node.hbDevice.id + event.aid + event.iid);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
this.updateStatus({ text: 'connected', shape: 'dot', fill: 'green' });
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Fetch and send initial state if required
|
|
53
|
-
fetchInitialState() {
|
|
54
|
-
this.fetchStatus(this.node.device, { perms: 'ev' }, (err, message) => {
|
|
55
|
-
if (!err) {
|
|
56
|
-
this.state = this._convertHBcharacteristicToNode(message.characteristics);
|
|
57
|
-
debug(
|
|
58
|
-
'hbEvent received: %s = %s',
|
|
59
|
-
this.node.fullName,
|
|
60
|
-
`${JSON.stringify(message.characteristics).slice(0, 80)}...`
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
if (this.sendInitialState) {
|
|
64
|
-
const msg = this.createMessage(message, true);
|
|
65
|
-
this.updateStatus({ text: `${JSON.stringify(msg.payload).slice(0, 30)}...`, shape: 'dot', fill: 'green' });
|
|
66
|
-
this.send(msg);
|
|
67
|
-
}
|
|
68
|
-
} else {
|
|
69
|
-
this.node.error('hbEvent _status: error', this.node.fullName, err);
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Create a message payload for event or initial state
|
|
75
|
-
createMessage(event, isInitialState = false) {
|
|
76
|
-
return {
|
|
77
|
-
name: this.node.name,
|
|
78
|
-
payload: this.state,
|
|
79
|
-
Homebridge: this.node.hbDevice.homebridge,
|
|
80
|
-
Manufacturer: this.node.hbDevice.manufacturer,
|
|
81
|
-
Service: this.node.hbDevice.deviceType,
|
|
82
|
-
_device: this.node.device,
|
|
83
|
-
_confId: this.node.confId,
|
|
84
|
-
_rawEvent: isInitialState ? event : undefined,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
22
|
}
|
|
88
23
|
|
|
89
24
|
module.exports = HbEventNode;
|
package/src/hbResumeNode.js
CHANGED
|
@@ -19,10 +19,21 @@ class HbResumeNode extends HbBaseNode {
|
|
|
19
19
|
// Handle device registration
|
|
20
20
|
debug('hbResume - hbConfigNode', this.hbConfigNode);
|
|
21
21
|
// debug('hbResume - hbConfigNode', this.configNode.hbConfigNode);
|
|
22
|
-
|
|
22
|
+
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
handleHBEventMessage(service) {
|
|
26
|
+
debug('topic for', this.id, service.serviceName, service.values);
|
|
27
|
+
|
|
28
|
+
this.status({
|
|
29
|
+
text: JSON.stringify(service.values),
|
|
30
|
+
shape: 'dot',
|
|
31
|
+
fill: 'green',
|
|
32
|
+
});
|
|
33
|
+
this.send({ payload: service.values });
|
|
23
34
|
}
|
|
24
35
|
|
|
25
|
-
handleInput(msg) {
|
|
36
|
+
handleInput(msg, send) {
|
|
26
37
|
this.msg = msg;
|
|
27
38
|
debug("hbResume.input: %s input", this.fullName, JSON.stringify(msg));
|
|
28
39
|
|
|
@@ -51,7 +62,7 @@ class HbResumeNode extends HbBaseNode {
|
|
|
51
62
|
newMsg = msg;
|
|
52
63
|
}
|
|
53
64
|
|
|
54
|
-
|
|
65
|
+
send(newMsg.payload.On ? newMsg : { ...newMsg, payload: { On: false } });
|
|
55
66
|
debug("hbResume.input: %s output", this.fullName, JSON.stringify(newMsg));
|
|
56
67
|
this.updateStatus(newMsg.payload);
|
|
57
68
|
this.lastMessageValue = newMsg.payload;
|
package/src/hbStatusNode.js
CHANGED
package/test/node-red/flows.json
CHANGED
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"tosidebar": true,
|
|
23
23
|
"console": false,
|
|
24
24
|
"tostatus": true,
|
|
25
|
-
"complete": "
|
|
26
|
-
"targetType": "
|
|
25
|
+
"complete": "true",
|
|
26
|
+
"targetType": "full",
|
|
27
27
|
"statusVal": "payload",
|
|
28
28
|
"statusType": "auto",
|
|
29
29
|
"x": 800,
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"tosidebar": true,
|
|
40
40
|
"console": false,
|
|
41
41
|
"tostatus": true,
|
|
42
|
-
"complete": "
|
|
43
|
-
"targetType": "
|
|
42
|
+
"complete": "true",
|
|
43
|
+
"targetType": "full",
|
|
44
44
|
"statusVal": "payload",
|
|
45
45
|
"statusType": "auto",
|
|
46
46
|
"x": 800,
|
|
@@ -72,8 +72,7 @@
|
|
|
72
72
|
"y": 140,
|
|
73
73
|
"wires": [
|
|
74
74
|
[
|
|
75
|
-
"3d7babac3a298e60"
|
|
76
|
-
"452e3e6171aa7a25"
|
|
75
|
+
"3d7babac3a298e60"
|
|
77
76
|
]
|
|
78
77
|
]
|
|
79
78
|
},
|
|
@@ -95,48 +94,10 @@
|
|
|
95
94
|
]
|
|
96
95
|
]
|
|
97
96
|
},
|
|
98
|
-
{
|
|
99
|
-
"id": "696e04753d952daf",
|
|
100
|
-
"type": "hb-status",
|
|
101
|
-
"z": "caef1e7b5b399e80",
|
|
102
|
-
"d": true,
|
|
103
|
-
"name": "West Bedroom",
|
|
104
|
-
"Homebridge": "homebridge",
|
|
105
|
-
"Manufacturer": "Tasmota",
|
|
106
|
-
"Service": "Lightbulb",
|
|
107
|
-
"device": "homebridge1C:22:3D:E3:CF:34TasmotaWest Bedroom00000043",
|
|
108
|
-
"conf": "557aec8e8c47e61e",
|
|
109
|
-
"x": 480,
|
|
110
|
-
"y": 300,
|
|
111
|
-
"wires": [
|
|
112
|
-
[
|
|
113
|
-
"a866ae0bb24ce682"
|
|
114
|
-
]
|
|
115
|
-
]
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
"id": "bb88544904b343a1",
|
|
119
|
-
"type": "hb-event",
|
|
120
|
-
"z": "caef1e7b5b399e80",
|
|
121
|
-
"d": true,
|
|
122
|
-
"name": "",
|
|
123
|
-
"Homebridge": "homebridge",
|
|
124
|
-
"Manufacturer": "Tasmota",
|
|
125
|
-
"Service": "Lightbulb",
|
|
126
|
-
"device": "homebridge1C:22:3D:E3:CF:34TasmotaWest Bedroom00000043",
|
|
127
|
-
"conf": "557aec8e8c47e61e",
|
|
128
|
-
"sendInitialState": false,
|
|
129
|
-
"x": 250,
|
|
130
|
-
"y": 380,
|
|
131
|
-
"wires": [
|
|
132
|
-
[]
|
|
133
|
-
]
|
|
134
|
-
},
|
|
135
97
|
{
|
|
136
98
|
"id": "452e3e6171aa7a25",
|
|
137
99
|
"type": "hb-resume",
|
|
138
100
|
"z": "caef1e7b5b399e80",
|
|
139
|
-
"d": true,
|
|
140
101
|
"name": "West Bedroom",
|
|
141
102
|
"Homebridge": "homebridge",
|
|
142
103
|
"Manufacturer": "Tasmota",
|
|
@@ -179,7 +140,7 @@
|
|
|
179
140
|
"device": "homebridge1C:22:3D:E3:CF:34TasmotaWest Bedroom Fan00000040",
|
|
180
141
|
"conf": "557aec8e8c47e61e",
|
|
181
142
|
"outputs": 0,
|
|
182
|
-
"x":
|
|
143
|
+
"x": 810,
|
|
183
144
|
"y": 600,
|
|
184
145
|
"wires": []
|
|
185
146
|
},
|
|
@@ -223,8 +184,8 @@
|
|
|
223
184
|
"device": "homebridge1C:22:3D:E3:CF:34TasmotaWest Bedroom00000043",
|
|
224
185
|
"conf": "557aec8e8c47e61e",
|
|
225
186
|
"outputs": 0,
|
|
226
|
-
"x":
|
|
227
|
-
"y":
|
|
187
|
+
"x": 800,
|
|
188
|
+
"y": 680,
|
|
228
189
|
"wires": []
|
|
229
190
|
},
|
|
230
191
|
{
|
|
@@ -401,5 +362,111 @@
|
|
|
401
362
|
"6703815a8874b156"
|
|
402
363
|
]
|
|
403
364
|
]
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"id": "80ffdbb93cd24b48",
|
|
368
|
+
"type": "inject",
|
|
369
|
+
"z": "caef1e7b5b399e80",
|
|
370
|
+
"name": "",
|
|
371
|
+
"props": [
|
|
372
|
+
{
|
|
373
|
+
"p": "payload"
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
"p": "topic",
|
|
377
|
+
"vt": "str"
|
|
378
|
+
}
|
|
379
|
+
],
|
|
380
|
+
"repeat": "",
|
|
381
|
+
"crontab": "",
|
|
382
|
+
"once": false,
|
|
383
|
+
"onceDelay": 0.1,
|
|
384
|
+
"topic": "",
|
|
385
|
+
"payload": "{\"On\": true}",
|
|
386
|
+
"payloadType": "json",
|
|
387
|
+
"x": 150,
|
|
388
|
+
"y": 340,
|
|
389
|
+
"wires": [
|
|
390
|
+
[
|
|
391
|
+
"452e3e6171aa7a25"
|
|
392
|
+
]
|
|
393
|
+
]
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
"id": "d0e413b3c28f757a",
|
|
397
|
+
"type": "inject",
|
|
398
|
+
"z": "caef1e7b5b399e80",
|
|
399
|
+
"name": "",
|
|
400
|
+
"props": [
|
|
401
|
+
{
|
|
402
|
+
"p": "payload"
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
"p": "topic",
|
|
406
|
+
"vt": "str"
|
|
407
|
+
}
|
|
408
|
+
],
|
|
409
|
+
"repeat": "",
|
|
410
|
+
"crontab": "",
|
|
411
|
+
"once": false,
|
|
412
|
+
"onceDelay": 0.1,
|
|
413
|
+
"topic": "",
|
|
414
|
+
"payload": "{\"On\": false}",
|
|
415
|
+
"payloadType": "json",
|
|
416
|
+
"x": 150,
|
|
417
|
+
"y": 400,
|
|
418
|
+
"wires": [
|
|
419
|
+
[
|
|
420
|
+
"452e3e6171aa7a25"
|
|
421
|
+
]
|
|
422
|
+
]
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
"id": "82638dac6ac32bb1",
|
|
426
|
+
"type": "hb-event",
|
|
427
|
+
"z": "caef1e7b5b399e80",
|
|
428
|
+
"name": "West Bedroom",
|
|
429
|
+
"Homebridge": "homebridge",
|
|
430
|
+
"Manufacturer": "Tasmota",
|
|
431
|
+
"Service": "Lightbulb",
|
|
432
|
+
"device": "homebridge1C:22:3D:E3:CF:34TasmotaWest Bedroom00000043",
|
|
433
|
+
"conf": "557aec8e8c47e61e",
|
|
434
|
+
"sendInitialState": true,
|
|
435
|
+
"x": 500,
|
|
436
|
+
"y": 260,
|
|
437
|
+
"wires": [
|
|
438
|
+
[
|
|
439
|
+
"a866ae0bb24ce682"
|
|
440
|
+
]
|
|
441
|
+
]
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
"id": "56633636bd2e624c",
|
|
445
|
+
"type": "inject",
|
|
446
|
+
"z": "caef1e7b5b399e80",
|
|
447
|
+
"name": "",
|
|
448
|
+
"props": [
|
|
449
|
+
{
|
|
450
|
+
"p": "payload"
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
"p": "topic",
|
|
454
|
+
"vt": "str"
|
|
455
|
+
}
|
|
456
|
+
],
|
|
457
|
+
"repeat": "60",
|
|
458
|
+
"crontab": "",
|
|
459
|
+
"once": true,
|
|
460
|
+
"onceDelay": "60",
|
|
461
|
+
"topic": "",
|
|
462
|
+
"payload": "",
|
|
463
|
+
"payloadType": "date",
|
|
464
|
+
"x": 190,
|
|
465
|
+
"y": 280,
|
|
466
|
+
"wires": [
|
|
467
|
+
[
|
|
468
|
+
"452e3e6171aa7a25"
|
|
469
|
+
]
|
|
470
|
+
]
|
|
404
471
|
}
|
|
405
472
|
]
|