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
91 lines
2.7 KiB
Python
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)
|