Files
sfmacro/README.md

4.2 KiB

sfmacro-client

sfmacro-client is a Node.js server that acts as a bridge between a custom Raspberry Pi Pico-based Macropad and your computer. It listens for physical button presses on the Pico over a USB Serial connection and executes corresponding configurable macros (such as simulating key presses, running commands, or toggling application audio). It also controls the RGB LEDs on the Macropad based on the button state or system metrics (e.g., CPU load).

How It Works

The architecture consists of three main components:

  1. Hardware (Raspberry Pi Pico)

    • The Pico is connected via USB and communicates over a Serial port.
    • It sends serial messages when buttons are pressed (P,<id>) and released (R,<id>).
    • It receives serial messages to set the RGB LED color for each button (C,<id>,<r>,<g>,<b>).
  2. Node.js Server (server.js)

    • The server auto-detects the connected Pico (by its Vendor ID 2E8A) and maintains the serial connection.
    • It stores the configuration in config.json.
    • When a button press is detected, it triggers the configured action:
      • key: Uses the @nut-tree-fork/nut-js library to simulate keyboard keystrokes or complex keyboard combos (e.g., LeftControl + G).
      • cmd: Runs arbitrary system commands using Node's child_process.exec.
      • mute_app: Toggles the mute state of specific applications (like firefox.exe) using the included SoundVolumeView.exe utility.
      • cpu_monitor: Instead of triggering an action, a button assigned this action will constantly have its LED color updated based on the host computer's current CPU utilization (Green -> Yellow -> Orange -> Red) by polling with the systeminformation library.
    • It hosts a local REST API and web server on port 3001 to allow configuration changes via a frontend UI.
  3. Web Interface (ui/ folder)

    • A Vite/React-based frontend is bundled into the ui/dist folder and served by the Node application.
    • It allows the user to easily configure each of the 16 buttons, setting their action type, command/key, idle LED color, and pressed LED color.

Starting the Server

There are a few ways to launch the software depending on your needs:

  • Interactive Mode (Windows) (Start-Macropad.bat): Starts the Node.js server, displays the console output, and automatically opens your default web browser to the http://localhost:3001 configuration page.
  • Background Mode (Windows) (Run-Hidden.vbs): Silently launches the Node server in the background without opening a visible command prompt window. This is ideal for adding to your Windows Startup folder for seamless background operation.
  • Linux Mode (start-macropad.sh): Starts the Node.js server and automatically opens the configuration page in your default browser.

Linux Installation & Prerequisites

To run the application on Linux (e.g., Ubuntu/Debian), perform the following configuration steps:

1. Serial Port Permissions

By default, Linux limits access to serial devices (like /dev/ttyACM0). Give your user account permission to access the Pico serial port by running:

sudo usermod -a -G dialout $USER

Note: You must log out and log back in (or reboot) for this change to take effect.

2. Keyboard Simulation Dependencies (nut-js)

The keyboard simulation library requires the development header for libXtst and requires an X11 / XWayland environment (native Wayland will block synthetic input):

sudo apt-get update
sudo apt-get install libxtst-dev

3. Launching

Make the script executable and run it:

chmod +x start-macropad.sh
./start-macropad.sh

Configuration

Configuration is saved automatically to config.json when updated via the web interface.

Each of the 16 buttons has the following properties:

  • actionType: Can be "key", "cmd", "mute_app", "cpu_monitor", or "none".
  • key: The keystroke combination to send (e.g., F20 or LeftControl + G). Used for the key action type.
  • cmd: The command to execute or executable to mute. Used for the cmd and mute_app action types.
  • color: The default RGB LED color when the button is idle.
  • pressedColor: The RGB LED color when the button is actively pressed down.