Skip to content
 
 

Repository files navigation

Advanced Shot Stopper

Advanced Shot Stopper

Advanced Shot Stopper adds brew-by-weight to an espresso machine: a Bluetooth scale measures the drink, and an ESP32-S3 controller requests a stop near your recipe's target weight. You keep using the machine's physical brew switch.

This repository provides firmware and hardware guidance for a DIY installation. It is a work in progress, not a ready-to-install or certified kit. Development started on the La Marzocco Linea Micra; other switch types have different wiring and stop behavior.

Before installation, read Hardware and complete the applicable bench checks. The relay must remain open on startup, reset, power loss, and safety failure. Machine-specific wiring instructions are incomplete. See the Disclaimer.

Start here

I want to… Read
Check whether my equipment fits Requirements and machine types
Prepare hardware and firmware HardwareBuild and USB installation
Choose a controller and machine build Hardware and machine build profiles
Connect and make the first shot First setup and daily use
Change how brewing works Features and settings
Integrate Advanced Shot Stopper with Home Assistant Home Assistant setup
Understand an unexpected result Troubleshooting
Update or recover the controller OTA / Recovery
Develop or contribute Contributing
Understand the test gates Testing and validation
Look up a technical term Technical glossary
Find a specific reference Documentation index

Requirements

  • Board: the current built-in hardware profiles use an ESP32-S3 N16R8 (16 MB flash / 8 MB PSRAM). The development relay board has a specific GPIO map; another board needs a complete reviewed profile.
  • Scale: a supported Bluetooth model. Bookoo Themis Mini/Ultra were the primary development scales. Check the model and capability table; implemented protocols are not all equally tested.
  • Machine: a compatible activation circuit connected only to isolated relay contacts, plus a physical switch input appropriate to the selected build.
  • Installation skills: identify and verify your machine's electrical connections, build the firmware, and test the installation on a bench.

A printable enclosure is included in standard and thicker versions. PETG is recommended for the thick pair in warmer installations. Classic ESP32, boards without PSRAM, and Timemore scales are outside the current support scope.

How it works

The controller reads your brew switch separately from the machine's activation circuit. It can therefore interpret your gesture and stop brewing according to the scale, recipe guards, or time limits.

On paddle machines, the relay remains closed while brewing and opens to stop. On momentary machines, it copies button presses and sends a pulse to request a stop. Opening that relay alone does not necessarily stop a momentary machine. See the distinctions below before choosing a build.

Machine types

Prefer a named hardware and machine build profile. The selected machine profile resolves the corresponding compile-time type; it is not a Web UI setting.

Build Value How the controller knows the group is running
Paddle / latch 0, default Follows the maintained brew contact. Developed first for the Linea Micra.
Momentary 1 Infers flow from scale readings. Without confirmed flow, an automatic stop pulse may not be sent.
Momentary + reed 2 Uses an additional reed/hall input to observe the machine state. Preferred for momentary installations.

Support for a switch model is not certification of a particular espresso machine. The firmware's 60 s relay limit and the ability to stop water flow are different on momentary machines; read the stop limitations.

This illustration shows the paddle-connector routing used during Micra development. It is not a wiring schematic or pinout; verify the actual machine circuit and follow the hardware safety guidance before installation.

Micra paddle connector and adapter-cable routing on the relay board

Main features

Need Feature
Stop near a recipe weight Brew by weight, with learned drip compensation
Use different recipes Presets, including factory Single and Double
Place the cup after starting Tare and retare
Handle cup removal or bumps Cup protection
Handle unexpectedly fast or slow shots Fast and Slow guards
Limit a shot after scale loss A→M time guard
Rinse with a switch gesture Quick rinse, with a machine-profile default
Hear local feedback Alerts, subject to scale/buzzer capabilities
Review results Shot history and statistics
Integrate with Home Assistant Home Assistant
Update safely over Wi-Fi Dual-slot OTA, with automatic rollback
Send events to another local receiver Local HTTP webhooks

Main settings

Recipe settings live in Settings → Brew. Machine and scale settings are shared across recipes. Presets explains what is saved and what a Home Quick Settings change affects.

The documentation index links each settings group. Defaults are starting points; Fast and Slow guards can intentionally finish above or below the target weight.

Brew by weight: offset and learning factor

Linear regression + offset correction (legacy in API/CSV) applies the full final-weight error to its learned stop offset. Linear prediction + adaptive EWMA applies a fraction, α, of that error. Both stop toward target − learned offset; Baseline offset (g) is the saved reset value for either method, not an additional compensation.

For an eligible EWMA shot, next offset = clamp(offset + α × (final − target), 0, 5). For example, with target 36 g, final weight 36.20 g and offset 1.50 g:

Current α Next offset
0.10 1.52 g
0.30 1.56 g
0.60 1.62 g

A larger α responds faster to changes but also follows individual-shot noise more strongly. A smaller α smooths that noise but adapts more slowly. An underweight result reduces the offset so the next cutoff occurs later. α learns between shots; it does not filter live scale readings or guarantee better accuracy on a particular machine.

Baseline learning factor (α) is saved per preset, from 0.01 to 1.00 in steps of 0.01, initially 0.30. Saving either base preserves current learning. Reset learned stop offset to baseline resets only the selected offset; EWMA keeps its current α. Reset EWMA learning restores both saved bases, marks α initial and clears its evidence. Automatic learning may subsequently choose 0.10, 0.30, 0.50 or 1.00; a custom α remains active until a candidate earns a switch. See BBW learning for eligibility, comparison windows and persistence.

First connection

After installation and bench verification, follow First setup and daily use. It covers connecting to the controller's access point, opening the Web UI, joining home Wi-Fi, selecting a scale, and making the first shot. Factory network details are in AP → First connection.

Admin

Home and Settings use a browser claim; privileged actions also require Admin unlock with the device password. These are separate controls: Web access explains both.

Technical features

Remote start and rinse are disabled by default. A deliberate development build can enable them; they are not part of the default operating workflow. Remote Stop still requires Admin unlock. MQTT and persistent remote-control integrations are outside the project goals. The Web UI provides status and shot summaries, not a guaranteed real-time telemetry stream.

Documentation

Use the complete index for user guides, settings, architecture, validation, and library integration. Read only the page needed for your task; parameter tables and protocol contracts have one canonical home.

Testing and validation

A gate is the set of checks that a change must pass before it can be accepted. The project first classifies the changed files by risk, then runs the matching gate. Higher levels include the lower-level checks, so a safety-critical change receives much more scrutiny than a wording correction. The authoritative rules and exact commands are in Validation gates.

Level What it is for What it checks When it runs
R0 Non-critical documentation and repository metadata Documentation contracts, local links, headings, images, and known paths For documentation-only changes and as the base of every higher gate
R1 Web UI, tests, developer tooling, and isolated logic R0 plus the normal host tests and any focused checks or generated assets relevant to the change While developing these areas and before submitting the finished change
R2 BLE, networking, saved data, OTA, and build changes Full host coverage, ASan/UBSan, TSAN, architecture rules, Web contracts, and every built-in compatible profile pair When a change can affect integration, concurrency, memory safety, or a firmware image
R3 Relay and machine control, ISR, watchdog, boot, GPIO, partitions, remote control, or an unknown path R2 plus stricter compiler warnings, cppcheck, build variants, and the applicable HIL/manual evidence Before accepting any safety-critical or not-yet-classified change
Release A firmware image intended for distribution or installation The complete automated analysis plus resource budgets, applicable soak tests, HIL, and the manual test plan For a release candidate; a passing automated R3 run alone is not release approval

Host tests run on the developer computer or a CI runner, without an ESP32 or espresso machine. They are quick feedback for software behavior, but cannot prove that real wiring, timing, radio conditions, or machine stopping are safe. The focused profiles are:

Profile Purpose When to use it
normal Runs the broad functional host suite without a sanitizer During ordinary development and in every R1-or-higher gate
asan Runs the host suite with ASan and UBSan to expose memory errors and undefined operations For R2/R3 changes and when investigating crashes or suspicious memory behavior
tsan Runs concurrent host scenarios with TSAN to find unsafe access to shared data For R2/R3 changes and whenever task or thread ownership changes
web Verifies generated Web UI assets and browser-facing contracts After changing the Web UI, its source assets, or asset generation
ble Focuses the normal host suite on scale protocols and companion BLE behavior After changing scale communication or BLE protocols
ota Exercises OTA host logic plus command-line and Web resilience cases After changing firmware-update behavior or its interfaces
tooling Checks the developer command facade, risk classification, and validation contracts After changing scripts, CI, or repository workflow rules

In GitHub Actions, classification runs first. The fast job always performs the R0 documentation checks. The host job then runs normal, asan, tsan, tooling, and web for R1-R3 changes. Firmware builds run for R2/R3 pull requests and on pushes to main, weekly scheduled runs, and manual workflow runs. A final job checks that every job required by the classified risk passed. These automated jobs do not flash a board, operate the relay, or replace required HIL and manual evidence.

Technical glossary

Term Meaning in this project
α (alpha) The learning factor used by adaptive EWMA. It controls how much the latest eligible shot changes the learned stop offset.
A→M Automatic-to-manual transition: brew-by-weight can no longer rely on the scale, so a time guard limits the remaining shot.
Admin unlock A password-protected authorization required for privileged Web UI actions; it is separate from claiming the browser session.
AGPL-3.0 GNU Affero General Public License version 3, the repository's current copyleft license. Network use of a modified version can require offering its corresponding source code.
AI Artificial intelligence. The README notes its use during project development.
API Application Programming Interface: a defined way for software components or external integrations to exchange commands and data.
ASan AddressSanitizer, a host-test instrument that detects invalid memory access, such as reading past a buffer or using freed memory.
BLE Bluetooth Low Energy, the wireless link used to communicate with supported scales.
BBW Brew by weight, the feature that uses live scale measurements to request a stop near the recipe target.
Baseline A saved starting value to which learned settings can be reset. It is not an extra correction added to the current value.
Boot / boot verification Boot is the controller's startup process. After OTA, verification confirms that the new image started safely before it is kept.
Browser claim The controller's way of assigning ordinary Home and Settings access to a browser session; it does not grant Admin privileges.
CI Continuous Integration, the automated GitHub Actions checks run for pull requests, pushes to main, scheduled validation, and manual workflow runs.
Clamp To restrict a calculated value to a minimum and maximum; the README's formula keeps the learned offset between 0 g and 5 g.
Compile-time setting A choice fixed while firmware is built. Changing it requires a new build; it cannot be changed later in the Web UI.
CSV Comma-Separated Values, a plain-text tabular format used when exporting or exchanging shot data.
Cutoff / stop offset The point at which the controller requests a stop before the target weight, allowing for coffee that continues to drip. The learned offset is adjusted from previous eligible shots.
DIY Do it yourself: the user assembles, installs, and validates the hardware rather than receiving a certified finished product.
Drip compensation Stopping early enough to account for liquid that continues reaching the cup after the machine receives the stop request.
ESP32-S3 The Espressif microcontroller family on which the controller firmware runs.
ESP-IDF Espressif IoT Development Framework, the supported toolchain and software framework used to build the firmware.
EWMA Exponentially Weighted Moving Average, the adaptive learning method that applies a chosen fraction of the latest final-weight error instead of the entire error.
Firmware Software built to run on the ESP32-S3 controller rather than on the user's computer or browser.
Firmware slot One of the flash-memory regions that can hold a bootable firmware image. OTA writes the inactive slot so the previous image remains available for rollback.
Flash memory Non-volatile storage that keeps firmware when power is removed; it is distinct from working memory such as PSRAM.
Gate The complete set of automated checks and, where required, physical evidence demanded for a change's risk level.
GPIO General-Purpose Input/Output, a configurable electrical pin used to sense a switch or control a signal. Its assignment and polarity are safety-critical here.
Guard A protective rule that stops or limits a shot when measured behavior is outside the recipe's expected conditions.
HIL Hardware in the loop: testing with the real controller or representative electrical hardware so physical timing and I/O behavior can be observed.
Host test A test compiled and run on a computer or CI runner, without operating the ESP32, relay, or espresso machine.
HTTP Hypertext Transfer Protocol, used by the local Web UI, webhooks, and update-related interfaces.
ISR Interrupt Service Routine, code that responds immediately to a hardware event and must obey stricter timing and concurrency rules.
K2 The README's example name for an optional external safety relay or barrier; its actual design depends on the machine and jurisdiction.
MB Megabyte, used here to describe flash and PSRAM capacity.
MIT License The permissive license that applies to identified upstream portions and historical snapshots, not to the repository's current work as a whole.
Momentary machine / pulse A momentary machine changes state after a brief button-like electrical signal, called a pulse, rather than following a maintained switch position.
MQTT Message Queuing Telemetry Transport, a publish/subscribe messaging protocol; persistent MQTT remote control is outside this project's goals.
n8r4 / n16r8 Supported memory variants: the number after n is flash capacity in MB and the number after r is PSRAM capacity in MB.
OTA Over-the-air update: installing firmware over Wi-Fi into an inactive firmware slot, followed by boot verification and possible rollback.
Paddle / latch A maintained physical switch: its state directly represents the requested brew state.
PETG Polyethylene terephthalate glycol, a 3D-printing material recommended for the thicker enclosure parts in warmer installations.
Pinout / GPIO map The documented assignment between board pins and electrical functions. A different board requires a reviewed assignment.
Preset A saved recipe and its related brew settings, such as target weight and learned values.
PSRAM Pseudostatic RAM, external working memory fitted to the supported ESP32-S3 boards.
Reed / Hall input A magnetic sensor input used by the preferred momentary-machine configuration to observe whether the machine is running.
Regression Here, a mathematical method that estimates drip behavior from previous eligible shots to improve the stop point.
Relay / isolated contacts An electrically controlled switch whose contact side is kept separate from the controller side. The project uses it to request machine activation or stopping.
Rollback Returning to the previous bootable firmware image when a new OTA image fails verification.
Sanitizer A test-build instrument that watches a running program for classes of bugs that ordinary functional assertions may miss.
Soak test A long or repeated run used to reveal resource leaks, timing drift, or failures that short tests may not expose.
Static analysis / cppcheck Inspection of source code without executing it, used to detect suspicious constructs and rule violations. cppcheck is one analyzer used by the R3 gate.
Tare / retare Setting the scale's current load to zero; retare repeats that action when the workflow needs a new zero reference.
Telemetry Status or measurement data reported while a system runs. The Web UI is not promised as a guaranteed real-time telemetry channel.
TSAN ThreadSanitizer, a host-test instrument that detects data races: unsafely coordinated simultaneous access to shared data by multiple threads.
UBSan UndefinedBehaviorSanitizer, a host-test instrument that detects invalid C/C++ operations whose result the language does not define.
USB Universal Serial Bus, used to install firmware, monitor serial output, and issue supported maintenance commands.
Watchdog A timer that detects software that has stopped making required progress and triggers a controlled recovery.
Web UI The browser-based user interface served by the controller.
Webhook An HTTP request sent to another local service when a configured event occurs.
Wi-Fi / access point (AP) Wi-Fi is the local wireless network technology; in access-point mode the controller creates its own temporary network for first setup or recovery.

