@homebridge-plugins/homebridge-govee 11.32.0-beta.2 → 11.32.0-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.
- package/CHANGELOG.md +12 -2
- package/lib/device/fan-H1310.js +18 -8
- package/lib/device/fan-H1370.js +14 -5
- package/lib/device/fan-H7100.js +18 -8
- package/lib/device/fan-H7101.js +18 -8
- package/lib/device/fan-H7102.js +18 -8
- package/lib/device/fan-H7105.js +20 -6
- package/lib/device/fan-H7106.js +18 -8
- package/lib/device/fan-H7107.js +20 -6
- package/lib/device/fan-H7111.js +17 -20
- package/lib/device/outlet-double.js +125 -16
- package/lib/device/switch-double.js +125 -16
- package/lib/homebridge-ui/public/index.html +167 -142
- package/lib/homebridge-ui/server.js +7 -0
- package/lib/platform.js +32 -0
- package/lib/utils/constants.js +6 -3
- package/lib/utils/functions.js +36 -0
- package/lib/utils/lang-en.js +1 -0
- package/package.json +9 -5
|
@@ -23,10 +23,17 @@
|
|
|
23
23
|
border-color: #444444;
|
|
24
24
|
color: #eeeeee;
|
|
25
25
|
}
|
|
26
|
+
|
|
27
|
+
.text-muted {
|
|
28
|
+
color: #aaaaaa !important;
|
|
29
|
+
}
|
|
26
30
|
}
|
|
27
31
|
.min-w-50 {
|
|
28
32
|
min-width: 50px;
|
|
29
33
|
}
|
|
34
|
+
.action-desc {
|
|
35
|
+
font-size: 0.85rem;
|
|
36
|
+
}
|
|
30
37
|
select {
|
|
31
38
|
background-image:
|
|
32
39
|
linear-gradient(45deg, transparent 50%, gray 50%),
|
|
@@ -82,31 +89,57 @@
|
|
|
82
89
|
</div>
|
|
83
90
|
<div id="deviceInfo">
|
|
84
91
|
<form>
|
|
85
|
-
<div class="form-group">
|
|
92
|
+
<div class="form-group mb-0">
|
|
86
93
|
<select class="form-control" id="deviceSelect"></select>
|
|
87
94
|
</div>
|
|
88
95
|
</form>
|
|
89
|
-
<ul class="list-group mt-
|
|
96
|
+
<ul class="list-group mt-4 mb-4 mx-0" id="configActionList" style="display: none;">
|
|
90
97
|
<li class="list-group-item">
|
|
91
98
|
<div class="d-flex justify-content-between align-items-center">
|
|
92
|
-
<
|
|
93
|
-
|
|
99
|
+
<div class="pr-2">
|
|
100
|
+
<div>Add All Devices</div>
|
|
101
|
+
<div class="text-muted action-desc">Add all devices to the config that are not already in the config.</div>
|
|
102
|
+
</div>
|
|
103
|
+
<button type="button" class="btn btn-primary m-0 ml-3 py-1 min-w-50" id="addAllBtn" aria-label="Add all devices to the config">
|
|
104
|
+
<i aria-hidden="true" class="fas fa-arrow-right"></i>
|
|
105
|
+
</button>
|
|
94
106
|
</div>
|
|
95
107
|
</li>
|
|
96
108
|
<li class="list-group-item">
|
|
97
109
|
<div class="d-flex justify-content-between align-items-center">
|
|
98
|
-
<
|
|
99
|
-
|
|
110
|
+
<div class="pr-2">
|
|
111
|
+
<div>Remove All Devices</div>
|
|
112
|
+
<div class="text-muted action-desc" id="removeAllText">Remove every device from the plugin config.</div>
|
|
113
|
+
</div>
|
|
114
|
+
<button type="button" class="btn btn-primary m-0 ml-3 py-1 min-w-50" id="removeAllBtn" aria-label="Remove all devices from the config">
|
|
115
|
+
<i aria-hidden="true" class="fas fa-arrow-right"></i>
|
|
116
|
+
</button>
|
|
100
117
|
</div>
|
|
101
118
|
</li>
|
|
102
119
|
<li class="list-group-item">
|
|
103
120
|
<div class="d-flex justify-content-between align-items-center">
|
|
104
|
-
<
|
|
105
|
-
|
|
121
|
+
<div class="pr-2">
|
|
122
|
+
<div id="deviceConfigTitle">Add This Device</div>
|
|
123
|
+
<div class="text-muted action-desc" id="deviceConfigText">Add this device to the plugin config.</div>
|
|
124
|
+
</div>
|
|
125
|
+
<button type="button" class="btn btn-primary m-0 ml-3 py-1 min-w-50" id="deviceConfigBtn" aria-label="Add this device to the config">
|
|
126
|
+
<i aria-hidden="true" class="fas fa-arrow-right"></i>
|
|
127
|
+
</button>
|
|
128
|
+
</div>
|
|
129
|
+
</li>
|
|
130
|
+
<li class="list-group-item">
|
|
131
|
+
<div class="d-flex justify-content-between align-items-center">
|
|
132
|
+
<div class="pr-2">
|
|
133
|
+
<div id="hideDeviceTitle">Hide This Device</div>
|
|
134
|
+
<div class="text-muted action-desc" id="hideDeviceText">Hide this device from HomeKit. This adds the device to the config if needed.</div>
|
|
135
|
+
</div>
|
|
136
|
+
<button type="button" class="btn btn-primary m-0 ml-3 py-1 min-w-50" id="hideDeviceBtn" aria-label="Hide this device from HomeKit">
|
|
137
|
+
<i aria-hidden="true" class="fas fa-arrow-right"></i>
|
|
138
|
+
</button>
|
|
106
139
|
</div>
|
|
107
140
|
</li>
|
|
108
141
|
</ul>
|
|
109
|
-
<table class="table w-100 mt-
|
|
142
|
+
<table class="table w-100 mt-0" id="deviceTable" style="display: none;">
|
|
110
143
|
<thead>
|
|
111
144
|
<tr class="table-active">
|
|
112
145
|
<th scope="col" style="width: 40%;">Device Name</th>
|
|
@@ -197,138 +230,69 @@
|
|
|
197
230
|
</table>
|
|
198
231
|
</div>
|
|
199
232
|
</div>
|
|
200
|
-
<div id="pageSupport" class="mt-4" style="display: none
|
|
233
|
+
<div id="pageSupport" class="mt-4" style="display: none">
|
|
201
234
|
<p class="text-center lead">Thank you for using <strong>homebridge-govee</strong></p>
|
|
202
|
-
<
|
|
203
|
-
|
|
204
|
-
<
|
|
205
|
-
<li>
|
|
206
|
-
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Installation" target="_blank"
|
|
207
|
-
>Installation</a
|
|
208
|
-
>
|
|
209
|
-
</li>
|
|
210
|
-
<li>
|
|
211
|
-
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Configuration" target="_blank"
|
|
212
|
-
>Configuration</a
|
|
213
|
-
>
|
|
214
|
-
</li>
|
|
215
|
-
<li>
|
|
216
|
-
<a href="https://github.com/homebridge/homebridge/wiki/How-to-Install-Alternate-Plugin-Versions" target="_blank"
|
|
217
|
-
>Beta Version</a
|
|
218
|
-
>
|
|
219
|
-
</li>
|
|
220
|
-
<li>
|
|
221
|
-
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Node-Version" target="_blank"
|
|
222
|
-
>Node Version</a
|
|
223
|
-
>
|
|
224
|
-
</li>
|
|
225
|
-
</ul>
|
|
226
|
-
<h4>Features</h4>
|
|
235
|
+
<h5>Plugin Information</h5>
|
|
236
|
+
<ul>
|
|
237
|
+
<li>This plugin allows you to view and control your Govee devices within HomeKit. The plugin:</li>
|
|
227
238
|
<ul>
|
|
228
|
-
<li>
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
</li>
|
|
233
|
-
<li>
|
|
234
|
-
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Connection-Methods" target="_blank"
|
|
235
|
-
>Connection Methods</a
|
|
236
|
-
>
|
|
237
|
-
</li>
|
|
238
|
-
<ul>
|
|
239
|
-
<li>
|
|
240
|
-
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/LAN-Control" target="_blank"
|
|
241
|
-
>LAN Control</a
|
|
242
|
-
>
|
|
243
|
-
</li>
|
|
244
|
-
<li>
|
|
245
|
-
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/API-Control" target="_blank"
|
|
246
|
-
>API Control</a
|
|
247
|
-
>
|
|
248
|
-
</li>
|
|
249
|
-
<li>
|
|
250
|
-
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/AWS-Control" target="_blank"
|
|
251
|
-
>AWS Control</a
|
|
252
|
-
>
|
|
253
|
-
</li>
|
|
254
|
-
<li>
|
|
255
|
-
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Bluetooth-Control" target="_blank"
|
|
256
|
-
>BLE Control</a
|
|
257
|
-
>
|
|
258
|
-
</li>
|
|
259
|
-
</ul>
|
|
260
|
-
<li>
|
|
261
|
-
<a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Scene%2C-Music%2C-DIY-Modes" target="_blank"
|
|
262
|
-
>Scene, Music, DIY Modes</a
|
|
263
|
-
>
|
|
264
|
-
</li>
|
|
239
|
+
<li>supports Govee OpenAPI discovery/state/control when an OpenAPI key is provided</li>
|
|
240
|
+
<li>requires your Govee credentials for most Cloud/AWS/BLE connections</li>
|
|
241
|
+
<li>can control certain models locally via LAN control without any Govee credentials</li>
|
|
242
|
+
<li>may use different connection methods depending on device model and account capabilities</li>
|
|
265
243
|
</ul>
|
|
266
|
-
|
|
244
|
+
</ul>
|
|
245
|
+
<h5>Prerequisites</h5>
|
|
246
|
+
<ul>
|
|
247
|
+
<li>To use this plugin, you will need to already have:</li>
|
|
267
248
|
<ul>
|
|
268
|
-
<li>
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
>
|
|
272
|
-
</li>
|
|
273
|
-
<li>
|
|
274
|
-
<a href="https://github.com/homebridge-plugins/homebridge-govee/issues/new/choose" target="_blank"
|
|
275
|
-
>Support Request</a
|
|
276
|
-
>
|
|
277
|
-
</li>
|
|
278
|
-
<li>
|
|
279
|
-
<a href="https://github.com/homebridge-plugins/homebridge-govee/blob/latest/CHANGELOG.md" target="_blank"
|
|
280
|
-
>Changelog</a
|
|
281
|
-
>
|
|
282
|
-
</li>
|
|
283
|
-
<li><a href="https://github.com/sponsors/bwp91" target="_blank">About Me</a></li>
|
|
249
|
+
<li><a href="https://nodejs.org" target="_blank">Node</a>: latest version of <code>v22</code> or <code>v24</code> - any other major version is not supported.</li>
|
|
250
|
+
<li><a href="https://homebridge.io" target="_blank">Homebridge</a>: <code>v1.6</code> or above - refer to link for more information and installation instructions.</li>
|
|
251
|
+
<li>For bluetooth connectivity, it may be necessary to install extra packages on your system, see <a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Bluetooth-Control" target="_blank">Bluetooth Control</a>. Bluetooth works best when using a Raspberry Pi, not been tested on Windows, and Mac devices are unsupported.</li>
|
|
284
252
|
</ul>
|
|
285
|
-
|
|
253
|
+
</ul>
|
|
254
|
+
<h5>Setup</h5>
|
|
255
|
+
<ul>
|
|
256
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Installation" target="_blank">Installation</a></li>
|
|
257
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Configuration" target="_blank">Configuration</a></li>
|
|
258
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Beta-Version" target="_blank">Beta Version</a></li>
|
|
259
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Node-Version" target="_blank">Node Version</a></li>
|
|
260
|
+
</ul>
|
|
261
|
+
<h5>Features</h5>
|
|
262
|
+
<ul>
|
|
263
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Supported-Devices" target="_blank">Supported Devices</a></li>
|
|
264
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Connection-Methods" target="_blank">Connection Methods</a></li>
|
|
286
265
|
<ul>
|
|
287
|
-
<li>
|
|
288
|
-
<li>
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
library which made the bluetooth connection possible.
|
|
292
|
-
</li>
|
|
293
|
-
<li>
|
|
294
|
-
To the creator/owner of the
|
|
295
|
-
<a href="https://github.com/towlerj/govee_api" target="_blank">govee_api</a>
|
|
296
|
-
library which made the AWS connection possible.
|
|
297
|
-
</li>
|
|
298
|
-
<li>
|
|
299
|
-
To <a href="https://github.com/alboiuvlad29" target="_blank">@alboiuvlad29</a> who made the LAN connection possible.
|
|
300
|
-
</li>
|
|
301
|
-
<li>
|
|
302
|
-
To <a href="https://github.com/JeremyDunn" target="_blank">@JeremyDunn</a> for his code from
|
|
303
|
-
<a href="https://github.com/JeremyDunn/homebridge-govee-water-detectors" target="_blank"
|
|
304
|
-
>homebridge-govee-water-detectors</a
|
|
305
|
-
>
|
|
306
|
-
for leak sensor support.
|
|
307
|
-
</li>
|
|
308
|
-
<li>
|
|
309
|
-
To the creator/owner of the
|
|
310
|
-
<a href="https://www.npmjs.com/package/govee-bt-client" target="_blank"
|
|
311
|
-
>govee-bt-client</a
|
|
312
|
-
>
|
|
313
|
-
library which made the BLE connection to sensors possible.
|
|
314
|
-
</li>
|
|
315
|
-
<li>
|
|
316
|
-
To the creator of the awesome plugin header logo:
|
|
317
|
-
<a href="https://www.instagram.com/keryan.me" target="_blank">Keryan Belahcene</a>.
|
|
318
|
-
</li>
|
|
319
|
-
<li>
|
|
320
|
-
To the creators/contributors of
|
|
321
|
-
<a href="https://homebridge.io" target="_blank">Homebridge</a> who make this plugin possible.
|
|
322
|
-
</li>
|
|
323
|
-
</ul>
|
|
324
|
-
<h4>Disclaimer</h4>
|
|
325
|
-
<ul>
|
|
326
|
-
<li>
|
|
327
|
-
I am in no way affiliated with Govee and this plugin is a personal project that I maintain in
|
|
328
|
-
my free time.
|
|
329
|
-
</li>
|
|
330
|
-
<li>Use this plugin entirely at your own risk - please see licence for more information.</li>
|
|
266
|
+
<li>OpenAPI Control</li>
|
|
267
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/LAN-Control" target="_blank">LAN Control</a></li>
|
|
268
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/AWS-Control" target="_blank">AWS Control</a></li>
|
|
269
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Bluetooth-Control" target="_blank">BLE Control</a></li>
|
|
331
270
|
</ul>
|
|
271
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Scene%2C-Music%2C-DIY-Modes" target="_blank">Scene, Music, DIY Modes</a></li>
|
|
272
|
+
</ul>
|
|
273
|
+
<h5>Help/About</h5>
|
|
274
|
+
<ul>
|
|
275
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/wiki/Common-Errors" target="_blank">Common Errors</a></li>
|
|
276
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/issues/new/choose" target="_blank">Support Request</a></li>
|
|
277
|
+
<li><a href="https://github.com/homebridge-plugins/homebridge-govee/blob/latest/CHANGELOG.md" target="_blank">Changelog</a></li>
|
|
278
|
+
<li><a href="https://github.com/sponsors/bwp91" target="_blank">About Me</a></li>
|
|
279
|
+
</ul>
|
|
280
|
+
<h5>Credits</h5>
|
|
281
|
+
<ul>
|
|
282
|
+
<li>To all users who have shared their devices to enable functionality.</li>
|
|
283
|
+
<li>To the creator/owner of the <a href="https://www.npmjs.com/package/govee-led-client" target="_blank">govee-led-client</a> library which made the BLE connection possible.</li>
|
|
284
|
+
<li>To the creator/owner of the <a href="https://github.com/towlerj/govee_api" target="_blank">govee_api</a> library which made the AWS connection possible.</li>
|
|
285
|
+
<li>To <a href="https://github.com/alboiuvlad29" target="_blank">@alboiuvlad29</a> who made the LAN connection possible.</li>
|
|
286
|
+
<li>To <a href="https://github.com/JeremyDunn" target="_blank">@JeremyDunn</a> for his code from <a href="https://github.com/JeremyDunn/homebridge-govee-water-detectors" target="_blank">homebridge-govee-water-detectors</a> for leak sensor support.</li>
|
|
287
|
+
<li>To the creator/owner of the <a href="https://www.npmjs.com/package/govee-bt-client" target="_blank">govee-bt-client</a> library which made the BLE connection to sensors possible.</li>
|
|
288
|
+
<li>To the creator of the awesome plugin header logo: <a href="https://www.instagram.com/keryan.me" target="_blank">Keryan Belahcene</a>.</li>
|
|
289
|
+
<li>To the creators/contributors of <a href="https://homebridge.io" target="_blank">Homebridge</a> who make this plugin possible.</li>
|
|
290
|
+
</ul>
|
|
291
|
+
<h5>Disclaimer</h5>
|
|
292
|
+
<ul>
|
|
293
|
+
<li>I am in no way affiliated with Govee and this plugin is a personal project that I maintain in my free time.</li>
|
|
294
|
+
<li>Use this plugin entirely at your own risk - please see licence for more information.</li>
|
|
295
|
+
</ul>
|
|
332
296
|
</div>
|
|
333
297
|
<script>
|
|
334
298
|
;(async () => {
|
|
@@ -355,6 +319,7 @@
|
|
|
355
319
|
let pickerAccessories = []
|
|
356
320
|
let pickerModelMap = {}
|
|
357
321
|
let removeConfirmTimer
|
|
322
|
+
let removeAllConfirmTimer
|
|
358
323
|
|
|
359
324
|
// Compare device ids ignoring case, colons and underscores, so an entry
|
|
360
325
|
// typed by hand in a different format still counts as the same device
|
|
@@ -381,13 +346,19 @@
|
|
|
381
346
|
return null
|
|
382
347
|
}
|
|
383
348
|
|
|
349
|
+
// The action buttons always show the settings-page arrow; the row text
|
|
350
|
+
// (and the button's aria-label) says what the arrow will do
|
|
351
|
+
const actionArrow = '<i aria-hidden="true" class="fas fa-arrow-right"></i>'
|
|
352
|
+
|
|
384
353
|
const setHideControl = hidden => {
|
|
385
354
|
const btn = document.getElementById('hideDeviceBtn')
|
|
386
355
|
btn.dataset.hidden = hidden ? 'yes' : 'no'
|
|
387
|
-
btn.innerHTML =
|
|
356
|
+
btn.innerHTML = actionArrow
|
|
357
|
+
btn.setAttribute('aria-label', hidden ? 'Show this device in HomeKit' : 'Hide this device from HomeKit')
|
|
358
|
+
document.getElementById('hideDeviceTitle').innerHTML = hidden ? 'Show This Device' : 'Hide This Device'
|
|
388
359
|
document.getElementById('hideDeviceText').innerHTML = hidden
|
|
389
|
-
? 'Show this device in HomeKit.'
|
|
390
|
-
: 'Hide this device from HomeKit.'
|
|
360
|
+
? 'Show this device in HomeKit again. The config entry is kept.'
|
|
361
|
+
: 'Hide this device from HomeKit. This adds the device to the config if needed.'
|
|
391
362
|
}
|
|
392
363
|
|
|
393
364
|
const setConfigButton = inConfig => {
|
|
@@ -397,10 +368,12 @@
|
|
|
397
368
|
btn.dataset.state = inConfig ? 'remove' : 'add'
|
|
398
369
|
btn.classList.remove('btn-danger')
|
|
399
370
|
btn.classList.add('btn-primary')
|
|
400
|
-
btn.innerHTML =
|
|
371
|
+
btn.innerHTML = actionArrow
|
|
372
|
+
btn.setAttribute('aria-label', inConfig ? 'Remove this device from the config' : 'Add this device to the config')
|
|
373
|
+
document.getElementById('deviceConfigTitle').innerHTML = inConfig ? 'Remove This Device' : 'Add This Device'
|
|
401
374
|
document.getElementById('deviceConfigText').innerHTML = inConfig
|
|
402
|
-
? '
|
|
403
|
-
: '
|
|
375
|
+
? 'Remove this device from the plugin config.'
|
|
376
|
+
: 'Add this device to the plugin config.'
|
|
404
377
|
}
|
|
405
378
|
|
|
406
379
|
const addDeviceToConfig = (config, acc) => {
|
|
@@ -453,8 +426,9 @@
|
|
|
453
426
|
btn.dataset.confirm = 'yes'
|
|
454
427
|
btn.classList.remove('btn-primary')
|
|
455
428
|
btn.classList.add('btn-danger')
|
|
456
|
-
btn.innerHTML =
|
|
457
|
-
|
|
429
|
+
btn.innerHTML = actionArrow
|
|
430
|
+
btn.setAttribute('aria-label', 'Confirm removing this device from the config')
|
|
431
|
+
document.getElementById('deviceConfigText').innerHTML = 'This entry has extra settings which will be lost. Click again to remove it.'
|
|
458
432
|
removeConfirmTimer = setTimeout(() => setConfigButton(true), 5000)
|
|
459
433
|
return
|
|
460
434
|
}
|
|
@@ -546,6 +520,57 @@
|
|
|
546
520
|
homebridge.toast.error(err.message, 'Error')
|
|
547
521
|
}
|
|
548
522
|
})
|
|
523
|
+
const resetRemoveAllButton = () => {
|
|
524
|
+
const btn = document.getElementById('removeAllBtn')
|
|
525
|
+
clearTimeout(removeAllConfirmTimer)
|
|
526
|
+
delete btn.dataset.confirm
|
|
527
|
+
btn.classList.remove('btn-danger')
|
|
528
|
+
btn.classList.add('btn-primary')
|
|
529
|
+
btn.innerHTML = actionArrow
|
|
530
|
+
btn.setAttribute('aria-label', 'Remove all devices from the config')
|
|
531
|
+
document.getElementById('removeAllText').innerHTML = 'Remove every device from the plugin config.'
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
document.getElementById('removeAllBtn').addEventListener('click', async () => {
|
|
535
|
+
try {
|
|
536
|
+
const btn = document.getElementById('removeAllBtn')
|
|
537
|
+
const blocks = await getConfigBlocks()
|
|
538
|
+
const config = blocks[0]
|
|
539
|
+
let total = 0
|
|
540
|
+
deviceArrayKeys.forEach((key) => {
|
|
541
|
+
if (Array.isArray(config[key])) {
|
|
542
|
+
total += config[key].length
|
|
543
|
+
}
|
|
544
|
+
})
|
|
545
|
+
if (total === 0) {
|
|
546
|
+
resetRemoveAllButton()
|
|
547
|
+
homebridge.toast.info('There are no devices in the config.', 'Nothing To Remove')
|
|
548
|
+
return
|
|
549
|
+
}
|
|
550
|
+
if (btn.dataset.confirm !== 'yes') {
|
|
551
|
+
// Removing everything always asks for a second click, since any
|
|
552
|
+
// settings on the entries would be lost
|
|
553
|
+
btn.dataset.confirm = 'yes'
|
|
554
|
+
btn.classList.remove('btn-primary')
|
|
555
|
+
btn.classList.add('btn-danger')
|
|
556
|
+
btn.innerHTML = actionArrow
|
|
557
|
+
btn.setAttribute('aria-label', 'Confirm removing all devices from the config')
|
|
558
|
+
document.getElementById('removeAllText').innerHTML = 'Any settings on these entries will be lost. Click again to remove all ' + total + (total === 1 ? ' entry.' : ' entries.')
|
|
559
|
+
removeAllConfirmTimer = setTimeout(resetRemoveAllButton, 5000)
|
|
560
|
+
return
|
|
561
|
+
}
|
|
562
|
+
deviceArrayKeys.forEach((key) => {
|
|
563
|
+
delete config[key]
|
|
564
|
+
})
|
|
565
|
+
await homebridge.updatePluginConfig(blocks)
|
|
566
|
+
resetRemoveAllButton()
|
|
567
|
+
setConfigButton(false)
|
|
568
|
+
setHideControl(false)
|
|
569
|
+
homebridge.toast.success(total + ' device entr' + (total === 1 ? 'y' : 'ies') + ' removed - press Save to apply.', 'Removed From Config')
|
|
570
|
+
} catch (err) {
|
|
571
|
+
homebridge.toast.error(err.message, 'Error')
|
|
572
|
+
}
|
|
573
|
+
})
|
|
549
574
|
// ===== End device picker =====
|
|
550
575
|
|
|
551
576
|
showIntro = () => {
|
|
@@ -31,6 +31,12 @@ const categoryToArray = {
|
|
|
31
31
|
template: 'lightDevices',
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
// Models whose category does not say what the device actually is, so the
|
|
35
|
+
// picker would file them in the wrong config section without an override
|
|
36
|
+
const modelOverrides = {
|
|
37
|
+
H5085: 'switchDevices', // dual smart plug, in the template category
|
|
38
|
+
}
|
|
39
|
+
|
|
34
40
|
class PluginUiServer extends HomebridgePluginUiServer {
|
|
35
41
|
constructor() {
|
|
36
42
|
super()
|
|
@@ -44,6 +50,7 @@ class PluginUiServer extends HomebridgePluginUiServer {
|
|
|
44
50
|
modelToArray[model] = arrayKey
|
|
45
51
|
})
|
|
46
52
|
})
|
|
53
|
+
Object.assign(modelToArray, modelOverrides)
|
|
47
54
|
return modelToArray
|
|
48
55
|
})
|
|
49
56
|
|
package/lib/platform.js
CHANGED
|
@@ -1444,6 +1444,18 @@ export default class {
|
|
|
1444
1444
|
accessory.context.hasOpenApiControl = true
|
|
1445
1445
|
accessory.context.useOpenApiControl = !!this.openApiClient
|
|
1446
1446
|
accessory.context.openApiCapabilities = device.openApiInfo.byInstance || {}
|
|
1447
|
+
|
|
1448
|
+
// Log what Govee says this device can do. Working out whether a model
|
|
1449
|
+
// exposes something like a night light otherwise means reverse
|
|
1450
|
+
// engineering its status messages, when the answer is right here
|
|
1451
|
+
const instances = Object.entries(accessory.context.openApiCapabilities)
|
|
1452
|
+
.map(([instance, capability]) => `${instance} (${capability?.type ?? 'unknown type'})`)
|
|
1453
|
+
this.log.debug(
|
|
1454
|
+
'[%s] openapi category [%s] capabilities [%s].',
|
|
1455
|
+
accessory.displayName,
|
|
1456
|
+
device.openApiInfo.category || 'unknown',
|
|
1457
|
+
instances.join(', ') || 'none',
|
|
1458
|
+
)
|
|
1447
1459
|
}
|
|
1448
1460
|
|
|
1449
1461
|
// Create the instance for this device type
|
|
@@ -1988,6 +2000,26 @@ export default class {
|
|
|
1988
2000
|
|
|
1989
2001
|
const data = parseDeviceUpdate(params, accessory.context)
|
|
1990
2002
|
|
|
2003
|
+
// The payload above logs the device's own status codes as base64 buried in
|
|
2004
|
+
// a large JSON blob, which is unreadable when working out what a device can
|
|
2005
|
+
// do. Decode them so a code like `aa 36 01 01` can be spotted by eye, and
|
|
2006
|
+
// matched to the `33 36 01 01` needed to set it. Codes with no handler yet
|
|
2007
|
+
// are exactly the ones worth seeing, so log them all rather than guessing
|
|
2008
|
+
// which are already understood
|
|
2009
|
+
const statusCodes = (Array.isArray(data.commands) ? data.commands : [])
|
|
2010
|
+
.map((command) => {
|
|
2011
|
+
try {
|
|
2012
|
+
return base64ToHex(command)
|
|
2013
|
+
} catch {
|
|
2014
|
+
return ''
|
|
2015
|
+
}
|
|
2016
|
+
})
|
|
2017
|
+
.filter(hexString => hexString.startsWith('aa'))
|
|
2018
|
+
.map(hexString => hexString.replace(/../g, '$& ').trim())
|
|
2019
|
+
if (statusCodes.length > 0) {
|
|
2020
|
+
accessory.logDebug(`[${params.source}] ${platformLang.statusCodes}:\n ${statusCodes.join('\n ')}`)
|
|
2021
|
+
}
|
|
2022
|
+
|
|
1991
2023
|
// Log if kelvin was out of range before clamping
|
|
1992
2024
|
if (data.kelvinOutOfRange) {
|
|
1993
2025
|
accessory.logDebug(`govee provided a kelvin out of range [${params.state?.colorTemInKelvin}]`)
|
package/lib/utils/constants.js
CHANGED
|
@@ -229,6 +229,7 @@ export default {
|
|
|
229
229
|
'H60B0',
|
|
230
230
|
'H60B1',
|
|
231
231
|
'H60B2',
|
|
232
|
+
'H60B3',
|
|
232
233
|
'H60C1',
|
|
233
234
|
'H6101',
|
|
234
235
|
'H6102',
|
|
@@ -506,8 +507,11 @@ export default {
|
|
|
506
507
|
'R16D0',
|
|
507
508
|
'R1741',
|
|
508
509
|
],
|
|
509
|
-
|
|
510
|
-
|
|
510
|
+
// H5901 is a water timer, controlled only through the OpenAPI - it has no
|
|
511
|
+
// usable AWS, BLE or LAN path, so it needs an API key configured. Set
|
|
512
|
+
// showAs to 'valve' or 'tap' for a more fitting HomeKit tile (#1324)
|
|
513
|
+
switchSingle: ['H5001', 'H5080', 'H5081', 'H5083', 'H5086', 'H5901', 'H7014'],
|
|
514
|
+
switchDouble: ['H5082', 'H5089'],
|
|
511
515
|
switchTriple: ['H5160'],
|
|
512
516
|
sensorLeak: ['H5054', 'H5058', 'H5059'],
|
|
513
517
|
sensorThermo: [
|
|
@@ -562,7 +566,6 @@ export default {
|
|
|
562
566
|
'H5042', // https://github.com/homebridge-plugins/homebridge-govee/issues/849
|
|
563
567
|
'H5043', // https://github.com/homebridge-plugins/homebridge-govee/issues/558
|
|
564
568
|
'H5085', // https://github.com/homebridge-plugins/homebridge-govee/issues/951
|
|
565
|
-
'H5089', // https://github.com/homebridge-plugins/homebridge-govee/issues/1242
|
|
566
569
|
'H5111', // https://github.com/homebridge-plugins/homebridge-govee/issues/1117
|
|
567
570
|
'H5121', // https://github.com/homebridge-plugins/homebridge-govee/issues/913
|
|
568
571
|
'H5124', // https://github.com/homebridge-plugins/homebridge-govee/issues/1119
|
package/lib/utils/functions.js
CHANGED
|
@@ -106,9 +106,44 @@ function statusToActionCode(statusCode) {
|
|
|
106
106
|
return Buffer.from(generatedCode, 'base64').toString('hex')
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Convert a HomeKit RotationSpeed percentage into a device speed step.
|
|
111
|
+
*
|
|
112
|
+
* `steps` is the number of REAL speeds the model has, excluding auto (8 on the
|
|
113
|
+
* H7100 family, 12 on the H7105/H7107/H1370). A percentage of 0 means "off" and
|
|
114
|
+
* is handled by the caller, so this always returns a usable step in 1..steps.
|
|
115
|
+
*
|
|
116
|
+
* Auto is deliberately NOT reachable from here. Auto is a mode, not a speed, so
|
|
117
|
+
* 100% means maximum speed. Exposing auto at the top of the slider is what made
|
|
118
|
+
* the previous behaviour surprising - dragging to full would silently select
|
|
119
|
+
* auto instead of full power.
|
|
120
|
+
*/
|
|
121
|
+
function hkPercentToFanSpeed(percent, steps) {
|
|
122
|
+
return Math.max(1, Math.min(steps, Math.round((percent * steps) / 100)))
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Convert a device speed step into a HomeKit RotationSpeed percentage.
|
|
127
|
+
*
|
|
128
|
+
* When the device reports auto, HomeKit is shown 100%, but callers should keep
|
|
129
|
+
* their own cache at `autoSpeed`. That lets the plugin tell "the device is in
|
|
130
|
+
* auto" apart from "the user asked for maximum speed", and so avoid echoing a
|
|
131
|
+
* redundant command straight back to the device.
|
|
132
|
+
*/
|
|
133
|
+
function fanSpeedToHkPercent(speed, steps, autoSpeed) {
|
|
134
|
+
if (autoSpeed !== undefined && speed === autoSpeed) {
|
|
135
|
+
return 100
|
|
136
|
+
}
|
|
137
|
+
if (!speed || speed < 1) {
|
|
138
|
+
return 0
|
|
139
|
+
}
|
|
140
|
+
return Math.min(100, Math.round((speed / steps) * 100))
|
|
141
|
+
}
|
|
142
|
+
|
|
109
143
|
export {
|
|
110
144
|
base64ToHex,
|
|
111
145
|
cenToFar,
|
|
146
|
+
fanSpeedToHkPercent,
|
|
112
147
|
farToCen,
|
|
113
148
|
generateCodeFromHexValues,
|
|
114
149
|
generateRandomString,
|
|
@@ -117,6 +152,7 @@ export {
|
|
|
117
152
|
hexToBase64,
|
|
118
153
|
hexToDecimal,
|
|
119
154
|
hexToTwoItems,
|
|
155
|
+
hkPercentToFanSpeed,
|
|
120
156
|
nearestHalf,
|
|
121
157
|
parseDeviceId,
|
|
122
158
|
parseError,
|
package/lib/utils/lang-en.js
CHANGED
|
@@ -133,5 +133,6 @@ export default {
|
|
|
133
133
|
syncFail: 'sync failed as',
|
|
134
134
|
syncStillRunning: 'skipping this sync as the previous one has not finished yet',
|
|
135
135
|
viaAL: 'via adaptive lighting',
|
|
136
|
+
statusCodes: 'device status codes',
|
|
136
137
|
unknownCommand: 'unknown command in payload received',
|
|
137
138
|
}
|
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": "11.32.0-beta.
|
|
5
|
+
"version": "11.32.0-beta.21",
|
|
6
6
|
"description": "Homebridge plugin to integrate Govee devices into HomeKit.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "bwp91",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"keywords": [
|
|
39
39
|
"homebridge",
|
|
40
40
|
"homebridge-plugin",
|
|
41
|
+
"supports-hap",
|
|
41
42
|
"homebridge-govee",
|
|
42
43
|
"hoobs",
|
|
43
44
|
"hoobs-plugin",
|
|
@@ -62,21 +63,24 @@
|
|
|
62
63
|
"mqtt": "^5.15.2",
|
|
63
64
|
"node-persist": "^4.0.4",
|
|
64
65
|
"node-rsa": "^2.0.0",
|
|
65
|
-
"p-queue": "^9.3.
|
|
66
|
+
"p-queue": "^9.3.3",
|
|
66
67
|
"patch-package": "^8.0.1",
|
|
67
68
|
"pem": "^1.14.8"
|
|
68
69
|
},
|
|
69
70
|
"optionalDependencies": {
|
|
70
71
|
"@stoprocent/bluetooth-hci-socket": "^2.2.6",
|
|
71
|
-
"@stoprocent/noble": "^2.5.
|
|
72
|
+
"@stoprocent/noble": "^2.5.9"
|
|
72
73
|
},
|
|
73
74
|
"devDependencies": {
|
|
74
|
-
"@antfu/eslint-config": "^9.
|
|
75
|
+
"@antfu/eslint-config": "^9.2.0"
|
|
75
76
|
},
|
|
76
77
|
"allowScripts": {
|
|
77
78
|
"@stoprocent/bluetooth-hci-socket@2.2.6": true,
|
|
78
|
-
"@stoprocent/noble@2.5.
|
|
79
|
+
"@stoprocent/noble@2.5.9": true,
|
|
79
80
|
"usb@2.18.0": true,
|
|
80
81
|
"@serialport/bindings-cpp@12.0.1": true
|
|
82
|
+
},
|
|
83
|
+
"overrides": {
|
|
84
|
+
"help-me": "^5.0.0"
|
|
81
85
|
}
|
|
82
86
|
}
|