Devialet Phantom Plugin
The Devialet plugin enables TMRemote to control Devialet Phantom speakers, Expert Pro amplifiers, and Dialog hubs via the Devialet IP Control API.
Supported Devices
- Phantom I - All variants (98dB, 103dB, 108dB)
- Phantom II - All variants (95dB, 98dB)
- Phantom Reactor - 600 and 900
- Expert Pro - With network connectivity
- Dialog - Hub for multi-room setups
- Arch - Soundbar
Features
- Volume control with smart acceleration (rapid clicks increase by 5 instead of 1)
- Source selection (Optical, AirPlay, Spotify Connect, Bluetooth, UPnP, Roon, etc.)
- Playback control (Play, Pause, Next, Previous)
- Mute/Unmute
- Night Mode toggle
- Power Off / Restart (standby) — wake requires physical button or Devialet app
- Bluetooth pairing mode (make device discoverable)
- mDNS device discovery
- System leader detection for stereo pairs
- Event-driven model — state changes fire events for scenario triggers
- State polling — detects external changes (from Devialet app, remotes)
- REST API — full control and event access via HTTP
Setup
1. Enable IP Control on Your Devialet
IP Control must be enabled in the Devialet app:
- Open the Devialet app on your phone
- Connect to your speaker
- Go to Settings > IP Control
- Enable IP Control
2. Add Device in TMRemote
- Open TMRemote and go to the Devialet plugin settings
- Click Discover to find devices on your network, or
- Enter the IP address manually and click Add
API Namespaces
The Devialet API uses different namespaces depending on your setup:
| Namespace | Use Case |
|---|---|
systems |
Stereo pairs and multi-room groups (recommended) |
devices |
Single speakers |
groups |
Multi-room configurations |
systems namespace which works for both stereo pairs and single speakers in most cases.
API Endpoints
The plugin communicates with the Devialet IP Control server running on port 80:
Base URL: http://{device-ip}/ipcontrol/v1/{namespace}/current/
Volume Control
| Endpoint | Method | Description |
|---|---|---|
sources/current/soundControl/volume |
GET | Get current volume (0-100) |
sources/current/soundControl/volume |
POST | Set volume: {"volume": 50} |
sources/current/soundControl/volumeUp |
POST | Increase volume by 1 |
sources/current/soundControl/volumeDown |
POST | Decrease volume by 1 |
Source Control
| Endpoint | Method | Description |
|---|---|---|
sources |
GET | List available sources |
sources/{sourceId}/playback/play |
POST | Switch to source |
Playback Control
| Endpoint | Method | Description |
|---|---|---|
sources/current/playback/play |
POST | Resume playback |
sources/current/playback/pause |
POST | Pause playback |
sources/current/playback/mute |
POST | Mute audio |
sources/current/playback/unmute |
POST | Unmute audio |
sources/current/playback/next |
POST | Next track |
sources/current/playback/previous |
POST | Previous track |
TMRemote REST API
The plugin exposes Devialet control through TMRemote's REST API. All endpoints are prefixed with /api/devialet/.
Device Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/devialet/devices |
GET | List all connected Devialet devices |
/api/devialet/devices/{id}/status |
GET | Get playback status, volume, source, and metadata |
Volume Control
| Endpoint | Method | Body |
|---|---|---|
/api/devialet/devices/{id}/volume |
GET | Returns {"volume": 50} |
/api/devialet/devices/{id}/volume |
POST | {"volume": 50} (0-100) |
/api/devialet/devices/{id}/mute |
POST | {"muted": true} or empty for toggle |
Source and Playback
| Endpoint | Method | Body |
|---|---|---|
/api/devialet/devices/{id}/source |
POST | {"sourceId": "optical"} |
/api/devialet/devices/{id}/playback |
POST | {"action": "play|pause|next|previous"} |
Power and Night Mode
| Endpoint | Method | Body |
|---|---|---|
/api/devialet/devices/{id}/power |
POST | {"action": "off|restart"} |
/api/devialet/devices/{id}/nightmode |
GET | Returns {"nightMode": true, "available": true} |
/api/devialet/devices/{id}/nightmode |
POST | {"enabled": true} |
/api/devialet/devices/{id}/bluetooth |
POST | {"action": "advertise"} — make device discoverable for pairing |
Events API
The plugin tracks state changes and exposes them via the events API. Events are stored in a ring buffer (last 100 events) and can be polled by external clients.
| Endpoint | Method | Description |
|---|---|---|
/api/devialet/events |
GET | Get recent events from all devices |
/api/devialet/devices/{id}/events |
GET | Get events for a specific device |
Query Parameters
| Parameter | Description | Example |
|---|---|---|
since |
Return events after this timestamp (ISO 8601) | ?since=2026-01-18T12:00:00 |
limit |
Maximum number of events to return (default: 100) | ?limit=10 |
type |
Filter by event type (partial match) | ?type=Volume |
Example Response
{
"events": [
{
"type": "DevialetVolumeChanged",
"deviceId": "devialet-192-168-1-100",
"deviceName": "Living Room Phantom",
"timestamp": "2026-01-18T14:30:00.000Z",
"data": { "volume": 45, "previousVolume": 40 }
},
{
"type": "DevialetSourceChanged",
"deviceId": "devialet-192-168-1-100",
"deviceName": "Living Room Phantom",
"timestamp": "2026-01-18T14:31:00.000Z",
"data": { "sourceId": "optical", "sourceType": "optical", "sourceName": "Optical", "previousSourceId": "airplay2" }
}
],
"count": 2,
"pollIntervalMs": 5000
}
Settings API
| Endpoint | Method | Description |
|---|---|---|
/api/devialet/settings |
GET | Get plugin settings |
/api/devialet/settings |
POST | Update plugin settings |
Settings Properties
| Property | Type | Description |
|---|---|---|
pollIntervalMs |
int | State polling interval in milliseconds (1000-60000) |
showNotifications |
bool | Show toast notifications for connection changes |
autoConnectOnStartup |
bool | Auto-connect to saved devices on TMRemote startup |
{id} is omitted, the first connected device is used.
Events
The plugin publishes events when device state changes. These events can trigger TMRemote scenarios and are available via the REST API.
Event Types
| Event | Description | Data |
|---|---|---|
DevialetVolumeChanged |
Volume level changed | volume, previousVolume |
DevialetSourceChanged |
Audio source changed | sourceId, sourceType, sourceName, previousSourceId |
DevialetPlaybackChanged |
Playback state changed | action, playingState, isPlaying |
DevialetMuteChanged |
Mute state changed | isMuted |
DevialetNightModeChanged |
Night mode toggled | isEnabled |
DevialetPowerChanged |
Power off or restart issued | action ("off" or "restart") |
DevialetBluetoothAdvertising |
Bluetooth pairing mode started | started |
DevialetConnectionChanged |
Device connected or disconnected | isConnected, reason, address |
Event Sources
Events are fired from two sources:
- Command execution: When you call an API endpoint (e.g., set volume), an event fires immediately after the command succeeds.
- State polling: The plugin polls device state at a configurable interval (default 5 seconds) and fires events when external changes are detected (e.g., volume changed via the Devialet app or remote).
/api/devialet/settings endpoint. Lower intervals provide faster detection but increase network traffic.
Technical Notes
Devialet IP Control Server
The Devialet speaker has an embedded HTTP server for IP Control. Important characteristics:
- Runs on port 80 (HTTP only, no HTTPS)
- Single-threaded - avoid parallel requests to prevent 503 errors
- Responses are JSON with
camelCaseproperty names - Errors may return HTTP 200 with error details in the JSON body
Smart Volume Acceleration
The plugin implements smart volume control matching the behavior of slPhantomRemote:
- Single press: volume changes by 1
- Rapid clicking (3+ presses within 1 second): volume changes by 5
This uses SetVolumeAsync() with a calculated value rather than the API's volumeUp/volumeDown endpoints (which only step by 1).
Optical/Digital Sources
Some source types cannot be paused (optical, HDMI, analog inputs). For these sources, the plugin automatically uses mute/unmute instead of play/pause.
Night Mode
Night Mode availability depends on firmware version:
- DOS 2.x: Uses
settings/audio/nightMode - DOS 3.x: Uses
settings/audio/nightModeOverlay
The plugin tries both endpoints automatically.
Troubleshooting
Device Not Found
- Ensure IP Control is enabled in the Devialet app
- Verify the speaker is on the same network as TMRemote
- Check firewall settings (port 80 must be accessible)
- Try using the IP address directly instead of discovery
Commands Fail or Timeout
- Check that the speaker is powered on (not in deep standby)
- Verify the IP address hasn't changed (use static IP)
- Check TMRemote logs for specific error messages
Volume Slider Not Updating
- Ensure the device is connected (check status in plugin settings)
- Check the poll interval setting (default 5000ms / 5 seconds)
- Verify the navigation panel is visible
- State polling runs in the background — changes may take up to one poll interval to appear
Events Not Firing
- Ensure the device is connected before expecting events
- Commands fired via API will generate events immediately
- External changes (Devialet app, remote) are detected via polling — check poll interval
- Use
GET /api/devialet/eventsto view recent event history
Sources Not Showing
- Sources are fetched when the device connects
- Disconnect and reconnect the device to refresh sources
- Check logs for JSON parsing errors
Reference
This plugin is based on the Devialet IP Control API as documented in slPhantomRemote. For detailed API specifications, see the slPhantomRemote documentation.