node-red-contrib-homebridge-automation 0.1.12-beta.24 → 0.1.12-beta.25
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 +14 -2
- package/src/hbConfigNode.js +5 -2
- package/src/hbEventNode.js +8 -74
- package/src/hbResumeNode.js +14 -3
- package/test/node-red/flows.json +80 -41
- 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,6 +38,18 @@ class HbBaseNode {
|
|
|
38
38
|
this.send({ payload: service.values });
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
createMessage(event, isInitialState = false) {
|
|
42
|
+
return {
|
|
43
|
+
name: this.node.name,
|
|
44
|
+
payload: this.state,
|
|
45
|
+
Homebridge: this.node.hbDevice.homebridge,
|
|
46
|
+
Manufacturer: this.node.hbDevice.manufacturer,
|
|
47
|
+
Service: this.node.hbDevice.deviceType,
|
|
48
|
+
_device: this.node.device,
|
|
49
|
+
_confId: this.node.confId,
|
|
50
|
+
_rawEvent: isInitialState ? event : undefined,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
41
53
|
|
|
42
54
|
registerNode() {
|
|
43
55
|
debug("Registering node:", this.fullName);
|
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
|
}
|
package/src/hbEventNode.js
CHANGED
|
@@ -3,87 +3,21 @@ 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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
this.updateStatus({ text: `${JSON.stringify(msg.payload).slice(0, 30)}...`, shape: 'dot', fill: 'green' });
|
|
18
|
-
this.send(msg);
|
|
19
|
-
} else if (event.status === true) {
|
|
20
|
-
this.updateStatus({ text: 'connected', shape: 'dot', fill: 'green' });
|
|
21
|
-
} else {
|
|
22
|
-
this.updateStatus({ text: `disconnected: ${event.status}`, shape: 'ring', fill: 'red' });
|
|
23
|
-
}
|
|
24
|
-
}
|
|
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
|
-
}
|
|
11
|
+
handleHbReady(service) {
|
|
12
|
+
this.status({
|
|
13
|
+
text: JSON.stringify(service.values),
|
|
14
|
+
shape: 'dot',
|
|
15
|
+
fill: 'green',
|
|
71
16
|
});
|
|
17
|
+
this.send({ payload: service.values });
|
|
72
18
|
}
|
|
73
|
-
|
|
74
19
|
// Create a message payload for event or initial state
|
|
75
|
-
|
|
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
|
-
}
|
|
20
|
+
|
|
87
21
|
}
|
|
88
22
|
|
|
89
23
|
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/test/node-red/flows.json
CHANGED
|
@@ -95,48 +95,10 @@
|
|
|
95
95
|
]
|
|
96
96
|
]
|
|
97
97
|
},
|
|
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
98
|
{
|
|
136
99
|
"id": "452e3e6171aa7a25",
|
|
137
100
|
"type": "hb-resume",
|
|
138
101
|
"z": "caef1e7b5b399e80",
|
|
139
|
-
"d": true,
|
|
140
102
|
"name": "West Bedroom",
|
|
141
103
|
"Homebridge": "homebridge",
|
|
142
104
|
"Manufacturer": "Tasmota",
|
|
@@ -179,7 +141,7 @@
|
|
|
179
141
|
"device": "homebridge1C:22:3D:E3:CF:34TasmotaWest Bedroom Fan00000040",
|
|
180
142
|
"conf": "557aec8e8c47e61e",
|
|
181
143
|
"outputs": 0,
|
|
182
|
-
"x":
|
|
144
|
+
"x": 810,
|
|
183
145
|
"y": 600,
|
|
184
146
|
"wires": []
|
|
185
147
|
},
|
|
@@ -223,8 +185,8 @@
|
|
|
223
185
|
"device": "homebridge1C:22:3D:E3:CF:34TasmotaWest Bedroom00000043",
|
|
224
186
|
"conf": "557aec8e8c47e61e",
|
|
225
187
|
"outputs": 0,
|
|
226
|
-
"x":
|
|
227
|
-
"y":
|
|
188
|
+
"x": 800,
|
|
189
|
+
"y": 680,
|
|
228
190
|
"wires": []
|
|
229
191
|
},
|
|
230
192
|
{
|
|
@@ -401,5 +363,82 @@
|
|
|
401
363
|
"6703815a8874b156"
|
|
402
364
|
]
|
|
403
365
|
]
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
"id": "80ffdbb93cd24b48",
|
|
369
|
+
"type": "inject",
|
|
370
|
+
"z": "caef1e7b5b399e80",
|
|
371
|
+
"name": "",
|
|
372
|
+
"props": [
|
|
373
|
+
{
|
|
374
|
+
"p": "payload"
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
"p": "topic",
|
|
378
|
+
"vt": "str"
|
|
379
|
+
}
|
|
380
|
+
],
|
|
381
|
+
"repeat": "",
|
|
382
|
+
"crontab": "",
|
|
383
|
+
"once": false,
|
|
384
|
+
"onceDelay": 0.1,
|
|
385
|
+
"topic": "",
|
|
386
|
+
"payload": "{\"On\": true}",
|
|
387
|
+
"payloadType": "json",
|
|
388
|
+
"x": 150,
|
|
389
|
+
"y": 340,
|
|
390
|
+
"wires": [
|
|
391
|
+
[
|
|
392
|
+
"452e3e6171aa7a25"
|
|
393
|
+
]
|
|
394
|
+
]
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
"id": "d0e413b3c28f757a",
|
|
398
|
+
"type": "inject",
|
|
399
|
+
"z": "caef1e7b5b399e80",
|
|
400
|
+
"name": "",
|
|
401
|
+
"props": [
|
|
402
|
+
{
|
|
403
|
+
"p": "payload"
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
"p": "topic",
|
|
407
|
+
"vt": "str"
|
|
408
|
+
}
|
|
409
|
+
],
|
|
410
|
+
"repeat": "",
|
|
411
|
+
"crontab": "",
|
|
412
|
+
"once": false,
|
|
413
|
+
"onceDelay": 0.1,
|
|
414
|
+
"topic": "",
|
|
415
|
+
"payload": "{\"On\": false}",
|
|
416
|
+
"payloadType": "json",
|
|
417
|
+
"x": 150,
|
|
418
|
+
"y": 400,
|
|
419
|
+
"wires": [
|
|
420
|
+
[
|
|
421
|
+
"452e3e6171aa7a25"
|
|
422
|
+
]
|
|
423
|
+
]
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
"id": "82638dac6ac32bb1",
|
|
427
|
+
"type": "hb-event",
|
|
428
|
+
"z": "caef1e7b5b399e80",
|
|
429
|
+
"name": "West Bedroom",
|
|
430
|
+
"Homebridge": "homebridge",
|
|
431
|
+
"Manufacturer": "Tasmota",
|
|
432
|
+
"Service": "Lightbulb",
|
|
433
|
+
"device": "homebridge1C:22:3D:E3:CF:34TasmotaWest Bedroom00000043",
|
|
434
|
+
"conf": "557aec8e8c47e61e",
|
|
435
|
+
"sendInitialState": true,
|
|
436
|
+
"x": 500,
|
|
437
|
+
"y": 260,
|
|
438
|
+
"wires": [
|
|
439
|
+
[
|
|
440
|
+
"a866ae0bb24ce682"
|
|
441
|
+
]
|
|
442
|
+
]
|
|
404
443
|
}
|
|
405
444
|
]
|
package/src/hbDevices.js
DELETED
package/src/lib/Accessory.js
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
var debug = require('debug')('Accessory');
|
|
2
|
-
var Service = require('./Service.js').Service;
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
Accessory: Accessory
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
/*
|
|
9
|
-
* Homebridges -> Homebridge -> Accessory -> Service -> Characteristic
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
function Accessory(devices, context) {
|
|
13
|
-
// debug("Accessory", devices);
|
|
14
|
-
this.aid = devices.aid;
|
|
15
|
-
this.host = context.host;
|
|
16
|
-
this.port = context.port;
|
|
17
|
-
this.homebridge = context.homebridge;
|
|
18
|
-
this.id = context.id;
|
|
19
|
-
this.services = [];
|
|
20
|
-
devices.services.forEach(function (element) {
|
|
21
|
-
// debug("Service", element);
|
|
22
|
-
switch (element.type.substring(0, 8)) {
|
|
23
|
-
case "0000003E": // Accessory Information
|
|
24
|
-
this.info = information(element.characteristics);
|
|
25
|
-
break;
|
|
26
|
-
case "00000110": // Camera RTPStream Management generates duplicates
|
|
27
|
-
var service = new Service(element, this);
|
|
28
|
-
// console.log('services', this.services);
|
|
29
|
-
if (this.services.some(e => e.type === '00000110')) {
|
|
30
|
-
|
|
31
|
-
} else {
|
|
32
|
-
this.services.push(service);
|
|
33
|
-
}
|
|
34
|
-
break;
|
|
35
|
-
case "000000D9": // Input Source from webosTV has a dummy input source
|
|
36
|
-
var service = new Service(element, this);
|
|
37
|
-
if (service.name !== "dummy") {
|
|
38
|
-
this.services.push(service);
|
|
39
|
-
}
|
|
40
|
-
break;
|
|
41
|
-
default:
|
|
42
|
-
var service = new Service(element, this);
|
|
43
|
-
this.services.push(service);
|
|
44
|
-
}
|
|
45
|
-
}.bind(this));
|
|
46
|
-
// debug("Info", this.info);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
Accessory.prototype.toList = function (context) {
|
|
50
|
-
var list = [];
|
|
51
|
-
// debug("toList", context);
|
|
52
|
-
context.aid = this.aid;
|
|
53
|
-
if (!this.info) {
|
|
54
|
-
console.log("ERROR: incorrect version of plugin, please upgrade");
|
|
55
|
-
}
|
|
56
|
-
context.name = this.info.Name;
|
|
57
|
-
context.manufacturer = this.info.Manufacturer;
|
|
58
|
-
for (var index in this.services) {
|
|
59
|
-
var service = this.services[index].toList(context);
|
|
60
|
-
if (service) {
|
|
61
|
-
list = list.concat(service);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// debug('toList', new Error('test'));
|
|
66
|
-
// debug("opt",context.opt,list.length);
|
|
67
|
-
return (list);
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
/*
|
|
71
|
-
[ { iid: 2,
|
|
72
|
-
type: '00000014-0000-1000-8000-0026BB765291',
|
|
73
|
-
perms: [Array],
|
|
74
|
-
format: 'bool',
|
|
75
|
-
description: 'Identify' },
|
|
76
|
-
{ iid: 3,
|
|
77
|
-
type: '00000020-0000-1000-8000-0026BB765291',
|
|
78
|
-
perms: [Array],
|
|
79
|
-
format: 'string',
|
|
80
|
-
value: 'NorthernMan54',
|
|
81
|
-
description: 'Manufacturer' },
|
|
82
|
-
{ iid: 4,
|
|
83
|
-
type: '00000021-0000-1000-8000-0026BB765291',
|
|
84
|
-
perms: [Array],
|
|
85
|
-
format: 'string',
|
|
86
|
-
value: 'dht22',
|
|
87
|
-
description: 'Model' },
|
|
88
|
-
{ iid: 5,
|
|
89
|
-
type: '00000023-0000-1000-8000-0026BB765291',
|
|
90
|
-
perms: [Array],
|
|
91
|
-
format: 'string',
|
|
92
|
-
value: 'Basement',
|
|
93
|
-
description: 'Name' },
|
|
94
|
-
{ iid: 6,
|
|
95
|
-
type: '00000030-0000-1000-8000-0026BB765291',
|
|
96
|
-
perms: [Array],
|
|
97
|
-
format: 'string',
|
|
98
|
-
value: 'penny-Basement',
|
|
99
|
-
description: 'Serial Number' },
|
|
100
|
-
{ iid: 7,
|
|
101
|
-
type: '00000052-0000-1000-8000-0026BB765291',
|
|
102
|
-
perms: [Array],
|
|
103
|
-
format: 'string',
|
|
104
|
-
value: '0.1.21',
|
|
105
|
-
description: 'Firmware Revision' } ],
|
|
106
|
-
*/
|
|
107
|
-
|
|
108
|
-
/*
|
|
109
|
-
{ Identify: undefined,
|
|
110
|
-
Manufacturer: 'Default-Manufacturer',
|
|
111
|
-
Model: 'Default-Model',
|
|
112
|
-
Name: 'FHall',
|
|
113
|
-
SerialNumber: 'Default-SerialNumber',
|
|
114
|
-
FirmwareRevision: '1.0' }
|
|
115
|
-
*/
|
|
116
|
-
|
|
117
|
-
function information(characteristics) {
|
|
118
|
-
var result = {};
|
|
119
|
-
characteristics.forEach(function (characteristic) {
|
|
120
|
-
if (characteristic.description) {
|
|
121
|
-
var key = characteristic.description.replace(/ /g, '').replace(/\./g, '_');
|
|
122
|
-
result[key] = characteristic.value;
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
return result;
|
|
126
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
var debug = require('debug')('Characteristic');
|
|
2
|
-
// var Service = require('./Service.js').Service;
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
Characteristic: Characteristic
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
/*
|
|
9
|
-
* Homebridges -> Homebridge -> Accessory -> Service -> Characteristic
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
function Characteristic(devices, context) {
|
|
13
|
-
// debug("Characteristic", devices);
|
|
14
|
-
this.iid = devices.iid;
|
|
15
|
-
this.type = devices.type.substring(0, 8);
|
|
16
|
-
this.perms = devices.perms;
|
|
17
|
-
this.value = devices.value;
|
|
18
|
-
this.description = (devices.description ? devices.description : this.type);
|
|
19
|
-
this.characteristic = {};
|
|
20
|
-
this.getCharacteristic = context.aid + '.' + this.iid;
|
|
21
|
-
this.characteristic[this.getCharacteristic] = {
|
|
22
|
-
characteristic: this.description.replace(/ /g, "").replace(/\./g, "_"),
|
|
23
|
-
iid: this.iid
|
|
24
|
-
};
|
|
25
|
-
this.eventRegister = {
|
|
26
|
-
aid: context.aid,
|
|
27
|
-
iid: this.iid,
|
|
28
|
-
"ev": true
|
|
29
|
-
};
|
|
30
|
-
}
|
package/src/lib/HbAccessories.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
var debug = require('debug')('HbAccessories');
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
HbAccessories: HbAccessories
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
function HbAccessories(devices, opt) {
|
|
8
|
-
debug("HbAccessories", devices);
|
|
9
|
-
if (typeof devices === 'array') {
|
|
10
|
-
devices.forEach(function(element) {
|
|
11
|
-
// debug('Device', element);
|
|
12
|
-
events = events.concat(_instance(element, perms));
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/*
|
|
18
|
-
function registerEv(homebridge, devices) {
|
|
19
|
-
return register(homebridge, devices, 'ev');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function registerCt(homebridge, devices) {
|
|
23
|
-
return register(homebridge, devices, 'pw');
|
|
24
|
-
}
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
function register(homebridge, devices, perms) {
|
|
28
|
-
// debug('Discovered', devices);
|
|
29
|
-
var events = [];
|
|
30
|
-
devices.forEach(function(element) {
|
|
31
|
-
// debug('Device', element);
|
|
32
|
-
events = events.concat(_instance(element, perms));
|
|
33
|
-
});
|
|
34
|
-
return (events);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function _instance(instance, perms) {
|
|
38
|
-
// debug('Accessories', instance.accessories.accessories);
|
|
39
|
-
var events = [];
|
|
40
|
-
instance.accessories.accessories.forEach(function(accessory) {
|
|
41
|
-
// debug('Accessory', instance.instance.txt);
|
|
42
|
-
events = events.concat(_service({
|
|
43
|
-
"host": instance.ipAddress,
|
|
44
|
-
"port": instance.instance.port,
|
|
45
|
-
"homebridge": instance.instance.txt.md,
|
|
46
|
-
"id": instance.instance.txt.id,
|
|
47
|
-
"aid": accessory.aid
|
|
48
|
-
}, accessory.services, perms));
|
|
49
|
-
});
|
|
50
|
-
return (events);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function _service(context, accessory, perms) {
|
|
54
|
-
var events = [];
|
|
55
|
-
accessory.forEach(function(service) {
|
|
56
|
-
// debug('Service', service);
|
|
57
|
-
switch (service.type.substring(0, 8)) {
|
|
58
|
-
case "00000043": // Lightbulb
|
|
59
|
-
case "00000047": // Outlet
|
|
60
|
-
case "00000049": // Switch
|
|
61
|
-
case "00000040": // Fan
|
|
62
|
-
case "0000008C": // WindowCovering
|
|
63
|
-
case "0000008A": // TemperatureSensor
|
|
64
|
-
case "000000B7": // Fan 2 aka Dyson
|
|
65
|
-
case "00000041": // Garage Door
|
|
66
|
-
case "000000D0": // Valve aka sprinkler
|
|
67
|
-
// case "0000003E": // AccessoryInformation
|
|
68
|
-
case "0000004A": // Thermostat
|
|
69
|
-
case "00000080": // Contact Sensor
|
|
70
|
-
case "00000085": // Motion Sensor
|
|
71
|
-
case "00000111": // Camera
|
|
72
|
-
// debug('Supported Service', service);
|
|
73
|
-
events = events.concat(_characteristics(context, service, perms));
|
|
74
|
-
// debug("Events", events);
|
|
75
|
-
break;
|
|
76
|
-
case "0000003E": // AccessoryInformation
|
|
77
|
-
_name(context, service);
|
|
78
|
-
// debug("Events", events);
|
|
79
|
-
break;
|
|
80
|
-
default:
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
return (events);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function _characteristics(context, service, perms) {
|
|
87
|
-
// debug("Char", service, Array.isArray(service));
|
|
88
|
-
|
|
89
|
-
var events = [];
|
|
90
|
-
service.characteristics.forEach(function(characteristic) {
|
|
91
|
-
switch (characteristic.type.substring(0, 8)) {
|
|
92
|
-
case "00000020": // manufacturer
|
|
93
|
-
context.manufacturer = characteristic.value;
|
|
94
|
-
break;
|
|
95
|
-
case "00000023": // name
|
|
96
|
-
context.name = characteristic.value;
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (characteristic.perms.includes(perms)) {
|
|
101
|
-
context.iid = characteristic.iid;
|
|
102
|
-
context.function = characteristic.description;
|
|
103
|
-
context.service = service.type.substring(0, 8);
|
|
104
|
-
context.characteristic = characteristic.type.substring(0, 8);
|
|
105
|
-
context.deviceType = _normalizeName(context.service);
|
|
106
|
-
// debug("Register", context);
|
|
107
|
-
context.fullName = context.name + ' - ' + _normalizeName(context.service) + ' - ' + context.function;
|
|
108
|
-
context.sortName = context.name + ':' + _normalizeName(context.service) + ':' + context.function;
|
|
109
|
-
context.uniqueId = context.homebridge + context.id + context.manufacturer + context.name + context.service + context.characteristic;
|
|
110
|
-
// debug("Perms ", context.fullName, characteristic.perms);
|
|
111
|
-
events.push(JSON.parse(JSON.stringify(context)));
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
// debug("Char Events", events);
|
|
115
|
-
return (events);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function _name(context, service) {
|
|
119
|
-
// debug("Char", service, Array.isArray(service));
|
|
120
|
-
|
|
121
|
-
var manufacturer, name;
|
|
122
|
-
service.characteristics.forEach(function(characteristic) {
|
|
123
|
-
switch (characteristic.type.substring(0, 8)) {
|
|
124
|
-
case "00000020": // manufacturer
|
|
125
|
-
context.manufacturer = characteristic.value;
|
|
126
|
-
break;
|
|
127
|
-
case "00000023": // name
|
|
128
|
-
context.name = characteristic.value;
|
|
129
|
-
break;
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
// debug("Char Events", events);
|
|
133
|
-
// return ({ "manufacturer": manufacturer, "name": name});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function _normalizeName(id) {
|
|
137
|
-
switch (id) {
|
|
138
|
-
case "00000043": // Lightbulb
|
|
139
|
-
return ("Lightbulb");
|
|
140
|
-
case "00000047": // Outlet
|
|
141
|
-
return ("Outlet");
|
|
142
|
-
case "00000049": // Switch
|
|
143
|
-
return ("Switch");
|
|
144
|
-
case "000000B7": // Fan 2 aka Dyson
|
|
145
|
-
case "00000040": // Fan
|
|
146
|
-
return ("Fan");
|
|
147
|
-
case "0000008C": // WindowCovering
|
|
148
|
-
return ("Blinds");
|
|
149
|
-
case "0000008A": // TemperatureSensor
|
|
150
|
-
return ("Temperature");
|
|
151
|
-
case "00000041": // Garage Door
|
|
152
|
-
return ("Garage Door");
|
|
153
|
-
case "000000D0": // Valve aka sprinkler
|
|
154
|
-
return ("Sprinkler");
|
|
155
|
-
// case "0000003E": // AccessoryInformation
|
|
156
|
-
case "0000004A": // Thermostat
|
|
157
|
-
return ("Thermostat");
|
|
158
|
-
case "00000080": // Contact Sensor
|
|
159
|
-
return ("Contact");
|
|
160
|
-
case "00000085": // Motion Sensor
|
|
161
|
-
return ("Motion");
|
|
162
|
-
case "00000111": // Camera
|
|
163
|
-
return ("Camera");
|
|
164
|
-
default:
|
|
165
|
-
debug("Missing HB Type", id);
|
|
166
|
-
}
|
|
167
|
-
}
|
package/src/lib/Homebridge.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
var debug = require('debug')('Homebridge');
|
|
2
|
-
var Accessory = require('./Accessory.js').Accessory;
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
Homebridge: Homebridge
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
/*
|
|
9
|
-
* Homebridges -> Homebridge -> Accessory -> Service -> Characteristic
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
/*
|
|
13
|
-
|
|
14
|
-
{ ipAddress: '192.168.1.202',
|
|
15
|
-
instance:
|
|
16
|
-
{ addresses: [ '192.168.1.202', 'fe80::eab6:f43b:eb39:9d7f' ],
|
|
17
|
-
name: 'Leonard-Aztest-A6F3',
|
|
18
|
-
fqdn: 'Leonard-Aztest-A6F3._hap._tcp.local',
|
|
19
|
-
host: 'AC_22_3D_E3_CE_32.local',
|
|
20
|
-
referer:
|
|
21
|
-
{ address: '192.168.1.202',
|
|
22
|
-
family: 'IPv4',
|
|
23
|
-
port: 5353,
|
|
24
|
-
size: 374 },
|
|
25
|
-
port: 51828,
|
|
26
|
-
type: 'hap',
|
|
27
|
-
protocol: 'tcp',
|
|
28
|
-
subtypes: [],
|
|
29
|
-
rawTxt: <Buffer 11 6d 64 3d 4c 65 6f 6e 61 72 64 2d 41 7a 74 65 73 74 06 70 76 3d 31 2e 30 14 69 64 3d 41 43 3a 32 32 3a 33 44 3a 45 33 3a 43 45 3a 33 32 04 63 23 3d ... >,
|
|
30
|
-
txt:
|
|
31
|
-
{ md: 'Leonard-Aztest',
|
|
32
|
-
pv: '1.0',
|
|
33
|
-
id: 'AC:22:3D:E3:CE:32',
|
|
34
|
-
'c#': '5',
|
|
35
|
-
's#': '1',
|
|
36
|
-
ff: '0',
|
|
37
|
-
ci: '2',
|
|
38
|
-
sf: '1',
|
|
39
|
-
sh: 'HjMYzQ==' } },
|
|
40
|
-
accessories: { accessories: [ [Object], [Object] ] } }
|
|
41
|
-
*/
|
|
42
|
-
|
|
43
|
-
function Homebridge(devices) {
|
|
44
|
-
// debug("Homebridge", devices);
|
|
45
|
-
this.accessories = [];
|
|
46
|
-
this.host = devices.ipAddress;
|
|
47
|
-
this.port = devices.instance.port;
|
|
48
|
-
this.homebridge = devices.instance.txt.md;
|
|
49
|
-
this.id = devices.instance.txt.id;
|
|
50
|
-
devices.accessories.accessories.forEach(function(element) {
|
|
51
|
-
var accessory = new Accessory(element, this);
|
|
52
|
-
this.accessories.push(accessory);
|
|
53
|
-
}.bind(this));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
Homebridge.prototype.toList = function(opt) {
|
|
57
|
-
var list = [];
|
|
58
|
-
for (var index in this.accessories) {
|
|
59
|
-
var accessory = this.accessories[index];
|
|
60
|
-
list = list.concat(accessory.toList({
|
|
61
|
-
host: this.host,
|
|
62
|
-
port: this.port,
|
|
63
|
-
homebridge: this.homebridge,
|
|
64
|
-
id: this.id,
|
|
65
|
-
opt: opt
|
|
66
|
-
}));
|
|
67
|
-
// list.push(accessory.toList());
|
|
68
|
-
}
|
|
69
|
-
// debug("opt",opt,list.length);
|
|
70
|
-
return (list);
|
|
71
|
-
};
|
package/src/lib/Homebridges.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
// var debug = require('debug')('Homebridges');
|
|
2
|
-
var Homebridge = require('./Homebridge.js').Homebridge;
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
Homebridges: Homebridges
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
/*
|
|
9
|
-
* Homebridges -> Homebridge -> Accessory -> Service -> Characteristic
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
function Homebridges(devices) {
|
|
13
|
-
// debug("Homebridges", devices);
|
|
14
|
-
this.homebridges = [];
|
|
15
|
-
devices.forEach(function(element) {
|
|
16
|
-
var homebridge = new Homebridge(element);
|
|
17
|
-
this.homebridges.push(homebridge);
|
|
18
|
-
}.bind(this));
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Homebridges.toList - description
|
|
23
|
-
*
|
|
24
|
-
* @param {type} opt description
|
|
25
|
-
* @return {type} description
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
Homebridges.prototype.toList = function(opt) {
|
|
29
|
-
var list = [];
|
|
30
|
-
for (var index in this.homebridges) {
|
|
31
|
-
var homebridge = this.homebridges[index];
|
|
32
|
-
// list.push(homebridge.toList());
|
|
33
|
-
list = list.concat(homebridge.toList(opt));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
list.sort((a, b) => (a.sortName > b.sortName) ? 1 : ((b.sortName > a.sortName) ? -1 : 0));
|
|
37
|
-
// debug("opt",opt,list.length);
|
|
38
|
-
return (list);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/* {
|
|
42
|
-
"characteristics": [{
|
|
43
|
-
"aid": endpoint.aid,
|
|
44
|
-
"iid": endpoint.iid,
|
|
45
|
-
"ev": true
|
|
46
|
-
}]
|
|
47
|
-
};
|
|
48
|
-
*/
|
|
49
|
-
|
|
50
|
-
Homebridges.prototype.findDevice = function(node, opt) {
|
|
51
|
-
var list = [];
|
|
52
|
-
for (var index in this.homebridges) {
|
|
53
|
-
var homebridge = this.homebridges[index];
|
|
54
|
-
// list.push(homebridge.toList());
|
|
55
|
-
list = list.concat(homebridge.toList(opt));
|
|
56
|
-
}
|
|
57
|
-
return (list.find(x => x.uniqueId === node));
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
Homebridges.prototype.findDeviceByName = function(name, opt) {
|
|
61
|
-
var list = [];
|
|
62
|
-
for (var index in this.homebridges) {
|
|
63
|
-
var homebridge = this.homebridges[index];
|
|
64
|
-
// list.push(homebridge.toList());
|
|
65
|
-
list = list.concat(homebridge.toList(opt));
|
|
66
|
-
}
|
|
67
|
-
return (list.find(x => x.name === name));
|
|
68
|
-
};
|
package/src/lib/Service.js
DELETED
|
@@ -1,307 +0,0 @@
|
|
|
1
|
-
var debug = require('debug')('Service');
|
|
2
|
-
var Characteristic = require('./Characteristic.js').Characteristic;
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
Service: Service
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
/*
|
|
9
|
-
* Homebridges -> Homebridge -> Accessory -> Service -> Characteristic
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
/*
|
|
13
|
-
|
|
14
|
-
This is a typical Service
|
|
15
|
-
|
|
16
|
-
{
|
|
17
|
-
"iid": 8,
|
|
18
|
-
"type": "0000008A-0000-1000-8000-0026BB765291",
|
|
19
|
-
"characteristics": [{
|
|
20
|
-
"iid": 9,
|
|
21
|
-
"type": "00000023-0000-1000-8000-0026BB765291",
|
|
22
|
-
"perms": ["pr"],
|
|
23
|
-
"format": "string",
|
|
24
|
-
"value": "Cold Cellar",
|
|
25
|
-
"description": "Name"
|
|
26
|
-
}, {
|
|
27
|
-
"iid": 10,
|
|
28
|
-
"type": "00000011-0000-1000-8000-0026BB765291",
|
|
29
|
-
"perms": ["pr", "ev"],
|
|
30
|
-
"format": "float",
|
|
31
|
-
"value": 4.9,
|
|
32
|
-
"description": "Current Temperature",
|
|
33
|
-
"unit": "celsius",
|
|
34
|
-
"maxValue": 100,
|
|
35
|
-
"minValue": -100,
|
|
36
|
-
"minStep": 0.1
|
|
37
|
-
}, {
|
|
38
|
-
"iid": 11,
|
|
39
|
-
"type": "00000010-0000-1000-8000-0026BB765291",
|
|
40
|
-
"perms": ["pr", "ev"],
|
|
41
|
-
"format": "float",
|
|
42
|
-
"value": 51,
|
|
43
|
-
"description": "Current Relative Humidity",
|
|
44
|
-
"unit": "percentage",
|
|
45
|
-
"maxValue": 100,
|
|
46
|
-
"minValue": 0,
|
|
47
|
-
"minStep": 1
|
|
48
|
-
}, {
|
|
49
|
-
"iid": 12,
|
|
50
|
-
"type": "E863F10F-079E-48FF-8F27-9C2605A29F52",
|
|
51
|
-
"perms": ["pr", "ev"],
|
|
52
|
-
"format": "uint8",
|
|
53
|
-
"value": 1011,
|
|
54
|
-
"description": "Air Pressure",
|
|
55
|
-
"unit": "mbar",
|
|
56
|
-
"maxValue": 1200,
|
|
57
|
-
"minValue": 800,
|
|
58
|
-
"minStep": 1
|
|
59
|
-
}],
|
|
60
|
-
"primary": false,
|
|
61
|
-
"hidden": false
|
|
62
|
-
}
|
|
63
|
-
*/
|
|
64
|
-
|
|
65
|
-
function Service(devices, context) {
|
|
66
|
-
// debug("Service", JSON.stringify(devices));
|
|
67
|
-
this.iid = devices.iid;
|
|
68
|
-
this.type = devices.type.substring(0, 8);
|
|
69
|
-
this.service = _normalizeName(this.type);
|
|
70
|
-
this.aid = context.aid;
|
|
71
|
-
this.host = context.host;
|
|
72
|
-
this.port = context.port;
|
|
73
|
-
this.homebridge = context.homebridge;
|
|
74
|
-
this.id = context.id;
|
|
75
|
-
this.characteristics = [];
|
|
76
|
-
// Fix for homebridge 1.3.0
|
|
77
|
-
devices.characteristics.forEach(function (element) {
|
|
78
|
-
// var service = new Characteristic(element, this);
|
|
79
|
-
if (element.type.substring(0, 8) === '00000023' && element.description === "Name") {
|
|
80
|
-
this.name = element.value;
|
|
81
|
-
} else if (element.type.substring(0, 8) === '000000E3' && element.description === "Configured Name") {
|
|
82
|
-
this.configuredName = element.value;
|
|
83
|
-
} else {
|
|
84
|
-
// this.characteristics.push(service);
|
|
85
|
-
}
|
|
86
|
-
}.bind(this));
|
|
87
|
-
devices.characteristics.forEach(function (element) {
|
|
88
|
-
var service = new Characteristic(element, this);
|
|
89
|
-
if (element.type.substring(0, 8) === '00000023' && element.description === "Name") {
|
|
90
|
-
this.name = element.value;
|
|
91
|
-
} else if (element.type.substring(0, 8) === '000000E3' && element.description === "Configured Name") {
|
|
92
|
-
this.configuredName = element.value;
|
|
93
|
-
} else {
|
|
94
|
-
this.characteristics.push(service);
|
|
95
|
-
}
|
|
96
|
-
}.bind(this));
|
|
97
|
-
if (this.configuredName) {
|
|
98
|
-
this.name = this.configuredName;
|
|
99
|
-
}
|
|
100
|
-
// Uncomment to display services not defined
|
|
101
|
-
// if (!this.service) {
|
|
102
|
-
// console.log('Missing', devices);
|
|
103
|
-
// }
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
Service.prototype.toList = function (context) {
|
|
107
|
-
var descriptions;
|
|
108
|
-
var getCharacteristics;
|
|
109
|
-
var putCharacteristics = [];
|
|
110
|
-
var eventRegisters = [];
|
|
111
|
-
var characteristics = {};
|
|
112
|
-
var fullName = context.name;
|
|
113
|
-
|
|
114
|
-
if (this.name) {
|
|
115
|
-
// Fix for #30
|
|
116
|
-
if (context.manufacturer === "Nest" && (this.name === "Fan" || this.name === "Eco Mode")) {
|
|
117
|
-
fullName = context.name + " - " + this.name;
|
|
118
|
-
} else if (context.manufacturer === "Mitsubishi" && !fullName.includes(this.name)) {
|
|
119
|
-
fullName = context.name + " - " + this.name;
|
|
120
|
-
} else if (context.manufacturer === "Allterco") {
|
|
121
|
-
fullName = context.name + " - " + this.name;
|
|
122
|
-
} else {
|
|
123
|
-
context.name = this.name;
|
|
124
|
-
fullName = context.name;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
for (var index in this.characteristics) {
|
|
129
|
-
var characteristic = this.characteristics[index];
|
|
130
|
-
// debug("characteristic", characteristic)
|
|
131
|
-
// debug("perms", context.opt);
|
|
132
|
-
// debug("perms", (context.opt ? "perms" + context.opt.perms + characteristic.perms.includes(context.opt.perms) : "noperms"));
|
|
133
|
-
if (characteristic.type !== '00000023' && characteristic.perms && (context.opt ? characteristic.perms.includes(context.opt.perms) : true)) {
|
|
134
|
-
// debug("Yes", context.name, characteristic.description, characteristic.perms);
|
|
135
|
-
descriptions = (descriptions ? descriptions + ', ' : '') + characteristic.description.replace(/ /g, "").replace(/\./g, "_");
|
|
136
|
-
getCharacteristics = (getCharacteristics ? getCharacteristics + ',' : '') + characteristic.getCharacteristic;
|
|
137
|
-
// characteristics = (characteristics ? characteristics + ',' : '') + characteristic.characteristic;
|
|
138
|
-
characteristics = Object.assign(characteristics, characteristic.characteristic);
|
|
139
|
-
putCharacteristics = putCharacteristics.concat(characteristic.putCharacteristic);
|
|
140
|
-
eventRegisters = eventRegisters.concat(characteristic.eventRegister);
|
|
141
|
-
} else {
|
|
142
|
-
// debug("No", context.name, characteristic.description, characteristic.perms);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
if (this.service && descriptions) {
|
|
146
|
-
return ({
|
|
147
|
-
homebridge: context.homebridge,
|
|
148
|
-
host: context.host,
|
|
149
|
-
port: context.port,
|
|
150
|
-
id: context.id,
|
|
151
|
-
manufacturer: context.manufacturer,
|
|
152
|
-
aid: this.aid,
|
|
153
|
-
type: this.type,
|
|
154
|
-
name: fullName,
|
|
155
|
-
service: this.service,
|
|
156
|
-
fullName: fullName + ' - ' + this.service,
|
|
157
|
-
sortName: fullName + ':' + this.service,
|
|
158
|
-
uniqueId: context.homebridge + this.id + context.manufacturer + fullName + this.type,
|
|
159
|
-
descriptions: descriptions,
|
|
160
|
-
characteristics: characteristics,
|
|
161
|
-
getCharacteristics: getCharacteristics,
|
|
162
|
-
eventRegisters: eventRegisters
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
function _normalizeName(id) {
|
|
168
|
-
switch (id) {
|
|
169
|
-
case "00000111":
|
|
170
|
-
return ("Camera Control");
|
|
171
|
-
case "00000088":
|
|
172
|
-
return ("Stateful Programmable Switch");
|
|
173
|
-
case "000000A1":
|
|
174
|
-
return ("Bridge Configuration");
|
|
175
|
-
case "00000062":
|
|
176
|
-
return ("Bridging State");
|
|
177
|
-
case "00000055":
|
|
178
|
-
return ("Pairing");
|
|
179
|
-
case "000000A2":
|
|
180
|
-
return ("Protocol Information");
|
|
181
|
-
case "0000005A":
|
|
182
|
-
return ("Relay");
|
|
183
|
-
case "00000099":
|
|
184
|
-
return ("Time Information");
|
|
185
|
-
case "00000056":
|
|
186
|
-
return ("Tunneled BTLEAccessory Service");
|
|
187
|
-
case "00000129":
|
|
188
|
-
return ("Data Stream Transport Management");
|
|
189
|
-
case "00000122":
|
|
190
|
-
return ("Target Control Management");
|
|
191
|
-
case "00000125":
|
|
192
|
-
return ("Target Control");
|
|
193
|
-
case "00000127":
|
|
194
|
-
return ("Audio Stream Management");
|
|
195
|
-
case "00000133":
|
|
196
|
-
return ("Siri");
|
|
197
|
-
case "000000D8":
|
|
198
|
-
return ("Television");
|
|
199
|
-
case "000000D9":
|
|
200
|
-
return ("Input Source");
|
|
201
|
-
case "000000DA":
|
|
202
|
-
return ("Access Control");
|
|
203
|
-
case "0000003E":
|
|
204
|
-
return ("Accessory Information");
|
|
205
|
-
case "000000BB":
|
|
206
|
-
return ("Air Purifier");
|
|
207
|
-
case "0000008D":
|
|
208
|
-
return ("Air Quality Sensor");
|
|
209
|
-
case "00000096":
|
|
210
|
-
return ("Battery Service");
|
|
211
|
-
case "00000110":
|
|
212
|
-
return ("Camera RTPStream Management");
|
|
213
|
-
case "00000097":
|
|
214
|
-
return ("Carbon Dioxide Sensor");
|
|
215
|
-
case "0000007F":
|
|
216
|
-
return ("Carbon Monoxide Sensor");
|
|
217
|
-
case "00000080":
|
|
218
|
-
return ("Contact Sensor");
|
|
219
|
-
case "00000081":
|
|
220
|
-
return ("Door");
|
|
221
|
-
case "00000121":
|
|
222
|
-
return ("Doorbell");
|
|
223
|
-
case "00000040":
|
|
224
|
-
return ("Fan");
|
|
225
|
-
case "000000B7":
|
|
226
|
-
return ("Fan v2");
|
|
227
|
-
case "000000BA":
|
|
228
|
-
return ("Filter Maintenance");
|
|
229
|
-
case "000000D7":
|
|
230
|
-
return ("Faucet");
|
|
231
|
-
case "00000041":
|
|
232
|
-
return ("Garage Door Opener");
|
|
233
|
-
case "000000BC":
|
|
234
|
-
return ("Heater Cooler");
|
|
235
|
-
case "000000BD":
|
|
236
|
-
return ("Humidifier Dehumidifier");
|
|
237
|
-
case "00000082":
|
|
238
|
-
return ("Humidity Sensor");
|
|
239
|
-
case "000000CF":
|
|
240
|
-
return ("Irrigation System");
|
|
241
|
-
case "00000083":
|
|
242
|
-
return ("Leak Sensor");
|
|
243
|
-
case "00000084":
|
|
244
|
-
return ("Light Sensor");
|
|
245
|
-
case "00000043":
|
|
246
|
-
return ("Lightbulb");
|
|
247
|
-
case "00000044":
|
|
248
|
-
return ("Lock Management");
|
|
249
|
-
case "00000045":
|
|
250
|
-
return ("Lock Mechanism");
|
|
251
|
-
case "00000112":
|
|
252
|
-
return ("Microphone");
|
|
253
|
-
case "00000085":
|
|
254
|
-
return ("Motion Sensor");
|
|
255
|
-
case "00000086":
|
|
256
|
-
return ("Occupancy Sensor");
|
|
257
|
-
case "00000047":
|
|
258
|
-
return ("Outlet");
|
|
259
|
-
case "0000007E":
|
|
260
|
-
return ("Security System");
|
|
261
|
-
case "000000CC":
|
|
262
|
-
return ("Service Label");
|
|
263
|
-
case "000000B9":
|
|
264
|
-
return ("Slat");
|
|
265
|
-
case "00000087":
|
|
266
|
-
return ("Smoke Sensor");
|
|
267
|
-
case "00000228":
|
|
268
|
-
return ("Smart Speaker");
|
|
269
|
-
case "00000113":
|
|
270
|
-
return ("Speaker");
|
|
271
|
-
case "00000089":
|
|
272
|
-
return ("Stateless Programmable Switch");
|
|
273
|
-
case "00000049":
|
|
274
|
-
return ("Switch");
|
|
275
|
-
case "0000008A":
|
|
276
|
-
return ("Temperature Sensor");
|
|
277
|
-
case "0000004A":
|
|
278
|
-
return ("Thermostat");
|
|
279
|
-
case "000000D0":
|
|
280
|
-
return ("Valve");
|
|
281
|
-
case "0000008B":
|
|
282
|
-
return ("Window");
|
|
283
|
-
case "0000008C":
|
|
284
|
-
return ("Window Covering");
|
|
285
|
-
case "0000021A":
|
|
286
|
-
return ("Camera Operating Mode");
|
|
287
|
-
case "00000204":
|
|
288
|
-
return ("Camera Event Recording Management");
|
|
289
|
-
case "0000020A":
|
|
290
|
-
return ("WiFi Router");
|
|
291
|
-
case "0000020F":
|
|
292
|
-
return ("WiFi Satellite");
|
|
293
|
-
case "00000221":
|
|
294
|
-
return ("Power Management");
|
|
295
|
-
case "00000203":
|
|
296
|
-
return ("Transfer Transport Management");
|
|
297
|
-
case "00000012":
|
|
298
|
-
return ("Heartrate");
|
|
299
|
-
// Eve types
|
|
300
|
-
case "B77831FD":
|
|
301
|
-
return ("Air Pressure Service");
|
|
302
|
-
case "E863F007":
|
|
303
|
-
return ("History Service");
|
|
304
|
-
default:
|
|
305
|
-
debug("Missing HB Type", id);
|
|
306
|
-
}
|
|
307
|
-
}
|
package/src/lib/register.js
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
var debug = require('debug')('register');
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
registerEv: registerEv,
|
|
5
|
-
registerCt: registerCt
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
function registerEv(homebridge, devices) {
|
|
9
|
-
return register(homebridge, devices, 'ev');
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function registerCt(homebridge, devices) {
|
|
13
|
-
return register(homebridge, devices, 'pw');
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function register(homebridge, devices, perms) {
|
|
17
|
-
// debug('Discovered', devices);
|
|
18
|
-
var events = [];
|
|
19
|
-
devices.forEach(function(element) {
|
|
20
|
-
// debug('Device', element);
|
|
21
|
-
events = events.concat(_instance(element, perms));
|
|
22
|
-
});
|
|
23
|
-
return (events);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function _instance(instance, perms) {
|
|
27
|
-
// debug('Accessories', instance.accessories.accessories);
|
|
28
|
-
var events = [];
|
|
29
|
-
instance.accessories.accessories.forEach(function(accessory) {
|
|
30
|
-
// debug('Accessory', instance.instance.txt);
|
|
31
|
-
events = events.concat(_service({
|
|
32
|
-
"host": instance.ipAddress,
|
|
33
|
-
"port": instance.instance.port,
|
|
34
|
-
"homebridge": instance.instance.txt.md,
|
|
35
|
-
"id": instance.instance.txt.id,
|
|
36
|
-
"aid": accessory.aid
|
|
37
|
-
}, accessory.services, perms));
|
|
38
|
-
});
|
|
39
|
-
return (events);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function _service(context, accessory, perms) {
|
|
43
|
-
var events = [];
|
|
44
|
-
accessory.forEach(function(service) {
|
|
45
|
-
// debug('Service', service);
|
|
46
|
-
switch (service.type.substring(0, 8)) {
|
|
47
|
-
case "00000043": // Lightbulb
|
|
48
|
-
case "00000047": // Outlet
|
|
49
|
-
case "00000049": // Switch
|
|
50
|
-
case "00000040": // Fan
|
|
51
|
-
case "0000008C": // WindowCovering
|
|
52
|
-
case "0000008A": // TemperatureSensor
|
|
53
|
-
case "000000B7": // Fan 2 aka Dyson
|
|
54
|
-
case "00000041": // Garage Door
|
|
55
|
-
case "000000D0": // Valve aka sprinkler
|
|
56
|
-
// case "0000003E": // AccessoryInformation
|
|
57
|
-
case "0000004A": // Thermostat
|
|
58
|
-
case "00000080": // Contact Sensor
|
|
59
|
-
case "00000085": // Motion Sensor
|
|
60
|
-
case "00000111": // Camera
|
|
61
|
-
// debug('Supported Service', service);
|
|
62
|
-
events = events.concat(_characteristics(context, service, perms));
|
|
63
|
-
// debug("Events", events);
|
|
64
|
-
break;
|
|
65
|
-
case "0000003E": // AccessoryInformation
|
|
66
|
-
_name(context, service);
|
|
67
|
-
// debug("Events", events);
|
|
68
|
-
break;
|
|
69
|
-
default:
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
return (events);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function _characteristics(context, service, perms) {
|
|
76
|
-
// debug("Char", service, Array.isArray(service));
|
|
77
|
-
|
|
78
|
-
var events = [];
|
|
79
|
-
service.characteristics.forEach(function(characteristic) {
|
|
80
|
-
switch (characteristic.type.substring(0, 8)) {
|
|
81
|
-
case "00000020": // manufacturer
|
|
82
|
-
context.manufacturer = characteristic.value;
|
|
83
|
-
break;
|
|
84
|
-
case "00000023": // name
|
|
85
|
-
context.name = characteristic.value;
|
|
86
|
-
break;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (characteristic.perms.includes(perms)) {
|
|
90
|
-
context.iid = characteristic.iid;
|
|
91
|
-
context.function = characteristic.description;
|
|
92
|
-
context.service = service.type.substring(0, 8);
|
|
93
|
-
context.characteristic = characteristic.type.substring(0, 8);
|
|
94
|
-
context.deviceType = _normalizeName(context.service);
|
|
95
|
-
// debug("Register", context);
|
|
96
|
-
context.fullName = context.name + ' - ' + _normalizeName(context.service) + ' - ' + context.function;
|
|
97
|
-
context.sortName = context.name + ':' + _normalizeName(context.service) + ':' + context.function;
|
|
98
|
-
context.uniqueId = context.homebridge + context.id + context.manufacturer + context.name + context.service + context.characteristic;
|
|
99
|
-
// debug("Perms ", context.fullName, characteristic.perms);
|
|
100
|
-
events.push(JSON.parse(JSON.stringify(context)));
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
// debug("Char Events", events);
|
|
104
|
-
return (events);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function _name(context, service) {
|
|
108
|
-
// debug("Char", service, Array.isArray(service));
|
|
109
|
-
|
|
110
|
-
var manufacturer, name;
|
|
111
|
-
service.characteristics.forEach(function(characteristic) {
|
|
112
|
-
switch (characteristic.type.substring(0, 8)) {
|
|
113
|
-
case "00000020": // manufacturer
|
|
114
|
-
context.manufacturer = characteristic.value;
|
|
115
|
-
break;
|
|
116
|
-
case "00000023": // name
|
|
117
|
-
context.name = characteristic.value;
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
// debug("Char Events", events);
|
|
122
|
-
// return ({ "manufacturer": manufacturer, "name": name});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function _normalizeName(id) {
|
|
126
|
-
switch (id) {
|
|
127
|
-
case "00000043": // Lightbulb
|
|
128
|
-
return ("Lightbulb");
|
|
129
|
-
case "00000047": // Outlet
|
|
130
|
-
return ("Outlet");
|
|
131
|
-
case "00000049": // Switch
|
|
132
|
-
return ("Switch");
|
|
133
|
-
case "000000B7": // Fan 2 aka Dyson
|
|
134
|
-
case "00000040": // Fan
|
|
135
|
-
return ("Fan");
|
|
136
|
-
case "0000008C": // WindowCovering
|
|
137
|
-
return ("Blinds");
|
|
138
|
-
case "0000008A": // TemperatureSensor
|
|
139
|
-
return ("Temperature");
|
|
140
|
-
case "00000041": // Garage Door
|
|
141
|
-
return ("Garage Door");
|
|
142
|
-
case "000000D0": // Valve aka sprinkler
|
|
143
|
-
return ("Sprinkler");
|
|
144
|
-
// case "0000003E": // AccessoryInformation
|
|
145
|
-
case "0000004A": // Thermostat
|
|
146
|
-
return ("Thermostat");
|
|
147
|
-
case "00000080": // Contact Sensor
|
|
148
|
-
return ("Contact");
|
|
149
|
-
case "00000085": // Motion Sensor
|
|
150
|
-
return ("Motion");
|
|
151
|
-
case "00000111": // Camera
|
|
152
|
-
return ("Camera");
|
|
153
|
-
default:
|
|
154
|
-
debug("Missing HB Type", id);
|
|
155
|
-
}
|
|
156
|
-
}
|