Ollama Monitor¶
Autonomes Anomalie-Monitoring für Home Assistant mit dreistufiger Eskalationskette: Direkt-Fix → Ollama → Claude → User.
Komponenten¶
| Script | Trigger | Funktion | | /config/tools/ollama_monitor.py | alle 10 Min | Anomalie-Erkennung + 3-stufiger Fix | | /config/tools/ollama_reporter.py | So 18:00 | Wöchentlicher Home-Report via Telegram | | /config/tools/claude_queue_processor.py | alle 10 Min | Claude löst eskalierte Tasks | | /usr/anatol/claude/scripts/arr_webhook.py (NAS) | Webhook Port 8090 | Smarte Fehlermeldungen (Sonarr/Radarr/Lidarr/SABnzbd) | | /config/tools/telegram_watchdog.sh | alle 5 Min | Überwacht bun-Prozess, meldet per Telegram wenn tot |
Eskalationskette¶
Anomalie erkannt
│
▼
Stufe 1: Direkt-Fix — bekannte Aktionen (turn_off) direkt via HA API
│ nicht möglich
▼
Stufe 2: Ollama-Fix — fragt Ollama nach passendem HA Service-Call
Prompt: Problem + Snapshot → KANN_FIXEN: ja/nein + DOMAIN/SERVICE/ENTITY_ID
Führt Service-Call aus + prüft VERIFY_STATE nach 3s
│ nicht möglich
▼
Stufe 3: Claude-Queue — JSON-Task in /config/tools/claude_queue/
claude_queue_processor läuft alle 10 Min, ruft claude direkt auf (KEIN Wrapper!)
│ Claude scheitert
▼
Telegram-Meldung + 24h Cooldown für dieses Problem
Anomalie-Checks¶
| Check | Bedingung | Stufe | | NAS-Disks | ≥ 95% → hoch, ≥ 90% → mittel | Claude-Queue | | Licht + niemand zuhause | switch/light on + both not_home | Direkt turn_off | | 3D-Drucker | Plug on + Status unavailable | Claude-Queue | | Ollama Catch-All | Snapshot-Analyse durch Ollama (max 3 Anomalien) | Claude-Queue |
Deduplizierung: /config/tools/anomaly_state.json
- Normaler Cooldown: 2h
- Nach Claude-Eskalation (FAILED): 24h — Wert wird als failed: gespeichert
Konfiguration¶
Shell-Commands (configuration.yaml)¶
shell_command:
ollama_monitor_run: "nohup python3 /config/tools/ollama_monitor.py > /tmp/ollama_monitor.log 2>&1 &"
ollama_reporter_run: "nohup python3 /config/tools/ollama_reporter.py > /tmp/ollama_reporter.log 2>&1 &"
claude_queue_process: "nohup python3 /config/tools/claude_queue_processor.py > /tmp/claude_queue.log 2>&1 &"
telegram_watchdog_run: "sh /config/tools/telegram_watchdog.sh >> /tmp/telegram_watchdog.log 2>&1"
Wichtig: nohup ... & ist Pflicht — HA tötet shell_commands nach 60s.
HA Automations¶
| Entity-ID | Trigger | | automation.ollama_anomalie_monitor_alle_10_min | time_pattern minutes: /10 | | automation.claude_queue_processor_alle_10_min | time_pattern minutes: /10 | | automation.ollama_wochentlicher_home_report_so_18_00 | weekday: sun, time: 18:00 | | automation.telegram_watchdog | time_pattern minutes: /5 |
Claude-Queue¶
/config/tools/claude_queue/ — Offene Tasks (JSON-Dateien)
/config/tools/claude_queue/failed/ — Claude konnte nicht helfen (Telegram + 24h Cooldown)
/config/tools/claude_queue/resolved.log — Protokoll erfolgreich gelöster Tasks
Task-Format (inkl. anomaly_key seit 2026-05-04):
{
"id": "20260504_120000_ollama_monitor",
"source": "ollama_monitor",
"description": "NAS sdd1 zu 96% voll (kritisch!)",
"context": "Schwere: hoch | Entity: keine",
"ollama_attempt": "Ollama-Fix gescheitert: Ollama kann nicht helfen",
"anomaly_key": "nas_disk_sdd1_95",
"created": "2026-05-04T12:00:00"
}
anomaly_key wird vom Processor genutzt um bei FAILED den Cooldown auf 24h zu setzen.
Rate-Limit: out of extra usage → Task bleibt in Queue und wird beim nächsten Run erneut versucht.
Wichtig: Claude wird DIREKT aufgerufen (kein Wrapper)¶
claude_queue_processor.py ruft Claude nicht über /usr/local/bin/claude (Wrapper) auf, sondern direkt:
CLAUDE_BIN = "/usr/local/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe"
subprocess.run([CLAUDE_BIN, "--dangerously-skip-permissions",
"--allow-dangerously-skip-permissions", "-p", prompt], ...)
Grund: Der Wrapper fügt --channels plugin:telegram hinzu. Im Subprocess-Kontext startet das einen zweiten Telegram-Bot → 409-Konflikt → erster Bot (MCP-Verbindung der Hauptsession) stirbt.
Der Wrapper selbst ist ebenfalls gepatcht: bei -p-Aufrufen wird --channels nicht hinzugefügt.
Telegram Watchdog¶
Script: /config/tools/telegram_watchdog.sh — läuft alle 5 Min via HA Automation.
Prüft:
- Ist der bun-Prozess am Leben? (pgrep -f "bun.*telegram")
- Antwortet der Bot korrekt? (getUpdates — Zombie-Detection)
Bei Problem: Nur Benachrichtigung via Telegram Bot API (kein automatischer Restart!).\ Grund: Auto-Restart würde den laufenden Konversations-Kontext von Claude Code zerstören.
Notify-Lock: /tmp/telegram_watchdog_notified — verhindert Spam. Wird gelöscht wenn Bot wieder OK.
Manueller Restart: HA → Add-ons → Claude Code (04e1c827-claude-terminal) → Neustart\ → Nur machen wenn keine wichtige Konversation läuft!
Ollama¶
| Modell | Größe | Verwendung | | qwen2.5:7b | 4.7 GB | Standard (Catch-All, Fix-Layer, Report, 600 Token/180s) | | qwen2.5:3b | 1.8 GB | Nur für schnelle State-Queries |
API: http://192.168.178.20:11434/api/generate\
GPU: AMD Radeon RENOIR via Vulkan (~5.5 t/s)
Logs & Diagnose¶
# Monitor-Ausführung
cat /tmp/ollama_monitor.log
# Claude-Queue-Prozessor
cat /tmp/claude_queue.log
# Wöchentlicher Report
cat /tmp/ollama_reporter.log
# Watchdog
cat /tmp/telegram_watchdog.log
# Offene Tasks
ls /config/tools/claude_queue/*.json 2>/dev/null
# Fehlgeschlagene Tasks
ls /config/tools/claude_queue/failed/
# Cooldown-Status (failed: = 24h, ISO = 2h)
cat /config/tools/anomaly_state.json
# Telegram Bot Status (ok+result=aktiv, result leer=Zombie)
curl -s "https://api.telegram.org/bot8685305507:.../getUpdates?limit=1"
Behobene Bugs¶
| Datum | Bug | Fix |
| 2026-05-03 | shell_command 60s Timeout: save_known() nie aufgerufen → Cooldown versagte → Spam | nohup + & für alle shell_commands |
| 2026-05-03 | ha_call() mit None entity_id → {"entity_id": null} → HA API Fehler | entity_id if entity_id else "" |
| 2026-05-03 | Dead Code: check_nas_disks() definiert aber nie aufgerufen | Entfernt |
| 2026-05-04 | --channels im Subprocess: Wrapper fügte Telegram zu claude -p hinzu → zweiter Bot → 409 → MCP-Disconnect | CLAUDE_BIN direkt + Wrapper überprüft -p Flag |
| 2026-05-04 | Disk-Check Regex zu eng: nur sda1/sdb1/nvme explizit geprüft | Generischer Regex sd[a-z]\d+ | nvme\d+ | md\d+ | dm-\d+ |
| 2026-05-04 | Endlosschleife bei unlösbaren Problemen: alle 2h neue Eskalation | 24h Cooldown via failed:-Prefix in anomaly_state |
Token-Spar-Tools für Claude (2026-05-04)¶
Drei Tools reduzieren Clauds Token-Verbrauch indem häufige Abfragen (Entity-Suche, Kontext-Sammlung, State-Abfrage) in lokale Dateien vorberechnet werden.
1. Erweiterter State-Snapshot¶
ha_state_snapshot.py (alle 2 Min via Automation) wurde um zwei neue Sektionen erweitert:
Neu: Fehlgeschlagene Integrationen
Neu: Kürzlich geänderte Entities (15 Min) Nur interessante Domains (person, device_tracker, light, switch, media_player, etc.) — keine Sensoren/Power-Readings.
Claude liest: cat /config/tools/state_snapshot.txt statt MCP-ha_get_state-Calls.
2. Entity-Alias-Map¶
Datei: /config/tools/entity_aliases.json
Mapping von Kurznamen → entity_id für alle häufig verwendeten Geräte:
{
"tv": "media_player.wohnzimmer_tv",
"receiver": "media_player.pioneer_vsx_s520d_e41051",
"arnold": "vacuum.arnold_schwarzensauger",
"drucker": "sensor.centauri_carbon_print_status",
"pv": "sensor.pv_eingang_power",
...
}
Claude liest: cat /config/tools/entity_aliases.json statt ha_search_entities MCP-Calls.
Pflege: Manuell aktualisieren wenn neue Geräte hinzukommen oder entity_ids sich ändern.
3. Problem-Kontext-Tool¶
Script: /config/tools/problem_context.py
Output: /tmp/problem_context.txt
Sammelt automatisch alles Relevante zu einem Gerät/Problem: - Gefundene Entity-States (via Alias + Fuzzy-Search) - Integration-Status (setup_retry, failed, reason) - Logbook letzte 2h - Relevante Zeilen aus state_snapshot.txt
Beispiel-Output:
### Problem-Kontext: vidaa_tv — 2026-05-04 23:34
-- GEFUNDENE ENTITIES (2) --
media_player.wohnzimmer_tv: unavailable (Wohnzimmer-TV)
update.vidaa_tv_update: off
-- INTEGRATION STATUS --
vidaa_tv 'Wohnzimmer-TV': setup_retry | Reason: Failed to connect to TV at 192.168.178.54
-- LOGBOOK (letzte 2h) --
...
-- AKTUELLER SYSTEM-SNAPSHOT (relevant) --
✗ vidaa_tv: Wohnzimmer-TV (setup_retry)
Claude braucht damit nur 1 Read-Call statt 4-6 API-Calls zum Sammeln von Kontext.
Anwendungs-Workflow (CLAUDE.md)¶
# Gerätestatus prüfen:
cat /config/tools/state_snapshot.txt
# Entity-ID finden:
cat /config/tools/entity_aliases.json
# Problem debuggen:
python3 /config/tools/problem_context.py
cat /tmp/problem_context.txt
Docker Auto-Updater (2026-05-05)¶
Täglich automatisches Update aller stale Docker-Container auf dem NAS.
Script: /usr/anatol/claude/scripts/docker_auto_updater.sh\
Cron: täglich 09:00 (nach watchtower-check um 08:05)\
Log: /tmp/docker_auto_updater.log
Ablauf¶
1. Watchtower (monitor-only) → erkennt stale Container
2. Filter: alles mit "postgres" im Namen/Image wird übersprungen
3. Watchtower (--run-once) → updated verbleibende Container
4. Telegram-Bericht: was wurde aktualisiert, was übersprungen
Ausnahmeliste¶
| Muster | Grund |
| postgres | Datenbankupdates können Breaking Changes haben |
Beispiel Telegram-Meldung¶
Manueller Aufruf¶
Monitoring: sensor.ollama_status¶
Hinzugefügt: 10.05.2026
Ein REST-Sensor überwacht Ollama direkt aus Home Assistant:
| Parameter | Wert | | Entity | sensor.ollama_status | | Package | /config/packages/docker_monitor.yaml | | Endpoint | http://192.168.178.20:11434/api/version | | Polling | alle 2 Minuten | | Wert (online) | Ollama-Versionsnummer (z.B. 0.23.2) | | Wert (offline) | unavailable → wird vom Sensor-Monitoring gezählt |
Wenn Ollama offline geht, erscheint sensor.ollama_status automatisch in der normalen Sensor-Monitoring-Benachrichtigung.
Bekanntes Problem: Runner-Crash (GPU)¶
Symptom: Ollama läuft (Container up), aber API-Requests schlagen mit HTTP 500 fehl. Logs zeigen:
Ursache: llama.cpp-Runner crasht während GPU-Inferenz auf AMD RENOIR iGPU (Vulkan). Tritt sporadisch auf, Ursache unklar (Vulkan-Bug oder Speicherproblem).
Fix:
Sensor sensor.ollama_status meldet den Ausfall automatisch — nach docker restart kehrt er in wenigen Minuten zu einem Versionswert zurück.