#include "include/communication.h" #include "esp_log.h" #include "mqtt_client.h" #include "stateManagement.h" #include "eventsManager.h" #if CONFIG_IDF_TARGET_ESP32P4 #include "esp_wifi.h" #endif #include "esp_log.h" static const char *TAG = "domo_mqtt"; /* FreeRTOS event group to signal when we are connected*/ static EventGroupHandle_t s_wifi_event_group; /* The event group allows multiple bits for each event, but we only care about two events: * - we are connected to the AP with an IP * - we failed to connect after the maximum amount of retries */ #define BIT0 0x00000001 #define WIFI_CONNECTED_BIT BIT0 #define WIFI_FAIL_BIT BIT1 #define EXAMPLE_ESP_WIFI_SSID "wifimms3" #define EXAMPLE_ESP_WIFI_PASS "mmswifi0611" #define EXAMPLE_ESP_MAXIMUM_RETRY 5 #define ESP_WIFI_SAE_MODE WPA3_SAE_PWE_BOTH #define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK static int s_retry_num = 0; wifi_callback cb; #if CONFIG_IDF_TARGET_ESP32P4 #define BIT0 0x00000001 static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { esp_wifi_connect(); } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { esp_wifi_connect(); s_retry_num++; ESP_LOGI(TAG, "retry to connect to the AP"); } else { //xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); } cb(WIFI_DISCONNECTED); ESP_LOGI(TAG, "connect to the AP fail"); } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); s_retry_num = 0; cb(WIFI_CONNECTED); //xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } } void wifi_init_sta(wifi_callback callback) { cb=callback; //s_wifi_event_group = xEventGroupCreate(); ESP_ERROR_CHECK(esp_netif_init()); //ESP_ERROR_CHECK(esp_event_loop_create_default()); esp_netif_create_default_wifi_sta(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); esp_event_handler_instance_t instance_any_id; esp_event_handler_instance_t instance_got_ip; ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, &instance_any_id)); ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, &instance_got_ip)); wifi_config_t wifi_config = { .sta = { .ssid = EXAMPLE_ESP_WIFI_SSID, .password = EXAMPLE_ESP_WIFI_PASS, /* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8). * If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value * to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to * WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards. */ .threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD, .sae_pwe_h2e = ESP_WIFI_SAE_MODE, .sae_h2e_identifier = "", }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, "wifi_init_sta finished."); /* // Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum // number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY); // xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually // happened. if (bits & WIFI_CONNECTED_BIT) { cb(CONNECTED); } else if (bits & WIFI_FAIL_BIT) { cb(CONNECT_FAIL); ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); } else { ESP_LOGE(TAG, "UNEXPECTED EVENT"); } */ } #else #include int64_t esp_timer_get_time(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (int64_t)ts.tv_sec * 1000000LL + ts.tv_nsec / 1000; } #endif esp_mqtt_client_handle_t client; static void log_error_if_nonzero(const char *message, int error_code) { if (error_code != 0) { ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code); } } void splitIt(char *payload, unsigned int length, float *datas) { char *sep = ","; char *token; char *saveptr1; token = strtok_r(payload, sep, &saveptr1); datas[0] = atof(token); ESP_LOGE(TAG,"%f",datas[0]); token = strtok_r(NULL, sep, &saveptr1); datas[1] = atof(token); ESP_LOGE(TAG,"%f",datas[1]); token = strtok_r(NULL, sep, &saveptr1); datas[2] = atof(token); ESP_LOGE(TAG,"%f",datas[2]); token = strtok_r(NULL, sep, &saveptr1); datas[3] = atof(token); ESP_LOGE(TAG,"%f",datas[3]); } mqtt_callback mqttcb; void mqtt_publish(const char *topic, const char *datas, bool retain){ esp_mqtt_client_publish(client, topic, datas, 0, 1, retain); } /* * @brief Event handler registered to receive MQTT events * * This function is called by the MQTT client event loop. * * @param handler_args user data registered to the event. * @param base Event base for the handler(always MQTT Base in this example). * @param event_id The id for the received event. * @param event_data The data for the event, esp_mqtt_event_handle_t. */ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) { ESP_LOGV(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id); esp_mqtt_event_handle_t event = event_data; esp_mqtt_client_handle_t client = event->client; int msg_id; switch ((esp_mqtt_event_id_t)event_id) { case MQTT_EVENT_CONNECTED: mqttcb(MQTT_CONNECTED,NULL); ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED"); //msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0); //ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id); msg_id = esp_mqtt_client_subscribe(client, topicTempExt, 0); ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); msg_id = esp_mqtt_client_subscribe(client, topicTempInt, 0); ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); msg_id = esp_mqtt_client_subscribe(client, topicHauteurCuve, 0); ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); msg_id = esp_mqtt_client_subscribe(client, topicHauteurCuveEvol, 0); ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); msg_id = esp_mqtt_client_subscribe(client, topicTest, 0); ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); msg_id = esp_mqtt_client_subscribe(client, topicdomoticCommand, 0); ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); msg_id = esp_mqtt_client_subscribe(client, topicdomoticCommand, 0); ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); msg_id = esp_mqtt_client_subscribe(client, topicEtatMachine, 0); ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); msg_id = esp_mqtt_client_subscribe(client, topicConsoElec, 0); ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); msg_id = esp_mqtt_client_subscribe(client, "devices/esp32p4_01/ota/update", 0); ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); //msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1); //ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); //msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1"); //ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id); break; case MQTT_EVENT_DISCONNECTED: mqttcb(MQTT_DISCONNECTED,NULL); ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED"); break; case MQTT_EVENT_SUBSCRIBED: ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id); //msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0); //ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id); break; case MQTT_EVENT_UNSUBSCRIBED: ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id); break; case MQTT_EVENT_PUBLISHED: ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id); break; case MQTT_EVENT_DATA: mqttcb(MQTT_DATA_RECEIVED, event); break; case MQTT_EVENT_ERROR: ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) { log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err); log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err); log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno); ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno)); } break; default: ESP_LOGI(TAG, "Other event id:%d", event->event_id); break; } } void mqtt_app_start(mqtt_callback callback, EventGroupHandle_t domotic_event_group) { mqttcb=callback; esp_mqtt_client_config_t mqtt_cfg = { .broker.address.uri = "mqtt://192.168.0.10", .network.timeout_ms = 1000, .session.keepalive=30, .session.last_will.topic="esp32p4_domotic/binary_sensor/online/state", .session.last_will.msg = "offline", .session.last_will.qos = 1, .session.last_will.retain = 1 }; #if CONFIG_BROKER_URL_FROM_STDIN char line[128]; if (strcmp(mqtt_cfg.broker.address.uri, "FROM_STDIN") == 0) { int count = 0; printf("Please enter url of mqtt broker\n"); while (count < 128) { int c = fgetc(stdin); if (c == '\n') { line[count] = '\0'; break; } else if (c > 0 && c < 127) { line[count] = c; ++count; } vTaskDelay(10 / portTICK_PERIOD_MS); } mqtt_cfg.broker.address.uri = line; printf("Broker url: %s\n", line); } else { ESP_LOGE(TAG, "Configuration mismatch: wrong broker url"); abort(); } #endif /* CONFIG_BROKER_URL_FROM_STDIN */ client = esp_mqtt_client_init(&mqtt_cfg); /* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */ esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL); // Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum // number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) EventBits_t bits = xEventGroupWaitBits(domotic_event_group, BIT0, pdFALSE, pdFALSE, portMAX_DELAY); if (bits & BIT0) { esp_mqtt_client_start(client); } }