Skip to main content

Python library and CLI for controlling Blustream audio devices

Project description

Blustream

Open-source toolkit for controlling Blustream audio devices — starting with the DMP168 digital audio matrix processor — across three home-automation surfaces.

Components

This repository is a monorepo housing three deliverables that share a single protocol contract under spec/:

  1. Python library + CLI (blustream/). A clean async Python API and a blustream console script. Ships to PyPI on v* tags.
  2. Control4 driver (control4/dmp168/). A Lua driver packaged as a .c4z archive that exposes the matrix as a standard Control4 audio matrix. Ships as a GitHub release with the .c4z attached on c4-v* tags.
  3. Home Assistant integration (custom_components/blustream/). The directory is reserved and registered with HACS; the integration code itself is deferred to a future PRD. The eventual integration will depend on the published blustream PyPI library rather than re-embedding the protocol code.

The protocol primitives shared between the library and the driver are generated from spec/protocol.yaml via the codegen tooling under spec/codegen/. The Python and Lua emitters write into blustream/devices/dmp168/_generated.py and control4/dmp168/src/generated.lua respectively, and CI fails when those committed files drift from what the spec would produce.

Independent versioning

Each component releases on its own cadence using a distinct tag prefix. The prefixes are disjoint so a tag for one component cannot accidentally trigger the wrong release workflow.

Component Tag prefix Workflow Artifact
Python library v* .github/workflows/release-pypi.yml blustream on PyPI (sdist + wheel)
Control4 driver c4-v* .github/workflows/release-c4z.yml GitHub release with attached .c4z
HA integration reserved deferred deferred (will use HACS once built)

For example, a library bug-fix release tags v0.2.1, while a driver-only update tags c4-v0.3.0. The shared spec/ directory is the coordination point when a protocol change requires both components to move in lockstep.

Installation

Python library + CLI

Once published, the library installs from PyPI:

pip install blustream

For local development from a checkout:

pip install -e ".[dev]"

Or run the CLI directly from the checkout without installing:

uvx --from . blustream --host 192.168.1.100 status

Control4 driver

Download the .c4z from the latest GitHub release tagged c4-v* and install it through Composer Pro. See docs/control4-driver-plan.md for the dealer-load workflow.

Library Usage

import asyncio
from blustream import DMP168

async def main():
    # Connect to device
    device = DMP168(host='192.168.1.100', port=23)
    await device.connect()

    # Read status
    status = await device.get_status()
    print(f"Temperature: {status.temperature}°C")
    print(f"DSP Usage: {status.dsp_usage}%")

    # Control device
    await device.power_on()
    await device.set_output_volume(1, 75, unit='percent')
    await device.route_input_to_output(input_ch=2, output=1)

    # Context manager support
    async with DMP168(host='192.168.1.100') as device:
        status = await device.get_status()
        await device.power_on()

    # Disconnect
    await device.disconnect()

# Run the async function
asyncio.run(main())

CLI Usage

Subcommand names are derived from the command registry. Use blustream --help to list all commands and blustream <command> --help for parameter details.

Get Device Status

blustream --host 192.168.1.100 status

Power Control

blustream --host 192.168.1.100 power-on
blustream --host 192.168.1.100 power-off

Volume Control

# Set output 1 volume to 75%
blustream --host 192.168.1.100 output-volume --output 1 --level 75

# Set output 1 volume to -10 dB
blustream --host 192.168.1.100 output-volume --output 1 --level -10 --unit dB

# Increase output 1 volume by one step
blustream --host 192.168.1.100 output-volume --output 1 --increase-level

# Decrease output 1 volume by one step
blustream --host 192.168.1.100 output-volume --output 1 --decrease-level

Mute Control

# Mute output 1
blustream --host 192.168.1.100 output-mute --output 1 --mute

# Unmute output 1
blustream --host 192.168.1.100 output-mute --output 1 --no-mute

Routing

# Route input 2 to output 1
blustream --host 192.168.1.100 route --input 2 --output 1

Presets

