From 6f49c1cfc9ab91f02a52c766e5831d34baa6f608 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Mon, 31 Aug 2026 14:10:18 -0500 Subject: [PATCH] hi --- scripts/MODEL_RELEASE.md | 2 +- scripts/model_release.py | 2 +- .../common/starpilot_download_utilities.py | 2 +- starpilot/system/bluetooth/daemon.py | 4 ++-- starpilot/system/bluetooth/protocol.py | 5 ++--- .../system/bluetooth/tests/test_bluetooth.py | 14 +++++++++++++- .../the_galaxy/assets/components/router.js | 2 +- .../assets/components/tools/bluetooth.js | 19 +++++++++++++------ .../tests/test_frontend_module_graph.py | 3 +++ starpilot/system/the_galaxy/the_galaxy.py | 2 +- 10 files changed, 38 insertions(+), 17 deletions(-) diff --git a/scripts/MODEL_RELEASE.md b/scripts/MODEL_RELEASE.md index 32f43c3626..8b84615770 100644 --- a/scripts/MODEL_RELEASE.md +++ b/scripts/MODEL_RELEASE.md @@ -48,7 +48,7 @@ rerun with `--allow-runtime-changes` only after Firestar approves it. The default resources checkout is `~/StarPilot-Resources` on branch `Models`. It must be clean and synchronized before starting. The default Hugging Face -bucket is `firestar4430/StarPilot-Resources`; authenticate with `hf auth login` +bucket is `StarPilot-Driving/StarPilot-Resources`; authenticate with `hf auth login` before use. Use `--dry-run` to test parsing and the runtime scan without touching the device or either resource store. diff --git a/scripts/model_release.py b/scripts/model_release.py index 52b682c2eb..e6c6aabe33 100755 --- a/scripts/model_release.py +++ b/scripts/model_release.py @@ -29,7 +29,7 @@ from pathlib import Path OPENPILOT_REPO = "commaai/openpilot" RESOURCES_REPO = os.environ.get("STARPILOT_RESOURCES_REPO", "firestar5683/StarPilot-Resources") -HF_BUCKET = os.environ.get("STARPILOT_HF_BUCKET", "firestar4430/StarPilot-Resources") +HF_BUCKET = os.environ.get("STARPILOT_HF_BUCKET", "StarPilot-Driving/StarPilot-Resources") RESOURCE_BRANCH = "Models" MANIFEST_VERSION = "v24" DEFAULT_BEHAVIOR_VERSION = "v16" diff --git a/starpilot/common/starpilot_download_utilities.py b/starpilot/common/starpilot_download_utilities.py index a86753fc90..aeb0b6f1e9 100644 --- a/starpilot/common/starpilot_download_utilities.py +++ b/starpilot/common/starpilot_download_utilities.py @@ -7,7 +7,7 @@ from datetime import datetime, timezone from openpilot.starpilot.common.starpilot_utilities import delete_file, is_url_pingable from openpilot.starpilot.common.starpilot_variables import RESOURCES_REPO -HF_BUCKET = os.getenv("STARPILOT_HF_BUCKET", "firestar4430/StarPilot-Resources") +HF_BUCKET = os.getenv("STARPILOT_HF_BUCKET", "StarPilot-Driving/StarPilot-Resources") HF_BUCKET_URL = f"https://huggingface.co/buckets/{HF_BUCKET}/resolve" GITHUB_URL = f"https://raw.githubusercontent.com/{RESOURCES_REPO}" diff --git a/starpilot/system/bluetooth/daemon.py b/starpilot/system/bluetooth/daemon.py index 98923dc10d..6ea8d5ae6f 100644 --- a/starpilot/system/bluetooth/daemon.py +++ b/starpilot/system/bluetooth/daemon.py @@ -99,7 +99,8 @@ class BluetoothController: prompt["name"] = device["name"] if device else self._pairing_address except Exception as error: result["error"] = str(error) - self._reset_client() + if not self._pairing_address: + self._reset_client() return result def _require_offroad(self, command: str) -> None: @@ -166,7 +167,6 @@ class BluetoothController: finally: self._reset_client() self._radio.stop() - self.params.remove("BluetoothAudioAddress") self.params.put_bool("BluetoothEnabled", False) self._scan_deadline = 0.0 elif command == "start_scan": diff --git a/starpilot/system/bluetooth/protocol.py b/starpilot/system/bluetooth/protocol.py index e2641691c6..a7ce359f99 100644 --- a/starpilot/system/bluetooth/protocol.py +++ b/starpilot/system/bluetooth/protocol.py @@ -17,7 +17,7 @@ A2DP_SINK_UUID = "0000110b-0000-1000-8000-00805f9b34fb" HID_UUID = "00001124-0000-1000-8000-00805f9b34fb" HOG_UUID = "00001812-0000-1000-8000-00805f9b34fb" COMMAND_TIMEOUTS = { - "set_power": 55.0, + "set_power": 90.0, "start_scan": 20.0, "stop_scan": 20.0, "connect": 35.0, @@ -151,7 +151,6 @@ class _DesktopFakeBluetooth: self._enabled = bool(payload.get("enabled", False)) self._discovering = False if not self._enabled: - self._selected_audio = "" self._devices = tuple(replace(device, connected=False) for device in self._devices) elif command == "start_scan": self._require_enabled() @@ -265,7 +264,7 @@ class BluetoothClient: bootstrap = enabled and not os.path.exists(self.socket_path) if bootstrap: params.put_bool("BluetoothEnabled", True) - deadline = time.monotonic() + max(self.timeout, 10.0) + deadline = time.monotonic() + max(self.timeout, 45.0) while not os.path.exists(self.socket_path): if time.monotonic() >= deadline: params.put_bool("BluetoothEnabled", False) diff --git a/starpilot/system/bluetooth/tests/test_bluetooth.py b/starpilot/system/bluetooth/tests/test_bluetooth.py index 1628a50cbc..0e61937e7d 100644 --- a/starpilot/system/bluetooth/tests/test_bluetooth.py +++ b/starpilot/system/bluetooth/tests/test_bluetooth.py @@ -201,10 +201,12 @@ def test_desktop_fake_bluetooth_is_stateful_and_interactive(monkeypatch, tmp_pat client.set_power(False) disabled = client.status() assert not disabled.enabled and not disabled.powered and not disabled.discovering + assert disabled.selected_audio == speaker.address with pytest.raises(RuntimeError, match="Enable Bluetooth"): client.start_scan() client.set_power(True) - assert client.status().enabled + enabled = client.status() + assert enabled.enabled and enabled.selected_audio == speaker.address def test_desktop_fake_bluetooth_cannot_activate_on_device(monkeypatch, tmp_path): @@ -265,6 +267,16 @@ def test_power_pair_audio_and_offroad_enforcement(): assert not params.get_bool("BluetoothEnabled") and radio.stops == 1 and clients[0].closed +def test_power_off_preserves_saved_audio_selection(): + params = FakeParams(IsOffroad=True, BluetoothEnabled=False, BluetoothAudioAddress="00:11:22:33:44:55") + controller = BluetoothController(params, FakeBlueZ, FakeRadio()) + + controller.handle({"command": "set_power", "enabled": True}) + controller.handle({"command": "set_power", "enabled": False}) + + assert params.get("BluetoothAudioAddress") == "00:11:22:33:44:55" + + def test_status_does_not_restart_radio_during_disable(): params = FakeParams(IsOffroad=True, BluetoothEnabled=True) radio = BlockingStopRadio() diff --git a/starpilot/system/the_galaxy/assets/components/router.js b/starpilot/system/the_galaxy/assets/components/router.js index 028cc284e7..fdb2a693b5 100644 --- a/starpilot/system/the_galaxy/assets/components/router.js +++ b/starpilot/system/the_galaxy/assets/components/router.js @@ -2,7 +2,7 @@ import { html, reactive } from "/assets/vendor/arrow-core.js" import { createBrowserHistory, createRouter } from "/assets/vendor/remix-router-1.3.1.js" import { hideSidebar } from "/assets/js/utils.js" import { DeviceSettings } from "/assets/components/tools/device_settings.js?v=favorite-c4-hint-1" -import { Bluetooth } from "/assets/components/tools/bluetooth.js?v=bluetooth-5" +import { Bluetooth } from "/assets/components/tools/bluetooth.js?v=bluetooth-6" import { WheelControls } from "/assets/components/tools/wheel_controls.js?v=controllers-2" import { ErrorLogs } from "/assets/components/tools/error_logs.js" import { VehicleFeatures } from "/assets/components/tools/vehicle_features.js" diff --git a/starpilot/system/the_galaxy/assets/components/tools/bluetooth.js b/starpilot/system/the_galaxy/assets/components/tools/bluetooth.js index f3289cd4a5..afc55f94c3 100644 --- a/starpilot/system/the_galaxy/assets/components/tools/bluetooth.js +++ b/starpilot/system/the_galaxy/assets/components/tools/bluetooth.js @@ -4,6 +4,7 @@ import { galaxyPath } from "/assets/js/utils.js" const state = reactive({ loading: true, busy: "", + powerTarget: null, available: false, enabled: false, powered: false, @@ -38,7 +39,8 @@ function pollDelay() { function schedulePoll(delay = pollDelay()) { if (pollTimer !== null) clearTimeout(pollTimer) pollTimer = setTimeout(async () => { - if (bluetoothPageActive()) await refresh() + pollTimer = null + if (bluetoothPageActive() && state.busy !== "power") await refresh() schedulePoll() }, delay) } @@ -69,6 +71,7 @@ function startAudioTestCountdown(address, delayMs, requestStartedAt) { async function request(operation, body = {}) { const requestStartedAt = performance.now() state.busy = operation + if (operation === "power") state.powerTarget = !!body.enabled schedulePoll(250) try { const response = await fetch(galaxyPath(`/api/bluetooth/${operation}`), { @@ -88,6 +91,7 @@ async function request(operation, body = {}) { state.error = error?.message || "Bluetooth operation failed" } finally { state.busy = "" + if (operation === "power") state.powerTarget = null schedulePoll(250) } } @@ -155,7 +159,8 @@ async function refresh() { } function initialize() { - if (!initialized) initialized = true + if (initialized) return + initialized = true schedulePoll(0) } @@ -203,7 +208,7 @@ function deviceActions(device) { const pairing = () => isPairing(device) return html`
- ${!device.paired ? html` + ${!device.paired && !device.connected ? html` @@ -222,10 +227,10 @@ function deviceActions(device) { ` : ""} ` : ""} - + }}">` : ""} `}
` @@ -279,7 +284,9 @@ export function Bluetooth() { diff --git a/starpilot/system/the_galaxy/tests/test_frontend_module_graph.py b/starpilot/system/the_galaxy/tests/test_frontend_module_graph.py index 5822eaa773..79944e4129 100644 --- a/starpilot/system/the_galaxy/tests/test_frontend_module_graph.py +++ b/starpilot/system/the_galaxy/tests/test_frontend_module_graph.py @@ -42,6 +42,9 @@ def test_bluetooth_actions_use_reactive_disabled_bindings(): assert "bluetoothForgetButton" in source assert "bi-trash3" in source assert "state.pairingAddress" in source + assert "state.busy !== \"power\"" in source + assert "Turning Bluetooth" in source + assert "!device.paired && !device.connected" in source assert 'galaxyPath("/bluetooth")' in source assert 'window.location.pathname === "/bluetooth"' not in source assert "schedulePoll(250)" in source diff --git a/starpilot/system/the_galaxy/the_galaxy.py b/starpilot/system/the_galaxy/the_galaxy.py index 88fb5b27a2..bd621b1837 100644 --- a/starpilot/system/the_galaxy/the_galaxy.py +++ b/starpilot/system/the_galaxy/the_galaxy.py @@ -4969,7 +4969,7 @@ def setup(app): @app.route("/api/bluetooth/status", methods=["GET"]) def bluetooth_status(): try: - status = BluetoothClient(timeout=3.0).status() + status = BluetoothClient(timeout=10.0).status() return jsonify(BluetoothClient.serialize_status(status)), 200 except Exception as error: return jsonify({