Crestron SIMPL+ module for controlling Lyrion Music Server (LMS) via HTTP JSON-RPC on a CP4N processor.
Drop-in replacement for RoonDeviceModule v1.0 Build 10 — same signal layout, same panel wiring.
- Play, Pause, Stop, Next, Previous track
- Volume control (absolute, normalized, up/down, mute/unmute)
- Shuffle and Repeat (loop, loop one) toggle
- Seek (absolute and normalized)
- Now Playing feedback: title, artist, album, artwork URL
- Track position and duration with formatted time strings
- Player auto-discovery by name
The module does not use SIMPL+ TCP sockets (which silently fail on 4-series). Instead:
- A Generic TCP/IP Client symbol in SIMPL Windows handles TCP transport
- The SIMPL+ module formats HTTP JSON-RPC requests and parses responses via serial I/O
STRING_INPUT(notBUFFER_INPUT) is used for RX to avoid CIP auto-reconnect buffer accumulation issues- Polls LMS every 5 seconds using
WHILE(1) { DELAY(500); }inMain()
Each poll cycle: Connect -> Send HTTP POST -> Receive response -> Parse via Content-Length -> Disconnect.
| Parameter | Description | Example |
|---|---|---|
LMS_IP |
IP address of your LMS server | 192.168.1.180 |
DefaultPlayer |
Player name to control | Music Room |
Add a Generic TCP/IP Client symbol and wire it to the module:
| TCP/IP Client Signal | Module Signal | Direction |
|---|---|---|
| TCP_Connect (Connect) | TCP_Connect | Output from module |
| TCP_Connected (Connected) | TCP_Connected | Input to module |
| TCP_Disconnect (Disconnect) | TCP_Disconnect | Output from module |
| To_Device (TX) | To_Device | Output from module |
| From_Device (RX) | From_Device | Input to module |
Set the TCP/IP Client's port to 9000 and address to your LMS server IP.
The module's digital/analog/serial I/O matches RoonDeviceModule v1.0 Build 10 pin-for-pin, so existing panel smart objects and SIMPL logic work without changes.
The module communicates via HTTP POST to /jsonrpc.js:
{
"id": 1,
"method": "slim.request",
"params": ["<playerid>", ["<command>", "<args>"]]
}Player discovery uses ["players", 0, 10]. Status polling uses ["status", "-", 1, "tags:cgaldK"].
STRING_INPUTnotBUFFER_INPUTfor TCP RX:BUFFER_INPUThas a hidden internal buffer that accumulates data uncontrollably with CIP auto-reconnect.STRING_INPUTdelivers one chunk per CHANGE event with no hidden state.- CIP auto-reconnect: The Generic TCP/IP Client auto-reconnects when Connect=1 and the server closes the connection.
TCP_Connect = 0set in a CHANGE handler doesn't propagate fast enough to prevent it. Connection: close: LMS echoes this header back only if the client sends it. Without it, LMS keeps the connection alive.- SIMPL+ named WAITs: Must be defined lexically before any CANCELWAIT/RETIMEWAIT references.
WHILE+DELAYinMain()is simpler and more reliable for polling. progresetdoes not reset CIP sockets: If the socket enters a corrupted state (ObjectDisposedException), a full processor reboot is required.
MIT