Replacement firmware for the MyBrewbot ESP8266 fermentation controller.
The original firmware depended on mybrewbot.co.uk for cloud
storage, the Blynk App, and OTA updates. All of those are now dead.
This firmware keeps your hardware working:
- All temperature probe control preserved (DS18B20 probes, same addressing)
- Smart plug RF transmit preserved (same codes, same protocol)
- Fermentation profile runner preserved
- Brewfather / Brewer's Friend integrations with per-fermenter toggles
- All JSON config files 100% compatible with original (same field names)
- iSpindel HTTP receiver
- OTA firmware update via web browser
- Tilt hydrometer support via HM-10 BLE module (standard and Tilt Pro)
New/Updated Features:
- Tilt Pro support — auto-detected by broadcast value magnitude; gravity and temperature decoded with correct Pro precision (÷10000 / ÷10), labelled "Pro" in the admin UI
- Brewfather integration uses the Custom Stream API
- MQTT support for publishing fermenter data to any MQTT broker
- Home Assistant MQTT Discovery — auto-creates HA entities with no YAML needed (optional, per-broker toggle)
- Home Assistant MQTT control - see section below
- Full local REST API
- Web-based admin page for configuring probes, fermenters, Tilts, iSpindels, plugs, and services
- mDNS — device registers as
ourbrewbot-CHIPID.localon the local network - LittleFS file browser in admin page for inspecting config files
- BLE AT command console for debugging HM-10 Bluetooth module
- Rebuilt Fermentation Profiles tab — 4 editable profiles with up to 15 steps each, per-fermenter assignment, start/stop/pause, manual step navigation
- Daily firmware update check — tells you (admin page, syslog, Home Assistant) when a newer release is out; it never installs anything itself
- Crash reports — after a crash or watchdog reset, the crash details are sent to ourbrewbot.com to help fix bugs
- Install from your browser at ourbrewbot.com — no tools needed
The update check and crash reports can each be switched off — see Contacting ourbrewbot.com.
Not yet implemented / tested:
- Pressure sensor - Untested - No hardware
Removed:
- mybrewbot.co.uk cloud backend (server gone)
- Blynk dashboard (replaced with REST API + admin page)
- Webhook support - Was added in v0.3, but due to stability & memory issues had to be removed.
The hardware connections were traced with a simple multimeter. Analysis of the previous firmware image was performed by Claude Code. Reverse engineering of the machine code was unfeasible, so instead we pulled generic information from the JSON configuration files and any function name strings/symbols it could find. From this, it was possible to build a basic framework to iterate upon and re-build features.
Pin assignments are in Pins.h using raw GPIO numbers (compatible with both
NodeMCU and generic ESP8266 board targets).
| Function | GPIO | NodeMCU Pin | Label |
|---|---|---|---|
| Probe Bus 1 | GPIO0 | D3 | Green Jack |
| Probe Bus 2 | GPIO2 | D4 | Black Jack |
| RF Transmitter | GPIO4 | D2 | FS1000A TX |
| RF Receiver | GPIO14 | D5 | MX-RM-5V RX |
| BLE (ESP TX) | GPIO12 | D6 | HM-10 BT 4.0 RX ← ESP TX |
| BLE (ESP RX) | GPIO13 | D7 | HM-10 BT 4.0 TX → ESP RX |
| LED | GPIO16 | D0 | NodeMCU LED_BUILTIN |
Download and install from https://code.visualstudio.com/
In VS Code: open the Extensions panel (Ctrl+Shift+X), search for PlatformIO IDE, and install it. Restart VS Code when prompted.
Open the repository root folder in VS Code (File → Open Folder). PlatformIO will detect platformio.ini automatically and install all required libraries and the ESP8266 toolchain on first open.
In platformio.ini, set upload_port and monitor_port to match your device's COM port (currently COM6). Adjust if your port differs.
- Build only: click the checkmark (✓) in the PlatformIO toolbar, or run
PlatformIO: Buildfrom the command palette (Ctrl+Alt+B). - Build and upload: click the right-arrow (→) in the toolbar, or run
PlatformIO: Upload(Ctrl+Alt+U). - Serial monitor: click the plug icon in the toolbar, or run
PlatformIO: Monitor.
Before flashing, back up the full 4 MB flash from your existing MyBrewbot device so you can restore it if needed.
Your config files (probes, fermenters, etc.) live in the LittleFS partition and survive a firmware-only flash — but a full backup protects everything.
Hold the FLASH button, press and release RST, then release FLASH. On NodeMCU boards the USB adapter usually handles this automatically via DTR/RTS when you connect it.
pip install esptool
esptool.py --port COM7 --baud 115200 read_flash 0x0 0x400000 mybrewbot_backup.bin
COM7is an example — check Device Manager (Windows) orls /dev/ttyUSB*(Linux/Mac) for your actual port.
The result is a 4 MB .bin file — store it somewhere safe.
Download and install the tool from the Espressif Flash Download Tool documentation.
- Run
flash_download_tool_x.x.x.exe - Select ESP8266 / Develop / UART
- Open the chipInfoDump tab
- Set start address
0x0and length0x400000 - Select your COM port and click READ — the tool saves the backup as a
.binautomatically
Pre-built binaries are attached to each release on the GitHub Releases page of this repository, named OurBrewbot_vX.Y.Z.bin. You do not need VS Code or PlatformIO installed — just the binary and one of the tools below.
Put the device in bootloader mode as described above before flashing.
Open ourbrewbot.com/install in Chrome or Edge on a desktop computer, connect the device by USB and follow the steps. It always installs the latest release.
esptool.py --port COM7 --baud 115200 write_flash 0x0 OurBrewbot_vX.Y.Z.binReplace
COM7with your actual port andOurBrewbot_vX.Y.Z.binwith the filename downloaded from the Releases page.
- Run the tool, select ESP8266 / Develop / UART
- Click the SPIDownload tab
- Tick the checkbox on the first row, click
...to browse toOurBrewbot_vX.Y.Z.bin, and set the address to0x0 - Set SPI Speed to
40MHzand SPI Mode toDIO - Select your COM port and baud rate to 115200
- Click START
Once the firmware is running, navigate to http://ourbrewbot-XXXXXX.local/update in your browser and upload the .bin file directly.
- On first boot the device creates a WiFi access point named
OurBrewbot-XXXXXX- Make a note of this! - Connect to it from your phone or laptop
- A configuration portal opens — enter your WiFi SSID and password
- The device reboots, connects to your network and registers its name in mDNS
- Open http://ourbrewbot-XXXXXX.local (the XXXXXX noted in step 1) in your browser. If this does not work, find your device's IP from your router admin page, then open
http://DEVICEIP/in a browser.
If you have the original device, its config files are stored in the LittleFS partition.
These should be auto-detected and used if you flash this firmware to the same device (the LittleFS partition is separate and survives firmware updates).
The controller runs entirely on your own network. It only contacts ourbrewbot.com for these two things, and both can be switched off in the admin page on the System Settings tab, under Global Settings:
| Setting | What it does | What is sent |
|---|---|---|
| Update Check | Once a day, downloads http://ourbrewbot.com/version.json and compares it with the running version. The result is shown on the admin page, in syslog and as a Home Assistant update entity. Nothing is downloaded or installed. The [check] link next to the firmware version (POST /update/check) works even when the daily check is off. |
The chip ID and firmware version (used to count the controllers in use) |
| Crash Reports | About 2 minutes after the device restarts from a crash or watchdog reset, it sends one report to http://ourbrewbot.com/api/crash (retried up to 3 times). Nothing is sent after a normal restart. |
The chip ID, firmware version and build date, the reset reason, the last code area that ran, the processor registers, and the top of the stack (raw memory, as hex numbers) |
Neither sends your settings, WiFi details, temperatures or brewing data. The stack snapshot is a few dozen raw memory words from the moment of the crash, used to find which code crashed.
| Method | Endpoint | Description |
|---|---|---|
| GET | / | Welcome / API index page |
| GET | /admin | Admin configuration page |
| GET | /ble/sniff | BLE AT command console page |
| GET | /ble/sniff/poll | Poll BLE serial data |
| POST | /ble/sniff/send | Send AT command to HM-10 |
| GET | /board_info.json | Board info |
| GET | /brewservices | Brew service config |
| POST | /brewservices | Update brew service config |
| POST | /brewservices/test | Test brew service connection |
| GET | /config | WiFi config page |
| GET | /controller | Controller config + plugs |
| POST | /controller | Update global config |
| GET | /debug | Debug mode and per-fermenter sensor overrides |
| POST | /debug | Set debug mode / sensor overrides (runtime only, not saved) |
| GET | /fermenter?id=0 | Single fermenter |
| POST | /fermenter | Update fermenter config |
| POST | /fermenter/profile | Profile control (start/stop/pause/next/prev) |
| GET | /fermenters | All fermenter data (JSON) |
| GET | /fs/file | Read LittleFS file content |
| GET | /fs/files | List LittleFS files |
| POST | /fs/save | Save a LittleFS config file |
| GET | /health | System health |
| POST | /iSpindel | iSpindel gravity data |
| POST | /ispindel/config | Update iSpindel config (fermenter, collect data, clear) |
| GET | /ispindels | iSpindel config + live data |
| GET | /mqtt | MQTT config (includes haDiscovery flag) |
| POST | /mqtt | Update MQTT config (haDiscovery, LWT, discovery cleanup on disable) |
| POST | /mqtt/discover | Trigger HA MQTT discovery |
| POST | /mqtt/test | Test MQTT connection |
| GET | /probes | All temperature probes |
| POST | /probes | Update probe config |
| POST | /profile | Update fermentation profile |
| GET | /profiles | Fermentation profile config |
| GET | /reboot | Reboot device |
| GET | /reset | Reset all config to defaults |
| GET | /rf/sniff | RF sniff page |
| GET | /rf/sniff/poll | Poll RF sniff results |
| POST | /smartplug | Update smart plug config |
| POST | /smartplug/test | Test smart plug RF on/off |
| GET | /smartplugs | Smart plug config (JSON) |
| GET | /status | Quick status all fermenters |
| GET | /syslog | Syslog config |
| POST | /syslog | Update syslog config (host, port, facility, minLevel) |
| POST | /tilt | Update Tilt config (fermenter, function, SG/temp adjust) |
| GET | /tilts | Tilt hydrometer config + live data |
| GET | /update | OTA firmware update page |
| POST | /update | Upload new firmware binary |
| POST | /update/check | Check ourbrewbot.com for a newer firmware now |
| GET | /WiFi | WiFi config page (alias) |
| POST | /wifi/reset | Clear WiFi settings and reboot into the setup portal |
When MQTT is enabled and HA Discovery is turned on, the device publishes Home Assistant MQTT discovery payloads on connect and whenever HA restarts. No manual YAML configuration is needed — entities appear automatically in HA.
Discovery creates one HA device for the controller, one for each fermenter, and one for each configured probe, Tilt and iSpindel. Empty or unassigned slots are skipped.
| HA device | Entity type | Fields |
|---|---|---|
OurBrewbot (controller) |
sensor |
firmware_version, ip_address, mdns_name, wifi_ssid, rssi, free_heap, uptime, chip_id, reboot_reason, reboot_code (all diagnostic) |
button |
reboot, all_off | |
update |
firmware (installed vs latest release, from the daily update check; display-only) | |
OurBrewbot F0–F3 (fermenters) |
sensor |
beer_temperature, ambient_temperature, gravity, gravity_source, attenuation, status, beer_temperature_source, temperature_unit, profile_step, profile_steps |
binary_sensor |
alarm | |
switch |
power, temp_control, profile_running | |
number |
ceiling_temperature, floor_temperature, hysteresis, compressor_delay, og, tg | |
text |
name, beer_name, yeast | |
select |
profile_no (options: 0–4) | |
OurBrewbot Probe <name> |
sensor |
temperature, name, function, fermenter |
binary_sensor |
active | |
OurBrewbot Tilt <colour> |
sensor |
temperature, gravity, fermenter, function |
binary_sensor |
active, is_pro | |
OurBrewbot iSpindel <name> |
sensor |
temperature, gravity, corrected_gravity, battery, rssi, angle, velocity, run_time, name, fermenter, function |
By default the device is read-only from HA's perspective. Enable Allow HA Control in the MQTT settings page to allow Home Assistant to send commands back to the device.
When enabled, the device subscribes to <baseTopic>/+/+/set and accepts commands for all writable entity types (switch, number, text, select, button). Commands are validated — out-of-range values are silently rejected and the HA entity reverts to the actual device state within ~60 seconds via the regular state publish.
When disabled, all discovery entities are still advertised (so the dashboard YAML remains stable), but the device ignores any incoming commands.
A ready-made Lovelace dashboard is provided in HomeAssistant/dashboard.yaml. It requires these HACS frontend cards:
Versions before v0.1.74 published all per-fermenter fields as sensor entities. From v0.1.74 onwards, several fields changed to more appropriate HA entity types (switch, number, text, select). The firmware sends empty retained payloads to the old discovery topics on connect to clean up stale HA entities automatically.
Steps after flashing:
- Flash the new binary via OTA (
http://ourbrewbot-XXXXXX.local/update) or esptool. - Once connected, the device retries HA discovery automatically. If entities don't update immediately, click HA Discover in the MQTT settings page of the admin UI, or reboot the device.
- HA will remove the old
sensor.*entities and create the newswitch.*,number.*,text.*, andselect.*entities. - Replace your Lovelace dashboard with the updated
HomeAssistant/dashboard.yamlfrom this repository. The new YAML references the correct entity types.
Entity ID changes (old → new):
| Old entity ID | New entity ID |
|---|---|
sensor.ourbrewbot_fN_power |
switch.ourbrewbot_fN_power |
sensor.ourbrewbot_fN_temp_control |
switch.ourbrewbot_fN_temp_control |
sensor.ourbrewbot_fN_profile_running |
switch.ourbrewbot_fN_profile_running |
sensor.ourbrewbot_fN_ceiling_temperature |
number.ourbrewbot_fN_ceiling_temperature |
sensor.ourbrewbot_fN_floor_temperature |
number.ourbrewbot_fN_floor_temperature |
sensor.ourbrewbot_fN_hysteresis |
number.ourbrewbot_fN_hysteresis |
sensor.ourbrewbot_fN_compressor_delay |
number.ourbrewbot_fN_compressor_delay |
sensor.ourbrewbot_fN_og |
number.ourbrewbot_fN_og |
sensor.ourbrewbot_fN_tg |
number.ourbrewbot_fN_tg |
sensor.ourbrewbot_fN_name |
text.ourbrewbot_fN_name |
sensor.ourbrewbot_fN_beer_name |
text.ourbrewbot_fN_beer_name |
sensor.ourbrewbot_fN_yeast |
text.ourbrewbot_fN_yeast |
| (new) | select.ourbrewbot_fN_profile_no |
Replace
Nwith the fermenter index (0–3).
Any HA automations, template sensors (binary_sensor.ourbrewbot_fN_online, sensor.ourbrewbot_fN_fermentation_progress, etc.) or Plotly graph history that reference the old sensor.* entity IDs will need to be updated to the new IDs.
OurBrewbot/
OurBrewbot.cpp Main sketch — setup, loop, state machine
Config.h/.cpp All data structures and JSON serialisation
Fermenter.h/.cpp Temperature control loop (heating/cooling/hysteresis state machine)
Temperatures.h/.cpp DS18B20 probe management
SmartPlugs.h/.cpp RF smart plug control
Profile.h/.cpp Fermentation profile runner
Reports.h/.cpp Brewfather / Brewer's Friend reporting
iSpindel.h/.cpp iSpindel WiFi hydrometer receive and registration
Tilt.h/.cpp Tilt hydrometer via HM-10 BLE
Mqtt.h/.cpp MQTT client — publishing, HA discovery, command dispatch
MqttParse.h/.cpp MQTT command-topic parsing (split out so it can be unit tested)
WebAPI.h/.cpp REST API web server
WebAdmin.cpp Admin configuration page (PROGMEM HTML)
Log.h/.cpp Centralised serial & syslog logging with timestamps
Crash.h/.cpp Crash and watchdog-reset details saved across reboot, logged on the next boot
CrashReport.h/.cpp Sends the saved crash details to ourbrewbot.com
UpdateCheck.h/.cpp Daily check of ourbrewbot.com for a newer firmware release
Pins.h Hardware GPIO pin assignments
Version.h Firmware version constants and ourbrewbot.com URLs
OurBrewbot is licensed under the Apache License, Version 2.0. See NOTICE for the copyright notice.
All JSON field names, file paths, REST routes, and error strings are preserved verbatim from the original firmware for compatibility with existing device configs.