Three tanks, three dead gauges, two replacements
Enja has three tanks — diesel, water to starboard, water to port — and she came with three analog WEMA gauges to read them, one each. All three had died. Two replacements had been sourced, one fuel and one water, which is the kind of arithmetic that leaves a tank with nowhere to show itself: three tanks, two working instruments, and a port water tank reduced to a rumour.
Meanwhile, thirty centimetres away, the Victron Cerbo had four resistive tank inputs sitting completely unused. The whole job, once you say it out loud, is embarrassingly obvious: stop buying gauges, wire the senders the boat already has into the inputs the boat already has, and let all three tanks read at once — on the Cerbo, on the phone, and in the logbook.
But first you have to find out what you're actually holding, and that is where the evening started earning its keep.


Four resistive tank inputs, four temperature inputs and four digital inputs, each numbered 1 to 4, with a DATA rail above them and a common ground below. Aboard Enja the same model sits behind the panel, thirty centimetres from three tank gauges that had all died — and all four of its tank inputs had never been used.
The fault that started the whole thing was a gauge wired to kill itself
Behind the panel is a nine-way barrier strip — instruments on the left tabs, the boat's harness on the right, and a trap in the middle. Two terminals are both stamped 29. They look like two terminals. They are the same 13.1-volt rail.
The fuel gauge's sender wire — its signal wire, the one that is supposed to read a float's resistance between zero and a couple of hundred ohms — was landed on 29. Somebody had wired the gauge's most delicate input straight to the twelve-volt rail and left it there, pouring 13.1 volts into a terminal that expected, at most, a knee-high trickle. The remarkable thing is that the gauge had survived the insult. We moved the wire one position over, to 41, where the diesel sender actually lives, and the gauge — the one part everyone had written off — turned out to have been innocent all along. It had been reading a power rail and dutifully pinning itself to full for who knows how long.
With everything on the right terminals, the senders finally told the truth, in ohms:
- 41, diesel — 130 Ω, about 68% of a tank.
- 42, water to starboard — 162 Ω, calling itself 85%.
- 43, water to port — 192 Ω. Full, and the tank was full, which is a rarer confirmation than it sounds.
All three plain European resistive senders, zero ohms empty to a hair under 190 full — which is exactly, precisely, what the Cerbo's built-in inputs want. No adapter. No extra box. Three wires and a decision.

Terminals 29 and 29 are not two terminals. They are the same 13.1-volt rail, and the fuel sender's signal wire — which is supposed to read a float's resistance, zero to about 190 ohms — had been landed on one of them. The gauge had been reading a power rail and dutifully pinning itself to full. Moving that one wire to 41, where the diesel sender actually lives, brought the gauge back from the dead; 42 and 43 are the two water tanks.
An open circuit reads full
There is a detail in the European tank standard that deserves to be printed on the inside of every boat's hatch boards: an open circuit reads full.
Zero ohms is empty, 190 is full, and a broken wire — infinite resistance — sails straight past 190 and pins the gauge at the top. Which means the single most common reason a tank reads full is not that it is full. It is that a wire has come adrift, or a terminal has corroded, or a sender has failed open. A gauge stuck at 4/4 is, far more often than not, a boat telling you about a broken connection in the only vocabulary it has.
Hold that thought. It comes back to bite, twice, before the night is out.

All three of Enja's senders are plain European resistive units — zero ohms empty, a hair under 190 full — which is exactly what the Cerbo's built-in tank inputs expect. Diesel read 130 Ω, about 68% of a tank; starboard water 162 Ω, calling itself 85%; port water 192 Ω, and the tank really was full. That last reading is in the hatched region past 190, which is also where a broken wire, a corroded terminal or a failed-open sender lands: an open circuit is infinite resistance, so it reads full. A gauge stuck at the top is more often a broken connection than a brimming tank, and only knowing which you did last tells them apart.
The manual had the answer in a diagram nobody reads
The Cerbo GX (the original, hardware revision 01) hides its tank pinout in a product photo in the manual — a strip along the bottom edge marked Tank, Temp, Digital inputs, each with its channels numbered 1 through 4, and two little dashed rails running the length of them: DATA along the top, a common ground along the bottom. That is the whole secret. The signal for each tank is its numbered pin on the top row; every sender's ground lands on the same shared rail underneath.
Which resolved the one genuine worry about this wiring — that the tanks have no return wire of their own. Each sender is a single wire back to the panel, closing its circuit through the metal tank flange into the boat's negative. That works, but it means the ground is the part that can wander: any voltage drop across the boat's negative network, every time the fridge or the autopilot draws, shows up as a tank level that breathes in and out with the electrical load. The fix is a fat, short reference wire from the Cerbo's ground rail to the boat's common negative, and a note to self that the real cure — a dedicated return from each tank flange — is an autumn job for when the tanks come apart anyway.
Then three wires, extended to reach the Cerbo, with one rule written on the back of the hand: the Cerbo measures resistance, so every ohm the extension adds is read as extra fuel. Solder or sealed crimps, not because the current is high — it is about seven milliamps — but because a corroding joint adds a drifting few ohms, and a drifting few ohms is a tank level that wanders for months while you slowly lose your mind. The joints are the whole job. The wire is an afterthought.

