Back to Feed
article 3m read

A ghost plug got fixed screen by screen before "now" had one owner

Retained MQTT readings outlive the plugs that sent them, so my sampler, history overview and device list each needed an availability check; after patching them one at a time I moved the rule into one module that only counts online devices, rejects junk values, and sums power instead of averaging it.

Article DepthPractice

Flow

From many copies of the check to one

  1. 1Saved totals

    The sampler stopped writing offline plugs into history first, since bad saved rows stay bad.

  2. 2History overview

    Live values got an availability check, and old saved points stopped standing in for the current value.

  3. 3Device list

    Power fields went blank for plugs that were not connected.

  4. 4One shared module

    Online-only, valid numbers only, and power added rather than averaged.

  5. 5Browser

    Tabs and summary refresh together, and the active tab copies the summary value.

Some screens agreed and others didn't: my power history was counting a plug that was offline. That mismatch was the bug.

Why an old reading sticks around

My plugs send their state over MQTT as retained messages. The broker keeps the last one and gives it to anyone who asks, even if the plug is gone. That's handy for a switch after a restart. It's bad for watts, because the last reading never fades.

Whether a plug is still there comes on a separate availability message: online, offline, or nothing at all. So "power right now" needs both the reading and proof the plug is alive.

One screen at a time

One summary screen already counted only online plugs. The rest each had their own loop, and I fixed them one by one.

The sampler came first, since it writes totals into the database. A wrong screen fixes itself on refresh. A wrong saved row stays wrong. Then the history overview, which still leaked after I added the check, because it also used the newest saved point as the current value. Then the device list. Each fix was another copy of the same check.

One place that decides

So I moved the decision into one small module, and every screen asks it. It does three things. It treats a plug as live only when availability says online. It throws away readings that aren't a real, non-negative number. And it picks how to combine devices: power and current get added, other sensors get averaged.

That last rule fixed the history chart, which had been averaging power across plugs. An average of plug wattages isn't anyone's number. The chart now asks the module.

Power and current are added up across plugs, and other metrics are averaged.

It also turned up one screen that never passed availability in at all.

One offline plug with a big number

The main test uses two live plugs and one offline plug with a big old reading. The overview and the history summary must show the same live total. The chart must still show the offline plug's past. Its current value must be empty.

The browser had its own drift. The tabs refreshed often and the chart rarely, so the same answer showed up as two numbers. Now they refresh together, and the active tab copies the summary's value.

The empty case is still open. My sampler still saves "nothing is online" as a real zero, and I haven't decided whether it should skip the row instead.

Keep reading

Pick up a connected idea or branch into a nearby one.

5 paths forward