@homebridge-plugins/homebridge-govee 11.32.2-beta.2 → 11.32.2-beta.21

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/config.schema.json +1 -1
  3. package/lib/connection/ble.js +26 -1
  4. package/lib/connection/openapi.js +18 -0
  5. package/lib/device/appliance-basic.js +377 -0
  6. package/lib/device/dehumidifier-H7150.js +9 -3
  7. package/lib/device/diffuser-H7161.js +7 -1
  8. package/lib/device/fan-H1370.js +7 -1
  9. package/lib/device/fan-H7100.js +36 -4
  10. package/lib/device/fan-H7105.js +7 -1
  11. package/lib/device/fan-H7107.js +7 -1
  12. package/lib/device/heater1a.js +52 -12
  13. package/lib/device/heater1b.js +14 -3
  14. package/lib/device/heater2.js +7 -1
  15. package/lib/device/humidifier-H7140.js +7 -1
  16. package/lib/device/humidifier-H7141.js +7 -1
  17. package/lib/device/humidifier-H7142.js +7 -1
  18. package/lib/device/humidifier-H7143.js +7 -1
  19. package/lib/device/humidifier-H7160.js +7 -1
  20. package/lib/device/ice-maker-H7172.js +19 -7
  21. package/lib/device/index.js +44 -51
  22. package/lib/device/kettle.js +7 -1
  23. package/lib/device/outlet-single.js +7 -1
  24. package/lib/device/purifier-H7120.js +14 -25
  25. package/lib/device/purifier-H7122.js +7 -1
  26. package/lib/device/purifier-H7123.js +9 -3
  27. package/lib/device/purifier-H7126.js +7 -1
  28. package/lib/device/{sensor-button.js → sensor-basic.js} +14 -2
  29. package/lib/device/sensor-presence.js +7 -1
  30. package/lib/device/sensor-thermo4.js +13 -2
  31. package/lib/device/switch-double.js +34 -15
  32. package/lib/device/switch-triple.js +36 -17
  33. package/lib/device/template.js +15 -2
  34. package/lib/platform.js +83 -799
  35. package/lib/utils/capabilities.js +220 -0
  36. package/lib/utils/command-builder.js +6 -4
  37. package/lib/utils/config-parser.js +280 -0
  38. package/lib/utils/constants.js +120 -8
  39. package/lib/utils/decode.js +4 -1
  40. package/lib/utils/device-capabilities.js +77 -3
  41. package/lib/utils/device-context.js +179 -0
  42. package/lib/utils/device-merge.js +251 -0
  43. package/lib/utils/dispatch.js +159 -0
  44. package/lib/utils/functions.js +9 -0
  45. package/lib/utils/lang-en.js +0 -2
  46. package/lib/utils/report-unknown.js +156 -0
  47. package/package.json +1 -1
  48. package/lib/device/dehumidifier-H7151.js +0 -189
  49. package/lib/device/dehumidifier-H7152.js +0 -180
  50. package/lib/device/diffuser-H7162.js +0 -123
  51. package/lib/device/fan-H1310.js +0 -284
  52. package/lib/device/fan-H7101.js +0 -340
  53. package/lib/device/fan-H7102.js +0 -284
  54. package/lib/device/fan-H7106.js +0 -284
  55. package/lib/device/fan-H7111.js +0 -345
  56. package/lib/device/humidifier-H7145.js +0 -187
  57. package/lib/device/humidifier-H7147.js +0 -187
  58. package/lib/device/humidifier-H7148.js +0 -187
  59. package/lib/device/humidifier-H7149.js +0 -187
  60. package/lib/device/humidifier-H714E.js +0 -187
  61. package/lib/device/ice-maker-H717D.js +0 -218
  62. package/lib/device/ice-maker-H8120.js +0 -218
  63. package/lib/device/outlet-double.js +0 -188
  64. package/lib/device/outlet-triple.js +0 -160
  65. package/lib/device/purifier-H7121.js +0 -406
  66. package/lib/device/purifier-H7124.js +0 -504
  67. package/lib/device/purifier-H7127.js +0 -359
  68. package/lib/device/purifier-H7128.js +0 -359
  69. package/lib/device/purifier-H7129.js +0 -359
  70. package/lib/device/purifier-H712C.js +0 -359
  71. package/lib/device/sensor-contact.js +0 -22
  72. package/lib/utils/ble-timeouts.test.js +0 -44
  73. package/lib/utils/functions.test.js +0 -292
@@ -1,189 +0,0 @@
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
- // Speed codes
21
- this.value2Code = {
22
- 1: 'MwUBAQAAAAAAAAAAAAAAAAAAADY=',
23
- 2: 'MwUBAgAAAAAAAAAAAAAAAAAAADU=',
24
- 3: 'MwUBAwAAAAAAAAAAAAAAAAAAADQ=',
25
- 4: 'MwUBBAAAAAAAAAAAAAAAAAAAADM=',
26
- 5: 'MwUBBQAAAAAAAAAAAAAAAAAAADI=',
27
- 6: 'MwUBBgAAAAAAAAAAAAAAAAAAADE=',
28
- 7: 'MwUBBwAAAAAAAAAAAAAAAAAAADA=',
29
- 8: 'MwUBCAAAAAAAAAAAAAAAAAAAAD8=',
30
- }
31
-
32
- // Migrate old %-rotation speed to unitless
33
- const existingFanService = this.accessory.getService(this.hapServ.Fan)
34
- if (existingFanService) {
35
- if (existingFanService.getCharacteristic(this.hapChar.RotationSpeed).props.unit === 'percentage') {
36
- this.accessory.removeService(existingFanService)
37
- }
38
- }
39
-
40
- // Add the fan service if it doesn't already exist
41
- this.service = this.accessory.getService(this.hapServ.Fan) || this.accessory.addService(this.hapServ.Fan)
42
-
43
- // Add the set handler to the fan on/off characteristic
44
- this.service
45
- .getCharacteristic(this.hapChar.On)
46
- .onSet(async value => this.internalStateUpdate(value))
47
- this.cacheState = this.service.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
48
-
49
- // Add the set handler to the fan rotation speed characteristic
50
- this.service
51
- .getCharacteristic(this.hapChar.RotationSpeed)
52
- .setProps({
53
- maxValue: 8,
54
- minStep: 1,
55
- minValue: 0,
56
- unit: 'unitless',
57
- })
58
- .onSet(async value => this.internalSpeedUpdate(value))
59
- this.cacheSpeed = this.service.getCharacteristic(this.hapChar.RotationSpeed).value
60
-
61
- // Output the customised options to the log
62
- const opts = JSON.stringify({})
63
- platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
64
- }
65
-
66
- async internalStateUpdate(value) {
67
- try {
68
- const newValue = value ? 'on' : 'off'
69
-
70
- // Don't continue if the new value is the same as before
71
- if (this.cacheState === newValue) {
72
- return
73
- }
74
-
75
- // Send the request to the platform sender function
76
- await this.platform.sendDeviceUpdate(this.accessory, {
77
- cmd: 'stateHumi',
78
- value: value ? 1 : 0,
79
- })
80
-
81
- // Cache the new state and log if appropriate
82
- this.cacheState = newValue
83
- this.accessory.log(`${platformLang.curState} [${newValue}]`)
84
- } catch (err) {
85
- // Catch any errors during the process
86
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
87
-
88
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
89
- setTimeout(() => {
90
- this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
91
- }, 2000)
92
- throw new this.hapErr(-70402)
93
- }
94
- }
95
-
96
- async internalSpeedUpdate(value) {
97
- try {
98
- // Don't continue if the speed is 0
99
- if (value === 0) {
100
- return
101
- }
102
-
103
- // Don't continue if the speed value won't have effect
104
- if (value === this.cacheSpeed) {
105
- return
106
- }
107
-
108
- // Get the scene code for this value
109
- const newCode = this.value2Code[value]
110
-
111
- // Send the request to the platform sender function
112
- await this.platform.sendDeviceUpdate(this.accessory, {
113
- cmd: 'ptReal',
114
- value: newCode,
115
- openApi: this.accessory.context.openApiCapabilities?.workMode
116
- ? { instance: 'workMode', capabilityType: 'devices.capabilities.work_mode', value: { workMode: 1, modeValue: value } }
117
- : undefined,
118
- })
119
-
120
- // Cache the new state and log if appropriate
121
- this.cacheSpeed = value
122
- this.accessory.log(`${platformLang.curSpeed} [${value}]`)
123
- } catch (err) {
124
- // Catch any errors during the process
125
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
126
-
127
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
128
- setTimeout(() => {
129
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
130
- }, 2000)
131
- throw new this.hapErr(-70402)
132
- }
133
- }
134
-
135
- externalUpdate(params) {
136
- // Check for an ON/OFF change
137
- if (params.state && params.state !== this.cacheState) {
138
- this.cacheState = params.state
139
- this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
140
-
141
- // Log the change
142
- this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
143
- }
144
-
145
- // Handle OpenAPI workMode (speed)
146
- if (params.workMode) {
147
- const speed = params.workMode.modeValue
148
- if (speed >= 1 && speed <= 8) {
149
- if (speed !== this.cacheSpeed) {
150
- this.cacheSpeed = speed
151
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
152
- this.accessory.log(`${platformLang.curSpeed} [${this.cacheSpeed}]`)
153
- }
154
- }
155
- }
156
-
157
- // Check for some other scene/mode change
158
- (params.commands || []).forEach((command) => {
159
- const hexString = base64ToHex(command)
160
- const hexParts = hexToTwoItems(hexString)
161
-
162
- // Return now if not a device query update code
163
- if (getTwoItemPosition(hexParts, 1) !== 'aa') {
164
- return
165
- }
166
-
167
- const deviceFunction = `${getTwoItemPosition(hexParts, 2)}${getTwoItemPosition(hexParts, 3)}`
168
-
169
- switch (deviceFunction) {
170
- case '0501':
171
- case '0502': {
172
- // Speed update
173
- const newSpeedValue = Number.parseInt(getTwoItemPosition(hexParts, 4), 16)
174
- if (newSpeedValue >= 1 && newSpeedValue <= 8) {
175
- if (newSpeedValue !== this.cacheSpeed) {
176
- this.cacheSpeed = newSpeedValue
177
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
178
- this.accessory.log(`${platformLang.curSpeed} [${this.cacheSpeed}]`)
179
- }
180
- }
181
- break
182
- }
183
- default:
184
- this.accessory.logDebugWarn(`${platformLang.newScene}: [${command}] [${hexString}]`)
185
- break
186
- }
187
- })
188
- }
189
- }
@@ -1,180 +0,0 @@
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
- // Speed codes
21
- this.value2Code = {
22
- 1: 'MwUBAQAAAAAAAAAAAAAAAAAAADY=',
23
- 2: 'MwUBAgAAAAAAAAAAAAAAAAAAADU=',
24
- 3: 'MwUBAwAAAAAAAAAAAAAAAAAAADQ=',
25
- 4: 'MwUBBAAAAAAAAAAAAAAAAAAAADM=',
26
- 5: 'MwUBBQAAAAAAAAAAAAAAAAAAADI=',
27
- 6: 'MwUBBgAAAAAAAAAAAAAAAAAAADE=',
28
- 7: 'MwUBBwAAAAAAAAAAAAAAAAAAADA=',
29
- 8: 'MwUBCAAAAAAAAAAAAAAAAAAAAD8=',
30
- }
31
-
32
- // Migrate old %-rotation speed to unitless
33
- const existingFanService = this.accessory.getService(this.hapServ.Fan)
34
- if (existingFanService) {
35
- if (existingFanService.getCharacteristic(this.hapChar.RotationSpeed).props.unit === 'percentage') {
36
- this.accessory.removeService(existingFanService)
37
- }
38
- }
39
-
40
- // Add the fan service if it doesn't already exist
41
- this.service = this.accessory.getService(this.hapServ.Fan) || this.accessory.addService(this.hapServ.Fan)
42
-
43
- // Add the set handler to the fan on/off characteristic
44
- this.service
45
- .getCharacteristic(this.hapChar.On)
46
- .onSet(async value => this.internalStateUpdate(value))
47
- this.cacheState = this.service.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
48
-
49
- // Add the set handler to the fan rotation speed characteristic
50
- this.service
51
- .getCharacteristic(this.hapChar.RotationSpeed)
52
- .setProps({
53
- maxValue: 8,
54
- minStep: 1,
55
- minValue: 0,
56
- unit: 'unitless',
57
- })
58
- .onSet(async value => this.internalSpeedUpdate(value))
59
- this.cacheSpeed = this.service.getCharacteristic(this.hapChar.RotationSpeed).value
60
-
61
- // Output the customised options to the log
62
- const opts = JSON.stringify({})
63
- platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
64
- }
65
-
66
- async internalStateUpdate(value) {
67
- try {
68
- const newValue = value ? 'on' : 'off'
69
-
70
- // Don't continue if the new value is the same as before
71
- if (this.cacheState === newValue) {
72
- return
73
- }
74
-
75
- // Send the request to the platform sender function
76
- await this.platform.sendDeviceUpdate(this.accessory, {
77
- cmd: 'stateHumi',
78
- value: value ? 1 : 0,
79
- })
80
-
81
- // Cache the new state and log if appropriate
82
- this.cacheState = newValue
83
- this.accessory.log(`${platformLang.curState} [${newValue}]`)
84
- } catch (err) {
85
- // Catch any errors during the process
86
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
87
-
88
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
89
- setTimeout(() => {
90
- this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
91
- }, 2000)
92
- throw new this.hapErr(-70402)
93
- }
94
- }
95
-
96
- async internalSpeedUpdate(value) {
97
- try {
98
- // Don't continue if the speed is 0
99
- if (value === 0) {
100
- return
101
- }
102
-
103
- // Don't continue if the speed value won't have effect
104
- if (value === this.cacheSpeed) {
105
- return
106
- }
107
-
108
- // Get the scene code for this value
109
- const newCode = this.value2Code[value]
110
-
111
- // Send the request to the platform sender function
112
- await this.platform.sendDeviceUpdate(this.accessory, {
113
- cmd: 'ptReal',
114
- value: newCode,
115
- })
116
-
117
- // Cache the new state and log if appropriate
118
- this.cacheSpeed = value
119
- this.accessory.log(`${platformLang.curSpeed} [${value}]`)
120
- } catch (err) {
121
- // Catch any errors during the process
122
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
123
-
124
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
125
- setTimeout(() => {
126
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
127
- }, 2000)
128
- throw new this.hapErr(-70402)
129
- }
130
- }
131
-
132
- externalUpdate(params) {
133
- // Check for an ON/OFF change
134
- if (params.state && params.state !== this.cacheState) {
135
- this.cacheState = params.state
136
- this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
137
-
138
- // Log the change
139
- this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
140
- }
141
-
142
- // Handle OpenAPI workMode
143
- if (params.workMode) {
144
- const mode = params.workMode.modeValue
145
- this.accessory.log(`${platformLang.curMode} [${mode}]`)
146
- }
147
-
148
- // Check for some other scene/mode change
149
- (params.commands || []).forEach((command) => {
150
- const hexString = base64ToHex(command)
151
- const hexParts = hexToTwoItems(hexString)
152
-
153
- // Return now if not a device query update code
154
- if (getTwoItemPosition(hexParts, 1) !== 'aa') {
155
- return
156
- }
157
-
158
- const deviceFunction = `${getTwoItemPosition(hexParts, 2)}${getTwoItemPosition(hexParts, 3)}`
159
-
160
- switch (deviceFunction) {
161
- case '0501':
162
- case '0502': {
163
- // Speed update
164
- const newSpeedValue = Number.parseInt(getTwoItemPosition(hexParts, 4), 16)
165
- if (newSpeedValue >= 1 && newSpeedValue <= 8) {
166
- if (newSpeedValue !== this.cacheSpeed) {
167
- this.cacheSpeed = newSpeedValue
168
- this.service.updateCharacteristic(this.hapChar.RotationSpeed, this.cacheSpeed)
169
- this.accessory.log(`${platformLang.curSpeed} [${this.cacheSpeed}]`)
170
- }
171
- }
172
- break
173
- }
174
- default:
175
- this.accessory.logDebugWarn(`${platformLang.newScene}: [${command}] [${hexString}]`)
176
- break
177
- }
178
- })
179
- }
180
- }
@@ -1,123 +0,0 @@
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
- // Remove fan service if exists
21
- if (this.accessory.getService(this.hapServ.Fan)) {
22
- this.accessory.removeService(this.accessory.getService(this.hapServ.Fan))
23
- }
24
-
25
- // Add the purifier service if it doesn't already exist
26
- this.service = this.accessory.getService(this.hapServ.AirPurifier)
27
- || this.accessory.addService(this.hapServ.AirPurifier)
28
-
29
- // Add the set handler to the switch on/off characteristic
30
- this.service.getCharacteristic(this.hapChar.Active).onSet(async (value) => {
31
- await this.internalStateUpdate(value)
32
- })
33
- this.cacheState = this.service.getCharacteristic(this.hapChar.Active).value === 1 ? 'on' : 'off'
34
-
35
- // Add options to the purifier target state characteristic
36
- this.service
37
- .getCharacteristic(this.hapChar.TargetAirPurifierState)
38
- .updateValue(1)
39
- .setProps({
40
- minValue: 1,
41
- maxValue: 1,
42
- validValues: [1],
43
- })
44
-
45
- // Output the customised options to the log
46
- const opts = JSON.stringify({})
47
- platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
48
- }
49
-
50
- async internalStateUpdate(value) {
51
- try {
52
- const newValue = value === 1 ? 'on' : 'off'
53
-
54
- // Don't continue if the new value is the same as before
55
- if (this.cacheState === newValue) {
56
- return
57
- }
58
-
59
- // Send the request to the platform sender function
60
- await this.platform.sendDeviceUpdate(this.accessory, {
61
- cmd: 'stateHumi',
62
- value,
63
- })
64
-
65
- // Cache the new state and log if appropriate
66
- if (this.cacheState !== newValue) {
67
- this.cacheState = newValue
68
- this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
69
- }
70
-
71
- this.service.updateCharacteristic(this.hapChar.CurrentAirPurifierState, value === 1 ? 2 : 0)
72
- } catch (err) {
73
- // Catch any errors during the process
74
- this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
75
-
76
- // Throw a 'no response' error and set a timeout to revert this after 2 seconds
77
- setTimeout(() => {
78
- this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
79
- }, 2000)
80
- throw new this.hapErr(-70402)
81
- }
82
- }
83
-
84
- externalUpdate(params) {
85
- // Check for an ON/OFF change
86
- if (params.state && params.state !== this.cacheState) {
87
- this.cacheState = params.state
88
- this.service.updateCharacteristic(this.hapChar.Active, this.cacheState === 'on' ? 1 : 0)
89
- this.service.updateCharacteristic(
90
- this.hapChar.CurrentAirPurifierState,
91
- this.cacheState === 'on' ? 2 : 0,
92
- )
93
-
94
- // Log the change
95
- this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
96
- }
97
-
98
- // Handle OpenAPI workMode
99
- if (params.workMode) {
100
- const mode = params.workMode.modeValue
101
- this.accessory.log(`${platformLang.curMode} [${mode}]`)
102
- }
103
-
104
- // Check for some other scene/mode change
105
- (params.commands || []).forEach((command) => {
106
- const hexString = base64ToHex(command)
107
- const hexParts = hexToTwoItems(hexString)
108
-
109
- // Return now if not a device query update code
110
- if (getTwoItemPosition(hexParts, 1) !== 'aa') {
111
- return
112
- }
113
-
114
- const deviceFunction = `${getTwoItemPosition(hexParts, 1)}${getTwoItemPosition(hexParts, 2)}`
115
-
116
- switch (deviceFunction) {
117
- default:
118
- this.accessory.logDebugWarn(`${platformLang.newScene}: [${command}] [${hexString}]`)
119
- break
120
- }
121
- })
122
- }
123
- }