What
While the robot is cleaning, the cat-panel status line shows CCP instead of a human-readable label like "Clean Cycle In Progress". Same problem for other states: RDY (Ready), DFS (Drawer Full), CCC (Clean Cycle Complete), EC (Empty Cycle), P (Paused).
The top status bar is not affected — it renders correct labels (⟳ Cycling, ⏸ Paused, ✓ Cycle done) via explicit enum comparisons in _refresh_status. Only the cat-panel status line is broken.
Root cause
asher/monitoring/__init__.py:222 renders status.value (the raw 3-letter Whisker cloud code) instead of status.text (the readable form):
status_str = status.value if status is not None and hasattr(status, "value") else "—"
status_color = STATUS_COLORS.get(status_str, "#3fb950" if online else "#f85149")
Verified against pylitterbot LitterBoxStatus — .value is the cloud code, .text is readable:
| Enum member |
.value (shown, wrong) |
.text (should show) |
CLEAN_CYCLE |
CCP |
Clean Cycle In Progress |
READY |
RDY |
Ready |
CLEAN_CYCLE_COMPLETE |
CCC |
Clean Cycle Complete |
EMPTY_CYCLE |
EC |
Empty Cycle |
PAUSED |
P |
Clean Cycle Paused |
DRAWER_FULL |
DFS |
Drawer Full |
$ uv run python -c "from pylitterbot.enums import LitterBoxStatus; "
READY .value='RDY' .text='Ready'
CLEAN_CYCLE .value='CCP' .text='Clean Cycle In Progress'
CLEAN_CYCLE_COMPLETE .value='CCC' .text='Clean Cycle Complete'
EMPTY_CYCLE .value='EC' .text='Empty Cycle'
PAUSED .value='P' .text='Clean Cycle Paused'
DRAWER_FULL .value='DFS' .text='Drawer Full'
Secondary bug (same line)
STATUS_COLORS in asher/constants.py is keyed on readable strings, but several keys never match an actual .text value — so the color lookup also falls through to the default and the status is always the wrong color:
# current keys that match nothing:
"Cycling" # no .text is "Cycling" — it's "Clean Cycle In Progress"
"Paused" # actual .text is "Clean Cycle Paused"
"Sleeping" # no LitterBoxStatus .text is "Sleeping" (sleep is a separate flag)
Fix
-
asher/monitoring/__init__.py:222 — render .text (matching the _status_text() helper already used by the status/info commands in asher/commands/__init__.py:45):
status_text = getattr(status, "text", None)
status_str = status_text if isinstance(status_text, str) else "—"
status_color = STATUS_COLORS.get(status_str, "#3fb950" if online else "#f85149")
-
asher/constants.py — fix STATUS_COLORS keys to match real .text values:
STATUS_COLORS = {
"Ready": "#3fb950",
"Clean Cycle In Progress": "#58a6ff",
"Empty Cycle": "#58a6ff",
"Clean Cycle Paused": "#d29922",
"Cat Detected": "#d29922",
"Drawer Full": "#f85149",
"Drawer Almost Full - 1 Cycle Left": "#d29922",
"Drawer Almost Full - 2 Cycles Left": "#d29922",
"Clean Cycle Complete": "#3fb950",
"Off": "#f85149",
"Offline": "#f85149",
}
(STATUS_COLORS is only consumed by this one line in monitoring/__init__.py — no other callers or tests reference the old keys, so renaming them is safe.)
Test
Add a Pilot regression test: set mock_robot.status = LitterBoxStatus.CLEAN_CYCLE, run _refresh_status (or _update_cat_panel), and assert the #cat-status widget content contains "Clean Cycle In Progress" and does not contain "CCP". Cover READY and DRAWER_FULL the same way.
Notes
- The narrow cat panel (
width: 22) will clip "Clean Cycle In Progress" by one char — acceptable, still far better than CCP. If desired, a shorter label map (e.g. "Cycling…") could be added later, but matching the rest of the app's status rendering is the correct first fix.
- The
_status_text() helper in commands/__init__.py already does this enum→text conversion; this is a case of two code paths rendering the same field differently.
What
While the robot is cleaning, the cat-panel status line shows
CCPinstead of a human-readable label like "Clean Cycle In Progress". Same problem for other states:RDY(Ready),DFS(Drawer Full),CCC(Clean Cycle Complete),EC(Empty Cycle),P(Paused).The top status bar is not affected — it renders correct labels (
⟳ Cycling,⏸ Paused,✓ Cycle done) via explicit enum comparisons in_refresh_status. Only the cat-panelstatusline is broken.Root cause
asher/monitoring/__init__.py:222rendersstatus.value(the raw 3-letter Whisker cloud code) instead ofstatus.text(the readable form):Verified against pylitterbot
LitterBoxStatus—.valueis the cloud code,.textis readable:.value(shown, wrong).text(should show)CLEAN_CYCLECCPREADYRDYCLEAN_CYCLE_COMPLETECCCEMPTY_CYCLEECPAUSEDPDRAWER_FULLDFSSecondary bug (same line)
STATUS_COLORSinasher/constants.pyis keyed on readable strings, but several keys never match an actual.textvalue — so the color lookup also falls through to the default and the status is always the wrong color:Fix
asher/monitoring/__init__.py:222— render.text(matching the_status_text()helper already used by thestatus/infocommands inasher/commands/__init__.py:45):asher/constants.py— fixSTATUS_COLORSkeys to match real.textvalues:(
STATUS_COLORSis only consumed by this one line inmonitoring/__init__.py— no other callers or tests reference the old keys, so renaming them is safe.)Test
Add a Pilot regression test: set
mock_robot.status = LitterBoxStatus.CLEAN_CYCLE, run_refresh_status(or_update_cat_panel), and assert the#cat-statuswidget content contains "Clean Cycle In Progress" and does not contain "CCP". CoverREADYandDRAWER_FULLthe same way.Notes
width: 22) will clip "Clean Cycle In Progress" by one char — acceptable, still far better thanCCP. If desired, a shorter label map (e.g. "Cycling…") could be added later, but matching the rest of the app's status rendering is the correct first fix._status_text()helper incommands/__init__.pyalready does this enum→text conversion; this is a case of two code paths rendering the same field differently.