homebridge-lib 5.1.24-5 → 5.2.2

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.
@@ -7,7 +7,6 @@
7
7
 
8
8
  const homebridgeLib = require('../index')
9
9
 
10
- const maxLogLevel = 4
11
10
  const startsWithUuid = /^[0-9A-F]{8}-[0-9A-F]{4}-[1-5][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}/
12
11
 
13
12
  /** Delegate of a HomeKit accessory.
@@ -35,9 +34,6 @@ class AccessoryDelegate extends homebridgeLib.Delegate {
35
34
  * @param {!string} params.firmware - The accessory firmware revision.
36
35
  * @param {?string} params.hardware - The accessory hardware revision.
37
36
  * @param {?string} params.software - The accessory software revision.
38
- * @param {integer} params.logLevel - The log level for the accessory.
39
- * @param {?boolean} [params.inheritLogLevel] - Inherit `logLevel` from
40
- * `platform` instead of maintaining it oneself.
41
37
  */
42
38
  constructor (platform, params = {}) {
43
39
  if (params.name == null) {
@@ -53,18 +49,16 @@ class AccessoryDelegate extends homebridgeLib.Delegate {
53
49
 
54
50
  // Link or create associated PlatformAccessory.
55
51
  this._accessory = this._platform._getAccessory(this, params)
56
- this._context = this._accessory.context
57
52
 
58
53
  if (params.logLevel != null) {
59
- this._context.logLevel = Math.max(0, Math.min(params.logLevel, maxLogLevel))
60
- } else if (params.inheritLogLevel != null) {
61
- if (params.inheritLogLevel) {
62
- Object.defineProperty(this, 'logLevel', {
63
- get () { return platform.logLevel }
64
- })
65
- }
66
- delete params.inheritLogLevel
54
+ this.warn('params.logLevel: deprecated')
67
55
  }
56
+ if (params.inheritLogLevel != null) {
57
+ this.warn('params.inheritLogLevel: deprecated')
58
+ }
59
+ this._context = this._accessory.context
60
+
61
+ delete this._context.logLevel
68
62
 
69
63
  // Setup shortcut for property values and values of the characteristics
70
64
  // of the _Accessory Information_ service.
@@ -270,16 +264,7 @@ class AccessoryDelegate extends homebridgeLib.Delegate {
270
264
  * @type {!integer}
271
265
  */
272
266
  get logLevel () {
273
- return this._context.logLevel
274
- }
275
-
276
- set logLevel (value) {
277
- const oldLogLevel = this._context.logLevel
278
- this._context.logLevel = Math.max(0, Math.min(value, maxLogLevel))
279
- this._platform._message(
280
- 'log', 2, this.name + ': ',
281
- 'set Log Level from %d to %d', oldLogLevel, this.logLevel
282
- )
267
+ return this.platform.logLevel
283
268
  }
284
269
 
285
270
  /** Inherit `logLevel` from another accessory delegate.
@@ -298,6 +283,19 @@ class AccessoryDelegate extends homebridgeLib.Delegate {
298
283
  })
299
284
  }
300
285
 
286
+ /** Manage `logLevel` from characteristic delegate.
287
+ * @param {CharacteristicDelegate} delegate - The delegate of the `logLevel`
288
+ * characteristic.
289
+ */
290
+ manageLogLevel (delegate) {
291
+ if (!(delegate instanceof homebridgeLib.CharacteristicDelegate)) {
292
+ throw new TypeError('delegate: not an CharacteristicDelegate')
293
+ }
294
+ Object.defineProperty(this, 'logLevel', {
295
+ get () { return delegate.value }
296
+ })
297
+ }
298
+
301
299
  // Called by homebridge when Identify is selected.
302
300
  _identify () {
303
301
  this.emit('identify')
@@ -5,6 +5,8 @@
5
5
 
6
6
  'use strict'
7
7
 
8
+ const homebridgeLib = require('../index')
9
+
8
10
  /* global BigInt */
9
11
 
10
12
  const epoch = (new Date('2001-01-01T00:00:00Z')).valueOf()
@@ -170,8 +172,12 @@ class AdaptiveLighting {
170
172
  * @param {integer} ct - The IID of the _Color Temperature_ characteristic.
171
173
  */
172
174
  constructor (bri, ct) {
173
- this.bri = bri
174
- this.ct = ct
175
+ this.bri = bri instanceof homebridgeLib.CharacteristicDelegate
176
+ ? bri._characteristic.iid
177
+ : bri
178
+ this.ct = ct instanceof homebridgeLib.CharacteristicDelegate
179
+ ? ct._characteristic.iid
180
+ : ct
175
181
  this._active = false
176
182
  }
177
183
 
@@ -200,6 +200,10 @@ class CharacteristicDelegate extends homebridgeLib.Delegate {
200
200
  return this._hasPerm(this.Characteristic.Perms.NOTIFY)
201
201
  }
202
202
 
203
+ get _writeResponse () {
204
+ return this._hasPerm(this.Characteristic.Perms.WRITE_RESPONSE)
205
+ }
206
+
203
207
  get _writeOnly () {
204
208
  return this._canWrite && !this._canRead && !this._canNotifiy
205
209
  }
@@ -375,6 +379,7 @@ class CharacteristicDelegate extends homebridgeLib.Delegate {
375
379
  // Called when characteristic is updated from HomeKit.
376
380
  async _onSet (v, callback) {
377
381
  const { value } = this.validate(v)
382
+ let result
378
383
 
379
384
  // Issue info message that Characteristic value was updated from HomeKit.
380
385
  if (this._writeOnly || this.value == null) {
@@ -407,7 +412,7 @@ class CharacteristicDelegate extends homebridgeLib.Delegate {
407
412
  callback(new Error('timed out'))
408
413
  }, this._timeout)
409
414
  try {
410
- await this._setter(value)
415
+ result = await this._setter(value)
411
416
  } catch (error) {
412
417
  clearTimeout(timeout)
413
418
  this.error(error)
@@ -423,7 +428,11 @@ class CharacteristicDelegate extends homebridgeLib.Delegate {
423
428
  }
424
429
 
425
430
  // Return status to HomeKit.
426
- callback()
431
+ if (this._writeResponse) {
432
+ callback(null, result)
433
+ } else {
434
+ callback()
435
+ }
427
436
 
428
437
  // Update persisted value in ~/.homebridge/accessories/cachedAccessories.
429
438
  this._serviceDelegate._context[this._key] = value
@@ -188,10 +188,11 @@ class EveHomeKitTypes extends homebridgeLib.CustomHomeKitTypes {
188
188
  }, 'Current Consumption')
189
189
 
190
190
  this.createCharacteristicClass('AirPressure', uuid('10F'), {
191
- format: this.Formats.UINT16,
191
+ format: this.Formats.FLOAT,
192
192
  unit: 'hPa',
193
193
  minValue: 700,
194
194
  maxValue: 1100,
195
+ minStep: 0.1,
195
196
  perms: [this.Perms.READ, this.Perms.NOTIFY]
196
197
  }, 'Air Pressure')
197
198
 
@@ -284,6 +285,11 @@ class EveHomeKitTypes extends homebridgeLib.CustomHomeKitTypes {
284
285
  perms: [this.Perms.READ, this.Perms.NOTIFY, this.Perms.WRITE],
285
286
  adminOnlyAccess: [this.Access.WRITE]
286
287
  })
288
+ this.Characteristics.Duration.VALID_VALUES = [
289
+ 5, 10, 20, 30,
290
+ 1 * 60, 2 * 60, 3 * 60, 5 * 60, 10 * 60, 20 * 60, 30 * 60,
291
+ 1 * 3600, 2 * 3600, 3 * 3600, 5 * 3600, 10 * 3600, 12 * 3600, 15 * 3600
292
+ ]
287
293
 
288
294
  this.createCharacteristicClass('ValvePosition', uuid('12E'), {
289
295
  format: this.Formats.UINT8,
@@ -589,7 +589,7 @@ class MyHomeKitTypes extends homebridgeLib.CustomHomeKitTypes {
589
589
  this.createCharacteristicClass('LogLevel', uuid('065'), {
590
590
  format: this.Formats.UINT8,
591
591
  minValue: 0,
592
- maxValue: 3,
592
+ maxValue: 3, // 4 for homebridge-zp
593
593
  minStep: 1, // Force Down|Up control in Eve
594
594
  perms: [this.Perms.READ, this.Perms.NOTIFY, this.Perms.WRITE],
595
595
  adminOnlyAccess: [this.Access.WRITE]
@@ -598,6 +598,7 @@ class MyHomeKitTypes extends homebridgeLib.CustomHomeKitTypes {
598
598
  this.Characteristics.LogLevel.LOG = 1
599
599
  this.Characteristics.LogLevel.DEBUG = 2
600
600
  this.Characteristics.LogLevel.VDEBUG = 3
601
+ this.Characteristics.LogLevel.VVDEBUG = 4
601
602
 
602
603
  this.createCharacteristicClass('Repeat', uuid('066'), {
603
604
  format: this.Formats.UINT8,
package/lib/Platform.js CHANGED
@@ -27,8 +27,6 @@ const context = {
27
27
  checkInterval: 7 * 24 * 3600
28
28
  }
29
29
 
30
- const globalKey = context.libName // + '@' + context.libVersion
31
-
32
30
  /** Homebridge dynamic platform plugin.
33
31
  *
34
32
  * `Platform` provides the following features to a platform plugin:
@@ -59,6 +57,8 @@ class Platform extends homebridgeLib.Delegate {
59
57
  static loadPlatform (homebridge, packageJson, platformName, Platform) {
60
58
  if (context.homebridge == null) {
61
59
  context.homebridge = homebridge
60
+ context.packageJson = packageJson
61
+ context.platformName = platformName
62
62
  context.homebridgeVersion = homebridge.serverVersion
63
63
  context.PlatformAccessory = homebridge.platformAccessory
64
64
  const hap = {
@@ -98,25 +98,6 @@ class Platform extends homebridgeLib.Delegate {
98
98
  my: Object.freeze(my.Characteristics)
99
99
  })
100
100
  }
101
- if (global[globalKey] == null) {
102
- global[globalKey] = {
103
- Platform: {
104
- platformName: context.libName,
105
- packageJson: libPackageJson,
106
- UpnpClient: homebridgeLib.UpnpClient
107
- }
108
- }
109
- homebridge.registerPlatform(
110
- // libPackageJson.name, 'Lib', homebridgeLib.Platform, false
111
- packageJson.name, 'Lib', homebridgeLib.Platform, false
112
- )
113
- // } else {
114
- // TODO: check compatible homebridge-lib version.
115
- }
116
- global[globalKey][Platform.name] = {
117
- platformName: platformName,
118
- packageJson: packageJson
119
- }
120
101
  homebridge.registerPlatform(
121
102
  packageJson.name, platformName, Platform, true
122
103
  )
@@ -148,50 +129,19 @@ class Platform extends homebridgeLib.Delegate {
148
129
  this._log = log
149
130
  this._configJson = configJson
150
131
  this._homebridge = homebridge
151
- const myContext = global[globalKey][this.className]
152
- this._platformName = myContext.platformName
153
- this._pluginName = myContext.packageJson.name
154
- this._pluginVersion = myContext.packageJson.version
155
- if (myContext.packageJson.name === context.libName) {
156
- this._isHomebridgeLib = true
157
- myContext.heartbeat = this
158
- // Delay start of Homebridge's HAP server until all plugins have
159
- // initialised.
160
- this.accessories = (f) => {
161
- this.on('initialised', () => { f([]) })
162
- }
163
- // this.debug('Categories: %j', this.Accessory.Categories)
164
- // for (const type of ['Access', 'Formats', 'Perms', 'Units']) {
165
- // this.debug('%s: %j', type, this.Characteristic[type])
166
- // }
167
- // for (const module of ['hap', 'eve', 'my']) {
168
- // this.debug('Services.%s: %j', module, Object.keys(this.Services[module]))
169
- // this.debug('Characteristics.%s: %j', module, Object.keys(this.Characteristics[module]))
170
- // }
171
- } else {
172
- /** Configure an accessory, after it has been restored from peristent
173
- * storage.
174
- *
175
- * Called by homebridge when restoring peristed accessories, typically from
176
- * `~/.homebridge/accessories/cachedAccessories`.
177
- * @method
178
- * @param {!PlatformAccessory} accessory - The restored Homebridge
179
- * [PlatformAccessory](https://github.com/nfarina/homebridge/blob/master/lib/platformAccessory.js).
180
- */
181
- this.configureAccessory = this._configureAccessory
182
- }
132
+ this._platformName = context.platformName
133
+ this._pluginName = context.packageJson.name
134
+ this._pluginVersion = context.packageJson.version
135
+
183
136
  this._accessories = {}
184
137
  this._accessoryDelegates = {}
185
138
 
186
- if (myContext.platform != null) {
139
+ if (context.platform != null) {
187
140
  this.fatal(
188
- 'config.json: duplicate entry for %s platform', myContext.platformName
141
+ 'config.json: duplicate entry for %s platform', context.platformName
189
142
  )
190
143
  }
191
- myContext.platform = this
192
- if (global[globalKey].Platform == null) {
193
- this.fatal('%s platform not registered', context.libName)
194
- }
144
+ context.platform = this
195
145
  this._identify()
196
146
 
197
147
  this._homebridge
@@ -205,54 +155,29 @@ class Platform extends homebridgeLib.Delegate {
205
155
  // Main platform function.
206
156
  // Called by homebridge after restoring accessories from cache.
207
157
  async _main () {
208
- if (this._isHomebridgeLib || global[globalKey].Platform.heartbeat == null) {
209
- // process.on('unhandledRejection', (error) => {
210
- // this.error('unhandled rejection: %s', error.stack)
211
- // })
212
- global[globalKey].Platform.heartbeat = this
213
- /** System information.
214
- * @type {SystemInfo}
215
- * @readonly
216
- */
217
- this.systemInfo = new homebridgeLib.SystemInfo()
218
- this.systemInfo
219
- .on('error', (error) => { this.warn(error) })
220
- .on('exec', (command) => { this.debug('exec: %s', command) })
221
- .on('readFile', (filename) => { this.debug('read file: %s', filename) })
222
- await this.systemInfo.init()
223
- this.log('hardware: %s', this.systemInfo.hwInfo.prettyName)
224
- this.log('os: %s', this.systemInfo.osInfo.prettyName)
225
- this.heartbeatClients = Object.keys(global[globalKey]).filter((key) => {
226
- return global[globalKey][key].platform != null
227
- })
228
- this.debug('starting heartbeat for %j', this.heartbeatClients)
229
- this._heartbeatStart = new Date()
230
- setTimeout(() => { this._beat(-1) }, 1000)
231
- this.on('exit', () => {
232
- this.debug('flush cachedAccessories')
233
- this._homebridge.updatePlatformAccessories()
234
- this.log('goodbye')
235
- })
236
- } else {
237
- this.systemInfo = global[globalKey].Platform.heartbeat.systemInfo
238
- }
239
- if (this._isHomebridgeLib) {
240
- const jobs = []
241
- for (const plugin in global[globalKey]) {
242
- const platform = global[globalKey][plugin].platform
243
- if (
244
- platform != null && platform !== this &&
245
- Object.keys(platform._accessories).length === 0
246
- ) {
247
- this.warn('waiting on %s', plugin)
248
- jobs.push(events.once(platform, 'initialised'))
249
- }
250
- }
251
- for (const job of jobs) {
252
- await job
253
- }
254
- this.emit('initialised')
255
- }
158
+ // process.on('unhandledRejection', (error) => {
159
+ // this.error('unhandled rejection: %s', error.stack)
160
+ // })
161
+ /** System information.
162
+ * @type {SystemInfo}
163
+ * @readonly
164
+ */
165
+ this.systemInfo = new homebridgeLib.SystemInfo()
166
+ this.systemInfo
167
+ .on('error', (error) => { this.warn(error) })
168
+ .on('exec', (command) => { this.debug('exec: %s', command) })
169
+ .on('readFile', (filename) => { this.debug('read file: %s', filename) })
170
+ await this.systemInfo.init()
171
+ this.log('hardware: %s', this.systemInfo.hwInfo.prettyName)
172
+ this.log('os: %s', this.systemInfo.osInfo.prettyName)
173
+ this._heartbeatStart = new Date()
174
+ setTimeout(() => { this._beat(-1) }, 1000)
175
+ this.on('exit', () => {
176
+ this.debug('flush cachedAccessories')
177
+ this._homebridge.updatePlatformAccessories()
178
+ this.log('goodbye')
179
+ })
180
+
256
181
  const n = Object.keys(this._accessories).length
257
182
  if (n > 0) {
258
183
  this.log('restored %d accessories from cache', n)
@@ -301,15 +226,11 @@ class Platform extends homebridgeLib.Delegate {
301
226
  this._homebridge.updatePlatformAccessories()
302
227
  }
303
228
 
304
- for (const plugin of this.heartbeatClients) {
305
- global[globalKey][plugin].platform._heartbeat(beat)
306
- }
307
- }
308
-
309
- _heartbeat (beat) {
310
229
  if (beat % context.checkInterval === 0) {
311
- this._checkLatest()
230
+ this._checkLatest(this._pluginName, this._pluginVersion)
231
+ this._checkLatest(context.libName, context.libVersion)
312
232
  }
233
+
313
234
  /** Emitted every second.
314
235
  * @event Platform#heartbeat
315
236
  * @param {number} beat - The sequence number of this heartbeat.
@@ -364,13 +285,10 @@ class Platform extends homebridgeLib.Delegate {
364
285
 
365
286
  // Issue an identity message.
366
287
  _identify () {
367
- const s = this._isHomebridgeLib
368
- ? ''
369
- : ', ' + context.libName + ' v' + context.libVersion
370
288
  this.log(
371
- '%s v%s, node v%s, homebridge v%s%s',
372
- this._pluginName, this._pluginVersion,
373
- context.nodeVersion, context.homebridgeVersion, s
289
+ '%s v%s, node v%s, homebridge v%s, %s v%s',
290
+ this._pluginName, this._pluginVersion, context.nodeVersion,
291
+ context.homebridgeVersion, context.libName, context.libVersion
374
292
  )
375
293
  if (context.nodeVersion !== context.recommendedNodeVersion) {
376
294
  this.warn(
@@ -391,16 +309,16 @@ class Platform extends homebridgeLib.Delegate {
391
309
  }
392
310
 
393
311
  // Check the NPM registry for the latest version of this plugin.
394
- async _checkLatest () {
312
+ async _checkLatest (name, version) {
395
313
  try {
396
- if (global[globalKey].Platform.npmRegistry == null) {
397
- const npmRegistry = new homebridgeLib.HttpClient({
314
+ if (this.npmRegistry == null) {
315
+ this.npmRegistry = new homebridgeLib.HttpClient({
398
316
  https: true,
399
317
  host: 'registry.npmjs.org',
400
318
  json: true,
401
319
  maxSockets: 1
402
320
  })
403
- npmRegistry
321
+ this.npmRegistry
404
322
  .on('error', (error) => {
405
323
  this.log(
406
324
  'npm registry: request %d: %s %s', error.request.id,
@@ -428,15 +346,14 @@ class Platform extends homebridgeLib.Delegate {
428
346
  response.statusCode, response.statusMessage
429
347
  )
430
348
  })
431
- global[globalKey].Platform.npmRegistry = npmRegistry
432
349
  }
433
- const { body } = await global[globalKey].Platform.npmRegistry.get(
434
- '/' + this._pluginName + '/latest', { Accept: 'application/json' })
350
+ const { body } = await this.npmRegistry.get(
351
+ '/' + name + '/latest', { Accept: 'application/json' })
435
352
  if (body != null && body.version != null) {
436
- if (body.version !== this._pluginVersion) {
437
- this.warn('latest version: %s v%s', this._pluginName, body.version)
353
+ if (body.version !== version) {
354
+ this.warn('latest version: %s v%s', name, body.version)
438
355
  } else {
439
- this.debug('latest version: %s v%s', this._pluginName, body.version)
356
+ this.debug('latest version: %s v%s', name, body.version)
440
357
  }
441
358
  }
442
359
  } catch (error) {
@@ -448,7 +365,16 @@ class Platform extends homebridgeLib.Delegate {
448
365
 
449
366
  // ===== Handle Accessories ==================================================
450
367
 
451
- _configureAccessory (accessory) {
368
+ /** Configure an accessory, after it has been restored from peristent
369
+ * storage.
370
+ *
371
+ * Called by homebridge when restoring peristed accessories, typically from
372
+ * `~/.homebridge/accessories/cachedAccessories`.
373
+ * @method
374
+ * @param {!PlatformAccessory} accessory - The restored Homebridge
375
+ * [PlatformAccessory](https://github.com/nfarina/homebridge/blob/master/lib/platformAccessory.js).
376
+ */
377
+ configureAccessory (accessory) {
452
378
  const className = accessory.context.className
453
379
  const version = accessory.context.version
454
380
  const id = accessory.context.id
@@ -584,7 +510,7 @@ class Platform extends homebridgeLib.Delegate {
584
510
  if (this._upnpMonitor != null) {
585
511
  throw new SyntaxError('upnpConfig(): already called')
586
512
  }
587
- this._upnpMonitor = new global[globalKey].Platform.UpnpClient(config)
513
+ this._upnpMonitor = new homebridgeLib.UpnpClient(config)
588
514
  this._upnpMonitor
589
515
  .on('error', (error) => {
590
516
  this.error('upnp: error')
@@ -0,0 +1,111 @@
1
+ // homebridge-lib/lib/ServiceDelegate/AccessoryInformation.js
2
+ //
3
+ // Library for Homebridge plugins.
4
+ // Copyright © 2017-2022 Erik Baauw. All rights reserved.
5
+
6
+ 'use strict'
7
+
8
+ const homebridgeLib = require('../../index')
9
+
10
+ const { ServiceDelegate } = homebridgeLib
11
+
12
+ /** Class for an _AccessoryInformation_ service delegate.
13
+ *
14
+ * This delegate sets up a `Services.hap.AccessoryInformation` HomeKit service
15
+ * with the following HomeKit characteristics:
16
+ *
17
+ * key | Characteristic | isOptional
18
+ * -------------- | -------------------------------------- | ----------
19
+ * `name` | `Characteristics.hap.Name` |
20
+ * `id` | `Characteristics.hap.SerialNumber` |
21
+ * `manufacturer` | `Characteristics.hap.Manufacturer` |
22
+ * `model` | `Characteristics.hap.Model` |
23
+ * `firmware` | `Characteristics.hap.FirmwareRevision` |
24
+ * `hardware` | `Characteristics.hap.HardwareRevision` | Y
25
+ * `software` | `Characteristics.hap.SoftwareRevision` | Y
26
+ * @extends ServiceDelegate
27
+ * @memberof ServiceDelegate
28
+ */
29
+ class AccessoryInformation extends ServiceDelegate {
30
+ /** Create a new instance of an _AccessoryInformation_ service delegate.
31
+ * @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
32
+ * corresponding HomeKit accessory.
33
+ * @param {!object} params - The parameters for the
34
+ * _AccessoryInformation_ HomeKit service.
35
+ * @param {!string} params.name - Initial value for
36
+ * `Characteristics.hap.Name`. Also used to prefix log and error messages.
37
+ * @param {!string} params.id - Initial value for
38
+ * `Characteristics.hap.SerialNumber`.
39
+ * @param {!string} params.manufacturer - Initial value for
40
+ * `Characteristics.hap.Manufacturer`.
41
+ * @param {!string} params.model - Initial value for
42
+ * `Characteristics.hap.Model`.
43
+ * @param {!string} params.firmware - Initial value for
44
+ * `Characteristics.hap.FirmwareRevision`.
45
+ * @param {?string} params.hardware - Initial value for
46
+ * `Characteristics.hap.HardwareRevision`.
47
+ * @param {?string} params.software - Initial value for
48
+ * `Characteristics.hap.SoftwareRevision`.
49
+ */
50
+ constructor (accessoryDelegate, params = {}) {
51
+ params.name = accessoryDelegate.name
52
+ params.Service = accessoryDelegate.Services.hap.AccessoryInformation
53
+ super(accessoryDelegate, params)
54
+ this.addCharacteristicDelegate({
55
+ key: 'id',
56
+ Characteristic: this.Characteristics.hap.SerialNumber,
57
+ value: params.id
58
+ })
59
+ this.addCharacteristicDelegate({
60
+ key: 'identify',
61
+ Characteristic: this.Characteristics.hap.Identify
62
+ })
63
+ this.addCharacteristicDelegate({
64
+ key: 'manufacturer',
65
+ Characteristic: this.Characteristics.hap.Manufacturer,
66
+ value: params.manufacturer
67
+ })
68
+ this.addCharacteristicDelegate({
69
+ key: 'model',
70
+ Characteristic: this.Characteristics.hap.Model,
71
+ value: params.model
72
+ })
73
+ this.addCharacteristicDelegate({
74
+ key: 'firmware',
75
+ Characteristic: this.Characteristics.hap.FirmwareRevision,
76
+ value: params.firmware
77
+ })
78
+ if (params.hardware != null || this._context.hardware != null) {
79
+ this.addCharacteristicDelegate({
80
+ key: 'hardware',
81
+ Characteristic: this.Characteristics.hap.HardwareRevision,
82
+ value: params.hardware
83
+ })
84
+ }
85
+ if (params.software != null || this._context.software != null) {
86
+ this.addCharacteristicDelegate({
87
+ key: 'software',
88
+ Characteristic: this.Characteristics.hap.SoftwareRevision,
89
+ value: params.software
90
+ })
91
+ }
92
+ }
93
+
94
+ addCharacteristicDelegate (params = {}) {
95
+ const delegate = super.addCharacteristicDelegate(params)
96
+ Object.defineProperty(this.accessoryDelegate.values, params.key, {
97
+ configurable: true, // make sure we can delete it again
98
+ writeable: true,
99
+ get () { return delegate.value },
100
+ set (value) { delegate.value = value }
101
+ })
102
+ return delegate
103
+ }
104
+
105
+ removeCharacteristicDelegate (key) {
106
+ delete this.accessoryDelegate.values[key]
107
+ super.removeCharacteristicDelegate(key)
108
+ }
109
+ }
110
+
111
+ module.exports = AccessoryInformation
@@ -0,0 +1,87 @@
1
+ // homebridge-lib/lib/ServiceDelegate/Battery.js
2
+ //
3
+ // Library for Homebridge plugins.
4
+ // Copyright © 2017-2022 Erik Baauw. All rights reserved.
5
+
6
+ 'use strict'
7
+
8
+ const homebridgeLib = require('../../index')
9
+
10
+ const { ServiceDelegate } = homebridgeLib
11
+
12
+ /** Class for a _Battery_ service delegate.
13
+ *
14
+ * This delegate sets up a `Services.hap.Battery` HomeKit service
15
+ * with the following HomeKit characteristics:
16
+ *
17
+ * key | Characteristic | isOptional
18
+ * ------------------ | -------------------------------------- | ----------
19
+ * `name` | `Characteristics.hap.Name` |
20
+ * `batteryLevel` | `Characteristics.hap.BatteryLevel` | Y
21
+ * `chargingState` | `Characteristics.hap.ChargingState` | Y
22
+ * `statusLowBattery` | `Characteristics.hap.StatusLowBattery` | Y
23
+ * `lowBatteryThreshold`| `Characteristics.my.LowBatteryThreshold` | Y
24
+ *
25
+ * @extends ServiceDelegate
26
+ * @memberof ServiceDelegate
27
+ */
28
+ class Battery extends ServiceDelegate {
29
+ /** Create a new instance of an _Battery_ service delegate.
30
+ * @param {!AccessoryDelegate} accessoryDelegate - The delegate of the
31
+ * corresponding HomeKit accessory.
32
+ * @param {object} params - The parameters for the
33
+ * _AccessoryInformation_ HomeKit service.
34
+ * @param {integer} [params.batteryLevel=100] - Initial value for
35
+ * `Characteristics.hap.BatteryLevel`.
36
+ * @param {integer} [params.chargingState=NOT_CHARGEABLE] - Initial value for
37
+ * `Characteristics.hap.ChargingState`.
38
+ * @param {integer} [params.statusLowBattery=BATTERY_LEVEL_NORMAL] - Initial
39
+ * value for `Characteristics.hap.StatusLowBattery`.
40
+ * @param {integer} [params.lowBatteryThreshold=20] - Initial value for
41
+ * low battery threshold.
42
+ */
43
+ constructor (accessoryDelegate, params = {}) {
44
+ params.name = accessoryDelegate.name + ' Battery'
45
+ params.Service = accessoryDelegate.Services.hap.BatteryService
46
+ super(accessoryDelegate, params)
47
+ this.addCharacteristicDelegate({
48
+ key: 'batteryLevel',
49
+ Characteristic: this.Characteristics.hap.BatteryLevel,
50
+ unit: '%',
51
+ value: params.batteryLevel != null ? params.batteryLevel : 100
52
+ }).on('didSet', (value) => {
53
+ this.updateStatusLowBattery()
54
+ })
55
+ this.addCharacteristicDelegate({
56
+ key: 'chargingState',
57
+ Characteristic: this.Characteristics.hap.ChargingState,
58
+ value: params.chargingState != null
59
+ ? params.chargingState
60
+ : this.Characteristics.hap.ChargingState.NOT_CHARGEABLE
61
+ })
62
+ this.addCharacteristicDelegate({
63
+ key: 'statusLowBattery',
64
+ Characteristic: this.Characteristics.hap.StatusLowBattery,
65
+ value: params.statusLowBattery != null
66
+ ? params.statusLowBattery
67
+ : this.Characteristics.hap.StatusLowBattery.BATTERY_LEVEL_NORMAL
68
+ })
69
+ this.addCharacteristicDelegate({
70
+ key: 'lowBatteryThreshold',
71
+ Characteristic: this.Characteristics.my.LowBatteryThreshold,
72
+ unit: '%',
73
+ value: params.lowBatteryThreshold != null ? params.lowBatteryThreshold : 20
74
+ }).on('didSet', (value) => {
75
+ this.updateStatusLowBattery()
76
+ })
77
+ }
78
+
79
+ updateStatusLowBattery () {
80
+ this.values.statusLowBattery =
81
+ this.values.batteryLevel <= this.values.lowBatteryThreshold
82
+ ? this.Characteristics.hap.StatusLowBattery.BATTERY_LEVEL_LOW
83
+ : this.Characteristics.hap.StatusLowBattery.BATTERY_LEVEL_NORMAL
84
+ }
85
+ }
86
+
87
+ module.exports = Battery