Fix offline board flooding: fail-fast probe in hardware driver poll()

All three hardware drivers (Olimex, generic_esp32, generic_esp8266) now
probe with the first request and bail immediately on failure.

Before: offline board with 4 relays + 3 inputs = 7 requests × 3 s timeout
        = up to 21 s of blocking + 7 log lines per recheck cycle.
After:  exactly 1 request × 3 s timeout regardless of I/O count.
This commit is contained in:
ske087
2026-02-27 16:20:10 +02:00
parent 1e89323035
commit b4db41a400
3 changed files with 64 additions and 18 deletions

View File

@@ -83,26 +83,44 @@ class OlimexESP32C6EVBDriver(BoardDriver):
# ── poll ──────────────────────────────────────────────────────────────────
def poll(self, board: "Board") -> dict:
_offline = {"relay_states": {}, "input_states": {}, "is_online": False}
# ── Connectivity probe ─────────────────────────────────────────────
# Try the very first endpoint. If the board doesn't reply we know
# it's offline and skip all remaining requests (saving N × 3 s worth
# of connect timeouts on every recheck cycle).
relay_states: dict = {}
input_states: dict = {}
online = False
for n in range(1, board.num_relays + 1):
if board.num_relays > 0:
probe = _get(f"{board.base_url}/relay/status?relay=1")
if probe is None:
return _offline
relay_states["relay_1"] = bool(probe.get("state", False))
elif board.num_inputs > 0:
probe = _get(f"{board.base_url}/input/status?input=1")
if probe is None:
return _offline
input_states["input_1"] = bool(probe.get("state", False))
else:
return _offline
# Board is reachable — collect remaining endpoints
for n in range(2, board.num_relays + 1):
data = _get(f"{board.base_url}/relay/status?relay={n}")
if data is not None:
relay_states[f"relay_{n}"] = bool(data.get("state", False))
online = True
for n in range(1, board.num_inputs + 1):
input_start = 2 if (board.num_relays == 0 and board.num_inputs > 0) else 1
for n in range(input_start, board.num_inputs + 1):
data = _get(f"{board.base_url}/input/status?input={n}")
if data is not None:
input_states[f"input_{n}"] = bool(data.get("state", True))
online = True
return {
"relay_states": relay_states,
"input_states": input_states,
"is_online": online,
"is_online": True,
}
# ── webhook registration ──────────────────────────────────────────────────