@tempivo/sensor-beacon 0.4.7 → 1.1.1
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 +13 -0
- package/README.md +11 -5
- package/android-aar/library/src/main/java/com/tempivo/sensor/beacon/TempivoSensorProfile.kt +2 -2
- package/dist/profile.d.ts +1 -1
- package/dist/profile.js +2 -2
- package/dist/tempivo-sensor-beacon.aar +0 -0
- package/ios/Frameworks/TempivoSensorBridge.xcframework/ios-arm64/TempivoSensorBridge.framework/TempivoSensorBridge +0 -0
- package/ios/Sources/TempivoSensorBeacon/TempivoSensorProfile.swift +2 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,19 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.1.1] - 2026-09-03
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Partner write min for `measurementIntervalMinutes` is **1** (was 60). Transmission min remains **3600** s.
|
|
14
|
+
|
|
15
|
+
## [1.1.0] - 2026-09-02
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- First **1.x** release line (API compatible with 0.4.7 for partners already on that series).
|
|
20
|
+
- README / package description: Node is decode and config helpers only (no BLE radio). Native scan and GATT remain Expo, React Native, Android, and iOS.
|
|
21
|
+
|
|
9
22
|
## [0.4.7] - 2026-09-01
|
|
10
23
|
|
|
11
24
|
### Added
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @tempivo/sensor-beacon
|
|
2
2
|
|
|
3
|
-
BLE for Tempivo sensors.
|
|
3
|
+
BLE for Tempivo sensors. Native scan + GATT on **Expo / React Native / Android / iOS**. **Node** gets decode and config helpers only (no radio).
|
|
4
4
|
|
|
5
5
|
## Expo and React Native
|
|
6
6
|
|
|
@@ -74,7 +74,11 @@ await setConfigurationJson({
|
|
|
74
74
|
},
|
|
75
75
|
],
|
|
76
76
|
});
|
|
77
|
+
// BLE write is on-device only. Cloud pending / last report update after a cellular uplink:
|
|
77
78
|
await triggerTransmission();
|
|
79
|
+
// Tempivo then drops from the cloud queue only fields the device already matches;
|
|
80
|
+
// other queued Cellular fields can still downlink. To cancel the whole queue:
|
|
81
|
+
// DELETE /api/v1/devices/{serial}/config (see docs/cellular-api.md).
|
|
78
82
|
const applied = await getConfiguration();
|
|
79
83
|
const cal = await getCalibration();
|
|
80
84
|
await disconnect();
|
|
@@ -100,9 +104,11 @@ The Expo config plugin sets **minSdk 26**, Android BLE permissions, and **`NSBlu
|
|
|
100
104
|
| `addDeviceFoundListener` | Callback per discovered device (includes `telemetry` when decoded). |
|
|
101
105
|
| `connect` / `disconnect` | GATT session with parsed QR (`TempivoSensorQr`). |
|
|
102
106
|
| `getConfiguration` / `setConfigurationJson` | Read / write alert rules, schedule, optional intervals. |
|
|
103
|
-
| `triggerTransmission` | Ask firmware to uplink now; returns `{ ok }`. |
|
|
107
|
+
| `triggerTransmission` | Ask firmware to uplink now; returns `{ ok }`. Cloud pending syncs after that uplink (or schedule/button), not from the BLE write alone. |
|
|
104
108
|
| `getCalibration` | Laboratory calibration date from extended config. |
|
|
105
109
|
|
|
110
|
+
**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).
|
|
111
|
+
|
|
106
112
|
### QR + connect helpers
|
|
107
113
|
|
|
108
114
|
Shared with the Tempivo app (same sticker JSON, PIN → encryption key, serial match checks):
|
|
@@ -250,10 +256,10 @@ Ignored over BLE: `slug`, `name`. Do not pass `alarmRules`.
|
|
|
250
256
|
|
|
251
257
|
| Field | Write (`setConfigurationJson`) | Read (`getConfiguration`) |
|
|
252
258
|
|------|--------------------------------|---------------------------|
|
|
253
|
-
| `measurementIntervalMinutes` |
|
|
259
|
+
| `measurementIntervalMinutes` | 1–600. Omitted: leave device value. | Returns current device value. |
|
|
254
260
|
| `transmissionIntervalSeconds` | 3600–604800 (1 h–7 d). Omitted: leave device value. | Returns current device value. |
|
|
255
261
|
|
|
256
|
-
When **both** are set on write, uplink must be at most **60×** the measurement interval. Example:
|
|
262
|
+
When **both** are set on write, uplink must be at most **60×** the measurement interval. Example: 1 min sampling → max `3600` s uplink; 60 min → max `3600` s; 120 min → max `7200` s.
|
|
257
263
|
|
|
258
264
|
Use `parseSensorConfigurationJson` to validate before write. Use `parseSensorConfigurationFromDevice` / `parseSensorConfigurationFromDeviceJson` when parsing a **readback** from the device (relaxed interval rules). For `GET /devices/config-profiles/{slug}`, use `configurationFromApiProfile(response.profile)` or pass the `{ profile }` envelope directly to `setConfigurationJson`.
|
|
259
265
|
|
|
@@ -372,7 +378,7 @@ AAR after `npm run build:android` (from `packages/tempivo-sensor-beacon`):
|
|
|
372
378
|
|
|
373
379
|
Sources: `android-aar/library`. Request `BLUETOOTH_SCAN`, `BLUETOOTH_CONNECT`, and on some OEMs **`ACCESS_FINE_LOCATION`** even on API 31+ (location on older APIs).
|
|
374
380
|
|
|
375
|
-
**Scan:** temperature and other live values are in scan-response frame **`0x04`** (`telemetry.readings`). Frame **`0x03`** alone fills firmware / battery / cellular but leaves `readings` empty until an active scan delivers `0x04` (usually within a second or two). Keep scanning; do not stop on the first event.
|
|
381
|
+
**Scan:** temperature and other live values are in scan-response frame **`0x04`** (`telemetry.readings`). Frame **`0x03`** alone fills firmware / battery / cellular but leaves `readings` empty until an active scan delivers `0x04` (usually within a second or two). Keep scanning; do not stop on the first event. Regression coverage: `src/scan-telemetry.regression.test.ts`.
|
|
376
382
|
|
|
377
383
|
```kotlin
|
|
378
384
|
val qr = TempivoSensorQrParser.parse(stickerQrText)
|
|
@@ -32,7 +32,7 @@ data class TempivoSensorConfiguration(
|
|
|
32
32
|
|
|
33
33
|
object TempivoSensorProfile {
|
|
34
34
|
private val timeRe = Regex("^([01]\\d|2[0-3]):([0-5]\\d)$")
|
|
35
|
-
private const val MIN_MEASUREMENT_MINUTES =
|
|
35
|
+
private const val MIN_MEASUREMENT_MINUTES = 1.0
|
|
36
36
|
private const val MAX_MEASUREMENT_MINUTES = 600.0
|
|
37
37
|
private const val MIN_TRANSMISSION_SECONDS = 3600
|
|
38
38
|
private const val MAX_TRANSMISSION_SECONDS = 604_800
|
|
@@ -120,7 +120,7 @@ object TempivoSensorProfile {
|
|
|
120
120
|
throw invalid("measurementIntervalMinutes must be a positive number.")
|
|
121
121
|
}
|
|
122
122
|
if (n < MIN_MEASUREMENT_MINUTES) {
|
|
123
|
-
throw invalid("measurementIntervalMinutes must be at least $MIN_MEASUREMENT_MINUTES
|
|
123
|
+
throw invalid("measurementIntervalMinutes must be at least $MIN_MEASUREMENT_MINUTES.")
|
|
124
124
|
}
|
|
125
125
|
if (n > MAX_MEASUREMENT_MINUTES) {
|
|
126
126
|
throw invalid("measurementIntervalMinutes must be at most $MAX_MEASUREMENT_MINUTES.")
|
package/dist/profile.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { TempivoSensorConfiguration } from './session-types.js';
|
|
|
2
2
|
/** Same default as Cellular API config profiles. */
|
|
3
3
|
export declare const DEFAULT_ALERT_HYSTERESIS_C = 1;
|
|
4
4
|
/** Same limits as Cellular API simple profiles. */
|
|
5
|
-
export declare const BLE_MIN_MEASUREMENT_INTERVAL_MINUTES =
|
|
5
|
+
export declare const BLE_MIN_MEASUREMENT_INTERVAL_MINUTES = 1;
|
|
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;
|
package/dist/profile.js
CHANGED
|
@@ -191,7 +191,7 @@ function rejectWireAlarmRules(rec) {
|
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
/** Same limits as Cellular API simple profiles. */
|
|
194
|
-
export const BLE_MIN_MEASUREMENT_INTERVAL_MINUTES =
|
|
194
|
+
export const BLE_MIN_MEASUREMENT_INTERVAL_MINUTES = 1;
|
|
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;
|
|
@@ -205,7 +205,7 @@ function parseOptionalIntervals(body, options = {}) {
|
|
|
205
205
|
}
|
|
206
206
|
if (validatePartnerLimits) {
|
|
207
207
|
if (n < BLE_MIN_MEASUREMENT_INTERVAL_MINUTES) {
|
|
208
|
-
throw new TempivoSensorError('invalidConfig', `measurementIntervalMinutes must be at least ${BLE_MIN_MEASUREMENT_INTERVAL_MINUTES}
|
|
208
|
+
throw new TempivoSensorError('invalidConfig', `measurementIntervalMinutes must be at least ${BLE_MIN_MEASUREMENT_INTERVAL_MINUTES}.`);
|
|
209
209
|
}
|
|
210
210
|
if (n > BLE_MAX_MEASUREMENT_INTERVAL_MINUTES) {
|
|
211
211
|
throw new TempivoSensorError('invalidConfig', `measurementIntervalMinutes must be at most ${BLE_MAX_MEASUREMENT_INTERVAL_MINUTES}.`);
|
|
Binary file
|
|
Binary file
|
|
@@ -90,7 +90,7 @@ public enum TempivoSensorProfile {
|
|
|
90
90
|
return String(data: data, encoding: .utf8) ?? "{}"
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
private static let minMeasurementMinutes: Double =
|
|
93
|
+
private static let minMeasurementMinutes: Double = 1
|
|
94
94
|
private static let maxMeasurementMinutes: Double = 600
|
|
95
95
|
private static let minTransmissionSeconds = 3600
|
|
96
96
|
private static let maxTransmissionSeconds = 604_800
|
|
@@ -107,7 +107,7 @@ public enum TempivoSensorProfile {
|
|
|
107
107
|
}
|
|
108
108
|
if validatePartnerLimits {
|
|
109
109
|
if n < minMeasurementMinutes {
|
|
110
|
-
throw TempivoSensorError(.invalidConfig, "measurementIntervalMinutes must be at least \(Int(minMeasurementMinutes))
|
|
110
|
+
throw TempivoSensorError(.invalidConfig, "measurementIntervalMinutes must be at least \(Int(minMeasurementMinutes)).")
|
|
111
111
|
}
|
|
112
112
|
if n > maxMeasurementMinutes {
|
|
113
113
|
throw TempivoSensorError(.invalidConfig, "measurementIntervalMinutes must be at most \(Int(maxMeasurementMinutes)).")
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tempivo/sensor-beacon",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Tempivo sensor BLE SDK for Expo, React Native, Android, iOS
|
|
3
|
+
"version": "1.1.1",
|
|
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": {
|
|
7
7
|
"type": "git",
|