tirecheck-device-sdk 0.2.2 → 0.2.22

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
@@ -104,6 +104,10 @@ function stringToArrayBuffer(string) {
104
104
  }
105
105
  return array.buffer;
106
106
  }
107
+ function decimalToHex(decimal, padStart = 2) {
108
+ const hex = decimal.toString(16);
109
+ return hex.padStart(padStart, "0");
110
+ }
107
111
  const toolsSvc = {
108
112
  delay,
109
113
  setIntervalImmediate,
@@ -1524,26 +1528,26 @@ const bridgeSecurity = {
1524
1528
  };
1525
1529
 
1526
1530
  const bridgeMeta = deviceMeta.bridge;
1527
- const devicePromiseQueue = {};
1528
- const deviceCurrentResolve = {};
1529
- const deviceCurrentReject = {};
1530
- const deviceResponseIdentifier = {};
1531
+ const devicePromiseQueue$1 = {};
1532
+ const deviceCurrentResolve$1 = {};
1533
+ const deviceCurrentReject$1 = {};
1534
+ const deviceResponseIdentifier$1 = {};
1531
1535
  const promiseQueue = {
1532
1536
  clearQueue(deviceId, message) {
1533
- if (deviceCurrentReject[deviceId]) {
1534
- deviceCurrentReject[deviceId](new Error(message ?? "Stopped sending commands"));
1537
+ if (deviceCurrentReject$1[deviceId]) {
1538
+ deviceCurrentReject$1[deviceId](new Error(message ?? "Stopped sending commands"));
1535
1539
  }
1536
- devicePromiseQueue[deviceId] = Promise.resolve();
1537
- deviceResponseIdentifier[deviceId] = [];
1540
+ devicePromiseQueue$1[deviceId] = Promise.resolve();
1541
+ deviceResponseIdentifier$1[deviceId] = [];
1538
1542
  },
1539
1543
  async enqueue(device, payload) {
1540
- if (devicePromiseQueue[device.id] === void 0) devicePromiseQueue[device.id] = Promise.resolve();
1541
- devicePromiseQueue[device.id] = devicePromiseQueue[device.id].then(() => {
1544
+ if (devicePromiseQueue$1[device.id] === void 0) devicePromiseQueue$1[device.id] = Promise.resolve();
1545
+ devicePromiseQueue$1[device.id] = devicePromiseQueue$1[device.id].then(() => {
1542
1546
  const promise = new Promise((resolve, reject) => {
1543
- deviceCurrentResolve[device.id] = resolve;
1544
- deviceCurrentReject[device.id] = reject;
1545
- const isKeepAlive = payload[3] === commandIds.keepAlive;
1546
- deviceResponseIdentifier[device.id] = [isKeepAlive ? 126 : 0, payload[4]];
1547
+ deviceCurrentResolve$1[device.id] = resolve;
1548
+ deviceCurrentReject$1[device.id] = reject;
1549
+ const isKeepAlive = payload[3] === commandIds$1.keepAlive;
1550
+ deviceResponseIdentifier$1[device.id] = [isKeepAlive ? 126 : 0, payload[4]];
1547
1551
  const signedData = bridgeSecurity.getSignedCommand(device, payload);
1548
1552
  if (!toolsSvc.canCommunicateWith(device.id)) return reject(new Error("Bridge not connected"));
1549
1553
  if (signedData.length > 110) {
@@ -1569,21 +1573,21 @@ const promiseQueue = {
1569
1573
  );
1570
1574
  }
1571
1575
  });
1572
- return withTimeout(promise, 5e3, `Command timed out ${deviceResponseIdentifier[device.id]}, ${device.id}`);
1576
+ return withTimeout(promise, 5e3, `Command timed out ${deviceResponseIdentifier$1[device.id]}, ${device.id}`);
1573
1577
  });
1574
- return devicePromiseQueue[device.id];
1578
+ return devicePromiseQueue$1[device.id];
1575
1579
  },
1576
1580
  async processMessage(deviceId, payload) {
1577
1581
  const numberArray = Array.from(new Uint8Array(payload));
1578
1582
  if (numberArray[3] === 127) {
1579
1583
  console.error(numberArray);
1580
- return deviceCurrentReject[deviceId](new Error(`Command not succesful: ${numberArray[4]}`));
1584
+ return deviceCurrentReject$1[deviceId](new Error(`Command not succesful: ${numberArray[4]}`));
1581
1585
  }
1582
1586
  if ([226, 81].includes(numberArray[3]) && numberArray[4] && toolsSvc.canCommunicateWith(deviceId)) {
1583
1587
  store.bridgeRebootRequired[deviceId] = true;
1584
1588
  }
1585
- if ((!deviceResponseIdentifier[deviceId][0] || numberArray[3] === deviceResponseIdentifier[deviceId][0]) && (!deviceResponseIdentifier[deviceId][1] || numberArray[4] === deviceResponseIdentifier[deviceId][1])) {
1586
- return deviceCurrentResolve[deviceId](numberArray);
1589
+ if ((!deviceResponseIdentifier$1[deviceId][0] || numberArray[3] === deviceResponseIdentifier$1[deviceId][0]) && (!deviceResponseIdentifier$1[deviceId][1] || numberArray[4] === deviceResponseIdentifier$1[deviceId][1])) {
1590
+ return deviceCurrentResolve$1[deviceId](numberArray);
1587
1591
  }
1588
1592
  console.warn("message from the device not belonging to the pending promise: ", numberArray);
1589
1593
  }
@@ -1600,7 +1604,7 @@ const messageTypeIds = {
1600
1604
  command: 0,
1601
1605
  response: 1
1602
1606
  };
1603
- const commandIds = {
1607
+ const commandIds$1 = {
1604
1608
  readData: 34,
1605
1609
  writeData: 46,
1606
1610
  keepAlive: 62,
@@ -1649,7 +1653,7 @@ const subCommandIds = {
1649
1653
  autolearnIdStatus: 176,
1650
1654
  autolearnUnknownSensors: 192
1651
1655
  };
1652
- ___default.invert(commandIds);
1656
+ ___default.invert(commandIds$1);
1653
1657
  ___default.invert(subCommandIds);
1654
1658
  const keepAliveTimer = {};
1655
1659
  const bridgeCommands = {
@@ -1660,7 +1664,7 @@ const bridgeCommands = {
1660
1664
  },
1661
1665
  async setAxlesPressure(deviceId, data) {
1662
1666
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1663
- await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.pressurePerAxle, data);
1667
+ await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.pressurePerAxle, data);
1664
1668
  },
1665
1669
  async setVehicleLayout(deviceId, structurizedPayload) {
1666
1670
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1669,7 +1673,7 @@ const bridgeCommands = {
1669
1673
  structurizedPayload,
1670
1674
  deviceData.advertisingData.fwVersion
1671
1675
  );
1672
- await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.vehicleLayout, payload);
1676
+ await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.vehicleLayout, payload);
1673
1677
  },
1674
1678
  async getCustomerCANSettings(deviceId) {
1675
1679
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1722,18 +1726,18 @@ const bridgeCommands = {
1722
1726
  return { ...structurized, isFactory: result.isFactory };
1723
1727
  },
1724
1728
  async sendKeepAliveCommand(device) {
1725
- return this.promisify(device, [...this.getCommandHeader(device), 2, commandIds.keepAlive, 0]);
1729
+ return this.promisify(device, [...this.getCommandHeader(device), 2, commandIds$1.keepAlive, 0]);
1726
1730
  },
1727
1731
  async sendOtaRequest(deviceId) {
1728
1732
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1729
- const command = [commandIds.otaRequest, 0];
1733
+ const command = [commandIds$1.otaRequest, 0];
1730
1734
  const result = await this.promisify(deviceData, [...this.getCommandHeader(deviceData), command.length, ...command]);
1731
1735
  return result;
1732
1736
  },
1733
1737
  async sendPinCommand(deviceId) {
1734
1738
  const deviceData = await bridgeTools.getBridgeFromStore(deviceId);
1735
1739
  const pin = await bridgeSecurity.getPin(deviceId);
1736
- return this.promisify(deviceData, [...this.getCommandHeader(deviceData), 18, commandIds.pin, 0, ...pin]);
1740
+ return this.promisify(deviceData, [...this.getCommandHeader(deviceData), 18, commandIds$1.pin, 0, ...pin]);
1737
1741
  },
1738
1742
  async setBridgeToRestart(deviceId) {
1739
1743
  if (store.bridgeRebootRequired[deviceId]) return;
@@ -1742,7 +1746,7 @@ const bridgeCommands = {
1742
1746
  await this.promisify(deviceData, [
1743
1747
  ...this.getCommandHeader(deviceData),
1744
1748
  2,
1745
- useNewCommand ? commandIds.ecuReset : commandIds.reboot,
1749
+ useNewCommand ? commandIds$1.ecuReset : commandIds$1.reboot,
1746
1750
  useNewCommand ? subCommandIds.ecuResetSubCommand : subCommandIds.rebootSubCommand
1747
1751
  ]);
1748
1752
  },
@@ -1753,7 +1757,7 @@ const bridgeCommands = {
1753
1757
  structurizedPayload,
1754
1758
  deviceData.advertisingData.fwVersion
1755
1759
  );
1756
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerCanSettings, payload);
1760
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.customerCanSettings, payload);
1757
1761
  },
1758
1762
  async setWorkshopCANSettings(deviceId, structurizedPayload) {
1759
1763
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1762,7 +1766,7 @@ const bridgeCommands = {
1762
1766
  structurizedPayload,
1763
1767
  deviceData.advertisingData.fwVersion
1764
1768
  );
1765
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.workshopCanSettings, payload);
1769
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.workshopCanSettings, payload);
1766
1770
  },
1767
1771
  async setCustomerPressureThresholds(deviceId, structurizedPayload) {
1768
1772
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1771,7 +1775,7 @@ const bridgeCommands = {
1771
1775
  structurizedPayload,
1772
1776
  deviceData.advertisingData.fwVersion
1773
1777
  );
1774
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerPressureThresholds, payload);
1778
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.customerPressureThresholds, payload);
1775
1779
  },
1776
1780
  async setCustomerTemperatureThresholds(deviceId, structurizedPayload) {
1777
1781
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1782,7 +1786,7 @@ const bridgeCommands = {
1782
1786
  );
1783
1787
  return await this.writeCommand(
1784
1788
  deviceData,
1785
- commandIds.writeData,
1789
+ commandIds$1.writeData,
1786
1790
  subCommandIds.customerTemperatureThresholds,
1787
1791
  payload
1788
1792
  );
@@ -1794,7 +1798,7 @@ const bridgeCommands = {
1794
1798
  structurizedPayload,
1795
1799
  deviceData.advertisingData.fwVersion
1796
1800
  );
1797
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerImbalanceThresholds, payload);
1801
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.customerImbalanceThresholds, payload);
1798
1802
  },
1799
1803
  async getAutolearnSettings(deviceId) {
1800
1804
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1823,7 +1827,7 @@ const bridgeCommands = {
1823
1827
  structurizedPayload,
1824
1828
  deviceData.advertisingData.fwVersion
1825
1829
  );
1826
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.autolearnSettings, payload);
1830
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.autolearnSettings, payload);
1827
1831
  },
1828
1832
  async setAutolearnIdStatus(deviceId, structurizedPayload) {
1829
1833
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1832,7 +1836,7 @@ const bridgeCommands = {
1832
1836
  structurizedPayload,
1833
1837
  deviceData.advertisingData.fwVersion
1834
1838
  );
1835
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.autolearnIdStatus, payload);
1839
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.autolearnIdStatus, payload);
1836
1840
  },
1837
1841
  async getAutolearnUnknownSensors(device) {
1838
1842
  const result = await this.readCommand(device, subCommandIds.autolearnUnknownSensors);
@@ -1853,7 +1857,7 @@ const bridgeCommands = {
1853
1857
  // move logic to bridge svc
1854
1858
  async setAxleInfo(deviceId, axleIndex, data) {
1855
1859
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1856
- await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.idsPerWheel(axleIndex), data);
1860
+ await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.idsPerWheel(axleIndex), data);
1857
1861
  },
1858
1862
  async getAxlesPressure(deviceId) {
1859
1863
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1877,7 +1881,7 @@ const bridgeCommands = {
1877
1881
  structurizedPayload,
1878
1882
  deviceData.advertisingData.fwVersion
1879
1883
  );
1880
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.pressurePerAxle, payload);
1884
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.pressurePerAxle, payload);
1881
1885
  },
1882
1886
  // // async setPressureThresholds(device: BleBridge, rules: any) {
1883
1887
  // // // https://tirecheck.atlassian.net/wiki/spaces/HWPRG/pages/6547767302/Technical+Design+Document+BLE+CAN+Bridge+Krone#Example.1
@@ -1920,7 +1924,7 @@ const bridgeCommands = {
1920
1924
  }
1921
1925
  const result = await this.writeCommand(
1922
1926
  deviceData,
1923
- commandIds.sensorMeasurement,
1927
+ commandIds$1.sensorMeasurement,
1924
1928
  subCommandIds.sensorMeasurementPerWheel(axlePosition, tyrePosition, isTwinTyre, isSpare),
1925
1929
  []
1926
1930
  );
@@ -1931,7 +1935,7 @@ const bridgeCommands = {
1931
1935
  const result = await this.promisify(device, [
1932
1936
  ...this.getCommandHeader(device),
1933
1937
  commandLength,
1934
- commandIds.readData,
1938
+ commandIds$1.readData,
1935
1939
  subCommandId
1936
1940
  ]);
1937
1941
  const data = result.slice(19, result.length - 8);
@@ -2896,6 +2900,344 @@ const pressureStick = {
2896
2900
  onPressure: pressureStickService.onPressure
2897
2901
  };
2898
2902
 
2903
+ const devicePromiseQueue = {};
2904
+ const deviceCurrentResolve = {};
2905
+ const deviceCurrentReject = {};
2906
+ const deviceResponseIdentifier = {};
2907
+ const deviceCurrentPartialMessage = {};
2908
+ const torqueWrenchPromiseQueue = {
2909
+ clearQueue(deviceId, message) {
2910
+ if (deviceCurrentReject[deviceId]) {
2911
+ deviceCurrentReject[deviceId](new Error(message ?? "Stopped sending commands"));
2912
+ }
2913
+ devicePromiseQueue[deviceId] = Promise.resolve();
2914
+ deviceResponseIdentifier[deviceId] = void 0;
2915
+ },
2916
+ async enqueue(deviceId, communication, payload, responseIdentifier, mtu = 20) {
2917
+ if (devicePromiseQueue[deviceId] === void 0) devicePromiseQueue[deviceId] = Promise.resolve();
2918
+ devicePromiseQueue[deviceId] = devicePromiseQueue[deviceId].then(() => {
2919
+ const promise = new Promise((resolve, reject) => {
2920
+ deviceCurrentResolve[deviceId] = resolve;
2921
+ deviceCurrentReject[deviceId] = reject;
2922
+ deviceResponseIdentifier[deviceId] = responseIdentifier;
2923
+ deviceCurrentPartialMessage[deviceId] = [];
2924
+ if (!toolsSvc.canCommunicateWith(deviceId)) return reject(new Error("Torque wrench not connected"));
2925
+ const chunks = [];
2926
+ for (let i = 0; i < payload.length; i += mtu) {
2927
+ chunks.push(payload.slice(i, i + mtu));
2928
+ }
2929
+ for (const chunk of chunks) {
2930
+ const convertedChunk = new Uint8Array(chunk).buffer;
2931
+ bluetooth.write(deviceId, communication.serviceId, communication.characteristicId, convertedChunk);
2932
+ }
2933
+ });
2934
+ return withTimeout(promise, 5e3, `Command timed out ${deviceResponseIdentifier[deviceId]}, ${deviceId}`);
2935
+ });
2936
+ return devicePromiseQueue[deviceId];
2937
+ },
2938
+ async processMessage(deviceId, payload, getIdentifier, isComplete, isError) {
2939
+ const numberArray = Array.from(new Uint8Array(payload));
2940
+ if (!deviceCurrentPartialMessage[deviceId]) deviceCurrentPartialMessage[deviceId] = [];
2941
+ deviceCurrentPartialMessage[deviceId] = ___default.concat(deviceCurrentPartialMessage[deviceId], numberArray);
2942
+ if (!isComplete(deviceCurrentPartialMessage[deviceId])) {
2943
+ return;
2944
+ }
2945
+ if (isError(deviceCurrentPartialMessage[deviceId])) {
2946
+ return deviceCurrentReject[deviceId](
2947
+ new Error("Error response", { cause: deviceCurrentPartialMessage[deviceId] })
2948
+ );
2949
+ }
2950
+ const identifier = getIdentifier(deviceCurrentPartialMessage[deviceId]);
2951
+ if (deviceResponseIdentifier[deviceId] === identifier) {
2952
+ deviceCurrentResolve[deviceId](deviceCurrentPartialMessage[deviceId]);
2953
+ }
2954
+ }
2955
+ };
2956
+
2957
+ const commandStart = "$9";
2958
+ const commandEnd = "*";
2959
+ const commandIds = {
2960
+ error: "004",
2961
+ acknowledge: "005",
2962
+ commTest: "100",
2963
+ getProperties: "120",
2964
+ startJob: "204",
2965
+ stopJob: "206",
2966
+ getNumberOfReadings: "224",
2967
+ getReading: "200",
2968
+ // Can only be called once for each reading.
2969
+ getReadingAgain: "202",
2970
+ getBattery: "150",
2971
+ getTime: "209",
2972
+ setTime: "208"
2973
+ };
2974
+ const errors = {
2975
+ "01": "Bad string",
2976
+ "02": "Bad checksum",
2977
+ "03": "Unknown command",
2978
+ "04": "No device present for command to act on",
2979
+ "05": "Invalid sample speed",
2980
+ "06": "Torque module offset difference bigger than 25%",
2981
+ "07": "Torque module gain outside 0.9 to 1.1",
2982
+ "08": "No RF properties",
2983
+ "09": "No reply from RF",
2984
+ "0A": "RF device already paired on this device",
2985
+ "0C": "Invalid frequency",
2986
+ "0D": "Invalid LED selection",
2987
+ "0F": "Transducer preloaded",
2988
+ "10": "No more readings",
2989
+ "11": "Job already loaded",
2990
+ "12": "No trace stored",
2991
+ "13": "Wrong transducers selected for Multi Start Mode",
2992
+ "14": "No short trace stored",
2993
+ "15": "Job finished",
2994
+ "16": "Missing time and date",
2995
+ "17": "Bad units for wrench type",
2996
+ "18": "Battery low"
2997
+ };
2998
+ const twMeta = deviceMeta.torqueWrench;
2999
+ const torqueWrenchCommands = {
3000
+ async sendCommand(deviceId, command, params) {
3001
+ const commandId = commandIds[command];
3002
+ let message = `${commandStart}${commandId}`;
3003
+ if (params?.length) {
3004
+ message += `,${params.join(",")}`;
3005
+ }
3006
+ message += commandEnd;
3007
+ const crc = getChecksum(message);
3008
+ message += `${crc}\r`;
3009
+ const array = new Uint8Array(message.length);
3010
+ for (let i = 0, l = message.length; i < l; i++) {
3011
+ array[i] = message.charCodeAt(i);
3012
+ }
3013
+ const decimalArray = Array.from(array);
3014
+ let result;
3015
+ try {
3016
+ result = await torqueWrenchPromiseQueue.enqueue(deviceId, twMeta.communication, decimalArray, commandIds[command]);
3017
+ } catch (error) {
3018
+ const formattedError = formatError(error);
3019
+ throw new Error(formattedError);
3020
+ }
3021
+ return result.map((num) => String.fromCharCode(num)).join("");
3022
+ },
3023
+ processMessage(deviceId, payload) {
3024
+ torqueWrenchPromiseQueue.processMessage(deviceId, payload, getIdentifier, isComplete, isError);
3025
+ }
3026
+ };
3027
+ function isComplete(message) {
3028
+ const completeReading = message[0] === 123 && message.at(-1) === 13;
3029
+ const completeCommand = message[0] === 36 && message.at(-1) === 13;
3030
+ return completeReading || completeCommand;
3031
+ }
3032
+ function isError(message) {
3033
+ return message[4] === 52;
3034
+ }
3035
+ function getIdentifier(message) {
3036
+ if (message[0] === 123) return "200";
3037
+ return message.slice(6, 9).map((num) => String.fromCharCode(num)).join("");
3038
+ }
3039
+ function getChecksum(message) {
3040
+ let checksum = 0;
3041
+ for (const ch of message) {
3042
+ checksum ^= ch.charCodeAt(0);
3043
+ }
3044
+ return decimalToHex(checksum).toUpperCase();
3045
+ }
3046
+ function formatError(error) {
3047
+ if (!error.cause) throw new Error(error);
3048
+ const message = error.cause.slice(6, 8);
3049
+ const errorId = message.map((num) => String.fromCharCode(num)).join("");
3050
+ return errors[errorId] || "Unknown error";
3051
+ }
3052
+
3053
+ let jobInterval = null;
3054
+ const torqueWrenchService = {
3055
+ onReading(callback) {
3056
+ simulatorSvc.registerEvent("tw:reading", callback);
3057
+ },
3058
+ async getProperties(deviceId) {
3059
+ const result = {
3060
+ serialNumber: "",
3061
+ span: 0,
3062
+ calibrationDate: "",
3063
+ ppr: 0,
3064
+ units: "Nm",
3065
+ threshold: 10
3066
+ };
3067
+ const message = await torqueWrenchCommands.sendCommand(deviceId, "getProperties");
3068
+ const params = getMessageParams(message);
3069
+ if (params[4] === "3") result.units = "Nm";
3070
+ else if (params[4] === "7") result.units = "lb-ft";
3071
+ result.serialNumber = params[0];
3072
+ result.span = Number.parseInt(params[1]);
3073
+ if (result.units === "lb-ft") result.span = Math.floor(result.span * 0.738);
3074
+ result.calibrationDate = params[2];
3075
+ result.ppr = Number.parseInt(params[3]);
3076
+ return result;
3077
+ },
3078
+ async startJob(deviceId, params) {
3079
+ await this.stopJob(deviceId);
3080
+ const { units, span, ppr, threshold } = store.torqueWrenchProperties[deviceId];
3081
+ console.log("\u{1F680} ~ startJob ~ units:", units);
3082
+ const { torqueMin, torqueMax, angleMin, angleMax, direction, jobTimeout } = params;
3083
+ const msgParams = {
3084
+ id: "01",
3085
+ nuts: decimalToHex(params.nuts),
3086
+ mode: units === "lb-ft" ? "20" : "1",
3087
+ // Peak measurement mode
3088
+ cycle: "7",
3089
+ // 10 seconds cycle (probably for measurements - not sure what it does exactly, not specified in docs)
3090
+ control: torqueMin != null || torqueMax != null ? "0" : "1",
3091
+ direction: direction === "counter-clockwise" ? "1" : "0",
3092
+ minTorqueThreshold: torqueToAdcParam(threshold, span, units),
3093
+ torqueMin: torqueToAdcParam(torqueMin ?? 0, span, units),
3094
+ torqueMax: torqueToAdcParam(torqueMax ?? -1, span, units),
3095
+ clickThreshold: torqueToAdcParam(threshold, span, units),
3096
+ // Probably not used in our case (for this specified mode).
3097
+ angleMin: angleToPulsesParam(angleMin ?? 0, ppr),
3098
+ angleMax: angleToPulsesParam(angleMax ?? -1, ppr),
3099
+ frequency: "0542"
3100
+ // No idea
3101
+ };
3102
+ const paramsString = Object.values(msgParams);
3103
+ await torqueWrenchCommands.sendCommand(deviceId, "startJob", paramsString);
3104
+ jobInterval = setInterval(async () => {
3105
+ const numberOfReading = await this.getNumberOfReadings(deviceId);
3106
+ console.log("\u{1F680} ~ jobInterval=setInterval ~ numberOfReading:", numberOfReading);
3107
+ if (numberOfReading.count > 0) this.getReading(deviceId);
3108
+ }, 1e3);
3109
+ if (jobTimeout) {
3110
+ await new Promise(
3111
+ (resolve) => setTimeout(() => {
3112
+ console.log("job terminated");
3113
+ clearInterval(jobInterval);
3114
+ this.stopJob(deviceId);
3115
+ resolve("");
3116
+ }, jobTimeout * 1e3)
3117
+ );
3118
+ }
3119
+ },
3120
+ async stopJob(deviceId) {
3121
+ return torqueWrenchCommands.sendCommand(deviceId, "stopJob");
3122
+ },
3123
+ async getNumberOfReadings(deviceId) {
3124
+ const message = await torqueWrenchCommands.sendCommand(deviceId, "getNumberOfReadings");
3125
+ const params = getMessageParams(message);
3126
+ return { count: Number(params[0]), jobId: params[1] };
3127
+ },
3128
+ async getReading(deviceId) {
3129
+ const reading = await torqueWrenchCommands.sendCommand(deviceId, "getReading");
3130
+ const properties = {
3131
+ jobId: reading.slice(2, 4),
3132
+ nut: reading.slice(4, 6),
3133
+ torqueAdc: reading.slice(6, 10),
3134
+ anglePulses: reading.slice(10, 14),
3135
+ duration: reading.slice(14, 18)
3136
+ };
3137
+ const torque = adcToTorque(
3138
+ properties.torqueAdc,
3139
+ store.torqueWrenchProperties[deviceId].span,
3140
+ store.torqueWrenchProperties[deviceId].units
3141
+ );
3142
+ const angle = pulsesToAngle(properties.anglePulses, store.torqueWrenchProperties[deviceId].ppr);
3143
+ const formattedReading = {
3144
+ jobId: Number.parseInt(properties.jobId, 16),
3145
+ nut: Number.parseInt(properties.nut, 16),
3146
+ torque,
3147
+ angle,
3148
+ duration: Number.parseInt(properties.duration, 16) / 1e3
3149
+ };
3150
+ simulatorSvc.triggerEvent("tw:reading", deviceId, formattedReading);
3151
+ },
3152
+ // getReadingAgain(deviceId: string) {
3153
+ // return torqueWrenchCommands.sendCommand(deviceId, 'getNumberOfReadings')
3154
+ // },
3155
+ async getBattery(deviceId) {
3156
+ const message = await torqueWrenchCommands.sendCommand(deviceId, "getBattery");
3157
+ const params = getMessageParams(message);
3158
+ return Number(params[0]);
3159
+ },
3160
+ async getTime(deviceId) {
3161
+ const message = await torqueWrenchCommands.sendCommand(deviceId, "getTime");
3162
+ const match = message.match(/209,([^*]*)\*/);
3163
+ console.log("\u{1F680} ~ getTime ~ match:", match);
3164
+ if (!match[1]) throw new Error("Invalid time response");
3165
+ const hh = match[1].substring(0, 2);
3166
+ const mm = match[1].substring(2, 4);
3167
+ const ss = match[1].substring(4, 6);
3168
+ const dd = match[1].substring(6, 8);
3169
+ const MM = match[1].substring(8, 10);
3170
+ const yy = match[1].substring(10, 12);
3171
+ const fullYear = `20${yy}`;
3172
+ return /* @__PURE__ */ new Date(`${fullYear}-${MM}-${dd}T${hh}:${mm}:${ss}Z`);
3173
+ },
3174
+ setTime(deviceId, date) {
3175
+ const hours = String(date.getHours()).padStart(2, "0");
3176
+ const minutes = String(date.getMinutes()).padStart(2, "0");
3177
+ const seconds = String(date.getSeconds()).padStart(2, "0");
3178
+ const day = String(date.getDate()).padStart(2, "0");
3179
+ const month = String(date.getMonth() + 1).padStart(2, "0");
3180
+ const year = String(date.getFullYear()).slice(-2);
3181
+ const params = [hours, minutes, seconds, day, month, year];
3182
+ return torqueWrenchCommands.sendCommand(deviceId, "setTime", params);
3183
+ }
3184
+ };
3185
+ function torqueToAdcParam(value, span, deviceUnits) {
3186
+ if (value < 0) return "FFFF";
3187
+ if (deviceUnits !== "Nm") value = value * 0.738;
3188
+ const adc = Math.round(value / span * 16384);
3189
+ return decimalToHex(adc, 4).toUpperCase();
3190
+ }
3191
+ function angleToPulsesParam(value, ppr) {
3192
+ if (value < 0) return "FFFF";
3193
+ const pulses = Math.round(value * ppr / 90);
3194
+ return decimalToHex(pulses, 4).toUpperCase();
3195
+ }
3196
+ function getMessageParams(message) {
3197
+ return message.match(/^\$[^,]+,[^,]+,(.*)\*/)?.[1].split(",") || [];
3198
+ }
3199
+ function adcToTorque(value, span, units) {
3200
+ const torque = Number.parseInt(value, 16) * span / 16384;
3201
+ if (units !== "Nm") return torque / 0.738;
3202
+ return torque;
3203
+ }
3204
+ function pulsesToAngle(value, ppr) {
3205
+ return Number.parseInt(value, 16) * 90 / ppr;
3206
+ }
3207
+
3208
+ const torqueWrench = {
3209
+ async connect(deviceId) {
3210
+ const twMeta = deviceMeta.torqueWrench;
3211
+ await bluetooth.connect(deviceId, this.disconnect);
3212
+ await ble.startNotification(
3213
+ deviceId,
3214
+ twMeta.communication.serviceId,
3215
+ twMeta.communication.characteristicId,
3216
+ (notification) => {
3217
+ torqueWrenchCommands.processMessage(deviceId, notification);
3218
+ },
3219
+ (error) => console.warn("ble.startNotification error", error)
3220
+ );
3221
+ const properties = await torqueWrenchService.getProperties(deviceId);
3222
+ store.torqueWrenchProperties[deviceId] = properties;
3223
+ store.setState(deviceId, "paired");
3224
+ },
3225
+ async disconnect(deviceId, reason) {
3226
+ store.setState(deviceId, "disconnecting");
3227
+ await bluetooth.disconnect(deviceId);
3228
+ store.setState(deviceId, void 0, reason ?? "manualDisconnection");
3229
+ },
3230
+ getProperties: torqueWrenchService.getProperties,
3231
+ setTime: torqueWrenchService.setTime,
3232
+ startJob: torqueWrenchService.startJob,
3233
+ stopJob: torqueWrenchService.stopJob,
3234
+ getNumberOfReadings: torqueWrenchService.getNumberOfReadings,
3235
+ getReading: torqueWrenchService.getReading,
3236
+ getBattery: torqueWrenchService.getBattery,
3237
+ getTime: torqueWrenchService.getTime,
3238
+ onReading: torqueWrenchService.onReading
3239
+ };
3240
+
2899
3241
  const bridgeSimulator = {
2900
3242
  isRebootRequired(deviceId) {
2901
3243
  return store.bridgeRebootRequired[deviceId];
@@ -3496,10 +3838,14 @@ function createTirecheckDeviceSdk(platform, bleImplementation, securityKeys) {
3496
3838
  bridgeOta,
3497
3839
  /** Methods for working with Tirecheck TPMS FlexiGauge */
3498
3840
  flexiGaugeTpms,
3841
+ // flexiGauge,
3499
3842
  /** Methods for working with Tirecheck Pressure Stick */
3500
3843
  pressureStick,
3844
+ // ateq,
3501
3845
  /** Allows simulating devices without actually using bluetooth */
3502
- simulator
3846
+ simulator,
3847
+ /** Methods for working with Tirecheck Torque Wrench */
3848
+ torqueWrench
3503
3849
  };
3504
3850
  }
3505
3851
 
package/dist/index.d.cts CHANGED
@@ -900,6 +900,23 @@ declare function createTirecheckDeviceSdk(platform: DevicePlatform, bleImplement
900
900
  getSimulatedDevices(): Record<string, BleDeviceSimulated>;
901
901
  triggerEvent: (eventName: EventName, deviceId: string, payload?: any) => void;
902
902
  };
903
+ /** Methods for working with Tirecheck Torque Wrench */
904
+ torqueWrench: {
905
+ connect(deviceId: string): Promise<void>;
906
+ disconnect(deviceId: string, reason?: StateReason): Promise<void>;
907
+ getProperties: (deviceId: string) => Promise<TorqueWrenchProperties>;
908
+ setTime: (deviceId: string, date: Date) => Promise<any>;
909
+ startJob: (deviceId: string, params: TorqueWrenchStartJobParams) => Promise<void>;
910
+ stopJob: (deviceId: string) => Promise<any>;
911
+ getNumberOfReadings: (deviceId: string) => Promise<{
912
+ count: number;
913
+ jobId: string;
914
+ }>;
915
+ getReading: (deviceId: string) => Promise<void>;
916
+ getBattery: (deviceId: string) => Promise<number>;
917
+ getTime: (deviceId: string) => Promise<Date>;
918
+ onReading: (callback: (deviceId: string, value: TorqueWrenchReading) => void) => void;
919
+ };
903
920
  };
904
921
 
905
922
  export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BleFlexiGaugeTpmsSimulated, type BlePressureStick, type BleSecurityKeys, type BridgeAccessLevel, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type DeepPartial, type DevicePlatform, type DeviceState, type EventHandlers, type EventName, type FgSensorReading, type PositionInfo, type ReportStatusFn, type Simulator, type StateReason, type Wrapper, createTirecheckDeviceSdk };
package/dist/index.d.mts CHANGED
@@ -900,6 +900,23 @@ declare function createTirecheckDeviceSdk(platform: DevicePlatform, bleImplement
900
900
  getSimulatedDevices(): Record<string, BleDeviceSimulated>;
901
901
  triggerEvent: (eventName: EventName, deviceId: string, payload?: any) => void;
902
902
  };
903
+ /** Methods for working with Tirecheck Torque Wrench */
904
+ torqueWrench: {
905
+ connect(deviceId: string): Promise<void>;
906
+ disconnect(deviceId: string, reason?: StateReason): Promise<void>;
907
+ getProperties: (deviceId: string) => Promise<TorqueWrenchProperties>;
908
+ setTime: (deviceId: string, date: Date) => Promise<any>;
909
+ startJob: (deviceId: string, params: TorqueWrenchStartJobParams) => Promise<void>;
910
+ stopJob: (deviceId: string) => Promise<any>;
911
+ getNumberOfReadings: (deviceId: string) => Promise<{
912
+ count: number;
913
+ jobId: string;
914
+ }>;
915
+ getReading: (deviceId: string) => Promise<void>;
916
+ getBattery: (deviceId: string) => Promise<number>;
917
+ getTime: (deviceId: string) => Promise<Date>;
918
+ onReading: (callback: (deviceId: string, value: TorqueWrenchReading) => void) => void;
919
+ };
903
920
  };
