A finished print is charged even when the printer never says it finished
Until now the ledger learned that a print had stopped in exactly one way: the
bambu_lab_event that ha-bambulab fires on the bus. That event is not delivered when the
printer's connection drops across its own ending — upstream fires it only on a transition it
observed, and a reconnection resets the state it compares against.
The failure is silent and it costs real filament. On the reference machine a seven-hour print
finished at 21:12:29 UTC on 2026-08-08; the sensor had gone unavailable at 21:08:13 and came
back already finished. No event was ever fired. The job stayed Running in the panel, and
248.41 g were never deducted. Nothing in the system would ever have closed it.
It is not a rare shape. That instance recorded 25 endings over the previous five days and
every one arrived correctly — the sensor dropped seven times in the same period and only this
one happened to land on an ending. Which is to say: it worked until the day it didn't, and
then it lost a whole spool's worth of accounting without a word.
This release gives the lifecycle a second, independent way to notice. The printer's status
sensor is now watched for finish and failed — never offline or pause, which describe
the connection and the machine rather than the job. It is read two ways:
- Live, as the sensor arrives at a terminal state, for a print that ends while Home
Assistant is up. - Once at startup, as a level, for the machine that stopped while nothing was listening —
a restart, a reload, or the dropout that swallowed the event.
What you will notice
- A print that finishes while the printer is dropping its connection is now charged normally,
instead of sitting in the panel as Running forever. - A job left open by a restart is closed the next time Home Assistant starts, and its
consumption recorded then. - Nothing changes for a healthy print. Both signals report it, and the ledger records it once.
What it will not do
An inferred ending can only ever close a job the ledger already believes is running. It
can never open one, and it never closes a job that a later print has already superseded. This
matters: an idle printer reports finish for as long as it sits there, and on the reference
machine it bounced finish → offline → finish five times in the ten minutes after a print
stopped. Anything that took that at face value would invent a print, and charge the previous
one's plan again, on every restart and every dropout.
A cancelled print reached through this path is recorded as failed rather than cancelled.
The status sensor does not distinguish them — upstream tells them apart by an error code that
travels on the MQTT payload and not on the sensor — and both open a review for you to decide,
so the difference is a word on a card rather than a number in the ledger. An ending announced
on the bus is still classified exactly as before.
Upgrading
Nothing to do. No schema migration, no settings to check, no re-sync.
Restart Home Assistant after updating, as usual. On that first start the new pass looks at
every machine once: if the ledger is holding a job open for a printer that has already
stopped, it is closed and its consumption recorded. If you have such a job, that is when it
will be settled.