// Note: Run menuconfig to set the WiFi Credentials -> CALE Configuration // Requirements: Needs to have an EPD Class defined. Needs PSRAM. // This example does not use a decoded buffer hence leaves more external RAM free // At the same time it looses the JPG_DITHER functionality in favour of render speed. // As default only configured for parallel epapers #include "esp_heap_caps.h" #include "esp_log.h" #include "esp_types.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_sleep.h" // WiFi related #include "esp_event.h" #include "esp_log.h" #include "esp_timer.h" #include "lwip/err.h" #include "lwip/sys.h" // HTTP Client + time #include "esp_http_client.h" #include "esp_sntp.h" #include #include #include #define EXAMPLE_MAX_CHAR_SIZE 64 #include "esp_task_wdt.h" #include #include #include // round + pow #include "image_downloader.h" #define MOUNT_POINT "/sdcard" static const char *TAG = "ImgDwn"; // Image URL and jpg settings. Make sure to update EPD_WIDTH/HEIGHT if using loremflickr // Note: Only HTTP protocol supported (Check README to use SSL secure URLs) loremflickr #define STR_HELPER(x) #x #define STR(x) STR_HELPER(x) #define IMGDWN_WIDTH_STR "800" #define IMGDWN_WIDTH 620 #define IMGDWN_HEIGHT_STR "600" #define IMGDWN_HEIGHT 460 #define IMGDWN_URL2 ("http://vps-edf71efa.vps.ovh.net:3000/render/d-solo/7BtRMrv4k/temperatures?orgId=1&var-emplacement=entree_ECS&var-emplacement=entree_reseauSol&panelId=4&width=650&height=460&scale=1&tz=Europe%2FParis/") #define IMGDWN_URL ("http://vps-edf71efa.vps.ovh.net:3000/render/d-solo/bOcPeysGz/hauteur-cuve?orgId=1&from=now-2d&refresh=1m&panelId=4&width=" IMGDWN_WIDTH_STR "&height=" IMGDWN_HEIGHT_STR "&scale=1&tz=Europe%2FParis") // 650 460 // As default is 512 without setting buffer_size property in esp_http_client_config_t #define HTTP_RECEIVE_BUFFER_SIZE 1938 #define DEBUG_VERBOSE false // Buffers uint8_t *fb; // EPD 2bpp buffer uint8_t *source_buf; // JPG download buffer uint8_t *decoded_image; // RAW decoded image uint32_t buffer_pos = 0; uint32_t time_download = 0; uint32_t time_decomp = 0; uint32_t time_render = 0; uint16_t countDataEventCalls = 0; uint32_t countDataBytes = 0; uint32_t img_buf_pos = 0; uint32_t dataLenTotal = 0; uint64_t startTime = 0; void create_file_app(uint8_t *buffer, uint32_t size) { ESP_LOGI(TAG, "Opening file"); //ESP_LOGI(TAG, "output buffer to spiffs: %s \n", buffer); FILE* f = fopen(MOUNT_POINT"/hello2.png", "wb+"); if (f == NULL) { ESP_LOGE(TAG, "Failed to open file for writing"); return; } for(int i=0; ievent_id) { case HTTP_EVENT_ERROR: ESP_LOGE(TAG, "HTTP_EVENT_ERROR"); break; case HTTP_EVENT_ON_CONNECTED: ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED"); break; case HTTP_EVENT_HEADER_SENT: ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT"); break; case HTTP_EVENT_ON_HEADER: #if DEBUG_VERBOSE ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value); #endif break; case HTTP_EVENT_ON_DATA: ++countDataEventCalls; #if DEBUG_VERBOSE if (countDataEventCalls%10==0) { ESP_LOGI(TAG, "%d len:%d\n", countDataEventCalls, evt->data_len); } #endif dataLenTotal += evt->data_len; if (countDataEventCalls == 1) startTime = esp_timer_get_time(); // Append received data into source_buf memcpy(&source_buf[img_buf_pos], evt->data, evt->data_len); img_buf_pos += evt->data_len; // Optional hexa dump //ESP_LOG_BUFFER_HEX(TAG, source_buf, 100); break; case HTTP_EVENT_REDIRECT: break; case HTTP_EVENT_ON_FINISH: // Do not draw if it's a redirect (302) if (esp_http_client_get_status_code(evt->client) == 200) { printf("%li bytes read from %s\nIMG_BUF size: %li\n", img_buf_pos, IMGDWN_URL, img_buf_pos); //drawBufJpeg(source_buf, 0, 0); create_file_app(source_buf,img_buf_pos); //function which opens and records data to spiffs file time_download = (esp_timer_get_time()-startTime)/1000; ESP_LOGI("www-dw", "%li ms - download", time_download); // Refresh display //display.update(); ESP_LOGI("total", "%li ms - total time spent\n", time_download+time_decomp+time_render); } else { printf("HTTP on finish got status code: %d\n", esp_http_client_get_status_code(evt->client)); } break; case HTTP_EVENT_DISCONNECTED: ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED\n"); break; } return ESP_OK; } // Handles http request static void download(void) { esp_http_client_config_t config = { .url = IMGDWN_URL, .disable_auto_redirect = false, .event_handler = _http_event_handler_id, .buffer_size = HTTP_RECEIVE_BUFFER_SIZE, .timeout_ms = 50000 }; esp_http_client_handle_t client = esp_http_client_init(&config); #if DEBUG_VERBOSE printf("Free heap before HTTP download: %d\n", xPortGetFreeHeapSize()); #endif esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "\nIMAGE URL: %s\n\nHTTP GET Status = %d, content_length = %lli\n", IMGDWN_URL, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "\nHTTP GET request failed: %s", esp_err_to_name(err)); } //printf("Go to sleep %d minutes\n", CONFIG_DEEPSLEEP_MINUTES_AFTER_RENDER); esp_http_client_cleanup(client); vTaskDelay(3600000 / portTICK_PERIOD_MS); //deepsleep(); } void imgdwn(void *pvParameter) { ESP_LOGE(TAG, "beginning"); // Should be big enough to allocate the JPEG file size, width * height should suffice source_buf = (uint8_t *)heap_caps_malloc(IMGDWN_HEIGHT * IMGDWN_WIDTH, MALLOC_CAP_SPIRAM); if (source_buf == NULL) { ESP_LOGE(TAG, "Initial alloc source_buf failed!"); } printf("Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize()); download(); heap_caps_free(source_buf); printf("Free heap after buffers allocation: %d\n", xPortGetFreeHeapSize()); }