"""Value source schemas (CRUD).""" from datetime import datetime from typing import List, Literal, Optional from pydantic import BaseModel, Field class ValueSourceCreate(BaseModel): """Request to create a value source.""" name: str = Field(description="Source name", min_length=1, max_length=100) source_type: Literal["static", "animated", "audio", "adaptive_time", "adaptive_scene"] = Field(description="Source type") # static fields value: Optional[float] = Field(None, description="Constant value (0.0-1.0)", ge=0.0, le=1.0) # animated fields waveform: Optional[str] = Field(None, description="Waveform: sine|triangle|square|sawtooth") speed: Optional[float] = Field(None, description="Cycles per minute (1.0-120.0)", ge=1.0, le=120.0) min_value: Optional[float] = Field(None, description="Minimum output (0.0-1.0)", ge=0.0, le=1.0) max_value: Optional[float] = Field(None, description="Maximum output (0.0-1.0)", ge=0.0, le=1.0) # audio fields audio_source_id: Optional[str] = Field(None, description="Mono audio source ID") mode: Optional[str] = Field(None, description="Audio mode: rms|peak|beat") sensitivity: Optional[float] = Field(None, description="Gain multiplier (0.1-5.0)", ge=0.1, le=5.0) smoothing: Optional[float] = Field(None, description="Temporal smoothing (0.0-1.0)", ge=0.0, le=1.0) # adaptive fields schedule: Optional[list] = Field(None, description="Time-of-day schedule: [{time: 'HH:MM', value: 0.0-1.0}]") picture_source_id: Optional[str] = Field(None, description="Picture source ID for scene mode") scene_behavior: Optional[str] = Field(None, description="Scene behavior: complement|match") description: Optional[str] = Field(None, description="Optional description", max_length=500) class ValueSourceUpdate(BaseModel): """Request to update a value source.""" name: Optional[str] = Field(None, description="Source name", min_length=1, max_length=100) # static fields value: Optional[float] = Field(None, description="Constant value (0.0-1.0)", ge=0.0, le=1.0) # animated fields waveform: Optional[str] = Field(None, description="Waveform: sine|triangle|square|sawtooth") speed: Optional[float] = Field(None, description="Cycles per minute (1.0-120.0)", ge=1.0, le=120.0) min_value: Optional[float] = Field(None, description="Minimum output (0.0-1.0)", ge=0.0, le=1.0) max_value: Optional[float] = Field(None, description="Maximum output (0.0-1.0)", ge=0.0, le=1.0) # audio fields audio_source_id: Optional[str] = Field(None, description="Mono audio source ID") mode: Optional[str] = Field(None, description="Audio mode: rms|peak|beat") sensitivity: Optional[float] = Field(None, description="Gain multiplier (0.1-5.0)", ge=0.1, le=5.0) smoothing: Optional[float] = Field(None, description="Temporal smoothing (0.0-1.0)", ge=0.0, le=1.0) # adaptive fields schedule: Optional[list] = Field(None, description="Time-of-day schedule") picture_source_id: Optional[str] = Field(None, description="Picture source ID for scene mode") scene_behavior: Optional[str] = Field(None, description="Scene behavior: complement|match") description: Optional[str] = Field(None, description="Optional description", max_length=500) class ValueSourceResponse(BaseModel): """Value source response.""" id: str = Field(description="Source ID") name: str = Field(description="Source name") source_type: str = Field(description="Source type: static, animated, audio, adaptive_time, or adaptive_scene") value: Optional[float] = Field(None, description="Static value") waveform: Optional[str] = Field(None, description="Waveform type") speed: Optional[float] = Field(None, description="Cycles per minute") min_value: Optional[float] = Field(None, description="Minimum output") max_value: Optional[float] = Field(None, description="Maximum output") audio_source_id: Optional[str] = Field(None, description="Mono audio source ID") mode: Optional[str] = Field(None, description="Audio mode") sensitivity: Optional[float] = Field(None, description="Gain multiplier") smoothing: Optional[float] = Field(None, description="Temporal smoothing") schedule: Optional[list] = Field(None, description="Time-of-day schedule") picture_source_id: Optional[str] = Field(None, description="Picture source ID") scene_behavior: Optional[str] = Field(None, description="Scene behavior") description: Optional[str] = Field(None, description="Description") created_at: datetime = Field(description="Creation timestamp") updated_at: datetime = Field(description="Last update timestamp") class ValueSourceListResponse(BaseModel): """List of value sources.""" sources: List[ValueSourceResponse] = Field(description="List of value sources") count: int = Field(description="Number of sources")