mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
display preview error handling
This commit is contained in:
@@ -1412,6 +1412,9 @@
|
||||
<div id="api-metrics" class="stat-card" style="text-align:left;">
|
||||
<div>Loading API metrics...</div>
|
||||
<div style="margin-top:10px; font-size:12px; color:#666;">If empty, ensure the server is running and /api/metrics is reachable.</div>
|
||||
<div style="margin-top:10px;">
|
||||
<button class="btn btn-primary" onclick="updateApiMetrics()"><i class="fas fa-sync"></i> Refresh API Metrics</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1992,6 +1995,10 @@
|
||||
|
||||
// Update image and meta label
|
||||
img.style.imageRendering = 'pixelated';
|
||||
img.onload = () => {
|
||||
// Ensure LED dot overlay samples after image is ready
|
||||
renderLedDots();
|
||||
};
|
||||
img.src = `data:image/png;base64,${data.image}`;
|
||||
const meta = document.getElementById('previewMeta');
|
||||
if (meta) {
|
||||
@@ -2034,9 +2041,8 @@
|
||||
const ctx = ledCanvas.getContext('2d');
|
||||
ctx.clearRect(0, 0, ledCanvas.width, ledCanvas.height);
|
||||
|
||||
// Draw black background (gaps between LEDs)
|
||||
ctx.fillStyle = '#000';
|
||||
ctx.fillRect(0, 0, ledCanvas.width, ledCanvas.height);
|
||||
// Clear previous overlay; do not forcibly black-out if sampling fails
|
||||
ctx.clearRect(0, 0, ledCanvas.width, ledCanvas.height);
|
||||
|
||||
// Create an offscreen canvas to sample pixel colors
|
||||
const off = document.createElement('canvas');
|
||||
@@ -2051,6 +2057,7 @@
|
||||
} catch (_) { /* draw failures ignored */ }
|
||||
|
||||
// Draw circular dots for each LED pixel
|
||||
let drawn = 0;
|
||||
for (let y = 0; y < logicalHeight; y++) {
|
||||
for (let x = 0; x < logicalWidth; x++) {
|
||||
const pixel = offCtx.getImageData(x, y, 1, 1).data;
|
||||
@@ -2063,8 +2070,14 @@
|
||||
ctx.beginPath();
|
||||
ctx.arc(cx, cy, dotRadius, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
drawn++;
|
||||
}
|
||||
}
|
||||
|
||||
// If nothing was drawn (e.g., image not ready), hide overlay to show base image
|
||||
if (drawn === 0) {
|
||||
ledCanvas.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Tab functionality
|
||||
|
||||
@@ -62,18 +62,28 @@ class DisplayMonitor:
|
||||
try:
|
||||
# Prefer service-provided snapshot if available (works when ledmatrix service is running)
|
||||
if os.path.exists(snapshot_path):
|
||||
# Read atomically by reopening; ignore partials by retrying once
|
||||
# Read atomically by reopening; ignore partials by skipping this frame
|
||||
img_bytes = None
|
||||
for _ in range(2):
|
||||
try:
|
||||
with open(snapshot_path, 'rb') as f:
|
||||
img_bytes = f.read()
|
||||
break
|
||||
except Exception:
|
||||
socketio.sleep(0.02)
|
||||
if not img_bytes:
|
||||
raise RuntimeError('Snapshot read failed')
|
||||
img_str = base64.b64encode(img_bytes).decode()
|
||||
try:
|
||||
with open(snapshot_path, 'rb') as f:
|
||||
img_bytes = f.read()
|
||||
except Exception:
|
||||
img_bytes = None
|
||||
if img_bytes:
|
||||
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)
|
||||
# Yield and continue to next frame
|
||||
socketio.sleep(0.1)
|
||||
continue
|
||||
# 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
|
||||
@@ -97,14 +107,15 @@ class DisplayMonitor:
|
||||
}
|
||||
socketio.emit('display_update', current_display_data)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Display monitor error: {e}", exc_info=True)
|
||||
except Exception:
|
||||
# Swallow errors in the monitor loop to avoid log spam
|
||||
pass
|
||||
|
||||
# Yield to the async loop; target ~5-10 FPS
|
||||
try:
|
||||
socketio.sleep(0.2)
|
||||
socketio.sleep(0.1)
|
||||
except Exception:
|
||||
time.sleep(0.2)
|
||||
time.sleep(0.1)
|
||||
|
||||
display_monitor = DisplayMonitor()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user