Moisture Live API
GET /api/rfid/u300/moisture/live
Returns the current fluid level classification for every AZN3120-AFR sensor tag in antenna range. Called by the useLiveFluidLevels React hook every ~3 seconds.
GET /api/rfid/u300/moisture/live
Authorization: Bearer <token>
x-selected-location: 42Response:
{
"ok": true,
"locationId": 42,
"skipTidReads": true,
"tagFamily": "AZN3120-AFR",
"items": [
{
"epc": "E28011702000021A12345678",
"isMagnus": true,
"tidPending": false,
"scValue": 412,
"level": "3/4",
"readCount": 5,
"error": null
},
{
"epc": "E28011702000021A87654321",
"isMagnus": true,
"tidPending": false,
"scValue": null,
"level": null,
"readCount": 1,
"error": "no match for target EPC"
}
]
}Response item fields
| Field | Type | Description |
|---|---|---|
epc | string | Tag EPC (uppercase hex) |
isMagnus | boolean | true if tag is identified as a sensor tag |
tidPending | boolean | true if TID read is in progress (only when skipTidReads: false) |
scValue | number | null | Raw SC sensor value (0–511). Null if read failed |
level | string | null | Classified level: "Full", "3/4", "1/2", "1/4", "Empty". Null if insufficient reads |
readCount | number | Number of stable readings in history window |
error | string | null | Relay error message if SC read failed |
Classification logic
- Items with
isMagnus: falseandtidPending: falseare inventory-only tags — no level data - Items with
isMagnus: truebutlevel: nullhave insufficient history (readCount < minReads) - Items with
tidPending: trueshow a "Reading…" badge in the UI until resolved - Once
readCount >= minReadsand readings are stable,levelis set
Frontend hook
import { useLiveFluidLevels } from '@/hooks/useLiveFluidLevels'
const { levels, pendingEpcs } = useLiveFluidLevels(epcs)
// levels: Map<string, ClassifyResult> — EPC → level result
// pendingEpcs: Set<string> — EPCs with TID read in progressThe hook polls /api/rfid/u300/moisture/live every 3 seconds, maintains per-EPC rolling history in a useRef Map, and prunes history for tags that have left antenna range.
Error handling
- If the relay is unreachable, the endpoint returns
{ ok: true, items: [] }— the UI simply shows no badges rather than an error "no match for target EPC"means the tag moved out of range between the inventory scan and the bank read — will retry on the next poll- SC reads are batched in a single relay round trip using
/banks/read/batch