feat: parallelize device shutdown with common _shutdown_devices function

- Curfew and budget exhaustion now use shared _shutdown_devices()
- All device turnoffs run in parallel via ThreadPoolExecutor
- Faster shutdown when multiple devices need to be turned off
This commit is contained in:
2026-06-17 22:23:18 +02:00
parent 2e47aa84f9
commit 4401b88726
2 changed files with 21 additions and 8 deletions

View File

@ -6,7 +6,7 @@
BUDGET_S = 3600 # default 60 min per device (in seconds)
TICK_INTERVAL = 10 # seconds between budget check cycles
ALLOWED_WEEKDAY = "7:00-23:30" # Mon-Fri allowed hours
ALLOWED_WEEKDAY = "7:00-20:30" # Mon-Fri allowed hours
ALLOWED_WEEKEND = "7:00-20:30" # Sat-Sun allowed hours
# ═══════════════════════════════════════════════════════════════════════

View File

@ -258,7 +258,15 @@ def curfew_status() -> dict:
}
# ── Budget timer (runs every 60s in background) ──────────────────────
def _shutdown_devices(device_ids: list[str]):
"""Shut down a list of devices in parallel."""
if not device_ids:
return
with ThreadPoolExecutor(max_workers=len(device_ids)) as executor:
list(executor.submit(DEVICES[dev_id]["turnoff"]) for dev_id in device_ids)
# ── Budget timer (runs every 10s in background) ──────────────────────
_timer_running = False
_timer_lock = threading.Lock()
@ -292,13 +300,14 @@ def _budget_tick():
# Process results sequentially (budget operations need to be thread-safe)
with _timer_lock:
if not is_curfew_allowed():
# Curfew in effect — turn off all online devices
for dev_id, online in online_status.items():
if online:
DEVICES[dev_id]["turnoff"]()
# Curfew in effect — turn off all online devices in parallel
online_devices = [dev_id for dev_id, online in online_status.items() if online]
_shutdown_devices(online_devices)
return
current_time = time.time() # float timestamp for precise elapsed calculation
devices_to_shutdown = []
for dev_id, online in online_status.items():
dev_info = DEVICES[dev_id]
state = _load_state()
@ -307,7 +316,7 @@ def _budget_tick():
# Expired budget + device back online → shut it down
if current_budget <= 0 and online:
dev_info["turnoff"]()
devices_to_shutdown.append(dev_id)
_set_budget(dev_id, 0.0)
continue
@ -320,11 +329,15 @@ def _budget_tick():
_set_budget(dev_id, new_budget)
if new_budget <= 0:
dev_info["turnoff"]()
devices_to_shutdown.append(dev_id)
else:
# Always update last_check even when offline
_set_budget(dev_id, current_budget)
# Shutdown all devices that hit zero budget in parallel
if devices_to_shutdown:
_shutdown_devices(devices_to_shutdown)
def start_timer():
"""Start the background budget timer (runs every 10s)."""