incyclist-devices 2.2.9 → 2.3.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 (142) hide show
  1. package/lib/antv2/base/interface.js +2 -2
  2. package/lib/antv2/factories/index.d.ts +1 -0
  3. package/lib/antv2/factories/index.js +17 -0
  4. package/lib/antv2/fe/adapter.js +5 -4
  5. package/lib/antv2/index.d.ts +1 -0
  6. package/lib/antv2/index.js +12 -8
  7. package/lib/base/adpater.js +1 -1
  8. package/lib/ble/adapter-factory.d.ts +20 -24
  9. package/lib/ble/adapter-factory.js +13 -36
  10. package/lib/ble/base/adapter.d.ts +16 -5
  11. package/lib/ble/base/adapter.js +169 -52
  12. package/lib/ble/base/comms.d.ts +2 -74
  13. package/lib/ble/base/comms.js +3 -596
  14. package/lib/ble/base/interface.d.ts +96 -0
  15. package/lib/ble/base/interface.js +544 -0
  16. package/lib/ble/base/peripheral.d.ts +34 -0
  17. package/lib/ble/base/peripheral.js +286 -0
  18. package/lib/ble/base/sensor.d.ts +31 -0
  19. package/lib/ble/base/sensor.js +130 -0
  20. package/lib/ble/base/types.d.ts +7 -0
  21. package/lib/ble/base/types.js +7 -0
  22. package/lib/ble/bindings/mock.js +6 -0
  23. package/lib/ble/bindings/types.d.ts +3 -4
  24. package/lib/ble/ble-interface.d.ts +7 -4
  25. package/lib/ble/ble-interface.js +16 -2
  26. package/lib/ble/ble-peripheral.d.ts +1 -0
  27. package/lib/ble/ble-peripheral.js +7 -11
  28. package/lib/ble/consts.d.ts +0 -6
  29. package/lib/ble/consts.js +1 -7
  30. package/lib/ble/cp/adapter.d.ts +3 -3
  31. package/lib/ble/cp/adapter.js +12 -13
  32. package/lib/ble/cp/comm.d.ts +1 -1
  33. package/lib/ble/cp/comm.js +2 -2
  34. package/lib/ble/cp/index.d.ts +1 -1
  35. package/lib/ble/cp/index.js +2 -2
  36. package/lib/ble/cp/sensor.d.ts +27 -0
  37. package/lib/ble/cp/sensor.js +107 -0
  38. package/lib/ble/elite/comms.d.ts +1 -1
  39. package/lib/ble/elite/comms.js +2 -2
  40. package/lib/ble/factories/adapter-factory.d.ts +32 -0
  41. package/lib/ble/factories/adapter-factory.js +104 -0
  42. package/lib/ble/factories/index.d.ts +2 -0
  43. package/lib/ble/factories/index.js +18 -0
  44. package/lib/ble/factories/interface-factory.d.ts +7 -0
  45. package/lib/ble/factories/interface-factory.js +18 -0
  46. package/lib/ble/fm/adapter.d.ts +9 -4
  47. package/lib/ble/fm/adapter.js +104 -108
  48. package/lib/ble/fm/comms.d.ts +1 -1
  49. package/lib/ble/fm/comms.js +3 -3
  50. package/lib/ble/fm/consts.d.ts +93 -0
  51. package/lib/ble/fm/consts.js +55 -1
  52. package/lib/ble/fm/index.d.ts +1 -1
  53. package/lib/ble/fm/index.js +2 -2
  54. package/lib/ble/fm/sensor.d.ts +44 -0
  55. package/lib/ble/fm/sensor.js +384 -0
  56. package/lib/ble/hr/adapter.d.ts +3 -3
  57. package/lib/ble/hr/adapter.js +5 -8
  58. package/lib/ble/hr/comm.d.ts +1 -1
  59. package/lib/ble/hr/comm.js +2 -2
  60. package/lib/ble/hr/index.d.ts +1 -1
  61. package/lib/ble/hr/index.js +2 -2
  62. package/lib/ble/hr/sensor.d.ts +17 -0
  63. package/lib/ble/hr/sensor.js +52 -0
  64. package/lib/ble/index.d.ts +4 -3
  65. package/lib/ble/index.js +29 -13
  66. package/lib/ble/tacx/adapter.d.ts +4 -2
  67. package/lib/ble/tacx/adapter.js +26 -66
  68. package/lib/ble/tacx/comms.d.ts +1 -1
  69. package/lib/ble/tacx/comms.js +2 -2
  70. package/lib/ble/tacx/consts.d.ts +23 -0
  71. package/lib/ble/tacx/consts.js +27 -0
  72. package/lib/ble/tacx/index.d.ts +1 -1
  73. package/lib/ble/tacx/index.js +2 -2
  74. package/lib/ble/tacx/sensor.d.ts +63 -0
  75. package/lib/ble/tacx/sensor.js +596 -0
  76. package/lib/ble/types.d.ts +81 -52
  77. package/lib/ble/utils.d.ts +7 -2
  78. package/lib/ble/utils.js +84 -9
  79. package/lib/ble/wahoo/adapter.d.ts +2 -2
  80. package/lib/ble/wahoo/adapter.js +4 -72
  81. package/lib/ble/wahoo/comms.d.ts +1 -1
  82. package/lib/ble/wahoo/comms.js +2 -2
  83. package/lib/ble/wahoo/consts.d.ts +16 -0
  84. package/lib/ble/wahoo/consts.js +7 -0
  85. package/lib/ble/wahoo/index.d.ts +1 -1
  86. package/lib/ble/wahoo/index.js +2 -2
  87. package/lib/ble/wahoo/sensor.d.ts +48 -0
  88. package/lib/ble/wahoo/sensor.js +356 -0
  89. package/lib/direct-connect/base/comms.d.ts +3 -0
  90. package/lib/direct-connect/base/comms.js +7 -0
  91. package/lib/direct-connect/base/interface.d.ts +75 -0
  92. package/lib/direct-connect/base/interface.js +306 -0
  93. package/lib/direct-connect/base/peripheral.d.ts +50 -0
  94. package/lib/direct-connect/base/peripheral.js +413 -0
  95. package/lib/direct-connect/base/sensor.d.ts +3 -0
  96. package/lib/direct-connect/base/sensor.js +7 -0
  97. package/lib/direct-connect/bindings/index.d.ts +1 -0
  98. package/lib/direct-connect/bindings/index.js +17 -0
  99. package/lib/direct-connect/bindings/types.d.ts +36 -0
  100. package/lib/direct-connect/bindings/types.js +2 -0
  101. package/lib/direct-connect/consts.d.ts +17 -0
  102. package/lib/direct-connect/consts.js +20 -0
  103. package/lib/direct-connect/index.d.ts +3 -0
  104. package/lib/direct-connect/index.js +22 -0
  105. package/lib/direct-connect/messages/CharacteristicNotification.d.ts +12 -0
  106. package/lib/direct-connect/messages/CharacteristicNotification.js +23 -0
  107. package/lib/direct-connect/messages/DiscoverCharacteristics.d.ts +22 -0
  108. package/lib/direct-connect/messages/DiscoverCharacteristics.js +43 -0
  109. package/lib/direct-connect/messages/DiscoverServices.d.ts +15 -0
  110. package/lib/direct-connect/messages/DiscoverServices.js +33 -0
  111. package/lib/direct-connect/messages/EnableCharacteristicNotifications.d.ts +18 -0
  112. package/lib/direct-connect/messages/EnableCharacteristicNotifications.js +35 -0
  113. package/lib/direct-connect/messages/ReadCharacteristic.d.ts +18 -0
  114. package/lib/direct-connect/messages/ReadCharacteristic.js +34 -0
  115. package/lib/direct-connect/messages/WriteCharacteristic.d.ts +18 -0
  116. package/lib/direct-connect/messages/WriteCharacteristic.js +36 -0
  117. package/lib/direct-connect/messages/error.d.ts +5 -0
  118. package/lib/direct-connect/messages/error.js +18 -0
  119. package/lib/direct-connect/messages/factory.d.ts +6 -0
  120. package/lib/direct-connect/messages/factory.js +44 -0
  121. package/lib/direct-connect/messages/index.d.ts +9 -0
  122. package/lib/direct-connect/messages/index.js +25 -0
  123. package/lib/direct-connect/messages/message.d.ts +20 -0
  124. package/lib/direct-connect/messages/message.js +90 -0
  125. package/lib/direct-connect/types.d.ts +24 -0
  126. package/lib/direct-connect/types.js +9 -0
  127. package/lib/direct-connect/utils.d.ts +5 -0
  128. package/lib/direct-connect/utils.js +73 -0
  129. package/lib/factories/adapters.js +16 -4
  130. package/lib/factories/interfaces.d.ts +2 -1
  131. package/lib/factories/interfaces.js +10 -7
  132. package/lib/index.d.ts +5 -4
  133. package/lib/index.js +6 -2
  134. package/lib/serial/bindings/tcp.d.ts +5 -4
  135. package/lib/serial/bindings/tcp.js +16 -23
  136. package/lib/types/device.d.ts +2 -1
  137. package/lib/types/device.js +1 -0
  138. package/lib/utils/operation.d.ts +17 -0
  139. package/lib/utils/operation.js +20 -0
  140. package/lib/utils/task.d.ts +44 -0
  141. package/lib/utils/task.js +127 -0
  142. package/package.json +3 -1
