@homebridge-plugins/homebridge-govee 10.12.1

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 (78) hide show
  1. package/CHANGELOG.md +1937 -0
  2. package/LICENSE +21 -0
  3. package/README.md +72 -0
  4. package/config.schema.json +1727 -0
  5. package/eslint.config.js +49 -0
  6. package/lib/connection/aws.js +174 -0
  7. package/lib/connection/ble.js +208 -0
  8. package/lib/connection/cert/AmazonRootCA1.pem +20 -0
  9. package/lib/connection/http.js +240 -0
  10. package/lib/connection/lan.js +284 -0
  11. package/lib/device/cooler-single.js +300 -0
  12. package/lib/device/dehumidifier-H7150.js +182 -0
  13. package/lib/device/dehumidifier-H7151.js +157 -0
  14. package/lib/device/diffuser-H7161.js +117 -0
  15. package/lib/device/diffuser-H7162.js +117 -0
  16. package/lib/device/fan-H7100.js +274 -0
  17. package/lib/device/fan-H7101.js +330 -0
  18. package/lib/device/fan-H7102.js +274 -0
  19. package/lib/device/fan-H7105.js +503 -0
  20. package/lib/device/fan-H7106.js +274 -0
  21. package/lib/device/fan-H7111.js +335 -0
  22. package/lib/device/heater-single.js +300 -0
  23. package/lib/device/heater1a.js +353 -0
  24. package/lib/device/heater1b.js +616 -0
  25. package/lib/device/heater2.js +838 -0
  26. package/lib/device/humidifier-H7140.js +224 -0
  27. package/lib/device/humidifier-H7141.js +257 -0
  28. package/lib/device/humidifier-H7142.js +522 -0
  29. package/lib/device/humidifier-H7143.js +157 -0
  30. package/lib/device/humidifier-H7148.js +157 -0
  31. package/lib/device/humidifier-H7160.js +446 -0
  32. package/lib/device/ice-maker-H7162.js +46 -0
  33. package/lib/device/index.js +105 -0
  34. package/lib/device/kettle.js +269 -0
  35. package/lib/device/light-switch.js +86 -0
  36. package/lib/device/light.js +617 -0
  37. package/lib/device/outlet-double.js +121 -0
  38. package/lib/device/outlet-single.js +172 -0
  39. package/lib/device/outlet-triple.js +160 -0
  40. package/lib/device/purifier-H7120.js +336 -0
  41. package/lib/device/purifier-H7121.js +336 -0
  42. package/lib/device/purifier-H7122.js +449 -0
  43. package/lib/device/purifier-H7123.js +411 -0
  44. package/lib/device/purifier-H7124.js +411 -0
  45. package/lib/device/purifier-H7126.js +296 -0
  46. package/lib/device/purifier-H7127.js +296 -0
  47. package/lib/device/purifier-H712C.js +296 -0
  48. package/lib/device/purifier-single.js +119 -0
  49. package/lib/device/sensor-button.js +22 -0
  50. package/lib/device/sensor-contact.js +22 -0
  51. package/lib/device/sensor-leak.js +87 -0
  52. package/lib/device/sensor-monitor.js +190 -0
  53. package/lib/device/sensor-presence.js +53 -0
  54. package/lib/device/sensor-thermo.js +144 -0
  55. package/lib/device/sensor-thermo4.js +55 -0
  56. package/lib/device/switch-double.js +121 -0
  57. package/lib/device/switch-single.js +95 -0
  58. package/lib/device/switch-triple.js +160 -0
  59. package/lib/device/tap-single.js +108 -0
  60. package/lib/device/template.js +43 -0
  61. package/lib/device/tv-single.js +84 -0
  62. package/lib/device/valve-single.js +155 -0
  63. package/lib/fakegato/LICENSE +21 -0
  64. package/lib/fakegato/fakegato-history.js +814 -0
  65. package/lib/fakegato/fakegato-storage.js +108 -0
  66. package/lib/fakegato/fakegato-timer.js +125 -0
  67. package/lib/fakegato/uuid.js +27 -0
  68. package/lib/homebridge-ui/public/index.html +433 -0
  69. package/lib/homebridge-ui/server.js +10 -0
  70. package/lib/index.js +8 -0
  71. package/lib/platform.js +1967 -0
  72. package/lib/utils/colour.js +564 -0
  73. package/lib/utils/constants.js +579 -0
  74. package/lib/utils/custom-chars.js +225 -0
  75. package/lib/utils/eve-chars.js +68 -0
  76. package/lib/utils/functions.js +117 -0
  77. package/lib/utils/lang-en.js +131 -0
  78. package/package.json +75 -0
@@ -0,0 +1,105 @@
1
+ import deviceCoolerSingle from './cooler-single.js'
2
+ import deviceDehumidifierH7150 from './dehumidifier-H7150.js'
3
+ import deviceDehumidifierH7151 from './dehumidifier-H7151.js'
4
+ import deviceDiffuserH7161 from './diffuser-H7161.js'
5
+ import deviceDiffuserH7162 from './diffuser-H7162.js'
6
+ import deviceFanH7100 from './fan-H7100.js'
7
+ import deviceFanH7101 from './fan-H7101.js'
8
+ import deviceFanH7102 from './fan-H7102.js'
9
+ import deviceFanH7105 from './fan-H7105.js'
10
+ import deviceFanH7106 from './fan-H7106.js'
11
+ import deviceFanH7111 from './fan-H7111.js'
12
+ import deviceHeaterSingle from './heater-single.js'
13
+ import deviceHeater1A from './heater1a.js'
14
+ import deviceHeater1B from './heater1b.js'
15
+ import deviceHeater2 from './heater2.js'
16
+ import deviceHumidifierH7140 from './humidifier-H7140.js'
17
+ import deviceHumidifierH7141 from './humidifier-H7141.js'
18
+ import deviceHumidifierH7142 from './humidifier-H7142.js'
19
+ import deviceHumidifierH7143 from './humidifier-H7143.js'
20
+ import deviceHumidifierH7148 from './humidifier-H7148.js'
21
+ import deviceHumidifierH7160 from './humidifier-H7160.js'
22
+ import deviceIceMakerH7162 from './ice-maker-H7162.js'
23
+ import deviceKettle from './kettle.js'
24
+ import deviceLight from './light.js'
25
+ import deviceLightSwitch from './light-switch.js'
26
+ import deviceOutletDouble from './outlet-double.js'
27
+ import deviceOutletSingle from './outlet-single.js'
28
+ import deviceOutletTriple from './outlet-triple.js'
29
+ import devicePurifierH712C from './purifier-H712C.js'
30
+ import devicePurifierH7120 from './purifier-H7120.js'
31
+ import devicePurifierH7121 from './purifier-H7121.js'
32
+ import devicePurifierH7122 from './purifier-H7122.js'
33
+ import devicePurifierH7123 from './purifier-H7123.js'
34
+ import devicePurifierH7124 from './purifier-H7124.js'
35
+ import devicePurifierH7126 from './purifier-H7126.js'
36
+ import devicePurifierH7127 from './purifier-H7127.js'
37
+ import devicePurifierSingle from './purifier-single.js'
38
+ import deviceSensorButton from './sensor-button.js'
39
+ import deviceSensorContact from './sensor-contact.js'
40
+ import deviceSensorLeak from './sensor-leak.js'
41
+ import deviceSensorMonitor from './sensor-monitor.js'
42
+ import deviceSensorPresence from './sensor-presence.js'
43
+ import deviceSensorThermo from './sensor-thermo.js'
44
+ import deviceSensorThermo4 from './sensor-thermo4.js'
45
+ import deviceSwitchDouble from './switch-double.js'
46
+ import deviceSwitchSingle from './switch-single.js'
47
+ import deviceSwitchTriple from './switch-triple.js'
48
+ import deviceTapSingle from './tap-single.js'
49
+ import deviceTemplate from './template.js'
50
+ import deviceTVSingle from './tv-single.js'
51
+ import deviceValveSingle from './valve-single.js'
52
+
53
+ export default {
54
+ deviceCoolerSingle,
55
+ deviceDehumidifierH7150,
56
+ deviceDehumidifierH7151,
57
+ deviceDiffuserH7161,
58
+ deviceDiffuserH7162,
59
+ deviceFanH7100,
60
+ deviceFanH7101,
61
+ deviceFanH7102,
62
+ deviceFanH7105,
63
+ deviceFanH7106,
64
+ deviceFanH7111,
65
+ deviceHeaterSingle,
66
+ deviceHeater1A,
67
+ deviceHeater1B,
68
+ deviceHeater2,
69
+ deviceHumidifierH7140,
70
+ deviceHumidifierH7141,
71
+ deviceHumidifierH7142,
72
+ deviceHumidifierH7143,
73
+ deviceHumidifierH7148,
74
+ deviceHumidifierH7160,
75
+ deviceIceMakerH7162,
76
+ deviceKettle,
77
+ deviceLight,
78
+ deviceLightSwitch,
79
+ deviceOutletDouble,
80
+ deviceOutletSingle,
81
+ deviceOutletTriple,
82
+ devicePurifierH712C,
83
+ devicePurifierH7120,
84
+ devicePurifierH7121,
85
+ devicePurifierH7122,
86
+ devicePurifierH7123,
87
+ devicePurifierH7124,
88
+ devicePurifierH7126,
89
+ devicePurifierH7127,
90
+ devicePurifierSingle,
91
+ deviceSensorButton,
92
+ deviceSensorContact,
93
+ deviceSensorLeak,
94
+ deviceSensorMonitor,
95
+ deviceSensorPresence,
96
+ deviceSensorThermo,
97
+ deviceSensorThermo4,
98
+ deviceSwitchDouble,
99
+ deviceSwitchSingle,
100
+ deviceSwitchTriple,
101
+ deviceTapSingle,
102
+ deviceTemplate,
103
+ deviceTVSingle,
104
+ deviceValveSingle,
105
+ }
@@ -0,0 +1,269 @@
1
+ import {
2
+ base64ToHex,
3
+ getTwoItemPosition,
4
+ hexToTwoItems,
5
+ parseError,
6
+ sleep,
7
+ } from '../utils/functions.js'
8
+ import platformLang from '../utils/lang-en.js'
9
+
10
+ /*
11
+ Custom Mode: aa050001010000000000000000000000000000af
12
+
13
+ Green Tea: MwUAAgAAAAAAAAAAAAAAAAAAADQ= 3305000200000000000000000000000000000034 [switch]
14
+ MwEBAgAAAAAAAAAAAAAAAAAAADk= 3301010200000000000000000000000000000039 [enable]
15
+
16
+ Oolong Tea: MwUAAwAAAAAAAAAAAAAAAAAAADU= 3305000300000000000000000000000000000035 [switch]
17
+ MwEBAwAAAAAAAAAAAAAAAAAAADg= 3301010300000000000000000000000000000038 [enable]
18
+
19
+ Coffee: MwUABAAAAAAAAAAAAAAAAAAAADI= 3305000400000000000000000000000000000032 [switch]
20
+ MwEBBAAAAAAAAAAAAAAAAAAAADc= 3301010400000000000000000000000000000037 [enable]
21
+
22
+ Black Tea/Boil: MwUABQAAAAAAAAAAAAAAAAAAADM= 3305000500000000000000000000000000000033 [switch]
23
+ MwEBBQAAAAAAAAAAAAAAAAAAADY= 3301010500000000000000000000000000000036 [enable]
24
+ */
25
+ export default class {
26
+ constructor(platform, accessory) {
27
+ // Set up variables from the platform
28
+ this.hapChar = platform.api.hap.Characteristic
29
+ this.hapErr = platform.api.hap.HapStatusError
30
+ this.hapServ = platform.api.hap.Service
31
+ this.platform = platform
32
+
33
+ // Set up variables from the accessory
34
+ this.accessory = accessory
35
+ const deviceConf = platform.deviceConf[accessory.context.gvDeviceId] || {}
36
+
37
+ this.codes = {
38
+ greenTea: 'MwUAAgAAAAAAAAAAAAAAAAAAADQ=',
39
+ oolongTea: 'MwUAAwAAAAAAAAAAAAAAAAAAADU=',
40
+ coffee: 'MwUABAAAAAAAAAAAAAAAAAAAADI=',
41
+ blackTea: 'MwUABQAAAAAAAAAAAAAAAAAAADM=',
42
+ customMode1: 'MwUAAQEAAAAAAAAAAAAAAAAAADY=',
43
+ customMode2: 'MwUAAQIAAAAAAAAAAAAAAAAAADU=',
44
+ }
45
+
46
+ // Add a switch service for Green Tea
47
+ this.service1 = this.accessory.getService('Green Tea')
48
+ if (deviceConf.hideModeGreenTea) {
49
+ if (this.service1) {
50
+ this.accessory.removeService(this.service1)
51
+ }
52
+ } else if (!this.service1) {
53
+ this.service1 = this.accessory.addService(this.hapServ.Switch, 'Green Tea', 'greenTea')
54
+ this.service1.addCharacteristic(this.hapChar.ConfiguredName)
55
+ this.service1.updateCharacteristic(this.hapChar.ConfiguredName, 'Green Tea')
56
+ this.service1.addCharacteristic(this.hapChar.ServiceLabelIndex)
57
+ this.service1.updateCharacteristic(this.hapChar.ServiceLabelIndex, 1)
58
+ }
59
+
60
+ // Add a switch service for Oolong Tea
61
+ this.service2 = this.accessory.getService('Oolong Tea')
62
+ if (deviceConf.hideModeOolongTea) {
63
+ if (this.service2) {
64
+ this.accessory.removeService(this.service2)
65
+ }
66
+ } else if (!this.service2) {
67
+ this.service2 = this.accessory.addService(this.hapServ.Switch, 'Oolong Tea', 'oolongTea')
68
+ this.service2.addCharacteristic(this.hapChar.ConfiguredName)
69
+ this.service2.updateCharacteristic(this.hapChar.ConfiguredName, 'Oolong Tea')
70
+ this.service2.addCharacteristic(this.hapChar.ServiceLabelIndex)
71
+ this.service2.updateCharacteristic(this.hapChar.ServiceLabelIndex, 2)
72
+ }
73
+
74
+ // Add a switch service for Coffee
75
+ this.service3 = this.accessory.getService('Coffee')
76
+ if (deviceConf.hideModeCoffee) {
77
+ if (this.service3) {
78
+ this.accessory.removeService(this.service3)
79
+ }
80
+ } else if (!this.service3) {
81
+ this.service3 = this.accessory.addService(this.hapServ.Switch, 'Coffee', 'coffee')
82
+ this.service3.addCharacteristic(this.hapChar.ConfiguredName)
83
+ this.service3.updateCharacteristic(this.hapChar.ConfiguredName, 'Coffee')
84
+ this.service3.addCharacteristic(this.hapChar.ServiceLabelIndex)
85
+ this.service3.updateCharacteristic(this.hapChar.ServiceLabelIndex, 3)
86
+ }
87
+
88
+ // Add a switch service for Black Tea/Boil
89
+ this.service4 = this.accessory.getService('Black Tea/Boil')
90
+ if (deviceConf.hideModeBlackTeaBoil) {
91
+ if (this.service4) {
92
+ this.accessory.removeService(this.service4)
93
+ }
94
+ } else if (!this.service4) {
95
+ this.service4 = this.accessory.addService(this.hapServ.Switch, 'Black Tea/Boil', 'blackTeaBoil')
96
+ this.service4.addCharacteristic(this.hapChar.ConfiguredName)
97
+ this.service4.updateCharacteristic(this.hapChar.ConfiguredName, 'Black Tea/Boil')
98
+ this.service4.addCharacteristic(this.hapChar.ServiceLabelIndex)
99
+ this.service4.updateCharacteristic(this.hapChar.ServiceLabelIndex, 4)
100
+ }
101
+
102
+ // Add a switch service for Custom Mode 1
103
+ this.service5 = this.accessory.getService('Custom Mode 1')
104
+ if (deviceConf.showCustomMode1) {
105
+ if (!this.service5) {
106
+ this.service5 = this.accessory.addService(this.hapServ.Switch, 'Custom Mode 1', 'customMode1')
107
+ this.service5.addCharacteristic(this.hapChar.ConfiguredName)
108
+ this.service5.updateCharacteristic(this.hapChar.ConfiguredName, 'Custom Mode 1')
109
+ this.service5.addCharacteristic(this.hapChar.ServiceLabelIndex)
110
+ this.service5.updateCharacteristic(this.hapChar.ServiceLabelIndex, 5)
111
+ }
112
+ } else if (this.service5) {
113
+ this.accessory.removeService(this.service5)
114
+ }
115
+
116
+ // Add a switch service for Custom Mode 2
117
+ this.service6 = this.accessory.getService('Custom Mode 2')
118
+ if (deviceConf.showCustomMode2) {
119
+ if (!this.service6) {
120
+ this.service6 = this.accessory.addService(this.hapServ.Switch, 'Custom Mode 2', 'customMode2')
121
+ this.service6.addCharacteristic(this.hapChar.ConfiguredName)
122
+ this.service6.updateCharacteristic(this.hapChar.ConfiguredName, 'Custom Mode 2')
123
+ this.service6.addCharacteristic(this.hapChar.ServiceLabelIndex)
124
+ this.service6.updateCharacteristic(this.hapChar.ServiceLabelIndex, 6)
125
+ }
126
+ } else if (this.service6) {
127
+ this.accessory.removeService(this.service6)
128
+ }
129
+
130
+ // Remove the temperature sensor service if it exists
131
+ if (this.accessory.getService(this.hapServ.TemperatureSensor)) {
132
+ this.accessory.removeService(this.accessory.getService(this.hapServ.TemperatureSensor))
133
+ }
134
+
135
+ // Add the set handler to the green tea switch if it exists
136
+ if (this.service1) {
137
+ this.service1.getCharacteristic(this.hapChar.On)
138
+ .updateValue(false)
139
+ .onSet(async value => this.internalStateUpdate(this.service1, value, this.codes.greenTea))
140
+ }
141
+
142
+ // Add the set handler to the oolong tea switch if it exists
143
+ if (this.service2) {
144
+ this.service2.getCharacteristic(this.hapChar.On)
145
+ .updateValue(false)
146
+ .onSet(async value => this.internalStateUpdate(this.service2, value, this.codes.oolongTea))
147
+ }
148
+
149
+ // Add the set handler to the coffee switch if it exists
150
+ if (this.service3) {
151
+ this.service3.getCharacteristic(this.hapChar.On)
152
+ .updateValue(false)
153
+ .onSet(async value => this.internalStateUpdate(this.service3, value, this.codes.coffee))
154
+ }
155
+
156
+ // Add the set handler to the black tea/boil switch if it exists
157
+ if (this.service4) {
158
+ this.service4.getCharacteristic(this.hapChar.On)
159
+ .updateValue(false)
160
+ .onSet(async value => this.internalStateUpdate(this.service4, value, this.codes.blackTea))
161
+ }
162
+
163
+ // Add the set handler to the custom mode 1 switch if it exists
164
+ if (this.service5) {
165
+ this.service5.getCharacteristic(this.hapChar.On)
166
+ .updateValue(false)
167
+ .onSet(async value => this.internalStateUpdate(this.service5, value, this.codes.customMode1))
168
+ }
169
+
170
+ // Add the set handler to the custom mode 2 switch if it exists
171
+ if (this.service6) {
172
+ this.service6.getCharacteristic(this.hapChar.On)
173
+ .updateValue(false)
174
+ .onSet(async value => this.internalStateUpdate(this.service6, value, this.codes.customMode2))
175
+ }
176
+
177
+ // Output the customised options to the log
178
+ const opts = JSON.stringify({})
179
+ platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
180
+ }
181
+
182
+ async internalStateUpdate(service, value, b64Code) {
183
+ try {
184
+ if (!value) {
185
+ return
186
+ }
187
+
188
+ // Send the request to the platform sender function to change the mode
189
+ await this.platform.sendDeviceUpdate(this.accessory, {
190
+ cmd: 'ptReal',
191
+ value: b64Code,
192
+ })
193
+
194
+ await sleep(1000)
195
+
196
+ // Send the request to the platform sender function to turn to boiling mode
197
+ await this.platform.sendDeviceUpdate(this.accessory, {
198
+ cmd: 'ptReal',
199
+ value: 'MwEBAAAAAAAAAAAAAAAAAAAAADM=',
200
+ })
201
+
202
+ // Cache the new state and log if appropriate
203
+ this.cacheState = 'on'
204
+ this.accessory.log(`${platformLang.curMode} [${service.displayName}]`)
205
+ setTimeout(() => {
206
+ service.updateCharacteristic(this.hapChar.On, false)
207
+ }, 3000)
208
+ } catch (err) {
209
+ // Catch any errors during the process
210
+ this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
211
+
212
+ // Throw a 'no response' error and set a timeout to revert this after 2 seconds
213
+ setTimeout(() => {
214
+ service.updateCharacteristic(this.hapChar.On, false)
215
+ }, 2000)
216
+ throw new this.hapErr(-70402)
217
+ }
218
+ }
219
+
220
+ externalUpdate(params) {
221
+ // Check for some other scene/mode change
222
+ (params.commands || []).forEach((command) => {
223
+ const hexString = base64ToHex(command)
224
+ const hexParts = hexToTwoItems(hexString)
225
+
226
+ // Return now if not a device query update code
227
+ if (getTwoItemPosition(hexParts, 1) !== 'aa') {
228
+ return
229
+ }
230
+
231
+ const deviceFunction = `${getTwoItemPosition(hexParts, 2)}${getTwoItemPosition(hexParts, 3)}`
232
+
233
+ switch (deviceFunction) {
234
+ case '0500': { // current mode
235
+ // switch to green tea_: aa050002000000000000000000000000000000ad
236
+ // switch to oolong tea: aa050003000000000000000000000000000000ac
237
+ // switch to coffee____: aa050004000000000000000000000000000000ab
238
+ // switch to black tea_: aa050005000000000000000000000000000000aa
239
+ // switch to preset1___: aa050001010000000000000000000000000000af
240
+ // switch to preset2___: aa050001020000000000000000000000000000ac
241
+ // No point in changing any switches for the sake of three seconds, no action taken here
242
+ break
243
+ }
244
+ case '1001': { // current temperature in F
245
+ // const currentTempInF = hexToDecimal(`${getTwoItemPosition(hexParts, 4)}${getTwoItemPosition(hexParts, 5)}`);
246
+ // const currentTempInC = farToCen(currentTempInF / 100);
247
+ break
248
+ }
249
+ case '1700': { // on/off base?
250
+ const onBase = getTwoItemPosition(hexParts, 4) === '00' ? 'yes' : 'no'
251
+ if (this.cacheOnBase !== onBase) {
252
+ this.cacheOnBase = onBase
253
+ this.accessory.log(`current on base [${this.cacheOnBase}]`)
254
+ }
255
+ break
256
+ }
257
+ case '2200': // keep warm off
258
+ case '2201': // keep warm on
259
+ case '2300': // scheduled start off
260
+ case '2301': { // scheduled start on
261
+ break
262
+ }
263
+ default:
264
+ this.accessory.logDebugWarn(`${platformLang.newScene}: [${command}] [${hexString}]`)
265
+ break
266
+ }
267
+ })
268
+ }
269
+ }
@@ -0,0 +1,86 @@
1
+ import { parseError } from '../utils/functions.js'
2
+ import platformLang from '../utils/lang-en.js'
3
+
4
+ export default class {
5
+ constructor(platform, accessory) {
6
+ // Set up variables from the platform
7
+ this.hapChar = platform.api.hap.Characteristic
8
+ this.hapErr = platform.api.hap.HapStatusError
9
+ this.hapServ = platform.api.hap.Service
10
+ this.platform = platform
11
+
12
+ // Set up variables from the accessory
13
+ this.accessory = accessory
14
+
15
+ // Remove any lightbulb service
16
+ if (accessory.getService(this.hapServ.Lightbulb)) {
17
+ accessory.removeService(accessory.getService(this.hapServ.Lightbulb))
18
+ }
19
+
20
+ // Add the main switch service if it doesn't already exist
21
+ this.service = this.accessory.getService(this.hapServ.Switch)
22
+ || this.accessory.addService(this.hapServ.Switch)
23
+
24
+ // Add the set handler to the lightbulb on/off characteristic
25
+ this.service.getCharacteristic(this.hapChar.On).onSet(async (value) => {
26
+ await this.internalStateUpdate(value)
27
+ })
28
+ this.cacheState = this.service.getCharacteristic(this.hapChar.On).value ? 'on' : 'off'
29
+
30
+ // Output the customised options to the log
31
+ const useAWSControl = accessory.context.useAWSControl ? 'enabled' : 'disabled'
32
+ const useBLEControl = accessory.context.useBLEControl ? 'enabled' : 'disabled'
33
+ const useLANControl = accessory.context.useLANControl ? 'enabled' : 'disabled'
34
+ const opts = JSON.stringify({
35
+ aws: accessory.context.hasAWSControl ? useAWSControl : 'unsupported',
36
+ ble: accessory.context.hasBLEControl ? useBLEControl : 'unsupported',
37
+ lan: accessory.context.hasLANControl ? useLANControl : 'unsupported',
38
+ showAs: 'switch',
39
+ })
40
+ platform.log('[%s] %s %s.', accessory.displayName, platformLang.devInitOpts, opts)
41
+ }
42
+
43
+ async internalStateUpdate(value) {
44
+ try {
45
+ const newValue = value ? 'on' : 'off'
46
+
47
+ // Don't continue if the new value is the same as before
48
+ if (newValue === this.cacheState) {
49
+ return
50
+ }
51
+
52
+ // Send the request to the platform sender function
53
+ await this.platform.sendDeviceUpdate(this.accessory, {
54
+ cmd: 'state',
55
+ value: newValue,
56
+ })
57
+
58
+ // Cache the new state and log if appropriate
59
+ if (this.cacheState !== newValue) {
60
+ this.cacheState = newValue
61
+ this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
62
+ }
63
+ } catch (err) {
64
+ // Catch any errors during the process
65
+ this.accessory.logWarn(`${platformLang.devNotUpdated} ${parseError(err)}`)
66
+
67
+ // Throw a 'no response' error and set a timeout to revert this after 2 seconds
68
+ setTimeout(() => {
69
+ this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
70
+ }, 2000)
71
+ throw new this.hapErr(-70402)
72
+ }
73
+ }
74
+
75
+ externalUpdate(params) {
76
+ // Check to see if the provided state is different from the cached value
77
+ if (params.state && params.state !== this.cacheState) {
78
+ // State is different so update Homebridge with new values
79
+ this.cacheState = params.state
80
+ this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
81
+
82
+ // Log the change
83
+ this.accessory.log(`${platformLang.curState} [${this.cacheState}]`)
84
+ }
85
+ }
86
+ }