mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 13:02:59 +00:00
add api counter
This commit is contained in:
@@ -394,12 +394,9 @@ class DisplayManager:
|
|||||||
|
|
||||||
# Draw the text
|
# Draw the text
|
||||||
if isinstance(current_font, freetype.Face):
|
if isinstance(current_font, freetype.Face):
|
||||||
# For BDF fonts, we need to adjust the y-coordinate.
|
# For BDF fonts, _draw_bdf_text will compute the baseline from the
|
||||||
# The passed 'y' is the top of the text, but our drawing function
|
# provided top-left y using the font ascender. Do not adjust here.
|
||||||
# expects the baseline. The 'ascender' is the distance from the
|
self._draw_bdf_text(text, x, y, color, current_font)
|
||||||
# baseline to the top of the glyphs.
|
|
||||||
baseline_y = y + (current_font.size.ascender >> 6)
|
|
||||||
self._draw_bdf_text(text, x, baseline_y, color, current_font)
|
|
||||||
else:
|
else:
|
||||||
# For TTF fonts, use PIL's text drawing which expects top-left.
|
# For TTF fonts, use PIL's text drawing which expects top-left.
|
||||||
self.draw.text((x, y), text, font=current_font, fill=color)
|
self.draw.text((x, y), text, font=current_font, fill=color)
|
||||||
@@ -636,8 +633,14 @@ class DisplayManager:
|
|||||||
snapshot_dir = os.path.dirname(self._snapshot_path)
|
snapshot_dir = os.path.dirname(self._snapshot_path)
|
||||||
if snapshot_dir and not os.path.exists(snapshot_dir):
|
if snapshot_dir and not os.path.exists(snapshot_dir):
|
||||||
os.makedirs(snapshot_dir, exist_ok=True)
|
os.makedirs(snapshot_dir, exist_ok=True)
|
||||||
# Write PNG snapshot
|
# Write atomically: temp then replace
|
||||||
self.image.save(self._snapshot_path, format='PNG')
|
tmp_path = f"{self._snapshot_path}.tmp"
|
||||||
|
self.image.save(tmp_path, format='PNG')
|
||||||
|
try:
|
||||||
|
os.replace(tmp_path, self._snapshot_path)
|
||||||
|
except Exception:
|
||||||
|
# Fallback to direct save if replace not supported
|
||||||
|
self.image.save(self._snapshot_path, format='PNG')
|
||||||
self._last_snapshot_ts = now
|
self._last_snapshot_ts = now
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Snapshot failures should never break display; log at debug to avoid noise
|
# Snapshot failures should never break display; log at debug to avoid noise
|
||||||
|
|||||||
@@ -768,7 +768,7 @@
|
|||||||
Show pixel grid
|
Show pixel grid
|
||||||
</label>
|
</label>
|
||||||
<label style="color:#333; background:#f3f3f3; padding:6px 10px; border-radius:8px; display:inline-flex; align-items:center; gap:8px;">
|
<label style="color:#333; background:#f3f3f3; padding:6px 10px; border-radius:8px; display:inline-flex; align-items:center; gap:8px;">
|
||||||
<input type="checkbox" id="toggleLedDots">
|
<input type="checkbox" id="toggleLedDots" checked>
|
||||||
LED dot mode
|
LED dot mode
|
||||||
</label>
|
</label>
|
||||||
<label style="color:#333; background:#f3f3f3; padding:6px 10px; border-radius:8px; display:inline-flex; align-items:center; gap:8px;">
|
<label style="color:#333; background:#f3f3f3; padding:6px 10px; border-radius:8px; display:inline-flex; align-items:center; gap:8px;">
|
||||||
@@ -1411,6 +1411,7 @@
|
|||||||
<h4>API Calls (24h window)</h4>
|
<h4>API Calls (24h window)</h4>
|
||||||
<div id="api-metrics" class="stat-card" style="text-align:left;">
|
<div id="api-metrics" class="stat-card" style="text-align:left;">
|
||||||
<div>Loading API metrics...</div>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1838,6 +1839,10 @@
|
|||||||
}
|
}
|
||||||
if (toggleLedDots) {
|
if (toggleLedDots) {
|
||||||
toggleLedDots.addEventListener('change', renderLedDots);
|
toggleLedDots.addEventListener('change', renderLedDots);
|
||||||
|
// Ensure dot mode is rendered on load if enabled by default
|
||||||
|
if (toggleLedDots.checked) {
|
||||||
|
setTimeout(renderLedDots, 200);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update stats every 30 seconds
|
// Update stats every 30 seconds
|
||||||
|
|||||||
@@ -62,8 +62,17 @@ class DisplayMonitor:
|
|||||||
try:
|
try:
|
||||||
# Prefer service-provided snapshot if available (works when ledmatrix service is running)
|
# Prefer service-provided snapshot if available (works when ledmatrix service is running)
|
||||||
if os.path.exists(snapshot_path):
|
if os.path.exists(snapshot_path):
|
||||||
with open(snapshot_path, 'rb') as f:
|
# Read atomically by reopening; ignore partials by retrying once
|
||||||
img_bytes = f.read()
|
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()
|
img_str = base64.b64encode(img_bytes).decode()
|
||||||
# If we can infer dimensions from display_manager, include them; else leave 0
|
# If we can infer dimensions from display_manager, include them; else leave 0
|
||||||
width = display_manager.width if display_manager else 0
|
width = display_manager.width if display_manager else 0
|
||||||
|
|||||||
Reference in New Issue
Block a user