homebridge-deconz 0.0.10 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -6
- package/cli/deconz.js +12 -0
- package/config.schema.json +1 -0
- 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 +751 -25
- package/lib/DeconzAccessory/Contact.js +54 -0
- package/lib/DeconzAccessory/Gateway.js +102 -66
- 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 +144 -2
- package/lib/DeconzPlatform.js +5 -2
- 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 +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 +122 -172
- 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 +162 -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,132 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzService/Daylight.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
|
+
const Deconz = require('../Deconz')
|
10
|
+
|
11
|
+
const { dateToString, lightLevelToLux } = Deconz.ApiClient
|
12
|
+
|
13
|
+
const daylightEvents = {
|
14
|
+
100: { name: 'Solar Midnight', period: 'Night' },
|
15
|
+
110: { name: 'Astronomical Dawn', period: 'Astronomical Twilight' },
|
16
|
+
120: { name: 'Nautical Dawn', period: 'Nautical Twilight' },
|
17
|
+
130: { name: 'Dawn', period: 'Twilight' },
|
18
|
+
140: { name: 'Sunrise', period: 'Sunrise' },
|
19
|
+
150: { name: 'End Sunrise', period: 'Golden Hour' },
|
20
|
+
160: { name: 'End Golden Hour', period: 'Day' },
|
21
|
+
170: { name: 'Solar Noon', period: 'Day' },
|
22
|
+
180: { name: 'Start Golden Hour', period: 'Golden Hour' },
|
23
|
+
190: { name: 'Start Sunset', period: 'Sunset' },
|
24
|
+
200: { name: 'Sunset', period: 'Twilight' },
|
25
|
+
210: { name: 'Dusk', period: 'Nautical Twilight' },
|
26
|
+
220: { name: 'Nautical Dusk', period: 'Astronomical Twilight' },
|
27
|
+
230: { name: 'Astronomical Dusk', period: 'Night' }
|
28
|
+
}
|
29
|
+
|
30
|
+
const daylightPeriods = {
|
31
|
+
Night: { lightlevel: 0, daylight: false, dark: true },
|
32
|
+
'Astronomical Twilight': { lightlevel: 100, daylight: false, dark: true },
|
33
|
+
'Nautical Twilight': { lightlevel: 1000, daylight: false, dark: true },
|
34
|
+
Twilight: { lightlevel: 10000, daylight: false, dark: false },
|
35
|
+
Sunrise: { lightlevel: 15000, daylight: true, dark: false },
|
36
|
+
Sunset: { lightlevel: 20000, daylight: true, dark: false },
|
37
|
+
'Golden Hour': { lightlevel: 40000, daylight: true, dark: false },
|
38
|
+
Day: { lightlevel: 65535, daylight: true, dark: false }
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* @memberof DeconzService
|
43
|
+
*/
|
44
|
+
class Daylight extends DeconzService.SensorsResource {
|
45
|
+
constructor (accessory, resource, params = {}) {
|
46
|
+
params.Service = accessory.Services.hap.LightSensor
|
47
|
+
super(accessory, resource, params)
|
48
|
+
|
49
|
+
this.addCharacteristicDelegate({
|
50
|
+
key: 'lightlevel',
|
51
|
+
Characteristic: this.Characteristics.hap.CurrentAmbientLightLevel,
|
52
|
+
unit: ' lux'
|
53
|
+
})
|
54
|
+
|
55
|
+
this.addCharacteristicDelegate({
|
56
|
+
key: 'dark',
|
57
|
+
Characteristic: this.Characteristics.my.Dark
|
58
|
+
})
|
59
|
+
|
60
|
+
this.addCharacteristicDelegate({
|
61
|
+
key: 'daylight',
|
62
|
+
Characteristic: this.Characteristics.my.Daylight
|
63
|
+
})
|
64
|
+
|
65
|
+
this.addCharacteristicDelegate({
|
66
|
+
key: 'status',
|
67
|
+
Characteristic: this.Characteristics.my.Status,
|
68
|
+
props: {
|
69
|
+
minValue: 100,
|
70
|
+
maxValue: 230,
|
71
|
+
perms: [
|
72
|
+
this.Characteristic.Perms.READ,
|
73
|
+
this.Characteristic.Perms.NOTIFY]
|
74
|
+
},
|
75
|
+
value: resource.body.state.status
|
76
|
+
})
|
77
|
+
|
78
|
+
this.addCharacteristicDelegate({
|
79
|
+
key: 'lastEvent',
|
80
|
+
Characteristic: this.Characteristics.my.LastEvent
|
81
|
+
})
|
82
|
+
|
83
|
+
this.addCharacteristicDelegate({
|
84
|
+
key: 'period',
|
85
|
+
Characteristic: this.Characteristics.my.Period
|
86
|
+
})
|
87
|
+
|
88
|
+
this.addCharacteristicDelegates()
|
89
|
+
|
90
|
+
this.addCharacteristicDelegate({
|
91
|
+
key: 'sunrise',
|
92
|
+
Characteristic: this.Characteristics.my.Sunrise
|
93
|
+
})
|
94
|
+
|
95
|
+
this.addCharacteristicDelegate({
|
96
|
+
key: 'sunset',
|
97
|
+
Characteristic: this.Characteristics.my.Sunset
|
98
|
+
})
|
99
|
+
|
100
|
+
if (!resource.body.config.configured) {
|
101
|
+
this.warn('%s: %s not configured', resource.rpath, resource.body.type)
|
102
|
+
}
|
103
|
+
|
104
|
+
this.update(resource.body)
|
105
|
+
}
|
106
|
+
|
107
|
+
updateState (state) {
|
108
|
+
if (state.status != null) {
|
109
|
+
this.values.status = state.status
|
110
|
+
const { name, period } = daylightEvents[state.status]
|
111
|
+
this.values.lastEvent = name
|
112
|
+
this.values.period = period
|
113
|
+
const { lightlevel } = daylightPeriods[period]
|
114
|
+
this.values.lightlevel = lightLevelToLux(lightlevel)
|
115
|
+
}
|
116
|
+
if (state.dark != null) {
|
117
|
+
this.values.dark = state.dark
|
118
|
+
}
|
119
|
+
if (state.daylight != null) {
|
120
|
+
this.values.daylight = state.daylight
|
121
|
+
}
|
122
|
+
if (state.sunrise != null) {
|
123
|
+
this.values.sunrise = dateToString(state.sunrise)
|
124
|
+
}
|
125
|
+
if (state.sunset != null) {
|
126
|
+
this.values.sunset = dateToString(state.sunset)
|
127
|
+
}
|
128
|
+
super.updateState(state)
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
module.exports = Daylight
|
@@ -16,6 +16,8 @@ class DeviceSettings extends homebridgeLib.ServiceDelegate {
|
|
16
16
|
params.Service = accessory.Services.my.DeconzDevice
|
17
17
|
super(accessory, params)
|
18
18
|
|
19
|
+
this.debug('settings: %j', params)
|
20
|
+
|
19
21
|
this.addCharacteristicDelegate({
|
20
22
|
key: 'expose',
|
21
23
|
Characteristic: this.Characteristics.my.Expose,
|
@@ -25,6 +27,15 @@ class DeviceSettings extends homebridgeLib.ServiceDelegate {
|
|
25
27
|
accessory.gateway.exposeDevice(params.subtype, value)
|
26
28
|
})
|
27
29
|
|
30
|
+
if (params.hasRepeat != null) {
|
31
|
+
this.addCharacteristicDelegate({
|
32
|
+
key: 'repeat',
|
33
|
+
Characteristic: this.Characteristics.my.Repeat,
|
34
|
+
props: { minValue: 0, maxValue: 1, minStep: 1 },
|
35
|
+
value: 0
|
36
|
+
})
|
37
|
+
}
|
38
|
+
|
28
39
|
if (params.logLevel != null) {
|
29
40
|
this.addCharacteristicDelegate({
|
30
41
|
key: 'logLevel',
|
@@ -0,0 +1,52 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzService/Flag.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 Flag extends DeconzService.SensorsResource {
|
14
|
+
constructor (accessory, resource, params = {}) {
|
15
|
+
params.Service = accessory.Services.hap.Switch
|
16
|
+
super(accessory, resource, params)
|
17
|
+
|
18
|
+
if (resource.capabilities.readonly) {
|
19
|
+
this.addCharacteristicDelegate({
|
20
|
+
key: 'on',
|
21
|
+
Characteristic: this.Characteristics.hap.On,
|
22
|
+
props: {
|
23
|
+
perms: [
|
24
|
+
this.Characteristic.Perms.READ, this.Characteristic.Perms.NOTIFY
|
25
|
+
]
|
26
|
+
}
|
27
|
+
})
|
28
|
+
} else {
|
29
|
+
this.addCharacteristicDelegate({
|
30
|
+
key: 'on',
|
31
|
+
Characteristic: this.Characteristics.hap.On
|
32
|
+
}).on('didSet', async (value, fromHomeKit) => {
|
33
|
+
if (fromHomeKit) {
|
34
|
+
await this.put('/state', { flag: value })
|
35
|
+
}
|
36
|
+
})
|
37
|
+
}
|
38
|
+
|
39
|
+
this.addCharacteristicDelegates()
|
40
|
+
|
41
|
+
this.update(resource.body)
|
42
|
+
}
|
43
|
+
|
44
|
+
updateState (state) {
|
45
|
+
if (state.flag != null) {
|
46
|
+
this.values.on = state.flag
|
47
|
+
}
|
48
|
+
super.updateState(state)
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
module.exports = Flag
|
@@ -0,0 +1,37 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzService/Humidity.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 Humidity extends DeconzService.SensorsResource {
|
14
|
+
constructor (accessory, resource, params = {}) {
|
15
|
+
params.Service = accessory.Services.hap.HumiditySensor
|
16
|
+
super(accessory, resource, params)
|
17
|
+
|
18
|
+
this.addCharacteristicDelegate({
|
19
|
+
key: 'humidity',
|
20
|
+
Characteristic: this.Characteristics.hap.CurrentRelativeHumidity,
|
21
|
+
unit: '%'
|
22
|
+
})
|
23
|
+
|
24
|
+
this.addCharacteristicDelegates()
|
25
|
+
|
26
|
+
this.update(resource.body)
|
27
|
+
}
|
28
|
+
|
29
|
+
updateState (state) {
|
30
|
+
if (state.humidity != null) {
|
31
|
+
this.values.humidity = Math.round(state.humidity / 10) / 10
|
32
|
+
}
|
33
|
+
super.updateState(state)
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
module.exports = Humidity
|
@@ -0,0 +1,38 @@
|
|
1
|
+
// homebridge-deconz/lib/DeconzService/Leak.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 Leak extends DeconzService.SensorsResource {
|
14
|
+
constructor (accessory, resource, params = {}) {
|
15
|
+
params.Service = accessory.Services.hap.LeakSensor
|
16
|
+
super(accessory, resource, params)
|
17
|
+
|
18
|
+
this.addCharacteristicDelegate({
|
19
|
+
key: 'leak',
|
20
|
+
Characteristic: this.Characteristics.hap.LeakDetected
|
21
|
+
})
|
22
|
+
|
23
|
+
super.addCharacteristicDelegates()
|
24
|
+
|
25
|
+
this.update(resource.body)
|
26
|
+
}
|
27
|
+
|
28
|
+
updateState (state) {
|
29
|
+
if (state.water != null || state.test != null) {
|
30
|
+
this.values.leak = state.water || state.test
|
31
|
+
? this.Characteristics.hap.LeakDetected.LEAK_DETECTED
|
32
|
+
: this.Characteristics.hap.LeakDetected.LEAK_NOT_DETECTED
|
33
|
+
}
|
34
|
+
super.updateState(state)
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
module.exports = Leak
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// homebridge-deconz/lib/DeconzService/
|
1
|
+
// homebridge-deconz/lib/DeconzService/Light.js
|
2
2
|
// Copyright © 2022 Erik Baauw. All rights reserved.
|
3
3
|
//
|
4
4
|
// Homebridge plugin for deCONZ.
|
@@ -6,34 +6,15 @@
|
|
6
6
|
'use strict'
|
7
7
|
|
8
8
|
const homebridgeLib = require('homebridge-lib')
|
9
|
-
const
|
9
|
+
const DeconzService = require('../DeconzService')
|
10
10
|
|
11
|
-
const { dateToString } = Deconz.ApiClient
|
12
11
|
const { timeout } = homebridgeLib
|
13
12
|
const { xyToHsv, hsvToXy, ctToXy } = homebridgeLib.Colour
|
14
13
|
|
15
|
-
class Light extends
|
16
|
-
constructor (accessory, resource) {
|
17
|
-
|
18
|
-
|
19
|
-
name: resource.body.name,
|
20
|
-
subtype: resource.subtype,
|
21
|
-
Service: accessory.Services.hap.Lightbulb
|
22
|
-
})
|
23
|
-
this.id = resource.id
|
24
|
-
this.gateway = accessory.gateway
|
25
|
-
this.client = accessory.client
|
26
|
-
this.resource = resource
|
27
|
-
this.rtype = resource.rtype
|
28
|
-
this.rid = resource.rid
|
29
|
-
this.rpath = resource.rpath +
|
30
|
-
(resource.rtype === 'groups' ? '/action' : '/state')
|
31
|
-
this.capabilities = resource.capabilities
|
32
|
-
|
33
|
-
this.debug('%s: capabilities: %j', this.resource.rpath, this.capabilities)
|
34
|
-
|
35
|
-
this.targetState = {}
|
36
|
-
this.deferrals = []
|
14
|
+
class Light extends DeconzService.LightsResource {
|
15
|
+
constructor (accessory, resource, params = {}) {
|
16
|
+
params.Service = accessory.Services.hap.Lightbulb
|
17
|
+
super(accessory, resource, params)
|
37
18
|
|
38
19
|
this.addCharacteristicDelegate({
|
39
20
|
key: 'on',
|
@@ -66,10 +47,10 @@ class Light extends homebridgeLib.ServiceDelegate {
|
|
66
47
|
key: 'brightness',
|
67
48
|
Characteristic: this.Characteristics.hap.Brightness,
|
68
49
|
unit: '%',
|
69
|
-
value: this.resource.body.state.bri
|
50
|
+
value: Math.round(this.resource.body.state.bri / 2.54)
|
70
51
|
}).on('didSet', (value, fromHomeKit) => {
|
71
52
|
if (fromHomeKit) {
|
72
|
-
const bri = Math.round(value *
|
53
|
+
const bri = Math.round(value * 2.54)
|
73
54
|
this.put({ bri: bri })
|
74
55
|
this.updateAdaptiveLighting()
|
75
56
|
}
|
@@ -206,23 +187,18 @@ class Light extends homebridgeLib.ServiceDelegate {
|
|
206
187
|
})
|
207
188
|
}
|
208
189
|
|
209
|
-
this.
|
210
|
-
key: 'lastSeen',
|
211
|
-
Characteristic: this.Characteristics.my.LastSeen,
|
212
|
-
silent: true
|
213
|
-
})
|
214
|
-
|
215
|
-
this.addCharacteristicDelegate({
|
216
|
-
key: 'statusFault',
|
217
|
-
Characteristic: this.Characteristics.hap.StatusFault
|
218
|
-
})
|
190
|
+
this.addCharacteristicDelegates()
|
219
191
|
|
220
192
|
if (this.capabilities.bri && this.capabilities.ct && !this.capabilities.hs) {
|
221
193
|
this.addCharacteristicDelegate({
|
222
194
|
key: 'supportedTransitionConfiguration',
|
223
195
|
Characteristic: this.Characteristics.hap
|
224
196
|
.SupportedCharacteristicValueTransitionConfiguration,
|
225
|
-
silent: true
|
197
|
+
silent: true,
|
198
|
+
getter: async () => {
|
199
|
+
this.initAdaptiveLighting()
|
200
|
+
return this.adaptiveLighting.generateConfiguration()
|
201
|
+
}
|
226
202
|
})
|
227
203
|
this.addCharacteristicDelegate({
|
228
204
|
key: 'transitionControl',
|
@@ -230,11 +206,9 @@ class Light extends homebridgeLib.ServiceDelegate {
|
|
230
206
|
.CharacteristicValueTransitionControl,
|
231
207
|
silent: true,
|
232
208
|
getter: async () => {
|
233
|
-
this.initAdaptiveLighting()
|
234
209
|
return this.adaptiveLighting.generateControl()
|
235
210
|
},
|
236
211
|
setter: async (value) => {
|
237
|
-
this.initAdaptiveLighting()
|
238
212
|
const control = this.adaptiveLighting.parseControl(value)
|
239
213
|
this.context.transitionControl = value
|
240
214
|
const response = this.adaptiveLighting.generateControlResponse()
|
@@ -259,9 +233,107 @@ class Light extends homebridgeLib.ServiceDelegate {
|
|
259
233
|
this.updateAdaptiveLighting()
|
260
234
|
}
|
261
235
|
})
|
262
|
-
|
263
|
-
|
236
|
+
}
|
237
|
+
|
238
|
+
if (this.resource.rtype === 'groups') {
|
239
|
+
this.sceneServices = []
|
240
|
+
for (const scene of this.resource.body.scenes) {
|
241
|
+
const service = new homebridgeLib.ServiceDelegate(accessory, {
|
242
|
+
name: this.resource.body.name + ' ' + scene.name,
|
243
|
+
Service: this.Services.hap.Switch,
|
244
|
+
subtype: this.subtype + '-S' + scene.id
|
245
|
+
})
|
246
|
+
service.addCharacteristicDelegate({
|
247
|
+
key: 'on',
|
248
|
+
Characteristic: this.Characteristics.hap.On,
|
249
|
+
value: false
|
250
|
+
}).on('didSet', async (value, fromHomeKit) => {
|
251
|
+
this.checkAdaptiveLighting()
|
252
|
+
if (fromHomeKit && value) {
|
253
|
+
try {
|
254
|
+
const path = this.resource.rpath + '/scenes/' + scene.id + '/recall'
|
255
|
+
this.debug('PUT %s', path)
|
256
|
+
await this.client.put(path)
|
257
|
+
} catch (error) { this.error(error) }
|
258
|
+
await timeout(this.platform.config.waitTimeReset)
|
259
|
+
service.values.on = false
|
260
|
+
}
|
261
|
+
})
|
262
|
+
this.sceneServices.push(service)
|
263
|
+
}
|
264
|
+
}
|
265
|
+
|
266
|
+
if (this.capabilities.effects != null) {
|
267
|
+
this.effectServices = []
|
268
|
+
this.addCharacteristicDelegate({
|
269
|
+
key: 'effect',
|
270
|
+
value: -1,
|
271
|
+
silent: true
|
272
|
+
}).on('didSet', (value) => {
|
273
|
+
for (const i in this.capabilities.effects) {
|
274
|
+
this.effectServices[i].values.on = value === i
|
275
|
+
}
|
276
|
+
})
|
277
|
+
for (const i in this.capabilities.effects) {
|
278
|
+
const effect = this.capabilities.effects[i]
|
279
|
+
const service = new homebridgeLib.ServiceDelegate(accessory, {
|
280
|
+
name: this.resource.body.name + ' ' + effect,
|
281
|
+
Service: this.Services.hap.Switch,
|
282
|
+
subtype: this.subtype + '-E' + i
|
283
|
+
})
|
284
|
+
service.addCharacteristicDelegate({
|
285
|
+
key: 'on',
|
286
|
+
Characteristic: this.Characteristics.hap.On
|
287
|
+
}).on('didSet', (value, fromHomeKit) => {
|
288
|
+
if (fromHomeKit) {
|
289
|
+
this.checkAdaptiveLighting()
|
290
|
+
this.values.effect = value ? i : -1
|
291
|
+
const newEffect = value
|
292
|
+
? effect.toLowerCase()
|
293
|
+
: 'none'
|
294
|
+
this.put({ effect: newEffect })
|
295
|
+
}
|
296
|
+
})
|
297
|
+
this.effectServices.push(service)
|
264
298
|
}
|
299
|
+
// if (this.capabilities.effectSpeed) {
|
300
|
+
// this.addCharacteristicDelegate({
|
301
|
+
// key: 'effectSpeed',
|
302
|
+
// Characteristic: this.Characteristics.my.EffectSpeed,
|
303
|
+
// value: 50
|
304
|
+
// }).on('didSet', (value) => {
|
305
|
+
// this.setEffectSpeed(value)
|
306
|
+
// })
|
307
|
+
// this.hk.effectColours = []
|
308
|
+
// for (let i = 0; i <= 5; i++) {
|
309
|
+
// const service = new this.Service.Lightbulb(
|
310
|
+
// this.name + ' Effect Color ' + (i + 1), this.subtype + '-C' + i
|
311
|
+
// )
|
312
|
+
// service.addCharacteristicDelegate({
|
313
|
+
// key: 'on',
|
314
|
+
// Characteristic: this.Characteristics.hap.On,
|
315
|
+
// value: true
|
316
|
+
// }).on('didSet', (value) => {
|
317
|
+
// this.setEffectOn(i, value)
|
318
|
+
// })
|
319
|
+
// service.addCharacteristicDelegate({
|
320
|
+
// key: 'hue',
|
321
|
+
// Characteristic: this.Characteristics.hap.Hue,
|
322
|
+
// value: i * 60
|
323
|
+
// }).on('didSet', (value) => {
|
324
|
+
// this.setEffectHue(i, value)
|
325
|
+
// })
|
326
|
+
// service.addCharacteristicDelegate({
|
327
|
+
// key: 'saturation',
|
328
|
+
// Characteristic: this.Characteristics.hap.Saturation,
|
329
|
+
// value: 100
|
330
|
+
// }).on('didSet', (value) => {
|
331
|
+
// this.setEffectSat(i, value)
|
332
|
+
// })
|
333
|
+
// this.effectServices.push(service)
|
334
|
+
// }
|
335
|
+
// }
|
336
|
+
// this.checkEffect(this.obj.state.effect)
|
265
337
|
}
|
266
338
|
|
267
339
|
this.settings = {
|
@@ -272,50 +344,6 @@ class Light extends homebridgeLib.ServiceDelegate {
|
|
272
344
|
}
|
273
345
|
}
|
274
346
|
|
275
|
-
update (body) {
|
276
|
-
if (this.updating) {
|
277
|
-
return
|
278
|
-
}
|
279
|
-
for (const key in body) {
|
280
|
-
const value = body[key]
|
281
|
-
switch (key) {
|
282
|
-
case 'action':
|
283
|
-
// Copied to `state` by `Resource` during polling.
|
284
|
-
break
|
285
|
-
case 'state':
|
286
|
-
this.updateState(value)
|
287
|
-
break
|
288
|
-
case 'lastannounced':
|
289
|
-
// this.values.lastBoot = dateToString(value)
|
290
|
-
break
|
291
|
-
case 'lastseen':
|
292
|
-
this.resource.body.lastseen = value
|
293
|
-
this.values.lastSeen = dateToString(value)
|
294
|
-
break
|
295
|
-
case 'colorcapabilities':
|
296
|
-
case 'ctmax':
|
297
|
-
case 'ctmin':
|
298
|
-
case 'devicemembership':
|
299
|
-
case 'etag':
|
300
|
-
case 'id':
|
301
|
-
case 'lights':
|
302
|
-
case 'hascolor':
|
303
|
-
case 'manufacturername':
|
304
|
-
case 'modelid':
|
305
|
-
case 'name':
|
306
|
-
case 'powerup':
|
307
|
-
case 'scenes':
|
308
|
-
case 'swversion':
|
309
|
-
case 'type':
|
310
|
-
case 'uniqueid':
|
311
|
-
break
|
312
|
-
default:
|
313
|
-
this.warn('%s: unknown %s attribute', key, this.rtype)
|
314
|
-
break
|
315
|
-
}
|
316
|
-
}
|
317
|
-
}
|
318
|
-
|
319
347
|
updateState (state) {
|
320
348
|
let updateAdaptiveLighting = false
|
321
349
|
for (const key in state) {
|
@@ -330,11 +358,9 @@ class Light extends homebridgeLib.ServiceDelegate {
|
|
330
358
|
this.values.anyOn = value
|
331
359
|
updateAdaptiveLighting = true
|
332
360
|
break
|
333
|
-
case 'alert':
|
334
|
-
break
|
335
361
|
case 'bri':
|
336
362
|
if (!this.recentlyUpdated) {
|
337
|
-
this.values.brightness = Math.round(value
|
363
|
+
this.values.brightness = Math.round(value / 2.54)
|
338
364
|
updateAdaptiveLighting = true
|
339
365
|
}
|
340
366
|
break
|
@@ -347,6 +373,11 @@ class Light extends homebridgeLib.ServiceDelegate {
|
|
347
373
|
}
|
348
374
|
break
|
349
375
|
case 'effect':
|
376
|
+
this.values.colorLoop = value === 'colorloop'
|
377
|
+
if (this.capabilities.effects != null) {
|
378
|
+
const effectName = value[0].toUpperCase() + value.slice(1)
|
379
|
+
this.values.effect = '' + this.capabilities.effects.indexOf(effectName)
|
380
|
+
}
|
350
381
|
break
|
351
382
|
case 'hue':
|
352
383
|
if (!this.capabilities.xy) {
|
@@ -356,18 +387,11 @@ class Light extends homebridgeLib.ServiceDelegate {
|
|
356
387
|
case 'on':
|
357
388
|
this.values.on = value
|
358
389
|
break
|
359
|
-
case 'reachable':
|
360
|
-
this.values.statusFault = value
|
361
|
-
? this.Characteristics.hap.StatusFault.NO_FAULT
|
362
|
-
: this.Characteristics.hap.StatusFault.GENERAL_FAULT
|
363
|
-
break
|
364
390
|
case 'sat':
|
365
391
|
if (!this.capabilities.xy) {
|
366
392
|
this.values.hue = value
|
367
393
|
}
|
368
394
|
break
|
369
|
-
case 'scene':
|
370
|
-
break
|
371
395
|
case 'xy':
|
372
396
|
if (
|
373
397
|
!this.recentlyUpdated &&
|
@@ -379,30 +403,13 @@ class Light extends homebridgeLib.ServiceDelegate {
|
|
379
403
|
}
|
380
404
|
break
|
381
405
|
default:
|
382
|
-
this.warn('state.%s: unknown %s attribute', key, this.rtype)
|
383
406
|
break
|
384
407
|
}
|
385
408
|
}
|
386
409
|
if (updateAdaptiveLighting) {
|
387
410
|
this.updateAdaptiveLighting()
|
388
411
|
}
|
389
|
-
|
390
|
-
|
391
|
-
async identify () {
|
392
|
-
try {
|
393
|
-
if (this.capabilities.alert) {
|
394
|
-
if (this.capabilities.breathe) {
|
395
|
-
await this.client.put({ alert: 'breathe' })
|
396
|
-
await timeout(1500)
|
397
|
-
return this.client.put({ alert: 'stop' })
|
398
|
-
}
|
399
|
-
return this.put({ alert: 'select' })
|
400
|
-
}
|
401
|
-
} catch (error) {
|
402
|
-
if (!(error instanceof Deconz.ApiClient.HttpError)) {
|
403
|
-
this.warn(error)
|
404
|
-
}
|
405
|
-
}
|
412
|
+
super.updateState(state)
|
406
413
|
}
|
407
414
|
|
408
415
|
initAdaptiveLighting () {
|
@@ -410,8 +417,6 @@ class Light extends homebridgeLib.ServiceDelegate {
|
|
410
417
|
this.adaptiveLighting = new homebridgeLib.AdaptiveLighting(
|
411
418
|
this.brightnessDelegate, this.colorTemperatureDelegate
|
412
419
|
)
|
413
|
-
this.values.supportedTransitionConfiguration =
|
414
|
-
this.adaptiveLighting.generateConfiguration()
|
415
420
|
if (this.values.activeTransitionCount > 0) {
|
416
421
|
const control = this.adaptiveLighting.parseControl(
|
417
422
|
this.context.transitionControl
|
@@ -462,67 +467,12 @@ class Light extends homebridgeLib.ServiceDelegate {
|
|
462
467
|
}
|
463
468
|
|
464
469
|
checkAdaptiveLighting (key, value) {
|
465
|
-
if (this.fromAdaptiveLighting) {
|
470
|
+
if (this.adaptiveLighting == null || this.fromAdaptiveLighting) {
|
466
471
|
return
|
467
472
|
}
|
468
473
|
this.adaptiveLighting.deactivate()
|
469
474
|
this.values.activeTransitionCount = 0
|
470
475
|
}
|
471
|
-
|
472
|
-
// Collect changes into a combined request.
|
473
|
-
put (state) {
|
474
|
-
for (const key in state) {
|
475
|
-
this.resource.body.state[key] = state[key]
|
476
|
-
this.targetState[key] = state[key]
|
477
|
-
}
|
478
|
-
this._put()
|
479
|
-
}
|
480
|
-
|
481
|
-
// Send the request (for the combined changes) to the gateway.
|
482
|
-
async _put () {
|
483
|
-
try {
|
484
|
-
if (this.updating) {
|
485
|
-
return
|
486
|
-
}
|
487
|
-
this.updating = true
|
488
|
-
if (this.settings.waitTimeUpdate > 0) {
|
489
|
-
await timeout(this.settings.waitTimeUpdate)
|
490
|
-
}
|
491
|
-
const targetState = this.targetState
|
492
|
-
this.targetState = {}
|
493
|
-
this.updating = false
|
494
|
-
if (
|
495
|
-
this.gateway.transitionTime !== this.gateway.defaultTransitionTime &&
|
496
|
-
targetState.transitiontime === undefined
|
497
|
-
) {
|
498
|
-
targetState.transitiontime = this.gateway.transitionTime * 10
|
499
|
-
this.gateway.resetTransitionTime()
|
500
|
-
}
|
501
|
-
if (this.capabilities.noTransition) {
|
502
|
-
if (
|
503
|
-
(
|
504
|
-
targetState.on != null || targetState.bri != null ||
|
505
|
-
targetState.bri_inc != null
|
506
|
-
) && (
|
507
|
-
targetState.xy != null || targetState.ct != null ||
|
508
|
-
targetState.hue != null || targetState.sat != null ||
|
509
|
-
targetState.effect != null
|
510
|
-
)
|
511
|
-
) {
|
512
|
-
targetState.transitiontime = 0
|
513
|
-
}
|
514
|
-
}
|
515
|
-
this.debug('PUT %s %j', this.rpath, targetState)
|
516
|
-
await this.client.put(this.rpath, targetState)
|
517
|
-
this.recentlyUpdated = true
|
518
|
-
await timeout(500)
|
519
|
-
this.recentlyUpdated = false
|
520
|
-
} catch (error) {
|
521
|
-
if (!(error instanceof Deconz.ApiClient.HttpError)) {
|
522
|
-
this.warn(error)
|
523
|
-
}
|
524
|
-
}
|
525
|
-
}
|
526
476
|
}
|
527
477
|
|
528
478
|
module.exports = Light
|