Skip to main content

The proactive companion for GaggiMate espresso machines: post-shot logging bot, .slog decoder, shot-journal site generator

Project description

matebot

A post-shot companion for GaggiMate espresso machines.

I kept forgetting to log my shots. Not for lack of caring — but after every shot the ritual was: pull out the phone, open the web UI, find Shot History, tap edit, type everything in. Most days that didn't happen, and by 23:47, lying in bed, the grind setting of today's best shot was gone for good.

matebot turns the workflow around: when a shot finishes, the machine messages you and asks the few things you'd otherwise forget — rating, taste, beans, grind, doses. Thirty seconds of tapping while you sip. The answers are written straight back into GaggiMate's own Shot Notes, exactly as if you'd typed them into the web UI.

matebot asking for a shot rating on Telegram right after the shot finished

What it does

  • Watches the machine over its WebSocket API and detects finished brew shots (backflush/descale/flush runs and anything under 10 s are ignored).
  • Runs a short questionnaire via Telegram or Discord (Matrix planned), with one-tap "same as last shot" defaults for beans, grind and dose.
  • Saves the answers into the machine's shot history — GaggiMate stays the source of truth, with or without matebot.
  • Optionally archives every shot (.slog + notes), your brew profiles and machine settings (credentials redacted) to a git repository after each shot.
  • Generates a static shot journal from that archive, ready for GitHub Pages. Because the journal lives outside the machine, it survives firmware updates and downgrades, a dying SD card, or a water-damaged machine.
  • Ships a standalone .slog decoder (matebot decode shot.slog --csv).
  • After a sour, bitter or low-rated shot it suggests the next dial-in step (grind → ratio → temperature, one variable at a time), following modsmthng's Automatic Pro cheat sheet — disable with MATEBOT_HINTS=0.

The shot journal

Live example — every shot with the familiar combined pressure/flow/temperature chart, phase markers, ratings and notes.

Shot journal list with ratings, ratios and peak pressure Per-shot detail with combined pressure/flow/temperature chart

Install

Docker

mkdir matebot && cd matebot
curl -O https://raw.githubusercontent.com/AlexNly/matebot/main/docker-compose.example.yml
cp docker-compose.example.yml docker-compose.yml
# edit: machine host, bot token, chat id
docker compose up -d

Images are multi-arch (amd64 + arm64, so a Raspberry Pi works): ghcr.io/alexnly/matebot:latest. There is no cloud service behind this — the bot needs to run on something in your home network that is always on. A Pi Zero 2 W and a USB charger is the whole data center.

pip

pipx install "matebot[telegram]"   # or: pip install "matebot[telegram]"
matebot run

NixOS (flake)

inputs.matebot.url = "github:AlexNly/matebot";

services.matebot = {
  enable = true;
  machineHost = "192.168.1.50";
  environmentFile = "/etc/secrets/matebot";  # TELEGRAM_BOT_TOKEN=... / TELEGRAM_CHAT_ID=...
  dataRepo = "/var/lib/gaggimate-journal";    # optional
};

Setup

  1. Telegram: create a bot with @BotFather (/newbot), copy the token. Message your bot once, then read your chat id from https://api.telegram.org/bot<TOKEN>/getUpdates. Discord: create an application + bot, invite it to a server, enable the message content intent, copy the channel id.
  2. Point MATEBOT_MACHINE_HOST at your GaggiMate. A DHCP reservation is more reliable than gaggimate.local.
  3. Pull a shot.

Chat commands

Besides the post-shot questionnaire, the bot answers commands (any messenger):

/wake     turn the machine on — pings you when it's at temperature
/sleep    back to standby
/status   mode, boiler temperature, water level
/last     the last logged shot (with journal link if configured)
/fix      redo the questionnaire for the last shot
/help     list commands

Smart plug cold start (optional)

GaggiMate in standby still draws power, so many people cut it at a smart plug — which normally kills /wake. Give MATEbot the plug's on/off commands and /wake becomes a true cold start (plug on → wait for the machine to boot → brew mode → ready ping), while /sleep powers everything down:

# Tasmota (Nous A1T, Eightree, ...)
MATEBOT_WAKE_HOOK='curl -sf "http://192.168.1.60/cm?cmnd=Power%20On"'
MATEBOT_SLEEP_HOOK='curl -sf "http://192.168.1.60/cm?cmnd=Power%20Off"'

# Shelly
MATEBOT_WAKE_HOOK='curl -sf "http://192.168.1.60/relay/0?turn=on"'