904
921
 
905
922
  export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BleFlexiGaugeTpmsSimulated, type BlePressureStick, type BleSecurityKeys, type BridgeAccessLevel, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type DeepPartial, type DevicePlatform, type DeviceState, type EventHandlers, type EventName, type FgSensorReading, type PositionInfo, type ReportStatusFn, type Simulator, type StateReason, type Wrapper, createTirecheckDeviceSdk };
package/dist/index.d.ts CHANGED
@@ -900,6 +900,23 @@ declare function createTirecheckDeviceSdk(platform: DevicePlatform, bleImplement
900
900
  getSimulatedDevices(): Record<string, BleDeviceSimulated>;
901
901
  triggerEvent: (eventName: EventName, deviceId: string, payload?: any) => void;
902
902
  };
903
+ /** Methods for working with Tirecheck Torque Wrench */
904
+ torqueWrench: {
905
+ connect(deviceId: string): Promise<void>;
906
+ disconnect(deviceId: string, reason?: StateReason): Promise<void>;
907
+ getProperties: (deviceId: string) => Promise<TorqueWrenchProperties>;
908
+ setTime: (deviceId: string, date: Date) => Promise<any>;
909
+ startJob: (deviceId: string, params: TorqueWrenchStartJobParams) => Promise<void>;
910
+ stopJob: (deviceId: string) => Promise<any>;
911
+ getNumberOfReadings: (deviceId: string) => Promise<{
912
+ count: number;
913
+ jobId: string;
914
+ }>;
915
+ getReading: (deviceId: string) => Promise<void>;
916
+ getBattery: (deviceId: string) => Promise<number>;
917
+ getTime: (deviceId: string) => Promise<Date>;
918
+ onReading: (callback: (deviceId: string, value: TorqueWrenchReading) => void) => void;
919
+ };
903
920
  };
904
921
 
905
922
  export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BleFlexiGaugeTpmsSimulated, type BlePressureStick, type BleSecurityKeys, type BridgeAccessLevel, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type DeepPartial, type DevicePlatform, type DeviceState, type EventHandlers, type EventName, type FgSensorReading, type PositionInfo, type ReportStatusFn, type Simulator, type StateReason, type Wrapper, createTirecheckDeviceSdk };
package/dist/index.mjs CHANGED
@@ -97,6 +97,10 @@ function stringToArrayBuffer(string) {
97
97
  }
98
98
  return array.buffer;
99
99
  }
100
+ function decimalToHex(decimal, padStart = 2) {
101
+ const hex = decimal.toString(16);
102
+ return hex.padStart(padStart, "0");
103
+ }
100
104
  const toolsSvc = {
101
105
  delay,
102
106
  setIntervalImmediate,
@@ -1517,26 +1521,26 @@ const bridgeSecurity = {
1517
1521
  };
1518
1522
 
1519
1523
  const bridgeMeta = deviceMeta.bridge;
1520
- const devicePromiseQueue = {};
1521
- const deviceCurrentResolve = {};
1522
- const deviceCurrentReject = {};
1523
- const deviceResponseIdentifier = {};
1524
+ const devicePromiseQueue$1 = {};
1525
+ const deviceCurrentResolve$1 = {};
1526
+ const deviceCurrentReject$1 = {};
1527
+ const deviceResponseIdentifier$1 = {};
1524
1528
  const promiseQueue = {
1525
1529
  clearQueue(deviceId, message) {
1526
- if (deviceCurrentReject[deviceId]) {
1527
- deviceCurrentReject[deviceId](new Error(message ?? "Stopped sending commands"));
1530
+ if (deviceCurrentReject$1[deviceId]) {
1531
+ deviceCurrentReject$1[deviceId](new Error(message ?? "Stopped sending commands"));
1528
1532
  }
1529
- devicePromiseQueue[deviceId] = Promise.resolve();
1530
- deviceResponseIdentifier[deviceId] = [];
1533
+ devicePromiseQueue$1[deviceId] = Promise.resolve();
1534
+ deviceResponseIdentifier$1[deviceId] = [];
1531
1535
  },
1532
1536
  async enqueue(device, payload) {
1533
- if (devicePromiseQueue[device.id] === void 0) devicePromiseQueue[device.id] = Promise.resolve();
1534
- devicePromiseQueue[device.id] = devicePromiseQueue[device.id].then(() => {
1537
+ if (devicePromiseQueue$1[device.id] === void 0) devicePromiseQueue$1[device.id] = Promise.resolve();
1538
+ devicePromiseQueue$1[device.id] = devicePromiseQueue$1[device.id].then(() => {
1535
1539
  const promise = new Promise((resolve, reject) => {
1536
- deviceCurrentResolve[device.id] = resolve;
1537
- deviceCurrentReject[device.id] = reject;
1538
- const isKeepAlive = payload[3] === commandIds.keepAlive;
1539
- deviceResponseIdentifier[device.id] = [isKeepAlive ? 126 : 0, payload[4]];
1540
+ deviceCurrentResolve$1[device.id] = resolve;
1541
+ deviceCurrentReject$1[device.id] = reject;
1542
+ const isKeepAlive = payload[3] === commandIds$1.keepAlive;
1543
+ deviceResponseIdentifier$1[device.id] = [isKeepAlive ? 126 : 0, payload[4]];
1540
1544
  const signedData = bridgeSecurity.getSignedCommand(device, payload);
1541
1545
  if (!toolsSvc.canCommunicateWith(device.id)) return reject(new Error("Bridge not connected"));
1542
1546
  if (signedData.length > 110) {
@@ -1562,21 +1566,21 @@ const promiseQueue = {
1562
1566
  );
1563
1567
  }
1564
1568
  });
1565
- return withTimeout(promise, 5e3, `Command timed out ${deviceResponseIdentifier[device.id]}, ${device.id}`);
1569
+ return withTimeout(promise, 5e3, `Command timed out ${deviceResponseIdentifier$1[device.id]}, ${device.id}`);
1566
1570
  });
1567
- return devicePromiseQueue[device.id];
1571
+ return devicePromiseQueue$1[device.id];
1568
1572
  },
1569
1573
  async processMessage(deviceId, payload) {
1570
1574
  const numberArray = Array.from(new Uint8Array(payload));
1571
1575
  if (numberArray[3] === 127) {
1572
1576
  console.error(numberArray);
1573
- return deviceCurrentReject[deviceId](new Error(`Command not succesful: ${numberArray[4]}`));
1577
+ return deviceCurrentReject$1[deviceId](new Error(`Command not succesful: ${numberArray[4]}`));
1574
1578
  }
1575
1579
  if ([226, 81].includes(numberArray[3]) && numberArray[4] && toolsSvc.canCommunicateWith(deviceId)) {
1576
1580
  store.bridgeRebootRequired[deviceId] = true;
1577
1581
  }
1578
- if ((!deviceResponseIdentifier[deviceId][0] || numberArray[3] === deviceResponseIdentifier[deviceId][0]) && (!deviceResponseIdentifier[deviceId][1] || numberArray[4] === deviceResponseIdentifier[deviceId][1])) {
1579
- return deviceCurrentResolve[deviceId](numberArray);
1582
+ if ((!deviceResponseIdentifier$1[deviceId][0] || numberArray[3] === deviceResponseIdentifier$1[deviceId][0]) && (!deviceResponseIdentifier$1[deviceId][1] || numberArray[4] === deviceResponseIdentifier$1[deviceId][1])) {
1583
+ return deviceCurrentResolve$1[deviceId](numberArray);
1580
1584
  }
1581
1585
  console.warn("message from the device not belonging to the pending promise: ", numberArray);
1582
1586
  }
@@ -1593,7 +1597,7 @@ const messageTypeIds = {
1593
1597
  command: 0,
1594
1598
  response: 1
1595
1599
  };
1596
- const commandIds = {
1600
+ const commandIds$1 = {
1597
1601
  readData: 34,
1598
1602
  writeData: 46,
1599
1603
  keepAlive: 62,
@@ -1642,7 +1646,7 @@ const subCommandIds = {
1642
1646
  autolearnIdStatus: 176,
1643
1647
  autolearnUnknownSensors: 192
1644
1648
  };
1645
- _.invert(commandIds);
1649
+ _.invert(commandIds$1);
1646
1650
  _.invert(subCommandIds);
1647
1651
  const keepAliveTimer = {};
1648
1652
  const bridgeCommands = {
@@ -1653,7 +1657,7 @@ const bridgeCommands = {
1653
1657
  },
1654
1658
  async setAxlesPressure(deviceId, data) {
1655
1659
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1656
- await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.pressurePerAxle, data);
1660
+ await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.pressurePerAxle, data);
1657
1661
  },
1658
1662
  async setVehicleLayout(deviceId, structurizedPayload) {
1659
1663
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1662,7 +1666,7 @@ const bridgeCommands = {
1662
1666
  structurizedPayload,
1663
1667
  deviceData.advertisingData.fwVersion
1664
1668
  );
1665
- await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.vehicleLayout, payload);
1669
+ await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.vehicleLayout, payload);
1666
1670
  },
1667
1671
  async getCustomerCANSettings(deviceId) {
1668
1672
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1715,18 +1719,18 @@ const bridgeCommands = {
1715
1719
  return { ...structurized, isFactory: result.isFactory };
1716
1720
  },
1717
1721
  async sendKeepAliveCommand(device) {
1718
- return this.promisify(device, [...this.getCommandHeader(device), 2, commandIds.keepAlive, 0]);
1722
+ return this.promisify(device, [...this.getCommandHeader(device), 2, commandIds$1.keepAlive, 0]);
1719
1723
  },
1720
1724
  async sendOtaRequest(deviceId) {
1721
1725
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1722
- const command = [commandIds.otaRequest, 0];
1726
+ const command = [commandIds$1.otaRequest, 0];
1723
1727
  const result = await this.promisify(deviceData, [...this.getCommandHeader(deviceData), command.length, ...command]);
1724
1728
  return result;
1725
1729
  },
1726
1730
  async sendPinCommand(deviceId) {
1727
1731
  const deviceData = await bridgeTools.getBridgeFromStore(deviceId);
1728
1732
  const pin = await bridgeSecurity.getPin(deviceId);
1729
- return this.promisify(deviceData, [...this.getCommandHeader(deviceData), 18, commandIds.pin, 0, ...pin]);
1733
+ return this.promisify(deviceData, [...this.getCommandHeader(deviceData), 18, commandIds$1.pin, 0, ...pin]);
1730
1734
  },
1731
1735
  async setBridgeToRestart(deviceId) {
1732
1736
  if (store.bridgeRebootRequired[deviceId]) return;
@@ -1735,7 +1739,7 @@ const bridgeCommands = {
1735
1739
  await this.promisify(deviceData, [
1736
1740
  ...this.getCommandHeader(deviceData),
1737
1741
  2,
1738
- useNewCommand ? commandIds.ecuReset : commandIds.reboot,
1742
+ useNewCommand ? commandIds$1.ecuReset : commandIds$1.reboot,
1739
1743
  useNewCommand ? subCommandIds.ecuResetSubCommand : subCommandIds.rebootSubCommand
1740
1744
  ]);
1741
1745
  },
@@ -1746,7 +1750,7 @@ const bridgeCommands = {
1746
1750
  structurizedPayload,
1747
1751
  deviceData.advertisingData.fwVersion
1748
1752
  );
1749
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerCanSettings, payload);
1753
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.customerCanSettings, payload);
1750
1754
  },
1751
1755
  async setWorkshopCANSettings(deviceId, structurizedPayload) {
1752
1756
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1755,7 +1759,7 @@ const bridgeCommands = {
1755
1759
  structurizedPayload,
1756
1760
  deviceData.advertisingData.fwVersion
1757
1761
  );
1758
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.workshopCanSettings, payload);
1762
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.workshopCanSettings, payload);
1759
1763
  },
1760
1764
  async setCustomerPressureThresholds(deviceId, structurizedPayload) {
1761
1765
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1764,7 +1768,7 @@ const bridgeCommands = {
1764
1768
  structurizedPayload,
1765
1769
  deviceData.advertisingData.fwVersion
1766
1770
  );
1767
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerPressureThresholds, payload);
1771
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.customerPressureThresholds, payload);
1768
1772
  },
1769
1773
  async setCustomerTemperatureThresholds(deviceId, structurizedPayload) {
1770
1774
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1775,7 +1779,7 @@ const bridgeCommands = {
1775
1779
  );
1776
1780
  return await this.writeCommand(
1777
1781
  deviceData,
1778
- commandIds.writeData,
1782
+ commandIds$1.writeData,
1779
1783
  subCommandIds.customerTemperatureThresholds,
1780
1784
  payload
1781
1785
  );
@@ -1787,7 +1791,7 @@ const bridgeCommands = {
1787
1791
  structurizedPayload,
1788
1792
  deviceData.advertisingData.fwVersion
1789
1793
  );
1790
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.customerImbalanceThresholds, payload);
1794
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.customerImbalanceThresholds, payload);
1791
1795
  },
1792
1796
  async getAutolearnSettings(deviceId) {
1793
1797
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1816,7 +1820,7 @@ const bridgeCommands = {
1816
1820
  structurizedPayload,
1817
1821
  deviceData.advertisingData.fwVersion
1818
1822
  );
1819
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.autolearnSettings, payload);
1823
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.autolearnSettings, payload);
1820
1824
  },
1821
1825
  async setAutolearnIdStatus(deviceId, structurizedPayload) {
1822
1826
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1825,7 +1829,7 @@ const bridgeCommands = {
1825
1829
  structurizedPayload,
1826
1830
  deviceData.advertisingData.fwVersion
1827
1831
  );
1828
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.autolearnIdStatus, payload);
1832
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.autolearnIdStatus, payload);
1829
1833
  },
1830
1834
  async getAutolearnUnknownSensors(device) {
1831
1835
  const result = await this.readCommand(device, subCommandIds.autolearnUnknownSensors);
@@ -1846,7 +1850,7 @@ const bridgeCommands = {
1846
1850
  // move logic to bridge svc
1847
1851
  async setAxleInfo(deviceId, axleIndex, data) {
1848
1852
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
1849
- await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.idsPerWheel(axleIndex), data);
1853
+ await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.idsPerWheel(axleIndex), data);
1850
1854
  },
1851
1855
  async getAxlesPressure(deviceId) {
1852
1856
  const deviceData = bridgeTools.getBridgeFromStore(deviceId);
@@ -1870,7 +1874,7 @@ const bridgeCommands = {
1870
1874
  structurizedPayload,
1871
1875
  deviceData.advertisingData.fwVersion
1872
1876
  );
1873
- return await this.writeCommand(deviceData, commandIds.writeData, subCommandIds.pressurePerAxle, payload);
1877
+ return await this.writeCommand(deviceData, commandIds$1.writeData, subCommandIds.pressurePerAxle, payload);
1874
1878
  },
1875
1879
  // // async setPressureThresholds(device: BleBridge, rules: any) {
1876
1880
  // // // https://tirecheck.atlassian.net/wiki/spaces/HWPRG/pages/6547767302/Technical+Design+Document+BLE+CAN+Bridge+Krone#Example.1
@@ -1913,7 +1917,7 @@ const bridgeCommands = {
1913
1917
  }
1914
1918
  const result = await this.writeCommand(
1915
1919
  deviceData,
1916
- commandIds.sensorMeasurement,
1920
+ commandIds$1.sensorMeasurement,
1917
1921
  subCommandIds.sensorMeasurementPerWheel(axlePosition, tyrePosition, isTwinTyre, isSpare),
1918
1922
  []
1919
1923
  );
