Un-cloud your Whisker devices — fully-local MQTT control + telemetry for the Litter-Robot 4.
Project description
whiskerless
Un-cloud your Whisker devices. Fully-local MQTT control and telemetry for the Whisker Litter-Robot 4 — no cloud account, no internet round-trip, no third-party servers. Your robot talks to your broker, and that's it.
Primary repository: developed at forgejo.bryantserver.com/SisyphusMD/whiskerless. The GitHub copy is a read-only mirror (HACS installs from it). Please file issues and pull requests on GitHub — the Forgejo repository does not take external issues.
Status: beta. The local protocol was recovered by reverse-engineering and validated against a real robot. Re-provisioning, telemetry, settings, and the clean cycle are proven on hardware. A few discrete actions (power, empty, resets) are intentionally left out — see What's not here.
Why
Out of the box, a Litter-Robot 4 only works through Whisker's AWS cloud: every status update and every button press makes a round-trip to the internet, and Whisker actively blocks third-party clients. whiskerless cuts the cloud out entirely. The robot keeps its firmware; you just re-point its MQTT trust + broker at your own, over its own BLE provisioning channel — no teardown, no UART, no reflash, and fully reversible.
You get:
- a Home Assistant integration (HACS) built to the Platinum quality bar — fully local, push-first, fully typed;
- a
whiskerlessCLI + Python library to provision, monitor, read, and control a robot directly; - a complete, public protocol reference — the first published map of the LR4 local MQTT protocol.
How it works (30 seconds)
BLE (one-time) re-point trust + broker runtime (forever after)
your laptop ───► CA + host + topics over protocomm ───► robot ──MQTT/TLS──► your broker ──► Home Assistant
The robot stores all of its cloud identity in NVS and exposes esp-idf
protocomm provisioning over BLE with no PIN. whiskerless writes your CA into
its root-CA slot and your broker IP as its host, then commits. From then on the
robot connects to your broker over TLS and speaks plain JSON — requestState,
settings writes, clean cycle, and a live telemetry stream. Full detail in
docs/how-it-works.md.
Install
Home Assistant (HACS)
- HACS → ⋮ → Custom repositories → add
https://github.com/SisyphusMD/whiskerlessas an Integration. - Install Whiskerless, restart Home Assistant.
- Make sure Home Assistant's MQTT integration is connected to your broker.
- Provision each robot onto that broker (below). It then appears on its own under Settings → Devices & Services as a Discovered device — click Add and give it a name. No broker details or serials to type.
See docs/setup/ for the broker, certificate, and discovery details.
The "app" — no Python needed (for provisioning)
Re-provisioning happens over Bluetooth from a computer near the robot. Grab the build for your OS from the releases page — Forgejo (primary) or GitHub (mirror):
-
macOS — download the signed installer (
whiskerless-macos-arm64.pkgor-x86_64.pkg), double-click to install, then run it in any terminal:whiskerless provision # prompts for everything
It's signed and notarized by Apple, so there's no "unidentified developer" warning. The first time it scans, macOS asks to let your terminal use Bluetooth — allow it.
-
Linux — download
whiskerless-linux-x86_64and run it:chmod +x ./whiskerless-linux-x86_64 ./whiskerless-linux-x86_64 provision
Prefer not to install anything? uvx whiskerless provision runs it one-shot.
CLI / library (PyPI)
uvx whiskerless provision # one-shot, no install
pipx install whiskerless # CLI on your PATH
pip install 'whiskerless[ble]' # library + BLE re-provisioning
Quickstart (CLI)
# 1. Re-provision the robot onto your broker (one-time, over BLE).
# Prompts for anything you omit; --host-ip is your broker's address.
whiskerless provision --serial LR4Cxxxxxx --host-ip <broker-ip> --ca ca.crt --wifi-ssid MyIoT
# 2. Watch it.
whiskerless monitor --serial LR4Cxxxxxx --host <broker-ip> --ca ca.crt
# 3. Read its decoded state.
whiskerless state --serial LR4Cxxxxxx --host <broker-ip> --ca ca.crt
# 4. Change a setting (writes, then reads back to confirm).
whiskerless set night-light-mode auto --serial LR4Cxxxxxx --host <broker-ip> --ca ca.crt
# 5. Run a clean cycle (asks for confirmation first).
whiskerless clean-cycle --serial LR4Cxxxxxx --host <broker-ip> --ca ca.crt
Safety first
This library can put commands on the wire that drive a motor or, in the worst case, brick a control board. So it guards every send:
- Three opcodes are refused unconditionally (
0xAC,0xA4,0xAD— flash erase, globe-motor OTA, hardware reset). No flag lets them through. - The clean cycle (the only motor command) requires explicit opt-in and the CLI/integration gate it behind a confirmation.
- Untraced / control-band / calibration writes are refused unless you override them on purpose.
The guard lives in safety.py and both the CLI and
the integration funnel through it — see docs/devices/litter-robot-4/.
What's not here
Power on/off, the empty cycle, and the panel/drawer resets are deliberately
omitted. Reverse-engineering could not pin their exact register+value to safe,
actionable confidence (the relevant firmware partition is physically absent from
the public image and the candidates are unproven and contradictory). Shipping
them as guesses would risk dangerous control-band writes. They're tracked as open
items with a clear path to close them — see
docs/devices/litter-robot-4/compatibility.md
and the issue templates. Contributions welcome.
Repository layout
whiskerless/
├─ src/whiskerless/ # the pip library (codec, MQTT, BLE, safety, CLI)
│ └─ devices/litter_robot_4/ # LR4 protocol: codec, commands, state model, link
├─ custom_components/whiskerless/ # the Home Assistant integration (depends on the lib)
├─ docs/ # protocol reference + setup + recovery guides
├─ examples/ # example automations
└─ tests/ # codec / safety / command / integration tests
Documentation
- How it works · Reverse-engineering writeup · Recovery
- Setup: MQTT broker · Certificates · Home Assistant
- LR4 protocol: protocol · commands · registers · compatibility
Adding another Whisker device
The library is structured so a new robot drops in under
src/whiskerless/devices/<x>/ (codec + commands + state model) and
custom_components/whiskerless/devices/<x>.py, reusing the shared MQTT transport,
BLE provisioning, and safety guard. See CONTRIBUTING.md.
License
MIT. Not affiliated with or endorsed by Whisker. "Litter-Robot" is a trademark of its respective owner; this project is independent and interoperates with hardware you own.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file whiskerless-0.1.0.tar.gz.
File metadata
- Download URL: whiskerless-0.1.0.tar.gz
- Upload date:
- Size: 79.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a74985aa3170d4bbf94aba9710594ac1f7e43079604b3243a76e1b3d3a8a9f1
|
|
| MD5 |
a51d0652016311e1c21759ef099b0485
|
|
| BLAKE2b-256 |
7b5a701267cbbcb6b0ed2b9d91db2324e10a1bd980b261c52805ddf674e3dcd5
|
File details
Details for the file whiskerless-0.1.0-py3-none-any.whl.
File metadata
- Download URL: whiskerless-0.1.0-py3-none-any.whl
- Upload date:
- Size: 41.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7960a5eb7070913edc941510a593787d4356f2a4ad5db069dabd261d59eee124
|
|
| MD5 |
776c619df2fed3c35820393621712948
|
|
| BLAKE2b-256 |
5c2a3b5bfc5319cad2ecb7fb4a84e906c2fb49e6ea686cffb6b130ee2cb00b9f
|