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
228 lines
6.5 KiB
Python
228 lines
6.5 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
from typing import Literal
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
|
|
class HealthResponse(BaseModel):
|
|
status: str
|
|
simulator_enabled: bool
|
|
version: str
|
|
|
|
|
|
class ChannelValue(BaseModel):
|
|
channel: int = Field(ge=1, le=512)
|
|
value: int = Field(ge=0, le=255)
|
|
precedence: str = "htp"
|
|
source: str = "scene"
|
|
|
|
|
|
class FixturePositionPayload(BaseModel):
|
|
x: float = Field(default=50.0, ge=0.0, le=100.0)
|
|
y: float = Field(default=50.0, ge=0.0, le=100.0)
|
|
z: float = Field(default=0.0, ge=0.0, le=100.0)
|
|
rotation: float = Field(default=0.0, ge=0.0, le=360.0)
|
|
|
|
|
|
class SceneAttributeValue(BaseModel):
|
|
attribute: str
|
|
value: int = Field(ge=0, le=255)
|
|
precedence: str | None = None
|
|
|
|
|
|
class SceneTargetPayload(BaseModel):
|
|
target_type: Literal["fixture", "group"]
|
|
patch_id: int | None = Field(default=None, ge=1)
|
|
group_name: str | None = None
|
|
values: list[SceneAttributeValue] = Field(default_factory=list)
|
|
|
|
|
|
class ScenePayload(BaseModel):
|
|
name: str
|
|
slug: str
|
|
color: str = "#00e5ff"
|
|
icon: str | None = None
|
|
priority: int = 10
|
|
fade_in_ms: int = 500
|
|
fade_out_ms: int = 500
|
|
hold_ms: int = 0
|
|
master_limit: int = 255
|
|
values: list[ChannelValue] = Field(default_factory=list)
|
|
targets: list[SceneTargetPayload] = Field(default_factory=list)
|
|
tags: list[str] = Field(default_factory=list)
|
|
|
|
|
|
class EffectPayload(BaseModel):
|
|
name: str
|
|
slug: str
|
|
effect_type: str
|
|
parameters: dict[str, object] = Field(default_factory=dict)
|
|
priority: int = 40
|
|
cooldown_ms: int = 0
|
|
|
|
|
|
class TriggerRequest(BaseModel):
|
|
model_config = ConfigDict(populate_by_name=True)
|
|
|
|
event_type: str = Field(default="custom", alias="eventType")
|
|
username: str | None = None
|
|
display_name: str | None = Field(default=None, alias="displayName")
|
|
amount: int | None = None
|
|
event_id: str | None = Field(default=None, alias="eventId")
|
|
platform: str = "twitch"
|
|
metadata: dict[str, object] = Field(default_factory=dict)
|
|
|
|
|
|
class TelemetrySnapshot(BaseModel):
|
|
uptime_seconds: float
|
|
cpu_percent: float
|
|
ram_percent: float
|
|
temperature_c: float | None = None
|
|
queue_depth: int
|
|
reconnect_count: int
|
|
last_error: str | None = None
|
|
last_sent_at: datetime | None = None
|
|
|
|
|
|
class PatchPayload(BaseModel):
|
|
universe: int = Field(default=1, ge=1, le=63999)
|
|
name: str
|
|
definition_id: int = Field(ge=1)
|
|
mode_key: str
|
|
start_address: int = Field(ge=1, le=512)
|
|
enabled: bool = True
|
|
group_names: list[str] = Field(default_factory=list)
|
|
position: FixturePositionPayload = Field(default_factory=FixturePositionPayload)
|
|
|
|
|
|
class PatchValidationPayload(BaseModel):
|
|
universe: int = Field(default=1, ge=1, le=63999)
|
|
definition_id: int = Field(ge=1)
|
|
mode_key: str
|
|
start_address: int = Field(ge=1, le=512)
|
|
enabled: bool = True
|
|
exclude_patch_id: int | None = Field(default=None, ge=1)
|
|
|
|
|
|
class ManualPatchValuesPayload(BaseModel):
|
|
values: dict[int, int] = Field(default_factory=dict)
|
|
|
|
|
|
class BpmAudioStartPayload(BaseModel):
|
|
device: str = "alsa:auto"
|
|
|
|
|
|
class BpmAudioConfigPayload(BaseModel):
|
|
preferred_device: str = "alsa:auto"
|
|
|
|
|
|
class DmxOutputConfigPayload(BaseModel):
|
|
backend: Literal["simulator", "ola", "artnet"] = "simulator"
|
|
universe: int = Field(default=1, ge=1, le=63999)
|
|
output_port: str | None = None
|
|
target_host: str | None = None
|
|
|
|
|
|
class HomeAssistantConfigPayload(BaseModel):
|
|
enabled: bool = False
|
|
base_url: str = ""
|
|
token: str | None = None
|
|
default_universe: int = Field(default=10, ge=1, le=63999)
|
|
|
|
|
|
class HomeAssistantMappingPayload(BaseModel):
|
|
name: str
|
|
universe: int = Field(default=10, ge=1, le=63999)
|
|
start_address: int = Field(ge=1, le=512)
|
|
fixture_type: Literal["dimmer", "rgb", "rgbw", "cct", "switch", "scene", "automation"] = "dimmer"
|
|
entity_id: str
|
|
rate_limit_hz: float = Field(default=5.0, ge=0.1, le=30.0)
|
|
deadband: int = Field(default=2, ge=0, le=255)
|
|
fade_ms: int = Field(default=0, ge=0, le=10000)
|
|
invert_channel: bool = False
|
|
min_value: int = Field(default=0, ge=0, le=255)
|
|
max_value: int = Field(default=255, ge=0, le=255)
|
|
enabled: bool = True
|
|
master_dimmer: bool = True
|
|
|
|
|
|
class MidiBridgeTokenCreatePayload(BaseModel):
|
|
label: str
|
|
bridge_id: str | None = None
|
|
scopes: list[str] = Field(default_factory=lambda: ["midi:connect", "midi:events", "midi:heartbeat"])
|
|
|
|
|
|
class MidiBridgeTokenResponse(BaseModel):
|
|
id: int
|
|
label: str
|
|
bridge_id: str | None
|
|
scopes: list[str]
|
|
created_at: datetime
|
|
revoked_at: datetime | None = None
|
|
last_used_at: datetime | None = None
|
|
token_preview: str
|
|
|
|
|
|
class MidiMessagePayload(BaseModel):
|
|
type: Literal["note_on", "note_off", "control_change", "program_change"]
|
|
channel: int = Field(ge=0, le=15)
|
|
number: int = Field(ge=0, le=127)
|
|
value: int = Field(ge=0, le=127)
|
|
|
|
|
|
class MidiBridgeEventPayload(BaseModel):
|
|
type: Literal["midi_event"]
|
|
protocol_version: int = Field(default=1, ge=1)
|
|
bridge_id: str
|
|
device: str
|
|
timestamp: datetime
|
|
message: MidiMessagePayload
|
|
|
|
|
|
class MidiBridgeHeartbeatPayload(BaseModel):
|
|
type: Literal["heartbeat"]
|
|
protocol_version: int = Field(default=1, ge=1)
|
|
bridge_id: str
|
|
device: str | None = None
|
|
timestamp: datetime | None = None
|
|
|
|
|
|
class MidiMappingPayload(BaseModel):
|
|
name: str
|
|
enabled: bool = True
|
|
bridge_id: str | None = None
|
|
device_name: str | None = None
|
|
message_type: Literal["note_on", "note_off", "control_change", "program_change"]
|
|
channel: int | None = Field(default=None, ge=0, le=15)
|
|
number: int = Field(ge=0, le=127)
|
|
action: Literal[
|
|
"activate_scene",
|
|
"deactivate_scene",
|
|
"toggle_scene",
|
|
"flash_scene",
|
|
"blackout_on",
|
|
"blackout_off",
|
|
"blackout_toggle",
|
|
"set_master_dimmer",
|
|
"set_scene_intensity",
|
|
"start_effect",
|
|
"stop_effect",
|
|
]
|
|
target_type: Literal["scene", "effect", "system", "global"] = "scene"
|
|
target_id: str | None = None
|
|
mode: Literal["trigger", "toggle", "hold", "flash", "continuous"] = "trigger"
|
|
minimum_value: int = Field(default=0, ge=0, le=127)
|
|
maximum_value: int = Field(default=127, ge=0, le=127)
|
|
|
|
|
|
class MidiLearnStartPayload(BaseModel):
|
|
timeout_seconds: int = Field(default=15, ge=3, le=120)
|
|
allow_passthrough: bool = False
|
|
|
|
|
|
class MidiTestMappingPayload(BaseModel):
|
|
value: int = Field(default=127, ge=0, le=127)
|
|
message_type: Literal["note_on", "note_off", "control_change", "program_change"] | None = None
|