homebridge-deconz 1.1.1 → 1.2.1
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/lib/Deconz/Resource.js +60 -56
- package/lib/DeconzAccessory/Gateway.js +52 -7
- package/lib/DeconzPlatform.js +0 -5
- package/package.json +6 -6
package/lib/Deconz/Resource.js
CHANGED
@@ -49,6 +49,25 @@ const hueTapMap = {
|
|
49
49
|
99: 0 // release 3 and 4
|
50
50
|
}
|
51
51
|
|
52
|
+
const hkEvent = {
|
53
|
+
SINGLE: 0x01,
|
54
|
+
DOUBLE: 0x02,
|
55
|
+
LONG: 0x04
|
56
|
+
}
|
57
|
+
|
58
|
+
const buttonEventMap = {
|
59
|
+
0: 0, // PRESS
|
60
|
+
1: hkEvent.LONG, // HOLD
|
61
|
+
2: hkEvent.SINGLE, // SHORT_RELEASE
|
62
|
+
3: hkEvent.LONG, // LONG_RELEASE
|
63
|
+
4: hkEvent.DOUBLE, // DOUBLE_PRESS
|
64
|
+
5: hkEvent.LONG, // TRIPLE_PRESS
|
65
|
+
6: hkEvent.LONG, // QUADRUPLE_PRESS
|
66
|
+
7: hkEvent.LONG, // SHAKE
|
67
|
+
8: hkEvent.DOUBLE, // DROP
|
68
|
+
9: 0 // TILT
|
69
|
+
}
|
70
|
+
|
52
71
|
const ancillaryControlMap = {
|
53
72
|
disarmed: 1002,
|
54
73
|
already_disarmed: 1002,
|
@@ -437,6 +456,30 @@ class Resource {
|
|
437
456
|
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
438
457
|
*/
|
439
458
|
patchLabel (gateway) {
|
459
|
+
// FIX_ME: use introspect until buttons and events are reported as capability
|
460
|
+
if (this.body.introspect?.buttons != null) {
|
461
|
+
this.capabilities._introspect = true
|
462
|
+
this.capabilities._buttons = {}
|
463
|
+
let dots = 0
|
464
|
+
for (const button in this.body.introspect.buttons) {
|
465
|
+
const label = this.body.introspect.buttons[button].name
|
466
|
+
this.capabilities._buttons[button] = { label, events: 0 }
|
467
|
+
if (label.includes(' Dot')) {
|
468
|
+
dots++
|
469
|
+
}
|
470
|
+
}
|
471
|
+
this.capabilities._namespace = dots === this.body.introspect.buttons.length
|
472
|
+
? gateway.Characteristics.hap.ServiceLabelNamespace.DOTS
|
473
|
+
: gateway.Characteristics.hap.ServiceLabelNamespace.ARABIC_NUMERALS
|
474
|
+
for (const value in this.body.introspect.values) {
|
475
|
+
const button = Math.round(value / 1000)
|
476
|
+
const event = value % 1000
|
477
|
+
if (this.capabilities._buttons[button] != null) {
|
478
|
+
this.capabilities._buttons[button].events |= buttonEventMap[event]
|
479
|
+
}
|
480
|
+
}
|
481
|
+
}
|
482
|
+
// End FIX_ME
|
440
483
|
const buttons = []
|
441
484
|
let dots = false
|
442
485
|
switch (this.manufacturer) {
|
@@ -555,11 +598,11 @@ class Resource {
|
|
555
598
|
buttons.push([1, 'Dim Up', SINGLE | LONG])
|
556
599
|
buttons.push([2, 'Dim Down', SINGLE | LONG])
|
557
600
|
break
|
558
|
-
case 'SOMRIG shortcut button':
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
601
|
+
// case 'SOMRIG shortcut button':
|
602
|
+
// dots = true
|
603
|
+
// buttons.push([1, '1', SINGLE | DOUBLE | LONG])
|
604
|
+
// buttons.push([2, '2', SINGLE | DOUBLE | LONG])
|
605
|
+
// break
|
563
606
|
case 'SYMFONISK Sound Controller':
|
564
607
|
if (this.cluster === '1000') {
|
565
608
|
buttons.push([1, 'Button', SINGLE | DOUBLE | LONG])
|
@@ -584,17 +627,6 @@ class Resource {
|
|
584
627
|
buttons.push([6, 'One Dot', SINGLE | DOUBLE | LONG])
|
585
628
|
buttons.push([7, 'Two Dots', SINGLE | DOUBLE | LONG])
|
586
629
|
break
|
587
|
-
case 'TRADFRI SHORTCUT Button':
|
588
|
-
buttons.push([1, 'Button', SINGLE | DOUBLE | LONG])
|
589
|
-
break
|
590
|
-
case 'TRADFRI on/off switch':
|
591
|
-
buttons.push([1, 'On', SINGLE | LONG])
|
592
|
-
buttons.push([2, 'Off', SINGLE | LONG])
|
593
|
-
break
|
594
|
-
case 'TRADFRI open/close remote':
|
595
|
-
buttons.push([1, 'Open', SINGLE | LONG])
|
596
|
-
buttons.push([2, 'Close', SINGLE | LONG])
|
597
|
-
break
|
598
630
|
case 'TRADFRI remote control':
|
599
631
|
buttons.push([1, 'Power', SINGLE])
|
600
632
|
buttons.push([2, 'Dim Up', SINGLE | LONG])
|
@@ -751,7 +783,7 @@ class Resource {
|
|
751
783
|
}
|
752
784
|
break
|
753
785
|
case 'lumi.sensor_switch': // Xiaomi Mi wireless switch
|
754
|
-
|
786
|
+
// fallthrough
|
755
787
|
case 'lumi.sensor_switch.aq3': // Xiaomi Aqara smart wireless switch with gyro
|
756
788
|
buttons.push([1, 'Button', SINGLE | DOUBLE | LONG])
|
757
789
|
break
|
@@ -1037,18 +1069,6 @@ class Resource {
|
|
1037
1069
|
break
|
1038
1070
|
}
|
1039
1071
|
break
|
1040
|
-
case '_TZ3000_mh9px7cq':
|
1041
|
-
switch (this.model) {
|
1042
|
-
case 'TS0044':
|
1043
|
-
buttons.push([1, 'Button 1', SINGLE | DOUBLE | LONG])
|
1044
|
-
buttons.push([2, 'Button 2', SINGLE | DOUBLE | LONG])
|
1045
|
-
buttons.push([3, 'Button 3', SINGLE | DOUBLE | LONG])
|
1046
|
-
buttons.push([4, 'Button 4', SINGLE | DOUBLE | LONG])
|
1047
|
-
break
|
1048
|
-
default:
|
1049
|
-
break
|
1050
|
-
}
|
1051
|
-
break
|
1052
1072
|
case '_TZ3000_pzui3skt':
|
1053
1073
|
switch (this.model) {
|
1054
1074
|
case 'TS0041': // Tuya 1-button switch
|
@@ -1234,30 +1254,6 @@ class Resource {
|
|
1234
1254
|
break
|
1235
1255
|
}
|
1236
1256
|
break
|
1237
|
-
case 'ubisys':
|
1238
|
-
switch (this.model) {
|
1239
|
-
case 'C4 (5504)':
|
1240
|
-
case 'C4-R (5604)':
|
1241
|
-
buttons.push([1, '1', SINGLE | LONG])
|
1242
|
-
buttons.push([2, '2', SINGLE | LONG])
|
1243
|
-
buttons.push([3, '3', SINGLE | LONG])
|
1244
|
-
buttons.push([4, '4', SINGLE | LONG])
|
1245
|
-
break
|
1246
|
-
case 'D1 (5503)':
|
1247
|
-
case 'D1-R (5603)':
|
1248
|
-
case 'S1-R (5601)':
|
1249
|
-
case 'S2 (5502)':
|
1250
|
-
case 'S2-R (5602)':
|
1251
|
-
buttons.push([1, '1', SINGLE | LONG])
|
1252
|
-
buttons.push([2, '2', SINGLE | LONG])
|
1253
|
-
break
|
1254
|
-
case 'S1 (5501)':
|
1255
|
-
buttons.push([1, '1', SINGLE | LONG])
|
1256
|
-
break
|
1257
|
-
default:
|
1258
|
-
break
|
1259
|
-
}
|
1260
|
-
break
|
1261
1257
|
default:
|
1262
1258
|
if (this.body.type === 'ZHAAncillaryControl') {
|
1263
1259
|
buttons.push([1, 'Disarm', SINGLE])
|
@@ -1279,13 +1275,20 @@ class Resource {
|
|
1279
1275
|
for (const button of buttons) {
|
1280
1276
|
this.capabilities.buttons[button[0]] = {
|
1281
1277
|
label: button[1],
|
1282
|
-
events: button[2]
|
1283
|
-
|
1278
|
+
events: button[2]
|
1279
|
+
}
|
1280
|
+
if (button[3]) {
|
1281
|
+
this.capabilities.buttons[button[0]].hasRepeat = button[3]
|
1284
1282
|
}
|
1285
1283
|
}
|
1286
1284
|
this.capabilities.namespace = dots
|
1287
1285
|
? gateway.Characteristics.hap.ServiceLabelNamespace.DOTS
|
1288
1286
|
: gateway.Characteristics.hap.ServiceLabelNamespace.ARABIC_NUMERALS
|
1287
|
+
} else if (this.capabilities._buttons != null) {
|
1288
|
+
this.capabilities.buttons = this.capabilities._buttons
|
1289
|
+
this.capabilities.namespace = this.capabilities._namespace
|
1290
|
+
delete this.capabilities._buttons
|
1291
|
+
delete this.capabilities._namespace
|
1289
1292
|
}
|
1290
1293
|
}
|
1291
1294
|
|
@@ -1304,7 +1307,8 @@ class Resource {
|
|
1304
1307
|
patchThermostat () {
|
1305
1308
|
if (
|
1306
1309
|
(this.manufacturer === 'Danfoss' && ['eTRV0100', 'eTRV0103'].includes(this.model)) ||
|
1307
|
-
(this.manufacturer === 'ELKO' && this.model === 'Super TR')
|
1310
|
+
(this.manufacturer === 'ELKO' && this.model === 'Super TR') ||
|
1311
|
+
(this.manufacturer === 'LUMI' && this.model === 'lumi.airrtc.agl001')
|
1308
1312
|
) {
|
1309
1313
|
this.capabilities.heatValue = 'heat'
|
1310
1314
|
} else {
|
@@ -78,12 +78,12 @@ class Gateway extends AccessoryDelegate {
|
|
78
78
|
if (this.context.settingsById == null) {
|
79
79
|
this.context.settingsById = {}
|
80
80
|
}
|
81
|
-
if (this.context.fullState != null) {
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
}
|
81
|
+
// if (this.context.fullState != null) {
|
82
|
+
// this.analyseFullState(this.context.fullState, {
|
83
|
+
// analyseOnly: true,
|
84
|
+
// logUnsupported: true
|
85
|
+
// })
|
86
|
+
// }
|
87
87
|
|
88
88
|
this.addPropertyDelegate({
|
89
89
|
key: 'apiKey',
|
@@ -997,8 +997,22 @@ class Gateway extends AccessoryDelegate {
|
|
997
997
|
} catch (error) {
|
998
998
|
fullState.alarmsystems = {}
|
999
999
|
}
|
1000
|
+
// FIX_ME: use introspect until buttons and events are reported as capability
|
1001
|
+
fullState.introspectByRid = {}
|
1002
|
+
for (const rid in fullState.sensors) {
|
1003
|
+
const sensor = fullState.sensors[rid]
|
1004
|
+
if (sensor.type === 'ZHASwitch') {
|
1005
|
+
try {
|
1006
|
+
fullState.introspectByRid[rid] = await this.client.get(
|
1007
|
+
'/devices/' + sensor.uniqueid + '/state/buttonevent/introspect'
|
1008
|
+
)
|
1009
|
+
} catch (error) { }
|
1010
|
+
}
|
1011
|
+
}
|
1012
|
+
// End FIX_ME
|
1000
1013
|
this.context.fullState = fullState
|
1001
1014
|
this.pollFullState = false
|
1015
|
+
await this.analyseFullState(this.context.fullState, { logUnsupported: true })
|
1002
1016
|
} else {
|
1003
1017
|
const config = await this.client.get('/config')
|
1004
1018
|
if (config.bridgeid === this.id && config.UTC == null) {
|
@@ -1027,8 +1041,8 @@ class Gateway extends AccessoryDelegate {
|
|
1027
1041
|
if (this.values.exposeSchedules) {
|
1028
1042
|
this.context.fullState.schedules = await this.client.get('/schedules')
|
1029
1043
|
}
|
1044
|
+
await this.analyseFullState(this.context.fullState)
|
1030
1045
|
}
|
1031
|
-
await this.analyseFullState(this.context.fullState)
|
1032
1046
|
} catch (error) {
|
1033
1047
|
this.error('poll error: %s', error)
|
1034
1048
|
} finally {
|
@@ -1316,8 +1330,39 @@ class Gateway extends AccessoryDelegate {
|
|
1316
1330
|
const warn = (logUnsupported ? this.warn : this.vdebug).bind(this)
|
1317
1331
|
const debug = (logUnsupported ? this.debug : this.vdebug).bind(this)
|
1318
1332
|
|
1333
|
+
// FIX_ME: use introspect until buttons and events are reported as capability
|
1334
|
+
if (this.context.fullState.introspectByRid?.[rid] != null) {
|
1335
|
+
body.introspect = this.context.fullState.introspectByRid[rid]
|
1336
|
+
}
|
1337
|
+
// End FIX_ME
|
1319
1338
|
const resource = new Deconz.Resource(this, rtype, rid, body)
|
1320
1339
|
const { id, serviceName } = resource
|
1340
|
+
// FIX_ME: check introspect against whitelist
|
1341
|
+
if (logUnsupported && resource.body.type === 'ZHASwitch') {
|
1342
|
+
if (!resource.capabilities._introspect) {
|
1343
|
+
this.warn(
|
1344
|
+
'%s: /sensors/%d: %s by %s: no introspect',
|
1345
|
+
id, rid, resource.model, resource.manufacturer
|
1346
|
+
)
|
1347
|
+
}
|
1348
|
+
} else if (resource.capabilities._buttons != null) {
|
1349
|
+
if (
|
1350
|
+
JSON.stringify(resource.capabilities._buttons) !==
|
1351
|
+
JSON.stringify(resource.capabilities.buttons) ||
|
1352
|
+
resource.capabilities._namespace !== resource.capabilities.namespace
|
1353
|
+
) {
|
1354
|
+
this.debug(
|
1355
|
+
'%s: /sensors/%d: %s by %s: whitelist vs introspect mismatch: %j',
|
1356
|
+
id, rid, resource.model, resource.manufacturer, resource.capabilities
|
1357
|
+
)
|
1358
|
+
} else {
|
1359
|
+
this.warn(
|
1360
|
+
'%s: /sensors/%d: %s by %s: whitelist matches introspect',
|
1361
|
+
id, rid, resource.model, resource.manufacturer
|
1362
|
+
)
|
1363
|
+
}
|
1364
|
+
}
|
1365
|
+
// End FIX_ME
|
1321
1366
|
if (this.blacklist[rtype]?.[rid]) {
|
1322
1367
|
debug('%s: /%s/%d: ignoring blacklisted resource', id, rtype, rid)
|
1323
1368
|
return
|
package/lib/DeconzPlatform.js
CHANGED
@@ -253,11 +253,6 @@ class DeconzPlatform extends Platform {
|
|
253
253
|
) {
|
254
254
|
this.gatewayMap[id] = new DeconzAccessory.Gateway(this, context)
|
255
255
|
}
|
256
|
-
} else {
|
257
|
-
const gateway = this.gatewayMap[context.gid]
|
258
|
-
if (gateway != null) {
|
259
|
-
gateway.addAccessory(id)
|
260
|
-
}
|
261
256
|
}
|
262
257
|
} catch (error) { this.error(error) }
|
263
258
|
}
|
package/package.json
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
"ebaauw"
|
8
8
|
],
|
9
9
|
"license": "Apache-2.0",
|
10
|
-
"version": "1.
|
10
|
+
"version": "1.2.1",
|
11
11
|
"keywords": [
|
12
12
|
"homebridge-plugin",
|
13
13
|
"homekit",
|
@@ -26,13 +26,13 @@
|
|
26
26
|
"ui": "cli/ui.js"
|
27
27
|
},
|
28
28
|
"engines": {
|
29
|
-
"deCONZ": "2.
|
30
|
-
"homebridge": "^1.
|
31
|
-
"node": "^22||^20
|
29
|
+
"deCONZ": "2.30.2",
|
30
|
+
"homebridge": "^1.10.0||^2.0.0-beta",
|
31
|
+
"node": "^22||^20"
|
32
32
|
},
|
33
33
|
"dependencies": {
|
34
|
-
"hb-deconz-tools": "~2.0.
|
35
|
-
"homebridge-lib": "~7.1.
|
34
|
+
"hb-deconz-tools": "~2.0.12",
|
35
|
+
"homebridge-lib": "~7.1.6"
|
36
36
|
},
|
37
37
|
"scripts": {
|
38
38
|
"prepare": "standard && rm -rf out && jsdoc -c jsdoc.json",
|