5static const char *
const TAG =
"online_image";
6static const char *
const ETAG_HEADER_NAME =
"etag";
7static const char *
const IF_NONE_MATCH_HEADER_NAME =
"if-none-match";
8static const char *
const LAST_MODIFIED_HEADER_NAME =
"last-modified";
9static const char *
const IF_MODIFIED_SINCE_HEADER_NAME =
"if-modified-since";
15 uint32_t buffer_size,
bool is_big_endian)
16 : RuntimeImage(format,
type, transparency, placeholder, is_big_endian, width, height),
17 download_buffer_(buffer_size),
18 download_buffer_initial_size_(buffer_size) {
24 ESP_LOGE(TAG,
"URL is empty");
27 if (url.length() > 2048) {
28 ESP_LOGE(TAG,
"URL is too long");
31 if (url.compare(0, 7,
"http://") != 0 && url.compare(0, 8,
"https://") != 0) {
32 ESP_LOGE(TAG,
"URL must start with http:// or https://");
40 ESP_LOGW(TAG,
"Image already being updated.");
45 ESP_LOGE(TAG,
"Invalid URL: %s", this->
url_.c_str());
50 ESP_LOGD(TAG,
"Updating image from %s", this->
url_.c_str());
52 std::vector<http_request::Header> headers;
55 if (!this->
etag_.empty()) {
56 headers.push_back({IF_NONE_MATCH_HEADER_NAME, this->
etag_});
59 headers.push_back({IF_MODIFIED_SINCE_HEADER_NAME, this->
last_modified_});
63 const char *accept_mime_type;
65#ifdef USE_RUNTIME_IMAGE_BMP
67 accept_mime_type =
"image/bmp,*/*;q=0.8";
70#ifdef USE_RUNTIME_IMAGE_JPEG
72 accept_mime_type =
"image/jpeg,*/*;q=0.8";
75#ifdef USE_RUNTIME_IMAGE_PNG
77 accept_mime_type =
"image/png,*/*;q=0.8";
81 accept_mime_type =
"image/*,*/*;q=0.8";
84 headers.push_back({
"Accept", accept_mime_type});
94 ESP_LOGE(TAG,
"Download failed.");
101 if (http_code == HTTP_CODE_NOT_MODIFIED) {
103 ESP_LOGI(TAG,
"Server returned HTTP 304 (Not Modified). Download skipped.");
108 if (http_code != HTTP_CODE_OK) {
109 ESP_LOGE(TAG,
"HTTP result: %d", http_code);
115 ESP_LOGD(TAG,
"Starting download");
116 size_t total_size = this->
downloader_->content_length;
120 ESP_LOGE(TAG,
"Failed to initialize decoder for format %d", this->
get_format());
131 ESP_LOGI(TAG,
"Downloading image (Size: %zu)", total_size);
144 ESP_LOGE(TAG,
"Downloader not instantiated; cannot download");
153 this->downloader_->get_bytes_read() >= this->downloader_->content_length &&
154 this->download_buffer_.unread() == 0)) {
158 ESP_LOGD(TAG,
"Image fully downloaded, %zu bytes in %" PRIu32
"s", this->
downloader_->get_bytes_read(),
159 (uint32_t) (::time(
nullptr) - this->start_time_));
184 ESP_LOGE(TAG,
"Error decoding image: %d", consumed);
193 }
else if (
len < 0) {
194 ESP_LOGE(TAG,
"Error downloading image: %d",
len);
204 }
else if (consumed < 0) {
205 ESP_LOGE(TAG,
"Decode error with full buffer: %d", consumed);
212 ESP_LOGV(TAG,
"Decoder waiting for more data");
221 RuntimeImage::release();
248 RuntimeImage::release();
void enable_loop()
Enable this component's loop.
void disable_loop()
Disable this component's loop.
esphome::http_request::HttpRequestComponent * parent_
std::shared_ptr< HttpContainer > get(const std::string &url)
size_t free_capacity() const
uint8_t * data(size_t offset=0)
size_t resize(size_t size)
std::string etag_
The value of the ETag HTTP header provided in the last response.
OnlineImage(const std::string &url, int width, int height, runtime_image::ImageFormat format, image::ImageType type, image::Transparency transparency, image::Image *placeholder, uint32_t buffer_size, bool is_big_endian=false)
Construct a new OnlineImage object.
bool validate_url_(const std::string &url)
CallbackManager< void(bool)> download_finished_callback_
std::vector< std::pair< std::string, TemplatableValue< std::string > > > request_headers_
void add_on_error_callback(std::function< void()> &&callback)
void add_on_finished_callback(std::function< void(bool)> &&callback)
DownloadBuffer download_buffer_
void set_url(const std::string &url)
Set the URL to download the image from.
std::shared_ptr< http_request::HttpContainer > downloader_
CallbackManager< void()> download_error_callback_
size_t download_buffer_initial_size_
This is the initial size of the download buffer, not the current size.
std::string last_modified_
The value of the Last-Modified HTTP header provided in the last response.
void release()
Release the buffer storing the image.
bool is_decoding() const
Check if decoding is currently in progress.
bool end_decode()
Complete the decoding process.
int feed_data(uint8_t *data, size_t len)
Feed data to the decoder.
bool is_decode_finished() const
Check if the decoder has finished processing all data.
ImageFormat get_format() const
Get the image format.
bool begin_decode(size_t expected_size=0)
Begin decoding an image.
ImageFormat
Image format types that can be decoded dynamically.