| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- # -*- coding: utf-8 -*-
- """
- LED Layout-Definitionen.
- Definiert verschiedene physische LED-Anordnungen (Single, Jewel, Ring)
- und stellt eine automatische Layout-Erkennung bereit.
- """
- from __future__ import annotations
- from dataclasses import dataclass, field
- from trixy_core.utils.debug import pdebug, pwarn
- @dataclass
- class LEDLayout:
- """Layout-Definition fuer eine LED-Anordnung.
- Beschreibt die physische Anordnung der LEDs, insbesondere
- welche LEDs zum Ring gehoeren und ob eine Center-LED existiert.
- Attributes:
- name: Bezeichnung des Layouts (z.B. "single", "jewel_7", "ring_12").
- led_count: Gesamtanzahl der LEDs.
- center_index: Index der Center-LED (None wenn keine vorhanden).
- ring_indices: Indizes der Ring-LEDs in Reihenfolge.
- """
- name: str
- led_count: int
- center_index: int | None = None
- ring_indices: list[int] = field(default_factory=list)
- @property
- def has_center(self) -> bool:
- """Prueft ob das Layout eine Center-LED hat."""
- return self.center_index is not None
- @property
- def ring_count(self) -> int:
- """Anzahl der Ring-LEDs."""
- return len(self.ring_indices)
- # ── Vordefinierte Layouts ──────────────────────────────────────────────
- LAYOUT_SINGLE = LEDLayout(
- name="single",
- led_count=1,
- center_index=None,
- ring_indices=[0],
- )
- LAYOUT_JEWEL_7 = LEDLayout(
- name="jewel_7",
- led_count=7,
- center_index=0,
- ring_indices=[1, 2, 3, 4, 5, 6],
- )
- LAYOUT_RING_12 = LEDLayout(
- name="ring_12",
- led_count=12,
- center_index=None,
- ring_indices=list(range(12)),
- )
- LAYOUT_RING_16 = LEDLayout(
- name="ring_16",
- led_count=16,
- center_index=None,
- ring_indices=list(range(16)),
- )
- LAYOUT_RING_24 = LEDLayout(
- name="ring_24",
- led_count=24,
- center_index=None,
- ring_indices=list(range(24)),
- )
- # Lookup-Tabelle: Name → Layout
- LAYOUTS: dict[str, LEDLayout] = {
- "single": LAYOUT_SINGLE,
- "jewel_7": LAYOUT_JEWEL_7,
- "ring_12": LAYOUT_RING_12,
- "ring_16": LAYOUT_RING_16,
- "ring_24": LAYOUT_RING_24,
- }
- # Auto-Detect: LED-Anzahl → Layout-Name (fuer gaengige Konfigurationen)
- _COUNT_TO_LAYOUT: dict[int, str] = {
- 1: "single",
- 7: "jewel_7",
- 12: "ring_12",
- 16: "ring_16",
- 24: "ring_24",
- }
- def get_layout(type_name: str, led_count: int) -> LEDLayout:
- """Gibt passendes Layout zurueck oder erkennt es automatisch.
- Sucht zuerst nach dem angegebenen Layout-Namen. Falls kein Name
- angegeben oder nicht gefunden, wird anhand der LED-Anzahl ein
- passendes Layout gewaehlt. Als Fallback wird ein generisches
- Ring-Layout erzeugt.
- Args:
- type_name: Gewuenschter Layout-Name (z.B. "jewel_7").
- Leerer String fuer Auto-Erkennung.
- led_count: Anzahl der LEDs.
- Returns:
- Passendes LEDLayout fuer die Konfiguration.
- """
- # Expliziter Layout-Name angegeben
- if type_name and type_name in LAYOUTS:
- layout = LAYOUTS[type_name]
- if layout.led_count != led_count:
- pwarn(
- f"LED-Layout '{type_name}' erwartet {layout.led_count} LEDs, "
- f"aber {led_count} konfiguriert — verwende Layout trotzdem"
- )
- pdebug(f"LED-Layout '{type_name}' geladen ({layout.led_count} LEDs)")
- return layout
- # Warnung wenn unbekannter Name angegeben
- if type_name:
- pwarn(
- f"Unbekanntes LED-Layout '{type_name}' — versuche Auto-Erkennung"
- )
- # Auto-Erkennung anhand LED-Anzahl
- if led_count in _COUNT_TO_LAYOUT:
- auto_name = _COUNT_TO_LAYOUT[led_count]
- layout = LAYOUTS[auto_name]
- pdebug(
- f"LED-Layout automatisch erkannt: '{auto_name}' ({led_count} LEDs)"
- )
- return layout
- # Fallback: Generisches Ring-Layout
- pdebug(
- f"Kein vordefiniertes Layout fuer {led_count} LEDs — "
- f"erzeuge generisches Ring-Layout"
- )
- return LEDLayout(
- name=f"ring_{led_count}",
- led_count=led_count,
- center_index=None,
- ring_indices=list(range(led_count)),
- )
|