Files
Infinity_Vis_Rust/docs/host_api.md
JFly02 8e19f535ae Die gemeinsame Plattform ist jetzt softwareseitig deutlich vollständiger. Der Host-Core hat mit [show_store.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host/src/show_store.rs>) eine echte Runtime-Bibliothek und Persistenz für aktive Szene, Runtime-Presets, Runtime-Gruppen und kreative Varianten bekommen; die Simulation in [simulation.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host/src/simulation.rs>) liefert jetzt typisierte Command-Ergebnisse, saubere Fehlercodes und persistiert nach data/runtime_state.json. Dazu kommt das generische External-Show-Control-Interface in [external_control.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host/src/external_control.rs>), damit spätere Adapter nur auf definierte Commands und Snapshot-/Preset-/Parameter-Flächen zugreifen.
Die API v1 ist als Produktgrenze geschärft in [dto.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/src/dto.rs>) und [server.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/src/server.rs>): getrennte Modelle für `state`, `preview`, `snapshot`, `command response`, `event stream` und stabile Fehlerobjekte mit echten Codes statt generischem Fallback. Dazu kamen `GET /api/v1/state` und `GET /api/v1/preview`, neue persistenzbezogene Commands wie `save_preset`, `save_creative_snapshot`, `recall_creative_snapshot`, `set_transition_style` und `upsert_group`, plus serverseitige Durchreichung der echten Fehlercodes. Die kreative Web-UI in [index.html](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/web/v1/index.html>), [app.js](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/web/v1/app.js>) und [styles.css](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/web/v1/styles.css>) nutzt jetzt genau diese API für Preset-Speichern/Überschreiben, Varianten, Transition-Style, filterbaren Eventfeed und klarere Preview-Darstellung, ohne Parallelarchitektur.

Die Doku ist auf den neuen Stand gezogen in [docs/host_api.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/docs/host_api.md>), [README.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/README.md>), [docs/build_and_deploy.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/docs/build_and_deploy.md>) und [docs/architecture.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/docs/architecture.md>). Verifiziert habe ich `cargo check -q` und `cargo test -q`; dabei laufen die erweiterten Contract- und Persistenztests in [contract.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/tests/contract.rs>) sowie neue Core-Tests in [show_store.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host/src/show_store.rs>) und [simulation.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host/src/simulation.rs>). Nicht separat verifiziert habe ich einen echten Browserlauf der Web-UI; die JS-Datei wurde hier nicht mit `node` geprüft, weil `node` in dieser Umgebung nicht installiert ist.
2026-04-17 12:34:03 +02:00

8.5 KiB

Host API

Purpose

The host API is the stable external product boundary for:

  • the creative web UI
  • the native engineering GUI
  • future remote operator clients
  • later external show-control adapters such as a grandMA bridge

The realtime rule remains strict:

  • the API is a control and observation layer
  • the host core remains the timing authority
  • no frontend or external adapter is allowed to become the LED clock

Runtime Components

Core and API implementation:

  • crates/infinity_host/src/control.rs
  • crates/infinity_host/src/scene.rs
  • crates/infinity_host/src/show_store.rs
  • crates/infinity_host/src/simulation.rs
  • crates/infinity_host/src/external_control.rs
  • crates/infinity_host_api/src/dto.rs
  • crates/infinity_host_api/src/server.rs

Server startup:

cargo run -p infinity_host_api -- --config config/project.example.toml --bind 127.0.0.1:9001 --runtime-state data/runtime_state.json

Creative web UI V1 is served by the same process:

http://127.0.0.1:9001/

Versioning Policy

The current public contract is v1.

Rules:

  • all public HTTP and WebSocket routes are namespaced under /api/v1
  • every response body carries api_version: "v1"
  • additive fields are allowed inside v1
  • semantic breaking changes require a new version namespace
  • external consumers must treat undocumented internal-only fields as unstable and ignore them

Stable External Models

Stable external response families:

  • command response
  • state snapshot
  • preview snapshot
  • combined snapshot
  • catalog
  • event stream
  • typed error object

Stable external command families:

  • global control
  • pattern and preset selection
  • group targeting
  • scene parameter updates
  • transition configuration
  • preset persistence
  • creative snapshot persistence and recall
  • panel test trigger

Internal Versus External Fields

External and stable in v1:

  • every field defined in crates/infinity_host_api/src/dto.rs
  • route names and payload shapes documented below
  • error object shape { api_version, error: { code, message } }
  • event stream envelope shape { api_version, sequence, generated_at_millis, message }

Internal and not part of the API contract:

  • the exact shape of HostSnapshot in crates/infinity_host/src/control.rs
  • simulation-only storage layout in data/runtime_state.json
  • internal event history buffering size
  • internal scene library structures in show_store.rs
  • engineering-GUI-specific rendering or polling behavior

HTTP Endpoints

GET /api/v1/state

Returns only the stable state snapshot.

Example:

{
  "api_version": "v1",
  "generated_at_millis": 512,
  "state": {
    "system": {
      "project_name": "Infinity Vis",
      "schema_version": 1,
      "topology_label": "6 nodes / 18 outputs / 106 LEDs"
    },
    "global": {
      "blackout": false,
      "master_brightness": 0.2,
      "selected_pattern": "gradient",
      "selected_group": "top_panels",
      "transition_duration_ms": 320,
      "transition_style": "chase"
    },
    "engine": {
      "logic_hz": 120,
      "frame_hz": 60,
      "preview_hz": 15,
      "uptime_ms": 512,
      "frame_index": 30,
      "dropped_frames": 0,
      "active_transition": {
        "style": "chase",
        "from_pattern_id": "solid_color",
        "to_pattern_id": "gradient",
        "duration_ms": 320,
        "progress": 0.28
      }
    }
  }
}

