]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
MQTT auto discovery working
authoraaronk6 <aaronk6@users.noreply.github.com>
Sun, 17 Mar 2024 21:22:47 +0000 (21:22 +0000)
committeraaronk6 <aaronk6@users.noreply.github.com>
Tue, 24 Sep 2024 18:32:08 +0000 (20:32 +0200)
mqtt.c

diff --git a/mqtt.c b/mqtt.c
index 51e474d8891765a00c75f1d2bf387d1c4b965968..c85dfeb93b7863697f0bd2c3890da9c21db132fe 100644 (file)
--- a/mqtt.c
+++ b/mqtt.c
@@ -21,10 +21,6 @@ struct mosquitto *global_mosq = NULL;
 char *topic = NULL;
 int connected = 0;
 
-// track active/playing state
-int is_active = 0;
-int is_playing = 0;
-
 // mosquitto logging
 void _cb_log(__attribute__((unused)) struct mosquitto *mosq, __attribute__((unused)) void *userdata,
              int level, const char *str) {
@@ -101,17 +97,20 @@ void on_connect(struct mosquitto *mosq, __attribute__((unused)) void *userdata,
   }
 }
 
+// function to send autodiscovery messages for Home Assistant
 void send_autodiscovery_messages(struct mosquitto *mosq) {
     const char *device_name = config.service_name;
     const char *sw_version = get_version_string();
     const char *model = "shairport-sync";
+    const char *model_friendly = "Shairport Sync";
     const char *manufacturer = "Mike Brady";
     const char *autodiscovery_prefix = (config.mqtt_autodiscovery_prefix != NULL) ?
         config.mqtt_autodiscovery_prefix : "homeassistant";
 
     char topic[512];
-    char payload[1024];
+    char payload[1280];
     char device_payload[512];
+    char id_string[128];
 
     snprintf(device_payload, sizeof(device_payload),
         "\"device\": {"
@@ -121,7 +120,7 @@ void send_autodiscovery_messages(struct mosquitto *mosq) {
             "\"sw_version\": \"%s\","
             "\"manufacturer\": \"%s\""
         "}",
-        model, device_name, model, sw_version, manufacturer);
+        model, device_name, model_friendly, sw_version, manufacturer);
 
     // when adding sensors here, be sure to also update sensor_names and icons below!
     const char *sensors[] = {
@@ -130,12 +129,18 @@ void send_autodiscovery_messages(struct mosquitto *mosq) {
         "title",
         "genre",
         "format",
+        "output_format",
+        "output_frame_rate",
         "track_id",
         "client_ip",
+        "client_mac_address",
         "client_name",
+        "client_model",
+        "client_device_id",
+        "server_ip",
         "volume",
-        "is_active",
-        "is_playing",
+        "active",
+        "playing",
         NULL
     };
 
@@ -145,12 +150,18 @@ void send_autodiscovery_messages(struct mosquitto *mosq) {
         "Title",
         "Genre",
         "Format",
+        "Output Format",
+        "Output Frame Rate",
         "Track ID", 
         "Client IP",
+        "Client MAC Address",
         "Client Name",
+        "Client Model",
+        "Client Device ID",
+        "Server IP",
         "Volume",
-        "Is Active",
-        "Is Playing"
+        "Active Session",
+        "Playing"
     };
 
     const char *icons[] = {
@@ -159,35 +170,48 @@ void send_autodiscovery_messages(struct mosquitto *mosq) {
         "mdi:music", // title
         "mdi:music-box-multiple", // genre
         "mdi:file", // format
+        "mdi:file", // output format
+        "mdi:file-chart", // output frame rate
         "mdi:identifier", // track ID
         "mdi:ip", // client IP
-        "mdi:cellphone-wireless", // client name
+        "mdi:hexadecimal", // client MAC address
+        "mdi:cellphone-text", // client name
+        "mdi:cellphone-text", // client model
+        "mdi:hexadecimal", // client device ID
+        "mdi:ip-network", // server IP
         "mdi:volume-high", // volume
-        "mdi:play-box-multiple", // is active
-        "mdi:play-box-multiple-outline" // is playing
+        "mdi:play-box-multiple", // active
+        "mdi:play-box-multiple-outline" // playing
     };
 
     for (int i = 0; sensors[i] != NULL; i++) {
-        bool is_binary_sensor = (strcmp(sensors[i], "is_active") == 0 || strcmp(sensors[i], "is_playing") == 0);
+        bool is_binary_sensor = (strcmp(sensors[i], "active") == 0 || strcmp(sensors[i], "playing") == 0);
+        bool is_volume_sensor = strcmp(sensors[i], "volume") == 0;
 
-        snprintf(topic, sizeof(topic), "%s/%ssensor/%s/%s_%s%s/config",
+        snprintf(topic, sizeof(topic), "%s/%ssensor/%s/%s_%s/config",
             autodiscovery_prefix, is_binary_sensor ? "binary_" : "",
-            model, model, device_name, sensors[i]);
+            model, device_name, sensors[i]);
+
+        snprintf(id_string, sizeof(id_string), "%s_%s_%s", model, device_name, sensors[i]);
 
         snprintf(payload, sizeof(payload),
             "{"
                 "\"name\": \"%s\","
                 "\"state_topic\": \"%s/%s\","
                 "\"icon\": \"%s\","
-                "\"unique_id\": \"%s_%s\","
-                "%s%s"
+                "\"unique_id\": \"%s\","
+                "\"object_id\": \"%s\","
+                "%s%s%s"
             "}",
-            sensor_names[i], config.mqtt_topic, sensors[i], icons[i], device_name, sensors[i],
+            sensor_names[i], config.mqtt_topic, sensors[i], icons[i], id_string, id_string,
             is_binary_sensor ? "\"payload_on\": \"1\",\"payload_off\": \"0\"," : "",
+            is_volume_sensor ? "\"value_template\": \"{{ ((value | regex_findall_index("
+                "find='^(.+?),', index=0, ignorecase=False) | float / 30 + 1) * 100) | round(0) }}\","
+                "\"unit_of_measurement\": \"%\"," : "",
             device_payload);
 
         mosquitto_publish(mosq, NULL, topic, strlen(payload), payload, 0, true);
-        debug(2, "[MQTT]: Published autodiscovery for %s", device_name)
+        debug(2, "[MQTT]: published autodiscovery for %s", id_string);
     }
 }
 
@@ -266,16 +290,14 @@ void mqtt_process_metadata(uint32_t type, uint32_t code, char *data, uint32_t le
     } else if (type == 'ssnc') {
       switch (code) {
       case 'abeg':
-        is_active = 1;
-        mqtt_publish("is_active", "1", 1);
+        mqtt_publish("active", "1", 1);
         mqtt_publish("active_start", data, length);
         break;
       case 'acre':
         mqtt_publish("active_remote_id", data, length);
         break;
       case 'aend':
-        is_active = 0;
-        mqtt_publish("is_active", "0", 1);
+        mqtt_publish("active", "0", 1);
         mqtt_publish("active_end", data, length);
         break;
       case 'asal':
@@ -313,13 +335,11 @@ void mqtt_process_metadata(uint32_t type, uint32_t code, char *data, uint32_t le
         mqtt_publish("output_frame_rate", data, length);
         break;
       case 'pbeg':
-        is_playing = 1;
-        mqtt_publish("is_playing", "1", 1);
+        mqtt_publish("playing", "1", 1);
         mqtt_publish("play_start", data, length);
         break;
       case 'pend':
-        is_playing = 0;
-        mqtt_publish("is_playing", "0", 1);
+        mqtt_publish("playing", "0", 1);
         mqtt_publish("play_end", data, length);
         break;
       case 'pfls':
@@ -331,8 +351,7 @@ void mqtt_process_metadata(uint32_t type, uint32_t code, char *data, uint32_t le
         }
         break;
       case 'prsm':
-        is_playing = 1;
-        mqtt_publish("is_playing", "1", 1);
+        mqtt_publish("playing", "1", 1);
         mqtt_publish("play_resume", data, length);
         break;
       case 'pvol':