incyclist-devices 1.4.0 → 1.4.3

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.
@@ -52,10 +52,13 @@ export default interface CyclingMode {
52
52
  setSetting(name: string, value: any): void;
53
53
  getSetting(name: string): any;
54
54
  getSettings(): Settings;
55
+ setModeProperty(name: string, value: any): void;
56
+ getModeProperty(name: string): any;
55
57
  }
56
58
  export declare class CyclingModeBase implements CyclingMode {
57
59
  adapter: Device;
58
60
  settings: Settings;
61
+ properties: Settings;
59
62
  constructor(adapter: Device, props?: any);
60
63
  setAdapter(adapter: Device): void;
61
64
  getBikeInitRequest(): UpdateRequest;
@@ -69,4 +72,6 @@ export declare class CyclingModeBase implements CyclingMode {
69
72
  setSetting(name: string, value: any): void;
70
73
  getSetting(name: string): any;
71
74
  getSettings(): Settings;
75
+ setModeProperty(name: string, value: any): void;
76
+ getModeProperty(name: string): any;
72
77
  }
@@ -13,6 +13,7 @@ var CyclingModeProperyType;
13
13
  class CyclingModeBase {
14
14
  constructor(adapter, props) {
15
15
  this.settings = {};
16
+ this.properties = {};
16
17
  if (!adapter)
17
18
  throw new Error('IllegalArgument: adapter is null');
18
19
  this.setAdapter(adapter);
@@ -62,5 +63,17 @@ class CyclingModeBase {
62
63
  getSettings() {
63
64
  return this.settings;
64
65
  }
66
+ setModeProperty(name, value) {
67
+ this.properties[name] = value;
68
+ }
69
+ getModeProperty(name) {
70
+ const res = this.properties[name];
71
+ if (res !== undefined)
72
+ return res;
73
+ const prop = this.getProperties().find(p => p.key === name);
74
+ if (prop && prop.default !== undefined)
75
+ return prop.default;
76
+ return undefined;
77
+ }
65
78
  }
66
79
  exports.CyclingModeBase = CyclingModeBase;
@@ -575,8 +575,6 @@ class AntProtocol extends DeviceProtocol_1.default {
575
575
  const channel = channelsUsed + idx;
576
576
  const { sensor } = i;
577
577
  i.device.setChannel(channel);
578
- if (process.env.DEBUG)
579
- console.log('~~~~Ant: attach', channel, i.device.getID());
580
578
  sensor.attach(channel, i.device.getID());
581
579
  this.sensors.attached.push(i);
582
580
  });
@@ -176,8 +176,9 @@ class AntFEAdapter extends AntAdapter_1.default {
176
176
  });
177
177
  return __awaiter(this, void 0, void 0, function* () {
178
178
  yield _super.start.call(this, props);
179
- this.logger.logEvent({ message: 'start()' });
180
- const args = props || {};
179
+ this.logger.logEvent({ message: 'start()', props });
180
+ const opts = props || {};
181
+ const { args } = opts;
181
182
  return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
182
183
  if (this.ignoreHrm && this.ignoreBike && this.ignorePower) {
183
184
  this.logger.logEvent({ message: 'start() not done: bike disabled' });
@@ -1,6 +1,7 @@
1
1
  import { EventLogger } from 'gd-eventlog';
2
2
  import CyclingMode from '../CyclingMode';
3
3
  import DeviceAdapterBase, { Bike, DeviceAdapter } from '../Device';
4
+ import { User } from '../types/user';
4
5
  interface DaumAdapter {
5
6
  getCurrentBikeData(): Promise<any>;
6
7
  }
@@ -18,7 +19,7 @@ export default class DaumAdapterBase extends DeviceAdapterBase implements Device
18
19
  iv: any;
19
20
  logger: EventLogger;
20
21
  cyclingMode: CyclingMode;
21
- userSettings: any;
22
+ userSettings: User;
22
23
  bikeSettings: any;
23
24
  tsPrevData: number;
24
25
  adapterTime: number;
@@ -29,7 +30,7 @@ export default class DaumAdapterBase extends DeviceAdapterBase implements Device
29
30
  getSupportedCyclingModes(): Array<any>;
30
31
  getCyclingMode(): CyclingMode;
31
32
  getDefaultCyclingMode(): CyclingMode;
32
- setUserSettings(userSettings: any): void;
33
+ setUserSettings(userSettings: User): void;
33
34
  setBikeSettings(bikeSettings: any): void;
34
35
  getWeight(): number;
35
36
  getCurrentBikeData(): Promise<any>;
@@ -11,7 +11,7 @@ const config = {
11
11
  description: "Calculates speed based on power and slope. Power is either set by workout or calculated based on gear and cadence",
12
12
  properties: [
13
13
  { key: 'bikeType', name: 'Bike Type', description: '', type: CyclingMode_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain', 'Triathlon'], default: 'Race' },
14
- { key: 'startPower', name: 'Starting Power', description: 'Initial power in Watts at start of raining', type: CyclingMode_1.CyclingModeProperyType.Integer, default: 50, min: 25, max: 800 },
14
+ { key: 'startPower', name: 'Starting Power', description: 'Initial power in Watts at start of training', type: CyclingMode_1.CyclingModeProperyType.Integer, default: 50, min: 25, max: 800 },
15
15
  ]
16
16
  };
17
17
  class ERGCyclingMode extends CyclingMode_1.CyclingModeBase {
@@ -13,7 +13,7 @@ const config = {
13
13
  description: "Calculates power based on speed and slope.",
14
14
  properties: [
15
15
  { key: 'bikeType', name: 'Bike Type', description: '', type: CyclingMode_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain', 'Triathlon'], default: 'Race' },
16
- { key: 'startPower', name: 'Starting Power', description: 'Initial power in Watts at start of raining', type: CyclingMode_1.CyclingModeProperyType.Integer, default: 50 },
16
+ { key: 'startPower', name: 'Starting Power', description: 'Initial power in Watts at start of training', type: CyclingMode_1.CyclingModeProperyType.Integer, default: 50 },
17
17
  { key: 'minPower', name: 'Minimum Power', description: 'Minimum power in declines', type: CyclingMode_1.CyclingModeProperyType.Integer, default: 50 },
18
18
  { key: 'simulation', name: 'Simulate ', description: 'Simulate ', type: CyclingMode_1.CyclingModeProperyType.Boolean, default: false },
19
19
  { key: 'chainRings', name: 'Chain Rings', description: 'Simulated chain rings (format: <min>-<max>)', type: CyclingMode_1.CyclingModeProperyType.String, validation: '', default: '36-52', condition: (s) => s.simulation },
@@ -83,7 +83,7 @@ class DaumClassicAdapter extends DaumAdapter_1.default {
83
83
  return __awaiter(this, void 0, void 0, function* () {
84
84
  this.logger.logEvent({ message: 'start()', props });
85
85
  const opts = props || {};
86
- const person = props;
86
+ const { user } = props;
87
87
  this.initData();
88
88
  let startState = {};
89
89
  return (0, utils_1.runWithRetries)(() => __awaiter(this, void 0, void 0, function* () {
@@ -96,7 +96,7 @@ class DaumClassicAdapter extends DaumAdapter_1.default {
96
96
  startState.setProg = true;
97
97
  }
98
98
  if (!startState.setPerson) {
99
- yield this.getBike().setPerson({ person });
99
+ yield this.getBike().setPerson(user);
100
100
  startState.setPerson = true;
101
101
  }
102
102
  if (!startState.startProg) {
@@ -156,7 +156,7 @@ class DaumClassicProtocol extends DeviceProtocol_1.default {
156
156
  return;
157
157
  scan.scanning = true;
158
158
  return device.check()
159
- .then(() => {
159
+ .then(() => __awaiter(this, void 0, void 0, function* () {
160
160
  if (this.state.stopScanning)
161
161
  return;
162
162
  const { onDeviceFound, onScanFinished, id } = opts;
@@ -166,10 +166,16 @@ class DaumClassicProtocol extends DeviceProtocol_1.default {
166
166
  if (onScanFinished) {
167
167
  onScanFinished(id);
168
168
  }
169
+ try {
170
+ yield device.getBike().saveClose();
171
+ }
172
+ catch (err) {
173
+ this.logger.logEvent({ message: 'scanCommand warning: Could not close port', error: err.message });
174
+ }
169
175
  clearInterval(scan.iv);
170
176
  scan.iv = undefined;
171
177
  scan.scanning = false;
172
- })
178
+ }))
173
179
  .catch(() => {
174
180
  scan.scanning = false;
175
181
  });
@@ -1,5 +1,6 @@
1
1
  import { EventLogger } from 'gd-eventlog';
2
2
  import { Queue } from '../../utils';
3
+ import { User } from '../../types/user';
3
4
  declare type SuccessCallbackFn = (data: any) => void;
4
5
  declare type ErrorCallbackFn = (status: number, error: any) => void;
5
6
  interface CommandInstructions {
@@ -32,7 +33,7 @@ export default class Daum8008 {
32
33
  getType(): string;
33
34
  getPort(): string;
34
35
  isConnected(): boolean;
35
- setUser(user: any, callback: any): void;
36
+ setUser(user: User, callback: any): void;
36
37
  getUserWeight(): number;
37
38
  getBikeWeight(): any;
38
39
  connect(): void;
@@ -54,7 +55,7 @@ export default class Daum8008 {
54
55
  stopProg(bikeNo?: number): Promise<unknown>;
55
56
  setProg(progNo?: number, bikeNo?: number): Promise<unknown>;
56
57
  setBikeType(bikeType: any, bikeNo?: number): Promise<unknown>;
57
- setPerson(user?: any, bikeNo?: number): Promise<unknown>;
58
+ setPerson(user?: User, bikeNo?: number): Promise<unknown>;
58
59
  runData(bikeNo?: number): Promise<unknown>;
59
60
  setGear(gear: any, bikeNo?: number): Promise<unknown>;
60
61
  setPower(power: any, bikeNo?: number): Promise<unknown>;
@@ -15,8 +15,8 @@ class Daum8008 {
15
15
  this.portName = opts.port || process.env.COM_PORT;
16
16
  this.settings = opts.settings || {};
17
17
  this.bikeData = {
18
- userWeight: 75,
19
- bikeWeight: 10,
18
+ userWeight: utils_1.DEFAULT_USER_WEIGHT,
19
+ bikeWeight: utils_1.DEFAULT_BIKE_WEIGHT,
20
20
  maxPower: 800
21
21
  };
22
22
  this.sp = undefined;
@@ -45,7 +45,8 @@ class Daum8008 {
45
45
  }
46
46
  setUser(user, callback) {
47
47
  this.logger.logEvent({ message: "setUser()", user });
48
- this.settings.user = user || {};
48
+ if (user)
49
+ this.settings.user = user;
49
50
  var cb = callback || nop;
50
51
  cb(200, user);
51
52
  }
@@ -361,7 +362,7 @@ class Daum8008 {
361
362
  });
362
363
  }
363
364
  setPerson(user = {}, bikeNo = 0) {
364
- const age = user.age !== undefined ? user.age : (0, utils_1.getAge)(user.birthday);
365
+ const age = user.age !== undefined ? user.age : utils_1.DEFAULT_AGE;
365
366
  const gender = (0, utils_1.getGender)(user.sex);
366
367
  const length = (0, utils_1.getLength)(user.length);
367
368
  const maxPower = this.settings.maxPower === undefined ? 800 : this.settings.maxPower;
@@ -1,6 +1,8 @@
1
- export declare function getCockpit(c: any): "Cardio" | "Fitness" | "Vita De Luxe" | "8008" | "8080" | "Therapie" | "8008 TRS Pro" | "8008 TRS3" | "Unknown";
1
+ export declare const DEFAULT_AGE = 30;
2
+ export declare const DEFAULT_USER_WEIGHT = 75;
3
+ export declare const DEFAULT_BIKE_WEIGHT = 10;
4
+ export declare function getCockpit(c: any): "Cardio" | "Fitness" | "Vita De Luxe" | "8008" | "8008 TRS" | "8080" | "Therapie" | "8008 TRS Pro" | "8008 TRS3" | "Unknown";
2
5
  export declare function getBikeType(type: any): 1 | 0;
3
- export declare function getAge(birthday: any): number;
4
6
  export declare function getGender(sex: any): 1 | 2;
5
7
  export declare function getLength(length: any): number;
6
8
  export declare function getWeight(weight?: any): number;
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Float32ToIntArray = exports.Float32ToHex = exports.hexstr = exports.buildError = exports.parseRunData = exports.getWeight = exports.getLength = exports.getGender = exports.getAge = exports.getBikeType = exports.getCockpit = void 0;
3
+ exports.Float32ToIntArray = exports.Float32ToHex = exports.hexstr = exports.buildError = exports.parseRunData = exports.getWeight = exports.getLength = exports.getGender = exports.getBikeType = exports.getCockpit = exports.DEFAULT_BIKE_WEIGHT = exports.DEFAULT_USER_WEIGHT = exports.DEFAULT_AGE = void 0;
4
+ exports.DEFAULT_AGE = 30;
5
+ exports.DEFAULT_USER_WEIGHT = 75;
6
+ exports.DEFAULT_BIKE_WEIGHT = 10;
4
7
  function getCockpit(c) {
5
8
  switch (c) {
6
9
  case 10:
@@ -11,6 +14,8 @@ function getCockpit(c) {
11
14
  return "Vita De Luxe";
12
15
  case 40:
13
16
  return "8008";
17
+ case 0x2A:
18
+ return "8008 TRS";
14
19
  case 50:
15
20
  return "8080";
16
21
  case 60:
@@ -39,21 +44,6 @@ function getBikeType(type) {
39
44
  }
40
45
  }
41
46
  exports.getBikeType = getBikeType;
42
- function getAge(birthday) {
43
- if (birthday === undefined) {
44
- return 30;
45
- }
46
- try {
47
- const bd = new Date(birthday);
48
- const ageDifMs = Date.now() - bd.getTime();
49
- var ageDate = new Date(ageDifMs);
50
- return Math.abs(ageDate.getUTCFullYear() - 1970);
51
- }
52
- catch (error) {
53
- return 30;
54
- }
55
- }
56
- exports.getAge = getAge;
57
47
  function getGender(sex) {
58
48
  if (sex === undefined)
59
49
  return 2;
@@ -0,0 +1,14 @@
1
+ import CyclingMode, { CyclingModeProperty, IncyclistBikeData, Settings, UpdateRequest } from "../../CyclingMode";
2
+ import DaumAdapter from "../DaumAdapter";
3
+ import PowerMeterCyclingMode from "../PowerMeterCyclingMode";
4
+ export default class DaumClassicCyclingMode extends PowerMeterCyclingMode implements CyclingMode {
5
+ constructor(adapter: DaumAdapter, props?: Settings);
6
+ getName(): string;
7
+ getDescription(): string;
8
+ getProperties(): CyclingModeProperty[];
9
+ getProperty(name: string): CyclingModeProperty;
10
+ getBikeInitRequest(): UpdateRequest;
11
+ getSettings(): Settings;
12
+ getSetting(name: string): any;
13
+ updateData(data: IncyclistBikeData): IncyclistBikeData;
14
+ }
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const gd_eventlog_1 = require("gd-eventlog");
7
+ const CyclingMode_1 = require("../../CyclingMode");
8
+ const PowerMeterCyclingMode_1 = __importDefault(require("../PowerMeterCyclingMode"));
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: CyclingMode_1.CyclingModeProperyType.SingleSelect, options: ['Race', 'Mountain'], default: 'Race' },
14
+ ]
15
+ };
16
+ class DaumClassicCyclingMode extends PowerMeterCyclingMode_1.default {
17
+ constructor(adapter, props) {
18
+ super(adapter, props);
19
+ this.logger = adapter ? adapter.logger : undefined;
20
+ if (!this.logger)
21
+ this.logger = new gd_eventlog_1.EventLogger('DaumClassic');
22
+ this.setModeProperty('eppSupport', true);
23
+ this.setModeProperty('setPersonSupport', true);
24
+ }
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
+ getBikeInitRequest() {
38
+ return {};
39
+ }
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
+ updateData(data) {
51
+ try {
52
+ const prevData = this.data || {};
53
+ const prevRequest = this.prevRequest || {};
54
+ const bikeData = JSON.parse(JSON.stringify(data));
55
+ let power = data.power || 0;
56
+ let speed = data.speed || 0;
57
+ let slope = (prevData.slope !== undefined ? prevData.slope : prevRequest.slope || 0);
58
+ let distanceBike = data.distanceInternal || 0;
59
+ let distancePrev = prevData.distanceInternal || 0;
60
+ let distanceInternal = distanceBike;
61
+ let ts = Date.now();
62
+ if (!bikeData.pedalRpm || bikeData.isPedalling === false) {
63
+ speed = 0;
64
+ power = 0;
65
+ }
66
+ if (distanceBike < distancePrev) {
67
+ let v = speed / 3.6;
68
+ let duration = this.prevUpdateTS === 0 ? 0 : ((ts - this.prevUpdateTS) / 1000);
69
+ distanceInternal = distancePrev + Math.round(v * duration);
70
+ }
71
+ data.speed = parseFloat(speed.toFixed(1));
72
+ data.power = Math.round(power);
73
+ data.distanceInternal = Math.round(distanceInternal);
74
+ data.distance = Math.round(distanceInternal / 100);
75
+ data.slope = slope;
76
+ this.logger.logEvent({ message: "updateData result", data, bikeData, prevRequest: {}, prevSpeed: prevData.speed });
77
+ this.data = JSON.parse(JSON.stringify(data));
78
+ this.prevUpdateTS = ts;
79
+ }
80
+ catch (err) {
81
+ this.logger.logEvent({ message: 'error', fn: 'updateData()', error: err.message || err });
82
+ }
83
+ return data;
84
+ }
85
+ }
86
+ exports.default = DaumClassicCyclingMode;
@@ -1,3 +1,4 @@
1
+ import { Route } from '../../types/route';
1
2
  import DaumAdapter from '../DaumAdapter';
2
3
  export default class DaumPremiumDevice extends DaumAdapter {
3
4
  static NAME: string;
@@ -5,7 +6,9 @@ export default class DaumPremiumDevice extends DaumAdapter {
5
6
  getName(): string;
6
7
  getPort(): any;
7
8
  getInterface(): any;
9
+ getSupportedCyclingModes(): Array<any>;
8
10
  check(): Promise<unknown>;
11
+ initClassic(route: Route): Promise<boolean>;
9
12
  start(props: any): Promise<unknown>;
10
13
  getCurrentBikeData(): Promise<any>;
11
14
  }
@@ -15,6 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const gd_eventlog_1 = require("gd-eventlog");
16
16
  const utils_1 = require("../../utils");
17
17
  const DaumAdapter_1 = __importDefault(require("../DaumAdapter"));
18
+ const DaumClassicCyclingMode_1 = __importDefault(require("./DaumClassicCyclingMode"));
18
19
  const PROTOCOL_NAME = "Daum Premium";
19
20
  class DaumPremiumDevice extends DaumAdapter_1.default {
20
21
  constructor(protocol, bike) {
@@ -38,6 +39,11 @@ class DaumPremiumDevice extends DaumAdapter_1.default {
38
39
  getInterface() {
39
40
  return this.bike.getInterface();
40
41
  }
42
+ getSupportedCyclingModes() {
43
+ const supported = super.getSupportedCyclingModes();
44
+ supported.push(DaumClassicCyclingMode_1.default);
45
+ return supported;
46
+ }
41
47
  check() {
42
48
  var info = {};
43
49
  return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
@@ -56,10 +62,28 @@ class DaumPremiumDevice extends DaumAdapter_1.default {
56
62
  }
57
63
  }));
58
64
  }
65
+ initClassic(route) {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ if (!route)
68
+ return true;
69
+ let res;
70
+ const bikeType = this.getCyclingMode().getSetting('bikeType');
71
+ res = yield this.bike.programUpload(bikeType, route);
72
+ if (!res)
73
+ return false;
74
+ res = yield this.bike.startProgram(route.programId);
75
+ if (!res)
76
+ return false;
77
+ });
78
+ }
59
79
  start(props) {
60
80
  return __awaiter(this, void 0, void 0, function* () {
61
- this.logger.logEvent({ message: 'start()', props });
81
+ this.logger.logEvent({ message: 'start()' });
82
+ console.log('~~~setPersonSupport:', this.getCyclingMode().getModeProperty('setPersonSupport'));
83
+ console.log('~~~eppSupport:', this.getCyclingMode().getModeProperty('eppSupport'));
62
84
  const opts = props || {};
85
+ const user = opts.user || this.userSettings;
86
+ const route = opts.route;
63
87
  var info = {};
64
88
  this.initData();
65
89
  return (0, utils_1.runWithRetries)(() => __awaiter(this, void 0, void 0, function* () {
@@ -75,10 +99,23 @@ class DaumPremiumDevice extends DaumAdapter_1.default {
75
99
  if (!info.version) {
76
100
  info.version = yield this.bike.getProtocolVersion();
77
101
  }
102
+ if (!info.init && this.getCyclingMode().getModeProperty('setPersonSupport')) {
103
+ info.init = yield this.initClassic(route);
104
+ }
105
+ else {
106
+ info.init = true;
107
+ }
108
+ if (!info.person && this.getCyclingMode().getModeProperty('eppSupport')) {
109
+ info.person = yield this.bike.setPerson(user);
110
+ }
111
+ else {
112
+ info.person = true;
113
+ }
78
114
  const gear = yield this.bike.setGear(this.data.gear || (opts.gear || 10));
79
115
  return gear;
80
116
  }
81
117
  catch (err) {
118
+ console.error(err);
82
119
  throw (new Error(`could not start device, reason:${err.message}`));
83
120
  }
84
121
  }), 5, 1000)
@@ -177,7 +177,7 @@ class DaumPremiumProtocol extends DeviceProtocol_1.default {
177
177
  return;
178
178
  scan.scanning = true;
179
179
  device.check()
180
- .then(() => {
180
+ .then(() => __awaiter(this, void 0, void 0, function* () {
181
181
  if (this.state.stopScanning)
182
182
  return;
183
183
  const { onDeviceFound, onScanFinished, id } = opts;
@@ -187,10 +187,16 @@ class DaumPremiumProtocol extends DeviceProtocol_1.default {
187
187
  if (onScanFinished) {
188
188
  onScanFinished(id);
189
189
  }
190
+ try {
191
+ yield device.getBike().saveClose();
192
+ }
193
+ catch (err) {
194
+ this.logger.logEvent({ message: 'scanCommand warning: Could not close port', error: err.message });
195
+ }
190
196
  clearInterval(scan.iv);
191
197
  scan.iv = undefined;
192
198
  scan.scanning = false;
193
- })
199
+ }))
194
200
  .catch(() => {
195
201
  scan.scanning = false;
196
202
  });
@@ -1,5 +1,9 @@
1
+ /// <reference types="node" />
2
+ import { ReservedCommands, BikeType } from './utils';
1
3
  import { Queue } from '../../utils';
2
4
  import { EventLogger } from 'gd-eventlog';
5
+ import { User } from "../../types/user";
6
+ import { Route } from "../../types/route";
3
7
  declare class Daum8i {
4
8
  portName: string;
5
9
  logger: EventLogger;
@@ -63,7 +67,7 @@ declare class Daum8i {
63
67
  sendDaum8iCommand(command: any, queryType: any, payload: any): Promise<unknown>;
64
68
  sendACK(): void;
65
69
  sendNAK(): void;
66
- sendReservedDaum8iCommand(command: any, cmdType: any, data: any): Promise<any[]>;
70
+ sendReservedDaum8iCommand(command: ReservedCommands, cmdType: any, data?: Buffer): Promise<any[]>;
67
71
  getProtocolVersion(): Promise<string>;
68
72
  getDashboardVersion(): Promise<unknown>;
69
73
  getDeviceType(): Promise<any>;
@@ -89,7 +93,13 @@ declare class Daum8i {
89
93
  setSlope(slope: any): void;
90
94
  setPower(power: any): Promise<number>;
91
95
  getPower(power: any): Promise<number>;
92
- setPerson(person: any): Promise<any[]>;
96
+ setPerson(person: User): Promise<boolean>;
97
+ programUploadInit(): Promise<boolean>;
98
+ programUploadStart(bikeType: BikeType, route: Route): Promise<Uint8Array>;
99
+ programUploadSendBlock(epp: Uint8Array, offset: number): Promise<boolean>;
100
+ programUploadDone(): Promise<boolean>;
101
+ programUpload(bikeType: BikeType, route: Route): Promise<boolean>;
102
+ startProgram(programId?: number): Promise<boolean>;
93
103
  setGear(gear: any): Promise<number>;
94
104
  getGear(): Promise<number>;
95
105
  }
@@ -25,6 +25,7 @@ const TIMEOUT_START = 15000;
25
25
  const OPEN_TIMEOUT = 1000;
26
26
  const DAUM_PREMIUM_DEFAULT_PORT = 51955;
27
27
  const DAUM_PREMIUM_DEFAULT_HOST = '127.0.0.1';
28
+ const MAX_DATA_BLOCK_SIZE = 512;
28
29
  var __SerialPort = undefined;
29
30
  var net = undefined;
30
31
  const DEBUG_LOGGER = {
@@ -166,21 +167,18 @@ class Daum8i {
166
167
  const tTimeout = Date.now() + TIMEOUT_START;
167
168
  const iv = setInterval(() => {
168
169
  if (this.state.error !== undefined) {
169
- console.log('~~ -> error');
170
170
  clearInterval(iv);
171
171
  this.forceClose();
172
172
  reject(this.state.error);
173
173
  this.state = { opened: false, closed: true, busy: false };
174
174
  }
175
175
  else if (this.isConnected()) {
176
- console.log('~~ -> connected');
177
176
  this.state.connecting = false;
178
177
  resolve(true);
179
178
  clearInterval(iv);
180
179
  }
181
180
  else {
182
181
  if (Date.now() > tTimeout) {
183
- console.log('~~ -> timeout');
184
182
  this.state.connecting = false;
185
183
  this.forceClose();
186
184
  clearInterval(iv);
@@ -281,7 +279,6 @@ class Daum8i {
281
279
  });
282
280
  }
283
281
  forceClose(updateState = false) {
284
- console.log('~~~ forceClose', updateState);
285
282
  const sp = this.sp;
286
283
  if (!this.sp)
287
284
  return;
@@ -578,20 +575,23 @@ class Daum8i {
578
575
  this.logger.logEvent({ message: "sendCommand:sending NAK", port });
579
576
  }
580
577
  sendReservedDaum8iCommand(command, cmdType, data) {
581
- let cmdData = [];
582
- const key = (0, utils_1.getReservedCommandKey)(command);
583
- (0, utils_1.append)(cmdData, (0, utils_1.Int16ToIntArray)(key));
578
+ let buffer;
584
579
  if (data !== undefined && data.length > 0) {
585
- (0, utils_1.append)(cmdData, (0, utils_1.Int16ToIntArray)(data.length));
586
- (0, utils_1.append)(cmdData, data);
580
+ buffer = Buffer.alloc(data.length + 4);
581
+ buffer.writeInt16LE(command, 0);
582
+ buffer.writeUInt16LE(data.length, 2);
583
+ data.copy(buffer, 4);
587
584
  }
588
585
  else {
589
- (0, utils_1.append)(cmdData, (0, utils_1.Int16ToIntArray)(0));
586
+ buffer = Buffer.alloc(4);
587
+ buffer.writeInt16LE(command, 0);
588
+ buffer.writeUInt16LE(0, 2);
590
589
  }
590
+ const cmdData = Uint8Array.from(buffer);
591
591
  return this.sendDaum8iCommand('M70', cmdType, (0, utils_1.bin2esc)(cmdData))
592
- .then((resData) => {
592
+ .then((res) => {
593
+ const resData = Uint8Array.from(res, x => x.charCodeAt(0));
593
594
  const cmd = (0, utils_1.esc2bin)(resData);
594
- cmd.splice(0, 4);
595
595
  return cmd;
596
596
  });
597
597
  }
@@ -710,7 +710,99 @@ class Daum8i {
710
710
  });
711
711
  }
712
712
  setPerson(person) {
713
- return this.sendReservedDaum8iCommand('PERSON_SET', 'BF', person.getData());
713
+ return this.sendReservedDaum8iCommand(utils_1.ReservedCommands.PERSON_SET, 'BF', (0, utils_1.getPersonData)(person))
714
+ .then((res) => {
715
+ const buffer = Buffer.from(res);
716
+ return buffer.readInt16LE(0) === utils_1.ReservedCommands.PERSON_SET;
717
+ });
718
+ }
719
+ programUploadInit() {
720
+ return this.sendReservedDaum8iCommand(utils_1.ReservedCommands.PROGRAM_LIST_BEGIN, 'BF')
721
+ .then((res) => {
722
+ const buffer = Buffer.from(res);
723
+ return buffer.readInt16LE(0) === utils_1.ReservedCommands.PROGRAM_LIST_BEGIN;
724
+ });
725
+ }
726
+ programUploadStart(bikeType, route) {
727
+ const payload = Buffer.alloc(40);
728
+ const epp = (0, utils_1.routeToEpp)(route);
729
+ payload.writeInt32LE(0, 0);
730
+ payload.writeInt8(bikeType, 4);
731
+ payload.writeInt8(bikeType, 5);
732
+ payload.writeInt16LE(0, 6);
733
+ payload.writeInt32LE(0, 8);
734
+ payload.writeInt32LE(0, 12);
735
+ payload.writeFloatLE(0, 16);
736
+ payload.writeFloatLE(0, 20);
737
+ payload.writeInt16LE(0, 24);
738
+ payload.writeInt16LE(0, 26);
739
+ payload.writeInt16LE(0, 28);
740
+ payload.writeInt16LE(0, 30);
741
+ payload.writeInt32LE(7, 32);
742
+ payload.writeInt32LE(epp.length, 36);
743
+ return this.sendReservedDaum8iCommand(utils_1.ReservedCommands.PROGRAM_LIST_NEW_PROGRAM, 'BF', payload)
744
+ .then((res) => {
745
+ const buffer = Buffer.from(res);
746
+ if (buffer.readInt16LE(0) === utils_1.ReservedCommands.PROGRAM_LIST_NEW_PROGRAM) {
747
+ return epp;
748
+ }
749
+ throw new Error('Illegal Response');
750
+ });
751
+ }
752
+ programUploadSendBlock(epp, offset) {
753
+ const remaining = epp.length - offset;
754
+ if (remaining <= 0)
755
+ return Promise.resolve(true);
756
+ const size = remaining > MAX_DATA_BLOCK_SIZE ? MAX_DATA_BLOCK_SIZE : remaining;
757
+ const payload = Buffer.alloc(size + 8);
758
+ payload.writeInt32LE(size, 0);
759
+ payload.writeInt32LE(offset, 4);
760
+ const chunk = Buffer.from(epp.slice(offset, offset + size));
761
+ chunk.copy(payload, 8);
762
+ return this.sendReservedDaum8iCommand(utils_1.ReservedCommands.PROGRAM_LIST_CONTINUE_PROGRAM, 'BF', payload)
763
+ .then((res) => {
764
+ const buffer = Buffer.from(res);
765
+ let success = buffer.readInt16LE(0) === utils_1.ReservedCommands.PROGRAM_LIST_CONTINUE_PROGRAM;
766
+ success = success && (buffer.readInt16LE(2) === 1);
767
+ success = success && (buffer.readInt8(4) === 1);
768
+ if (!success)
769
+ throw new Error('Illegal Response');
770
+ return success;
771
+ });
772
+ }
773
+ programUploadDone() {
774
+ return this.sendReservedDaum8iCommand(utils_1.ReservedCommands.PROGRAM_LIST_END, 'BF')
775
+ .then((res) => {
776
+ const buffer = Buffer.from(res);
777
+ return buffer.readInt16LE(0) === utils_1.ReservedCommands.PROGRAM_LIST_END;
778
+ });
779
+ }
780
+ programUpload(bikeType, route) {
781
+ return __awaiter(this, void 0, void 0, function* () {
782
+ yield this.programUploadInit();
783
+ const epp = yield this.programUploadStart(bikeType, route);
784
+ let success = true;
785
+ let done = false;
786
+ let offset = 0;
787
+ while (success && !done) {
788
+ success = yield this.programUploadSendBlock(epp, offset);
789
+ offset += MAX_DATA_BLOCK_SIZE;
790
+ done = offset >= epp.length;
791
+ }
792
+ if (done) {
793
+ return yield this.programUploadDone();
794
+ }
795
+ return false;
796
+ });
797
+ }
798
+ startProgram(programId = 1) {
799
+ const payload = Buffer.alloc(2);
800
+ payload.writeInt16LE(programId, 0);
801
+ return this.sendReservedDaum8iCommand(utils_1.ReservedCommands.PROGRAM_LIST_START, 'BF', payload)
802
+ .then((res) => {
803
+ const buffer = Buffer.from(res);
804
+ return buffer.readInt16LE(0) === utils_1.ReservedCommands.PROGRAM_LIST_START;
805
+ });
714
806
  }
715
807
  setGear(gear) {
716
808
  return this.sendDaum8iCommand('M71', 'BF', `${gear}`)
@@ -38,18 +38,15 @@ class TcpSocketPort {
38
38
  });
39
39
  }
40
40
  this.logger.logEvent({ message: 'opening', id: this.id, retry });
41
- console.log('~~opening socket', this.id);
42
41
  this.socket.connect(this.port, this.host);
43
42
  }
44
43
  catch (err) {
45
44
  this.logger.logEvent({ message: 'opening error', id: this.id, error: err.message, stack: err.stack });
46
- console.log('~~open socket error', this.id, err);
47
45
  this.emit('error', err);
48
46
  }
49
47
  }
50
48
  close() {
51
49
  this.logger.logEvent({ message: 'closing', id: this.id });
52
- console.log('~~closing socket', this.id);
53
50
  this.isOpen = false;
54
51
  this.isClosed = true;
55
52
  try {
@@ -67,7 +64,6 @@ class TcpSocketPort {
67
64
  if (this.isOpen)
68
65
  return;
69
66
  this.logger.logEvent({ message: 'timeout', id: this.id });
70
- console.log('~~socket timeout', this.id);
71
67
  try {
72
68
  this.socket.end();
73
69
  }
@@ -78,14 +74,12 @@ class TcpSocketPort {
78
74
  }
79
75
  onConnect() {
80
76
  this.logger.logEvent({ message: 'connected', id: this.id });
81
- console.log('~~socket connected', this.id);
82
77
  this.isOpen = true;
83
78
  this.isClosed = false;
84
79
  this.emit('open');
85
80
  }
86
81
  onError(err) {
87
82
  this.logger.logEvent({ message: 'error', error: err.message });
88
- console.log('~~socket error', this.id, err);
89
83
  if (this.callbacks['error'])
90
84
  this.callbacks['error'](err);
91
85
  }
@@ -1,3 +1,6 @@
1
+ /// <reference types="node" />
2
+ import { Route } from "../../types/route";
3
+ import { User } from "../../types/user";
1
4
  export declare function bin2esc(arr: any): any[];
2
5
  export declare function esc2bin(arr: any): any[];
3
6
  export declare function checkSum(cmdArr: any, payload: any): string;
@@ -14,7 +17,33 @@ export declare function Float32ToHex(float32: any): any;
14
17
  export declare function Float32ToIntArray(float32: any): any[];
15
18
  export declare function Int16ToIntArray(int16: any): any[];
16
19
  export declare function Int32ToIntArray(int32: any): any[];
17
- export declare function getReservedCommandKey(cmdStr: any): any;
20
+ export declare enum ReservedCommands {
21
+ RESULT_RESET = 0,
22
+ RESULT_GET = 1,
23
+ NETRACE_START = 2,
24
+ NETRACE_STOP = 3,
25
+ NETRACE_USERNAME = 4,
26
+ NETRACE_USERDATA = 5,
27
+ PERSON_GET = 6,
28
+ PERSON_SET = 7,
29
+ PROGRAM_LIST_BEGIN = 8,
30
+ PROGRAM_LIST_NEW_PROGRAM = 9,
31
+ PROGRAM_LIST_CONTINUE_PROGRAM = 10,
32
+ PROGRAM_LIST_END = 11,
33
+ PROGRAM_LIST_START = 12,
34
+ RELAX_START = 12,
35
+ RELAX_STOP = 14,
36
+ RELAX_GET_DATA = 15,
37
+ KEY_PRESSED = 16,
38
+ PROGRAM_CONTROL = 17
39
+ }
40
+ export declare enum BikeType {
41
+ ALLROUND = 0,
42
+ RACE = 1,
43
+ MOUNTAIN = 2
44
+ }
45
+ export declare function getBikeType(bikeTypeStr?: string): BikeType;
46
+ export declare function routeToEpp(route: Route, date?: Date): Uint8Array;
18
47
  export declare function parseTrainingData(payload: any): {
19
48
  time: number;
20
49
  heartrate: number;
@@ -30,3 +59,4 @@ export declare function parseTrainingData(payload: any): {
30
59
  deviceState: number;
31
60
  speedStatus: string;
32
61
  };
62
+ export declare function getPersonData(user: User): Buffer;
@@ -1,6 +1,12 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseTrainingData = exports.getReservedCommandKey = 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;
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
+ const user_1 = require("../../types/user");
8
+ const utils_1 = require("../classic/utils");
9
+ const win32filetime_1 = __importDefault(require("win32filetime"));
4
10
  const sum = (arr) => arr.reduce((a, b) => a + b, 0);
5
11
  function bin2esc(arr) {
6
12
  if (arr === undefined) {
@@ -114,7 +120,7 @@ function getMessageData(command) {
114
120
  }
115
121
  exports.getMessageData = getMessageData;
116
122
  function hexstr(arr, start, len) {
117
- const isArr = Array.isArray(arr);
123
+ const isArr = Array.isArray(arr) || arr instanceof Uint8Array;
118
124
  if (!arr)
119
125
  return '';
120
126
  var str = "";
@@ -211,30 +217,95 @@ function Int32ToIntArray(int32) {
211
217
  return arr;
212
218
  }
213
219
  exports.Int32ToIntArray = Int32ToIntArray;
214
- const __commands = {
215
- RESULT_RESET: 0,
216
- RESULT_GET: 1,
217
- NETRACE_START: 2,
218
- NETRACE_STOP: 3,
219
- NETRACE_USERNAME: 4,
220
- NETRACE_USERDATA: 5,
221
- PERSON_GET: 6,
222
- PERSON_SET: 7,
223
- PROGRAM_LIST_BEGIN: 8,
224
- PROGRAM_LIST_NEW_PROGRAM: 9,
225
- PROGRAM_LIST_CONTINUE_PROGRAM: 10,
226
- PROGRAM_LIST_END: 11,
227
- PROGRAM_LIST_START: 12,
228
- RELAX_START: 12,
229
- RELAX_STOP: 14,
230
- RELAX_GET_DATA: 0xF,
231
- KEY_PRESSED: 0x10,
232
- PROGRAM_CONTROL: 17
233
- };
234
- function getReservedCommandKey(cmdStr) {
235
- return __commands[cmdStr];
220
+ var ReservedCommands;
221
+ (function (ReservedCommands) {
222
+ ReservedCommands[ReservedCommands["RESULT_RESET"] = 0] = "RESULT_RESET";
223
+ ReservedCommands[ReservedCommands["RESULT_GET"] = 1] = "RESULT_GET";
224
+ ReservedCommands[ReservedCommands["NETRACE_START"] = 2] = "NETRACE_START";
225
+ ReservedCommands[ReservedCommands["NETRACE_STOP"] = 3] = "NETRACE_STOP";
226
+ ReservedCommands[ReservedCommands["NETRACE_USERNAME"] = 4] = "NETRACE_USERNAME";
227
+ ReservedCommands[ReservedCommands["NETRACE_USERDATA"] = 5] = "NETRACE_USERDATA";
228
+ ReservedCommands[ReservedCommands["PERSON_GET"] = 6] = "PERSON_GET";
229
+ ReservedCommands[ReservedCommands["PERSON_SET"] = 7] = "PERSON_SET";
230
+ ReservedCommands[ReservedCommands["PROGRAM_LIST_BEGIN"] = 8] = "PROGRAM_LIST_BEGIN";
231
+ ReservedCommands[ReservedCommands["PROGRAM_LIST_NEW_PROGRAM"] = 9] = "PROGRAM_LIST_NEW_PROGRAM";
232
+ ReservedCommands[ReservedCommands["PROGRAM_LIST_CONTINUE_PROGRAM"] = 10] = "PROGRAM_LIST_CONTINUE_PROGRAM";
233
+ ReservedCommands[ReservedCommands["PROGRAM_LIST_END"] = 11] = "PROGRAM_LIST_END";
234
+ ReservedCommands[ReservedCommands["PROGRAM_LIST_START"] = 12] = "PROGRAM_LIST_START";
235
+ ReservedCommands[ReservedCommands["RELAX_START"] = 12] = "RELAX_START";
236
+ ReservedCommands[ReservedCommands["RELAX_STOP"] = 14] = "RELAX_STOP";
237
+ ReservedCommands[ReservedCommands["RELAX_GET_DATA"] = 15] = "RELAX_GET_DATA";
238
+ ReservedCommands[ReservedCommands["KEY_PRESSED"] = 16] = "KEY_PRESSED";
239
+ ReservedCommands[ReservedCommands["PROGRAM_CONTROL"] = 17] = "PROGRAM_CONTROL";
240
+ })(ReservedCommands = exports.ReservedCommands || (exports.ReservedCommands = {}));
241
+ var BikeType;
242
+ (function (BikeType) {
243
+ BikeType[BikeType["ALLROUND"] = 0] = "ALLROUND";
244
+ BikeType[BikeType["RACE"] = 1] = "RACE";
245
+ BikeType[BikeType["MOUNTAIN"] = 2] = "MOUNTAIN";
246
+ })(BikeType = exports.BikeType || (exports.BikeType = {}));
247
+ function getBikeType(bikeTypeStr) {
248
+ if (bikeTypeStr === undefined || bikeTypeStr === null)
249
+ return BikeType.RACE;
250
+ if (bikeTypeStr.toLowerCase() === 'mountain')
251
+ return BikeType.MOUNTAIN;
252
+ return BikeType.RACE;
253
+ }
254
+ exports.getBikeType = getBikeType;
255
+ function routeToEpp(route, date) {
256
+ const buffer = Buffer.alloc(376 + route.points.length * 12);
257
+ const fileTime = win32filetime_1.default.fromUnix(date ? date : Date.now());
258
+ let offset = 0;
259
+ const name = route.name || '';
260
+ const description = route.description || '';
261
+ const minElevation = Math.min(...route.points.map(p => p.elevation));
262
+ const maxElevation = Math.max(...route.points.map(p => p.elevation));
263
+ const sampleRate = route.points.length !== 0 ? route.totalDistance / route.points.length : 0;
264
+ buffer.writeUInt32LE(fileTime.low, offset);
265
+ offset += 4;
266
+ buffer.writeUInt32LE(fileTime.high, offset);
267
+ offset += 4;
268
+ buffer.write(name, offset, name.length, 'ascii');
269
+ offset += 64;
270
+ buffer.write(description, offset, description.length, 'ascii');
271
+ offset += 256;
272
+ buffer.writeInt32LE(0x10, offset);
273
+ offset += 4;
274
+ buffer.writeInt32LE(0x0, offset);
275
+ offset += 4;
276
+ buffer.writeInt32LE(minElevation, offset);
277
+ offset += 4;
278
+ buffer.writeInt32LE(maxElevation, offset);
279
+ offset += 4;
280
+ buffer.writeInt32LE(route.points.length, offset);
281
+ offset += 4;
282
+ buffer.writeInt32LE(sampleRate, offset);
283
+ offset += 4;
284
+ buffer.writeInt32LE(0x01, offset);
285
+ offset += 4;
286
+ buffer.writeInt32LE(0x0, offset);
287
+ offset += 4;
288
+ buffer.writeInt16LE(0x0, offset);
289
+ offset += 2;
290
+ buffer.writeInt16LE(0x0, offset);
291
+ offset += 2;
292
+ buffer.writeInt32LE(0x0, offset);
293
+ offset += 4;
294
+ buffer.writeInt32LE(0x0, offset);
295
+ offset += 4;
296
+ buffer.writeInt32LE(0x0, offset);
297
+ offset += 4;
298
+ route.points.forEach(p => {
299
+ buffer.writeUInt32LE(sampleRate, offset);
300
+ offset += 4;
301
+ buffer.writeFloatLE(p.elevation, offset);
302
+ offset += 4;
303
+ buffer.writeFloatLE(0, offset);
304
+ offset += 4;
305
+ });
306
+ return new Uint8Array(buffer);
236
307
  }
237
- exports.getReservedCommandKey = getReservedCommandKey;
308
+ exports.routeToEpp = routeToEpp;
238
309
  function parseTrainingData(payload) {
239
310
  const GS = 0x1D;
240
311
  const speedVals = ['ok', 'too low', 'too high'];
@@ -258,3 +329,47 @@ function parseTrainingData(payload) {
258
329
  return data;
259
330
  }
260
331
  exports.parseTrainingData = parseTrainingData;
332
+ function getPersonData(user) {
333
+ const buffer = Buffer.alloc(136);
334
+ let offset = 0;
335
+ for (let i = 0; i < 4; i++) {
336
+ buffer.writeInt32LE(0, offset);
337
+ offset += 4;
338
+ buffer.writeFloatLE(-100, offset);
339
+ offset += 4;
340
+ buffer.writeFloatLE(0, offset);
341
+ offset += 4;
342
+ buffer.writeFloatLE(0, offset);
343
+ offset += 4;
344
+ buffer.writeUInt16LE(0, offset);
345
+ offset += 2;
346
+ buffer.writeUInt16LE(0, offset);
347
+ offset += 2;
348
+ buffer.writeUInt16LE(0, offset);
349
+ offset += 2;
350
+ buffer.writeUInt16LE(0, offset);
351
+ offset += 2;
352
+ buffer.writeUInt8(0, offset);
353
+ offset += 1;
354
+ buffer.writeUInt8(0, offset);
355
+ offset += 1;
356
+ buffer.writeUInt8(0, offset);
357
+ offset += 1;
358
+ buffer.writeUInt8(0, offset);
359
+ offset += 1;
360
+ }
361
+ buffer.writeInt32LE(user.sex === user_1.Gender.FEMALE ? 2 : 1, offset);
362
+ offset += 4;
363
+ buffer.writeInt32LE(user.age !== undefined ? user.age : utils_1.DEFAULT_AGE, offset);
364
+ offset += 4;
365
+ buffer.writeInt32LE(user.length !== undefined ? user.length : 180, offset);
366
+ offset += 4;
367
+ buffer.writeFloatLE(user.weight !== undefined ? user.weight : utils_1.DEFAULT_USER_WEIGHT, offset);
368
+ offset += 4;
369
+ buffer.writeFloatLE(0, offset);
370
+ offset += 4;
371
+ buffer.writeUInt32LE(0, offset);
372
+ offset += 4;
373
+ return buffer;
374
+ }
375
+ exports.getPersonData = getPersonData;
@@ -0,0 +1,21 @@
1
+ export declare type Point = {
2
+ lat?: number;
3
+ lng?: number;
4
+ elevation?: number;
5
+ distance: number;
6
+ slope?: number;
7
+ };
8
+ export declare enum RouteType {
9
+ FREE_RIDE = "free ride",
10
+ FOLLOW_ROUTE = "follow route",
11
+ VIDEO = "video"
12
+ }
13
+ export declare type Route = {
14
+ programId: number;
15
+ points: Point[];
16
+ type: string;
17
+ name?: string;
18
+ description?: string;
19
+ lapMode: boolean;
20
+ totalDistance: number;
21
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RouteType = void 0;
4
+ var RouteType;
5
+ (function (RouteType) {
6
+ RouteType["FREE_RIDE"] = "free ride";
7
+ RouteType["FOLLOW_ROUTE"] = "follow route";
8
+ RouteType["VIDEO"] = "video";
9
+ })(RouteType = exports.RouteType || (exports.RouteType = {}));
@@ -0,0 +1,11 @@
1
+ export declare enum Gender {
2
+ MALE = "M",
3
+ FEMALE = "F",
4
+ OTHERS = "o"
5
+ }
6
+ export declare type User = {
7
+ weight?: number;
8
+ length?: number;
9
+ age?: number;
10
+ sex?: Gender;
11
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Gender = void 0;
4
+ var Gender;
5
+ (function (Gender) {
6
+ Gender["MALE"] = "M";
7
+ Gender["FEMALE"] = "F";
8
+ Gender["OTHERS"] = "o";
9
+ })(Gender = exports.Gender || (exports.Gender = {}));
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "incyclist-devices",
3
- "version": "1.4.0",
3
+ "version": "1.4.3",
4
4
  "dependencies": {
5
5
  "@serialport/parser-byte-length": "^9.0.1",
6
6
  "@serialport/parser-delimiter": "^9.0.1",
7
7
  "@types/serialport": "^8.0.1",
8
- "gd-ant-plus": "^0.0.33"
8
+ "gd-ant-plus": "^0.0.33",
9
+ "win32filetime": "^1.0.2"
9
10
  },
10
11
  "peerDependencies": {
11
12
  "gd-eventlog": "^0.1.22"