Skip to main content

MEATER BBQ probe monitor with Matrix alerts and SIP phone call notifications

Project description

black-lint mypy and pytests BuildAndPushMultiarch Cumulative Clones Docker Pulls PyPI Downloads PyPI

Gemini_Generated_Image_vka2wyvka2wyvka2_250x250.png

wachtmeater

MEATER BBQ probe monitoring with Matrix chat alerts and SIP phone call notifications. Scrapes MEATER Cloud cook pages via CDP (Chrome DevTools Protocol), posts status updates to E2E-encrypted Matrix rooms, and calls you when something needs attention (fire out, target reached, stall, cook ended, etc.). Supports automatic per-cook Matrix room creation and TOML-based configuration.

Why this exists

Long cooks — brisket, pulled pork, pork belly — routinely run 10 to 16 hours. You go to sleep, and while you sleep the fire can go out, the meat can stall for hours, or the target temperature gets reached with nobody there to pull it off. By the time you notice, the cook is ruined or at least far from ideal.

wachtmeater watches the MEATER Cloud page continuously and reaches out only when something actually needs your attention. Periodic Matrix messages give you the full picture at a glance — current internal and ambient temps, elapsed time, remaining estimate — so you can check in whenever you want without opening an app.

When things go sideways (or the cook finishes), a SIP phone call is triggered automatically. A phone call is the reliable escape hatch here: push notifications are easy to sleep through, but a ringing phone is not.

Tip: Save the calling number as a contact on your phone and mark it as a VIP / priority / starred contact. That way the call bypasses Do Not Disturb mode and actually wakes you up at 3 a.m. when your brisket hits target.

Screenshots

Real-world Beef Brisket cook, ~14 hours, monitored from start to finish.

Matrix chat mid-cook status: 86 °C internal, 9 h 22 min elapsed

Matrix status update mid-cook — 86 °C internal, 9 h 22 min elapsed.

MEATER Cloud dashboard showing 5 minutes before cook ends, 94 °C with 95 °C target

MEATER Cloud dashboard showing "5 minutes before cook ends" — 94 °C with 95 °C target.

Matrix chat near-end status: 94 °C internal, 13 h 36 min elapsed

Matrix status update near the end — 94 °C internal, 13 h 36 min elapsed.

MEATER Cloud finished cook summary: target 95 °C, peak 94 °C, approximately 14 hours

MEATER Cloud finished cook summary — target 95 °C, peak 94 °C, total time ~14 hours.

Components

Module Description
meater_watcher Persistent async event loop: periodic MEATER checks + Matrix command interface
meater_monitor Single-shot CDP scraper: extracts temperatures, status, timing from a MEATER Cloud cook URL
create_meater_watcher_job Deploys the watcher stack as a Kubernetes Job (Namespace, ConfigMap, Secret, Job)
call_pitmaster Triggers a SIP phone call via sipstuff-operator

CLI Sub-Commands

Sub-command Purpose
wachtmeater watcher [--skip-startup-test-call] Persistent watcher event loop with Matrix listener
wachtmeater monitor [<url>] Single-shot MEATER status check via CDP
wachtmeater call <text> Trigger a SIP phone call via sipstuff-operator
wachtmeater send-matrix <text> [--image PATH] [--room ID] Send message (and optional screenshot) to Matrix rooms
wachtmeater deploy --meater-url <URL> [--delete] Deploy/delete MEATER watcher K8s Job

Matrix Commands

Send these in the Matrix room the bot has joined (case-insensitive):

Command Description
status Fetch and post current MEATER status
enable tempdown Enable ambient temp drop alert (fire out detection)
disable tempdown Disable ambient temp drop alert
enable ruhephase <temp> Enable rest/cooldown alert at target temp (C)
disable ruhephase Disable rest/cooldown alert
enable stall [<delta>] Enable stall detection (optional: min rise in C)
disable stall Disable stall detection
enable wrap <temp> Enable wrap reminder at internal temp (C)
disable wrap Disable wrap reminder
enable ambient <min> <max> Enable ambient range alert (min/max C)
disable ambient Disable ambient range alert
enable cookend Enable cook-end detection (auto-stop)
disable cookend Disable cook-end detection
reset stall Reset stall alert (re-arms after it fired)
reset wrap Reset wrap alert (re-arms after it fired)
hilfe / help / ? Show available commands
stop / quit / beenden / exit Shut down the watcher loop

Cook-End Detection

When cookend is enabled, the watcher uses four independent mechanisms to detect that a cook has finished:

# Mechanism Trigger Default threshold
A Consecutive fetch errors CDP scrape fails N times in a row COOKEND_ERROR_THRESHOLD = 3
B Probe removed Internal temp drops below threshold after having been above 50 °C COOKEND_PROBE_REMOVED_TEMP = 35.0 °C
C Status "done" MEATER reports internal temp ≥ target
D MEATER Cloud "finished" Cook page shows summary view (#cook.finished CSS class)

Mechanisms A, B, and D post a Matrix message and trigger a SIP phone call. Mechanism C sets cook-ended state silently (the watcher loop posts a generic shutdown message). The watcher loop stops automatically once any mechanism fires.

Configuration

Settings are loaded from a TOML config file (wachtmeater.toml or path in $CONFIG), a flat .env file, or plain environment variables. Existing env vars always take precedence. See wachtmeater.toml.example for a full annotated example.

Variable Description Default
MEATER_URL MEATER Cloud cook URL to monitor — (required)
BROWSER_CDP_URL CDP endpoint for headless Chrome http://chrome-kasmvnc.kasmvnc.svc.cluster.local:9222
SCREENSHOT_DIR Directory for cook page screenshots /data
STATE_FILE_DIR Directory for the JSON state file /data
STATE_FILE_NAME State file name (auto-generated from cook UUID when empty) ""
CHECK_INTERVAL Seconds between periodic checks 600
STALL_WINDOW Number of consecutive checks for stall detection 3
AMBIENT_TEMP_DROP_THRESHOLD Ambient temp drop (°C) to trigger fire-out alert 10
COOKEND_ERROR_THRESHOLD Consecutive fetch errors before declaring cook ended 3
COOKEND_PROBE_REMOVED_TEMP Internal temp (°C) below which probe counts as removed 35.0
MATRIX_HOMESERVER Matrix homeserver URL http://synapse.matrix.svc.cluster.local:8008
MATRIX_USER Matrix bot user ID — (required)
MATRIX_PASSWORD Matrix bot password — (required)
MATRIX_ROOM Default room ID or alias to join !exampleroom:matrix.example.com
MATRIX_AUTO_CREATE_ROOM Auto-create an E2E-encrypted Matrix room per cook UUID false
MATRIX_PITMASTER Matrix user ID to invite into auto-created rooms ""
CRYPTO_STORE_PATH Path for E2E encryption crypto store /data/crypto_store
AUTH_METHOD Auth method (password or jwt) password
KEYCLOAK_URL Keycloak base URL (required if jwt)
KEYCLOAK_REALM Keycloak realm name
KEYCLOAK_CLIENT_ID Keycloak client ID
KEYCLOAK_CLIENT_SECRET Keycloak client secret ""
JWT_LOGIN_TYPE Matrix login type for JWT com.famedly.login.token.oauth
SOPERATORURL sipstuff-operator call endpoint http://sipstuff-operator.sipstuff.svc.cluster.local/call

Installation

pip install wachtmeater

From source

git clone https://github.com/vroomfondel/wachtmeater.git
cd wachtmeater
make install
source .venv/bin/activate

Running locally

# Single status check
./runcli.sh monitor

# Persistent watcher with Matrix listener
./runcli.sh watcher

Override settings in runcli.local.include.sh (sourced automatically, gitignored).

Kubernetes Deployment

wachtmeater deploy --meater-url https://cooks.cloud.meater.com/cook/<uuid>

This creates: Namespace meater, ConfigMap with scripts, Secret with .env, and a Job running xomoxcc/wachtmeater:latest.

To tear down (deletes the per-cook Job, Secret, and ConfigMap; the shared meater namespace is kept):

wachtmeater deploy --meater-url https://cooks.cloud.meater.com/cook/<uuid> --delete
Alternative: module invocation
python -m wachtmeater.create_meater_watcher_job \
  --meater-url https://cooks.cloud.meater.com/cook/<uuid>
python -m wachtmeater.create_meater_watcher_job --delete

Development

Target Description
make install Create virtualenv and install all dependencies
make tests Run pytest
make lint Format code with black (line length 120)
make isort Sort imports with isort
make tcheck Static type checking with mypy (strict)
make commit-checks Run pre-commit hooks on all files
make prepare Run tests + commit-checks
make pypibuild Build sdist + wheel with hatch
make pypipush Publish to PyPI with hatch

License

This project is licensed under the LGPL where applicable/possible — see LICENSE.md. Some files/parts may use other licenses: MIT | GPL | LGPL. Always check per‑file headers/comments.

Authors

  • Repo owner (primary author)
  • Additional attributions are noted inline in code comments

Acknowledgments

  • Inspirations and snippets are referenced in code comments where appropriate.

⚠️ Note

This is a development/experimental project. For production use, review security settings, customize configurations, and test thoroughly in your environment. Provided "as is" without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software. Use at your own risk.

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

wachtmeater-0.0.2.tar.gz (41.5 kB view details)

Uploaded Source

Built Distribution

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

wachtmeater-0.0.2-py3-none-any.whl (46.2 kB view details)

Uploaded Python 3

File details

Details for the file wachtmeater-0.0.2.tar.gz.

File metadata

  • Download URL: wachtmeater-0.0.2.tar.gz
  • Upload date:
  • Size: 41.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.16.5 cpython/3.14.4 HTTPX/0.28.1

File hashes

Hashes for wachtmeater-0.0.2.tar.gz
Algorithm Hash digest
SHA256 a830d07f1126378f7db4469afa0cc07acc4db4f251a32036cf04d939b99a0c4a
MD5 8f639944690f7b5d06e5726be984b920
BLAKE2b-256 65d5cec8b85bf9bd7dcb43bb3081284d6d909812fab5f42d107a0df631f5e080

See more details on using hashes here.

File details

Details for the file wachtmeater-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: wachtmeater-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 46.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.16.5 cpython/3.14.4 HTTPX/0.28.1

File hashes

Hashes for wachtmeater-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e83b2e54177666a9b643d2fa12bf8110002b5908becc56501a1f8c968bdfadcc
MD5 373c631e7d72a37712e45d6a6be17729
BLAKE2b-256 209e05c4d7eb4ad2505d3fabe86b77bc72b6df31ac1c3d25a43edd5e60d1a189

See more details on using hashes here.

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