Skip to content

System Monitor display for Framework 16 LED Matrix input module

License

Notifications You must be signed in to change notification settings

MidnightJava/led-matrix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

125 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Framework 16 LED Matrix System Monitoring Application

This software is intended for use on a Framework 16 laptop with LED Matrix Panels installed. It's a clone of the LED System Monitor project, with certain modifications and extensions applied.

Compatibility

Hardware: Framework 16 laptops with LED Matrix Panels
Operating Systems: Linux distributions (Ubuntu, Fedora, NixOS, Debian, CentOS, RHEL, and others)
Dependencies: Python 3.7+ with numpy, psutil, pyserial, and evdev

Quick Start (install the app and run it as a service)

For most users, the fastest way to get started. This installs dependencies, builds the app, installs it as a service, and starts the service:

# Clone the repository
git clone <repository-url>
cd led-matrix-monitoring

# Run with automatic dependency installation
chmod +x build_and_install.sh
./build_and_install.sh
./dist/led_mon/led_mon #optionally run manually

The build_and_install.sh script will automatically detect your Linux distribution, install the required dependencies, build an executable file of the python application, and install it as a systemd service fwledmonitor.service.

Capabilities

  • Display system performance characteristics in real-time
    • CPU utilization
    • Battery charge level and plug status + memory utilization
    • Disk Input/Output rates
    • Network Upload/Download rates
    • Temperature sensor readings
    • Fan speeds
  • Other apps
    • Current weather or weather forecast
    • Time
    • Display patterns saved in snapshot json files
  • Display any system monitoring app on any quadrant
    • Top or bottom of left or right panel
    • Assign multiple apps to any quadrant and cycle throiugh them at specified time intervals
    • Turn on animation and define command arguments for apps
    • Specified via a yaml config file
  • Display a "snapshot" from specified json file(s) on either or both panels.
  • Keyboard shortcut ALT + I identifies apps running in each quadrant by displaying abbreviated name
  • Plugin framework supports simplified development of addiitonal LED Panel applications
  • Automatic detection of left and right LED panels
  • Automatic detection of keyboard device (for keyboard shortcut use)
  • Snapshot app
  • Plugin capability
  • Automatic device and keyboard detection

Import note about Python environments

Pep 668 provides a mechanism for a Python installation to communicate to tools such as Pip that the installation is externally managed. For Python installations that implement this notification, an attempt to install a package in the global context will be denied, with a message that the installation is externally managed. There are ways to override the PEP 668 constraint (such as using pipx or the --break-system-packages flag). The standard solution, however, is to use a Python Virtual Environment. See installation notes below for more information.

The build and installation instructions and scripts for this project assume that every Python installation action is done in a virtual environment. If you want to perform a global installation, it's up to you to make whatever changes are needed to make that work. Also, please note that a misconfigured virtual environment will result in either build-time or run-time failures. Generally, you should 1) Install package dependencies for the selected virtual environment tool 2) Install the tool 3) Configure the tool per instructions provided by the tool provider 3) Create a virtual environment and activate it 4) Ensure that the virtual environment is currently activated in any shell from which you perform a Python installation, whether launching python directly or invoking a build or installation script. The error message python: command not found is a likely indicator of a missing or misconfigured virtual environment.

Manual Installation (run the app from the command line in the foreground)

For Ubuntu/Debian users:

  • Install PyEnv or any other python virtual environment package
  • Commands below work with PyEnv:
sudo apt update
sudo apt install -y python3-numpy python3-psutil python3-serial python3-evdev python3-pynput python3-yaml python3-pip
cd led-matrix-monitoring
pyenv install 3.11 # or higher (tested up to 3.14)
pyenv virtualenv 3.11 led-matrix-env
pyenv activate led-matrix-env
python3 -m pip install -r requirements.txt
python3 led_system_monitor.py

For Fedora users:

sudo yum install -y python3-numpy python3-psutil python3-pyserial python3-evdev python3-pynput python3-pyyaml python3-pip
cd led-matrix-monitoring\
pyenv install 3.11 # or higher (tested up to 3.14)
pyenv virtualenv 3.11 led-matrix-env
pyenv activate led-matrix-env
python3 led_system_monitor.py

For NixOS users:

# Using the Nix flake (recommended)
nix run github:MidnightJava/led-matrix

# Or build locally
nix build
./result/bin/led-matrix-monitor

NixOS System Integration

For NixOS users who want to run LED matrix monitoring as a system service, additional configuration is required:

1. Add to your flake.nix inputs:

{
  inputs = {
    # ... other inputs
    led-matrix-monitoring.url = "github:MidnightJava/led-matrix";
  };
}

2. Import the module in your NixOS configuration:

{
  imports = [
    inputs.led-matrix-monitoring.nixosModules.led-matrix-monitoring
  ];
}

3. Enable and configure the service:

services.led-matrix-monitoring = {
  enable = true;
  topLeft = "cpu";
  bottomLeft = "mem-bat";
  topRight = "disk";
  bottomRight = "net";
  disableKeyListener = true;  # Recommended for system service
  user = "your-username";
};

4. Add systemd service environment override (Required):

The service needs access to the display server. Add this to your NixOS configuration:

# Override the LED matrix monitoring service to add DISPLAY environment variable
systemd.services.led-matrix-monitoring = {
  environment = {
    DISPLAY = ":0";  # Adjust if using different display
  };
  serviceConfig = {
    # Ensure the service waits for the graphical session
    After = [ "graphical-session.target" ];
    Wants = [ "graphical-session.target" ];
  };
};

5. Rebuild your system:

sudo nixos-rebuild switch

Troubleshooting NixOS Service Issues:

