-
v0.2.0-rc.12
Pre-releaseSome checks failedCI / Lint, type-check, test (library, 3.11.0) (push) Successful in 34sCI / Lint, type-check, test (library, 3.14) (push) Successful in 35sCI / Shell scripts and documentation links (push) Successful in 19sCI / Test the dependency floors the package advertises (push) Successful in 21sPublish / Publish to PyPI (push) Successful in 25sCI / Type-check + test the integration (push) Successful in 3m2sPublish / Update the Homebrew tap formula (stable or -rc per tag) (push) Failing after 19sPublish / Create releases + Linux binary (Forgejo, NAS, GitHub) (push) Failing after 26m2sPublish / Bridge the macOS .pkg → NAS (push) Has been skippedreleased this
2026-08-12 16:36:20 -07:00 | 132 commits to main since this releaseThanks to @CryingPecan, whose LitterHopper robot
on ESP 1.4.4 is behind much of what's below. Protocol detail lives in
docs/devices/litter-robot-4/.Added
- The clean cycle and reset buttons are back, and this time they work: they
synthesise the same button press the panel sends. Proven on ESP 1.1.75 and 1.4.4. - Empty cycle and Power buttons, disabled by default and named
(danger)— an
empty cycle dumps the globe into the drawer, and Power takes the robot off the
network. The CLI gainsempty-cycleandpower, which prompt first. - Pet weight actually works. Recent rc builds doubled the reading; weights now
match the household scale (raw ÷ 100, the cloud's own units). - LitterHopper support: connected, fill gauge, and an out-of-litter alert the
firmware itself never raises. The hopper entities switch themselves on the first
time a hopper reports. - Litter level as a percentage. It calibrates itself over time; one button press
with the globe filled to the line pins it immediately. - New entities: last cat visit, last visit duration, waste drawer last moved,
and panel brightness for bright and dark rooms. - Activity-derived entities survive a restart instead of reading unknown until
the next cat visit. - New install channels:
brew install sisyphusmd/tap/whiskerless,.deband
.rpmfor amd64 and arm64, and standalone Linux binaries for both. None of them
need a system Python — the audience is someone provisioning a robot from a laptop
that has none. - Excess weight detection. The robot refuses to cycle while it thinks something
is sitting on the scale, raises the condition itself after 30 minutes, and shows it
on the panel — but says nothing about it over MQTT. One robot here sat like that for
over two hours after a bonnet was reseated slightly off, with its clean cycle stuck
the whole time and nothing on the dashboard to explain it. Now a sensor. Pressing
Reset zeroes the scale and clears it.
Fixed
- The hopper entities no longer disappear from a robot that has one. An upgrade
sweep retired hopper detections recorded from the link register, which is right —
that register proves nothing. But it also cleared them on robots whose hopper was
genuinely proven, and the replacement evidence is a dispense, which only happens
when the litter is actually low. A well-fed robot could go weeks without one. The
sweep now recognises a previously recorded fill gauge as the proof it is, since
only a dispense can produce that number. - Handling the robot no longer shows up as a cat visit. A Reset press closes a
visit on the same register a cat does; two of them were published as genuine
four-minute and three-minute visits. A visit now needs something to have actually
broken the beam, which a hand on the bonnet does not. - The globe motor fault sensor could sit at
offthrough a real fault. It read
the state document, and the state document does not carry the fault: a robot raised
one on its activity stream, held it for fifty minutes and cleared it, while
globeMotorFaultStatusreported no fault in every single state document it published
in that window. The sensor now watches both channels, and either one raising a fault
is a fault. - The LitterHopper is now detected by watching it deliver litter. The link
register0x57looked like the answer, but a narrated session produced healthy
readings from it with the hopper sitting on a bench, and its "disconnected" code
from merely opening the hopper's drawer to refill it — so a refill could park the
hopper sensor on disconnected with nothing on the wire to ever clear it. Nothing
is derived from that register any more. Hopper reports connected once litter
has actually been dispensed and never reports disconnected, because no signal for
that exists. - A robot that dispenses but rarely reports its link no longer loses its hopper
telemetry. Requiring0x57to corroborate a dispense discarded every fill
reading on such a robot and left its four hopper entities disabled indefinitely. - The hopper level survives a restart. Dispensing only happens when the litter
bed is actually low, so a well-fed robot can go days without one; the last gauge
is now remembered instead of the level reading unknown until it next runs low. - Event sensors now appear only once their fact has actually been reported. Pet
weight, last cat visit, and waste drawer last moved start hidden and switch on at
their first real report — some firmware never emits the drawer event or a weight,
and those sensors read unknown forever there. A one-time sweep on upgrade applies
the same standard to existing installs: sensors whose values were real stay, hopper
and visit-duration detections re-prove themselves at the next report (a robot with
a real hopper re-enables within one visit), and phantom entities disappear. - Last cat visit now updates on every robot. It stamps from the occupancy signal
itself, not only from weight events — one robot has visits but has never weighed
anything, and its visit sensor stayed empty. - Cat detection no longer mistakes weight on the scale for a cat. The occupancy
field is two bits — one for what the robot can see, one for what it can feel — and
a bonnet reseated slightly off held the second bit for over two hours, which the
robot itself reports as an "excess weight" fault. Occupancy and litter calibration
now use the bit that tracks the animal. - Fewer unknowns while calibration settles. The litter calibration reference
shows the built-in default (markedsource: default) instead of unknown, and the
hopper level shows a labelled estimate until the empty floor has actually been
learned. - The weekday sleep schedule now arms every day. It is a per-day bitmask, not a
switch, and turning it on armed Sunday alone — so it looked fine if you tested on
a Sunday and did nothing all week. - The panel sleep schedule can actually be set. The sleep and wake time entities
wrote a register the firmware only computes, so they never did anything. - Litter readings are suppressed while the globe is not level. Mid-cycle the
sensors read the globe rather than the litter, and that was published as a level. robotStatus10 is the clean cycle on every firmware; the old map called it a
cat pause. The boot cycle and the filter-change wizard are mapped too — both move
the globe, and while unmapped their readings published as real litter levels.whiskerless set night-light-mode autoworks. Every spelling the command
accepts used to crash — and it is the command in the README quickstart.- The declared Home Assistant minimum was wrong (2025.2.0), so a user on 2025.2
could install this and watch it fail. It is 2025.3.0. - Every settings write is verified by reading it back, a multi-register write no
longer loses one of its parts, and broker failures are reported rather than raised
as a traceback. - The hopper no longer drops to unknown on a link code that is not a disconnect, and
one dispense can no longer prove an empty hopper on its own.
Changed
- Breaking:
binary_sensor.<robot>_waste_drawer_removedis replaced by
sensor.<robot>_waste_drawer_last_moved. The robot reports that the drawer moved
and never which way — nine codes turned up across removals and insertions alike. - Breaking: clean cycle wait time is a number (3–30 minutes), not a select. Move
automations fromselect.<robot>_clean_cycle_wait_timeto
number.<robot>_clean_cycle_wait_time. - Breaking (library):
Hazard.MOTOR,MotorCommandErrorandallow_motorare
gone. A written press is the same event as a physical one, so the robot's own
interlocks apply either way. Power still requiresallow_dangerous. - Last visit duration is not reported by every robot, so it ships disabled and
switches on the first time yours reports one, rather than reading unknown for the
life of a robot that never will. This was thought to be a firmware split; it is not.
Two robots on the same ESP build sit either side of it.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- The clean cycle and reset buttons are back, and this time they work: they