homebridge-bedjet 0.1.6 → 0.1.8

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "homebridge-bedjet",
3
3
  "displayName": "BedJet",
4
- "version": "0.1.6",
4
+ "version": "0.1.8",
5
5
  "description": "Homebridge plugin for BedJet V3 via Bluetooth LE",
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
@@ -149,28 +149,26 @@ export class BedJet extends EventEmitter {
149
149
 
150
150
  peripheral.once('disconnect', () => this._onDisconnected());
151
151
 
152
- await peripheral.connectAsync();
152
+ try {
153
+ await peripheral.connectAsync();
154
+ } catch (err) {
155
+ throw new Error(`[${this.config.name}] connectAsync failed: ${err}`);
156
+ }
153
157
  this.log.info(`[${this.config.name}] Connected — discovering services…`);
154
158
 
155
- // discoverAllServicesAndCharacteristicsAsync can hang on Linux/BlueZ even after
156
- // returning characteristics — use the callback API directly instead.
157
- const characteristics = await new Promise<Characteristic[]>((resolve, reject) => {
158
- const timer = setTimeout(() =>
159
- reject(new Error(`[${this.config.name}] Service discovery timed out`)), 10_000);
160
- peripheral.discoverAllServicesAndCharacteristics((err, _services, chars) => {
161
- clearTimeout(timer);
162
- if (err) {
163
- reject(new Error(`[${this.config.name}] Discovery error: ${err}`));
164
- } else {
165
- resolve(chars ?? []);
166
- }
167
- });
168
- });
159
+ // Use async discovery — works on Linux when the device is already bonded
160
+ let characteristics: Characteristic[];
161
+ try {
162
+ const result = await peripheral.discoverAllServicesAndCharacteristicsAsync();
163
+ characteristics = result.characteristics;
164
+ } catch (err) {
165
+ throw new Error(`[${this.config.name}] discoverAllServices failed: ${err}`);
166
+ }
169
167
 
170
168
  this.log.info(`[${this.config.name}] Found ${characteristics.length} characteristics`);
171
169
  for (const char of characteristics) {
172
170
  const uuid = normalize(char.uuid);
173
- this.log.debug(`[${this.config.name}] char: ${uuid}`);
171
+ this.log.info(`[${this.config.name}] char: ${uuid}`);
174
172
  if (uuid === NORM_STATUS_UUID) {
175
173
  this.statusChar = char;
176
174
  this.log.info(`[${this.config.name}] Found status characteristic`);
@@ -180,32 +178,37 @@ export class BedJet extends EventEmitter {
180
178
  }
181
179
  }
182
180
 
181
+ // Small delay to let noble/BlueZ internal events settle after discovery
182
+ await new Promise<void>(resolve => setTimeout(resolve, 500));
183
+
184
+ this.log.info(`[${this.config.name}] Char check: status=${!!this.statusChar} command=${!!this.commandChar}`);
185
+
183
186
  if (!this.commandChar || !this.statusChar) {
184
- throw new Error(`[${this.config.name}] Required characteristics not found (status=${!!this.statusChar} command=${!!this.commandChar})`);
187
+ throw new Error(`[${this.config.name}] Required characteristics not found`);
185
188
  }
186
189
 
187
190
  // Subscribe to notifications on the status characteristic
188
191
  this.log.info(`[${this.config.name}] Subscribing to notifications…`);
189
- const statusChar = this.statusChar;
190
- await new Promise<void>((resolve, reject) => {
191
- const timer = setTimeout(() =>
192
- reject(new Error(`[${this.config.name}] Subscribe timed out`)), 10_000);
193
- statusChar.subscribe((err) => {
194
- clearTimeout(timer);
195
- if (err) {
196
- reject(new Error(`[${this.config.name}] Subscribe error: ${err}`));
197
- } else {
198
- resolve();
199
- }
200
- });
201
- });
192
+ try {
193
+ await this.statusChar.subscribeAsync();
194
+ } catch (err) {
195
+ throw new Error(`[${this.config.name}] subscribeAsync failed: ${err}`);
196
+ }
202
197
  this.log.info(`[${this.config.name}] Subscribed — reading device status…`);
203
198
  this.statusChar.on('data', (data: Buffer) => this._handleNotification(data));
204
199
 
205
200
  // Read extended status and device name
206
- await this._readDeviceStatus();
201
+ try {
202
+ await this._readDeviceStatus();
203
+ } catch (err) {
204
+ this.log.warn(`[${this.config.name}] _readDeviceStatus failed: ${err}`);
205
+ }
207
206
  this.log.info(`[${this.config.name}] Reading device name…`);
208
- await this._readDeviceName();
207
+ try {
208
+ await this._readDeviceName();
209
+ } catch (err) {
210
+ this.log.warn(`[${this.config.name}] _readDeviceName failed: ${err}`);
211
+ }
209
212
 
210
213
  this.reconnectAttempts = 0;
211
214
  this._state = { ...this._state, isConnected: true };