From 052f5581317f740aeda28af9902e8b0b822500a6 Mon Sep 17 00:00:00 2001 From: Stanislav Meduna Date: Wed, 11 Jun 2025 12:14:02 +0200 Subject: [PATCH] Add support for custom request headers in online_image component (#8985) --- esphome/components/online_image/__init__.py | 12 ++++++++++++ esphome/components/online_image/online_image.cpp | 4 ++++ esphome/components/online_image/online_image.h | 7 +++++++ tests/components/online_image/common.yaml | 3 +++ 4 files changed, 26 insertions(+) diff --git a/esphome/components/online_image/__init__.py b/esphome/components/online_image/__init__.py index 7ef80ff92f..9380cf1b1b 100644 --- a/esphome/components/online_image/__init__.py +++ b/esphome/components/online_image/__init__.py @@ -2,6 +2,7 @@ import logging from esphome import automation import esphome.codegen as cg +from esphome.components.const import CONF_REQUEST_HEADERS from esphome.components.http_request import CONF_HTTP_REQUEST_ID, HttpRequestComponent from esphome.components.image import ( CONF_INVERT_ALPHA, @@ -24,6 +25,7 @@ from esphome.const import ( CONF_TYPE, CONF_URL, ) +from esphome.core import Lambda AUTO_LOAD = ["image"] DEPENDENCIES = ["display", "http_request"] @@ -124,6 +126,9 @@ ONLINE_IMAGE_SCHEMA = ( cv.GenerateID(CONF_HTTP_REQUEST_ID): cv.use_id(HttpRequestComponent), # Online Image specific options cv.Required(CONF_URL): cv.url, + cv.Optional(CONF_REQUEST_HEADERS): cv.All( + cv.Schema({cv.string: cv.templatable(cv.string)}) + ), cv.Required(CONF_FORMAT): cv.one_of(*IMAGE_FORMATS, upper=True), cv.Optional(CONF_PLACEHOLDER): cv.use_id(Image_), cv.Optional(CONF_BUFFER_SIZE, default=65536): cv.int_range(256, 65536), @@ -207,6 +212,13 @@ async def to_code(config): await cg.register_component(var, config) await cg.register_parented(var, config[CONF_HTTP_REQUEST_ID]) + for key, value in config.get(CONF_REQUEST_HEADERS, {}).items(): + if isinstance(value, Lambda): + template_ = await cg.templatable(value, [], cg.std_string) + cg.add(var.add_request_header(key, template_)) + else: + cg.add(var.add_request_header(key, value)) + if placeholder_id := config.get(CONF_PLACEHOLDER): placeholder = await cg.get_variable(placeholder_id) cg.add(var.set_placeholder(placeholder)) diff --git a/esphome/components/online_image/online_image.cpp b/esphome/components/online_image/online_image.cpp index 2b20b32772..8030bd0095 100644 --- a/esphome/components/online_image/online_image.cpp +++ b/esphome/components/online_image/online_image.cpp @@ -143,6 +143,10 @@ void OnlineImage::update() { headers.push_back(accept_header); + for (auto &header : this->request_headers_) { + headers.push_back(http_request::Header{header.first, header.second.value()}); + } + this->downloader_ = this->parent_->get(this->url_, headers, {ETAG_HEADER_NAME, LAST_MODIFIED_HEADER_NAME}); if (this->downloader_ == nullptr) { diff --git a/esphome/components/online_image/online_image.h b/esphome/components/online_image/online_image.h index 920aee2796..6ed9c7956f 100644 --- a/esphome/components/online_image/online_image.h +++ b/esphome/components/online_image/online_image.h @@ -67,6 +67,11 @@ class OnlineImage : public PollingComponent, this->last_modified_ = ""; } + /** Add the request header */ + template void add_request_header(const std::string &header, V value) { + this->request_headers_.push_back(std::pair >(header, value)); + } + /** * @brief Set the image that needs to be shown as long as the downloaded image * is not available. @@ -153,6 +158,8 @@ class OnlineImage : public PollingComponent, std::string url_{""}; + std::vector > > request_headers_; + /** width requested on configuration, or 0 if non specified. */ const int fixed_width_; /** height requested on configuration, or 0 if non specified. */ diff --git a/tests/components/online_image/common.yaml b/tests/components/online_image/common.yaml index 25809930b5..422a24b540 100644 --- a/tests/components/online_image/common.yaml +++ b/tests/components/online_image/common.yaml @@ -11,6 +11,9 @@ online_image: format: PNG type: BINARY resize: 50x50 + request_headers: + X-Test1: 'Test1' + X-Test2: !lambda 'static int x; return to_string(x++);' on_download_finished: lambda: |- if (cached) {