Files
LEDMatrix/docs/SSH_UNAVAILABLE_AFTER_INSTALL.md
T
ChuckandClaude Opus 5.5 a231d4dbc7 chore: delete unreferenced scripts and archived docs; fix stale doc claims (#607)
* chore(scripts): delete unreferenced helper scripts

None of these is referenced by an installer, systemd unit, CI workflow,
test, the web UI or src/:

- utils/cleanup_venv.sh removes venv_web_v2, which nothing creates
- utils/clear_python_cache.sh hardcodes ~/LEDMatrix and a .webassets-cache
  nothing uses
- install/migrate_config.sh only copies the template, which the installer
  and ConfigManager already do
- install/debug_install.sh, debug/debug_web_manual.py
- diagnose_web_ui.sh and verify_web_ui.sh overlap diagnose_web_interface.sh,
  which the docs point to
- fix_internet_connectivity.sh is iptables-only (stale on nftables)
- diagnose_plugin_permissions.sh, dev/validate_python.py
- download_nba_logos.py + README_NBA_LOGOS.md: logo_downloader fetches
  logos on demand
- setup_plugin_repos.py linked into the production plugin-repos/ dir; the
  dev workflow is scripts/dev/dev_plugin_setup.sh, and
  MULTI_ROOT_WORKSPACE_SETUP.md now uses it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(config): drop unused plugin_system flags and a dead unit comment

- config.template.json: remove plugin_system.auto_discover,
  auto_load_enabled and development_mode. Nothing reads them; the web UI
  only stores them when a client sends them. ConfigManager's migration
  only adds template keys, so existing configs keep theirs unchanged.
- config.template.json: re-indent vegas_scroll's live_* keys.
- systemd/ledmatrix.service: remove the comment documenting
  LEDMATRIX_ON_DEMAND_PLUGIN / on_demand_env.conf; nothing reads either.
- CONFIG_REFERENCE.md: say the legacy keys are no longer in the template.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: delete docs/archive and PLUGIN_IMPLEMENTATION_SUMMARY.md

- docs/archive/: superseded guides; the repository history keeps them
  and no live doc links into the directory. The one open document in it,
  WEB_UI_AUDIT_2026-09.md, moves to docs/audits/ and is linked from the
  docs index.
- PLUGIN_IMPLEMENTATION_SUMMARY.md invented usage statistics, called
  v2.0.0 current, listed shipped auto-updates as future work and
  documented a BasePlugin.get_config() that does not exist.
- docs/README.md: drop both, and stop telling contributors to archive
  obsolete pages instead of deleting them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(plugin-api): fix extra_small_font size, cache metric key and scroll pacing example

- PLUGIN_API_REFERENCE: extra_small_font loads at 7, not 6 (crisp_size
  snaps it, src/display_manager.py); get_cache_metrics() returns
  cache_hit_rate, not hit_rate (src/cache/cache_metrics.py).
- ADVANCED_PLUGIN_DEVELOPMENT: the basic scrolling example slept in a loop
  and never passed frame_hold; use ScrollHelper + scroll_config.configure()
  and set_scrolling_state(True, frame_hold=...) as PLUGIN_API_REFERENCE does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(plugin-config): match the config tab, icon and web-action docs to the code

- PLUGIN_CONFIG_QUICK_START / PLUGIN_CONFIGURATION_TABS /
  PLUGIN_CONFIGURATION_GUIDE: there is no "Reset to Defaults" button (the
  tab has Refresh, Update, Uninstall, Save Configuration); plugin config
  hot-reloads (ConfigService + on_config_change), so no restart; the
  schema is found by the fixed name config_schema.json, not a manifest
  config_schema field; the tab row is "Plugin Manager", not "Plugins";
  forms are server-rendered from /v3/partials/plugin-config/<id>; the
  duration hook is get_display_duration()/display_duration; a class_name
  mismatch raises PluginError; the store requires id, name, class_name and
  display_modes (not version); plugin_system.debug/log_level do not exist
  (use run.py -d / LEDMATRIX_DEBUG). Drop "future" features that shipped.
- PLUGIN_CONFIG_CORE_PROPERTIES: list all of CORE_PLUGIN_PROPERTIES,
  including skin, skin_options and the vegas_* tuning keys.
- PLUGIN_CUSTOM_ICONS: icon is only a Font Awesome class (fallback
  fa-puzzle-piece); emoji/URL icons and getPluginIcon() never existed in
  v3. Note that /api/v3/plugins/installed currently omits icon.
- PLUGIN_WEB_UI_ACTIONS (+ example JSON): success_message, error_message
  and step1_message are never read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(store): describe the monorepo registry and the store UI as they are

- PLUGIN_STORE_GUIDE: the Plugin Store is a section of the Plugin
  Manager tab; URL installs are "Install from GitHub" -> "Install Single
  Plugin"; bulk update exists (Check & Update All) plus opt-in weekly
  auto-update; PluginStoreManager() defaults to plugins/, so the Python
  examples pass plugin-repos; registry plugins are downloaded (GitHub API,
  ZIP fallback), not cloned; updates compare version with latest_version.
- PLUGIN_REGISTRY_SETUP_GUIDE: replace the per-plugin-repo + tag
  walkthrough with a short page on the monorepo registry (plugin_path,
  latest_version, update_registry.py) that points at the monorepo's own
  SUBMISSION.md. Drops the reference to the deleted
  PLUGIN_IMPLEMENTATION_SUMMARY.md and setup_plugin_repos.py.
- plugin_registry_template.json: use the real entry shape.
- PLUGIN_QUICK_REFERENCE: automatic background updates exist (opt-in);
  registry example and publishing steps use the monorepo, not tags.
- PLUGIN_DEVELOPMENT_GUIDE: tags/releases are not read by the store.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(readme): fix the Triple Bonnet mapping, install prerequisites and backup names

- README: the Adafruit Triple Bonnet uses `regular` (3 outputs), not
  `regular-pi1` (1 output) -- src/matrix_support.py MAPPING_OUTPUTS, and
  the README's own hardware_mapping section; the template default mapping
  is adafruit-hat, the PWM mod switches it to adafruit-hat-pwm; manual
  install only needs git up front (first_time_install.sh installs
  python-dev-is-python3, cmake, ninja-build etc.; cython3/scons are not
  used); the Pi Zero 2 W is a supported low-memory board, consistent with
  PRODUCT.md, LOW_MEMORY_BOARDS.md and the installer's low-memory build;
  fix the "First_time_install.sh" spelling, an orphan "2." list item and
  the hello-world starter link (it lives in the plugins monorepo).
- CONFIG_DEBUGGING: automatic backups are
  config/backups/config.json.backup.<YYYYMMDD_HHMMSS_ffffff> (five kept),
  not config_YYYYMMDD_HHMMSS.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(dev): correct the test-running and rgbmatrix build instructions

- HOW_TO_RUN_TESTS: coverage is not collected by a plain pytest run and
  pytest.ini has no threshold; the only one is --cov-fail-under=52 in the
  core unit-test job of .github/workflows/test.yml, which runs the whole
  test/ tree (not an allowlist). Almost no tests carry markers, so
  -m integration / -m slow select nothing; drop them and -m unit as the
  quick check. Replace the hardcoded /home/chuck path.
- DEVELOPMENT: the rgbmatrix package is built with pip install . from
  the submodule root (scikit-build-core + CMake + Ninja), as
  first_time_install.sh does; there is no make build-python /
  bindings/python step, and the build deps are python-dev-is-python3,
  cmake and ninja-build, not cython3/scons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(wifi): the setup AP is open; auto-enable can be turned off without code changes

- WIFI_NETWORK_SETUP / SSH_UNAVAILABLE_AFTER_INSTALL: both AP paths in
  src/wifi_manager.py create an open network and nothing reads
  ap_password, so drop the "ledmatrix123" password and the ap_password
  key/advice.
- SSH_UNAVAILABLE_AFTER_INSTALL: disabling automatic AP mode does not
  need code changes -- auto_enable_ap_mode is a WiFi-tab toggle and
  POST /api/v3/wifi/ap/auto-enable; note the monitor daemon reads
  wifi_config.json at start, so restart it after changing the setting.
  Use the ledpi username and a relative install path like the other docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(reference): add auto_update, drop drifted line numbers, fix UI and service details

- CONFIG_REFERENCE: document the top-level auto_update.enabled key (read
  by web_interface/auto_update.py and src/auto_update_setup.py); replace
  drifted file:line references with function names; the template's
  dim_schedule mode is "global".
- ADVANCED_FEATURES: core does not read a per-plugin background_service
  block (the sports plugins read their own), and priority is "higher
  number = higher priority" on FetchRequest but not used for ordering.
- WEB_INTERFACE_GUIDE: the General tab toggle is "Web Display Autostart"
  (web interface service), brightness is 1-100, and config paths are
  relative to the LEDMatrix folder, not /config.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: drop references to code removed in #608

get_installed_plugin_info, WiFiManager's saved_networks and the six
always-skipping plugin test files are deleted there. NetworkManager already
remembers joined networks; LEDMatrix no longer stores WiFi passwords.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: don't link SKIN_SYSTEM.md from the core-properties page

#615 deletes SKIN_SYSTEM.md; with this link, whichever of the two merged
second would break test_doc_links. The skin/skin_options entries go when
#615 removes the keys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 12:36:38 -04:00

7.2 KiB

SSH Unavailable After Installation - Troubleshooting Guide

Why SSH Becomes Unavailable

After running first_time_install.sh, SSH may become unavailable for the following reasons:

1. WiFi Monitor Service Enables AP Mode

Primary Cause: The WiFi monitor service (ledmatrix-wifi-monitor) automatically enables Access Point (AP) mode when it detects that the Raspberry Pi is not connected to WiFi. When AP mode is active:

  • The Pi creates its own WiFi network: LEDMatrix-Setup (open, no password)
  • The Pi's WiFi interface (wlan0) switches from client mode to AP mode
  • This disconnects the Pi from your original WiFi network
  • SSH becomes unavailable because the Pi is no longer on your network

2. Network Configuration Changes

The installation script:

  • Installs and configures hostapd (Access Point daemon)
  • Installs and configures dnsmasq (DHCP server for AP mode)
  • These services can interfere with normal WiFi client mode

3. The Board Ran Out of Memory

On a 512MB or 1GB board, memory exhaustion stops sshd being able to fork a session process. The connection is accepted and then closed immediately, before any banner:

kex_exchange_identification: Connection closed by remote host

The giveaway is that the board is otherwise healthy — ping is clean and the web UI still responds — but nothing that needs to start a new process works, and the panel is usually dark. Only a power cycle clears it. See LOW_MEMORY_BOARDS.md.

4. Reboot After Installation

If the script reboots the Pi (which it recommends), network services may restart in a different state, potentially triggering AP mode.

How to Regain SSH Access

  1. Find the AP Network:

    • Look for a WiFi network named LEDMatrix-Setup on your phone/computer
    • It is an open network: no password
  2. Connect to the AP:

    • Connect your device to the LEDMatrix-Setup network
    • The Pi will have IP address: 192.168.4.1
  3. SSH via AP Mode:

    ssh ledpi@192.168.4.1
    
  4. Disable AP Mode and Reconnect to WiFi: Once connected via SSH:

    # Check WiFi status
    nmcli device status
    
    # Disable AP mode manually
    sudo systemctl stop hostapd
    sudo systemctl stop dnsmasq
    
    # Connect to your WiFi network (replace with your SSID and password)
    sudo nmcli device wifi connect "YourWiFiSSID" password "YourPassword"
    
    # Or use the web interface at http://192.168.4.1:5000
    # Navigate to WiFi tab and connect to your network
    

Option 2: Disable WiFi Monitor Service Temporarily

If you have physical access to the Pi or can connect via AP mode:

# Stop the WiFi monitor service
sudo systemctl stop ledmatrix-wifi-monitor

# Disable it from starting on boot (optional)
sudo systemctl disable ledmatrix-wifi-monitor

# Stop AP mode services
sudo systemctl stop hostapd
sudo systemctl stop dnsmasq

# Reconnect to your WiFi network
sudo nmcli device wifi connect "YourWiFiSSID" password "YourPassword"

Option 3: Use Ethernet Connection

If your Pi is connected via Ethernet:

  • SSH should remain available via Ethernet even if WiFi is in AP mode
  • Connect via: ssh ledpi@<pi-ip-address>

Option 4: Physical Access

If you have physical access to the Pi:

  1. Connect a keyboard and monitor
  2. Log in locally
  3. Follow Option 2 to disable AP mode and reconnect to WiFi

Preventing SSH Loss in the Future

Method 1: Configure WiFi Before Installation

Before running first_time_install.sh, ensure WiFi is properly configured and connected:

# Check WiFi status
nmcli device status

# If not connected, connect to WiFi
sudo nmcli device wifi connect "YourWiFiSSID" password "YourPassword"

# Verify connection
ping -c 3 8.8.8.8

Method 2: Disable WiFi Monitor Service

If you don't need the WiFi setup feature:

# After installation, disable the WiFi monitor service
sudo systemctl stop ledmatrix-wifi-monitor
sudo systemctl disable ledmatrix-wifi-monitor

Method 3: Configure WiFi Monitor to Not Auto-Enable AP

Turn off auto_enable_ap_mode so the monitor never starts AP mode on its own (you can still enable AP mode by hand). Either switch off Auto-Enable AP Mode in the web interface's WiFi tab, or use the API:

curl -X POST http://<pi-ip-address>:5000/api/v3/wifi/ap/auto-enable \
  -H "Content-Type: application/json" \
  -d '{"auto_enable_ap_mode": false}'

Or set "auto_enable_ap_mode": false in config/wifi_config.json by hand. The monitor daemon reads wifi_config.json when it starts, so whichever way you change the setting, restart it afterwards:

sudo systemctl restart ledmatrix-wifi-monitor

Verification Steps

After regaining SSH access, verify your installation:

cd ~/LEDMatrix   # wherever you installed LEDMatrix
./scripts/verify_installation.sh

This script will check:

  • Systemd services status
  • Python dependencies
  • Configuration files
  • File permissions
  • Web interface availability (ledmatrix-web listening on port 5000)
  • Network connectivity

Once it passes, the web interface is at http://<pi-ip>:5000.

Quick Reference Commands

# Check WiFi status
nmcli device status
nmcli device wifi list

# Check AP mode status
sudo systemctl status hostapd
sudo systemctl status dnsmasq

# Check WiFi monitor service
sudo systemctl status ledmatrix-wifi-monitor

# View WiFi monitor logs
sudo journalctl -u ledmatrix-wifi-monitor -f

# Connect to WiFi
sudo nmcli device wifi connect "SSID" password "password"

# Disable AP mode
sudo systemctl stop hostapd dnsmasq

# Restart network services
sudo systemctl restart NetworkManager

Web Interface Access

Even if SSH is unavailable, you can access the web interface:

  1. Via AP Mode: Connect to LEDMatrix-Setup network and visit http://192.168.4.1:5000
  2. Via WiFi: If WiFi is connected, visit http://<pi-ip-address>:5000
  3. Via Ethernet: Visit http://<pi-ip-address>:5000

The web interface allows you to:

  • Configure WiFi connections
  • Enable/disable AP mode
  • Check service status
  • View logs
  • Manage the LED Matrix display

Summary

SSH becomes unavailable because — two unrelated causes, and they need different responses:

AP mode (most common):

  • WiFi monitor service enables AP mode when WiFi disconnects
  • AP mode switches WiFi from client to access point mode
  • Pi loses connection to your original network

Memory exhaustion (low-memory boards):

  • The board runs out of memory, so sshd cannot fork a session process
  • The connection is accepted and closed before any banner
  • Ping still answers and the web UI still responds, so it looks healthy
  • The panel is usually dark and the service cannot restart
  • Only a power cycle clears this — there is no remote recovery, because every remote route needs a new process
  • Prevention and tuning: LOW_MEMORY_BOARDS.md

To regain SSH:

  1. Connect to LEDMatrix-Setup AP network (open, no password)
  2. SSH to 192.168.4.1
  3. Disable AP mode and reconnect to your WiFi network
  4. Or disable the WiFi monitor service if not needed

To prevent future issues:

  • Ensure WiFi is connected before installation
  • Or disable WiFi monitor service if you don't need AP mode feature