Disclaimer

Use at your own risk. Anyone who builds, installs, configures, or operates firmware from this repository does so under their sole responsibility. The authors and contributors accept no liability for any harm, loss, or damage whatsoever — including but not limited to personal injury, death, property damage, equipment damage, business interruption, or psychological distress — arising from the use or misuse of this software, documentation, or any derivative work.

You are solely responsible for:

  • Designing and building a correct, safe circuit — suitable relay or contact, electrical isolation, ratings, polarity, feedback, and any external safety barrier (e.g. K2) appropriate for your machine and jurisdiction.
  • Installing and verifying that circuit on your equipment, including bench tests and the full manual test plan before connecting to a live espresso machine.
  • Configuring the firmware correctly and safely — including GPIO assignment, compile-time pin maps, polarity, machine circuit limits, and workflow parameters — so that paddle readback, machine control, and automatic stop behavior match your hardware. GPIO and other safety-critical pin assignments are not configurable from the Web UI; they must be set in source and verified at build time (see Hardware and the FAQ).

Espresso machines are inherently hazardous. A machine such as the La Marzocco Linea Micra contains pressurized boilers, hot water, and steam at high temperature. Adding automatic or remote control — including brew-by-weight stop, relay actuation, Wi-Fi commands, and timer-based limits — can increase risk if wiring, isolation, configuration, or software behavior is wrong. Malfunction or misconfiguration could leave the brew circuit energized too long, defeat intended safety interlocks, or cause scalding, flooding, electrical hazard, or fire. Do not connect this firmware to mains-powered espresso equipment unless you understand these risks and have validated your entire system on the bench first.

This project provides software and documentation only. It does not certify, warrant, or guarantee safe operation on any machine. No statement in this repository should be interpreted as professional electrical, plumbing, or machinery safety advice.

This project was developed with substantial assistance from artificial intelligence tools. AI helped with design, implementation, documentation, and testing workflows; human review, hardware validation, and safety judgment remain the author’s responsibility. Use on real espresso equipment only after you have verified wiring, isolation, and behavior on your own setup.

License

Advanced Shot Stopper is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).

You may use, modify, and distribute it freely, including for commercial purposes. If you distribute a modified version, or offer one to users over a network, you must provide the complete corresponding source code under the AGPL. Closed proprietary forks are not allowed.

Earlier snapshots of this repository were published under the MIT License. Those historical releases remain available to their recipients under MIT. Portions derive from tatemazer/AcaiaArduinoBLE (MIT); see LICENSE for the full terms and upstream notice.

Credits

Advanced Shot Stopper is maintained by Felipe Urzúa (cheerpipe@gmail.com) — Cheerpipe/AcaiaArduinoBLE.

It would not exist without tatemazer and tatemazer/AcaiaArduinoBLE. That project proved BLE brew-by-weight stop, shared the core scale protocol work, and shipped the original Shot Stopper as a plug-and-play kit. This application firmware, Web UI, paddle and momentary machine models, and safety workflow are new work on top of that foundation.

Thanks to AtomHeart-Lang for AtomHeart Eclair scale support, contributed upstream in tatemazer/AcaiaArduinoBLE#41. That work is vendored here and keeps Eclair in the supported scale set.

The vendored library also credits:

See the library acknowledgement.

Runtime and tooling:

About

ESP32-S3 firmware that adds hands-off brew-by-weight to espresso machines using Bluetooth scales and a circuit that takes control of the brew switch through a relay to start and stop extraction automatically.

Resources

Contributing

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages