homebridge-deconz 0.0.26 → 0.1.0

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.
Files changed (41) hide show
  1. package/config.schema.json +0 -7
  2. package/lib/Deconz/ApiError.js +12 -5
  3. package/lib/Deconz/ApiResponse.js +10 -7
  4. package/lib/Deconz/Resource.js +27 -4
  5. package/lib/DeconzAccessory/AirPurifier.js +0 -2
  6. package/lib/DeconzAccessory/Gateway.js +297 -147
  7. package/lib/DeconzAccessory/Light.js +32 -61
  8. package/lib/DeconzAccessory/Sensor.js +89 -1
  9. package/lib/DeconzAccessory/Thermostat.js +5 -8
  10. package/lib/DeconzAccessory/WarningDevice.js +2 -13
  11. package/lib/DeconzAccessory/WindowCovering.js +0 -2
  12. package/lib/DeconzAccessory/index.js +123 -13
  13. package/lib/DeconzPlatform.js +12 -20
  14. package/lib/DeconzService/AirPressure.js +8 -1
  15. package/lib/DeconzService/AirPurifier.js +2 -2
  16. package/lib/DeconzService/AirQuality.js +1 -1
  17. package/lib/DeconzService/Alarm.js +1 -1
  18. package/lib/DeconzService/Battery.js +21 -10
  19. package/lib/DeconzService/Button.js +1 -0
  20. package/lib/DeconzService/CarbonMonoxide.js +1 -1
  21. package/lib/DeconzService/Consumption.js +3 -1
  22. package/lib/DeconzService/Contact.js +1 -25
  23. package/lib/DeconzService/Daylight.js +22 -19
  24. package/lib/DeconzService/Flag.js +1 -1
  25. package/lib/DeconzService/Gateway.js +48 -0
  26. package/lib/DeconzService/Humidity.js +1 -1
  27. package/lib/DeconzService/Leak.js +1 -1
  28. package/lib/DeconzService/Light.js +121 -74
  29. package/lib/DeconzService/LightLevel.js +3 -3
  30. package/lib/DeconzService/LightsResource.js +24 -18
  31. package/lib/DeconzService/Motion.js +3 -9
  32. package/lib/DeconzService/Power.js +2 -1
  33. package/lib/DeconzService/Status.js +1 -1
  34. package/lib/DeconzService/WindowCovering.js +14 -4
  35. package/lib/DeconzService/index.js +14 -3
  36. package/package.json +6 -6
  37. package/lib/DeconzAccessory/Contact.js +0 -54
  38. package/lib/DeconzAccessory/Motion.js +0 -54
  39. package/lib/DeconzAccessory/Temperature.js +0 -63
  40. package/lib/DeconzService/DeviceSettings.js +0 -56
  41. package/lib/DeconzService/GatewaySettings.js +0 -175
@@ -39,6 +39,8 @@ class Consumption extends DeconzService.SensorsResource {
39
39
  silent: true
40
40
  })
41
41
  }
42
+
43
+ service.update(resource.body, resource.rpath)
42
44
  }
43
45
 
44
46
  static updateResourceState (service, state) {
@@ -61,7 +63,7 @@ class Consumption extends DeconzService.SensorsResource {
61
63
 
62
64
  super.addCharacteristicDelegates({ noLastUpdated: true })
63
65
 
64
- this.update(resource.body)
66
+ this.update(resource.body, resource.rpath)
65
67
  }
66
68
 
67
69
  updateState (state) {
@@ -20,33 +20,9 @@ class Contact extends DeconzService.SensorsResource {
20
20
  Characteristic: this.Characteristics.hap.ContactSensorState
21
21
  })
22
22
 
23
- this.addCharacteristicDelegate({
24
- key: 'timesOpened',
25
- Characteristic: this.Characteristics.eve.TimesOpened,
26
- value: 0
27
- })
28
-
29
- this.addCharacteristicDelegate({
30
- key: 'openDuration',
31
- Characteristic: this.Characteristics.eve.OpenDuration,
32
- value: 0
33
- })
34
-
35
- this.addCharacteristicDelegate({
36
- key: 'closedDuration',
37
- Characteristic: this.Characteristics.eve.ClosedDuration,
38
- value: 0
39
- })
40
-
41
- this.addCharacteristicDelegate({
42
- key: 'lastActivation',
43
- Characteristic: this.Characteristics.eve.LastActivation,
44
- silent: true
45
- })
46
-
47
23
  this.addCharacteristicDelegates({ noTampered: true })
48
24
 
49
- this.update(resource.body)
25
+ this.update(resource.body, resource.rpath)
50
26
  }
