tirecheck-device-sdk 0.1.5 → 0.1.7
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 +81 -22
- package/dist/index.d.cts +10 -5
- package/dist/index.d.mts +10 -5
- package/dist/index.d.ts +10 -5
- package/dist/index.mjs +81 -22
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -14,13 +14,17 @@ function setBleImplementation(bleImplementation) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const store = {
|
|
17
|
-
platform: "
|
|
17
|
+
platform: "android",
|
|
18
|
+
/** Defines access level for each connection, should be 'driver' as default, Supported roles: ['manufacturer', 'driver'] , Example: F4B4553322: 'manufacturer' */
|
|
19
|
+
deviceAccessLevel: {},
|
|
18
20
|
devices: {},
|
|
19
21
|
simulatedDevices: {},
|
|
20
22
|
/** undefined - no information but since we get advertisings it is most likely disconnected, connecting - trying to connect via bluetooth, connected - connected via bluetooth (can send write and read), paired - all additional connection steps completed (setMtu, sendPin, etc) */
|
|
21
23
|
deviceState: {},
|
|
22
24
|
// undefined => connecting => connected => paired => disconnecting => disconnected
|
|
23
25
|
bridgesReboot: {},
|
|
26
|
+
//** Ios uses generated device Id, bridges send mac address in advertising so internaly we always use mac address but when real device id is needed we check mapping table for it */
|
|
27
|
+
deviceIdMapingTable: {},
|
|
24
28
|
setState(deviceId, state) {
|
|
25
29
|
this.deviceState[deviceId] = state;
|
|
26
30
|
deviceStateChangeCallback?.(deviceId, state);
|
|
@@ -306,9 +310,14 @@ const bridgeAdvertisingParser = {
|
|
|
306
310
|
const adversitingType = getAdvertisingType(device);
|
|
307
311
|
if (adversitingType !== "connectable") return void 0;
|
|
308
312
|
const advertisingData = getAdvertisingData({ advertising: device.advertising, deviceName: device.name });
|
|
309
|
-
const
|
|
313
|
+
const macArray = advertisingData?.macAddress?.map((n) => bridgeTools.decimalToHex(n).toUpperCase()).reverse() || [];
|
|
314
|
+
const bridgeId = macArray.join("");
|
|
310
315
|
const vin = String.fromCharCode(...advertisingData?.vinNum || []).split("\0").join("");
|
|
311
|
-
|
|
316
|
+
const macString = macArray.join(":");
|
|
317
|
+
if (store.platform === "ios") {
|
|
318
|
+
store.deviceIdMapingTable[macString] = device.id;
|
|
319
|
+
}
|
|
320
|
+
return { id: macString, name: device.name, bridgeId, vin, advertisingData, type: "bridge", rssi: device.rssi };
|
|
312
321
|
}
|
|
313
322
|
};
|
|
314
323
|
function getAdvertisingType(device) {
|
|
@@ -398,6 +407,49 @@ function processIosAdvertising(adv, isKrone) {
|
|
|
398
407
|
return advertisingData;
|
|
399
408
|
}
|
|
400
409
|
|
|
410
|
+
const bridgeOtaAdvertisingParser = {
|
|
411
|
+
getDeviceInfoFromAdvertising: (device) => {
|
|
412
|
+
const adv = Array.from(new Uint8Array(device.advertising));
|
|
413
|
+
let deviceId = "";
|
|
414
|
+
let bridgeId = "";
|
|
415
|
+
let processedByteCount = 0;
|
|
416
|
+
if (store.platform === "ios") {
|
|
417
|
+
if (!device.advertising.kCBAdvDataLeBluetoothDeviceAddress)
|
|
418
|
+
return console.warn("No mac address in advertising data");
|
|
419
|
+
const macAddress = Array.from(new Uint8Array(device.advertising.kCBAdvDataLeBluetoothDeviceAddress)).map(
|
|
420
|
+
(x) => bridgeTools.decimalToHex(x).toUpperCase()
|
|
421
|
+
);
|
|
422
|
+
deviceId = macAddress.join(":");
|
|
423
|
+
bridgeId = macAddress.join("");
|
|
424
|
+
} else {
|
|
425
|
+
do {
|
|
426
|
+
const length = adv[processedByteCount];
|
|
427
|
+
const identificator = adv[processedByteCount + 1];
|
|
428
|
+
const packet = adv.slice(processedByteCount, processedByteCount + length + 1);
|
|
429
|
+
if (!length) {
|
|
430
|
+
processedByteCount = adv.length;
|
|
431
|
+
}
|
|
432
|
+
processedByteCount += length + 1;
|
|
433
|
+
if (identificator === 27) {
|
|
434
|
+
const macAddress = packet.slice(-6).reverse().map((x) => bridgeTools.decimalToHex(x).toUpperCase());
|
|
435
|
+
deviceId = macAddress.join(":");
|
|
436
|
+
bridgeId = macAddress.join("");
|
|
437
|
+
processedByteCount = adv.length;
|
|
438
|
+
}
|
|
439
|
+
} while (processedByteCount < adv.length);
|
|
440
|
+
}
|
|
441
|
+
if (!deviceId) return console.warn("Failed to get device Id");
|
|
442
|
+
store.deviceIdMapingTable[deviceId] = device.id;
|
|
443
|
+
const bleDevice = {
|
|
444
|
+
...device,
|
|
445
|
+
id: deviceId,
|
|
446
|
+
advertisingData: { bridgeId },
|
|
447
|
+
type: "bridgeOta"
|
|
448
|
+
};
|
|
449
|
+
return bleDevice;
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
401
453
|
const deviceMeta = {
|
|
402
454
|
bridge: {
|
|
403
455
|
nameRegex: /(030303|030321)/,
|
|
@@ -415,13 +467,7 @@ const deviceMeta = {
|
|
|
415
467
|
serviceId: "4880c12c-fdcb-4077-8920-a450d7f9b907",
|
|
416
468
|
characteristicId: "fec26ec4-6d71-4442-9f81-55bc21d658d7"
|
|
417
469
|
},
|
|
418
|
-
getDeviceInfoFromAdvertising:
|
|
419
|
-
const bleDevice = {
|
|
420
|
-
...device,
|
|
421
|
-
type: "bridgeOta"
|
|
422
|
-
};
|
|
423
|
-
return bleDevice;
|
|
424
|
-
}
|
|
470
|
+
getDeviceInfoFromAdvertising: bridgeOtaAdvertisingParser.getDeviceInfoFromAdvertising
|
|
425
471
|
},
|
|
426
472
|
flexiGaugeTpms: {
|
|
427
473
|
nameRegex: /Flexi.*/,
|
|
@@ -517,6 +563,7 @@ async function scanDevices(services = [], duration) {
|
|
|
517
563
|
);
|
|
518
564
|
}
|
|
519
565
|
async function connect(deviceId, disconnectCallback) {
|
|
566
|
+
if (toolsSvc.canCommunicateWith(deviceId)) return console.warn("Connect Warn: Already connected to device");
|
|
520
567
|
store.setState(deviceId, "connecting");
|
|
521
568
|
let connectedDevice;
|
|
522
569
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
@@ -528,7 +575,8 @@ async function connect(deviceId, disconnectCallback) {
|
|
|
528
575
|
if (attempt === 3) throw new Error("Connection unsuccessful");
|
|
529
576
|
}
|
|
530
577
|
}
|
|
531
|
-
const
|
|
578
|
+
const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
|
|
579
|
+
const isConnected = await ble.isConnected(_deviceId);
|
|
532
580
|
if (!isConnected) {
|
|
533
581
|
store.setState(deviceId, void 0);
|
|
534
582
|
throw new Error("Connect Error");
|
|
@@ -537,8 +585,9 @@ async function connect(deviceId, disconnectCallback) {
|
|
|
537
585
|
return connectedDevice;
|
|
538
586
|
}
|
|
539
587
|
function connectInner(deviceId, disconnectCallback) {
|
|
588
|
+
const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
|
|
540
589
|
return new Promise(
|
|
541
|
-
(resolve, reject) => ble.connect(
|
|
590
|
+
(resolve, reject) => ble.connect(_deviceId, resolve, (err) => {
|
|
542
591
|
if (toolsSvc.canCommunicateWith(deviceId)) {
|
|
543
592
|
deviceLostConnectionCallback?.(deviceId);
|
|
544
593
|
disconnectCallback(deviceId);
|
|
@@ -549,8 +598,9 @@ function connectInner(deviceId, disconnectCallback) {
|
|
|
549
598
|
}
|
|
550
599
|
async function disconnect(deviceId) {
|
|
551
600
|
for (let attempts = 0; attempts < 3; attempts++) {
|
|
552
|
-
|
|
553
|
-
|
|
601
|
+
const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
|
|
602
|
+
await withTimeout(ble.disconnect(_deviceId), 1e3, "Disconnect timed out");
|
|
603
|
+
const isConnected = await ble.isConnected(_deviceId);
|
|
554
604
|
if (!isConnected) return;
|
|
555
605
|
}
|
|
556
606
|
store.setState(deviceId, void 0);
|
|
@@ -559,7 +609,8 @@ async function disconnect(deviceId) {
|
|
|
559
609
|
async function write(deviceId, serviceUuid, characteristicUuid, value) {
|
|
560
610
|
if (!toolsSvc.canCommunicateWith(deviceId)) throw new Error("Write Error: Not connected to device");
|
|
561
611
|
try {
|
|
562
|
-
|
|
612
|
+
const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
|
|
613
|
+
await ble.writeWithoutResponse(_deviceId, serviceUuid, characteristicUuid, value);
|
|
563
614
|
} catch (e) {
|
|
564
615
|
throw new Error(`Write Error: ${e}`);
|
|
565
616
|
}
|
|
@@ -567,7 +618,8 @@ async function write(deviceId, serviceUuid, characteristicUuid, value) {
|
|
|
567
618
|
async function read(deviceId, serviceUuid, characteristicUuid) {
|
|
568
619
|
if (!toolsSvc.canCommunicateWith(deviceId)) throw new Error("Read Error: Not connected to device");
|
|
569
620
|
try {
|
|
570
|
-
const
|
|
621
|
+
const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
|
|
622
|
+
const value = await ble.read(_deviceId, serviceUuid, characteristicUuid);
|
|
571
623
|
return Array.from(new Uint8Array(value));
|
|
572
624
|
} catch (e) {
|
|
573
625
|
throw new Error(`Read Error: ${e}`);
|
|
@@ -1780,6 +1832,7 @@ const bridgeCommands = {
|
|
|
1780
1832
|
);
|
|
1781
1833
|
return { ...structurized, isFactory: result.isFactory };
|
|
1782
1834
|
},
|
|
1835
|
+
// Zdenek - add structure
|
|
1783
1836
|
async getAxleInfo(deviceId, axleIndex) {
|
|
1784
1837
|
const deviceData = bridgeTools.getBridgeFromStore(deviceId);
|
|
1785
1838
|
if (!___default.inRange(axleIndex, 0, 16)) throw new Error("Error getting an axle");
|
|
@@ -1927,7 +1980,7 @@ const bridgeOtaCommands = {
|
|
|
1927
1980
|
}
|
|
1928
1981
|
};
|
|
1929
1982
|
|
|
1930
|
-
const mtu = 180;
|
|
1983
|
+
const mtu = store.platform === "android" ? 512 : 180;
|
|
1931
1984
|
const bridgeOtaService = {
|
|
1932
1985
|
async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
|
|
1933
1986
|
await delay(2e3);
|
|
@@ -1943,7 +1996,7 @@ const bridgeOtaService = {
|
|
|
1943
1996
|
await bridgeOtaCommands.endOta(deviceId);
|
|
1944
1997
|
progressCallback("Upload completed, disconnecting...", 0.81);
|
|
1945
1998
|
await bridgeOta.disconnect(deviceId);
|
|
1946
|
-
progressCallback("Disconnected...",
|
|
1999
|
+
progressCallback("Disconnected...", 1);
|
|
1947
2000
|
}
|
|
1948
2001
|
};
|
|
1949
2002
|
async function uploadOta(deviceId, firmwareBinary, reportStatus) {
|
|
@@ -2614,18 +2667,23 @@ function createNewTyre(positionId) {
|
|
|
2614
2667
|
}
|
|
2615
2668
|
|
|
2616
2669
|
const bridge = {
|
|
2617
|
-
async connect(deviceId) {
|
|
2670
|
+
async connect(deviceId, accessLevel) {
|
|
2671
|
+
if (canCommunicateWith(deviceId)) return;
|
|
2618
2672
|
await promiseQueue$1.clearQueue("Previous pending commands aborted");
|
|
2619
2673
|
const bridgeMeta = deviceMeta.bridge;
|
|
2620
2674
|
await bluetooth.connect(deviceId, this.disconnect);
|
|
2621
|
-
|
|
2675
|
+
const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
|
|
2676
|
+
if (store.platform !== "ios") {
|
|
2677
|
+
await ble.requestMtu(_deviceId, deviceMeta.bridge.mtu);
|
|
2678
|
+
}
|
|
2622
2679
|
await ble.startNotification(
|
|
2623
|
-
|
|
2680
|
+
_deviceId,
|
|
2624
2681
|
bridgeMeta.communication.serviceId,
|
|
2625
2682
|
bridgeMeta.communication.characteristicId,
|
|
2626
2683
|
(notification) => promiseQueue$1.processMessage(deviceId, notification),
|
|
2627
2684
|
(error) => console.error("startNotification Error", error)
|
|
2628
2685
|
);
|
|
2686
|
+
store.deviceAccessLevel[deviceId] = accessLevel ?? "driver";
|
|
2629
2687
|
await bridgeCommands.sendPinCommand(deviceId);
|
|
2630
2688
|
store.setState(deviceId, "paired");
|
|
2631
2689
|
},
|
|
@@ -3053,7 +3111,8 @@ class BridgeTcVehicleAxle {
|
|
|
3053
3111
|
minTargetPressure;
|
|
3054
3112
|
}
|
|
3055
3113
|
|
|
3056
|
-
function createTirecheckDeviceSdk(bleImplementation) {
|
|
3114
|
+
function createTirecheckDeviceSdk(bleImplementation, platform) {
|
|
3115
|
+
store.platform = platform;
|
|
3057
3116
|
setBleImplementation(bleImplementation);
|
|
3058
3117
|
return {
|
|
3059
3118
|
/** Generic methods common for all devices */
|
package/dist/index.d.cts
CHANGED
|
@@ -66,7 +66,7 @@ declare const _default$1: {
|
|
|
66
66
|
serviceId: string;
|
|
67
67
|
characteristicId: string;
|
|
68
68
|
};
|
|
69
|
-
getDeviceInfoFromAdvertising: (device: PeripheralData) =>
|
|
69
|
+
getDeviceInfoFromAdvertising: (device: PeripheralData) => void | BleDevice;
|
|
70
70
|
};
|
|
71
71
|
flexiGaugeTpms: {
|
|
72
72
|
nameRegex: RegExp;
|
|
@@ -705,6 +705,8 @@ interface BridgeTcVehicle {
|
|
|
705
705
|
id: string;
|
|
706
706
|
};
|
|
707
707
|
}
|
|
708
|
+
type DevicePlatform = 'ios' | 'android' | 'web';
|
|
709
|
+
type BridgeAccessLevel = 'tirecheck' | 'vehicleManufacturer' | 'vehicleDealership' | 'workshop' | 'driver';
|
|
708
710
|
interface BridgeTcTyre {
|
|
709
711
|
mountedOn?: TcTyreMountedOn;
|
|
710
712
|
serialNumber?: string;
|
|
@@ -836,6 +838,9 @@ interface BleFlexiGaugeTpms extends BleDeviceBase {
|
|
|
836
838
|
type: 'flexiGaugeTpms';
|
|
837
839
|
}
|
|
838
840
|
interface BleBridgeOta extends BleDeviceBase {
|
|
841
|
+
advertisingData: {
|
|
842
|
+
bridgeId: string;
|
|
843
|
+
};
|
|
839
844
|
type: 'bridgeOta';
|
|
840
845
|
}
|
|
841
846
|
interface BleBridgeSimulated extends BleBridge {
|
|
@@ -866,7 +871,7 @@ type Wrapper<T extends Record<string, (...args: any) => any>> = {
|
|
|
866
871
|
};
|
|
867
872
|
type ReportStatusFn = (status: string, completionPercentage: number) => void;
|
|
868
873
|
|
|
869
|
-
declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation): {
|
|
874
|
+
declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation, platform: DevicePlatform): {
|
|
870
875
|
/** Generic methods common for all devices */
|
|
871
876
|
bluetooth: {
|
|
872
877
|
onDeviceAdvertising(callback: (device: BleDevice) => void): void;
|
|
@@ -875,14 +880,14 @@ declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation):
|
|
|
875
880
|
onDeviceStateChange(callback: (deviceId: string, state: string | undefined) => void): void;
|
|
876
881
|
scanDevices: (services?: string[], duration?: number) => Promise<void>;
|
|
877
882
|
stopScan(): void;
|
|
878
|
-
connect: (deviceId: string, disconnectCallback: (deviceId: string) => void) => Promise<
|
|
883
|
+
connect: (deviceId: string, disconnectCallback: (deviceId: string) => void) => Promise<void | PeripheralDataExtended>;
|
|
879
884
|
disconnect: (deviceId: string) => Promise<void>;
|
|
880
885
|
write: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer) => Promise<void>;
|
|
881
886
|
read: (deviceId: string, serviceUuid: string, characteristicUuid: string) => Promise<number[]>;
|
|
882
887
|
};
|
|
883
888
|
/** Methods for working with Tirecheck CAN Bridge */
|
|
884
889
|
bridge: {
|
|
885
|
-
connect(deviceId: string): Promise<void>;
|
|
890
|
+
connect(deviceId: string, accessLevel: BridgeAccessLevel): Promise<void>;
|
|
886
891
|
disconnect(deviceId: string): Promise<void>;
|
|
887
892
|
getVehicle: (deviceId: string) => Promise<BridgeTcVehicle>;
|
|
888
893
|
setVehicle: (deviceId: string, tcVehicle: BridgeTcVehicle) => Promise<void>;
|
|
@@ -918,4 +923,4 @@ declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation):
|
|
|
918
923
|
};
|
|
919
924
|
};
|
|
920
925
|
|
|
921
|
-
export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type FgSensorReading, type PositionInfo, type ReportStatusFn, type Wrapper, createTirecheckDeviceSdk };
|
|
926
|
+
export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BridgeAccessLevel, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type DevicePlatform, type FgSensorReading, type PositionInfo, type ReportStatusFn, type Wrapper, createTirecheckDeviceSdk };
|
package/dist/index.d.mts
CHANGED
|
@@ -66,7 +66,7 @@ declare const _default$1: {
|
|
|
66
66
|
serviceId: string;
|
|
67
67
|
characteristicId: string;
|
|
68
68
|
};
|
|
69
|
-
getDeviceInfoFromAdvertising: (device: PeripheralData) =>
|
|
69
|
+
getDeviceInfoFromAdvertising: (device: PeripheralData) => void | BleDevice;
|
|
70
70
|
};
|
|
71
71
|
flexiGaugeTpms: {
|
|
72
72
|
nameRegex: RegExp;
|
|
@@ -705,6 +705,8 @@ interface BridgeTcVehicle {
|
|
|
705
705
|
id: string;
|
|
706
706
|
};
|
|
707
707
|
}
|
|
708
|
+
type DevicePlatform = 'ios' | 'android' | 'web';
|
|
709
|
+
type BridgeAccessLevel = 'tirecheck' | 'vehicleManufacturer' | 'vehicleDealership' | 'workshop' | 'driver';
|
|
708
710
|
interface BridgeTcTyre {
|
|
709
711
|
mountedOn?: TcTyreMountedOn;
|
|
710
712
|
serialNumber?: string;
|
|
@@ -836,6 +838,9 @@ interface BleFlexiGaugeTpms extends BleDeviceBase {
|
|
|
836
838
|
type: 'flexiGaugeTpms';
|
|
837
839
|
}
|
|
838
840
|
interface BleBridgeOta extends BleDeviceBase {
|
|
841
|
+
advertisingData: {
|
|
842
|
+
bridgeId: string;
|
|
843
|
+
};
|
|
839
844
|
type: 'bridgeOta';
|
|
840
845
|
}
|
|
841
846
|
interface BleBridgeSimulated extends BleBridge {
|
|
@@ -866,7 +871,7 @@ type Wrapper<T extends Record<string, (...args: any) => any>> = {
|
|
|
866
871
|
};
|
|
867
872
|
type ReportStatusFn = (status: string, completionPercentage: number) => void;
|
|
868
873
|
|
|
869
|
-
declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation): {
|
|
874
|
+
declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation, platform: DevicePlatform): {
|
|
870
875
|
/** Generic methods common for all devices */
|
|
871
876
|
bluetooth: {
|
|
872
877
|
onDeviceAdvertising(callback: (device: BleDevice) => void): void;
|
|
@@ -875,14 +880,14 @@ declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation):
|
|
|
875
880
|
onDeviceStateChange(callback: (deviceId: string, state: string | undefined) => void): void;
|
|
876
881
|
scanDevices: (services?: string[], duration?: number) => Promise<void>;
|
|
877
882
|
stopScan(): void;
|
|
878
|
-
connect: (deviceId: string, disconnectCallback: (deviceId: string) => void) => Promise<
|
|
883
|
+
connect: (deviceId: string, disconnectCallback: (deviceId: string) => void) => Promise<void | PeripheralDataExtended>;
|
|
879
884
|
disconnect: (deviceId: string) => Promise<void>;
|
|
880
885
|
write: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer) => Promise<void>;
|
|
881
886
|
read: (deviceId: string, serviceUuid: string, characteristicUuid: string) => Promise<number[]>;
|
|
882
887
|
};
|
|
883
888
|
/** Methods for working with Tirecheck CAN Bridge */
|
|
884
889
|
bridge: {
|
|
885
|
-
connect(deviceId: string): Promise<void>;
|
|
890
|
+
connect(deviceId: string, accessLevel: BridgeAccessLevel): Promise<void>;
|
|
886
891
|
disconnect(deviceId: string): Promise<void>;
|
|
887
892
|
getVehicle: (deviceId: string) => Promise<BridgeTcVehicle>;
|
|
888
893
|
setVehicle: (deviceId: string, tcVehicle: BridgeTcVehicle) => Promise<void>;
|
|
@@ -918,4 +923,4 @@ declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation):
|
|
|
918
923
|
};
|
|
919
924
|
};
|
|
920
925
|
|
|
921
|
-
export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type FgSensorReading, type PositionInfo, type ReportStatusFn, type Wrapper, createTirecheckDeviceSdk };
|
|
926
|
+
export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BridgeAccessLevel, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type DevicePlatform, type FgSensorReading, type PositionInfo, type ReportStatusFn, type Wrapper, createTirecheckDeviceSdk };
|
package/dist/index.d.ts
CHANGED
|
@@ -66,7 +66,7 @@ declare const _default$1: {
|
|
|
66
66
|
serviceId: string;
|
|
67
67
|
characteristicId: string;
|
|
68
68
|
};
|
|
69
|
-
getDeviceInfoFromAdvertising: (device: PeripheralData) =>
|
|
69
|
+
getDeviceInfoFromAdvertising: (device: PeripheralData) => void | BleDevice;
|
|
70
70
|
};
|
|
71
71
|
flexiGaugeTpms: {
|
|
72
72
|
nameRegex: RegExp;
|
|
@@ -705,6 +705,8 @@ interface BridgeTcVehicle {
|
|
|
705
705
|
id: string;
|
|
706
706
|
};
|
|
707
707
|
}
|
|
708
|
+
type DevicePlatform = 'ios' | 'android' | 'web';
|
|
709
|
+
type BridgeAccessLevel = 'tirecheck' | 'vehicleManufacturer' | 'vehicleDealership' | 'workshop' | 'driver';
|
|
708
710
|
interface BridgeTcTyre {
|
|
709
711
|
mountedOn?: TcTyreMountedOn;
|
|
710
712
|
serialNumber?: string;
|
|
@@ -836,6 +838,9 @@ interface BleFlexiGaugeTpms extends BleDeviceBase {
|
|
|
836
838
|
type: 'flexiGaugeTpms';
|
|
837
839
|
}
|
|
838
840
|
interface BleBridgeOta extends BleDeviceBase {
|
|
841
|
+
advertisingData: {
|
|
842
|
+
bridgeId: string;
|
|
843
|
+
};
|
|
839
844
|
type: 'bridgeOta';
|
|
840
845
|
}
|
|
841
846
|
interface BleBridgeSimulated extends BleBridge {
|
|
@@ -866,7 +871,7 @@ type Wrapper<T extends Record<string, (...args: any) => any>> = {
|
|
|
866
871
|
};
|
|
867
872
|
type ReportStatusFn = (status: string, completionPercentage: number) => void;
|
|
868
873
|
|
|
869
|
-
declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation): {
|
|
874
|
+
declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation, platform: DevicePlatform): {
|
|
870
875
|
/** Generic methods common for all devices */
|
|
871
876
|
bluetooth: {
|
|
872
877
|
onDeviceAdvertising(callback: (device: BleDevice) => void): void;
|
|
@@ -875,14 +880,14 @@ declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation):
|
|
|
875
880
|
onDeviceStateChange(callback: (deviceId: string, state: string | undefined) => void): void;
|
|
876
881
|
scanDevices: (services?: string[], duration?: number) => Promise<void>;
|
|
877
882
|
stopScan(): void;
|
|
878
|
-
connect: (deviceId: string, disconnectCallback: (deviceId: string) => void) => Promise<
|
|
883
|
+
connect: (deviceId: string, disconnectCallback: (deviceId: string) => void) => Promise<void | PeripheralDataExtended>;
|
|
879
884
|
disconnect: (deviceId: string) => Promise<void>;
|
|
880
885
|
write: (deviceId: string, serviceUuid: string, characteristicUuid: string, value: ArrayBuffer) => Promise<void>;
|
|
881
886
|
read: (deviceId: string, serviceUuid: string, characteristicUuid: string) => Promise<number[]>;
|
|
882
887
|
};
|
|
883
888
|
/** Methods for working with Tirecheck CAN Bridge */
|
|
884
889
|
bridge: {
|
|
885
|
-
connect(deviceId: string): Promise<void>;
|
|
890
|
+
connect(deviceId: string, accessLevel: BridgeAccessLevel): Promise<void>;
|
|
886
891
|
disconnect(deviceId: string): Promise<void>;
|
|
887
892
|
getVehicle: (deviceId: string) => Promise<BridgeTcVehicle>;
|
|
888
893
|
setVehicle: (deviceId: string, tcVehicle: BridgeTcVehicle) => Promise<void>;
|
|
@@ -918,4 +923,4 @@ declare function createTirecheckDeviceSdk(bleImplementation: BleImplementation):
|
|
|
918
923
|
};
|
|
919
924
|
};
|
|
920
925
|
|
|
921
|
-
export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type FgSensorReading, type PositionInfo, type ReportStatusFn, type Wrapper, createTirecheckDeviceSdk };
|
|
926
|
+
export { type BleBridge, type BleBridgeAdvertisingData, type BleBridgeOta, type BleBridgeSimulated, type BleDevice, type BleDeviceBase, type BleDeviceSimulated, type BleDeviceStatus, type BleDeviceType, type BleFlexiGaugeTpms, type BridgeAccessLevel, type BridgeAutolearnStatus, type BridgeCommandStructure, type BridgeCommandStructureProperties, type BridgeCommandStructurized, type BridgeConfiguration, type BridgeReading, type BridgeTcIssue, type BridgeTcTyre, type BridgeTcVehicle, BridgeTcVehicleAxle, type DevicePlatform, type FgSensorReading, type PositionInfo, type ReportStatusFn, type Wrapper, createTirecheckDeviceSdk };
|
package/dist/index.mjs
CHANGED
|
@@ -7,13 +7,17 @@ function setBleImplementation(bleImplementation) {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
const store = {
|
|
10
|
-
platform: "
|
|
10
|
+
platform: "android",
|
|
11
|
+
/** Defines access level for each connection, should be 'driver' as default, Supported roles: ['manufacturer', 'driver'] , Example: F4B4553322: 'manufacturer' */
|
|
12
|
+
deviceAccessLevel: {},
|
|
11
13
|
devices: {},
|
|
12
14
|
simulatedDevices: {},
|
|
13
15
|
/** undefined - no information but since we get advertisings it is most likely disconnected, connecting - trying to connect via bluetooth, connected - connected via bluetooth (can send write and read), paired - all additional connection steps completed (setMtu, sendPin, etc) */
|
|
14
16
|
deviceState: {},
|
|
15
17
|
// undefined => connecting => connected => paired => disconnecting => disconnected
|
|
16
18
|
bridgesReboot: {},
|
|
19
|
+
//** Ios uses generated device Id, bridges send mac address in advertising so internaly we always use mac address but when real device id is needed we check mapping table for it */
|
|
20
|
+
deviceIdMapingTable: {},
|
|
17
21
|
setState(deviceId, state) {
|
|
18
22
|
this.deviceState[deviceId] = state;
|
|
19
23
|
deviceStateChangeCallback?.(deviceId, state);
|
|
@@ -299,9 +303,14 @@ const bridgeAdvertisingParser = {
|
|
|
299
303
|
const adversitingType = getAdvertisingType(device);
|
|
300
304
|
if (adversitingType !== "connectable") return void 0;
|
|
301
305
|
const advertisingData = getAdvertisingData({ advertising: device.advertising, deviceName: device.name });
|
|
302
|
-
const
|
|
306
|
+
const macArray = advertisingData?.macAddress?.map((n) => bridgeTools.decimalToHex(n).toUpperCase()).reverse() || [];
|
|
307
|
+
const bridgeId = macArray.join("");
|
|
303
308
|
const vin = String.fromCharCode(...advertisingData?.vinNum || []).split("\0").join("");
|
|
304
|
-
|
|
309
|
+
const macString = macArray.join(":");
|
|
310
|
+
if (store.platform === "ios") {
|
|
311
|
+
store.deviceIdMapingTable[macString] = device.id;
|
|
312
|
+
}
|
|
313
|
+
return { id: macString, name: device.name, bridgeId, vin, advertisingData, type: "bridge", rssi: device.rssi };
|
|
305
314
|
}
|
|
306
315
|
};
|
|
307
316
|
function getAdvertisingType(device) {
|
|
@@ -391,6 +400,49 @@ function processIosAdvertising(adv, isKrone) {
|
|
|
391
400
|
return advertisingData;
|
|
392
401
|
}
|
|
393
402
|
|
|
403
|
+
const bridgeOtaAdvertisingParser = {
|
|
404
|
+
getDeviceInfoFromAdvertising: (device) => {
|
|
405
|
+
const adv = Array.from(new Uint8Array(device.advertising));
|
|
406
|
+
let deviceId = "";
|
|
407
|
+
let bridgeId = "";
|
|
408
|
+
let processedByteCount = 0;
|
|
409
|
+
if (store.platform === "ios") {
|
|
410
|
+
if (!device.advertising.kCBAdvDataLeBluetoothDeviceAddress)
|
|
411
|
+
return console.warn("No mac address in advertising data");
|
|
412
|
+
const macAddress = Array.from(new Uint8Array(device.advertising.kCBAdvDataLeBluetoothDeviceAddress)).map(
|
|
413
|
+
(x) => bridgeTools.decimalToHex(x).toUpperCase()
|
|
414
|
+
);
|
|
415
|
+
deviceId = macAddress.join(":");
|
|
416
|
+
bridgeId = macAddress.join("");
|
|
417
|
+
} else {
|
|
418
|
+
do {
|
|
419
|
+
const length = adv[processedByteCount];
|
|
420
|
+
const identificator = adv[processedByteCount + 1];
|
|
421
|
+
const packet = adv.slice(processedByteCount, processedByteCount + length + 1);
|
|
422
|
+
if (!length) {
|
|
423
|
+
processedByteCount = adv.length;
|
|
424
|
+
}
|
|
425
|
+
processedByteCount += length + 1;
|
|
426
|
+
if (identificator === 27) {
|
|
427
|
+
const macAddress = packet.slice(-6).reverse().map((x) => bridgeTools.decimalToHex(x).toUpperCase());
|
|
428
|
+
deviceId = macAddress.join(":");
|
|
429
|
+
bridgeId = macAddress.join("");
|
|
430
|
+
processedByteCount = adv.length;
|
|
431
|
+
}
|
|
432
|
+
} while (processedByteCount < adv.length);
|
|
433
|
+
}
|
|
434
|
+
if (!deviceId) return console.warn("Failed to get device Id");
|
|
435
|
+
store.deviceIdMapingTable[deviceId] = device.id;
|
|
436
|
+
const bleDevice = {
|
|
437
|
+
...device,
|
|
438
|
+
id: deviceId,
|
|
439
|
+
advertisingData: { bridgeId },
|
|
440
|
+
type: "bridgeOta"
|
|
441
|
+
};
|
|
442
|
+
return bleDevice;
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
|
|
394
446
|
const deviceMeta = {
|
|
395
447
|
bridge: {
|
|
396
448
|
nameRegex: /(030303|030321)/,
|
|
@@ -408,13 +460,7 @@ const deviceMeta = {
|
|
|
408
460
|
serviceId: "4880c12c-fdcb-4077-8920-a450d7f9b907",
|
|
409
461
|
characteristicId: "fec26ec4-6d71-4442-9f81-55bc21d658d7"
|
|
410
462
|
},
|
|
411
|
-
getDeviceInfoFromAdvertising:
|
|
412
|
-
const bleDevice = {
|
|
413
|
-
...device,
|
|
414
|
-
type: "bridgeOta"
|
|
415
|
-
};
|
|
416
|
-
return bleDevice;
|
|
417
|
-
}
|
|
463
|
+
getDeviceInfoFromAdvertising: bridgeOtaAdvertisingParser.getDeviceInfoFromAdvertising
|
|
418
464
|
},
|
|
419
465
|
flexiGaugeTpms: {
|
|
420
466
|
nameRegex: /Flexi.*/,
|
|
@@ -510,6 +556,7 @@ async function scanDevices(services = [], duration) {
|
|
|
510
556
|
);
|
|
511
557
|
}
|
|
512
558
|
async function connect(deviceId, disconnectCallback) {
|
|
559
|
+
if (toolsSvc.canCommunicateWith(deviceId)) return console.warn("Connect Warn: Already connected to device");
|
|
513
560
|
store.setState(deviceId, "connecting");
|
|
514
561
|
let connectedDevice;
|
|
515
562
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
@@ -521,7 +568,8 @@ async function connect(deviceId, disconnectCallback) {
|
|
|
521
568
|
if (attempt === 3) throw new Error("Connection unsuccessful");
|
|
522
569
|
}
|
|
523
570
|
}
|
|
524
|
-
const
|
|
571
|
+
const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
|
|
572
|
+
const isConnected = await ble.isConnected(_deviceId);
|
|
525
573
|
if (!isConnected) {
|
|
526
574
|
store.setState(deviceId, void 0);
|
|
527
575
|
throw new Error("Connect Error");
|
|
@@ -530,8 +578,9 @@ async function connect(deviceId, disconnectCallback) {
|
|
|
530
578
|
return connectedDevice;
|
|
531
579
|
}
|
|
532
580
|
function connectInner(deviceId, disconnectCallback) {
|
|
581
|
+
const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
|
|
533
582
|
return new Promise(
|
|
534
|
-
(resolve, reject) => ble.connect(
|
|
583
|
+
(resolve, reject) => ble.connect(_deviceId, resolve, (err) => {
|
|
535
584
|
if (toolsSvc.canCommunicateWith(deviceId)) {
|
|
536
585
|
deviceLostConnectionCallback?.(deviceId);
|
|
537
586
|
disconnectCallback(deviceId);
|
|
@@ -542,8 +591,9 @@ function connectInner(deviceId, disconnectCallback) {
|
|
|
542
591
|
}
|
|
543
592
|
async function disconnect(deviceId) {
|
|
544
593
|
for (let attempts = 0; attempts < 3; attempts++) {
|
|
545
|
-
|
|
546
|
-
|
|
594
|
+
const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
|
|
595
|
+
await withTimeout(ble.disconnect(_deviceId), 1e3, "Disconnect timed out");
|
|
596
|
+
const isConnected = await ble.isConnected(_deviceId);
|
|
547
597
|
if (!isConnected) return;
|
|
548
598
|
}
|
|
549
599
|
store.setState(deviceId, void 0);
|
|
@@ -552,7 +602,8 @@ async function disconnect(deviceId) {
|
|
|
552
602
|
async function write(deviceId, serviceUuid, characteristicUuid, value) {
|
|
553
603
|
if (!toolsSvc.canCommunicateWith(deviceId)) throw new Error("Write Error: Not connected to device");
|
|
554
604
|
try {
|
|
555
|
-
|
|
605
|
+
const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
|
|
606
|
+
await ble.writeWithoutResponse(_deviceId, serviceUuid, characteristicUuid, value);
|
|
556
607
|
} catch (e) {
|
|
557
608
|
throw new Error(`Write Error: ${e}`);
|
|
558
609
|
}
|
|
@@ -560,7 +611,8 @@ async function write(deviceId, serviceUuid, characteristicUuid, value) {
|
|
|
560
611
|
async function read(deviceId, serviceUuid, characteristicUuid) {
|
|
561
612
|
if (!toolsSvc.canCommunicateWith(deviceId)) throw new Error("Read Error: Not connected to device");
|
|
562
613
|
try {
|
|
563
|
-
const
|
|
614
|
+
const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
|
|
615
|
+
const value = await ble.read(_deviceId, serviceUuid, characteristicUuid);
|
|
564
616
|
return Array.from(new Uint8Array(value));
|
|
565
617
|
} catch (e) {
|
|
566
618
|
throw new Error(`Read Error: ${e}`);
|
|
@@ -1773,6 +1825,7 @@ const bridgeCommands = {
|
|
|
1773
1825
|
);
|
|
1774
1826
|
return { ...structurized, isFactory: result.isFactory };
|
|
1775
1827
|
},
|
|
1828
|
+
// Zdenek - add structure
|
|
1776
1829
|
async getAxleInfo(deviceId, axleIndex) {
|
|
1777
1830
|
const deviceData = bridgeTools.getBridgeFromStore(deviceId);
|
|
1778
1831
|
if (!_.inRange(axleIndex, 0, 16)) throw new Error("Error getting an axle");
|
|
@@ -1920,7 +1973,7 @@ const bridgeOtaCommands = {
|
|
|
1920
1973
|
}
|
|
1921
1974
|
};
|
|
1922
1975
|
|
|
1923
|
-
const mtu = 180;
|
|
1976
|
+
const mtu = store.platform === "android" ? 512 : 180;
|
|
1924
1977
|
const bridgeOtaService = {
|
|
1925
1978
|
async updateFirmware(deviceId, bootloader, firmware, progressCallback) {
|
|
1926
1979
|
await delay(2e3);
|
|
@@ -1936,7 +1989,7 @@ const bridgeOtaService = {
|
|
|
1936
1989
|
await bridgeOtaCommands.endOta(deviceId);
|
|
1937
1990
|
progressCallback("Upload completed, disconnecting...", 0.81);
|
|
1938
1991
|
await bridgeOta.disconnect(deviceId);
|
|
1939
|
-
progressCallback("Disconnected...",
|
|
1992
|
+
progressCallback("Disconnected...", 1);
|
|
1940
1993
|
}
|
|
1941
1994
|
};
|
|
1942
1995
|
async function uploadOta(deviceId, firmwareBinary, reportStatus) {
|
|
@@ -2607,18 +2660,23 @@ function createNewTyre(positionId) {
|
|
|
2607
2660
|
}
|
|
2608
2661
|
|
|
2609
2662
|
const bridge = {
|
|
2610
|
-
async connect(deviceId) {
|
|
2663
|
+
async connect(deviceId, accessLevel) {
|
|
2664
|
+
if (canCommunicateWith(deviceId)) return;
|
|
2611
2665
|
await promiseQueue$1.clearQueue("Previous pending commands aborted");
|
|
2612
2666
|
const bridgeMeta = deviceMeta.bridge;
|
|
2613
2667
|
await bluetooth.connect(deviceId, this.disconnect);
|
|
2614
|
-
|
|
2668
|
+
const _deviceId = store.deviceIdMapingTable[deviceId] ?? deviceId;
|
|
2669
|
+
if (store.platform !== "ios") {
|
|
2670
|
+
await ble.requestMtu(_deviceId, deviceMeta.bridge.mtu);
|
|
2671
|
+
}
|
|
2615
2672
|
await ble.startNotification(
|
|
2616
|
-
|
|
2673
|
+
_deviceId,
|
|
2617
2674
|
bridgeMeta.communication.serviceId,
|
|
2618
2675
|
bridgeMeta.communication.characteristicId,
|
|
2619
2676
|
(notification) => promiseQueue$1.processMessage(deviceId, notification),
|
|
2620
2677
|
(error) => console.error("startNotification Error", error)
|
|
2621
2678
|
);
|
|
2679
|
+
store.deviceAccessLevel[deviceId] = accessLevel ?? "driver";
|
|
2622
2680
|
await bridgeCommands.sendPinCommand(deviceId);
|
|
2623
2681
|
store.setState(deviceId, "paired");
|
|
2624
2682
|
},
|
|
@@ -3046,7 +3104,8 @@ class BridgeTcVehicleAxle {
|
|
|
3046
3104
|
minTargetPressure;
|
|
3047
3105
|
}
|
|
3048
3106
|
|
|
3049
|
-
function createTirecheckDeviceSdk(bleImplementation) {
|
|
3107
|
+
function createTirecheckDeviceSdk(bleImplementation, platform) {
|
|
3108
|
+
store.platform = platform;
|
|
3050
3109
|
setBleImplementation(bleImplementation);
|
|
3051
3110
|
return {
|
|
3052
3111
|
/** Generic methods common for all devices */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tirecheck-device-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
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",
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
"typecheck": "pnpm tsc --noEmit",
|
|
47
47
|
"lint": "eslint \"{src,test}/**/*.{vue,ts,js}\"",
|
|
48
48
|
"dev": "pnpm install && vitest --ui",
|
|
49
|
-
"dev-server-old": "ts-node ./devServer/devServer.ts",
|
|
50
49
|
"dev-server": "npx --yes listhen -w --ws --open ./devServer/devServer.ts",
|
|
51
50
|
"dev-ngrok": "node --loader ts-node/esm ./devServer/ngrok.mts",
|
|
51
|
+
"npmPublish": "node --loader ts-node/esm ./scripts/npmPublish.mts",
|
|
52
52
|
"build": "unbuild"
|
|
53
53
|
}
|
|
54
54
|
}
|