homebridge-nb 1.1.13 → 1.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.
package/cli/nb.js CHANGED
@@ -77,10 +77,12 @@ Parameters:
77
77
  Print debug messages for communication with Nuki bridge.
78
78
 
79
79
  ${b('-H')} ${u('hostname')}[${b(':')}${u('port')}], ${b('--host=')}${u('hostname')}[${b(':')}${u('port')}]
80
- Connect to ${u('hostname')}${b(':8080')} or ${u('hostname')}${b(':')}${u('port')}.
80
+ Connect to Nuki bridge at ${u('hostname')}${b(':8080')} or ${u('hostname')}${b(':')}${u('port')}.
81
+ You can also specify the hostname and port in the ${b('NB_HOST')} environment variable.
81
82
 
82
83
  ${b('-T')} ${u('token')}, ${b('--token=')}${u('token')}
83
- Use ${u('token')} instead of the token saved in ${b('~/.nb')}.
84
+ Use token ${u('token')} to connect to the Nuki bridge.
85
+ You can also specify the token in the ${b('NB_TOKEN')} environment variable.
84
86
 
85
87
  Commands:
86
88
  ${usage.discover}
@@ -188,8 +190,10 @@ Parameters:
188
190
 
189
191
  ${u('deviceType')}
190
192
  The type of the Nuki device (from ${b('nb list')}):
191
- 0: smartlock
192
- 2: opener`,
193
+ 0: Smart Lock 1.0 or 2.0
194
+ 2: Opener
195
+ 3: Smart Door
196
+ 4: Smart Lock 3.0`,
193
197
  lock: `${description.lock}
194
198
 
195
199
  Usage: ${usage.lock}
@@ -203,8 +207,10 @@ Parameters:
203
207
 
204
208
  ${u('deviceType')}
205
209
  The type of the Nuki device (from ${b('nb list')}):
206
- 0: smartlock
207
- 2: opener`,
210
+ 0: Smart Lock 1.0 or 2.0
211
+ 2: Opener
212
+ 3: Smart Door
213
+ 4: Smart Lock 3.0`,
208
214
  unlock: `${description.unlock}
209
215
 
210
216
  Usage: ${usage.unlock}
@@ -218,8 +224,10 @@ Parameters:
218
224
 
219
225
  ${u('deviceType')}
220
226
  The type of the Nuki device (from ${b('nb list')}):
221
- 0: smartlock
222
- 2: opener`,
227
+ 0: Smart Lock 1.0 or 2.0
228
+ 2: Opener
229
+ 3: Smart Door
230
+ 4: Smart Lock 3.0`,
223
231
  lockAction: `${description.lockAction}
224
232
 
225
233
  Usage: ${usage.lockAction}
@@ -233,12 +241,14 @@ Parameters:
233
241
 
234
242
  ${u('deviceType')}
235
243
  The type of the Nuki device (from ${b('nb list')}):
236
- 0: smartlock
237
- 2: opener
244
+ 0: Smart Lock 1.0 or 2.0
245
+ 2: Opener
246
+ 3: Smart Door
247
+ 4: Smart Lock 3.0
238
248
 
239
249
  ${u('action')}
240
250
  The action to send to the Nuki device:
241
- smartlock opener
251
+ Smart Lock, Smart Door Opener
242
252
  - ------------------------ -------------------------
243
253
  1 unlock activate rto
244
254
  2 lock deactivate rto
@@ -376,7 +386,7 @@ class Main extends homebridgeLib.CommandLineTool {
376
386
  args += ' -H ' + clargs.options.host
377
387
  }
378
388
  await this.fatal(
379
- `Missing token. Run ${b('nb' + args + ' auth')} and press bridge button.`
389
+ `Missing token. Set ${b('NB_TOKEN')} or specify ${b('-T')}. Run ${b('nb' + args + ' auth')} to obtain the token.`
380
390
  )
381
391
  }
382
392
  }
@@ -25,6 +25,7 @@ class NbAccessory extends homebridgeLib.AccessoryDelegate {
25
25
  this.client = this.bridge.client
26
26
  this.context.bridgeId = this.bridge.id
27
27
  this.context.firmware = params.firmware
28
+ this.context.deviceType = params.deviceType
28
29
  this.log('Nuki %s v%s %s', params.model, params.firmware, params.id)
29
30
  this.on('identify', this.identify)
30
31
  setImmediate(() => { this.emit('initialised') })
@@ -99,6 +100,8 @@ class Bridge extends homebridgeLib.AccessoryDelegate {
99
100
  const id = event.nukiId.toString(16).toUpperCase()
100
101
  switch (event.deviceType) {
101
102
  case NbClient.DeviceTypes.SMARTLOCK:
103
+ case NbClient.DeviceTypes.SMARTDOOR:
104
+ case NbClient.DeviceTypes.SMARTLOCK3:
102
105
  if (this.smartLocks[id] != null) {
103
106
  this.smartLocks[id].update(event)
104
107
  }
@@ -123,11 +126,16 @@ class Bridge extends homebridgeLib.AccessoryDelegate {
123
126
  this.debug('now at %s', value)
124
127
  this.client.host = value
125
128
  this.context.host = value
129
+ this.once('heartbeat', this.init)
126
130
  }
127
131
  }
128
132
 
129
133
  async init (beat) {
130
- await this.client.init()
134
+ try {
135
+ await this.client.init()
136
+ } catch (error) {
137
+ return
138
+ }
131
139
  if (this.context.callbackUrl) {
132
140
  this.warn('unclean shutdown - checking for stale subscriptions')
133
141
  try {
@@ -219,14 +227,18 @@ class Bridge extends homebridgeLib.AccessoryDelegate {
219
227
  const id = device.nukiId.toString(16).toUpperCase()
220
228
  switch (device.deviceType) {
221
229
  case NbClient.DeviceTypes.SMARTLOCK:
230
+ case NbClient.DeviceTypes.SMARTDOOR:
231
+ case NbClient.DeviceTypes.SMARTLOCK3:
222
232
  if (this.smartLocks[id] == null) {
223
233
  this.addSmartLock(id, {
224
234
  id: id,
225
235
  name: device.name,
226
- firmware: device.firmwareVersion
236
+ firmware: device.firmwareVersion,
237
+ deviceType: device.deviceType
227
238
  })
228
239
  }
229
240
  this.smartLocks[id].values.firmware = device.firmwareVersion
241
+ this.smartLocks[id].context.deviceType = device.deviceType
230
242
  this.smartLocks[id].update(device.lastKnownState)
231
243
  if (
232
244
  device.lastKnownState.doorsensorState != null &&
@@ -236,10 +248,12 @@ class Bridge extends homebridgeLib.AccessoryDelegate {
236
248
  this.addDoorSensor(id + '-S', {
237
249
  id: id + '-S',
238
250
  name: device.name + ' Sensor',
239
- firmware: device.firmwareVersion
251
+ firmware: device.firmwareVersion,
252
+ deviceType: device.deviceType
240
253
  })
241
254
  }
242
255
  this.doorSensors[id + '-S'].values.firmware = device.firmwareVersion
256
+ this.doorSensors[id + '-S'].context.deviceType = device.deviceType
243
257
  this.doorSensors[id + '-S'].update(device.lastKnownState)
244
258
  } else if (this.doorSensors[id + '-S'] != null) {
245
259
  this.doorSensors[id + '-S'].destroy()
@@ -251,10 +265,12 @@ class Bridge extends homebridgeLib.AccessoryDelegate {
251
265
  this.addOpener(id, {
252
266
  id: id,
253
267
  name: device.name,
254
- firmware: device.firmwareVersion
268
+ firmware: device.firmwareVersion,
269
+ deviceType: device.deviceType
255
270
  })
256
271
  }
257
272
  this.openers[id].values.firmware = device.firmwareVersion
273
+ this.openers[id].context.deviceType = device.deviceType
258
274
  this.openers[id].update(device.lastKnownState)
259
275
  break
260
276
  default:
@@ -271,8 +287,9 @@ class Bridge extends homebridgeLib.AccessoryDelegate {
271
287
  class SmartLock extends NbAccessory {
272
288
  constructor (bridge, params) {
273
289
  params.category = bridge.Accessory.Categories.DOOR_LOCK
274
- params.model = 'Smart Lock'
290
+ params.model = NbClient.modelName(params.deviceType, params.firmware)
275
291
  super(bridge, params)
292
+ this.context.deviceType = params.firmware
276
293
  this.batteryService = new homebridgeLib.ServiceDelegate.Battery(this)
277
294
  this.service = new NbService.SmartLock(this)
278
295
  if (this.platform.config.latch) {
@@ -296,10 +313,12 @@ class SmartLock extends NbAccessory {
296
313
  }
297
314
 
298
315
  async identify () {
299
- const response = await this.client.lockState(
300
- this.id, NbClient.DeviceTypes.SMARTLOCK
301
- )
302
- this.update(response.body)
316
+ try {
317
+ const response = await this.client.lockState(
318
+ this.id, this.context.deviceType
319
+ )
320
+ this.update(response.body)
321
+ } catch (error) { this.error(error) }
303
322
  }
304
323
  }
305
324
 
@@ -322,17 +341,19 @@ class DoorSensor extends NbAccessory {
322
341
  }
323
342
 
324
343
  async identify () {
325
- const response = await this.client.lockState(
326
- this.id, NbClient.DeviceTypes.SMARTLOCK
327
- )
328
- this.update(response.body)
344
+ try {
345
+ const response = await this.client.lockState(
346
+ this.id, this.context.deviceType
347
+ )
348
+ this.update(response.body)
349
+ } catch (error) { this.error(error) }
329
350
  }
330
351
  }
331
352
 
332
353
  class Opener extends NbAccessory {
333
354
  constructor (bridge, params) {
334
355
  params.category = bridge.Accessory.Categories.DOOR_LOCK
335
- params.model = 'Opener'
356
+ params.model = NbClient.modelName(params.deviceType, params.firmware)
336
357
  super(bridge, params)
337
358
  this.batteryService = new homebridgeLib.ServiceDelegate.Battery(this)
338
359
  this.doorBellService = new NbService.DoorBell(this)
@@ -356,10 +377,12 @@ class Opener extends NbAccessory {
356
377
  }
357
378
 
358
379
  async identify () {
359
- const response = await this.client.lockState(
360
- this.id, NbClient.DeviceTypes.OPENER
361
- )
362
- this.update(response.body)
380
+ try {
381
+ const response = await this.client.lockState(
382
+ this.id, NbClient.DeviceTypes.OPENER
383
+ )
384
+ this.update(response.body)
385
+ } catch (error) { this.error(error) }
363
386
  }
364
387
  }
365
388
 
package/lib/NbClient.js CHANGED
@@ -10,7 +10,12 @@ const homebridgeLib = require('homebridge-lib')
10
10
 
11
11
  class NbClient extends homebridgeLib.HttpClient {
12
12
  static get DeviceTypes () {
13
- return { SMARTLOCK: 0, OPENER: 2 }
13
+ return {
14
+ SMARTLOCK: 0,
15
+ OPENER: 2,
16
+ SMARTDOOR: 3,
17
+ SMARTLOCK3: 4
18
+ }
14
19
  }
15
20
 
16
21
  static get LockStates () {
@@ -77,6 +82,22 @@ class NbClient extends homebridgeLib.HttpClient {
77
82
  }
78
83
  }
79
84
 
85
+ static modelName (deviceType, firmware) {
86
+ switch (deviceType) {
87
+ case NbClient.DeviceTypes.SMARTLOCK:
88
+ if (firmware[0] === '1') {
89
+ return 'Smart Lock 1.0'
90
+ }
91
+ return 'Smart Lock 2.0'
92
+ case NbClient.DeviceTypes.OPENER:
93
+ return 'Opener'
94
+ case NbClient.DeviceTypes.SMARTDOOR:
95
+ return 'Smart Door'
96
+ case NbClient.DeviceTypes.SMARTLOCK3:
97
+ return 'Smart Lock 3.0'
98
+ }
99
+ }
100
+
80
101
  constructor (params = {}) {
81
102
  const _params = {
82
103
  hashedToken: true,
@@ -36,7 +36,7 @@ class NbDiscovery extends homebridgeLib.HttpClient {
36
36
  for (const bridge of response.body.bridges) {
37
37
  const client = new homebridgeLib.HttpClient({
38
38
  host: bridge.ip + ':' + bridge.port,
39
- path: '/',
39
+ path: '',
40
40
  timeout: this.config.timeout,
41
41
  validStatusCodes: [200, 401]
42
42
  })
@@ -45,7 +45,7 @@ class NbDiscovery extends homebridgeLib.HttpClient {
45
45
  .on('request', (request) => { this.emit('request', request) })
46
46
  .on('response', (response) => { this.emit('response', response) })
47
47
  try {
48
- await client.get('info')
48
+ await client.get('/info')
49
49
  bridges.push(bridge)
50
50
  } catch (error) {}
51
51
  }
package/lib/NbService.js CHANGED
@@ -107,7 +107,7 @@ class SmartLock extends homebridgeLib.ServiceDelegate {
107
107
  return
108
108
  }
109
109
  const response = await nbAccessory.client.lockAction(
110
- nbAccessory.id, NbClient.DeviceTypes.SMARTLOCK,
110
+ nbAccessory.id, nbAccessory.context.deviceType,
111
111
  value === this.Characteristics.hap.LockTargetState.UNSECURED
112
112
  ? NbClient.LockActions.UNLOCK
113
113
  : NbClient.LockActions.LOCK
@@ -124,7 +124,7 @@ class SmartLock extends homebridgeLib.ServiceDelegate {
124
124
  }
125
125
  if (value === this.Characteristics.hap.LockTargetState.UNSECURED) {
126
126
  await nbAccessory.client.lockAction(
127
- nbAccessory.id, NbClient.DeviceTypes.SMARTLOCK,
127
+ nbAccessory.id, nbAccessory.context.deviceType,
128
128
  NbClient.LockActions.UNLATCH
129
129
  )
130
130
  }
@@ -145,7 +145,7 @@ class SmartLock extends homebridgeLib.ServiceDelegate {
145
145
  nbAccessory.update({ state: NbClient.LockStates.UNLATCHED })
146
146
  }, 3000)
147
147
  const response = await nbAccessory.client.lockAction(
148
- nbAccessory.id, NbClient.DeviceTypes.SMARTLOCK,
148
+ nbAccessory.id, nbAccessory.context.deviceType,
149
149
  NbClient.LockActions.UNLATCH
150
150
  )
151
151
  if (response != null && response.body.success) {
@@ -235,7 +235,7 @@ class Latch extends homebridgeLib.ServiceDelegate {
235
235
  nbAccessory.update({ state: NbClient.LockStates.UNLATCHED })
236
236
  }, 3000)
237
237
  const response = await nbAccessory.client.lockAction(
238
- nbAccessory.id, NbClient.DeviceTypes.SMARTLOCK,
238
+ nbAccessory.id, nbAccessory.context.deviceType,
239
239
  NbClient.LockActions.UNLATCH
240
240
  )
241
241
  if (response != null && response.body.success) {
@@ -394,7 +394,7 @@ class Opener extends homebridgeLib.ServiceDelegate {
394
394
  }
395
395
  if (value === this.Characteristics.hap.LockTargetState.UNSECURED) {
396
396
  const response = await nbAccessory.client.lockAction(
397
- nbAccessory.id, NbClient.DeviceTypes.OPENER,
397
+ nbAccessory.id, nbAccessory.context.deviceType,
398
398
  NbClient.OpenerActions.OPEN
399
399
  )
400
400
  if (response != null && response.body.success) {
@@ -417,7 +417,7 @@ class Opener extends homebridgeLib.ServiceDelegate {
417
417
  return
418
418
  }
419
419
  await nbAccessory.client.lockAction(
420
- nbAccessory.id, NbClient.DeviceTypes.OPENER, value
420
+ nbAccessory.id, nbAccessory.context.deviceType, value
421
421
  ? NbClient.OpenerActions.ACTIVATE_RTO
422
422
  : NbClient.OpenerActions.DEACTIVATE_RTO
423
423
  )
@@ -432,7 +432,7 @@ class Opener extends homebridgeLib.ServiceDelegate {
432
432
  return
433
433
  }
434
434
  await nbAccessory.client.lockAction(
435
- nbAccessory.id, NbClient.DeviceTypes.OPENER, value
435
+ nbAccessory.id, nbAccessory.context.deviceType, value
436
436
  ? NbClient.OpenerActions.ACTIVATE_CM
437
437
  : NbClient.OpenerActions.DEACTIVATE_CM
438
438
  )
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "displayName": "Homebridge NB",
5
5
  "author": "Erik Baauw",
6
6
  "license": "Apache-2.0",
7
- "version": "1.1.13",
7
+ "version": "1.2.2",
8
8
  "keywords": [
9
9
  "homebridge-plugin",
10
10
  "homekit",
@@ -18,11 +18,11 @@
18
18
  "nb": "cli/nb.js"
19
19
  },
20
20
  "engines": {
21
- "homebridge": "^1.3.5",
22
- "node": "^16.13.0"
21
+ "homebridge": "^1.3.8",
22
+ "node": "^16.13.1"
23
23
  },
24
24
  "dependencies": {
25
- "homebridge-lib": "~5.1.16"
25
+ "homebridge-lib": "~5.1.20"
26
26
  },
27
27
  "scripts": {
28
28
  "prepare": "standard",