feat(costs): Stufe 2 — geschätzte Quellen (lokaler Strom, Cartesia, Notruf)

Lokales LLM: Call-Dauer gemessen -> Stromkosten je Job ((max-idle)*load*n/
3.6e6*Preis(EUR/kWh)*usd_per_eur), Kategorie llm_local. Cartesia-TTS: Zeichen x
cartesia_usd_per_char (tts). Notruf: pro Webhook-Alarm 0,20€*usd_per_eur
(alert), nur Doku, nie Sperre. Helfer in costs.py; neue Settings (GPU-Watt/Last/
Strompreis/usd_per_eur/cartesia/alert). Statistik: "exakt vs. geschätzt"
(Tooltip + Summenzeile, Kategorien tts/alert/llm_local). Tests: 318.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-30 13:27:50 +02:00
commit d45e2c9ae3
8 changed files with 85 additions and 5 deletions

View file

@ -24,6 +24,7 @@ from email.message import EmailMessage
import httpx
from app.config import settings
from app.core.costs import eur_to_usd
from app.metrics import metrics
logger = logging.getLogger(__name__)
@ -422,6 +423,8 @@ async def record_manual_emergency(user, store, language: str | None = None,
webhook_sent = await _post_webhook(cfg.emergency_webhook_url, payload, cfg)
if webhook_sent:
metrics.inc("emergency_notify_total", {"channel": "webhook"})
# Geschätzte Alarm-Kosten (SMS+Anruf) dokumentieren — nie blockieren.
store.add_cost_usage(user.id, "alert", eur_to_usd(cfg.emergency_alert_eur, cfg))
notified = email_sent or webhook_sent
ready = notify_readiness(user, cfg)