Any shell command works (Home Assistant webhook, tinytuya, zigbee2mqtt…).

Configuration

Environment variables, or the same keys in ~/.config/matebot/config.toml:

Variable Default Meaning
MATEBOT_MACHINE_HOST gaggimate.local GaggiMate hostname/IP
MATEBOT_MESSENGER telegram telegram or discord
TELEGRAM_BOT_TOKEN / TELEGRAM_CHAT_ID Telegram credentials
DISCORD_BOT_TOKEN / DISCORD_CHANNEL_ID Discord credentials
MATEBOT_DATA_REPO Path to a git clone; enables archive + journal
MATEBOT_SITE_TITLE Shot Journal Title of the generated journal
MATEBOT_JOURNAL_URL Public journal URL, used for /last deep links
MATEBOT_HINTS 1 Dial-in hints after sour/bitter/low-rated shots
MATEBOT_STATE_DIR ~/.local/state/matebot Bot state (defaults, resume)
MATEBOT_MIN_SHOT_S 10 Ignore shots shorter than this
MATEBOT_IGNORE_PROFILES (?i)backflush|descale|flush|clean Profile regex to skip

CLI

matebot run                 # the bot (--replay frames.jsonl --dry-run to test)
matebot decode SHOT.slog    # .slog -> JSON (--csv for CSV)
matebot sitegen shots/ -o docs/ --title "My Shot Journal"
matebot sync                # one-off journal sync (shots, profiles, settings, site)

Publishing your journal on GitHub Pages

  1. Create a repo for your data, clone it where matebot runs, set MATEBOT_DATA_REPO to the clone.
  2. On GitHub: Settings → Pages → Deploy from branch → main / /docs.
  3. Every shot now updates https://<you>.github.io/<repo>/.

How it talks to the machine

Local network only — nothing leaves your LAN except the messenger API and your own git remote. Requires GaggiMate firmware ≥ v1.7 (binary shot logs).

  • ws://<machine>/wsevt:status for shot detection, req:history:notes:save for notes, req:profiles:list for backup
  • GET /api/history/index.bin, <id>.slog, <id>.json — shot downloads
  • GET /api/settings — settings backup; WiFi/AP/Home-Assistant credentials are redacted before anything is written to disk

The .slog v5 binary format (512-byte header, 26-byte samples at 250 ms) is documented in src/matebot/slog.py.

WhatsApp?

There is no reasonable self-hosted WhatsApp bot API. Two workable paths: bridge your Telegram/Matrix chat via mautrix, or Meta's WhatsApp Business Cloud API (requires a business account). Native support: contributions welcome.

Credits

  • GaggiMate by jniebuhr — the machine controller this companion talks to.
  • The journal's shot chart recreates the look of GaggiMate's own web UI (independent reimplementation — GaggiMate's UI code is CC BY-NC-SA and none of it is copied). Rendered with Chart.js and chartjs-plugin-annotation (MIT, vendored).
  • The dial-in hints follow the guide from Automatic Pro cheat sheet by modsmthng.

License

MIT. Not affiliated with the GaggiMate project.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

matebot-0.2.2.tar.gz (647.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

matebot-0.2.2-py3-none-any.whl (133.6 kB view details)

Uploaded Python 3

File details

Details for the file matebot-0.2.2.tar.gz.

File metadata

  • Download URL: matebot-0.2.2.tar.gz
  • Upload date:
  • Size: 647.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for matebot-0.2.2.tar.gz
Algorithm Hash digest
SHA256 7cde0c051022bc7cd191defe3cf495dc51cb22559ebd86a864080d035c9e3ef2
MD5 8884193f1c7b9c81ccfe24645687a930
BLAKE2b-256 ed815a30c28ec977d5b00e1498779515f2c1296741d47f2634d38720aad7caf4

See more details on using hashes here.

Provenance

The following attestation bundles were made for matebot-0.2.2.tar.gz:

Publisher: release.yml on AlexNly/MATEbot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file matebot-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: matebot-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 133.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for matebot-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 71add29f65c14caf1e652971267322e51bf3b0dfbac9ddbcef1dcd96dce792e1
MD5 ff188c21f57d6b430197d921159a72cd
BLAKE2b-256 ccc1d612936d7e8cd23fa8e5cdc3c6ad04d085b8ecb0997a1fcf53e27c074d4e

See more details on using hashes here.

Provenance

The following attestation bundles were made for matebot-0.2.2-py3-none-any.whl:

Publisher: release.yml on AlexNly/MATEbot

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page