Update docs and screenshots
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
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
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user