Skip to content

Turn a vintage stereo tuner into a Plex music streaming device

Notifications You must be signed in to change notification settings

johnsylvain/plex-tuner

Repository files navigation

Plex Tuner - Yamaha T-420 Front Panel Controller

A Python application that maps button presses from a Yamaha T-420 tuner's front panel (via TCA8418 I2C matrix) to Plexamp playback actions. Includes a web-based configuration interface for managing presets and a 1602A LCD display for showing now-playing information.

App UI Screenshot

Features

  • Hardware Integration: Reads button presses from TCA8418 I2C keypad matrix
  • LCD Display: 1602A LCD via I2C shows now-playing information with marquee scrolling
  • Plexamp Control: Controls Plexamp playback via HTTP API
  • Web Configuration UI: Flask-based web interface at http://localhost:5000 for managing presets
  • Preset Management: Save and load 8 presets (artists, albums, playlists, tracks)
  • Now Playing Display: Real-time track information (song - artist - album) with automatic scrolling
  • Preset Feedback: LCD displays preset name when activated

Prerequisites

  • Python 3.7 or higher
  • Raspberry Pi or Linux system with I2C support
  • TCA8418 I2C keypad matrix connected to I2C bus 1 at address 0x34
  • 1602A LCD with PCF8574 I2C backpack (optional, but recommended)
  • Plexamp running and accessible on your network
  • Plex server with music library

Hardware Setup

TCA8418 Keypad Matrix

  1. Connect the TCA8418 to your Raspberry Pi:
    • SDA → GPIO 2 (Pin 3)
    • SCL → GPIO 3 (Pin 5)
    • VCC → 3.3V
    • GND → Ground

1602A LCD Display (Optional)

  1. Connect the 1602A LCD with PCF8574 I2C backpack to your Raspberry Pi:

    • SDA → GPIO 2 (Pin 3) - shared with TCA8418
    • SCL → GPIO 3 (Pin 5) - shared with TCA8418
    • VCC → 5V (Pin 2 or 4)
    • GND → Ground

    Note: The LCD and TCA8418 can share the same I2C bus since they use different addresses.

    How I2C Addressing Works: Each I2C device has a unique, hardware-determined address:

    • TCA8418: Always uses address 0x34 (fixed by the chip design)
    • PCF8574 (LCD backpack): Uses 0x27 or 0x3F (determined by address pins A0/A1/A2 on the chip)

    The software automatically identifies devices by their addresses - you don't need to configure which address is which. When the code communicates with address 0x34, it's talking to the TCA8418. When it uses 0x27 or 0x3F, it's talking to the LCD.

  2. Enable I2C on Raspberry Pi:

    sudo raspi-config
    # Navigate to: Interface Options → I2C → Enable
  3. Verify I2C connections:

    sudo apt-get install i2c-tools
    sudo i2cdetect -y 1
    # Should show:
    # - TCA8418 at address 0x34
    # - LCD at address 0x27 or 0x3F (depending on your module)

    The LCD address is automatically detected by the application. Common addresses are:

    • 0x27 - Most common PCF8574 backpack address (A0/A1/A2 pins connected to GND)
    • 0x3F - Alternative PCF8574 backpack address (varies by manufacturer/module)

    Important: If you have multiple PCF8574 modules, you can change their addresses by connecting the A0, A1, A2 pins differently (see PCF8574 datasheet). However, for this project, we only need one LCD, so the default address is fine.

Installation

Option 1: Using the Setup Script (Recommended)

Run the automated setup script:

chmod +x setup.sh
./setup.sh

This will:

  • Create a Python virtual environment
  • Install all dependencies
  • Set up the project structure

Option 2: Manual Setup

  1. Create a virtual environment:

    python3 -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
  2. Install dependencies:

    pip install -r requirements.txt
  3. Install system dependencies (for I2C on Raspberry Pi):

    sudo apt-get update
    sudo apt-get install python3-dev i2c-tools

Configuration

Before running the application, you need to configure Plex connection settings. The code currently references several variables that need to be set:

  • PLEX_SERVER_URL: Your Plex server URL (e.g., https://your-plex-server.com)
  • PLEX_TOKEN: Your Plex authentication token
  • PLEX_MACHINE_ID: Your Plex server machine identifier
  • MUSIC_SECTION_ID: Your Plex music library section ID
  • PLEX_DEVICE_NAME: Device name for Plex API calls
  • PLEXAMP_BASE_URL: Plexamp base URL (e.g., http://192.168.68.92:32500)

Note: You may need to add these as environment variables or modify plex_tuner.py to include them. Consider creating a .env file or config.py for these settings.

Finding Your Plex Token

  1. Log into your Plex server web interface
  2. Open browser developer tools (F12)
  3. Go to Network tab
  4. Make a request in Plex web UI
  5. Look for requests containing X-Plex-Token in headers
  6. Copy the token value

Finding Your Plex Machine ID

Check your Plex server's Preferences.xml file or use the Plex API.

Usage

Manual Run

  1. Activate the virtual environment:

    source venv/bin/activate  # On Windows: venv\Scripts\activate
  2. Run the application:

    python3 plex_tuner.py

    Or use the convenience script:

    ./run.sh
  3. Access the web configuration UI:

    Open your browser and navigate to:

    http://localhost:8888
    

    (Port may vary - check the console output)

Run at Boot (Raspberry Pi)

To automatically start the application when the Raspberry Pi boots:

  1. Install the systemd service:

    sudo ./install-service.sh
  2. The service will:

    • Start automatically on boot
    • Restart automatically if it crashes
    • Log output to systemd journal
  3. Service management:

    # Start the service
    sudo systemctl start plex-tuner
    
    # Stop the service
    sudo systemctl stop plex-tuner
    
    # Restart the service
    sudo systemctl restart plex-tuner
    
    # Check service status
    sudo systemctl status plex-tuner
    
    # View logs
    sudo journalctl -u plex-tuner -f
    
    # Disable auto-start at boot (keeps service installed)
    sudo systemctl disable plex-tuner
    
    # Uninstall the service completely
    sudo ./uninstall-service.sh
  4. Configure presets:

    • Use the search box to find artists, albums, playlists, or tracks
    • Select a preset number (1-8)
    • Click on a search result to assign it to that preset
    • Presets are automatically saved to presets.json
  5. Use the hardware buttons:

    • Press the configured buttons on your T-420 front panel
    • The application will trigger the corresponding Plexamp actions

LCD Display Features

The LCD display (if connected) provides visual feedback:

  • Now Playing Display:

    • Top row shows: "song - artist - album"
    • Automatically scrolls (marquee) if text is longer than 16 characters
    • Updates every 3 seconds with current playback information
    • Shows "No signal" when nothing is playing
  • Preset Feedback:

    • When a preset is activated (via hardware button or web UI), the LCD displays the preset name
    • Preset name is shown for 3 seconds, then returns to now-playing display
    • Format: "Preset: [name]"
  • Graceful Degradation:

    • If the LCD is not connected, the application continues to work normally
    • All functionality remains available via the web UI

Project Structure

plex-tuner/
├── plex_tuner.py          # Main application file
├── requirements.txt       # Python dependencies
├── setup.sh              # Automated setup script
├── run.sh                # Convenience script to run the app
├── install-service.sh    # Install systemd service for auto-start
├── uninstall-service.sh  # Remove systemd service
├── plex-tuner.service    # Systemd service file
├── README.md             # This file
├── presets.json          # Preset configuration (auto-generated)
└── public/
    └── index.html        # Web UI template

Troubleshooting

I2C Connection Issues

  • Verify I2C is enabled: sudo i2cdetect -y 1
  • Check device addresses:
    • TCA8418 should be at 0x34
    • LCD should be at 0x27 or 0x3F
  • Ensure proper wiring and power supply
  • LCD requires 5V power (not 3.3V like TCA8418)

LCD Display Issues

  • LCD not detected:

    • Check wiring connections (SDA, SCL, VCC, GND)
    • Verify LCD is powered (5V)
    • Run sudo i2cdetect -y 1 to see if LCD appears at 0x27 or 0x3F
    • Application will continue to work without LCD (graceful degradation)
  • LCD shows garbled text:

    • Check contrast potentiometer on LCD module (if present)
    • Verify I2C address is correct (check console output for detected address)
    • Try power cycling the LCD module
  • Text not scrolling:

    • Marquee scrolling only activates when text exceeds 16 characters
    • Short text will be displayed statically

Plex Connection Issues

  • Verify Plexamp is running and accessible
  • Check network connectivity to Plex server
  • Verify Plex token is valid and has proper permissions
  • Check firewall settings

Import Errors

  • Ensure virtual environment is activated
  • Reinstall dependencies: pip install -r requirements.txt
  • For smbus2 on Raspberry Pi, ensure python3-dev is installed

Development

Modifying Button Mappings

To modify button mappings, edit the KEYMAP dictionary in plex_tuner/hardware/tca8418.py:

KEYMAP = {
    (row, col): "action_name",
    # ...
}

LCD Configuration

LCD settings can be modified in plex_tuner/hardware/lcd1602.py:

  • LCD_I2C_BUS: I2C bus number (default: 1)
  • LCD_I2C_ADDRESSES: List of addresses to try (default: [0x27, 0x3F])
  • Marquee scroll speed: Adjust marquee_update_interval in LCDDisplay class
  • Preset display duration: Modify duration parameter in show_preset() calls

License

[Add your license here]

Contributing

[Add contribution guidelines here]

About

Turn a vintage stereo tuner into a Plex music streaming device

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published