diff --git a/monitor.py b/monitor.py
index 8a168c3..3aaa0e4 100644
--- a/monitor.py
+++ b/monitor.py
@@ -41,6 +41,7 @@ MAX_CHAT_ID = os.getenv("MAX_CHAT_ID", "")
MAX_API_URL = os.getenv("MAX_API_URL", "https://platform-api.max.ru")
ADDRESS_LIST_NAME = os.environ["ADDRESS_LIST_NAME"]
+OBJECT_NAME = os.getenv("OBJECT_NAME", "") # название объекта/локации
CHECK_INTERVAL = int(os.getenv("CHECK_INTERVAL", "60"))
PING_COUNT = int(os.getenv("PING_COUNT", "3"))
PING_TIMEOUT_MS = int(os.getenv("PING_TIMEOUT_MS", "1000"))
@@ -59,6 +60,13 @@ logging.basicConfig(
)
log = logging.getLogger(__name__)
+# ──────────────────────────────────────────────
+# Хелпер: префикс объекта для уведомлений
+# ──────────────────────────────────────────────
+def obj_prefix() -> str:
+ return f"🏢 {OBJECT_NAME}\n" if OBJECT_NAME else ""
+
+
# ──────────────────────────────────────────────
# Глобальное состояние
# ──────────────────────────────────────────────
@@ -222,7 +230,8 @@ def fmt_label(ip: str) -> str:
# ──────────────────────────────────────────────
def build_status_report(title: str) -> str:
now = datetime.now()
- lines = [f"{title}", f"🔧 Роутер: {router_identity}", ""]
+ prefix = f"🏢 {OBJECT_NAME}\n" if OBJECT_NAME else ""
+ lines = [f"{prefix}{title}", f"🔧 Роутер: {router_identity}", ""]
down = [ip for ip, s in hosts_state.items() if s["status"] == "down"]
up = [ip for ip, s in hosts_state.items() if s["status"] == "up"]
@@ -444,6 +453,7 @@ def main() -> None:
if mikrotik_error_notified:
mikrotik_error_notified = False
notify(
+ f"{obj_prefix()}"
f"✅ Подключение к MikroTik восстановлено\n"
f"🔧 Роутер: {router_identity} ({MIKROTIK_HOST})"
)
@@ -457,6 +467,7 @@ def main() -> None:
for ip, comment in ip_list
) or " (список пуст)"
notify(
+ f"{obj_prefix()}"
f"🟢 MikroTik Monitor запущен\n\n"
f"🔧 Роутер: {router_identity} ({MIKROTIK_HOST})\n"
f"📋 Address-list: {ADDRESS_LIST_NAME}\n\n"
@@ -502,6 +513,7 @@ def main() -> None:
dur = fmt_duration(now - ds) if ds else "?"
state.update({"status": "up", "down_since": None, "last_notify": None})
notify(
+ f"{obj_prefix()}"
f"✅ Хост восстановился\n"
f"IP: {ip}" + (f" ({comment})" if comment else "") + "\n"
f"RTT: {rtt:.1f} ms\n"
@@ -518,6 +530,7 @@ def main() -> None:
if state["status"] != "down":
state.update({"status": "down", "down_since": now, "last_notify": now})
notify(
+ f"{obj_prefix()}"
f"🔴 Хост недоступен!\n"
f"IP: {ip}" + (f" ({comment})" if comment else "") + "\n"
f"Список: {ADDRESS_LIST_NAME}\n"
@@ -530,6 +543,7 @@ def main() -> None:
dur = fmt_duration(now - ds) if ds else "?"
state["last_notify"] = now
notify(
+ f"{obj_prefix()}"
f"🔴 Хост всё ещё недоступен!\n"
f"IP: {ip}" + (f" ({comment})" if comment else "") + "\n"
f"Недоступен уже: {dur}\n"
@@ -544,6 +558,7 @@ def main() -> None:
if not mikrotik_error_notified:
mikrotik_error_notified = True
notify(
+ f"{obj_prefix()}"
f"⚠️ Ошибка подключения к MikroTik\n"
f"🔧 Роутер: {router_identity} ({MIKROTIK_HOST})\n"
f"{exc}"
diff --git a/stack.yml b/stack.yml
index 34de9c2..a90ba04 100644
--- a/stack.yml
+++ b/stack.yml
@@ -40,6 +40,9 @@ services:
- MAX_CHAT_ID=123456789 # ← ID чата в MAX
- MAX_API_URL=https://platform-api.max.ru
+ # Название объекта/локации где стоит роутер (отображается в уведомлениях)
+ - OBJECT_NAME=Офис # ← например: Склад, Квартал54, Офис
+
# Имя address-list из /ip firewall address-list на MikroTik
- ADDRESS_LIST_NAME=monitor
@@ -48,10 +51,17 @@ services:
- PING_COUNT=3 # кол-во пинг-пакетов
- PING_TIMEOUT_MS=1000 # таймаут пинга (мс)
- FAILURE_THRESHOLD=2 # провалов подряд → уведомление DOWN
+ - REPEAT_NOTIFY_MIN=30 # повтор уведомления DOWN каждые N минут (0 = отключить)
+ - DAILY_REPORT_TIME=09:00 # время ежедневного отчёта (HH:MM)
+ - WEB_PORT=8080 # порт веб-дашборда
# Временная зона
- TZ=Europe/Moscow
+ # ── Порты ──────────────────────────────────────────────────────
+ ports:
+ - "8080:8080" # веб-дашборд
+
# ── Тома ───────────────────────────────────────────────────────
volumes:
- /etc/localtime:/etc/localtime:ro