@homebridge-plugins/homebridge-govee 11.3.0 → 11.3.2-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/config.schema.json +10 -1
- package/lib/device/fan-H7105.js +133 -159
- package/lib/platform.js +1 -0
- package/lib/utils/constants.js +1 -1
- package/lib/utils/eve-chars.js +56 -50
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to homebridge-govee will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## v11.4.0 (Unreleased)
|
|
6
|
+
|
|
7
|
+
- ⚠️ This update will remove and re-add any H7105 fan accessories in your Homebridge setup.
|
|
8
|
+
- It will replace the 0-100% rotation speed with a unitless rotation speed characteristic.
|
|
9
|
+
- The new rotation speed values (0-12) will better match the speeds from the Govee app.
|
|
10
|
+
|
|
11
|
+
### Notable Changes
|
|
12
|
+
|
|
13
|
+
- add option to hide fan light for H7105
|
|
14
|
+
- use unitless rotation speed for H7105
|
|
15
|
+
- fix updating swing mode for H7105 when externally controlled
|
|
16
|
+
- temporarily disable controlling swing mode for H7105
|
|
17
|
+
|
|
18
|
+
## v11.3.1 (2025-07-13)
|
|
19
|
+
|
|
20
|
+
### Notable Changes
|
|
21
|
+
|
|
22
|
+
- fix eve characteristics for hb 2
|
|
23
|
+
|
|
5
24
|
## v11.3.0 (2025-07-13)
|
|
6
25
|
|
|
7
26
|
### Notable Changes
|
package/config.schema.json
CHANGED
|
@@ -1153,6 +1153,14 @@
|
|
|
1153
1153
|
"condition": {
|
|
1154
1154
|
"functionBody": "return (model.fanDevices && model.fanDevices[arrayIndices] && model.fanDevices[arrayIndices].deviceId && model.fanDevices[arrayIndices].deviceId.length === 23);"
|
|
1155
1155
|
}
|
|
1156
|
+
},
|
|
1157
|
+
"hideLight": {
|
|
1158
|
+
"type": "boolean",
|
|
1159
|
+
"title": "Hide Light",
|
|
1160
|
+
"description": "Enable this to not expose the light service in Homebridge/Homekit if your fan has one.",
|
|
1161
|
+
"condition": {
|
|
1162
|
+
"functionBody": "return (model.fanDevices && model.fanDevices[arrayIndices] && model.fanDevices[arrayIndices].deviceId && model.fanDevices[arrayIndices].deviceId.length === 23 && !model.fanDevices[arrayIndices].ignoreDevice);"
|
|
1163
|
+
}
|
|
1156
1164
|
}
|
|
1157
1165
|
}
|
|
1158
1166
|
}
|
|
@@ -1604,7 +1612,8 @@
|
|
|
1604
1612
|
"items": [
|
|
1605
1613
|
"fanDevices[].label",
|
|
1606
1614
|
"fanDevices[].deviceId",
|
|
1607
|
-
"fanDevices[].ignoreDevice"
|
|
1615
|
+
"fanDevices[].ignoreDevice",
|
|
1616
|
+
"fanDevices[].hideLight"
|
|
1608
1617
|
]
|
|
1609
1618
|
}
|
|
1610
1619
|
]
|
package/lib/device/fan-H7105.js
CHANGED
|
@@ -22,20 +22,24 @@ export default class {
|
|
|
22
22
|
// Set up variables from the accessory
|
|
23
23
|
this.accessory = accessory
|
|
24
24
|
|
|
25
|
+
// Set up custom variables for this device type
|
|
26
|
+
const deviceConf = platform.deviceConf[accessory.context.gvDeviceId]
|
|
27
|
+
this.hideLight = deviceConf && deviceConf.hideLight
|
|
28
|
+
|
|
25
29
|
// Codes etc
|
|
26
30
|
this.speedCodes = {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
1: 'MwUBAQAAAAAAAAAAAAAAAAAAADY=',
|
|
32
|
+
2: 'MwUBAgAAAAAAAAAAAAAAAAAAADU=',
|
|
33
|
+
3: 'MwUBAwAAAAAAAAAAAAAAAAAAADQ=',
|
|
34
|
+
4: 'MwUBBAAAAAAAAAAAAAAAAAAAADM=',
|
|
35
|
+
5: 'MwUBBQAAAAAAAAAAAAAAAAAAADI=',
|
|
36
|
+
6: 'MwUBBgAAAAAAAAAAAAAAAAAAADE=',
|
|
37
|
+
7: 'MwUBBwAAAAAAAAAAAAAAAAAAADA=',
|
|
38
|
+
8: 'MwUBCAAAAAAAAAAAAAAAAAAAAD8=',
|
|
39
|
+
9: 'MwUBCQAAAAAAAAAAAAAAAAAAAD4=',
|
|
40
|
+
10: 'MwUBCgAAAAAAAAAAAAAAAAAAAD0=',
|
|
41
|
+
11: 'MwUBCwAAAAAAAAAAAAAAAAAAADw=',
|
|
42
|
+
12: 'MwUBDAAAAAAAAAAAAAAAAAAAADs=',
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
// Remove any old original Fan services
|
|
@@ -43,12 +47,17 @@ export default class {
|
|
|
43
47
|
this.accessory.removeService(this.accessory.getService(this.hapServ.Fan))
|
|
44
48
|
}
|
|
45
49
|
|
|
50
|
+
// Migrate old %-rotation speed to unitless
|
|
51
|
+
const existingService = this.accessory.getService(this.hapServ.Fanv2)
|
|
52
|
+
if (existingService) {
|
|
53
|
+
if (existingService.getCharacteristic(this.hapChar.RotationSpeed).props.unit === 'percentage') {
|
|
54
|
+
this.accessory.removeService(existingService)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
46
58
|
// Add the fan service for the fan if it doesn't already exist
|
|
47
59
|
this.service = this.accessory.getService(this.hapServ.Fanv2) || this.accessory.addService(this.hapServ.Fanv2)
|
|
48
60
|
|
|
49
|
-
// Add the night light service if it doesn't already exist
|
|
50
|
-
this.lightService = this.accessory.getService(this.hapServ.Lightbulb) || this.accessory.addService(this.hapServ.Lightbulb)
|
|
51
|
-
|
|
52
61
|
// Add the set handler to the fan on/off characteristic
|
|
53
62
|
this.service
|
|
54
63
|
.getCharacteristic(this.hapChar.Active)
|
|
@@ -59,43 +68,56 @@ export default class {
|
|
|
59
68
|
this.service
|
|
60
69
|
.getCharacteristic(this.hapChar.RotationSpeed)
|
|
61
70
|
.setProps({
|
|
62
|
-
|
|
71
|
+
maxValue: 12,
|
|
72
|
+
minStep: 1,
|
|
63
73
|
minValue: 0,
|
|
64
|
-
|
|
74
|
+
unit: 'unitless', // This is actually from HAP for Bluetooth LE Specification, but fits
|
|
65
75
|
})
|
|
66
76
|
.onSet(async value => this.internalSpeedUpdate(value))
|
|
67
77
|
this.cacheSpeed = this.service.getCharacteristic(this.hapChar.RotationSpeed).value
|
|
68
|
-
this.cacheMode = this.cacheSpeed >= 91 ? 'auto' : 'manual'
|
|
69
78
|
|
|
70
79
|
// Add the set handler to the fan swing mode
|
|
71
80
|
this.service
|
|
72
81
|
.getCharacteristic(this.hapChar.SwingMode)
|
|
73
82
|
.onSet(async value => this.internalSwingUpdate(value))
|
|
74
83
|
this.cacheSwing = this.service.getCharacteristic(this.hapChar.SwingMode).value === 1 ? 'on' : 'off'
|
|
84
|
+
this.cacheSwingCode = ''
|
|
75
85
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
86
|
+
if (this.hideLight) {
|
|
87
|
+
if (this.accessory.getService(this.hapServ.Lightbulb)) {
|
|
88
|
+
// Remove the light service if it exists
|
|
89
|
+
this.accessory.removeService(this.accessory.getService(this.hapServ.Lightbulb))
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
// Add the night light service if it doesn't already exist
|
|
93
|
+
this.lightService = this.accessory.getService(this.hapServ.Lightbulb) || this.accessory.addService(this.hapServ.Lightbulb)
|
|
81
94
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
.onSet(async (value) => {
|
|
86
|
-
await this.internalBrightnessUpdate(value)
|
|
95
|
+
// Add the set handler to the lightbulb on/off characteristic
|
|
96
|
+
this.lightService.getCharacteristic(this.hapChar.On).onSet(async (value) => {
|
|
97
|
+
await this.internalLightStateUpdate(value)
|
|
87
98
|
})
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
this.cacheLightState = this.lightService.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
|
|
100
|
+
|
|
101
|
+
// Add the set handler to the lightbulb brightness characteristic
|
|
102
|
+
this.lightService
|
|
103
|
+
.getCharacteristic(this.hapChar.Brightness)
|
|
104
|
+
.onSet(async (value) => {
|
|
105
|
+
await this.internalBrightnessUpdate(value)
|
|
106
|
+
})
|
|
107
|
+
this.cacheBright = this.lightService.getCharacteristic(this.hapChar.Brightness).value
|
|
108
|
+
|
|
109
|
+
// Add the set handler to the lightbulb hue characteristic
|
|
110
|
+
this.lightService.getCharacteristic(this.hapChar.Hue).onSet(async (value) => {
|
|
111
|
+
await this.internalColourUpdate(value)
|
|
112
|
+
})
|
|
113
|
+
this.cacheHue = this.lightService.getCharacteristic(this.hapChar.Hue).value
|
|
114
|
+
this.cacheSat = this.lightService.getCharacteristic(this.hapChar.Saturation).value
|
|
115
|
+
}
|
|
96
116
|
|
|
97
117
|
// Output the customised options to the log
|
|
98
|
-
const opts = JSON.stringify({
|
|
118
|
+
const opts = JSON.stringify({
|
|
119
|
+
hideLight: this.hideLight,
|
|
120
|
+
})
|
|
99
121
|
platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
|
|
100
122
|
}
|
|
101
123
|
|
|
@@ -133,74 +155,20 @@ export default class {
|
|
|
133
155
|
|
|
134
156
|
async internalSpeedUpdate(value) {
|
|
135
157
|
try {
|
|
136
|
-
if (value < 3) {
|
|
137
|
-
return
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
let newValue
|
|
141
|
-
if (value < 10) {
|
|
142
|
-
newValue = 7
|
|
143
|
-
} else if (value < 17) {
|
|
144
|
-
newValue = 14
|
|
145
|
-
} else if (value < 24) {
|
|
146
|
-
newValue = 21
|
|
147
|
-
} else if (value < 31) {
|
|
148
|
-
newValue = 28
|
|
149
|
-
} else if (value < 38) {
|
|
150
|
-
newValue = 35
|
|
151
|
-
} else if (value < 45) {
|
|
152
|
-
newValue = 42
|
|
153
|
-
} else if (value < 52) {
|
|
154
|
-
newValue = 49
|
|
155
|
-
} else if (value < 59) {
|
|
156
|
-
newValue = 56
|
|
157
|
-
} else if (value < 66) {
|
|
158
|
-
newValue = 63
|
|
159
|
-
} else if (value < 73) {
|
|
160
|
-
newValue = 70
|
|
161
|
-
} else if (value < 80) {
|
|
162
|
-
newValue = 77
|
|
163
|
-
} else if (value < 87) {
|
|
164
|
-
newValue = 84
|
|
165
|
-
} else {
|
|
166
|
-
newValue = 91
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
let newMode = value === 91 ? 'auto' : 'manual'
|
|
170
|
-
|
|
171
158
|
// Don't continue if the new value is the same as before
|
|
172
|
-
if (this.cacheSpeed ===
|
|
159
|
+
if (this.cacheSpeed === value || value === 0) {
|
|
173
160
|
return
|
|
174
161
|
}
|
|
175
162
|
|
|
176
|
-
// Don't continue if trying to access auto mode but there is no sensor attached
|
|
177
|
-
let codeToSend
|
|
178
|
-
if (newMode === 'auto') {
|
|
179
|
-
if (!this.accessory.context.sensorAttached || !this.cacheAutoCode) {
|
|
180
|
-
this.accessory.logWarn('auto mode not supported without a linked sensor')
|
|
181
|
-
codeToSend = this.speedCodes[84]
|
|
182
|
-
newMode = 'manual'
|
|
183
|
-
newValue = 84
|
|
184
|
-
} else {
|
|
185
|
-
codeToSend = this.cacheAutoCode
|
|
186
|
-
}
|
|
187
|
-
} else {
|
|
188
|
-
codeToSend = this.speedCodes[newValue]
|
|
189
|
-
}
|
|
190
|
-
|
|
191
163
|
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
192
164
|
cmd: 'ptReal',
|
|
193
|
-
value:
|
|
165
|
+
value: this.speedCodes[value],
|
|
194
166
|
})
|
|
195
167
|
|
|
196
168
|
// Cache the new state and log if appropriate
|
|
197
|
-
if (this.
|
|
198
|
-
this.
|
|
199
|
-
this.accessory.log(`${platformLang.
|
|
200
|
-
}
|
|
201
|
-
if (this.cacheSpeed !== newValue) {
|
|
202
|
-
this.cacheSpeed = newValue
|
|
203
|
-
this.accessory.log(`${platformLang.curSpeed} [${newValue}%]`)
|
|
169
|
+
if (this.cacheSpeed !== value) {
|
|
170
|
+
this.cacheSpeed = value
|
|
171
|
+
this.accessory.log(`${platformLang.curSpeed} [${value}]`)
|
|
204
172
|
}
|
|
205
173
|
} catch (err) {
|
|
206
174
|
// Catch any errors during the process
|
|
@@ -216,22 +184,33 @@ export default class {
|
|
|
216
184
|
|
|
217
185
|
async internalSwingUpdate(value) {
|
|
218
186
|
try {
|
|
219
|
-
const newValue = value ? 'on' : 'off'
|
|
220
187
|
// Don't continue if the new value is the same as before
|
|
221
188
|
if (this.cacheSwing === value) {
|
|
222
189
|
return
|
|
223
190
|
}
|
|
224
191
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
192
|
+
throw new Error('Swing mode update not implemented yet')
|
|
193
|
+
|
|
194
|
+
// const newValue = value ? 'on' : 'off'
|
|
195
|
+
// The existing cacheSwingCode might be something like aa1d0101960384000000000000000000000000a6
|
|
196
|
+
// We need to change the third hex value to 00 for off or 01 for on
|
|
197
|
+
// const hexValues = [
|
|
198
|
+
// 0x3A,
|
|
199
|
+
// 0x1D,
|
|
200
|
+
// value ? 0x01 : 0x00,
|
|
201
|
+
// ...this.cacheSwingCode.slice(6, 14).match(/.{1,2}/g).map(byte => Number.parseInt(byte, 16)),
|
|
202
|
+
// ]
|
|
203
|
+
//
|
|
204
|
+
// await this.platform.sendDeviceUpdate(this.accessory, {
|
|
205
|
+
// cmd: 'multiSync',
|
|
206
|
+
// value: generateCodeFromHexValues(hexValues),
|
|
207
|
+
// })
|
|
229
208
|
|
|
230
209
|
// Cache the new state and log if appropriate
|
|
231
|
-
if (this.cacheSwing !== newValue) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
210
|
+
// if (this.cacheSwing !== newValue) {
|
|
211
|
+
// this.cacheSwing = newValue
|
|
212
|
+
// this.accessory.log(`${platformLang.curSwing} [${newValue}]`)
|
|
213
|
+
// }
|
|
235
214
|
} catch (err) {
|
|
236
215
|
// Catch any errors during the process
|
|
237
216
|
this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
|
|
@@ -408,16 +387,11 @@ export default class {
|
|
|
408
387
|
case '0501': {
|
|
409
388
|
// Fan speed
|
|
410
389
|
const newSpeed = getTwoItemPosition(hexParts, 4)
|
|
411
|
-
const newSpeedInt = Number.parseInt(newSpeed, 16)
|
|
412
|
-
const newMode = 'manual'
|
|
413
|
-
if (this.cacheMode !== newMode) {
|
|
414
|
-
this.cacheMode = newMode
|
|
415
|
-
this.accessory.log(`${platformLang.curMode} [${this.cacheMode}]`)
|
|
416
|
-
}
|
|
390
|
+
const newSpeedInt = Number.parseInt(newSpeed, 16)
|
|
417
391
|
if (this.cacheSpeed !== newSpeedInt) {
|
|
418
392
|
this.cacheSpeed = newSpeedInt
|
|
419
393
|
this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
|
|
420
|
-
this.accessory.log(`${platformLang.curSpeed} [${this.cacheSpeed}
|
|
394
|
+
this.accessory.log(`${platformLang.curSpeed} [${this.cacheSpeed}]`)
|
|
421
395
|
}
|
|
422
396
|
break
|
|
423
397
|
}
|
|
@@ -430,66 +404,66 @@ export default class {
|
|
|
430
404
|
// Sleep: 5
|
|
431
405
|
// Nature: 6
|
|
432
406
|
// Turbo: 7
|
|
433
|
-
const newMode = getTwoItemPosition(hexParts, 4) === '03' ? 'auto' : 'manual'
|
|
434
|
-
if (this.cacheMode !== newMode) {
|
|
435
|
-
this.cacheMode = newMode
|
|
436
|
-
this.accessory.log(`${platformLang.curMode} [${this.cacheMode}]`)
|
|
437
|
-
|
|
438
|
-
if (this.cacheMode === 'auto' && this.cacheSpeed < 91) {
|
|
439
|
-
this.cacheSpeed = 91
|
|
440
|
-
this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
|
|
441
|
-
this.accessory.log(`${platformLang.curSpeed} [${this.cacheSpeed}%]`)
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
break
|
|
445
|
-
}
|
|
446
|
-
case '0503': {
|
|
447
|
-
// Auto mode, we need to keep this code to send it back to the device
|
|
448
|
-
const code = hexToTwoItems(`33${hexString.substring(2, hexString.length - 2)}`)
|
|
449
|
-
this.cacheAutoCode = generateCodeFromHexValues(code.map(p => Number.parseInt(p, 16)))
|
|
450
407
|
break
|
|
451
408
|
}
|
|
452
409
|
case '1b01': {
|
|
453
|
-
|
|
454
|
-
if (this.
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
410
|
+
// Night light on/off
|
|
411
|
+
if (!this.hideLight) {
|
|
412
|
+
const newLightState = getTwoItemPosition(hexParts, 4) === '01' ? 'on' : 'off'
|
|
413
|
+
if (this.cacheLightState !== newLightState) {
|
|
414
|
+
this.cacheLightState = newLightState
|
|
415
|
+
this.lightService.updateCharacteristic(this.hapChar.On, this.cacheLightState === 'on')
|
|
416
|
+
this.accessory.log(`${platformLang.curLight} [${this.cacheLightState}]`)
|
|
417
|
+
}
|
|
418
|
+
const newBrightness = hexToDecimal(getTwoItemPosition(hexParts, 5))
|
|
419
|
+
if (this.cacheBright !== newBrightness) {
|
|
420
|
+
this.cacheBright = newBrightness
|
|
421
|
+
this.lightService.updateCharacteristic(this.hapChar.Brightness, this.cacheBright)
|
|
422
|
+
this.accessory.log(`${platformLang.curBright} [${this.cacheBright}%]`)
|
|
423
|
+
}
|
|
464
424
|
}
|
|
465
425
|
break
|
|
466
426
|
}
|
|
467
427
|
case '1b05': {
|
|
468
428
|
// Night light colour
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
429
|
+
if (!this.hideLight) {
|
|
430
|
+
const newR = hexToDecimal(getTwoItemPosition(hexParts, 5))
|
|
431
|
+
const newG = hexToDecimal(getTwoItemPosition(hexParts, 6))
|
|
432
|
+
const newB = hexToDecimal(getTwoItemPosition(hexParts, 7))
|
|
433
|
+
|
|
434
|
+
const hs = rgb2hs(newR, newG, newB)
|
|
435
|
+
|
|
436
|
+
// Check for a colour change
|
|
437
|
+
if (hs[0] !== this.cacheHue) {
|
|
438
|
+
// Colour is different so update Homebridge with new values
|
|
439
|
+
this.lightService.updateCharacteristic(this.hapChar.Hue, hs[0])
|
|
440
|
+
this.lightService.updateCharacteristic(this.hapChar.Saturation, hs[1]);
|
|
441
|
+
[this.cacheHue] = hs
|
|
442
|
+
|
|
443
|
+
// Log the change
|
|
444
|
+
this.accessory.log(`${platformLang.curColour} [rgb ${newR} ${newG} ${newB}]`)
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
break
|
|
448
|
+
}
|
|
449
|
+
case '1d00':{
|
|
450
|
+
// Swing Mode Off
|
|
451
|
+
const newSwing = 'off'
|
|
452
|
+
this.cacheSwingCode = hexString
|
|
453
|
+
if (this.cacheSwing !== newSwing) {
|
|
454
|
+
this.cacheSwing = newSwing
|
|
455
|
+
this.service.updateCharacteristic(this.hapChar.SwingMode, 0)
|
|
456
|
+
this.accessory.log(`${platformLang.curSwing} [${this.cacheSwing}]`)
|
|
484
457
|
}
|
|
485
458
|
break
|
|
486
459
|
}
|
|
487
|
-
case '
|
|
488
|
-
// Swing Mode
|
|
489
|
-
const newSwing =
|
|
460
|
+
case '1d01':{
|
|
461
|
+
// Swing Mode On
|
|
462
|
+
const newSwing = 'on'
|
|
463
|
+
this.cacheSwingCode = hexString
|
|
490
464
|
if (this.cacheSwing !== newSwing) {
|
|
491
465
|
this.cacheSwing = newSwing
|
|
492
|
-
this.service.updateCharacteristic(this.hapChar.SwingMode,
|
|
466
|
+
this.service.updateCharacteristic(this.hapChar.SwingMode, 1)
|
|
493
467
|
this.accessory.log(`${platformLang.curSwing} [${this.cacheSwing}]`)
|
|
494
468
|
}
|
|
495
469
|
break
|
package/lib/platform.js
CHANGED
package/lib/utils/constants.js
CHANGED
|
@@ -91,7 +91,7 @@ export default {
|
|
|
91
91
|
],
|
|
92
92
|
leakDevices: ['label', 'deviceId', 'ignoreDevice', 'lowBattThreshold'],
|
|
93
93
|
thermoDevices: ['label', 'deviceId', 'ignoreDevice', 'lowBattThreshold', 'showExtraSwitch'],
|
|
94
|
-
fanDevices: ['label', 'deviceId', 'ignoreDevice'],
|
|
94
|
+
fanDevices: ['label', 'deviceId', 'ignoreDevice', 'hideLight'],
|
|
95
95
|
heaterDevices: ['label', 'deviceId', 'ignoreDevice', 'tempReporting'],
|
|
96
96
|
humidifierDevices: ['label', 'deviceId', 'ignoreDevice'],
|
|
97
97
|
dehumidifierDevices: ['label', 'deviceId', 'ignoreDevice'],
|
package/lib/utils/eve-chars.js
CHANGED
|
@@ -1,65 +1,71 @@
|
|
|
1
|
-
import { inherits } from 'node:util'
|
|
2
|
-
|
|
3
1
|
export default class {
|
|
4
2
|
constructor(api) {
|
|
5
|
-
this.hapServ = api.hap.Service
|
|
6
|
-
this.hapChar = api.hap.Characteristic
|
|
7
3
|
this.uuids = {
|
|
8
4
|
currentConsumption: 'E863F10D-079E-48FF-8F27-9C2605A29F52',
|
|
9
5
|
voltage: 'E863F10A-079E-48FF-8F27-9C2605A29F52',
|
|
10
6
|
electricCurrent: 'E863F126-079E-48FF-8F27-9C2605A29F52',
|
|
11
7
|
lastActivation: 'E863F11A-079E-48FF-8F27-9C2605A29F52',
|
|
12
8
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
9
|
+
|
|
10
|
+
const uuids = this.uuids
|
|
11
|
+
|
|
12
|
+
this.CurrentConsumption = class extends api.hap.Characteristic {
|
|
13
|
+
constructor() {
|
|
14
|
+
super('Current Consumption', uuids.currentConsumption)
|
|
15
|
+
this.setProps({
|
|
16
|
+
format: api.hap.Formats.UINT16,
|
|
17
|
+
unit: 'W',
|
|
18
|
+
maxValue: 100000,
|
|
19
|
+
minValue: 0,
|
|
20
|
+
minStep: 1,
|
|
21
|
+
perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY],
|
|
22
|
+
})
|
|
23
|
+
this.value = this.getDefaultValue()
|
|
24
|
+
}
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
|
|
27
|
+
this.Voltage = class extends api.hap.Characteristic {
|
|
28
|
+
constructor() {
|
|
29
|
+
super('Voltage', uuids.voltage)
|
|
30
|
+
this.setProps({
|
|
31
|
+
format: api.hap.Formats.FLOAT,
|
|
32
|
+
unit: 'V',
|
|
33
|
+
maxValue: 100000000000,
|
|
34
|
+
minValue: 0,
|
|
35
|
+
minStep: 1,
|
|
36
|
+
perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY],
|
|
37
|
+
})
|
|
38
|
+
this.value = this.getDefaultValue()
|
|
39
|
+
}
|
|
37
40
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
|
|
42
|
+
this.ElectricCurrent = class extends api.hap.Characteristic {
|
|
43
|
+
constructor() {
|
|
44
|
+
super('Electric Current', uuids.electricCurrent)
|
|
45
|
+
this.setProps({
|
|
46
|
+
format: api.hap.Formats.FLOAT,
|
|
47
|
+
unit: 'A',
|
|
48
|
+
maxValue: 100000000000,
|
|
49
|
+
minValue: 0,
|
|
50
|
+
minStep: 0.1,
|
|
51
|
+
perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY],
|
|
52
|
+
})
|
|
53
|
+
this.value = this.getDefaultValue()
|
|
54
|
+
}
|
|
49
55
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
|
|
57
|
+
this.LastActivation = class extends api.hap.Characteristic {
|
|
58
|
+
constructor() {
|
|
59
|
+
super('Last Activation', uuids.lastActivation)
|
|
60
|
+
this.setProps({
|
|
61
|
+
format: api.hap.Formats.UINT32,
|
|
62
|
+
unit: api.hap.Units.SECONDS,
|
|
63
|
+
perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY],
|
|
64
|
+
})
|
|
65
|
+
this.value = this.getDefaultValue()
|
|
66
|
+
}
|
|
58
67
|
}
|
|
59
|
-
|
|
60
|
-
inherits(this.Voltage, this.hapChar)
|
|
61
|
-
inherits(this.ElectricCurrent, this.hapChar)
|
|
62
|
-
inherits(this.LastActivation, this.hapChar)
|
|
68
|
+
|
|
63
69
|
this.CurrentConsumption.UUID = this.uuids.currentConsumption
|
|
64
70
|
this.Voltage.UUID = this.uuids.voltage
|
|
65
71
|
this.ElectricCurrent.UUID = this.uuids.electricCurrent
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@homebridge-plugins/homebridge-govee",
|
|
3
3
|
"alias": "Govee",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "11.3.0",
|
|
5
|
+
"version": "11.3.2-beta.0",
|
|
6
6
|
"description": "Homebridge plugin to integrate Govee devices into HomeKit.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "bwp91",
|
|
@@ -68,6 +68,6 @@
|
|
|
68
68
|
"@stoprocent/noble": "^1.19.1"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@antfu/eslint-config": "^4.
|
|
71
|
+
"@antfu/eslint-config": "^4.17.0"
|
|
72
72
|
}
|
|
73
73
|
}
|