incyclist-devices 1.4.34 → 1.4.37
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/lib/ble/ble-device.d.ts +2 -2
- package/lib/ble/ble-device.js +22 -11
- package/lib/ble/ble-interface.d.ts +2 -1
- package/lib/ble/ble-interface.js +49 -20
- package/lib/ble/ble.d.ts +1 -0
- package/lib/ble/hrm.d.ts +1 -1
- package/lib/ble/hrm.js +8 -8
- package/lib/ble/pwr.d.ts +2 -2
- package/lib/ble/pwr.js +4 -3
- package/lib/modes/power-meter.js +1 -1
- package/package.json +1 -1
package/lib/ble/ble-device.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { EventLogger } from "gd-eventlog";
|
|
3
|
-
import { BleInterfaceClass, BleDeviceClass, BlePeripheral,
|
|
3
|
+
import { BleInterfaceClass, BleDeviceClass, BlePeripheral, BleDeviceProps, ConnectProps } from "./ble";
|
|
4
4
|
interface ConnectState {
|
|
5
5
|
isConnecting: boolean;
|
|
6
6
|
isConnected: boolean;
|
|
@@ -17,7 +17,7 @@ export declare abstract class BleDevice extends BleDeviceClass {
|
|
|
17
17
|
services: string[];
|
|
18
18
|
ble: BleInterfaceClass;
|
|
19
19
|
peripheral?: BlePeripheral;
|
|
20
|
-
characteristics:
|
|
20
|
+
characteristics: any[];
|
|
21
21
|
state?: string;
|
|
22
22
|
connectState: ConnectState;
|
|
23
23
|
logger?: EventLogger;
|
package/lib/ble/ble-device.js
CHANGED
|
@@ -71,11 +71,14 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
71
71
|
return __awaiter(this, void 0, void 0, function* () {
|
|
72
72
|
const connectPeripheral = (peripheral) => __awaiter(this, void 0, void 0, function* () {
|
|
73
73
|
this.connectState.isConnecting = true;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
const connected = this.ble.findConnected(peripheral);
|
|
75
|
+
if (!connected) {
|
|
76
|
+
try {
|
|
77
|
+
yield peripheral.connectAsync();
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
this.logEvent({ message: 'cannot connect', error: err.message || err });
|
|
81
|
+
}
|
|
79
82
|
}
|
|
80
83
|
this.connectState.isConnecting = false;
|
|
81
84
|
this.connectState.isConnected = true;
|
|
@@ -85,16 +88,24 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
85
88
|
this.ble.addConnectedDevice(this);
|
|
86
89
|
this.peripheral.once('disconnect', () => { this.onDisconnect(); });
|
|
87
90
|
try {
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
if (!connected) {
|
|
92
|
+
const { characteristics } = yield peripheral.discoverSomeServicesAndCharacteristicsAsync(this.services || [], []);
|
|
93
|
+
this.characteristics = characteristics;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
this.characteristics = connected.characteristics;
|
|
97
|
+
}
|
|
98
|
+
this.characteristics.forEach(c => {
|
|
90
99
|
if (c.properties.find(p => p === 'notify')) {
|
|
91
100
|
c.on('data', (data, _isNotification) => {
|
|
92
101
|
this.onData(ble_1.uuid(c.uuid), data);
|
|
93
102
|
});
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
103
|
+
if (!connected) {
|
|
104
|
+
c.subscribe((err) => {
|
|
105
|
+
if (err)
|
|
106
|
+
this.logEvent({ message: 'cannot subscribe', error: err.message || err });
|
|
107
|
+
});
|
|
108
|
+
}
|
|
98
109
|
}
|
|
99
110
|
});
|
|
100
111
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { EventLogger } from 'gd-eventlog';
|
|
3
|
-
import { BleInterfaceClass, ConnectProps, ScanProps, BleDeviceClass, BleBinding } from './ble';
|
|
3
|
+
import { BleInterfaceClass, ConnectProps, ScanProps, BleDeviceClass, BlePeripheral, BleBinding } from './ble';
|
|
4
4
|
export interface ScanState {
|
|
5
5
|
isScanning: boolean;
|
|
6
6
|
timeout?: NodeJS.Timeout;
|
|
@@ -53,5 +53,6 @@ export default class BleInterface extends BleInterfaceClass {
|
|
|
53
53
|
stopScan(): Promise<boolean>;
|
|
54
54
|
isScanning(): boolean;
|
|
55
55
|
addConnectedDevice(device: BleDeviceClass): void;
|
|
56
|
+
findConnected(device: BleDeviceClass | BlePeripheral): BleDeviceClass;
|
|
56
57
|
removeConnectedDevice(device: BleDeviceClass): void;
|
|
57
58
|
}
|
package/lib/ble/ble-interface.js
CHANGED
|
@@ -84,21 +84,26 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
84
84
|
try {
|
|
85
85
|
if (!this.connectState.isInitSuccess) {
|
|
86
86
|
const binding = this.getBinding()._bindings;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
87
|
+
if (binding) {
|
|
88
|
+
const binding_init_original = binding.init.bind(binding);
|
|
89
|
+
const self = this;
|
|
90
|
+
binding.on('error', (err) => { this.getBinding().emit('error', err); });
|
|
91
|
+
binding.init = function () {
|
|
92
|
+
try {
|
|
93
|
+
binding_init_original();
|
|
94
|
+
self.connectState.isInitSuccess = true;
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
self.connectState.isInitSuccess = false;
|
|
98
|
+
self.connectState.isConnected = false;
|
|
99
|
+
self.connectState.isConnecting = false;
|
|
100
|
+
self.logEvent({ message: 'connect result: error', error: err.message });
|
|
101
|
+
return reject(new Error(err.message));
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
}
|
|
102
107
|
}
|
|
103
108
|
const state = this.getBinding().state;
|
|
104
109
|
if (state === ble_1.BleState.POWERED_ON) {
|
|
@@ -278,9 +283,10 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
278
283
|
yield this.connect();
|
|
279
284
|
}
|
|
280
285
|
const detectedPeripherals = {};
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
this.logEvent({ message: 'search device request', device, deviceTypes });
|
|
286
|
+
if (scanForDevice) {
|
|
287
|
+
const { id, address, name } = device;
|
|
288
|
+
this.logEvent({ message: 'search device request', device: { id, address, name }, deviceTypes });
|
|
289
|
+
}
|
|
284
290
|
else
|
|
285
291
|
this.logEvent({ message: 'scan start', services });
|
|
286
292
|
return new Promise((resolve, reject) => {
|
|
@@ -289,7 +295,15 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
289
295
|
return reject(new Error('scanning already in progress'));
|
|
290
296
|
}
|
|
291
297
|
this.scanState.isScanning = true;
|
|
292
|
-
|
|
298
|
+
if (scanForDevice && device instanceof ble_1.BleDeviceClass) {
|
|
299
|
+
const existing = this.devices.find(i => i.device.address === device.address && i.isConnected);
|
|
300
|
+
if (existing) {
|
|
301
|
+
device.peripheral = existing.device.peripheral;
|
|
302
|
+
this.logEvent({ message: 'scan: device already connected', device: device.name, address: device.address });
|
|
303
|
+
return resolve([device]);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
bleBinding.startScanning([], true, (err) => {
|
|
293
307
|
if (err) {
|
|
294
308
|
this.logEvent({ message: 'scan result: error', error: err.message });
|
|
295
309
|
this.scanState.isScanning = false;
|
|
@@ -299,6 +313,8 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
299
313
|
if (!peripheral || !peripheral.advertisement)
|
|
300
314
|
return;
|
|
301
315
|
if (!detectedPeripherals[peripheral.id]) {
|
|
316
|
+
if (process.env.BLE_DEBUG)
|
|
317
|
+
console.log('discovered', peripheral);
|
|
302
318
|
detectedPeripherals[peripheral.id] = peripheral;
|
|
303
319
|
let DeviceClasses;
|
|
304
320
|
if (scanForDevice && (!deviceTypes || deviceTypes.length === 0)) {
|
|
@@ -316,6 +332,8 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
316
332
|
return;
|
|
317
333
|
const C = DeviceClass;
|
|
318
334
|
const d = new C({ peripheral });
|
|
335
|
+
if (device.getProfile && device.getProfile() !== d.getProfile())
|
|
336
|
+
return;
|
|
319
337
|
d.setInterface(this);
|
|
320
338
|
if (scanForDevice) {
|
|
321
339
|
if ((device.id && device.id !== '' && d.id === device.id) ||
|
|
@@ -325,7 +343,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
325
343
|
}
|
|
326
344
|
else
|
|
327
345
|
cntFound++;
|
|
328
|
-
const existing = this.devices.find(i => i.device.id === d.id);
|
|
346
|
+
const existing = this.devices.find(i => i.device.id === d.id && i.device.getProfile() === d.getProfile());
|
|
329
347
|
if (cntFound > 0 && !existing) {
|
|
330
348
|
this.logEvent({ message: 'scan: device found', device: d.name, address: d.address, services: d.services.join(',') });
|
|
331
349
|
this.devices.push({ device: d, isConnected: false });
|
|
@@ -336,6 +354,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
336
354
|
clearTimeout(this.scanState.timeout);
|
|
337
355
|
this.scanState.timeout = null;
|
|
338
356
|
bleBinding.stopScanning(() => {
|
|
357
|
+
this.getBinding().removeAllListeners('discover');
|
|
339
358
|
this.scanState.isScanning = false;
|
|
340
359
|
resolve([d]);
|
|
341
360
|
});
|
|
@@ -346,11 +365,14 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
346
365
|
}
|
|
347
366
|
});
|
|
348
367
|
}
|
|
368
|
+
else {
|
|
369
|
+
}
|
|
349
370
|
});
|
|
350
371
|
});
|
|
351
372
|
this.scanState.timeout = setTimeout(() => {
|
|
352
373
|
this.scanState.timeout = null;
|
|
353
374
|
this.logEvent({ message: 'scan result: devices found', devices: this.devices.map(i => i.device.name + (!i.device.name || i.device.name === '') ? `addr=${i.device.address}` : '') });
|
|
375
|
+
this.getBinding().removeAllListeners('discover');
|
|
354
376
|
bleBinding.stopScanning(() => {
|
|
355
377
|
this.scanState.isScanning = false;
|
|
356
378
|
resolve(this.devices.map(i => i.device));
|
|
@@ -365,6 +387,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
365
387
|
}
|
|
366
388
|
if (!this.getBinding())
|
|
367
389
|
return Promise.reject(new Error('no binding defined'));
|
|
390
|
+
this.getBinding().removeAllListeners('discover');
|
|
368
391
|
this.logEvent({ message: 'scan stop request' });
|
|
369
392
|
return new Promise(resolve => {
|
|
370
393
|
this.getBinding().stopScanning(() => {
|
|
@@ -385,6 +408,12 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
385
408
|
}
|
|
386
409
|
this.devices.push({ device, isConnected: true });
|
|
387
410
|
}
|
|
411
|
+
findConnected(device) {
|
|
412
|
+
const connected = this.devices.find(i => i.device.id === device.id && i.isConnected);
|
|
413
|
+
if (connected)
|
|
414
|
+
return connected.device;
|
|
415
|
+
return undefined;
|
|
416
|
+
}
|
|
388
417
|
removeConnectedDevice(device) {
|
|
389
418
|
const existigDevice = this.devices.find(i => i.device.id === device.id);
|
|
390
419
|
if (existigDevice) {
|
package/lib/ble/ble.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ export declare abstract class BleInterfaceClass extends EventEmitter {
|
|
|
51
51
|
abstract isScanning(): boolean;
|
|
52
52
|
abstract addConnectedDevice(device: BleDeviceClass): void;
|
|
53
53
|
abstract removeConnectedDevice(device: BleDeviceClass): void;
|
|
54
|
+
abstract findConnected(device: BleDeviceClass | BlePeripheral): BleDeviceClass;
|
|
54
55
|
getBinding(): BleBinding;
|
|
55
56
|
setBinding(binding: BleBinding): void;
|
|
56
57
|
}
|
package/lib/ble/hrm.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export default class BleHrmDevice extends BleDevice {
|
|
|
19
19
|
constructor(props?: any);
|
|
20
20
|
getProfile(): string;
|
|
21
21
|
getServiceUUids(): string[];
|
|
22
|
-
parseHrm(
|
|
22
|
+
parseHrm(_data: Uint8Array): HrmData;
|
|
23
23
|
onData(characteristic: string, data: Buffer): void;
|
|
24
24
|
write(characteristic: any, data: any): Promise<boolean>;
|
|
25
25
|
read(characteristic: any): Promise<Buffer>;
|
package/lib/ble/hrm.js
CHANGED
|
@@ -28,20 +28,20 @@ class BleHrmDevice extends ble_device_1.BleDevice {
|
|
|
28
28
|
getServiceUUids() {
|
|
29
29
|
return BleHrmDevice.services;
|
|
30
30
|
}
|
|
31
|
-
parseHrm(
|
|
31
|
+
parseHrm(_data) {
|
|
32
|
+
const data = Buffer.from(_data);
|
|
32
33
|
try {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
let offset = 1;
|
|
34
|
+
const flags = data.readUInt8(0);
|
|
35
|
+
let offset = 2;
|
|
36
36
|
if (flags % 1 === 0) {
|
|
37
|
-
this.heartrate =
|
|
37
|
+
this.heartrate = data.readUInt8(1);
|
|
38
38
|
}
|
|
39
39
|
else {
|
|
40
|
-
this.heartrate =
|
|
41
|
-
offset =
|
|
40
|
+
this.heartrate = data.readUInt16LE(1);
|
|
41
|
+
offset = 3;
|
|
42
42
|
}
|
|
43
43
|
if (flags % 0xF) {
|
|
44
|
-
this.rr = (
|
|
44
|
+
this.rr = (data.readUInt16LE(offset)) / 1024;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
catch (err) {
|
package/lib/ble/pwr.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ declare type PowerData = {
|
|
|
14
14
|
accTorque?: number;
|
|
15
15
|
time: number;
|
|
16
16
|
rpm: number;
|
|
17
|
-
raw?:
|
|
17
|
+
raw?: string;
|
|
18
18
|
};
|
|
19
19
|
declare type CrankData = {
|
|
20
20
|
revolutions?: number;
|
|
@@ -39,7 +39,7 @@ export default class BleCyclingPowerDevice extends BleDevice {
|
|
|
39
39
|
rpm: number;
|
|
40
40
|
time: any;
|
|
41
41
|
};
|
|
42
|
-
parsePower(
|
|
42
|
+
parsePower(_data: Uint8Array): PowerData;
|
|
43
43
|
onData(characteristic: string, data: Buffer): void;
|
|
44
44
|
write(characteristic: any, data: any): Promise<boolean>;
|
|
45
45
|
read(characteristic: any): Promise<Buffer>;
|
package/lib/ble/pwr.js
CHANGED
|
@@ -66,7 +66,8 @@ class BleCyclingPowerDevice extends ble_device_1.BleDevice {
|
|
|
66
66
|
this.prevCrankData.cntUpdateMissing = cntUpdateMissing + 1;
|
|
67
67
|
return { rpm, time: this.timeOffset + c.time };
|
|
68
68
|
}
|
|
69
|
-
parsePower(
|
|
69
|
+
parsePower(_data) {
|
|
70
|
+
const data = Buffer.from(_data);
|
|
70
71
|
try {
|
|
71
72
|
let offset = 4;
|
|
72
73
|
const flags = data.readUInt16LE(0);
|
|
@@ -91,7 +92,7 @@ class BleCyclingPowerDevice extends ble_device_1.BleDevice {
|
|
|
91
92
|
catch (err) {
|
|
92
93
|
}
|
|
93
94
|
const { instantaneousPower, balance, accTorque, rpm, time } = this;
|
|
94
|
-
return { instantaneousPower, balance, accTorque, rpm, time, raw: data };
|
|
95
|
+
return { instantaneousPower, balance, accTorque, rpm, time, raw: data.toString('hex') };
|
|
95
96
|
}
|
|
96
97
|
onData(characteristic, data) {
|
|
97
98
|
if (characteristic.toLocaleLowerCase() === '2a63') {
|
|
@@ -176,7 +177,7 @@ class PwrAdapter extends Device_1.default {
|
|
|
176
177
|
const data = {
|
|
177
178
|
isPedalling: false,
|
|
178
179
|
power: 0,
|
|
179
|
-
pedalRpm:
|
|
180
|
+
pedalRpm: undefined,
|
|
180
181
|
speed: 0,
|
|
181
182
|
heartrate: 0,
|
|
182
183
|
distanceInternal: 0,
|
package/lib/modes/power-meter.js
CHANGED
|
@@ -47,7 +47,7 @@ class PowerMeterCyclingMode extends power_base_1.default {
|
|
|
47
47
|
let power = bikeData.power || 0;
|
|
48
48
|
const slope = prevData.slope || 0;
|
|
49
49
|
const distanceInternal = prevData.distanceInternal || 0;
|
|
50
|
-
if (
|
|
50
|
+
if (bikeData.pedalRpm === 0 || bikeData.isPedalling === false) {
|
|
51
51
|
power = 0;
|
|
52
52
|
}
|
|
53
53
|
const m = this.getWeight();
|