Skip to main content

Python library for WiiM/LinkPlay device communication

Project description

pywiim

Python library for WiiM and LinkPlay device control with command-line tools for discovery, diagnostics, and monitoring.

CI Security codecov PyPI version Python 3.11+ License: MIT

Code style: black Type checking: mypy Linting: ruff

Overview

pywiim provides control of WiiM and LinkPlay-based audio devices through a Python API and command-line tools. The library handles playback control, volume management, multiroom audio, EQ settings, presets, and more.

Key Features

  • MCP Server - Expose WiiM control to Cursor, Claude Desktop, and other MCP hosts. pip install pywiim[mcp] then wiim-mcp. Control playback, volume, and more via AI assistants.
  • Playback Control - Play, pause, stop, next/previous track, seek
  • Volume & Audio - Volume control, mute, channel balance, audio output selection (Line Out, Optical, Coax, USB Out, HDMI Out, Bluetooth/Headphones)
  • Sources - Intelligent model-specific source management (Bluetooth, Line In, Optical In, Coaxial, USB, HDMI ARC, Phono) and streaming services. Authoritative hardware filtering and UI-ready formatting.
  • Source Catalog - Structured source metadata via player.source_catalog (source type, selectability, and per-source capability flags) for integrations like Music Assistant.
  • Multiroom Audio - Create/join/leave groups, synchronized volume and playback
  • EQ & Presets - 10-band EQ with presets, 20 preset stations; Parametric EQ (PEQ) on WiiM (10-band per-source, stereo/L-R, presets; see [PR #12]
  • Timers & Alarms - Sleep timers and alarm clocks (WiiM devices)
  • State Synchronization - UPnP events with HTTP polling fallback
  • Device Discovery - SSDP/UPnP discovery with network scanning fallback
  • Multi-vendor Support - WiiM, Arylic, Audio Pro, and generic LinkPlay devices

Device Compatibility:

  • All LinkPlay devices: Core playback, volume, sources, multiroom, presets
  • Device-dependent features: EQ support (varies by device)
  • WiiM devices only: Alarm clocks, sleep timers, audio output mode selection, and Parametric EQ (PEQ) (LV2 PEQ API)

The library automatically detects device capabilities and adapts functionality accordingly.

Installation

Install pywiim to use the command-line tools for discovering, testing, and monitoring your WiiM/LinkPlay devices, or to use the Python library in your projects.

Prerequisites

  • Python 3.11 or later
  • pip (usually included with Python)

Installing Python:

  • Linux/macOS: Usually pre-installed. If not, use your package manager or download from python.org
  • Windows: Download from python.org and check "Add Python to PATH" during installation

Install pywiim

pip install pywiim

The CLI tools (wiim-discover, wiim-diagnostics, wiim-monitor, wiim-verify) are automatically installed and available in your PATH.

Verify installation:

wiim-discover --help

Note for Windows users: If the commands are not found after installation, ensure Python's Scripts directory is in your PATH (usually C:\Users\YourName\AppData\Local\Programs\Python\Python3X\Scripts), or restart your terminal.

Command-Line Tools

The library includes four powerful CLI tools that are automatically installed with pywiim. These tools provide an easy way to discover, diagnose, monitor, and test your WiiM/LinkPlay devices without writing any code.

Quick Start

  1. Discover devices on your network:

    wiim-discover
    
  2. Test a device (replace 192.168.1.100 with your device IP):

    wiim-verify 192.168.1.100
    
  3. Monitor a device in real-time:

    wiim-monitor 192.168.1.100
    
  4. Run diagnostics:

    wiim-diagnostics 192.168.1.100
    

1. Device Discovery (wiim-discover)

Discover all WiiM/LinkPlay devices on your network using SSDP/UPnP or network scanning.

What it does:

  • Automatically finds all WiiM and LinkPlay-based devices on your local network
  • Validates discovered devices by testing their API
  • Displays device information (name, model, firmware, IP, MAC, UUID)
  • Supports multiple discovery methods for maximum compatibility

Usage:

# Basic discovery (SSDP/UPnP)
wiim-discover

# Output as JSON (useful for scripting)
wiim-discover --output json

# Skip API validation (faster, less detailed)
wiim-discover --no-validate

# Verbose logging
wiim-discover --verbose

# Custom SSDP timeout
wiim-discover --ssdp-timeout 10

Options:

  • --ssdp-timeout <seconds> - SSDP discovery timeout (default: 5)
  • --no-validate - Skip API validation of discovered devices
  • --output <text|json> - Output format (default: text)
  • --verbose, -v - Enable verbose logging

Example Output:

🔍 Discovering WiiM/LinkPlay devices via SSDP...

Device: WiiM Mini
  IP Address: 192.168.1.100:80
  Protocol: HTTP
  Model: WiiM Mini
  Firmware: 4.8.123456
  MAC Address: AA:BB:CC:DD:EE:FF
  UUID: 12345678-1234-1234-1234-123456789abc
  Vendor: WiiM
  Discovered via: SSDP
  Status: Validated ✓

See Discovery Documentation for more information.

2. Diagnostic Tool (wiim-diagnostics)

Comprehensive diagnostic tool for troubleshooting device issues and gathering information for support.

What it does:

  • Gathers complete device information (model, firmware, MAC, UUID, capabilities)
  • Includes UPnP description.xml capability enrichment (advertised services like PlayQueue/QPlay)
  • Tests all API endpoints to verify functionality
  • Tests feature support (presets, EQ, multiroom, Bluetooth, etc.)
  • Generates detailed JSON reports for sharing with developers
  • Identifies errors and warnings

Usage:

# Basic diagnostic
wiim-diagnostics 192.168.1.100

# Save report to file (for sharing with support)
wiim-diagnostics 192.168.1.100 --output report.json

# HTTPS device
wiim-diagnostics 192.168.1.100 --port 443

# Verbose output
wiim-diagnostics 192.168.1.100 --verbose

Options:

  • <device_ip> - Device IP address or hostname (required)
  • --port <port> - Device port (default: 80, use 443 for HTTPS)
  • --output <file> - Save report to JSON file
  • --verbose - Enable detailed logging

What it tests:

  • Device information retrieval
  • Capability detection
  • All status endpoints
  • Feature support detection
  • API endpoint availability
  • Error conditions

Example Output:

🔍 Starting comprehensive device diagnostic...
   Device: 192.168.1.100:80

📋 Gathering device information...
   ✓ Device: WiiM Mini (WiiM Mini)
   ✓ Firmware: 4.8.123456
   ✓ MAC: AA:BB:CC:DD:EE:FF

🔧 Detecting device capabilities...
   ✓ Vendor: WiiM
   ✓ Device Type: WiiM
   ✓ Supports EQ: Yes
   ✓ Supports Presets: Yes
   ...

See Diagnostics Documentation for more information.

3. Real-time Monitor (wiim-monitor)

Monitor your device in real-time with adaptive polling and UPnP event support.

What it does:

  • Displays live device status with automatic updates
  • Uses UPnP events for instant updates when available
  • Falls back to adaptive HTTP polling
  • Shows play state, volume, mute, track info, and playback position
  • Displays device role in multiroom groups
  • Tracks statistics (poll count, state changes, UPnP events)

Usage:

# Basic monitoring
wiim-monitor 192.168.1.100

# Specify callback host for UPnP (if auto-detection fails)
wiim-monitor 192.168.1.100 --callback-host 192.168.1.254

# Verbose logging
wiim-monitor 192.168.1.100 --verbose

# Custom log level
wiim-monitor 192.168.1.100 --log-level DEBUG

# Verbose UPnP event logging (shows full event JSON/XML)
wiim-monitor 192.168.1.100 --upnp-verbose

Options:

  • <device_ip> - Device IP address or hostname (required)
  • --callback-host <ip> - Override UPnP callback host (auto-detected by default)
  • --verbose, -v - Enable verbose logging
  • --log-level <level> - Set log level (DEBUG, INFO, WARNING, ERROR)
  • --upnp-verbose - Enable verbose UPnP event logging (shows full event JSON/XML data)

What it displays:

  • Play state (playing, paused, stopped)
  • Volume level and mute status
  • Current track (title, artist, album)
  • Playback position and duration
  • Device role (solo/master/slave)
  • Group information (if in a group)
  • Update source (polling or UPnP event)
  • Statistics on exit

Example Output:

🎵 Monitoring WiiM Mini (192.168.1.100)...
   UPnP: Enabled ✓ (events: 0)
   Polling: Adaptive (interval: 2.0s)

📊 Status:
   State: playing
   Volume: 50% (muted: No)
   Source: wifi
   Role: solo

🎶 Track:
   Title: Song Title
   Artist: Artist Name
   Album: Album Name
   Position: 1:23 / 3:45

[UPnP] State changed: volume → 55%

Press Ctrl+C to stop monitoring and view statistics.

4. Feature Verification (wiim-verify)

Comprehensive testing tool that verifies all device features and endpoints with safety constraints.

What it does:

  • Tests all playback controls (play, pause, stop, next, previous)
  • Tests volume controls (safely, never exceeds 10%)
  • Tests source switching
  • Tests audio output modes
  • Tests EQ controls (if supported)
  • Tests group operations (if applicable)
  • Tests preset playback
  • Tests all status endpoints
  • Saves and restores original device state
  • Generates detailed test report

Usage:

# Basic verification
wiim-verify 192.168.1.100

# Verbose output (shows detailed test data)
wiim-verify 192.168.1.100 --verbose

# HTTPS device
wiim-verify 192.168.1.100 --port 443

Options:

  • <device_ip> - Device IP address or hostname (required)
  • --port <port> - Device port (default: 80, use 443 for HTTPS)
  • --verbose, -v - Enable verbose output (shows detailed test data)

Safety Features:

  • Volume never exceeds 10% during testing
  • Original device state is saved and restored
  • Non-destructive testing (doesn't disrupt normal use)
  • Graceful error handling

What it tests:

  • Status endpoints (get_player_status, get_device_info, etc.)
  • Playback controls (play, pause, resume, stop, next, previous)
  • Volume controls (set_volume, set_mute)
  • Source controls (set_source, get_source)
  • Audio output controls (set_audio_output_mode)
  • EQ controls (get_eq, set_eq_preset, set_eq_custom, etc.)
  • Group operations (create_group, join_group, leave_group)
  • Preset operations (play_preset)
  • And more...

Example Output:

💾 Saving original device state...
   ✓ Volume: 0.5
   ✓ Mute: False
   ✓ Source: wifi
   ✓ Play state: playing

📊 Testing Status Endpoints...
   ✓ get_player_status
   ✓ get_player_status_model
   ✓ get_meta_info

▶️  Testing Playback Controls...
   ✓ play
   ✓ pause
   ✓ resume
   ✓ stop
   ✓ next_track
   ✓ previous_track

🔊 Testing Volume Controls (max 10%)...
   ✓ set_volume (5%)
   ✓ set_volume (10%)
   ✓ set_mute (True)
   ✓ set_mute (False)

...

🔄 Restoring original device state...
   ✓ Volume restored
   ✓ Mute restored
   ✓ Source restored

============================================================
Total tests: 45
✅ Passed: 42
❌ Failed: 0
⊘ Skipped: 3

Exit Codes:

  • 0 - All tests passed
  • 1 - One or more tests failed or interrupted

MCP Server (wiim-mcp)

Expose WiiM/LinkPlay control as an MCP (Model Context Protocol) server for use with Cursor, Claude Desktop, and other MCP hosts.

Install:

pip install pywiim[mcp]

Run:

wiim-mcp
# or
python -m pywiim.mcp

Config (config file or env vars; env overrides file):

Config file: ~/.config/wiim/config.json (or WIIM_CONFIG_FILE to override path). Copy from example:

mkdir -p ~/.config/wiim
cp $(python -c "import pywiim.mcp, os; print(os.path.join(os.path.dirname(pywiim.mcp.__file__), 'config.example.json'))") ~/.config/wiim/config.json

Edit with your device IPs (e.g. 192.168.1.115, 192.168.1.116, 192.168.1.68).

Config file keys: default_device, named_devices, discovery_disabled, timeout, discovery_timeout

Env vars (override file): WIIM_DEFAULT_DEVICE, WIIM_NAMED_DEVICES (JSON), WIIM_DISCOVERY_DISABLED, WIIM_TIMEOUT, WIIM_DISCOVERY_TIMEOUT, WIIM_CONFIG_FILE

WSL / discovery doesn't work? Set discovery_disabled: true in config and use pre-configured named_devices with your device IPs.

Tools: wiim_discover, wiim_status, wiim_play, wiim_pause, wiim_media_play_pause, wiim_stop, wiim_next_track, wiim_previous_track, wiim_volume, wiim_mute, wiim_unmute, wiim_sources, wiim_set_source, wiim_play_url, wiim_group_join, wiim_group_leave

Cursor config (add to MCP settings):

{
  "mcpServers": {
    "wiim": {
      "command": "wiim-mcp",
      "args": []
    }
  }
}

Claude Desktop config (claude_desktop_config.json):

{
  "mcpServers": {
    "wiim": {
      "command": "wiim-mcp",
      "args": []
    }
  }
}

Quick Start

import asyncio
from pywiim import Player

async def main():
    player = Player("192.168.1.100")
    await player.refresh()  # Load initial state
    
    # Access device properties
    print(f"Device: {player.name} ({player.model_name or player.model})")
    print(f"Playing: {player.play_state}")
    print(f"Volume: {player.volume}")
    
    # Control playback
    await player.set_volume(0.5)
    await player.play()
    
    await player.close()

asyncio.run(main())

See API Reference for complete Player API documentation.

Notification Playback Limitations

play_notification() uses a source-aware strategy so notifications are audible across more real-world scenarios:

  • Native prompt path (playPromptUrl) on device-controlled sources where firmware duck/resume is expected.
  • Fallback path (play_url) on unsupported or unknown sources to ensure audio is heard.
  • Returned result object reports what happened:
    • method_used: "prompt" or "play_url"
    • source_before: source observed before decision
    • likely_interrupted: True for fallback path
    • reason: optional fallback reason

Why this is needed

Some firmware/source combinations return OK for playPromptUrl but produce no audible prompt. In those cases, pywiim chooses fallback playback to prioritize audible notifications.

Practical limitations

  • Fallback playback is interruptive by design and may stop/replace the previous source session.
  • Unknown/unmapped sources default to fallback for reliability.
  • Native prompt behavior remains firmware-dependent even on documented-compatible sources.

Documentation

User Guides

Integration Guides

  • Home Assistant Integration - Complete guide for HA integrations
    • DataUpdateCoordinator patterns
    • Adaptive polling strategies
    • UPnP event integration
    • Queue management
    • Source-aware shuffle/repeat control
  • API Reference - Complete API documentation

Design Documentation

  • Architecture & Data Flow - System architecture
  • State Management - State synchronization patterns
  • Operation Patterns - Common operation patterns
  • LinkPlay Architecture - In-depth analysis of LinkPlay/WiiM streaming architecture
    • "Split Brain" control authority model
    • Transport protocol analysis (AirPlay, Spotify, USB, Bluetooth)
    • Hardware constraints (A98 SoM, RAM limits, queue management)
    • Why shuffle/repeat controls work differently for different sources
    • Integration strategies for automation systems

Development Setup

See SETUP.md for detailed development setup instructions.

Quick start:

# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest tests/unit/ -v

# Run code quality checks
make lint typecheck

Acknowledgments

This library was made possible by the work of many developers who have reverse-engineered and documented the WiiM/LinkPlay API. We would like to acknowledge the following projects and resources that provided valuable API information and implementation insights:

Libraries and Implementations

Official Documentation

Contributors and Notable Contributions

  • jeromeof – Full Parametric EQ (PEQ) API (PR #12): WiiM LV2 PEQ support (10-band per-source, stereo/L-R channel modes, preset save/load/delete/rename). Implemented with capability probing (supports_peq) and integration tests against real devices.

Additional Resources

  • Various GitHub repositories and community contributions that helped document the LinkPlay protocol and WiiM-specific enhancements
  • The LinkPlay and WiiM developer communities for sharing API discoveries and reverse-engineering efforts

If you know of other libraries or resources that should be acknowledged, please open an issue or submit a pull request.

License

MIT License

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pywiim-2.1.90.tar.gz (293.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pywiim-2.1.90-py3-none-any.whl (322.1 kB view details)

Uploaded Python 3

File details

Details for the file pywiim-2.1.90.tar.gz.

File metadata

  • Download URL: pywiim-2.1.90.tar.gz
  • Upload date:
  • Size: 293.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pywiim-2.1.90.tar.gz
Algorithm Hash digest
SHA256 9d6bcc83e86e50db8a7ab9ef0db1cdc14ef592d15f43caa8b58b10dfd152f744
MD5 ed482085571510c9c7139d2590cbd1f2
BLAKE2b-256 dfa4d01cfea494fa431f5f9d1fc0e6a48cad33366cd66282c8e38ceb4eb4aec9

See more details on using hashes here.

Provenance

The following attestation bundles were made for pywiim-2.1.90.tar.gz:

Publisher: publish.yml on mjcumming/pywiim

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pywiim-2.1.90-py3-none-any.whl.

File metadata

  • Download URL: pywiim-2.1.90-py3-none-any.whl
  • Upload date:
  • Size: 322.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pywiim-2.1.90-py3-none-any.whl
Algorithm Hash digest
SHA256 dd6d46dc144687e4ff896e7f4bd15fbb01bc92a4aa550265ca66c9ba7b3023db
MD5 d0f883363b27872462a1c610ba74b0dd
BLAKE2b-256 16d16f054c32c367ec4592d92a084c7ce87c6707ed165638e3283095f85874b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for pywiim-2.1.90-py3-none-any.whl:

Publisher: publish.yml on mjcumming/pywiim

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page