From e252ee7fb5ac54dc52a21e87441e78b3eedd7fed Mon Sep 17 00:00:00 2001 From: aaronk6 Date: Sun, 17 Mar 2024 21:22:47 +0000 Subject: [PATCH] MQTT auto discovery working --- mqtt.c | 79 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/mqtt.c b/mqtt.c index 51e474d8..c85dfeb9 100644 --- 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': -- 2.47.2