incyclist-devices 1.5.38 → 2.0.0-beta.1

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 (251) hide show
  1. package/README.MD +0 -0
  2. package/lib/adapters.d.ts +6 -0
  3. package/lib/adapters.js +30 -0
  4. package/lib/antv2/adapter-factory.d.ts +20 -10
  5. package/lib/antv2/adapter-factory.js +49 -33
  6. package/lib/antv2/adapter.d.ts +64 -0
  7. package/lib/antv2/adapter.js +299 -0
  8. package/lib/antv2/ant-interface.d.ts +11 -9
  9. package/lib/antv2/ant-interface.js +15 -11
  10. package/lib/antv2/fe/adapter.d.ts +25 -0
  11. package/lib/antv2/{fe.js → fe/adapter.js} +48 -72
  12. package/lib/antv2/fe/index.d.ts +2 -0
  13. package/lib/antv2/fe/index.js +7 -0
  14. package/lib/antv2/hr/adapter.d.ts +14 -0
  15. package/lib/antv2/hr/adapter.js +73 -0
  16. package/lib/antv2/hr/index.d.ts +2 -0
  17. package/lib/antv2/hr/index.js +7 -0
  18. package/lib/antv2/index.d.ts +7 -0
  19. package/lib/antv2/index.js +20 -0
  20. package/lib/antv2/modes/ant-fe-adv-st-mode.d.ts +9 -0
  21. package/lib/{ant/antfe → antv2/modes}/ant-fe-adv-st-mode.js +1 -1
  22. package/lib/antv2/modes/ant-fe-erg-mode.d.ts +6 -0
  23. package/lib/{ant/antfe → antv2/modes}/ant-fe-erg-mode.js +1 -1
  24. package/lib/antv2/modes/ant-fe-st-mode.d.ts +5 -0
  25. package/lib/{ant/antfe → antv2/modes}/ant-fe-st-mode.js +1 -1
  26. package/lib/antv2/pwr/adapter.d.ts +22 -0
  27. package/lib/antv2/{pwr.js → pwr/adapter.js} +38 -76
  28. package/lib/antv2/pwr/index.d.ts +2 -0
  29. package/lib/antv2/pwr/index.js +7 -0
  30. package/lib/antv2/types.d.ts +19 -0
  31. package/lib/antv2/types.js +2 -0
  32. package/lib/antv2/utils.d.ts +1 -0
  33. package/lib/antv2/utils.js +181 -0
  34. package/lib/base/adpater.d.ts +56 -0
  35. package/lib/base/adpater.js +144 -0
  36. package/lib/ble/adapter-factory.d.ts +31 -0
  37. package/lib/ble/adapter-factory.js +96 -0
  38. package/lib/ble/adapter.d.ts +41 -0
  39. package/lib/ble/adapter.js +188 -0
  40. package/lib/ble/{ble-device.d.ts → ble-comms.d.ts} +9 -4
  41. package/lib/ble/{ble-device.js → ble-comms.js} +23 -11
  42. package/lib/ble/ble-interface.d.ts +15 -24
  43. package/lib/ble/ble-interface.js +32 -137
  44. package/lib/ble/ble-peripheral.d.ts +3 -3
  45. package/lib/ble/ble-peripheral.js +14 -14
  46. package/lib/ble/ble.d.ts +9 -81
  47. package/lib/ble/ble.js +1 -39
  48. package/lib/ble/consts.d.ts +2 -0
  49. package/lib/ble/consts.js +3 -1
  50. package/lib/ble/cp/adapter.d.ts +23 -0
  51. package/lib/ble/cp/adapter.js +124 -0
  52. package/lib/ble/cp/comm.d.ts +28 -0
  53. package/lib/ble/cp/comm.js +140 -0
  54. package/lib/ble/cp/index.d.ts +4 -0
  55. package/lib/ble/cp/index.js +10 -0
  56. package/lib/ble/cp/types.d.ts +13 -0
  57. package/lib/ble/cp/types.js +2 -0
  58. package/lib/ble/elite/adapter.d.ts +20 -0
  59. package/lib/ble/elite/adapter.js +127 -0
  60. package/lib/ble/elite/comms.d.ts +28 -0
  61. package/lib/ble/elite/comms.js +139 -0
  62. package/lib/ble/elite/index.d.ts +3 -0
  63. package/lib/ble/elite/index.js +10 -0
  64. package/lib/ble/fm/adapter.d.ts +21 -0
  65. package/lib/ble/fm/adapter.js +190 -0
  66. package/lib/ble/fm/comms.d.ts +50 -0
  67. package/lib/ble/{fm.js → fm/comms.js} +3 -224
  68. package/lib/ble/fm/consts.d.ts +6 -0
  69. package/lib/ble/fm/consts.js +9 -0
  70. package/lib/ble/fm/index.d.ts +5 -0
  71. package/lib/ble/fm/index.js +13 -0
  72. package/lib/ble/fm/types.d.ts +25 -0
  73. package/lib/ble/fm/types.js +2 -0
  74. package/lib/ble/hr/adapter.d.ts +17 -0
  75. package/lib/ble/hr/adapter.js +62 -0
  76. package/lib/ble/hr/comm.d.ts +15 -0
  77. package/lib/ble/hr/comm.js +52 -0
  78. package/lib/ble/hr/index.d.ts +4 -0
  79. package/lib/ble/hr/index.js +10 -0
  80. package/lib/ble/hr/types.d.ts +5 -0
  81. package/lib/ble/hr/types.js +2 -0
  82. package/lib/ble/index.d.ts +8 -0
  83. package/lib/ble/index.js +26 -0
  84. package/lib/ble/tacx/adapter.d.ts +10 -0
  85. package/lib/ble/tacx/adapter.js +93 -0
  86. package/lib/ble/{tacx.d.ts → tacx/comms.d.ts} +6 -38
  87. package/lib/ble/{tacx.js → tacx/comms.js} +13 -112
  88. package/lib/ble/tacx/index.d.ts +4 -0
  89. package/lib/ble/tacx/index.js +10 -0
  90. package/lib/ble/tacx/types.d.ts +25 -0
  91. package/lib/ble/tacx/types.js +2 -0
  92. package/lib/ble/types.d.ts +101 -0
  93. package/lib/ble/types.js +19 -0
  94. package/lib/ble/utils.d.ts +7 -0
  95. package/lib/ble/utils.js +95 -0
  96. package/lib/ble/wahoo/adapter.d.ts +9 -0
  97. package/lib/ble/wahoo/adapter.js +93 -0
  98. package/lib/ble/{wahoo-kickr.d.ts → wahoo/comms.d.ts} +5 -39
  99. package/lib/ble/{wahoo-kickr.js → wahoo/comms.js} +14 -112
  100. package/lib/ble/wahoo/index.d.ts +4 -0
  101. package/lib/ble/wahoo/index.js +10 -0
  102. package/lib/ble/wahoo/types.d.ts +19 -0
  103. package/lib/ble/wahoo/types.js +2 -0
  104. package/lib/device.d.ts +0 -94
  105. package/lib/device.js +0 -76
  106. package/lib/index.d.ts +12 -0
  107. package/lib/index.js +38 -0
  108. package/lib/interfaces.d.ts +6 -0
  109. package/lib/interfaces.js +23 -0
  110. package/lib/{ble → modes}/ble-erg-mode.d.ts +4 -4
  111. package/lib/{ble → modes}/ble-erg-mode.js +2 -2
  112. package/lib/{ble → modes}/ble-st-mode.d.ts +3 -3
  113. package/lib/{ble → modes}/ble-st-mode.js +1 -1
  114. package/lib/{cycling-mode.d.ts → modes/cycling-mode.d.ts} +8 -8
  115. package/lib/modes/power-base.d.ts +3 -3
  116. package/lib/modes/power-base.js +4 -4
  117. package/lib/modes/power-meter.d.ts +3 -3
  118. package/lib/modes/simulator.d.ts +2 -2
  119. package/lib/modes/simulator.js +1 -1
  120. package/lib/serial/adapter-factory.d.ts +12 -0
  121. package/lib/serial/adapter-factory.js +30 -0
  122. package/lib/serial/adapter.d.ts +16 -0
  123. package/lib/serial/adapter.js +42 -0
  124. package/lib/serial/bindings/tcp.d.ts +44 -0
  125. package/lib/serial/bindings/tcp.js +270 -0
  126. package/lib/serial/comm.d.ts +7 -0
  127. package/lib/serial/comm.js +2 -0
  128. package/lib/{daum → serial/daum}/DaumAdapter.d.ts +13 -22
  129. package/lib/{daum → serial/daum}/DaumAdapter.js +44 -90
  130. package/lib/{daum → serial/daum}/DaumPowerMeterCyclingMode.d.ts +2 -2
  131. package/lib/{daum → serial/daum}/DaumPowerMeterCyclingMode.js +1 -1
  132. package/lib/{daum → serial/daum}/ERGCyclingMode.d.ts +3 -3
  133. package/lib/{daum → serial/daum}/ERGCyclingMode.js +3 -3
  134. package/lib/{daum → serial/daum}/SmartTrainerCyclingMode.d.ts +3 -3
  135. package/lib/{daum → serial/daum}/SmartTrainerCyclingMode.js +4 -3
  136. package/lib/serial/daum/classic/adapter.d.ts +29 -0
  137. package/lib/{daum/classic/DaumClassicAdapter.js → serial/daum/classic/adapter.js} +77 -50
  138. package/lib/{daum/classic/bike.d.ts → serial/daum/classic/comms.d.ts} +14 -16
  139. package/lib/{daum/classic/bike.js → serial/daum/classic/comms.js} +68 -152
  140. package/lib/serial/daum/classic/mock.d.ts +96 -0
  141. package/lib/serial/daum/classic/mock.js +365 -0
  142. package/lib/{daum/classic/DaumClassicCyclingMode.d.ts → serial/daum/classic/modes/daum-classic.d.ts} +3 -3
  143. package/lib/{daum/classic/DaumClassicCyclingMode.js → serial/daum/classic/modes/daum-classic.js} +2 -2
  144. package/lib/{daum → serial/daum}/classic/utils.d.ts +1 -1
  145. package/lib/serial/daum/premium/adapter.d.ts +24 -0
  146. package/lib/{daum/premium/DaumPremiumAdapter.js → serial/daum/premium/adapter.js} +99 -46
  147. package/lib/{daum/premium/bike.d.ts → serial/daum/premium/comms.d.ts} +26 -54
  148. package/lib/{daum/premium/bike.js → serial/daum/premium/comms.js} +208 -420
  149. package/lib/serial/daum/premium/mock.d.ts +75 -0
  150. package/lib/serial/daum/premium/mock.js +290 -0
  151. package/lib/{daum/premium/DaumClassicCyclingMode.d.ts → serial/daum/premium/modes/daum-classic.d.ts} +3 -3
  152. package/lib/{daum/premium/DaumClassicCyclingMode.js → serial/daum/premium/modes/daum-classic.js} +2 -2
  153. package/lib/serial/daum/premium/types.d.ts +12 -0
  154. package/lib/serial/daum/premium/types.js +2 -0
  155. package/lib/{daum → serial/daum}/premium/utils.d.ts +8 -11
  156. package/lib/{daum → serial/daum}/premium/utils.js +22 -63
  157. package/lib/serial/index.d.ts +9 -0
  158. package/lib/serial/index.js +49 -0
  159. package/lib/{kettler → serial/kettler}/comms.d.ts +8 -6
  160. package/lib/{kettler → serial/kettler}/comms.js +71 -32
  161. package/lib/{kettler → serial/kettler}/ergo-racer/adapter.d.ts +13 -24
  162. package/lib/{kettler → serial/kettler}/ergo-racer/adapter.js +87 -130
  163. package/lib/serial/kettler/ergo-racer/mock.d.ts +66 -0
  164. package/lib/serial/kettler/ergo-racer/mock.js +216 -0
  165. package/lib/{kettler/ergo-racer/ERGCyclingMode.d.ts → serial/kettler/ergo-racer/modes/erg.d.ts} +4 -4
  166. package/lib/{kettler/ergo-racer/ERGCyclingMode.js → serial/kettler/ergo-racer/modes/erg.js} +2 -2
  167. package/lib/serial/serial-interface.d.ts +58 -0
  168. package/lib/serial/serial-interface.js +283 -0
  169. package/lib/simulator/Simulator.d.ts +10 -25
  170. package/lib/simulator/Simulator.js +19 -83
  171. package/lib/types/adapter.d.ts +32 -0
  172. package/lib/types/adapter.js +2 -0
  173. package/lib/types/capabilities.d.ts +8 -0
  174. package/lib/types/capabilities.js +12 -0
  175. package/lib/types/data.d.ts +12 -0
  176. package/lib/types/data.js +2 -0
  177. package/lib/types/device.d.ts +29 -0
  178. package/lib/types/device.js +11 -0
  179. package/lib/types/interface.d.ts +14 -0
  180. package/lib/types/interface.js +2 -0
  181. package/lib/types/route.d.ts +2 -2
  182. package/lib/types/user.d.ts +1 -1
  183. package/lib/{utils.d.ts → utils/utils.d.ts} +1 -0
  184. package/lib/{utils.js → utils/utils.js} +5 -1
  185. package/package.json +15 -11
  186. package/lib/DeviceSupport.d.ts +0 -36
  187. package/lib/DeviceSupport.js +0 -82
  188. package/lib/ant/AntAdapter.d.ts +0 -50
  189. package/lib/ant/AntAdapter.js +0 -109
  190. package/lib/ant/AntScanner.d.ts +0 -60
  191. package/lib/ant/AntScanner.js +0 -651
  192. package/lib/ant/antfe/AntFEAdapter.d.ts +0 -83
  193. package/lib/ant/antfe/AntFEAdapter.js +0 -652
  194. package/lib/ant/antfe/ant-fe-adv-st-mode.d.ts +0 -9
  195. package/lib/ant/antfe/ant-fe-erg-mode.d.ts +0 -6
  196. package/lib/ant/antfe/ant-fe-st-mode.d.ts +0 -5
  197. package/lib/ant/anthrm/AntHrmAdapter.d.ts +0 -16
  198. package/lib/ant/anthrm/AntHrmAdapter.js +0 -130
  199. package/lib/ant/antpwr/pwr-adapter.d.ts +0 -49
  200. package/lib/ant/antpwr/pwr-adapter.js +0 -251
  201. package/lib/ant/utils.d.ts +0 -1
  202. package/lib/ant/utils.js +0 -23
  203. package/lib/antv2/AntAdapter.d.ts +0 -48
  204. package/lib/antv2/AntAdapter.js +0 -104
  205. package/lib/antv2/ant-device.d.ts +0 -59
  206. package/lib/antv2/ant-device.js +0 -161
  207. package/lib/antv2/fe.d.ts +0 -32
  208. package/lib/antv2/hr.d.ts +0 -18
  209. package/lib/antv2/hr.js +0 -102
  210. package/lib/antv2/incyclist-protocol.d.ts +0 -37
  211. package/lib/antv2/incyclist-protocol.js +0 -126
  212. package/lib/antv2/pwr.d.ts +0 -28
  213. package/lib/ble/elite.d.ts +0 -90
  214. package/lib/ble/elite.js +0 -322
  215. package/lib/ble/fm.d.ts +0 -125
  216. package/lib/ble/hrm.d.ts +0 -48
  217. package/lib/ble/hrm.js +0 -134
  218. package/lib/ble/incyclist-protocol.d.ts +0 -31
  219. package/lib/ble/incyclist-protocol.js +0 -153
  220. package/lib/ble/pwr.d.ts +0 -89
  221. package/lib/ble/pwr.js +0 -322
  222. package/lib/daum/classic/DaumClassicAdapter.d.ts +0 -28
  223. package/lib/daum/classic/DaumClassicProtocol.d.ts +0 -27
  224. package/lib/daum/classic/DaumClassicProtocol.js +0 -185
  225. package/lib/daum/premium/DaumPremiumAdapter.d.ts +0 -16
  226. package/lib/daum/premium/DaumPremiumProtocol.d.ts +0 -32
  227. package/lib/daum/premium/DaumPremiumProtocol.js +0 -207
  228. package/lib/daum/premium/tcpserial.d.ts +0 -33
  229. package/lib/daum/premium/tcpserial.js +0 -123
  230. package/lib/kettler/ergo-racer/protocol.d.ts +0 -41
  231. package/lib/kettler/ergo-racer/protocol.js +0 -203
  232. package/lib/protocol.d.ts +0 -74
  233. package/lib/protocol.js +0 -41
  234. package/lib/registry.d.ts +0 -8
  235. package/lib/registry.js +0 -33
  236. package/lib/serialport/bindings/tcp.d.ts +0 -20
  237. package/lib/serialport/bindings/tcp.js +0 -33
  238. package/lib/serialport/index.d.ts +0 -2
  239. package/lib/serialport/index.js +0 -29
  240. package/lib/serialport/serialport.d.ts +0 -29
  241. package/lib/serialport/serialport.js +0 -87
  242. /package/lib/antv2/{ant-binding.d.ts → binding.d.ts} +0 -0
  243. /package/lib/antv2/{ant-binding.js → binding.js} +0 -0
  244. /package/lib/{cycling-mode.js → modes/cycling-mode.js} +0 -0
  245. /package/lib/{daum → serial/daum}/classic/utils.js +0 -0
  246. /package/lib/{daum → serial/daum}/constants.d.ts +0 -0
  247. /package/lib/{daum → serial/daum}/constants.js +0 -0
  248. /package/lib/{serialport.d.ts → serial/serialport.d.ts} +0 -0
  249. /package/lib/{serialport.js → serial/serialport.js} +0 -0
  250. /package/lib/{calculations.d.ts → utils/calculations.d.ts} +0 -0
  251. /package/lib/{calculations.js → utils/calculations.js} +0 -0
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const gd_eventlog_1 = require("gd-eventlog");
16
+ const power_meter_1 = __importDefault(require("../../modes/power-meter"));
17
+ const ble_st_mode_1 = __importDefault(require("../../modes/ble-st-mode"));
18
+ const ble_erg_mode_1 = __importDefault(require("../../modes/ble-erg-mode"));
19
+ const comms_1 = __importDefault(require("./comms"));
20
+ const adapter_1 = require("../adapter");
21
+ const consts_1 = require("./consts");
22
+ const utils_1 = require("../../utils/utils");
23
+ const capabilities_1 = require("../../types/capabilities");
24
+ class BleFmAdapter extends adapter_1.BleControllableAdapter {
25
+ constructor(settings, props) {
26
+ super(settings, props);
27
+ this.distanceInternal = 0;
28
+ this.logger = new gd_eventlog_1.EventLogger('BLE-FM');
29
+ const { id, address, name } = settings;
30
+ const logger = this.logger;
31
+ const ble = this.ble;
32
+ this.device = new comms_1.default({ id, address, name, ble, logger });
33
+ this.capabilities = [
34
+ capabilities_1.IncyclistCapability.Power, capabilities_1.IncyclistCapability.Speed, capabilities_1.IncyclistCapability.Cadence,
35
+ capabilities_1.IncyclistCapability.Control
36
+ ];
37
+ }
38
+ isSame(device) {
39
+ if (!(device instanceof BleFmAdapter))
40
+ return false;
41
+ return this.isEqual(device.settings);
42
+ }
43
+ getProfile() {
44
+ return 'Smart Trainer';
45
+ }
46
+ getName() {
47
+ return `${this.device.name}`;
48
+ }
49
+ getDisplayName() {
50
+ return this.getName();
51
+ }
52
+ getSupportedCyclingModes() {
53
+ return [ble_st_mode_1.default, ble_erg_mode_1.default, power_meter_1.default];
54
+ }
55
+ getDefaultCyclingMode() {
56
+ return new ble_st_mode_1.default(this);
57
+ }
58
+ onDeviceData(deviceData) {
59
+ super.onDeviceData(deviceData);
60
+ if (!this.started || this.paused || !this.onDataFn)
61
+ return;
62
+ this.logger.logEvent({ message: 'onDeviceData', data: deviceData });
63
+ if (!this.lastUpdate || (Date.now() - this.lastUpdate) > this.updateFrequency) {
64
+ let incyclistData = this.mapData(deviceData);
65
+ incyclistData = this.getCyclingMode().updateData(incyclistData);
66
+ this.data = this.transformData(incyclistData);
67
+ this.onDataFn(this.data);
68
+ this.lastUpdate = Date.now();
69
+ }
70
+ }
71
+ mapData(deviceData) {
72
+ const data = {
73
+ isPedalling: false,
74
+ power: 0,
75
+ pedalRpm: undefined,
76
+ speed: 0,
77
+ heartrate: 0,
78
+ distanceInternal: 0,
79
+ slope: undefined,
80
+ time: undefined
81
+ };
82
+ data.power = (deviceData.instantaneousPower !== undefined ? deviceData.instantaneousPower : data.power);
83
+ data.pedalRpm = (deviceData.cadence !== undefined ? deviceData.cadence : data.pedalRpm);
84
+ data.time = (deviceData.time !== undefined ? deviceData.time : data.time);
85
+ data.isPedalling = data.pedalRpm > 0 || (data.pedalRpm === undefined && data.power > 0);
86
+ return data;
87
+ }
88
+ transformData(bikeData) {
89
+ if (bikeData === undefined)
90
+ return;
91
+ let distance = 0;
92
+ if (this.distanceInternal !== undefined && bikeData.distanceInternal !== undefined) {
93
+ distance = Math.round(bikeData.distanceInternal - this.distanceInternal);
94
+ }
95
+ if (bikeData.distanceInternal !== undefined)
96
+ this.distanceInternal = bikeData.distanceInternal;
97
+ let data = {
98
+ speed: bikeData.speed,
99
+ slope: bikeData.slope,
100
+ power: bikeData.power !== undefined ? Math.round(bikeData.power) : undefined,
101
+ cadence: bikeData.pedalRpm !== undefined ? Math.round(bikeData.pedalRpm) : undefined,
102
+ distance,
103
+ timestamp: Date.now()
104
+ };
105
+ return data;
106
+ }
107
+ start(props = {}) {
108
+ return __awaiter(this, void 0, void 0, function* () {
109
+ if (this.started)
110
+ return true;
111
+ this.logger.logEvent({ message: 'start requested', protocol: this.getProtocolName(), props });
112
+ const { restart } = props;
113
+ if (!restart && this.ble.isScanning())
114
+ yield this.ble.stopScan();
115
+ try {
116
+ let bleDevice;
117
+ if (!this.device || !restart) {
118
+ bleDevice = (yield this.ble.connectDevice(this.device));
119
+ this.device = bleDevice;
120
+ }
121
+ else
122
+ bleDevice = this.device;
123
+ if (bleDevice) {
124
+ bleDevice.setLogger(this.logger);
125
+ const mode = this.getCyclingMode();
126
+ if (mode && mode.getSetting('bikeType')) {
127
+ const bikeType = mode.getSetting('bikeType').toLowerCase();
128
+ bleDevice.setCrr(consts_1.cRR);
129
+ switch (bikeType) {
130
+ case 'race':
131
+ bleDevice.setCw(consts_1.cwABike.race);
132
+ break;
133
+ case 'triathlon':
134
+ bleDevice.setCw(consts_1.cwABike.triathlon);
135
+ break;
136
+ case 'mountain':
137
+ bleDevice.setCw(consts_1.cwABike.mountain);
138
+ break;
139
+ }
140
+ }
141
+ let hasControl = yield bleDevice.requestControl();
142
+ if (!hasControl) {
143
+ let retry = 1;
144
+ while (!hasControl && retry < 3) {
145
+ yield (0, utils_1.sleep)(1000);
146
+ hasControl = yield bleDevice.requestControl();
147
+ retry++;
148
+ }
149
+ }
150
+ if (!hasControl)
151
+ throw new Error('could not establish control');
152
+ const startRequest = this.getCyclingMode().getBikeInitRequest();
153
+ yield this.sendUpdate(startRequest);
154
+ bleDevice.on('data', (data) => {
155
+ this.onDeviceData(data);
156
+ });
157
+ bleDevice.on('disconnected', this.emit);
158
+ if (bleDevice.isHrm() && !this.hasCapability(capabilities_1.IncyclistCapability.HeartRate)) {
159
+ this.capabilities.push(capabilities_1.IncyclistCapability.HeartRate);
160
+ }
161
+ this.resetData();
162
+ this.stopped = false;
163
+ this.started = true;
164
+ this.paused = false;
165
+ return true;
166
+ }
167
+ }
168
+ catch (err) {
169
+ this.logger.logEvent({ message: 'start result: error', error: err.message, profile: this.getProfile() });
170
+ throw new Error(`could not start device, reason:${err.message}`);
171
+ }
172
+ });
173
+ }
174
+ sendUpdate(request) {
175
+ return __awaiter(this, void 0, void 0, function* () {
176
+ if (this.paused || !this.device)
177
+ return;
178
+ const update = this.getCyclingMode().sendBikeUpdate(request);
179
+ this.logger.logEvent({ message: 'send bike update requested', profile: this.getProfile(), update, request });
180
+ const device = this.device;
181
+ if (update.slope !== undefined) {
182
+ yield device.setSlope(update.slope);
183
+ }
184
+ if (update.targetPower !== undefined) {
185
+ yield device.setTargetPower(update.targetPower);
186
+ }
187
+ });
188
+ }
189
+ }
190
+ exports.default = BleFmAdapter;
@@ -0,0 +1,50 @@
1
+ /// <reference types="node" />
2
+ import { BleWriteProps, IBlePeripheralConnector } from "../types";
3
+ import { BleComms } from "../ble-comms";
4
+ import { IndoorBikeData, IndoorBikeFeatures } from "./types";
5
+ export default class BleFitnessMachineDevice extends BleComms {
6
+ static services: string[];
7
+ static characteristics: string[];
8
+ static detectionPriority: number;
9
+ data: IndoorBikeData;
10
+ features: IndoorBikeFeatures;
11
+ hasControl: boolean;
12
+ isCheckingControl: boolean;
13
+ isCPSubscribed: boolean;
14
+ crr: number;
15
+ cw: number;
16
+ windSpeed: number;
17
+ wheelSize: number;
18
+ constructor(props?: any);
19
+ isMatching(characteristics: string[]): boolean;
20
+ subscribeWriteResponse(cuuid: string): Promise<void>;
21
+ subscribeAll(conn?: IBlePeripheralConnector): Promise<void>;
22
+ init(): Promise<boolean>;
23
+ onDisconnect(): void;
24
+ getProfile(): string;
25
+ getServiceUUids(): string[];
26
+ isBike(): boolean;
27
+ isPower(): boolean;
28
+ isHrm(): boolean;
29
+ parseHrm(_data: Uint8Array): IndoorBikeData;
30
+ setCrr(crr: number): void;
31
+ getCrr(): number;
32
+ setCw(cw: number): void;
33
+ getCw(): number;
34
+ setWindSpeed(windSpeed: number): void;
35
+ getWindSpeed(): number;
36
+ parseIndoorBikeData(_data: Uint8Array): IndoorBikeData;
37
+ parseFitnessMachineStatus(_data: Uint8Array): IndoorBikeData;
38
+ getFitnessMachineFeatures(): Promise<IndoorBikeFeatures>;
39
+ onData(characteristic: string, data: Buffer): boolean;
40
+ writeFtmsMessage(requestedOpCode: any, data: any, props?: BleWriteProps): Promise<number>;
41
+ requestControl(): Promise<boolean>;
42
+ setTargetPower(power: number): Promise<boolean>;
43
+ setSlope(slope: any): Promise<boolean>;
44
+ setTargetInclination(inclination: number): Promise<boolean>;
45
+ setIndoorBikeSimulation(windSpeed: number, gradient: number, crr: number, cw: number): Promise<boolean>;
46
+ startRequest(): Promise<boolean>;
47
+ stopRequest(): Promise<boolean>;
48
+ PauseRequest(): Promise<boolean>;
49
+ reset(): void;
50
+ }
@@ -8,26 +8,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.FmAdapter = void 0;
16
- const ble_device_1 = require("./ble-device");
17
- const ble_interface_1 = __importDefault(require("./ble-interface"));
18
- const device_1 = __importDefault(require("../device"));
19
- const gd_eventlog_1 = require("gd-eventlog");
20
- const power_meter_1 = __importDefault(require("../modes/power-meter"));
21
- const ble_st_mode_1 = __importDefault(require("./ble-st-mode"));
22
- const ble_erg_mode_1 = __importDefault(require("./ble-erg-mode"));
23
- const consts_1 = require("./consts");
24
- const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
25
- const cwABike = {
26
- race: 0.35,
27
- triathlon: 0.29,
28
- mountain: 0.57
29
- };
30
- const cRR = 0.0036;
12
+ const ble_comms_1 = require("../ble-comms");
13
+ const consts_1 = require("../consts");
31
14
  const bit = (nr) => (1 << nr);
