homebridge-deconz 0.0.6 → 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/README.md +8 -0
- package/cli/deconz.js +980 -0
- package/config.schema.json +1 -1
- package/lib/Client/ApiError.js +42 -0
- package/lib/{DeconzClient.js → Deconz/ApiClient.js} +82 -158
- package/lib/Deconz/ApiError.js +42 -0
- package/lib/Deconz/ApiResponse.js +54 -0
- package/lib/Deconz/Device.js +100 -0
- package/lib/{DeconzDiscovery.js → Deconz/Discovery.js} +4 -3
- package/lib/Deconz/Resource.js +1206 -0
- package/lib/{DeconzWsClient.js → Deconz/WsClient.js} +59 -44
- package/lib/Deconz/index.js +21 -0
- package/lib/DeconzAccessory/Contact.js +54 -0
- package/lib/DeconzAccessory/Gateway.js +316 -374
- package/lib/DeconzAccessory/Light.js +72 -0
- 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 +216 -0
- package/lib/DeconzPlatform.js +8 -3
- package/lib/DeconzService/AirPressure.js +43 -0
- package/lib/DeconzService/AirQuality.js +20 -10
- package/lib/DeconzService/Alarm.js +16 -9
- package/lib/DeconzService/Battery.js +43 -0
- package/lib/DeconzService/Button.js +12 -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 +13 -5
- package/lib/DeconzService/Flag.js +52 -0
- package/lib/DeconzService/GatewaySettings.js +8 -58
- package/lib/DeconzService/Humidity.js +37 -0
- package/lib/DeconzService/Leak.js +38 -0
- package/lib/DeconzService/Light.js +376 -0
- 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 +94 -0
- package/package.json +7 -4
- package/lib/DeconzAccessory/Device.js +0 -91
- package/lib/DeconzAccessory.js +0 -16
- package/lib/DeconzDevice.js +0 -245
- package/lib/DeconzService/Sensor.js +0 -58
- package/lib/DeconzService.js +0 -43
@@ -0,0 +1,101 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzService/Motion.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 Motion extends DeconzService.SensorsResource {
|
14
|
+
constructor (accessory, resource, params = {}) {
|
15
|
+
params.Service = accessory.Services.hap.MotionSensor
|
16
|
+
super(accessory, resource, params)
|
17
|
+
|
18
|
+
this.durationKey = resource.body.config.delay !== null ? 'delay' : 'duration'
|
19
|
+
this.sensitivitymax = resource.body.config.sensitivitymax
|
20
|
+
|
21
|
+
this.addCharacteristicDelegate({
|
22
|
+
key: 'motion',
|
23
|
+
Characteristic: this.Characteristics.hap.MotionDetected,
|
24
|
+
value: 0
|
25
|
+
})
|
26
|
+
|
27
|
+
this.addCharacteristicDelegate({
|
28
|
+
key: 'sensitivity',
|
29
|
+
Characteristic: this.Characteristics.eve.Sensitivity,
|
30
|
+
value: this.Characteristics.hap.TemperatureDisplayUnits.CELSIUS
|
31
|
+
}).on('didSet', async (value, fromHomeKit) => {
|
32
|
+
if (fromHomeKit) {
|
33
|
+
const sensitivity = value === this.Characteristics.eve.Sensitivity.HIGH
|
34
|
+
? this.sensitivitymax
|
35
|
+
: value === this.Characteristics.eve.Sensitivity.LOW
|
36
|
+
? 0
|
37
|
+
: Math.round(this.sensitivitymax / 2)
|
38
|
+
await this.put('/config', { sensitivity: sensitivity })
|
39
|
+
}
|
40
|
+
})
|
41
|
+
|
42
|
+
this.addCharacteristicDelegate({
|
43
|
+
key: 'duration',
|
44
|
+
Characteristic: this.Characteristics.eve.Duration,
|
45
|
+
unit: 's'
|
46
|
+
}).on('didSet', async (value, fromHomeKit) => {
|
47
|
+
if (fromHomeKit) {
|
48
|
+
const config = {}
|
49
|
+
config[this.durationKey] =
|
50
|
+
value === this.Characteristics.eve.Duration.VALID_VALUES[0] ? 0 : value
|
51
|
+
await this.put('/config', config)
|
52
|
+
}
|
53
|
+
})
|
54
|
+
|
55
|
+
this.addCharacteristicDelegate({
|
56
|
+
key: 'lastActivation',
|
57
|
+
Characteristic: this.Characteristics.eve.LastActivation,
|
58
|
+
silent: true
|
59
|
+
})
|
60
|
+
|
61
|
+
this.addCharacteristicDelegates()
|
62
|
+
|
63
|
+
this.update(resource.body)
|
64
|
+
}
|
65
|
+
|
66
|
+
updateState (state) {
|
67
|
+
if (state.presence != null) {
|
68
|
+
this.values.motion = state.presence
|
69
|
+
}
|
70
|
+
if (state.vibration != null) {
|
71
|
+
this.values.motion = state.vibration
|
72
|
+
}
|
73
|
+
if (state.tampered != null) {
|
74
|
+
this.values.tampered = state.tampered
|
75
|
+
}
|
76
|
+
super.updateState(state)
|
77
|
+
}
|
78
|
+
|
79
|
+
updateConfig (config) {
|
80
|
+
if (config[this.durationKey] != null) {
|
81
|
+
let duration
|
82
|
+
for (const value of this.Characteristics.eve.Duration.VALID_VALUES) {
|
83
|
+
duration = value
|
84
|
+
if (config[this.durationKey] <= value) {
|
85
|
+
break
|
86
|
+
}
|
87
|
+
}
|
88
|
+
this.values.duration = duration
|
89
|
+
}
|
90
|
+
if (config.sensitivity != null) {
|
91
|
+
this.values.sensitivity = config.sensitivity === this.sensitivitymax
|
92
|
+
? this.Characteristics.eve.Sensitivity.HIGH
|
93
|
+
: config.sensitivity === 0
|
94
|
+
? this.Characteristics.eve.Sensitivity.LOW
|
95
|
+
: this.Characteristics.eve.Sensitivity.MEDIUM
|
96
|
+
}
|
97
|
+
super.updateConfig(config)
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
module.exports = Motion
|
@@ -0,0 +1,76 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzService/Outlet.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 Outlet 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: this.capabilities.on
|
19
|
+
? this.resource.body.state.on
|
20
|
+
: this.resource.body.state.all_on
|
21
|
+
}).on('didSet', (value, fromHomeKit) => {
|
22
|
+
if (fromHomeKit) {
|
23
|
+
this.put({ on: value })
|
24
|
+
}
|
25
|
+
})
|
26
|
+
|
27
|
+
if (!this.capabilities.on) {
|
28
|
+
this.addCharacteristicDelegate({
|
29
|
+
key: 'anyOn',
|
30
|
+
Characteristic: this.Characteristics.my.AnyOn,
|
31
|
+
value: this.resource.body.state.any_on
|
32
|
+
}).on('didSet', (value, fromHomeKit) => {
|
33
|
+
if (fromHomeKit) {
|
34
|
+
this.put({ on: value })
|
35
|
+
}
|
36
|
+
})
|
37
|
+
}
|
38
|
+
|
39
|
+
this.addCharacteristicDelegate({
|
40
|
+
key: 'outletInUse',
|
41
|
+
Characteristic: this.Characteristics.hap.OutletInUse,
|
42
|
+
value: 1
|
43
|
+
})
|
44
|
+
|
45
|
+
this.addCharacteristicDelegates()
|
46
|
+
|
47
|
+
this.settings = {
|
48
|
+
resetTimeout: this.platform.config.resetTimeout,
|
49
|
+
waitTimeUpdate: this.platform.config.waitTimeUpdate,
|
50
|
+
wallSwitch: false
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
updateState (state, rpath) {
|
55
|
+
for (const key in state) {
|
56
|
+
const value = state[key]
|
57
|
+
this.resource.body.state[key] = value
|
58
|
+
switch (key) {
|
59
|
+
case 'all_on':
|
60
|
+
this.values.on = value
|
61
|
+
break
|
62
|
+
case 'any_on':
|
63
|
+
this.values.anyOn = value
|
64
|
+
break
|
65
|
+
case 'on':
|
66
|
+
this.values.on = value
|
67
|
+
break
|
68
|
+
default:
|
69
|
+
break
|
70
|
+
}
|
71
|
+
}
|
72
|
+
super.updateState(state)
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
module.exports = Outlet
|
@@ -0,0 +1,83 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzService/Power.js
|
2
|
+
// Copyright © 2022 Erik Baauw. All rights reserved.
|
3
|
+
//
|
4
|
+
// Homebridge plugin for deCONZ.
|
5
|
+
|
6
|
+
'use strict'
|
7
|
+
|
8
|
+
const Deconz = require('../Deconz')
|
9
|
+
const DeconzService = require('../DeconzService')
|
10
|
+
|
11
|
+
const { dateToString } = Deconz.ApiClient
|
12
|
+
|
13
|
+
/**
|
14
|
+
* @memberof DeconzService
|
15
|
+
*/
|
16
|
+
class Power extends DeconzService.SensorsResource {
|
17
|
+
static addResource (service, resource) {
|
18
|
+
if (service.values.currentConsumption === undefined) {
|
19
|
+
service.addCharacteristicDelegate({
|
20
|
+
key: 'currentConsumption',
|
21
|
+
Characteristic: service.Characteristics.eve.CurrentConsumption,
|
22
|
+
unit: ' W'
|
23
|
+
})
|
24
|
+
}
|
25
|
+
|
26
|
+
if (resource.body.state.current !== undefined) {
|
27
|
+
service.addCharacteristicDelegate({
|
28
|
+
key: 'electricCurrent',
|
29
|
+
Characteristic: service.Characteristics.eve.ElectricCurrent,
|
30
|
+
unit: ' A'
|
31
|
+
})
|
32
|
+
}
|
33
|
+
|
34
|
+
if (resource.body.state.voltage !== undefined) {
|
35
|
+
service.addCharacteristicDelegate({
|
36
|
+
key: 'voltage',
|
37
|
+
Characteristic: service.Characteristics.eve.Voltage,
|
38
|
+
unit: ' V'
|
39
|
+
})
|
40
|
+
}
|
41
|
+
|
42
|
+
if (service.values.lastUpdated === undefined) {
|
43
|
+
service.addCharacteristicDelegate({
|
44
|
+
key: 'lastUpdated',
|
45
|
+
Characteristic: service.Characteristics.my.LastUpdated,
|
46
|
+
silent: true
|
47
|
+
})
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
static updateResourceState (service, state) {
|
52
|
+
if (state.power != null) {
|
53
|
+
service.values.currentConsumption = state.power
|
54
|
+
}
|
55
|
+
if (state.current != null) {
|
56
|
+
service.values.electricCurrent = state.current / 1000
|
57
|
+
}
|
58
|
+
if (state.voltage != null) {
|
59
|
+
service.values.voltage = state.voltage
|
60
|
+
}
|
61
|
+
if (state.lastupdated != null) {
|
62
|
+
service.values.lastUpdated = dateToString(state.lastupdated)
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
constructor (accessory, resource, params = {}) {
|
67
|
+
params.Service = accessory.Services.my.Resource
|
68
|
+
super(accessory, resource, params)
|
69
|
+
|
70
|
+
Power.addResource(this, resource)
|
71
|
+
|
72
|
+
super.addCharacteristicDelegates()
|
73
|
+
|
74
|
+
this.update(resource.body)
|
75
|
+
}
|
76
|
+
|
77
|
+
updateState (state) {
|
78
|
+
Power.updateResourceState(this.service, state)
|
79
|
+
super.updateState(state)
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
module.exports = Power
|
@@ -0,0 +1,96 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzService/SensorsResource.js
|
2
|
+
// Copyright © 2022 Erik Baauw. All rights reserved.
|
3
|
+
//
|
4
|
+
// Homebridge plugin for deCONZ.
|
5
|
+
|
6
|
+
'use strict'
|
7
|
+
|
8
|
+
const Deconz = require('../Deconz')
|
9
|
+
const DeconzService = require('../DeconzService')
|
10
|
+
|
11
|
+
const { dateToString, HttpError } = Deconz.ApiClient
|
12
|
+
|
13
|
+
/**
|
14
|
+
* @memberof DeconzService
|
15
|
+
*/
|
16
|
+
class SensorsResource extends DeconzService {
|
17
|
+
// constructor (accessory, resource, params) {
|
18
|
+
// super(accessory, resource, params)
|
19
|
+
// }
|
20
|
+
|
21
|
+
addCharacteristicDelegates (params = {}) {
|
22
|
+
if (!params.noLastUpdated) {
|
23
|
+
this.addCharacteristicDelegate({
|
24
|
+
key: 'lastUpdated',
|
25
|
+
Characteristic: this.Characteristics.my.LastUpdated,
|
26
|
+
silent: true
|
27
|
+
})
|
28
|
+
}
|
29
|
+
|
30
|
+
this.addCharacteristicDelegate({
|
31
|
+
key: 'enabled',
|
32
|
+
Characteristic: this.Characteristics.my.Enabled
|
33
|
+
}).on('didSet', (value) => {
|
34
|
+
this.values.statusActive = value
|
35
|
+
})
|
36
|
+
|
37
|
+
this.addCharacteristicDelegate({
|
38
|
+
key: 'statusActive',
|
39
|
+
Characteristic: this.Characteristics.hap.StatusActive
|
40
|
+
})
|
41
|
+
|
42
|
+
if (this.resource.body.config.reachable !== undefined) {
|
43
|
+
this.addCharacteristicDelegate({
|
44
|
+
key: 'statusFault',
|
45
|
+
Characteristic: this.Characteristics.hap.StatusFault
|
46
|
+
})
|
47
|
+
}
|
48
|
+
|
49
|
+
if (this.resource.body.state.tampered !== undefined && !params.noTampered) {
|
50
|
+
this.addCharacteristicDelegate({
|
51
|
+
key: 'tampered',
|
52
|
+
Characteristic: this.Characteristics.hap.StatusTampered
|
53
|
+
})
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
async identify () {
|
58
|
+
if (this.resource.body.config.alert) {
|
59
|
+
return this.put('/config', { alert: 'select' })
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
updateState (state) {
|
64
|
+
if (state.lastupdated != null) {
|
65
|
+
this.values.lastUpdated = dateToString(state.lastupdated)
|
66
|
+
}
|
67
|
+
if (state.tampered != null) {
|
68
|
+
this.values.tampered = state.tampered
|
69
|
+
? this.Characteristics.hap.StatusTampered.TAMPERED
|
70
|
+
: this.Characteristics.hap.StatusTampered.NOT_TAMPERED
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
updateConfig (config) {
|
75
|
+
if (config.on != null) {
|
76
|
+
this.values.enabled = !!config.on
|
77
|
+
}
|
78
|
+
if (config.reachable != null) {
|
79
|
+
this.values.statusFault = config.reachable
|
80
|
+
? this.Characteristics.hap.StatusFault.NO_FAULT
|
81
|
+
: this.Characteristics.hap.StatusFault.GENERAL_FAULT
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
async put (resource, body) {
|
86
|
+
try {
|
87
|
+
await this.client.put(this.rpath + resource, body)
|
88
|
+
} catch (error) {
|
89
|
+
if (!(error instanceof HttpError)) {
|
90
|
+
this.warn(error)
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
module.exports = SensorsResource
|
@@ -0,0 +1,38 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzService/Smoke.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 Smoke extends DeconzService.SensorsResource {
|
14
|
+
constructor (accessory, resource, params = {}) {
|
15
|
+
params.Service = accessory.Services.hap.SmokeSensor
|
16
|
+
super(accessory, resource, params)
|
17
|
+
|
18
|
+
this.addCharacteristicDelegate({
|
19
|
+
key: 'fire',
|
20
|
+
Characteristic: this.Characteristics.hap.SmokeDetected
|
21
|
+
})
|
22
|
+
|
23
|
+
super.addCharacteristicDelegates(params)
|
24
|
+
|
25
|
+
this.update(resource.body, resource.rpath)
|
26
|
+
}
|
27
|
+
|
28
|
+
updateState (state) {
|
29
|
+
if (state.fire != null || state.test != null) {
|
30
|
+
this.values.fire = state.fire || state.test
|
31
|
+
? this.Characteristics.hap.SmokeDetected.SMOKE_DETECTED
|
32
|
+
: this.Characteristics.hap.SmokeDetected.SMOKE_NOT_DETECTED
|
33
|
+
}
|
34
|
+
super.updateState(state)
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
module.exports = Smoke
|
@@ -0,0 +1,53 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzService/Status.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 Status extends DeconzService.SensorsResource {
|
14
|
+
constructor (accessory, resource, params = {}) {
|
15
|
+
params.Service = accessory.Services.my.Status
|
16
|
+
super(accessory, resource, params)
|
17
|
+
|
18
|
+
if (resource.capabilities.readonly) {
|
19
|
+
this.addCharacteristicDelegate({
|
20
|
+
key: 'status',
|
21
|
+
Characteristic: this.Characteristics.my.Status,
|
22
|
+
props: {
|
23
|
+
perms: [
|
24
|
+
this.Characteristic.Perms.READ, this.Characteristic.Perms.NOTIFY
|
25
|
+
]
|
26
|
+
}
|
27
|
+
})
|
28
|
+
} else {
|
29
|
+
this.addCharacteristicDelegate({
|
30
|
+
key: 'status',
|
31
|
+
Characteristic: this.Characteristics.my.Status,
|
32
|
+
props: resource.capabilities.props
|
33
|
+
}).on('didSet', async (value, fromHomeKit) => {
|
34
|
+
if (fromHomeKit) {
|
35
|
+
await this.put('/state', { status: value })
|
36
|
+
}
|
37
|
+
})
|
38
|
+
}
|
39
|
+
|
40
|
+
this.addCharacteristicDelegates()
|
41
|
+
|
42
|
+
this.update(resource.body)
|
43
|
+
}
|
44
|
+
|
45
|
+
updateState (state) {
|
46
|
+
if (state.status != null) {
|
47
|
+
this.values.status = state.status
|
48
|
+
}
|
49
|
+
super.updateState(state)
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
module.exports = Status
|
@@ -0,0 +1,93 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzService/Switch.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 Switch extends DeconzService.SensorsResource {
|
14
|
+
constructor (accessory, resource, params = {}) {
|
15
|
+
params.Service = accessory.Services.hap.ServiceLabel
|
16
|
+
super(accessory, resource, params)
|
17
|
+
|
18
|
+
this.addCharacteristicDelegate({
|
19
|
+
key: 'namespace',
|
20
|
+
Characteristic: this.Characteristics.hap.ServiceLabelNamespace,
|
21
|
+
value: resource.capabilities.namespace
|
22
|
+
})
|
23
|
+
|
24
|
+
this.addCharacteristicDelegates({ noLastUpdated: true })
|
25
|
+
|
26
|
+
this.buttonResources = {}
|
27
|
+
this.buttonServices = {}
|
28
|
+
this.hasRepeat = false
|
29
|
+
}
|
30
|
+
|
31
|
+
createButtonServices (resource) {
|
32
|
+
this.buttonResources[resource.rpath] = {
|
33
|
+
buttonEvent: resource.body.state.buttonevent,
|
34
|
+
lastUpdated: '',
|
35
|
+
toButtonEvent: resource.capabilities.toButtonEvent
|
36
|
+
}
|
37
|
+
for (const i in resource.capabilities.buttons) {
|
38
|
+
const { label, events, hasRepeat } = resource.capabilities.buttons[i]
|
39
|
+
if (hasRepeat) {
|
40
|
+
this.hasRepeat = hasRepeat
|
41
|
+
}
|
42
|
+
this.buttonServices[i] = new DeconzService.Button(this.accessoryDelegate, {
|
43
|
+
name: this.name + ' ' + label,
|
44
|
+
button: Number(i),
|
45
|
+
events: events,
|
46
|
+
hasRepeat: hasRepeat
|
47
|
+
})
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
updateState (state, rpath) {
|
52
|
+
const buttonResource = this.buttonResources[rpath]
|
53
|
+
if (buttonResource.lastUpdated === '') {
|
54
|
+
buttonResource.lastUpdated = state.lastupdated
|
55
|
+
} else if (
|
56
|
+
state.lastupdated != null &&
|
57
|
+
state.lastupdated !== buttonResource.lastUpdated
|
58
|
+
) {
|
59
|
+
buttonResource.lastUpdated = state.lastupdated
|
60
|
+
const oldValue = buttonResource.buttonEvent
|
61
|
+
if (state.buttonevent != null) {
|
62
|
+
buttonResource.buttonEvent = buttonResource.toButtonEvent == null
|
63
|
+
? state.buttonevent
|
64
|
+
: buttonResource.toButtonEvent(state.buttonevent)
|
65
|
+
}
|
66
|
+
// TODO handle repeat
|
67
|
+
this.updateButtonEvent(
|
68
|
+
buttonResource.buttonEvent, oldValue,
|
69
|
+
this.accessoryDelegate.settingsService.values.repeat
|
70
|
+
)
|
71
|
+
}
|
72
|
+
super.updateState(state)
|
73
|
+
}
|
74
|
+
|
75
|
+
updateConfig (config) {
|
76
|
+
// TODO handle change in devicemode
|
77
|
+
super.updateConfig(config)
|
78
|
+
}
|
79
|
+
|
80
|
+
updateButtonEvent (value, oldValue, repeat) {
|
81
|
+
const i = Math.floor(value / 1000)
|
82
|
+
if (this.buttonServices[i] != null) {
|
83
|
+
this.buttonServices[i].update(value, oldValue, repeat)
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
async identify () {
|
88
|
+
this.debug('hasRepeat: %j', this.hasRepeat)
|
89
|
+
return super.identify()
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
module.exports = Switch
|
@@ -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
|