homebridge-deconz 1.0.15 → 1.0.17

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.
@@ -135,6 +135,9 @@ class Resource {
135
135
  * @type {string}
136
136
  */
137
137
  this.id = mac
138
+ if (gateway.splitdevice[this.rtype]?.[this.rid]) {
139
+ this.id += '-' + endpoint
140
+ }
138
141
 
139
142
  /** The subtype of the corresponding HomeKit service.
140
143
  *
@@ -1007,6 +1007,7 @@ class Gateway extends AccessoryDelegate {
1007
1007
  this.context.fullState.config = config
1008
1008
  this.context.fullState.lights = await this.client.get('/lights')
1009
1009
  this.context.fullState.sensors = await this.client.get('/sensors')
1010
+ this.context.fullState.resourcelinks = await this.client.get('/resourcelinks')
1010
1011
  if (this.nDevicesByRtype.groups > 0) {
1011
1012
  this.context.fullState.groups = await this.client.get('/groups')
1012
1013
  this.context.fullState.groups[0] = await this.client.get('/groups/0')
@@ -1030,6 +1031,54 @@ class Gateway extends AccessoryDelegate {
1030
1031
  }
1031
1032
  }
1032
1033
 
1034
+ /* Analyse blacklist resourcelinks.
1035
+ */
1036
+ analyseResourcelinks (logUnsupported = false) {
1037
+ const warn = (logUnsupported ? this.warn : this.vdebug).bind(this)
1038
+ /** Blacklisted resources.
1039
+ *
1040
+ * Updated by
1041
+ * {@link DeconzAccessory.Gateway#analyseBlacklist analyseBlacklist()}.
1042
+ * @type {Object<string, boolean>}
1043
+ */
1044
+ this.blacklist = {
1045
+ lights: {},
1046
+ sensors: {}
1047
+ }
1048
+ this.splitdevice = {
1049
+ lights: {},
1050
+ sensors: {}
1051
+ }
1052
+ for (const key in this.context.fullState.resourcelinks) {
1053
+ const link = this.context.fullState.resourcelinks[key]
1054
+ if (
1055
+ link.name === 'homebridge-deconz' && link.links != null &&
1056
+ link.description != null
1057
+ ) {
1058
+ const type = link.description.toLowerCase()
1059
+ switch (type) {
1060
+ case 'migration':
1061
+ break
1062
+ case 'splitdevice':
1063
+ case 'blacklist':
1064
+ this.debug('/resourcelinks/%d: %d %s entries', key, link.links.length, type)
1065
+ for (const resource of link.links) {
1066
+ const rtype = resource.split('/')[1]
1067
+ const rid = resource.split('/')[2]
1068
+ if (this[type][rtype] == null) {
1069
+ warn('/resourcelinks/%d: %s: ignoring unsupported %s resource', key, resource, type)
1070
+ continue
1071
+ }
1072
+ this[type][rtype][rid] = true
1073
+ }
1074
+ break
1075
+ default:
1076
+ warn('/resourcelinks/%d: %s: ignoring unsupported resourcelink', key, type)
1077
+ }
1078
+ }
1079
+ }
1080
+ }
1081
+
1033
1082
  /** Analyse the peristed full state of the gateway,
1034
1083
  * adding, re-configuring, and deleting delegates for corresponding HomeKit
1035
1084
  * accessories and services.
@@ -1094,6 +1143,7 @@ class Gateway extends AccessoryDelegate {
1094
1143
  this.nDevicesByRtype = {}
1095
1144
 
1096
1145
  this.vdebug('analysing resources...')
1146
+ this.analyseResourcelinks(params.logUnsupported)
1097
1147
  for (const rtype of rtypes) {
1098
1148
  this.deviceByRidByRtype[rtype] = {}
1099
1149
  for (const rid in fullState[rtype]) {
@@ -1251,10 +1301,16 @@ class Gateway extends AccessoryDelegate {
1251
1301
  * unsupported resources.
1252
1302
  */
1253
1303
  analyseResource (rtype, rid, body, logUnsupported) {
1304
+ const warn = (logUnsupported ? this.warn : this.vdebug).bind(this)
1305
+ const debug = (logUnsupported ? this.debug : this.vdebug).bind(this)
1306
+
1254
1307
  const resource = new Deconz.Resource(this, rtype, rid, body)
1255
1308
  const { id, serviceName } = resource
1309
+ if (this.blacklist[rtype]?.[rid]) {
1310
+ debug('%s: /%s/%d: ignoring blacklisted resource', id, rtype, rid)
1311
+ return
1312
+ }
1256
1313
  if (id === this.id || serviceName === '') {
1257
- const debug = (logUnsupported ? this.debug : this.vdebug).bind(this)
1258
1314
  debug(
1259
1315
  '%s: /%s/%d: %s: ignoring unsupported %s type',
1260
1316
  id, rtype, rid, body.type, rtype
@@ -1262,7 +1318,6 @@ class Gateway extends AccessoryDelegate {
1262
1318
  return
1263
1319
  }
1264
1320
  if (serviceName == null) {
1265
- const warn = (logUnsupported ? this.warn : this.vdebug).bind(this)
1266
1321
  warn(
1267
1322
  '%s: /%s/%d: %s: ignoring unknown %s type',
1268
1323
  id, rtype, rid, body.type, rtype
@@ -236,7 +236,6 @@ class DeconzAccessory extends AccessoryDelegate {
236
236
  lowBatteryThreshold: this.servicesByServiceName?.Battery?.[0].values.lowBatteryThreshold,
237
237
  // offset: this.servicesByServiceName?.Temperature?.[0].values.offset,
238
238
  serviceName: this.values.serviceName,
239
- splitLight: undefined,
240
239
  venetianBlind: this.service.values.venetianBlind,
241
240
  useExternalTemperature: this.service.values.useExternalTemperature,
242
241
  wallSwitch: this.service.values.wallSwitch
@@ -15,7 +15,6 @@ class LightsResource extends DeconzService {
15
15
 
16
16
  this.updating = 0
17
17
  this.targetState = {}
18
- this.deferrals = []
19
18
  }
20
19
 
21
20
  addCharacteristicDelegates (params = {}) {
@@ -23,6 +23,15 @@ class Motion extends DeconzService.SensorsResource {
23
23
  value: false
24
24
  })
25
25
 
26
+ if (resource.body.state.distance !== undefined) {
27
+ this.addCharacteristicDelegate({
28
+ key: 'distance',
29
+ Characteristic: this.Characteristics.my.Distance,
30
+ unit: ' cm',
31
+ value: 0
32
+ })
33
+ }
34
+
26
35
  this.addCharacteristicDelegate({
27
36
  key: 'sensitivity',
28
37
  Characteristic: this.Characteristics.eve.Sensitivity
@@ -50,6 +59,32 @@ class Motion extends DeconzService.SensorsResource {
50
59
  }
51
60
  })
52
61
 
62
+ if (resource.body.config.detectionrange !== undefined) {
63
+ this.addCharacteristicDelegate({
64
+ key: 'detectionRange',
65
+ Characteristic: this.Characteristics.my.DetectionRange,
66
+ unit: ' cm',
67
+ value: 600
68
+ }).on('didSet', async (value, fromHomeKit) => {
69
+ if (fromHomeKit) {
70
+ const detectionrange = Math.max(0, Math.min(value, 600))
71
+ await this.putConfig({ detectionrange })
72
+ }
73
+ })
74
+ }
75
+
76
+ if (resource.body.config.resetpresence !== undefined) {
77
+ this.addCharacteristicDelegate({
78
+ key: 'reset',
79
+ Characteristic: this.Characteristics.my.Reset,
80
+ value: false
81
+ }).on('didSet', async (value, fromHomeKit) => {
82
+ if (fromHomeKit) {
83
+ await this.put('/config', { resetpresence: value })
84
+ }
85
+ })
86
+ }
87
+
53
88
  this.addCharacteristicDelegates()
54
89
 
55
90
  this.update(resource.body, resource.rpath)
@@ -59,6 +94,9 @@ class Motion extends DeconzService.SensorsResource {
59
94
  if (state.presence != null) {
60
95
  this.values.motion = state.presence
61
96
  }
97
+ if (state.distance != null) {
98
+ this.values.distance = state.distance
99
+ }
62
100
  if (state.vibration != null) {
63
101
  this.values.motion = state.vibration
64
102
  }
@@ -83,6 +121,12 @@ class Motion extends DeconzService.SensorsResource {
83
121
  ? this.Characteristics.eve.Sensitivity.LOW
84
122
  : this.Characteristics.eve.Sensitivity.MEDIUM
85
123
  }
124
+ if (config.detectionrange != null) {
125
+ this.values.detectionRange = config.detectionrange
126
+ }
127
+ if (config.resetpresence != null) {
128
+ this.values.reset = config.resetpresence
129
+ }
86
130
  super.updateConfig(config)
87
131
  }
88
132
  }
@@ -3,6 +3,8 @@
3
3
  //
4
4
  // Homebridge plugin for deCONZ.
5
5
 
6
+ import { timeout } from 'homebridge-lib'
7
+
6
8
  import { ApiClient } from 'hb-deconz-tools/ApiClient'
7
9
 
8
10
  import { DeconzService } from '../DeconzService/index.js'
@@ -13,9 +15,12 @@ const { dateToString } = ApiClient
13
15
  * @memberof DeconzService
14
16
  */
15
17
  class SensorsResource extends DeconzService {
16
- // constructor (accessory, resource, params) {
17
- // super(accessory, resource, params)
18
- // }
18
+ constructor (accessory, resource, params) {
19
+ super(accessory, resource, params)
20
+
21
+ this.updating = 0
22
+ this.targetConfig = {}
23
+ }
19
24
 
20
25
  addCharacteristicDelegates (params = {}) {
21
26
  if (!params.noLastUpdated) {
@@ -83,6 +88,34 @@ class SensorsResource extends DeconzService {
83
88
  return this.put('/config', { alert: 'select' })
84
89
  }
85
90
  }
91
+
92
+ // Collect config changes into a combined request.
93
+ async putConfig (config) {
94
+ for (const key in config) {
95
+ this.resource.body.config[key] = config[key]
96
+ this.targetConfig[key] = config[key]
97
+ }
98
+ return this._putConfig()
99
+ }
100
+
101
+ // Send the request (for the combined state changes) to the gateway.
102
+ async _putConfig () {
103
+ try {
104
+ if (this.platform.config.waitTimeUpdate > 0) {
105
+ this.updating++
106
+ await timeout(this.platform.config.waitTimeUpdate)
107
+ if (--this.updating > 0) {
108
+ return
109
+ }
110
+ }
111
+ const targetConfig = this.targetConfig
112
+ this.targetConfig = {}
113
+ await this.put('/config', targetConfig)
114
+ // this.recentlyUpdated = true
115
+ // await timeout(500)
116
+ // this.recentlyUpdated = false
117
+ } catch (error) { this.warn(error) }
118
+ }
86
119
  }
87
120
 
88
121
  DeconzService.SensorsResource = SensorsResource
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "ebaauw"
8
8
  ],
9
9
  "license": "Apache-2.0",
10
- "version": "1.0.15",
10
+ "version": "1.0.17",
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.27.6",
29
+ "deCONZ": "2.28.1",
30
30
  "homebridge": "^1.8.4||^2.0.0-beta",
31
31
  "node": "^20||^18"
32
32
  },
33
33
  "dependencies": {
34
34
  "hb-deconz-tools": "~2.0.3",
35
- "homebridge-lib": "~7.0.6"
35
+ "homebridge-lib": "~7.0.8"
36
36
  },
37
37
  "scripts": {
38
38
  "prepare": "standard && rm -rf out && jsdoc -c jsdoc.json",