Skip to main content

SWAMP Controller

Interactive command-line controller for Crestron SWAMP media amplifier systems.

Features

  • Interactive Shell: User-friendly command prompt with autocomplete
  • TCP Server: Listens for connections from SWAMP devices
  • State Management: Maintains local state synchronized with device
  • Multi-zone Support: Commands automatically broadcast to all zones in a target
  • Pluggable Protocol: Protocol handler designed for easy extension
  • Home Assistant Integration: Native HA integration with media player entities

Home Assistant Integration

This project includes a Home Assistant integration that exposes your Crestron SWAMP system as media player entities in Home Assistant. Each target (room/zone) appears as a controllable media player with volume control, source selection, and power control.

hacs_badge PyPI

Note: This is a custom HACS repository. You need to add it manually using the instructions below.

  1. Ensure HACS is installed in your Home Assistant instance
  2. Add this repository as a custom repository in HACS:
    • Open HACS in Home Assistant
    • Go to "Integrations"
    • Click the three dots menu (top right) and select "Custom repositories"
    • Add https://github.com/jaroy/swamp-controller as an Integration
    • Click "Add"
  3. Find "Crestron SWAMP Controller" in HACS and click "Download"
  4. Restart Home Assistant
  5. Add the integration through Settings > Devices & Services > Add Integration

The crestron-swamp-controller package will be automatically installed from PyPI when you add the integration.

See HOMEASSISTANT.md for more detailed installation instructions and configuration options.

Features

  • Media player entity for each target/zone
  • Real-time state updates from SWAMP device
  • Volume control (0-100%)
  • Source selection from configured sources
  • Power on/off control
  • Device availability tracking

CLI Installation

  1. Ensure Python 3.12+ is installed
  2. Create and activate virtual environment:
    python -m venv .venv
    source .venv/bin/activate  # On Linux/Mac
    # or
    .venv\Scripts\activate  # On Windows
    
  3. Install dependencies:
    pip install -r requirements.txt
    

Configuration

Edit config/config.yaml to define your audio sources and target zones:

# Volume (0-100) a zone is set to when its player is turned on, so enabling a zone
# isn't silent. Optional (defaults to 40); can be overridden per target.
default-volume: 40

sources:
  - id: music-a
    name: Player A
    swamp-source-id: 4
    # Optional: the HA media_player that renders this source into the SWAMP input
    # (e.g. a Music Assistant player). Zones routed to this source proxy that
    # player's play/pause state, now-playing metadata, and transport controls.
    upstream-player: media_player.player_a

targets:
  - id: office-terrace
    name: Office Terrace
    default-volume: 30   # optional per-zone override
    swamp-zones:
      - unit: 3
        zone: 1

Proxying source playback state (upstream-player)

The SWAMP hardware only knows a zone's volume, selected source, and on/off state — it has no concept of play/pause, the current track, or a queue. That information lives on whatever HA media_player actually renders the audio into the SWAMP input (for example, the Music Assistant player feeding a source). Set upstream-player on a source to that entity_id, and any zone routed to that source will mirror the upstream player's transport state and now-playing metadata, and forward play/pause/stop/next/previous to it.

Because a SWAMP input is a single shared stream, every zone on the same source shows the same now-playing — which matches reality. The upstream player's queue itself isn't part of HA's media_player model; point a Music Assistant card at the upstream entity for full queue control.

On the SWAMP

We have to tell the SWAMP to connect to us instead of a Crestron processor. Use these TELNET commands:

adds 51 <IP address> 4 <port>
reboot

Note that you can see the currently configured controller with the ipt command:

$ telnet 192.168.1.89
Trying 192.168.1.89...
Connected to 192.168.1.89.
Escape character is '^]'.

SWAMP Control Console
Connected to Host: SWAMP-00107FE7C4CD

SWAMP>ipt
CIP_ID  Type    Status     DevID  Port   IP Address/SiteName
    51  GWAY    ONLINE        4   41794  010.194.005.251

Usage

Start the controller:

python -m swamp

Or with custom port:

python -m swamp --port 41794

Or with custom config:

python -m swamp --config /path/to/config.yaml

Available Commands

Once the shell is running, you can use these commands:

Route audio source to target

route <source-id> <target-id>

Example: route music-a office

Set volume

volume <target-id> <level>

Example: volume office 75

Adjust volume relatively

volume <target-id> +/-<delta>

Example: volume office +10 or volume office -5

Power control

power <target-id> on <source-id>
power <target-id> off

Power on requires a source (zones need a source to be "on"). Power off sets the source to 0.