@@ -0,0 +1,384 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const consts_1 = require("../consts");
13
+ const sensor_1 = require("../base/sensor");
14
+ const utils_1 = require("../utils");
15
+ const consts_2 = require("./consts");
16
+ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
17
+ constructor(peripheral, props) {
18
+ super(peripheral, props);
19
+ this._features = undefined;
20
+ this.hasControl = false;
21
+ this.isCheckingControl = false;
22
+ this.isCPSubscribed = false;
23
+ this.crr = 0.0033;
24
+ this.cw = 0.6;
25
+ this.windSpeed = 0;
26
+ this.wheelSize = 2100;
27
+ this.reset();
28
+ }
29
+ get features() {
30
+ return this._features;
31
+ }
32
+ reset() {
33
+ this.data = {};
34
+ }
35
+ getRequiredCharacteristics() {
36
+ return [consts_1.INDOOR_BIKE_DATA, '2a37', consts_1.FTMS_STATUS];
37
+ }
38
+ onData(characteristic, data) {
39
+ try {
40
+ const hasData = super.onData(characteristic, data);
41
+ if (!hasData)
42
+ return false;
43
+ const uuid = (0, utils_1.beautifyUUID)(characteristic).toLowerCase();
44
+ let res = undefined;
45
+ switch (uuid) {
46
+ case consts_1.INDOOR_BIKE_DATA:
47
+ res = this.parseIndoorBikeData(data);
48
+ break;
49
+ case '2a37':
50
+ res = this.parseHrm(data);
51
+ break;
52
+ case consts_1.FTMS_STATUS:
53
+ res = this.parseFitnessMachineStatus(data);
54
+ break;
55
+ case '2a63':
56
+ case '2a5b':
57
+ case '347b0011-7635-408b-8918-8ff3949ce592':
58
+ break;
59
+ default:
60
+ break;
61
+ }
62
+ if (res) {
63
+ this.emit('data', res);
64
+ return false;
65
+ }
66
+ return true;
67
+ }
68
+ catch (err) {
69
+ this.logEvent({ message: 'Error', fn: 'onData', error: err.message, stack: err.stack });
70
+ return false;
71
+ }
72
+ }
73
+ setCrr(crr) { this.crr = crr; }
74
+ getCrr() { return this.crr; }
75
+ setCw(cw) { this.cw = cw; }
76
+ getCw() { return this.cw; }
77
+ setWindSpeed(windSpeed) { this.windSpeed = windSpeed; }
78
+ getWindSpeed() { return this.windSpeed; }
79
+ requestControl() {
80
+ return __awaiter(this, void 0, void 0, function* () {
81
+ if (this.hasControl)
82
+ return true;
83
+ this.logEvent({ message: 'requestControl' });
84
+ this.isCheckingControl = true;
85
+ const data = Buffer.alloc(1);
86
+ data.writeUInt8(0, 0);
87
+ const res = yield this.writeFtmsMessage(0, data, { timeout: 5000 });
88
+ if (res === 1) {
89
+ this.hasControl = true;
90
+ }
91
+ else {
92
+ this.logEvent({ message: 'requestControl failed', reason: res });
93
+ }
94
+ this.isCheckingControl = false;
95
+ return this.hasControl;
96
+ });
97
+ }
98
+ setTargetPower(power) {
99
+ return __awaiter(this, void 0, void 0, function* () {
100
+ this.logEvent({ message: 'setTargetPower', power, skip: (this.data.targetPower !== undefined && this.data.targetPower === power) });
101
+ if (this.data.targetPower !== undefined && this.data.targetPower === power)
102
+ return true;
103
+ if (!this.hasControl)
104
+ return;
105
+ const hasControl = yield this.requestControl();
106
+ if (!hasControl) {
107
+ this.logEvent({ message: 'setTargetPower failed', reason: 'control is disabled' });
108
+ return true;
109
+ }
110
+ const data = Buffer.alloc(3);
111
+ data.writeUInt8(5, 0);
112
+ data.writeInt16LE(Math.round(power), 1);
113
+ const res = yield this.writeFtmsMessage(5, data);
114
+ return (res === 1);
115
+ });
116
+ }
117
+ setSlope(slope) {
118
+ return __awaiter(this, void 0, void 0, function* () {
119
+ this.logEvent({ message: 'setSlope', slope });
120
+ const hasControl = yield this.requestControl();
121
+ if (!hasControl)
122
+ return;
123
+ const { windSpeed, crr, cw } = this;
124
+ return yield this.setIndoorBikeSimulation(windSpeed, slope, crr, cw);
125
+ });
126
+ }
127
+ parseHrm(_data) {
128
+ const data = Buffer.from(_data);
129
+ try {
130
+ const flags = data.readUInt8(0);
131
+ if (flags % 1 === 0) {
132
+ this.data.heartrate = data.readUInt8(1);
133
+ }
134
+ else {
135
+ this.data.heartrate = data.readUInt16LE(1);
136
+ }
137
+ }
138
+ catch (err) {
139
+ this.logEvent({ message: 'error', fn: 'parseHrm()', error: err.message | err, stack: err.stack });
140
+ }
141
+ return Object.assign(Object.assign({}, this.data), { raw: `2a37:${data.toString('hex')}` });
142
+ }
143
+ parseIndoorBikeData(_data) {
144
+ const data = Buffer.from(_data);
145
+ try {
146
+ const flags = data.readUInt16LE(0);
147
+ let offset = 2;
148
+ if ((flags & consts_2.IndoorBikeDataFlag.MoreData) === 0) {
149
+ this.data.speed = data.readUInt16LE(offset) / 100;
150
+ offset += 2;
151
+ }
152
+ if (flags & consts_2.IndoorBikeDataFlag.AverageSpeedPresent) {
153
+ this.data.averageSpeed = data.readUInt16LE(offset) / 100;
154
+ offset += 2;
155
+ }
156
+ if (flags & consts_2.IndoorBikeDataFlag.InstantaneousCadence) {
157
+ this.data.cadence = data.readUInt16LE(offset) / 2;
158
+ offset += 2;
159
+ }
160
+ if (flags & consts_2.IndoorBikeDataFlag.AverageCadencePresent) {
161
+ this.data.averageCadence = data.readUInt16LE(offset) / 2;
162
+ offset += 2;
163
+ }
164
+ if (flags & consts_2.IndoorBikeDataFlag.TotalDistancePresent) {
165
+ const dvLow = data.readUInt8(offset);
166
+ offset += 1;
167
+ const dvHigh = data.readUInt16LE(offset);
168
+ offset += 2;
169
+ this.data.totalDistance = (dvHigh << 8) + dvLow;
170
+ }
171
+ if (flags & consts_2.IndoorBikeDataFlag.ResistanceLevelPresent) {
172
+ this.data.resistanceLevel = data.readInt16LE(offset);
173
+ offset += 2;
174
+ }
175
+ if (flags & consts_2.IndoorBikeDataFlag.InstantaneousPowerPresent) {
176
+ this.data.instantaneousPower = data.readInt16LE(offset);
177
+ offset += 2;
178
+ }
179
+ if (flags & consts_2.IndoorBikeDataFlag.AveragePowerPresent) {
180
+ this.data.averagePower = data.readInt16LE(offset);
181
+ offset += 2;
182
+ }
183
+ if (flags & consts_2.IndoorBikeDataFlag.ExpendedEnergyPresent) {
184
+ this.data.totalEnergy = data.readUInt16LE(offset);
185
+ offset += 2;
186
+ this.data.energyPerHour = data.readUInt16LE(offset);
187
+ offset += 2;
188
+ this.data.energyPerMinute = data.readUInt8(offset);
189
+ offset += 1;
190
+ }
191
+ if (flags & consts_2.IndoorBikeDataFlag.HeartRatePresent) {
192
+ this.data.heartrate = data.readUInt8(offset);
193
+ offset += 1;
194
+ }
195
+ if (flags & consts_2.IndoorBikeDataFlag.MetabolicEquivalentPresent) {
196
+ this.data.metabolicEquivalent = data.readUInt8(offset) / 10;
197
+ offset += 2;
198
+ }
199
+ if (flags & consts_2.IndoorBikeDataFlag.ElapsedTimePresent) {
200
+ this.data.time = data.readUInt16LE(offset);
201
+ offset += 2;
202
+ }
203
+ if (flags & consts_2.IndoorBikeDataFlag.RemainingTimePresent) {
204
+ this.data.remainingTime = data.readUInt16LE(offset);
205
+ }
206
+ }
207
+ catch (err) {
208
+ this.logEvent({ message: 'error', fn: 'parseIndoorBikeData()', error: err.message | err, stack: err.stack });
209
+ }
210
+ return Object.assign(Object.assign({}, this.data), { raw: `2ad2:${data.toString('hex')}` });
211
+ }
212
+ parseFitnessMachineStatus(_data) {
213
+ const data = Buffer.from(_data);
214
+ try {
215
+ const OpCode = data.readUInt8(0);
216
+ switch (OpCode) {
217
+ case 8:
218
+ this.data.targetPower = data.readInt16LE(1);
219
+ break;
220
+ case 6:
221
+ this.data.targetInclination = data.readInt16LE(1) / 10;
222
+ break;
223
+ case 4:
224
+ this.data.status = "STARTED";
225
+ break;
226
+ case 3:
227
+ case 2:
228
+ this.data.status = "STOPPED";
229
+ break;
230
+ case 20:
231
+ {
232
+ const spinDownStatus = data.readUInt8(1);
233
+ switch (spinDownStatus) {
234
+ case 1:
235
+ this.data.status = "SPIN DOWN REQUESTED";
236
+ break;
237
+ case 2:
238
+ this.data.status = "SPIN DOWN SUCCESS";
239
+ break;
240
+ case 3:
241
+ this.data.status = "SPIN DOWN ERROR";
242
+ break;
243
+ case 4:
244
+ this.data.status = "STOP PEDALING";
245
+ break;
246
+ default: break;
247
+ }
248
+ }
249
+ }
250
+ }
251
+ catch (err) {
252
+ this.logEvent({ message: 'error', fn: 'parseFitnessMachineStatus()', error: err.message | err, stack: err.stack });
253
+ }
254
+ return Object.assign(Object.assign({}, this.data), { raw: `2ada:${data.toString('hex')}` });
255
+ }
256
+ getFitnessMachineFeatures() {
257
+ return __awaiter(this, void 0, void 0, function* () {
258
+ if (this._features)
259
+ return this._features;
260
+ try {
261
+ const data = yield this.read('2acc');
262
+ const buffer = data ? Buffer.from(data) : undefined;
263
+ if (buffer) {
264
+ const fitnessMachine = buffer.readUInt32LE(0);
265
+ const targetSettings = buffer.readUInt32LE(4);
266
+ const power = (fitnessMachine & consts_2.FitnessMachineFeatureFlag.PowerMeasurementSupported) !== 0;
267
+ const heartrate = (fitnessMachine & consts_2.FitnessMachineFeatureFlag.HeartRateMeasurementSupported) !== 0;
268
+ const cadence = (fitnessMachine & consts_2.FitnessMachineFeatureFlag.CadenceSupported) !== 0;
269
+ const setSlope = (targetSettings & consts_2.TargetSettingFeatureFlag.IndoorBikeSimulationParametersSupported) !== 0
270
+ || (targetSettings & consts_2.TargetSettingFeatureFlag.InclinationTargetSettingSupported) !== 0;
271
+ const setPower = (targetSettings & consts_2.TargetSettingFeatureFlag.PowerTargetSettingSupported) !== 0;
272
+ this._features = { fitnessMachine, targetSettings, power, heartrate, cadence, setPower, setSlope };
273
+ this.logEvent({ message: 'supported Features: ', fatures: this._features, power, heartrate, cadence });
274
+ }
275
+ }
276
+ catch (err) {
277
+ this.logEvent({ message: 'could not read FitnessMachineFeatures', error: err.message, stack: err.stack });
278
+ return undefined;
279
+ }
280
+ });
281
+ }
282
+ writeFtmsMessage(requestedOpCode, data, props) {
283
+ return __awaiter(this, void 0, void 0, function* () {
284
+ try {
285
+ this.logEvent({ message: 'fmts:write', data: data.toString('hex') });
286
+ const res = yield this.write(consts_1.FTMS_CP, data, props);
287
+ const responseData = Buffer.from(res);
288
+ const opCode = responseData.readUInt8(0);
289
+ const request = responseData.readUInt8(1);
290
+ const result = responseData.readUInt8(2);
291
+ if (opCode !== 128 || request !== requestedOpCode)
292
+ throw new Error('Illegal response ');
293
+ this.logEvent({ message: 'fmts:write result', res, result });
294
+ return result;
295
+ }
296
+ catch (err) {
297
+ this.logEvent({ message: 'fmts:write failed', opCode: requestedOpCode, reason: err.message });
298
+ return 4;
299
+ }
300
+ });
301
+ }
302
+ setTargetInclination(inclination) {
303
+ return __awaiter(this, void 0, void 0, function* () {
304
+ if (this.data.targetInclination !== undefined && this.data.targetInclination === inclination)
305
+ return true;
306
+ if (!this.hasControl)
307
+ return;
308
+ const hasControl = yield this.requestControl();
309
+ if (!hasControl) {
310
+ this.logEvent({ message: 'setTargetInclination failed', reason: 'control is disabled' });
311
+ return false;
312
+ }
313
+ const data = Buffer.alloc(3);
314
+ data.writeUInt8(3, 0);
315
+ data.writeInt16LE(Math.round(inclination * 10), 1);
316
+ const res = yield this.writeFtmsMessage(3, data);
317
+ return (res === 1);
318
+ });
319
+ }
320
+ setIndoorBikeSimulation(windSpeed, gradient, crr, cw) {
321
+ return __awaiter(this, void 0, void 0, function* () {
322
+ const hasControl = yield this.requestControl();
323
+ if (!hasControl) {
324
+ this.logEvent({ message: 'setIndoorBikeSimulation failed', reason: 'control is disabled' });
325
+ return false;
326
+ }
327
+ const data = Buffer.alloc(7);
328
+ data.writeUInt8(17, 0);
329
+ data.writeInt16LE(Math.round(windSpeed * 1000), 1);
330
+ data.writeInt16LE(Math.round(gradient * 100), 3);
331
+ data.writeUInt8(Math.round(crr * 10000), 5);
332
+ data.writeUInt8(Math.round(cw * 100), 6);
333
+ const res = yield this.writeFtmsMessage(17, data);
334
+ return (res === 1);
335
+ });
336
+ }
337
+ startRequest() {
338
+ return __awaiter(this, void 0, void 0, function* () {
339
+ const hasControl = yield this.requestControl();
340
+ if (!hasControl) {
341
+ this.logEvent({ message: 'startRequest failed', reason: 'control is disabled' });
342
+ return false;
343
+ }
344
+ const data = Buffer.alloc(1);
345
+ data.writeUInt8(7, 0);
346
+ const res = yield this.writeFtmsMessage(7, data);
347
+ return (res === 1);
348
+ });
349
+ }
350
+ stopRequest() {
351
+ return __awaiter(this, void 0, void 0, function* () {
352
+ const hasControl = yield this.requestControl();
353
+ if (!hasControl) {
354
+ this.logEvent({ message: 'stopRequest failed', reason: 'control is disabled' });
355
+ return false;
356
+ }
357
+ const data = Buffer.alloc(2);
358
+ data.writeUInt8(8, 0);
359
+ data.writeUInt8(1, 1);
360
+ const res = yield this.writeFtmsMessage(8, data);
361
+ return (res === 1);
362
+ });
363
+ }
364
+ PauseRequest() {
365
+ return __awaiter(this, void 0, void 0, function* () {
366
+ const hasControl = yield this.requestControl();
367
+ if (!hasControl) {
368
+ this.logEvent({ message: 'PauseRequest failed', reason: 'control is disabled' });
369
+ return false;
370
+ }
371
+ const data = Buffer.alloc(2);
372
+ data.writeUInt8(8, 0);
373
+ data.writeUInt8(2, 1);
374
+ const res = yield this.writeFtmsMessage(8, data);
375
+ return (res === 1);
376
+ });
377
+ }
378
+ }
379
+ BleFitnessMachineDevice.profile = 'Smart Trainer';
380
+ BleFitnessMachineDevice.protocol = 'fm';
381
+ BleFitnessMachineDevice.services = [consts_1.FTMS];
382
+ BleFitnessMachineDevice.characteristics = ['2acc', consts_1.INDOOR_BIKE_DATA, '2ad6', '2ad8', consts_1.FTMS_CP, consts_1.FTMS_STATUS];
383
+ BleFitnessMachineDevice.detectionPriority = 100;
384
+ exports.default = BleFitnessMachineDevice;
@@ -1,7 +1,7 @@
1
1
  import BleAdapter from '../base/adapter';
