Autonomic Mirage (MMS)
For Spotify on the player with the Spotify source page (playlist tiles, liked songs, search), add a Spotify (Autonomic Mirage) device on the same instance — the player accepts both sessions.
Autonomic Mirage / MMS music servers (the eMMS, MMS-1e/2e/5e and related models from
Autonomic / Snap One) are controlled over the MMS control protocol on TCP port 5004 — short
text commands terminated by a carriage-return/line-feed. One player instance inside the
server — Player_A, Player_B, … — becomes one GEM device, so a single server that streams
several rooms is represented by several GEM devices, one per player.
This driver creates no zones. A Mirage player is a source: you expose each player as an AV source that a user selects on a touchpanel, and route its audio to rooms through your matrix or amplifier the same way you would any other audio source. What you get on screen:
- Streaming source & station browsing — the player's radio/streaming providers (Spotify, Pandora, SiriusXM, internet radio, and whatever the server has accounts for), their stations, genres, favorites, and the music library (albums, artists, genres, playlists).
- Live now-playing — station, artist, album, and track for what the player is currently streaming, plus track time and duration, pushed to the source panel as it changes.
- Full transport and play modes — play / pause / stop / skip, volume, mute, repeat, shuffle, and thumbs up / down where the streaming provider supports rating.
- Presets, playlists, and queue management — store and recall presets, save / rename / delete playlists, and reorder, jump within, or clear the now-playing queue.
What it does
- Transport: play, pause, stop, play/pause toggle, skip next / previous, and seek to a position.
- Volume: volume up / down, mute, and absolute set-volume (where the player exposes volume).
- Play modes: repeat and shuffle toggles; thumbs up / down and add / remove from library for services that rate tracks.
- Browse: the streaming/radio sources, stations, and genres; the music library (albums, artists, genres, playlists); favorites; and the live now-playing queue.
- Direct play: start an album, artist, genre, or playlist by its server id (GUID).
- Presets: store, recall, and delete presets by name or id; the player's presets also sync into a channel provider named after the device so they appear in the Channel widget and the AV source preset list.
- Playlists: save the current queue as a playlist, rename a playlist, and delete one.
- Queue: jump to a track, reorder, remove a single item, or clear the now-playing queue.
- Live now-playing written back as device attributes (station / artist / album / track, track time and duration) so it feeds the source panel and can drive widgets and triggers.
- A dedicated Mirage source view for end users (browse providers/stations + now-playing +
transport). Set the AV source's Component to
mirageto get it.
Prerequisites
- An Autonomic Mirage / MMS server reachable on the same LAN as GEM, with its control protocol enabled (it listens on TCP 5004 by default).
- A static IP or a DHCP reservation for the server so its address never moves — a moved address means GEM can no longer reach it.
- For each room you want to control independently, a distinct player instance configured on
the MMS (
Player_A,Player_B, …). You will create one GEM device per player.
Setup
Open Devices
- Confirm the MMS server's control protocol is reachable on port 5004 (the default; enable it in the server's configuration if it has been turned off).
- Go to System → Devices → Add Device and choose the Autonomic Mirage (MMS) driver.
- Set MMS IP Address to the server's LAN IP and leave TCP Port at 5004.
- Set Player Instance to the player that drives this room —
Player_Aby default. This is the single most important field: every command this device sends targets that one player, so it must match the player the server has assigned to the room. - (Optional) Set Client Name (an identifier GEM advertises to the server; defaults to
GEM). - Save and enable the device. On connect GEM runs its start-up sequence (announce client, set the server host, switch the server to list/UTF-8 mode, select the configured player, and subscribe to event pushes) and then reads current status. Within a few seconds the device shows connected.
For a multi-room server, add one GEM device per player instance — same IP and port on each,
with a different Player Instance (Player_A, Player_B, Player_C, …). Two GEM devices can
share one player instance — the server keeps both sessions live and answers each — which is how a
Spotify (Autonomic Mirage) device runs beside the main one. Each device on a
shared instance sees and controls the same player, so a second device is only useful when it adds
something (like Spotify search), not as a separate room.
Using a Mirage player as an AV source
Open AV Sources
To put a player on a touchpanel as a selectable source with the browse + now-playing panel, create an AV source for it:
-
Add a source whose Device is this Mirage device (the one bound to the player you want).
-
Set the Component field to
mirage. -
Set AV Type to Audio.
-
Mark it Global source (not zone-specific) if every room should be able to select it, or assign it to a single AV zone for a one-room player.
-
Save. When a user selects that source, GEM draws the Mirage panel. Opening it runs several round trips to the player, so the panel first shows a spinner and Loading… and swaps to the full view once the player answers. If a start-up step fails, the panel shows Player unavailable with the reason instead of sitting on the spinner. Once loaded:
- the Browse side lists the player's streaming/radio sources and their stations, with a search box;
- the Now Playing side shows the current station / artist / album / track with cover art
and the thumbs up / down controls. Transport, volume, shuffle and repeat sit on the shared
media bar at the bottom of the screen: shuffle and repeat highlight from the player's
reported state and are hidden while the current service does not accept them (the
shuffle__available/repeat__availableattributes below), and on phones the bar drops them along with previous, keeping play / pause / next. When a browse drill-down lands on a station or track list, this side displays that list instead and takes the name the player gives the list — Playlists, Followed Artists, a playlist's own title for its tracks — falling back to Stations or Tracks when the player sends no name. Pressing back restores the parent list under the parent's name (on phones, where the two sides become tabs, the tab name follows what the pane is showing). A short list is a menu: it replaces the tree on the Browse side only, and this side returns to Now Playing rather than showing the same menu twice.
The panel's button bar carries browse home / back, now-playing info, and search / clear search. Home and back sit under the Browse side, since they move the whole browse tree; info and search act only on the other side and sit under it. Info flips that side between Now Playing and the drilled list, so it is hidden while there is no list to flip to. On phones, where one side shows at a time, home and back appear on both bars so they are always reachable. Library add / remove are not on the bar — the
add_to_libraryandremove_from_librarycommands are still available to macros and Button widgets.
If you create one source per player and mark each global, every room can pick any player. To route the player's audio to a room, give the source an On Macro that switches your matrix or amplifier input — see AV Sources for the source editor (Device, Component, Global, routing macros) and AV Zones for routing the source into rooms.
To limit which streaming/radio providers appear in the Browse panel, set the optional
provider_whitelist attribute on the device to a JSON list of provider names (for example
["Spotify", "Pandora"]). When set, the source view shows only those providers; leave it empty to
show everything the server offers.
Presets as a channel provider
The player's Presets / Favorites — the snapshots the MMS stores when you save a station, playlist, or the current queue — sync into a GEM channel provider named after the device. Each preset becomes one channel row, so the presets show up anywhere a channel provider is consumed: the Channel widget's tile grid and the AV source preset list.
- Sync timing — the driver reads the preset list a moment after it connects, again within a
couple of seconds of any change, and once a day as a backstop. The player pushes
FavoritesChangedwhenever a preset is stored or deleted — by GEM, a macro, or the Mirage app — and the driver re-reads on that push, so the provider tracks the player's list live. Alast_channel_synctimestamp throttles the connect-time read, so a flapping connection does not re-read on every reconnect. - Recall is by GUID — each channel row carries the preset's server id in its channel field and
recalls it with
RecallPreset, which works from any point in the browse tree. Selecting a preset tile therefore starts it immediately with no navigation, and works the same whichever streaming service the preset came from. - Provider binding — on first sync the driver points this device's AV sources at the new provider, but only ones that do not already name a provider, so a hand-assigned provider is never overwritten. Presets deleted on the player are removed from the provider on the next sync; the provider row and its channels are left untouched if a sync cannot read the player.
- Populating presets — save them from the Mirage page's save button (below), the Mirage/MMS app,
or with the
store_presetcommand from a macro or Button widget.store_presetsnapshots whatever the player is on — station, playlist or queue — under the name you give it; the name is the only argument because the content is implicit. Storing a name that already exists overwrites that preset (verified on hardware). An empty preset list produces an empty provider.
Presets on the Mirage page
The Mirage source page (/av/mirage) works with presets directly:
- Save — the save button under the Now Playing card stores what is playing as a preset. The
on-screen keyboard opens pre-filled with the player's own name for the current queue
(
default_preset_name, e.g. "FISHER and others on Spotify"); retype it or press enter to keep it. A toast confirms once the player has reported the new list. - List and recall — the star button in the browse bar lists the presets in the left pane, with cover art where the player has it. Tapping one recalls it; the preset the player reports as current is highlighted.
- Delete — the edit button in the presets view reveals a delete button per row, each behind a confirmation.
Because the list refreshes from the player's own change push, a preset saved or deleted from the Mirage app appears or disappears here, in the Channel widget and in the AV preset list within a few seconds.
Cover art for each preset is taken from the MMS web service and, like now-playing art, must be reachable from the GEM server (see below).
How now-playing works
As the player streams, the server pushes metadata events and GEM writes the current station, artist, album, and track, along with track time and track duration, back onto the device as attributes. Cover art is fetched from the MMS server's own web service (the server reports its base URL; it defaults to port 5005 on the same IP). GEM proxies that image through the server rather than loading it directly in the browser, so cover art displays correctly on secured (HTTPS) touchpanels without being blocked as mixed content — the trade-off is that port 5005 must be reachable from the GEM server, not from each client.
On the panel, the track clock only appears when the player reports a time: nothing playing means no
clock at all, and a live radio stream — which has an elapsed time but no fixed length — shows just
the elapsed side rather than a 0:00 duration that would read as a stalled track. Times run m:ss
and roll over to h:mm:ss past an hour, so a long mix or set reads as 1:24:12 rather than
84:12.
Unlike some source drivers, these now-playing fields are stored as device attributes, so they can drive now-playing widgets and be used as attribute-trigger conditions — for example, an automation that fires when a particular station starts playing.
Attributes
Device — required
| Attribute | Type | Description |
|---|---|---|
ip | string | The MMS server's LAN IP (the MMS IP Address field). |
port | int | Control-protocol port (the TCP Port field). Defaults to 5004. |
Device — optional
| Attribute | Type | Default | Description |
|---|---|---|---|
instance | string | Player_A | Which player inside the server this device controls (the Player Instance field) — Player_A … Player_F. |
client_name | string | GEM | Identifier GEM advertises to the server on connect. |
client_version | string | 1.0.0.0 | Client version string GEM advertises on connect. |
max_buffer | int | 1048576 | Largest single response GEM will buffer, in bytes. Browse responses for large libraries (a full Spotify album list can exceed 60 KB) need a big buffer; the 1 MB default covers most catalogs — raise it for unusually large libraries. |
provider_whitelist | json | — | Optional list of provider names to show in the Mirage source view's Browse panel (for example ["Spotify"]). Empty shows all providers. |
Device — live state (written by the driver)
The driver writes the player's current state back onto the device as it changes. These names are stable, so you can bind widgets to them and build attribute triggers:
| Attribute | Type | Meaning |
|---|---|---|
now_playing_station | string | Current station / service name. |
now_playing_artist | string | Current artist. |
now_playing_album | string | Current album. |
now_playing_track | string | Current track title. |
now_playing_guid | string | Server id of the now-playing item. |
tracktime | int | Elapsed time of the current track, in seconds. |
trackduration | int | Total length of the current track, in seconds. |
mute | bool | Whether the player is muted. |
repeat | bool | Whether repeat is on. |
shuffle | bool | Whether shuffle is on. |
repeat__available / shuffle__available | bool | Whether the current service accepts the command. The media bar hides its repeat / shuffle buttons while these are false. |
thumbsup / thumbsdown / stars | int | Current rating state reported by the streaming service. |
current_preset | string | Name of the preset the player is on after a recall; blank otherwise (storing a preset does not set it). |
default_preset_name | string | The name the player itself would give the current queue as a preset — the Mirage page's save prompt default. |
preset_count | int | Number of presets on the player. |
last_channel_sync | date | When the driver last synced the player's presets into the channel provider. |
The driver also publishes transport-availability flags — play_pause__available,
skip_next__available, skip_prev__available, repeat__available, shuffle__available,
seek__available (booleans, with the double underscore exactly as shown) — indicating which
controls the current stream actually offers, plus a back boolean for whether menu-back navigation
is available.
This driver creates no zones, so there are no zone attributes. The attribute catalog lists the
configuration fields and the three preset-state attributes (current_preset, default_preset_name,
preset_count) under this driver; the now-playing, transport and rating attributes are not
catalogued, so type those names exactly as shown when referencing them.
Commands
Driver-declared commands appear on the device's Commands tab and can be used in macros, triggers, and on UI buttons. Browse and direct-play commands are mainly consumed by the source view, but they are equally available to macros.
Transport
| Command | Args | Action |
|---|---|---|
play pause stop play_pause | — | Playback transport (play_pause toggles). |
next / skip_next | — | Skip to the next track. |
previous / skip_previous | — | Skip to the previous track. |
seek | position | Seek to a position in the current track. |
Volume and play modes
| Command | Args | Action |
|---|---|---|
volume_up volume_down | — | Step the player volume. |
mute | — | Toggle mute. |
set_volume | level | Set absolute volume (players that expose volume). |
repeat | state (optional) | Toggle repeat, or set it: on / off (also true / false). The player's own verb only ever turns the mode on, so the toggle is derived from the last reported state. |
shuffle | state (optional) | Toggle shuffle, or set it — same forms as repeat. |
repeat_on repeat_off shuffle_on shuffle_off | — | Explicit forms for macros. |
thumbs_up thumbs_down | — | Rate the current track (rating-capable services). |
add_to_library remove_from_library | — | Save / remove the now-playing track from the streaming service's library (for example Spotify's My Music). Works through the now-playing context menu, so the current source must offer a per-track save action; a track already in (or already absent from) the library is a no-op. Not on the Mirage panel — drive these from a macro or a Button widget. |
context_menu | — | Open the now-playing context menu. Returns a list of per-service actions (save song, save album, follow artist, …); select one with select_item / ack_pick_item. |
Browse
| Command | Args | Action |
|---|---|---|
browse_top_menu | — | Browse the player's top menu. |
browse_albums browse_artists browse_genres browse_playlists browse_favorites | start, count | Page through a music-library category (defaults: start 1, count 10). |
browse_presets | start, count | Page the player's presets / favorites (defaults: start 1, count 100) and return them: {presets: [{guid, name, artGuid, logo}]}. The preset sync reads this, and so do the argument pickers on the preset verbs below. |
browse_now_playing | start, count | Page through the now-playing queue. |
browse_radio_sources | — | List the player's streaming / radio providers. |
browse_radio_stations browse_radio_genres | start, count | Page stations / genres for the active radio source. |
browse | action, start, count | Run an arbitrary browse verb with paging — the escape hatch for browse actions without a named command. With no action it returns the error action required without sending anything. |
A browse response carries the list header alongside its items: caption (the name the player
gives the list — "Playlists", "Home Menu", a playlist's title for its tracks), source (the
provider), and the paging fields total, start and more (more is a boolean). Each is present
only when the player sent it, so a macro can title a list or decide whether to page without
tracking the browse path itself.
Direct play
| Command | Args | Action |
|---|---|---|
play_album play_artist play_genre play_playlist | guid | Start a library item by its server id. |
select_item / ack_pick_item | guid | Choose an item from a picklist returned by a browse. ack_pick_item with no guid returns the error guid required without sending anything. |
Presets and playlists
| Command | Args | Action |
|---|---|---|
store_preset | name | Save what is playing now as a preset under name; an existing name is overwritten. Omit name for the player's default slot. The player pushes FavoritesChanged afterwards, which refreshes the channel provider and any open Mirage page. |
recall_preset | name or guid | Recall a preset by name or id. |
recall_preset_guid | guid | Recall a preset by id (the id-only form of recall_preset). |
set_channel | channel | Recall the preset whose id is in channel. This is the channel-provider dispatch verb the Channel widget and AV preset grid send; you rarely call it directly. |
delete_preset | name or guid | Delete a preset. A name is sent in double quotes, as recall_preset sends it; an id is sent as-is. |
save_playlist | name | Save the now-playing queue as a playlist. |
rename_playlist | old_name, new_name | Rename a playlist. |
delete_playlist | name or guid | Delete a playlist. A name is sent in double quotes; an id is sent as-is. |
Preset and playlist names travel in double quotes, so a name can contain spaces but not a double
quote: store_preset, recall_preset, delete_preset, save_playlist, rename_playlist and
delete_playlist return the error names cannot contain double quotes without sending anything when
a name contains one. The player's escape for a quote inside a name is not known. The delete-by-name
forms have not been tried against a player; delete by id is the path the Mirage page uses.
The name, guid and channel arguments of recall_preset, recall_preset_guid, delete_preset
and set_channel are dropdowns wherever commands are configured — the Commands tester, macro steps,
Button widgets. They are filled live by running browse_presets on the selected device (the
[@command:…] placeholder described in Commands), so the list is the
player's presets at the moment you open the picker; the id pickers show name (guid) and send the
id. Free text still works, and the picker stays empty until a concrete device is selected. On the
Mirage page, opening the preset list runs the same command and shows a warning toast if the player
does not answer.
Queue
| Command | Args | Action |
|---|---|---|
jump_to_track | index | Jump to a position in the now-playing queue and play it. |
reorder_queue | from, to | Move a queue item from one position to another. |
remove_from_queue | index | Remove a single item from the queue. |
clear_queue | — | Clear the now-playing queue. |
Status, navigation, and filters
| Command | Args | Action |
|---|---|---|
get_status | — | Request a full status refresh. |
set_instance / set_zone | instance | Re-point this connection at a different player instance at run time. It lasts until the next reconnect, which re-binds the device's configured Player Instance; album-art links follow whichever instance the connection is on. |
back | steps | Step back in the on-screen menu (default 1 step). |
set_radio_source | source | Filter the radio browse to one source. |
clear_music_filter clear_radio_filter | — | Clear the music / radio browse filter. |
Advanced
| Command | Args | Action |
|---|---|---|
passthrough | command | Send a raw control-protocol command verbatim — for any verb the named commands don't cover. |
Known limitations
- One connection per player. Each GEM device controls a single MMS player instance. For
multi-room, create one device per
Player_X. Two devices on the same player both stay connected, but they control the same room — see the setup section above. - No zones. A Mirage player is one device and creates no GEM zones — route it to rooms at the AV-source / AV-zone layer, like any other source.
- Large browse responses. Big catalogs (a full Spotify album list, large playlists) can exceed
60 KB; the 1 MB
max_bufferdefault covers most cases — raise it for unusually large libraries. - List/UTF-8 mode is fixed on connect. GEM puts the server into list mode and UTF-8 encoding at
start-up; don't override those with
passthroughmid-session or browse parsing will break.
Troubleshooting
| Symptom | Check |
|---|---|
| Commands are accepted but the wrong room reacts. | The Player Instance is wrong. Confirm the Player_A / Player_B / … value matches the player the MMS has assigned to that room. |
| The connection flaps up and down on the dashboard. | Check the network path to the server and its TCP port (5004). A second GEM device on the same player instance is not the cause — the server keeps both sessions live. GEM also drops and redials the connection on its own when the server stops answering at the network level (it lost power, rebooted or left the network). |
| Browse responses are truncated or never resolve. | Raise Max Response Buffer (max_buffer) above 1 MB for very large libraries, and confirm nothing has overridden the server's list mode mid-session. |
| The Browse panel is missing providers. | The provider_whitelist attribute may be filtering them out. Clear it to show every provider, or add the provider's name to the list. |
| The source view shows Player unavailable with a message. | A start-up step failed before the panel could draw. Confirm the device exists, is enabled, and is connected on port 5004, then reopen the source. |
| The source view sits on Loading…. | The player is not answering the start-up round trips. Check the device's connection state on the dashboard and that the MMS is reachable from the GEM server. |
| No track times show on the panel. | Expected when nothing is playing. A live radio stream shows only elapsed time, since the stream has no fixed duration. |
| Now-playing or cover art is blank. | Confirm the device is connected and the player is actually streaming; cover art is served by the MMS web service (port 5005 by default), which GEM proxies through the server — so that port must be reachable from the GEM server, not from the client browser. |
See also
- AV Sources — add a Mirage player as a selectable source and pick the
miragepanel. - AV Zones — route the source into rooms.
- Devices — adding and configuring devices.
- Commands — running and scripting device commands.