Skip to content

Commit

Permalink
Merge pull request #1838 from 1ockwood/mqtt-documentation-updates
Browse files Browse the repository at this point in the history
Update MQTT.md. Thanks!
  • Loading branch information
mikebrady authored Apr 7, 2024
2 parents d5d9843 + 5959a08 commit b5ea2b1
Showing 1 changed file with 57 additions and 75 deletions.
132 changes: 57 additions & 75 deletions MQTT.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
MQTT in Shairport Sync
====
# MQTT in Shairport Sync

To enable Shairport Sync to act as an MQTT publisher, you need to:
1. Install the mosquitto library:
```
# apt install libmosquitto-dev
```
2. Add the configuration flag `--with-mqtt-client` to the list of parameters to the `./configure...` command, for example:
2. Add the configuration flag `--with-mqtt-client` to the list of parameters to the `./configure...` command. For example:
```
$ ./configure --with-mqtt-client --sysconfdir=/etc --with-alsa --with-avahi --with-ssl=openssl --with-systemd
```
Expand All @@ -16,82 +16,71 @@ $ shairport-sync -V
3.3.8-OpenSSL-Avahi-ALSA-metadata-mqtt-sysconfdir:/etc
```

Setting Up MQTT Publishing
====
**Note:** [The Docker image](https://hub.docker.com/r/mikebrady/shairport-sync) will have MQTT support enabled by default.

This is a rough guide on the setup of MQTT publishing in ShairPort-Sync. The MQTT service listens for and publishes metadata generated by the airplay source and shairport-sync.
## Setting Up MQTT Publishing

Below is a simple example of configuring shairport-sync to send parsed metadata to a MQTT server under the topic "shairport"
This is a rough guide on the setup of MQTT publishing in ShairPort Sync. The MQTT service listens for and publishes metadata generated by the AirPlay source and Shairport Sync.

Example Configuration
----
### Example Configuration

Shairport-sync is configured below to published parsed metadata information and album-art to a MQTT server.
In the following example, Shairport Sync is configured to publish parsed metadata information and album-art to a MQTT server under the topic "shairport".

```xml

metadata =
{
enabled = "yes"; // set this to yes to get Shairport Sync to solicit metadata from the source and to pass it on via a pipe
include_cover_art = "yes"; // set to "yes" to get Shairport Sync to solicit cover art from the source and pass it via the pipe. You must also set "enabled" to "yes".
cover_art_cache_directory = "/tmp/shairport-sync/.cache/coverart"; // artwork will be stored in this directory if the dbus or MPRIS interfaces are enabled or if the MQTT client is in use. Set it to "" to prevent caching, which may be useful on some systems
enabled = "yes"; // Set this to yes to get Shairport Sync to solicit metadata from the source and to pass it on via a pipe.
include_cover_art = "yes"; // Set to "yes" to get Shairport Sync to solicit cover art from the source and pass it via the pipe. You must also set "enabled" to "yes".
cover_art_cache_directory = "/tmp/shairport-sync/.cache/coverart"; // Artwork will be stored in this directory if the dbus or MPRIS interfaces are enabled or if the MQTT client is in use. Set it to "" to prevent caching, which may be useful on some systems.
pipe_name = "/tmp/shairport-sync-metadata";
pipe_timeout = 5000; // wait for this number of milliseconds for a blocked pipe to unblock before giving up
pipe_timeout = 5000; // Wait for this number of milliseconds for a blocked pipe to unblock before giving up.
};


mqtt =
{
enabled = "yes"; // set this to yes to enable the mqtt-metadata-service
hostname = "192.168.1.111"; // Hostname of the MQTT Broker
port = 1883; // Port on the MQTT Broker to connect to
username = "username"; //set this to a string to your username in order to enable username authentication
password = "password"; //set this to a string you your password in order to enable username & password authentication
topic = "shairport"; //MQTT topic where this instance of shairport-sync should publish. If not set, the general.name value is used.
// publish_raw = "no"; //whether to publish all available metadata under the codes given in the 'metadata' docs.
publish_parsed = "yes"; //whether to publish a small (but useful) subset of metadata under human-understandable topics
publish_cover = "yes"; //whether to publish the cover over mqtt in binary form. This may lead to a bit of load on the broker
// enable_remote = "no"; //whether to remote control via MQTT. RC is available under `topic`/remote.
enabled = "yes"; // Set this to yes to enable the mqtt-metadata-service.
hostname = "192.168.1.111"; // Hostname of the MQTT Broker.
port = 1883; // Port on the MQTT Broker to connect to.
username = "username"; // Set this to your MQTT user's username in order to enable username authentication.
password = "password"; // Set this to your MQTT user's password in order to enable username & password authentication.
topic = "shairport"; // MQTT topic where this instance of Shairport Sync should publish. If not set, the general.name value is used.
// publish_raw = "no"; // Whether to publish all available metadata under the codes given in the 'metadata' docs.
publish_parsed = "yes"; // Whether to publish a small (but useful) subset of metadata under human-understandable topics.
publish_cover = "yes"; // Whether to publish the cover over MQTT in binary form. This may lead to a bit of load on the broker.
// enable_remote = "no"; // Whether to remote control via MQTT. RC is available under `topic`/remote.
};
```
**Important:** Either `publish_raw`, `publish_parsed`, or `publish_cover` need to be set in the MQTT configuration. Otherwise, no messages will be published.

Import Notes
----

Publish Options

One needs to set either `publish_raw`, `publish_parsed` or `publish_cover` in the MQTT setup or no messages will be published.


Overall Active State of Stream
## Overall Active States

`active_start` and `active_end` represent a stable on/off flag for the current airplay session.
`active_start` and `active_end` represent a stable on/off flag for the current AirPlay session.

`active_start` is plublished when any new airplay session begins
`active_start` is plublished when any new AirPlay session begins.

`active_end` will fire after a configured timeout period unless the airplay stream is resumed.
`active_end` will fire after a configured timeout period unless the AirPlay stream is resumed.

```xml
sessioncontrol =
{
// "active" state starts when play begins and ends when the active_state_timeout has elapsed after play ends, unless another play session starts before the timeout has fully elapsed.
// "active" state starts when play begins, and ends when the active_state_timeout has elapsed after play ends, unless another play session starts before the timeout has fully elapsed.
active_state_timeout = 30.0;
};
```

MetaData Parsing
----
## Metadata Parsing

Additional details regarding the metadata can be found at https://github.com/mikebrady/shairport-sync-metadata-reader.

Additional details regarding the metadata can be found at [https://github.com/mikebrady/shairport-sync-metadata-reader]

Meta data is generated by both the stream source (iOS, itunes, etc) and by shairport-sync itself. This data is coded as two 4-character codes to identify each piece of data, the `type` and the `code`.
Metadata is generated by both the stream source (iOS, iTunes, etc.) and by Shairport Sync itself. This data is coded as two 4-character codes to identify each piece of data, the `type` and the `code`.

The first 4-character code, called the `type`, is either:
* `core` for all the regular metadadata coming from iTunes, etc., or
* `ssnc` (for 'shairport-sync') for all metadata coming from Shairport Sync itself, such as start/end delimiters, etc.

* For `core` metadata, the second 4-character code is the 4-character metadata code that comes from iTunes etc. See, for example, https://code.google.com/p/ytrack/wiki/DMAP for information about the significance of the codes. The original data supplied by the source, if any, follows, and is encoded in base64 format. The length of the data is also provided.
Additionally:
* For `core` metadata, the second 4-character code is the 4-character metadata code that comes from iTunes, etc. See, for example, https://code.google.com/p/ytrack/wiki/DMAP for information about the significance of the codes. The original data supplied by the source, if any, follows, and is encoded in base64 format. The length of the data is also provided.
* For `ssnc` metadata, the second 4-character code is used to distinguish the messages. Cover art, coming from the source, is not tagged in the same way as other metadata, it seems, so is sent as an `ssnc` type metadata message with the code `PICT`. Progress information, similarly, is not tagged like other source-originated metadata, so it is sent as an `ssnc` type with the code `prgr`.

Here are some of the `core` codes commonly passed from the source:
Expand Down Expand Up @@ -128,14 +117,12 @@ Here are the 'ssnc' codes defined so far:
* `stal` -- this is an error message meaning that reception of a large piece of metadata, usually a large picture, has stalled; bad things may happen.
* `svip` -- the payload is the IP address of the server, i.e. shairport-sync. Can be an IPv4 or an IPv6 address.

### Parsed Messages

Parsed Messages
----

The MQTT service can parse the above raw messages into a subset of human-readable topics that include,
The MQTT service can parse the above raw messages into a subset of human-readable topics that include:

* `active_remote_id` -- Active Remote ID
* `artist` -- text of artist name
* `artist` -- text of artist name
* `album` -- text of album name
* `client_ip` -- IP address of the connected client
* `client_device_id` -- Client advertised Device ID
Expand All @@ -145,50 +132,45 @@ The MQTT service can parse the above raw messages into a subset of human-readabl
* `dacp_id` -- DACP ID
* `format` -- ??
* `genre` -- text of genre
* `server_ip` -- IP address of shairport-sync that the client is connected to
* `songalbum` --
* `server_ip` -- IP address of Shairport Sync that the client is connected to
* `songalbum` --
* `title` -- text of song title
* `volume` -- The volume is sent as a string -- "airplay_volume,volume,lowest_volume,highest_volume", where "volume", "lowest_volume" and "highest_volume" are given in dB. (see above)

and empty messages (`--`) at the following topics are published.
Additionally, empty messages (`--`) at the following topics are published.

* `play_start` -- fired at the begining of every song
* `play_end` -- fired at the end of every song
* `play_flush` -- fired when song is skipped or on positional change
* `play_resume` -- fired when song play resumes from pause
* `active_start` -- fired when a new active airplay session begins
* `active_start` -- fired when a new active AirPlay session begins
* `active_end` -- fired after a configured timeout period after the stream ends (unless a new stream begins)



## Consuming MQTT Data

Users will find examples on how to consume the MQTT data in various home automation projects. If a user has an interesting use please raise a new issue to suggest adding it to the guide, or simply fork the development branch and create a pull-request.
MQTT provides users with the flexibility to consume the MQTT data in various home automation projects. If you have an interesting use, please raise a new issue to suggest adding it to the guide, or simply fork the development branch and create a pull request.

### Home Assistant Variable Templates
### [Home Assistant](https://www.home-assistant.io/) Examples

Examples of consuming "parsed" MQTT data in [Home Assistant](https://www.home-assistant.io/)
The `active_start` and `active_end` have good potential use as triggers to turn on and off various connect receivers/zones. "payload_off" is set to prevent accidental triggering.
The `active_start` and `active_end` have good potential use as triggers to turn on and off various connected receivers/zones. Note that `payload_off` is set to prevent accidental triggering.

```yml
binary_sensor:

- platform: mqtt
name: "shairport active start"
state_topic: "shairport/active_start"
payload_on: "--"
payload_off: "OFF"
off_delay: 300

- platform: mqtt
name: "shairport active end"
state_topic: "shairport/active_end"
payload_on: "--"
payload_off: "OFF"
off_delay: 300
mqtt:
- binary_sensor:
name: "shairport active start"
state_topic: "shairport/active_start"
payload_on: "--"
payload_off: "OFF"
off_delay: 300
- binary_sensor:
name: "shairport active end"
state_topic: "shairport/active_end"
payload_on: "--"
payload_off: "OFF"
off_delay: 300
```
Below parsed data is saved into the Home Assistant database as sensor data. Please note the conversion of the volume from dB to percentage.
In the below example, the parsed data is saved into the Home Assistant database as sensor data. Please note the conversion of the volume from dB to percentage.
```yml
mqtt:
Expand Down

0 comments on commit b5ea2b1

Please sign in to comment.