@homebridge-plugins/homebridge-govee 11.25.0 → 11.26.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 +11 -0
- package/lib/device/light.js +17 -5
- package/lib/platform.js +26 -10
- package/lib/utils/constants.js +2 -0
- package/lib/utils/device-capabilities.js +3 -1
- package/lib/utils/lang-en.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@homebridge-plugins/homebridge-govee` will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## v11.26.0 (2026-07-12)
|
|
6
|
+
|
|
7
|
+
### Changes
|
|
8
|
+
|
|
9
|
+
- feat: add support for the H609D Galaxy Light Projector (#1298)
|
|
10
|
+
- fix: never remove accessories based on a failed device fetch (#1264)
|
|
11
|
+
- fix: skip Govee app device groups from the OpenAPI device list (#1309)
|
|
12
|
+
- feat: add under-construction support for the H1370 fan (#1307)
|
|
13
|
+
- fix: use the segment-based BLE colour command for the H617E (#1290)
|
|
14
|
+
- fix: send the on command first so scenes from off apply their colour (#1277)
|
|
15
|
+
|
|
5
16
|
## v11.25.0 (2026-07-12)
|
|
6
17
|
|
|
7
18
|
### Changes
|
package/lib/device/light.js
CHANGED
|
@@ -250,8 +250,13 @@ export default class {
|
|
|
250
250
|
return
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
//
|
|
254
|
-
|
|
253
|
+
// Send off after colour/brightness (a colour command can implicitly power a
|
|
254
|
+
// bulb back on), but send on straight away so the bulb is awake in time to
|
|
255
|
+
// receive the colour and brightness a HomeKit scene sends alongside it, as
|
|
256
|
+
// some models ignore these commands while switched off (#1277)
|
|
257
|
+
if (newValue === 'off') {
|
|
258
|
+
await sleep(400)
|
|
259
|
+
}
|
|
255
260
|
|
|
256
261
|
// Send the request to the platform sender function
|
|
257
262
|
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
@@ -316,9 +321,11 @@ export default class {
|
|
|
316
321
|
async internalBrightnessUpdate(value) {
|
|
317
322
|
try {
|
|
318
323
|
// This acts like a debounce function when endlessly sliding the brightness scale
|
|
324
|
+
// If the light is off (e.g. a HomeKit scene turning it on), wait longer so the
|
|
325
|
+
// on command sent by internalStateUpdate has time to wake the bulb first (#1277)
|
|
319
326
|
const updateKeyBright = generateRandomString(5)
|
|
320
327
|
this.updateKeyBright = updateKeyBright
|
|
321
|
-
await sleep(350)
|
|
328
|
+
await sleep(this.cacheState !== 'on' ? 1050 : 350)
|
|
322
329
|
if (updateKeyBright !== this.updateKeyBright) {
|
|
323
330
|
return
|
|
324
331
|
}
|
|
@@ -367,9 +374,11 @@ export default class {
|
|
|
367
374
|
async internalColourUpdate(value, force = false) {
|
|
368
375
|
try {
|
|
369
376
|
// This acts like a debounce function when endlessly sliding the colour wheel
|
|
377
|
+
// If the light is off (e.g. a HomeKit scene turning it on), wait longer so the
|
|
378
|
+
// on command sent by internalStateUpdate has time to wake the bulb first (#1277)
|
|
370
379
|
const updateKeyColour = generateRandomString(5)
|
|
371
380
|
this.updateKeyColour = updateKeyColour
|
|
372
|
-
await sleep(300)
|
|
381
|
+
await sleep(this.cacheState !== 'on' ? 1000 : 300)
|
|
373
382
|
if (updateKeyColour !== this.updateKeyColour) {
|
|
374
383
|
return
|
|
375
384
|
}
|
|
@@ -440,9 +449,12 @@ export default class {
|
|
|
440
449
|
async internalCTUpdate(value) {
|
|
441
450
|
try {
|
|
442
451
|
// This acts like a debounce function when endlessly sliding the colour wheel
|
|
452
|
+
// If the light is off (e.g. a HomeKit scene turning it on), wait longer so the
|
|
453
|
+
// on command sent by internalStateUpdate has time to wake the bulb first, and
|
|
454
|
+
// so the 'skip when off' check below sees the updated state (#1277)
|
|
443
455
|
const updateKeyCT = generateRandomString(5)
|
|
444
456
|
this.updateKeyCT = updateKeyCT
|
|
445
|
-
await sleep(300)
|
|
457
|
+
await sleep(this.cacheState !== 'on' ? 1000 : 300)
|
|
446
458
|
if (updateKeyCT !== this.updateKeyCT) {
|
|
447
459
|
return
|
|
448
460
|
}
|
package/lib/platform.js
CHANGED
|
@@ -654,6 +654,12 @@ export default class {
|
|
|
654
654
|
|
|
655
655
|
if (openApiDevices && openApiDevices.length > 0) {
|
|
656
656
|
openApiDevices.forEach((openApiDevice) => {
|
|
657
|
+
// Skip Govee app device groups as these are not real devices (#1309)
|
|
658
|
+
if (['BaseGroup', 'SameModeGroup'].includes(openApiDevice.model)) {
|
|
659
|
+
this.log.debug('[%s] %s.', openApiDevice.deviceName, platformLang.devIsGroup)
|
|
660
|
+
return
|
|
661
|
+
}
|
|
662
|
+
|
|
657
663
|
if (this.ignoredDevices.includes(openApiDevice.device)) {
|
|
658
664
|
return
|
|
659
665
|
}
|
|
@@ -717,18 +723,28 @@ export default class {
|
|
|
717
723
|
}
|
|
718
724
|
|
|
719
725
|
// Check for redundant Homebridge accessories
|
|
726
|
+
// Only treat 'not found in Govee' as a reason to remove an accessory when the
|
|
727
|
+
// configured cloud clients actually returned their device lists this session,
|
|
728
|
+
// otherwise a failed fetch would remove the accessory and destroy any HomeKit
|
|
729
|
+
// scenes and automations it is part of (#1264)
|
|
730
|
+
const cloudListsFetched = (!this.config.username || !!this.httpClient)
|
|
731
|
+
&& (!!this.config.openApiDisable || !this.config.apiKey || !!this.openApiClient)
|
|
720
732
|
devicesInHB.forEach((accessory) => {
|
|
721
|
-
//
|
|
722
|
-
//
|
|
723
|
-
//
|
|
724
|
-
|
|
725
|
-
if (
|
|
726
|
-
(!httpDevices.some(el => el.device === accessory.context.gvDeviceId)
|
|
727
|
-
&& !lanDevices.some(el => el.device === accessory.context.gvDeviceId)
|
|
728
|
-
&& !openApiDevices.some(el => el.device === accessory.context.gvDeviceId))
|
|
729
|
-
|| this.ignoredDevices.includes(accessory.context.gvDeviceId)
|
|
733
|
+
// Remove the accessory if it is now being ignored, or if it is a matter model
|
|
734
|
+
// and the user has enabled ignoreMatter (otherwise the cached accessory lingers
|
|
735
|
+
// even though the device is skipped during setup) (#1287)
|
|
736
|
+
const isIgnored = this.ignoredDevices.includes(accessory.context.gvDeviceId)
|
|
730
737
|
|| (this.config.ignoreMatter && platformConsts.matterModels.includes(accessory.context.gvModel))
|
|
731
|
-
|
|
738
|
+
|
|
739
|
+
// Also remove it if the device no longer exists in Govee, but never based on
|
|
740
|
+
// an incomplete cloud list, and never for LAN-only devices which may simply
|
|
741
|
+
// have missed a scan window (#1264)
|
|
742
|
+
const isMissing = !httpDevices.some(el => el.device === accessory.context.gvDeviceId)
|
|
743
|
+
&& !lanDevices.some(el => el.device === accessory.context.gvDeviceId)
|
|
744
|
+
&& !openApiDevices.some(el => el.device === accessory.context.gvDeviceId)
|
|
745
|
+
const isLanOnly = accessory.context.hasLanControl && !accessory.context.firmware
|
|
746
|
+
|
|
747
|
+
if (isIgnored || (isMissing && cloudListsFetched && !isLanOnly)) {
|
|
732
748
|
this.removeAccessory(accessory)
|
|
733
749
|
}
|
|
734
750
|
})
|
package/lib/utils/constants.js
CHANGED
|
@@ -219,6 +219,7 @@ export default {
|
|
|
219
219
|
'H6097',
|
|
220
220
|
'H6098',
|
|
221
221
|
'H6099',
|
|
222
|
+
'H609D',
|
|
222
223
|
'H60A0',
|
|
223
224
|
'H60A1',
|
|
224
225
|
'H60A4',
|
|
@@ -542,6 +543,7 @@ export default {
|
|
|
542
543
|
kettle: ['H7170', 'H7171', 'H7173', 'H7175', 'H717A'],
|
|
543
544
|
template: [
|
|
544
545
|
'H1162', // https://github.com/homebridge-plugins/homebridge-govee/issues/422
|
|
546
|
+
'H1370', // https://github.com/homebridge-plugins/homebridge-govee/issues/1307
|
|
545
547
|
'H1167', // https://github.com/homebridge-plugins/homebridge-govee/issues/1142
|
|
546
548
|
'H5010', // https://github.com/homebridge-plugins/homebridge-govee/issues/1235
|
|
547
549
|
'H5024', // https://github.com/homebridge-plugins/homebridge-govee/issues/835
|
|
@@ -14,12 +14,14 @@ const modelOverrides = {
|
|
|
14
14
|
H6102: { bleColorCmd: [COLOR_SUB.RGB_ALT], bleBrightnessScale: 0x64 },
|
|
15
15
|
H613B: { bleColorCmd: [COLOR_SUB.RGB_ALT], bleBrightnessScale: 0x64 },
|
|
16
16
|
H613D: { bleColorCmd: [COLOR_SUB.RGB_ALT], bleBrightnessScale: 0x64 },
|
|
17
|
-
H617E: { bleColorCmd: [COLOR_SUB.RGB_ALT], bleBrightnessScale: 0x64 },
|
|
18
17
|
|
|
19
18
|
// BLE color sub-command: 0x15 0x01 (extended) with trailing bytes
|
|
20
19
|
H6053: { bleColorCmd: COLOR_SUB.RGB_EXTENDED, bleColorCmdSuffix: [0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x7F] },
|
|
21
20
|
H6072: { bleColorCmd: COLOR_SUB.RGB_EXTENDED, bleColorCmdSuffix: [0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x7F] },
|
|
22
21
|
H6199: { bleColorCmd: COLOR_SUB.RGB_EXTENDED, bleColorCmdSuffix: [0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x7F] },
|
|
22
|
+
// H617E is an RGBIC strip which ignores the 0x0D command - it needs the
|
|
23
|
+
// segment-based extended format, as seen in its own TTR rule data (#1290)
|
|
24
|
+
H617E: { bleColorCmd: COLOR_SUB.RGB_EXTENDED, bleColorCmdSuffix: [0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x7F], bleBrightnessScale: 0x64 },
|
|
23
25
|
|
|
24
26
|
// AWS outlet uses 17/16 for on/off instead of 1/0
|
|
25
27
|
H5080: { awsPowerOn: 17, awsPowerOff: 16 },
|
package/lib/utils/lang-en.js
CHANGED
|
@@ -68,6 +68,7 @@ export default {
|
|
|
68
68
|
curWatt: 'current wattage',
|
|
69
69
|
devAdd: 'has been added to Homebridge',
|
|
70
70
|
devInit: 'initialised with id',
|
|
71
|
+
devIsGroup: 'is a Govee app device group so will not be added to Homebridge',
|
|
71
72
|
devInitOpts: 'initialising with options',
|
|
72
73
|
devMaySupp: 'is not currently supported, do create a Github issue with the following info',
|
|
73
74
|
devNoBlePackage: 'will not be added as BLE is disabled in the config',
|
package/package.json
CHANGED