incyclist-devices 2.0.37 → 2.1.0

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 (103) hide show
  1. package/lib/antv2/adapter-factory.d.ts +4 -2
  2. package/lib/antv2/adapter.d.ts +3 -20
  3. package/lib/antv2/adapter.js +7 -93
  4. package/lib/antv2/fe/adapter.d.ts +9 -5
  5. package/lib/antv2/fe/adapter.js +25 -14
  6. package/lib/antv2/hr/adapter.d.ts +2 -1
  7. package/lib/antv2/pwr/adapter.d.ts +9 -5
  8. package/lib/antv2/pwr/adapter.js +19 -8
  9. package/lib/antv2/types.d.ts +2 -1
  10. package/lib/base/adpater.d.ts +31 -13
  11. package/lib/base/adpater.js +84 -28
  12. package/lib/ble/adapter-factory.d.ts +10 -9
  13. package/lib/ble/base/adapter.d.ts +9 -20
  14. package/lib/ble/base/adapter.js +15 -72
  15. package/lib/ble/ble-interface.d.ts +5 -4
  16. package/lib/ble/cp/adapter.d.ts +5 -8
  17. package/lib/ble/cp/adapter.js +26 -10
  18. package/lib/ble/elite/adapter.d.ts +6 -5
  19. package/lib/ble/elite/adapter.js +26 -2
  20. package/lib/ble/fm/adapter.d.ts +10 -9
  21. package/lib/ble/fm/adapter.js +38 -11
  22. package/lib/ble/hr/adapter.d.ts +5 -3
  23. package/lib/ble/peripheral-cache.d.ts +3 -2
  24. package/lib/ble/tacx/adapter.d.ts +2 -2
  25. package/lib/ble/wahoo/adapter.d.ts +2 -2
  26. package/lib/index.d.ts +5 -5
  27. package/lib/index.js +4 -2
  28. package/lib/interfaces.d.ts +1 -1
  29. package/lib/modes/ant-fe-adv-st-mode.d.ts +12 -0
  30. package/lib/modes/ant-fe-adv-st-mode.js +83 -0
  31. package/lib/modes/antble-erg.d.ts +31 -0
  32. package/lib/modes/antble-erg.js +28 -0
  33. package/lib/modes/antble-smarttrainer.d.ts +23 -0
  34. package/lib/modes/antble-smarttrainer.js +65 -0
  35. package/lib/modes/base.d.ts +29 -0
  36. package/lib/modes/{cycling-mode.js → base.js} +23 -26
  37. package/lib/modes/daum-classic-standard.d.ts +16 -0
  38. package/lib/modes/daum-classic-standard.js +54 -0
  39. package/lib/modes/daum-erg.d.ts +49 -0
  40. package/lib/{serial/daum/ERGCyclingMode.js → modes/daum-erg.js} +45 -73
  41. package/lib/modes/daum-power.d.ts +5 -0
  42. package/lib/{serial/daum/DaumPowerMeterCyclingMode.js → modes/daum-power.js} +1 -10
  43. package/lib/modes/daum-premium-standard.d.ts +23 -0
  44. package/lib/{serial/daum/premium/modes/daum-classic.js → modes/daum-premium-standard.js} +26 -38
  45. package/lib/modes/daum-smarttrainer.d.ts +82 -0
  46. package/lib/{serial/daum/SmartTrainerCyclingMode.js → modes/daum-smarttrainer.js} +23 -26
  47. package/lib/modes/kettler-erg.d.ts +44 -0
  48. package/lib/{serial/kettler/ergo-racer/modes/erg.js → modes/kettler-erg.js} +12 -23
  49. package/lib/modes/power-base.d.ts +28 -3
  50. package/lib/modes/power-base.js +182 -5
  51. package/lib/modes/power-meter.d.ts +10 -16
  52. package/lib/modes/power-meter.js +15 -54
  53. package/lib/modes/simulator.d.ts +37 -10
  54. package/lib/modes/simulator.js +14 -46
  55. package/lib/modes/{cycling-mode.d.ts → types.d.ts} +22 -19
  56. package/lib/modes/types.js +56 -0
  57. package/lib/serial/adapter-factory.d.ts +7 -5
  58. package/lib/serial/adapter.d.ts +2 -2
  59. package/lib/serial/adapter.js +5 -2
  60. package/lib/serial/daum/DaumAdapter.d.ts +27 -24
  61. package/lib/serial/daum/DaumAdapter.js +200 -128
  62. package/lib/serial/daum/classic/adapter.d.ts +20 -21
  63. package/lib/serial/daum/classic/adapter.js +83 -157
  64. package/lib/serial/daum/classic/comms.d.ts +19 -13
  65. package/lib/serial/daum/classic/comms.js +39 -12
  66. package/lib/serial/daum/classic/mock.d.ts +4 -0
  67. package/lib/serial/daum/classic/mock.js +14 -4
  68. package/lib/serial/daum/premium/adapter.d.ts +16 -11
  69. package/lib/serial/daum/premium/adapter.js +98 -95
  70. package/lib/serial/daum/premium/comms.d.ts +4 -1
  71. package/lib/serial/daum/premium/comms.js +25 -17
  72. package/lib/serial/daum/premium/mock.d.ts +4 -0
  73. package/lib/serial/daum/premium/mock.js +15 -5
  74. package/lib/serial/daum/types.d.ts +11 -0
  75. package/lib/serial/daum/types.js +5 -0
  76. package/lib/serial/kettler/ergo-racer/adapter.d.ts +10 -8
  77. package/lib/serial/kettler/ergo-racer/adapter.js +17 -7
  78. package/lib/serial/serial-interface.js +1 -2
  79. package/lib/simulator/Simulator.d.ts +14 -17
  80. package/lib/simulator/Simulator.js +18 -47
  81. package/lib/types/adapter.d.ts +29 -8
  82. package/lib/types/adapter.js +68 -0
  83. package/lib/utils/utils.d.ts +1 -1
  84. package/package.json +3 -3
  85. package/lib/antv2/modes/ant-fe-adv-st-mode.d.ts +0 -9
  86. package/lib/antv2/modes/ant-fe-adv-st-mode.js +0 -51
  87. package/lib/antv2/modes/ant-fe-erg-mode.d.ts +0 -6
  88. package/lib/antv2/modes/ant-fe-erg-mode.js +0 -14
  89. package/lib/antv2/modes/ant-fe-st-mode.d.ts +0 -5
  90. package/lib/antv2/modes/ant-fe-st-mode.js +0 -13
  91. package/lib/modes/ble-erg-mode.d.ts +0 -18
  92. package/lib/modes/ble-erg-mode.js +0 -148
  93. package/lib/modes/ble-st-mode.d.ts +0 -15
  94. package/lib/modes/ble-st-mode.js +0 -96
  95. package/lib/serial/daum/DaumPowerMeterCyclingMode.d.ts +0 -8
  96. package/lib/serial/daum/ERGCyclingMode.d.ts +0 -26
  97. package/lib/serial/daum/SmartTrainerCyclingMode.d.ts +0 -42
  98. package/lib/serial/daum/classic/modes/daum-classic.d.ts +0 -13
  99. package/lib/serial/daum/classic/modes/daum-classic.js +0 -97
  100. package/lib/serial/daum/premium/modes/daum-classic.d.ts +0 -14
  101. package/lib/serial/kettler/ergo-racer/modes/erg.d.ts +0 -25
  102. /package/lib/serial/daum/{constants.d.ts → consts.d.ts} +0 -0
  103. /package/lib/serial/daum/{constants.js → consts.js} +0 -0
@@ -1,20 +1,45 @@
1
- import { IncyclistBikeData, Settings, CyclingModeBase } from './cycling-mode';
1
+ import { CyclingModeConfig, IncyclistBikeData, Settings, UpdateRequest } from './types';
2
2
  import { EventLogger } from 'gd-eventlog';
3
- import { ControllableDeviceAdapter } from '..';
3
+ import { IncyclistDeviceAdapter } from '..';
4
+ import { CyclingModeBase } from './base';
4
5
  export default class PowerBasedCyclingModeBase extends CyclingModeBase {
5
6
  data: IncyclistBikeData;
6
7
  prevUpdateTS: number;
7
8
  logger: EventLogger;
8
- constructor(adapter: ControllableDeviceAdapter, props?: Settings);
9
+ prevRequest: UpdateRequest | undefined;
10
+ protected static config: CyclingModeConfig;
11
+ constructor(adapter: IncyclistDeviceAdapter, props?: Settings);
12
+ getData(): IncyclistBikeData;
13
+ getSlope(): number;
9
14
  initLogger(defaultLogName: any): void;
10
15
  getWeight(): number;
11
16
  getTimeSinceLastUpdate(): number;
17
+ checkForResetOrEmpty(request: UpdateRequest): UpdateRequest | undefined;
18
+ protected checkForTempPowerAdjustments(request: UpdateRequest): void;
19
+ protected checkRefresh(request: UpdateRequest, newRequest: UpdateRequest): void;
20
+ protected checkTargetPowerSet(request: UpdateRequest, newRequest: UpdateRequest): void;
21
+ protected checkSlope(request: UpdateRequest): void;
22
+ protected checkEmptyRequest(newRequest: UpdateRequest): void;
23
+ protected checkMinPower(request: UpdateRequest, newRequest: UpdateRequest): void;
24
+ protected checkMaxPower(request: UpdateRequest, newRequest: UpdateRequest): void;
12
25
  calculateSpeedAndDistance(power: number, slope: number, m: number, t: number, props?: {}): {
13
26
  speed: number;
14
27
  distance: number;
15
28
  };
29
+ protected updateSpeedAndDistance(power: number, slope: any, bikeType: any, data: IncyclistBikeData, prevData: any): number;
30
+ protected getCalcBasics(bikeData: IncyclistBikeData): {
31
+ data: IncyclistBikeData;
32
+ prevData: any;
33
+ prevRequest: UpdateRequest;
34
+ bikeType: any;
35
+ slope: any;
36
+ };
37
+ copyBikeData(data: IncyclistBikeData, bikeData: IncyclistBikeData): IncyclistBikeData;
16
38
  calculatePowerAndDistance(speed: number, slope: number, m: number, t: number, props?: {}): {
17
39
  power: number;
18
40
  distance: number;
19
41
  };
42
+ getBikeInitRequest(): UpdateRequest;
43
+ sendBikeUpdate(incoming: UpdateRequest): UpdateRequest;
44
+ updateData(bikeData: IncyclistBikeData, log?: boolean): IncyclistBikeData;
20
45
  }
@@ -3,16 +3,24 @@ 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
- const cycling_mode_1 = require("./cycling-mode");
7
6
  const adpater_1 = require("../base/adpater");
8
7
  const calculations_1 = __importDefault(require("../utils/calculations"));
9
8
  const gd_eventlog_1 = require("gd-eventlog");
10
- class PowerBasedCyclingModeBase extends cycling_mode_1.CyclingModeBase {
9
+ const base_1 = require("./base");
10
+ const MIN_SPEED = 10;
11
+ class PowerBasedCyclingModeBase extends base_1.CyclingModeBase {
11
12
  constructor(adapter, props) {
12
13
  super(adapter, props);
13
14
  this.prevUpdateTS = 0;
14
15
  this.data = { speed: 0, power: 0, distanceInternal: 0, pedalRpm: 0, isPedalling: false, heartrate: 0 };
15
16
  }
17
+ getData() {
18
+ return this.data;
19
+ }
20
+ getSlope() {
21
+ const { slope } = this.data;
22
+ return slope || 0;
23
+ }
16
24
  initLogger(defaultLogName) {
17
25
  const a = this.adapter;
18
26
  this.logger = a.getLogger();
@@ -28,11 +36,86 @@ class PowerBasedCyclingModeBase extends cycling_mode_1.CyclingModeBase {
28
36
  getTimeSinceLastUpdate() {
29
37
  const ts = Date.now();
30
38
  const duration = this.prevUpdateTS === 0 ? 0 : ((ts - this.prevUpdateTS) / 1000);
31
- this.prevUpdateTS = ts;
32
39
  return duration;
33
40
  }
41
+ checkForResetOrEmpty(request) {
42
+ if (!request || request.reset) {
43
+ this.prevRequest = {};
44
+ return { reset: true };
45
+ }
46
+ if (Object.keys(request).length === 0 && this.prevRequest) {
47
+ return { targetPower: this.prevRequest.targetPower, refresh: true };
48
+ }
49
+ }
50
+ checkForTempPowerAdjustments(request) {
51
+ if (request.targetPowerDelta && this.prevRequest && this.prevRequest.targetPower) {
52
+ request.targetPower = this.prevRequest.targetPower + request.targetPowerDelta;
53
+ if (request.targetPower < 10)
54
+ request.targetPower = this.prevRequest.targetPower;
55
+ delete request.targetPowerDelta;
56
+ }
57
+ }
58
+ checkRefresh(request, newRequest) {
59
+ if (request.refresh && request.targetPower === undefined) {
60
+ delete request.refresh;
61
+ if (this.prevRequest)
62
+ newRequest.targetPower = this.prevRequest.targetPower;
63
+ }
64
+ }
65
+ checkTargetPowerSet(request, newRequest) {
66
+ let target = undefined;
67
+ if (request.targetPower !== undefined)
68
+ target = request.targetPower;
69
+ if (request.targetPower === undefined && request.maxPower !== undefined && request.minPower !== undefined && request.maxPower === request.minPower) {
70
+ target = request.minPower;
71
+ }
72
+ if (target !== undefined) {
73
+ delete request.refresh;
74
+ newRequest.targetPower = Number(target);
75
+ }
76
+ }
77
+ checkSlope(request) {
78
+ if (request.slope !== undefined) {
79
+ this.data.slope = request.slope;
80
+ delete request.slope;
81
+ }
82
+ }
83
+ checkEmptyRequest(newRequest) {
84
+ if (Object.keys(newRequest).length === 0) {
85
+ if (this.prevRequest) {
86
+ newRequest.targetPower = this.prevRequest.targetPower;
87
+ newRequest.refresh = true;
88
+ }
89
+ }
90
+ }
91
+ checkMinPower(request, newRequest) {
92
+ if (request.minPower !== undefined) {
93
+ const target = newRequest.targetPower !== undefined ? newRequest.targetPower : this.prevRequest.targetPower;
94
+ if (target && target < request.minPower) {
95
+ newRequest.targetPower = request.minPower;
96
+ }
97
+ else {
98
+ if (this.prevRequest)
99
+ newRequest.targetPower = this.prevRequest.targetPower;
100
+ }
101
+ newRequest.minPower = request.minPower;
102
+ }
103
+ }
104
+ checkMaxPower(request, newRequest) {
105
+ if (request.maxPower !== undefined) {
106
+ const target = newRequest.targetPower !== undefined ? newRequest.targetPower : this.prevRequest.targetPower;
107
+ if (target && target > request.maxPower) {
108
+ newRequest.targetPower = request.maxPower;
109
+ }
110
+ else {
111
+ if (this.prevRequest)
112
+ newRequest.targetPower = this.prevRequest.targetPower;
113
+ }
114
+ newRequest.maxPower = request.maxPower;
115
+ }
116
+ }
34
117
  calculateSpeedAndDistance(power, slope, m, t, props = {}) {
35
- const prevData = this.data || {};
118
+ const prevData = this.getData();
36
119
  const vPrev = (prevData.speed || 0) / 3.6;
37
120
  const EkinPrev = 1 / 2 * m * vPrev * vPrev;
38
121
  let powerToMaintainSpeed = calculations_1.default.calculatePower(m, vPrev, slope, props);
@@ -57,8 +140,57 @@ class PowerBasedCyclingModeBase extends cycling_mode_1.CyclingModeBase {
57
140
  return { speed, distance };
58
141
  }
59
142
  }
143
+ updateSpeedAndDistance(power, slope, bikeType, data, prevData) {
144
+ const distanceInternal = prevData.distanceInternal || 0;
145
+ const m = this.getWeight();
146
+ const t = this.getTimeSinceLastUpdate();
147
+ const { speed, distance } = this.calculateSpeedAndDistance(power, slope, m, t, { bikeType });
148
+ if (power === 0 && speed < MIN_SPEED) {
149
+ data.speed = prevData.speed < 1 ? 0 : prevData.speed - 1;
150
+ data.distanceInternal = distanceInternal || 0 + data.speed / 3.6 * t;
151
+ }
152
+ else {
153
+ data.speed = speed;
154
+ data.distanceInternal = distanceInternal + distance;
155
+ }
156
+ return t;
157
+ }
158
+ getCalcBasics(bikeData) {
159
+ var _a;
160
+ const prevData = JSON.parse(JSON.stringify(this.getData()));
161
+ const data = Object.assign({}, this.getData());
162
+ const prevRequest = this.prevRequest || {};
163
+ const bikeType = (_a = this.getSetting('bikeType')) === null || _a === void 0 ? void 0 : _a.toLowerCase();
164
+ const slope = (prevData.slope !== undefined ? prevData.slope : prevRequest.slope || 0);
165
+ this.copyBikeData(data, bikeData);
166
+ return { data, prevData, prevRequest, bikeType, slope };
167
+ }
168
+ copyBikeData(data, bikeData) {
169
+ var _a;
170
+ const keys = Object.keys(bikeData);
171
+ keys.forEach(key => {
172
+ if (bikeData[key] === null)
173
+ delete data[key];
174
+ if (key === 'slope')
175
+ return;
176
+ else if (bikeData[key] !== undefined)
177
+ data[key] = bikeData[key];
178
+ });
179
+ if (data.distanceInternal === undefined)
180
+ data.distanceInternal = 0;
181
+ if (data.time === undefined)
182
+ data.time = 0;
183
+ if (data.slope === undefined)
184
+ data.slope = 0;
185
+ if (bikeData.isPedalling === undefined)
186
+ data.isPedalling = data.pedalRpm > 0;
187
+ if (((_a = this.prevRequest) === null || _a === void 0 ? void 0 : _a.slope) !== undefined) {
188
+ data.slope = this.prevRequest.slope;
189
+ }
190
+ return data;
191
+ }
60
192
  calculatePowerAndDistance(speed, slope, m, t, props = {}) {
61
- const prevData = this.data || {};
193
+ const prevData = this.getData();
62
194
  const vPrev = (prevData.speed || 0) / 3.6;
63
195
  const EkinPrev = 1 / 2 * m * vPrev * vPrev;
64
196
  const vTarget = (speed || 0) / 3.6;
@@ -71,5 +203,50 @@ class PowerBasedCyclingModeBase extends cycling_mode_1.CyclingModeBase {
71
203
  this.data.power = power;
72
204
  return { power, distance };
73
205
  }
206
+ getBikeInitRequest() {
207
+ return {};
208
+ }
209
+ sendBikeUpdate(incoming) {
210
+ if (this.logger)
211
+ this.logger.logEvent({ message: "processing update request", request: incoming, prev: this.prevRequest, data: this.getData() });
212
+ let newRequest = {};
213
+ const request = Object.assign({}, incoming);
214
+ try {
215
+ const req = this.checkForResetOrEmpty(request);
216
+ if (req)
217
+ return req;
218
+ this.checkSlope(request);
219
+ this.checkForTempPowerAdjustments(request);
220
+ this.checkTargetPowerSet(request, newRequest);
221
+ this.checkRefresh(request, newRequest);
222
+ this.checkMaxPower(request, newRequest);
223
+ this.checkMinPower(request, newRequest);
224
+ this.checkEmptyRequest(newRequest);
225
+ this.prevRequest = JSON.parse(JSON.stringify(newRequest));
226
+ }
227
+ catch (err) {
228
+ if (this.logger)
229
+ this.logger.logEvent({ message: "error", fn: 'sendBikeUpdate()', error: err.message, stack: err.stack });
230
+ }
231
+ return newRequest;
232
+ }
233
+ updateData(bikeData, log = true) {
234
+ try {
235
+ const { data, prevData, slope, bikeType } = this.getCalcBasics(bikeData);
236
+ const t = this.updateSpeedAndDistance(data.power, slope, bikeType, data, prevData);
237
+ data.time = (data.speed > 0) ? data.time + t : data.time;
238
+ if (log && this.logger)
239
+ this.logger.logEvent({ message: "updateData result", mode: this.getName(), data, bikeData });
240
+ this.data = data;
241
+ this.prevUpdateTS = Date.now();
242
+ return data;
243
+ }
244
+ catch (err) {
245
+ if (this.logger)
246
+ this.logger.logEvent({ message: 'error', fn: 'updateData()', error: err.message || err });
247
+ return this.getData();
248
+ }
249
+ }
74
250
  }
251
+ PowerBasedCyclingModeBase.config = { name: '', description: '', properties: [] };
75
252
  exports.default = PowerBasedCyclingModeBase;
@@ -1,20 +1,14 @@
1
- import CyclingMode, { CyclingModeProperty, IncyclistBikeData, Settings, UpdateRequest } from '../modes/cycling-mode';
1
+ import ICyclingMode, { IncyclistBikeData, Settings, UpdateRequest } from './types';
2
2
  import PowerBasedCyclingModeBase from './power-base';
3
- import { ControllableDeviceAdapter } from '..';
4
- export declare const config: {
5
- name: string;
6
- description: string;
7
- properties: any[];
8
- };
9
- export default class PowerMeterCyclingMode extends PowerBasedCyclingModeBase implements CyclingMode {
10
- constructor(adapter: ControllableDeviceAdapter, props?: Settings);
11
- getName(): string;
12
- getDescription(): string;
13
- getProperties(): CyclingModeProperty[];
14
- getProperty(name: string): CyclingModeProperty;
3
+ import { IncyclistDeviceAdapter } from '..';
4
+ export default class PowerMeterCyclingMode extends PowerBasedCyclingModeBase implements ICyclingMode {
5
+ protected static config: {
6
+ name: string;
7
+ description: string;
8
+ properties: any[];
9
+ };
10
+ constructor(adapter: IncyclistDeviceAdapter, props?: Settings);
15
11
  getBikeInitRequest(): UpdateRequest;
16
12
  sendBikeUpdate(request?: UpdateRequest): UpdateRequest;
17
- updateData(bikeData: IncyclistBikeData, props?: {
18
- log: boolean;
19
- }): IncyclistBikeData;
13
+ copyBikeData(data: IncyclistBikeData, bikeData: IncyclistBikeData): IncyclistBikeData;
20
14
  }
@@ -3,76 +3,37 @@ 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.config = void 0;
7
6
  const power_base_1 = __importDefault(require("./power-base"));
8
- const MIN_SPEED = 10;
9
- exports.config = {
10
- name: 'PowerMeter',
11
- description: 'Power and cadence are taken from device. Speed is calculated from power and current slope\nThis mode will not respect maximum power and/or workout limits',
12
- properties: []
13
- };
14
7
  class PowerMeterCyclingMode extends power_base_1.default {
15
8
  constructor(adapter, props) {
16
9
  super(adapter, props);
17
10
  this.initLogger('PowerMeterMode');
18
- this.data = { speed: 0, slope: 0, power: 0, distanceInternal: 0, pedalRpm: 0, isPedalling: false, heartrate: 0 };
19
- }
20
- getName() {
21
- return exports.config.name;
22
- }
23
- getDescription() {
24
- return exports.config.description;
25
- }
26
- getProperties() {
27
- return exports.config.properties;
28
- }
29
- getProperty(name) {
30
- return exports.config.properties.find(p => p.name === name);
11
+ this.data.slope = 0;
31
12
  }
32
13
  getBikeInitRequest() {
33
14
  return {};
34
15
  }
35
16
  sendBikeUpdate(request = {}) {
36
- const prevData = this.data || {};
37
- const prevSlope = prevData.slope || 0;
17
+ this.logger.logEvent({ message: "processing update request", request });
18
+ const prevData = this.data;
19
+ const prevSlope = prevData.slope;
38
20
  if (request.slope && request.slope !== prevSlope) {
39
21
  this.data.slope = request.slope;
40
- this.updateData(this.data, { log: false });
22
+ this.updateData(this.data, false);
41
23
  }
42
- this.logger.logEvent({ message: "processing update request", request });
43
24
  return {};
44
25
  }
45
- updateData(bikeData, props = { log: true }) {
46
- try {
47
- const prevData = this.data || {};
48
- const data = JSON.parse(JSON.stringify(bikeData));
49
- let power = bikeData.power || 0;
50
- const slope = prevData.slope || 0;
51
- const distanceInternal = prevData.distanceInternal || 0;
52
- if (power > 0) {
53
- data.isPedalling = true;
54
- }
55
- const m = this.getWeight();
56
- const t = this.getTimeSinceLastUpdate();
57
- const { speed, distance } = this.calculateSpeedAndDistance(power, slope, m, t);
58
- data.power = Math.round(power);
59
- data.slope = slope;
60
- if (power === 0 && speed < MIN_SPEED) {
61
- data.speed = Math.round(prevData.speed - 1) < 0 ? 0 : Math.round(prevData.speed - 1);
62
- data.distanceInternal = distanceInternal + data.speed / 3.6 * t;
63
- }
64
- else {
65
- data.speed = speed;
66
- data.distanceInternal = distanceInternal + distance;
67
- }
68
- if (props.log)
69
- this.logger.logEvent({ message: "updateData result", data, bikeData, prevSpeed: prevData.speed, stopped: speed < MIN_SPEED });
70
- this.data = data;
26
+ copyBikeData(data, bikeData) {
27
+ const newData = super.copyBikeData(data, bikeData);
28
+ if (bikeData.power > 0) {
29
+ newData.isPedalling = true;
71
30
  }
72
- catch (err) {
73
- this.logger.logEvent({ message: 'error', fn: 'updateData()', error: err.message || err });
74
- }
75
- return this.data;
31
+ return newData;
76
32
  }
77
33
  }
34
+ PowerMeterCyclingMode.config = {
35
+ name: 'PowerMeter',
36
+ description: 'Power and cadence are taken from device. Speed is calculated from power and current slope\nThis mode will not respect maximum power and/or workout limits',
37
+ properties: []
38
+ };
78
39
  exports.default = PowerMeterCyclingMode;
@@ -1,5 +1,5 @@
1
1
  import { EventLogger } from "gd-eventlog";
2
- import { CyclingModeProperty, IncyclistBikeData, UpdateRequest } from "../modes/cycling-mode";
2
+ import { CyclingModeProperyType, IncyclistBikeData, UpdateRequest } from "./types";
3
3
  import { Simulator } from "../simulator/Simulator";
4
4
  import PowerBasedCyclingModeBase from "./power-base";
5
5
  export type ERGEvent = {
@@ -9,21 +9,48 @@ export type ERGEvent = {
9
9
  tsStart?: number;
10
10
  };
11
11
  export default class SimulatorCyclingMode extends PowerBasedCyclingModeBase {
12
- static isERG: boolean;
12
+ protected static config: {
13
+ isERG: boolean;
14
+ name: string;
15
+ description: string;
16
+ properties: ({
17
+ key: string;
18
+ name: string;
19
+ description: string;
20
+ type: CyclingModeProperyType;
21
+ options: string[];
22
+ default: string;
23
+ min?: undefined;
24
+ max?: undefined;
25
+ condition?: undefined;
26
+ } | {
27
+ key: string;
28
+ name: string;
29
+ description: string;
30
+ type: CyclingModeProperyType;
31
+ default: number;
32
+ min: number;
33
+ max: number;
34
+ options?: undefined;
35
+ condition?: undefined;
36
+ } | {
37
+ key: string;
38
+ name: string;
39
+ description: string;
40
+ condition: (s: any) => boolean;
41
+ type: CyclingModeProperyType;
42
+ default: number;
43
+ min: number;
44
+ max: number;
45
+ options?: undefined;
46
+ })[];
47
+ };
13
48
  logger: EventLogger;
14
49
  data: IncyclistBikeData;
15
50
  prevRequest: UpdateRequest;
16
51
  prevUpdateTS: number;
17
- hasBikeUpdate: boolean;
18
- chain: number[];
19
- cassette: number[];
20
52
  event: ERGEvent;
21
53
  constructor(adapter: Simulator, props?: any);
22
- getName(): string;
23
- getDescription(): string;
24
- getProperties(): CyclingModeProperty[];
25
- getProperty(name: string): CyclingModeProperty;
26
54
  getBikeInitRequest(): UpdateRequest;
27
- sendBikeUpdate(request: UpdateRequest): UpdateRequest;
28
55
  updateData(bikeData: IncyclistBikeData): IncyclistBikeData;
29
56
  }
@@ -3,62 +3,19 @@ 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
- const gd_eventlog_1 = require("gd-eventlog");
7
- const cycling_mode_1 = require("../modes/cycling-mode");
6
+ const types_1 = require("./types");
8
7
  const power_base_1 = __importDefault(require("./power-base"));
9
8
  const MIN_SPEED = 10;
10
- const config = {
11
- name: "Simulator",
12
- description: "Simulates a ride with constant speed or power output",
13
- properties: [
14
- { key: 'mode', name: 'Simulation Type', description: '', type: cycling_mode_1.CyclingModeProperyType.SingleSelect, options: ['Speed', 'Power'], default: 'Power' },
15
- { key: 'delay', name: 'Start Delay', description: 'Delay (in s) at start of training', type: cycling_mode_1.CyclingModeProperyType.Integer, default: 2, min: 0, max: 30 },
16
- { key: 'power', name: 'Power', description: 'Power (in W) at start of training', condition: (s) => !s.mode || s.mode === 'Power', type: cycling_mode_1.CyclingModeProperyType.Integer, default: 150, min: 25, max: 800 },
17
- { key: 'speed', name: 'Speed', description: 'Speed (in km/h) at start of training', condition: (s) => s.mode === 'Speed', type: cycling_mode_1.CyclingModeProperyType.Integer, default: 30, min: 5, max: 50 },
18
- { key: 'bikeType', name: 'Bike Type', description: '', type: cycling_mode_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain', 'Triathlon'], default: 'Race' }
19
- ]
20
- };
21
9
  class SimulatorCyclingMode extends power_base_1.default {
22
10
  constructor(adapter, props) {
23
11
  super(adapter, props);
24
12
  this.prevUpdateTS = 0;
25
- this.hasBikeUpdate = false;
26
13
  this.event = {};
27
- this.logger = adapter.logger || new gd_eventlog_1.EventLogger('SIMMode');
28
- this.data = {};
29
- this.logger.logEvent({ message: 'constructor', props });
30
- }
31
- getName() {
32
- return config.name;
33
- }
34
- getDescription() {
35
- return config.description;
36
- }
37
- getProperties() {
38
- return config.properties;
39
- }
40
- getProperty(name) {
41
- return config.properties.find(p => p.name === name);
14
+ this.initLogger('SIMMode');
42
15
  }
43
16
  getBikeInitRequest() {
44
17
  return {};
45
18
  }
46
- sendBikeUpdate(request) {
47
- this.logger.logEvent({ message: 'bike update request', request });
48
- const r = request || { refresh: true };
49
- if (r.refresh) {
50
- if (Object.keys(r).length === 1)
51
- return this.prevRequest || {};
52
- delete r.refresh;
53
- }
54
- if (request.slope !== undefined) {
55
- if (!this.data)
56
- this.data = {};
57
- this.data.slope = request.slope;
58
- }
59
- this.prevRequest = request ? JSON.parse(JSON.stringify(request)) : {};
60
- return r;
61
- }
62
19
  updateData(bikeData) {
63
20
  const prevData = JSON.parse(JSON.stringify(this.data || {}));
64
21
  const prevSpeed = prevData.speed;
@@ -136,5 +93,16 @@ class SimulatorCyclingMode extends power_base_1.default {
136
93
  return data;
137
94
  }
138
95
  }
139
- SimulatorCyclingMode.isERG = true;
96
+ SimulatorCyclingMode.config = {
97
+ isERG: true,
98
+ name: "Simulator",
99
+ description: "Simulates a ride with constant speed or power output",
100
+ properties: [
101
+ { key: 'mode', name: 'Simulation Type', description: '', type: types_1.CyclingModeProperyType.SingleSelect, options: ['Speed', 'Power'], default: 'Power' },
102
+ { key: 'delay', name: 'Start Delay', description: 'Delay (in s) at start of training', type: types_1.CyclingModeProperyType.Integer, default: 2, min: 0, max: 30 },
103
+ { key: 'power', name: 'Power', description: 'Power (in W) at start of training', condition: (s) => !s.mode || s.mode === 'Power', type: types_1.CyclingModeProperyType.Integer, default: 150, min: 25, max: 800 },
104
+ { key: 'speed', name: 'Speed', description: 'Speed (in km/h) at start of training', condition: (s) => s.mode === 'Speed', type: types_1.CyclingModeProperyType.Integer, default: 30, min: 5, max: 50 },
105
+ { key: 'bikeType', name: 'Bike Type', description: '', type: types_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain', 'Triathlon'], default: 'Race' }
106
+ ]
107
+ };
140
108
  exports.default = SimulatorCyclingMode;
@@ -1,4 +1,4 @@
1
- import { ControllableDeviceAdapter } from "..";
1
+ import { IBike } from "../types/adapter";
2
2
  export type UpdateRequest = {
3
3
  slope?: number;
4
4
  minPower?: number;
@@ -41,14 +41,14 @@ export type IncyclistBikeData = {
41
41
  export type Settings = {
42
42
  [key: string]: any;
43
43
  };
44
- export default interface CyclingMode {
44
+ export default interface ICyclingMode {
45
45
  getName(): string;
46
46
  getDescription(): string;
47
+ getProperties(): CyclingModeProperty[];
48
+ getProperty(name: string): CyclingModeProperty;
47
49
  getBikeInitRequest(): UpdateRequest;
48
50
  sendBikeUpdate(request: UpdateRequest): UpdateRequest;
49
51
  updateData(data: IncyclistBikeData): IncyclistBikeData;
50
- getProperties(): CyclingModeProperty[];
51
- getProperty(name: string): CyclingModeProperty;
52
52
  setSettings(settings: any): any;
53
53
  setSetting(name: string, value: any): void;
54
54
  getSetting(name: string): any;
@@ -56,23 +56,26 @@ export default interface CyclingMode {
56
56
  setModeProperty(name: string, value: any): void;
57
57
  getModeProperty(name: string): any;
58
58
  }
59
- export declare class CyclingModeBase implements CyclingMode {
60
- adapter: ControllableDeviceAdapter;
61
- settings: Settings;
62
- properties: Settings;
63
- constructor(adapter: ControllableDeviceAdapter, props?: any);
64
- setAdapter(adapter: ControllableDeviceAdapter): void;
65
- getBikeInitRequest(): UpdateRequest;
59
+ export type CyclingModeConfig = {
60
+ isERG?: boolean;
61
+ name: string;
62
+ description: string;
63
+ properties: CyclingModeProperty[];
64
+ };
65
+ export declare class CyclingMode implements ICyclingMode {
66
+ constructor(_adapter: IBike, _props?: any);
67
+ static supportsERGMode(): boolean;
66
68
  getName(): string;
67
69
  getDescription(): string;
68
- sendBikeUpdate(request: UpdateRequest): UpdateRequest;
69
- updateData(data: IncyclistBikeData): IncyclistBikeData;
70
70
  getProperties(): CyclingModeProperty[];
71
- getProperty(name: string): CyclingModeProperty;
72
- setSettings(settings?: any): void;
73
- setSetting(name: string, value: any): void;
74
- getSetting(name: string): any;
71
+ getProperty(_name: string): CyclingModeProperty;
72
+ getBikeInitRequest(): UpdateRequest;
73
+ sendBikeUpdate(_request: UpdateRequest): UpdateRequest;
74
+ updateData(_data: IncyclistBikeData): IncyclistBikeData;
75
+ setSettings(_settings: any): void;
76
+ setSetting(_name: string, _value: any): void;
77
+ getSetting(_name: string): void;
75
78
  getSettings(): Settings;
76
- setModeProperty(name: string, value: any): void;
77
- getModeProperty(name: string): any;
79
+ setModeProperty(_name: string, _value: any): void;
80
+ getModeProperty(_name: string): void;
78
81
  }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CyclingMode = exports.CyclingModeProperyType = void 0;
4
+ var CyclingModeProperyType;
5
+ (function (CyclingModeProperyType) {
6
+ CyclingModeProperyType["Integer"] = "Integer";
7
+ CyclingModeProperyType["Boolean"] = "Boolean";
8
+ CyclingModeProperyType["Float"] = "Float";
9
+ CyclingModeProperyType["String"] = "String";
10
+ CyclingModeProperyType["SingleSelect"] = "SingleSelect";
11
+ CyclingModeProperyType["MultiSelect"] = "MultiSelect";
12
+ })(CyclingModeProperyType || (exports.CyclingModeProperyType = CyclingModeProperyType = {}));
13
+ class CyclingMode {
14
+ constructor(_adapter, _props) { }
15
+ static supportsERGMode() { return false; }
16
+ getName() {
17
+ throw new Error("Method not implemented.");
18
+ }
19
+ getDescription() {
20
+ throw new Error("Method not implemented.");
21
+ }
22
+ getProperties() {
23
+ throw new Error("Method not implemented.");
24
+ }
25
+ getProperty(_name) {
26
+ throw new Error("Method not implemented.");
27
+ }
28
+ getBikeInitRequest() {
29
+ throw new Error("Method not implemented.");
30
+ }
31
+ sendBikeUpdate(_request) {
32
+ throw new Error("Method not implemented.");
33
+ }
34
+ updateData(_data) {
35
+ throw new Error("Method not implemented.");
36
+ }
37
+ setSettings(_settings) {
38
+ throw new Error("Method not implemented.");
39
+ }
40
+ setSetting(_name, _value) {
41
+ throw new Error("Method not implemented.");
42
+ }
43
+ getSetting(_name) {
44
+ throw new Error("Method not implemented.");
45
+ }
46
+ getSettings() {
47
+ throw new Error("Method not implemented.");
48
+ }
49
+ setModeProperty(_name, _value) {
50
+ throw new Error("Method not implemented.");
51
+ }
52
+ getModeProperty(_name) {
53
+ throw new Error("Method not implemented.");
54
+ }
55
+ }
56
+ exports.CyclingMode = CyclingMode;