homebridge-deconz 0.0.9 → 0.0.12
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 +3 -6
- package/cli/deconz.js +12 -0
- package/config.schema.json +2 -1
- package/homebridge-ui/public/index.html +26 -0
- package/homebridge-ui/public/style.css +0 -0
- package/homebridge-ui/server.js +43 -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 +752 -27
- package/lib/DeconzAccessory/Contact.js +54 -0
- package/lib/DeconzAccessory/Gateway.js +102 -66
- package/lib/DeconzAccessory/Light.js +42 -35
- 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 +145 -4
- package/lib/DeconzPlatform.js +6 -3
- package/lib/DeconzService/AirPressure.js +43 -0
- package/lib/DeconzService/AirQuality.js +20 -11
- package/lib/DeconzService/Alarm.js +13 -9
- package/lib/DeconzService/Battery.js +53 -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 +12 -4
- package/lib/DeconzService/Flag.js +52 -0
- package/lib/DeconzService/GatewaySettings.js +1 -4
- package/lib/DeconzService/Humidity.js +37 -0
- package/lib/DeconzService/Leak.js +38 -0
- package/lib/DeconzService/Light.js +289 -280
- 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 +79 -25
- package/package.json +6 -5
- package/lib/Client/ApiError.js +0 -42
- package/lib/DeconzAccessory/Device.js +0 -69
- package/lib/DeconzService/Sensor.js +0 -61
@@ -0,0 +1,54 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzAccessory/Contact.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 contact sensor,
|
14
|
+
* with Eve Door & Window history.
|
15
|
+
* @extends DeconzAccessory
|
16
|
+
* @memberof DeconzAccessory
|
17
|
+
*/
|
18
|
+
class Contact extends DeconzAccessory {
|
19
|
+
/** Instantiate a contact sensor delegate.
|
20
|
+
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
21
|
+
* @param {Deconz.Device} device - The device.
|
22
|
+
*/
|
23
|
+
constructor (gateway, device) {
|
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
|
+
this.historyService = new History.Contact(
|
39
|
+
this, {},
|
40
|
+
this.service.characteristicDelegate('contact'),
|
41
|
+
this.service.characteristicDelegate('timesOpened'),
|
42
|
+
this.service.characteristicDelegate('lastActivation')
|
43
|
+
)
|
44
|
+
|
45
|
+
this.createSettingsService()
|
46
|
+
|
47
|
+
setImmediate(() => {
|
48
|
+
this.debug('initialised')
|
49
|
+
this.emit('initialised')
|
50
|
+
})
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
module.exports = Contact
|
@@ -8,7 +8,7 @@
|
|
8
8
|
const homebridgeLib = require('homebridge-lib')
|
9
9
|
|
10
10
|
const Deconz = require('../Deconz')
|
11
|
-
const DeconzAccessory = require('
|
11
|
+
const DeconzAccessory = require('../DeconzAccessory')
|
12
12
|
const DeconzService = require('../DeconzService')
|
13
13
|
|
14
14
|
const rtypes = ['lights', 'sensors', 'groups']
|
@@ -20,8 +20,6 @@ const periodicEvents = [
|
|
20
20
|
]
|
21
21
|
|
22
22
|
/** Delegate class for a deCONZ gateway.
|
23
|
-
*
|
24
|
-
* @class
|
25
23
|
* @extends AccessoryDelegate
|
26
24
|
* @memberof DeconzAccessory
|
27
25
|
*/
|
@@ -41,7 +39,7 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
41
39
|
model: params.config.modelid + ' / ' + params.config.devicename,
|
42
40
|
firmware: '0.0.0',
|
43
41
|
software: params.config.swversion,
|
44
|
-
category: platform.Accessory.Categories.
|
42
|
+
category: platform.Accessory.Categories.BRIDGE
|
45
43
|
})
|
46
44
|
|
47
45
|
this.gateway = this
|
@@ -62,6 +60,9 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
62
60
|
if (this.context.blacklist == null) {
|
63
61
|
this.context.blacklist = {}
|
64
62
|
}
|
63
|
+
if (this.context.fullState != null) {
|
64
|
+
this.analyseFullState(this.context.fullState, { analyseOnly: true })
|
65
|
+
}
|
65
66
|
|
66
67
|
this.addPropertyDelegate({
|
67
68
|
key: 'apiKey',
|
@@ -139,6 +140,7 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
139
140
|
primaryService: true,
|
140
141
|
host: params.host
|
141
142
|
})
|
143
|
+
this.manageLogLevel(this.service.characteristicDelegate('logLevel'))
|
142
144
|
|
143
145
|
/** The service delegate for the Stateless Programmable Switch service.
|
144
146
|
* @type {DeconzService.Button}
|
@@ -214,9 +216,6 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
214
216
|
try {
|
215
217
|
this.debug('initialising...')
|
216
218
|
this.initialBeat = beat
|
217
|
-
if (this.context.fullState != null) {
|
218
|
-
this.analyseFullState(this.context.fullState, true)
|
219
|
-
}
|
220
219
|
await this.connect()
|
221
220
|
this.initialised = true
|
222
221
|
this.debug('initialised')
|
@@ -441,6 +440,9 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
441
440
|
}
|
442
441
|
try {
|
443
442
|
try {
|
443
|
+
if (this.context.migration != null) {
|
444
|
+
await this.client.delete(this.context.migration)
|
445
|
+
}
|
444
446
|
await this.client.deleteApiKey()
|
445
447
|
} catch (error) {}
|
446
448
|
this.values.apiKey = null
|
@@ -456,10 +458,12 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
456
458
|
this.exposeErrors = {}
|
457
459
|
this.context.blacklist = {}
|
458
460
|
this.context.fullState = null
|
461
|
+
this.context.migration = null
|
459
462
|
this.service.values.lights = false
|
460
463
|
this.service.values.sensors = false
|
461
464
|
this.service.values.groups = false
|
462
465
|
this.service.values.schedules = false
|
466
|
+
this.service.values.logLevel = 2
|
463
467
|
this.values.rtypes = []
|
464
468
|
} catch (error) { this.error(error) }
|
465
469
|
}
|
@@ -503,12 +507,12 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
503
507
|
if (this.accessoryById[id] == null) {
|
504
508
|
const device = this.deviceById[id]
|
505
509
|
delete this.exposeErrorById[id]
|
506
|
-
const { body
|
510
|
+
const { body } = device.resource
|
507
511
|
this.log('%s: add accessory', body.name)
|
508
512
|
let { serviceName } = device.resource
|
509
513
|
if (DeconzAccessory[serviceName] == null) {
|
510
|
-
this.warn('%s: %s: not yet supported %s type', body.name, body.type, rtype)
|
511
|
-
serviceName = '
|
514
|
+
// this.warn('%s: %s: not yet supported %s type', body.name, body.type, rtype)
|
515
|
+
serviceName = 'Sensor'
|
512
516
|
}
|
513
517
|
const accessory = new DeconzAccessory[serviceName](this, device)
|
514
518
|
this.accessoryById[id] = accessory
|
@@ -592,6 +596,9 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
592
596
|
throw new RangeError(`${id}: unknown device ID`)
|
593
597
|
}
|
594
598
|
if (this.serviceById[id] == null) {
|
599
|
+
if (Object.keys(this.serviceById).length >= 97) {
|
600
|
+
return null
|
601
|
+
}
|
595
602
|
const { resource, rpaths } = this.deviceById[id]
|
596
603
|
const { body } = resource
|
597
604
|
const service = new DeconzService.DeviceSettings(this, {
|
@@ -644,11 +651,14 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
644
651
|
return
|
645
652
|
}
|
646
653
|
this.context.fullState.config = config
|
647
|
-
if (
|
654
|
+
if (
|
655
|
+
this.service.values.lights || this.nDevicesByRtype.lights > 0 ||
|
656
|
+
this.service.values.sensors || this.nDevicesByRtype.sensors > 0
|
657
|
+
) {
|
648
658
|
this.context.fullState.lights = await this.client.get('/lights')
|
649
659
|
this.context.fullState.sensors = await this.client.get('/sensors')
|
650
660
|
}
|
651
|
-
if (this.service.values.groups) {
|
661
|
+
if (this.service.values.groups || this.nDevicesByRtype.groups > 0) {
|
652
662
|
this.context.fullState.groups = await this.client.get('/groups')
|
653
663
|
this.context.fullState.groups[0] = await this.client.get('/groups/0')
|
654
664
|
}
|
@@ -656,7 +666,7 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
656
666
|
this.context.fullState.schedules = await this.client.get('/schedules')
|
657
667
|
}
|
658
668
|
}
|
659
|
-
this.analyseFullState(this.context.fullState)
|
669
|
+
await this.analyseFullState(this.context.fullState)
|
660
670
|
} catch (error) {
|
661
671
|
this.error(error)
|
662
672
|
} finally {
|
@@ -697,12 +707,12 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
697
707
|
* accessories, corresponding to devices have been blacklisted.
|
698
708
|
* @param {Object} fullState - The gateway full state, as returned by
|
699
709
|
* {@link DeconzAccessory.Gateway#poll poll()}.
|
700
|
-
* @param {
|
701
|
-
*
|
710
|
+
* @param {Object} params - Parameters
|
711
|
+
* @param {boolean} [params.logUnsupportedResources=false] - Issue debug
|
712
|
+
* messsages for unsupported resources.
|
713
|
+
* @param {boolean} [params.analyseOnly=false]
|
702
714
|
*/
|
703
|
-
analyseFullState (fullState,
|
704
|
-
this.update(fullState.config)
|
705
|
-
|
715
|
+
async analyseFullState (fullState, params = {}) {
|
706
716
|
/** Supported devices by device ID.
|
707
717
|
*
|
708
718
|
* Updated by
|
@@ -739,8 +749,10 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
739
749
|
for (const rtype of rtypes) {
|
740
750
|
this.deviceByRidByRtype[rtype] = {}
|
741
751
|
for (const rid in fullState[rtype]) {
|
742
|
-
|
743
|
-
|
752
|
+
try {
|
753
|
+
const body = fullState[rtype][rid]
|
754
|
+
this.analyseResource(rtype, rid, body, params.logUnsupported)
|
755
|
+
} catch (error) { this.error(error) }
|
744
756
|
}
|
745
757
|
}
|
746
758
|
|
@@ -773,64 +785,74 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
773
785
|
this.vdebug('%d %s devices', this.nDevicesByRtype[rtype], rtype)
|
774
786
|
}
|
775
787
|
|
788
|
+
if (params.analyseOnly) {
|
789
|
+
return
|
790
|
+
}
|
791
|
+
|
792
|
+
this.update(fullState.config)
|
793
|
+
|
776
794
|
let changed = false
|
777
795
|
|
778
796
|
this.vdebug('analysing accessories...')
|
779
797
|
for (const id in this.accessoryById) {
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
798
|
+
try {
|
799
|
+
if (
|
800
|
+
this.deviceById[id] == null
|
801
|
+
) {
|
802
|
+
delete this.context.blacklist[id]
|
803
|
+
this.deleteAccessory(id)
|
804
|
+
this.deleteService(id)
|
805
|
+
changed = true
|
806
|
+
} else {
|
807
|
+
/** Emitted when the gateway has been polled.
|
808
|
+
* @event DeconzAccessory.Device#polled
|
809
|
+
* @param {Deconz.Device} device - The updated device.
|
810
|
+
*/
|
811
|
+
this.accessoryById[id].emit('polled', this.deviceById[id])
|
812
|
+
}
|
813
|
+
} catch (error) { this.error(error) }
|
795
814
|
}
|
796
815
|
|
797
816
|
this.vdebug('analysing services...')
|
798
817
|
for (const id in this.serviceById) {
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
818
|
+
try {
|
819
|
+
if (
|
820
|
+
this.deviceById[id] == null ||
|
821
|
+
!this.values.rtypes.includes(this.deviceById[id].resource.rtype)
|
822
|
+
) {
|
823
|
+
delete this.exposeErrorById[id]
|
824
|
+
this.deleteService(id)
|
825
|
+
changed = true
|
826
|
+
}
|
827
|
+
} catch (error) { this.error(error) }
|
808
828
|
}
|
809
829
|
|
810
830
|
for (const rtype of this.values.rtypes) {
|
811
831
|
this.vdebug('analysing %s devices...', rtype)
|
812
832
|
const rids = Object.keys(this.deviceByRidByRtype[rtype]).sort()
|
813
833
|
for (const rid of rids) {
|
814
|
-
|
815
|
-
|
816
|
-
if (this.
|
817
|
-
this.
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
this.
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
this.
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
this.
|
831
|
-
|
834
|
+
try {
|
835
|
+
const { id } = this.deviceByRidByRtype[rtype][rid]
|
836
|
+
if (this.context.blacklist[id] == null) {
|
837
|
+
if (this.accessoryById[id] == null) {
|
838
|
+
this.addAccessory(id)
|
839
|
+
changed = true
|
840
|
+
}
|
841
|
+
if (this.serviceById[id] != null) {
|
842
|
+
this.deleteService(id)
|
843
|
+
changed = true
|
844
|
+
}
|
845
|
+
} else {
|
846
|
+
if (this.serviceById[id] == null) {
|
847
|
+
this.addService(id)
|
848
|
+
changed = true
|
849
|
+
}
|
850
|
+
if (this.accessoryById[id] != null) {
|
851
|
+
this.deleteAccessory(id)
|
852
|
+
changed = true
|
853
|
+
}
|
832
854
|
}
|
833
|
-
}
|
855
|
+
} catch (error) { this.error(error) }
|
834
856
|
}
|
835
857
|
}
|
836
858
|
|
@@ -847,8 +869,22 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
847
869
|
if (changed) {
|
848
870
|
this.nResourcesMonitored = Object.keys(this.accessoryByRpath).length
|
849
871
|
this.identify()
|
850
|
-
this.
|
851
|
-
|
872
|
+
if (this.context.migration == null) {
|
873
|
+
const response = await this.client.post('/resourcelinks', {
|
874
|
+
name: 'homebridge-deconz',
|
875
|
+
description: 'migration',
|
876
|
+
classid: 1,
|
877
|
+
links: Object.keys(this.resourceByRpath).sort()
|
878
|
+
})
|
879
|
+
this.context.migration = '/resourcelinks/' + response.success.id
|
880
|
+
} else {
|
881
|
+
await this.client.put(this.context.migration, {
|
882
|
+
links: Object.keys(this.resourceByRpath).sort()
|
883
|
+
})
|
884
|
+
}
|
885
|
+
this.log(
|
886
|
+
'migration: %s: %d resources', this.context.migration, this.nResources
|
887
|
+
)
|
852
888
|
}
|
853
889
|
}
|
854
890
|
|
@@ -861,7 +897,7 @@ class Gateway extends homebridgeLib.AccessoryDelegate {
|
|
861
897
|
* `groups`, `lights`, or `sensors`.
|
862
898
|
* @param {integer} rid - The resource ID of the resource.
|
863
899
|
* @param {object} body - The body of the resource.
|
864
|
-
* @param {boolean}
|
900
|
+
* @param {boolean} logUnsupported - Issue a debug message for
|
865
901
|
* unsupported resources.
|
866
902
|
*/
|
867
903
|
analyseResource (rtype, rid, body, logUnsupported) {
|
@@ -1,16 +1,17 @@
|
|
1
|
-
// homebridge-deconz/lib/DeconzAccessory/
|
1
|
+
// homebridge-deconz/lib/DeconzAccessory/Light.js
|
2
2
|
// Copyright © 2022 Erik Baauw. All rights reserved.
|
3
3
|
//
|
4
4
|
// Homebridge plugin for deCONZ.
|
5
5
|
|
6
6
|
'use strict'
|
7
7
|
|
8
|
-
const
|
9
|
-
const
|
8
|
+
const homebridgeLib = require('homebridge-lib')
|
9
|
+
const DeconzAccessory = require('../DeconzAccessory')
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
const { History } = homebridgeLib.ServiceDelegate
|
12
|
+
|
13
|
+
/** Delegate class for a HomeKit accessory, corresponding to a light device
|
14
|
+
* or groups resource.
|
14
15
|
* @extends DeconzAccessory
|
15
16
|
* @memberof DeconzAccessory
|
16
17
|
*/
|
@@ -19,47 +20,53 @@ class Light extends DeconzAccessory {
|
|
19
20
|
* @param {DeconzAccessory.Gateway} gateway - The gateway.
|
20
21
|
* @param {Deconz.Device} device - The device.
|
21
22
|
*/
|
22
|
-
constructor (gateway, device) {
|
23
|
-
super(gateway, device)
|
23
|
+
constructor (gateway, device, settings = {}) {
|
24
|
+
super(gateway, device, gateway.Accessory.Categories.LIGHTBULB)
|
24
25
|
|
25
26
|
this.identify()
|
26
27
|
|
27
|
-
this.
|
28
|
+
this.addPropertyDelegate({
|
29
|
+
key: 'serviceName',
|
30
|
+
value: device.resource.capabilities.bri ? 'Light' : 'Outlet'
|
31
|
+
})
|
28
32
|
|
29
|
-
this.
|
30
|
-
|
31
|
-
|
32
|
-
resource: this.device.rpaths.join(', '),
|
33
|
-
expose: true,
|
34
|
-
logLevel: gateway.logLevel
|
33
|
+
this.service = this.createService(device.resource, {
|
34
|
+
primaryService: true,
|
35
|
+
serviceName: this.values.serviceName
|
35
36
|
})
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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()
|
50
64
|
|
51
65
|
setImmediate(() => {
|
52
66
|
this.debug('initialised')
|
53
67
|
this.emit('initialised')
|
54
68
|
})
|
55
69
|
}
|
56
|
-
|
57
|
-
async identify () {
|
58
|
-
super.identify()
|
59
|
-
if (this.service != null) {
|
60
|
-
await this.service.identify()
|
61
|
-
}
|
62
|
-
}
|
63
70
|
}
|
64
71
|
|
65
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
|