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.
- package/lib/ble/wahoo/adapter.js +0 -3
- package/lib/serial/adapter.d.ts +1 -0
- package/lib/serial/adapter.js +3 -0
- package/lib/serial/bindings/tcp.d.ts +2 -2
- package/lib/serial/bindings/tcp.js +7 -5
- package/lib/serial/daum/DaumAdapter.js +5 -3
- package/lib/serial/daum/classic/adapter.d.ts +2 -0
- package/lib/serial/daum/classic/adapter.js +4 -0
- package/lib/serial/daum/premium/adapter.d.ts +2 -0
- package/lib/serial/daum/premium/adapter.js +10 -3
- package/lib/serial/daum/premium/comms.js +0 -1
- package/lib/serial/daum/premium/mock.d.ts +2 -2
- package/lib/serial/kettler/comms.d.ts +1 -0
- package/lib/serial/kettler/comms.js +3 -0
- package/lib/serial/kettler/ergo-racer/adapter.d.ts +2 -0
- package/lib/serial/kettler/ergo-racer/adapter.js +4 -0
- package/lib/serial/serial-interface.d.ts +4 -0
- package/lib/serial/serial-interface.js +29 -4
- package/package.json +1 -1
package/lib/ble/wahoo/adapter.js
CHANGED
|
@@ -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;
|
package/lib/serial/adapter.d.ts
CHANGED
|
@@ -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;
|
package/lib/serial/adapter.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
95
|
-
|
|
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 {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { MockBindingInterface, MockPortBinding, CreatePortOptions } from '@serialport/binding-mock';
|
|
3
|
-
import { BindingInterface
|
|
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
|
-
|
|
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
|
}
|