Files
Infinity_Vis_Rust/docs/host_api.md
JFly02 a37a3c5cbe Der nächste Layer ist jetzt als echte gemeinsame Außenkante umgesetzt. Das neue API-Crate in [server.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/src/server.rs>), [dto.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/src/dto.rs>) und [main.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/src/main.rs>) stellt die geforderten versionierten Endpunkte bereit: GET /api/v1/snapshot, GET /api/v1/catalog, GET /api/v1/presets, GET /api/v1/groups, POST /api/v1/command und WS /api/v1/stream. Die API trennt jetzt sauber zwischen Command-, State-, Preview- und Event-Modell, inklusive stabiler Außen-Enums und dokumentierten Fehlerobjekten statt eines unreflektierten 1:1-Core-Leaks.
Darauf sitzt die erste Web-UI V1 direkt gegen diese API 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>). Sie enthält Pattern-/Preset-Auswahl, globale Regler, Gruppenauswahl, Übergänge, Preview, Snapshot-Anzeige und Event-Feed. Die technische Desktop-GUI bleibt bewusst die Engineering-/Diagnoseoberfläche; die kreative Web-UI baut nicht an einer Parallelarchitektur vorbei.

Contract-Tests liegen in [contract.rs](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/crates/infinity_host_api/tests/contract.rs>), und die API ist mit Beispiel-Responses in [docs/host_api.md](</C:/Users/janni/Documents/RFP/Infinity_Vis _Rust/docs/host_api.md>) dokumentiert. Zusätzlich habe ich [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>) auf den neuen Stand gebracht.

Verifiziert habe ich:
- `cargo check -p infinity_host_api`
- `cargo test -p infinity_host_api`
- `cargo test -q`

Nicht verifiziert habe ich eine separate JS-Syntaxprüfung mit `node --check`, weil `node` in dieser Umgebung nicht installiert ist.
2026-04-17 11:58:07 +02:00

6.2 KiB

Host API

Purpose

The host API is the stable external boundary for:

  • the creative web UI
  • the existing engineering GUI
  • future external show-control adapters such as grandMA

The core rule stays unchanged:

  • the API is a control and observation layer
  • the realtime engine remains the timing authority
  • no surface is allowed to become the LED clock

Current Implementation

Runtime pieces:

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

The network-facing server is started with:

cargo run -p infinity_host_api -- --config config/project.example.toml --bind 127.0.0.1:9001

Creative web UI V1 is served by the same process at:

http://127.0.0.1:9001/

Versioning

  • HTTP and WebSocket routes are versioned under /api/v1
  • responses include api_version: "v1"
  • the external DTOs are intentionally not a direct 1:1 dump of internal core structs

Endpoint Contract

GET /api/v1/snapshot

Returns the current state and preview in one response.

Example:

{
  "api_version": "v1",
  "generated_at_millis": 241,
  "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": "solid_color",
      "selected_group": null,
      "transition_duration_ms": 150
    },
    "engine": {
      "logic_hz": 120,
      "frame_hz": 60,
      "preview_hz": 15,
      "uptime_ms": 241,
      "frame_index": 14,
      "dropped_frames": 0,
      "active_transition": null
    },
    "active_scene": {
      "preset_id": null,
      "pattern_id": "solid_color",
      "seed": 100,
      "palette": [
        "#ffffff"
      ],
      "parameters": [],
      "target_group": null,
      "blackout": false
    }
  },
  "preview": {
    "generated_at_millis": 241,
    "panels": [
      {
        "node_id": "node-01",
        "panel_position": "top",
        "representative_color_hex": "#33CCFF",
        "sample_led_hex": [
          "#33CCFF",
          "#28A3CC",
          "#1E7A99"
        ],
        "energy_percent": 28,
        "source": "scene"
      }
    ]
  }
}

GET /api/v1/catalog

Returns the creative catalog:

  • patterns
  • presets
  • groups

GET /api/v1/presets

Returns only preset summaries.

Example:

{
  "api_version": "v1",
  "presets": [
    {
      "preset_id": "ocean_gradient",
      "pattern_id": "gradient",
      "target_group": null,
      "transition_duration_ms": 320
    }
  ]
}

GET /api/v1/groups

Returns only group summaries.

Example:

{
  "api_version": "v1",
  "groups": [
    {
      "group_id": "top_panels",
      "member_count": 6,
      "tags": [
        "row",
        "top"
      ]
    }
  ]
}

POST /api/v1/command

Accepts a versioned command envelope.

Example request:

{
  "request_id": "web-1713352662000",
  "command": {
    "type": "set_master_brightness",
    "payload": {
      "value": 0.42
    }
  }
}

Example response:

{
  "api_version": "v1",
  "accepted": true,
  "request_id": "web-1713352662000",
  "generated_at_millis": 522,
  "summary": "master brightness set to 42%"
}

Errors use a stable error object:

{
  "api_version": "v1",
  "error": {
    "code": "invalid_command",
    "message": "command request was rejected: missing field `enabled`"
  }
}

WS /api/v1/stream

The WebSocket stream emits envelopes with a monotonic sequence and a typed payload.

Stream message types:

  • snapshot
  • preview
  • event

Example snapshot envelope:

{
  "api_version": "v1",
  "sequence": 17,
  "generated_at_millis": 875,
  "message": {
    "type": "snapshot",
    "payload": {
      "global": {
        "blackout": false,
        "master_brightness": 0.35,
        "selected_pattern": "gradient",
        "selected_group": "top_panels",
        "transition_duration_ms": 320
      }
    }
  }
}

Example preview envelope:

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

Example event envelope:

{
  "api_version": "v1",
  "sequence": 19,
  "generated_at_millis": 880,
  "message": {
    "type": "event",
    "payload": {
      "kind": "info",
      "message": "preset recalled: ocean_gradient"
    }
  }
}

Supported Commands

The current API command set covers:

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

This is intentionally enough for:

  • creative look development in the web UI
  • engineering test triggers in the native GUI
  • future external show-control translation layers

Web UI V1

The first creative web UI is intentionally limited to:

  • pattern selection
  • preset recall
  • group selection
  • global brightness
  • blackout
  • transition duration
  • scene parameter controls driven from the API schema
  • panel preview
  • snapshot display
  • event feed

It does not absorb mapping, topology, or hardware-diagnostic workflows. Those stay in the native engineering UI.

Contract Tests

The API contract is currently verified in:

  • crates/infinity_host_api/tests/contract.rs

Covered paths:

  • root web shell
  • GET /api/v1/snapshot
  • GET /api/v1/catalog
  • GET /api/v1/presets
  • GET /api/v1/groups
  • POST /api/v1/command
  • WS /api/v1/stream

Future Direction

Next adapters should be built on this boundary instead of reaching into the host core directly.

That includes:

  • a richer web authoring surface
  • remote operator clients
  • a grandMA bridge that translates external show control into host API commands