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 +400 -25
- package/dist/index.d.cts +222 -7
- package/dist/index.d.mts +222 -7
- package/dist/index.d.ts +222 -7
- package/dist/index.mjs +400 -25
- package/package.json +1 -1
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
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,
|