pywiim


Namepywiim JSON
Version 1.0.47 PyPI version JSON
download
home_pageNone
SummaryPython library for WiiM/LinkPlay device communication
upload_time2025-11-16 17:44:15
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseMIT
keywords wiim linkplay audio upnp streaming music async
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # pywiim

Python library for WiiM/LinkPlay device communication (HTTP API + UPnP).

[![CI](https://github.com/mjcumming/pywiim/actions/workflows/ci.yml/badge.svg)](https://github.com/mjcumming/pywiim/actions/workflows/ci.yml)
[![Security](https://github.com/mjcumming/pywiim/actions/workflows/security.yml/badge.svg)](https://github.com/mjcumming/pywiim/actions/workflows/security.yml)
[![PyPI version](https://badge.fury.io/py/pywiim.svg)](https://badge.fury.io/py/pywiim)
[![PyPI downloads](https://pepy.tech/badge/pywiim)](https://pepy.tech/project/pywiim)
[![PyPI downloads/week](https://pepy.tech/badge/pywiim/week)](https://pepy.tech/project/pywiim)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Status](https://img.shields.io/badge/status-stable-green)](https://github.com/mjcumming/pywiim)
[![Maintenance](https://img.shields.io/badge/maintained-yes-green.svg)](https://github.com/mjcumming/pywiim)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Type checking: mypy](https://img.shields.io/badge/type%20checking-mypy-blue.svg)](https://mypy.readthedocs.io/)
[![Linting: ruff](https://img.shields.io/badge/linting-ruff-yellow.svg)](https://github.com/astral-sh/ruff)
[![Coverage](https://codecov.io/gh/mjcumming/pywiim/branch/main/graph/badge.svg)](https://codecov.io/gh/mjcumming/pywiim)
[![Documentation](https://img.shields.io/badge/docs-available-brightgreen)](https://github.com/mjcumming/pywiim#readme)
[![Dependencies](https://img.shields.io/badge/dependencies-up%20to%20date-brightgreen.svg)](https://github.com/mjcumming/pywiim)

## Overview

`pywiim` is a Python library that provides a clean interface for communicating with WimM and LinkPlay-based audio devices.

## Features

### Core Functionality
- **HTTP API Client** - Complete implementation of WiiM/LinkPlay HTTP API
  - Official and unofficial endpoints
  - Automatic capability detection
  - Multi-vendor support (WiiM, Arylic, Audio Pro, generic LinkPlay)
- **UPnP Integration** - Real-time event subscriptions via UPnP
  - Automatic event handling
  - HTTP polling fallback
  - State synchronization
- **Async/Await Support** - Fully asynchronous API throughout
- **Type Hints** - Comprehensive type annotations for better IDE support
- **Error Handling** - Robust error handling with custom exception types

### Media Control
- Play, pause, resume, stop
- Next/previous track navigation
- Seek to position in track
- Play URLs, playlists, and notifications
- Play presets
- Queue management (add to queue, insert next) - requires UPnP client

### Volume & Audio Control
- Individual volume control (0.0-1.0)
- Group volume synchronization
- Mute/unmute
- Channel balance control
- Audio output mode selection (Line Out, Optical Out, Coax Out, Bluetooth Out, HDMI Out)
- SPDIF settings and sample rate detection

### Source Management
- Smart source detection
- Source switching (WiFi, Bluetooth, Line-in, Optical, Coaxial, USB, HDMI)
- Streaming service sources (Spotify, AirPlay, DLNA, Amazon Music, Tidal, Qobuz, Deezer, etc.)
- Internet radio sources (iHeartRadio, Pandora, TuneIn)

### Multiroom Groups
- Create, join, and leave groups
- Group state synchronization
- Role detection (solo/master/slave)
- Group volume control

### Equalizer (EQ)
- EQ preset selection
- Custom EQ with 10-band control
- Enable/disable EQ
- Get EQ status and available presets

### Presets
- Play presets (1-20)
- Get preset information
- Preset slot detection

### Bluetooth
- Scan for Bluetooth devices
- Connect/disconnect Bluetooth devices
- Bluetooth discovery results

### LMS (Logitech Media Server) Integration
- Discover LMS servers on network
- Connect to LMS server
- Auto-connect configuration
- Squeezelite state management

### Device Management
- Device information (model, firmware, MAC, UUID)
- Device reboot
- Touch button control
- Timer management
- Firmware update support

### Discovery & Diagnostics
- SSDP/UPnP device discovery
- Network scanning fallback
- Comprehensive diagnostic tool
- Feature verification tool
- Real-time monitoring tool

## 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](https://www.python.org/downloads/)
- **Windows**: Download from [python.org](https://www.python.org/downloads/) and check "Add Python to PATH" during installation

### Install pywiim

```bash
pip install pywiim
```

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

**Verify installation:**
```bash
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:**
   ```bash
   wiim-discover
   ```

2. **Test a device** (replace `192.168.1.100` with your device IP):
   ```bash
   wiim-verify 192.168.1.100
   ```

3. **Monitor a device in real-time:**
   ```bash
   wiim-monitor 192.168.1.100
   ```

4. **Run diagnostics:**
   ```bash
   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:**
```bash
# 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](docs/user/DISCOVERY.md) 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)
- 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:**
```bash
# 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](docs/user/DIAGNOSTICS.md) 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:**
```bash
# 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
```

**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)

**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:**
```bash
# 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

## Quick Start

Using the Python API:

```python
import asyncio
from pywiim import WiiMClient

async def main():
    # Create client
    client = WiiMClient("192.168.1.100")
    
    # Get device info
    device_info = await client.get_device_info_model()
    print(f"Device: {device_info.name} ({device_info.model})")
    
    # Get player status
    status = await client.get_player_status()
    print(f"Playing: {status.get('play_state')}")
    
    # Control playback
    await client.set_volume(0.5)
    await client.play()
    
    # Set audio output mode (WiiM devices only)
    if client.capabilities.get("supports_audio_output", False):
        await client.set_audio_output_mode("Optical Out")
        # Or use integer: await client.set_audio_output_mode(1)
    
    # Clean up
    await client.close()

asyncio.run(main())
```

## Audio Output Selection

WiiM devices support selecting different audio output modes. This feature is available on all WiiM devices (WiiM Mini, WiiM Pro, WiiM Pro Plus, WiiM Amp, WiiM Ultra).

### Available Output Modes

Different WiiM models support different output combinations:

- **WiiM Mini**: Line Out, Optical Out
- **WiiM Pro/Pro Plus**: Line Out, Optical Out, Coax Out, Bluetooth Out
- **WiiM Amp**: Line Out (integrated amplifier, no digital outputs)
- **WiiM Ultra**: Line Out, Optical Out, Coax Out, Bluetooth Out, HDMI Out

### Usage Examples

```python
import asyncio
from pywiim import WiiMClient

async def main():
    client = WiiMClient("192.168.1.100")
    
    # Check if device supports audio output control
    if client.capabilities.get("supports_audio_output", False):
        # Get current output mode
        status = await client.get_audio_output_status()
        print(f"Current output: {status}")
        
        # Set output mode using friendly name
        await client.set_audio_output_mode("Optical Out")
        await client.set_audio_output_mode("Line Out")
        await client.set_audio_output_mode("Coax Out")
        await client.set_audio_output_mode("Bluetooth Out")
        
        # Or use integer mode (0-4)
        await client.set_audio_output_mode(0)  # Line Out
        await client.set_audio_output_mode(1)  # Optical Out
        await client.set_audio_output_mode(3)  # Coax Out
        await client.set_audio_output_mode(4)  # Bluetooth Out
        
        # Convert between names and integers
        mode_int = client.audio_output_name_to_mode("Optical Out")  # Returns 1
        mode_name = client.audio_output_mode_to_name(1)  # Returns "Optical Out"
    
    await client.close()

asyncio.run(main())
```

### Using the Player Class

The `Player` class provides convenient properties for output selection:

```python
from pywiim import Player

async def main():
    player = Player("192.168.1.100")
    await player.refresh()
    
    # Get current output mode
    current_mode = player.audio_output_mode  # e.g., "Optical Out"
    print(f"Current output: {current_mode}")
    
    # Get available output modes for this device
    available = player.available_output_modes
    print(f"Available modes: {available}")
    # Example: ["Line Out", "Optical Out", "Coax Out", "Bluetooth Out"]
    
    # Set output mode
    await player.set_audio_output_mode("Optical Out")
    
    # Check if Bluetooth output is active
    if player.is_bluetooth_output_active:
        print("Bluetooth output is currently active")
    
    await player.close()

asyncio.run(main())
```

## Queue Management

Queue management allows you to add media to the playback queue instead of replacing the current track. This feature requires UPnP AVTransport actions and is useful for building playlists or adding songs to an existing queue.

### Overview

Queue management supports three operations:
- **Add to queue** - Append media to the end of the queue
- **Insert next** - Insert media after the current track (plays next)
- **Play with enqueue** - Play URL with optional enqueue behavior

### Requirements

Queue management requires:
- **UPnP client** - Must be created and passed to `Player`
- **AVTransport service** - Device must support UPnP AVTransport (all WiiM devices do)

### Basic Usage

Queue management requires a UPnP client. Create the UPnP client and pass it to the Player:

```python
import asyncio
from pywiim import WiiMClient, Player, UpnpClient

async def main():
    # Create HTTP client
    http_client = WiiMClient("192.168.1.100")
    
    # Create UPnP client (required for queue management)
    description_url = f"http://192.168.1.100:49152/description.xml"
    upnp_client = await UpnpClient.create("192.168.1.100", description_url)
    
    # Create player with UPnP client
    player = Player(http_client, upnp_client=upnp_client)
    
    # Add songs to queue
    await player.add_to_queue("http://example.com/song1.mp3")
    await player.add_to_queue("http://example.com/song2.mp3")
    
    # Insert song after current track
    await player.insert_next("http://example.com/urgent.mp3")
    
    # Play URL with enqueue option
    await player.play_url("http://example.com/song3.mp3", enqueue="add")
    
    # Clean up
    await http_client.close()

asyncio.run(main())
```

### Methods

#### `add_to_queue(url, metadata="")`

Add a URL to the end of the playback queue.

```python
# Add songs to queue
await player.add_to_queue("http://example.com/song1.mp3")
await player.add_to_queue("http://example.com/song2.mp3")

# With optional DIDL-Lite metadata
await player.add_to_queue(
    "http://example.com/song.mp3",
    metadata="<DIDL-Lite>...</DIDL-Lite>"
)
```

#### `insert_next(url, metadata="")`

Insert a URL after the current track (will play next).

```python
# Insert urgent song to play next
await player.insert_next("http://example.com/urgent.mp3")
```

#### `play_url(url, enqueue="replace|add|next|play")`

Play a URL with optional enqueue behavior.

```python
# Default: replace current (uses HTTP API)
await player.play_url("http://example.com/song.mp3")

# Add to end of queue (uses UPnP)
await player.play_url("http://example.com/song.mp3", enqueue="add")

# Insert after current (uses UPnP)
await player.play_url("http://example.com/song.mp3", enqueue="next")

# Play immediately (uses HTTP API, same as default)
await player.play_url("http://example.com/song.mp3", enqueue="play")
```

### Error Handling

Queue management methods will raise `WiiMError` if:
- UPnP client is not available (not passed to `Player.__init__()`)
- UPnP AVTransport service is not available
- Device doesn't support queue operations

**Best Practice:** Check for UPnP client availability before using queue features:

```python
if player._upnp_client:
    await player.add_to_queue("http://example.com/song.mp3")
else:
    # Fallback to regular play
    await player.play_url("http://example.com/song.mp3")
```

### Notes

- Queue management methods (`add_to_queue`, `insert_next`) and the `enqueue` parameter in `play_url()` require a UPnP client
- Without a UPnP client, these operations will raise a `WiiMError` with a helpful error message
- The UPnP client can be shared between `UpnpEventer` (for events) and `Player` (for queue management)
- See [Home Assistant Integration Guide](docs/integration/HA_INTEGRATION.md) for integration examples

## Audio Output Selection

### Output Mode Reference

| Mode | Integer | Description |
|------|---------|-------------|
| Line Out | 0 | Analog line output (RCA) |
| Optical Out | 1 | Digital optical output (TOSLINK) |
| Line Out (alt) | 2 | Alternative line out mode (some devices) |
| Coax Out | 3 | Digital coaxial output |
| Bluetooth Out | 4 | Bluetooth audio output |

**Note:** Bluetooth output takes precedence over hardware output mode when active. The `get_audio_output_status()` method returns both `hardware` (hardware output mode) and `source` (Bluetooth output status).

## Development Setup

See [SETUP.md](SETUP.md) for detailed development setup instructions.

Quick start:
```bash
# 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
```

## Project Status

✅ **Core Features Complete:**
- HTTP API client with all mixins
- UPnP client and event handling
- Capability detection system
- State synchronization
- Diagnostic tool
- Comprehensive test suite

✅ **Code Quality:**
- Major refactoring completed (24% reduction in largest file)
- Improved error handling and logging
- Enhanced type hints across codebase
- All large files properly documented

🚧 **Package Finalization:**
- Package metadata ready
- Build testing pending (requires build tools)

## 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
- **[python-linkplay](https://pypi.org/project/python-linkplay/)** - Python library for LinkPlay devices that provided insights into state detection and API patterns (enhanced state detection logic from v0.2.9)
- **[linkplay-cli](https://github.com/ramikg/linkplay-cli)** - Command-line tool for LinkPlay devices (provided SSL certificate reference for Audio Pro devices)
- **[WiiM HTTP API OpenAPI Specification](https://github.com/cvdlinden/wiim-httpapi)** - Comprehensive OpenAPI 3.0 specification for WiiM HTTP API endpoints
- **[Home Assistant WiiM Integration](https://github.com/mjcumming/wiim)** - Production-tested implementation that informed many design decisions, polling strategies, and state management patterns
- **[WiiM Play](https://github.com/shumatech/wiimplay)** - UPnP-based implementation that provided UPnP integration insights
- **Vellmon LinkPlay library** - Provided valuable API information and patterns for LinkPlay device communication
- **[Home Assistant LinkPlay Custom Component](https://github.com/nagyrobi/home-assistant-custom-components-linkplay)** - Custom Home Assistant integration for LinkPlay devices
- **[LinkPlay A31 Alternative Firmware](https://github.com/hn/linkplay-a31)** - Alternative firmware project that provided insights into LinkPlay hardware capabilities

### Official Documentation
- [Arylic LinkPlay API Documentation](https://developer.arylic.com/httpapi/) - Official LinkPlay protocol documentation
- [WiiM HTTP API PDF](https://www.wiimhome.com/pdf/HTTP%20API%20for%20WiiM%20Products.pdf) - Official WiiM API documentation

### 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](https://github.com/mjcumming/pywiim/issues) or submit a pull request.

## License

MIT License

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "pywiim",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": null,
    "keywords": "wiim, linkplay, audio, upnp, streaming, music, async",
    "author": null,
    "author_email": "Michael Cumming <mjcumming@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/ed/00/01a8274577965a14d1eb301dfd5c9101b4ded7923c3d9962dbb1c8523f84/pywiim-1.0.47.tar.gz",
    "platform": null,
    "description": "# pywiim\n\nPython library for WiiM/LinkPlay device communication (HTTP API + UPnP).\n\n[![CI](https://github.com/mjcumming/pywiim/actions/workflows/ci.yml/badge.svg)](https://github.com/mjcumming/pywiim/actions/workflows/ci.yml)\n[![Security](https://github.com/mjcumming/pywiim/actions/workflows/security.yml/badge.svg)](https://github.com/mjcumming/pywiim/actions/workflows/security.yml)\n[![PyPI version](https://badge.fury.io/py/pywiim.svg)](https://badge.fury.io/py/pywiim)\n[![PyPI downloads](https://pepy.tech/badge/pywiim)](https://pepy.tech/project/pywiim)\n[![PyPI downloads/week](https://pepy.tech/badge/pywiim/week)](https://pepy.tech/project/pywiim)\n[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Status](https://img.shields.io/badge/status-stable-green)](https://github.com/mjcumming/pywiim)\n[![Maintenance](https://img.shields.io/badge/maintained-yes-green.svg)](https://github.com/mjcumming/pywiim)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Type checking: mypy](https://img.shields.io/badge/type%20checking-mypy-blue.svg)](https://mypy.readthedocs.io/)\n[![Linting: ruff](https://img.shields.io/badge/linting-ruff-yellow.svg)](https://github.com/astral-sh/ruff)\n[![Coverage](https://codecov.io/gh/mjcumming/pywiim/branch/main/graph/badge.svg)](https://codecov.io/gh/mjcumming/pywiim)\n[![Documentation](https://img.shields.io/badge/docs-available-brightgreen)](https://github.com/mjcumming/pywiim#readme)\n[![Dependencies](https://img.shields.io/badge/dependencies-up%20to%20date-brightgreen.svg)](https://github.com/mjcumming/pywiim)\n\n## Overview\n\n`pywiim` is a Python library that provides a clean interface for communicating with WimM and LinkPlay-based audio devices.\n\n## Features\n\n### Core Functionality\n- **HTTP API Client** - Complete implementation of WiiM/LinkPlay HTTP API\n  - Official and unofficial endpoints\n  - Automatic capability detection\n  - Multi-vendor support (WiiM, Arylic, Audio Pro, generic LinkPlay)\n- **UPnP Integration** - Real-time event subscriptions via UPnP\n  - Automatic event handling\n  - HTTP polling fallback\n  - State synchronization\n- **Async/Await Support** - Fully asynchronous API throughout\n- **Type Hints** - Comprehensive type annotations for better IDE support\n- **Error Handling** - Robust error handling with custom exception types\n\n### Media Control\n- Play, pause, resume, stop\n- Next/previous track navigation\n- Seek to position in track\n- Play URLs, playlists, and notifications\n- Play presets\n- Queue management (add to queue, insert next) - requires UPnP client\n\n### Volume & Audio Control\n- Individual volume control (0.0-1.0)\n- Group volume synchronization\n- Mute/unmute\n- Channel balance control\n- Audio output mode selection (Line Out, Optical Out, Coax Out, Bluetooth Out, HDMI Out)\n- SPDIF settings and sample rate detection\n\n### Source Management\n- Smart source detection\n- Source switching (WiFi, Bluetooth, Line-in, Optical, Coaxial, USB, HDMI)\n- Streaming service sources (Spotify, AirPlay, DLNA, Amazon Music, Tidal, Qobuz, Deezer, etc.)\n- Internet radio sources (iHeartRadio, Pandora, TuneIn)\n\n### Multiroom Groups\n- Create, join, and leave groups\n- Group state synchronization\n- Role detection (solo/master/slave)\n- Group volume control\n\n### Equalizer (EQ)\n- EQ preset selection\n- Custom EQ with 10-band control\n- Enable/disable EQ\n- Get EQ status and available presets\n\n### Presets\n- Play presets (1-20)\n- Get preset information\n- Preset slot detection\n\n### Bluetooth\n- Scan for Bluetooth devices\n- Connect/disconnect Bluetooth devices\n- Bluetooth discovery results\n\n### LMS (Logitech Media Server) Integration\n- Discover LMS servers on network\n- Connect to LMS server\n- Auto-connect configuration\n- Squeezelite state management\n\n### Device Management\n- Device information (model, firmware, MAC, UUID)\n- Device reboot\n- Touch button control\n- Timer management\n- Firmware update support\n\n### Discovery & Diagnostics\n- SSDP/UPnP device discovery\n- Network scanning fallback\n- Comprehensive diagnostic tool\n- Feature verification tool\n- Real-time monitoring tool\n\n## Installation\n\nInstall `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.\n\n### Prerequisites\n\n- Python 3.11 or later\n- pip (usually included with Python)\n\n**Installing Python:**\n- **Linux/macOS**: Usually pre-installed. If not, use your package manager or download from [python.org](https://www.python.org/downloads/)\n- **Windows**: Download from [python.org](https://www.python.org/downloads/) and check \"Add Python to PATH\" during installation\n\n### Install pywiim\n\n```bash\npip install pywiim\n```\n\nThe CLI tools (`wiim-discover`, `wiim-diagnostics`, `wiim-monitor`, `wiim-verify`) are automatically installed and available in your PATH.\n\n**Verify installation:**\n```bash\nwiim-discover --help\n```\n\n**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.\n\n## Command-Line Tools\n\nThe 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.\n\n### Quick Start\n\n1. **Discover devices on your network:**\n   ```bash\n   wiim-discover\n   ```\n\n2. **Test a device** (replace `192.168.1.100` with your device IP):\n   ```bash\n   wiim-verify 192.168.1.100\n   ```\n\n3. **Monitor a device in real-time:**\n   ```bash\n   wiim-monitor 192.168.1.100\n   ```\n\n4. **Run diagnostics:**\n   ```bash\n   wiim-diagnostics 192.168.1.100\n   ```\n\n### 1. Device Discovery (`wiim-discover`)\n\nDiscover all WiiM/LinkPlay devices on your network using SSDP/UPnP or network scanning.\n\n**What it does:**\n- Automatically finds all WiiM and LinkPlay-based devices on your local network\n- Validates discovered devices by testing their API\n- Displays device information (name, model, firmware, IP, MAC, UUID)\n- Supports multiple discovery methods for maximum compatibility\n\n**Usage:**\n```bash\n# Basic discovery (SSDP/UPnP)\nwiim-discover\n\n# Output as JSON (useful for scripting)\nwiim-discover --output json\n\n# Skip API validation (faster, less detailed)\nwiim-discover --no-validate\n\n# Verbose logging\nwiim-discover --verbose\n\n# Custom SSDP timeout\nwiim-discover --ssdp-timeout 10\n```\n\n**Options:**\n- `--ssdp-timeout <seconds>` - SSDP discovery timeout (default: 5)\n- `--no-validate` - Skip API validation of discovered devices\n- `--output <text|json>` - Output format (default: text)\n- `--verbose, -v` - Enable verbose logging\n\n**Example Output:**\n```\n\ud83d\udd0d Discovering WiiM/LinkPlay devices via SSDP...\n\nDevice: WiiM Mini\n  IP Address: 192.168.1.100:80\n  Protocol: HTTP\n  Model: WiiM Mini\n  Firmware: 4.8.123456\n  MAC Address: AA:BB:CC:DD:EE:FF\n  UUID: 12345678-1234-1234-1234-123456789abc\n  Vendor: WiiM\n  Discovered via: SSDP\n  Status: Validated \u2713\n```\n\nSee [Discovery Documentation](docs/user/DISCOVERY.md) for more information.\n\n### 2. Diagnostic Tool (`wiim-diagnostics`)\n\nComprehensive diagnostic tool for troubleshooting device issues and gathering information for support.\n\n**What it does:**\n- Gathers complete device information (model, firmware, MAC, UUID, capabilities)\n- Tests all API endpoints to verify functionality\n- Tests feature support (presets, EQ, multiroom, Bluetooth, etc.)\n- Generates detailed JSON reports for sharing with developers\n- Identifies errors and warnings\n\n**Usage:**\n```bash\n# Basic diagnostic\nwiim-diagnostics 192.168.1.100\n\n# Save report to file (for sharing with support)\nwiim-diagnostics 192.168.1.100 --output report.json\n\n# HTTPS device\nwiim-diagnostics 192.168.1.100 --port 443\n\n# Verbose output\nwiim-diagnostics 192.168.1.100 --verbose\n```\n\n**Options:**\n- `<device_ip>` - Device IP address or hostname (required)\n- `--port <port>` - Device port (default: 80, use 443 for HTTPS)\n- `--output <file>` - Save report to JSON file\n- `--verbose` - Enable detailed logging\n\n**What it tests:**\n- Device information retrieval\n- Capability detection\n- All status endpoints\n- Feature support detection\n- API endpoint availability\n- Error conditions\n\n**Example Output:**\n```\n\ud83d\udd0d Starting comprehensive device diagnostic...\n   Device: 192.168.1.100:80\n\n\ud83d\udccb Gathering device information...\n   \u2713 Device: WiiM Mini (WiiM Mini)\n   \u2713 Firmware: 4.8.123456\n   \u2713 MAC: AA:BB:CC:DD:EE:FF\n\n\ud83d\udd27 Detecting device capabilities...\n   \u2713 Vendor: WiiM\n   \u2713 Device Type: WiiM\n   \u2713 Supports EQ: Yes\n   \u2713 Supports Presets: Yes\n   ...\n```\n\nSee [Diagnostics Documentation](docs/user/DIAGNOSTICS.md) for more information.\n\n### 3. Real-time Monitor (`wiim-monitor`)\n\nMonitor your device in real-time with adaptive polling and UPnP event support.\n\n**What it does:**\n- Displays live device status with automatic updates\n- Uses UPnP events for instant updates when available\n- Falls back to adaptive HTTP polling\n- Shows play state, volume, mute, track info, and playback position\n- Displays device role in multiroom groups\n- Tracks statistics (poll count, state changes, UPnP events)\n\n**Usage:**\n```bash\n# Basic monitoring\nwiim-monitor 192.168.1.100\n\n# Specify callback host for UPnP (if auto-detection fails)\nwiim-monitor 192.168.1.100 --callback-host 192.168.1.254\n\n# Verbose logging\nwiim-monitor 192.168.1.100 --verbose\n\n# Custom log level\nwiim-monitor 192.168.1.100 --log-level DEBUG\n```\n\n**Options:**\n- `<device_ip>` - Device IP address or hostname (required)\n- `--callback-host <ip>` - Override UPnP callback host (auto-detected by default)\n- `--verbose, -v` - Enable verbose logging\n- `--log-level <level>` - Set log level (DEBUG, INFO, WARNING, ERROR)\n\n**What it displays:**\n- Play state (playing, paused, stopped)\n- Volume level and mute status\n- Current track (title, artist, album)\n- Playback position and duration\n- Device role (solo/master/slave)\n- Group information (if in a group)\n- Update source (polling or UPnP event)\n- Statistics on exit\n\n**Example Output:**\n```\n\ud83c\udfb5 Monitoring WiiM Mini (192.168.1.100)...\n   UPnP: Enabled \u2713 (events: 0)\n   Polling: Adaptive (interval: 2.0s)\n\n\ud83d\udcca Status:\n   State: playing\n   Volume: 50% (muted: No)\n   Source: wifi\n   Role: solo\n\n\ud83c\udfb6 Track:\n   Title: Song Title\n   Artist: Artist Name\n   Album: Album Name\n   Position: 1:23 / 3:45\n\n[UPnP] State changed: volume \u2192 55%\n```\n\nPress `Ctrl+C` to stop monitoring and view statistics.\n\n### 4. Feature Verification (`wiim-verify`)\n\nComprehensive testing tool that verifies all device features and endpoints with safety constraints.\n\n**What it does:**\n- Tests all playback controls (play, pause, stop, next, previous)\n- Tests volume controls (safely, never exceeds 10%)\n- Tests source switching\n- Tests audio output modes\n- Tests EQ controls (if supported)\n- Tests group operations (if applicable)\n- Tests preset playback\n- Tests all status endpoints\n- Saves and restores original device state\n- Generates detailed test report\n\n**Usage:**\n```bash\n# Basic verification\nwiim-verify 192.168.1.100\n\n# Verbose output (shows detailed test data)\nwiim-verify 192.168.1.100 --verbose\n\n# HTTPS device\nwiim-verify 192.168.1.100 --port 443\n```\n\n**Options:**\n- `<device_ip>` - Device IP address or hostname (required)\n- `--port <port>` - Device port (default: 80, use 443 for HTTPS)\n- `--verbose, -v` - Enable verbose output (shows detailed test data)\n\n**Safety Features:**\n- Volume never exceeds 10% during testing\n- Original device state is saved and restored\n- Non-destructive testing (doesn't disrupt normal use)\n- Graceful error handling\n\n**What it tests:**\n- Status endpoints (get_player_status, get_device_info, etc.)\n- Playback controls (play, pause, resume, stop, next, previous)\n- Volume controls (set_volume, set_mute)\n- Source controls (set_source, get_source)\n- Audio output controls (set_audio_output_mode)\n- EQ controls (get_eq, set_eq_preset, set_eq_custom, etc.)\n- Group operations (create_group, join_group, leave_group)\n- Preset operations (play_preset)\n- And more...\n\n**Example Output:**\n```\n\ud83d\udcbe Saving original device state...\n   \u2713 Volume: 0.5\n   \u2713 Mute: False\n   \u2713 Source: wifi\n   \u2713 Play state: playing\n\n\ud83d\udcca Testing Status Endpoints...\n   \u2713 get_player_status\n   \u2713 get_player_status_model\n   \u2713 get_meta_info\n\n\u25b6\ufe0f  Testing Playback Controls...\n   \u2713 play\n   \u2713 pause\n   \u2713 resume\n   \u2713 stop\n   \u2713 next_track\n   \u2713 previous_track\n\n\ud83d\udd0a Testing Volume Controls (max 10%)...\n   \u2713 set_volume (5%)\n   \u2713 set_volume (10%)\n   \u2713 set_mute (True)\n   \u2713 set_mute (False)\n\n...\n\n\ud83d\udd04 Restoring original device state...\n   \u2713 Volume restored\n   \u2713 Mute restored\n   \u2713 Source restored\n\n============================================================\nTotal tests: 45\n\u2705 Passed: 42\n\u274c Failed: 0\n\u2298 Skipped: 3\n```\n\n**Exit Codes:**\n- `0` - All tests passed\n- `1` - One or more tests failed or interrupted\n\n## Quick Start\n\nUsing the Python API:\n\n```python\nimport asyncio\nfrom pywiim import WiiMClient\n\nasync def main():\n    # Create client\n    client = WiiMClient(\"192.168.1.100\")\n    \n    # Get device info\n    device_info = await client.get_device_info_model()\n    print(f\"Device: {device_info.name} ({device_info.model})\")\n    \n    # Get player status\n    status = await client.get_player_status()\n    print(f\"Playing: {status.get('play_state')}\")\n    \n    # Control playback\n    await client.set_volume(0.5)\n    await client.play()\n    \n    # Set audio output mode (WiiM devices only)\n    if client.capabilities.get(\"supports_audio_output\", False):\n        await client.set_audio_output_mode(\"Optical Out\")\n        # Or use integer: await client.set_audio_output_mode(1)\n    \n    # Clean up\n    await client.close()\n\nasyncio.run(main())\n```\n\n## Audio Output Selection\n\nWiiM devices support selecting different audio output modes. This feature is available on all WiiM devices (WiiM Mini, WiiM Pro, WiiM Pro Plus, WiiM Amp, WiiM Ultra).\n\n### Available Output Modes\n\nDifferent WiiM models support different output combinations:\n\n- **WiiM Mini**: Line Out, Optical Out\n- **WiiM Pro/Pro Plus**: Line Out, Optical Out, Coax Out, Bluetooth Out\n- **WiiM Amp**: Line Out (integrated amplifier, no digital outputs)\n- **WiiM Ultra**: Line Out, Optical Out, Coax Out, Bluetooth Out, HDMI Out\n\n### Usage Examples\n\n```python\nimport asyncio\nfrom pywiim import WiiMClient\n\nasync def main():\n    client = WiiMClient(\"192.168.1.100\")\n    \n    # Check if device supports audio output control\n    if client.capabilities.get(\"supports_audio_output\", False):\n        # Get current output mode\n        status = await client.get_audio_output_status()\n        print(f\"Current output: {status}\")\n        \n        # Set output mode using friendly name\n        await client.set_audio_output_mode(\"Optical Out\")\n        await client.set_audio_output_mode(\"Line Out\")\n        await client.set_audio_output_mode(\"Coax Out\")\n        await client.set_audio_output_mode(\"Bluetooth Out\")\n        \n        # Or use integer mode (0-4)\n        await client.set_audio_output_mode(0)  # Line Out\n        await client.set_audio_output_mode(1)  # Optical Out\n        await client.set_audio_output_mode(3)  # Coax Out\n        await client.set_audio_output_mode(4)  # Bluetooth Out\n        \n        # Convert between names and integers\n        mode_int = client.audio_output_name_to_mode(\"Optical Out\")  # Returns 1\n        mode_name = client.audio_output_mode_to_name(1)  # Returns \"Optical Out\"\n    \n    await client.close()\n\nasyncio.run(main())\n```\n\n### Using the Player Class\n\nThe `Player` class provides convenient properties for output selection:\n\n```python\nfrom pywiim import Player\n\nasync def main():\n    player = Player(\"192.168.1.100\")\n    await player.refresh()\n    \n    # Get current output mode\n    current_mode = player.audio_output_mode  # e.g., \"Optical Out\"\n    print(f\"Current output: {current_mode}\")\n    \n    # Get available output modes for this device\n    available = player.available_output_modes\n    print(f\"Available modes: {available}\")\n    # Example: [\"Line Out\", \"Optical Out\", \"Coax Out\", \"Bluetooth Out\"]\n    \n    # Set output mode\n    await player.set_audio_output_mode(\"Optical Out\")\n    \n    # Check if Bluetooth output is active\n    if player.is_bluetooth_output_active:\n        print(\"Bluetooth output is currently active\")\n    \n    await player.close()\n\nasyncio.run(main())\n```\n\n## Queue Management\n\nQueue management allows you to add media to the playback queue instead of replacing the current track. This feature requires UPnP AVTransport actions and is useful for building playlists or adding songs to an existing queue.\n\n### Overview\n\nQueue management supports three operations:\n- **Add to queue** - Append media to the end of the queue\n- **Insert next** - Insert media after the current track (plays next)\n- **Play with enqueue** - Play URL with optional enqueue behavior\n\n### Requirements\n\nQueue management requires:\n- **UPnP client** - Must be created and passed to `Player`\n- **AVTransport service** - Device must support UPnP AVTransport (all WiiM devices do)\n\n### Basic Usage\n\nQueue management requires a UPnP client. Create the UPnP client and pass it to the Player:\n\n```python\nimport asyncio\nfrom pywiim import WiiMClient, Player, UpnpClient\n\nasync def main():\n    # Create HTTP client\n    http_client = WiiMClient(\"192.168.1.100\")\n    \n    # Create UPnP client (required for queue management)\n    description_url = f\"http://192.168.1.100:49152/description.xml\"\n    upnp_client = await UpnpClient.create(\"192.168.1.100\", description_url)\n    \n    # Create player with UPnP client\n    player = Player(http_client, upnp_client=upnp_client)\n    \n    # Add songs to queue\n    await player.add_to_queue(\"http://example.com/song1.mp3\")\n    await player.add_to_queue(\"http://example.com/song2.mp3\")\n    \n    # Insert song after current track\n    await player.insert_next(\"http://example.com/urgent.mp3\")\n    \n    # Play URL with enqueue option\n    await player.play_url(\"http://example.com/song3.mp3\", enqueue=\"add\")\n    \n    # Clean up\n    await http_client.close()\n\nasyncio.run(main())\n```\n\n### Methods\n\n#### `add_to_queue(url, metadata=\"\")`\n\nAdd a URL to the end of the playback queue.\n\n```python\n# Add songs to queue\nawait player.add_to_queue(\"http://example.com/song1.mp3\")\nawait player.add_to_queue(\"http://example.com/song2.mp3\")\n\n# With optional DIDL-Lite metadata\nawait player.add_to_queue(\n    \"http://example.com/song.mp3\",\n    metadata=\"<DIDL-Lite>...</DIDL-Lite>\"\n)\n```\n\n#### `insert_next(url, metadata=\"\")`\n\nInsert a URL after the current track (will play next).\n\n```python\n# Insert urgent song to play next\nawait player.insert_next(\"http://example.com/urgent.mp3\")\n```\n\n#### `play_url(url, enqueue=\"replace|add|next|play\")`\n\nPlay a URL with optional enqueue behavior.\n\n```python\n# Default: replace current (uses HTTP API)\nawait player.play_url(\"http://example.com/song.mp3\")\n\n# Add to end of queue (uses UPnP)\nawait player.play_url(\"http://example.com/song.mp3\", enqueue=\"add\")\n\n# Insert after current (uses UPnP)\nawait player.play_url(\"http://example.com/song.mp3\", enqueue=\"next\")\n\n# Play immediately (uses HTTP API, same as default)\nawait player.play_url(\"http://example.com/song.mp3\", enqueue=\"play\")\n```\n\n### Error Handling\n\nQueue management methods will raise `WiiMError` if:\n- UPnP client is not available (not passed to `Player.__init__()`)\n- UPnP AVTransport service is not available\n- Device doesn't support queue operations\n\n**Best Practice:** Check for UPnP client availability before using queue features:\n\n```python\nif player._upnp_client:\n    await player.add_to_queue(\"http://example.com/song.mp3\")\nelse:\n    # Fallback to regular play\n    await player.play_url(\"http://example.com/song.mp3\")\n```\n\n### Notes\n\n- Queue management methods (`add_to_queue`, `insert_next`) and the `enqueue` parameter in `play_url()` require a UPnP client\n- Without a UPnP client, these operations will raise a `WiiMError` with a helpful error message\n- The UPnP client can be shared between `UpnpEventer` (for events) and `Player` (for queue management)\n- See [Home Assistant Integration Guide](docs/integration/HA_INTEGRATION.md) for integration examples\n\n## Audio Output Selection\n\n### Output Mode Reference\n\n| Mode | Integer | Description |\n|------|---------|-------------|\n| Line Out | 0 | Analog line output (RCA) |\n| Optical Out | 1 | Digital optical output (TOSLINK) |\n| Line Out (alt) | 2 | Alternative line out mode (some devices) |\n| Coax Out | 3 | Digital coaxial output |\n| Bluetooth Out | 4 | Bluetooth audio output |\n\n**Note:** Bluetooth output takes precedence over hardware output mode when active. The `get_audio_output_status()` method returns both `hardware` (hardware output mode) and `source` (Bluetooth output status).\n\n## Development Setup\n\nSee [SETUP.md](SETUP.md) for detailed development setup instructions.\n\nQuick start:\n```bash\n# Create virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate  # On Windows: .venv\\Scripts\\activate\n\n# Install with dev dependencies\npip install -e \".[dev]\"\n\n# Run tests\npytest tests/unit/ -v\n\n# Run code quality checks\nmake lint typecheck\n```\n\n## Project Status\n\n\u2705 **Core Features Complete:**\n- HTTP API client with all mixins\n- UPnP client and event handling\n- Capability detection system\n- State synchronization\n- Diagnostic tool\n- Comprehensive test suite\n\n\u2705 **Code Quality:**\n- Major refactoring completed (24% reduction in largest file)\n- Improved error handling and logging\n- Enhanced type hints across codebase\n- All large files properly documented\n\n\ud83d\udea7 **Package Finalization:**\n- Package metadata ready\n- Build testing pending (requires build tools)\n\n## Acknowledgments\n\nThis 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:\n\n### Libraries and Implementations\n- **[python-linkplay](https://pypi.org/project/python-linkplay/)** - Python library for LinkPlay devices that provided insights into state detection and API patterns (enhanced state detection logic from v0.2.9)\n- **[linkplay-cli](https://github.com/ramikg/linkplay-cli)** - Command-line tool for LinkPlay devices (provided SSL certificate reference for Audio Pro devices)\n- **[WiiM HTTP API OpenAPI Specification](https://github.com/cvdlinden/wiim-httpapi)** - Comprehensive OpenAPI 3.0 specification for WiiM HTTP API endpoints\n- **[Home Assistant WiiM Integration](https://github.com/mjcumming/wiim)** - Production-tested implementation that informed many design decisions, polling strategies, and state management patterns\n- **[WiiM Play](https://github.com/shumatech/wiimplay)** - UPnP-based implementation that provided UPnP integration insights\n- **Vellmon LinkPlay library** - Provided valuable API information and patterns for LinkPlay device communication\n- **[Home Assistant LinkPlay Custom Component](https://github.com/nagyrobi/home-assistant-custom-components-linkplay)** - Custom Home Assistant integration for LinkPlay devices\n- **[LinkPlay A31 Alternative Firmware](https://github.com/hn/linkplay-a31)** - Alternative firmware project that provided insights into LinkPlay hardware capabilities\n\n### Official Documentation\n- [Arylic LinkPlay API Documentation](https://developer.arylic.com/httpapi/) - Official LinkPlay protocol documentation\n- [WiiM HTTP API PDF](https://www.wiimhome.com/pdf/HTTP%20API%20for%20WiiM%20Products.pdf) - Official WiiM API documentation\n\n### Additional Resources\n- Various GitHub repositories and community contributions that helped document the LinkPlay protocol and WiiM-specific enhancements\n- The LinkPlay and WiiM developer communities for sharing API discoveries and reverse-engineering efforts\n\nIf you know of other libraries or resources that should be acknowledged, please [open an issue](https://github.com/mjcumming/pywiim/issues) or submit a pull request.\n\n## License\n\nMIT License\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python library for WiiM/LinkPlay device communication",
    "version": "1.0.47",
    "project_urls": {
        "Homepage": "https://github.com/mjcumming/pywiim",
        "Issues": "https://github.com/mjcumming/pywiim/issues",
        "Repository": "https://github.com/mjcumming/pywiim"
    },
    "split_keywords": [
        "wiim",
        " linkplay",
        " audio",
        " upnp",
        " streaming",
        " music",
        " async"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "435ad3a5f1292930ea19764ae1eb6a3f8aaeae365b6ed2b9d26c1f5a5ec9b727",
                "md5": "d8bc2c04deca81b71c14c2100ad6e8bc",
                "sha256": "fc6d64a7214a8af24c5cbf2584f4c57c200d09095119b5aff95c26b44ceabd27"
            },
            "downloads": -1,
            "filename": "pywiim-1.0.47-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d8bc2c04deca81b71c14c2100ad6e8bc",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 183330,
            "upload_time": "2025-11-16T17:44:13",
            "upload_time_iso_8601": "2025-11-16T17:44:13.624851Z",
            "url": "https://files.pythonhosted.org/packages/43/5a/d3a5f1292930ea19764ae1eb6a3f8aaeae365b6ed2b9d26c1f5a5ec9b727/pywiim-1.0.47-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ed0001a8274577965a14d1eb301dfd5c9101b4ded7923c3d9962dbb1c8523f84",
                "md5": "32c928332c67d21603430c01f1ec66ca",
                "sha256": "879fcac0a4a8d9a6899ffb8786758a1bd3828df324da32fe8ff3014a0cde9aaa"
            },
            "downloads": -1,
            "filename": "pywiim-1.0.47.tar.gz",
            "has_sig": false,
            "md5_digest": "32c928332c67d21603430c01f1ec66ca",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 169090,
            "upload_time": "2025-11-16T17:44:15",
            "upload_time_iso_8601": "2025-11-16T17:44:15.391428Z",
            "url": "https://files.pythonhosted.org/packages/ed/00/01a8274577965a14d1eb301dfd5c9101b4ded7923c3d9962dbb1c8523f84/pywiim-1.0.47.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-11-16 17:44:15",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "mjcumming",
    "github_project": "pywiim",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "pywiim"
}
        
Elapsed time: 0.80998s