Python 3 library for discovering and controlling Pulse-Eight AV distribution hardware over a local network: video/audio matrices, HDMI-over-IP encoders/decoders, multiviewers, and audio amplifiers. Supports device discovery, video/audio routing, volume control, remote-control key passthrough, HDMI-over-IP streaming, multiviewer control, and more.
If you are looking to integrate Pulse-Eight neo, OneIP, or ProAmp8 devices into your own software or home-automation system, this is the library for it.
Documentation: opdenkamp.github.io/mx-remote
MX Remote is the network protocol these Pulse-Eight devices use to discover and control one another over UDP (multicast or broadcast). All of them run the shared MatrixOS firmware, which speaks this protocol natively. This library is a client implementation of that protocol — its purpose is to expose the devices to third-party software.
All devices below run MatrixOS and are controlled through the same protocol:
- Pulse-Eight neo — HDBaseT video/audio matrices (neo:4, neo:8, neo:X, and splitters)
- Pulse-Eight OneIP — HDMI-over-IP units: Transmitter (TX), Receiver (RX), Transceiver (TZ), and Multiviewer
- Pulse-Eight ProAmp8 — 8-zone audio amplifier with Dolby support
- Python 3.11 or later
- Network access to one or more of the Pulse-Eight devices above (multicast or broadcast)
pip install .The minimum code to discover devices on the network:
import asyncio
import mx_remote
async def main():
mx = mx_remote.Remote()
await mx.start_async()
# wait for devices to be discovered
await asyncio.sleep(5)
for uid, device in mx.remotes.items():
print(f"{device.serial} ({device.name}) - {device.model_name} - {device.status}")
for port, bay in device.bays.items():
print(f" {bay.bay_label} [{bay.mode}] signal={bay.signal_detected}")
await mx.close()
asyncio.run(main())The guides below are published at opdenkamp.github.io/mx-remote alongside an API reference generated from the docstrings, and are readable here in docs/.
| Page | Covers |
|---|---|
| Configuration | Opening a connection and keeping it in step with the mesh. |
| Devices and bays | Naming, hiding, EDID and the device registry. |
| Routing | Selecting video and audio sources for an output. |
| Callbacks | Reacting to state changes rather than polling for them. |
| Audio | Volume, mute and remote-control passthrough. |
| OneIP and V2IP | Streaming endpoints, stream sources and statistics. |
| Multiviewer | Layout, sources and output configuration. |
| Diagnostics | Network status, the mxr console app and capture replay. |
The same protocol, implemented independently:
- Go — https://github.com/opdenkamp/mx-remote-golang
- Rust — https://github.com/opdenkamp/mx-remote-rust (also ships a C ABI, for C and C++)
Python is the oldest of the three and the one that still decodes what older
firmware sent: 0x06, 0x36 and 0x47 are superseded opcodes kept because a
unit on older firmware still emits them. So it decodes a slightly wider set than
the others, and the difference is deliberate rather than drift.
BSD 3-Clause License. See LICENSE for details.