incyclist-devices 2.3.28 → 2.3.31

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 (41) hide show
  1. package/lib/antv2/types.d.ts +1 -1
  2. package/lib/base/adpater.d.ts +2 -0
  3. package/lib/base/adpater.js +24 -11
  4. package/lib/ble/base/adapter.js +2 -1
  5. package/lib/ble/base/interface.d.ts +1 -0
  6. package/lib/ble/base/interface.js +29 -4
  7. package/lib/ble/base/peripheral.d.ts +3 -2
  8. package/lib/ble/base/peripheral.js +62 -38
  9. package/lib/ble/base/sensor.d.ts +2 -0
  10. package/lib/ble/base/sensor.js +16 -4
  11. package/lib/ble/fm/adapter.js +10 -8
  12. package/lib/ble/index.js +2 -0
  13. package/lib/ble/types.d.ts +4 -2
  14. package/lib/ble/zwift/click/adapter.d.ts +19 -0
  15. package/lib/ble/zwift/click/adapter.js +74 -0
  16. package/lib/ble/zwift/click/index.d.ts +2 -0
  17. package/lib/ble/zwift/click/index.js +18 -0
  18. package/lib/ble/zwift/click/sensor.d.ts +40 -0
  19. package/lib/ble/zwift/click/sensor.js +221 -0
  20. package/lib/ble/zwift/play/adapter.d.ts +19 -0
  21. package/lib/ble/zwift/play/adapter.js +76 -0
  22. package/lib/ble/zwift/play/index.d.ts +2 -0
  23. package/lib/ble/zwift/play/index.js +18 -0
  24. package/lib/ble/zwift/play/sensor.d.ts +43 -0
  25. package/lib/ble/zwift/play/sensor.js +246 -0
  26. package/lib/modes/antble-smarttrainer.d.ts +22 -3
  27. package/lib/modes/antble-smarttrainer.js +226 -3
  28. package/lib/modes/daum-classic-standard.d.ts +2 -1
  29. package/lib/modes/daum-classic-standard.js +6 -0
  30. package/lib/modes/power-base.js +17 -3
  31. package/lib/modes/types.d.ts +1 -0
  32. package/lib/serial/daum/DaumAdapter.d.ts +1 -0
  33. package/lib/serial/daum/DaumAdapter.js +14 -0
  34. package/lib/types/adapter.d.ts +1 -0
  35. package/lib/types/capabilities.d.ts +2 -1
  36. package/lib/types/capabilities.js +1 -0
  37. package/lib/types/data.d.ts +2 -0
  38. package/lib/utils/calculations.d.ts +1 -0
  39. package/lib/utils/calculations.js +13 -1
  40. package/lib/utils/utils.js +33 -26
  41. package/package.json +22 -10
@@ -7,7 +7,7 @@ export interface AntDeviceSettings extends DeviceSettings {
7
7
  interface: string;
8
8
  protocol?: string;
9
9
  }
10
- export type LegacyProfile = 'Heartrate Monitor' | 'Power Meter' | 'Smart Trainer' | 'Speed Sensor' | 'Cadence Sensor' | 'Speed + Cadence Sensor';
10
+ export type LegacyProfile = 'Heartrate Monitor' | 'Power Meter' | 'Smart Trainer' | 'Speed Sensor' | 'Cadence Sensor' | 'Speed + Cadence Sensor' | 'Controller';
11
11
  export declare const isLegacyProfile: (o: unknown) => boolean;
12
12
  export type DeviceFoundCallback = (device: IAdapter, protocol: string) => void;
13
13
  export type ScanFinishedCallback = (id: number) => void;
@@ -19,6 +19,7 @@ export default class IncyclistDevice<P extends DeviceProperties> extends EventEm
19
19
  protected user: User;
20
20
  protected data: IncyclistAdapterData;
21
21
  constructor(settings: DeviceSettings, props?: P);
22
+ supportsVirtualShifting(): boolean;
22
23
  getLogger(): EventLogger;
23
24
  isDebugEnabled(): boolean;
24
25
  logEvent(event: any): void;
@@ -48,6 +49,7 @@ export default class IncyclistDevice<P extends DeviceProperties> extends EventEm
48
49
  setMaxUpdateFrequency(value: number): void;
49
50
  update(): void;
50
51
  setCyclingMode(mode: string | ICyclingMode, settings?: any, sendInitCommands?: boolean): void;
52
+ protected createOrGetMode(mode: string | ICyclingMode): ICyclingMode;
51
53
  getSupportedCyclingModes(): Array<typeof CyclingMode>;
52
54
  getCyclingMode(): ICyclingMode;
53
55
  getDefaultCyclingMode(): ICyclingMode;
@@ -31,6 +31,9 @@ class IncyclistDevice extends events_1.default {
31
31
  this.data = {};
32
32
  this.cyclingMode = this.getDefaultCyclingMode();
33
33
  }
34
+ supportsVirtualShifting() {
35
+ return false;
36
+ }
34
37
  getLogger() { return this.logger; }
35
38
  isDebugEnabled() {
36
39
  const w = global.window;
@@ -139,21 +142,29 @@ class IncyclistDevice extends events_1.default {
139
142
  setCyclingMode(mode, settings, sendInitCommands) {
140
143
  if (!this.isControllable())
141
144
  return;
142
- let selectedMode;
145
+ const selectedMode = this.createOrGetMode(mode);
146
+ this.cyclingMode = selectedMode;
147
+ this.cyclingMode.setSettings(settings);
148
+ }
149
+ createOrGetMode(mode) {
150
+ var _a, _b;
143
151
  if (typeof mode === 'string') {
152
+ if (mode === ((_a = this.getCyclingMode()) === null || _a === void 0 ? void 0 : _a.getName())) {
153
+ return this.cyclingMode;
154
+ }
144
155
  const supported = this.getSupportedCyclingModes();
145
156
  const CyclingModeClass = supported.find(M => { const m = new M(this); return m.getName() === mode; });
146
157
  if (CyclingModeClass) {
147
- this.cyclingMode = new CyclingModeClass(this, settings);
148
- return;
158
+ return new CyclingModeClass(this);
159
+ }
160
+ else {
161
+ return this.getDefaultCyclingMode();
149
162
  }
150
- selectedMode = this.getDefaultCyclingMode();
151
163
  }
152
- else {
153
- selectedMode = mode;
164
+ if (mode.getName() === ((_b = this.cyclingMode) === null || _b === void 0 ? void 0 : _b.getName())) {
165
+ return this.cyclingMode;
154
166
  }
155
- this.cyclingMode = selectedMode;
156
- this.cyclingMode.setSettings(settings);
167
+ return mode;
157
168
  }
158
169
  getSupportedCyclingModes() {
159
170
  if (!this.isControllable())
@@ -259,9 +270,11 @@ class IncyclistDevice extends events_1.default {
259
270
  return this.data;
260
271
  }
261
272
  getStartProps(startProps) {
262
- if (startProps)
263
- this.props = startProps;
264
- return startProps || {};
273
+ if (startProps) {
274
+ const current = this.props || {};
275
+ this.props = Object.assign(Object.assign({}, current), startProps);
276
+ }
277
+ return startProps !== null && startProps !== void 0 ? startProps : {};
265
278
  }
266
279
  hasDataListeners() {
267
280
  return this.onDataFn || this.listenerCount('data') > 0;
@@ -328,12 +328,13 @@ class BleAdapter extends adpater_1.default {
328
328
  return false;
329
329
  }
330
330
  const sensor = this.getSensor();
331
- const connected = yield sensor.startSensor();
331
+ let connected = yield sensor.startSensor();
332
332
  yield sensor.subscribe();
333
333
  if (connected) {
334
334
  sensor.on('data', this.onDeviceDataHandler);
335
335
  sensor.on('disconnected', this.emit.bind(this));
336
336
  sensor.on('error', console.log);
337
+ connected = yield sensor.pair();
337
338
  }
338
339
  return connected;
339
340
  });
@@ -105,6 +105,7 @@ export declare class BleInterface extends EventEmitter implements IBleInterface<
105
105
  protected getExpectedServices(): string[];
106
106
  logEvent(event: any): void;
107
107
  logError(err: Error, fn: string, args?: any): void;
108
+ protected reset(): Promise<void>;
108
109
  }
109
110
  export declare class BleInterfaceFactory extends InterfaceFactory {
110
111
  protected iface: BleInterface;
@@ -228,10 +228,16 @@ class BleInterface extends events_1.default {
228
228
  pauseLogging() {
229
229
  this.logEvent({ message: 'pausing logging' });
230
230
  this.logDisabled = true;
231
- this.getBinding().pauseLogging();
231
+ try {
232
+ this.getBinding().pauseLogging();
233
+ }
234
+ catch (_a) { }
232
235
  }
233
236
  resumeLogging() {
234
- this.getBinding().resumeLogging();
237
+ try {
238
+ this.getBinding().resumeLogging();
239
+ }
240
+ catch (_a) { }
235
241
  this.logDisabled = false;
236
242
  this.logEvent({ message: 'resuming logging' });
237
243
  }
@@ -407,11 +413,12 @@ class BleInterface extends events_1.default {
407
413
  });
408
414
  }
409
415
  buildAnnouncement(peripheral) {
410
- var _a;
416
+ var _a, _b;
411
417
  return {
412
418
  advertisement: peripheral.advertisement,
413
419
  name: peripheral.advertisement.localName,
414
- serviceUUIDs: (_a = peripheral.advertisement.serviceUuids) !== null && _a !== void 0 ? _a : [],
420
+ manufacturerData: ((_a = peripheral.advertisement) === null || _a === void 0 ? void 0 : _a.manufacturerData) ? Buffer.from(peripheral.advertisement.manufacturerData) : undefined,
421
+ serviceUUIDs: (_b = peripheral.advertisement.serviceUuids) !== null && _b !== void 0 ? _b : [],
415
422
  peripheral,
416
423
  transport: this.getName()
417
424
  };
@@ -668,6 +675,24 @@ class BleInterface extends events_1.default {
668
675
  const logInfo = args || {};
669
676
  this.logEvent(Object.assign(Object.assign({ message: 'Error', fn }, logInfo), { error: err.message, stack: err.stack }));
670
677
  }
678
+ reset() {
679
+ return __awaiter(this, void 0, void 0, function* () {
680
+ if (this.connectTask) {
681
+ yield this.connectTask.stop();
682
+ }
683
+ if (this.disconnectTask) {
684
+ yield this.disconnectTask.stop();
685
+ }
686
+ if (this.scanTask) {
687
+ yield this.scanTask.stop();
688
+ }
689
+ if (this.discoverTask) {
690
+ yield this.discoverTask.stop();
691
+ }
692
+ this.removeAllListeners();
693
+ this.internalEvents.removeAllListeners();
694
+ });
695
+ }
671
696
  }
672
697
  exports.BleInterface = BleInterface;
673
698
  BleInterface.INTERFACE_NAME = 'ble';
@@ -22,13 +22,14 @@ export declare class BlePeripheral implements IBlePeripheral {
22
22
  isConnected(): boolean;
23
23
  isConnecting(): boolean;
24
24
  onDisconnect(callback: () => void): void;
25
+ getManufacturerData(): Buffer<ArrayBufferLike>;
25
26
  protected onPeripheralDisconnect(): Promise<void>;
26
27
  protected onPeripheralError(err: Error): void;
27
28
  discoverServices(): Promise<string[]>;
28
29
  discoverCharacteristics(serviceUUID: string): Promise<BleCharacteristic[]>;
29
- subscribe(characteristicUUID: string, callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
30
+ subscribe(characteristicUUID: string, callback: (characteristicUuid: string, data: Buffer, isNotify?: any) => void): Promise<boolean>;
30
31
  unsubscribe(characteristicUUID: string): Promise<boolean>;
31
- subscribeSelected(characteristics: string[], callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
32
+ subscribeSelected(characteristics: string[], callback: (characteristicUuid: string, data: Buffer, isNotify?: boolean) => void): Promise<boolean>;
32
33
  discoverAllCharacteristics(): Promise<string[]>;
33
34
  discoverSomeCharacteristics(characteristics: string[]): Promise<string[]>;
34
35
  subscribeAll(callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
@@ -93,6 +93,10 @@ class BlePeripheral {
93
93
  onDisconnect(callback) {
94
94
  this.onDisconnectHandler = callback;
95
95
  }
96
+ getManufacturerData() {
97
+ var _a;
98
+ return (_a = this.announcement) === null || _a === void 0 ? void 0 : _a.manufacturerData;
99
+ }
96
100
  onPeripheralDisconnect() {
97
101
  return __awaiter(this, void 0, void 0, function* () {
98
102
  var _a;
@@ -148,9 +152,9 @@ class BlePeripheral {
148
152
  if (this.disconnecting || !this.connected)
149
153
  return false;
150
154
  const uuid = (0, utils_1.beautifyUUID)(characteristicUUID);
151
- const onData = (data) => {
155
+ const onData = (data, isNotify) => {
152
156
  try {
153
- callback(characteristicUUID, data);
157
+ callback(characteristicUUID, data, isNotify);
154
158
  }
155
159
  catch (_a) { }
156
160
  };
@@ -241,7 +245,7 @@ class BlePeripheral {
241
245
  const retry = [];
242
246
  for (const element of characteristics) {
243
247
  const c = this.getRawCharacteristic(element);
244
- if (c === null || c === void 0 ? void 0 : c.properties.includes('notify')) {
248
+ if ((c === null || c === void 0 ? void 0 : c.properties.includes('notify')) || (c === null || c === void 0 ? void 0 : c.properties.includes('indicate'))) {
245
249
  const success = yield this.subscribe(c.uuid, callback);
246
250
  if (!success)
247
251
  retry.push(c);
@@ -315,46 +319,66 @@ class BlePeripheral {
315
319
  });
316
320
  }
317
321
  read(characteristicUUID) {
318
- if (this.disconnecting || !this.connected)
319
- return Promise.resolve(Buffer.from([]));
320
- const c = this.characteristics[(0, utils_1.beautifyUUID)(characteristicUUID)];
321
- if (!c) {
322
- return Promise.reject(new Error('characteristic not found'));
323
- }
324
- return new Promise((resolve, reject) => {
325
- c.read((err, data) => {
326
- if (err) {
327
- reject(err);
328
- }
329
- else {
330
- resolve(data);
322
+ return __awaiter(this, void 0, void 0, function* () {
323
+ if (this.disconnecting || !this.connected)
324
+ return Buffer.from([]);
325
+ let c = this.characteristics[(0, utils_1.beautifyUUID)(characteristicUUID)];
326
+ if (!c) {
327
+ yield this.discoverAllCharacteristics();
328
+ c = this.characteristics[(0, utils_1.beautifyUUID)(characteristicUUID)];
329
+ if (!c) {
330
+ return Promise.reject(new Error('characteristic not found: ' + characteristicUUID));
331
331
  }
332
+ }
333
+ return new Promise((resolve, reject) => {
334
+ c.read((err, data) => {
335
+ if (err) {
336
+ reject(err);
337
+ }
338
+ else {
339
+ resolve(data);
340
+ }
341
+ });
332
342
  });
333
343
  });
334
344
  }
335
345
  write(characteristicUUID, data, options) {
336
- if (this.disconnecting || !this.connected)
337
- return Promise.resolve(Buffer.from([]));
338
- const uuid = (0, utils_1.beautifyUUID)(characteristicUUID);
339
- const c = this.characteristics[uuid];
340
- if (!c) {
341
- return Promise.reject(new Error('characteristic not found'));
342
- }
343
- return new Promise((resolve, reject) => {
344
- this.subscribe(characteristicUUID, null).then(success => {
345
- if (this.disconnecting || !this.connected)
346
- return Promise.resolve(Buffer.from([]));
347
- c.on('data', (data) => {
348
- c.removeAllListeners('data');
349
- resolve(data);
350
- });
351
- this.logEvent({ message: 'write request', characteristic: uuid, data: data.toString('hex'), withoutResponse: (options === null || options === void 0 ? void 0 : options.withoutResponse) === true });
352
- c.write(data, (options === null || options === void 0 ? void 0 : options.withoutResponse) === true, (err) => {
353
- if (err)
354
- reject(err);
355
- });
356
- if (options === null || options === void 0 ? void 0 : options.withoutResponse) {
357
- resolve(Buffer.from([]));
346
+ return __awaiter(this, void 0, void 0, function* () {
347
+ if (this.disconnecting || !this.connected)
348
+ return Buffer.from([]);
349
+ const uuid = (0, utils_1.beautifyUUID)(characteristicUUID);
350
+ let c = this.characteristics[uuid];
351
+ if (!c) {
352
+ yield this.discoverAllCharacteristics();
353
+ c = this.characteristics[(0, utils_1.beautifyUUID)(characteristicUUID)];
354
+ if (!c) {
355
+ return Promise.reject(new Error('characteristic not found: ' + characteristicUUID));
356
+ }
357
+ }
358
+ return new Promise((resolve, reject) => {
359
+ const write = () => {
360
+ if (this.disconnecting || !this.connected)
361
+ return Promise.resolve(Buffer.from([]));
362
+ c.on('data', (data) => {
363
+ c.removeAllListeners('data');
364
+ resolve(data);
365
+ });
366
+ this.logEvent({ message: 'write request', characteristic: uuid, data: data.toString('hex'), withoutResponse: (options === null || options === void 0 ? void 0 : options.withoutResponse) === true });
367
+ c.write(data, (options === null || options === void 0 ? void 0 : options.withoutResponse) === true, (err) => {
368
+ if (err)
369
+ reject(err);
370
+ });
371
+ if (options === null || options === void 0 ? void 0 : options.withoutResponse) {
372
+ resolve(Buffer.from([]));
373
+ }
374
+ };
375
+ if (!(options === null || options === void 0 ? void 0 : options.withoutResponse)) {
376
+ this.subscribe(characteristicUUID, null).then(success => {
377
+ write();
378
+ });
379
+ }
380
+ else {
381
+ write();
358
382
  }
359
383
  });
360
384
  });
@@ -18,6 +18,7 @@ export declare class TBleSensor extends EventEmitter implements IBleSensor {
18
18
  getServiceUUids(): string[];
19
19
  isMatching(serviceUUIDs: string[]): boolean;
20
20
  hasPeripheral(): boolean;
21
+ pair(): Promise<boolean>;
21
22
  startSensor(reconnect?: boolean): Promise<boolean>;
22
23
  protected getRequiredCharacteristics(): Array<string>;
23
24
  subscribe(): Promise<boolean>;
@@ -28,5 +29,6 @@ export declare class TBleSensor extends EventEmitter implements IBleSensor {
28
29
  read(characteristicUUID: string): Promise<Buffer>;
29
30
  write(characteristicUUID: string, data: Buffer, options?: BleWriteProps): Promise<Buffer>;
30
31
  onData(characteristic: string, data: Buffer): boolean;
32
+ getAnnouncement(): IBlePeripheral;
31
33
  protected getDefaultLogger(): EventLogger;
32
34
  }
@@ -61,6 +61,11 @@ class TBleSensor extends events_1.default {
61
61
  hasPeripheral() {
62
62
  return !!this.peripheral;
63
63
  }
64
+ pair() {
65
+ return __awaiter(this, void 0, void 0, function* () {
66
+ return true;
67
+ });
68
+ }
64
69
  startSensor(reconnect) {
65
70
  return __awaiter(this, void 0, void 0, function* () {
66
71
  if (!reconnect)
@@ -83,11 +88,15 @@ class TBleSensor extends events_1.default {
83
88
  subscribe() {
84
89
  return __awaiter(this, void 0, void 0, function* () {
85
90
  const selected = this.getRequiredCharacteristics();
86
- if (selected === null)
87
- return yield this.peripheral.subscribeAll(this.onDataHandler);
88
- if (selected.length === 0)
91
+ if (selected === null) {
92
+ const res = yield this.peripheral.subscribeAll(this.onDataHandler);
93
+ return res;
94
+ }
95
+ if (selected.length === 0) {
89
96
  return true;
90
- return yield this.peripheral.subscribeSelected(selected, this.onDataHandler);
97
+ }
98
+ const res = yield this.peripheral.subscribeSelected(selected, this.onDataHandler);
99
+ return res;
91
100
  });
92
101
  }
93
102
  stopSensor() {
@@ -142,6 +151,9 @@ class TBleSensor extends events_1.default {
142
151
  onData(characteristic, data) {
143
152
  return true;
144
153
  }
154
+ getAnnouncement() {
155
+ return this.peripheral;
156
+ }
145
157
  getDefaultLogger() {
146
158
  return new gd_eventlog_1.EventLogger(this.constructor.name);
147
159
  }
@@ -45,11 +45,11 @@ class BleFmAdapter extends adapter_1.default {
45
45
  return true;
46
46
  }
47
47
  getSupportedCyclingModes() {
48
- var _a;
48
+ var _a, _b;
49
49
  const modes = [power_meter_1.default];
50
- if (this.props.capabilities && this.props.capabilities.indexOf(types_1.IncyclistCapability.Control) === -1)
50
+ if (((_a = this.props) === null || _a === void 0 ? void 0 : _a.capabilities) && this.props.capabilities.indexOf(types_1.IncyclistCapability.Control) === -1)
51
51
  return modes;
52
- const features = (_a = this.getSensor()) === null || _a === void 0 ? void 0 : _a.features;
52
+ const features = (_b = this.getSensor()) === null || _b === void 0 ? void 0 : _b.features;
53
53
  if (!features)
54
54
  return [power_meter_1.default, antble_smarttrainer_1.default, antble_erg_1.default];
55
55
  if (features.setPower === undefined || features.setPower)
@@ -59,10 +59,10 @@ class BleFmAdapter extends adapter_1.default {
59
59
  return modes;
60
60
  }
61
61
  getDefaultCyclingMode() {
62
- var _a;
63
- if (this.props.capabilities && this.props.capabilities.indexOf(types_1.IncyclistCapability.Control) === -1)
62
+ var _a, _b;
63
+ if (((_a = this.props) === null || _a === void 0 ? void 0 : _a.capabilities) && this.props.capabilities.indexOf(types_1.IncyclistCapability.Control) === -1)
64
64
  return new power_meter_1.default(this);
65
- const features = (_a = this.getSensor()) === null || _a === void 0 ? void 0 : _a.features;
65
+ const features = (_b = this.getSensor()) === null || _b === void 0 ? void 0 : _b.features;
66
66
  if (!features)
67
67
  return new antble_smarttrainer_1.default(this);
68
68
  if (features.setSlope === undefined || features.setSlope)
@@ -106,7 +106,8 @@ class BleFmAdapter extends adapter_1.default {
106
106
  cadence: bikeData.pedalRpm !== undefined ? Math.round(bikeData.pedalRpm) : undefined,
107
107
  distance,
108
108
  heartrate: bikeData.heartrate,
109
- timestamp: Date.now()
109
+ timestamp: Date.now(),
110
+ gearStr: bikeData.gearStr
110
111
  };
111
112
  return data;
112
113
  }
@@ -231,13 +232,14 @@ class BleFmAdapter extends adapter_1.default {
231
232
  }
232
233
  sendUpdate(request_1) {
233
234
  return __awaiter(this, arguments, void 0, function* (request, enforced = false) {
235
+ var _a;
234
236
  if (!enforced && (this.paused || !this.device))
235
237
  return;
236
238
  if (!enforced && (this.stopped && !this.isStarting()))
237
239
  return;
238
240
  try {
239
241
  const update = this.getCyclingMode().sendBikeUpdate(request);
240
- this.logEvent({ message: 'send bike update requested', profile: this.getProfile(), update, request });
242
+ this.logEvent({ message: 'send bike update requested', profile: this.getProfile(), mode: (_a = this.getCyclingMode()) === null || _a === void 0 ? void 0 : _a.getName(), update, request });
241
243
  const device = this.getSensor();
242
244
  if (this.hasCapability(types_1.IncyclistCapability.Control)) {
243
245
  if (update.slope !== undefined) {
package/lib/ble/index.js CHANGED
@@ -31,6 +31,7 @@ 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
33
  const csc_1 = require("./csc");
34
+ const play_1 = require("./zwift/play");
34
35
  ['ble', 'wifi'].forEach(i => {
35
36
  const af = factories_1.BleAdapterFactory.getInstance(i);
36
37
  af.register('hr', hr_1.BleHrmAdapter, hr_1.BleHrmComms);
@@ -39,6 +40,7 @@ const csc_1 = require("./csc");
39
40
  af.register('wahoo', wahoo_1.BleWahooAdapter, wahoo_1.BleWahooComms);
40
41
  af.register('tacx', tacx_1.BleTacxAdapter, tacx_1.BleTacxComms);
41
42
  af.register('csc', csc_1.BleCSCAdapter, csc_1.BleCyclingSpeedCadenceDevice);
43
+ af.register('zwift-play', play_1.ZwiftPlayAdapter, play_1.BleZwiftPlaySensor);
42
44
  });
43
45
  factories_1.BleMultiTransportInterfaceFactory.register('ble', interface_1.BleInterfaceFactory);
44
46
  __exportStar(require("./utils"), exports);
@@ -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' | 'csc';
4
+ export type BleProtocol = 'hr' | 'fm' | 'cp' | 'tacx' | 'wahoo' | 'elite' | 'csc' | 'zwift-play';
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;
@@ -39,6 +39,7 @@ export interface PeripheralAnnouncement {
39
39
  }
40
40
  export interface BlePeripheralAnnouncement extends PeripheralAnnouncement {
41
41
  advertisement: any;
42
+ manufacturerData?: Buffer;
42
43
  peripheral: BleRawPeripheral;
43
44
  }
44
45
  export interface BlePeripheralInfo {
@@ -86,7 +87,7 @@ export type DiscoverResult = {
86
87
  services: BleService[];
87
88
  characteristics: BleRawCharacteristic[];
88
89
  };
89
- export type BleProperty = 'notify' | 'read' | 'write';
90
+ export type BleProperty = 'notify' | 'read' | 'write' | 'indicate';
90
91
  export interface BleCharacteristic {
91
92
  uuid: string;
92
93
  properties: BleProperty[];
@@ -152,6 +153,7 @@ export interface IBlePeripheral {
152
153
  subscribeSelected(characteristics: string[], callback: (characteristicUuid: string, data: Buffer) => void): Promise<boolean>;
153
154
  read(characteristicUUID: string): Promise<Buffer>;
154
155
  write(characteristicUUID: string, data: Buffer, options?: BleWriteProps): Promise<Buffer>;
156
+ getManufacturerData?(): Buffer;
155
157
  }
156
158
  export interface IBleSensor extends EventEmitter {
157
159
  startSensor(): Promise<boolean>;
@@ -0,0 +1,19 @@
1
+ import { BleDeviceData } from '../../base/types';
2
+ import { LegacyProfile } from '../../../antv2/types';
3
+ import BleAdapter from '../../base/adapter';
4
+ import { BleZwiftClickSensor } from './sensor';
5
+ import { DeviceProperties, IAdapter, IncyclistAdapterData, IncyclistCapability } from '../../../types';
6
+ import { BleDeviceSettings, BleStartProperties, IBlePeripheral } from '../../types';
7
+ export declare class ZwiftClickAdapter extends BleAdapter<BleDeviceData, BleZwiftClickSensor> {
8
+ protected static INCYCLIST_PROFILE_NAME: LegacyProfile;
9
+ protected static CAPABILITIES: IncyclistCapability[];
10
+ constructor(settings: BleDeviceSettings, props?: DeviceProperties);
11
+ protected checkCapabilities(): Promise<void>;
12
+ start(startProps?: BleStartProperties): Promise<boolean>;
13
+ startSensor(): Promise<boolean>;
14
+ isSame(adapter: IAdapter): boolean;
15
+ updateSensor(peripheral: IBlePeripheral): void;
16
+ getProfile(): LegacyProfile;
17
+ getDisplayName(): string;
18
+ mapData(deviceData: BleDeviceData): IncyclistAdapterData;
19
+ }
@@ -0,0 +1,74 @@
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.ZwiftClickAdapter = void 0;
16
+ const gd_eventlog_1 = require("gd-eventlog");
17
+ const adapter_1 = __importDefault(require("../../base/adapter"));
18
+ const sensor_1 = require("./sensor");
19
+ const types_1 = require("../../../types");
20
+ class ZwiftClickAdapter extends adapter_1.default {
21
+ constructor(settings, props) {
22
+ super(settings, props);
23
+ this.logger = new gd_eventlog_1.EventLogger('Zwift-Click');
24
+ this.device = new sensor_1.BleZwiftClickSensor(this.getPeripheral(), { logger: this.logger });
25
+ this.capabilities = ZwiftClickAdapter.CAPABILITIES;
26
+ }
27
+ checkCapabilities() {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ return;
30
+ });
31
+ }
32
+ start(startProps) {
33
+ return super.start(startProps);
34
+ }
35
+ startSensor() {
36
+ const _super = Object.create(null, {
37
+ startSensor: { get: () => super.startSensor }
38
+ });
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ let connected = yield _super.startSensor.call(this);
41
+ if (connected) {
42
+ const sensor = this.getSensor();
43
+ connected = yield sensor.pair();
44
+ sensor.on('up', (duration) => {
45
+ console.log('Up button pressed for', duration, 'ms');
46
+ });
47
+ sensor.on('down', (duration) => {
48
+ console.log('Down button pressed for', duration, 'ms');
49
+ });
50
+ }
51
+ return connected;
52
+ });
53
+ }
54
+ isSame(adapter) {
55
+ if (!(adapter instanceof ZwiftClickAdapter))
56
+ return false;
57
+ return this.isEqual(adapter.settings);
58
+ }
59
+ updateSensor(peripheral) {
60
+ this.device = new sensor_1.BleZwiftClickSensor(peripheral, { logger: this.logger });
61
+ }
62
+ getProfile() {
63
+ return ZwiftClickAdapter.INCYCLIST_PROFILE_NAME;
64
+ }
65
+ getDisplayName() {
66
+ return this.getName();
67
+ }
68
+ mapData(deviceData) {
69
+ return {};
70
+ }
71
+ }
72
+ exports.ZwiftClickAdapter = ZwiftClickAdapter;
73
+ ZwiftClickAdapter.INCYCLIST_PROFILE_NAME = 'Controller';
74
+ ZwiftClickAdapter.CAPABILITIES = [types_1.IncyclistCapability.AppControl];
@@ -0,0 +1,2 @@
1
+ export * from './sensor';
2
+ export * from './adapter';
@@ -0,0 +1,18 @@
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("./sensor"), exports);
18
+ __exportStar(require("./adapter"), exports);
@@ -0,0 +1,40 @@
1
+ import { LegacyProfile } from "incyclist-devices/lib/antv2/types";
2
+ import { TBleSensor } from "../../base/sensor";
3
+ import { BleProtocol } from "../../types";
4
+ import { EventEmitter } from "stream";
5
+ type ButtonState = {
6
+ pressed: boolean;
7
+ timestamp: number;
8
+ };
9
+ type DeviceType = 'left' | 'right' | 'click';
10
+ export declare class BleZwiftClickSensor extends TBleSensor {
11
+ static readonly profile: LegacyProfile;
12
+ static readonly protocol: BleProtocol;
13
+ static readonly services: string[];
14
+ static readonly characteristics: any[];
15
+ static readonly detectionPriority = 1;
16
+ protected emitter: EventEmitter;
17
+ protected paired: boolean;
18
+ protected encrypted: boolean;
19
+ protected deviceKey: Buffer;
20
+ protected prevClickMessage: string;
21
+ protected upState: ButtonState;
22
+ protected downState: ButtonState;
23
+ protected deviceType: DeviceType;
24
+ protected publicKey: Buffer;
25
+ protected privateKey: Buffer;
26
+ constructor(peripheral: any, props?: any);
27
+ reconnectSensor(): Promise<void>;
28
+ stopSensor(): Promise<boolean>;
29
+ protected getRequiredCharacteristics(): Array<string>;
30
+ onData(characteristic: string, data: Buffer, isNotify?: boolean): boolean;
31
+ onPlayMeasurement(data: Buffer): boolean;
32
+ onButtonMessage(message: Buffer): void;
33
+ onPingMessage(message: Buffer): void;
34
+ onPairResponse(data: Buffer): boolean;
35
+ read(characteristic: string, ignoreErrors?: boolean): Promise<Buffer | null>;
36
+ pair(): Promise<boolean>;
37
+ reset(): void;
38
+ protected setInitialState(): void;
39
+ }
40
+ export {};