homebridge-deconz 0.0.10 → 0.0.11
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.
- package/cli/deconz.js +12 -0
- package/lib/Deconz/ApiClient.js +34 -1
- package/lib/Deconz/ApiResponse.js +1 -1
- package/lib/Deconz/Device.js +0 -7
- package/lib/Deconz/Resource.js +749 -24
- package/lib/DeconzAccessory/Contact.js +54 -0
- package/lib/DeconzAccessory/Gateway.js +83 -61
- package/lib/DeconzAccessory/Light.js +42 -37
- package/lib/DeconzAccessory/Motion.js +51 -0
- package/lib/DeconzAccessory/Sensor.js +35 -0
- package/lib/DeconzAccessory/Temperature.js +63 -0
- package/lib/DeconzAccessory/Thermostat.js +50 -0
- package/lib/DeconzAccessory/WarningDevice.js +56 -0
- package/lib/DeconzAccessory/WindowCovering.js +47 -0
- package/lib/DeconzAccessory/index.js +142 -2
- package/lib/DeconzPlatform.js +5 -0
- package/lib/DeconzService/AirPressure.js +43 -0
- package/lib/DeconzService/AirQuality.js +17 -10
- package/lib/DeconzService/Alarm.js +13 -9
- package/lib/DeconzService/Battery.js +43 -0
- package/lib/DeconzService/Button.js +9 -2
- package/lib/DeconzService/CarbonMonoxide.js +38 -0
- package/lib/DeconzService/Consumption.js +65 -0
- package/lib/DeconzService/Contact.js +60 -0
- package/lib/DeconzService/Daylight.js +132 -0
- package/lib/DeconzService/DeviceSettings.js +11 -0
- package/lib/DeconzService/Flag.js +52 -0
- package/lib/DeconzService/Humidity.js +37 -0
- package/lib/DeconzService/Leak.js +38 -0
- package/lib/DeconzService/Light.js +12 -164
- package/lib/DeconzService/LightLevel.js +54 -0
- package/lib/DeconzService/LightsResource.js +112 -0
- package/lib/DeconzService/Motion.js +101 -0
- package/lib/DeconzService/Outlet.js +76 -0
- package/lib/DeconzService/Power.js +83 -0
- package/lib/DeconzService/SensorsResource.js +96 -0
- package/lib/DeconzService/Smoke.js +38 -0
- package/lib/DeconzService/Status.js +53 -0
- package/lib/DeconzService/Switch.js +93 -0
- package/lib/DeconzService/Temperature.js +63 -0
- package/lib/DeconzService/Thermostat.js +175 -0
- package/lib/DeconzService/WarningDevice.js +68 -0
- package/lib/DeconzService/WindowCovering.js +139 -0
- package/lib/DeconzService/index.js +76 -25
- package/package.json +2 -2
- package/lib/DeconzAccessory/Device.js +0 -69
- 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.TemperatureSensor
|
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,139 @@
|
|
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.positionChange) {
|
67
|
+
this.addCharacteristicDelegate({
|
68
|
+
key: 'positionChange',
|
69
|
+
Characteristic: this.Characteristics.my.PositionChange
|
70
|
+
}).on('didSet', async (value) => {
|
71
|
+
if (value !== 0) {
|
72
|
+
this.put({ lift_inc: -value })
|
73
|
+
await timeout(this.platform.config.waitTimeReset)
|
74
|
+
this.values.positionChange = 0
|
75
|
+
}
|
76
|
+
})
|
77
|
+
this.values.positionChange = 0
|
78
|
+
}
|
79
|
+
|
80
|
+
this.addCharacteristicDelegates()
|
81
|
+
|
82
|
+
this.update(resource.body, resource.rpath)
|
83
|
+
}
|
84
|
+
|
85
|
+
setPosition () {
|
86
|
+
if (this.timer != null) {
|
87
|
+
clearTimeout(this.timer)
|
88
|
+
delete this.timer
|
89
|
+
}
|
90
|
+
let lift = 100 - this.values.targetPosition // % closed --> % open
|
91
|
+
if (this.venetianBlind) {
|
92
|
+
if (this.values.closeUpwards) {
|
93
|
+
lift *= -1
|
94
|
+
}
|
95
|
+
lift += 100
|
96
|
+
lift /= 2
|
97
|
+
lift = Math.round(lift)
|
98
|
+
this.targetCloseUpwards = this.values.closeUpwards
|
99
|
+
}
|
100
|
+
this.values.positionState =
|
101
|
+
this.values.targetPosition > this.values.currentPosition
|
102
|
+
? this.Characteristics.hap.PositionState.INCREASING
|
103
|
+
: this.Characteristics.hap.PositionState.DECREASING
|
104
|
+
this.put({ lift: lift })
|
105
|
+
this.timer = setTimeout(() => {
|
106
|
+
this.values.positionState =
|
107
|
+
this.Characteristics.hap.PositionState.STOPPED
|
108
|
+
}, 15000)
|
109
|
+
}
|
110
|
+
|
111
|
+
updateState (state, rpath) {
|
112
|
+
if (state.lift != null) {
|
113
|
+
let position = Math.round(state.lift / 5) * 5
|
114
|
+
let closeUpwards
|
115
|
+
if (this.venetianBlind) {
|
116
|
+
if (position < 0) {
|
117
|
+
position *= -1
|
118
|
+
closeUpwards = true
|
119
|
+
} else if (position > 0) {
|
120
|
+
closeUpwards = false
|
121
|
+
}
|
122
|
+
}
|
123
|
+
position = 100 - position // % open -> % closed
|
124
|
+
if (
|
125
|
+
position === this.values.targetPosition &&
|
126
|
+
(closeUpwards == null || closeUpwards === this.targetCloseUpwards)
|
127
|
+
) {
|
128
|
+
this.values.positionState = this.Characteristics.hap.PositionState.STOPPED
|
129
|
+
}
|
130
|
+
this.values.currentPosition = position
|
131
|
+
if (closeUpwards != null) {
|
132
|
+
this.values.closeUpwards = closeUpwards
|
133
|
+
}
|
134
|
+
}
|
135
|
+
super.updateState(state)
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
module.exports = WindowCovering
|
@@ -5,39 +5,90 @@
|
|
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
|
-
* @
|
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
|
-
|
20
|
+
static get Battery () { return require('./Battery') }
|
15
21
|
static get Button () { return require('./Button') }
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
21
|
-
// static get Fire () { return require('./Fire') }
|
27
|
+
static get Flag () { return require('./Flag') }
|
22
28
|
static get GatewaySettings () { return require('./GatewaySettings') }
|
23
|
-
|
24
|
-
|
29
|
+
static get Humidity () { return require('./Humidity') }
|
30
|
+
static get Leak () { return require('./Leak') }
|
25
31
|
static get Light () { return require('./Light') }
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
static get
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
+
}
|
88
|
+
if (body.state != null) {
|
89
|
+
this.updateState(body.state, rpath)
|
90
|
+
}
|
91
|
+
}
|
41
92
|
}
|
42
93
|
|
43
94
|
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.
|
7
|
+
"version": "0.0.11",
|
8
8
|
"keywords": [
|
9
9
|
"homebridge-plugin",
|
10
10
|
"homekit",
|
@@ -25,7 +25,7 @@
|
|
25
25
|
"node": "^16.13.2"
|
26
26
|
},
|
27
27
|
"dependencies": {
|
28
|
-
"homebridge-lib": "~5.2.
|
28
|
+
"homebridge-lib": "~5.2.2",
|
29
29
|
"semver": "^7.3.5",
|
30
30
|
"ws": "^8.4.2",
|
31
31
|
"xml2js": "~0.4.23"
|
@@ -1,69 +0,0 @@
|
|
1
|
-
// homebridge-deconz/lib/DeconzAccessory/Device.js
|
2
|
-
// Copyright © 2022 Erik Baauw. All rights reserved.
|
3
|
-
//
|
4
|
-
// Homebridge plugin for deCONZ.
|
5
|
-
|
6
|
-
'use strict'
|
7
|
-
|
8
|
-
const DeconzAccessory = require('.')
|
9
|
-
const DeconzService = require('../DeconzService')
|
10
|
-
|
11
|
-
/** Delegate class for a HomeKit accessory,
|
12
|
-
* corresponding to a Zigbee or virtual device on a deCONZ gateway,
|
13
|
-
* that is not yet supported.
|
14
|
-
* @extends DeconzAccessory
|
15
|
-
* @memberof DeconzAccessory
|
16
|
-
*/
|
17
|
-
class Device extends DeconzAccessory {
|
18
|
-
/** Instantiate a delegate for an accessory corresponding to a device.
|
19
|
-
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
20
|
-
* @param {Deconz.Device} device - The device.
|
21
|
-
*/
|
22
|
-
constructor (gateway, device) {
|
23
|
-
super(gateway, device)
|
24
|
-
|
25
|
-
this.identify()
|
26
|
-
|
27
|
-
this.service = new DeconzService.Button(this, {
|
28
|
-
name: this.name + ' Button',
|
29
|
-
button: 1,
|
30
|
-
events: DeconzService.Button.SINGLE | DeconzService.Button.LONG,
|
31
|
-
primaryService: true
|
32
|
-
})
|
33
|
-
|
34
|
-
this.settingsService = new DeconzService.DeviceSettings(this, {
|
35
|
-
name: this.name + ' Settings',
|
36
|
-
subtype: this.id,
|
37
|
-
resource: this.device.rpaths.join(', '),
|
38
|
-
expose: true,
|
39
|
-
logLevel: gateway.logLevel
|
40
|
-
})
|
41
|
-
|
42
|
-
this
|
43
|
-
.on('polled', (device) => {
|
44
|
-
this.vdebug('%s: polled', this.device.rpaths.join(', '))
|
45
|
-
this.service.update(1003)
|
46
|
-
})
|
47
|
-
.on('changed', (rpath, body) => {
|
48
|
-
if (Object.keys(body).length === 1) {
|
49
|
-
if (body.state != null) {
|
50
|
-
rpath += '/state'
|
51
|
-
body = body.state
|
52
|
-
} else if (body.config != null) {
|
53
|
-
rpath += '/config'
|
54
|
-
body = body.config
|
55
|
-
}
|
56
|
-
}
|
57
|
-
this.debug('%s: changed: %j', rpath, body)
|
58
|
-
this.service.update(1002)
|
59
|
-
})
|
60
|
-
.on('identify', this.identify)
|
61
|
-
|
62
|
-
setImmediate(() => {
|
63
|
-
this.debug('initialised')
|
64
|
-
this.emit('initialised')
|
65
|
-
})
|
66
|
-
}
|
67
|
-
}
|
68
|
-
|
69
|
-
module.exports = Device
|