Files
LEDMatrix/web_interface
ChuckandClaude Opus 5 05cb9dc31f Merge main into the api_v3 split, carrying the three fixes it would have dropped
main modified web_interface/blueprints/api_v3.py while this branch deletes it,
so git reports a modify/delete conflict. Resolving that by accepting the
deletion - the obvious move - would silently discard every api_v3.py change
merged since this branch forked. Three were:

  #560  the sudo diagnosis on /system/action  -> api_v3/system.py
  #557  the stale-reconciliation-findings filter -> api_v3/plugins.py
  #550  the deletion of dead _validate_time_range -> api_v3/__init__.py

All three were verified absent from the split beforehand: _sudo_hint_for,
_SUDO_NEEDS_PASSWORD and _drop_stale_reconciliation_findings appeared in zero
files, while _validate_time_range was still sitting at __init__.py:343 after
#550 removed it from main. Each is now ported to the module that owns the
affected route, and the dead function is gone.

Two further changes this surfaced:

- api_v3/__init__.py imported fcntl at module scope. fcntl is POSIX-only, the
  monolithic blueprint never imported it, and on this branch it made the whole
  api_v3 package unimportable off POSIX: the pristine branch cannot run its
  test suite on Windows at all - 14 collection errors interrupt the run. The
  import now happens inside _starlark_manifest_lock(), the only thing that uses
  it. Deliberately NOT degraded to a no-op lock off POSIX; that function's
  docstring describes a real lost-update race, and silently not locking would
  be worse than failing loudly on a platform that cannot drive the display.

- test/test_reconciliation_status_endpoint.py is new. #557's endpoint wiring had
  no test - only the pure still_unresolved() helper in src/ was covered, and
  that lives outside web_interface so it survived the split untouched. Losing
  the filter during this merge would therefore have been completely silent.
  Removing the filter call now fails three of its seven cases.

Suite on this merge: 115 failed / 4317 passed. main today: 105 / 4252. All 11
extra failures are in test_starlark_pixlet_routes.py and need POSIX file locks,
so they are Windows-only; on that same file the pristine branch shows 19 failed
plus 39 errors, so this is a large net improvement rather than a regression.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 09:07:35 -04:00
..
2025-12-27 14:15:49 -05:00

LED Matrix Web Interface V3

Modern, production web interface for controlling the LED Matrix display.

Overview

This directory contains the active V3 web interface with the following features:

  • Real-time display preview via Server-Sent Events (SSE)
  • Plugin management and configuration
  • System monitoring and logs
  • Modern, responsive UI
  • RESTful API

Directory Structure

web_interface/
├── app.py                    # Main Flask application
├── start.py                  # Startup script
├── run.sh                    # Shell runner script
├── requirements.txt          # Python dependencies
├── blueprints/               # Flask blueprints
│   ├── api_v3.py            # API endpoints
│   └── pages_v3.py          # Page routes
├── templates/                # HTML templates
│   └── v3/
│       ├── base.html
│       ├── index.html
│       └── partials/
└── static/                   # CSS/JS assets
    └── v3/
        ├── app.css
        ├── app.js
        ├── manifest.json     # PWA manifest
        ├── plugins_manager.js
        ├── icons/            # PWA / touch icons
        ├── js/               # Alpine, htmx, app shell, widgets, utils
        └── vendor/           # codemirror, fontawesome

Running the Web Interface

Standalone (Development)

From the project root:

python3 web_interface/start.py

Or using the shell script:

./web_interface/run.sh

As a Service (Production)

The web interface can run as a systemd service that starts automatically based on the web_display_autostart configuration setting:

sudo systemctl start ledmatrix-web
sudo systemctl enable ledmatrix-web  # Start on boot

Accessing the Interface

Once running, access the web interface at:

Configuration

The web interface reads configuration from:

  • config/config.json - Main configuration
  • config/config_secrets.json - API keys and secrets

API Documentation

The V3 API is mounted at /api/v3/ (app.py:144). For the complete list and request/response formats, see docs/REST_API_REFERENCE.md. Quick reference for the most common endpoints:

Configuration

  • GET /api/v3/config/main - Get main configuration
  • POST /api/v3/config/main - Save main configuration
  • GET /api/v3/config/secrets - Get secrets configuration
  • POST /api/v3/config/raw/main - Save raw main config (Config Editor)
  • POST /api/v3/config/raw/secrets - Save raw secrets

Display & System Control

  • GET /api/v3/system/status - System status
  • POST /api/v3/system/action - Control display (action body: start_display, stop_display, restart_display_service, restart_web_service, git_pull, reboot_system, shutdown_system, enable_autostart, disable_autostart)
  • GET /api/v3/display/current - Current display frame
  • GET /api/v3/display/on-demand/status - On-demand status
  • POST /api/v3/display/on-demand/start - Trigger on-demand display
  • POST /api/v3/display/on-demand/stop - Clear on-demand

Plugins

  • GET /api/v3/plugins/installed - List installed plugins
  • GET /api/v3/plugins/config?plugin_id=<id> - Get plugin config
  • POST /api/v3/plugins/config - Update plugin configuration
  • GET /api/v3/plugins/schema?plugin_id=<id> - Get plugin schema
  • POST /api/v3/plugins/toggle - Enable/disable plugin
  • POST /api/v3/plugins/install - Install from registry
  • POST /api/v3/plugins/install-from-url - Install from GitHub URL
  • POST /api/v3/plugins/uninstall - Uninstall plugin
  • POST /api/v3/plugins/update - Update plugin

Plugin Store

  • GET /api/v3/plugins/store/list - List available registry plugins
  • GET /api/v3/plugins/store/github-status - GitHub authentication status
  • POST /api/v3/plugins/store/refresh - Refresh registry from GitHub

Real-time Streams (SSE)

SSE stream endpoints are defined directly on the Flask app (app.py:607-619 — includes the CSRF exemption and rate-limit hookup alongside the three route definitions), not on the api_v3 blueprint:

  • GET /api/v3/stream/stats - System statistics stream
  • GET /api/v3/stream/display - Display preview stream
  • GET /api/v3/stream/logs - Service logs stream

Development

When making changes to the web interface:

  1. Edit files in this directory
  2. Test changes by running python3 web_interface/start.py
  3. Restart the service if running: sudo systemctl restart ledmatrix-web

Notes

  • Templates and static files use the v3/ prefix to allow for future versions
  • The interface uses Flask blueprints for modular organization
  • SSE streams provide real-time updates without polling