homebridge-deconz 0.1.14 → 0.1.16

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.
@@ -129,10 +129,17 @@ class Resource {
129
129
  * @type {boolean}
130
130
  */
131
131
  this.zigbee = true
132
- } else if (this.isMultiClip()) {
133
- const a = body.uniqueid.split('-')
134
- this.id = gateway.id + '-M' + a[0]
135
- this.subtype = a[1]
132
+ } else if (this.rtype === 'sensors') {
133
+ const { mac, endpoint, cluster } = Resource.parseUniqueid(body.uniqueid)
134
+ if (mac != null && endpoint != null && cluster != null) {
135
+ this.id = mac
136
+ this.subtype = endpoint + (cluster == null ? '' : '-' + cluster)
137
+ this.endpoint = endpoint
138
+ this.cluster = cluster
139
+ } else {
140
+ this.subtype = rtype[0].toUpperCase() + rid
141
+ this.id = gateway.id + '-' + this.subtype
142
+ }
136
143
  this.zigbee = false
137
144
  } else {
138
145
  this.subtype = rtype[0].toUpperCase() + rid
@@ -147,8 +154,8 @@ class Resource {
147
154
  * For virtual devices, this is the _Manufacturer_ for the gateway.
148
155
  * @type {string}
149
156
  */
150
- this.manufacturer = this.zigbee
151
- ? body.manufacturername
157
+ this.manufacturer = this.endpoint != null
158
+ ? body.manufacturername.replace(/\//g, '')
152
159
  : gateway.values.manufacturer
153
160
 
154
161
  /** The associated HomeKit _Model_.
@@ -158,7 +165,7 @@ class Resource {
158
165
  * For virtual devices, this is the `type` in the resource body.
159
166
  * @type {string}
160
167
  */
161
- this.model = this.zigbee ? body.modelid : body.type
168
+ this.model = this.endpoint != null ? body.modelid : body.type
162
169
 
163
170
  /** The associated HomeKit _Firmware Version_.
164
171
  *
@@ -166,7 +173,7 @@ class Resource {
166
173
  * resource body.
167
174
  * For virtual devices, this is the _Firmware Version_ for the gateway.
168
175
  */
169
- this.firmware = this.zigbee
176
+ this.firmware = this.endpoint != null
170
177
  ? body.swversion == null ? '0.0.0' : body.swversion
171
178
  : gateway.values.software
172
179
 
@@ -195,7 +202,7 @@ class Resource {
195
202
  if (this.rtype === 'groups') {
196
203
  return -1
197
204
  }
198
- if (this.rtype === 'lights' || this.isMultiClip()) {
205
+ if (this.rtype === 'lights') {
199
206
  return 0xFF - this.endpoint
200
207
  }
201
208
  return sensorsPrios.indexOf(this.serviceName)
@@ -327,36 +334,20 @@ class Resource {
327
334
  }
328
335
  }
329
336
 
330
- /** Check whether resource is a CLIP sensor for Homebridge deCONZ.
331
- * For these, we use the following conventions:
332
- * - Use `uniqueid` to indicate device ID and subtype;
333
- * - Use `swversion` to indicate readonly and range for `Flag` and `Status`.
334
- */
335
- isDeconzClip () {
336
- return this.rtype === 'sensors' &&
337
- this.body.type.startsWith('CLIP') &&
338
- this.body.modelid === this.body.type && (
339
- this.body.manufacturername === 'homebridge-deconz' ||
340
- this.body.manufacturername === 'homebridge-hue'
341
- )
342
- }
343
-
344
- isMultiClip () {
345
- return this.isDeconzClip() && /^[0-9]+-[0-9]+$/.test(this.body.uniqueid)
346
- }
347
-
348
337
  /** Patch a resource corresponding to a `Flag` service.
349
338
  */
350
339
  patchFlag () {
351
- if (this.isDeconzClip() && this.body.swversion === '0') {
352
- this.capabilities.readonly = true
340
+ if (this.endpoint != null && this.cluster === '0006') {
341
+ if (this.body.swversion === '0') {
342
+ this.capabilities.readonly = true
343
+ }
353
344
  }
354
345
  }
355
346
 
356
347
  /** Patch a resource corresponding to a `Status` service.
357
348
  */
358
349
  patchStatus () {
359
- if (this.isDeconzClip()) {
350
+ if (this.endpoint != null && this.cluster === '0012') {
360
351
  const a = this.body.swversion.split(',')
361
352
  const min = parseInt(a[0])
362
353
  const max = parseInt(a[1])
@@ -1059,6 +1050,16 @@ class Resource {
1059
1050
  }
1060
1051
  }
1061
1052
 
1053
+ /** Patch a resource corresponding to a `Motion` service.
1054
+ */
1055
+ patchMotion () {
1056
+ if (this.manufacturer === 'Aqara' && this.model === 'PS-S02D') {
1057
+ if (this.endpoint !== '01') {
1058
+ this.id += '-' + this.endpoint
1059
+ }
1060
+ }
1061
+ }
1062
+
1062
1063
  /** Patch a resource corresponding to a `Thermostat` service.
1063
1064
  */
1064
1065
  patchThermostat () {
@@ -637,7 +637,6 @@ class Gateway extends AccessoryDelegate {
637
637
  '%s: resetting after expose error: %s', id, this.exposeErrorById[id]
638
638
  )
639
639
  this.deleteAccessory(id)
640
- this.deleteService(id)
641
640
  }
642
641
  }
643
642
  }
@@ -672,7 +671,6 @@ class Gateway extends AccessoryDelegate {
672
671
  '%s: resetting after expose error: %s', id, this.exposeErrorById[id]
673
672
  )
674
673
  this.deleteAccessory(id)
675
- this.deleteService(id)
676
674
  }
677
675
 
678
676
  /** Assert that migration resourcelink exists and is valid.
@@ -921,6 +919,10 @@ class Gateway extends AccessoryDelegate {
921
919
  await this.wsClient.close()
922
920
  return
923
921
  }
922
+ if (config.fwversion === '0x00000000') {
923
+ this.warn('deCONZ not ready')
924
+ return
925
+ }
924
926
  this.context.fullState.config = config
925
927
  this.context.fullState.lights = await this.client.get('/lights')
926
928
  this.context.fullState.sensors = await this.client.get('/sensors')
@@ -964,16 +966,10 @@ class Gateway extends AccessoryDelegate {
964
966
  * {@link DeconzAccessory.Gateway#deleteAccessory deleteAccessory()} for
965
967
  * stale accessories, corresponding to devices that have been deleted from
966
968
  * the gateway, blacklisted, or excluded by device primary resource type.
967
- * 3. Analyse (pre-existing) _Device Settings_ services, calling
968
- * {@link DeconzAccessory.Gateway#deleteService deleteService()}
969
- * for stale services, corresponding to devices that have been deleted from
970
- * the gateway, un-blacklisted, or excluded by device primary resource type.
971
- * 4. Analysing supported devices with enabled device primary resource types,
972
- * calling {@link DeconzAccessory.Gateway#addAccessory addAccessory()} and
973
- * {@link DeconzAccessory.Gateway#deleteService deleteService()} for new
969
+ * 3. Analysing supported devices with enabled device primary resource types,
970
+ * calling {@link DeconzAccessory.Gateway#addAccessory addAccessory()} for new
974
971
  * _Device_ accessories, corresponding to devices added to the gateway,
975
972
  * un-blacklisted, or included by device primary resource type, and calling
976
- * {@link DeconzAccessory.Gateway#addService addService()} and
977
973
  * {@link DeconzAccessory.Gateway#deleteAccessory deleteAccessory()} for
978
974
  * accessories, corresponding to devices have been blacklisted.
979
975
  * @param {Object} fullState - The gateway full state, as returned by
@@ -1072,7 +1068,6 @@ class Gateway extends AccessoryDelegate {
1072
1068
  ) {
1073
1069
  delete this.context.settingsById[id]
1074
1070
  this.deleteAccessory(id)
1075
- // this.deleteService(id)
1076
1071
  changed = true
1077
1072
  } else {
1078
1073
  /** Emitted when the gateway has been polled.
@@ -5,6 +5,7 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ const { ServiceDelegate } = require('homebridge-lib')
8
9
  const DeconzAccessory = require('../DeconzAccessory')
9
10
 
10
11
  /** Delegate class for a HomeKit accessory, corresponding to a light device
@@ -32,6 +33,23 @@ class WarningDevice extends DeconzAccessory {
32
33
  this.createService(resource)
33
34
  }
34
35
 
36
+ const params = {}
37
+ if (this.servicesByServiceName.WarningDevice?.length === 1) {
38
+ params.switchOnDelegate = this.service.characteristicDelegate('on')
39
+ params.lastSwitchOnDelegate = this.service.addCharacteristicDelegate({
40
+ key: 'lastActivation',
41
+ Characteristic: this.Characteristics.eve.LastActivation,
42
+ silent: true
43
+ })
44
+ }
45
+ if (this.servicesByServiceName.Temperature?.length === 1) {
46
+ const service = this.servicesByServiceName.Temperature[0]
47
+ params.temperatureDelegate = service.characteristicDelegate('temperature')
48
+ }
49
+ if (Object.keys(params).length > 0) {
50
+ this.historyService = new ServiceDelegate.History(this, params)
51
+ }
52
+
35
53
  setImmediate(() => {
36
54
  this.debug('initialised')
37
55
  this.emit('initialised')
@@ -16,10 +16,15 @@ class Smoke extends DeconzService.SensorsResource {
16
16
  super(accessory, resource, params)
17
17
 
18
18
  this.addCharacteristicDelegate({
19
- key: 'fire',
19
+ key: 'smoke',
20
20
  Characteristic: this.Characteristics.hap.SmokeDetected
21
21
  })
22
22
 
23
+ this.addCharacteristicDelegate({
24
+ key: 'deviceStatus',
25
+ Characteristic: this.Characteristics.eve.ElgatoDeviceStatus
26
+ })
27
+
23
28
  super.addCharacteristicDelegates(params)
24
29
 
25
30
  this.update(resource.body, resource.rpath)
@@ -27,9 +32,17 @@ class Smoke extends DeconzService.SensorsResource {
27
32
 
28
33
  updateState (state) {
29
34
  if (state.fire != null || state.test != null) {
30
- this.values.fire = state.fire || state.test
35
+ this.values.smoke = state.fire
31
36
  ? this.Characteristics.hap.SmokeDetected.SMOKE_DETECTED
32
37
  : this.Characteristics.hap.SmokeDetected.SMOKE_NOT_DETECTED
38
+ let status = 0
39
+ if (state.fire) {
40
+ status |= this.Characteristics.eve.ElgatoDeviceStatus.SMOKE_DETECTED
41
+ }
42
+ if (state.test) {
43
+ status |= this.Characteristics.eve.ElgatoDeviceStatus.ALARM_TEST_ACTIVE
44
+ }
45
+ this.values.deviceStatus = status
33
46
  }
34
47
  super.updateState(state)
35
48
  }
@@ -9,7 +9,7 @@ const DeconzService = require('../DeconzService')
9
9
 
10
10
  class WarningDevice extends DeconzService.LightsResource {
11
11
  constructor (accessory, resource, params = {}) {
12
- params.Service = accessory.Services.hap.Outlet
12
+ params.Service = accessory.Services.hap.Switch
13
13
  super(accessory, resource, params)
14
14
 
15
15
  this.addCharacteristicDelegate({
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "displayName": "Homebridge deCONZ",
5
5
  "author": "Erik Baauw",
6
6
  "license": "Apache-2.0",
7
- "version": "0.1.14",
7
+ "version": "0.1.16",
8
8
  "keywords": [
9
9
  "homebridge-plugin",
10
10
  "homekit",
@@ -26,7 +26,7 @@
26
26
  "node": "^18.16.0"
27
27
  },
28
28
  "dependencies": {
29
- "homebridge-lib": "~6.3.15",
29
+ "homebridge-lib": "~6.3.17",
30
30
  "ws": "^8.13.0",
31
31
  "xml2js": "~0.5.0"
32
32
  },