incyclist-devices 2.3.0 → 2.3.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 (81) 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 +83 -49
  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 +19 -10
  12. package/lib/ble/base/interface.js +148 -73
  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 +2 -1
  16. package/lib/ble/base/sensor.js +22 -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/factories/adapter-factory.d.ts +8 -6
  42. package/lib/ble/factories/adapter-factory.js +33 -0
  43. package/lib/ble/factories/types.d.ts +18 -0
  44. package/lib/ble/factories/types.js +2 -0
  45. package/lib/ble/fm/adapter.d.ts +4 -3
  46. package/lib/ble/fm/adapter.js +53 -48
  47. package/lib/ble/fm/comms.d.ts +1 -1
  48. package/lib/ble/fm/comms.js +3 -3
  49. package/lib/ble/fm/sensor.d.ts +1 -1
  50. package/lib/ble/fm/sensor.js +6 -5
  51. package/lib/ble/hr/comm.d.ts +1 -1
  52. package/lib/ble/hr/comm.js +2 -2
  53. package/lib/ble/index.js +2 -0
  54. package/lib/ble/tacx/adapter.d.ts +1 -1
  55. package/lib/ble/tacx/adapter.js +12 -10
  56. package/lib/ble/tacx/comms.d.ts +1 -1
  57. package/lib/ble/tacx/comms.js +2 -2
  58. package/lib/ble/tacx/sensor.js +9 -3
  59. package/lib/ble/types.d.ts +8 -2
  60. package/lib/ble/utils.d.ts +1 -0
  61. package/lib/ble/utils.js +15 -2
  62. package/lib/ble/wahoo/adapter.d.ts +1 -0
  63. package/lib/ble/wahoo/adapter.js +14 -0
  64. package/lib/ble/wahoo/comms.d.ts +1 -1
  65. package/lib/ble/wahoo/comms.js +2 -2
  66. package/lib/ble/wahoo/sensor.js +3 -6
  67. package/lib/direct-connect/base/interface.d.ts +2 -1
  68. package/lib/direct-connect/base/interface.js +20 -10
  69. package/lib/direct-connect/base/peripheral.d.ts +4 -4
  70. package/lib/direct-connect/base/peripheral.js +181 -68
  71. package/lib/direct-connect/bindings/types.d.ts +2 -1
  72. package/lib/direct-connect/messages/message.d.ts +1 -0
  73. package/lib/direct-connect/messages/message.js +16 -1
  74. package/lib/factories/adapters.js +0 -2
  75. package/lib/modes/ant-fe-adv-st-mode.d.ts +7 -1
  76. package/lib/modes/ant-fe-adv-st-mode.js +4 -3
  77. package/lib/types/adapter.d.ts +3 -0
  78. package/lib/types/interface.d.ts +1 -0
  79. package/lib/utils/task.d.ts +3 -0
  80. package/lib/utils/task.js +12 -0
  81. package/package.json +1 -1
@@ -0,0 +1,66 @@
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
+ exports.BleCSCAdapter = void 0;
16
+ const gd_eventlog_1 = require("gd-eventlog");
17
+ const adapter_1 = __importDefault(require("../base/adapter"));
18
+ const types_1 = require("../../types");
19
+ const sensor_1 = require("./sensor");
20
+ class BleCSCAdapter extends adapter_1.default {
21
+ constructor(settings, props) {
22
+ super(settings, props);
23
+ this.logger = new gd_eventlog_1.EventLogger('Ble-CSC');
24
+ this.device = new sensor_1.BleCyclingSpeedCadenceDevice(this.getPeripheral(), { logger: this.logger });
25
+ this.capabilities = BleCSCAdapter.CAPABILITIES;
26
+ }
27
+ checkCapabilities() {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ const before = this.capabilities.join(',');
30
+ const sensor = this.getSensor();
31
+ if (!sensor)
32
+ return;
33
+ const features = yield sensor.getFeatures();
34
+ if (!(features === null || features === void 0 ? void 0 : features.wheelRevolutionData))
35
+ this.capabilities = this.capabilities.filter(c => c !== types_1.IncyclistCapability.Speed);
36
+ if (!(features === null || features === void 0 ? void 0 : features.crankRevolutionData))
37
+ this.capabilities = this.capabilities.filter(c => c !== types_1.IncyclistCapability.Cadence);
38
+ const after = this.capabilities.join(',');
39
+ if (before !== after) {
40
+ this.logEvent({ message: 'device capabilities updated', name: this.getSettings().name, interface: this.getSettings().interface, capabilities: this.capabilities });
41
+ this.emit('device-info', this.getSettings(), { capabilities: this.capabilities });
42
+ }
43
+ });
44
+ }
45
+ isSame(device) {
46
+ if (!(device instanceof BleCSCAdapter))
47
+ return false;
48
+ return this.isEqual(device.settings);
49
+ }
50
+ updateSensor(peripheral) {
51
+ this.device = new sensor_1.BleCyclingSpeedCadenceDevice(peripheral, { logger: this.logger });
52
+ }
53
+ getProfile() {
54
+ return BleCSCAdapter.INCYCLIST_PROFILE_NAME;
55
+ }
56
+ getDisplayName() {
57
+ return this.getName();
58
+ }
59
+ mapData(deviceData) {
60
+ const { cadence, speed } = deviceData;
61
+ return { cadence, speed };
62
+ }
63
+ }
64
+ exports.BleCSCAdapter = BleCSCAdapter;
65
+ BleCSCAdapter.INCYCLIST_PROFILE_NAME = 'Speed + Cadence Sensor';
66
+ BleCSCAdapter.CAPABILITIES = [types_1.IncyclistCapability.Speed, types_1.IncyclistCapability.Cadence];
@@ -0,0 +1,3 @@
1
+ export * from './adapter';
2
+ export * from './sensor';
3
+ export * from './types';
@@ -0,0 +1,19 @@
1
+ "use strict";
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);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./adapter"), exports);
18
+ __exportStar(require("./sensor"), exports);
19
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,21 @@
1
+ import { LegacyProfile } from '../../antv2/types';
2
+ import { BleProtocol } from '../types';
3
+ import { TBleSensor } from '../base/sensor';
4
+ import { CharacteristicParser } from '../characteristics/types';
5
+ import { CyclingCadenceAndSpeed } from '../characteristics/csc/measurement';
6
+ import { BleCSCFeatures, CscFeatures } from '../characteristics/csc/features';
7
+ export declare class BleCyclingSpeedCadenceDevice extends TBleSensor {
8
+ static readonly profile: LegacyProfile;
9
+ static readonly protocol: BleProtocol;
10
+ static readonly services: string[];
11
+ static readonly characteristics: string[];
12
+ static readonly detectionPriority = 1;
13
+ protected data: CyclingCadenceAndSpeed;
14
+ protected parsers: Record<string, CharacteristicParser<any>>;
15
+ protected featureParser: CscFeatures;
16
+ constructor(peripheral: any, props?: any);
17
+ protected getRequiredCharacteristics(): Array<string>;
18
+ getFeatures(): Promise<BleCSCFeatures>;
19
+ onData(characteristic: string, data: Buffer): boolean;
20
+ reset(): void;
21
+ }
@@ -0,0 +1,64 @@
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
+ exports.BleCyclingSpeedCadenceDevice = void 0;
13
+ const consts_1 = require("../consts");
14
+ const utils_1 = require("../utils");
15
+ const sensor_1 = require("../base/sensor");
16
+ const measurement_1 = require("../characteristics/csc/measurement");
17
+ const features_1 = require("../characteristics/csc/features");
18
+ class BleCyclingSpeedCadenceDevice extends sensor_1.TBleSensor {
19
+ constructor(peripheral, props) {
20
+ super(peripheral, props);
21
+ this.parsers = {};
22
+ this.data = {};
23
+ const measurement = new measurement_1.CscMeasurement();
24
+ this.featureParser = new features_1.CscFeatures();
25
+ this.parsers[(0, utils_1.beautifyUUID)(consts_1.CSC_MEASUREMENT)] = measurement;
26
+ }
27
+ getRequiredCharacteristics() {
28
+ return [consts_1.CSC_MEASUREMENT];
29
+ }
30
+ getFeatures() {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ try {
33
+ const data = yield this.read(consts_1.CSC_FEATURE);
34
+ return this.featureParser.parse(data);
35
+ }
36
+ catch (err) {
37
+ this.logEvent({ message: 'read failed', characteristic: consts_1.CSC_FEATURE, reason: err.message });
38
+ }
39
+ });
40
+ }
41
+ onData(characteristic, data) {
42
+ const hasData = super.onData(characteristic, data);
43
+ if (!hasData)
44
+ return false;
45
+ const uuid = (0, utils_1.beautifyUUID)(characteristic);
46
+ const parser = this.parsers[uuid];
47
+ if (!parser) {
48
+ return false;
49
+ }
50
+ const parsed = parser.parse(data);
51
+ this.data = Object.assign(Object.assign({}, this.data), parsed);
52
+ this.emit('data', this.data);
53
+ return true;
54
+ }
55
+ reset() {
56
+ this.data = {};
57
+ }
58
+ }
59
+ exports.BleCyclingSpeedCadenceDevice = BleCyclingSpeedCadenceDevice;
60
+ BleCyclingSpeedCadenceDevice.profile = 'Speed + Cadence Sensor';
61
+ BleCyclingSpeedCadenceDevice.protocol = 'csc';
62
+ BleCyclingSpeedCadenceDevice.services = [consts_1.CSC];
63
+ BleCyclingSpeedCadenceDevice.characteristics = [consts_1.CSC_MEASUREMENT, consts_1.CSC_FEATURE];
64
+ BleCyclingSpeedCadenceDevice.detectionPriority = 1;
@@ -0,0 +1,6 @@
1
+ import { BleDeviceData } from "../base/types";
2
+ export interface CSCData extends BleDeviceData {
3
+ speed?: number;
4
+ cadence?: number;
5
+ raw?: string;
6
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -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 { CrankData, PowerData } from "../cp";
4
4
  import { BleProtocol, IBlePeripheralConnector } from "../types";
5
5
  export default class BleEliteDevice extends BleComms {
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const _1 = require(".");
4
- const sensor_1 = require("../base/sensor");
4
+ const comms_1 = require("../base/comms");
5
5
  const consts_1 = require("../consts");
6
6
  const utils_1 = require("../utils");
7
- class BleEliteDevice extends sensor_1.BleComms {
7
+ class BleEliteDevice extends comms_1.BleComms {
8
8
  constructor(props) {
9
9
  super(props);
10
10
  this.instantaneousPower = undefined;
@@ -3,12 +3,8 @@ import { BleDeviceSettings, BleProtocol } from "../types";
3
3
  import { DeviceProperties } from "../../types";
4
4
  import { BleDeviceData } from "../base/types";
5
5
  import { TBleSensor } from "../base/sensor";
6
- export interface BleAdapterInfo<T extends TBleSensor> {
7
- protocol: BleProtocol;
8
- Adapter: typeof BleAdapter<BleDeviceData, T>;
9
- Sensor: typeof TBleSensor;
10
- }
11
- export declare class BleAdapterFactory<T extends TBleSensor> {
6
+ import { BleAdapterInfo, TBleAdapterFactory } from "./types";
7
+ export declare class BleAdapterFactory<T extends TBleSensor> implements TBleAdapterFactory<T> {
12
8
  transport: string;
13
9
  static readonly _instances: Record<string, BleAdapterFactory<any>>;
14
10
  implementations: BleAdapterInfo<any>[];
@@ -29,4 +25,10 @@ export declare class BleAdapterFactory<T extends TBleSensor> {
29
25
  getAllSupportedAdapters(): Array<(typeof BleAdapter<BleDeviceData, T>)>;
30
26
  getServices(info: BleAdapterInfo<T>): string[];
31
27
  getAllSupportedServices(): string[];
28
+ getProtocol(services: string[]): BleProtocol;
29
+ protected getMatchingSensors(services: string[], props?: {
30
+ protocol?: BleProtocol;
31
+ services?: string[];
32
+ }): TBleSensor[];
33
+ getSensorsFromServices(sensorTypes: (typeof TBleSensor)[], services: string | string[]): TBleSensor[];
32
34
  }
@@ -99,6 +99,39 @@ class BleAdapterFactory {
99
99
  }
100
100
  return res;
101
101
  }
102
+ getProtocol(services) {
103
+ const matching = this.getMatchingSensors(services);
104
+ if (!(matching === null || matching === void 0 ? void 0 : matching.length)) {
105
+ return;
106
+ }
107
+ if (matching.length === 1) {
108
+ return matching[0].getProtocol();
109
+ }
110
+ matching.sort((a, b) => b.getDetectionPriority() - a.getDetectionPriority());
111
+ return matching[0].getProtocol();
112
+ }
113
+ getMatchingSensors(services, props = {}) {
114
+ let sensors;
115
+ const { protocol } = props;
116
+ const classes = this.getAllSupportedSensors();
117
+ sensors = this.getSensorsFromServices(classes, services);
118
+ if (protocol && (sensors === null || sensors === void 0 ? void 0 : sensors.length) > 0) {
119
+ return sensors.filter(sensor => {
120
+ if (sensor.getProtocol() !== protocol)
121
+ return false;
122
+ return true;
123
+ });
124
+ }
125
+ return sensors;
126
+ }
127
+ getSensorsFromServices(sensorTypes, services) {
128
+ if (!sensorTypes || !Array.isArray(sensorTypes) || sensorTypes.length === 0) {
129
+ return [];
130
+ }
131
+ let serviceUUIDs = Array.isArray(services) ? services : [services];
132
+ const types = sensorTypes.map(SensorType => new SensorType(null)).filter(sensor => sensor.isMatching(serviceUUIDs));
133
+ return types;
134
+ }
102
135
  }
103
136
  exports.BleAdapterFactory = BleAdapterFactory;
104
137
  BleAdapterFactory._instances = {};
@@ -0,0 +1,18 @@
1
+ import { DeviceProperties } from "../../types";
2
+ import BleAdapter from "../base/adapter";
3
+ import { TBleSensor } from "../base/sensor";
4
+ import { BleDeviceData } from "../base/types";
5
+ import { BleDeviceSettings, BleProtocol } from "../types";
6
+ export interface TBleAdapterFactory<T extends TBleSensor> {
7
+ createInstance(settings: BleDeviceSettings, props?: DeviceProperties): BleAdapter<BleDeviceData, T>;
8
+ removeInstance(query: {
9
+ settings?: BleDeviceSettings;
10
+ adapter?: BleAdapter<BleDeviceData, T>;
11
+ }): void;
12
+ getProtocol(services: string[]): BleProtocol;
13
+ }
14
+ export interface BleAdapterInfo<T extends TBleSensor> {
15
+ protocol: BleProtocol;
16
+ Adapter: typeof BleAdapter<BleDeviceData, T>;
17
+ Sensor: typeof TBleSensor;
18
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -7,8 +7,9 @@ import { IAdapter, IncyclistAdapterData, IncyclistBikeData } from '../../types';
7
7
  import { LegacyProfile } from '../../antv2/types';
8
8
  export default class BleFmAdapter extends BleAdapter<IndoorBikeData, BleFitnessMachineDevice> {
9
9
  protected static INCYCLIST_PROFILE_NAME: LegacyProfile;
10
- distanceInternal: number;
11
- connectPromise: Promise<boolean>;
10
+ protected distanceInternal: number;
11
+ protected connectPromise: Promise<boolean>;
12
+ protected requestControlRetryDelay: number;
12
13
  constructor(settings: BleDeviceSettings, props?: BleDeviceProperties);
13
14
  updateSensor(peripheral: IBlePeripheral): void;
14
15
  isSame(device: IAdapter): boolean;
@@ -22,7 +23,7 @@ export default class BleFmAdapter extends BleAdapter<IndoorBikeData, BleFitnessM
22
23
  protected setConstants(): void;
23
24
  protected establishControl(): Promise<boolean>;
24
25
  protected sendInitialRequest(): Promise<void>;
25
- protected checkCapabilities(): void;
26
+ protected checkCapabilities(): Promise<void>;
26
27
  sendUpdate(request: any, enforced?: boolean): Promise<void>;
27
28
  sendInitCommands(): Promise<boolean>;
28
29
  }
@@ -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,22 +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.emit('device-info', this.getSettings(), { capabilities: this.capabilities });
205
- }
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
+ });
206
211
  }
207
212
  sendUpdate(request_1) {
208
213
  return __awaiter(this, arguments, void 0, function* (request, enforced = false) {
@@ -211,7 +216,7 @@ class BleFmAdapter extends adapter_1.default {
211
216
  try {
212
217
  const update = this.getCyclingMode().sendBikeUpdate(request);
213
218
  this.logEvent({ message: 'send bike update requested', profile: this.getProfile(), update, request });
214
- const device = this.device;
219
+ const device = this.getSensor();
215
220
  if (update.slope !== undefined) {
216
221
  yield device.setSlope(update.slope);
217
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
  }