Each channel has its own signal pin on the DATA row along the top; every sender shares the one ground rail underneath. Enja's three senders land on tank inputs 1, 2 and 3 — diesel, starboard water, port water — coming from terminals 41, 42 and 43 on the barrier strip behind the panel. The fourth input is switched off in software: wired to nothing, it published a phantom empty tank. The senders have no return wire of their own and close their circuit through the metal tank flange into the boat's negative, which is why the ground rail wants a fat, short reference wire to the common negative — otherwise every tank level breathes in and out with the fridge.
Redrawn from the Cerbo GX manual's pinout, hardware revision 01.
Capacity is in cubic metres, and this will get you exactly once
The last analog act was to teach the Cerbo the tanks. Fluid type, sender standard, capacity — and capacity, by default, in cubic metres. A 180-litre water tank is 0.18, and if you type 180 you have just told the boat she is carrying a hundred and eighty tonnes of water, which she will believe, because believing things is what she does best.
So: switch the unit to litres first, type the honest number, and set the two water tanks to fresh water rather than leaving them as the fuel they defaulted to — otherwise the boat cheerly reports 400 litres of diesel she does not have. Diesel a hundred and fifty, water a hundred and eighty each. Done.
And on the screen, at last, all three tanks — the first time in this boat's recent life that every tank has been readable at the same moment, from somewhere other than a torch and a contorted neck behind the panel.
The ghosts of tanks that used to be fuel
Then the part where the software confidently read the wrong thing, because it would not be an evening aboard Enja otherwise.
Signal K picked the tanks up on its own and dutifully published them. Then I changed a fluid type in the Cerbo — the two water tanks, from fuel to fresh water — and watched the boat sprout tanks she does not have. The old path, fuel.21, did not vanish when the tank became freshWater.21. It sat there, frozen at its last value, a ghost of a tank that used to be diesel, quietly poisoning any total that summed the fuel.
Restarting the plugin did nothing, and why it did nothing is the useful bit: Signal K keeps a whole in-memory model of the boat, and a path the source stops publishing does not get deleted — it just goes stale and lingers, forever, until the server itself restarts. A plugin bounce re-reads the live tanks; it never forgets the dead ones. Only a full restart wipes the slate. After that — and after switching off the fourth tank input, which was busily publishing a phantom empty tank wired to nothing — exactly three tanks remained, which is exactly how many Enja has.
The starboard tank that read full, and this time meant it
One reading refused to settle: starboard water, sitting at 100% when three days earlier it had measured 85%.
Now — an open circuit reads full. Starboard's wire had just been handled, extended, re-landed; a bad splice reading false-full was the obvious suspect, and the honest first assumption. The guide even had the test written down for it.
Except the answer, this time, was the boring one: we had filled the tanks. It really was full. The needle that so often means "your wire is broken" occasionally means "your tank is full," and the only way to tell them apart is to know which one you did last. A full-tank reading also quietly confirmed the sender reaches the top of its range honestly — the one thing a half-full tank can never prove.
Two identical symptoms, a broken wire and a brimming tank, and the entire difference between them is context the instrument does not have and you do.
The lamp made of brittle plastic, overruled by a shunt
There is a Philippi charge-control panel aboard with two little lamps — Laden and Batterie voll — and we use the "charging" one for a real job: a glance to confirm the shore line is actually feeding the boat. The trouble is the lamps are brittle plastic and one has already fallen off, so the question was whether "is she charging?" could move to the Cerbo too.
It can, but not the way instinct says. The lamp is a twelve-volt signal, and the Cerbo's digital inputs top out at five volts and want a dry contact — wire the lamp straight in and you do not get a reading, you get a dead input. You would need a relay or an optocoupler per signal just to translate.
And then the better answer, which needed no wiring at all: there is no charger device on the bus for the Cerbo to ask, but there is a battery monitor, and a battery monitor measures current. "The landline is charging" is just "current is flowing into the battery" — a truer statement than a lamp, because it confirms the electricity actually arrived rather than merely that an LED lit. We read it live off the shunt: +0.1 A at 13.79 V, a battery sitting content on a float. The brittle lamp doesn't need rebuilding. It needs replacing with a number the boat already knows and can put on your phone.

The number on every passage page that was a guess
Here is what the whole evening was actually for.
Every passage Enja publishes carries a motoring figure, and until tonight it was an estimate — an inference from her speed and the wind, because there was no engine sensor to ask. It is a good inference. It is still a guess.
The diesel tank is not a guess. It is a measurement, and now it is on the bus. So the logbook gained a new line: diesel burned per leg — the tank level's drop across the leg, times a hundred and fifty litres — sitting right beside the motoring estimate it has always printed. One inferred, one measured, and now you can see them next to each other.
It is a coarse measurement, and the code is honest about exactly how coarse. A resistive float resolves to maybe one percent of the tank, about a litre and a half, so three guardrails keep it from lying:
- Every voyage recorded before tonight has no tank level at all, so it reports no burn — not a zero, which would be a lie, but nothing, which is the truth.
- If the level goes up mid-leg, somebody refuelled, and the row says so rather than reporting a nonsensical negative.
- A drop too small for the sender to genuinely resolve is labelled as such, not dressed up as a precise figure it hasn't earned.
The endpoints are medians over a short window at each end, so a single jittery reading can't invent or erase a few litres. And the whole thing degrades into silence on the old voyages instead of fabricating a number — which, after the week we'd had with software confidently reading the wrong copy of the truth, felt like the only decent way to write it.
The motoring percentage is an inference from her speed against what the wind could account for, and every voyage on file has one. Diesel burned is a measurement — the tank level's drop across a leg, times 150 litres — and no voyage on file has one, because all four were sailed before the sender was wired to the Cerbo on 18 July. The code reports nothing for them rather than a zero, which would be a lie. A resistive float resolves about one percent of the tank, roughly a litre and a half, so a drop smaller than that is labelled as unresolvable instead of being dressed up as a figure.
The symlink, striking for the second time this month
The last act was the deploy, and the deploy is where the boat reminded me she has a sense of humour and a long memory.
Cut a signed release, and Enja updates herself: she verifies the tag against the one key she trusts, runs the whole test suite on her own hardware, rebuilds, and rolls back if anything so much as flinches. She did all of that flawlessly, and then failed to build the website — and kept serving the old one, exactly as designed, so nothing broke.
The cause was an old friend. Aboard, the logbook folder is a symlink onto the SSD, and the new site needed some data files that live, committed, in the code tree — a boat manifest, the route list, the forecast, the tide tables. The symlink shadows them. They are right there in the release, and they are invisible at the path the build reads, because the folder they're in has been redirected to a disk that doesn't have them. This is precisely the disease that hid a pilot boat named STEVEN from the logbook a week ago: not a crash, not an error — a piece of software reading, with total confidence, from the wrong copy of the truth.
So the boat now generates those files herself before every build, the same way she already regenerates her device list. One more thing: the release carried the first proper image the site has ever had — the very tank pinout diagram from this job — and the boat has no heavy image library to optimise it with, nor should she, so the site was told to pass images through untouched. A second signed release, v1.0.8, and she took it: verified, tested aboard, the four data files generated, the site built, health-checked, and swapped in live. Two minutes, no laptop, nobody standing over her.
Where she stands tonight
She reads all three of her tanks at once, for the first time in years. She knows the shore line is charging from the current going in, not a lamp that keeps falling off. And when she next goes to sea, she will tell us not just that she motored, but roughly how much diesel it cost — a measurement, at last, in the one place on every passage page that was ever only a guess.
The gauges stay in the panel, dead and honest about it, because an empty hole is worse than dead jewellery. And the one number that would make all of this feel real — an actual litre count against an actual passage — cannot be printed yet, because every voyage on file is older than the sender. That reading is waiting on the same thing the motoring estimate has been waiting on all along:
An actual sail.
