mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-29 20:13:00 +00:00
Respect live game display duration when no priority is given
This commit is contained in:
@@ -915,7 +915,19 @@ class DisplayController:
|
||||
# No live_priority takeover, regular rotation
|
||||
needs_switch = False
|
||||
if self.current_display_mode.endswith('_live'):
|
||||
# For live modes without live_priority, check if duration has elapsed
|
||||
if current_time - self.last_switch >= self.get_current_duration():
|
||||
needs_switch = True
|
||||
self.current_mode_index = (self.current_mode_index + 1) % len(self.available_modes)
|
||||
new_mode_after_timer = self.available_modes[self.current_mode_index]
|
||||
if previous_mode_before_switch == 'music' and self.music_manager and new_mode_after_timer != 'music':
|
||||
self.music_manager.deactivate_music_display()
|
||||
if self.current_display_mode != new_mode_after_timer:
|
||||
logger.info(f"Switching to {new_mode_after_timer} from {self.current_display_mode}")
|
||||
self.current_display_mode = new_mode_after_timer
|
||||
# Reset logged duration when mode changes
|
||||
if hasattr(self, '_last_logged_duration'):
|
||||
delattr(self, '_last_logged_duration')
|
||||
elif current_time - self.last_switch >= self.get_current_duration():
|
||||
if self.current_display_mode == 'calendar' and self.calendar:
|
||||
self.calendar.advance_event()
|
||||
|
||||
@@ -37,6 +37,8 @@ class DisplayManager:
|
||||
def _setup_matrix(self):
|
||||
"""Initialize the RGB matrix with configuration settings."""
|
||||
setup_start = time.time()
|
||||
|
||||
try:
|
||||
options = RGBMatrixOptions()
|
||||
|
||||
# Hardware configuration
|
||||
@@ -71,16 +73,21 @@ class DisplayManager:
|
||||
if 'inverse_colors' in hardware_config:
|
||||
options.inverse_colors = hardware_config.get('inverse_colors')
|
||||
|
||||
logger.info(f"Initializing RGB Matrix with settings: rows={options.rows}, cols={options.cols}, chain_length={options.chain_length}, parallel={options.parallel}, hardware_mapping={options.hardware_mapping}")
|
||||
|
||||
# Initialize the matrix
|
||||
self.matrix = RGBMatrix(options=options)
|
||||
logger.info("RGB Matrix initialized successfully")
|
||||
|
||||
# Create double buffer for smooth updates
|
||||
self.offscreen_canvas = self.matrix.CreateFrameCanvas()
|
||||
self.current_canvas = self.matrix.CreateFrameCanvas()
|
||||
logger.info("Frame canvases created successfully")
|
||||
|
||||
# Create image with full chain width
|
||||
self.image = Image.new('RGB', (self.matrix.width, self.matrix.height))
|
||||
self.draw = ImageDraw.Draw(self.image)
|
||||
logger.info(f"Image canvas created with dimensions: {self.matrix.width}x{self.matrix.height}")
|
||||
|
||||
# Initialize font with Press Start 2P
|
||||
try:
|
||||
@@ -93,20 +100,49 @@ class DisplayManager:
|
||||
# Draw a test pattern
|
||||
self._draw_test_pattern()
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to initialize RGB Matrix: {e}", exc_info=True)
|
||||
# Create a fallback image for web preview
|
||||
self.matrix = None
|
||||
self.image = Image.new('RGB', (128, 32)) # Default size
|
||||
self.draw = ImageDraw.Draw(self.image)
|
||||
self.draw.text((10, 10), "Matrix Error", fill=(255, 0, 0))
|
||||
logger.error(f"Matrix initialization failed, using fallback mode. Error: {e}")
|
||||
raise
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
"""Get the display width."""
|
||||
return self.matrix.width if hasattr(self, 'matrix') else 128
|
||||
if hasattr(self, 'matrix') and self.matrix is not None:
|
||||
return self.matrix.width
|
||||
elif hasattr(self, 'image'):
|
||||
return self.image.width
|
||||
else:
|
||||
return 128 # Default fallback width
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
"""Get the display height."""
|
||||
return self.matrix.height if hasattr(self, 'matrix') else 32
|
||||
if hasattr(self, 'matrix') and self.matrix is not None:
|
||||
return self.matrix.height
|
||||
elif hasattr(self, 'image'):
|
||||
return self.image.height
|
||||
else:
|
||||
return 32 # Default fallback height
|
||||
|
||||
def _draw_test_pattern(self):
|
||||
"""Draw a test pattern to verify the display is working."""
|
||||
try:
|
||||
self.clear()
|
||||
|
||||
if self.matrix is None:
|
||||
# Fallback mode - just draw on the image
|
||||
self.draw.rectangle([0, 0, self.image.width-1, self.image.height-1], outline=(255, 0, 0))
|
||||
self.draw.line([0, 0, self.image.width-1, self.image.height-1], fill=(0, 255, 0))
|
||||
self.draw.text((10, 10), "Simulation", font=self.font, fill=(0, 0, 255))
|
||||
logger.info("Drew test pattern in fallback mode")
|
||||
return
|
||||
|
||||
# Draw a red rectangle border
|
||||
self.draw.rectangle([0, 0, self.matrix.width-1, self.matrix.height-1], outline=(255, 0, 0))
|
||||
|
||||
@@ -120,9 +156,17 @@ class DisplayManager:
|
||||
self.update_display()
|
||||
time.sleep(0.5) # Reduced from 1 second to 0.5 seconds for faster animation
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error drawing test pattern: {e}", exc_info=True)
|
||||
|
||||
def update_display(self):
|
||||
"""Update the display using double buffering with proper sync."""
|
||||
try:
|
||||
if self.matrix is None:
|
||||
# Fallback mode - no actual hardware to update
|
||||
logger.debug("Update display called in fallback mode (no hardware)")
|
||||
return
|
||||
|
||||
# Copy the current image to the offscreen canvas
|
||||
self.offscreen_canvas.SetImage(self.image)
|
||||
|
||||
@@ -137,6 +181,13 @@ class DisplayManager:
|
||||
def clear(self):
|
||||
"""Clear the display completely."""
|
||||
try:
|
||||
if self.matrix is None:
|
||||
# Fallback mode - just clear the image
|
||||
self.image = Image.new('RGB', (self.image.width, self.image.height))
|
||||
self.draw = ImageDraw.Draw(self.image)
|
||||
logger.debug("Cleared display in fallback mode")
|
||||
return
|
||||
|
||||
# Create a new black image
|
||||
self.image = Image.new('RGB', (self.matrix.width, self.matrix.height))
|
||||
self.draw = ImageDraw.Draw(self.image)
|
||||
|
||||
@@ -15,6 +15,7 @@ from PIL import Image
|
||||
import io
|
||||
import signal
|
||||
import sys
|
||||
import logging
|
||||
|
||||
app = Flask(__name__)
|
||||
app.secret_key = os.urandom(24)
|
||||
@@ -28,6 +29,9 @@ display_running = False
|
||||
editor_mode = False
|
||||
current_display_data = {}
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
class DisplayMonitor:
|
||||
def __init__(self):
|
||||
self.running = False
|
||||
@@ -71,7 +75,7 @@ class DisplayMonitor:
|
||||
socketio.emit('display_update', current_display_data)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Display monitor error: {e}")
|
||||
logger.error(f"Display monitor error: {e}", exc_info=True)
|
||||
|
||||
time.sleep(0.05) # Update 20 times per second for smoother display
|
||||
|
||||
@@ -182,7 +186,15 @@ def start_display():
|
||||
try:
|
||||
if not display_manager:
|
||||
config = config_manager.load_config()
|
||||
try:
|
||||
display_manager = DisplayManager(config)
|
||||
logger.info("DisplayManager initialized successfully")
|
||||
except Exception as dm_error:
|
||||
logger.error(f"Failed to initialize DisplayManager: {dm_error}")
|
||||
# Create a fallback display manager for web simulation
|
||||
display_manager = DisplayManager(config)
|
||||
logger.info("Using fallback DisplayManager for web simulation")
|
||||
|
||||
display_monitor.start()
|
||||
|
||||
display_running = True
|
||||
@@ -192,6 +204,7 @@ def start_display():
|
||||
'message': 'Display started successfully'
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error in start_display: {e}", exc_info=True)
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': f'Error starting display: {e}'
|
||||
@@ -235,7 +248,14 @@ def toggle_editor_mode():
|
||||
# Initialize display manager for editor if needed
|
||||
if not display_manager:
|
||||
config = config_manager.load_config()
|
||||
try:
|
||||
display_manager = DisplayManager(config)
|
||||
logger.info("DisplayManager initialized for editor mode")
|
||||
except Exception as dm_error:
|
||||
logger.error(f"Failed to initialize DisplayManager for editor: {dm_error}")
|
||||
# Create a fallback display manager for web simulation
|
||||
display_manager = DisplayManager(config)
|
||||
logger.info("Using fallback DisplayManager for editor simulation")
|
||||
display_monitor.start()
|
||||
else:
|
||||
# Resume normal display operation
|
||||
@@ -247,6 +267,7 @@ def toggle_editor_mode():
|
||||
'message': f'Editor mode {"enabled" if editor_mode else "disabled"}'
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error toggling editor mode: {e}", exc_info=True)
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': f'Error toggling editor mode: {e}'
|
||||
|
||||
Reference in New Issue
Block a user