GET /api/v1/preview

Returns only the stable preview snapshot.

Example:

{
  "api_version": "v1",
  "generated_at_millis": 512,
  "preview": {
    "generated_at_millis": 512,
    "panels": [
      {
        "node_id": "node-01",
        "panel_position": "top",
        "representative_color_hex": "#FF8A5B",
        "sample_led_hex": [
          "#FF8A5B",
          "#F36E43",
          "#D85A2F"
        ],
        "energy_percent": 47,
        "source": "transition"
      }
    ]
  }
}

GET /api/v1/snapshot

Returns the convenience composition of state plus preview.

This route exists for lightweight clients and debugging. Consumers that want strict separation should prefer GET /api/v1/state and GET /api/v1/preview.

GET /api/v1/catalog

Returns the stable creative library:

  • patterns
  • presets
  • groups
  • creative snapshots

Example preset summary:

{
  "preset_id": "ocean_gradient",
  "pattern_id": "gradient",
  "target_group": null,
  "transition_duration_ms": 320,
  "transition_style": "crossfade",
  "source": "built_in"
}

Example creative snapshot summary:

{
  "snapshot_id": "variant_floor",
  "label": "Variant Floor",
  "pattern_id": "noise",
  "target_group": "bottom_panels",
  "transition_duration_ms": 220,
  "transition_style": "chase",
  "saved_at_unix_ms": 1760000000000
}

GET /api/v1/presets

Returns only preset summaries.

GET /api/v1/groups

Returns only group summaries.

POST /api/v1/command

Accepts one versioned command envelope.

Example request:

{
  "request_id": "web-1713352662000",
  "command": {
    "type": "save_creative_snapshot",
    "payload": {
      "snapshot_id": "variant_floor",
      "label": "Variant Floor",
      "overwrite": false
    }
  }
}

Example response:

{
  "api_version": "v1",
  "accepted": true,
  "request_id": "web-1713352662000",
  "generated_at_millis": 522,
  "command_type": "save_creative_snapshot",
  "summary": "creative snapshot saved: variant_floor"
}

Stable Error Object

All API failures return:

{
  "api_version": "v1",
  "error": {
    "code": "unknown_creative_snapshot",
    "message": "creative snapshot 'does_not_exist' does not exist"
  }
}

Stable v1 error families currently include:

  • invalid_request_json
  • invalid_command
  • unknown_group
  • unknown_preset
  • unknown_creative_snapshot
  • preset_exists
  • snapshot_exists
  • group_exists
  • persist_failed
  • missing_websocket_key
  • not_found

WebSocket Event Stream

WS /api/v1/stream

The stream emits a typed envelope with a monotonic sequence counter:

{
  "api_version": "v1",
  "sequence": 19,
  "generated_at_millis": 880,
  "message": {
    "type": "event",
    "payload": {
      "kind": "warning",
      "code": "unknown_creative_snapshot",
      "message": "creative snapshot 'does_not_exist' does not exist"
    }
  }
}

Stable message types:

  • snapshot
  • preview
  • event

Stable event kinds:

  • info
  • warning
  • error

Guaranteed Commands In v1

Guaranteed control commands:

  • set_blackout
  • set_master_brightness
  • select_pattern
  • recall_preset
  • select_group
  • set_scene_parameter
  • set_transition_duration_ms
  • set_transition_style
  • trigger_panel_test

Guaranteed persistence and creative-library commands:

  • save_preset
  • save_creative_snapshot
  • recall_creative_snapshot
  • upsert_group

Persistence Behavior

The simulation-backed host service now persists runtime-facing creative data to data/runtime_state.json by default.

Persisted data includes:

  • active scene
  • global blackout and brightness state
  • transition duration and style
  • runtime user presets
  • runtime user groups
  • creative snapshots and variants

This persistence file is an internal runtime artifact, not the public API contract.

External Show Control Adapter Boundary

The generic internal adapter surface lives in:

  • crates/infinity_host/src/external_control.rs

Key rule:

  • future adapters may only translate external intent into the defined host command surface
  • they must not reach into simulation internals, UI state, or hardware driver details directly

Contract And Integration Coverage

Current software-side hardening lives in:

  • crates/infinity_host_api/tests/contract.rs
  • crates/infinity_host/src/show_store.rs tests
  • crates/infinity_host/src/simulation.rs tests

Covered flows include:

  • state, preview, snapshot, catalog, presets, and groups endpoints
  • command success and typed command failure
  • WebSocket snapshot, preview, and event messages
  • group targeting
  • parameter updates
  • transition configuration
  • blackout
  • preset save
  • creative snapshot save and recall
  • persistence across restart
  • a longer ignored load-oriented sequence for platform hardening

Web UI Scope

The current web UI intentionally focuses on creative use:

  • pattern and preset selection
  • group targeting
  • transition configuration
  • scene parameters
  • preset save and overwrite
  • creative snapshot save and recall
  • preview
  • raw snapshot display
  • filterable event feed

Mapping, topology diagnostics, panel-test administration, and low-level node status remain primarily in the native engineering GUI.