OTE informatin discord
Some checks failed
CI and deploy / migration-check (push) Failing after 25s
CI and deploy / deploy (push) Has been skipped

This commit is contained in:
Dusan Vojacek
2026-04-29 14:17:24 +02:00
parent 2eeab58c8e
commit 6074535d96
5 changed files with 348 additions and 1 deletions

View File

@@ -16,6 +16,7 @@ logger = logging.getLogger(__name__)
_WEBHOOK_CACHE: dict[tuple[int, str], str] = {}
_OTE_IMPORT_ALERT_CACHE: dict[tuple[str, str], float] = {}
_OTE_IMPORT_OK_CACHE: dict[str, float] = {}
async def _get_site_webhook_url(
@@ -255,6 +256,65 @@ async def notify_ote_import_format_changed(
await send_discord(conn, site_id=None, message=msg, level="critical")
def _should_send_ote_ok(report_date: str, *, cooldown_s: float) -> bool:
now = datetime.now(timezone.utc).timestamp()
key = str(report_date)
last = _OTE_IMPORT_OK_CACHE.get(key)
if last is not None and (now - last) < cooldown_s:
return False
_OTE_IMPORT_OK_CACHE[key] = now
return True
async def notify_ote_import_ok_brief(
conn: asyncpg.Connection | None,
*,
report_date: str,
brief: dict,
url: str,
) -> None:
"""
Info notifikace po úspěšném importu kompletního dne OTE (stručná analýza "co čekat zítra").
Dedup: 1× za cooldown na report_date.
"""
if not _should_send_ote_ok(report_date, cooldown_s=20 * 3600):
return
def _f(x, default: float = 0.0) -> float:
try:
if x is None:
return default
return float(x)
except Exception:
return default
min_p = _f(brief.get("min_price"))
max_p = _f(brief.get("max_price"))
raw_signals = brief.get("signals") or []
signals: list[str] = []
if isinstance(raw_signals, list):
for s in raw_signals[:6]:
if not isinstance(s, dict):
continue
title = str(s.get("title") or s.get("code") or "").strip()
detail = str(s.get("detail") or "").strip()
if title and detail:
signals.append(f"{title} ({detail})")
elif title:
signals.append(title)
if not signals:
signals.append("běžný den (bez extrémů)")
msg = (
f"OTE ceny staženy `{report_date}`\n"
f"URL: `{url}`\n"
f"Min: **{min_p:.3f}** | Max: **{max_p:.3f}** Kč/kWh\n"
f"Signály: " + "; ".join(f"**{s}**" for s in signals)
)
await send_discord(conn, site_id=None, message=msg, level="info")
async def notify_modbus_mismatch(
conn: asyncpg.Connection | None,
site_id: int | None,