An ESPHome-based grind-by-weight controller for espresso grinders using:
- a cheap BLE coffee scale
- an ESP32 smart plug with relay output
- fully local, on-device dosing logic
This project lets you plug your grinder into an ESP32 smart plug, pair it with a BLE scale, and dose by target weight automatically.
- Connects to a BLE coffee scale
- Reads live weight updates
- Starts the grinder relay
- Estimates dispense rate in real time
- Predictively stops the grinder before the target is reached
- Learns grinder delay over time to improve accuracy
- Exposes a built-in local web UI
- Works with or without Home Assistant once flashed
This project was built against this very cheap BLE scale:
At the time of writing it was roughly AUD $20.
This was built for the Athom ESPHome-compatible ESP32-C3 AU plug:
- Athom ESP32-C3 AU plug for ESPHome: https://www.athom.tech/blank-1/esp32-c3-au-plug-for-esphome
This project uses ESPHome as the firmware platform, but the actual grind-by-weight logic runs locally on the device.
That means:
- Home Assistant is optional
- Internet access is not required
- Dosing still works if Home Assistant is down
- The device exposes a built-in web interface via
web_server - BLE handling, relay switching, prediction, and delay learning all happen on-device
So while this is packaged as an ESPHome YAML config, operationally it behaves like a standalone local controller.
- Predictive grind-by-weight dosing
- BLE scale integration
- Optional tare before dose
- Learned grind-delay compensation
- Live dispense-rate estimation
- Physical button actions on the smart plug
- Local web interface
- Home Assistant support if you want it
- Fallback AP for recovery
The controller watches live weight notifications from the BLE scale and estimates current grind rate in grams per second.
While dosing:
- the grinder relay turns on
- the device watches the measured weight
- it estimates the current dispense rate
- it predicts where the final weight will land after grinder stop lag
- it turns the grinder off before the target is physically reached
- after settling, it learns from the final error and adjusts the delay parameter
This makes it much more accurate than a simple timed run.
The plug LED is used as a simple connection indicator:
- solid blue when the scale is connected
- blink pattern when not connected to the scale
This switches mains power to your grinder. Use appropriate caution.
A few notes:
- This config is designed for an Athom plug with the pinout used below
- BLE scale protocols vary; this config is written for the scale linked above - you may be able to change it for (for example) the BooKoo scale, but I haven't tried that.
- It will only work with other BLE scales with modification
- Always test with an empty grinder / safe setup first
- Grinder relay control is local, so treat it like any other mains-powered automation
Flash the YAML to a compatible Athom ESP32-C3 AU plug using ESPHome.
Create secrets for:
- Wi-Fi SSID
- Wi-Fi password
- BLE MAC address of your scale, which you can find with any BLE browser app on your phone. I vaguely suspect it's the same on all MY_SCALE devices, D0:4D:00:4F:FE:1A in my case.
Example:
wifi_ssid: "your-wifi"
wifi_password: "your-password"
my_scale_mac: "D0:4D:00:4F:FE:1A"
fallback_ap_password: "change-me"After the device joins Wi-Fi, open its local IP or mDNS name in a browser.
The built-in web interface lets you:
- trigger doses
- stop the grinder
- tare the scale
- adjust parameters
- inspect live states
If you use Home Assistant, the device can also integrate through the ESPHome API.
But it is not required for normal operation.
The goal was a very cheap, very practical grind-by-weight setup.
Using:
- a ~$20 BLE scale
- an ESPHome-capable smart plug
- local logic on the microcontroller
…you can get a surprisingly capable dose-by-weight workflow for very little money.
Known working target hardware:
- Athom ESP32-C3 AU plug
- BLE scale linked above
- Works with my Sunbeam grinder with the dose switch bridged out (I used a piece of cardboard jammed into the grind switch!)
Other BLE scales may work if they use the same service/characteristic layout and packet format.
This repo is intentionally kept as a single ESPHome config for simplicity.
The dosing logic includes:
- rate gating
- smoothing
- predictive stop
- adaptive delay learning
- connection watchdog behaviour
- interlocks for invalid start weights
If you want to adapt it for another scale, the main things to change are:
- BLE MAC
- service/characteristic UUIDs
- payload parsing in
myscale_grams
I'd welcome a PR that supports more types of bluetooth scale.
MIT.