incyclist-services 1.0.3 → 1.0.5

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.
@@ -1,3 +1,4 @@
1
+ import { IncyclistCapability } from "incyclist-devices";
1
2
  import { DeviceProperties } from "incyclist-devices/lib/types/device";
2
3
  import { AdapterInfo } from "../configuration";
3
4
  export interface AdapterRideInfo extends AdapterInfo {
@@ -10,6 +11,12 @@ export interface RideServiceDeviceProperties extends DeviceProperties {
10
11
  rideMode?: string;
11
12
  route?: any;
12
13
  }
14
+ export interface RideServiceCheckFilter {
15
+ interface?: string;
16
+ interfaces?: string[];
17
+ udid?: string;
18
+ capability?: IncyclistCapability;
19
+ }
13
20
  export interface Point {
14
21
  elevation: number;
15
22
  distance: number;
@@ -4,7 +4,7 @@ import { DeviceData, DeviceSettings } from "incyclist-devices";
4
4
  import { DeviceAccessService } from "../access/service";
5
5
  import { AdapterInfo, DeviceConfigurationService } from "../configuration";
6
6
  import CyclingMode, { UpdateRequest } from "incyclist-devices/lib/modes/cycling-mode";
7
- import { AdapterRideInfo, PreparedRoute, RideServiceDeviceProperties } from "./model";
7
+ import { AdapterRideInfo, PreparedRoute, RideServiceCheckFilter, RideServiceDeviceProperties } from "./model";
8
8
  import { UserSettingsService } from "../../settings";
9
9
  import { EventLogger } from 'gd-eventlog';
10
10
  export declare class DeviceRideService extends EventEmitter {
@@ -34,6 +34,10 @@ export declare class DeviceRideService extends EventEmitter {
34
34
  };
35
35
  protected getAdapterList(): AdapterRideInfo[];
36
36
  prepareEppRoute(props: RideServiceDeviceProperties): PreparedRoute;
37
+ protected waitForPreviousStartToFinish(): Promise<boolean>;
38
+ startCheck(filter: RideServiceCheckFilter): Promise<void>;
39
+ protected getAdapters(filter: RideServiceCheckFilter): AdapterRideInfo[];
40
+ protected startAdapters(adapters: AdapterRideInfo[], startType: 'start' | 'check', props?: RideServiceDeviceProperties): Promise<boolean>;
37
41
  start(props: RideServiceDeviceProperties): Promise<boolean>;
38
42
  cancelStart(): Promise<boolean>;
39
43
  startRide(_props: any): void;
@@ -267,70 +267,115 @@ class DeviceRideService extends events_1.default {
267
267
  }
268
268
  return res;
269
269
  }
270
- start(props) {
270
+ waitForPreviousStartToFinish() {
271
271
  return __awaiter(this, void 0, void 0, function* () {
272
- this.lazyInit();
273
- const { forceErgMode, startPos, realityFactor, rideMode, route } = props;
274
- while (this.startPromises) {
275
- (0, sleep_1.sleep)(500);
276
- }
277
- const adapters = this.getAdapterList();
278
- this.emit('start-request', adapters.map(this.getAdapterStateInfo));
272
+ const TIMEOUT = 3000;
273
+ if (!this.startPromises)
274
+ return true;
275
+ const prevStartState = yield Promise.race([
276
+ (0, sleep_1.sleep)(TIMEOUT).then(() => 'timeout'),
277
+ Promise.allSettled(this.startPromises)
278
+ ]).then(() => 'finished');
279
+ return (prevStartState === 'finished');
280
+ });
281
+ }
282
+ startCheck(filter) {
283
+ return __awaiter(this, void 0, void 0, function* () {
284
+ yield this.lazyInit();
285
+ const adapters = this.getAdapters(filter);
286
+ const goodToGo = yield this.waitForPreviousStartToFinish();
287
+ if (!goodToGo)
288
+ return;
289
+ this.emit('check-request', adapters.map(this.getAdapterStateInfo));
290
+ yield this.startAdapters(adapters, 'check');
291
+ });
292
+ }
293
+ getAdapters(filter) {
294
+ const { udid, interface: ifName, interfaces, capability } = filter;
295
+ let adapters = this.getAdapterList();
296
+ const getIf = (adapter) => {
297
+ var _a;
298
+ const i = (_a = adapter === null || adapter === void 0 ? void 0 : adapter.getSettings()) === null || _a === void 0 ? void 0 : _a.interface;
299
+ if (!i)
300
+ return;
301
+ if (typeof (i) === 'string')
302
+ return i;
303
+ return i.getName();
304
+ };
305
+ if (udid) {
306
+ adapters = adapters === null || adapters === void 0 ? void 0 : adapters.filter(ai => ai.udid === udid);
307
+ }
308
+ if (ifName) {
309
+ adapters = adapters === null || adapters === void 0 ? void 0 : adapters.filter(ai => getIf(ai.adapter) === ifName);
310
+ }
311
+ if (interfaces) {
312
+ adapters = adapters === null || adapters === void 0 ? void 0 : adapters.filter(ai => interfaces.includes(getIf(ai.adapter)));
313
+ }
314
+ return adapters || [];
315
+ }
316
+ startAdapters(adapters, startType, props) {
317
+ return __awaiter(this, void 0, void 0, function* () {
318
+ const { forceErgMode, startPos, realityFactor, rideMode, route } = props || {};
279
319
  this.startPromises = adapters.map(ai => {
280
- const startProps = (0, clone_1.default)(props);
281
- if (ai.adapter.isControllable()) {
282
- const d = ai.adapter;
283
- let mode, settings;
284
- if (!this.simulatorEnforced) {
285
- if (forceErgMode) {
286
- const modes = d.getSupportedCyclingModes().filter(C => C.isERG);
287
- if (modes.length > 0) {
288
- mode = new modes[0](d);
289
- const modeInfo = this.configurationService.getModeSettings(ai.udid, mode);
320
+ const startProps = (0, clone_1.default)(props || {});
321
+ if (startType === 'check') {
322
+ startProps.timeout = 5000;
323
+ }
324
+ if (startType === 'start') {
325
+ if (ai.adapter.isControllable()) {
326
+ const d = ai.adapter;
327
+ let mode, settings;
328
+ if (!this.simulatorEnforced) {
329
+ if (forceErgMode) {
330
+ const modes = d.getSupportedCyclingModes().filter(C => C.isERG);
331
+ if (modes.length > 0) {
332
+ mode = new modes[0](d);
333
+ const modeInfo = this.configurationService.getModeSettings(ai.udid, mode);
334
+ settings = modeInfo.settings;
335
+ }
336
+ }
337
+ if (!mode) {
338
+ const modeInfo = this.configurationService.getModeSettings(ai.udid);
339
+ mode = modeInfo.mode;
290
340
  settings = modeInfo.settings;
291
341
  }
292
342
  }
293
- if (!mode) {
294
- const modeInfo = this.configurationService.getModeSettings(ai.udid);
295
- mode = modeInfo.mode;
296
- settings = modeInfo.settings;
343
+ if (!mode)
344
+ mode = d.getDefaultCyclingMode();
345
+ d.setCyclingMode(mode, settings);
346
+ if (d.getCyclingMode().getModeProperty('eppSupport')) {
347
+ startProps.route = this.prepareEppRoute({ route, startPos, realityFactor, rideMode });
348
+ startProps.onStatusUpdate = (completed, total) => {
349
+ this.emit('start-update', this.getAdapterStateInfo(ai), completed, total);
350
+ };
297
351
  }
298
352
  }
299
- if (!mode)
300
- mode = d.getDefaultCyclingMode();
301
- d.setCyclingMode(mode, settings);
302
- if (d.getCyclingMode().getModeProperty('eppSupport')) {
303
- startProps.route = this.prepareEppRoute({ route, startPos, realityFactor, rideMode });
304
- startProps.onStatusUpdate = (completed, total) => {
305
- this.emit('start-update', this.getAdapterStateInfo(ai), completed, total);
306
- };
307
- }
308
353
  }
309
354
  const sType = ai.adapter.hasCapability(incyclist_devices_1.IncyclistCapability.Control) ? 'bike' : 'sensor';
310
355
  const logProps = {};
311
356
  logProps[sType] = ai.adapter.getUniqueName();
312
357
  logProps.cability = ai.adapter.getCapabilities().join('/');
313
358
  logProps.interface = (0, logging_1.getLegacyInterface)(ai.adapter);
314
- this.logEvent(Object.assign({ message: `start ${sType} request` }, logProps));
359
+ this.logEvent(Object.assign({ message: `${startType} ${sType} request` }, logProps));
315
360
  return ai.adapter.start(startProps)
316
361
  .then(success => {
317
362
  if (success) {
318
- this.emit('start-success', this.getAdapterStateInfo(ai));
363
+ this.emit(`${startType}-success`, this.getAdapterStateInfo(ai));
319
364
  }
320
365
  ai.isStarted = true;
321
- this.logEvent(Object.assign({ message: `start ${sType} request finished` }, logProps));
366
+ this.logEvent(Object.assign({ message: `${startType} ${sType} request finished` }, logProps));
322
367
  return success;
323
368
  })
324
369
  .catch(err => {
325
370
  ai.isStarted = false;
326
- this.logEvent(Object.assign(Object.assign({ message: `start ${sType} request failed` }, logProps), { reason: err.message }));
327
- this.emit('start-error', this.getAdapterStateInfo(ai), err);
371
+ this.logEvent(Object.assign(Object.assign({ message: `${startType} ${sType} request failed` }, logProps), { reason: err.message }));
372
+ this.emit(`${startType}-error`, this.getAdapterStateInfo(ai), err);
328
373
  return false;
329
374
  });
330
375
  });
331
376
  const status = yield Promise.all(this.startPromises);
332
377
  const allOK = status.find(s => s === false) === undefined;
333
- this.emit('start-result', allOK);
378
+ this.emit(`${startType}-result`, allOK);
334
379
  if (allOK) {
335
380
  this.startRide(props);
336
381
  }
@@ -338,6 +383,17 @@ class DeviceRideService extends events_1.default {
338
383
  return allOK;
339
384
  });
340
385
  }
386
+ start(props) {
387
+ return __awaiter(this, void 0, void 0, function* () {
388
+ yield this.lazyInit();
389
+ const adapters = this.getAdapterList();
390
+ this.emit('start-request', adapters.map(this.getAdapterStateInfo));
391
+ const goodToGo = yield this.waitForPreviousStartToFinish();
392
+ if (!goodToGo)
393
+ return;
394
+ return this.startAdapters(adapters, 'start', props);
395
+ });
396
+ }
341
397
  cancelStart() {
342
398
  return __awaiter(this, void 0, void 0, function* () {
343
399
  const adapters = this.getAdapterList();
@@ -386,6 +442,8 @@ class DeviceRideService extends events_1.default {
386
442
  const hasControl = adapters.find(ai => ai.capabilities.includes(incyclist_devices_1.IncyclistCapability.Control)) !== undefined;
387
443
  const hasPower = adapters.find(ai => ai.capabilities.includes(incyclist_devices_1.IncyclistCapability.Power)) !== undefined;
388
444
  const adapterInfo = adapters.find(ai => ai.adapter.isEqual(deviceSettings));
445
+ if (!adapterInfo)
446
+ return;
389
447
  adapterInfo.capabilities.forEach(capability => {
390
448
  switch (capability) {
391
449
  case incyclist_devices_1.IncyclistCapability.HeartRate:
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  function clone(obj) {
4
+ if (obj === null || obj === undefined)
5
+ return obj;
4
6
  return JSON.parse(JSON.stringify(obj));
5
7
  }
6
8
  exports.default = clone;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-services",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "peerDependencies": {
5
5
  "gd-eventlog": "^0.1.22"
6
6
  },
@@ -36,7 +36,7 @@
36
36
  "lib": "./src"
37
37
  },
38
38
  "dependencies": {
39
- "incyclist-devices": "^2.0.3",
39
+ "incyclist-devices": "^2.0.4",
40
40
  "uuid": "^9.0.0"
41
41
  }
42
42
  }