tirecheck-device-sdk 0.2.70 → 0.2.72

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.mjs CHANGED
@@ -127,6 +127,19 @@ function normalizeError(error) {
127
127
  return error;
128
128
  }
129
129
 
130
+ const emptyBluetoothClassicSerialImplementation = {
131
+ list: async () => [],
132
+ discoverUnpaired: async () => [],
133
+ setDeviceDiscoveredListener: () => {
134
+ },
135
+ clearDeviceDiscoveredListener: () => {
136
+ }
137
+ };
138
+ let bluetoothClassicSerial = emptyBluetoothClassicSerialImplementation;
139
+ function setBluetoothClassicSerialImplementation(bluetoothClassicSerialImplementation) {
140
+ bluetoothClassicSerial = bluetoothClassicSerialImplementation ?? emptyBluetoothClassicSerialImplementation;
141
+ }
142
+
130
143
  const tyreLabels = getDefaultTyreLabels();
131
144
  const bridgeTools = {
132
145
  getBridgeFromStore,
@@ -159,7 +172,7 @@ const bridgeTools = {
159
172
  );
160
173
  const result = [];
161
174
  for (const key of keys) {
162
- if (!structurizedObj[key]) throw new Error(`Missing key ${key} in the structure`);
175
+ if (structurizedObj[key] == null) throw new Error(`Missing key ${key} in the structure`);
163
176
  const encoded = this.encodeData(structurizedObj[key], objStructure[key].display);
164
177
  if (encoded.length < objStructure[key].size) {
165
178
  const _padArray = Array.from({ length: objStructure[key].size - encoded.length }, () => 0);
@@ -199,7 +212,8 @@ const bridgeTools = {
199
212
  return this.asciiToDecimalArray(_data);
200
213
  }
201
214
  if (displayUnits === "decimal") {
202
- return this.hexToDecimalArray(decimalToHex(_data)).reverse();
215
+ const hex = decimalToHex(_data);
216
+ return this.hexToDecimalArray(hex.length % 2 ? `0${hex}` : hex).reverse();
203
217
  }
204
218
  if (displayUnits === "reverseHex") {
205
219
  const byteArray = _data.match(/.{1,2}/g) || [];
@@ -650,6 +664,17 @@ const deviceMeta = {
650
664
  };
651
665
  return bleDevice;
652
666
  }
667
+ },
668
+ unitechRfid: {
669
+ nameRegex: /^RP902/i,
670
+ transport: "serial",
671
+ getDeviceInfoFromAdvertising: (device) => {
672
+ const bleDevice = {
673
+ ...device,
674
+ type: "unitechRfid"
675
+ };
676
+ return bleDevice;
677
+ }
653
678
  }
654
679
  };
655
680
 
@@ -686,6 +711,8 @@ const bluetooth = {
686
711
  deviceStateChangeCallback = callback;
687
712
  },
688
713
  scanDevices,
714
+ scanSerialDevicesPaired,
715
+ scanSerialDevicesUnpaired,
689
716
  stopScan() {
690
717
  ble.stopScan();
691
718
  },
@@ -716,6 +743,47 @@ async function scanDevices(services = [], duration) {
716
743
  (e) => console.error("ble.startScanWithOptions error:", e)
717
744
  );
718
745
  }
746
+ async function scanSerialDevicesPaired() {
747
+ try {
748
+ const pairedDevices = await bluetoothClassicSerial.list();
749
+ for (const device of pairedDevices ?? []) handleSerialDevice(device);
750
+ } catch (e) {
751
+ console.error("scanPairedSerialDevices error:", e);
752
+ }
753
+ }
754
+ async function scanSerialDevicesUnpaired() {
755
+ bluetoothClassicSerial.setDeviceDiscoveredListener?.((device) => handleSerialDevice(device));
756
+ try {
757
+ const unpairedDevices = await bluetoothClassicSerial.discoverUnpaired();
758
+ for (const device of unpairedDevices ?? []) handleSerialDevice(device);
759
+ } catch (e) {
760
+ const message = (typeof e === "string" ? e : e?.message ?? "").toLowerCase();
761
+ const pickerDismissed = store.platform === "ios" && ["cancel", "alreadyconnected", "already connected", "notfound", "not found"].some((m) => message.includes(m));
762
+ if (pickerDismissed) {
763
+ console.log("discoverSerialDevices: accessory picker returned no unpaired device -", message);
764
+ } else {
765
+ console.error("discoverSerialDevices error:", e);
766
+ }
767
+ } finally {
768
+ bluetoothClassicSerial.clearDeviceDiscoveredListener?.();
769
+ }
770
+ }
771
+ function handleSerialDevice(device) {
772
+ const rawId = device.id ?? device.address;
773
+ const id = rawId != null ? String(rawId) : void 0;
774
+ if (!id) {
775
+ console.warn("handleSerialDevice: skipped, no id/address", device);
776
+ return;
777
+ }
778
+ const peripheral = { id, name: device.name, rssi: device.rssi ?? 0, advertising: {} };
779
+ const processedDevice = processDevice(peripheral);
780
+ if (!processedDevice) {
781
+ console.warn("handleSerialDevice: processDevice returned null (filtered out)", id, device.name);
782
+ return;
783
+ }
784
+ store.devices[processedDevice.id] = processedDevice;
785
+ deviceAdvertisingCallback?.(processedDevice);
786
+ }
719
787
  async function connect$1(deviceId, disconnectCallback) {
720
788
  if (toolsSvc.canCommunicateWith(deviceId)) return console.warn("Connect Warn: Already connected to device");
721
789
  store.setState(deviceId, "connecting");
@@ -804,7 +872,8 @@ function processDevice(device) {
804
872
  console.warn("Error processing advertising", e);
805
873
  return;
806
874
  }
807
- unreachableSvc.refresh(processedDevice.id, deviceUnreachableCallback);
875
+ const isSerial = deviceMeta[deviceType].transport === "serial";
876
+ if (!isSerial) unreachableSvc.refresh(processedDevice.id, deviceUnreachableCallback);
808
877
  return processedDevice;
809
878
  }
810
879
  function getDeviceTypeFromName(name) {
@@ -1777,6 +1846,109 @@ const bridgeCommandStructures = {
1777
1846
  description: "Bluetooth chip FW version: major.minor.patch + release type (e.g. 1.2.0 Release)"
1778
1847
  }
1779
1848
  }
1849
+ },
1850
+ bridgeConfiguration: {
1851
+ id: [98, 1],
1852
+ name: "bridgeConfiguration",
1853
+ structure: {
1854
+ configVersion: {
1855
+ size: 4,
1856
+ description: "Application configuration version details",
1857
+ display: "decimal"
1858
+ },
1859
+ bleTxPower: {
1860
+ size: 2,
1861
+ description: "Used BLE Tx power (16 bit signed value; LSB = 0.1)",
1862
+ display: "decimal"
1863
+ },
1864
+ bleTxChannels: {
1865
+ size: 1,
1866
+ description: "BLE channel configuration (0x07 = all channels)"
1867
+ },
1868
+ bleConnectableAdvPeriod: {
1869
+ size: 2,
1870
+ description: "BLE Connectable Advertisement Period [LSB = 0.625 ms]",
1871
+ display: "decimal"
1872
+ },
1873
+ configurationFlags: {
1874
+ size: 1,
1875
+ description: "Configuration flags (1 = Enable inactivity timeout; 4 = Disable time lockout on false PINs)"
1876
+ },
1877
+ wrongPinsUntilLockout: {
1878
+ size: 1,
1879
+ description: "Minimal number of wrong pins allowed before the lockout activates",
1880
+ display: "decimal"
1881
+ },
1882
+ maxLockoutPeriodIncreases: {
1883
+ size: 1,
1884
+ description: "How many times the lockout period may be doubled",
1885
+ display: "decimal"
1886
+ },
1887
+ wrongPinInitialLockoutTime: {
1888
+ size: 1,
1889
+ description: "Initial lockout time duration after too many wrong PINs",
1890
+ display: "decimal"
1891
+ },
1892
+ securityConfiguration: {
1893
+ size: 1,
1894
+ description: "Bluetooth security configuration (0x03 - legacy pairing enabled; 0x07 - disabled)"
1895
+ },
1896
+ canEnabled: {
1897
+ size: 1,
1898
+ description: "CAN enabled state",
1899
+ display: "decimal"
1900
+ },
1901
+ bleEnabled: {
1902
+ size: 1,
1903
+ description: "BLE Advertisement enabled state",
1904
+ display: "decimal"
1905
+ },
1906
+ canBitrate: {
1907
+ size: 2,
1908
+ description: "CAN Bitrate [kbps]",
1909
+ display: "decimal"
1910
+ },
1911
+ movementDetectionLimit: {
1912
+ size: 2,
1913
+ description: "Movement detection limit [1/256 kmph per bit]",
1914
+ display: "decimal"
1915
+ },
1916
+ sensorInactivityTimeout: {
1917
+ size: 2,
1918
+ description: "Timeout [s] after which an inactive sensor is marked erroneous (max. 512 s)",
1919
+ display: "decimal"
1920
+ },
1921
+ manufacturerCode: {
1922
+ size: 4,
1923
+ description: "Manufacturer Code as per SAE J1939",
1924
+ display: "decimal"
1925
+ },
1926
+ identityNumber: {
1927
+ size: 4,
1928
+ description: "Identity number for ECU (max. 22 bits = 0x1FFFFF)",
1929
+ display: "decimal"
1930
+ },
1931
+ manufacturerName: {
1932
+ size: 20,
1933
+ description: "Manufacturer Name (SPN 4304, max. 20 bytes)",
1934
+ display: "ascii"
1935
+ },
1936
+ ecuPartNumber: {
1937
+ size: 20,
1938
+ description: "ECU Part Number (SPN 2901, max. 20 bytes)",
1939
+ display: "ascii"
1940
+ },
1941
+ softwareVersion: {
1942
+ size: 20,
1943
+ description: "Software Version (SPN 234, max. 20 bytes)",
1944
+ display: "ascii"
1945
+ },
1946
+ reservedConfiguration: {
1947
+ size: 4,
1948
+ description: "Reserved configuration",
1949
+ display: "decimal"
1950
+ }
1951
+ }
1780
1952
  }
1781
1953
  };
1782
1954
 
@@ -1875,6 +2047,18 @@ const bridgeSecurity = {
1875
2047
  }
1876
2048
  return crc >>> 0;
1877
2049
  },
2050
+ /** CRC-16/CCITT-FALSE (poly 0x1021, init 0xFFFF). Used for the RxSWIN (0xF18F) E010/E141 checksums. */
2051
+ crc16Ccitt(msg) {
2052
+ let crc = 65535;
2053
+ const polynomial = 4129;
2054
+ for (const byte of msg) {
2055
+ crc ^= (byte & 255) << 8;
2056
+ for (let j = 0; j < 8; j++) {
2057
+ crc = crc & 32768 ? (crc << 1 ^ polynomial) & 65535 : crc << 1 & 65535;
2058
+ }
2059
+ }
2060
+ return crc & 65535;
2061
+ },
1878
2062
  getCrcArray(msg) {
1879
2063
  const crc = this.crc32mpeg2(msg);
1880
2064
  const crcHex = decimalToHex(crc).padStart(8, "0");
@@ -2280,6 +2464,21 @@ const bridgeCommands = {
2280
2464
  deviceData.advertisingData.fwVersion
2281
2465
  );
2282
2466
  },
2467
+ async getBridgeConfiguration(deviceId) {
2468
+ const deviceData = bridgeTools.getBridgeFromStore(deviceId);
2469
+ const result = await this.readCommand(deviceData, subCommandIds.bridgeConfiguration);
2470
+ const structurized = bridgeTools.convertBytesToStructure(
2471
+ bridgeCommandStructures.bridgeConfiguration.structure,
2472
+ result.data,
2473
+ deviceData.advertisingData.fwVersion
2474
+ );
2475
+ console.log(
2476
+ `[getBridgeConfiguration] raw payload (${result.data.length}B):`,
2477
+ result.data.map((b) => decimalToHex(b)).join(" ")
2478
+ );
2479
+ console.log("[getBridgeConfiguration] decoded structure:", structurized, `(isFactory: ${result.isFactory})`);
2480
+ return { ...structurized, isFactory: result.isFactory };
2481
+ },
2283
2482
  async getErrorHistoryCounter(deviceId) {
2284
2483
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
2285
2484
  const result = await this.readCommand(deviceData, subCommandIds.errorHistoryCounter, {
@@ -2391,6 +2590,7 @@ const bridgeService = {
2391
2590
  setVehicle,
2392
2591
  getConfiguration,
2393
2592
  setConfiguration,
2593
+ getRxSWIN,
2394
2594
  getSensorReading,
2395
2595
  getVehicleReadings,
2396
2596
  resetAutolearnStatuses,
@@ -2462,7 +2662,7 @@ async function setVehicleLayout(deviceId, tcVehicle) {
2462
2662
  }
2463
2663
  await bridgeCommands.setVehicleLayout(deviceId, result);
2464
2664
  }
2465
- async function getConfiguration(deviceId, includeVehicleData = false) {
2665
+ async function getConfiguration(deviceId) {
2466
2666
  const customerCANSettings = await bridgeCommands.getCustomerCANSettings(deviceId);
2467
2667
  const workshopCANSettings = await bridgeCommands.getWorkshopCANSettings(deviceId);
2468
2668
  const customerPressureThresholds = await bridgeCommands.getCustomerPressureThresholds(deviceId);
@@ -2470,16 +2670,23 @@ async function getConfiguration(deviceId, includeVehicleData = false) {
2470
2670
  const customerImbalanceThresholds = await bridgeCommands.getCustomerImbalanceThresholds(deviceId);
2471
2671
  const pressuresPerAxle = await bridgeCommands.getPressuresPerAxle(deviceId);
2472
2672
  let autolearnSettings;
2673
+ let autolearnIdStatus;
2674
+ let autolearnUnknownSensors;
2473
2675
  let errorHistoryCounter;
2474
2676
  let eolStatus;
2677
+ let firmwareVersion;
2475
2678
  if (bridgeTools.isVersionGreaterThan(deviceId, "0.9.7")) {
2476
2679
  autolearnSettings = await bridgeCommands.getAutolearnSettings(deviceId);
2680
+ autolearnIdStatus = await bridgeCommands.getAutolearnIdStatus(deviceId);
2681
+ autolearnUnknownSensors = await bridgeCommands.getAutolearnUnknownSensors(deviceId);
2477
2682
  }
2478
2683
  if (bridgeTools.isVersionGreaterThan(deviceId, "1.1.F")) {
2479
2684
  errorHistoryCounter = await bridgeCommands.getErrorHistoryCounter(deviceId);
2480
2685
  eolStatus = await bridgeCommands.getEolStatus(deviceId);
2686
+ firmwareVersion = await bridgeCommands.getFirmwareVersion(deviceId);
2481
2687
  }
2482
- const configuration = {
2688
+ const rxswin = await getRxSWIN(deviceId, { customerPressureThresholds, customerCANSettings });
2689
+ return {
2483
2690
  customerCANSettings,
2484
2691
  workshopCANSettings,
2485
2692
  customerPressureThresholds,
@@ -2487,27 +2694,75 @@ async function getConfiguration(deviceId, includeVehicleData = false) {
2487
2694
  customerImbalanceThresholds,
2488
2695
  pressuresPerAxle,
2489
2696
  autolearnSettings,
2697
+ autolearnIdStatus,
2698
+ autolearnUnknownSensors,
2490
2699
  errorHistoryCounter,
2491
- eolStatus
2700
+ eolStatus,
2701
+ firmwareVersion,
2702
+ rxswin
2492
2703
  };
2493
- if (includeVehicleData) {
2494
- configuration.vehicleLayout = await bridgeCommands.getVehicleLayout(deviceId);
2495
- configuration.axleInfo = [];
2496
- for (let axleIndex = 0; axleIndex < 15; axleIndex++) {
2497
- const axleBytes = await bridgeCommands.getAxleInfo(deviceId, axleIndex);
2498
- configuration.axleInfo.push(
2499
- bridgeTools.convertBytesToStructure(bridgeCommandStructures.idsPerWheel.structure, axleBytes)
2500
- );
2501
- }
2502
- if (bridgeTools.isVersionGreaterThan(deviceId, "1.1.F")) {
2503
- configuration.firmwareVersion = await bridgeCommands.getFirmwareVersion(deviceId);
2504
- }
2505
- if (bridgeTools.isVersionGreaterThan(deviceId, "0.9.7")) {
2506
- configuration.autolearnIdStatus = await bridgeCommands.getAutolearnIdStatus(deviceId);
2507
- configuration.autolearnUnknownSensors = await bridgeCommands.getAutolearnUnknownSensors(deviceId);
2508
- }
2509
- }
2510
- return configuration;
2704
+ }
2705
+ async function getRxSWIN(deviceId, configuration) {
2706
+ if (!canCommunicateWith(deviceId)) throw new Error("Bridge not connected");
2707
+ const bridgeConfiguration = bridgeTools.isVersionGreaterThan(deviceId, "1.1.F") ? await bridgeCommands.getBridgeConfiguration(deviceId) : {
2708
+ canEnabled: 1,
2709
+ movementDetectionLimit: 1280,
2710
+ // Firmware default provided as 0x01FA for pre-1.2.0 bridges where record 0x01 is unavailable.
2711
+ sensorInactivityTimeout: 506,
2712
+ bleTxPower: 60,
2713
+ bleTxChannels: "07"
2714
+ };
2715
+ const customerPressureThresholds = configuration?.customerPressureThresholds ?? await bridgeCommands.getCustomerPressureThresholds(deviceId);
2716
+ const customerCANSettings = configuration?.customerCANSettings ?? await bridgeCommands.getCustomerCANSettings(deviceId);
2717
+ const fwVersion = bridgeTools.getBridgeFromStore(deviceId).advertisingData.fwVersion;
2718
+ const bleTxChannels = bridgeTools.hexToDecimalArray(bridgeConfiguration.bleTxChannels ?? "").reverse();
2719
+ const axle01PressureThresholds = bridgeTools.hexToDecimalArray(customerPressureThresholds.axle01 ?? "");
2720
+ const canProtocol = bridgeTools.hexToDecimalArray(customerCANSettings.canProtocol ?? "").reverse();
2721
+ const transparentFilteredMode = bridgeTools.hexToDecimalArray(customerCANSettings.transparentFilteredMode ?? "").reverse();
2722
+ const fwMajor = (fwVersion || "0").split(".")[0].charCodeAt(0) & 255;
2723
+ const bleTxPower = bridgeTools.intToBytes(bridgeConfiguration.bleTxPower ?? 0, 2);
2724
+ const canEnabled = bridgeTools.intToBytes(bridgeConfiguration.canEnabled ?? 0, 1);
2725
+ const movementDetectionLimit = bridgeTools.intToBytes(bridgeConfiguration.movementDetectionLimit ?? 0, 2);
2726
+ const sensorInactivityTimeout = bridgeTools.intToBytes(bridgeConfiguration.sensorInactivityTimeout ?? 0, 2);
2727
+ const e010Input = [bleTxPower[0] ?? 0, bleTxPower[1] ?? 0, bleTxChannels[0] ?? 0];
2728
+ const e141Input = [
2729
+ canEnabled[0] ?? 0,
2730
+ movementDetectionLimit[0] ?? 0,
2731
+ movementDetectionLimit[1] ?? 0,
2732
+ sensorInactivityTimeout[0] ?? 0,
2733
+ sensorInactivityTimeout[1] ?? 0,
2734
+ axle01PressureThresholds[0] ?? 0,
2735
+ canProtocol[0] ?? 0,
2736
+ transparentFilteredMode[0] ?? 0,
2737
+ fwMajor
2738
+ ];
2739
+ console.log(`[getRxSWIN] e010: ${e010Input}`);
2740
+ console.log(`[getRxSWIN] e141: ${e141Input}`);
2741
+ const result = {
2742
+ R10SWIN: decimalToHex(bridgeSecurity.crc16Ccitt(e010Input), 4),
2743
+ R141SWIN: decimalToHex(bridgeSecurity.crc16Ccitt(e141Input), 4)
2744
+ };
2745
+ const item1Content = [
2746
+ ...bridgeTools.asciiToDecimalArray("R010"),
2747
+ 32,
2748
+ ...bridgeTools.asciiToDecimalArray(result.R10SWIN)
2749
+ ];
2750
+ const item2Content = [
2751
+ ...bridgeTools.asciiToDecimalArray("R141"),
2752
+ 32,
2753
+ ...bridgeTools.asciiToDecimalArray(result.R141SWIN)
2754
+ ];
2755
+ const item1 = [item1Content.length, ...item1Content];
2756
+ const item2 = [item2Content.length, ...item2Content];
2757
+ const payload = [...item1, ...item2];
2758
+ console.log(
2759
+ `[getRxSWIN] R010 item: "${String.fromCharCode(...item1.slice(1))}" (${item1.map((b) => decimalToHex(b)).join(" ")})`
2760
+ );
2761
+ console.log(
2762
+ `[getRxSWIN] R141 item: "${String.fromCharCode(...item2.slice(1))}" (${item2.map((b) => decimalToHex(b)).join(" ")})`
2763
+ );
2764
+ console.log(`[getRxSWIN] final payload (${payload.length}B): ${payload.map((b) => decimalToHex(b)).join(" ")}`);
2765
+ return result;
2511
2766
  }
2512
2767
  function bridgeVehiclesDifference(original, change) {
2513
2768
  const differences = [];
@@ -3086,6 +3341,7 @@ const bridge = {
3086
3341
  setVehicle: bridgeService.setVehicle,
3087
3342
  getConfiguration: bridgeService.getConfiguration,
3088
3343
  setConfiguration: bridgeService.setConfiguration,
3344
+ getRxSWIN: bridgeService.getRxSWIN,
3089
3345
  getSensorReading: bridgeService.getSensorReading,
3090
3346
  getVehicleReadings: bridgeService.getVehicleReadings,
3091
3347
  getAutolearnStatuses: bridgeService.getAutolearnStatuses,
@@ -4153,6 +4409,95 @@ const torqueWrench = {
4153
4409
  onReading: torqueWrenchService.onReading
4154
4410
  };
4155
4411
 
4412
+ let unitech;
4413
+ function setUnitechRfidImplementation(unitechRfidImplementation) {
4414
+ if (!unitechRfidImplementation)
4415
+ return console.warn("Unitech RFID implementation is not provided, Unitech RFID functionality will not work");
4416
+ unitech = unitechRfidImplementation;
4417
+ }
4418
+
4419
+ const unitechRfidService = {
4420
+ subscribeListeners(deviceId) {
4421
+ unitech.addListener("readerState", (event) => {
4422
+ simulatorSvc.triggerEvent("unitech:readerState", deviceId, event);
4423
+ simulatorSvc.triggerEvent("unitech:readerStateConnect", deviceId, event);
4424
+ });
4425
+ unitech.addListener("actionState", (event) => simulatorSvc.triggerEvent("unitech:actionState", deviceId, event));
4426
+ unitech.addListener("trigger", (event) => simulatorSvc.triggerEvent("unitech:trigger", deviceId, event));
4427
+ unitech.addListener("tagRead", (event) => simulatorSvc.triggerEvent("unitech:tag", deviceId, event));
4428
+ unitech.addListener("battery", (event) => simulatorSvc.triggerEvent("unitech:battery", deviceId, event));
4429
+ unitech.addListener("temperature", (event) => simulatorSvc.triggerEvent("unitech:temperature", deviceId, event));
4430
+ },
4431
+ onReaderState(callback) {
4432
+ simulatorSvc.registerEvent("unitech:readerState", callback);
4433
+ },
4434
+ onActionState(callback) {
4435
+ simulatorSvc.registerEvent("unitech:actionState", callback);
4436
+ },
4437
+ onTrigger(callback) {
4438
+ simulatorSvc.registerEvent("unitech:trigger", callback);
4439
+ },
4440
+ onTagRead(callback) {
4441
+ simulatorSvc.registerEvent("unitech:tag", callback);
4442
+ },
4443
+ onBattery(callback) {
4444
+ simulatorSvc.registerEvent("unitech:battery", callback);
4445
+ },
4446
+ onTemperature(callback) {
4447
+ simulatorSvc.registerEvent("unitech:temperature", callback);
4448
+ }
4449
+ };
4450
+
4451
+ const unitechRfid = {
4452
+ async connect(deviceId) {
4453
+ const unitechDevices = Object.values(store.devices).filter((d) => d.type === "unitechRfid");
4454
+ for (const device2 of unitechDevices) {
4455
+ if (device2.id !== deviceId && store.deviceState[device2.id] === "paired") {
4456
+ await this.disconnect(device2.id, "manualDisconnection");
4457
+ }
4458
+ }
4459
+ store.setState(deviceId, "connecting");
4460
+ await unitech.removeAllListeners();
4461
+ const device = store.devices[deviceId];
4462
+ if (store.platform === "ios") {
4463
+ await unitech.startDetect({ deviceName: device.name });
4464
+ await toolsSvc.delay(500);
4465
+ await unitech.stopDetect();
4466
+ }
4467
+ const { connected } = await unitech.connect({ bluetoothAddress: device.id });
4468
+ if (!connected) throw new Error("UnitechRfid Error: Unable to connect to the device.");
4469
+ await unitechRfidService.subscribeListeners(deviceId);
4470
+ await withTimeout(
4471
+ new Promise((resolve) => {
4472
+ simulatorSvc.registerEvent("unitech:readerStateConnect", (_deviceId, event) => {
4473
+ if (event.state?.toLowerCase() === "connected") resolve();
4474
+ });
4475
+ }),
4476
+ 15e3
4477
+ );
4478
+ await unitech.initDeviceSettings();
4479
+ store.setState(deviceId, "paired");
4480
+ },
4481
+ async disconnect(deviceId, reason) {
4482
+ store.setState(deviceId, "disconnecting");
4483
+ await unitech.removeAllListeners();
4484
+ await unitech.disconnect();
4485
+ store.setState(deviceId, void 0, reason ?? "manualDisconnection");
4486
+ },
4487
+ async startReading() {
4488
+ await unitech.startInventory();
4489
+ },
4490
+ async stopReading() {
4491
+ await unitech.stopInventory();
4492
+ },
4493
+ onReaderState: unitechRfidService.onReaderState,
4494
+ onActionState: unitechRfidService.onActionState,
4495
+ onTrigger: unitechRfidService.onTrigger,
4496
+ onTagRead: unitechRfidService.onTagRead,
4497
+ onBattery: unitechRfidService.onBattery,
4498
+ onTemperature: unitechRfidService.onTemperature
4499
+ };
4500
+
4156
4501
  const bridgeSimulator = {
4157
4502
  isRebootRequired(deviceId) {
4158
4503
  return store.bridgeRebootRequired[deviceId];
@@ -4190,6 +4535,32 @@ const bridgeSimulator = {
4190
4535
  const bridge = getSimulatedBridge(deviceId);
4191
4536
  bridge.simulatorData.configuration = _.cloneDeep(config);
4192
4537
  },
4538
+ async getRxSWIN(deviceId) {
4539
+ const bridge = getSimulatedBridge(deviceId);
4540
+ const config = bridge.simulatorData.configuration;
4541
+ const axle01PressureThresholds = bridgeTools.hexToDecimalArray(config.customerPressureThresholds?.axle01 ?? "");
4542
+ const canProtocol = bridgeTools.hexToDecimalArray(config.customerCANSettings?.canProtocol ?? "");
4543
+ const transparentFilteredMode = bridgeTools.hexToDecimalArray(
4544
+ config.customerCANSettings?.transparentFilteredMode ?? ""
4545
+ );
4546
+ const fwMajor = (bridge.advertisingData.fwVersion || "0").split(".")[0].charCodeAt(0) & 255;
4547
+ const e010Input = [0, 0, 0];
4548
+ const e141Input = [
4549
+ 0,
4550
+ 0,
4551
+ 0,
4552
+ 0,
4553
+ 0,
4554
+ axle01PressureThresholds[0] ?? 0,
4555
+ canProtocol[0] ?? 0,
4556
+ transparentFilteredMode[0] ?? 0,
4557
+ fwMajor
4558
+ ];
4559
+ return {
4560
+ R10SWIN: decimalToHex(bridgeSecurity.crc16Ccitt(e010Input), 4),
4561
+ R141SWIN: decimalToHex(bridgeSecurity.crc16Ccitt(e141Input), 4)
4562
+ };
4563
+ },
4193
4564
  async getSensorReading(deviceId, positionId) {
4194
4565
  const bridge = getSimulatedBridge(deviceId);
4195
4566
  return bridge.simulatorData.sensors[positionId];
@@ -4794,11 +5165,13 @@ class BridgeTcVehicleAxle {
4794
5165
  minTargetPressure;
4795
5166
  }
4796
5167
 
4797
- function createTirecheckDeviceSdk(platform, bleImplementation, securityKeys) {
5168
+ function createTirecheckDeviceSdk(platform, bleImplementation, securityKeys, unitechRfidImplementation, bluetoothClassicSerialImplementation) {
4798
5169
  store.platform = platform;
4799
5170
  bleImplementation = bleImplementation || emptyBleImplementation;
4800
5171
  store.securityKeys = securityKeys || {};
4801
5172
  setBleImplementation(bleImplementation);
5173
+ setUnitechRfidImplementation(unitechRfidImplementation);
5174
+ setBluetoothClassicSerialImplementation(bluetoothClassicSerialImplementation);
4802
5175
  return {
4803
5176
  /** Generic methods common for all devices */
4804
5177
  bluetooth,
@@ -4816,6 +5189,8 @@ function createTirecheckDeviceSdk(platform, bleImplementation, securityKeys) {
4816
5189
  simulator,
4817
5190
  /** Methods for working with Tirecheck Torque Wrench */
4818
5191
  torqueWrench,
5192
+ /** Methods for working with Unitech RFID reader */
5193
+ unitechRfid,
4819
5194
  utils: {
4820
5195
  bridge: {
4821
5196
  convertBarToKpaByte: bridgeTools.convertBarToKpaByte,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tirecheck-device-sdk",
3
- "version": "0.2.70",
3
+ "version": "0.2.72",
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",