Files
site/WESP_REL/app/services/feed_quality/notify.py
T
2026-07-17 12:57:18 +03:00

86 lines
3.0 KiB
Python

"""Уведомления в центр зоотехника по алертам feed_quality."""
from __future__ import annotations
import logging
from typing import Iterable
from app.models.feed_alert import FeedAlert
from app.services.feed_quality.rules import (
EVENT_LEFT_IN_MIXER,
EVENT_LOADING_FAST,
EVENT_LOADING_TIME,
EVENT_MIX_TIME,
EVENT_OVERLOAD,
EVENT_UNDERLOAD,
SEVERITY_ERROR,
SEVERITY_WARNING,
settings_section_for_alert,
)
from app.services.feed_quality.settings_store import get_feed_quality_settings
from app.services.notification_center_service import create_notification, format_detail_timestamp
logger = logging.getLogger(__name__)
_EVENT_TITLES = {
EVENT_OVERLOAD: "Перегруз при загрузке",
EVENT_UNDERLOAD: "Недогруз при загрузке",
EVENT_LOADING_TIME: "Долгая загрузка компонента",
EVENT_LOADING_FAST: "Быстрая загрузка компонента",
EVENT_MIX_TIME: "Отклонение смешивания",
EVENT_LEFT_IN_MIXER: "Остаток в миксере",
}
def _alert_title(alert: FeedAlert) -> str:
if alert.group_name and alert.event_type in (EVENT_OVERLOAD, EVENT_UNDERLOAD):
return "Отклонение при выгрузке"
return _EVENT_TITLES.get(alert.event_type, "Отклонение кормления")
def _alert_detail(alert: FeedAlert) -> str:
when = format_detail_timestamp(alert.created_at)
recipe = alert.recipe_name or "рейс"
return f"Рейс «{recipe}»: {alert.detail}{when}"
def _should_notify(alert: FeedAlert) -> bool:
if alert.severity not in (SEVERITY_WARNING, SEVERITY_ERROR):
return False
section_key = settings_section_for_alert(
alert.event_type,
component_name=alert.component_name,
group_name=alert.group_name,
)
cfg = get_feed_quality_settings().get(section_key) or {}
if alert.severity == SEVERITY_ERROR:
return bool(cfg.get("notify_critical", True))
return bool(cfg.get("notify_warning", True))
def notify_feed_quality_alerts(alerts: Iterable[FeedAlert]) -> int:
"""Создаёт записи в «К» по флагам notify_* в настройках."""
count = 0
for alert in alerts:
if not _should_notify(alert):
continue
kind = "error" if alert.severity == SEVERITY_ERROR else "warning"
try:
create_notification(
title=_alert_title(alert),
detail=_alert_detail(alert),
kind=kind,
category="feed_quality",
page="reports",
link_kind="report_loading",
link_id=alert.loading_report_id,
)
count += 1
except Exception:
logger.exception(
"[FEED-QUALITY-NOTIFY] alert=%s report=%s",
alert.id,
alert.loading_report_id,
)
return count