Files
LEDMatrix/docs/CONFIG_REFERENCE.md
T
Claude b428ae3eae fix: address CodeRabbit review findings
Verified each finding against the code; fixes for the valid ones:

- install_dependencies_apt.py: the installer listed 'freetype', but the
  declared dependency is freetype-py — an apt miss would pip-install the
  wrong PyPI package. Now installs freetype-py with an import-name
  mapping (pre-existing bug, surfaced by the review).
- api_v3.py: pixel_mapper_config is validated as a string before being
  saved to display.hardware (JSON callers could previously store an
  object/list the matrix library can't use).
- .cursorrules: the Plugin Loading Process and File Organization
  sections still said discovery scans plugins/ — now consistent with the
  corrected overview (configured directory, default plugin-repos/).
- README.md: removed the stale '(except the core calendar)' claim — no
  core calendar exists in src/ — and qualified the plugin inventory
  (official plugins in the monorepo; third-party from their own repos).
- CONFIG_REFERENCE.md: hardware_mapping now shows the code fallback
  (adafruit-hat-pwm) alongside the template value.
- PLUGIN_REGISTRY_SETUP_GUIDE.md: check_plugin.py takes --plugin, not a
  positional id.
- scripts/fix_perms/fix_*.sh: exec bits set so the documented
  'sudo ./...' invocations work.
- Guard tests hardened: template guard now catches multi-line
  render_template() calls; widget guard parses actual <script> src
  values and fails if the widgets dir goes missing; type hints and
  docstrings added per repo coding guidelines.

Skipped with reasons (noted on the PR): limit_refresh_rate_hz 100-vs-90
is documented as intentional in CONFIG_REFERENCE.md; the psutil comment
already names the enforcing manifest; docs/archive/ findings are out of
scope per the docs policy (archive may rot).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SXb4mKcAkVaxkeTb3YnAdr
2026-08-06 01:32:23 +00:00

7.7 KiB
Raw Blame History

Configuration Reference

Every key in config/config.json, what it does, its default, and where the code reads it. The file is created from config/config.template.json on first run, and ConfigManager._migrate_config() merges any template keys added by later releases into your existing config (your values are never overwritten). Secrets live in config/config_secrets.json and are merged into the config at load time.

Most settings are editable from the web interface; this page documents the underlying keys for people editing config.json directly or writing tooling against it.

Top level

Key Type / default Meaning Read by
web_display_autostart bool, true Whether the web interface service starts with the system scripts/utils/start_web_conditionally.py
timezone string, "America/New_York" IANA timezone for schedules and displays ConfigManager.get_timezone()
target_fps int, 100 Frame-rate ceiling for plugin rendering src/plugin_system/base_plugin.py, src/common/sports_scroll.py
location object city / state / country, offered to plugins that need a location (weather, etc.) plugins via merged config

schedule — display on/off hours

Key Type / default Meaning
enabled bool, false Master switch for scheduled display on/off
mode "global" or "per-day", template uses "per-day" Whether one time range applies to all days or each day has its own
start_time / end_time "HH:MM", 07:0023:00 Global-mode on/off times
days.<weekday>.{enabled,start_time,end_time} per-day objects Per-day-mode overrides

Read by DisplayController (src/display_controller.py, _check_schedule around line 603). Managed in the web UI under Schedule.

dim_schedule — scheduled brightness dimming

Same shape as schedule, plus:

Key Type / default Meaning
dim_brightness int, 30 Brightness percentage applied while the dim window is active

Read by DisplayController (src/display_controller.py around line 770; saved via POST /api/v3/config/dim-schedule). The display returns to display.hardware.brightness outside the window.

display.hardware — matrix panel hardware

All keys map to the corresponding rpi-rgb-led-matrix options and are read in DisplayManager (src/display_manager.py, ~lines 270295).

Key Type / default
rows / cols int, 32 / 64
chain_length int, 2
parallel int, 1
brightness int, 90
hardware_mapping string, "adafruit-hat" (code default "adafruit-hat-pwm")
scan_mode int, 0
pwm_bits int, 9 (code default 10)
pwm_dither_bits int, 1
pwm_lsb_nanoseconds int, 130 (code default 150)
disable_hardware_pulsing bool, false
inverse_colors bool, false
show_refresh_rate bool, false
led_rgb_sequence string, "RGB"
limit_refresh_rate_hz int, 100 (code default 90)
pixel_mapper_config string, "" — e.g. "U-mapper" / "Rotate:90"
row_address_type int, 0 — non-standard panel row addressing
multiplexing int, 0 — panel multiplexing scheme
panel_type string, "" — set to "FM6126A" or "FM6127" for panels needing init

Where "code default" differs from the template value, the code default only applies if the key is missing entirely from your config.

display.runtime

Key Type / default Meaning
gpio_slowdown int, 3 GPIO timing slowdown for faster Pis
rp1_rio int, 0 RP1 RIO mode on Pi 5 (applied only if the installed matrix library supports it)

display.double_sided

Drives _LogicalMatrix in src/display_manager.py — renders the same logical image to multiple chained physical panels.

Key Type / default Meaning
enabled bool, false Mirror output across panel copies
copies int, 2 Number of physical copies in the chain
axis "horizontal", default Axis along which panels are chained

display — other keys

Key Type / default Meaning Read by
display_durations object, {} Per-plugin display duration in seconds, keyed by plugin id (e.g. "clock": 15) src/display_controller.py:1030
plugin_rotation_order array, [] Explicit rotation order of plugin ids; empty = all enabled plugins in discovery order src/display_controller.py:2894
use_short_date_format bool, true Compact date rendering in sports scoreboards src/base_classes/sports/core.py
dynamic_duration.max_duration_seconds int, optional Cap for plugins that request dynamic display time src/display_controller.py:405

display.vegas_scroll — continuous scroll mode

Read by src/vegas_mode/config.py (VegasScrollConfig.from_config). See ADVANCED_FEATURES.md for behavior details.

Key Type / default
enabled bool, false
scroll_speed int, 50 (px/s)
separator_width int, 32
plugin_order array, []
excluded_plugins array, []
target_fps int, 125
buffer_ahead int, 2
intra_plugin_gap int, 8
render_width_pct int, 100
min_content_separation int, 24
min_cut_gap int, 6
continuous_scroll bool, true
smooth_scroll bool, true
extend_threshold_screens float, 2.0
auto_trim bool, true
trim_threshold int, 10
content_padding int, 8
min_plugin_width int, 8
lead_in_width int, 0
plugins_per_cycle int, 6
max_plugin_width_ratio float, 3.0
overflow_mode string, "rotate"
dynamic_duration_enabled bool, true
min_cycle_duration int, 60
max_cycle_duration int, 240
frame_based_scrolling bool, true — frame-count-based scroll stepping
scroll_delay float, 0.02 — seconds between scroll updates (~50 FPS)

sync — multi-display synchronization

Read by src/common/sync_manager.py and src/display_controller.py.

Key Type / default Meaning
role "standalone" (default), "leader", or "follower" This device's role in a synced pair
port int, 5765 TCP port used for sync traffic
follower_position "left" (default) or "right" Which half of the combined image this follower renders (src/display_controller.py:522)

plugin_system

Read by the plugin loader/manager (src/plugin_system/).

Key Type / default Meaning
plugins_directory string, "plugin-repos" Where the Plugin Store installs plugins
auto_discover bool, true Scan the plugins directory at startup
auto_load_enabled bool, true Load discovered plugins automatically
development_mode bool, false Development conveniences in the web UI (editable under General settings)

Plugin config blocks

Every installed plugin stores its settings under a top-level key equal to its plugin id (the template ships one for the bundled web-ui-info plugin). The shape of each block is defined by that plugin's config_schema.json; common keys are enabled and display_duration. See PLUGIN_CONFIG_CORE_PROPERTIES.md.

config/config_secrets.json

Key Meaning
github.api_token Optional GitHub token the Plugin Store uses to avoid API rate limits (src/plugin_system/store_manager.py:348)
<plugin-id>.* Secrets a plugin declares with "x-secret": true in its config schema; merged into that plugin's config at load time