incyclist-devices 2.1.1 → 2.1.3

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.
Files changed (41) hide show
  1. package/lib/antv2/base/adapter.d.ts +13 -7
  2. package/lib/antv2/base/adapter.js +162 -89
  3. package/lib/antv2/base/interface.d.ts +46 -0
  4. package/lib/antv2/base/interface.js +343 -0
  5. package/lib/antv2/factories/adapter-factory.d.ts +4 -4
  6. package/lib/antv2/factories/adapter-factory.js +17 -9
  7. package/lib/antv2/fe/adapter.d.ts +7 -11
  8. package/lib/antv2/fe/adapter.js +50 -145
  9. package/lib/antv2/index.d.ts +1 -1
  10. package/lib/antv2/index.js +2 -2
  11. package/lib/antv2/types.d.ts +9 -0
  12. package/lib/base/adpater.js +10 -2
  13. package/lib/ble/adapter-factory.d.ts +9 -8
  14. package/lib/ble/base/adapter.d.ts +13 -10
  15. package/lib/ble/base/adapter.js +9 -8
  16. package/lib/ble/base/types.d.ts +2 -0
  17. package/lib/ble/base/types.js +2 -0
  18. package/lib/ble/ble-interface.d.ts +0 -4
  19. package/lib/ble/ble-interface.js +0 -11
  20. package/lib/ble/cp/adapter.d.ts +5 -3
  21. package/lib/ble/cp/adapter.js +1 -7
  22. package/lib/ble/elite/adapter.d.ts +5 -3
  23. package/lib/ble/elite/adapter.js +1 -7
  24. package/lib/ble/fm/adapter.d.ts +4 -3
  25. package/lib/ble/fm/adapter.js +1 -6
  26. package/lib/ble/hr/adapter.d.ts +4 -2
  27. package/lib/ble/hr/adapter.js +1 -3
  28. package/lib/ble/peripheral-cache.d.ts +3 -1
  29. package/lib/ble/tacx/adapter.d.ts +3 -1
  30. package/lib/ble/tacx/adapter.js +1 -0
  31. package/lib/ble/wahoo/adapter.d.ts +3 -1
  32. package/lib/ble/wahoo/adapter.js +1 -0
  33. package/lib/factories/interfaces.d.ts +1 -1
  34. package/lib/factories/interfaces.js +2 -2
  35. package/lib/modes/power-base.js +1 -4
  36. package/lib/serial/base/serial-interface.js +1 -1
  37. package/lib/serial/base/serial-scanner.js +2 -2
  38. package/lib/serial/daum/classic/mock.js +1 -1
  39. package/lib/utils/utils.d.ts +1 -0
  40. package/lib/utils/utils.js +18 -1
  41. package/package.json +1 -1
