tirecheck-device-sdk 0.1.97 → 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
  },
@@ -1379,12 +1383,7 @@ const bridgeCommandStructures = {
1379
1383
  size: 1,
1380
1384
  description: "VIN extension",
1381
1385
  display: "ascii",
1382
- optional: true
1383
- },
1384
- test: {
1385
- size: 3,
1386
- description: "Test",
1387
- optional: true
1386
+ version: "1.0.3"
1388
1387
  }
1389
1388
  }
1390
1389
  }
@@ -1738,16 +1737,22 @@ const bridgeCommands = {
1738
1737
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1739
1738
  await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.pressurePerAxle, data);
1740
1739
  },
1741
- async setVehicleLayout(deviceId, data) {
1740
+ async setVehicleLayout(deviceId, structurizedPayload) {
1742
1741
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1743
- 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);
1744
1748
  },
1745
1749
  async getCustomerCANSettings(deviceId) {
1746
1750
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1747
1751
  const result = await this.readCommand(deviceData, subCommandIds.customerCanSettings);
1748
1752
  const structurized = bridgeTools.convertBytesToStructure(
1749
1753
  bridgeCommandStructures.customerCanSettings.structure,
1750
- result.data
1754
+ result.data,
1755
+ deviceData.advertisingData.fwVersion
1751
1756
  );
1752
1757
  return { ...structurized, isFactory: result.isFactory };
1753
1758
  },
@@ -1756,7 +1761,8 @@ const bridgeCommands = {
1756
1761
  const result = await this.readCommand(deviceData, subCommandIds.workshopCanSettings);
1757
1762
  const structurized = bridgeTools.convertBytesToStructure(
1758
1763
  bridgeCommandStructures.workshopCanSettings.structure,
1759
- result.data
1764
+ result.data,
1765
+ deviceData.advertisingData.fwVersion
1760
1766
  );
1761
1767
  return { ...structurized, isFactory: result.isFactory };
1762
1768
  },
@@ -1765,7 +1771,8 @@ const bridgeCommands = {
1765
1771
  const result = await this.readCommand(deviceData, subCommandIds.customerPressureThresholds);
1766
1772
  const structurized = bridgeTools.convertBytesToStructure(
1767
1773
  bridgeCommandStructures.axlePressureThresholds.structure,
1768
- result.data
1774
+ result.data,
1775
+ deviceData.advertisingData.fwVersion
1769
1776
  );
1770
1777
  return { ...structurized, isFactory: result.isFactory };
1771
1778
  },
@@ -1774,7 +1781,8 @@ const bridgeCommands = {
1774
1781
  const result = await this.readCommand(deviceData, subCommandIds.customerTemperatureThresholds);
1775
1782
  const structurized = bridgeTools.convertBytesToStructure(
1776
1783
  bridgeCommandStructures.axleTemperatureThresholds.structure,
1777
- result.data
1784
+ result.data,
1785
+ deviceData.advertisingData.fwVersion
1778
1786
  );
1779
1787
  return { ...structurized, isFactory: result.isFactory };
1780
1788
  },
@@ -1783,7 +1791,8 @@ const bridgeCommands = {
1783
1791
  const result = await this.readCommand(deviceData, subCommandIds.customerImbalanceThresholds);
1784
1792
  const structurized = bridgeTools.convertBytesToStructure(
1785
1793
  bridgeCommandStructures.axleImbalanceThresholds.structure,
1786
- result.data
1794
+ result.data,
1795
+ deviceData.advertisingData.fwVersion
1787
1796
  );
1788
1797
  return { ...structurized, isFactory: result.isFactory };
1789
1798
  },
@@ -1815,7 +1824,8 @@ const bridgeCommands = {
1815
1824
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1816
1825
  const payload = bridgeTools.convertStructureToBytes(
1817
1826
  bridgeCommandStructures.customerCanSettings.structure,
1818
- structurizedPayload
1827
+ structurizedPayload,
1828
+ deviceData.advertisingData.fwVersion
1819
1829
  );
1820
1830
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerCanSettings, payload);
1821
1831
  },
@@ -1841,7 +1851,8 @@ const bridgeCommands = {
1841
1851
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1842
1852
  const payload = bridgeTools.convertStructureToBytes(
1843
1853
  bridgeCommandStructures.workshopCanSettings.structure,
1844
- structurizedPayload
1854
+ structurizedPayload,
1855
+ deviceData.advertisingData.fwVersion
1845
1856
  );
1846
1857
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.workshopCanSettings, payload);
1847
1858
  },
@@ -1849,7 +1860,8 @@ const bridgeCommands = {
1849
1860
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1850
1861
  const payload = bridgeTools.convertStructureToBytes(
1851
1862
  bridgeCommandStructures.axlePressureThresholds.structure,
1852
- structurizedPayload
1863
+ structurizedPayload,
1864
+ deviceData.advertisingData.fwVersion
1853
1865
  );
1854
1866
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerPressureThresholds, payload);
1855
1867
  },
@@ -1857,7 +1869,8 @@ const bridgeCommands = {
1857
1869
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1858
1870
  const payload = bridgeTools.convertStructureToBytes(
1859
1871
  bridgeCommandStructures.axleTemperatureThresholds.structure,
1860
- structurizedPayload
1872
+ structurizedPayload,
1873
+ deviceData.advertisingData.fwVersion
1861
1874
  );
1862
1875
  return await this.writeCommand(
1863
1876
  deviceData,
@@ -1870,7 +1883,8 @@ const bridgeCommands = {
1870
1883
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1871
1884
  const payload = bridgeTools.convertStructureToBytes(
1872
1885
  bridgeCommandStructures.axleImbalanceThresholds.structure,
1873
- structurizedPayload
1886
+ structurizedPayload,
1887
+ deviceData.advertisingData.fwVersion
1874
1888
  );
1875
1889
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerImbalanceThresholds, payload);
1876
1890
  },
@@ -1879,7 +1893,8 @@ const bridgeCommands = {
1879
1893
  const result = await this.readCommand(deviceData, subCommandIds.autolearnSettings);
1880
1894
  const structurized = bridgeTools.convertBytesToStructure(
1881
1895
  bridgeCommandStructures.autolearnSettings.structure,
1882
- result.data
1896
+ result.data,
1897
+ deviceData.advertisingData.fwVersion
1883
1898
  );
1884
1899
  return { ...structurized, isFactory: result.isFactory };
1885
1900
  },
@@ -1888,7 +1903,8 @@ const bridgeCommands = {
1888
1903
  const result = await this.readCommand(deviceData, subCommandIds.autolearnIdStatus);
1889
1904
  const structurized = bridgeTools.convertBytesToStructure(
1890
1905
  bridgeCommandStructures.autolearnIdStatus.structure,
1891
- result.data
1906
+ result.data,
1907
+ deviceData.advertisingData.fwVersion
1892
1908
  );
1893
1909
  return { ...structurized, isFactory: result.isFactory };
1894
1910
  },
@@ -1896,7 +1912,8 @@ const bridgeCommands = {
1896
1912
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1897
1913
  const payload = bridgeTools.convertStructureToBytes(
1898
1914
  bridgeCommandStructures.autolearnSettings.structure,
1899
- structurizedPayload
1915
+ structurizedPayload,
1916
+ deviceData.advertisingData.fwVersion
1900
1917
  );
1901
1918
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.autolearnSettings, payload);
1902
1919
  },
@@ -1904,7 +1921,8 @@ const bridgeCommands = {
1904
1921
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1905
1922
  const payload = bridgeTools.convertStructureToBytes(
1906
1923
  bridgeCommandStructures.autolearnIdStatus.structure,
1907
- structurizedPayload
1924
+ structurizedPayload,
1925
+ deviceData.advertisingData.fwVersion
1908
1926
  );
1909
1927
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.autolearnIdStatus, payload);
1910
1928
  },
@@ -1912,7 +1930,8 @@ const bridgeCommands = {
1912
1930
  const result = await this.readCommand(device, subCommandIds.autolearnUnknownSensors);
1913
1931
  const structurized = bridgeTools.convertBytesToStructure(
1914
1932
  bridgeCommandStructures.autolearnUnknownSensors.structure,
1915
- result.data
1933
+ result.data,
1934
+ device.advertisingData.fwVersion
1916
1935
  );
1917
1936
  return { ...structurized, isFactory: result.isFactory };
1918
1937
  },
@@ -1938,7 +1957,8 @@ const bridgeCommands = {
1938
1957
  const result = await this.readCommand(deviceData, subCommandIds.pressurePerAxle);
1939
1958
  const structurizedData = bridgeTools.convertBytesToStructure(
1940
1959
  bridgeCommandStructures.pressuresPerAxle.structure,
1941
- result.data
1960
+ result.data,
1961
+ deviceData.advertisingData.fwVersion
1942
1962
  );
1943
1963
  return structurizedData;
1944
1964
  },
@@ -1946,7 +1966,8 @@ const bridgeCommands = {
1946
1966
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1947
1967
  const payload = bridgeTools.convertStructureToBytes(
1948
1968
  bridgeCommandStructures.pressuresPerAxle.structure,
1949
- structurizedPayload
1969
+ structurizedPayload,
1970
+ deviceData.advertisingData.fwVersion
1950
1971
  );
1951
1972
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.pressurePerAxle, payload);
1952
1973
  },
@@ -1974,7 +1995,12 @@ const bridgeCommands = {
1974
1995
  async getVehicleLayout(deviceId) {
1975
1996
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1976
1997
  const result = await this.readCommand(deviceData, subCommandIds.vehicleLayout);
1977
- return result.data;
1998
+ const structurizedData = bridgeTools.convertBytesToStructure(
1999
+ bridgeCommandStructures.vehicleLayout.structure,
2000
+ result.data,
2001
+ deviceData.advertisingData.fwVersion
2002
+ );
2003
+ return structurizedData;
1978
2004
  },
1979
2005
  async getSensorMeasurement(deviceId, positionId) {
1980
2006
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -2051,12 +2077,12 @@ const bridgeCommands = {
2051
2077
  };
2052
2078
 
2053
2079
  const vehicleLayoutAxleTypes = {
2054
- noAxle: [0, 0],
2055
- twoTyresAxle: [128, 2],
2056
- twoTyresAxleSpare: [128, 3],
2057
- fourTyresAxle: [192, 6],
2058
- fourTyresAxleSpare: [192, 7],
2059
- spareTyreAxle: [1, 0]
2080
+ noAxle: "0000",
2081
+ twoTyresAxle: "0280",
2082
+ twoTyresAxleSpare: "0380",
2083
+ fourTyresAxle: "06C0",
2084
+ fourTyresAxleSpare: "07C0",
2085
+ spareTyreAxle: "0001"
2060
2086
  };
2061
2087
  const bridgeService = {
2062
2088
  updateFirmware,
@@ -2091,37 +2117,49 @@ async function updateFirmware(deviceId, bootloader, firmware, reportStatus) {
2091
2117
  async function setVehicleLayout(deviceId, tcVehicle) {
2092
2118
  const spareTyres = tcVehicle.tcTyres?.filter((tyre) => String(tyre.mountedOn?.positionId).endsWith("0"));
2093
2119
  let spareTyresCount = Math.min(spareTyres.length || 0, 2);
2094
- 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
+ };
2095
2139
  for (let index = 0; index < 15; index++) {
2096
- const tyresCount = tcVehicle.axles && tcVehicle.axles[index]?.tyresCount;
2097
- if (tyresCount === 2) {
2098
- let value = vehicleLayoutAxleTypes.twoTyresAxle;
2140
+ const resultKey = Object.keys(result)[index];
2141
+ const tyreCount = tcVehicle.axles[index]?.tyresCount;
2142
+ if (tyreCount === 2) {
2099
2143
  if (spareTyresCount) {
2100
- value = vehicleLayoutAxleTypes.twoTyresAxleSpare;
2144
+ result[resultKey] = vehicleLayoutAxleTypes.twoTyresAxleSpare;
2101
2145
  spareTyresCount -= 1;
2146
+ } else {
2147
+ result[resultKey] = vehicleLayoutAxleTypes.twoTyresAxle;
2102
2148
  }
2103
- layout = [...layout, ...value];
2104
2149
  continue;
2105
2150
  }
2106
- if (tyresCount === 4) {
2107
- let value = vehicleLayoutAxleTypes.fourTyresAxle;
2151
+ if (tyreCount === 4) {
2108
2152
  if (spareTyresCount) {
2109
- value = vehicleLayoutAxleTypes.fourTyresAxleSpare;
2153
+ result[resultKey] = vehicleLayoutAxleTypes.fourTyresAxleSpare;
2110
2154
  spareTyresCount -= 1;
2155
+ } else {
2156
+ result[resultKey] = vehicleLayoutAxleTypes.fourTyresAxle;
2111
2157
  }
2112
- layout = [...layout, ...value];
2113
2158
  continue;
2114
2159
  }
2115
- layout = [...layout, ...vehicleLayoutAxleTypes.noAxle];
2116
- }
2117
- 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];
2118
- if (vin.length !== 17) {
2119
- throw new Error(`Incorrect VIN length: ${vin}`);
2120
- }
2121
- if (bridgeTools.isVersionGreaterThan(deviceId, "1.0.2")) {
2122
- vin = [...vin, 0];
2160
+ result[resultKey] = vehicleLayoutAxleTypes.noAxle;
2123
2161
  }
2124
- await bridgeCommands.setVehicleLayout(deviceId, [...layout, ...vin]);
2162
+ await bridgeCommands.setVehicleLayout(deviceId, result);
2125
2163
  }
2126
2164
  async function getConfiguration(deviceId) {
2127
2165
  const customerCANSettings = await bridgeCommands.getCustomerCANSettings(deviceId);
@@ -2593,9 +2631,8 @@ async function getVehicle(deviceId) {
2593
2631
  }
2594
2632
  async function assignAxles(deviceId, tcVehicle) {
2595
2633
  const result = await bridgeCommands.getVehicleLayout(deviceId);
2596
- const data = result.map((x) => bridgeTools.decimalToHex(x));
2597
- const joinedData = Array.from({ length: data.length / 2 }, (_2, index) => data[2 * index + 1] + data[2 * index]);
2598
- 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));
2599
2636
  const axlesPressureData = (await bridgeCommands.getAxlesPressure(deviceId)).data;
2600
2637
  let axleTypesBytes;
2601
2638
  if (bridgeTools.isVersionGreaterThan(deviceId, "0.9.7")) {
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
  },
@@ -1372,12 +1376,7 @@ const bridgeCommandStructures = {
1372
1376
  size: 1,
1373
1377
  description: "VIN extension",
1374
1378
  display: "ascii",
1375
- optional: true
1376
- },
1377
- test: {
1378
- size: 3,
1379
- description: "Test",
1380
- optional: true
1379
+ version: "1.0.3"
1381
1380
  }
1382
1381
  }
1383
1382
  }
@@ -1731,16 +1730,22 @@ const bridgeCommands = {
1731
1730
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1732
1731
  await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.pressurePerAxle, data);
1733
1732
  },
1734
- async setVehicleLayout(deviceId, data) {
1733
+ async setVehicleLayout(deviceId, structurizedPayload) {
1735
1734
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1736
- 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);
1737
1741
  },
1738
1742
  async getCustomerCANSettings(deviceId) {
1739
1743
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1740
1744
  const result = await this.readCommand(deviceData, subCommandIds.customerCanSettings);
1741
1745
  const structurized = bridgeTools.convertBytesToStructure(
1742
1746
  bridgeCommandStructures.customerCanSettings.structure,
1743
- result.data
1747
+ result.data,
1748
+ deviceData.advertisingData.fwVersion
1744
1749
  );
1745
1750
  return { ...structurized, isFactory: result.isFactory };
1746
1751
  },
@@ -1749,7 +1754,8 @@ const bridgeCommands = {
1749
1754
  const result = await this.readCommand(deviceData, subCommandIds.workshopCanSettings);
1750
1755
  const structurized = bridgeTools.convertBytesToStructure(
1751
1756
  bridgeCommandStructures.workshopCanSettings.structure,
1752
- result.data
1757
+ result.data,
1758
+ deviceData.advertisingData.fwVersion
1753
1759
  );
1754
1760
  return { ...structurized, isFactory: result.isFactory };
1755
1761
  },
@@ -1758,7 +1764,8 @@ const bridgeCommands = {
1758
1764
  const result = await this.readCommand(deviceData, subCommandIds.customerPressureThresholds);
1759
1765
  const structurized = bridgeTools.convertBytesToStructure(
1760
1766
  bridgeCommandStructures.axlePressureThresholds.structure,
1761
- result.data
1767
+ result.data,
1768
+ deviceData.advertisingData.fwVersion
1762
1769
  );
1763
1770
  return { ...structurized, isFactory: result.isFactory };
1764
1771
  },
@@ -1767,7 +1774,8 @@ const bridgeCommands = {
1767
1774
  const result = await this.readCommand(deviceData, subCommandIds.customerTemperatureThresholds);
1768
1775
  const structurized = bridgeTools.convertBytesToStructure(
1769
1776
  bridgeCommandStructures.axleTemperatureThresholds.structure,
1770
- result.data
1777
+ result.data,
1778
+ deviceData.advertisingData.fwVersion
1771
1779
  );
1772
1780
  return { ...structurized, isFactory: result.isFactory };
1773
1781
  },
@@ -1776,7 +1784,8 @@ const bridgeCommands = {
1776
1784
  const result = await this.readCommand(deviceData, subCommandIds.customerImbalanceThresholds);
1777
1785
  const structurized = bridgeTools.convertBytesToStructure(
1778
1786
  bridgeCommandStructures.axleImbalanceThresholds.structure,
1779
- result.data
1787
+ result.data,
1788
+ deviceData.advertisingData.fwVersion
1780
1789
  );
1781
1790
  return { ...structurized, isFactory: result.isFactory };
1782
1791
  },
@@ -1808,7 +1817,8 @@ const bridgeCommands = {
1808
1817
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1809
1818
  const payload = bridgeTools.convertStructureToBytes(
1810
1819
  bridgeCommandStructures.customerCanSettings.structure,
1811
- structurizedPayload
1820
+ structurizedPayload,
1821
+ deviceData.advertisingData.fwVersion
1812
1822
  );
1813
1823
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerCanSettings, payload);
1814
1824
  },
@@ -1834,7 +1844,8 @@ const bridgeCommands = {
1834
1844
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1835
1845
  const payload = bridgeTools.convertStructureToBytes(
1836
1846
  bridgeCommandStructures.workshopCanSettings.structure,
1837
- structurizedPayload
1847
+ structurizedPayload,
1848
+ deviceData.advertisingData.fwVersion
1838
1849
  );
1839
1850
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.workshopCanSettings, payload);
1840
1851
  },
@@ -1842,7 +1853,8 @@ const bridgeCommands = {
1842
1853
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1843
1854
  const payload = bridgeTools.convertStructureToBytes(
1844
1855
  bridgeCommandStructures.axlePressureThresholds.structure,
1845
- structurizedPayload
1856
+ structurizedPayload,
1857
+ deviceData.advertisingData.fwVersion
1846
1858
  );
1847
1859
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerPressureThresholds, payload);
1848
1860
  },
@@ -1850,7 +1862,8 @@ const bridgeCommands = {
1850
1862
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1851
1863
  const payload = bridgeTools.convertStructureToBytes(
1852
1864
  bridgeCommandStructures.axleTemperatureThresholds.structure,
1853
- structurizedPayload
1865
+ structurizedPayload,
1866
+ deviceData.advertisingData.fwVersion
1854
1867
  );
1855
1868
  return await this.writeCommand(
1856
1869
  deviceData,
@@ -1863,7 +1876,8 @@ const bridgeCommands = {
1863
1876
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1864
1877
  const payload = bridgeTools.convertStructureToBytes(
1865
1878
  bridgeCommandStructures.axleImbalanceThresholds.structure,
1866
- structurizedPayload
1879
+ structurizedPayload,
1880
+ deviceData.advertisingData.fwVersion
1867
1881
  );
1868
1882
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerImbalanceThresholds, payload);
1869
1883
  },
@@ -1872,7 +1886,8 @@ const bridgeCommands = {
1872
1886
  const result = await this.readCommand(deviceData, subCommandIds.autolearnSettings);
1873
1887
  const structurized = bridgeTools.convertBytesToStructure(
1874
1888
  bridgeCommandStructures.autolearnSettings.structure,
1875
- result.data
1889
+ result.data,
1890
+ deviceData.advertisingData.fwVersion
1876
1891
  );
1877
1892
  return { ...structurized, isFactory: result.isFactory };
1878
1893
  },
@@ -1881,7 +1896,8 @@ const bridgeCommands = {
1881
1896
  const result = await this.readCommand(deviceData, subCommandIds.autolearnIdStatus);
1882
1897
  const structurized = bridgeTools.convertBytesToStructure(
1883
1898
  bridgeCommandStructures.autolearnIdStatus.structure,
1884
- result.data
1899
+ result.data,
1900
+ deviceData.advertisingData.fwVersion
1885
1901
  );
1886
1902
  return { ...structurized, isFactory: result.isFactory };
1887
1903
  },
@@ -1889,7 +1905,8 @@ const bridgeCommands = {
1889
1905
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1890
1906
  const payload = bridgeTools.convertStructureToBytes(
1891
1907
  bridgeCommandStructures.autolearnSettings.structure,
1892
- structurizedPayload
1908
+ structurizedPayload,
1909
+ deviceData.advertisingData.fwVersion
1893
1910
  );
1894
1911
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.autolearnSettings, payload);
1895
1912
  },
