@homebridge-plugins/homebridge-govee 11.32.2-beta.22 → 11.32.2-beta.24
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 +2 -0
- package/lib/device/appliance-basic.js +8 -1
- package/lib/device/index.js +4 -2
- package/lib/device/sensor-probe.js +52 -0
- package/lib/utils/capabilities.js +1 -0
- package/lib/utils/constants.js +24 -5
- package/lib/utils/dispatch.js +2 -1
- package/package.json +1 -1
- package/lib/device/sensor-thermo4.js +0 -59
package/CHANGELOG.md
CHANGED
|
@@ -41,6 +41,8 @@ All notable changes to `@homebridge-plugins/homebridge-govee` will be documented
|
|
|
41
41
|
- feat: say when govee has not listed a capability the plugin is about to use, since the request then succeeds and the device does nothing
|
|
42
42
|
- docs: note that the local network api accepts the raw command form, which is how scenes work without the cloud
|
|
43
43
|
- refactor: give every device one shared starting point, so the way a failed command is reported and undone is decided in one place rather than a hundred
|
|
44
|
+
- feat: recognise eleven more meat thermometers, which report what they send so their readings can be worked out, and stop the one already known printing its whole update as a warning
|
|
45
|
+
- feat: add the H5161 power strip and give the H7184 kitchen composter an on and off switch
|
|
44
46
|
|
|
45
47
|
## v11.32.1 (2026-08-02)
|
|
46
48
|
|
|
@@ -66,7 +66,7 @@ class ApplianceBasic extends GoveeDevice {
|
|
|
66
66
|
// The plain Fan service switches on a boolean `On`, while Fanv2 and
|
|
67
67
|
// AirPurifier use `Active`. Follow whichever this service uses, so these
|
|
68
68
|
// tiles behave like the hand-written handlers for the same kind of device.
|
|
69
|
-
const usesOn = serviceName === 'Fan'
|
|
69
|
+
const usesOn = serviceName === 'Fan' || serviceName === 'Switch'
|
|
70
70
|
this.powerChar = usesOn ? this.hapChar.On : this.hapChar.Active
|
|
71
71
|
this.powerOn = usesOn ? true : 1
|
|
72
72
|
this.powerOff = usesOn ? false : 0
|
|
@@ -354,6 +354,13 @@ export const deviceDiffuserBasic = makeBasicAppliance({
|
|
|
354
354
|
currentStateOff: 0, // inactive
|
|
355
355
|
})
|
|
356
356
|
|
|
357
|
+
// A composter is on or off. It has a mode and a light too, but neither is
|
|
358
|
+
// worked out, so they are left off rather than shown as controls that do nothing
|
|
359
|
+
export const deviceComposterBasic = makeBasicAppliance({
|
|
360
|
+
family: 'composter',
|
|
361
|
+
service: 'Switch',
|
|
362
|
+
})
|
|
363
|
+
|
|
357
364
|
export const devicePurifierBasic = makeBasicAppliance({
|
|
358
365
|
family: 'purifier',
|
|
359
366
|
service: 'AirPurifier',
|
package/lib/device/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
deviceComposterBasic,
|
|
2
3
|
deviceDehumidifierBasic,
|
|
3
4
|
deviceDiffuserBasic,
|
|
4
5
|
deviceFanBasic,
|
|
@@ -37,7 +38,7 @@ import deviceSensorCO2 from './sensor-co2.js'
|
|
|
37
38
|
import deviceSensorLeak from './sensor-leak.js'
|
|
38
39
|
import deviceSensorMonitor from './sensor-monitor.js'
|
|
39
40
|
import deviceSensorPresence from './sensor-presence.js'
|
|
40
|
-
import
|
|
41
|
+
import deviceSensorProbe from './sensor-probe.js'
|
|
41
42
|
import deviceSensorThermoSwitch from './sensor-thermo-switch.js'
|
|
42
43
|
import deviceSensorThermo from './sensor-thermo.js'
|
|
43
44
|
import deviceSwitchDouble, { asOutlet as deviceOutletDouble } from './switch-double.js'
|
|
@@ -55,6 +56,7 @@ export default {
|
|
|
55
56
|
deviceDehumidifierH7152: deviceDehumidifierH7150, // same device, and this gives it proper speed feedback
|
|
56
57
|
deviceDiffuserH7161,
|
|
57
58
|
deviceDiffuserH7162: deviceDiffuserH7161, // identical to the H7161
|
|
59
|
+
deviceComposterBasic,
|
|
58
60
|
deviceDehumidifierBasic,
|
|
59
61
|
deviceDiffuserBasic,
|
|
60
62
|
deviceFanBasic,
|
|
@@ -116,7 +118,7 @@ export default {
|
|
|
116
118
|
deviceSensorPresence,
|
|
117
119
|
deviceSensorThermo,
|
|
118
120
|
deviceSensorThermoSwitch,
|
|
119
|
-
|
|
121
|
+
deviceSensorProbe,
|
|
120
122
|
deviceSwitchDouble,
|
|
121
123
|
deviceSwitchSingle,
|
|
122
124
|
deviceSwitchTriple,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { base64ToHex } from '../utils/functions.js'
|
|
2
|
+
import { logUnknownData } from '../utils/report-unknown.js'
|
|
3
|
+
import GoveeDevice from './base.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A meat thermometer: one or more probes, each reading its own temperature.
|
|
7
|
+
*
|
|
8
|
+
* None of these models has had its readings worked out yet. The H5198 was once
|
|
9
|
+
* given the ordinary thermometer tiles and it went badly - owners saw one probe
|
|
10
|
+
* out of four, stuck at its starting value (#338). A tile showing a number that
|
|
11
|
+
* never changes is worse than no tile, because there is no way to tell it apart
|
|
12
|
+
* from a real reading.
|
|
13
|
+
*
|
|
14
|
+
* So this offers nothing, and instead reports what the device sends in the form
|
|
15
|
+
* that can be pasted into an issue. One owner's log is all that is needed to
|
|
16
|
+
* turn these into real temperature tiles.
|
|
17
|
+
*/
|
|
18
|
+
export default class extends GoveeDevice {
|
|
19
|
+
constructor(platform, accessory) {
|
|
20
|
+
super(platform, accessory)
|
|
21
|
+
|
|
22
|
+
// Clear the tiles a previous version gave this device, which never updated
|
|
23
|
+
this.removeServiceIfPresent(this.hapServ.TemperatureSensor)
|
|
24
|
+
this.removeServiceIfPresent(this.hapServ.HumiditySensor)
|
|
25
|
+
this.removeServiceIfPresent(this.hapServ.Battery)
|
|
26
|
+
|
|
27
|
+
this.logInitOptions({})
|
|
28
|
+
this.accessory.log('this thermometer\'s readings are not understood yet, so it has no tiles - the lines below are what is needed to add them')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
externalUpdate(params) {
|
|
32
|
+
// The probe readings could arrive as raw commands or as fields on the
|
|
33
|
+
// update itself, and which is not known yet - so both are reported
|
|
34
|
+
;(params.commands || []).forEach((command) => {
|
|
35
|
+
logUnknownData(this.accessory, {
|
|
36
|
+
kind: 'probe reading',
|
|
37
|
+
source: params.source,
|
|
38
|
+
raw: command,
|
|
39
|
+
hex: base64ToHex(command),
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const fields = Object.keys(params).filter(key => !['commands', 'source'].includes(key))
|
|
44
|
+
if (fields.length > 0) {
|
|
45
|
+
logUnknownData(this.accessory, {
|
|
46
|
+
kind: 'probe update',
|
|
47
|
+
source: params.source,
|
|
48
|
+
raw: JSON.stringify(Object.fromEntries(fields.map(key => [key, params[key]]))),
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -40,6 +40,7 @@ const familyControls = {
|
|
|
40
40
|
purifier: { swing: false, lock: false, light: false },
|
|
41
41
|
iceMaker: { swing: false, lock: false, light: false },
|
|
42
42
|
diffuser: { swing: false, lock: false, light: false },
|
|
43
|
+
composter: { swing: false, lock: false, light: false },
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
const emptyControls = {
|
package/lib/utils/constants.js
CHANGED
|
@@ -623,7 +623,9 @@ export default {
|
|
|
623
623
|
// showAs to 'valve' or 'tap' for a more fitting HomeKit tile (#1324)
|
|
624
624
|
switchSingle: ['H5001', 'H5080', 'H5081', 'H5083', 'H5085', 'H5086', 'H5901', 'H7014'],
|
|
625
625
|
switchDouble: ['H5082', 'H5089'],
|
|
626
|
-
|
|
626
|
+
// The H5161 shares the H5160's goodsType, which is what decides how the
|
|
627
|
+
// app talks to it, so it is handled the same way
|
|
628
|
+
switchTriple: ['H5160', 'H5161'],
|
|
627
629
|
sensorLeak: ['H5054', 'H5058', 'H5059', 'H5830'],
|
|
628
630
|
sensorThermo: [
|
|
629
631
|
'B5178',
|
|
@@ -657,7 +659,27 @@ export default {
|
|
|
657
659
|
'H5310', // https://github.com/homebridge-plugins/homebridge-govee/issues/1293
|
|
658
660
|
'R5112', // the refreshed H5112
|
|
659
661
|
],
|
|
660
|
-
|
|
662
|
+
// Meat thermometers. None has had its readings worked out yet, so they
|
|
663
|
+
// report what they send rather than showing a tile that never changes.
|
|
664
|
+
// ⚠️ The H5183 is one of these but stays on the list above, because it has
|
|
665
|
+
// been given working tiles for years and nobody has said they are wrong
|
|
666
|
+
// Power only for now. It also has a mode and a light, which report what
|
|
667
|
+
// they need rather than guessing (#1282)
|
|
668
|
+
composter: ['H7184'],
|
|
669
|
+
|
|
670
|
+
sensorProbe: [
|
|
671
|
+
'H5181',
|
|
672
|
+
'H5182',
|
|
673
|
+
'H5184',
|
|
674
|
+
'H5185', // https://github.com/homebridge-plugins/homebridge-govee/issues/804
|
|
675
|
+
'H5191', // https://github.com/homebridge-plugins/homebridge-govee/issues/1121
|
|
676
|
+
'H5192',
|
|
677
|
+
'H5194',
|
|
678
|
+
'H5196',
|
|
679
|
+
'H5198',
|
|
680
|
+
'H5199',
|
|
681
|
+
'H5610',
|
|
682
|
+
],
|
|
661
683
|
sensorMonitor: ['H5106'],
|
|
662
684
|
sensorCO2: ['H5140'], // CO2 + temp + humidity monitor, AWS opcode 0x0A — closes #1179
|
|
663
685
|
fan: ['H1310', 'H1370', 'H7100', 'H7101', 'H7102', 'H7103', 'H7105', 'H7106', 'H7107', 'H7111', 'H7112', 'R1310'],
|
|
@@ -686,9 +708,6 @@ export default {
|
|
|
686
708
|
'H5126', // https://github.com/homebridge-plugins/homebridge-govee/issues/910
|
|
687
709
|
'H5129', // https://github.com/homebridge-plugins/homebridge-govee/issues/1084
|
|
688
710
|
'H5125', // https://github.com/homebridge-plugins/homebridge-govee/issues/981
|
|
689
|
-
'H5185', // https://github.com/homebridge-plugins/homebridge-govee/issues/804
|
|
690
|
-
'H5191', // https://github.com/homebridge-plugins/homebridge-govee/issues/1121
|
|
691
|
-
'H7184', // https://github.com/homebridge-plugins/homebridge-govee/issues/1282
|
|
692
711
|
],
|
|
693
712
|
},
|
|
694
713
|
|
package/lib/utils/dispatch.js
CHANGED
|
@@ -45,7 +45,8 @@ const routes = [
|
|
|
45
45
|
list: 'sensorThermo',
|
|
46
46
|
choose: ({ deviceConf }) => (deviceConf.showExtraSwitch ? 'deviceSensorThermoSwitch' : 'deviceSensorThermo'),
|
|
47
47
|
},
|
|
48
|
-
{ list: '
|
|
48
|
+
{ list: 'composter', handler: 'deviceComposterBasic', awsPolling: true },
|
|
49
|
+
{ list: 'sensorProbe', handler: 'deviceSensorProbe' },
|
|
49
50
|
{ list: 'sensorMonitor', handler: 'deviceSensorMonitor', awsPolling: true },
|
|
50
51
|
{ list: 'sensorCO2', handler: 'deviceSensorCO2', awsPolling: true },
|
|
51
52
|
{ list: 'fan', prefix: 'deviceFan', fallback: 'deviceFanBasic' },
|
package/package.json
CHANGED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { base64ToHex, getTwoItemPosition, hexToTwoItems } from '../utils/functions.js'
|
|
2
|
-
import platformLang from '../utils/lang-en.js'
|
|
3
|
-
import { logUnknownData } from '../utils/report-unknown.js'
|
|
4
|
-
import GoveeDevice from './base.js'
|
|
5
|
-
|
|
6
|
-
export default class extends GoveeDevice {
|
|
7
|
-
constructor(platform, accessory) {
|
|
8
|
-
super(platform, accessory)
|
|
9
|
-
// remove temperature sensor, humidity sensor, battery service
|
|
10
|
-
if (this.accessory.getService(this.hapServ.TemperatureSensor)) {
|
|
11
|
-
this.accessory.removeService(this.accessory.getService(this.hapServ.TemperatureSensor))
|
|
12
|
-
}
|
|
13
|
-
if (this.accessory.getService(this.hapServ.HumiditySensor)) {
|
|
14
|
-
this.accessory.removeService(this.accessory.getService(this.hapServ.HumiditySensor))
|
|
15
|
-
}
|
|
16
|
-
if (this.accessory.getService(this.hapServ.Battery)) {
|
|
17
|
-
this.accessory.removeService(this.accessory.getService(this.hapServ.Battery))
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Output the customised options to the log
|
|
21
|
-
const opts = JSON.stringify({})
|
|
22
|
-
platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
externalUpdate(params) {
|
|
26
|
-
this.accessory.logWarn(JSON.stringify(params, null, 2));
|
|
27
|
-
|
|
28
|
-
// Check for some other scene/mode change
|
|
29
|
-
(params.commands || []).forEach((command) => {
|
|
30
|
-
const hexString = base64ToHex(command)
|
|
31
|
-
const hexParts = hexToTwoItems(hexString)
|
|
32
|
-
|
|
33
|
-
logUnknownData(this.accessory, {
|
|
34
|
-
kind: 'scene',
|
|
35
|
-
source: params.source,
|
|
36
|
-
raw: command,
|
|
37
|
-
hex: hexString,
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
// Return now if not a device query update code
|
|
41
|
-
if (getTwoItemPosition(hexParts, 1) !== 'aa') {
|
|
42
|
-
return
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const deviceFunction = `${getTwoItemPosition(hexParts, 1)}${getTwoItemPosition(hexParts, 2)}`
|
|
46
|
-
|
|
47
|
-
switch (deviceFunction) {
|
|
48
|
-
default:
|
|
49
|
-
logUnknownData(this.accessory, {
|
|
50
|
-
kind: 'scene',
|
|
51
|
-
source: params.source,
|
|
52
|
-
raw: command,
|
|
53
|
-
hex: hexString,
|
|
54
|
-
})
|
|
55
|
-
break
|
|
56
|
-
}
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
}
|