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,72 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzAccessory/Light.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 DeconzAccessory = require('../DeconzAccessory')
|
10
|
+
|
11
|
+
const { History } = homebridgeLib.ServiceDelegate
|
12
|
+
|
13
|
+
/** Delegate class for a HomeKit accessory, corresponding to a light device
|
14
|
+
* or groups resource.
|
15
|
+
* @extends DeconzAccessory
|
16
|
+
* @memberof DeconzAccessory
|
17
|
+
*/
|
18
|
+
class Light extends DeconzAccessory {
|
19
|
+
/** Instantiate a delegate for an accessory corresponding to a device.
|
20
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
21
|
+
* @param {Deconz.Device} device - The device.
|
22
|
+
*/
|
23
|
+
constructor (gateway, device, settings = {}) {
|
24
|
+
super(gateway, device, gateway.Accessory.Categories.LIGHTBULB)
|
25
|
+
|
26
|
+
this.identify()
|
27
|
+
|
28
|
+
this.addPropertyDelegate({
|
29
|
+
key: 'serviceName',
|
30
|
+
value: device.resource.capabilities.bri ? 'Light' : 'Outlet'
|
31
|
+
})
|
32
|
+
|
33
|
+
this.service = this.createService(device.resource, {
|
34
|
+
primaryService: true,
|
35
|
+
serviceName: this.values.serviceName
|
36
|
+
})
|
37
|
+
|
38
|
+
for (const subtype in device.resourceBySubtype) {
|
39
|
+
const resource = device.resourceBySubtype[subtype]
|
40
|
+
if (subtype === device.primary) {
|
41
|
+
continue
|
42
|
+
}
|
43
|
+
if (resource.rtype === 'lights') {
|
44
|
+
this.createService(resource, { serviceName: this.values.serviceName })
|
45
|
+
} else {
|
46
|
+
this.createService(resource)
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
if (this.serviceByServiceName.Consumption != null) {
|
51
|
+
this.historyService = new History.Consumption(
|
52
|
+
this, {},
|
53
|
+
this.serviceByServiceName.Consumption.characteristicDelegate('totalConsumption'),
|
54
|
+
this.serviceByServiceName.Consumption.characteristicDelegate('currentConsumption')
|
55
|
+
)
|
56
|
+
} else if (this.serviceByServiceName.Power != null) {
|
57
|
+
this.historyService = new History.Power(
|
58
|
+
this, {},
|
59
|
+
this.serviceByServiceName.Power.characteristicDelegate('currentConsumption')
|
60
|
+
)
|
61
|
+
}
|
62
|
+
|
63
|
+
this.createSettingsService()
|
64
|
+
|
65
|
+
setImmediate(() => {
|
66
|
+
this.debug('initialised')
|
67
|
+
this.emit('initialised')
|
68
|
+
})
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
module.exports = Light
|
@@ -0,0 +1,51 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzAccessory/Motion.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 DeconzAccessory = require('../DeconzAccessory')
|
10
|
+
|
11
|
+
const { History } = homebridgeLib.ServiceDelegate
|
12
|
+
|
13
|
+
class Motion extends DeconzAccessory {
|
14
|
+
/** Instantiate a delegate for an accessory corresponding to a device.
|
15
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
16
|
+
* @param {Deconz.Device} device - The device.
|
17
|
+
*/
|
18
|
+
constructor (gateway, device) {
|
19
|
+
super(gateway, device, gateway.Accessory.Categories.SENSOR)
|
20
|
+
|
21
|
+
this.identify()
|
22
|
+
|
23
|
+
this.service = this.createService(device.resource, { primaryService: true })
|
24
|
+
|
25
|
+
for (const subtype in device.resourceBySubtype) {
|
26
|
+
const resource = device.resourceBySubtype[subtype]
|
27
|
+
if (subtype === device.primary) {
|
28
|
+
continue
|
29
|
+
}
|
30
|
+
this.createService(resource)
|
31
|
+
}
|
32
|
+
|
33
|
+
this.historyService = new History.Motion(
|
34
|
+
this, {},
|
35
|
+
this.service.characteristicDelegate('motion'),
|
36
|
+
this.service.characteristicDelegate('lastActivation'),
|
37
|
+
this.serviceByServiceName.Temperature == null
|
38
|
+
? null
|
39
|
+
: this.serviceByServiceName.Temperature.characteristicDelegate('temperature')
|
40
|
+
)
|
41
|
+
|
42
|
+
this.createSettingsService()
|
43
|
+
|
44
|
+
setImmediate(() => {
|
45
|
+
this.debug('initialised')
|
46
|
+
this.emit('initialised')
|
47
|
+
})
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
module.exports = Motion
|
@@ -0,0 +1,35 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzAccessory/Sensor.js
|
2
|
+
// Copyright © 2022 Erik Baauw. All rights reserved.
|
3
|
+
//
|
4
|
+
// Homebridge plugin for deCONZ.
|
5
|
+
|
6
|
+
'use strict'
|
7
|
+
|
8
|
+
const DeconzAccessory = require('../DeconzAccessory')
|
9
|
+
|
10
|
+
class Sensor extends DeconzAccessory {
|
11
|
+
constructor (gateway, device) {
|
12
|
+
super(gateway, device, gateway.Accessory.Categories.SENSOR)
|
13
|
+
|
14
|
+
this.identify()
|
15
|
+
|
16
|
+
this.service = this.createService(device.resource, { primaryService: true })
|
17
|
+
|
18
|
+
for (const subtype in device.resourceBySubtype) {
|
19
|
+
const resource = device.resourceBySubtype[subtype]
|
20
|
+
if (subtype === device.primary) {
|
21
|
+
continue
|
22
|
+
}
|
23
|
+
this.createService(resource)
|
24
|
+
}
|
25
|
+
|
26
|
+
this.createSettingsService()
|
27
|
+
|
28
|
+
setImmediate(() => {
|
29
|
+
this.debug('initialised')
|
30
|
+
this.emit('initialised')
|
31
|
+
})
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
module.exports = Sensor
|
@@ -0,0 +1,63 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzAccessory/Temperature.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 DeconzAccessory = require('../DeconzAccessory')
|
10
|
+
|
11
|
+
const { History } = homebridgeLib.ServiceDelegate
|
12
|
+
|
13
|
+
class Temperature extends DeconzAccessory {
|
14
|
+
/** Instantiate a delegate for an accessory corresponding to a device.
|
15
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
16
|
+
* @param {Deconz.Device} device - The device.
|
17
|
+
*/
|
18
|
+
constructor (gateway, device, settings = {}) {
|
19
|
+
super(gateway, device, gateway.Accessory.Categories.SENSOR)
|
20
|
+
this.identify()
|
21
|
+
|
22
|
+
this.service = this.createService(device.resource, { primaryService: true })
|
23
|
+
|
24
|
+
for (const subtype in device.resourceBySubtype) {
|
25
|
+
const resource = device.resourceBySubtype[subtype]
|
26
|
+
if (subtype === device.primary) {
|
27
|
+
continue
|
28
|
+
}
|
29
|
+
this.createService(resource)
|
30
|
+
}
|
31
|
+
|
32
|
+
if (this.serviceByServiceName.AirQuality == null) {
|
33
|
+
this.historyService = new History.Weather(
|
34
|
+
this, {},
|
35
|
+
this.service.characteristicDelegate('temperature'),
|
36
|
+
this.serviceByServiceName.Humidity == null
|
37
|
+
? null
|
38
|
+
: this.serviceByServiceName.Humidity.characteristicDelegate('humidity'),
|
39
|
+
this.serviceByServiceName.AirPressure == null
|
40
|
+
? null
|
41
|
+
: this.serviceByServiceName.AirPressure.characteristicDelegate('airPressure')
|
42
|
+
)
|
43
|
+
} else {
|
44
|
+
this.historyService = new History.Room(
|
45
|
+
this, {},
|
46
|
+
this.service.characteristicDelegate('temperature'),
|
47
|
+
this.serviceByServiceName.Humidity == null
|
48
|
+
? null
|
49
|
+
: this.serviceByServiceName.Humidity.characteristicDelegate('humidity'),
|
50
|
+
this.serviceByServiceName.AirQuality.characteristicDelegate('vocDensity')
|
51
|
+
)
|
52
|
+
}
|
53
|
+
|
54
|
+
this.createSettingsService()
|
55
|
+
|
56
|
+
setImmediate(() => {
|
57
|
+
this.debug('initialised')
|
58
|
+
this.emit('initialised')
|
59
|
+
})
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
module.exports = Temperature
|
@@ -0,0 +1,50 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzAccessory/Thermostat.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 DeconzAccessory = require('../DeconzAccessory')
|
10
|
+
|
11
|
+
const { History } = homebridgeLib.ServiceDelegate
|
12
|
+
|
13
|
+
class Thermostat extends DeconzAccessory {
|
14
|
+
/** Instantiate a delegate for an accessory corresponding to a device.
|
15
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
16
|
+
* @param {Deconz.Device} device - The device.
|
17
|
+
*/
|
18
|
+
constructor (gateway, device, settings = {}) {
|
19
|
+
super(gateway, device, gateway.Accessory.Categories.THERMOSTAT)
|
20
|
+
this.identify()
|
21
|
+
|
22
|
+
this.service = this.createService(device.resource, { primaryService: true })
|
23
|
+
|
24
|
+
for (const subtype in device.resourceBySubtype) {
|
25
|
+
const resource = device.resourceBySubtype[subtype]
|
26
|
+
if (subtype === device.primary) {
|
27
|
+
continue
|
28
|
+
}
|
29
|
+
this.createService(resource)
|
30
|
+
}
|
31
|
+
|
32
|
+
if (device.resource.body.state.valve !== undefined) {
|
33
|
+
this.historyService = new History.Thermo(
|
34
|
+
this, {},
|
35
|
+
this.service.characteristicDelegate('currentTemperature'),
|
36
|
+
this.service.characteristicDelegate('targetTemperature'),
|
37
|
+
this.service.characteristicDelegate('valvePosition')
|
38
|
+
)
|
39
|
+
}
|
40
|
+
|
41
|
+
this.createSettingsService()
|
42
|
+
|
43
|
+
setImmediate(() => {
|
44
|
+
this.debug('initialised')
|
45
|
+
this.emit('initialised')
|
46
|
+
})
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
module.exports = Thermostat
|
@@ -0,0 +1,56 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzAccessory/WarningDevice.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 DeconzAccessory = require('../DeconzAccessory')
|
10
|
+
|
11
|
+
const { History } = homebridgeLib.ServiceDelegate
|
12
|
+
|
13
|
+
/** Delegate class for a HomeKit accessory, corresponding to a light device
|
14
|
+
* or groups resource.
|
15
|
+
* @extends DeconzAccessory
|
16
|
+
* @memberof DeconzAccessory
|
17
|
+
*/
|
18
|
+
class WarningDevice extends DeconzAccessory {
|
19
|
+
/** Instantiate a delegate for an accessory corresponding to a device.
|
20
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
21
|
+
* @param {Deconz.Device} device - The device.
|
22
|
+
*/
|
23
|
+
constructor (gateway, device, settings = {}) {
|
24
|
+
super(gateway, device, gateway.Accessory.Categories.SENSOR)
|
25
|
+
|
26
|
+
this.identify()
|
27
|
+
|
28
|
+
this.service = this.createService(device.resource, { primaryService: true })
|
29
|
+
|
30
|
+
for (const subtype in device.resourceBySubtype) {
|
31
|
+
const resource = device.resourceBySubtype[subtype]
|
32
|
+
if (subtype === device.primary) {
|
33
|
+
continue
|
34
|
+
}
|
35
|
+
this.createService(resource)
|
36
|
+
}
|
37
|
+
|
38
|
+
if (this.serviceByServiceName.Temperature != null) {
|
39
|
+
this.historyService = new History.Weather(
|
40
|
+
this, {},
|
41
|
+
this.serviceByServiceName.Temperature.characteristicDelegate('temperature'),
|
42
|
+
null,
|
43
|
+
null
|
44
|
+
)
|
45
|
+
}
|
46
|
+
|
47
|
+
this.createSettingsService()
|
48
|
+
|
49
|
+
setImmediate(() => {
|
50
|
+
this.debug('initialised')
|
51
|
+
this.emit('initialised')
|
52
|
+
})
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
module.exports = WarningDevice
|
@@ -0,0 +1,47 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzAccessory/WindowCovering.js
|
2
|
+
// Copyright © 2022 Erik Baauw. All rights reserved.
|
3
|
+
//
|
4
|
+
// Homebridge plugin for deCONZ.
|
5
|
+
|
6
|
+
'use strict'
|
7
|
+
|
8
|
+
const DeconzAccessory = require('../DeconzAccessory')
|
9
|
+
|
10
|
+
/** Delegate class for a HomeKit accessory, corresponding to a light device
|
11
|
+
* or groups resource.
|
12
|
+
* @extends DeconzAccessory
|
13
|
+
* @memberof DeconzAccessory
|
14
|
+
*/
|
15
|
+
class WindowCovering extends DeconzAccessory {
|
16
|
+
/** Instantiate a delegate for an accessory corresponding to a device.
|
17
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
18
|
+
* @param {Deconz.Device} device - The device.
|
19
|
+
*/
|
20
|
+
constructor (gateway, device, settings = {}) {
|
21
|
+
super(gateway, device, gateway.Accessory.Categories.WINDOW_COVERING)
|
22
|
+
|
23
|
+
this.identify()
|
24
|
+
|
25
|
+
this.service = this.createService(device.resource, {
|
26
|
+
primaryService: true,
|
27
|
+
serviceName: this.values.serviceName
|
28
|
+
})
|
29
|
+
|
30
|
+
for (const subtype in device.resourceBySubtype) {
|
31
|
+
const resource = device.resourceBySubtype[subtype]
|
32
|
+
if (subtype === device.primary) {
|
33
|
+
continue
|
34
|
+
}
|
35
|
+
this.createService(resource)
|
36
|
+
}
|
37
|
+
|
38
|
+
this.createSettingsService()
|
39
|
+
|
40
|
+
setImmediate(() => {
|
41
|
+
this.debug('initialised')
|
42
|
+
this.emit('initialised')
|
43
|
+
})
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
module.exports = WindowCovering
|
@@ -0,0 +1,216 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzAccessory/index.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 Deconz = require('../Deconz')
|
10
|
+
const DeconzService = require('../DeconzService')
|
11
|
+
|
12
|
+
const { HttpError } = Deconz.ApiClient
|
13
|
+
const { SINGLE, DOUBLE, LONG } = DeconzService.Button
|
14
|
+
|
15
|
+
/** Abstract superclass for a delegate of a HomeKit accessory,
|
16
|
+
* corresponding to a Zigbee or virtual device on a deCONZ gateway.
|
17
|
+
* @extends AccessoryDelegate
|
18
|
+
*/
|
19
|
+
class DeconzAccessory extends homebridgeLib.AccessoryDelegate {
|
20
|
+
static get Contact () { return require('./Contact') }
|
21
|
+
static get Light () { return require('./Light') }
|
22
|
+
static get Gateway () { return require('./Gateway') }
|
23
|
+
static get Motion () { return require('./Motion') }
|
24
|
+
static get Sensor () { return require('./Sensor') }
|
25
|
+
static get Temperature () { return require('./Temperature') }
|
26
|
+
static get WarningDevice () { return require('./WarningDevice') }
|
27
|
+
static get WindowCovering () { return require('./WindowCovering') }
|
28
|
+
|
29
|
+
/** Instantiate a delegate for an accessory corresponding to a device.
|
30
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
31
|
+
* @param {Deconz.Device} device - The device.
|
32
|
+
* @param {Accessory.Category} category - The HomeKit accessory category.
|
33
|
+
*/
|
34
|
+
constructor (gateway, device, category) {
|
35
|
+
// TODO device settings
|
36
|
+
super(gateway.platform, {
|
37
|
+
id: device.id,
|
38
|
+
name: device.resource.body.name,
|
39
|
+
manufacturer: device.resource.manufacturer,
|
40
|
+
model: device.resource.model,
|
41
|
+
firmware: device.resource.firmware,
|
42
|
+
category: category
|
43
|
+
})
|
44
|
+
|
45
|
+
this.context.gid = gateway.id
|
46
|
+
|
47
|
+
this.serviceByRpath = {}
|
48
|
+
this.serviceBySubtype = {}
|
49
|
+
this.serviceByServiceName = {}
|
50
|
+
|
51
|
+
/** The gateway.
|
52
|
+
* @type {DeconzAccessory.Gateway}
|
53
|
+
*/
|
54
|
+
this.gateway = gateway
|
55
|
+
|
56
|
+
/** The accessory ID.
|
57
|
+
*
|
58
|
+
* This is the {@link Deconz.Device#id id} of the corresponding device.
|
59
|
+
* @type {string}
|
60
|
+
*/
|
61
|
+
this.id = device.id
|
62
|
+
|
63
|
+
/** The corresponding device.
|
64
|
+
* @type {Deconz.Device}
|
65
|
+
*/
|
66
|
+
this.device = device
|
67
|
+
|
68
|
+
/** The API client instance for the gateway.
|
69
|
+
* @type {Deconz.ApiClient}
|
70
|
+
*/
|
71
|
+
this.client = gateway.client
|
72
|
+
|
73
|
+
this
|
74
|
+
.on('polled', (device) => {
|
75
|
+
this.values.firmware = device.resource.firmware
|
76
|
+
for (const subtype in this.serviceBySubtype) {
|
77
|
+
try {
|
78
|
+
const service = this.serviceBySubtype[subtype]
|
79
|
+
const resource = device.resourceBySubtype[subtype]
|
80
|
+
this.debug('%s: polled: %j', resource.rpath, resource.body)
|
81
|
+
service.update(resource.body, resource.rpath)
|
82
|
+
} catch (error) { this.error(error) }
|
83
|
+
}
|
84
|
+
})
|
85
|
+
.on('changed', (rpath, body) => {
|
86
|
+
this.debug('%s: changed: %j', rpath, body)
|
87
|
+
const service = this.serviceByRpath[rpath]
|
88
|
+
if (service != null) {
|
89
|
+
service.update(body, rpath)
|
90
|
+
}
|
91
|
+
})
|
92
|
+
.on('identify', async () => {
|
93
|
+
try {
|
94
|
+
await this.identify()
|
95
|
+
} catch (error) {
|
96
|
+
if (!(error instanceof HttpError)) {
|
97
|
+
this.warn(error)
|
98
|
+
}
|
99
|
+
}
|
100
|
+
})
|
101
|
+
}
|
102
|
+
|
103
|
+
/** The primary resource of the device.
|
104
|
+
* @type {Deconz.Resource}
|
105
|
+
*/
|
106
|
+
get resource () { return this.device.resource }
|
107
|
+
|
108
|
+
/** List of resource paths of associated resources in order of prio.
|
109
|
+
* @type {string[]}
|
110
|
+
*/
|
111
|
+
get rpaths () { return this.device.rpaths }
|
112
|
+
|
113
|
+
async identify () {
|
114
|
+
this.log(
|
115
|
+
'%s %s v%s (%d resources)', this.values.manufacturer, this.values.model,
|
116
|
+
this.values.firmware, this.rpaths.length
|
117
|
+
)
|
118
|
+
this.debug('%d resources: %s', this.rpaths.length, this.rpaths.join(', '))
|
119
|
+
if (this.service != null) {
|
120
|
+
await this.service.identify()
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
createService (resource, params = {}) {
|
125
|
+
if (resource == null) {
|
126
|
+
return
|
127
|
+
}
|
128
|
+
if (params.serviceName == null) {
|
129
|
+
params.serviceName = resource.serviceName
|
130
|
+
}
|
131
|
+
if (DeconzService[params.serviceName] == null) {
|
132
|
+
this.warn(
|
133
|
+
'%s: %s: not yet supported %s type',
|
134
|
+
resource.rpath, resource.body.type, resource.rtype
|
135
|
+
)
|
136
|
+
return
|
137
|
+
}
|
138
|
+
this.debug(
|
139
|
+
'%s: capabilities: %j', resource.rpath, resource.capabilities
|
140
|
+
)
|
141
|
+
this.debug('%s: params: %j', resource.rpath, params)
|
142
|
+
|
143
|
+
let service
|
144
|
+
if (params.serviceName === 'Battery') {
|
145
|
+
service = this.serviceByServiceName.Battery
|
146
|
+
} else if (params.serviceName === 'Consumption') {
|
147
|
+
service = this.serviceByServiceName.Light ||
|
148
|
+
this.serviceByServiceName.Power
|
149
|
+
if (service != null) {
|
150
|
+
service.addResource(resource)
|
151
|
+
}
|
152
|
+
} else if (params.serviceName === 'Power') {
|
153
|
+
service = this.serviceByServiceName.Light ||
|
154
|
+
this.serviceByServiceName.Consumption
|
155
|
+
if (service != null) {
|
156
|
+
service.addResource(resource)
|
157
|
+
}
|
158
|
+
this.consumptionService = service
|
159
|
+
} else if (params.serviceName === 'Switch') {
|
160
|
+
// Default button
|
161
|
+
if (resource.capabilities.buttons == null) {
|
162
|
+
this.warn(
|
163
|
+
'%s: unknown %s: %j', resource.rpath, resource.body.type,
|
164
|
+
resource.body
|
165
|
+
)
|
166
|
+
resource.capabilities.buttons = {
|
167
|
+
1: {
|
168
|
+
label: 'Unknown Button',
|
169
|
+
events: SINGLE | DOUBLE | LONG
|
170
|
+
}
|
171
|
+
}
|
172
|
+
resource.capabilities.namespace =
|
173
|
+
this.Characteristics.hap.ServiceLabelNamespace.ARABIC_NUMERALS
|
174
|
+
}
|
175
|
+
service = this.serviceByServiceName.Switch
|
176
|
+
if (service == null) {
|
177
|
+
service = new DeconzService.Switch(this, resource, {
|
178
|
+
primaryService: params.primaryService
|
179
|
+
})
|
180
|
+
}
|
181
|
+
service.createButtonServices(resource, params)
|
182
|
+
}
|
183
|
+
if (service == null) {
|
184
|
+
service = new DeconzService[params.serviceName](this, resource, {
|
185
|
+
primaryService: params.primaryService
|
186
|
+
})
|
187
|
+
}
|
188
|
+
this.serviceBySubtype[resource.subtype] = service
|
189
|
+
this.serviceByRpath[resource.rpath] = service
|
190
|
+
if (this.serviceByServiceName[resource.serviceName] == null) {
|
191
|
+
this.serviceByServiceName[resource.serviceName] = service
|
192
|
+
}
|
193
|
+
if (
|
194
|
+
this.serviceByServiceName.Battery == null &&
|
195
|
+
resource.body.config != null &&
|
196
|
+
resource.body.config.battery !== undefined
|
197
|
+
) {
|
198
|
+
this.serviceByServiceName.Battery = new DeconzService.Battery(this, resource)
|
199
|
+
}
|
200
|
+
return service
|
201
|
+
}
|
202
|
+
|
203
|
+
createSettingsService (params = {}) {
|
204
|
+
this.settingsService = new DeconzService.DeviceSettings(this, {
|
205
|
+
name: this.name + ' Settings',
|
206
|
+
subtype: this.id,
|
207
|
+
resource: this.device.rpaths.join(', '),
|
208
|
+
expose: true,
|
209
|
+
logLevel: this.gateway.logLevel,
|
210
|
+
hasRepeat: this.service.hasRepeat
|
211
|
+
})
|
212
|
+
this.manageLogLevel(this.settingsService.characteristicDelegate('logLevel'))
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
module.exports = DeconzAccessory
|
package/lib/DeconzPlatform.js
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
const events = require('events')
|
9
9
|
const homebridgeLib = require('homebridge-lib')
|
10
|
-
const
|
10
|
+
const Deconz = require('./Deconz')
|
11
11
|
const DeconzAccessory = require('./DeconzAccessory')
|
12
12
|
|
13
13
|
class DeconzPlatform extends homebridgeLib.Platform {
|
@@ -37,7 +37,7 @@ class DeconzPlatform extends homebridgeLib.Platform {
|
|
37
37
|
waitTimePutGroup: 1000,
|
38
38
|
waitTimeResend: 300,
|
39
39
|
waitTimeReset: 500,
|
40
|
-
waitTimeUpdate:
|
40
|
+
waitTimeUpdate: 100
|
41
41
|
}
|
42
42
|
const optionParser = new homebridgeLib.OptionParser(this.config, true)
|
43
43
|
optionParser
|
@@ -62,7 +62,7 @@ class DeconzPlatform extends homebridgeLib.Platform {
|
|
62
62
|
|
63
63
|
try {
|
64
64
|
optionParser.parse(configJson)
|
65
|
-
this.discovery = new
|
65
|
+
this.discovery = new Deconz.Discovery({
|
66
66
|
forceHttp: this.config.forceHttp,
|
67
67
|
timeout: this.config.timeout
|
68
68
|
})
|
@@ -190,6 +190,11 @@ class DeconzPlatform extends homebridgeLib.Platform {
|
|
190
190
|
) {
|
191
191
|
this.gatewayMap[id] = new DeconzAccessory.Gateway(this, context)
|
192
192
|
}
|
193
|
+
} else {
|
194
|
+
const gateway = this.gatewayMap[context.gid]
|
195
|
+
if (gateway != null) {
|
196
|
+
gateway.addAccessory(id)
|
197
|
+
}
|
193
198
|
}
|
194
199
|
} catch (error) { this.error(error) }
|
195
200
|
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzService/AirPressure.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 AirPressure extends DeconzService.SensorsResource {
|
14
|
+
constructor (accessory, resource, params = {}) {
|
15
|
+
params.Service = accessory.Services.eve.AirPressureSensor
|
16
|
+
super(accessory, resource, params)
|
17
|
+
|
18
|
+
this.addCharacteristicDelegate({
|
19
|
+
key: 'airPressure',
|
20
|
+
Characteristic: this.Characteristics.eve.AirPressure,
|
21
|
+
unit: ' hPa'
|
22
|
+
})
|
23
|
+
|
24
|
+
this.addCharacteristicDelegate({
|
25
|
+
key: 'elevation',
|
26
|
+
Characteristic: this.Characteristics.eve.Elevation,
|
27
|
+
value: 0
|
28
|
+
})
|
29
|
+
|
30
|
+
this.addCharacteristicDelegates()
|
31
|
+
|
32
|
+
this.update(resource.body)
|
33
|
+
}
|
34
|
+
|
35
|
+
updateState (state) {
|
36
|
+
if (state.pressure != null) {
|
37
|
+
this.values.airPressure = Math.round(state.pressure * 10) / 10
|
38
|
+
}
|
39
|
+
super.updateState(state)
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
module.exports = AirPressure
|