@homebridge-plugins/homebridge-ewelink 12.11.0 → 12.11.1-beta.0
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 +19 -0
- package/lib/connection/http.js +4 -4
- package/lib/connection/ws.js +3 -3
- package/lib/device/light-rgb-cct.js +3 -4
- package/lib/device/outlet-multi.js +1 -1
- package/lib/device/panel.js +1 -1
- package/lib/device/rf-bridge.js +5 -3
- package/lib/device/switch-man.js +1 -1
- package/lib/device/switch-mate.js +1 -1
- package/lib/device/zigbee/sensor-leak.js +1 -1
- package/lib/device/zigbee/sensor-motion.js +1 -1
- package/lib/device/zigbee/sensor-occupancy.js +1 -1
- package/lib/device/zigbee/switch-stateless.js +1 -1
- package/lib/fakegato/fakegato-history.js +5 -5
- package/lib/fakegato/fakegato-storage.js +1 -1
- package/lib/fakegato/fakegato-timer.js +6 -3
- package/lib/fakegato/uuid.js +5 -4
- package/lib/node-dns-sd/lib/dns-sd-parser.js +5 -3
- package/lib/node-dns-sd/lib/dns-sd.js +26 -13
- package/lib/platform.js +4 -4
- package/lib/utils/eve-chars.js +1 -1
- package/lib/utils/functions.js +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@homebridge-plugins/homebridge-ewelink` will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## v12.11.1 (Pending Release)
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- fix: wrong parseInt radix in channel name lookup
|
|
10
|
+
- fix: undefined variable in apiPort config check
|
|
11
|
+
- fix: copy-paste errors in RGB color comparison
|
|
12
|
+
- fix: color temp diff always zero in adaptive lighting
|
|
13
|
+
- fix: hue cache overwritten to zero on CT update
|
|
14
|
+
- fix: panel channel 2 returning channel 1 state
|
|
15
|
+
- fix: wrong characteristic in outlet-multi cleanup
|
|
16
|
+
- fix: incorrect bit shifts in DNS header parsing
|
|
17
|
+
- fix: missing await in group update request
|
|
18
|
+
- fix: fakegato unsubscribe removing wrong service
|
|
19
|
+
- fix: fakegato immediate callback missing averaging
|
|
20
|
+
- fix: string radix in fakegato toString call
|
|
21
|
+
- fix: incorrect unit casing in eve characteristic
|
|
22
|
+
- dependency updates + code lint fixes
|
|
23
|
+
|
|
5
24
|
## v12.11.0 (2026-02-28)
|
|
6
25
|
|
|
7
26
|
### Added
|
package/lib/connection/http.js
CHANGED
|
@@ -63,7 +63,7 @@ export default class {
|
|
|
63
63
|
'X-CK-Appid': this.appId,
|
|
64
64
|
'X-CK-Nonce': Math.random()
|
|
65
65
|
.toString(36)
|
|
66
|
-
.
|
|
66
|
+
.substring(2, 10),
|
|
67
67
|
},
|
|
68
68
|
})
|
|
69
69
|
|
|
@@ -156,7 +156,7 @@ export default class {
|
|
|
156
156
|
'X-CK-Appid': this.appId,
|
|
157
157
|
'X-CK-Nonce': Math.random()
|
|
158
158
|
.toString(36)
|
|
159
|
-
.
|
|
159
|
+
.substring(2, 10),
|
|
160
160
|
},
|
|
161
161
|
})
|
|
162
162
|
|
|
@@ -208,7 +208,7 @@ export default class {
|
|
|
208
208
|
'X-CK-Appid': this.appId,
|
|
209
209
|
'X-CK-Nonce': Math.random()
|
|
210
210
|
.toString(36)
|
|
211
|
-
.
|
|
211
|
+
.substring(2, 10),
|
|
212
212
|
},
|
|
213
213
|
params: {
|
|
214
214
|
num: 0,
|
|
@@ -292,7 +292,7 @@ export default class {
|
|
|
292
292
|
'X-CK-Appid': this.appId,
|
|
293
293
|
'X-CK-Nonce': Math.random()
|
|
294
294
|
.toString(36)
|
|
295
|
-
.
|
|
295
|
+
.substring(2, 10),
|
|
296
296
|
},
|
|
297
297
|
},
|
|
298
298
|
)
|
package/lib/connection/ws.js
CHANGED
|
@@ -42,8 +42,8 @@ export default class {
|
|
|
42
42
|
appid: this.appId,
|
|
43
43
|
nonce: Math.random()
|
|
44
44
|
.toString(36)
|
|
45
|
-
.
|
|
46
|
-
ts: Math.floor(
|
|
45
|
+
.substring(2, 10),
|
|
46
|
+
ts: Math.floor(Date.now() / 1000),
|
|
47
47
|
version: 8,
|
|
48
48
|
},
|
|
49
49
|
timeout: 6000,
|
|
@@ -121,7 +121,7 @@ export default class {
|
|
|
121
121
|
at: this.aToken,
|
|
122
122
|
nonce: Math.random()
|
|
123
123
|
.toString(36)
|
|
124
|
-
.
|
|
124
|
+
.substring(2, 10),
|
|
125
125
|
sequence,
|
|
126
126
|
ts: Math.floor(new Date() / 1000),
|
|
127
127
|
userAgent: 'app',
|
|
@@ -483,7 +483,6 @@ export default class {
|
|
|
483
483
|
this.cacheMired = value;
|
|
484
484
|
[this.cacheHue] = hs
|
|
485
485
|
this.cacheCT = scaledCT
|
|
486
|
-
this.cacheHue = 0
|
|
487
486
|
switch (this.accessory.context.eweUIID) {
|
|
488
487
|
case 33:
|
|
489
488
|
case 59:
|
|
@@ -589,12 +588,12 @@ export default class {
|
|
|
589
588
|
}
|
|
590
589
|
if (
|
|
591
590
|
params.colorR !== this.cacheR
|
|
592
|
-
|| params.colorG !== this.
|
|
591
|
+
|| params.colorG !== this.cacheG
|
|
593
592
|
|| params.colorB !== this.cacheB
|
|
594
593
|
) {
|
|
595
594
|
const rgbDiff = Math.abs(params.colorR - this.cacheR)
|
|
596
595
|
+ Math.abs(params.colorG - this.cacheG)
|
|
597
|
-
+ Math.abs(params.
|
|
596
|
+
+ Math.abs(params.colorB - this.cacheB)
|
|
598
597
|
this.cacheR = params.colorR
|
|
599
598
|
this.cacheG = params.colorG
|
|
600
599
|
this.cacheB = params.colorB
|
|
@@ -630,8 +629,8 @@ export default class {
|
|
|
630
629
|
this.service.updateCharacteristic(this.cusChar.FestiveScene, false)
|
|
631
630
|
}
|
|
632
631
|
if (params.colorTemp !== this.cacheCTRaw && params.mode === 2) {
|
|
633
|
-
this.cacheCTRaw = params.colorTemp
|
|
634
632
|
const ctDiff = Math.abs(params.colorTemp - this.cacheCTRaw)
|
|
633
|
+
this.cacheCTRaw = params.colorTemp
|
|
635
634
|
this.cacheCT = 100 - params.colorTemp
|
|
636
635
|
const ctToK = Math.round((this.cacheCT / 100) * 3800 + 2700)
|
|
637
636
|
this.cacheMired = Math.max(Math.min(Math.round(1000000 / ctToK), 500), 140)
|
|
@@ -85,7 +85,7 @@ export default class {
|
|
|
85
85
|
} else {
|
|
86
86
|
// Remove unused Eve characteristics
|
|
87
87
|
if (this.service.testCharacteristic(this.hapChar.OutletInUse)) {
|
|
88
|
-
this.service.removeCharacteristic(this.service.getCharacteristic(this.
|
|
88
|
+
this.service.removeCharacteristic(this.service.getCharacteristic(this.hapChar.OutletInUse))
|
|
89
89
|
}
|
|
90
90
|
if (this.service.testCharacteristic(this.eveChar.CurrentConsumption)) {
|
|
91
91
|
this.service.removeCharacteristic(
|
package/lib/device/panel.js
CHANGED
package/lib/device/rf-bridge.js
CHANGED
|
@@ -3,6 +3,8 @@ import axios from 'axios'
|
|
|
3
3
|
import platformConsts from '../utils/constants.js'
|
|
4
4
|
import { hasProperty, parseError, sleep } from '../utils/functions.js'
|
|
5
5
|
|
|
6
|
+
const rfTrigRegex = /rfTrig/
|
|
7
|
+
|
|
6
8
|
export default class {
|
|
7
9
|
constructor(platform, accessory, devicesInHB) {
|
|
8
10
|
// Set up variables from the platform
|
|
@@ -115,7 +117,7 @@ export default class {
|
|
|
115
117
|
) {
|
|
116
118
|
// RF Sensor
|
|
117
119
|
Object.keys(params)
|
|
118
|
-
.filter(name =>
|
|
120
|
+
.filter(name => rfTrigRegex.test(name))
|
|
119
121
|
.forEach(async (chan) => {
|
|
120
122
|
try {
|
|
121
123
|
this.devicesInHB.forEach((acc) => {
|
|
@@ -234,7 +236,7 @@ export default class {
|
|
|
234
236
|
}
|
|
235
237
|
}
|
|
236
238
|
|
|
237
|
-
// Call any webhook
|
|
239
|
+
// Call any webhook defined in the config
|
|
238
240
|
if (deviceConf.sensorWebHook) {
|
|
239
241
|
try {
|
|
240
242
|
await axios.get(deviceConf.sensorWebHook, {
|
|
@@ -286,7 +288,7 @@ export default class {
|
|
|
286
288
|
|
|
287
289
|
const updateKey = Math.random()
|
|
288
290
|
.toString(36)
|
|
289
|
-
.
|
|
291
|
+
.substring(2, 10)
|
|
290
292
|
subAccessory.context.updateKey = updateKey
|
|
291
293
|
await sleep(sensorTimeLength * 1000)
|
|
292
294
|
if (updateKey !== subAccessory.context.updateKey) {
|
package/lib/device/switch-man.js
CHANGED
|
@@ -80,7 +80,7 @@ export default class {
|
|
|
80
80
|
setTimeout(() => {
|
|
81
81
|
this.timeouts[label] = false
|
|
82
82
|
}, 1000)
|
|
83
|
-
const timeDiff = (
|
|
83
|
+
const timeDiff = (Date.now() - Date.parse(params.actionTime)) / 1000
|
|
84
84
|
if (timeDiff < 5) {
|
|
85
85
|
const service = this[`service${label}`]
|
|
86
86
|
service.updateCharacteristic(this.hapChar.ProgrammableSwitchEvent, params.key)
|
|
@@ -65,7 +65,7 @@ export default class {
|
|
|
65
65
|
setTimeout(() => {
|
|
66
66
|
this.timeouts[params.outlet] = false
|
|
67
67
|
}, 1000)
|
|
68
|
-
const timeDiff = (
|
|
68
|
+
const timeDiff = (Date.now() - Date.parse(params.actionTime)) / 1000
|
|
69
69
|
if (timeDiff < 5) {
|
|
70
70
|
this.service.updateCharacteristic(this.hapChar.ProgrammableSwitchEvent, params.outlet)
|
|
71
71
|
if (params.updateSource && this.enableLogging) {
|
|
@@ -88,7 +88,7 @@ export default class {
|
|
|
88
88
|
&& this.cacheState !== params.water
|
|
89
89
|
) {
|
|
90
90
|
this.cacheState = params.water
|
|
91
|
-
const timeDiff = (
|
|
91
|
+
const timeDiff = (Date.now() - params.trigTime) / 1000
|
|
92
92
|
const leakDetected = !!(
|
|
93
93
|
params.updateSource
|
|
94
94
|
&& params.water === 1
|
|
@@ -88,7 +88,7 @@ export default class {
|
|
|
88
88
|
&& params.motion !== this.cacheState
|
|
89
89
|
) {
|
|
90
90
|
this.cacheState = params.motion
|
|
91
|
-
const timeDiff = (
|
|
91
|
+
const timeDiff = (Date.now() - params.trigTime) / 1000
|
|
92
92
|
const motionDetected = !!(
|
|
93
93
|
params.updateSource
|
|
94
94
|
&& params.motion === 1
|
|
@@ -88,7 +88,7 @@ export default class {
|
|
|
88
88
|
&& params.occupancy !== this.cacheState
|
|
89
89
|
) {
|
|
90
90
|
this.cacheState = params.occupancy
|
|
91
|
-
const timeDiff = (
|
|
91
|
+
const timeDiff = (Date.now() - params.trigTime) / 1000
|
|
92
92
|
const occupancyDetected = !!(
|
|
93
93
|
params.updateSource
|
|
94
94
|
&& params.occupancy === 1
|
|
@@ -87,7 +87,7 @@ export default class {
|
|
|
87
87
|
&& [0, 1, 2].includes(params.key)
|
|
88
88
|
&& params.trigTime
|
|
89
89
|
) {
|
|
90
|
-
const timeDiff = (
|
|
90
|
+
const timeDiff = (Date.now() - params.trigTime) / 1000
|
|
91
91
|
if (timeDiff < this.sensorTimeDifference) {
|
|
92
92
|
this.service.updateCharacteristic(this.hapChar.ProgrammableSwitchEvent, params.key)
|
|
93
93
|
if (params.updateSource && this.enableLogging) {
|
|
@@ -39,7 +39,7 @@ export default function (homebridge) {
|
|
|
39
39
|
return s
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
const ucfirst = val => val.charAt(0).toUpperCase() + val.
|
|
42
|
+
const ucfirst = val => val.charAt(0).toUpperCase() + val.substring(1)
|
|
43
43
|
|
|
44
44
|
const precisionRound = (number, precision) => {
|
|
45
45
|
const factor = 10 ** precision
|
|
@@ -370,9 +370,9 @@ export default function (homebridge) {
|
|
|
370
370
|
avrg: {},
|
|
371
371
|
}
|
|
372
372
|
for (const h in backLog) {
|
|
373
|
-
if (Object.
|
|
373
|
+
if (Object.hasOwn(backLog, h)) {
|
|
374
374
|
for (const key in backLog[h]) {
|
|
375
|
-
if (Object.
|
|
375
|
+
if (Object.hasOwn(backLog[h], key) && key !== 'time') {
|
|
376
376
|
if (!calc.sum[key]) {
|
|
377
377
|
calc.sum[key] = 0
|
|
378
378
|
}
|
|
@@ -389,7 +389,7 @@ export default function (homebridge) {
|
|
|
389
389
|
calc.avrg.time = Math.round(new Date().valueOf() / 1000)
|
|
390
390
|
|
|
391
391
|
for (const key in previousAvrg) {
|
|
392
|
-
if (Object.
|
|
392
|
+
if (Object.hasOwn(previousAvrg, key) && key !== 'time') {
|
|
393
393
|
if (!backLog.length || calc.avrg[key] === undefined) {
|
|
394
394
|
calc.avrg[key] = previousAvrg[key]
|
|
395
395
|
}
|
|
@@ -798,7 +798,7 @@ export default function (homebridge) {
|
|
|
798
798
|
const substring = valHex.substring(4, 12)
|
|
799
799
|
const valInt = Number.parseInt(substring, 16)
|
|
800
800
|
const address = swap32(valInt)
|
|
801
|
-
const hexAddress = address.toString(
|
|
801
|
+
const hexAddress = address.toString(16)
|
|
802
802
|
this.log('[%s] FGH address req [%s].', this.accessoryName, hexAddress)
|
|
803
803
|
this.sendHistory(address)
|
|
804
804
|
}
|
|
@@ -71,7 +71,7 @@ export default class {
|
|
|
71
71
|
'[%s] FGS write file [%s] [%s].',
|
|
72
72
|
params.service.accessoryName,
|
|
73
73
|
fileLoc,
|
|
74
|
-
params.data.
|
|
74
|
+
params.data.substring(1, 81),
|
|
75
75
|
)
|
|
76
76
|
writer.storageHandler.writeFile(fileLoc, params.data, 'utf8', (...args) => {
|
|
77
77
|
this.writing = false
|
|
@@ -39,7 +39,9 @@ export default class {
|
|
|
39
39
|
|
|
40
40
|
unsubscribe(service) {
|
|
41
41
|
const index = this._getSubscriberIndex(service)
|
|
42
|
-
|
|
42
|
+
if (index !== -1) {
|
|
43
|
+
this.subscribedServices.splice(index, 1)
|
|
44
|
+
}
|
|
43
45
|
if (this.subscribedServices.length === 0 && this.running) {
|
|
44
46
|
this.stop()
|
|
45
47
|
}
|
|
@@ -65,7 +67,7 @@ export default class {
|
|
|
65
67
|
this.log('FGT executeCallbacks().')
|
|
66
68
|
if (this.subscribedServices.length !== 0) {
|
|
67
69
|
for (const s in this.subscribedServices) {
|
|
68
|
-
if (Object.
|
|
70
|
+
if (Object.hasOwn(this.subscribedServices, s)) {
|
|
69
71
|
const service = this.subscribedServices[s]
|
|
70
72
|
if (typeof service.callback === 'function') {
|
|
71
73
|
service.previousAvrg = service.callback({
|
|
@@ -83,8 +85,9 @@ export default class {
|
|
|
83
85
|
executeImmediateCallback(service) {
|
|
84
86
|
this.log('[%s] FGT executeImmediateCallback().', service.accessoryName)
|
|
85
87
|
if (typeof service.callback === 'function' && service.backLog.length) {
|
|
86
|
-
service.callback({
|
|
88
|
+
service.previousAvrg = service.callback({
|
|
87
89
|
backLog: service.backLog,
|
|
90
|
+
previousAvrg: service.previousAvrg,
|
|
88
91
|
timer: this,
|
|
89
92
|
immediate: true,
|
|
90
93
|
})
|
package/lib/fakegato/uuid.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
// https://github.com/homebridge/HAP-NodeJS/blob/master/src/lib/util/uuid.ts
|
|
2
2
|
|
|
3
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
|
|
4
|
+
const shortRegex = /^[0-9a-f]{1,8}$/i
|
|
5
|
+
|
|
3
6
|
function isValid(UUID) {
|
|
4
|
-
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
|
|
5
7
|
return uuidRegex.test(UUID)
|
|
6
8
|
}
|
|
7
9
|
|
|
8
10
|
function toLongFormUUID(uuid, base = '-0000-1000-8000-0026BB765291') {
|
|
9
|
-
const shortRegex = /^[0-9a-f]{1,8}$/i
|
|
10
11
|
if (isValid(uuid)) {
|
|
11
12
|
return uuid.toUpperCase()
|
|
12
13
|
}
|
|
@@ -16,12 +17,12 @@ function toLongFormUUID(uuid, base = '-0000-1000-8000-0026BB765291') {
|
|
|
16
17
|
if (!isValid(`00000000${base}`)) {
|
|
17
18
|
throw new TypeError('base was not a valid base UUID')
|
|
18
19
|
}
|
|
19
|
-
return ((`00000000${uuid}`).
|
|
20
|
+
return ((`00000000${uuid}`).slice(-8) + base).toUpperCase()
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
function toShortFormUUID(uuid, base = '-0000-1000-8000-0026BB765291') {
|
|
23
24
|
uuid = toLongFormUUID(uuid, base)
|
|
24
|
-
return uuid.
|
|
25
|
+
return uuid.substring(0, 8)
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
export { toLongFormUUID, toShortFormUUID }
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'
|
|
2
2
|
|
|
3
|
+
const kvPairRegex = /^([^=]+)=(.*)/
|
|
4
|
+
|
|
3
5
|
/* ------------------------------------------------------------------
|
|
4
6
|
* node-dns-sd - dns-sd-parser.js
|
|
5
7
|
*
|
|
@@ -53,8 +55,8 @@ DnsSdParser.prototype.parse = function (buf) {
|
|
|
53
55
|
rd: (buf.readUInt8(2) & 0b00000001),
|
|
54
56
|
ra: (buf.readUInt8(3) & 0b10000000) >> 7,
|
|
55
57
|
z: (buf.readUInt8(3) & 0b01000000) >> 6,
|
|
56
|
-
ad: (buf.readUInt8(3) & 0b00100000) >>
|
|
57
|
-
cd: (buf.readUInt8(3) & 0b00010000) >>
|
|
58
|
+
ad: (buf.readUInt8(3) & 0b00100000) >> 5,
|
|
59
|
+
cd: (buf.readUInt8(3) & 0b00010000) >> 4,
|
|
58
60
|
rc: (buf.readUInt8(3) & 0b00001111),
|
|
59
61
|
questions: buf.readUInt16BE(4),
|
|
60
62
|
answers: buf.readUInt16BE(6),
|
|
@@ -271,7 +273,7 @@ DnsSdParser.prototype._parseRdataTxt = function (buf, offset, len, buf_flag) {
|
|
|
271
273
|
i += 1
|
|
272
274
|
if (i + blen <= len) {
|
|
273
275
|
const pair = buf.slice(offset + i, offset + i + blen).toString('utf8')
|
|
274
|
-
const m = pair.match(
|
|
276
|
+
const m = pair.match(kvPairRegex)
|
|
275
277
|
if (m) {
|
|
276
278
|
labels[m[1]] = m[2]
|
|
277
279
|
if (buf_flag) {
|
|
@@ -12,6 +12,19 @@ import mOs from 'node:os'
|
|
|
12
12
|
import mDnsSdComposer from './dns-sd-composer.js'
|
|
13
13
|
import mDnsSdParser from './dns-sd-parser.js'
|
|
14
14
|
|
|
15
|
+
const appleTvRegex = /Apple TV/
|
|
16
|
+
const deviceInfoRegex = /_device-info/
|
|
17
|
+
const googlecastRegex = /_googlecast/
|
|
18
|
+
const philipsHueRegex = /Philips hue/
|
|
19
|
+
const canonRegex = /Canon/
|
|
20
|
+
const appleTvDashRegex = /Apple-TV/
|
|
21
|
+
const iPadRegex = /iPad/
|
|
22
|
+
const spaceRegex = / /
|
|
23
|
+
const leadingUnderscoreRegex = /^_/
|
|
24
|
+
const typeValidRegex = /^[a-z0-9]{1,10}$/i
|
|
25
|
+
const keyValidRegex = /^(?:address|fqdn)$/
|
|
26
|
+
const ipv4Regex = /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/
|
|
27
|
+
|
|
15
28
|
/* ------------------------------------------------------------------
|
|
16
29
|
* Constructor: DnsSd()
|
|
17
30
|
* ---------------------------------------------------------------- */
|
|
@@ -116,26 +129,26 @@ DnsSd.prototype._createDeviceObject = function (packet) {
|
|
|
116
129
|
const r = trecs.TXT[0]
|
|
117
130
|
const d = r.rdata || {}
|
|
118
131
|
const name = r.name || ''
|
|
119
|
-
if (
|
|
132
|
+
if (appleTvRegex.test(name)) {
|
|
120
133
|
o.modelName = 'Apple TV'
|
|
121
134
|
if (trecs.TXT) {
|
|
122
135
|
for (let i = 0; i < trecs.TXT.length; i += 1) {
|
|
123
136
|
const r = trecs.TXT[i]
|
|
124
|
-
if (
|
|
137
|
+
if (deviceInfoRegex.test(r.name) && r.rdata && r.rdata.model) {
|
|
125
138
|
o.modelName = `Apple TV ${r.rdata.model}`
|
|
126
139
|
break
|
|
127
140
|
}
|
|
128
141
|
}
|
|
129
142
|
}
|
|
130
|
-
} else if (
|
|
143
|
+
} else if (googlecastRegex.test(name)) {
|
|
131
144
|
o.modelName = d.md || null
|
|
132
145
|
o.familyName = d.fn || null
|
|
133
|
-
} else if (
|
|
146
|
+
} else if (philipsHueRegex.test(name)) {
|
|
134
147
|
o.modelName = 'Philips hue'
|
|
135
148
|
if (d.md) {
|
|
136
149
|
o.modelName += ` ${d.md}`
|
|
137
150
|
}
|
|
138
|
-
} else if (
|
|
151
|
+
} else if (canonRegex.test(name)) {
|
|
139
152
|
o.modelName = d.ty || null
|
|
140
153
|
}
|
|
141
154
|
}
|
|
@@ -143,9 +156,9 @@ DnsSd.prototype._createDeviceObject = function (packet) {
|
|
|
143
156
|
if (trecs.A && trecs.A[0]) {
|
|
144
157
|
const r = trecs.A[0]
|
|
145
158
|
const { name } = r
|
|
146
|
-
if (
|
|
159
|
+
if (appleTvDashRegex.test(name)) {
|
|
147
160
|
o.modelName = 'Apple TV'
|
|
148
|
-
} else if (
|
|
161
|
+
} else if (iPadRegex.test(name)) {
|
|
149
162
|
o.modelName = 'iPad'
|
|
150
163
|
}
|
|
151
164
|
}
|
|
@@ -154,7 +167,7 @@ DnsSd.prototype._createDeviceObject = function (packet) {
|
|
|
154
167
|
if (!o.modelName) {
|
|
155
168
|
if (o.fqdn) {
|
|
156
169
|
const hostname = (o.fqdn.split('.')).shift()
|
|
157
|
-
if (hostname &&
|
|
170
|
+
if (hostname && spaceRegex.test(hostname)) {
|
|
158
171
|
o.modelName = hostname
|
|
159
172
|
}
|
|
160
173
|
}
|
|
@@ -167,8 +180,8 @@ DnsSd.prototype._createDeviceObject = function (packet) {
|
|
|
167
180
|
name_parts.reverse()
|
|
168
181
|
o.service = {
|
|
169
182
|
port: rec.rdata.port,
|
|
170
|
-
protocol: name_parts[1].replace(
|
|
171
|
-
type: name_parts[2].replace(
|
|
183
|
+
protocol: name_parts[1].replace(leadingUnderscoreRegex, ''),
|
|
184
|
+
type: name_parts[2].replace(leadingUnderscoreRegex, ''),
|
|
172
185
|
}
|
|
173
186
|
}
|
|
174
187
|
|
|
@@ -223,7 +236,7 @@ DnsSd.prototype._checkDiscoveryParameters = function (params) {
|
|
|
223
236
|
|
|
224
237
|
if ('type' in params) {
|
|
225
238
|
const v = params.type
|
|
226
|
-
if (typeof (v) !== 'string' || !(
|
|
239
|
+
if (typeof (v) !== 'string' || !(typeValidRegex.test(v) || v === '*')) {
|
|
227
240
|
return { error: new Error('The `type` is invalid.') }
|
|
228
241
|
}
|
|
229
242
|
p.type = v.toUpperCase()
|
|
@@ -231,7 +244,7 @@ DnsSd.prototype._checkDiscoveryParameters = function (params) {
|
|
|
231
244
|
|
|
232
245
|
if ('key' in params) {
|
|
233
246
|
let v = params.key
|
|
234
|
-
if (typeof (v) !== 'string' ||
|
|
247
|
+
if (typeof (v) !== 'string' || !keyValidRegex.test(v)) {
|
|
235
248
|
return { error: new Error('The `key` is invalid.') }
|
|
236
249
|
}
|
|
237
250
|
if (!v) {
|
|
@@ -443,7 +456,7 @@ DnsSd.prototype._getSourceAddressList = function () {
|
|
|
443
456
|
for (const dev in netifs) {
|
|
444
457
|
netifs[dev].forEach((info) => {
|
|
445
458
|
if (info.family === 'IPv4' && info.internal === false) {
|
|
446
|
-
const m = info.address.match(
|
|
459
|
+
const m = info.address.match(ipv4Regex)
|
|
447
460
|
if (m) {
|
|
448
461
|
list.push(m[1])
|
|
449
462
|
}
|
package/lib/platform.js
CHANGED
|
@@ -126,7 +126,7 @@ export default class {
|
|
|
126
126
|
const [key, val] = entry
|
|
127
127
|
switch (key) {
|
|
128
128
|
case 'apiPort': {
|
|
129
|
-
if (typeof
|
|
129
|
+
if (typeof val === 'string') {
|
|
130
130
|
logQuotes(key)
|
|
131
131
|
}
|
|
132
132
|
const intVal = Number.parseInt(val, 10)
|
|
@@ -1845,7 +1845,7 @@ export default class {
|
|
|
1845
1845
|
// Try and obtain the eWeLink channel name
|
|
1846
1846
|
if (device?.tags?.ck_channel_name?.[Number.parseInt(switchNumber, 10) - 1]) {
|
|
1847
1847
|
// Found the eWeLink channel name
|
|
1848
|
-
newDeviceName = device.tags.ck_channel_name[Number.parseInt(switchNumber,
|
|
1848
|
+
newDeviceName = device.tags.ck_channel_name[Number.parseInt(switchNumber, 10) - 1]
|
|
1849
1849
|
} else {
|
|
1850
1850
|
// Didn't find the eWeLink channel name use generic SW channel
|
|
1851
1851
|
newDeviceName += ` SW${switchNumber}`
|
|
@@ -2046,7 +2046,7 @@ export default class {
|
|
|
2046
2046
|
accessory.logDebug(`${this.lang.updSend} ${JSON.stringify(params)}`)
|
|
2047
2047
|
|
|
2048
2048
|
// Send the request via HTTP
|
|
2049
|
-
this.httpClient.updateGroup(accessory.context.eweDeviceId, params)
|
|
2049
|
+
await this.httpClient.updateGroup(accessory.context.eweDeviceId, params)
|
|
2050
2050
|
})
|
|
2051
2051
|
}
|
|
2052
2052
|
|
|
@@ -2134,7 +2134,7 @@ export default class {
|
|
|
2134
2134
|
}
|
|
2135
2135
|
|
|
2136
2136
|
// Update this new online/offline status for all switches of multichannel devices
|
|
2137
|
-
if (reachableChange && accessory.context.hbDeviceId.
|
|
2137
|
+
if (reachableChange && accessory.context.hbDeviceId.slice(-1) !== 'X') {
|
|
2138
2138
|
// Loop through to see which channels are in HB
|
|
2139
2139
|
for (let i = 1; i <= accessory.context.channelCount; i += 1) {
|
|
2140
2140
|
const uuid = this.api.hap.uuid.generate(`${deviceId}SW${i}`)
|
package/lib/utils/eve-chars.js
CHANGED
|
@@ -79,7 +79,7 @@ export default class {
|
|
|
79
79
|
super('Reset Total', uuids.resetTotal)
|
|
80
80
|
this.setProps({
|
|
81
81
|
format: api.hap.Formats.UINT32,
|
|
82
|
-
unit: api.hap.Units.
|
|
82
|
+
unit: api.hap.Units.SECONDS,
|
|
83
83
|
perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY, api.hap.Perms.PAIRED_WRITE],
|
|
84
84
|
})
|
|
85
85
|
this.value = this.getDefaultValue()
|
package/lib/utils/functions.js
CHANGED
|
@@ -7,7 +7,7 @@ function generateRandomString(length) {
|
|
|
7
7
|
return nonce
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
const hasProperty = (obj, prop) => Object.
|
|
10
|
+
const hasProperty = (obj, prop) => Object.hasOwn(obj, prop)
|
|
11
11
|
|
|
12
12
|
function parseDeviceId(deviceId) {
|
|
13
13
|
return deviceId
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"displayName": "Homebridge eWeLink",
|
|
4
4
|
"alias": "eWeLink",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"version": "12.11.0",
|
|
6
|
+
"version": "12.11.1-beta.0",
|
|
7
7
|
"description": "Homebridge plugin to integrate eWeLink devices into HomeKit.",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "bwp91",
|
|
@@ -61,14 +61,14 @@
|
|
|
61
61
|
"lint:fix": "npm run lint -- --fix"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@homebridge/plugin-ui-utils": "^2.2.
|
|
65
|
-
"axios": "^1.
|
|
64
|
+
"@homebridge/plugin-ui-utils": "^2.2.3",
|
|
65
|
+
"axios": "^1.14.0",
|
|
66
66
|
"node-persist": "^4.0.4",
|
|
67
|
-
"p-queue": "^9.1.
|
|
67
|
+
"p-queue": "^9.1.1",
|
|
68
68
|
"websocket-as-promised": "^3.0.1",
|
|
69
|
-
"ws": "^8.
|
|
69
|
+
"ws": "^8.20.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@antfu/eslint-config": "^
|
|
72
|
+
"@antfu/eslint-config": "^8.0.0"
|
|
73
73
|
}
|
|
74
74
|
}
|