@@ -1897,7 +1914,8 @@ const bridgeCommands = {
1897
1914
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1898
1915
  const payload = bridgeTools.convertStructureToBytes(
1899
1916
  bridgeCommandStructures.autolearnIdStatus.structure,
1900
- structurizedPayload
1917
+ structurizedPayload,
1918
+ deviceData.advertisingData.fwVersion
1901
1919
  );
1902
1920
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.autolearnIdStatus, payload);
1903
1921
  },
@@ -1905,7 +1923,8 @@ const bridgeCommands = {
1905
1923
  const result = await this.readCommand(device, subCommandIds.autolearnUnknownSensors);
1906
1924
  const structurized = bridgeTools.convertBytesToStructure(
1907
1925
  bridgeCommandStructures.autolearnUnknownSensors.structure,
1908
- result.data
1926
+ result.data,
1927
+ device.advertisingData.fwVersion
1909
1928
  );
1910
1929
  return { ...structurized, isFactory: result.isFactory };
1911
1930
  },
@@ -1931,7 +1950,8 @@ const bridgeCommands = {
1931
1950
  const result = await this.readCommand(deviceData, subCommandIds.pressurePerAxle);
1932
1951
  const structurizedData = bridgeTools.convertBytesToStructure(
1933
1952
  bridgeCommandStructures.pressuresPerAxle.structure,
1934
- result.data
1953
+ result.data,
1954
+ deviceData.advertisingData.fwVersion
1935
1955
  );
1936
1956
  return structurizedData;
1937
1957
  },
