led_interface.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. """
  2. Unified LED interface for different LED control systems
  3. Provides a common abstraction layer for pattern manager integration.
  4. """
  5. from typing import Optional, Literal
  6. from modules.led.led_controller import LEDController, effect_loading as wled_loading, effect_idle as wled_idle, effect_connected as wled_connected, effect_playing as wled_playing
  7. from modules.led.dw_led_controller import DWLEDController, effect_loading as dw_led_loading, effect_idle as dw_led_idle, effect_connected as dw_led_connected, effect_playing as dw_led_playing
  8. LEDProviderType = Literal["wled", "dw_leds", "none"]
  9. class LEDInterface:
  10. """
  11. Unified interface for LED control that works with multiple backends.
  12. Automatically delegates to the appropriate controller based on configuration.
  13. """
  14. def __init__(self, provider: LEDProviderType = "none", ip_address: Optional[str] = None,
  15. num_leds: Optional[int] = None, gpio_pin: Optional[int] = None, pixel_order: Optional[str] = None,
  16. brightness: Optional[float] = None, speed: Optional[int] = None, intensity: Optional[int] = None):
  17. self.provider = provider
  18. self._controller = None
  19. if provider == "wled" and ip_address:
  20. self._controller = LEDController(ip_address)
  21. elif provider == "dw_leds":
  22. # DW LEDs uses local GPIO, no IP needed
  23. num_leds = num_leds or 60
  24. gpio_pin = gpio_pin or 12
  25. pixel_order = pixel_order or "GRB"
  26. brightness = brightness if brightness is not None else 0.35
  27. speed = speed if speed is not None else 128
  28. intensity = intensity if intensity is not None else 128
  29. self._controller = DWLEDController(num_leds, gpio_pin, brightness, pixel_order=pixel_order, speed=speed, intensity=intensity)
  30. @property
  31. def is_configured(self) -> bool:
  32. """Check if LED controller is configured"""
  33. return self._controller is not None
  34. def update_config(self, provider: LEDProviderType, ip_address: Optional[str] = None,
  35. num_leds: Optional[int] = None, gpio_pin: Optional[int] = None, pixel_order: Optional[str] = None,
  36. brightness: Optional[float] = None, speed: Optional[int] = None, intensity: Optional[int] = None):
  37. """Update LED provider configuration"""
  38. self.provider = provider
  39. # Stop existing controller if switching providers
  40. if self._controller and hasattr(self._controller, 'stop'):
  41. try:
  42. self._controller.stop()
  43. except:
  44. pass
  45. if provider == "wled" and ip_address:
  46. self._controller = LEDController(ip_address)
  47. elif provider == "dw_leds":
  48. num_leds = num_leds or 60
  49. gpio_pin = gpio_pin or 12
  50. pixel_order = pixel_order or "GRB"
  51. brightness = brightness if brightness is not None else 0.35
  52. speed = speed if speed is not None else 128
  53. intensity = intensity if intensity is not None else 128
  54. self._controller = DWLEDController(num_leds, gpio_pin, brightness, pixel_order=pixel_order, speed=speed, intensity=intensity)
  55. else:
  56. self._controller = None
  57. def effect_loading(self) -> bool:
  58. """Show loading effect"""
  59. if not self.is_configured:
  60. return False
  61. if self.provider == "wled":
  62. return wled_loading(self._controller)
  63. elif self.provider == "dw_leds":
  64. return dw_led_loading(self._controller)
  65. return False
  66. def effect_idle(self, effect_name: Optional[str] = None) -> bool:
  67. """Show idle effect"""
  68. if not self.is_configured:
  69. return False
  70. if self.provider == "wled":
  71. return wled_idle(self._controller)
  72. elif self.provider == "dw_leds":
  73. return dw_led_idle(self._controller, effect_name)
  74. return False
  75. def effect_connected(self) -> bool:
  76. """Show connected effect"""
  77. if not self.is_configured:
  78. return False
  79. if self.provider == "wled":
  80. return wled_connected(self._controller)
  81. elif self.provider == "dw_leds":
  82. return dw_led_connected(self._controller)
  83. return False
  84. def effect_playing(self, effect_name: Optional[str] = None) -> bool:
  85. """Show playing effect"""
  86. if not self.is_configured:
  87. return False
  88. if self.provider == "wled":
  89. return wled_playing(self._controller)
  90. elif self.provider == "dw_leds":
  91. return dw_led_playing(self._controller, effect_name)
  92. return False
  93. def set_power(self, state: int) -> dict:
  94. """Set power state (0=Off, 1=On, 2=Toggle)"""
  95. if not self.is_configured:
  96. return {"connected": False, "message": "No LED controller configured"}
  97. return self._controller.set_power(state)
  98. def check_status(self) -> dict:
  99. """Check controller status"""
  100. if not self.is_configured:
  101. return {"connected": False, "message": "No LED controller configured"}
  102. if self.provider == "wled":
  103. return self._controller.check_wled_status()
  104. elif self.provider == "dw_leds":
  105. return self._controller.check_status()
  106. return {"connected": False, "message": "Unknown provider"}
  107. def get_controller(self):
  108. """Get the underlying controller instance (for advanced usage)"""
  109. return self._controller