homebridge-pitpat-treadmill 0.1.2 → 0.1.3
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
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. The project follows Semantic Versioning.
|
|
4
4
|
|
|
5
|
+
## [0.1.3] - 2026-10-09
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Attempt one controlled HCI controller reset when Noble remains outside the `poweredOn` state after a BLE link timeout.
|
|
10
|
+
- Preserve normal reconnect backoff when the adapter cannot recover.
|
|
11
|
+
|
|
5
12
|
## [0.1.2] - 2026-10-09
|
|
6
13
|
|
|
7
14
|
### Fixed
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import type { Logger } from 'homebridge';
|
|
1
2
|
import type { BleConnection, BleTransport } from './transport.js';
|
|
2
3
|
export declare class NobleTransport implements BleTransport {
|
|
4
|
+
private readonly log;
|
|
3
5
|
private noble?;
|
|
6
|
+
constructor(log: Pick<Logger, 'warn'>);
|
|
4
7
|
private loadNoble;
|
|
5
8
|
connect(deviceIdentifier: string, timeoutMs: number): Promise<BleConnection>;
|
|
9
|
+
private ensurePoweredOn;
|
|
6
10
|
private findPeripheral;
|
|
7
11
|
}
|
|
@@ -39,7 +39,11 @@ class NobleConnection {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
export class NobleTransport {
|
|
42
|
+
log;
|
|
42
43
|
noble;
|
|
44
|
+
constructor(log) {
|
|
45
|
+
this.log = log;
|
|
46
|
+
}
|
|
43
47
|
async loadNoble() {
|
|
44
48
|
if (!this.noble) {
|
|
45
49
|
const module = await import('@stoprocent/noble');
|
|
@@ -49,7 +53,7 @@ export class NobleTransport {
|
|
|
49
53
|
}
|
|
50
54
|
async connect(deviceIdentifier, timeoutMs) {
|
|
51
55
|
const noble = await this.loadNoble();
|
|
52
|
-
await
|
|
56
|
+
await this.ensurePoweredOn(noble, timeoutMs);
|
|
53
57
|
const peripheral = await this.findPeripheral(noble, deviceIdentifier, timeoutMs);
|
|
54
58
|
await peripheral.connectAsync();
|
|
55
59
|
try {
|
|
@@ -71,6 +75,25 @@ export class NobleTransport {
|
|
|
71
75
|
throw error;
|
|
72
76
|
}
|
|
73
77
|
}
|
|
78
|
+
async ensurePoweredOn(noble, timeoutMs) {
|
|
79
|
+
try {
|
|
80
|
+
await noble.waitForPoweredOnAsync(timeoutMs);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
if (noble.state === 'unauthorized' || noble.state === 'unsupported') {
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
this.log.warn(`[PiTPAT] BLE adapter state is ${noble.state}; attempting one controller reset`);
|
|
88
|
+
noble.reset();
|
|
89
|
+
try {
|
|
90
|
+
await noble.waitForPoweredOnAsync(Math.min(timeoutMs, 10_000));
|
|
91
|
+
}
|
|
92
|
+
catch (recoveryError) {
|
|
93
|
+
throw new Error(`BLE adapter did not recover after reset (state ${noble.state}): ${errorMessage(recoveryError)}`, { cause: recoveryError });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
74
97
|
async findPeripheral(noble, configuredIdentifier, timeoutMs) {
|
|
75
98
|
const expected = normalizeIdentifier(configuredIdentifier);
|
|
76
99
|
return await new Promise((resolve, reject) => {
|
|
@@ -111,3 +134,6 @@ export class NobleTransport {
|
|
|
111
134
|
});
|
|
112
135
|
}
|
|
113
136
|
}
|
|
137
|
+
function errorMessage(error) {
|
|
138
|
+
return error instanceof Error ? error.message : String(error);
|
|
139
|
+
}
|
package/dist/platform.js
CHANGED
|
@@ -40,7 +40,7 @@ export class PitPatPlatform {
|
|
|
40
40
|
accessory = new this.api.platformAccessory(config.name, uuid, 3 /* this.api.hap.Categories.FAN */);
|
|
41
41
|
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
|
|
42
42
|
}
|
|
43
|
-
this.bleManager = new BleManager(config, new NobleTransport(), this.log);
|
|
43
|
+
this.bleManager = new BleManager(config, new NobleTransport(this.log), this.log);
|
|
44
44
|
new TreadmillAccessory(accessory, this.bleManager, config, this.api, this.log);
|
|
45
45
|
void this.bleManager.start().catch(() => undefined);
|
|
46
46
|
const staleAccessories = [...this.cachedAccessories.values()].filter((cached) => cached.UUID !== uuid);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-pitpat-treadmill",
|
|
3
3
|
"displayName": "PitPat Treadmill",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.3",
|
|
5
5
|
"description": "Local Homebridge integration for PitPat treadmills over Bluetooth Low Energy.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|