incyclist-devices 1.4.43 → 1.4.46
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 +242 -193
- 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 +148 -10
- 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
|
@@ -0,0 +1,170 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const ble_1 = require("./ble");
|
|
16
|
+
const gd_eventlog_1 = require("gd-eventlog");
|
|
17
|
+
const events_1 = __importDefault(require("events"));
|
|
18
|
+
class BlePeripheralConnector {
|
|
19
|
+
constructor(ble, peripheral) {
|
|
20
|
+
this.ble = ble;
|
|
21
|
+
this.peripheral = peripheral;
|
|
22
|
+
this.emitter = new events_1.default();
|
|
23
|
+
if (!this.peripheral || !this.ble)
|
|
24
|
+
throw new Error('Illegal Arguments');
|
|
25
|
+
this.state = { isConnected: false, isConnecting: false, isInitialized: false, isInitializing: false, isSubscribing: false };
|
|
26
|
+
this.services = undefined;
|
|
27
|
+
this.characteristics = undefined;
|
|
28
|
+
this.logger = new gd_eventlog_1.EventLogger('BLE');
|
|
29
|
+
}
|
|
30
|
+
logEvent(event) {
|
|
31
|
+
if (this.logger) {
|
|
32
|
+
this.logger.logEvent(event);
|
|
33
|
+
}
|
|
34
|
+
if (process.env.BLE_DEBUG) {
|
|
35
|
+
console.log('~~~BLE:', event);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
connect() {
|
|
39
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
40
|
+
if (this.state.isConnected)
|
|
41
|
+
return;
|
|
42
|
+
this.logEvent({ message: 'connect', peripheral: this.peripheral.address, state: this.state });
|
|
43
|
+
this.state.isConnecting = true;
|
|
44
|
+
try {
|
|
45
|
+
if (!this.state.isConnected || (this.peripheral && this.peripheral.state !== 'connected')) {
|
|
46
|
+
yield this.peripheral.connectAsync();
|
|
47
|
+
this.peripheral.once('disconnect', this.onDisconnect.bind(this));
|
|
48
|
+
}
|
|
49
|
+
this.state.isConnected = this.peripheral.state === 'connected';
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
this.logEvent({ message: 'Error', fn: 'connect()', error: err.message });
|
|
53
|
+
}
|
|
54
|
+
this.state.isConnecting = false;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
reconnect() {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
this.connect();
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
onDisconnect() {
|
|
63
|
+
this.logEvent({ message: 'onDisconnected', peripheral: this.peripheral.address, state: this.state });
|
|
64
|
+
this.state.isConnected = false;
|
|
65
|
+
this.reconnect();
|
|
66
|
+
}
|
|
67
|
+
initialize(enforce = false) {
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
if (this.state.isInitialized && !enforce)
|
|
70
|
+
return;
|
|
71
|
+
this.logEvent({ message: 'initialize', peripheral: this.peripheral.address, state: this.state, enforce });
|
|
72
|
+
if (this.state.isInitialized && enforce) {
|
|
73
|
+
this.state.isInitialized = false;
|
|
74
|
+
}
|
|
75
|
+
this.state.isInitializing = true;
|
|
76
|
+
this.characteristics = undefined;
|
|
77
|
+
this.services = undefined;
|
|
78
|
+
try {
|
|
79
|
+
const res = yield this.peripheral.discoverSomeServicesAndCharacteristicsAsync([], []);
|
|
80
|
+
this.characteristics = res.characteristics;
|
|
81
|
+
this.services = res.services;
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
}
|
|
85
|
+
this.state.isInitializing = false;
|
|
86
|
+
this.state.isInitialized = this.characteristics !== undefined && this.services !== undefined;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
subscribeAll(callback) {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
const cnt = this.characteristics.length;
|
|
92
|
+
this.state.isSubscribing = true;
|
|
93
|
+
const subscribed = [];
|
|
94
|
+
if (!this.state.subscribed)
|
|
95
|
+
this.state.subscribed = [];
|
|
96
|
+
for (let i = 0; i < cnt; i++) {
|
|
97
|
+
try {
|
|
98
|
+
const c = this.characteristics[i];
|
|
99
|
+
const isNotify = c.properties.find(p => p === 'notify');
|
|
100
|
+
if (isNotify && subscribed.find(uuid => uuid === c.uuid) === undefined) {
|
|
101
|
+
c.on('data', (data, _isNotification) => {
|
|
102
|
+
this.onData((0, ble_1.uuid)(c.uuid), data);
|
|
103
|
+
});
|
|
104
|
+
if (callback)
|
|
105
|
+
this.on((0, ble_1.uuid)(c.uuid), callback);
|
|
106
|
+
this.logEvent({ message: 'subscribe', peripheral: this.peripheral.address, characteristic: c.uuid });
|
|
107
|
+
if (this.state.subscribed.find(uuid => uuid === c.uuid) === undefined) {
|
|
108
|
+
try {
|
|
109
|
+
yield this.subscribe(c.uuid);
|
|
110
|
+
subscribed.push(c.uuid);
|
|
111
|
+
this.state.subscribed.push(c.uuid);
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
this.logEvent({ message: 'cannot subscribe', peripheral: this.peripheral.address, characteristic: c.uuid, error: err.message || err });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
console.log('~~~ error', err);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
this.state.isSubscribing = false;
|
|
124
|
+
this.state.subscribed = subscribed;
|
|
125
|
+
return subscribed;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
subscribe(characteristicUuid) {
|
|
129
|
+
return new Promise((resolve, reject) => {
|
|
130
|
+
const characteristic = this.characteristics.find(c => c.uuid === characteristicUuid || (0, ble_1.uuid)(c.uuid) === characteristicUuid);
|
|
131
|
+
if (!characteristic) {
|
|
132
|
+
reject(new Error('Characteristic not found'));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
characteristic.on('data', (data, _isNotification) => {
|
|
136
|
+
this.onData(characteristicUuid, data);
|
|
137
|
+
});
|
|
138
|
+
characteristic.subscribe((err) => {
|
|
139
|
+
if (err)
|
|
140
|
+
reject(err);
|
|
141
|
+
else
|
|
142
|
+
resolve(true);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
onData(characteristicUuid, data) {
|
|
147
|
+
this.emitter.emit(characteristicUuid, characteristicUuid, data);
|
|
148
|
+
}
|
|
149
|
+
on(characteristicUuid, callback) {
|
|
150
|
+
if (callback)
|
|
151
|
+
this.emitter.on(characteristicUuid, callback);
|
|
152
|
+
}
|
|
153
|
+
off(characteristicUuid, callback) {
|
|
154
|
+
if (callback)
|
|
155
|
+
this.emitter.off(characteristicUuid, callback);
|
|
156
|
+
}
|
|
157
|
+
removeAllListeners(characteristicUuid) {
|
|
158
|
+
this.emitter.removeAllListeners(characteristicUuid);
|
|
159
|
+
}
|
|
160
|
+
getState() {
|
|
161
|
+
return this.peripheral.state;
|
|
162
|
+
}
|
|
163
|
+
getCharachteristics() {
|
|
164
|
+
return this.characteristics;
|
|
165
|
+
}
|
|
166
|
+
getServices() {
|
|
167
|
+
return this.services;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
exports.default = BlePeripheralConnector;
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const CyclingMode_1 = require("../CyclingMode");
|
|
7
|
+
const power_base_1 = __importDefault(require("../modes/power-base"));
|
|
8
|
+
const config = {
|
|
9
|
+
name: "Smart Trainer",
|
|
10
|
+
description: "Calculates speed based on power and slope. Slope is set to the device",
|
|
11
|
+
properties: [
|
|
12
|
+
{ key: 'bikeType', name: 'Bike Type', description: '', type: CyclingMode_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain', 'Triathlon'], default: 'Race' },
|
|
13
|
+
{ key: 'startPower', name: 'Starting Power', description: 'Initial power in Watts at start of training', type: CyclingMode_1.CyclingModeProperyType.Integer, default: 50, min: 25, max: 800 },
|
|
14
|
+
]
|
|
15
|
+
};
|
|
16
|
+
class ERGCyclingMode extends power_base_1.default {
|
|
17
|
+
constructor(adapter, props) {
|
|
18
|
+
super(adapter, props);
|
|
19
|
+
this.hasBikeUpdate = false;
|
|
20
|
+
this.event = {};
|
|
21
|
+
this.initLogger('ERGMode');
|
|
22
|
+
}
|
|
23
|
+
getName() {
|
|
24
|
+
return config.name;
|
|
25
|
+
}
|
|
26
|
+
getDescription() {
|
|
27
|
+
return config.description;
|
|
28
|
+
}
|
|
29
|
+
getProperties() {
|
|
30
|
+
return config.properties;
|
|
31
|
+
}
|
|
32
|
+
getProperty(name) {
|
|
33
|
+
return config.properties.find(p => p.name === name);
|
|
34
|
+
}
|
|
35
|
+
getBikeInitRequest() {
|
|
36
|
+
const startPower = this.getSetting('startPower');
|
|
37
|
+
return { targetPower: startPower };
|
|
38
|
+
}
|
|
39
|
+
sendBikeUpdate(request) {
|
|
40
|
+
const getData = () => {
|
|
41
|
+
if (!this.data)
|
|
42
|
+
return {};
|
|
43
|
+
const { pedalRpm, slope, power, speed } = this.data;
|
|
44
|
+
return { pedalRpm, slope, power, speed };
|
|
45
|
+
};
|
|
46
|
+
this.logger.logEvent({ message: "processing update request", request, prev: this.prevRequest, data: getData(), event: this.event });
|
|
47
|
+
let newRequest = {};
|
|
48
|
+
try {
|
|
49
|
+
if (!request || request.reset || Object.keys(request).length === 0) {
|
|
50
|
+
this.prevRequest = {};
|
|
51
|
+
return request || {};
|
|
52
|
+
}
|
|
53
|
+
const prevData = this.data || {};
|
|
54
|
+
if (request.targetPower !== undefined) {
|
|
55
|
+
delete request.slope;
|
|
56
|
+
delete request.refresh;
|
|
57
|
+
}
|
|
58
|
+
if (this.event.starting && request.targetPower === undefined) {
|
|
59
|
+
newRequest.targetPower = this.getSetting('startPower');
|
|
60
|
+
if (this.event.tsStart && Date.now() - this.event.tsStart > 5000) {
|
|
61
|
+
delete this.event.starting;
|
|
62
|
+
delete this.event.tsStart;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (request.refresh) {
|
|
66
|
+
delete request.refresh;
|
|
67
|
+
newRequest.targetPower = this.prevRequest.targetPower;
|
|
68
|
+
}
|
|
69
|
+
if (request.slope !== undefined) {
|
|
70
|
+
if (!this.data)
|
|
71
|
+
this.data = {};
|
|
72
|
+
this.data.slope = request.slope;
|
|
73
|
+
}
|
|
74
|
+
if (request.maxPower !== undefined && request.minPower !== undefined && request.maxPower === request.minPower) {
|
|
75
|
+
request.targetPower = request.maxPower;
|
|
76
|
+
}
|
|
77
|
+
if (request.targetPower !== undefined) {
|
|
78
|
+
newRequest.targetPower = request.targetPower;
|
|
79
|
+
}
|
|
80
|
+
delete request.slope;
|
|
81
|
+
if (request.maxPower !== undefined) {
|
|
82
|
+
if (newRequest.targetPower !== undefined && newRequest.targetPower > request.maxPower) {
|
|
83
|
+
newRequest.targetPower = request.maxPower;
|
|
84
|
+
}
|
|
85
|
+
newRequest.maxPower = request.maxPower;
|
|
86
|
+
}
|
|
87
|
+
if (request.minPower !== undefined) {
|
|
88
|
+
if (newRequest.targetPower !== undefined && newRequest.targetPower < request.minPower) {
|
|
89
|
+
newRequest.targetPower = request.minPower;
|
|
90
|
+
}
|
|
91
|
+
newRequest.minPower = request.minPower;
|
|
92
|
+
}
|
|
93
|
+
if (newRequest.targetPower !== undefined && prevData.power !== undefined && newRequest.targetPower === prevData.power) {
|
|
94
|
+
delete newRequest.targetPower;
|
|
95
|
+
}
|
|
96
|
+
this.prevRequest = JSON.parse(JSON.stringify(request));
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
this.logger.logEvent({ message: "error", fn: 'sendBikeUpdate()', error: err.message || err, stack: err.stack });
|
|
100
|
+
}
|
|
101
|
+
return newRequest;
|
|
102
|
+
}
|
|
103
|
+
updateData(bikeData) {
|
|
104
|
+
const prevData = JSON.parse(JSON.stringify(this.data || {}));
|
|
105
|
+
const prevSpeed = prevData.speed;
|
|
106
|
+
const prevRequest = this.prevRequest || {};
|
|
107
|
+
const data = this.data || {};
|
|
108
|
+
const bikeType = this.getSetting('bikeType').toLowerCase();
|
|
109
|
+
delete this.event.rpmUpdated;
|
|
110
|
+
if (prevData === {} || prevData.speed === undefined || prevData.speed === 0) {
|
|
111
|
+
this.event.starting = true;
|
|
112
|
+
this.event.tsStart = Date.now();
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
const rpm = bikeData.pedalRpm || 0;
|
|
116
|
+
let power = bikeData.power || 0;
|
|
117
|
+
const slope = (prevData.slope !== undefined ? prevData.slope : prevRequest.slope || 0);
|
|
118
|
+
const distanceInternal = prevData.distanceInternal || 0;
|
|
119
|
+
if (!bikeData.pedalRpm || bikeData.isPedalling === false) {
|
|
120
|
+
power = 0;
|
|
121
|
+
}
|
|
122
|
+
const m = this.getWeight();
|
|
123
|
+
const t = this.getTimeSinceLastUpdate();
|
|
124
|
+
const { speed, distance } = this.calculateSpeedAndDistance(power, slope, m, t, { bikeType });
|
|
125
|
+
data.speed = parseFloat(speed.toFixed(1));
|
|
126
|
+
data.power = Math.round(power);
|
|
127
|
+
data.distanceInternal = Math.round(distanceInternal + distance);
|
|
128
|
+
data.slope = slope;
|
|
129
|
+
data.pedalRpm = rpm;
|
|
130
|
+
if (data.time !== undefined && !(this.event.starting && !bikeData.pedalRpm))
|
|
131
|
+
data.time += t;
|
|
132
|
+
else
|
|
133
|
+
data.time = 0;
|
|
134
|
+
data.heartrate = bikeData.heartrate;
|
|
135
|
+
data.isPedalling = bikeData.isPedalling;
|
|
136
|
+
if (rpm && rpm !== prevData.pedalRpm) {
|
|
137
|
+
this.event.rpmUpdated = true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
this.logger.logEvent({ message: 'error', fn: 'updateData()', error: err.message || err });
|
|
142
|
+
}
|
|
143
|
+
this.logger.logEvent({ message: "updateData result", data, bikeData, prevRequest, prevSpeed });
|
|
144
|
+
this.data = data;
|
|
145
|
+
return data;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.default = ERGCyclingMode;
|
package/lib/ble/ble.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
2
3
|
import EventEmitter from "events";
|
|
4
|
+
import BlePeripheralConnector from "./ble-peripheral";
|
|
3
5
|
export declare type ConnectProps = {
|
|
4
6
|
timeout?: number;
|
|
5
7
|
};
|
|
@@ -13,6 +15,20 @@ export interface ConnectState {
|
|
|
13
15
|
isConnected: boolean;
|
|
14
16
|
isDisconnecting: boolean;
|
|
15
17
|
}
|
|
18
|
+
export declare type BleDeviceInfo = {
|
|
19
|
+
manufacturer?: string;
|
|
20
|
+
hwRevision?: string;
|
|
21
|
+
swRevision?: string;
|
|
22
|
+
fwRevision?: string;
|
|
23
|
+
model?: string;
|
|
24
|
+
serialNo?: string;
|
|
25
|
+
};
|
|
26
|
+
export interface BleDeviceDescription {
|
|
27
|
+
id?: string;
|
|
28
|
+
address: string;
|
|
29
|
+
name?: string;
|
|
30
|
+
profile: string;
|
|
31
|
+
}
|
|
16
32
|
export declare abstract class BleDeviceClass extends EventEmitter {
|
|
17
33
|
static services: string[];
|
|
18
34
|
id?: string;
|
|
@@ -26,6 +42,7 @@ export declare abstract class BleDeviceClass extends EventEmitter {
|
|
|
26
42
|
abstract getServiceUUids(): string[];
|
|
27
43
|
abstract connect(props?: ConnectProps): Promise<boolean>;
|
|
28
44
|
abstract disconnect(): Promise<boolean>;
|
|
45
|
+
abstract getDeviceInfo(): Promise<BleDeviceInfo>;
|
|
29
46
|
}
|
|
30
47
|
export interface BleBinding extends EventEmitter {
|
|
31
48
|
startScanning(serviceUUIDs?: string[], allowDuplicates?: boolean, callback?: (error?: Error) => void): void;
|
|
@@ -36,7 +53,7 @@ export interface BleBinding extends EventEmitter {
|
|
|
36
53
|
export declare type ScanProps = {
|
|
37
54
|
timeout?: number;
|
|
38
55
|
deviceTypes?: (typeof BleDeviceClass)[];
|
|
39
|
-
|
|
56
|
+
requested?: BleDeviceClass | BleDeviceDescription;
|
|
40
57
|
isBackgroundScan?: boolean;
|
|
41
58
|
};
|
|
42
59
|
export declare class BleBindingWrapper {
|
|
@@ -61,6 +78,12 @@ export declare abstract class BleInterfaceClass extends EventEmitter {
|
|
|
61
78
|
abstract addConnectedDevice(device: BleDeviceClass): void;
|
|
62
79
|
abstract removeConnectedDevice(device: BleDeviceClass): void;
|
|
63
80
|
abstract findConnected(device: BleDeviceClass | BlePeripheral): BleDeviceClass;
|
|
81
|
+
abstract getConnector(peripheral: BlePeripheral): BlePeripheralConnector;
|
|
82
|
+
abstract findPeripheral(peripheral: BlePeripheral | {
|
|
83
|
+
id?: string;
|
|
84
|
+
address?: string;
|
|
85
|
+
name?: string;
|
|
86
|
+
}): BlePeripheral;
|
|
64
87
|
getBinding(): BleBinding;
|
|
65
88
|
setBinding(binding: BleBinding): void;
|
|
66
89
|
}
|
|
@@ -73,6 +96,11 @@ export interface BlePeripheral extends EventEmitter, BleDeviceIdentifier {
|
|
|
73
96
|
discoverSomeServicesAndCharacteristicsAsync(serviceUUIDs: string[], characteristicUUIDs: string[]): Promise<any>;
|
|
74
97
|
}
|
|
75
98
|
export interface BleCharacteristic extends EventEmitter {
|
|
99
|
+
uuid: string;
|
|
100
|
+
properties: string[];
|
|
101
|
+
subscribe(callback: (err: Error) => void): void;
|
|
102
|
+
read(callback: (err: Error, data: Buffer) => void): void;
|
|
103
|
+
write(data: Buffer, withoutResponse: boolean, callback?: (err: Error) => void): void;
|
|
76
104
|
}
|
|
77
105
|
export declare type BleDeviceProps = {
|
|
78
106
|
id?: string;
|
package/lib/ble/ble.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.uuid = exports.BleState = exports.BleInterfaceClass = exports.BleBindingWrapper = exports.BleDeviceClass = void 0;
|
|
6
7
|
const events_1 = __importDefault(require("events"));
|
|
7
8
|
class BleDeviceClass extends events_1.default {
|
|
8
9
|
constructor() {
|
|
@@ -59,7 +60,7 @@ var BleState;
|
|
|
59
60
|
BleState["POWERED_OFF"] = "poweredOff";
|
|
60
61
|
BleState["POWERED_ON"] = "poweredOn";
|
|
61
62
|
})(BleState = exports.BleState || (exports.BleState = {}));
|
|
62
|
-
|
|
63
|
+
const uuid = (s) => {
|
|
63
64
|
if (s) {
|
|
64
65
|
if (s.includes('-')) {
|
|
65
66
|
const parts = s.split('-');
|
|
@@ -69,3 +70,4 @@ exports.uuid = (s) => {
|
|
|
69
70
|
return s;
|
|
70
71
|
}
|
|
71
72
|
};
|
|
73
|
+
exports.uuid = uuid;
|
package/lib/ble/fm.d.ts
CHANGED
|
@@ -32,17 +32,31 @@ declare type IndoorBikeData = {
|
|
|
32
32
|
remainingTime?: number;
|
|
33
33
|
raw?: string;
|
|
34
34
|
};
|
|
35
|
+
declare type IndoorBikeFeatures = {
|
|
36
|
+
fitnessMachine: number;
|
|
37
|
+
targetSettings: number;
|
|
38
|
+
};
|
|
35
39
|
export default class BleFitnessMachineDevice extends BleDevice {
|
|
36
40
|
static services: string[];
|
|
37
41
|
static characteristics: string[];
|
|
38
42
|
data: IndoorBikeData;
|
|
43
|
+
features: IndoorBikeFeatures;
|
|
44
|
+
hasControl: boolean;
|
|
45
|
+
isCPSubscribed: boolean;
|
|
39
46
|
constructor(props?: any);
|
|
47
|
+
init(): Promise<boolean>;
|
|
48
|
+
onDisconnect(): void;
|
|
40
49
|
getProfile(): string;
|
|
41
50
|
getServiceUUids(): string[];
|
|
51
|
+
isBike(): boolean;
|
|
52
|
+
isPower(): boolean;
|
|
53
|
+
isHrm(): boolean;
|
|
54
|
+
parseHrm(_data: Uint8Array): IndoorBikeData;
|
|
42
55
|
parseIndoorBikeData(_data: Uint8Array): IndoorBikeData;
|
|
56
|
+
getFitnessMachineFeatures(): Promise<IndoorBikeFeatures>;
|
|
43
57
|
onData(characteristic: string, data: Buffer): void;
|
|
44
|
-
|
|
45
|
-
|
|
58
|
+
requestControl(): Promise<boolean>;
|
|
59
|
+
setTargetPower(power: number): Promise<void>;
|
|
46
60
|
reset(): void;
|
|
47
61
|
}
|
|
48
62
|
export declare class FmAdapter extends DeviceAdapter {
|
|
@@ -59,6 +73,7 @@ export declare class FmAdapter extends DeviceAdapter {
|
|
|
59
73
|
isBike(): boolean;
|
|
60
74
|
isHrm(): boolean;
|
|
61
75
|
isPower(): boolean;
|
|
76
|
+
isSame(device: DeviceAdapter): boolean;
|
|
62
77
|
getProfile(): string;
|
|
63
78
|
getName(): string;
|
|
64
79
|
getDisplayName(): string;
|