incyclist-devices 2.0.0-beta.1 → 2.0.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/README.MD +238 -0
- package/lib/adapters.d.ts +1 -0
- package/lib/adapters.js +19 -0
- package/lib/antv2/adapter-factory.d.ts +8 -7
- package/lib/antv2/adapter-factory.js +4 -2
- package/lib/antv2/adapter.d.ts +3 -2
- package/lib/antv2/adapter.js +15 -4
- package/lib/antv2/ant-interface.d.ts +6 -2
- package/lib/antv2/ant-interface.js +27 -21
- package/lib/antv2/binding.d.ts +1 -1
- package/lib/antv2/binding.js +1 -1
- package/lib/antv2/fe/adapter.d.ts +12 -9
- package/lib/antv2/fe/adapter.js +67 -27
- package/lib/antv2/hr/adapter.d.ts +6 -5
- package/lib/antv2/hr/adapter.js +19 -16
- package/lib/antv2/index.d.ts +2 -2
- package/lib/antv2/pwr/adapter.d.ts +6 -4
- package/lib/antv2/pwr/adapter.js +24 -16
- package/lib/antv2/sensor-factory.d.ts +2 -2
- package/lib/antv2/types.d.ts +5 -2
- package/lib/antv2/types.js +3 -0
- package/lib/antv2/utils.d.ts +3 -0
- package/lib/antv2/utils.js +12 -1
- package/lib/base/adpater.d.ts +14 -2
- package/lib/base/adpater.js +43 -4
- package/lib/ble/adapter-factory.d.ts +18 -16
- package/lib/ble/adapter-factory.js +54 -45
- package/lib/ble/base/adapter.d.ts +53 -0
- package/lib/ble/{adapter.js → base/adapter.js} +111 -9
- package/lib/ble/base/comms-utils.d.ts +7 -0
- package/lib/ble/base/comms-utils.js +91 -0
- package/lib/ble/{ble-comms.d.ts → base/comms.d.ts} +27 -17
- package/lib/ble/{ble-comms.js → base/comms.js} +179 -53
- package/lib/ble/bindings/index.d.ts +2 -0
- package/lib/ble/bindings/index.js +8 -0
- package/lib/ble/bindings/linux.d.ts +15 -0
- package/lib/ble/bindings/linux.js +39 -0
- package/lib/ble/bindings/mock.d.ts +9 -0
- package/lib/ble/bindings/mock.js +108 -0
- package/lib/ble/bindings/types.d.ts +57 -0
- package/lib/ble/bindings/types.js +96 -0
- package/lib/ble/ble-interface.d.ts +34 -46
- package/lib/ble/ble-interface.js +242 -345
- package/lib/ble/ble-peripheral.d.ts +4 -2
- package/lib/ble/ble-peripheral.js +39 -8
- package/lib/ble/consts.d.ts +1 -0
- package/lib/ble/consts.js +2 -1
- package/lib/ble/cp/adapter.d.ts +1 -2
- package/lib/ble/cp/adapter.js +2 -15
- package/lib/ble/cp/comm.d.ts +8 -5
- package/lib/ble/cp/comm.js +12 -27
- package/lib/ble/elite/adapter.d.ts +1 -2
- package/lib/ble/elite/adapter.js +12 -19
- package/lib/ble/elite/comms.d.ts +8 -4
- package/lib/ble/elite/comms.js +12 -25
- package/lib/ble/fm/adapter.d.ts +3 -2
- package/lib/ble/fm/adapter.js +129 -70
- package/lib/ble/fm/comms.d.ts +8 -8
- package/lib/ble/fm/comms.js +33 -55
- package/lib/ble/fm/types.d.ts +5 -0
- package/lib/ble/hr/adapter.d.ts +1 -4
- package/lib/ble/hr/adapter.js +1 -18
- package/lib/ble/hr/comm.d.ts +6 -2
- package/lib/ble/hr/comm.js +6 -2
- package/lib/ble/hr/mock.d.ts +7 -0
- package/lib/ble/hr/mock.js +47 -0
- package/lib/ble/index.d.ts +2 -1
- package/lib/ble/index.js +5 -5
- package/lib/ble/peripheral-cache.d.ts +43 -0
- package/lib/ble/peripheral-cache.js +107 -0
- package/lib/ble/tacx/adapter.d.ts +1 -1
- package/lib/ble/tacx/adapter.js +20 -14
- package/lib/ble/tacx/comms.d.ts +6 -6
- package/lib/ble/tacx/comms.js +10 -43
- package/lib/ble/types.d.ts +54 -27
- package/lib/ble/types.js +0 -17
- package/lib/ble/utils.d.ts +15 -5
- package/lib/ble/utils.js +25 -66
- package/lib/ble/wahoo/adapter.d.ts +1 -1
- package/lib/ble/wahoo/adapter.js +12 -10
- package/lib/ble/wahoo/comms.d.ts +7 -6
- package/lib/ble/wahoo/comms.js +15 -17
- package/lib/index.d.ts +10 -7
- package/lib/index.js +21 -25
- package/lib/interfaces.d.ts +2 -1
- package/lib/interfaces.js +4 -0
- package/lib/modes/power-base.js +4 -0
- package/lib/serial/adapter.d.ts +5 -0
- package/lib/serial/adapter.js +19 -0
- package/lib/serial/bindings/tcp.d.ts +2 -1
- package/lib/serial/bindings/tcp.js +19 -5
- package/lib/serial/daum/DaumAdapter.d.ts +1 -1
- package/lib/serial/daum/DaumAdapter.js +16 -10
- package/lib/serial/daum/premium/adapter.d.ts +1 -0
- package/lib/serial/daum/premium/adapter.js +9 -2
- package/lib/serial/daum/premium/comms.js +10 -3
- package/lib/serial/daum/premium/mock.js +0 -1
- package/lib/serial/index.d.ts +3 -3
- package/lib/serial/index.js +2 -2
- package/lib/serial/kettler/ergo-racer/adapter.d.ts +1 -4
- package/lib/serial/kettler/ergo-racer/adapter.js +15 -39
- package/lib/serial/serial-interface.d.ts +3 -1
- package/lib/serial/serial-interface.js +43 -17
- package/lib/simulator/Simulator.d.ts +2 -0
- package/lib/simulator/Simulator.js +8 -5
- package/lib/types/adapter.d.ts +10 -3
- package/lib/types/device.d.ts +3 -0
- package/lib/types/interface.d.ts +7 -3
- package/package.json +3 -5
- package/lib/ble/adapter.d.ts +0 -41
- package/lib/ble/ble.d.ts +0 -57
- package/lib/ble/ble.js +0 -48
- package/lib/device.d.ts +0 -0
- package/lib/device.js +0 -0
package/lib/ble/ble-interface.js
CHANGED
|
@@ -13,15 +13,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
const gd_eventlog_1 = require("gd-eventlog");
|
|
16
|
-
const utils_1 = require("../utils/utils");
|
|
17
|
-
const ble_1 = require("./ble");
|
|
18
|
-
const ble_comms_1 = require("./ble-comms");
|
|
19
|
-
const ble_peripheral_1 = __importDefault(require("./ble-peripheral"));
|
|
20
16
|
const adapter_factory_1 = __importDefault(require("./adapter-factory"));
|
|
21
|
-
const
|
|
22
|
-
const
|
|
17
|
+
const utils_1 = require("./utils");
|
|
18
|
+
const comms_utils_1 = require("./base/comms-utils");
|
|
19
|
+
const peripheral_cache_1 = __importDefault(require("./peripheral-cache"));
|
|
20
|
+
const events_1 = __importDefault(require("events"));
|
|
21
|
+
const utils_2 = require("../utils/utils");
|
|
23
22
|
const DEFAULT_SCAN_TIMEOUT = 20000;
|
|
24
|
-
class BleInterface extends
|
|
23
|
+
class BleInterface extends events_1.default {
|
|
25
24
|
static getInstance(props = {}) {
|
|
26
25
|
if (!BleInterface._instance) {
|
|
27
26
|
BleInterface._instance = new BleInterface(props);
|
|
@@ -40,14 +39,38 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
40
39
|
return BleInterface._instance;
|
|
41
40
|
}
|
|
42
41
|
constructor(props = {}) {
|
|
43
|
-
super(
|
|
42
|
+
super();
|
|
44
43
|
this.scanState = { isScanning: false, isConnecting: false, timeout: undefined, isBackgroundScan: false };
|
|
45
44
|
this.connectState = { isConnecting: false, isConnected: false, isInitSuccess: false };
|
|
46
|
-
this.
|
|
47
|
-
|
|
45
|
+
this.props = props;
|
|
46
|
+
if (props.binding)
|
|
47
|
+
this.setBinding(props.binding);
|
|
48
|
+
this.peripheralCache = new peripheral_cache_1.default();
|
|
49
|
+
this.connectedDevices = [];
|
|
48
50
|
if (props.logger)
|
|
49
51
|
this.logger = props.logger;
|
|
50
|
-
|
|
52
|
+
else
|
|
53
|
+
this.logger = new gd_eventlog_1.EventLogger('BLE');
|
|
54
|
+
}
|
|
55
|
+
getBinding() { return this.binding; }
|
|
56
|
+
setBinding(binding) { if (binding)
|
|
57
|
+
this.binding = binding; }
|
|
58
|
+
getName() {
|
|
59
|
+
return 'ble';
|
|
60
|
+
}
|
|
61
|
+
startConnectSensor() {
|
|
62
|
+
this.sensorIsConnecting = true;
|
|
63
|
+
}
|
|
64
|
+
stopConnectSensor() {
|
|
65
|
+
this.sensorIsConnecting = false;
|
|
66
|
+
}
|
|
67
|
+
waitForSensorConnectionFinish() {
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
while (this.sensorIsConnecting && this.connectState.isConnected) {
|
|
70
|
+
yield (0, utils_2.sleep)(100);
|
|
71
|
+
}
|
|
72
|
+
return;
|
|
73
|
+
});
|
|
51
74
|
}
|
|
52
75
|
getAdapterFactory() {
|
|
53
76
|
return adapter_factory_1.default.getInstance();
|
|
@@ -61,7 +84,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
61
84
|
}
|
|
62
85
|
}
|
|
63
86
|
onStateChange(state) {
|
|
64
|
-
if (state !==
|
|
87
|
+
if (state !== 'poweredOn') {
|
|
65
88
|
this.connectState.isConnected = false;
|
|
66
89
|
}
|
|
67
90
|
else {
|
|
@@ -71,8 +94,8 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
71
94
|
onError(err) {
|
|
72
95
|
this.logEvent({ message: 'error', error: err.message, stack: err.stack });
|
|
73
96
|
}
|
|
74
|
-
connect(
|
|
75
|
-
const timeout = props.timeout || 2000;
|
|
97
|
+
connect(to) {
|
|
98
|
+
const timeout = this.props.timeout || to || 2000;
|
|
76
99
|
return new Promise((resolve, reject) => {
|
|
77
100
|
if (this.connectState.isConnected) {
|
|
78
101
|
return resolve(true);
|
|
@@ -85,34 +108,11 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
85
108
|
this.connectState.isConnecting = false;
|
|
86
109
|
this.connectState.timeout = null;
|
|
87
110
|
this.logEvent({ message: 'Ble connect result: timeout' });
|
|
88
|
-
|
|
111
|
+
resolve(false);
|
|
89
112
|
}, timeout);
|
|
90
113
|
try {
|
|
91
|
-
if (!this.connectState.isInitSuccess) {
|
|
92
|
-
const binding = this.getBinding()._bindings;
|
|
93
|
-
if (binding) {
|
|
94
|
-
const binding_init_original = binding.init.bind(binding);
|
|
95
|
-
const self = this;
|
|
96
|
-
binding.on('error', (err) => { this.getBinding().emit('error', err); });
|
|
97
|
-
binding.init = function () {
|
|
98
|
-
try {
|
|
99
|
-
binding_init_original();
|
|
100
|
-
self.connectState.isInitSuccess = true;
|
|
101
|
-
}
|
|
102
|
-
catch (err) {
|
|
103
|
-
self.connectState.isInitSuccess = false;
|
|
104
|
-
self.connectState.isConnected = false;
|
|
105
|
-
self.connectState.isConnecting = false;
|
|
106
|
-
self.logEvent({ message: 'connect result: error', error: err.message });
|
|
107
|
-
return reject(new Error(err.message));
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
114
|
const state = this.getBinding().state;
|
|
115
|
-
if (state ===
|
|
115
|
+
if (state === 'poweredOn') {
|
|
116
116
|
clearTimeout(this.connectState.timeout);
|
|
117
117
|
this.connectState.timeout = null;
|
|
118
118
|
this.getBinding().removeAllListeners('stateChange');
|
|
@@ -132,7 +132,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
132
132
|
return reject(err);
|
|
133
133
|
});
|
|
134
134
|
this.getBinding().on('stateChange', (state) => {
|
|
135
|
-
if (state ===
|
|
135
|
+
if (state === 'poweredOn') {
|
|
136
136
|
clearTimeout(this.connectState.timeout);
|
|
137
137
|
this.connectState.timeout = null;
|
|
138
138
|
this.getBinding().removeAllListeners('stateChange');
|
|
@@ -170,11 +170,11 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
170
170
|
if (this.scanState.isScanning) {
|
|
171
171
|
yield this.stopScan();
|
|
172
172
|
}
|
|
173
|
-
const
|
|
173
|
+
const devices = this.getAdapterFactory().getAllInstances();
|
|
174
|
+
const connectedDevices = devices.filter(d => d.isConnected());
|
|
174
175
|
for (let i = 0; i < connectedDevices.length; i++) {
|
|
175
176
|
const d = connectedDevices[i];
|
|
176
|
-
|
|
177
|
-
yield device.disconnect();
|
|
177
|
+
yield d.close();
|
|
178
178
|
}
|
|
179
179
|
this.connectState.isConnected = false;
|
|
180
180
|
this.connectState.isConnecting = false;
|
|
@@ -205,39 +205,18 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
205
205
|
}, 100);
|
|
206
206
|
});
|
|
207
207
|
}
|
|
208
|
-
addPeripheralToCache(peripheral, props = {}) {
|
|
209
|
-
const info = this.peripheralCache.find(i => i.address === peripheral.address);
|
|
210
|
-
const connector = info && info.connector ? info.connector : new ble_peripheral_1.default(this, peripheral);
|
|
211
|
-
this.peripheralCache.push(Object.assign({ address: peripheral.address, ts: Date.now(), peripheral, connector }, props));
|
|
212
|
-
}
|
|
213
208
|
onDisconnect(peripheral) {
|
|
214
|
-
|
|
215
|
-
if (idx !== -1)
|
|
216
|
-
this.peripheralCache.splice(idx, 1);
|
|
217
|
-
}
|
|
218
|
-
getConnector(peripheral) {
|
|
219
|
-
const info = this.peripheralCache.find(i => i.address === peripheral.address);
|
|
220
|
-
if (!info) {
|
|
221
|
-
const connector = new ble_peripheral_1.default(this, peripheral);
|
|
222
|
-
this.peripheralCache.push({ address: peripheral.address, ts: Date.now(), peripheral, connector });
|
|
223
|
-
return connector;
|
|
224
|
-
}
|
|
225
|
-
return info.connector;
|
|
226
|
-
}
|
|
227
|
-
findPeripheral(peripheral) {
|
|
228
|
-
const info = this.peripheralCache.find(i => i.address === peripheral.address || peripheral.address === i.peripheral.address || peripheral.name === i.peripheral.name || peripheral.id === i.peripheral.id);
|
|
229
|
-
return info ? info.peripheral : undefined;
|
|
209
|
+
this.peripheralCache.remove(peripheral);
|
|
230
210
|
}
|
|
231
211
|
getCharacteristics(peripheral) {
|
|
232
212
|
return __awaiter(this, void 0, void 0, function* () {
|
|
233
213
|
let characteristics = undefined;
|
|
234
|
-
let chachedPeripheralInfo = this.peripheralCache.find(
|
|
214
|
+
let chachedPeripheralInfo = this.peripheralCache.find({ peripheral });
|
|
235
215
|
if (chachedPeripheralInfo && Date.now() - chachedPeripheralInfo.ts > 600000) {
|
|
236
216
|
chachedPeripheralInfo.ts = Date.now();
|
|
237
217
|
}
|
|
238
218
|
if (!chachedPeripheralInfo) {
|
|
239
|
-
this.
|
|
240
|
-
chachedPeripheralInfo = this.peripheralCache.find(i => i.address === peripheral.address);
|
|
219
|
+
chachedPeripheralInfo = this.peripheralCache.add({ address: peripheral.address, ts: Date.now(), peripheral });
|
|
241
220
|
}
|
|
242
221
|
const connector = chachedPeripheralInfo.connector;
|
|
243
222
|
if (!chachedPeripheralInfo.characteristics) {
|
|
@@ -247,130 +226,23 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
247
226
|
peripheral.state = connector.getState();
|
|
248
227
|
yield connector.initialize();
|
|
249
228
|
characteristics = connector.getCharachteristics();
|
|
250
|
-
this.logEvent({ message: 'characteristic info (+):', info: characteristics.map(
|
|
229
|
+
this.logEvent({ message: 'characteristic info (+):', address: peripheral.address, info: characteristics.map(utils_1.getCharachteristicsInfo) });
|
|
251
230
|
chachedPeripheralInfo.characteristics = characteristics;
|
|
252
231
|
chachedPeripheralInfo.state = { isConfigured: true, isLoading: false, isInterrupted: false };
|
|
253
232
|
}
|
|
254
233
|
catch (err) {
|
|
255
|
-
console.log(err);
|
|
234
|
+
console.log('~~ ERROR', err);
|
|
256
235
|
}
|
|
257
236
|
}
|
|
258
237
|
else {
|
|
259
238
|
characteristics = chachedPeripheralInfo.characteristics;
|
|
260
|
-
this.logEvent({ message: 'characteristic info (*):', info: characteristics.map(
|
|
239
|
+
this.logEvent({ message: 'characteristic info (*):', address: peripheral.address, info: characteristics.map(utils_1.getCharachteristicsInfo) });
|
|
261
240
|
}
|
|
262
241
|
if (!characteristics)
|
|
263
242
|
this.logEvent({ message: 'characteristic info:', info: 'none' });
|
|
264
243
|
return characteristics;
|
|
265
244
|
});
|
|
266
245
|
}
|
|
267
|
-
createDeviceComms(DeviceClass, peripheral, characteristics) {
|
|
268
|
-
try {
|
|
269
|
-
const C = DeviceClass;
|
|
270
|
-
const device = new C({ peripheral });
|
|
271
|
-
const cids = characteristics ? characteristics.map(c => (0, utils_2.uuid)(c.uuid)) : [];
|
|
272
|
-
this.logEvent({ message: 'trying to create device', peripheral: peripheral.address, characteristics: cids, profile: device.getProfile() });
|
|
273
|
-
const existingDevice = this.devices.find(i => i.device.id === device.id && i.device.getProfile() === device.getProfile());
|
|
274
|
-
if (existingDevice)
|
|
275
|
-
return existingDevice.device;
|
|
276
|
-
device.setInterface(this);
|
|
277
|
-
if (characteristics && device.isMatching(cids)) {
|
|
278
|
-
device.characteristics = characteristics;
|
|
279
|
-
device.setCharacteristicUUIDs(characteristics.map(c => c.uuid));
|
|
280
|
-
return device;
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
283
|
-
this.logEvent({ message: 'failed to create device', peripheral: peripheral.address, profile: device.getProfile() });
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
catch (err) {
|
|
287
|
-
this.logEvent({ message: 'error', fn: '', error: err.message || err, stack: err.stack });
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
connectDevice(requested, timeout = DEFAULT_SCAN_TIMEOUT + CONNECT_TIMEOUT) {
|
|
291
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
292
|
-
const { id, name, address } = requested;
|
|
293
|
-
const profile = requested instanceof ble_comms_1.BleComms ?
|
|
294
|
-
(requested.getProfile && typeof (requested.getProfile) === 'function' ? requested.getProfile() : undefined) :
|
|
295
|
-
requested.profile;
|
|
296
|
-
this.logEvent({ message: 'connectDevice', id, name, address, profile, isbusy: this.scanState.isConnecting });
|
|
297
|
-
if (this.scanState.isConnecting) {
|
|
298
|
-
yield this.waitForConnectFinished(CONNECT_TIMEOUT);
|
|
299
|
-
}
|
|
300
|
-
this.scanState.isConnecting = true;
|
|
301
|
-
const existing = this.devices.find(i => (!profile || i.device.getProfile() === profile) && (i.device.address === requested.address || i.device.id === requested.id || i.device.name === requested.name));
|
|
302
|
-
if (existing) {
|
|
303
|
-
this.logEvent({ message: 'connect existing device' });
|
|
304
|
-
yield existing.device.connect();
|
|
305
|
-
this.scanState.isConnecting = false;
|
|
306
|
-
return existing.device;
|
|
307
|
-
}
|
|
308
|
-
const peripheralInfo = this.peripheralCache.find(i => (i.address === requested.address || (i.periphal && i.peripheral.id === requested.id)));
|
|
309
|
-
if (peripheralInfo) {
|
|
310
|
-
if (!peripheralInfo.characteristic) {
|
|
311
|
-
yield this.getCharacteristics(peripheralInfo.periphal);
|
|
312
|
-
const DeviceClasses = this.getAdapterFactory().getDeviceClasses(peripheralInfo.peripheral, { profile });
|
|
313
|
-
if (!DeviceClasses || DeviceClasses.length === 0)
|
|
314
|
-
return;
|
|
315
|
-
const devices = DeviceClasses.map(C => this.createDeviceComms(C, peripheralInfo.periphal, peripheralInfo.characteristics));
|
|
316
|
-
if (devices && devices.length > 0) {
|
|
317
|
-
for (let i = 0; i < devices.length; i++) {
|
|
318
|
-
const idx = this.devices.push({ device: devices[i], isConnected: false }) - 1;
|
|
319
|
-
if (!devices[i].isConnected())
|
|
320
|
-
yield devices[i].connect();
|
|
321
|
-
this.devices[idx].isConnected = true;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
const connectedDevice = this.devices.find(d => d.isConnected);
|
|
326
|
-
if (connectedDevice)
|
|
327
|
-
return connectedDevice.device;
|
|
328
|
-
}
|
|
329
|
-
let devices = [];
|
|
330
|
-
let retry = false;
|
|
331
|
-
let retryCount = 0;
|
|
332
|
-
do {
|
|
333
|
-
if (retryCount > 0) {
|
|
334
|
-
this.logEvent({ message: 'retry connect device', id, name, address, profile, retryCount });
|
|
335
|
-
}
|
|
336
|
-
try {
|
|
337
|
-
devices = yield this.scan({ timeout: DEFAULT_SCAN_TIMEOUT, requested: requested });
|
|
338
|
-
if (devices.length === 0) {
|
|
339
|
-
retryCount++;
|
|
340
|
-
retry = retryCount < 5;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
catch (err) {
|
|
344
|
-
if (err.message === 'scanning already in progress') {
|
|
345
|
-
yield (0, utils_1.sleep)(1000);
|
|
346
|
-
retryCount++;
|
|
347
|
-
retry = retryCount < 5;
|
|
348
|
-
continue;
|
|
349
|
-
}
|
|
350
|
-
this.scanState.isConnecting = false;
|
|
351
|
-
throw err;
|
|
352
|
-
}
|
|
353
|
-
} while (devices.length === 0 && retry);
|
|
354
|
-
if (devices.length === 0) {
|
|
355
|
-
this.logEvent({ message: 'connectDevice failure', id, name, address, profile, error: 'device not found' });
|
|
356
|
-
this.scanState.isConnecting = false;
|
|
357
|
-
throw new Error('device not found');
|
|
358
|
-
}
|
|
359
|
-
if (devices[0]) {
|
|
360
|
-
this.logEvent({ message: 'connectDevice connecting', id, name, address, profile });
|
|
361
|
-
const connected = yield devices[0].connect();
|
|
362
|
-
this.scanState.isConnecting = false;
|
|
363
|
-
if (connected) {
|
|
364
|
-
this.logEvent({ message: 'connectDevice success', id, name, address, profile });
|
|
365
|
-
return devices[0];
|
|
366
|
-
}
|
|
367
|
-
else {
|
|
368
|
-
this.logEvent({ message: 'connectDevice failure', id, name, address, profile });
|
|
369
|
-
throw new Error('connect failed');
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
246
|
waitForScanFinished(timeout) {
|
|
375
247
|
const waitStart = Date.now();
|
|
376
248
|
const waitTimeout = waitStart + timeout;
|
|
@@ -387,174 +259,222 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
387
259
|
}, 100);
|
|
388
260
|
});
|
|
389
261
|
}
|
|
390
|
-
|
|
262
|
+
onPeripheralFound(p, callback, props = {}) {
|
|
391
263
|
return __awaiter(this, void 0, void 0, function* () {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
264
|
+
let peripheral = p;
|
|
265
|
+
if (!peripheral || !peripheral.advertisement || !peripheral.advertisement.localName) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const scanForDevice = (props.comms !== undefined) || (props.request !== undefined && props.request !== null);
|
|
269
|
+
const request = props.comms ? props.comms.getSettings() : props.request;
|
|
270
|
+
if (scanForDevice && this.scanState.peripherals.size > 0) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
if (!this.scanState.peripherals)
|
|
274
|
+
this.scanState.peripherals = new Map();
|
|
275
|
+
if (peripheral.address === undefined || peripheral.address === '')
|
|
276
|
+
peripheral.address = peripheral.id || peripheral.name;
|
|
277
|
+
const isPeripheralProcessed = this.scanState.peripherals.get(peripheral.address) !== undefined;
|
|
278
|
+
if (isPeripheralProcessed) {
|
|
279
|
+
return;
|
|
406
280
|
}
|
|
407
|
-
const peripheralsProcessed = [];
|
|
408
|
-
const devicesProcessed = [];
|
|
409
|
-
this.logEvent({ message: 'scan()', props: { timeout }, scanState: this.scanState,
|
|
410
|
-
peripheralCache: this.peripheralCache.map(i => ({ address: i.address, ts: i.ts, name: i.peripheral ? i.peripheral.advertisement.localName : '' })),
|
|
411
|
-
deviceCache: this.devices.map(i => ({ address: i.device.address, profile: i.device.getProfile(), isConnected: i.isConnected }))
|
|
412
|
-
});
|
|
413
|
-
let opStr;
|
|
414
281
|
if (scanForDevice) {
|
|
415
|
-
|
|
416
|
-
|
|
282
|
+
let found = false;
|
|
283
|
+
found =
|
|
284
|
+
(request.name && peripheral.advertisement && request.name === peripheral.advertisement.localName) ||
|
|
285
|
+
(request.address && request.address === peripheral.address);
|
|
286
|
+
if (!found) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
this.logEvent({ message: 'search device: found device', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), scanForDevice, callback: callback !== undefined });
|
|
290
|
+
this.scanState.peripherals.set(peripheral.address, peripheral);
|
|
291
|
+
const characteristics = yield this.getCharacteristics(peripheral);
|
|
292
|
+
callback(peripheral, characteristics);
|
|
293
|
+
return;
|
|
417
294
|
}
|
|
418
295
|
else {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
296
|
+
this.logEvent({ message: 'BLE scan: found device', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), scanForDevice, callback: callback !== undefined });
|
|
297
|
+
this.scanState.peripherals.set(peripheral.address, peripheral);
|
|
298
|
+
const { protocolFilter } = props;
|
|
299
|
+
const connector = this.peripheralCache.getConnector(p);
|
|
300
|
+
const characteristics = yield this.getCharacteristics(p);
|
|
301
|
+
const announcedServices = connector.getServices();
|
|
302
|
+
const services = announcedServices ? announcedServices.map(utils_1.uuid) : undefined;
|
|
303
|
+
peripheral = connector.getPeripheral();
|
|
304
|
+
const DeviceClasses = this.getAdapterFactory().getDeviceClasses(peripheral, { services }) || [];
|
|
305
|
+
const MatchingClasses = protocolFilter && DeviceClasses ? DeviceClasses.filter(C => protocolFilter.includes(C.protocol)) : DeviceClasses;
|
|
306
|
+
const DeviceClass = (0, comms_utils_1.getBestDeviceMatch)(MatchingClasses.filter(C => C.isMatching(characteristics.map(c => c.uuid))));
|
|
307
|
+
this.logEvent({ message: 'BLE scan: device connected', peripheral: (0, utils_1.getPeripheralInfo)(peripheral), services, protocols: DeviceClasses.map(c => c.protocol) });
|
|
308
|
+
if (!DeviceClass)
|
|
309
|
+
return callback(null);
|
|
310
|
+
const { id, name, address } = (0, utils_1.getPeripheralInfo)(peripheral);
|
|
311
|
+
const settings = { protocol: DeviceClass.protocol, interface: 'ble', id, name: peripheral.name || name, address: peripheral.address || address };
|
|
312
|
+
callback(settings, characteristics);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
scanForDevice(comms, props) {
|
|
317
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
318
|
+
const { timeout = DEFAULT_SCAN_TIMEOUT } = props;
|
|
319
|
+
const request = comms.getSettings();
|
|
320
|
+
const { protocol } = request;
|
|
321
|
+
const ble = this.getBinding();
|
|
322
|
+
if (!this.isConnected()) {
|
|
323
|
+
yield this.connect();
|
|
422
324
|
}
|
|
325
|
+
const device = adapter_factory_1.default.getInstance().createInstance(request);
|
|
326
|
+
if (device.isConnected())
|
|
327
|
+
return device.getComms().peripheral;
|
|
328
|
+
let opStr;
|
|
329
|
+
opStr = 'search device';
|
|
330
|
+
this.logEvent({ message: 'search device request', request });
|
|
423
331
|
if (this.scanState.isScanning) {
|
|
424
332
|
try {
|
|
425
333
|
this.logEvent({ message: `${opStr}: waiting for previous scan to finish` });
|
|
426
334
|
yield this.waitForScanFinished(timeout);
|
|
427
335
|
}
|
|
428
336
|
catch (err) {
|
|
429
|
-
this.logEvent({ message: `${opStr} result: already scanning
|
|
430
|
-
|
|
337
|
+
this.logEvent({ message: `${opStr} result: already scanning`, error: err.message });
|
|
338
|
+
throw (err);
|
|
431
339
|
}
|
|
432
340
|
}
|
|
433
341
|
return new Promise((resolve, reject) => {
|
|
434
342
|
this.scanState.isScanning = true;
|
|
435
|
-
|
|
436
|
-
if (this.devices && this.devices.length > 0) {
|
|
437
|
-
const knownDevices = this.devices.map(i => ({ name: i.device.name, address: i.device.address, isConnected: i.isConnected, connectState: i.device.getConnectState() }));
|
|
438
|
-
this.logEvent({ message: `${opStr}: check if already registered`, device: { name, address }, knownDevices });
|
|
439
|
-
const existing = this.devices.find(i => (i.device.address === address || i.device.name === name || i.device.id === id));
|
|
440
|
-
if (existing)
|
|
441
|
-
this.logEvent({ message: `${opStr}: device already registered`, device: { name, address } });
|
|
442
|
-
}
|
|
443
|
-
}
|
|
343
|
+
this.scanState.peripherals = new Map();
|
|
444
344
|
const onTimeout = () => {
|
|
445
345
|
if (!this.scanState.isScanning || !this.scanState.timeout)
|
|
446
346
|
return;
|
|
447
347
|
this.scanState.timeout = null;
|
|
448
|
-
this.logEvent({ message: `${opStr} result:
|
|
449
|
-
|
|
450
|
-
this.logEvent({ message: `${opStr}: stop scanning`,
|
|
451
|
-
|
|
348
|
+
this.logEvent({ message: `${opStr} result: timeout`, request });
|
|
349
|
+
ble.removeAllListeners('discover');
|
|
350
|
+
this.logEvent({ message: `${opStr}: stop scanning`, request });
|
|
351
|
+
ble.stopScanning(() => {
|
|
452
352
|
this.scanState.isScanning = false;
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
resolve(this.devices.map(i => i.device));
|
|
353
|
+
reject(new Error('device not found'));
|
|
354
|
+
return;
|
|
458
355
|
});
|
|
459
356
|
};
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
this.
|
|
469
|
-
|
|
470
|
-
if (peripheral.address === undefined || peripheral.address === '')
|
|
471
|
-
peripheral.address = peripheral.id;
|
|
472
|
-
const isPeripheralProcessed = peripheralsProcessed.find(p => p === peripheral.address) !== undefined;
|
|
473
|
-
if (isPeripheralProcessed)
|
|
474
|
-
return;
|
|
475
|
-
peripheralsProcessed.push(peripheral.address);
|
|
476
|
-
if (scanForDevice && requested.name && requested.name !== peripheral.advertisement.localName)
|
|
477
|
-
return;
|
|
478
|
-
const connector = this.getConnector(peripheral);
|
|
479
|
-
const characteristics = yield this.getCharacteristics(peripheral);
|
|
480
|
-
const connectedServices = connector.getServices();
|
|
481
|
-
const services = connectedServices ? connectedServices.map(cs => cs.uuid) : undefined;
|
|
482
|
-
const connectedPeripheral = connector.getPeripheral();
|
|
483
|
-
const { id, name, address, advertisement = {} } = connectedPeripheral;
|
|
484
|
-
const DeviceClasses = this.getAdapterFactory().getDeviceClasses(connectedPeripheral, { profile, services }) || [];
|
|
485
|
-
this.logEvent({ message: 'BLE scan: device connected', peripheral: { id, name, address, services: advertisement.serviceUuids }, services, classes: DeviceClasses.map(c => c.prototype.constructor.name) });
|
|
486
|
-
let cntFound = 0;
|
|
487
|
-
const DeviceClass = (0, utils_2.getBestDeviceMatch)(DeviceClasses);
|
|
488
|
-
if (!DeviceClass)
|
|
489
|
-
return;
|
|
490
|
-
if (scanForDevice && cntFound > 0)
|
|
491
|
-
return;
|
|
492
|
-
const d = this.createDeviceComms(DeviceClass, peripheral, characteristics);
|
|
493
|
-
if (!d) {
|
|
494
|
-
this.logEvent({ message: `${opStr}: could not create device `, DeviceClass });
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
try {
|
|
498
|
-
this.logEvent({ message: `${opStr}: connecting `, device: d.name, profile: d.getProfile(), address: d.address });
|
|
499
|
-
yield d.connect();
|
|
500
|
-
}
|
|
501
|
-
catch (err) {
|
|
502
|
-
this.logEvent({ message: 'error', fn: 'onPeripheralFound()', error: err.message || err, stack: err.stack });
|
|
503
|
-
}
|
|
504
|
-
if (scanForDevice) {
|
|
505
|
-
if ((id && id !== '' && d.id === id) ||
|
|
506
|
-
(address && address !== '' && d.address === address) ||
|
|
507
|
-
(name && name !== '' && d.name === name))
|
|
508
|
-
cntFound++;
|
|
509
|
-
}
|
|
510
|
-
else
|
|
511
|
-
cntFound++;
|
|
512
|
-
const existing = devicesProcessed.find(device => device.id === d.id && device.getProfile() === d.getProfile());
|
|
513
|
-
if (!scanForDevice && cntFound > 0 && !existing) {
|
|
514
|
-
this.logEvent({ message: `${opStr}: device found`, device: d.name, profile: d.getProfile(), address: d.address, services: d.services.join(',') });
|
|
515
|
-
this.addDeviceToCache(d, peripheral.state === 'connected');
|
|
516
|
-
devicesProcessed.push(d);
|
|
517
|
-
this.emit('device', d);
|
|
518
|
-
return;
|
|
357
|
+
this.logEvent({ message: `${opStr}: start scanning`, request, timeout });
|
|
358
|
+
let services = [];
|
|
359
|
+
if (protocol !== 'tacx') {
|
|
360
|
+
services = (device.getComms().getServices()) || [];
|
|
361
|
+
}
|
|
362
|
+
ble.startScanning(services, false, (err) => {
|
|
363
|
+
if (err) {
|
|
364
|
+
this.logEvent({ message: `${opStr} result: error`, request, error: err.message });
|
|
365
|
+
this.scanState.isScanning = false;
|
|
366
|
+
return reject(err);
|
|
519
367
|
}
|
|
520
|
-
|
|
521
|
-
this.
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
this.
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
resolve([d]);
|
|
368
|
+
ble.on('discover', (p) => {
|
|
369
|
+
this.onPeripheralFound(p, (peripheral, characteristics) => {
|
|
370
|
+
device.getComms().characteristics = characteristics;
|
|
371
|
+
process.nextTick(() => {
|
|
372
|
+
if (this.scanState.timeout) {
|
|
373
|
+
clearTimeout(this.scanState.timeout);
|
|
374
|
+
this.scanState.timeout = null;
|
|
375
|
+
}
|
|
376
|
+
this.logEvent({ message: `${opStr}: stop scanning`, request });
|
|
377
|
+
ble.stopScanning(() => {
|
|
378
|
+
ble.removeAllListeners('discover');
|
|
379
|
+
this.scanState.isScanning = false;
|
|
380
|
+
resolve(peripheral);
|
|
381
|
+
});
|
|
535
382
|
});
|
|
536
|
-
});
|
|
383
|
+
}, { comms });
|
|
384
|
+
});
|
|
385
|
+
const cachedItem = this.peripheralCache.find(request);
|
|
386
|
+
if (cachedItem) {
|
|
387
|
+
this.logEvent({ message: `${opStr}: adding peripheral from cache `, peripheral: (0, utils_1.getPeripheralInfo)(cachedItem.peripheral) });
|
|
388
|
+
ble.emit('discover', cachedItem.peripheral);
|
|
537
389
|
}
|
|
538
390
|
});
|
|
539
|
-
this.
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
391
|
+
this.scanState.timeout = setTimeout(onTimeout, timeout);
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
scan(props = {}) {
|
|
396
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
397
|
+
const { timeout = DEFAULT_SCAN_TIMEOUT, protocol, protocols } = props;
|
|
398
|
+
const requestedProtocols = protocols || [];
|
|
399
|
+
if (protocol && !requestedProtocols.find(p => p === protocol))
|
|
400
|
+
requestedProtocols.push(protocol);
|
|
401
|
+
const protocolFilter = requestedProtocols.length > 0 ? requestedProtocols : null;
|
|
402
|
+
const services = protocolFilter === null ? this.getAdapterFactory().getAllSupportedServices() : (0, comms_utils_1.getServicesFromProtocols)(protocolFilter);
|
|
403
|
+
const ble = this.getBinding();
|
|
404
|
+
const opStr = 'scan';
|
|
405
|
+
if (this.scanState.isScanning) {
|
|
406
|
+
try {
|
|
407
|
+
this.logEvent({ message: `${opStr}: waiting for previous scan to finish` });
|
|
408
|
+
yield this.waitForScanFinished(timeout);
|
|
546
409
|
}
|
|
547
|
-
|
|
410
|
+
catch (err) {
|
|
411
|
+
this.logEvent({ message: `${opStr} result: already scanning` });
|
|
412
|
+
throw (err);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
this.scanState.isScanning = true;
|
|
416
|
+
const tsStart = Date.now();
|
|
417
|
+
const tsTimeoutExpired = tsStart + timeout;
|
|
418
|
+
while (!this.isConnected() && this.scanState.isScanning && Date.now() < tsTimeoutExpired) {
|
|
419
|
+
const connected = yield this.connect();
|
|
420
|
+
if (!connected)
|
|
421
|
+
yield (0, utils_2.sleep)(1000);
|
|
422
|
+
}
|
|
423
|
+
if (Date.now() > tsTimeoutExpired) {
|
|
424
|
+
return [];
|
|
425
|
+
}
|
|
426
|
+
if (!this.scanState.isScanning) {
|
|
427
|
+
return [];
|
|
428
|
+
}
|
|
429
|
+
const adjustedScanTimeout = tsStart - Date.now() + timeout;
|
|
430
|
+
const supported = adapter_factory_1.default.getInstance().getAll().map(i => i.protocol);
|
|
431
|
+
this.logEvent({ message: 'scan start', services, supported });
|
|
432
|
+
return new Promise((resolve, reject) => {
|
|
433
|
+
this.scanState.peripherals = new Map();
|
|
434
|
+
const detected = [];
|
|
435
|
+
const requested = protocolFilter;
|
|
436
|
+
const onTimeout = () => {
|
|
437
|
+
if (!this.scanState.isScanning || !this.scanState.timeout)
|
|
438
|
+
return;
|
|
439
|
+
this.scanState.timeout = null;
|
|
440
|
+
const devices = detected.map(d => {
|
|
441
|
+
const { id, name, address, protocol } = d;
|
|
442
|
+
return { id, name, address, protocol };
|
|
443
|
+
});
|
|
444
|
+
this.logEvent({ message: `${opStr} result: timeout, devices found`, requested, devices });
|
|
445
|
+
ble.removeAllListeners('discover');
|
|
446
|
+
this.logEvent({ message: `${opStr}: stop scanning`, requested });
|
|
447
|
+
ble.stopScanning(() => {
|
|
448
|
+
this.scanState.isScanning = false;
|
|
449
|
+
resolve(detected);
|
|
450
|
+
});
|
|
451
|
+
};
|
|
452
|
+
this.logEvent({ message: `${opStr}: start scanning`, requested, timeout });
|
|
453
|
+
this.scanState.timeout = setTimeout(onTimeout, adjustedScanTimeout);
|
|
454
|
+
ble.startScanning(protocolFilter ? services : [], false, (err) => {
|
|
548
455
|
if (err) {
|
|
549
|
-
this.logEvent({ message: `${opStr} result: error`, requested
|
|
456
|
+
this.logEvent({ message: `${opStr} result: error`, requested, error: err.message });
|
|
550
457
|
this.scanState.isScanning = false;
|
|
551
458
|
return reject(err);
|
|
552
459
|
}
|
|
553
|
-
|
|
554
|
-
onPeripheralFound(p)
|
|
460
|
+
ble.on('discover', (p) => {
|
|
461
|
+
this.onPeripheralFound(p, (deviceSettings, characteristics) => {
|
|
462
|
+
if (deviceSettings) {
|
|
463
|
+
detected.push(deviceSettings);
|
|
464
|
+
const device = this.getAdapterFactory().createInstance(deviceSettings);
|
|
465
|
+
device.getComms().characteristics = characteristics;
|
|
466
|
+
this.emit('device', deviceSettings);
|
|
467
|
+
}
|
|
468
|
+
}, { protocolFilter });
|
|
555
469
|
});
|
|
470
|
+
const cachedItems = this.peripheralCache.filter(protocolFilter ? services : []);
|
|
471
|
+
if (cachedItems && cachedItems.length > 0) {
|
|
472
|
+
cachedItems.map(c => c.peripheral).forEach(peripheral => {
|
|
473
|
+
this.logEvent({ message: `${opStr}: adding peripheral from cache `, peripheral: (0, utils_1.getPeripheralInfo)(peripheral) });
|
|
474
|
+
ble.emit('discover', peripheral);
|
|
475
|
+
});
|
|
476
|
+
}
|
|
556
477
|
});
|
|
557
|
-
this.scanState.timeout = setTimeout(onTimeout, timeout);
|
|
558
478
|
});
|
|
559
479
|
});
|
|
560
480
|
}
|
|
@@ -565,13 +485,12 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
565
485
|
this.logEvent({ message: 'scan stop result: not scanning' });
|
|
566
486
|
return true;
|
|
567
487
|
}
|
|
568
|
-
|
|
488
|
+
const ble = this.getBinding();
|
|
489
|
+
if (!ble)
|
|
569
490
|
throw new Error('no binding defined');
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
ongoing.forEach(i => { i.isInterrupted = true; });
|
|
574
|
-
yield this.getBinding().stopScanning();
|
|
491
|
+
ble.removeAllListeners('discover');
|
|
492
|
+
this.peripheralCache.handleStopScan();
|
|
493
|
+
ble.stopScanning();
|
|
575
494
|
this.scanState.isScanning = false;
|
|
576
495
|
this.logEvent({ message: 'scan stop result: success' });
|
|
577
496
|
return true;
|
|
@@ -581,36 +500,14 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
581
500
|
return this.scanState.isScanning === true;
|
|
582
501
|
}
|
|
583
502
|
addConnectedDevice(device) {
|
|
584
|
-
const
|
|
585
|
-
if (
|
|
586
|
-
|
|
587
|
-
return;
|
|
588
|
-
}
|
|
589
|
-
this.devices.push({ device, isConnected: true });
|
|
590
|
-
}
|
|
591
|
-
addDeviceToCache(device, isConnected) {
|
|
592
|
-
const existigDevice = this.devices.find(i => i.device.id === device.id && i.device.getProfile() === device.getProfile());
|
|
593
|
-
if (existigDevice) {
|
|
594
|
-
return;
|
|
595
|
-
}
|
|
596
|
-
this.devices.push({ device, isConnected });
|
|
597
|
-
}
|
|
598
|
-
findConnected(device) {
|
|
599
|
-
const connected = this.devices.find(i => i.device.id === device.id && i.isConnected);
|
|
600
|
-
if (connected)
|
|
601
|
-
return connected.device;
|
|
602
|
-
return undefined;
|
|
603
|
-
}
|
|
604
|
-
findDeviceInCache(device) {
|
|
605
|
-
const existing = this.devices.find(i => (i.device.id === device.id || i.device.address === device.address || i.device.name === device.name) && i.device.getProfile() === device.profile);
|
|
606
|
-
return existing ? existing.device : undefined;
|
|
503
|
+
const idx = this.connectedDevices.findIndex(d => d.isSame(device));
|
|
504
|
+
if (idx === -1)
|
|
505
|
+
this.connectedDevices.push(device);
|
|
607
506
|
}
|
|
608
507
|
removeConnectedDevice(device) {
|
|
609
|
-
const
|
|
610
|
-
if (
|
|
611
|
-
|
|
612
|
-
return;
|
|
613
|
-
}
|
|
508
|
+
const idx = this.connectedDevices.findIndex(d => d.isSame(device));
|
|
509
|
+
if (idx !== -1)
|
|
510
|
+
this.connectedDevices.splice(idx);
|
|
614
511
|
}
|
|
615
512
|
}
|
|
616
513
|
exports.default = BleInterface;
|