Host System Console service
Runtime and configuration
The console is a FastAPI host daemon plus React frontend. It controls configured systemd services, Docker/SDK installation, network profiles, audio, USB inspection, Jetson provisioning, Feetech diagnostics, RustDesk and console update status. These operations execute with the daemon's host permissions.
Configuration loads from /etc/hr-system-console/config.yaml, overridden by HR_SYSTEM_CONSOLE_CONFIG. Nested mappings merge with defaults. The source default bind is 0.0.0.0:80; development and README examples use different ports. Treat source defaults, packaged settings and example commands separately.
Default managed units include hrsdk.service, head-perception.service and hr-system-console-code.service. SDK settings select the host user, environment path and CLI executable. Setup state defaults beneath /var/lib/hr-system-console; configuration and credentials must be backed up with appropriate protection.
The inspected main application has no route-level login/authorization dependency. Remote proxy authentication is deployment-specific. Do not expose administrative endpoints directly to untrusted networks.
Common response patterns
Read routes return either fresh service results or refresh-cache snapshots. Mutating routes can return an immediate result or a background task. Pydantic request validation supplies HTTP 422 for missing/wrong typed fields; service errors and command errors follow handler-specific conversion. Use the route reference and inherited model reference for exact fields and explicit errors.
Background task records include UUID id, label, state, createdAt, updatedAt and, after completion, result and error. States are running/completed/failed. Progress can add bounded 0–100 progress and message. A completed task can contain an application-specific unsuccessful result; inspect it. Persisted tasks that were running at process restart are marked failed rather than resumed by the TaskStore itself.
# Read-only example: follow a task already created by an authorized operation.
import json
import time
from urllib.request import urlopen
base = "http://ROBOT_HOST:CONSOLE_PORT"
task_id = "TASK_ID"
while True:
with urlopen(f"{base}/api/tasks/{task_id}", timeout=10) as response:
task = json.load(response)
print(task)
if task["state"] != "running":
break
time.sleep(1.5)
Unknown tasks return 404. Refreshing the UI does not cancel work. Task persistence can be disabled internally if SQLite/storage setup fails; do not assume every task survives a daemon restart.
Cached status and WebSocket events
The refresh manager activates on health polling for a default ten-second window. It coalesces in-flight refreshes and returns cached values with metadata such as refreshing, updatedAt, stale and error. updatedAt in refresh metadata uses monotonic time; do not interpret it as a Unix timestamp. Failed refreshes can leave previous cached values available alongside an error.
Console /ws is an event channel, separate from Robot WebUI's command channel. Initial events include resources and services; client.ping returns server.pong. Task operations emit task.updated. Resource-specific events update the UI after refresh. Reconnect and reread tasks/resources when recovering from a dropped connection.
SDK setup, configuration and updates
Setup endpoints cover status, preflight, logs, draft storage, credential validation and installation. Installation takes a values object and is a background task. Releases can be listed and switched using version and optional configRef.
GET/POST /api/hrsdk/config reads/writes selected environment values. Runtime secrets use a separate PATCH with set dictionary and clear list; use the secret interface rather than writing credentials into public examples. Configuration pull and container updates are separate operations. Updating one container accepts its repository name; it is not the same as selecting a coherent release manifest.
Review exact release compatibility and current state before switching. Preserve configuration and selected artifact identifiers for rollback. The UI's incompatible-release disabling is useful guidance, but remote clients must still handle backend rejection.
Networking
Inspect adapters, routes, internet and connection status first. Wi-Fi operations use SSID/password for connect, SSID for forget and optional device for disconnect. Rescan is distinct from listing cached state.
Ethernet apply accepts a nested values object. It saves rollback state and returns rollbackToken plus confirmBy; the default confirmation window is 45 seconds. Confirm using POST /api/network/ethernet/confirm with { "token": "..." } after verifying connectivity. Rollback uses the corresponding rollback endpoint and token. The daemon persists rollback metadata and maintains timers. Do not confirm merely because the initial request returned successfully.
Modes include DHCP, static and robot LAN without a default route. DDS route testing is per device. Internet sharing is separate from selecting an internet interface; inspect its target and persisted state before enabling it.
Audio
Device selection, application input/output choice, volume, per-channel mapping and routing are separate APIs. Routing apply accepts physicalSink, optional connections, preset, and persist (false by default); preset apply defaults persist to true. Connections carry sourceChannel, targetChannel and gain defaulting to 100. Test tone accepts channel, optional sink, seconds defaulting to 1.0, and mode defaulting to voice.
Routing operations can run as tasks. After completion inspect device, routing and container visibility results. Persistence and host routing do not guarantee the SDK container can access the selected PulseAudio server. Reset is a state-changing routing operation, not a read-only refresh.
Servo diagnostics
Targets identify serial port, baud (default 1,000,000), family (sms_sts default) and servo ID. Scan adds ID range defaults 0–253. Register write adds address/value. Motion adds robot name/body, position and speed. Families select endianness and register maps; a wrong family can misinterpret values.
The service distinguishes read-only registers, EEPROM and SRAM, signed encoding and units. Reset neutral and register writes change hardware state. Stop conflicting SDK bus access before direct diagnostics where required by the service, and retain calibrated configuration before changing EEPROM or neutral. Use the register metadata from the selected family rather than assuming addresses are universal.
Jetson and remote support
Jetson status, restart, provision and update are separate endpoints. Provision accepts setup values; tasks can involve SSH and host changes. The UI collects a one-time SSH password for provisioning. Avoid copying it into saved examples or logs.
RustDesk status/install/password/virtual-display operations support remote desktop setup. Console update status is read separately. Configuring a remote desktop password or virtual display changes host access/display behavior; check the task result and current status after applying it.
Evidence: hr_system_console/api/system_console/{main.py,config.py,tasks.py,refresh.py,event_hub.py,setup.py,services/*} and frontend pages. No host/robot configuration changes were made to validate these APIs.
Managed-service limits and diagnostic reads
Service start/stop/restart and log access are restricted to the configured managed-unit list. An arbitrary unit name is not accepted as general shell access. Control calls use a bounded host command timeout; log reads cap requested lines to 1–500 with a default of 120. Status for unmanaged units reports allowed: false.
Some GET routes have diagnostic side effects: checkUpdates=true can contact registries, fetch=true/fetchConfigs=true can fetch Git metadata, and /api/hrsdk/servos?scan=true can schedule a hardware scan (the summary path suppresses active-SDK scans as implemented). Use scan=false for cached status. Do not classify every GET as a passive snapshot based only on its HTTP method.
For the full nested installation values, supported clean-install OS, credential allowlist/validation and secret-file semantics, see setup and credential contracts.