Files
thomas 1f110866f5
CI / backend (pull_request) Canceled after 0s
CI / shell (pull_request) Canceled after 0s
CI / frontend (pull_request) Canceled after 0s
CI / arm64-smoke (pull_request) Canceled after 0s
CI / backend (push) Canceled after 0s
CI / shell (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / arm64-smoke (push) Canceled after 0s
Update docs and screenshots
2026-07-25 10:26:29 +02:00

91 lines
2.7 KiB
Python

from __future__ import annotations
import os
import socket
from dataclasses import dataclass
from pathlib import Path
from typing import Any
import yaml
@dataclass(slots=True)
class ServerConfig:
url: str
api_token: str
reconnect_seconds: float = 3.0
verify_tls: bool = True
@dataclass(slots=True)
class MidiConfig:
device_name: str
channel_filter: int | None = None
ignore_active_sensing: bool = True
@dataclass(slots=True)
class PerformanceConfig:
control_change_interval_ms: int = 25
suppress_duplicate_values: bool = True
@dataclass(slots=True)
class LoggingConfig:
level: str = "INFO"
show_midi_events: bool = True
@dataclass(slots=True)
class BridgeConfig:
bridge_id: str
server: ServerConfig
midi: MidiConfig
performance: PerformanceConfig
logging: LoggingConfig
def load_config(path: str | Path) -> BridgeConfig:
config_path = Path(path)
raw = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {}
if not isinstance(raw, dict):
raise ValueError("Konfigurationsfilen skal være YAML med topniveau som objekt.")
server_data = raw.get("server") or {}
midi_data = raw.get("midi") or {}
performance_data = raw.get("performance") or {}
logging_data = raw.get("logging") or {}
env_token = os.getenv("TUXDMX_API_TOKEN", "").strip()
api_token = env_token or str(server_data.get("api_token", "")).strip()
if not api_token:
raise ValueError("API-token mangler. Angiv det i YAML eller via TUXDMX_API_TOKEN.")
return BridgeConfig(
bridge_id=str(raw.get("bridge_id") or socket.gethostname()).strip(),
server=ServerConfig(
url=str(server_data.get("url", "")).rstrip("/"),
api_token=api_token,
reconnect_seconds=float(server_data.get("reconnect_seconds", 3)),
verify_tls=bool(server_data.get("verify_tls", True)),
),
midi=MidiConfig(
device_name=str(midi_data.get("device_name", "")).strip(),
channel_filter=_optional_int(midi_data.get("channel_filter")),
ignore_active_sensing=bool(midi_data.get("ignore_active_sensing", True)),
),
performance=PerformanceConfig(
control_change_interval_ms=int(performance_data.get("control_change_interval_ms", 25)),
suppress_duplicate_values=bool(performance_data.get("suppress_duplicate_values", True)),
),
logging=LoggingConfig(
level=str(logging_data.get("level", "INFO")).upper(),
show_midi_events=bool(logging_data.get("show_midi_events", True)),
),
)
def _optional_int(value: Any) -> int | None:
if value in {None, "", "null"}:
return None
return int(value)