incyclist-devices 1.4.44 → 1.4.47
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/CyclingMode.js +1 -0
- package/lib/Device.d.ts +2 -0
- package/lib/Device.js +2 -0
- package/lib/DeviceProtocol.js +1 -0
- package/lib/DeviceSupport.js +25 -8
- package/lib/ant/AntAdapter.d.ts +1 -0
- package/lib/ant/AntAdapter.js +7 -0
- package/lib/ant/AntScanner.js +24 -7
- package/lib/ant/antfe/AntFEAdapter.js +7 -7
- package/lib/ant/anthrm/AntHrmAdapter.js +1 -1
- package/lib/ant/antpwr/pwr-adapter.js +1 -1
- package/lib/ant/utils.js +3 -1
- package/lib/ble/ble-device.d.ts +14 -5
- package/lib/ble/ble-device.js +138 -69
- package/lib/ble/ble-erg-mode.d.ts +24 -0
- package/lib/ble/ble-erg-mode.js +148 -0
- package/lib/ble/ble-interface.d.ts +35 -5
- package/lib/ble/ble-interface.js +237 -190
- package/lib/ble/ble-peripheral.d.ts +34 -0
- package/lib/ble/ble-peripheral.js +170 -0
- package/lib/ble/ble-st-mode.d.ts +24 -0
- package/lib/ble/ble-st-mode.js +148 -0
- package/lib/ble/ble.d.ts +29 -1
- package/lib/ble/ble.js +3 -1
- package/lib/ble/fm.d.ts +17 -2
- package/lib/ble/fm.js +155 -14
- package/lib/ble/hrm.d.ts +1 -2
- package/lib/ble/hrm.js +7 -8
- package/lib/ble/incyclist-protocol.js +32 -8
- package/lib/ble/pwr.d.ts +2 -2
- package/lib/ble/pwr.js +20 -8
- package/lib/calculations.js +1 -0
- package/lib/daum/DaumAdapter.d.ts +1 -0
- package/lib/daum/DaumAdapter.js +35 -13
- package/lib/daum/SmartTrainerCyclingMode.js +1 -0
- package/lib/daum/classic/DaumClassicAdapter.js +1 -1
- package/lib/daum/classic/DaumClassicProtocol.js +23 -7
- package/lib/daum/classic/bike.js +26 -26
- package/lib/daum/classic/utils.js +1 -0
- package/lib/daum/constants.js +1 -0
- package/lib/daum/premium/DaumPremiumAdapter.js +1 -1
- package/lib/daum/premium/DaumPremiumProtocol.js +23 -7
- package/lib/daum/premium/bike.js +18 -17
- package/lib/daum/premium/utils.js +1 -0
- package/lib/kettler/comms.d.ts +1 -0
- package/lib/kettler/comms.js +2 -1
- package/lib/kettler/ergo-racer/adapter.d.ts +1 -0
- package/lib/kettler/ergo-racer/adapter.js +31 -9
- package/lib/kettler/ergo-racer/protocol.d.ts +1 -1
- package/lib/kettler/ergo-racer/protocol.js +23 -7
- package/lib/modes/power-meter.js +1 -0
- package/lib/simulator/Simulator.d.ts +2 -1
- package/lib/simulator/Simulator.js +29 -7
- package/lib/types/route.js +1 -0
- package/lib/types/user.js +1 -0
- package/lib/utils.js +3 -1
- package/package.json +1 -1
package/lib/CyclingMode.js
CHANGED
package/lib/Device.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export interface DeviceAdapter extends Device {
|
|
|
28
28
|
isBike(): boolean;
|
|
29
29
|
isPower(): boolean;
|
|
30
30
|
isHrm(): boolean;
|
|
31
|
+
isSame(device: DeviceAdapter): boolean;
|
|
31
32
|
getID(): string;
|
|
32
33
|
getDisplayName(): string;
|
|
33
34
|
getName(): string;
|
|
@@ -58,6 +59,7 @@ export default class IncyclistDevice implements DeviceAdapter {
|
|
|
58
59
|
isBike(): boolean;
|
|
59
60
|
isPower(): boolean;
|
|
60
61
|
isHrm(): boolean;
|
|
62
|
+
isSame(device: DeviceAdapter): boolean;
|
|
61
63
|
getID(): string;
|
|
62
64
|
getDisplayName(): string;
|
|
63
65
|
getName(): string;
|
package/lib/Device.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_USER_WEIGHT = exports.DEFAULT_BIKE_WEIGHT = void 0;
|
|
3
4
|
exports.DEFAULT_BIKE_WEIGHT = 10;
|
|
4
5
|
exports.DEFAULT_USER_WEIGHT = 75;
|
|
5
6
|
class IncyclistDevice {
|
|
@@ -12,6 +13,7 @@ class IncyclistDevice {
|
|
|
12
13
|
isBike() { throw new Error('not implemented'); }
|
|
13
14
|
isPower() { throw new Error('not implemented'); }
|
|
14
15
|
isHrm() { throw new Error('not implemented'); }
|
|
16
|
+
isSame(device) { throw new Error('not implemented'); }
|
|
15
17
|
getID() { throw new Error('not implemented'); }
|
|
16
18
|
getDisplayName() { return this.getName(); }
|
|
17
19
|
getName() { throw new Error('not implemented'); }
|
package/lib/DeviceProtocol.js
CHANGED
package/lib/DeviceSupport.js
CHANGED
|
@@ -1,32 +1,49 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
5
18
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
6
19
|
if (mod && mod.__esModule) return mod;
|
|
7
20
|
var result = {};
|
|
8
|
-
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result
|
|
9
|
-
result
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
10
23
|
return result;
|
|
11
24
|
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
12
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.BleFitnessMachineDevice = exports.BleCyclingPowerDevice = exports.BleHrmDevice = exports.BleInterface = exports.CyclingModeProperyType = exports.BleProtocol = exports.AntScanner = exports.Protocols = exports.Device = exports.INTERFACE = exports.DeviceRegistry = exports.DeviceProtocolBase = void 0;
|
|
13
30
|
const DeviceRegistry_1 = __importDefault(require("./DeviceRegistry"));
|
|
14
31
|
exports.DeviceRegistry = DeviceRegistry_1.default;
|
|
15
32
|
const Device_1 = __importDefault(require("./Device"));
|
|
16
33
|
exports.Device = Device_1.default;
|
|
17
34
|
const DeviceProtocol_1 = __importStar(require("./DeviceProtocol"));
|
|
18
35
|
exports.DeviceProtocolBase = DeviceProtocol_1.default;
|
|
19
|
-
exports
|
|
36
|
+
Object.defineProperty(exports, "INTERFACE", { enumerable: true, get: function () { return DeviceProtocol_1.INTERFACE; } });
|
|
20
37
|
const Simulator_1 = __importDefault(require("./simulator/Simulator"));
|
|
21
38
|
const DaumPremiumProtocol_1 = __importDefault(require("./daum/premium/DaumPremiumProtocol"));
|
|
22
39
|
const DaumClassicProtocol_1 = __importDefault(require("./daum/classic/DaumClassicProtocol"));
|
|
23
40
|
const protocol_1 = __importDefault(require("./kettler/ergo-racer/protocol"));
|
|
24
41
|
const AntScanner_1 = require("./ant/AntScanner");
|
|
25
|
-
exports
|
|
42
|
+
Object.defineProperty(exports, "AntScanner", { enumerable: true, get: function () { return AntScanner_1.AntScanner; } });
|
|
26
43
|
const incyclist_protocol_1 = __importDefault(require("./ble/incyclist-protocol"));
|
|
27
44
|
exports.BleProtocol = incyclist_protocol_1.default;
|
|
28
45
|
const CyclingMode_1 = require("./CyclingMode");
|
|
29
|
-
exports
|
|
46
|
+
Object.defineProperty(exports, "CyclingModeProperyType", { enumerable: true, get: function () { return CyclingMode_1.CyclingModeProperyType; } });
|
|
30
47
|
const ble_interface_1 = __importDefault(require("./ble/ble-interface"));
|
|
31
48
|
exports.BleInterface = ble_interface_1.default;
|
|
32
49
|
const hrm_1 = __importDefault(require("./ble/hrm"));
|
package/lib/ant/AntAdapter.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export default class AntAdapter extends DeviceAdapter {
|
|
|
18
18
|
lastUpdate?: number;
|
|
19
19
|
updateFrequency: number;
|
|
20
20
|
constructor(protocol: any);
|
|
21
|
+
isSame(device: DeviceAdapter): boolean;
|
|
21
22
|
setSensor(sensor: any): void;
|
|
22
23
|
getID(): string;
|
|
23
24
|
setIgnoreHrm(ignore: any): void;
|
package/lib/ant/AntAdapter.js
CHANGED
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DEFAULT_UPDATE_FREQUENCY = void 0;
|
|
6
7
|
const Device_1 = __importDefault(require("../Device"));
|
|
7
8
|
exports.DEFAULT_UPDATE_FREQUENCY = 1000;
|
|
8
9
|
class AntAdapter extends Device_1.default {
|
|
@@ -21,6 +22,12 @@ class AntAdapter extends Device_1.default {
|
|
|
21
22
|
this.data = {};
|
|
22
23
|
this.updateFrequency = exports.DEFAULT_UPDATE_FREQUENCY;
|
|
23
24
|
}
|
|
25
|
+
isSame(device) {
|
|
26
|
+
if (!(device instanceof AntAdapter))
|
|
27
|
+
return false;
|
|
28
|
+
const adapter = device;
|
|
29
|
+
return (adapter.getName() === this.getName() && adapter.getProfile() === this.getProfile());
|
|
30
|
+
}
|
|
24
31
|
setSensor(sensor) {
|
|
25
32
|
this.sensor = sensor;
|
|
26
33
|
}
|
package/lib/ant/AntScanner.js
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
26
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
27
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -8,17 +31,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
31
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
32
|
});
|
|
10
33
|
};
|
|
11
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
12
|
-
if (mod && mod.__esModule) return mod;
|
|
13
|
-
var result = {};
|
|
14
|
-
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
|
15
|
-
result["default"] = mod;
|
|
16
|
-
return result;
|
|
17
|
-
};
|
|
18
34
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
36
|
};
|
|
21
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.AntScanner = exports.AntProtocol = void 0;
|
|
22
39
|
const gd_eventlog_1 = require("gd-eventlog");
|
|
23
40
|
const DeviceProtocol_1 = __importStar(require("../DeviceProtocol"));
|
|
24
41
|
const AntHrmAdapter_1 = __importDefault(require("./anthrm/AntHrmAdapter"));
|
|
@@ -52,7 +52,7 @@ class AntFEAdapter extends AntAdapter_1.default {
|
|
|
52
52
|
getDisplayName() {
|
|
53
53
|
const { DeviceID, ManId, ComputedHeartRate } = this.deviceData;
|
|
54
54
|
const hrmStr = ComputedHeartRate ? ` (${ComputedHeartRate})` : '';
|
|
55
|
-
return `${utils_1.getBrand(ManId)} FE ${DeviceID}${hrmStr}`;
|
|
55
|
+
return `${(0, utils_1.getBrand)(ManId)} FE ${DeviceID}${hrmStr}`;
|
|
56
56
|
}
|
|
57
57
|
onAttached() {
|
|
58
58
|
this.logger.logEvent({ message: 'Device connected' });
|
|
@@ -233,7 +233,7 @@ class AntFEAdapter extends AntAdapter_1.default {
|
|
|
233
233
|
trackResistanceSent: false,
|
|
234
234
|
userSent: false,
|
|
235
235
|
};
|
|
236
|
-
utils_2.runWithRetries(() => __awaiter(this, void 0, void 0, function* () {
|
|
236
|
+
(0, utils_2.runWithRetries)(() => __awaiter(this, void 0, void 0, function* () {
|
|
237
237
|
if (this.isStopped())
|
|
238
238
|
resolve(false);
|
|
239
239
|
try {
|
|
@@ -299,18 +299,18 @@ class AntFEAdapter extends AntAdapter_1.default {
|
|
|
299
299
|
try {
|
|
300
300
|
const isReset = (!request || request.reset || Object.keys(request).length === 0);
|
|
301
301
|
if (request.slope !== undefined) {
|
|
302
|
-
yield utils_2.runWithRetries(() => __awaiter(this, void 0, void 0, function* () { return yield this.sendTrackResistance(request.slope); }), 2, 100);
|
|
302
|
+
yield (0, utils_2.runWithRetries)(() => __awaiter(this, void 0, void 0, function* () { return yield this.sendTrackResistance(request.slope); }), 2, 100);
|
|
303
303
|
}
|
|
304
304
|
if (request.targetPower !== undefined) {
|
|
305
|
-
yield utils_2.runWithRetries(() => __awaiter(this, void 0, void 0, function* () { return yield this.sendTargetPower(request.targetPower); }), 2, 100);
|
|
305
|
+
yield (0, utils_2.runWithRetries)(() => __awaiter(this, void 0, void 0, function* () { return yield this.sendTargetPower(request.targetPower); }), 2, 100);
|
|
306
306
|
}
|
|
307
307
|
else if (request.maxPower !== undefined) {
|
|
308
308
|
if (this.data.power && this.data.power > request.maxPower)
|
|
309
|
-
yield utils_2.runWithRetries(() => __awaiter(this, void 0, void 0, function* () { return yield this.sendTargetPower(request.maxPower); }), 2, 100);
|
|
309
|
+
yield (0, utils_2.runWithRetries)(() => __awaiter(this, void 0, void 0, function* () { return yield this.sendTargetPower(request.maxPower); }), 2, 100);
|
|
310
310
|
}
|
|
311
311
|
else if (request.minPower !== undefined) {
|
|
312
312
|
if (this.data.power && this.data.power < request.minPower)
|
|
313
|
-
yield utils_2.runWithRetries(() => __awaiter(this, void 0, void 0, function* () { return yield this.sendTargetPower(request.minPower); }), 2, 100);
|
|
313
|
+
yield (0, utils_2.runWithRetries)(() => __awaiter(this, void 0, void 0, function* () { return yield this.sendTargetPower(request.minPower); }), 2, 100);
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
316
|
catch (err) {
|
|
@@ -395,7 +395,7 @@ class AntFEAdapter extends AntAdapter_1.default {
|
|
|
395
395
|
this.currentCmd = this.queue.dequeue();
|
|
396
396
|
this.currentCmd.tsStart = Date.now();
|
|
397
397
|
const { msg, logStr } = this.currentCmd;
|
|
398
|
-
this.logger.logEvent({ message: "sending", cmd: logStr, msg: utils_2.hexstr(msg), queueSize: this.queue.size() });
|
|
398
|
+
this.logger.logEvent({ message: "sending", cmd: logStr, msg: (0, utils_2.hexstr)(msg), queueSize: this.queue.size() });
|
|
399
399
|
if (this.stick)
|
|
400
400
|
this.stick.write(msg);
|
|
401
401
|
}
|
|
@@ -43,7 +43,7 @@ class AntHrmAdapter extends AntAdapter_1.default {
|
|
|
43
43
|
getDisplayName() {
|
|
44
44
|
const { DeviceID, manID, ComputedHeartRate } = this.deviceData;
|
|
45
45
|
const hrmStr = ComputedHeartRate ? ` (${ComputedHeartRate})` : '';
|
|
46
|
-
return `${utils_1.getBrand(manID)} Hrm ${DeviceID}${hrmStr}`;
|
|
46
|
+
return `${(0, utils_1.getBrand)(manID)} Hrm ${DeviceID}${hrmStr}`;
|
|
47
47
|
}
|
|
48
48
|
onDeviceData(deviceData) {
|
|
49
49
|
if (!this.started)
|
|
@@ -48,7 +48,7 @@ class AntFEAdapter extends AntAdapter_1.default {
|
|
|
48
48
|
}
|
|
49
49
|
getDisplayName() {
|
|
50
50
|
const { DeviceID, ManId } = this.deviceData;
|
|
51
|
-
return `${utils_1.getBrand(ManId)} PWR ${DeviceID}`;
|
|
51
|
+
return `${(0, utils_1.getBrand)(ManId)} PWR ${DeviceID}`;
|
|
52
52
|
}
|
|
53
53
|
getCyclingMode() {
|
|
54
54
|
if (!this.mode)
|
package/lib/ant/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getBrand =
|
|
3
|
+
exports.getBrand = void 0;
|
|
4
|
+
const getBrand = (manId) => {
|
|
4
5
|
if (manId === undefined)
|
|
5
6
|
return "ANT+";
|
|
6
7
|
switch (manId) {
|
|
@@ -19,3 +20,4 @@ exports.getBrand = (manId) => {
|
|
|
19
20
|
return "ANT+";
|
|
20
21
|
}
|
|
21
22
|
};
|
|
23
|
+
exports.getBrand = getBrand;
|
package/lib/ble/ble-device.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { EventLogger } from "gd-eventlog";
|
|
3
|
-
import { BleInterfaceClass, BleDeviceClass, BlePeripheral, BleDeviceProps, ConnectProps } from "./ble";
|
|
3
|
+
import { BleInterfaceClass, BleDeviceClass, BlePeripheral, BleDeviceProps, ConnectProps, BleDeviceInfo } from "./ble";
|
|
4
|
+
import BlePeripheralConnector from "./ble-peripheral";
|
|
4
5
|
interface BleDeviceConstructProps extends BleDeviceProps {
|
|
5
6
|
log?: boolean;
|
|
6
7
|
logger?: EventLogger;
|
|
@@ -15,17 +16,25 @@ export declare abstract class BleDevice extends BleDeviceClass {
|
|
|
15
16
|
characteristics: any[];
|
|
16
17
|
state?: string;
|
|
17
18
|
logger?: EventLogger;
|
|
19
|
+
deviceInfo: BleDeviceInfo;
|
|
20
|
+
isInitialized: boolean;
|
|
21
|
+
subscribedCharacteristics: string[];
|
|
18
22
|
constructor(props?: BleDeviceConstructProps);
|
|
19
23
|
logEvent(event: any): void;
|
|
20
24
|
setInterface(ble: BleInterfaceClass): void;
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
cleanupListeners(): void;
|
|
26
|
+
onDisconnect(): void;
|
|
23
27
|
waitForConnectFinished(timeout: any): Promise<unknown>;
|
|
28
|
+
hasService(serviceUuid: any): boolean;
|
|
29
|
+
init(): Promise<boolean>;
|
|
30
|
+
connectPeripheral(peripheral: BlePeripheral): Promise<void>;
|
|
31
|
+
subscribeAll(conn?: BlePeripheralConnector): Promise<void>;
|
|
24
32
|
connect(props?: ConnectProps): Promise<boolean>;
|
|
25
33
|
disconnect(): Promise<boolean>;
|
|
26
34
|
abstract getProfile(): string;
|
|
27
35
|
abstract onData(characteristic: string, data: Buffer): void;
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
write(characteristicUuid: string, data: Buffer, withoutResponse?: boolean): Promise<boolean>;
|
|
37
|
+
read(characteristicUuid: string): Promise<Uint8Array>;
|
|
38
|
+
getDeviceInfo(): Promise<BleDeviceInfo>;
|
|
30
39
|
}
|
|
31
40
|
export {};
|
package/lib/ble/ble-device.js
CHANGED
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.BleDevice = void 0;
|
|
12
13
|
const gd_eventlog_1 = require("gd-eventlog");
|
|
13
14
|
const ble_1 = require("./ble");
|
|
14
15
|
const CONNECT_WAIT_TIMEOUT = 10000;
|
|
@@ -16,12 +17,15 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
16
17
|
constructor(props) {
|
|
17
18
|
super();
|
|
18
19
|
this.characteristics = [];
|
|
20
|
+
this.deviceInfo = {};
|
|
19
21
|
this.id = props.id;
|
|
20
22
|
this.address = props.address;
|
|
21
23
|
this.name = props.name;
|
|
22
24
|
this.services = props.services;
|
|
23
25
|
this.ble = props.ble;
|
|
24
26
|
this.characteristics = [];
|
|
27
|
+
this.subscribedCharacteristics = [];
|
|
28
|
+
this.isInitialized = false;
|
|
25
29
|
if (props.peripheral) {
|
|
26
30
|
const { id, address, advertisement, state } = props.peripheral;
|
|
27
31
|
this.peripheral = props.peripheral;
|
|
@@ -54,15 +58,18 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
54
58
|
this.characteristics = [];
|
|
55
59
|
}
|
|
56
60
|
else {
|
|
61
|
+
const connector = this.ble.getConnector(this.peripheral);
|
|
57
62
|
this.characteristics.forEach(c => {
|
|
58
|
-
|
|
59
|
-
c.removeAllListeners('data');
|
|
63
|
+
connector.removeAllListeners((0, ble_1.uuid)(c.uuid));
|
|
60
64
|
});
|
|
61
65
|
}
|
|
62
66
|
}
|
|
63
67
|
onDisconnect() {
|
|
68
|
+
this.logEvent({ message: 'device disconnected', address: this.address, profile: this.getProfile() });
|
|
64
69
|
this.state = "disconnected";
|
|
65
70
|
if (!this.connectState.isDisconnecting) {
|
|
71
|
+
this.peripheral.state = 'disconnected';
|
|
72
|
+
this.connectState.isConnected = false;
|
|
66
73
|
this.connect();
|
|
67
74
|
}
|
|
68
75
|
this.emit('disconnected');
|
|
@@ -88,85 +95,82 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
88
95
|
}, 100);
|
|
89
96
|
});
|
|
90
97
|
}
|
|
98
|
+
hasService(serviceUuid) {
|
|
99
|
+
return this.services && this.services.find(s => s === serviceUuid || (0, ble_1.uuid)(serviceUuid)) !== undefined;
|
|
100
|
+
}
|
|
101
|
+
init() {
|
|
102
|
+
if (this.isInitialized)
|
|
103
|
+
return Promise.resolve(true);
|
|
104
|
+
return this.getDeviceInfo().then(() => {
|
|
105
|
+
this.emit('deviceInfo', this.deviceInfo);
|
|
106
|
+
this.isInitialized = true;
|
|
107
|
+
return true;
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
connectPeripheral(peripheral) {
|
|
111
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
112
|
+
this.connectState.isConnecting = true;
|
|
113
|
+
try {
|
|
114
|
+
const connector = this.ble.getConnector(peripheral);
|
|
115
|
+
yield connector.connect();
|
|
116
|
+
yield connector.initialize();
|
|
117
|
+
yield this.subscribeAll(connector);
|
|
118
|
+
this.connectState.isConnected = true;
|
|
119
|
+
this.state = "connected";
|
|
120
|
+
this.emit('connected');
|
|
121
|
+
yield this.init();
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
this.logEvent({ message: 'Error', fn: 'connectPeripheral()', error: err.message, stack: err.stack });
|
|
125
|
+
}
|
|
126
|
+
this.connectState.isConnecting = false;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
subscribeAll(conn) {
|
|
130
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
131
|
+
try {
|
|
132
|
+
const connector = conn || this.ble.getConnector(this.peripheral);
|
|
133
|
+
const subscribed = yield connector.subscribeAll((uuid, data) => { this.onData(uuid, data); });
|
|
134
|
+
subscribed.forEach(c => this.subscribedCharacteristics.push(c));
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
this.logEvent({ message: 'Error', fn: 'subscribeAll()', error: err.message, stack: err.stack });
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
91
141
|
connect(props) {
|
|
92
142
|
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
-
const connectPeripheral = (peripheral) => __awaiter(this, void 0, void 0, function* () {
|
|
94
|
-
this.connectState.isConnecting = true;
|
|
95
|
-
const connected = this.ble.findConnected(peripheral);
|
|
96
|
-
if (!connected && peripheral.state !== 'connected') {
|
|
97
|
-
try {
|
|
98
|
-
yield peripheral.connectAsync();
|
|
99
|
-
}
|
|
100
|
-
catch (err) {
|
|
101
|
-
this.logEvent({ message: 'cannot connect', error: err.message || err });
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
try {
|
|
105
|
-
if (!this.characteristics)
|
|
106
|
-
this.characteristics = [];
|
|
107
|
-
if (!connected) {
|
|
108
|
-
if (!this.characteristics || this.characteristics.length === 0) {
|
|
109
|
-
this.logEvent({ message: 'connect: discover characteristics start' });
|
|
110
|
-
const res = yield peripheral.discoverSomeServicesAndCharacteristicsAsync([], []);
|
|
111
|
-
const { characteristics } = res;
|
|
112
|
-
this.logEvent({ message: 'connect: discover characteristics result',
|
|
113
|
-
result: characteristics.map(c => ({ uuid: ble_1.uuid(c.uuid), properties: c.properties.join(','), service: ble_1.uuid(c._serviceUuid) }))
|
|
114
|
-
});
|
|
115
|
-
this.characteristics = characteristics;
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
this.characteristics = connected.characteristics;
|
|
122
|
-
}
|
|
123
|
-
this.connectState.isConnecting = false;
|
|
124
|
-
this.connectState.isConnected = true;
|
|
125
|
-
this.state = "connected";
|
|
126
|
-
this.emit('connected');
|
|
127
|
-
this.ble.addConnectedDevice(this);
|
|
128
|
-
this.peripheral.once('disconnect', () => { this.onDisconnect(); });
|
|
129
|
-
this.characteristics.forEach(c => {
|
|
130
|
-
if (c.properties.find(p => p === 'notify')) {
|
|
131
|
-
c.on('data', (data, _isNotification) => {
|
|
132
|
-
this.onData(ble_1.uuid(c.uuid), data);
|
|
133
|
-
});
|
|
134
|
-
if (!connected) {
|
|
135
|
-
this.logEvent({ message: 'subscribe', device: this.name, address: this.address, service: c._serviceUuid, characteristic: c.uuid });
|
|
136
|
-
c.subscribe((err) => {
|
|
137
|
-
if (err)
|
|
138
|
-
this.logEvent({ message: 'cannot subscribe', device: this.name, address: this.address, service: c._serviceUuid, characteristic: c.uuid, error: err.message || err });
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
catch (err) {
|
|
145
|
-
this.logEvent({ message: 'cannot connect', error: err.message || err });
|
|
146
|
-
this.connectState.isConnecting = false;
|
|
147
|
-
this.connectState.isConnected = false;
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
143
|
try {
|
|
144
|
+
this.logEvent({ message: 'connect', address: this.peripheral ? this.peripheral.address : this.address, state: this.connectState });
|
|
151
145
|
if (this.connectState.isConnecting) {
|
|
152
146
|
yield this.waitForConnectFinished(CONNECT_WAIT_TIMEOUT);
|
|
153
147
|
}
|
|
154
148
|
if (this.connectState.isConnected) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
|
|
149
|
+
try {
|
|
150
|
+
yield this.subscribeAll();
|
|
151
|
+
yield this.init();
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
this.logEvent({ message: 'cannot reconnect', error: err.message || err });
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
162
157
|
return true;
|
|
163
158
|
}
|
|
164
159
|
this.connectState.isConnecting = true;
|
|
160
|
+
if (!this.peripheral) {
|
|
161
|
+
const { id, name, address } = this;
|
|
162
|
+
try {
|
|
163
|
+
this.peripheral = this.ble.findPeripheral({ id, name, address });
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
console.log('~~~ error', err);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
165
169
|
if (this.peripheral) {
|
|
166
170
|
const { id, address, advertisement } = this.peripheral;
|
|
167
171
|
const name = advertisement === null || advertisement === void 0 ? void 0 : advertisement.localName;
|
|
168
172
|
this.logEvent({ message: 'connect requested', mode: 'peripheral', device: { id, name, address: address } });
|
|
169
|
-
yield connectPeripheral(this.peripheral);
|
|
173
|
+
yield this.connectPeripheral(this.peripheral);
|
|
170
174
|
this.logEvent({ message: 'connect result: success', mode: 'peripheral', device: { id, name, address } });
|
|
171
175
|
return true;
|
|
172
176
|
}
|
|
@@ -179,10 +183,10 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
179
183
|
if (this.ble.isScanning()) {
|
|
180
184
|
yield this.ble.stopScan();
|
|
181
185
|
}
|
|
182
|
-
const devices = yield this.ble.scan({
|
|
186
|
+
const devices = yield this.ble.scan({ requested: this });
|
|
183
187
|
if (devices && devices.length > 0) {
|
|
184
188
|
this.peripheral = devices[0].peripheral;
|
|
185
|
-
yield connectPeripheral(this.peripheral);
|
|
189
|
+
yield this.connectPeripheral(this.peripheral);
|
|
186
190
|
this.logEvent({ message: 'connect result: success', mode: 'device', device: { id, name, address } });
|
|
187
191
|
return true;
|
|
188
192
|
}
|
|
@@ -231,5 +235,70 @@ class BleDevice extends ble_1.BleDeviceClass {
|
|
|
231
235
|
}
|
|
232
236
|
});
|
|
233
237
|
}
|
|
238
|
+
write(characteristicUuid, data, withoutResponse = false) {
|
|
239
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
240
|
+
if (this.subscribedCharacteristics.find(c => c === characteristicUuid) === undefined) {
|
|
241
|
+
const connector = this.ble.getConnector(this.peripheral);
|
|
242
|
+
connector.on(characteristicUuid, (uuid, data) => {
|
|
243
|
+
this.onData(uuid, data);
|
|
244
|
+
});
|
|
245
|
+
yield connector.subscribe(characteristicUuid);
|
|
246
|
+
this.subscribedCharacteristics.push(characteristicUuid);
|
|
247
|
+
}
|
|
248
|
+
return new Promise((resolve, reject) => {
|
|
249
|
+
const characteristic = this.characteristics.find(c => c.uuid === characteristicUuid || (0, ble_1.uuid)(c.uuid) === characteristicUuid);
|
|
250
|
+
if (!characteristic) {
|
|
251
|
+
reject(new Error('Characteristic not found'));
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
characteristic.write(data, withoutResponse, (err) => {
|
|
255
|
+
if (err)
|
|
256
|
+
reject(err);
|
|
257
|
+
else
|
|
258
|
+
resolve(true);
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
read(characteristicUuid) {
|
|
264
|
+
return new Promise((resolve, reject) => {
|
|
265
|
+
const characteristic = this.characteristics.find(c => c.uuid === characteristicUuid || (0, ble_1.uuid)(c.uuid) === characteristicUuid);
|
|
266
|
+
if (!characteristic) {
|
|
267
|
+
reject(new Error('Characteristic not found'));
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
characteristic.read((err, data) => {
|
|
271
|
+
if (err && data instanceof Error)
|
|
272
|
+
reject(err);
|
|
273
|
+
else if (data instanceof Error)
|
|
274
|
+
reject(data);
|
|
275
|
+
else
|
|
276
|
+
resolve(data);
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
getDeviceInfo() {
|
|
281
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
282
|
+
const info = this.deviceInfo;
|
|
283
|
+
const readValue = (c) => __awaiter(this, void 0, void 0, function* () {
|
|
284
|
+
try {
|
|
285
|
+
const b = yield this.read(c);
|
|
286
|
+
const buffer = b ? Buffer.from(b) : undefined;
|
|
287
|
+
return buffer ? buffer.toString() : undefined;
|
|
288
|
+
}
|
|
289
|
+
catch (_a) {
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
info.model = info.model || (yield readValue('2a24'));
|
|
294
|
+
info.serialNo = info.serialNo || (yield readValue('2a25'));
|
|
295
|
+
info.fwRevision = info.fwRevision || (yield readValue('2a26'));
|
|
296
|
+
info.hwRevision = info.hwRevision || (yield readValue('2a27'));
|
|
297
|
+
info.swRevision = info.swRevision || (yield readValue('2a28'));
|
|
298
|
+
info.manufacturer = info.manufacturer || (yield readValue('2a29'));
|
|
299
|
+
this.deviceInfo = info;
|
|
300
|
+
return info;
|
|
301
|
+
});
|
|
302
|
+
}
|
|
234
303
|
}
|
|
235
304
|
exports.BleDevice = BleDevice;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import CyclingMode, { CyclingModeProperty, IncyclistBikeData, UpdateRequest } from "../CyclingMode";
|
|
2
|
+
import PowerBasedCyclingModeBase from "../modes/power-base";
|
|
3
|
+
import { FmAdapter } from "./fm";
|
|
4
|
+
export declare type ERGEvent = {
|
|
5
|
+
rpmUpdated?: boolean;
|
|
6
|
+
gearUpdated?: boolean;
|
|
7
|
+
starting?: boolean;
|
|
8
|
+
tsStart?: number;
|
|
9
|
+
};
|
|
10
|
+
export default class ERGCyclingMode extends PowerBasedCyclingModeBase implements CyclingMode {
|
|
11
|
+
prevRequest: UpdateRequest;
|
|
12
|
+
hasBikeUpdate: boolean;
|
|
13
|
+
chain: number[];
|
|
14
|
+
cassette: number[];
|
|
15
|
+
event: ERGEvent;
|
|
16
|
+
constructor(adapter: FmAdapter, props?: any);
|
|
17
|
+
getName(): string;
|
|
18
|
+
getDescription(): string;
|
|
19
|
+
getProperties(): CyclingModeProperty[];
|
|
20
|
+
getProperty(name: string): CyclingModeProperty;
|
|
21
|
+
getBikeInitRequest(): UpdateRequest;
|
|
22
|
+
sendBikeUpdate(request: UpdateRequest): UpdateRequest;
|
|
23
|
+
updateData(bikeData: IncyclistBikeData): any;
|
|
24
|
+
}
|