Examples:

  • power office on music-a - Power on office with music-a as source
  • power office off - Power off office

Show status

status [target-id]

Example: status office or status (shows all)

Send WHOIS request

whois

Sends a WHOIS request (0f 00 01 02) to the connected SWAMP device. This is automatically sent when a device connects.

List sources or targets

list sources
list targets

Get help

help

Exit

quit

Architecture

The controller works by impersonating a Crestron processor gateway, e.g. a Crestron CP3. The client is the SWAMP and it connects to our server which then establishes the communication link.

User Shell (REPL)
       ↓
Controller (orchestration)
       ↓
State Manager (zone/source mapping)
       ↓
Protocol Handler (pluggable)
       ↓
TCP Server (asyncio)

Components

  • Models: Data classes for configuration and state
  • Core: Configuration loading, state management, orchestration
  • Protocol: Abstract protocol handler with stub implementation
  • Network: Asyncio TCP server for SWAMP device connections
  • Shell: Command parser and interactive REPL

Protocol Implementation

The Protocol Handler partially implements the Crestron Internet Protocol (CIP), a proprietary protocol for communication between Crestron devices. Only the message types for basic control of the SWAMP system are implemented.

Message Format

All CIP messages follow this format:

  • Byte 0: Message type
  • Bytes 1-2: Remaining length (total bytes - 3) in big-endian
  • Bytes 3+: Payload

Example: 0a 00 0a 00 51 a3 42 40 02 00 00 00 00

  • Type: 0x0a (CLIENT_SIGNON)
  • Length: 0x00 0x0a = 10 bytes remaining
  • Payload: 00 51 a3 42 40 02 00 00 00 00 (10 bytes)
  • Total: 1 + 2 + 10 = 13 bytes

Implemented Messages

  • WHOIS (0f 00 01 02) - Sent automatically when client connects, also available via whois command
  • PING (0d 00 02 00 00) - Automatically detected and triggers PONG response. Sent periodically in the background.
  • PONG (0e 00 02 00 00) - Sent automatically in response to PING
  • CLIENT_SIGNON (0a ...) - Sent by device on connect, triggers CONN_ACCEPTED response
  • CONN_ACCEPTED (02 00 04 00 00 00 03) - Sent automatically in response to CLIENT_SIGNON
  • JOIN (05 ...) - The actual control messages for setting and getting information about the SWAMP

Unknown Message Handling

Any message not recognized will be printed to the console in hex format, making it easy to discover and implement new message types.

Example output:

Unknown message type ff (4 bytes): ff aa bb cc
Recognized but unimplemented message type 0a (13 bytes): 0a 00 0a 00 51 a3 42 40 02 00 00 00 00

Adding New Message Types

To add support for a new message type, edit swamp/protocol/swamp_protocol.py:

  1. Add the message type to decode_message() dispatcher
  2. Create a _decode_message_type_XX() method
  3. Implement encoding methods if needed:
    • encode_route_command() - Route audio source to zone
    • encode_volume_command() - Set zone volume
    • encode_power_command() - Control zone power

Development

Run tests:

pytest

The test suite uses dynamic port allocation (via get_free_port()) to avoid conflicts with running instances of the controller.

Enable debug logging:

python -m swamp --log-level DEBUG

Run on a different port:

python -m swamp --port 41795

License

Copyright © 2025

Metadata

Release files for crestron-swamp-controller 1.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for crestron-swamp-controller 1.4.0
File Size Uploaded
crestron_swamp_controller-1.4.0.tar.gz 31.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for crestron-swamp-controller 1.4.0
File Interpreter ABI Platform
crestron_swamp_controller-1.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 56.6 kB

Release files / crestron_swamp_controller-1.4.0.tar.gz

Download URL crestron_swamp_controller-1.4.0.tar.gz
Size 31.9 kB
Tags Source
SHA-256 checksum
How to use checksums
29c0dbd2fcf7bb8fab94ae0e81e9b80b0c85e87b5eb2b915ca207c4e0483355e
BLAKE2b-256 checksum
How to use checksums
0fa8ec9bd2cf4aed54ad9893d81559c287e35f43409e6341de1c29e13b952c9d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / crestron_swamp_controller-1.4.0-py3-none-any.whl

Download URL crestron_swamp_controller-1.4.0-py3-none-any.whl
Size 24.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9dc46d888e6dd7aca20444b107eba5e79e6cd7f5743967c7eb905ad562b89cd6
BLAKE2b-256 checksum
How to use checksums
efef7bf8d4f695997e10b3364e9e4c835126b8b675b81728108763a328a3810b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.4.0 This release

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page