@tempivo/sensor-beacon 1.1.6 → 1.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/CHANGELOG.md CHANGED
@@ -6,6 +6,12 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.1.7] - 2026-09-30
10
+
11
+ ### Added
12
+
13
+ - `clearMeasurementQueue()`: clear on-device measurement / uplink queue (memory reset). Manual recovery only; not used by `setConfigurationJson`.
14
+
9
15
  ## [1.1.6] - 2026-09-25
10
16
 
11
17
  ### Changed
@@ -13,7 +19,8 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
13
19
  - Parsed sticker model **TS10** stays `TS10` on `TempivoSensorQr` (connect / native still maps to HC7).
14
20
  - Production defaults check is looser: PLMN `1000000` and legacy `0xFFFFFFFF` as automatic, DEL-only APN user/password as unused, DNS `255.255.255.255` as automatic, any regional NB-IoT band mask, any non-empty firmware string.
15
21
  - React Native entry re-exports native BLE helpers live from the native module (avoids a stale snapshot when Metro loads).
16
- - Docs: prefer Cellular API for laboratory calibration date; BLE `getCalibration` is not the source of truth. Cloud field is not released yet and returns `null` for now. Examples no longer call `getCalibration()`.
22
+ - Docs: prefer Cellular API for laboratory calibration date; BLE `getCalibration` is optional. Examples no longer call `getCalibration()`.
23
+ - Docs: cloud `laboratoryCalibrationDate` is live (certificate and/or device extended-config uplink); remove “not released yet” wording.
17
24
 
18
25
  ## [1.1.5] - 2026-09-08
19
26
 
