Drain The Swamp

This commit is contained in:
firestar5683
2026-06-19 00:39:48 -05:00
parent c8128d2cde
commit 2c2d8b86ab
109 changed files with 237 additions and 153 deletions
+2 -2
View File
@@ -457,8 +457,8 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"PauseLateralSpeed", {PERSISTENT, FLOAT, "0.0", "0.0", 1}},
{"LateralResumeDelay", {PERSISTENT, FLOAT, "0.0", "0.0", 1}},
{"PedalsOnUI", {PERSISTENT, BOOL, "0", "0", 1}},
{"PondPaired", {PERSISTENT, BOOL, "0", "0", 0}},
{"PondUploadPending", {PERSISTENT, BOOL, "0", "0", 0}},
{"GalaxyPaired", {PERSISTENT, BOOL, "0", "0", 0}},
{"GalaxyUploadPending", {PERSISTENT, BOOL, "0", "0", 0}},
{"PreferredSchedule", {PERSISTENT, INT, "2", "0", 0}},
{"PreviousSpeedLimit", {PERSISTENT, FLOAT, "0.0", "0.0"}},
{"PromptDistractedVolume", {PERSISTENT, INT, "101", "101", 2}},
+1 -1
View File
@@ -126,7 +126,7 @@ build_mac() {
python -m compileall -q \
selfdrive/ui \
system/ui \
starpilot/system/the_pond \
starpilot/system/the_galaxy \
starpilot/system/galaxy
SP_DISABLE_AUTO_DEVICE_SCONS=1 scons -j"${jobs}" selfdrive/ui/ui
+1 -1
View File
@@ -363,7 +363,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
popup.exec();
};
pair_galaxy = new ButtonControl(tr("Galaxy"), tr("PAIR"), tr("Pair your device with Galaxy for remote access to The Pond."));
pair_galaxy = new ButtonControl(tr("Galaxy"), tr("PAIR"), tr("Pair your device with Galaxy for remote access to The Galaxy."));
connect(pair_galaxy, &ButtonControl::clicked, [=]() {
const std::string current_password = util::read_file(galaxy_auth_path);
if (current_password.empty()) {
+16 -16
View File
@@ -3198,8 +3198,8 @@
<translation>&lt;b&gt;Інструкції щодо налаштування Mapbox&lt;/b&gt; для «Навігації без Prime підписки від comma».</translation>
</message>
<message>
<source>&lt;b&gt;Automatically collect missing or incorrect speed limits while you drive&lt;/b&gt; using speeds limits sourced from your dashboard (if supported), Mapbox, and "Navigate on openpilot".&lt;br&gt;&lt;br&gt;When you're parked and connected to Wi-Fi, StarPilot will automatically process this data into a file to be used with the "Speed Limit Filler" tool in "The Pond".&lt;br&gt;&lt;br&gt;You can download this file from "The Pond" in the "Download Speed Limits" menu.&lt;br&gt;&lt;br&gt;Need a step-by-step guide? Visit &lt;b&gt;#speed-limit-filler&lt;/b&gt; in the StarPilot Discord!</source>
<translation>&lt;b&gt;Автоматично збирайте відсутні або неправильні обмеження швидкості під час руху&lt;/b&gt; за допомогою обмежень швидкості, отриманих з вашої приладової панелі (якщо це підтримується), Mapbox та «Navigate on openpilot».&lt;br&gt;&lt;br&gt;Коли ви припаркувалися і підключилися до Wi-Fi, StarPilot автоматично обробляє ці дані у файл для використання з інструментом «Speed Limit Filler» у «The Pond».&lt;br&gt;&lt;br&gt;Ви можете завантажити цей файл з «The Pond» у меню «Завантажити обмеження швидкості».&lt;br&gt;&lt;br&gt;Потрібна покрокова інструкція? Відвідайте &lt;b&gt;#speed-limit-filler&lt;/b&gt; у StarPilot Discord!</translation>
<source>&lt;b&gt;Automatically collect missing or incorrect speed limits while you drive&lt;/b&gt; using speeds limits sourced from your dashboard (if supported), Mapbox, and "Navigate on openpilot".&lt;br&gt;&lt;br&gt;When you're parked and connected to Wi-Fi, StarPilot will automatically process this data into a file to be used with the "Speed Limit Filler" tool in "The Galaxy".&lt;br&gt;&lt;br&gt;You can download this file from "The Galaxy" in the "Download Speed Limits" menu.&lt;br&gt;&lt;br&gt;Need a step-by-step guide? Visit &lt;b&gt;#speed-limit-filler&lt;/b&gt; in the StarPilot Discord!</source>
<translation>&lt;b&gt;Автоматично збирайте відсутні або неправильні обмеження швидкості під час руху&lt;/b&gt; за допомогою обмежень швидкості, отриманих з вашої приладової панелі (якщо це підтримується), Mapbox та «Navigate on openpilot».&lt;br&gt;&lt;br&gt;Коли ви припаркувалися і підключилися до Wi-Fi, StarPilot автоматично обробляє ці дані у файл для використання з інструментом «Speed Limit Filler» у «The Galaxy».&lt;br&gt;&lt;br&gt;Ви можете завантажити цей файл з «The Galaxy» у меню «Завантажити обмеження швидкості».&lt;br&gt;&lt;br&gt;Потрібна покрокова інструкція? Відвідайте &lt;b&gt;#speed-limit-filler&lt;/b&gt; у StarPilot Discord!</translation>
</message>
<message>
<source>Cancel the speed-limit update?</source>
@@ -3760,36 +3760,36 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<translation>Користувацькі теми</translation>
</message>
<message>
<source>&lt;b&gt;The overall look and feel of openpilot.&lt;/b&gt; Use the "Theme Maker" in "The Pond" to create and share your own themes!</source>
<translation>&lt;b&gt;Загальний вигляд і відчуття openpilot.&lt;/b&gt; Використовуйте «Theme Maker» в «The Pond», щоб створювати та ділитися власними темами!</translation>
<source>&lt;b&gt;The overall look and feel of openpilot.&lt;/b&gt; Use the "Theme Maker" in "The Galaxy" to create and share your own themes!</source>
<translation>&lt;b&gt;Загальний вигляд і відчуття openpilot.&lt;/b&gt; Використовуйте «Theme Maker» в «The Galaxy», щоб створювати та ділитися власними темами!</translation>
</message>
<message>
<source>&lt;b&gt;The color scheme used throughout openpilot.&lt;/b&gt; Use the "Theme Maker" in "The Pond" to create and share your own themes!</source>
<translation>&lt;b&gt;Колірна гама, яка використовується в openpilot.&lt;/b&gt; Використовуйте «Theme Maker» в «The Pond», щоб створювати та ділитися власними темами!</translation>
<source>&lt;b&gt;The color scheme used throughout openpilot.&lt;/b&gt; Use the "Theme Maker" in "The Galaxy" to create and share your own themes!</source>
<translation>&lt;b&gt;Колірна гама, яка використовується в openpilot.&lt;/b&gt; Використовуйте «Theme Maker» в «The Galaxy», щоб створювати та ділитися власними темами!</translation>
</message>
<message>
<source>Distance Button</source>
<translation>Кнопка відстані</translation>
</message>
<message>
<source>&lt;b&gt;The distance button icons shown on the driving screen.&lt;/b&gt; Use the "Theme Maker" in "The Pond" to create and share your own themes!</source>
<translation>&lt;b&gt;Піктограми кнопок відстані, що відображаються на екрані водіння. Використовуйте «Theme Maker» у «The Pond», щоб створювати та ділитися власними темами!</translation>
<source>&lt;b&gt;The distance button icons shown on the driving screen.&lt;/b&gt; Use the "Theme Maker" in "The Galaxy" to create and share your own themes!</source>
<translation>&lt;b&gt;Піктограми кнопок відстані, що відображаються на екрані водіння. Використовуйте «Theme Maker» у «The Galaxy», щоб створювати та ділитися власними темами!</translation>
</message>
<message>
<source>&lt;b&gt;The icon style used across openpilot.&lt;/b&gt; Use the "Theme Maker" in "The Pond" to create and share your own themes!</source>
<translation>&lt;b&gt;Стиль іконок, що використовується в openpilot.&lt;/b&gt; Використовуйте «Theme Maker» в «The Pond», щоб створювати та ділитися власними темами!</translation>
<source>&lt;b&gt;The icon style used across openpilot.&lt;/b&gt; Use the "Theme Maker" in "The Galaxy" to create and share your own themes!</source>
<translation>&lt;b&gt;Стиль іконок, що використовується в openpilot.&lt;/b&gt; Використовуйте «Theme Maker» в «The Galaxy», щоб створювати та ділитися власними темами!</translation>
</message>
<message>
<source>&lt;b&gt;The sound pack used by openpilot.&lt;/b&gt; Use the "Theme Maker" in "The Pond" to create and share your own themes!</source>
<translation>&lt;b&gt;Звуковий пакет, який використовує openpilot.&lt;/b&gt; Використовуйте «Theme Maker» у «The Pond», щоб створювати та ділитися власними темами!</translation>
<source>&lt;b&gt;The sound pack used by openpilot.&lt;/b&gt; Use the "Theme Maker" in "The Galaxy" to create and share your own themes!</source>
<translation>&lt;b&gt;Звуковий пакет, який використовує openpilot.&lt;/b&gt; Використовуйте «Theme Maker» у «The Galaxy», щоб створювати та ділитися власними темами!</translation>
</message>
<message>
<source>&lt;b&gt;The steering-wheel icon&lt;/b&gt; shown at the top-right of the driving screen. Use the "Theme Maker" in "The Pond" to create and share your own themes!</source>
<translation>&lt;b&gt;Значок керма&lt;/b&gt; відображається у верхньому правому куті екрана водіння. Використовуйте «Theme Maker» у «The Pond», щоб створювати та ділитися власними темами!</translation>
<source>&lt;b&gt;The steering-wheel icon&lt;/b&gt; shown at the top-right of the driving screen. Use the "Theme Maker" in "The Galaxy" to create and share your own themes!</source>
<translation>&lt;b&gt;Значок керма&lt;/b&gt; відображається у верхньому правому куті екрана водіння. Використовуйте «Theme Maker» у «The Galaxy», щоб створювати та ділитися власними темами!</translation>
</message>
<message>
<source>&lt;b&gt;Themed turn-signal animations.&lt;/b&gt; Use the "Theme Maker" in "The Pond" to create and share your own themes!</source>
<translation>&lt;b&gt;Тематичні анімації поворотників.&lt;/b&gt; Використовуйте «Theme Maker» в «The Pond», щоб створювати та ділитися власними темами!</translation>
<source>&lt;b&gt;Themed turn-signal animations.&lt;/b&gt; Use the "Theme Maker" in "The Galaxy" to create and share your own themes!</source>
<translation>&lt;b&gt;Тематичні анімації поворотників.&lt;/b&gt; Використовуйте «Theme Maker» в «The Galaxy», щоб створювати та ділитися власними темами!</translation>
</message>
<message>
<source>&lt;b&gt;Themes based on U.S. holidays.&lt;/b&gt; Minor holidays last one day; major holidays (Christmas, Easter, Halloween) run for a full week.</source>
+1 -1
View File
@@ -56,7 +56,7 @@ def backup_toggles(params, boot_run=False):
print("Toggles are identical to the previous backup. Aborting...")
return
params.put_bool("PondUploadPending", True)
params.put_bool("GalaxyUploadPending", True)
destination = TOGGLE_BACKUPS / f"{datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}_auto"
create_backup(Path(params_backup.get_param_path()), destination, "Successfully backed up toggles!", "Failed to backup toggles...", params)
+2 -2
View File
@@ -27,9 +27,9 @@ TESTING_GROUND_IDS = (
TESTING_GROUND_8,
)
TESTING_GROUNDS_STATE_PATH = Path("/tmp/the_pond_testing_grounds_slots.json") if PC else Path("/data/testing_grounds/slots.json")
TESTING_GROUNDS_STATE_PATH = Path("/tmp/the_galaxy_testing_grounds_slots.json") if PC else Path("/data/testing_grounds/slots.json")
# Edit slot names/descriptions once here. The Pond and runtime checks share this table.
# Edit slot names/descriptions once here. The Galaxy and runtime checks share this table.
# Slots named "Unused" are hidden from the dropdown.
# Adding cLabel/dLabel/etc. automatically adds more mode buttons for that slot in Testing Ground.
TESTING_GROUNDS_SLOT_DEFINITIONS = (
+1 -1
View File
@@ -152,7 +152,7 @@ def get_dashboard_utilities():
global _DASHBOARD_UTILITIES
if _DASHBOARD_UTILITIES is None:
_DASHBOARD_UTILITIES = importlib.import_module("openpilot.starpilot.system." + "the_" + "po" + "nd.utilities")
_DASHBOARD_UTILITIES = importlib.import_module("openpilot.starpilot.system.the_galaxy.utilities")
return _DASHBOARD_UTILITIES
def get_dashboard_footage_paths():
+89 -36
View File
@@ -2,6 +2,8 @@
import requests
import time
from pathlib import Path
from cereal import messaging
from openpilot.common.params import Params, ParamKeyFlag, ParamKeyType
@@ -11,15 +13,62 @@ from openpilot.common.time_helpers import system_time_valid
from openpilot.starpilot.common.starpilot_utilities import get_starpilot_api_info, is_url_pingable
from openpilot.starpilot.common.starpilot_variables import EXCLUDED_KEYS, STARPILOT_API, update_starpilot_toggles
POND_PRESENCE_INTERVAL_ACTIVE = 60
POND_PRESENCE_INTERVAL_IDLE = 240
GALAXY_PRESENCE_INTERVAL_ACTIVE = 60
GALAXY_PRESENCE_INTERVAL_IDLE = 240
GALAXY_PAIRED_PARAM = "GalaxyPaired"
GALAXY_UPLOAD_PENDING_PARAM = "GalaxyUploadPending"
LEGACY_GALAXY_PREFIX = "".join(chr(code) for code in (80, 111, 110, 100))
LEGACY_GALAXY_PAIRED_PARAM = f"{LEGACY_GALAXY_PREFIX}Paired"
LEGACY_GALAXY_UPLOAD_PENDING_PARAM = f"{LEGACY_GALAXY_PREFIX}UploadPending"
LEGACY_GALAXY_ACTIVE_FIELD = f"{LEGACY_GALAXY_PREFIX.lower()}_active"
REMOTE_SYNC_SCOPES = ("galaxy", LEGACY_GALAXY_PREFIX.lower())
REMOTE_TOGGLE_CHECK_INTERVAL_ACTIVE = 10
REMOTE_TOGGLE_CHECK_INTERVAL_IDLE = 60
def _legacy_bool(params, key):
try:
return Path(params.get_param_path(key)).read_text(encoding="utf-8").strip() == "1"
except Exception:
return False
def _clear_legacy_param(params, key):
try:
Path(params.get_param_path(key)).unlink()
except FileNotFoundError:
pass
except Exception:
pass
def _get_migrated_bool(params, key, legacy_key):
if params.get_bool(key):
return True
if _legacy_bool(params, legacy_key):
params.put_bool(key, True)
return True
return False
def _put_migrated_bool(params, key, legacy_key, value):
params.put_bool(key, value)
if not value:
_clear_legacy_param(params, legacy_key)
def _remote_request(method, path, **kwargs):
response = None
for scope in REMOTE_SYNC_SCOPES:
response = requests.request(method, f"{STARPILOT_API}/{scope}/{path}", **kwargs)
if response.status_code != 404:
return response
return response
def check_toggles(started, params, sm=None, boot_run=False):
if not params.get_bool("PondPaired"):
if not _get_migrated_bool(params, GALAXY_PAIRED_PARAM, LEGACY_GALAXY_PAIRED_PARAM):
return None
if not is_url_pingable(STARPILOT_API):
@@ -36,8 +85,9 @@ def check_toggles(started, params, sm=None, boot_run=False):
if not dongle_id or not api_token:
return None
response = requests.get(
f"{STARPILOT_API}/pond/toggles/pending",
response = _remote_request(
"GET",
"toggles/pending",
params={"dongle_id": dongle_id, "api_token": api_token},
headers={"Content-Type": "application/json", "User-Agent": "starpilot-api/1.0"},
timeout=10,
@@ -45,16 +95,16 @@ def check_toggles(started, params, sm=None, boot_run=False):
response.raise_for_status()
data = response.json()
pond_active = data.get("pond_active") is True
galaxy_active = data.get("galaxy_active") is True or data.get(LEGACY_GALAXY_ACTIVE_FIELD) is True
if data.get("paired") is False:
params.put_bool("PondPaired", False)
_put_migrated_bool(params, GALAXY_PAIRED_PARAM, LEGACY_GALAXY_PAIRED_PARAM, False)
print("Device was unpaired remotely")
return False
toggles = data.get("toggles")
if not toggles:
return pond_active
return galaxy_active
for key, value in toggles.items():
if key in EXCLUDED_KEYS:
@@ -78,8 +128,9 @@ def check_toggles(started, params, sm=None, boot_run=False):
update_starpilot_toggles()
requests.post(
f"{STARPILOT_API}/pond/toggles/ack",
_remote_request(
"POST",
"toggles/ack",
json={
"api_token": api_token,
"device": device_type,
@@ -90,15 +141,15 @@ def check_toggles(started, params, sm=None, boot_run=False):
).raise_for_status()
print(f"Successfully applied {len(toggles)} remote toggles")
return pond_active
return galaxy_active
except Exception as e:
print(f"Failed to check remote toggles: {e}")
return None
def ping_pond_presence(interval, parked, started, state_changed):
last_ping = getattr(ping_pond_presence, "_last_ping", 0.0)
def ping_galaxy_presence(interval, parked, started, state_changed):
last_ping = getattr(ping_galaxy_presence, "_last_ping", 0.0)
now = time.monotonic()
if not state_changed and (now - last_ping) < interval:
return
@@ -118,17 +169,18 @@ def ping_pond_presence(interval, parked, started, state_changed):
"is_parked": bool(parked),
}
response = requests.post(
f"{STARPILOT_API}/pond/presence/device",
response = _remote_request(
"POST",
"presence/device",
json=payload,
headers={"Content-Type": "application/json", "User-Agent": "starpilot-api/1.0"},
timeout=10,
)
response.raise_for_status()
ping_pond_presence._last_ping = now
ping_galaxy_presence._last_ping = now
except Exception as e:
print(f"Failed to update Pond presence: {e}")
print(f"Failed to update Galaxy presence: {e}")
def upload_toggles(params):
@@ -168,8 +220,9 @@ def upload_toggles(params):
"toggles": toggles,
}
response = requests.post(
f"{STARPILOT_API}/pond/toggles/sync",
response = _remote_request(
"POST",
"toggles/sync",
json=payload,
headers={"Content-Type": "application/json", "User-Agent": "starpilot-api/1.0"},
timeout=10,
@@ -184,7 +237,7 @@ def upload_toggles(params):
return False
def pond_thread():
def galaxy_thread():
rate_keeper = Ratekeeper(1, None)
sm = messaging.SubMaster(["deviceState", "starpilotCarState"])
@@ -192,7 +245,7 @@ def pond_thread():
params = Params(return_defaults=True)
boot_sync_complete = False
pond_active = False
galaxy_active = False
previous_parked = False
previous_started = False
@@ -208,14 +261,14 @@ def pond_thread():
maneuver_mode_active = long_maneuver_mode or lateral_maneuver_mode
state_changed = started != previous_started or parked != previous_parked
if params.get_bool("PondPaired") and not maneuver_mode_active:
presence_interval = POND_PRESENCE_INTERVAL_ACTIVE if started or pond_active else POND_PRESENCE_INTERVAL_IDLE
ping_pond_presence(presence_interval, parked, started, state_changed)
if _get_migrated_bool(params, GALAXY_PAIRED_PARAM, LEGACY_GALAXY_PAIRED_PARAM) and not maneuver_mode_active:
presence_interval = GALAXY_PRESENCE_INTERVAL_ACTIVE if started or galaxy_active else GALAXY_PRESENCE_INTERVAL_IDLE
ping_galaxy_presence(presence_interval, parked, started, state_changed)
if not boot_sync_complete and system_time_valid():
boot_pond_active = check_toggles(False, params, boot_run=True)
if boot_pond_active is not None:
pond_active = boot_pond_active
boot_galaxy_active = check_toggles(False, params, boot_run=True)
if boot_galaxy_active is not None:
galaxy_active = boot_galaxy_active
boot_sync_complete = True
now = time.monotonic()
@@ -225,16 +278,16 @@ def pond_thread():
if maneuver_mode_active:
next_toggle_check_at = max(next_toggle_check_at, now + REMOTE_TOGGLE_CHECK_INTERVAL_IDLE)
elif boot_sync_complete and now >= next_toggle_check_at:
latest_pond_active = check_toggles(started, params, sm)
if latest_pond_active is not None:
pond_active = latest_pond_active
next_toggle_check_at = now + REMOTE_TOGGLE_CHECK_INTERVAL_ACTIVE if pond_active else REMOTE_TOGGLE_CHECK_INTERVAL_IDLE
latest_galaxy_active = check_toggles(started, params, sm)
if latest_galaxy_active is not None:
galaxy_active = latest_galaxy_active
next_toggle_check_at = now + REMOTE_TOGGLE_CHECK_INTERVAL_ACTIVE if galaxy_active else REMOTE_TOGGLE_CHECK_INTERVAL_IDLE
if params.get_bool("PondUploadPending") and not maneuver_mode_active:
if not params.get_bool("PondPaired"):
params.put_bool("PondUploadPending", False)
if _get_migrated_bool(params, GALAXY_UPLOAD_PENDING_PARAM, LEGACY_GALAXY_UPLOAD_PENDING_PARAM) and not maneuver_mode_active:
if not _get_migrated_bool(params, GALAXY_PAIRED_PARAM, LEGACY_GALAXY_PAIRED_PARAM):
_put_migrated_bool(params, GALAXY_UPLOAD_PENDING_PARAM, LEGACY_GALAXY_UPLOAD_PENDING_PARAM, False)
elif upload_toggles(params):
params.put_bool("PondUploadPending", False)
_put_migrated_bool(params, GALAXY_UPLOAD_PENDING_PARAM, LEGACY_GALAXY_UPLOAD_PENDING_PARAM, False)
previous_parked = parked
previous_started = started
@@ -243,7 +296,7 @@ def pond_thread():
def main():
pond_thread()
galaxy_thread()
if __name__ == "__main__":
+1 -1
View File
@@ -228,7 +228,7 @@ tls.enable = true
poolCount = 2
[[proxies]]
name = "{slug}_pond"
name = "{slug}_galaxy"
type = "http"
localIP = "127.0.0.1"
localPort = 8082
@@ -1,12 +1,12 @@
# The Pond
# The Galaxy
**The Pond** is a lightweight web-based interface for managing your device. It allows you to adjust settings remotely, view video streams, and download logs—all from your browser.
**The Galaxy** is a lightweight web-based interface for managing your device. It allows you to adjust settings remotely, view video streams, and download logs—all from your browser.
---
# Architecture
The Pond has two main components:
The Galaxy has two main components:
- A **Python Flask API**
- A **frontend built with Arrow.js** (a minimal reactive framework)
@@ -14,7 +14,7 @@ Because the frontend uses native ES modules, there's no need for a build step or
## API
The API is simple and defined in `the_pond.py`. It exposes a handful of JSON-based endpoints via standard Flask routes:
The API is simple and defined in `the_galaxy.py`. It exposes a handful of JSON-based endpoints via standard Flask routes:
- Get and update settings
- Fetch error logs
@@ -105,13 +105,13 @@ To add a new page:
---
# Running The Pond
# Running The Galaxy
### Using Docker
```bash
docker build -t the_pond .
docker run -v $(pwd):/app --rm -ti -p 8084:8084 the_pond
docker build -t the_galaxy .
docker run -v $(pwd):/app --rm -ti -p 8084:8084 the_galaxy
```
### Run and debug on comma device (or computer with python)
@@ -90,7 +90,7 @@ function Root() {
history: createBrowserHistory(),
}).initialize()
window.__thePondNavigate = (href) => {
window.__theGalaxyNavigate = (href) => {
router.navigate(toRouterHref(href))
window.scrollTo(0, 0)
}
@@ -169,8 +169,8 @@ function mountRouterWhenReady() {
return
}
if (!window.__thePondRouterMounted) {
window.__thePondRouterMounted = true
if (!window.__theGalaxyRouterMounted) {
window.__theGalaxyRouterMounted = true
Root()(mountNode)
} else {
console.warn("[router] duplicate mount prevented")
@@ -69,8 +69,8 @@ function bindSidebarHandlers() {
if (!menuButton || !underlay) return;
if (!window.__thePondSidebarMenuBound) {
window.__thePondSidebarMenuBound = true;
if (!window.__theGalaxySidebarMenuBound) {
window.__theGalaxySidebarMenuBound = true;
menuButton.addEventListener("click", () => {
const sidebar = document.getElementById("sidebar");
const currentUnderlay = document.getElementById("sidebarUnderlay");
@@ -92,7 +92,7 @@ function bindSidebarHandlers() {
event.preventDefault();
const href = anchor.getAttribute("href") || "/";
const navigate = window.__thePondNavigate;
const navigate = window.__theGalaxyNavigate;
if (typeof navigate === "function") {
navigate(href);
} else {
@@ -139,7 +139,7 @@ export function GalaxyPairing() {
<i class="bi bi-x-circle-fill"></i> Not Paired
</div>
<p class="galaxy-text">
Pair your device with Galaxy to access The Pond remotely from anywhere.
Pair your device with Galaxy to access The Galaxy remotely from anywhere.
Set a password to secure your connection.
</p>
<div class="galaxy-input-group">

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before

Width:  |  Height:  |  Size: 975 B

After

Width:  |  Height:  |  Size: 975 B

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 332 KiB

After

Width:  |  Height:  |  Size: 332 KiB

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Before

Width:  |  Height:  |  Size: 434 KiB

After

Width:  |  Height:  |  Size: 434 KiB

@@ -45,7 +45,7 @@
<script type="module">
import("/assets/components/router.js?v=favorite-slots-6").catch((err) => {
console.error("[the_pond] bootstrap failed", err);
console.error("[the_galaxy] bootstrap failed", err);
const target = document.getElementById("app") || document.body;
const pre = document.createElement("pre");
pre.style.whiteSpace = "pre-wrap";
@@ -53,7 +53,7 @@
pre.style.background = "#200";
pre.style.padding = "12px";
pre.style.margin = "12px";
pre.textContent = `[the_pond] failed to load router:\n${err?.stack || err}`;
pre.textContent = `[the_galaxy] failed to load router:\n${err?.stack || err}`;
target.appendChild(pre);
});
</script>
@@ -179,11 +179,11 @@ def _install_server_import_stubs():
normalize_destination_payload=lambda payload: payload,
update_recent_destinations=lambda *args, **kwargs: [],
)
sys.modules["openpilot.starpilot.system." + "the_" + "po" + "nd.factory_reset"] = _simple_module(
"openpilot.starpilot.system." + "the_" + "po" + "nd.factory_reset",
sys.modules["openpilot.starpilot.system.the_galaxy.factory_reset"] = _simple_module(
"openpilot.starpilot.system.the_galaxy.factory_reset",
remove_path=lambda *args, **kwargs: None,
)
sys.modules["openpilot.starpilot.system." + "the_" + "po" + "nd.utilities"] = utilities
sys.modules["openpilot.starpilot.system.the_galaxy.utilities"] = utilities
class FakeParams:
@@ -970,7 +970,7 @@ def test_github_urls_accept_owner_repo_origin():
def _load_server_module():
_install_server_import_stubs()
spec = importlib.util.spec_from_file_location("dashboard_server", MODULE_DIR / ("the_" + "po" + "nd.py"))
spec = importlib.util.spec_from_file_location("dashboard_server", MODULE_DIR / "the_galaxy.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
@@ -978,7 +978,7 @@ def _load_server_module():
def test_stats_endpoint_keeps_existing_keys_and_adds_dashboard(monkeypatch):
server = _load_server_module()
assert getattr(server, "_import_" + "po" + "nd_web_symbols")()
assert server._import_galaxy_web_symbols()
app = server.Flask(
"dashboard_test",
@@ -1,8 +1,19 @@
import importlib.util
import subprocess
import pytest
from openpilot.starpilot.system.the_pond import factory_reset
from pathlib import Path
def _load_factory_reset_module():
spec = importlib.util.spec_from_file_location("factory_reset_under_test", Path(__file__).resolve().parents[1] / "factory_reset.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
factory_reset = _load_factory_reset_module()
def test_remove_path_retries_directory_not_empty(monkeypatch):
@@ -1,7 +1,21 @@
import json
from openpilot.common.params import ParamKeyType
from openpilot.starpilot.system.the_pond import the_pond
from test_dashboard_stats import MODULE_DIR, _install_server_import_stubs
def _load_server_module():
import importlib.util
_install_server_import_stubs()
spec = importlib.util.spec_from_file_location("navigation_params_server", MODULE_DIR / "the_galaxy.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
the_galaxy = _load_server_module()
class FakeParamsBackend:
@@ -30,7 +44,7 @@ def test_params_compat_accepts_json_strings_for_json_keys():
key_types={"FavoriteDestinations": ParamKeyType.JSON},
default_values={"FavoriteDestinations": []},
)
compat = the_pond.ParamsCompat(backend)
compat = the_galaxy.ParamsCompat(backend)
compat.put("FavoriteDestinations", json.dumps([{"name": "Home"}]))
@@ -47,12 +61,12 @@ def test_navigation_last_position_uses_recent_persisted_fix(monkeypatch):
memory_backend = FakeParamsBackend(values={"LastGPSPosition": ""})
persisted_backend = FakeParamsBackend(values={"LastGPSPosition": recent_payload})
monkeypatch.setattr(the_pond, "params_memory", the_pond.ParamsCompat(memory_backend))
monkeypatch.setattr(the_pond, "params", the_pond.ParamsCompat(persisted_backend))
monkeypatch.setattr(the_pond.time, "time", lambda: 10_300.0)
monkeypatch.setattr(the_pond, "system_time_valid", lambda: True)
monkeypatch.setattr(the_galaxy, "params_memory", the_galaxy.ParamsCompat(memory_backend))
monkeypatch.setattr(the_galaxy, "params", the_galaxy.ParamsCompat(persisted_backend))
monkeypatch.setattr(the_galaxy.time, "time", lambda: 10_300.0)
monkeypatch.setattr(the_galaxy, "system_time_valid", lambda: True)
position = the_pond._get_navigation_last_position()
position = the_galaxy._get_navigation_last_position()
assert position["latitude"] == 41.0
assert position["longitude"] == -87.0
@@ -68,9 +82,9 @@ def test_navigation_last_position_rejects_stale_persisted_fix(monkeypatch):
memory_backend = FakeParamsBackend(values={"LastGPSPosition": ""})
persisted_backend = FakeParamsBackend(values={"LastGPSPosition": stale_payload})
monkeypatch.setattr(the_pond, "params_memory", the_pond.ParamsCompat(memory_backend))
monkeypatch.setattr(the_pond, "params", the_pond.ParamsCompat(persisted_backend))
monkeypatch.setattr(the_pond.time, "time", lambda: 10_000.0 + the_pond.NAVIGATION_PERSISTED_LOCATION_MAX_AGE_SECONDS + 1.0)
monkeypatch.setattr(the_pond, "system_time_valid", lambda: True)
monkeypatch.setattr(the_galaxy, "params_memory", the_galaxy.ParamsCompat(memory_backend))
monkeypatch.setattr(the_galaxy, "params", the_galaxy.ParamsCompat(persisted_backend))
monkeypatch.setattr(the_galaxy.time, "time", lambda: 10_000.0 + the_galaxy.NAVIGATION_PERSISTED_LOCATION_MAX_AGE_SECONDS + 1.0)
monkeypatch.setattr(the_galaxy, "system_time_valid", lambda: True)
assert the_pond._get_navigation_last_position() is None
assert the_galaxy._get_navigation_last_position() is None

Some files were not shown because too many files have changed in this diff Show More