phase2a: Kern fuer zwei Instanzen (Rolle, Partner, Telegram-Zweitweg)

- kern/einstellungen.py: MC_ROLLE (box|homelab), Instanzname, Datenordner, Partner-URL
- kern/zeit.py: eine Zeitzone statt sechs Kopien
- app.py/steward.py: Box-Router und Warm-Set nur in der Rolle box; der Homelab-Teil
  laedt nichts von der Box
- /api/health nennt Rolle und Instanz; Engine/Gateway/Hirn nur auf der Box
- /api/partner (Lebenszeichen) und /api/partner/<pfad> (Durchreiche, ohne Schleifen und SSE)
- Waechter prueft die andere Instanz (rot erst nach 5 Takten, ein Neustart ist kein Alarm)
- notify.sh: Zweitweg direkt an die Telegram-Bot-API, wenn hermes send scheitert oder fehlt;
  Token nicht in der Prozessliste, Tests greifen nie auf die echte .env
- update_verlauf erkennt "OK telegram direkt"

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-09-24 15:41:08 +02:00
co-authored by Claude Opus 5.5
parent 99ba6a78ab
commit 75611be9a9
19 changed files with 637 additions and 98 deletions
+44 -4
View File
@@ -1,7 +1,9 @@
#!/usr/bin/env bash
# Meldeweg der Box (Autonomie E1): eine Nachricht an den User schicken.
# Primär: hermes send → Telegram (nutzt Gateway-Credentials, kein LLM nötig).
# Fallback: Logfile + wall (falls Telegram/hermes nicht erreichbar).
# Zweitweg (seit 24.09.2026): direkt an die Telegram-Bot-API mit den Zugangsdaten aus Hermes' .env —
# greift, wenn Hermes steht oder fehlt (die Homelab-Instanz hat gar kein Hermes).
# Letzter Ausweg: Logfile + wall.
#
# Nutzung: notify.sh "Nachricht" (oder via stdin: echo msg | notify.sh)
# notify.sh -s "[Update]" "Text" (Betreffzeile voranstellen)
@@ -15,12 +17,16 @@
#
# Exit 0 = zugestellt (Telegram, Fallback-Log oder Nacht-Warteschlange).
# MC_NOTIFY_STRICT=1: Exit 1, wenn Telegram scheitert (für morgenmeldung.sh, damit nichts verloren geht).
# Test-Schalter: MC_NOTIFY_STUNDE (Stunde vortäuschen), MC_NIGHT_QUEUE, MC_NOTIFY_HERMES (hermes-Befehl).
# Test-Schalter: MC_NOTIFY_STUNDE (Stunde vortäuschen), MC_NIGHT_QUEUE, MC_NOTIFY_HERMES (hermes-Befehl),
# MC_TELEGRAM_ENV (Datei mit TELEGRAM_BOT_TOKEN/TELEGRAM_HOME_CHANNEL), MC_TELEGRAM_API (Bot-API-Adresse),
# MC_NOTIFY_OHNE_WALL=1 (kein wall im letzten Ausweg).
set -uo pipefail
LOG="${MC_NOTIFY_LOG:-$HOME/mc2-notify.log}"
NIGHT_QUEUE="${MC_NIGHT_QUEUE:-$HOME/.hermes/night-queue.txt}"
HERMES_BIN="${MC_NOTIFY_HERMES:-hermes}"
TG_ENV="${MC_TELEGRAM_ENV:-$HOME/.hermes/.env}"
TG_API="${MC_TELEGRAM_API:-https://api.telegram.org}"
SUBJECT=""
DRINGEND=0
@@ -85,9 +91,43 @@ if [ $? -eq 0 ]; then
exit 0
fi
# Fallback: Logfile + wall — Meldung darf nie verloren gehen.
# Zweitweg: direkt an die Bot-API. Das Token geht über --config auf stdin an curl, damit es nicht
# in der Prozessliste steht.
env_wert() {
local wert
wert="$(grep -E "^(export +)?$1=" "$TG_ENV" 2>/dev/null | tail -n 1)"
wert="${wert#*=}"
wert="${wert%$'\r'}"
wert="${wert%\"}"; wert="${wert#\"}"
wert="${wert%\'}"; wert="${wert#\'}"
printf '%s' "$wert"
}
telegram_direkt() {
local token chat thread text
[ -r "$TG_ENV" ] || return 1
token="$(env_wert TELEGRAM_BOT_TOKEN)"
chat="$(env_wert TELEGRAM_HOME_CHANNEL)"
thread="$(env_wert TELEGRAM_HOME_CHANNEL_THREAD_ID)"
[ -n "$token" ] && [ -n "$chat" ] || return 1
text="$MSG"
[ -n "$SUBJECT" ] && text="$SUBJECT
$MSG"
printf 'url = "%s/bot%s/sendMessage"\n' "$TG_API" "$token" \
| curl -sf -m 15 -o /dev/null --config - \
--data-urlencode "chat_id=$chat" --data-urlencode "text=$text" \
${thread:+--data-urlencode "message_thread_id=$thread"}
}
if telegram_direkt; then
# „OK telegram direkt“: services/update_verlauf.py erkennt beide Wege.
echo "$TS OK telegram direkt: $MSG" >> "$LOG"
exit 0
fi
# Letzter Ausweg: Logfile + wall — Meldung darf nie verloren gehen.
echo "$TS FALLBACK (telegram fehlgeschlagen: $SEND_OUT): $MSG" >> "$LOG"
printf '%s\n' "MC2-Meldung: ${SUBJECT:+$SUBJECT }$MSG" | wall 2>/dev/null || true
if [ "${MC_NOTIFY_OHNE_WALL:-0}" != "1" ]; then
printf '%s\n' "MC2-Meldung: ${SUBJECT:+$SUBJECT }$MSG" | wall 2>/dev/null || true
fi
echo "WARN: Telegram fehlgeschlagen, in $LOG protokolliert" >&2
[ "${MC_NOTIFY_STRICT:-0}" = "1" ] && exit 1
exit 0