#include #include #include #include #include #include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_http_server.h" #include "esp_netif.h" #include "esp_eth.h" #include "esp_http_client.h" #include "esp_tls.h" #include "protocol_examples_common.h" #include "bme280.h" #include "dht22.h" #define MAX_HTTP_RECV_BUFFER 512 static const char *TAG = "micro_climate"; static esp_err_t bme280_readout_handler(httpd_req_t *req); static httpd_handle_t start_webserver(void); static void stop_webserver(httpd_handle_t server); static void disconnect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); static void connect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); static const httpd_uri_t bme280_uri = { .uri = "/bme280", .method = HTTP_GET, .handler = bme280_readout_handler }; esp_err_t _http_event_handler(esp_http_client_event_t *evt); static void post_data_http(int status, char *s, float t, float h, float p); void setup_i2c(void); int8_t init_bme280(void); int8_t bme280_readout(); int8_t lastReadoutStatus = 1; extern struct bme280_dev bme280; // from bme280_sup.c void DHT_task(void *pvParameter); void app_main(void) { // initialization ESP_ERROR_CHECK(nvs_flash_init()); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); // connect to wifi static httpd_handle_t server = NULL; ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server)); ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server)); ESP_ERROR_CHECK(example_connect()); // setup the sensors setup_i2c(); int8_t ret = init_bme280(); printf("BME init result %d\n", ret); /* while(1) { */ /* lastReadoutStatus = bme280_readout(); */ /* vTaskDelay(1600/portTICK_PERIOD_MS); */ /* } */ vTaskDelay( 1000 / portTICK_RATE_MS ); xTaskCreate( &DHT_task, "DHT_task", 2048, NULL, 5, NULL ); } struct bme280_data comp_data; int8_t bme280_readout(){ int8_t ret; char msgbuf[128]; ret = bme280_set_sensor_mode(BME280_NORMAL_MODE, &bme280); bme280.delay_ms(40); ret = bme280_get_sensor_data(BME280_ALL, &comp_data, &bme280); if (ret != BME280_OK) ESP_LOGI(TAG, "bme280_get_sensor_data() returned %d", ret); snprintf(msgbuf, sizeof(msgbuf), "%.1f C, %0.1f hPa, %0.1f%%", comp_data.temperature, comp_data.pressure / 100., comp_data.humidity); ESP_LOGI(TAG, "%s", msgbuf); return ret; } void DHT_task(void *pvParameter) { setDHTgpio( 32 ); printf( "Starting DHT Task\n\n"); while(1) { printf("=== Reading DHT ===\n" ); int ret = readDHT(); errorHandler(ret); printf( "Hum %.1f\n", getHumidity() ); printf( "Tmp %.1f\n", getTemperature() ); post_data_http(ret, "bedroom-am2302-01", getHumidity(), getTemperature(), -1); // -- wait at least 2 sec before reading again ------------ // The interval of whole process must be beyond 2 seconds !! vTaskDelay( 4000 / portTICK_RATE_MS ); } } static esp_err_t bme280_readout_handler(httpd_req_t *req) { char buffer[128]; httpd_resp_set_type(req, "text/json"); int8_t ret = bme280_readout(); if (ret == 0) { snprintf(buffer, sizeof(buffer), "{\"status\": \"ok\", \"sensor\": \"bedroom-bme280-01\", \"temp\": %.2f, \"humidity\": %.2f, \"pressure\": %0.2f}", comp_data.temperature, comp_data.humidity, comp_data.pressure/100.); ESP_LOGI(TAG, "%s", buffer); httpd_resp_send(req, buffer, -1); } else { ESP_LOGE(TAG, "bme280_readout failed"); httpd_resp_send(req, "{\"status\": failed, \"error\": \"could not read from sensor\"}", -1); } return ESP_OK; } static void post_data_http(int status, char *s, float t, float h, float p) { esp_http_client_config_t config = { .url = "http://192.168.1.107:3000/am2302", .event_handler = _http_event_handler, }; esp_http_client_handle_t client = esp_http_client_init(&config); // POST char post_data[256]; if (status == 0) { snprintf(post_data, sizeof(post_data), "{\"status\": \"ok\", \"sensor\": \"%s\", \"temp\": %.2f, \"humidity\": %.2f, \"pressure\": %.2f}", s, t, h, p); } else { snprintf(post_data, sizeof(post_data), "{\"status\": failed, \"error\": \"could not read from sensor\", \"sensor\": \"%s\"}", s); } esp_http_client_set_method(client, HTTP_METHOD_POST); esp_http_client_set_header(client, "Content-Type", "application/json"); esp_http_client_set_post_field(client, post_data, strlen(post_data)); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %d", esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } static httpd_handle_t start_webserver(void) { httpd_handle_t server = NULL; // Start the httpd server ESP_LOGI(TAG, "Starting server"); httpd_config_t conf = HTTPD_DEFAULT_CONFIG(); esp_err_t ret = httpd_start(&server, &conf); if (ESP_OK != ret) { ESP_LOGI(TAG, "Error starting server!"); return NULL; } // Set URI handlers ESP_LOGI(TAG, "Registering URI handlers"); httpd_register_uri_handler(server, &bme280_uri); return server; } static void stop_webserver(httpd_handle_t server) { httpd_stop(server); } static void disconnect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { httpd_handle_t* server = (httpd_handle_t*) arg; if (*server) { stop_webserver(*server); *server = NULL; } } static void connect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { httpd_handle_t* server = (httpd_handle_t*) arg; if (*server == NULL) { *server = start_webserver(); } } esp_err_t _http_event_handler(esp_http_client_event_t *evt) { switch(evt->event_id) { case HTTP_EVENT_ERROR: ESP_LOGD(TAG, "HTTP_EVENT_ERROR"); break; case HTTP_EVENT_ON_CONNECTED: ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED"); break; case HTTP_EVENT_HEADER_SENT: ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT"); break; case HTTP_EVENT_ON_HEADER: ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value); break; case HTTP_EVENT_ON_DATA: ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len); if (!esp_http_client_is_chunked_response(evt->client)) { // Write out data // printf("%.*s", evt->data_len, (char*)evt->data); } break; case HTTP_EVENT_ON_FINISH: ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH"); break; case HTTP_EVENT_DISCONNECTED: ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED"); int mbedtls_err = 0; esp_err_t err = esp_tls_get_and_clear_last_error(evt->data, &mbedtls_err, NULL); if (err != 0) { ESP_LOGI(TAG, "Last esp error code: 0x%x", err); ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err); } break; } return ESP_OK; }