incyclist-devices 2.3.0-beta.2 → 2.3.0-beta.20

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 (75) hide show
  1. package/README.MD +55 -0
  2. package/lib/antv2/base/adapter.d.ts +2 -2
  3. package/lib/base/adpater.d.ts +4 -0
  4. package/lib/base/adpater.js +16 -2
  5. package/lib/ble/adapter-factory.d.ts +24 -20
  6. package/lib/ble/adapter-factory.js +36 -13
  7. package/lib/ble/base/adapter.d.ts +6 -3
  8. package/lib/ble/base/adapter.js +72 -38
  9. package/lib/ble/base/comms.d.ts +74 -2
  10. package/lib/ble/base/comms.js +596 -3
  11. package/lib/ble/base/interface.d.ts +14 -5
  12. package/lib/ble/base/interface.js +125 -66
  13. package/lib/ble/base/peripheral.d.ts +7 -3
  14. package/lib/ble/base/peripheral.js +76 -22
  15. package/lib/ble/base/sensor.d.ts +1 -1
  16. package/lib/ble/base/sensor.js +17 -3
  17. package/lib/ble/ble-interface.d.ts +4 -7
  18. package/lib/ble/ble-interface.js +2 -16
  19. package/lib/ble/ble-peripheral.d.ts +0 -1
  20. package/lib/ble/ble-peripheral.js +11 -7
  21. package/lib/ble/characteristics/csc/features.d.ts +10 -0
  22. package/lib/ble/characteristics/csc/features.js +19 -0
  23. package/lib/ble/characteristics/csc/measurement.d.ts +33 -0
  24. package/lib/ble/characteristics/csc/measurement.js +109 -0
  25. package/lib/ble/characteristics/types.d.ts +6 -0
  26. package/lib/ble/characteristics/types.js +2 -0
  27. package/lib/ble/consts.d.ts +1 -0
  28. package/lib/ble/consts.js +2 -1
  29. package/lib/ble/cp/comm.d.ts +1 -1
  30. package/lib/ble/cp/comm.js +2 -2
  31. package/lib/ble/csc/adapter.d.ts +17 -0
  32. package/lib/ble/csc/adapter.js +66 -0
  33. package/lib/ble/csc/index.d.ts +3 -0
  34. package/lib/ble/csc/index.js +19 -0
  35. package/lib/ble/csc/sensor.d.ts +21 -0
  36. package/lib/ble/csc/sensor.js +64 -0
  37. package/lib/ble/csc/types.d.ts +6 -0
  38. package/lib/ble/csc/types.js +2 -0
  39. package/lib/ble/elite/comms.d.ts +1 -1
  40. package/lib/ble/elite/comms.js +2 -2
  41. package/lib/ble/fm/adapter.d.ts +4 -3
  42. package/lib/ble/fm/adapter.js +53 -49
  43. package/lib/ble/fm/comms.d.ts +1 -1
  44. package/lib/ble/fm/comms.js +3 -3
  45. package/lib/ble/fm/sensor.d.ts +1 -1
  46. package/lib/ble/fm/sensor.js +6 -5
  47. package/lib/ble/hr/comm.d.ts +1 -1
  48. package/lib/ble/hr/comm.js +2 -2
  49. package/lib/ble/index.js +2 -0
  50. package/lib/ble/tacx/adapter.d.ts +1 -1
  51. package/lib/ble/tacx/adapter.js +12 -10
  52. package/lib/ble/tacx/comms.d.ts +1 -1
  53. package/lib/ble/tacx/comms.js +2 -2
  54. package/lib/ble/tacx/sensor.js +9 -3
  55. package/lib/ble/types.d.ts +8 -2
  56. package/lib/ble/utils.d.ts +1 -0
  57. package/lib/ble/utils.js +5 -1
  58. package/lib/ble/wahoo/adapter.d.ts +1 -0
  59. package/lib/ble/wahoo/adapter.js +14 -0
  60. package/lib/ble/wahoo/comms.d.ts +1 -1
  61. package/lib/ble/wahoo/comms.js +2 -2
  62. package/lib/ble/wahoo/sensor.js +3 -6
  63. package/lib/direct-connect/base/interface.d.ts +1 -0
  64. package/lib/direct-connect/base/interface.js +9 -4
  65. package/lib/direct-connect/base/peripheral.d.ts +4 -4
  66. package/lib/direct-connect/base/peripheral.js +106 -31
  67. package/lib/direct-connect/messages/message.d.ts +1 -0
  68. package/lib/direct-connect/messages/message.js +16 -1
  69. package/lib/modes/ant-fe-adv-st-mode.d.ts +7 -1
  70. package/lib/modes/ant-fe-adv-st-mode.js +4 -3
  71. package/lib/types/adapter.d.ts +3 -0
  72. package/lib/types/interface.d.ts +1 -0
  73. package/lib/utils/task.d.ts +3 -0
  74. package/lib/utils/task.js +12 -0
  75. package/package.json +1 -1
