From 3651dd9ef97d5661e837b573771cc62fa40fa07a Mon Sep 17 00:00:00 2001 From: dvdrw Date: Sun, 17 May 2026 14:36:45 +0200 Subject: [PATCH] feat: publish/respond version string --- components/mqtt_publisher/include/mqtt_publisher.h | 4 +++- components/mqtt_publisher/src/mqtt_publisher.c | 12 +++++++++--- main/main.c | 7 +++++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/components/mqtt_publisher/include/mqtt_publisher.h b/components/mqtt_publisher/include/mqtt_publisher.h index ae1686c..654004d 100644 --- a/components/mqtt_publisher/include/mqtt_publisher.h +++ b/components/mqtt_publisher/include/mqtt_publisher.h @@ -46,10 +46,12 @@ void mqtt_publisher_send_ota_status(const char *status, const char *version); * sensor_id — stable anchor ID string (e.g. "anchor_a1b2c3") * broker_uri — e.g. "mqtt://192.168.1.100:1883" * evt_group — FreeRTOS event group; publisher sets bits above on events + * version — firmware version string included in announce payload and version query responses */ esp_err_t mqtt_publisher_init(const char *sensor_id, const char *broker_uri, - EventGroupHandle_t evt_group); + EventGroupHandle_t evt_group, + const char *version); /** Publish an RSSI reading. Non-blocking (QoS 1). */ void mqtt_publisher_send_rssi(const char *tag_id, int8_t rssi); diff --git a/components/mqtt_publisher/src/mqtt_publisher.c b/components/mqtt_publisher/src/mqtt_publisher.c index 9f068fd..5c0e315 100644 --- a/components/mqtt_publisher/src/mqtt_publisher.c +++ b/components/mqtt_publisher/src/mqtt_publisher.c @@ -11,6 +11,7 @@ static esp_mqtt_client_handle_t s_client = NULL; static char s_sensor_id[32]; +static char s_firmware_version[32]; static EventGroupHandle_t s_evt = NULL; static mqtt_reconfigure_data_t s_reconfigure_data; static mqtt_ota_data_t s_ota_data; @@ -60,6 +61,7 @@ static void handle_cmd(const char *data, int data_len) else if (strcmp(a, "selected") == 0) xEventGroupSetBits(s_evt, MQTT_SELECTED_BIT); else if (strcmp(a, "deselected") == 0) xEventGroupSetBits(s_evt, MQTT_DESELECTED_BIT); else if (strcmp(a, "factory_reset") == 0) xEventGroupSetBits(s_evt, MQTT_FACTORY_RESET_BIT); + else if (strcmp(a, "version") == 0) mqtt_publisher_announce(); else if (strcmp(a, "ota") == 0) { memset(&s_ota_data, 0, sizeof(s_ota_data)); cJSON *url_j = cJSON_GetObjectItemCaseSensitive(root, "url"); @@ -122,9 +124,11 @@ static void mqtt_event_handler(void *arg, esp_event_base_t base, esp_err_t mqtt_publisher_init(const char *sensor_id, const char *broker_uri, - EventGroupHandle_t evt_group) + EventGroupHandle_t evt_group, + const char *version) { strncpy(s_sensor_id, sensor_id, sizeof(s_sensor_id) - 1); + strncpy(s_firmware_version, version ? version : "", sizeof(s_firmware_version) - 1); s_evt = evt_group; build_topics(); @@ -147,8 +151,10 @@ esp_err_t mqtt_publisher_init(const char *sensor_id, void mqtt_publisher_announce(void) { if (!s_client) return; - esp_mqtt_client_publish(s_client, s_topic_announce, "", 0, 1, 0); - ESP_LOGI(TAG, "Announced on %s", s_topic_announce); + char payload[48]; + int len = snprintf(payload, sizeof(payload), "{\"version\":\"%s\"}", s_firmware_version); + esp_mqtt_client_publish(s_client, s_topic_announce, payload, len, 1, 0); + ESP_LOGI(TAG, "Announced on %s (version: %s)", s_topic_announce, s_firmware_version); } void mqtt_publisher_send_rssi(const char *tag_id, int8_t rssi) diff --git a/main/main.c b/main/main.c index fb04af2..d54bb1e 100644 --- a/main/main.c +++ b/main/main.c @@ -221,12 +221,15 @@ void app_main(void) snprintf(broker_uri, sizeof(broker_uri), "mqtt://%s:%u", broker_host, broker_port); // init MQTT - ESP_ERROR_CHECK(mqtt_publisher_init(sensor_id, broker_uri, s_evt)); + const esp_partition_t *running = esp_ota_get_running_partition(); + esp_app_desc_t app_desc; + const char *fw_version = (esp_ota_get_partition_description(running, &app_desc) == ESP_OK) + ? app_desc.version : "unknown"; + ESP_ERROR_CHECK(mqtt_publisher_init(sensor_id, broker_uri, s_evt, fw_version)); xEventGroupWaitBits(s_evt, MQTT_CONNECTED_BIT, pdFALSE, pdTRUE, portMAX_DELAY); /* Confirm this firmware is healthy so the bootloader won't roll back */ esp_ota_img_states_t ota_state; - const esp_partition_t *running = esp_ota_get_running_partition(); if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK && ota_state == ESP_OTA_IMG_PENDING_VERIFY) { esp_ota_mark_app_valid_cancel_rollback();