tirecheck-device-sdk 0.1.94 → 0.1.95

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.
package/dist/index.cjs CHANGED
@@ -502,7 +502,7 @@ const deviceMeta = {
502
502
  getDeviceInfoFromAdvertising: bridgeOtaAdvertisingParser.getDeviceInfoFromAdvertising
503
503
  },
504
504
  flexiGaugeTpms: {
505
- nameRegex: /Flexi.*/,
505
+ nameRegex: /^Flexi.*/,
506
506
  communication: {
507
507
  serviceId: "4880c12c-fdcb-4077-8920-a450d7f9b907",
508
508
  characteristicId: "fec26ec4-6d71-4442-9f81-55bc21d658d6"
@@ -565,7 +565,7 @@ const bluetooth = {
565
565
  stopScan() {
566
566
  ble.stopScan();
567
567
  },
568
- connect,
568
+ connect: connect$1,
569
569
  disconnect: disconnect$1,
570
570
  write,
571
571
  read
@@ -592,7 +592,7 @@ async function scanDevices(services = [], duration) {
592
592
  (e) => console.error("ble.startScanWithOptions error:", e)
593
593
  );
594
594
  }
595
- async function connect(deviceId, disconnectCallback) {
595
+ async function connect$1(deviceId, disconnectCallback) {
596
596
  if (toolsSvc.canCommunicateWith(deviceId)) return console.warn("Connect Warn: Already connected to device");
597
597
  store.setState(deviceId, "connecting");
598
598
  let connectedDevice;
@@ -713,6 +713,78 @@ function getDeviceNameFromAdvertising(advertising) {
713
713
  return deviceName;
714
714
  }
715
715
 
716
+ const otaServiceUuid = "1d14d6ee-fd63-4fa1-bfa4-8f47b42119f0";
717
+ const otaControlCharacteristicUuid = "f7bf3564-fb6d-4e53-88a4-5e37e0326063";
718
+ const otaDataCharacteristicUuid = "984227f3-34fc-4045-a5d0-2c581f81a153";
719
+ const bridgeOtaCommands = {
720
+ async beginOta(deviceId) {
721
+ await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([0]).buffer, true);
722
+ },
723
+ async uploadOtaChunk(deviceId, data) {
724
+ await bluetooth.write(deviceId, otaServiceUuid, otaDataCharacteristicUuid, data, true);
725
+ },
726
+ async endOta(deviceId) {
727
+ await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([3]).buffer, true);
728
+ }
729
+ };
730
+
731
+ const bridgeOtaService = {
732
+ async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
733
+ await delay(2e3);
734
+ progressCallback("Connecting to the bridge...", 0.1);
735
+ await bridgeOta.connect(deviceId);
736
+ progressCallback("Uploading bootloader...", 0.12);
737
+ await bridgeOtaCommands.beginOta(deviceId);
738
+ await uploadOta(deviceId, bootloader, (str, percents) => progressCallback(str, 0.12 + percents * 0.2));
739
+ await bridgeOtaCommands.endOta(deviceId);
740
+ progressCallback("Uploading application...", 0.32);
741
+ await bridgeOtaCommands.beginOta(deviceId);
742
+ await uploadOta(deviceId, firmware, (str, percents) => progressCallback(str, 0.32 + percents * 0.5));
743
+ await bridgeOtaCommands.endOta(deviceId);
744
+ progressCallback("Upload completed, disconnecting...", 0.81);
745
+ await bridgeOta.disconnect(deviceId);
746
+ progressCallback("Disconnected...", 1);
747
+ }
748
+ };
749
+ async function uploadOta(deviceId, firmwareBinary, reportStatus) {
750
+ let uploadedBytes = 0;
751
+ let chunkIndex = 0;
752
+ const mtu = store.platform === "android" ? 512 : deviceMeta.bridgeOta.mtu;
753
+ while (uploadedBytes < firmwareBinary.byteLength) {
754
+ if (chunkIndex % 100 === 0)
755
+ reportStatus(
756
+ `Uploading new firmware... (${___default.round(uploadedBytes / 1e3)} / ${___default.round(
757
+ firmwareBinary.byteLength / 1e3
758
+ )} KB)`,
759
+ uploadedBytes / firmwareBinary.byteLength
760
+ );
761
+ const chunkSize = Math.min(mtu - 3, firmwareBinary.byteLength - uploadedBytes);
762
+ const chunk = firmwareBinary.slice(uploadedBytes, uploadedBytes + chunkSize);
763
+ await bridgeOtaCommands.uploadOtaChunk(deviceId, chunk);
764
+ uploadedBytes += chunkSize;
765
+ chunkIndex++;
766
+ }
767
+ }
768
+
769
+ const bridgeOta = {
770
+ async connect(deviceId) {
771
+ await bluetooth.connect(deviceId, this.disconnect);
772
+ const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
773
+ if (store.platform !== "ios") {
774
+ await ble.requestMtu(_deviceId, 512);
775
+ }
776
+ store.setState(deviceId, "paired");
777
+ },
778
+ async disconnect(deviceId, reason) {
779
+ store.setState(deviceId, "disconnecting");
780
+ await bluetooth.disconnect(deviceId);
781
+ store.setState(deviceId, void 0, reason ?? "manualDisconnection");
782
+ },
783
+ async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
784
+ return bridgeOtaService.updateFirmware(deviceId, bootloader, firmware, progressCallback);
785
+ }
786
+ };
787
+
716
788
  const bridgeCommandStructures = {
717
789
  workshopCanSettings: {
718
790
  id: [98, 96],
@@ -1530,25 +1602,26 @@ const bridgeSecurity = {
1530
1602
  };
1531
1603
 
1532
1604
  const bridgeMeta = deviceMeta.bridge;
1533
- let promiseQueue = Promise.resolve();
1534
- let currentResolve = (_v) => {
1535
- };
1536
- let currentReject = (_v) => {
1537
- };
1538
- let responseIdentifier;
1539
- const promiseQueue$1 = {
1540
- clearQueue(message) {
1541
- currentReject(new Error(message ?? "Stopped sending commands"));
1542
- promiseQueue = Promise.resolve();
1543
- responseIdentifier = [];
1605
+ const devicePromiseQueue = {};
1606
+ const deviceCurrentResolve = {};
1607
+ const deviceCurrentReject = {};
1608
+ const deviceResponseIdentifier = {};
1609
+ const promiseQueue = {
1610
+ clearQueue(deviceId, message) {
1611
+ if (deviceCurrentReject[deviceId]) {
1612
+ deviceCurrentReject[deviceId](new Error(message ?? "Stopped sending commands"));
1613
+ }
1614
+ devicePromiseQueue[deviceId] = Promise.resolve();
1615
+ deviceResponseIdentifier[deviceId] = [];
1544
1616
  },
1545
1617
  async enqueue(device, payload) {
1546
- promiseQueue = promiseQueue.then(() => {
1618
+ if (devicePromiseQueue[device.id] === void 0) devicePromiseQueue[device.id] = Promise.resolve();
1619
+ devicePromiseQueue[device.id] = devicePromiseQueue[device.id].then(() => {
1547
1620
  const promise = new Promise((resolve, reject) => {
1548
- currentResolve = resolve;
1549
- currentReject = reject;
1621
+ deviceCurrentResolve[device.id] = resolve;
1622
+ deviceCurrentReject[device.id] = reject;
1550
1623
  const isKeepAlive = payload[3] === commandIds.keepAlive;
1551
- responseIdentifier = [isKeepAlive ? 126 : 0, payload[4]];
1624
+ deviceResponseIdentifier[device.id] = [isKeepAlive ? 126 : 0, payload[4]];
1552
1625
  const signedData = bridgeSecurity.getSignedCommand(device, payload);
1553
1626
  if (!toolsSvc.canCommunicateWith(device.id)) return reject(new Error("Bridge not connected"));
1554
1627
  if (signedData.length > 110) {
@@ -1574,21 +1647,21 @@ const promiseQueue$1 = {
1574
1647
  );
1575
1648
  }
1576
1649
  });
1577
- return withTimeout(promise, 5e3, `Command timed out ${responseIdentifier}`);
1650
+ return withTimeout(promise, 5e3, `Command timed out ${deviceResponseIdentifier[device.id]}, ${device.id}`);
1578
1651
  });
1579
- return promiseQueue;
1652
+ return devicePromiseQueue[device.id];
1580
1653
  },
1581
1654
  async processMessage(deviceId, payload) {
1582
1655
  const numberArray = Array.from(new Uint8Array(payload));
1583
1656
  if (numberArray[3] === 127) {
1584
1657
  console.error(numberArray);
1585
- return currentReject(new Error(`Command not succesful: ${numberArray[4]}`));
1658
+ return deviceCurrentReject[deviceId](new Error(`Command not succesful: ${numberArray[4]}`));
1586
1659
  }
1587
1660
  if ([226, 81].includes(numberArray[3]) && numberArray[4] && toolsSvc.canCommunicateWith(deviceId)) {
1588
1661
  store.bridgeRebootRequired[deviceId] = true;
1589
1662
  }
1590
- if ((!responseIdentifier[0] || numberArray[3] === responseIdentifier[0]) && (!responseIdentifier[1] || numberArray[4] === responseIdentifier[1])) {
1591
- return currentResolve(numberArray);
1663
+ if ((!deviceResponseIdentifier[deviceId][0] || numberArray[3] === deviceResponseIdentifier[deviceId][0]) && (!deviceResponseIdentifier[deviceId][1] || numberArray[4] === deviceResponseIdentifier[deviceId][1])) {
1664
+ return deviceCurrentResolve[deviceId](numberArray);
1592
1665
  }
1593
1666
  console.warn("message from the device not belonging to the pending promise: ", numberArray);
1594
1667
  }
@@ -1975,79 +2048,7 @@ const bridgeCommands = {
1975
2048
  }
1976
2049
  this.sendKeepAliveCommand(device);
1977
2050
  }, 1e4);
1978
- return promiseQueue$1.enqueue(device, writeCommand);
1979
- }
1980
- };
1981
-
1982
- const otaServiceUuid = "1d14d6ee-fd63-4fa1-bfa4-8f47b42119f0";
1983
- const otaControlCharacteristicUuid = "f7bf3564-fb6d-4e53-88a4-5e37e0326063";
1984
- const otaDataCharacteristicUuid = "984227f3-34fc-4045-a5d0-2c581f81a153";
1985
- const bridgeOtaCommands = {
1986
- async beginOta(deviceId) {
1987
- await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([0]).buffer, true);
1988
- },
1989
- async uploadOtaChunk(deviceId, data) {
1990
- await bluetooth.write(deviceId, otaServiceUuid, otaDataCharacteristicUuid, data, true);
1991
- },
1992
- async endOta(deviceId) {
1993
- await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([3]).buffer, true);
1994
- }
1995
- };
1996
-
1997
- const bridgeOtaService = {
1998
- async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
1999
- await delay(2e3);
2000
- progressCallback("Connecting to the bridge...", 0.1);
2001
- await bridgeOta.connect(deviceId);
2002
- progressCallback("Uploading bootloader...", 0.12);
2003
- await bridgeOtaCommands.beginOta(deviceId);
2004
- await uploadOta(deviceId, bootloader, (str, percents) => progressCallback(str, 0.12 + percents * 0.2));
2005
- await bridgeOtaCommands.endOta(deviceId);
2006
- progressCallback("Uploading application...", 0.32);
2007
- await bridgeOtaCommands.beginOta(deviceId);
2008
- await uploadOta(deviceId, firmware, (str, percents) => progressCallback(str, 0.32 + percents * 0.5));
2009
- await bridgeOtaCommands.endOta(deviceId);
2010
- progressCallback("Upload completed, disconnecting...", 0.81);
2011
- await bridgeOta.disconnect(deviceId);
2012
- progressCallback("Disconnected...", 1);
2013
- }
2014
- };
2015
- async function uploadOta(deviceId, firmwareBinary, reportStatus) {
2016
- let uploadedBytes = 0;
2017
- let chunkIndex = 0;
2018
- const mtu = store.platform === "android" ? 512 : deviceMeta.bridgeOta.mtu;
2019
- while (uploadedBytes < firmwareBinary.byteLength) {
2020
- if (chunkIndex % 100 === 0)
2021
- reportStatus(
2022
- `Uploading new firmware... (${___default.round(uploadedBytes / 1e3)} / ${___default.round(
2023
- firmwareBinary.byteLength / 1e3
2024
- )} KB)`,
2025
- uploadedBytes / firmwareBinary.byteLength
2026
- );
2027
- const chunkSize = Math.min(mtu - 3, firmwareBinary.byteLength - uploadedBytes);
2028
- const chunk = firmwareBinary.slice(uploadedBytes, uploadedBytes + chunkSize);
2029
- await bridgeOtaCommands.uploadOtaChunk(deviceId, chunk);
2030
- uploadedBytes += chunkSize;
2031
- chunkIndex++;
2032
- }
2033
- }
2034
-
2035
- const bridgeOta = {
2036
- async connect(deviceId) {
2037
- await bluetooth.connect(deviceId, this.disconnect);
2038
- const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
2039
- if (store.platform !== "ios") {
2040
- await ble.requestMtu(_deviceId, 512);
2041
- }
2042
- store.setState(deviceId, "paired");
2043
- },
2044
- async disconnect(deviceId, reason) {
2045
- store.setState(deviceId, "disconnecting");
2046
- await bluetooth.disconnect(deviceId);
2047
- store.setState(deviceId, void 0, reason ?? "manualDisconnection");
2048
- },
2049
- async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
2050
- return bridgeOtaService.updateFirmware(deviceId, bootloader, firmware, progressCallback);
2051
+ return promiseQueue.enqueue(device, writeCommand);
2051
2052
  }
2052
2053
  };
