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:
@@ -70,21 +70,35 @@ class GenericESP32Driver(BoardDriver):
|
||||
return bool(data["state"]) if data is not None else None
|
||||
|
||||
def poll(self, board: "Board") -> dict:
|
||||
relay_states, input_states, online = {}, {}, False
|
||||
_offline = {"relay_states": {}, "input_states": {}, "is_online": False}
|
||||
relay_states, input_states = {}, {}
|
||||
|
||||
for n in range(1, board.num_relays + 1):
|
||||
# Fail-fast probe — bail immediately if board is unreachable
|
||||
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
|
||||
|
||||
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", False))
|
||||
online = True
|
||||
|
||||
return {"relay_states": relay_states, "input_states": input_states, "is_online": online}
|
||||
return {"relay_states": relay_states, "input_states": input_states, "is_online": True}
|
||||
|
||||
def register_webhook(self, board: "Board", callback_url: str) -> bool:
|
||||
return _post(f"{board.base_url}/register?callback_url={callback_url}") is not None
|
||||
|
||||
@@ -60,21 +60,35 @@ class GenericESP8266Driver(BoardDriver):
|
||||
return bool(data["state"]) if data is not None else None
|
||||
|
||||
def poll(self, board: "Board") -> dict:
|
||||
relay_states, input_states, online = {}, {}, False
|
||||
_offline = {"relay_states": {}, "input_states": {}, "is_online": False}
|
||||
relay_states, input_states = {}, {}
|
||||
|
||||
for n in range(1, board.num_relays + 1):
|
||||
# Fail-fast probe — bail immediately if board is unreachable
|
||||
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
|
||||
|
||||
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", False))
|
||||
online = True
|
||||
|
||||
return {"relay_states": relay_states, "input_states": input_states, "is_online": online}
|
||||
return {"relay_states": relay_states, "input_states": input_states, "is_online": True}
|
||||
|
||||
def register_webhook(self, board: "Board", callback_url: str) -> bool:
|
||||
return _post(f"{board.base_url}/register?callback_url={callback_url}") is not None
|
||||
|
||||
@@ -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 ──────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user