# Save current configuration to preset 1
blustream --host 192.168.1.100 preset-save --preset 1

# Recall preset 1
blustream --host 192.168.1.100 preset-recall --preset 1

# Get preset status
blustream --host 192.168.1.100 preset-status --preset 1

JSON Output

# Get status as JSON
blustream --host 192.168.1.100 status --json

Command Line Options

Global flags must appear before the subcommand (e.g. blustream --yes reboot, not blustream reboot --yes).

  • --device: Device type (default: dmp168)
  • --host: Device hostname or IP address (default: localhost)
  • --port: TCP port (default: 23)
  • --timeout: Connection timeout in seconds (default: 5.0)
  • --verbose, -v: Enable verbose output
  • --debug: Enable debug output
  • --json: Output results as JSON
  • --yes, -y: Skip confirmations

Architecture

The library is designed with extensibility in mind:

  • Base Framework: Abstract base classes for devices and connections
  • Device Implementations: Device-specific code in separate modules
  • Command Registry: Commands are registered with metadata for introspection
  • Connection Layer: Pluggable connection implementations (TCP/IP, serial, etc.)

Supported Devices

  • DMP168: Digital audio matrix processor (16 inputs, 8 outputs)

Development

Project Structure

blustream/
├── blustream/              # Main package
│   ├── base/                # Base classes and interfaces
│   ├── connection/          # Connection implementations
│   ├── devices/             # Device-specific implementations
│   │   └── dmp168/          # DMP168 device
│   └── cli/                 # CLI implementation
├── tests/                   # Test suite
├── main.py                  # CLI entry point
└── README.md               # This file

Running Tests

pytest tests/

Lua development

The Control4 driver lives under control4/ and targets Lua 5.1 (the version the Control4 Composer sandbox runs). CI lints all Lua sources with luacheck and runs the unit tests with busted — see .github/workflows/lua.yml.

To install the toolchain locally:

# macOS
brew install lua@5.1 luarocks
luarocks --lua-version=5.1 install luacheck
luarocks --lua-version=5.1 install busted

# Debian / Ubuntu
sudo apt-get install lua5.1 liblua5.1-0-dev luarocks
sudo luarocks --lua-version=5.1 install luacheck
sudo luarocks --lua-version=5.1 install busted

Then, from the repo root:

luacheck .                              # lint all Lua source
busted --pattern=_spec control4/        # run Lua unit tests

License

This project is licensed under the Apache License 2.0.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Future Enhancements

See FUTURE_ENHANCEMENTS.md for planned features and improvements.

Project details


Download files

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

Source Distribution

blustream-0.1.0.tar.gz (64.7 kB view details)

Uploaded Source

Built Distribution

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

blustream-0.1.0-py3-none-any.whl (40.8 kB view details)

Uploaded Python 3

File details

Details for the file blustream-0.1.0.tar.gz.

File metadata

  • Download URL: blustream-0.1.0.tar.gz
  • Upload date:
  • Size: 64.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for blustream-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d4ef0aba54f69faf8065e99c068cd925c67db2249174ffbd25e6e33d1e81216f
MD5 7a6a7e54606f6b768f53f3f85c851668
BLAKE2b-256 fbf201c111ad3553d72e3053f2044d030effb25f0a204635f3d4238438b8226a

See more details on using hashes here.

Provenance

The following attestation bundles were made for blustream-0.1.0.tar.gz:

Publisher: release-pypi.yml on caidurbin/blustream

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

File details

Details for the file blustream-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: blustream-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 40.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for blustream-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f7d3b9061d7cb91fdda4673008ab1eb4ef24ab5715fe172099f17358c6baf733
MD5 2e034afffd81d52435f828171893763d
BLAKE2b-256 d733475a74a5d7cbe4b7b577dcd0fabaff8e28c39743f3f1277d69741acf5f58

See more details on using hashes here.

Provenance

The following attestation bundles were made for blustream-0.1.0-py3-none-any.whl:

Publisher: release-pypi.yml on caidurbin/blustream

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