feat: add remote device settings portal and Pi hot reload
- add /settings/device portal page and portal device-config GET endpoint - add portal navigation and client-side device settings editor UI - hot-reload Account/Car display config after local saves and server syncs - document portal workflow and Phase 25.5b completion - add runtime reload tests for account, car, and sync callback Co-authored-by: Copilot <[email protected]>
This commit is contained in:
@@ -1,15 +1,22 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
|
||||
class Account:
|
||||
def __init__(self):
|
||||
# Load from config/device.json at startup
|
||||
# Database values are updated via Settings UI, but Account object reflects startup state
|
||||
config = self._load_config()
|
||||
self.name = config.get("owner_name", "quoije")
|
||||
self.avatar_path = config.get("avatar_path", "img/yaris.png")
|
||||
self.pp_image = None
|
||||
self.car = None
|
||||
|
||||
def reload_runtime_config(self):
|
||||
"""Refresh display-facing fields from the live device config store."""
|
||||
from . import app_device_config
|
||||
|
||||
config = app_device_config.get_device_config()
|
||||
self.name = config.get("owner_name", "quoije")
|
||||
self.avatar_path = config.get("avatar_path", "img/yaris.png")
|
||||
|
||||
def _load_config(self):
|
||||
"""Load device config from JSON file, return dict with defaults."""
|
||||
|
||||
+10
-3
@@ -1,15 +1,22 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
|
||||
class Car:
|
||||
def __init__(self):
|
||||
# Load from config/device.json at startup
|
||||
# Database values are updated via Settings UI, but Car object reflects startup state
|
||||
config = self._load_config()
|
||||
self.model = config.get("car_model", "Yaris 2013")
|
||||
self.device_name = config.get("device_name", "Yaris OBD")
|
||||
self.obd = None
|
||||
|
||||
|
||||
def reload_runtime_config(self):
|
||||
"""Refresh display-facing fields from the live device config store."""
|
||||
from . import app_device_config
|
||||
|
||||
config = app_device_config.get_device_config()
|
||||
self.model = config.get("car_model", "Yaris 2013")
|
||||
self.device_name = config.get("device_name", "Yaris OBD")
|
||||
|
||||
def _load_config(self):
|
||||
"""Load device config from JSON file, return dict with defaults."""
|
||||
config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config", "device.json")
|
||||
|
||||
@@ -17,6 +17,7 @@ from . import app_network, app_sql
|
||||
_SYNC_THREAD = None
|
||||
_SYNC_STOP = False
|
||||
_SYNC_CONFIG_VERSION = 0 # Track last-synced version to detect changes
|
||||
_RELOAD_CALLBACK = None
|
||||
|
||||
|
||||
def _has_internet():
|
||||
@@ -44,6 +45,12 @@ def start_sync():
|
||||
_SYNC_THREAD.start()
|
||||
|
||||
|
||||
def register_reload_callback(callback):
|
||||
"""Register a callback invoked after synced config is written locally."""
|
||||
global _RELOAD_CALLBACK
|
||||
_RELOAD_CALLBACK = callback
|
||||
|
||||
|
||||
def stop_sync():
|
||||
"""Stop background device config sync thread."""
|
||||
global _SYNC_STOP
|
||||
@@ -112,10 +119,8 @@ def _store_synced_config(config):
|
||||
|
||||
def _on_config_changed():
|
||||
"""Called when config changes and needs to be reloaded by app."""
|
||||
# This is a signal for future hot-reload implementation
|
||||
# For now, config is automatically read from database on each request
|
||||
# A full reload would require restarting the app or using a signal handler
|
||||
pass
|
||||
if _RELOAD_CALLBACK is not None:
|
||||
_RELOAD_CALLBACK()
|
||||
|
||||
|
||||
def is_sync_enabled():
|
||||
|
||||
Reference in New Issue
Block a user