diff --git a/SUB Control/README.md b/SUB Control/README.md index bc9db4a..86148ee 100644 --- a/SUB Control/README.md +++ b/SUB Control/README.md @@ -4,6 +4,8 @@ A deliberately small, low-bandwidth MAVLink controller for bench-testing an ArduSub vehicle over a USB serial connection. It sends no parameter-list request and no telemetry-stream request. +![SUB Control interface](docs/sub-control-interface.png) + The desktop window uses a local HTML/CSS/JavaScript interface rendered by the Windows WebView. Python remains the only launcher and owns the MAVLink worker, arming, logging, output limiting, and parameter writes. It does not run a web diff --git a/SUB Control/docs/sub-control-interface.png b/SUB Control/docs/sub-control-interface.png new file mode 100644 index 0000000..db24d5b Binary files /dev/null and b/SUB Control/docs/sub-control-interface.png differ diff --git a/SUB Control/web/index.html b/SUB Control/web/index.html index 9b0248d..116d5ca 100644 --- a/SUB Control/web/index.html +++ b/SUB Control/web/index.html @@ -62,7 +62,7 @@
PILOT CONSOLE

Drive

- + diff --git a/SUB Control/web_ui.py b/SUB Control/web_ui.py index 2b824c0..0eaa2a9 100644 --- a/SUB Control/web_ui.py +++ b/SUB Control/web_ui.py @@ -35,7 +35,9 @@ class ControlApi: self.motor_directions: dict[int, int] = {} self.battery_path = Path(__file__).resolve().parent / "battery_settings.json" self.model_path = Path(__file__).resolve().parent / "model_settings.json" - self.window = None + # Leading underscore keeps the native WebView object out of js_api + # serialization. Only the small public methods below are exposed. + self._window = None self.maximized = False self.battery_config = { "cells": 4, "capacity_mah": 5500, "c_rating": 35, @@ -58,29 +60,29 @@ class ControlApi: return [p.device for p in list_ports.comports()] def minimize_window(self): - if self.window: - self.window.minimize() + if self._window: + self._window.minimize() return True def toggle_maximize_window(self): - if not self.window: + if not self._window: return False if self.maximized: - self.window.restore() + self._window.restore() else: - self.window.maximize() + self._window.maximize() self.maximized = not self.maximized return self.maximized def close_window(self): - if self.window: - self.window.destroy() + if self._window: + self._window.destroy() return True def choose_model(self): - if not self.window: + if not self._window: raise RuntimeError("Window is not ready") - selected = self.window.create_file_dialog( + selected = self._window.create_file_dialog( webview.OPEN_DIALOG, allow_multiple=False, file_types=("STL mesh (*.stl)", "STEP model (*.step;*.stp)"), @@ -285,7 +287,7 @@ def main(): background_color="#111719", frameless=True, easy_drag=False, shadow=True, ) - api.window = window + api._window = window window.events.maximized += lambda: setattr(api, "maximized", True) window.events.restored += lambda: setattr(api, "maximized", False) try: