mikebrady / shairport-sync

AirPlay and AirPlay 2 audio player
Other
7.2k stars 571 forks source link

documentation of MQTT interface? #1113

Closed brianlay714 closed 3 years ago

brianlay714 commented 3 years ago

Searched but didn't find anything. Would like to interface to OpenHAB home automation

mikebrady commented 3 years ago

Hmm, I'm afraid there isn't any, really. But the relevant code file is pretty compact -- mqtt.c/h.

brianlay714 commented 3 years ago

ok thanks between that and the config file I will try to get something going

On Thu, Dec 10, 2020 at 11:25 AM Mike Brady notifications@github.com wrote:

Hmm, I'm afraid there isn't any, really. But the relevant code file is pretty compact -- mqtt.c/h.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mikebrady/shairport-sync/issues/1113#issuecomment-742627859, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC2TTSQUIYW3MND5RJU6R6DSUDY6TANCNFSM4UUJ6KLQ .

minix1234 commented 3 years ago

i could try writing up a bit. I've been using the mqtt interface with home assistant to help control my wifi receiver when someone starts an airplay stream.

mqtt seems to work well but is a bit chatty. I believe that's related to iOS though

mikebrady commented 3 years ago

@minix1234, that would be great!

brianlay714 commented 3 years ago

any help would be appreciated. My first attempt was a fail My use case is sending metadata so it can be displayed on an OpenHAB automation system. I have 3 instances of Shairport feeding inputs on a whole-home audio router. Trying to get 'now playing' metadata published to a broker. Eventually the data will be displayed in a player widget.

I compiled a shairport using --with-metadata and with-mqtt options but it doesn't show up in the version.

pi@aspen:~ $ shairport-sync --version
3.3.8rc1-OpenSSL-Avahi-ALSA-soxr-metadata-sysconfdir:/etc

my current config is

// For this section to be operative, Shairport Sync must be built with the following configuration flag:
// --with-mqtt-client
mqtt =
{
enabled = "yes"; // set this to yes to enable the mqtt-metadata-service
hostname = "192.168.1.150"; // Hostname of the MQTT Broker
port = 1883; // Port on the MQTT Broker to connect to
//      username = NULL; //set this to a string to your username in order to enable username authentication
//      password = NULL; //set this to a string you your password in order to enable username & password auth$
//      capath = NULL; //set this to the folder with the CA-Certificates to be accepted for the server certif$
//      cafile = NULL; //this may be used as an (exclusive) alternative to capath with a single file for all $
//      certfile = NULL; //set this to a string to a user certificate to enable MQTT Client certificates. key$
//      keyfile = NULL; //private key for MQTT Client authentication
//      topic = NULL; //MQTT topic where this instance of shairport-sync should publish. If not set, the gene$
//      publish_raw = "no"; //whether to publish all available metadata under the codes given in the 'metadat$
//      publish_parsed = "no"; //whether to publish a small (but useful) subset of metadata under human-under$
//      Currently published topics:artist,album,title,genre,format,songalbum,volume,client_ip,
//      Additionally, empty messages at the topics play_start,play_end,play_flush,play_resume are published
//      publish_cover = "no"; //whether to publish the cover over mqtt in binary form. This may lead to a bit$
//      enable_remote = "no"; //whether to remote control via MQTT. RC is available under `topic`/remote.
//      Available commands are "command", "beginff", "beginrew", "mutetoggle", "nextitem", "previtem", "pause$
};

As soon as I add a topic to the config, shairport fails to start

Any ideas?

mikebrady commented 3 years ago

Thanks. I edited your post slightly for formatting.

It does seem as MQTT support has not been included in Shairport-Sync, and this issue needs to be solved. To do that, let me suggest that you build Shairport Sync again. The guide on the INSTALL.md page is probably the best, but instead of the configuration command:

$ ./configure --sysconfdir=/etc --with-alsa --with-soxr --with-avahi --with-ssl=openssl --with-systemd

use this instead:

$ ./configure --sysconfdir=/etc --with-alsa --with-soxr --with-avahi --with-ssl=openssl  --with-mqtt-client --with-systemd

In the long output from the ./configure... step, you should see:

...
...
>>Including MQTT support
checking for mosquitto_lib_init in -lmosquitto... yes

It is not necessary to add --with-metadata as that is added automatically when MQTT support is requested.

brianlay714 commented 3 years ago

thanks, i'll give that a try.

I need to figure out how to use fences...

minix1234 commented 3 years ago

Once you build with MQTT support you will also need to enable the metadata section.

here are the relevant sections from my current setup where shairport-sync is simply publishing to my MQTT server. I have yet to experiment or play with the "remote" control part.

// How to deal with metadata, including artwork
// For this section to be operative, Shairport Sync must be built with at one (or more) of the following configuration flags:
// --with-metadata, --with-dbus-interface, --with-mpris-interface or --with-mqtt-client.
// In those cases, "enabled" and "include_cover_art" will both be "yes" by default
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
    pipe_name = "/tmp/shairport-sync-metadata";
    pipe_timeout = 5000; // wait for this number of milliseconds for a blocked pipe to unblock before giving up
//  socket_address = "226.0.0.1"; // if set to a host name or IP address, UDP packets containing metadata will be sent to this address. May be a multicast address. "socket-port" must be non-zero and "enabled" must be set to yes"
//  socket_port = 5555; // if socket_address is set, the port to send UDP packets to
//  socket_msglength = 65000; // the maximum packet size for any UDP metadata. This will be clipped to be between 500 or 65000. The default is 500.
};

// How to enable the MQTT-metadata/remote-service
// For this section to be operative, Shairport Sync must be built with the following configuration flag:
// --with-mqtt-client
mqtt =
{
    enabled = "yes"; // set this to yes to enable the mqtt-metadata-service
    hostname = "###.###.###.###"; // Hostname of the MQTT Broker
    port = ###; // Port on the MQTT Broker to connect to
    username = "---"; //set this to a string to your username in order to enable username authentication
    password = "---"; //set this to a string you your password in order to enable username & password authentication
//  capath = NULL; //set this to the folder with the CA-Certificates to be accepted for the server certificate. If not set, TLS is not used
//  cafile = NULL; //this may be used as an (exclusive) alternative to capath with a single file for all ca-certificates
//  certfile = NULL; //set this to a string to a user certificate to enable MQTT Client certificates. keyfile must also be set!
//  keyfile = NULL; //private key for MQTT Client 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
//  Currently published topics:artist,album,title,genre,format,songalbum,volume,client_ip,
//  Additionally, empty messages at the topics play_start,play_end,play_flush,play_resume are published
    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.
//  Available commands are "command", "beginff", "beginrew", "mutetoggle", "nextitem", "previtem", "pause", "playpause", "play", "stop", "playresume", "shuffle_songs", "volumedown", "volumeup"
};
``'
minix1234 commented 3 years ago

as a bit more background. Given that I set:

    topic = "shairport"; //MQTT topic where this instance of shairport-sync should publish. If not set, the general.name value is used.
    publish_parsed = "yes"; //whether to publish a small (but useful) subset of metadata under human-understandable topics

in my config all parsed messages are published to the tune of "shairport/artist", "shairport/volume", etc

the subset of parsed (aka. human readable) data is specified in the conf, see below.

//  Currently published topics:artist,album,title,genre,format,songalbum,volume,client_ip,
//  Additionally, empty messages at the topics play_start,play_end,play_flush,play_resume are published

and the volume is published in dB values, so you need to convert it. This is what it looks like when its published,

image

and here is what I do in home assistant. My volum2 utilizes a regex to find capture groups between comma's. I then pick off the first one (index=0). This is the airplay volume given from 0 down to -30. I convert to a positive percentage as (value/30 +1). This works well enough, but i do not have logic in place to deal with mute which is sent as -144.

  - platform: mqtt
    name: "shairport volume"
    state_topic: "shairport/volume"

  - platform: mqtt
    name: "shairport volume2"
    state_topic: "shairport/volume"
    value_template: "{{ value |  regex_findall_index(find='^(.+?),', index=0, ignorecase=False) | float / 30 + 1  }}"
    unit_of_measurement: 'percent'

image

brianlay714 commented 3 years ago

I finally got it working...thanks to both of you for the pointers. I really don't have a need for client Ip and play flush but I can just ignore them for now I see 3 values for volume, not sure what they represent... image

minix1234 commented 3 years ago

volume -- play 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.

The airplay_volume is what's sent by the source (e.g. iTunes) to the player, and is from 0.00 down to -30.00, with -144.00 meaning "mute".

This is linear on the volume control slider of iTunes or iOS AirPlay.

If the volume setting is being ignored by Shairport Sync itself (ignore_volume_control = "yes"), the volume, lowest_volume and highest_volume values are zero.

In home assistant you can use regex to find the group of interest and select that, (see above notes)

I don't have much experience with openhab, but would be interested to know what you end up doing. I am working on a pull request to add MQTT documentation and think having some common configurations for automation projects would be helpful.

minix1234 commented 3 years ago

Mike,

I did a brief writeup on configuration and usage of MQTT for shairport. see #1117. I currently do not have a section for building shairport with MQTT support or background on the utilized libraries. I figured the most useful info is the basic configurations and metadata properties.

github-actions[bot] commented 3 years ago

This issue has been inactive for 60 days so will be closed 7 days from now. To prevent this, please remove the "stale" label or post a comment.