homebridge-deconz 0.0.10 → 0.0.13

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 (53) hide show
  1. package/README.md +3 -6
  2. package/cli/deconz.js +12 -0
  3. package/config.schema.json +1 -0
  4. package/homebridge-ui/public/index.html +26 -0
  5. package/homebridge-ui/public/style.css +0 -0
  6. package/homebridge-ui/server.js +43 -0
  7. package/lib/Deconz/ApiClient.js +34 -1
  8. package/lib/Deconz/ApiResponse.js +1 -1
  9. package/lib/Deconz/Device.js +0 -7
  10. package/lib/Deconz/Resource.js +751 -25
  11. package/lib/DeconzAccessory/Contact.js +54 -0
  12. package/lib/DeconzAccessory/Gateway.js +102 -66
  13. package/lib/DeconzAccessory/Light.js +42 -37
  14. package/lib/DeconzAccessory/Motion.js +51 -0
  15. package/lib/DeconzAccessory/Sensor.js +35 -0
  16. package/lib/DeconzAccessory/Temperature.js +63 -0
  17. package/lib/DeconzAccessory/Thermostat.js +50 -0
  18. package/lib/DeconzAccessory/WarningDevice.js +56 -0
  19. package/lib/DeconzAccessory/WindowCovering.js +47 -0
  20. package/lib/DeconzAccessory/index.js +144 -2
  21. package/lib/DeconzPlatform.js +5 -2
  22. package/lib/DeconzService/AirPressure.js +43 -0
  23. package/lib/DeconzService/AirQuality.js +20 -11
  24. package/lib/DeconzService/Alarm.js +13 -9
  25. package/lib/DeconzService/Battery.js +53 -0
  26. package/lib/DeconzService/Button.js +9 -2
  27. package/lib/DeconzService/CarbonMonoxide.js +38 -0
  28. package/lib/DeconzService/Consumption.js +65 -0
  29. package/lib/DeconzService/Contact.js +60 -0
  30. package/lib/DeconzService/Daylight.js +132 -0
  31. package/lib/DeconzService/DeviceSettings.js +11 -0
  32. package/lib/DeconzService/Flag.js +52 -0
  33. package/lib/DeconzService/Humidity.js +37 -0
  34. package/lib/DeconzService/Leak.js +38 -0
  35. package/lib/DeconzService/Light.js +122 -172
  36. package/lib/DeconzService/LightLevel.js +54 -0
  37. package/lib/DeconzService/LightsResource.js +112 -0
  38. package/lib/DeconzService/Motion.js +101 -0
  39. package/lib/DeconzService/Outlet.js +76 -0
  40. package/lib/DeconzService/Power.js +83 -0
  41. package/lib/DeconzService/SensorsResource.js +96 -0
  42. package/lib/DeconzService/Smoke.js +38 -0
  43. package/lib/DeconzService/Status.js +53 -0
  44. package/lib/DeconzService/Switch.js +93 -0
  45. package/lib/DeconzService/Temperature.js +63 -0
  46. package/lib/DeconzService/Thermostat.js +175 -0
  47. package/lib/DeconzService/WarningDevice.js +68 -0
  48. package/lib/DeconzService/WindowCovering.js +162 -0
  49. package/lib/DeconzService/index.js +79 -25
  50. package/package.json +6 -5
  51. package/lib/Client/ApiError.js +0 -42
  52. package/lib/DeconzAccessory/Device.js +0 -69
  53. package/lib/DeconzService/Sensor.js +0 -61
@@ -0,0 +1,63 @@
1
+ // homebridge-deconz/lib/DeconzService/Temperature.js
2
+ // Copyright © 2022 Erik Baauw. All rights reserved.
3
+ //
4
+ // Homebridge plugin for deCONZ.
5
+
6
+ 'use strict'
7
+
8
+ const DeconzService = require('../DeconzService')
9
+
10
+ /**
11
+ * @memberof DeconzService
12
+ */
13
+ class Temperature extends DeconzService.SensorsResource {
14
+ constructor (accessory, resource, params = {}) {
15
+ params.Service = accessory.Services.hap.TemperatureSensor
16
+ super(accessory, resource, params)
17
+
18
+ this.addCharacteristicDelegate({
19
+ key: 'temperature',
20
+ Characteristic: this.Characteristics.hap.CurrentTemperature,
21
+ unit: '°C',
22
+ props: { minValue: -40, maxValue: 100, minStep: 0.1 },
23
+ value: 0
24
+ })
25
+
26
+ this.addCharacteristicDelegate({
27
+ key: 'offset',
28
+ Characteristic: this.Characteristics.my.Offset,
29
+ unit: '°C',
30
+ value: 0
31
+ }).on('didSet', async (value, fromHomeKit) => {
32
+ if (fromHomeKit) {
33
+ await this.put('/config', { offset: Math.round(value * 100) })
34
+ }
35
+ })
36
+
37
+ this.addCharacteristicDelegate({
38
+ key: 'displayUnits',
39
+ Characteristic: this.Characteristics.hap.TemperatureDisplayUnits,
40
+ value: this.Characteristics.hap.TemperatureDisplayUnits.CELSIUS
41
+ })
42
+
43
+ this.addCharacteristicDelegates()
44
+
45
+ this.update(resource.body, resource.rpath)
46
+ }
47
+
48
+ updateState (state) {
49
+ if (state.temperature != null) {
50
+ this.values.temperature = Math.round(state.temperature / 10) / 10
51
+ }
52
+ super.updateState(state)
53
+ }
54
+
55
+ updateConfig (config) {
56
+ if (config.offset != null) {
57
+ this.values.offset = Math.round(config.offset / 10) / 10
58
+ }
59
+ super.updateConfig(config)
60
+ }
61
+ }
62
+
63
+ module.exports = Temperature
@@ -0,0 +1,175 @@
1
+ // homebridge-deconz/lib/DeconzService/Thermostat.js
2
+ // Copyright © 2022 Erik Baauw. All rights reserved.
3
+ //
4
+ // Homebridge plugin for deCONZ.
5
+
6
+ 'use strict'
7
+
8
+ const DeconzService = require('../DeconzService')
9
+
10
+ /**
11
+ * @memberof DeconzService
12
+ */
13
+ class Thermostat extends DeconzService.SensorsResource {
14
+ constructor (accessory, resource, params = {}) {
15
+ params.Service = accessory.Services.hap.Thermostat
16
+ super(accessory, resource, params)
17
+
18
+ this.addCharacteristicDelegate({
19
+ key: 'currentTemperature',
20
+ Characteristic: this.Characteristics.hap.CurrentTemperature,
21
+ unit: '°C',
22
+ props: { minValue: -40, maxValue: 100, minStep: 0.1 },
23
+ value: 0
24
+ })
25
+
26
+ this.addCharacteristicDelegate({
27
+ key: 'targetTemperature',
28
+ Characteristic: this.Characteristics.hap.TargetTemperature,
29
+ unit: '°C',
30
+ props: { minValue: 5, maxValue: 30, minStep: 0.5 },
31
+ value: 0
32
+ }).on('didSet', async (value, fromHomeKit) => {
33
+ if (fromHomeKit) {
34
+ await this.put('/config', { heatsetpoint: Math.round(value * 100) })
35
+ }
36
+ })
37
+
38
+ if (resource.body.state.valve !== undefined) {
39
+ this.addCharacteristicDelegate({
40
+ key: 'valvePosition',
41
+ Characteristic: this.Characteristics.eve.ValvePosition,
42
+ unit: '%'
43
+ })
44
+ }
45
+
46
+ this.addCharacteristicDelegate({
47
+ key: 'currentState',
48
+ Characteristic: this.Characteristics.hap.CurrentHeatingCoolingState,
49
+ props: {
50
+ validValues: [
51
+ this.Characteristics.hap.CurrentHeatingCoolingState.OFF,
52
+ this.Characteristics.hap.CurrentHeatingCoolingState.HEAT
53
+ ]
54
+ }
55
+ })
56
+
57
+ this.addCharacteristicDelegate({
58
+ key: 'targetState',
59
+ Characteristic: this.Characteristics.hap.TargetHeatingCoolingState,
60
+ props: {
61
+ validValues: [
62
+ this.Characteristics.hap.TargetHeatingCoolingState.OFF,
63
+ this.Characteristics.hap.TargetHeatingCoolingState.HEAT
64
+ ]
65
+ }
66
+ }).on('didSet', async (value, fromHomeKit) => {
67
+ if (fromHomeKit) {
68
+ await this.put('/mode', {
69
+ mode: value === this.Characteristics.hap.TargetHeatingCoolingState.OFF
70
+ ? 'off'
71
+ : this.capabilities.heatValue
72
+ })
73
+ }
74
+ })
75
+
76
+ this.addCharacteristicDelegate({
77
+ key: 'offset',
78
+ Characteristic: this.Characteristics.my.Offset,
79
+ unit: '°C',
80
+ value: 0
81
+ }).on('didSet', async (value, fromHomeKit) => {
82
+ if (fromHomeKit) {
83
+ await this.put('/config', { offset: Math.round(value * 100) })
84
+ }
85
+ })
86
+
87
+ this.addCharacteristicDelegate({
88
+ key: 'displayUnits',
89
+ Characteristic: this.Characteristics.hap.TemperatureDisplayUnits,
90
+ value: this.Characteristics.hap.TemperatureDisplayUnits.CELSIUS
91
+ })
92
+
93
+ this.addCharacteristicDelegate({
94
+ key: 'programData',
95
+ Characteristic: this.Characteristics.eve.ProgramData,
96
+ silent: true,
97
+ value: Buffer.from('ff04f6', 'hex').toString('base64')
98
+ })
99
+
100
+ this.addCharacteristicDelegate({
101
+ key: 'programCommand',
102
+ Characteristic: this.Characteristics.eve.ProgramCommand,
103
+ silent: true
104
+ })
105
+
106
+ if (resource.body.config.displayflipped !== undefined) {
107
+ this.addCharacteristicDelegate({
108
+ key: 'imageMirroring',
109
+ Characteristic: this.Characteristics.hap.ImageMirroring
110
+ }).on('didSet', async (value, fromHomeKit) => {
111
+ if (fromHomeKit) {
112
+ await this.put('/config', { displayflipped: value })
113
+ }
114
+ })
115
+ }
116
+
117
+ if (resource.body.config.locked !== undefined) {
118
+ this.addCharacteristicDelegate({
119
+ key: 'lockPhysicalControls',
120
+ Characteristic: this.Characteristics.hap.LockPhysicalControls
121
+ }).on('didSet', async (value, fromHomeKit) => {
122
+ if (fromHomeKit) {
123
+ await this.put('/config', {
124
+ locked: value === this.Characteristics.hap.LockPhysicalControls
125
+ .CONTROL_LOCK_ENABLED
126
+ })
127
+ }
128
+ })
129
+ }
130
+
131
+ super.addCharacteristicDelegates()
132
+
133
+ this.update(resource.body, resource.rpath)
134
+ }
135
+
136
+ updateState (state) {
137
+ if (state.on != null) {
138
+ this.values.currentState = state.on
139
+ ? this.Characteristics.hap.CurrentHeatingCoolingState.HEAT
140
+ : this.Characteristics.hap.CurrentHeatingCoolingState.OFF
141
+ }
142
+ if (state.temperature != null) {
143
+ this.values.currentTemperature = Math.round(state.temperature / 10) / 10
144
+ }
145
+ if (state.valve != null) {
146
+ this.values.valvePosition = Math.round(state.valve / 2.55)
147
+ }
148
+ super.updateState(state)
149
+ }
150
+
151
+ updateConfig (config) {
152
+ if (config.displayflipped != null) {
153
+ this.values.imageMirroring = config.displayflipped
154
+ }
155
+ if (config.heatsetpoint != null) {
156
+ this.values.targetTemperature = Math.round(config.heatsetpoint / 50) / 2
157
+ }
158
+ if (config.locked != null) {
159
+ this.values.lockPhysicalControls = config.locked
160
+ ? this.Characteristics.hap.LockPhysicalControls.CONTROL_LOCK_ENABLED
161
+ : this.Characteristics.hap.LockPhysicalControls.CONTROL_LOCK_DISABLED
162
+ }
163
+ if (config.mode != null) {
164
+ this.values.targetState = config.mode === 'off'
165
+ ? this.Characteristics.hap.TargetHeatingCoolingState.OFF
166
+ : this.Characteristics.hap.TargetHeatingCoolingState.HEAT
167
+ }
168
+ if (config.offset != null) {
169
+ this.values.offset = Math.round(config.offset / 10) / 10
170
+ }
171
+ super.updateConfig(config)
172
+ }
173
+ }
174
+
175
+ module.exports = Thermostat
@@ -0,0 +1,68 @@
1
+ // homebridge-deconz/lib/DeconzService/WarningDevice.js
2
+ // Copyright © 2022 Erik Baauw. All rights reserved.
3
+ //
4
+ // Homebridge plugin for deCONZ.
5
+
6
+ 'use strict'
7
+
8
+ const DeconzService = require('../DeconzService')
9
+
10
+ class WarningDevice extends DeconzService.LightsResource {
11
+ constructor (accessory, resource, params = {}) {
12
+ params.Service = accessory.Services.hap.Outlet
13
+ super(accessory, resource, params)
14
+
15
+ this.addCharacteristicDelegate({
16
+ key: 'on',
17
+ Characteristic: this.Characteristics.hap.On,
18
+ value: false
19
+ }).on('didSet', async (value, fromHomeKit) => {
20
+ if (fromHomeKit) {
21
+ if (this.timer != null) {
22
+ clearTimeout(this.timer)
23
+ delete this.timer
24
+ }
25
+ const onTime = this.values.duration > 0 ? this.values.duration : 1
26
+ let body = { alert: 'none' }
27
+ if (value) {
28
+ if (this.values.mute) {
29
+ body = { alert: 'blink', ontime: onTime }
30
+ } else if (this.values.duration === 0) {
31
+ body = { alert: 'select' }
32
+ } else {
33
+ body = { alert: 'lselect', ontime: onTime }
34
+ }
35
+ }
36
+ this.put(body)
37
+ if (value) {
38
+ this.timer = setTimeout(() => {
39
+ this.values.on = false
40
+ }, onTime * 1000)
41
+ }
42
+ }
43
+ })
44
+
45
+ this.addCharacteristicDelegate({
46
+ key: 'duration',
47
+ Characteristic: this.Characteristics.hap.SetDuration
48
+ })
49
+
50
+ this.addCharacteristicDelegate({
51
+ key: 'mute',
52
+ Characteristic: this.Characteristics.hap.Mute
53
+ })
54
+
55
+ this.addCharacteristicDelegates()
56
+
57
+ this.update(resource.body, resource.rpath)
58
+ }
59
+
60
+ updateState (state, rpath) {
61
+ if (state.on != null) {
62
+ this.values.on = state.on
63
+ }
64
+ super.updateState(state)
65
+ }
66
+ }
67
+
68
+ module.exports = WarningDevice
@@ -0,0 +1,162 @@
1
+ // homebridge-deconz/lib/DeconzService/WindowCovering.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
+ const DeconzService = require('../DeconzService')
10
+
11
+ const { timeout } = homebridgeLib
12
+
13
+ class WindowCovering extends DeconzService.LightsResource {
14
+ constructor (accessory, resource, params = {}) {
15
+ params.Service = accessory.Services.hap.WindowCovering
16
+ super(accessory, resource, params)
17
+
18
+ this.addCharacteristicDelegate({
19
+ key: 'currentPosition',
20
+ Characteristic: this.Characteristics.hap.CurrentPosition,
21
+ unit: '%'
22
+ })
23
+
24
+ this.addCharacteristicDelegate({
25
+ key: 'targetPosition',
26
+ Characteristic: this.Characteristics.hap.TargetPosition,
27
+ unit: '%'
28
+ }).on('didSet', async (value, fromHomeKit) => {
29
+ if (!fromHomeKit) {
30
+ return
31
+ }
32
+ this.values.targetPosition = Math.round(this.values.targetPosition / 5) * 5
33
+ await this.setPosition()
34
+ })
35
+
36
+ this.addCharacteristicDelegate({
37
+ key: 'positionState',
38
+ Characteristic: this.Characteristics.hap.PositionState,
39
+ value: this.Characteristics.hap.PositionState.STOPPED
40
+ }).on('didSet', (value) => {
41
+ if (value === this.Characteristics.hap.PositionState.STOPPED) {
42
+ this.values.targetPosition = this.values.currentPosition
43
+ }
44
+ })
45
+
46
+ this.addCharacteristicDelegate({
47
+ key: 'holdPosition',
48
+ Characteristic: this.Characteristics.hap.HoldPosition
49
+ }).on('didSet', () => {
50
+ this.put({ stop: true })
51
+ this.values.positionState = this.Characteristics.hap.PositionState.STOPPED
52
+ })
53
+
54
+ if (this.venetianBlind) {
55
+ this.addCharacteristicDelegate({
56
+ key: 'closeUpwards',
57
+ Characteristic: this.Characteristics.my.CloseUpwards
58
+ }).on('didSet', async (value, fromHomeKit) => {
59
+ if (!fromHomeKit) {
60
+ return
61
+ }
62
+ await this.setPosition()
63
+ })
64
+ }
65
+
66
+ if (resource.capabilities.maxSpeed != null) {
67
+ this.addCharacteristicDelegate({
68
+ key: 'motorSpeed',
69
+ Characteristic: this.Characteristics.my.MotorSpeed,
70
+ unit: '',
71
+ props: {
72
+ unit: '',
73
+ minValue: 0,
74
+ maxValue: resource.capabilities.maxSpeed,
75
+ minStep: 1
76
+ }
77
+ }).on('didSet', async (value, fromHomeKit) => {
78
+ if (!fromHomeKit) {
79
+ return
80
+ }
81
+ await this.put({ speed: value })
82
+ })
83
+ }
84
+
85
+ if (resource.capabilities.positionChange) {
86
+ this.addCharacteristicDelegate({
87
+ key: 'positionChange',
88
+ Characteristic: this.Characteristics.my.PositionChange
89
+ }).on('didSet', async (value) => {
90
+ if (value !== 0) {
91
+ this.put({ lift_inc: -value })
92
+ await timeout(this.platform.config.waitTimeReset)
93
+ this.values.positionChange = 0
94
+ }
95
+ })
96
+ this.values.positionChange = 0
97
+ }
98
+
99
+ this.addCharacteristicDelegates()
100
+
101
+ this.update(resource.body, resource.rpath)
102
+ this.values.targetPosition = this.values.currentPosition
103
+ }
104
+
105
+ async setPosition () {
106
+ if (this.timer != null) {
107
+ clearTimeout(this.timer)
108
+ delete this.timer
109
+ }
110
+ let lift = 100 - this.values.targetPosition // % closed --> % open
111
+ if (this.venetianBlind) {
112
+ if (this.values.closeUpwards) {
113
+ lift *= -1
114
+ }
115
+ lift += 100
116
+ lift /= 2
117
+ lift = Math.round(lift)
118
+ this.targetCloseUpwards = this.values.closeUpwards
119
+ }
120
+ this.values.positionState =
121
+ this.values.targetPosition > this.values.currentPosition
122
+ ? this.Characteristics.hap.PositionState.INCREASING
123
+ : this.Characteristics.hap.PositionState.DECREASING
124
+ await this.put({ lift: lift })
125
+ this.timer = setTimeout(() => {
126
+ this.values.positionState =
127
+ this.Characteristics.hap.PositionState.STOPPED
128
+ }, 15000)
129
+ }
130
+
131
+ updateState (state) {
132
+ if (state.lift != null) {
133
+ let position = Math.round(state.lift / 5) * 5
134
+ let closeUpwards
135
+ if (this.venetianBlind) {
136
+ if (position < 0) {
137
+ position *= -1
138
+ closeUpwards = true
139
+ } else if (position > 0) {
140
+ closeUpwards = false
141
+ }
142
+ }
143
+ position = 100 - position // % open -> % closed
144
+ this.values.currentPosition = position
145
+ if (closeUpwards != null) {
146
+ this.values.closeUpwards = closeUpwards
147
+ }
148
+ if (
149
+ position === this.values.targetPosition &&
150
+ (closeUpwards == null || closeUpwards === this.targetCloseUpwards)
151
+ ) {
152
+ this.values.positionState = this.Characteristics.hap.PositionState.STOPPED
153
+ }
154
+ }
155
+ if (state.speed != null) {
156
+ this.values.motorSpeed = state.speed
157
+ }
158
+ super.updateState(state)
159
+ }
160
+ }
161
+
162
+ module.exports = WindowCovering
@@ -5,39 +5,93 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ const homebridgeLib = require('homebridge-lib')
9
+ const Deconz = require('../Deconz')
10
+
11
+ const { dateToString } = Deconz.ApiClient
12
+
8
13
  /** Service delegates.
9
- * @hideconstructor
14
+ * @extends ServiceDelegate
10
15
  */
