Skip to content

Units on the wire

Two things in this protocol are stored in units the API does not use, and both were the cause of long-lived bugs. The rule is not "convert everything" or "convert nothing" - it is per-field, and the table below is the authority.

Every entry was checked against a real ALPHA HWR; see bench findings for the measurements.

Telemetry: already in physical units

Live readings arrive as IEEE-754 floats in the unit you want. No scaling, no GENI unit-index lookup, no offset.

Reading Unit
Flow m³/h
Head m
Temperature °C
Speed RPM
Power W
Voltage V
Current A
Inlet / outlet pressure bar

Setpoints: SI, and not the same as telemetry

Setpoint Wire unit API unit Factor
Constant / proportional pressure Pa m × 9806.65 writing, ÷ writing back
Constant speed RPM RPM none
Constant flow m³/s m³/h ÷ 3600 writing, × 3600 reading
Cycle-mode flow (Obj 91 Sub 421) m³/s m³/h ÷ 3600 / × 3600
Temperature range (Obj 91 Sub 430) °C °C none

Why flow is the dangerous one

Telemetry flow really is m³/h and the flow setpoint really is m³/s. They are different encodings of the same quantity, not a mismatch to be reconciled - so a single "flow conversion" applied everywhere is wrong in one direction or the other.

Writing m³/h straight through sends a commanded 2.5 as 2.5 m³/s, which is 9000 m³/h. The pump rejects it as out of range and keeps its old value, so the register appears frozen and reads back about 1000× low. That reads like a broken readback, and was diagnosed as one for a long time; it is a broken write.

Limits are the pump's, and it clamps rather than refusing

The library validates against generous ranges and lets the pump decide. Asking for a value outside its limits is not an error: it stores its own and reports it back, which surfaces as a clamped write result carrying the stored value.

Measured on one unit - yours may differ, since installer settings in the Grundfos GO app (pipe size, maximum flow) also clamp:

Requested Stored
600 RPM 1650
4400 RPM 3671

Both ends appear verbatim in the pump's own speed-limits block (Object 86 Sub 13). That block is also where the number 3671 came from: it is the maximum, and it used to be sent as the "default" setpoint suffix on every start - so a start command was a request to run at full speed.

Timestamps are local Unix time

Single-event windows (Object 84, Sub 900+) store the wall clock stamped as though it were UTC - timegm(local fields) - matching the pump's RTC, which reports bare wall-clock fields with no offset.

This one cannot be caught by verification. The value round-trips byte-identically under either interpretation, so a write settles as accepted and a readback agrees with itself while the event opens hours from where it was meant to. It was settled here by writing an event and watching the motor: it started within a few seconds of the intended wall clock.

Re-checking any of this

Read the object, decode the raw float, and compare against what the Grundfos GO app shows for the same setting. A factor-of-3600 or 9806.65 discrepancy is the usual failure, and a value that will not change however you write it usually means the write is out of range rather than the register being read-only.