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) {
}
}
+// 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\": {"
"\"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[] = {
"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
};
"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[] = {
"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);
}
}
} 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':
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':
}
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':