@@ -20,11 +20,12 @@ const sensor_1 = __importDefault(require("./sensor"));
20
20
  const adapter_1 = __importDefault(require("../base/adapter"));
21
21
  const consts_1 = require("./consts");
22
22
  const types_1 = require("../../types");
23
- const task_1 = require("../../utils/task");
23
+ const utils_1 = require("../../utils/utils");
24
24
  class BleFmAdapter extends adapter_1.default {
25
25
  constructor(settings, props) {
26
26
  super(settings, props);
27
27
  this.distanceInternal = 0;
28
+ this.requestControlRetryDelay = 1000;
28
29
  this.logger = new gd_eventlog_1.EventLogger('BLE-FM');
29
30
  this.device = new sensor_1.default(this.getPeripheral(), { logger: this.logger });
30
31
  this.capabilities = [
@@ -46,7 +47,7 @@ class BleFmAdapter extends adapter_1.default {
46
47
  getSupportedCyclingModes() {
47
48
  var _a;
48
49
  const modes = [power_meter_1.default];
49
- const features = (_a = this.getComms()) === null || _a === void 0 ? void 0 : _a.features;
50
+ const features = (_a = this.getSensor()) === null || _a === void 0 ? void 0 : _a.features;
50
51
  if (!features)
51
52
  return [power_meter_1.default, antble_smarttrainer_1.default, antble_erg_1.default];
52
53
  if (features.setPower === undefined || features.setPower)
@@ -57,7 +58,7 @@ class BleFmAdapter extends adapter_1.default {
57
58
  }
58
59
  getDefaultCyclingMode() {
59
60
  var _a;
60
- const features = (_a = this.getComms()) === null || _a === void 0 ? void 0 : _a.features;
61
+ const features = (_a = this.getSensor()) === null || _a === void 0 ? void 0 : _a.features;
61
62
  if (!features)
62
63
  return new antble_smarttrainer_1.default(this);
63
64
  if (features.setSlope === undefined || features.setSlope)
@@ -117,15 +118,16 @@ class BleFmAdapter extends adapter_1.default {
117
118
  }
118
119
  initControl(_startProps) {
119
120
  return __awaiter(this, void 0, void 0, function* () {
121
+ if (!this.isStarting())
122
+ return;
120
123
  this.setConstants();
121
124
  yield this.establishControl();
122
- this.setConstants();
123
125
  yield this.sendInitialRequest();
124
126
  });
125
127
  }
126
128
  setConstants() {
127
129
  const mode = this.getCyclingMode();
128
- const sensor = this.getComms();
130
+ const sensor = this.getSensor();
129
131
  if (mode === null || mode === void 0 ? void 0 : mode.getSetting('bikeType')) {
130
132
  const bikeType = mode.getSetting('bikeType').toLowerCase();
131
133
  sensor.setCrr(consts_1.cRR);
@@ -146,38 +148,30 @@ class BleFmAdapter extends adapter_1.default {
146
148
  return __awaiter(this, void 0, void 0, function* () {
147
149
  if (!this.isStarting())
148
150
  return false;
149
- let waitTask;
150
- let iv;
151
- const sensor = this.getComms();
152
- const wait = () => {
153
- const res = new Promise((resolve) => {
154
- iv = setInterval(() => __awaiter(this, void 0, void 0, function* () {
155
- if (!this.isStarting() || !(waitTask === null || waitTask === void 0 ? void 0 : waitTask.isRunning)) {
156
- resolve(false);
157
- clearInterval(iv);
158
- return;
151
+ let hasControl = false;
152
+ let tryCnt = 0;
153
+ const sensor = this.getSensor();
154
+ return new Promise((resolve) => {
155
+ this.startTask.notifyOnStop(() => {
156
+ resolve(false);
157
+ });
158
+ const waitUntilControl = () => __awaiter(this, void 0, void 0, function* () {
159
+ while (!hasControl && this.isStarting()) {
160
+ if (tryCnt++ === 0) {
161
+ this.logEvent({ message: 'requesting control', device: this.getName(), interface: this.getInterface() });
159
162
  }
160
- const hasControl = yield sensor.requestControl();
163
+ hasControl = yield sensor.requestControl();
161
164
  if (hasControl) {
162
- clearInterval(iv);
163
- resolve(true);
165
+ this.logEvent({ message: 'control granted', device: this.getName(), interface: this.getInterface() });
166
+ resolve(this.isStarting());
164
167
  }
165
- else if (!this.isStarting() || !(waitTask === null || waitTask === void 0 ? void 0 : waitTask.isRunning)) {
166
- resolve(false);
167
- clearInterval(iv);
168
+ else {
169
+ yield (0, utils_1.sleep)(this.requestControlRetryDelay);
168
170
  }
169
- }), 1000);
171
+ }
170
172
  });
171
- return res;
172
- };
173
- waitTask = new task_1.InteruptableTask(wait(), {
174
- errorOnTimeout: false,
175
- timeout: 10000
173
+ waitUntilControl();
176
174
  });
177
- const hasControl = yield waitTask.run();
178
- clearInterval(iv);
179
- if (!hasControl && this.isStarting())
180
- throw new Error('could not establish control');
181
175
  });
182
176
  }
183
177
  sendInitialRequest() {
@@ -187,23 +181,33 @@ class BleFmAdapter extends adapter_1.default {
187
181
  });
188
182
  }
189
183
  checkCapabilities() {
190
- var _a, _b, _c;
191
- const before = this.capabilities.join(',');
192
- const sensor = this.getComms();
193
- if (((_a = sensor.features) === null || _a === void 0 ? void 0 : _a.heartrate) && !this.hasCapability(types_1.IncyclistCapability.HeartRate)) {
194
- this.capabilities.push(types_1.IncyclistCapability.HeartRate);
195
- }
196
- if (((_b = sensor.features) === null || _b === void 0 ? void 0 : _b.cadence) && !this.hasCapability(types_1.IncyclistCapability.Cadence)) {
197
- this.capabilities.push(types_1.IncyclistCapability.Cadence);
198
- }
199
- if (((_c = sensor.features) === null || _c === void 0 ? void 0 : _c.power) && !this.hasCapability(types_1.IncyclistCapability.Power)) {
200
- this.capabilities.push(types_1.IncyclistCapability.Power);
201
- }
202
- const after = this.capabilities.join(',');
203
- if (before !== after) {
204
- this.logEvent({ message: 'device capabilities updated', name: this.getSettings().name, interface: this.getSettings().interface, capabilities: this.capabilities });
205
- this.emit('device-info', this.getSettings(), { capabilities: this.capabilities });
206
- }
184
+ return __awaiter(this, void 0, void 0, function* () {
185
+ var _a, _b, _c;
186
+ const before = this.capabilities.join(',');
187
+ const sensor = this.getSensor();
188
+ if (!sensor.features) {
189
+ try {
190
+ yield sensor.getFitnessMachineFeatures();
191
+ }
192
+ catch (err) {
193
+ this.logEvent({ message: 'error getting fitness machine features', device: this.getName(), interface: this.getInterface(), error: err });
194
+ }
195
+ }
196
+ if (((_a = sensor.features) === null || _a === void 0 ? void 0 : _a.heartrate) && !this.hasCapability(types_1.IncyclistCapability.HeartRate)) {
197
+ this.capabilities.push(types_1.IncyclistCapability.HeartRate);
198
+ }
199
+ if (((_b = sensor.features) === null || _b === void 0 ? void 0 : _b.cadence) && !this.hasCapability(types_1.IncyclistCapability.Cadence)) {
200
+ this.capabilities.push(types_1.IncyclistCapability.Cadence);
201
+ }
202
+ if (((_c = sensor.features) === null || _c === void 0 ? void 0 : _c.power) && !this.hasCapability(types_1.IncyclistCapability.Power)) {
203
+ this.capabilities.push(types_1.IncyclistCapability.Power);
204
+ }
205
+ const after = this.capabilities.join(',');
206
+ if (before !== after) {
207
+ this.logEvent({ message: 'device capabilities updated', name: this.getSettings().name, interface: this.getSettings().interface, capabilities: this.capabilities });
208
+ this.emit('device-info', this.getSettings(), { capabilities: this.capabilities });
209
+ }
210
+ });
207
211
  }
208
212
  sendUpdate(request_1) {
209
213
  return __awaiter(this, arguments, void 0, function* (request, enforced = false) {
@@ -212,7 +216,7 @@ class BleFmAdapter extends adapter_1.default {
212
216
  try {
213
217
  const update = this.getCyclingMode().sendBikeUpdate(request);
214
218
  this.logEvent({ message: 'send bike update requested', profile: this.getProfile(), update, request });
215
- const device = this.device;
219
+ const device = this.getSensor();
216
220
  if (update.slope !== undefined) {
217
221
  yield device.setSlope(update.slope);
218
222
  }
@@ -1,6 +1,6 @@
1
1
  import { BleProtocol, BleWriteProps, IBlePeripheralConnector } from "../types";
2
2
  import { IndoorBikeData, IndoorBikeFeatures } from "./types";
3
- import { BleComms } from "../base/sensor";
3
+ import { BleComms } from "../base/comms";
4
4
  import { LegacyProfile } from "../../antv2/types";
5
5
  export default class BleFitnessMachineDevice extends BleComms {
6
6
  static protocol: BleProtocol;
@@ -10,7 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const consts_1 = require("../consts");
13
- const sensor_1 = require("../base/sensor");
13
+ const comms_1 = require("../base/comms");
14
14
  const utils_1 = require("../utils");
15
15
  const bit = (nr) => (1 << nr);
16
16
  const IndoorBikeDataFlag = {
@@ -66,7 +66,7 @@ const TargetSettingFeatureFlag = {
66
66
  SpinDownControlSupported: bit(15),
67
67
  TargetedCadenceConfigurationSupported: bit(16)
68
68
  };
69
- class BleFitnessMachineDevice extends sensor_1.BleComms {
69
+ class BleFitnessMachineDevice extends comms_1.BleComms {
70
70
  constructor(props) {
71
71
  super(props);
72
72
  this.features = undefined;
@@ -92,7 +92,7 @@ class BleFitnessMachineDevice extends sensor_1.BleComms {
92
92
  subscribeWriteResponse(cuuid) {
93
93
  return __awaiter(this, void 0, void 0, function* () {
94
94
  this.logEvent({ message: 'subscribe to CP response', characteristics: cuuid });
95
- const connector = this.getPeripheral();
95
+ const connector = this.ble.peripheralCache.getConnector(this.peripheral);
96
96
  const isAlreadySubscribed = connector.isSubscribed(cuuid);
97
97
  if (!isAlreadySubscribed) {
98
98
  connector.removeAllListeners(cuuid);
@@ -34,7 +34,7 @@ export default class BleFitnessMachineDevice extends TBleSensor {
34
34
  protected parseHrm(_data: Uint8Array): IndoorBikeData;
35
35
  protected parseIndoorBikeData(_data: Uint8Array): IndoorBikeData;
36
36
  protected parseFitnessMachineStatus(_data: Uint8Array): IndoorBikeData;
37
- protected getFitnessMachineFeatures(): Promise<IndoorBikeFeatures | undefined>;
37
+ getFitnessMachineFeatures(): Promise<IndoorBikeFeatures | undefined>;
38
38
  protected writeFtmsMessage(requestedOpCode: any, data: any, props?: BleWriteProps): Promise<number>;
39
39
  setTargetInclination(inclination: number): Promise<boolean>;
40
40
  setIndoorBikeSimulation(windSpeed: number, gradient: number, crr: number, cw: number): Promise<boolean>;
@@ -100,8 +100,6 @@ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
100
100
  this.logEvent({ message: 'setTargetPower', power, skip: (this.data.targetPower !== undefined && this.data.targetPower === power) });
101
101
  if (this.data.targetPower !== undefined && this.data.targetPower === power)
102
102
  return true;
103
- if (!this.hasControl)
104
- return;
105
103
  const hasControl = yield this.requestControl();
106
104
  if (!hasControl) {
107
105
  this.logEvent({ message: 'setTargetPower failed', reason: 'control is disabled' });
@@ -111,15 +109,15 @@ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
111
109
  data.writeUInt8(5, 0);
112
110
  data.writeInt16LE(Math.round(power), 1);
113
111
  const res = yield this.writeFtmsMessage(5, data);
112
+ if (res === 5) {
113
+ this.hasControl = false;
114
+ }
114
115
  return (res === 1);
115
116
  });
116
117
  }
117
118
  setSlope(slope) {
118
119
  return __awaiter(this, void 0, void 0, function* () {
119
120
  this.logEvent({ message: 'setSlope', slope });
120
- const hasControl = yield this.requestControl();
121
- if (!hasControl)
122
- return;
123
121
  const { windSpeed, crr, cw } = this;
124
122
  return yield this.setIndoorBikeSimulation(windSpeed, slope, crr, cw);
125
123
  });
@@ -331,6 +329,9 @@ class BleFitnessMachineDevice extends sensor_1.TBleSensor {
331
329
  data.writeUInt8(Math.round(crr * 10000), 5);
332
330
  data.writeUInt8(Math.round(cw * 100), 6);
333
331
  const res = yield this.writeFtmsMessage(17, data);
332
+ if (res === 5) {
333
+ this.hasControl = false;
334
+ }
334
335
  return (res === 1);
335
336
  });
336
337
  }
@@ -1,5 +1,5 @@
1
1
  import { LegacyProfile } from '../../antv2/types';
2
- import { BleComms } from '../base/sensor';
2
+ import { BleComms } from '../base/comms';
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 sensor_1 = require("../base/sensor");
3
+ const comms_1 = require("../base/comms");
4
4
  const consts_1 = require("../consts");
5
5
  const utils_1 = require("../utils");
6
- class BleHrmDevice extends sensor_1.BleComms {
6
+ class BleHrmDevice extends comms_1.BleComms {
7
7
  constructor(props) {
8
8
  super(props);
9
9
  this.heartrate = undefined;
package/lib/ble/index.js CHANGED
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "BleInterface", { enumerable: true, get: function
30
30
  const factories_1 = require("./factories");
31
31
  Object.defineProperty(exports, "BleInterfaceFactory", { enumerable: true, get: function () { return factories_1.BleMultiTransportInterfaceFactory; } });
32
32
  Object.defineProperty(exports, "BleAdapterFactory", { enumerable: true, get: function () { return factories_1.BleAdapterFactory; } });
33
+ const csc_1 = require("./csc");
33
34
  ['ble', 'wifi'].forEach(i => {
34
35
  const af = factories_1.BleAdapterFactory.getInstance(i);
35
36
  af.register('hr', hr_1.BleHrmAdapter, hr_1.BleHrmComms);
@@ -37,6 +38,7 @@ Object.defineProperty(exports, "BleAdapterFactory", { enumerable: true, get: fun
37
38
  af.register('fm', fm_1.BleFmAdapter, fm_1.BleFmComms);
38
39
  af.register('wahoo', wahoo_1.BleWahooAdapter, wahoo_1.BleWahooComms);
39
40
  af.register('tacx', tacx_1.BleTacxAdapter, tacx_1.BleTacxComms);
41
+ af.register('csc', csc_1.BleCSCAdapter, csc_1.BleCyclingSpeedCadenceDevice);
40
42
  });
41
43
  factories_1.BleMultiTransportInterfaceFactory.register('ble', interface_1.BleInterfaceFactory);
42
44
  __exportStar(require("./utils"), exports);
@@ -9,5 +9,5 @@ export default class BleTacxAdapter extends BleFmAdapter {
9
9
  updateSensor(peripheral: IBlePeripheral): void;
10
10
  getProfile(): LegacyProfile;
11
11
  protected initControl(props?: BleStartProperties): Promise<void>;
12
- protected checkCapabilities(): void;
12
+ protected checkCapabilities(): Promise<void>;
13
13
  }
@@ -41,7 +41,7 @@ class BleTacxAdapter extends fm_1.BleFmAdapter {
41
41
  initControl(props) {
42
42
  return __awaiter(this, void 0, void 0, function* () {
43
43
  var _a;
44
- const sensor = this.getComms();
44
+ const sensor = this.getSensor();
45
45
  const { user, wheelDiameter, gearRatio, bikeWeight = consts_1.DEFAULT_BIKE_WEIGHT } = props || {};
46
46
  const userWeight = ((_a = user === null || user === void 0 ? void 0 : user.weight) !== null && _a !== void 0 ? _a : consts_1.DEFAULT_USER_WEIGHT);
47
47
  sensor.sendTrackResistance(0.0);
@@ -51,15 +51,17 @@ class BleTacxAdapter extends fm_1.BleFmAdapter {
51
51
  });
52
52
  }
53
53
  checkCapabilities() {
54
- const before = this.capabilities.join(',');
55
- const sensor = this.getComms();
56
- if (sensor.features && sensor.features.heartrate && !this.hasCapability(types_1.IncyclistCapability.HeartRate)) {
57
- this.capabilities.push(types_1.IncyclistCapability.HeartRate);
58
- }
59
- const after = this.capabilities.join(',');
60
- if (before !== after) {
61
- this.emit('device-info', this.getSettings(), { capabilities: this.capabilities });
62
- }
54
+ return __awaiter(this, void 0, void 0, function* () {
55
+ const before = this.capabilities.join(',');
56
+ const sensor = this.getSensor();
57
+ if (sensor.features && sensor.features.heartrate && !this.hasCapability(types_1.IncyclistCapability.HeartRate)) {
58
+ this.capabilities.push(types_1.IncyclistCapability.HeartRate);
59
+ }
60
+ const after = this.capabilities.join(',');
61
+ if (before !== after) {
62
+ this.emit('device-info', this.getSettings(), { capabilities: this.capabilities });
63
+ }
64
+ });
63
65
  }
64
66
  }
65
67
  BleTacxAdapter.INCYCLIST_PROFILE_NAME = 'Smart Trainer';
@@ -1,7 +1,7 @@
1
1
  import { LegacyProfile } from "../../antv2/types";
2
2
  import { CrankData } from "../cp";
3
3
  import { IndoorBikeData } from "../fm";
4
- import BleFitnessMachineDevice from "../fm/sensor";
4
+ import BleFitnessMachineDevice from "../fm/comms";
5
5
  import { BleProtocol, IBlePeripheralConnector } from "../types";
6
6
  import { BleFeBikeData } from "./types";
7
7
  export default class TacxAdvancedFitnessMachineDevice extends BleFitnessMachineDevice {
@@ -13,7 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const consts_1 = require("../consts");
16
- const sensor_1 = __importDefault(require("../fm/sensor"));
16
+ const comms_1 = __importDefault(require("../fm/comms"));
17
17
  const utils_1 = require("../utils");
18
18
  var ANTMessages;
19
19
  (function (ANTMessages) {
@@ -37,7 +37,7 @@ const PROFILE_ID = 'Tacx SmartTrainer';
37
37
  const SYNC_BYTE = 0xA4;
38
38
  const DEFAULT_CHANNEL = 5;
39
39
  const ACKNOWLEDGED_DATA = 0x4F;
40
- class TacxAdvancedFitnessMachineDevice extends sensor_1.default {
40
+ class TacxAdvancedFitnessMachineDevice extends comms_1.default {
41
41
  constructor(props) {
42
42
  super(props);
43
43
  this.prevCrankData = undefined;
@@ -43,7 +43,7 @@ class TacxAdvancedFitnessMachineDevice extends sensor_1.default {
43
43
  }
44
44
  this.messageCnt++;
45
45
  try {
46
- const uuid = characteristic.toLocaleLowerCase();
46
+ const uuid = (0, utils_1.beautifyUUID)(characteristic).toLowerCase();
47
47
  let res = undefined;
48
48
  if (uuid && (0, utils_1.matches)(uuid, this.tacxRx)) {
49
49
  res = this.parseFECMessage(data);
@@ -452,8 +452,14 @@ class TacxAdvancedFitnessMachineDevice extends sensor_1.default {
452
452
  sendMessage(message) {
453
453
  return __awaiter(this, void 0, void 0, function* () {
454
454
  this.logEvent({ message: 'write', characteristic: this.tacxTx, data: message.toString('hex') });
455
- yield this.write(this.tacxTx, message, { withoutResponse: true });
456
- return true;
455
+ try {
456
+ yield this.write(this.tacxTx, message, { withoutResponse: true });
457
+ return true;
458
+ }
459
+ catch (err) {
460
+ this.logEvent({ message: 'write failed', characteristic: this.tacxTx, reason: err.message });
461
+ return false;
462
+ }
457
463
  });
458
464
  }
459
465
  sendUserConfiguration(userWeight, bikeWeight, wheelDiameter, gearRatio) {
@@ -1,7 +1,7 @@
1
1
  import EventEmitter from "events";
2
2
  import { EventLogger } from "gd-eventlog";
3
3
  import { DeviceProperties, DeviceSettings, DeviceStartProperties, IncyclistInterface, IncyclistScanProps, InterfaceProps } from "../types";
4
- export type BleProtocol = 'hr' | 'fm' | 'cp' | 'tacx' | 'wahoo' | 'elite';
4
+ export type BleProtocol = 'hr' | 'fm' | 'cp' | 'tacx' | 'wahoo' | 'elite' | 'csc';
5
5
  export type BleInterfaceState = 'unknown' | 'resetting' | 'unsupported' | 'unauthorized' | 'poweredOff' | 'poweredOn';
6
6
  export interface BleBinding extends EventEmitter {
7
7
  startScanning(serviceUUIDs?: string[], allowDuplicates?: boolean, callback?: (error?: Error) => void): void;
@@ -13,11 +13,17 @@ export interface BleBinding extends EventEmitter {
13
13
  state: BleInterfaceState;
14
14
  on(eventName: string | symbol, listener: (...args: any[]) => void): this;
15
15
  }
16
+ export interface BleRawAdvertisement {
17
+ address?: string;
18
+ localName?: string;
19
+ serviceUuids?: string[];
20
+ rssi?: number;
21
+ }
16
22
  export interface BleRawPeripheral extends EventEmitter {
17
23
  id?: string;
18
24
  address?: string;
19
25
  name?: string;
20
- services: [];
26
+ services: any[];
21
27
  advertisement: any;
22
28
  state: string;
23
29
  connectAsync(): Promise<void>;
@@ -19,4 +19,5 @@ export declare const beautifyUUID: (str: string, withX?: boolean) => string;
19
19
  export declare const fullUUID: (str: string) => string;
20
20
  export declare const propertyVal: (properties: BleProperty[]) => number;
21
21
  export declare const propertyFromVal: (val: number) => BleProperty[];
22
+ export declare const bit: (nr: any) => number;
22
23
  export {};
package/lib/ble/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.propertyFromVal = exports.propertyVal = exports.fullUUID = exports.beautifyUUID = exports.parseUUID = void 0;
3
+ exports.bit = exports.propertyFromVal = exports.propertyVal = exports.fullUUID = exports.beautifyUUID = exports.parseUUID = void 0;
4
4
  exports.mapLegacyProfile = mapLegacyProfile;
5
5
  exports.uuid = uuid;
6
6
  exports.matches = matches;
@@ -138,3 +138,7 @@ const propertyFromVal = (val) => {
138
138
  return res;
139
139
  };
140
140
  exports.propertyFromVal = propertyFromVal;
141
+ const bit = (nr) => {
142
+ return (1 << nr);
143
+ };
144
+ exports.bit = bit;
@@ -8,4 +8,5 @@ export default class BleWahooAdapter extends BleFmAdapter {
8
8
  isSame(device: IAdapter): boolean;
9
9
  getProfile(): LegacyProfile;
10
10
  updateSensor(peripheral: IBlePeripheral): void;
11
+ protected checkCapabilities(): Promise<void>;
11
12
  }
@@ -1,4 +1,13 @@
1
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
+ };
2
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
13
  };
@@ -28,6 +37,11 @@ class BleWahooAdapter extends fm_1.BleFmAdapter {
28
37
  updateSensor(peripheral) {
29
38
  this.device = new sensor_1.default(peripheral, { logger: this.logger });
30
39
  }
40
+ checkCapabilities() {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ this.logEvent({ message: 'device capabilities updated', name: this.getSettings().name, interface: this.getSettings().interface, capabilities: this.capabilities });
43
+ });
44
+ }
31
45
  }
32
46
  BleWahooAdapter.INCYCLIST_PROFILE_NAME = 'Smart Trainer';
33
47
  exports.default = BleWahooAdapter;
@@ -1,7 +1,7 @@
1
1
  import { LegacyProfile } from "../../antv2/types";
2
2
  import { CrankData } from "../cp";
3
3
  import { IndoorBikeData } from "../fm";
4
- import BleFitnessMachineDevice from "../fm/sensor";
4
+ import BleFitnessMachineDevice from "../fm/comms";
5
5
  import { BleProtocol, BleWriteProps, IBlePeripheralConnector } from "../types";
6
6
  export declare const enum OpCode {
7
7
  unlock = 32,
@@ -15,10 +15,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const _1 = require(".");
16
16
  const consts_1 = require("../../base/consts");
17
17
  const consts_2 = require("../consts");
18
- const sensor_1 = __importDefault(require("../fm/sensor"));
18
+ const comms_1 = __importDefault(require("../fm/comms"));
19
19
  const utils_1 = require("../utils");
20
20
  const ErgWriteDelay = 2000;
21
- class BleWahooDevice extends sensor_1.default {
21
+ class BleWahooDevice extends comms_1.default {
22
22
  constructor(props) {
23
23
  super(props);
24
24
  this.prevCrankData = undefined;
@@ -43,11 +43,8 @@ class BleWahooDevice extends sensor_1.default {
43
43
  return [consts_2.INDOOR_BIKE_DATA, consts_2.FTMS_STATUS, consts_2.CSP_MEASUREMENT, consts_2.HR_MEASUREMENT];
44
44
  }
45
45
  onData(characteristic, data) {
46
- const hasData = super.onData(characteristic, data);
47
- if (!hasData)
48
- return false;
49
- const uuid = characteristic.toLowerCase();
50
- let res = undefined;
46
+ const uuid = (0, utils_1.beautifyUUID)(characteristic).toLowerCase();
47
+ let res;
51
48
  switch (uuid) {
52
49
  case consts_2.CSP_MEASUREMENT:
53
50
  res = this.parsePower(data);
@@ -62,7 +59,7 @@ class BleWahooDevice extends sensor_1.default {
62
59
  res = this.parseFitnessMachineStatus(data);
63
60
  break;
64
61
  default:
65
- this.logEvent({ message: 'data', uuid, data: data.toString('hex') });
62
+ this.logEvent({ message: 'data', uuid, data: Buffer.from(data).toString('hex') });
66
63
  break;
67
64
  }
68
65
  if (res) {
@@ -29,6 +29,7 @@ export default class DirectConnectInterface extends EventEmitter implements IBle
29
29
  protected connected: boolean;
30
30
  static getInstance(props?: InterfaceProps): DirectConnectInterface;
31
31
  constructor(props: InterfaceProps);
32
+ setProps(props: InterfaceProps): void;
32
33
  createPeripheral(announcement: MulticastDnsAnnouncement): IBlePeripheral;
33
34
  createDeviceSetting(service: MulticastDnsAnnouncement): BleDeviceSettings;
34
35
  createPeripheralFromSettings(settings: DeviceSettings): IBlePeripheral;
@@ -27,6 +27,7 @@ class DirectConnectInterface extends events_1.default {
27
27
  if (DirectConnectInterface._instance === undefined)
28
28
  DirectConnectInterface._instance = new DirectConnectInterface(props);
29
29
  else {
30
+ DirectConnectInterface._instance.setProps(props);
30
31
  if (props.binding) {
31
32
  DirectConnectInterface._instance.setBinding(props.binding);
32
33
  }
@@ -54,9 +55,13 @@ class DirectConnectInterface extends events_1.default {
54
55
  }
55
56
  this.internalEvents = new events_1.default();
56
57
  this.instance = ++instanceId;
57
- if (this.binding)
58
+ const { enabled } = props;
59
+ if (this.binding && (enabled !== null && enabled !== void 0 ? enabled : false))
58
60
  this.autoConnect();
59
61
  }
62
+ setProps(props) {
63
+ this.props = props;
64
+ }
60
65
  createPeripheral(announcement) {
61
66
  return peripheral_1.DirectConnectPeripheral.create(announcement);
62
67
  }
@@ -83,7 +88,7 @@ class DirectConnectInterface extends events_1.default {
83
88
  setBinding(binding) {
84
89
  const prev = this.binding;
85
90
  this.binding = binding;
86
- if (!prev)
91
+ if (!prev && this.props.enabled)
87
92
  this.autoConnect();
88
93
  }
89
94
  getBinding() {
@@ -238,10 +243,10 @@ class DirectConnectInterface extends events_1.default {
238
243
  this.services[idx] = { ts: Date.now(), service };
239
244
  }
240
245
  else {
241
- this.logEvent({ message: 'device announced', device: service.name, announcement: service, source });
242
246
  this.services.push({ ts: Date.now(), service });
243
- if (service.type !== DC_TYPE && ((_a = service.serviceUUIDs) === null || _a === void 0 ? void 0 : _a.length) === 0)
247
+ if (!((_a = service.serviceUUIDs) === null || _a === void 0 ? void 0 : _a.length))
244
248
  return;
249
+ this.logEvent({ message: 'device announced', device: service.name, announcement: service, source });
245
250
  this.emitDevice(service);
246
251
  (_b = this.matching) === null || _b === void 0 ? void 0 : _b.push(service.name);
247
252
  }
@@ -21,24 +21,24 @@ export declare class DirectConnectPeripheral implements IBlePeripheral {
21
21
  constructor(announcement: MulticastDnsAnnouncement);
22
22
  get services(): BleService[];
23
23
  connect(): Promise<boolean>;
24
- disconnect(): Promise<boolean>;
24
+ disconnect(connectionLost?: boolean): Promise<boolean>;
25
25
  isConnected(): boolean;
26
26
  isConnecting(): boolean;
27
27
  onDisconnect(callback: () => void): void;
28
28
  discoverServices(): Promise<string[]>;
29
29
  discoverCharacteristics(serviceUUID: string): Promise<BleCharacteristic[]>;
30
- subscribe(characteristicUUID: string, callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
30
+ subscribe(characteristicUUID: string, callback?: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
31
31
  unsubscribe(characteristicUUID: string): Promise<boolean>;
32
32
  subscribeAll(callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
33
33
  subscribeSelected(characteristics: string[], callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
34
- unsubscribeAll(): Promise<boolean>;
34
+ unsubscribeAll(connectionLost?: boolean): Promise<void>;
35
35
  read(characteristicUUID: string): Promise<Buffer>;
36
36
  write(characteristicUUID: string, data: Buffer, options?: BleWriteProps): Promise<Buffer>;
37
37
  protected startConnection(): Promise<boolean>;
38
38
  protected onPortError(err: Error): void;
39
39
  protected onPortClose(): Promise<void>;
40
40
  protected getPath(): string;
41
- protected stopConnection(): Promise<boolean>;
41
+ protected stopConnection(connectionLost?: boolean): Promise<boolean>;
42
42
  protected getNextSeqNo(): number;
43
43
  protected send(seqNo: number, data: Buffer): Promise<Buffer>;
44
44
  protected getNextMessage(data: Buffer): Buffer;