@homebridge-plugins/homebridge-wemo 7.7.3 → 7.7.4-beta.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/CHANGELOG.md +8 -0
- package/eslint.config.js +9 -2
- package/lib/connection/http.js +6 -2
- package/lib/device/crockpot.js +9 -3
- package/lib/device/dimmer.js +3 -1
- package/lib/device/heater.js +3 -1
- package/lib/device/humidifier.js +6 -2
- package/lib/device/insight.js +2 -2
- package/lib/device/lightswitch.js +6 -2
- package/lib/device/link-hub.js +3 -1
- package/lib/device/maker-garage.js +15 -5
- package/lib/device/maker-switch.js +3 -1
- package/lib/device/motion.js +3 -1
- package/lib/device/purifier.js +15 -5
- package/lib/device/simulation/purifier-insight.js +8 -4
- package/lib/device/simulation/purifier.js +12 -4
- package/lib/device/simulation/switch-insight.js +2 -2
- package/lib/device/simulation/switch.js +6 -2
- package/lib/fakegato/fakegato-history.js +9 -3
- package/lib/fakegato/fakegato-storage.js +6 -2
- package/lib/platform.js +90 -20
- package/lib/utils/colour.js +27 -8
- package/lib/utils/constants.js +18 -2
- package/lib/utils/eve-chars.js +8 -3
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@homebridge-plugins/homebridge-wemo` will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## v7.7.4 (Pending Release)
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- ci: update github actions to their latest versions (#288)
|
|
10
|
+
- fix: keep the decimals of a power reading, so 5.5w is no longer shown as 6w
|
|
11
|
+
- chore(deps): dependency updates
|
|
12
|
+
|
|
5
13
|
## v7.7.3 (2026-10-18)
|
|
6
14
|
|
|
7
15
|
### Changed
|
package/eslint.config.js
CHANGED
|
@@ -32,10 +32,17 @@ export default antfu(
|
|
|
32
32
|
'perfectionist/sort-named-imports': 'error',
|
|
33
33
|
'quotes': ['error', 'single'],
|
|
34
34
|
'sort-imports': 0,
|
|
35
|
-
'style/brace-style': [
|
|
35
|
+
'style/brace-style': [
|
|
36
|
+
'error',
|
|
37
|
+
'1tbs',
|
|
38
|
+
{ allowSingleLine: true },
|
|
39
|
+
],
|
|
36
40
|
'style/quote-props': ['error', 'consistent-as-needed'],
|
|
37
41
|
'test/no-only-tests': 'error',
|
|
38
|
-
'unused-imports/no-unused-vars': [
|
|
42
|
+
'unused-imports/no-unused-vars': [
|
|
43
|
+
'error',
|
|
44
|
+
{ caughtErrors: 'none' },
|
|
45
|
+
],
|
|
39
46
|
},
|
|
40
47
|
typescript: false,
|
|
41
48
|
},
|
package/lib/connection/http.js
CHANGED
|
@@ -52,7 +52,9 @@ export default class {
|
|
|
52
52
|
'SOAPACTION': `"${serviceType}#${action}"`,
|
|
53
53
|
'Content-Type': 'text/xml; charset="utf-8"',
|
|
54
54
|
},
|
|
55
|
-
data: (body
|
|
55
|
+
data: (body
|
|
56
|
+
? xml.ele(body)
|
|
57
|
+
: xml).end(),
|
|
56
58
|
timeout: 10000,
|
|
57
59
|
})
|
|
58
60
|
|
|
@@ -77,7 +79,9 @@ export default class {
|
|
|
77
79
|
this.platform.updateHTTPStatus(accessory, false)
|
|
78
80
|
}
|
|
79
81
|
throw new Error(
|
|
80
|
-
eText.includes('EHOSTUNREACH')
|
|
82
|
+
eText.includes('EHOSTUNREACH')
|
|
83
|
+
? platformLang.timeoutUnreach
|
|
84
|
+
: platformLang.timeout,
|
|
81
85
|
)
|
|
82
86
|
}
|
|
83
87
|
throw err
|
package/lib/device/crockpot.js
CHANGED
|
@@ -286,7 +286,9 @@ export default class {
|
|
|
286
286
|
|
|
287
287
|
// Log the change of cooking minutes if appropriate
|
|
288
288
|
const modMinutes = minutes % 60
|
|
289
|
-
this.accessory.log(`${platformLang.curTimer} [${Math.floor(value)}:${modMinutes >= 10
|
|
289
|
+
this.accessory.log(`${platformLang.curTimer} [${Math.floor(value)}:${modMinutes >= 10
|
|
290
|
+
? modMinutes
|
|
291
|
+
: `0${modMinutes}`}]`)
|
|
290
292
|
} catch (err) {
|
|
291
293
|
const eText = parseError(err, [platformLang.timeout, platformLang.timeoutUnreach])
|
|
292
294
|
this.accessory.logWarn(`${platformLang.cantCtl} ${eText}`)
|
|
@@ -327,7 +329,9 @@ export default class {
|
|
|
327
329
|
throw new Error(`Unknown value passed [${value} ${typeof value}]`)
|
|
328
330
|
}
|
|
329
331
|
// Update the HomeKit characteristics
|
|
330
|
-
this.service.updateCharacteristic(this.hapChar.Active, value !== 0
|
|
332
|
+
this.service.updateCharacteristic(this.hapChar.Active, value !== 0
|
|
333
|
+
? 1
|
|
334
|
+
: 0)
|
|
331
335
|
this.service.updateCharacteristic(this.hapChar.RotationSpeed, rotSpeed)
|
|
332
336
|
|
|
333
337
|
// Update the cache and log if appropriate
|
|
@@ -377,7 +381,9 @@ export default class {
|
|
|
377
381
|
// Update the cache and log if appropriate
|
|
378
382
|
this.accessory.context.cacheTime = value
|
|
379
383
|
const modMinutes = value % 60
|
|
380
|
-
this.accessory.log(`${platformLang.curTimer} [${Math.floor(value / 60)}:${modMinutes >= 10
|
|
384
|
+
this.accessory.log(`${platformLang.curTimer} [${Math.floor(value / 60)}:${modMinutes >= 10
|
|
385
|
+
? modMinutes
|
|
386
|
+
: `0${modMinutes}`}]`)
|
|
381
387
|
} catch (err) {
|
|
382
388
|
this.accessory.logWarn(`${platformLang.cantUpd} ${parseError(err)}`)
|
|
383
389
|
}
|
package/lib/device/dimmer.js
CHANGED
package/lib/device/heater.js
CHANGED
|
@@ -348,7 +348,9 @@ export default class {
|
|
|
348
348
|
}
|
|
349
349
|
|
|
350
350
|
// Update the HomeKit characteristics
|
|
351
|
-
this.service.updateCharacteristic(this.hapChar.Active, value !== 1
|
|
351
|
+
this.service.updateCharacteristic(this.hapChar.Active, value !== 1
|
|
352
|
+
? 1
|
|
353
|
+
: 0)
|
|
352
354
|
this.service.updateCharacteristic(this.hapChar.RotationSpeed, rotSpeed)
|
|
353
355
|
|
|
354
356
|
// Update the last used mode if the device is not off
|
package/lib/device/humidifier.js
CHANGED
|
@@ -197,7 +197,9 @@ export default class {
|
|
|
197
197
|
// Use the set handler to run the RotationSpeed set handler, to send updates to device
|
|
198
198
|
this.service.setCharacteristic(
|
|
199
199
|
this.hapChar.RotationSpeed,
|
|
200
|
-
value === 0
|
|
200
|
+
value === 0
|
|
201
|
+
? 0
|
|
202
|
+
: this.accessory.context.cacheLastOnMode * 20,
|
|
201
203
|
)
|
|
202
204
|
} catch (err) {
|
|
203
205
|
const eText = parseError(err, [platformLang.timeout, platformLang.timeoutUnreach])
|
|
@@ -323,7 +325,9 @@ export default class {
|
|
|
323
325
|
const rotSpeed = value * 20
|
|
324
326
|
|
|
325
327
|
// Update the HomeKit characteristics
|
|
326
|
-
this.service.updateCharacteristic(this.hapChar.Active, value !== 0
|
|
328
|
+
this.service.updateCharacteristic(this.hapChar.Active, value !== 0
|
|
329
|
+
? 1
|
|
330
|
+
: 0)
|
|
327
331
|
this.service.updateCharacteristic(this.hapChar.RotationSpeed, rotSpeed)
|
|
328
332
|
|
|
329
333
|
// Update the last used mode if not off
|
package/lib/device/insight.js
CHANGED
|
@@ -269,8 +269,8 @@ export default class {
|
|
|
269
269
|
|
|
270
270
|
externalConsumptionUpdate(power) {
|
|
271
271
|
try {
|
|
272
|
-
//
|
|
273
|
-
const powerInWatts = Math.round(power /
|
|
272
|
+
// The device reports milliwatts, so keep two decimal places of watts
|
|
273
|
+
const powerInWatts = Math.round(power / 10) / 100
|
|
274
274
|
|
|
275
275
|
// Check to see if the cache value is different
|
|
276
276
|
if (powerInWatts === this.cachePowerInWatts) {
|
|
@@ -113,7 +113,9 @@ export default class {
|
|
|
113
113
|
|
|
114
114
|
// Update the cache value
|
|
115
115
|
this.cacheState = value
|
|
116
|
-
this.accessory.historyService.addEntry({
|
|
116
|
+
this.accessory.historyService.addEntry({
|
|
117
|
+
status: value ? 1 : 0,
|
|
118
|
+
})
|
|
117
119
|
|
|
118
120
|
// Log the change if appropriate
|
|
119
121
|
this.accessory.log(`${platformLang.curState} [${value ? 'on' : 'off'}]`)
|
|
@@ -145,7 +147,9 @@ export default class {
|
|
|
145
147
|
|
|
146
148
|
// Log the change if appropriate
|
|
147
149
|
this.accessory.log(`${platformLang.curState} [${value ? 'on' : 'off'}]`)
|
|
148
|
-
this.accessory.historyService.addEntry({
|
|
150
|
+
this.accessory.historyService.addEntry({
|
|
151
|
+
status: value ? 1 : 0,
|
|
152
|
+
})
|
|
149
153
|
} catch (err) {
|
|
150
154
|
// Catch any errors
|
|
151
155
|
this.accessory.logWarn(`${platformLang.cantUpd} ${parseError(err)}`)
|
package/lib/device/link-hub.js
CHANGED
|
@@ -32,7 +32,9 @@ export default class {
|
|
|
32
32
|
encoding: 'utf-8',
|
|
33
33
|
})
|
|
34
34
|
.ele({
|
|
35
|
-
IsGroupAction: deviceId.length === 10
|
|
35
|
+
IsGroupAction: deviceId.length === 10
|
|
36
|
+
? 'YES'
|
|
37
|
+
: 'NO',
|
|
36
38
|
DeviceID: deviceId,
|
|
37
39
|
CapabilityID: capability,
|
|
38
40
|
CapabilityValue: value,
|
|
@@ -77,7 +77,9 @@ export default class {
|
|
|
77
77
|
log: () => {},
|
|
78
78
|
})
|
|
79
79
|
this.accessory.eveService.addEntry({
|
|
80
|
-
status: this.service.getCharacteristic(this.hapChar.CurrentDoorState).value === 0
|
|
80
|
+
status: this.service.getCharacteristic(this.hapChar.CurrentDoorState).value === 0
|
|
81
|
+
? 0
|
|
82
|
+
: 1,
|
|
81
83
|
})
|
|
82
84
|
|
|
83
85
|
// Output the customised options to the log
|
|
@@ -237,7 +239,9 @@ export default class {
|
|
|
237
239
|
const target = this.service.getCharacteristic(this.hapChar.TargetDoorState).value
|
|
238
240
|
const state = 1 - target
|
|
239
241
|
this.accessory.log(
|
|
240
|
-
`${platformLang.tarState} [${state === 1
|
|
242
|
+
`${platformLang.tarState} [${state === 1
|
|
243
|
+
? platformLang.labelClosed
|
|
244
|
+
: platformLang.labelOpen}] [${platformLang.makerTrigExt}]`,
|
|
241
245
|
)
|
|
242
246
|
|
|
243
247
|
// Update the new target state HomeKit characteristic
|
|
@@ -360,7 +364,9 @@ export default class {
|
|
|
360
364
|
|
|
361
365
|
// Toggle TargetDoorState after receiving a stop
|
|
362
366
|
await sleep(500)
|
|
363
|
-
const target = targetDoorState === this.gStates.Open
|
|
367
|
+
const target = targetDoorState === this.gStates.Open
|
|
368
|
+
? this.gStates.Closed
|
|
369
|
+
: this.gStates.Open
|
|
364
370
|
this.service.updateCharacteristic(this.hapChar.TargetDoorState, target)
|
|
365
371
|
this.accessory.context.cacheLastTargetState = target
|
|
366
372
|
return
|
|
@@ -408,11 +414,15 @@ export default class {
|
|
|
408
414
|
if (!this.sensorPresent) {
|
|
409
415
|
this.service.updateCharacteristic(
|
|
410
416
|
this.hapChar.CurrentDoorState,
|
|
411
|
-
target === 1
|
|
417
|
+
target === 1
|
|
418
|
+
? this.gStates.Closed
|
|
419
|
+
: this.gStates.Open,
|
|
412
420
|
)
|
|
413
421
|
|
|
414
422
|
// Log the change if appropriate
|
|
415
|
-
this.accessory.log(`${platformLang.curState} [${target === 1
|
|
423
|
+
this.accessory.log(`${platformLang.curState} [${target === 1
|
|
424
|
+
? platformLang.labelClosed
|
|
425
|
+
: platformLang.labelOpen}]`)
|
|
416
426
|
return
|
|
417
427
|
}
|
|
418
428
|
if (target === 1) {
|
|
@@ -194,7 +194,9 @@ export default class {
|
|
|
194
194
|
|
|
195
195
|
// Update the cache and log the change if appropriate
|
|
196
196
|
this.cacheContact = value
|
|
197
|
-
this.accessory.log(`${platformLang.curCont} [${value === 1
|
|
197
|
+
this.accessory.log(`${platformLang.curCont} [${value === 1
|
|
198
|
+
? platformLang.detectedNo
|
|
199
|
+
: platformLang.detectedYes}]`)
|
|
198
200
|
} catch (err) {
|
|
199
201
|
this.accessory.logWarn(`${platformLang.cantUpd} ${parseError(err)}`)
|
|
200
202
|
}
|
package/lib/device/motion.js
CHANGED
|
@@ -106,7 +106,9 @@ export default class {
|
|
|
106
106
|
this.service.updateCharacteristic(this.hapChar.MotionDetected, value)
|
|
107
107
|
|
|
108
108
|
// Add the entry to Eve
|
|
109
|
-
this.accessory.historyService.addEntry({
|
|
109
|
+
this.accessory.historyService.addEntry({
|
|
110
|
+
status: value ? 1 : 0,
|
|
111
|
+
})
|
|
110
112
|
|
|
111
113
|
// If motion detected then update the LastActivation Eve characteristic
|
|
112
114
|
if (value) {
|
package/lib/device/purifier.js
CHANGED
|
@@ -128,7 +128,9 @@ export default class {
|
|
|
128
128
|
this.externalAirQualityUpdate(attribute.value)
|
|
129
129
|
break
|
|
130
130
|
case 'ExpiredFilterTime':
|
|
131
|
-
this.externalFilterChangeUpdate(attribute.value !== 0
|
|
131
|
+
this.externalFilterChangeUpdate(attribute.value !== 0
|
|
132
|
+
? 1
|
|
133
|
+
: 0)
|
|
132
134
|
break
|
|
133
135
|
case 'FilterLife':
|
|
134
136
|
this.externalFilterLifeUpdate(Math.round((attribute.value / 60480) * 100))
|
|
@@ -243,7 +245,9 @@ export default class {
|
|
|
243
245
|
// Update the characteristic if we are now ON ie purifying air
|
|
244
246
|
this.service.updateCharacteristic(
|
|
245
247
|
this.hapChar.CurrentAirPurifierState,
|
|
246
|
-
newSpeed === 0
|
|
248
|
+
newSpeed === 0
|
|
249
|
+
? 0
|
|
250
|
+
: 2,
|
|
247
251
|
)
|
|
248
252
|
|
|
249
253
|
// Update the ionizer characteristic if the purifier is on and the ionizer was on before
|
|
@@ -373,7 +377,9 @@ export default class {
|
|
|
373
377
|
}
|
|
374
378
|
|
|
375
379
|
// Update the HomeKit characteristics
|
|
376
|
-
this.service.updateCharacteristic(this.hapChar.Active, value !== 0
|
|
380
|
+
this.service.updateCharacteristic(this.hapChar.Active, value !== 0
|
|
381
|
+
? 1
|
|
382
|
+
: 0)
|
|
377
383
|
this.service.updateCharacteristic(this.hapChar.RotationSpeed, rotSpeed)
|
|
378
384
|
|
|
379
385
|
// Turn the ionizer on or off based on whether the purifier is on or off
|
|
@@ -415,7 +421,9 @@ export default class {
|
|
|
415
421
|
externalIonizerUpdate(value) {
|
|
416
422
|
try {
|
|
417
423
|
// Don't continue if the value is the same as before
|
|
418
|
-
const state = this.ioService.getCharacteristic(this.hapChar.On).value
|
|
424
|
+
const state = this.ioService.getCharacteristic(this.hapChar.On).value
|
|
425
|
+
? 1
|
|
426
|
+
: 0
|
|
419
427
|
if (state === value) {
|
|
420
428
|
return
|
|
421
429
|
}
|
|
@@ -425,7 +433,9 @@ export default class {
|
|
|
425
433
|
|
|
426
434
|
// Update the cache value and log the change if appropriate
|
|
427
435
|
this.accessory.context.cacheIonizerOn = value
|
|
428
|
-
this.accessory.log(`${platformLang.curIon} [${value === 1
|
|
436
|
+
this.accessory.log(`${platformLang.curIon} [${value === 1
|
|
437
|
+
? 'on'
|
|
438
|
+
: 'off'}]`)
|
|
429
439
|
} catch (err) {
|
|
430
440
|
this.accessory.logWarn(`${platformLang.cantUpd} ${parseError(err)}`)
|
|
431
441
|
}
|
|
@@ -116,7 +116,9 @@ export default class {
|
|
|
116
116
|
case 'BinaryState': {
|
|
117
117
|
// BinaryState is reported as 0=off, 1=on, 8=standby
|
|
118
118
|
// Send a HomeKit needed 1/0 argument (0=0, 1,8=1)
|
|
119
|
-
this.externalStateUpdate(attribute.value === 0
|
|
119
|
+
this.externalStateUpdate(attribute.value === 0
|
|
120
|
+
? 0
|
|
121
|
+
: 1)
|
|
120
122
|
break
|
|
121
123
|
}
|
|
122
124
|
case 'InsightParams':
|
|
@@ -213,7 +215,9 @@ export default class {
|
|
|
213
215
|
|
|
214
216
|
externalInsightUpdate(value, power, todayWm, todayOnSeconds) {
|
|
215
217
|
// Update whether the switch is ON (value=1) or OFF (value=0)
|
|
216
|
-
this.externalStateUpdate(value === 0
|
|
218
|
+
this.externalStateUpdate(value === 0
|
|
219
|
+
? 0
|
|
220
|
+
: 1)
|
|
217
221
|
|
|
218
222
|
// Update whether the outlet-in-use is YES (value=1) or NO (value=0,8)
|
|
219
223
|
this.externalInUseUpdate(value === 1)
|
|
@@ -274,8 +278,8 @@ export default class {
|
|
|
274
278
|
|
|
275
279
|
externalConsumptionUpdate(power) {
|
|
276
280
|
try {
|
|
277
|
-
//
|
|
278
|
-
const powerInWatts = Math.round(power /
|
|
281
|
+
// The device reports milliwatts, so keep two decimal places of watts
|
|
282
|
+
const powerInWatts = Math.round(power / 10) / 100
|
|
279
283
|
|
|
280
284
|
// Check to see if the cache value is different
|
|
281
285
|
if (powerInWatts === this.cachePowerInWatts) {
|
|
@@ -115,13 +115,17 @@ export default class {
|
|
|
115
115
|
})
|
|
116
116
|
|
|
117
117
|
// Update the HomeKit characteristic
|
|
118
|
-
this.service.updateCharacteristic(this.hapChar.CurrentAirPurifierState, value === 1
|
|
118
|
+
this.service.updateCharacteristic(this.hapChar.CurrentAirPurifierState, value === 1
|
|
119
|
+
? 2
|
|
120
|
+
: 0)
|
|
119
121
|
|
|
120
122
|
// Update the cache value
|
|
121
123
|
this.cacheState = value
|
|
122
124
|
|
|
123
125
|
// Log the change if appropriate
|
|
124
|
-
this.accessory.log(`${platformLang.curState} [${value === 1
|
|
126
|
+
this.accessory.log(`${platformLang.curState} [${value === 1
|
|
127
|
+
? platformLang.purifyYes
|
|
128
|
+
: platformLang.purifyNo}]`)
|
|
125
129
|
} catch (err) {
|
|
126
130
|
// Catch any errors
|
|
127
131
|
const eText = parseError(err, [platformLang.timeout, platformLang.timeoutUnreach])
|
|
@@ -144,13 +148,17 @@ export default class {
|
|
|
144
148
|
|
|
145
149
|
// Update the HomeKit characteristic
|
|
146
150
|
this.service.updateCharacteristic(this.hapChar.Active, value)
|
|
147
|
-
this.service.updateCharacteristic(this.hapChar.CurrentAirPurifierState, value === 1
|
|
151
|
+
this.service.updateCharacteristic(this.hapChar.CurrentAirPurifierState, value === 1
|
|
152
|
+
? 2
|
|
153
|
+
: 0)
|
|
148
154
|
|
|
149
155
|
// Update the cache value
|
|
150
156
|
this.cacheState = value
|
|
151
157
|
|
|
152
158
|
// Log the change if appropriate
|
|
153
|
-
this.accessory.log(`${platformLang.curState} [${value === 1
|
|
159
|
+
this.accessory.log(`${platformLang.curState} [${value === 1
|
|
160
|
+
? platformLang.purifyYes
|
|
161
|
+
: platformLang.purifyNo}]`)
|
|
154
162
|
} catch (err) {
|
|
155
163
|
// Catch any errors
|
|
156
164
|
this.accessory.logWarn(`${platformLang.cantUpd} ${parseError(err)}`)
|
|
@@ -232,8 +232,8 @@ export default class {
|
|
|
232
232
|
|
|
233
233
|
externalConsumptionUpdate(power) {
|
|
234
234
|
try {
|
|
235
|
-
//
|
|
236
|
-
const powerInWatts = Math.round(power /
|
|
235
|
+
// The device reports milliwatts, so keep two decimal places of watts
|
|
236
|
+
const powerInWatts = Math.round(power / 10) / 100
|
|
237
237
|
|
|
238
238
|
// Check to see if the cache value is different
|
|
239
239
|
if (powerInWatts === this.cachePowerInWatts) {
|
|
@@ -113,7 +113,9 @@ export default class {
|
|
|
113
113
|
|
|
114
114
|
// Update the cache value
|
|
115
115
|
this.cacheState = value
|
|
116
|
-
this.accessory.historyService.addEntry({
|
|
116
|
+
this.accessory.historyService.addEntry({
|
|
117
|
+
status: value ? 1 : 0,
|
|
118
|
+
})
|
|
117
119
|
|
|
118
120
|
// Log the change if appropriate
|
|
119
121
|
this.accessory.log(`${platformLang.curState} [${value ? 'on' : 'off'}]`)
|
|
@@ -145,7 +147,9 @@ export default class {
|
|
|
145
147
|
|
|
146
148
|
// Log the change if appropriate
|
|
147
149
|
this.accessory.log(`${platformLang.curState} [${value ? 'on' : 'off'}]`)
|
|
148
|
-
this.accessory.historyService.addEntry({
|
|
150
|
+
this.accessory.historyService.addEntry({
|
|
151
|
+
status: value ? 1 : 0,
|
|
152
|
+
})
|
|
149
153
|
} catch (err) {
|
|
150
154
|
// Catch any errors
|
|
151
155
|
this.accessory.logWarn(`${platformLang.cantUpd} ${parseError(err)}`)
|
|
@@ -329,7 +329,9 @@ export default function (homebridge) {
|
|
|
329
329
|
this.signatures.length.toString()
|
|
330
330
|
} ${
|
|
331
331
|
this.signatures
|
|
332
|
-
.sort((a, b) => (a.signature > b.signature
|
|
332
|
+
.sort((a, b) => (a.signature > b.signature
|
|
333
|
+
? 1
|
|
334
|
+
: -1))
|
|
333
335
|
.map(a => a.signature)
|
|
334
336
|
.join(' ')
|
|
335
337
|
} `
|
|
@@ -584,7 +586,9 @@ export default function (homebridge) {
|
|
|
584
586
|
}
|
|
585
587
|
homebridge.globalFakeGatoStorage.write({
|
|
586
588
|
service: this,
|
|
587
|
-
data: typeof data === 'object'
|
|
589
|
+
data: typeof data === 'object'
|
|
590
|
+
? JSON.stringify(data)
|
|
591
|
+
: data,
|
|
588
592
|
})
|
|
589
593
|
} else {
|
|
590
594
|
setTimeout(() => this.save(), 100)
|
|
@@ -608,7 +612,9 @@ export default function (homebridge) {
|
|
|
608
612
|
|
|
609
613
|
try {
|
|
610
614
|
// this.log('[%s] read data [%s].', this.accessoryName, data)
|
|
611
|
-
const jsonFile = typeof data === 'object'
|
|
615
|
+
const jsonFile = typeof data === 'object'
|
|
616
|
+
? data
|
|
617
|
+
: JSON.parse(data)
|
|
612
618
|
this.firstEntry = jsonFile.firstEntry
|
|
613
619
|
this.lastEntry = jsonFile.lastEntry
|
|
614
620
|
this.usedMemory = jsonFile.usedMemory
|
|
@@ -20,7 +20,9 @@ const hostname = os.hostname().split('.')[0]
|
|
|
20
20
|
* backslash is an ordinary filename character on Linux, so replacing it there
|
|
21
21
|
* would rename the file of anyone already using one and lose their history.
|
|
22
22
|
*/
|
|
23
|
-
const PATH_SEPARATORS = process.platform === 'win32'
|
|
23
|
+
const PATH_SEPARATORS = process.platform === 'win32'
|
|
24
|
+
? /[\\/]/g
|
|
25
|
+
: /\//g
|
|
24
26
|
|
|
25
27
|
function toFileNamePart(name) {
|
|
26
28
|
return String(name ?? '').replace(PATH_SEPARATORS, '-')
|
|
@@ -51,7 +53,9 @@ export default class {
|
|
|
51
53
|
callback: params.callback,
|
|
52
54
|
fileName: `${hostname}_${toFileNamePart(service.accessoryName)}_persist.json`,
|
|
53
55
|
}
|
|
54
|
-
const onReady = typeof params.onReady === 'function'
|
|
56
|
+
const onReady = typeof params.onReady === 'function'
|
|
57
|
+
? params.onReady
|
|
58
|
+
: () => {}
|
|
55
59
|
newWriter.storageHandler = fs
|
|
56
60
|
newWriter.path = params.path || path.join(os.homedir(), '.homebridge')
|
|
57
61
|
this.writers.push(newWriter)
|
package/lib/platform.js
CHANGED
|
@@ -14,7 +14,7 @@ import upnpClient from './connection/upnp.js'
|
|
|
14
14
|
import deviceTypes from './device/index.js'
|
|
15
15
|
import eveService from './fakegato/fakegato-history.js'
|
|
16
16
|
import platformConsts from './utils/constants.js'
|
|
17
|
-
import eveChars from './utils/eve-chars.js'
|
|
17
|
+
import eveChars, { currentConsumptionUUID } from './utils/eve-chars.js'
|
|
18
18
|
import { parseError, parseSerialNumber, sameIpv4Subnet } from './utils/functions.js'
|
|
19
19
|
import platformLang from './utils/lang-en.js'
|
|
20
20
|
|
|
@@ -121,7 +121,9 @@ export default class {
|
|
|
121
121
|
if (typeof val === 'string') {
|
|
122
122
|
logQuotes(key)
|
|
123
123
|
}
|
|
124
|
-
this.config[key] = val === 'false'
|
|
124
|
+
this.config[key] = val === 'false'
|
|
125
|
+
? false
|
|
126
|
+
: !!val
|
|
125
127
|
break
|
|
126
128
|
case 'discoveryInterval':
|
|
127
129
|
case 'pollingInterval':
|
|
@@ -235,7 +237,9 @@ export default class {
|
|
|
235
237
|
if (typeof v === 'string') {
|
|
236
238
|
logQuotes(`${key}.${id}.${k}`)
|
|
237
239
|
}
|
|
238
|
-
this.deviceConf[id][k] = v === 'false'
|
|
240
|
+
this.deviceConf[id][k] = v === 'false'
|
|
241
|
+
? false
|
|
242
|
+
: !!v
|
|
239
243
|
break
|
|
240
244
|
case 'ignoreDevice':
|
|
241
245
|
if (typeof v === 'string') {
|
|
@@ -290,7 +294,9 @@ export default class {
|
|
|
290
294
|
if (typeof v2 === 'string') {
|
|
291
295
|
logQuotes(`${key}.${k1}.${k2}`)
|
|
292
296
|
}
|
|
293
|
-
this.config[key][k1][k2] = v2 === 'false'
|
|
297
|
+
this.config[key][k1][k2] = v2 === 'false'
|
|
298
|
+
? false
|
|
299
|
+
: !!v2
|
|
294
300
|
break
|
|
295
301
|
case 'interfaces':
|
|
296
302
|
if (typeof v2 !== 'string' || v2 === '') {
|
|
@@ -559,7 +565,9 @@ export default class {
|
|
|
559
565
|
async discoverDevices() {
|
|
560
566
|
// Increment the discovery run count
|
|
561
567
|
this.discoveryRun += 1
|
|
562
|
-
const accessoryArray = [
|
|
568
|
+
const accessoryArray = [
|
|
569
|
+
...devicesInHB.values(),
|
|
570
|
+
]
|
|
563
571
|
|
|
564
572
|
// Nothing to do if mode is semi or manual and no device is re/awaiting connection
|
|
565
573
|
if (
|
|
@@ -833,7 +841,9 @@ export default class {
|
|
|
833
841
|
const deviceConf = this.deviceConf[parseSerialNumber(device.serialNumber)] || {}
|
|
834
842
|
|
|
835
843
|
// Save context information for the plugin to use
|
|
836
|
-
const listenerType = deviceConf.listenerType === 'http'
|
|
844
|
+
const listenerType = deviceConf.listenerType === 'http'
|
|
845
|
+
? 'http'
|
|
846
|
+
: 'upnp'
|
|
837
847
|
const disableUPNP = this.config.disableUPNP ? 'http' : 'upnp'
|
|
838
848
|
const context = {
|
|
839
849
|
connection: deviceConf.listenerType ? listenerType : disableUPNP,
|
|
@@ -845,7 +855,9 @@ export default class {
|
|
|
845
855
|
hidden: false,
|
|
846
856
|
icon: device.iconList?.icon?.url || false,
|
|
847
857
|
ipAddress: device.host,
|
|
848
|
-
macAddress: device.macAddress
|
|
858
|
+
macAddress: device.macAddress
|
|
859
|
+
? device.macAddress.replace(/..\B/g, '$&:')
|
|
860
|
+
: false,
|
|
849
861
|
port: device.port,
|
|
850
862
|
serialNumber: device.serialNumber,
|
|
851
863
|
udn: device.UDN,
|
|
@@ -896,7 +908,11 @@ export default class {
|
|
|
896
908
|
// Set up the main 'hidden' accessory for the Link
|
|
897
909
|
accessory = this.addAccessory(device, true, true)
|
|
898
910
|
this.applyAccessoryLogging(accessory)
|
|
899
|
-
accessory.context = {
|
|
911
|
+
accessory.context = {
|
|
912
|
+
...accessory.context,
|
|
913
|
+
...context,
|
|
914
|
+
hidden: true,
|
|
915
|
+
}
|
|
900
916
|
if (Object.keys(context.serviceList).length > 0 && context.connection === 'upnp') {
|
|
901
917
|
accessory.client = new upnpClient(this, accessory)
|
|
902
918
|
}
|
|
@@ -992,7 +1008,11 @@ export default class {
|
|
|
992
1008
|
|
|
993
1009
|
// Get the cached accessory or add to Homebridge if it doesn't exist
|
|
994
1010
|
const subAcc = devicesInHB.get(uuidSub) || this.addAccessory(subdevice)
|
|
995
|
-
subAcc.context = {
|
|
1011
|
+
subAcc.context = {
|
|
1012
|
+
...subAcc.context,
|
|
1013
|
+
...context,
|
|
1014
|
+
...extraContext,
|
|
1015
|
+
}
|
|
996
1016
|
this.applyAccessoryLogging(subAcc)
|
|
997
1017
|
subAcc.control = new deviceTypes.deviceLinkBulb(this, accessory, subAcc)
|
|
998
1018
|
|
|
@@ -1040,7 +1060,10 @@ export default class {
|
|
|
1040
1060
|
*/
|
|
1041
1061
|
// Retrieve or add accessory, and add client and control properties
|
|
1042
1062
|
accessory = devicesInHB.get(uuid) || this.addAccessory(device, true)
|
|
1043
|
-
accessory.context = {
|
|
1063
|
+
accessory.context = {
|
|
1064
|
+
...accessory.context,
|
|
1065
|
+
...context,
|
|
1066
|
+
}
|
|
1044
1067
|
this.applyAccessoryLogging(accessory)
|
|
1045
1068
|
if (Object.keys(context.serviceList).length > 0 && context.connection === 'upnp') {
|
|
1046
1069
|
accessory.client = new upnpClient(this, accessory)
|
|
@@ -1067,7 +1090,10 @@ export default class {
|
|
|
1067
1090
|
**********
|
|
1068
1091
|
*/
|
|
1069
1092
|
accessory = devicesInHB.get(uuid) || this.addAccessory(device, true)
|
|
1070
|
-
accessory.context = {
|
|
1093
|
+
accessory.context = {
|
|
1094
|
+
...accessory.context,
|
|
1095
|
+
...context,
|
|
1096
|
+
}
|
|
1071
1097
|
this.applyAccessoryLogging(accessory)
|
|
1072
1098
|
if (Object.keys(context.serviceList).length > 0 && context.connection === 'upnp') {
|
|
1073
1099
|
accessory.client = new upnpClient(this, accessory)
|
|
@@ -1083,7 +1109,10 @@ export default class {
|
|
|
1083
1109
|
*****************
|
|
1084
1110
|
*/
|
|
1085
1111
|
accessory = devicesInHB.get(uuid) || this.addAccessory(device, true)
|
|
1086
|
-
accessory.context = {
|
|
1112
|
+
accessory.context = {
|
|
1113
|
+
...accessory.context,
|
|
1114
|
+
...context,
|
|
1115
|
+
}
|
|
1087
1116
|
this.applyAccessoryLogging(accessory)
|
|
1088
1117
|
if (Object.keys(context.serviceList).length > 0 && context.connection === 'upnp') {
|
|
1089
1118
|
accessory.client = new upnpClient(this, accessory)
|
|
@@ -1100,7 +1129,10 @@ export default class {
|
|
|
1100
1129
|
*/
|
|
1101
1130
|
// Retrieve or add accessory, and add client and control properties
|
|
1102
1131
|
accessory = devicesInHB.get(uuid) || this.addAccessory(device, true)
|
|
1103
|
-
accessory.context = {
|
|
1132
|
+
accessory.context = {
|
|
1133
|
+
...accessory.context,
|
|
1134
|
+
...context,
|
|
1135
|
+
}
|
|
1104
1136
|
this.applyAccessoryLogging(accessory)
|
|
1105
1137
|
if (Object.keys(context.serviceList).length > 0 && context.connection === 'upnp') {
|
|
1106
1138
|
accessory.client = new upnpClient(this, accessory)
|
|
@@ -1121,7 +1153,10 @@ export default class {
|
|
|
1121
1153
|
**********
|
|
1122
1154
|
*/
|
|
1123
1155
|
accessory = devicesInHB.get(uuid) || this.addAccessory(device, true)
|
|
1124
|
-
accessory.context = {
|
|
1156
|
+
accessory.context = {
|
|
1157
|
+
...accessory.context,
|
|
1158
|
+
...context,
|
|
1159
|
+
}
|
|
1125
1160
|
this.applyAccessoryLogging(accessory)
|
|
1126
1161
|
if (Object.keys(context.serviceList).length > 0 && context.connection === 'upnp') {
|
|
1127
1162
|
accessory.client = new upnpClient(this, accessory)
|
|
@@ -1139,7 +1174,10 @@ export default class {
|
|
|
1139
1174
|
*/
|
|
1140
1175
|
// Retrieve or add accessory, and add client and control properties
|
|
1141
1176
|
accessory = devicesInHB.get(uuid) || this.addAccessory(device, true)
|
|
1142
|
-
accessory.context = {
|
|
1177
|
+
accessory.context = {
|
|
1178
|
+
...accessory.context,
|
|
1179
|
+
...context,
|
|
1180
|
+
}
|
|
1143
1181
|
this.applyAccessoryLogging(accessory)
|
|
1144
1182
|
if (Object.keys(context.serviceList).length > 0 && context.connection === 'upnp') {
|
|
1145
1183
|
accessory.client = new upnpClient(this, accessory)
|
|
@@ -1168,7 +1206,10 @@ export default class {
|
|
|
1168
1206
|
**********
|
|
1169
1207
|
*/
|
|
1170
1208
|
accessory = devicesInHB.get(uuid) || this.addAccessory(device, true)
|
|
1171
|
-
accessory.context = {
|
|
1209
|
+
accessory.context = {
|
|
1210
|
+
...accessory.context,
|
|
1211
|
+
...context,
|
|
1212
|
+
}
|
|
1172
1213
|
this.applyAccessoryLogging(accessory)
|
|
1173
1214
|
if (Object.keys(context.serviceList).length > 0 && context.connection === 'upnp') {
|
|
1174
1215
|
accessory.client = new upnpClient(this, accessory)
|
|
@@ -1185,7 +1226,10 @@ export default class {
|
|
|
1185
1226
|
**************
|
|
1186
1227
|
*/
|
|
1187
1228
|
accessory = devicesInHB.get(uuid) || this.addAccessory(device, true)
|
|
1188
|
-
accessory.context = {
|
|
1229
|
+
accessory.context = {
|
|
1230
|
+
...accessory.context,
|
|
1231
|
+
...context,
|
|
1232
|
+
}
|
|
1189
1233
|
this.applyAccessoryLogging(accessory)
|
|
1190
1234
|
if (Object.keys(context.serviceList).length > 0 && context.connection === 'upnp') {
|
|
1191
1235
|
accessory.client = new upnpClient(this, accessory)
|
|
@@ -1204,7 +1248,10 @@ export default class {
|
|
|
1204
1248
|
device.friendlyName = deviceConf.label
|
|
1205
1249
|
}
|
|
1206
1250
|
accessory = devicesInHB.get(uuid) || this.addAccessory(device, true)
|
|
1207
|
-
accessory.context = {
|
|
1251
|
+
accessory.context = {
|
|
1252
|
+
...accessory.context,
|
|
1253
|
+
...context,
|
|
1254
|
+
}
|
|
1208
1255
|
this.applyAccessoryLogging(accessory)
|
|
1209
1256
|
if (Object.keys(context.serviceList).length > 0 && context.connection === 'upnp') {
|
|
1210
1257
|
accessory.client = new upnpClient(this, accessory)
|
|
@@ -1222,7 +1269,11 @@ export default class {
|
|
|
1222
1269
|
accessory = devicesInHB.get(uuid) || this.addAccessory(device, true)
|
|
1223
1270
|
|
|
1224
1271
|
// Wemo Crockpot does not support UPnP so override the connection to http
|
|
1225
|
-
accessory.context = {
|
|
1272
|
+
accessory.context = {
|
|
1273
|
+
...accessory.context,
|
|
1274
|
+
...context,
|
|
1275
|
+
connection: 'http',
|
|
1276
|
+
}
|
|
1226
1277
|
this.applyAccessoryLogging(accessory)
|
|
1227
1278
|
if (Object.keys(context.serviceList).length > 0 && context.connection === 'upnp') {
|
|
1228
1279
|
accessory.client = new upnpClient(this, accessory)
|
|
@@ -1238,7 +1289,10 @@ export default class {
|
|
|
1238
1289
|
****************
|
|
1239
1290
|
*/
|
|
1240
1291
|
accessory = devicesInHB.get(uuid) || this.addAccessory(device, true)
|
|
1241
|
-
accessory.context = {
|
|
1292
|
+
accessory.context = {
|
|
1293
|
+
...accessory.context,
|
|
1294
|
+
...context,
|
|
1295
|
+
}
|
|
1242
1296
|
this.applyAccessoryLogging(accessory)
|
|
1243
1297
|
if (Object.keys(context.serviceList).length > 0 && context.connection === 'upnp') {
|
|
1244
1298
|
accessory.client = new upnpClient(this, accessory)
|
|
@@ -1350,6 +1404,22 @@ export default class {
|
|
|
1350
1404
|
}
|
|
1351
1405
|
|
|
1352
1406
|
configureAccessory(accessory) {
|
|
1407
|
+
// A cached accessory comes back with the characteristic props it was saved
|
|
1408
|
+
// with, so a power reading made before it became decimal would stay whole
|
|
1409
|
+
// watts and keep rounding. Every restored accessory passes through here
|
|
1410
|
+
// before any device handler runs, so this one place covers all of them.
|
|
1411
|
+
// eveChar is not created until launch, hence the uuid on its own.
|
|
1412
|
+
if (this.api) {
|
|
1413
|
+
accessory.services.forEach((service) => {
|
|
1414
|
+
service.characteristics
|
|
1415
|
+
.filter(characteristic => characteristic.UUID === currentConsumptionUUID)
|
|
1416
|
+
.forEach(characteristic => characteristic.setProps({
|
|
1417
|
+
format: this.api.hap.Formats.FLOAT,
|
|
1418
|
+
minStep: 0.01,
|
|
1419
|
+
}))
|
|
1420
|
+
})
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1353
1423
|
// Add the configured accessory to our global map
|
|
1354
1424
|
devicesInHB.set(accessory.UUID, accessory)
|
|
1355
1425
|
}
|
package/lib/utils/colour.js
CHANGED
|
@@ -36,7 +36,11 @@ function hs2rgb(h, s) {
|
|
|
36
36
|
rgb[1] = 0
|
|
37
37
|
rgb[2] = 0
|
|
38
38
|
}
|
|
39
|
-
return [
|
|
39
|
+
return [
|
|
40
|
+
Math.round(rgb[0]),
|
|
41
|
+
Math.round(rgb[1]),
|
|
42
|
+
Math.round(rgb[2]),
|
|
43
|
+
]
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
function rgb2hs(r, g, b) {
|
|
@@ -71,16 +75,25 @@ function rgb2hs(r, g, b) {
|
|
|
71
75
|
if (h < 0) {
|
|
72
76
|
h += 360
|
|
73
77
|
}
|
|
74
|
-
return [
|
|
78
|
+
return [
|
|
79
|
+
Math.round(h),
|
|
80
|
+
Math.round(s),
|
|
81
|
+
]
|
|
75
82
|
}
|
|
76
83
|
|
|
77
84
|
function rgb2xy(r, g, b) {
|
|
78
85
|
const redC = r / 255
|
|
79
86
|
const greenC = g / 255
|
|
80
87
|
const blueC = b / 255
|
|
81
|
-
const redN = redC > 0.04045
|
|
82
|
-
|
|
83
|
-
|
|
88
|
+
const redN = redC > 0.04045
|
|
89
|
+
? ((redC + 0.055) / (1.0 + 0.055)) ** 2.4
|
|
90
|
+
: redC / 12.92
|
|
91
|
+
const greenN = greenC > 0.04045
|
|
92
|
+
? ((greenC + 0.055) / (1.0 + 0.055)) ** 2.4
|
|
93
|
+
: greenC / 12.92
|
|
94
|
+
const blueN = blueC > 0.04045
|
|
95
|
+
? ((blueC + 0.055) / (1.0 + 0.055)) ** 2.4
|
|
96
|
+
: blueC / 12.92
|
|
84
97
|
const X = redN * 0.664511 + greenN * 0.154324 + blueN * 0.162028
|
|
85
98
|
const Y = redN * 0.283881 + greenN * 0.668433 + blueN * 0.047685
|
|
86
99
|
const Z = redN * 0.000088 + greenN * 0.07231 + blueN * 0.986039
|
|
@@ -109,9 +122,15 @@ function xy2rgb(x, y) {
|
|
|
109
122
|
green /= blue
|
|
110
123
|
blue = 1.0
|
|
111
124
|
}
|
|
112
|
-
red = red <= 0.0031308
|
|
113
|
-
|
|
114
|
-
|
|
125
|
+
red = red <= 0.0031308
|
|
126
|
+
? 12.92 * red
|
|
127
|
+
: (1.0 + 0.055) * red ** (1.0 / 2.4) - 0.055
|
|
128
|
+
green = green <= 0.0031308
|
|
129
|
+
? 12.92 * green
|
|
130
|
+
: (1.0 + 0.055) * green ** (1.0 / 2.4) - 0.055
|
|
131
|
+
blue = blue <= 0.0031308
|
|
132
|
+
? 12.92 * blue
|
|
133
|
+
: (1.0 + 0.055) * blue ** (1.0 / 2.4) - 0.055
|
|
115
134
|
red = Math.abs(Math.round(red * 255))
|
|
116
135
|
green = Math.abs(Math.round(green * 255))
|
|
117
136
|
blue = Math.abs(Math.round(blue * 255))
|
package/lib/utils/constants.js
CHANGED
|
@@ -107,7 +107,13 @@ export default {
|
|
|
107
107
|
'manualIP',
|
|
108
108
|
'listenerType',
|
|
109
109
|
],
|
|
110
|
-
wemoLinks: [
|
|
110
|
+
wemoLinks: [
|
|
111
|
+
'label',
|
|
112
|
+
'serialNumber',
|
|
113
|
+
'ignoreDevice',
|
|
114
|
+
'manualIP',
|
|
115
|
+
'listenerType',
|
|
116
|
+
],
|
|
111
117
|
wemoMotions: [
|
|
112
118
|
'label',
|
|
113
119
|
'serialNumber',
|
|
@@ -134,7 +140,17 @@ export default {
|
|
|
134
140
|
showAs: ['default', 'switch', 'purifier'],
|
|
135
141
|
},
|
|
136
142
|
|
|
137
|
-
portsToScan: [
|
|
143
|
+
portsToScan: [
|
|
144
|
+
49153,
|
|
145
|
+
49152,
|
|
146
|
+
49154,
|
|
147
|
+
49155,
|
|
148
|
+
49151,
|
|
149
|
+
49156,
|
|
150
|
+
49157,
|
|
151
|
+
49158,
|
|
152
|
+
49159,
|
|
153
|
+
],
|
|
138
154
|
servicesToSubscribe: [
|
|
139
155
|
'urn:Belkin:service:basicevent:1',
|
|
140
156
|
'urn:Belkin:service:insight:1',
|
package/lib/utils/eve-chars.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
// Exported on its own because the platform needs it for cached accessories,
|
|
2
|
+
// which Homebridge restores before the characteristics below are created
|
|
3
|
+
export const currentConsumptionUUID = 'E863F10D-079E-48FF-8F27-9C2605A29F52'
|
|
4
|
+
|
|
1
5
|
export default class {
|
|
2
6
|
constructor(api) {
|
|
3
7
|
this.uuids = {
|
|
4
|
-
currentConsumption:
|
|
8
|
+
currentConsumption: currentConsumptionUUID,
|
|
5
9
|
totalConsumption: 'E863F10C-079E-48FF-8F27-9C2605A29F52',
|
|
6
10
|
voltage: 'E863F10A-079E-48FF-8F27-9C2605A29F52',
|
|
7
11
|
electricCurrent: 'E863F126-079E-48FF-8F27-9C2605A29F52',
|
|
@@ -17,12 +21,13 @@ export default class {
|
|
|
17
21
|
this.CurrentConsumption = class extends api.hap.Characteristic {
|
|
18
22
|
constructor() {
|
|
19
23
|
super('Current Consumption', uuids.currentConsumption)
|
|
24
|
+
// decimal, like Eve's own plugs: whole watts read 5.5W as 6W
|
|
20
25
|
this.setProps({
|
|
21
|
-
format: api.hap.Formats.
|
|
26
|
+
format: api.hap.Formats.FLOAT,
|
|
22
27
|
unit: 'W',
|
|
23
28
|
maxValue: 100000,
|
|
24
29
|
minValue: 0,
|
|
25
|
-
minStep:
|
|
30
|
+
minStep: 0.01,
|
|
26
31
|
perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY],
|
|
27
32
|
})
|
|
28
33
|
this.value = this.getDefaultValue()
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@homebridge-plugins/homebridge-wemo",
|
|
3
3
|
"alias": "Wemo",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "7.7.
|
|
5
|
+
"version": "7.7.4-beta.1",
|
|
6
6
|
"description": "Homebridge plugin to integrate Wemo devices into HomeKit.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "bwp91",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"xmlbuilder": "^15.1.1"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@antfu/eslint-config": "^
|
|
71
|
+
"@antfu/eslint-config": "^10.0.0",
|
|
72
72
|
"@vitest/coverage-v8": "^5.0.5",
|
|
73
73
|
"vitest": "^5.0.5"
|
|
74
74
|
}
|