incyclist-devices 1.4.35 → 1.4.38
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 -21
- 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,22 +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
|
-
|
|
102
|
-
|
|
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
|
+
}
|
|
103
107
|
}
|
|
104
108
|
const state = this.getBinding().state;
|
|
105
109
|
if (state === ble_1.BleState.POWERED_ON) {
|
|
@@ -279,9 +283,10 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
279
283
|
yield this.connect();
|
|
280
284
|
}
|
|
281
285
|
const detectedPeripherals = {};
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
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
|
+
}
|
|
285
290
|
else
|
|
286
291
|
this.logEvent({ message: 'scan start', services });
|
|
287
292
|
return new Promise((resolve, reject) => {
|
|
@@ -290,7 +295,15 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
290
295
|
return reject(new Error('scanning already in progress'));
|
|
291
296
|
}
|
|
292
297
|
this.scanState.isScanning = true;
|
|
293
|
-
|
|
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) => {
|
|
294
307
|
if (err) {
|
|
295
308
|
this.logEvent({ message: 'scan result: error', error: err.message });
|
|
296
309
|
this.scanState.isScanning = false;
|
|
@@ -300,6 +313,8 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
300
313
|
if (!peripheral || !peripheral.advertisement)
|
|
301
314
|
return;
|
|
302
315
|
if (!detectedPeripherals[peripheral.id]) {
|
|
316
|
+
if (process.env.BLE_DEBUG)
|
|
317
|
+
console.log('discovered', peripheral);
|
|
303
318
|
detectedPeripherals[peripheral.id] = peripheral;
|
|
304
319
|
let DeviceClasses;
|
|
305
320
|
if (scanForDevice && (!deviceTypes || deviceTypes.length === 0)) {
|
|
@@ -317,6 +332,8 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
317
332
|
return;
|
|
318
333
|
const C = DeviceClass;
|
|
319
334
|
const d = new C({ peripheral });
|
|
335
|
+
if (device && device.getProfile && device.getProfile() !== d.getProfile())
|
|
336
|
+
return;
|
|
320
337
|
d.setInterface(this);
|
|
321
338
|
if (scanForDevice) {
|
|
322
339
|
if ((device.id && device.id !== '' && d.id === device.id) ||
|
|
@@ -326,7 +343,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
326
343
|
}
|
|
327
344
|
else
|
|
328
345
|
cntFound++;
|
|
329
|
-
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());
|
|
330
347
|
if (cntFound > 0 && !existing) {
|
|
331
348
|
this.logEvent({ message: 'scan: device found', device: d.name, address: d.address, services: d.services.join(',') });
|
|
332
349
|
this.devices.push({ device: d, isConnected: false });
|
|
@@ -337,6 +354,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
337
354
|
clearTimeout(this.scanState.timeout);
|
|
338
355
|
this.scanState.timeout = null;
|
|
339
356
|
bleBinding.stopScanning(() => {
|
|
357
|
+
this.getBinding().removeAllListeners('discover');
|
|
340
358
|
this.scanState.isScanning = false;
|
|
341
359
|
resolve([d]);
|
|
342
360
|
});
|
|
@@ -347,11 +365,14 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
347
365
|
}
|
|
348
366
|
});
|
|
349
367
|
}
|
|
368
|
+
else {
|
|
369
|
+
}
|
|
350
370
|
});
|
|
351
371
|
});
|
|
352
372
|
this.scanState.timeout = setTimeout(() => {
|
|
353
373
|
this.scanState.timeout = null;
|
|
354
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');
|
|
355
376
|
bleBinding.stopScanning(() => {
|
|
356
377
|
this.scanState.isScanning = false;
|
|
357
378
|
resolve(this.devices.map(i => i.device));
|
|
@@ -366,6 +387,7 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
366
387
|
}
|
|
367
388
|
if (!this.getBinding())
|
|
368
389
|
return Promise.reject(new Error('no binding defined'));
|
|
390
|
+
this.getBinding().removeAllListeners('discover');
|
|
369
391
|
this.logEvent({ message: 'scan stop request' });
|
|
370
392
|
return new Promise(resolve => {
|
|
371
393
|
this.getBinding().stopScanning(() => {
|
|
@@ -386,6 +408,12 @@ class BleInterface extends ble_1.BleInterfaceClass {
|
|
|
386
408
|
}
|
|
387
409
|
this.devices.push({ device, isConnected: true });
|
|
388
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
|
+
}
|
|
389
417
|
removeConnectedDevice(device) {
|
|
390
418
|
const existigDevice = this.devices.find(i => i.device.id === device.id);
|
|
391
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();
|