@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 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/bwp91/homebridge-govee/wiki/Scene,-Music,-DIY-Modes
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/bwp91/homebridge-govee/wiki/Scene,-Music,-DIY-Modes) for more info
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/bwp91/homebridge-govee/wiki/Supported-Devices) for supported devices
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/bwp91/homebridge-govee/issues/99)
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/bwp91/homebridge-govee/wiki/Bluetooth-Control)
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/bwp91/homebridge-govee/issues/56))
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/bwp91/homebridge-govee"><img src="https://user-images.githubusercontent.com/43026681/101324574-5e997d80-3862-11eb-81b0-932330f6e242.png" width="600px"></a>
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
  [![npm](https://img.shields.io/npm/v/homebridge-govee/latest?label=latest)](https://www.npmjs.com/package/homebridge-govee)
11
- [![npm](https://img.shields.io/npm/v/homebridge-govee/beta?label=beta)](https://github.com/bwp91/homebridge-govee/wiki/Beta-Version)
11
+ [![npm](https://img.shields.io/npm/v/homebridge-govee/beta?label=beta)](https://github.com/homebridge-plugins/homebridge-govee/wiki/Beta-Version)
12
12
 
13
13
  [![verified-by-homebridge](https://badgen.net/badge/homebridge/verified/purple)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
14
14
  [![hoobs-certified](https://badgen.net/badge/HOOBS/certified/yellow?label=hoobs)](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/bwp91/homebridge-govee/wiki/Bluetooth-Control). Bluetooth works best when using a Raspberry Pi, not been tested on Windows, and Mac devices are unsupported.
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/bwp91/homebridge-govee/wiki/Installation)
38
- - [Configuration](https://github.com/bwp91/homebridge-govee/wiki/Configuration)
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/bwp91/homebridge-govee/wiki/Node-Version)
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/bwp91/homebridge-govee/wiki/Supported-Devices)
45
- - [Connection Methods](https://github.com/bwp91/homebridge-govee/wiki/Connection-Methods)
46
- - [LAN Control](https://github.com/bwp91/homebridge-govee/wiki/LAN-Control)
47
- - [AWS Control](https://github.com/bwp91/homebridge-govee/wiki/AWS-Control)
48
- - [BLE Control](https://github.com/bwp91/homebridge-govee/wiki/Bluetooth-Control)
49
- - [Scene, Music, DIY Modes](https://github.com/bwp91/homebridge-govee/wiki/Scene%2C-Music%2C-DIY-Modes)
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/bwp91/homebridge-govee/wiki/Common-Errors)
54
- - [Support Request](https://github.com/bwp91/homebridge-govee/issues/new/choose)
55
- - [Changelog](https://github.com/bwp91/homebridge-govee/blob/latest/CHANGELOG.md)
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
@@ -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/bwp91/homebridge-govee/wiki\">GitHub Wiki</a>. We hope you find this plugin useful!</p>",
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/bwp91/homebridge-govee/wiki/Supported-Devices\" target=\"_blank\">Read more →</a>"
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/bwp91/homebridge-govee/wiki/Supported-Devices\" target=\"_blank\">Read more →</a>"
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/bwp91/homebridge-govee/wiki/Bluetooth-Control#finding-the-bluetooth-address\" target=\"_blank\">Read more →</a>",
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": 23
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/bwp91/homebridge-govee/wiki/Scene%2C-Music%2C-DIY-Modes\" target=\"_blank\">Read more →</a>",
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
+ }
@@ -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 deviceIceMakerH7162 from './ice-maker-H7162.js'
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
- deviceIceMakerH7162,
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/bwp91/homebridge-govee/wiki/Installation" target="_blank"
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/bwp91/homebridge-govee/wiki/Configuration" target="_blank"
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/bwp91/homebridge-govee/wiki/Node-Version" target="_blank"
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/bwp91/homebridge-govee/wiki/Supported-Devices" target="_blank"
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/bwp91/homebridge-govee/wiki/Connection-Methods" target="_blank"
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/bwp91/homebridge-govee/wiki/LAN-Control" target="_blank"
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/bwp91/homebridge-govee/wiki/API-Control" target="_blank"
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/bwp91/homebridge-govee/wiki/AWS-Control" target="_blank"
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/bwp91/homebridge-govee/wiki/Bluetooth-Control" target="_blank"
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/bwp91/homebridge-govee/wiki/Scene%2C-Music%2C-DIY-Modes" target="_blank"
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/bwp91/homebridge-govee/wiki/Common-Errors" target="_blank"
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/bwp91/homebridge-govee/issues/new/choose" target="_blank"
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/bwp91/homebridge-govee/blob/latest/CHANGELOG.md" target="_blank"
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
- httpDevice.device = httpDevice.device.replace(/..\B/g, '$&:').toUpperCase()
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
- device.device = device.device.replace(/..\B/g, '$&:').toUpperCase()
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
@@ -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/bwp91/homebridge-govee/issues/422
432
- 'H5024', // https://github.com/bwp91/homebridge-govee/issues/835
433
- 'H5042', // https://github.com/bwp91/homebridge-govee/issues/849
434
- 'H5043', // https://github.com/bwp91/homebridge-govee/issues/558
435
- 'H5121', // https://github.com/bwp91/homebridge-govee/issues/913
436
- 'H5126', // https://github.com/bwp91/homebridge-govee/issues/910
437
- 'H5107', // https://github.com/bwp91/homebridge-govee/issues/803
438
- 'H5109', // https://github.com/bwp91/homebridge-govee/issues/823
439
- 'H5185', // https://github.com/bwp91/homebridge-govee/issues/804
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/bwp91/homebridge-govee/issues/827
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/bwp91/homebridge-govee/issues/775
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/bwp91/homebridge-govee/issues/783
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/bwp91/homebridge-govee/issues/904
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/bwp91/homebridge-govee/issues/757
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/bwp91/homebridge-govee/issues/825
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/bwp91/homebridge-govee/issues/795
534
- 'H7039', // !NOT CONFIRMED! https://github.com/bwp91/homebridge-govee/issues/771
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/bwp91/homebridge-govee/issues/818
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'],
@@ -50,7 +50,7 @@ function parseDeviceId(deviceId) {
50
50
  return deviceId
51
51
  .toString()
52
52
  .toUpperCase()
53
- .replace(/[^A-F0-9:]+/g, '')
53
+ .replace(/[^A-F0-9_:]+/g, '')
54
54
  }
55
55
 
56
56
  function parseError(err, hideStack = []) {
@@ -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/bwp91/homebridge-govee/wiki/OpenSSL for more info about installing OpenSSL',
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.12.1",
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/bwp91/homebridge-govee",
30
+ "homepage": "https://github.com/homebridge-plugins/homebridge-govee",
31
31
  "repository": {
32
32
  "type": "git",
33
- "url": "git+https://github.com/bwp91/homebridge-govee.git"
33
+ "url": "git+https://github.com/homebridge-plugins/homebridge-govee.git"
34
34
  },
35
35
  "bugs": {
36
- "url": "https://github.com/bwp91/homebridge-govee/issues"
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.4 || ^20.18.0 || ^22.9.0"
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": "^1.0.3",
58
+ "@homebridge/plugin-ui-utils": "^2.0.0",
59
59
  "aws-iot-device-sdk": "^2.2.15",
60
- "axios": "^1.7.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.7.3",
73
- "eslint": "^9.12.0"
72
+ "@antfu/eslint-config": "^3.11.2"
74
73
  }
75
74
  }