Skip to content

Fuel: from a probe reading to a fuel-loss alert

What this chapter covers

A fuel sensor reports a number many times an hour. Turning that stream into trustworthy answers — how full is the tank, did someone refuel, did someone lose fuel unexpectedly, and how sure are we — takes a full pipeline: reading the right sensor, converting a liquid height into a volume, smoothing out noise, detecting fills and drains, scoring how much to believe each one, pinning a location on it, and rolling it up into per-trip cost. This chapter walks that pipeline end to end.

The picture

The behavior

Two sensor families, one basis

The corridor fleet runs capacitive fuel probes over Bluetooth, wired into the tracker. Two families are recognised by the sensor's Bluetooth name prefix, and they differ only in how a raw reading becomes a fraction of a full tank:

  • KF201S carries its own calibrated full-scale value in each frame; the raw reading is divided by that.
  • Escort uses a fixed 12-bit scale — the raw reading runs 0 to 4095, and that 4095 is the divisor. (Escort frames also carry a bogus scale field the engine deliberately ignores; trusting it would peg every reading at 100%.)

From that point on the two families are identical. The result is a height fraction between 0 and 1, and everything downstream — the calibration curve, the smoothing, the state machine, per-vehicle tank capacity — is shared.

Each reading also stamps which sensor it came from and keeps the raw numbers, so a level can be recomputed later under a better per-sensor calibration.

Height is not volume

Here is the subtlety that a capacitive probe forces on the whole system: the probe measures the height of the liquid, not its volume. A truck tank has a rounded-rectangle cross-section — the corners curve away near the top and bottom. So a tank that is half-full by height is very close to half-full by volume, but a tank a tenth full by height holds noticeably less than a tenth of its volume, because the rounded bottom removes capacity down there.

The engine corrects for this with a height-to-volume calibration curve — an eleven-point map from height fraction to volume fraction. A height of 0.1 maps to a volume of about 0.082; 0.9 maps to about 0.918; the straight middle of the tank stays close to linear. Passing every reading through this curve gives the single canonical basis the rest of the system uses: volume-percent. Liters follow directly once a per-vehicle tank capacity is set — volume-% times capacity — and stay hidden until it is, so the gauge always shows a percentage and only promises liters when it can be honest about them.

Smoothing and error codes

A single probe reading is noisy — fuel sloshes, the probe bounces. The engine never reacts to one reading. It keeps a rolling history and works from the median of a window whose size follows a per-vehicle filter level (the default smooths over the last 15 readings). Until it has a full window it makes no strong judgement — a deliberate cold-start silence that stops a freshly-installed sensor from inventing events.

Each frame also carries a sensor state code. A non-zero code means the reading is invalid: the engine nulls the level so neither the gauge nor the state machine uses it, but it still stores the error code, the raw values, the sensor temperature, and the sensor battery as evidence. (Two of those arrive mislabelled by the upstream pipeline and are corrected on the way in — temperature scaled back up, battery voltage scaled back down.)

A reading is judged valid by its error code, regardless of whether the frame had a GPS fix. Escort probes and any sensor in a dead zone routinely report fuel on frames with no location at all — those still carry a real tank level, and the gauge shows them.

Detecting fills and drains

The state machine has three states — normal, draining, refilling — and works by comparing the current smoothed median against a reference level set when it last settled into normal:

  • A median that drops more than the drain threshold below the reference opens a drain. The threshold is a volume (5 litres by default) converted to percentage points using the tank capacity.
  • A median that rises more than the fill threshold above the reference opens a fill (also 5 litres by default).
  • An open event closes once the level holds steady for the join window (5 minutes) — the tank has settled at its new level.

Two refinements keep the detector honest:

  • While driving, the reference level tracks fuel burned. The reference follows the median downward as the truck moves, so ordinary consumption never accumulates into a false drain. A refill still rises above the reference and is caught; only a genuine loss while parked keeps the reference frozen and trips the drain.
  • A sensor swap resets the baseline. A jump of more than 30 percentage points between two readings is read as a sensor replacement or recalibration. The history and reference reset, and any open event closes immediately as a sensor-reset — bookkeeping that carries no volume and raises no alert.

A short continuation of a just-ended event rejoins it, and the detector is rate-limited so a thrashing sensor cannot flood the alert stream.

How much to believe an event: confidence

Every closed event carries a confidence — high, medium, or low — that downstream readers weigh before acting. The scoring differs between drains and fills because the available corroboration differs.

A drain can be cross-checked against the engine itself. The tracker reports the ECU's cumulative fuel-consumed counter, so the engine knows how many litres were burned over the drain window. If the tank-level drop exceeds what the engine burned by a clear margin (at least 5 litres of unexplained loss), the drain is corroborated and rated high — fuel left the tank that the engine never used. If the drop is fully explained by burn, the drain is vetoed as ordinary consumption. With no usable CAN counter, a drain is medium. There is no other route to a high-confidence drain.

A fill has no engine cross-check, so it earns high confidence from context. A fill is high when any of these holds:

  • A large, clean rise while stopped — at least a 15-percentage-point gain that coincides with an open stop. A refuel that big physically requires being parked at a pump.
  • At a known fuel station — the nearest waypoint is a fuel station.
  • Matched to a receipt — a driver-submitted fuel receipt reconciled to the event (see below).

Otherwise a fill is medium. A sensor-reset close is always low and never alerts.

Pinning a location on a fuel event

A fuel event often opens on a frame with no GPS fix — exactly the dead-zone and Escort case above. A drain or fill with no coordinate would render as "position inconnue" with no place. So at close, the engine recovers a location the way a person reads a trace: it brackets the fuel-change time with the surrounding GPS fixes and takes the nearest one within 30 minutes (admitting only good-quality, non-buffered fixes, whose timestamps are reliable for the join). The recovered coordinate does three things: it becomes the event's position, it drives the nearest-waypoint lookup (so a fill can be recognised as at-station), and it lets the place label resolve to a real name. When no fix exists in the window, the event stays location-less rather than guessing.

Receipts raise confidence

Drivers can submit fuel receipts. When a receipt reconciles to a detected fill within the same 30-minute window, the fill is promoted from medium to high — a human-confirmed pump transaction is the strongest corroboration a sensor-detected fill can get. The promotion is idempotent and applies out of band, after the event has already closed.

Fuel-loss and drain alerts

A drain becomes a fuel-loss anomaly only when the level change looks unexplained rather than ordinary burn. The engine escalates to the critical channel for a drain that happened while the truck was stationary, or for one the engine cross-check corroborates as loss beyond burn. A moving truck's loss is otherwise consumption until proven otherwise, so a drain that sees motion during its window loses its stationary flag, and with it its claim on the critical channel unless the cross-check corroborates it.

Hard exclusions

Known fuel-station drains are treated as fueling context and never become fuel_drain_anomaly alerts. A CAN explanation that accounts for the loss as burn is also a veto. CAN-corroborated unexplained loss bypasses the stationary gate, but it still has to clear the magnitude and rate floors.

Beyond that, an anomaly has to clear a magnitude floor and a rate floor: an actionable drain is fast (at least 8 percentage points per hour), while slow sensor drift or legitimate idle burn is not. When the tank capacity is unknown, a percentage-point floor stands in for the litres test so the anomaly never silently disables itself.

Fuel becomes cost: per-trip and per-traversal accounting

When a trip closes, the engine derives its fuel story from the readings inside the trip window: the start and end level, the litres consumed, and the efficiency in litres per 100 km. Consumption is the net level drop plus any mid-trip refill added back — a refuel mid-trip otherwise hides the burn behind it. Efficiency is only computed when the trip is long enough for the number to mean something. The same accounting runs per segment traversal, where it prefers the ECU cumulative-consumed delta (which is immune to mid-window refills) over the tank-level drop. These per-trip and per-segment figures are what feed fuel cost and efficiency reporting.

Edge cases

  • A dead-zone tank. A probe reporting fuel on fix-less frames still drives the gauge and can still open events; the level's validity is decided by its error code, not by the missing GPS fix, and the location is recovered at close by the nearest-fix time-join.
  • A parked overnight drain. The per-vehicle detection window anchors to each truck's own newest reading rather than a wall-clock floor, so a truck parked and offline for days still accumulates a usable median from its own recent history — precisely the profile a parked fuel-loss anomaly needs to be caught in.
  • A fill and a drain that are really a sensor swap. A greater-than-30-point jump resets the baseline and closes any open event as a sensor-reset, so an installer swapping a probe never produces a phantom refuel or drain anomaly.
  • A mid-trip refuel. It shows up as a fill event and is added back into the trip's consumed litres, so the trip's efficiency reflects fuel burned, not the raw start-minus-end delta.
  • A long-silent truck on the dashboard. Fuel older than 7 days is hidden from the live dashboard rather than shown as a stale value. This display cutoff is independent of the engine's detection window, which keeps working from each truck's own history regardless of how long the truck has been quiet.
  • A truck that reports more than one fuel probe. Every reading is stored stamped with the identity of the sensor that produced it, its raw values, and the derived level, so two probes on the same truck are kept as distinct, self-identified series.

Known limitations

Fuel is the noisiest signal Korido reasons about, and the pipeline is honest about where its answers stop.

  • The two probe families do not measure to the same fineness. A KF201S carries its own calibrated full-scale value, so its fraction is anchored to a real calibration. An Escort has no usable scale on the wire, so Korido divides by the sensor's fixed twelve-bit range — a coarser, uncalibrated basis that reads a little rougher near the extremes. Both are trustworthy for detecting a fill or a drain; they are not identically precise gauges.
  • Height-to-volume runs through one shared curve. A single eleven-point curve models the rounded-rectangle cross-section every corridor tank is assumed to share. A tank whose true shape departs from that curve carries a small volume error, largest near a full or empty tank.
  • High-confidence fuel-loss anomalies need a CAN fuel counter. A drain can only be rated high confidence by cross-checking the tank drop against litres the engine actually burned. Without a usable ECU fuel-consumed counter, a drain is capped at medium — real, but uncorroborated. And until a per-vehicle tank capacity is recorded, litres stay hidden and percentage-point floors stand in for the litre-based tests.
  • The live gauge stops claiming after 7 days. Fuel older than 7 days is hidden from the dashboard rather than shown as a stale value, so a long-silent truck's tile makes no fuel claim at all. The detection window is independent and keeps working from each truck's own history — but the displayed gauge is deliberately bounded to recent readings.

What's ahead

  • Multi-tank trucks. Today the pipeline reasons about one tank per vehicle. Because every reading already stamps which sensor produced it and keeps its raw values, Korido will be able to give a twin-tank truck a left and a right tank, each with its own capacity and calibration curve, without having lost any of the history captured under the single-tank model.
  • Recalibration without losing the past. Since the raw probe numbers are retained alongside every derived level, Korido will be able to recompute a truck's fuel history under an improved per-sensor calibration — sharpening old readings rather than discarding them when a better curve is known.

How it connects