@tempivo/sensor-beacon 1.1.0 → 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 CHANGED
@@ -6,7 +6,11 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
- <!-- Publish trigger: 1.1.0 not yet on npm until CI Trusted Publisher (ci.yml) runs. -->
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.
10
14
 
11
15
  ## [1.1.0] - 2026-09-02
12
16
 
package/README.md CHANGED
@@ -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` | 60–600. Omitted: leave device value. | Returns current device value (may be below 60 if set outside the SDK). |
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: 60 min sampling → max `3600` s uplink; 120 min → max `7200` s.
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 = 60.0
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 (1 hour).")
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 = 60;
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 = 60;
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} (1 hour).`);
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
@@ -8,7 +8,7 @@
8
8
  <key>BinaryPath</key>
9
9
  <string>TempivoSensorBridge.framework/TempivoSensorBridge</string>
10
10
  <key>LibraryIdentifier</key>
11
- <string>ios-arm64-simulator</string>
11
+ <string>ios-arm64</string>
12
12
  <key>LibraryPath</key>
13
13
  <string>TempivoSensorBridge.framework</string>
14
14
  <key>SupportedArchitectures</key>
@@ -17,14 +17,12 @@
17
17
  </array>
18
18
  <key>SupportedPlatform</key>
19
19
  <string>ios</string>
20
- <key>SupportedPlatformVariant</key>
21
- <string>simulator</string>
22
20
  </dict>
23
21
  <dict>
24
22
  <key>BinaryPath</key>
25
23
  <string>TempivoSensorBridge.framework/TempivoSensorBridge</string>
26
24
  <key>LibraryIdentifier</key>
27
- <string>ios-arm64</string>
25
+ <string>ios-arm64-simulator</string>
28
26
  <key>LibraryPath</key>
29
27
  <string>TempivoSensorBridge.framework</string>
30
28
  <key>SupportedArchitectures</key>
@@ -33,6 +31,8 @@
33
31
  </array>
34
32
  <key>SupportedPlatform</key>
35
33
  <string>ios</string>
34
+ <key>SupportedPlatformVariant</key>
35
+ <string>simulator</string>
36
36
  </dict>
37
37
  </array>
38
38
  <key>CFBundlePackageType</key>
@@ -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 = 60
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)) (1 hour).")
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@tempivo/sensor-beacon",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
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": {