incyclist-devices 1.4.26 → 1.4.27
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 +0 -1
- package/lib/Device.d.ts +1 -1
- package/lib/Device.js +2 -3
- package/lib/DeviceProtocol.d.ts +2 -1
- package/lib/DeviceProtocol.js +1 -1
- package/lib/DeviceSupport.d.ts +6 -1
- package/lib/DeviceSupport.js +17 -21
- package/lib/ant/AntAdapter.js +0 -1
- package/lib/ant/AntScanner.js +7 -20
- 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 +1 -3
- package/lib/ble/ble-device.d.ts +36 -0
- package/lib/ble/ble-device.js +174 -0
- package/lib/ble/ble-interface.d.ts +51 -0
- package/lib/ble/ble-interface.js +330 -0
- package/lib/ble/ble.d.ts +81 -0
- package/lib/ble/ble.js +51 -0
- package/lib/ble/hrm.d.ts +48 -0
- package/lib/ble/hrm.js +128 -0
- package/lib/ble/incyclist-protocol.d.ts +31 -0
- package/lib/ble/incyclist-protocol.js +106 -0
- package/lib/ble/pwr.d.ts +32 -0
- package/lib/ble/pwr.js +96 -0
- package/lib/calculations.js +0 -1
- package/lib/daum/DaumAdapter.d.ts +2 -2
- package/lib/daum/DaumAdapter.js +13 -25
- package/lib/daum/SmartTrainerCyclingMode.js +0 -1
- package/lib/daum/classic/DaumClassicAdapter.js +1 -1
- package/lib/daum/classic/DaumClassicProtocol.js +7 -19
- package/lib/daum/classic/bike.js +26 -26
- package/lib/daum/classic/utils.js +0 -1
- package/lib/daum/constants.js +0 -1
- package/lib/daum/premium/DaumPremiumAdapter.js +1 -1
- package/lib/daum/premium/DaumPremiumProtocol.js +7 -19
- package/lib/daum/premium/bike.js +17 -18
- package/lib/daum/premium/utils.js +0 -1
- package/lib/kettler/comms.js +1 -2
- package/lib/kettler/ergo-racer/adapter.js +9 -21
- package/lib/kettler/ergo-racer/protocol.js +7 -19
- package/lib/modes/power-meter.js +0 -1
- package/lib/simulator/Simulator.js +7 -20
- package/lib/types/route.js +0 -1
- package/lib/types/user.js +0 -1
- package/lib/utils.js +1 -3
- package/package.json +1 -1
package/lib/CyclingMode.js
CHANGED
package/lib/Device.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export interface DeviceAdapter extends Device {
|
|
|
49
49
|
sendUpdate(request: any): void;
|
|
50
50
|
onData(callback: OnDeviceDataCallback): void;
|
|
51
51
|
}
|
|
52
|
-
export default class
|
|
52
|
+
export default class IncyclistDevice implements DeviceAdapter {
|
|
53
53
|
protocol: DeviceProtocol;
|
|
54
54
|
detected: boolean;
|
|
55
55
|
selected: boolean;
|
package/lib/Device.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_USER_WEIGHT = exports.DEFAULT_BIKE_WEIGHT = void 0;
|
|
4
3
|
exports.DEFAULT_BIKE_WEIGHT = 10;
|
|
5
4
|
exports.DEFAULT_USER_WEIGHT = 75;
|
|
6
|
-
class
|
|
5
|
+
class IncyclistDevice {
|
|
7
6
|
constructor(proto) {
|
|
8
7
|
this.protocol = proto;
|
|
9
8
|
this.detected = false;
|
|
@@ -43,4 +42,4 @@ class DeviceAdapterBase {
|
|
|
43
42
|
this.onDataFn = callback;
|
|
44
43
|
}
|
|
45
44
|
}
|
|
46
|
-
exports.default =
|
|
45
|
+
exports.default = IncyclistDevice;
|
package/lib/DeviceProtocol.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare type Device = {
|
|
|
16
16
|
};
|
|
17
17
|
export interface DeviceSettings {
|
|
18
18
|
name: string;
|
|
19
|
-
port
|
|
19
|
+
port?: string;
|
|
20
20
|
userSettings?: User;
|
|
21
21
|
bikeSettings?: any;
|
|
22
22
|
}
|
|
@@ -64,6 +64,7 @@ export default class DeviceProtocolBase {
|
|
|
64
64
|
getSerialPort(): void;
|
|
65
65
|
setNetImpl(netClass: any): void;
|
|
66
66
|
getNetImpl(): any;
|
|
67
|
+
setBinding(_bindingClass: any): void;
|
|
67
68
|
static setAnt(antClass: any): void;
|
|
68
69
|
static getAnt(): any;
|
|
69
70
|
static setSerialPort(serialClass: any): void;
|
package/lib/DeviceProtocol.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.INTERFACE = void 0;
|
|
4
3
|
exports.INTERFACE = {
|
|
5
4
|
SERIAL: 'serial',
|
|
6
5
|
ANT: 'ant',
|
|
@@ -30,6 +29,7 @@ class DeviceProtocolBase {
|
|
|
30
29
|
getSerialPort() { DeviceProtocolBase.getSerialPort(); }
|
|
31
30
|
setNetImpl(netClass) { DeviceProtocolBase.setNetImpl(netClass); }
|
|
32
31
|
getNetImpl() { return DeviceProtocolBase.getNetImpl(); }
|
|
32
|
+
setBinding(_bindingClass) { }
|
|
33
33
|
static setAnt(antClass) { _ant = antClass; }
|
|
34
34
|
static getAnt() { return _ant; }
|
|
35
35
|
static setSerialPort(serialClass) { _serial = serialClass; }
|
package/lib/DeviceSupport.d.ts
CHANGED
|
@@ -6,11 +6,16 @@ import DaumPremiumProtocol from './daum/premium/DaumPremiumProtocol';
|
|
|
6
6
|
import DaumClassicProtocol from './daum/classic/DaumClassicProtocol';
|
|
7
7
|
import KettlerRacerProtocol from './kettler/ergo-racer/protocol';
|
|
8
8
|
import { AntScanner } from './ant/AntScanner';
|
|
9
|
+
import BleProtocol from './ble/incyclist-protocol';
|
|
9
10
|
import { CyclingModeProperyType } from './CyclingMode';
|
|
11
|
+
import BleInterface from './ble/ble-interface';
|
|
12
|
+
import BleHrmDevice from './ble/hrm';
|
|
13
|
+
import BleCyclingPowerDevice from './ble/pwr';
|
|
10
14
|
declare const Protocols: {
|
|
11
15
|
SimulatorProtocol: typeof SimulatorProtocol;
|
|
12
16
|
DaumClassicProtocol: typeof DaumClassicProtocol;
|
|
13
17
|
DaumPremiumProtocol: typeof DaumPremiumProtocol;
|
|
14
18
|
KettlerRacerProtocol: typeof KettlerRacerProtocol;
|
|
19
|
+
BleProtocol: typeof BleProtocol;
|
|
15
20
|
};
|
|
16
|
-
export { DeviceProtocolBase, DeviceProtocol, DeviceRegistry, INTERFACE, DeviceAdapter as Device, Protocols, AntScanner, CyclingModeProperyType };
|
|
21
|
+
export { DeviceProtocolBase, DeviceProtocol, DeviceRegistry, INTERFACE, DeviceAdapter as Device, Protocols, AntScanner, BleProtocol, CyclingModeProperyType, BleInterface, BleHrmDevice, BleCyclingPowerDevice };
|
package/lib/DeviceSupport.js
CHANGED
|
@@ -1,47 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
14
5
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
6
|
if (mod && mod.__esModule) return mod;
|
|
16
7
|
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (
|
|
18
|
-
|
|
8
|
+
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
|
9
|
+
result["default"] = mod;
|
|
19
10
|
return result;
|
|
20
11
|
};
|
|
21
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
-
};
|
|
24
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.CyclingModeProperyType = exports.AntScanner = exports.Protocols = exports.Device = exports.INTERFACE = exports.DeviceRegistry = exports.DeviceProtocolBase = void 0;
|
|
26
13
|
const DeviceRegistry_1 = __importDefault(require("./DeviceRegistry"));
|
|
27
14
|
exports.DeviceRegistry = DeviceRegistry_1.default;
|
|
28
15
|
const Device_1 = __importDefault(require("./Device"));
|
|
29
16
|
exports.Device = Device_1.default;
|
|
30
17
|
const DeviceProtocol_1 = __importStar(require("./DeviceProtocol"));
|
|
31
18
|
exports.DeviceProtocolBase = DeviceProtocol_1.default;
|
|
32
|
-
|
|
19
|
+
exports.INTERFACE = DeviceProtocol_1.INTERFACE;
|
|
33
20
|
const Simulator_1 = __importDefault(require("./simulator/Simulator"));
|
|
34
21
|
const DaumPremiumProtocol_1 = __importDefault(require("./daum/premium/DaumPremiumProtocol"));
|
|
35
22
|
const DaumClassicProtocol_1 = __importDefault(require("./daum/classic/DaumClassicProtocol"));
|
|
36
23
|
const protocol_1 = __importDefault(require("./kettler/ergo-racer/protocol"));
|
|
37
24
|
const AntScanner_1 = require("./ant/AntScanner");
|
|
38
|
-
|
|
25
|
+
exports.AntScanner = AntScanner_1.AntScanner;
|
|
26
|
+
const incyclist_protocol_1 = __importDefault(require("./ble/incyclist-protocol"));
|
|
27
|
+
exports.BleProtocol = incyclist_protocol_1.default;
|
|
39
28
|
const CyclingMode_1 = require("./CyclingMode");
|
|
40
|
-
|
|
29
|
+
exports.CyclingModeProperyType = CyclingMode_1.CyclingModeProperyType;
|
|
30
|
+
const ble_interface_1 = __importDefault(require("./ble/ble-interface"));
|
|
31
|
+
exports.BleInterface = ble_interface_1.default;
|
|
32
|
+
const hrm_1 = __importDefault(require("./ble/hrm"));
|
|
33
|
+
exports.BleHrmDevice = hrm_1.default;
|
|
34
|
+
const pwr_1 = __importDefault(require("./ble/pwr"));
|
|
35
|
+
exports.BleCyclingPowerDevice = pwr_1.default;
|
|
41
36
|
const Protocols = {
|
|
42
37
|
SimulatorProtocol: Simulator_1.default,
|
|
43
38
|
DaumClassicProtocol: DaumClassicProtocol_1.default,
|
|
44
39
|
DaumPremiumProtocol: DaumPremiumProtocol_1.default,
|
|
45
40
|
KettlerRacerProtocol: protocol_1.default,
|
|
41
|
+
BleProtocol: incyclist_protocol_1.default
|
|
46
42
|
};
|
|
47
43
|
exports.Protocols = Protocols;
|
package/lib/ant/AntAdapter.js
CHANGED
|
@@ -3,7 +3,6 @@ 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;
|
|
7
6
|
const Device_1 = __importDefault(require("../Device"));
|
|
8
7
|
exports.DEFAULT_UPDATE_FREQUENCY = 1000;
|
|
9
8
|
class AntAdapter extends Device_1.default {
|
package/lib/ant/AntScanner.js
CHANGED
|
@@ -1,23 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
22
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
23
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -27,11 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
27
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
9
|
});
|
|
29
10
|
};
|
|
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
|
+
};
|
|
30
18
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
31
19
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
20
|
};
|
|
33
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
-
exports.AntScanner = exports.AntProtocol = void 0;
|
|
35
22
|
const gd_eventlog_1 = require("gd-eventlog");
|
|
36
23
|
const DeviceProtocol_1 = __importStar(require("../DeviceProtocol"));
|
|
37
24
|
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 `${
|
|
55
|
+
return `${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
|
-
|
|
236
|
+
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
|
|
302
|
+
yield 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
|
|
305
|
+
yield 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
|
|
309
|
+
yield 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
|
|
313
|
+
yield 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:
|
|
398
|
+
this.logger.logEvent({ message: "sending", cmd: logStr, msg: 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 `${
|
|
46
|
+
return `${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 `${
|
|
51
|
+
return `${utils_1.getBrand(ManId)} PWR ${DeviceID}`;
|
|
52
52
|
}
|
|
53
53
|
getCyclingMode() {
|
|
54
54
|
if (!this.mode)
|
package/lib/ant/utils.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getBrand =
|
|
4
|
-
const getBrand = (manId) => {
|
|
3
|
+
exports.getBrand = (manId) => {
|
|
5
4
|
if (manId === undefined)
|
|
6
5
|
return "ANT+";
|
|
7
6
|
switch (manId) {
|
|
@@ -20,4 +19,3 @@ const getBrand = (manId) => {
|
|
|
20
19
|
return "ANT+";
|
|
21
20
|
}
|
|
22
21
|
};
|
|
23
|
-
exports.getBrand = getBrand;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventLogger } from "gd-eventlog";
|
|
3
|
+
import { BleInterfaceClass, BleDeviceClass, BlePeripheral, BleCharacteristic, BleDeviceProps, ConnectProps } from "./ble";
|
|
4
|
+
interface ConnectState {
|
|
5
|
+
isConnecting: boolean;
|
|
6
|
+
isConnected: boolean;
|
|
7
|
+
isDisconnecting: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface BleDeviceConstructProps extends BleDeviceProps {
|
|
10
|
+
log?: boolean;
|
|
11
|
+
logger?: EventLogger;
|
|
12
|
+
}
|
|
13
|
+
export declare abstract class BleDevice extends BleDeviceClass {
|
|
14
|
+
id: string;
|
|
15
|
+
address: string;
|
|
16
|
+
name: string;
|
|
17
|
+
services: string[];
|
|
18
|
+
ble: BleInterfaceClass;
|
|
19
|
+
peripheral?: BlePeripheral;
|
|
20
|
+
characteristics: BleCharacteristic[];
|
|
21
|
+
state?: string;
|
|
22
|
+
connectState: ConnectState;
|
|
23
|
+
logger?: EventLogger;
|
|
24
|
+
constructor(props?: BleDeviceConstructProps);
|
|
25
|
+
logEvent(event: any): void;
|
|
26
|
+
setInterface(ble: BleInterfaceClass): void;
|
|
27
|
+
private cleanupListeners;
|
|
28
|
+
private onDisconnect;
|
|
29
|
+
connect(props?: ConnectProps): Promise<boolean>;
|
|
30
|
+
disconnect(): Promise<boolean>;
|
|
31
|
+
abstract getProfile(): string;
|
|
32
|
+
abstract onData(characteristic: string, data: Buffer): void;
|
|
33
|
+
abstract write(characteristic: string, data: Buffer): Promise<boolean>;
|
|
34
|
+
abstract read(characteristic: string): Promise<Buffer>;
|
|
35
|
+
}
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const gd_eventlog_1 = require("gd-eventlog");
|
|
13
|
+
const ble_1 = require("./ble");
|
|
14
|
+
class BleDevice extends ble_1.BleDeviceClass {
|
|
15
|
+
constructor(props) {
|
|
16
|
+
super();
|
|
17
|
+
this.characteristics = [];
|
|
18
|
+
this.connectState = { isConnecting: false, isConnected: false, isDisconnecting: false };
|
|
19
|
+
this.id = props.id;
|
|
20
|
+
this.address = props.address;
|
|
21
|
+
this.name = props.name;
|
|
22
|
+
this.services = props.services;
|
|
23
|
+
this.ble = props.ble;
|
|
24
|
+
this.characteristics = [];
|
|
25
|
+
if (props.peripheral) {
|
|
26
|
+
const { id, address, advertisement, state } = props.peripheral;
|
|
27
|
+
this.peripheral = props.peripheral;
|
|
28
|
+
this.id = id;
|
|
29
|
+
this.address = address;
|
|
30
|
+
this.name = advertisement.localName;
|
|
31
|
+
this.services = advertisement.serviceUuids;
|
|
32
|
+
this.state = state;
|
|
33
|
+
}
|
|
34
|
+
if (props.logger) {
|
|
35
|
+
this.logger = props.logger;
|
|
36
|
+
}
|
|
37
|
+
else if (props.log) {
|
|
38
|
+
this.logger = new gd_eventlog_1.EventLogger('BleDevice');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
logEvent(event) {
|
|
42
|
+
if (this.logger) {
|
|
43
|
+
this.logger.logEvent(event);
|
|
44
|
+
}
|
|
45
|
+
if (process.env.BLE_DEBUG) {
|
|
46
|
+
console.log(event);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
setInterface(ble) {
|
|
50
|
+
this.ble = ble;
|
|
51
|
+
}
|
|
52
|
+
cleanupListeners() {
|
|
53
|
+
if (this.characteristics === undefined) {
|
|
54
|
+
this.characteristics = [];
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
this.characteristics.forEach(c => {
|
|
58
|
+
c.removeAllListeners('data');
|
|
59
|
+
});
|
|
60
|
+
this.characteristics = [];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
onDisconnect() {
|
|
64
|
+
this.state = "disconnected";
|
|
65
|
+
if (!this.connectState.isDisconnecting) {
|
|
66
|
+
this.connect();
|
|
67
|
+
}
|
|
68
|
+
this.emit('disconnected');
|
|
69
|
+
}
|
|
70
|
+
connect(props) {
|
|
71
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
72
|
+
const connectPeripheral = (peripheral) => __awaiter(this, void 0, void 0, function* () {
|
|
73
|
+
this.connectState.isConnecting = true;
|
|
74
|
+
try {
|
|
75
|
+
yield peripheral.connectAsync();
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
this.logEvent({ message: 'cannot connect', error: err.message || err });
|
|
79
|
+
}
|
|
80
|
+
this.connectState.isConnecting = false;
|
|
81
|
+
this.connectState.isConnected = true;
|
|
82
|
+
this.state = "connected";
|
|
83
|
+
this.emit('connected');
|
|
84
|
+
this.cleanupListeners();
|
|
85
|
+
this.ble.addConnectedDevice(this);
|
|
86
|
+
this.peripheral.once('disconnect', () => { this.onDisconnect(); });
|
|
87
|
+
try {
|
|
88
|
+
const { characteristics } = yield peripheral.discoverSomeServicesAndCharacteristicsAsync(this.services || [], []);
|
|
89
|
+
characteristics.forEach(c => {
|
|
90
|
+
if (c.properties.find(p => p === 'notify')) {
|
|
91
|
+
c.on('data', (data, _isNotification) => {
|
|
92
|
+
this.onData(c.uuid, data);
|
|
93
|
+
});
|
|
94
|
+
c.subscribe((err) => {
|
|
95
|
+
if (err)
|
|
96
|
+
this.logEvent({ message: 'cannot subscribe', error: err.message || err });
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
this.logEvent({ message: 'cannot connect', error: err.message || err });
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
try {
|
|
106
|
+
if (this.peripheral) {
|
|
107
|
+
const { id, address, advertisement } = this.peripheral;
|
|
108
|
+
const name = advertisement === null || advertisement === void 0 ? void 0 : advertisement.localName;
|
|
109
|
+
this.logEvent({ message: 'connect requested', mode: 'peripheral', device: { id, name, address: address } });
|
|
110
|
+
yield connectPeripheral(this.peripheral);
|
|
111
|
+
this.logEvent({ message: 'connect result: success', mode: 'peripheral', device: { id, name, address } });
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
const { id, name, address } = this;
|
|
116
|
+
if (this.address || this.id || this.name) {
|
|
117
|
+
this.connectState.isConnecting = true;
|
|
118
|
+
this.logEvent({ message: 'connect requested', mode: 'device', device: { id, name, address } });
|
|
119
|
+
try {
|
|
120
|
+
if (this.ble.isScanning()) {
|
|
121
|
+
yield this.ble.stopScan();
|
|
122
|
+
}
|
|
123
|
+
const devices = yield this.ble.scan({ device: this });
|
|
124
|
+
if (devices && devices.length > 0) {
|
|
125
|
+
this.peripheral = devices[0].peripheral;
|
|
126
|
+
yield connectPeripheral(this.peripheral);
|
|
127
|
+
this.logEvent({ message: 'connect result: success', mode: 'device', device: { id, name, address } });
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
this.logEvent({ message: 'connect result: failure', mode: 'device', device: { id, name, address } });
|
|
135
|
+
this.connectState.isConnecting = false;
|
|
136
|
+
this.connectState.isConnected = false;
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
this.connectState.isConnecting = false;
|
|
142
|
+
this.connectState.isConnected = false;
|
|
143
|
+
this.logEvent({ message: 'connect result: error', error: err.message });
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
disconnect() {
|
|
149
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
const { id, name, address } = this;
|
|
151
|
+
this.logEvent({ message: 'disconnect requested', device: { id, name, address } });
|
|
152
|
+
this.connectState.isDisconnecting = true;
|
|
153
|
+
if (!this.connectState.isConnecting && !this.connectState.isConnected) {
|
|
154
|
+
this.connectState.isDisconnecting = false;
|
|
155
|
+
this.logEvent({ message: 'disconnect result: success', device: { id, name, address } });
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
if (this.connectState.isConnecting) {
|
|
159
|
+
this.cleanupListeners();
|
|
160
|
+
setTimeout(() => { this.connectState.isDisconnecting = false; }, 1000);
|
|
161
|
+
this.logEvent({ message: 'disconnect result: unclear - connect ongoing', device: { id, name, address } });
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
if (this.connectState.isConnected) {
|
|
165
|
+
this.ble.removeConnectedDevice(this);
|
|
166
|
+
this.cleanupListeners();
|
|
167
|
+
setTimeout(() => { this.connectState.isDisconnecting = false; }, 1000);
|
|
168
|
+
this.logEvent({ message: 'disconnect result: success', device: { id, name, address } });
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
exports.BleDevice = BleDevice;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventLogger } from 'gd-eventlog';
|
|
3
|
+
import { BleInterfaceClass, ConnectProps, ScanProps, BleDeviceClass, BleBinding } from './ble';
|
|
4
|
+
export interface ScanState {
|
|
5
|
+
isScanning: boolean;
|
|
6
|
+
timeout?: NodeJS.Timeout;
|
|
7
|
+
}
|
|
8
|
+
export interface ConnectState {
|
|
9
|
+
isConnecting: boolean;
|
|
10
|
+
isConnected: boolean;
|
|
11
|
+
timeout?: NodeJS.Timeout;
|
|
12
|
+
isOpened: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface BleDeviceInfo {
|
|
15
|
+
device: BleDeviceClass;
|
|
16
|
+
isConnected: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface BleDeviceClassInfo {
|
|
19
|
+
Class: typeof BleDeviceClass;
|
|
20
|
+
type: string;
|
|
21
|
+
services: string[];
|
|
22
|
+
id: string;
|
|
23
|
+
}
|
|
24
|
+
export default class BleInterface extends BleInterfaceClass {
|
|
25
|
+
scanState: ScanState;
|
|
26
|
+
connectState: ConnectState;
|
|
27
|
+
devices: BleDeviceInfo[];
|
|
28
|
+
logger: EventLogger;
|
|
29
|
+
static deviceClasses: BleDeviceClassInfo[];
|
|
30
|
+
constructor(props?: {
|
|
31
|
+
binding?: BleBinding;
|
|
32
|
+
log?: boolean;
|
|
33
|
+
logger?: EventLogger;
|
|
34
|
+
});
|
|
35
|
+
static register(id: string, type: string, Class: typeof BleDeviceClass, services: string[]): void;
|
|
36
|
+
logEvent(event: any): void;
|
|
37
|
+
onStateChange(state: any): void;
|
|
38
|
+
onError(err: any): void;
|
|
39
|
+
connect(props?: ConnectProps): Promise<boolean>;
|
|
40
|
+
disconnect(): Promise<boolean>;
|
|
41
|
+
isConnected(): boolean;
|
|
42
|
+
getDevicesFromServices(deviceTypes: (typeof BleDeviceClass)[], services: string | string[]): (typeof BleDeviceClass)[];
|
|
43
|
+
getServicesFromDeviceTypes(deviceTypes: (typeof BleDeviceClass)[]): string[];
|
|
44
|
+
getServicesFromDevice(device: BleDeviceClass): string[];
|
|
45
|
+
connectDevice(requested: BleDeviceClass, timeout?: number): Promise<BleDeviceClass>;
|
|
46
|
+
scan(props: ScanProps): Promise<BleDeviceClass[]>;
|
|
47
|
+
stopScan(): Promise<boolean>;
|
|
48
|
+
isScanning(): boolean;
|
|
49
|
+
addConnectedDevice(device: BleDeviceClass): void;
|
|
50
|
+
removeConnectedDevice(device: BleDeviceClass): void;
|
|
51
|
+
}
|