2
- import BleHrmDevice from './comm';
2
+ import BleHrmDevice from './sensor';
3
3
  import { IncyclistAdapterData, IAdapter, DeviceProperties } from '../../types';
4
- import { BleDeviceSettings } from '../types';
4
+ import { BleDeviceSettings, IBlePeripheral } from '../types';
5
5
  import { HrmData } from './types';
6
6
  import { LegacyProfile } from '../../antv2/types';
7
7
  export default class HrmAdapter extends BleAdapter<HrmData, BleHrmDevice> {
@@ -9,7 +9,7 @@ export default class HrmAdapter extends BleAdapter<HrmData, BleHrmDevice> {
9
9
  ignore: boolean;
10
10
  constructor(settings: BleDeviceSettings, props?: DeviceProperties);
11
11
  isSame(device: IAdapter): boolean;
12
- getName(): string;
12
+ updateSensor(peripheral: IBlePeripheral): void;
13
13
  getDisplayName(): string;
14
14
  mapData(deviceData: HrmData): IncyclistAdapterData;
15
15
  }
@@ -5,17 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const gd_eventlog_1 = require("gd-eventlog");
7
7
  const adapter_1 = __importDefault(require("../base/adapter"));
8
- const comm_1 = __importDefault(require("./comm"));
8
+ const sensor_1 = __importDefault(require("./sensor"));
9
9
  const types_1 = require("../../types");
10
10
  class HrmAdapter extends adapter_1.default {
11
11
  constructor(settings, props) {
12
12
  super(settings, props);
13
13
  this.ignore = false;
14
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 });
15
+ this.device = new sensor_1.default(this.getPeripheral(), { logger: this.logger });
19
16
  this.capabilities = [
20
17
  types_1.IncyclistCapability.HeartRate
21
18
  ];
@@ -25,11 +22,11 @@ class HrmAdapter extends adapter_1.default {
25
22
  return false;
26
23
  return this.isEqual(device.settings);
27
24
  }
28
- getName() {
29
- return `${this.device.name}`;
25
+ updateSensor(peripheral) {
26
+ this.device = new sensor_1.default(peripheral, { logger: this.logger });
30
27
  }
31
28
  getDisplayName() {
32
- const { name } = this.device;
29
+ const name = this.getName();
33
30
  const { heartrate: hrm } = this.deviceData;
34
31
  const hrmStr = hrm ? ` (${hrm})` : '';
35
32
  return `${name}${hrmStr}`;
@@ -1,5 +1,5 @@
1
1
  import { LegacyProfile } from '../../antv2/types';
2
- import { BleComms } from '../base/comms';
2
+ import { BleComms } from '../base/sensor';
3
3
  import { BleProtocol } from '../types';
4
4
  import { HrmData } from './types';
5
5
  export default class BleHrmDevice extends BleComms {
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const comms_1 = require("../base/comms");
3
+ const sensor_1 = require("../base/sensor");
4
4
  const consts_1 = require("../consts");
5
5
  const utils_1 = require("../utils");
6
- class BleHrmDevice extends comms_1.BleComms {
6
+ class BleHrmDevice extends sensor_1.BleComms {
7
7
  constructor(props) {
8
8
  super(props);
9
9
  this.heartrate = undefined;
@@ -1,4 +1,4 @@
1
1
  import { HrmData } from './types';
2
2
  import BleHrmAdapter from './adapter';
3
- import BleHrmComms from './comm';
3
+ import BleHrmComms from './sensor';
4
4
  export { HrmData, BleHrmAdapter, BleHrmComms };
@@ -6,5 +6,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.BleHrmComms = exports.BleHrmAdapter = void 0;
7
7
  const adapter_1 = __importDefault(require("./adapter"));
8
8
  exports.BleHrmAdapter = adapter_1.default;
9
- const comm_1 = __importDefault(require("./comm"));
10
- exports.BleHrmComms = comm_1.default;
9
+ const sensor_1 = __importDefault(require("./sensor"));
10
+ exports.BleHrmComms = sensor_1.default;
@@ -0,0 +1,17 @@
1
+ import { LegacyProfile } from '../../antv2/types';
2
+ import { TBleSensor } from '../base/sensor';
3
+ import { BleProtocol } from '../types';
4
+ import { HrmData } from './types';
5
+ export default class BleHrmDevice extends TBleSensor {
6
+ static readonly profile: LegacyProfile;
7
+ static readonly protocol: BleProtocol;
8
+ static readonly services: string[];
9
+ static readonly characteristics: string[];
10
+ static readonly detectionPriority = 1;
11
+ protected heartrate: number;
12
+ protected rr: number;
13
+ parseHrm(_data: Uint8Array): HrmData;
14
+ reset(): void;
15
+ protected getRequiredCharacteristics(): Array<string>;
16
+ onData(characteristic: string, data: Buffer): boolean;
17
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const sensor_1 = require("../base/sensor");
4
+ const consts_1 = require("../consts");
5
+ const utils_1 = require("../utils");
6
+ class BleHrmDevice extends sensor_1.TBleSensor {
7
+ parseHrm(_data) {
8
+ const data = Buffer.from(_data);
9
+ try {
10
+ const flags = data.readUInt8(0);
11
+ let offset = 2;
12
+ if (flags % 1 === 0) {
13
+ this.heartrate = data.readUInt8(1);
14
+ }
15
+ else {
16
+ this.heartrate = data.readUInt16LE(1);
17
+ offset = 3;
18
+ }
19
+ if (flags % 0xF) {
20
+ this.rr = (data.readUInt16LE(offset)) / 1024;
21
+ }
22
+ }
23
+ catch (err) {
24
+ }
25
+ const { heartrate, rr } = this;
26
+ return { heartrate, rr, raw: data.toString('hex') };
27
+ }
28
+ reset() {
29
+ delete this.heartrate;
30
+ delete this.rr;
31
+ }
32
+ getRequiredCharacteristics() {
33
+ return [consts_1.HR_MEASUREMENT];
34
+ }
35
+ onData(characteristic, data) {
36
+ const hasData = super.onData(characteristic, data);
37
+ if (!hasData)
38
+ return;
39
+ if ((0, utils_1.matches)(characteristic, consts_1.HR_MEASUREMENT)) {
40
+ const res = this.parseHrm(data);
41
+ this.emit('data', res);
42
+ return false;
43
+ }
44
+ return true;
45
+ }
46
+ }
47
+ BleHrmDevice.profile = 'Heartrate Monitor';
48
+ BleHrmDevice.protocol = 'hr';
49
+ BleHrmDevice.services = ['180d'];
50
+ BleHrmDevice.characteristics = [consts_1.HR_MEASUREMENT, '2a38', '2a39', '2a3c'];
51
+ BleHrmDevice.detectionPriority = 1;
52
+ exports.default = BleHrmDevice;
@@ -1,9 +1,10 @@
1
- import BleInterface from './ble-interface';
2
- import BleAdapterFactory from './adapter-factory';
3
1
  import { BleHrmAdapter } from './hr';
4
2
  import { BlePwrAdapter } from './cp';
5
3
  import { BleFmAdapter } from './fm';
6
4
  import { BleWahooAdapter } from './wahoo';
7
5
  import { BleTacxAdapter } from './tacx';
8
6
  import { BleDeviceSettings, BleInterfaceProps } from './types';
9
- export { BleAdapterFactory, BleInterface, BleInterfaceProps, BleDeviceSettings, BleHrmAdapter, BlePwrAdapter, BleFmAdapter, BleWahooAdapter, BleTacxAdapter };
7
+ import { BleInterface } from '../ble/base/interface';
8
+ import { BleMultiTransportInterfaceFactory, BleAdapterFactory } from './factories';
9
+ export * from './utils';
10
+ export { BleAdapterFactory, BleMultiTransportInterfaceFactory as BleInterfaceFactory, BleInterface, BleInterfaceProps, BleDeviceSettings, BleHrmAdapter, BlePwrAdapter, BleFmAdapter, BleWahooAdapter, BleTacxAdapter };
package/lib/ble/index.js CHANGED
@@ -1,13 +1,20 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
4
15
  };
5
16
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.BleTacxAdapter = exports.BleWahooAdapter = exports.BleFmAdapter = exports.BlePwrAdapter = exports.BleHrmAdapter = exports.BleInterface = exports.BleAdapterFactory = void 0;
7
- const ble_interface_1 = __importDefault(require("./ble-interface"));
8
- exports.BleInterface = ble_interface_1.default;
9
- const adapter_factory_1 = __importDefault(require("./adapter-factory"));
10
- exports.BleAdapterFactory = adapter_factory_1.default;
17
+ exports.BleTacxAdapter = exports.BleWahooAdapter = exports.BleFmAdapter = exports.BlePwrAdapter = exports.BleHrmAdapter = exports.BleInterface = exports.BleInterfaceFactory = exports.BleAdapterFactory = void 0;
11
18
  const hr_1 = require("./hr");
12
19
  Object.defineProperty(exports, "BleHrmAdapter", { enumerable: true, get: function () { return hr_1.BleHrmAdapter; } });
13
20
  const cp_1 = require("./cp");
@@ -18,9 +25,18 @@ const wahoo_1 = require("./wahoo");
18
25
  Object.defineProperty(exports, "BleWahooAdapter", { enumerable: true, get: function () { return wahoo_1.BleWahooAdapter; } });
19
26
  const tacx_1 = require("./tacx");
20
27
  Object.defineProperty(exports, "BleTacxAdapter", { enumerable: true, get: function () { return tacx_1.BleTacxAdapter; } });
21
- const af = adapter_factory_1.default.getInstance();
22
- af.register('hr', hr_1.BleHrmAdapter, hr_1.BleHrmComms);
23
- af.register('cp', cp_1.BlePwrAdapter, cp_1.BlePwrComms);
24
- af.register('fm', fm_1.BleFmAdapter, fm_1.BleFmComms);
25
- af.register('wahoo', wahoo_1.BleWahooAdapter, wahoo_1.BleWahooComms);
26
- af.register('tacx', tacx_1.BleTacxAdapter, tacx_1.BleTacxComms);
28
+ const interface_1 = require("../ble/base/interface");
29
+ Object.defineProperty(exports, "BleInterface", { enumerable: true, get: function () { return interface_1.BleInterface; } });
30
+ const factories_1 = require("./factories");
31
+ Object.defineProperty(exports, "BleInterfaceFactory", { enumerable: true, get: function () { return factories_1.BleMultiTransportInterfaceFactory; } });
32
+ Object.defineProperty(exports, "BleAdapterFactory", { enumerable: true, get: function () { return factories_1.BleAdapterFactory; } });
33
+ ['ble', 'wifi'].forEach(i => {
34
+ const af = factories_1.BleAdapterFactory.getInstance(i);
35
+ af.register('hr', hr_1.BleHrmAdapter, hr_1.BleHrmComms);
36
+ af.register('cp', cp_1.BlePwrAdapter, cp_1.BlePwrComms);
37
+ af.register('fm', fm_1.BleFmAdapter, fm_1.BleFmComms);
38
+ af.register('wahoo', wahoo_1.BleWahooAdapter, wahoo_1.BleWahooComms);
39
+ af.register('tacx', tacx_1.BleTacxAdapter, tacx_1.BleTacxComms);
40
+ });
41
+ factories_1.BleMultiTransportInterfaceFactory.register('ble', interface_1.BleInterfaceFactory);
42
+ __exportStar(require("./utils"), exports);
@@ -1,11 +1,13 @@
1
1
  import { BleFmAdapter } from '../fm';
2
- import { BleDeviceSettings, BleStartProperties } from '../types';
2
+ import { BleDeviceSettings, BleStartProperties, IBlePeripheral } from '../types';
3
3
  import { DeviceProperties, IAdapter } from '../../types';
4
4
  import { LegacyProfile } from '../../antv2/types';
5
5
  export default class BleTacxAdapter extends BleFmAdapter {
6
6
  protected static INCYCLIST_PROFILE_NAME: LegacyProfile;
7
7
  constructor(settings: BleDeviceSettings, props?: DeviceProperties);
8
8
  isSame(device: IAdapter): boolean;
9
+ updateSensor(peripheral: IBlePeripheral): void;
9
10
  getProfile(): LegacyProfile;
10
- start(props?: BleStartProperties): Promise<any>;
11
+ protected initControl(props?: BleStartProperties): Promise<void>;
12
+ protected checkCapabilities(): void;
11
13
  }