@benjaminmichoux/homebridge-leviton 2.2.0 → 2.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 +36 -29
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -9,6 +9,7 @@ class LevitonDecoraSmartPlatform {
|
|
|
9
9
|
this.config = config
|
|
10
10
|
this.api = api
|
|
11
11
|
this.accessories = []
|
|
12
|
+
this.token = null
|
|
12
13
|
|
|
13
14
|
const noop = function () {}
|
|
14
15
|
const logger = (level) => (msg) =>
|
|
@@ -37,6 +38,15 @@ class LevitonDecoraSmartPlatform {
|
|
|
37
38
|
const excludedModels = (config.excludedModels || []).map((name) => name.toUpperCase())
|
|
38
39
|
const excludedSerials = (config.excludedSerials || []).map((name) => name.toUpperCase())
|
|
39
40
|
if (Array.isArray(devices) && devices.length > 0) {
|
|
41
|
+
// Set up accessories restored from cache with the fresh token (their
|
|
42
|
+
// cached token has since expired). Refresh their device data too.
|
|
43
|
+
for (const accessory of this.accessories) {
|
|
44
|
+
const device = devices.find((d) => d.serial === accessory.context.device.serial)
|
|
45
|
+
if (device) accessory.context.device = device
|
|
46
|
+
accessory.context.token = token
|
|
47
|
+
await this.setupService(accessory)
|
|
48
|
+
}
|
|
49
|
+
// Add any newly discovered devices not already restored from cache.
|
|
40
50
|
devices.forEach((device) => {
|
|
41
51
|
if (!this.accessories.find((acc) => acc.context.device.serial === device.serial)) {
|
|
42
52
|
if (!excludedModels.includes(device.model) && !excludedSerials.includes(device.serial)) {
|
|
@@ -81,6 +91,7 @@ class LevitonDecoraSmartPlatform {
|
|
|
81
91
|
password: this.config['password'],
|
|
82
92
|
})
|
|
83
93
|
var { id: token, userId: personID } = login
|
|
94
|
+
this.token = token
|
|
84
95
|
this.log.debug(`personID: ${personID}, hasToken: ${!!token}`)
|
|
85
96
|
} catch (err) {
|
|
86
97
|
this.log.error(`Failed to login to leviton: ${err.message}`)
|
|
@@ -176,13 +187,13 @@ class LevitonDecoraSmartPlatform {
|
|
|
176
187
|
|
|
177
188
|
async configureAccessory(accessory) {
|
|
178
189
|
this.log.debug(`configureAccessory: ${accessory.displayName}`)
|
|
179
|
-
|
|
190
|
+
// Defer service setup until didFinishLaunching, once we have a fresh token.
|
|
180
191
|
this.accessories.push(accessory)
|
|
181
192
|
}
|
|
182
193
|
|
|
183
|
-
async getStatus(device
|
|
194
|
+
async getStatus(device) {
|
|
184
195
|
this.log.debug(`getStatus: ${device.name}`)
|
|
185
|
-
return Leviton.getIotSwitch({ switchID: device.id, token })
|
|
196
|
+
return Leviton.getIotSwitch({ switchID: device.id, token: this.token })
|
|
186
197
|
}
|
|
187
198
|
|
|
188
199
|
async setupService(accessory) {
|
|
@@ -218,21 +229,20 @@ class LevitonDecoraSmartPlatform {
|
|
|
218
229
|
this.log.debug(`Setting up device as Switch: ${accessory.displayName}`)
|
|
219
230
|
|
|
220
231
|
const device = accessory.context.device
|
|
221
|
-
const
|
|
222
|
-
const status = await this.getStatus(device, token)
|
|
232
|
+
const status = await this.getStatus(device)
|
|
223
233
|
|
|
224
234
|
const service = accessory.getService(Service.Switch) || accessory.addService(Service.Switch, device.name)
|
|
225
235
|
|
|
226
236
|
service
|
|
227
237
|
.getCharacteristic(Characteristic.On)
|
|
228
238
|
.onGet(async () => {
|
|
229
|
-
const res = await Leviton.getIotSwitch({ switchID: device.id, token })
|
|
239
|
+
const res = await Leviton.getIotSwitch({ switchID: device.id, token: this.token })
|
|
230
240
|
this.log.debug(`onGetPower: ${device.name} ${res.power}`)
|
|
231
241
|
return res.power === 'ON'
|
|
232
242
|
})
|
|
233
243
|
.onSet(async (value) => {
|
|
234
|
-
|
|
235
|
-
this.log.info(`onSetPower: ${device.name} ${
|
|
244
|
+
await Leviton.putIotSwitch({ switchID: device.id, power: value ? 'ON' : 'OFF', token: this.token })
|
|
245
|
+
this.log.info(`onSetPower: ${device.name} ${value ? 'ON' : 'OFF'}`)
|
|
236
246
|
})
|
|
237
247
|
.updateValue(status.power === 'ON')
|
|
238
248
|
}
|
|
@@ -241,21 +251,20 @@ class LevitonDecoraSmartPlatform {
|
|
|
241
251
|
this.log.debug(`Setting up device as Outlet: ${accessory.displayName}`)
|
|
242
252
|
|
|
243
253
|
const device = accessory.context.device
|
|
244
|
-
const
|
|
245
|
-
const status = await this.getStatus(device, token)
|
|
254
|
+
const status = await this.getStatus(device)
|
|
246
255
|
|
|
247
256
|
const service = accessory.getService(Service.Outlet) || accessory.addService(Service.Outlet, device.name)
|
|
248
257
|
|
|
249
258
|
service
|
|
250
259
|
.getCharacteristic(Characteristic.On)
|
|
251
260
|
.onGet(async () => {
|
|
252
|
-
const res = await Leviton.getIotSwitch({ switchID: device.id, token })
|
|
261
|
+
const res = await Leviton.getIotSwitch({ switchID: device.id, token: this.token })
|
|
253
262
|
this.log.debug(`onGetPower: ${device.name} ${res.power}`)
|
|
254
263
|
return res.power === 'ON'
|
|
255
264
|
})
|
|
256
265
|
.onSet(async (value) => {
|
|
257
|
-
|
|
258
|
-
this.log.info(`onSetPower: ${device.name} ${
|
|
266
|
+
await Leviton.putIotSwitch({ switchID: device.id, power: value ? 'ON' : 'OFF', token: this.token })
|
|
267
|
+
this.log.info(`onSetPower: ${device.name} ${value ? 'ON' : 'OFF'}`)
|
|
259
268
|
})
|
|
260
269
|
.updateValue(status.power === 'ON')
|
|
261
270
|
}
|
|
@@ -264,34 +273,33 @@ class LevitonDecoraSmartPlatform {
|
|
|
264
273
|
this.log.debug(`Setting up device as Lightbulb: ${accessory.displayName}`)
|
|
265
274
|
|
|
266
275
|
const device = accessory.context.device
|
|
267
|
-
const
|
|
268
|
-
const status = await this.getStatus(device, token)
|
|
276
|
+
const status = await this.getStatus(device)
|
|
269
277
|
|
|
270
278
|
const service = accessory.getService(Service.Lightbulb) || accessory.addService(Service.Lightbulb, device.name)
|
|
271
279
|
|
|
272
280
|
service
|
|
273
281
|
.getCharacteristic(Characteristic.On)
|
|
274
282
|
.onGet(async () => {
|
|
275
|
-
const res = await Leviton.getIotSwitch({ switchID: device.id, token })
|
|
283
|
+
const res = await Leviton.getIotSwitch({ switchID: device.id, token: this.token })
|
|
276
284
|
this.log.debug(`onGetPower: ${device.name} ${res.power}`)
|
|
277
285
|
return res.power === 'ON'
|
|
278
286
|
})
|
|
279
287
|
.onSet(async (value) => {
|
|
280
|
-
|
|
281
|
-
this.log.info(`onSetPower: ${device.name} ${
|
|
288
|
+
await Leviton.putIotSwitch({ switchID: device.id, power: value ? 'ON' : 'OFF', token: this.token })
|
|
289
|
+
this.log.info(`onSetPower: ${device.name} ${value ? 'ON' : 'OFF'}`)
|
|
282
290
|
})
|
|
283
291
|
.updateValue(status.power === 'ON')
|
|
284
292
|
|
|
285
293
|
service
|
|
286
294
|
.getCharacteristic(Characteristic.Brightness)
|
|
287
295
|
.onGet(async () => {
|
|
288
|
-
const res = await Leviton.getIotSwitch({ switchID: device.id, token })
|
|
296
|
+
const res = await Leviton.getIotSwitch({ switchID: device.id, token: this.token })
|
|
289
297
|
this.log.debug(`onGetBrightness: ${device.name} @ ${res.brightness}%`)
|
|
290
298
|
return res.brightness
|
|
291
299
|
})
|
|
292
300
|
.onSet(async (brightness) => {
|
|
293
|
-
|
|
294
|
-
this.log.info(`onSetBrightness: ${device.name} @ ${
|
|
301
|
+
await Leviton.putIotSwitch({ switchID: device.id, brightness, token: this.token })
|
|
302
|
+
this.log.info(`onSetBrightness: ${device.name} @ ${brightness}%`)
|
|
295
303
|
})
|
|
296
304
|
.setProps({ minValue: status.minLevel, maxValue: status.maxLevel, minStep: 1 })
|
|
297
305
|
.updateValue(status.brightness)
|
|
@@ -301,34 +309,33 @@ class LevitonDecoraSmartPlatform {
|
|
|
301
309
|
this.log.debug(`Setting up device as Fan: ${accessory.displayName}`)
|
|
302
310
|
|
|
303
311
|
const device = accessory.context.device
|
|
304
|
-
const
|
|
305
|
-
const status = await this.getStatus(device, token)
|
|
312
|
+
const status = await this.getStatus(device)
|
|
306
313
|
|
|
307
314
|
const service = accessory.getService(Service.Fan) || accessory.addService(Service.Fan, device.name)
|
|
308
315
|
|
|
309
316
|
service
|
|
310
317
|
.getCharacteristic(Characteristic.On)
|
|
311
318
|
.onGet(async () => {
|
|
312
|
-
const res = await Leviton.getIotSwitch({ switchID: device.id, token })
|
|
319
|
+
const res = await Leviton.getIotSwitch({ switchID: device.id, token: this.token })
|
|
313
320
|
this.log.debug(`onGetPower: ${device.name} ${res.power}`)
|
|
314
321
|
return res.power === 'ON'
|
|
315
322
|
})
|
|
316
323
|
.onSet(async (value) => {
|
|
317
|
-
|
|
318
|
-
this.log.info(`onSetPower: ${device.name} ${
|
|
324
|
+
await Leviton.putIotSwitch({ switchID: device.id, power: value ? 'ON' : 'OFF', token: this.token })
|
|
325
|
+
this.log.info(`onSetPower: ${device.name} ${value ? 'ON' : 'OFF'}`)
|
|
319
326
|
})
|
|
320
327
|
.updateValue(status.power === 'ON')
|
|
321
328
|
|
|
322
329
|
service
|
|
323
330
|
.getCharacteristic(Characteristic.RotationSpeed)
|
|
324
331
|
.onGet(async () => {
|
|
325
|
-
const res = await Leviton.getIotSwitch({ switchID: device.id, token })
|
|
332
|
+
const res = await Leviton.getIotSwitch({ switchID: device.id, token: this.token })
|
|
326
333
|
this.log.debug(`onGetRotationSpeed: ${device.name} @ ${res.brightness}%`)
|
|
327
334
|
return res.brightness
|
|
328
335
|
})
|
|
329
336
|
.onSet(async (brightness) => {
|
|
330
|
-
|
|
331
|
-
this.log.info(`onSetRotationSpeed: ${device.name} @ ${
|
|
337
|
+
await Leviton.putIotSwitch({ switchID: device.id, brightness, token: this.token })
|
|
338
|
+
this.log.info(`onSetRotationSpeed: ${device.name} @ ${brightness}%`)
|
|
332
339
|
})
|
|
333
340
|
.setProps({ minValue: 0, maxValue: status.maxLevel, minStep: status.minLevel })
|
|
334
341
|
.updateValue(status.brightness)
|