package/README.md CHANGED
@@ -107,7 +107,8 @@ The Expo config plugin sets **minSdk 26**, Android BLE permissions, and **`NSBlu
107
107
  | `connect` / `disconnect` | GATT session with parsed QR (`TempivoSensorQr`). |
108
108
  | `getConfiguration` / `setConfigurationJson` | Read / write alert rules, schedule, optional intervals. |
109
109
  | `triggerTransmission` | Ask firmware to uplink now; returns `{ ok }`. Cloud pending syncs after that uplink (or schedule/button), not from the BLE write alone. |
110
- | `getCalibration` | Legacy BLE read of laboratory calibration date. Prefer the Cellular API (see below). |
110
+ | `clearMeasurementQueue` | Clear on-device measurement / uplink queue (memory reset). Manual recovery only; not used by `setConfigurationJson`. |
111
+ | `getCalibration` | Optional BLE read of laboratory calibration date. Prefer the Cellular API (see below). |
111
112
 
112
113
  **Cloud queue:** BLE updates the sensor only. After uplink, Tempivo drops from Cellular `pendingConfig` only fields the device already matches; other queued fields can still downlink. Cancel the whole queue with `DELETE /api/v1/devices/{serial}/config` (see Tempivo Cellular API docs).
113
114
 
@@ -363,9 +364,9 @@ Prefer **cloud to cloud**, not BLE:
363
364
  - After the sensor is registered, use **`GET /api/v1/assets/{assetId}`** (`laboratoryCalibrationDate`, and `calibrationCertificate` when a PDF is linked).
364
365
  - Download PDF: **`GET /api/v1/assets/{assetId}/calibration-certificate`**.
365
366
 
366
- This cloud field is **not released yet**. Until Tempivo turns it on, the API returns **`null`** for `laboratoryCalibrationDate` (except sample / demo serials documented in the Cellular API). Do not use BLE for production calibration dates.
367
+ `laboratoryCalibrationDate` is live. Sources (first wins): uploaded certificate date, then device extended-config `LABORATORY_CALIBRATION_DATE` after cellular uplink. `null` only when neither exists yet (see Cellular API sample serial `STOREVIEW001` for a fixed demo date).
367
368
 
368
- BLE `getCalibration()` exists for tooling only and is not shown in the examples above.
369
+ BLE `getCalibration()` can still read the on-device date when present; it is not shown in the examples above.
369
370
 
370
371
  ## Node / TypeScript helpers
371
372
 
@@ -409,6 +410,8 @@ session.connect(qr)
409
410
  try {
410
411
  session.setConfigurationJson(profileJson)
411
412
  val trigger = session.triggerTransmission()
413
+ // Manual recovery only (not part of setConfiguration):
414
+ // session.clearMeasurementQueue()
412
415
  val applied = session.getConfiguration()
413
416
  } finally {
414
417
  // Without disconnect, the sensor will not advertise for startScan.
@@ -122,6 +122,17 @@ final class SensorBeaconNative {
122
122
  }
123
123
  }
124
124
 
125
+ Map<String, Object> clearMeasurementQueue() {
126
+ try {
127
+ requireSessionConnected().clearMeasurementQueueBlocking();
128
+ Map<String, Object> payload = new HashMap<>();
129
+ payload.put("ok", true);
130
+ return payload;
131
+ } catch (Throwable error) {
132
+ throw wrap(error);
133
+ }
134
+ }
135
+
125
136
  Map<String, Object> getCalibration() {
126
137
  try {
127
138
  return calibrationMap(requireSessionConnected().getCalibrationBlocking());
@@ -92,6 +92,14 @@ class TempivoSensorBeaconModule : Module() {
92
92
  }
93
93
  }
94
94
 
95
+ AsyncFunction("clearMeasurementQueue") {
96
+ try {
97
+ native.clearMeasurementQueue()
98
+ } catch (error: Throwable) {
99
+ throw error.toSensorException()
100
+ }
101
+ }
102
+
95
103
  AsyncFunction("getCalibration") {
96
104
  try {
97
105
  native.calibration
@@ -119,6 +119,15 @@ internal object SensorBleRuntime {
119
119
  }
120
120
  }
121
121
 
122
+ /**
123
+ * Clear on-device measurement / uplink queue (memory reset).
124
+ * Manual recovery only: not used by [writeConfiguration] / partner setConfiguration.
125
+ */
126
+ suspend fun clearMeasurementQueue(session: Session) {
127
+ val base = modernGetConfiguration(session.connection)
128
+ session.connection.commands.setConfiguration(base.copy(resetMemoryRequest = true)) { }
129
+ }
130
+
122
131
  suspend fun readCalibration(session: Session): TempivoSensorCalibration {
123
132
  val ext = session.connection.commands.getExtendedConfiguration { }
124
133
  return TempivoSensorCalibrationDecoder.decode(ext.laboratoryCalibrationTimestamp)
@@ -170,6 +170,16 @@ class TempivoSensorSession(
170
170
  }
171
171
  }
172
172
 
173
+ /**
174
+ * Clear on-device measurement / uplink queue (memory reset). Manual recovery only.
175
+ */
176
+ suspend fun clearMeasurementQueue() {
177
+ runGatt {
178
+ ensureSdkConnected()
179
+ SensorBleRuntime.clearMeasurementQueue(requireSession())
180
+ }
181
+ }
182
+
173
183
  suspend fun getCalibration(): TempivoSensorCalibration {
174
184
  return runGatt {
175
185
  ensureSdkConnected()
@@ -192,6 +202,8 @@ class TempivoSensorSession(
192
202
 
193
203
  fun triggerTransmissionBlocking(): TriggerResult = runBlocking { triggerTransmission() }
194
204
 
205
+ fun clearMeasurementQueueBlocking() = runBlocking { clearMeasurementQueue() }
206
+
195
207
  fun getCalibrationBlocking(): TempivoSensorCalibration = runBlocking { getCalibration() }
196
208
 
197
209
  private fun requireSession(): SensorBleRuntime.Session =
package/dist/index.d.ts CHANGED
@@ -12,5 +12,5 @@ export type { ParsedSensorQrLoose, SensorBleConnectCredentials, } from './connec
12
12
  export { calibrationFromExtendedJson, decodeLaboratoryCalibrationTimestamp, } from './calibration.js';
13
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';
14
14
  export type { TempivoSchedule, TempivoScheduleAlways, TempivoScheduleWeek, TempivoSensorCalibration, TempivoSensorConfiguration, TempivoSensorQr, TempivoSensorSessionType, TempivoTemperatureAlert, TempivoTemperatureChannel, TempivoTemperatureMaxAlert, TempivoTemperatureMinAlert, TempivoTemperatureRangeAlert, TempivoTriggerTransmissionResult, } from './session-types.js';
15
- export { addDeviceFoundListener, connect, disconnect, getCalibration, getConfiguration, getProtoConfiguration, isNativeSensorBeaconAvailable, isScanning, requestPermissions, setConfigurationJson, startScan, stopScan, triggerTransmission, } from './native-bridge.js';
15
+ export { addDeviceFoundListener, connect, clearMeasurementQueue, disconnect, getCalibration, getConfiguration, getProtoConfiguration, isNativeSensorBeaconAvailable, isScanning, requestPermissions, setConfigurationJson, startScan, stopScan, triggerTransmission, } from './native-bridge.js';
16
16
  export type { TempivoDeviceFoundSubscription, TempivoNativeCalibration, TempivoNativeMeasurement, TempivoNativePermissionResponse, TempivoNativePermissionStatus, TempivoNativeQr, TempivoNativeTelemetry, TempivoSensorBeaconDevice, } from './native-types.js';
package/dist/index.js CHANGED
@@ -9,4 +9,4 @@ export { isMissingAdvertisementFirmware, sensorModelFromFirmware, } from './mode
9
9
  export { buildSensorQrConnectJson, draftSensorQrConnectJsonFromScanDevice, formatSensorReadingLine, mergeScanTargetIntoSensorQr, normalizeSensorStickerModel, parseSensorQrForConnect, pinFromSensorQrRecord, resolveSensorBleConnectCredentialsFromPin, sensorQrConnectJsonFromLoose, sensorQrSerialMatchesSelected, serialHexFromSensorQrScan, tryParseSensorQrJson, } from './connect-helpers.js';
10
10
  export { calibrationFromExtendedJson, decodeLaboratoryCalibrationTimestamp, } from './calibration.js';
11
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';
12
- export { addDeviceFoundListener, connect, disconnect, getCalibration, getConfiguration, getProtoConfiguration, isNativeSensorBeaconAvailable, isScanning, requestPermissions, setConfigurationJson, startScan, stopScan, triggerTransmission, } from './native-bridge.js';
12
+ export { addDeviceFoundListener, connect, clearMeasurementQueue, disconnect, getCalibration, getConfiguration, getProtoConfiguration, isNativeSensorBeaconAvailable, isScanning, requestPermissions, setConfigurationJson, startScan, stopScan, triggerTransmission, } from './native-bridge.js';
@@ -11,5 +11,8 @@ export declare function disconnect(): Promise<void>;
11
11
  export declare function getConfiguration(): Promise<TempivoSensorConfiguration>;
12
12
  export declare function setConfigurationJson(config: string | TempivoSensorConfiguration): Promise<void>;
13
13
  export declare function triggerTransmission(): Promise<TempivoTriggerTransmissionResult>;
14
+ export declare function clearMeasurementQueue(): Promise<{
15
+ ok: boolean;
16
+ }>;
14
17
  export declare function getCalibration(): Promise<TempivoNativeCalibration>;
15
18
  export declare function getProtoConfiguration(): Promise<Record<string, unknown>>;
@@ -46,6 +46,9 @@ export async function setConfigurationJson(config) {
46
46
  export async function triggerTransmission() {
47
47
  return (await loadNative()).triggerTransmission();
48
48
  }
49
+ export async function clearMeasurementQueue() {
50
+ return (await loadNative()).clearMeasurementQueue();
51
+ }
49
52
  export async function getCalibration() {
50
53
  return (await loadNative()).getCalibration();
51
54
  }
@@ -22,6 +22,13 @@ export declare function getConfiguration(): Promise<TempivoSensorConfiguration>;
22
22
  */
23
23
  export declare function setConfigurationJson(config: string | TempivoSensorConfiguration): Promise<void>;
24
24
  export declare function triggerTransmission(): Promise<TempivoTriggerTransmissionResult>;
25
+ /**
26
+ * Clear on-device measurement / uplink queue (memory reset).
27
+ * Manual recovery only: not used by setConfigurationJson.
28
+ */
29
+ export declare function clearMeasurementQueue(): Promise<{
30
+ ok: boolean;
31
+ }>;
25
32
  /** Decoded device ProtoConfig (server, APN, intervals). Requires an open BLE session. */
26
33
  export declare function getProtoConfiguration(): Promise<ProtoConfigObject>;
27
34
  export declare function getCalibration(): Promise<TempivoNativeCalibration>;
@@ -142,6 +142,22 @@ export async function triggerTransmission() {
142
142
  throw mapNativeError(error);
143
143
  }
144
144
  }
145
+ /**
146
+ * Clear on-device measurement / uplink queue (memory reset).
147
+ * Manual recovery only: not used by setConfigurationJson.
148
+ */
149
+ export async function clearMeasurementQueue() {
150
+ try {
151
+ const native = getNative();
152
+ if (typeof native.clearMeasurementQueue !== 'function') {
153
+ throw new TempivoSensorError('runtimeUnavailable', 'Native clearMeasurementQueue is unavailable in this build.');
154
+ }
155
+ return await native.clearMeasurementQueue();
156
+ }
157
+ catch (error) {
158
+ throw mapNativeError(error);
159
+ }
160
+ }
145
161
  /** Decoded device ProtoConfig (server, APN, intervals). Requires an open BLE session. */
146
162
  export async function getProtoConfiguration() {
147
163
  try {
@@ -13,6 +13,6 @@ export { calibrationFromExtendedJson, decodeLaboratoryCalibrationTimestamp, } fr
13
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';
14
14
  export type { TempivoSchedule, TempivoScheduleAlways, TempivoScheduleWeek, TempivoSensorCalibration, TempivoSensorConfiguration, TempivoSensorQr, TempivoSensorSessionType, TempivoTemperatureAlert, TempivoTemperatureChannel, TempivoTemperatureMaxAlert, TempivoTemperatureMinAlert, TempivoTemperatureRangeAlert, TempivoTriggerTransmissionResult, } from './session-types.js';
15
15
  export type { TempivoDeviceFoundSubscription, TempivoNativeCalibration, TempivoNativeMeasurement, TempivoNativePermissionResponse, TempivoNativePermissionStatus, TempivoNativeQr, TempivoNativeTelemetry, TempivoSensorBeaconDevice, } from './native-types.js';
16
- export { isNativeSensorBeaconAvailable, requestPermissions, startScan, stopScan, isScanning, addDeviceFoundListener, connect, disconnect, getConfiguration, setConfigurationJson, triggerTransmission, getCalibration, getProtoConfiguration, } from './native-module.js';
16
+ export { isNativeSensorBeaconAvailable, requestPermissions, startScan, stopScan, isScanning, addDeviceFoundListener, connect, disconnect, getConfiguration, setConfigurationJson, triggerTransmission, clearMeasurementQueue, getCalibration, getProtoConfiguration, } from './native-module.js';
17
17
  export { checkProductionDefaults } from './production-defaults.js';
18
18
  export type { ProductionCheckLine, ProductionCheckResult } from './production-defaults.js';
@@ -9,5 +9,5 @@ export { isMissingAdvertisementFirmware, sensorModelFromFirmware } from './model
9
9
  export { buildSensorQrConnectJson, draftSensorQrConnectJsonFromScanDevice, formatSensorReadingLine, mergeScanTargetIntoSensorQr, normalizeSensorStickerModel, parseSensorQrForConnect, pinFromSensorQrRecord, resolveSensorBleConnectCredentialsFromPin, sensorQrConnectJsonFromLoose, sensorQrSerialMatchesSelected, serialHexFromSensorQrScan, tryParseSensorQrJson, } from './connect-helpers.js';
10
10
  export { calibrationFromExtendedJson, decodeLaboratoryCalibrationTimestamp, } from './calibration.js';
11
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';
12
- export { isNativeSensorBeaconAvailable, requestPermissions, startScan, stopScan, isScanning, addDeviceFoundListener, connect, disconnect, getConfiguration, setConfigurationJson, triggerTransmission, getCalibration, getProtoConfiguration, } from './native-module.js';
12
+ export { isNativeSensorBeaconAvailable, requestPermissions, startScan, stopScan, isScanning, addDeviceFoundListener, connect, disconnect, getConfiguration, setConfigurationJson, triggerTransmission, clearMeasurementQueue, getCalibration, getProtoConfiguration, } from './native-module.js';
13
13
  export { checkProductionDefaults } from './production-defaults.js';
Binary file
@@ -169,6 +169,7 @@ __attribute__((swift_name("TempivoSensorBridge")))
169
169
  @interface TSBTempivoSensorBridge : TSBBase
170
170
  - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
171
171
  + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
172
+ - (NSString *)clearMeasurementQueuePayloadJson __attribute__((swift_name("clearMeasurementQueuePayloadJson()")));
172
173
  - (NSString *)connectPayloadJsonDeviceId:(NSString *)deviceId bluetoothMac:(NSString *)bluetoothMac pin:(NSString *)pin legacy:(BOOL)legacy __attribute__((swift_name("connectPayloadJson(deviceId:bluetoothMac:pin:legacy:)")));
173
174
  - (void)disconnect __attribute__((swift_name("disconnect()")));
174
175
  - (NSString *)getCalibrationPayloadJson __attribute__((swift_name("getCalibrationPayloadJson()")));
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/ios/Frameworks/TempivoSensorBridge.xcframework/ios-arm64/TempivoSensorBridge.framework/TempivoSensorBridge
3
- size: 78397208 bytes
4
- sha256: 47d3b00a0b04f500eaa566d288ee0884e55da39ce593c844dc164b415ef8ccab
3
+ size: 78427712 bytes
4
+ sha256: 3d8331bcccc757e88f3cc11ebd41a81837c0712942178f3bfdd869094b90cd45
@@ -169,6 +169,7 @@ __attribute__((swift_name("TempivoSensorBridge")))
169
169
  @interface TSBTempivoSensorBridge : TSBBase
170
170
  - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
171
171
  + (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
172
+ - (NSString *)clearMeasurementQueuePayloadJson __attribute__((swift_name("clearMeasurementQueuePayloadJson()")));
172
173
  - (NSString *)connectPayloadJsonDeviceId:(NSString *)deviceId bluetoothMac:(NSString *)bluetoothMac pin:(NSString *)pin legacy:(BOOL)legacy __attribute__((swift_name("connectPayloadJson(deviceId:bluetoothMac:pin:legacy:)")));
173
174
  - (void)disconnect __attribute__((swift_name("disconnect()")));
174
175
  - (NSString *)getCalibrationPayloadJson __attribute__((swift_name("getCalibrationPayloadJson()")));
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/ios/Frameworks/TempivoSensorBridge.xcframework/ios-arm64-simulator/TempivoSensorBridge.framework/TempivoSensorBridge
3
- size: 35252152 bytes
4
- sha256: 6ff38e03c9e174414232b38328a14ccca43929477cb2769ca7c604f14341f188
3
+ size: 35253832 bytes
4
+ sha256: e861ca361a1210560b37ef321f2a2590a8f634f493a424a50cfd2c4c90b4e401
@@ -146,6 +146,17 @@ public final class TempivoSensorSession: @unchecked Sendable {
146
146
  #endif
147
147
  }
148
148
 
149
+ /// Clear on-device measurement / uplink queue (memory reset). Manual recovery only.
150
+ public func clearMeasurementQueue() throws {
151
+ #if canImport(TempivoSensorBridge)
152
+ try ensureSdkConnected()
153
+ let result = parseBridgeJson(bridge.clearMeasurementQueuePayloadJson())
154
+ try throwIfBridgeError(result)
155
+ #else
156
+ throw TempivoSensorError(.runtimeUnavailable, "Sensor GATT requires a physical device with the native runtime.")
157
+ #endif
158
+ }
159
+
149
160
  public func getCalibration() throws -> TempivoSensorCalibration {
150
161
  #if canImport(TempivoSensorBridge)
151
162
  try ensureSdkConnected()
@@ -120,6 +120,15 @@ public class TempivoSensorBeaconModule: Module {
120
120
  }
121
121
  }
122
122
 
123
+ AsyncFunction("clearMeasurementQueue") { () -> [String: Any] in
124
+ do {
125
+ try self.session.clearMeasurementQueue()
126
+ return ["ok": true]
127
+ } catch {
128
+ throw self.mapError(error)
129
+ }
130
+ }
131
+
123
132
  AsyncFunction("getCalibration") { () -> [String: Any] in
124
133
  do {
125
134
  let cal = try self.session.getCalibration()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tempivo/sensor-beacon",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "description": "Tempivo sensor BLE SDK. Native scan and GATT for Expo, React Native, Android, and iOS. Node helpers decode advertisements and parse QR or config (no radio).",
5
5
  "homepage": "https://app.tempivo.com/integrations",
6
6
  "repository": {