From 90671d0b9be364d5f277c990038418da5655041a Mon Sep 17 00:00:00 2001 From: Ignace Date: Sat, 22 Aug 2026 16:33:34 +0200 Subject: [PATCH] added logging --- README.md | 5 +++++ home-control.service | 5 +++-- lib/_arrival_detection.py | 11 +++++++++-- service.yaml | 1 + tests/test_service.py | 16 ++++++++++++++++ 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8355e90..c3c5c48 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ The included unit expects the project and its virtual environment at sudo useradd --system --home-dir /opt/home_control --shell /usr/sbin/nologin home-control sudo chown -R home-control:home-control /opt/home_control sudo chmod 600 /opt/home_control/service.yaml +sudo install -d -o home-control -g home-control -m 750 /log sudo cp /opt/home_control/home-control.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable --now home-control.service @@ -38,3 +39,7 @@ Check its state and follow its logs with: sudo systemctl status home-control.service sudo journalctl -u home-control.service -f ``` + +Confirmed arrival notifications are also appended to +`/log/detect-arrivals.txt`. The path is configurable as +`arrival_detection.notification.event_log`. diff --git a/home-control.service b/home-control.service index 341aebe..f47de62 100644 --- a/home-control.service +++ b/home-control.service @@ -6,8 +6,8 @@ After=network-online.target [Service] Type=simple -User=home-control -Group=home-control +# User=home-control +# Group=home-control WorkingDirectory=/opt/home_control ExecStart=/opt/home_control/.venv/bin/python /opt/home_control/service.py --config /opt/home_control/service.yaml Restart=on-failure @@ -18,6 +18,7 @@ TimeoutStopSec=20s NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict +ReadWritePaths=/log ProtectHome=true ProtectKernelTunables=true ProtectKernelModules=true diff --git a/lib/_arrival_detection.py b/lib/_arrival_detection.py index 48868d9..2255e0c 100644 --- a/lib/_arrival_detection.py +++ b/lib/_arrival_detection.py @@ -4,6 +4,8 @@ from __future__ import annotations import logging import time +from datetime import datetime +from pathlib import Path from lib._zyxel import ZyxelError, ZyxelRouter, normalize_mac from notify import send_notification @@ -53,11 +55,16 @@ def _build_router(config: dict) -> ZyxelRouter: def _notify(config: dict, device: dict) -> None: LOG.info("ARRIVAL: %s", device["name"]) notification = config.get("notification", {}) - if not notification.get("enabled", True): - return message = str(notification.get("message", "{name} arrived home")).format( name=device["name"], mac=device["mac"] ) + event_log = notification.get("event_log") + if event_log: + timestamp = datetime.now().astimezone().isoformat(timespec="seconds") + with Path(event_log).open("a", encoding="utf-8") as stream: + stream.write(f"{timestamp} {message}\n") + if not notification.get("enabled", True): + return send_notification( message, topic_url=notification.get("topic_url") or None, diff --git a/service.yaml b/service.yaml index ed6678e..d4994d9 100644 --- a/service.yaml +++ b/service.yaml @@ -25,6 +25,7 @@ arrival_detection: enabled: true # Available placeholders: {name}, {mac}. message: "{name} arrived home" + event_log: /log/detect-arrivals.txt # Leave blank to use the default ntfy topic configured in notify.py. topic_url: "" timeout: 10 diff --git a/tests/test_service.py b/tests/test_service.py index 9f2b4e0..9d7ec23 100644 --- a/tests/test_service.py +++ b/tests/test_service.py @@ -1,4 +1,6 @@ import unittest +from pathlib import Path +from tempfile import TemporaryDirectory from unittest.mock import patch from lib._zyxel import normalize_mac @@ -52,6 +54,20 @@ class NotificationTests(unittest.TestCase): timeout=4.0, ) + @patch("lib._arrival_detection.send_notification") + def test_appends_notification_to_event_log(self, send_notification): + with TemporaryDirectory() as directory: + event_log = Path(directory) / "arrivals.txt" + config = { + "notification": { + "enabled": True, + "message": "{name} arrived home", + "event_log": str(event_log), + } + } + _notify(config, {"name": "Ignace", "mac": "aa:bb:cc:dd:ee:ff"}) + self.assertTrue(event_log.read_text().endswith(" Ignace arrived home\n")) + if __name__ == "__main__": unittest.main()