homebridge-bedjet 0.1.7 → 0.2.0
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/dist/bedjet/BedJet.d.ts +9 -11
- package/dist/bedjet/BedJet.js +101 -183
- package/dist/bedjet/BedJet.js.map +1 -1
- package/package.json +2 -2
- package/src/bedjet/BedJet.ts +114 -228
package/dist/bedjet/BedJet.d.ts
CHANGED
|
@@ -5,27 +5,24 @@ import type { BedJetConfig, BedJetState } from './types';
|
|
|
5
5
|
export declare class BedJet extends EventEmitter {
|
|
6
6
|
private readonly config;
|
|
7
7
|
private readonly log;
|
|
8
|
-
private peripheral;
|
|
9
|
-
private commandChar;
|
|
10
|
-
private statusChar;
|
|
11
|
-
private disconnectTimer;
|
|
12
|
-
private staleTimer;
|
|
13
|
-
private reconnectAttempts;
|
|
14
|
-
private connecting;
|
|
15
8
|
private _state;
|
|
16
9
|
private deviceName;
|
|
17
10
|
private firmwareVersion;
|
|
11
|
+
private reconnectAttempts;
|
|
12
|
+
private connecting;
|
|
13
|
+
private destroyed;
|
|
14
|
+
private bleDestroy;
|
|
15
|
+
private commandChar;
|
|
16
|
+
private disconnectTimer;
|
|
17
|
+
private staleTimer;
|
|
18
18
|
constructor(config: BedJetConfig, log: Logger);
|
|
19
19
|
get state(): BedJetState;
|
|
20
20
|
get name(): string;
|
|
21
21
|
get firmware(): string | null;
|
|
22
22
|
connect(): Promise<void>;
|
|
23
|
-
private
|
|
24
|
-
private _connectPeripheral;
|
|
23
|
+
private _doConnect;
|
|
25
24
|
private _handleNotification;
|
|
26
25
|
private _handleStatusRead;
|
|
27
|
-
private _readDeviceName;
|
|
28
|
-
private _readDeviceStatus;
|
|
29
26
|
private _sendCommand;
|
|
30
27
|
setTemperature(celsius: number): Promise<void>;
|
|
31
28
|
setFanSpeed(percent: number): Promise<void>;
|
|
@@ -38,5 +35,6 @@ export declare class BedJet extends EventEmitter {
|
|
|
38
35
|
private _resetDisconnectTimer;
|
|
39
36
|
private _resetStaleTimer;
|
|
40
37
|
private _onDisconnected;
|
|
38
|
+
private _scheduleReconnect;
|
|
41
39
|
disconnect(): Promise<void>;
|
|
42
40
|
}
|
package/dist/bedjet/BedJet.js
CHANGED
|
@@ -2,159 +2,112 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BedJet = void 0;
|
|
4
4
|
const events_1 = require("events");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
8
|
-
const noble = require('@abandonware/noble');
|
|
5
|
+
const NodeBle = require("node-ble");
|
|
6
|
+
const { createBluetooth } = NodeBle;
|
|
9
7
|
const constants_1 = require("./constants");
|
|
10
8
|
const types_1 = require("./types");
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
const NORM_STATUS_UUID = normalize(constants_1.BEDJET3_STATUS_UUID);
|
|
14
|
-
const NORM_NAME_UUID = normalize(constants_1.BEDJET3_NAME_UUID);
|
|
15
|
-
const NORM_COMMAND_UUID = normalize(constants_1.BEDJET3_COMMAND_UUID);
|
|
16
|
-
const NORM_SERVICE_UUID = normalize(constants_1.BEDJET3_SERVICE_UUID);
|
|
9
|
+
// node-ble uses BlueZ D-Bus — works alongside BlueZ without raw HCI conflicts.
|
|
10
|
+
// This mirrors how Python bleak / Home Assistant ha-bedjet connects.
|
|
17
11
|
class BedJet extends events_1.EventEmitter {
|
|
18
12
|
constructor(config, log) {
|
|
19
13
|
super();
|
|
20
14
|
this.config = config;
|
|
21
15
|
this.log = log;
|
|
22
|
-
this.peripheral = null;
|
|
23
|
-
this.commandChar = null;
|
|
24
|
-
this.statusChar = null;
|
|
25
|
-
this.disconnectTimer = null;
|
|
26
|
-
this.staleTimer = null;
|
|
27
|
-
this.reconnectAttempts = 0;
|
|
28
|
-
this.connecting = false;
|
|
29
16
|
this._state = { ...types_1.DEFAULT_STATE };
|
|
30
17
|
this.deviceName = null;
|
|
31
18
|
this.firmwareVersion = null;
|
|
19
|
+
this.reconnectAttempts = 0;
|
|
20
|
+
this.connecting = false;
|
|
21
|
+
this.destroyed = false;
|
|
22
|
+
this.bleDestroy = null;
|
|
23
|
+
this.commandChar = null;
|
|
24
|
+
this.disconnectTimer = null;
|
|
25
|
+
this.staleTimer = null;
|
|
32
26
|
}
|
|
33
|
-
get state() {
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return this.deviceName ?? this.config.name;
|
|
38
|
-
}
|
|
39
|
-
get firmware() {
|
|
40
|
-
return this.firmwareVersion;
|
|
41
|
-
}
|
|
42
|
-
// ── Connection ────────────────────────────────────────────────────────────
|
|
27
|
+
get state() { return this._state; }
|
|
28
|
+
get name() { return this.deviceName ?? this.config.name; }
|
|
29
|
+
get firmware() { return this.firmwareVersion; }
|
|
30
|
+
// ── Connection ─────────────────────────────────────────────────────────────
|
|
43
31
|
async connect() {
|
|
44
|
-
if (this.connecting) {
|
|
32
|
+
if (this.connecting || this.destroyed) {
|
|
45
33
|
return;
|
|
46
34
|
}
|
|
47
35
|
this.connecting = true;
|
|
48
36
|
try {
|
|
49
|
-
await this.
|
|
37
|
+
await this._doConnect();
|
|
50
38
|
}
|
|
51
39
|
catch (err) {
|
|
40
|
+
this.log.error(`[${this.config.name}] Connect failed: ${err}`);
|
|
41
|
+
this._scheduleReconnect();
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
52
44
|
this.connecting = false;
|
|
53
|
-
throw err;
|
|
54
45
|
}
|
|
55
|
-
this.connecting = false;
|
|
56
46
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const targetNorm = this.config.address.toLowerCase().replace(/:/g, '').replace(/-/g, '');
|
|
63
|
-
const timeoutMs = (this.config.scanTimeout ?? 30) * 1000;
|
|
64
|
-
const scanTimeout = setTimeout(() => {
|
|
65
|
-
noble.stopScanning();
|
|
66
|
-
noble.removeListener('discover', onDiscover);
|
|
67
|
-
reject(new Error(`[${this.config.name}] Scan timed out after ${this.config.scanTimeout ?? 30}s`));
|
|
68
|
-
}, timeoutMs);
|
|
69
|
-
const onDiscover = async (peripheral) => {
|
|
70
|
-
const addrNorm = peripheral.address.toLowerCase().replace(/:/g, '').replace(/-/g, '');
|
|
71
|
-
const uuidNorm = (peripheral.uuid ?? '').toLowerCase().replace(/-/g, '');
|
|
72
|
-
if (addrNorm !== targetNorm && uuidNorm !== targetNorm) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
clearTimeout(scanTimeout);
|
|
76
|
-
noble.stopScanning();
|
|
77
|
-
noble.removeListener('discover', onDiscover);
|
|
78
|
-
try {
|
|
79
|
-
await this._connectPeripheral(peripheral);
|
|
80
|
-
resolve();
|
|
81
|
-
}
|
|
82
|
-
catch (err) {
|
|
83
|
-
reject(err);
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
noble.on('discover', onDiscover);
|
|
87
|
-
const startScan = () => {
|
|
88
|
-
// Scan with no service UUID filter — BlueZ on Linux silently drops devices
|
|
89
|
-
// when filtering by 128-bit custom UUIDs. We match by address in onDiscover instead.
|
|
90
|
-
noble.startScanning([], false, (err) => {
|
|
91
|
-
if (err) {
|
|
92
|
-
clearTimeout(scanTimeout);
|
|
93
|
-
noble.removeListener('discover', onDiscover);
|
|
94
|
-
reject(new Error(`[${this.config.name}] startScanning failed: ${err}`));
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
};
|
|
98
|
-
if (noble.state === 'poweredOn') {
|
|
99
|
-
startScan();
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
noble.once('stateChange', (state) => {
|
|
103
|
-
if (state === 'poweredOn') {
|
|
104
|
-
startScan();
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
clearTimeout(scanTimeout);
|
|
108
|
-
noble.removeListener('discover', onDiscover);
|
|
109
|
-
reject(new Error(`[${this.config.name}] Bluetooth not available (state: ${state})`));
|
|
110
|
-
}
|
|
111
|
-
});
|
|
47
|
+
async _doConnect() {
|
|
48
|
+
// Clean up any previous bluetooth instance
|
|
49
|
+
if (this.bleDestroy) {
|
|
50
|
+
try {
|
|
51
|
+
this.bleDestroy();
|
|
112
52
|
}
|
|
53
|
+
catch { /* ignore */ }
|
|
54
|
+
this.bleDestroy = null;
|
|
55
|
+
}
|
|
56
|
+
const { bluetooth, destroy } = createBluetooth();
|
|
57
|
+
this.bleDestroy = destroy;
|
|
58
|
+
this.log.info(`[${this.config.name}] Getting Bluetooth adapter…`);
|
|
59
|
+
const adapter = await bluetooth.defaultAdapter();
|
|
60
|
+
if (!await adapter.isDiscovering()) {
|
|
61
|
+
await adapter.startDiscovery();
|
|
62
|
+
}
|
|
63
|
+
const timeoutMs = (this.config.scanTimeout ?? 30) * 1000;
|
|
64
|
+
this.log.info(`[${this.config.name}] Waiting for device ${this.config.address}…`);
|
|
65
|
+
const device = await adapter.waitDevice(this.config.address.toUpperCase(), timeoutMs);
|
|
66
|
+
await adapter.stopDiscovery().catch(() => { });
|
|
67
|
+
this.log.info(`[${this.config.name}] Connecting…`);
|
|
68
|
+
await device.connect();
|
|
69
|
+
this.log.info(`[${this.config.name}] Connected — getting GATT server…`);
|
|
70
|
+
device.on('disconnect', () => {
|
|
71
|
+
this.log.warn(`[${this.config.name}] Device disconnected`);
|
|
72
|
+
this._onDisconnected();
|
|
113
73
|
});
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
this.log.info(`[${this.config.name}]
|
|
118
|
-
|
|
119
|
-
await
|
|
120
|
-
this.log.info(`[${this.config.name}]
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
this.log.
|
|
131
|
-
if (uuid === NORM_STATUS_UUID) {
|
|
132
|
-
this.statusChar = char;
|
|
133
|
-
this.log.info(`[${this.config.name}] Found status characteristic`);
|
|
134
|
-
}
|
|
135
|
-
else if (uuid === NORM_COMMAND_UUID) {
|
|
136
|
-
this.commandChar = char;
|
|
137
|
-
this.log.info(`[${this.config.name}] Found command characteristic`);
|
|
138
|
-
}
|
|
74
|
+
const gatt = await device.gatt();
|
|
75
|
+
this.log.info(`[${this.config.name}] Got GATT server — getting BedJet service…`);
|
|
76
|
+
const service = await gatt.getPrimaryService(constants_1.BEDJET3_SERVICE_UUID);
|
|
77
|
+
this.log.info(`[${this.config.name}] Got service — getting characteristics…`);
|
|
78
|
+
const statusChar = await service.getCharacteristic(constants_1.BEDJET3_STATUS_UUID);
|
|
79
|
+
this.commandChar = await service.getCharacteristic(constants_1.BEDJET3_COMMAND_UUID);
|
|
80
|
+
this.log.info(`[${this.config.name}] Got characteristics — subscribing to notifications…`);
|
|
81
|
+
await statusChar.startNotifications();
|
|
82
|
+
statusChar.on('valuechanged', (buf) => this._handleNotification(buf));
|
|
83
|
+
this.log.info(`[${this.config.name}] Subscribed — reading initial state…`);
|
|
84
|
+
// Read the 11-byte status characteristic directly
|
|
85
|
+
try {
|
|
86
|
+
const statusData = await statusChar.readValue();
|
|
87
|
+
this._handleStatusRead(statusData);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
this.log.warn(`[${this.config.name}] Could not read device status: ${err}`);
|
|
139
91
|
}
|
|
140
|
-
|
|
141
|
-
|
|
92
|
+
// Read device name
|
|
93
|
+
try {
|
|
94
|
+
const nameChar = await service.getCharacteristic(constants_1.BEDJET3_NAME_UUID);
|
|
95
|
+
const nameData = await nameChar.readValue();
|
|
96
|
+
this.deviceName = nameData.toString('utf8').replace(/\0/g, '').trim();
|
|
97
|
+
this.log.info(`[${this.config.name}] Device name: ${this.deviceName}`);
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
this.log.warn(`[${this.config.name}] Could not read device name: ${err}`);
|
|
142
101
|
}
|
|
143
|
-
// Subscribe to notifications on the status characteristic
|
|
144
|
-
await this.statusChar.subscribeAsync();
|
|
145
|
-
this.statusChar.on('data', (data) => this._handleNotification(data));
|
|
146
|
-
// Read extended status and device name
|
|
147
|
-
await this._readDeviceStatus();
|
|
148
|
-
await this._readDeviceName();
|
|
149
102
|
this.reconnectAttempts = 0;
|
|
150
103
|
this._state = { ...this._state, isConnected: true };
|
|
151
104
|
this._resetDisconnectTimer();
|
|
152
105
|
this._resetStaleTimer();
|
|
153
106
|
this.emit('connected');
|
|
154
107
|
this.emit('stateChange', this._state);
|
|
155
|
-
this.log.info(`[${this.config.name}] Ready
|
|
108
|
+
this.log.info(`[${this.config.name}] Ready`);
|
|
156
109
|
}
|
|
157
|
-
// ── Packet parsing
|
|
110
|
+
// ── Packet parsing ──────────────────────────────────────────────────────────
|
|
158
111
|
_handleNotification(data) {
|
|
159
112
|
if (data.length !== constants_1.BEDJET3_NOTIFICATION_LENGTH) {
|
|
160
113
|
return;
|
|
@@ -168,13 +121,10 @@ class BedJet extends events_1.EventEmitter {
|
|
|
168
121
|
targetTemperature: data[8] / 2,
|
|
169
122
|
operatingMode: data[9],
|
|
170
123
|
fanSpeed: (data[10] + 1) * 5,
|
|
171
|
-
// data[11] = maximum_hours, data[12] = maximum_minutes (not stored in state)
|
|
172
124
|
minimumTemperature: data[13] / 2,
|
|
173
125
|
maximumTemperature: data[14] / 2,
|
|
174
|
-
// bytes [15–16] = turbo_time uint16 big-endian
|
|
175
126
|
turboTimeSeconds: (data[15] << 8) | data[16],
|
|
176
127
|
ambientTemperature: data[17] / 2,
|
|
177
|
-
// data[18] = shutdown_reason (not stored)
|
|
178
128
|
isConnected: true,
|
|
179
129
|
};
|
|
180
130
|
this._resetStaleTimer();
|
|
@@ -188,7 +138,6 @@ class BedJet extends events_1.EventEmitter {
|
|
|
188
138
|
this._state = {
|
|
189
139
|
...this._state,
|
|
190
140
|
isDualZone: (data[2] & 0x02) !== 0,
|
|
191
|
-
// flags bits MSB→LSB: [_, _, connTestPassed, ledEnabled, _, unitsSetup, _, beepsMuted]
|
|
192
141
|
connTestPassed: (flags & 0x20) !== 0,
|
|
193
142
|
ledEnabled: (flags & 0x10) !== 0,
|
|
194
143
|
unitsSetup: (flags & 0x04) !== 0,
|
|
@@ -196,45 +145,15 @@ class BedJet extends events_1.EventEmitter {
|
|
|
196
145
|
notificationCode: data[9],
|
|
197
146
|
};
|
|
198
147
|
}
|
|
199
|
-
|
|
200
|
-
if (!this.peripheral) {
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
try {
|
|
204
|
-
// Rediscover to get the name characteristic
|
|
205
|
-
const { characteristics } = await this.peripheral.discoverSomeServicesAndCharacteristicsAsync([NORM_SERVICE_UUID], [NORM_NAME_UUID]);
|
|
206
|
-
const nameChar = characteristics.find(c => normalize(c.uuid) === NORM_NAME_UUID);
|
|
207
|
-
if (nameChar) {
|
|
208
|
-
const data = await nameChar.readAsync();
|
|
209
|
-
this.deviceName = data.toString('utf8').replace(/\0/g, '').trim();
|
|
210
|
-
this.log.debug(`[${this.config.name}] Device name: ${this.deviceName}`);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
catch (err) {
|
|
214
|
-
this.log.warn(`[${this.config.name}] Could not read device name: ${err}`);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
async _readDeviceStatus() {
|
|
218
|
-
if (!this.statusChar) {
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
try {
|
|
222
|
-
const data = await this.statusChar.readAsync();
|
|
223
|
-
this._handleStatusRead(data);
|
|
224
|
-
}
|
|
225
|
-
catch (err) {
|
|
226
|
-
this.log.warn(`[${this.config.name}] Could not read device status: ${err}`);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
// ── Commands ──────────────────────────────────────────────────────────────
|
|
148
|
+
// ── Commands ────────────────────────────────────────────────────────────────
|
|
230
149
|
async _sendCommand(command, ...args) {
|
|
231
150
|
if (!this.commandChar) {
|
|
232
151
|
throw new Error(`[${this.config.name}] Not connected`);
|
|
233
152
|
}
|
|
234
153
|
const buf = Buffer.from([command, ...args]);
|
|
235
154
|
try {
|
|
236
|
-
//
|
|
237
|
-
await this.commandChar.
|
|
155
|
+
// writeValueWithResponse = write with response, required for BedJet V3
|
|
156
|
+
await this.commandChar.writeValueWithResponse(buf);
|
|
238
157
|
this._resetDisconnectTimer();
|
|
239
158
|
}
|
|
240
159
|
catch (err) {
|
|
@@ -267,7 +186,7 @@ class BedJet extends events_1.EventEmitter {
|
|
|
267
186
|
async setMuted(muted) {
|
|
268
187
|
await this.pressButton(muted ? constants_1.BedJetButton.MUTE : constants_1.BedJetButton.UNMUTE);
|
|
269
188
|
}
|
|
270
|
-
// ── Timers
|
|
189
|
+
// ── Timers ──────────────────────────────────────────────────────────────────
|
|
271
190
|
_resetDisconnectTimer() {
|
|
272
191
|
if (this.disconnectTimer) {
|
|
273
192
|
clearTimeout(this.disconnectTimer);
|
|
@@ -277,7 +196,6 @@ class BedJet extends events_1.EventEmitter {
|
|
|
277
196
|
await this.disconnect();
|
|
278
197
|
}, constants_1.DISCONNECT_DELAY_MS);
|
|
279
198
|
}
|
|
280
|
-
// Mark stale and update HomeKit if no notification arrives within 65s
|
|
281
199
|
_resetStaleTimer() {
|
|
282
200
|
if (this.staleTimer) {
|
|
283
201
|
clearTimeout(this.staleTimer);
|
|
@@ -288,10 +206,9 @@ class BedJet extends events_1.EventEmitter {
|
|
|
288
206
|
this.emit('stateChange', this._state);
|
|
289
207
|
}, 65000);
|
|
290
208
|
}
|
|
291
|
-
// ── Disconnect / reconnect
|
|
209
|
+
// ── Disconnect / reconnect ──────────────────────────────────────────────────
|
|
292
210
|
_onDisconnected() {
|
|
293
211
|
this.commandChar = null;
|
|
294
|
-
this.statusChar = null;
|
|
295
212
|
if (this.disconnectTimer) {
|
|
296
213
|
clearTimeout(this.disconnectTimer);
|
|
297
214
|
this.disconnectTimer = null;
|
|
@@ -303,22 +220,27 @@ class BedJet extends events_1.EventEmitter {
|
|
|
303
220
|
this._state = { ...this._state, isConnected: false };
|
|
304
221
|
this.emit('disconnected');
|
|
305
222
|
this.emit('stateChange', this._state);
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
`
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
else {
|
|
317
|
-
this.log.error(`[${this.config.name}] Max reconnect attempts reached — giving up`);
|
|
318
|
-
this.emit('maxReconnectReached');
|
|
223
|
+
this._scheduleReconnect();
|
|
224
|
+
}
|
|
225
|
+
_scheduleReconnect() {
|
|
226
|
+
if (this.destroyed || this.reconnectAttempts >= constants_1.MAX_RECONNECT_ATTEMPTS) {
|
|
227
|
+
if (!this.destroyed && this.reconnectAttempts >= constants_1.MAX_RECONNECT_ATTEMPTS) {
|
|
228
|
+
this.log.error(`[${this.config.name}] Max reconnect attempts reached`);
|
|
229
|
+
this.emit('maxReconnectReached');
|
|
230
|
+
}
|
|
231
|
+
return;
|
|
319
232
|
}
|
|
233
|
+
const delay = Math.pow(2, this.reconnectAttempts + 1) * 1000;
|
|
234
|
+
this.reconnectAttempts++;
|
|
235
|
+
this.log.info(`[${this.config.name}] Reconnecting in ${delay / 1000}s ` +
|
|
236
|
+
`(attempt ${this.reconnectAttempts}/${constants_1.MAX_RECONNECT_ATTEMPTS})`);
|
|
237
|
+
setTimeout(() => {
|
|
238
|
+
this.connect().catch(err => this.log.error(`[${this.config.name}] Reconnect failed: ${err}`));
|
|
239
|
+
}, delay);
|
|
320
240
|
}
|
|
321
241
|
async disconnect() {
|
|
242
|
+
this.destroyed = true;
|
|
243
|
+
this.commandChar = null;
|
|
322
244
|
if (this.disconnectTimer) {
|
|
323
245
|
clearTimeout(this.disconnectTimer);
|
|
324
246
|
this.disconnectTimer = null;
|
|
@@ -327,16 +249,12 @@ class BedJet extends events_1.EventEmitter {
|
|
|
327
249
|
clearTimeout(this.staleTimer);
|
|
328
250
|
this.staleTimer = null;
|
|
329
251
|
}
|
|
330
|
-
|
|
331
|
-
this.reconnectAttempts = constants_1.MAX_RECONNECT_ATTEMPTS;
|
|
332
|
-
if (this.peripheral) {
|
|
252
|
+
if (this.bleDestroy) {
|
|
333
253
|
try {
|
|
334
|
-
|
|
335
|
-
}
|
|
336
|
-
catch {
|
|
337
|
-
// ignore errors during intentional disconnect
|
|
254
|
+
this.bleDestroy();
|
|
338
255
|
}
|
|
339
|
-
|
|
256
|
+
catch { /* ignore */ }
|
|
257
|
+
this.bleDestroy = null;
|
|
340
258
|
}
|
|
341
259
|
}
|
|
342
260
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BedJet.js","sourceRoot":"","sources":["../../src/bedjet/BedJet.ts"],"names":[],"mappings":";;;AAAA,mCAAsC;AAItC,mFAAmF;AACnF,iFAAiF;AACjF,iEAAiE;AACjE,MAAM,KAAK,GAAG,OAAO,CAAC,oBAAoB,CAA4D,CAAC;AACvG,2CAaqB;AAErB,mCAAwC;AAExC,6CAA6C;AAC7C,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AAEzE,MAAM,gBAAgB,GAAI,SAAS,CAAC,+BAAmB,CAAC,CAAC;AACzD,MAAM,cAAc,GAAM,SAAS,CAAC,6BAAiB,CAAC,CAAC;AACvD,MAAM,iBAAiB,GAAG,SAAS,CAAC,gCAAoB,CAAC,CAAC;AAC1D,MAAM,iBAAiB,GAAG,SAAS,CAAC,gCAAoB,CAAC,CAAC;AAE1D,MAAa,MAAO,SAAQ,qBAAY;IAYtC,YACmB,MAAoB,EACpB,GAAW;QAE5B,KAAK,EAAE,CAAC;QAHS,WAAM,GAAN,MAAM,CAAc;QACpB,QAAG,GAAH,GAAG,CAAQ;QAbtB,eAAU,GAAsB,IAAI,CAAC;QACrC,gBAAW,GAA0B,IAAI,CAAC;QAC1C,eAAU,GAA0B,IAAI,CAAC;QACzC,oBAAe,GAA0B,IAAI,CAAC;QAC9C,eAAU,GAA0B,IAAI,CAAC;QACzC,sBAAiB,GAAG,CAAC,CAAC;QACtB,eAAU,GAAG,KAAK,CAAC;QACnB,WAAM,GAAgB,EAAE,GAAG,qBAAa,EAAE,CAAC;QAC3C,eAAU,GAAkB,IAAI,CAAC;QACjC,oBAAe,GAAkB,IAAI,CAAC;IAO9C,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC7C,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED,6EAA6E;IAE7E,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC1B,CAAC;IAEO,KAAK;QACX,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,wEAAwE;YACxE,oEAAoE;YACpE,0EAA0E;YAC1E,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACzF,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;YAEzD,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE;gBAClC,KAAK,CAAC,YAAY,EAAE,CAAC;gBACrB,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;gBAC7C,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,0BAA0B,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;YACpG,CAAC,EAAE,SAAS,CAAC,CAAC;YAEd,MAAM,UAAU,GAAG,KAAK,EAAE,UAAsB,EAAE,EAAE;gBAClD,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACtF,MAAM,QAAQ,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACzE,IAAI,QAAQ,KAAK,UAAU,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACvD,OAAO;gBACT,CAAC;gBAED,YAAY,CAAC,WAAW,CAAC,CAAC;gBAC1B,KAAK,CAAC,YAAY,EAAE,CAAC;gBACrB,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;gBAE7C,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;oBAC1C,OAAO,EAAE,CAAC;gBACZ,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC;YACH,CAAC,CAAC;YAEF,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAEjC,MAAM,SAAS,GAAG,GAAG,EAAE;gBACrB,2EAA2E;gBAC3E,qFAAqF;gBACrF,KAAK,CAAC,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;oBACrC,IAAI,GAAG,EAAE,CAAC;wBACR,YAAY,CAAC,WAAW,CAAC,CAAC;wBAC1B,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;wBAC7C,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,2BAA2B,GAAG,EAAE,CAAC,CAAC,CAAC;oBAC1E,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CAAC;YAEF,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;gBAChC,SAAS,EAAE,CAAC;YACd,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;oBAClC,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;wBAC1B,SAAS,EAAE,CAAC;oBACd,CAAC;yBAAM,CAAC;wBACN,YAAY,CAAC,WAAW,CAAC,CAAC;wBAC1B,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;wBAC7C,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,qCAAqC,KAAK,GAAG,CAAC,CAAC,CAAC;oBACvF,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,UAAsB;QACrD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,mBAAmB,UAAU,CAAC,OAAO,GAAG,CAAC,CAAC;QAE5E,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;QAE5D,MAAM,UAAU,CAAC,YAAY,EAAE,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,qCAAqC,CAAC,CAAC;QAEzE,6EAA6E;QAC7E,0DAA0D;QAC1D,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAC7C,UAAU,CAAC,0CAA0C,EAAE;YACvD,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,+BAA+B,CAAC,CAAC,EAAE,KAAM,CAAC,CACjG;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,WAAW,eAAe,CAAC,MAAM,kBAAkB,CAAC,CAAC;QACvF,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,aAAa,IAAI,EAAE,CAAC,CAAC;YACxD,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBAC9B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,+BAA+B,CAAC,CAAC;YACrE,CAAC;iBAAM,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBACtC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;gBACxB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,gCAAgC,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,gDAAgD,CAAC,CAAC,IAAI,CAAC,UAAU,YAAY,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QAC1I,CAAC;QAED,0DAA0D;QAC1D,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC;QACvC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;QAE7E,uCAAuC;QACvC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/B,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAE7B,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QACpD,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7B,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAExB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAEtC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,sBAAsB,IAAI,CAAC,eAAe,IAAI,SAAS,GAAG,CAAC,CAAC;IAChG,CAAC;IAED,6EAA6E;IAErE,mBAAmB,CAAC,IAAY;QACtC,IAAI,IAAI,CAAC,MAAM,KAAK,uCAA2B,EAAE,CAAC;YAChD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,GAAG;YACZ,GAAG,IAAI,CAAC,MAAM;YACd,cAAc,EAAM,IAAI,CAAC,CAAC,CAAC;YAC3B,gBAAgB,EAAI,IAAI,CAAC,CAAC,CAAC;YAC3B,gBAAgB,EAAI,IAAI,CAAC,CAAC,CAAC;YAC3B,kBAAkB,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;YAC/B,iBAAiB,EAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;YAC/B,aAAa,EAAO,IAAI,CAAC,CAAC,CAAkB;YAC5C,QAAQ,EAAY,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;YACtC,6EAA6E;YAC7E,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;YAChC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;YAChC,+CAA+C;YAC/C,gBAAgB,EAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;YAC9C,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;YAChC,0CAA0C;YAC1C,WAAW,EAAE,IAAI;SAClB,CAAC;QAEF,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAEO,iBAAiB,CAAC,IAAY;QACpC,IAAI,IAAI,CAAC,MAAM,KAAK,iCAAqB,EAAE,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG;YACZ,GAAG,IAAI,CAAC,MAAM;YACd,UAAU,EAAK,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;YACrC,uFAAuF;YACvF,cAAc,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACpC,UAAU,EAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACpC,UAAU,EAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACpC,UAAU,EAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACpC,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC;SAC1B,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,4CAA4C;YAC5C,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,2CAA2C,CAC3F,CAAC,iBAAiB,CAAC,EACnB,CAAC,cAAc,CAAC,CACjB,CAAC;YACF,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,cAAc,CAAC,CAAC;YACjF,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,CAAC;gBACxC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBAClE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,kBAAkB,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,iCAAiC,GAAG,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;YAC/C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,mCAAmC,GAAG,EAAE,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,6EAA6E;IAErE,KAAK,CAAC,YAAY,CAAC,OAAsB,EAAE,GAAG,IAAc;QAClE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,iBAAiB,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC;YACH,kEAAkE;YAClE,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC9C,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,eAAe,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;YACzF,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAAe;QAClC,MAAM,IAAI,CAAC,YAAY,CAAC,yBAAa,CAAC,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAe;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACpE,MAAM,IAAI,CAAC,YAAY,CAAC,yBAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,IAAmB;QACxC,MAAM,IAAI,CAAC,YAAY,CAAC,yBAAa,CAAC,MAAM,EAAE,qCAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;IACjF,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAoB;QACpC,MAAM,IAAI,CAAC,YAAY,CAAC,yBAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,MAAc;QACzC,MAAM,IAAI,CAAC,YAAY,CAAC,yBAAa,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,KAAa,EAAE,OAAe;QACtD,MAAM,IAAI,CAAC,YAAY,CAAC,yBAAa,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAW;QACtB,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,wBAAY,CAAC,MAAM,CAAC,CAAC,CAAC,wBAAY,CAAC,OAAO,CAAC,CAAC;IAC1E,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAc;QAC3B,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,wBAAY,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAY,CAAC,MAAM,CAAC,CAAC;IAC1E,CAAC;IAED,6EAA6E;IAErE,qBAAqB;QAC3B,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YAC3C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,sCAAsC,CAAC,CAAC;YAC3E,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAC1B,CAAC,EAAE,+BAAmB,CAAC,CAAC;IAC1B,CAAC;IAED,sEAAsE;IAC9D,gBAAgB;QACtB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,mDAAmD,CAAC,CAAC;YACvF,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;YACrD,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC,EAAE,KAAM,CAAC,CAAC;IACb,CAAC;IAED,6EAA6E;IAErE,eAAe;QACrB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACnC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;QACrD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAEtC,IAAI,IAAI,CAAC,iBAAiB,GAAG,kCAAsB,EAAE,CAAC;YACpD,4CAA4C;YAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;YAC7D,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,IAAI,CACX,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,oCAAoC,KAAK,GAAG,IAAI,IAAI;gBACxE,YAAY,IAAI,CAAC,iBAAiB,IAAI,kCAAsB,GAAG,CAChE,CAAC;YACF,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CACzB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,uBAAuB,GAAG,EAAE,CAAC,CACjE,CAAC;YACJ,CAAC,EAAE,KAAK,CAAC,CAAC;QACZ,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,8CAA8C,CAAC,CAAC;YACnF,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACnC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,mFAAmF;QACnF,IAAI,CAAC,iBAAiB,GAAG,kCAAsB,CAAC;QAChD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC;YAC1C,CAAC;YAAC,MAAM,CAAC;gBACP,8CAA8C;YAChD,CAAC;YACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;CACF;AA3XD,wBA2XC"}
|
|
1
|
+
{"version":3,"file":"BedJet.js","sourceRoot":"","sources":["../../src/bedjet/BedJet.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-bedjet",
|
|
3
3
|
"displayName": "BedJet",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"description": "Homebridge plugin for BedJet V3 via Bluetooth LE",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"main": "dist/index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"node": ">=18.0.0"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"
|
|
19
|
+
"node-ble": "^1.10.1"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/node": "^20.0.0",
|
package/src/bedjet/BedJet.ts
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import type { Peripheral, Characteristic } from '@abandonware/noble';
|
|
3
2
|
import type { Logger } from 'homebridge';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
// The default ESM export doesn't expose `.state` in its type — we patch it here.
|
|
7
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
8
|
-
const noble = require('@abandonware/noble') as typeof import('@abandonware/noble') & { state: string };
|
|
3
|
+
import NodeBle = require('node-ble');
|
|
4
|
+
const { createBluetooth } = NodeBle;
|
|
9
5
|
import {
|
|
10
6
|
BEDJET3_SERVICE_UUID,
|
|
11
7
|
BEDJET3_STATUS_UUID,
|
|
@@ -23,26 +19,23 @@ import {
|
|
|
23
19
|
import type { BedJetConfig, BedJetState } from './types';
|
|
24
20
|
import { DEFAULT_STATE } from './types';
|
|
25
21
|
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const NORM_STATUS_UUID = normalize(BEDJET3_STATUS_UUID);
|
|
30
|
-
const NORM_NAME_UUID = normalize(BEDJET3_NAME_UUID);
|
|
31
|
-
const NORM_COMMAND_UUID = normalize(BEDJET3_COMMAND_UUID);
|
|
32
|
-
const NORM_SERVICE_UUID = normalize(BEDJET3_SERVICE_UUID);
|
|
22
|
+
// node-ble uses BlueZ D-Bus — works alongside BlueZ without raw HCI conflicts.
|
|
23
|
+
// This mirrors how Python bleak / Home Assistant ha-bedjet connects.
|
|
33
24
|
|
|
34
25
|
export class BedJet extends EventEmitter {
|
|
35
|
-
private peripheral: Peripheral | null = null;
|
|
36
|
-
private commandChar: Characteristic | null = null;
|
|
37
|
-
private statusChar: Characteristic | null = null;
|
|
38
|
-
private disconnectTimer: NodeJS.Timeout | null = null;
|
|
39
|
-
private staleTimer: NodeJS.Timeout | null = null;
|
|
40
|
-
private reconnectAttempts = 0;
|
|
41
|
-
private connecting = false;
|
|
42
26
|
private _state: BedJetState = { ...DEFAULT_STATE };
|
|
43
27
|
private deviceName: string | null = null;
|
|
44
28
|
private firmwareVersion: string | null = null;
|
|
45
29
|
|
|
30
|
+
private reconnectAttempts = 0;
|
|
31
|
+
private connecting = false;
|
|
32
|
+
private destroyed = false;
|
|
33
|
+
|
|
34
|
+
private bleDestroy: (() => void) | null = null;
|
|
35
|
+
private commandChar: NodeBle.GattCharacteristic | null = null;
|
|
36
|
+
private disconnectTimer: NodeJS.Timeout | null = null;
|
|
37
|
+
private staleTimer: NodeJS.Timeout | null = null;
|
|
38
|
+
|
|
46
39
|
constructor(
|
|
47
40
|
private readonly config: BedJetConfig,
|
|
48
41
|
private readonly log: Logger,
|
|
@@ -50,161 +43,94 @@ export class BedJet extends EventEmitter {
|
|
|
50
43
|
super();
|
|
51
44
|
}
|
|
52
45
|
|
|
53
|
-
get state(): BedJetState {
|
|
54
|
-
|
|
55
|
-
}
|
|
46
|
+
get state(): BedJetState { return this._state; }
|
|
47
|
+
get name(): string { return this.deviceName ?? this.config.name; }
|
|
48
|
+
get firmware(): string | null { return this.firmwareVersion; }
|
|
56
49
|
|
|
57
|
-
|
|
58
|
-
return this.deviceName ?? this.config.name;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
get firmware(): string | null {
|
|
62
|
-
return this.firmwareVersion;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// ── Connection ────────────────────────────────────────────────────────────
|
|
50
|
+
// ── Connection ─────────────────────────────────────────────────────────────
|
|
66
51
|
|
|
67
52
|
async connect(): Promise<void> {
|
|
68
|
-
if (this.connecting) {
|
|
53
|
+
if (this.connecting || this.destroyed) {
|
|
69
54
|
return;
|
|
70
55
|
}
|
|
71
56
|
this.connecting = true;
|
|
72
|
-
|
|
73
57
|
try {
|
|
74
|
-
await this.
|
|
58
|
+
await this._doConnect();
|
|
75
59
|
} catch (err) {
|
|
60
|
+
this.log.error(`[${this.config.name}] Connect failed: ${err}`);
|
|
61
|
+
this._scheduleReconnect();
|
|
62
|
+
} finally {
|
|
76
63
|
this.connecting = false;
|
|
77
|
-
throw err;
|
|
78
64
|
}
|
|
79
|
-
|
|
80
|
-
this.connecting = false;
|
|
81
65
|
}
|
|
82
66
|
|
|
83
|
-
private
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const timeoutMs = (this.config.scanTimeout ?? 30) * 1000;
|
|
90
|
-
|
|
91
|
-
const scanTimeout = setTimeout(() => {
|
|
92
|
-
noble.stopScanning();
|
|
93
|
-
noble.removeListener('discover', onDiscover);
|
|
94
|
-
reject(new Error(`[${this.config.name}] Scan timed out after ${this.config.scanTimeout ?? 30}s`));
|
|
95
|
-
}, timeoutMs);
|
|
96
|
-
|
|
97
|
-
const onDiscover = async (peripheral: Peripheral) => {
|
|
98
|
-
const addrNorm = peripheral.address.toLowerCase().replace(/:/g, '').replace(/-/g, '');
|
|
99
|
-
const uuidNorm = (peripheral.uuid ?? '').toLowerCase().replace(/-/g, '');
|
|
100
|
-
if (addrNorm !== targetNorm && uuidNorm !== targetNorm) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
clearTimeout(scanTimeout);
|
|
105
|
-
noble.stopScanning();
|
|
106
|
-
noble.removeListener('discover', onDiscover);
|
|
107
|
-
|
|
108
|
-
try {
|
|
109
|
-
await this._connectPeripheral(peripheral);
|
|
110
|
-
resolve();
|
|
111
|
-
} catch (err) {
|
|
112
|
-
reject(err);
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
noble.on('discover', onDiscover);
|
|
117
|
-
|
|
118
|
-
const startScan = () => {
|
|
119
|
-
// Scan with no service UUID filter — BlueZ on Linux silently drops devices
|
|
120
|
-
// when filtering by 128-bit custom UUIDs. We match by address in onDiscover instead.
|
|
121
|
-
noble.startScanning([], false, (err) => {
|
|
122
|
-
if (err) {
|
|
123
|
-
clearTimeout(scanTimeout);
|
|
124
|
-
noble.removeListener('discover', onDiscover);
|
|
125
|
-
reject(new Error(`[${this.config.name}] startScanning failed: ${err}`));
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
if (noble.state === 'poweredOn') {
|
|
131
|
-
startScan();
|
|
132
|
-
} else {
|
|
133
|
-
noble.once('stateChange', (state) => {
|
|
134
|
-
if (state === 'poweredOn') {
|
|
135
|
-
startScan();
|
|
136
|
-
} else {
|
|
137
|
-
clearTimeout(scanTimeout);
|
|
138
|
-
noble.removeListener('discover', onDiscover);
|
|
139
|
-
reject(new Error(`[${this.config.name}] Bluetooth not available (state: ${state})`));
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
}
|
|
67
|
+
private async _doConnect(): Promise<void> {
|
|
68
|
+
// Clean up any previous bluetooth instance
|
|
69
|
+
if (this.bleDestroy) {
|
|
70
|
+
try { this.bleDestroy(); } catch { /* ignore */ }
|
|
71
|
+
this.bleDestroy = null;
|
|
72
|
+
}
|
|
145
73
|
|
|
146
|
-
|
|
147
|
-
this.
|
|
148
|
-
this.log.info(`[${this.config.name}] Connecting to ${peripheral.address}…`);
|
|
74
|
+
const { bluetooth, destroy } = createBluetooth();
|
|
75
|
+
this.bleDestroy = destroy;
|
|
149
76
|
|
|
150
|
-
|
|
77
|
+
this.log.info(`[${this.config.name}] Getting Bluetooth adapter…`);
|
|
78
|
+
const adapter = await bluetooth.defaultAdapter();
|
|
151
79
|
|
|
152
|
-
|
|
153
|
-
await
|
|
154
|
-
} catch (err) {
|
|
155
|
-
throw new Error(`[${this.config.name}] connectAsync failed: ${err}`);
|
|
80
|
+
if (!await adapter.isDiscovering()) {
|
|
81
|
+
await adapter.startDiscovery();
|
|
156
82
|
}
|
|
157
|
-
this.log.info(`[${this.config.name}] Connected — discovering services…`);
|
|
158
83
|
|
|
159
|
-
|
|
160
|
-
|
|
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
|
-
}
|
|
84
|
+
const timeoutMs = (this.config.scanTimeout ?? 30) * 1000;
|
|
85
|
+
this.log.info(`[${this.config.name}] Waiting for device ${this.config.address}…`);
|
|
167
86
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (uuid === NORM_STATUS_UUID) {
|
|
173
|
-
this.statusChar = char;
|
|
174
|
-
this.log.info(`[${this.config.name}] Found status characteristic`);
|
|
175
|
-
} else if (uuid === NORM_COMMAND_UUID) {
|
|
176
|
-
this.commandChar = char;
|
|
177
|
-
this.log.info(`[${this.config.name}] Found command characteristic`);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
87
|
+
const device = await adapter.waitDevice(
|
|
88
|
+
this.config.address.toUpperCase(),
|
|
89
|
+
timeoutMs,
|
|
90
|
+
);
|
|
180
91
|
|
|
181
|
-
|
|
92
|
+
await adapter.stopDiscovery().catch(() => { /* ignore if already stopped */ });
|
|
182
93
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
94
|
+
this.log.info(`[${this.config.name}] Connecting…`);
|
|
95
|
+
await device.connect();
|
|
96
|
+
this.log.info(`[${this.config.name}] Connected — getting GATT server…`);
|
|
186
97
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
this.log.info(`[${this.config.name}] Subscribed — reading device status…`);
|
|
195
|
-
this.statusChar.on('data', (data: Buffer) => this._handleNotification(data));
|
|
98
|
+
device.on('disconnect', () => {
|
|
99
|
+
this.log.warn(`[${this.config.name}] Device disconnected`);
|
|
100
|
+
this._onDisconnected();
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const gatt = await device.gatt();
|
|
104
|
+
this.log.info(`[${this.config.name}] Got GATT server — getting BedJet service…`);
|
|
196
105
|
|
|
197
|
-
|
|
106
|
+
const service = await gatt.getPrimaryService(BEDJET3_SERVICE_UUID);
|
|
107
|
+
this.log.info(`[${this.config.name}] Got service — getting characteristics…`);
|
|
108
|
+
|
|
109
|
+
const statusChar = await service.getCharacteristic(BEDJET3_STATUS_UUID);
|
|
110
|
+
this.commandChar = await service.getCharacteristic(BEDJET3_COMMAND_UUID);
|
|
111
|
+
|
|
112
|
+
this.log.info(`[${this.config.name}] Got characteristics — subscribing to notifications…`);
|
|
113
|
+
await statusChar.startNotifications();
|
|
114
|
+
statusChar.on('valuechanged', (buf: Buffer) => this._handleNotification(buf));
|
|
115
|
+
|
|
116
|
+
this.log.info(`[${this.config.name}] Subscribed — reading initial state…`);
|
|
117
|
+
|
|
118
|
+
// Read the 11-byte status characteristic directly
|
|
198
119
|
try {
|
|
199
|
-
await
|
|
120
|
+
const statusData = await statusChar.readValue();
|
|
121
|
+
this._handleStatusRead(statusData);
|
|
200
122
|
} catch (err) {
|
|
201
|
-
this.log.warn(`[${this.config.name}]
|
|
123
|
+
this.log.warn(`[${this.config.name}] Could not read device status: ${err}`);
|
|
202
124
|
}
|
|
203
|
-
|
|
125
|
+
|
|
126
|
+
// Read device name
|
|
204
127
|
try {
|
|
205
|
-
await
|
|
128
|
+
const nameChar = await service.getCharacteristic(BEDJET3_NAME_UUID);
|
|
129
|
+
const nameData = await nameChar.readValue();
|
|
130
|
+
this.deviceName = nameData.toString('utf8').replace(/\0/g, '').trim();
|
|
131
|
+
this.log.info(`[${this.config.name}] Device name: ${this.deviceName}`);
|
|
206
132
|
} catch (err) {
|
|
207
|
-
this.log.warn(`[${this.config.name}]
|
|
133
|
+
this.log.warn(`[${this.config.name}] Could not read device name: ${err}`);
|
|
208
134
|
}
|
|
209
135
|
|
|
210
136
|
this.reconnectAttempts = 0;
|
|
@@ -215,16 +141,15 @@ export class BedJet extends EventEmitter {
|
|
|
215
141
|
this.emit('connected');
|
|
216
142
|
this.emit('stateChange', this._state);
|
|
217
143
|
|
|
218
|
-
this.log.info(`[${this.config.name}] Ready
|
|
144
|
+
this.log.info(`[${this.config.name}] Ready`);
|
|
219
145
|
}
|
|
220
146
|
|
|
221
|
-
// ── Packet parsing
|
|
147
|
+
// ── Packet parsing ──────────────────────────────────────────────────────────
|
|
222
148
|
|
|
223
149
|
private _handleNotification(data: Buffer): void {
|
|
224
150
|
if (data.length !== BEDJET3_NOTIFICATION_LENGTH) {
|
|
225
151
|
return;
|
|
226
152
|
}
|
|
227
|
-
|
|
228
153
|
this._state = {
|
|
229
154
|
...this._state,
|
|
230
155
|
hoursRemaining: data[4],
|
|
@@ -234,16 +159,12 @@ export class BedJet extends EventEmitter {
|
|
|
234
159
|
targetTemperature: data[8] / 2,
|
|
235
160
|
operatingMode: data[9] as OperatingMode,
|
|
236
161
|
fanSpeed: (data[10] + 1) * 5,
|
|
237
|
-
// data[11] = maximum_hours, data[12] = maximum_minutes (not stored in state)
|
|
238
162
|
minimumTemperature: data[13] / 2,
|
|
239
163
|
maximumTemperature: data[14] / 2,
|
|
240
|
-
// bytes [15–16] = turbo_time uint16 big-endian
|
|
241
164
|
turboTimeSeconds: (data[15] << 8) | data[16],
|
|
242
165
|
ambientTemperature: data[17] / 2,
|
|
243
|
-
|
|
244
|
-
isConnected: true,
|
|
166
|
+
isConnected: true,
|
|
245
167
|
};
|
|
246
|
-
|
|
247
168
|
this._resetStaleTimer();
|
|
248
169
|
this.emit('stateChange', this._state);
|
|
249
170
|
}
|
|
@@ -252,54 +173,19 @@ export class BedJet extends EventEmitter {
|
|
|
252
173
|
if (data.length !== BEDJET3_STATUS_LENGTH) {
|
|
253
174
|
return;
|
|
254
175
|
}
|
|
255
|
-
|
|
256
176
|
const flags = data[7];
|
|
257
177
|
this._state = {
|
|
258
178
|
...this._state,
|
|
259
|
-
isDualZone:
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
beepsMuted: (flags & 0x01) !== 0,
|
|
179
|
+
isDualZone: (data[2] & 0x02) !== 0,
|
|
180
|
+
connTestPassed: (flags & 0x20) !== 0,
|
|
181
|
+
ledEnabled: (flags & 0x10) !== 0,
|
|
182
|
+
unitsSetup: (flags & 0x04) !== 0,
|
|
183
|
+
beepsMuted: (flags & 0x01) !== 0,
|
|
265
184
|
notificationCode: data[9],
|
|
266
185
|
};
|
|
267
186
|
}
|
|
268
187
|
|
|
269
|
-
|
|
270
|
-
if (!this.peripheral) {
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
try {
|
|
274
|
-
// Rediscover to get the name characteristic
|
|
275
|
-
const { characteristics } = await this.peripheral.discoverSomeServicesAndCharacteristicsAsync(
|
|
276
|
-
[NORM_SERVICE_UUID],
|
|
277
|
-
[NORM_NAME_UUID],
|
|
278
|
-
);
|
|
279
|
-
const nameChar = characteristics.find(c => normalize(c.uuid) === NORM_NAME_UUID);
|
|
280
|
-
if (nameChar) {
|
|
281
|
-
const data = await nameChar.readAsync();
|
|
282
|
-
this.deviceName = data.toString('utf8').replace(/\0/g, '').trim();
|
|
283
|
-
this.log.debug(`[${this.config.name}] Device name: ${this.deviceName}`);
|
|
284
|
-
}
|
|
285
|
-
} catch (err) {
|
|
286
|
-
this.log.warn(`[${this.config.name}] Could not read device name: ${err}`);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
private async _readDeviceStatus(): Promise<void> {
|
|
291
|
-
if (!this.statusChar) {
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
try {
|
|
295
|
-
const data = await this.statusChar.readAsync();
|
|
296
|
-
this._handleStatusRead(data);
|
|
297
|
-
} catch (err) {
|
|
298
|
-
this.log.warn(`[${this.config.name}] Could not read device status: ${err}`);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// ── Commands ──────────────────────────────────────────────────────────────
|
|
188
|
+
// ── Commands ────────────────────────────────────────────────────────────────
|
|
303
189
|
|
|
304
190
|
private async _sendCommand(command: BedJetCommand, ...args: number[]): Promise<void> {
|
|
305
191
|
if (!this.commandChar) {
|
|
@@ -307,8 +193,8 @@ export class BedJet extends EventEmitter {
|
|
|
307
193
|
}
|
|
308
194
|
const buf = Buffer.from([command, ...args]);
|
|
309
195
|
try {
|
|
310
|
-
//
|
|
311
|
-
await this.commandChar.
|
|
196
|
+
// writeValueWithResponse = write with response, required for BedJet V3
|
|
197
|
+
await this.commandChar.writeValueWithResponse(buf);
|
|
312
198
|
this._resetDisconnectTimer();
|
|
313
199
|
} catch (err) {
|
|
314
200
|
this.log.error(`[${this.config.name}] Command 0x${command.toString(16)} failed: ${err}`);
|
|
@@ -349,7 +235,7 @@ export class BedJet extends EventEmitter {
|
|
|
349
235
|
await this.pressButton(muted ? BedJetButton.MUTE : BedJetButton.UNMUTE);
|
|
350
236
|
}
|
|
351
237
|
|
|
352
|
-
// ── Timers
|
|
238
|
+
// ── Timers ──────────────────────────────────────────────────────────────────
|
|
353
239
|
|
|
354
240
|
private _resetDisconnectTimer(): void {
|
|
355
241
|
if (this.disconnectTimer) {
|
|
@@ -361,7 +247,6 @@ export class BedJet extends EventEmitter {
|
|
|
361
247
|
}, DISCONNECT_DELAY_MS);
|
|
362
248
|
}
|
|
363
249
|
|
|
364
|
-
// Mark stale and update HomeKit if no notification arrives within 65s
|
|
365
250
|
private _resetStaleTimer(): void {
|
|
366
251
|
if (this.staleTimer) {
|
|
367
252
|
clearTimeout(this.staleTimer);
|
|
@@ -373,11 +258,10 @@ export class BedJet extends EventEmitter {
|
|
|
373
258
|
}, 65_000);
|
|
374
259
|
}
|
|
375
260
|
|
|
376
|
-
// ── Disconnect / reconnect
|
|
261
|
+
// ── Disconnect / reconnect ──────────────────────────────────────────────────
|
|
377
262
|
|
|
378
263
|
private _onDisconnected(): void {
|
|
379
264
|
this.commandChar = null;
|
|
380
|
-
this.statusChar = null;
|
|
381
265
|
|
|
382
266
|
if (this.disconnectTimer) {
|
|
383
267
|
clearTimeout(this.disconnectTimer);
|
|
@@ -392,26 +276,34 @@ export class BedJet extends EventEmitter {
|
|
|
392
276
|
this.emit('disconnected');
|
|
393
277
|
this.emit('stateChange', this._state);
|
|
394
278
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
`
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
this.log.error(`[${this.config.name}] Reconnect failed: ${err}`),
|
|
406
|
-
);
|
|
407
|
-
}, delay);
|
|
408
|
-
} else {
|
|
409
|
-
this.log.error(`[${this.config.name}] Max reconnect attempts reached — giving up`);
|
|
410
|
-
this.emit('maxReconnectReached');
|
|
279
|
+
this._scheduleReconnect();
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
private _scheduleReconnect(): void {
|
|
283
|
+
if (this.destroyed || this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
284
|
+
if (!this.destroyed && this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
285
|
+
this.log.error(`[${this.config.name}] Max reconnect attempts reached`);
|
|
286
|
+
this.emit('maxReconnectReached');
|
|
287
|
+
}
|
|
288
|
+
return;
|
|
411
289
|
}
|
|
290
|
+
const delay = Math.pow(2, this.reconnectAttempts + 1) * 1000;
|
|
291
|
+
this.reconnectAttempts++;
|
|
292
|
+
this.log.info(
|
|
293
|
+
`[${this.config.name}] Reconnecting in ${delay / 1000}s ` +
|
|
294
|
+
`(attempt ${this.reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})`,
|
|
295
|
+
);
|
|
296
|
+
setTimeout(() => {
|
|
297
|
+
this.connect().catch(err =>
|
|
298
|
+
this.log.error(`[${this.config.name}] Reconnect failed: ${err}`),
|
|
299
|
+
);
|
|
300
|
+
}, delay);
|
|
412
301
|
}
|
|
413
302
|
|
|
414
303
|
async disconnect(): Promise<void> {
|
|
304
|
+
this.destroyed = true;
|
|
305
|
+
this.commandChar = null;
|
|
306
|
+
|
|
415
307
|
if (this.disconnectTimer) {
|
|
416
308
|
clearTimeout(this.disconnectTimer);
|
|
417
309
|
this.disconnectTimer = null;
|
|
@@ -420,15 +312,9 @@ export class BedJet extends EventEmitter {
|
|
|
420
312
|
clearTimeout(this.staleTimer);
|
|
421
313
|
this.staleTimer = null;
|
|
422
314
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
try {
|
|
427
|
-
await this.peripheral.disconnectAsync();
|
|
428
|
-
} catch {
|
|
429
|
-
// ignore errors during intentional disconnect
|
|
430
|
-
}
|
|
431
|
-
this.peripheral = null;
|
|
315
|
+
if (this.bleDestroy) {
|
|
316
|
+
try { this.bleDestroy(); } catch { /* ignore */ }
|
|
317
|
+
this.bleDestroy = null;
|
|
432
318
|
}
|
|
433
319
|
}
|
|
434
320
|
}
|