Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

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, and settings are proven on hardware, and the panel actions (clean cycle, reset, empty, power) were recovered in August 2026 — see What's not here for what is still open.


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 against the platinum checklist — fully local, push-first, fully typed. (The quality scale is only awarded to core integrations, so that is the bar it was written to, not a badge it holds.)
  • a whiskerless CLI + 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, and a live telemetry stream. Full detail in docs/how-it-works.md.

Install

Home Assistant (HACS)

  1. HACS → ⋮ → Custom repositories → add https://github.com/SisyphusMD/whiskerless as an Integration.
  2. Install Whiskerless, restart Home Assistant.
  3. Make sure Home Assistant's MQTT integration is connected to your broker.
  4. 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 for your chip (whiskerless-macos-arm64.pkg for Apple Silicon, whiskerless-macos-x86_64.pkg for Intel), double-click to install, then run it in any terminal — it prompts for everything:

    whiskerless provision
    

    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. To update later, just download the newer .pkg and double-click — it installs over the old one in place.

  • Linux — download whiskerless-linux-x86_64 and run it:

    chmod +x ./whiskerless-linux-x86_64
    ./whiskerless-linux-x86_64 provision
    
  • Windows — no standalone binary, but the PyPI CLI works nativelybleak drives Windows' built-in Bluetooth:

    uvx --from 'whiskerless[ble]' whiskerless provision
    

    (Don't run the Linux binary under WSL: WSL can't reach the Bluetooth adapter, so provisioning won't work there.)

Prefer not to install anything? uvx --from 'whiskerless[ble]' whiskerless provision runs it one-shot (the [ble] extra brings in the Bluetooth stack that provisioning needs — plain uvx whiskerless installs the base package without it).

CLI / library (PyPI)

  • One-shot, no install: uvx --from 'whiskerless[ble]' whiskerless provision
  • CLI on your PATH: pipx install whiskerless
  • Library + BLE re-provisioning: pip install 'whiskerless[ble]'

Quickstart (CLI)

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

Watch it:

whiskerless monitor --serial LR4Cxxxxxx --host <broker-ip> --ca ca.crt

Read its decoded state:

whiskerless state --serial LR4Cxxxxxx --host <broker-ip> --ca ca.crt

Change a setting (writes, then reads back to confirm):

whiskerless set night-light-mode auto --serial LR4Cxxxxxx --host <broker-ip> --ca ca.crt

Safety first

This library talks straight to a robot's controller, and some opcodes can reset it or, in the worst case, brick a control board. So it guards every send:

  • Four opcodes are refused unconditionally (0xA3, 0xA4, 0xAC, 0xAD — reset / main-board-OTA orchestrator, globe-motor OTA, flash erase, hardware reset). No flag lets them through.
  • The destructive panel combos are refused too — factory reset, plug pull and onboarding mode are all one write away from the clean cycle, so 0x01 is whitelisted by value, not opened as a register.
  • Power needs an explicit opt-in, because a robot switched off has left the network and nothing over MQTT can switch it back on.
  • Untraced / control-band / calibration writes are refused unless you override them on purpose.

The routine presses — clean cycle, reset, empty — are ungated. Writing the panel button register reproduces the exact code the panel emits, so the robot cannot tell it from a finger, and the firmware's pinch, cat-detect and bonnet interlocks apply either way.

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

The filter-change wizard, and it is not coming. Its panel chord is a long press, and the firmware performs short presses over MQTT while silently declining long ones — so every hold-only function is out of reach by this route. Whisker's own cloud has no long-press command either; it reaches those settings by writing registers, which is what whiskerless already does for panel lockout, the night light, the cycle delay and the sleep schedule.

Empty and Power ship disabled by default. Their codes are captured from physical presses but nobody has written one yet, and both are expensive to get wrong: an empty cycle costs a litter refill, and Power can leave the robot off the network. Enable them deliberately or use the CLI, which prompts.

See the reverse-engineering writeup. 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

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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

whiskerless-0.2.0rc9.tar.gz (254.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

whiskerless-0.2.0rc9-py3-none-any.whl (65.1 kB view details)

Uploaded Python 3

File details

Details for the file whiskerless-0.2.0rc9.tar.gz.

File metadata

  • Download URL: whiskerless-0.2.0rc9.tar.gz
  • Upload date:
  • Size: 254.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.7

File hashes

Hashes for whiskerless-0.2.0rc9.tar.gz
Algorithm Hash digest
SHA256 dfd903d8db21cde68db715e56c9be7a40305b525c87f81c7401d186e21b3fb61
MD5 e326eb6b0329e7285a87b812d40f69bd
BLAKE2b-256 85dfb1696c15765e9c4682af3af6281f22089fffec516dd4edb1999867b30e51

See more details on using hashes here.

File details

Details for the file whiskerless-0.2.0rc9-py3-none-any.whl.

File metadata

  • Download URL: whiskerless-0.2.0rc9-py3-none-any.whl
  • Upload date:
  • Size: 65.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.7

File hashes

Hashes for whiskerless-0.2.0rc9-py3-none-any.whl
Algorithm Hash digest
SHA256 ebed4fc5fc094be3ade15d6354b31343db65b981848f4bfb467f5bf360f66ffa
MD5 ac991c3235af133a43e5184bae283a5c
BLAKE2b-256 494ac9e787e694a454ed2105eed4ac4a191407475a62d30de14d5743d8b1bed2

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.0rc9 This release

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page