@homebridge-plugins/homebridge-govee 10.12.1 → 10.13.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 +21 -6
- package/README.md +15 -15
- package/config.schema.json +6 -6
- package/lib/device/humidifier-H7147.js +157 -0
- package/lib/device/index.js +9 -5
- package/lib/device/purifier-H7129.js +296 -0
- package/lib/homebridge-ui/public/index.html +17 -13
- package/lib/platform.js +6 -2
- package/lib/utils/constants.js +43 -20
- package/lib/utils/functions.js +1 -1
- package/lib/utils/lang-en.js +1 -1
- package/package.json +8 -9
- /package/lib/device/{ice-maker-H7162.js → ice-maker-H7172.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,21 @@ This project tries to adhere to [Semantic Versioning](http://semver.org/). In pr
|
|
|
8
8
|
- `MINOR` version when a new device type is added, or when a new feature is added that is backwards-compatible
|
|
9
9
|
- `PATCH` version when backwards-compatible bug fixes are implemented
|
|
10
10
|
|
|
11
|
+
## v10.13.0 (2024-12-08)
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- added models H8072 and H80C4 (#969) (@EricHigdon)
|
|
16
|
+
- added recent models
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Bump `node` recommended versions to `v18.20.5` or `v20.18.1` or `v22.12.0`
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Fix for H5178 Temp sensor (#870) (@damonaw)
|
|
25
|
+
|
|
11
26
|
## v10.12.1 (2024-10-15)
|
|
12
27
|
|
|
13
28
|
### Fixed
|
|
@@ -302,7 +317,7 @@ This project tries to adhere to [Semantic Versioning](http://semver.org/). In pr
|
|
|
302
317
|
- bring some consistency to how the plugin handles scenes
|
|
303
318
|
|
|
304
319
|
See the first section of the updated wiki document for instructions:
|
|
305
|
-
- https://github.com/
|
|
320
|
+
- https://github.com/homebridge-plugins/homebridge-govee/wiki/Scene,-Music,-DIY-Modes
|
|
306
321
|
|
|
307
322
|
### Added
|
|
308
323
|
|
|
@@ -529,7 +544,7 @@ Unfortunately this update will break your kettle. This is something I am working
|
|
|
529
544
|
|
|
530
545
|
- Better handling of custom light scenes
|
|
531
546
|
- Unfortunately all existing scene codes are no longer valid - you will need to recreate your scenes
|
|
532
|
-
- See [wiki page](https://github.com/
|
|
547
|
+
- See [wiki page](https://github.com/homebridge-plugins/homebridge-govee/wiki/Scene,-Music,-DIY-Modes) for more info
|
|
533
548
|
- There _may_ be some older models which this method does not work for - if you have one of these, please open an issue
|
|
534
549
|
|
|
535
550
|
### Fixed
|
|
@@ -786,7 +801,7 @@ Unfortunately this update will break your kettle. This is something I am working
|
|
|
786
801
|
### Added
|
|
787
802
|
|
|
788
803
|
- 🎉 LAN mode! 🎉 (thanks [@alboiuvlad29](https://github.com/alboiuvlad29)!)
|
|
789
|
-
- See [the homebridge-govee wiki](https://github.com/
|
|
804
|
+
- See [the homebridge-govee wiki](https://github.com/homebridge-plugins/homebridge-govee/wiki/Supported-Devices) for supported devices
|
|
790
805
|
- The plugin will scan your local network for supported Govee lights
|
|
791
806
|
- You can also specify the IP address of your Govee light in the config
|
|
792
807
|
- The plugin will match any discovered devices to your existing accessories from cloud usage
|
|
@@ -1313,7 +1328,7 @@ See ⚠️ for potentially-breaking changes.
|
|
|
1313
1328
|
|
|
1314
1329
|
### Fixed
|
|
1315
1330
|
|
|
1316
|
-
- Removed H6144 from 'scale brightness' list, fixes [#99](https://github.com/
|
|
1331
|
+
- Removed H6144 from 'scale brightness' list, fixes [#99](https://github.com/homebridge-plugins/homebridge-govee/issues/99)
|
|
1317
1332
|
|
|
1318
1333
|
## v4.4.0 (2021-08-09)
|
|
1319
1334
|
|
|
@@ -1517,7 +1532,7 @@ See ⚠️ for potentially-breaking changes.
|
|
|
1517
1532
|
### Added
|
|
1518
1533
|
|
|
1519
1534
|
- Support for Bluetooth control for power/brightness/colour for supported devices
|
|
1520
|
-
- Extra packages may need to be installed on your system - [see wiki](https://github.com/
|
|
1535
|
+
- Extra packages may need to be installed on your system - [see wiki](https://github.com/homebridge-plugins/homebridge-govee/wiki/Bluetooth-Control)
|
|
1521
1536
|
- Enter your Govee username and password in the config
|
|
1522
1537
|
- Create an entry for your light in the 'Light Devices' section and check 'Enable Bluetooth Control'
|
|
1523
1538
|
|
|
@@ -1713,7 +1728,7 @@ See ⚠️ for potentially-breaking changes.
|
|
|
1713
1728
|
|
|
1714
1729
|
### Changed
|
|
1715
1730
|
|
|
1716
|
-
- **Light devices** will now send on/off commands **after** brightness and colour ([#56](https://github.com/
|
|
1731
|
+
- **Light devices** will now send on/off commands **after** brightness and colour ([#56](https://github.com/homebridge-plugins/homebridge-govee/issues/56))
|
|
1717
1732
|
- More welcome messages
|
|
1718
1733
|
- Updated `plugin-ui-utils` dependency
|
|
1719
1734
|
|
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<a href="https://github.com/
|
|
2
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee"><img src="https://user-images.githubusercontent.com/43026681/101324574-5e997d80-3862-11eb-81b0-932330f6e242.png" width="600px"></a>
|
|
3
3
|
</p>
|
|
4
4
|
<span align="center">
|
|
5
5
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
Homebridge plugin to integrate Govee devices into HomeKit
|
|
9
9
|
|
|
10
10
|
[](https://www.npmjs.com/package/homebridge-govee)
|
|
11
|
-
[](https://github.com/
|
|
11
|
+
[](https://github.com/homebridge-plugins/homebridge-govee/wiki/Beta-Version)
|
|
12
12
|
|
|
13
13
|
[](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
|
|
14
14
|
[](https://plugins.hoobs.org/plugin/homebridge-govee)
|
|
@@ -30,29 +30,29 @@ Homebridge plugin to integrate Govee devices into HomeKit
|
|
|
30
30
|
- To use this plugin, you will need to already have:
|
|
31
31
|
- [Node](https://nodejs.org): latest version of `v18` or `v20` - any other major version is not supported.
|
|
32
32
|
- [Homebridge](https://homebridge.io): `v1.6` - refer to link for more information and installation instructions.
|
|
33
|
-
- For bluetooth connectivity, it may be necessary to install extra packages on your system, see [Bluetooth Control](https://github.com/
|
|
33
|
+
- For bluetooth connectivity, it may be necessary to install extra packages on your system, see [Bluetooth Control](https://github.com/homebridge-plugins/homebridge-govee/wiki/Bluetooth-Control). Bluetooth works best when using a Raspberry Pi, not been tested on Windows, and Mac devices are unsupported.
|
|
34
34
|
|
|
35
35
|
### Setup
|
|
36
36
|
|
|
37
|
-
- [Installation](https://github.com/
|
|
38
|
-
- [Configuration](https://github.com/
|
|
37
|
+
- [Installation](https://github.com/homebridge-plugins/homebridge-govee/wiki/Installation)
|
|
38
|
+
- [Configuration](https://github.com/homebridge-plugins/homebridge-govee/wiki/Configuration)
|
|
39
39
|
- [Beta Version](https://github.com/homebridge/homebridge/wiki/How-to-Install-Alternate-Plugin-Versions)
|
|
40
|
-
- [Node Version](https://github.com/
|
|
40
|
+
- [Node Version](https://github.com/homebridge-plugins/homebridge-govee/wiki/Node-Version)
|
|
41
41
|
|
|
42
42
|
### Features
|
|
43
43
|
|
|
44
|
-
- [Supported Devices](https://github.com/
|
|
45
|
-
- [Connection Methods](https://github.com/
|
|
46
|
-
- [LAN Control](https://github.com/
|
|
47
|
-
- [AWS Control](https://github.com/
|
|
48
|
-
- [BLE Control](https://github.com/
|
|
49
|
-
- [Scene, Music, DIY Modes](https://github.com/
|
|
44
|
+
- [Supported Devices](https://github.com/homebridge-plugins/homebridge-govee/wiki/Supported-Devices)
|
|
45
|
+
- [Connection Methods](https://github.com/homebridge-plugins/homebridge-govee/wiki/Connection-Methods)
|
|
46
|
+
- [LAN Control](https://github.com/homebridge-plugins/homebridge-govee/wiki/LAN-Control)
|
|
47
|
+
- [AWS Control](https://github.com/homebridge-plugins/homebridge-govee/wiki/AWS-Control)
|
|
48
|
+
- [BLE Control](https://github.com/homebridge-plugins/homebridge-govee/wiki/Bluetooth-Control)
|
|
49
|
+
- [Scene, Music, DIY Modes](https://github.com/homebridge-plugins/homebridge-govee/wiki/Scene%2C-Music%2C-DIY-Modes)
|
|
50
50
|
|
|
51
51
|
### Help/About
|
|
52
52
|
|
|
53
|
-
- [Common Errors](https://github.com/
|
|
54
|
-
- [Support Request](https://github.com/
|
|
55
|
-
- [Changelog](https://github.com/
|
|
53
|
+
- [Common Errors](https://github.com/homebridge-plugins/homebridge-govee/wiki/Common-Errors)
|
|
54
|
+
- [Support Request](https://github.com/homebridge-plugins/homebridge-govee/issues/new/choose)
|
|
55
|
+
- [Changelog](https://github.com/homebridge-plugins/homebridge-govee/blob/latest/CHANGELOG.md)
|
|
56
56
|
- [About Me](https://github.com/sponsors/bwp91)
|
|
57
57
|
|
|
58
58
|
### Credits
|
package/config.schema.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"singular": true,
|
|
5
5
|
"customUi": true,
|
|
6
6
|
"customUiPath": "./lib/homebridge-ui",
|
|
7
|
-
"headerDisplay": "<p align=\"center\"><img width=\"60%\" src=\"https://user-images.githubusercontent.com/43026681/101324574-5e997d80-3862-11eb-81b0-932330f6e242.png\"></p><p align=\"center\">For help and support please visit our <a href=\"https://github.com/
|
|
7
|
+
"headerDisplay": "<p align=\"center\"><img width=\"60%\" src=\"https://user-images.githubusercontent.com/43026681/101324574-5e997d80-3862-11eb-81b0-932330f6e242.png\"></p><p align=\"center\">For help and support please visit our <a href=\"https://github.com/homebridge-plugins/homebridge-govee/wiki\">GitHub Wiki</a>. We hope you find this plugin useful!</p>",
|
|
8
8
|
"schema": {
|
|
9
9
|
"type": "object",
|
|
10
10
|
"properties": {
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
"username": {
|
|
17
17
|
"type": "string",
|
|
18
18
|
"title": "Govee Email",
|
|
19
|
-
"description": "Required for most device models and for AWS/BLE connections. <a href=\"https://github.com/
|
|
19
|
+
"description": "Required for most device models and for AWS/BLE connections. <a href=\"https://github.com/homebridge-plugins/homebridge-govee/wiki/Supported-Devices\" target=\"_blank\">Read more →</a>"
|
|
20
20
|
},
|
|
21
21
|
"password": {
|
|
22
22
|
"type": "string",
|
|
23
23
|
"title": "Govee Password",
|
|
24
|
-
"description": "Required for certain light models. <a href=\"https://github.com/
|
|
24
|
+
"description": "Required for certain light models. <a href=\"https://github.com/homebridge-plugins/homebridge-govee/wiki/Supported-Devices\" target=\"_blank\">Read more →</a>"
|
|
25
25
|
},
|
|
26
26
|
"httpRefreshTime": {
|
|
27
27
|
"title": "HTTP Refresh Interval",
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
"title": "Custom Bluetooth Address",
|
|
145
145
|
"type": "string",
|
|
146
146
|
"placeholder": "a1:b2:c3:d4:e5:f6",
|
|
147
|
-
"description": "The plugin may not be able to determine the bluetooth address of some older models. <a href=\"https://github.com/
|
|
147
|
+
"description": "The plugin may not be able to determine the bluetooth address of some older models. <a href=\"https://github.com/homebridge-plugins/homebridge-govee/wiki/Bluetooth-Control#finding-the-bluetooth-address\" target=\"_blank\">Read more →</a>",
|
|
148
148
|
"minLength": 17,
|
|
149
149
|
"maxLength": 17,
|
|
150
150
|
"condition": {
|
|
@@ -1087,7 +1087,7 @@
|
|
|
1087
1087
|
"type": "string",
|
|
1088
1088
|
"description": "Enter the 23/26 digit Govee Device ID to begin (e.g. 12:AB:A1:C5:A8:99:D2:17).",
|
|
1089
1089
|
"minLength": 23,
|
|
1090
|
-
"maxLength":
|
|
1090
|
+
"maxLength": 26
|
|
1091
1091
|
},
|
|
1092
1092
|
"ignoreDevice": {
|
|
1093
1093
|
"type": "boolean",
|
|
@@ -1458,7 +1458,7 @@
|
|
|
1458
1458
|
"expandable": true,
|
|
1459
1459
|
"title": "Custom Scenes/Modes",
|
|
1460
1460
|
"type": "fieldset",
|
|
1461
|
-
"description": "Use these settings to start creating HomeKit scenes with your Govee scenes, music mode and DIY modes. <a href=\"https://github.com/
|
|
1461
|
+
"description": "Use these settings to start creating HomeKit scenes with your Govee scenes, music mode and DIY modes. <a href=\"https://github.com/homebridge-plugins/homebridge-govee/wiki/Scene%2C-Music%2C-DIY-Modes\" target=\"_blank\">Read more →</a>",
|
|
1462
1462
|
"items": [
|
|
1463
1463
|
"lightDevices[].scene.sceneCode",
|
|
1464
1464
|
"lightDevices[].scene.bleCode",
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import {
|
|
2
|
+
base64ToHex,
|
|
3
|
+
getTwoItemPosition,
|
|
4
|
+
hexToTwoItems,
|
|
5
|
+
parseError,
|
|
6
|
+
} from '../utils/functions.js'
|
|
7
|
+
import platformLang from '../utils/lang-en.js'
|
|
8
|
+
|
|
9
|
+
export default class {
|
|
10
|
+
constructor(platform, accessory) {
|
|
11
|
+
// Set up variables from the platform
|
|
12
|
+
this.hapChar = platform.api.hap.Characteristic
|
|
13
|
+
this.hapErr = platform.api.hap.HapStatusError
|
|
14
|
+
this.hapServ = platform.api.hap.Service
|
|
15
|
+
this.platform = platform
|
|
16
|
+
|
|
17
|
+
// Set up variables from the accessory
|
|
18
|
+
this.accessory = accessory
|
|
19
|
+
|
|
20
|
+
// Rotation speed to value in {1, 2, ..., 8}
|
|
21
|
+
this.speed2Value = speed => Math.min(Math.max(Number.parseInt(Math.round(speed / 10), 10), 1), 8)
|
|
22
|
+
|
|
23
|
+
// Speed codes
|
|
24
|
+
this.value2Code = {
|
|
25
|
+
1: 'MwUBAQAAAAAAAAAAAAAAAAAAADY=',
|
|
26
|
+
2: 'MwUBAgAAAAAAAAAAAAAAAAAAADU=',
|
|
27
|
+
3: 'MwUBAwAAAAAAAAAAAAAAAAAAADQ=',
|
|
28
|
+
4: 'MwUBBAAAAAAAAAAAAAAAAAAAADM=',
|
|
29
|
+
5: 'MwUBBQAAAAAAAAAAAAAAAAAAADI=',
|
|
30
|
+
6: 'MwUBBgAAAAAAAAAAAAAAAAAAADE=',
|
|
31
|
+
7: 'MwUBBwAAAAAAAAAAAAAAAAAAADA=',
|
|
32
|
+
8: 'MwUBCAAAAAAAAAAAAAAAAAAAAD8=',
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Add the fan service if it doesn't already exist
|
|
36
|
+
this.service = this.accessory.getService(this.hapServ.Fan) || this.accessory.addService(this.hapServ.Fan)
|
|
37
|
+
|
|
38
|
+
// Add the set handler to the fan on/off characteristic
|
|
39
|
+
this.service
|
|
40
|
+
.getCharacteristic(this.hapChar.On)
|
|
41
|
+
.onSet(async value => this.internalStateUpdate(value))
|
|
42
|
+
this.cacheState = this.service.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
|
|
43
|
+
|
|
44
|
+
// Add the set handler to the fan rotation speed characteristic
|
|
45
|
+
this.service
|
|
46
|
+
.getCharacteristic(this.hapChar.RotationSpeed)
|
|
47
|
+
.setProps({
|
|
48
|
+
minStep: 10,
|
|
49
|
+
validValues: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
|
|
50
|
+
})
|
|
51
|
+
.onSet(async value => this.internalSpeedUpdate(value))
|
|
52
|
+
this.cacheSpeed = this.service.getCharacteristic(this.hapChar.RotationSpeed).value
|
|
53
|
+
|
|
54
|
+
// Output the customised options to the log
|
|
55
|
+
const opts = JSON.stringify({})
|
|
56
|
+
platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async internalStateUpdate(value) {
|
|
60
|
+
try {
|
|
61
|
+
const newValue = value ? 'on' : 'off'
|
|
62
|
+
|
|
63
|
+
// Don't continue if the new value is the same as before
|
|
64
|
+
if (this.cacheState === newValue) {
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Send the request to the platform sender function
|
|
69
|
+
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
70
|
+
cmd: 'stateHumi',
|
|
71
|
+
value: value ? 1 : 0,
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
// Cache the new state and log if appropriate
|
|
75
|
+
this.cacheState = newValue
|
|
76
|
+
this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
|
|
77
|
+
} catch (err) {
|
|
78
|
+
// Catch any errors during the process
|
|
79
|
+
this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
|
|
80
|
+
|
|
81
|
+
// Throw a 'no response' error and set a timeout to revert this after 2 seconds
|
|
82
|
+
setTimeout(() => {
|
|
83
|
+
this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
|
|
84
|
+
}, 2000)
|
|
85
|
+
throw new this.hapErr(-70402)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async internalSpeedUpdate(value) {
|
|
90
|
+
try {
|
|
91
|
+
// Don't continue if the speed is 0
|
|
92
|
+
if (value === 0) {
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Get the single Govee value {1, 2, ..., 8}
|
|
97
|
+
const newValue = this.speed2Value(value)
|
|
98
|
+
|
|
99
|
+
// Don't continue if the speed value won't have effect
|
|
100
|
+
if (newValue * 10 === this.cacheSpeed) {
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Get the scene code for this value
|
|
105
|
+
const newCode = this.value2Code[newValue]
|
|
106
|
+
|
|
107
|
+
// Send the request to the platform sender function
|
|
108
|
+
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
109
|
+
cmd: 'ptReal',
|
|
110
|
+
value: newCode,
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
// Cache the new state and log if appropriate
|
|
114
|
+
this.cacheSpeed = newValue * 10
|
|
115
|
+
this.accessory.log(`${platformLang.curSpeed} [${newValue}]`)
|
|
116
|
+
} catch (err) {
|
|
117
|
+
// Catch any errors during the process
|
|
118
|
+
this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
|
|
119
|
+
|
|
120
|
+
// Throw a 'no response' error and set a timeout to revert this after 2 seconds
|
|
121
|
+
setTimeout(() => {
|
|
122
|
+
this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
|
|
123
|
+
}, 2000)
|
|
124
|
+
throw new this.hapErr(-70402)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
externalUpdate(params) {
|
|
129
|
+
// Check for an ON/OFF change
|
|
130
|
+
if (params.state && params.state !== this.cacheState) {
|
|
131
|
+
this.cacheState = params.state
|
|
132
|
+
this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
|
|
133
|
+
|
|
134
|
+
// Log the change
|
|
135
|
+
this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Check for some other scene/mode change
|
|
139
|
+
(params.commands || []).forEach((command) => {
|
|
140
|
+
const hexString = base64ToHex(command)
|
|
141
|
+
const hexParts = hexToTwoItems(hexString)
|
|
142
|
+
|
|
143
|
+
// Return now if not a device query update code
|
|
144
|
+
if (getTwoItemPosition(hexParts, 1) !== 'aa') {
|
|
145
|
+
return
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const deviceFunction = `${getTwoItemPosition(hexParts, 1)}${getTwoItemPosition(hexParts, 2)}`
|
|
149
|
+
|
|
150
|
+
switch (deviceFunction) {
|
|
151
|
+
default:
|
|
152
|
+
this.accessory.logDebugWarn(`${platformLang.newScene}: [${command}] [${hexString}]`)
|
|
153
|
+
break
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
}
|
package/lib/device/index.js
CHANGED
|
@@ -9,20 +9,21 @@ import deviceFanH7102 from './fan-H7102.js'
|
|
|
9
9
|
import deviceFanH7105 from './fan-H7105.js'
|
|
10
10
|
import deviceFanH7106 from './fan-H7106.js'
|
|
11
11
|
import deviceFanH7111 from './fan-H7111.js'
|
|
12
|
-
import deviceHeaterSingle from './heater-single.js'
|
|
13
12
|
import deviceHeater1A from './heater1a.js'
|
|
14
13
|
import deviceHeater1B from './heater1b.js'
|
|
15
14
|
import deviceHeater2 from './heater2.js'
|
|
15
|
+
import deviceHeaterSingle from './heater-single.js'
|
|
16
16
|
import deviceHumidifierH7140 from './humidifier-H7140.js'
|
|
17
17
|
import deviceHumidifierH7141 from './humidifier-H7141.js'
|
|
18
18
|
import deviceHumidifierH7142 from './humidifier-H7142.js'
|
|
19
19
|
import deviceHumidifierH7143 from './humidifier-H7143.js'
|
|
20
|
+
import deviceHumidifierH7147 from './humidifier-H7147.js'
|
|
20
21
|
import deviceHumidifierH7148 from './humidifier-H7148.js'
|
|
21
22
|
import deviceHumidifierH7160 from './humidifier-H7160.js'
|
|
22
|
-
import
|
|
23
|
+
import deviceIceMakerH7172 from './ice-maker-H7172.js'
|
|
23
24
|
import deviceKettle from './kettle.js'
|
|
24
|
-
import deviceLight from './light.js'
|
|
25
25
|
import deviceLightSwitch from './light-switch.js'
|
|
26
|
+
import deviceLight from './light.js'
|
|
26
27
|
import deviceOutletDouble from './outlet-double.js'
|
|
27
28
|
import deviceOutletSingle from './outlet-single.js'
|
|
28
29
|
import deviceOutletTriple from './outlet-triple.js'
|
|
@@ -34,14 +35,15 @@ import devicePurifierH7123 from './purifier-H7123.js'
|
|
|
34
35
|
import devicePurifierH7124 from './purifier-H7124.js'
|
|
35
36
|
import devicePurifierH7126 from './purifier-H7126.js'
|
|
36
37
|
import devicePurifierH7127 from './purifier-H7127.js'
|
|
38
|
+
import devicePurifierH7129 from './purifier-H7129.js'
|
|
37
39
|
import devicePurifierSingle from './purifier-single.js'
|
|
38
40
|
import deviceSensorButton from './sensor-button.js'
|
|
39
41
|
import deviceSensorContact from './sensor-contact.js'
|
|
40
42
|
import deviceSensorLeak from './sensor-leak.js'
|
|
41
43
|
import deviceSensorMonitor from './sensor-monitor.js'
|
|
42
44
|
import deviceSensorPresence from './sensor-presence.js'
|
|
43
|
-
import deviceSensorThermo from './sensor-thermo.js'
|
|
44
45
|
import deviceSensorThermo4 from './sensor-thermo4.js'
|
|
46
|
+
import deviceSensorThermo from './sensor-thermo.js'
|
|
45
47
|
import deviceSwitchDouble from './switch-double.js'
|
|
46
48
|
import deviceSwitchSingle from './switch-single.js'
|
|
47
49
|
import deviceSwitchTriple from './switch-triple.js'
|
|
@@ -70,9 +72,10 @@ export default {
|
|
|
70
72
|
deviceHumidifierH7141,
|
|
71
73
|
deviceHumidifierH7142,
|
|
72
74
|
deviceHumidifierH7143,
|
|
75
|
+
deviceHumidifierH7147,
|
|
73
76
|
deviceHumidifierH7148,
|
|
74
77
|
deviceHumidifierH7160,
|
|
75
|
-
|
|
78
|
+
deviceIceMakerH7172,
|
|
76
79
|
deviceKettle,
|
|
77
80
|
deviceLight,
|
|
78
81
|
deviceLightSwitch,
|
|
@@ -87,6 +90,7 @@ export default {
|
|
|
87
90
|
devicePurifierH7124,
|
|
88
91
|
devicePurifierH7126,
|
|
89
92
|
devicePurifierH7127,
|
|
93
|
+
devicePurifierH7129,
|
|
90
94
|
devicePurifierSingle,
|
|
91
95
|
deviceSensorButton,
|
|
92
96
|
deviceSensorContact,
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import {
|
|
2
|
+
base64ToHex,
|
|
3
|
+
getTwoItemPosition,
|
|
4
|
+
hexToTwoItems,
|
|
5
|
+
parseError,
|
|
6
|
+
} from '../utils/functions.js'
|
|
7
|
+
import platformLang from '../utils/lang-en.js'
|
|
8
|
+
|
|
9
|
+
export default class {
|
|
10
|
+
constructor(platform, accessory) {
|
|
11
|
+
// Set up variables from the platform
|
|
12
|
+
this.cusChar = platform.cusChar
|
|
13
|
+
this.hapChar = platform.api.hap.Characteristic
|
|
14
|
+
this.hapErr = platform.api.hap.HapStatusError
|
|
15
|
+
this.hapServ = platform.api.hap.Service
|
|
16
|
+
this.platform = platform
|
|
17
|
+
|
|
18
|
+
// Set up variables from the accessory
|
|
19
|
+
this.accessory = accessory
|
|
20
|
+
|
|
21
|
+
// Rotation speed to value in {1, 2, 3}
|
|
22
|
+
this.speed2Value = speed => Math.min(Math.max(Number.parseInt(speed / 33, 10), 1), 3)
|
|
23
|
+
|
|
24
|
+
// Speed codes
|
|
25
|
+
this.value2Code = {
|
|
26
|
+
1: 'MwUBAQAAAAAAAAAAAAAAAAAAADY=', // sleep
|
|
27
|
+
2: 'MwUBAgAAAAAAAAAAAAAAAAAAADU=', // low
|
|
28
|
+
3: 'MwUBAwAAAAAAAAAAAAAAAAAAADQ=', // high
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Lock codes
|
|
32
|
+
this.lock2Code = {
|
|
33
|
+
on: 'MxABAAAAAAAAAAAAAAAAAAAAACI=',
|
|
34
|
+
off: 'MxAAAAAAAAAAAAAAAAAAAAAAACM=',
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Display codes
|
|
38
|
+
this.display2Code = {
|
|
39
|
+
on: 'MxYBAAAAAAAAAAAAAAAAAAAAACQ=',
|
|
40
|
+
off: 'MxYAAAAAAAAAAAAAAAAAAAAAACU=',
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Add the purifier service if it doesn't already exist
|
|
44
|
+
this.service = this.accessory.getService(this.hapServ.AirPurifier)
|
|
45
|
+
|| this.accessory.addService(this.hapServ.AirPurifier)
|
|
46
|
+
|
|
47
|
+
// Add the set handler to the switch on/off characteristic
|
|
48
|
+
this.service.getCharacteristic(this.hapChar.Active).onSet(async (value) => {
|
|
49
|
+
await this.internalStateUpdate(value)
|
|
50
|
+
})
|
|
51
|
+
this.cacheState = this.service.getCharacteristic(this.hapChar.Active).value === 1 ? 'on' : 'off'
|
|
52
|
+
|
|
53
|
+
// Add options to the purifier target state characteristic
|
|
54
|
+
this.service
|
|
55
|
+
.getCharacteristic(this.hapChar.TargetAirPurifierState)
|
|
56
|
+
.updateValue(1)
|
|
57
|
+
// .setProps({
|
|
58
|
+
// minValue: 1,
|
|
59
|
+
// maxValue: 1,
|
|
60
|
+
// validValues: [1],
|
|
61
|
+
// })
|
|
62
|
+
|
|
63
|
+
// Add the set handler to the fan rotation speed characteristic
|
|
64
|
+
this.service
|
|
65
|
+
.getCharacteristic(this.hapChar.RotationSpeed)
|
|
66
|
+
.setProps({
|
|
67
|
+
minStep: 25,
|
|
68
|
+
validValues: [0, 33, 66, 99],
|
|
69
|
+
})
|
|
70
|
+
.onSet(async value => this.internalSpeedUpdate(value))
|
|
71
|
+
this.cacheSpeed = this.service.getCharacteristic(this.hapChar.RotationSpeed).value
|
|
72
|
+
|
|
73
|
+
// Add the set handler to the lock controls characteristic
|
|
74
|
+
this.service.getCharacteristic(this.hapChar.LockPhysicalControls).onSet(async (value) => {
|
|
75
|
+
await this.internalLockUpdate(value)
|
|
76
|
+
})
|
|
77
|
+
this.cacheLock = this.service.getCharacteristic(this.hapChar.LockPhysicalControls).value === 1 ? 'on' : 'off'
|
|
78
|
+
|
|
79
|
+
// Add display light Eve characteristic if it doesn't exist already
|
|
80
|
+
if (!this.service.testCharacteristic(this.cusChar.DisplayLight)) {
|
|
81
|
+
this.service.addCharacteristic(this.cusChar.DisplayLight)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Add the set handler to the custom display light characteristic
|
|
85
|
+
this.service.getCharacteristic(this.cusChar.DisplayLight).onSet(async (value) => {
|
|
86
|
+
await this.internalDisplayLightUpdate(value)
|
|
87
|
+
})
|
|
88
|
+
this.cacheDisplay = this.service.getCharacteristic(this.cusChar.DisplayLight).value
|
|
89
|
+
? 'on'
|
|
90
|
+
: 'off'
|
|
91
|
+
|
|
92
|
+
// Output the customised options to the log
|
|
93
|
+
const opts = JSON.stringify({})
|
|
94
|
+
platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async internalStateUpdate(value) {
|
|
98
|
+
try {
|
|
99
|
+
const newValue = value === 1 ? 'on' : 'off'
|
|
100
|
+
|
|
101
|
+
// Don't continue if the new value is the same as before
|
|
102
|
+
if (this.cacheState === newValue) {
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Send the request to the platform sender function
|
|
107
|
+
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
108
|
+
cmd: 'statePuri',
|
|
109
|
+
value: value ? 1 : 0,
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
// Update the current state characteristic
|
|
113
|
+
this.service.updateCharacteristic(this.hapChar.CurrentAirPurifierState, value === 1 ? 2 : 0)
|
|
114
|
+
|
|
115
|
+
// Cache the new state and log if appropriate
|
|
116
|
+
this.cacheState = newValue
|
|
117
|
+
this.accessory.log(`${platformLang.curState} [${newValue}]`)
|
|
118
|
+
} catch (err) {
|
|
119
|
+
// Catch any errors during the process
|
|
120
|
+
this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
|
|
121
|
+
|
|
122
|
+
// Throw a 'no response' error and set a timeout to revert this after 2 seconds
|
|
123
|
+
setTimeout(() => {
|
|
124
|
+
this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
|
|
125
|
+
}, 2000)
|
|
126
|
+
throw new this.hapErr(-70402)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async internalSpeedUpdate(value) {
|
|
131
|
+
try {
|
|
132
|
+
// Don't continue if the speed is 0
|
|
133
|
+
if (value === 0) {
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Get the single Govee value {1, 2, ..., 8}
|
|
138
|
+
const newValue = this.speed2Value(value)
|
|
139
|
+
|
|
140
|
+
// Don't continue if the speed value won't have effect
|
|
141
|
+
if (newValue * 33 === this.cacheSpeed) {
|
|
142
|
+
return
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Get the scene code for this value
|
|
146
|
+
const newCode = this.value2Code[newValue]
|
|
147
|
+
|
|
148
|
+
// Send the request to the platform sender function
|
|
149
|
+
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
150
|
+
cmd: 'ptReal',
|
|
151
|
+
value: newCode,
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
// Cache the new state and log if appropriate
|
|
155
|
+
this.cacheSpeed = newValue * 33
|
|
156
|
+
this.accessory.log(`${platformLang.curSpeed} [${this.cacheSpeed}%]`)
|
|
157
|
+
} catch (err) {
|
|
158
|
+
// Catch any errors during the process
|
|
159
|
+
this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
|
|
160
|
+
|
|
161
|
+
// Throw a 'no response' error and set a timeout to revert this after 2 seconds
|
|
162
|
+
setTimeout(() => {
|
|
163
|
+
this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
|
|
164
|
+
}, 2000)
|
|
165
|
+
throw new this.hapErr(-70402)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async internalLockUpdate(value) {
|
|
170
|
+
try {
|
|
171
|
+
const newValue = value === 1 ? 'on' : 'off'
|
|
172
|
+
|
|
173
|
+
// Don't continue if the new value is the same as before
|
|
174
|
+
if (this.cacheLock === newValue) {
|
|
175
|
+
return
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Send the request to the platform sender function
|
|
179
|
+
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
180
|
+
cmd: 'ptReal',
|
|
181
|
+
value: this.lock2Code[newValue],
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
// Cache the new state and log if appropriate
|
|
185
|
+
this.cacheLock = newValue
|
|
186
|
+
this.accessory.log(`${platformLang.curLock} [${newValue}]`)
|
|
187
|
+
} catch (err) {
|
|
188
|
+
// Catch any errors during the process
|
|
189
|
+
this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
|
|
190
|
+
|
|
191
|
+
// Throw a 'no response' error and set a timeout to revert this after 2 seconds
|
|
192
|
+
setTimeout(() => {
|
|
193
|
+
this.service.updateCharacteristic(
|
|
194
|
+
this.hapChar.LockPhysicalControls,
|
|
195
|
+
this.cacheLock === 'on' ? 1 : 0,
|
|
196
|
+
)
|
|
197
|
+
}, 2000)
|
|
198
|
+
throw new this.hapErr(-70402)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async internalDisplayLightUpdate(value) {
|
|
203
|
+
try {
|
|
204
|
+
const newValue = value ? 'on' : 'off'
|
|
205
|
+
|
|
206
|
+
// Don't continue if the new value is the same as before
|
|
207
|
+
if (this.cacheDisplay === newValue) {
|
|
208
|
+
return
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Send the request to the platform sender function
|
|
212
|
+
await this.platform.sendDeviceUpdate(this.accessory, {
|
|
213
|
+
cmd: 'ptReal',
|
|
214
|
+
value: this.display2Code[newValue],
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
// Cache the new state and log if appropriate
|
|
218
|
+
this.cacheDisplay = newValue
|
|
219
|
+
this.accessory.log(`${platformLang.curDisplay} [${newValue}]`)
|
|
220
|
+
} catch (err) {
|
|
221
|
+
// Catch any errors during the process
|
|
222
|
+
this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
|
|
223
|
+
|
|
224
|
+
// Throw a 'no response' error and set a timeout to revert this after 2 seconds
|
|
225
|
+
setTimeout(() => {
|
|
226
|
+
this.service.updateCharacteristic(this.cusChar.DisplayLight, this.cacheLight === 'on')
|
|
227
|
+
}, 2000)
|
|
228
|
+
throw new this.hapErr(-70402)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
externalUpdate(params) {
|
|
233
|
+
// Check for an ON/OFF change
|
|
234
|
+
if (params.state && params.state !== this.cacheState) {
|
|
235
|
+
this.cacheState = params.state
|
|
236
|
+
this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on')
|
|
237
|
+
this.service.updateCharacteristic(this.hapChar.CurrentAirPurifierState, this.cacheState === 'on' ? 2 : 0)
|
|
238
|
+
|
|
239
|
+
// Log the change
|
|
240
|
+
this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Check for some other scene/mode change
|
|
244
|
+
(params.commands || []).forEach((command) => {
|
|
245
|
+
const hexString = base64ToHex(command)
|
|
246
|
+
const hexParts = hexToTwoItems(hexString)
|
|
247
|
+
|
|
248
|
+
// Return now if not a device query update code
|
|
249
|
+
if (getTwoItemPosition(hexParts, 1) !== 'aa') {
|
|
250
|
+
return
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const deviceFunction = `${getTwoItemPosition(hexParts, 2)}${getTwoItemPosition(hexParts, 3)}`
|
|
254
|
+
|
|
255
|
+
switch (deviceFunction) {
|
|
256
|
+
case '0501': {
|
|
257
|
+
// Manual speed
|
|
258
|
+
const newSpeedRaw = getTwoItemPosition(hexParts, 4)
|
|
259
|
+
if (newSpeedRaw !== this.cacheSpeedRaw) {
|
|
260
|
+
this.cacheSpeedRaw = newSpeedRaw
|
|
261
|
+
this.cacheSpeed = Number.parseInt(newSpeedRaw, 10) * 10
|
|
262
|
+
this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
|
|
263
|
+
this.accessory.log(`${platformLang.curSpeed} [${this.cacheSpeed}]`)
|
|
264
|
+
}
|
|
265
|
+
break
|
|
266
|
+
}
|
|
267
|
+
case 'aa10': { // lock
|
|
268
|
+
const newLock = getTwoItemPosition(hexParts, 3) === '01' ? 'on' : 'off'
|
|
269
|
+
if (newLock !== this.cacheLock) {
|
|
270
|
+
this.cacheLock = newLock
|
|
271
|
+
this.service.updateCharacteristic(this.hapChar.LockPhysicalControls, this.cacheLock === 'on' ? 1 : 0)
|
|
272
|
+
this.accessory.log(`${platformLang.curLock} [${this.cacheLock}]`)
|
|
273
|
+
}
|
|
274
|
+
break
|
|
275
|
+
}
|
|
276
|
+
case 'aa16': { // display light
|
|
277
|
+
const newDisplay = getTwoItemPosition(hexParts, 3) === '01' ? 'on' : 'off'
|
|
278
|
+
if (newDisplay === 'on') {
|
|
279
|
+
this.accessory.context.cacheDisplayCode = hexString
|
|
280
|
+
}
|
|
281
|
+
if (newDisplay !== this.cacheDisplay) {
|
|
282
|
+
this.cacheDisplay = newDisplay
|
|
283
|
+
this.service.updateCharacteristic(this.cusChar.DisplayLight, this.cacheDisplay === 'on')
|
|
284
|
+
|
|
285
|
+
// Log the change
|
|
286
|
+
this.accessory.log(`${platformLang.curDisplay} [${this.cacheDisplay}]`)
|
|
287
|
+
}
|
|
288
|
+
break
|
|
289
|
+
}
|
|
290
|
+
default:
|
|
291
|
+
this.accessory.logDebugWarn(`${platformLang.newScene}: [${command}] [${hexString}]`)
|
|
292
|
+
break
|
|
293
|
+
}
|
|
294
|
+
})
|
|
295
|
+
}
|
|
296
|
+
}
|
|
@@ -119,12 +119,12 @@
|
|
|
119
119
|
<h4>Setup</h4>
|
|
120
120
|
<ul>
|
|
121
121
|
<li>
|
|
122
|
-
<a href="https://github.com/
|
|
122
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Installation" target="_blank"
|
|
123
123
|
>Installation</a
|
|
124
124
|
>
|
|
125
125
|
</li>
|
|
126
126
|
<li>
|
|
127
|
-
<a href="https://github.com/
|
|
127
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Configuration" target="_blank"
|
|
128
128
|
>Configuration</a
|
|
129
129
|
>
|
|
130
130
|
</li>
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
>
|
|
135
135
|
</li>
|
|
136
136
|
<li>
|
|
137
|
-
<a href="https://github.com/
|
|
137
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Node-Version" target="_blank"
|
|
138
138
|
>Node Version</a
|
|
139
139
|
>
|
|
140
140
|
</li>
|
|
@@ -142,39 +142,39 @@
|
|
|
142
142
|
<h4>Features</h4>
|
|
143
143
|
<ul>
|
|
144
144
|
<li>
|
|
145
|
-
<a href="https://github.com/
|
|
145
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Supported-Devices" target="_blank"
|
|
146
146
|
>Supported Devices</a
|
|
147
147
|
>
|
|
148
148
|
</li>
|
|
149
149
|
<li>
|
|
150
|
-
<a href="https://github.com/
|
|
150
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Connection-Methods" target="_blank"
|
|
151
151
|
>Connection Methods</a
|
|
152
152
|
>
|
|
153
153
|
</li>
|
|
154
154
|
<ul>
|
|
155
155
|
<li>
|
|
156
|
-
<a href="https://github.com/
|
|
156
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/LAN-Control" target="_blank"
|
|
157
157
|
>LAN Control</a
|
|
158
158
|
>
|
|
159
159
|
</li>
|
|
160
160
|
<li>
|
|
161
|
-
<a href="https://github.com/
|
|
161
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/API-Control" target="_blank"
|
|
162
162
|
>API Control</a
|
|
163
163
|
>
|
|
164
164
|
</li>
|
|
165
165
|
<li>
|
|
166
|
-
<a href="https://github.com/
|
|
166
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/AWS-Control" target="_blank"
|
|
167
167
|
>AWS Control</a
|
|
168
168
|
>
|
|
169
169
|
</li>
|
|
170
170
|
<li>
|
|
171
|
-
<a href="https://github.com/
|
|
171
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Bluetooth-Control" target="_blank"
|
|
172
172
|
>BLE Control</a
|
|
173
173
|
>
|
|
174
174
|
</li>
|
|
175
175
|
</ul>
|
|
176
176
|
<li>
|
|
177
|
-
<a href="https://github.com/
|
|
177
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Scene%2C-Music%2C-DIY-Modes" target="_blank"
|
|
178
178
|
>Scene, Music, DIY Modes</a
|
|
179
179
|
>
|
|
180
180
|
</li>
|
|
@@ -182,17 +182,17 @@
|
|
|
182
182
|
<h4>Help/About</h4>
|
|
183
183
|
<ul>
|
|
184
184
|
<li>
|
|
185
|
-
<a href="https://github.com/
|
|
185
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Common-Errors" target="_blank"
|
|
186
186
|
>Common Errors</a
|
|
187
187
|
>
|
|
188
188
|
</li>
|
|
189
189
|
<li>
|
|
190
|
-
<a href="https://github.com/
|
|
190
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/issues/new/choose" target="_blank"
|
|
191
191
|
>Support Request</a
|
|
192
192
|
>
|
|
193
193
|
</li>
|
|
194
194
|
<li>
|
|
195
|
-
<a href="https://github.com/
|
|
195
|
+
<a href="https://github.com/homebridge-plugins/homebridge-govee/blob/latest/CHANGELOG.md" target="_blank"
|
|
196
196
|
>Changelog</a
|
|
197
197
|
>
|
|
198
198
|
</li>
|
|
@@ -254,6 +254,7 @@
|
|
|
254
254
|
const introContinue = document.getElementById('introContinue')
|
|
255
255
|
introContinue.addEventListener('click', () => {
|
|
256
256
|
homebridge.showSpinner()
|
|
257
|
+
homebridge.disableSaveButton()
|
|
257
258
|
document.getElementById('pageIntro').style.display = 'none'
|
|
258
259
|
document.getElementById('menuWrapper').style.display = 'inline-flex'
|
|
259
260
|
showSettings()
|
|
@@ -263,6 +264,7 @@
|
|
|
263
264
|
}
|
|
264
265
|
showDevices = async () => {
|
|
265
266
|
homebridge.showSpinner()
|
|
267
|
+
homebridge.disableSaveButton()
|
|
266
268
|
homebridge.hideSchemaForm()
|
|
267
269
|
document.getElementById('menuHome').classList.remove('btn-elegant')
|
|
268
270
|
document.getElementById('menuHome').classList.add('btn-primary')
|
|
@@ -389,6 +391,7 @@
|
|
|
389
391
|
}
|
|
390
392
|
showSupport = () => {
|
|
391
393
|
homebridge.showSpinner()
|
|
394
|
+
homebridge.disableSaveButton()
|
|
392
395
|
homebridge.hideSchemaForm()
|
|
393
396
|
document.getElementById('menuHome').classList.add('btn-elegant')
|
|
394
397
|
document.getElementById('menuHome').classList.remove('btn-primary')
|
|
@@ -402,6 +405,7 @@
|
|
|
402
405
|
}
|
|
403
406
|
showSettings = () => {
|
|
404
407
|
homebridge.showSpinner()
|
|
408
|
+
homebridge.enableSaveButton()
|
|
405
409
|
document.getElementById('menuHome').classList.remove('btn-elegant')
|
|
406
410
|
document.getElementById('menuHome').classList.add('btn-primary')
|
|
407
411
|
document.getElementById('menuDevices').classList.remove('btn-elegant')
|
package/lib/platform.js
CHANGED
|
@@ -578,7 +578,9 @@ export default class {
|
|
|
578
578
|
// Format device id
|
|
579
579
|
if (!httpDevice.device.includes(':')) {
|
|
580
580
|
// Eg converts abcd1234abcd1234 to AB:CD:12:34:AB:CD:12:34
|
|
581
|
-
|
|
581
|
+
// For sensors with an add on sensor like H5178
|
|
582
|
+
// Eg converts abcd1234abcd1234_1 to AB:CD:12:34:AB:CD:12:34_1
|
|
583
|
+
httpDevice.device = httpDevice.device.replace(/([a-z0-9]{2})(?=[a-z0-9])/gi, '$&:').toUpperCase()
|
|
582
584
|
}
|
|
583
585
|
|
|
584
586
|
// Check it's not a user-ignored device
|
|
@@ -1239,7 +1241,9 @@ export default class {
|
|
|
1239
1241
|
// Reformat the device id
|
|
1240
1242
|
if (!device.device.includes(':')) {
|
|
1241
1243
|
// Eg converts abcd1234abcd1234 to AB:CD:12:34:AB:CD:12:34
|
|
1242
|
-
|
|
1244
|
+
// For sensors with an add on sensor like H5178
|
|
1245
|
+
// Eg converts abcd1234abcd1234_1 to AB:CD:12:34:AB:CD:12:34_1
|
|
1246
|
+
device.device = device.device.replace(/([a-z0-9]{2})(?=[a-z0-9])/gi, '$&:').toUpperCase()
|
|
1243
1247
|
}
|
|
1244
1248
|
|
|
1245
1249
|
// Generate the UIID from which we can match our Homebridge accessory
|
package/lib/utils/constants.js
CHANGED
|
@@ -138,6 +138,8 @@ export default {
|
|
|
138
138
|
'H601B',
|
|
139
139
|
'H601C',
|
|
140
140
|
'H601D',
|
|
141
|
+
'H6022',
|
|
142
|
+
'H6039',
|
|
141
143
|
'H6042',
|
|
142
144
|
'H6043',
|
|
143
145
|
'H6046',
|
|
@@ -203,6 +205,10 @@ export default {
|
|
|
203
205
|
'H611C',
|
|
204
206
|
'H611Z',
|
|
205
207
|
'H6121',
|
|
208
|
+
'H612B',
|
|
209
|
+
'H612C',
|
|
210
|
+
'H612D',
|
|
211
|
+
'H612F',
|
|
206
212
|
'H6135',
|
|
207
213
|
'H6137',
|
|
208
214
|
'H6141',
|
|
@@ -227,6 +233,7 @@ export default {
|
|
|
227
233
|
'H6163',
|
|
228
234
|
'H6167',
|
|
229
235
|
'H6168',
|
|
236
|
+
'H6169',
|
|
230
237
|
'H616C',
|
|
231
238
|
'H616D',
|
|
232
239
|
'H616E',
|
|
@@ -272,13 +279,18 @@ export default {
|
|
|
272
279
|
'H61E0',
|
|
273
280
|
'H61E1',
|
|
274
281
|
'H61E5',
|
|
282
|
+
'H61E6',
|
|
275
283
|
'H61F5',
|
|
276
284
|
'H6601',
|
|
277
285
|
'H6602',
|
|
286
|
+
'H6604',
|
|
278
287
|
'H6609',
|
|
279
288
|
'H6640',
|
|
280
289
|
'H6641',
|
|
290
|
+
'H6800',
|
|
291
|
+
'H6810',
|
|
281
292
|
'H6811',
|
|
293
|
+
'H6840',
|
|
282
294
|
'H7005',
|
|
283
295
|
'H7006',
|
|
284
296
|
'H7007',
|
|
@@ -303,6 +315,7 @@ export default {
|
|
|
303
315
|
'H7052',
|
|
304
316
|
'H7053',
|
|
305
317
|
'H7055',
|
|
318
|
+
'H7057',
|
|
306
319
|
'H705A',
|
|
307
320
|
'H705B',
|
|
308
321
|
'H705C',
|
|
@@ -315,6 +328,8 @@ export default {
|
|
|
315
328
|
'H7063',
|
|
316
329
|
'H7065',
|
|
317
330
|
'H7066',
|
|
331
|
+
'H7067',
|
|
332
|
+
'H7069',
|
|
318
333
|
'H706A',
|
|
319
334
|
'H706B',
|
|
320
335
|
'H706C',
|
|
@@ -328,13 +343,17 @@ export default {
|
|
|
328
343
|
'H70BC',
|
|
329
344
|
'H70C1',
|
|
330
345
|
'H70C2',
|
|
346
|
+
'H70C4',
|
|
331
347
|
'H70C5',
|
|
348
|
+
'H70C7',
|
|
332
349
|
'H70D1',
|
|
350
|
+
'H8072',
|
|
333
351
|
'H801B',
|
|
334
352
|
'H801C',
|
|
335
353
|
'H805A',
|
|
336
354
|
'H805B',
|
|
337
355
|
'H805C',
|
|
356
|
+
'H80C4',
|
|
338
357
|
'HXXXX', // placeholder for LAN-only configured models
|
|
339
358
|
],
|
|
340
359
|
rgbBT: [
|
|
@@ -419,8 +438,8 @@ export default {
|
|
|
419
438
|
heater1: ['H7130', 'H713A', 'H713B', 'H713C'],
|
|
420
439
|
heater2: ['H7131', 'H7132', 'H7133', 'H7134', 'H7135'],
|
|
421
440
|
dehumidifier: ['H7150', 'H7151'],
|
|
422
|
-
humidifier: ['H7140', 'H7141', 'H7142', 'H7143', 'H7148', 'H7160'],
|
|
423
|
-
purifier: ['H7120', 'H7121', 'H7122', 'H7123', 'H7124', 'H7126', 'H7127', 'H712C'],
|
|
441
|
+
humidifier: ['H7140', 'H7141', 'H7142', 'H7143', 'H7147', 'H7148', 'H7160'],
|
|
442
|
+
purifier: ['H7120', 'H7121', 'H7122', 'H7123', 'H7124', 'H7126', 'H7127', 'H7129', 'H712C'],
|
|
424
443
|
diffuser: ['H7161', 'H7162'],
|
|
425
444
|
iceMaker: ['H7172'],
|
|
426
445
|
sensorButton: ['H5122'],
|
|
@@ -428,15 +447,17 @@ export default {
|
|
|
428
447
|
sensorPresence: ['H5127'],
|
|
429
448
|
kettle: ['H7170', 'H7171', 'H7173', 'H7175'],
|
|
430
449
|
template: [
|
|
431
|
-
'H1162', // https://github.com/
|
|
432
|
-
'H5024', // https://github.com/
|
|
433
|
-
'H5042', // https://github.com/
|
|
434
|
-
'H5043', // https://github.com/
|
|
435
|
-
'
|
|
436
|
-
'
|
|
437
|
-
'
|
|
438
|
-
'
|
|
439
|
-
'
|
|
450
|
+
'H1162', // https://github.com/homebridge-plugins/homebridge-govee/issues/422
|
|
451
|
+
'H5024', // https://github.com/homebridge-plugins/homebridge-govee/issues/835
|
|
452
|
+
'H5042', // https://github.com/homebridge-plugins/homebridge-govee/issues/849
|
|
453
|
+
'H5043', // https://github.com/homebridge-plugins/homebridge-govee/issues/558
|
|
454
|
+
'H5085', // https://github.com/homebridge-plugins/homebridge-govee/issues/951
|
|
455
|
+
'H5121', // https://github.com/homebridge-plugins/homebridge-govee/issues/913
|
|
456
|
+
'H5126', // https://github.com/homebridge-plugins/homebridge-govee/issues/910
|
|
457
|
+
'H5107', // https://github.com/homebridge-plugins/homebridge-govee/issues/803
|
|
458
|
+
'H5109', // https://github.com/homebridge-plugins/homebridge-govee/issues/823
|
|
459
|
+
'H5125', // https://github.com/homebridge-plugins/homebridge-govee/issues/981
|
|
460
|
+
'H5185', // https://github.com/homebridge-plugins/homebridge-govee/issues/804
|
|
440
461
|
],
|
|
441
462
|
},
|
|
442
463
|
|
|
@@ -449,7 +470,7 @@ export default {
|
|
|
449
470
|
'H6052', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
450
471
|
'H6056', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
451
472
|
'H6059', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
452
|
-
'H605A', // !NOT CONFIRMED! https://github.com/
|
|
473
|
+
'H605A', // !NOT CONFIRMED! https://github.com/homebridge-plugins/homebridge-govee/issues/827
|
|
453
474
|
'H6061', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
454
475
|
'H6062', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
455
476
|
'H6063', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
@@ -461,7 +482,7 @@ export default {
|
|
|
461
482
|
'H6073', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
462
483
|
'H6076', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
463
484
|
'H6078', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
464
|
-
'H6079', // https://github.com/
|
|
485
|
+
'H6079', // https://github.com/homebridge-plugins/homebridge-govee/issues/775
|
|
465
486
|
'H607C', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
466
487
|
'H6087', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
467
488
|
'H6088', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
@@ -470,7 +491,7 @@ export default {
|
|
|
470
491
|
'H608C', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
471
492
|
'H608D', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
472
493
|
'H60A0', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
473
|
-
'H60A1', // !NOT CONFIRMED! https://github.com/
|
|
494
|
+
'H60A1', // !NOT CONFIRMED! https://github.com/homebridge-plugins/homebridge-govee/issues/783
|
|
474
495
|
'H610A', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
475
496
|
'H610B', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
476
497
|
'H6110', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
@@ -484,7 +505,7 @@ export default {
|
|
|
484
505
|
'H615C', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
485
506
|
'H615D', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
486
507
|
'H615E', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
487
|
-
'H615F', // https://github.com/
|
|
508
|
+
'H615F', // https://github.com/homebridge-plugins/homebridge-govee/issues/904
|
|
488
509
|
'H6163', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
489
510
|
'H6167', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
490
511
|
'H6168', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
@@ -521,17 +542,17 @@ export default {
|
|
|
521
542
|
'H61C2', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
522
543
|
'H61C3', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
523
544
|
'H61C5', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
524
|
-
'H61D3', // !NOT CONFIRMED! https://github.com/
|
|
545
|
+
'H61D3', // !NOT CONFIRMED! https://github.com/homebridge-plugins/homebridge-govee/issues/757
|
|
525
546
|
'H61E0', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
526
547
|
'H61E1', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
527
|
-
'H6641', // !NOT CONFIRMED! https://github.com/
|
|
548
|
+
'H6641', // !NOT CONFIRMED! https://github.com/homebridge-plugins/homebridge-govee/issues/825
|
|
528
549
|
'H7012', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
529
550
|
'H7013', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
530
551
|
'H7021', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
531
552
|
'H7028', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
532
553
|
'H7033', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
533
|
-
'H7038', // !NOT CONFIRMED! https://github.com/
|
|
534
|
-
'H7039', // !NOT CONFIRMED! https://github.com/
|
|
554
|
+
'H7038', // !NOT CONFIRMED! https://github.com/homebridge-plugins/homebridge-govee/issues/795
|
|
555
|
+
'H7039', // !NOT CONFIRMED! https://github.com/homebridge-plugins/homebridge-govee/issues/771
|
|
535
556
|
'H7041', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
536
557
|
'H7042', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
537
558
|
'H7050', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
@@ -555,14 +576,16 @@ export default {
|
|
|
555
576
|
'H706B', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
556
577
|
'H706C', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
557
578
|
'H7075', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
558
|
-
'H70A2', // !NOT CONFIRMED! https://github.com/
|
|
579
|
+
'H70A2', // !NOT CONFIRMED! https://github.com/homebridge-plugins/homebridge-govee/issues/818
|
|
559
580
|
'H70B1', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
560
581
|
'H70BC', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
561
582
|
'H70C1', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
562
583
|
'H70C2', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
584
|
+
'H8072', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
563
585
|
'H805A', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
564
586
|
'H805B', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
565
587
|
'H805C', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
588
|
+
'H80C4', // https://app-h5.govee.com/user-manual/wlan-guide (2024-10-15)
|
|
566
589
|
],
|
|
567
590
|
|
|
568
591
|
awsOutlet1617: ['H5080', 'H5083'],
|
package/lib/utils/functions.js
CHANGED
package/lib/utils/lang-en.js
CHANGED
|
@@ -112,7 +112,7 @@ export default {
|
|
|
112
112
|
notAWSSent: 'not using AWS connection as',
|
|
113
113
|
notBLESent: 'not using BLE connection as',
|
|
114
114
|
notLANSent: 'not using LAN connection as',
|
|
115
|
-
noOpenssl: 'See https://github.com/
|
|
115
|
+
noOpenssl: 'See https://github.com/homebridge-plugins/homebridge-govee/wiki/OpenSSL for more info about installing OpenSSL',
|
|
116
116
|
noToken: 'no data received from Govee server whilst obtaining token',
|
|
117
117
|
noTokenExists: 'no account token has been retrieved',
|
|
118
118
|
offlineBTConn: 'has been reported [disconnected] via BLE',
|
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": "10.
|
|
5
|
+
"version": "10.13.0",
|
|
6
6
|
"description": "Homebridge plugin to integrate Govee devices into HomeKit.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "bwp91",
|
|
@@ -27,13 +27,13 @@
|
|
|
27
27
|
"url": "https://www.paypal.me/BenPotter"
|
|
28
28
|
}
|
|
29
29
|
],
|
|
30
|
-
"homepage": "https://github.com/
|
|
30
|
+
"homepage": "https://github.com/homebridge-plugins/homebridge-govee",
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
|
33
|
-
"url": "git+https://github.com/
|
|
33
|
+
"url": "git+https://github.com/homebridge-plugins/homebridge-govee.git"
|
|
34
34
|
},
|
|
35
35
|
"bugs": {
|
|
36
|
-
"url": "https://github.com/
|
|
36
|
+
"url": "https://github.com/homebridge-plugins/homebridge-govee/issues"
|
|
37
37
|
},
|
|
38
38
|
"keywords": [
|
|
39
39
|
"homebridge",
|
|
@@ -48,16 +48,16 @@
|
|
|
48
48
|
"main": "lib/index.js",
|
|
49
49
|
"engines": {
|
|
50
50
|
"homebridge": "^1.6.0 || ^2.0.0-beta.0",
|
|
51
|
-
"node": "^18.20.
|
|
51
|
+
"node": "^18.20.5 || ^20.18.1 || ^22.12.0"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"lint": "eslint . --fix",
|
|
55
55
|
"rebuild": "rm -rf package-lock.json && rm -rf node_modules && npm install"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@homebridge/plugin-ui-utils": "^
|
|
58
|
+
"@homebridge/plugin-ui-utils": "^2.0.0",
|
|
59
59
|
"aws-iot-device-sdk": "^2.2.15",
|
|
60
|
-
"axios": "^1.7.
|
|
60
|
+
"axios": "^1.7.9",
|
|
61
61
|
"node-persist": "^4.0.3",
|
|
62
62
|
"node-rsa": "^1.1.1",
|
|
63
63
|
"p-queue": "^8.0.1",
|
|
@@ -69,7 +69,6 @@
|
|
|
69
69
|
"govee-bt-client": "^1.0.15"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@antfu/eslint-config": "^3.
|
|
73
|
-
"eslint": "^9.12.0"
|
|
72
|
+
"@antfu/eslint-config": "^3.11.2"
|
|
74
73
|
}
|
|
75
74
|
}
|
|
File without changes
|