homebridge-lib 5.1.24-4 → 5.2.1

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/index.js CHANGED
@@ -175,6 +175,13 @@ class homebridgeLib {
175
175
  */
176
176
  static get Platform () { return require('./lib/Platform') }
177
177
 
178
+ /** Delegate of a property of a HomeKit accessory or service.
179
+ * <br>See {@link PropertyDelegate}.
180
+ * @type {Class}
181
+ * @memberof module:homebridgeLib
182
+ */
183
+ static get PropertyDelegate () { return require('./lib/PropertyDelegate') }
184
+
178
185
  /** Delegate of a HomeKit service.
179
186
  * <br>See {@link ServiceDelegate}.
180
187
  * @type {Class}
@@ -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,22 @@ 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')
55
+ }
56
+ if (params.inheritLogLevel != null) {
57
+ this.warn('params.inheritLogLevel: deprecated')
67
58
  }
59
+ this._context = this._accessory.context
60
+
61
+ delete this._context.logLevel
62
+
63
+ // Setup shortcut for property values and values of the characteristics
64
+ // of the _Accessory Information_ service.
65
+ this._values = {} // by key
66
+
67
+ this._propertyDelegates = {}
68
68
 
69
69
  // Create delegate for AccessoryInformation service.
70
70
  this._serviceDelegates = {}
@@ -138,16 +138,88 @@ class AccessoryDelegate extends homebridgeLib.Delegate {
138
138
  }
139
139
  }
140
140
 
141
+ /** Creates a new {@link PropertyDelegate} instance, for a property of the
142
+ * associated HomeKit accessory.
143
+ *
144
+ * The property value is accessed through
145
+ * {@link AccessoryDelegate#values values}.
146
+ * The delegate is returned, but can also be accessed through
147
+ * {@link AccessoryDelegate#propertyDelegate propertyDelegate()}.
148
+ * @param {!object} params - Parameters of the property delegate.
149
+ * @param {!string} params.key - The key for the property delegate.<br>
150
+ * Needs to be unique with parent delegate.
151
+ // * @param {!type} params.type - The type of the property value.
152
+ * @param {?*} params.value - The initial value of the property.<br>
153
+ * Only used when the property delegate is created for the first time.
154
+ * Otherwise, the value is restored from persistent storage.
155
+ * @param {?boolean} params.logLevel - Level for homebridge log messages
156
+ * when property was set or has been changed.
157
+ * @param {?string} params.unit - The unit of the value of the property.
158
+ * @throws {TypeError} When a parameter has an invalid type.
159
+ * @throws {RangeError} When a parameter has an invalid value.
160
+ * @throws {SyntaxError} When a mandatory parameter is missing or an
161
+ * optional parameter is not applicable.
162
+ * @returns {PropertyDelegate}
163
+ * @throws {TypeError} When a parameter has an invalid type.
164
+ * @throws {RangeError} When a parameter has an invalid value.
165
+ * @throws {SyntaxError} When a mandatory parameter is missing or an
166
+ * optional parameter is not applicable.
167
+ */
168
+ addPropertyDelegate (params = {}) {
169
+ if (typeof params.key !== 'string') {
170
+ throw new TypeError(`params.key: ${params.key}: invalid key`)
171
+ }
172
+ if (params.key === '') {
173
+ throw new RangeError(`params.key: ${params.key}: invalid key`)
174
+ }
175
+ const key = params.key
176
+ if (this.values[key] !== undefined) {
177
+ throw new SyntaxError(`${key}: duplicate key`)
178
+ }
179
+
180
+ const delegate = new homebridgeLib.PropertyDelegate(this, params)
181
+ this._propertyDelegates[key] = delegate
182
+
183
+ // Create shortcut for characteristic value.
184
+ Object.defineProperty(this.values, key, {
185
+ configurable: true, // make sure we can delete it again
186
+ writeable: true,
187
+ get () { return delegate.value },
188
+ set (value) { delegate.value = value }
189
+ })
190
+
191
+ return delegate
192
+ }
193
+
194
+ removePropertyDelegate (key) {
195
+ if (this._accessoryInformationDelegate.values[key] != null) {
196
+ throw new RangeError('%s: invalid key')
197
+ }
198
+ delete this.values[key]
199
+ const delegate = this._propertyDelegates[key]
200
+ delegate._destroy()
201
+ delete this._propertyDelegates[key]
202
+ delete this._context[key]
203
+ }
204
+
205
+ /** Returns the property delegate correspondig to the property key.
206
+ * @param {!string} key - The key for the property.
207
+ * returns {PropertyDelegate}
208
+ */
209
+ propertyDelegate (key) {
210
+ return this._propertyDelegates[key]
211
+ }
212
+
141
213
  /** Values of the HomeKit characteristics for the `AccessoryInformation` service.
142
214
  *
143
- * Contains the key of each characteristic in
215
+ * Contains the key of each property and of each characteristic in
144
216
  * {@link ServiceDelegate.AccessoryInformation AccessoryInformation}.
145
217
  * When the value is written, the value of the corresponding HomeKit
146
218
  * characteristic is updated.
147
219
  * @type {object}
148
220
  */
149
221
  get values () {
150
- return this._accessoryInformationDelegate._values
222
+ return this._values
151
223
  }
152
224
 
153
225
  /** Enable `heartbeat` events for this accessory delegate.
@@ -192,16 +264,7 @@ class AccessoryDelegate extends homebridgeLib.Delegate {
192
264
  * @type {!integer}
193
265
  */
194
266
  get logLevel () {
195
- return this._context.logLevel
196
- }
197
-
198
- set logLevel (value) {
199
- const oldLogLevel = this._context.logLevel
200
- this._context.logLevel = Math.max(0, Math.min(value, maxLogLevel))
201
- this._platform._message(
202
- 'log', 2, this.name + ': ',
203
- 'set Log Level from %d to %d', oldLogLevel, this.logLevel
204
- )
267
+ return this.platform.logLevel
205
268
  }
206
269
 
207
270
  /** Inherit `logLevel` from another accessory delegate.
@@ -220,6 +283,19 @@ class AccessoryDelegate extends homebridgeLib.Delegate {
220
283
  })
221
284
  }
222
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
+
223
299
  // Called by homebridge when Identify is selected.
224
300
  _identify () {
225
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')