homebridge-deconz 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/cli/deconz.js +12 -0
  2. package/lib/Deconz/ApiClient.js +34 -1
  3. package/lib/Deconz/ApiResponse.js +1 -1
  4. package/lib/Deconz/Device.js +0 -7
  5. package/lib/Deconz/Resource.js +749 -24
  6. package/lib/DeconzAccessory/Contact.js +54 -0
  7. package/lib/DeconzAccessory/Gateway.js +83 -61
  8. package/lib/DeconzAccessory/Light.js +42 -37
  9. package/lib/DeconzAccessory/Motion.js +51 -0
  10. package/lib/DeconzAccessory/Sensor.js +35 -0
  11. package/lib/DeconzAccessory/Temperature.js +63 -0
  12. package/lib/DeconzAccessory/Thermostat.js +50 -0
  13. package/lib/DeconzAccessory/WarningDevice.js +56 -0
  14. package/lib/DeconzAccessory/WindowCovering.js +47 -0
  15. package/lib/DeconzAccessory/index.js +142 -2
  16. package/lib/DeconzPlatform.js +5 -0
  17. package/lib/DeconzService/AirPressure.js +43 -0
  18. package/lib/DeconzService/AirQuality.js +17 -10
  19. package/lib/DeconzService/Alarm.js +13 -9
  20. package/lib/DeconzService/Battery.js +43 -0
  21. package/lib/DeconzService/Button.js +9 -2
  22. package/lib/DeconzService/CarbonMonoxide.js +38 -0
  23. package/lib/DeconzService/Consumption.js +65 -0
  24. package/lib/DeconzService/Contact.js +60 -0
  25. package/lib/DeconzService/Daylight.js +132 -0
  26. package/lib/DeconzService/DeviceSettings.js +11 -0
  27. package/lib/DeconzService/Flag.js +52 -0
  28. package/lib/DeconzService/Humidity.js +37 -0
  29. package/lib/DeconzService/Leak.js +38 -0
  30. package/lib/DeconzService/Light.js +12 -164
  31. package/lib/DeconzService/LightLevel.js +54 -0
  32. package/lib/DeconzService/LightsResource.js +112 -0
  33. package/lib/DeconzService/Motion.js +101 -0
  34. package/lib/DeconzService/Outlet.js +76 -0
  35. package/lib/DeconzService/Power.js +83 -0
  36. package/lib/DeconzService/SensorsResource.js +96 -0
  37. package/lib/DeconzService/Smoke.js +38 -0
  38. package/lib/DeconzService/Status.js +53 -0
  39. package/lib/DeconzService/Switch.js +93 -0
  40. package/lib/DeconzService/Temperature.js +63 -0
  41. package/lib/DeconzService/Thermostat.js +175 -0
  42. package/lib/DeconzService/WarningDevice.js +68 -0
  43. package/lib/DeconzService/WindowCovering.js +139 -0
  44. package/lib/DeconzService/index.js +76 -25
  45. package/package.json +2 -2
  46. package/lib/DeconzAccessory/Device.js +0 -69
  47. 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/Sensor.js
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 Deconz = require('../Deconz')
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 homebridgeLib.ServiceDelegate {
16
- constructor (accessory, resource) {
17
- super(accessory, {
18
- id: resource.id,
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 * 254.0 / 100.0)
53
+ const bri = Math.round(value * 2.54)
73
54
  this.put({ bri: bri })
74
55
  this.updateAdaptiveLighting()
75
56
  }
@@ -206,16 +187,7 @@ class Light extends homebridgeLib.ServiceDelegate {
206
187
  })
207
188
  }
208
189
 
209
- this.addCharacteristicDelegate({
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({
@@ -272,50 +244,6 @@ class Light extends homebridgeLib.ServiceDelegate {
272
244
  }
273
245
  }
274
246
 
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
247
  updateState (state) {
320
248
  let updateAdaptiveLighting = false
321
249
  for (const key in state) {
@@ -330,11 +258,9 @@ class Light extends homebridgeLib.ServiceDelegate {
330
258
  this.values.anyOn = value
331
259
  updateAdaptiveLighting = true
332
260
  break
333
- case 'alert':
334
- break
335
261
  case 'bri':
336
262
  if (!this.recentlyUpdated) {
337
- this.values.brightness = Math.round(value * 100.0 / 254.0)
263
+ this.values.brightness = Math.round(value / 2.54)
338
264
  updateAdaptiveLighting = true
339
265
  }
340
266
  break
@@ -347,6 +273,7 @@ class Light extends homebridgeLib.ServiceDelegate {
347
273
  }
348
274
  break
349
275
  case 'effect':
276
+ this.values.colorLoop = value === 'colorloop'
350
277
  break
351
278
  case 'hue':
352
279
  if (!this.capabilities.xy) {
@@ -356,18 +283,11 @@ class Light extends homebridgeLib.ServiceDelegate {
356
283
  case 'on':
357
284
  this.values.on = value
358
285
  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
286
  case 'sat':
365
287
  if (!this.capabilities.xy) {
366
288
  this.values.hue = value
367
289
  }
368
290
  break
369
- case 'scene':
370
- break
371
291
  case 'xy':
372
292
  if (
373
293
  !this.recentlyUpdated &&
@@ -379,30 +299,13 @@ class Light extends homebridgeLib.ServiceDelegate {
379
299
  }
380
300
  break
381
301
  default:
382
- this.warn('state.%s: unknown %s attribute', key, this.rtype)
383
302
  break
384
303
  }
385
304
  }
386
305
  if (updateAdaptiveLighting) {
387
306
  this.updateAdaptiveLighting()
388
307
  }
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
- }
308
+ super.updateState(state)
406
309
  }
407
310
 
408
311
  initAdaptiveLighting () {
@@ -468,61 +371,6 @@ class Light extends homebridgeLib.ServiceDelegate {
468
371
  this.adaptiveLighting.deactivate()
469
372
  this.values.activeTransitionCount = 0
470
373
  }
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
374
  }
527
375
 
528
376
  module.exports = Light
@@ -0,0 +1,54 @@
1
+ // homebridge-deconz/lib/DeconzService/LightLevel.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 { lightLevelToLux } = Deconz.ApiClient
12
+
13
+ /**
14
+ * @memberof DeconzService
15
+ */
16
+ class LightLevel extends DeconzService.SensorsResource {
17
+ constructor (accessory, resource, params = {}) {
18
+ params.Service = accessory.Services.hap.LightSensor
19
+ super(accessory, resource, params)
20
+
21
+ this.addCharacteristicDelegate({
22
+ key: 'lightlevel',
23
+ Characteristic: this.Characteristics.hap.CurrentAmbientLightLevel,
24
+ unit: ' lux'
25
+ })
26
+
27
+ this.addCharacteristicDelegate({
28
+ key: 'dark',
29
+ Characteristic: this.Characteristics.my.Dark
30
+ })
31
+
32
+ this.addCharacteristicDelegate({
33
+ key: 'daylight',
34
+ Characteristic: this.Characteristics.my.Daylight
35
+ })
36
+
37
+ this.addCharacteristicDelegates()
38
+ }
39
+
40
+ updateState (state) {
41
+ if (state.lightlevel != null) {
42
+ this.values.lightlevel = lightLevelToLux(state.lightlevel)
43
+ }
44
+ if (state.dark != null) {
45
+ this.values.dark = state.dark
46
+ }
47
+ if (state.daylight != null) {
48
+ this.values.daylight = state.daylight
49
+ }
50
+ super.updateState(state)
51
+ }
52
+ }
53
+
54
+ module.exports = LightLevel