51
27
 
52
28
  updateState (state) {
@@ -8,7 +8,7 @@
8
8
  const DeconzService = require('../DeconzService')
9
9
  const Deconz = require('../Deconz')
10
10
 
11
- const { dateToString, lightLevelToLux } = Deconz.ApiClient
11
+ const { dateToString } = Deconz.ApiClient
12
12
 
13
13
  const daylightEvents = {
14
14
  100: { name: 'Solar Midnight', period: 'Night' },
@@ -27,15 +27,22 @@ const daylightEvents = {
27
27
  230: { name: 'Astronomical Dusk', period: 'Night' }
28
28
  }
29
29
 
30
+ // Eve uses the following thresholds:
31
+ const VERY_BRIGHT = 1000
32
+ const BRIGHT = 300
33
+ const NORMAL = 100
34
+ const DIM = 10
35
+ const DARK = 0
36
+
30
37
  const daylightPeriods = {
31
- Night: { lightlevel: 0, daylight: false, dark: true },
32
- 'Astronomical Twilight': { lightlevel: 100, daylight: false, dark: true },
33
- 'Nautical Twilight': { lightlevel: 1000, daylight: false, dark: true },
34
- Twilight: { lightlevel: 10000, daylight: false, dark: false },
35
- Sunrise: { lightlevel: 15000, daylight: true, dark: false },
36
- Sunset: { lightlevel: 20000, daylight: true, dark: false },
37
- 'Golden Hour': { lightlevel: 40000, daylight: true, dark: false },
38
- Day: { lightlevel: 65535, daylight: true, dark: false }
38
+ Night: { lightLevel: DARK, dark: true, daylight: false },
39
+ 'Astronomical Twilight': { lightLevel: DIM, dark: true, daylight: false },
40
+ 'Nautical Twilight': { lightLevel: DIM, dark: true, daylight: false },
41
+ Twilight: { lightLevel: NORMAL, dark: false, daylight: false },
42
+ Sunrise: { lightLevel: BRIGHT, dark: false, daylight: true },
43
+ Sunset: { lightLevel: BRIGHT, dark: false, daylight: true },
44
+ 'Golden Hour': { lightLevel: BRIGHT, dark: false, daylight: true },
45
+ Day: { lightLevel: VERY_BRIGHT, dark: false, daylight: true }
39
46
  }
40
47
 
41
48
  /**
@@ -47,7 +54,7 @@ class Daylight extends DeconzService.SensorsResource {
47
54
  super(accessory, resource, params)
48
55
 
49
56
  this.addCharacteristicDelegate({
50
- key: 'lightlevel',
57
+ key: 'lightLevel',
51
58
  Characteristic: this.Characteristics.hap.CurrentAmbientLightLevel,
52
59
  unit: ' lux'
53
60
  })
@@ -101,7 +108,7 @@ class Daylight extends DeconzService.SensorsResource {
101
108
  this.warn('%s: %s not configured', resource.rpath, resource.body.type)
102
109
  }
103
110
 
104
- this.update(resource.body)
111
+ this.update(resource.body, resource.rpath)
105
112
  }
106
113
 
107
114
  updateState (state) {
@@ -110,14 +117,10 @@ class Daylight extends DeconzService.SensorsResource {
110
117
  const { name, period } = daylightEvents[state.status]
111
118
  this.values.lastEvent = name
112
119
  this.values.period = period
113
- const { lightlevel } = daylightPeriods[period]
114
- this.values.lightlevel = lightLevelToLux(lightlevel)
115
- }
116
- if (state.dark != null) {
117
- this.values.dark = state.dark
118
- }
119
- if (state.daylight != null) {
120
- this.values.daylight = state.daylight
120
+ const { lightLevel, dark, daylight } = daylightPeriods[period]
121
+ this.values.lightLevel = lightLevel
122
+ this.values.dark = dark
123
+ this.values.daylight = daylight
121
124
  }
122
125
  if (state.sunrise != null) {
123
126
  this.values.sunrise = dateToString(state.sunrise)
@@ -38,7 +38,7 @@ class Flag extends DeconzService.SensorsResource {
38
38
 
39
39
  this.addCharacteristicDelegates()
40
40
 
41
- this.update(resource.body)
41
+ this.update(resource.body, resource.rpath)
42
42
  }
43
43
 
44
44
  updateState (state) {
@@ -0,0 +1,48 @@
1
+ // homebridge-deconz/lib/DeconzService/Gateway.js
2
+ // Copyright © 2022 Erik Baauw. All rights reserved.
3
+ //
4
+ // Homebridge plugin for deCONZ.
5
+
6
+ 'use strict'
7
+
8
+ const homebridgeLib = require('homebridge-lib')
9
+
10
+ /** Delegate class for a DeconzGateway service.
11
+ * @extends ServiceDelegate
12
+ * @memberof DeconzService
13
+ */
14
+ class Gateway extends homebridgeLib.ServiceDelegate {
15
+ constructor (gateway, params = {}) {
16
+ params.Service = gateway.Services.my.DeconzGateway
17
+ params.exposeConfiguredName = true
18
+ super(gateway, params)
19
+ this.gateway = gateway
20
+
21
+ this.addCharacteristicDelegate({
22
+ key: 'lastUpdated',
23
+ Characteristic: this.Characteristics.my.LastUpdated,
24
+ silent: true
25
+ })
26
+
27
+ this.addCharacteristicDelegate({
28
+ key: 'statusActive',
29
+ Characteristic: this.Characteristics.hap.StatusActive,
30
+ value: true,
31
+ silent: true
32
+ })
33
+
34
+ this.addCharacteristicDelegate({
35
+ key: 'transitionTime',
36
+ Characteristic: this.Characteristics.my.TransitionTime,
37
+ value: this.gateway.defaultTransitionTime
38
+ })
39
+ this.values.transitionTime = this.gateway.defaultTransitionTime
40
+ }
41
+
42
+ update (config) {
43
+ this.values.expose = true
44
+ this.values.lastUpdated = new Date().toString().slice(0, 24)
45
+ }
46
+ }
47
+
48
+ module.exports = Gateway
@@ -23,7 +23,7 @@ class Humidity extends DeconzService.SensorsResource {
23
23
 
24
24
  this.addCharacteristicDelegates()
25
25
 
26
- this.update(resource.body)
26
+ this.update(resource.body, resource.rpath)
27
27
  }
28
28
 
29
29
  updateState (state) {
@@ -22,7 +22,7 @@ class Leak extends DeconzService.SensorsResource {
22
22
 
23
23
  super.addCharacteristicDelegates()
24
24
 
25
- this.update(resource.body)
25
+ this.update(resource.body, resource.rpath)
26
26
  }
27
27
 
28
28
  updateState (state) {
@@ -8,6 +8,7 @@
8
8
  const homebridgeLib = require('homebridge-lib')
9
9
  const DeconzService = require('../DeconzService')
10
10
 
11
+ const { History } = homebridgeLib.ServiceDelegate
11
12
  const { timeout } = homebridgeLib
12
13
  const { xyToHsv, hsvToXy, ctToXy } = homebridgeLib.Colour
13
14
 
@@ -207,6 +208,7 @@ class Light extends DeconzService.LightsResource {
207
208
  .CharacteristicValueTransitionControl,
208
209
  silent: true,
209
210
  getter: async () => {
211
+ this.initAdaptiveLighting()
210
212
  return this.adaptiveLighting.generateControl()
211
213
  },
212
214
  setter: async (value) => {
@@ -238,81 +240,24 @@ class Light extends DeconzService.LightsResource {
238
240
  }
239
241
 
240
242
  if (this.resource.rtype === 'groups') {
241
- this.sceneServices = {}
242
- this.updateScenes(this.resource.body.scenes)
243
+ this.addCharacteristicDelegate({
244
+ key: 'exposeScenes',
245
+ value: true
246
+ })
247
+ if (this.values.exposeScenes) {
248
+ this.sceneServices = {}
249
+ this.updateScenes(this.resource.body.scenes)
250
+ }
243
251
  }
244
252
 
245
253
  if (this.capabilities.effects != null) {
246
- this.effectServices = []
247
254
  this.addCharacteristicDelegate({
248
- key: 'effect',
249
- value: -1,
250
- silent: true
251
- }).on('didSet', (value) => {
252
- for (const i in this.capabilities.effects) {
253
- this.effectServices[i].values.on = value === i
254
- }
255
+ key: 'exposeEffects',
256
+ value: true
255
257
  })
256
- for (const i in this.capabilities.effects) {
257
- const effect = this.capabilities.effects[i]
258
- const service = new homebridgeLib.ServiceDelegate(accessory, {
259
- name: this.resource.body.name + ' ' + effect,
260
- Service: this.Services.hap.Switch,
261
- subtype: this.subtype + '-E' + i
262
- })
263
- service.addCharacteristicDelegate({
264
- key: 'on',
265
- Characteristic: this.Characteristics.hap.On
266
- }).on('didSet', (value, fromHomeKit) => {
267
- if (fromHomeKit) {
268
- this.checkAdaptiveLighting()
269
- this.values.effect = value ? i : -1
270
- const newEffect = value
271
- ? effect.toLowerCase()
272
- : 'none'
273
- this.put({ effect: newEffect })
274
- }
275
- })
276
- this.effectServices.push(service)
258
+ if (this.values.exposeEffects) {
259
+ this.exposeEffects()
277
260
  }
278
- // if (this.capabilities.effectSpeed) {
279
- // this.addCharacteristicDelegate({
280
- // key: 'effectSpeed',
281
- // Characteristic: this.Characteristics.my.EffectSpeed,
282
- // value: 50
283
- // }).on('didSet', (value) => {
284
- // this.setEffectSpeed(value)
285
- // })
286
- // this.hk.effectColours = []
287
- // for (let i = 0; i <= 5; i++) {
288
- // const service = new this.Service.Lightbulb(
289
- // this.name + ' Effect Color ' + (i + 1), this.subtype + '-C' + i
290
- // )
291
- // service.addCharacteristicDelegate({
292
- // key: 'on',
293
- // Characteristic: this.Characteristics.hap.On,
294
- // value: true
295
- // }).on('didSet', (value) => {
296
- // this.setEffectOn(i, value)
297
- // })
298
- // service.addCharacteristicDelegate({
299
- // key: 'hue',
300
- // Characteristic: this.Characteristics.hap.Hue,
301
- // value: i * 60
302
- // }).on('didSet', (value) => {
303
- // this.setEffectHue(i, value)
304
- // })
305
- // service.addCharacteristicDelegate({
306
- // key: 'saturation',
307
- // Characteristic: this.Characteristics.hap.Saturation,
308
- // value: 100
309
- // }).on('didSet', (value) => {
310
- // this.setEffectSat(i, value)
311
- // })
312
- // this.effectServices.push(service)
313
- // }
314
- // }
315
- // this.checkEffect(this.obj.state.effect)
316
261
  }
317
262
 
318
263
  this.settings = {
@@ -322,6 +267,100 @@ class Light extends DeconzService.LightsResource {
322
267
  }
323
268
  }
324
269
 
270
+ exposeEffects () {
271
+ this.effectServices = {}
272
+ this.addCharacteristicDelegate({
273
+ key: 'effect',
274
+ value: -1,
275
+ silent: true
276
+ }).on('didSet', (value) => {
277
+ for (const i in this.capabilities.effects) {
278
+ this.effectServices[i].values.on = value === i
279
+ }
280
+ })
281
+ for (const id in this.capabilities.effects) {
282
+ const effect = this.capabilities.effects[id]
283
+ const service = new homebridgeLib.ServiceDelegate(this.accessoryDelegate, {
284
+ name: this.resource.body.name + ' ' + effect,
285
+ Service: this.Services.hap.Lightbulb,
286
+ subtype: this.subtype + '-E' + id,
287
+ exposeConfiguredName: true
288
+ })
289
+ service.addCharacteristicDelegate({
290
+ key: 'on',
291
+ Characteristic: this.Characteristics.hap.On
292
+ }).on('didSet', (value, fromHomeKit) => {
293
+ service.values.lastActivation =
294
+ this.accessoryDelegate.historyService.lastActivationValue(History.now())
295
+ if (fromHomeKit) {
296
+ this.checkAdaptiveLighting()
297
+ this.values.effect = value ? id : -1
298
+ const newEffect = value
299
+ ? effect.toLowerCase()
300
+ : 'none'
301
+ this.put({ effect: newEffect })
302
+ }
303
+ })
304
+ service.addCharacteristicDelegate({
305
+ key: 'index',
306
+ Characteristic: this.Characteristics.hap.ServiceLabelIndex,
307
+ value: Number(id) + 1
308
+ })
309
+ service.addCharacteristicDelegate({
310
+ key: 'lastActivation',
311
+ Characteristic: this.Characteristics.eve.LastActivation,
312
+ silent: true
313
+ })
314
+ this.effectServices[id] = service
315
+
316
+ this.characteristicDelegate('configuredName')
317
+ .on('didSet', (value) => {
318
+ for (const id in this.capabilities.effects) {
319
+ this.effectServices[id].values.configuredName = value +
320
+ ' ' + this.capabilities.effects[id]
321
+ }
322
+ })
323
+ }
324
+ // if (this.capabilities.effectSpeed) {
325
+ // this.addCharacteristicDelegate({
326
+ // key: 'effectSpeed',
327
+ // Characteristic: this.Characteristics.my.EffectSpeed,
328
+ // value: 50
329
+ // }).on('didSet', (value) => {
330
+ // this.setEffectSpeed(value)
331
+ // })
332
+ // this.hk.effectColours = []
333
+ // for (let i = 0; i <= 5; i++) {
334
+ // const service = new this.Service.Lightbulb(
335
+ // this.name + ' Effect Color ' + (i + 1), this.subtype + '-C' + i
336
+ // )
337
+ // service.addCharacteristicDelegate({
338
+ // key: 'on',
339
+ // Characteristic: this.Characteristics.hap.On,
340
+ // value: true
341
+ // }).on('didSet', (value) => {
342
+ // this.setEffectOn(i, value)
343
+ // })
344
+ // service.addCharacteristicDelegate({
345
+ // key: 'hue',
346
+ // Characteristic: this.Characteristics.hap.Hue,
347
+ // value: i * 60
348
+ // }).on('didSet', (value) => {
349
+ // this.setEffectHue(i, value)
350
+ // })
351
+ // service.addCharacteristicDelegate({
352
+ // key: 'saturation',
353
+ // Characteristic: this.Characteristics.hap.Saturation,
354
+ // value: 100
355
+ // }).on('didSet', (value) => {
356
+ // this.setEffectSat(i, value)
357
+ // })
358
+ // this.effectServices.push(service)
359
+ // }
360
+ // }
361
+ // this.checkEffect(this.obj.state.effect)
362
+ }
363
+
325
364
  updateState (state) {
326
365
  this.initAdaptiveLighting()
327
366
  let updateAdaptiveLighting = false
@@ -399,8 +438,9 @@ class Light extends DeconzService.LightsResource {
399
438
  if (this.sceneServices[scene.id] == null) {
400
439
  const service = new homebridgeLib.ServiceDelegate(this.accessoryDelegate, {
401
440
  name: this.resource.body.name + ' ' + scene.name,
402
- Service: this.Services.hap.Switch,
403
- subtype: this.subtype + '-S' + scene.id
441
+ Service: this.Services.hap.Lightbulb,
442
+ subtype: this.subtype + '-S' + scene.id,
443
+ exposeConfiguredName: true
404
444
  })
405
445
  service.addCharacteristicDelegate({
406
446
  key: 'on',
@@ -418,8 +458,15 @@ class Light extends DeconzService.LightsResource {
418
458
  service.values.on = false
419
459
  }
420
460
  })
461
+ service.addCharacteristicDelegate({
462
+ key: 'index',
463
+ Characteristic: this.Characteristics.hap.ServiceLabelIndex,
464
+ value: Number(scene.id) + 1
465
+ })
421
466
  this.sceneServices[scene.id] = service
422
467
  }
468
+ this.sceneServices[scene.id].values.configuredName =
469
+ this.resource.body.name + ' ' + scene.name
423
470
  }
424
471
  for (const id in this.scenesServices) {
425
472
  if (sceneById[id] == null) {
@@ -452,13 +499,13 @@ class Light extends DeconzService.LightsResource {
452
499
  async updateAdaptiveLighting () {
453
500
  if (
454
501
  this.adaptiveLighting == null || // not supported
455
- this.values.activeTransitionCount === 0 || // disabled
456
- !this.values.on // light is off
502
+ this.values.activeTransitionCount === 0 // disabled
503
+ // !this.values.on // light is off
457
504
  ) {
458
505
  return
459
506
  }
460
507
  const ct = this.adaptiveLighting.getCt(
461
- this.values.brightness * this.platform.config.brightnessAdjustment
508
+ this.values.brightness * this.gateway.values.brightnessAdjustment
462
509
  )
463
510
  if (ct == null) {
464
511
  this.warn('adaptive lighting: cannot compute Color Temperature')
@@ -19,7 +19,7 @@ class LightLevel extends DeconzService.SensorsResource {
19
19
  super(accessory, resource, params)
20
20
 
21
21
  this.addCharacteristicDelegate({
22
- key: 'lightlevel',
22
+ key: 'lightLevel',
23
23
  Characteristic: this.Characteristics.hap.CurrentAmbientLightLevel,
24
24
  unit: ' lux'
25
25
  })
@@ -36,12 +36,12 @@ class LightLevel extends DeconzService.SensorsResource {
36
36
 
37
37
  this.addCharacteristicDelegates()
38
38
 
39
- this.update(resource.body)
39
+ this.update(resource.body, resource.rpath)
40
40
  }
41
41
 
42
42
  updateState (state) {
43
43
  if (state.lightlevel != null) {
44
- this.values.lightlevel = lightLevelToLux(state.lightlevel)
44
+ this.values.lightLevel = lightLevelToLux(state.lightlevel)
45
45
  }
46
46
  if (state.dark != null) {
47
47
  this.values.dark = state.dark
@@ -15,7 +15,7 @@ const { timeout } = homebridgeLib
15
15
  class LightsResource extends DeconzService {
16
16
  constructor (accessory, resource, params) {
17
17
  super(accessory, resource, params)
18
- this.rpath += resource.rtype === 'groups' ? '/action' : '/state'
18
+ this.rpathState = this.rpath + (resource.rtype === 'groups' ? '/action' : '/state')
19
19
 
20
20
  this.updating = 0
21
21
  this.targetState = {}
@@ -23,16 +23,18 @@ class LightsResource extends DeconzService {
23
23
  }
24
24
 
25
25
  addCharacteristicDelegates (params = {}) {
26
- this.addCharacteristicDelegate({
27
- key: 'lastSeen',
28
- Characteristic: this.Characteristics.my.LastSeen,
29
- silent: true
30
- })
26
+ if (this.resource.rtype !== 'groups') {
27
+ this.addCharacteristicDelegate({
28
+ key: 'lastSeen',
29
+ Characteristic: this.Characteristics.my.LastSeen,
30
+ silent: true
31
+ })
31
32
 
32
- this.addCharacteristicDelegate({
33
- key: 'statusFault',
34
- Characteristic: this.Characteristics.hap.StatusFault
35
- })
33
+ this.addCharacteristicDelegate({
34
+ key: 'statusFault',
35
+ Characteristic: this.Characteristics.hap.StatusFault
36
+ })
37
+ }
36
38
  }
37
39
 
38
40
  updateState (state) {
@@ -43,24 +45,28 @@ class LightsResource extends DeconzService {
43
45
  }
44
46
  }
45
47
 
48
+ updateConfig (config) {
49
+ }
50
+
46
51
  async identify () {
47
52
  if (this.capabilities.alert) {
48
53
  if (this.capabilities.breathe) {
49
- await this.client.put(this.rpath, { alert: 'breathe' })
50
- await timeout(1500)
51
- await this.client.put(this.rpath, { alert: 'stop' })
54
+ await this.put({ alert: 'breathe' })
55
+ await timeout(1000)
56
+ await this.put({ alert: 'stop' })
57
+ } else {
58
+ await this.put({ alert: 'select' })
52
59
  }
53
- await this.put(this.rpath, { alert: 'select' })
54
60
  }
55
61
  }
56
62
 
57
63
  // Collect changes into a combined request.
58
- put (state) {
64
+ async put (state) {
59
65
  for (const key in state) {
60
66
  this.resource.body.state[key] = state[key]
61
67
  this.targetState[key] = state[key]
62
68
  }
63
- this._put()
69
+ return this._put()
64
70
  }
65
71
 
66
72
  // Send the request (for the combined changes) to the gateway.
@@ -96,8 +102,8 @@ class LightsResource extends DeconzService {
96
102
  targetState.transitiontime = 0
97
103
  }
98
104
  }
99
- this.debug('PUT %s %j', this.rpath, targetState)
100
- await this.client.put(this.rpath, targetState)
105
+ this.debug('PUT %s %j', this.rpathState, targetState)
106
+ await this.client.put(this.rpathState, targetState)
101
107
  this.recentlyUpdated = true
102
108
  await timeout(500)
103
109
  this.recentlyUpdated = false
@@ -15,13 +15,13 @@ class Motion extends DeconzService.SensorsResource {
15
15
  params.Service = accessory.Services.hap.MotionSensor
16
16
  super(accessory, resource, params)
17
17
 
18
- this.durationKey = resource.body.config.delay !== null ? 'delay' : 'duration'
18
+ this.durationKey = resource.body.config.delay != null ? 'delay' : 'duration'
19
19
  this.sensitivitymax = resource.body.config.sensitivitymax
20
20
 
21
21
  this.addCharacteristicDelegate({
22
22
  key: 'motion',
23
23
  Characteristic: this.Characteristics.hap.MotionDetected,
24
- value: 0
24
+ value: false
25
25
  })
26
26
 
27
27
  this.addCharacteristicDelegate({
@@ -52,15 +52,9 @@ class Motion extends DeconzService.SensorsResource {
52
52
  }
53
53
  })
54
54
 
55
- this.addCharacteristicDelegate({
56
- key: 'lastActivation',
57
- Characteristic: this.Characteristics.eve.LastActivation,
58
- silent: true
59
- })
60
-
61
55
  this.addCharacteristicDelegates()
62
56
 
63
- this.update(resource.body)
57
+ this.update(resource.body, resource.rpath)
64
58
  }
65
59
 
66
60
  updateState (state) {
@@ -46,6 +46,7 @@ class Power extends DeconzService.SensorsResource {
46
46
  silent: true
47
47
  })
48
48
  }
49
+ service.update(resource.body, resource.rpath)
49
50
  }
50
51
 
51
52
  static updateResourceState (service, state) {
@@ -71,7 +72,7 @@ class Power extends DeconzService.SensorsResource {
71
72
 
72
73
  super.addCharacteristicDelegates({ noLastUpdated: true })
73
74
 
74
- this.update(resource.body)
75
+ this.update(resource.body, resource.rpath)
75
76
  }
76
77
 
77
78
  updateState (state) {
@@ -39,7 +39,7 @@ class Status extends DeconzService.SensorsResource {
39
39
 
40
40
  this.addCharacteristicDelegates()
41
41
 
42
- this.update(resource.body)
42
+ this.update(resource.body, resource.rpath)
43
43
  }
44
44
 
45
45
  updateState (state) {
@@ -15,6 +15,12 @@ class WindowCovering extends DeconzService.LightsResource {
15
15
  params.Service = accessory.Services.hap.WindowCovering
16
16
  super(accessory, resource, params)
17
17
 
18
+ this.addCharacteristicDelegate({
19
+ key: 'venetianBlind',
20
+ value: false,
21
+ silent: true
22
+ })
23
+
18
24
  this.addCharacteristicDelegate({
19
25
  key: 'currentPosition',
20
26
  Characteristic: this.Characteristics.hap.CurrentPosition,
@@ -47,7 +53,7 @@ class WindowCovering extends DeconzService.LightsResource {
47
53
  this.values.positionState = this.Characteristics.hap.PositionState.STOPPED
48
54
  })
49
55
 
50
- if (this.venetianBlind) {
56
+ if (this.values.venetianBlind) {
51
57
  this.addCharacteristicDelegate({
52
58
  key: 'closeUpwards',
53
59
  Characteristic: this.Characteristics.my.CloseUpwards
@@ -55,7 +61,9 @@ class WindowCovering extends DeconzService.LightsResource {
55
61
  if (!fromHomeKit) {
56
62
  return
57
63
  }
58
- await this.setPosition()
64
+ if (this.values.currentPosition !== 100) {
65
+ await this.setPosition()
66
+ }
59
67
  })
60
68
  }
61
69
 
@@ -100,7 +108,7 @@ class WindowCovering extends DeconzService.LightsResource {
100
108
 
101
109
  async setPosition () {
102
110
  let lift = 100 - this.values.targetPosition // % closed --> % open
103
- if (this.venetianBlind) {
111
+ if (this.values.venetianBlind) {
104
112
  if (this.values.closeUpwards) {
105
113
  lift *= -1
106
114
  }
@@ -121,7 +129,9 @@ class WindowCovering extends DeconzService.LightsResource {
121
129
  if (state.lift != null) {
122
130
  let position = Math.round(state.lift / 5) * 5
123
131
  let closeUpwards
124
- if (this.venetianBlind) {
132
+ if (this.values.venetianBlind) {
133
+ position *= 2
134
+ position -= 100
125
135
  if (position < 0) {
126
136
  position *= -1
127
137
  closeUpwards = true