Connect an iRobot Roomba to your WiFi network from the command line — no iRobot app, no iRobot account, and no internet access required. Works for putting a robot on an isolated/no-internet VLAN for purely local control (Home Assistant, dorita980, roombapy, etc.).
Tested end-to-end on a Roomba 694 (R694020, firmware 3.5.68) on modern Linux (Python 3.14, OpenSSL 3.x). Should also work on 600/800/900-series and other firmware v2/v3 robots — see the flag guide below.
- Original library: NickWaterton/Roomba980-Python (MIT)
- WiFi provisioning (
initwifi.py) concept: kFYatek/Roomba980-Python, branchinitwifi - Password-from-cloud research: Matthew Garrett
- MQTT protocol knowledge: koalazak/dorita980
This fork repairs the code for modern OpenSSL/Python, fixes several bugs, and adds flags needed for robots (like 600-series firmware 3.5.x) whose provisioning behavior differs from what the original code assumed.
- Python 3.6+ (tested up to 3.14)
pip install -r requirements.txt- paho-mqtt must be 1.x — 2.x changed the client API and will crash. The requirements file pins this.
tzlocalandpytzare optional (auto-detection of timezone/country).
-
Install dependencies first (you'll lose internet in step 3):
pip install -r requirements.txt
-
Put the robot in AP (provisioning) mode. With the robot awake and docked, press and hold the HOME button (~2 seconds) until it chimes and the WiFi light flashes green. It now broadcasts a network named
Roomba-XXXXXXXXXXXXand sits at192.168.10.1. -
Connect your computer to that
Roomba-...network. -
Run the provisioning script from inside the
roomba/directory (the imports are flat — it will not work from the repo root):cd roomba python initwifi.py -s 'YourSSID' -p 'YourWifiPassword' -w -n "Kitchen Roomba"
Use single quotes around the SSID and password so your shell doesn't mangle special characters. See the flag guide for whether you need
-w,-P, or-H. -
Save the credentials it prints. The lines
blid is: XXXXXXXXXXXXXXXX Password=> :1:1234567890:abcdefghijklmnop <= Yes, all this string.are the robot's permanent local MQTT credentials. Every local-control tool (this library, dorita980, roombapy, Home Assistant's iRobot integration) needs them. If you run with
-wmore than once, each run rotates the password — the printout from the last successful run is the one that counts. -
Hands off for a minute or two after
Provisioning information sent. Success: the WiFi light goes solid, and the robot's MAC shows up in your DHCP server. Failure: a sad beep and a red WiFi light — see Troubleshooting.
| Flag | What it does | When to use it |
|---|---|---|
-s SSID |
Target network SSID | Always (or you'll be prompted) |
-p PASSWORD |
Target network password | Always (or you'll be prompted) |
-n NAME |
Set the robot's name | Optional |
-w / --set_password |
Set a fresh MQTT password directly instead of trying to read one first | Recommended for factory-fresh robots. Required on robots (e.g. 600-series fw 3.5.x) that drop out of AP mode the moment the password read endpoint is touched |
-P / --plain_password |
Send the WiFi password plaintext instead of hex-encoded | Firmware reports ver: 3 but actually expects v2-style plaintext (600-series fw 3.5.x does). Symptom: robot associates with the AP but WPA auth fails |
-H / --hidden |
Skip the robot's SSID visibility scan (chkssid: false) |
Hidden (non-broadcast) SSIDs |
-x / --skip_password |
Attempt provisioning with dummy MQTT credentials | Diagnostic only; known to be rejected (rc=5) on tested firmware |
-R IP |
Robot's IP address | Default 192.168.10.1 is correct in AP mode |
-T / -c |
Timezone / country override | If tzlocal/pytz are absent or wrong |
-S / -N / -C |
Service discovery URL / NTP hosts / cloud env | Advanced: pointing the robot at non-iRobot infrastructure |
A known-good invocation for a Roomba 694 on firmware 3.5.68:
python initwifi.py -s 'MySSID' -p 'MyPassword' -w -P -n "My Roomba"Once you have credentials, you can log into the robot (in AP mode at
192.168.10.1, or on your LAN at its DHCP address) and dump its stored
network configuration:
python netinfo.py -R 192.168.10.1 -b YOURBLID -p ':1:1234567890:abcdefghij'It queries netinfo/wlcfg/sys and decodes any hex-encoded stored SSID to
plaintext (lines marked ***) so you can verify the robot stored exactly the
SSID you intended. Also handy as a quick "do my credentials work?" test.
| Symptom | Cause / fix |
|---|---|
SSL: UNSAFE_LEGACY_RENEGOTIATION_DISABLED |
OpenSSL 3.x vs the robot's ancient TLS stack. Fixed in this fork (legacy renegotiation flag). Update your copy |
SSL: WRONG_SIGNATURE_TYPE |
Robot signs the TLS handshake with SHA-1. Fixed in this fork (SECLEVEL=0) |
RuntimeError: no current event loop |
Python 3.10+ asyncio change. Fixed in this fork |
TypeError mentioning CallbackAPIVersion |
paho-mqtt 2.x installed. pip install "paho-mqtt<2" |
| Robot answers UDP discovery, then the WiFi light goes solid white and it vanishes mid-run | Your robot kills its AP when the password read endpoint is touched. Re-enter AP mode and use -w |
Connected with result code 5 |
The robot's MQTT broker rejected the credentials. Use -w to set a known password |
Password read returns f005efcc3b2903 (note trailing 03) |
A password exists but the robot won't reveal it without a HOME-button press. Either press-and-hold HOME until the beep and retry within ~30 s (robot on your LAN), or use -w to rotate it (AP mode) |
| Sad beep + red WiFi light ~30–60 s after provisioning | The robot failed to join the network. Check, in order: (1) the SSID exists on 2.4 GHz (600/800/900-series have no 5 GHz radio); (2) security is WPA2-PSK/AES — not WPA3 or WPA2/WPA3 transition mode, and no TKIP; (3) hidden SSID → re-run with -H; (4) shell didn't mangle your credentials → single-quote them; (5) AP logs show the robot's MAC with Authentication failed despite a correct password → re-run with -P |
| Robot joins WiFi but never reaches the iRobot cloud | Expected on no-internet VLANs — local control works fine. The robot's local MQTT broker (port 8883) is always available on its LAN IP |
Compatibility fixes:
- TLS contexts now set
OP_LEGACY_SERVER_CONNECTandSECLEVEL=0so modern OpenSSL 3.x can talk to the robot (both the password channel and MQTT) asyncioevent loop creation fixed for Python 3.10+/3.14- Bundled
password.pywas an older version missingset_new_password_on_roomba()thatinitwifi.pycalled — restored from the original fork - Restored methods/properties that the "WiFi-only" trim removed but left
referenced (
timer,changed,previous,mssnM,rechrgM,bin_full,cleanMissionStatus,pose,sku,calc_mssM, plus stubs for the removed mapping code) — previously crashed withAttributeErroron every robot message
Behavior/robustness fixes:
- Single-session password negotiation: if the robot reports "no password set", the new password is set on the same TLS connection instead of reconnecting (some robots leave AP mode within seconds)
- UDP discovery returns immediately when a specifically-targeted robot answers, instead of always waiting out the 10-second timeout
- MQTT connect loop now aborts after repeated auth rejections instead of retrying forever
- The state machine is firewalled so unexpected errors in it can't disrupt provisioning
- Hex dumps of all password-channel traffic at DEBUG level, plus negotiated TLS version/cipher logging
New options:
-w/--set_password— set the MQTT password directly, never touching the read endpoint (required on robots whose AP mode dies when the read endpoint is poked)-P/--plain_password— send the WiFi password plaintext (600-series firmware 3.5.x reportsver: 3but expects v2-style plaintext)-H/--hidden— provision onto hidden SSIDs (chkssid: false)-x/--skip_password— diagnostic: attempt provisioning with dummy credentials- New
netinfo.pytool for dumping/verifying the robot's stored network config, with hex SSID decoding
The robot runs its own MQTT-over-TLS broker on port 8883 at its LAN IP, independent of any cloud connectivity. Your saved blid/password work with:
roomba.pyin this repo- dorita980
- roombapy / Home Assistant's iRobot integration (enter blid + password when adding the integration)
Give the robot a DHCP reservation — the robot itself always uses DHCP.
MIT, same as the upstream projects. See LICENSE.