incyclist-devices 1.4.8 → 1.4.11

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 (40) hide show
  1. package/lib/CyclingMode.js +0 -1
  2. package/lib/Device.d.ts +2 -0
  3. package/lib/Device.js +2 -0
  4. package/lib/DeviceProtocol.d.ts +4 -1
  5. package/lib/DeviceProtocol.js +0 -1
  6. package/lib/DeviceSupport.d.ts +2 -0
  7. package/lib/DeviceSupport.js +11 -22
  8. package/lib/ant/AntAdapter.js +0 -1
  9. package/lib/ant/AntScanner.js +7 -20
  10. package/lib/ant/antfe/AntFEAdapter.js +8 -8
  11. package/lib/ant/anthrm/AntHrmAdapter.js +1 -1
  12. package/lib/ant/utils.js +1 -3
  13. package/lib/calculations.js +0 -1
  14. package/lib/daum/DaumAdapter.js +18 -13
  15. package/lib/daum/ERGCyclingMode.js +2 -1
  16. package/lib/daum/SmartTrainerCyclingMode.js +0 -1
  17. package/lib/daum/classic/DaumClassicAdapter.js +1 -1
  18. package/lib/daum/classic/DaumClassicProtocol.js +7 -19
  19. package/lib/daum/classic/bike.js +26 -26
  20. package/lib/daum/classic/utils.js +0 -1
  21. package/lib/daum/constants.js +0 -1
  22. package/lib/daum/premium/DaumPremiumAdapter.js +1 -1
  23. package/lib/daum/premium/DaumPremiumProtocol.js +7 -19
  24. package/lib/daum/premium/bike.js +21 -19
  25. package/lib/daum/premium/utils.js +0 -1
  26. package/lib/kettler/comms.d.ts +48 -0
  27. package/lib/kettler/comms.js +194 -0
  28. package/lib/kettler/ergo-racer/adapter.d.ts +99 -0
  29. package/lib/kettler/ergo-racer/adapter.js +587 -0
  30. package/lib/kettler/ergo-racer/modes/power-meter.d.ts +18 -0
  31. package/lib/kettler/ergo-racer/modes/power-meter.js +78 -0
  32. package/lib/kettler/ergo-racer/protocol.d.ts +41 -0
  33. package/lib/kettler/ergo-racer/protocol.js +191 -0
  34. package/lib/simulator/Simulator.js +2 -15
  35. package/lib/types/command.d.ts +8 -0
  36. package/lib/types/command.js +2 -0
  37. package/lib/types/route.js +0 -1
  38. package/lib/types/user.js +0 -1
  39. package/lib/utils.js +1 -3
  40. package/package.json +1 -1
@@ -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,6 +8,13 @@ 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
  };
@@ -12,7 +12,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.Daum8iSerial = exports.Daum8iTcp = void 0;
16
15
  const constants_1 = require("../constants");
17
16
  const tcpserial_1 = __importDefault(require("./tcpserial"));
18
17
  const utils_1 = require("./utils");
@@ -26,6 +25,8 @@ const OPEN_TIMEOUT = 1000;
26
25
  const DAUM_PREMIUM_DEFAULT_PORT = 51955;
27
26
  const DAUM_PREMIUM_DEFAULT_HOST = '127.0.0.1';
28
27
  const MAX_DATA_BLOCK_SIZE = 512;
28
+ const DS_BITS_OFF = 0;
29
+ const DS_BITS_ENDLESS_RACE = 2;
29
30
  var __SerialPort = undefined;
30
31
  var net = undefined;
31
32
  const DEBUG_LOGGER = {
@@ -406,7 +407,7 @@ class Daum8i {
406
407
  incoming = bufferData;
407
408
  }
408
409
  const response = [...incoming];
409
- this.logger.logEvent({ message: 'sendCommand:RECV', data: (0, utils_1.hexstr)(response) });
410
+ this.logger.logEvent({ message: 'sendCommand:RECV', data: utils_1.hexstr(response) });
410
411
  for (let i = 0; i < incoming.length; i++) {
411
412
  const getRemaining = () => {
412
413
  let remaining = '';
@@ -439,11 +440,11 @@ class Daum8i {
439
440
  }
440
441
  else if (c === 0x17) {
441
442
  const remaining = getRemaining();
442
- this.logger.logEvent({ message: "sendCommand:received:", duration: Date.now() - this.state.sending.tsRequest, port: portName, cmd: `${cmd} [${(0, utils_1.hexstr)(cmd)}]`, remaining: (0, utils_1.hexstr)(remaining) });
443
+ this.logger.logEvent({ message: "sendCommand:received:", duration: Date.now() - this.state.sending.tsRequest, port: portName, cmd: `${cmd} [${utils_1.hexstr(cmd)}]`, remaining: utils_1.hexstr(remaining) });
443
444
  this.state.waitingForEnd = false;
444
445
  const cmdStr = cmd.substring(0, cmd.length - 2);
445
446
  const checksumExtracted = cmd.slice(-2);
446
- const checksumCalculated = (0, utils_1.checkSum)((0, utils_1.getAsciiArrayFromStr)(cmdStr), []);
447
+ const checksumCalculated = utils_1.checkSum(utils_1.getAsciiArrayFromStr(cmdStr), []);
447
448
  if (checksumExtracted === checksumCalculated) {
448
449
  this.sendACK();
449
450
  if (this.state.sending && this.state.sending.responseCheckIv) {
@@ -485,8 +486,8 @@ class Daum8i {
485
486
  this.state.busy = true;
486
487
  }
487
488
  else {
488
- const message = (0, utils_1.buildMessage)(command, payload);
489
- this.logger.logEvent({ message: 'sendCommand:waiting', port: this.portName, cmd: command, hex: (0, utils_1.hexstr)(message) });
489
+ const message = utils_1.buildMessage(command, payload);
490
+ this.logger.logEvent({ message: 'sendCommand:waiting', port: this.portName, cmd: command, hex: utils_1.hexstr(message) });
490
491
  const busyWait = () => {
491
492
  return new Promise((done) => {
492
493
  let start = Date.now();
@@ -507,7 +508,7 @@ class Daum8i {
507
508
  };
508
509
  const res = yield busyWait();
509
510
  if (!res) {
510
- this.logger.logEvent({ message: 'sendCommand:busy timeout', port: this.portName, cmd: command, hex: (0, utils_1.hexstr)(message), duration: Date.now() - tsRequest });
511
+ this.logger.logEvent({ message: 'sendCommand:busy timeout', port: this.portName, cmd: command, hex: utils_1.hexstr(message), duration: Date.now() - tsRequest });
511
512
  return reject(new Error('BUSY timeout'));
512
513
  }
513
514
  this.state.busy = true;
@@ -525,10 +526,10 @@ class Daum8i {
525
526
  const portName = this.portName;
526
527
  this.state.received = [];
527
528
  try {
528
- const message = (0, utils_1.buildMessage)(command, payload);
529
+ const message = utils_1.buildMessage(command, payload);
529
530
  const start = Date.now();
530
531
  const timeout = start + this.getTimeoutValue();
531
- this.logger.logEvent({ message: "sendCommand:sending:", port: this.portName, cmd: command, hex: (0, utils_1.hexstr)(message) });
532
+ this.logger.logEvent({ message: "sendCommand:sending:", port: this.portName, cmd: command, hex: utils_1.hexstr(message) });
532
533
  this.state.writeBusy = true;
533
534
  if (!this.connected || port === undefined) {
534
535
  this.logger.logEvent({ message: "sendCommand:error: not connected", port: this.portName });
@@ -588,10 +589,10 @@ class Daum8i {
588
589
  buffer.writeUInt16LE(0, 2);
589
590
  }
590
591
  const cmdData = Uint8Array.from(buffer);
591
- return this.sendDaum8iCommand('M70', cmdType, (0, utils_1.bin2esc)(cmdData))
592
+ return this.sendDaum8iCommand('M70', cmdType, utils_1.bin2esc(cmdData))
592
593
  .then((res) => {
593
594
  const resData = Uint8Array.from(res, x => x.charCodeAt(0));
594
- const cmd = (0, utils_1.esc2bin)(resData);
595
+ const cmd = utils_1.esc2bin(resData);
595
596
  return cmd;
596
597
  });
597
598
  }
@@ -616,7 +617,7 @@ class Daum8i {
616
617
  else if (str === '7')
617
618
  deviceType = 'lyps';
618
619
  else
619
- throw (new Error(`unknown device type ${typeof str === 'string' ? (0, utils_1.ascii)(str.charAt(0)) : str}`));
620
+ throw (new Error(`unknown device type ${typeof str === 'string' ? utils_1.ascii(str.charAt(0)) : str}`));
620
621
  return deviceType;
621
622
  });
622
623
  }
@@ -631,7 +632,7 @@ class Daum8i {
631
632
  else if (str === '2')
632
633
  deviceType = constants_1.ACTUAL_BIKE_TYPE.MOUNTAIN;
633
634
  else {
634
- throw (new Error(`unknown actual device type ${typeof str === 'string' ? (0, utils_1.ascii)(str.charAt(0)) : str}`));
635
+ throw (new Error(`unknown actual device type ${typeof str === 'string' ? utils_1.ascii(str.charAt(0)) : str}`));
635
636
  }
636
637
  this.state.actualBikeType = deviceType;
637
638
  return deviceType;
@@ -673,12 +674,12 @@ class Daum8i {
673
674
  getTrainingData() {
674
675
  return this.sendDaum8iCommand('X70', 'AF', [])
675
676
  .then((data) => {
676
- const td = (0, utils_1.parseTrainingData)(data);
677
+ const td = utils_1.parseTrainingData(data);
677
678
  return td;
678
679
  });
679
680
  }
680
681
  setLoadControl(enabled) {
681
- const val = enabled ? (0, utils_1.ascii)('1') : (0, utils_1.ascii)('0');
682
+ const val = enabled ? utils_1.ascii('1') : utils_1.ascii('0');
682
683
  return this.sendDaum8iCommand('S20', 'BF', [val])
683
684
  .then((data) => {
684
685
  const res = data === '1';
@@ -712,7 +713,7 @@ class Daum8i {
712
713
  setPerson(person) {
713
714
  const { sex, age, length, weight } = person;
714
715
  this.logger.logEvent({ message: 'setPerson() request', sex, age, length, weight });
715
- return this.sendReservedDaum8iCommand(utils_1.ReservedCommands.PERSON_SET, 'BF', (0, utils_1.getPersonData)(person))
716
+ return this.sendReservedDaum8iCommand(utils_1.ReservedCommands.PERSON_SET, 'BF', utils_1.getPersonData(person))
716
717
  .then((res) => {
717
718
  const buffer = Buffer.from(res);
718
719
  const success = buffer.readInt16LE(0) === utils_1.ReservedCommands.PERSON_SET;
@@ -736,9 +737,10 @@ class Daum8i {
736
737
  }
737
738
  programUploadStart(bikeType, route) {
738
739
  const payload = Buffer.alloc(40);
739
- const epp = route ? (0, utils_1.routeToEpp)(route) : undefined;
740
+ const epp = route ? utils_1.routeToEpp(route) : undefined;
740
741
  const eppLength = epp ? epp.length : 0;
741
- const bikeTypeVal = (0, utils_1.getBikeType)(bikeType);
742
+ const bikeTypeVal = utils_1.getBikeType(bikeType);
743
+ const wBits = route.lapMode ? DS_BITS_ENDLESS_RACE : DS_BITS_OFF;
742
744
  payload.writeInt32LE(0, 0);
743
745
  payload.writeInt8(bikeTypeVal, 4);
744
746
  payload.writeInt8(0, 5);
@@ -750,7 +752,7 @@ class Daum8i {
750
752
  payload.writeInt16LE(0, 24);
751
753
  payload.writeInt16LE(0, 26);
752
754
  payload.writeInt16LE(0, 28);
753
- payload.writeInt16LE(0, 30);
755
+ payload.writeInt16LE(wBits, 30);
754
756
  payload.writeInt32LE(7, 32);
755
757
  payload.writeInt32LE(eppLength, 36);
756
758
  this.logger.logEvent({ message: 'programUploadStart() request', bikeType, length: eppLength });
@@ -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.getPersonData = exports.parseTrainingData = exports.routeToEpp = exports.getBikeType = exports.BikeType = exports.ReservedCommands = exports.Int32ToIntArray = exports.Int16ToIntArray = exports.Float32ToIntArray = exports.Float32ToHex = exports.getAsciiArrayFromStr = exports.asciiArrayToString = exports.charArrayToString = exports.ascii = exports.append = exports.getHex = exports.hexstr = exports.getMessageData = exports.buildMessage = exports.checkSum = exports.esc2bin = exports.bin2esc = void 0;
7
6
  const win32filetime_1 = __importDefault(require("win32filetime"));
8
7
  const sum = (arr) => arr.reduce((a, b) => a + b, 0);
9
8
  function bin2esc(arr) {
@@ -0,0 +1,48 @@
1
+ /// <reference types="node" />
2
+ import { DeviceProtocol } from "../DeviceProtocol";
3
+ import { EventLogger } from "gd-eventlog";
4
+ import { Command } from "../types/command";
5
+ import EventEmitter from "events";
6
+ export declare type SerialCommsProps = {
7
+ logger?: EventLogger;
8
+ protocol: DeviceProtocol;
9
+ port: string;
10
+ settings?: any;
11
+ };
12
+ declare enum SerialCommsState {
13
+ Idle = 0,
14
+ Connecting = 1,
15
+ Connected = 2,
16
+ Disconnecting = 3,
17
+ Disconnected = 4,
18
+ Error = 5
19
+ }
20
+ export default class KettlerSerialComms<T extends Command> extends EventEmitter {
21
+ private logger;
22
+ private port;
23
+ private sp;
24
+ private queue;
25
+ private state;
26
+ private settings;
27
+ private worker;
28
+ private sendState;
29
+ private currentCmd;
30
+ private protocol;
31
+ constructor(opts: SerialCommsProps);
32
+ getPort(): string;
33
+ setPort(port: any): void;
34
+ isConnected(): boolean;
35
+ stateIn: (allowedStates: SerialCommsState[]) => boolean;
36
+ onPortOpen(): void;
37
+ onPortClose(): Promise<void>;
38
+ onPortError(err: any): void;
39
+ open(): void;
40
+ close(): void;
41
+ startWorker(): void;
42
+ stopWorker(): void;
43
+ onData(data: string | Buffer): void;
44
+ write(cmd: Command): void;
45
+ sendNextCommand(): Command | undefined;
46
+ send(cmd: Command): void;
47
+ }
48
+ export {};
@@ -0,0 +1,194 @@
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 gd_eventlog_1 = require("gd-eventlog");
16
+ const utils_1 = require("../utils");
17
+ const events_1 = __importDefault(require("events"));
18
+ const DEFAULT_RCV_TIMEOUT = 500;
19
+ const DEBUG_LOGGER = {
20
+ log: (e, ...args) => console.log(e, ...args),
21
+ logEvent: (event) => console.log(JSON.stringify(event))
22
+ };
23
+ var SerialCommsState;
24
+ (function (SerialCommsState) {
25
+ SerialCommsState[SerialCommsState["Idle"] = 0] = "Idle";
26
+ SerialCommsState[SerialCommsState["Connecting"] = 1] = "Connecting";
27
+ SerialCommsState[SerialCommsState["Connected"] = 2] = "Connected";
28
+ SerialCommsState[SerialCommsState["Disconnecting"] = 3] = "Disconnecting";
29
+ SerialCommsState[SerialCommsState["Disconnected"] = 4] = "Disconnected";
30
+ SerialCommsState[SerialCommsState["Error"] = 5] = "Error";
31
+ })(SerialCommsState || (SerialCommsState = {}));
32
+ var SendState;
33
+ (function (SendState) {
34
+ SendState[SendState["Idle"] = 0] = "Idle";
35
+ SendState[SendState["Sending"] = 1] = "Sending";
36
+ SendState[SendState["Receiving"] = 2] = "Receiving";
37
+ })(SendState || (SendState = {}));
38
+ const CRLF = '\r\n';
39
+ class KettlerSerialComms extends events_1.default {
40
+ constructor(opts) {
41
+ super();
42
+ this.stateIn = (allowedStates) => {
43
+ return allowedStates.indexOf(this.state) >= 0;
44
+ };
45
+ this.logger = process.env.DEBUG ? DEBUG_LOGGER : (opts.logger || new gd_eventlog_1.EventLogger(opts.protocol.getName()));
46
+ this.port = opts.port || process.env.COM_PORT;
47
+ this.sp = undefined;
48
+ this.queue = new utils_1.Queue();
49
+ this.state = SerialCommsState.Idle;
50
+ this.sendState = SendState.Idle;
51
+ this.settings = opts.settings || {};
52
+ this.currentCmd = undefined;
53
+ this.protocol = opts.protocol;
54
+ }
55
+ getPort() {
56
+ return this.port;
57
+ }
58
+ setPort(port) {
59
+ this.port = port;
60
+ }
61
+ isConnected() {
62
+ return this.state === SerialCommsState.Connected;
63
+ }
64
+ onPortOpen() {
65
+ this.logger.logEvent({ message: 'port opened', port: this.getPort() });
66
+ this.state = SerialCommsState.Connected;
67
+ this.sendState = SendState.Idle;
68
+ this.startWorker();
69
+ this.emit('opened');
70
+ }
71
+ onPortClose() {
72
+ return __awaiter(this, void 0, void 0, function* () {
73
+ this.logger.logEvent({ message: 'port closed', port: this.getPort() });
74
+ this.stopWorker();
75
+ if (this.sendState === SendState.Sending) {
76
+ }
77
+ this.state = SerialCommsState.Disconnected;
78
+ this.sendState = SendState.Idle;
79
+ this.queue.clear();
80
+ this.emit('closed');
81
+ this.sp.removeAllListeners();
82
+ this.sp = undefined;
83
+ });
84
+ }
85
+ onPortError(err) {
86
+ if (this.stateIn([SerialCommsState.Connected, SerialCommsState.Disconnected]))
87
+ return;
88
+ if (this.state === SerialCommsState.Disconnecting && (err.message === 'Port is not open' || err.message === 'Writing to COM port (GetOverlappedResult): Operation aborted'))
89
+ return;
90
+ if (this.state === SerialCommsState.Connecting && (err.message === 'Port is already open' || err.message === 'Port is opening'))
91
+ return;
92
+ this.logger.logEvent({ message: "port error:", port: this.getPort(), error: err.message, stack: err.stack, state: this.state });
93
+ this.emit('error', err);
94
+ }
95
+ open() {
96
+ this.logger.logEvent({ message: "open()", port: this.getPort() });
97
+ if (this.stateIn([SerialCommsState.Connected, SerialCommsState.Connecting, SerialCommsState.Disconnecting])) {
98
+ return;
99
+ }
100
+ try {
101
+ const SerialPort = this.protocol.getSerialPort();
102
+ if (this.sp === undefined) {
103
+ this.sp = new SerialPort(this.getPort(), this.settings);
104
+ this.sp.on('open', () => { this.onPortOpen(); });
105
+ this.sp.on('close', () => { this.onPortClose(); });
106
+ this.sp.on('error', (error) => { this.onPortError(error); });
107
+ }
108
+ this.state = SerialCommsState.Connecting;
109
+ const parser = this.sp.pipe(new SerialPort.parsers.Readline({ delimiter: CRLF }));
110
+ parser.on('data', (data) => { this.onData(data); });
111
+ this.sp.open();
112
+ }
113
+ catch (err) {
114
+ this.logger.logEvent({ message: "error", fn: 'open()', error: err.message });
115
+ this.state = SerialCommsState.Disconnected;
116
+ }
117
+ }
118
+ close() {
119
+ this.logger.logEvent({ message: 'close()', port: this.getPort() });
120
+ if (this.stateIn([SerialCommsState.Idle, SerialCommsState.Disconnected, SerialCommsState.Disconnecting])) {
121
+ return;
122
+ }
123
+ this.state = SerialCommsState.Disconnecting;
124
+ this.sp.close();
125
+ }
126
+ startWorker() {
127
+ this.worker = setInterval(() => {
128
+ this.sendNextCommand();
129
+ }, 50);
130
+ }
131
+ stopWorker() {
132
+ if (this.worker) {
133
+ clearInterval(this.worker);
134
+ this.worker = undefined;
135
+ }
136
+ }
137
+ onData(data) {
138
+ this.sendState = SendState.Idle;
139
+ this.currentCmd = undefined;
140
+ this.logger.logEvent({ message: "sendCommand:receiving:", data: data });
141
+ if (typeof data === 'string') {
142
+ if (data.length > 2)
143
+ data = data.trim();
144
+ this.currentCmd.onResponse(data);
145
+ }
146
+ else {
147
+ this.currentCmd.onResponse(data);
148
+ }
149
+ }
150
+ write(cmd) {
151
+ this.sendState = SendState.Sending;
152
+ const { logStr, message, timeout = (this.settings.timeout || DEFAULT_RCV_TIMEOUT) } = cmd;
153
+ const msg = typeof message === 'string' ? message : utils_1.hexstr(message);
154
+ const onError = (err) => {
155
+ this.logger.logEvent({ message: "sendCommand:error:", cmd: logStr, error: err.message, port: this.getPort() });
156
+ cmd.onError(err);
157
+ this.sendState = SendState.Idle;
158
+ this.currentCmd = undefined;
159
+ };
160
+ try {
161
+ this.logger.logEvent({ message: "sendCommand:sending:", cmd: logStr, msg, port: this.getPort() });
162
+ if (typeof (message) !== 'string')
163
+ throw new Error('message must be a string');
164
+ this.sp.write(msg + CRLF, (err) => {
165
+ this.sendState = SendState.Receiving;
166
+ this.currentCmd = cmd;
167
+ if (timeout) {
168
+ setTimeout(() => {
169
+ if (this.sendState === SendState.Receiving) {
170
+ onError(new Error("timeout"));
171
+ }
172
+ }, timeout);
173
+ }
174
+ if (err)
175
+ onError(err);
176
+ });
177
+ }
178
+ catch (err) {
179
+ onError(err);
180
+ }
181
+ }
182
+ sendNextCommand() {
183
+ if (this.sendState !== SendState.Idle) {
184
+ return;
185
+ }
186
+ const cmd = this.queue.dequeue();
187
+ if (cmd)
188
+ this.write(cmd);
189
+ }
190
+ send(cmd) {
191
+ this.queue.enqueue(cmd);
192
+ }
193
+ }
194
+ exports.default = KettlerSerialComms;
@@ -0,0 +1,99 @@
1
+ import { DeviceSettings } from "../../DeviceProtocol";
2
+ import DeviceAdapterBase, { DeviceAdapter, DeviceData, Bike } from "../../Device";
3
+ import { DeviceProtocol } from "../../DeviceProtocol";
4
+ import { EventLogger } from "gd-eventlog";
5
+ import { Command } from "../../types/command";
6
+ import CyclingMode, { IncyclistBikeData } from "../../CyclingMode";
7
+ import { User } from "../../types/user";
8
+ export interface KettlerRacerCommand extends Command {
9
+ }
10
+ export interface KettlerExtendedBikeData {
11
+ }
12
+ export interface KettlerBikeData {
13
+ heartrate?: number;
14
+ cadence?: number;
15
+ speed?: number;
16
+ distance?: number;
17
+ requestedPower?: number;
18
+ energy?: number;
19
+ timestamp?: number;
20
+ time: number;
21
+ power: number;
22
+ }
23
+ export interface KettlerDeviceSettings extends DeviceSettings {
24
+ userSettings?: User;
25
+ bikeSettings?: any;
26
+ cyclingMode?: CyclingMode;
27
+ }
28
+ export default class KettlerRacerAdapter extends DeviceAdapterBase implements DeviceAdapter, Bike {
29
+ private id;
30
+ private settings;
31
+ private ignoreHrm;
32
+ private ignoreBike;
33
+ private ignorePower;
34
+ private logger;
35
+ private paused;
36
+ private comms;
37
+ private iv;
38
+ private requests;
39
+ private data;
40
+ private idata;
41
+ private kettlerData;
42
+ private updateBusy;
43
+ private requestBusy;
44
+ constructor(protocol: DeviceProtocol, settings: DeviceSettings);
45
+ isBike(): boolean;
46
+ isPower(): boolean;
47
+ isHrm(): boolean;
48
+ setID(id: any): void;
49
+ getID(): string;
50
+ getName(): string;
51
+ getPort(): string;
52
+ setIgnoreHrm(ignore: boolean): void;
53
+ setIgnorePower(ignore: boolean): void;
54
+ setIgnoreBike(ignore: boolean): void;
55
+ getLogger(): EventLogger;
56
+ getUserSettings(): User;
57
+ getWeight(): number;
58
+ setComputerMode(): Promise<boolean>;
59
+ setClientMode(): Promise<boolean>;
60
+ reset(): Promise<boolean>;
61
+ getIdentifier(): Promise<string>;
62
+ getInterface(): Promise<string>;
63
+ getVersion(): Promise<string>;
64
+ getCalibration(): Promise<string>;
65
+ startTraining(): Promise<string>;
66
+ unknownSN(): Promise<string>;
67
+ setBaudrate(baudrate: number): Promise<string>;
68
+ setPower(power: number): Promise<string>;
69
+ getExtendedStatus(): Promise<KettlerExtendedBikeData>;
70
+ getStatus(): Promise<KettlerBikeData>;
71
+ getDB(): Promise<string>;
72
+ send(logStr: string, message: string, timeout?: any): Promise<any>;
73
+ parseExtendedStatus(data: string): KettlerExtendedBikeData;
74
+ parseStatus(data: string): KettlerBikeData;
75
+ check(): Promise<boolean>;
76
+ start(props?: any): Promise<any>;
77
+ startUpdatePull(): void;
78
+ stop(): Promise<boolean>;
79
+ pause(): Promise<boolean>;
80
+ resume(): Promise<boolean>;
81
+ mapData(bikeData: KettlerBikeData): IncyclistBikeData;
82
+ transformData(internalData: IncyclistBikeData, bikeData: KettlerBikeData): DeviceData;
83
+ update(): Promise<void>;
84
+ sendRequest(request: any): Promise<any>;
85
+ sendRequests(): Promise<void>;
86
+ bikeSync(): Promise<void>;
87
+ sendUpdate(request: any): Promise<unknown>;
88
+ sendData(): void;
89
+ refreshRequests(): void;
90
+ processClientRequest(request: any): Promise<unknown>;
91
+ waitForOpened(): Promise<boolean>;
92
+ waitForClosed(): Promise<boolean>;
93
+ getSupportedCyclingModes(): any[];
94
+ setCyclingMode(mode: CyclingMode | string, settings?: any): void;
95
+ getCyclingMode(): CyclingMode;
96
+ getDefaultCyclingMode(): CyclingMode;
97
+ setUserSettings(userSettings: any): void;
98
+ setBikeSettings(bikeSettings: any): void;
99
+ }