11
- class DeconzService {
16
+ class DeconzService extends homebridgeLib.ServiceDelegate {
17
+ static get AirPressure () { return require('./AirPressure') }
12
18
  static get AirQuality () { return require('./AirQuality') }
13
19
  static get Alarm () { return require('./Alarm') }
14
- // static get Battery () { return require('./Battery') }
20
+ static get Battery () { return require('./Battery') }
15
21
  static get Button () { return require('./Button') }
16
- // static get CarbonMonoxide () { return require('./CarbonMonoxide') }
17
- // static get Consumption () { return require('./Consumption') }
18
- // static get Daylight () { return require('./Daylight') }
22
+ static get CarbonMonoxide () { return require('./CarbonMonoxide') }
23
+ static get Consumption () { return require('./Consumption') }
24
+ static get Contact () { return require('./Contact') }
25
+ static get Daylight () { return require('./Daylight') }
19
26
  static get DeviceSettings () { return require('./DeviceSettings') }
20
- // static get Flag () { return require('./Flag') }
21
- // static get Fire () { return require('./Fire') }
27
+ static get Flag () { return require('./Flag') }
22
28
  static get GatewaySettings () { return require('./GatewaySettings') }
23
- // static get Humidity () { return require('./Humidity') }
24
- // static get Light () { return require('./Light') }
29
+ static get Humidity () { return require('./Humidity') }
30
+ static get Leak () { return require('./Leak') }
25
31
  static get Light () { return require('./Light') }
26
- // static get LightLevel () { return require('./LightLevel') }
27
- // static get Outlet () { return require('./Outlet') }
28
- // static get OpenClose () { return require('./OpenClose') }
29
- // static get Power () { return require('./Power') }
30
- // static get Presence () { return require('./Presence') }
31
- // static get Pressure () { return require('./Pressure') }
32
- static get Sensor () { return require('./Sensor') }
33
- // static get Status () { return require('./Status') }
34
- // static get Switch () { return require('./Switch') }
35
- // static get Temperature () { return require('./Temperature') }
36
- // static get Thermostat () { return require('./Thermostat') }
37
- // static get Vibration () { return require('./Vibration') }
38
- // static get Water () { return require('./Water') }
39
- // static get WarningDevice () { return require('./WarningDevice') }
40
- // static get WindowCovering () { return require('./WindowCovering') }
32
+ static get LightsResource () { return require('./LightsResource') }
33
+ static get LightLevel () { return require('./LightLevel') }
34
+ static get Motion () { return require('./Motion') }
35
+ static get Outlet () { return require('./Outlet') }
36
+ static get Power () { return require('./Power') }
37
+ static get SensorsResource () { return require('./SensorsResource') }
38
+ static get Status () { return require('./Status') }
39
+ static get Smoke () { return require('./Smoke') }
40
+ static get Switch () { return require('./Switch') }
41
+ static get Temperature () { return require('./Temperature') }
42
+ static get Thermostat () { return require('./Thermostat') }
43
+ static get WarningDevice () { return require('./WarningDevice') }
44
+ static get WindowCovering () { return require('./WindowCovering') }
45
+
46
+ constructor (accessory, resource, params) {
47
+ super(accessory, {
48
+ id: resource.id,
49
+ name: resource.body.name,
50
+ Service: params.Service,
51
+ subtype: resource.subtype,
52
+ primaryService: params.primaryService
53
+ })
54
+ this.id = resource.id
55
+ this.gateway = accessory.gateway
56
+ this.client = accessory.client
57
+ this.resource = resource
58
+ this.rtype = resource.rtype
59
+ this.rid = resource.rid
60
+ this.rpath = resource.rpath
61
+ this.capabilities = resource.capabilities
62
+
63
+ this.serviceNameByRpath = {}
64
+ }
65
+
66
+ addResource (resource) {
67
+ this.serviceNameByRpath[resource.rpath] = resource.serviceName
68
+ DeconzService[resource.serviceName].addResource(this, resource)
69
+ }
70
+
71
+ update (body, rpath) {
72
+ if (this.updating) {
73
+ return
74
+ }
75
+ const serviceName = this.serviceNameByRpath[rpath]
76
+ if (serviceName != null) {
77
+ if (body.state != null) {
78
+ DeconzService[serviceName].updateResourceState(this, body.state)
79
+ }
80
+ return
81
+ }
82
+ if (body.lastseen != null && this.rtype === 'lights') {
83
+ this.values.lastSeen = dateToString(body.lastseen)
84
+ }
85
+ if (body.config != null) {
86
+ this.updateConfig(body.config)
87
+ if (this.batteryService != null) {
88
+ this.batteryService.updateConfig(body.config)
89
+ }
90
+ }
91
+ if (body.state != null) {
92
+ this.updateState(body.state, rpath)
93
+ }
94
+ }
41
95
  }
42
96
 
43
97
  module.exports = DeconzService
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.0.10",
7
+ "version": "0.0.13",
8
8
  "keywords": [
9
9
  "homebridge-plugin",
10
10
  "homekit",
@@ -20,14 +20,15 @@
20
20
  "deconz": "cli/deconz.js"
21
21
  },
22
22
  "engines": {
23
- "deCONZ": "2.13.4",
23
+ "deCONZ": "2.14.1",
24
24
  "homebridge": "^1.4.0",
25
- "node": "^16.13.2"
25
+ "node": "^16.14.0"
26
26
  },
27
27
  "dependencies": {
28
- "homebridge-lib": "~5.2.0",
28
+ "@homebridge/plugin-ui-utils": "~0.0.19",
29
+ "homebridge-lib": "~5.2.3",
29
30
  "semver": "^7.3.5",
30
- "ws": "^8.4.2",
31
+ "ws": "^8.5.0",
31
32
  "xml2js": "~0.4.23"
32
33
  },
33
34
  "scripts": {
@@ -1,42 +0,0 @@
1
- // homebridge-deconz/lib/Deconz/ApiError.js
2
- //
3
- // Homebridge plug-in for deCONZ.
4
- // Copyright © 2018-2022 Erik Baauw. All rights reserved.
5
-
6
- 'use strict'
7
-
8
- const homebridgeLib = require('homebridge-lib')
9
-
10
- // API errors that could still cause (part of) the PUT command to be executed.
11
- const nonCriticalApiErrorTypes = [
12
- 6, // parameter not available
13
- 7, // invalid value for parameter
14
- 8, // paramater not modifiable
15
- 201 // paramater not modifiable, device is set to off
16
- ]
17
-
18
- /** Deconz API error.
19
- * @hideconstructor
20
- * @extends HttpClient.HttpError
21
- * @memberof Deconz
22
- */
23
- class ApiError extends homebridgeLib.HttpClient.HttpError {
24
- constructor (message, response, type, description) {
25
- super(message, response.request, response.statusCode, response.statusMessage)
26
-
27
- /** @member {integer} - The API error type.
28
- */
29
- this.type = type
30
-
31
- /** @member {string} - The API error description.
32
- */
33
- this.description = description
34
-
35
- /** @member {boolean} - Indication that the request might still succeed
36
- * for other attributes.
37
- */
38
- this.nonCritical = nonCriticalApiErrorTypes.includes(type)
39
- }
40
- }
41
-
42
- module.exports = ApiError