mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 13:02:59 +00:00
web preview fixes
This commit is contained in:
@@ -25,6 +25,10 @@ class DisplayManager:
|
||||
start_time = time.time()
|
||||
self.config = config or {}
|
||||
self._force_fallback = force_fallback
|
||||
# Snapshot settings for web preview integration (service writes, web reads)
|
||||
self._snapshot_path = "/tmp/led_matrix_preview.png"
|
||||
self._snapshot_min_interval_sec = 0.2 # max ~5 fps
|
||||
self._last_snapshot_ts = 0.0
|
||||
self._setup_matrix()
|
||||
logger.info("Matrix setup completed in %.3f seconds", time.time() - start_time)
|
||||
|
||||
@@ -186,6 +190,8 @@ class DisplayManager:
|
||||
if self.matrix is None:
|
||||
# Fallback mode - no actual hardware to update
|
||||
logger.debug("Update display called in fallback mode (no hardware)")
|
||||
# Still write a snapshot so the web UI can preview
|
||||
self._write_snapshot_if_due()
|
||||
return
|
||||
|
||||
# Copy the current image to the offscreen canvas
|
||||
@@ -196,6 +202,9 @@ class DisplayManager:
|
||||
|
||||
# Swap our canvas references
|
||||
self.offscreen_canvas, self.current_canvas = self.current_canvas, self.offscreen_canvas
|
||||
|
||||
# Write a snapshot for the web preview (throttled)
|
||||
self._write_snapshot_if_due()
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating display: {e}")
|
||||
|
||||
@@ -615,4 +624,21 @@ class DisplayManager:
|
||||
else:
|
||||
suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(day % 10, 'th')
|
||||
|
||||
return dt.strftime(f"%b %-d{suffix}")
|
||||
return dt.strftime(f"%b %-d{suffix}")
|
||||
|
||||
def _write_snapshot_if_due(self) -> None:
|
||||
"""Write the current image to a PNG snapshot file at a limited frequency."""
|
||||
try:
|
||||
now = time.time()
|
||||
if (now - self._last_snapshot_ts) < self._snapshot_min_interval_sec:
|
||||
return
|
||||
# Ensure directory exists
|
||||
snapshot_dir = os.path.dirname(self._snapshot_path)
|
||||
if snapshot_dir and not os.path.exists(snapshot_dir):
|
||||
os.makedirs(snapshot_dir, exist_ok=True)
|
||||
# Write PNG snapshot
|
||||
self.image.save(self._snapshot_path, format='PNG')
|
||||
self._last_snapshot_ts = now
|
||||
except Exception as e:
|
||||
# Snapshot failures should never break display; log at debug to avoid noise
|
||||
logger.debug(f"Snapshot write skipped: {e}")
|
||||
@@ -57,32 +57,45 @@ class DisplayMonitor:
|
||||
|
||||
def _monitor_loop(self):
|
||||
global display_manager, current_display_data
|
||||
snapshot_path = "/tmp/led_matrix_preview.png"
|
||||
while self.running:
|
||||
try:
|
||||
if display_manager and hasattr(display_manager, 'image'):
|
||||
# Convert raw image to base64 (no server-side scaling; client scales visually)
|
||||
# Prefer service-provided snapshot if available (works when ledmatrix service is running)
|
||||
if os.path.exists(snapshot_path):
|
||||
with open(snapshot_path, 'rb') as f:
|
||||
img_bytes = f.read()
|
||||
img_str = base64.b64encode(img_bytes).decode()
|
||||
# If we can infer dimensions from display_manager, include them; else leave 0
|
||||
width = display_manager.width if display_manager else 0
|
||||
height = display_manager.height if display_manager else 0
|
||||
current_display_data = {
|
||||
'image': img_str,
|
||||
'width': width,
|
||||
'height': height,
|
||||
'timestamp': time.time()
|
||||
}
|
||||
socketio.emit('display_update', current_display_data)
|
||||
elif display_manager and hasattr(display_manager, 'image'):
|
||||
# Fallback to in-process manager image
|
||||
img_buffer = io.BytesIO()
|
||||
display_manager.image.save(img_buffer, format='PNG')
|
||||
img_str = base64.b64encode(img_buffer.getvalue()).decode()
|
||||
|
||||
current_display_data = {
|
||||
'image': img_str,
|
||||
'width': display_manager.width,
|
||||
'height': display_manager.height,
|
||||
'timestamp': time.time()
|
||||
}
|
||||
|
||||
# Emit to all connected clients
|
||||
socketio.emit('display_update', current_display_data)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Display monitor error: {e}", exc_info=True)
|
||||
|
||||
# Yield to the async loop; target ~10 FPS to reduce load
|
||||
# Yield to the async loop; target ~5-10 FPS
|
||||
try:
|
||||
socketio.sleep(0.1)
|
||||
socketio.sleep(0.2)
|
||||
except Exception:
|
||||
time.sleep(0.1)
|
||||
time.sleep(0.2)
|
||||
|
||||
display_monitor = DisplayMonitor()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user