incyclist-devices 2.0.30 → 2.0.32

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.
@@ -83,9 +83,6 @@ class BleWahooAdapter extends fm_1.BleFmAdapter {
83
83
  comms.on('data', (data) => {
84
84
  this.onDeviceData(data);
85
85
  });
86
- if (comms.features.heartrate && !this.hasCapability(capabilities_1.IncyclistCapability.HeartRate)) {
87
- this.capabilities.push(capabilities_1.IncyclistCapability.HeartRate);
88
- }
89
86
  this.resetData();
90
87
  this.stopped = false;
91
88
  this.started = true;
@@ -14,6 +14,7 @@ export declare class SerialIncyclistDevice extends ControllableDevice {
14
14
  isEqual(settings: SerialDeviceSettings): boolean;
15
15
  getPort(): string;
16
16
  getUniqueName(): string;
17
+ getSerialInterface(): SerialInterface;
17
18
  getInterface(): string;
18
19
  setMaxUpdateFrequency(ms: number): void;
19
20
  setPullFrequency(ms: number): void;
@@ -40,6 +40,9 @@ class SerialIncyclistDevice extends adpater_1.ControllableDevice {
40
40
  getUniqueName() {
41
41
  return `${this.getName()} (${this.getPort()})`;
42
42
  }
43
+ getSerialInterface() {
44
+ throw new Error('not implemented');
45
+ }
43
46
  getInterface() {
44
47
  return 'serial';
45
48
  }
@@ -7,14 +7,14 @@ export interface TCPOpenOptions extends OpenOptions {
7
7
  timeout?: number;
8
8
  }
9
9
  export declare interface TCPBindingInterface<T extends BindingPortInterface = BindingPortInterface, R extends OpenOptions = OpenOptions, P extends PortInfo = PortInfo> extends BindingInterface<TCPPortBinding, TCPOpenOptions> {
10
- list(port?: number): Promise<P[]>;
10
+ list(port?: number, excludeList?: string[]): Promise<P[]>;
11
11
  }
12
12
  export declare class CanceledError extends Error {
13
13
  canceled: true;
14
14
  constructor(message: string);
15
15
  }
16
16
  export declare function scanPort(host: string, port: number): Promise<boolean>;
17
- export declare function scanSubNet(sn: string, port: number): Promise<string[]>;
17
+ export declare function scanSubNet(sn: string, port: number, excludeHosts?: string[]): Promise<string[]>;
18
18
  export declare function getSubnets(): string[];
19
19
  export declare const TCPBinding: TCPBindingInterface;
20
20
  export declare class TCPPortBinding implements BindingPortInterface {
@@ -50,10 +50,11 @@ function scanPort(host, port) {
50
50
  });
51
51
  }
52
52
  exports.scanPort = scanPort;
53
- function scanSubNet(sn, port) {
53
+ function scanSubNet(sn, port, excludeHosts) {
54
54
  const range = [];
55
55
  for (let i = 1; i < 255; i++)
56
- range.push(i);
56
+ if (!excludeHosts || !excludeHosts.includes(`${sn}.${i}`))
57
+ range.push(i);
57
58
  return Promise.all(range.map(j => scanPort(`${sn}.${j}`, port).then(success => success ? `${sn}.${j}` : null).catch()))
58
59
  .then(hosts => hosts.filter(h => h !== null))
59
60
  .catch();
@@ -86,13 +87,14 @@ function getSubnets() {
86
87
  }
87
88
  exports.getSubnets = getSubnets;
88
89
  exports.TCPBinding = {
89
- list(port) {
90
+ list(port, excludeList) {
90
91
  return __awaiter(this, void 0, void 0, function* () {
91
92
  if (!port)
92
93
  return [];
93
94
  const subnets = getSubnets();
94
- const hosts = [];
95
- yield Promise.all(subnets.map(sn => scanSubNet(sn, port).then(found => { hosts.push(...found); })));
95
+ let hosts = [];
96
+ const excludeHosts = excludeList.map(e => e && e.includes(':') ? e.split(':')[0] : e);
97
+ yield Promise.all(subnets.map(sn => scanSubNet(sn, port, excludeHosts).then(found => { hosts.push(...found); })));
96
98
  return hosts.map(host => ({
97
99
  path: `${host}:${port}`,
98
100
  manufacturer: undefined,
@@ -199,8 +199,10 @@ class DaumAdapterBase extends adapter_1.SerialIncyclistDevice {
199
199
  if (this.stopped)
200
200
  return Promise.resolve(true);
201
201
  this.logEvent({ message: 'stop request' });
202
+ if (this.paused)
203
+ this.resume();
202
204
  this.stopped = true;
203
- return new Promise((resolve, reject) => {
205
+ return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
204
206
  try {
205
207
  if (this.iv) {
206
208
  if (this.iv.sync)
@@ -211,15 +213,15 @@ class DaumAdapterBase extends adapter_1.SerialIncyclistDevice {
211
213
  }
212
214
  if (this.bike.stopWorker && typeof this.bike.stopWorker === 'function')
213
215
  this.bike.stopWorker();
216
+ yield this.bike.close();
214
217
  this.logEvent({ message: 'stop request completed' });
215
- this.paused = undefined;
216
218
  resolve(true);
217
219
  }
218
220
  catch (err) {
219
221
  this.logEvent({ message: 'stop error', error: err.message });
220
222
  reject(err);
221
223
  }
222
- });
224
+ }));
223
225
  }
224
226
  canSendUpdate() {
225
227
  if (this.paused || this.stopped)
@@ -2,6 +2,7 @@ import CyclingMode from '../../../modes/cycling-mode';
2
2
  import DaumAdapter from '../DaumAdapter';
3
3
  import { DeviceProperties } from '../../../types/device';
4
4
  import { SerialDeviceSettings } from '../../adapter';
5
+ import SerialInterface from '../../serial-interface';
5
6
  export interface DaumClassicDeviceProperties extends DeviceProperties {
6
7
  gear?: number;
7
8
  }
@@ -21,6 +22,7 @@ export default class DaumClassicAdapter extends DaumAdapter {
21
22
  getProtocolName(): string;
22
23
  getSupportedCyclingModes(): Array<any>;
23
24
  getDefaultCyclingMode(): CyclingMode;
25
+ getSerialInterface(): SerialInterface;
24
26
  check(): Promise<boolean>;
25
27
  performCheck(): Promise<boolean>;
26
28
  pause(): Promise<boolean>;
@@ -80,6 +80,10 @@ class DaumClassicAdapter extends DaumAdapter_1.default {
80
80
  getDefaultCyclingMode() {
81
81
  return new daum_classic_1.default(this);
82
82
  }
83
+ getSerialInterface() {
84
+ var _a;
85
+ return (_a = this.bike) === null || _a === void 0 ? void 0 : _a.serial;
86
+ }
83
87
  check() {
84
88
  return __awaiter(this, void 0, void 0, function* () {
85
89
  if (this.isStopped())
@@ -1,4 +1,5 @@
1
1
  import { DeviceProperties } from '../../../types/device';
2
+ import { SerialInterface } from '../..';
2
3
  import { SerialDeviceSettings } from '../../adapter';
3
4
  import { SerialCommProps } from '../../comm';
4
5
  import DaumAdapter from '../DaumAdapter';
@@ -14,6 +15,7 @@ export default class DaumPremiumAdapter extends DaumAdapter {
14
15
  getPort(): any;
15
16
  getInterface(): string;
16
17
  getProtocolName(): string;
18
+ getSerialInterface(): SerialInterface;
17
19
  isEqual(settings: SerialDeviceSettings): boolean;
18
20
  getSupportedCyclingModes(): Array<any>;
19
21
  check(): Promise<boolean>;
@@ -90,12 +90,19 @@ class DaumPremiumAdapter extends DaumAdapter_1.default {
90
90
  getProtocolName() {
91
91
  return PROTOCOL_NAME;
92
92
  }
93
+ getSerialInterface() {
94
+ var _a;
95
+ return (_a = this.bike) === null || _a === void 0 ? void 0 : _a.serial;
96
+ }
93
97
  isEqual(settings) {
94
98
  if (this.getInterface() === device_1.INTERFACE.TCPIP) {
95
- const equal = super.isEqual(settings);
96
- if (!equal)
97
- return false;
98
99
  const as = this.settings;
100
+ if (settings.interface !== this.getInterface())
101
+ return false;
102
+ if (settings.protocol !== as.protocol)
103
+ return false;
104
+ if ((settings.port || DAUM_PREMIUM_DEFAULT_PORT) !== (as.port || DAUM_PREMIUM_DEFAULT_PORT))
105
+ return false;
99
106
  return (settings.host === as.host);
100
107
  }
101
108
  else {
@@ -34,7 +34,6 @@ const validatePath = (path) => {
34
34
  const port = parts[1];
35
35
  return `${host}:${port}`;
36
36
  };
37
- const drain = (sp) => new Promise(resolve => { sp.drain(resolve); });
38
37
  class Daum8i {
39
38
  constructor(props) {
40
39
  this.props = props || {};
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { MockBindingInterface, MockPortBinding, CreatePortOptions } from '@serialport/binding-mock';
3
- import { BindingInterface, PortInfo } from '@serialport/bindings-interface';
3
+ import { BindingInterface } from '@serialport/bindings-interface';
4
4
  import { User } from '../../../types/user';
5
5
  export type MockProps = {
6
6
  interface: string;
@@ -25,7 +25,7 @@ export declare class Daum8iMockImpl {
25
25
  getSimulator(path: any): Daum8MockSimulator;
26
26
  reset(): void;
27
27
  createPort(path: string, options?: CreatePortOptions): void;
28
- list(): Promise<PortInfo[]>;
28
+ list(): Promise<import("@serialport/bindings-interface").PortInfo[]>;
29
29
  open(options: any): Promise<Daum8iMockBinding>;
30
30
  }
31
31
  export declare class Daum8MockSimulator {
@@ -46,6 +46,7 @@ export default class KettlerSerialComms<T extends Command> extends EventEmitter
46
46
  _setSendState(state: SendState): void;
47
47
  _setCurrentCmd(cmd: T): void;
48
48
  stopCurrentTimeoutCheck(): void;
49
+ getSerialInterface(): SerialInterface;
49
50
  onPortOpen(): void;
50
51
  onPortClose(): Promise<void>;
51
52
  onPortError(err: any): void;
@@ -102,6 +102,9 @@ class KettlerSerialComms extends events_1.default {
102
102
  this.currentTimeout = undefined;
103
103
  }
104
104
  }
105
+ getSerialInterface() {
106
+ return this.serial;
107
+ }
105
108
  onPortOpen() {
106
109
  this.logger.logEvent({ message: 'port opened', port: this.getPort() });
107
110
  this.state = SerialCommsState.Connected;
@@ -5,6 +5,7 @@ import { Command } from "../../../types/command";
5
5
  import CyclingMode, { IncyclistBikeData } from "../../../modes/cycling-mode";
6
6
  import { SerialDeviceSettings, SerialIncyclistDevice } from "../../adapter";
7
7
  import { DeviceData } from "../../../types/data";
8
+ import SerialInterface from "../../serial-interface";
8
9
  export interface KettlerRacerCommand extends Command {
9
10
  }
10
11
  export interface KettlerExtendedBikeData {
@@ -44,6 +45,7 @@ export default class KettlerRacerAdapter extends SerialIncyclistDevice {
44
45
  getID(): string;
45
46
  getName(): string;
46
47
  getPort(): string;
48
+ getSerialInterface(): SerialInterface;
47
49
  _getComms(): SerialComms<KettlerRacerCommand>;
48
50
  _setComms(comms: SerialComms<KettlerRacerCommand>): void;
49
51
  getLogger(): EventLogger;
@@ -58,6 +58,10 @@ class KettlerRacerAdapter extends adapter_1.SerialIncyclistDevice {
58
58
  const settings = this.settings;
59
59
  return settings.port;
60
60
  }
61
+ getSerialInterface() {
62
+ if (this.comms)
63
+ return this.comms.getSerialInterface();
64
+ }
61
65
  _getComms() {
62
66
  return this.comms;
63
67
  }
@@ -30,6 +30,7 @@ export declare class SinglePathScanner {
30
30
  isScanning: boolean;
31
31
  props: SerialScannerProps;
32
32
  logger: EventLogger;
33
+ isFound: boolean;
33
34
  constructor(path: string, serial: SerialInterface, props: SerialScannerProps);
34
35
  logEvent(event: any): void;
35
36
  onStopRequest(resolve: any): Promise<void>;
@@ -45,6 +46,7 @@ export default class SerialInterface extends EventEmitter implements IncyclistIn
45
46
  logger: EventLogger;
46
47
  toScan: NodeJS.Timeout;
47
48
  connected: boolean;
49
+ inUse: string[];
48
50
  static _instances: SerialInterface[];
49
51
  static getInstance(props: SerialInterfaceProps): SerialInterface;
50
52
  static _add(instance: SerialInterface): void;
@@ -53,6 +55,8 @@ export default class SerialInterface extends EventEmitter implements IncyclistIn
53
55
  setBinding(binding: BindingInterface): void;
54
56
  getName(): string;
55
57
  isConnected(): boolean;
58
+ setInUse(path: string): void;
59
+ releaseInUse(path: string): void;
56
60
  connect(): Promise<boolean>;
57
61
  disconnect(): Promise<boolean>;
58
62
  openPort(path: string): Promise<SerialPortStream | null>;
@@ -18,6 +18,7 @@ const serialport_1 = __importDefault(require("./serialport"));
18
18
  const gd_eventlog_1 = require("gd-eventlog");
19
19
  const utils_1 = require("../utils/utils");
20
20
  const adapters_1 = __importDefault(require("../adapters"));
21
+ const adapter_factory_1 = __importDefault(require("./adapter-factory"));
21
22
  const DEFAULT_SCAN_TIMEOUT = 10000;
22
23
  exports.SerialInterfaceType = {
23
24
  SERIAL: 'serial',
@@ -29,6 +30,7 @@ class SinglePathScanner {
29
30
  this.serial = serial;
30
31
  this.result = undefined;
31
32
  this.isScanning = false;
33
+ this.isFound = false;
32
34
  this.props = props;
33
35
  this.logger = props.logger || new gd_eventlog_1.EventLogger('SerialScanner');
34
36
  }
@@ -44,7 +46,8 @@ class SinglePathScanner {
44
46
  onStopRequest(resolve) {
45
47
  return __awaiter(this, void 0, void 0, function* () {
46
48
  this.logEvent({ message: 'stopping scan', path: this.path });
47
- yield this.serial.closePort(this.path);
49
+ if (!this.isFound)
50
+ yield this.serial.closePort(this.path);
48
51
  this.isScanning = false;
49
52
  resolve(this.result);
50
53
  });
@@ -73,8 +76,8 @@ class SinglePathScanner {
73
76
  const adapter = adapters_1.default.create(adapterSettings);
74
77
  found = yield adapter.check();
75
78
  if (found) {
79
+ this.isFound = true;
76
80
  const name = adapter.getName();
77
- yield this.serial.closePort(this.path).catch();
78
81
  resolve(Object.assign(Object.assign({}, adapterSettings), { name }));
79
82
  }
80
83
  yield (0, utils_1.sleep)(100);
@@ -117,6 +120,7 @@ class SerialInterface extends events_1.default {
117
120
  this.ifaceName = ifaceName;
118
121
  this.binding = undefined;
119
122
  this.ports = [];
123
+ this.inUse = [];
120
124
  this.isScanning = false;
121
125
  this.isStopScanRequested = false;
122
126
  this.scanEvents = new events_1.default();
@@ -148,6 +152,18 @@ class SerialInterface extends events_1.default {
148
152
  isConnected() {
149
153
  return this.connected;
150
154
  }
155
+ setInUse(path) {
156
+ this.logEvent({ message: 'block port for further scans', port: path });
157
+ if (!this.inUse.includes(path))
158
+ this.inUse.push(path);
159
+ }
160
+ releaseInUse(path) {
161
+ if (this.inUse.includes(path)) {
162
+ this.logEvent({ message: 're-enable port for further scans', port: path });
163
+ const idx = this.inUse.findIndex(r => r === path);
164
+ this.inUse.splice(idx, 1);
165
+ }
166
+ }
151
167
  connect() {
152
168
  return __awaiter(this, void 0, void 0, function* () {
153
169
  const binding = serialport_1.default.getInstance().getBinding(this.ifaceName);
@@ -255,13 +271,18 @@ class SerialInterface extends events_1.default {
255
271
  this.scanEvents.emit('timeout');
256
272
  }, timeout);
257
273
  }
258
- this.logEvent({ message: 'checking for ports' });
259
274
  this.isScanning = true;
275
+ let attemptNo = 0;
260
276
  do {
277
+ if (attemptNo === 0)
278
+ this.logEvent({ message: 'checking for ports', port, excludes: this.inUse });
279
+ else
280
+ this.logEvent({ message: 'checking for ports retry', retry: attemptNo });
281
+ attemptNo++;
261
282
  try {
262
283
  if (this.getName() === 'tcpip') {
263
284
  const _binding = binding;
264
- paths = (yield _binding.list(port)) || [];
285
+ paths = (yield _binding.list(port, this.inUse)) || [];
265
286
  }
266
287
  else {
267
288
  paths = (yield binding.list()) || [];
@@ -277,6 +298,7 @@ class SerialInterface extends events_1.default {
277
298
  if (Date.now() > toExpiresAt)
278
299
  timeOutExpired = true;
279
300
  } while (this.isScanning && !timeOutExpired && paths.length === 0);
301
+ paths = paths.filter(p => !this.inUse.includes(p.path));
280
302
  if (paths.length === 0) {
281
303
  this.logEvent({ message: 'nothing to scan ' });
282
304
  if (this.toScan) {
@@ -291,6 +313,9 @@ class SerialInterface extends events_1.default {
291
313
  yield Promise.all(scanners.map(s => s.scan()
292
314
  .then(device => {
293
315
  if (device) {
316
+ const adapter = adapter_factory_1.default.getInstance().createInstance(device);
317
+ const path = adapter.getPort();
318
+ this.inUse.push(path);
294
319
  detected.push(device);
295
320
  this.emit('device', device);
296
321
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-devices",
3
- "version": "2.0.30",
3
+ "version": "2.0.32",
4
4
  "dependencies": {
5
5
  "@serialport/bindings-interface": "^1.2.2",
6
6
  "@serialport/parser-byte-length": "^9.0.1",