From: jweigele Date: Mon, 4 Sep 2023 17:48:51 +0000 (-0700) Subject: testot connects with MQTT directly over an IP, and just sends uptime X-Git-Url: http://git.hexthepla.net/?a=commitdiff_plain;h=1371dd764d6c1a3c33a0d816513f2dddc5bc263f;p=esp32projects testot connects with MQTT directly over an IP, and just sends uptime --- diff --git a/testot/main/Kconfig b/testot/main/Kconfig new file mode 100644 index 0000000..4ab293c --- /dev/null +++ b/testot/main/Kconfig @@ -0,0 +1,12 @@ +menu "AQI Program Configuration" +config BROKER_URL + string "Set this to connect mqtt and report back data" + default "mqtts://esp32:sensorauth@rabbitmq.hexthepla.net" + help + Gets used downstream +config LOCATION + string "Set this to whatever you'd like reported as location" + default "ESP32 babyyy" + help + Gets used when sending off sensor data +endmenu diff --git a/testot/main/esp_ot_sleepy_device.c b/testot/main/esp_ot_sleepy_device.c index d0cd8ad..cd7126d 100644 --- a/testot/main/esp_ot_sleepy_device.c +++ b/testot/main/esp_ot_sleepy_device.c @@ -38,6 +38,197 @@ #define TAG "ot_esp_power_save" +static bool ot_connected = false; +static bool mqtt_connected = false; +static QueueHandle_t event_queue; + +// for tracking and reporting device uptime +static uint32_t device_uptime_seconds = 0; + + + +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); + } +} + +static void mqtt_reinit(esp_mqtt_client_handle_t client){ + ESP_LOGW(TAG, "trying to shutdown old mqtt client here"); + // get rid of previous handle + // the auto reconnect should handle everything else + ESP_ERROR_CHECK(esp_mqtt_client_stop(client)); +} + + +/* + * @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_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id); + esp_mqtt_event_handle_t event = event_data; + switch ((esp_mqtt_event_id_t)event_id) { + case MQTT_EVENT_CONNECTED: + mqtt_client = event->client; + mqtt_connected = true; + ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED"); + break; + case MQTT_EVENT_DISCONNECTED: + if ( event->client != mqtt_client ){ + ESP_LOGI(TAG, "disco old mqtt client, staying connected on this one"); + } else { + ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED"); + mqtt_connected = false; + } + break; + + case MQTT_EVENT_SUBSCRIBED: + ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->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: + ESP_LOGI(TAG, "MQTT_EVENT_DATA"); + printf("TOPIC=%.*s\r\n", event->topic_len, event->topic); + printf("DATA=%.*s\r\n", event->data_len, event->data); + break; + case MQTT_EVENT_ERROR: + if ( mqtt_client != NULL && event->client != mqtt_client ){ + ESP_LOGI(TAG, "old mqtt client, staying connected on this one and shutting down old"); + esp_mqtt_client_handle_t send_item = event->client; + xQueueSend(event_queue, &send_item, portMAX_DELAY); + } else { + mqtt_connected = false; + 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)); + + } + + //ESP_ERROR_CHECK(esp_mqtt_client_reconnect(mqtt_client)); + break; + default: + ESP_LOGI(TAG, "Other event id:%d", event->event_id); + break; + } +} + +static void send_report_wifi(){ + ESP_LOGI(TAG, "send_report_wifi was called!"); + cJSON *root; + root = cJSON_CreateObject(); + cJSON_AddStringToObject(root, "location", CONFIG_LOCATION); + cJSON_AddNumberToObject(root, "uptime", device_uptime_seconds); + + //const char *my_json_string = cJSON_Print(root); + char *mqtt_string = cJSON_Print(root); + ESP_LOGI(TAG, "sending mqtt_string:\n%s",mqtt_string); + if (mqtt_connected == true){ + int msg_id = esp_mqtt_client_publish(mqtt_client, "esp32/sensor_info", mqtt_string, 0, 1, 0); + ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id); + } else { + ESP_LOGW(TAG, "well, not quite yet (not connected)"); + } + free(mqtt_string); + cJSON_Delete(root); +} + + +void init_mqtt(){ + ESP_LOGI(TAG, "attempting to connect to MQTT"); + mqtt_client = NULL; + esp_mqtt_client_config_t mqtt_cfg = { + .broker = { + .address.uri = CONFIG_BROKER_URL, + .verification.certificate = NULL, + //.verification.use_global_ca_store = true, + //.verification.crt_bundle_attach = esp_crt_bundle_attach, + }, + .session.keepalive = 10, + //.cacert_buf = ca_cert, + //.cacert_bytes = strlen(ca_cert)+1, + }; + esp_mqtt_client_handle_t 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); + esp_mqtt_client_start(client); +} + +static void monitoring_task(void* discard) +{ + int64_t cur_uptime = 0; + int64_t next_sleep_uptime = 0; + int64_t remaining_time = 0; + esp_mqtt_client_handle_t queue_item; + for(;;){ + + // receive an event we need to deal with from elsewhere, right now just reconnect related + if (xQueueReceive(event_queue, &queue_item, 0 )){ + ESP_LOGW(TAG, "received a queue event in main monitoring loop! %p", queue_item); + mqtt_reinit(queue_item); + } + ESP_LOGI(TAG, "free heap: %"PRIu32, esp_get_free_heap_size()); + cur_uptime = esp_timer_get_time(); + // we'll use this to calc our sleeps later + next_sleep_uptime = cur_uptime + SLEEP_MS*1000; + // first things first (function gives microseconds, just convert to seconds) + // 32 bits is enough for >50 years and zigbee stack gets mad if we use more bits + device_uptime_seconds = (uint32_t)(cur_uptime/1000000); + // one BIG report for wifi + send_report_wifi(); + cur_uptime = esp_timer_get_time(); + remaining_time = next_sleep_uptime - cur_uptime; + ESP_LOGI(TAG, "next sleep uptime %lld cur_uptime %lld remaining time %lld", next_sleep_uptime, cur_uptime, remaining_time); + // sleep for 10 seconds before measuring again + ESP_LOGI(TAG, "sleeping for %lld ms", remaining_time/1000); + vTaskDelay( pdMS_TO_TICKS(remaining_time/1000) ); + } +} + + + +void handleNetifStateChanged(uint32_t aFlags, void *aContext) +{ + if ((aFlags & OT_CHANGED_THREAD_ROLE) != 0) + { + otDeviceRole changedRole = otThreadGetDeviceRole(aContext); + + switch (changedRole) + { + case OT_DEVICE_ROLE_LEADER: + case OT_DEVICE_ROLE_ROUTER: + case OT_DEVICE_ROLE_CHILD: + ot_connected = true; + ESP_LOGI(TAG, "is_connected = true"); + init_mqtt(); + break; + + case OT_DEVICE_ROLE_DETACHED: + case OT_DEVICE_ROLE_DISABLED: + ot_connected = false; + ESP_LOGI(TAG, "is_connected = false"); + break; + } + } +} + /** * Override default network settings, such as panid, so the devices can join a network @@ -103,6 +294,10 @@ static void create_config_network(otInstance *instance) ESP_LOGE(TAG, "Failed to set OpenThread linkmode."); abort(); } + + /* Register Thread state change handler */ + otSetStateChangedCallback(instance, handleNetifStateChanged, instance); + ESP_ERROR_CHECK(esp_openthread_auto_start(NULL)); /* Override default network credentials */ @@ -192,6 +387,9 @@ void app_main(void) ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_vfs_eventfd_register(&eventfd_config)); ESP_ERROR_CHECK(ot_power_save_init()); + event_queue = xQueueCreate(5, sizeof(esp_mqtt_client_handle_t)); + xTaskCreate(ot_task_worker, "ot_power_save_main", 4096, NULL, 5, NULL); + xTaskCreate(monitoring_task, "monitoring_task", 4096, NULL, 1, NULL); } diff --git a/testot/main/esp_ot_sleepy_device_config.h b/testot/main/esp_ot_sleepy_device_config.h index d5b9383..b1125de 100644 --- a/testot/main/esp_ot_sleepy_device_config.h +++ b/testot/main/esp_ot_sleepy_device_config.h @@ -12,6 +12,23 @@ * CONDITIONS OF ANY KIND, either express or implied. */ +#include "esp_timer.h" +#include +#include +#include +#include "mqtt_client.h" +#include "esp_crt_bundle.h" +#include "esp_netif_sntp.h" +#include "cJSON.h" +static esp_mqtt_client_handle_t mqtt_client; +void init_mqtt(); + +static void mqtt_reinit(); +// ten second loop +#define SLEEP_MS 10000 + + + #pragma once #include "esp_openthread_types.h" diff --git a/testot/sdkconfig b/testot/sdkconfig index fc61f17..2ccf5bf 100644 --- a/testot/sdkconfig +++ b/testot/sdkconfig @@ -624,7 +624,8 @@ CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set # CONFIG_ESP_TLS_SERVER is not set # CONFIG_ESP_TLS_PSK_VERIFICATION is not set -# CONFIG_ESP_TLS_INSECURE is not set +CONFIG_ESP_TLS_INSECURE=y +CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY=y # end of ESP-TLS # @@ -1701,6 +1702,13 @@ CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set # end of Wi-Fi Provisioning Manager + +# +# AQI Program Configuration +# +CONFIG_BROKER_URL="mqtts://esp32:sensorauth@10.246.1.110" +CONFIG_LOCATION="OT Test" +# end of AQI Program Configuration # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set