From 2faa1799577f059994194c7e5dcdc63ba68dbaf1 Mon Sep 17 00:00:00 2001 From: Codex Date: Wed, 8 Jul 2026 13:28:05 +0200 Subject: [PATCH] pi_wake_agent.py: Add run_once and run_wake with non-blocking h5i bus --- pi_wake_agent.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/pi_wake_agent.py b/pi_wake_agent.py index dd1bfa92..5acedc3c 100644 --- a/pi_wake_agent.py +++ b/pi_wake_agent.py @@ -204,6 +204,49 @@ def zellij_write_enter(session: str) -> bool: pid_file.write_text(str(os.getpid())) +def run_wake(sessions: List[str], message: str, logger: logging.Logger) -> None: + sessions_str = ",".join(sessions) + logger.info(f"Waking {sessions_str} with message: {message}") + + for session in sessions: + zellij_write_chars(session, f"[{AGENT_NICK} via zellij] {message} Run: h5i-bus msg inbox") + for _ in range(5): + zellij_write_enter(session) + time.sleep(1) + + # Fire-and-forget h5i bus message (non-blocking) + def _send_bus(): + try: + subprocess.run( + ["h5i", "msg", "send", "Fable", f"{message} (timer wakeup)"], + cwd=H5I_BUS_ROOT, + env={**os.environ, "H5I_AGENT": H5I_AGENT}, + capture_output=True, + timeout=5 + ) + except Exception: + pass # Silently ignore - fire and forget + + threading.Thread(target=_send_bus, daemon=True).start() + + logger.info(f"Wake sent to {sessions_str}") + +def run_once(sessions: List[str], interval: str, message: str, logger: logging.Logger) -> None: + interval_seconds = parse_interval(interval) + logger.info(f"One-shot timer set for {interval} ({interval_to_human(interval)})") + + def _wake(): + time.sleep(interval_seconds) + run_wake(sessions, message, logger) + + thread = threading.Thread(target=_wake, daemon=True) + thread.start() + logger.info(f"Background timer started (thread: {thread.ident})") + pid_file = Path(f"/tmp/pi_wake_agent_{sessions[0]}.pid") + pid_file.write_text(str(os.getpid())) + return 0 + + def run_daemon(sessions: List[str], interval: str, message: str, logger: logging.Logger) -> None: interval_seconds = parse_interval(interval) logger.info("=== DAEMON START ===")