Files
RFP_Infinity-Vis/app/config/models.py

122 lines
3.0 KiB
Python

from __future__ import annotations
from dataclasses import dataclass, field
from pathlib import Path
from typing import Iterable
import copy
@dataclass
class CompositionInfo:
width: int = 1200
height: int = 600
@dataclass
class SourceInfo:
original_export: str = ""
derived_from: str = ""
composition: CompositionInfo = field(default_factory=CompositionInfo)
@dataclass
class LogicalDisplayConfig:
rows: int = 3
cols: int = 6
preview_width: int = 1200
preview_height: int = 600
tile_width: int = 200
tile_height: int = 200
@dataclass
class DefaultsConfig:
protocol: str = "artnet"
subnet: int = 0
color_format: str = "rgb"
tile_behavior: str = "solid_color_per_tile"
global_gamma: float = 2.2
@dataclass
class CalibrationConfig:
brightness: float = 1.0
red_gain: float = 1.0
green_gain: float = 1.0
blue_gain: float = 1.0
@dataclass
class SegmentConfig:
name: str
side: str
start_channel: int
led_count: int
orientation_rad: float = 0.0
x0: float = 0.0
y0: float = 0.0
x1: float = 0.0
y1: float = 0.0
reverse: bool = False
@dataclass
class TileConfig:
tile_id: str
row: int
col: int
screen_name: str = ""
controller_ip: str = ""
controller_host: str = ""
controller_name: str = ""
controller_mac: str = ""
universe: int = 0
subnet: int = 0
led_total: int = 0
x0: float = 0.0
y0: float = 0.0
x1: float = 0.0
y1: float = 0.0
enabled: bool = True
calibration: CalibrationConfig = field(default_factory=CalibrationConfig)
segments: list[SegmentConfig] = field(default_factory=list)
@property
def brightness_factor(self) -> float:
return self.calibration.brightness
@brightness_factor.setter
def brightness_factor(self, value: float) -> None:
self.calibration.brightness = value
@dataclass
class InfinityMirrorConfig:
name: str = "Infinity Mirror"
version: str = "1.0"
source: SourceInfo = field(default_factory=SourceInfo)
logical_display: LogicalDisplayConfig = field(default_factory=LogicalDisplayConfig)
defaults: DefaultsConfig = field(default_factory=DefaultsConfig)
tiles: list[TileConfig] = field(default_factory=list)
file_path: Path | None = None
def clone(self) -> "InfinityMirrorConfig":
return copy.deepcopy(self)
def sorted_tiles(self) -> list[TileConfig]:
return sorted(self.tiles, key=lambda tile: (tile.row, tile.col, tile.tile_id))
def tile_lookup(self) -> dict[str, TileConfig]:
return {tile.tile_id: tile for tile in self.tiles}
def tile_at(self, row: int, col: int) -> TileConfig | None:
for tile in self.tiles:
if tile.row == row and tile.col == col:
return tile
return None
def all_segments(self) -> Iterable[tuple[TileConfig, SegmentConfig]]:
for tile in self.sorted_tiles():
for segment in tile.segments:
yield tile, segment