Skip to content

spiercey/plexamp-control-listener

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Plexamp Control Listener 🎛️

A lightweight Python service that lets external hardware controllers (like microcontrollers or button boxes) send simple playback commands to a Plexamp headless instance.

The control listener reads serial commands from connected devices (e.g., Arduino, RP2040, ESP32) over USB and translates them into Plexamp HTTP API calls — letting you control playback, skip tracks, and adjust volume from physical buttons or other input sources.


Features

  • Controls Plexamp headless through its local HTTP API (http://127.0.0.1:32500)
  • Listens for commands over a serial interface (/dev/ttyACM*)
  • Basic playback controls:
    • PLAY
    • PAUSE
    • NEXT
    • PREVIOUS
  • Volume control:
    • VOL_UP
    • VOL_DOWN
  • Automatically reconnects if the serial device is unplugged or lost
  • Runs as a systemd service for continuous background operation

Requirements

  • Linux device running Plexamp headless
  • Python 3.8 or newer
  • USB-connected microcontroller that sends simple newline-terminated serial messages (examples below)
  • curl available on the host (used by the Python script to call local Plexamp endpoints)
  • Assumes the running user is the default pi user. Update plexamp-control.service with a different user before install if you are using a different user.

Installation

Clone the repository to your Plexamp device (or copy the files there), then run the included installer:

git clone https://github.com/<yourusername>/plexamp-control-listener.git
cd plexamp-control-listener
chmod +x install.sh
./install.sh

What install.sh does:

  1. Creates a Python virtual environment (if missing).
  2. Installs pyserial into the venv.
  3. Patches the systemd service to use the venv's python.
  4. Copies the patched service to /etc/systemd/system/.
  5. Enables and starts plexamp-control.service.

After install, view logs with:

journalctl -fu plexamp-control.service

Configuration

Edit plexamp-control.py to tune behavior and endpoints. Key variables at the top of the file:

BAUD_RATE = 115200
PLEXAMP_HOST = "http://127.0.0.1:32500"

COMMANDS = {
    "PLAY": f"curl -s {PLEXAMP_HOST}/player/playback/play",
    "PAUSE": f"curl -s {PLEXAMP_HOST}/player/playback/pause",
    "NEXT": f"curl -s {PLEXAMP_HOST}/player/playback/skipNext",
    "PREVIOUS": f"curl -s {PLEXAMP_HOST}/player/playback/skipPrevious",
}

VOLUME_STEP = 5
MIN_VOLUME = 0
MAX_VOLUME = 100
VOLUME_REFRESH_SEC = 30

How It Works

  1. The service finds a serial device by scanning /dev/ttyACM*.
  2. It opens the serial port and reads newline-terminated text lines.
  3. Each received line (e.g. PLAY) is mapped to a shell curl command sent to Plexamp's local HTTP endpoint.
  4. Volume commands fetch/update current volume using the Plexamp timeline XML endpoint and call the setParameters API to change volume.

Example Serial Commands

Send any of these (each on its own line):

PLAY
PAUSE
NEXT
PREVIOUS
VOL_UP
VOL_DOWN

Example RP2040 Circuit Python program

import board
import digitalio
import time
#import usb_cdc

#print(dir(board))

# Button pin setup
buttons = {
    "PLAY": board.GP27,
    "PAUSE": board.GP26,
    "NEXT": board.GP15,
    "PREVIOUS": board.GP14,
    "VOL_UP": board.GP13,
    "VOL_DOWN": board.GP12,
}

# Configure pins
button_inputs = {}
button_states = {}

for name, pin in buttons.items():
    btn = digitalio.DigitalInOut(pin)
    btn.direction = digitalio.Direction.INPUT
    btn.pull = digitalio.Pull.UP
    button_inputs[name] = btn
    button_states[name] = False  # debounce state

while True:
    for name, btn in button_inputs.items():
        if not btn.value and not button_states[name]:
            # Button just pressed
            print(name)
            #usb_cdc.data.write((name + "\n").encode())
            button_states[name] = True
        elif btn.value and button_states[name]:
            # Button released
            button_states[name] = False

    time.sleep(0.05)  # debounce delay

Monitoring & Logs

systemctl status plexamp-control.service
sudo journalctl -f -u plexamp-control.service
sudo systemctl restart plexamp-control.service
sudo systemctl disable plexamp-control.service

Troubleshooting

  • No serial device found: Check with ls /dev/ttyACM* /dev/ttyUSB*
  • Permission errors: Add user to dialout: sudo usermod -a -G dialout $USER
  • Volume not changing: Confirm Plexamp is reachable at PLEXAMP_HOST
  • Service won't start: Run sudo journalctl -u plexamp-control.service -xe

About

A service that will listen over usb for commands to control plexamp headless. It allows play, pause, previous track, next track, and VOL Up/Down.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages