homebridge-deconz 0.1.9 → 0.1.10

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.
@@ -30,51 +30,6 @@ const sensorsPrios = [
30
30
 
31
31
  // =============================================================================
32
32
 
33
- // See: http://www.developers.meethue.com/documentation/supported-lights
34
-
35
- const hueGamutType = { // Color gamut per light model.
36
- A: { // Color Lights
37
- r: [0.7040, 0.2960],
38
- g: [0.2151, 0.7106],
39
- b: [0.1380, 0.0800]
40
- },
41
- B: { // Extended Color Lights
42
- r: [0.6750, 0.3220],
43
- g: [0.4090, 0.5180],
44
- b: [0.1670, 0.0400]
45
- },
46
- C: { // next gen Extended Color Lights
47
- r: [0.6920, 0.3080],
48
- g: [0.1700, 0.7000],
49
- b: [0.1530, 0.0480]
50
- }
51
- }
52
-
53
- const hueGamutTypeByModel = {
54
- LCT001: 'B', // Hue bulb A19
55
- LCT002: 'B', // Hue Spot BR30
56
- LCT003: 'B', // Hue Spot GU10
57
- LCT007: 'B', // Hue bulb A19
58
- LCT010: 'C', // Hue bulb A19
59
- LCT011: 'C', // Hue BR30
60
- LCT012: 'C', // Hue Color Candle
61
- LCT014: 'C', // Hue bulb A19
62
- LCT015: 'C', // Hue bulb A19
63
- LCT016: 'C', // Hue bulb A19
64
- LLC005: 'A', // Living Colors Gen3 Bloom, Aura
65
- LLC006: 'A', // Living Colors Gen3 Iris
66
- LLC007: 'A', // Living Colors Gen3 Bloom, Aura
67
- LLC010: 'A', // Hue Living Colors Iris
68
- LLC011: 'A', // Hue Living Colors Bloom
69
- LLC012: 'A', // Hue Living Colors Bloom
70
- LLC013: 'A', // Disney Living Colors
71
- LLC014: 'A', // Living Colors Gen3 Bloom, Aura
72
- LLC020: 'C', // Hue Go
73
- LLM001: 'B', // Color Light Module
74
- LST001: 'A', // Hue LightStrips
75
- LST002: 'C' // Hue LightStrips Plus
76
- }
77
-
78
33
  const hueTapMap = {
79
34
  34: 1002, // press 1
80
35
  16: 2002, // press 2
@@ -240,9 +195,7 @@ class Resource {
240
195
  this.capabilities.ctMin = cap.color.ct.min
241
196
  }
242
197
  if (cap.color.effects != null && cap.color.effects.length > 2) {
243
- this.capabilities.effects = cap.color.effects.slice(2).map((effect) => {
244
- return effect[0].toUpperCase() + effect.slice(1)
245
- })
198
+ this.capabilities.effects = cap.color.effects.slice(2)
246
199
  }
247
200
  if (cap.color.xy != null) {
248
201
  this.capabilities.gamut = {
@@ -386,34 +339,7 @@ class Resource {
386
339
  */
387
340
  patchLight (gateway) {
388
341
  switch (this.manufacturer) {
389
- case 'Busch-Jaeger':
390
- // See: https://www.busch-jaeger.de/en/products/product-solutions/dimmer/busch-radio-controlled-dimmer-zigbee-light-link/
391
- if (
392
- this.model === 'RM01' && // 6715 U-500 with 6736-84.
393
- this.capabilities.bri && this.body.type === 'On/Off light' // Issue #241
394
- ) {
395
- gateway.vdebug(
396
- '%s: ignoring state.bri for %s', this.rpath, this.body.type
397
- )
398
- this.capabilities.bri = false
399
- }
400
- break
401
- case 'dresden elektronik':
402
- // See: https://www.dresden-elektronik.de/funktechnik/solutions/wireless-light-control/wireless-ballasts/?L=1
403
- this.capabilities.computesXy = true
404
- break
405
- case 'FeiBit':
406
- if (this.model === 'FNB56-SKT1EHG1.2') { // issue #361
407
- this.body.type = 'On/Off plug-in unit'
408
- }
409
- break
410
342
  case 'GLEDOPTO':
411
- // See: https://www.led-trading.de/zigbee-kompatibel-controller-led-lichtsteuerung
412
- this.capabilities.gamut = {
413
- r: [0.7006, 0.2993],
414
- g: [0.1387, 0.8148],
415
- b: [0.1510, 0.0227]
416
- }
417
343
  if (this.model === 'GLEDOPTO') { // Issue #244
418
344
  if (
419
345
  this.endpoint === '0A' &&
@@ -444,37 +370,6 @@ class Resource {
444
370
  gateway.vdebug('%s: set model to %j', this.rpath, this.model)
445
371
  }
446
372
  break
447
- case 'IKEA of Sweden':
448
- // See: http://www.ikea.com/us/en/catalog/categories/departments/lighting/smart_lighting/
449
- this.capabilities.gamut = defaultGamut // Issue #956
450
- this.capabilities.noTransition = true
451
- if (this.model === 'TRADFRI bulb E27 CWS 806lm') {
452
- this.capabilities.computesXy = true
453
- this.capabilities.gamut = {
454
- r: [0.68, 0.31],
455
- g: [0.11, 0.82],
456
- b: [0.13, 0.04]
457
- }
458
- }
459
- break
460
- case 'innr':
461
- // See: https://shop.innrlighting.com/en/shop
462
- this.capabilities.gamut = { // Issue #152
463
- r: [0.8817, 0.1033],
464
- g: [0.2204, 0.7758],
465
- b: [0.0551, 0.1940]
466
- }
467
- if (this.model === 'SP 120') { // smart plug
468
- this.capabilities.bri = false
469
- }
470
- break
471
- case 'LEDVANCE':
472
- this.capabilities.gamut = {
473
- r: [0.6972, 0.3027],
474
- g: [0.1737, 0.6991],
475
- b: [0.1227, 0.0959]
476
- }
477
- break
478
373
  case 'LIDL Livarno Lux':
479
374
  this.capabilities.ctMax = 454 // 2200 K
480
375
  this.capabilities.ctMin = 153 // 6500 K
@@ -489,36 +384,6 @@ class Resource {
489
384
  ]
490
385
  }
491
386
  break
492
- case 'MLI': // Issue #439
493
- this.capabilities.gamut = {
494
- r: [0.68, 0.31],
495
- g: [0.11, 0.82],
496
- b: [0.13, 0.04]
497
- }
498
- if (this.capabilities.colorLoop) {
499
- this.capabilities.effects = [
500
- 'Sunset', 'Party', 'Worklight', 'Campfire', 'Romance', 'Nightlight'
501
- ]
502
- }
503
- break
504
- case 'OSRAM':
505
- this.capabilities.gamut = {
506
- r: [0.6850, 0.3149],
507
- g: [0.1780, 0.7253],
508
- b: [0.1241, 0.0578]
509
- }
510
- break
511
- case 'Philips':
512
- case 'Signify Netherlands B.V.':
513
- // See: http://www.developers.meethue.com/documentation/supported-lights
514
- this.manufacturer = 'Signify Netherlands B.V.'
515
- this.capabilities.breathe = true
516
- this.capabilities.computesXy = true
517
- if (this.body.capabilities == null) {
518
- const gamut = hueGamutTypeByModel[this.model] || 'C'
519
- this.capabilities.gamut = hueGamutType[gamut]
520
- }
521
- break
522
387
  default:
523
388
  break
524
389
  }
@@ -784,12 +649,16 @@ class Resource {
784
649
  }
785
650
  }
786
651
  break
787
- case 'lumi.sensor_86sw1': // Xiaomi wall switch (single button)
788
652
  case 'lumi.ctrl_ln1.aq1':
653
+ case 'lumi.sensor_86sw1': // Xiaomi wall switch (single button).
654
+ case 'lumi.switch.l1aeu1': // Xiaomi Aqara H1, see #1149.
655
+ case 'lumi.switch.n1aeu1': // Xiaomi Aqara H1, see #1149.
789
656
  buttons.push([1, 'Button', SINGLE | DOUBLE])
790
657
  break
791
- case 'lumi.sensor_86sw2': // Xiaomi wall switch (two buttons)
792
658
  case 'lumi.ctrl_ln2.aq1':
659
+ case 'lumi.sensor_86sw2': // Xiaomi wall switch (two buttons).
660
+ case 'lumi.switch.l2aeu1': // Xiaomi Aqara H2, see #1149.
661
+ case 'lumi.switch.n2aeu1': // Xiaomi Aqara H2, see #1149.
793
662
  buttons.push([1, 'Left', SINGLE | DOUBLE])
794
663
  buttons.push([2, 'Right', SINGLE | DOUBLE])
795
664
  buttons.push([3, 'Both', SINGLE | DOUBLE])
@@ -66,19 +66,19 @@ class Light extends DeconzAccessory {
66
66
  })
67
67
  }
68
68
  if (this.serviceByServiceName.Consumption != null) {
69
- params.consumptionDelegate = this.service.characteristicDelegate('totalConsumption')
70
- if (this.service.values.currentConsumption === undefined) {
71
- // Current Consumption to be computed by history if not exposed by device
72
- params.computedPowerDelegate = this.service.addCharacteristicDelegate({
73
- key: 'currentConsumption',
74
- Characteristic: this.Characteristics.eve.CurrentConsumption,
69
+ params.totalConsumptionDelegate = this.service.characteristicDelegate('totalConsumption')
70
+ if (this.service.values.consumption === undefined) {
71
+ // Power to be computed by history if not exposed by device
72
+ params.computedConsumptionDelegate = this.service.addCharacteristicDelegate({
73
+ key: 'consumption',
74
+ Characteristic: this.Characteristics.eve.Consumption,
75
75
  unit: ' W'
76
76
  })
77
77
  }
78
78
  } else if (this.serviceByServiceName.Power != null) {
79
- params.powerDelegate = this.service.characteristicDelegate('currentConsumption')
79
+ params.consumptionDelegate = this.service.characteristicDelegate('consumption')
80
80
  // Total Consumption to be computed by history
81
- params.computedConsumptionDelegate = this.service.addCharacteristicDelegate({
81
+ params.computedTotalConsumptionDelegate = this.service.addCharacteristicDelegate({
82
82
  key: 'totalConsumption',
83
83
  Characteristic: this.Characteristics.eve.TotalConsumption,
84
84
  unit: ' kWh'
@@ -139,7 +139,12 @@ class DeconzAccessory extends AccessoryDelegate {
139
139
  this.debug('%s: params: %j', resource.rpath, params)
140
140
 
141
141
  let service
142
- if (params.serviceName === 'Battery') {
142
+ if (params.serviceName === 'AirQuality') {
143
+ service = this.serviceByServiceName.AirQuality
144
+ if (service != null) {
145
+ service.addResource(resource)
146
+ }
147
+ } else if (params.serviceName === 'Battery') {
143
148
  service = this.serviceByServiceName.Battery
144
149
  } else if (params.serviceName === 'Consumption') {
145
150
  service = this.serviceByServiceName.Outlet ||
@@ -5,73 +5,104 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ const Deconz = require('../Deconz')
8
9
  const DeconzService = require('../DeconzService')
9
10
 
11
+ const { dateToString } = Deconz.ApiClient
12
+
10
13
  /**
11
14
  * @memberof DeconzService
12
15
  */
13
16
  class AirQuality extends DeconzService.SensorsResource {
14
- constructor (accessory, resource, params = {}) {
15
- params.Service = accessory.Services.hap.AirQualitySensor
16
- super(accessory, resource, params)
17
-
18
- this.addCharacteristicDelegate({
19
- key: 'airQuality',
20
- Characteristic: this.Characteristics.hap.AirQuality
21
- })
17
+ static addResource (service, resource) {
18
+ if (service.values.airQuality === undefined) {
19
+ service.addCharacteristicDelegate({
20
+ key: 'airQuality',
21
+ Characteristic: service.Characteristics.hap.AirQuality
22
+ })
23
+ }
22
24
 
23
25
  if (resource.body.state.airqualityppb !== undefined) {
24
- this.addCharacteristicDelegate({
26
+ service.addCharacteristicDelegate({
25
27
  key: 'vocDensity',
26
- Characteristic: this.Characteristics.hap.VOCDensity,
28
+ Characteristic: service.Characteristics.hap.VOCDensity,
27
29
  unit: ' µg/m³',
28
30
  props: { minValue: 0, maxValue: 65535, minStep: 1 }
29
31
  })
30
32
  }
31
33
 
32
34
  if (resource.body.state.pm2_5 !== undefined) {
33
- this.addCharacteristicDelegate({
34
- key: 'pm2_5Density',
35
- Characteristic: this.Characteristics.hap.PM2_5Density,
35
+ service.addCharacteristicDelegate({
36
+ key: 'pm25Density',
37
+ Characteristic: service.Characteristics.hap.PM2_5Density,
36
38
  unit: ' µg/m³',
37
39
  props: { minValue: 0, maxValue: 65535, minStep: 1 }
38
40
  })
39
41
  }
40
42
 
41
- if (params.linkedServiceDelegate == null) {
42
- super.addCharacteristicDelegates()
43
+ if (service.values.lastUpdated === undefined) {
44
+ service.addCharacteristicDelegate({
45
+ key: 'lastUpdated',
46
+ Characteristic: service.Characteristics.my.LastUpdated,
47
+ silent: true
48
+ })
43
49
  }
44
50
 
45
- this.update(resource.body, resource.rpath)
51
+ AirQuality.updateResourceState(service, resource.body.state)
46
52
  }
47
53
 
48
- airQualityValue (value) {
54
+ static airQualityValue (service, value) {
49
55
  switch (value) {
50
56
  case 'excellent':
51
- return this.Characteristics.hap.AirQuality.EXCELLENT
57
+ return service.Characteristics.hap.AirQuality.EXCELLENT
52
58
  case 'good':
53
- return this.Characteristics.hap.AirQuality.GOOD
59
+ return service.Characteristics.hap.AirQuality.GOOD
54
60
  case 'moderate':
55
- return this.Characteristics.hap.AirQuality.FAIR
61
+ return service.Characteristics.hap.AirQuality.FAIR
56
62
  case 'poor':
57
- return this.Characteristics.hap.AirQuality.INFERIOR
63
+ return service.Characteristics.hap.AirQuality.INFERIOR
58
64
  case 'unhealthy':
59
- return this.Characteristics.hap.AirQuality.POOR
65
+ return service.Characteristics.hap.AirQuality.POOR
60
66
  default:
61
- return this.Characteristics.hap.AirQuality.UNKNOWN
67
+ return service.Characteristics.hap.AirQuality.UNKNOWN
62
68
  }
63
69
  }
64
70
 
65
- updateState (state) {
66
- if (state.airquality != null) {
67
- this.values.airQuality = this.airQualityValue(state.airquality)
68
- }
71
+ static updateResourceState (service, state) {
69
72
  if (state.airqualityppb != null) {
70
- this.values.vocDensity = Math.round(state.airqualityppb * 4.57)
73
+ service.values.vocDensity = Math.round(state.airqualityppb * 4.57)
74
+ if (state.airquality != null) {
75
+ service.values.airQuality = AirQuality.airQualityValue(
76
+ service, state.airquality
77
+ )
78
+ }
71
79
  }
72
80
  if (state.pm2_5 != null) {
73
- this.values.pm2_5Density = state.pm2_5
81
+ service.values.pm25Density = state.pm2_5
82
+ if (state.airquality != null && service.values.vocDensity === undefined) {
83
+ service.values.airQuality = AirQuality.airQualityValue(
84
+ service, state.airquality
85
+ )
86
+ }
87
+ }
88
+ if (state.lastupdated != null) {
89
+ service.values.lastUpdated = dateToString(state.lastupdated)
74
90
  }
91
+ }
92
+
93
+ constructor (accessory, resource, params = {}) {
94
+ params.Service = accessory.Services.hap.AirQualitySensor
95
+ super(accessory, resource, params)
96
+
97
+ AirQuality.addResource(this, resource)
98
+
99
+ super.addCharacteristicDelegates({ noLastUpdated: true })
100
+
101
+ this.update(resource.body, resource.rpath)
102
+ }
103
+
104
+ updateState (state) {
105
+ AirQuality.updateResourceState(this, state)
75
106
  super.updateState(state)
76
107
  }
77
108
  }
@@ -23,11 +23,11 @@ class Consumption extends DeconzService.SensorsResource {
23
23
 
24
24
  if (
25
25
  resource.body.state.power !== undefined &&
26
- service.values.currentConsumption === undefined
26
+ service.values.consumption === undefined
27
27
  ) {
28
28
  service.addCharacteristicDelegate({
29
- key: 'currentConsumption',
30
- Characteristic: service.Characteristics.eve.CurrentConsumption,
29
+ key: 'consumption',
30
+ Characteristic: service.Characteristics.eve.Consumption,
31
31
  unit: ' W'
32
32
  })
33
33
  }
@@ -40,7 +40,7 @@ class Consumption extends DeconzService.SensorsResource {
40
40
  })
41
41
  }
42
42
 
43
- service.update(resource.body, resource.rpath)
43
+ Consumption.updateResourceState(service, resource.body.state)
44
44
  }
45
45
 
46
46
  static updateResourceState (service, state) {
@@ -48,7 +48,7 @@ class Consumption extends DeconzService.SensorsResource {
48
48
  service.values.totalConsumption = state.consumption / 1000
49
49
  }
50
50
  if (state.power != null) {
51
- service.values.currentConsumption = state.power
51
+ service.values.consumption = state.power
52
52
  }
53
53
  if (state.lastupdated != null) {
54
54
  service.values.lastUpdated = dateToString(state.lastupdated)
@@ -8,14 +8,31 @@
8
8
  const { AdaptiveLighting, Colour, ServiceDelegate, timeout } = require('homebridge-lib')
9
9
  const DeconzService = require('../DeconzService')
10
10
 
11
- const { xyToHsv, hsvToXy, ctToXy } = Colour
12
- const { History } = ServiceDelegate
11
+ const { defaultGamut, xyToHsv, hsvToXy, ctToXy } = Colour
13
12
 
14
13
  class Light extends DeconzService.LightsResource {
15
14
  constructor (accessory, resource, params = {}) {
16
15
  params.Service = accessory.Services.hap.Lightbulb
17
16
  super(accessory, resource, params)
18
17
 
18
+ this.capabilities = {
19
+ on: this.resource.body.state.on !== undefined,
20
+ bri: this.resource.body.state.bri !== undefined,
21
+ ct: this.resource.body.state.ct !== undefined,
22
+ hs: this.resource.body.state.xy === undefined &&
23
+ this.resource.body.state.hue !== undefined,
24
+ xy: this.resource.body.state.xy !== undefined
25
+ }
26
+ if (this.resource.body?.capabilities?.color?.effects != null) {
27
+ const effects = this.resource.body.capabilities.color.effects
28
+ if (effects.length > 1 && effects[1] === 'colorloop') {
29
+ this.capabilities.colorLoop = true
30
+ this.capabilities.effects = effects.length > 2
31
+ } else if (effects.length > 1) {
32
+ this.capabilities.effects = effects.length > 1
33
+ }
34
+ }
35
+
19
36
  this.addCharacteristicDelegate({
20
37
  key: 'on',
21
38
  Characteristic: this.Characteristics.hap.On,
@@ -81,11 +98,7 @@ class Light extends DeconzService.LightsResource {
81
98
  })
82
99
  }
83
100
 
84
- if (
85
- this.resource.body.config != null &&
86
- this.resource.body.config.color != null &&
87
- this.resource.body.config.color.execute_if_off != null
88
- ) {
101
+ if (this.resource.body?.config?.color?.execute_if_off != null) {
89
102
  this.addCharacteristicDelegate({
90
103
  key: 'colorExecuteIfOff',
91
104
  value: this.resource.body.config.color.execute_if_off
@@ -93,19 +106,25 @@ class Light extends DeconzService.LightsResource {
93
106
  }
94
107
 
95
108
  if (this.capabilities.ct) {
109
+ if (
110
+ this.resource.body?.capabilities?.color?.ct?.min == null ||
111
+ this.resource.body?.capabilities?.color?.ct?.max == null
112
+ ) {
113
+ this.warn('using default ct range')
114
+ }
115
+ const ctMin = this.resource.body?.capabilities?.color?.ct?.min ?? 153
116
+ const ctMax = this.resource.body?.capabilities?.color?.ct?.max ?? 500
96
117
  this.colorTemperatureDelegate = this.addCharacteristicDelegate({
97
118
  key: 'colorTemperature',
98
119
  Characteristic: this.Characteristics.hap.ColorTemperature,
99
120
  unit: ' mired',
100
121
  props: {
101
- minValue: this.capabilities.ctMin,
102
- maxValue: this.capabilities.ctMax
122
+ minValue: ctMin,
123
+ maxValue: ctMax
103
124
  },
104
125
  value: this.resource.body.state.ct
105
126
  }).on('didSet', (value, fromHomeKit) => {
106
- const ct = Math.max(
107
- this.capabilities.ctMin, Math.min(value, this.capabilities.ctMax)
108
- )
127
+ const ct = Math.max(ctMin, Math.min(value, ctMax))
109
128
  if (fromHomeKit) {
110
129
  this.checkAdaptiveLighting()
111
130
  this.put({ ct })
@@ -120,6 +139,21 @@ class Light extends DeconzService.LightsResource {
120
139
  }
121
140
 
122
141
  if (this.capabilities.xy) {
142
+ if (
143
+ this.resource.body?.capabilities?.color?.xy?.blue == null ||
144
+ this.resource.body?.capabilities?.color?.xy?.green == null ||
145
+ this.resource.body?.capabilities?.color?.xy?.red == null
146
+ ) {
147
+ this.warn('using default xy gamut')
148
+ this.capabilities.gamut = defaultGamut
149
+ } else {
150
+ this.capabilities.gamut = {
151
+ r: this.resource.body.capabilities.color.xy.red,
152
+ g: this.resource.body.capabilities.color.xy.green,
153
+ b: this.resource.body.capabilities.color.xy.blue
154
+ }
155
+ }
156
+
123
157
  this.addCharacteristicDelegate({
124
158
  key: 'hue',
125
159
  Characteristic: this.Characteristics.hap.Hue,
@@ -261,13 +295,7 @@ class Light extends DeconzService.LightsResource {
261
295
  }
262
296
 
263
297
  if (this.capabilities.effects != null) {
264
- this.addCharacteristicDelegate({
265
- key: 'exposeEffects',
266
- value: true
267
- })
268
- if (this.values.exposeEffects) {
269
- this.exposeEffects()
270
- }
298
+ this.exposeEffects()
271
299
  }
272
300
 
273
301
  if (this.resource.rtype === 'lights') {
@@ -279,57 +307,29 @@ class Light extends DeconzService.LightsResource {
279
307
  }
280
308
 
281
309
  exposeEffects () {
282
- this.effectServices = {}
283
- this.addCharacteristicDelegate({
284
- key: 'effect',
285
- value: -1,
310
+ const effectString = this.addCharacteristicDelegate({
311
+ key: 'effectString',
312
+ value: 'none',
286
313
  silent: true
287
- }).on('didSet', (value) => {
288
- for (const i in this.capabilities.effects) {
289
- this.effectServices[i].values.on = value === i
290
- }
291
314
  })
292
- for (const id in this.capabilities.effects) {
293
- const effect = this.capabilities.effects[id]
294
- const service = new ServiceDelegate(this.accessoryDelegate, {
295
- name: this.resource.body.name + ' ' + effect,
296
- Service: this.Services.hap.Lightbulb,
297
- subtype: (this.subtype == null ? 'E' : this.subtype + '-E') + id
298
- })
299
- service.addCharacteristicDelegate({
300
- key: 'on',
301
- Characteristic: this.Characteristics.hap.On
302
- }).on('didSet', (value, fromHomeKit) => {
303
- service.values.lastActivation =
304
- this.accessoryDelegate.historyService.lastActivationValue(History.now())
305
- if (fromHomeKit) {
306
- this.checkAdaptiveLighting()
307
- this.values.effect = value ? id : -1
308
- const newEffect = value
309
- ? effect.toLowerCase()
310
- : 'none'
311
- this.put({ effect: newEffect })
312
- }
313
- })
314
- service.addCharacteristicDelegate({
315
- key: 'index',
316
- Characteristic: this.Characteristics.hap.ServiceLabelIndex,
317
- value: Number(id) + 1
318
- })
319
- service.addCharacteristicDelegate({
320
- key: 'lastActivation',
321
- Characteristic: this.Characteristics.eve.LastActivation,
322
- silent: true
323
- })
324
- this.effectServices[id] = service
325
-
326
- this.characteristicDelegate('configuredName')
327
- .on('didSet', (value) => {
328
- for (const id in this.capabilities.effects) {
329
- this.effectServices[id].values.configuredName = value +
330
- ' ' + this.capabilities.effects[id]
315
+ for (const id in this.resource.body.capabilities.color.effects) {
316
+ const effect = this.resource.body.capabilities.color.effects[id]
317
+ const characteristicName = effect[0].toUpperCase() + effect.slice(1) + 'Effect'
318
+ if (this.Characteristics.my[characteristicName] != null) {
319
+ this.addCharacteristicDelegate({
320
+ key: effect,
321
+ Characteristic: this.Characteristics.my[characteristicName]
322
+ }).on('didSet', (value, fromHomeKit) => {
323
+ if (fromHomeKit) {
324
+ this.checkAdaptiveLighting()
325
+ this.put({ effect: value ? effect : 'none' })
326
+ this.values.effectString = value ? effect : 'none'
331
327
  }
332
328
  })
329
+ effectString.on('didSet', (value) => {
330
+ this.values[effect] = value === effect
331
+ })
332
+ }
333
333
  }
334
334
  // if (this.capabilities.effectSpeed) {
335
335
  // this.addCharacteristicDelegate({
@@ -403,9 +403,8 @@ class Light extends DeconzService.LightsResource {
403
403
  break
404
404
  case 'effect':
405
405
  this.values.colorLoop = value === 'colorloop'
406
- if (this.capabilities.effects != null) {
407
- const effectName = value[0].toUpperCase() + value.slice(1)
408
- this.values.effect = '' + this.capabilities.effects.indexOf(effectName)
406
+ if (this.capabilities.effects) {
407
+ this.values.effectString = value
409
408
  }
410
409
  break
411
410
  case 'hue':
@@ -430,8 +429,10 @@ class Light extends DeconzService.LightsResource {
430
429
  break
431
430
  case 'xy':
432
431
  if (
433
- !this.recentlyUpdated &&
434
- (this.values.colormode !== 'ct' || this.capabilities.computesXy)
432
+ !this.recentlyUpdated && (
433
+ this.values.colormode !== 'ct' ||
434
+ this.resource.body?.capabilities?.color?.ct?.computesXy
435
+ )
435
436
  ) {
436
437
  const { h, s } = xyToHsv(value, this.capabilities.gamut)
437
438
  this.values.hue = h
@@ -15,10 +15,10 @@ const { dateToString } = Deconz.ApiClient
15
15
  */
16
16
  class Power extends DeconzService.SensorsResource {
17
17
  static addResource (service, resource) {
18
- if (service.values.currentConsumption === undefined) {
18
+ if (service.values.consumption === undefined) {
19
19
  service.addCharacteristicDelegate({
20
- key: 'currentConsumption',
21
- Characteristic: service.Characteristics.eve.CurrentConsumption,
20
+ key: 'consumption',
21
+ Characteristic: service.Characteristics.eve.Consumption,
22
22
  unit: ' W'
23
23
  })
24
24
  }
@@ -46,12 +46,13 @@ class Power extends DeconzService.SensorsResource {
46
46
  silent: true
47
47
  })
48
48
  }
49
- service.update(resource.body, resource.rpath)
49
+
50
+ Power.updateResourceState(service, resource.body.state)
50
51
  }
51
52
 
52
53
  static updateResourceState (service, state) {
53
54
  if (state.power != null) {
54
- service.values.currentConsumption = state.power
55
+ service.values.consumption = state.power
55
56
  }
56
57
  if (state.current != null) {
57
58
  service.values.electricCurrent = state.current / 1000
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.9",
7
+ "version": "0.1.10",
8
8
  "keywords": [
9
9
  "homebridge-plugin",
10
10
  "homekit",
@@ -21,12 +21,12 @@
21
21
  "ui": "cli/ui.js"
22
22
  },
23
23
  "engines": {
24
- "deCONZ": "2.19.3",
24
+ "deCONZ": "2.20.1",
25
25
  "homebridge": "^1.6.0",
26
- "node": "^18.14.2"
26
+ "node": "^18.15.0"
27
27
  },
28
28
  "dependencies": {
29
- "homebridge-lib": "~6.3.11",
29
+ "homebridge-lib": "~6.3.12",
30
30
  "ws": "^8.12.1",
31
31
  "xml2js": "~0.4.23"
32
32
  },