@homebridge-plugins/homebridge-govee 11.32.2-beta.31 → 11.32.2-beta.32

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
@@ -7,6 +7,7 @@ All notable changes to `@homebridge-plugins/homebridge-govee` will be documented
7
7
  ### Changed
8
8
 
9
9
  - fix: stop shipping the test files to npm, since they are only needed in the repository
10
+ - fix: BLE device control on macOS by resolving peripherals via advertised name (#1336) (@Perafan18)
10
11
  - fix: implement the H7107's oscillation toggle, which threw a not-implemented error when tapped (#1334)
11
12
  - fix: also send the H7107's oscillation command as the multiSync frame the fan itself uses, since the first shape only turned it off sometimes (#1334)
12
13
  - fix: send the H7107's oscillation-off command without the swing-range bytes, matching the zero-tailed frame the fan echoes back (#1334)
package/README.md CHANGED
@@ -29,7 +29,7 @@ Homebridge plugin to integrate Govee devices into HomeKit
29
29
  - To use this plugin, you will need to already have:
30
30
  - [Node](https://nodejs.org): latest version of `v22`, `v24` or `v26` - any other major version is not supported.
31
31
  - [Homebridge](https://homebridge.io): `v1.6` or above - refer to link for more information and installation instructions.
32
- - 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.
32
+ - 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, and has not been tested on Windows. On macOS, the plugin resolves BLE devices via their advertised name (macOS does not expose bluetooth MAC addresses), and the `node` binary running Homebridge needs Bluetooth permission in System Settings → Privacy & Security → Bluetooth.
33
33
 
34
34
  ### Setup
35
35
 
@@ -390,7 +390,9 @@ export default class BLEConnection {
390
390
  let timeoutId
391
391
  try {
392
392
  return await Promise.race([
393
- btClient.connectAsync(address),
393
+ process.platform === 'darwin'
394
+ ? this.connectByNameDarwin(address, timeout)
395
+ : btClient.connectAsync(address),
394
396
  new Promise((_, reject) => {
395
397
  timeoutId = setTimeout(() => reject(new Error('Connection timeout')), timeout)
396
398
  }),
@@ -400,6 +402,49 @@ export default class BLEConnection {
400
402
  }
401
403
  }
402
404
 
405
+ // macOS: CoreBluetooth never exposes MAC addresses, so connect-by-address can
406
+ // never resolve. Govee devices advertise a local name whose suffix is the last
407
+ // two bytes of their MAC (e.g. Govee_H617A_325A for ...:32:5A), so scan and
408
+ // match on that instead, then connect to the discovered peripheral directly.
409
+ async connectByNameDarwin(address, timeout) {
410
+ const suffix = address.replace(/:/g, '').slice(-4).toLowerCase()
411
+ this.darwinPeripheralCache = this.darwinPeripheralCache ?? new Map()
412
+ const cached = this.darwinPeripheralCache.get(suffix)
413
+ if (cached) {
414
+ try {
415
+ await cached.connectAsync()
416
+ return cached
417
+ } catch (err) {
418
+ this.darwinPeripheralCache.delete(suffix)
419
+ this.log.debug('[BLE] cached peripheral for %s failed (%s), rescanning.', suffix, err.message)
420
+ }
421
+ }
422
+ const peripheral = await new Promise((resolve, reject) => {
423
+ let done = false
424
+ function onDiscover(p) {
425
+ const name = (p.advertisement?.localName ?? '').toLowerCase()
426
+ if (name.endsWith(suffix) && (name.startsWith('govee') || name.startsWith('ihoment'))) {
427
+ finish(resolve, p)
428
+ }
429
+ }
430
+ function finish(fn, value) {
431
+ if (done) {
432
+ return
433
+ }
434
+ done = true
435
+ btClient.removeListener('discover', onDiscover)
436
+ btClient.stopScanningAsync().catch(() => {})
437
+ fn(value)
438
+ }
439
+ btClient.on('discover', onDiscover)
440
+ btClient.startScanningAsync([], true).catch(err => finish(reject, err))
441
+ setTimeout(() => finish(reject, new Error(`no peripheral advertising name suffix ${suffix} found in scan`)), Math.max(timeout - 1000, 4000))
442
+ })
443
+ this.darwinPeripheralCache.set(suffix, peripheral)
444
+ await peripheral.connectAsync()
445
+ return peripheral
446
+ }
447
+
403
448
  async writeWithTimeout(characteristic, buffer, timeout) {
404
449
  let timeoutId
405
450
  try {
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.2-beta.31",
5
+ "version": "11.32.2-beta.32",
6
6
  "description": "Homebridge plugin to integrate Govee devices into HomeKit.",
7
7
  "author": {
8
8
  "name": "bwp91",