Reduce status polling load and add 1Hz ready LED blink
This commit is contained in:
29
src/main.py
29
src/main.py
@@ -1,4 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import signal
|
import signal
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
@@ -14,6 +15,33 @@ from webapp import WebPortal
|
|||||||
LOG = logging.getLogger("serial-bridge")
|
LOG = logging.getLogger("serial-bridge")
|
||||||
|
|
||||||
|
|
||||||
|
def _configure_ready_led_blink() -> None:
|
||||||
|
led_bases = [
|
||||||
|
"/sys/class/leds/PWR",
|
||||||
|
"/sys/class/leds/led1",
|
||||||
|
"/sys/class/leds/ACT",
|
||||||
|
"/sys/class/leds/led0",
|
||||||
|
]
|
||||||
|
for base in led_bases:
|
||||||
|
trigger_path = os.path.join(base, "trigger")
|
||||||
|
delay_on_path = os.path.join(base, "delay_on")
|
||||||
|
delay_off_path = os.path.join(base, "delay_off")
|
||||||
|
if not (os.path.exists(trigger_path) and os.path.exists(delay_on_path) and os.path.exists(delay_off_path)):
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
with open(trigger_path, "w", encoding="utf-8") as f:
|
||||||
|
f.write("timer\n")
|
||||||
|
with open(delay_on_path, "w", encoding="utf-8") as f:
|
||||||
|
f.write("500\n")
|
||||||
|
with open(delay_off_path, "w", encoding="utf-8") as f:
|
||||||
|
f.write("500\n")
|
||||||
|
LOG.info("Ready LED blink enabled on %s (1 Hz)", base)
|
||||||
|
return
|
||||||
|
except Exception as exc:
|
||||||
|
LOG.warning("Failed to configure LED blink on %s: %s", base, exc)
|
||||||
|
LOG.warning("No controllable LED found for ready blink")
|
||||||
|
|
||||||
|
|
||||||
class Supervisor(threading.Thread):
|
class Supervisor(threading.Thread):
|
||||||
def __init__(self, state: AppState, nm: NetworkManager, rtc: RTCAndNTPManager) -> None:
|
def __init__(self, state: AppState, nm: NetworkManager, rtc: RTCAndNTPManager) -> None:
|
||||||
super().__init__(daemon=True)
|
super().__init__(daemon=True)
|
||||||
@@ -133,6 +161,7 @@ def main() -> None:
|
|||||||
name="web-portal",
|
name="web-portal",
|
||||||
)
|
)
|
||||||
web_thread.start()
|
web_thread.start()
|
||||||
|
_configure_ready_led_blink()
|
||||||
|
|
||||||
while not stop_event.wait(1):
|
while not stop_event.wait(1):
|
||||||
if not web_thread.is_alive():
|
if not web_thread.is_alive():
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import json
|
|||||||
import queue
|
import queue
|
||||||
import subprocess
|
import subprocess
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
from flask import Flask, Response, jsonify, render_template, request, stream_with_context
|
from flask import Flask, Response, jsonify, render_template, request, stream_with_context
|
||||||
@@ -24,6 +25,9 @@ class WebPortal:
|
|||||||
self.state = state
|
self.state = state
|
||||||
self.network_manager = network_manager
|
self.network_manager = network_manager
|
||||||
self.broadcaster = broadcaster
|
self.broadcaster = broadcaster
|
||||||
|
self._status_refresh_interval_s = 15.0
|
||||||
|
self._last_status_refresh_mono = 0.0
|
||||||
|
self._status_lock = threading.Lock()
|
||||||
self.app = Flask(__name__, template_folder=template_folder, static_folder=static_folder)
|
self.app = Flask(__name__, template_folder=template_folder, static_folder=static_folder)
|
||||||
self._register_routes()
|
self._register_routes()
|
||||||
|
|
||||||
@@ -39,7 +43,11 @@ class WebPortal:
|
|||||||
@self.app.route("/api/status", methods=["GET"])
|
@self.app.route("/api/status", methods=["GET"])
|
||||||
def status() -> Response:
|
def status() -> Response:
|
||||||
try:
|
try:
|
||||||
|
now = time.monotonic()
|
||||||
|
with self._status_lock:
|
||||||
|
if now - self._last_status_refresh_mono >= self._status_refresh_interval_s:
|
||||||
self.network_manager.refresh_state()
|
self.network_manager.refresh_state()
|
||||||
|
self._last_status_refresh_mono = now
|
||||||
return jsonify(self.state.snapshot())
|
return jsonify(self.state.snapshot())
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
self.state.update_status("Status update failed", str(exc))
|
self.state.update_status("Status update failed", str(exc))
|
||||||
|
|||||||
@@ -146,7 +146,7 @@
|
|||||||
document.getElementById('shutdownBtn').addEventListener('click', () => triggerSystemAction('shutdown'));
|
document.getElementById('shutdownBtn').addEventListener('click', () => triggerSystemAction('shutdown'));
|
||||||
|
|
||||||
refreshStatus();
|
refreshStatus();
|
||||||
setInterval(refreshStatus, 5000);
|
setInterval(refreshStatus, 15000);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user