32
15
  const IndoorBikeDataFlag = {
33
16
  MoreData: bit(0),
@@ -82,7 +65,7 @@ const TargetSettingFeatureFlag = {
82
65
  SpinDownControlSupported: bit(15),
83
66
  TargetedCadenceConfigurationSupported: bit(16)
84
67
  };
85
- class BleFitnessMachineDevice extends ble_device_1.BleDevice {
68
+ class BleFitnessMachineDevice extends ble_comms_1.BleComms {
86
69
  constructor(props) {
87
70
  super(props);
88
71
  this.features = undefined;
@@ -540,207 +523,3 @@ exports.default = BleFitnessMachineDevice;
540
523
  BleFitnessMachineDevice.services = [consts_1.FTMS];
541
524
  BleFitnessMachineDevice.characteristics = ['2acc', consts_1.INDOOR_BIKE_DATA, '2ad6', '2ad8', consts_1.FTMS_CP, consts_1.FTMS_STATUS];
542
525
  BleFitnessMachineDevice.detectionPriority = 100;
543
- ble_interface_1.default.register('BleFitnessMachineDevice', 'fm', BleFitnessMachineDevice, BleFitnessMachineDevice.services);
544
- class FmAdapter extends device_1.default {
545
- constructor(device, protocol) {
546
- super(protocol);
547
- this.ignore = false;
548
- this.paused = false;
549
- this.distanceInternal = 0;
550
- this.device = device;
551
- this.ble = protocol.ble;
552
- this.cyclingMode = this.getDefaultCyclingMode();
553
- this.logger = new gd_eventlog_1.EventLogger('BLE-FM');
554
- if (this.device)
555
- this.device.setLogger(this.logger);
556
- }
557
- isBike() { return this.device.isBike() || this.device.isPower(); }
558
- isHrm() { return this.device.isHrm(); }
559
- isPower() { return this.device.isPower(); }
560
- isSame(device) {
561
- if (!(device instanceof FmAdapter))
562
- return false;
563
- const adapter = device;
564
- return (adapter.getName() === this.getName() && adapter.getProfile() === this.getProfile());
565
- }
566
- getProfile() {
567
- const profile = this.device ? this.device.getProfile() : undefined;
568
- return profile || 'Smart Trainer';
569
- }
570
- getName() {
571
- return `${this.device.name}`;
572
- }
573
- getDisplayName() {
574
- return this.getName();
575
- }
576
- getSupportedCyclingModes() {
577
- return [ble_st_mode_1.default, ble_erg_mode_1.default, power_meter_1.default];
578
- }
579
- setCyclingMode(mode, settings) {
580
- let selectedMode;
581
- if (typeof mode === 'string') {
582
- const supported = this.getSupportedCyclingModes();
583
- const CyclingModeClass = supported.find(M => { const m = new M(this); return m.getName() === mode; });
584
- if (CyclingModeClass) {
585
- this.cyclingMode = new CyclingModeClass(this, settings);
586
- return;
587
- }
588
- selectedMode = this.getDefaultCyclingMode();
589
- }
590
- else {
591
- selectedMode = mode;
592
- }
593
- this.cyclingMode = selectedMode;
594
- this.cyclingMode.setSettings(settings);
595
- }
596
- getCyclingMode() {
597
- if (!this.cyclingMode)
598
- this.cyclingMode = this.getDefaultCyclingMode();
599
- return this.cyclingMode;
600
- }
601
- getDefaultCyclingMode() {
602
- return new ble_st_mode_1.default(this);
603
- }
604
- getPort() {
605
- return 'ble';
606
- }
607
- setIgnoreBike(ignore) {
608
- this.ignore = ignore;
609
- }
610
- setIgnorePower(ignore) {
611
- this.ignore = ignore;
612
- }
613
- onDeviceData(deviceData) {
614
- if (this.prevDataTS && Date.now() - this.prevDataTS < 1000)
615
- return;
616
- this.prevDataTS = Date.now();
617
- this.logger.logEvent({ message: 'onDeviceData', data: deviceData });
618
- let incyclistData = this.mapData(deviceData);
619
- incyclistData = this.getCyclingMode().updateData(incyclistData);
620
- const data = this.transformData(incyclistData);
621
- if (this.onDataFn && !this.ignore && !this.paused)
622
- this.onDataFn(data);
623
- }
624
- mapData(deviceData) {
625
- const data = {
626
- isPedalling: false,
627
- power: 0,
628
- pedalRpm: undefined,
629
- speed: 0,
630
- heartrate: 0,
631
- distanceInternal: 0,
632
- slope: undefined,
633
- time: undefined
634
- };
635
- data.power = (deviceData.instantaneousPower !== undefined ? deviceData.instantaneousPower : data.power);
636
- data.pedalRpm = (deviceData.cadence !== undefined ? deviceData.cadence : data.pedalRpm);
637
- data.time = (deviceData.time !== undefined ? deviceData.time : data.time);
638
- data.isPedalling = data.pedalRpm > 0 || (data.pedalRpm === undefined && data.power > 0);
639
- return data;
640
- }
641
- transformData(bikeData) {
642
- if (this.ignore) {
643
- return {};
644
- }
645
- if (bikeData === undefined)
646
- return;
647
- let distance = 0;
648
- if (this.distanceInternal !== undefined && bikeData.distanceInternal !== undefined) {
649
- distance = Math.round(bikeData.distanceInternal - this.distanceInternal);
650
- }
651
- if (bikeData.distanceInternal !== undefined)
652
- this.distanceInternal = bikeData.distanceInternal;
653
- let data = {
654
- speed: bikeData.speed,
655
- slope: bikeData.slope,
656
- power: bikeData.power !== undefined ? Math.round(bikeData.power) : undefined,
657
- cadence: bikeData.pedalRpm !== undefined ? Math.round(bikeData.pedalRpm) : undefined,
658
- distance,
659
- timestamp: Date.now()
660
- };
661
- return data;
662
- }
663
- start(props) {
664
- return __awaiter(this, void 0, void 0, function* () {
665
- this.logger.logEvent({ message: 'ftms: start requested', profile: this.getProfile(), props });
666
- const { restart } = props || {};
667
- if (!restart && this.ble.isScanning())
668
- yield this.ble.stopScan();
669
- try {
670
- let bleDevice;
671
- if (!this.device || !restart) {
672
- bleDevice = (yield this.ble.connectDevice(this.device));
673
- this.device = bleDevice;
674
- }
675
- else
676
- bleDevice = this.device;
677
- if (bleDevice) {
678
- bleDevice.setLogger(this.logger);
679
- const mode = this.getCyclingMode();
680
- if (mode && mode.getSetting('bikeType')) {
681
- const bikeType = mode.getSetting('bikeType').toLowerCase();
682
- this.device.setCrr(cRR);
683
- switch (bikeType) {
684
- case 'race':
685
- this.device.setCw(cwABike.race);
686
- break;
687
- case 'triathlon':
688
- this.device.setCw(cwABike.triathlon);
689
- break;
690
- case 'mountain':
691
- this.device.setCw(cwABike.mountain);
692
- break;
693
- }
694
- }
695
- let hasControl = yield this.device.requestControl();
696
- if (!hasControl) {
697
- let retry = 1;
698
- while (!hasControl && retry < 3) {
699
- yield sleep(1000);
700
- hasControl = yield this.device.requestControl();
701
- retry++;
702
- }
703
- }
704
- if (!hasControl)
705
- throw new Error('could not establish control');
706
- const startRequest = this.getCyclingMode().getBikeInitRequest();
707
- yield this.sendUpdate(startRequest);
708
- bleDevice.on('data', (data) => {
709
- this.onDeviceData(data);
710
- });
711
- bleDevice.on('disconnected', this.emit);
712
- return true;
713
- }
714
- }
715
- catch (err) {
716
- this.logger.logEvent({ message: 'start result: error', error: err.message, profile: this.getProfile() });
717
- throw new Error(`could not start device, reason:${err.message}`);
718
- }
719
- });
720
- }
721
- stop() {
722
- return __awaiter(this, void 0, void 0, function* () {
723
- this.logger.logEvent({ message: 'stop requested', profile: this.getProfile() });
724
- this.distanceInternal = 0;
725
- this.device.reset();
726
- return this.device.disconnect();
727
- });
728
- }
729
- sendUpdate(request) {
730
- return __awaiter(this, void 0, void 0, function* () {
731
- if (this.paused || !this.device)
732
- return;
733
- const update = this.getCyclingMode().sendBikeUpdate(request);
734
- this.logger.logEvent({ message: 'send bike update requested', profile: this.getProfile(), update, request });
735
- if (update.slope !== undefined) {
736
- yield this.device.setSlope(update.slope);
737
- }
738
- if (update.targetPower !== undefined) {
739
- yield this.device.setTargetPower(update.targetPower);
740
- }
741
- });
742
- }
743
- pause() { this.paused = true; return Promise.resolve(true); }
744
- resume() { this.paused = false; return Promise.resolve(true); }
745
- }
746
- exports.FmAdapter = FmAdapter;
@@ -0,0 +1,6 @@
1
+ export declare const cwABike: {
2
+ race: number;
3
+ triathlon: number;
4
+ mountain: number;
5
+ };
6
+ export declare const cRR = 0.0036;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cRR = exports.cwABike = void 0;
4
+ exports.cwABike = {
5
+ race: 0.35,
6
+ triathlon: 0.29,
7
+ mountain: 0.57
8
+ };
9
+ exports.cRR = 0.0036;
@@ -0,0 +1,5 @@
1
+ import BleFmComms from './comms';
2
+ import BleFmAdapter from './adapter';
3
+ import { IndoorBikeData } from './types';
4
+ import { cRR, cwABike } from './consts';
5
+ export { BleFmAdapter, BleFmComms, IndoorBikeData, cRR, cwABike };
@@ -0,0 +1,13 @@
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
+ exports.cwABike = exports.cRR = exports.BleFmComms = exports.BleFmAdapter = void 0;
7
+ const comms_1 = __importDefault(require("./comms"));
8
+ exports.BleFmComms = comms_1.default;
9
+ const adapter_1 = __importDefault(require("./adapter"));
10
+ exports.BleFmAdapter = adapter_1.default;
11
+ const consts_1 = require("./consts");
12
+ Object.defineProperty(exports, "cRR", { enumerable: true, get: function () { return consts_1.cRR; } });
13
+ Object.defineProperty(exports, "cwABike", { enumerable: true, get: function () { return consts_1.cwABike; } });
@@ -0,0 +1,25 @@
1
+ export type IndoorBikeData = {
2
+ speed?: number;
3
+ averageSpeed?: number;
4
+ cadence?: number;
5
+ averageCadence?: number;
6
+ totalDistance?: number;
7
+ resistanceLevel?: number;
8
+ instantaneousPower?: number;
9
+ averagePower?: number;
10
+ totalEnergy?: number;
11
+ energyPerHour?: number;
12
+ energyPerMinute?: number;
13
+ heartrate?: number;
14
+ metabolicEquivalent?: number;
15
+ time?: number;
16
+ remainingTime?: number;
17
+ raw?: string;
18
+ targetPower?: number;
19
+ targetInclination?: number;
20
+ status?: string;
21
+ };
22
+ export type IndoorBikeFeatures = {
23
+ fitnessMachine: number;
24
+ targetSettings: number;
25
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,17 @@
1
+ import BleAdapter from '../adapter';
2
+ import { DeviceProperties } from '../../types/device';
3
+ import { BleDeviceSettings } from '../types';
4
+ import { HrmData } from './types';
5
+ import { DeviceData } from '../../types/data';
6
+ export default class HrmAdapter extends BleAdapter {
7
+ ignore: boolean;
8
+ constructor(settings: BleDeviceSettings, props?: DeviceProperties);
9
+ isSame(device: BleAdapter): boolean;
10
+ getProfile(): string;
11
+ getName(): string;
12
+ getDisplayName(): string;
13
+ getPort(): string;
14
+ setIgnoreHrm(ignore: any): void;
15
+ onDeviceData(deviceData: HrmData): void;
16
+ mapData(deviceData: HrmData): DeviceData;
17
+ }
@@ -0,0 +1,62 @@
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 adapter_1 = __importDefault(require("../adapter"));
8
+ const comm_1 = __importDefault(require("./comm"));
9
+ const capabilities_1 = require("../../types/capabilities");
10
+ class HrmAdapter extends adapter_1.default {
11
+ constructor(settings, props) {
12
+ super(settings, props);
13
+ this.ignore = false;
14
+ this.logger = new gd_eventlog_1.EventLogger('Ble-HR');
15
+ const { id, address, name } = settings;
16
+ const logger = this.logger;
17
+ const ble = this.ble;
18
+ this.device = new comm_1.default({ id, address, name, ble, logger });
19
+ this.capabilities = [
20
+ capabilities_1.IncyclistCapability.HeartRate
21
+ ];
22
+ }
23
+ isSame(device) {
24
+ if (!(device instanceof HrmAdapter))
25
+ return false;
26
+ return this.isEqual(device.settings);
27
+ }
28
+ getProfile() {
29
+ return 'Heartrate Monitor';
30
+ }
31
+ getName() {
32
+ return `${this.device.name}`;
33
+ }
34
+ getDisplayName() {
35
+ const { name } = this.device;
36
+ const { heartrate: hrm } = this.deviceData;
37
+ const hrmStr = hrm ? ` (${hrm})` : '';
38
+ return `${name}${hrmStr}`;
39
+ }
40
+ getPort() {
41
+ return 'ble';
42
+ }
43
+ setIgnoreHrm(ignore) {
44
+ this.ignore = ignore;
45
+ }
46
+ onDeviceData(deviceData) {
47
+ super.onDeviceData(deviceData);
48
+ if (!this.started || this.paused || !this.onDataFn)
49
+ return;
50
+ if (!this.lastUpdate || (Date.now() - this.lastUpdate) > this.updateFrequency) {
51
+ this.logger.logEvent({ message: 'onDeviceData', data: deviceData });
52
+ this.data = this.mapData(this.deviceData);
53
+ this.onDataFn(this.data);
54
+ this.lastUpdate = Date.now();
55
+ }
56
+ }
57
+ mapData(deviceData) {
58
+ const { heartrate } = deviceData;
59
+ return { heartrate };
60
+ }
61
+ }
62
+ exports.default = HrmAdapter;
@@ -0,0 +1,15 @@
1
+ /// <reference types="node" />
2
+ import { BleComms } from '../ble-comms';
3
+ import { HrmData } from './types';
4
+ export default class BleHrmDevice extends BleComms {
5
+ static services: string[];
6
+ static characteristics: string[];
7
+ static detectionPriority: number;
8
+ heartrate: number;
9
+ rr: number;
10
+ constructor(props?: any);
11
+ getProfile(): string;
12
+ getServiceUUids(): string[];
13
+ parseHrm(_data: Uint8Array): HrmData;
14
+ onData(characteristic: string, data: Buffer): boolean;
15
+ }