If the service fails to start with display connection errors:

# Check service status
systemctl status led-matrix-monitoring

# View logs
journalctl -u led-matrix-monitoring -f

# Common error: "failed to acquire X connection: Bad display name"
# Solution: Ensure DISPLAY environment variable is set in service override

Alternative: Systemd Service (Advanced)

For automated continuous execution, you can run as a systemd service instead:

# The service runs as system user led_mon (created by the script if needed)
./build_andOnstall.sh
# manage the service
systemctl start|stop|status fwledmatrix.service
# The service config file is at /etc/systemd/system/led_mon.service.
# The service executable is at /opt/led_mon/led_mon (sym-linked to /usr/local/bin/led_mon)

Required Permissions

LED Matrix Device Access

By default, LED Matrix devices appear as serial devices (e.g., /dev/ttyACM0, /dev/ttyACM1) that are typically owned by root with restricted permissions. To allow your user to access these devices, you have several options:

Option 1: Add User to dialout Group (Recommended for running under user account, not needed for service execution)

# Add your user to the dialout group
sudo usermod -a -G dialout $USER

# Log out and log back in, or use:
newgrp dialout

# Verify group membership
groups $USER

# This is done by install_service.sh for the led_mon system account that executes the service

Option 2: Create Custom udev Rules

Create a udev rule file to automatically set proper permissions:

# Create the udev rule file
sudo tee /etc/udev/rules.d/99-framework-led-matrix.rules <<EOF
# Framework 16 LED Matrix Input Modules
SUBSYSTEM=="tty", ATTRS{idVendor}=="32ac", ATTRS{idProduct}=="0020", MODE="0666", GROUP="dialout"
SUBSYSTEM=="usb", ATTRS{idVendor}=="32ac", ATTRS{idProduct}=="0020", MODE="0666", GROUP="dialout"
EOF

# Reload udev rules
sudo udevadm control --reload-rules
sudo udevadm trigger

Option 3: Run as Root (Not Recommended)

While running as root will bypass permission issues, this is not recommended for security reasons:

sudo python3 led_system_monitor.py

Keyboard Input Access (Optional)

For the Alt+I keyboard shortcut feature to work, the application needs read access to keyboard input devices:

# Add user to input group (be aware of security implications)
sudo usermod -a -G input $USER

# Log out and log back in, then verify
groups $USER

# This is done by install_servce.sh for the led_mon system account that executes the service

Security Note: Adding your user to the input group allows any program running as your user to potentially capture keystrokes. Consider the security implications before doing this, or do not add your user to the group, and use --no-key-listener to disable this feature.

Modifying the Apps Configuration

  • Look at the file config.yaml to see the default configuration, along with comments explaining the format and meaning of config setting.
  • Make a copy of config.yaml, named config-local.yaml, in the project main directory, if you want to customize your configuration. This file is git-ignored, so it will not be shared or overwritten.
  • If config-local.yaml is present, it will be thhe active config and config.yaml will be ignored.
  • When running as a service, both config files will be copied to /opt/led_mon/_internal/. Files in this directory will be completely overwritten for every installation, so you should maintain your local configuration in the project repo, not the application installation directory.
  • The config.yaml file may be updated when you run git pull in the repo. Check Pull Request comments for an explanation of what changed. Every effort will be made to avoid breaking changes, but they cannot be ruled out at this stage of dvelopment. When new widgets are added to the app, you'll need to manually copy the new widget config settings into your local config file if you have one.

Verifying Device Access

To check if your LED Matrix devices are properly accessible:

# List LED Matrix devices
ls -la /dev/ttyACM*

# Check if they're accessible by your user
python3 -c "from serial.tools import list_ports; [print(f'{p.device}: {p.description}') for p in list_ports.comports() if 'LED Matrix' in str(p)]"

Run from the command line

cd led-matrix
python -m led_mon.led_system_monitor [--help] [--no-key-listener] [--disable-plugins] [--list-apps]
python -m led_mon.led_system_monitor --help #For more verbose help info

Run as a Linux service

ENter the top-level project directory, and ensure that a virtual environment is configured and activated.

./build_and_install.sh
sudo systemctl start|stop|restart|status fwledmonitor

Keyboard Shortcut

  • Alt+I: displays app names in each quadrant while keys are pressed
  • Disable key listener with --no-key-listener program arg
  • To use the key listener, the app must have read permission on the keyboard device (e.g /dev/input/event7). The service runs under a system account that has the required access. If you want to use the key listener while running the app manually, you need to add your user account to the input group and ensure there is a group read permission on the keyboard device. NB: Consider the implications of this. Any program running as a user in the input group will be able to capture your keystrokes.

Plugin Development

  • Add a file in the plugins dir with a name that matches the blob pattern *_plugin.py
  • See temp_fan_plugin.py for an implementation example

Notes

>>> import evdev

>>> devices = [evdev.InputDevice(path) for path in evdev.list_devices()]
>>> for device in devices:
>>>     print(device.path, device.name, device.phys)
/dev/input/event1    Dell Dell USB Keyboard   usb-0000:00:12.1-2/input0
/dev/input/event0    Dell USB Optical Mouse   usb-0000:00:12.0-2/input0
  • The baseline reference for calculating the ratio used to display temperature and fan speed readings were arbitarily defined. See TEMP_REF and MAX_FAN_SPEED in temp_fan_plugin.py.
  • To examine system performance measures manually and in detail, run python ps-util-sensors.py
  • To use a different key combination for identifying the running apps, see KEY_I and MODIFIER_KEYS in led_system_monitor.py

About

System Monitor display for Framework 16 LED Matrix input module

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •