mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-10-18 04:49:13 +00:00
fix(core): register tom_thumb, accept frame_hold in the test double, wire api_v3's managers
Three independent fixes found while validating every plugin on a 256x64 rig. FontManager never registered tom_thumb even though assets/fonts/tom-thumb.bdf ships with the core, so every plugin offering it logged "Font family 'tom_thumb' not found" (16 warnings per countdown render) and had to carry a private loader to use a bundled font. Closes #524. VisualTestDisplayManager.set_scrolling_state() lacked the frame_hold parameter that DisplayManager gained, so any plugin passing it died with TypeError at render time and failed every size. Nine plugins now make that call; ledmatrix-stocks and ledmatrix-leaderboard were failing outright and the other seven only passed because their scroll path was unreachable without data. Closes #525. api_v3 declared module-level config_manager/plugin_manager = None that nothing ever assigned -- app.py sets the blueprint attributes, which the other 150+ call sites use. Three sites read the decoys, so /health reported the config unreadable and the plugin system uninitialised (making "degraded" permanent and unreachable-by-design) and /display/current fell back to a hardcoded 128x64 on every rig. The decoys are removed rather than assigned, so a bare name is now a NameError at test time instead of a silent None. The same function's first-call uptime was computed from two separate clock reads and came out negative. Closes #529. Verified on the rig: both previously-failing plugins render, the tom_thumb warnings are gone, /health reports "healthy" with all three checks passing, and /display/current reports the real 256x64.
This commit is contained in:
+2
-1
@@ -96,7 +96,8 @@ class FontManager:
|
||||
self.common_fonts = {
|
||||
"press_start": "assets/fonts/PressStart2P-Regular.ttf",
|
||||
"four_by_six": "assets/fonts/4x6-font.ttf",
|
||||
"five_by_seven": "assets/fonts/5x7.bdf"
|
||||
"five_by_seven": "assets/fonts/5x7.bdf",
|
||||
"tom_thumb": "assets/fonts/tom-thumb.bdf"
|
||||
# Note: cozette_bdf removed - font file not available
|
||||
# To re-enable: download cozette.bdf from https://github.com/the-moonwitch/Cozette
|
||||
# and add: "cozette_bdf": "assets/fonts/cozette.bdf"
|
||||
|
||||
@@ -506,9 +506,16 @@ class VisualTestDisplayManager:
|
||||
# Scrolling state (no-op interface compat)
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def set_scrolling_state(self, is_scrolling: bool):
|
||||
"""Set the current scrolling state (no-op for testing)."""
|
||||
def set_scrolling_state(self, is_scrolling: bool, frame_hold: int = 1):
|
||||
"""Set the current scrolling state (no-op for testing).
|
||||
|
||||
``frame_hold`` mirrors DisplayManager.set_scrolling_state so a plugin
|
||||
that paces its scroll can be rendered here. Without it every such
|
||||
plugin raised TypeError at render time and failed every size, which is
|
||||
invisible until a plugin happens to pass the argument.
|
||||
"""
|
||||
self._scrolling_state['is_scrolling'] = is_scrolling
|
||||
self._scrolling_state['frame_hold'] = frame_hold
|
||||
if is_scrolling:
|
||||
self._scrolling_state['last_scroll_activity'] = time.time()
|
||||
|
||||
|
||||
@@ -78,8 +78,11 @@ def _scrub_git_remote_url(url: str) -> str:
|
||||
return url
|
||||
|
||||
# Will be initialized when blueprint is registered
|
||||
config_manager = None
|
||||
plugin_manager = None
|
||||
# NOTE: the managers live on the blueprint object (app.py sets
|
||||
# api_v3.config_manager / api_v3.plugin_manager). Deliberately not
|
||||
# mirrored as module globals: a bare `config_manager` used to resolve to
|
||||
# a None that was never assigned, which silently disabled the /health
|
||||
# checks and made /display/current fall back to a hardcoded 128x64.
|
||||
plugin_store_manager = None
|
||||
saved_repositories_manager = None
|
||||
cache_manager = None
|
||||
@@ -1598,11 +1601,16 @@ def get_health():
|
||||
}
|
||||
|
||||
# Check web interface service
|
||||
# Stamp the start time before measuring against it -- reading it with a
|
||||
# fallback of time.time() and only assigning afterwards made the very
|
||||
# first call subtract two separate clock reads, reporting a small
|
||||
# negative uptime.
|
||||
if not hasattr(get_health, '_start_time'):
|
||||
get_health._start_time = time.time()
|
||||
health_status['services']['web_interface'] = {
|
||||
'status': 'running',
|
||||
'uptime_seconds': time.time() - (getattr(get_health, '_start_time', time.time()))
|
||||
'uptime_seconds': time.time() - get_health._start_time
|
||||
}
|
||||
get_health._start_time = getattr(get_health, '_start_time', time.time())
|
||||
|
||||
# Check display service
|
||||
display_service_status = _get_display_service_status()
|
||||
@@ -1613,8 +1621,8 @@ def get_health():
|
||||
|
||||
# Check config file accessibility
|
||||
try:
|
||||
if config_manager:
|
||||
test_config = config_manager.load_config()
|
||||
if api_v3.config_manager:
|
||||
test_config = api_v3.config_manager.load_config()
|
||||
health_status['checks']['config_file'] = {
|
||||
'status': 'accessible',
|
||||
'readable': True
|
||||
@@ -1633,9 +1641,9 @@ def get_health():
|
||||
|
||||
# Check plugin system
|
||||
try:
|
||||
if plugin_manager:
|
||||
if api_v3.plugin_manager:
|
||||
# Try to discover plugins (lightweight check)
|
||||
plugin_count = len(plugin_manager.get_available_plugins()) if hasattr(plugin_manager, 'get_available_plugins') else 0
|
||||
plugin_count = len(api_v3.plugin_manager.get_available_plugins()) if hasattr(api_v3.plugin_manager, 'get_available_plugins') else 0
|
||||
health_status['checks']['plugin_system'] = {
|
||||
'status': 'operational',
|
||||
'plugin_count': plugin_count
|
||||
@@ -2468,8 +2476,8 @@ def get_display_current():
|
||||
|
||||
# Get display dimensions from config
|
||||
try:
|
||||
if config_manager:
|
||||
main_config = config_manager.load_config()
|
||||
if api_v3.config_manager:
|
||||
main_config = api_v3.config_manager.load_config()
|
||||
hardware_config = main_config.get('display', {}).get('hardware', {})
|
||||
cols = hardware_config.get('cols', 64)
|
||||
chain_length = hardware_config.get('chain_length', 2)
|
||||
|
||||
Reference in New Issue
Block a user