Skip to content

About

Cloud emulator for Roomba V4 robots

Resources

Stars

11 stars

Watchers

1 watching

Forks

Repository files navigation

Roomba Cloud

Tests Latest release Publish release Container image License: MIT

Roomba Cloud is a local replacement for the cloud services used by iRobot V4 robots. It lets a compatible robot connect to your own server, keeping its telemetry and maps on your network and making them available to Roomba Local for Home Assistant. No custom robot firmware is required; we provision the robot over Bluetooth.

This is an independent project, not affiliated with iRobot.

Supported models

Model Tested firmware Status
Roomba 505/507 p25-505+9.3.6+I3.8.149 Physically tested

Other V4 models have not been verified.

Requirements

  • A domain name you control, with a publicly trusted TLS certificate for it. The emulator includes ACME/Let's Encrypt support
  • A server running Docker with TCP ports 443 (HTTPS) and 8883 (MQTT) reachable from the robot and 443 reachable from Home Assitant
  • A Bluetooth-capable computer near the robot for provisioning, with Python and Bluetooth access. This can be a different computer from the server.
  • ⚠️ The roomba requires an NTP server to continue functioning. You can either allow NTP traffic from it to the internet, or setup your own NTP server and point *.irobot.pool.ntp.org to it.

Keep the emulator on a trusted, firewalled LAN. Do not expose it to the Internet.

Installation

1. Prepare DNS

Configure DNS so that roomba.example.com (your domain) resolves to your Docker server's LAN address from the robot's network. Keep the default published ports, 443 and 8883, available. This A record can be local, it doesn't need to be on public DNS.

2. Choose one installation method:

Docker Compose

Download the Compose file and environment template from the latest stable release:

mkdir roomba-cloud
cd roomba-cloud
curl -fL https://github.com/carbon198/roomba-cloud/releases/latest/download/compose.yaml -o compose.yaml
curl -fL https://github.com/carbon198/roomba-cloud/releases/latest/download/default.env.example -o .env.example
cp .env.example .env
mkdir -p certs

1. Configuration

Edit .env and set:

HOSTNAME=roomba.example.com

Leave the port and storage settings at their defaults.

2. Choose how to obtain a certificate

Option A: Built-in Let's Encrypt DNS validation

In .env, leave TLS_CERT and TLS_KEY empty and set:

TLS_CERT=
TLS_KEY=
ACME_EMAIL=you@example.com
ACME_AGREE_TOS=true
ACME_STAGING=false

Use your own email address. Set ACME_AGREE_TOS=true only after accepting the Let's Encrypt subscriber agreement. You will need to add a TXT to your DNS provider record after starting the containers below.

Option B: Supply an existing certificate

Click to Expand

Copy the full certificate chain and matching unencrypted private key into certs/fullchain.pem and certs/privkey.pem.

Set these values in .env:

TLS_CERT=/certs/fullchain.pem
TLS_KEY=/certs/privkey.pem

The containers run as UID/GID 10001, so give that user access:

sudo chown 10001:10001 certs certs/fullchain.pem certs/privkey.pem
sudo chmod 700 certs
sudo chmod 600 certs/fullchain.pem certs/privkey.pem

User-supplied certificate and ACME are mutually exclusive.

3. Download and start the server

docker compose pull
docker compose up -d
docker compose logs -f https

If using built-in Let's Encrypt, wait for an acme_dns_challenge event:

{"event":"acme_dns_challenge","name":"_acme-challenge.roomba.example.com","type":"TXT","value":"<challenge value>"}

Add the exact TXT value at the public DNS name shown in the log. Leave the containers running: the server waits for DNS propagation, then requests the certificate automatically. It allows up to 30 minutes for propagation. If the attempt times out, follow the logs for the next attempt and its current value.

Automating DNS updates with another app (optional)
Click to Expand

The HA addon includes a sensor with the TXT challenge value. If you can update your DNS provider within HA, using an automation is probably the easiest route. The sensor value will be Unknown when no TXT update is needed.

The HTTPS service also writes /data/dns-challenges/challenge.json:

{"name":"_acme-challenge.roomba.example.com","type":"TXT","value":"<challenge value>"}

The separate Compose dns-challenges volume contains only these public challenge details.

Have your DNS updater read /challenges/challenge.json, add the TXT value through your DNS provider. When the cert is renewed, challenge.json will be deleted.

4. Get the customer token

The customer token is your login credential and is generated automatically on first startup

docker compose exec https cat /data/customer-token.txt

Paste the key into the web login page at https://<your-hostname>. Save it somewhere; the same key is also used by Home Assistant to authenticate.

Manual container setup

Click to Expand
Setting Value
Image repository ghcr.io/carbon198/roomba-cloud
Image tag Your chosen release tag, or latest
Published TCP ports (host → container) 443 → 8443 and 8883 → 8883

With host networking, omit port mappings and set HTTPS_PORT=443 and MQTT_PORT=8883.

Environment and certificates

Set HOSTNAME=roomba.example.com to your DNS hostname. Configure DNS as described in the Compose instructions. HTTPS is advertised on the standard public port 443.

For built-in Let's Encrypt, set these additional variables:

Variable Value
ACME_EMAIL Your email address
ACME_AGREE_TOS true, after accepting the Let's Encrypt terms

Leave TLS_CERT and TLS_KEY unset in this mode. Alternatively, mount supplied certificates as described below and set TLS_CERT=/certs/fullchain.pem and TLS_KEY=/certs/privkey.pem, leaving ACME options unset. Other settings can remain at their defaults.

Storage

Storage Mount inside container Access
Roomba Data/Maps /data Read/write
DNS challenge directory (optional for sharing with an updater) /data/dns-challenges Read/write
Supplied certificate directory (not needed for built-in ACME) /certs Read-only

The private /data directory must be owned by UID/GID 10001 with mode 0700. Keep it on local storage supporting Unix sockets.

Start and sign in

Start the container. For built-in ACME, watch its logs and complete the TXT challenge as described above, or have your DNS updater read the shared challenge directory. MQTT waits until the certificate is available.

Open your configured HTTPS address. In your container manager's console run:

cat /data/customer-token.txt

Use that customer key to sign in, then continue to Bluetooth provisioning.

Native Python installation (without Docker)

Click to Expand

Download the source first:

git clone https://github.com/carbon198/roomba-cloud.git
cd roomba-cloud

From that repository directory:

python3.14 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
mkdir -p tools
cc -O2 -Wall -Wextra -Werror native/mqtt_tls_bridge.c -o tools/mqtt_tls_bridge -lssl -lcrypto

Run these in two terminals, both in the repository directory. These examples use sudo to bind HTTPS port 443; both processes must run as the same user and share the same data directory.

# Terminal 1
sudo .venv/bin/python -m roomba_cloud mqtt \
  --hostname roomba.example.com --https-port 443 --data-dir ./data \
  --acme-email you@example.com --acme-agree-tos
# Terminal 2
sudo .venv/bin/python -m roomba_cloud https \
  --hostname roomba.example.com --https-port 443 --data-dir ./data \
  --acme-email you@example.com --acme-agree-tos

Retrieve the key with sudo cat ./data/customer-token.txt. These commands run in the foreground; arrange service supervision yourself if needed.

Provision the robot over Bluetooth

Start the emulator and verify its HTTPS page works before provisioning. Provisioning changes the robot's Wi-Fi and cloud settings and will disconnect the robot from the cloud. It won't break Matter integrations though. There is no need to factory reset the robot. The emulator will pull your existing maps from the robot.

Provisioning does not have to run on the emulator server. Clone or download this repository on any Bluetooth-capable computer, move near the robot, and run the tool there.

Install the provisioning tool

Download the source on the Bluetooth computer, if you do not already have it:

git clone https://github.com/carbon198/roomba-cloud.git
cd roomba-cloud

From that repository directory:

Linux / macOS

python3 -m venv .venv
.venv/bin/python -m pip install -r requirements-provisioning.txt
.venv/bin/python -m provisioning.ble_provision --ssid 'YOUR_WIFI_SSID' \
  --domain roomba.example.com --country US --timezone America/New_York

Windows (PowerShell)

py -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements-provisioning.txt
.\.venv\Scripts\python.exe -m provisioning.ble_provision --ssid "YOUR_WIFI_SSID" --domain roomba.example.com --country US --timezone America/New_York

Replace the Wi-Fi name, country, and timezone with your own values.

Follow the prompts

  1. Keep the robot nearby and ready for Wi-Fi/Bluetooth setup. Select a Bluetooth adapter if prompted, then select your robot from the scan results.
  2. Enter the Wi-Fi password at the hidden prompt.
  3. Follow the authorization prompt. If requested, press the robot's Power button once after it beeps. An already authorized robot may proceed without another button press.
  4. Wait while settings are written and the robot joins Wi-Fi. The tool displays a generated robot password once; retain it privately if needed. This is not the customer key used to sign in.
  5. Open the dashboard link, sign in with your customer key, and confirm the robot appears with an online MQTT connection.

If you encounter issues, add --debug to the provisioning command for additional diagnostics

Using the web interface

Open your configured HTTPS address and enter the customer key. The browser remembers it across refreshes and restarts until you Sign out or clear the site's stored data. Use this only on a trusted device.

The dashboard provides:

  • Robot status: robot ID, reported model/SKU, IP address, MQTT connection, battery, mission phase, firmware, and last-seen time. It refreshes automatically.
  • Maps and rooms: open a robot's room editor and select a saved map to view it.
  • Map editing: rename rooms, split a room, merge adjacent rooms, or delete an available map. These actions change the robot's saved map, not just the displayed image. Map changes cannot be reverted.

Editing and deletion require the robot to be idle with no mission. Controls are locked during running or paused missions, or when mission state is unknown. After an edit, wait for the robot's updated map before making another change. Maps and room details appear as the robot reports them; missing data is not necessarily a setup failure.

For cleaning controls and day-to-day automation, install Roomba Local for Home Assistant and follow its setup instructions. Use the emulator's HTTPS address, customer key, and the robot ID shown on the dashboard.

Reconnecting to Roomba's Cloud

If you want to reconnect your Roomba to the manufacturer's cloud, simply follow the Change Wi-Fi process in the Roomba Home app. Click your robot -> Robot Settings -> Change Wi-Fi.

FAQ

Q: Why can't we do all this in a Home Assistant App? A: I would like to, but I haven't been able to coerce the Roomba to connect on non-standard HTTPS and MQTT ports. Most people already use 443 and 8883 on Home Assistant and the Roomba does some weird MQTT stuff that Mosquitto doesn't handle.

Q: Will this wipe my Roomba? A: No, the provisioning is the same as the Roomba Home app's Change Wi-Fi feature. It does not wipe the robot

Q: Can I use my existing maps? A: Yes please do, the emulator will pull them from the robot automatically

Q: Should I block the Roomba's internet? A: I do, and you probably should. I can't guarantee they won't block this provisioning process in the future. Be sure to provide NTP server access to it as detailed in the Requirements section above.

Q: Can this brick the Roomba? A: No not to my knowledge, we aren't flashing the firmware. Using the map editor always entails some risk you might lose or corrupt your maps, but that's the extent of the risk.

Q: Do I need to backup the /data folder? A: Not really. All the historical state will be in Home Assistant. If you need to setup this project on a new server you can reprovision the robot, repoint Home Assistant and everything will continue working as normal.

Q: Can the emulator restore maps to a robot? A: I've been researching that but I haven't figured out how to get the robot to download them as yet.

Q: Do V4 Roombas not have a local MQTT server? A: They do, but it isn't for local robot control. It only turns on when sending it certain bluetooth commands and it appears to be for firmware provisioning. One promising thing about that is it looks like you can upload new firmware signing keys, so custom firmware for these robots may be possible in the future.

About

Cloud emulator for Roomba V4 robots

Resources

Stars

11 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages