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
@@ -0,0 +1,49 @@
1
+ import ICyclingMode, { CyclingModeProperyType, IncyclistBikeData, UpdateRequest } from "./types";
2
+ import PowerBasedCyclingModeBase from "./power-base";
3
+ import { IncyclistDeviceAdapter } from "../types/adapter";
4
+ export type ERGEvent = {
5
+ rpmUpdated?: boolean;
6
+ gearUpdated?: boolean;
7
+ starting?: boolean;
8
+ tsStart?: number;
9
+ };
10
+ export default class ERGCyclingMode extends PowerBasedCyclingModeBase implements ICyclingMode {
11
+ prevRequest: UpdateRequest;
12
+ hasBikeUpdate: boolean;
13
+ chain: number[];
14
+ cassette: number[];
15
+ event: ERGEvent;
16
+ protected static config: {
17
+ isERG: boolean;
18
+ name: string;
19
+ description: string;
20
+ properties: ({
21
+ key: string;
22
+ name: string;
23
+ description: string;
24
+ type: CyclingModeProperyType;
25
+ options: string[];
26
+ default: string;
27
+ min?: undefined;
28
+ max?: undefined;
29
+ } | {
30
+ key: string;
31
+ name: string;
32
+ description: string;
33
+ type: CyclingModeProperyType;
34
+ default: number;
35
+ min: number;
36
+ max: number;
37
+ options?: undefined;
38
+ })[];
39
+ };
40
+ constructor(adapter: IncyclistDeviceAdapter, props?: any);
41
+ getBikeInitRequest(): UpdateRequest;
42
+ sendBikeUpdate(request: UpdateRequest): UpdateRequest;
43
+ copyBikeData(data: IncyclistBikeData, bikeData: IncyclistBikeData): IncyclistBikeData;
44
+ updateData(bikeData: IncyclistBikeData): IncyclistBikeData;
45
+ private checkForEvents;
46
+ private cleanupPrevEvents;
47
+ private checkIsStarting;
48
+ calculateTargetPower(request: any, updateMode?: boolean): any;
49
+ }
@@ -3,18 +3,9 @@ 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("../../modes/cycling-mode");
7
- const calculations_1 = __importDefault(require("../../utils/calculations"));
8
- const power_base_1 = __importDefault(require("../../modes/power-base"));
9
- const MIN_SPEED = 10;
10
- const config = {
11
- name: "ERG",
12
- description: "Calculates speed based on power and slope. Power is either set by workout or calculated based on gear and cadence",
13
- properties: [
14
- { key: 'bikeType', name: 'Bike Type', description: '', type: cycling_mode_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain', 'Triathlon'], default: 'Race' },
15
- { key: 'startPower', name: 'Starting Power', description: 'Initial power in Watts at start of training', type: cycling_mode_1.CyclingModeProperyType.Integer, default: 50, min: 25, max: 800 },
16
- ]
17
- };
6
+ const types_1 = require("./types");
7
+ const calculations_1 = __importDefault(require("../utils/calculations"));
8
+ const power_base_1 = __importDefault(require("./power-base"));
18
9
  class ERGCyclingMode extends power_base_1.default {
19
10
  constructor(adapter, props) {
20
11
  super(adapter, props);
@@ -22,18 +13,6 @@ class ERGCyclingMode extends power_base_1.default {
22
13
  this.event = {};
23
14
  this.initLogger('ERGMode');
24
15
  }
25
- getName() {
26
- return config.name;
27
- }
28
- getDescription() {
29
- return config.description;
30
- }
31
- getProperties() {
32
- return config.properties;
33
- }
34
- getProperty(name) {
35
- return config.properties.find(p => p.name === name);
36
- }
37
16
  getBikeInitRequest() {
38
17
  const startPower = this.getSetting('startPower');
39
18
  return { targetPower: startPower, init: true };
@@ -133,61 +112,46 @@ class ERGCyclingMode extends power_base_1.default {
133
112
  this.event.rpmUpdated = false;
134
113
  return newRequest;
135
114
  }
115
+ copyBikeData(data, bikeData) {
116
+ const newData = super.copyBikeData(data, bikeData);
117
+ if (!bikeData.pedalRpm || bikeData.isPedalling === false) {
118
+ newData.power = 0;
119
+ }
120
+ if (newData.gear === undefined)
121
+ newData.gear = 0;
122
+ return newData;
123
+ }
136
124
  updateData(bikeData) {
137
- const prevData = JSON.parse(JSON.stringify(this.data || {}));
138
- const prevSpeed = prevData.speed;
139
- const prevRequest = this.prevRequest || {};
140
- const data = this.data || {};
141
- const bikeType = this.getSetting('bikeType').toLowerCase();
125
+ try {
126
+ const prevData = JSON.parse(JSON.stringify(this.getData()));
127
+ this.cleanupPrevEvents();
128
+ this.checkIsStarting(prevData);
129
+ const data = super.updateData(bikeData);
130
+ this.checkForEvents(bikeData, prevData);
131
+ return data;
132
+ }
133
+ catch (err) {
134
+ this.logger.logEvent({ message: 'error', fn: 'updateData()', error: err.message, stack: err.stack });
135
+ return this.getData();
136
+ }
137
+ }
138
+ checkForEvents(bikeData, prevData) {
139
+ if (bikeData.gear !== prevData.gear) {
140
+ this.event.gearUpdated = true;
141
+ }
142
+ if (bikeData.pedalRpm && bikeData.pedalRpm !== prevData.pedalRpm) {
143
+ this.event.rpmUpdated = true;
144
+ }
145
+ }
146
+ cleanupPrevEvents() {
142
147
  delete this.event.gearUpdated;
143
148
  delete this.event.rpmUpdated;
149
+ }
150
+ checkIsStarting(prevData) {
144
151
  if (Object.keys(prevData).length === 0 || prevData.speed === undefined || prevData.speed === 0) {
145
152
  this.event.starting = true;
146
153
  this.event.tsStart = Date.now();
147
154
  }
148
- try {
149
- const rpm = bikeData.pedalRpm || 0;
150
- const gear = bikeData.gear || 0;
151
- let power = bikeData.power || 0;
152
- const slope = (prevData.slope !== undefined ? prevData.slope : prevRequest.slope || 0);
153
- const distanceInternal = prevData.distanceInternal || 0;
154
- if (!bikeData.pedalRpm || bikeData.isPedalling === false) {
155
- power = 0;
156
- }
157
- const m = this.getWeight();
158
- const t = this.getTimeSinceLastUpdate();
159
- const { speed, distance } = this.calculateSpeedAndDistance(power, slope, m, t, { bikeType });
160
- if (power === 0 && speed < MIN_SPEED) {
161
- data.speed = Math.round(prevData.speed - 1) < 0 ? 0 : Math.round(prevData.speed - 1);
162
- data.distanceInternal = distanceInternal + data.speed / 3.6 * t;
163
- }
164
- else {
165
- data.speed = speed;
166
- data.distanceInternal = distanceInternal + distance;
167
- }
168
- data.power = Math.round(power);
169
- data.slope = slope;
170
- data.pedalRpm = rpm;
171
- data.gear = gear;
172
- if (data.time !== undefined && !(this.event.starting && !bikeData.pedalRpm))
173
- data.time += t;
174
- else
175
- data.time = 0;
176
- data.heartrate = bikeData.heartrate;
177
- data.isPedalling = bikeData.isPedalling;
178
- if (gear !== prevData.gear) {
179
- this.event.gearUpdated = true;
180
- }
181
- if (rpm && rpm !== prevData.pedalRpm) {
182
- this.event.rpmUpdated = true;
183
- }
184
- }
185
- catch (err) {
186
- this.logger.logEvent({ message: 'error', fn: 'updateData()', error: err.message || err, stack: err.stack });
187
- }
188
- this.logger.logEvent({ message: "updateData result", data, bikeData, prevRequest, prevSpeed });
189
- this.data = data;
190
- return data;
191
155
  }
192
156
  calculateTargetPower(request, updateMode = true) {
193
157
  const bikeType = this.getSetting('bikeType').toLowerCase();
@@ -206,5 +170,13 @@ class ERGCyclingMode extends power_base_1.default {
206
170
  return target;
207
171
  }
208
172
  }
209
- ERGCyclingMode.isERG = true;
173
+ ERGCyclingMode.config = {
174
+ isERG: true,
175
+ name: "ERG",
176
+ description: "Calculates speed based on power and slope. Power is either set by workout or calculated based on gear and cadence",
177
+ properties: [
178
+ { key: 'bikeType', name: 'Bike Type', description: '', type: types_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain', 'Triathlon'], default: 'Race' },
179
+ { key: 'startPower', name: 'Starting Power', description: 'Initial power in Watts at start of training', type: types_1.CyclingModeProperyType.Integer, default: 50, min: 25, max: 800 },
180
+ ]
181
+ };
210
182
  exports.default = ERGCyclingMode;
@@ -0,0 +1,5 @@
1
+ import ICyclingMode, { UpdateRequest } from "./types";
2
+ import PowerMeterCyclingMode from "./power-meter";
3
+ export default class DaumPowerMeterCyclingMode extends PowerMeterCyclingMode implements ICyclingMode {
4
+ getBikeInitRequest(): UpdateRequest;
5
+ }
@@ -3,19 +3,10 @@ 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 power_meter_1 = __importDefault(require("../../modes/power-meter"));
6
+ const power_meter_1 = __importDefault(require("./power-meter"));
7
7
  class DaumPowerMeterCyclingMode extends power_meter_1.default {
8
- constructor() {
9
- super(...arguments);
10
- this.hasBikeUpdate = false;
11
- }
12
8
  getBikeInitRequest() {
13
9
  return { slope: 0 };
14
10
  }
15
- sendBikeUpdate(request) {
16
- super.sendBikeUpdate(request);
17
- this.prevRequest = {};
18
- return {};
19
- }
20
11
  }
21
12
  exports.default = DaumPowerMeterCyclingMode;
@@ -0,0 +1,23 @@
1
+ import ICyclingMode, { CyclingModeProperyType, IncyclistBikeData, Settings, UpdateRequest } from "./types";
2
+ import { IncyclistDeviceAdapter } from "../types/adapter";
3
+ import PowerMeterCyclingMode from "./power-meter";
4
+ export default class DaumClassicCyclingMode extends PowerMeterCyclingMode implements ICyclingMode {
5
+ prevInternalDistance: number;
6
+ distanceOffset: number;
7
+ protected static config: {
8
+ name: string;
9
+ description: string;
10
+ properties: {
11
+ key: string;
12
+ name: string;
13
+ description: string;
14
+ type: CyclingModeProperyType;
15
+ options: string[];
16
+ default: string;
17
+ }[];
18
+ };
19
+ constructor(adapter: IncyclistDeviceAdapter, props?: Settings);
20
+ getBikeInitRequest(): UpdateRequest;
21
+ updateData(data: IncyclistBikeData): IncyclistBikeData;
22
+ sendBikeUpdate(request: UpdateRequest): UpdateRequest;
23
+ }
@@ -4,16 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const gd_eventlog_1 = require("gd-eventlog");
7
- const cycling_mode_1 = require("../../../../modes/cycling-mode");
8
- const DaumPowerMeterCyclingMode_1 = __importDefault(require("../../DaumPowerMeterCyclingMode"));
9
- const config = {
10
- name: "Daum Classic",
11
- description: "The device calculates speed and power based on slope. Incyclist will not modify any values recived from the device\nThis mode will not respect maximum power and/or workout limits",
12
- properties: [
13
- { key: 'bikeType', name: 'Bike Type', description: '', type: cycling_mode_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain'], default: 'Race' },
14
- ]
15
- };
16
- class DaumClassicCyclingMode extends DaumPowerMeterCyclingMode_1.default {
7
+ const types_1 = require("./types");
8
+ const power_meter_1 = __importDefault(require("./power-meter"));
9
+ class DaumClassicCyclingMode extends power_meter_1.default {
17
10
  constructor(adapter, props) {
18
11
  super(adapter, props);
19
12
  this.logger = adapter ? adapter.getLogger() : undefined;
@@ -22,65 +15,60 @@ class DaumClassicCyclingMode extends DaumPowerMeterCyclingMode_1.default {
22
15
  this.setModeProperty('eppSupport', true);
23
16
  this.setModeProperty('setPersonSupport', true);
24
17
  }
25
- getName() {
26
- return config.name;
27
- }
28
- getDescription() {
29
- return config.description;
30
- }
31
- getProperties() {
32
- return config.properties;
33
- }
34
- getProperty(name) {
35
- return config.properties.find(p => p.name === name);
36
- }
37
18
  getBikeInitRequest() {
38
19
  return {};
39
20
  }
40
- getSettings() {
41
- const settings = super.getSettings();
42
- settings['setPerson'] = true;
43
- return settings;
44
- }
45
- getSetting(name) {
46
- if (name === 'setPerson')
47
- return true;
48
- return super.getSetting(name);
49
- }
50
21
  updateData(data) {
51
22
  try {
52
- const prevData = this.data || {};
23
+ const prevData = Object.assign({}, this.getData());
53
24
  const prevRequest = this.prevRequest || {};
54
25
  const bikeData = JSON.parse(JSON.stringify(data));
55
26
  let power = data.power || 0;
56
27
  let speed = data.speed || 0;
57
28
  let slope = (prevData.slope !== undefined ? prevData.slope : prevRequest.slope || 0);
58
29
  let distanceBike = data.distanceInternal || 0;
59
- let distancePrev = prevData.distanceInternal || 0;
60
- let distanceInternal = distanceBike;
30
+ let distancePrev = this.prevInternalDistance || 0;
31
+ let distanceInternal = distanceBike + (this.distanceOffset || 0);
32
+ let time = prevData.time || 0;
61
33
  let ts = Date.now();
34
+ let t = this.getTimeSinceLastUpdate();
62
35
  if (!bikeData.pedalRpm || bikeData.isPedalling === false) {
63
36
  speed = 0;
64
37
  power = 0;
65
38
  }
66
39
  if (distanceBike < distancePrev) {
67
- this.logger.logEvent({ message: '~~~ distance overflow', distanceBike, distancePrev });
40
+ this.logger.logEvent({ message: 'distance overflow', distanceBike, distancePrev });
68
41
  let v = speed / 3.6;
69
- let duration = this.prevUpdateTS === 0 ? 0 : ((ts - this.prevUpdateTS) / 1000);
70
- distanceInternal = distancePrev + v * duration;
42
+ const calculateDistance = distancePrev + (this.distanceOffset || 0) + v * t;
43
+ this.distanceOffset = calculateDistance - distanceBike;
44
+ distanceInternal = calculateDistance;
71
45
  }
72
46
  data.speed = parseFloat(speed.toFixed(1));
73
47
  data.power = Math.round(power);
74
48
  data.distanceInternal = distanceInternal;
75
49
  data.slope = slope;
50
+ data.time = speed > 0 ? time + t : time;
76
51
  this.logger.logEvent({ message: "updateData result", data, bikeData, prevRequest: {}, prevSpeed: prevData.speed });
77
52
  this.data = JSON.parse(JSON.stringify(data));
78
53
  this.prevUpdateTS = ts;
54
+ this.prevInternalDistance = distanceBike;
79
55
  }
80
56
  catch (err) {
81
57
  this.logger.logEvent({ message: 'error', fn: 'updateData()', error: err.message || err });
82
58
  }
83
59
  return data;
84
60
  }
61
+ sendBikeUpdate(request) {
62
+ super.sendBikeUpdate(request);
63
+ this.prevRequest = {};
64
+ return {};
65
+ }
85
66
  }
67
+ DaumClassicCyclingMode.config = {
68
+ name: "Daum Classic",
69
+ description: "The device calculates speed and power based on slope. Incyclist will not modify any values recived from the device\nThis mode will not respect maximum power and/or workout limits",
70
+ properties: [
71
+ { key: 'bikeType', name: 'Bike Type', description: '', type: types_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain'], default: 'Race' },
72
+ ]
73
+ };
86
74
  exports.default = DaumClassicCyclingMode;
@@ -0,0 +1,82 @@
1
+ import { EventLogger } from "gd-eventlog";
2
+ import ICyclingMode, { CyclingModeProperyType, IncyclistBikeData, Settings, UpdateRequest } from "./types";
3
+ import { IncyclistDeviceAdapter } from "..";
4
+ import { CyclingModeBase } from "./base";
5
+ interface STUpdateRequest extends UpdateRequest {
6
+ calculatedPower?: number;
7
+ delta?: number;
8
+ enforced?: boolean;
9
+ belowMin?: boolean;
10
+ aboveMax?: boolean;
11
+ }
12
+ export declare enum direction {
13
+ up = "up",
14
+ down = "down"
15
+ }
16
+ interface STEvent {
17
+ gearUpdate?: direction;
18
+ rpmUpdate?: boolean;
19
+ targetNotReached?: number;
20
+ }
21
+ export default class SmartTrainerCyclingMode extends CyclingModeBase implements ICyclingMode {
22
+ logger: EventLogger;
23
+ data?: IncyclistBikeData;
24
+ prevRequest?: STUpdateRequest;
25
+ prevUpdateTS: number;
26
+ chain: number[];
27
+ cassette: number[];
28
+ event: STEvent;
29
+ protected static config: {
30
+ name: string;
31
+ description: string;
32
+ properties: ({
33
+ key: string;
34
+ name: string;
35
+ description: string;
36
+ type: CyclingModeProperyType;
37
+ options: string[];
38
+ default: string;
39
+ validation?: undefined;
40
+ condition?: undefined;
41
+ } | {
42
+ key: string;
43
+ name: string;
44
+ description: string;
45
+ type: CyclingModeProperyType;
46
+ default: number;
47
+ options?: undefined;
48
+ validation?: undefined;
49
+ condition?: undefined;
50
+ } | {
51
+ key: string;
52
+ name: string;
53
+ description: string;
54
+ type: CyclingModeProperyType;
55
+ default: boolean;
56
+ options?: undefined;
57
+ validation?: undefined;
58
+ condition?: undefined;
59
+ } | {
60
+ key: string;
61
+ name: string;
62
+ description: string;
63
+ type: CyclingModeProperyType;
64
+ validation: string;
65
+ default: string;
66
+ condition: (s: any) => any;
67
+ options?: undefined;
68
+ })[];
69
+ };
70
+ constructor(adapter: IncyclistDeviceAdapter, props?: Settings);
71
+ getData(): IncyclistBikeData;
72
+ getSlope(): number;
73
+ getWeight(): number;
74
+ getBikeInitRequest(): STUpdateRequest;
75
+ useGearSimulation(): boolean;
76
+ getMinMaxGears(source: string): [number, number];
77
+ sendBikeUpdate(request: STUpdateRequest): STUpdateRequest;
78
+ updateData(bikeData: IncyclistBikeData): any;
79
+ calculateSpeed(gear: any, rpm: any, slope: any, bikeSpeed: any, props?: any): any;
80
+ calculateTargetPower(request: STUpdateRequest, speed?: number): STUpdateRequest;
81
+ }
82
+ export {};
@@ -5,28 +5,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.direction = void 0;
7
7
  const gd_eventlog_1 = require("gd-eventlog");
8
- const cycling_mode_1 = require("../../modes/cycling-mode");
9
- const calculations_1 = __importDefault(require("../../utils/calculations"));
10
- const utils_1 = require("./classic/utils");
8
+ const types_1 = require("./types");
9
+ const calculations_1 = __importDefault(require("../utils/calculations"));
10
+ const utils_1 = require("../serial/daum/classic/utils");
11
+ const base_1 = require("./base");
11
12
  const SEC_DELAY = 3;
12
- const config = {
13
- name: "SmartTrainer",
14
- description: "Calculates power based on speed and slope.",
15
- properties: [
16
- { key: 'bikeType', name: 'Bike Type', description: '', type: cycling_mode_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain', 'Triathlon'], default: 'Race' },
17
- { key: 'startPower', name: 'Starting Power', description: 'Initial power in Watts at start of training', type: cycling_mode_1.CyclingModeProperyType.Integer, default: 50 },
18
- { key: 'minPower', name: 'Minimum Power', description: 'Minimum power in declines', type: cycling_mode_1.CyclingModeProperyType.Integer, default: 50 },
19
- { key: 'simulation', name: 'Simulate ', description: 'Simulate ', type: cycling_mode_1.CyclingModeProperyType.Boolean, default: false },
20
- { key: 'chainRings', name: 'Chain Rings', description: 'Simulated chain rings (format: <min>-<max>)', type: cycling_mode_1.CyclingModeProperyType.String, validation: '', default: '36-52', condition: (s) => s.simulation },
21
- { key: 'cassetteRings', name: 'Cassette', description: 'Simulated cassette (format: <min>-<max>)', type: cycling_mode_1.CyclingModeProperyType.String, validation: '', default: '11-30', condition: (s) => s.simulation },
22
- ]
23
- };
24
13
  var direction;
25
14
  (function (direction) {
26
15
  direction["up"] = "up";
27
16
  direction["down"] = "down";
28
17
  })(direction || (exports.direction = direction = {}));
29
- class SmartTrainerCyclingMode extends cycling_mode_1.CyclingModeBase {
18
+ class SmartTrainerCyclingMode extends base_1.CyclingModeBase {
30
19
  constructor(adapter, props) {
31
20
  super(adapter, props);
32
21
  this.prevUpdateTS = 0;
@@ -34,18 +23,14 @@ class SmartTrainerCyclingMode extends cycling_mode_1.CyclingModeBase {
34
23
  this.logger = adapter ? adapter.getLogger() : undefined;
35
24
  if (!this.logger)
36
25
  this.logger = new gd_eventlog_1.EventLogger('SmartTrainer');
26
+ this.data = { speed: 0, power: 0, distanceInternal: 0, pedalRpm: 0, isPedalling: false, heartrate: 0 };
37
27
  }
38
- getName() {
39
- return config.name;
40
- }
41
- getDescription() {
42
- return config.description;
28
+ getData() {
29
+ return this.data;
43
30
  }
44
- getProperties() {
45
- return config.properties;
46
- }
47
- getProperty(name) {
48
- return config.properties.find(p => p.name === name);
31
+ getSlope() {
32
+ const { slope } = this.data;
33
+ return slope || 0;
49
34
  }
50
35
  getWeight() {
51
36
  const a = this.adapter;
@@ -347,4 +332,16 @@ class SmartTrainerCyclingMode extends cycling_mode_1.CyclingModeBase {
347
332
  return request;
348
333
  }
349
334
  }
335
+ SmartTrainerCyclingMode.config = {
336
+ name: "SmartTrainer",
337
+ description: "Calculates power based on speed and slope.",
338
+ properties: [
339
+ { key: 'bikeType', name: 'Bike Type', description: '', type: types_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain', 'Triathlon'], default: 'Race' },
340
+ { key: 'startPower', name: 'Starting Power', description: 'Initial power in Watts at start of training', type: types_1.CyclingModeProperyType.Integer, default: 50 },
341
+ { key: 'minPower', name: 'Minimum Power', description: 'Minimum power in declines', type: types_1.CyclingModeProperyType.Integer, default: 50 },
342
+ { key: 'simulation', name: 'Simulate ', description: 'Simulate ', type: types_1.CyclingModeProperyType.Boolean, default: false },
343
+ { key: 'chainRings', name: 'Chain Rings', description: 'Simulated chain rings (format: <min>-<max>)', type: types_1.CyclingModeProperyType.String, validation: '', default: '36-52', condition: (s) => s.simulation },
344
+ { key: 'cassetteRings', name: 'Cassette', description: 'Simulated cassette (format: <min>-<max>)', type: types_1.CyclingModeProperyType.String, validation: '', default: '11-30', condition: (s) => s.simulation },
345
+ ]
346
+ };
350
347
  exports.default = SmartTrainerCyclingMode;
@@ -0,0 +1,44 @@
1
+ import ICyclingMode, { CyclingModeProperyType, IncyclistBikeData, UpdateRequest } from './types';
2
+ import PowerBasedCyclingModeBase from './power-base';
3
+ import { IncyclistDeviceAdapter } from '../types/adapter';
4
+ export type ERGEvent = {
5
+ rpmUpdated?: boolean;
6
+ gearUpdated?: boolean;
7
+ starting?: boolean;
8
+ tsStart?: number;
9
+ };
10
+ export default class ERGCyclingMode extends PowerBasedCyclingModeBase implements ICyclingMode {
11
+ protected static config: {
12
+ isERG: boolean;
13
+ name: string;
14
+ description: string;
15
+ properties: ({
16
+ key: string;
17
+ name: string;
18
+ description: string;
19
+ type: CyclingModeProperyType;
20
+ options: string[];
21
+ default: string;
22
+ min?: undefined;
23
+ max?: undefined;
24
+ } | {
25
+ key: string;
26
+ name: string;
27
+ description: string;
28
+ type: CyclingModeProperyType;
29
+ default: number;
30
+ min: number;
31
+ max: number;
32
+ options?: undefined;
33
+ })[];
34
+ };
35
+ prevRequest: UpdateRequest;
36
+ hasBikeUpdate: boolean;
37
+ chain: number[];
38
+ cassette: number[];
39
+ event: ERGEvent;
40
+ constructor(adapter: IncyclistDeviceAdapter, props?: any);
41
+ getBikeInitRequest(): UpdateRequest;
42
+ sendBikeUpdate(request: UpdateRequest): UpdateRequest;
43
+ updateData(bikeData: IncyclistBikeData): any;
44
+ }
@@ -3,17 +3,9 @@ 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("../../../../modes/cycling-mode");
7
- const power_base_1 = __importDefault(require("../../../../modes/power-base"));
6
+ const types_1 = require("./types");
7
+ const power_base_1 = __importDefault(require("./power-base"));
8
8
  const MIN_SPEED = 10;
9
- const config = {
10
- name: "ERG",
11
- description: "Calculates speed based on power and slope. Power is either set by a workout",
12
- properties: [
13
- { key: 'bikeType', name: 'Bike Type', description: '', type: cycling_mode_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain', 'Triathlon'], default: 'Race' },
14
- { key: 'startPower', name: 'Starting Power', description: 'Initial power in Watts at start of training', type: cycling_mode_1.CyclingModeProperyType.Integer, default: 50, min: 25, max: 800 },
15
- ]
16
- };
17
9
  class ERGCyclingMode extends power_base_1.default {
18
10
  constructor(adapter, props) {
19
11
  super(adapter, props);
@@ -21,18 +13,6 @@ class ERGCyclingMode extends power_base_1.default {
21
13
  this.event = {};
22
14
  this.initLogger('ERGMode');
23
15
  }
24
- getName() {
25
- return config.name;
26
- }
27
- getDescription() {
28
- return config.description;
29
- }
30
- getProperties() {
31
- return config.properties;
32
- }
33
- getProperty(name) {
34
- return config.properties.find(p => p.name === name);
35
- }
36
16
  getBikeInitRequest() {
37
17
  const startPower = this.getSetting('startPower');
38
18
  return { targetPower: startPower };
@@ -131,6 +111,7 @@ class ERGCyclingMode extends power_base_1.default {
131
111
  data.time = 0;
132
112
  data.heartrate = bikeData.heartrate;
133
113
  data.isPedalling = bikeData.isPedalling;
114
+ this.prevUpdateTS = Date.now();
134
115
  }
135
116
  catch (err) {
136
117
  this.logger.logEvent({ message: 'error', fn: 'updateData()', error: err.message || err });
@@ -140,5 +121,13 @@ class ERGCyclingMode extends power_base_1.default {
140
121
  return data;
141
122
  }
142
123
  }
143
- ERGCyclingMode.isERG = true;
124
+ ERGCyclingMode.config = {
125
+ isERG: true,
126
+ name: "ERG",
127
+ description: "Calculates speed based on power and slope. Power is either set by a workout",
128
+ properties: [
129
+ { key: 'bikeType', name: 'Bike Type', description: '', type: types_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain', 'Triathlon'], default: 'Race' },
130
+ { key: 'startPower', name: 'Starting Power', description: 'Initial power in Watts at start of training', type: types_1.CyclingModeProperyType.Integer, default: 50, min: 25, max: 800 },
131
+ ]
132
+ };
144
133
  exports.default = ERGCyclingMode;