2053
2054
 
@@ -2069,8 +2070,13 @@ const bridgeService = {
2069
2070
  getVehicleReadings,
2070
2071
  resetAutolearnStatuses,
2071
2072
  getAutolearnStatuses,
2072
- isRebootRequired
2073
+ isRebootRequired,
2074
+ sendPinCommand
2073
2075
  };
2076
+ async function sendPinCommand(deviceId) {
2077
+ if (!canCommunicateWith(deviceId)) throw new Error("Bridge not connected");
2078
+ await bridgeCommands.sendPinCommand(deviceId);
2079
+ }
2074
2080
  async function updateFirmware(deviceId, bootloader, firmware, reportStatus) {
2075
2081
  reportStatus("Sending OTA Request...", 0.02);
2076
2082
  await bridgeCommands.sendOtaRequest(deviceId);
@@ -2392,7 +2398,7 @@ async function getVehicleReadings(deviceId, tcVehicle) {
2392
2398
  try {
2393
2399
  for (const vehicleTyre of tcVehicle.tcTyres) {
2394
2400
  if (vehicleTyre.tcTpmsSensor && vehicleTyre.mountedOn?.positionId) {
2395
- if (!canCommunicateWith(deviceId)) throw new Error("getVehicleReadings: no connected bridge");
2401
+ if (!canCommunicateWith(deviceId)) break;
2396
2402
  const reading = await getSensorReading(deviceId, vehicleTyre.mountedOn.positionId);
2397
2403
  readings.push(reading);
2398
2404
  }
@@ -2690,12 +2696,28 @@ function isRebootRequired(deviceId) {
2690
2696
 
2691
2697
  const bridge = {
2692
2698
  disconnect,
2693
- async connect(deviceId, accessLevel) {
2694
- if (canCommunicateWith(deviceId)) return;
2695
- await promiseQueue$1.clearQueue("Previous pending commands aborted");
2696
- const bridgeMeta = deviceMeta.bridge;
2697
- await bluetooth.connect(deviceId, disconnect);
2698
- const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
2699
+ connect,
2700
+ getVehicle: bridgeService.getVehicle,
2701
+ setVehicle: bridgeService.setVehicle,
2702
+ getConfiguration: bridgeService.getConfiguration,
2703
+ setConfiguration: bridgeService.setConfiguration,
2704
+ getSensorReading: bridgeService.getSensorReading,
2705
+ getVehicleReadings: bridgeService.getVehicleReadings,
2706
+ getAutolearnStatuses: bridgeService.getAutolearnStatuses,
2707
+ resetAutolearnStatuses: bridgeService.resetAutolearnStatuses,
2708
+ updateFirmware: bridgeService.updateFirmware,
2709
+ isRebootRequired: bridgeService.isRebootRequired
2710
+ };
2711
+ async function connect(deviceId, accessLevel) {
2712
+ if (canCommunicateWith(deviceId)) return;
2713
+ await promiseQueue.clearQueue(deviceId, "Previous pending commands aborted");
2714
+ const bridgeMeta = deviceMeta.bridge;
2715
+ await bluetooth.connect(deviceId, disconnect);
2716
+ if (store.deviceState[deviceId] === "paired") {
2717
+ return console.warn("Connect Warn: Already connected");
2718
+ }
2719
+ const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
2720
+ try {
2699
2721
  if (store.platform !== "ios") {
2700
2722
  await ble.requestMtu(_deviceId, deviceMeta.bridge.mtu);
2701
2723
  }
@@ -2703,28 +2725,22 @@ const bridge = {
2703
2725
  _deviceId,
2704
2726
  bridgeMeta.communication.serviceId,
2705
2727
  bridgeMeta.communication.characteristicId,
2706
- (notification) => promiseQueue$1.processMessage(deviceId, notification),
2728
+ (notification) => promiseQueue.processMessage(deviceId, notification),
2707
2729
  (error) => console.error("startNotification Error", error)
2708
2730
  );
2709
2731
  store.deviceAccessLevel[deviceId] = accessLevel ?? "driver";
2710
2732
  store.bridgeRebootRequired[deviceId] = false;
2711
- await bridgeCommands.sendPinCommand(deviceId);
2733
+ await bridgeService.sendPinCommand(deviceId);
2712
2734
  store.setState(deviceId, "paired");
2713
- },
2714
- getVehicle: bridgeService.getVehicle,
2715
- setVehicle: bridgeService.setVehicle,
2716
- getConfiguration: bridgeService.getConfiguration,
2717
- setConfiguration: bridgeService.setConfiguration,
2718
- getSensorReading: bridgeService.getSensorReading,
2719
- getVehicleReadings: bridgeService.getVehicleReadings,
2720
- getAutolearnStatuses: bridgeService.getAutolearnStatuses,
2721
- resetAutolearnStatuses: bridgeService.resetAutolearnStatuses,
2722
- updateFirmware: bridgeService.updateFirmware,
2723
- isRebootRequired: bridgeService.isRebootRequired
2724
- };
2735
+ } catch (e) {
2736
+ disconnect(deviceId);
2737
+ throw new Error(`Pairing unsuccessful ${e}`);
2738
+ }
2739
+ }
2725
2740
  async function disconnect(deviceId, reason) {
2741
+ await waitUntil(() => store.deviceState[deviceId] === "paired" || store.deviceState[deviceId] === void 0);
2726
2742
  store.setState(deviceId, "disconnecting");
2727
- promiseQueue$1.clearQueue("Previous pending commands aborted");
2743
+ promiseQueue.clearQueue(deviceId, "Previous pending commands aborted");
2728
2744
  await bluetooth.disconnect(deviceId);
2729
2745
  delete store.devices[deviceId];
2730
2746
  deviceUnreachableCallback?.(deviceId);
package/dist/index.d.cts CHANGED
@@ -809,7 +809,7 @@ type Wrapper<T extends Record<string, (...args: any) => any>> = {
809
809
  };
810
810
  type ReportStatusFn = (status: string, completionPercentage: number) => void;
811
811
  type DeviceState = 'connected' | 'connecting' | 'disconnecting' | 'paired' | undefined;
812
- type StateReason = 'lostConnection' | 'manualDisconnection' | 'failedConnection' | 'failedDisconnection' | 'firmwareUpdate';
812
+ type StateReason = 'lostConnection' | 'manualDisconnection' | 'failedConnection' | 'failedDisconnection' | 'firmwareUpdate' | string;
813
813
  interface EventHandlers {
814
814
  'fg:treadDepth'?: (deviceId: string, value: number) => void;
815
815
  'fg:button'?: (deviceId: string, value: string) => void;
@@ -836,7 +836,7 @@ declare function createTirecheckDeviceSdk(platform: DevicePlatform, bleImplement
836
836
  /** Methods for working with Tirecheck CAN Bridge */
837
837
  bridge: {
838
838
  disconnect: (deviceId: string, reason?: StateReason) => Promise<void>;
839
- connect(deviceId: string, accessLevel: BridgeAccessLevel): Promise<void>;
839
+ connect: (deviceId: string, accessLevel: BridgeAccessLevel) => Promise<void>;
840
840
  getVehicle: (deviceId: string) => Promise<BridgeTcVehicle>;
841
841
  setVehicle: (deviceId: string, tcVehicle: BridgeTcVehicle) => Promise<void>;
842
842
  getConfiguration: (deviceId: string) => Promise<BridgeConfiguration>;
package/dist/index.d.mts CHANGED
@@ -809,7 +809,7 @@ type Wrapper<T extends Record<string, (...args: any) => any>> = {
809
809
  };
810
810
  type ReportStatusFn = (status: string, completionPercentage: number) => void;
811
811
  type DeviceState = 'connected' | 'connecting' | 'disconnecting' | 'paired' | undefined;
812
- type StateReason = 'lostConnection' | 'manualDisconnection' | 'failedConnection' | 'failedDisconnection' | 'firmwareUpdate';
812
+ type StateReason = 'lostConnection' | 'manualDisconnection' | 'failedConnection' | 'failedDisconnection' | 'firmwareUpdate' | string;
813
813
  interface EventHandlers {
814
814
  'fg:treadDepth'?: (deviceId: string, value: number) => void;
815
815
  'fg:button'?: (deviceId: string, value: string) => void;
@@ -836,7 +836,7 @@ declare function createTirecheckDeviceSdk(platform: DevicePlatform, bleImplement
836
836
  /** Methods for working with Tirecheck CAN Bridge */
837
837
  bridge: {
838
838
  disconnect: (deviceId: string, reason?: StateReason) => Promise<void>;
839
- connect(deviceId: string, accessLevel: BridgeAccessLevel): Promise<void>;
839
+ connect: (deviceId: string, accessLevel: BridgeAccessLevel) => Promise<void>;
840
840
  getVehicle: (deviceId: string) => Promise<BridgeTcVehicle>;
841
841
  setVehicle: (deviceId: string, tcVehicle: BridgeTcVehicle) => Promise<void>;
842
842
  getConfiguration: (deviceId: string) => Promise<BridgeConfiguration>;
package/dist/index.d.ts CHANGED
@@ -809,7 +809,7 @@ type Wrapper<T extends Record<string, (...args: any) => any>> = {
809
809
  };
810
810
  type ReportStatusFn = (status: string, completionPercentage: number) => void;
811
811
  type DeviceState = 'connected' | 'connecting' | 'disconnecting' | 'paired' | undefined;
812
- type StateReason = 'lostConnection' | 'manualDisconnection' | 'failedConnection' | 'failedDisconnection' | 'firmwareUpdate';
812
+ type StateReason = 'lostConnection' | 'manualDisconnection' | 'failedConnection' | 'failedDisconnection' | 'firmwareUpdate' | string;
813
813
  interface EventHandlers {
814
814
  'fg:treadDepth'?: (deviceId: string, value: number) => void;
815
815
  'fg:button'?: (deviceId: string, value: string) => void;
@@ -836,7 +836,7 @@ declare function createTirecheckDeviceSdk(platform: DevicePlatform, bleImplement
836
836
  /** Methods for working with Tirecheck CAN Bridge */
837
837
  bridge: {
838
838
  disconnect: (deviceId: string, reason?: StateReason) => Promise<void>;
839
- connect(deviceId: string, accessLevel: BridgeAccessLevel): Promise<void>;
839
+ connect: (deviceId: string, accessLevel: BridgeAccessLevel) => Promise<void>;
840
840
  getVehicle: (deviceId: string) => Promise<BridgeTcVehicle>;
841
841
  setVehicle: (deviceId: string, tcVehicle: BridgeTcVehicle) => Promise<void>;
842
842
  getConfiguration: (deviceId: string) => Promise<BridgeConfiguration>;
package/dist/index.mjs CHANGED
@@ -495,7 +495,7 @@ const deviceMeta = {
495
495
  getDeviceInfoFromAdvertising: bridgeOtaAdvertisingParser.getDeviceInfoFromAdvertising
496
496
  },
497
497
  flexiGaugeTpms: {
498
- nameRegex: /Flexi.*/,
498
+ nameRegex: /^Flexi.*/,
499
499
  communication: {
500
500
  serviceId: "4880c12c-fdcb-4077-8920-a450d7f9b907",
501
501
  characteristicId: "fec26ec4-6d71-4442-9f81-55bc21d658d6"
@@ -558,7 +558,7 @@ const bluetooth = {
558
558
  stopScan() {
559
559
  ble.stopScan();
560
560
  },
561
- connect,
561
+ connect: connect$1,
562
562
  disconnect: disconnect$1,
563
563
  write,
564
564
  read
@@ -585,7 +585,7 @@ async function scanDevices(services = [], duration) {
585
585
  (e) => console.error("ble.startScanWithOptions error:", e)
586
586
  );
587
587
  }
588
- async function connect(deviceId, disconnectCallback) {
588
+ async function connect$1(deviceId, disconnectCallback) {
589
589
  if (toolsSvc.canCommunicateWith(deviceId)) return console.warn("Connect Warn: Already connected to device");
590
590
  store.setState(deviceId, "connecting");
591
591
  let connectedDevice;
@@ -706,6 +706,78 @@ function getDeviceNameFromAdvertising(advertising) {
706
706
  return deviceName;
707
707
  }
708
708
 
709
+ const otaServiceUuid = "1d14d6ee-fd63-4fa1-bfa4-8f47b42119f0";
710
+ const otaControlCharacteristicUuid = "f7bf3564-fb6d-4e53-88a4-5e37e0326063";
711
+ const otaDataCharacteristicUuid = "984227f3-34fc-4045-a5d0-2c581f81a153";
712
+ const bridgeOtaCommands = {
713
+ async beginOta(deviceId) {
714
+ await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([0]).buffer, true);
715
+ },
716
+ async uploadOtaChunk(deviceId, data) {
717
+ await bluetooth.write(deviceId, otaServiceUuid, otaDataCharacteristicUuid, data, true);
718
+ },
719
+ async endOta(deviceId) {
720
+ await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([3]).buffer, true);
721
+ }
722
+ };
723
+
724
+ const bridgeOtaService = {
725
+ async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
726
+ await delay(2e3);
727
+ progressCallback("Connecting to the bridge...", 0.1);
728
+ await bridgeOta.connect(deviceId);
729
+ progressCallback("Uploading bootloader...", 0.12);
730
+ await bridgeOtaCommands.beginOta(deviceId);
731
+ await uploadOta(deviceId, bootloader, (str, percents) => progressCallback(str, 0.12 + percents * 0.2));
732
+ await bridgeOtaCommands.endOta(deviceId);
733
+ progressCallback("Uploading application...", 0.32);
734
+ await bridgeOtaCommands.beginOta(deviceId);
735
+ await uploadOta(deviceId, firmware, (str, percents) => progressCallback(str, 0.32 + percents * 0.5));
736
+ await bridgeOtaCommands.endOta(deviceId);
737
+ progressCallback("Upload completed, disconnecting...", 0.81);
738
+ await bridgeOta.disconnect(deviceId);
739
+ progressCallback("Disconnected...", 1);
740
+ }
741
+ };
742
+ async function uploadOta(deviceId, firmwareBinary, reportStatus) {
743
+ let uploadedBytes = 0;
744
+ let chunkIndex = 0;
745
+ const mtu = store.platform === "android" ? 512 : deviceMeta.bridgeOta.mtu;
746
+ while (uploadedBytes < firmwareBinary.byteLength) {
747
+ if (chunkIndex % 100 === 0)
748
+ reportStatus(
749
+ `Uploading new firmware... (${_.round(uploadedBytes / 1e3)} / ${_.round(
750
+ firmwareBinary.byteLength / 1e3
751
+ )} KB)`,
752
+ uploadedBytes / firmwareBinary.byteLength
753
+ );
754
+ const chunkSize = Math.min(mtu - 3, firmwareBinary.byteLength - uploadedBytes);
755
+ const chunk = firmwareBinary.slice(uploadedBytes, uploadedBytes + chunkSize);
756
+ await bridgeOtaCommands.uploadOtaChunk(deviceId, chunk);
757
+ uploadedBytes += chunkSize;
758
+ chunkIndex++;
759
+ }
760
+ }
761
+
762
+ const bridgeOta = {
763
+ async connect(deviceId) {
764
+ await bluetooth.connect(deviceId, this.disconnect);
765
+ const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
766
+ if (store.platform !== "ios") {
767
+ await ble.requestMtu(_deviceId, 512);
768
+ }
769
+ store.setState(deviceId, "paired");
770
+ },
771
+ async disconnect(deviceId, reason) {
772
+ store.setState(deviceId, "disconnecting");
773
+ await bluetooth.disconnect(deviceId);
774
+ store.setState(deviceId, void 0, reason ?? "manualDisconnection");
775
+ },
776
+ async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
777
+ return bridgeOtaService.updateFirmware(deviceId, bootloader, firmware, progressCallback);
778
+ }
779
+ };
780
+
709
781
  const bridgeCommandStructures = {
710
782
  workshopCanSettings: {
711
783
  id: [98, 96],
@@ -1523,25 +1595,26 @@ const bridgeSecurity = {
1523
1595
  };
1524
1596
 
1525
1597
  const bridgeMeta = deviceMeta.bridge;
1526
- let promiseQueue = Promise.resolve();
1527
- let currentResolve = (_v) => {
1528
- };
1529
- let currentReject = (_v) => {
1530
- };
1531
- let responseIdentifier;
1532
- const promiseQueue$1 = {
1533
- clearQueue(message) {
1534
- currentReject(new Error(message ?? "Stopped sending commands"));
1535
- promiseQueue = Promise.resolve();
1536
- responseIdentifier = [];
1598
+ const devicePromiseQueue = {};
1599
+ const deviceCurrentResolve = {};
1600
+ const deviceCurrentReject = {};
1601
+ const deviceResponseIdentifier = {};
1602
+ const promiseQueue = {
1603
+ clearQueue(deviceId, message) {
1604
+ if (deviceCurrentReject[deviceId]) {
1605
+ deviceCurrentReject[deviceId](new Error(message ?? "Stopped sending commands"));
1606
+ }
1607
+ devicePromiseQueue[deviceId] = Promise.resolve();
1608
+ deviceResponseIdentifier[deviceId] = [];
1537
1609
  },
1538
1610
  async enqueue(device, payload) {
1539
- promiseQueue = promiseQueue.then(() => {
1611
+ if (devicePromiseQueue[device.id] === void 0) devicePromiseQueue[device.id] = Promise.resolve();
1612
+ devicePromiseQueue[device.id] = devicePromiseQueue[device.id].then(() => {
1540
1613
  const promise = new Promise((resolve, reject) => {
1541
- currentResolve = resolve;
1542
- currentReject = reject;
1614
+ deviceCurrentResolve[device.id] = resolve;
1615
+ deviceCurrentReject[device.id] = reject;
1543
1616
  const isKeepAlive = payload[3] === commandIds.keepAlive;
1544
- responseIdentifier = [isKeepAlive ? 126 : 0, payload[4]];
1617
+ deviceResponseIdentifier[device.id] = [isKeepAlive ? 126 : 0, payload[4]];
1545
1618
  const signedData = bridgeSecurity.getSignedCommand(device, payload);
1546
1619
  if (!toolsSvc.canCommunicateWith(device.id)) return reject(new Error("Bridge not connected"));
1547
1620
  if (signedData.length > 110) {
@@ -1567,21 +1640,21 @@ const promiseQueue$1 = {
1567
1640
  );
1568
1641
  }
1569
1642
  });
1570
- return withTimeout(promise, 5e3, `Command timed out ${responseIdentifier}`);
1643
+ return withTimeout(promise, 5e3, `Command timed out ${deviceResponseIdentifier[device.id]}, ${device.id}`);
1571
1644
  });
1572
- return promiseQueue;
1645
+ return devicePromiseQueue[device.id];
1573
1646
  },
1574
1647
  async processMessage(deviceId, payload) {
1575
1648
  const numberArray = Array.from(new Uint8Array(payload));
1576
1649
  if (numberArray[3] === 127) {
1577
1650
  console.error(numberArray);
1578
- return currentReject(new Error(`Command not succesful: ${numberArray[4]}`));
1651
+ return deviceCurrentReject[deviceId](new Error(`Command not succesful: ${numberArray[4]}`));
1579
1652
  }
1580
1653
  if ([226, 81].includes(numberArray[3]) && numberArray[4] && toolsSvc.canCommunicateWith(deviceId)) {
1581
1654
  store.bridgeRebootRequired[deviceId] = true;
1582
1655
  }
1583
- if ((!responseIdentifier[0] || numberArray[3] === responseIdentifier[0]) && (!responseIdentifier[1] || numberArray[4] === responseIdentifier[1])) {
1584
- return currentResolve(numberArray);
1656
+ if ((!deviceResponseIdentifier[deviceId][0] || numberArray[3] === deviceResponseIdentifier[deviceId][0]) && (!deviceResponseIdentifier[deviceId][1] || numberArray[4] === deviceResponseIdentifier[deviceId][1])) {
1657
+ return deviceCurrentResolve[deviceId](numberArray);
1585
1658
  }
1586
1659
  console.warn("message from the device not belonging to the pending promise: ", numberArray);
1587
1660
  }
@@ -1968,79 +2041,7 @@ const bridgeCommands = {
1968
2041
  }
1969
2042
  this.sendKeepAliveCommand(device);
1970
2043
  }, 1e4);
1971
- return promiseQueue$1.enqueue(device, writeCommand);
1972
- }
1973
- };
1974
-
1975
- const otaServiceUuid = "1d14d6ee-fd63-4fa1-bfa4-8f47b42119f0";
1976
- const otaControlCharacteristicUuid = "f7bf3564-fb6d-4e53-88a4-5e37e0326063";
1977
- const otaDataCharacteristicUuid = "984227f3-34fc-4045-a5d0-2c581f81a153";
1978
- const bridgeOtaCommands = {
1979
- async beginOta(deviceId) {
1980
- await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([0]).buffer, true);
1981
- },
1982
- async uploadOtaChunk(deviceId, data) {
1983
- await bluetooth.write(deviceId, otaServiceUuid, otaDataCharacteristicUuid, data, true);
1984
- },
1985
- async endOta(deviceId) {
1986
- await bluetooth.write(deviceId, otaServiceUuid, otaControlCharacteristicUuid, new Uint8Array([3]).buffer, true);
1987
- }
1988
- };
1989
-
1990
- const bridgeOtaService = {
1991
- async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
1992
- await delay(2e3);
1993
- progressCallback("Connecting to the bridge...", 0.1);
1994
- await bridgeOta.connect(deviceId);
1995
- progressCallback("Uploading bootloader...", 0.12);
1996
- await bridgeOtaCommands.beginOta(deviceId);
1997
- await uploadOta(deviceId, bootloader, (str, percents) => progressCallback(str, 0.12 + percents * 0.2));
1998
- await bridgeOtaCommands.endOta(deviceId);
1999
- progressCallback("Uploading application...", 0.32);
2000
- await bridgeOtaCommands.beginOta(deviceId);
2001
- await uploadOta(deviceId, firmware, (str, percents) => progressCallback(str, 0.32 + percents * 0.5));
2002
- await bridgeOtaCommands.endOta(deviceId);
2003
- progressCallback("Upload completed, disconnecting...", 0.81);
2004
- await bridgeOta.disconnect(deviceId);
2005
- progressCallback("Disconnected...", 1);
2006
- }
2007
- };
2008
- async function uploadOta(deviceId, firmwareBinary, reportStatus) {
2009
- let uploadedBytes = 0;
2010
- let chunkIndex = 0;
2011
- const mtu = store.platform === "android" ? 512 : deviceMeta.bridgeOta.mtu;
2012
- while (uploadedBytes < firmwareBinary.byteLength) {
2013
- if (chunkIndex % 100 === 0)
2014
- reportStatus(
2015
- `Uploading new firmware... (${_.round(uploadedBytes / 1e3)} / ${_.round(
2016
- firmwareBinary.byteLength / 1e3
2017
- )} KB)`,
2018
- uploadedBytes / firmwareBinary.byteLength
2019
- );
2020
- const chunkSize = Math.min(mtu - 3, firmwareBinary.byteLength - uploadedBytes);
2021
- const chunk = firmwareBinary.slice(uploadedBytes, uploadedBytes + chunkSize);
2022
- await bridgeOtaCommands.uploadOtaChunk(deviceId, chunk);
2023
- uploadedBytes += chunkSize;
2024
- chunkIndex++;
2025
- }
2026
- }
2027
-
2028
- const bridgeOta = {
2029
- async connect(deviceId) {
2030
- await bluetooth.connect(deviceId, this.disconnect);
2031
- const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
2032
- if (store.platform !== "ios") {
2033
- await ble.requestMtu(_deviceId, 512);
2034
- }
2035
- store.setState(deviceId, "paired");
2036
- },
2037
- async disconnect(deviceId, reason) {
2038
- store.setState(deviceId, "disconnecting");
2039
- await bluetooth.disconnect(deviceId);
2040
- store.setState(deviceId, void 0, reason ?? "manualDisconnection");
2041
- },
2042
- async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
2043
- return bridgeOtaService.updateFirmware(deviceId, bootloader, firmware, progressCallback);
2044
+ return promiseQueue.enqueue(device, writeCommand);
2044
2045
  }
2045
2046
  };
2046
2047
 
@@ -2062,8 +2063,13 @@ const bridgeService = {
2062
2063
  getVehicleReadings,
2063
2064
  resetAutolearnStatuses,
2064
2065
  getAutolearnStatuses,
2065
- isRebootRequired
2066
+ isRebootRequired,
2067
+ sendPinCommand
2066
2068
  };
2069
+ async function sendPinCommand(deviceId) {
2070
+ if (!canCommunicateWith(deviceId)) throw new Error("Bridge not connected");
2071
+ await bridgeCommands.sendPinCommand(deviceId);
2072
+ }
2067
2073
  async function updateFirmware(deviceId, bootloader, firmware, reportStatus) {
2068
2074
  reportStatus("Sending OTA Request...", 0.02);
2069
2075
  await bridgeCommands.sendOtaRequest(deviceId);
@@ -2385,7 +2391,7 @@ async function getVehicleReadings(deviceId, tcVehicle) {
2385
2391
  try {
2386
2392
  for (const vehicleTyre of tcVehicle.tcTyres) {
2387
2393
  if (vehicleTyre.tcTpmsSensor && vehicleTyre.mountedOn?.positionId) {
2388
- if (!canCommunicateWith(deviceId)) throw new Error("getVehicleReadings: no connected bridge");
2394
+ if (!canCommunicateWith(deviceId)) break;
2389
2395
  const reading = await getSensorReading(deviceId, vehicleTyre.mountedOn.positionId);
2390
2396
  readings.push(reading);
2391
2397
  }
@@ -2683,12 +2689,28 @@ function isRebootRequired(deviceId) {
2683
2689
 
2684
2690
  const bridge = {
2685
2691
  disconnect,
2686
- async connect(deviceId, accessLevel) {
2687
- if (canCommunicateWith(deviceId)) return;
2688
- await promiseQueue$1.clearQueue("Previous pending commands aborted");
2689
- const bridgeMeta = deviceMeta.bridge;
2690
- await bluetooth.connect(deviceId, disconnect);
2691
- const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
2692
+ connect,
2693
+ getVehicle: bridgeService.getVehicle,
2694
+ setVehicle: bridgeService.setVehicle,
2695
+ getConfiguration: bridgeService.getConfiguration,
2696
+ setConfiguration: bridgeService.setConfiguration,
2697
+ getSensorReading: bridgeService.getSensorReading,
2698
+ getVehicleReadings: bridgeService.getVehicleReadings,
2699
+ getAutolearnStatuses: bridgeService.getAutolearnStatuses,
2700
+ resetAutolearnStatuses: bridgeService.resetAutolearnStatuses,
2701
+ updateFirmware: bridgeService.updateFirmware,
2702
+ isRebootRequired: bridgeService.isRebootRequired
2703
+ };
2704
+ async function connect(deviceId, accessLevel) {
2705
+ if (canCommunicateWith(deviceId)) return;
2706
+ await promiseQueue.clearQueue(deviceId, "Previous pending commands aborted");
2707
+ const bridgeMeta = deviceMeta.bridge;
2708
+ await bluetooth.connect(deviceId, disconnect);
2709
+ if (store.deviceState[deviceId] === "paired") {
2710
+ return console.warn("Connect Warn: Already connected");
2711
+ }
2712
+ const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
2713
+ try {
2692
2714
  if (store.platform !== "ios") {
2693
2715
  await ble.requestMtu(_deviceId, deviceMeta.bridge.mtu);
2694
2716
  }
@@ -2696,28 +2718,22 @@ const bridge = {
2696
2718
  _deviceId,
2697
2719
  bridgeMeta.communication.serviceId,
2698
2720
  bridgeMeta.communication.characteristicId,
2699
- (notification) => promiseQueue$1.processMessage(deviceId, notification),
2721
+ (notification) => promiseQueue.processMessage(deviceId, notification),
2700
2722
  (error) => console.error("startNotification Error", error)
2701
2723
  );
2702
2724
  store.deviceAccessLevel[deviceId] = accessLevel ?? "driver";
2703
2725
  store.bridgeRebootRequired[deviceId] = false;
2704
- await bridgeCommands.sendPinCommand(deviceId);
2726
+ await bridgeService.sendPinCommand(deviceId);
2705
2727
  store.setState(deviceId, "paired");
2706
- },
2707
- getVehicle: bridgeService.getVehicle,
2708
- setVehicle: bridgeService.setVehicle,
2709
- getConfiguration: bridgeService.getConfiguration,
2710
- setConfiguration: bridgeService.setConfiguration,
2711
- getSensorReading: bridgeService.getSensorReading,
2712
- getVehicleReadings: bridgeService.getVehicleReadings,
2713
- getAutolearnStatuses: bridgeService.getAutolearnStatuses,
2714
- resetAutolearnStatuses: bridgeService.resetAutolearnStatuses,
2715
- updateFirmware: bridgeService.updateFirmware,
2716
- isRebootRequired: bridgeService.isRebootRequired
2717
- };
2728
+ } catch (e) {
2729
+ disconnect(deviceId);
2730
+ throw new Error(`Pairing unsuccessful ${e}`);
2731
+ }
2732
+ }
2718
2733
  async function disconnect(deviceId, reason) {
2734
+ await waitUntil(() => store.deviceState[deviceId] === "paired" || store.deviceState[deviceId] === void 0);
2719
2735
  store.setState(deviceId, "disconnecting");
2720
- promiseQueue$1.clearQueue("Previous pending commands aborted");
2736
+ promiseQueue.clearQueue(deviceId, "Previous pending commands aborted");
2721
2737
  await bluetooth.disconnect(deviceId);
2722
2738
  delete store.devices[deviceId];
2723
2739
  deviceUnreachableCallback?.(deviceId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tirecheck-device-sdk",
3
- "version": "0.1.94",
3
+ "version": "0.1.95",
4
4
  "description": "SDK for working with various devices produced by Tirecheck via Bluetooth (CAN Bridge, Routers, Sensors, FlexiGauge, PressureStick, etc)",
5
5
  "author": "Leonid Buneev <leonid.buneev@tirecheck.com>",
6
6
  "license": "ISC",