chore(fleet): sync operator memory, hatch menu dialogs, and watchdog alerts

This commit is contained in:
operator
2026-10-07 00:25:51 +00:00
parent 0065d11e97
commit 34b0ef9fe2
38 changed files with 2205 additions and 444 deletions
+28 -13
View File
@@ -168,14 +168,32 @@ def _eval(ws, js, timeout=8.0):
return None
VERIFY_TRIES = 10
VERIFY_PAUSE = 1.5
def _poll(check, tries=VERIFY_TRIES, pause=VERIFY_PAUSE):
"""Poll a state check until true. Fast exit; tolerates slow commits."""
for _ in range(tries):
try:
if check():
return True
except Exception:
pass
time.sleep(pause)
return False
def list_radios(ws):
"""All dialog radios with heading/label/value/checked (or [])."""
return _eval(ws, JS_LIST_RADIOS) or []
rows = _eval(ws, JS_LIST_RADIOS)
return rows if isinstance(rows, list) else []
def list_switches(ws):
"""All dialog switches with row label + checked (or [])."""
return _eval(ws, JS_LIST_SWITCHES) or []
rows = _eval(ws, JS_LIST_SWITCHES)
return rows if isinstance(rows, list) else []
def radio_state(ws, heading, value):
@@ -188,9 +206,9 @@ def radio_state(ws, heading, value):
def set_radio_by_heading(ws, heading, value):
"""Set a heading-grouped radio; verify, else trusted click, verify."""
"""Set a heading-grouped radio; poll, else trusted click, poll."""
if _eval(ws, JS_CLICK_RADIO % (heading, value)) == "CLICKED" \
and radio_state(ws, heading, value) is True:
and _poll(lambda: radio_state(ws, heading, value) is True):
return True
rect = _eval(ws, JS_RADIO_RECT % (heading, value))
if not rect or "x" not in rect:
@@ -199,8 +217,7 @@ def set_radio_by_heading(ws, heading, value):
real_click(ws, rect["x"], rect["y"])
except Exception:
return False
time.sleep(0.6)
return radio_state(ws, heading, value) is True
return _poll(lambda: radio_state(ws, heading, value) is True)
def radio_aria_state(ws, name):
@@ -214,9 +231,9 @@ def radio_aria_state(ws, name):
def set_radio_by_aria(ws, name):
"""Set an aria-labeled radio; verify, else trusted click, verify."""
"""Set an aria-labeled radio; poll, else trusted click, poll."""
if _eval(ws, JS_CLICK_RADIO_ARIA % name) == "CLICKED" \
and radio_aria_state(ws, name) is True:
and _poll(lambda: radio_aria_state(ws, name) is True):
return True
rect = _eval(ws, JS_RADIO_ARIA_RECT % name)
if not rect or "x" not in rect:
@@ -225,8 +242,7 @@ def set_radio_by_aria(ws, name):
real_click(ws, rect["x"], rect["y"])
except Exception:
return False
time.sleep(0.6)
return radio_aria_state(ws, name) is True
return _poll(lambda: radio_aria_state(ws, name) is True)
def switch_state(ws, label):
@@ -247,7 +263,7 @@ def set_switch(ws, label, on):
if state == bool(on):
return True
if _eval(ws, JS_CLICK_SWITCH % label) == "CLICKED" \
and switch_state(ws, label) is bool(on):
and _poll(lambda: switch_state(ws, label) is bool(on)):
return True
rect = _eval(ws, JS_SWITCH_RECT % label)
if not rect or "x" not in rect:
@@ -256,5 +272,4 @@ def set_switch(ws, label, on):
real_click(ws, rect["x"], rect["y"])
except Exception:
return False
time.sleep(0.6)
return switch_state(ws, label) is bool(on)
return _poll(lambda: switch_state(ws, label) is bool(on))