Make checking parallel (faster).
This commit is contained in:
69
devices.py
69
devices.py
@ -3,6 +3,7 @@
|
||||
import json
|
||||
import subprocess
|
||||
import threading
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
@ -274,17 +275,28 @@ def _budget_tick():
|
||||
if not is_curfew_allowed():
|
||||
return
|
||||
|
||||
# Check all devices in parallel
|
||||
online_status = {}
|
||||
with ThreadPoolExecutor(max_workers=3) as executor:
|
||||
futures = {
|
||||
executor.submit(dev_info["check"]): dev_id
|
||||
for dev_id, dev_info in DEVICES.items()
|
||||
}
|
||||
for future in as_completed(futures):
|
||||
dev_id = futures[future]
|
||||
result = future.result()
|
||||
if isinstance(result, dict):
|
||||
online_status[dev_id] = result.get("online", False)
|
||||
else:
|
||||
online_status[dev_id] = bool(result)
|
||||
|
||||
# Process results sequentially (budget operations need to be thread-safe)
|
||||
with _timer_lock:
|
||||
for dev_id, dev_info in DEVICES.items():
|
||||
for dev_id, online in online_status.items():
|
||||
dev_info = DEVICES[dev_id]
|
||||
state = _load_state()
|
||||
current_budget = state.get(dev_id, {}).get("budget", BUDGET_S)
|
||||
|
||||
is_online = dev_info["check"]()
|
||||
if isinstance(is_online, dict):
|
||||
online = is_online.get("online", False)
|
||||
else:
|
||||
online = bool(is_online)
|
||||
|
||||
# Expired budget + device back online → shut it down
|
||||
if current_budget <= 0 and online:
|
||||
dev_info["turnoff"]()
|
||||
@ -342,14 +354,8 @@ def shutdown_all() -> list[dict]:
|
||||
return actions
|
||||
|
||||
|
||||
def status_all() -> list[dict]:
|
||||
"""Get current status + budget for all devices. Returns ordered list."""
|
||||
curfew = curfew_status()
|
||||
actions = []
|
||||
for dev_id, dev_info in DEVICES.items():
|
||||
state = _load_state()
|
||||
budget_seconds = state.get(dev_id, {}).get("budget", BUDGET_S)
|
||||
|
||||
def _check_device(dev_id: str, dev_info: dict) -> dict:
|
||||
"""Check a single device and return its status dict."""
|
||||
is_online = dev_info["check"]()
|
||||
if isinstance(is_online, dict):
|
||||
online = is_online.get("online", False)
|
||||
@ -358,6 +364,8 @@ def status_all() -> list[dict]:
|
||||
online = bool(is_online)
|
||||
detail = "Online" if online else "Offline"
|
||||
|
||||
state = _load_state()
|
||||
budget_seconds = state.get(dev_id, {}).get("budget", BUDGET_S)
|
||||
budget_minutes = _budget_to_minutes(budget_seconds)
|
||||
|
||||
# Budget warning
|
||||
@ -368,9 +376,36 @@ def status_all() -> list[dict]:
|
||||
else:
|
||||
icon = dev_info["icon"]
|
||||
|
||||
actions.append({
|
||||
return {
|
||||
"icon": icon,
|
||||
"title": dev_info["name"],
|
||||
"detail": f"{detail} · {budget_minutes} min left",
|
||||
})
|
||||
"online": online,
|
||||
}
|
||||
|
||||
|
||||
def status_all() -> list[dict]:
|
||||
"""Get current status + budget for all devices. Returns ordered list."""
|
||||
curfew = curfew_status()
|
||||
|
||||
# Check all devices in parallel
|
||||
results = {}
|
||||
with ThreadPoolExecutor(max_workers=3) as executor:
|
||||
futures = {
|
||||
executor.submit(_check_device, dev_id, dev_info): dev_id
|
||||
for dev_id, dev_info in DEVICES.items()
|
||||
}
|
||||
for future in as_completed(futures):
|
||||
dev_id = futures[future]
|
||||
results[dev_id] = future.result()
|
||||
|
||||
# Return in ordered list (DEVICES preserves insertion order)
|
||||
actions = [
|
||||
{
|
||||
"icon": results[dev_id]["icon"],
|
||||
"title": results[dev_id]["title"],
|
||||
"detail": results[dev_id]["detail"],
|
||||
}
|
||||
for dev_id in DEVICES
|
||||
]
|
||||
return actions, curfew
|
||||
|
||||
Reference in New Issue
Block a user