@@ -1939,7 +1959,8 @@ const bridgeCommands = {
1939
1959
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1940
1960
  const payload = bridgeTools.convertStructureToBytes(
1941
1961
  bridgeCommandStructures.pressuresPerAxle.structure,
1942
- structurizedPayload
1962
+ structurizedPayload,
1963
+ deviceData.advertisingData.fwVersion
1943
1964
  );
1944
1965
  return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.pressurePerAxle, payload);
1945
1966
  },
@@ -1967,7 +1988,12 @@ const bridgeCommands = {
1967
1988
  async getVehicleLayout(deviceId) {
1968
1989
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1969
1990
  const result = await this.readCommand(deviceData, subCommandIds.vehicleLayout);
1970
- return result.data;
1991
+ const structurizedData = bridgeTools.convertBytesToStructure(
1992
+ bridgeCommandStructures.vehicleLayout.structure,
1993
+ result.data,
1994
+ deviceData.advertisingData.fwVersion
1995
+ );
1996
+ return structurizedData;
1971
1997
  },
1972
1998
  async getSensorMeasurement(deviceId, positionId) {
1973
1999
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -2044,12 +2070,12 @@ const bridgeCommands = {
2044
2070
  };
2045
2071
 
2046
2072
  const vehicleLayoutAxleTypes = {
2047
- noAxle: [0, 0],
2048
- twoTyresAxle: [128, 2],
2049
- twoTyresAxleSpare: [128, 3],
2050
- fourTyresAxle: [192, 6],
2051
- fourTyresAxleSpare: [192, 7],
2052
- spareTyreAxle: [1, 0]
2073
+ noAxle: "0000",
2074
+ twoTyresAxle: "0280",
2075
+ twoTyresAxleSpare: "0380",
2076
+ fourTyresAxle: "06C0",
2077
+ fourTyresAxleSpare: "07C0",
2078
+ spareTyreAxle: "0001"
2053
2079
  };
2054
2080
  const bridgeService = {
2055
2081
  updateFirmware,
@@ -2084,37 +2110,49 @@ async function updateFirmware(deviceId, bootloader, firmware, reportStatus) {
2084
2110
  async function setVehicleLayout(deviceId, tcVehicle) {
2085
2111
  const spareTyres = tcVehicle.tcTyres?.filter((tyre) => String(tyre.mountedOn?.positionId).endsWith("0"));
2086
2112
  let spareTyresCount = Math.min(spareTyres.length || 0, 2);
2087
- 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
+ };
2088
2132
  for (let index = 0; index < 15; index++) {
2089
- const tyresCount = tcVehicle.axles && tcVehicle.axles[index]?.tyresCount;
2090
- if (tyresCount === 2) {
2091
- let value = vehicleLayoutAxleTypes.twoTyresAxle;
2133
+ const resultKey = Object.keys(result)[index];
2134
+ const tyreCount = tcVehicle.axles[index]?.tyresCount;
2135
+ if (tyreCount === 2) {
2092
2136
  if (spareTyresCount) {
2093
- value = vehicleLayoutAxleTypes.twoTyresAxleSpare;
2137
+ result[resultKey] = vehicleLayoutAxleTypes.twoTyresAxleSpare;
2094
2138
  spareTyresCount -= 1;
2139
+ } else {
2140
+ result[resultKey] = vehicleLayoutAxleTypes.twoTyresAxle;
2095
2141
  }
2096
- layout = [...layout, ...value];
2097
2142
  continue;
2098
2143
  }
2099
- if (tyresCount === 4) {
2100
- let value = vehicleLayoutAxleTypes.fourTyresAxle;
2144
+ if (tyreCount === 4) {
2101
2145
  if (spareTyresCount) {
2102
- value = vehicleLayoutAxleTypes.fourTyresAxleSpare;
2146
+ result[resultKey] = vehicleLayoutAxleTypes.fourTyresAxleSpare;
2103
2147
  spareTyresCount -= 1;
2148
+ } else {
2149
+ result[resultKey] = vehicleLayoutAxleTypes.fourTyresAxle;
2104
2150
  }
2105
- layout = [...layout, ...value];
2106
2151
  continue;
2107
2152
  }
2108
- layout = [...layout, ...vehicleLayoutAxleTypes.noAxle];
2109
- }
2110
- 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];
2111
- if (vin.length !== 17) {
2112
- throw new Error(`Incorrect VIN length: ${vin}`);
2113
- }
2114
- if (bridgeTools.isVersionGreaterThan(deviceId, "1.0.2")) {
2115
- vin = [...vin, 0];
2153
+ result[resultKey] = vehicleLayoutAxleTypes.noAxle;
2116
2154
  }
2117
- await bridgeCommands.setVehicleLayout(deviceId, [...layout, ...vin]);
2155
+ await bridgeCommands.setVehicleLayout(deviceId, result);
2118
2156
  }
2119
2157
  async function getConfiguration(deviceId) {
2120
2158
  const customerCANSettings = await bridgeCommands.getCustomerCANSettings(deviceId);
@@ -2586,9 +2624,8 @@ async function getVehicle(deviceId) {
2586
2624
  }
2587
2625
  async function assignAxles(deviceId, tcVehicle) {
2588
2626
  const result = await bridgeCommands.getVehicleLayout(deviceId);
2589
- const data = result.map((x) => bridgeTools.decimalToHex(x));
2590
- const joinedData = Array.from({ length: data.length / 2 }, (_2, index) => data[2 * index + 1] + data[2 * index]);
2591
- 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));
2592
2629
  const axlesPressureData = (await bridgeCommands.getAxlesPressure(deviceId)).data;
2593
2630
  let axleTypesBytes;
2594
2631
  if (bridgeTools.isVersionGreaterThan(deviceId, "0.9.7")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tirecheck-device-sdk",
3
- "version": "0.1.97",
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",