Add audio sources as first-class entities, add mapped CSS type, simplify target editor for mapped sources
- Audio sources moved to separate tab with dedicated CRUD API, store, and editor modal - New "mapped" color strip source type: assigns different CSS sources to distinct LED sub-ranges (zones) - Mapped stream runtime with per-zone sub-streams, auto-sizing, hot-update support - Target editor auto-collapses segments UI when mapped CSS is selected - Delete protection for CSS sources referenced by mapped zones - Compact header/footer layout Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
53
server/src/wled_controller/api/schemas/audio_sources.py
Normal file
53
server/src/wled_controller/api/schemas/audio_sources.py
Normal file
@@ -0,0 +1,53 @@
|
||||
"""Audio source schemas (CRUD)."""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import List, Literal, Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class AudioSourceCreate(BaseModel):
|
||||
"""Request to create an audio source."""
|
||||
|
||||
name: str = Field(description="Source name", min_length=1, max_length=100)
|
||||
source_type: Literal["multichannel", "mono"] = Field(description="Source type")
|
||||
# multichannel fields
|
||||
device_index: Optional[int] = Field(None, description="Audio device index (-1 = default)")
|
||||
is_loopback: Optional[bool] = Field(None, description="True for system audio (WASAPI loopback)")
|
||||
# mono fields
|
||||
audio_source_id: Optional[str] = Field(None, description="Parent multichannel audio source ID")
|
||||
channel: Optional[str] = Field(None, description="Channel: mono|left|right")
|
||||
description: Optional[str] = Field(None, description="Optional description", max_length=500)
|
||||
|
||||
|
||||
class AudioSourceUpdate(BaseModel):
|
||||
"""Request to update an audio source."""
|
||||
|
||||
name: Optional[str] = Field(None, description="Source name", min_length=1, max_length=100)
|
||||
device_index: Optional[int] = Field(None, description="Audio device index (-1 = default)")
|
||||
is_loopback: Optional[bool] = Field(None, description="True for system audio (WASAPI loopback)")
|
||||
audio_source_id: Optional[str] = Field(None, description="Parent multichannel audio source ID")
|
||||
channel: Optional[str] = Field(None, description="Channel: mono|left|right")
|
||||
description: Optional[str] = Field(None, description="Optional description", max_length=500)
|
||||
|
||||
|
||||
class AudioSourceResponse(BaseModel):
|
||||
"""Audio source response."""
|
||||
|
||||
id: str = Field(description="Source ID")
|
||||
name: str = Field(description="Source name")
|
||||
source_type: str = Field(description="Source type: multichannel or mono")
|
||||
device_index: Optional[int] = Field(None, description="Audio device index")
|
||||
is_loopback: Optional[bool] = Field(None, description="WASAPI loopback mode")
|
||||
audio_source_id: Optional[str] = Field(None, description="Parent multichannel source ID")
|
||||
channel: Optional[str] = Field(None, description="Channel: mono|left|right")
|
||||
description: Optional[str] = Field(None, description="Description")
|
||||
created_at: datetime = Field(description="Creation timestamp")
|
||||
updated_at: datetime = Field(description="Last update timestamp")
|
||||
|
||||
|
||||
class AudioSourceListResponse(BaseModel):
|
||||
"""List of audio sources."""
|
||||
|
||||
sources: List[AudioSourceResponse] = Field(description="List of audio sources")
|
||||
count: int = Field(description="Number of sources")
|
||||
Reference in New Issue
Block a user