HTTP 请求
http_request 组件允许您发起 HTTP/HTTPS 请求。为此,您需要将其添加到设备的配置中:
# 示例配置条目http_request:-
id (可选, ID): 手动指定用于代码生成的 ID。
-
follow_redirects (可选, boolean): 启用跟随 HTTP 重定向。默认为
true。 -
redirect_limit (可选, integer): 启用时跟随的最大重定向次数。默认为
3。 -
timeout (可选, 时间): 请求超时时间。默认为
4.5s。 -
useragent (可选, string): 请求的 User-Agent 头。默认为
ESPHome/<version> (https://esphome.io),其中<version>是设备运行的 ESPHome 版本。 例如:ESPHome/2024.6.0 (https://esphome.io) -
verify_ssl (可选, boolean): 设置为
true(默认)时,SSL/TLS 证书将在连接时进行验证; 如果无效,连接将被中止。为此,ESP-IDF 的默认 ESP x509 证书包将包含在构建中。此证书包包含 Mozilla NSS 根证书存储中的完整根证书列表。仅 ESP32 支持;在其他平台上必须显式设置为 false。 -
watchdog_timeout (可选, 时间): 更改连接/数据传输期间的看门狗超时时间。 在慢速连接或高延迟连接上可能有用。除非您遇到因看门狗超时导致的设备重启,否则不要更改此值; 这样做可能会阻止设备因合法问题而重启。仅在 ESP32 和 RP2040 上可用。
对于 ESP32:
- buffer_size_rx (可选, integer): 更改 HTTP 接收缓冲区大小。默认为
512。 - buffer_size_tx (可选, integer): 更改 HTTP 发送缓冲区大小。默认为
512。 - ca_certificate_path (可选, file path): PEM 编码的 CA 证书文件路径。使用此选项在保持
verify_ssl启用的同时验证使用自签名或自定义 CA 证书的服务器连接。 证书在编译时嵌入固件中。指定时,不包含默认证书包,从而减小固件大小。
对于 ESP8266:
-
esp8266_disable_ssl_support (可选, boolean): 确定是否在固件二进制文件中包含 HTTPS/SSL 支持。 从构建中排除 SSL 库将导致较小的二进制文件,这对于内存受限的设备(512 kB 或 1 MB)可能是必要的。 如果您在设备日志中看到
Error: ESP does not have enough space to store OTA file,您可能需要启用此选项。 默认为false。将此选项设置为true后:- HTTPS 连接将无法进行
- 隐含
verify_ssl: false
WARNING
将 verify_ssl 设置为 false 在使用 HTTPS 连接时会降低安全性!
没有根证书包,远程 HTTPS 服务器使用的证书无法验证,使 HTTPS 连接容易受到中间人攻击。
为了最大限度地提高安全性,*除非满足以下条件,*否则不要将 verify_ssl 设置为 false:
- 在非 ESP32 设备上使用 Arduino 框架,或
- 设备没有足够的内存来存储证书包
如果您需要在 ESP32 上连接使用自签名或自定义 CA 证书的服务器,请使用
ca_certificate_path 选项而不是禁用 verify_ssl。
我们强烈建议使用正确支持 TLS/SSL 的硬件。
对于主机平台:
- ca_certificate_path (可选, file path): CA 证书包的路径。在 MacOS 上不需要(使用内置 CA 包并默认启用 SSL)。 在 Linux 上,这是启用 SSL 所必需的。
NOTE
要在 Linux 上使用 SSL,您必须安装 libssl-dev 包(例如 sudo apt install libssl-dev)。
在 Linux 上,ca_certificate_path 的典型值是 /etc/ssl/certs/ca-certificates.crt。
http_request 组件支持许多可用于发送请求的动作。
http_request.get 动作
Section titled “http_request.get 动作”此动作发送 GET 请求。
on_...: - http_request.get: url: https://esphome.io request_headers: Content-Type: application/json on_response: then: - logger.log: format: '响应状态: %d, 持续时间: %u ms' args: - response->status_code - response->duration_ms # 简写形式 - http_request.get: https://esphome.io-
url (必需, string, 可模板化): 发送请求的 URL。
-
request_headers (可选, mapping): HTTP 头映射。值为可模板化。
-
collect_headers (可选, list of strings): 要从响应中收集的 HTTP 头名称列表。
-
capture_response (可选, boolean): 设置为
true时,响应数据将被捕获并放入body变量中作为std::string,用于 lambda。默认为false。 -
max_response_buffer_size (可选, integer): 用于存储响应的最大缓冲区大小。 默认为
1 kB。 -
on_response (可选, 自动化): 收到请求后执行的自动化。
-
on_error (可选, 自动化): 请求无法完成时执行的自动化。
http_request.post 动作
Section titled “http_request.post 动作”此动作发送 POST 请求。
on_...: - http_request.post: url: https://esphome.io request_headers: Content-Type: application/json json: key: value # 简写形式 - http_request.post: https://esphome.io-
body (可选, string, 可模板化): 随请求发送的 HTTP body 字符串。
-
http_request.get动作的所有其他选项。
http_request.send 动作
Section titled “http_request.send 动作”此动作发送请求。
on_...: - http_request.send: method: PUT url: https://esphome.io request_headers: Content-Type: application/json body: "Some data"- method (必需, string): 要使用的 HTTP 方法(
GET、POST、PUT、DELETE、PATCH)。 -
http_request.post动作和http_request.get动作的所有其他选项。
on_response 触发器
Section titled “on_response 触发器”当 HTTP 请求完成时将触发此自动化。 以下变量可在 lambda 中使用:
response作为指向HttpContainer对象的指针,其中包含content_length、status_code和duration_ms。std::string get_response_header(const std::string &header_name)用于读取响应头(只有名称在collect_headers中指定的头可用)。body作为std::string,当设置capture_response(请参阅http_request.get动作)为true时包含响应体。
NOTE
在使用 body 变量之前应该检查 status_code。成功的响应通常会有
状态码 200。服务器错误如”未找到”(404)或”内部服务器错误”(500)会有适当的状态码,并且可能在 body 变量中包含错误消息。
on_... then: - http_request.get: url: https://esphome.io collect_headers: - Content-Type on_response: then: - logger.log: format: "响应状态: %d, 持续时间: %u ms, Content-Type: %s" args: - response->status_code - response->duration_ms - response->get_response_header("Content-Type").c_str() - lambda: |- ESP_LOGD(TAG, "响应状态: %d, 持续时间: %u ms, Content-Type: %s", response->status_code, response->duration_ms, response->get_response_header("Content-Type").c_str()); on_error: then: - logger.log: "请求失败!"on_error 触发器
Section titled “on_error 触发器”当 HTTP 请求无法完成时将触发此自动化。例如网络不可用或服务器不可达。 如果请求完成,即使响应码不是 200,也不会触发此触发器。没有关于错误类型的信息,也没有变量可在 lambda 中使用。请参阅上面的示例用法。
可模板化的值
Section titled “可模板化的值”on_...: - http_request.post: url: !lambda |- return ((std::string) "https://esphome.io?state=" + id(my_sensor).state).c_str(); request_headers: X-Custom-Header: !lambda |- return ((std::string) "Value-" + id(my_sensor).state).c_str(); body: !lambda |- return id(my_sensor).state;JSON 格式的 POST Body(语法 1)
Section titled “JSON 格式的 POST Body(语法 1)”注意: 映射的所有值必须是字符串。使用此语法无法发送 JSON boolean 或 numbers。
on_...: - http_request.post: url: https://esphome.io json: key: !lambda |- return id(my_sensor).state; greeting: "Hello World"
# 将发送: # {"key": "42.0", "greeting": "Hello World"}JSON 格式的 POST Body(语法 2)
Section titled “JSON 格式的 POST Body(语法 2)”注意: 使用此语法发送 JSON 中的 boolean 或 numbers。
JSON 消息将使用 ArduinoJson 库构建。
在 json 选项中,您可以访问一个 root 对象,它代表 JSON 消息的基对象。您
可以使用 root["KEY_NAME"] = VALUE; 语法为键分配值,如下所示。
on_...: - http_request.post: url: https://esphome.io json: |- root["key"] = id(my_sensor).state; root["greeting"] = "Hello World";
# 将发送: # {"key": 42.0, "greeting": "Hello World"}从 JSON body 响应中获取值
Section titled “从 JSON body 响应中获取值”如果您想检索 vol 键的值并将其分配给 id 设置为 player_volume 的模板传感器或数字组件,您可以这样做,但请注意,检查键的存在可以防止难以阅读的错误消息:
此示例假设服务器返回类似以下的 JSON 对象响应:
{"status":"play","vol":"42","mute":"0"}
如果您想检索 vol 键的值并将其分配给 id 设置为 player_volume 的模板 sensor 或 number 组件:
on_...:- http_request.get: url: https://esphome.io capture_response: true on_response: then: - if: condition: lambda: return response->status_code == 200; then: - lambda: |- json::parse_json(body, [](JsonObject root) -> bool { if (root["vol"]) { id(player_volume).publish_state(root["vol"]); return true; } else { ESP_LOGI(TAG,"此 json 中没有 'vol' 键!"); return false; } }); else: - logger.log: format: "错误: 响应状态: %d, 消息 %s" args: [ 'response->status_code', 'body.c_str()' ]