@@ -0,0 +1,343 @@
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 events_1 = __importDefault(require("events"));
16
+ const gd_eventlog_1 = require("gd-eventlog");
17
+ const sensor_factory_1 = __importDefault(require("../factories/sensor-factory"));
18
+ const utils_1 = require("../../utils/utils");
19
+ class AntInterface extends events_1.default {
20
+ static getInstance(props = {}) {
21
+ if (AntInterface._instance === undefined)
22
+ AntInterface._instance = new AntInterface(props);
23
+ return AntInterface._instance;
24
+ }
25
+ static hasInstance() {
26
+ return AntInterface._instance !== undefined;
27
+ }
28
+ constructor(props) {
29
+ super();
30
+ this.props = props;
31
+ this.device = undefined;
32
+ this.connected = false;
33
+ this.connectPromise = null;
34
+ this.logEnabled = props.log || true;
35
+ const { binding, logger } = props;
36
+ this.setLogger(logger || new gd_eventlog_1.EventLogger('Ant+'));
37
+ if (binding) {
38
+ this.setBinding(binding);
39
+ }
40
+ }
41
+ getName() {
42
+ return AntInterface.INTERFACE_NAME;
43
+ }
44
+ getBinding() {
45
+ return this.Binding;
46
+ }
47
+ setBinding(binding) {
48
+ this.Binding = binding;
49
+ }
50
+ getLogger() {
51
+ return this.logger;
52
+ }
53
+ setLogger(logger) {
54
+ this.logger = logger;
55
+ }
56
+ enableLogging() {
57
+ this.logEnabled = true;
58
+ }
59
+ disableLogging() {
60
+ this.logEnabled = false;
61
+ }
62
+ logEvent(event) {
63
+ if (!this.logEnabled || !this.logger)
64
+ return;
65
+ this.logger.logEvent(event);
66
+ const w = global.window;
67
+ if ((w === null || w === void 0 ? void 0 : w.DEVICE_DEBUG) || (0, utils_1.isTrue)(process.env.ANT_DEBUG)) {
68
+ console.log('~~~ ANT', event);
69
+ }
70
+ }
71
+ isConnected() {
72
+ return this.connected && this.device !== undefined;
73
+ }
74
+ connect() {
75
+ return __awaiter(this, void 0, void 0, function* () {
76
+ if (this.isConnected())
77
+ return true;
78
+ if (this.connectPromise) {
79
+ return yield this.connectPromise;
80
+ }
81
+ const _connect = () => __awaiter(this, void 0, void 0, function* () {
82
+ try {
83
+ this.logEvent({ message: 'ANT+ connecting ...' });
84
+ const device = new this.Binding(Object.assign(Object.assign({}, this.props), { logger: this.logger }));
85
+ const opened = yield device.open();
86
+ if (!opened) {
87
+ this.logEvent({ message: 'ANT+ not connected' });
88
+ return false;
89
+ }
90
+ this.device = device;
91
+ this.connected = true;
92
+ this.logEvent({ message: 'ANT+ connected' });
93
+ return true;
94
+ }
95
+ catch (err) {
96
+ this.logEvent({ message: 'error', fn: 'connect', error: err.message, stack: err.stack });
97
+ this.connected = false;
98
+ return false;
99
+ }
100
+ });
101
+ this.connectPromise = _connect();
102
+ return yield this.connectPromise;
103
+ });
104
+ }
105
+ disconnect() {
106
+ return __awaiter(this, void 0, void 0, function* () {
107
+ this.logEvent({ message: 'ANT+ disconnecting ...' });
108
+ let closed = false;
109
+ if (this.device) {
110
+ try {
111
+ closed = yield this.device.close();
112
+ }
113
+ catch (_a) {
114
+ closed = false;
115
+ }
116
+ }
117
+ else {
118
+ closed = true;
119
+ }
120
+ this.logEvent({ message: 'ANT+ disconnected' });
121
+ this.connectPromise = null;
122
+ this.scanPromise = null;
123
+ this.connected = false;
124
+ return closed;
125
+ });
126
+ }
127
+ onError(profile, error) {
128
+ this.logEvent({ message: 'ANT+ERROR:', profile, error });
129
+ }
130
+ onData(profile, id, data, tag) {
131
+ this.emit('data', profile, id, data, tag);
132
+ }
133
+ getReconnectPause() {
134
+ return 1000;
135
+ }
136
+ scannerWaitForConnection() {
137
+ var _a;
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ let scanFinished = false;
140
+ let scanStopRequested = false;
141
+ this.activeScan.emitter.once('timeout', () => {
142
+ this.activeScan.emitter.removeAllListeners();
143
+ scanFinished = true;
144
+ });
145
+ this.activeScan.emitter.once('stop', () => {
146
+ scanStopRequested = true;
147
+ this.activeScan.emitter.removeAllListeners();
148
+ });
149
+ while (!this.isConnected() && !scanFinished && !scanStopRequested) {
150
+ const connected = yield this.connect();
151
+ if (!connected)
152
+ yield (0, utils_1.sleep)(this.getReconnectPause());
153
+ }
154
+ if (scanStopRequested)
155
+ this.emit('scan stopped', true);
156
+ (_a = this.activeScan) === null || _a === void 0 ? void 0 : _a.emitter.removeAllListeners();
157
+ });
158
+ }
159
+ scan(props = {}) {
160
+ return __awaiter(this, void 0, void 0, function* () {
161
+ this.logEvent({ message: 'starting scan ..' });
162
+ if (this.isScanning()) {
163
+ return yield this.scanPromise;
164
+ }
165
+ this.activeScan = { emitter: new events_1.default() };
166
+ const detected = [];
167
+ const _scan = () => new Promise((done) => __awaiter(this, void 0, void 0, function* () {
168
+ const onDetected = (profile, deviceID) => {
169
+ if (deviceID && detected.find(s => s.deviceID === deviceID && s.profile === profile) === undefined) {
170
+ try {
171
+ detected.push({ interface: this.getName(), profile, deviceID });
172
+ this.emit('device', { interface: 'ant', profile, deviceID });
173
+ }
174
+ catch (err) {
175
+ this.logEvent({ message: 'error', fn: 'onDetected', error: err.message, stack: err.stack });
176
+ }
177
+ }
178
+ };
179
+ const addListeners = (channel) => {
180
+ channel.on('detected', onDetected);
181
+ channel.on('data', this.onData.bind(this));
182
+ channel.on('error', this.onError.bind(this));
183
+ };
184
+ const removeListeners = (channel) => {
185
+ channel.off('detected', onDetected);
186
+ channel.off('data', this.onData.bind(this));
187
+ channel.off('error', this.onError.bind(this));
188
+ };
189
+ yield this.scannerWaitForConnection();
190
+ if (!this.isConnected()) {
191
+ return done(detected);
192
+ }
193
+ let channel;
194
+ channel = this.device.getChannel();
195
+ if (!channel)
196
+ return done(detected);
197
+ this.activeScan.channel = channel;
198
+ channel.setProps({ logger: this.logger });
199
+ const sensors = sensor_factory_1.default.createAll();
200
+ sensors.forEach((sensor) => {
201
+ channel.attach(sensor);
202
+ });
203
+ addListeners(channel);
204
+ try {
205
+ const success = yield channel.startScanner();
206
+ this.logEvent({ message: 'scan started', success });
207
+ }
208
+ catch (err) {
209
+ this.logEvent({ message: 'scan could not be started', error: err.message, stack: err.stack });
210
+ removeListeners(channel);
211
+ return done(detected);
212
+ }
213
+ this.activeScan.emitter.on('stop', () => __awaiter(this, void 0, void 0, function* () {
214
+ this.activeScan.emitter.removeAllListeners();
215
+ this.emit('stop-scan');
216
+ const stopped = yield this.activeScan.channel.stopScanner();
217
+ this.logEvent({ message: 'scan stopped' });
218
+ removeListeners(channel);
219
+ this.activeScan = undefined;
220
+ this.scanPromise = null;
221
+ this.emit('scan stopped', stopped);
222
+ done(detected);
223
+ }));
224
+ this.activeScan.emitter.on('timeout', () => __awaiter(this, void 0, void 0, function* () {
225
+ this.activeScan.emitter.removeAllListeners();
226
+ yield this.activeScan.channel.stopScanner();
227
+ this.emit('stop-scan');
228
+ removeListeners(channel);
229
+ this.logEvent({ message: 'scan finished(timeout) ..' });
230
+ done(detected);
231
+ }));
232
+ }));
233
+ const { timeout } = props;
234
+ this.scanPromise = _scan();
235
+ if (timeout) {
236
+ yield (0, utils_1.waitWithTimeout)(this.scanPromise, timeout, () => {
237
+ var _a;
238
+ (_a = this.activeScan) === null || _a === void 0 ? void 0 : _a.emitter.emit('timeout');
239
+ });
240
+ this.scanPromise = null;
241
+ this.activeScan = null;
242
+ return detected;
243
+ }
244
+ else {
245
+ const res = yield this.scanPromise;
246
+ this.scanPromise = null;
247
+ this.activeScan = null;
248
+ return res;
249
+ }
250
+ });
251
+ }
252
+ isScanning() {
253
+ return this.scanPromise !== undefined && this.scanPromise !== null;
254
+ }
255
+ stopScan() {
256
+ return __awaiter(this, void 0, void 0, function* () {
257
+ this.logEvent({ message: 'stopping scan ..' });
258
+ if (!this.isScanning())
259
+ return true;
260
+ return new Promise(done => {
261
+ this.activeScan.emitter.emit('stop');
262
+ this.once('scan stopped', (res) => {
263
+ this.logEvent({ message: 'stopping scan done ..' });
264
+ done(res);
265
+ });
266
+ });
267
+ });
268
+ }
269
+ startSensor(sensor, onDeviceData) {
270
+ return __awaiter(this, void 0, void 0, function* () {
271
+ if (!this.isConnected()) {
272
+ const connected = yield this.connect();
273
+ if (!connected)
274
+ return false;
275
+ }
276
+ let channel;
277
+ channel = this.device.getChannel();
278
+ if (!channel)
279
+ return false;
280
+ channel.setProps({ logger: this.logger });
281
+ const onData = (profile, deviceID, data, tag) => {
282
+ if (profile === sensor.getProfile() && deviceID === sensor.getDeviceID())
283
+ this.onData(profile, deviceID, data, tag);
284
+ onDeviceData(data);
285
+ };
286
+ channel.on('data', onData);
287
+ sensor.setChannel(channel);
288
+ try {
289
+ const started = yield channel.startSensor(sensor);
290
+ if (!started) {
291
+ this.logEvent({ message: 'could not start sensor' });
292
+ channel.off('data', onData);
293
+ }
294
+ return started;
295
+ }
296
+ catch (err) {
297
+ this.logEvent({ message: 'could not start sensor', error: err.message, stack: err.stack });
298
+ channel.off('data', onData);
299
+ try {
300
+ yield channel.stopSensor(sensor);
301
+ }
302
+ catch (_a) { }
303
+ return false;
304
+ }
305
+ });
306
+ }
307
+ stopSensor(sensor) {
308
+ return __awaiter(this, void 0, void 0, function* () {
309
+ if (!this.isConnected()) {
310
+ return true;
311
+ }
312
+ const channel = sensor.getChannel();
313
+ if (channel) {
314
+ try {
315
+ if (!channel.flush) {
316
+ this.logEvent({ message: 'old version of ant-channel detected' });
317
+ channel.flush = () => {
318
+ const c = channel;
319
+ c.messageQueue.forEach(msg => { msg.resolve(false); });
320
+ c.messageQueue = [];
321
+ c.isWriting = false;
322
+ };
323
+ }
324
+ channel.flush();
325
+ channel.removeAllListeners('data');
326
+ const stopped = yield channel.stopSensor(sensor);
327
+ return stopped;
328
+ }
329
+ catch (err) {
330
+ this.logEvent({ message: 'could not stop sensor', error: err.message, deviceID: sensor.getDeviceID(), stack: err.stack });
331
+ return false;
332
+ }
333
+ }
334
+ else {
335
+ this.logEvent({ message: 'could not stop sensor', deviceID: sensor.getDeviceID(), error: 'no channel attached' });
336
+ return false;
337
+ }
338
+ });
339
+ }
340
+ }
341
+ AntInterface._instance = undefined;
342
+ AntInterface.INTERFACE_NAME = 'ant';
343
+ exports.default = AntInterface;
@@ -1,13 +1,13 @@
1
1
  import { Profile } from "incyclist-ant-plus";
2
2
  import AntAdapter from "../base/adapter";
3
- import { AntDeviceProperties, AntDeviceSettings, LegacyProfile, BaseDeviceData } from "../types";
4
- import { AntAdapterInfo, AdapterQuery } from "../types";
3
+ import { AntDeviceProperties, AntDeviceSettings, LegacyProfile, BaseDeviceData, AntAdapterInfo, AdapterQuery } from "../types";
5
4
  export default class AntAdapterFactory {
6
- static _instance: AntAdapterFactory;
7
- adapters: AntAdapterInfo[];
5
+ protected static _instance: AntAdapterFactory | undefined;
6
+ protected adapters: AntAdapterInfo[];
8
7
  static getInstance(): AntAdapterFactory;
9
8
  constructor();
10
9
  register<TDeviceData extends BaseDeviceData>(antProfile: Profile, incyclistProfile: LegacyProfile, Adapter: typeof AntAdapter<TDeviceData>): void;
10
+ _getAll(): AntAdapterInfo[];
11
11
  getAdapter(query?: AdapterQuery): any;
12
12
  createInstance(settings: AntDeviceSettings, props?: AntDeviceProperties): any;
13
13
  createFromDetected(profile: Profile, deviceID: number, props?: AntDeviceProperties): any;
@@ -17,6 +17,9 @@ class AntAdapterFactory {
17
17
  else
18
18
  this.adapters.push(info);
19
19
  }
20
+ _getAll() {
21
+ return this.adapters;
22
+ }
20
23
  getAdapter(query) {
21
24
  const { antProfile, incyclistProfile } = query;
22
25
  if (!antProfile && !incyclistProfile)
@@ -24,7 +27,7 @@ class AntAdapterFactory {
24
27
  let found;
25
28
  if (antProfile)
26
29
  found = this.adapters.find(a => a.antProfile === antProfile);
27
- if (incyclistProfile)
30
+ if (!found && incyclistProfile)
28
31
  found = this.adapters.find(a => a.incyclistProfile === incyclistProfile);
29
32
  return found;
30
33
  }
@@ -36,28 +39,33 @@ class AntAdapterFactory {
36
39
  try {
37
40
  const incyclistProfile = profile;
38
41
  info = this.getAdapter({ incyclistProfile });
39
- isLegacy = true;
42
+ isLegacy = (info !== undefined && info !== null);
40
43
  }
41
44
  catch (_a) {
42
- isLegacy = false;
45
+ return;
43
46
  }
44
47
  }
45
48
  if (!isLegacy) {
46
49
  const antProfile = profile;
47
- info = this.getAdapter({ antProfile });
50
+ try {
51
+ info = this.getAdapter({ antProfile });
52
+ }
53
+ catch (_b) { }
54
+ }
55
+ if (info && info.Adapter) {
56
+ const { deviceID, interface: ifName } = settings;
57
+ const { antProfile } = info;
58
+ return new info.Adapter({ profile: antProfile, interface: ifName, deviceID }, props);
48
59
  }
49
- if (info && info.Adapter)
50
- return new info.Adapter(settings, props);
51
60
  }
52
61
  createFromDetected(profile, deviceID, props) {
53
62
  const info = this.getAdapter({ antProfile: profile });
54
63
  if (!info || !info.Adapter)
55
64
  return;
56
65
  const settings = Object.assign({}, {
57
- profile: info.incyclistProfile,
66
+ profile: info.antProfile,
58
67
  deviceID: deviceID.toString(),
59
- interface: 'ant',
60
- protocol: 'Ant'
68
+ interface: 'ant'
61
69
  });
62
70
  return new info.Adapter(settings, props);
63
71
  }
@@ -1,9 +1,8 @@
1
1
  import { FitnessEquipmentSensorState, Profile } from "incyclist-ant-plus";
2
2
  import AntAdapter from "../base/adapter";
3
3
  import { UpdateRequest } from '../../modes/types';
4
- import { IncyclistBikeData } from "../../types/data";
5
4
  import { AntDeviceProperties, AntDeviceSettings, LegacyProfile } from "../types";
6
- import { ControllerConfig } from "../../types/adapter";
5
+ import { IncyclistBikeData, ControllerConfig } from "../../types";
7
6
  interface AntFEStartDeviceProperties extends AntDeviceProperties {
8
7
  reconnect?: boolean;
9
8
  reconnectTimeout?: number;
@@ -15,22 +14,19 @@ export default class AntFEAdapter extends AntAdapter<FitnessEquipmentSensorState
15
14
  protected distanceInternal?: number;
16
15
  protected startProps: AntDeviceProperties;
17
16
  protected promiseReconnect: Promise<boolean>;
18
- protected sensorConnected: boolean;
19
17
  constructor(settings: AntDeviceSettings, props?: AntDeviceProperties);
20
18
  getDisplayName(): string;
21
- getDefaultReconnectDelay(): number;
22
19
  isReconnecting(): boolean;
23
20
  sendUpdate(request: UpdateRequest, forced?: boolean): Promise<void>;
24
21
  onDeviceData(deviceData: FitnessEquipmentSensorState): void;
25
22
  mapData(deviceData: FitnessEquipmentSensorState): IncyclistBikeData;
26
23
  transformData(adapterData: IncyclistBikeData, deviceData: FitnessEquipmentSensorState): void;
27
- start(props?: AntFEStartDeviceProperties): Promise<any>;
28
- performStart(props: AntFEStartDeviceProperties, isReconnect: boolean): Promise<any>;
29
- private waitForInitialData;
30
- stopSensor(): Promise<void>;
31
- initSensor(status: any, props: any): Promise<boolean>;
32
- sendInititalUserMessage(status: any, props: any): Promise<void>;
33
- sendInitialRequest(status: any, props: any): Promise<void>;
24
+ start(props?: AntFEStartDeviceProperties): Promise<boolean>;
25
+ resetStartStatus(): void;
26
+ startPreChecks(props: AntFEStartDeviceProperties): Promise<'done' | 'connected' | 'connection-failed'>;
27
+ initControl(): Promise<void>;
28
+ sendInititalUserMessage(): Promise<void>;
29
+ sendInitialRequest(): Promise<void>;
34
30
  setFEDefaultTimeout(): void;
35
31
  stop(): Promise<boolean>;
36
32
  reconnect(): Promise<boolean>;