devkit_ui.missions
- class devkit_ui.missions.MissionStore(path: str = '/workspace/maps/missions.db')[source]
Bases:
objectOwns the mission list and its YAML persistence.
After attach(node), the node exposes:
node.missions : tuple[dict, …] read-only snapshot node.missions_version : int bumps on every change node.mission_status : str last-action status
Mission record schema:
id: ‘MISSION_1’ (allocated, immutable) name: str (operator label; defaults to id) rows: list[str] (topo entry-node names) action: str (key in ACTIONS) action_params: dict (per-action parameter overrides) repeat_every_hours: int | None (None == one-shot) active: bool created_at: str (ISO 8601 UTC) last_run_at: str | None last_run_success: bool | None
- add(*, rows: list, action: str, action_params: dict | None = None, name: str = '', repeat_every_hours: int | None = None, active: bool = True) str | None[source]
Add a mission. Returns its allocated id, or None on failure. Status carries the reason either way.
- close() None[source]
Release backend resources (the SQLite connection). A no-op for the YAML backend.
- find(mid: str) dict | None[source]
Lock-free single-mission lookup by id. Returns the dict from the current snapshot — treat as read-only.
- find_by_name(name: str) dict | None[source]
Lock-free lookup by operator name. Returns the first match. Useful for collision checks before add() (e.g. the UI_RUN record the executor creates to anchor repeat intervals).
- next_due_in_hours(mid: str) float | None[source]
For the UI chip. Returns one of:
DUE_NOW (0.0) active, never run yet DUE_FAILED (-1.0) active, last run failed — retry sentinel > 0.0 hours until the recurring interval elapses None inactive, completed one-shot, or unknown id
Import DUE_NOW / DUE_FAILED from this module rather than comparing against magic floats. UI rendering pattern:
h = store.next_due_in_hours(mid) if h is None: label = ‘done’ elif h == DUE_FAILED: label = ‘retry’ elif h == DUE_NOW: label = ‘due now’ else: label = f’in {h:.1f}h’
- record_run(mid: str, success: bool) bool[source]
Record a run outcome. Called by the executor (and any ‘Run now’ path) so the repeat interval re-arms from actual robot activity regardless of who triggered the run.
Side effect: one-shot missions (repeat_every_hours is None) that complete successfully are auto-deactivated.
Returns False for an unknown ID; otherwise returns whether the backend accepted the update.
- reset(mid: str) bool[source]
Re-arm a mission: clear run history and re-activate.
- The canonical path for:
a completed one-shot that needs to run again (e.g. crop re-planted),
a failed mission the operator wants to retry without waiting for the next scheduled executor pass.
Does not modify other mission fields. Returns False for an unknown ID; otherwise returns whether the backend accepted the update.
- set_active(mid: str, active: bool) bool[source]
Convenience wrapper around update(). The common toggle.
- devkit_ui.missions.validate_mission(name: str, rows: list, action: str, repeat_every_hours: int | None) str | None[source]
Return an error string, or None if OK.
Expects name to already be cleaned (uppercase, only [A-Z0-9_]). MissionStore.add() and .update() clean before calling; external callers should do the same or pass name=’’ to use the id default.
Modules
Mission storage and scheduling for the Sowbot webui. |
|