@@ -1924,7 +1928,7 @@ const bridgeCommands = {
1924
1928
  const result = await this.promisify(device, [
1925
1929
  ...this.getCommandHeader(device),
1926
1930
  commandLength,
1927
- commandIds.readData,
1931
+ commandIds$1.readData,
1928
1932
  subCommandId
1929
1933
  ]);
1930
1934
  const data = result.slice(19, result.length - 8);
@@ -2889,6 +2893,344 @@ const pressureStick = {
2889
2893
  onPressure: pressureStickService.onPressure
2890
2894
  };
2891
2895
 
2896
+ const devicePromiseQueue = {};
2897
+ const deviceCurrentResolve = {};
2898
+ const deviceCurrentReject = {};
2899
+ const deviceResponseIdentifier = {};
2900
+ const deviceCurrentPartialMessage = {};
2901
+ const torqueWrenchPromiseQueue = {
2902
+ clearQueue(deviceId, message) {
2903
+ if (deviceCurrentReject[deviceId]) {
2904
+ deviceCurrentReject[deviceId](new Error(message ?? "Stopped sending commands"));
2905
+ }
2906
+ devicePromiseQueue[deviceId] = Promise.resolve();
2907
+ deviceResponseIdentifier[deviceId] = void 0;
2908
+ },
2909
+ async enqueue(deviceId, communication, payload, responseIdentifier, mtu = 20) {
2910
+ if (devicePromiseQueue[deviceId] === void 0) devicePromiseQueue[deviceId] = Promise.resolve();
2911
+ devicePromiseQueue[deviceId] = devicePromiseQueue[deviceId].then(() => {
2912
+ const promise = new Promise((resolve, reject) => {
2913
+ deviceCurrentResolve[deviceId] = resolve;
2914
+ deviceCurrentReject[deviceId] = reject;
2915
+ deviceResponseIdentifier[deviceId] = responseIdentifier;
2916
+ deviceCurrentPartialMessage[deviceId] = [];
2917
+ if (!toolsSvc.canCommunicateWith(deviceId)) return reject(new Error("Torque wrench not connected"));
2918
+ const chunks = [];
2919
+ for (let i = 0; i < payload.length; i += mtu) {
2920
+ chunks.push(payload.slice(i, i + mtu));
2921
+ }
2922
+ for (const chunk of chunks) {
2923
+ const convertedChunk = new Uint8Array(chunk).buffer;
2924
+ bluetooth.write(deviceId, communication.serviceId, communication.characteristicId, convertedChunk);
2925
+ }
2926
+ });
2927
+ return withTimeout(promise, 5e3, `Command timed out ${deviceResponseIdentifier[deviceId]}, ${deviceId}`);
2928
+ });
2929
+ return devicePromiseQueue[deviceId];
2930
+ },
2931
+ async processMessage(deviceId, payload, getIdentifier, isComplete, isError) {
2932
+ const numberArray = Array.from(new Uint8Array(payload));
2933
+ if (!deviceCurrentPartialMessage[deviceId]) deviceCurrentPartialMessage[deviceId] = [];
2934
+ deviceCurrentPartialMessage[deviceId] = _.concat(deviceCurrentPartialMessage[deviceId], numberArray);
2935
+ if (!isComplete(deviceCurrentPartialMessage[deviceId])) {
2936
+ return;
2937
+ }
2938
+ if (isError(deviceCurrentPartialMessage[deviceId])) {
2939
+ return deviceCurrentReject[deviceId](
2940
+ new Error("Error response", { cause: deviceCurrentPartialMessage[deviceId] })
2941
+ );
2942
+ }
2943
+ const identifier = getIdentifier(deviceCurrentPartialMessage[deviceId]);
2944
+ if (deviceResponseIdentifier[deviceId] === identifier) {
2945
+ deviceCurrentResolve[deviceId](deviceCurrentPartialMessage[deviceId]);
2946
+ }
2947
+ }
2948
+ };
2949
+
2950
+ const commandStart = "$9";
2951
+ const commandEnd = "*";
2952
+ const commandIds = {
2953
+ error: "004",
2954
+ acknowledge: "005",
2955
+ commTest: "100",
2956
+ getProperties: "120",
2957
+ startJob: "204",
2958
+ stopJob: "206",
2959
+ getNumberOfReadings: "224",
2960
+ getReading: "200",
2961
+ // Can only be called once for each reading.
2962
+ getReadingAgain: "202",
2963
+ getBattery: "150",
2964
+ getTime: "209",
2965
+ setTime: "208"
2966
+ };
2967
+ const errors = {
2968
+ "01": "Bad string",
2969
+ "02": "Bad checksum",
2970
+ "03": "Unknown command",
2971
+ "04": "No device present for command to act on",
2972
+ "05": "Invalid sample speed",
2973
+ "06": "Torque module offset difference bigger than 25%",
2974
+ "07": "Torque module gain outside 0.9 to 1.1",
2975
+ "08": "No RF properties",
2976
+ "09": "No reply from RF",
2977
+ "0A": "RF device already paired on this device",
2978
+ "0C": "Invalid frequency",
2979
+ "0D": "Invalid LED selection",
2980
+ "0F": "Transducer preloaded",
2981
+ "10": "No more readings",
2982
+ "11": "Job already loaded",
2983
+ "12": "No trace stored",
2984
+ "13": "Wrong transducers selected for Multi Start Mode",
2985
+ "14": "No short trace stored",
2986
+ "15": "Job finished",
2987
+ "16": "Missing time and date",
2988
+ "17": "Bad units for wrench type",
2989
+ "18": "Battery low"
2990
+ };
2991
+ const twMeta = deviceMeta.torqueWrench;
2992
+ const torqueWrenchCommands = {
2993
+ async sendCommand(deviceId, command, params) {
2994
+ const commandId = commandIds[command];
2995
+ let message = `${commandStart}${commandId}`;
2996
+ if (params?.length) {
2997
+ message += `,${params.join(",")}`;
2998
+ }
2999
+ message += commandEnd;
3000
+ const crc = getChecksum(message);
3001
+ message += `${crc}\r`;
3002
+ const array = new Uint8Array(message.length);
3003
+ for (let i = 0, l = message.length; i < l; i++) {
3004
+ array[i] = message.charCodeAt(i);
3005
+ }
3006
+ const decimalArray = Array.from(array);
3007
+ let result;
3008
+ try {
3009
+ result = await torqueWrenchPromiseQueue.enqueue(deviceId, twMeta.communication, decimalArray, commandIds[command]);
3010
+ } catch (error) {
3011
+ const formattedError = formatError(error);
3012
+ throw new Error(formattedError);
3013
+ }
3014
+ return result.map((num) => String.fromCharCode(num)).join("");
3015
+ },
3016
+ processMessage(deviceId, payload) {
3017
+ torqueWrenchPromiseQueue.processMessage(deviceId, payload, getIdentifier, isComplete, isError);
3018
+ }
3019
+ };
3020
+ function isComplete(message) {
3021
+ const completeReading = message[0] === 123 && message.at(-1) === 13;
3022
+ const completeCommand = message[0] === 36 && message.at(-1) === 13;
3023
+ return completeReading || completeCommand;
3024
+ }
3025
+ function isError(message) {
3026
+ return message[4] === 52;
3027
+ }
3028
+ function getIdentifier(message) {
3029
+ if (message[0] === 123) return "200";
3030
+ return message.slice(6, 9).map((num) => String.fromCharCode(num)).join("");
3031
+ }
3032
+ function getChecksum(message) {
3033
+ let checksum = 0;
3034
+ for (const ch of message) {
3035
+ checksum ^= ch.charCodeAt(0);
3036
+ }
3037
+ return decimalToHex(checksum).toUpperCase();
3038
+ }
3039
+ function formatError(error) {
3040
+ if (!error.cause) throw new Error(error);
3041
+ const message = error.cause.slice(6, 8);
3042
+ const errorId = message.map((num) => String.fromCharCode(num)).join("");
3043
+ return errors[errorId] || "Unknown error";
3044
+ }
3045
+
3046
+ let jobInterval = null;
3047
+ const torqueWrenchService = {
3048
+ onReading(callback) {
3049
+ simulatorSvc.registerEvent("tw:reading", callback);
3050
+ },
3051
+ async getProperties(deviceId) {
3052
+ const result = {
3053
+ serialNumber: "",
3054
+ span: 0,
3055
+ calibrationDate: "",
3056
+ ppr: 0,
3057
+ units: "Nm",
3058
+ threshold: 10
3059
+ };
3060
+ const message = await torqueWrenchCommands.sendCommand(deviceId, "getProperties");
3061
+ const params = getMessageParams(message);
3062
+ if (params[4] === "3") result.units = "Nm";
3063
+ else if (params[4] === "7") result.units = "lb-ft";
3064
+ result.serialNumber = params[0];
3065
+ result.span = Number.parseInt(params[1]);
3066
+ if (result.units === "lb-ft") result.span = Math.floor(result.span * 0.738);
3067
+ result.calibrationDate = params[2];
3068
+ result.ppr = Number.parseInt(params[3]);
3069
+ return result;
3070
+ },
3071
+ async startJob(deviceId, params) {
3072
+ await this.stopJob(deviceId);
3073
+ const { units, span, ppr, threshold } = store.torqueWrenchProperties[deviceId];
3074
+ console.log("\u{1F680} ~ startJob ~ units:", units);
3075
+ const { torqueMin, torqueMax, angleMin, angleMax, direction, jobTimeout } = params;
3076
+ const msgParams = {
3077
+ id: "01",
3078
+ nuts: decimalToHex(params.nuts),
3079
+ mode: units === "lb-ft" ? "20" : "1",
3080
+ // Peak measurement mode
3081
+ cycle: "7",
3082
+ // 10 seconds cycle (probably for measurements - not sure what it does exactly, not specified in docs)
3083
+ control: torqueMin != null || torqueMax != null ? "0" : "1",
3084
+ direction: direction === "counter-clockwise" ? "1" : "0",
3085
+ minTorqueThreshold: torqueToAdcParam(threshold, span, units),
3086
+ torqueMin: torqueToAdcParam(torqueMin ?? 0, span, units),
3087
+ torqueMax: torqueToAdcParam(torqueMax ?? -1, span, units),
3088
+ clickThreshold: torqueToAdcParam(threshold, span, units),
3089
+ // Probably not used in our case (for this specified mode).
3090
+ angleMin: angleToPulsesParam(angleMin ?? 0, ppr),
3091
+ angleMax: angleToPulsesParam(angleMax ?? -1, ppr),
3092
+ frequency: "0542"
3093
+ // No idea
3094
+ };
3095
+ const paramsString = Object.values(msgParams);
3096
+ await torqueWrenchCommands.sendCommand(deviceId, "startJob", paramsString);
3097
+ jobInterval = setInterval(async () => {
3098
+ const numberOfReading = await this.getNumberOfReadings(deviceId);
3099
+ console.log("\u{1F680} ~ jobInterval=setInterval ~ numberOfReading:", numberOfReading);
3100
+ if (numberOfReading.count > 0) this.getReading(deviceId);
3101
+ }, 1e3);
3102
+ if (jobTimeout) {
3103
+ await new Promise(
3104
+ (resolve) => setTimeout(() => {
3105
+ console.log("job terminated");
3106
+ clearInterval(jobInterval);
3107
+ this.stopJob(deviceId);
3108
+ resolve("");
3109
+ }, jobTimeout * 1e3)
3110
+ );
3111
+ }
3112
+ },
3113
+ async stopJob(deviceId) {
3114
+ return torqueWrenchCommands.sendCommand(deviceId, "stopJob");
3115
+ },
3116
+ async getNumberOfReadings(deviceId) {
3117
+ const message = await torqueWrenchCommands.sendCommand(deviceId, "getNumberOfReadings");
3118
+ const params = getMessageParams(message);
3119
+ return { count: Number(params[0]), jobId: params[1] };
3120
+ },
3121
+ async getReading(deviceId) {
3122
+ const reading = await torqueWrenchCommands.sendCommand(deviceId, "getReading");
3123
+ const properties = {
3124
+ jobId: reading.slice(2, 4),
3125
+ nut: reading.slice(4, 6),
3126
+ torqueAdc: reading.slice(6, 10),
3127
+ anglePulses: reading.slice(10, 14),
3128
+ duration: reading.slice(14, 18)
3129
+ };
3130
+ const torque = adcToTorque(
3131
+ properties.torqueAdc,
3132
+ store.torqueWrenchProperties[deviceId].span,
3133
+ store.torqueWrenchProperties[deviceId].units
3134
+ );
3135
+ const angle = pulsesToAngle(properties.anglePulses, store.torqueWrenchProperties[deviceId].ppr);
3136
+ const formattedReading = {
3137
+ jobId: Number.parseInt(properties.jobId, 16),
3138
+ nut: Number.parseInt(properties.nut, 16),
3139
+ torque,
3140
+ angle,
3141
+ duration: Number.parseInt(properties.duration, 16) / 1e3
3142
+ };
3143
+ simulatorSvc.triggerEvent("tw:reading", deviceId, formattedReading);
3144
+ },
3145
+ // getReadingAgain(deviceId: string) {
3146
+ // return torqueWrenchCommands.sendCommand(deviceId, 'getNumberOfReadings')
3147
+ // },
3148
+ async getBattery(deviceId) {
3149
+ const message = await torqueWrenchCommands.sendCommand(deviceId, "getBattery");
3150
+ const params = getMessageParams(message);
3151
+ return Number(params[0]);
3152
+ },
3153
+ async getTime(deviceId) {
3154
+ const message = await torqueWrenchCommands.sendCommand(deviceId, "getTime");
3155
+ const match = message.match(/209,([^*]*)\*/);
3156
+ console.log("\u{1F680} ~ getTime ~ match:", match);
3157
+ if (!match[1]) throw new Error("Invalid time response");
3158
+ const hh = match[1].substring(0, 2);
3159
+ const mm = match[1].substring(2, 4);
3160
+ const ss = match[1].substring(4, 6);
3161
+ const dd = match[1].substring(6, 8);
3162
+ const MM = match[1].substring(8, 10);
3163
+ const yy = match[1].substring(10, 12);
3164
+ const fullYear = `20${yy}`;
3165
+ return /* @__PURE__ */ new Date(`${fullYear}-${MM}-${dd}T${hh}:${mm}:${ss}Z`);
3166
+ },
3167
+ setTime(deviceId, date) {
3168
+ const hours = String(date.getHours()).padStart(2, "0");
3169
+ const minutes = String(date.getMinutes()).padStart(2, "0");
3170
+ const seconds = String(date.getSeconds()).padStart(2, "0");
3171
+ const day = String(date.getDate()).padStart(2, "0");
3172
+ const month = String(date.getMonth() + 1).padStart(2, "0");
3173
+ const year = String(date.getFullYear()).slice(-2);
3174
+ const params = [hours, minutes, seconds, day, month, year];
3175
+ return torqueWrenchCommands.sendCommand(deviceId, "setTime", params);
3176
+ }
3177
+ };
3178
+ function torqueToAdcParam(value, span, deviceUnits) {
3179
+ if (value < 0) return "FFFF";
3180
+ if (deviceUnits !== "Nm") value = value * 0.738;
3181
+ const adc = Math.round(value / span * 16384);
3182
+ return decimalToHex(adc, 4).toUpperCase();
3183
+ }
3184
+ function angleToPulsesParam(value, ppr) {
3185
+ if (value < 0) return "FFFF";
3186
+ const pulses = Math.round(value * ppr / 90);
3187
+ return decimalToHex(pulses, 4).toUpperCase();
3188
+ }
3189
+ function getMessageParams(message) {
3190
+ return message.match(/^\$[^,]+,[^,]+,(.*)\*/)?.[1].split(",") || [];
3191
+ }
3192
+ function adcToTorque(value, span, units) {
3193
+ const torque = Number.parseInt(value, 16) * span / 16384;
3194
+ if (units !== "Nm") return torque / 0.738;
3195
+ return torque;
3196
+ }
3197
+ function pulsesToAngle(value, ppr) {
3198
+ return Number.parseInt(value, 16) * 90 / ppr;
3199
+ }
3200
+
3201
+ const torqueWrench = {
3202
+ async connect(deviceId) {
3203
+ const twMeta = deviceMeta.torqueWrench;
3204
+ await bluetooth.connect(deviceId, this.disconnect);
3205
+ await ble.startNotification(
3206
+ deviceId,
3207
+ twMeta.communication.serviceId,
3208
+ twMeta.communication.characteristicId,
3209
+ (notification) => {
3210
+ torqueWrenchCommands.processMessage(deviceId, notification);
3211
+ },
3212
+ (error) => console.warn("ble.startNotification error", error)
3213
+ );
3214
+ const properties = await torqueWrenchService.getProperties(deviceId);
3215
+ store.torqueWrenchProperties[deviceId] = properties;
3216
+ store.setState(deviceId, "paired");
3217
+ },
3218
+ async disconnect(deviceId, reason) {
3219
+ store.setState(deviceId, "disconnecting");
3220
+ await bluetooth.disconnect(deviceId);
3221
+ store.setState(deviceId, void 0, reason ?? "manualDisconnection");
3222
+ },
3223
+ getProperties: torqueWrenchService.getProperties,
3224
+ setTime: torqueWrenchService.setTime,
3225
+ startJob: torqueWrenchService.startJob,
3226
+ stopJob: torqueWrenchService.stopJob,
3227
+ getNumberOfReadings: torqueWrenchService.getNumberOfReadings,
3228
+ getReading: torqueWrenchService.getReading,
3229
+ getBattery: torqueWrenchService.getBattery,
3230
+ getTime: torqueWrenchService.getTime,
3231
+ onReading: torqueWrenchService.onReading
3232
+ };
3233
+
2892
3234
  const bridgeSimulator = {
2893
3235
  isRebootRequired(deviceId) {
2894
3236
  return store.bridgeRebootRequired[deviceId];
@@ -3489,10 +3831,14 @@ function createTirecheckDeviceSdk(platform, bleImplementation, securityKeys) {
3489
3831
  bridgeOta,
3490
3832
  /** Methods for working with Tirecheck TPMS FlexiGauge */
3491
3833
  flexiGaugeTpms,
3834
+ // flexiGauge,
3492
3835
  /** Methods for working with Tirecheck Pressure Stick */
3493
3836
  pressureStick,
3837
+ // ateq,
3494
3838
  /** Allows simulating devices without actually using bluetooth */
3495
- simulator
3839
+ simulator,
3840
+ /** Methods for working with Tirecheck Torque Wrench */
3841
+ torqueWrench
3496
3842
  };
3497
3843
  }
3498
3844
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tirecheck-device-sdk",
3
- "version": "0.2.02",
3
+ "version": "0.2.22",
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",