mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
feat: add timezone support for schedules and dim schedule feature (#218)
* feat: add timezone support for schedules and dim schedule feature - Fix timezone handling in _check_schedule() to use configured timezone instead of system time (addresses schedule offset issues) - Add dim schedule feature for automatic brightness dimming: - New dim_schedule config section with brightness level and time windows - Smart interaction: dim schedule won't turn display on if it's off - Supports both global and per-day modes like on/off schedule - Add set_brightness() and get_brightness() methods to DisplayManager for runtime brightness control - Add REST API endpoints: GET/POST /api/v3/config/dim-schedule - Add web UI for dim schedule configuration in schedule settings page Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: normalize per-day mode and validate dim_brightness input - Normalize mode string in _check_dim_schedule to handle both "per-day" and "per_day" variants - Add try/except around dim_brightness int conversion to handle invalid input gracefully Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: improve error handling in brightness and dim schedule endpoints - display_manager.py: Add fail-fast input validation, catch specific exceptions (AttributeError, TypeError, ValueError), add [BRIGHTNESS] context tags, include stack traces in error logs - api_v3.py: Catch specific config exceptions (FileNotFoundError, JSONDecodeError, IOError), add [DIM SCHEDULE] context tags for Pi debugging, include stack traces Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Chuck <chuck@example.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -174,6 +174,57 @@ class DisplayManager:
|
||||
else:
|
||||
return 32 # Default fallback height
|
||||
|
||||
def set_brightness(self, brightness: int) -> bool:
|
||||
"""
|
||||
Set display brightness at runtime.
|
||||
|
||||
Args:
|
||||
brightness: Brightness level (0-100)
|
||||
|
||||
Returns:
|
||||
True if brightness was set successfully, False otherwise
|
||||
"""
|
||||
# Fail fast: validate input type
|
||||
if not isinstance(brightness, (int, float)):
|
||||
logger.error(f"[BRIGHTNESS] Invalid brightness type: {type(brightness).__name__}, expected int")
|
||||
return False
|
||||
|
||||
if self.matrix is None:
|
||||
logger.warning("[BRIGHTNESS] Cannot set brightness in fallback mode")
|
||||
return False
|
||||
|
||||
# Clamp to valid range
|
||||
brightness = max(0, min(100, int(brightness)))
|
||||
|
||||
try:
|
||||
# RGBMatrix accepts brightness as a property
|
||||
self.matrix.brightness = brightness
|
||||
logger.info(f"[BRIGHTNESS] Display brightness set to {brightness}%")
|
||||
return True
|
||||
except AttributeError as e:
|
||||
logger.error(f"[BRIGHTNESS] Matrix does not support brightness property: {e}", exc_info=True)
|
||||
return False
|
||||
except (TypeError, ValueError) as e:
|
||||
logger.error(f"[BRIGHTNESS] Invalid brightness value rejected by hardware: {e}", exc_info=True)
|
||||
return False
|
||||
|
||||
def get_brightness(self) -> int:
|
||||
"""
|
||||
Get current display brightness.
|
||||
|
||||
Returns:
|
||||
Current brightness level (0-100), or -1 if unavailable
|
||||
"""
|
||||
if self.matrix is None:
|
||||
logger.debug("[BRIGHTNESS] Cannot get brightness in fallback mode")
|
||||
return -1
|
||||
|
||||
try:
|
||||
return self.matrix.brightness
|
||||
except AttributeError as e:
|
||||
logger.warning(f"[BRIGHTNESS] Matrix does not support brightness property: {e}", exc_info=True)
|
||||
return -1
|
||||
|
||||
def _draw_test_pattern(self):
|
||||
"""Draw a test pattern to verify the display is working."""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user