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.cjs CHANGED
@@ -134,6 +134,19 @@ function normalizeError(error) {
134
134
  return error;
135
135
  }
136
136
 
137
+ const emptyBluetoothClassicSerialImplementation = {
138
+ list: async () => [],
139
+ discoverUnpaired: async () => [],
140
+ setDeviceDiscoveredListener: () => {
141
+ },
142
+ clearDeviceDiscoveredListener: () => {
143
+ }
144
+ };
145
+ let bluetoothClassicSerial = emptyBluetoothClassicSerialImplementation;
146
+ function setBluetoothClassicSerialImplementation(bluetoothClassicSerialImplementation) {
147
+ bluetoothClassicSerial = bluetoothClassicSerialImplementation ?? emptyBluetoothClassicSerialImplementation;
148
+ }
149
+
137
150
  const tyreLabels = getDefaultTyreLabels();
138
151
  const bridgeTools = {
139
152
  getBridgeFromStore,
@@ -166,7 +179,7 @@ const bridgeTools = {
166
179
  );
167
180
  const result = [];
168
181
  for (const key of keys) {
169
- if (!structurizedObj[key]) throw new Error(`Missing key ${key} in the structure`);
182
+ if (structurizedObj[key] == null) throw new Error(`Missing key ${key} in the structure`);
170
183
  const encoded = this.encodeData(structurizedObj[key], objStructure[key].display);
171
184
  if (encoded.length < objStructure[key].size) {
172
185
  const _padArray = Array.from({ length: objStructure[key].size - encoded.length }, () => 0);
@@ -206,7 +219,8 @@ const bridgeTools = {
206
219
  return this.asciiToDecimalArray(_data);
207
220
  }
208
221
  if (displayUnits === "decimal") {
209
- return this.hexToDecimalArray(decimalToHex(_data)).reverse();
222
+ const hex = decimalToHex(_data);
223
+ return this.hexToDecimalArray(hex.length % 2 ? `0${hex}` : hex).reverse();
210
224
  }
211
225
  if (displayUnits === "reverseHex") {
212
226
  const byteArray = _data.match(/.{1,2}/g) || [];
@@ -657,6 +671,17 @@ const deviceMeta = {
657
671
  };
658
672
  return bleDevice;
659
673
  }
674
+ },
675
+ unitechRfid: {
676
+ nameRegex: /^RP902/i,
677
+ transport: "serial",
678
+ getDeviceInfoFromAdvertising: (device) => {
679
+ const bleDevice = {
680
+ ...device,
681
+ type: "unitechRfid"
682
+ };
683
+ return bleDevice;
684
+ }
660
685
  }
661
686
  };
662
687
 
@@ -693,6 +718,8 @@ const bluetooth = {
693
718
  deviceStateChangeCallback = callback;
694
719
  },
695
720
  scanDevices,
721
+ scanSerialDevicesPaired,
722
+ scanSerialDevicesUnpaired,
696
723
  stopScan() {
697
724
  ble.stopScan();
698
725
  },
@@ -723,6 +750,47 @@ async function scanDevices(services = [], duration) {
723
750
  (e) => console.error("ble.startScanWithOptions error:", e)
724
751
  );
725
752
  }
753
+ async function scanSerialDevicesPaired() {
754
+ try {
755
+ const pairedDevices = await bluetoothClassicSerial.list();
756
+ for (const device of pairedDevices ?? []) handleSerialDevice(device);
757
+ } catch (e) {
758
+ console.error("scanPairedSerialDevices error:", e);
759
+ }
760
+ }
761
+ async function scanSerialDevicesUnpaired() {
762
+ bluetoothClassicSerial.setDeviceDiscoveredListener?.((device) => handleSerialDevice(device));
763
+ try {
764
+ const unpairedDevices = await bluetoothClassicSerial.discoverUnpaired();
765
+ for (const device of unpairedDevices ?? []) handleSerialDevice(device);
766
+ } catch (e) {
767
+ const message = (typeof e === "string" ? e : e?.message ?? "").toLowerCase();
768
+ const pickerDismissed = store.platform === "ios" && ["cancel", "alreadyconnected", "already connected", "notfound", "not found"].some((m) => message.includes(m));
769
+ if (pickerDismissed) {
770
+ console.log("discoverSerialDevices: accessory picker returned no unpaired device -", message);
771
+ } else {
772
+ console.error("discoverSerialDevices error:", e);
773
+ }
774
+ } finally {
775
+ bluetoothClassicSerial.clearDeviceDiscoveredListener?.();
776
+ }
777
+ }
778
+ function handleSerialDevice(device) {
779
+ const rawId = device.id ?? device.address;
780
+ const id = rawId != null ? String(rawId) : void 0;
781
+ if (!id) {
782
+ console.warn("handleSerialDevice: skipped, no id/address", device);
783
+ return;
784
+ }
785
+ const peripheral = { id, name: device.name, rssi: device.rssi ?? 0, advertising: {} };
786
+ const processedDevice = processDevice(peripheral);
787
+ if (!processedDevice) {
788
+ console.warn("handleSerialDevice: processDevice returned null (filtered out)", id, device.name);
789
+ return;
790
+ }
791
+ store.devices[processedDevice.id] = processedDevice;
792
+ deviceAdvertisingCallback?.(processedDevice);
793
+ }
726
794
  async function connect$1(deviceId, disconnectCallback) {
727
795
  if (toolsSvc.canCommunicateWith(deviceId)) return console.warn("Connect Warn: Already connected to device");
728
796
  store.setState(deviceId, "connecting");
@@ -811,7 +879,8 @@ function processDevice(device) {
811
879
  console.warn("Error processing advertising", e);
812
880
  return;
813
881
  }
814
- unreachableSvc.refresh(processedDevice.id, deviceUnreachableCallback);
882
+ const isSerial = deviceMeta[deviceType].transport === "serial";
883
+ if (!isSerial) unreachableSvc.refresh(processedDevice.id, deviceUnreachableCallback);
815
884
  return processedDevice;
816
885
  }
817
886
  function getDeviceTypeFromName(name) {
@@ -1784,6 +1853,109 @@ const bridgeCommandStructures = {
1784
1853
  description: "Bluetooth chip FW version: major.minor.patch + release type (e.g. 1.2.0 Release)"
1785
1854
  }
1786
1855
  }
1856
+ },
1857
+ bridgeConfiguration: {
1858
+ id: [98, 1],
1859
+ name: "bridgeConfiguration",
1860
+ structure: {
1861
+ configVersion: {
1862
+ size: 4,
1863
+ description: "Application configuration version details",
1864
+ display: "decimal"
1865
+ },
1866
+ bleTxPower: {
1867
+ size: 2,
1868
+ description: "Used BLE Tx power (16 bit signed value; LSB = 0.1)",
1869
+ display: "decimal"
1870
+ },
1871
+ bleTxChannels: {
1872
+ size: 1,
1873
+ description: "BLE channel configuration (0x07 = all channels)"
1874
+ },
1875
+ bleConnectableAdvPeriod: {
1876
+ size: 2,
1877
+ description: "BLE Connectable Advertisement Period [LSB = 0.625 ms]",
1878
+ display: "decimal"
1879
+ },
1880
+ configurationFlags: {
1881
+ size: 1,
1882
+ description: "Configuration flags (1 = Enable inactivity timeout; 4 = Disable time lockout on false PINs)"
1883
+ },
1884
+ wrongPinsUntilLockout: {
1885
+ size: 1,
1886
+ description: "Minimal number of wrong pins allowed before the lockout activates",
1887
+ display: "decimal"
1888
+ },
1889
+ maxLockoutPeriodIncreases: {
1890
+ size: 1,
1891
+ description: "How many times the lockout period may be doubled",
1892
+ display: "decimal"
1893
+ },
1894
+ wrongPinInitialLockoutTime: {
1895
+ size: 1,
1896
+ description: "Initial lockout time duration after too many wrong PINs",
1897
+ display: "decimal"
1898
+ },
1899
+ securityConfiguration: {
1900
+ size: 1,
1901
+ description: "Bluetooth security configuration (0x03 - legacy pairing enabled; 0x07 - disabled)"
1902
+ },
1903
+ canEnabled: {
1904
+ size: 1,
1905
+ description: "CAN enabled state",
1906
+ display: "decimal"
1907
+ },
1908
+ bleEnabled: {
1909
+ size: 1,
1910
+ description: "BLE Advertisement enabled state",
1911
+ display: "decimal"
1912
+ },
1913
+ canBitrate: {
1914
+ size: 2,
1915
+ description: "CAN Bitrate [kbps]",
1916
+ display: "decimal"
1917
+ },
1918
+ movementDetectionLimit: {
1919
+ size: 2,
1920
+ description: "Movement detection limit [1/256 kmph per bit]",
1921
+ display: "decimal"
1922
+ },
1923
+ sensorInactivityTimeout: {
1924
+ size: 2,
1925
+ description: "Timeout [s] after which an inactive sensor is marked erroneous (max. 512 s)",
1926
+ display: "decimal"
1927
+ },
1928
+ manufacturerCode: {
1929
+ size: 4,
1930
+ description: "Manufacturer Code as per SAE J1939",
1931
+ display: "decimal"
1932
+ },
1933
+ identityNumber: {
1934
+ size: 4,
1935
+ description: "Identity number for ECU (max. 22 bits = 0x1FFFFF)",
1936
+ display: "decimal"
1937
+ },
1938
+ manufacturerName: {
1939
+ size: 20,
1940
+ description: "Manufacturer Name (SPN 4304, max. 20 bytes)",
1941
+ display: "ascii"
1942
+ },
1943
+ ecuPartNumber: {
1944
+ size: 20,
1945
+ description: "ECU Part Number (SPN 2901, max. 20 bytes)",
1946
+ display: "ascii"
1947
+ },
1948
+ softwareVersion: {
1949
+ size: 20,
1950
+ description: "Software Version (SPN 234, max. 20 bytes)",
1951
+ display: "ascii"
1952
+ },
1953
+ reservedConfiguration: {
1954
+ size: 4,
1955
+ description: "Reserved configuration",
1956
+ display: "decimal"
1957
+ }
1958
+ }
1787
1959
  }
1788
1960
  };
1789
1961
 
@@ -1882,6 +2054,18 @@ const bridgeSecurity = {
1882
2054
  }
1883
2055
  return crc >>> 0;
1884
2056
  },
2057
+ /** CRC-16/CCITT-FALSE (poly 0x1021, init 0xFFFF). Used for the RxSWIN (0xF18F) E010/E141 checksums. */
2058
+ crc16Ccitt(msg) {
2059
+ let crc = 65535;
2060
+ const polynomial = 4129;
2061
+ for (const byte of msg) {
2062
+ crc ^= (byte & 255) << 8;
2063
+ for (let j = 0; j < 8; j++) {
2064
+ crc = crc & 32768 ? (crc << 1 ^ polynomial) & 65535 : crc << 1 & 65535;
2065
+ }
2066
+ }
2067
+ return crc & 65535;
2068
+ },
1885
2069
  getCrcArray(msg) {
1886
2070
  const crc = this.crc32mpeg2(msg);
1887
2071
  const crcHex = decimalToHex(crc).padStart(8, "0");
@@ -2287,6 +2471,21 @@ const bridgeCommands = {
2287
2471
  deviceData.advertisingData.fwVersion
2288
2472
  );
2289
2473
  },
2474
+ async getBridgeConfiguration(deviceId) {
2475
+ const deviceData = bridgeTools.getBridgeFromStore(deviceId);
2476
+ const result = await this.readCommand(deviceData, subCommandIds.bridgeConfiguration);
2477
+ const structurized = bridgeTools.convertBytesToStructure(
2478
+ bridgeCommandStructures.bridgeConfiguration.structure,
2479
+ result.data,
2480
+ deviceData.advertisingData.fwVersion
2481
+ );
2482
+ console.log(
2483
+ `[getBridgeConfiguration] raw payload (${result.data.length}B):`,
2484
+ result.data.map((b) => decimalToHex(b)).join(" ")
2485
+ );
2486
+ console.log("[getBridgeConfiguration] decoded structure:", structurized, `(isFactory: ${result.isFactory})`);
2487
+ return { ...structurized, isFactory: result.isFactory };
2488
+ },
2290
2489
  async getErrorHistoryCounter(deviceId) {
2291
2490
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
2292
2491
  const result = await this.readCommand(deviceData, subCommandIds.errorHistoryCounter, {
@@ -2398,6 +2597,7 @@ const bridgeService = {
2398
2597
  setVehicle,
2399
2598
  getConfiguration,
2400
2599
  setConfiguration,
2600
+ getRxSWIN,
2401
2601
  getSensorReading,
2402
2602
  getVehicleReadings,
2403
2603
  resetAutolearnStatuses,
@@ -2469,7 +2669,7 @@ async function setVehicleLayout(deviceId, tcVehicle) {
2469
2669
  }
2470
2670
  await bridgeCommands.setVehicleLayout(deviceId, result);
2471
2671
  }
2472
- async function getConfiguration(deviceId, includeVehicleData = false) {
2672
+ async function getConfiguration(deviceId) {
2473
2673
  const customerCANSettings = await bridgeCommands.getCustomerCANSettings(deviceId);
2474
2674
  const workshopCANSettings = await bridgeCommands.getWorkshopCANSettings(deviceId);
2475
2675
  const customerPressureThresholds = await bridgeCommands.getCustomerPressureThresholds(deviceId);
@@ -2477,16 +2677,23 @@ async function getConfiguration(deviceId, includeVehicleData = false) {
2477
2677
  const customerImbalanceThresholds = await bridgeCommands.getCustomerImbalanceThresholds(deviceId);
2478
2678
  const pressuresPerAxle = await bridgeCommands.getPressuresPerAxle(deviceId);
2479
2679
  let autolearnSettings;
2680
+ let autolearnIdStatus;
2681
+ let autolearnUnknownSensors;
2480
2682
  let errorHistoryCounter;
2481
2683
  let eolStatus;
2684
+ let firmwareVersion;
2482
2685
  if (bridgeTools.isVersionGreaterThan(deviceId, "0.9.7")) {
2483
2686
  autolearnSettings = await bridgeCommands.getAutolearnSettings(deviceId);
2687
+ autolearnIdStatus = await bridgeCommands.getAutolearnIdStatus(deviceId);
2688
+ autolearnUnknownSensors = await bridgeCommands.getAutolearnUnknownSensors(deviceId);
2484
2689
  }
2485
2690
  if (bridgeTools.isVersionGreaterThan(deviceId, "1.1.F")) {
2486
2691
  errorHistoryCounter = await bridgeCommands.getErrorHistoryCounter(deviceId);
2487
2692
  eolStatus = await bridgeCommands.getEolStatus(deviceId);
2693
+ firmwareVersion = await bridgeCommands.getFirmwareVersion(deviceId);
2488
2694
  }
2489
- const configuration = {
2695
+ const rxswin = await getRxSWIN(deviceId, { customerPressureThresholds, customerCANSettings });
2696
+ return {
2490
2697
  customerCANSettings,
2491
2698
  workshopCANSettings,
2492
2699
  customerPressureThresholds,
@@ -2494,27 +2701,75 @@ async function getConfiguration(deviceId, includeVehicleData = false) {
2494
2701
  customerImbalanceThresholds,
2495
2702
  pressuresPerAxle,
2496
2703
  autolearnSettings,
2704
+ autolearnIdStatus,
2705
+ autolearnUnknownSensors,
2497
2706
  errorHistoryCounter,
2498
- eolStatus
2707
+ eolStatus,
2708
+ firmwareVersion,
2709
+ rxswin
2499
2710
  };
2500
- if (includeVehicleData) {
2501
- configuration.vehicleLayout = await bridgeCommands.getVehicleLayout(deviceId);
2502
- configuration.axleInfo = [];
2503
- for (let axleIndex = 0; axleIndex < 15; axleIndex++) {
2504
- const axleBytes = await bridgeCommands.getAxleInfo(deviceId, axleIndex);
2505
- configuration.axleInfo.push(
2506
- bridgeTools.convertBytesToStructure(bridgeCommandStructures.idsPerWheel.structure, axleBytes)
2507
- );
2508
- }
2509
- if (bridgeTools.isVersionGreaterThan(deviceId, "1.1.F")) {
2510
- configuration.firmwareVersion = await bridgeCommands.getFirmwareVersion(deviceId);
2511
- }
2512
- if (bridgeTools.isVersionGreaterThan(deviceId, "0.9.7")) {
2513
- configuration.autolearnIdStatus = await bridgeCommands.getAutolearnIdStatus(deviceId);
2514
- configuration.autolearnUnknownSensors = await bridgeCommands.getAutolearnUnknownSensors(deviceId);
2515
- }
2516
- }
2517
- return configuration;
2711
+ }
2712
+ async function getRxSWIN(deviceId, configuration) {
2713
+ if (!canCommunicateWith(deviceId)) throw new Error("Bridge not connected");
2714
+ const bridgeConfiguration = bridgeTools.isVersionGreaterThan(deviceId, "1.1.F") ? await bridgeCommands.getBridgeConfiguration(deviceId) : {
2715
+ canEnabled: 1,
2716
+ movementDetectionLimit: 1280,
2717
+ // Firmware default provided as 0x01FA for pre-1.2.0 bridges where record 0x01 is unavailable.
2718
+ sensorInactivityTimeout: 506,
2719
+ bleTxPower: 60,
2720
+ bleTxChannels: "07"
2721
+ };
2722
+ const customerPressureThresholds = configuration?.customerPressureThresholds ?? await bridgeCommands.getCustomerPressureThresholds(deviceId);
2723
+ const customerCANSettings = configuration?.customerCANSettings ?? await bridgeCommands.getCustomerCANSettings(deviceId);
2724
+ const fwVersion = bridgeTools.getBridgeFromStore(deviceId).advertisingData.fwVersion;
2725
+ const bleTxChannels = bridgeTools.hexToDecimalArray(bridgeConfiguration.bleTxChannels ?? "").reverse();
2726
+ const axle01PressureThresholds = bridgeTools.hexToDecimalArray(customerPressureThresholds.axle01 ?? "");
2727
+ const canProtocol = bridgeTools.hexToDecimalArray(customerCANSettings.canProtocol ?? "").reverse();
2728
+ const transparentFilteredMode = bridgeTools.hexToDecimalArray(customerCANSettings.transparentFilteredMode ?? "").reverse();
2729
+ const fwMajor = (fwVersion || "0").split(".")[0].charCodeAt(0) & 255;
2730
+ const bleTxPower = bridgeTools.intToBytes(bridgeConfiguration.bleTxPower ?? 0, 2);
2731
+ const canEnabled = bridgeTools.intToBytes(bridgeConfiguration.canEnabled ?? 0, 1);
2732
+ const movementDetectionLimit = bridgeTools.intToBytes(bridgeConfiguration.movementDetectionLimit ?? 0, 2);
2733
+ const sensorInactivityTimeout = bridgeTools.intToBytes(bridgeConfiguration.sensorInactivityTimeout ?? 0, 2);
2734
+ const e010Input = [bleTxPower[0] ?? 0, bleTxPower[1] ?? 0, bleTxChannels[0] ?? 0];
2735
+ const e141Input = [
2736
+ canEnabled[0] ?? 0,
2737
+ movementDetectionLimit[0] ?? 0,
2738
+ movementDetectionLimit[1] ?? 0,
2739
+ sensorInactivityTimeout[0] ?? 0,
2740
+ sensorInactivityTimeout[1] ?? 0,
2741
+ axle01PressureThresholds[0] ?? 0,
2742
+ canProtocol[0] ?? 0,
2743
+ transparentFilteredMode[0] ?? 0,
2744
+ fwMajor
2745
+ ];
2746
+ console.log(`[getRxSWIN] e010: ${e010Input}`);
2747
+ console.log(`[getRxSWIN] e141: ${e141Input}`);
2748
+ const result = {
2749
+ R10SWIN: decimalToHex(bridgeSecurity.crc16Ccitt(e010Input), 4),
2750
+ R141SWIN: decimalToHex(bridgeSecurity.crc16Ccitt(e141Input), 4)
2751
+ };
2752
+ const item1Content = [
2753
+ ...bridgeTools.asciiToDecimalArray("R010"),
2754
+ 32,
2755
+ ...bridgeTools.asciiToDecimalArray(result.R10SWIN)
2756
+ ];
2757
+ const item2Content = [
2758
+ ...bridgeTools.asciiToDecimalArray("R141"),
2759
+ 32,
2760
+ ...bridgeTools.asciiToDecimalArray(result.R141SWIN)
2761
+ ];
2762
+ const item1 = [item1Content.length, ...item1Content];
2763
+ const item2 = [item2Content.length, ...item2Content];
2764
+ const payload = [...item1, ...item2];
2765
+ console.log(
2766
+ `[getRxSWIN] R010 item: "${String.fromCharCode(...item1.slice(1))}" (${item1.map((b) => decimalToHex(b)).join(" ")})`
2767
+ );
2768
+ console.log(
2769
+ `[getRxSWIN] R141 item: "${String.fromCharCode(...item2.slice(1))}" (${item2.map((b) => decimalToHex(b)).join(" ")})`
2770
+ );
2771
+ console.log(`[getRxSWIN] final payload (${payload.length}B): ${payload.map((b) => decimalToHex(b)).join(" ")}`);
2772
+ return result;
2518
2773
  }
2519
2774
  function bridgeVehiclesDifference(original, change) {
2520
2775
  const differences = [];
@@ -3093,6 +3348,7 @@ const bridge = {
3093
3348
  setVehicle: bridgeService.setVehicle,
3094
3349
  getConfiguration: bridgeService.getConfiguration,
3095
3350
  setConfiguration: bridgeService.setConfiguration,
3351
+ getRxSWIN: bridgeService.getRxSWIN,
3096
3352
  getSensorReading: bridgeService.getSensorReading,
3097
3353
  getVehicleReadings: bridgeService.getVehicleReadings,
3098
3354
  getAutolearnStatuses: bridgeService.getAutolearnStatuses,
@@ -4160,6 +4416,95 @@ const torqueWrench = {
4160
4416
  onReading: torqueWrenchService.onReading
4161
4417
  };
4162
4418
 
4419
+ let unitech;
4420
+ function setUnitechRfidImplementation(unitechRfidImplementation) {
4421
+ if (!unitechRfidImplementation)
4422
+ return console.warn("Unitech RFID implementation is not provided, Unitech RFID functionality will not work");
4423
+ unitech = unitechRfidImplementation;
4424
+ }
4425
+
4426
+ const unitechRfidService = {
4427
+ subscribeListeners(deviceId) {
4428
+ unitech.addListener("readerState", (event) => {
4429
+ simulatorSvc.triggerEvent("unitech:readerState", deviceId, event);
4430
+ simulatorSvc.triggerEvent("unitech:readerStateConnect", deviceId, event);
4431
+ });
4432
+ unitech.addListener("actionState", (event) => simulatorSvc.triggerEvent("unitech:actionState", deviceId, event));
4433
+ unitech.addListener("trigger", (event) => simulatorSvc.triggerEvent("unitech:trigger", deviceId, event));
4434
+ unitech.addListener("tagRead", (event) => simulatorSvc.triggerEvent("unitech:tag", deviceId, event));
4435
+ unitech.addListener("battery", (event) => simulatorSvc.triggerEvent("unitech:battery", deviceId, event));
4436
+ unitech.addListener("temperature", (event) => simulatorSvc.triggerEvent("unitech:temperature", deviceId, event));
4437
+ },
4438
+ onReaderState(callback) {
4439
+ simulatorSvc.registerEvent("unitech:readerState", callback);
4440
+ },
4441
+ onActionState(callback) {
4442
+ simulatorSvc.registerEvent("unitech:actionState", callback);
4443
+ },
4444
+ onTrigger(callback) {
4445
+ simulatorSvc.registerEvent("unitech:trigger", callback);
4446
+ },
4447
+ onTagRead(callback) {
4448
+ simulatorSvc.registerEvent("unitech:tag", callback);
4449
+ },
4450
+ onBattery(callback) {
4451
+ simulatorSvc.registerEvent("unitech:battery", callback);
4452
+ },
4453
+ onTemperature(callback) {
4454
+ simulatorSvc.registerEvent("unitech:temperature", callback);
4455
+ }
4456
+ };
4457
+
4458
+ const unitechRfid = {
4459
+ async connect(deviceId) {
4460
+ const unitechDevices = Object.values(store.devices).filter((d) => d.type === "unitechRfid");
4461
+ for (const device2 of unitechDevices) {
4462
+ if (device2.id !== deviceId && store.deviceState[device2.id] === "paired") {
4463
+ await this.disconnect(device2.id, "manualDisconnection");
4464
+ }
4465
+ }
4466
+ store.setState(deviceId, "connecting");
4467
+ await unitech.removeAllListeners();
4468
+ const device = store.devices[deviceId];
4469
+ if (store.platform === "ios") {
4470
+ await unitech.startDetect({ deviceName: device.name });
4471
+ await toolsSvc.delay(500);
4472
+ await unitech.stopDetect();
4473
+ }
4474
+ const { connected } = await unitech.connect({ bluetoothAddress: device.id });
4475
+ if (!connected) throw new Error("UnitechRfid Error: Unable to connect to the device.");
4476
+ await unitechRfidService.subscribeListeners(deviceId);
4477
+ await withTimeout(
4478
+ new Promise((resolve) => {
4479
+ simulatorSvc.registerEvent("unitech:readerStateConnect", (_deviceId, event) => {
4480
+ if (event.state?.toLowerCase() === "connected") resolve();
4481
+ });
4482
+ }),
4483
+ 15e3
4484
+ );
4485
+ await unitech.initDeviceSettings();
4486
+ store.setState(deviceId, "paired");
4487
+ },
4488
+ async disconnect(deviceId, reason) {
4489
+ store.setState(deviceId, "disconnecting");
4490
+ await unitech.removeAllListeners();
4491
+ await unitech.disconnect();
4492
+ store.setState(deviceId, void 0, reason ?? "manualDisconnection");
4493
+ },
4494
+ async startReading() {
4495
+ await unitech.startInventory();
4496
+ },
4497
+ async stopReading() {
4498
+ await unitech.stopInventory();
4499
+ },
4500
+ onReaderState: unitechRfidService.onReaderState,
4501
+ onActionState: unitechRfidService.onActionState,
4502
+ onTrigger: unitechRfidService.onTrigger,
4503
+ onTagRead: unitechRfidService.onTagRead,
4504
+ onBattery: unitechRfidService.onBattery,
4505
+ onTemperature: unitechRfidService.onTemperature
4506
+ };
4507
+
4163
4508
  const bridgeSimulator = {
4164
4509
  isRebootRequired(deviceId) {
4165
4510
  return store.bridgeRebootRequired[deviceId];
@@ -4197,6 +4542,32 @@ const bridgeSimulator = {
4197
4542
  const bridge = getSimulatedBridge(deviceId);
4198
4543
  bridge.simulatorData.configuration = ___default.cloneDeep(config);
4199
4544
  },
4545
+ async getRxSWIN(deviceId) {
4546
+ const bridge = getSimulatedBridge(deviceId);
4547
+ const config = bridge.simulatorData.configuration;
4548
+ const axle01PressureThresholds = bridgeTools.hexToDecimalArray(config.customerPressureThresholds?.axle01 ?? "");
4549
+ const canProtocol = bridgeTools.hexToDecimalArray(config.customerCANSettings?.canProtocol ?? "");
4550
+ const transparentFilteredMode = bridgeTools.hexToDecimalArray(
4551
+ config.customerCANSettings?.transparentFilteredMode ?? ""
4552
+ );
4553
+ const fwMajor = (bridge.advertisingData.fwVersion || "0").split(".")[0].charCodeAt(0) & 255;
4554
+ const e010Input = [0, 0, 0];
4555
+ const e141Input = [
4556
+ 0,
4557
+ 0,
4558
+ 0,
4559
+ 0,
4560
+ 0,
4561
+ axle01PressureThresholds[0] ?? 0,
4562
+ canProtocol[0] ?? 0,
4563
+ transparentFilteredMode[0] ?? 0,
4564
+ fwMajor
4565
+ ];
4566
+ return {
4567
+ R10SWIN: decimalToHex(bridgeSecurity.crc16Ccitt(e010Input), 4),
4568
+ R141SWIN: decimalToHex(bridgeSecurity.crc16Ccitt(e141Input), 4)
4569
+ };
4570
+ },
4200
4571
  async getSensorReading(deviceId, positionId) {
4201
4572
  const bridge = getSimulatedBridge(deviceId);
4202
4573
  return bridge.simulatorData.sensors[positionId];
@@ -4801,11 +5172,13 @@ class BridgeTcVehicleAxle {
4801
5172
  minTargetPressure;
4802
5173
  }
4803
5174
 
4804
- function createTirecheckDeviceSdk(platform, bleImplementation, securityKeys) {
5175
+ function createTirecheckDeviceSdk(platform, bleImplementation, securityKeys, unitechRfidImplementation, bluetoothClassicSerialImplementation) {
4805
5176
  store.platform = platform;
4806
5177
  bleImplementation = bleImplementation || emptyBleImplementation;
4807
5178
  store.securityKeys = securityKeys || {};
4808
5179
  setBleImplementation(bleImplementation);
5180
+ setUnitechRfidImplementation(unitechRfidImplementation);
5181
+ setBluetoothClassicSerialImplementation(bluetoothClassicSerialImplementation);
4809
5182
  return {
4810
5183
  /** Generic methods common for all devices */
4811
5184
  bluetooth,
@@ -4823,6 +5196,8 @@ function createTirecheckDeviceSdk(platform, bleImplementation, securityKeys) {
4823
5196
  simulator,
4824
5197
  /** Methods for working with Tirecheck Torque Wrench */
4825
5198
  torqueWrench,
5199
+ /** Methods for working with Unitech RFID reader */
5200
+ unitechRfid,
4826
5201
  utils: {
4827
5202
  bridge: {
4828
5203
  convertBarToKpaByte: bridgeTools.convertBarToKpaByte,