tirecheck-device-sdk 0.1.96 → 0.1.98

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
@@ -123,15 +123,23 @@ const bridgeTools = {
123
123
  if (deviceData.type !== "bridge") throw new Error("Device is not bridge");
124
124
  return deviceData;
125
125
  },
126
- convertBytesToStructure(objStructure, payload) {
127
- const numArray = ___default.clone(payload);
128
- const keys = Object.keys(objStructure);
126
+ convertBytesToStructure(objStructure, payload, fwVersion) {
127
+ let numArray = ___default.clone(payload);
128
+ const keys = Object.keys(objStructure).filter(
129
+ (key) => !objStructure[key].version || !fwVersion || fwVersion >= objStructure[key].version
130
+ );
129
131
  let sumWithInitial = 0;
130
132
  for (const key of keys) {
131
133
  sumWithInitial += objStructure[key].size;
132
134
  }
135
+ if (numArray.length < sumWithInitial) {
136
+ console.warn("missing bytes filled with empty values");
137
+ numArray = numArray.concat(Array.from({ length: sumWithInitial - numArray.length }, () => 0));
138
+ }
133
139
  if (numArray.length !== sumWithInitial) {
134
- throw new Error("Cannot convert bytes to object");
140
+ throw new Error(
141
+ `Cannot convert bytes to object: bytes received ${numArray.length}, expected ${sumWithInitial}, fw version ${fwVersion}`
142
+ );
135
143
  }
136
144
  const result = {};
137
145
  for (const key of keys) {
@@ -140,10 +148,13 @@ const bridgeTools = {
140
148
  }
141
149
  return result;
142
150
  },
143
- convertStructureToBytes(objStructure, structurizedObj) {
144
- const keys = Object.keys(objStructure);
151
+ convertStructureToBytes(objStructure, structurizedObj, fwVersion) {
152
+ const keys = Object.keys(objStructure).filter(
153
+ (key) => !objStructure[key].version || !fwVersion || fwVersion >= objStructure[key].version
154
+ );
145
155
  const result = [];
146
156
  for (const key of keys) {
157
+ if (!structurizedObj[key]) throw new Error(`Missing key ${key} in the structure`);
147
158
  const encoded = this.encodeData(structurizedObj[key], objStructure[key].display);
148
159
  if (encoded.length < objStructure[key].size) {
149
160
  const _padArray = Array.from({ length: objStructure[key].size - encoded.length }, () => 0);
@@ -180,7 +191,7 @@ const bridgeTools = {
180
191
  encodeData(data, displayUnits) {
181
192
  const _data = ___default.clone(data);
182
193
  if (displayUnits === "ascii") {
183
- return _data.split("").map((v, i) => _data.charCodeAt(i));
194
+ return this.asciiToDecimalArray(_data);
184
195
  }
185
196
  if (displayUnits === "decimal") {
186
197
  return this.hexToDecimalArray(this.decimalToHex(_data)).reverse();
@@ -192,16 +203,6 @@ const bridgeTools = {
192
203
  }
193
204
  return this.hexToDecimalArray(_data).reverse();
194
205
  },
195
- // getBridgeId(device: BluetoothDeviceBridge) {
196
- // // [244,177, 0, 34,123, 155] => F4B100227B9B
197
- // return (
198
- // device.advertisingData.macAddress
199
- // ?.map(n => this.decimalToHex(n))
200
- // .reverse()
201
- // .join('')
202
- // .toUpperCase() || ''
203
- // )
204
- // },
205
206
  pkcs(array, length) {
206
207
  const pkcsValue = length - array.length;
207
208
  if (pkcsValue > 0) {
@@ -213,6 +214,9 @@ const bridgeTools = {
213
214
  const hex = decimal.toString(16);
214
215
  return hex.padStart(2, "0");
215
216
  },
217
+ asciiToDecimalArray(ascii) {
218
+ return ascii.split("").map((x) => x.charCodeAt(0));
219
+ },
216
220
  hexToDecimalArray(hex) {
217
221
  return hex.match(/.{1,2}/g)?.map((byte) => Number.parseInt(byte, 16)) || [];
218
222
  },
@@ -341,8 +345,9 @@ function getDefaultTyreLabels() {
341
345
  const bridgeAdvertisingParser = {
342
346
  getDeviceInfoFromAdvertising(device) {
343
347
  const adversitingType = getAdvertisingType(device);
344
- if (adversitingType !== "connectable") return void 0;
348
+ if (adversitingType !== "connectable") return;
345
349
  const advertisingData = getAdvertisingData({ advertising: device.advertising, deviceName: device.name });
350
+ if (!advertisingData) return;
346
351
  const macArray = advertisingData?.macAddress?.map((n) => bridgeTools.decimalToHex(n).toUpperCase()).reverse() || [];
347
352
  const bridgeId = macArray.join("");
348
353
  const vin = String.fromCharCode(...advertisingData?.vinNum || []).split("\0").join("");
@@ -378,7 +383,7 @@ function getAdvertisingData({ advertising, deviceName }) {
378
383
  const adv = Array.from(uint8);
379
384
  const advertisingData = advertising.kCBAdvDataIsConnectable ? processIosAdvertising(adv, isKrone) : processAndroidAdvertising(adv, isKrone);
380
385
  if (!advertisingData || !advertisingData.macAddress.length || !advertisingData.randomAdvNumber.length || !advertisingData.vinNum.length) {
381
- throw new Error("Device not recognized");
386
+ return;
382
387
  }
383
388
  return advertisingData;
384
389
  }
@@ -589,12 +594,16 @@ async function connect$1(deviceId, disconnectCallback) {
589
594
  if (toolsSvc.canCommunicateWith(deviceId)) return console.warn("Connect Warn: Already connected to device");
590
595
  store.setState(deviceId, "connecting");
591
596
  let connectedDevice;
592
- for (let attempt = 0; attempt < 3; attempt++) {
597
+ for (let attempt = 1; attempt <= 3; attempt++) {
593
598
  try {
594
599
  connectedDevice = await withTimeout(connectInner(deviceId, disconnectCallback), 2e4);
595
600
  const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
596
601
  const isConnected = await ble.isConnected(_deviceId);
597
- if (connectedDevice && isConnected) break;
602
+ if (connectedDevice || isConnected) {
603
+ break;
604
+ } else {
605
+ throw new Error("Connection incomplete");
606
+ }
598
607
  } catch (e) {
599
608
  console.warn(`${attempt} connect fail`, e);
600
609
  if (attempt === 3) {
@@ -1374,12 +1383,7 @@ const bridgeCommandStructures = {
1374
1383
  size: 1,
1375
1384
  description: "VIN extension",
1376
1385
  display: "ascii",
1377
- optional: true
1378
- },
1379
- test: {
1380
- size: 3,
1381
- description: "Test",
1382
- optional: true
1386
+ version: "1.0.3"
1383
1387
  }
1384
1388
  }
1385
1389
  }
@@ -1722,7 +1726,7 @@ const subCommandIds = {
1722
1726
  };
1723
1727
  ___default.invert(commandIds);
1724
1728
  ___default.invert(subCommandIds);
1725
- let keepAliveTimer;
1729
+ const keepAliveTimer = {};
1726
1730
  const bridgeCommands = {
1727
1731
  getCommandHeader(device) {
1728
1732
  const accessLevel = store.deviceAccessLevel[device.id];
@@ -1733,16 +1737,22 @@ const bridgeCommands = {
1733
1737
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1734
1738
  await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.pressurePerAxle, data);
1735
1739
  },
1736
- async setVehicleLayout(deviceId, data) {
1740
+ async setVehicleLayout(deviceId, structurizedPayload) {
1737
1741
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1738
- await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.vehicleLayout, data);
1742
+ const payload = bridgeTools.convertStructureToBytes(
1743
+ bridgeCommandStructures.vehicleLayout.structure,
1744
+ structurizedPayload,
1745
+ deviceData.advertisingData.fwVersion
1746
+ );
1747
+ await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.vehicleLayout, payload);
1739
1748
  },
1740
1749
  async getCustomerCANSettings(deviceId) {
1741
1750
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1742
1751
  const result = await this.readCommand(deviceData, subCommandIds.customerCanSettings);
1743
1752
  const structurized = bridgeTools.convertBytesToStructure(
1744
1753
  bridgeCommandStructures.customerCanSettings.structure,
1745
- result.data
1754
+ result.data,
1755
+ deviceData.advertisingData.fwVersion
1746
1756
  );
1747
1757
  return { ...structurized, isFactory: result.isFactory };
1748
1758
  },
@@ -1751,7 +1761,8 @@ const bridgeCommands = {
1751
1761
  const result = await this.readCommand(deviceData, subCommandIds.workshopCanSettings);
1752
1762
  const structurized = bridgeTools.convertBytesToStructure(
1753
1763
  bridgeCommandStructures.workshopCanSettings.structure,
1754
- result.data
1764
+ result.data,
1765
+ deviceData.advertisingData.fwVersion
1755
1766
  );
1756
1767
  return { ...structurized, isFactory: result.isFactory };
1757
1768
  },
@@ -1760,7 +1771,8 @@ const bridgeCommands = {
1760
1771
  const result = await this.readCommand(deviceData, subCommandIds.customerPressureThresholds);
1761
1772
  const structurized = bridgeTools.convertBytesToStructure(
1762
1773
  bridgeCommandStructures.axlePressureThresholds.structure,
1763
- result.data
1774
+ result.data,
1775
+ deviceData.advertisingData.fwVersion
1764
1776
  );
1765
1777
  return { ...structurized, isFactory: result.isFactory };
1766
1778
  },
@@ -1769,7 +1781,8 @@ const bridgeCommands = {
1769
1781
  const result = await this.readCommand(deviceData, subCommandIds.customerTemperatureThresholds);
1770
1782
  const structurized = bridgeTools.convertBytesToStructure(
1771
1783
  bridgeCommandStructures.axleTemperatureThresholds.structure,
1772
- result.data
1784
+ result.data,
1785
+ deviceData.advertisingData.fwVersion
1773
1786
  );
1774
1787
  return { ...structurized, isFactory: result.isFactory };
1775
1788
  },
@@ -1778,7 +1791,8 @@ const bridgeCommands = {
1778
1791
  const result = await this.readCommand(deviceData, subCommandIds.customerImbalanceThresholds);
1779
1792
  const structurized = bridgeTools.convertBytesToStructure(
1780
1793
  bridgeCommandStructures.axleImbalanceThresholds.structure,
1781
- result.data
1794
+ result.data,
1795
+ deviceData.advertisingData.fwVersion
1782
1796
  );
1783
1797
  return { ...structurized, isFactory: result.isFactory };
1784
1798
  },
@@ -1810,7 +1824,8 @@ const bridgeCommands = {
1810
1824
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1811
1825
  const payload = bridgeTools.convertStructureToBytes(
1812
1826
  bridgeCommandStructures.customerCanSettings.structure,
1813
- structurizedPayload
1827
+ structurizedPayload,
1828
+ deviceData.advertisingData.fwVersion
1814
1829
  );
1815
1830
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerCanSettings, payload);
1816
1831
  },
@@ -1836,7 +1851,8 @@ const bridgeCommands = {
1836
1851
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1837
1852
  const payload = bridgeTools.convertStructureToBytes(
1838
1853
  bridgeCommandStructures.workshopCanSettings.structure,
1839
- structurizedPayload
1854
+ structurizedPayload,
1855
+ deviceData.advertisingData.fwVersion
1840
1856
  );
1841
1857
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.workshopCanSettings, payload);
1842
1858
  },
@@ -1844,7 +1860,8 @@ const bridgeCommands = {
1844
1860
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1845
1861
  const payload = bridgeTools.convertStructureToBytes(
1846
1862
  bridgeCommandStructures.axlePressureThresholds.structure,
1847
- structurizedPayload
1863
+ structurizedPayload,
1864
+ deviceData.advertisingData.fwVersion
1848
1865
  );
1849
1866
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerPressureThresholds, payload);
1850
1867
  },
@@ -1852,7 +1869,8 @@ const bridgeCommands = {
1852
1869
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1853
1870
  const payload = bridgeTools.convertStructureToBytes(
1854
1871
  bridgeCommandStructures.axleTemperatureThresholds.structure,
1855
- structurizedPayload
1872
+ structurizedPayload,
1873
+ deviceData.advertisingData.fwVersion
1856
1874
  );
1857
1875
  return await this.writeCommand(
1858
1876
  deviceData,
@@ -1865,7 +1883,8 @@ const bridgeCommands = {
1865
1883
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1866
1884
  const payload = bridgeTools.convertStructureToBytes(
1867
1885
  bridgeCommandStructures.axleImbalanceThresholds.structure,
1868
- structurizedPayload
1886
+ structurizedPayload,
1887
+ deviceData.advertisingData.fwVersion
1869
1888
  );
1870
1889
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerImbalanceThresholds, payload);
1871
1890
  },
@@ -1874,7 +1893,8 @@ const bridgeCommands = {
1874
1893
  const result = await this.readCommand(deviceData, subCommandIds.autolearnSettings);
1875
1894
  const structurized = bridgeTools.convertBytesToStructure(
1876
1895
  bridgeCommandStructures.autolearnSettings.structure,
1877
- result.data
1896
+ result.data,
1897
+ deviceData.advertisingData.fwVersion
1878
1898
  );
1879
1899
  return { ...structurized, isFactory: result.isFactory };
1880
1900
  },
@@ -1883,7 +1903,8 @@ const bridgeCommands = {
1883
1903
  const result = await this.readCommand(deviceData, subCommandIds.autolearnIdStatus);
1884
1904
  const structurized = bridgeTools.convertBytesToStructure(
1885
1905
  bridgeCommandStructures.autolearnIdStatus.structure,
1886
- result.data
1906
+ result.data,
1907
+ deviceData.advertisingData.fwVersion
1887
1908
  );
1888
1909
  return { ...structurized, isFactory: result.isFactory };
1889
1910
  },
@@ -1891,7 +1912,8 @@ const bridgeCommands = {
1891
1912
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1892
1913
  const payload = bridgeTools.convertStructureToBytes(
1893
1914
  bridgeCommandStructures.autolearnSettings.structure,
1894
- structurizedPayload
1915
+ structurizedPayload,
1916
+ deviceData.advertisingData.fwVersion
1895
1917
  );
1896
1918
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.autolearnSettings, payload);
1897
1919
  },
@@ -1899,7 +1921,8 @@ const bridgeCommands = {
1899
1921
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1900
1922
  const payload = bridgeTools.convertStructureToBytes(
1901
1923
  bridgeCommandStructures.autolearnIdStatus.structure,
1902
- structurizedPayload
1924
+ structurizedPayload,
1925
+ deviceData.advertisingData.fwVersion
1903
1926
  );
1904
1927
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.autolearnIdStatus, payload);
1905
1928
  },
@@ -1907,7 +1930,8 @@ const bridgeCommands = {
1907
1930
  const result = await this.readCommand(device, subCommandIds.autolearnUnknownSensors);
1908
1931
  const structurized = bridgeTools.convertBytesToStructure(
1909
1932
  bridgeCommandStructures.autolearnUnknownSensors.structure,
1910
- result.data
1933
+ result.data,
1934
+ device.advertisingData.fwVersion
1911
1935
  );
1912
1936
  return { ...structurized, isFactory: result.isFactory };
1913
1937
  },
@@ -1933,7 +1957,8 @@ const bridgeCommands = {
1933
1957
  const result = await this.readCommand(deviceData, subCommandIds.pressurePerAxle);
1934
1958
  const structurizedData = bridgeTools.convertBytesToStructure(
1935
1959
  bridgeCommandStructures.pressuresPerAxle.structure,
1936
- result.data
1960
+ result.data,
1961
+ deviceData.advertisingData.fwVersion
1937
1962
  );
1938
1963
  return structurizedData;
1939
1964
  },
@@ -1941,7 +1966,8 @@ const bridgeCommands = {
1941
1966
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1942
1967
  const payload = bridgeTools.convertStructureToBytes(
1943
1968
  bridgeCommandStructures.pressuresPerAxle.structure,
1944
- structurizedPayload
1969
+ structurizedPayload,
1970
+ deviceData.advertisingData.fwVersion
1945
1971
  );
1946
1972
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.pressurePerAxle, payload);
1947
1973
  },
@@ -1969,7 +1995,12 @@ const bridgeCommands = {
1969
1995
  async getVehicleLayout(deviceId) {
1970
1996
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1971
1997
  const result = await this.readCommand(deviceData, subCommandIds.vehicleLayout);
1972
- return result.data;
1998
+ const structurizedData = bridgeTools.convertBytesToStructure(
1999
+ bridgeCommandStructures.vehicleLayout.structure,
2000
+ result.data,
2001
+ deviceData.advertisingData.fwVersion
2002
+ );
2003
+ return structurizedData;
1973
2004
  },
1974
2005
  async getSensorMeasurement(deviceId, positionId) {
1975
2006
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -2033,11 +2064,11 @@ const bridgeCommands = {
2033
2064
  throw new Error("Invalid command");
2034
2065
  }
2035
2066
  if (!canCommunicateWith(device.id)) throw new Error("Bridge not connected");
2036
- clearTimeout(keepAliveTimer);
2037
- keepAliveTimer = setTimeout(() => {
2067
+ clearTimeout(keepAliveTimer[device.id]);
2068
+ keepAliveTimer[device.id] = setTimeout(() => {
2038
2069
  if (store.deviceState[device.id] !== "paired" || store.devices[device.id]?.type !== "bridge") {
2039
2070
  console.warn("keep alive timer cleared");
2040
- return clearTimeout(keepAliveTimer);
2071
+ return clearTimeout(keepAliveTimer[device.id]);
2041
2072
  }
2042
2073
  this.sendKeepAliveCommand(device);
2043
2074
  }, 1e4);
@@ -2046,12 +2077,12 @@ const bridgeCommands = {
2046
2077
  };
2047
2078
 
2048
2079
  const vehicleLayoutAxleTypes = {
2049
- noAxle: [0, 0],
2050
- twoTyresAxle: [128, 2],
2051
- twoTyresAxleSpare: [128, 3],
2052
- fourTyresAxle: [192, 6],
2053
- fourTyresAxleSpare: [192, 7],
2054
- spareTyreAxle: [1, 0]
2080
+ noAxle: "0000",
2081
+ twoTyresAxle: "0280",
2082
+ twoTyresAxleSpare: "0380",
2083
+ fourTyresAxle: "06C0",
2084
+ fourTyresAxleSpare: "07C0",
2085
+ spareTyreAxle: "0001"
2055
2086
  };
2056
2087
  const bridgeService = {
2057
2088
  updateFirmware,
@@ -2086,37 +2117,49 @@ async function updateFirmware(deviceId, bootloader, firmware, reportStatus) {
2086
2117
  async function setVehicleLayout(deviceId, tcVehicle) {
2087
2118
  const spareTyres = tcVehicle.tcTyres?.filter((tyre) => String(tyre.mountedOn?.positionId).endsWith("0"));
2088
2119
  let spareTyresCount = Math.min(spareTyres.length || 0, 2);
2089
- let layout = [];
2120
+ const result = {
2121
+ axle01: "0000",
2122
+ axle02: "0000",
2123
+ axle03: "0000",
2124
+ axle04: "0000",
2125
+ axle05: "0000",
2126
+ axle06: "0000",
2127
+ axle07: "0000",
2128
+ axle08: "0000",
2129
+ axle09: "0000",
2130
+ axle10: "0000",
2131
+ axle11: "0000",
2132
+ axle12: "0000",
2133
+ axle13: "0000",
2134
+ axle14: "0000",
2135
+ axle15: "0000",
2136
+ vin: tcVehicle.vin ?? "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
2137
+ vinExtension: tcVehicle.vinExtension ?? "\0"
2138
+ };
2090
2139
  for (let index = 0; index < 15; index++) {
2091
- const tyresCount = tcVehicle.axles && tcVehicle.axles[index]?.tyresCount;
2092
- if (tyresCount === 2) {
2093
- let value = vehicleLayoutAxleTypes.twoTyresAxle;
2140
+ const resultKey = Object.keys(result)[index];
2141
+ const tyreCount = tcVehicle.axles[index]?.tyresCount;
2142
+ if (tyreCount === 2) {
2094
2143
  if (spareTyresCount) {
2095
- value = vehicleLayoutAxleTypes.twoTyresAxleSpare;
2144
+ result[resultKey] = vehicleLayoutAxleTypes.twoTyresAxleSpare;
2096
2145
  spareTyresCount -= 1;
2146
+ } else {
2147
+ result[resultKey] = vehicleLayoutAxleTypes.twoTyresAxle;
2097
2148
  }
2098
- layout = [...layout, ...value];
2099
2149
  continue;
2100
2150
  }
2101
- if (tyresCount === 4) {
2102
- let value = vehicleLayoutAxleTypes.fourTyresAxle;
2151
+ if (tyreCount === 4) {
2103
2152
  if (spareTyresCount) {
2104
- value = vehicleLayoutAxleTypes.fourTyresAxleSpare;
2153
+ result[resultKey] = vehicleLayoutAxleTypes.fourTyresAxleSpare;
2105
2154
  spareTyresCount -= 1;
2155
+ } else {
2156
+ result[resultKey] = vehicleLayoutAxleTypes.fourTyresAxle;
2106
2157
  }
2107
- layout = [...layout, ...value];
2108
2158
  continue;
2109
2159
  }
2110
- layout = [...layout, ...vehicleLayoutAxleTypes.noAxle];
2111
- }
2112
- let vin = tcVehicle.vin ? tcVehicle.vin.split("").map((x) => x.charCodeAt(0)) : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2113
- if (vin.length !== 17) {
2114
- throw new Error(`Incorrect VIN length: ${vin}`);
2115
- }
2116
- if (bridgeTools.isVersionGreaterThan(deviceId, "1.0.2")) {
2117
- vin = [...vin, 0];
2160
+ result[resultKey] = vehicleLayoutAxleTypes.noAxle;
2118
2161
  }
2119
- await bridgeCommands.setVehicleLayout(deviceId, [...layout, ...vin]);
2162
+ await bridgeCommands.setVehicleLayout(deviceId, result);
2120
2163
  }
2121
2164
  async function getConfiguration(deviceId) {
2122
2165
  const customerCANSettings = await bridgeCommands.getCustomerCANSettings(deviceId);
@@ -2588,9 +2631,8 @@ async function getVehicle(deviceId) {
2588
2631
  }
2589
2632
  async function assignAxles(deviceId, tcVehicle) {
2590
2633
  const result = await bridgeCommands.getVehicleLayout(deviceId);
2591
- const data = result.map((x) => bridgeTools.decimalToHex(x));
2592
- const joinedData = Array.from({ length: data.length / 2 }, (_2, index) => data[2 * index + 1] + data[2 * index]);
2593
- const activeAxles = joinedData.slice(0, 15).filter((x) => Number(`0x${x}`));
2634
+ tcVehicle.vinExtension = result.vinExtension;
2635
+ const activeAxles = Object.values(result).slice(0, 15).filter((a) => Number.parseInt(a, 16));
2594
2636
  const axlesPressureData = (await bridgeCommands.getAxlesPressure(deviceId)).data;
2595
2637
  let axleTypesBytes;
2596
2638
  if (bridgeTools.isVersionGreaterThan(deviceId, "0.9.7")) {
@@ -2664,10 +2706,10 @@ async function assignTyres(deviceId, tcVehicle) {
2664
2706
  async function assignAxlePressureLimits(deviceId, tcVehicle, tcVehicleAxle, axleIndex, bridgeAxlesPressureData) {
2665
2707
  const axlesPressureData = bridgeAxlesPressureData ?? (await bridgeCommands.getAxlesPressure(deviceId)).data;
2666
2708
  if (axlesPressureData[axleIndex * 3]) {
2667
- tcVehicleAxle.maxTargetPressure = ___default.round(bridgeTools.kpaByteToBar(axlesPressureData[axleIndex * 3]), 1);
2709
+ tcVehicleAxle.maxTargetPressure = ___default.floor(bridgeTools.kpaByteToBar(axlesPressureData[axleIndex * 3]), 1);
2668
2710
  }
2669
2711
  if (axlesPressureData[axleIndex * 3 + 1]) {
2670
- tcVehicleAxle.minTargetPressure = ___default.round(bridgeTools.kpaByteToBar(axlesPressureData[axleIndex * 3 + 1]), 1);
2712
+ tcVehicleAxle.minTargetPressure = ___default.ceil(bridgeTools.kpaByteToBar(axlesPressureData[axleIndex * 3 + 1]), 1);
2671
2713
  }
2672
2714
  if (axlesPressureData[axleIndex * 3 + 2]) {
2673
2715
  tcVehicleAxle.targetPressure = ___default.round(
@@ -2726,12 +2768,11 @@ async function connect(deviceId, accessLevel) {
2726
2768
  await bridgeService.sendPinCommand(deviceId);
2727
2769
  store.setState(deviceId, "paired");
2728
2770
  } catch (e) {
2729
- disconnect(deviceId);
2771
+ disconnect(deviceId, "failedConnection");
2730
2772
  throw new Error(`Pairing unsuccessful ${e}`);
2731
2773
  }
2732
2774
  }
2733
2775
  async function disconnect(deviceId, reason) {
2734
- await waitUntil(() => store.deviceState[deviceId] === "paired" || store.deviceState[deviceId] === void 0);
2735
2776
  store.setState(deviceId, "disconnecting");
2736
2777
  promiseQueue.clearQueue(deviceId, "Previous pending commands aborted");
2737
2778
  await bluetooth.disconnect(deviceId);
package/dist/index.d.cts CHANGED
@@ -609,12 +609,7 @@ declare const _default: {
609
609
  size: number;
610
610
  description: string;
611
611
  display: "ascii";
612
- optional: true;
613
- };
614
- test: {
615
- size: number;
616
- description: string;
617
- optional: true;
612
+ version: string;
618
613
  };
619
614
  };
620
615
  };
@@ -626,6 +621,7 @@ type DeepPartial<T> = T extends object ? {
626
621
  interface BridgeTcVehicle {
627
622
  registrationNumber?: string;
628
623
  vin?: string;
624
+ vinExtension?: string;
629
625
  axles: BridgeTcVehicleAxle[];
630
626
  tcTyres: BridgeTcTyre[];
631
627
  /** Ignored in set, returned in get */
@@ -734,7 +730,8 @@ interface BridgeCommandStructureProperties {
734
730
  size: number;
735
731
  display?: 'decimal' | 'ascii' | 'reverseHex';
736
732
  description: string;
737
- optional?: boolean;
733
+ /** From which bridge version is this property available */
734
+ version?: string;
738
735
  };
739
736
  }
740
737
  type BridgeCommandStructurized<T extends BridgeCommandStructureProperties> = {
package/dist/index.d.mts CHANGED
@@ -609,12 +609,7 @@ declare const _default: {
609
609
  size: number;
610
610
  description: string;
611
611
  display: "ascii";
612
- optional: true;
613
- };
614
- test: {
615
- size: number;
616
- description: string;
617
- optional: true;
612
+ version: string;
618
613
  };
619
614
  };
620
615
  };
@@ -626,6 +621,7 @@ type DeepPartial<T> = T extends object ? {
626
621
  interface BridgeTcVehicle {
627
622
  registrationNumber?: string;
628
623
  vin?: string;
624
+ vinExtension?: string;
629
625
  axles: BridgeTcVehicleAxle[];
630
626
  tcTyres: BridgeTcTyre[];
631
627
  /** Ignored in set, returned in get */
@@ -734,7 +730,8 @@ interface BridgeCommandStructureProperties {
734
730
  size: number;
735
731
  display?: 'decimal' | 'ascii' | 'reverseHex';
736
732
  description: string;
737
- optional?: boolean;
733
+ /** From which bridge version is this property available */
734
+ version?: string;
738
735
  };
739
736
  }
740
737
  type BridgeCommandStructurized<T extends BridgeCommandStructureProperties> = {
package/dist/index.d.ts CHANGED
@@ -609,12 +609,7 @@ declare const _default: {
609
609
  size: number;
610
610
  description: string;
611
611
  display: "ascii";
612
- optional: true;
613
- };
614
- test: {
615
- size: number;
616
- description: string;
617
- optional: true;
612
+ version: string;
618
613
  };
619
614
  };
620
615
  };
@@ -626,6 +621,7 @@ type DeepPartial<T> = T extends object ? {
626
621
  interface BridgeTcVehicle {
627
622
  registrationNumber?: string;
628
623
  vin?: string;
624
+ vinExtension?: string;
629
625
  axles: BridgeTcVehicleAxle[];
630
626
  tcTyres: BridgeTcTyre[];
631
627
  /** Ignored in set, returned in get */
@@ -734,7 +730,8 @@ interface BridgeCommandStructureProperties {
734
730
  size: number;
735
731
  display?: 'decimal' | 'ascii' | 'reverseHex';
736
732
  description: string;
737
- optional?: boolean;
733
+ /** From which bridge version is this property available */
734
+ version?: string;
738
735
  };
739
736
  }
740
737
  type BridgeCommandStructurized<T extends BridgeCommandStructureProperties> = {
package/dist/index.mjs CHANGED
@@ -116,15 +116,23 @@ const bridgeTools = {
116
116
  if (deviceData.type !== "bridge") throw new Error("Device is not bridge");
117
117
  return deviceData;
118
118
  },
119
- convertBytesToStructure(objStructure, payload) {
120
- const numArray = _.clone(payload);
121
- const keys = Object.keys(objStructure);
119
+ convertBytesToStructure(objStructure, payload, fwVersion) {
120
+ let numArray = _.clone(payload);
121
+ const keys = Object.keys(objStructure).filter(
122
+ (key) => !objStructure[key].version || !fwVersion || fwVersion >= objStructure[key].version
123
+ );
122
124
  let sumWithInitial = 0;
123
125
  for (const key of keys) {
124
126
  sumWithInitial += objStructure[key].size;
125
127
  }
128
+ if (numArray.length < sumWithInitial) {
129
+ console.warn("missing bytes filled with empty values");
130
+ numArray = numArray.concat(Array.from({ length: sumWithInitial - numArray.length }, () => 0));
131
+ }
126
132
  if (numArray.length !== sumWithInitial) {
127
- throw new Error("Cannot convert bytes to object");
133
+ throw new Error(
134
+ `Cannot convert bytes to object: bytes received ${numArray.length}, expected ${sumWithInitial}, fw version ${fwVersion}`
135
+ );
128
136
  }
129
137
  const result = {};
130
138
  for (const key of keys) {
@@ -133,10 +141,13 @@ const bridgeTools = {
133
141
  }
134
142
  return result;
135
143
  },
136
- convertStructureToBytes(objStructure, structurizedObj) {
137
- const keys = Object.keys(objStructure);
144
+ convertStructureToBytes(objStructure, structurizedObj, fwVersion) {
145
+ const keys = Object.keys(objStructure).filter(
146
+ (key) => !objStructure[key].version || !fwVersion || fwVersion >= objStructure[key].version
147
+ );
138
148
  const result = [];
139
149
  for (const key of keys) {
150
+ if (!structurizedObj[key]) throw new Error(`Missing key ${key} in the structure`);
140
151
  const encoded = this.encodeData(structurizedObj[key], objStructure[key].display);
141
152
  if (encoded.length < objStructure[key].size) {
142
153
  const _padArray = Array.from({ length: objStructure[key].size - encoded.length }, () => 0);
@@ -173,7 +184,7 @@ const bridgeTools = {
173
184
  encodeData(data, displayUnits) {
174
185
  const _data = _.clone(data);
175
186
  if (displayUnits === "ascii") {
176
- return _data.split("").map((v, i) => _data.charCodeAt(i));
187
+ return this.asciiToDecimalArray(_data);
177
188
  }
178
189
  if (displayUnits === "decimal") {
179
190
  return this.hexToDecimalArray(this.decimalToHex(_data)).reverse();
@@ -185,16 +196,6 @@ const bridgeTools = {
185
196
  }
186
197
  return this.hexToDecimalArray(_data).reverse();
187
198
  },
188
- // getBridgeId(device: BluetoothDeviceBridge) {
189
- // // [244,177, 0, 34,123, 155] => F4B100227B9B
190
- // return (
191
- // device.advertisingData.macAddress
192
- // ?.map(n => this.decimalToHex(n))
193
- // .reverse()
194
- // .join('')
195
- // .toUpperCase() || ''
196
- // )
197
- // },
198
199
  pkcs(array, length) {
199
200
  const pkcsValue = length - array.length;
200
201
  if (pkcsValue > 0) {
@@ -206,6 +207,9 @@ const bridgeTools = {
206
207
  const hex = decimal.toString(16);
207
208
  return hex.padStart(2, "0");
208
209
  },
210
+ asciiToDecimalArray(ascii) {
211
+ return ascii.split("").map((x) => x.charCodeAt(0));
212
+ },
209
213
  hexToDecimalArray(hex) {
210
214
  return hex.match(/.{1,2}/g)?.map((byte) => Number.parseInt(byte, 16)) || [];
211
215
  },
@@ -334,8 +338,9 @@ function getDefaultTyreLabels() {
334
338
  const bridgeAdvertisingParser = {
335
339
  getDeviceInfoFromAdvertising(device) {
336
340
  const adversitingType = getAdvertisingType(device);
337
- if (adversitingType !== "connectable") return void 0;
341
+ if (adversitingType !== "connectable") return;
338
342
  const advertisingData = getAdvertisingData({ advertising: device.advertising, deviceName: device.name });
343
+ if (!advertisingData) return;
339
344
  const macArray = advertisingData?.macAddress?.map((n) => bridgeTools.decimalToHex(n).toUpperCase()).reverse() || [];
340
345
  const bridgeId = macArray.join("");
341
346
  const vin = String.fromCharCode(...advertisingData?.vinNum || []).split("\0").join("");
@@ -371,7 +376,7 @@ function getAdvertisingData({ advertising, deviceName }) {
371
376
  const adv = Array.from(uint8);
372
377
  const advertisingData = advertising.kCBAdvDataIsConnectable ? processIosAdvertising(adv, isKrone) : processAndroidAdvertising(adv, isKrone);
373
378
  if (!advertisingData || !advertisingData.macAddress.length || !advertisingData.randomAdvNumber.length || !advertisingData.vinNum.length) {
374
- throw new Error("Device not recognized");
379
+ return;
375
380
  }
376
381
  return advertisingData;
377
382
  }
@@ -582,12 +587,16 @@ async function connect$1(deviceId, disconnectCallback) {
582
587
  if (toolsSvc.canCommunicateWith(deviceId)) return console.warn("Connect Warn: Already connected to device");
583
588
  store.setState(deviceId, "connecting");
584
589
  let connectedDevice;
585
- for (let attempt = 0; attempt < 3; attempt++) {
590
+ for (let attempt = 1; attempt <= 3; attempt++) {
586
591
  try {
587
592
  connectedDevice = await withTimeout(connectInner(deviceId, disconnectCallback), 2e4);
588
593
  const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
589
594
  const isConnected = await ble.isConnected(_deviceId);
590
- if (connectedDevice && isConnected) break;
595
+ if (connectedDevice || isConnected) {
596
+ break;
597
+ } else {
598
+ throw new Error("Connection incomplete");
599
+ }
591
600
  } catch (e) {
592
601
  console.warn(`${attempt} connect fail`, e);
593
602
  if (attempt === 3) {
@@ -1367,12 +1376,7 @@ const bridgeCommandStructures = {
1367
1376
  size: 1,
1368
1377
  description: "VIN extension",
1369
1378
  display: "ascii",
1370
- optional: true
1371
- },
1372
- test: {
1373
- size: 3,
1374
- description: "Test",
1375
- optional: true
1379
+ version: "1.0.3"
1376
1380
  }
1377
1381
  }
1378
1382
  }
@@ -1715,7 +1719,7 @@ const subCommandIds = {
1715
1719
  };
1716
1720
  _.invert(commandIds);
1717
1721
  _.invert(subCommandIds);
1718
- let keepAliveTimer;
1722
+ const keepAliveTimer = {};
1719
1723
  const bridgeCommands = {
1720
1724
  getCommandHeader(device) {
1721
1725
  const accessLevel = store.deviceAccessLevel[device.id];
@@ -1726,16 +1730,22 @@ const bridgeCommands = {
1726
1730
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1727
1731
  await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.pressurePerAxle, data);
1728
1732
  },
1729
- async setVehicleLayout(deviceId, data) {
1733
+ async setVehicleLayout(deviceId, structurizedPayload) {
1730
1734
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1731
- await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.vehicleLayout, data);
1735
+ const payload = bridgeTools.convertStructureToBytes(
1736
+ bridgeCommandStructures.vehicleLayout.structure,
1737
+ structurizedPayload,
1738
+ deviceData.advertisingData.fwVersion
1739
+ );
1740
+ await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.vehicleLayout, payload);
1732
1741
  },
1733
1742
  async getCustomerCANSettings(deviceId) {
1734
1743
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1735
1744
  const result = await this.readCommand(deviceData, subCommandIds.customerCanSettings);
1736
1745
  const structurized = bridgeTools.convertBytesToStructure(
1737
1746
  bridgeCommandStructures.customerCanSettings.structure,
1738
- result.data
1747
+ result.data,
1748
+ deviceData.advertisingData.fwVersion
1739
1749
  );
1740
1750
  return { ...structurized, isFactory: result.isFactory };
1741
1751
  },
@@ -1744,7 +1754,8 @@ const bridgeCommands = {
1744
1754
  const result = await this.readCommand(deviceData, subCommandIds.workshopCanSettings);
1745
1755
  const structurized = bridgeTools.convertBytesToStructure(
1746
1756
  bridgeCommandStructures.workshopCanSettings.structure,
1747
- result.data
1757
+ result.data,
1758
+ deviceData.advertisingData.fwVersion
1748
1759
  );
1749
1760
  return { ...structurized, isFactory: result.isFactory };
1750
1761
  },
@@ -1753,7 +1764,8 @@ const bridgeCommands = {
1753
1764
  const result = await this.readCommand(deviceData, subCommandIds.customerPressureThresholds);
1754
1765
  const structurized = bridgeTools.convertBytesToStructure(
1755
1766
  bridgeCommandStructures.axlePressureThresholds.structure,
1756
- result.data
1767
+ result.data,
1768
+ deviceData.advertisingData.fwVersion
1757
1769
  );
1758
1770
  return { ...structurized, isFactory: result.isFactory };
1759
1771
  },
@@ -1762,7 +1774,8 @@ const bridgeCommands = {
1762
1774
  const result = await this.readCommand(deviceData, subCommandIds.customerTemperatureThresholds);
1763
1775
  const structurized = bridgeTools.convertBytesToStructure(
1764
1776
  bridgeCommandStructures.axleTemperatureThresholds.structure,
1765
- result.data
1777
+ result.data,
1778
+ deviceData.advertisingData.fwVersion
1766
1779
  );
1767
1780
  return { ...structurized, isFactory: result.isFactory };
1768
1781
  },
@@ -1771,7 +1784,8 @@ const bridgeCommands = {
1771
1784
  const result = await this.readCommand(deviceData, subCommandIds.customerImbalanceThresholds);
1772
1785
  const structurized = bridgeTools.convertBytesToStructure(
1773
1786
  bridgeCommandStructures.axleImbalanceThresholds.structure,
1774
- result.data
1787
+ result.data,
1788
+ deviceData.advertisingData.fwVersion
1775
1789
  );
1776
1790
  return { ...structurized, isFactory: result.isFactory };
1777
1791
  },
@@ -1803,7 +1817,8 @@ const bridgeCommands = {
1803
1817
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1804
1818
  const payload = bridgeTools.convertStructureToBytes(
1805
1819
  bridgeCommandStructures.customerCanSettings.structure,
1806
- structurizedPayload
1820
+ structurizedPayload,
1821
+ deviceData.advertisingData.fwVersion
1807
1822
  );
1808
1823
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerCanSettings, payload);
1809
1824
  },
@@ -1829,7 +1844,8 @@ const bridgeCommands = {
1829
1844
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1830
1845
  const payload = bridgeTools.convertStructureToBytes(
1831
1846
  bridgeCommandStructures.workshopCanSettings.structure,
1832
- structurizedPayload
1847
+ structurizedPayload,
1848
+ deviceData.advertisingData.fwVersion
1833
1849
  );
1834
1850
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.workshopCanSettings, payload);
1835
1851
  },
@@ -1837,7 +1853,8 @@ const bridgeCommands = {
1837
1853
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1838
1854
  const payload = bridgeTools.convertStructureToBytes(
1839
1855
  bridgeCommandStructures.axlePressureThresholds.structure,
1840
- structurizedPayload
1856
+ structurizedPayload,
1857
+ deviceData.advertisingData.fwVersion
1841
1858
  );
1842
1859
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerPressureThresholds, payload);
1843
1860
  },
@@ -1845,7 +1862,8 @@ const bridgeCommands = {
1845
1862
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1846
1863
  const payload = bridgeTools.convertStructureToBytes(
1847
1864
  bridgeCommandStructures.axleTemperatureThresholds.structure,
1848
- structurizedPayload
1865
+ structurizedPayload,
1866
+ deviceData.advertisingData.fwVersion
1849
1867
  );
1850
1868
  return await this.writeCommand(
1851
1869
  deviceData,
@@ -1858,7 +1876,8 @@ const bridgeCommands = {
1858
1876
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1859
1877
  const payload = bridgeTools.convertStructureToBytes(
1860
1878
  bridgeCommandStructures.axleImbalanceThresholds.structure,
1861
- structurizedPayload
1879
+ structurizedPayload,
1880
+ deviceData.advertisingData.fwVersion
1862
1881
  );
1863
1882
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerImbalanceThresholds, payload);
1864
1883
  },
@@ -1867,7 +1886,8 @@ const bridgeCommands = {
1867
1886
  const result = await this.readCommand(deviceData, subCommandIds.autolearnSettings);
1868
1887
  const structurized = bridgeTools.convertBytesToStructure(
1869
1888
  bridgeCommandStructures.autolearnSettings.structure,
1870
- result.data
1889
+ result.data,
1890
+ deviceData.advertisingData.fwVersion
1871
1891
  );
1872
1892
  return { ...structurized, isFactory: result.isFactory };
1873
1893
  },
@@ -1876,7 +1896,8 @@ const bridgeCommands = {
1876
1896
  const result = await this.readCommand(deviceData, subCommandIds.autolearnIdStatus);
1877
1897
  const structurized = bridgeTools.convertBytesToStructure(
1878
1898
  bridgeCommandStructures.autolearnIdStatus.structure,
1879
- result.data
1899
+ result.data,
1900
+ deviceData.advertisingData.fwVersion
1880
1901
  );
1881
1902
  return { ...structurized, isFactory: result.isFactory };
1882
1903
  },
@@ -1884,7 +1905,8 @@ const bridgeCommands = {
1884
1905
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1885
1906
  const payload = bridgeTools.convertStructureToBytes(
1886
1907
  bridgeCommandStructures.autolearnSettings.structure,
1887
- structurizedPayload
1908
+ structurizedPayload,
1909
+ deviceData.advertisingData.fwVersion
1888
1910
  );
1889
1911
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.autolearnSettings, payload);
1890
1912
  },
@@ -1892,7 +1914,8 @@ const bridgeCommands = {
1892
1914
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1893
1915
  const payload = bridgeTools.convertStructureToBytes(
1894
1916
  bridgeCommandStructures.autolearnIdStatus.structure,
1895
- structurizedPayload
1917
+ structurizedPayload,
1918
+ deviceData.advertisingData.fwVersion
1896
1919
  );
1897
1920
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.autolearnIdStatus, payload);
1898
1921
  },
@@ -1900,7 +1923,8 @@ const bridgeCommands = {
1900
1923
  const result = await this.readCommand(device, subCommandIds.autolearnUnknownSensors);
1901
1924
  const structurized = bridgeTools.convertBytesToStructure(
1902
1925
  bridgeCommandStructures.autolearnUnknownSensors.structure,
1903
- result.data
1926
+ result.data,
1927
+ device.advertisingData.fwVersion
1904
1928
  );
1905
1929
  return { ...structurized, isFactory: result.isFactory };
1906
1930
  },
@@ -1926,7 +1950,8 @@ const bridgeCommands = {
1926
1950
  const result = await this.readCommand(deviceData, subCommandIds.pressurePerAxle);
1927
1951
  const structurizedData = bridgeTools.convertBytesToStructure(
1928
1952
  bridgeCommandStructures.pressuresPerAxle.structure,
1929
- result.data
1953
+ result.data,
1954
+ deviceData.advertisingData.fwVersion
1930
1955
  );
1931
1956
  return structurizedData;
1932
1957
  },
@@ -1934,7 +1959,8 @@ const bridgeCommands = {
1934
1959
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1935
1960
  const payload = bridgeTools.convertStructureToBytes(
1936
1961
  bridgeCommandStructures.pressuresPerAxle.structure,
1937
- structurizedPayload
1962
+ structurizedPayload,
1963
+ deviceData.advertisingData.fwVersion
1938
1964
  );
1939
1965
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.pressurePerAxle, payload);
1940
1966
  },
@@ -1962,7 +1988,12 @@ const bridgeCommands = {
1962
1988
  async getVehicleLayout(deviceId) {
1963
1989
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1964
1990
  const result = await this.readCommand(deviceData, subCommandIds.vehicleLayout);
1965
- return result.data;
1991
+ const structurizedData = bridgeTools.convertBytesToStructure(
1992
+ bridgeCommandStructures.vehicleLayout.structure,
1993
+ result.data,
1994
+ deviceData.advertisingData.fwVersion
1995
+ );
1996
+ return structurizedData;
1966
1997
  },
1967
1998
  async getSensorMeasurement(deviceId, positionId) {
1968
1999
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -2026,11 +2057,11 @@ const bridgeCommands = {
2026
2057
  throw new Error("Invalid command");
2027
2058
  }
2028
2059
  if (!canCommunicateWith(device.id)) throw new Error("Bridge not connected");
2029
- clearTimeout(keepAliveTimer);
2030
- keepAliveTimer = setTimeout(() => {
2060
+ clearTimeout(keepAliveTimer[device.id]);
2061
+ keepAliveTimer[device.id] = setTimeout(() => {
2031
2062
  if (store.deviceState[device.id] !== "paired" || store.devices[device.id]?.type !== "bridge") {
2032
2063
  console.warn("keep alive timer cleared");
2033
- return clearTimeout(keepAliveTimer);
2064
+ return clearTimeout(keepAliveTimer[device.id]);
2034
2065
  }
2035
2066
  this.sendKeepAliveCommand(device);
2036
2067
  }, 1e4);
@@ -2039,12 +2070,12 @@ const bridgeCommands = {
2039
2070
  };
2040
2071
 
2041
2072
  const vehicleLayoutAxleTypes = {
2042
- noAxle: [0, 0],
2043
- twoTyresAxle: [128, 2],
2044
- twoTyresAxleSpare: [128, 3],
2045
- fourTyresAxle: [192, 6],
2046
- fourTyresAxleSpare: [192, 7],
2047
- spareTyreAxle: [1, 0]
2073
+ noAxle: "0000",
2074
+ twoTyresAxle: "0280",
2075
+ twoTyresAxleSpare: "0380",
2076
+ fourTyresAxle: "06C0",
2077
+ fourTyresAxleSpare: "07C0",
2078
+ spareTyreAxle: "0001"
2048
2079
  };
2049
2080
  const bridgeService = {
2050
2081
  updateFirmware,
@@ -2079,37 +2110,49 @@ async function updateFirmware(deviceId, bootloader, firmware, reportStatus) {
2079
2110
  async function setVehicleLayout(deviceId, tcVehicle) {
2080
2111
  const spareTyres = tcVehicle.tcTyres?.filter((tyre) => String(tyre.mountedOn?.positionId).endsWith("0"));
2081
2112
  let spareTyresCount = Math.min(spareTyres.length || 0, 2);
2082
- let layout = [];
2113
+ const result = {
2114
+ axle01: "0000",
2115
+ axle02: "0000",
2116
+ axle03: "0000",
2117
+ axle04: "0000",
2118
+ axle05: "0000",
2119
+ axle06: "0000",
2120
+ axle07: "0000",
2121
+ axle08: "0000",
2122
+ axle09: "0000",
2123
+ axle10: "0000",
2124
+ axle11: "0000",
2125
+ axle12: "0000",
2126
+ axle13: "0000",
2127
+ axle14: "0000",
2128
+ axle15: "0000",
2129
+ vin: tcVehicle.vin ?? "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
2130
+ vinExtension: tcVehicle.vinExtension ?? "\0"
2131
+ };
2083
2132
  for (let index = 0; index < 15; index++) {
2084
- const tyresCount = tcVehicle.axles && tcVehicle.axles[index]?.tyresCount;
2085
- if (tyresCount === 2) {
2086
- let value = vehicleLayoutAxleTypes.twoTyresAxle;
2133
+ const resultKey = Object.keys(result)[index];
2134
+ const tyreCount = tcVehicle.axles[index]?.tyresCount;
2135
+ if (tyreCount === 2) {
2087
2136
  if (spareTyresCount) {
2088
- value = vehicleLayoutAxleTypes.twoTyresAxleSpare;
2137
+ result[resultKey] = vehicleLayoutAxleTypes.twoTyresAxleSpare;
2089
2138
  spareTyresCount -= 1;
2139
+ } else {
2140
+ result[resultKey] = vehicleLayoutAxleTypes.twoTyresAxle;
2090
2141
  }
2091
- layout = [...layout, ...value];
2092
2142
  continue;
2093
2143
  }
2094
- if (tyresCount === 4) {
2095
- let value = vehicleLayoutAxleTypes.fourTyresAxle;
2144
+ if (tyreCount === 4) {
2096
2145
  if (spareTyresCount) {
2097
- value = vehicleLayoutAxleTypes.fourTyresAxleSpare;
2146
+ result[resultKey] = vehicleLayoutAxleTypes.fourTyresAxleSpare;
2098
2147
  spareTyresCount -= 1;
2148
+ } else {
2149
+ result[resultKey] = vehicleLayoutAxleTypes.fourTyresAxle;
2099
2150
  }
2100
- layout = [...layout, ...value];
2101
2151
  continue;
2102
2152
  }
2103
- layout = [...layout, ...vehicleLayoutAxleTypes.noAxle];
2104
- }
2105
- let vin = tcVehicle.vin ? tcVehicle.vin.split("").map((x) => x.charCodeAt(0)) : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2106
- if (vin.length !== 17) {
2107
- throw new Error(`Incorrect VIN length: ${vin}`);
2108
- }
2109
- if (bridgeTools.isVersionGreaterThan(deviceId, "1.0.2")) {
2110
- vin = [...vin, 0];
2153
+ result[resultKey] = vehicleLayoutAxleTypes.noAxle;
2111
2154
  }
2112
- await bridgeCommands.setVehicleLayout(deviceId, [...layout, ...vin]);
2155
+ await bridgeCommands.setVehicleLayout(deviceId, result);
2113
2156
  }
2114
2157
  async function getConfiguration(deviceId) {
2115
2158
  const customerCANSettings = await bridgeCommands.getCustomerCANSettings(deviceId);
@@ -2581,9 +2624,8 @@ async function getVehicle(deviceId) {
2581
2624
  }
2582
2625
  async function assignAxles(deviceId, tcVehicle) {
2583
2626
  const result = await bridgeCommands.getVehicleLayout(deviceId);
2584
- const data = result.map((x) => bridgeTools.decimalToHex(x));
2585
- const joinedData = Array.from({ length: data.length / 2 }, (_2, index) => data[2 * index + 1] + data[2 * index]);
2586
- const activeAxles = joinedData.slice(0, 15).filter((x) => Number(`0x${x}`));
2627
+ tcVehicle.vinExtension = result.vinExtension;
2628
+ const activeAxles = Object.values(result).slice(0, 15).filter((a) => Number.parseInt(a, 16));
2587
2629
  const axlesPressureData = (await bridgeCommands.getAxlesPressure(deviceId)).data;
2588
2630
  let axleTypesBytes;
2589
2631
  if (bridgeTools.isVersionGreaterThan(deviceId, "0.9.7")) {
@@ -2657,10 +2699,10 @@ async function assignTyres(deviceId, tcVehicle) {
2657
2699
  async function assignAxlePressureLimits(deviceId, tcVehicle, tcVehicleAxle, axleIndex, bridgeAxlesPressureData) {
2658
2700
  const axlesPressureData = bridgeAxlesPressureData ?? (await bridgeCommands.getAxlesPressure(deviceId)).data;
2659
2701
  if (axlesPressureData[axleIndex * 3]) {
2660
- tcVehicleAxle.maxTargetPressure = _.round(bridgeTools.kpaByteToBar(axlesPressureData[axleIndex * 3]), 1);
2702
+ tcVehicleAxle.maxTargetPressure = _.floor(bridgeTools.kpaByteToBar(axlesPressureData[axleIndex * 3]), 1);
2661
2703
  }
2662
2704
  if (axlesPressureData[axleIndex * 3 + 1]) {
2663
- tcVehicleAxle.minTargetPressure = _.round(bridgeTools.kpaByteToBar(axlesPressureData[axleIndex * 3 + 1]), 1);
2705
+ tcVehicleAxle.minTargetPressure = _.ceil(bridgeTools.kpaByteToBar(axlesPressureData[axleIndex * 3 + 1]), 1);
2664
2706
  }
2665
2707
  if (axlesPressureData[axleIndex * 3 + 2]) {
2666
2708
  tcVehicleAxle.targetPressure = _.round(
@@ -2719,12 +2761,11 @@ async function connect(deviceId, accessLevel) {
2719
2761
  await bridgeService.sendPinCommand(deviceId);
2720
2762
  store.setState(deviceId, "paired");
2721
2763
  } catch (e) {
2722
- disconnect(deviceId);
2764
+ disconnect(deviceId, "failedConnection");
2723
2765
  throw new Error(`Pairing unsuccessful ${e}`);
2724
2766
  }
2725
2767
  }
2726
2768
  async function disconnect(deviceId, reason) {
2727
- await waitUntil(() => store.deviceState[deviceId] === "paired" || store.deviceState[deviceId] === void 0);
2728
2769
  store.setState(deviceId, "disconnecting");
2729
2770
  promiseQueue.clearQueue(deviceId, "Previous pending commands aborted");
2730
2771
  await bluetooth.disconnect(deviceId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tirecheck-device-sdk",
3
- "version": "0.1.96",
3
+ "version": "0.1.98",
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",