@tempivo/sensor-beacon 0.4.3 → 0.4.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/CHANGELOG.md +29 -0
- package/README.md +155 -5
- package/android/src/main/java/expo/modules/tempivosensorbeacon/SensorBeaconNative.java +17 -2
- package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/BleConnectCredentials.kt +25 -0
- package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/SdkMeasurementFormat.kt +111 -0
- package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/SensorBleRuntime.kt +21 -12
- package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/SensorBleVendor.kt +28 -0
- package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/SensorModelHint.kt +20 -0
- package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/SensorSdkScanTelemetry.kt +5 -31
- package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/TempivoSensorBeaconDecoder.kt +1 -1
- package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/TempivoSensorBeaconScanner.kt +5 -6
- package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/TempivoSensorBeaconTypes.kt +2 -0
- package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/TempivoSensorQr.kt +20 -1
- package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/TempivoSensorSession.kt +19 -7
- package/dist/connect-helpers.d.ts +52 -0
- package/dist/connect-helpers.js +153 -0
- package/dist/decoder.d.ts +1 -0
- package/dist/decoder.js +7 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +4 -2
- package/dist/model.d.ts +5 -0
- package/dist/model.js +25 -0
- package/dist/native-helpers.js +5 -2
- package/dist/native-module.js +2 -2
- package/dist/native-types.d.ts +2 -0
- package/dist/profile.d.ts +8 -1
- package/dist/profile.js +42 -19
- package/dist/react-native.d.ts +5 -1
- package/dist/react-native.js +3 -1
- package/dist/session-types.d.ts +2 -1
- package/dist/tempivo-sensor-beacon.aar +0 -0
- package/ios/Frameworks/TempivoSensorBridge.xcframework/ios-arm64/TempivoSensorBridge.framework/Headers/TempivoSensorBridge.h +28 -1
- package/ios/Frameworks/TempivoSensorBridge.xcframework/ios-arm64/TempivoSensorBridge.framework/TempivoSensorBridge +0 -0
- package/ios/Frameworks/TempivoSensorBridge.xcframework/ios-arm64-simulator/TempivoSensorBridge.framework/Headers/TempivoSensorBridge.h +28 -1
- package/ios/Frameworks/TempivoSensorBridge.xcframework/ios-arm64-simulator/TempivoSensorBridge.framework/TempivoSensorBridge +0 -0
- package/ios/Sources/TempivoSensorBeacon/TempivoSensorBeaconDecoder.swift +8 -1
- package/ios/Sources/TempivoSensorBeacon/TempivoSensorBeaconScanner.swift +10 -1
- package/ios/Sources/TempivoSensorBeacon/TempivoSensorModelHint.swift +29 -0
- package/ios/Sources/TempivoSensorBeacon/TempivoSensorProfile.swift +37 -13
- package/ios/Sources/TempivoSensorBeacon/TempivoSensorQr.swift +38 -1
- package/ios/Sources/TempivoSensorBeacon/TempivoSensorSession.swift +24 -12
- package/ios/Sources/TempivoSensorBeacon/TempivoSensorSessionTypes.swift +1 -3
- package/ios/TempivoSensorBeaconModule.swift +83 -16
- package/package.json +3 -2
package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/TempivoSensorBeaconTypes.kt
CHANGED
|
@@ -35,6 +35,8 @@ data class TempivoSensorBeaconDevice(
|
|
|
35
35
|
val bluetoothMacAddress: String,
|
|
36
36
|
val serialNumber: String,
|
|
37
37
|
val rssi: Int,
|
|
38
|
+
/** HC7 when advertisement firmware is missing; else inferred from FW major. */
|
|
39
|
+
val model: String = SensorModelHint.DEFAULT_MODEL,
|
|
38
40
|
val telemetry: TempivoSensorBeaconTelemetry?,
|
|
39
41
|
val summary: String?,
|
|
40
42
|
)
|
|
@@ -8,6 +8,8 @@ data class TempivoSensorQr(
|
|
|
8
8
|
val pin: String,
|
|
9
9
|
val model: String?,
|
|
10
10
|
val bluetoothMac: String,
|
|
11
|
+
/** SDK `device.id` from scan when it differs from sticker serial. */
|
|
12
|
+
val deviceId: String? = null,
|
|
11
13
|
)
|
|
12
14
|
|
|
13
15
|
object TempivoSensorQrParser {
|
|
@@ -29,6 +31,15 @@ object TempivoSensorQrParser {
|
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
fun normalizeMac(value: String): String {
|
|
35
|
+
val trimmed = value.trim()
|
|
36
|
+
if (trimmed.contains(':')) {
|
|
37
|
+
val key = normalizeSerial(trimmed.replace(":", ""))
|
|
38
|
+
return bluetoothMacFromSerial(key)
|
|
39
|
+
}
|
|
40
|
+
return bluetoothMacFromSerial(trimmed)
|
|
41
|
+
}
|
|
42
|
+
|
|
32
43
|
fun assertSupportedModel(model: String) {
|
|
33
44
|
val m = model.trim().uppercase(Locale.US).replace("-", "")
|
|
34
45
|
if (m == "HC5") {
|
|
@@ -62,11 +73,19 @@ object TempivoSensorQrParser {
|
|
|
62
73
|
val model = rec.optString("model").trim().ifEmpty { DEFAULT_MODEL }
|
|
63
74
|
assertSupportedModel(model)
|
|
64
75
|
val hex = if (serial.length == 12) serial else serial.takeLast(12)
|
|
76
|
+
val macOverride =
|
|
77
|
+
sequenceOf("bluetoothMac", "bluetoothMacAddress", "mac")
|
|
78
|
+
.mapNotNull { key ->
|
|
79
|
+
rec.optString(key).trim().takeIf { it.isNotEmpty() }
|
|
80
|
+
}
|
|
81
|
+
.firstOrNull()
|
|
82
|
+
val deviceId = rec.optString("deviceId").trim().ifEmpty { null }
|
|
65
83
|
return TempivoSensorQr(
|
|
66
84
|
serial = serial,
|
|
67
85
|
pin = pin,
|
|
68
86
|
model = model,
|
|
69
|
-
bluetoothMac = bluetoothMacFromSerial(hex),
|
|
87
|
+
bluetoothMac = macOverride?.let { normalizeMac(it) } ?: bluetoothMacFromSerial(hex),
|
|
88
|
+
deviceId = deviceId,
|
|
70
89
|
)
|
|
71
90
|
}
|
|
72
91
|
|
|
@@ -15,7 +15,6 @@ class TempivoSensorSession(
|
|
|
15
15
|
) {
|
|
16
16
|
data class TriggerResult(
|
|
17
17
|
val ok: Boolean,
|
|
18
|
-
val supported: Boolean,
|
|
19
18
|
)
|
|
20
19
|
|
|
21
20
|
private val application = context.applicationContext as android.app.Application
|
|
@@ -26,10 +25,16 @@ class TempivoSensorSession(
|
|
|
26
25
|
serial: String,
|
|
27
26
|
bluetoothMac: String,
|
|
28
27
|
pin: String,
|
|
28
|
+
deviceId: String? = null,
|
|
29
29
|
) {
|
|
30
|
-
val
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
val trimmedPin = pin.trim()
|
|
31
|
+
if (trimmedPin.isEmpty()) {
|
|
32
|
+
throw TempivoSensorException(TempivoSensorException.Code.INVALID_PIN, "PIN must be numeric.")
|
|
33
|
+
}
|
|
34
|
+
if (!trimmedPin.matches(Regex("^\\d+$"))) {
|
|
35
|
+
throw TempivoSensorException(TempivoSensorException.Code.INVALID_PIN, "PIN must be numeric.")
|
|
36
|
+
}
|
|
37
|
+
val resolvedDeviceId = deviceId?.trim()?.takeIf { it.isNotEmpty() } ?: serial
|
|
33
38
|
try {
|
|
34
39
|
mutex.withLock {
|
|
35
40
|
SensorBleRuntime.disconnect(session)
|
|
@@ -38,9 +43,9 @@ class TempivoSensorSession(
|
|
|
38
43
|
withContext(Dispatchers.Main) {
|
|
39
44
|
SensorBleRuntime.connect(
|
|
40
45
|
application = application,
|
|
41
|
-
|
|
46
|
+
deviceId = resolvedDeviceId,
|
|
42
47
|
bluetoothMac = bluetoothMac,
|
|
43
|
-
pin =
|
|
48
|
+
pin = trimmedPin,
|
|
44
49
|
)
|
|
45
50
|
}
|
|
46
51
|
}
|
|
@@ -55,8 +60,12 @@ class TempivoSensorSession(
|
|
|
55
60
|
}
|
|
56
61
|
}
|
|
57
62
|
|
|
63
|
+
suspend fun connect(qr: TempivoSensorQr, deviceId: String, bluetoothMac: String) {
|
|
64
|
+
connect(qr.serial, bluetoothMac, qr.pin, deviceId)
|
|
65
|
+
}
|
|
66
|
+
|
|
58
67
|
suspend fun connect(qr: TempivoSensorQr) {
|
|
59
|
-
connect(qr.serial, qr.bluetoothMac, qr.pin)
|
|
68
|
+
connect(qr.serial, qr.bluetoothMac, qr.pin, qr.deviceId)
|
|
60
69
|
}
|
|
61
70
|
|
|
62
71
|
suspend fun disconnect() {
|
|
@@ -92,6 +101,9 @@ class TempivoSensorSession(
|
|
|
92
101
|
return runGatt { SensorBleRuntime.readCalibration(requireSession()) }
|
|
93
102
|
}
|
|
94
103
|
|
|
104
|
+
fun connectBlocking(qr: TempivoSensorQr, deviceId: String, bluetoothMac: String) =
|
|
105
|
+
runBlocking { connect(qr, deviceId, bluetoothMac) }
|
|
106
|
+
|
|
95
107
|
fun connectBlocking(qr: TempivoSensorQr) = runBlocking { connect(qr) }
|
|
96
108
|
|
|
97
109
|
fun disconnectBlocking() = runBlocking { disconnect() }
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { TempivoNativeMeasurement, TempivoSensorBeaconDevice } from './native-types.js';
|
|
2
|
+
import type { TempivoSensorQr } from './session-types.js';
|
|
3
|
+
/** Loose sticker QR parse (same shape as in-app `parseEfentoQrJson`). Returns null on invalid JSON. */
|
|
4
|
+
export type ParsedSensorQrLoose = {
|
|
5
|
+
sn?: string;
|
|
6
|
+
pin?: string;
|
|
7
|
+
model?: string;
|
|
8
|
+
iccid?: string;
|
|
9
|
+
};
|
|
10
|
+
export type SensorStickerModel = 'HC5' | 'HC7';
|
|
11
|
+
export type SensorBleConnectCredentials = {
|
|
12
|
+
resetCode?: number;
|
|
13
|
+
encryptionKey?: string;
|
|
14
|
+
};
|
|
15
|
+
/** PIN / reset code from sticker JSON (`pin` or `resetCode`, string or number). */
|
|
16
|
+
export declare function pinFromSensorQrRecord(rec: Record<string, unknown>): string | undefined;
|
|
17
|
+
/** Parse sticker QR JSON without throwing (invalid → null). */
|
|
18
|
+
export declare function tryParseSensorQrJson(text: string): ParsedSensorQrLoose | null;
|
|
19
|
+
/** Serial from QR scan payload (structured or raw JSON). 12 hex chars or null. */
|
|
20
|
+
export declare function serialHexFromSensorQrScan(data: string | {
|
|
21
|
+
sn?: string;
|
|
22
|
+
raw?: string;
|
|
23
|
+
} | null | undefined): string | null;
|
|
24
|
+
/**
|
|
25
|
+
* True when QR serial is missing/incomplete, or matches selected BLE serial.
|
|
26
|
+
* False when both are 12-hex and differ (wrong sticker for selected device).
|
|
27
|
+
*/
|
|
28
|
+
export declare function sensorQrSerialMatchesSelected(qrSerialHex: string | null | undefined, selectedSerial: string | null | undefined): boolean;
|
|
29
|
+
/** Normalize sticker `model` to HC5/HC7, or null if missing/unknown. */
|
|
30
|
+
export declare function normalizeSensorStickerModel(model: string | undefined | null): SensorStickerModel | null;
|
|
31
|
+
/**
|
|
32
|
+
* Map label PIN to native connect credentials (resetCode + encryptionKey for 5–6 digit codes).
|
|
33
|
+
* Same rules as Tempivo app `resolveEfentoBleConnectCredentialsFromPin`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveSensorBleConnectCredentialsFromPin(pinOrCode: string | undefined | null): SensorBleConnectCredentials;
|
|
36
|
+
export declare function buildSensorQrConnectJson(parts: {
|
|
37
|
+
serial: string;
|
|
38
|
+
pin: string;
|
|
39
|
+
model?: string;
|
|
40
|
+
deviceId?: string;
|
|
41
|
+
}): string;
|
|
42
|
+
/** Build connect JSON from a parsed QR (strict) or loose scan result. */
|
|
43
|
+
export declare function sensorQrConnectJsonFromLoose(loose: ParsedSensorQrLoose, deviceId?: string): string | null;
|
|
44
|
+
type ScanDevicePick = Pick<TempivoSensorBeaconDevice, 'serialNumber' | 'deviceId' | 'bluetoothMacAddress' | 'model' | 'telemetry'>;
|
|
45
|
+
/** Draft QR JSON from a scan row (uses device model / FW hint, keeps existing PIN if provided). */
|
|
46
|
+
export declare function draftSensorQrConnectJsonFromScanDevice(device: ScanDevicePick, pin?: string): string | null;
|
|
47
|
+
/** Merge scan `deviceId` / MAC from a selected row into a parsed QR for connect. */
|
|
48
|
+
export declare function mergeScanTargetIntoSensorQr(qr: TempivoSensorQr, device: ScanDevicePick | null | undefined): TempivoSensorQr;
|
|
49
|
+
/** Parse QR text and attach scan target (deviceId, MAC) when a row is selected. */
|
|
50
|
+
export declare function parseSensorQrForConnect(qrText: string, selectedDevice?: ScanDevicePick | null): TempivoSensorQr;
|
|
51
|
+
export declare function formatSensorReadingLine(reading: Pick<TempivoNativeMeasurement, 'typeHex' | 'text'>): string;
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { sensorModelFromFirmware } from './model.js';
|
|
2
|
+
import { DEFAULT_SENSOR_MODEL, normalizeSensorSerial, parseSensorQrJson } from './qr.js';
|
|
3
|
+
/** PIN / reset code from sticker JSON (`pin` or `resetCode`, string or number). */
|
|
4
|
+
export function pinFromSensorQrRecord(rec) {
|
|
5
|
+
const raw = rec.pin ?? rec.resetCode;
|
|
6
|
+
if (typeof raw === 'string') {
|
|
7
|
+
const t = raw.trim();
|
|
8
|
+
return t.length > 0 ? t : undefined;
|
|
9
|
+
}
|
|
10
|
+
if (typeof raw === 'number' && Number.isFinite(raw)) {
|
|
11
|
+
return String(Math.trunc(raw));
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
function serialFromQrRecord(rec) {
|
|
16
|
+
if (typeof rec.sn === 'string')
|
|
17
|
+
return rec.sn;
|
|
18
|
+
if (typeof rec.sn === 'number' && Number.isFinite(rec.sn))
|
|
19
|
+
return String(Math.trunc(rec.sn));
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
/** Parse sticker QR JSON without throwing (invalid → null). */
|
|
23
|
+
export function tryParseSensorQrJson(text) {
|
|
24
|
+
try {
|
|
25
|
+
const o = JSON.parse(text.trim());
|
|
26
|
+
if (o === null || typeof o !== 'object' || Array.isArray(o))
|
|
27
|
+
return null;
|
|
28
|
+
const rec = o;
|
|
29
|
+
return {
|
|
30
|
+
sn: serialFromQrRecord(rec),
|
|
31
|
+
pin: pinFromSensorQrRecord(rec),
|
|
32
|
+
model: typeof rec.model === 'string' ? rec.model : undefined,
|
|
33
|
+
iccid: typeof rec.iccid === 'string' ? rec.iccid : undefined,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Serial from QR scan payload (structured or raw JSON). 12 hex chars or null. */
|
|
41
|
+
export function serialHexFromSensorQrScan(data) {
|
|
42
|
+
if (data == null)
|
|
43
|
+
return null;
|
|
44
|
+
let sn;
|
|
45
|
+
if (typeof data === 'string') {
|
|
46
|
+
sn = tryParseSensorQrJson(data)?.sn;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
sn = data.sn?.trim() || (typeof data.raw === 'string' ? tryParseSensorQrJson(data.raw)?.sn : undefined);
|
|
50
|
+
}
|
|
51
|
+
if (!sn)
|
|
52
|
+
return null;
|
|
53
|
+
const hex = normalizeSensorSerial(sn);
|
|
54
|
+
return hex.length === 12 ? hex : null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* True when QR serial is missing/incomplete, or matches selected BLE serial.
|
|
58
|
+
* False when both are 12-hex and differ (wrong sticker for selected device).
|
|
59
|
+
*/
|
|
60
|
+
export function sensorQrSerialMatchesSelected(qrSerialHex, selectedSerial) {
|
|
61
|
+
const qr = normalizeSensorSerial(qrSerialHex ?? '');
|
|
62
|
+
const sel = normalizeSensorSerial(selectedSerial ?? '');
|
|
63
|
+
if (qr.length !== 12 || sel.length !== 12)
|
|
64
|
+
return true;
|
|
65
|
+
return qr === sel;
|
|
66
|
+
}
|
|
67
|
+
/** Normalize sticker `model` to HC5/HC7, or null if missing/unknown. */
|
|
68
|
+
export function normalizeSensorStickerModel(model) {
|
|
69
|
+
if (model == null || model.trim() === '')
|
|
70
|
+
return null;
|
|
71
|
+
const m = model.trim().toUpperCase().replace(/-/g, '');
|
|
72
|
+
if (m === 'HC5')
|
|
73
|
+
return 'HC5';
|
|
74
|
+
if (m === 'HC7')
|
|
75
|
+
return 'HC7';
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Map label PIN to native connect credentials (resetCode + encryptionKey for 5–6 digit codes).
|
|
80
|
+
* Same rules as Tempivo app `resolveEfentoBleConnectCredentialsFromPin`.
|
|
81
|
+
*/
|
|
82
|
+
export function resolveSensorBleConnectCredentialsFromPin(pinOrCode) {
|
|
83
|
+
const pin = pinOrCode?.trim() ?? '';
|
|
84
|
+
if (!pin)
|
|
85
|
+
return {};
|
|
86
|
+
if (!/^\d+$/.test(pin)) {
|
|
87
|
+
return { encryptionKey: pin };
|
|
88
|
+
}
|
|
89
|
+
const parsed = Number.parseInt(pin, 10);
|
|
90
|
+
if (Number.isNaN(parsed) || parsed < 0) {
|
|
91
|
+
return { encryptionKey: pin };
|
|
92
|
+
}
|
|
93
|
+
const cred = { resetCode: parsed };
|
|
94
|
+
if (pin.length > 4 || pin.startsWith('0')) {
|
|
95
|
+
cred.encryptionKey = pin;
|
|
96
|
+
}
|
|
97
|
+
return cred;
|
|
98
|
+
}
|
|
99
|
+
export function buildSensorQrConnectJson(parts) {
|
|
100
|
+
const body = {
|
|
101
|
+
sn: parts.serial,
|
|
102
|
+
pin: parts.pin,
|
|
103
|
+
model: parts.model ?? DEFAULT_SENSOR_MODEL,
|
|
104
|
+
};
|
|
105
|
+
if (parts.deviceId?.trim())
|
|
106
|
+
body.deviceId = parts.deviceId.trim();
|
|
107
|
+
return JSON.stringify(body);
|
|
108
|
+
}
|
|
109
|
+
/** Build connect JSON from a parsed QR (strict) or loose scan result. */
|
|
110
|
+
export function sensorQrConnectJsonFromLoose(loose, deviceId) {
|
|
111
|
+
if (!loose.sn?.trim() || !loose.pin?.trim())
|
|
112
|
+
return null;
|
|
113
|
+
return buildSensorQrConnectJson({
|
|
114
|
+
serial: loose.sn.trim(),
|
|
115
|
+
pin: loose.pin.trim(),
|
|
116
|
+
model: loose.model,
|
|
117
|
+
deviceId,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/** Draft QR JSON from a scan row (uses device model / FW hint, keeps existing PIN if provided). */
|
|
121
|
+
export function draftSensorQrConnectJsonFromScanDevice(device, pin = '111111') {
|
|
122
|
+
const serial = device.serialNumber?.trim();
|
|
123
|
+
if (!serial)
|
|
124
|
+
return null;
|
|
125
|
+
const fw = device.telemetry?.firmware ?? null;
|
|
126
|
+
const model = normalizeSensorStickerModel(device.model ?? undefined) ??
|
|
127
|
+
sensorModelFromFirmware(fw);
|
|
128
|
+
return buildSensorQrConnectJson({
|
|
129
|
+
serial,
|
|
130
|
+
pin,
|
|
131
|
+
model,
|
|
132
|
+
deviceId: device.deviceId,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/** Merge scan `deviceId` / MAC from a selected row into a parsed QR for connect. */
|
|
136
|
+
export function mergeScanTargetIntoSensorQr(qr, device) {
|
|
137
|
+
if (!device)
|
|
138
|
+
return qr;
|
|
139
|
+
const mac = device.bluetoothMacAddress?.includes(':') ? device.bluetoothMacAddress : qr.bluetoothMac;
|
|
140
|
+
return {
|
|
141
|
+
...qr,
|
|
142
|
+
deviceId: device.deviceId || qr.deviceId,
|
|
143
|
+
bluetoothMac: mac ?? qr.bluetoothMac,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/** Parse QR text and attach scan target (deviceId, MAC) when a row is selected. */
|
|
147
|
+
export function parseSensorQrForConnect(qrText, selectedDevice) {
|
|
148
|
+
const qr = parseSensorQrJson(qrText);
|
|
149
|
+
return mergeScanTargetIntoSensorQr(qr, selectedDevice);
|
|
150
|
+
}
|
|
151
|
+
export function formatSensorReadingLine(reading) {
|
|
152
|
+
return `${reading.typeHex}: ${reading.text}`;
|
|
153
|
+
}
|
package/dist/decoder.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { SensorBeaconReading } from './types.js';
|
|
|
2
2
|
export declare const TEMPVO_SENSOR_MANUFACTURER_ID = 620;
|
|
3
3
|
/** FW6 `0x03` advertisement frame length (bytes after company id). */
|
|
4
4
|
export declare const ADV_FRAME_03_LEN = 22;
|
|
5
|
+
export declare function measurementTypeLabel(mtype: number): string;
|
|
5
6
|
export declare function decodeMeasurementSlot(mtype: number, raw24: number): string;
|
|
6
7
|
export declare function serialKeyFromAdv03Frame(frame: Uint8Array): string | null;
|
|
7
8
|
export declare function macKeyFromAddress(macWithColons: string): string;
|
package/dist/decoder.js
CHANGED
|
@@ -44,6 +44,12 @@ function unitForType(mtype) {
|
|
|
44
44
|
return '';
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
export function measurementTypeLabel(mtype) {
|
|
48
|
+
const spec = MEASURE_SPECS.get(mtype);
|
|
49
|
+
if (spec)
|
|
50
|
+
return spec.name.toLowerCase();
|
|
51
|
+
return `type_${mtype.toString(16).padStart(2, '0')}`;
|
|
52
|
+
}
|
|
47
53
|
export function decodeMeasurementSlot(mtype, raw24) {
|
|
48
54
|
const spec = MEASURE_SPECS.get(mtype);
|
|
49
55
|
if (!spec) {
|
|
@@ -200,7 +206,7 @@ function parseScan04(frame) {
|
|
|
200
206
|
summaryParts.push(text);
|
|
201
207
|
measurements.push({
|
|
202
208
|
typeId: mtype,
|
|
203
|
-
typeHex:
|
|
209
|
+
typeHex: measurementTypeLabel(mtype),
|
|
204
210
|
raw24: raw24 & 0xffffff,
|
|
205
211
|
text,
|
|
206
212
|
...parsedValuesFromSlot(mtype, raw24),
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
export { ADV_FRAME_03_LEN, TEMPVO_SENSOR_MANUFACTURER_ID, buildSensorBeaconReading, decodeMeasurementSlot, decodeSensorBeaconPayload, lookupDeviceKeys, macKeyFromAddress, serialKeyFromAdv03Frame, splitSensorBeaconFrames, } from './decoder.js';
|
|
1
|
+
export { ADV_FRAME_03_LEN, TEMPVO_SENSOR_MANUFACTURER_ID, buildSensorBeaconReading, decodeMeasurementSlot, decodeSensorBeaconPayload, lookupDeviceKeys, macKeyFromAddress, measurementTypeLabel, serialKeyFromAdv03Frame, splitSensorBeaconFrames, } from './decoder.js';
|
|
2
2
|
export { ingestManufacturerPayload } from './ingest.js';
|
|
3
3
|
export { dataViewToUint8Array, manufacturerPayloadsFromScanRecordBytes, normalizeManufacturerBytes } from './normalize.js';
|
|
4
4
|
export { MEASURE_SPECS, type MeasureSpec } from './measure-specs.js';
|
|
5
5
|
export { createSensorBeaconFrameCache, type SensorBeaconFrameCache, type SensorBeaconMeasurement, type SensorBeaconReading, } from './types.js';
|
|
6
6
|
export { TempivoSensorError, type TempivoSensorErrorCode } from './errors.js';
|
|
7
7
|
export { DEFAULT_SENSOR_MODEL, assertSupportedSensorModel, bluetoothMacFromSerial, normalizeSensorSerial, encodeSensorPinPayload, parseSensorQrJson, sessionTypeFromModel, } from './qr.js';
|
|
8
|
+
export { isMissingAdvertisementFirmware, sensorModelFromFirmware, } from './model.js';
|
|
9
|
+
export type { SensorStickerModel } from './model.js';
|
|
10
|
+
export { buildSensorQrConnectJson, draftSensorQrConnectJsonFromScanDevice, formatSensorReadingLine, mergeScanTargetIntoSensorQr, normalizeSensorStickerModel, parseSensorQrForConnect, pinFromSensorQrRecord, resolveSensorBleConnectCredentialsFromPin, sensorQrConnectJsonFromLoose, sensorQrSerialMatchesSelected, serialHexFromSensorQrScan, tryParseSensorQrJson, } from './connect-helpers.js';
|
|
11
|
+
export type { ParsedSensorQrLoose, SensorBleConnectCredentials, } from './connect-helpers.js';
|
|
8
12
|
export { calibrationFromExtendedJson, decodeLaboratoryCalibrationTimestamp, } from './calibration.js';
|
|
9
|
-
export { BLE_MAX_MEASUREMENT_INTERVAL_MINUTES, BLE_MAX_TRANSMISSION_INTERVAL_SECONDS, BLE_MIN_MEASUREMENT_INTERVAL_MINUTES, BLE_MIN_TRANSMISSION_INTERVAL_SECONDS, DEFAULT_ALERT_HYSTERESIS_C, compileSensorProfileToBleJson, configurationFromApiProfile, parseSensorConfiguration, parseSensorConfigurationJson, pickPartnerConfigurationJson, } from './profile.js';
|
|
13
|
+
export { BLE_MAX_MEASUREMENT_INTERVAL_MINUTES, BLE_MAX_TRANSMISSION_INTERVAL_SECONDS, BLE_MIN_MEASUREMENT_INTERVAL_MINUTES, BLE_MIN_TRANSMISSION_INTERVAL_SECONDS, DEFAULT_ALERT_HYSTERESIS_C, compileSensorProfileToBleJson, configurationFromApiProfile, parseSensorConfiguration, parseSensorConfigurationFromDevice, parseSensorConfigurationFromDeviceJson, parseSensorConfigurationJson, pickPartnerConfigurationJson, } from './profile.js';
|
|
10
14
|
export type { TempivoSchedule, TempivoScheduleAlways, TempivoScheduleWeek, TempivoSensorCalibration, TempivoSensorConfiguration, TempivoSensorQr, TempivoSensorSessionType, TempivoTemperatureAlert, TempivoTemperatureChannel, TempivoTemperatureMaxAlert, TempivoTemperatureMinAlert, TempivoTemperatureRangeAlert, TempivoTriggerTransmissionResult, } from './session-types.js';
|
|
11
15
|
export { addDeviceFoundListener, connect, disconnect, getCalibration, getConfiguration, isNativeSensorBeaconAvailable, isScanning, requestPermissions, setConfigurationJson, startScan, stopScan, triggerTransmission, } from './native-bridge.js';
|
|
12
16
|
export type { TempivoDeviceFoundSubscription, TempivoNativeCalibration, TempivoNativeMeasurement, TempivoNativePermissionResponse, TempivoNativePermissionStatus, TempivoNativeQr, TempivoNativeTelemetry, TempivoSensorBeaconDevice, } from './native-types.js';
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
export { ADV_FRAME_03_LEN, TEMPVO_SENSOR_MANUFACTURER_ID, buildSensorBeaconReading, decodeMeasurementSlot, decodeSensorBeaconPayload, lookupDeviceKeys, macKeyFromAddress, serialKeyFromAdv03Frame, splitSensorBeaconFrames, } from './decoder.js';
|
|
1
|
+
export { ADV_FRAME_03_LEN, TEMPVO_SENSOR_MANUFACTURER_ID, buildSensorBeaconReading, decodeMeasurementSlot, decodeSensorBeaconPayload, lookupDeviceKeys, macKeyFromAddress, measurementTypeLabel, serialKeyFromAdv03Frame, splitSensorBeaconFrames, } from './decoder.js';
|
|
2
2
|
export { ingestManufacturerPayload } from './ingest.js';
|
|
3
3
|
export { dataViewToUint8Array, manufacturerPayloadsFromScanRecordBytes, normalizeManufacturerBytes } from './normalize.js';
|
|
4
4
|
export { MEASURE_SPECS } from './measure-specs.js';
|
|
5
5
|
export { createSensorBeaconFrameCache, } from './types.js';
|
|
6
6
|
export { TempivoSensorError } from './errors.js';
|
|
7
7
|
export { DEFAULT_SENSOR_MODEL, assertSupportedSensorModel, bluetoothMacFromSerial, normalizeSensorSerial, encodeSensorPinPayload, parseSensorQrJson, sessionTypeFromModel, } from './qr.js';
|
|
8
|
+
export { isMissingAdvertisementFirmware, sensorModelFromFirmware, } from './model.js';
|
|
9
|
+
export { buildSensorQrConnectJson, draftSensorQrConnectJsonFromScanDevice, formatSensorReadingLine, mergeScanTargetIntoSensorQr, normalizeSensorStickerModel, parseSensorQrForConnect, pinFromSensorQrRecord, resolveSensorBleConnectCredentialsFromPin, sensorQrConnectJsonFromLoose, sensorQrSerialMatchesSelected, serialHexFromSensorQrScan, tryParseSensorQrJson, } from './connect-helpers.js';
|
|
8
10
|
export { calibrationFromExtendedJson, decodeLaboratoryCalibrationTimestamp, } from './calibration.js';
|
|
9
|
-
export { BLE_MAX_MEASUREMENT_INTERVAL_MINUTES, BLE_MAX_TRANSMISSION_INTERVAL_SECONDS, BLE_MIN_MEASUREMENT_INTERVAL_MINUTES, BLE_MIN_TRANSMISSION_INTERVAL_SECONDS, DEFAULT_ALERT_HYSTERESIS_C, compileSensorProfileToBleJson, configurationFromApiProfile, parseSensorConfiguration, parseSensorConfigurationJson, pickPartnerConfigurationJson, } from './profile.js';
|
|
11
|
+
export { BLE_MAX_MEASUREMENT_INTERVAL_MINUTES, BLE_MAX_TRANSMISSION_INTERVAL_SECONDS, BLE_MIN_MEASUREMENT_INTERVAL_MINUTES, BLE_MIN_TRANSMISSION_INTERVAL_SECONDS, DEFAULT_ALERT_HYSTERESIS_C, compileSensorProfileToBleJson, configurationFromApiProfile, parseSensorConfiguration, parseSensorConfigurationFromDevice, parseSensorConfigurationFromDeviceJson, parseSensorConfigurationJson, pickPartnerConfigurationJson, } from './profile.js';
|
|
10
12
|
export { addDeviceFoundListener, connect, disconnect, getCalibration, getConfiguration, isNativeSensorBeaconAvailable, isScanning, requestPermissions, setConfigurationJson, startScan, stopScan, triggerTransmission, } from './native-bridge.js';
|
package/dist/model.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type SensorStickerModel = 'HC5' | 'HC7';
|
|
2
|
+
/** True when advertisement has no usable firmware semver (incl. SDK placeholder `0.0.0`). */
|
|
3
|
+
export declare function isMissingAdvertisementFirmware(firmware: string | null | undefined): boolean;
|
|
4
|
+
/** Product hint from firmware only. Missing FW → HC7. */
|
|
5
|
+
export declare function sensorModelFromFirmware(firmware: string | null | undefined): SensorStickerModel;
|
package/dist/model.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DEFAULT_SENSOR_MODEL } from './qr.js';
|
|
2
|
+
/** True when advertisement has no usable firmware semver (incl. SDK placeholder `0.0.0`). */
|
|
3
|
+
export function isMissingAdvertisementFirmware(firmware) {
|
|
4
|
+
const t = firmware?.trim() ?? '';
|
|
5
|
+
return t.length === 0 || t === '0.0.0';
|
|
6
|
+
}
|
|
7
|
+
/** Product hint from firmware only. Missing FW → HC7. */
|
|
8
|
+
export function sensorModelFromFirmware(firmware) {
|
|
9
|
+
if (isMissingAdvertisementFirmware(firmware))
|
|
10
|
+
return DEFAULT_SENSOR_MODEL;
|
|
11
|
+
const t = firmware.trim();
|
|
12
|
+
if (/^FW\s*5/i.test(t))
|
|
13
|
+
return 'HC5';
|
|
14
|
+
const m = /(?:^FW\s*)?(\d+)\.\d+/i.exec(t);
|
|
15
|
+
if (!m)
|
|
16
|
+
return DEFAULT_SENSOR_MODEL;
|
|
17
|
+
const major = Number(m[1]);
|
|
18
|
+
if (!Number.isFinite(major))
|
|
19
|
+
return DEFAULT_SENSOR_MODEL;
|
|
20
|
+
if (major >= 7)
|
|
21
|
+
return 'HC7';
|
|
22
|
+
if (major >= 1)
|
|
23
|
+
return 'HC5';
|
|
24
|
+
return DEFAULT_SENSOR_MODEL;
|
|
25
|
+
}
|
package/dist/native-helpers.js
CHANGED
|
@@ -12,11 +12,14 @@ const SENSOR_CODES = [
|
|
|
12
12
|
export function qrToConnectJson(qr) {
|
|
13
13
|
if (typeof qr === 'string')
|
|
14
14
|
return qr;
|
|
15
|
-
|
|
15
|
+
const body = {
|
|
16
16
|
sn: qr.serial,
|
|
17
17
|
pin: qr.pin,
|
|
18
18
|
model: qr.model ?? 'HC7',
|
|
19
|
-
}
|
|
19
|
+
};
|
|
20
|
+
if (qr.deviceId)
|
|
21
|
+
body.deviceId = qr.deviceId;
|
|
22
|
+
return JSON.stringify(body);
|
|
20
23
|
}
|
|
21
24
|
export function configToJson(config) {
|
|
22
25
|
return typeof config === 'string' ? config : JSON.stringify(config);
|
package/dist/native-module.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { requireOptionalNativeModule } from 'expo-modules-core';
|
|
2
2
|
import { TempivoSensorError } from './errors.js';
|
|
3
3
|
import { configToJson, mapNativeError, qrToConnectJson } from './native-helpers.js';
|
|
4
|
-
import {
|
|
4
|
+
import { parseSensorConfigurationFromDeviceJson } from './profile.js';
|
|
5
5
|
function getNative() {
|
|
6
6
|
const native = requireOptionalNativeModule('TempivoSensorBeacon');
|
|
7
7
|
if (!native) {
|
|
@@ -76,7 +76,7 @@ export async function disconnect() {
|
|
|
76
76
|
export async function getConfiguration() {
|
|
77
77
|
try {
|
|
78
78
|
const json = await getNative().getConfigurationJson();
|
|
79
|
-
return
|
|
79
|
+
return parseSensorConfigurationFromDeviceJson(json);
|
|
80
80
|
}
|
|
81
81
|
catch (error) {
|
|
82
82
|
throw mapNativeError(error);
|
package/dist/native-types.d.ts
CHANGED
|
@@ -27,6 +27,8 @@ export type TempivoNativeTelemetry = {
|
|
|
27
27
|
export type TempivoSensorBeaconDevice = {
|
|
28
28
|
deviceId: string;
|
|
29
29
|
rssi: number;
|
|
30
|
+
/** HC7 when advertisement firmware is missing; else inferred from FW major. */
|
|
31
|
+
model?: string;
|
|
30
32
|
bluetoothMacAddress?: string | null;
|
|
31
33
|
serialNumber?: string | null;
|
|
32
34
|
summary?: string | null;
|
package/dist/profile.d.ts
CHANGED
|
@@ -6,10 +6,17 @@ export declare const BLE_MIN_MEASUREMENT_INTERVAL_MINUTES = 60;
|
|
|
6
6
|
export declare const BLE_MAX_MEASUREMENT_INTERVAL_MINUTES = 600;
|
|
7
7
|
export declare const BLE_MIN_TRANSMISSION_INTERVAL_SECONDS = 3600;
|
|
8
8
|
export declare const BLE_MAX_TRANSMISSION_INTERVAL_SECONDS = 604800;
|
|
9
|
+
export type ParseSensorConfigurationOptions = {
|
|
10
|
+
/** When true, accept intervals outside partner API limits (device readback). Default false. */
|
|
11
|
+
fromDevice?: boolean;
|
|
12
|
+
};
|
|
9
13
|
/** Validate Cellular API config-profile JSON for BLE setConfiguration. */
|
|
10
|
-
export declare function parseSensorConfiguration(input: unknown): TempivoSensorConfiguration;
|
|
14
|
+
export declare function parseSensorConfiguration(input: unknown, options?: ParseSensorConfigurationOptions): TempivoSensorConfiguration;
|
|
15
|
+
/** Parse configuration read from the device (intervals may be below partner API minimums). */
|
|
16
|
+
export declare function parseSensorConfigurationFromDevice(input: unknown): TempivoSensorConfiguration;
|
|
11
17
|
/** Same as {@link parseSensorConfiguration}: GET `{ profile }` or the profile object. */
|
|
12
18
|
export declare const configurationFromApiProfile: typeof parseSensorConfiguration;
|
|
13
19
|
export declare function parseSensorConfigurationJson(json: string): TempivoSensorConfiguration;
|
|
20
|
+
export declare function parseSensorConfigurationFromDeviceJson(json: string): TempivoSensorConfiguration;
|
|
14
21
|
export declare function compileSensorProfileToBleJson(input: unknown): string;
|
|
15
22
|
export declare function pickPartnerConfigurationJson(json: string): string;
|
package/dist/profile.js
CHANGED
|
@@ -195,18 +195,21 @@ export const BLE_MIN_MEASUREMENT_INTERVAL_MINUTES = 60;
|
|
|
195
195
|
export const BLE_MAX_MEASUREMENT_INTERVAL_MINUTES = 600;
|
|
196
196
|
export const BLE_MIN_TRANSMISSION_INTERVAL_SECONDS = 3600;
|
|
197
197
|
export const BLE_MAX_TRANSMISSION_INTERVAL_SECONDS = 604_800;
|
|
198
|
-
function parseOptionalIntervals(body) {
|
|
198
|
+
function parseOptionalIntervals(body, options = {}) {
|
|
199
|
+
const validatePartnerLimits = !options.fromDevice;
|
|
199
200
|
const out = {};
|
|
200
201
|
if (body.measurementIntervalMinutes !== undefined) {
|
|
201
202
|
const n = parseFiniteNumber(body.measurementIntervalMinutes);
|
|
202
203
|
if (n === undefined || !Number.isFinite(n) || n <= 0) {
|
|
203
204
|
throw new TempivoSensorError('invalidConfig', 'measurementIntervalMinutes must be a positive number.');
|
|
204
205
|
}
|
|
205
|
-
if (
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
206
|
+
if (validatePartnerLimits) {
|
|
207
|
+
if (n < BLE_MIN_MEASUREMENT_INTERVAL_MINUTES) {
|
|
208
|
+
throw new TempivoSensorError('invalidConfig', `measurementIntervalMinutes must be at least ${BLE_MIN_MEASUREMENT_INTERVAL_MINUTES} (1 hour).`);
|
|
209
|
+
}
|
|
210
|
+
if (n > BLE_MAX_MEASUREMENT_INTERVAL_MINUTES) {
|
|
211
|
+
throw new TempivoSensorError('invalidConfig', `measurementIntervalMinutes must be at most ${BLE_MAX_MEASUREMENT_INTERVAL_MINUTES}.`);
|
|
212
|
+
}
|
|
210
213
|
}
|
|
211
214
|
out.measurementIntervalMinutes = n;
|
|
212
215
|
}
|
|
@@ -215,15 +218,18 @@ function parseOptionalIntervals(body) {
|
|
|
215
218
|
if (n === undefined || !Number.isInteger(n) || n <= 0) {
|
|
216
219
|
throw new TempivoSensorError('invalidConfig', 'transmissionIntervalSeconds must be a positive integer.');
|
|
217
220
|
}
|
|
218
|
-
if (
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
if (validatePartnerLimits) {
|
|
222
|
+
if (n < BLE_MIN_TRANSMISSION_INTERVAL_SECONDS) {
|
|
223
|
+
throw new TempivoSensorError('invalidConfig', `transmissionIntervalSeconds must be at least ${BLE_MIN_TRANSMISSION_INTERVAL_SECONDS} (1 hour).`);
|
|
224
|
+
}
|
|
225
|
+
if (n > BLE_MAX_TRANSMISSION_INTERVAL_SECONDS) {
|
|
226
|
+
throw new TempivoSensorError('invalidConfig', `transmissionIntervalSeconds must be at most ${BLE_MAX_TRANSMISSION_INTERVAL_SECONDS}.`);
|
|
227
|
+
}
|
|
223
228
|
}
|
|
224
229
|
out.transmissionIntervalSeconds = n;
|
|
225
230
|
}
|
|
226
|
-
if (
|
|
231
|
+
if (validatePartnerLimits &&
|
|
232
|
+
out.measurementIntervalMinutes != null &&
|
|
227
233
|
out.transmissionIntervalSeconds != null) {
|
|
228
234
|
const maxTx = out.measurementIntervalMinutes * 60 * 60;
|
|
229
235
|
if (out.transmissionIntervalSeconds > maxTx) {
|
|
@@ -232,12 +238,7 @@ function parseOptionalIntervals(body) {
|
|
|
232
238
|
}
|
|
233
239
|
return out;
|
|
234
240
|
}
|
|
235
|
-
|
|
236
|
-
export function parseSensorConfiguration(input) {
|
|
237
|
-
if (!isRecord(input)) {
|
|
238
|
-
throw new TempivoSensorError('invalidConfig', 'Configuration must be a JSON object.');
|
|
239
|
-
}
|
|
240
|
-
const body = unwrapApiProfile(input);
|
|
241
|
+
function parseSensorConfigurationBody(body, options = {}) {
|
|
241
242
|
rejectWireAlarmRules(body);
|
|
242
243
|
const alertsRaw = body.temperatureAlerts;
|
|
243
244
|
if (alertsRaw !== undefined && !Array.isArray(alertsRaw)) {
|
|
@@ -245,13 +246,25 @@ export function parseSensorConfiguration(input) {
|
|
|
245
246
|
}
|
|
246
247
|
const temperatureAlerts = (alertsRaw ?? []).map((item, i) => parseAlert(item, i));
|
|
247
248
|
assertAlertSlotBudget(temperatureAlerts);
|
|
248
|
-
const intervals = parseOptionalIntervals(body);
|
|
249
|
+
const intervals = parseOptionalIntervals(body, options);
|
|
249
250
|
return {
|
|
250
251
|
temperatureAlerts,
|
|
251
252
|
schedule: parseSchedule(body.schedule),
|
|
252
253
|
...intervals,
|
|
253
254
|
};
|
|
254
255
|
}
|
|
256
|
+
/** Validate Cellular API config-profile JSON for BLE setConfiguration. */
|
|
257
|
+
export function parseSensorConfiguration(input, options = {}) {
|
|
258
|
+
if (!isRecord(input)) {
|
|
259
|
+
throw new TempivoSensorError('invalidConfig', 'Configuration must be a JSON object.');
|
|
260
|
+
}
|
|
261
|
+
const body = unwrapApiProfile(input);
|
|
262
|
+
return parseSensorConfigurationBody(body, options);
|
|
263
|
+
}
|
|
264
|
+
/** Parse configuration read from the device (intervals may be below partner API minimums). */
|
|
265
|
+
export function parseSensorConfigurationFromDevice(input) {
|
|
266
|
+
return parseSensorConfiguration(input, { fromDevice: true });
|
|
267
|
+
}
|
|
255
268
|
/** Same as {@link parseSensorConfiguration}: GET `{ profile }` or the profile object. */
|
|
256
269
|
export const configurationFromApiProfile = parseSensorConfiguration;
|
|
257
270
|
export function parseSensorConfigurationJson(json) {
|
|
@@ -264,6 +277,16 @@ export function parseSensorConfigurationJson(json) {
|
|
|
264
277
|
}
|
|
265
278
|
return parseSensorConfiguration(parsed);
|
|
266
279
|
}
|
|
280
|
+
export function parseSensorConfigurationFromDeviceJson(json) {
|
|
281
|
+
let parsed;
|
|
282
|
+
try {
|
|
283
|
+
parsed = JSON.parse(json);
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
throw new TempivoSensorError('invalidConfig', 'Configuration is not valid JSON.');
|
|
287
|
+
}
|
|
288
|
+
return parseSensorConfigurationFromDevice(parsed);
|
|
289
|
+
}
|
|
267
290
|
export function compileSensorProfileToBleJson(input) {
|
|
268
291
|
return JSON.stringify(parseSensorConfiguration(input));
|
|
269
292
|
}
|
package/dist/react-native.d.ts
CHANGED
|
@@ -5,8 +5,12 @@ export { MEASURE_SPECS, type MeasureSpec } from './measure-specs.js';
|
|
|
5
5
|
export { createSensorBeaconFrameCache, type SensorBeaconFrameCache, type SensorBeaconMeasurement, type SensorBeaconReading, } from './types.js';
|
|
6
6
|
export { TempivoSensorError, type TempivoSensorErrorCode } from './errors.js';
|
|
7
7
|
export { DEFAULT_SENSOR_MODEL, bluetoothMacFromSerial, normalizeSensorSerial, encodeSensorPinPayload, parseSensorQrJson, sessionTypeFromModel, } from './qr.js';
|
|
8
|
+
export { isMissingAdvertisementFirmware, sensorModelFromFirmware } from './model.js';
|
|
9
|
+
export type { SensorStickerModel } from './model.js';
|
|
10
|
+
export { buildSensorQrConnectJson, draftSensorQrConnectJsonFromScanDevice, formatSensorReadingLine, mergeScanTargetIntoSensorQr, normalizeSensorStickerModel, parseSensorQrForConnect, pinFromSensorQrRecord, resolveSensorBleConnectCredentialsFromPin, sensorQrConnectJsonFromLoose, sensorQrSerialMatchesSelected, serialHexFromSensorQrScan, tryParseSensorQrJson, } from './connect-helpers.js';
|
|
11
|
+
export type { ParsedSensorQrLoose, SensorBleConnectCredentials } from './connect-helpers.js';
|
|
8
12
|
export { calibrationFromExtendedJson, decodeLaboratoryCalibrationTimestamp, } from './calibration.js';
|
|
9
|
-
export { BLE_MAX_MEASUREMENT_INTERVAL_MINUTES, BLE_MAX_TRANSMISSION_INTERVAL_SECONDS, BLE_MIN_MEASUREMENT_INTERVAL_MINUTES, BLE_MIN_TRANSMISSION_INTERVAL_SECONDS, DEFAULT_ALERT_HYSTERESIS_C, compileSensorProfileToBleJson, configurationFromApiProfile, parseSensorConfiguration, parseSensorConfigurationJson, pickPartnerConfigurationJson, } from './profile.js';
|
|
13
|
+
export { BLE_MAX_MEASUREMENT_INTERVAL_MINUTES, BLE_MAX_TRANSMISSION_INTERVAL_SECONDS, BLE_MIN_MEASUREMENT_INTERVAL_MINUTES, BLE_MIN_TRANSMISSION_INTERVAL_SECONDS, DEFAULT_ALERT_HYSTERESIS_C, compileSensorProfileToBleJson, configurationFromApiProfile, parseSensorConfiguration, parseSensorConfigurationFromDevice, parseSensorConfigurationFromDeviceJson, parseSensorConfigurationJson, pickPartnerConfigurationJson, } from './profile.js';
|
|
10
14
|
export type { TempivoSchedule, TempivoScheduleAlways, TempivoScheduleWeek, TempivoSensorCalibration, TempivoSensorConfiguration, TempivoSensorQr, TempivoSensorSessionType, TempivoTemperatureAlert, TempivoTemperatureChannel, TempivoTemperatureMaxAlert, TempivoTemperatureMinAlert, TempivoTemperatureRangeAlert, TempivoTriggerTransmissionResult, } from './session-types.js';
|
|
11
15
|
export type { TempivoDeviceFoundSubscription, TempivoNativeCalibration, TempivoNativeMeasurement, TempivoNativePermissionResponse, TempivoNativePermissionStatus, TempivoNativeQr, TempivoNativeTelemetry, TempivoSensorBeaconDevice, } from './native-types.js';
|
|
12
16
|
import * as native from './native-module.js';
|
package/dist/react-native.js
CHANGED
|
@@ -5,8 +5,10 @@ export { MEASURE_SPECS } from './measure-specs.js';
|
|
|
5
5
|
export { createSensorBeaconFrameCache, } from './types.js';
|
|
6
6
|
export { TempivoSensorError } from './errors.js';
|
|
7
7
|
export { DEFAULT_SENSOR_MODEL, bluetoothMacFromSerial, normalizeSensorSerial, encodeSensorPinPayload, parseSensorQrJson, sessionTypeFromModel, } from './qr.js';
|
|
8
|
+
export { isMissingAdvertisementFirmware, sensorModelFromFirmware } from './model.js';
|
|
9
|
+
export { buildSensorQrConnectJson, draftSensorQrConnectJsonFromScanDevice, formatSensorReadingLine, mergeScanTargetIntoSensorQr, normalizeSensorStickerModel, parseSensorQrForConnect, pinFromSensorQrRecord, resolveSensorBleConnectCredentialsFromPin, sensorQrConnectJsonFromLoose, sensorQrSerialMatchesSelected, serialHexFromSensorQrScan, tryParseSensorQrJson, } from './connect-helpers.js';
|
|
8
10
|
export { calibrationFromExtendedJson, decodeLaboratoryCalibrationTimestamp, } from './calibration.js';
|
|
9
|
-
export { BLE_MAX_MEASUREMENT_INTERVAL_MINUTES, BLE_MAX_TRANSMISSION_INTERVAL_SECONDS, BLE_MIN_MEASUREMENT_INTERVAL_MINUTES, BLE_MIN_TRANSMISSION_INTERVAL_SECONDS, DEFAULT_ALERT_HYSTERESIS_C, compileSensorProfileToBleJson, configurationFromApiProfile, parseSensorConfiguration, parseSensorConfigurationJson, pickPartnerConfigurationJson, } from './profile.js';
|
|
11
|
+
export { BLE_MAX_MEASUREMENT_INTERVAL_MINUTES, BLE_MAX_TRANSMISSION_INTERVAL_SECONDS, BLE_MIN_MEASUREMENT_INTERVAL_MINUTES, BLE_MIN_TRANSMISSION_INTERVAL_SECONDS, DEFAULT_ALERT_HYSTERESIS_C, compileSensorProfileToBleJson, configurationFromApiProfile, parseSensorConfiguration, parseSensorConfigurationFromDevice, parseSensorConfigurationFromDeviceJson, parseSensorConfigurationJson, pickPartnerConfigurationJson, } from './profile.js';
|
|
10
12
|
import * as native from './native-module.js';
|
|
11
13
|
export const isNativeSensorBeaconAvailable = native.isNativeSensorBeaconAvailable;
|
|
12
14
|
export const requestPermissions = native.requestPermissions;
|