From 2ee01e22cdac6a24e1b31c301dc2a1e622d3143e Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Fri, 22 Dec 2023 03:28:25 +1300 Subject: [PATCH 001/189] Fix replaced - in allowed characters during object_id sanitizing (#5983) --- esphome/helpers.py | 2 +- tests/unit_tests/test_helpers.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/esphome/helpers.py b/esphome/helpers.py index 00416b591f..254c950b5d 100644 --- a/esphome/helpers.py +++ b/esphome/helpers.py @@ -357,7 +357,7 @@ def snake_case(value): return value.replace(" ", "_").lower() -_DISALLOWED_CHARS = re.compile(r"[^a-zA-Z0-9_]") +_DISALLOWED_CHARS = re.compile(r"[^a-zA-Z0-9-_]") def sanitize(value): diff --git a/tests/unit_tests/test_helpers.py b/tests/unit_tests/test_helpers.py index 79d39901f0..fc6bdbcdec 100644 --- a/tests/unit_tests/test_helpers.py +++ b/tests/unit_tests/test_helpers.py @@ -261,6 +261,7 @@ def test_snake_case(text, expected): ('!"§$%&/()=?foo_bar', "___________foo_bar"), ('foo_!"§$%&/()=?bar', "foo____________bar"), ('foo_bar!"§$%&/()=?', "foo_bar___________"), + ('foo-bar!"§$%&/()=?', "foo-bar___________"), ), ) def test_sanitize(text, expected): From 00ab17cb8e9452bb4575b92ad6cc0a75551911d3 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Thu, 21 Dec 2023 23:33:35 +0900 Subject: [PATCH 002/189] Bump version to 2023.12.1 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 55be91a4f9..4537c276c5 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2023.12.0" +__version__ = "2023.12.1" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From 1a8e7854c7548322402f4d70de528d0b7f66fdb1 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Fri, 15 Dec 2023 11:24:52 +1100 Subject: [PATCH 003/189] ESP32-S3 and ESP-IDF don't play well with USB_CDC and need USB_SERIAL_JTAG (#5929) Co-authored-by: Keith Burzinski --- esphome/components/logger/__init__.py | 4 +- esphome/config_validation.py | 27 +++++++--- tests/test8.1.yaml | 78 +++++++++++++++++++++++++++ tests/test8.2.yaml | 75 ++++++++++++++++++++++++++ 4 files changed, 177 insertions(+), 7 deletions(-) create mode 100644 tests/test8.1.yaml create mode 100644 tests/test8.2.yaml diff --git a/esphome/components/logger/__init__.py b/esphome/components/logger/__init__.py index be302bd489..6cad783db9 100644 --- a/esphome/components/logger/__init__.py +++ b/esphome/components/logger/__init__.py @@ -172,7 +172,9 @@ CONFIG_SCHEMA = cv.All( esp8266=UART0, esp32=UART0, esp32_s2=USB_CDC, - esp32_s3=USB_CDC, + esp32_s3_idf=USB_SERIAL_JTAG, + esp32_c3_idf=USB_SERIAL_JTAG, + esp32_s3_arduino=USB_CDC, rp2040=USB_CDC, bk72xx=DEFAULT, rtl87xx=DEFAULT, diff --git a/esphome/config_validation.py b/esphome/config_validation.py index 7b94608509..8f2e080b46 100644 --- a/esphome/config_validation.py +++ b/esphome/config_validation.py @@ -1541,6 +1541,9 @@ class SplitDefault(Optional): esp32_s3=vol.UNDEFINED, esp32_s3_arduino=vol.UNDEFINED, esp32_s3_idf=vol.UNDEFINED, + esp32_c3=vol.UNDEFINED, + esp32_c3_arduino=vol.UNDEFINED, + esp32_c3_idf=vol.UNDEFINED, rp2040=vol.UNDEFINED, bk72xx=vol.UNDEFINED, rtl87xx=vol.UNDEFINED, @@ -1549,22 +1552,28 @@ class SplitDefault(Optional): super().__init__(key) self._esp8266_default = vol.default_factory(esp8266) self._esp32_arduino_default = vol.default_factory( - _get_priority_default(esp32, esp32_arduino) + _get_priority_default(esp32_arduino, esp32) ) self._esp32_idf_default = vol.default_factory( - _get_priority_default(esp32, esp32_idf) + _get_priority_default(esp32_idf, esp32) ) self._esp32_s2_arduino_default = vol.default_factory( - _get_priority_default(esp32_s2, esp32, esp32_s2_arduino, esp32_arduino) + _get_priority_default(esp32_s2_arduino, esp32_s2, esp32_arduino, esp32) ) self._esp32_s2_idf_default = vol.default_factory( - _get_priority_default(esp32_s2, esp32, esp32_s2_idf, esp32_idf) + _get_priority_default(esp32_s2_idf, esp32_s2, esp32_idf, esp32) ) self._esp32_s3_arduino_default = vol.default_factory( - _get_priority_default(esp32_s3, esp32, esp32_s3_arduino, esp32_arduino) + _get_priority_default(esp32_s3_arduino, esp32_s3, esp32_arduino, esp32) ) self._esp32_s3_idf_default = vol.default_factory( - _get_priority_default(esp32_s3, esp32, esp32_s3_idf, esp32_idf) + _get_priority_default(esp32_s3_idf, esp32_s3, esp32_idf, esp32) + ) + self._esp32_c3_arduino_default = vol.default_factory( + _get_priority_default(esp32_c3_arduino, esp32_c3, esp32_arduino, esp32) + ) + self._esp32_c3_idf_default = vol.default_factory( + _get_priority_default(esp32_c3_idf, esp32_c3, esp32_idf, esp32) ) self._rp2040_default = vol.default_factory(rp2040) self._bk72xx_default = vol.default_factory(bk72xx) @@ -1580,6 +1589,7 @@ class SplitDefault(Optional): from esphome.components.esp32.const import ( VARIANT_ESP32S2, VARIANT_ESP32S3, + VARIANT_ESP32C3, ) variant = get_esp32_variant() @@ -1593,6 +1603,11 @@ class SplitDefault(Optional): return self._esp32_s3_arduino_default if CORE.using_esp_idf: return self._esp32_s3_idf_default + elif variant == VARIANT_ESP32C3: + if CORE.using_arduino: + return self._esp32_c3_arduino_default + if CORE.using_esp_idf: + return self._esp32_c3_idf_default else: if CORE.using_arduino: return self._esp32_arduino_default diff --git a/tests/test8.1.yaml b/tests/test8.1.yaml new file mode 100644 index 0000000000..bc1d2e22a4 --- /dev/null +++ b/tests/test8.1.yaml @@ -0,0 +1,78 @@ +# Tests for ESP32-S3 boards - IDf +--- +wifi: + ssid: "ssid" + +network: + enable_ipv6: true + +esp32: + board: esp32s3box + variant: ESP32S3 + framework: + type: esp-idf + +esphome: + name: esp32-s3-test + +logger: + +debug: + +psram: + +spi: + - id: spi_id_1 + clk_pin: + number: GPIO7 + allow_other_uses: false + mosi_pin: GPIO6 + interface: any + +spi_device: + id: spidev + data_rate: 2MHz + spi_id: spi_id_1 + mode: 3 + bit_order: lsb_first + +display: + - platform: ili9xxx + id: displ8 + model: ili9342 + cs_pin: GPIO5 + dc_pin: GPIO4 + reset_pin: + number: GPIO48 + allow_other_uses: true + +i2c: + scl: GPIO18 + sda: GPIO8 + +touchscreen: + - platform: tt21100 + display: displ8 + interrupt_pin: + number: GPIO3 + ignore_strapping_warning: true + allow_other_uses: false + reset_pin: + number: GPIO48 + allow_other_uses: true + +binary_sensor: + - platform: tt21100 + name: Home Button + index: 1 + +sensor: + - platform: debug + free: + name: "Heap Free" + block: + name: "Max Block Free" + loop_time: + name: "Loop Time" + psram: + name: "PSRAM Free" diff --git a/tests/test8.2.yaml b/tests/test8.2.yaml new file mode 100644 index 0000000000..69525b333b --- /dev/null +++ b/tests/test8.2.yaml @@ -0,0 +1,75 @@ +# Tests for ESP32-C3 boards - IDf +--- +wifi: + ssid: "ssid" + +network: + enable_ipv6: true + +esp32: + board: lolin_c3_mini + variant: ESP32C3 + framework: + type: esp-idf + +esphome: + name: esp32-c3-test + +logger: + +debug: + +psram: + +spi: + - id: spi_id_1 + clk_pin: + number: GPIO7 + allow_other_uses: false + mosi_pin: GPIO6 + interface: any + +spi_device: + id: spidev + data_rate: 2MHz + spi_id: spi_id_1 + mode: 3 + bit_order: lsb_first + +display: + - platform: ili9xxx + id: displ8 + model: ili9342 + cs_pin: GPIO5 + dc_pin: GPIO4 + reset_pin: + number: GPIO21 + +i2c: + scl: GPIO18 + sda: GPIO8 + +touchscreen: + - platform: tt21100 + display: displ8 + interrupt_pin: + number: GPIO3 + allow_other_uses: false + reset_pin: + number: GPIO20 + +binary_sensor: + - platform: tt21100 + name: Home Button + index: 1 + +sensor: + - platform: debug + free: + name: "Heap Free" + block: + name: "Max Block Free" + loop_time: + name: "Loop Time" + psram: + name: "PSRAM Free" From 2a69a49061080365c6e199e4f9a661549667fd88 Mon Sep 17 00:00:00 2001 From: CVan Date: Thu, 21 Dec 2023 17:55:10 -0500 Subject: [PATCH 004/189] Update libtiff6 (#5985) --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index ee7c70bb0f..7c162fc316 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -50,7 +50,7 @@ RUN \ libssl-dev=3.0.11-1~deb12u2 \ libffi-dev=3.4.4-1 \ libopenjp2-7=2.5.0-2 \ - libtiff6=4.5.0-6 \ + libtiff6=4.5.0-6+deb12u1 \ cargo=0.66.0+ds1-1 \ pkg-config=1.8.1-1 \ gcc-arm-linux-gnueabihf=4:12.2.0-3; \ From 872519f7f6e44a31055cbd01efc32ef73b27682f Mon Sep 17 00:00:00 2001 From: davidmonro Date: Fri, 22 Dec 2023 09:57:12 +1100 Subject: [PATCH 005/189] Override GPIOs 12 and 13 on the airm2m (LuatOS) board (#5982) Co-authored-by: David Monro --- esphome/components/esp32/boards.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/esphome/components/esp32/boards.py b/esphome/components/esp32/boards.py index e6c23c4d96..eaeab2caec 100644 --- a/esphome/components/esp32/boards.py +++ b/esphome/components/esp32/boards.py @@ -133,6 +133,10 @@ ESP32_BOARD_PINS = { "BUTTON": 0, "SWITCH": 0, }, + "airm2m_core_esp32c3": { + "LED1_BUILTIN": 12, + "LED2_BUILTIN": 13, + }, "alksesp32": { "A0": 32, "A1": 33, From 4f8e3211bf9427f739585268516645042611e521 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Thu, 21 Dec 2023 19:42:12 -0600 Subject: [PATCH 006/189] Add workaround for crash in Arduino 2.0.9 when CDC is configured (#5987) --- esphome/components/logger/logger.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/esphome/components/logger/logger.cpp b/esphome/components/logger/logger.cpp index 05b97a5f64..e0f7e77d2c 100644 --- a/esphome/components/logger/logger.cpp +++ b/esphome/components/logger/logger.cpp @@ -285,6 +285,7 @@ void Logger::pre_setup() { #if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) #if ARDUINO_USB_CDC_ON_BOOT this->hw_serial_ = &Serial; + Serial.setTxTimeoutMs(0); // workaround for 2.0.9 crash when there's no data connection Serial.begin(this->baud_rate_); #else this->hw_serial_ = &Serial; From 8e13c3e1b0a413cc0820f1932ed2521ec05b404e Mon Sep 17 00:00:00 2001 From: Jessica Hamilton Date: Fri, 22 Dec 2023 14:58:30 +1300 Subject: [PATCH 007/189] web_server.py: return empty content when file doesn't exist (#5980) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/dashboard/web_server.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/esphome/dashboard/web_server.py b/esphome/dashboard/web_server.py index 4552aebf7b..c4b84d3fe3 100644 --- a/esphome/dashboard/web_server.py +++ b/esphome/dashboard/web_server.py @@ -792,13 +792,22 @@ class EditRequestHandler(BaseHandler): """Get the content of a file.""" loop = asyncio.get_running_loop() filename = settings.rel_path(configuration) - content = await loop.run_in_executor(None, self._read_file, filename) - self.write(content) + content = await loop.run_in_executor( + None, self._read_file, filename, configuration + ) + if content is not None: + self.write(content) - def _read_file(self, filename: str) -> bytes: + def _read_file(self, filename: str, configuration: str) -> bytes | None: """Read a file and return the content as bytes.""" - with open(file=filename, encoding="utf-8") as f: - return f.read() + try: + with open(file=filename, encoding="utf-8") as f: + return f.read() + except FileNotFoundError: + if configuration in const.SECRETS_FILES: + return "" + self.set_status(404) + return None def _write_file(self, filename: str, content: bytes) -> None: """Write a file with the given content.""" From 19e5a4a81a01611d0f6620165bdb438bc94a1adb Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Fri, 22 Dec 2023 11:04:00 +0900 Subject: [PATCH 008/189] Bump version to 2023.12.2 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 4537c276c5..5fa2d91e33 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2023.12.1" +__version__ = "2023.12.2" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From f5c99d164798d3f0f6af78567e37f1025fbf2cfa Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 21 Dec 2023 16:59:24 -1000 Subject: [PATCH 009/189] Fix unexpected disconnects when outgoing buffer is full during keepalive (#5988) --- esphome/components/api/api_connection.cpp | 24 +++++++++++++++++++---- esphome/components/api/api_connection.h | 3 +++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index d5ab00a822..4ebfb7582e 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -118,7 +118,9 @@ void APIConnection::loop() { this->list_entities_iterator_.advance(); this->initial_state_iterator_.advance(); - const uint32_t keepalive = 60000; + static uint32_t keepalive = 60000; + static uint8_t max_ping_retries = 60; + static uint16_t ping_retry_interval = 1000; const uint32_t now = millis(); if (this->sent_ping_) { // Disconnect if not responded within 2.5*keepalive @@ -126,10 +128,24 @@ void APIConnection::loop() { on_fatal_error(); ESP_LOGW(TAG, "%s didn't respond to ping request in time. Disconnecting...", this->client_combined_info_.c_str()); } - } else if (now - this->last_traffic_ > keepalive) { + } else if (now - this->last_traffic_ > keepalive && now > this->next_ping_retry_) { ESP_LOGVV(TAG, "Sending keepalive PING..."); - this->sent_ping_ = true; - this->send_ping_request(PingRequest()); + this->sent_ping_ = this->send_ping_request(PingRequest()); + if (!this->sent_ping_) { + this->next_ping_retry_ = now + ping_retry_interval; + this->ping_retries_++; + if (this->ping_retries_ >= max_ping_retries) { + on_fatal_error(); + ESP_LOGE(TAG, "%s: Sending keepalive failed %d time(s). Disconnecting...", this->client_combined_info_.c_str(), + this->ping_retries_); + } else if (this->ping_retries_ >= 10) { + ESP_LOGW(TAG, "%s: Sending keepalive failed %d time(s), will retry in %d ms", + this->client_combined_info_.c_str(), this->ping_retries_, ping_retry_interval); + } else { + ESP_LOGD(TAG, "%s: Sending keepalive failed %d time(s), will retry in %d ms", + this->client_combined_info_.c_str(), this->ping_retries_, ping_retry_interval); + } + } } #ifdef USE_ESP32_CAMERA diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index 09b595bb71..9d01468807 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -140,6 +140,7 @@ class APIConnection : public APIServerConnection { void on_disconnect_response(const DisconnectResponse &value) override; void on_ping_response(const PingResponse &value) override { // we initiated ping + this->ping_retries_ = 0; this->sent_ping_ = false; } void on_home_assistant_state_response(const HomeAssistantStateResponse &msg) override; @@ -217,6 +218,8 @@ class APIConnection : public APIServerConnection { bool state_subscription_{false}; int log_subscription_{ESPHOME_LOG_LEVEL_NONE}; uint32_t last_traffic_; + uint32_t next_ping_retry_{0}; + uint8_t ping_retries_{0}; bool sent_ping_{false}; bool service_call_subscription_{false}; bool next_close_ = false; From 46310ff223932b34b67c4f207a6e6154950ef8e1 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:29:10 +1300 Subject: [PATCH 010/189] Regenerate api_pb2 after manual changes were added incorrectly in #5732 (#5990) --- esphome/components/api/api_pb2.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index 8dd34e7ef1..f81bf04e99 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -3848,6 +3848,7 @@ void ListEntitiesClimateResponse::dump_to(std::string &out) const { sprintf(buffer, "%g", this->visual_max_humidity); out.append(buffer); out.append("\n"); + out.append("}"); } #endif bool ClimateStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) { @@ -4015,6 +4016,7 @@ void ClimateStateResponse::dump_to(std::string &out) const { sprintf(buffer, "%g", this->target_humidity); out.append(buffer); out.append("\n"); + out.append("}"); } #endif bool ClimateCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) { From 45f9f3d9723340b2ab049b643b881e3c0de6ed80 Mon Sep 17 00:00:00 2001 From: matzman666 Date: Fri, 22 Dec 2023 07:58:17 +0100 Subject: [PATCH 011/189] Improved sensor readings in htu21d component. (#5839) --- esphome/components/htu21d/htu21d.cpp | 67 ++++++++++++++++------------ 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/esphome/components/htu21d/htu21d.cpp b/esphome/components/htu21d/htu21d.cpp index a8133ae32e..d0dbb15a43 100644 --- a/esphome/components/htu21d/htu21d.cpp +++ b/esphome/components/htu21d/htu21d.cpp @@ -39,45 +39,54 @@ void HTU21DComponent::dump_config() { LOG_SENSOR(" ", "Humidity", this->humidity_); } void HTU21DComponent::update() { - uint16_t raw_temperature; if (this->write(&HTU21D_REGISTER_TEMPERATURE, 1) != i2c::ERROR_OK) { this->status_set_warning(); return; } - delay(50); // NOLINT - if (this->read(reinterpret_cast(&raw_temperature), 2) != i2c::ERROR_OK) { - this->status_set_warning(); - return; - } - raw_temperature = i2c::i2ctohs(raw_temperature); - float temperature = (float(raw_temperature & 0xFFFC)) * 175.72f / 65536.0f - 46.85f; + // According to the datasheet sht21 temperature readings can take up to 85ms + this->set_timeout(85, [this]() { + uint16_t raw_temperature; + if (this->read(reinterpret_cast(&raw_temperature), 2) != i2c::ERROR_OK) { + this->status_set_warning(); + return; + } + raw_temperature = i2c::i2ctohs(raw_temperature); - uint16_t raw_humidity; - if (this->write(&HTU21D_REGISTER_HUMIDITY, 1) != i2c::ERROR_OK) { - this->status_set_warning(); - return; - } - delay(50); // NOLINT - if (this->read(reinterpret_cast(&raw_humidity), 2) != i2c::ERROR_OK) { - this->status_set_warning(); - return; - } - raw_humidity = i2c::i2ctohs(raw_humidity); + float temperature = (float(raw_temperature & 0xFFFC)) * 175.72f / 65536.0f - 46.85f; - float humidity = (float(raw_humidity & 0xFFFC)) * 125.0f / 65536.0f - 6.0f; + ESP_LOGD(TAG, "Got Temperature=%.1f°C", temperature); - int8_t heater_level = this->get_heater_level(); + if (this->temperature_ != nullptr) + this->temperature_->publish_state(temperature); + this->status_clear_warning(); - ESP_LOGD(TAG, "Got Temperature=%.1f°C Humidity=%.1f%% Heater Level=%d", temperature, humidity, heater_level); + if (this->write(&HTU21D_REGISTER_HUMIDITY, 1) != i2c::ERROR_OK) { + this->status_set_warning(); + return; + } - if (this->temperature_ != nullptr) - this->temperature_->publish_state(temperature); - if (this->humidity_ != nullptr) - this->humidity_->publish_state(humidity); - if (this->heater_ != nullptr) - this->heater_->publish_state(heater_level); - this->status_clear_warning(); + this->set_timeout(50, [this]() { + uint16_t raw_humidity; + if (this->read(reinterpret_cast(&raw_humidity), 2) != i2c::ERROR_OK) { + this->status_set_warning(); + return; + } + raw_humidity = i2c::i2ctohs(raw_humidity); + + float humidity = (float(raw_humidity & 0xFFFC)) * 125.0f / 65536.0f - 6.0f; + + int8_t heater_level = this->get_heater_level(); + + ESP_LOGD(TAG, "Got Humidity=%.1f%% Heater Level=%d", humidity, heater_level); + + if (this->humidity_ != nullptr) + this->humidity_->publish_state(humidity); + if (this->heater_ != nullptr) + this->heater_->publish_state(heater_level); + this->status_clear_warning(); + }); + }); } bool HTU21DComponent::is_heater_enabled() { From 9202a30dc7f3bf92fafe80c3d76a9ddd184a613f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 21 Dec 2023 21:35:31 -1000 Subject: [PATCH 012/189] Fix dashboard logs when api is disabled and using MQTT (#5992) --- esphome/dashboard/web_server.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/esphome/dashboard/web_server.py b/esphome/dashboard/web_server.py index c4b84d3fe3..6a80865906 100644 --- a/esphome/dashboard/web_server.py +++ b/esphome/dashboard/web_server.py @@ -301,11 +301,16 @@ class EsphomePortCommandWebSocket(EsphomeCommandWebSocket): config_file = settings.rel_path(configuration) port = json_message["port"] if ( - port == "OTA" + port == "OTA" # pylint: disable=too-many-boolean-expressions and (mdns := dashboard.mdns_status) and (entry := entries.get(config_file)) + and entry.loaded_integrations + and "api" in entry.loaded_integrations and (address := await mdns.async_resolve_host(entry.name)) ): + # Use the IP address if available but only + # if the API is loaded and the device is online + # since MQTT logging will not work otherwise port = address return [ From 7dc35a10290891123953ab1d6fa6feb84bb81ef5 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Fri, 22 Dec 2023 21:10:35 +1300 Subject: [PATCH 013/189] Fix broken configs with non-existent components (#5993) --- esphome/config.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/esphome/config.py b/esphome/config.py index e9433d537e..4aca0d6056 100644 --- a/esphome/config.py +++ b/esphome/config.py @@ -315,7 +315,11 @@ class LoadValidationStep(ConfigValidationStep): return result.add_output_path([self.domain], self.domain) component = get_component(self.domain) - if component.multi_conf_no_default and isinstance(self.conf, core.AutoLoad): + if ( + component is not None + and component.multi_conf_no_default + and isinstance(self.conf, core.AutoLoad) + ): self.conf = [] result[self.domain] = self.conf path = [self.domain] From 417e37d291f1643e19266ab8abe4b67ca2644334 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Fri, 22 Dec 2023 17:12:42 +0900 Subject: [PATCH 014/189] Bump version to 2023.12.3 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 5fa2d91e33..8844b11a19 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2023.12.2" +__version__ = "2023.12.3" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From 0990d0812efca972b5af2a2b284c66676b09f99f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 22 Dec 2023 15:43:17 -1000 Subject: [PATCH 015/189] dashboard: Only ping when polling is active (#6001) fixes https://github.com/esphome/issues/issues/5257 --- esphome/dashboard/status/ping.py | 1 + 1 file changed, 1 insertion(+) diff --git a/esphome/dashboard/status/ping.py b/esphome/dashboard/status/ping.py index d8281d9de1..989cd1570f 100644 --- a/esphome/dashboard/status/ping.py +++ b/esphome/dashboard/status/ping.py @@ -31,6 +31,7 @@ class PingStatus: while not dashboard.stop_event.is_set(): # Only ping if the dashboard is open await dashboard.ping_request.wait() + dashboard.ping_request.clear() current_entries = dashboard.entries.async_all() to_ping: list[DashboardEntry] = [ entry for entry in current_entries if entry.address is not None From dc0cc0b431d1aeacf61c2d864ec850ed0e1a7d51 Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Sun, 24 Dec 2023 14:54:53 +0100 Subject: [PATCH 016/189] tt21100: restore init read (#6008) --- esphome/components/tt21100/touchscreen/tt21100.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/esphome/components/tt21100/touchscreen/tt21100.cpp b/esphome/components/tt21100/touchscreen/tt21100.cpp index 6b5cba74cd..ba4b0ee02d 100644 --- a/esphome/components/tt21100/touchscreen/tt21100.cpp +++ b/esphome/components/tt21100/touchscreen/tt21100.cpp @@ -64,6 +64,9 @@ void TT21100Touchscreen::setup() { // Update display dimensions if they were updated during display setup this->x_raw_max_ = this->get_width_(); this->y_raw_max_ = this->get_height_(); + + // Trigger initial read to activate the interrupt + this->store_.touched = true; } void TT21100Touchscreen::update_touches() { From 7bce999bba6ad954548127fe85c2c7fa94f1fc5c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 24 Dec 2023 03:56:31 -1000 Subject: [PATCH 017/189] dashboard: Fix file writes on Windows (#6013) --- esphome/dashboard/util/file.py | 10 +++++++++- tests/dashboard/util/test_file.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/esphome/dashboard/util/file.py b/esphome/dashboard/util/file.py index 5f3c5f5f1b..661d5f34cf 100644 --- a/esphome/dashboard/util/file.py +++ b/esphome/dashboard/util/file.py @@ -30,6 +30,7 @@ def write_file( """ tmp_filename = "" + missing_fchmod = False try: # Modern versions of Python tempfile create this file with mode 0o600 with tempfile.NamedTemporaryFile( @@ -38,8 +39,15 @@ def write_file( fdesc.write(utf8_data) tmp_filename = fdesc.name if not private: - os.fchmod(fdesc.fileno(), 0o644) + try: + os.fchmod(fdesc.fileno(), 0o644) + except AttributeError: + # os.fchmod is not available on Windows + missing_fchmod = True + os.replace(tmp_filename, filename) + if missing_fchmod: + os.chmod(filename, 0o644) finally: if os.path.exists(tmp_filename): try: diff --git a/tests/dashboard/util/test_file.py b/tests/dashboard/util/test_file.py index 89e6b97086..270ab565f1 100644 --- a/tests/dashboard/util/test_file.py +++ b/tests/dashboard/util/test_file.py @@ -13,7 +13,7 @@ def test_write_utf8_file(tmp_path: Path) -> None: assert tmp_path.joinpath("foo.txt").read_text() == "foo" with pytest.raises(OSError): - write_utf8_file(Path("/not-writable"), "bar") + write_utf8_file(Path("/dev/not-writable"), "bar") def test_write_file(tmp_path: Path) -> None: From b68420b2cc3004168fc6b7aecae59709cf6dee6c Mon Sep 17 00:00:00 2001 From: NP v/d Spek Date: Sun, 24 Dec 2023 14:58:27 +0100 Subject: [PATCH 018/189] Display: fix class inherence in Python script (#6009) --- esphome/components/display/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/display/__init__.py b/esphome/components/display/__init__.py index 9f4e922a37..91f10c5458 100644 --- a/esphome/components/display/__init__.py +++ b/esphome/components/display/__init__.py @@ -18,8 +18,8 @@ from esphome.core import coroutine_with_priority IS_PLATFORM_COMPONENT = True display_ns = cg.esphome_ns.namespace("display") -Display = display_ns.class_("Display") -DisplayBuffer = display_ns.class_("DisplayBuffer") +Display = display_ns.class_("Display", cg.PollingComponent) +DisplayBuffer = display_ns.class_("DisplayBuffer", Display) DisplayPage = display_ns.class_("DisplayPage") DisplayPagePtr = DisplayPage.operator("ptr") DisplayRef = Display.operator("ref") From 4c8c4a2579f7ec2c232d3e51edf04832f088de72 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Mon, 25 Dec 2023 21:14:55 +0900 Subject: [PATCH 019/189] Bump version to 2023.12.4 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 8844b11a19..5435538204 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2023.12.3" +__version__ = "2023.12.4" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From 21e5806a7387cc95a666f21970caf530b96f229d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 24 Dec 2023 03:57:15 -1000 Subject: [PATCH 020/189] Fix docker builds (#6012) --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 7c162fc316..468124e3ed 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -34,7 +34,7 @@ RUN \ python3-wheel=0.38.4-2 \ iputils-ping=3:20221126-1 \ git=1:2.39.2-1.1 \ - curl=7.88.1-10+deb12u4 \ + curl=7.88.1-10+deb12u5 \ openssh-client=1:9.2p1-2+deb12u1 \ python3-cffi=1.15.1-5 \ libcairo2=1.16.0-7 \ From 6ceefe08abfe1d38c0566688a0f2b1a1b250eecb Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Mon, 25 Dec 2023 22:24:13 +0900 Subject: [PATCH 021/189] Bump version to 2023.12.5 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 5435538204..d762b0aa71 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2023.12.4" +__version__ = "2023.12.5" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From 48a4e6bae9417fbb732cae539cd0c4864b75a2d7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 27 Dec 2023 17:51:00 -1000 Subject: [PATCH 022/189] Fix device not requesting Home Assistant time at the update interval (#6022) --- esphome/components/api/api_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/api/api_server.cpp b/esphome/components/api/api_server.cpp index 0348112fcd..8df860bb09 100644 --- a/esphome/components/api/api_server.cpp +++ b/esphome/components/api/api_server.cpp @@ -319,7 +319,7 @@ void APIServer::set_reboot_timeout(uint32_t reboot_timeout) { this->reboot_timeo #ifdef USE_HOMEASSISTANT_TIME void APIServer::request_time() { for (auto &client : this->clients_) { - if (!client->remove_ && client->connection_state_ == APIConnection::ConnectionState::CONNECTED) + if (!client->remove_ && client->is_authenticated()) client->send_time_request(); } } From da56d333dc24b9e7385252f09ad2b9b8cbfa03f1 Mon Sep 17 00:00:00 2001 From: tomaszduda23 Date: Tue, 9 Jan 2024 00:05:52 +0100 Subject: [PATCH 023/189] fix compilation error for libretiny (#6064) --- esphome/components/libretiny/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/libretiny/__init__.py b/esphome/components/libretiny/__init__.py index e36c08d522..7dca370eff 100644 --- a/esphome/components/libretiny/__init__.py +++ b/esphome/components/libretiny/__init__.py @@ -309,7 +309,7 @@ async def component_to_code(config): lt_options["LT_UART_SILENT_ENABLED"] = 0 lt_options["LT_UART_SILENT_ALL"] = 0 # set default UART port - if uart_port := framework.get(CONF_UART_PORT, None) is not None: + if (uart_port := framework.get(CONF_UART_PORT, None)) is not None: lt_options["LT_UART_DEFAULT_PORT"] = uart_port # add custom options lt_options.update(framework[CONF_OPTIONS]) From 33051906bd30e5e0c0a3b8201266b5245c6598b6 Mon Sep 17 00:00:00 2001 From: functionpointer Date: Tue, 9 Jan 2024 00:26:13 +0100 Subject: [PATCH 024/189] pylontech: Fix parsing error with US2000 (#6061) --- esphome/components/pylontech/__init__.py | 2 +- esphome/components/pylontech/pylontech.cpp | 57 +++++++++++++--------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/esphome/components/pylontech/__init__.py b/esphome/components/pylontech/__init__.py index 56fac92e89..197f7e7904 100644 --- a/esphome/components/pylontech/__init__.py +++ b/esphome/components/pylontech/__init__.py @@ -19,7 +19,7 @@ PylontechComponent = pylontech_ns.class_( ) PylontechBattery = pylontech_ns.class_("PylontechBattery") -CV_NUM_BATTERIES = cv.int_range(1, 6) +CV_NUM_BATTERIES = cv.int_range(1, 16) PYLONTECH_COMPONENT_SCHEMA = cv.Schema( { diff --git a/esphome/components/pylontech/pylontech.cpp b/esphome/components/pylontech/pylontech.cpp index 4bfa876110..b33f4d4874 100644 --- a/esphome/components/pylontech/pylontech.cpp +++ b/esphome/components/pylontech/pylontech.cpp @@ -1,5 +1,6 @@ #include "pylontech.h" #include "esphome/core/log.h" +#include "esphome/core/helpers.h" namespace esphome { namespace pylontech { @@ -34,26 +35,30 @@ void PylontechComponent::setup() { void PylontechComponent::update() { this->write_str("pwr\n"); } void PylontechComponent::loop() { - uint8_t data; - - // pylontech sends a lot of data very suddenly - // we need to quickly put it all into our own buffer, otherwise the uart's buffer will overflow - while (this->available() > 0) { - if (this->read_byte(&data)) { - buffer_[buffer_index_write_] += (char) data; - if (buffer_[buffer_index_write_].back() == static_cast(ASCII_LF) || - buffer_[buffer_index_write_].length() >= MAX_DATA_LENGTH_BYTES) { - // complete line received - buffer_index_write_ = (buffer_index_write_ + 1) % NUM_BUFFERS; + if (this->available() > 0) { + // pylontech sends a lot of data very suddenly + // we need to quickly put it all into our own buffer, otherwise the uart's buffer will overflow + uint8_t data; + int recv = 0; + while (this->available() > 0) { + if (this->read_byte(&data)) { + buffer_[buffer_index_write_] += (char) data; + recv++; + if (buffer_[buffer_index_write_].back() == static_cast(ASCII_LF) || + buffer_[buffer_index_write_].length() >= MAX_DATA_LENGTH_BYTES) { + // complete line received + buffer_index_write_ = (buffer_index_write_ + 1) % NUM_BUFFERS; + } } } - } - - // only process one line per call of loop() to not block esphome for too long - if (buffer_index_read_ != buffer_index_write_) { - this->process_line_(buffer_[buffer_index_read_]); - buffer_[buffer_index_read_].clear(); - buffer_index_read_ = (buffer_index_read_ + 1) % NUM_BUFFERS; + ESP_LOGV(TAG, "received %d bytes", recv); + } else { + // only process one line per call of loop() to not block esphome for too long + if (buffer_index_read_ != buffer_index_write_) { + this->process_line_(buffer_[buffer_index_read_]); + buffer_[buffer_index_read_].clear(); + buffer_index_read_ = (buffer_index_read_ + 1) % NUM_BUFFERS; + } } } @@ -66,10 +71,11 @@ void PylontechComponent::process_line_(std::string &buffer) { // clang-format on PylontechListener::LineContents l{}; - const int parsed = sscanf( // NOLINT - buffer.c_str(), "%d %d %d %d %d %d %d %d %7s %7s %7s %7s %d%% %*d-%*d-%*d %*d:%*d:%*d %*s %*s %d %*s", // NOLINT - &l.bat_num, &l.volt, &l.curr, &l.tempr, &l.tlow, &l.thigh, &l.vlow, &l.vhigh, l.base_st, l.volt_st, // NOLINT - l.curr_st, l.temp_st, &l.coulomb, &l.mostempr); // NOLINT + char mostempr_s[6]; + const int parsed = sscanf( // NOLINT + buffer.c_str(), "%d %d %d %d %d %d %d %d %7s %7s %7s %7s %d%% %*d-%*d-%*d %*d:%*d:%*d %*s %*s %5s %*s", // NOLINT + &l.bat_num, &l.volt, &l.curr, &l.tempr, &l.tlow, &l.thigh, &l.vlow, &l.vhigh, l.base_st, l.volt_st, // NOLINT + l.curr_st, l.temp_st, &l.coulomb, mostempr_s); // NOLINT if (l.bat_num <= 0) { ESP_LOGD(TAG, "invalid bat_num in line %s", buffer.substr(0, buffer.size() - 2).c_str()); @@ -79,6 +85,13 @@ void PylontechComponent::process_line_(std::string &buffer) { ESP_LOGW(TAG, "invalid line: found only %d items in %s", parsed, buffer.substr(0, buffer.size() - 2).c_str()); return; } + auto mostempr_parsed = parse_number(mostempr_s); + if (mostempr_parsed.has_value()) { + l.mostempr = mostempr_parsed.value(); + } else { + l.mostempr = -300; + ESP_LOGW(TAG, "bat_num %d: received no mostempr", l.bat_num); + } for (PylontechListener *listener : this->listeners_) { listener->on_line_read(&l); From 978a676c7c533cde18c66b8d17b6b73b1ed22d14 Mon Sep 17 00:00:00 2001 From: Robert Paskowitz Date: Mon, 8 Jan 2024 16:44:08 -0800 Subject: [PATCH 025/189] Support full (>460 char) dumps of Pronto IR commands (#6040) Co-authored-by: Rob Paskowitz --- .../remote_base/pronto_protocol.cpp | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/esphome/components/remote_base/pronto_protocol.cpp b/esphome/components/remote_base/pronto_protocol.cpp index 4b6977e1a2..ccae64449a 100644 --- a/esphome/components/remote_base/pronto_protocol.cpp +++ b/esphome/components/remote_base/pronto_protocol.cpp @@ -227,16 +227,17 @@ optional ProntoProtocol::decode(RemoteReceiveData src) { } void ProntoProtocol::dump(const ProntoData &data) { - std::string first, rest; - if (data.data.size() < 230) { - first = data.data; - } else { - first = data.data.substr(0, 229); - rest = data.data.substr(230); - } - ESP_LOGI(TAG, "Received Pronto: data=%s", first.c_str()); - if (!rest.empty()) { - ESP_LOGI(TAG, "%s", rest.c_str()); + std::string rest; + + rest = data.data; + ESP_LOGI(TAG, "Received Pronto: data="); + while (true) { + ESP_LOGI(TAG, "%s", rest.substr(0, 230).c_str()); + if (rest.size() > 230) { + rest = rest.substr(230); + } else { + break; + } } } From ff7de4c9719e00841f262edec594ac797cca7515 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Wed, 10 Jan 2024 17:05:34 -0600 Subject: [PATCH 026/189] ESP32-C3 USB_CDC fixes (#6069) --- esphome/components/logger/__init__.py | 9 ++++++--- esphome/components/logger/logger.cpp | 12 ++++-------- esphome/components/logger/logger.h | 5 +++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/esphome/components/logger/__init__.py b/esphome/components/logger/__init__.py index 6cad783db9..fd64c65c77 100644 --- a/esphome/components/logger/__init__.py +++ b/esphome/components/logger/__init__.py @@ -84,7 +84,7 @@ UART_SELECTION_ESP32 = { VARIANT_ESP32: [UART0, UART1, UART2], VARIANT_ESP32S2: [UART0, UART1, USB_CDC], VARIANT_ESP32S3: [UART0, UART1, USB_CDC, USB_SERIAL_JTAG], - VARIANT_ESP32C3: [UART0, UART1, USB_SERIAL_JTAG], + VARIANT_ESP32C3: [UART0, UART1, USB_CDC, USB_SERIAL_JTAG], VARIANT_ESP32C2: [UART0, UART1], VARIANT_ESP32C6: [UART0, UART1, USB_CDC, USB_SERIAL_JTAG], VARIANT_ESP32H2: [UART0, UART1, USB_CDC, USB_SERIAL_JTAG], @@ -172,9 +172,10 @@ CONFIG_SCHEMA = cv.All( esp8266=UART0, esp32=UART0, esp32_s2=USB_CDC, - esp32_s3_idf=USB_SERIAL_JTAG, - esp32_c3_idf=USB_SERIAL_JTAG, esp32_s3_arduino=USB_CDC, + esp32_s3_idf=USB_SERIAL_JTAG, + esp32_c3_arduino=USB_CDC, + esp32_c3_idf=USB_SERIAL_JTAG, rp2040=USB_CDC, bk72xx=DEFAULT, rtl87xx=DEFAULT, @@ -265,6 +266,8 @@ async def to_code(config): if CORE.using_arduino: if config[CONF_HARDWARE_UART] == USB_CDC: cg.add_build_flag("-DARDUINO_USB_CDC_ON_BOOT=1") + if CORE.is_esp32 and get_esp32_variant() == VARIANT_ESP32C3: + cg.add_build_flag("-DARDUINO_USB_MODE=1") if CORE.using_esp_idf: if config[CONF_HARDWARE_UART] == USB_CDC: diff --git a/esphome/components/logger/logger.cpp b/esphome/components/logger/logger.cpp index e0f7e77d2c..d5f5c275eb 100644 --- a/esphome/components/logger/logger.cpp +++ b/esphome/components/logger/logger.cpp @@ -272,17 +272,13 @@ void Logger::pre_setup() { #endif #if defined(USE_ESP32) && \ (defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C3)) -#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) +#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C3) case UART_SELECTION_USB_CDC: -#endif // USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3 +#endif // USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32C3 #if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S3) case UART_SELECTION_USB_SERIAL_JTAG: #endif // USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32S3 -#ifdef USE_ESP32_VARIANT_ESP32C3 - this->hw_serial_ = &Serial; - Serial.begin(this->baud_rate_); -#endif // USE_ESP32_VARIANT_ESP32C3 -#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) +#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C3) #if ARDUINO_USB_CDC_ON_BOOT this->hw_serial_ = &Serial; Serial.setTxTimeoutMs(0); // workaround for 2.0.9 crash when there's no data connection @@ -291,7 +287,7 @@ void Logger::pre_setup() { this->hw_serial_ = &Serial; Serial.begin(this->baud_rate_); #endif // ARDUINO_USB_CDC_ON_BOOT -#endif // USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3 +#endif // USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32C3 break; #endif // USE_ESP32 && (USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32C3) #ifdef USE_RP2040 diff --git a/esphome/components/logger/logger.h b/esphome/components/logger/logger.h index 68efc056df..c7f0fe4139 100644 --- a/esphome/components/logger/logger.h +++ b/esphome/components/logger/logger.h @@ -45,9 +45,10 @@ enum UARTSelection { UART_SELECTION_UART2, #endif // !USE_ESP32_VARIANT_ESP32C3 && !USE_ESP32_VARIANT_ESP32C6 && !USE_ESP32_VARIANT_ESP32S2 && // !USE_ESP32_VARIANT_ESP32S3 && !USE_ESP32_VARIANT_ESP32H2 -#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) +#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || \ + (defined(USE_ESP32_VARIANT_ESP32C3) && defined(USE_ARDUINO)) UART_SELECTION_USB_CDC, -#endif // USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3 +#endif // USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3 || USE_ESP32_VARIANT_ESP32C3 #if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32S3) || \ defined(USE_ESP32_VARIANT_ESP32H2) UART_SELECTION_USB_SERIAL_JTAG, From 59e7c523413e4aa7ee5245f4a4ec74074e416b50 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Sat, 13 Jan 2024 02:21:28 -0600 Subject: [PATCH 027/189] Improv Serial -- don't wait for incoming bytes (#6089) --- esphome/components/improv_serial/improv_serial_component.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/improv_serial/improv_serial_component.cpp b/esphome/components/improv_serial/improv_serial_component.cpp index 600069b781..2318fd43cb 100644 --- a/esphome/components/improv_serial/improv_serial_component.cpp +++ b/esphome/components/improv_serial/improv_serial_component.cpp @@ -52,7 +52,7 @@ optional ImprovSerialComponent::read_byte_() { size_t available; uart_get_buffered_data_len(this->uart_num_, &available); if (available) { - uart_read_bytes(this->uart_num_, &data, 1, 20 / portTICK_PERIOD_MS); + uart_read_bytes(this->uart_num_, &data, 1, 0); byte = data; } } @@ -71,7 +71,7 @@ optional ImprovSerialComponent::read_byte_() { #endif // USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3 #if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32S3) case logger::UART_SELECTION_USB_SERIAL_JTAG: { - if (usb_serial_jtag_read_bytes((char *) &data, 1, 20 / portTICK_PERIOD_MS)) { + if (usb_serial_jtag_read_bytes((char *) &data, 1, 0)) { byte = data; } break; From b8b64628442a46c0a29c3b7b7f41d6da13775b0e Mon Sep 17 00:00:00 2001 From: tomaszduda23 Date: Mon, 15 Jan 2024 00:01:20 +0100 Subject: [PATCH 028/189] add STATE_CLASS_TOTAL_INCREASING to bl0940 and bl0942 (#6090) --- esphome/components/bl0940/sensor.py | 2 ++ esphome/components/bl0942/sensor.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/esphome/components/bl0940/sensor.py b/esphome/components/bl0940/sensor.py index 702230e020..a197becef8 100644 --- a/esphome/components/bl0940/sensor.py +++ b/esphome/components/bl0940/sensor.py @@ -18,6 +18,7 @@ from esphome.const import ( UNIT_KILOWATT_HOURS, UNIT_VOLT, UNIT_WATT, + STATE_CLASS_TOTAL_INCREASING, ) DEPENDENCIES = ["uart"] @@ -54,6 +55,7 @@ CONFIG_SCHEMA = ( unit_of_measurement=UNIT_KILOWATT_HOURS, accuracy_decimals=0, device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, ), cv.Optional(CONF_INTERNAL_TEMPERATURE): sensor.sensor_schema( unit_of_measurement=UNIT_CELSIUS, diff --git a/esphome/components/bl0942/sensor.py b/esphome/components/bl0942/sensor.py index 663eea0c4d..9612df6d4c 100644 --- a/esphome/components/bl0942/sensor.py +++ b/esphome/components/bl0942/sensor.py @@ -19,6 +19,7 @@ from esphome.const import ( UNIT_VOLT, UNIT_WATT, UNIT_HERTZ, + STATE_CLASS_TOTAL_INCREASING, ) DEPENDENCIES = ["uart"] @@ -52,6 +53,7 @@ CONFIG_SCHEMA = ( unit_of_measurement=UNIT_KILOWATT_HOURS, accuracy_decimals=0, device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, ), cv.Optional(CONF_FREQUENCY): sensor.sensor_schema( unit_of_measurement=UNIT_HERTZ, From 3fec8f9b538c1c0c78c8a0d110bf5eb8e9873f4f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 14 Jan 2024 13:06:13 -1000 Subject: [PATCH 029/189] Fallback to pure-python loader for better error when YAML loading fails (#6081) --- esphome/yaml_util.py | 113 ++++++++++-------- .../yaml_util/broken_includetest.yaml | 18 +++ .../includes/broken_included.yaml.txt | 5 + tests/unit_tests/test_yaml_util.py | 11 ++ 4 files changed, 98 insertions(+), 49 deletions(-) create mode 100644 tests/unit_tests/fixtures/yaml_util/broken_includetest.yaml create mode 100644 tests/unit_tests/fixtures/yaml_util/includes/broken_included.yaml.txt diff --git a/esphome/yaml_util.py b/esphome/yaml_util.py index f0f755dd61..ef9feaab2e 100644 --- a/esphome/yaml_util.py +++ b/esphome/yaml_util.py @@ -1,36 +1,37 @@ +from __future__ import annotations + import fnmatch import functools import inspect import logging import math import os - import uuid +from typing import Any + import yaml import yaml.constructor +from yaml import SafeLoader as PurePythonLoader + +try: + from yaml import CSafeLoader as FastestAvailableSafeLoader +except ImportError: + FastestAvailableSafeLoader = PurePythonLoader from esphome import core -from esphome.config_helpers import read_config_file, Extend, Remove +from esphome.config_helpers import Extend, Remove, read_config_file from esphome.core import ( + CORE, + DocumentRange, EsphomeError, IPAddress, Lambda, MACAddress, TimePeriod, - DocumentRange, - CORE, ) from esphome.helpers import add_class_to_obj from esphome.util import OrderedDict, filter_yaml_files -try: - from yaml import CSafeLoader as FastestAvailableSafeLoader -except ImportError: - from yaml import ( # type: ignore[assignment] - SafeLoader as FastestAvailableSafeLoader, - ) - - _LOGGER = logging.getLogger(__name__) # Mostly copied from Home Assistant because that code works fine and @@ -97,7 +98,7 @@ def _add_data_ref(fn): return wrapped -class ESPHomeLoader(FastestAvailableSafeLoader): +class ESPHomeLoaderMixin: """Loader class that keeps track of line numbers.""" @_add_data_ref @@ -282,8 +283,8 @@ class ESPHomeLoader(FastestAvailableSafeLoader): return file, vars def substitute_vars(config, vars): - from esphome.const import CONF_SUBSTITUTIONS from esphome.components import substitutions + from esphome.const import CONF_SUBSTITUTIONS org_subs = None result = config @@ -367,50 +368,64 @@ class ESPHomeLoader(FastestAvailableSafeLoader): return Remove(str(node.value)) -ESPHomeLoader.add_constructor("tag:yaml.org,2002:int", ESPHomeLoader.construct_yaml_int) -ESPHomeLoader.add_constructor( - "tag:yaml.org,2002:float", ESPHomeLoader.construct_yaml_float -) -ESPHomeLoader.add_constructor( - "tag:yaml.org,2002:binary", ESPHomeLoader.construct_yaml_binary -) -ESPHomeLoader.add_constructor( - "tag:yaml.org,2002:omap", ESPHomeLoader.construct_yaml_omap -) -ESPHomeLoader.add_constructor("tag:yaml.org,2002:str", ESPHomeLoader.construct_yaml_str) -ESPHomeLoader.add_constructor("tag:yaml.org,2002:seq", ESPHomeLoader.construct_yaml_seq) -ESPHomeLoader.add_constructor("tag:yaml.org,2002:map", ESPHomeLoader.construct_yaml_map) -ESPHomeLoader.add_constructor("!env_var", ESPHomeLoader.construct_env_var) -ESPHomeLoader.add_constructor("!secret", ESPHomeLoader.construct_secret) -ESPHomeLoader.add_constructor("!include", ESPHomeLoader.construct_include) -ESPHomeLoader.add_constructor( - "!include_dir_list", ESPHomeLoader.construct_include_dir_list -) -ESPHomeLoader.add_constructor( - "!include_dir_merge_list", ESPHomeLoader.construct_include_dir_merge_list -) -ESPHomeLoader.add_constructor( - "!include_dir_named", ESPHomeLoader.construct_include_dir_named -) -ESPHomeLoader.add_constructor( - "!include_dir_merge_named", ESPHomeLoader.construct_include_dir_merge_named -) -ESPHomeLoader.add_constructor("!lambda", ESPHomeLoader.construct_lambda) -ESPHomeLoader.add_constructor("!force", ESPHomeLoader.construct_force) -ESPHomeLoader.add_constructor("!extend", ESPHomeLoader.construct_extend) -ESPHomeLoader.add_constructor("!remove", ESPHomeLoader.construct_remove) +class ESPHomeLoader(ESPHomeLoaderMixin, FastestAvailableSafeLoader): + """Loader class that keeps track of line numbers.""" -def load_yaml(fname, clear_secrets=True): +class ESPHomePurePythonLoader(ESPHomeLoaderMixin, PurePythonLoader): + """Loader class that keeps track of line numbers.""" + + +for _loader in (ESPHomeLoader, ESPHomePurePythonLoader): + _loader.add_constructor("tag:yaml.org,2002:int", _loader.construct_yaml_int) + _loader.add_constructor("tag:yaml.org,2002:float", _loader.construct_yaml_float) + _loader.add_constructor("tag:yaml.org,2002:binary", _loader.construct_yaml_binary) + _loader.add_constructor("tag:yaml.org,2002:omap", _loader.construct_yaml_omap) + _loader.add_constructor("tag:yaml.org,2002:str", _loader.construct_yaml_str) + _loader.add_constructor("tag:yaml.org,2002:seq", _loader.construct_yaml_seq) + _loader.add_constructor("tag:yaml.org,2002:map", _loader.construct_yaml_map) + _loader.add_constructor("!env_var", _loader.construct_env_var) + _loader.add_constructor("!secret", _loader.construct_secret) + _loader.add_constructor("!include", _loader.construct_include) + _loader.add_constructor("!include_dir_list", _loader.construct_include_dir_list) + _loader.add_constructor( + "!include_dir_merge_list", _loader.construct_include_dir_merge_list + ) + _loader.add_constructor("!include_dir_named", _loader.construct_include_dir_named) + _loader.add_constructor( + "!include_dir_merge_named", _loader.construct_include_dir_merge_named + ) + _loader.add_constructor("!lambda", _loader.construct_lambda) + _loader.add_constructor("!force", _loader.construct_force) + _loader.add_constructor("!extend", _loader.construct_extend) + _loader.add_constructor("!remove", _loader.construct_remove) + + +def load_yaml(fname: str, clear_secrets: bool = True) -> Any: if clear_secrets: _SECRET_VALUES.clear() _SECRET_CACHE.clear() return _load_yaml_internal(fname) -def _load_yaml_internal(fname): +def _load_yaml_internal(fname: str) -> Any: + """Load a YAML file.""" content = read_config_file(fname) - loader = ESPHomeLoader(content) + try: + return _load_yaml_internal_with_type(ESPHomeLoader, fname, content) + except EsphomeError: + # Loading failed, so we now load with the Python loader which has more + # readable exceptions + return _load_yaml_internal_with_type(ESPHomePurePythonLoader, fname, content) + + +def _load_yaml_internal_with_type( + loader_type: type[ESPHomeLoader] | type[ESPHomePurePythonLoader], + fname: str, + content: str, +) -> Any: + """Load a YAML file.""" + loader = loader_type(content) loader.name = fname try: return loader.get_single_data() or OrderedDict() diff --git a/tests/unit_tests/fixtures/yaml_util/broken_includetest.yaml b/tests/unit_tests/fixtures/yaml_util/broken_includetest.yaml new file mode 100644 index 0000000000..aaca55b807 --- /dev/null +++ b/tests/unit_tests/fixtures/yaml_util/broken_includetest.yaml @@ -0,0 +1,18 @@ +--- +substitutions: + name: original + +wifi: !include + file: includes/broken_included.yaml.txt + vars: + name: my_custom_ssid + +esphome: + # should be substituted as 'original', + # not overwritten by vars in the !include above + name: ${name} + name_add_mac_suffix: true + platform: esp8266 + board: !include {file: includes/scalar.yaml, vars: {var1: nodemcu}} + + libraries: !include {file: includes/list.yaml, vars: {var1: Wire}} diff --git a/tests/unit_tests/fixtures/yaml_util/includes/broken_included.yaml.txt b/tests/unit_tests/fixtures/yaml_util/includes/broken_included.yaml.txt new file mode 100644 index 0000000000..6e53395c86 --- /dev/null +++ b/tests/unit_tests/fixtures/yaml_util/includes/broken_included.yaml.txt @@ -0,0 +1,5 @@ +--- +# yamllint disable-line + ssid: ${name} +# yamllint disable-line + fdf: error diff --git a/tests/unit_tests/test_yaml_util.py b/tests/unit_tests/test_yaml_util.py index 8ee991f5b3..78b6a2ad84 100644 --- a/tests/unit_tests/test_yaml_util.py +++ b/tests/unit_tests/test_yaml_util.py @@ -1,5 +1,6 @@ from esphome import yaml_util from esphome.components import substitutions +from esphome.core import EsphomeError def test_include_with_vars(fixture_path): @@ -11,3 +12,13 @@ def test_include_with_vars(fixture_path): assert actual["esphome"]["libraries"][0] == "Wire" assert actual["esphome"]["board"] == "nodemcu" assert actual["wifi"]["ssid"] == "my_custom_ssid" + + +def test_loading_a_broken_yaml_file(fixture_path): + """Ensure we fallback to pure python to give good errors.""" + yaml_file = fixture_path / "yaml_util" / "broken_includetest.yaml" + + try: + yaml_util.load_yaml(yaml_file) + except EsphomeError as err: + assert "broken_included.yaml" in str(err) From 534c14e3132225397e87fa449f9657be4d027b0d Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Mon, 15 Jan 2024 08:25:48 +0900 Subject: [PATCH 030/189] Bump version to 2023.12.6 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index d762b0aa71..6db8fd5a2c 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2023.12.5" +__version__ = "2023.12.6" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From f37a812e5994f318e1d6ce4e66aa83c10d40bae3 Mon Sep 17 00:00:00 2001 From: Piotr Majkrzak Date: Tue, 16 Jan 2024 09:10:44 +0100 Subject: [PATCH 031/189] Fix RMT timing clock base (#6101) --- esphome/components/esp32_rmt_led_strip/led_strip.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/esphome/components/esp32_rmt_led_strip/led_strip.cpp b/esphome/components/esp32_rmt_led_strip/led_strip.cpp index df6ee2ce2f..3df4077c96 100644 --- a/esphome/components/esp32_rmt_led_strip/led_strip.cpp +++ b/esphome/components/esp32_rmt_led_strip/led_strip.cpp @@ -13,6 +13,8 @@ namespace esp32_rmt_led_strip { static const char *const TAG = "esp32_rmt_led_strip"; +static const uint32_t RMT_CLK_FREQ = 80000000; + static const uint8_t RMT_CLK_DIV = 2; void ESP32RMTLEDStripLightOutput::setup() { @@ -65,7 +67,7 @@ void ESP32RMTLEDStripLightOutput::setup() { void ESP32RMTLEDStripLightOutput::set_led_params(uint32_t bit0_high, uint32_t bit0_low, uint32_t bit1_high, uint32_t bit1_low) { - float ratio = (float) APB_CLK_FREQ / RMT_CLK_DIV / 1e09f; + float ratio = (float) RMT_CLK_FREQ / RMT_CLK_DIV / 1e09f; // 0-bit this->bit0_.duration0 = (uint32_t) (ratio * bit0_high); From 86c9546362aa4aee6c17c9a12d143ded7fa57863 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Tue, 16 Jan 2024 21:37:57 +1300 Subject: [PATCH 032/189] Create RingBuffer for VoiceAssistant (#6102) --- .../voice_assistant/voice_assistant.cpp | 32 ++++-------- .../voice_assistant/voice_assistant.h | 4 +- esphome/core/ring_buffer.cpp | 49 +++++++++++++++++++ esphome/core/ring_buffer.h | 34 +++++++++++++ 4 files changed, 95 insertions(+), 24 deletions(-) create mode 100644 esphome/core/ring_buffer.cpp create mode 100644 esphome/core/ring_buffer.h diff --git a/esphome/components/voice_assistant/voice_assistant.cpp b/esphome/components/voice_assistant/voice_assistant.cpp index 29fc664342..299e624f5f 100644 --- a/esphome/components/voice_assistant/voice_assistant.cpp +++ b/esphome/components/voice_assistant/voice_assistant.cpp @@ -86,14 +86,14 @@ void VoiceAssistant::setup() { #ifdef USE_ESP_ADF this->vad_instance_ = vad_create(VAD_MODE_4); +#endif - this->ring_buffer_ = rb_create(BUFFER_SIZE, sizeof(int16_t)); + this->ring_buffer_ = RingBuffer::create(BUFFER_SIZE * sizeof(int16_t)); if (this->ring_buffer_ == nullptr) { ESP_LOGW(TAG, "Could not allocate ring buffer"); this->mark_failed(); return; } -#endif ExternalRAMAllocator send_allocator(ExternalRAMAllocator::ALLOW_FAILURE); this->send_buffer_ = send_allocator.allocate(SEND_BUFFER_SIZE); @@ -112,14 +112,8 @@ int VoiceAssistant::read_microphone_() { memset(this->input_buffer_, 0, INPUT_BUFFER_SIZE * sizeof(int16_t)); return 0; } -#ifdef USE_ESP_ADF // Write audio into ring buffer - int available = rb_bytes_available(this->ring_buffer_); - if (available < bytes_read) { - rb_read(this->ring_buffer_, nullptr, bytes_read - available, 0); - } - rb_write(this->ring_buffer_, (char *) this->input_buffer_, bytes_read, 0); -#endif + this->ring_buffer_->write((void *) this->input_buffer_, bytes_read); } else { ESP_LOGD(TAG, "microphone not running"); } @@ -141,9 +135,9 @@ void VoiceAssistant::loop() { switch (this->state_) { case State::IDLE: { if (this->continuous_ && this->desired_state_ == State::IDLE) { + this->ring_buffer_->reset(); #ifdef USE_ESP_ADF if (this->use_wake_word_) { - rb_reset(this->ring_buffer_); this->set_state_(State::START_MICROPHONE, State::WAIT_FOR_VAD); } else #endif @@ -236,19 +230,13 @@ void VoiceAssistant::loop() { break; // State changed when udp server port received } case State::STREAMING_MICROPHONE: { - size_t bytes_read = this->read_microphone_(); -#ifdef USE_ESP_ADF - if (rb_bytes_filled(this->ring_buffer_) >= SEND_BUFFER_SIZE) { - rb_read(this->ring_buffer_, (char *) this->send_buffer_, SEND_BUFFER_SIZE, 0); + this->read_microphone_(); + if (this->ring_buffer_->available() >= SEND_BUFFER_SIZE) { + this->ring_buffer_->read((void *) this->send_buffer_, SEND_BUFFER_SIZE, 0); this->socket_->sendto(this->send_buffer_, SEND_BUFFER_SIZE, 0, (struct sockaddr *) &this->dest_addr_, sizeof(this->dest_addr_)); } -#else - if (bytes_read > 0) { - this->socket_->sendto(this->input_buffer_, bytes_read, 0, (struct sockaddr *) &this->dest_addr_, - sizeof(this->dest_addr_)); - } -#endif + break; } case State::STOP_MICROPHONE: { @@ -473,9 +461,9 @@ void VoiceAssistant::request_start(bool continuous, bool silence_detection) { if (this->state_ == State::IDLE) { this->continuous_ = continuous; this->silence_detection_ = silence_detection; + this->ring_buffer_->reset(); #ifdef USE_ESP_ADF if (this->use_wake_word_) { - rb_reset(this->ring_buffer_); this->set_state_(State::START_MICROPHONE, State::WAIT_FOR_VAD); } else #endif @@ -618,9 +606,9 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) { case api::enums::VOICE_ASSISTANT_RUN_END: { ESP_LOGD(TAG, "Assist Pipeline ended"); if (this->state_ == State::STREAMING_MICROPHONE) { + this->ring_buffer_->reset(); #ifdef USE_ESP_ADF if (this->use_wake_word_) { - rb_reset(this->ring_buffer_); // No need to stop the microphone since we didn't use the speaker this->set_state_(State::WAIT_FOR_VAD, State::WAITING_FOR_VAD); } else diff --git a/esphome/components/voice_assistant/voice_assistant.h b/esphome/components/voice_assistant/voice_assistant.h index f9325dff54..d996efe08e 100644 --- a/esphome/components/voice_assistant/voice_assistant.h +++ b/esphome/components/voice_assistant/voice_assistant.h @@ -7,6 +7,7 @@ #include "esphome/core/automation.h" #include "esphome/core/component.h" #include "esphome/core/helpers.h" +#include "esphome/core/ring_buffer.h" #include "esphome/components/api/api_connection.h" #include "esphome/components/api/api_pb2.h" @@ -21,7 +22,6 @@ #ifdef USE_ESP_ADF #include -#include #endif namespace esphome { @@ -177,10 +177,10 @@ class VoiceAssistant : public Component { #ifdef USE_ESP_ADF vad_handle_t vad_instance_; - ringbuf_handle_t ring_buffer_; uint8_t vad_threshold_{5}; uint8_t vad_counter_{0}; #endif + std::unique_ptr ring_buffer_; bool use_wake_word_; uint8_t noise_suppression_level_; diff --git a/esphome/core/ring_buffer.cpp b/esphome/core/ring_buffer.cpp new file mode 100644 index 0000000000..d9c56d84c5 --- /dev/null +++ b/esphome/core/ring_buffer.cpp @@ -0,0 +1,49 @@ +#include "ring_buffer.h" + +#include "esphome/core/helpers.h" +#include "esphome/core/log.h" + +#ifdef USE_ESP32 + +#include "helpers.h" + +namespace esphome { + +static const char *const TAG = "ring_buffer"; + +std::unique_ptr RingBuffer::create(size_t len) { + std::unique_ptr rb = make_unique(); + + ExternalRAMAllocator allocator(ExternalRAMAllocator::ALLOW_FAILURE); + rb->storage_ = allocator.allocate(len); + if (rb->storage_ == nullptr) { + return nullptr; + } + + rb->handle_ = xStreamBufferCreateStatic(len, 0, rb->storage_, &rb->structure_); + return rb; +} + +size_t RingBuffer::read(void *data, size_t size, TickType_t ticks_to_wait) { + return xStreamBufferReceive(this->handle_, data, size, ticks_to_wait); +} + +size_t RingBuffer::write(void *data, size_t len) { + size_t free = this->free(); + if (free < len) { + size_t needed = len - free; + uint8_t discard[needed]; + xStreamBufferReceive(this->handle_, discard, needed, 0); + } + return xStreamBufferSend(this->handle_, data, len, 0); +} + +size_t RingBuffer::available() const { return xStreamBufferBytesAvailable(this->handle_); } + +size_t RingBuffer::free() const { return xStreamBufferSpacesAvailable(this->handle_); } + +BaseType_t RingBuffer::reset() { return xStreamBufferReset(this->handle_); } + +} // namespace esphome + +#endif diff --git a/esphome/core/ring_buffer.h b/esphome/core/ring_buffer.h new file mode 100644 index 0000000000..6c6d04117a --- /dev/null +++ b/esphome/core/ring_buffer.h @@ -0,0 +1,34 @@ +#pragma once + +#ifdef USE_ESP32 + +#include +#include + +#include +#include + +namespace esphome { + +class RingBuffer { + public: + size_t read(void *data, size_t size, TickType_t ticks_to_wait = 0); + + size_t write(void *data, size_t len); + + size_t available() const; + size_t free() const; + + BaseType_t reset(); + + static std::unique_ptr create(size_t len); + + protected: + StreamBufferHandle_t handle_; + StaticStreamBuffer_t structure_; + uint8_t *storage_; +}; + +} // namespace esphome + +#endif From 95292dbba1e79db85969fc105e31e7b72015bb1c Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Wed, 17 Jan 2024 10:23:36 +1100 Subject: [PATCH 033/189] Inkplate6: Fix crash with initial set of greyscale (#6038) --- esphome/components/inkplate6/inkplate.cpp | 3 +++ esphome/components/inkplate6/inkplate.h | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/esphome/components/inkplate6/inkplate.cpp b/esphome/components/inkplate6/inkplate.cpp index 92a226de87..f4d0fedf83 100644 --- a/esphome/components/inkplate6/inkplate.cpp +++ b/esphome/components/inkplate6/inkplate.cpp @@ -55,6 +55,9 @@ void Inkplate6::setup() { this->wakeup_pin_->digital_write(false); } +/** + * Allocate buffers. May be called after setup to re-initialise if e.g. greyscale is changed. + */ void Inkplate6::initialize_() { ExternalRAMAllocator allocator(ExternalRAMAllocator::ALLOW_FAILURE); ExternalRAMAllocator allocator32(ExternalRAMAllocator::ALLOW_FAILURE); diff --git a/esphome/components/inkplate6/inkplate.h b/esphome/components/inkplate6/inkplate.h index 307d9671e6..2946c89e1c 100644 --- a/esphome/components/inkplate6/inkplate.h +++ b/esphome/components/inkplate6/inkplate.h @@ -68,8 +68,9 @@ class Inkplate6 : public display::DisplayBuffer, public i2c::I2CDevice { void set_greyscale(bool greyscale) { this->greyscale_ = greyscale; - this->initialize_(); this->block_partial_ = true; + if (this->is_ready()) + this->initialize_(); } void set_partial_updating(bool partial_updating) { this->partial_updating_ = partial_updating; } void set_full_update_every(uint32_t full_update_every) { this->full_update_every_ = full_update_every; } From 36de6440656a2487de418d12330c7776783171a1 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 17 Jan 2024 08:27:03 +0900 Subject: [PATCH 034/189] Bump version to 2023.12.7 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 6db8fd5a2c..34a28fb400 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2023.12.6" +__version__ = "2023.12.7" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From bd7fe1227c442dfdeaf745682ddb39c3b071dc97 Mon Sep 17 00:00:00 2001 From: guillempages Date: Sat, 13 Jan 2024 22:01:32 +0100 Subject: [PATCH 035/189] Let show_*_page actions depend on "Display" (#6092) Instead of forcing a DisplayBuffer, let the display page actions use Displays without buffer. --- esphome/components/display/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/display/__init__.py b/esphome/components/display/__init__.py index 91f10c5458..992799008a 100644 --- a/esphome/components/display/__init__.py +++ b/esphome/components/display/__init__.py @@ -145,7 +145,7 @@ async def display_page_show_to_code(config, action_id, template_arg, args): DisplayPageShowNextAction, maybe_simple_id( { - cv.Required(CONF_ID): cv.templatable(cv.use_id(DisplayBuffer)), + cv.Required(CONF_ID): cv.templatable(cv.use_id(Display)), } ), ) @@ -159,7 +159,7 @@ async def display_page_show_next_to_code(config, action_id, template_arg, args): DisplayPageShowPrevAction, maybe_simple_id( { - cv.Required(CONF_ID): cv.templatable(cv.use_id(DisplayBuffer)), + cv.Required(CONF_ID): cv.templatable(cv.use_id(Display)), } ), ) @@ -173,7 +173,7 @@ async def display_page_show_previous_to_code(config, action_id, template_arg, ar DisplayIsDisplayingPageCondition, cv.maybe_simple_value( { - cv.GenerateID(CONF_ID): cv.use_id(DisplayBuffer), + cv.GenerateID(CONF_ID): cv.use_id(Display), cv.Required(CONF_PAGE_ID): cv.use_id(DisplayPage), }, key=CONF_PAGE_ID, From d5fe5b089974f22419939bdb418faee2d3fa890b Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Sat, 20 Jan 2024 03:38:37 +1300 Subject: [PATCH 036/189] Fix some Voice Assistant bugs (#6121) --- esphome/components/voice_assistant/voice_assistant.cpp | 10 ++++++---- esphome/core/ring_buffer.cpp | 9 +++++---- esphome/core/ring_buffer.h | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/esphome/components/voice_assistant/voice_assistant.cpp b/esphome/components/voice_assistant/voice_assistant.cpp index 299e624f5f..9094b93c02 100644 --- a/esphome/components/voice_assistant/voice_assistant.cpp +++ b/esphome/components/voice_assistant/voice_assistant.cpp @@ -17,7 +17,7 @@ static const char *const TAG = "voice_assistant"; static const size_t SAMPLE_RATE_HZ = 16000; static const size_t INPUT_BUFFER_SIZE = 32 * SAMPLE_RATE_HZ / 1000; // 32ms * 16kHz / 1000ms -static const size_t BUFFER_SIZE = 1000 * SAMPLE_RATE_HZ / 1000; // 1s +static const size_t BUFFER_SIZE = 1024 * SAMPLE_RATE_HZ / 1000; static const size_t SEND_BUFFER_SIZE = INPUT_BUFFER_SIZE * sizeof(int16_t); static const size_t RECEIVE_SIZE = 1024; static const size_t SPEAKER_BUFFER_SIZE = 16 * RECEIVE_SIZE; @@ -231,10 +231,12 @@ void VoiceAssistant::loop() { } case State::STREAMING_MICROPHONE: { this->read_microphone_(); - if (this->ring_buffer_->available() >= SEND_BUFFER_SIZE) { - this->ring_buffer_->read((void *) this->send_buffer_, SEND_BUFFER_SIZE, 0); - this->socket_->sendto(this->send_buffer_, SEND_BUFFER_SIZE, 0, (struct sockaddr *) &this->dest_addr_, + size_t available = this->ring_buffer_->available(); + while (available >= SEND_BUFFER_SIZE) { + size_t read_bytes = this->ring_buffer_->read((void *) this->send_buffer_, SEND_BUFFER_SIZE, 0); + this->socket_->sendto(this->send_buffer_, read_bytes, 0, (struct sockaddr *) &this->dest_addr_, sizeof(this->dest_addr_)); + available = this->ring_buffer_->available(); } break; diff --git a/esphome/core/ring_buffer.cpp b/esphome/core/ring_buffer.cpp index d9c56d84c5..9bd3d9d853 100644 --- a/esphome/core/ring_buffer.cpp +++ b/esphome/core/ring_buffer.cpp @@ -15,17 +15,18 @@ std::unique_ptr RingBuffer::create(size_t len) { std::unique_ptr rb = make_unique(); ExternalRAMAllocator allocator(ExternalRAMAllocator::ALLOW_FAILURE); - rb->storage_ = allocator.allocate(len); + rb->storage_ = allocator.allocate(len + 1); if (rb->storage_ == nullptr) { return nullptr; } - rb->handle_ = xStreamBufferCreateStatic(len, 0, rb->storage_, &rb->structure_); + rb->handle_ = xStreamBufferCreateStatic(len + 1, 0, rb->storage_, &rb->structure_); + ESP_LOGD(TAG, "Created ring buffer with size %u", len); return rb; } -size_t RingBuffer::read(void *data, size_t size, TickType_t ticks_to_wait) { - return xStreamBufferReceive(this->handle_, data, size, ticks_to_wait); +size_t RingBuffer::read(void *data, size_t len, TickType_t ticks_to_wait) { + return xStreamBufferReceive(this->handle_, data, len, ticks_to_wait); } size_t RingBuffer::write(void *data, size_t len) { diff --git a/esphome/core/ring_buffer.h b/esphome/core/ring_buffer.h index 6c6d04117a..e602068844 100644 --- a/esphome/core/ring_buffer.h +++ b/esphome/core/ring_buffer.h @@ -12,7 +12,7 @@ namespace esphome { class RingBuffer { public: - size_t read(void *data, size_t size, TickType_t ticks_to_wait = 0); + size_t read(void *data, size_t len, TickType_t ticks_to_wait = 0); size_t write(void *data, size_t len); From aee702f84fbee28a9dcb1d9b75aed8238c630799 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Fri, 19 Jan 2024 23:40:26 +0900 Subject: [PATCH 037/189] Bump version to 2023.12.8 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 34a28fb400..3b31a17c3e 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2023.12.7" +__version__ = "2023.12.8" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From a6f864a4a3525e472264ffd1269a8bbb3ff47704 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Fri, 12 Jan 2024 01:11:42 -0800 Subject: [PATCH 038/189] fix sen5x negative temperature (#6082) --- esphome/components/sen5x/sen5x.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/sen5x/sen5x.cpp b/esphome/components/sen5x/sen5x.cpp index c90880bc9f..0efc961943 100644 --- a/esphome/components/sen5x/sen5x.cpp +++ b/esphome/components/sen5x/sen5x.cpp @@ -352,7 +352,7 @@ void SEN5XComponent::update() { float humidity = measurements[4] / 100.0; if (measurements[4] == 0xFFFF) humidity = NAN; - float temperature = measurements[5] / 200.0; + float temperature = (int16_t) measurements[5] / 200.0; if (measurements[5] == 0xFFFF) temperature = NAN; float voc = measurements[6] / 10.0; From 2cda6462f3a236f54f307980ccbc9773f30ad0e9 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Fri, 12 Jan 2024 01:20:08 -0800 Subject: [PATCH 039/189] negative values for all DHT22 variants (#6074) Co-authored-by: Samuel Sieb --- esphome/components/dht/dht.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/esphome/components/dht/dht.cpp b/esphome/components/dht/dht.cpp index c70b227330..07634cafdf 100644 --- a/esphome/components/dht/dht.cpp +++ b/esphome/components/dht/dht.cpp @@ -217,8 +217,12 @@ bool HOT IRAM_ATTR DHT::read_sensor_(float *temperature, float *humidity, bool r uint16_t raw_humidity = (uint16_t(data[0] & 0xFF) << 8) | (data[1] & 0xFF); uint16_t raw_temperature = (uint16_t(data[2] & 0xFF) << 8) | (data[3] & 0xFF); - if (this->model_ != DHT_MODEL_DHT22_TYPE2 && (raw_temperature & 0x8000) != 0) - raw_temperature = ~(raw_temperature & 0x7FFF); + if (raw_temperature & 0x8000) { + if (!(raw_temperature & 0x4000)) + raw_temperature = ~(raw_temperature & 0x7FFF); + } else if (raw_temperature & 0x800) { + raw_temperature |= 0xf000; + } if (raw_temperature == 1 && raw_humidity == 10) { if (report_errors) { From 354314dbf3ab9963bfdd0f09891abe37732b5c1e Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Fri, 12 Jan 2024 01:47:50 -0800 Subject: [PATCH 040/189] fix negative temperature for pmsx003 (#6083) * fix negative temperature for pmsx003 * Update esphome/components/pmsx003/pmsx003.cpp --- esphome/components/pmsx003/pmsx003.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/pmsx003/pmsx003.cpp b/esphome/components/pmsx003/pmsx003.cpp index 04aba4382b..62488b765c 100644 --- a/esphome/components/pmsx003/pmsx003.cpp +++ b/esphome/components/pmsx003/pmsx003.cpp @@ -195,7 +195,7 @@ void PMSX003Component::send_command_(uint8_t cmd, uint16_t data) { void PMSX003Component::parse_data_() { switch (this->type_) { case PMSX003_TYPE_5003ST: { - float temperature = this->get_16_bit_uint_(30) / 10.0f; + float temperature = (int16_t) this->get_16_bit_uint_(30) / 10.0f; float humidity = this->get_16_bit_uint_(32) / 10.0f; ESP_LOGD(TAG, "Got Temperature: %.1f°C, Humidity: %.1f%%", temperature, humidity); From 4e5534850c9bdc2385037641266aff5708b3e4b0 Mon Sep 17 00:00:00 2001 From: aschmitz <29508+aschmitz@users.noreply.github.com> Date: Mon, 15 Jan 2024 01:08:19 -0600 Subject: [PATCH 041/189] fix: negative temperatures on PMS5003T sensors (#6100) --- esphome/components/pmsx003/pmsx003.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/pmsx003/pmsx003.cpp b/esphome/components/pmsx003/pmsx003.cpp index 62488b765c..de2b23b8eb 100644 --- a/esphome/components/pmsx003/pmsx003.cpp +++ b/esphome/components/pmsx003/pmsx003.cpp @@ -279,7 +279,7 @@ void PMSX003Component::parse_data_() { // Note the pm particles 50um & 100um are not returned, // as PMS5003T uses those data values for temperature and humidity. - float temperature = this->get_16_bit_uint_(24) / 10.0f; + float temperature = (int16_t) this->get_16_bit_uint_(24) / 10.0f; float humidity = this->get_16_bit_uint_(26) / 10.0f; ESP_LOGD(TAG, From f3997d0f77d2295e90f96e31cccd0515ea0acf5f Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Mon, 22 Jan 2024 19:28:12 -0600 Subject: [PATCH 042/189] Bump version to 2023.12.9 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 3b31a17c3e..f65a155cd2 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2023.12.8" +__version__ = "2023.12.9" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From 0e769d77ffa4146dc8c4d78fa900e3021c6880a7 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Tue, 13 Feb 2024 09:45:30 +1300 Subject: [PATCH 043/189] Bump version to 2024.2.0b1 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 8f9606c5fd..39ef0f8475 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2024.1.0-dev" +__version__ = "2024.2.0b1" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From 6935b02d3fb208cf94022349d8b35ba221defb62 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Tue, 13 Feb 2024 10:19:02 +1300 Subject: [PATCH 044/189] Bump openssh-client to 1:9.2p1-2+deb12u2 --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index b28ca2ba66..5d9ece16a1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -35,7 +35,7 @@ RUN \ iputils-ping=3:20221126-1 \ git=1:2.39.2-1.1 \ curl=7.88.1-10+deb12u5 \ - openssh-client=1:9.2p1-2+deb12u1 \ + openssh-client=1:9.2p1-2+deb12u2 \ python3-cffi=1.15.1-5 \ libcairo2=1.16.0-7 \ libmagic1=1:5.44-3 \ From 373569d86d2cfab71a3cf48b6ddd21c4853b9fd1 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Thu, 15 Feb 2024 15:47:42 -0600 Subject: [PATCH 045/189] AUTO_LOAD `sensor` for `shelly_dimmer` (#6223) --- esphome/components/shelly_dimmer/light.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esphome/components/shelly_dimmer/light.py b/esphome/components/shelly_dimmer/light.py index 5bdb54baf5..625784427f 100644 --- a/esphome/components/shelly_dimmer/light.py +++ b/esphome/components/shelly_dimmer/light.py @@ -29,7 +29,8 @@ from esphome.const import ( from esphome.core import HexInt, CORE DOMAIN = "shelly_dimmer" -DEPENDENCIES = ["sensor", "uart", "esp8266"] +AUTO_LOAD = ["sensor"] +DEPENDENCIES = ["uart", "esp8266"] shelly_dimmer_ns = cg.esphome_ns.namespace("shelly_dimmer") ShellyDimmer = shelly_dimmer_ns.class_( From 7aa2c494c8528110ae129cda073dc27b7655abb1 Mon Sep 17 00:00:00 2001 From: kahrendt Date: Sun, 18 Feb 2024 00:50:24 -0500 Subject: [PATCH 046/189] Add more debugging logs to microWakeWord (#6238) --- .../components/micro_wake_word/__init__.py | 2 +- .../micro_wake_word/micro_wake_word.cpp | 44 +++++++++++++------ .../micro_wake_word/micro_wake_word.h | 3 ++ 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/esphome/components/micro_wake_word/__init__.py b/esphome/components/micro_wake_word/__init__.py index 2a84b7d74b..38202bdfb9 100644 --- a/esphome/components/micro_wake_word/__init__.py +++ b/esphome/components/micro_wake_word/__init__.py @@ -261,7 +261,7 @@ CONFIG_SCHEMA = cv.All( { cv.GenerateID(): cv.declare_id(MicroWakeWord), cv.GenerateID(CONF_MICROPHONE): cv.use_id(microphone.Microphone), - cv.Optional(CONF_PROBABILITY_CUTOFF): cv.float_, + cv.Optional(CONF_PROBABILITY_CUTOFF): cv.percentage, cv.Optional(CONF_SLIDING_WINDOW_AVERAGE_SIZE): cv.positive_int, cv.Optional(CONF_ON_WAKE_WORD_DETECTED): automation.validate_automation( single=True diff --git a/esphome/components/micro_wake_word/micro_wake_word.cpp b/esphome/components/micro_wake_word/micro_wake_word.cpp index 8a443bc224..f0b3d55a9d 100644 --- a/esphome/components/micro_wake_word/micro_wake_word.cpp +++ b/esphome/components/micro_wake_word/micro_wake_word.cpp @@ -53,8 +53,15 @@ static const LogString *micro_wake_word_state_to_string(State state) { } } +void MicroWakeWord::dump_config() { + ESP_LOGCONFIG(TAG, "microWakeWord:"); + ESP_LOGCONFIG(TAG, " Wake Word: %s", this->get_wake_word().c_str()); + ESP_LOGCONFIG(TAG, " Probability cutoff: %.3f", this->probability_cutoff_); + ESP_LOGCONFIG(TAG, " Sliding window size: %d", this->sliding_window_average_size_); +} + void MicroWakeWord::setup() { - ESP_LOGCONFIG(TAG, "Setting up Micro Wake Word..."); + ESP_LOGCONFIG(TAG, "Setting up microWakeWord..."); if (!this->initialize_models()) { ESP_LOGE(TAG, "Failed to initialize models"); @@ -63,7 +70,7 @@ void MicroWakeWord::setup() { } ExternalRAMAllocator allocator(ExternalRAMAllocator::ALLOW_FAILURE); - this->input_buffer_ = allocator.allocate(NEW_SAMPLES_TO_GET); + this->input_buffer_ = allocator.allocate(INPUT_BUFFER_SIZE * sizeof(int16_t)); if (this->input_buffer_ == nullptr) { ESP_LOGW(TAG, "Could not allocate input buffer"); this->mark_failed(); @@ -81,7 +88,7 @@ void MicroWakeWord::setup() { } int MicroWakeWord::read_microphone_() { - size_t bytes_read = this->microphone_->read(this->input_buffer_, NEW_SAMPLES_TO_GET * sizeof(int16_t)); + size_t bytes_read = this->microphone_->read(this->input_buffer_, INPUT_BUFFER_SIZE * sizeof(int16_t)); if (bytes_read == 0) { return 0; } @@ -279,11 +286,6 @@ bool MicroWakeWord::initialize_models() { } bool MicroWakeWord::update_features_() { - // Verify we have enough samples for a feature slice - if (!this->slice_available_()) { - return false; - } - // Retrieve strided audio samples int16_t *audio_samples = nullptr; if (!this->stride_audio_samples_(&audio_samples)) { @@ -369,20 +371,36 @@ void MicroWakeWord::set_sliding_window_average_size(size_t size) { bool MicroWakeWord::slice_available_() { size_t available = this->ring_buffer_->available(); + size_t free = this->ring_buffer_->free(); + + if (free < NEW_SAMPLES_TO_GET * sizeof(int16_t)) { + // If the ring buffer is within one audio slice of being full, then wake word detection will have issues. + // If this is constantly occuring, then some possibilities why are + // 1) there are too many other slow components configured + // 2) the ESP32 isn't fast enough; e.g., an ESP32 is much slower than an ESP32-S3 at inferences. + // 3) the model is too large + // 4) the model uses operations that are not optimized + ESP_LOGW(TAG, + "Audio buffer is nearly full. Wake word detection may be less accurate and have slower reponse times. " +#if !defined(USE_ESP32_VARIANT_ESP32S3) + "microWakeWord is designed for the ESP32-S3. The current platform is too slow for this model." +#endif + ); + } + return available > (NEW_SAMPLES_TO_GET * sizeof(int16_t)); } bool MicroWakeWord::stride_audio_samples_(int16_t **audio_samples) { + if (!this->slice_available_()) { + return false; + } + // Copy 320 bytes (160 samples over 10 ms) into preprocessor_audio_buffer_ from history in // preprocessor_stride_buffer_ memcpy((void *) (this->preprocessor_audio_buffer_), (void *) (this->preprocessor_stride_buffer_), HISTORY_SAMPLES_TO_KEEP * sizeof(int16_t)); - if (this->ring_buffer_->available() < NEW_SAMPLES_TO_GET * sizeof(int16_t)) { - ESP_LOGD(TAG, "Audio Buffer not full enough"); - return false; - } - // Copy 640 bytes (320 samples over 20 ms) from the ring buffer // The first 320 bytes (160 samples over 10 ms) will be from history size_t bytes_read = this->ring_buffer_->read((void *) (this->preprocessor_audio_buffer_ + HISTORY_SAMPLES_TO_KEEP), diff --git a/esphome/components/micro_wake_word/micro_wake_word.h b/esphome/components/micro_wake_word/micro_wake_word.h index 82f28b2ebb..27d05c3e09 100644 --- a/esphome/components/micro_wake_word/micro_wake_word.h +++ b/esphome/components/micro_wake_word/micro_wake_word.h @@ -66,6 +66,7 @@ class MicroWakeWord : public Component { void setup() override; void loop() override; float get_setup_priority() const override; + void dump_config() override; void start(); void stop(); @@ -74,6 +75,8 @@ class MicroWakeWord : public Component { bool initialize_models(); + std::string get_wake_word() { return this->wake_word_; } + // Increasing either of these will reduce the rate of false acceptances while increasing the false rejection rate void set_probability_cutoff(float probability_cutoff) { this->probability_cutoff_ = probability_cutoff; } void set_sliding_window_average_size(size_t size); From 61a45dcebedb2edddb192f2871b485de49cb779f Mon Sep 17 00:00:00 2001 From: marshn Date: Sun, 18 Feb 2024 18:38:32 +0000 Subject: [PATCH 047/189] Fix to RF receiver for Drayton Digistat heating controller (#6235) --- esphome/components/remote_base/drayton_protocol.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/remote_base/drayton_protocol.cpp b/esphome/components/remote_base/drayton_protocol.cpp index 6c617f56c8..acfb7a0f16 100644 --- a/esphome/components/remote_base/drayton_protocol.cpp +++ b/esphome/components/remote_base/drayton_protocol.cpp @@ -14,7 +14,7 @@ static const uint8_t NBITS_ADDRESS = 16; static const uint8_t NBITS_CHANNEL = 5; static const uint8_t NBITS_COMMAND = 7; static const uint8_t NDATABITS = NBITS_ADDRESS + NBITS_CHANNEL + NBITS_COMMAND; -static const uint8_t MIN_RX_SRC = (NDATABITS * 2 + NBITS_SYNC / 2); +static const uint8_t MIN_RX_SRC = (NDATABITS + NBITS_SYNC / 2); static const uint8_t CMD_ON = 0x41; static const uint8_t CMD_OFF = 0x02; @@ -135,7 +135,7 @@ optional DraytonProtocol::decode(RemoteReceiveData src) { .command = 0, }; - while (src.size() - src.get_index() > MIN_RX_SRC) { + while (src.size() - src.get_index() >= MIN_RX_SRC) { ESP_LOGVV(TAG, "Decode Drayton: %" PRId32 ", %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 " %" PRId32 @@ -150,7 +150,7 @@ optional DraytonProtocol::decode(RemoteReceiveData src) { } // Look for sync pulse, after. If sucessful index points to space of sync symbol - while (src.size() - src.get_index() >= NDATABITS) { + while (src.size() - src.get_index() >= MIN_RX_SRC) { ESP_LOGVV(TAG, "Decode Drayton: sync search %d, %" PRId32 " %" PRId32, src.size() - src.get_index(), src.peek(), src.peek(1)); if (src.peek_mark(2 * BIT_TIME_US) && From 29ec40db5f4ebf3dfc151a658628effa5e1651c0 Mon Sep 17 00:00:00 2001 From: Marcel Hetzendorfer Date: Sun, 18 Feb 2024 19:40:20 +0100 Subject: [PATCH 048/189] WRGB Use correct multiplier (#6237) --- esphome/components/esp32_rmt_led_strip/led_strip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/esp32_rmt_led_strip/led_strip.cpp b/esphome/components/esp32_rmt_led_strip/led_strip.cpp index c5a7f7918d..7727b64f29 100644 --- a/esphome/components/esp32_rmt_led_strip/led_strip.cpp +++ b/esphome/components/esp32_rmt_led_strip/led_strip.cpp @@ -160,7 +160,7 @@ light::ESPColorView ESP32RMTLEDStripLightOutput::get_view_internal(int32_t index b = 0; break; } - uint8_t multiplier = this->is_rgbw_ ? 4 : 3; + uint8_t multiplier = this->is_rgbw_ || this->is_wrgb_ ? 4 : 3; uint8_t white = this->is_wrgb_ ? 0 : 3; return {this->buf_ + (index * multiplier) + r + this->is_wrgb_, From 6eb3c654455bbc4248b39c8044599be28f95d6ff Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Mon, 19 Feb 2024 11:52:37 +1300 Subject: [PATCH 049/189] Add optional minimum esphome version to microWakeWord manifest (#6240) --- esphome/components/micro_wake_word/__init__.py | 4 ++++ esphome/config_validation.py | 11 +++++++++++ esphome/core/config.py | 12 +----------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/esphome/components/micro_wake_word/__init__.py b/esphome/components/micro_wake_word/__init__.py index 38202bdfb9..209a1412ca 100644 --- a/esphome/components/micro_wake_word/__init__.py +++ b/esphome/components/micro_wake_word/__init__.py @@ -103,6 +103,7 @@ KEY_AUTHOR = "author" KEY_WEBSITE = "website" KEY_VERSION = "version" KEY_MICRO = "micro" +KEY_MINIMUM_ESPHOME_VERSION = "minimum_esphome_version" MANIFEST_SCHEMA_V1 = cv.Schema( { @@ -116,6 +117,9 @@ MANIFEST_SCHEMA_V1 = cv.Schema( { cv.Required(CONF_PROBABILITY_CUTOFF): cv.float_, cv.Required(CONF_SLIDING_WINDOW_AVERAGE_SIZE): cv.positive_int, + cv.Optional(KEY_MINIMUM_ESPHOME_VERSION): cv.All( + cv.version_number, cv.validate_esphome_version + ), } ), } diff --git a/esphome/config_validation.py b/esphome/config_validation.py index fa1170fb93..9f577773d4 100644 --- a/esphome/config_validation.py +++ b/esphome/config_validation.py @@ -57,6 +57,7 @@ from esphome.const import ( TYPE_GIT, TYPE_LOCAL, VALID_SUBSTITUTIONS_CHARACTERS, + __version__ as ESPHOME_VERSION, ) from esphome.core import ( CORE, @@ -1895,6 +1896,16 @@ def version_number(value): raise Invalid("Not a valid version number") from e +def validate_esphome_version(value: str): + min_version = Version.parse(value) + current_version = Version.parse(ESPHOME_VERSION) + if current_version < min_version: + raise Invalid( + f"Your ESPHome version is too old. Please update to at least {min_version}" + ) + return value + + def platformio_version_constraint(value): # for documentation on valid version constraints: # https://docs.platformio.org/en/latest/core/userguide/platforms/cmd_install.html#cmd-platform-install diff --git a/esphome/core/config.py b/esphome/core/config.py index e4a1fdcafa..f3d732a8fc 100644 --- a/esphome/core/config.py +++ b/esphome/core/config.py @@ -102,16 +102,6 @@ def valid_project_name(value: str): return value -def validate_version(value: str): - min_version = cv.Version.parse(value) - current_version = cv.Version.parse(ESPHOME_VERSION) - if current_version < min_version: - raise cv.Invalid( - f"Your ESPHome version is too old. Please update to at least {min_version}" - ) - return value - - if "ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT" in os.environ: _compile_process_limit_default = min( int(os.environ["ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT"]), @@ -164,7 +154,7 @@ CONFIG_SCHEMA = cv.All( } ), cv.Optional(CONF_MIN_VERSION, default=ESPHOME_VERSION): cv.All( - cv.version_number, validate_version + cv.version_number, cv.validate_esphome_version ), cv.Optional( CONF_COMPILE_PROCESS_LIMIT, default=_compile_process_limit_default From cc1813f5b99a0a90916ea201c3deb06c212387f9 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Mon, 19 Feb 2024 16:44:18 +1300 Subject: [PATCH 050/189] Fix xl9535 pin reads (#6242) --- esphome/components/xl9535/xl9535.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/xl9535/xl9535.cpp b/esphome/components/xl9535/xl9535.cpp index 8f4f556b4a..93c65a4cb7 100644 --- a/esphome/components/xl9535/xl9535.cpp +++ b/esphome/components/xl9535/xl9535.cpp @@ -36,14 +36,14 @@ bool XL9535Component::digital_read(uint8_t pin) { return state; } - state = (port & (pin - 10)) != 0; + state = (port & (1 << (pin - 10))) != 0; } else { if (this->read_register(XL9535_INPUT_PORT_0_REGISTER, &port, 1) != i2c::ERROR_OK) { this->status_set_warning(); return state; } - state = (port & pin) != 0; + state = (port & (1 << pin)) != 0; } this->status_clear_warning(); From e0e348933506ecd2bf974d9327da7fc7e9c05b55 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Mon, 19 Feb 2024 17:01:01 +1300 Subject: [PATCH 051/189] Bump version to 2024.2.0b2 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 39ef0f8475..776ae86d19 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2024.2.0b1" +__version__ = "2024.2.0b2" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From ae4af2966a06826ebd6d5339f01d74a07608ba70 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Mon, 19 Feb 2024 11:13:12 -0800 Subject: [PATCH 052/189] hold interrupt disable for dallas one-wire (#6244) Co-authored-by: Samuel Sieb --- esphome/components/dallas/dallas_component.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/esphome/components/dallas/dallas_component.cpp b/esphome/components/dallas/dallas_component.cpp index 302422d6c7..b1983fef72 100644 --- a/esphome/components/dallas/dallas_component.cpp +++ b/esphome/components/dallas/dallas_component.cpp @@ -168,10 +168,6 @@ bool IRAM_ATTR DallasTemperatureSensor::read_scratch_pad() { if (!wire->reset()) { return false; } - } - - { - InterruptLock lock; wire->select(this->address_); wire->write8(DALLAS_COMMAND_READ_SCRATCH_PAD); From 841a831c63b2e477601d2fe42170e72e89a4874c Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Tue, 20 Feb 2024 13:12:08 -0600 Subject: [PATCH 053/189] Fix tm1651 enum (#6248) --- esphome/components/tm1651/__init__.py | 7 ++++--- esphome/components/tm1651/tm1651.cpp | 14 +++++++------- esphome/components/tm1651/tm1651.h | 7 +++++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/esphome/components/tm1651/__init__.py b/esphome/components/tm1651/__init__.py index a6b2189eb6..4ef8842571 100644 --- a/esphome/components/tm1651/__init__.py +++ b/esphome/components/tm1651/__init__.py @@ -13,6 +13,7 @@ from esphome.const import ( CODEOWNERS = ["@freekode"] tm1651_ns = cg.esphome_ns.namespace("tm1651") +TM1651Brightness = tm1651_ns.enum("TM1651Brightness") TM1651Display = tm1651_ns.class_("TM1651Display", cg.Component) SetLevelPercentAction = tm1651_ns.class_("SetLevelPercentAction", automation.Action) @@ -24,9 +25,9 @@ TurnOffAction = tm1651_ns.class_("SetLevelPercentAction", automation.Action) CONF_LEVEL_PERCENT = "level_percent" TM1651_BRIGHTNESS_OPTIONS = { - 1: TM1651Display.TM1651_BRIGHTNESS_LOW, - 2: TM1651Display.TM1651_BRIGHTNESS_MEDIUM, - 3: TM1651Display.TM1651_BRIGHTNESS_HIGH, + 1: TM1651Brightness.TM1651_BRIGHTNESS_LOW, + 2: TM1651Brightness.TM1651_BRIGHTNESS_MEDIUM, + 3: TM1651Brightness.TM1651_BRIGHTNESS_HIGH, } CONFIG_SCHEMA = cv.All( diff --git a/esphome/components/tm1651/tm1651.cpp b/esphome/components/tm1651/tm1651.cpp index c6bb1bc025..89807f5565 100644 --- a/esphome/components/tm1651/tm1651.cpp +++ b/esphome/components/tm1651/tm1651.cpp @@ -12,9 +12,9 @@ static const char *const TAG = "tm1651.display"; static const uint8_t MAX_INPUT_LEVEL_PERCENT = 100; static const uint8_t TM1651_MAX_LEVEL = 7; -static const uint8_t TM1651_BRIGHTNESS_LOW = 0; -static const uint8_t TM1651_BRIGHTNESS_MEDIUM = 2; -static const uint8_t TM1651_BRIGHTNESS_HIGH = 7; +static const uint8_t TM1651_BRIGHTNESS_LOW_HW = 0; +static const uint8_t TM1651_BRIGHTNESS_MEDIUM_HW = 2; +static const uint8_t TM1651_BRIGHTNESS_HIGH_HW = 7; void TM1651Display::setup() { ESP_LOGCONFIG(TAG, "Setting up TM1651..."); @@ -78,14 +78,14 @@ uint8_t TM1651Display::calculate_level_(uint8_t new_level) { uint8_t TM1651Display::calculate_brightness_(uint8_t new_brightness) { if (new_brightness <= 1) { - return TM1651_BRIGHTNESS_LOW; + return TM1651_BRIGHTNESS_LOW_HW; } else if (new_brightness == 2) { - return TM1651_BRIGHTNESS_MEDIUM; + return TM1651_BRIGHTNESS_MEDIUM_HW; } else if (new_brightness >= 3) { - return TM1651_BRIGHTNESS_HIGH; + return TM1651_BRIGHTNESS_HIGH_HW; } - return TM1651_BRIGHTNESS_LOW; + return TM1651_BRIGHTNESS_LOW_HW; } } // namespace tm1651 diff --git a/esphome/components/tm1651/tm1651.h b/esphome/components/tm1651/tm1651.h index eb65ed186d..fe7b7d9c6f 100644 --- a/esphome/components/tm1651/tm1651.h +++ b/esphome/components/tm1651/tm1651.h @@ -13,6 +13,12 @@ namespace esphome { namespace tm1651 { +enum TM1651Brightness : uint8_t { + TM1651_BRIGHTNESS_LOW = 1, + TM1651_BRIGHTNESS_MEDIUM = 2, + TM1651_BRIGHTNESS_HIGH = 3, +}; + class TM1651Display : public Component { public: void set_clk_pin(InternalGPIOPin *pin) { clk_pin_ = pin; } @@ -24,6 +30,7 @@ class TM1651Display : public Component { void set_level_percent(uint8_t new_level); void set_level(uint8_t new_level); void set_brightness(uint8_t new_brightness); + void set_brightness(TM1651Brightness new_brightness) { this->set_brightness(static_cast(new_brightness)); } void turn_on(); void turn_off(); From 4eb04afa62f8516973aa85d43f024c54ca831388 Mon Sep 17 00:00:00 2001 From: SmartShackMaster Date: Tue, 20 Feb 2024 23:27:17 +0200 Subject: [PATCH 054/189] Clear UART read buffer before sending next command (#6200) --- esphome/components/fingerprint_grow/fingerprint_grow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esphome/components/fingerprint_grow/fingerprint_grow.cpp b/esphome/components/fingerprint_grow/fingerprint_grow.cpp index 0a46755bd3..e8c6b2537f 100644 --- a/esphome/components/fingerprint_grow/fingerprint_grow.cpp +++ b/esphome/components/fingerprint_grow/fingerprint_grow.cpp @@ -336,6 +336,8 @@ void FingerprintGrowComponent::aura_led_control(uint8_t state, uint8_t speed, ui } uint8_t FingerprintGrowComponent::send_command_() { + while (this->available()) + this->read(); this->write((uint8_t) (START_CODE >> 8)); this->write((uint8_t) (START_CODE & 0xFF)); this->write(this->address_[0]); From fb16e6b027125c1d9362ad9a7ad131ae7628df96 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Tue, 20 Feb 2024 15:38:33 -0600 Subject: [PATCH 055/189] Voice Assistant: add on_idle trigger and fix nevermind (#6141) --- esphome/components/voice_assistant/__init__.py | 9 +++++++++ esphome/components/voice_assistant/voice_assistant.cpp | 5 +++++ esphome/components/voice_assistant/voice_assistant.h | 2 ++ 3 files changed, 16 insertions(+) diff --git a/esphome/components/voice_assistant/__init__.py b/esphome/components/voice_assistant/__init__.py index 59aef901f2..b21a5b27da 100644 --- a/esphome/components/voice_assistant/__init__.py +++ b/esphome/components/voice_assistant/__init__.py @@ -32,6 +32,7 @@ CONF_ON_TTS_START = "on_tts_start" CONF_ON_TTS_STREAM_START = "on_tts_stream_start" CONF_ON_TTS_STREAM_END = "on_tts_stream_end" CONF_ON_WAKE_WORD_DETECTED = "on_wake_word_detected" +CONF_ON_IDLE = "on_idle" CONF_SILENCE_DETECTION = "silence_detection" CONF_USE_WAKE_WORD = "use_wake_word" @@ -127,6 +128,7 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_ON_TTS_STREAM_END): automation.validate_automation( single=True ), + cv.Optional(CONF_ON_IDLE): automation.validate_automation(single=True), } ).extend(cv.COMPONENT_SCHEMA), tts_stream_validate, @@ -259,6 +261,13 @@ async def to_code(config): config[CONF_ON_TTS_STREAM_END], ) + if CONF_ON_IDLE in config: + await automation.build_automation( + var.get_idle_trigger(), + [], + config[CONF_ON_IDLE], + ) + cg.add_define("USE_VOICE_ASSISTANT") diff --git a/esphome/components/voice_assistant/voice_assistant.cpp b/esphome/components/voice_assistant/voice_assistant.cpp index 9094b93c02..260605c0b4 100644 --- a/esphome/components/voice_assistant/voice_assistant.cpp +++ b/esphome/components/voice_assistant/voice_assistant.cpp @@ -135,6 +135,8 @@ void VoiceAssistant::loop() { switch (this->state_) { case State::IDLE: { if (this->continuous_ && this->desired_state_ == State::IDLE) { + this->idle_trigger_->trigger(); + this->ring_buffer_->reset(); #ifdef USE_ESP_ADF if (this->use_wake_word_) { @@ -618,6 +620,9 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) { { this->set_state_(State::IDLE, State::IDLE); } + } else if (this->state_ == State::AWAITING_RESPONSE) { + // No TTS start event ("nevermind") + this->set_state_(State::IDLE, State::IDLE); } this->defer([this]() { this->end_trigger_->trigger(); }); break; diff --git a/esphome/components/voice_assistant/voice_assistant.h b/esphome/components/voice_assistant/voice_assistant.h index d996efe08e..f0ee793f53 100644 --- a/esphome/components/voice_assistant/voice_assistant.h +++ b/esphome/components/voice_assistant/voice_assistant.h @@ -116,6 +116,7 @@ class VoiceAssistant : public Component { Trigger *get_tts_end_trigger() const { return this->tts_end_trigger_; } Trigger *get_tts_start_trigger() const { return this->tts_start_trigger_; } Trigger *get_error_trigger() const { return this->error_trigger_; } + Trigger<> *get_idle_trigger() const { return this->idle_trigger_; } Trigger<> *get_client_connected_trigger() const { return this->client_connected_trigger_; } Trigger<> *get_client_disconnected_trigger() const { return this->client_disconnected_trigger_; } @@ -148,6 +149,7 @@ class VoiceAssistant : public Component { Trigger *tts_end_trigger_ = new Trigger(); Trigger *tts_start_trigger_ = new Trigger(); Trigger *error_trigger_ = new Trigger(); + Trigger<> *idle_trigger_ = new Trigger<>(); Trigger<> *client_connected_trigger_ = new Trigger<>(); Trigger<> *client_disconnected_trigger_ = new Trigger<>(); From 7bf676abfa55b0ccd36a71cbca72830e05cdb297 Mon Sep 17 00:00:00 2001 From: sibowler Date: Wed, 21 Feb 2024 08:40:17 +1100 Subject: [PATCH 056/189] Tuya Fan component fix to handle enum datapoint type (#6135) --- esphome/components/tuya/fan/tuya_fan.cpp | 10 +++++++++- esphome/components/tuya/fan/tuya_fan.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/esphome/components/tuya/fan/tuya_fan.cpp b/esphome/components/tuya/fan/tuya_fan.cpp index 481c931f2e..8a613d0bae 100644 --- a/esphome/components/tuya/fan/tuya_fan.cpp +++ b/esphome/components/tuya/fan/tuya_fan.cpp @@ -34,9 +34,13 @@ void TuyaFan::setup() { } if (this->oscillation_id_.has_value()) { this->parent_->register_listener(*this->oscillation_id_, [this](const TuyaDatapoint &datapoint) { + // Whether data type is BOOL or ENUM, it will still be a 1 or a 0, so the functions below are valid in both + // scenarios ESP_LOGV(TAG, "MCU reported oscillation is: %s", ONOFF(datapoint.value_bool)); this->oscillating = datapoint.value_bool; this->publish_state(); + + this->oscillation_type_ = datapoint.type; }); } if (this->direction_id_.has_value()) { @@ -80,7 +84,11 @@ void TuyaFan::control(const fan::FanCall &call) { this->parent_->set_boolean_datapoint_value(*this->switch_id_, *call.get_state()); } if (this->oscillation_id_.has_value() && call.get_oscillating().has_value()) { - this->parent_->set_boolean_datapoint_value(*this->oscillation_id_, *call.get_oscillating()); + if (this->oscillation_type_ == TuyaDatapointType::ENUM) { + this->parent_->set_enum_datapoint_value(*this->oscillation_id_, *call.get_oscillating()); + } else if (this->speed_type_ == TuyaDatapointType::BOOLEAN) { + this->parent_->set_boolean_datapoint_value(*this->oscillation_id_, *call.get_oscillating()); + } } if (this->direction_id_.has_value() && call.get_direction().has_value()) { bool enable = *call.get_direction() == fan::FanDirection::REVERSE; diff --git a/esphome/components/tuya/fan/tuya_fan.h b/esphome/components/tuya/fan/tuya_fan.h index 77b2cc6383..527efa8246 100644 --- a/esphome/components/tuya/fan/tuya_fan.h +++ b/esphome/components/tuya/fan/tuya_fan.h @@ -29,6 +29,7 @@ class TuyaFan : public Component, public fan::Fan { optional direction_id_{}; int speed_count_{}; TuyaDatapointType speed_type_{}; + TuyaDatapointType oscillation_type_{}; }; } // namespace tuya From 03ea71034fb91456671aac338b3b759961e5acf9 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 21 Feb 2024 10:57:43 +1300 Subject: [PATCH 057/189] Bump version to 2024.2.0b3 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 776ae86d19..cfbff7060b 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2024.2.0b2" +__version__ = "2024.2.0b3" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From c92968da8a1199351b7c5cc2edeacde23c4248cc Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 21 Feb 2024 12:51:13 +1300 Subject: [PATCH 058/189] Bump version to 2024.2.0 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index cfbff7060b..26cb0c5183 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2024.2.0b3" +__version__ = "2024.2.0" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From 2e7129e816a49df1d32c56edb0d79294f2245bec Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:51:06 +1300 Subject: [PATCH 059/189] Add missing timeout to "async_request" (#6267) --- esphome/zeroconf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/zeroconf.py b/esphome/zeroconf.py index 72cc4c00c6..77044d4a11 100644 --- a/esphome/zeroconf.py +++ b/esphome/zeroconf.py @@ -110,7 +110,7 @@ class DashboardImportDiscovery: self, zeroconf: Zeroconf, info: AsyncServiceInfo, service_type: str, name: str ) -> None: """Process a service info.""" - if await info.async_request(zeroconf): + if await info.async_request(zeroconf, timeout=5): self._process_service_info(name, info) def _process_service_info(self, name: str, info: ServiceInfo) -> None: From 62d59cffcc2e6bbfaa9fe9099d63e51ae835d250 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Thu, 22 Feb 2024 14:26:00 +1300 Subject: [PATCH 060/189] Bump zeroconf timeout to 3000 (#6270) --- esphome/zeroconf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/zeroconf.py b/esphome/zeroconf.py index 77044d4a11..b67ea41323 100644 --- a/esphome/zeroconf.py +++ b/esphome/zeroconf.py @@ -110,7 +110,7 @@ class DashboardImportDiscovery: self, zeroconf: Zeroconf, info: AsyncServiceInfo, service_type: str, name: str ) -> None: """Process a service info.""" - if await info.async_request(zeroconf, timeout=5): + if await info.async_request(zeroconf, timeout=3000): self._process_service_info(name, info) def _process_service_info(self, name: str, info: ServiceInfo) -> None: From db5205931ba07abecd37bf50ad3cc5f898be19f1 Mon Sep 17 00:00:00 2001 From: Daniel Baulig Date: Wed, 21 Feb 2024 17:33:28 -0800 Subject: [PATCH 061/189] web_server: Add a position property for cover entities that have the supports position trait (#6269) --- esphome/components/web_server/web_server.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index 54e9e6ebcc..f87e920f13 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -785,6 +785,8 @@ std::string WebServer::cover_json(cover::Cover *obj, JsonDetail start_config) { obj->position, start_config); root["current_operation"] = cover::cover_operation_to_str(obj->current_operation); + if (obj->get_traits().get_supports_position()) + root["position"] = obj->position; if (obj->get_traits().get_supports_tilt()) root["tilt"] = obj->tilt; }); From 5a7759f1c43fd4e260341e568e2d5102b2db85ac Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Thu, 22 Feb 2024 18:17:10 -0800 Subject: [PATCH 062/189] allow multiple emc2101 (#6272) --- esphome/components/emc2101/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esphome/components/emc2101/__init__.py b/esphome/components/emc2101/__init__.py index 7a7b31cf14..8012d3e897 100644 --- a/esphome/components/emc2101/__init__.py +++ b/esphome/components/emc2101/__init__.py @@ -7,6 +7,8 @@ CODEOWNERS = ["@ellull"] DEPENDENCIES = ["i2c"] +MULTI_CONF = True + CONF_PWM = "pwm" CONF_DIVIDER = "divider" CONF_DAC = "dac" From 2cf639316130a898afff5bae03f58f062d0fcd9d Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Sat, 24 Feb 2024 00:31:20 -0600 Subject: [PATCH 063/189] Fix RP2040 SPI pin validation (#6277) --- esphome/components/spi/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/esphome/components/spi/__init__.py b/esphome/components/spi/__init__.py index 10ea906a92..d45362435e 100644 --- a/esphome/components/spi/__init__.py +++ b/esphome/components/spi/__init__.py @@ -74,7 +74,8 @@ CONF_FORCE_SW = "force_sw" CONF_INTERFACE = "interface" CONF_INTERFACE_INDEX = "interface_index" -# RP2040 SPI pin assignments are complicated. Refer to https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf +# RP2040 SPI pin assignments are complicated; +# refer to GPIO function select table in https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf RP_SPI_PINSETS = [ { @@ -85,7 +86,7 @@ RP_SPI_PINSETS = [ { CONF_MISO_PIN: [8, 12, 24, 28, -1], CONF_CLK_PIN: [10, 14, 26], - CONF_MOSI_PIN: [11, 23, 27, -1], + CONF_MOSI_PIN: [11, 15, 27, -1], }, ] From 84c6e52be21daf775572d692bffee2f91fd8d1e6 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 24 Feb 2024 18:39:47 -1000 Subject: [PATCH 064/189] dashboard: move storage json update to a background task in edit save (#6280) * dashboard: move storage json update to a background task in edit save * dashboard: move storage json update to a background task in edit save * fix typing * docs --- esphome/dashboard/const.py | 2 ++ esphome/dashboard/core.py | 16 ++++++++++++++++ esphome/dashboard/entries.py | 10 ++++++++++ esphome/dashboard/web_server.py | 10 +++------- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/esphome/dashboard/const.py b/esphome/dashboard/const.py index 190d6c4a9a..db66cb5ead 100644 --- a/esphome/dashboard/const.py +++ b/esphome/dashboard/const.py @@ -8,3 +8,5 @@ MAX_EXECUTOR_WORKERS = 48 SENTINEL = object() + +DASHBOARD_COMMAND = ["esphome", "--dashboard"] diff --git a/esphome/dashboard/core.py b/esphome/dashboard/core.py index e22d95fba9..875ff6b91f 100644 --- a/esphome/dashboard/core.py +++ b/esphome/dashboard/core.py @@ -1,11 +1,13 @@ from __future__ import annotations import asyncio +import contextlib import logging import threading from dataclasses import dataclass from functools import partial from typing import TYPE_CHECKING, Any, Callable +from collections.abc import Coroutine from ..zeroconf import DiscoveredImport from .dns import DNSCache @@ -71,6 +73,7 @@ class ESPHomeDashboard: "mdns_status", "settings", "dns_cache", + "_background_tasks", ) def __init__(self) -> None: @@ -85,6 +88,7 @@ class ESPHomeDashboard: self.mdns_status: MDNSStatus | None = None self.settings = DashboardSettings() self.dns_cache = DNSCache() + self._background_tasks: set[asyncio.Task] = set() async def async_setup(self) -> None: """Setup the dashboard.""" @@ -132,7 +136,19 @@ class ESPHomeDashboard: if settings.status_use_mqtt: status_thread_mqtt.join() self.mqtt_ping_request.set() + for task in self._background_tasks: + task.cancel() + with contextlib.suppress(asyncio.CancelledError): + await task await asyncio.sleep(0) + def async_create_background_task( + self, coro: Coroutine[Any, Any, Any] + ) -> asyncio.Task: + """Create a background task.""" + task = self.loop.create_task(coro) + task.add_done_callback(self._background_tasks.discard) + return task + DASHBOARD = ESPHomeDashboard() diff --git a/esphome/dashboard/entries.py b/esphome/dashboard/entries.py index ad139b830b..cd318ba8a7 100644 --- a/esphome/dashboard/entries.py +++ b/esphome/dashboard/entries.py @@ -10,12 +10,14 @@ from esphome import const, util from esphome.storage_json import StorageJSON, ext_storage_path from .const import ( + DASHBOARD_COMMAND, EVENT_ENTRY_ADDED, EVENT_ENTRY_REMOVED, EVENT_ENTRY_STATE_CHANGED, EVENT_ENTRY_UPDATED, ) from .enum import StrEnum +from .util.subprocess import async_run_system_command if TYPE_CHECKING: from .core import ESPHomeDashboard @@ -235,6 +237,14 @@ class DashboardEntries: ) return path_to_cache_key + def async_schedule_storage_json_update(self, filename: str) -> None: + """Schedule a task to update the storage JSON file.""" + self._dashboard.async_create_background_task( + async_run_system_command( + [*DASHBOARD_COMMAND, "compile", "--only-generate", filename] + ) + ) + class DashboardEntry: """Represents a single dashboard entry. diff --git a/esphome/dashboard/web_server.py b/esphome/dashboard/web_server.py index c16461d174..a53f547039 100644 --- a/esphome/dashboard/web_server.py +++ b/esphome/dashboard/web_server.py @@ -9,11 +9,11 @@ import hashlib import json import logging import os -import time import secrets import shutil import subprocess import threading +import time from collections.abc import Iterable from pathlib import Path from typing import TYPE_CHECKING, Any, Callable, TypeVar @@ -40,6 +40,7 @@ from esphome.storage_json import StorageJSON, ext_storage_path, trash_storage_pa from esphome.util import get_serial_ports, shlex_quote from esphome.yaml_util import FastestAvailableSafeLoader +from .const import DASHBOARD_COMMAND from .core import DASHBOARD from .entries import EntryState, entry_state_to_bool from .util.file import write_file @@ -286,9 +287,6 @@ class EsphomeCommandWebSocket(tornado.websocket.WebSocketHandler): raise NotImplementedError -DASHBOARD_COMMAND = ["esphome", "--dashboard"] - - class EsphomePortCommandWebSocket(EsphomeCommandWebSocket): """Base class for commands that require a port.""" @@ -841,9 +839,7 @@ class EditRequestHandler(BaseHandler): None, self._write_file, config_file, self.request.body ) # Ensure the StorageJSON is updated as well - await async_run_system_command( - [*DASHBOARD_COMMAND, "compile", "--only-generate", config_file] - ) + DASHBOARD.entries.async_schedule_storage_json_update(filename) self.set_status(200) From d814ed1d4adc71fde47c4df41215bee449884513 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Fri, 23 Feb 2024 07:38:24 +1300 Subject: [PATCH 065/189] Merge pull request from GHSA-8p25-3q46-8q2p --- esphome/dashboard/web_server.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/esphome/dashboard/web_server.py b/esphome/dashboard/web_server.py index a53f547039..8bcc8efa0b 100644 --- a/esphome/dashboard/web_server.py +++ b/esphome/dashboard/web_server.py @@ -806,8 +806,16 @@ class EditRequestHandler(BaseHandler): @bind_config async def get(self, configuration: str | None = None) -> None: """Get the content of a file.""" - loop = asyncio.get_running_loop() + if not configuration.endswith((".yaml", ".yml")): + self.send_error(404) + return + filename = settings.rel_path(configuration) + if Path(filename).resolve().parent != settings.absolute_config_dir: + self.send_error(404) + return + + loop = asyncio.get_running_loop() content = await loop.run_in_executor( None, self._read_file, filename, configuration ) @@ -833,11 +841,17 @@ class EditRequestHandler(BaseHandler): @bind_config async def post(self, configuration: str | None = None) -> None: """Write the content of a file.""" + if not configuration.endswith((".yaml", ".yml")): + self.send_error(404) + return + + filename = settings.rel_path(configuration) + if Path(filename).resolve().parent != settings.absolute_config_dir: + self.send_error(404) + return + loop = asyncio.get_running_loop() - config_file = settings.rel_path(configuration) - await loop.run_in_executor( - None, self._write_file, config_file, self.request.body - ) + await loop.run_in_executor(None, self._write_file, filename, self.request.body) # Ensure the StorageJSON is updated as well DASHBOARD.entries.async_schedule_storage_json_update(filename) self.set_status(200) From e66e135a638313fd7f60d79bf26d7023fa8eaee8 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Sun, 25 Feb 2024 10:23:01 -0800 Subject: [PATCH 066/189] make output optional for speed fan (#6274) Co-authored-by: Samuel Sieb --- esphome/components/speed/fan/__init__.py | 9 ++++++--- esphome/components/speed/fan/speed_fan.cpp | 7 ++++--- esphome/components/speed/fan/speed_fan.h | 5 +++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/esphome/components/speed/fan/__init__.py b/esphome/components/speed/fan/__init__.py index 3acfb005bd..221e67d6c7 100644 --- a/esphome/components/speed/fan/__init__.py +++ b/esphome/components/speed/fan/__init__.py @@ -19,7 +19,7 @@ SpeedFan = speed_ns.class_("SpeedFan", cg.Component, fan.Fan) CONFIG_SCHEMA = fan.FAN_SCHEMA.extend( { cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(SpeedFan), - cv.Required(CONF_OUTPUT): cv.use_id(output.FloatOutput), + cv.Optional(CONF_OUTPUT): cv.use_id(output.FloatOutput), cv.Optional(CONF_OSCILLATION_OUTPUT): cv.use_id(output.BinaryOutput), cv.Optional(CONF_DIRECTION_OUTPUT): cv.use_id(output.BinaryOutput), cv.Optional(CONF_SPEED): cv.invalid( @@ -32,11 +32,14 @@ CONFIG_SCHEMA = fan.FAN_SCHEMA.extend( async def to_code(config): - output_ = await cg.get_variable(config[CONF_OUTPUT]) - var = cg.new_Pvariable(config[CONF_OUTPUT_ID], output_, config[CONF_SPEED_COUNT]) + var = cg.new_Pvariable(config[CONF_OUTPUT_ID], config[CONF_SPEED_COUNT]) await cg.register_component(var, config) await fan.register_fan(var, config) + if CONF_OUTPUT in config: + output_ = await cg.get_variable(config[CONF_OUTPUT]) + cg.add(var.set_output(output_)) + if CONF_OSCILLATION_OUTPUT in config: oscillation_output = await cg.get_variable(config[CONF_OSCILLATION_OUTPUT]) cg.add(var.set_oscillating(oscillation_output)) diff --git a/esphome/components/speed/fan/speed_fan.cpp b/esphome/components/speed/fan/speed_fan.cpp index 41b222acd6..bd0af7714d 100644 --- a/esphome/components/speed/fan/speed_fan.cpp +++ b/esphome/components/speed/fan/speed_fan.cpp @@ -36,9 +36,10 @@ void SpeedFan::control(const fan::FanCall &call) { } void SpeedFan::write_state_() { - float speed = this->state ? static_cast(this->speed) / static_cast(this->speed_count_) : 0.0f; - this->output_->set_level(speed); - + if (this->output_ != nullptr) { + float speed = this->state ? static_cast(this->speed) / static_cast(this->speed_count_) : 0.0f; + this->output_->set_level(speed); + } if (this->oscillating_ != nullptr) this->oscillating_->set_state(this->oscillating); if (this->direction_ != nullptr) diff --git a/esphome/components/speed/fan/speed_fan.h b/esphome/components/speed/fan/speed_fan.h index ca0fe20e2a..57436d298b 100644 --- a/esphome/components/speed/fan/speed_fan.h +++ b/esphome/components/speed/fan/speed_fan.h @@ -12,9 +12,10 @@ namespace speed { class SpeedFan : public Component, public fan::Fan { public: - SpeedFan(output::FloatOutput *output, int speed_count) : output_(output), speed_count_(speed_count) {} + SpeedFan(int speed_count) : speed_count_(speed_count) {} void setup() override; void dump_config() override; + void set_output(output::FloatOutput *output) { this->output_ = output; } void set_oscillating(output::BinaryOutput *oscillating) { this->oscillating_ = oscillating; } void set_direction(output::BinaryOutput *direction) { this->direction_ = direction; } void set_preset_modes(const std::set &presets) { this->preset_modes_ = presets; } @@ -24,7 +25,7 @@ class SpeedFan : public Component, public fan::Fan { void control(const fan::FanCall &call) override; void write_state_(); - output::FloatOutput *output_; + output::FloatOutput *output_{nullptr}; output::BinaryOutput *oscillating_{nullptr}; output::BinaryOutput *direction_{nullptr}; int speed_count_{}; From f3174c58bc5e5c13737bab74412db84e1c4e0edd Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Sun, 25 Feb 2024 10:26:35 -0800 Subject: [PATCH 067/189] fix throttle average nan handling (#6275) Co-authored-by: Samuel Sieb --- esphome/components/sensor/filter.cpp | 8 ++++++-- esphome/components/sensor/filter.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/esphome/components/sensor/filter.cpp b/esphome/components/sensor/filter.cpp index b5bef4930c..6d7acad7e0 100644 --- a/esphome/components/sensor/filter.cpp +++ b/esphome/components/sensor/filter.cpp @@ -252,7 +252,9 @@ ThrottleAverageFilter::ThrottleAverageFilter(uint32_t time_period) : time_period optional ThrottleAverageFilter::new_value(float value) { ESP_LOGVV(TAG, "ThrottleAverageFilter(%p)::new_value(value=%f)", this, value); - if (!std::isnan(value)) { + if (std::isnan(value)) { + this->have_nan_ = true; + } else { this->sum_ += value; this->n_++; } @@ -262,12 +264,14 @@ void ThrottleAverageFilter::setup() { this->set_interval("throttle_average", this->time_period_, [this]() { ESP_LOGVV(TAG, "ThrottleAverageFilter(%p)::interval(sum=%f, n=%i)", this, this->sum_, this->n_); if (this->n_ == 0) { - this->output(NAN); + if (this->have_nan_) + this->output(NAN); } else { this->output(this->sum_ / this->n_); this->sum_ = 0.0f; this->n_ = 0; } + this->have_nan_ = false; }); } float ThrottleAverageFilter::get_setup_priority() const { return setup_priority::HARDWARE; } diff --git a/esphome/components/sensor/filter.h b/esphome/components/sensor/filter.h index fa78f2fa46..1a08699d7b 100644 --- a/esphome/components/sensor/filter.h +++ b/esphome/components/sensor/filter.h @@ -245,6 +245,7 @@ class ThrottleAverageFilter : public Filter, public Component { uint32_t time_period_; float sum_{0.0f}; unsigned int n_{0}; + bool have_nan_{false}; }; using lambda_filter_t = std::function(float)>; From b1b8217713c4cfbbd01f1a373ef97e917758ada1 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Sun, 25 Feb 2024 12:28:52 -0600 Subject: [PATCH 068/189] Fix thermostat supplemental actions (#6282) --- .../thermostat/thermostat_climate.cpp | 28 +++++++++---------- .../thermostat/thermostat_climate.h | 28 +++++++++++-------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/esphome/components/thermostat/thermostat_climate.cpp b/esphome/components/thermostat/thermostat_climate.cpp index 40a29295f1..26be6ba53a 100644 --- a/esphome/components/thermostat/thermostat_climate.cpp +++ b/esphome/components/thermostat/thermostat_climate.cpp @@ -1,6 +1,5 @@ #include "thermostat_climate.h" #include "esphome/core/log.h" -#include namespace esphome { namespace thermostat { @@ -63,6 +62,15 @@ void ThermostatClimate::setup() { this->publish_state(); } +void ThermostatClimate::loop() { + for (auto &timer : this->timer_) { + if (timer.active && (timer.started + timer.time < millis())) { + timer.active = false; + timer.func(); + } + } +} + float ThermostatClimate::cool_deadband() { return this->cooling_deadband_; } float ThermostatClimate::cool_overrun() { return this->cooling_overrun_; } float ThermostatClimate::heat_deadband() { return this->heating_deadband_; } @@ -439,6 +447,7 @@ void ThermostatClimate::switch_to_action_(climate::ClimateAction action, bool pu this->start_timer_(thermostat::TIMER_FANNING_ON); trig_fan = this->fan_only_action_trigger_; } + this->cooling_max_runtime_exceeded_ = false; trig = this->cool_action_trigger_; ESP_LOGVV(TAG, "Switching to COOLING action"); action_ready = true; @@ -452,6 +461,7 @@ void ThermostatClimate::switch_to_action_(climate::ClimateAction action, bool pu this->start_timer_(thermostat::TIMER_FANNING_ON); trig_fan = this->fan_only_action_trigger_; } + this->heating_max_runtime_exceeded_ = false; trig = this->heat_action_trigger_; ESP_LOGVV(TAG, "Switching to HEATING action"); action_ready = true; @@ -752,15 +762,15 @@ bool ThermostatClimate::heating_action_ready_() { void ThermostatClimate::start_timer_(const ThermostatClimateTimerIndex timer_index) { if (this->timer_duration_(timer_index) > 0) { - this->set_timeout(this->timer_[timer_index].name, this->timer_duration_(timer_index), - this->timer_cbf_(timer_index)); + this->timer_[timer_index].started = millis(); this->timer_[timer_index].active = true; } } bool ThermostatClimate::cancel_timer_(ThermostatClimateTimerIndex timer_index) { + auto ret = this->timer_[timer_index].active; this->timer_[timer_index].active = false; - return this->cancel_timeout(this->timer_[timer_index].name); + return ret; } bool ThermostatClimate::timer_active_(ThermostatClimateTimerIndex timer_index) { @@ -777,7 +787,6 @@ std::function ThermostatClimate::timer_cbf_(ThermostatClimateTimerIndex void ThermostatClimate::cooling_max_run_time_timer_callback_() { ESP_LOGVV(TAG, "cooling_max_run_time timer expired"); - this->timer_[thermostat::TIMER_COOLING_MAX_RUN_TIME].active = false; this->cooling_max_runtime_exceeded_ = true; this->trigger_supplemental_action_(); this->switch_to_supplemental_action_(this->compute_supplemental_action_()); @@ -785,21 +794,18 @@ void ThermostatClimate::cooling_max_run_time_timer_callback_() { void ThermostatClimate::cooling_off_timer_callback_() { ESP_LOGVV(TAG, "cooling_off timer expired"); - this->timer_[thermostat::TIMER_COOLING_OFF].active = false; this->switch_to_action_(this->compute_action_()); this->switch_to_supplemental_action_(this->compute_supplemental_action_()); } void ThermostatClimate::cooling_on_timer_callback_() { ESP_LOGVV(TAG, "cooling_on timer expired"); - this->timer_[thermostat::TIMER_COOLING_ON].active = false; this->switch_to_action_(this->compute_action_()); this->switch_to_supplemental_action_(this->compute_supplemental_action_()); } void ThermostatClimate::fan_mode_timer_callback_() { ESP_LOGVV(TAG, "fan_mode timer expired"); - this->timer_[thermostat::TIMER_FAN_MODE].active = false; this->switch_to_fan_mode_(this->fan_mode.value_or(climate::CLIMATE_FAN_ON)); if (this->supports_fan_only_action_uses_fan_mode_timer_) this->switch_to_action_(this->compute_action_()); @@ -807,19 +813,16 @@ void ThermostatClimate::fan_mode_timer_callback_() { void ThermostatClimate::fanning_off_timer_callback_() { ESP_LOGVV(TAG, "fanning_off timer expired"); - this->timer_[thermostat::TIMER_FANNING_OFF].active = false; this->switch_to_action_(this->compute_action_()); } void ThermostatClimate::fanning_on_timer_callback_() { ESP_LOGVV(TAG, "fanning_on timer expired"); - this->timer_[thermostat::TIMER_FANNING_ON].active = false; this->switch_to_action_(this->compute_action_()); } void ThermostatClimate::heating_max_run_time_timer_callback_() { ESP_LOGVV(TAG, "heating_max_run_time timer expired"); - this->timer_[thermostat::TIMER_HEATING_MAX_RUN_TIME].active = false; this->heating_max_runtime_exceeded_ = true; this->trigger_supplemental_action_(); this->switch_to_supplemental_action_(this->compute_supplemental_action_()); @@ -827,21 +830,18 @@ void ThermostatClimate::heating_max_run_time_timer_callback_() { void ThermostatClimate::heating_off_timer_callback_() { ESP_LOGVV(TAG, "heating_off timer expired"); - this->timer_[thermostat::TIMER_HEATING_OFF].active = false; this->switch_to_action_(this->compute_action_()); this->switch_to_supplemental_action_(this->compute_supplemental_action_()); } void ThermostatClimate::heating_on_timer_callback_() { ESP_LOGVV(TAG, "heating_on timer expired"); - this->timer_[thermostat::TIMER_HEATING_ON].active = false; this->switch_to_action_(this->compute_action_()); this->switch_to_supplemental_action_(this->compute_supplemental_action_()); } void ThermostatClimate::idle_on_timer_callback_() { ESP_LOGVV(TAG, "idle_on timer expired"); - this->timer_[thermostat::TIMER_IDLE_ON].active = false; this->switch_to_action_(this->compute_action_()); this->switch_to_supplemental_action_(this->compute_supplemental_action_()); } diff --git a/esphome/components/thermostat/thermostat_climate.h b/esphome/components/thermostat/thermostat_climate.h index 559812a94f..50510cf070 100644 --- a/esphome/components/thermostat/thermostat_climate.h +++ b/esphome/components/thermostat/thermostat_climate.h @@ -1,10 +1,12 @@ #pragma once -#include "esphome/core/component.h" #include "esphome/core/automation.h" +#include "esphome/core/component.h" +#include "esphome/core/hal.h" #include "esphome/components/climate/climate.h" #include "esphome/components/sensor/sensor.h" +#include #include #include @@ -26,9 +28,9 @@ enum ThermostatClimateTimerIndex : size_t { enum OnBootRestoreFrom : size_t { MEMORY = 0, DEFAULT_PRESET = 1 }; struct ThermostatClimateTimer { - const std::string name; bool active; uint32_t time; + uint32_t started; std::function func; }; @@ -59,6 +61,7 @@ class ThermostatClimate : public climate::Climate, public Component { ThermostatClimate(); void setup() override; void dump_config() override; + void loop() override; void set_default_preset(const std::string &custom_preset); void set_default_preset(climate::ClimatePreset preset); @@ -441,16 +444,17 @@ class ThermostatClimate : public climate::Climate, public Component { /// Climate action timers std::vector timer_{ - {"cool_run", false, 0, std::bind(&ThermostatClimate::cooling_max_run_time_timer_callback_, this)}, - {"cool_off", false, 0, std::bind(&ThermostatClimate::cooling_off_timer_callback_, this)}, - {"cool_on", false, 0, std::bind(&ThermostatClimate::cooling_on_timer_callback_, this)}, - {"fan_mode", false, 0, std::bind(&ThermostatClimate::fan_mode_timer_callback_, this)}, - {"fan_off", false, 0, std::bind(&ThermostatClimate::fanning_off_timer_callback_, this)}, - {"fan_on", false, 0, std::bind(&ThermostatClimate::fanning_on_timer_callback_, this)}, - {"heat_run", false, 0, std::bind(&ThermostatClimate::heating_max_run_time_timer_callback_, this)}, - {"heat_off", false, 0, std::bind(&ThermostatClimate::heating_off_timer_callback_, this)}, - {"heat_on", false, 0, std::bind(&ThermostatClimate::heating_on_timer_callback_, this)}, - {"idle_on", false, 0, std::bind(&ThermostatClimate::idle_on_timer_callback_, this)}}; + {false, 0, 0, std::bind(&ThermostatClimate::cooling_max_run_time_timer_callback_, this)}, + {false, 0, 0, std::bind(&ThermostatClimate::cooling_off_timer_callback_, this)}, + {false, 0, 0, std::bind(&ThermostatClimate::cooling_on_timer_callback_, this)}, + {false, 0, 0, std::bind(&ThermostatClimate::fan_mode_timer_callback_, this)}, + {false, 0, 0, std::bind(&ThermostatClimate::fanning_off_timer_callback_, this)}, + {false, 0, 0, std::bind(&ThermostatClimate::fanning_on_timer_callback_, this)}, + {false, 0, 0, std::bind(&ThermostatClimate::heating_max_run_time_timer_callback_, this)}, + {false, 0, 0, std::bind(&ThermostatClimate::heating_off_timer_callback_, this)}, + {false, 0, 0, std::bind(&ThermostatClimate::heating_on_timer_callback_, this)}, + {false, 0, 0, std::bind(&ThermostatClimate::idle_on_timer_callback_, this)}, + }; /// The set of standard preset configurations this thermostat supports (Eg. AWAY, ECO, etc) std::map preset_config_{}; From badac933aea62ff9ca7b4fabfa9b0ad2971cc7c8 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Mon, 26 Feb 2024 07:52:25 +1300 Subject: [PATCH 069/189] Bump version to 2024.2.1 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 26cb0c5183..717401df27 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2024.2.0" +__version__ = "2024.2.1" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From a3fc1acdcb171ab36fe8874ab35485ff665897fd Mon Sep 17 00:00:00 2001 From: puuu Date: Tue, 27 Feb 2024 12:47:45 +0900 Subject: [PATCH 070/189] CSE7766: Fix energy calculation (#6286) Co-authored-by: DAVe3283 --- esphome/components/cse7766/cse7766.cpp | 36 ++++++++++---------------- esphome/components/cse7766/cse7766.h | 4 +-- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/esphome/components/cse7766/cse7766.cpp b/esphome/components/cse7766/cse7766.cpp index f482ba26c3..cdd4220e50 100644 --- a/esphome/components/cse7766/cse7766.cpp +++ b/esphome/components/cse7766/cse7766.cpp @@ -118,7 +118,7 @@ void CSE7766Component::parse_data_() { uint32_t power_coeff = this->get_24_bit_uint_(14); uint32_t power_cycle = this->get_24_bit_uint_(17); uint8_t adj = this->raw_data_[20]; - uint32_t cf_pulses = (this->raw_data_[21] << 8) + this->raw_data_[22]; + uint16_t cf_pulses = (this->raw_data_[21] << 8) + this->raw_data_[22]; bool have_power = adj & 0x10; bool have_current = adj & 0x20; @@ -132,8 +132,19 @@ void CSE7766Component::parse_data_() { } } + float energy = 0.0; + if (this->energy_sensor_ != nullptr) { + if (this->cf_pulses_last_ == 0 && !this->energy_sensor_->has_state()) { + this->cf_pulses_last_ = cf_pulses; + } + uint16_t cf_diff = cf_pulses - this->cf_pulses_last_; + this->cf_pulses_total_ += cf_diff; + this->cf_pulses_last_ = cf_pulses; + energy = this->cf_pulses_total_ * float(power_coeff) / 1000000.0f / 3600.0f; + this->energy_sensor_->publish_state(energy); + } + float power = 0.0f; - float energy = 0.0f; if (power_cycle_exceeds_range) { // Datasheet: power cycle exceeding range means active power is 0 if (this->power_sensor_ != nullptr) { @@ -144,27 +155,6 @@ void CSE7766Component::parse_data_() { if (this->power_sensor_ != nullptr) { this->power_sensor_->publish_state(power); } - - // Add CF pulses to the total energy only if we have Power coefficient to multiply by - - if (this->cf_pulses_last_ == 0) { - this->cf_pulses_last_ = cf_pulses; - } - - uint32_t cf_diff; - if (cf_pulses < this->cf_pulses_last_) { - cf_diff = cf_pulses + (0x10000 - this->cf_pulses_last_); - } else { - cf_diff = cf_pulses - this->cf_pulses_last_; - } - this->cf_pulses_last_ = cf_pulses; - - energy = cf_diff * float(power_coeff) / 1000000.0f / 3600.0f; - this->energy_total_ += energy; - if (this->energy_sensor_ != nullptr) - this->energy_sensor_->publish_state(this->energy_total_); - } else if ((this->energy_sensor_ != nullptr) && !this->energy_sensor_->has_state()) { - this->energy_sensor_->publish_state(0); } float current = 0.0f; diff --git a/esphome/components/cse7766/cse7766.h b/esphome/components/cse7766/cse7766.h index 3ab8d609bd..4d9ba7be74 100644 --- a/esphome/components/cse7766/cse7766.h +++ b/esphome/components/cse7766/cse7766.h @@ -30,8 +30,8 @@ class CSE7766Component : public Component, public uart::UARTDevice { sensor::Sensor *current_sensor_{nullptr}; sensor::Sensor *power_sensor_{nullptr}; sensor::Sensor *energy_sensor_{nullptr}; - float energy_total_{0.0f}; - uint32_t cf_pulses_last_{0}; + uint32_t cf_pulses_total_{0}; + uint16_t cf_pulses_last_{0}; }; } // namespace cse7766 From 1aab87b41c1d5a236a3dac63a096674aede19555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=9F=E9=87=8ESKY?= <87404327+FlyingFeng2021@users.noreply.github.com> Date: Mon, 4 Mar 2024 09:02:40 +0800 Subject: [PATCH 071/189] handling with the negative temperature in the sensor tmp102 (#6316) --- esphome/components/tmp102/tmp102.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/esphome/components/tmp102/tmp102.cpp b/esphome/components/tmp102/tmp102.cpp index f6bb9a05c0..7d92a28cf1 100644 --- a/esphome/components/tmp102/tmp102.cpp +++ b/esphome/components/tmp102/tmp102.cpp @@ -28,7 +28,7 @@ void TMP102Component::dump_config() { } void TMP102Component::update() { - uint16_t raw_temperature; + int16_t raw_temperature; if (this->write(&TMP102_REGISTER_TEMPERATURE, 1) != i2c::ERROR_OK) { this->status_set_warning(); return; @@ -39,7 +39,9 @@ void TMP102Component::update() { return; } raw_temperature = i2c::i2ctohs(raw_temperature); - + if (raw_temperature & 0x8000) { + raw_temperature |= 0xF000; + } raw_temperature = raw_temperature >> 4; float temperature = raw_temperature * TMP102_CONVERSION_FACTOR; ESP_LOGD(TAG, "Got Temperature=%.1f°C", temperature); From 63cce916e2804f8bfe8f1cb66340a151869fcc72 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Sun, 3 Mar 2024 23:33:39 -0800 Subject: [PATCH 072/189] fix tmp102 negative calculation (#6320) --- esphome/components/tmp102/tmp102.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/esphome/components/tmp102/tmp102.cpp b/esphome/components/tmp102/tmp102.cpp index 7d92a28cf1..be60a2d8d4 100644 --- a/esphome/components/tmp102/tmp102.cpp +++ b/esphome/components/tmp102/tmp102.cpp @@ -39,9 +39,6 @@ void TMP102Component::update() { return; } raw_temperature = i2c::i2ctohs(raw_temperature); - if (raw_temperature & 0x8000) { - raw_temperature |= 0xF000; - } raw_temperature = raw_temperature >> 4; float temperature = raw_temperature * TMP102_CONVERSION_FACTOR; ESP_LOGD(TAG, "Got Temperature=%.1f°C", temperature); From 37d2b3c7977a4ccbec59726ca7549cb776661455 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:09:45 +1300 Subject: [PATCH 073/189] Merge pull request from GHSA-9p43-hj5j-96h5 --- esphome/dashboard/web_server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/esphome/dashboard/web_server.py b/esphome/dashboard/web_server.py index 8bcc8efa0b..de3fe6e8ae 100644 --- a/esphome/dashboard/web_server.py +++ b/esphome/dashboard/web_server.py @@ -820,6 +820,7 @@ class EditRequestHandler(BaseHandler): None, self._read_file, filename, configuration ) if content is not None: + self.set_header("Content-Type", "application/yaml") self.write(content) def _read_file(self, filename: str, configuration: str) -> bytes | None: From b0a25401f74e718bb947817781ff3c3d5c6a62ac Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Tue, 5 Mar 2024 10:40:27 -0800 Subject: [PATCH 074/189] auto load output for now (#6309) Co-authored-by: Samuel Sieb --- esphome/components/speed/fan/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esphome/components/speed/fan/__init__.py b/esphome/components/speed/fan/__init__.py index 221e67d6c7..4527e1eed1 100644 --- a/esphome/components/speed/fan/__init__.py +++ b/esphome/components/speed/fan/__init__.py @@ -14,6 +14,8 @@ from esphome.const import ( from .. import speed_ns +AUTO_LOAD = ["output"] + SpeedFan = speed_ns.class_("SpeedFan", cg.Component, fan.Fan) CONFIG_SCHEMA = fan.FAN_SCHEMA.extend( From f39dc49f49adf2e5885c41026673f6f87a08af73 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 6 Mar 2024 07:41:18 +1300 Subject: [PATCH 075/189] Add wake word phrase to voice assistant start command (#6290) --- esphome/components/api/api.proto | 1 + esphome/components/api/api_pb2.cpp | 9 +++++++++ esphome/components/api/api_pb2.h | 1 + .../components/micro_wake_word/micro_wake_word.cpp | 2 +- esphome/components/voice_assistant/__init__.py | 6 ++++++ .../components/voice_assistant/voice_assistant.cpp | 2 ++ esphome/components/voice_assistant/voice_assistant.h | 11 ++++++++++- 7 files changed, 30 insertions(+), 2 deletions(-) diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index 04db649aef..5557c56240 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -1449,6 +1449,7 @@ message VoiceAssistantRequest { string conversation_id = 2; uint32 flags = 3; VoiceAssistantAudioSettings audio_settings = 4; + string wake_word_phrase = 5; } message VoiceAssistantResponse { diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index f81bf04e99..dccebf0d5d 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -6594,6 +6594,10 @@ bool VoiceAssistantRequest::decode_length(uint32_t field_id, ProtoLengthDelimite this->audio_settings = value.as_message(); return true; } + case 5: { + this->wake_word_phrase = value.as_string(); + return true; + } default: return false; } @@ -6603,6 +6607,7 @@ void VoiceAssistantRequest::encode(ProtoWriteBuffer buffer) const { buffer.encode_string(2, this->conversation_id); buffer.encode_uint32(3, this->flags); buffer.encode_message(4, this->audio_settings); + buffer.encode_string(5, this->wake_word_phrase); } #ifdef HAS_PROTO_MESSAGE_DUMP void VoiceAssistantRequest::dump_to(std::string &out) const { @@ -6624,6 +6629,10 @@ void VoiceAssistantRequest::dump_to(std::string &out) const { out.append(" audio_settings: "); this->audio_settings.dump_to(out); out.append("\n"); + + out.append(" wake_word_phrase: "); + out.append("'").append(this->wake_word_phrase).append("'"); + out.append("\n"); out.append("}"); } #endif diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index 02fc7b88f8..2854a2e9c1 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -1701,6 +1701,7 @@ class VoiceAssistantRequest : public ProtoMessage { std::string conversation_id{}; uint32_t flags{0}; VoiceAssistantAudioSettings audio_settings{}; + std::string wake_word_phrase{}; void encode(ProtoWriteBuffer buffer) const override; #ifdef HAS_PROTO_MESSAGE_DUMP void dump_to(std::string &out) const override; diff --git a/esphome/components/micro_wake_word/micro_wake_word.cpp b/esphome/components/micro_wake_word/micro_wake_word.cpp index f0b3d55a9d..7321e5b05b 100644 --- a/esphome/components/micro_wake_word/micro_wake_word.cpp +++ b/esphome/components/micro_wake_word/micro_wake_word.cpp @@ -134,7 +134,7 @@ void MicroWakeWord::loop() { this->set_state_(State::IDLE); if (this->detected_) { this->detected_ = false; - this->wake_word_detected_trigger_->trigger(""); + this->wake_word_detected_trigger_->trigger(this->wake_word_); } } break; diff --git a/esphome/components/voice_assistant/__init__.py b/esphome/components/voice_assistant/__init__.py index b21a5b27da..17bdffd9da 100644 --- a/esphome/components/voice_assistant/__init__.py +++ b/esphome/components/voice_assistant/__init__.py @@ -42,6 +42,8 @@ CONF_AUTO_GAIN = "auto_gain" CONF_NOISE_SUPPRESSION_LEVEL = "noise_suppression_level" CONF_VOLUME_MULTIPLIER = "volume_multiplier" +CONF_WAKE_WORD = "wake_word" + voice_assistant_ns = cg.esphome_ns.namespace("voice_assistant") VoiceAssistant = voice_assistant_ns.class_("VoiceAssistant", cg.Component) @@ -285,6 +287,7 @@ VOICE_ASSISTANT_ACTION_SCHEMA = cv.Schema({cv.GenerateID(): cv.use_id(VoiceAssis VOICE_ASSISTANT_ACTION_SCHEMA.extend( { cv.Optional(CONF_SILENCE_DETECTION, default=True): cv.boolean, + cv.Optional(CONF_WAKE_WORD): cv.templatable(cv.string), } ), ) @@ -293,6 +296,9 @@ async def voice_assistant_listen_to_code(config, action_id, template_arg, args): await cg.register_parented(var, config[CONF_ID]) if CONF_SILENCE_DETECTION in config: cg.add(var.set_silence_detection(config[CONF_SILENCE_DETECTION])) + if wake_word := config.get(CONF_WAKE_WORD): + templ = await cg.templatable(wake_word, args, cg.std_string) + cg.add(var.set_wake_word(templ)) return var diff --git a/esphome/components/voice_assistant/voice_assistant.cpp b/esphome/components/voice_assistant/voice_assistant.cpp index 260605c0b4..49b8fdc959 100644 --- a/esphome/components/voice_assistant/voice_assistant.cpp +++ b/esphome/components/voice_assistant/voice_assistant.cpp @@ -215,6 +215,8 @@ void VoiceAssistant::loop() { msg.conversation_id = this->conversation_id_; msg.flags = flags; msg.audio_settings = audio_settings; + msg.wake_word_phrase = this->wake_word_; + this->wake_word_ = ""; if (this->api_client_ == nullptr || !this->api_client_->send_voice_assistant_request(msg)) { ESP_LOGW(TAG, "Could not request start"); diff --git a/esphome/components/voice_assistant/voice_assistant.h b/esphome/components/voice_assistant/voice_assistant.h index f0ee793f53..14352bf3ae 100644 --- a/esphome/components/voice_assistant/voice_assistant.h +++ b/esphome/components/voice_assistant/voice_assistant.h @@ -124,6 +124,8 @@ class VoiceAssistant : public Component { void client_subscription(api::APIConnection *client, bool subscribe); api::APIConnection *get_api_connection() const { return this->api_client_; } + void set_wake_word(const std::string &wake_word) { this->wake_word_ = wake_word; } + protected: int read_microphone_(); void set_state_(State state); @@ -175,6 +177,8 @@ class VoiceAssistant : public Component { std::string conversation_id_{""}; + std::string wake_word_{""}; + HighFrequencyLoopRequester high_freq_; #ifdef USE_ESP_ADF @@ -200,8 +204,13 @@ class VoiceAssistant : public Component { }; template class StartAction : public Action, public Parented { + TEMPLATABLE_VALUE(std::string, wake_word); + public: - void play(Ts... x) override { this->parent_->request_start(false, this->silence_detection_); } + void play(Ts... x) override { + this->parent_->set_wake_word(this->wake_word_.value(x...)); + this->parent_->request_start(false, this->silence_detection_); + } void set_silence_detection(bool silence_detection) { this->silence_detection_ = silence_detection; } From e2b197dc2c4f4a2c353ecdc0962a6ca91bb97ecb Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 6 Mar 2024 09:34:48 +1300 Subject: [PATCH 076/189] Bump version to 2024.2.2 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 717401df27..a305199585 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2024.2.1" +__version__ = "2024.2.2" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From 430ee43b930cd08f061ade071873a1e00047fbf4 Mon Sep 17 00:00:00 2001 From: Fabio Pugliese Ornellas Date: Mon, 11 Mar 2024 18:17:47 +0000 Subject: [PATCH 077/189] Mhz19 warmup (#6214) --- esphome/components/mhz19/mhz19.cpp | 10 ++++++++++ esphome/components/mhz19/mhz19.h | 2 ++ esphome/components/mhz19/sensor.py | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/esphome/components/mhz19/mhz19.cpp b/esphome/components/mhz19/mhz19.cpp index db3ad50851..019f6cee51 100644 --- a/esphome/components/mhz19/mhz19.cpp +++ b/esphome/components/mhz19/mhz19.cpp @@ -29,6 +29,14 @@ void MHZ19Component::setup() { } void MHZ19Component::update() { + uint32_t now_ms = millis(); + uint32_t warmup_ms = this->warmup_seconds_ * 1000; + if (now_ms < warmup_ms) { + ESP_LOGW(TAG, "MHZ19 warming up, %ds left", (warmup_ms - now_ms) / 1000); + this->status_set_warning(); + return; + } + uint8_t response[MHZ19_RESPONSE_LENGTH]; if (!this->mhz19_write_command_(MHZ19_COMMAND_GET_PPM, response)) { ESP_LOGW(TAG, "Reading data from MHZ19 failed!"); @@ -101,6 +109,8 @@ void MHZ19Component::dump_config() { } else if (this->abc_boot_logic_ == MHZ19_ABC_DISABLED) { ESP_LOGCONFIG(TAG, " Automatic baseline calibration disabled on boot"); } + + ESP_LOGCONFIG(TAG, " Warmup seconds: %ds", this->warmup_seconds_); } } // namespace mhz19 diff --git a/esphome/components/mhz19/mhz19.h b/esphome/components/mhz19/mhz19.h index 151351be4c..ec38f2cd2f 100644 --- a/esphome/components/mhz19/mhz19.h +++ b/esphome/components/mhz19/mhz19.h @@ -25,6 +25,7 @@ class MHZ19Component : public PollingComponent, public uart::UARTDevice { void set_temperature_sensor(sensor::Sensor *temperature_sensor) { temperature_sensor_ = temperature_sensor; } void set_co2_sensor(sensor::Sensor *co2_sensor) { co2_sensor_ = co2_sensor; } void set_abc_enabled(bool abc_enabled) { abc_boot_logic_ = abc_enabled ? MHZ19_ABC_ENABLED : MHZ19_ABC_DISABLED; } + void set_warmup_seconds(uint32_t seconds) { warmup_seconds_ = seconds; } protected: bool mhz19_write_command_(const uint8_t *command, uint8_t *response); @@ -32,6 +33,7 @@ class MHZ19Component : public PollingComponent, public uart::UARTDevice { sensor::Sensor *temperature_sensor_{nullptr}; sensor::Sensor *co2_sensor_{nullptr}; MHZ19ABCLogic abc_boot_logic_{MHZ19_ABC_NONE}; + uint32_t warmup_seconds_; }; template class MHZ19CalibrateZeroAction : public Action { diff --git a/esphome/components/mhz19/sensor.py b/esphome/components/mhz19/sensor.py index 0081f42952..3956727981 100644 --- a/esphome/components/mhz19/sensor.py +++ b/esphome/components/mhz19/sensor.py @@ -18,6 +18,7 @@ from esphome.const import ( DEPENDENCIES = ["uart"] CONF_AUTOMATIC_BASELINE_CALIBRATION = "automatic_baseline_calibration" +CONF_WARMUP_TIME = "warmup_time" mhz19_ns = cg.esphome_ns.namespace("mhz19") MHZ19Component = mhz19_ns.class_("MHZ19Component", cg.PollingComponent, uart.UARTDevice) @@ -45,6 +46,9 @@ CONFIG_SCHEMA = ( state_class=STATE_CLASS_MEASUREMENT, ), cv.Optional(CONF_AUTOMATIC_BASELINE_CALIBRATION): cv.boolean, + cv.Optional( + CONF_WARMUP_TIME, default="75s" + ): cv.positive_time_period_seconds, } ) .extend(cv.polling_component_schema("60s")) @@ -68,6 +72,8 @@ async def to_code(config): if CONF_AUTOMATIC_BASELINE_CALIBRATION in config: cg.add(var.set_abc_enabled(config[CONF_AUTOMATIC_BASELINE_CALIBRATION])) + cg.add(var.set_warmup_seconds(config[CONF_WARMUP_TIME])) + CALIBRATION_ACTION_SCHEMA = maybe_simple_id( { From cd89c38a079f4da8f21fe8e8a541fcdcf862d156 Mon Sep 17 00:00:00 2001 From: Mike La Spina Date: Mon, 11 Mar 2024 13:23:13 -0500 Subject: [PATCH 078/189] Refactor ATM90E32 to reduce blocking time and improve accuracy. (#5670) Co-authored-by: descipher <120155735+GelidusResearch@users.noreply.github.com> --- esphome/components/atm90e26/atm90e26.cpp | 18 +- esphome/components/atm90e32/atm90e32.cpp | 566 ++++++++++++--------- esphome/components/atm90e32/atm90e32.h | 88 +++- esphome/components/atm90e32/atm90e32_reg.h | 15 + esphome/components/atm90e32/sensor.py | 51 +- 5 files changed, 473 insertions(+), 265 deletions(-) diff --git a/esphome/components/atm90e26/atm90e26.cpp b/esphome/components/atm90e26/atm90e26.cpp index 42a52c4ccf..6743f1a442 100644 --- a/esphome/components/atm90e26/atm90e26.cpp +++ b/esphome/components/atm90e26/atm90e26.cpp @@ -117,7 +117,7 @@ void ATM90E26Component::setup() { this->write16_(ATM90E26_REGISTER_ADJSTART, 0x8765); // Checks correctness of 31-3A registers and starts normal measurement if ok - uint16_t sys_status = this->read16_(ATM90E26_REGISTER_SYSSTATUS); + const uint16_t sys_status = this->read16_(ATM90E26_REGISTER_SYSSTATUS); if (sys_status & 0xC000) { // Checksum 1 Error ESP_LOGW(TAG, "Could not initialize ATM90E26 IC: CS1 was incorrect, expected: 0x%04X", @@ -177,27 +177,27 @@ void ATM90E26Component::write16_(uint8_t a_register, uint16_t val) { } float ATM90E26Component::get_line_current_() { - uint16_t current = this->read16_(ATM90E26_REGISTER_IRMS); + const uint16_t current = this->read16_(ATM90E26_REGISTER_IRMS); return current / 1000.0f; } float ATM90E26Component::get_line_voltage_() { - uint16_t voltage = this->read16_(ATM90E26_REGISTER_URMS); + const uint16_t voltage = this->read16_(ATM90E26_REGISTER_URMS); return voltage / 100.0f; } float ATM90E26Component::get_active_power_() { - int16_t val = this->read16_(ATM90E26_REGISTER_PMEAN); // two's complement + const int16_t val = this->read16_(ATM90E26_REGISTER_PMEAN); // two's complement return (float) val; } float ATM90E26Component::get_reactive_power_() { - int16_t val = this->read16_(ATM90E26_REGISTER_QMEAN); // two's complement + const int16_t val = this->read16_(ATM90E26_REGISTER_QMEAN); // two's complement return (float) val; } float ATM90E26Component::get_power_factor_() { - uint16_t val = this->read16_(ATM90E26_REGISTER_POWERF); // signed + const uint16_t val = this->read16_(ATM90E26_REGISTER_POWERF); // signed if (val & 0x8000) { return -(val & 0x7FF) / 1000.0f; } else { @@ -206,7 +206,7 @@ float ATM90E26Component::get_power_factor_() { } float ATM90E26Component::get_forward_active_energy_() { - uint16_t val = this->read16_(ATM90E26_REGISTER_APENERGY); + const uint16_t val = this->read16_(ATM90E26_REGISTER_APENERGY); if ((UINT32_MAX - this->cumulative_forward_active_energy_) > val) { this->cumulative_forward_active_energy_ += val; } else { @@ -217,7 +217,7 @@ float ATM90E26Component::get_forward_active_energy_() { } float ATM90E26Component::get_reverse_active_energy_() { - uint16_t val = this->read16_(ATM90E26_REGISTER_ANENERGY); + const uint16_t val = this->read16_(ATM90E26_REGISTER_ANENERGY); if (UINT32_MAX - this->cumulative_reverse_active_energy_ > val) { this->cumulative_reverse_active_energy_ += val; } else { @@ -227,7 +227,7 @@ float ATM90E26Component::get_reverse_active_energy_() { } float ATM90E26Component::get_frequency_() { - uint16_t freq = this->read16_(ATM90E26_REGISTER_FREQ); + const uint16_t freq = this->read16_(ATM90E26_REGISTER_FREQ); return freq / 100.0f; } diff --git a/esphome/components/atm90e32/atm90e32.cpp b/esphome/components/atm90e32/atm90e32.cpp index e38fd3866a..e27459b18a 100644 --- a/esphome/components/atm90e32/atm90e32.cpp +++ b/esphome/components/atm90e32/atm90e32.cpp @@ -7,82 +7,128 @@ namespace esphome { namespace atm90e32 { static const char *const TAG = "atm90e32"; +void ATM90E32Component::loop() { + if (this->get_publish_interval_flag_()) { + this->set_publish_interval_flag_(false); + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].voltage_sensor_ != nullptr) { + this->phase_[phase].voltage_ = this->get_phase_voltage_(phase); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].current_sensor_ != nullptr) { + this->phase_[phase].current_ = this->get_phase_current_(phase); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].power_sensor_ != nullptr) { + this->phase_[phase].active_power_ = this->get_phase_active_power_(phase); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].power_factor_sensor_ != nullptr) { + this->phase_[phase].power_factor_ = this->get_phase_power_factor_(phase); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].reactive_power_sensor_ != nullptr) { + this->phase_[phase].reactive_power_ = this->get_phase_reactive_power_(phase); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].forward_active_energy_sensor_ != nullptr) { + this->phase_[phase].forward_active_energy_ = this->get_phase_forward_active_energy_(phase); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].reverse_active_energy_sensor_ != nullptr) { + this->phase_[phase].reverse_active_energy_ = this->get_phase_reverse_active_energy_(phase); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].phase_angle_sensor_ != nullptr) { + this->phase_[phase].phase_angle_ = this->get_phase_angle_(phase); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].harmonic_active_power_sensor_ != nullptr) { + this->phase_[phase].harmonic_active_power_ = this->get_phase_harmonic_active_power_(phase); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].peak_current_sensor_ != nullptr) { + this->phase_[phase].peak_current_ = this->get_phase_peak_current_(phase); + } + } + // After the local store in collected we can publish them trusting they are withing +-1 haardware sampling + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].voltage_sensor_ != nullptr) { + this->phase_[phase].voltage_sensor_->publish_state(this->get_local_phase_voltage_(phase)); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].current_sensor_ != nullptr) { + this->phase_[phase].current_sensor_->publish_state(this->get_local_phase_current_(phase)); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].power_sensor_ != nullptr) { + this->phase_[phase].power_sensor_->publish_state(this->get_local_phase_active_power_(phase)); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].power_factor_sensor_ != nullptr) { + this->phase_[phase].power_factor_sensor_->publish_state(this->get_local_phase_power_factor_(phase)); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].reactive_power_sensor_ != nullptr) { + this->phase_[phase].reactive_power_sensor_->publish_state(this->get_local_phase_reactive_power_(phase)); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].forward_active_energy_sensor_ != nullptr) { + this->phase_[phase].forward_active_energy_sensor_->publish_state( + this->get_local_phase_forward_active_energy_(phase)); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].reverse_active_energy_sensor_ != nullptr) { + this->phase_[phase].reverse_active_energy_sensor_->publish_state( + this->get_local_phase_reverse_active_energy_(phase)); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].phase_angle_sensor_ != nullptr) { + this->phase_[phase].phase_angle_sensor_->publish_state(this->get_local_phase_angle_(phase)); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].harmonic_active_power_sensor_ != nullptr) { + this->phase_[phase].harmonic_active_power_sensor_->publish_state( + this->get_local_phase_harmonic_active_power_(phase)); + } + } + for (uint8_t phase = 0; phase < 3; phase++) { + if (this->phase_[phase].peak_current_sensor_ != nullptr) { + this->phase_[phase].peak_current_sensor_->publish_state(this->get_local_phase_peak_current_(phase)); + } + } + if (this->freq_sensor_ != nullptr) { + this->freq_sensor_->publish_state(this->get_frequency_()); + } + if (this->chip_temperature_sensor_ != nullptr) { + this->chip_temperature_sensor_->publish_state(this->get_chip_temperature_()); + } + } +} void ATM90E32Component::update() { if (this->read16_(ATM90E32_REGISTER_METEREN) != 1) { this->status_set_warning(); return; } - - if (this->phase_[0].voltage_sensor_ != nullptr) { - this->phase_[0].voltage_sensor_->publish_state(this->get_line_voltage_a_()); - } - if (this->phase_[1].voltage_sensor_ != nullptr) { - this->phase_[1].voltage_sensor_->publish_state(this->get_line_voltage_b_()); - } - if (this->phase_[2].voltage_sensor_ != nullptr) { - this->phase_[2].voltage_sensor_->publish_state(this->get_line_voltage_c_()); - } - if (this->phase_[0].current_sensor_ != nullptr) { - this->phase_[0].current_sensor_->publish_state(this->get_line_current_a_()); - } - if (this->phase_[1].current_sensor_ != nullptr) { - this->phase_[1].current_sensor_->publish_state(this->get_line_current_b_()); - } - if (this->phase_[2].current_sensor_ != nullptr) { - this->phase_[2].current_sensor_->publish_state(this->get_line_current_c_()); - } - if (this->phase_[0].power_sensor_ != nullptr) { - this->phase_[0].power_sensor_->publish_state(this->get_active_power_a_()); - } - if (this->phase_[1].power_sensor_ != nullptr) { - this->phase_[1].power_sensor_->publish_state(this->get_active_power_b_()); - } - if (this->phase_[2].power_sensor_ != nullptr) { - this->phase_[2].power_sensor_->publish_state(this->get_active_power_c_()); - } - if (this->phase_[0].reactive_power_sensor_ != nullptr) { - this->phase_[0].reactive_power_sensor_->publish_state(this->get_reactive_power_a_()); - } - if (this->phase_[1].reactive_power_sensor_ != nullptr) { - this->phase_[1].reactive_power_sensor_->publish_state(this->get_reactive_power_b_()); - } - if (this->phase_[2].reactive_power_sensor_ != nullptr) { - this->phase_[2].reactive_power_sensor_->publish_state(this->get_reactive_power_c_()); - } - if (this->phase_[0].power_factor_sensor_ != nullptr) { - this->phase_[0].power_factor_sensor_->publish_state(this->get_power_factor_a_()); - } - if (this->phase_[1].power_factor_sensor_ != nullptr) { - this->phase_[1].power_factor_sensor_->publish_state(this->get_power_factor_b_()); - } - if (this->phase_[2].power_factor_sensor_ != nullptr) { - this->phase_[2].power_factor_sensor_->publish_state(this->get_power_factor_c_()); - } - if (this->phase_[0].forward_active_energy_sensor_ != nullptr) { - this->phase_[0].forward_active_energy_sensor_->publish_state(this->get_forward_active_energy_a_()); - } - if (this->phase_[1].forward_active_energy_sensor_ != nullptr) { - this->phase_[1].forward_active_energy_sensor_->publish_state(this->get_forward_active_energy_b_()); - } - if (this->phase_[2].forward_active_energy_sensor_ != nullptr) { - this->phase_[2].forward_active_energy_sensor_->publish_state(this->get_forward_active_energy_c_()); - } - if (this->phase_[0].reverse_active_energy_sensor_ != nullptr) { - this->phase_[0].reverse_active_energy_sensor_->publish_state(this->get_reverse_active_energy_a_()); - } - if (this->phase_[1].reverse_active_energy_sensor_ != nullptr) { - this->phase_[1].reverse_active_energy_sensor_->publish_state(this->get_reverse_active_energy_b_()); - } - if (this->phase_[2].reverse_active_energy_sensor_ != nullptr) { - this->phase_[2].reverse_active_energy_sensor_->publish_state(this->get_reverse_active_energy_c_()); - } - if (this->freq_sensor_ != nullptr) { - this->freq_sensor_->publish_state(this->get_frequency_()); - } - if (this->chip_temperature_sensor_ != nullptr) { - this->chip_temperature_sensor_->publish_state(this->get_chip_temperature_()); - } + this->set_publish_interval_flag_(true); this->status_clear_warning(); } @@ -101,29 +147,51 @@ void ATM90E32Component::setup() { } this->write16_(ATM90E32_REGISTER_SOFTRESET, 0x789A); // Perform soft reset + delay(6); // Wait for the minimum 5ms + 1ms this->write16_(ATM90E32_REGISTER_CFGREGACCEN, 0x55AA); // enable register config access - this->write16_(ATM90E32_REGISTER_METEREN, 0x0001); // Enable Metering - if (this->read16_(ATM90E32_REGISTER_LASTSPIDATA) != 0x0001) { + if (this->read16_(ATM90E32_REGISTER_LASTSPIDATA) != 0x55AA) { ESP_LOGW(TAG, "Could not initialize ATM90E32 IC, check SPI settings"); this->mark_failed(); return; } - this->write16_(ATM90E32_REGISTER_PLCONSTH, 0x0861); // PL Constant MSB (default) = 140625000 - this->write16_(ATM90E32_REGISTER_PLCONSTL, 0xC468); // PL Constant LSB (default) - this->write16_(ATM90E32_REGISTER_ZXCONFIG, 0xD654); // ZX2, ZX1, ZX0 pin config - this->write16_(ATM90E32_REGISTER_MMODE0, mmode0); // Mode Config (frequency set in main program) - this->write16_(ATM90E32_REGISTER_MMODE1, pga_gain_); // PGA Gain Configuration for Current Channels - this->write16_(ATM90E32_REGISTER_PSTARTTH, 0x1D4C); // All Active Startup Power Threshold - 0.02A/0.00032 = 7500 - this->write16_(ATM90E32_REGISTER_QSTARTTH, 0x1D4C); // All Reactive Startup Power Threshold - 50% - this->write16_(ATM90E32_REGISTER_PPHASETH, 0x02EE); // Each Phase Active Phase Threshold - 0.002A/0.00032 = 750 - this->write16_(ATM90E32_REGISTER_QPHASETH, 0x02EE); // Each phase Reactive Phase Threshold - 10% - this->write16_(ATM90E32_REGISTER_UGAINA, this->phase_[0].volt_gain_); // A Voltage rms gain - this->write16_(ATM90E32_REGISTER_IGAINA, this->phase_[0].ct_gain_); // A line current gain - this->write16_(ATM90E32_REGISTER_UGAINB, this->phase_[1].volt_gain_); // B Voltage rms gain - this->write16_(ATM90E32_REGISTER_IGAINB, this->phase_[1].ct_gain_); // B line current gain - this->write16_(ATM90E32_REGISTER_UGAINC, this->phase_[2].volt_gain_); // C Voltage rms gain - this->write16_(ATM90E32_REGISTER_IGAINC, this->phase_[2].ct_gain_); // C line current gain - this->write16_(ATM90E32_REGISTER_CFGREGACCEN, 0x0000); // end configuration + + this->write16_(ATM90E32_REGISTER_METEREN, 0x0001); // Enable Metering + this->write16_(ATM90E32_REGISTER_SAGPEAKDETCFG, 0xFF3F); // Peak Detector time ms (15:8), Sag Period ms (7:0) + this->write16_(ATM90E32_REGISTER_PLCONSTH, 0x0861); // PL Constant MSB (default) = 140625000 + this->write16_(ATM90E32_REGISTER_PLCONSTL, 0xC468); // PL Constant LSB (default) + this->write16_(ATM90E32_REGISTER_ZXCONFIG, 0xD654); // ZX2, ZX1, ZX0 pin config + this->write16_(ATM90E32_REGISTER_MMODE0, mmode0); // Mode Config (frequency set in main program) + this->write16_(ATM90E32_REGISTER_MMODE1, pga_gain_); // PGA Gain Configuration for Current Channels + this->write16_(ATM90E32_REGISTER_PSTARTTH, 0x1D4C); // All Active Startup Power Threshold - 0.02A/0.00032 = 7500 + this->write16_(ATM90E32_REGISTER_QSTARTTH, 0x1D4C); // All Reactive Startup Power Threshold - 50% + this->write16_(ATM90E32_REGISTER_SSTARTTH, 0x1D4C); // All Reactive Startup Power Threshold - 50% + this->write16_(ATM90E32_REGISTER_PPHASETH, 0x02EE); // Each Phase Active Phase Threshold - 0.002A/0.00032 = 750 + this->write16_(ATM90E32_REGISTER_QPHASETH, 0x02EE); // Each phase Reactive Phase Threshold - 10% + // Setup voltage and current calibration offsets for PHASE A + this->phase_[PHASEA].voltage_offset_ = calibrate_voltage_offset_phase(PHASEA); + this->write16_(ATM90E32_REGISTER_UOFFSETA, this->phase_[PHASEA].voltage_offset_); // A Voltage offset + this->phase_[PHASEA].current_offset_ = calibrate_current_offset_phase(PHASEA); + this->write16_(ATM90E32_REGISTER_IOFFSETA, this->phase_[PHASEA].current_offset_); // A Current offset + // Setup voltage and current gain for PHASE A + this->write16_(ATM90E32_REGISTER_UGAINA, this->phase_[PHASEA].voltage_gain_); // A Voltage rms gain + this->write16_(ATM90E32_REGISTER_IGAINA, this->phase_[PHASEA].ct_gain_); // A line current gain + // Setup voltage and current calibration offsets for PHASE B + this->phase_[PHASEB].voltage_offset_ = calibrate_voltage_offset_phase(PHASEB); + this->write16_(ATM90E32_REGISTER_UOFFSETB, this->phase_[PHASEB].voltage_offset_); // B Voltage offset + this->phase_[PHASEB].current_offset_ = calibrate_current_offset_phase(PHASEB); + this->write16_(ATM90E32_REGISTER_IOFFSETB, this->phase_[PHASEB].current_offset_); // B Current offset + // Setup voltage and current gain for PHASE B + this->write16_(ATM90E32_REGISTER_UGAINB, this->phase_[PHASEB].voltage_gain_); // B Voltage rms gain + this->write16_(ATM90E32_REGISTER_IGAINB, this->phase_[PHASEB].ct_gain_); // B line current gain + // Setup voltage and current calibration offsets for PHASE C + this->phase_[PHASEC].voltage_offset_ = calibrate_voltage_offset_phase(PHASEC); + this->write16_(ATM90E32_REGISTER_UOFFSETC, this->phase_[PHASEC].voltage_offset_); // C Voltage offset + this->phase_[PHASEC].current_offset_ = calibrate_current_offset_phase(PHASEC); + this->write16_(ATM90E32_REGISTER_IOFFSETC, this->phase_[PHASEC].current_offset_); // C Current offset + // Setup voltage and current gain for PHASE C + this->write16_(ATM90E32_REGISTER_UGAINC, this->phase_[PHASEC].voltage_gain_); // C Voltage rms gain + this->write16_(ATM90E32_REGISTER_IGAINC, this->phase_[PHASEC].ct_gain_); // C line current gain + this->write16_(ATM90E32_REGISTER_CFGREGACCEN, 0x0000); // end configuration } void ATM90E32Component::dump_config() { @@ -133,43 +201,54 @@ void ATM90E32Component::dump_config() { ESP_LOGE(TAG, "Communication with ATM90E32 failed!"); } LOG_UPDATE_INTERVAL(this); - LOG_SENSOR(" ", "Voltage A", this->phase_[0].voltage_sensor_); - LOG_SENSOR(" ", "Current A", this->phase_[0].current_sensor_); - LOG_SENSOR(" ", "Power A", this->phase_[0].power_sensor_); - LOG_SENSOR(" ", "Reactive Power A", this->phase_[0].reactive_power_sensor_); - LOG_SENSOR(" ", "PF A", this->phase_[0].power_factor_sensor_); - LOG_SENSOR(" ", "Active Forward Energy A", this->phase_[0].forward_active_energy_sensor_); - LOG_SENSOR(" ", "Active Reverse Energy A", this->phase_[0].reverse_active_energy_sensor_); - LOG_SENSOR(" ", "Voltage B", this->phase_[1].voltage_sensor_); - LOG_SENSOR(" ", "Current B", this->phase_[1].current_sensor_); - LOG_SENSOR(" ", "Power B", this->phase_[1].power_sensor_); - LOG_SENSOR(" ", "Reactive Power B", this->phase_[1].reactive_power_sensor_); - LOG_SENSOR(" ", "PF B", this->phase_[1].power_factor_sensor_); - LOG_SENSOR(" ", "Active Forward Energy B", this->phase_[1].forward_active_energy_sensor_); - LOG_SENSOR(" ", "Active Reverse Energy B", this->phase_[1].reverse_active_energy_sensor_); - LOG_SENSOR(" ", "Voltage C", this->phase_[2].voltage_sensor_); - LOG_SENSOR(" ", "Current C", this->phase_[2].current_sensor_); - LOG_SENSOR(" ", "Power C", this->phase_[2].power_sensor_); - LOG_SENSOR(" ", "Reactive Power C", this->phase_[2].reactive_power_sensor_); - LOG_SENSOR(" ", "PF C", this->phase_[2].power_factor_sensor_); - LOG_SENSOR(" ", "Active Forward Energy C", this->phase_[2].forward_active_energy_sensor_); - LOG_SENSOR(" ", "Active Reverse Energy C", this->phase_[2].reverse_active_energy_sensor_); + LOG_SENSOR(" ", "Voltage A", this->phase_[PHASEA].voltage_sensor_); + LOG_SENSOR(" ", "Current A", this->phase_[PHASEA].current_sensor_); + LOG_SENSOR(" ", "Power A", this->phase_[PHASEA].power_sensor_); + LOG_SENSOR(" ", "Reactive Power A", this->phase_[PHASEA].reactive_power_sensor_); + LOG_SENSOR(" ", "PF A", this->phase_[PHASEA].power_factor_sensor_); + LOG_SENSOR(" ", "Active Forward Energy A", this->phase_[PHASEA].forward_active_energy_sensor_); + LOG_SENSOR(" ", "Active Reverse Energy A", this->phase_[PHASEA].reverse_active_energy_sensor_); + LOG_SENSOR(" ", "Harmonic Power A", this->phase_[PHASEA].harmonic_active_power_sensor_); + LOG_SENSOR(" ", "Phase Angle A", this->phase_[PHASEA].phase_angle_sensor_); + LOG_SENSOR(" ", "Peak Current A", this->phase_[PHASEA].peak_current_sensor_); + LOG_SENSOR(" ", "Voltage B", this->phase_[PHASEB].voltage_sensor_); + LOG_SENSOR(" ", "Current B", this->phase_[PHASEB].current_sensor_); + LOG_SENSOR(" ", "Power B", this->phase_[PHASEB].power_sensor_); + LOG_SENSOR(" ", "Reactive Power B", this->phase_[PHASEB].reactive_power_sensor_); + LOG_SENSOR(" ", "PF B", this->phase_[PHASEB].power_factor_sensor_); + LOG_SENSOR(" ", "Active Forward Energy B", this->phase_[PHASEB].forward_active_energy_sensor_); + LOG_SENSOR(" ", "Active Reverse Energy B", this->phase_[PHASEB].reverse_active_energy_sensor_); + LOG_SENSOR(" ", "Harmonic Power A", this->phase_[PHASEB].harmonic_active_power_sensor_); + LOG_SENSOR(" ", "Phase Angle A", this->phase_[PHASEB].phase_angle_sensor_); + LOG_SENSOR(" ", "Peak Current A", this->phase_[PHASEB].peak_current_sensor_); + LOG_SENSOR(" ", "Voltage C", this->phase_[PHASEC].voltage_sensor_); + LOG_SENSOR(" ", "Current C", this->phase_[PHASEC].current_sensor_); + LOG_SENSOR(" ", "Power C", this->phase_[PHASEC].power_sensor_); + LOG_SENSOR(" ", "Reactive Power C", this->phase_[PHASEC].reactive_power_sensor_); + LOG_SENSOR(" ", "PF C", this->phase_[PHASEC].power_factor_sensor_); + LOG_SENSOR(" ", "Active Forward Energy C", this->phase_[PHASEC].forward_active_energy_sensor_); + LOG_SENSOR(" ", "Active Reverse Energy C", this->phase_[PHASEC].reverse_active_energy_sensor_); + LOG_SENSOR(" ", "Harmonic Power A", this->phase_[PHASEC].harmonic_active_power_sensor_); + LOG_SENSOR(" ", "Phase Angle A", this->phase_[PHASEC].phase_angle_sensor_); + LOG_SENSOR(" ", "Peak Current A", this->phase_[PHASEC].peak_current_sensor_); LOG_SENSOR(" ", "Frequency", this->freq_sensor_); LOG_SENSOR(" ", "Chip Temp", this->chip_temperature_sensor_); } -float ATM90E32Component::get_setup_priority() const { return setup_priority::DATA; } +float ATM90E32Component::get_setup_priority() const { return setup_priority::IO; } + +// R/C registers can conly be cleared after the LastSPIData register is updated (register 78H) +// Peakdetect period: 05H. Bit 15:8 are PeakDet_period in ms. 7:0 are Sag_period +// Default is 143FH (20ms, 63ms) uint16_t ATM90E32Component::read16_(uint16_t a_register) { uint8_t addrh = (1 << 7) | ((a_register >> 8) & 0x03); uint8_t addrl = (a_register & 0xFF); uint8_t data[2]; uint16_t output; - this->enable(); - delayMicroseconds(10); + delay_microseconds_safe(10); this->write_byte(addrh); this->write_byte(addrl); - delayMicroseconds(4); this->read_array(data, 2); this->disable(); @@ -179,9 +258,9 @@ uint16_t ATM90E32Component::read16_(uint16_t a_register) { } int ATM90E32Component::read32_(uint16_t addr_h, uint16_t addr_l) { - uint16_t val_h = this->read16_(addr_h); - uint16_t val_l = this->read16_(addr_l); - int32_t val = (val_h << 16) | val_l; + const uint16_t val_h = this->read16_(addr_h); + const uint16_t val_l = this->read16_(addr_l); + const int32_t val = (val_h << 16) | val_l; ESP_LOGVV(TAG, "read32_ addr_h 0x%04" PRIX16 " val_h 0x%04" PRIX16 " addr_l 0x%04" PRIX16 " val_l 0x%04" PRIX16 @@ -192,141 +271,174 @@ int ATM90E32Component::read32_(uint16_t addr_h, uint16_t addr_l) { } void ATM90E32Component::write16_(uint16_t a_register, uint16_t val) { - uint8_t addrh = (a_register >> 8) & 0x03; - uint8_t addrl = (a_register & 0xFF); - ESP_LOGVV(TAG, "write16_ 0x%04" PRIX16 " val 0x%04" PRIX16, a_register, val); this->enable(); - delayMicroseconds(10); - this->write_byte(addrh); - this->write_byte(addrl); - delayMicroseconds(4); - this->write_byte((val >> 8) & 0xff); - this->write_byte(val & 0xFF); + this->write_byte16(a_register); + this->write_byte16(val); this->disable(); + if (this->read16_(ATM90E32_REGISTER_LASTSPIDATA) != val) + ESP_LOGW(TAG, "SPI write error 0x%04X val 0x%04X", a_register, val); } -float ATM90E32Component::get_line_voltage_a_() { - uint16_t voltage = this->read16_(ATM90E32_REGISTER_URMSA); +float ATM90E32Component::get_local_phase_voltage_(uint8_t phase) { return this->phase_[phase].voltage_; } + +float ATM90E32Component::get_local_phase_current_(uint8_t phase) { return this->phase_[phase].current_; } + +float ATM90E32Component::get_local_phase_active_power_(uint8_t phase) { return this->phase_[phase].active_power_; } + +float ATM90E32Component::get_local_phase_reactive_power_(uint8_t phase) { return this->phase_[phase].reactive_power_; } + +float ATM90E32Component::get_local_phase_power_factor_(uint8_t phase) { return this->phase_[phase].power_factor_; } + +float ATM90E32Component::get_local_phase_forward_active_energy_(uint8_t phase) { + return this->phase_[phase].forward_active_energy_; +} + +float ATM90E32Component::get_local_phase_reverse_active_energy_(uint8_t phase) { + return this->phase_[phase].reverse_active_energy_; +} + +float ATM90E32Component::get_local_phase_angle_(uint8_t phase) { return this->phase_[phase].phase_angle_; } + +float ATM90E32Component::get_local_phase_harmonic_active_power_(uint8_t phase) { + return this->phase_[phase].harmonic_active_power_; +} + +float ATM90E32Component::get_local_phase_peak_current_(uint8_t phase) { return this->phase_[phase].peak_current_; } + +float ATM90E32Component::get_phase_voltage_(uint8_t phase) { + const uint16_t voltage = this->read16_(ATM90E32_REGISTER_URMS + phase); + if (this->read16_(ATM90E32_REGISTER_LASTSPIDATA) != voltage) + ESP_LOGW(TAG, "SPI URMS voltage register read error."); return (float) voltage / 100; } -float ATM90E32Component::get_line_voltage_b_() { - uint16_t voltage = this->read16_(ATM90E32_REGISTER_URMSB); - return (float) voltage / 100; + +float ATM90E32Component::get_phase_voltage_avg_(uint8_t phase) { + const uint8_t reads = 10; + uint32_t accumulation = 0; + uint16_t voltage = 0; + for (uint8_t i = 0; i < reads; i++) { + voltage = this->read16_(ATM90E32_REGISTER_URMS + phase); + if (this->read16_(ATM90E32_REGISTER_LASTSPIDATA) != voltage) + ESP_LOGW(TAG, "SPI URMS voltage register read error."); + accumulation += voltage; + } + voltage = accumulation / reads; + this->phase_[phase].voltage_ = (float) voltage / 100; + return this->phase_[phase].voltage_; } -float ATM90E32Component::get_line_voltage_c_() { - uint16_t voltage = this->read16_(ATM90E32_REGISTER_URMSC); - return (float) voltage / 100; + +float ATM90E32Component::get_phase_current_avg_(uint8_t phase) { + const uint8_t reads = 10; + uint32_t accumulation = 0; + uint16_t current = 0; + for (uint8_t i = 0; i < reads; i++) { + current = this->read16_(ATM90E32_REGISTER_IRMS + phase); + if (this->read16_(ATM90E32_REGISTER_LASTSPIDATA) != current) + ESP_LOGW(TAG, "SPI IRMS current register read error."); + accumulation += current; + } + current = accumulation / reads; + this->phase_[phase].current_ = (float) current / 1000; + return this->phase_[phase].current_; } -float ATM90E32Component::get_line_current_a_() { - uint16_t current = this->read16_(ATM90E32_REGISTER_IRMSA); + +float ATM90E32Component::get_phase_current_(uint8_t phase) { + const uint16_t current = this->read16_(ATM90E32_REGISTER_IRMS + phase); + if (this->read16_(ATM90E32_REGISTER_LASTSPIDATA) != current) + ESP_LOGW(TAG, "SPI IRMS current register read error."); return (float) current / 1000; } -float ATM90E32Component::get_line_current_b_() { - uint16_t current = this->read16_(ATM90E32_REGISTER_IRMSB); - return (float) current / 1000; -} -float ATM90E32Component::get_line_current_c_() { - uint16_t current = this->read16_(ATM90E32_REGISTER_IRMSC); - return (float) current / 1000; -} -float ATM90E32Component::get_active_power_a_() { - int val = this->read32_(ATM90E32_REGISTER_PMEANA, ATM90E32_REGISTER_PMEANALSB); + +float ATM90E32Component::get_phase_active_power_(uint8_t phase) { + const int val = this->read32_(ATM90E32_REGISTER_PMEAN + phase, ATM90E32_REGISTER_PMEANLSB + phase); return val * 0.00032f; } -float ATM90E32Component::get_active_power_b_() { - int val = this->read32_(ATM90E32_REGISTER_PMEANB, ATM90E32_REGISTER_PMEANBLSB); + +float ATM90E32Component::get_phase_reactive_power_(uint8_t phase) { + const int val = this->read32_(ATM90E32_REGISTER_QMEAN + phase, ATM90E32_REGISTER_QMEANLSB + phase); return val * 0.00032f; } -float ATM90E32Component::get_active_power_c_() { - int val = this->read32_(ATM90E32_REGISTER_PMEANC, ATM90E32_REGISTER_PMEANCLSB); + +float ATM90E32Component::get_phase_power_factor_(uint8_t phase) { + const int16_t powerfactor = this->read16_(ATM90E32_REGISTER_PFMEAN + phase); + if (this->read16_(ATM90E32_REGISTER_LASTSPIDATA) != powerfactor) + ESP_LOGW(TAG, "SPI power factor read error."); + return (float) powerfactor / 1000; +} + +float ATM90E32Component::get_phase_forward_active_energy_(uint8_t phase) { + const uint16_t val = this->read16_(ATM90E32_REGISTER_APENERGY + phase); + if ((UINT32_MAX - this->phase_[phase].cumulative_forward_active_energy_) > val) { + this->phase_[phase].cumulative_forward_active_energy_ += val; + } else { + this->phase_[phase].cumulative_forward_active_energy_ = val; + } + return ((float) this->phase_[phase].cumulative_forward_active_energy_ * 10 / 3200); +} + +float ATM90E32Component::get_phase_reverse_active_energy_(uint8_t phase) { + const uint16_t val = this->read16_(ATM90E32_REGISTER_ANENERGY); + if (UINT32_MAX - this->phase_[phase].cumulative_reverse_active_energy_ > val) { + this->phase_[phase].cumulative_reverse_active_energy_ += val; + } else { + this->phase_[phase].cumulative_reverse_active_energy_ = val; + } + return ((float) this->phase_[phase].cumulative_reverse_active_energy_ * 10 / 3200); +} + +float ATM90E32Component::get_phase_harmonic_active_power_(uint8_t phase) { + int val = this->read32_(ATM90E32_REGISTER_PMEANH + phase, ATM90E32_REGISTER_PMEANHLSB + phase); return val * 0.00032f; } -float ATM90E32Component::get_reactive_power_a_() { - int val = this->read32_(ATM90E32_REGISTER_QMEANA, ATM90E32_REGISTER_QMEANALSB); - return val * 0.00032f; + +float ATM90E32Component::get_phase_angle_(uint8_t phase) { + uint16_t val = this->read16_(ATM90E32_REGISTER_PANGLE + phase) / 10.0; + return (float) (val > 180) ? val - 360.0 : val; } -float ATM90E32Component::get_reactive_power_b_() { - int val = this->read32_(ATM90E32_REGISTER_QMEANB, ATM90E32_REGISTER_QMEANBLSB); - return val * 0.00032f; -} -float ATM90E32Component::get_reactive_power_c_() { - int val = this->read32_(ATM90E32_REGISTER_QMEANC, ATM90E32_REGISTER_QMEANCLSB); - return val * 0.00032f; -} -float ATM90E32Component::get_power_factor_a_() { - int16_t pf = this->read16_(ATM90E32_REGISTER_PFMEANA); - return (float) pf / 1000; -} -float ATM90E32Component::get_power_factor_b_() { - int16_t pf = this->read16_(ATM90E32_REGISTER_PFMEANB); - return (float) pf / 1000; -} -float ATM90E32Component::get_power_factor_c_() { - int16_t pf = this->read16_(ATM90E32_REGISTER_PFMEANC); - return (float) pf / 1000; -} -float ATM90E32Component::get_forward_active_energy_a_() { - uint16_t val = this->read16_(ATM90E32_REGISTER_APENERGYA); - if ((UINT32_MAX - this->phase_[0].cumulative_forward_active_energy_) > val) { - this->phase_[0].cumulative_forward_active_energy_ += val; - } else { - this->phase_[0].cumulative_forward_active_energy_ = val; - } - return ((float) this->phase_[0].cumulative_forward_active_energy_ * 10 / 3200); -} -float ATM90E32Component::get_forward_active_energy_b_() { - uint16_t val = this->read16_(ATM90E32_REGISTER_APENERGYB); - if (UINT32_MAX - this->phase_[1].cumulative_forward_active_energy_ > val) { - this->phase_[1].cumulative_forward_active_energy_ += val; - } else { - this->phase_[1].cumulative_forward_active_energy_ = val; - } - return ((float) this->phase_[1].cumulative_forward_active_energy_ * 10 / 3200); -} -float ATM90E32Component::get_forward_active_energy_c_() { - uint16_t val = this->read16_(ATM90E32_REGISTER_APENERGYC); - if (UINT32_MAX - this->phase_[2].cumulative_forward_active_energy_ > val) { - this->phase_[2].cumulative_forward_active_energy_ += val; - } else { - this->phase_[2].cumulative_forward_active_energy_ = val; - } - return ((float) this->phase_[2].cumulative_forward_active_energy_ * 10 / 3200); -} -float ATM90E32Component::get_reverse_active_energy_a_() { - uint16_t val = this->read16_(ATM90E32_REGISTER_ANENERGYA); - if (UINT32_MAX - this->phase_[0].cumulative_reverse_active_energy_ > val) { - this->phase_[0].cumulative_reverse_active_energy_ += val; - } else { - this->phase_[0].cumulative_reverse_active_energy_ = val; - } - return ((float) this->phase_[0].cumulative_reverse_active_energy_ * 10 / 3200); -} -float ATM90E32Component::get_reverse_active_energy_b_() { - uint16_t val = this->read16_(ATM90E32_REGISTER_ANENERGYB); - if (UINT32_MAX - this->phase_[1].cumulative_reverse_active_energy_ > val) { - this->phase_[1].cumulative_reverse_active_energy_ += val; - } else { - this->phase_[1].cumulative_reverse_active_energy_ = val; - } - return ((float) this->phase_[1].cumulative_reverse_active_energy_ * 10 / 3200); -} -float ATM90E32Component::get_reverse_active_energy_c_() { - uint16_t val = this->read16_(ATM90E32_REGISTER_ANENERGYC); - if (UINT32_MAX - this->phase_[2].cumulative_reverse_active_energy_ > val) { - this->phase_[2].cumulative_reverse_active_energy_ += val; - } else { - this->phase_[2].cumulative_reverse_active_energy_ = val; - } - return ((float) this->phase_[2].cumulative_reverse_active_energy_ * 10 / 3200); + +float ATM90E32Component::get_phase_peak_current_(uint8_t phase) { + int16_t val = (float) this->read16_(ATM90E32_REGISTER_IPEAK + phase); + if (!this->peak_current_signed_) + val = abs(val); + // phase register * phase current gain value / 1000 * 2^13 + return (float) (val * this->phase_[phase].ct_gain_ / 8192000.0); } + float ATM90E32Component::get_frequency_() { - uint16_t freq = this->read16_(ATM90E32_REGISTER_FREQ); + const uint16_t freq = this->read16_(ATM90E32_REGISTER_FREQ); return (float) freq / 100; } + float ATM90E32Component::get_chip_temperature_() { - uint16_t ctemp = this->read16_(ATM90E32_REGISTER_TEMP); + const uint16_t ctemp = this->read16_(ATM90E32_REGISTER_TEMP); return (float) ctemp; } + +uint16_t ATM90E32Component::calibrate_voltage_offset_phase(uint8_t phase) { + const uint8_t num_reads = 5; + uint64_t total_value = 0; + for (int i = 0; i < num_reads; ++i) { + const uint32_t measurement_value = read32_(ATM90E32_REGISTER_URMS + phase, ATM90E32_REGISTER_URMSLSB + phase); + total_value += measurement_value; + } + const uint32_t average_value = total_value / num_reads; + const uint32_t shifted_value = average_value >> 7; + const uint32_t voltage_offset = ~shifted_value + 1; + return voltage_offset & 0xFFFF; // Take the lower 16 bits +} + +uint16_t ATM90E32Component::calibrate_current_offset_phase(uint8_t phase) { + const uint8_t num_reads = 5; + uint64_t total_value = 0; + for (int i = 0; i < num_reads; ++i) { + const uint32_t measurement_value = read32_(ATM90E32_REGISTER_IRMS + phase, ATM90E32_REGISTER_IRMSLSB + phase); + total_value += measurement_value; + } + const uint32_t average_value = total_value / num_reads; + const uint32_t current_offset = ~average_value + 1; + return current_offset & 0xFFFF; // Take the lower 16 bits +} + } // namespace atm90e32 } // namespace esphome diff --git a/esphome/components/atm90e32/atm90e32.h b/esphome/components/atm90e32/atm90e32.h index c9662df26e..0a334dbe8b 100644 --- a/esphome/components/atm90e32/atm90e32.h +++ b/esphome/components/atm90e32/atm90e32.h @@ -3,14 +3,19 @@ #include "esphome/core/component.h" #include "esphome/components/sensor/sensor.h" #include "esphome/components/spi/spi.h" +#include "atm90e32_reg.h" namespace esphome { namespace atm90e32 { class ATM90E32Component : public PollingComponent, public spi::SPIDevice { + spi::CLOCK_PHASE_TRAILING, spi::DATA_RATE_1MHZ> { public: + static const uint8_t PHASEA = 0; + static const uint8_t PHASEB = 1; + static const uint8_t PHASEC = 2; + void loop() override; void setup() override; void dump_config() override; float get_setup_priority() const override; @@ -20,6 +25,7 @@ class ATM90E32Component : public PollingComponent, void set_current_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].current_sensor_ = obj; } void set_power_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].power_sensor_ = obj; } void set_reactive_power_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].reactive_power_sensor_ = obj; } + void set_apparent_power_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].apparent_power_sensor_ = obj; } void set_forward_active_energy_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].forward_active_energy_sensor_ = obj; } @@ -27,64 +33,94 @@ class ATM90E32Component : public PollingComponent, this->phase_[phase].reverse_active_energy_sensor_ = obj; } void set_power_factor_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].power_factor_sensor_ = obj; } - void set_volt_gain(int phase, uint16_t gain) { this->phase_[phase].volt_gain_ = gain; } + void set_phase_angle_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].phase_angle_sensor_ = obj; } + void set_harmonic_active_power_sensor(int phase, sensor::Sensor *obj) { + this->phase_[phase].harmonic_active_power_sensor_ = obj; + } + void set_peak_current_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].peak_current_sensor_ = obj; } + void set_volt_gain(int phase, uint16_t gain) { this->phase_[phase].voltage_gain_ = gain; } void set_ct_gain(int phase, uint16_t gain) { this->phase_[phase].ct_gain_ = gain; } - void set_freq_sensor(sensor::Sensor *freq_sensor) { freq_sensor_ = freq_sensor; } + void set_peak_current_signed(bool flag) { peak_current_signed_ = flag; } void set_chip_temperature_sensor(sensor::Sensor *chip_temperature_sensor) { chip_temperature_sensor_ = chip_temperature_sensor; } void set_line_freq(int freq) { line_freq_ = freq; } void set_current_phases(int phases) { current_phases_ = phases; } void set_pga_gain(uint16_t gain) { pga_gain_ = gain; } + uint16_t calibrate_voltage_offset_phase(uint8_t /*phase*/); + uint16_t calibrate_current_offset_phase(uint8_t /*phase*/); + + int32_t last_periodic_millis = millis(); protected: uint16_t read16_(uint16_t a_register); int read32_(uint16_t addr_h, uint16_t addr_l); void write16_(uint16_t a_register, uint16_t val); - - float get_line_voltage_a_(); - float get_line_voltage_b_(); - float get_line_voltage_c_(); - float get_line_current_a_(); - float get_line_current_b_(); - float get_line_current_c_(); - float get_active_power_a_(); - float get_active_power_b_(); - float get_active_power_c_(); - float get_reactive_power_a_(); - float get_reactive_power_b_(); - float get_reactive_power_c_(); - float get_power_factor_a_(); - float get_power_factor_b_(); - float get_power_factor_c_(); - float get_forward_active_energy_a_(); - float get_forward_active_energy_b_(); - float get_forward_active_energy_c_(); - float get_reverse_active_energy_a_(); - float get_reverse_active_energy_b_(); - float get_reverse_active_energy_c_(); + float get_local_phase_voltage_(uint8_t /*phase*/); + float get_local_phase_current_(uint8_t /*phase*/); + float get_local_phase_active_power_(uint8_t /*phase*/); + float get_local_phase_reactive_power_(uint8_t /*phase*/); + float get_local_phase_power_factor_(uint8_t /*phase*/); + float get_local_phase_forward_active_energy_(uint8_t /*phase*/); + float get_local_phase_reverse_active_energy_(uint8_t /*phase*/); + float get_local_phase_angle_(uint8_t /*phase*/); + float get_local_phase_harmonic_active_power_(uint8_t /*phase*/); + float get_local_phase_peak_current_(uint8_t /*phase*/); + float get_phase_voltage_(uint8_t /*phase*/); + float get_phase_voltage_avg_(uint8_t /*phase*/); + float get_phase_current_(uint8_t /*phase*/); + float get_phase_current_avg_(uint8_t /*phase*/); + float get_phase_active_power_(uint8_t /*phase*/); + float get_phase_reactive_power_(uint8_t /*phase*/); + float get_phase_power_factor_(uint8_t /*phase*/); + float get_phase_forward_active_energy_(uint8_t /*phase*/); + float get_phase_reverse_active_energy_(uint8_t /*phase*/); + float get_phase_angle_(uint8_t /*phase*/); + float get_phase_harmonic_active_power_(uint8_t /*phase*/); + float get_phase_peak_current_(uint8_t /*phase*/); float get_frequency_(); float get_chip_temperature_(); + bool get_publish_interval_flag_() { return publish_interval_flag_; }; + void set_publish_interval_flag_(bool flag) { publish_interval_flag_ = flag; }; struct ATM90E32Phase { - uint16_t volt_gain_{7305}; + uint16_t voltage_gain_{7305}; uint16_t ct_gain_{27961}; + uint16_t voltage_offset_{0}; + uint16_t current_offset_{0}; + float voltage_{0}; + float current_{0}; + float active_power_{0}; + float reactive_power_{0}; + float power_factor_{0}; + float forward_active_energy_{0}; + float reverse_active_energy_{0}; + float phase_angle_{0}; + float harmonic_active_power_{0}; + float peak_current_{0}; sensor::Sensor *voltage_sensor_{nullptr}; sensor::Sensor *current_sensor_{nullptr}; sensor::Sensor *power_sensor_{nullptr}; sensor::Sensor *reactive_power_sensor_{nullptr}; + sensor::Sensor *apparent_power_sensor_{nullptr}; sensor::Sensor *power_factor_sensor_{nullptr}; sensor::Sensor *forward_active_energy_sensor_{nullptr}; sensor::Sensor *reverse_active_energy_sensor_{nullptr}; + sensor::Sensor *phase_angle_sensor_{nullptr}; + sensor::Sensor *harmonic_active_power_sensor_{nullptr}; + sensor::Sensor *peak_current_sensor_{nullptr}; uint32_t cumulative_forward_active_energy_{0}; uint32_t cumulative_reverse_active_energy_{0}; } phase_[3]; + sensor::Sensor *freq_sensor_{nullptr}; sensor::Sensor *chip_temperature_sensor_{nullptr}; uint16_t pga_gain_{0x15}; int line_freq_{60}; int current_phases_{3}; + bool publish_interval_flag_{true}; + bool peak_current_signed_{false}; }; } // namespace atm90e32 diff --git a/esphome/components/atm90e32/atm90e32_reg.h b/esphome/components/atm90e32/atm90e32_reg.h index 7927a7fdfb..dac62aa6b4 100644 --- a/esphome/components/atm90e32/atm90e32_reg.h +++ b/esphome/components/atm90e32/atm90e32_reg.h @@ -131,10 +131,12 @@ static const uint16_t ATM90E32_REGISTER_IOFFSETN = 0x6E; // N Current Offset /* ENERGY REGISTERS */ static const uint16_t ATM90E32_REGISTER_APENERGYT = 0x80; // Total Forward Active +static const uint16_t ATM90E32_REGISTER_APENERGY = 0x81; // Forward Active Reg Base static const uint16_t ATM90E32_REGISTER_APENERGYA = 0x81; // A Forward Active static const uint16_t ATM90E32_REGISTER_APENERGYB = 0x82; // B Forward Active static const uint16_t ATM90E32_REGISTER_APENERGYC = 0x83; // C Forward Active static const uint16_t ATM90E32_REGISTER_ANENERGYT = 0x84; // Total Reverse Active +static const uint16_t ATM90E32_REGISTER_ANENERGY = 0x85; // Reverse Active Reg Base static const uint16_t ATM90E32_REGISTER_ANENERGYA = 0x85; // A Reverse Active static const uint16_t ATM90E32_REGISTER_ANENERGYB = 0x86; // B Reverse Active static const uint16_t ATM90E32_REGISTER_ANENERGYC = 0x87; // C Reverse Active @@ -172,10 +174,12 @@ static const uint16_t ATM90E32_REGISTER_ANENERGYCH = 0xAF; // C Reverse Harm. E /* POWER & P.F. REGISTERS */ static const uint16_t ATM90E32_REGISTER_PMEANT = 0xB0; // Total Mean Power (P) +static const uint16_t ATM90E32_REGISTER_PMEAN = 0xB1; // Mean Power Reg Base (P) static const uint16_t ATM90E32_REGISTER_PMEANA = 0xB1; // A Mean Power (P) static const uint16_t ATM90E32_REGISTER_PMEANB = 0xB2; // B Mean Power (P) static const uint16_t ATM90E32_REGISTER_PMEANC = 0xB3; // C Mean Power (P) static const uint16_t ATM90E32_REGISTER_QMEANT = 0xB4; // Total Mean Power (Q) +static const uint16_t ATM90E32_REGISTER_QMEAN = 0xB5; // Mean Power Reg Base (Q) static const uint16_t ATM90E32_REGISTER_QMEANA = 0xB5; // A Mean Power (Q) static const uint16_t ATM90E32_REGISTER_QMEANB = 0xB6; // B Mean Power (Q) static const uint16_t ATM90E32_REGISTER_QMEANC = 0xB7; // C Mean Power (Q) @@ -184,15 +188,18 @@ static const uint16_t ATM90E32_REGISTER_SMEANA = 0xB9; // A Mean Power (S) static const uint16_t ATM90E32_REGISTER_SMEANB = 0xBA; // B Mean Power (S) static const uint16_t ATM90E32_REGISTER_SMEANC = 0xBB; // C Mean Power (S) static const uint16_t ATM90E32_REGISTER_PFMEANT = 0xBC; // Mean Power Factor +static const uint16_t ATM90E32_REGISTER_PFMEAN = 0xBD; // Power Factor Reg Base static const uint16_t ATM90E32_REGISTER_PFMEANA = 0xBD; // A Power Factor static const uint16_t ATM90E32_REGISTER_PFMEANB = 0xBE; // B Power Factor static const uint16_t ATM90E32_REGISTER_PFMEANC = 0xBF; // C Power Factor static const uint16_t ATM90E32_REGISTER_PMEANTLSB = 0xC0; // Lower Word (Tot. Act. Power) +static const uint16_t ATM90E32_REGISTER_PMEANLSB = 0xC1; // Lower Word Reg Base (Active Power) static const uint16_t ATM90E32_REGISTER_PMEANALSB = 0xC1; // Lower Word (A Act. Power) static const uint16_t ATM90E32_REGISTER_PMEANBLSB = 0xC2; // Lower Word (B Act. Power) static const uint16_t ATM90E32_REGISTER_PMEANCLSB = 0xC3; // Lower Word (C Act. Power) static const uint16_t ATM90E32_REGISTER_QMEANTLSB = 0xC4; // Lower Word (Tot. React. Power) +static const uint16_t ATM90E32_REGISTER_QMEANLSB = 0xC5; // Lower Word Reg Base (Reactive Power) static const uint16_t ATM90E32_REGISTER_QMEANALSB = 0xC5; // Lower Word (A React. Power) static const uint16_t ATM90E32_REGISTER_QMEANBLSB = 0xC6; // Lower Word (B React. Power) static const uint16_t ATM90E32_REGISTER_QMEANCLSB = 0xC7; // Lower Word (C React. Power) @@ -207,12 +214,15 @@ static const uint16_t ATM90E32_REGISTER_PMEANAF = 0xD1; // A Active Fund. Power static const uint16_t ATM90E32_REGISTER_PMEANBF = 0xD2; // B Active Fund. Power static const uint16_t ATM90E32_REGISTER_PMEANCF = 0xD3; // C Active Fund. Power static const uint16_t ATM90E32_REGISTER_PMEANTH = 0xD4; // Total Active Harm. Power +static const uint16_t ATM90E32_REGISTER_PMEANH = 0xD5; // Active Harm. Power Reg Base static const uint16_t ATM90E32_REGISTER_PMEANAH = 0xD5; // A Active Harm. Power static const uint16_t ATM90E32_REGISTER_PMEANBH = 0xD6; // B Active Harm. Power static const uint16_t ATM90E32_REGISTER_PMEANCH = 0xD7; // C Active Harm. Power +static const uint16_t ATM90E32_REGISTER_URMS = 0xD9; // RMS Voltage Reg Base static const uint16_t ATM90E32_REGISTER_URMSA = 0xD9; // A RMS Voltage static const uint16_t ATM90E32_REGISTER_URMSB = 0xDA; // B RMS Voltage static const uint16_t ATM90E32_REGISTER_URMSC = 0xDB; // C RMS Voltage +static const uint16_t ATM90E32_REGISTER_IRMS = 0xDD; // RMS Current Reg Base static const uint16_t ATM90E32_REGISTER_IRMSA = 0xDD; // A RMS Current static const uint16_t ATM90E32_REGISTER_IRMSB = 0xDE; // B RMS Current static const uint16_t ATM90E32_REGISTER_IRMSC = 0xDF; // C RMS Current @@ -223,12 +233,15 @@ static const uint16_t ATM90E32_REGISTER_PMEANAFLSB = 0xE1; // Lower Word (A Act static const uint16_t ATM90E32_REGISTER_PMEANBFLSB = 0xE2; // Lower Word (B Act. Fund. Power) static const uint16_t ATM90E32_REGISTER_PMEANCFLSB = 0xE3; // Lower Word (C Act. Fund. Power) static const uint16_t ATM90E32_REGISTER_PMEANTHLSB = 0xE4; // Lower Word (Tot. Act. Harm. Power) +static const uint16_t ATM90E32_REGISTER_PMEANHLSB = 0xE5; // Lower Word (A Act. Harm. Power) Reg Base static const uint16_t ATM90E32_REGISTER_PMEANAHLSB = 0xE5; // Lower Word (A Act. Harm. Power) static const uint16_t ATM90E32_REGISTER_PMEANBHLSB = 0xE6; // Lower Word (B Act. Harm. Power) static const uint16_t ATM90E32_REGISTER_PMEANCHLSB = 0xE7; // Lower Word (C Act. Harm. Power) +static const uint16_t ATM90E32_REGISTER_URMSLSB = 0xE9; // Lower Word RMS Voltage Reg Base static const uint16_t ATM90E32_REGISTER_URMSALSB = 0xE9; // Lower Word (A RMS Voltage) static const uint16_t ATM90E32_REGISTER_URMSBLSB = 0xEA; // Lower Word (B RMS Voltage) static const uint16_t ATM90E32_REGISTER_URMSCLSB = 0xEB; // Lower Word (C RMS Voltage) +static const uint16_t ATM90E32_REGISTER_IRMSLSB = 0xED; // Lower Word RMS Current Reg Base static const uint16_t ATM90E32_REGISTER_IRMSALSB = 0xED; // Lower Word (A RMS Current) static const uint16_t ATM90E32_REGISTER_IRMSBLSB = 0xEE; // Lower Word (B RMS Current) static const uint16_t ATM90E32_REGISTER_IRMSCLSB = 0xEF; // Lower Word (C RMS Current) @@ -237,10 +250,12 @@ static const uint16_t ATM90E32_REGISTER_IRMSCLSB = 0xEF; // Lower Word (C RMS static const uint16_t ATM90E32_REGISTER_UPEAKA = 0xF1; // A Voltage Peak static const uint16_t ATM90E32_REGISTER_UPEAKB = 0xF2; // B Voltage Peak static const uint16_t ATM90E32_REGISTER_UPEAKC = 0xF3; // C Voltage Peak +static const uint16_t ATM90E32_REGISTER_IPEAK = 0xF5; // Peak Current Reg Base static const uint16_t ATM90E32_REGISTER_IPEAKA = 0xF5; // A Current Peak static const uint16_t ATM90E32_REGISTER_IPEAKB = 0xF6; // B Current Peak static const uint16_t ATM90E32_REGISTER_IPEAKC = 0xF7; // C Current Peak static const uint16_t ATM90E32_REGISTER_FREQ = 0xF8; // Frequency +static const uint16_t ATM90E32_REGISTER_PANGLE = 0xF9; // Mean Phase Angle Reg Base static const uint16_t ATM90E32_REGISTER_PANGLEA = 0xF9; // A Mean Phase Angle static const uint16_t ATM90E32_REGISTER_PANGLEB = 0xFA; // B Mean Phase Angle static const uint16_t ATM90E32_REGISTER_PANGLEC = 0xFB; // C Mean Phase Angle diff --git a/esphome/components/atm90e32/sensor.py b/esphome/components/atm90e32/sensor.py index af4d2ef412..2bc7f0498d 100644 --- a/esphome/components/atm90e32/sensor.py +++ b/esphome/components/atm90e32/sensor.py @@ -9,8 +9,10 @@ from esphome.const import ( CONF_PHASE_A, CONF_PHASE_B, CONF_PHASE_C, + CONF_PHASE_ANGLE, CONF_POWER, CONF_POWER_FACTOR, + CONF_APPARENT_POWER, CONF_FREQUENCY, CONF_FORWARD_ACTIVE_ENERGY, CONF_REVERSE_ACTIVE_ENERGY, @@ -25,12 +27,13 @@ from esphome.const import ( ICON_CURRENT_AC, STATE_CLASS_MEASUREMENT, STATE_CLASS_TOTAL_INCREASING, + UNIT_AMPERE, + UNIT_DEGREES, + UNIT_CELSIUS, UNIT_HERTZ, UNIT_VOLT, - UNIT_AMPERE, - UNIT_WATT, - UNIT_CELSIUS, UNIT_VOLT_AMPS_REACTIVE, + UNIT_WATT, UNIT_WATT_HOURS, ) @@ -40,6 +43,10 @@ CONF_GAIN_PGA = "gain_pga" CONF_CURRENT_PHASES = "current_phases" CONF_GAIN_VOLTAGE = "gain_voltage" CONF_GAIN_CT = "gain_ct" +CONF_HARMONIC_POWER = "harmonic_power" +CONF_PEAK_CURRENT = "peak_current" +CONF_PEAK_CURRENT_SIGNED = "peak_current_signed" +UNIT_DEG = "degrees" LINE_FREQS = { "50HZ": 50, "60HZ": 60, @@ -85,6 +92,12 @@ ATM90E32_PHASE_SCHEMA = cv.Schema( accuracy_decimals=2, state_class=STATE_CLASS_MEASUREMENT, ), + cv.Optional(CONF_APPARENT_POWER): sensor.sensor_schema( + unit_of_measurement=UNIT_WATT, + accuracy_decimals=2, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), cv.Optional(CONF_POWER_FACTOR): sensor.sensor_schema( accuracy_decimals=2, device_class=DEVICE_CLASS_POWER_FACTOR, @@ -102,6 +115,24 @@ ATM90E32_PHASE_SCHEMA = cv.Schema( device_class=DEVICE_CLASS_ENERGY, state_class=STATE_CLASS_TOTAL_INCREASING, ), + cv.Optional(CONF_PHASE_ANGLE): sensor.sensor_schema( + unit_of_measurement=UNIT_DEGREES, + accuracy_decimals=2, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_HARMONIC_POWER): sensor.sensor_schema( + unit_of_measurement=UNIT_WATT, + accuracy_decimals=2, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_PEAK_CURRENT): sensor.sensor_schema( + unit_of_measurement=UNIT_AMPERE, + accuracy_decimals=2, + device_class=DEVICE_CLASS_CURRENT, + state_class=STATE_CLASS_MEASUREMENT, + ), cv.Optional(CONF_GAIN_VOLTAGE, default=7305): cv.uint16_t, cv.Optional(CONF_GAIN_CT, default=27961): cv.uint16_t, } @@ -132,6 +163,7 @@ CONFIG_SCHEMA = ( CURRENT_PHASES, upper=True ), cv.Optional(CONF_GAIN_PGA, default="2X"): cv.enum(PGA_GAINS, upper=True), + cv.Optional(CONF_PEAK_CURRENT_SIGNED, default=False): cv.boolean, } ) .extend(cv.polling_component_schema("60s")) @@ -162,6 +194,9 @@ async def to_code(config): if reactive_power_config := conf.get(CONF_REACTIVE_POWER): sens = await sensor.new_sensor(reactive_power_config) cg.add(var.set_reactive_power_sensor(i, sens)) + if apparent_power_config := conf.get(CONF_APPARENT_POWER): + sens = await sensor.new_sensor(apparent_power_config) + cg.add(var.set_apparent_power_sensor(i, sens)) if power_factor_config := conf.get(CONF_POWER_FACTOR): sens = await sensor.new_sensor(power_factor_config) cg.add(var.set_power_factor_sensor(i, sens)) @@ -171,6 +206,15 @@ async def to_code(config): if reverse_active_energy_config := conf.get(CONF_REVERSE_ACTIVE_ENERGY): sens = await sensor.new_sensor(reverse_active_energy_config) cg.add(var.set_reverse_active_energy_sensor(i, sens)) + if phase_angle_config := conf.get(CONF_PHASE_ANGLE): + sens = await sensor.new_sensor(phase_angle_config) + cg.add(var.set_phase_angle_sensor(i, sens)) + if harmonic_active_power_config := conf.get(CONF_HARMONIC_POWER): + sens = await sensor.new_sensor(harmonic_active_power_config) + cg.add(var.set_harmonic_active_power_sensor(i, sens)) + if peak_current_config := conf.get(CONF_PEAK_CURRENT): + sens = await sensor.new_sensor(peak_current_config) + cg.add(var.set_peak_current_sensor(i, sens)) if frequency_config := config.get(CONF_FREQUENCY): sens = await sensor.new_sensor(frequency_config) @@ -182,3 +226,4 @@ async def to_code(config): cg.add(var.set_line_freq(config[CONF_LINE_FREQUENCY])) cg.add(var.set_current_phases(config[CONF_CURRENT_PHASES])) cg.add(var.set_pga_gain(config[CONF_GAIN_PGA])) + cg.add(var.set_peak_current_signed(config[CONF_PEAK_CURRENT_SIGNED])) From 0ecd938570530c69f18038b23f37a8f306ac39fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 07:25:11 +1300 Subject: [PATCH 079/189] Bump aioesphomeapi from 23.1.0 to 23.1.1 (#6348) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index cbf925c1b5..32955bf6e7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ platformio==6.1.13 # When updating platformio, also update Dockerfile esptool==4.7.0 click==8.1.7 esphome-dashboard==20231107.0 -aioesphomeapi==23.1.0 +aioesphomeapi==23.1.1 zeroconf==0.131.0 python-magic==0.4.27 From 32be12423ac415bd263d15649256725d8b6aa102 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 07:25:19 +1300 Subject: [PATCH 080/189] Bump pytest from 8.0.2 to 8.1.1 (#6346) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements_test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_test.txt b/requirements_test.txt index b370214380..29e5420d78 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -5,7 +5,7 @@ pyupgrade==3.15.1 # also change in .pre-commit-config.yaml when updating pre-commit # Unit tests -pytest==8.0.2 +pytest==8.1.1 pytest-cov==4.1.0 pytest-mock==3.12.0 pytest-asyncio==0.23.5.post1 From a96762220a569015d87693562f22e0c1e5e13d55 Mon Sep 17 00:00:00 2001 From: Manuel Kasper Date: Mon, 11 Mar 2024 19:38:59 +0100 Subject: [PATCH 081/189] Add support for Waveshare 2.13" V2 display (#6337) * Add support for Waveshare 2.13" V2 display * Fix clang-tidy error, add comment about BUSY in deep sleep * Add test * Add nullptr check and move tests to separate file * Fix GPIO pins in test --- .../components/waveshare_epaper/display.py | 4 + .../waveshare_epaper/waveshare_epaper.cpp | 75 +++++++-- .../waveshare_epaper/waveshare_epaper.h | 8 +- .../waveshare_epaper/test.esp32.yaml | 154 ++++++++++++++++++ tests/test4.yaml | 124 -------------- 5 files changed, 228 insertions(+), 137 deletions(-) create mode 100644 tests/components/waveshare_epaper/test.esp32.yaml diff --git a/esphome/components/waveshare_epaper/display.py b/esphome/components/waveshare_epaper/display.py index 7f86bf8d08..744ae8848f 100644 --- a/esphome/components/waveshare_epaper/display.py +++ b/esphome/components/waveshare_epaper/display.py @@ -85,6 +85,9 @@ WaveshareEPaper7P5InHDB = waveshare_epaper_ns.class_( WaveshareEPaper2P13InDKE = waveshare_epaper_ns.class_( "WaveshareEPaper2P13InDKE", WaveshareEPaper ) +WaveshareEPaper2P13InV2 = waveshare_epaper_ns.class_( + "WaveshareEPaper2P13InV2", WaveshareEPaper +) WaveshareEPaper2P13InV3 = waveshare_epaper_ns.class_( "WaveshareEPaper2P13InV3", WaveshareEPaper ) @@ -97,6 +100,7 @@ MODELS = { "1.54in": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_1_54_IN), "1.54inv2": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_1_54_IN_V2), "2.13in": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_13_IN), + "2.13inv2": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_13_IN_V2), "2.13in-ttgo": ("a", WaveshareEPaperTypeAModel.TTGO_EPAPER_2_13_IN), "2.13in-ttgo-b1": ("a", WaveshareEPaperTypeAModel.TTGO_EPAPER_2_13_IN_B1), "2.13in-ttgo-b73": ("a", WaveshareEPaperTypeAModel.TTGO_EPAPER_2_13_IN_B73), diff --git a/esphome/components/waveshare_epaper/waveshare_epaper.cpp b/esphome/components/waveshare_epaper/waveshare_epaper.cpp index a4417e0d1c..cf43c4cc32 100644 --- a/esphome/components/waveshare_epaper/waveshare_epaper.cpp +++ b/esphome/components/waveshare_epaper/waveshare_epaper.cpp @@ -256,12 +256,14 @@ void WaveshareEPaperTypeA::initialize() { } } void WaveshareEPaperTypeA::init_display_() { - if (this->model_ == TTGO_EPAPER_2_13_IN_B74) { - this->reset_pin_->digital_write(false); - delay(10); - this->reset_pin_->digital_write(true); - delay(10); - this->wait_until_idle_(); + if (this->model_ == TTGO_EPAPER_2_13_IN_B74 || this->model_ == WAVESHARE_EPAPER_2_13_IN_V2) { + if (this->reset_pin_ != nullptr) { + this->reset_pin_->digital_write(false); + delay(10); + this->reset_pin_->digital_write(true); + delay(10); + this->wait_until_idle_(); + } this->command(0x12); // SWRESET this->wait_until_idle_(); @@ -321,6 +323,9 @@ void WaveshareEPaperTypeA::dump_config() { case WAVESHARE_EPAPER_2_13_IN: ESP_LOGCONFIG(TAG, " Model: 2.13in"); break; + case WAVESHARE_EPAPER_2_13_IN_V2: + ESP_LOGCONFIG(TAG, " Model: 2.13inV2"); + break; case TTGO_EPAPER_2_13_IN: ESP_LOGCONFIG(TAG, " Model: 2.13in (TTGO)"); break; @@ -366,6 +371,8 @@ void HOT WaveshareEPaperTypeA::display() { if (full_update != prev_full_update) { switch (this->model_) { case TTGO_EPAPER_2_13_IN: + case WAVESHARE_EPAPER_2_13_IN_V2: + // Waveshare 2.13" V2 uses the same LUTs as TTGO this->write_lut_(full_update ? FULL_UPDATE_LUT_TTGO : PARTIAL_UPDATE_LUT_TTGO, LUT_SIZE_TTGO); break; case TTGO_EPAPER_2_13_IN_B73: @@ -384,6 +391,41 @@ void HOT WaveshareEPaperTypeA::display() { this->at_update_ = (this->at_update_ + 1) % this->full_update_every_; } + if (this->model_ == WAVESHARE_EPAPER_2_13_IN_V2) { + // Set VCOM for full or partial update + this->command(0x2C); + this->data(full_update ? 0x55 : 0x26); + + if (!full_update) { + // Enable "ping-pong" + this->command(0x37); + this->data(0x00); + this->data(0x00); + this->data(0x00); + this->data(0x00); + this->data(0x40); + this->data(0x00); + this->data(0x00); + this->command(0x22); + this->data(0xc0); + this->command(0x20); + } + } + + // Border waveform + switch (this->model_) { + case TTGO_EPAPER_2_13_IN_B74: + this->command(0x3C); + this->data(full_update ? 0x05 : 0x80); + break; + case WAVESHARE_EPAPER_2_13_IN_V2: + this->command(0x3C); + this->data(full_update ? 0x03 : 0x01); + break; + default: + break; + } + // Set x & y regions we want to write to (full) switch (this->model_) { case TTGO_EPAPER_2_13_IN_B1: @@ -407,12 +449,6 @@ void HOT WaveshareEPaperTypeA::display() { this->data((this->get_height_internal() - 1) >> 8); break; - case TTGO_EPAPER_2_13_IN_B74: - // BorderWaveform - this->command(0x3C); - this->data(full_update ? 0x05 : 0x80); - - // fall through default: // COMMAND SET RAM X ADDRESS START END POSITION this->command(0x44); @@ -458,6 +494,14 @@ void HOT WaveshareEPaperTypeA::display() { } this->end_data_(); + if (this->model_ == WAVESHARE_EPAPER_2_13_IN_V2 && full_update) { + // Write base image again on full refresh + this->command(0x26); + this->start_data_(); + this->write_array(this->buffer_, this->get_buffer_length_()); + this->end_data_(); + } + // COMMAND DISPLAY UPDATE CONTROL 2 this->command(0x22); switch (this->model_) { @@ -469,6 +513,9 @@ void HOT WaveshareEPaperTypeA::display() { case TTGO_EPAPER_2_13_IN_B73: this->data(0xC7); break; + case WAVESHARE_EPAPER_2_13_IN_V2: + this->data(full_update ? 0xC7 : 0x0C); + break; default: this->data(0xC4); break; @@ -492,6 +539,7 @@ int WaveshareEPaperTypeA::get_width_internal() { case WAVESHARE_EPAPER_1_54_IN_V2: return 200; case WAVESHARE_EPAPER_2_13_IN: + case WAVESHARE_EPAPER_2_13_IN_V2: case TTGO_EPAPER_2_13_IN: case TTGO_EPAPER_2_13_IN_B73: case TTGO_EPAPER_2_13_IN_B74: @@ -507,6 +555,7 @@ int WaveshareEPaperTypeA::get_width_internal() { int WaveshareEPaperTypeA::get_width_controller() { switch (this->model_) { case WAVESHARE_EPAPER_2_13_IN: + case WAVESHARE_EPAPER_2_13_IN_V2: case TTGO_EPAPER_2_13_IN: case TTGO_EPAPER_2_13_IN_B73: case TTGO_EPAPER_2_13_IN_B74: @@ -522,6 +571,7 @@ int WaveshareEPaperTypeA::get_height_internal() { case WAVESHARE_EPAPER_1_54_IN_V2: return 200; case WAVESHARE_EPAPER_2_13_IN: + case WAVESHARE_EPAPER_2_13_IN_V2: case TTGO_EPAPER_2_13_IN: case TTGO_EPAPER_2_13_IN_B73: case TTGO_EPAPER_2_13_IN_B74: @@ -548,6 +598,7 @@ uint32_t WaveshareEPaperTypeA::idle_timeout_() { switch (this->model_) { case WAVESHARE_EPAPER_1_54_IN: case WAVESHARE_EPAPER_1_54_IN_V2: + case WAVESHARE_EPAPER_2_13_IN_V2: case TTGO_EPAPER_2_13_IN_B1: return 2500; default: diff --git a/esphome/components/waveshare_epaper/waveshare_epaper.h b/esphome/components/waveshare_epaper/waveshare_epaper.h index f12d5f7d54..ffc099ca56 100644 --- a/esphome/components/waveshare_epaper/waveshare_epaper.h +++ b/esphome/components/waveshare_epaper/waveshare_epaper.h @@ -90,6 +90,7 @@ enum WaveshareEPaperTypeAModel { WAVESHARE_EPAPER_1_54_IN = 0, WAVESHARE_EPAPER_1_54_IN_V2, WAVESHARE_EPAPER_2_13_IN, + WAVESHARE_EPAPER_2_13_IN_V2, WAVESHARE_EPAPER_2_9_IN, WAVESHARE_EPAPER_2_9_IN_V2, TTGO_EPAPER_2_13_IN, @@ -114,6 +115,7 @@ class WaveshareEPaperTypeA : public WaveshareEPaper { case WAVESHARE_EPAPER_1_54_IN: case WAVESHARE_EPAPER_1_54_IN_V2: case WAVESHARE_EPAPER_2_9_IN_V2: + case WAVESHARE_EPAPER_2_13_IN_V2: // COMMAND DEEP SLEEP MODE this->command(0x10); this->data(0x01); @@ -124,7 +126,11 @@ class WaveshareEPaperTypeA : public WaveshareEPaper { this->command(0x10); break; } - this->wait_until_idle_(); + if (this->model_ != WAVESHARE_EPAPER_2_13_IN_V2) { + // From panel specification: + // "After this command initiated, the chip will enter Deep Sleep Mode, BUSY pad will keep output high." + this->wait_until_idle_(); + } } void set_full_update_every(uint32_t full_update_every); diff --git a/tests/components/waveshare_epaper/test.esp32.yaml b/tests/components/waveshare_epaper/test.esp32.yaml new file mode 100644 index 0000000000..616698f902 --- /dev/null +++ b/tests/components/waveshare_epaper/test.esp32.yaml @@ -0,0 +1,154 @@ +--- +spi: + - id: spi_id_1 + clk_pin: + number: GPIO18 + mosi_pin: + number: GPIO23 + miso_pin: + number: GPIO19 + interface: hardware + +display: + - platform: waveshare_epaper + model: 2.13in-ttgo-b1 + spi_id: spi_id_1 + cs_pin: + allow_other_uses: true + number: GPIO25 + dc_pin: + allow_other_uses: true + number: GPIO26 + busy_pin: + allow_other_uses: true + number: GPIO27 + reset_pin: + allow_other_uses: true + number: GPIO32 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + model: 2.90in + spi_id: spi_id_1 + cs_pin: + allow_other_uses: true + number: GPIO25 + dc_pin: + allow_other_uses: true + number: GPIO26 + busy_pin: + allow_other_uses: true + number: GPIO27 + reset_pin: + allow_other_uses: true + number: GPIO32 + full_update_every: 30 + reset_duration: 200ms + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + model: 2.90inv2 + spi_id: spi_id_1 + cs_pin: + allow_other_uses: true + number: GPIO25 + dc_pin: + allow_other_uses: true + number: GPIO26 + busy_pin: + allow_other_uses: true + number: GPIO27 + reset_pin: + allow_other_uses: true + number: GPIO32 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + model: 2.70in-b + spi_id: spi_id_1 + cs_pin: + allow_other_uses: true + number: GPIO25 + dc_pin: + allow_other_uses: true + number: GPIO26 + busy_pin: + allow_other_uses: true + number: GPIO27 + reset_pin: + allow_other_uses: true + number: GPIO32 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + model: 2.70in-bv2 + spi_id: spi_id_1 + cs_pin: + allow_other_uses: true + number: GPIO25 + dc_pin: + allow_other_uses: true + number: GPIO26 + busy_pin: + allow_other_uses: true + number: GPIO27 + reset_pin: + allow_other_uses: true + number: GPIO32 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + model: 1.54in-m5coreink-m09 + spi_id: spi_id_1 + cs_pin: + allow_other_uses: true + number: GPIO25 + dc_pin: + allow_other_uses: true + number: GPIO26 + busy_pin: + allow_other_uses: true + number: GPIO27 + reset_pin: + allow_other_uses: true + number: GPIO32 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + model: 2.13inv3 + spi_id: spi_id_1 + cs_pin: + allow_other_uses: true + number: GPIO25 + dc_pin: + allow_other_uses: true + number: GPIO26 + busy_pin: + allow_other_uses: true + number: GPIO27 + reset_pin: + allow_other_uses: true + number: GPIO32 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + model: 2.13inv2 + spi_id: spi_id_1 + cs_pin: + allow_other_uses: true + number: GPIO25 + dc_pin: + allow_other_uses: true + number: GPIO26 + busy_pin: + allow_other_uses: true + number: GPIO27 + reset_pin: + allow_other_uses: true + number: GPIO32 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); diff --git a/tests/test4.yaml b/tests/test4.yaml index 7cda05381f..993ce126a8 100644 --- a/tests/test4.yaml +++ b/tests/test4.yaml @@ -612,112 +612,6 @@ display: rotation: 0° update_interval: 16ms - - platform: waveshare_epaper - spi_id: spi_id_1 - cs_pin: - allow_other_uses: true - number: GPIO23 - dc_pin: - allow_other_uses: true - number: GPIO23 - busy_pin: - allow_other_uses: true - number: GPIO23 - reset_pin: - allow_other_uses: true - number: GPIO23 - model: 2.13in-ttgo-b1 - full_update_every: 30 - lambda: |- - it.rectangle(0, 0, it.get_width(), it.get_height()); - - platform: waveshare_epaper - spi_id: spi_id_1 - cs_pin: - allow_other_uses: true - number: GPIO23 - dc_pin: - allow_other_uses: true - number: GPIO23 - busy_pin: - allow_other_uses: true - number: GPIO23 - reset_pin: - allow_other_uses: true - number: GPIO23 - model: 2.90in - full_update_every: 30 - reset_duration: 200ms - lambda: |- - it.rectangle(0, 0, it.get_width(), it.get_height()); - - platform: waveshare_epaper - spi_id: spi_id_1 - cs_pin: - allow_other_uses: true - number: GPIO23 - dc_pin: - allow_other_uses: true - number: GPIO23 - busy_pin: - allow_other_uses: true - number: GPIO23 - reset_pin: - allow_other_uses: true - number: GPIO23 - model: 2.90inv2 - full_update_every: 30 - lambda: |- - it.rectangle(0, 0, it.get_width(), it.get_height()); - - platform: waveshare_epaper - spi_id: spi_id_1 - cs_pin: - allow_other_uses: true - number: GPIO23 - dc_pin: - allow_other_uses: true - number: GPIO23 - busy_pin: - allow_other_uses: true - number: GPIO23 - reset_pin: - allow_other_uses: true - number: GPIO23 - model: 2.70in-b - lambda: |- - it.rectangle(0, 0, it.get_width(), it.get_height()); - - platform: waveshare_epaper - spi_id: spi_id_1 - cs_pin: - allow_other_uses: true - number: GPIO23 - dc_pin: - allow_other_uses: true - number: GPIO23 - busy_pin: - allow_other_uses: true - number: GPIO23 - reset_pin: - allow_other_uses: true - number: GPIO23 - model: 2.70in-bv2 - lambda: |- - it.rectangle(0, 0, it.get_width(), it.get_height()); - - platform: waveshare_epaper - spi_id: spi_id_1 - cs_pin: - allow_other_uses: true - number: GPIO23 - dc_pin: - allow_other_uses: true - number: GPIO23 - busy_pin: - allow_other_uses: true - number: GPIO23 - reset_pin: - allow_other_uses: true - number: GPIO23 - model: 1.54in-m5coreink-m09 - lambda: |- - it.rectangle(0, 0, it.get_width(), it.get_height()); - platform: inkplate6 id: inkplate_display greyscale: false @@ -771,24 +665,6 @@ display: vcom_pin: number: GPIO1 allow_other_uses: true - - platform: waveshare_epaper - spi_id: spi_id_1 - cs_pin: - number: GPIO23 - allow_other_uses: true - dc_pin: - number: GPIO23 - allow_other_uses: true - busy_pin: - number: GPIO23 - allow_other_uses: true - reset_pin: - number: GPIO23 - allow_other_uses: true - model: 2.13inv3 - full_update_every: 30 - lambda: |- - it.rectangle(0, 0, it.get_width(), it.get_height()); number: - platform: tuya From 8cb689b58c4fa6279bcc765f93f86510ec940289 Mon Sep 17 00:00:00 2001 From: RubyBailey <60991881+RubyBailey@users.noreply.github.com> Date: Mon, 11 Mar 2024 14:01:05 -0700 Subject: [PATCH 082/189] Mitsubishi Climate updates (#3886) Co-authored-by: Blair McBride Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Co-authored-by: RubyBailey Co-authored-by: X-Ryl669 Co-authored-by: OlympusMonds --- esphome/components/mitsubishi/climate.py | 52 ++- esphome/components/mitsubishi/mitsubishi.cpp | 335 ++++++++++++++++++- esphome/components/mitsubishi/mitsubishi.h | 63 +++- tests/test1.yaml | 4 + 4 files changed, 436 insertions(+), 18 deletions(-) diff --git a/esphome/components/mitsubishi/climate.py b/esphome/components/mitsubishi/climate.py index 0df17a5d16..5e865c636f 100644 --- a/esphome/components/mitsubishi/climate.py +++ b/esphome/components/mitsubishi/climate.py @@ -9,9 +9,53 @@ AUTO_LOAD = ["climate_ir"] mitsubishi_ns = cg.esphome_ns.namespace("mitsubishi") MitsubishiClimate = mitsubishi_ns.class_("MitsubishiClimate", climate_ir.ClimateIR) -CONFIG_SCHEMA = climate_ir.CLIMATE_IR_SCHEMA.extend( +CONF_SET_FAN_MODE = "set_fan_mode" +SetFanMode = mitsubishi_ns.enum("SetFanMode") +SETFANMODE = { + "quiet_4levels": SetFanMode.MITSUBISHI_FAN_Q4L, + # "5levels": SetFanMode.MITSUBISHI_FAN_5L, + "4levels": SetFanMode.MITSUBISHI_FAN_4L, + "3levels": SetFanMode.MITSUBISHI_FAN_3L, +} + +CONF_SUPPORTS_DRY = "supports_dry" +CONF_SUPPORTS_FAN_ONLY = "supports_fan_only" + +CONF_HORIZONTAL_DEFAULT = "horizontal_default" +HorizontalDirections = mitsubishi_ns.enum("HorizontalDirections") +HORIZONTAL_DIRECTIONS = { + "left": HorizontalDirections.HORIZONTAL_DIRECTION_LEFT, + "middle-left": HorizontalDirections.HORIZONTAL_DIRECTION_MIDDLE_LEFT, + "middle": HorizontalDirections.HORIZONTAL_DIRECTION_MIDDLE, + "middle-right": HorizontalDirections.HORIZONTAL_DIRECTION_MIDDLE_RIGHT, + "right": HorizontalDirections.HORIZONTAL_DIRECTION_RIGHT, + "split": HorizontalDirections.HORIZONTAL_DIRECTION_SPLIT, +} + +CONF_VERTICAL_DEFAULT = "vertical_default" +VerticalDirections = mitsubishi_ns.enum("VerticalDirections") +VERTICAL_DIRECTIONS = { + "auto": VerticalDirections.VERTICAL_DIRECTION_AUTO, + "up": VerticalDirections.VERTICAL_DIRECTION_UP, + "middle-up": VerticalDirections.VERTICAL_DIRECTION_MIDDLE_UP, + "middle": VerticalDirections.VERTICAL_DIRECTION_MIDDLE, + "middle-down": VerticalDirections.VERTICAL_DIRECTION_MIDDLE_DOWN, + "down": VerticalDirections.VERTICAL_DIRECTION_DOWN, +} + + +CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend( { cv.GenerateID(): cv.declare_id(MitsubishiClimate), + cv.Optional(CONF_SET_FAN_MODE, default="3levels"): cv.enum(SETFANMODE), + cv.Optional(CONF_SUPPORTS_DRY, default=False): cv.boolean, + cv.Optional(CONF_SUPPORTS_FAN_ONLY, default=False): cv.boolean, + cv.Optional(CONF_HORIZONTAL_DEFAULT, default="middle"): cv.enum( + HORIZONTAL_DIRECTIONS + ), + cv.Optional(CONF_VERTICAL_DEFAULT, default="middle"): cv.enum( + VERTICAL_DIRECTIONS + ), } ) @@ -19,3 +63,9 @@ CONFIG_SCHEMA = climate_ir.CLIMATE_IR_SCHEMA.extend( async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await climate_ir.register_climate_ir(var, config) + + cg.add(var.set_fan_mode(config[CONF_SET_FAN_MODE])) + cg.add(var.set_supports_dry(config[CONF_SUPPORTS_DRY])) + cg.add(var.set_supports_fan_only(config[CONF_SUPPORTS_FAN_ONLY])) + cg.add(var.set_horizontal_default(config[CONF_HORIZONTAL_DEFAULT])) + cg.add(var.set_vertical_default(config[CONF_VERTICAL_DEFAULT])) diff --git a/esphome/components/mitsubishi/mitsubishi.cpp b/esphome/components/mitsubishi/mitsubishi.cpp index 87b78128e4..081c24a050 100644 --- a/esphome/components/mitsubishi/mitsubishi.cpp +++ b/esphome/components/mitsubishi/mitsubishi.cpp @@ -8,12 +8,31 @@ static const char *const TAG = "mitsubishi.climate"; const uint32_t MITSUBISHI_OFF = 0x00; -const uint8_t MITSUBISHI_COOL = 0x18; -const uint8_t MITSUBISHI_DRY = 0x10; -const uint8_t MITSUBISHI_AUTO = 0x20; -const uint8_t MITSUBISHI_HEAT = 0x08; +const uint8_t MITSUBISHI_MODE_AUTO = 0x20; +const uint8_t MITSUBISHI_MODE_COOL = 0x18; +const uint8_t MITSUBISHI_MODE_DRY = 0x10; +const uint8_t MITSUBISHI_MODE_FAN_ONLY = 0x38; +const uint8_t MITSUBISHI_MODE_HEAT = 0x08; + +const uint8_t MITSUBISHI_MODE_A_HEAT = 0x00; +const uint8_t MITSUBISHI_MODE_A_DRY = 0x02; +const uint8_t MITSUBISHI_MODE_A_COOL = 0x06; +const uint8_t MITSUBISHI_MODE_A_AUTO = 0x06; + +const uint8_t MITSUBISHI_WIDE_VANE_SWING = 0xC0; + const uint8_t MITSUBISHI_FAN_AUTO = 0x00; +const uint8_t MITSUBISHI_VERTICAL_VANE_SWING = 0x38; + +// const uint8_t MITSUBISHI_AUTO = 0X80; +const uint8_t MITSUBISHI_OTHERWISE = 0X40; +const uint8_t MITSUBISHI_POWERFUL = 0x08; + +// Optional presets used to enable some model features +const uint8_t MITSUBISHI_ECONOCOOL = 0x20; +const uint8_t MITSUBISHI_NIGHTMODE = 0xC1; + // Pulse parameters in usec const uint16_t MITSUBISHI_BIT_MARK = 430; const uint16_t MITSUBISHI_ONE_SPACE = 1250; @@ -22,19 +41,97 @@ const uint16_t MITSUBISHI_HEADER_MARK = 3500; const uint16_t MITSUBISHI_HEADER_SPACE = 1700; const uint16_t MITSUBISHI_MIN_GAP = 17500; +// Marker bytes +const uint8_t MITSUBISHI_BYTE00 = 0X23; +const uint8_t MITSUBISHI_BYTE01 = 0XCB; +const uint8_t MITSUBISHI_BYTE02 = 0X26; +const uint8_t MITSUBISHI_BYTE03 = 0X01; +const uint8_t MITSUBISHI_BYTE04 = 0X00; +const uint8_t MITSUBISHI_BYTE13 = 0X00; +const uint8_t MITSUBISHI_BYTE16 = 0X00; + +climate::ClimateTraits MitsubishiClimate::traits() { + auto traits = climate::ClimateTraits(); + traits.set_supports_action(false); + traits.set_visual_min_temperature(MITSUBISHI_TEMP_MIN); + traits.set_visual_max_temperature(MITSUBISHI_TEMP_MAX); + traits.set_visual_temperature_step(1.0f); + traits.set_supported_modes({climate::CLIMATE_MODE_OFF}); + + if (this->supports_cool_) + traits.add_supported_mode(climate::CLIMATE_MODE_COOL); + if (this->supports_heat_) + traits.add_supported_mode(climate::CLIMATE_MODE_HEAT); + + if (this->supports_cool_ && this->supports_heat_) + traits.add_supported_mode(climate::CLIMATE_MODE_HEAT_COOL); + + if (this->supports_dry_) + traits.add_supported_mode(climate::CLIMATE_MODE_DRY); + if (this->supports_fan_only_) + traits.add_supported_mode(climate::CLIMATE_MODE_FAN_ONLY); + + // Default to only 3 levels in ESPHome even if most unit supports 4. The 3rd level is not used. + traits.set_supported_fan_modes( + {climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM, climate::CLIMATE_FAN_HIGH}); + if (this->fan_mode_ == MITSUBISHI_FAN_Q4L) + traits.add_supported_fan_mode(climate::CLIMATE_FAN_QUIET); + if (/*this->fan_mode_ == MITSUBISHI_FAN_5L ||*/ this->fan_mode_ >= MITSUBISHI_FAN_4L) + traits.add_supported_fan_mode(climate::CLIMATE_FAN_MIDDLE); // Shouldn't be used for this but it helps + + traits.set_supported_swing_modes({climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_BOTH, + climate::CLIMATE_SWING_VERTICAL, climate::CLIMATE_SWING_HORIZONTAL}); + + traits.set_supported_presets({climate::CLIMATE_PRESET_NONE, climate::CLIMATE_PRESET_ECO, + climate::CLIMATE_PRESET_BOOST, climate::CLIMATE_PRESET_SLEEP}); + + return traits; +} + void MitsubishiClimate::transmit_state() { - uint32_t remote_state[18] = {0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x08, 0x00, 0x30, - 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + // Byte 0-4: Constant: 0x23, 0xCB, 0x26, 0x01, 0x00 + // Byte 5: On=0x20, Off: 0x00 + // Byte 6: MODE (See MODEs above (Heat/Dry/Cool/Auto/FanOnly) + // Byte 7: TEMP bits 0,1,2,3, added to MITSUBISHI_TEMP_MIN + // Example: 0x00 = 0°C+MITSUBISHI_TEMP_MIN = 16°C; 0x07 = 7°C+MITSUBISHI_TEMP_MIN = 23°C + // Byte 8: MODE_A & Wide Vane (if present) + // MODE_A bits 0,1,2 different than Byte 6 (See MODE_As above) + // Wide Vane bits 4,5,6,7 (Middle = 0x30) + // Byte 9: FAN/Vertical Vane/Switch To Auto + // FAN (Speed) bits 0,1,2 + // Vertical Vane bits 3,4,5 (Auto = 0x00) + // Switch To Auto bits 6,7 + // Byte 10: CLOCK Current time as configured on remote (0x00=Not used) + // Byte 11: END CLOCK Stop time of HVAC (0x00 for no setting) + // Byte 12: START CLOCK Start time of HVAC (0x00 for no setting) + // Byte 13: Constant 0x00 + // Byte 14: HVAC specfic, i.e. ECONO COOL, CLEAN MODE, always 0x00 + // Byte 15: HVAC specfic, i.e. POWERFUL, SMART SET, PLASMA, always 0x00 + // Byte 16: Constant 0x00 + // Byte 17: Checksum: SUM[Byte0...Byte16] + uint32_t remote_state[18] = {0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; switch (this->mode) { - case climate::CLIMATE_MODE_COOL: - remote_state[6] = MITSUBISHI_COOL; - break; case climate::CLIMATE_MODE_HEAT: - remote_state[6] = MITSUBISHI_HEAT; + remote_state[6] = MITSUBISHI_MODE_HEAT; + remote_state[8] = MITSUBISHI_MODE_A_HEAT; + break; + case climate::CLIMATE_MODE_DRY: + remote_state[6] = MITSUBISHI_MODE_DRY; + remote_state[8] = MITSUBISHI_MODE_A_DRY; + break; + case climate::CLIMATE_MODE_COOL: + remote_state[6] = MITSUBISHI_MODE_COOL; + remote_state[8] = MITSUBISHI_MODE_A_COOL; break; case climate::CLIMATE_MODE_HEAT_COOL: - remote_state[6] = MITSUBISHI_AUTO; + remote_state[6] = MITSUBISHI_MODE_AUTO; + remote_state[8] = MITSUBISHI_MODE_A_AUTO; + break; + case climate::CLIMATE_MODE_FAN_ONLY: + remote_state[6] = MITSUBISHI_MODE_FAN_ONLY; + remote_state[8] = MITSUBISHI_MODE_A_AUTO; break; case climate::CLIMATE_MODE_OFF: default: @@ -42,17 +139,111 @@ void MitsubishiClimate::transmit_state() { break; } - remote_state[7] = (uint8_t) roundf(clamp(this->target_temperature, MITSUBISHI_TEMP_MIN, MITSUBISHI_TEMP_MAX) - - MITSUBISHI_TEMP_MIN); + // Temperature + if (this->mode == climate::CLIMATE_MODE_DRY) { + remote_state[7] = 24 - MITSUBISHI_TEMP_MIN; // Remote sends always 24°C if "Dry" mode is selected + } else { + remote_state[7] = (uint8_t) roundf( + clamp(this->target_temperature, MITSUBISHI_TEMP_MIN, MITSUBISHI_TEMP_MAX) - MITSUBISHI_TEMP_MIN); + } - ESP_LOGV(TAG, "Sending Mitsubishi target temp: %.1f state: %02" PRIX32 " mode: %02" PRIX32 " temp: %02" PRIX32, - this->target_temperature, remote_state[5], remote_state[6], remote_state[7]); + // Wide Vane + switch (this->swing_mode) { + case climate::CLIMATE_SWING_HORIZONTAL: + case climate::CLIMATE_SWING_BOTH: + remote_state[8] = remote_state[8] | MITSUBISHI_WIDE_VANE_SWING; // Wide Vane Swing + break; + case climate::CLIMATE_SWING_OFF: + default: + remote_state[8] = remote_state[8] | this->default_horizontal_direction_; // Off--> horizontal default position + break; + } + + ESP_LOGD(TAG, "default_horizontal_direction_: %02X", this->default_horizontal_direction_); + + // Fan Speed & Vertical Vane + // Map of Climate fan mode to this device expected value + // For 3Level: Low = 1, Medium = 2, High = 3 + // For 4Level: Low = 1, Middle = 2, Medium = 3, High = 4 + // For 5Level: Low = 1, Middle = 2, Medium = 3, High = 4 + // For 4Level + Quiet: Low = 1, Middle = 2, Medium = 3, High = 4, Quiet = 5 + + switch (this->fan_mode.value()) { + case climate::CLIMATE_FAN_LOW: + remote_state[9] = 1; + break; + case climate::CLIMATE_FAN_MEDIUM: + if (this->fan_mode_ == MITSUBISHI_FAN_3L) { + remote_state[9] = 2; + } else { + remote_state[9] = 3; + } + break; + case climate::CLIMATE_FAN_HIGH: + if (this->fan_mode_ == MITSUBISHI_FAN_3L) { + remote_state[9] = 3; + } else { + remote_state[9] = 4; + } + break; + case climate::CLIMATE_FAN_MIDDLE: + remote_state[9] = 2; + break; + case climate::CLIMATE_FAN_QUIET: + remote_state[9] = 5; + break; + default: + remote_state[9] = MITSUBISHI_FAN_AUTO; + break; + } + + ESP_LOGD(TAG, "fan: %02x state: %02x", this->fan_mode.value(), remote_state[9]); + + // Vertical Vane + switch (this->swing_mode) { + case climate::CLIMATE_SWING_VERTICAL: + case climate::CLIMATE_SWING_BOTH: + remote_state[9] = remote_state[9] | MITSUBISHI_VERTICAL_VANE_SWING | MITSUBISHI_OTHERWISE; // Vane Swing + break; + case climate::CLIMATE_SWING_OFF: + default: + remote_state[9] = remote_state[9] | this->default_vertical_direction_ | + MITSUBISHI_OTHERWISE; // Off--> vertical default position + break; + } + + ESP_LOGD(TAG, "default_vertical_direction_: %02X", this->default_vertical_direction_); + + // Special modes + switch (this->preset.value()) { + case climate::CLIMATE_PRESET_ECO: + remote_state[6] = MITSUBISHI_MODE_COOL | MITSUBISHI_OTHERWISE; + remote_state[8] = (remote_state[8] & ~7) | MITSUBISHI_MODE_A_COOL; + remote_state[14] = MITSUBISHI_ECONOCOOL; + break; + case climate::CLIMATE_PRESET_SLEEP: + remote_state[9] = MITSUBISHI_FAN_AUTO; + remote_state[14] = MITSUBISHI_NIGHTMODE; + break; + case climate::CLIMATE_PRESET_BOOST: + remote_state[6] |= MITSUBISHI_OTHERWISE; + remote_state[15] = MITSUBISHI_POWERFUL; + break; + case climate::CLIMATE_PRESET_NONE: + default: + break; + } // Checksum for (int i = 0; i < 17; i++) { remote_state[17] += remote_state[i]; } + ESP_LOGD(TAG, "sending: %02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X", + remote_state[0], remote_state[1], remote_state[2], remote_state[3], remote_state[4], remote_state[5], + remote_state[6], remote_state[7], remote_state[8], remote_state[9], remote_state[10], remote_state[11], + remote_state[12], remote_state[13], remote_state[14], remote_state[15], remote_state[16], remote_state[17]); + auto transmit = this->transmitter_->transmit(); auto *data = transmit.get_data(); @@ -81,5 +272,119 @@ void MitsubishiClimate::transmit_state() { transmit.perform(); } +bool MitsubishiClimate::parse_state_frame_(const uint8_t frame[]) { return false; } + +bool MitsubishiClimate::on_receive(remote_base::RemoteReceiveData data) { + uint8_t state_frame[18] = {}; + + if (!data.expect_item(MITSUBISHI_HEADER_MARK, MITSUBISHI_HEADER_SPACE)) { + ESP_LOGV(TAG, "Header fail"); + return false; + } + + for (uint8_t pos = 0; pos < 18; pos++) { + uint8_t byte = 0; + for (int8_t bit = 0; bit < 8; bit++) { + if (data.expect_item(MITSUBISHI_BIT_MARK, MITSUBISHI_ONE_SPACE)) { + byte |= 1 << bit; + } else if (!data.expect_item(MITSUBISHI_BIT_MARK, MITSUBISHI_ZERO_SPACE)) { + ESP_LOGV(TAG, "Byte %d bit %d fail", pos, bit); + return false; + } + } + state_frame[pos] = byte; + + // Check Header && Footer + if ((pos == 0 && byte != MITSUBISHI_BYTE00) || (pos == 1 && byte != MITSUBISHI_BYTE01) || + (pos == 2 && byte != MITSUBISHI_BYTE02) || (pos == 3 && byte != MITSUBISHI_BYTE03) || + (pos == 4 && byte != MITSUBISHI_BYTE04) || (pos == 13 && byte != MITSUBISHI_BYTE13) || + (pos == 16 && byte != MITSUBISHI_BYTE16)) { + ESP_LOGV(TAG, "Bytes 0,1,2,3,4,13 or 16 fail - invalid value"); + return false; + } + } + + // On/Off and Mode + if (state_frame[5] == MITSUBISHI_OFF) { + this->mode = climate::CLIMATE_MODE_OFF; + } else { + switch (state_frame[6]) { + case MITSUBISHI_MODE_HEAT: + this->mode = climate::CLIMATE_MODE_HEAT; + break; + case MITSUBISHI_MODE_DRY: + this->mode = climate::CLIMATE_MODE_DRY; + break; + case MITSUBISHI_MODE_COOL: + this->mode = climate::CLIMATE_MODE_COOL; + break; + case MITSUBISHI_MODE_FAN_ONLY: + this->mode = climate::CLIMATE_MODE_FAN_ONLY; + break; + case MITSUBISHI_MODE_AUTO: + this->mode = climate::CLIMATE_MODE_HEAT_COOL; + break; + } + } + + // Temp + this->target_temperature = state_frame[7] + MITSUBISHI_TEMP_MIN; + + // Fan + uint8_t fan = state_frame[9] & 0x07; //(Bit 0,1,2 = Speed) + // Map of Climate fan mode to this device expected value + // For 3Level: Low = 1, Medium = 2, High = 3 + // For 4Level: Low = 1, Middle = 2, Medium = 3, High = 4 + // For 5Level: Low = 1, Middle = 2, Medium = 3, High = 4 + // For 4Level + Quiet: Low = 1, Middle = 2, Medium = 3, High = 4, Quiet = 5 + climate::ClimateFanMode modes_mapping[8] = { + climate::CLIMATE_FAN_AUTO, + climate::CLIMATE_FAN_LOW, + this->fan_mode_ == MITSUBISHI_FAN_3L ? climate::CLIMATE_FAN_MEDIUM : climate::CLIMATE_FAN_MIDDLE, + this->fan_mode_ == MITSUBISHI_FAN_3L ? climate::CLIMATE_FAN_HIGH : climate::CLIMATE_FAN_MEDIUM, + climate::CLIMATE_FAN_HIGH, + climate::CLIMATE_FAN_QUIET, + climate::CLIMATE_FAN_AUTO, + climate::CLIMATE_FAN_AUTO}; + this->fan_mode = modes_mapping[fan]; + + // Wide Vane + uint8_t wide_vane = state_frame[8] & 0xF0; // Bits 4,5,6,7 + switch (wide_vane) { + case MITSUBISHI_WIDE_VANE_SWING: + this->swing_mode = climate::CLIMATE_SWING_HORIZONTAL; + break; + default: + this->swing_mode = climate::CLIMATE_SWING_OFF; + break; + } + + // Vertical Vane + uint8_t vertical_vane = state_frame[9] & 0x38; // Bits 3,4,5 + switch (vertical_vane) { + case MITSUBISHI_VERTICAL_VANE_SWING: + if (this->swing_mode == climate::CLIMATE_SWING_HORIZONTAL) { + this->swing_mode = climate::CLIMATE_SWING_BOTH; + } else { + this->swing_mode = climate::CLIMATE_SWING_VERTICAL; + } + break; + } + + switch (state_frame[14]) { + case MITSUBISHI_ECONOCOOL: + this->preset = climate::CLIMATE_PRESET_ECO; + break; + case MITSUBISHI_NIGHTMODE: + this->preset = climate::CLIMATE_PRESET_SLEEP; + break; + } + + ESP_LOGV(TAG, "Receiving: %s", format_hex_pretty(state_frame, 18).c_str()); + + this->publish_state(); + return true; +} + } // namespace mitsubishi } // namespace esphome diff --git a/esphome/components/mitsubishi/mitsubishi.h b/esphome/components/mitsubishi/mitsubishi.h index 9a88040d3f..cfe12428da 100644 --- a/esphome/components/mitsubishi/mitsubishi.h +++ b/esphome/components/mitsubishi/mitsubishi.h @@ -11,13 +11,72 @@ namespace mitsubishi { const uint8_t MITSUBISHI_TEMP_MIN = 16; // Celsius const uint8_t MITSUBISHI_TEMP_MAX = 31; // Celsius +// Fan mode +enum SetFanMode { + MITSUBISHI_FAN_3L = 0, // 3 levels + auto + MITSUBISHI_FAN_4L, // 4 levels + auto + MITSUBISHI_FAN_Q4L, // Quiet + 4 levels + auto + // MITSUBISHI_FAN_5L, // 5 levels + auto +}; + +// Enum to represent horizontal directios +enum HorizontalDirection { + HORIZONTAL_DIRECTION_LEFT = 0x10, + HORIZONTAL_DIRECTION_MIDDLE_LEFT = 0x20, + HORIZONTAL_DIRECTION_MIDDLE = 0x30, + HORIZONTAL_DIRECTION_MIDDLE_RIGHT = 0x40, + HORIZONTAL_DIRECTION_RIGHT = 0x50, + HORIZONTAL_DIRECTION_SPLIT = 0x80, +}; + +// Enum to represent vertical directions +enum VerticalDirection { + VERTICAL_DIRECTION_AUTO = 0x00, + VERTICAL_DIRECTION_UP = 0x08, + VERTICAL_DIRECTION_MIDDLE_UP = 0x10, + VERTICAL_DIRECTION_MIDDLE = 0x18, + VERTICAL_DIRECTION_MIDDLE_DOWN = 0x20, + VERTICAL_DIRECTION_DOWN = 0x28, +}; + class MitsubishiClimate : public climate_ir::ClimateIR { public: - MitsubishiClimate() : climate_ir::ClimateIR(MITSUBISHI_TEMP_MIN, MITSUBISHI_TEMP_MAX) {} + MitsubishiClimate() + : climate_ir::ClimateIR(MITSUBISHI_TEMP_MIN, MITSUBISHI_TEMP_MAX, 1.0f, true, true, + {climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MIDDLE, + climate::CLIMATE_FAN_MEDIUM, climate::CLIMATE_FAN_HIGH, climate::CLIMATE_FAN_QUIET}, + {climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_BOTH, climate::CLIMATE_SWING_VERTICAL, + climate::CLIMATE_SWING_HORIZONTAL}, + {climate::CLIMATE_PRESET_NONE, climate::CLIMATE_PRESET_ECO, climate::CLIMATE_PRESET_BOOST, + climate::CLIMATE_PRESET_SLEEP}) {} + + void set_supports_cool(bool supports_cool) { this->supports_cool_ = supports_cool; } + void set_supports_dry(bool supports_dry) { this->supports_dry_ = supports_dry; } + void set_supports_fan_only(bool supports_fan_only) { this->supports_fan_only_ = supports_fan_only; } + void set_supports_heat(bool supports_heat) { this->supports_heat_ = supports_heat; } + + void set_fan_mode(SetFanMode fan_mode) { this->fan_mode_ = fan_mode; } + + void set_horizontal_default(HorizontalDirection horizontal_direction) { + this->default_horizontal_direction_ = horizontal_direction; + } + void set_vertical_default(VerticalDirection vertical_direction) { + this->default_vertical_direction_ = vertical_direction; + } protected: - /// Transmit via IR the state of this climate controller. + // Transmit via IR the state of this climate controller. void transmit_state() override; + // Handle received IR Buffer + bool on_receive(remote_base::RemoteReceiveData data) override; + bool parse_state_frame_(const uint8_t frame[]); + + SetFanMode fan_mode_; + + HorizontalDirection default_horizontal_direction_; + VerticalDirection default_vertical_direction_; + + climate::ClimateTraits traits() override; }; } // namespace mitsubishi diff --git a/tests/test1.yaml b/tests/test1.yaml index 505e839f5b..c8ae9691c2 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -2652,6 +2652,10 @@ climate: name: Yashima Climate - platform: mitsubishi name: Mitsubishi + supports_dry: "true" + supports_fan_only: "true" + horizontal_default: "left" + vertical_default: "down" - platform: whirlpool name: Whirlpool Climate - platform: climate_ir_lg From 1dd14254b3eddcf84903d36508cbd1649223a027 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:55:23 +1100 Subject: [PATCH 083/189] Drivers for RGB 16 bit parallel displays (#5872) Co-authored-by: clydebarrow <366188+clydebarrow@users.noreply.github.com> --- CODEOWNERS | 2 + esphome/components/rpi_dpi_rgb/__init__.py | 1 + esphome/components/rpi_dpi_rgb/display.py | 197 ++++++++++ .../components/rpi_dpi_rgb/rpi_dpi_rgb.cpp | 116 ++++++ esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.h | 92 +++++ esphome/components/st7701s/__init__.py | 1 + esphome/components/st7701s/display.py | 253 ++++++++++++ esphome/components/st7701s/init_sequences.py | 363 ++++++++++++++++++ esphome/components/st7701s/st7701s.cpp | 180 +++++++++ esphome/components/st7701s/st7701s.h | 115 ++++++ .../rpi_dpi_rgb/test.esp32-s3-idf.yaml | 40 ++ .../components/st7701s/test.esp32-s3-idf.yaml | 60 +++ 12 files changed, 1420 insertions(+) create mode 100644 esphome/components/rpi_dpi_rgb/__init__.py create mode 100644 esphome/components/rpi_dpi_rgb/display.py create mode 100644 esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp create mode 100644 esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.h create mode 100644 esphome/components/st7701s/__init__.py create mode 100644 esphome/components/st7701s/display.py create mode 100644 esphome/components/st7701s/init_sequences.py create mode 100644 esphome/components/st7701s/st7701s.cpp create mode 100644 esphome/components/st7701s/st7701s.h create mode 100644 tests/components/rpi_dpi_rgb/test.esp32-s3-idf.yaml create mode 100644 tests/components/st7701s/test.esp32-s3-idf.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 3b2d1eeeed..320c2d5e7e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -282,6 +282,7 @@ esphome/components/rgbct/* @jesserockz esphome/components/rp2040/* @jesserockz esphome/components/rp2040_pio_led_strip/* @Papa-DMan esphome/components/rp2040_pwm/* @jesserockz +esphome/components/rpi_dpi_rgb/* @clydebarrow esphome/components/rtl87xx/* @kuba2k2 esphome/components/rtttl/* @glmnet esphome/components/safe_mode/* @jsuanet @paulmonigatti @@ -333,6 +334,7 @@ esphome/components/ssd1351_spi/* @kbx81 esphome/components/st7567_base/* @latonita esphome/components/st7567_i2c/* @latonita esphome/components/st7567_spi/* @latonita +esphome/components/st7701s/* @clydebarrow esphome/components/st7735/* @SenexCrenshaw esphome/components/st7789v/* @kbx81 esphome/components/st7920/* @marsjan155 diff --git a/esphome/components/rpi_dpi_rgb/__init__.py b/esphome/components/rpi_dpi_rgb/__init__.py new file mode 100644 index 0000000000..c58ce8a01e --- /dev/null +++ b/esphome/components/rpi_dpi_rgb/__init__.py @@ -0,0 +1 @@ +CODEOWNERS = ["@clydebarrow"] diff --git a/esphome/components/rpi_dpi_rgb/display.py b/esphome/components/rpi_dpi_rgb/display.py new file mode 100644 index 0000000000..0cde16e0fb --- /dev/null +++ b/esphome/components/rpi_dpi_rgb/display.py @@ -0,0 +1,197 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome import pins +from esphome.components import display +from esphome.const import ( + CONF_RESET_PIN, + CONF_DATA_PINS, + CONF_ID, + CONF_IGNORE_STRAPPING_WARNING, + CONF_DIMENSIONS, + CONF_WIDTH, + CONF_HEIGHT, + CONF_LAMBDA, + CONF_COLOR_ORDER, + CONF_RED, + CONF_GREEN, + CONF_BLUE, + CONF_NUMBER, + CONF_OFFSET_HEIGHT, + CONF_OFFSET_WIDTH, + CONF_INVERT_COLORS, +) +from esphome.components.esp32 import ( + only_on_variant, + const, +) + +DEPENDENCIES = ["esp32"] + +CONF_DE_PIN = "de_pin" +CONF_PCLK_PIN = "pclk_pin" +CONF_HSYNC_PIN = "hsync_pin" +CONF_VSYNC_PIN = "vsync_pin" + +CONF_HSYNC_FRONT_PORCH = "hsync_front_porch" +CONF_HSYNC_PULSE_WIDTH = "hsync_pulse_width" +CONF_HSYNC_BACK_PORCH = "hsync_back_porch" +CONF_VSYNC_FRONT_PORCH = "vsync_front_porch" +CONF_VSYNC_PULSE_WIDTH = "vsync_pulse_width" +CONF_VSYNC_BACK_PORCH = "vsync_back_porch" +CONF_PCLK_FREQUENCY = "pclk_frequency" +CONF_PCLK_INVERTED = "pclk_inverted" + +rpi_dpi_rgb_ns = cg.esphome_ns.namespace("rpi_dpi_rgb") +RPI_DPI_RGB = rpi_dpi_rgb_ns.class_("RpiDpiRgb", display.Display, cg.Component) +ColorOrder = display.display_ns.enum("ColorMode") + +COLOR_ORDERS = { + "RGB": ColorOrder.COLOR_ORDER_RGB, + "BGR": ColorOrder.COLOR_ORDER_BGR, +} +DATA_PIN_SCHEMA = pins.internal_gpio_output_pin_schema + + +def data_pin_validate(value): + """ + It is safe to use strapping pins as RGB output data bits, as they are outputs only, + and not initialised until after boot. + """ + if not isinstance(value, dict): + try: + return DATA_PIN_SCHEMA( + {CONF_NUMBER: value, CONF_IGNORE_STRAPPING_WARNING: True} + ) + except cv.Invalid: + pass + return DATA_PIN_SCHEMA(value) + + +def data_pin_set(length): + return cv.All( + [data_pin_validate], + cv.Length(min=length, max=length, msg=f"Exactly {length} data pins required"), + ) + + +CONFIG_SCHEMA = cv.All( + display.FULL_DISPLAY_SCHEMA.extend( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(RPI_DPI_RGB), + cv.Required(CONF_DIMENSIONS): cv.Any( + cv.dimensions, + cv.Schema( + { + cv.Required(CONF_WIDTH): cv.int_, + cv.Required(CONF_HEIGHT): cv.int_, + cv.Optional(CONF_OFFSET_HEIGHT, default=0): cv.int_, + cv.Optional(CONF_OFFSET_WIDTH, default=0): cv.int_, + } + ), + ), + cv.Optional(CONF_PCLK_FREQUENCY, default="16MHz"): cv.All( + cv.frequency, cv.Range(min=4e6, max=30e6) + ), + cv.Optional(CONF_PCLK_INVERTED, default=True): cv.boolean, + cv.Required(CONF_DATA_PINS): cv.Any( + data_pin_set(16), + cv.Schema( + { + cv.Required(CONF_RED): data_pin_set(5), + cv.Required(CONF_GREEN): data_pin_set(6), + cv.Required(CONF_BLUE): data_pin_set(5), + } + ), + ), + cv.Optional(CONF_COLOR_ORDER): cv.one_of( + *COLOR_ORDERS.keys(), upper=True + ), + cv.Optional(CONF_INVERT_COLORS, default=False): cv.boolean, + cv.Required(CONF_DE_PIN): pins.internal_gpio_output_pin_schema, + cv.Required(CONF_PCLK_PIN): pins.internal_gpio_output_pin_schema, + cv.Required(CONF_HSYNC_PIN): pins.internal_gpio_output_pin_schema, + cv.Required(CONF_VSYNC_PIN): pins.internal_gpio_output_pin_schema, + cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema, + cv.Optional(CONF_HSYNC_PULSE_WIDTH, default=10): cv.int_, + cv.Optional(CONF_HSYNC_BACK_PORCH, default=10): cv.int_, + cv.Optional(CONF_HSYNC_FRONT_PORCH, default=20): cv.int_, + cv.Optional(CONF_VSYNC_PULSE_WIDTH, default=10): cv.int_, + cv.Optional(CONF_VSYNC_BACK_PORCH, default=10): cv.int_, + cv.Optional(CONF_VSYNC_FRONT_PORCH, default=10): cv.int_, + } + ) + ), + only_on_variant(supported=[const.VARIANT_ESP32S3]), + cv.only_with_esp_idf, +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await display.register_display(var, config) + + cg.add(var.set_color_mode(COLOR_ORDERS[config[CONF_COLOR_ORDER]])) + cg.add(var.set_invert_colors(config[CONF_INVERT_COLORS])) + cg.add(var.set_hsync_pulse_width(config[CONF_HSYNC_PULSE_WIDTH])) + cg.add(var.set_hsync_back_porch(config[CONF_HSYNC_BACK_PORCH])) + cg.add(var.set_hsync_front_porch(config[CONF_HSYNC_FRONT_PORCH])) + cg.add(var.set_vsync_pulse_width(config[CONF_VSYNC_PULSE_WIDTH])) + cg.add(var.set_vsync_back_porch(config[CONF_VSYNC_BACK_PORCH])) + cg.add(var.set_vsync_front_porch(config[CONF_VSYNC_FRONT_PORCH])) + cg.add(var.set_pclk_inverted(config[CONF_PCLK_INVERTED])) + cg.add(var.set_pclk_frequency(config[CONF_PCLK_FREQUENCY])) + index = 0 + dpins = [] + if CONF_RED in config[CONF_DATA_PINS]: + red_pins = config[CONF_DATA_PINS][CONF_RED] + green_pins = config[CONF_DATA_PINS][CONF_GREEN] + blue_pins = config[CONF_DATA_PINS][CONF_BLUE] + if config[CONF_COLOR_ORDER] == "BGR": + dpins.extend(red_pins) + dpins.extend(green_pins) + dpins.extend(blue_pins) + else: + dpins.extend(blue_pins) + dpins.extend(green_pins) + dpins.extend(red_pins) + # swap bytes to match big-endian format + dpins = dpins[8:16] + dpins[0:8] + else: + dpins = config[CONF_DATA_PINS] + for pin in dpins: + data_pin = await cg.gpio_pin_expression(pin) + cg.add(var.add_data_pin(data_pin, index)) + index += 1 + + if reset_pin := config.get(CONF_RESET_PIN): + reset = await cg.gpio_pin_expression(reset_pin) + cg.add(var.set_reset_pin(reset)) + + if CONF_DIMENSIONS in config: + dimensions = config[CONF_DIMENSIONS] + if isinstance(dimensions, dict): + cg.add(var.set_dimensions(dimensions[CONF_WIDTH], dimensions[CONF_HEIGHT])) + cg.add( + var.set_offsets( + dimensions[CONF_OFFSET_WIDTH], dimensions[CONF_OFFSET_HEIGHT] + ) + ) + else: + (width, height) = dimensions + cg.add(var.set_dimensions(width, height)) + + if lamb := config.get(CONF_LAMBDA): + lambda_ = await cg.process_lambda( + lamb, [(display.DisplayRef, "it")], return_type=cg.void + ) + cg.add(var.set_writer(lambda_)) + + pin = await cg.gpio_pin_expression(config[CONF_DE_PIN]) + cg.add(var.set_de_pin(pin)) + pin = await cg.gpio_pin_expression(config[CONF_PCLK_PIN]) + cg.add(var.set_pclk_pin(pin)) + pin = await cg.gpio_pin_expression(config[CONF_HSYNC_PIN]) + cg.add(var.set_hsync_pin(pin)) + pin = await cg.gpio_pin_expression(config[CONF_VSYNC_PIN]) + cg.add(var.set_vsync_pin(pin)) diff --git a/esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp b/esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp new file mode 100644 index 0000000000..2ffdb3272a --- /dev/null +++ b/esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp @@ -0,0 +1,116 @@ +#ifdef USE_ESP32_VARIANT_ESP32S3 +#include "rpi_dpi_rgb.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace rpi_dpi_rgb { + +void RpiDpiRgb::setup() { + esph_log_config(TAG, "Setting up RPI_DPI_RGB"); + esp_lcd_rgb_panel_config_t config{}; + config.flags.fb_in_psram = 1; + config.timings.h_res = this->width_; + config.timings.v_res = this->height_; + config.timings.hsync_pulse_width = this->hsync_pulse_width_; + config.timings.hsync_back_porch = this->hsync_back_porch_; + config.timings.hsync_front_porch = this->hsync_front_porch_; + config.timings.vsync_pulse_width = this->vsync_pulse_width_; + config.timings.vsync_back_porch = this->vsync_back_porch_; + config.timings.vsync_front_porch = this->vsync_front_porch_; + config.timings.flags.pclk_active_neg = this->pclk_inverted_; + config.timings.pclk_hz = this->pclk_frequency_; + config.clk_src = LCD_CLK_SRC_PLL160M; + config.sram_trans_align = 64; + config.psram_trans_align = 64; + size_t data_pin_count = sizeof(this->data_pins_) / sizeof(this->data_pins_[0]); + for (size_t i = 0; i != data_pin_count; i++) { + config.data_gpio_nums[i] = this->data_pins_[i]->get_pin(); + } + config.data_width = data_pin_count; + config.disp_gpio_num = -1; + config.hsync_gpio_num = this->hsync_pin_->get_pin(); + config.vsync_gpio_num = this->vsync_pin_->get_pin(); + config.de_gpio_num = this->de_pin_->get_pin(); + config.pclk_gpio_num = this->pclk_pin_->get_pin(); + esp_err_t err = esp_lcd_new_rgb_panel(&config, &this->handle_); + if (err != ESP_OK) { + esph_log_e(TAG, "lcd_new_rgb_panel failed: %s", esp_err_to_name(err)); + } + ESP_ERROR_CHECK(esp_lcd_panel_reset(this->handle_)); + ESP_ERROR_CHECK(esp_lcd_panel_init(this->handle_)); + esph_log_config(TAG, "RPI_DPI_RGB setup complete"); +} + +void RpiDpiRgb::draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order, + display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) { + if (w <= 0 || h <= 0) + return; + // if color mapping is required, pass the buck. + // note that endianness is not considered here - it is assumed to match! + if (bitness != display::COLOR_BITNESS_565) { + return display::Display::draw_pixels_at(x_start, y_start, w, h, ptr, order, bitness, big_endian, x_offset, y_offset, + x_pad); + } + x_start += this->offset_x_; + y_start += this->offset_y_; + esp_err_t err; + // x_ and y_offset are offsets into the source buffer, unrelated to our own offsets into the display. + if (x_offset == 0 && x_pad == 0 && y_offset == 0) { + // we could deal here with a non-zero y_offset, but if x_offset is zero, y_offset probably will be so don't bother + err = esp_lcd_panel_draw_bitmap(this->handle_, x_start, y_start, x_start + w, y_start + h, ptr); + } else { + // draw line by line + auto stride = x_offset + w + x_pad; + for (int y = 0; y != h; y++) { + err = esp_lcd_panel_draw_bitmap(this->handle_, x_start, y + y_start, x_start + w, y + y_start + 1, + ptr + ((y + y_offset) * stride + x_offset) * 2); + if (err != ESP_OK) + break; + } + } + if (err != ESP_OK) + esph_log_e(TAG, "lcd_lcd_panel_draw_bitmap failed: %s", esp_err_to_name(err)); +} + +void RpiDpiRgb::draw_pixel_at(int x, int y, Color color) { + if (!this->get_clipping().inside(x, y)) + return; // NOLINT + + switch (this->rotation_) { + case display::DISPLAY_ROTATION_0_DEGREES: + break; + case display::DISPLAY_ROTATION_90_DEGREES: + std::swap(x, y); + x = this->width_ - x - 1; + break; + case display::DISPLAY_ROTATION_180_DEGREES: + x = this->width_ - x - 1; + y = this->height_ - y - 1; + break; + case display::DISPLAY_ROTATION_270_DEGREES: + std::swap(x, y); + y = this->height_ - y - 1; + break; + } + auto pixel = convert_big_endian(display::ColorUtil::color_to_565(color)); + + this->draw_pixels_at(x, y, 1, 1, (const uint8_t *) &pixel, display::COLOR_ORDER_RGB, display::COLOR_BITNESS_565, true, + 0, 0, 0); + App.feed_wdt(); +} + +void RpiDpiRgb::dump_config() { + ESP_LOGCONFIG("", "RPI_DPI_RGB LCD"); + ESP_LOGCONFIG(TAG, " Height: %u", this->height_); + ESP_LOGCONFIG(TAG, " Width: %u", this->width_); + LOG_PIN(" DE Pin: ", this->de_pin_); + LOG_PIN(" Reset Pin: ", this->reset_pin_); + size_t data_pin_count = sizeof(this->data_pins_) / sizeof(this->data_pins_[0]); + for (size_t i = 0; i != data_pin_count; i++) + ESP_LOGCONFIG(TAG, " Data pin %d: %s", i, (this->data_pins_[i])->dump_summary().c_str()); +} + +} // namespace rpi_dpi_rgb +} // namespace esphome + +#endif // USE_ESP32_VARIANT_ESP32S3 diff --git a/esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.h b/esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.h new file mode 100644 index 0000000000..0319b46391 --- /dev/null +++ b/esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.h @@ -0,0 +1,92 @@ +// +// Created by Clyde Stubbs on 29/10/2023. +// +#pragma once + +// only applicable on ESP32-S3 +#ifdef USE_ESP32_VARIANT_ESP32S3 +#include "esphome/core/component.h" +#include "esphome/core/gpio.h" +#include "esphome/core/log.h" +#include "esphome/core/application.h" +#include "esphome/components/display/display.h" +#include "esp_lcd_panel_ops.h" + +#include "esp_lcd_panel_rgb.h" + +namespace esphome { +namespace rpi_dpi_rgb { + +constexpr static const char *const TAG = "rpi_dpi_rgb"; + +class RpiDpiRgb : public display::Display { + public: + void update() override { this->do_update_(); } + void setup() override; + void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order, + display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) override; + void draw_pixel_at(int x, int y, Color color) override; + + display::ColorOrder get_color_mode() { return this->color_mode_; } + void set_color_mode(display::ColorOrder color_mode) { this->color_mode_ = color_mode; } + void set_invert_colors(bool invert_colors) { this->invert_colors_ = invert_colors; } + + void add_data_pin(InternalGPIOPin *data_pin, size_t index) { this->data_pins_[index] = data_pin; }; + void set_de_pin(InternalGPIOPin *de_pin) { this->de_pin_ = de_pin; } + void set_pclk_pin(InternalGPIOPin *pclk_pin) { this->pclk_pin_ = pclk_pin; } + void set_vsync_pin(InternalGPIOPin *vsync_pin) { this->vsync_pin_ = vsync_pin; } + void set_hsync_pin(InternalGPIOPin *hsync_pin) { this->hsync_pin_ = hsync_pin; } + void set_reset_pin(GPIOPin *reset_pin) { this->reset_pin_ = reset_pin; } + void set_width(uint16_t width) { this->width_ = width; } + void set_dimensions(uint16_t width, uint16_t height) { + this->width_ = width; + this->height_ = height; + } + int get_width() override { return this->width_; } + int get_height() override { return this->height_; } + void set_hsync_back_porch(uint16_t hsync_back_porch) { this->hsync_back_porch_ = hsync_back_porch; } + void set_hsync_front_porch(uint16_t hsync_front_porch) { this->hsync_front_porch_ = hsync_front_porch; } + void set_hsync_pulse_width(uint16_t hsync_pulse_width) { this->hsync_pulse_width_ = hsync_pulse_width; } + void set_vsync_pulse_width(uint16_t vsync_pulse_width) { this->vsync_pulse_width_ = vsync_pulse_width; } + void set_vsync_back_porch(uint16_t vsync_back_porch) { this->vsync_back_porch_ = vsync_back_porch; } + void set_vsync_front_porch(uint16_t vsync_front_porch) { this->vsync_front_porch_ = vsync_front_porch; } + void set_pclk_frequency(uint32_t pclk_frequency) { this->pclk_frequency_ = pclk_frequency; } + void set_pclk_inverted(bool inverted) { this->pclk_inverted_ = inverted; } + void set_offsets(int16_t offset_x, int16_t offset_y) { + this->offset_x_ = offset_x; + this->offset_y_ = offset_y; + } + display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; } + void dump_config() override; + + protected: + int get_width_internal() override { return this->width_; } + int get_height_internal() override { return this->height_; } + InternalGPIOPin *de_pin_{nullptr}; + InternalGPIOPin *pclk_pin_{nullptr}; + InternalGPIOPin *hsync_pin_{nullptr}; + InternalGPIOPin *vsync_pin_{nullptr}; + GPIOPin *reset_pin_{nullptr}; + InternalGPIOPin *data_pins_[16] = {}; + uint16_t hsync_front_porch_ = 8; + uint16_t hsync_pulse_width_ = 4; + uint16_t hsync_back_porch_ = 8; + uint16_t vsync_front_porch_ = 8; + uint16_t vsync_pulse_width_ = 4; + uint16_t vsync_back_porch_ = 8; + uint32_t pclk_frequency_ = 16 * 1000 * 1000; + bool pclk_inverted_{true}; + + bool invert_colors_{}; + display::ColorOrder color_mode_{display::COLOR_ORDER_BGR}; + size_t width_{}; + size_t height_{}; + int16_t offset_x_{0}; + int16_t offset_y_{0}; + + esp_lcd_panel_handle_t handle_{}; +}; + +} // namespace rpi_dpi_rgb +} // namespace esphome +#endif // USE_ESP32_VARIANT_ESP32S3 diff --git a/esphome/components/st7701s/__init__.py b/esphome/components/st7701s/__init__.py new file mode 100644 index 0000000000..c58ce8a01e --- /dev/null +++ b/esphome/components/st7701s/__init__.py @@ -0,0 +1 @@ +CODEOWNERS = ["@clydebarrow"] diff --git a/esphome/components/st7701s/display.py b/esphome/components/st7701s/display.py new file mode 100644 index 0000000000..e33eeb89ae --- /dev/null +++ b/esphome/components/st7701s/display.py @@ -0,0 +1,253 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome import pins +from esphome.components import ( + spi, + display, +) +from esphome.const import ( + CONF_DC_PIN, + CONF_RESET_PIN, + CONF_DATA_PINS, + CONF_ID, + CONF_DIMENSIONS, + CONF_WIDTH, + CONF_HEIGHT, + CONF_LAMBDA, + CONF_MIRROR_X, + CONF_MIRROR_Y, + CONF_COLOR_ORDER, + CONF_TRANSFORM, + CONF_OFFSET_HEIGHT, + CONF_OFFSET_WIDTH, + CONF_INVERT_COLORS, + CONF_RED, + CONF_GREEN, + CONF_BLUE, + CONF_NUMBER, + CONF_IGNORE_STRAPPING_WARNING, +) + +from esphome.components.esp32 import ( + only_on_variant, + const, +) +from esphome.components.rpi_dpi_rgb.display import ( + CONF_PCLK_FREQUENCY, + CONF_PCLK_INVERTED, +) +from .init_sequences import ( + ST7701S_INITS, + cmd, +) + +CONF_INIT_SEQUENCE = "init_sequence" +CONF_DE_PIN = "de_pin" +CONF_PCLK_PIN = "pclk_pin" +CONF_HSYNC_PIN = "hsync_pin" +CONF_VSYNC_PIN = "vsync_pin" + +CONF_HSYNC_PULSE_WIDTH = "hsync_pulse_width" +CONF_HSYNC_BACK_PORCH = "hsync_back_porch" +CONF_HSYNC_FRONT_PORCH = "hsync_front_porch" +CONF_VSYNC_PULSE_WIDTH = "vsync_pulse_width" +CONF_VSYNC_BACK_PORCH = "vsync_back_porch" +CONF_VSYNC_FRONT_PORCH = "vsync_front_porch" + +DEPENDENCIES = ["spi", "esp32"] + +st7701s_ns = cg.esphome_ns.namespace("st7701s") +ST7701S = st7701s_ns.class_("ST7701S", display.Display, cg.Component, spi.SPIDevice) +ColorOrder = display.display_ns.enum("ColorMode") + +COLOR_ORDERS = { + "RGB": ColorOrder.COLOR_ORDER_RGB, + "BGR": ColorOrder.COLOR_ORDER_BGR, +} +DATA_PIN_SCHEMA = pins.internal_gpio_output_pin_schema + + +def data_pin_validate(value): + """ + It is safe to use strapping pins as RGB output data bits, as they are outputs only, + and not initialised until after boot. + """ + if not isinstance(value, dict): + try: + return DATA_PIN_SCHEMA( + {CONF_NUMBER: value, CONF_IGNORE_STRAPPING_WARNING: True} + ) + except cv.Invalid: + pass + return DATA_PIN_SCHEMA(value) + + +def data_pin_set(length): + return cv.All( + [data_pin_validate], + cv.Length(min=length, max=length, msg=f"Exactly {length} data pins required"), + ) + + +def map_sequence(value): + """ + An initialisation sequence can be selected from one of the pre-defined sequences in init_sequences.py, + or can be a literal array of data bytes. + The format is a repeated sequence of [CMD, LEN, ] where is LEN bytes. + """ + if not isinstance(value, list): + value = cv.int_(value) + value = cv.one_of(*ST7701S_INITS)(value) + return ST7701S_INITS[value] + # value = cv.ensure_list(cv.uint8_t)(value) + data_length = len(value) + if data_length == 0: + raise cv.Invalid("Empty sequence") + value = cmd(*value) + return value + + +CONFIG_SCHEMA = cv.All( + display.FULL_DISPLAY_SCHEMA.extend( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(ST7701S), + cv.Required(CONF_DIMENSIONS): cv.Any( + cv.dimensions, + cv.Schema( + { + cv.Required(CONF_WIDTH): cv.int_, + cv.Required(CONF_HEIGHT): cv.int_, + cv.Optional(CONF_OFFSET_HEIGHT, default=0): cv.int_, + cv.Optional(CONF_OFFSET_WIDTH, default=0): cv.int_, + } + ), + ), + cv.Optional(CONF_TRANSFORM): cv.Schema( + { + cv.Optional(CONF_MIRROR_X, default=False): cv.boolean, + cv.Optional(CONF_MIRROR_Y, default=False): cv.boolean, + } + ), + cv.Required(CONF_DATA_PINS): cv.Any( + data_pin_set(16), + cv.Schema( + { + cv.Required(CONF_RED): data_pin_set(5), + cv.Required(CONF_GREEN): data_pin_set(6), + cv.Required(CONF_BLUE): data_pin_set(5), + } + ), + ), + cv.Optional(CONF_INIT_SEQUENCE, default=1): cv.ensure_list( + map_sequence + ), + cv.Optional(CONF_COLOR_ORDER): cv.one_of( + *COLOR_ORDERS.keys(), upper=True + ), + cv.Optional(CONF_PCLK_FREQUENCY, default="16MHz"): cv.All( + cv.frequency, cv.Range(min=4e6, max=30e6) + ), + cv.Optional(CONF_PCLK_INVERTED, default=True): cv.boolean, + cv.Optional(CONF_INVERT_COLORS, default=False): cv.boolean, + cv.Required(CONF_DE_PIN): pins.internal_gpio_output_pin_schema, + cv.Required(CONF_PCLK_PIN): pins.internal_gpio_output_pin_schema, + cv.Required(CONF_HSYNC_PIN): pins.internal_gpio_output_pin_schema, + cv.Required(CONF_VSYNC_PIN): pins.internal_gpio_output_pin_schema, + cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema, + cv.Optional(CONF_DC_PIN): pins.gpio_output_pin_schema, + cv.Optional(CONF_HSYNC_PULSE_WIDTH, default=10): cv.int_, + cv.Optional(CONF_HSYNC_BACK_PORCH, default=10): cv.int_, + cv.Optional(CONF_HSYNC_FRONT_PORCH, default=20): cv.int_, + cv.Optional(CONF_VSYNC_PULSE_WIDTH, default=10): cv.int_, + cv.Optional(CONF_VSYNC_BACK_PORCH, default=10): cv.int_, + cv.Optional(CONF_VSYNC_FRONT_PORCH, default=10): cv.int_, + } + ).extend(spi.spi_device_schema(cs_pin_required=False, default_data_rate=1e6)) + ), + only_on_variant(supported=[const.VARIANT_ESP32S3]), + cv.only_with_esp_idf, +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await display.register_display(var, config) + await spi.register_spi_device(var, config) + + sequence = [] + for seq in config[CONF_INIT_SEQUENCE]: + sequence.extend(seq) + cg.add(var.set_init_sequence(sequence)) + cg.add(var.set_color_mode(COLOR_ORDERS[config[CONF_COLOR_ORDER]])) + cg.add(var.set_invert_colors(config[CONF_INVERT_COLORS])) + cg.add(var.set_hsync_pulse_width(config[CONF_HSYNC_PULSE_WIDTH])) + cg.add(var.set_hsync_back_porch(config[CONF_HSYNC_BACK_PORCH])) + cg.add(var.set_hsync_front_porch(config[CONF_HSYNC_FRONT_PORCH])) + cg.add(var.set_vsync_pulse_width(config[CONF_VSYNC_PULSE_WIDTH])) + cg.add(var.set_vsync_back_porch(config[CONF_VSYNC_BACK_PORCH])) + cg.add(var.set_vsync_front_porch(config[CONF_VSYNC_FRONT_PORCH])) + cg.add(var.set_pclk_inverted(config[CONF_PCLK_INVERTED])) + cg.add(var.set_pclk_frequency(config[CONF_PCLK_FREQUENCY])) + index = 0 + dpins = [] + if CONF_RED in config[CONF_DATA_PINS]: + red_pins = config[CONF_DATA_PINS][CONF_RED] + green_pins = config[CONF_DATA_PINS][CONF_GREEN] + blue_pins = config[CONF_DATA_PINS][CONF_BLUE] + if config[CONF_COLOR_ORDER] == "BGR": + dpins.extend(red_pins) + dpins.extend(green_pins) + dpins.extend(blue_pins) + else: + dpins.extend(blue_pins) + dpins.extend(green_pins) + dpins.extend(red_pins) + # swap bytes to match big-endian format + dpins = dpins[8:16] + dpins[0:8] + else: + dpins = config[CONF_DATA_PINS] + for pin in dpins: + data_pin = await cg.gpio_pin_expression(pin) + cg.add(var.add_data_pin(data_pin, index)) + index += 1 + + if dc_pin := config.get(CONF_DC_PIN): + dc = await cg.gpio_pin_expression(dc_pin) + cg.add(var.set_dc_pin(dc)) + + if reset_pin := config.get(CONF_RESET_PIN): + reset = await cg.gpio_pin_expression(reset_pin) + cg.add(var.set_reset_pin(reset)) + + if transform := config.get(CONF_TRANSFORM): + cg.add(var.set_mirror_x(transform[CONF_MIRROR_X])) + cg.add(var.set_mirror_y(transform[CONF_MIRROR_Y])) + + if CONF_DIMENSIONS in config: + dimensions = config[CONF_DIMENSIONS] + if isinstance(dimensions, dict): + cg.add(var.set_dimensions(dimensions[CONF_WIDTH], dimensions[CONF_HEIGHT])) + cg.add( + var.set_offsets( + dimensions[CONF_OFFSET_WIDTH], dimensions[CONF_OFFSET_HEIGHT] + ) + ) + else: + (width, height) = dimensions + cg.add(var.set_dimensions(width, height)) + + if lamb := config.get(CONF_LAMBDA): + lambda_ = await cg.process_lambda( + lamb, [(display.DisplayRef, "it")], return_type=cg.void + ) + cg.add(var.set_writer(lambda_)) + + pin = await cg.gpio_pin_expression(config[CONF_DE_PIN]) + cg.add(var.set_de_pin(pin)) + pin = await cg.gpio_pin_expression(config[CONF_PCLK_PIN]) + cg.add(var.set_pclk_pin(pin)) + pin = await cg.gpio_pin_expression(config[CONF_HSYNC_PIN]) + cg.add(var.set_hsync_pin(pin)) + pin = await cg.gpio_pin_expression(config[CONF_VSYNC_PIN]) + cg.add(var.set_vsync_pin(pin)) diff --git a/esphome/components/st7701s/init_sequences.py b/esphome/components/st7701s/init_sequences.py new file mode 100644 index 0000000000..4786731c78 --- /dev/null +++ b/esphome/components/st7701s/init_sequences.py @@ -0,0 +1,363 @@ +# These are initialisation sequences for ST7701S displays. The contents are somewhat arcane. + + +def cmd(c, *args): + """ + Create a command sequence + :param c: The command (8 bit) + :param args: zero or more arguments (8 bit values) + :return: a list with the command, the argument count and the arguments + """ + return [c, len(args)] + list(args) + + +ST7701S_1_INIT = ( + cmd(0x01) + + cmd(0xFF, 0x77, 0x01, 0x00, 0x00, 0x10) + + cmd(0xC0, 0x3B, 0x00) + + cmd(0xC1, 0x0D, 0x02) + + cmd(0xC2, 0x31, 0x05) + + cmd(0xCD, 0x08) + + cmd( + 0xB0, + 0x00, + 0x11, + 0x18, + 0x0E, + 0x11, + 0x06, + 0x07, + 0x08, + 0x07, + 0x22, + 0x04, + 0x12, + 0x0F, + 0xAA, + 0x31, + 0x18, + ) + + cmd( + 0xB1, + 0x00, + 0x11, + 0x19, + 0x0E, + 0x12, + 0x07, + 0x08, + 0x08, + 0x08, + 0x22, + 0x04, + 0x11, + 0x11, + 0xA9, + 0x32, + 0x18, + ) + + cmd(0xFF, 0x77, 0x01, 0x00, 0x00, 0x11) + + cmd(0xB0, 0x60) + + cmd(0xB1, 0x32) + + cmd(0xB2, 0x07) + + cmd(0xB3, 0x80) + + cmd(0xB5, 0x49) + + cmd(0xB7, 0x85) + + cmd(0xB8, 0x21) + + cmd(0xC1, 0x78) + + cmd(0xC2, 0x78) + + cmd(0xE0, 0x00, 0x1B, 0x02) + + cmd(0xE1, 0x08, 0xA0, 0x00, 0x00, 0x07, 0xA0, 0x00, 0x00, 0x00, 0x44, 0x44) + + cmd(0xE2, 0x11, 0x11, 0x44, 0x44, 0xED, 0xA0, 0x00, 0x00, 0xEC, 0xA0, 0x00, 0x00) + + cmd(0xE3, 0x00, 0x00, 0x11, 0x11) + + cmd(0xE4, 0x44, 0x44) + + cmd( + 0xE5, + 0x0A, + 0xE9, + 0xD8, + 0xA0, + 0x0C, + 0xEB, + 0xD8, + 0xA0, + 0x0E, + 0xED, + 0xD8, + 0xA0, + 0x10, + 0xEF, + 0xD8, + 0xA0, + ) + + cmd(0xE6, 0x00, 0x00, 0x11, 0x11) + + cmd(0xE7, 0x44, 0x44) + + cmd( + 0xE8, + 0x09, + 0xE8, + 0xD8, + 0xA0, + 0x0B, + 0xEA, + 0xD8, + 0xA0, + 0x0D, + 0xEC, + 0xD8, + 0xA0, + 0x0F, + 0xEE, + 0xD8, + 0xA0, + ) + + cmd(0xEB, 0x02, 0x00, 0xE4, 0xE4, 0x88, 0x00, 0x40) + + cmd(0xEC, 0x3C, 0x00) + + cmd( + 0xED, + 0xAB, + 0x89, + 0x76, + 0x54, + 0x02, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0x20, + 0x45, + 0x67, + 0x98, + 0xBA, + ) + + cmd(0xFF, 0x77, 0x01, 0x00, 0x00, 0x13) + + cmd(0xE5, 0xE4) + + cmd(0x3A, 0x60) +) + +# This is untested +ST7701S_7_INIT = ( + cmd( + 0xFF, + 0x77, + 0x01, + 0x00, + 0x00, + 0x10, + ) + + cmd(0xC0, 0x3B, 0x00) + + cmd(0xC1, 0x0B, 0x02) + + cmd(0xC2, 0x07, 0x02) + + cmd(0xCC, 0x10) + + cmd(0xCD, 0x08) + + cmd( + 0xB0, + 0x00, + 0x11, + 0x16, + 0x0E, + 0x11, + 0x06, + 0x05, + 0x09, + 0x08, + 0x21, + 0x06, + 0x13, + 0x10, + 0x29, + 0x31, + 0x18, + ) + + cmd( + 0xB1, + 0x00, + 0x11, + 0x16, + 0x0E, + 0x11, + 0x07, + 0x05, + 0x09, + 0x09, + 0x21, + 0x05, + 0x13, + 0x11, + 0x2A, + 0x31, + 0x18, + ) + + cmd( + 0xFF, + 0x77, + 0x01, + 0x00, + 0x00, + 0x11, + ) + + cmd(0xB0, 0x6D) + + cmd(0xB1, 0x37) + + cmd(0xB2, 0x81) + + cmd(0xB3, 0x80) + + cmd(0xB5, 0x43) + + cmd(0xB7, 0x85) + + cmd(0xB8, 0x20) + + cmd(0xC1, 0x78) + + cmd(0xC2, 0x78) + + cmd(0xD0, 0x88) + + cmd( + 0xE0, + 3, + 0x00, + 0x00, + 0x02, + ) + + cmd( + 0xE1, + 0x03, + 0xA0, + 0x00, + 0x00, + 0x04, + 0xA0, + 0x00, + 0x00, + 0x00, + 0x20, + 0x20, + ) + + cmd( + 0xE2, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ) + + cmd( + 0xE3, + 0x00, + 0x00, + 0x11, + 0x00, + ) + + cmd(0xE4, 0x22, 0x00) + + cmd( + 0xE5, + 0x05, + 0xEC, + 0xA0, + 0xA0, + 0x07, + 0xEE, + 0xA0, + 0xA0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ) + + cmd( + 0xE6, + 0x00, + 0x00, + 0x11, + 0x00, + ) + + cmd(0xE7, 0x22, 0x00) + + cmd( + 0xE8, + 0x06, + 0xED, + 0xA0, + 0xA0, + 0x08, + 0xEF, + 0xA0, + 0xA0, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + ) + + cmd( + 0xEB, + 0x00, + 0x00, + 0x40, + 0x40, + 0x00, + 0x00, + 0x00, + ) + + cmd( + 0xED, + 0xFF, + 0xFF, + 0xFF, + 0xBA, + 0x0A, + 0xBF, + 0x45, + 0xFF, + 0xFF, + 0x54, + 0xFB, + 0xA0, + 0xAB, + 0xFF, + 0xFF, + 0xFF, + ) + + cmd( + 0xEF, + 0x10, + 0x0D, + 0x04, + 0x08, + 0x3F, + 0x1F, + ) + + cmd( + 0xFF, + 0x77, + 0x01, + 0x00, + 0x00, + 0x13, + ) + + cmd(0xEF, 0x08) + + cmd( + 0xFF, + 0x77, + 0x01, + 0x00, + 0x00, + 0x00, + ) + + cmd(0x3A, 0x66) +) + +ST7701S_INITS = { + 1: ST7701S_1_INIT, + # 7: ST7701S_7_INIT, +} diff --git a/esphome/components/st7701s/st7701s.cpp b/esphome/components/st7701s/st7701s.cpp new file mode 100644 index 0000000000..43d8653709 --- /dev/null +++ b/esphome/components/st7701s/st7701s.cpp @@ -0,0 +1,180 @@ +#ifdef USE_ESP32_VARIANT_ESP32S3 +#include "st7701s.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace st7701s { + +void ST7701S::setup() { + esph_log_config(TAG, "Setting up ST7701S"); + this->spi_setup(); + esp_lcd_rgb_panel_config_t config{}; + config.flags.fb_in_psram = 1; + config.timings.h_res = this->width_; + config.timings.v_res = this->height_; + config.timings.hsync_pulse_width = this->hsync_pulse_width_; + config.timings.hsync_back_porch = this->hsync_back_porch_; + config.timings.hsync_front_porch = this->hsync_front_porch_; + config.timings.vsync_pulse_width = this->vsync_pulse_width_; + config.timings.vsync_back_porch = this->vsync_back_porch_; + config.timings.vsync_front_porch = this->vsync_front_porch_; + config.timings.flags.pclk_active_neg = this->pclk_inverted_; + config.timings.pclk_hz = this->pclk_frequency_; + config.clk_src = LCD_CLK_SRC_PLL160M; + config.sram_trans_align = 64; + config.psram_trans_align = 64; + size_t data_pin_count = sizeof(this->data_pins_) / sizeof(this->data_pins_[0]); + for (size_t i = 0; i != data_pin_count; i++) { + config.data_gpio_nums[i] = this->data_pins_[i]->get_pin(); + } + config.data_width = data_pin_count; + config.disp_gpio_num = -1; + config.hsync_gpio_num = this->hsync_pin_->get_pin(); + config.vsync_gpio_num = this->vsync_pin_->get_pin(); + config.de_gpio_num = this->de_pin_->get_pin(); + config.pclk_gpio_num = this->pclk_pin_->get_pin(); + esp_err_t err = esp_lcd_new_rgb_panel(&config, &this->handle_); + if (err != ESP_OK) { + esph_log_e(TAG, "lcd_new_rgb_panel failed: %s", esp_err_to_name(err)); + } + ESP_ERROR_CHECK(esp_lcd_panel_reset(this->handle_)); + ESP_ERROR_CHECK(esp_lcd_panel_init(this->handle_)); + this->write_init_sequence_(); + esph_log_config(TAG, "ST7701S setup complete"); +} + +void ST7701S::draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order, + display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) { + if (w <= 0 || h <= 0) + return; + // if color mapping is required, pass the buck. + // note that endianness is not considered here - it is assumed to match! + if (bitness != display::COLOR_BITNESS_565) { + return display::Display::draw_pixels_at(x_start, y_start, w, h, ptr, order, bitness, big_endian, x_offset, y_offset, + x_pad); + } + x_start += this->offset_x_; + y_start += this->offset_y_; + esp_err_t err; + // x_ and y_offset are offsets into the source buffer, unrelated to our own offsets into the display. + if (x_offset == 0 && x_pad == 0 && y_offset == 0) { + // we could deal here with a non-zero y_offset, but if x_offset is zero, y_offset probably will be so don't bother + err = esp_lcd_panel_draw_bitmap(this->handle_, x_start, y_start, x_start + w, y_start + h, ptr); + } else { + // draw line by line + auto stride = x_offset + w + x_pad; + for (int y = 0; y != h; y++) { + err = esp_lcd_panel_draw_bitmap(this->handle_, x_start, y + y_start, x_start + w, y + y_start + 1, + ptr + ((y + y_offset) * stride + x_offset) * 2); + if (err != ESP_OK) + break; + } + } + if (err != ESP_OK) + esph_log_e(TAG, "lcd_lcd_panel_draw_bitmap failed: %s", esp_err_to_name(err)); +} + +void ST7701S::draw_pixel_at(int x, int y, Color color) { + if (!this->get_clipping().inside(x, y)) + return; // NOLINT + + switch (this->rotation_) { + case display::DISPLAY_ROTATION_0_DEGREES: + break; + case display::DISPLAY_ROTATION_90_DEGREES: + std::swap(x, y); + x = this->width_ - x - 1; + break; + case display::DISPLAY_ROTATION_180_DEGREES: + x = this->width_ - x - 1; + y = this->height_ - y - 1; + break; + case display::DISPLAY_ROTATION_270_DEGREES: + std::swap(x, y); + y = this->height_ - y - 1; + break; + } + auto pixel = convert_big_endian(display::ColorUtil::color_to_565(color)); + + this->draw_pixels_at(x, y, 1, 1, (const uint8_t *) &pixel, display::COLOR_ORDER_RGB, display::COLOR_BITNESS_565, true, + 0, 0, 0); + App.feed_wdt(); +} + +void ST7701S::write_command_(uint8_t value) { + this->enable(); + if (this->dc_pin_ == nullptr) { + this->write(value, 9); + } else { + this->dc_pin_->digital_write(false); + this->write_byte(value); + this->dc_pin_->digital_write(true); + } + this->disable(); +} + +void ST7701S::write_data_(uint8_t value) { + this->enable(); + if (this->dc_pin_ == nullptr) { + this->write(value | 0x100, 9); + } else { + this->dc_pin_->digital_write(true); + this->write_byte(value); + } + this->disable(); +} + +/** + * this relies upon the init sequence being well-formed, which is guaranteed by the Python init code. + */ + +void ST7701S::write_sequence_(uint8_t cmd, size_t len, const uint8_t *bytes) { + this->write_command_(cmd); + while (len-- != 0) + this->write_data_(*bytes++); +} + +void ST7701S::write_init_sequence_() { + for (size_t i = 0; i != this->init_sequence_.size();) { + uint8_t cmd = this->init_sequence_[i++]; + size_t len = this->init_sequence_[i++]; + this->write_sequence_(cmd, len, &this->init_sequence_[i]); + i += len; + esph_log_v(TAG, "Command %X, %d bytes", cmd, len); + if (cmd == SW_RESET_CMD) + delay(6); + } + // st7701 does not appear to support axis swapping + this->write_sequence_(CMD2_BKSEL, sizeof(CMD2_BK0), CMD2_BK0); + this->write_command_(SDIR_CMD); // this is in the BK0 command set + this->write_data_(this->mirror_x_ ? 0x04 : 0x00); + uint8_t val = this->color_mode_ == display::COLOR_ORDER_BGR ? 0x08 : 0x00; + if (this->mirror_y_) + val |= 0x10; + this->write_command_(MADCTL_CMD); + this->write_data_(val); + esph_log_d(TAG, "write MADCTL %X", val); + this->write_command_(this->invert_colors_ ? INVERT_ON : INVERT_OFF); + this->set_timeout(120, [this] { + this->write_command_(SLEEP_OUT); + this->write_command_(DISPLAY_ON); + }); +} + +void ST7701S::dump_config() { + ESP_LOGCONFIG("", "ST7701S RGB LCD"); + ESP_LOGCONFIG(TAG, " Height: %u", this->height_); + ESP_LOGCONFIG(TAG, " Width: %u", this->width_); + LOG_PIN(" CS Pin: ", this->cs_); + LOG_PIN(" DC Pin: ", this->dc_pin_); + LOG_PIN(" DE Pin: ", this->de_pin_); + LOG_PIN(" Reset Pin: ", this->reset_pin_); + size_t data_pin_count = sizeof(this->data_pins_) / sizeof(this->data_pins_[0]); + for (size_t i = 0; i != data_pin_count; i++) + ESP_LOGCONFIG(TAG, " Data pin %d: %s", i, (this->data_pins_[i])->dump_summary().c_str()); + ESP_LOGCONFIG(TAG, " SPI Data rate: %dMHz", (unsigned) (this->data_rate_ / 1000000)); +} + +} // namespace st7701s +} // namespace esphome +#endif // USE_ESP32_VARIANT_ESP32S3 diff --git a/esphome/components/st7701s/st7701s.h b/esphome/components/st7701s/st7701s.h new file mode 100644 index 0000000000..2328bca965 --- /dev/null +++ b/esphome/components/st7701s/st7701s.h @@ -0,0 +1,115 @@ +// +// Created by Clyde Stubbs on 29/10/2023. +// +#pragma once + +// only applicable on ESP32-S3 +#ifdef USE_ESP32_VARIANT_ESP32S3 +#include "esphome/core/component.h" +#include "esphome/components/spi/spi.h" +#include "esphome/components/display/display.h" +#include "esp_lcd_panel_ops.h" + +#include "esp_lcd_panel_rgb.h" + +namespace esphome { +namespace st7701s { + +constexpr static const char *const TAG = "display.st7701s"; +const uint8_t SW_RESET_CMD = 0x01; +const uint8_t SLEEP_OUT = 0x11; +const uint8_t SDIR_CMD = 0xC7; +const uint8_t MADCTL_CMD = 0x36; +const uint8_t INVERT_OFF = 0x20; +const uint8_t INVERT_ON = 0x21; +const uint8_t DISPLAY_ON = 0x29; +const uint8_t CMD2_BKSEL = 0xFF; +const uint8_t CMD2_BK0[5] = {0x77, 0x01, 0x00, 0x00, 0x10}; + +class ST7701S : public display::Display, + public spi::SPIDevice { + public: + void update() override { this->do_update_(); } + void setup() override; + void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order, + display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) override; + + display::ColorOrder get_color_mode() { return this->color_mode_; } + void set_color_mode(display::ColorOrder color_mode) { this->color_mode_ = color_mode; } + void set_invert_colors(bool invert_colors) { this->invert_colors_ = invert_colors; } + + void add_data_pin(InternalGPIOPin *data_pin, size_t index) { this->data_pins_[index] = data_pin; }; + void set_de_pin(InternalGPIOPin *de_pin) { this->de_pin_ = de_pin; } + void set_pclk_pin(InternalGPIOPin *pclk_pin) { this->pclk_pin_ = pclk_pin; } + void set_vsync_pin(InternalGPIOPin *vsync_pin) { this->vsync_pin_ = vsync_pin; } + void set_hsync_pin(InternalGPIOPin *hsync_pin) { this->hsync_pin_ = hsync_pin; } + void set_dc_pin(GPIOPin *dc_pin) { this->dc_pin_ = dc_pin; } + void set_reset_pin(GPIOPin *reset_pin) { this->reset_pin_ = reset_pin; } + void set_width(uint16_t width) { this->width_ = width; } + void set_pclk_frequency(uint32_t pclk_frequency) { this->pclk_frequency_ = pclk_frequency; } + void set_pclk_inverted(bool inverted) { this->pclk_inverted_ = inverted; } + void set_dimensions(uint16_t width, uint16_t height) { + this->width_ = width; + this->height_ = height; + } + int get_width() override { return this->width_; } + int get_height() override { return this->height_; } + void set_hsync_back_porch(uint16_t hsync_back_porch) { this->hsync_back_porch_ = hsync_back_porch; } + void set_hsync_front_porch(uint16_t hsync_front_porch) { this->hsync_front_porch_ = hsync_front_porch; } + void set_hsync_pulse_width(uint16_t hsync_pulse_width) { this->hsync_pulse_width_ = hsync_pulse_width; } + void set_vsync_pulse_width(uint16_t vsync_pulse_width) { this->vsync_pulse_width_ = vsync_pulse_width; } + void set_vsync_back_porch(uint16_t vsync_back_porch) { this->vsync_back_porch_ = vsync_back_porch; } + void set_vsync_front_porch(uint16_t vsync_front_porch) { this->vsync_front_porch_ = vsync_front_porch; } + void set_init_sequence(const std::vector &init_sequence) { this->init_sequence_ = init_sequence; } + void set_mirror_x(bool mirror_x) { this->mirror_x_ = mirror_x; } + void set_mirror_y(bool mirror_y) { this->mirror_y_ = mirror_y; } + void set_offsets(int16_t offset_x, int16_t offset_y) { + this->offset_x_ = offset_x; + this->offset_y_ = offset_y; + } + display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; } + int get_width_internal() override { return this->width_; } + int get_height_internal() override { return this->height_; } + void dump_config() override; + void draw_pixel_at(int x, int y, Color color) override; + + // this will be horribly slow. + protected: + void write_command_(uint8_t value); + void write_data_(uint8_t value); + void write_sequence_(uint8_t cmd, size_t len, const uint8_t *bytes); + void write_init_sequence_(); + + InternalGPIOPin *de_pin_{nullptr}; + InternalGPIOPin *pclk_pin_{nullptr}; + InternalGPIOPin *hsync_pin_{nullptr}; + InternalGPIOPin *vsync_pin_{nullptr}; + GPIOPin *reset_pin_{nullptr}; + GPIOPin *dc_pin_{nullptr}; + InternalGPIOPin *data_pins_[16] = {}; + uint16_t hsync_pulse_width_ = 10; + uint16_t hsync_back_porch_ = 10; + uint16_t hsync_front_porch_ = 20; + uint16_t vsync_pulse_width_ = 10; + uint16_t vsync_back_porch_ = 10; + uint16_t vsync_front_porch_ = 10; + std::vector init_sequence_; + uint32_t pclk_frequency_ = 16 * 1000 * 1000; + bool pclk_inverted_{true}; + + bool invert_colors_{}; + display::ColorOrder color_mode_{display::COLOR_ORDER_BGR}; + size_t width_{}; + size_t height_{}; + int16_t offset_x_{0}; + int16_t offset_y_{0}; + bool mirror_x_{}; + bool mirror_y_{}; + + esp_lcd_panel_handle_t handle_{}; +}; + +} // namespace st7701s +} // namespace esphome +#endif diff --git a/tests/components/rpi_dpi_rgb/test.esp32-s3-idf.yaml b/tests/components/rpi_dpi_rgb/test.esp32-s3-idf.yaml new file mode 100644 index 0000000000..9ce2d9b9fd --- /dev/null +++ b/tests/components/rpi_dpi_rgb/test.esp32-s3-idf.yaml @@ -0,0 +1,40 @@ +psram: + mode: octal + speed: 80MHz +display: + - platform: rpi_dpi_rgb + update_interval: never + auto_clear_enabled: false + id: rpi_display + color_order: RGB + rotation: 90 + dimensions: + width: 800 + height: 480 + de_pin: + number: 40 + hsync_pin: 39 + vsync_pin: 41 + pclk_pin: 42 + data_pins: + red: + - number: 45 # r1 + ignore_strapping_warning: true + - 48 # r2 + - 47 # r3 + - 21 # r4 + - number: 14 # r5 + ignore_strapping_warning: false + green: + - 5 # g0 + - 6 # g1 + - 7 # g2 + - 15 # g3 + - 16 # g4 + - 4 # g5 + blue: + - 8 # b1 + - 3 # b2 + - 46 # b3 + - 9 # b4 + - 1 # b5 diff --git a/tests/components/st7701s/test.esp32-s3-idf.yaml b/tests/components/st7701s/test.esp32-s3-idf.yaml new file mode 100644 index 0000000000..497df8c8ce --- /dev/null +++ b/tests/components/st7701s/test.esp32-s3-idf.yaml @@ -0,0 +1,60 @@ +psram: + mode: octal + speed: 80MHz +spi: + - id: lcd_spi + clk_pin: 41 + mosi_pin: 48 + +i2c: + sda: 39 + scl: 40 + scan: false + id: bus_a + +pca9554: + - id: p_c_a + pin_count: 16 + address: 0x20 + +display: + - platform: st7701s + spi_mode: MODE3 + color_order: RGB + dimensions: + width: 480 + height: 480 + invert_colors: true + transform: + mirror_x: true + mirror_y: true + cs_pin: + pca9554: p_c_a + number: 4 + reset_pin: + pca9554: p_c_a + number: 5 + de_pin: 18 + hsync_pin: 16 + vsync_pin: 17 + pclk_pin: 21 + init_sequence: 1 + data_pins: + - number: 0 + ignore_strapping_warning: true + - 1 + - 2 + - 3 + - number: 4 + ignore_strapping_warning: false + - 5 + - 6 + - 7 + - 8 + - 9 + - 10 + - 11 + - 12 + - 13 + - 14 + - 15 From 51ab15c40e6f81ac78fc884946ff3ecd999a14d0 Mon Sep 17 00:00:00 2001 From: mrtoy-me <118446898+mrtoy-me@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:31:58 +1000 Subject: [PATCH 084/189] hydreon_rgxx - add resolution option (#6077) Co-authored-by: functionpointer --- esphome/components/hydreon_rgxx/__init__.py | 1 + .../components/hydreon_rgxx/hydreon_rgxx.cpp | 11 ++++++++++- esphome/components/hydreon_rgxx/hydreon_rgxx.h | 9 +++++++++ esphome/components/hydreon_rgxx/sensor.py | 18 +++++++++++++++--- tests/test3.yaml | 1 + 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/esphome/components/hydreon_rgxx/__init__.py b/esphome/components/hydreon_rgxx/__init__.py index 5fe050edf2..b488bfc1b4 100644 --- a/esphome/components/hydreon_rgxx/__init__.py +++ b/esphome/components/hydreon_rgxx/__init__.py @@ -6,6 +6,7 @@ DEPENDENCIES = ["uart"] hydreon_rgxx_ns = cg.esphome_ns.namespace("hydreon_rgxx") RGModel = hydreon_rgxx_ns.enum("RGModel") +RG15Resolution = hydreon_rgxx_ns.enum("RG15Resolution") HydreonRGxxComponent = hydreon_rgxx_ns.class_( "HydreonRGxxComponent", cg.PollingComponent, uart.UARTDevice ) diff --git a/esphome/components/hydreon_rgxx/hydreon_rgxx.cpp b/esphome/components/hydreon_rgxx/hydreon_rgxx.cpp index c026d7cce6..95702fe9e8 100644 --- a/esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +++ b/esphome/components/hydreon_rgxx/hydreon_rgxx.cpp @@ -22,6 +22,11 @@ void HydreonRGxxComponent::dump_config() { ESP_LOGCONFIG(TAG, " Disable Led: %s", TRUEFALSE(this->disable_led_)); } else { ESP_LOGCONFIG(TAG, " Model: RG15"); + if (this->resolution_ == FORCE_HIGH) { + ESP_LOGCONFIG(TAG, " Resolution: high"); + } else { + ESP_LOGCONFIG(TAG, " Resolution: low"); + } } LOG_UPDATE_INTERVAL(this); @@ -195,7 +200,11 @@ void HydreonRGxxComponent::process_line_() { ESP_LOGI(TAG, "Boot detected: %s", this->buffer_.substr(0, this->buffer_.size() - 2).c_str()); if (this->model_ == RG15) { - this->write_str("P\nH\nM\n"); // set sensor to (P)polling mode, (H)high res mode, (M)metric mode + if (this->resolution_ == FORCE_HIGH) { + this->write_str("P\nH\nM\n"); // set sensor to (P)polling mode, (H)high res mode, (M)metric mode + } else { + this->write_str("P\nL\nM\n"); // set sensor to (P)polling mode, (L)low res mode, (M)metric mode + } } if (this->model_ == RG9) { diff --git a/esphome/components/hydreon_rgxx/hydreon_rgxx.h b/esphome/components/hydreon_rgxx/hydreon_rgxx.h index 1edda59800..76b0985a24 100644 --- a/esphome/components/hydreon_rgxx/hydreon_rgxx.h +++ b/esphome/components/hydreon_rgxx/hydreon_rgxx.h @@ -16,6 +16,11 @@ enum RGModel { RG15 = 2, }; +enum RG15Resolution { + FORCE_LOW = 1, + FORCE_HIGH = 2, +}; + #ifdef HYDREON_RGXX_NUM_SENSORS static const uint8_t NUM_SENSORS = HYDREON_RGXX_NUM_SENSORS; #else @@ -37,6 +42,7 @@ class HydreonRGxxComponent : public PollingComponent, public uart::UARTDevice { void set_em_sat_sensor(binary_sensor::BinarySensor *sensor) { this->em_sat_sensor_ = sensor; } #endif void set_model(RGModel model) { model_ = model; } + void set_resolution(RG15Resolution resolution) { resolution_ = resolution; } void set_request_temperature(bool b) { request_temperature_ = b; } /// Schedule data readings. @@ -68,7 +74,10 @@ class HydreonRGxxComponent : public PollingComponent, public uart::UARTDevice { int16_t boot_count_ = 0; int16_t no_response_count_ = 0; std::string buffer_; + RGModel model_ = RG9; + RG15Resolution resolution_ = FORCE_HIGH; + int sw_version_ = 0; bool too_cold_ = false; bool lens_bad_ = false; diff --git a/esphome/components/hydreon_rgxx/sensor.py b/esphome/components/hydreon_rgxx/sensor.py index f9cb316c24..72b74bf624 100644 --- a/esphome/components/hydreon_rgxx/sensor.py +++ b/esphome/components/hydreon_rgxx/sensor.py @@ -5,6 +5,7 @@ from esphome.const import ( CONF_ID, CONF_MODEL, CONF_MOISTURE, + CONF_RESOLUTION, CONF_TEMPERATURE, DEVICE_CLASS_PRECIPITATION_INTENSITY, DEVICE_CLASS_PRECIPITATION, @@ -14,7 +15,7 @@ from esphome.const import ( ICON_THERMOMETER, ) -from . import RGModel, HydreonRGxxComponent +from . import RGModel, RG15Resolution, HydreonRGxxComponent UNIT_INTENSITY = "intensity" UNIT_MILLIMETERS = "mm" @@ -37,11 +38,18 @@ RG_MODELS = { # 1.100 - https://rainsensors.com/wp-content/uploads/sites/3/2021/03/2021.03.11-rg-9_instructions.pdf # 1.200 - https://rainsensors.com/wp-content/uploads/sites/3/2022/03/2022.02.17-rev-1.200-rg-9_instructions.pdf } -SUPPORTED_SENSORS = { + +RG15_RESOLUTION = { + "low": RG15Resolution.FORCE_LOW, + "high": RG15Resolution.FORCE_HIGH, +} + +SUPPORTED_OPTIONS = { CONF_ACC: ["RG_15"], CONF_EVENT_ACC: ["RG_15"], CONF_TOTAL_ACC: ["RG_15"], CONF_R_INT: ["RG_15"], + CONF_RESOLUTION: ["RG_15"], CONF_MOISTURE: ["RG_9"], CONF_TEMPERATURE: ["RG_9"], CONF_DISABLE_LED: ["RG_9"], @@ -57,7 +65,7 @@ PROTOCOL_NAMES = { def _validate(config): - for conf, models in SUPPORTED_SENSORS.items(): + for conf, models in SUPPORTED_OPTIONS.items(): if conf in config: if config[CONF_MODEL] not in models: raise cv.Invalid( @@ -75,6 +83,7 @@ CONFIG_SCHEMA = cv.All( upper=True, space="_", ), + cv.Optional(CONF_RESOLUTION): cv.enum(RG15_RESOLUTION, upper=False), cv.Optional(CONF_ACC): sensor.sensor_schema( unit_of_measurement=UNIT_MILLIMETERS, accuracy_decimals=2, @@ -139,6 +148,9 @@ async def to_code(config): cg.add(var.set_sensor(sens, i)) cg.add(var.set_model(config[CONF_MODEL])) + if CONF_RESOLUTION in config: + cg.add(var.set_resolution(config[CONF_RESOLUTION])) + cg.add(var.set_request_temperature(CONF_TEMPERATURE in config)) if CONF_DISABLE_LED in config: diff --git a/tests/test3.yaml b/tests/test3.yaml index 29ed40c52a..61d814385b 100644 --- a/tests/test3.yaml +++ b/tests/test3.yaml @@ -409,6 +409,7 @@ sensor: name: hydreon_total_acc r_int: name: hydreon_r_int + resolution: low - platform: adc pin: VCC From 782d662c2029e21fbb6ddb3a434cbe20dc310208 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:50:24 +1100 Subject: [PATCH 085/189] SPI schema now uses typed_schema with `type` key (#6353) --- esphome/components/spi/__init__.py | 22 +++++++++++++------- tests/components/spi/test.esp32-s3-idf.yaml | 23 +++++++++++++++++++++ tests/test8.1.yaml | 12 ++--------- 3 files changed, 39 insertions(+), 18 deletions(-) create mode 100644 tests/components/spi/test.esp32-s3-idf.yaml diff --git a/esphome/components/spi/__init__.py b/esphome/components/spi/__init__.py index d45362435e..c2335bd92a 100644 --- a/esphome/components/spi/__init__.py +++ b/esphome/components/spi/__init__.py @@ -32,7 +32,10 @@ from esphome.const import ( CONF_ALLOW_OTHER_USES, CONF_DATA_PINS, ) -from esphome.core import coroutine_with_priority, CORE +from esphome.core import ( + coroutine_with_priority, + CORE, +) CODEOWNERS = ["@esphome/core", "@clydebarrow"] spi_ns = cg.esphome_ns.namespace("spi") @@ -73,6 +76,8 @@ CONF_SPI_MODE = "spi_mode" CONF_FORCE_SW = "force_sw" CONF_INTERFACE = "interface" CONF_INTERFACE_INDEX = "interface_index" +TYPE_SINGLE = "single" +TYPE_QUAD = "quad" # RP2040 SPI pin assignments are complicated; # refer to GPIO function select table in https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf @@ -297,18 +302,19 @@ SPI_QUAD_SCHEMA = cv.All( ), } ), + cv.only_on([PLATFORM_ESP32]), cv.only_with_esp_idf, ) CONFIG_SCHEMA = cv.All( - # Order is important. SPI_SCHEMA is the default. cv.ensure_list( - cv.Any( - SPI_SCHEMA, - SPI_QUAD_SCHEMA, - msg="Standard SPI requires mosi_pin and/or miso_pin; quad SPI requires data_pins only." - + " A clock pin is always required", - ), + cv.typed_schema( + { + TYPE_SINGLE: SPI_SCHEMA, + TYPE_QUAD: SPI_QUAD_SCHEMA, + }, + default_type=TYPE_SINGLE, + ) ), validate_spi_config, ) diff --git a/tests/components/spi/test.esp32-s3-idf.yaml b/tests/components/spi/test.esp32-s3-idf.yaml new file mode 100644 index 0000000000..3aae21cbeb --- /dev/null +++ b/tests/components/spi/test.esp32-s3-idf.yaml @@ -0,0 +1,23 @@ +spi: + - id: spi_id_1 + type: single + clk_pin: + number: GPIO7 + allow_other_uses: false + mosi_pin: GPIO6 + interface: hardware + - id: quad_spi + type: quad + clk_pin: 47 + interface: spi3 + data_pins: + - number: 40 + allow_other_uses: false + - 41 + - 42 + - 43 + - id: spi_id_3 + clk_pin: 8 + mosi_pin: 9 + interface: any + diff --git a/tests/test8.1.yaml b/tests/test8.1.yaml index fdfa8bc786..ab3d0d44aa 100644 --- a/tests/test8.1.yaml +++ b/tests/test8.1.yaml @@ -23,20 +23,12 @@ psram: spi: - id: spi_id_1 + type: single clk_pin: number: GPIO7 allow_other_uses: false mosi_pin: GPIO6 - interface: any - - id: quad_spi - clk_pin: 47 - data_pins: - - number: 40 - allow_other_uses: false - - 41 - - 42 - - 43 - + interface: hardware spi_device: id: spidev data_rate: 2MHz From 5b28bd3d97733c44a7f79f9f6d2f143b0264fe34 Mon Sep 17 00:00:00 2001 From: Anton Viktorov Date: Tue, 12 Mar 2024 03:51:01 +0100 Subject: [PATCH 086/189] VEML7700 and VEML6030 light sensors (#6067) * VEML7700 and VEML6030 light sensors * VEML7700 and VEML6030 light sensors - CODEOWNERS * VEML7700 and VEML6030 light sensors - tidy up * VEML7700 and VEML6030 light sensors - tidy up * VEML7700 tidy up * VEML7700 tidy up 4 * VEML7700 tidying up more * VEML7700 after review. non-blocking approach * VEML7700 CONSTANT_CASE * VEML7700 merge fix * VEML7700 pragma pack changed to attribute * VEML7700 pragma pack -> attribute * Minor publish split * minor * LOGD->LOGV * new school tests added * Discard changes to tests/test1.yaml --------- Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Co-authored-by: Keith Burzinski --- CODEOWNERS | 1 + esphome/components/veml7700/__init__.py | 1 + esphome/components/veml7700/sensor.py | 190 ++++++++ esphome/components/veml7700/veml7700.cpp | 437 ++++++++++++++++++ esphome/components/veml7700/veml7700.h | 202 ++++++++ tests/components/veml7700/common.yaml | 10 + .../veml7700/test.esp32-c3-idf.yaml | 6 + tests/components/veml7700/test.esp32-c3.yaml | 6 + tests/components/veml7700/test.esp32-idf.yaml | 6 + tests/components/veml7700/test.esp32.yaml | 6 + tests/components/veml7700/test.esp8266.yaml | 6 + tests/components/veml7700/test.rp2040.yaml | 6 + 12 files changed, 877 insertions(+) create mode 100644 esphome/components/veml7700/__init__.py create mode 100644 esphome/components/veml7700/sensor.py create mode 100644 esphome/components/veml7700/veml7700.cpp create mode 100644 esphome/components/veml7700/veml7700.h create mode 100644 tests/components/veml7700/common.yaml create mode 100644 tests/components/veml7700/test.esp32-c3-idf.yaml create mode 100644 tests/components/veml7700/test.esp32-c3.yaml create mode 100644 tests/components/veml7700/test.esp32-idf.yaml create mode 100644 tests/components/veml7700/test.esp32.yaml create mode 100644 tests/components/veml7700/test.esp8266.yaml create mode 100644 tests/components/veml7700/test.rp2040.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 320c2d5e7e..e31dd16077 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -380,6 +380,7 @@ esphome/components/ultrasonic/* @OttoWinter esphome/components/uponor_smatrix/* @kroimon esphome/components/vbus/* @ssieb esphome/components/veml3235/* @kbx81 +esphome/components/veml7700/* @latonita esphome/components/version/* @esphome/core esphome/components/voice_assistant/* @jesserockz esphome/components/wake_on_lan/* @willwill2will54 diff --git a/esphome/components/veml7700/__init__.py b/esphome/components/veml7700/__init__.py new file mode 100644 index 0000000000..dd06cfffea --- /dev/null +++ b/esphome/components/veml7700/__init__.py @@ -0,0 +1 @@ +CODEOWNERS = ["@latonita"] diff --git a/esphome/components/veml7700/sensor.py b/esphome/components/veml7700/sensor.py new file mode 100644 index 0000000000..7ce05b47e4 --- /dev/null +++ b/esphome/components/veml7700/sensor.py @@ -0,0 +1,190 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import i2c, sensor +from esphome.const import ( + CONF_ACTUAL_GAIN, + CONF_AUTO_MODE, + CONF_FULL_SPECTRUM, + CONF_GAIN, + CONF_GLASS_ATTENUATION_FACTOR, + CONF_ID, + CONF_INFRARED, + CONF_INTEGRATION_TIME, + CONF_NAME, + UNIT_LUX, + UNIT_MILLISECOND, + ICON_BRIGHTNESS_5, + ICON_BRIGHTNESS_6, + ICON_TIMER, + DEVICE_CLASS_ILLUMINANCE, + STATE_CLASS_MEASUREMENT, +) + +CODEOWNERS = ["@latonita"] +DEPENDENCIES = ["i2c"] + +UNIT_COUNTS = "#" +ICON_MULTIPLICATION = "mdi:multiplication" +ICON_BRIGHTNESS_7 = "mdi:brightness-7" + +CONF_ACTUAL_INTEGRATION_TIME = "actual_integration_time" +CONF_AMBIENT_LIGHT = "ambient_light" +CONF_AMBIENT_LIGHT_COUNTS = "ambient_light_counts" +CONF_FULL_SPECTRUM_COUNTS = "full_spectrum_counts" +CONF_LUX_COMPENSATION = "lux_compensation" + +veml7700_ns = cg.esphome_ns.namespace("veml7700") + +VEML7700Component = veml7700_ns.class_( + "VEML7700Component", cg.PollingComponent, i2c.I2CDevice +) + +Gain = veml7700_ns.enum("Gain") +GAINS = { + "1/8X": Gain.X_1_8, + "1/4X": Gain.X_1_4, + "1X": Gain.X_1, + "2X": Gain.X_2, +} + +IntegrationTime = veml7700_ns.enum("IntegrationTime") +INTEGRATION_TIMES = { + 25: IntegrationTime.INTEGRATION_TIME_25MS, + 50: IntegrationTime.INTEGRATION_TIME_50MS, + 100: IntegrationTime.INTEGRATION_TIME_100MS, + 200: IntegrationTime.INTEGRATION_TIME_200MS, + 400: IntegrationTime.INTEGRATION_TIME_400MS, + 800: IntegrationTime.INTEGRATION_TIME_800MS, +} + + +def validate_integration_time(value): + value = cv.positive_time_period_milliseconds(value).total_milliseconds + return cv.enum(INTEGRATION_TIMES, int=True)(value) + + +CONFIG_SCHEMA = cv.All( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(VEML7700Component), + cv.Optional(CONF_AUTO_MODE, default=True): cv.boolean, + cv.Optional(CONF_GAIN, default="1/8X"): cv.enum(GAINS, upper=True), + cv.Optional( + CONF_INTEGRATION_TIME, default="100ms" + ): validate_integration_time, + cv.Optional(CONF_LUX_COMPENSATION, default=True): cv.boolean, + cv.Optional(CONF_GLASS_ATTENUATION_FACTOR, default=1.0): cv.float_range( + min=1.0 + ), + cv.Optional(CONF_AMBIENT_LIGHT): cv.maybe_simple_value( + sensor.sensor_schema( + unit_of_measurement=UNIT_LUX, + icon=ICON_BRIGHTNESS_6, + accuracy_decimals=1, + device_class=DEVICE_CLASS_ILLUMINANCE, + state_class=STATE_CLASS_MEASUREMENT, + ), + key=CONF_NAME, + ), + cv.Optional(CONF_AMBIENT_LIGHT_COUNTS): cv.maybe_simple_value( + sensor.sensor_schema( + unit_of_measurement=UNIT_COUNTS, + icon=ICON_BRIGHTNESS_6, + accuracy_decimals=0, + device_class=DEVICE_CLASS_ILLUMINANCE, + state_class=STATE_CLASS_MEASUREMENT, + ), + key=CONF_NAME, + ), + cv.Optional(CONF_FULL_SPECTRUM): cv.maybe_simple_value( + sensor.sensor_schema( + unit_of_measurement=UNIT_LUX, + icon=ICON_BRIGHTNESS_7, + accuracy_decimals=1, + device_class=DEVICE_CLASS_ILLUMINANCE, + state_class=STATE_CLASS_MEASUREMENT, + ), + key=CONF_NAME, + ), + cv.Optional(CONF_FULL_SPECTRUM_COUNTS): cv.maybe_simple_value( + sensor.sensor_schema( + unit_of_measurement=UNIT_COUNTS, + icon=ICON_BRIGHTNESS_7, + accuracy_decimals=0, + device_class=DEVICE_CLASS_ILLUMINANCE, + state_class=STATE_CLASS_MEASUREMENT, + ), + key=CONF_NAME, + ), + cv.Optional(CONF_INFRARED): cv.maybe_simple_value( + sensor.sensor_schema( + unit_of_measurement=UNIT_LUX, + icon=ICON_BRIGHTNESS_5, + accuracy_decimals=1, + device_class=DEVICE_CLASS_ILLUMINANCE, + state_class=STATE_CLASS_MEASUREMENT, + ), + key=CONF_NAME, + ), + cv.Optional(CONF_ACTUAL_GAIN): cv.maybe_simple_value( + sensor.sensor_schema( + icon=ICON_MULTIPLICATION, + accuracy_decimals=3, + state_class=STATE_CLASS_MEASUREMENT, + ), + key=CONF_NAME, + ), + cv.Optional(CONF_ACTUAL_INTEGRATION_TIME): cv.maybe_simple_value( + sensor.sensor_schema( + unit_of_measurement=UNIT_MILLISECOND, + icon=ICON_TIMER, + accuracy_decimals=0, + state_class=STATE_CLASS_MEASUREMENT, + ), + key=CONF_NAME, + ), + } + ) + .extend(cv.polling_component_schema("60s")) + .extend(i2c.i2c_device_schema(0x10)), +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) + await i2c.register_i2c_device(var, config) + + if als_config := config.get(CONF_AMBIENT_LIGHT): + sens = await sensor.new_sensor(als_config) + cg.add(var.set_ambient_light_sensor(sens)) + + if als_cnt_config := config.get(CONF_AMBIENT_LIGHT_COUNTS): + sens = await sensor.new_sensor(als_cnt_config) + cg.add(var.set_ambient_light_counts_sensor(sens)) + + if full_spect_config := config.get(CONF_FULL_SPECTRUM): + sens = await sensor.new_sensor(full_spect_config) + cg.add(var.set_white_sensor(sens)) + + if full_spect_cnt_config := config.get(CONF_FULL_SPECTRUM_COUNTS): + sens = await sensor.new_sensor(full_spect_cnt_config) + cg.add(var.set_white_counts_sensor(sens)) + + if infrared_config := config.get(CONF_INFRARED): + sens = await sensor.new_sensor(infrared_config) + cg.add(var.set_infrared_sensor(sens)) + + if act_gain_config := config.get(CONF_ACTUAL_GAIN): + sens = await sensor.new_sensor(act_gain_config) + cg.add(var.set_actual_gain_sensor(sens)) + + if act_itime_config := config.get(CONF_ACTUAL_INTEGRATION_TIME): + sens = await sensor.new_sensor(act_itime_config) + cg.add(var.set_actual_integration_time_sensor(sens)) + + cg.add(var.set_enable_automatic_mode(config[CONF_AUTO_MODE])) + cg.add(var.set_enable_lux_compensation(config[CONF_LUX_COMPENSATION])) + cg.add(var.set_gain(config[CONF_GAIN])) + cg.add(var.set_integration_time(config[CONF_INTEGRATION_TIME])) + cg.add(var.set_glass_attenuation_factor(config[CONF_GLASS_ATTENUATION_FACTOR])) diff --git a/esphome/components/veml7700/veml7700.cpp b/esphome/components/veml7700/veml7700.cpp new file mode 100644 index 0000000000..68550811a1 --- /dev/null +++ b/esphome/components/veml7700/veml7700.cpp @@ -0,0 +1,437 @@ +#include "veml7700.h" +#include "esphome/core/application.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace veml7700 { + +static const char *const TAG = "veml7700"; +static const size_t VEML_REG_SIZE = 2; + +static float reduce_to_zero(float a, float b) { return (a > b) ? (a - b) : 0; } + +template T get_next(const T (&array)[size], const T val) { + size_t i = 0; + size_t idx = -1; + while (idx == -1 && i < size) { + if (array[i] == val) { + idx = i; + break; + } + i++; + } + if (idx == -1 || i + 1 >= size) + return val; + return array[i + 1]; +} + +template T get_prev(const T (&array)[size], const T val) { + size_t i = size - 1; + size_t idx = -1; + while (idx == -1 && i > 0) { + if (array[i] == val) { + idx = i; + break; + } + i--; + } + if (idx == -1 || i == 0) + return val; + return array[i - 1]; +} + +static uint16_t get_itime_ms(IntegrationTime time) { + uint16_t ms = 0; + switch (time) { + case INTEGRATION_TIME_100MS: + ms = 100; + break; + case INTEGRATION_TIME_200MS: + ms = 200; + break; + case INTEGRATION_TIME_400MS: + ms = 400; + break; + case INTEGRATION_TIME_800MS: + ms = 800; + break; + case INTEGRATION_TIME_50MS: + ms = 50; + break; + case INTEGRATION_TIME_25MS: + ms = 25; + break; + default: + ms = 100; + } + return ms; +} + +static float get_gain_coeff(Gain gain) { + static const float GAIN_FLOAT[GAINS_COUNT] = {1.0f, 2.0f, 0.125f, 0.25f}; + return GAIN_FLOAT[gain & 0b11]; +} + +static const char *get_gain_str(Gain gain) { + static const char *gain_str[GAINS_COUNT] = {"1x", "2x", "1/8x", "1/4x"}; + return gain_str[gain & 0b11]; +} + +void VEML7700Component::setup() { + ESP_LOGCONFIG(TAG, "Setting up VEML7700/6030..."); + + auto err = this->configure_(); + if (err != i2c::ERROR_OK) { + ESP_LOGW(TAG, "Sensor configuration failed"); + this->mark_failed(); + } else { + this->state_ = State::INITIAL_SETUP_COMPLETED; + } +} + +void VEML7700Component::dump_config() { + LOG_I2C_DEVICE(this); + ESP_LOGCONFIG(TAG, " Automatic gain/time: %s", YESNO(this->automatic_mode_enabled_)); + if (!this->automatic_mode_enabled_) { + ESP_LOGCONFIG(TAG, " Gain: %s", get_gain_str(this->gain_)); + ESP_LOGCONFIG(TAG, " Integration time: %d ms", get_itime_ms(this->integration_time_)); + } + ESP_LOGCONFIG(TAG, " Lux compensation: %s", YESNO(this->lux_compensation_enabled_)); + ESP_LOGCONFIG(TAG, " Glass attenuation factor: %f", this->glass_attenuation_factor_); + LOG_UPDATE_INTERVAL(this); + + LOG_SENSOR(" ", "ALS channel lux", this->ambient_light_sensor_); + LOG_SENSOR(" ", "ALS channel counts", this->ambient_light_counts_sensor_); + LOG_SENSOR(" ", "WHITE channel lux", this->white_sensor_); + LOG_SENSOR(" ", "WHITE channel counts", this->white_counts_sensor_); + LOG_SENSOR(" ", "FAKE_IR channel lux", this->fake_infrared_sensor_); + LOG_SENSOR(" ", "Actual gain", this->actual_gain_sensor_); + LOG_SENSOR(" ", "Actual integration time", this->actual_integration_time_sensor_); + + if (this->is_failed()) { + ESP_LOGE(TAG, "Communication with I2C VEML7700/6030 failed!"); + } +} + +void VEML7700Component::update() { + if (this->is_ready() && this->state_ == State::IDLE) { + ESP_LOGV(TAG, "Update: Initiating new data collection"); + + this->state_ = this->automatic_mode_enabled_ ? State::COLLECTING_DATA_AUTO : State::COLLECTING_DATA; + + this->readings_.als_counts = 0; + this->readings_.white_counts = 0; + this->readings_.actual_time = this->integration_time_; + this->readings_.actual_gain = this->gain_; + this->readings_.als_lux = 0; + this->readings_.white_lux = 0; + this->readings_.fake_infrared_lux = 0; + } else { + ESP_LOGV(TAG, "Update: Component not ready yet"); + } +} + +void VEML7700Component::loop() { + ErrorCode err = i2c::ERROR_OK; + + if (this->state_ == State::INITIAL_SETUP_COMPLETED) { + // Datasheet: 2.5 ms before the first measurement is needed, allowing for the correct start of the signal processor + // and oscillator. + // Reality: wait for couple integration times to have first samples captured + this->set_timeout(2 * this->integration_time_, [this]() { this->state_ = State::IDLE; }); + } + + if (this->is_ready()) { + switch (this->state_) { + case State::IDLE: + // doing nothing, having best time + break; + + case State::COLLECTING_DATA: + err = this->read_sensor_output_(this->readings_); + this->state_ = (err == i2c::ERROR_OK) ? State::DATA_COLLECTED : State::IDLE; + break; + + case State::COLLECTING_DATA_AUTO: // Automatic mode - we start here to reconfigure device first + case State::DATA_COLLECTED: + if (!this->are_adjustments_required_(this->readings_)) { + this->state_ = State::READY_TO_PUBLISH_PART_1; + } else { + // if sensitivity adjustment needed - + // shutdown device to change config and wait one integration time period + this->state_ = State::ADJUSTMENT_IN_PROGRESS; + err = this->reconfigure_time_and_gain_(this->readings_.actual_time, this->readings_.actual_gain, true); + if (err == i2c::ERROR_OK) { + this->set_timeout(1 * get_itime_ms(this->readings_.actual_time), + [this]() { this->state_ = State::READY_TO_APPLY_ADJUSTMENTS; }); + } else { + this->state_ = State::IDLE; + } + } + break; + + case State::ADJUSTMENT_IN_PROGRESS: + // nothing to be done, just waiting for the timeout + break; + + case State::READY_TO_APPLY_ADJUSTMENTS: + // second stage of sensitivity adjustment - turn device back on + // and wait 2-3 integration time periods to get good data samples + this->state_ = State::ADJUSTMENT_IN_PROGRESS; + err = this->reconfigure_time_and_gain_(this->readings_.actual_time, this->readings_.actual_gain, false); + if (err == i2c::ERROR_OK) { + this->set_timeout(3 * get_itime_ms(this->readings_.actual_time), + [this]() { this->state_ = State::COLLECTING_DATA; }); + } else { + this->state_ = State::IDLE; + } + break; + + case State::READY_TO_PUBLISH_PART_1: + this->status_clear_warning(); + + this->apply_lux_calculation_(this->readings_); + this->apply_lux_compensation_(this->readings_); + this->apply_glass_attenuation_(this->readings_); + + this->publish_data_part_1_(this->readings_); + this->state_ = State::READY_TO_PUBLISH_PART_2; + break; + + case State::READY_TO_PUBLISH_PART_2: + this->publish_data_part_2_(this->readings_); + this->state_ = State::READY_TO_PUBLISH_PART_3; + break; + + case State::READY_TO_PUBLISH_PART_3: + this->publish_data_part_3_(this->readings_); + this->state_ = State::IDLE; + break; + + default: + break; + } + if (err != i2c::ERROR_OK) + this->status_set_warning(); + } +} + +ErrorCode VEML7700Component::configure_() { + ESP_LOGV(TAG, "Configure"); + + ConfigurationRegister als_conf{0}; + als_conf.ALS_INT_EN = false; + als_conf.ALS_PERS = Persistence::PERSISTENCE_1; + als_conf.ALS_IT = this->integration_time_; + als_conf.ALS_GAIN = this->gain_; + + als_conf.ALS_SD = true; + ESP_LOGV(TAG, "Shutdown before config. ALS_CONF_0 to 0x%04X", als_conf.raw); + auto err = this->write_register((uint8_t) CommandRegisters::ALS_CONF_0, als_conf.raw_bytes, VEML_REG_SIZE); + if (err != i2c::ERROR_OK) { + ESP_LOGW(TAG, "Failed to shutdown, I2C error %d", err); + return err; + } + delay(3); + + als_conf.ALS_SD = false; + ESP_LOGV(TAG, "Turning on. Setting ALS_CONF_0 to 0x%04X", als_conf.raw); + err = this->write_register((uint8_t) CommandRegisters::ALS_CONF_0, als_conf.raw_bytes, VEML_REG_SIZE); + if (err != i2c::ERROR_OK) { + ESP_LOGW(TAG, "Failed to turn on, I2C error %d", err); + return err; + } + + PSMRegister psm{0}; + psm.PSM = PSM::PSM_MODE_1; + psm.PSM_EN = false; + ESP_LOGV(TAG, "Setting PSM to 0x%04X", psm.raw); + err = this->write_register((uint8_t) CommandRegisters::PWR_SAVING, psm.raw_bytes, VEML_REG_SIZE); + if (err != i2c::ERROR_OK) { + ESP_LOGW(TAG, "Failed to set PSM, I2C error %d", err); + return err; + } + + return err; +} + +ErrorCode VEML7700Component::reconfigure_time_and_gain_(IntegrationTime time, Gain gain, bool shutdown) { + ESP_LOGV(TAG, "Reconfigure time and gain (%d ms, %s) %s", get_itime_ms(time), get_gain_str(gain), + shutdown ? "Shutting down" : "Turning back on"); + + ConfigurationRegister als_conf{0}; + als_conf.raw = 0; + + // We have to before changing parameters + als_conf.ALS_SD = shutdown; + als_conf.ALS_INT_EN = false; + als_conf.ALS_PERS = Persistence::PERSISTENCE_1; + als_conf.ALS_IT = time; + als_conf.ALS_GAIN = gain; + auto err = this->write_register((uint8_t) CommandRegisters::ALS_CONF_0, als_conf.raw_bytes, VEML_REG_SIZE); + if (err != i2c::ERROR_OK) { + ESP_LOGW(TAG, "%s failed", shutdown ? "Shutdown" : "Turn on"); + } + + return err; +} + +ErrorCode VEML7700Component::read_sensor_output_(Readings &data) { + auto als_err = + this->read_register((uint8_t) CommandRegisters::ALS, (uint8_t *) &data.als_counts, VEML_REG_SIZE, false); + if (als_err != i2c::ERROR_OK) { + ESP_LOGW(TAG, "Error reading ALS register, err = %d", als_err); + } + auto white_err = + this->read_register((uint8_t) CommandRegisters::WHITE, (uint8_t *) &data.white_counts, VEML_REG_SIZE, false); + if (white_err != i2c::ERROR_OK) { + ESP_LOGW(TAG, "Error reading WHITE register, err = %d", white_err); + } + + ConfigurationRegister conf{0}; + auto err = + this->read_register((uint8_t) CommandRegisters::ALS_CONF_0, (uint8_t *) conf.raw_bytes, VEML_REG_SIZE, false); + if (err != i2c::ERROR_OK) { + ESP_LOGW(TAG, "Error reading ALS_CONF_0 register, err = %d", white_err); + } + data.actual_time = conf.ALS_IT; + data.actual_gain = conf.ALS_GAIN; + + ESP_LOGV(TAG, "Data from sensors: ALS = %d, WHITE = %d, Gain = %s, Time = %d ms", data.als_counts, data.white_counts, + get_gain_str(data.actual_gain), get_itime_ms(data.actual_time)); + return std::max(als_err, white_err); +} + +bool VEML7700Component::are_adjustments_required_(Readings &data) { + // skip first sample in auto mode - + // we need to reconfigure device after last measurement + if (this->state_ == State::COLLECTING_DATA_AUTO) + return true; + + if (!this->automatic_mode_enabled_) + return false; + + // Recommended thresholds as per datasheet + static constexpr uint16_t LOW_INTENSITY_THRESHOLD = 100; + static constexpr uint16_t HIGH_INTENSITY_THRESHOLD = 10000; + + static const IntegrationTime TIMES[INTEGRATION_TIMES_COUNT] = {INTEGRATION_TIME_25MS, INTEGRATION_TIME_50MS, + INTEGRATION_TIME_100MS, INTEGRATION_TIME_200MS, + INTEGRATION_TIME_400MS, INTEGRATION_TIME_800MS}; + static const Gain GAINS[GAINS_COUNT] = {X_1_8, X_1_4, X_1, X_2}; + + if (data.als_counts <= LOW_INTENSITY_THRESHOLD) { + Gain next_gain = get_next(GAINS, data.actual_gain); + if (next_gain != data.actual_gain) { + data.actual_gain = next_gain; + return true; + } + IntegrationTime next_time = get_next(TIMES, data.actual_time); + if (next_time != data.actual_time) { + data.actual_time = next_time; + return true; + } + } else if (data.als_counts >= HIGH_INTENSITY_THRESHOLD) { + Gain prev_gain = get_prev(GAINS, data.actual_gain); + if (prev_gain != data.actual_gain) { + data.actual_gain = prev_gain; + return true; + } + IntegrationTime prev_time = get_prev(TIMES, data.actual_time); + if (prev_time != data.actual_time) { + data.actual_time = prev_time; + return true; + } + } + + // Counts are either good (between thresholds) + // or there is no room to change sensitivity anymore + return false; +} + +void VEML7700Component::apply_lux_calculation_(Readings &data) { + static const float MAX_GAIN = 2.0f; + static const float MAX_ITIME_MS = 800.0f; + static const float MAX_LX_RESOLUTION = 0.0036f; + float lux_resolution = (MAX_ITIME_MS / (float) get_itime_ms(data.actual_time)) * + (MAX_GAIN / get_gain_coeff(data.actual_gain)) * MAX_LX_RESOLUTION; + ESP_LOGV(TAG, "Lux resolution for (%d, %s) = %.4f ", get_itime_ms(data.actual_time), get_gain_str(data.actual_gain), + lux_resolution); + + data.als_lux = lux_resolution * (float) data.als_counts; + data.white_lux = lux_resolution * (float) data.white_counts; + data.fake_infrared_lux = reduce_to_zero(data.white_lux, data.als_lux); + + ESP_LOGV(TAG, "%s mode - ALS = %.1f lx, WHITE = %.1f lx, FAKE_IR = %.1f lx", + this->automatic_mode_enabled_ ? "Automatic" : "Manual", data.als_lux, data.white_lux, + data.fake_infrared_lux); +} + +void VEML7700Component::apply_lux_compensation_(Readings &data) { + if (!this->lux_compensation_enabled_) + return; + auto &local_data = data; + // Always apply correction for G1/4 and G1/8 + // Other Gains G1 and G2 are not supposed to be used for lux > 1000, + // corrections may help, but not a lot. + // + // "Illumination values higher than 1000 lx show non-linearity. + // This non-linearity is the same for all sensors, so a compensation formula can be applied + // if this light level is exceeded" + auto compensate = [&local_data](float &lux) { + auto calculate_high_lux_compensation = [](float lux_veml) -> float { + return (((6.0135e-13 * lux_veml - 9.3924e-9) * lux_veml + 8.1488e-5) * lux_veml + 1.0023) * lux_veml; + }; + + if (lux > 1000.0f || local_data.actual_gain == Gain::X_1_8 || local_data.actual_gain == Gain::X_1_4) { + lux = calculate_high_lux_compensation(lux); + } + }; + + compensate(data.als_lux); + compensate(data.white_lux); + data.fake_infrared_lux = reduce_to_zero(data.white_lux, data.als_lux); + + ESP_LOGV(TAG, "Lux compensation - ALS = %.1f lx, WHITE = %.1f lx, FAKE_IR = %.1f lx", data.als_lux, data.white_lux, + data.fake_infrared_lux); +} + +void VEML7700Component::apply_glass_attenuation_(Readings &data) { + data.als_lux *= this->glass_attenuation_factor_; + data.white_lux *= this->glass_attenuation_factor_; + data.fake_infrared_lux = reduce_to_zero(data.white_lux, data.als_lux); + ESP_LOGV(TAG, "Glass attenuation - ALS = %.1f lx, WHITE = %.1f lx, FAKE_IR = %.1f lx", data.als_lux, data.white_lux, + data.fake_infrared_lux); +} + +void VEML7700Component::publish_data_part_1_(Readings &data) { + if (this->ambient_light_sensor_ != nullptr) { + this->ambient_light_sensor_->publish_state(data.als_lux); + } + if (this->white_sensor_ != nullptr) { + this->white_sensor_->publish_state(data.white_lux); + } +} + +void VEML7700Component::publish_data_part_2_(Readings &data) { + if (this->fake_infrared_sensor_ != nullptr) { + this->fake_infrared_sensor_->publish_state(data.fake_infrared_lux); + } + if (this->ambient_light_counts_sensor_ != nullptr) { + this->ambient_light_counts_sensor_->publish_state(data.als_counts); + } + if (this->white_counts_sensor_ != nullptr) { + this->white_counts_sensor_->publish_state(data.white_counts); + } +} + +void VEML7700Component::publish_data_part_3_(Readings &data) { + if (this->actual_gain_sensor_ != nullptr) { + this->actual_gain_sensor_->publish_state(get_gain_coeff(data.actual_gain)); + } + if (this->actual_integration_time_sensor_ != nullptr) { + this->actual_integration_time_sensor_->publish_state(get_itime_ms(data.actual_time)); + } +} +} // namespace veml7700 +} // namespace esphome diff --git a/esphome/components/veml7700/veml7700.h b/esphome/components/veml7700/veml7700.h new file mode 100644 index 0000000000..fe5e1158e3 --- /dev/null +++ b/esphome/components/veml7700/veml7700.h @@ -0,0 +1,202 @@ +#pragma once + +#include "esphome/components/i2c/i2c.h" +#include "esphome/components/sensor/sensor.h" +#include "esphome/core/component.h" +#include "esphome/core/optional.h" + +namespace esphome { +namespace veml7700 { + +using esphome::i2c::ErrorCode; + +// +// Datasheet: https://www.vishay.com/docs/84286/veml7700.pdf +// + +enum class CommandRegisters : uint8_t { + ALS_CONF_0 = 0x00, // W: ALS gain, integration time, interrupt, and shutdown + ALS_WH = 0x01, // W: ALS high threshold window setting + ALS_WL = 0x02, // W: ALS low threshold window setting + PWR_SAVING = 0x03, // W: Set (15 : 3) 0000 0000 0000 0b + ALS = 0x04, // R: MSB, LSB data of whole ALS 16 bits + WHITE = 0x05, // R: MSB, LSB data of whole WHITE 16 bits + ALS_INT = 0x06 // R: ALS INT trigger event +}; + +enum Gain : uint8_t { + X_1 = 0, + X_2 = 1, + X_1_8 = 2, + X_1_4 = 3, +}; +const uint8_t GAINS_COUNT = 4; + +enum IntegrationTime : uint8_t { + INTEGRATION_TIME_25MS = 0b1100, + INTEGRATION_TIME_50MS = 0b1000, + INTEGRATION_TIME_100MS = 0b0000, + INTEGRATION_TIME_200MS = 0b0001, + INTEGRATION_TIME_400MS = 0b0010, + INTEGRATION_TIME_800MS = 0b0011, +}; +const uint8_t INTEGRATION_TIMES_COUNT = 6; + +enum Persistence : uint8_t { + PERSISTENCE_1 = 0, + PERSISTENCE_2 = 1, + PERSISTENCE_4 = 2, + PERSISTENCE_8 = 3, +}; + +enum PSM : uint8_t { + PSM_MODE_1 = 0, + PSM_MODE_2 = 1, + PSM_MODE_3 = 2, + PSM_MODE_4 = 3, +}; + +// The following section with bit-fields brings GCC compilation 'notes' about padding bytes due to bug in older GCC back +// in 2009 "Packed bit-fields of type char were not properly bit-packed on many targets prior to GCC 4.4" Even more to +// this - this message can't be disabled with "#pragma GCC diagnostic ignored" due to another bug which was only fixed +// in GCC 13 in 2022 :) No actions required, it is just a note. The code is correct. + +// +// VEML7700_CR_ALS_CONF_0 Register (0x00) +// +union ConfigurationRegister { + uint16_t raw; + uint8_t raw_bytes[2]; + struct { + bool ALS_SD : 1; // ALS shut down setting: 0 = ALS power on, 1 = ALS shut + // down + bool ALS_INT_EN : 1; // ALS interrupt enable setting: 0 = ALS INT disable, 1 + // = ALS INT enable + bool reserved_2 : 1; // 0 + bool reserved_3 : 1; // 0 + Persistence ALS_PERS : 2; // 00 - 1, 01- 2, 10 - 4, 11 - 8 + IntegrationTime ALS_IT : 4; // ALS integration time setting + bool reserved_10 : 1; // 0 + Gain ALS_GAIN : 2; // Gain selection + bool reserved_13 : 1; // 0 + bool reserved_14 : 1; // 0 + bool reserved_15 : 1; // 0 + } __attribute__((packed)); +}; + +// +// Power Saving Mode: PSM Register (0x03) +// +union PSMRegister { + uint16_t raw; + uint8_t raw_bytes[2]; + struct { + bool PSM_EN : 1; + uint8_t PSM : 2; + uint16_t reserved : 13; + } __attribute__((packed)); +}; + +class VEML7700Component : public PollingComponent, public i2c::I2CDevice { + public: + // + // EspHome framework functions + // + float get_setup_priority() const override { return setup_priority::DATA; } + void setup() override; + void dump_config() override; + void update() override; + void loop() override; + + // + // Configuration setters + // + void set_gain(Gain gain) { this->gain_ = gain; } + void set_integration_time(IntegrationTime time) { this->integration_time_ = time; } + void set_enable_automatic_mode(bool enable) { this->automatic_mode_enabled_ = enable; } + void set_enable_lux_compensation(bool enable) { this->lux_compensation_enabled_ = enable; } + void set_glass_attenuation_factor(float factor) { this->glass_attenuation_factor_ = factor; } + + void set_ambient_light_sensor(sensor::Sensor *sensor) { this->ambient_light_sensor_ = sensor; } + void set_ambient_light_counts_sensor(sensor::Sensor *sensor) { this->ambient_light_counts_sensor_ = sensor; } + void set_white_sensor(sensor::Sensor *sensor) { this->white_sensor_ = sensor; } + void set_white_counts_sensor(sensor::Sensor *sensor) { this->white_counts_sensor_ = sensor; } + void set_infrared_sensor(sensor::Sensor *sensor) { this->fake_infrared_sensor_ = sensor; } + void set_actual_gain_sensor(sensor::Sensor *sensor) { this->actual_gain_sensor_ = sensor; } + void set_actual_integration_time_sensor(sensor::Sensor *sensor) { this->actual_integration_time_sensor_ = sensor; } + + protected: + // + // Internal state machine, used to split all the actions into + // small steps in loop() to make sure we are not blocking execution + // + enum class State : uint8_t { + NOT_INITIALIZED, + INITIAL_SETUP_COMPLETED, + IDLE, + COLLECTING_DATA, + COLLECTING_DATA_AUTO, + DATA_COLLECTED, + ADJUSTMENT_NEEDED, + ADJUSTMENT_IN_PROGRESS, + READY_TO_APPLY_ADJUSTMENTS, + READY_TO_PUBLISH_PART_1, + READY_TO_PUBLISH_PART_2, + READY_TO_PUBLISH_PART_3 + } state_{State::NOT_INITIALIZED}; + + // + // Current measurements data + // + struct Readings { + uint16_t als_counts{0}; + uint16_t white_counts{0}; + IntegrationTime actual_time{INTEGRATION_TIME_100MS}; + Gain actual_gain{X_1_8}; + float als_lux{0}; + float white_lux{0}; + float fake_infrared_lux{0}; + ErrorCode err{i2c::ERROR_OK}; + } readings_; + + // + // Device interaction + // + ErrorCode configure_(); + ErrorCode reconfigure_time_and_gain_(IntegrationTime time, Gain gain, bool shutdown); + ErrorCode read_sensor_output_(Readings &data); + + // + // Working with the data + // + bool are_adjustments_required_(Readings &data); + void apply_lux_calculation_(Readings &data); + void apply_lux_compensation_(Readings &data); + void apply_glass_attenuation_(Readings &data); + void publish_data_part_1_(Readings &data); + void publish_data_part_2_(Readings &data); + void publish_data_part_3_(Readings &data); + + // + // Component configuration + // + bool automatic_mode_enabled_{true}; + bool lux_compensation_enabled_{true}; + float glass_attenuation_factor_{1.0}; + IntegrationTime integration_time_{INTEGRATION_TIME_100MS}; + Gain gain_{X_1}; + + // + // Sensors for publishing data + // + sensor::Sensor *ambient_light_sensor_{nullptr}; // Human eye range 500-600 nm, lx + sensor::Sensor *ambient_light_counts_sensor_{nullptr}; // Raw counts + sensor::Sensor *white_sensor_{nullptr}; // Wide range 450-950 nm, lx + sensor::Sensor *white_counts_sensor_{nullptr}; // Raw counts + sensor::Sensor *fake_infrared_sensor_{nullptr}; // Artificial. = WHITE lx - ALS lx. + sensor::Sensor *actual_gain_sensor_{nullptr}; // Actual gain multiplier for the measurement + sensor::Sensor *actual_integration_time_sensor_{nullptr}; // Actual integration time for the measurement +}; + +} // namespace veml7700 +} // namespace esphome diff --git a/tests/components/veml7700/common.yaml b/tests/components/veml7700/common.yaml new file mode 100644 index 0000000000..6620c8d7e1 --- /dev/null +++ b/tests/components/veml7700/common.yaml @@ -0,0 +1,10 @@ +sensor: + - platform: veml7700 + address: 0x10 + i2c_id: i2c_veml7700 + ambient_light: Ambient light + ambient_light_counts: Ambient light counts + full_spectrum: Full spectrum + full_spectrum_counts: Full spectrum counts + actual_integration_time: Actual integration time + actual_gain: Actual gain diff --git a/tests/components/veml7700/test.esp32-c3-idf.yaml b/tests/components/veml7700/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..ce0fa0125b --- /dev/null +++ b/tests/components/veml7700/test.esp32-c3-idf.yaml @@ -0,0 +1,6 @@ +i2c: + - id: i2c_veml7700 + scl: 5 + sda: 4 + +<<: !include common.yaml diff --git a/tests/components/veml7700/test.esp32-c3.yaml b/tests/components/veml7700/test.esp32-c3.yaml new file mode 100644 index 0000000000..ce0fa0125b --- /dev/null +++ b/tests/components/veml7700/test.esp32-c3.yaml @@ -0,0 +1,6 @@ +i2c: + - id: i2c_veml7700 + scl: 5 + sda: 4 + +<<: !include common.yaml diff --git a/tests/components/veml7700/test.esp32-idf.yaml b/tests/components/veml7700/test.esp32-idf.yaml new file mode 100644 index 0000000000..4b812a1392 --- /dev/null +++ b/tests/components/veml7700/test.esp32-idf.yaml @@ -0,0 +1,6 @@ +i2c: + - id: i2c_veml7700 + scl: 16 + sda: 17 + +<<: !include common.yaml diff --git a/tests/components/veml7700/test.esp32.yaml b/tests/components/veml7700/test.esp32.yaml new file mode 100644 index 0000000000..4b812a1392 --- /dev/null +++ b/tests/components/veml7700/test.esp32.yaml @@ -0,0 +1,6 @@ +i2c: + - id: i2c_veml7700 + scl: 16 + sda: 17 + +<<: !include common.yaml diff --git a/tests/components/veml7700/test.esp8266.yaml b/tests/components/veml7700/test.esp8266.yaml new file mode 100644 index 0000000000..ce0fa0125b --- /dev/null +++ b/tests/components/veml7700/test.esp8266.yaml @@ -0,0 +1,6 @@ +i2c: + - id: i2c_veml7700 + scl: 5 + sda: 4 + +<<: !include common.yaml diff --git a/tests/components/veml7700/test.rp2040.yaml b/tests/components/veml7700/test.rp2040.yaml new file mode 100644 index 0000000000..ce0fa0125b --- /dev/null +++ b/tests/components/veml7700/test.rp2040.yaml @@ -0,0 +1,6 @@ +i2c: + - id: i2c_veml7700 + scl: 5 + sda: 4 + +<<: !include common.yaml From 4bbde8357a65c0b2060f459b3b1f6e7bc228e4e2 Mon Sep 17 00:00:00 2001 From: Citric Lee <37475446+limengdu@users.noreply.github.com> Date: Tue, 12 Mar 2024 11:33:40 +0800 Subject: [PATCH 087/189] Add Seeed Studio mmWave Kit MR24HPC1 (#5761) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Co-authored-by: Peter Pan --- CODEOWNERS | 1 + esphome/components/seeed_mr24hpc1/__init__.py | 51 + .../seeed_mr24hpc1/binary_sensor.py | 23 + .../seeed_mr24hpc1/button/__init__.py | 42 + .../button/custom_mode_end_button.cpp | 9 + .../button/custom_mode_end_button.h | 18 + .../seeed_mr24hpc1/button/restart_button.cpp | 9 + .../seeed_mr24hpc1/button/restart_button.h | 18 + .../seeed_mr24hpc1/number/__init__.py | 132 +++ .../number/custom_mode_number.cpp | 12 + .../number/custom_mode_number.h | 18 + .../number/custom_unman_time_number.cpp | 9 + .../number/custom_unman_time_number.h | 18 + .../number/existence_threshold_number.cpp | 9 + .../number/existence_threshold_number.h | 18 + .../number/motion_threshold_number.cpp | 9 + .../number/motion_threshold_number.h | 18 + .../number/motion_trigger_time_number.cpp | 9 + .../number/motion_trigger_time_number.h | 18 + .../number/motiontorest_time_number.cpp | 9 + .../number/motiontorest_time_number.h | 18 + .../number/sensitivity_number.cpp | 9 + .../number/sensitivity_number.h | 18 + .../seeed_mr24hpc1/seeed_mr24hpc1.cpp | 890 ++++++++++++++++++ .../seeed_mr24hpc1/seeed_mr24hpc1.h | 217 +++++ .../seeed_mr24hpc1/seeed_mr24hpc1_constants.h | 173 ++++ .../seeed_mr24hpc1/select/__init__.py | 103 ++ .../select/existence_boundary_select.cpp | 15 + .../select/existence_boundary_select.h | 18 + .../select/motion_boundary_select.cpp | 15 + .../select/motion_boundary_select.h | 18 + .../select/scene_mode_select.cpp | 15 + .../seeed_mr24hpc1/select/scene_mode_select.h | 18 + .../select/unman_time_select.cpp | 15 + .../seeed_mr24hpc1/select/unman_time_select.h | 18 + esphome/components/seeed_mr24hpc1/sensor.py | 82 ++ .../seeed_mr24hpc1/switch/__init__.py | 32 + .../switch/underlyFuc_switch.cpp | 12 + .../seeed_mr24hpc1/switch/underlyFuc_switch.h | 18 + .../components/seeed_mr24hpc1/text_sensor.py | 74 ++ tests/components/seeed_mr24hpc1/common.yaml | 92 ++ .../seeed_mr24hpc1/test.esp32-c3-idf.yaml | 5 + .../seeed_mr24hpc1/test.esp32-c3.yaml | 5 + 43 files changed, 2330 insertions(+) create mode 100644 esphome/components/seeed_mr24hpc1/__init__.py create mode 100644 esphome/components/seeed_mr24hpc1/binary_sensor.py create mode 100644 esphome/components/seeed_mr24hpc1/button/__init__.py create mode 100644 esphome/components/seeed_mr24hpc1/button/custom_mode_end_button.cpp create mode 100644 esphome/components/seeed_mr24hpc1/button/custom_mode_end_button.h create mode 100644 esphome/components/seeed_mr24hpc1/button/restart_button.cpp create mode 100644 esphome/components/seeed_mr24hpc1/button/restart_button.h create mode 100644 esphome/components/seeed_mr24hpc1/number/__init__.py create mode 100644 esphome/components/seeed_mr24hpc1/number/custom_mode_number.cpp create mode 100644 esphome/components/seeed_mr24hpc1/number/custom_mode_number.h create mode 100644 esphome/components/seeed_mr24hpc1/number/custom_unman_time_number.cpp create mode 100644 esphome/components/seeed_mr24hpc1/number/custom_unman_time_number.h create mode 100644 esphome/components/seeed_mr24hpc1/number/existence_threshold_number.cpp create mode 100644 esphome/components/seeed_mr24hpc1/number/existence_threshold_number.h create mode 100644 esphome/components/seeed_mr24hpc1/number/motion_threshold_number.cpp create mode 100644 esphome/components/seeed_mr24hpc1/number/motion_threshold_number.h create mode 100644 esphome/components/seeed_mr24hpc1/number/motion_trigger_time_number.cpp create mode 100644 esphome/components/seeed_mr24hpc1/number/motion_trigger_time_number.h create mode 100644 esphome/components/seeed_mr24hpc1/number/motiontorest_time_number.cpp create mode 100644 esphome/components/seeed_mr24hpc1/number/motiontorest_time_number.h create mode 100644 esphome/components/seeed_mr24hpc1/number/sensitivity_number.cpp create mode 100644 esphome/components/seeed_mr24hpc1/number/sensitivity_number.h create mode 100644 esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp create mode 100644 esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.h create mode 100644 esphome/components/seeed_mr24hpc1/seeed_mr24hpc1_constants.h create mode 100644 esphome/components/seeed_mr24hpc1/select/__init__.py create mode 100644 esphome/components/seeed_mr24hpc1/select/existence_boundary_select.cpp create mode 100644 esphome/components/seeed_mr24hpc1/select/existence_boundary_select.h create mode 100644 esphome/components/seeed_mr24hpc1/select/motion_boundary_select.cpp create mode 100644 esphome/components/seeed_mr24hpc1/select/motion_boundary_select.h create mode 100644 esphome/components/seeed_mr24hpc1/select/scene_mode_select.cpp create mode 100644 esphome/components/seeed_mr24hpc1/select/scene_mode_select.h create mode 100644 esphome/components/seeed_mr24hpc1/select/unman_time_select.cpp create mode 100644 esphome/components/seeed_mr24hpc1/select/unman_time_select.h create mode 100644 esphome/components/seeed_mr24hpc1/sensor.py create mode 100644 esphome/components/seeed_mr24hpc1/switch/__init__.py create mode 100644 esphome/components/seeed_mr24hpc1/switch/underlyFuc_switch.cpp create mode 100644 esphome/components/seeed_mr24hpc1/switch/underlyFuc_switch.h create mode 100644 esphome/components/seeed_mr24hpc1/text_sensor.py create mode 100644 tests/components/seeed_mr24hpc1/common.yaml create mode 100644 tests/components/seeed_mr24hpc1/test.esp32-c3-idf.yaml create mode 100644 tests/components/seeed_mr24hpc1/test.esp32-c3.yaml diff --git a/CODEOWNERS b/CODEOWNERS index e31dd16077..64005b1a81 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -290,6 +290,7 @@ esphome/components/scd4x/* @martgras @sjtrny esphome/components/script/* @esphome/core esphome/components/sdm_meter/* @jesserockz @polyfaces esphome/components/sdp3x/* @Azimath +esphome/components/seeed_mr24hpc1/* @limengdu esphome/components/selec_meter/* @sourabhjaiswal esphome/components/select/* @esphome/core esphome/components/sen0321/* @notjj diff --git a/esphome/components/seeed_mr24hpc1/__init__.py b/esphome/components/seeed_mr24hpc1/__init__.py new file mode 100644 index 0000000000..52b971e7e4 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/__init__.py @@ -0,0 +1,51 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import uart +from esphome.const import CONF_ID + +DEPENDENCIES = ["uart"] +# is the code owner of the relevant code base +CODEOWNERS = ["@limengdu"] +# The current component or platform can be configured or defined multiple times in the same configuration file. +MULTI_CONF = True + +# This line of code creates a new namespace called mr24hpc1_ns. +# This namespace will be used as a prefix for all classes, functions and variables associated with the mr24hpc1_ns component, ensuring that they do not conflict with the names of other components. +mr24hpc1_ns = cg.esphome_ns.namespace("seeed_mr24hpc1") +# This MR24HPC1Component class will be a periodically polled UART device +MR24HPC1Component = mr24hpc1_ns.class_( + "MR24HPC1Component", cg.Component, uart.UARTDevice +) + +CONF_MR24HPC1_ID = "mr24hpc1_id" + +CONFIG_SCHEMA = ( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(MR24HPC1Component), + } + ) + .extend(uart.UART_DEVICE_SCHEMA) + .extend(cv.COMPONENT_SCHEMA) +) + +# A verification mode was created to verify the configuration parameters of a UART device named "seeed_mr24hpc1". +# This authentication mode requires that the device must have transmit and receive functionality, a parity mode of "NONE", and a stop bit of one. +FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema( + "seeed_mr24hpc1", + require_tx=True, + require_rx=True, + parity="NONE", + stop_bits=1, +) + + +# The async def keyword is used to define a concurrent function. +# Concurrent functions are special functions designed to work with Python's asyncio library to support asynchronous I/O operations. +async def to_code(config): + # This line of code creates a new Pvariable (a Python object representing a C++ variable) with the variable's ID taken from the configuration. + var = cg.new_Pvariable(config[CONF_ID]) + # This line of code registers the newly created Pvariable as a component so that ESPHome can manage it at runtime. + await cg.register_component(var, config) + # This line of code registers the newly created Pvariable as a device. + await uart.register_uart_device(var, config) diff --git a/esphome/components/seeed_mr24hpc1/binary_sensor.py b/esphome/components/seeed_mr24hpc1/binary_sensor.py new file mode 100644 index 0000000000..e3e54d03f9 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/binary_sensor.py @@ -0,0 +1,23 @@ +import esphome.codegen as cg +from esphome.components import binary_sensor +import esphome.config_validation as cv +from esphome.const import ( + DEVICE_CLASS_OCCUPANCY, +) +from . import CONF_MR24HPC1_ID, MR24HPC1Component + +CONF_HAS_TARGET = "has_target" + +CONFIG_SCHEMA = { + cv.GenerateID(CONF_MR24HPC1_ID): cv.use_id(MR24HPC1Component), + cv.Optional(CONF_HAS_TARGET): binary_sensor.binary_sensor_schema( + device_class=DEVICE_CLASS_OCCUPANCY, icon="mdi:motion-sensor" + ), +} + + +async def to_code(config): + mr24hpc1_component = await cg.get_variable(config[CONF_MR24HPC1_ID]) + if has_target_config := config.get(CONF_HAS_TARGET): + sens = await binary_sensor.new_binary_sensor(has_target_config) + cg.add(mr24hpc1_component.set_has_target_binary_sensor(sens)) diff --git a/esphome/components/seeed_mr24hpc1/button/__init__.py b/esphome/components/seeed_mr24hpc1/button/__init__.py new file mode 100644 index 0000000000..0a0e7a1865 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/button/__init__.py @@ -0,0 +1,42 @@ +import esphome.codegen as cg +from esphome.components import button +import esphome.config_validation as cv +from esphome.const import ( + DEVICE_CLASS_RESTART, + ENTITY_CATEGORY_CONFIG, + ICON_RESTART_ALERT, +) +from .. import CONF_MR24HPC1_ID, MR24HPC1Component, mr24hpc1_ns + +RestartButton = mr24hpc1_ns.class_("RestartButton", button.Button) +CustomSetEndButton = mr24hpc1_ns.class_("CustomSetEndButton", button.Button) + +CONF_RESTART = "restart" +CONF_CUSTOM_SET_END = "custom_set_end" + +CONFIG_SCHEMA = { + cv.GenerateID(CONF_MR24HPC1_ID): cv.use_id(MR24HPC1Component), + cv.Optional(CONF_RESTART): button.button_schema( + RestartButton, + device_class=DEVICE_CLASS_RESTART, + entity_category=ENTITY_CATEGORY_CONFIG, + icon=ICON_RESTART_ALERT, + ), + cv.Optional(CONF_CUSTOM_SET_END): button.button_schema( + CustomSetEndButton, + entity_category=ENTITY_CATEGORY_CONFIG, + icon="mdi:cog", + ), +} + + +async def to_code(config): + mr24hpc1_component = await cg.get_variable(config[CONF_MR24HPC1_ID]) + if restart_config := config.get(CONF_RESTART): + b = await button.new_button(restart_config) + await cg.register_parented(b, config[CONF_MR24HPC1_ID]) + cg.add(mr24hpc1_component.set_restart_button(b)) + if custom_set_end_config := config.get(CONF_CUSTOM_SET_END): + b = await button.new_button(custom_set_end_config) + await cg.register_parented(b, config[CONF_MR24HPC1_ID]) + cg.add(mr24hpc1_component.set_custom_set_end_button(b)) diff --git a/esphome/components/seeed_mr24hpc1/button/custom_mode_end_button.cpp b/esphome/components/seeed_mr24hpc1/button/custom_mode_end_button.cpp new file mode 100644 index 0000000000..0ae8889247 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/button/custom_mode_end_button.cpp @@ -0,0 +1,9 @@ +#include "custom_mode_end_button.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void CustomSetEndButton::press_action() { this->parent_->set_custom_end_mode(); } + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/button/custom_mode_end_button.h b/esphome/components/seeed_mr24hpc1/button/custom_mode_end_button.h new file mode 100644 index 0000000000..a1701d8581 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/button/custom_mode_end_button.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/button/button.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class CustomSetEndButton : public button::Button, public Parented { + public: + CustomSetEndButton() = default; + + protected: + void press_action() override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/button/restart_button.cpp b/esphome/components/seeed_mr24hpc1/button/restart_button.cpp new file mode 100644 index 0000000000..6c4a070d1c --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/button/restart_button.cpp @@ -0,0 +1,9 @@ +#include "restart_button.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void RestartButton::press_action() { this->parent_->set_restart(); } + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/button/restart_button.h b/esphome/components/seeed_mr24hpc1/button/restart_button.h new file mode 100644 index 0000000000..8a2ec2087c --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/button/restart_button.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/button/button.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class RestartButton : public button::Button, public Parented { + public: + RestartButton() = default; + + protected: + void press_action() override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/__init__.py b/esphome/components/seeed_mr24hpc1/number/__init__.py new file mode 100644 index 0000000000..d9dfcb19a5 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/__init__.py @@ -0,0 +1,132 @@ +import esphome.codegen as cg +from esphome.components import number +import esphome.config_validation as cv +from esphome.const import ( + ENTITY_CATEGORY_CONFIG, +) +from .. import CONF_MR24HPC1_ID, MR24HPC1Component, mr24hpc1_ns + +SensitivityNumber = mr24hpc1_ns.class_("SensitivityNumber", number.Number) +CustomModeNumber = mr24hpc1_ns.class_("CustomModeNumber", number.Number) +ExistenceThresholdNumber = mr24hpc1_ns.class_("ExistenceThresholdNumber", number.Number) +MotionThresholdNumber = mr24hpc1_ns.class_("MotionThresholdNumber", number.Number) +MotionTriggerTimeNumber = mr24hpc1_ns.class_("MotionTriggerTimeNumber", number.Number) +MotionToRestTimeNumber = mr24hpc1_ns.class_("MotionToRestTimeNumber", number.Number) +CustomUnmanTimeNumber = mr24hpc1_ns.class_("CustomUnmanTimeNumber", number.Number) + +CONF_SENSITIVITY = "sensitivity" +CONF_CUSTOM_MODE = "custom_mode" +CONF_EXISTENCE_THRESHOLD = "existence_threshold" +CONF_MOTION_THRESHOLD = "motion_threshold" +CONF_MOTION_TRIGGER = "motion_trigger" +CONF_MOTION_TO_REST = "motion_to_rest" +CONF_CUSTOM_UNMAN_TIME = "custom_unman_time" + +CONFIG_SCHEMA = cv.Schema( + { + cv.GenerateID(CONF_MR24HPC1_ID): cv.use_id(MR24HPC1Component), + cv.Optional(CONF_SENSITIVITY): number.number_schema( + SensitivityNumber, + entity_category=ENTITY_CATEGORY_CONFIG, + icon="mdi:archive-check-outline", + ), + cv.Optional(CONF_CUSTOM_MODE): number.number_schema( + CustomModeNumber, + entity_category=ENTITY_CATEGORY_CONFIG, + icon="mdi:cog", + ), + cv.Optional(CONF_EXISTENCE_THRESHOLD): number.number_schema( + ExistenceThresholdNumber, + entity_category=ENTITY_CATEGORY_CONFIG, + ), + cv.Optional(CONF_MOTION_THRESHOLD): number.number_schema( + MotionThresholdNumber, + entity_category=ENTITY_CATEGORY_CONFIG, + ), + cv.Optional(CONF_MOTION_TRIGGER): number.number_schema( + MotionTriggerTimeNumber, + entity_category=ENTITY_CATEGORY_CONFIG, + icon="mdi:camera-timer", + unit_of_measurement="ms", + ), + cv.Optional(CONF_MOTION_TO_REST): number.number_schema( + MotionToRestTimeNumber, + entity_category=ENTITY_CATEGORY_CONFIG, + icon="mdi:camera-timer", + unit_of_measurement="ms", + ), + cv.Optional(CONF_CUSTOM_UNMAN_TIME): number.number_schema( + CustomUnmanTimeNumber, + entity_category=ENTITY_CATEGORY_CONFIG, + icon="mdi:camera-timer", + unit_of_measurement="s", + ), + } +) + + +async def to_code(config): + mr24hpc1_component = await cg.get_variable(config[CONF_MR24HPC1_ID]) + if sensitivity_config := config.get(CONF_SENSITIVITY): + n = await number.new_number( + sensitivity_config, + min_value=0, + max_value=3, + step=1, + ) + await cg.register_parented(n, mr24hpc1_component) + cg.add(mr24hpc1_component.set_sensitivity_number(n)) + if custom_mode_config := config.get(CONF_CUSTOM_MODE): + n = await number.new_number( + custom_mode_config, + min_value=0, + max_value=4, + step=1, + ) + await cg.register_parented(n, mr24hpc1_component) + cg.add(mr24hpc1_component.set_custom_mode_number(n)) + if existence_threshold_config := config.get(CONF_EXISTENCE_THRESHOLD): + n = await number.new_number( + existence_threshold_config, + min_value=0, + max_value=250, + step=1, + ) + await cg.register_parented(n, mr24hpc1_component) + cg.add(mr24hpc1_component.set_existence_threshold_number(n)) + if motion_threshold_config := config.get(CONF_MOTION_THRESHOLD): + n = await number.new_number( + motion_threshold_config, + min_value=0, + max_value=250, + step=1, + ) + await cg.register_parented(n, mr24hpc1_component) + cg.add(mr24hpc1_component.set_motion_threshold_number(n)) + if motion_trigger_config := config.get(CONF_MOTION_TRIGGER): + n = await number.new_number( + motion_trigger_config, + min_value=0, + max_value=150, + step=1, + ) + await cg.register_parented(n, mr24hpc1_component) + cg.add(mr24hpc1_component.set_motion_trigger_number(n)) + if motion_to_rest_config := config.get(CONF_MOTION_TO_REST): + n = await number.new_number( + motion_to_rest_config, + min_value=0, + max_value=3000, + step=1, + ) + await cg.register_parented(n, mr24hpc1_component) + cg.add(mr24hpc1_component.set_motion_to_rest_number(n)) + if custom_unman_time_config := config.get(CONF_CUSTOM_UNMAN_TIME): + n = await number.new_number( + custom_unman_time_config, + min_value=0, + max_value=3600, + step=1, + ) + await cg.register_parented(n, mr24hpc1_component) + cg.add(mr24hpc1_component.set_custom_unman_time_number(n)) diff --git a/esphome/components/seeed_mr24hpc1/number/custom_mode_number.cpp b/esphome/components/seeed_mr24hpc1/number/custom_mode_number.cpp new file mode 100644 index 0000000000..0aebd8fb9f --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/custom_mode_number.cpp @@ -0,0 +1,12 @@ +#include "custom_mode_number.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void CustomModeNumber::control(float value) { + this->publish_state(value); + this->parent_->set_custom_mode(value); +} + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/custom_mode_number.h b/esphome/components/seeed_mr24hpc1/number/custom_mode_number.h new file mode 100644 index 0000000000..40ff3f201a --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/custom_mode_number.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/number/number.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class CustomModeNumber : public number::Number, public Parented { + public: + CustomModeNumber() = default; + + protected: + void control(float value) override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/custom_unman_time_number.cpp b/esphome/components/seeed_mr24hpc1/number/custom_unman_time_number.cpp new file mode 100644 index 0000000000..12a8ff69fa --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/custom_unman_time_number.cpp @@ -0,0 +1,9 @@ +#include "custom_unman_time_number.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void CustomUnmanTimeNumber::control(float value) { this->parent_->set_custom_unman_time(value); } + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/custom_unman_time_number.h b/esphome/components/seeed_mr24hpc1/number/custom_unman_time_number.h new file mode 100644 index 0000000000..6b871c4c13 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/custom_unman_time_number.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/number/number.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class CustomUnmanTimeNumber : public number::Number, public Parented { + public: + CustomUnmanTimeNumber() = default; + + protected: + void control(float value) override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/existence_threshold_number.cpp b/esphome/components/seeed_mr24hpc1/number/existence_threshold_number.cpp new file mode 100644 index 0000000000..58ef56509e --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/existence_threshold_number.cpp @@ -0,0 +1,9 @@ +#include "existence_threshold_number.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void ExistenceThresholdNumber::control(float value) { this->parent_->set_existence_threshold(value); } + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/existence_threshold_number.h b/esphome/components/seeed_mr24hpc1/number/existence_threshold_number.h new file mode 100644 index 0000000000..656bad17de --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/existence_threshold_number.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/number/number.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class ExistenceThresholdNumber : public number::Number, public Parented { + public: + ExistenceThresholdNumber() = default; + + protected: + void control(float value) override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/motion_threshold_number.cpp b/esphome/components/seeed_mr24hpc1/number/motion_threshold_number.cpp new file mode 100644 index 0000000000..d252b4f01d --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/motion_threshold_number.cpp @@ -0,0 +1,9 @@ +#include "motion_threshold_number.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void MotionThresholdNumber::control(float value) { this->parent_->set_motion_threshold(value); } + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/motion_threshold_number.h b/esphome/components/seeed_mr24hpc1/number/motion_threshold_number.h new file mode 100644 index 0000000000..e8ae37b96f --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/motion_threshold_number.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/number/number.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class MotionThresholdNumber : public number::Number, public Parented { + public: + MotionThresholdNumber() = default; + + protected: + void control(float value) override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/motion_trigger_time_number.cpp b/esphome/components/seeed_mr24hpc1/number/motion_trigger_time_number.cpp new file mode 100644 index 0000000000..fc7659dc54 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/motion_trigger_time_number.cpp @@ -0,0 +1,9 @@ +#include "motion_trigger_time_number.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void MotionTriggerTimeNumber::control(float value) { this->parent_->set_motion_trigger_time(value); } + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/motion_trigger_time_number.h b/esphome/components/seeed_mr24hpc1/number/motion_trigger_time_number.h new file mode 100644 index 0000000000..996356e237 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/motion_trigger_time_number.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/number/number.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class MotionTriggerTimeNumber : public number::Number, public Parented { + public: + MotionTriggerTimeNumber() = default; + + protected: + void control(float value) override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/motiontorest_time_number.cpp b/esphome/components/seeed_mr24hpc1/number/motiontorest_time_number.cpp new file mode 100644 index 0000000000..f598e6686c --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/motiontorest_time_number.cpp @@ -0,0 +1,9 @@ +#include "motiontorest_time_number.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void MotionToRestTimeNumber::control(float value) { this->parent_->set_motion_to_rest_time(value); } + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/motiontorest_time_number.h b/esphome/components/seeed_mr24hpc1/number/motiontorest_time_number.h new file mode 100644 index 0000000000..559d23fdeb --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/motiontorest_time_number.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/number/number.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class MotionToRestTimeNumber : public number::Number, public Parented { + public: + MotionToRestTimeNumber() = default; + + protected: + void control(float value) override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/sensitivity_number.cpp b/esphome/components/seeed_mr24hpc1/number/sensitivity_number.cpp new file mode 100644 index 0000000000..d903dfd818 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/sensitivity_number.cpp @@ -0,0 +1,9 @@ +#include "sensitivity_number.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void SensitivityNumber::control(float value) { this->parent_->set_sensitivity(value); } + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/number/sensitivity_number.h b/esphome/components/seeed_mr24hpc1/number/sensitivity_number.h new file mode 100644 index 0000000000..fee33521d0 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/number/sensitivity_number.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/number/number.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class SensitivityNumber : public number::Number, public Parented { + public: + SensitivityNumber() = default; + + protected: + void control(float value) override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp b/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp new file mode 100644 index 0000000000..1cf9bd300a --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp @@ -0,0 +1,890 @@ +#include "seeed_mr24hpc1.h" + +#include "esphome/core/log.h" + +#include + +namespace esphome { +namespace seeed_mr24hpc1 { + +static const char *const TAG = "seeed_mr24hpc1"; + +// Prints the component's configuration data. dump_config() prints all of the component's configuration +// items in an easy-to-read format, including the configuration key-value pairs. +void MR24HPC1Component::dump_config() { + ESP_LOGCONFIG(TAG, "MR24HPC1:"); +#ifdef USE_TEXT_SENSOR + LOG_TEXT_SENSOR(" ", "Heartbeat Text Sensor", this->heartbeat_state_text_sensor_); + LOG_TEXT_SENSOR(" ", "Product Model Text Sensor", this->product_model_text_sensor_); + LOG_TEXT_SENSOR(" ", "Product ID Text Sensor", this->product_id_text_sensor_); + LOG_TEXT_SENSOR(" ", "Hardware Model Text Sensor", this->hardware_model_text_sensor_); + LOG_TEXT_SENSOR(" ", "Firware Verison Text Sensor", this->firware_version_text_sensor_); + LOG_TEXT_SENSOR(" ", "Keep Away Text Sensor", this->keep_away_text_sensor_); + LOG_TEXT_SENSOR(" ", "Motion Status Text Sensor", this->motion_status_text_sensor_); + LOG_TEXT_SENSOR(" ", "Custom Mode End Text Sensor", this->custom_mode_end_text_sensor_); +#endif +#ifdef USE_BINARY_SENSOR + LOG_BINARY_SENSOR(" ", "Has Target Binary Sensor", this->has_target_binary_sensor_); +#endif +#ifdef USE_SENSOR + LOG_SENSOR(" ", "Custom Presence Of Detection Sensor", this->custom_presence_of_detection_sensor_); + LOG_SENSOR(" ", "Movement Signs Sensor", this->movement_signs_sensor_); + LOG_SENSOR(" ", "Custom Motion Distance Sensor", this->custom_motion_distance_sensor_); + LOG_SENSOR(" ", "Custom Spatial Static Sensor", this->custom_spatial_static_value_sensor_); + LOG_SENSOR(" ", "Custom Spatial Motion Sensor", this->custom_spatial_motion_value_sensor_); + LOG_SENSOR(" ", "Custom Motion Speed Sensor", this->custom_motion_speed_sensor_); + LOG_SENSOR(" ", "Custom Mode Num Sensor", this->custom_mode_num_sensor_); +#endif +#ifdef USE_SWITCH + LOG_SWITCH(" ", "Underly Open Function Switch", this->underlying_open_function_switch_); +#endif +#ifdef USE_BUTTON + LOG_BUTTON(" ", "Restart Button", this->restart_button_); + LOG_BUTTON(" ", "Custom Set End Button", this->custom_set_end_button_); +#endif +#ifdef USE_SELECT + LOG_SELECT(" ", "Scene Mode Select", this->scene_mode_select_); + LOG_SELECT(" ", "Unman Time Select", this->unman_time_select_); + LOG_SELECT(" ", "Existence Boundary Select", this->existence_boundary_select_); + LOG_SELECT(" ", "Motion Boundary Select", this->motion_boundary_select_); +#endif +#ifdef USE_NUMBER + LOG_NUMBER(" ", "Sensitivity Number", this->sensitivity_number_); + LOG_NUMBER(" ", "Custom Mode Number", this->custom_mode_number_); + LOG_NUMBER(" ", "Existence Threshold Number", this->existence_threshold_number_); + LOG_NUMBER(" ", "Motion Threshold Number", this->motion_threshold_number_); + LOG_NUMBER(" ", "Motion Trigger Time Number", this->motion_trigger_number_); + LOG_NUMBER(" ", "Motion To Rest Time Number", this->motion_to_rest_number_); + LOG_NUMBER(" ", "Custom Unman Time Number", this->custom_unman_time_number_); +#endif +} + +// Initialisation functions +void MR24HPC1Component::setup() { + ESP_LOGCONFIG(TAG, "Setting up MR24HPC1..."); + this->check_uart_settings(115200); + + if (this->custom_mode_number_ != nullptr) { + this->custom_mode_number_->publish_state(0); // Zero out the custom mode + } + if (this->custom_mode_num_sensor_ != nullptr) { + this->custom_mode_num_sensor_->publish_state(0); + } + if (this->custom_mode_end_text_sensor_ != nullptr) { + this->custom_mode_end_text_sensor_->publish_state("Not in custom mode"); + } + this->set_custom_end_mode(); + this->poll_time_base_func_check_ = true; + this->check_dev_inf_sign_ = true; + this->sg_start_query_data_ = STANDARD_FUNCTION_QUERY_PRODUCT_MODE; + this->sg_data_len_ = 0; + this->sg_frame_len_ = 0; + this->sg_recv_data_state_ = FRAME_IDLE; + this->s_output_info_switch_flag_ = OUTPUT_SWITCH_INIT; + + memset(this->c_product_mode_, 0, PRODUCT_BUF_MAX_SIZE); + memset(this->c_product_id_, 0, PRODUCT_BUF_MAX_SIZE); + memset(this->c_firmware_version_, 0, PRODUCT_BUF_MAX_SIZE); + memset(this->c_hardware_model_, 0, PRODUCT_BUF_MAX_SIZE); + memset(this->sg_frame_prase_buf_, 0, FRAME_BUF_MAX_SIZE); + memset(this->sg_frame_buf_, 0, FRAME_BUF_MAX_SIZE); + + this->set_interval(8000, [this]() { this->update_(); }); + ESP_LOGCONFIG(TAG, "Set up MR24HPC1 complete"); +} + +// Timed polling of radar data +void MR24HPC1Component::update_() { + this->get_radar_output_information_switch(); // Query the key status every so often + this->poll_time_base_func_check_ = true; // Query the base functionality information at regular intervals +} + +// main loop +void MR24HPC1Component::loop() { + uint8_t byte; + + // Is there data on the serial port + while (this->available()) { + this->read_byte(&byte); + this->r24_split_data_frame_(byte); // split data frame + } + + if ((this->s_output_info_switch_flag_ == OUTPUT_SWTICH_OFF) && + (this->sg_start_query_data_ > CUSTOM_FUNCTION_QUERY_TIME_OF_ENTER_UNMANNED) && (!this->check_dev_inf_sign_)) { + this->sg_start_query_data_ = STANDARD_FUNCTION_QUERY_SCENE_MODE; + } else if ((this->s_output_info_switch_flag_ == OUTPUT_SWITCH_ON) && + (this->sg_start_query_data_ < CUSTOM_FUNCTION_QUERY_EXISTENCE_BOUNDARY) && (!this->check_dev_inf_sign_)) { + this->sg_start_query_data_ = CUSTOM_FUNCTION_QUERY_EXISTENCE_BOUNDARY; + } else if (this->check_dev_inf_sign_ && (this->sg_start_query_data_ > STANDARD_FUNCTION_QUERY_HARDWARE_MODE)) { + // First time power up information polling + this->sg_start_query_data_ = STANDARD_FUNCTION_QUERY_PRODUCT_MODE; + } + + // Polling Functions + if (this->poll_time_base_func_check_) { + switch (this->sg_start_query_data_) { + case STANDARD_FUNCTION_QUERY_PRODUCT_MODE: + this->get_product_mode(); + this->sg_start_query_data_++; + break; + case STANDARD_FUNCTION_QUERY_PRODUCT_ID: + this->get_product_id(); + this->sg_start_query_data_++; + break; + case STANDARD_FUNCTION_QUERY_FIRMWARE_VERSION: + this->get_product_mode(); + this->get_product_id(); + this->get_firmware_version(); + this->sg_start_query_data_++; + break; + case STANDARD_FUNCTION_QUERY_HARDWARE_MODE: // Above is the equipment information + this->get_product_mode(); + this->get_product_id(); + this->get_hardware_model(); + this->sg_start_query_data_++; + this->check_dev_inf_sign_ = false; + break; + case STANDARD_FUNCTION_QUERY_SCENE_MODE: + this->get_scene_mode(); + this->sg_start_query_data_++; + break; + case STANDARD_FUNCTION_QUERY_SENSITIVITY: + this->get_sensitivity(); + this->sg_start_query_data_++; + break; + case STANDARD_FUNCTION_QUERY_UNMANNED_TIME: + this->get_unmanned_time(); + this->sg_start_query_data_++; + break; + case STANDARD_FUNCTION_QUERY_HUMAN_STATUS: + this->get_human_status(); + this->sg_start_query_data_++; + break; + case STANDARD_FUNCTION_QUERY_HUMAN_MOTION_INF: + this->get_human_motion_info(); + this->sg_start_query_data_++; + break; + case STANDARD_FUNCTION_QUERY_BODY_MOVE_PARAMETER: + this->get_body_motion_params(); + this->sg_start_query_data_++; + break; + case STANDARD_FUNCTION_QUERY_KEEPAWAY_STATUS: // The above is the basic functional information + this->get_keep_away(); + this->sg_start_query_data_++; + break; + case STANDARD_QUERY_CUSTOM_MODE: + this->get_custom_mode(); + this->sg_start_query_data_++; + break; + case STANDARD_FUNCTION_QUERY_HEARTBEAT_STATE: + this->get_heartbeat_packet(); + this->sg_start_query_data_++; + break; + case CUSTOM_FUNCTION_QUERY_EXISTENCE_BOUNDARY: + this->get_existence_boundary(); + this->sg_start_query_data_++; + break; + case CUSTOM_FUNCTION_QUERY_MOTION_BOUNDARY: + this->get_motion_boundary(); + this->sg_start_query_data_++; + break; + case CUSTOM_FUNCTION_QUERY_EXISTENCE_THRESHOLD: + this->get_existence_threshold(); + this->sg_start_query_data_++; + break; + case CUSTOM_FUNCTION_QUERY_MOTION_THRESHOLD: + this->get_motion_threshold(); + this->sg_start_query_data_++; + break; + case CUSTOM_FUNCTION_QUERY_MOTION_TRIGGER_TIME: + this->get_motion_trigger_time(); + this->sg_start_query_data_++; + break; + case CUSTOM_FUNCTION_QUERY_MOTION_TO_REST_TIME: + this->get_motion_to_rest_time(); + this->sg_start_query_data_++; + break; + case CUSTOM_FUNCTION_QUERY_TIME_OF_ENTER_UNMANNED: + this->get_custom_unman_time(); + this->sg_start_query_data_++; + if (this->s_output_info_switch_flag_ == OUTPUT_SWTICH_OFF) { + this->poll_time_base_func_check_ = false; // Avoiding high-speed polling that can cause the device to jam + } + break; + case UNDERLY_FUNCTION_QUERY_HUMAN_STATUS: + this->get_human_status(); + this->sg_start_query_data_++; + break; + case UNDERLY_FUNCTION_QUERY_SPATIAL_STATIC_VALUE: + this->get_spatial_static_value(); + this->sg_start_query_data_++; + break; + case UNDERLY_FUNCTION_QUERY_SPATIAL_MOTION_VALUE: + this->get_spatial_motion_value(); + this->sg_start_query_data_++; + break; + case UNDERLY_FUNCTION_QUERY_DISTANCE_OF_STATIC_OBJECT: + this->get_distance_of_static_object(); + this->sg_start_query_data_++; + break; + case UNDERLY_FUNCTION_QUERY_DISTANCE_OF_MOVING_OBJECT: + this->get_distance_of_moving_object(); + this->sg_start_query_data_++; + break; + case UNDERLY_FUNCTION_QUERY_TARGET_MOVEMENT_SPEED: + this->get_target_movement_speed(); + this->sg_start_query_data_++; + this->poll_time_base_func_check_ = false; // Avoiding high-speed polling that can cause the device to jam + break; + default: + break; + } + } +} + +// Calculate CRC check digit +static uint8_t get_frame_crc_sum(const uint8_t *data, int len) { + unsigned int crc_sum = 0; + for (int i = 0; i < len - 3; i++) { + crc_sum += data[i]; + } + return crc_sum & 0xff; +} + +// Check that the check digit is correct +static int get_frame_check_status(uint8_t *data, int len) { + uint8_t crc_sum = get_frame_crc_sum(data, len); + uint8_t verified = data[len - 3]; + return (verified == crc_sum) ? 1 : 0; +} + +// split data frame +void MR24HPC1Component::r24_split_data_frame_(uint8_t value) { + switch (this->sg_recv_data_state_) { + case FRAME_IDLE: // starting value + if (FRAME_HEADER1_VALUE == value) { + this->sg_recv_data_state_ = FRAME_HEADER2; + } + break; + case FRAME_HEADER2: + if (FRAME_HEADER2_VALUE == value) { + this->sg_frame_buf_[0] = FRAME_HEADER1_VALUE; + this->sg_frame_buf_[1] = FRAME_HEADER2_VALUE; + this->sg_recv_data_state_ = FRAME_CTL_WORD; + } else { + this->sg_recv_data_state_ = FRAME_IDLE; + ESP_LOGD(TAG, "FRAME_IDLE ERROR value:%x", value); + } + break; + case FRAME_CTL_WORD: + this->sg_frame_buf_[2] = value; + this->sg_recv_data_state_ = FRAME_CMD_WORD; + break; + case FRAME_CMD_WORD: + this->sg_frame_buf_[3] = value; + this->sg_recv_data_state_ = FRAME_DATA_LEN_H; + break; + case FRAME_DATA_LEN_H: + if (value <= 4) { + this->sg_data_len_ = value * 256; + this->sg_frame_buf_[4] = value; + this->sg_recv_data_state_ = FRAME_DATA_LEN_L; + } else { + this->sg_data_len_ = 0; + this->sg_recv_data_state_ = FRAME_IDLE; + ESP_LOGD(TAG, "FRAME_DATA_LEN_H ERROR value:%x", value); + } + break; + case FRAME_DATA_LEN_L: + this->sg_data_len_ += value; + if (this->sg_data_len_ > 32) { + ESP_LOGD(TAG, "len=%d, FRAME_DATA_LEN_L ERROR value:%x", this->sg_data_len_, value); + this->sg_data_len_ = 0; + this->sg_recv_data_state_ = FRAME_IDLE; + } else { + this->sg_frame_buf_[5] = value; + this->sg_frame_len_ = 6; + this->sg_recv_data_state_ = FRAME_DATA_BYTES; + } + break; + case FRAME_DATA_BYTES: + this->sg_data_len_ -= 1; + this->sg_frame_buf_[this->sg_frame_len_++] = value; + if (this->sg_data_len_ <= 0) { + this->sg_recv_data_state_ = FRAME_DATA_CRC; + } + break; + case FRAME_DATA_CRC: + this->sg_frame_buf_[this->sg_frame_len_++] = value; + this->sg_recv_data_state_ = FRAME_TAIL1; + break; + case FRAME_TAIL1: + if (FRAME_TAIL1_VALUE == value) { + this->sg_recv_data_state_ = FRAME_TAIL2; + } else { + this->sg_recv_data_state_ = FRAME_IDLE; + this->sg_frame_len_ = 0; + this->sg_data_len_ = 0; + ESP_LOGD(TAG, "FRAME_TAIL1 ERROR value:%x", value); + } + break; + case FRAME_TAIL2: + if (FRAME_TAIL2_VALUE == value) { + this->sg_frame_buf_[this->sg_frame_len_++] = FRAME_TAIL1_VALUE; + this->sg_frame_buf_[this->sg_frame_len_++] = FRAME_TAIL2_VALUE; + memcpy(this->sg_frame_prase_buf_, this->sg_frame_buf_, this->sg_frame_len_); + if (get_frame_check_status(this->sg_frame_prase_buf_, this->sg_frame_len_)) { + this->r24_parse_data_frame_(this->sg_frame_prase_buf_, this->sg_frame_len_); + } else { + ESP_LOGD(TAG, "frame check failer!"); + } + } else { + ESP_LOGD(TAG, "FRAME_TAIL2 ERROR value:%x", value); + } + memset(this->sg_frame_prase_buf_, 0, FRAME_BUF_MAX_SIZE); + memset(this->sg_frame_buf_, 0, FRAME_BUF_MAX_SIZE); + this->sg_frame_len_ = 0; + this->sg_data_len_ = 0; + this->sg_recv_data_state_ = FRAME_IDLE; + break; + default: + this->sg_recv_data_state_ = FRAME_IDLE; + } +} + +// Parses data frames related to product information +void MR24HPC1Component::r24_frame_parse_product_information_(uint8_t *data) { + uint16_t product_len = encode_uint16(data[FRAME_COMMAND_WORD_INDEX + 1], data[FRAME_COMMAND_WORD_INDEX + 2]); + if (data[FRAME_COMMAND_WORD_INDEX] == COMMAND_PRODUCT_MODE) { + if ((this->product_model_text_sensor_ != nullptr) && (product_len < PRODUCT_BUF_MAX_SIZE)) { + memset(this->c_product_mode_, 0, PRODUCT_BUF_MAX_SIZE); + memcpy(this->c_product_mode_, &data[FRAME_DATA_INDEX], product_len); + this->product_model_text_sensor_->publish_state(this->c_product_mode_); + } else { + ESP_LOGD(TAG, "Reply: get product_mode error!"); + } + } else if (data[FRAME_COMMAND_WORD_INDEX] == COMMAND_PRODUCT_ID) { + if ((this->product_id_text_sensor_ != nullptr) && (product_len < PRODUCT_BUF_MAX_SIZE)) { + memset(this->c_product_id_, 0, PRODUCT_BUF_MAX_SIZE); + memcpy(this->c_product_id_, &data[FRAME_DATA_INDEX], product_len); + this->product_id_text_sensor_->publish_state(this->c_product_id_); + } else { + ESP_LOGD(TAG, "Reply: get productId error!"); + } + } else if (data[FRAME_COMMAND_WORD_INDEX] == COMMAND_HARDWARE_MODEL) { + if ((this->hardware_model_text_sensor_ != nullptr) && (product_len < PRODUCT_BUF_MAX_SIZE)) { + memset(this->c_hardware_model_, 0, PRODUCT_BUF_MAX_SIZE); + memcpy(this->c_hardware_model_, &data[FRAME_DATA_INDEX], product_len); + this->hardware_model_text_sensor_->publish_state(this->c_hardware_model_); + ESP_LOGD(TAG, "Reply: get hardware_model :%s", this->c_hardware_model_); + } else { + ESP_LOGD(TAG, "Reply: get hardwareModel error!"); + } + } else if (data[FRAME_COMMAND_WORD_INDEX] == COMMAND_FIRMWARE_VERSION) { + if ((this->firware_version_text_sensor_ != nullptr) && (product_len < PRODUCT_BUF_MAX_SIZE)) { + memset(this->c_firmware_version_, 0, PRODUCT_BUF_MAX_SIZE); + memcpy(this->c_firmware_version_, &data[FRAME_DATA_INDEX], product_len); + this->firware_version_text_sensor_->publish_state(this->c_firmware_version_); + } else { + ESP_LOGD(TAG, "Reply: get firmwareVersion error!"); + } + } +} + +// Parsing the underlying open parameters +void MR24HPC1Component::r24_frame_parse_open_underlying_information_(uint8_t *data) { + if (data[FRAME_COMMAND_WORD_INDEX] == 0x00) { + if (this->underlying_open_function_switch_ != nullptr) { + this->underlying_open_function_switch_->publish_state( + data[FRAME_DATA_INDEX]); // Underlying Open Parameter Switch Status Updates + } + if (data[FRAME_DATA_INDEX]) { + this->s_output_info_switch_flag_ = OUTPUT_SWITCH_ON; + } else { + this->s_output_info_switch_flag_ = OUTPUT_SWTICH_OFF; + } + } else if (data[FRAME_COMMAND_WORD_INDEX] == 0x01) { + if (this->custom_spatial_static_value_sensor_ != nullptr) { + this->custom_spatial_static_value_sensor_->publish_state(data[FRAME_DATA_INDEX]); + } + if (this->custom_presence_of_detection_sensor_ != nullptr) { + this->custom_presence_of_detection_sensor_->publish_state(data[FRAME_DATA_INDEX + 1] * 0.5f); + } + if (this->custom_spatial_motion_value_sensor_ != nullptr) { + this->custom_spatial_motion_value_sensor_->publish_state(data[FRAME_DATA_INDEX + 2]); + } + if (this->custom_motion_distance_sensor_ != nullptr) { + this->custom_motion_distance_sensor_->publish_state(data[FRAME_DATA_INDEX + 3] * 0.5f); + } + if (this->custom_motion_speed_sensor_ != nullptr) { + this->custom_motion_speed_sensor_->publish_state((data[FRAME_DATA_INDEX + 4] - 10) * 0.5f); + } + } else if ((data[FRAME_COMMAND_WORD_INDEX] == 0x06) || (data[FRAME_COMMAND_WORD_INDEX] == 0x86)) { + // none:0x00 close_to:0x01 far_away:0x02 + if ((this->keep_away_text_sensor_ != nullptr) && (data[FRAME_DATA_INDEX] < 3)) { + this->keep_away_text_sensor_->publish_state(S_KEEP_AWAY_STR[data[FRAME_DATA_INDEX]]); + } + } else if ((this->movement_signs_sensor_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x07) || (data[FRAME_COMMAND_WORD_INDEX] == 0x87))) { + this->movement_signs_sensor_->publish_state(data[FRAME_DATA_INDEX]); + } else if ((this->existence_threshold_number_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x08) || (data[FRAME_COMMAND_WORD_INDEX] == 0x88))) { + this->existence_threshold_number_->publish_state(data[FRAME_DATA_INDEX]); + } else if ((this->motion_threshold_number_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x09) || (data[FRAME_COMMAND_WORD_INDEX] == 0x89))) { + this->motion_threshold_number_->publish_state(data[FRAME_DATA_INDEX]); + } else if ((this->existence_boundary_select_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x0a) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8a))) { + if (this->existence_boundary_select_->has_index(data[FRAME_DATA_INDEX] - 1)) { + this->existence_boundary_select_->publish_state(S_BOUNDARY_STR[data[FRAME_DATA_INDEX] - 1]); + } + } else if ((this->motion_boundary_select_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x0b) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8b))) { + if (this->motion_boundary_select_->has_index(data[FRAME_DATA_INDEX] - 1)) { + this->motion_boundary_select_->publish_state(S_BOUNDARY_STR[data[FRAME_DATA_INDEX] - 1]); + } + } else if ((this->motion_trigger_number_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x0c) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8c))) { + uint32_t motion_trigger_time = encode_uint32(data[FRAME_DATA_INDEX], data[FRAME_DATA_INDEX + 1], + data[FRAME_DATA_INDEX + 2], data[FRAME_DATA_INDEX + 3]); + this->motion_trigger_number_->publish_state(motion_trigger_time); + } else if ((this->motion_to_rest_number_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x0d) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8d))) { + uint32_t move_to_rest_time = encode_uint32(data[FRAME_DATA_INDEX], data[FRAME_DATA_INDEX + 1], + data[FRAME_DATA_INDEX + 2], data[FRAME_DATA_INDEX + 3]); + this->motion_to_rest_number_->publish_state(move_to_rest_time); + } else if ((this->custom_unman_time_number_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x0e) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8e))) { + uint32_t enter_unmanned_time = encode_uint32(data[FRAME_DATA_INDEX], data[FRAME_DATA_INDEX + 1], + data[FRAME_DATA_INDEX + 2], data[FRAME_DATA_INDEX + 3]); + float custom_unmanned_time = enter_unmanned_time / 1000.0; + this->custom_unman_time_number_->publish_state(custom_unmanned_time); + } else if (data[FRAME_COMMAND_WORD_INDEX] == 0x80) { + if (data[FRAME_DATA_INDEX]) { + this->s_output_info_switch_flag_ = OUTPUT_SWITCH_ON; + } else { + this->s_output_info_switch_flag_ = OUTPUT_SWTICH_OFF; + } + if (this->underlying_open_function_switch_ != nullptr) { + this->underlying_open_function_switch_->publish_state(data[FRAME_DATA_INDEX]); + } + } else if ((this->custom_spatial_static_value_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x81)) { + this->custom_spatial_static_value_sensor_->publish_state(data[FRAME_DATA_INDEX]); + } else if ((this->custom_spatial_motion_value_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x82)) { + this->custom_spatial_motion_value_sensor_->publish_state(data[FRAME_DATA_INDEX]); + } else if ((this->custom_presence_of_detection_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x83)) { + this->custom_presence_of_detection_sensor_->publish_state( + S_PRESENCE_OF_DETECTION_RANGE_STR[data[FRAME_DATA_INDEX]]); + } else if ((this->custom_motion_distance_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x84)) { + this->custom_motion_distance_sensor_->publish_state(data[FRAME_DATA_INDEX] * 0.5f); + } else if ((this->custom_motion_speed_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x85)) { + this->custom_motion_speed_sensor_->publish_state((data[FRAME_DATA_INDEX] - 10) * 0.5f); + } +} + +void MR24HPC1Component::r24_parse_data_frame_(uint8_t *data, uint8_t len) { + switch (data[FRAME_CONTROL_WORD_INDEX]) { + case 0x01: { + if ((this->heartbeat_state_text_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x01)) { + this->heartbeat_state_text_sensor_->publish_state("Equipment Normal"); + } else if (data[FRAME_COMMAND_WORD_INDEX] == 0x02) { + ESP_LOGD(TAG, "Reply: query restart packet"); + } else if (this->heartbeat_state_text_sensor_ != nullptr) { + this->heartbeat_state_text_sensor_->publish_state("Equipment Abnormal"); + } + } break; + case 0x02: { + this->r24_frame_parse_product_information_(data); + } break; + case 0x05: { + this->r24_frame_parse_work_status_(data); + } break; + case 0x08: { + this->r24_frame_parse_open_underlying_information_(data); + } break; + case 0x80: { + this->r24_frame_parse_human_information_(data); + } break; + default: + ESP_LOGD(TAG, "control word:0x%02X not found", data[FRAME_CONTROL_WORD_INDEX]); + break; + } +} + +void MR24HPC1Component::r24_frame_parse_work_status_(uint8_t *data) { + if (data[FRAME_COMMAND_WORD_INDEX] == 0x01) { + ESP_LOGD(TAG, "Reply: get radar init status 0x%02X", data[FRAME_DATA_INDEX]); + } else if (data[FRAME_COMMAND_WORD_INDEX] == 0x07) { + if ((this->scene_mode_select_ != nullptr) && (this->scene_mode_select_->has_index(data[FRAME_DATA_INDEX]))) { + this->scene_mode_select_->publish_state(S_SCENE_STR[data[FRAME_DATA_INDEX]]); + } else { + ESP_LOGD(TAG, "Select has index offset %d Error", data[FRAME_DATA_INDEX]); + } + } else if ((this->sensitivity_number_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x08) || (data[FRAME_COMMAND_WORD_INDEX] == 0x88))) { + // 1-3 + this->sensitivity_number_->publish_state(data[FRAME_DATA_INDEX]); + } else if (data[FRAME_COMMAND_WORD_INDEX] == 0x09) { + // 1-4 + if (this->custom_mode_num_sensor_ != nullptr) { + this->custom_mode_num_sensor_->publish_state(data[FRAME_DATA_INDEX]); + } + if (this->custom_mode_number_ != nullptr) { + this->custom_mode_number_->publish_state(0); + } + if (this->custom_mode_end_text_sensor_ != nullptr) { + this->custom_mode_end_text_sensor_->publish_state("Setup in progress..."); + } + } else if (data[FRAME_COMMAND_WORD_INDEX] == 0x81) { + ESP_LOGD(TAG, "Reply: get radar init status 0x%02X", data[FRAME_DATA_INDEX]); + } else if (data[FRAME_COMMAND_WORD_INDEX] == 0x87) { + if ((this->scene_mode_select_ != nullptr) && (this->scene_mode_select_->has_index(data[FRAME_DATA_INDEX]))) { + this->scene_mode_select_->publish_state(S_SCENE_STR[data[FRAME_DATA_INDEX]]); + } else { + ESP_LOGD(TAG, "Select has index offset %d Error", data[FRAME_DATA_INDEX]); + } + } else if ((this->custom_mode_end_text_sensor_ != nullptr) && (data[FRAME_COMMAND_WORD_INDEX] == 0x0A)) { + this->custom_mode_end_text_sensor_->publish_state("Set Success!"); + } else if (data[FRAME_COMMAND_WORD_INDEX] == 0x89) { + if (data[FRAME_DATA_INDEX] == 0) { + if (this->custom_mode_end_text_sensor_ != nullptr) { + this->custom_mode_end_text_sensor_->publish_state("Not in custom mode"); + } + if (this->custom_mode_number_ != nullptr) { + this->custom_mode_number_->publish_state(0); + } + if (this->custom_mode_num_sensor_ != nullptr) { + this->custom_mode_num_sensor_->publish_state(data[FRAME_DATA_INDEX]); + } + } else { + if (this->custom_mode_num_sensor_ != nullptr) { + this->custom_mode_num_sensor_->publish_state(data[FRAME_DATA_INDEX]); + } + } + } else { + ESP_LOGD(TAG, "[%s] No found COMMAND_WORD(%02X) in Frame", __FUNCTION__, data[FRAME_COMMAND_WORD_INDEX]); + } +} + +void MR24HPC1Component::r24_frame_parse_human_information_(uint8_t *data) { + if ((this->has_target_binary_sensor_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x01) || (data[FRAME_COMMAND_WORD_INDEX] == 0x81))) { + this->has_target_binary_sensor_->publish_state(S_SOMEONE_EXISTS_STR[data[FRAME_DATA_INDEX]]); + } else if ((this->motion_status_text_sensor_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x02) || (data[FRAME_COMMAND_WORD_INDEX] == 0x82))) { + if (data[FRAME_DATA_INDEX] < 3) { + this->motion_status_text_sensor_->publish_state(S_MOTION_STATUS_STR[data[FRAME_DATA_INDEX]]); + } + } else if ((this->movement_signs_sensor_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x03) || (data[FRAME_COMMAND_WORD_INDEX] == 0x83))) { + this->movement_signs_sensor_->publish_state(data[FRAME_DATA_INDEX]); + } else if ((this->unman_time_select_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x0A) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8A))) { + // none:0x00 1s:0x01 30s:0x02 1min:0x03 2min:0x04 5min:0x05 10min:0x06 30min:0x07 1hour:0x08 + if (data[FRAME_DATA_INDEX] < 9) { + this->unman_time_select_->publish_state(S_UNMANNED_TIME_STR[data[FRAME_DATA_INDEX]]); + } + } else if ((this->keep_away_text_sensor_ != nullptr) && + ((data[FRAME_COMMAND_WORD_INDEX] == 0x0B) || (data[FRAME_COMMAND_WORD_INDEX] == 0x8B))) { + // none:0x00 close_to:0x01 far_away:0x02 + if (data[FRAME_DATA_INDEX] < 3) { + this->keep_away_text_sensor_->publish_state(S_KEEP_AWAY_STR[data[FRAME_DATA_INDEX]]); + } + } else { + ESP_LOGD(TAG, "[%s] No found COMMAND_WORD(%02X) in Frame", __FUNCTION__, data[FRAME_COMMAND_WORD_INDEX]); + } +} + +// Sending data frames +void MR24HPC1Component::send_query_(const uint8_t *query, size_t string_length) { + this->write_array(query, string_length); +} + +// Send Heartbeat Packet Command +void MR24HPC1Component::get_heartbeat_packet() { this->send_query_(GET_HEARTBEAT, sizeof(GET_HEARTBEAT)); } + +// Issuance of the underlying open parameter query command +void MR24HPC1Component::get_radar_output_information_switch() { + this->send_query_(GET_RADAR_OUTPUT_INFORMATION_SWITCH, sizeof(GET_RADAR_OUTPUT_INFORMATION_SWITCH)); +} + +// Issuance of product model orders +void MR24HPC1Component::get_product_mode() { this->send_query_(GET_PRODUCT_MODE, sizeof(GET_PRODUCT_MODE)); } + +// Issuing the Get Product ID command +void MR24HPC1Component::get_product_id() { this->send_query_(GET_PRODUCT_ID, sizeof(GET_PRODUCT_ID)); } + +// Issuing hardware model commands +void MR24HPC1Component::get_hardware_model() { this->send_query_(GET_HARDWARE_MODEL, sizeof(GET_HARDWARE_MODEL)); } + +// Issuing software version commands +void MR24HPC1Component::get_firmware_version() { + this->send_query_(GET_FIRMWARE_VERSION, sizeof(GET_FIRMWARE_VERSION)); +} + +void MR24HPC1Component::get_human_status() { this->send_query_(GET_HUMAN_STATUS, sizeof(GET_HUMAN_STATUS)); } + +void MR24HPC1Component::get_human_motion_info() { + this->send_query_(GET_HUMAN_MOTION_INFORMATION, sizeof(GET_HUMAN_MOTION_INFORMATION)); +} + +void MR24HPC1Component::get_body_motion_params() { + this->send_query_(GET_BODY_MOTION_PARAMETERS, sizeof(GET_BODY_MOTION_PARAMETERS)); +} + +void MR24HPC1Component::get_keep_away() { this->send_query_(GET_KEEP_AWAY, sizeof(GET_KEEP_AWAY)); } + +void MR24HPC1Component::get_scene_mode() { this->send_query_(GET_SCENE_MODE, sizeof(GET_SCENE_MODE)); } + +void MR24HPC1Component::get_sensitivity() { this->send_query_(GET_SENSITIVITY, sizeof(GET_SENSITIVITY)); } + +void MR24HPC1Component::get_unmanned_time() { this->send_query_(GET_UNMANNED_TIME, sizeof(GET_UNMANNED_TIME)); } + +void MR24HPC1Component::get_custom_mode() { this->send_query_(GET_CUSTOM_MODE, sizeof(GET_CUSTOM_MODE)); } + +void MR24HPC1Component::get_existence_boundary() { + this->send_query_(GET_EXISTENCE_BOUNDARY, sizeof(GET_EXISTENCE_BOUNDARY)); +} + +void MR24HPC1Component::get_motion_boundary() { this->send_query_(GET_MOTION_BOUNDARY, sizeof(GET_MOTION_BOUNDARY)); } + +void MR24HPC1Component::get_spatial_static_value() { + this->send_query_(GET_SPATIAL_STATIC_VALUE, sizeof(GET_SPATIAL_STATIC_VALUE)); +} + +void MR24HPC1Component::get_spatial_motion_value() { + this->send_query_(GET_SPATIAL_MOTION_VALUE, sizeof(GET_SPATIAL_MOTION_VALUE)); +} + +void MR24HPC1Component::get_distance_of_static_object() { + this->send_query_(GET_DISTANCE_OF_STATIC_OBJECT, sizeof(GET_DISTANCE_OF_STATIC_OBJECT)); +} + +void MR24HPC1Component::get_distance_of_moving_object() { + this->send_query_(GET_DISTANCE_OF_MOVING_OBJECT, sizeof(GET_DISTANCE_OF_MOVING_OBJECT)); +} + +void MR24HPC1Component::get_target_movement_speed() { + this->send_query_(GET_TARGET_MOVEMENT_SPEED, sizeof(GET_TARGET_MOVEMENT_SPEED)); +} + +void MR24HPC1Component::get_existence_threshold() { + this->send_query_(GET_EXISTENCE_THRESHOLD, sizeof(GET_EXISTENCE_THRESHOLD)); +} + +void MR24HPC1Component::get_motion_threshold() { + this->send_query_(GET_MOTION_THRESHOLD, sizeof(GET_MOTION_THRESHOLD)); +} + +void MR24HPC1Component::get_motion_trigger_time() { + this->send_query_(GET_MOTION_TRIGGER_TIME, sizeof(GET_MOTION_TRIGGER_TIME)); +} + +void MR24HPC1Component::get_motion_to_rest_time() { + this->send_query_(GET_MOTION_TO_REST_TIME, sizeof(GET_MOTION_TO_REST_TIME)); +} + +void MR24HPC1Component::get_custom_unman_time() { + this->send_query_(GET_CUSTOM_UNMAN_TIME, sizeof(GET_CUSTOM_UNMAN_TIME)); +} + +// Logic of setting: After setting, query whether the setting is successful or not! + +void MR24HPC1Component::set_underlying_open_function(bool enable) { + if (enable) { + this->send_query_(UNDERLYING_SWITCH_ON, sizeof(UNDERLYING_SWITCH_ON)); + } else { + this->send_query_(UNDERLYING_SWITCH_OFF, sizeof(UNDERLYING_SWITCH_OFF)); + } + if (this->keep_away_text_sensor_ != nullptr) { + this->keep_away_text_sensor_->publish_state(""); + } + if (this->motion_status_text_sensor_ != nullptr) { + this->motion_status_text_sensor_->publish_state(""); + } + if (this->custom_spatial_static_value_sensor_ != nullptr) { + this->custom_spatial_static_value_sensor_->publish_state(NAN); + } + if (this->custom_spatial_motion_value_sensor_ != nullptr) { + this->custom_spatial_motion_value_sensor_->publish_state(NAN); + } + if (this->custom_motion_distance_sensor_ != nullptr) { + this->custom_motion_distance_sensor_->publish_state(NAN); + } + if (this->custom_presence_of_detection_sensor_ != nullptr) { + this->custom_presence_of_detection_sensor_->publish_state(NAN); + } + if (this->custom_motion_speed_sensor_ != nullptr) { + this->custom_motion_speed_sensor_->publish_state(NAN); + } +} + +void MR24HPC1Component::set_scene_mode(uint8_t value) { + uint8_t send_data_len = 10; + uint8_t send_data[10] = {0x53, 0x59, 0x05, 0x07, 0x00, 0x01, value, 0x00, 0x54, 0x43}; + send_data[7] = get_frame_crc_sum(send_data, send_data_len); + this->send_query_(send_data, send_data_len); + if (this->custom_mode_number_ != nullptr) { + this->custom_mode_number_->publish_state(0); + } + if (this->custom_mode_num_sensor_ != nullptr) { + this->custom_mode_num_sensor_->publish_state(0); + } + this->get_scene_mode(); + this->get_sensitivity(); + this->get_custom_mode(); + this->get_existence_boundary(); + this->get_motion_boundary(); + this->get_existence_threshold(); + this->get_motion_threshold(); + this->get_motion_trigger_time(); + this->get_motion_to_rest_time(); + this->get_custom_unman_time(); +} + +void MR24HPC1Component::set_sensitivity(uint8_t value) { + if (value == 0x00) + return; + uint8_t send_data_len = 10; + uint8_t send_data[10] = {0x53, 0x59, 0x05, 0x08, 0x00, 0x01, value, 0x00, 0x54, 0x43}; + send_data[7] = get_frame_crc_sum(send_data, send_data_len); + this->send_query_(send_data, send_data_len); + this->get_scene_mode(); + this->get_sensitivity(); +} + +void MR24HPC1Component::set_restart() { + this->send_query_(SET_RESTART, sizeof(SET_RESTART)); + this->check_dev_inf_sign_ = true; +} + +void MR24HPC1Component::set_unman_time(uint8_t value) { + uint8_t send_data_len = 10; + uint8_t send_data[10] = {0x53, 0x59, 0x80, 0x0a, 0x00, 0x01, value, 0x00, 0x54, 0x43}; + send_data[7] = get_frame_crc_sum(send_data, send_data_len); + this->send_query_(send_data, send_data_len); + this->get_unmanned_time(); +} + +void MR24HPC1Component::set_custom_mode(uint8_t mode) { + if (mode == 0) { + this->set_custom_end_mode(); // Equivalent to end setting + if (this->custom_mode_number_ != nullptr) { + this->custom_mode_number_->publish_state(0); + } + return; + } + uint8_t send_data_len = 10; + uint8_t send_data[10] = {0x53, 0x59, 0x05, 0x09, 0x00, 0x01, mode, 0x00, 0x54, 0x43}; + send_data[7] = get_frame_crc_sum(send_data, send_data_len); + this->send_query_(send_data, send_data_len); + this->get_existence_boundary(); + this->get_motion_boundary(); + this->get_existence_threshold(); + this->get_motion_threshold(); + this->get_motion_trigger_time(); + this->get_motion_to_rest_time(); + this->get_custom_unman_time(); + this->get_custom_mode(); + this->get_scene_mode(); + this->get_sensitivity(); +} + +void MR24HPC1Component::set_custom_end_mode() { + uint8_t send_data_len = 10; + uint8_t send_data[10] = {0x53, 0x59, 0x05, 0x0a, 0x00, 0x01, 0x0F, 0xCB, 0x54, 0x43}; + this->send_query_(send_data, send_data_len); + if (this->custom_mode_number_ != nullptr) { + this->custom_mode_number_->publish_state(0); // Clear setpoints + } + this->get_existence_boundary(); + this->get_motion_boundary(); + this->get_existence_threshold(); + this->get_motion_threshold(); + this->get_motion_trigger_time(); + this->get_motion_to_rest_time(); + this->get_custom_unman_time(); + this->get_custom_mode(); + this->get_scene_mode(); + this->get_sensitivity(); +} + +void MR24HPC1Component::set_existence_boundary(uint8_t value) { + if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0)) + return; // You'll have to check that you're in custom mode to set it up + uint8_t send_data_len = 10; + uint8_t send_data[10] = {0x53, 0x59, 0x08, 0x0A, 0x00, 0x01, (uint8_t) (value + 1), 0x00, 0x54, 0x43}; + send_data[7] = get_frame_crc_sum(send_data, send_data_len); + this->send_query_(send_data, send_data_len); + this->get_existence_boundary(); +} + +void MR24HPC1Component::set_motion_boundary(uint8_t value) { + if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0)) + return; // You'll have to check that you're in custom mode to set it up + uint8_t send_data_len = 10; + uint8_t send_data[10] = {0x53, 0x59, 0x08, 0x0B, 0x00, 0x01, (uint8_t) (value + 1), 0x00, 0x54, 0x43}; + send_data[7] = get_frame_crc_sum(send_data, send_data_len); + this->send_query_(send_data, send_data_len); + this->get_motion_boundary(); +} + +void MR24HPC1Component::set_existence_threshold(uint8_t value) { + if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0)) + return; // You'll have to check that you're in custom mode to set it up + uint8_t send_data_len = 10; + uint8_t send_data[10] = {0x53, 0x59, 0x08, 0x08, 0x00, 0x01, value, 0x00, 0x54, 0x43}; + send_data[7] = get_frame_crc_sum(send_data, send_data_len); + this->send_query_(send_data, send_data_len); + this->get_existence_threshold(); +} + +void MR24HPC1Component::set_motion_threshold(uint8_t value) { + if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0)) + return; // You'll have to check that you're in custom mode to set it up + uint8_t send_data_len = 10; + uint8_t send_data[10] = {0x53, 0x59, 0x08, 0x09, 0x00, 0x01, value, 0x00, 0x54, 0x43}; + send_data[7] = get_frame_crc_sum(send_data, send_data_len); + this->send_query_(send_data, send_data_len); + this->get_motion_threshold(); +} + +void MR24HPC1Component::set_motion_trigger_time(uint8_t value) { + if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0)) + return; // You'll have to check that you're in custom mode to set it up + uint8_t send_data_len = 13; + uint8_t send_data[13] = {0x53, 0x59, 0x08, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, value, 0x00, 0x54, 0x43}; + send_data[10] = get_frame_crc_sum(send_data, send_data_len); + this->send_query_(send_data, send_data_len); + this->get_motion_trigger_time(); +} + +void MR24HPC1Component::set_motion_to_rest_time(uint16_t value) { + if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0)) + return; // You'll have to check that you're in custom mode to set it up + uint8_t h8_num = (value >> 8) & 0xff; + uint8_t l8_num = value & 0xff; + uint8_t send_data_len = 13; + uint8_t send_data[13] = {0x53, 0x59, 0x08, 0x0D, 0x00, 0x04, 0x00, 0x00, h8_num, l8_num, 0x00, 0x54, 0x43}; + send_data[10] = get_frame_crc_sum(send_data, send_data_len); + this->send_query_(send_data, send_data_len); + this->get_motion_to_rest_time(); +} + +void MR24HPC1Component::set_custom_unman_time(uint16_t value) { + if ((this->custom_mode_num_sensor_ != nullptr) && (this->custom_mode_num_sensor_->state == 0)) + return; // You'll have to check that you're in custom mode to set it up + uint32_t value_ms = value * 1000; + uint8_t h24_num = (value_ms >> 24) & 0xff; + uint8_t h16_num = (value_ms >> 16) & 0xff; + uint8_t h8_num = (value_ms >> 8) & 0xff; + uint8_t l8_num = value_ms & 0xff; + uint8_t send_data_len = 13; + uint8_t send_data[13] = {0x53, 0x59, 0x08, 0x0E, 0x00, 0x04, h24_num, h16_num, h8_num, l8_num, 0x00, 0x54, 0x43}; + send_data[10] = get_frame_crc_sum(send_data, send_data_len); + this->send_query_(send_data, send_data_len); + this->get_custom_unman_time(); +} + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.h b/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.h new file mode 100644 index 0000000000..8fc61ad37c --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.h @@ -0,0 +1,217 @@ +#pragma once +#include "esphome/core/component.h" +#include "esphome/core/defines.h" +#ifdef USE_BINARY_SENSOR +#include "esphome/components/binary_sensor/binary_sensor.h" +#endif +#ifdef USE_SENSOR +#include "esphome/components/sensor/sensor.h" +#endif +#ifdef USE_NUMBER +#include "esphome/components/number/number.h" +#endif +#ifdef USE_SWITCH +#include "esphome/components/switch/switch.h" +#endif +#ifdef USE_BUTTON +#include "esphome/components/button/button.h" +#endif +#ifdef USE_SELECT +#include "esphome/components/select/select.h" +#endif +#ifdef USE_TEXT_SENSOR +#include "esphome/components/text_sensor/text_sensor.h" +#endif +#include "esphome/components/uart/uart.h" +#include "esphome/core/automation.h" +#include "esphome/core/helpers.h" + +#include "seeed_mr24hpc1_constants.h" + +#include + +namespace esphome { +namespace seeed_mr24hpc1 { + +enum FrameState { + FRAME_IDLE, + FRAME_HEADER2, + FRAME_CTL_WORD, + FRAME_CMD_WORD, + FRAME_DATA_LEN_H, + FRAME_DATA_LEN_L, + FRAME_DATA_BYTES, + FRAME_DATA_CRC, + FRAME_TAIL1, + FRAME_TAIL2, +}; + +enum PollingState { + STANDARD_FUNCTION_QUERY_PRODUCT_MODE = 0, + STANDARD_FUNCTION_QUERY_PRODUCT_ID, + STANDARD_FUNCTION_QUERY_FIRMWARE_VERSION, + STANDARD_FUNCTION_QUERY_HARDWARE_MODE, // Above is the equipment information + STANDARD_FUNCTION_QUERY_SCENE_MODE, + STANDARD_FUNCTION_QUERY_SENSITIVITY, + STANDARD_FUNCTION_QUERY_UNMANNED_TIME, + STANDARD_FUNCTION_QUERY_HUMAN_STATUS, + STANDARD_FUNCTION_QUERY_HUMAN_MOTION_INF, + STANDARD_FUNCTION_QUERY_BODY_MOVE_PARAMETER, + STANDARD_FUNCTION_QUERY_KEEPAWAY_STATUS, + STANDARD_QUERY_CUSTOM_MODE, + STANDARD_FUNCTION_QUERY_HEARTBEAT_STATE, // Above is the basic function + + CUSTOM_FUNCTION_QUERY_EXISTENCE_BOUNDARY, + CUSTOM_FUNCTION_QUERY_MOTION_BOUNDARY, + CUSTOM_FUNCTION_QUERY_EXISTENCE_THRESHOLD, + CUSTOM_FUNCTION_QUERY_MOTION_THRESHOLD, + CUSTOM_FUNCTION_QUERY_MOTION_TRIGGER_TIME, + CUSTOM_FUNCTION_QUERY_MOTION_TO_REST_TIME, + CUSTOM_FUNCTION_QUERY_TIME_OF_ENTER_UNMANNED, + + UNDERLY_FUNCTION_QUERY_HUMAN_STATUS, + UNDERLY_FUNCTION_QUERY_SPATIAL_STATIC_VALUE, + UNDERLY_FUNCTION_QUERY_SPATIAL_MOTION_VALUE, + UNDERLY_FUNCTION_QUERY_DISTANCE_OF_STATIC_OBJECT, + UNDERLY_FUNCTION_QUERY_DISTANCE_OF_MOVING_OBJECT, + UNDERLY_FUNCTION_QUERY_TARGET_MOVEMENT_SPEED, +}; + +enum OutputSwitch { + OUTPUT_SWITCH_INIT, + OUTPUT_SWITCH_ON, + OUTPUT_SWTICH_OFF, +}; + +static const char *const S_SCENE_STR[5] = {"None", "Living Room", "Bedroom", "Washroom", "Area Detection"}; +static const bool S_SOMEONE_EXISTS_STR[2] = {false, true}; +static const char *const S_MOTION_STATUS_STR[3] = {"None", "Motionless", "Active"}; +static const char *const S_KEEP_AWAY_STR[3] = {"None", "Close", "Away"}; +static const char *const S_UNMANNED_TIME_STR[9] = {"None", "10s", "30s", "1min", "2min", + "5min", "10min", "30min", "60min"}; +static const char *const S_BOUNDARY_STR[10] = {"0.5m", "1.0m", "1.5m", "2.0m", "2.5m", + "3.0m", "3.5m", "4.0m", "4.5m", "5.0m"}; // uint: m +static const float S_PRESENCE_OF_DETECTION_RANGE_STR[7] = {0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 2.5f, 3.0f}; // uint: m + +class MR24HPC1Component : public Component, + public uart::UARTDevice { // The class name must be the name defined by text_sensor.py +#ifdef USE_TEXT_SENSOR + SUB_TEXT_SENSOR(heartbeat_state) + SUB_TEXT_SENSOR(product_model) + SUB_TEXT_SENSOR(product_id) + SUB_TEXT_SENSOR(hardware_model) + SUB_TEXT_SENSOR(firware_version) + SUB_TEXT_SENSOR(keep_away) + SUB_TEXT_SENSOR(motion_status) + SUB_TEXT_SENSOR(custom_mode_end) +#endif +#ifdef USE_BINARY_SENSOR + SUB_BINARY_SENSOR(has_target) +#endif +#ifdef USE_SENSOR + SUB_SENSOR(custom_presence_of_detection) + SUB_SENSOR(movement_signs) + SUB_SENSOR(custom_motion_distance) + SUB_SENSOR(custom_spatial_static_value) + SUB_SENSOR(custom_spatial_motion_value) + SUB_SENSOR(custom_motion_speed) + SUB_SENSOR(custom_mode_num) +#endif +#ifdef USE_SWITCH + SUB_SWITCH(underlying_open_function) +#endif +#ifdef USE_BUTTON + SUB_BUTTON(restart) + SUB_BUTTON(custom_set_end) +#endif +#ifdef USE_SELECT + SUB_SELECT(scene_mode) + SUB_SELECT(unman_time) + SUB_SELECT(existence_boundary) + SUB_SELECT(motion_boundary) +#endif +#ifdef USE_NUMBER + SUB_NUMBER(sensitivity) + SUB_NUMBER(custom_mode) + SUB_NUMBER(existence_threshold) + SUB_NUMBER(motion_threshold) + SUB_NUMBER(motion_trigger) + SUB_NUMBER(motion_to_rest) + SUB_NUMBER(custom_unman_time) +#endif + + protected: + char c_product_mode_[PRODUCT_BUF_MAX_SIZE + 1]; + char c_product_id_[PRODUCT_BUF_MAX_SIZE + 1]; + char c_hardware_model_[PRODUCT_BUF_MAX_SIZE + 1]; + char c_firmware_version_[PRODUCT_BUF_MAX_SIZE + 1]; + uint8_t s_output_info_switch_flag_; + uint8_t sg_recv_data_state_; + uint8_t sg_frame_len_; + uint8_t sg_data_len_; + uint8_t sg_frame_buf_[FRAME_BUF_MAX_SIZE]; + uint8_t sg_frame_prase_buf_[FRAME_BUF_MAX_SIZE]; + int sg_start_query_data_; + bool check_dev_inf_sign_; + bool poll_time_base_func_check_; + + void update_(); + void r24_split_data_frame_(uint8_t value); + void r24_parse_data_frame_(uint8_t *data, uint8_t len); + void r24_frame_parse_open_underlying_information_(uint8_t *data); + void r24_frame_parse_work_status_(uint8_t *data); + void r24_frame_parse_product_information_(uint8_t *data); + void r24_frame_parse_human_information_(uint8_t *data); + void send_query_(const uint8_t *query, size_t string_length); + + public: + float get_setup_priority() const override { return esphome::setup_priority::LATE; } + void setup() override; + void dump_config() override; + void loop() override; + + void get_heartbeat_packet(); + void get_radar_output_information_switch(); + void get_product_mode(); + void get_product_id(); + void get_hardware_model(); + void get_firmware_version(); + void get_human_status(); + void get_human_motion_info(); + void get_body_motion_params(); + void get_keep_away(); + void get_scene_mode(); + void get_sensitivity(); + void get_unmanned_time(); + void get_custom_mode(); + void get_existence_boundary(); + void get_motion_boundary(); + void get_spatial_static_value(); + void get_spatial_motion_value(); + void get_distance_of_static_object(); + void get_distance_of_moving_object(); + void get_target_movement_speed(); + void get_existence_threshold(); + void get_motion_threshold(); + void get_motion_trigger_time(); + void get_motion_to_rest_time(); + void get_custom_unman_time(); + + void set_scene_mode(uint8_t value); + void set_underlying_open_function(bool enable); + void set_sensitivity(uint8_t value); + void set_restart(); + void set_unman_time(uint8_t value); + void set_custom_mode(uint8_t mode); + void set_custom_end_mode(); + void set_existence_boundary(uint8_t value); + void set_motion_boundary(uint8_t value); + void set_existence_threshold(uint8_t value); + void set_motion_threshold(uint8_t value); + void set_motion_trigger_time(uint8_t value); + void set_motion_to_rest_time(uint16_t value); + void set_custom_unman_time(uint16_t value); +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1_constants.h b/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1_constants.h new file mode 100644 index 0000000000..dafc6c0368 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/seeed_mr24hpc1_constants.h @@ -0,0 +1,173 @@ +#pragma once + +#include + +namespace esphome { +namespace seeed_mr24hpc1 { + +static const uint8_t FRAME_BUF_MAX_SIZE = 128; +static const uint8_t PRODUCT_BUF_MAX_SIZE = 32; + +static const uint8_t FRAME_CONTROL_WORD_INDEX = 2; +static const uint8_t FRAME_COMMAND_WORD_INDEX = 3; +static const uint8_t FRAME_DATA_INDEX = 6; + +static const uint8_t FRAME_HEADER1_VALUE = 0x53; +static const uint8_t FRAME_HEADER2_VALUE = 0x59; +static const uint8_t FRAME_TAIL1_VALUE = 0x54; +static const uint8_t FRAME_TAIL2_VALUE = 0x43; + +static const uint8_t CONTROL_MAIN = 0x01; +static const uint8_t CONTROL_PRODUCT_INFORMATION = 0x02; +static const uint8_t CONTROL_WORK = 0x05; +static const uint8_t CONTROL_UNDERLYING_FUNCTION = 0x08; +static const uint8_t CONTROL_HUMAN_INFORMATION = 0x80; + +static const uint8_t COMMAND_HEARTBEAT = 0x01; +static const uint8_t COMMAND_RESTART = 0x02; + +static const uint8_t COMMAND_PRODUCT_MODE = 0xA1; +static const uint8_t COMMAND_PRODUCT_ID = 0xA2; +static const uint8_t COMMAND_HARDWARE_MODEL = 0xA3; +static const uint8_t COMMAND_FIRMWARE_VERSION = 0xA4; + +static const uint8_t GET_HEARTBEAT[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_MAIN, COMMAND_HEARTBEAT, 0x00, 0x01, 0x0F, 0xBE, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t SET_RESTART[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_MAIN, COMMAND_RESTART, 0x00, 0x01, 0x0F, 0xBF, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; + +static const uint8_t GET_PRODUCT_MODE[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_PRODUCT_INFORMATION, COMMAND_PRODUCT_MODE, 0x00, 0x01, 0x0F, 0x5F, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_PRODUCT_ID[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_PRODUCT_INFORMATION, COMMAND_PRODUCT_ID, 0x00, 0x01, 0x0F, 0x60, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_HARDWARE_MODEL[] = { + FRAME_HEADER1_VALUE, + FRAME_HEADER2_VALUE, + CONTROL_PRODUCT_INFORMATION, + COMMAND_HARDWARE_MODEL, + 0x00, + 0x01, + 0x0F, + 0x61, + FRAME_TAIL1_VALUE, + FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_FIRMWARE_VERSION[] = { + FRAME_HEADER1_VALUE, + FRAME_HEADER2_VALUE, + CONTROL_PRODUCT_INFORMATION, + COMMAND_FIRMWARE_VERSION, + 0x00, + 0x01, + 0x0F, + 0x62, + FRAME_TAIL1_VALUE, + FRAME_TAIL2_VALUE, +}; + +static const uint8_t GET_SCENE_MODE[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_WORK, 0x87, 0x00, 0x01, 0x0F, 0x48, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_SENSITIVITY[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_WORK, 0x88, 0x00, 0x01, 0x0F, 0x49, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_CUSTOM_MODE[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_WORK, 0x89, 0x00, 0x01, 0x0F, 0x4A, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; + +static const uint8_t UNDERLYING_SWITCH_ON[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x00, 0x00, 0x01, 0x01, 0xB6, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t UNDERLYING_SWITCH_OFF[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x00, 0x00, 0x01, 0x00, 0xB5, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; + +static const uint8_t GET_RADAR_OUTPUT_INFORMATION_SWITCH[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x80, 0x00, 0x01, 0x0F, 0x44, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_SPATIAL_STATIC_VALUE[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x81, 0x00, 0x01, 0x0F, 0x45, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_SPATIAL_MOTION_VALUE[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x82, 0x00, 0x01, 0x0F, 0x46, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_DISTANCE_OF_STATIC_OBJECT[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x83, 0x00, 0x01, 0x0F, 0x47, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_DISTANCE_OF_MOVING_OBJECT[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x84, 0x00, 0x01, 0x0F, 0x48, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_TARGET_MOVEMENT_SPEED[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x85, 0x00, 0x01, 0x0F, 0x49, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_EXISTENCE_THRESHOLD[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x88, 0x00, 0x01, 0x0F, 0x4C, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_MOTION_THRESHOLD[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x89, 0x00, 0x01, 0x0F, 0x4D, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_EXISTENCE_BOUNDARY[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x8A, 0x00, 0x01, 0x0F, 0x4E, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_MOTION_BOUNDARY[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x8B, 0x00, 0x01, 0x0F, 0x4F, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_MOTION_TRIGGER_TIME[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x8C, 0x00, 0x01, 0x0F, 0x50, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_MOTION_TO_REST_TIME[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x8D, 0x00, 0x01, 0x0F, 0x51, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_CUSTOM_UNMAN_TIME[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_UNDERLYING_FUNCTION, 0x8E, 0x00, 0x01, 0x0F, 0x52, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; + +static const uint8_t GET_HUMAN_STATUS[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_HUMAN_INFORMATION, 0x81, 0x00, 0x01, 0x0F, 0xBD, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_HUMAN_MOTION_INFORMATION[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_HUMAN_INFORMATION, 0x82, 0x00, 0x01, 0x0F, 0xBE, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_BODY_MOTION_PARAMETERS[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_HUMAN_INFORMATION, 0x83, 0x00, 0x01, 0x0F, 0xBF, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_UNMANNED_TIME[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_HUMAN_INFORMATION, 0x8A, 0x00, 0x01, 0x0F, 0xC6, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; +static const uint8_t GET_KEEP_AWAY[] = { + FRAME_HEADER1_VALUE, FRAME_HEADER2_VALUE, CONTROL_HUMAN_INFORMATION, 0x8B, 0x00, 0x01, 0x0F, 0xC7, + FRAME_TAIL1_VALUE, FRAME_TAIL2_VALUE, +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/select/__init__.py b/esphome/components/seeed_mr24hpc1/select/__init__.py new file mode 100644 index 0000000000..7da83627b9 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/select/__init__.py @@ -0,0 +1,103 @@ +import esphome.codegen as cg +from esphome.components import select +import esphome.config_validation as cv +from esphome.const import ( + ENTITY_CATEGORY_CONFIG, +) +from .. import CONF_MR24HPC1_ID, MR24HPC1Component, mr24hpc1_ns + +SceneModeSelect = mr24hpc1_ns.class_("SceneModeSelect", select.Select) +UnmanTimeSelect = mr24hpc1_ns.class_("UnmanTimeSelect", select.Select) +ExistenceBoundarySelect = mr24hpc1_ns.class_("ExistenceBoundarySelect", select.Select) +MotionBoundarySelect = mr24hpc1_ns.class_("MotionBoundarySelect", select.Select) + +CONF_SCENE_MODE = "scene_mode" +CONF_UNMAN_TIME = "unman_time" +CONF_EXISTENCE_BOUNDARY = "existence_boundary" +CONF_MOTION_BOUNDARY = "motion_boundary" + +CONFIG_SCHEMA = { + cv.GenerateID(CONF_MR24HPC1_ID): cv.use_id(MR24HPC1Component), + cv.Optional(CONF_SCENE_MODE): select.select_schema( + SceneModeSelect, + entity_category=ENTITY_CATEGORY_CONFIG, + icon="mdi:hoop-house", + ), + cv.Optional(CONF_UNMAN_TIME): select.select_schema( + UnmanTimeSelect, + entity_category=ENTITY_CATEGORY_CONFIG, + icon="mdi:timeline-clock", + ), + cv.Optional(CONF_EXISTENCE_BOUNDARY): select.select_schema( + ExistenceBoundarySelect, + entity_category=ENTITY_CATEGORY_CONFIG, + ), + cv.Optional(CONF_MOTION_BOUNDARY): select.select_schema( + MotionBoundarySelect, + entity_category=ENTITY_CATEGORY_CONFIG, + ), +} + + +async def to_code(config): + mr24hpc1_component = await cg.get_variable(config[CONF_MR24HPC1_ID]) + if scenemode_config := config.get(CONF_SCENE_MODE): + s = await select.new_select( + scenemode_config, + options=["None", "Living Room", "Bedroom", "Washroom", "Area Detection"], + ) + await cg.register_parented(s, config[CONF_MR24HPC1_ID]) + cg.add(mr24hpc1_component.set_scene_mode_select(s)) + if unmantime_config := config.get(CONF_UNMAN_TIME): + s = await select.new_select( + unmantime_config, + options=[ + "None", + "10s", + "30s", + "1min", + "2min", + "5min", + "10min", + "30min", + "60min", + ], + ) + await cg.register_parented(s, config[CONF_MR24HPC1_ID]) + cg.add(mr24hpc1_component.set_unman_time_select(s)) + if existence_boundary_config := config.get(CONF_EXISTENCE_BOUNDARY): + s = await select.new_select( + existence_boundary_config, + options=[ + "0.5m", + "1.0m", + "1.5m", + "2.0m", + "2.5m", + "3.0m", + "3.5m", + "4.0m", + "4.5m", + "5.0m", + ], + ) + await cg.register_parented(s, config[CONF_MR24HPC1_ID]) + cg.add(mr24hpc1_component.set_existence_boundary_select(s)) + if motion_boundary_config := config.get(CONF_MOTION_BOUNDARY): + s = await select.new_select( + motion_boundary_config, + options=[ + "0.5m", + "1.0m", + "1.5m", + "2.0m", + "2.5m", + "3.0m", + "3.5m", + "4.0m", + "4.5m", + "5.0m", + ], + ) + await cg.register_parented(s, config[CONF_MR24HPC1_ID]) + cg.add(mr24hpc1_component.set_motion_boundary_select(s)) diff --git a/esphome/components/seeed_mr24hpc1/select/existence_boundary_select.cpp b/esphome/components/seeed_mr24hpc1/select/existence_boundary_select.cpp new file mode 100644 index 0000000000..03c2ec4745 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/select/existence_boundary_select.cpp @@ -0,0 +1,15 @@ +#include "existence_boundary_select.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void ExistenceBoundarySelect::control(const std::string &value) { + this->publish_state(value); + auto index = this->index_of(value); + if (index.has_value()) { + this->parent_->set_existence_boundary(index.value()); + } +} + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/select/existence_boundary_select.h b/esphome/components/seeed_mr24hpc1/select/existence_boundary_select.h new file mode 100644 index 0000000000..ad770a7296 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/select/existence_boundary_select.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/select/select.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class ExistenceBoundarySelect : public select::Select, public Parented { + public: + ExistenceBoundarySelect() = default; + + protected: + void control(const std::string &value) override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/select/motion_boundary_select.cpp b/esphome/components/seeed_mr24hpc1/select/motion_boundary_select.cpp new file mode 100644 index 0000000000..619a4f0935 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/select/motion_boundary_select.cpp @@ -0,0 +1,15 @@ +#include "motion_boundary_select.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void MotionBoundarySelect::control(const std::string &value) { + this->publish_state(value); + auto index = this->index_of(value); + if (index.has_value()) { + this->parent_->set_motion_boundary(index.value()); + } +} + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/select/motion_boundary_select.h b/esphome/components/seeed_mr24hpc1/select/motion_boundary_select.h new file mode 100644 index 0000000000..9058e3130b --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/select/motion_boundary_select.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/select/select.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class MotionBoundarySelect : public select::Select, public Parented { + public: + MotionBoundarySelect() = default; + + protected: + void control(const std::string &value) override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/select/scene_mode_select.cpp b/esphome/components/seeed_mr24hpc1/select/scene_mode_select.cpp new file mode 100644 index 0000000000..153ae603cf --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/select/scene_mode_select.cpp @@ -0,0 +1,15 @@ +#include "scene_mode_select.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void SceneModeSelect::control(const std::string &value) { + this->publish_state(value); + auto index = this->index_of(value); + if (index.has_value()) { + this->parent_->set_scene_mode(index.value()); + } +} + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/select/scene_mode_select.h b/esphome/components/seeed_mr24hpc1/select/scene_mode_select.h new file mode 100644 index 0000000000..95508d49b0 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/select/scene_mode_select.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/select/select.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class SceneModeSelect : public select::Select, public Parented { + public: + SceneModeSelect() = default; + + protected: + void control(const std::string &value) override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/select/unman_time_select.cpp b/esphome/components/seeed_mr24hpc1/select/unman_time_select.cpp new file mode 100644 index 0000000000..a9d96c8f67 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/select/unman_time_select.cpp @@ -0,0 +1,15 @@ +#include "unman_time_select.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void UnmanTimeSelect::control(const std::string &value) { + this->publish_state(value); + auto index = this->index_of(value); + if (index.has_value()) { + this->parent_->set_unman_time(index.value()); + } +} + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/select/unman_time_select.h b/esphome/components/seeed_mr24hpc1/select/unman_time_select.h new file mode 100644 index 0000000000..7131988cda --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/select/unman_time_select.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/select/select.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class UnmanTimeSelect : public select::Select, public Parented { + public: + UnmanTimeSelect() = default; + + protected: + void control(const std::string &value) override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/sensor.py b/esphome/components/seeed_mr24hpc1/sensor.py new file mode 100644 index 0000000000..d5eb09e265 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/sensor.py @@ -0,0 +1,82 @@ +import esphome.codegen as cg +from esphome.components import sensor +import esphome.config_validation as cv +from esphome.const import ( + DEVICE_CLASS_DISTANCE, + DEVICE_CLASS_ENERGY, + DEVICE_CLASS_SPEED, + UNIT_METER, +) +from . import CONF_MR24HPC1_ID, MR24HPC1Component + +CONF_CUSTOM_PRESENCE_OF_DETECTION = "custom_presence_of_detection" +CONF_MOVEMENT_SIGNS = "movement_signs" +CONF_CUSTOM_MOTION_DISTANCE = "custom_motion_distance" +CONF_CUSTOM_SPATIAL_STATIC_VALUE = "custom_spatial_static_value" +CONF_CUSTOM_SPATIAL_MOTION_VALUE = "custom_spatial_motion_value" +CONF_CUSTOM_MOTION_SPEED = "custom_motion_speed" +CONF_CUSTOM_MODE_NUM = "custom_mode_num" + +CONFIG_SCHEMA = cv.Schema( + { + cv.GenerateID(CONF_MR24HPC1_ID): cv.use_id(MR24HPC1Component), + cv.Optional(CONF_CUSTOM_PRESENCE_OF_DETECTION): sensor.sensor_schema( + device_class=DEVICE_CLASS_DISTANCE, + unit_of_measurement=UNIT_METER, + accuracy_decimals=2, # Specify the number of decimal places + icon="mdi:signal-distance-variant", + ), + cv.Optional(CONF_MOVEMENT_SIGNS): sensor.sensor_schema( + icon="mdi:human-greeting-variant", + ), + cv.Optional(CONF_CUSTOM_MOTION_DISTANCE): sensor.sensor_schema( + unit_of_measurement=UNIT_METER, + accuracy_decimals=2, + icon="mdi:signal-distance-variant", + ), + cv.Optional(CONF_CUSTOM_SPATIAL_STATIC_VALUE): sensor.sensor_schema( + device_class=DEVICE_CLASS_ENERGY, + icon="mdi:counter", + ), + cv.Optional(CONF_CUSTOM_SPATIAL_MOTION_VALUE): sensor.sensor_schema( + device_class=DEVICE_CLASS_ENERGY, + icon="mdi:counter", + ), + cv.Optional(CONF_CUSTOM_MOTION_SPEED): sensor.sensor_schema( + unit_of_measurement="m/s", + device_class=DEVICE_CLASS_SPEED, + accuracy_decimals=2, + icon="mdi:run-fast", + ), + cv.Optional(CONF_CUSTOM_MODE_NUM): sensor.sensor_schema( + icon="mdi:counter", + ), + } +) + + +async def to_code(config): + mr24hpc1_component = await cg.get_variable(config[CONF_MR24HPC1_ID]) + if custompresenceofdetection_config := config.get( + CONF_CUSTOM_PRESENCE_OF_DETECTION + ): + sens = await sensor.new_sensor(custompresenceofdetection_config) + cg.add(mr24hpc1_component.set_custom_presence_of_detection_sensor(sens)) + if movementsigns_config := config.get(CONF_MOVEMENT_SIGNS): + sens = await sensor.new_sensor(movementsigns_config) + cg.add(mr24hpc1_component.set_movement_signs_sensor(sens)) + if custommotiondistance_config := config.get(CONF_CUSTOM_MOTION_DISTANCE): + sens = await sensor.new_sensor(custommotiondistance_config) + cg.add(mr24hpc1_component.set_custom_motion_distance_sensor(sens)) + if customspatialstaticvalue_config := config.get(CONF_CUSTOM_SPATIAL_STATIC_VALUE): + sens = await sensor.new_sensor(customspatialstaticvalue_config) + cg.add(mr24hpc1_component.set_custom_spatial_static_value_sensor(sens)) + if customspatialmotionvalue_config := config.get(CONF_CUSTOM_SPATIAL_MOTION_VALUE): + sens = await sensor.new_sensor(customspatialmotionvalue_config) + cg.add(mr24hpc1_component.set_custom_spatial_motion_value_sensor(sens)) + if custommotionspeed_config := config.get(CONF_CUSTOM_MOTION_SPEED): + sens = await sensor.new_sensor(custommotionspeed_config) + cg.add(mr24hpc1_component.set_custom_motion_speed_sensor(sens)) + if custommodenum_config := config.get(CONF_CUSTOM_MODE_NUM): + sens = await sensor.new_sensor(custommodenum_config) + cg.add(mr24hpc1_component.set_custom_mode_num_sensor(sens)) diff --git a/esphome/components/seeed_mr24hpc1/switch/__init__.py b/esphome/components/seeed_mr24hpc1/switch/__init__.py new file mode 100644 index 0000000000..bbf5391a57 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/switch/__init__.py @@ -0,0 +1,32 @@ +import esphome.codegen as cg +from esphome.components import switch +import esphome.config_validation as cv +from esphome.const import ( + DEVICE_CLASS_SWITCH, + ENTITY_CATEGORY_CONFIG, +) +from .. import CONF_MR24HPC1_ID, MR24HPC1Component, mr24hpc1_ns + +UnderlyingOpenFuncSwitch = mr24hpc1_ns.class_( + "UnderlyOpenFunctionSwitch", switch.Switch +) + +CONF_UNDERLYING_OPEN_FUNCTION = "underlying_open_function" + +CONFIG_SCHEMA = { + cv.GenerateID(CONF_MR24HPC1_ID): cv.use_id(MR24HPC1Component), + cv.Optional(CONF_UNDERLYING_OPEN_FUNCTION): switch.switch_schema( + UnderlyingOpenFuncSwitch, + device_class=DEVICE_CLASS_SWITCH, + entity_category=ENTITY_CATEGORY_CONFIG, + icon="mdi:electric-switch", + ), +} + + +async def to_code(config): + mr24hpc1_component = await cg.get_variable(config[CONF_MR24HPC1_ID]) + if underlying_open_function_config := config.get(CONF_UNDERLYING_OPEN_FUNCTION): + s = await switch.new_switch(underlying_open_function_config) + await cg.register_parented(s, config[CONF_MR24HPC1_ID]) + cg.add(mr24hpc1_component.set_underlying_open_function_switch(s)) diff --git a/esphome/components/seeed_mr24hpc1/switch/underlyFuc_switch.cpp b/esphome/components/seeed_mr24hpc1/switch/underlyFuc_switch.cpp new file mode 100644 index 0000000000..0fcc49bc4c --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/switch/underlyFuc_switch.cpp @@ -0,0 +1,12 @@ +#include "underlyFuc_switch.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +void UnderlyOpenFunctionSwitch::write_state(bool state) { + this->publish_state(state); + this->parent_->set_underlying_open_function(state); +} + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/switch/underlyFuc_switch.h b/esphome/components/seeed_mr24hpc1/switch/underlyFuc_switch.h new file mode 100644 index 0000000000..1baabb25ce --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/switch/underlyFuc_switch.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/switch/switch.h" +#include "../seeed_mr24hpc1.h" + +namespace esphome { +namespace seeed_mr24hpc1 { + +class UnderlyOpenFunctionSwitch : public switch_::Switch, public Parented { + public: + UnderlyOpenFunctionSwitch() = default; + + protected: + void write_state(bool state) override; +}; + +} // namespace seeed_mr24hpc1 +} // namespace esphome diff --git a/esphome/components/seeed_mr24hpc1/text_sensor.py b/esphome/components/seeed_mr24hpc1/text_sensor.py new file mode 100644 index 0000000000..aa50f577d4 --- /dev/null +++ b/esphome/components/seeed_mr24hpc1/text_sensor.py @@ -0,0 +1,74 @@ +import esphome.codegen as cg +from esphome.components import text_sensor +import esphome.config_validation as cv +from esphome.const import ENTITY_CATEGORY_DIAGNOSTIC +from . import CONF_MR24HPC1_ID, MR24HPC1Component + +CONF_HEART_BEAT = "heart_beat" +CONF_PRODUCT_MODEL = "product_model" +CONF_PRODUCT_ID = "product_id" +CONF_HARDWARE_MODEL = "hardware_model" +CONF_HARDWARE_VERSION = "hardware_version" + +CONF_KEEP_AWAY = "keep_away" +CONF_MOTION_STATUS = "motion_status" + +CONF_CUSTOM_MODE_END = "custom_mode_end" + + +# The entity category for read only diagnostic values, for example RSSI, uptime or MAC Address +CONFIG_SCHEMA = { + cv.GenerateID(CONF_MR24HPC1_ID): cv.use_id(MR24HPC1Component), + cv.Optional(CONF_HEART_BEAT): text_sensor.text_sensor_schema( + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, icon="mdi:connection" + ), + cv.Optional(CONF_PRODUCT_MODEL): text_sensor.text_sensor_schema( + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, icon="mdi:information-outline" + ), + cv.Optional(CONF_PRODUCT_ID): text_sensor.text_sensor_schema( + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, icon="mdi:information-outline" + ), + cv.Optional(CONF_HARDWARE_MODEL): text_sensor.text_sensor_schema( + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, icon="mdi:information-outline" + ), + cv.Optional(CONF_HARDWARE_VERSION): text_sensor.text_sensor_schema( + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, icon="mdi:information-outline" + ), + cv.Optional(CONF_KEEP_AWAY): text_sensor.text_sensor_schema( + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, icon="mdi:walk" + ), + cv.Optional(CONF_MOTION_STATUS): text_sensor.text_sensor_schema( + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, icon="mdi:human-greeting" + ), + cv.Optional(CONF_CUSTOM_MODE_END): text_sensor.text_sensor_schema( + entity_category=ENTITY_CATEGORY_DIAGNOSTIC, icon="mdi:account-check" + ), +} + + +async def to_code(config): + mr24hpc1_component = await cg.get_variable(config[CONF_MR24HPC1_ID]) + if heartbeat_config := config.get(CONF_HEART_BEAT): + sens = await text_sensor.new_text_sensor(heartbeat_config) + cg.add(mr24hpc1_component.set_heartbeat_state_text_sensor(sens)) + if productmodel_config := config.get(CONF_PRODUCT_MODEL): + sens = await text_sensor.new_text_sensor(productmodel_config) + cg.add(mr24hpc1_component.set_product_model_text_sensor(sens)) + if productid_config := config.get(CONF_PRODUCT_ID): + sens = await text_sensor.new_text_sensor(productid_config) + cg.add(mr24hpc1_component.set_product_id_text_sensor(sens)) + if hardwaremodel_config := config.get(CONF_HARDWARE_MODEL): + sens = await text_sensor.new_text_sensor(hardwaremodel_config) + cg.add(mr24hpc1_component.set_hardware_model_text_sensor(sens)) + if firwareversion_config := config.get(CONF_HARDWARE_VERSION): + sens = await text_sensor.new_text_sensor(firwareversion_config) + cg.add(mr24hpc1_component.set_firware_version_text_sensor(sens)) + if keepaway_config := config.get(CONF_KEEP_AWAY): + sens = await text_sensor.new_text_sensor(keepaway_config) + cg.add(mr24hpc1_component.set_keep_away_text_sensor(sens)) + if motionstatus_config := config.get(CONF_MOTION_STATUS): + sens = await text_sensor.new_text_sensor(motionstatus_config) + cg.add(mr24hpc1_component.set_motion_status_text_sensor(sens)) + if custommodeend_config := config.get(CONF_CUSTOM_MODE_END): + sens = await text_sensor.new_text_sensor(custommodeend_config) + cg.add(mr24hpc1_component.set_custom_mode_end_text_sensor(sens)) diff --git a/tests/components/seeed_mr24hpc1/common.yaml b/tests/components/seeed_mr24hpc1/common.yaml new file mode 100644 index 0000000000..38692b3e5e --- /dev/null +++ b/tests/components/seeed_mr24hpc1/common.yaml @@ -0,0 +1,92 @@ +uart: + - id: seeed_mr24hpc1_uart + tx_pin: ${uart_tx_pin} + rx_pin: ${uart_rx_pin} + baud_rate: 115200 + parity: NONE + stop_bits: 1 + +seeed_mr24hpc1: + id: my_seeed_mr24hpc1 + uart_id: seeed_mr24hpc1_uart + +sensor: + - platform: seeed_mr24hpc1 + custom_presence_of_detection: + name: "Static Distance" + movement_signs: + name: "Body Movement Parameter" + custom_motion_distance: + name: "Motion Distance" + custom_spatial_static_value: + name: "Existence Energy" + custom_spatial_motion_value: + name: "Motion Energy" + custom_motion_speed: + name: "Motion Speed" + custom_mode_num: + name: "Current Custom Mode" + +binary_sensor: + - platform: seeed_mr24hpc1 + has_target: + name: "Presence Information" + +switch: + - platform: seeed_mr24hpc1 + underlying_open_function: + name: Underlying Open Function Info Output Switch + +text_sensor: + - platform: seeed_mr24hpc1 + heart_beat: + name: "Heartbeat" + product_model: + name: "Product Model" + product_id: + name: "Product ID" + hardware_model: + name: "Hardware Model" + hardware_version: + name: "Hardware Version" + keep_away: + name: "Active Reporting Of Proximity" + motion_status: + name: "Motion Information" + custom_mode_end: + name: "Custom Mode Status" + +number: + - platform: seeed_mr24hpc1 + sensitivity: + name: "Sensitivity" + custom_mode: + name: "Custom Mode" + existence_threshold: + name: "Existence Energy Threshold" + motion_threshold: + name: "Motion Energy Threshold" + motion_trigger: + name: "Motion Trigger Time" + motion_to_rest: + name: "Motion To Rest Time" + custom_unman_time: + name: "Time For Entering No Person State (Underlying Open Function)" + +select: + - platform: seeed_mr24hpc1 + scene_mode: + name: "Scene" + unman_time: + name: "Time For Entering No Person State (Standard Function)" + existence_boundary: + name: "Existence Boundary" + motion_boundary: + name: "Motion Boundary" + +button: + - platform: seeed_mr24hpc1 + restart: + name: "Module Restart" + custom_set_end: + name: "End Of Custom Mode Settings" diff --git a/tests/components/seeed_mr24hpc1/test.esp32-c3-idf.yaml b/tests/components/seeed_mr24hpc1/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..4fb884abf4 --- /dev/null +++ b/tests/components/seeed_mr24hpc1/test.esp32-c3-idf.yaml @@ -0,0 +1,5 @@ +substitutions: + uart_tx_pin: GPIO5 + uart_rx_pin: GPIO4 + +<<: !include common.yaml diff --git a/tests/components/seeed_mr24hpc1/test.esp32-c3.yaml b/tests/components/seeed_mr24hpc1/test.esp32-c3.yaml new file mode 100644 index 0000000000..4fb884abf4 --- /dev/null +++ b/tests/components/seeed_mr24hpc1/test.esp32-c3.yaml @@ -0,0 +1,5 @@ +substitutions: + uart_tx_pin: GPIO5 + uart_rx_pin: GPIO4 + +<<: !include common.yaml From b0a192d6a5ae8d79b70dfa1ccc7edf2bd2706b2c Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Tue, 12 Mar 2024 15:26:31 +1100 Subject: [PATCH 088/189] Add getter for font glyph data (#6355) --- esphome/components/font/font.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esphome/components/font/font.h b/esphome/components/font/font.h index 91bcd399ba..57002cf510 100644 --- a/esphome/components/font/font.h +++ b/esphome/components/font/font.h @@ -30,6 +30,8 @@ class Glyph { void scan_area(int *x1, int *y1, int *width, int *height) const; + const GlyphData *get_glyph_data() const { return this->glyph_data_; } + protected: friend Font; From f5b02056b95a4d3af6b854e714d0657ce65f93cd Mon Sep 17 00:00:00 2001 From: Manuel Kasper Date: Tue, 12 Mar 2024 11:35:29 +0100 Subject: [PATCH 089/189] Require reset_pin for certain waveshare_epaper models in YAML validation (#6357) --- esphome/components/waveshare_epaper/display.py | 11 +++++++++++ .../waveshare_epaper/test.esp32.yaml | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/esphome/components/waveshare_epaper/display.py b/esphome/components/waveshare_epaper/display.py index 744ae8848f..dc43cbf5a7 100644 --- a/esphome/components/waveshare_epaper/display.py +++ b/esphome/components/waveshare_epaper/display.py @@ -131,6 +131,8 @@ MODELS = { "1.54in-m5coreink-m09": ("c", GDEW0154M09), } +RESET_PIN_REQUIRED_MODELS = ("2.13inv2", "2.13in-ttgo-b74") + def validate_full_update_every_only_types_ac(value): if CONF_FULL_UPDATE_EVERY not in value: @@ -147,6 +149,14 @@ def validate_full_update_every_only_types_ac(value): return value +def validate_reset_pin_required(config): + if config[CONF_MODEL] in RESET_PIN_REQUIRED_MODELS and CONF_RESET_PIN not in config: + raise cv.Invalid( + f"'{CONF_RESET_PIN}' is required for model {config[CONF_MODEL]}" + ) + return config + + CONFIG_SCHEMA = cv.All( display.FULL_DISPLAY_SCHEMA.extend( { @@ -165,6 +175,7 @@ CONFIG_SCHEMA = cv.All( .extend(cv.polling_component_schema("1s")) .extend(spi.spi_device_schema()), validate_full_update_every_only_types_ac, + validate_reset_pin_required, cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA), ) diff --git a/tests/components/waveshare_epaper/test.esp32.yaml b/tests/components/waveshare_epaper/test.esp32.yaml index 616698f902..cc6c665e7d 100644 --- a/tests/components/waveshare_epaper/test.esp32.yaml +++ b/tests/components/waveshare_epaper/test.esp32.yaml @@ -28,6 +28,24 @@ display: full_update_every: 30 lambda: |- it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + model: 2.13in-ttgo-b74 + spi_id: spi_id_1 + cs_pin: + allow_other_uses: true + number: GPIO25 + dc_pin: + allow_other_uses: true + number: GPIO26 + busy_pin: + allow_other_uses: true + number: GPIO27 + reset_pin: + allow_other_uses: true + number: GPIO32 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); - platform: waveshare_epaper model: 2.90in spi_id: spi_id_1 From f264151537729625b86a62d2b34a85781abc8443 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Wed, 13 Mar 2024 05:20:16 +1100 Subject: [PATCH 090/189] touchscreen driver fixes (#6356) --- .../ft5x06/touchscreen/ft5x06_touchscreen.h | 2 +- esphome/components/touchscreen/touchscreen.cpp | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.h b/esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.h index 0a1e51227d..7ddd2e44d7 100644 --- a/esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.h +++ b/esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.h @@ -71,7 +71,7 @@ class FT5x06Touchscreen : public touchscreen::Touchscreen, public i2c::I2CDevice this->x_raw_max_ = this->display_->get_native_width(); } if (this->y_raw_max_ == this->y_raw_min_) { - this->x_raw_max_ = this->display_->get_native_height(); + this->y_raw_max_ = this->display_->get_native_height(); } } esph_log_config(TAG, "FT5x06 Touchscreen setup complete"); diff --git a/esphome/components/touchscreen/touchscreen.cpp b/esphome/components/touchscreen/touchscreen.cpp index 83783a634f..b9498de152 100644 --- a/esphome/components/touchscreen/touchscreen.cpp +++ b/esphome/components/touchscreen/touchscreen.cpp @@ -39,7 +39,6 @@ void Touchscreen::loop() { ESP_LOGVV(TAG, "<< Do Touch loop >>"); this->first_touch_ = this->touches_.empty(); this->need_update_ = false; - this->was_touched_ = this->is_touched_; this->is_touched_ = false; this->skip_update_ = false; for (auto &tp : this->touches_) { @@ -62,7 +61,11 @@ void Touchscreen::loop() { if (this->touch_timeout_ > 0) { // Simulate a touch after touch_timeout_> ms. This will reset any existing timeout operation. // This is to detect touch release. - this->set_timeout(TAG, this->touch_timeout_, [this]() { this->store_.touched = true; }); + if (this->is_touched_) { + this->set_timeout(TAG, this->touch_timeout_, [this]() { this->store_.touched = true; }); + } else { + this->cancel_timeout(TAG); + } } } } @@ -111,6 +114,7 @@ void Touchscreen::add_raw_touch_position_(uint8_t id, int16_t x_raw, int16_t y_r void Touchscreen::send_touches_() { TouchPoints_t touches; + ESP_LOGV(TAG, "Touch status: is_touched=%d, was_touched=%d", this->is_touched_, this->was_touched_); for (auto tp : this->touches_) { ESP_LOGV(TAG, "Touch status: %d/%d: raw:(%4d,%4d,%4d) calc:(%3d,%4d)", tp.second.id, tp.second.state, tp.second.x_raw, tp.second.y_raw, tp.second.z_raw, tp.second.x, tp.second.y); @@ -124,14 +128,10 @@ void Touchscreen::send_touches_() { } if (!this->is_touched_) { if (this->was_touched_) { - if (this->touch_timeout_ > 0) { - this->cancel_timeout(TAG); - } this->release_trigger_.trigger(); for (auto *listener : this->touch_listeners_) listener->release(); this->touches_.clear(); - this->was_touched_ = false; } } else { if (this->first_touch_) { @@ -142,6 +142,7 @@ void Touchscreen::send_touches_() { } } } + this->was_touched_ = this->is_touched_; } int16_t Touchscreen::normalize_(int16_t val, int16_t min_val, int16_t max_val, bool inverted) { From d3a028f7fa4174ab6d2e5fbb10e4374454480124 Mon Sep 17 00:00:00 2001 From: M-A Date: Tue, 12 Mar 2024 16:22:28 -0400 Subject: [PATCH 091/189] Make USE_HOST compilable on msys2 (#6359) --- esphome/core/helpers.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index cec8a82d04..0f7afc6a4e 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -12,9 +12,11 @@ #include #ifdef USE_HOST +#ifndef _WIN32 #include #include #include +#endif #include #endif #if defined(USE_ESP8266) From 2df9c30446f471e8754beeb89b2e45ca57e1c786 Mon Sep 17 00:00:00 2001 From: Landon Rohatensky Date: Tue, 12 Mar 2024 16:07:40 -0700 Subject: [PATCH 092/189] download font from url on build (#5254) Co-authored-by: guillempages Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Co-authored-by: clydebarrow <2366188+clydebarrow@users.noreply.github.com> --- esphome/components/font/__init__.py | 145 +++++++++++++++++++------- esphome/external_files.py | 4 +- tests/components/font/test.esp32.yaml | 11 ++ tests/test2.yaml | 5 - 4 files changed, 122 insertions(+), 43 deletions(-) diff --git a/esphome/components/font/__init__.py b/esphome/components/font/__init__.py index 6473ef53dc..76eb05e6ad 100644 --- a/esphome/components/font/__init__.py +++ b/esphome/components/font/__init__.py @@ -1,13 +1,15 @@ +import hashlib +import logging + import functools from pathlib import Path -import hashlib import os import re from packaging import version - import requests from esphome import core +from esphome import external_files import esphome.config_validation as cv import esphome.codegen as cg from esphome.helpers import ( @@ -15,21 +17,26 @@ from esphome.helpers import ( cpp_string_escape, ) from esphome.const import ( + __version__, CONF_FAMILY, CONF_FILE, CONF_GLYPHS, CONF_ID, CONF_RAW_DATA_ID, CONF_TYPE, + CONF_REFRESH, CONF_SIZE, CONF_PATH, CONF_WEIGHT, + CONF_URL, ) from esphome.core import ( CORE, HexInt, ) +_LOGGER = logging.getLogger(__name__) + DOMAIN = "font" DEPENDENCIES = ["display"] MULTI_CONF = True @@ -125,20 +132,10 @@ def validate_truetype_file(value): return cv.file_(value) -def _compute_local_font_dir(name) -> Path: - h = hashlib.new("sha256") - h.update(name.encode()) - return Path(CORE.data_dir) / DOMAIN / h.hexdigest()[:8] - - -def _compute_gfonts_local_path(value) -> Path: - name = f"{value[CONF_FAMILY]}@{value[CONF_WEIGHT]}@{value[CONF_ITALIC]}@v1" - return _compute_local_font_dir(name) / "font.ttf" - - TYPE_LOCAL = "local" TYPE_LOCAL_BITMAP = "local_bitmap" TYPE_GFONTS = "gfonts" +TYPE_WEB = "web" LOCAL_SCHEMA = cv.Schema( { cv.Required(CONF_PATH): validate_truetype_file, @@ -169,21 +166,64 @@ def validate_weight_name(value): return FONT_WEIGHTS[cv.one_of(*FONT_WEIGHTS, lower=True, space="-")(value)] -def download_gfonts(value): +def _compute_local_font_path(value: dict) -> Path: + url = value[CONF_URL] + h = hashlib.new("sha256") + h.update(url.encode()) + key = h.hexdigest()[:8] + base_dir = external_files.compute_local_file_dir(DOMAIN) + _LOGGER.debug("_compute_local_font_path: base_dir=%s", base_dir / key) + return base_dir / key + + +def get_font_path(value, type) -> Path: + if type == TYPE_GFONTS: + name = f"{value[CONF_FAMILY]}@{value[CONF_WEIGHT]}@{value[CONF_ITALIC]}@v1" + return external_files.compute_local_file_dir(DOMAIN) / f"{name}.ttf" + if type == TYPE_WEB: + return _compute_local_font_path(value) / "font.ttf" + return None + + +def download_content(url: str, path: Path) -> None: + if not external_files.has_remote_file_changed(url, path): + _LOGGER.debug("Remote file has not changed %s", url) + return + + _LOGGER.debug( + "Remote file has changed, downloading from %s to %s", + url, + path, + ) + + try: + req = requests.get( + url, + timeout=external_files.NETWORK_TIMEOUT, + headers={"User-agent": f"ESPHome/{__version__} (https://esphome.io)"}, + ) + req.raise_for_status() + except requests.exceptions.RequestException as e: + raise cv.Invalid(f"Could not download from {url}: {e}") + + path.parent.mkdir(parents=True, exist_ok=True) + path.write_bytes(req.content) + + +def download_gfont(value): name = ( f"{value[CONF_FAMILY]}:ital,wght@{int(value[CONF_ITALIC])},{value[CONF_WEIGHT]}" ) url = f"https://fonts.googleapis.com/css2?family={name}" + path = get_font_path(value, TYPE_GFONTS) + _LOGGER.debug("download_gfont: path=%s", path) - path = _compute_gfonts_local_path(value) - if path.is_file(): - return value try: - req = requests.get(url, timeout=30) + req = requests.get(url, timeout=external_files.NETWORK_TIMEOUT) req.raise_for_status() except requests.exceptions.RequestException as e: raise cv.Invalid( - f"Could not download font for {name}, please check the fonts exists " + f"Could not download font at {url}, please check the fonts exists " f"at google fonts ({e})" ) match = re.search(r"src:\s+url\((.+)\)\s+format\('truetype'\);", req.text) @@ -194,26 +234,48 @@ def download_gfonts(value): ) ttf_url = match.group(1) - try: - req = requests.get(ttf_url, timeout=30) - req.raise_for_status() - except requests.exceptions.RequestException as e: - raise cv.Invalid(f"Could not download ttf file for {name} ({ttf_url}): {e}") + _LOGGER.debug("download_gfont: ttf_url=%s", ttf_url) - path.parent.mkdir(exist_ok=True, parents=True) - path.write_bytes(req.content) + download_content(ttf_url, path) return value -GFONTS_SCHEMA = cv.All( +def download_web_font(value): + url = value[CONF_URL] + path = get_font_path(value, TYPE_WEB) + + download_content(url, path) + _LOGGER.debug("download_web_font: path=%s", path) + return value + + +EXTERNAL_FONT_SCHEMA = cv.Schema( { - cv.Required(CONF_FAMILY): cv.string_strict, cv.Optional(CONF_WEIGHT, default="regular"): cv.Any( cv.int_, validate_weight_name ), cv.Optional(CONF_ITALIC, default=False): cv.boolean, - }, - download_gfonts, + cv.Optional(CONF_REFRESH, default="1d"): cv.All(cv.string, cv.source_refresh), + } +) + + +GFONTS_SCHEMA = cv.All( + EXTERNAL_FONT_SCHEMA.extend( + { + cv.Required(CONF_FAMILY): cv.string_strict, + } + ), + download_gfont, +) + +WEB_FONT_SCHEMA = cv.All( + EXTERNAL_FONT_SCHEMA.extend( + { + cv.Required(CONF_URL): cv.string_strict, + } + ), + download_web_font, ) @@ -233,6 +295,14 @@ def validate_file_shorthand(value): data[CONF_WEIGHT] = weight[1:] return FILE_SCHEMA(data) + if value.startswith("http://") or value.startswith("https://"): + return FILE_SCHEMA( + { + CONF_TYPE: TYPE_WEB, + CONF_URL: value, + } + ) + if value.endswith(".pcf") or value.endswith(".bdf"): return FILE_SCHEMA( { @@ -254,6 +324,7 @@ TYPED_FILE_SCHEMA = cv.typed_schema( TYPE_LOCAL: LOCAL_SCHEMA, TYPE_GFONTS: GFONTS_SCHEMA, TYPE_LOCAL_BITMAP: LOCAL_BITMAP_SCHEMA, + TYPE_WEB: WEB_FONT_SCHEMA, } ) @@ -264,7 +335,7 @@ def _file_schema(value): return TYPED_FILE_SCHEMA(value) -FILE_SCHEMA = cv.Schema(_file_schema) +FILE_SCHEMA = cv.All(_file_schema) DEFAULT_GLYPHS = ( ' !"%()+=,-.:/?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz°' @@ -288,7 +359,7 @@ FONT_SCHEMA = cv.Schema( ), cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_id(cg.uint8), cv.GenerateID(CONF_RAW_GLYPH_ID): cv.declare_id(GlyphData), - } + }, ) CONFIG_SCHEMA = cv.All(validate_pillow_installed, FONT_SCHEMA, merge_glyphs) @@ -343,8 +414,8 @@ class EFont: elif ftype == TYPE_LOCAL: path = CORE.relative_config_path(file[CONF_PATH]) font = load_ttf_font(path, size) - elif ftype == TYPE_GFONTS: - path = _compute_gfonts_local_path(file) + elif ftype in (TYPE_GFONTS, TYPE_WEB): + path = get_font_path(file, ftype) font = load_ttf_font(path, size) else: raise cv.Invalid(f"Could not load font: unknown type: {ftype}") @@ -361,9 +432,9 @@ def convert_bitmap_to_pillow_font(filepath): BdfFontFile, ) - local_bitmap_font_file = _compute_local_font_dir(filepath) / os.path.basename( - filepath - ) + local_bitmap_font_file = external_files.compute_local_file_dir( + DOMAIN, + ) / os.path.basename(filepath) copy_file_if_changed(filepath, local_bitmap_font_file) diff --git a/esphome/external_files.py b/esphome/external_files.py index 5b476286f3..a1422d02b1 100644 --- a/esphome/external_files.py +++ b/esphome/external_files.py @@ -33,7 +33,9 @@ def has_remote_file_changed(url, local_file_path): IF_MODIFIED_SINCE: local_modification_time_str, CACHE_CONTROL: CACHE_CONTROL_MAX_AGE + "3600", } - response = requests.head(url, headers=headers, timeout=NETWORK_TIMEOUT) + response = requests.head( + url, headers=headers, timeout=NETWORK_TIMEOUT, allow_redirects=True + ) _LOGGER.debug( "has_remote_file_changed: File %s, Local modified %s, response code %d", diff --git a/tests/components/font/test.esp32.yaml b/tests/components/font/test.esp32.yaml index 9d699a1752..d142463893 100644 --- a/tests/components/font/test.esp32.yaml +++ b/tests/components/font/test.esp32.yaml @@ -6,6 +6,17 @@ font: extras: - file: "gfonts://Roboto" glyphs: ["\u00C4", "\u00C5", "\U000000C7"] + - file: "gfonts://Roboto" + id: roboto_web + size: 20 + - file: "https://github.com/IdreesInc/Monocraft/releases/download/v3.0/Monocraft.ttf" + id: monocraft + size: 20 + - file: + type: web + url: "https://github.com/IdreesInc/Monocraft/releases/download/v3.0/Monocraft.ttf" + id: monocraft2 + size: 24 spi: clk_pin: 14 diff --git a/tests/test2.yaml b/tests/test2.yaml index 217a4c8feb..a1e310be9c 100644 --- a/tests/test2.yaml +++ b/tests/test2.yaml @@ -812,11 +812,6 @@ image: file: mdi:alert-outline type: BINARY -font: - - file: "gfonts://Roboto" - id: roboto - size: 20 - graph: - id: my_graph sensor: ha_hello_world_temperature From c7305e15a7a5181cce3db77ba9842afcceb7cfa5 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Wed, 13 Mar 2024 10:14:57 +1100 Subject: [PATCH 093/189] Add driver for quad SPI AMOLED displays (#6354) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- CODEOWNERS | 1 + esphome/components/qspi_amoled/__init__.py | 1 + esphome/components/qspi_amoled/display.py | 131 ++++++++++++++ .../components/qspi_amoled/qspi_amoled.cpp | 165 ++++++++++++++++++ esphome/components/qspi_amoled/qspi_amoled.h | 165 ++++++++++++++++++ .../qspi_amoled/test.esp32-s3-idf.yaml | 36 ++++ 6 files changed, 499 insertions(+) create mode 100644 esphome/components/qspi_amoled/__init__.py create mode 100644 esphome/components/qspi_amoled/display.py create mode 100644 esphome/components/qspi_amoled/qspi_amoled.cpp create mode 100644 esphome/components/qspi_amoled/qspi_amoled.h create mode 100644 tests/components/qspi_amoled/test.esp32-s3-idf.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 64005b1a81..483672bf54 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -269,6 +269,7 @@ esphome/components/pvvx_mithermometer/* @pasiz esphome/components/pylontech/* @functionpointer esphome/components/qmp6988/* @andrewpc esphome/components/qr_code/* @wjtje +esphome/components/qspi_amoled/* @clydebarrow esphome/components/qwiic_pir/* @kahrendt esphome/components/radon_eye_ble/* @jeffeb3 esphome/components/radon_eye_rd200/* @jeffeb3 diff --git a/esphome/components/qspi_amoled/__init__.py b/esphome/components/qspi_amoled/__init__.py new file mode 100644 index 0000000000..c58ce8a01e --- /dev/null +++ b/esphome/components/qspi_amoled/__init__.py @@ -0,0 +1 @@ +CODEOWNERS = ["@clydebarrow"] diff --git a/esphome/components/qspi_amoled/display.py b/esphome/components/qspi_amoled/display.py new file mode 100644 index 0000000000..84bf9553cb --- /dev/null +++ b/esphome/components/qspi_amoled/display.py @@ -0,0 +1,131 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome import pins +from esphome.components import ( + spi, + display, +) +from esphome.const import ( + CONF_RESET_PIN, + CONF_ID, + CONF_DIMENSIONS, + CONF_WIDTH, + CONF_HEIGHT, + CONF_LAMBDA, + CONF_BRIGHTNESS, + CONF_ENABLE_PIN, + CONF_MODEL, + CONF_OFFSET_HEIGHT, + CONF_OFFSET_WIDTH, + CONF_INVERT_COLORS, + CONF_MIRROR_X, + CONF_MIRROR_Y, + CONF_SWAP_XY, + CONF_COLOR_ORDER, + CONF_TRANSFORM, +) + +DEPENDENCIES = ["spi"] + +qspi_amoled_ns = cg.esphome_ns.namespace("qspi_amoled") +QSPI_AMOLED = qspi_amoled_ns.class_( + "QspiAmoLed", display.Display, display.DisplayBuffer, cg.Component, spi.SPIDevice +) +ColorOrder = display.display_ns.enum("ColorMode") +Model = qspi_amoled_ns.enum("Model") + +MODELS = {"RM690B0": Model.RM690B0, "RM67162": Model.RM67162} + +COLOR_ORDERS = { + "RGB": ColorOrder.COLOR_ORDER_RGB, + "BGR": ColorOrder.COLOR_ORDER_BGR, +} +DATA_PIN_SCHEMA = pins.internal_gpio_output_pin_schema + +CONFIG_SCHEMA = cv.All( + display.FULL_DISPLAY_SCHEMA.extend( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(QSPI_AMOLED), + cv.Required(CONF_MODEL): cv.enum(MODELS, upper=True), + cv.Required(CONF_DIMENSIONS): cv.Any( + cv.dimensions, + cv.Schema( + { + cv.Required(CONF_WIDTH): cv.int_, + cv.Required(CONF_HEIGHT): cv.int_, + cv.Optional(CONF_OFFSET_HEIGHT, default=0): cv.int_, + cv.Optional(CONF_OFFSET_WIDTH, default=0): cv.int_, + } + ), + ), + cv.Optional(CONF_TRANSFORM): cv.Schema( + { + cv.Optional(CONF_MIRROR_X, default=False): cv.boolean, + cv.Optional(CONF_MIRROR_Y, default=False): cv.boolean, + cv.Optional(CONF_SWAP_XY, default=False): cv.boolean, + } + ), + cv.Optional(CONF_COLOR_ORDER, default="RGB"): cv.enum( + COLOR_ORDERS, upper=True + ), + cv.Optional(CONF_INVERT_COLORS, default=False): cv.boolean, + cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema, + cv.Optional(CONF_ENABLE_PIN): pins.gpio_output_pin_schema, + cv.Optional(CONF_BRIGHTNESS, default=0xD0): cv.int_range( + 0, 0xFF, min_included=True, max_included=True + ), + } + ).extend( + spi.spi_device_schema( + cs_pin_required=False, + default_mode="MODE0", + default_data_rate=10e6, + quad=True, + ) + ) + ), + cv.only_with_esp_idf, +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await display.register_display(var, config) + await spi.register_spi_device(var, config) + + cg.add(var.set_color_mode(config[CONF_COLOR_ORDER])) + cg.add(var.set_invert_colors(config[CONF_INVERT_COLORS])) + cg.add(var.set_brightness(config[CONF_BRIGHTNESS])) + cg.add(var.set_model(config[CONF_MODEL])) + if enable_pin := config.get(CONF_ENABLE_PIN): + enable = await cg.gpio_pin_expression(enable_pin) + cg.add(var.set_enable_pin(enable)) + + if reset_pin := config.get(CONF_RESET_PIN): + reset = await cg.gpio_pin_expression(reset_pin) + cg.add(var.set_reset_pin(reset)) + + if transform := config.get(CONF_TRANSFORM): + cg.add(var.set_mirror_x(transform[CONF_MIRROR_X])) + cg.add(var.set_mirror_y(transform[CONF_MIRROR_Y])) + cg.add(var.set_swap_xy(transform[CONF_SWAP_XY])) + + if CONF_DIMENSIONS in config: + dimensions = config[CONF_DIMENSIONS] + if isinstance(dimensions, dict): + cg.add(var.set_dimensions(dimensions[CONF_WIDTH], dimensions[CONF_HEIGHT])) + cg.add( + var.set_offsets( + dimensions[CONF_OFFSET_WIDTH], dimensions[CONF_OFFSET_HEIGHT] + ) + ) + else: + (width, height) = dimensions + cg.add(var.set_dimensions(width, height)) + + if lamb := config.get(CONF_LAMBDA): + lambda_ = await cg.process_lambda( + lamb, [(display.DisplayRef, "it")], return_type=cg.void + ) + cg.add(var.set_writer(lambda_)) diff --git a/esphome/components/qspi_amoled/qspi_amoled.cpp b/esphome/components/qspi_amoled/qspi_amoled.cpp new file mode 100644 index 0000000000..697989e861 --- /dev/null +++ b/esphome/components/qspi_amoled/qspi_amoled.cpp @@ -0,0 +1,165 @@ +#ifdef USE_ESP_IDF +#include "qspi_amoled.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace qspi_amoled { + +void QspiAmoLed::setup() { + esph_log_config(TAG, "Setting up QSPI_AMOLED"); + this->spi_setup(); + if (this->enable_pin_ != nullptr) { + this->enable_pin_->setup(); + this->enable_pin_->digital_write(true); + } + if (this->reset_pin_ != nullptr) { + this->reset_pin_->setup(); + this->reset_pin_->digital_write(true); + delay(5); + this->reset_pin_->digital_write(false); + delay(5); + this->reset_pin_->digital_write(true); + } + this->set_timeout(120, [this] { this->write_command_(SLEEP_OUT); }); + this->set_timeout(240, [this] { this->write_init_sequence_(); }); +} + +void QspiAmoLed::update() { + this->do_update_(); + int w = this->x_high_ - this->x_low_ + 1; + int h = this->y_high_ - this->y_low_ + 1; + this->draw_pixels_at(this->x_low_, this->y_low_, w, h, this->buffer_, this->color_mode_, display::COLOR_BITNESS_565, + true, this->x_low_, this->y_low_, this->get_width_internal() - w - this->x_low_); + // invalidate watermarks + this->x_low_ = this->width_; + this->y_low_ = this->height_; + this->x_high_ = 0; + this->y_high_ = 0; +} + +void QspiAmoLed::draw_absolute_pixel_internal(int x, int y, Color color) { + if (x >= this->get_width_internal() || x < 0 || y >= this->get_height_internal() || y < 0) { + return; + } + if (this->buffer_ == nullptr) + this->init_internal_(this->width_ * this->height_ * 2); + if (this->is_failed()) + return; + uint32_t pos = (y * this->width_) + x; + uint16_t new_color; + bool updated = false; + pos = pos * 2; + new_color = display::ColorUtil::color_to_565(color, display::ColorOrder::COLOR_ORDER_RGB); + if (this->buffer_[pos] != (uint8_t) (new_color >> 8)) { + this->buffer_[pos] = (uint8_t) (new_color >> 8); + updated = true; + } + pos = pos + 1; + new_color = new_color & 0xFF; + + if (this->buffer_[pos] != new_color) { + this->buffer_[pos] = new_color; + updated = true; + } + if (updated) { + // low and high watermark may speed up drawing from buffer + if (x < this->x_low_) + this->x_low_ = x; + if (y < this->y_low_) + this->y_low_ = y; + if (x > this->x_high_) + this->x_high_ = x; + if (y > this->y_high_) + this->y_high_ = y; + } +} + +void QspiAmoLed::reset_params_(bool ready) { + if (!ready && !this->is_ready()) + return; + this->write_command_(this->invert_colors_ ? INVERT_ON : INVERT_OFF); + // custom x/y transform and color order + uint8_t mad = this->color_mode_ == display::COLOR_ORDER_BGR ? MADCTL_BGR : MADCTL_RGB; + if (this->swap_xy_) + mad |= MADCTL_MV; + if (this->mirror_x_) + mad |= MADCTL_MX; + if (this->mirror_y_) + mad |= MADCTL_MY; + this->write_command_(MADCTL_CMD, &mad, 1); + this->write_command_(BRIGHTNESS, &this->brightness_, 1); +} + +void QspiAmoLed::write_init_sequence_() { + if (this->model_ == RM690B0) { + this->write_command_(PAGESEL, 0x20); + this->write_command_(MIPI, 0x0A); + this->write_command_(WRAM, 0x80); + this->write_command_(SWIRE1, 0x51); + this->write_command_(SWIRE2, 0x2E); + this->write_command_(PAGESEL, 0x00); + this->write_command_(0xC2, 0x00); + delay(10); + this->write_command_(TEON, 0x00); + } + this->write_command_(PIXFMT, 0x55); + this->write_command_(BRIGHTNESS, 0); + this->write_command_(DISPLAY_ON); + this->reset_params_(true); + this->setup_complete_ = true; + esph_log_config(TAG, "QSPI_AMOLED setup complete"); +} + +void QspiAmoLed::set_addr_window_(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { + uint8_t buf[4]; + x1 += this->offset_x_; + x2 += this->offset_x_; + y1 += this->offset_y_; + y2 += this->offset_y_; + put16_be(buf, x1); + put16_be(buf + 2, x2); + this->write_command_(CASET, buf, sizeof buf); + put16_be(buf, y1); + put16_be(buf + 2, y2); + this->write_command_(RASET, buf, sizeof buf); +} + +void QspiAmoLed::draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order, + display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) { + if (!this->setup_complete_ || this->is_failed()) + return; + if (w <= 0 || h <= 0) + return; + if (bitness != display::COLOR_BITNESS_565 || order != this->color_mode_ || + big_endian != (this->bit_order_ == spi::BIT_ORDER_MSB_FIRST)) { + return display::Display::draw_pixels_at(x_start, y_start, w, h, ptr, order, bitness, big_endian, x_offset, y_offset, + x_pad); + } + this->set_addr_window_(x_start, y_start, x_start + w - 1, y_start + h - 1); + this->enable(); + // x_ and y_offset are offsets into the source buffer, unrelated to our own offsets into the display. + if (x_offset == 0 && x_pad == 0 && y_offset == 0) { + // we could deal here with a non-zero y_offset, but if x_offset is zero, y_offset probably will be so don't bother + this->write_cmd_addr_data(8, 0x32, 24, 0x2C00, ptr, w * h * 2, 4); + } else { + this->write_cmd_addr_data(8, 0x32, 24, 0x2C00, nullptr, 0, 4); + auto stride = x_offset + w + x_pad; + for (int y = 0; y != h; y++) { + this->write_cmd_addr_data(0, 0, 0, 0, ptr + ((y + y_offset) * stride + x_offset) * 2, w * 2, 4); + } + } + this->disable(); +} + +void QspiAmoLed::dump_config() { + ESP_LOGCONFIG("", "QSPI AMOLED"); + ESP_LOGCONFIG(TAG, " Height: %u", this->height_); + ESP_LOGCONFIG(TAG, " Width: %u", this->width_); + LOG_PIN(" CS Pin: ", this->cs_); + LOG_PIN(" Reset Pin: ", this->reset_pin_); + ESP_LOGCONFIG(TAG, " SPI Data rate: %dMHz", (unsigned) (this->data_rate_ / 1000000)); +} + +} // namespace qspi_amoled +} // namespace esphome +#endif diff --git a/esphome/components/qspi_amoled/qspi_amoled.h b/esphome/components/qspi_amoled/qspi_amoled.h new file mode 100644 index 0000000000..28d243f548 --- /dev/null +++ b/esphome/components/qspi_amoled/qspi_amoled.h @@ -0,0 +1,165 @@ +// +// Created by Clyde Stubbs on 29/10/2023. +// +#pragma once + +#ifdef USE_ESP_IDF +#include "esphome/core/component.h" +#include "esphome/components/spi/spi.h" +#include "esphome/components/display/display.h" +#include "esphome/components/display/display_buffer.h" +#include "esphome/components/display/display_color_utils.h" +#include "esp_lcd_panel_ops.h" + +#include "esp_lcd_panel_rgb.h" + +namespace esphome { +namespace qspi_amoled { + +constexpr static const char *const TAG = "display.qspi_amoled"; +static const uint8_t SW_RESET_CMD = 0x01; +static const uint8_t SLEEP_OUT = 0x11; +static const uint8_t INVERT_OFF = 0x20; +static const uint8_t INVERT_ON = 0x21; +static const uint8_t ALL_ON = 0x23; +static const uint8_t WRAM = 0x24; +static const uint8_t MIPI = 0x26; +static const uint8_t DISPLAY_ON = 0x29; +static const uint8_t RASET = 0x2B; +static const uint8_t CASET = 0x2A; +static const uint8_t WDATA = 0x2C; +static const uint8_t TEON = 0x35; +static const uint8_t MADCTL_CMD = 0x36; +static const uint8_t PIXFMT = 0x3A; +static const uint8_t BRIGHTNESS = 0x51; +static const uint8_t SWIRE1 = 0x5A; +static const uint8_t SWIRE2 = 0x5B; +static const uint8_t PAGESEL = 0xFE; + +static const uint8_t MADCTL_MY = 0x80; ///< Bit 7 Bottom to top +static const uint8_t MADCTL_MX = 0x40; ///< Bit 6 Right to left +static const uint8_t MADCTL_MV = 0x20; ///< Bit 5 Reverse Mode +static const uint8_t MADCTL_RGB = 0x00; ///< Bit 3 Red-Green-Blue pixel order +static const uint8_t MADCTL_BGR = 0x08; ///< Bit 3 Blue-Green-Red pixel order + +// store a 16 bit value in a buffer, big endian. +static inline void put16_be(uint8_t *buf, uint16_t value) { + buf[0] = value >> 8; + buf[1] = value; +} + +enum Model { + RM690B0, + RM67162, +}; + +class QspiAmoLed : public display::DisplayBuffer, + public spi::SPIDevice { + public: + void set_model(Model model) { this->model_ = model; } + void update() override; + void setup() override; + display::ColorOrder get_color_mode() { return this->color_mode_; } + void set_color_mode(display::ColorOrder color_mode) { this->color_mode_ = color_mode; } + + void set_reset_pin(GPIOPin *reset_pin) { this->reset_pin_ = reset_pin; } + void set_enable_pin(GPIOPin *enable_pin) { this->enable_pin_ = enable_pin; } + void set_width(uint16_t width) { this->width_ = width; } + void set_dimensions(uint16_t width, uint16_t height) { + this->width_ = width; + this->height_ = height; + } + int get_width() override { return this->width_; } + int get_height() override { return this->height_; } + void set_invert_colors(bool invert_colors) { + this->invert_colors_ = invert_colors; + this->reset_params_(); + } + void set_mirror_x(bool mirror_x) { + this->mirror_x_ = mirror_x; + this->reset_params_(); + } + void set_mirror_y(bool mirror_y) { + this->mirror_y_ = mirror_y; + this->reset_params_(); + } + void set_swap_xy(bool swap_xy) { + this->swap_xy_ = swap_xy; + this->reset_params_(); + } + void set_brightness(uint8_t brightness) { + this->brightness_ = brightness; + this->reset_params_(); + } + void set_offsets(int16_t offset_x, int16_t offset_y) { + this->offset_x_ = offset_x; + this->offset_y_ = offset_y; + } + display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; } + void dump_config() override; + + int get_width_internal() override { return this->width_; } + int get_height_internal() override { return this->height_; } + bool can_proceed() override { return this->setup_complete_; } + + protected: + void draw_absolute_pixel_internal(int x, int y, Color color) override; + void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order, + display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) override; + /** + * the RM67162 in quad SPI mode seems to work like this (not in the datasheet, this is deduced from the + * sample code.) + * + * Immediately after enabling /CS send 4 bytes in single-dataline SPI mode: + * 0: either 0x2 or 0x32. The first indicates that any subsequent data bytes after the initial 4 will be + * sent in 1-dataline SPI. The second indicates quad mode. + * 1: 0x00 + * 2: The command (register address) byte. + * 3: 0x00 + * + * This is followed by zero or more data bytes in either 1-wire or 4-wire mode, depending on the first byte. + * At the conclusion of the write, de-assert /CS. + * + * @param cmd + * @param bytes + * @param len + */ + void write_command_(uint8_t cmd, const uint8_t *bytes, size_t len) { + this->enable(); + this->write_cmd_addr_data(8, 0x02, 24, cmd << 8, bytes, len); + this->disable(); + } + + void write_command_(uint8_t cmd, uint8_t data) { this->write_command_(cmd, &data, 1); } + void write_command_(uint8_t cmd) { this->write_command_(cmd, &cmd, 0); } + void reset_params_(bool ready = false); + void write_init_sequence_(); + void set_addr_window_(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); + + GPIOPin *reset_pin_{nullptr}; + GPIOPin *enable_pin_{nullptr}; + uint16_t x_low_{0}; + uint16_t y_low_{0}; + uint16_t x_high_{0}; + uint16_t y_high_{0}; + bool setup_complete_{}; + + bool invert_colors_{}; + display::ColorOrder color_mode_{display::COLOR_ORDER_BGR}; + size_t width_{}; + size_t height_{}; + int16_t offset_x_{0}; + int16_t offset_y_{0}; + bool swap_xy_{}; + bool mirror_x_{}; + bool mirror_y_{}; + uint8_t brightness_{0xD0}; + Model model_{RM690B0}; + + esp_lcd_panel_handle_t handle_{}; +}; + +} // namespace qspi_amoled +} // namespace esphome +#endif diff --git a/tests/components/qspi_amoled/test.esp32-s3-idf.yaml b/tests/components/qspi_amoled/test.esp32-s3-idf.yaml new file mode 100644 index 0000000000..01d1a63bcb --- /dev/null +++ b/tests/components/qspi_amoled/test.esp32-s3-idf.yaml @@ -0,0 +1,36 @@ +spi: + id: quad_spi + clk_pin: 15 + type: quad + data_pins: [14, 10, 16, 12] + +display: + - platform: qspi_amoled + model: RM690B0 + data_rate: 80MHz + spi_mode: mode0 + dimensions: + width: 450 + height: 600 + offset_width: 16 + color_order: rgb + invert_colors: false + brightness: 255 + cs_pin: 11 + reset_pin: 13 + enable_pin: 9 + + - platform: qspi_amoled + model: RM67162 + id: main_lcd + dimensions: + height: 240 + width: 536 + transform: + mirror_x: true + swap_xy: true + color_order: rgb + brightness: 255 + cs_pin: 6 + reset_pin: 17 + enable_pin: 38 From 77214a677b85266e319f81f30573bc3546f032d7 Mon Sep 17 00:00:00 2001 From: Sorin Iordachescu Date: Tue, 12 Mar 2024 23:17:06 +0000 Subject: [PATCH 094/189] ADE7953: Add the ability to use accumulating energy registers, more precise power reporting (#6311) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/components/ade7953_base/__init__.py | 5 +++ .../components/ade7953_base/ade7953_base.cpp | 43 +++++++++++++------ .../components/ade7953_base/ade7953_base.h | 4 ++ 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/esphome/components/ade7953_base/__init__.py b/esphome/components/ade7953_base/__init__.py index d4c18f8ffd..28014ef142 100644 --- a/esphome/components/ade7953_base/__init__.py +++ b/esphome/components/ade7953_base/__init__.py @@ -41,6 +41,7 @@ CONF_CURRENT_GAIN_A = "current_gain_a" CONF_CURRENT_GAIN_B = "current_gain_b" CONF_ACTIVE_POWER_GAIN_A = "active_power_gain_a" CONF_ACTIVE_POWER_GAIN_B = "active_power_gain_b" +CONF_USE_ACCUMULATED_ENERGY_REGISTERS = "use_accumulated_energy_registers" PGA_GAINS = { "1x": 0b000, "2x": 0b001, @@ -155,6 +156,7 @@ ADE7953_CONFIG_SCHEMA = cv.Schema( cv.Optional(CONF_ACTIVE_POWER_GAIN_B, default=0x400000): cv.hex_int_range( min=0x100000, max=0x800000 ), + cv.Optional(CONF_USE_ACCUMULATED_ENERGY_REGISTERS, default=False): cv.boolean, } ).extend(cv.polling_component_schema("60s")) @@ -174,6 +176,9 @@ async def register_ade7953(var, config): cg.add(var.set_bigain(config.get(CONF_CURRENT_GAIN_B))) cg.add(var.set_awgain(config.get(CONF_ACTIVE_POWER_GAIN_A))) cg.add(var.set_bwgain(config.get(CONF_ACTIVE_POWER_GAIN_B))) + cg.add( + var.set_use_acc_energy_regs(config.get(CONF_USE_ACCUMULATED_ENERGY_REGISTERS)) + ) for key in [ CONF_VOLTAGE, diff --git a/esphome/components/ade7953_base/ade7953_base.cpp b/esphome/components/ade7953_base/ade7953_base.cpp index af6fe0a5df..862f5567a8 100644 --- a/esphome/components/ade7953_base/ade7953_base.cpp +++ b/esphome/components/ade7953_base/ade7953_base.cpp @@ -6,6 +6,9 @@ namespace ade7953_base { static const char *const TAG = "ade7953"; +static const float ADE_POWER_FACTOR = 154.0f; +static const float ADE_WATTSEC_POWER_FACTOR = ADE_POWER_FACTOR * ADE_POWER_FACTOR / 3600; + void ADE7953::setup() { if (this->irq_pin_ != nullptr) { this->irq_pin_->setup(); @@ -34,6 +37,7 @@ void ADE7953::setup() { this->ade_read_32(BIGAIN_32, &bigain_); this->ade_read_32(AWGAIN_32, &awgain_); this->ade_read_32(BWGAIN_32, &bwgain_); + this->last_update_ = millis(); this->is_setup_ = true; }); } @@ -52,6 +56,7 @@ void ADE7953::dump_config() { LOG_SENSOR(" ", "Active Power B Sensor", this->active_power_b_sensor_); LOG_SENSOR(" ", "Rective Power A Sensor", this->reactive_power_a_sensor_); LOG_SENSOR(" ", "Reactive Power B Sensor", this->reactive_power_b_sensor_); + ESP_LOGCONFIG(TAG, " USE_ACC_ENERGY_REGS: %d", this->use_acc_energy_regs_); ESP_LOGCONFIG(TAG, " PGA_V_8: 0x%X", pga_v_); ESP_LOGCONFIG(TAG, " PGA_IA_8: 0x%X", pga_ia_); ESP_LOGCONFIG(TAG, " PGA_IB_8: 0x%X", pga_ib_); @@ -85,6 +90,7 @@ void ADE7953::update() { uint32_t val; uint16_t val_16; + uint16_t reg; // Power factor err = this->ade_read_16(0x010A, &val_16); @@ -92,23 +98,36 @@ void ADE7953::update() { err = this->ade_read_16(0x010B, &val_16); ADE_PUBLISH(power_factor_b, (int16_t) val_16, (0x7FFF / 100.0f)); + float pf = ADE_POWER_FACTOR; + if (this->use_acc_energy_regs_) { + const uint32_t now = millis(); + const auto diff = now - this->last_update_; + this->last_update_ = now; + // prevent DIV/0 + pf = ADE_WATTSEC_POWER_FACTOR * (diff < 10 ? 10 : diff) / 1000; + ESP_LOGVV(TAG, "ADE7953::update() diff=%d pf=%f", diff, pf); + } + // Apparent power - err = this->ade_read_32(0x0310, &val); - ADE_PUBLISH(apparent_power_a, (int32_t) val, 154.0f); - err = this->ade_read_32(0x0311, &val); - ADE_PUBLISH(apparent_power_b, (int32_t) val, 154.0f); + reg = this->use_acc_energy_regs_ ? 0x0322 : 0x0310; + err = this->ade_read_32(reg, &val); + ADE_PUBLISH(apparent_power_a, (int32_t) val, pf); + err = this->ade_read_32(reg + 1, &val); + ADE_PUBLISH(apparent_power_b, (int32_t) val, pf); // Active power - err = this->ade_read_32(0x0312, &val); - ADE_PUBLISH(active_power_a, (int32_t) val, 154.0f); - err = this->ade_read_32(0x0313, &val); - ADE_PUBLISH(active_power_b, (int32_t) val, 154.0f); + reg = this->use_acc_energy_regs_ ? 0x031E : 0x0312; + err = this->ade_read_32(reg, &val); + ADE_PUBLISH(active_power_a, (int32_t) val, pf); + err = this->ade_read_32(reg + 1, &val); + ADE_PUBLISH(active_power_b, (int32_t) val, pf); // Reactive power - err = this->ade_read_32(0x0314, &val); - ADE_PUBLISH(reactive_power_a, (int32_t) val, 154.0f); - err = this->ade_read_32(0x0315, &val); - ADE_PUBLISH(reactive_power_b, (int32_t) val, 154.0f); + reg = this->use_acc_energy_regs_ ? 0x0320 : 0x0314; + err = this->ade_read_32(reg, &val); + ADE_PUBLISH(reactive_power_a, (int32_t) val, pf); + err = this->ade_read_32(reg + 1, &val); + ADE_PUBLISH(reactive_power_b, (int32_t) val, pf); // Current err = this->ade_read_32(0x031A, &val); diff --git a/esphome/components/ade7953_base/ade7953_base.h b/esphome/components/ade7953_base/ade7953_base.h index f57a8aa1df..d711a5c6be 100644 --- a/esphome/components/ade7953_base/ade7953_base.h +++ b/esphome/components/ade7953_base/ade7953_base.h @@ -52,6 +52,8 @@ class ADE7953 : public PollingComponent, public sensor::Sensor { void set_awgain(uint32_t awgain) { awgain_ = awgain; } void set_bwgain(uint32_t bwgain) { bwgain_ = bwgain; } + void set_use_acc_energy_regs(bool use_acc_energy_regs) { use_acc_energy_regs_ = use_acc_energy_regs; } + void set_voltage_sensor(sensor::Sensor *voltage_sensor) { voltage_sensor_ = voltage_sensor; } void set_frequency_sensor(sensor::Sensor *frequency_sensor) { frequency_sensor_ = frequency_sensor; } @@ -103,6 +105,8 @@ class ADE7953 : public PollingComponent, public sensor::Sensor { uint32_t bigain_; uint32_t awgain_; uint32_t bwgain_; + bool use_acc_energy_regs_{false}; + uint32_t last_update_; virtual bool ade_write_8(uint16_t reg, uint8_t value) = 0; From 3abf2f1d1489608f9304ea7ccbd49f28fa8e208d Mon Sep 17 00:00:00 2001 From: Mark Spicer Date: Tue, 12 Mar 2024 21:04:59 -0400 Subject: [PATCH 095/189] feat: Add HTU31D Support (#5805) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- CODEOWNERS | 1 + esphome/components/htu31d/__init__.py | 1 + esphome/components/htu31d/htu31d.cpp | 269 ++++++++++++++++++++ esphome/components/htu31d/htu31d.h | 33 +++ esphome/components/htu31d/sensor.py | 56 ++++ tests/components/htu31d/common.yaml | 9 + tests/components/htu31d/test.esp32-idf.yaml | 1 + tests/components/htu31d/test.esp32.yaml | 1 + tests/components/htu31d/test.esp8266.yaml | 1 + 9 files changed, 372 insertions(+) create mode 100644 esphome/components/htu31d/__init__.py create mode 100644 esphome/components/htu31d/htu31d.cpp create mode 100644 esphome/components/htu31d/htu31d.h create mode 100644 esphome/components/htu31d/sensor.py create mode 100644 tests/components/htu31d/common.yaml create mode 100644 tests/components/htu31d/test.esp32-idf.yaml create mode 100644 tests/components/htu31d/test.esp32.yaml create mode 100644 tests/components/htu31d/test.esp8266.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 483672bf54..c8d2a579d1 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -152,6 +152,7 @@ esphome/components/honeywellabp2_i2c/* @jpfaff esphome/components/host/* @esphome/core esphome/components/hrxl_maxsonar_wr/* @netmikey esphome/components/hte501/* @Stock-M +esphome/components/htu31d/* @betterengineering esphome/components/hydreon_rgxx/* @functionpointer esphome/components/hyt271/* @Philippe12 esphome/components/i2c/* @esphome/core diff --git a/esphome/components/htu31d/__init__.py b/esphome/components/htu31d/__init__.py new file mode 100644 index 0000000000..039693cb30 --- /dev/null +++ b/esphome/components/htu31d/__init__.py @@ -0,0 +1 @@ +CODEOWNERS = ["@betterengineering"] diff --git a/esphome/components/htu31d/htu31d.cpp b/esphome/components/htu31d/htu31d.cpp new file mode 100644 index 0000000000..928250a5b2 --- /dev/null +++ b/esphome/components/htu31d/htu31d.cpp @@ -0,0 +1,269 @@ +/* + * This file contains source code derived from Adafruit_HTU31D which is under + * the BSD license: + * Written by Limor Fried/Ladyada for Adafruit Industries. + * BSD license, all text above must be included in any redistribution. + * + * Modifications made by Mark Spicer. + */ + +#include "htu31d.h" +#include "esphome/core/hal.h" +#include "esphome/core/helpers.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace htu31d { + +/** Logging prefix */ +static const char *const TAG = "htu31d"; + +/** Default I2C address for the HTU31D. */ +static const uint8_t HTU31D_DEFAULT_I2CADDR = 0x40; + +/** Read temperature and humidity. */ +static const uint8_t HTU31D_READTEMPHUM = 0x00; + +/** Start a conversion! */ +static const uint8_t HTU31D_CONVERSION = 0x40; + +/** Read serial number command. */ +static const uint8_t HTU31D_READSERIAL = 0x0A; + +/** Enable heater */ +static const uint8_t HTU31D_HEATERON = 0x04; + +/** Disable heater */ +static const uint8_t HTU31D_HEATEROFF = 0x02; + +/** Reset command. */ +static const uint8_t HTU31D_RESET = 0x1E; + +/** Diagnostics command. */ +static const uint8_t HTU31D_DIAGNOSTICS = 0x08; + +/** + * Computes a CRC result for the provided input. + * + * @returns the computed CRC result for the provided input + */ +uint8_t compute_crc(uint32_t value) { + uint32_t polynom = 0x98800000; // x^8 + x^5 + x^4 + 1 + uint32_t msb = 0x80000000; + uint32_t mask = 0xFF800000; + uint32_t threshold = 0x00000080; + uint32_t result = value; + + while (msb != threshold) { + // Check if msb of current value is 1 and apply XOR mask + if (result & msb) + result = ((result ^ polynom) & mask) | (result & ~mask); + + // Shift by one + msb >>= 1; + mask >>= 1; + polynom >>= 1; + } + + return result; +} + +/** + * Resets the sensor and ensures that the devices serial number can be read over + * I2C. + */ +void HTU31DComponent::setup() { + ESP_LOGCONFIG(TAG, "Setting up esphome/components/htu31d HTU31D..."); + + if (!this->reset_()) { + this->mark_failed(); + return; + } + + if (this->read_serial_num_() == 0) { + this->mark_failed(); + return; + } +} + +/** + * Called once every update interval (user configured, defaults to 60s) and sets + * the current temperature and humidity. + */ +void HTU31DComponent::update() { + ESP_LOGD(TAG, "Checking temperature and humidty values"); + + // Trigger a conversion. From the spec sheet: The conversion command triggers + // a single temperature and humidity conversion. + if (this->write_register(HTU31D_CONVERSION, nullptr, 0) != i2c::ERROR_OK) { + this->status_set_warning(); + ESP_LOGE(TAG, "Received errror writing conversion register"); + return; + } + + // Wait conversion time. + this->set_timeout(20, [this]() { + uint8_t thdata[6]; + if (this->read_register(HTU31D_READTEMPHUM, thdata, 6) != i2c::ERROR_OK) { + this->status_set_warning(); + ESP_LOGE(TAG, "Error reading temperature/humidty register"); + return; + } + + // Calculate temperature value. + uint16_t raw_temp = encode_uint16(thdata[0], thdata[1]); + + uint8_t crc = compute_crc((uint32_t) raw_temp << 8); + if (crc != thdata[2]) { + this->status_set_warning(); + ESP_LOGE(TAG, "Error validating temperature CRC"); + return; + } + + float temperature = raw_temp; + temperature /= 65535.0f; + temperature *= 165; + temperature -= 40; + + if (this->temperature_ != nullptr) { + this->temperature_->publish_state(temperature); + } + + // Calculate humidty value. + uint16_t raw_hum = encode_uint16(thdata[3], thdata[4]); + + crc = compute_crc((uint32_t) raw_hum << 8); + if (crc != thdata[5]) { + this->status_set_warning(); + ESP_LOGE(TAG, "Error validating humidty CRC"); + return; + } + + float humidity = raw_hum; + humidity /= 65535.0f; + humidity *= 100; + + if (this->humidity_ != nullptr) { + this->humidity_->publish_state(humidity); + } + + ESP_LOGD(TAG, "Got Temperature=%.1f°C Humidity=%.1f%%", temperature, humidity); + this->status_clear_warning(); + }); +} + +/** + * Logs the current compoenent config. + */ +void HTU31DComponent::dump_config() { + ESP_LOGCONFIG(TAG, "HTU31D:"); + LOG_I2C_DEVICE(this); + if (this->is_failed()) { + ESP_LOGE(TAG, "Communication with HTU31D failed!"); + } + LOG_UPDATE_INTERVAL(this); + LOG_SENSOR(" ", "Temperature", this->temperature_); + LOG_SENSOR(" ", "Humidity", this->humidity_); +} + +/** + * Sends a 'reset' request to the HTU31D, followed by a 15ms delay. + * + * @returns True if was able to write the command successfully + */ +bool HTU31DComponent::reset_() { + if (this->write_register(HTU31D_RESET, nullptr, 0) != i2c::ERROR_OK) { + return false; + } + + delay(15); + return true; +} + +/** + * Reads the serial number from the device and checks the CRC. + * + * @returns the 24bit serial number from the device + */ +uint32_t HTU31DComponent::read_serial_num_() { + uint8_t reply[4]; + uint32_t serial = 0; + uint8_t padding = 0; + + // Verify we can read the device serial. + if (this->read_register(HTU31D_READSERIAL, reply, 4) != i2c::ERROR_OK) { + ESP_LOGE(TAG, "Error reading device serial"); + return 0; + } + + serial = encode_uint32(reply[0], reply[1], reply[2], padding); + + uint8_t crc = compute_crc(serial); + if (crc != reply[3]) { + ESP_LOGE(TAG, "Error validating serial CRC"); + return 0; + } + + ESP_LOGD(TAG, "Found serial: 0x%X", serial); + + return serial; +} + +/** + * Checks the diagnostics register to determine if the heater is currently + * enabled. + * + * @returns True if the heater is currently enabled, False otherwise + */ +bool HTU31DComponent::is_heater_enabled() { + uint8_t reply[1]; + uint8_t heater_enabled_position = 0; + uint8_t mask = 1 << heater_enabled_position; + uint8_t diagnostics = 0; + + if (this->read_register(HTU31D_DIAGNOSTICS, reply, 1) != i2c::ERROR_OK) { + ESP_LOGE(TAG, "Error reading device serial"); + return false; + } + + diagnostics = reply[0]; + return (diagnostics & mask) != 0; +} + +/** + * Sets the heater state on or off. + * + * @param desired True for on, and False for off. + */ +void HTU31DComponent::set_heater_state(bool desired) { + bool current = this->is_heater_enabled(); + + // If the current state matches the desired state, there is nothing to do. + if (current == desired) { + return; + } + + // Update heater state. + esphome::i2c::ErrorCode err; + if (desired) { + err = this->write_register(HTU31D_HEATERON, nullptr, 0); + } else { + err = this->write_register(HTU31D_HEATEROFF, nullptr, 0); + } + + // Record any error. + if (err != i2c::ERROR_OK) { + this->status_set_warning(); + ESP_LOGE(TAG, "Received error updating heater state"); + return; + } +} + +/** + * Sets the startup priority for this component. + * + * @returns The startup priority + */ +float HTU31DComponent::get_setup_priority() const { return setup_priority::DATA; } +} // namespace htu31d +} // namespace esphome diff --git a/esphome/components/htu31d/htu31d.h b/esphome/components/htu31d/htu31d.h new file mode 100644 index 0000000000..9462133ced --- /dev/null +++ b/esphome/components/htu31d/htu31d.h @@ -0,0 +1,33 @@ +#pragma once + +#include "esphome/components/i2c/i2c.h" +#include "esphome/components/sensor/sensor.h" +#include "esphome/core/automation.h" +#include "esphome/core/component.h" + +namespace esphome { +namespace htu31d { + +class HTU31DComponent : public PollingComponent, public i2c::I2CDevice { + public: + void setup() override; /// Setup (reset) the sensor and check connection. + void update() override; /// Update the sensor values (temperature+humidity). + void dump_config() override; /// Dumps the configuration values. + + void set_temperature(sensor::Sensor *temperature) { this->temperature_ = temperature; } + void set_humidity(sensor::Sensor *humidity) { this->humidity_ = humidity; } + + void set_heater_state(bool desired); + bool is_heater_enabled(); + + float get_setup_priority() const override; + + protected: + bool reset_(); + uint32_t read_serial_num_(); + + sensor::Sensor *temperature_{nullptr}; + sensor::Sensor *humidity_{nullptr}; +}; +} // namespace htu31d +} // namespace esphome diff --git a/esphome/components/htu31d/sensor.py b/esphome/components/htu31d/sensor.py new file mode 100644 index 0000000000..fe53aa376e --- /dev/null +++ b/esphome/components/htu31d/sensor.py @@ -0,0 +1,56 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import i2c, sensor +from esphome.const import ( + CONF_HUMIDITY, + CONF_ID, + CONF_TEMPERATURE, + DEVICE_CLASS_HUMIDITY, + DEVICE_CLASS_TEMPERATURE, + STATE_CLASS_MEASUREMENT, + UNIT_CELSIUS, + UNIT_PERCENT, +) + +DEPENDENCIES = ["i2c"] + +htu31d_ns = cg.esphome_ns.namespace("htu31d") +HTU31DComponent = htu31d_ns.class_( + "HTU31DComponent", cg.PollingComponent, i2c.I2CDevice +) + +CONFIG_SCHEMA = ( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(HTU31DComponent), + cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema( + unit_of_measurement=UNIT_CELSIUS, + accuracy_decimals=1, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_HUMIDITY): sensor.sensor_schema( + unit_of_measurement=UNIT_PERCENT, + accuracy_decimals=1, + device_class=DEVICE_CLASS_HUMIDITY, + state_class=STATE_CLASS_MEASUREMENT, + ), + } + ) + .extend(cv.polling_component_schema("60s")) + .extend(i2c.i2c_device_schema(0x40)) +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) + await i2c.register_i2c_device(var, config) + + if temperature_config := config.get(CONF_TEMPERATURE): + sens = await sensor.new_sensor(temperature_config) + cg.add(var.set_temperature(sens)) + + if humidity_config := config.get(CONF_HUMIDITY): + sens = await sensor.new_sensor(humidity_config) + cg.add(var.set_humidity(sens)) diff --git a/tests/components/htu31d/common.yaml b/tests/components/htu31d/common.yaml new file mode 100644 index 0000000000..c8ef2fede9 --- /dev/null +++ b/tests/components/htu31d/common.yaml @@ -0,0 +1,9 @@ +i2c: + +sensor: + - platform: htu31d + temperature: + name: Living Room Temperature 7 + humidity: + name: Living Room Humidity 7 + update_interval: 15s diff --git a/tests/components/htu31d/test.esp32-idf.yaml b/tests/components/htu31d/test.esp32-idf.yaml new file mode 100644 index 0000000000..dade44d145 --- /dev/null +++ b/tests/components/htu31d/test.esp32-idf.yaml @@ -0,0 +1 @@ +<<: !include common.yaml diff --git a/tests/components/htu31d/test.esp32.yaml b/tests/components/htu31d/test.esp32.yaml new file mode 100644 index 0000000000..dade44d145 --- /dev/null +++ b/tests/components/htu31d/test.esp32.yaml @@ -0,0 +1 @@ +<<: !include common.yaml diff --git a/tests/components/htu31d/test.esp8266.yaml b/tests/components/htu31d/test.esp8266.yaml new file mode 100644 index 0000000000..dade44d145 --- /dev/null +++ b/tests/components/htu31d/test.esp8266.yaml @@ -0,0 +1 @@ +<<: !include common.yaml From b34b10888bf89777dbc887e6b17601737ab35859 Mon Sep 17 00:00:00 2001 From: Ettore Beltrame <42470585+E440QF@users.noreply.github.com> Date: Wed, 13 Mar 2024 02:16:02 +0100 Subject: [PATCH 096/189] Emmeti infrared climate support (#5197) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- CODEOWNERS | 1 + esphome/components/emmeti/__init__.py | 0 esphome/components/emmeti/climate.py | 21 ++ esphome/components/emmeti/emmeti.cpp | 316 ++++++++++++++++++++ esphome/components/emmeti/emmeti.h | 109 +++++++ tests/components/emmeti/common.yaml | 14 + tests/components/emmeti/test.esp32-idf.yaml | 5 + tests/components/emmeti/test.esp32.yaml | 5 + tests/components/emmeti/test.esp8266.yaml | 5 + 9 files changed, 476 insertions(+) create mode 100644 esphome/components/emmeti/__init__.py create mode 100644 esphome/components/emmeti/climate.py create mode 100644 esphome/components/emmeti/emmeti.cpp create mode 100644 esphome/components/emmeti/emmeti.h create mode 100644 tests/components/emmeti/common.yaml create mode 100644 tests/components/emmeti/test.esp32-idf.yaml create mode 100644 tests/components/emmeti/test.esp32.yaml create mode 100644 tests/components/emmeti/test.esp8266.yaml diff --git a/CODEOWNERS b/CODEOWNERS index c8d2a579d1..0a94c254d2 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -103,6 +103,7 @@ esphome/components/duty_time/* @dudanov esphome/components/ee895/* @Stock-M esphome/components/ektf2232/touchscreen/* @jesserockz esphome/components/emc2101/* @ellull +esphome/components/emmeti/* @E440QF esphome/components/ens160/* @vincentscode esphome/components/ens210/* @itn3rd77 esphome/components/esp32/* @esphome/core diff --git a/esphome/components/emmeti/__init__.py b/esphome/components/emmeti/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/esphome/components/emmeti/climate.py b/esphome/components/emmeti/climate.py new file mode 100644 index 0000000000..36585061e6 --- /dev/null +++ b/esphome/components/emmeti/climate.py @@ -0,0 +1,21 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import climate_ir +from esphome.const import CONF_ID + +CODEOWNERS = ["@E440QF"] +AUTO_LOAD = ["climate_ir"] + +emmeti_ns = cg.esphome_ns.namespace("emmeti") +EmmetiClimate = emmeti_ns.class_("EmmetiClimate", climate_ir.ClimateIR) + +CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend( + { + cv.GenerateID(): cv.declare_id(EmmetiClimate), + } +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await climate_ir.register_climate_ir(var, config) diff --git a/esphome/components/emmeti/emmeti.cpp b/esphome/components/emmeti/emmeti.cpp new file mode 100644 index 0000000000..3cb184f868 --- /dev/null +++ b/esphome/components/emmeti/emmeti.cpp @@ -0,0 +1,316 @@ +#include "emmeti.h" +#include "esphome/components/remote_base/remote_base.h" + +namespace esphome { +namespace emmeti { + +static const char *const TAG = "emmeti.climate"; + +// setters +uint8_t EmmetiClimate::set_temp_() { + return (uint8_t) roundf(clamp(this->target_temperature, EMMETI_TEMP_MIN, EMMETI_TEMP_MAX) - EMMETI_TEMP_MIN); +} + +uint8_t EmmetiClimate::set_mode_() { + switch (this->mode) { + case climate::CLIMATE_MODE_COOL: + return EMMETI_MODE_COOL; + case climate::CLIMATE_MODE_DRY: + return EMMETI_MODE_DRY; + case climate::CLIMATE_MODE_HEAT: + return EMMETI_MODE_HEAT; + case climate::CLIMATE_MODE_FAN_ONLY: + return EMMETI_MODE_FAN; + case climate::CLIMATE_MODE_HEAT_COOL: + default: + return EMMETI_MODE_HEAT_COOL; + } +} + +uint8_t EmmetiClimate::set_fan_speed_() { + switch (this->fan_mode.value()) { + case climate::CLIMATE_FAN_LOW: + return EMMETI_FAN_1; + case climate::CLIMATE_FAN_MEDIUM: + return EMMETI_FAN_2; + case climate::CLIMATE_FAN_HIGH: + return EMMETI_FAN_3; + case climate::CLIMATE_FAN_AUTO: + default: + return EMMETI_FAN_AUTO; + } +} + +uint8_t EmmetiClimate::set_blades_() { + if (this->swing_mode == climate::CLIMATE_SWING_VERTICAL) { + switch (this->blades_) { + case EMMETI_BLADES_1: + case EMMETI_BLADES_2: + case EMMETI_BLADES_HIGH: + this->blades_ = EMMETI_BLADES_HIGH; + break; + case EMMETI_BLADES_3: + case EMMETI_BLADES_MID: + this->blades_ = EMMETI_BLADES_MID; + break; + case EMMETI_BLADES_4: + case EMMETI_BLADES_5: + case EMMETI_BLADES_LOW: + this->blades_ = EMMETI_BLADES_LOW; + break; + default: + this->blades_ = EMMETI_BLADES_FULL; + break; + } + } else { + switch (this->blades_) { + case EMMETI_BLADES_1: + case EMMETI_BLADES_2: + case EMMETI_BLADES_HIGH: + this->blades_ = EMMETI_BLADES_1; + break; + case EMMETI_BLADES_3: + case EMMETI_BLADES_MID: + this->blades_ = EMMETI_BLADES_3; + break; + case EMMETI_BLADES_4: + case EMMETI_BLADES_5: + case EMMETI_BLADES_LOW: + this->blades_ = EMMETI_BLADES_5; + break; + default: + this->blades_ = EMMETI_BLADES_STOP; + break; + } + } + return this->blades_; +} + +uint8_t EmmetiClimate::gen_checksum_() { return (this->set_temp_() + this->set_mode_() + 2) % 16; } + +// getters +float EmmetiClimate::get_temp_(uint8_t temp) { return (float) (temp + EMMETI_TEMP_MIN); } + +climate::ClimateMode EmmetiClimate::get_mode_(uint8_t mode) { + switch (mode) { + case EMMETI_MODE_COOL: + return climate::CLIMATE_MODE_COOL; + case EMMETI_MODE_DRY: + return climate::CLIMATE_MODE_DRY; + case EMMETI_MODE_HEAT: + return climate::CLIMATE_MODE_HEAT; + case EMMETI_MODE_HEAT_COOL: + return climate::CLIMATE_MODE_HEAT_COOL; + case EMMETI_MODE_FAN: + return climate::CLIMATE_MODE_FAN_ONLY; + default: + return climate::CLIMATE_MODE_HEAT_COOL; + } +} + +climate::ClimateFanMode EmmetiClimate::get_fan_speed_(uint8_t fan_speed) { + switch (fan_speed) { + case EMMETI_FAN_1: + return climate::CLIMATE_FAN_LOW; + case EMMETI_FAN_2: + return climate::CLIMATE_FAN_MEDIUM; + case EMMETI_FAN_3: + return climate::CLIMATE_FAN_HIGH; + case EMMETI_FAN_AUTO: + default: + return climate::CLIMATE_FAN_AUTO; + } +} + +climate::ClimateSwingMode EmmetiClimate::get_swing_(uint8_t bitmap) { + return (bitmap >> 1) & 0x01 ? climate::CLIMATE_SWING_VERTICAL : climate::CLIMATE_SWING_OFF; +} + +template T EmmetiClimate::reverse_(T val, size_t len) { + T result = 0; + for (size_t i = 0; i < len; i++) { + result |= ((val & 1 << i) != 0) << (len - 1 - i); + } + return result; +} + +template void EmmetiClimate::add_(T val, size_t len, esphome::remote_base::RemoteTransmitData *data) { + for (size_t i = len; i > 0; i--) { + data->mark(EMMETI_BIT_MARK); + data->space((val & (1 << (i - 1))) ? EMMETI_ONE_SPACE : EMMETI_ZERO_SPACE); + } +} + +template void EmmetiClimate::add_(T val, esphome::remote_base::RemoteTransmitData *data) { + data->mark(EMMETI_BIT_MARK); + data->space((val & 1) ? EMMETI_ONE_SPACE : EMMETI_ZERO_SPACE); +} + +template +void EmmetiClimate::reverse_add_(T val, size_t len, esphome::remote_base::RemoteTransmitData *data) { + this->add_(this->reverse_(val, len), len, data); +} + +bool EmmetiClimate::check_checksum_(uint8_t checksum) { + uint8_t expected = this->gen_checksum_(); + ESP_LOGV(TAG, "Expected checksum: %X", expected); + ESP_LOGV(TAG, "Checksum received: %X", checksum); + + return checksum == expected; +} + +void EmmetiClimate::transmit_state() { + auto transmit = this->transmitter_->transmit(); + auto *data = transmit.get_data(); + data->set_carrier_frequency(EMMETI_IR_FREQUENCY); + + data->mark(EMMETI_HEADER_MARK); + data->space(EMMETI_HEADER_SPACE); + + if (this->mode != climate::CLIMATE_MODE_OFF) { + this->reverse_add_(this->set_mode_(), 3, data); + this->add_(1, data); + this->reverse_add_(this->set_fan_speed_(), 2, data); + this->add_(this->swing_mode != climate::CLIMATE_SWING_OFF, data); + this->add_(0, data); // sleep mode + this->reverse_add_(this->set_temp_(), 4, data); + this->add_(0, 8, data); // zeros + this->add_(0, data); // turbo mode + this->add_(1, data); // light + this->add_(1, data); // tree icon thingy + this->add_(0, data); // blow mode + this->add_(0x52, 11, data); // idk + + data->mark(EMMETI_BIT_MARK); + data->space(EMMETI_MESSAGE_SPACE); + + this->reverse_add_(this->set_blades_(), 4, data); + this->add_(0, 4, data); // zeros + this->reverse_add_(2, 2, data); // thermometer + this->add_(0, 18, data); // zeros + this->reverse_add_(this->gen_checksum_(), 4, data); + } else { + this->add_(9, 12, data); + this->add_(0, 8, data); + this->add_(0x2052, 15, data); + data->mark(EMMETI_BIT_MARK); + data->space(EMMETI_MESSAGE_SPACE); + this->add_(0, 8, data); + this->add_(1, 2, data); + this->add_(0, 18, data); + this->add_(0x0C, 4, data); + } + data->mark(EMMETI_BIT_MARK); + data->space(0); + + transmit.perform(); +} + +bool EmmetiClimate::parse_state_frame_(EmmetiState curr_state) { + this->mode = this->get_mode_(curr_state.mode); + this->fan_mode = this->get_fan_speed_(curr_state.fan_speed); + this->target_temperature = this->get_temp_(curr_state.temp); + this->swing_mode = this->get_swing_(curr_state.bitmap); + // this->blades_ = curr_state.fan_pos; + if (!(curr_state.bitmap & 0x01)) { + this->mode = climate::CLIMATE_MODE_OFF; + } + + this->publish_state(); + return true; +} + +bool EmmetiClimate::on_receive(remote_base::RemoteReceiveData data) { + if (!data.expect_item(EMMETI_HEADER_MARK, EMMETI_HEADER_SPACE)) { + return false; + } + ESP_LOGD(TAG, "Received emmeti frame"); + + EmmetiState curr_state; + + for (size_t pos = 0; pos < 3; pos++) { + if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) { + curr_state.mode |= 1 << pos; + } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) { + return false; + } + } + + ESP_LOGD(TAG, "Mode: %d", curr_state.mode); + + if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) { + curr_state.bitmap |= 1 << 0; + } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) { + return false; + } + + ESP_LOGD(TAG, "On: %d", curr_state.bitmap & 0x01); + + for (size_t pos = 0; pos < 2; pos++) { + if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) { + curr_state.fan_speed |= 1 << pos; + } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) { + return false; + } + } + + ESP_LOGD(TAG, "Fan speed: %d", curr_state.fan_speed); + + for (size_t pos = 0; pos < 2; pos++) { + if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) { + curr_state.bitmap |= 1 << (pos + 1); + } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) { + return false; + } + } + + ESP_LOGD(TAG, "Swing: %d", (curr_state.bitmap >> 1) & 0x01); + ESP_LOGD(TAG, "Sleep: %d", (curr_state.bitmap >> 2) & 0x01); + + for (size_t pos = 0; pos < 4; pos++) { + if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) { + curr_state.temp |= 1 << pos; + } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) { + return false; + } + } + + ESP_LOGD(TAG, "Temp: %d", curr_state.temp); + + for (size_t pos = 0; pos < 8; pos++) { + if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) { + return false; + } + } + + for (size_t pos = 0; pos < 4; pos++) { + if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) { + curr_state.bitmap |= 1 << (pos + 3); + } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) { + return false; + } + } + + ESP_LOGD(TAG, "Turbo: %d", (curr_state.bitmap >> 3) & 0x01); + ESP_LOGD(TAG, "Light: %d", (curr_state.bitmap >> 4) & 0x01); + ESP_LOGD(TAG, "Tree: %d", (curr_state.bitmap >> 5) & 0x01); + ESP_LOGD(TAG, "Blow: %d", (curr_state.bitmap >> 6) & 0x01); + + uint16_t control_data = 0; + for (size_t pos = 0; pos < 11; pos++) { + if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) { + control_data |= 1 << pos; + } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) { + return false; + } + } + + if (control_data != 0x250) { + return false; + } + + return this->parse_state_frame_(curr_state); +} + +} // namespace emmeti +} // namespace esphome diff --git a/esphome/components/emmeti/emmeti.h b/esphome/components/emmeti/emmeti.h new file mode 100644 index 0000000000..9bfb7a7a98 --- /dev/null +++ b/esphome/components/emmeti/emmeti.h @@ -0,0 +1,109 @@ +#pragma once + +#include "esphome/components/climate_ir/climate_ir.h" + +namespace esphome { +namespace emmeti { + +const uint8_t EMMETI_TEMP_MIN = 16; // Celsius +const uint8_t EMMETI_TEMP_MAX = 30; // Celsius + +// Modes + +enum EmmetiMode : uint8_t { + EMMETI_MODE_HEAT_COOL = 0x00, + EMMETI_MODE_COOL = 0x01, + EMMETI_MODE_DRY = 0x02, + EMMETI_MODE_FAN = 0x03, + EMMETI_MODE_HEAT = 0x04, +}; + +// Fan Speed + +enum EmmetiFanMode : uint8_t { + EMMETI_FAN_AUTO = 0x00, + EMMETI_FAN_1 = 0x01, + EMMETI_FAN_2 = 0x02, + EMMETI_FAN_3 = 0x03, +}; + +// Fan Position + +enum EmmetiBlades : uint8_t { + EMMETI_BLADES_STOP = 0x00, + EMMETI_BLADES_FULL = 0x01, + EMMETI_BLADES_1 = 0x02, + EMMETI_BLADES_2 = 0x03, + EMMETI_BLADES_3 = 0x04, + EMMETI_BLADES_4 = 0x05, + EMMETI_BLADES_5 = 0x06, + EMMETI_BLADES_LOW = 0x07, + EMMETI_BLADES_MID = 0x09, + EMMETI_BLADES_HIGH = 0x11, +}; + +// IR Transmission +const uint32_t EMMETI_IR_FREQUENCY = 38000; +const uint32_t EMMETI_HEADER_MARK = 9076; +const uint32_t EMMETI_HEADER_SPACE = 4408; +const uint32_t EMMETI_BIT_MARK = 660; +const uint32_t EMMETI_ONE_SPACE = 1630; +const uint32_t EMMETI_ZERO_SPACE = 530; +const uint32_t EMMETI_MESSAGE_SPACE = 20000; + +struct EmmetiState { + uint8_t mode = 0; + uint8_t bitmap = 0; + uint8_t fan_speed = 0; + uint8_t temp = 0; + uint8_t fan_pos = 0; + uint8_t th = 0; + uint8_t checksum = 0; +}; + +class EmmetiClimate : public climate_ir::ClimateIR { + public: + EmmetiClimate() + : climate_ir::ClimateIR(EMMETI_TEMP_MIN, EMMETI_TEMP_MAX, 1.0f, true, true, + {climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM, + climate::CLIMATE_FAN_HIGH}, + {climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL}) {} + + protected: + // Transmit via IR the state of this climate controller + void transmit_state() override; + // Handle received IR Buffer + bool on_receive(remote_base::RemoteReceiveData data) override; + bool parse_state_frame_(EmmetiState curr_state); + + // setters + uint8_t set_mode_(); + uint8_t set_temp_(); + uint8_t set_fan_speed_(); + uint8_t gen_checksum_(); + uint8_t set_blades_(); + + // getters + climate::ClimateMode get_mode_(uint8_t mode); + climate::ClimateFanMode get_fan_speed_(uint8_t fan); + void get_blades_(uint8_t fanpos); + // get swing + climate::ClimateSwingMode get_swing_(uint8_t bitmap); + float get_temp_(uint8_t temp); + + // check if the received frame is valid + bool check_checksum_(uint8_t checksum); + + template T reverse_(T val, size_t len); + + template void add_(T val, size_t len, esphome::remote_base::RemoteTransmitData *ata); + + template void add_(T val, esphome::remote_base::RemoteTransmitData *data); + + template void reverse_add_(T val, size_t len, esphome::remote_base::RemoteTransmitData *data); + + uint8_t blades_ = EMMETI_BLADES_STOP; +}; + +} // namespace emmeti +} // namespace esphome diff --git a/tests/components/emmeti/common.yaml b/tests/components/emmeti/common.yaml new file mode 100644 index 0000000000..ac4201e19b --- /dev/null +++ b/tests/components/emmeti/common.yaml @@ -0,0 +1,14 @@ +remote_transmitter: + id: tx + pin: ${remote_transmitter_pin} + carrier_duty_percent: 100% + +remote_receiver: + id: rcvr + pin: ${remote_receiver_pin} + +climate: + - platform: emmeti + name: Emmeti + receiver_id: rcvr + transmitter_id: tx diff --git a/tests/components/emmeti/test.esp32-idf.yaml b/tests/components/emmeti/test.esp32-idf.yaml new file mode 100644 index 0000000000..2689ff279e --- /dev/null +++ b/tests/components/emmeti/test.esp32-idf.yaml @@ -0,0 +1,5 @@ +substitutions: + remote_transmitter_pin: GPIO33 + remote_receiver_pin: GPIO32 + +<<: !include common.yaml diff --git a/tests/components/emmeti/test.esp32.yaml b/tests/components/emmeti/test.esp32.yaml new file mode 100644 index 0000000000..2689ff279e --- /dev/null +++ b/tests/components/emmeti/test.esp32.yaml @@ -0,0 +1,5 @@ +substitutions: + remote_transmitter_pin: GPIO33 + remote_receiver_pin: GPIO32 + +<<: !include common.yaml diff --git a/tests/components/emmeti/test.esp8266.yaml b/tests/components/emmeti/test.esp8266.yaml new file mode 100644 index 0000000000..2fb00aea61 --- /dev/null +++ b/tests/components/emmeti/test.esp8266.yaml @@ -0,0 +1,5 @@ +substitutions: + remote_transmitter_pin: GPIO4 + remote_receiver_pin: GPIO5 + +<<: !include common.yaml From 64a47f840eecc10e463ac678e51788ecba827546 Mon Sep 17 00:00:00 2001 From: Chris Feenstra <73584137+cfeenstra1024@users.noreply.github.com> Date: Wed, 13 Mar 2024 04:01:22 +0100 Subject: [PATCH 097/189] Added Kamstrup Multical 40x component (#4200) Co-authored-by: Chris Feenstra Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Co-authored-by: cfeenstra1024 --- CODEOWNERS | 1 + esphome/components/dfplayer/__init__.py | 3 +- esphome/components/ezo_pmp/__init__.py | 9 +- esphome/components/kamstrup_kmp/__init__.py | 0 .../components/kamstrup_kmp/kamstrup_kmp.cpp | 301 ++++++++++++++++++ .../components/kamstrup_kmp/kamstrup_kmp.h | 131 ++++++++ esphome/components/kamstrup_kmp/sensor.py | 132 ++++++++ esphome/components/media_player/__init__.py | 3 +- esphome/const.py | 1 + tests/components/kamstrup_kmp/common.yaml | 25 ++ .../kamstrup_kmp/test.esp32-idf.yaml | 5 + tests/components/kamstrup_kmp/test.esp32.yaml | 5 + .../components/kamstrup_kmp/test.esp8266.yaml | 5 + 13 files changed, 615 insertions(+), 6 deletions(-) create mode 100644 esphome/components/kamstrup_kmp/__init__.py create mode 100644 esphome/components/kamstrup_kmp/kamstrup_kmp.cpp create mode 100644 esphome/components/kamstrup_kmp/kamstrup_kmp.h create mode 100644 esphome/components/kamstrup_kmp/sensor.py create mode 100644 tests/components/kamstrup_kmp/common.yaml create mode 100644 tests/components/kamstrup_kmp/test.esp32-idf.yaml create mode 100644 tests/components/kamstrup_kmp/test.esp32.yaml create mode 100644 tests/components/kamstrup_kmp/test.esp8266.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 0a94c254d2..4c24096faa 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -173,6 +173,7 @@ esphome/components/integration/* @OttoWinter esphome/components/internal_temperature/* @Mat931 esphome/components/interval/* @esphome/core esphome/components/json/* @OttoWinter +esphome/components/kamstrup_kmp/* @cfeenstra1024 esphome/components/key_collector/* @ssieb esphome/components/key_provider/* @ssieb esphome/components/kuntze/* @ssieb diff --git a/esphome/components/dfplayer/__init__.py b/esphome/components/dfplayer/__init__.py index 5ea04b4804..c37c9999aa 100644 --- a/esphome/components/dfplayer/__init__.py +++ b/esphome/components/dfplayer/__init__.py @@ -1,7 +1,7 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome import automation -from esphome.const import CONF_ID, CONF_TRIGGER_ID, CONF_FILE, CONF_DEVICE +from esphome.const import CONF_ID, CONF_TRIGGER_ID, CONF_FILE, CONF_DEVICE, CONF_VOLUME from esphome.components import uart DEPENDENCIES = ["uart"] @@ -19,7 +19,6 @@ DFPlayerIsPlayingCondition = dfplayer_ns.class_( MULTI_CONF = True CONF_FOLDER = "folder" CONF_LOOP = "loop" -CONF_VOLUME = "volume" CONF_EQ_PRESET = "eq_preset" CONF_ON_FINISHED_PLAYBACK = "on_finished_playback" diff --git a/esphome/components/ezo_pmp/__init__.py b/esphome/components/ezo_pmp/__init__.py index e65fcf74ca..87cda41f89 100644 --- a/esphome/components/ezo_pmp/__init__.py +++ b/esphome/components/ezo_pmp/__init__.py @@ -1,7 +1,13 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome.components import i2c -from esphome.const import CONF_ADDRESS, CONF_COMMAND, CONF_ID, CONF_DURATION +from esphome.const import ( + CONF_ADDRESS, + CONF_COMMAND, + CONF_ID, + CONF_DURATION, + CONF_VOLUME, +) from esphome import automation from esphome.automation import maybe_simple_id @@ -9,7 +15,6 @@ CODEOWNERS = ["@carlos-sarmiento"] DEPENDENCIES = ["i2c"] MULTI_CONF = True -CONF_VOLUME = "volume" CONF_VOLUME_PER_MINUTE = "volume_per_minute" ezo_pmp_ns = cg.esphome_ns.namespace("ezo_pmp") diff --git a/esphome/components/kamstrup_kmp/__init__.py b/esphome/components/kamstrup_kmp/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/esphome/components/kamstrup_kmp/kamstrup_kmp.cpp b/esphome/components/kamstrup_kmp/kamstrup_kmp.cpp new file mode 100644 index 0000000000..b870d1b56d --- /dev/null +++ b/esphome/components/kamstrup_kmp/kamstrup_kmp.cpp @@ -0,0 +1,301 @@ +#include "kamstrup_kmp.h" + +#include "esphome/core/log.h" + +namespace esphome { +namespace kamstrup_kmp { + +static const char *const TAG = "kamstrup_kmp"; + +void KamstrupKMPComponent::dump_config() { + ESP_LOGCONFIG(TAG, "kamstrup_kmp:"); + if (this->is_failed()) { + ESP_LOGE(TAG, "Communication with Kamstrup meter failed!"); + } + LOG_UPDATE_INTERVAL(this); + + LOG_SENSOR(" ", "Heat Energy", this->heat_energy_sensor_); + LOG_SENSOR(" ", "Power", this->power_sensor_); + LOG_SENSOR(" ", "Temperature 1", this->temp1_sensor_); + LOG_SENSOR(" ", "Temperature 2", this->temp2_sensor_); + LOG_SENSOR(" ", "Temperature Difference", this->temp_diff_sensor_); + LOG_SENSOR(" ", "Flow", this->flow_sensor_); + LOG_SENSOR(" ", "Volume", this->volume_sensor_); + + for (int i = 0; i < this->custom_sensors_.size(); i++) { + LOG_SENSOR(" ", "Custom Sensor", this->custom_sensors_[i]); + ESP_LOGCONFIG(TAG, " Command: 0x%04X", this->custom_commands_[i]); + } + + this->check_uart_settings(1200, 2, uart::UART_CONFIG_PARITY_NONE, 8); +} + +float KamstrupKMPComponent::get_setup_priority() const { return setup_priority::DATA; } + +void KamstrupKMPComponent::update() { + if (this->heat_energy_sensor_ != nullptr) { + this->command_queue_.push(CMD_HEAT_ENERGY); + } + + if (this->power_sensor_ != nullptr) { + this->command_queue_.push(CMD_POWER); + } + + if (this->temp1_sensor_ != nullptr) { + this->command_queue_.push(CMD_TEMP1); + } + + if (this->temp2_sensor_ != nullptr) { + this->command_queue_.push(CMD_TEMP2); + } + + if (this->temp_diff_sensor_ != nullptr) { + this->command_queue_.push(CMD_TEMP_DIFF); + } + + if (this->flow_sensor_ != nullptr) { + this->command_queue_.push(CMD_FLOW); + } + + if (this->volume_sensor_ != nullptr) { + this->command_queue_.push(CMD_VOLUME); + } + + for (uint16_t custom_command : this->custom_commands_) { + this->command_queue_.push(custom_command); + } +} + +void KamstrupKMPComponent::loop() { + if (!this->command_queue_.empty()) { + uint16_t command = this->command_queue_.front(); + this->send_command_(command); + this->command_queue_.pop(); + } +} + +void KamstrupKMPComponent::send_command_(uint16_t command) { + uint32_t msg_len = 5; + uint8_t msg[msg_len]; + + msg[0] = 0x3F; + msg[1] = 0x10; + msg[2] = 0x01; + msg[3] = command >> 8; + msg[4] = command & 0xFF; + + this->clear_uart_rx_buffer_(); + this->send_message_(msg, msg_len); + this->read_command_(command); +} + +void KamstrupKMPComponent::send_message_(const uint8_t *msg, int msg_len) { + int buffer_len = msg_len + 2; + uint8_t buffer[buffer_len]; + + // Prepare the basic message and appand CRC + for (int i = 0; i < msg_len; i++) { + buffer[i] = msg[i]; + } + + buffer[buffer_len - 2] = 0; + buffer[buffer_len - 1] = 0; + + uint16_t crc = crc16_ccitt(buffer, buffer_len); + buffer[buffer_len - 2] = crc >> 8; + buffer[buffer_len - 1] = crc & 0xFF; + + // Prepare actual TX message + uint8_t tx_msg[20]; + int tx_msg_len = 1; + tx_msg[0] = 0x80; // prefix + + for (int i = 0; i < buffer_len; i++) { + if (buffer[i] == 0x06 || buffer[i] == 0x0d || buffer[i] == 0x1b || buffer[i] == 0x40 || buffer[i] == 0x80) { + tx_msg[tx_msg_len++] = 0x1b; + tx_msg[tx_msg_len++] = buffer[i] ^ 0xff; + } else { + tx_msg[tx_msg_len++] = buffer[i]; + } + } + + tx_msg[tx_msg_len++] = 0x0D; // EOM + + this->write_array(tx_msg, tx_msg_len); +} + +void KamstrupKMPComponent::clear_uart_rx_buffer_() { + uint8_t tmp; + while (this->available()) { + this->read_byte(&tmp); + } +} + +void KamstrupKMPComponent::read_command_(uint16_t command) { + uint8_t buffer[20] = {0}; + int buffer_len = 0; + int data; + int timeout = 250; // ms + + // Read the data from the UART + while (timeout > 0) { + if (this->available()) { + data = this->read(); + if (data > -1) { + if (data == 0x40) { // start of message + buffer_len = 0; + } + buffer[buffer_len++] = (uint8_t) data; + if (data == 0x0D) { + break; + } + } else { + ESP_LOGE(TAG, "Error while reading from UART"); + } + } else { + delay(1); + timeout--; + } + } + + if (timeout == 0 || buffer_len == 0) { + ESP_LOGE(TAG, "Request timed out"); + return; + } + + // Validate message (prefix and suffix) + if (buffer[0] != 0x40) { + ESP_LOGE(TAG, "Received invalid message (prefix mismatch received 0x%02X, expected 0x40)", buffer[0]); + return; + } + + if (buffer[buffer_len - 1] != 0x0D) { + ESP_LOGE(TAG, "Received invalid message (EOM mismatch received 0x%02X, expected 0x0D)", buffer[buffer_len - 1]); + return; + } + + // Decode + uint8_t msg[20] = {0}; + int msg_len = 0; + for (int i = 1; i < buffer_len - 1; i++) { + if (buffer[i] == 0x1B) { + msg[msg_len++] = buffer[i + 1] ^ 0xFF; + i++; + } else { + msg[msg_len++] = buffer[i]; + } + } + + // Validate CRC + if (crc16_ccitt(msg, msg_len)) { + ESP_LOGE(TAG, "Received invalid message (CRC mismatch)"); + return; + } + + // All seems good. Now parse the message + this->parse_command_message_(command, msg, msg_len); +} + +void KamstrupKMPComponent::parse_command_message_(uint16_t command, const uint8_t *msg, int msg_len) { + // Validate the message + if (msg_len < 8) { + ESP_LOGE(TAG, "Received invalid message (message too small)"); + return; + } + + if (msg[0] != 0x3F || msg[1] != 0x10) { + ESP_LOGE(TAG, "Received invalid message (invalid header received 0x%02X%02X, expected 0x3F10)", msg[0], msg[1]); + return; + } + + uint16_t recv_command = msg[2] << 8 | msg[3]; + if (recv_command != command) { + ESP_LOGE(TAG, "Received invalid message (invalid unexpected command received 0x%04X, expected 0x%04X)", + recv_command, command); + return; + } + + uint8_t unit_idx = msg[4]; + uint8_t mantissa_range = msg[5]; + + if (mantissa_range > 4) { + ESP_LOGE(TAG, "Received invalid message (mantissa size too large %d, expected 4)", mantissa_range); + return; + } + + // Calculate exponent + float exponent = msg[6] & 0x3F; + if (msg[6] & 0x40) { + exponent = -exponent; + } + exponent = powf(10, exponent); + if (msg[6] & 0x80) { + exponent = -exponent; + } + + // Calculate mantissa + uint32_t mantissa = 0; + for (int i = 0; i < mantissa_range; i++) { + mantissa <<= 8; + mantissa |= msg[i + 7]; + } + + // Calculate the actual value + float value = mantissa * exponent; + + // Set sensor value + this->set_sensor_value_(command, value, unit_idx); +} + +void KamstrupKMPComponent::set_sensor_value_(uint16_t command, float value, uint8_t unit_idx) { + const char *unit = UNITS[unit_idx]; + + // Standard sensors + if (command == CMD_HEAT_ENERGY && this->heat_energy_sensor_ != nullptr) { + this->heat_energy_sensor_->publish_state(value); + } else if (command == CMD_POWER && this->power_sensor_ != nullptr) { + this->power_sensor_->publish_state(value); + } else if (command == CMD_TEMP1 && this->temp1_sensor_ != nullptr) { + this->temp1_sensor_->publish_state(value); + } else if (command == CMD_TEMP2 && this->temp2_sensor_ != nullptr) { + this->temp2_sensor_->publish_state(value); + } else if (command == CMD_TEMP_DIFF && this->temp_diff_sensor_ != nullptr) { + this->temp_diff_sensor_->publish_state(value); + } else if (command == CMD_FLOW && this->flow_sensor_ != nullptr) { + this->flow_sensor_->publish_state(value); + } else if (command == CMD_VOLUME && this->volume_sensor_ != nullptr) { + this->volume_sensor_->publish_state(value); + } + + // Custom sensors + for (int i = 0; i < this->custom_commands_.size(); i++) { + if (command == this->custom_commands_[i]) { + this->custom_sensors_[i]->publish_state(value); + } + } + + ESP_LOGD(TAG, "Received value for command 0x%04X: %.3f [%s]", command, value, unit); +} + +uint16_t crc16_ccitt(const uint8_t *buffer, int len) { + uint32_t poly = 0x1021; + uint32_t reg = 0x00; + for (int i = 0; i < len; i++) { + int mask = 0x80; + while (mask > 0) { + reg <<= 1; + if (buffer[i] & mask) { + reg |= 1; + } + mask >>= 1; + if (reg & 0x10000) { + reg &= 0xffff; + reg ^= poly; + } + } + } + return (uint16_t) reg; +} + +} // namespace kamstrup_kmp +} // namespace esphome diff --git a/esphome/components/kamstrup_kmp/kamstrup_kmp.h b/esphome/components/kamstrup_kmp/kamstrup_kmp.h new file mode 100644 index 0000000000..c9cc9c5a39 --- /dev/null +++ b/esphome/components/kamstrup_kmp/kamstrup_kmp.h @@ -0,0 +1,131 @@ +#pragma once + +#include "esphome/components/sensor/sensor.h" +#include "esphome/components/uart/uart.h" +#include "esphome/core/component.h" + +namespace esphome { +namespace kamstrup_kmp { + +/* + =========================================================================== + === KAMSTRUP KMP === + =========================================================================== + + Kamstrup Meter Protocol (KMP) is a protocol used with Kamstrup district + heating meters, e.g. Kamstrup MULTICAL 403. + These devices register consumed heat from a district heating system. + It does this by measuring the incoming and outgoing water temperature + and by measuring the water flow. The temperature difference (delta T) + together with the water flow results in consumed energy, typically + in giga joule (GJ). + + The Kamstrup Multical has an optical interface just above the display. + This interface is essentially an RS-232 interface using a proprietary + protocol (Kamstrup Meter Protocol [KMP]). + + The integration uses this optical interface to periodically read the + configured values (sensors) from the meter. Supported sensors are: + - Heat Energy [GJ] + - Current Power Consumption [kW] + - Temperature 1 [°C] + - Temperature 2 [°C] + - Temperature Difference [°K] + - Water Flow [l/h] + - Volume [m3] + + Apart from these supported 'fixed' sensors, the user can configure up to + five custom sensors. The KMP command (16 bit unsigned int) has to be + provided in that case. + + Note: + The optical interface is enabled as soon as a button on the meter is pushed. + The interface stays active for a few minutes. To keep the interface 'alive' + magnets must be placed around the optical sensor. + + Units: + Units are set using the regular Sensor config in the user yaml. However, + KMP does also send the correct unit with every value. When DEBUG logging + is enabled, the received value with the received unit are logged. + + Acknowledgement: + This interface was inspired by: + - https://atomstar.tweakblogs.net/blog/19110/reading-out-kamstrup-multical-402-403-with-home-built-optical-head + - https://wiki.hal9k.dk/projects/kamstrup +*/ + +// KMP Commands +static const uint16_t CMD_HEAT_ENERGY = 0x003C; +static const uint16_t CMD_POWER = 0x0050; +static const uint16_t CMD_TEMP1 = 0x0056; +static const uint16_t CMD_TEMP2 = 0x0057; +static const uint16_t CMD_TEMP_DIFF = 0x0059; +static const uint16_t CMD_FLOW = 0x004A; +static const uint16_t CMD_VOLUME = 0x0044; + +// KMP units +static const char *const UNITS[] = { + "", "Wh", "kWh", "MWh", "GWh", "J", "kJ", "MJ", "GJ", "Cal", + "kCal", "Mcal", "Gcal", "varh", "kvarh", "Mvarh", "Gvarh", "VAh", "kVAh", "MVAh", + "GVAh", "kW", "kW", "MW", "GW", "kvar", "kvar", "Mvar", "Gvar", "VA", + "kVA", "MVA", "GVA", "V", "A", "kV", "kA", "C", "K", "l", + "m3", "l/h", "m3/h", "m3xC", "ton", "ton/h", "h", "hh:mm:ss", "yy:mm:dd", "yyyy:mm:dd", + "mm:dd", "", "bar", "RTC", "ASCII", "m3 x 10", "ton x 10", "GJ x 10", "minutes", "Bitfield", + "s", "ms", "days", "RTC-Q", "Datetime"}; + +class KamstrupKMPComponent : public PollingComponent, public uart::UARTDevice { + public: + void set_heat_energy_sensor(sensor::Sensor *sensor) { this->heat_energy_sensor_ = sensor; } + void set_power_sensor(sensor::Sensor *sensor) { this->power_sensor_ = sensor; } + void set_temp1_sensor(sensor::Sensor *sensor) { this->temp1_sensor_ = sensor; } + void set_temp2_sensor(sensor::Sensor *sensor) { this->temp2_sensor_ = sensor; } + void set_temp_diff_sensor(sensor::Sensor *sensor) { this->temp_diff_sensor_ = sensor; } + void set_flow_sensor(sensor::Sensor *sensor) { this->flow_sensor_ = sensor; } + void set_volume_sensor(sensor::Sensor *sensor) { this->volume_sensor_ = sensor; } + void dump_config() override; + float get_setup_priority() const override; + void update() override; + void loop() override; + void add_custom_sensor(sensor::Sensor *sensor, uint16_t command) { + this->custom_sensors_.push_back(sensor); + this->custom_commands_.push_back(command); + } + + protected: + // Sensors + sensor::Sensor *heat_energy_sensor_{nullptr}; + sensor::Sensor *power_sensor_{nullptr}; + sensor::Sensor *temp1_sensor_{nullptr}; + sensor::Sensor *temp2_sensor_{nullptr}; + sensor::Sensor *temp_diff_sensor_{nullptr}; + sensor::Sensor *flow_sensor_{nullptr}; + sensor::Sensor *volume_sensor_{nullptr}; + + // Custom sensors and commands + std::vector custom_sensors_; + std::vector custom_commands_; + + // Command queue + std::queue command_queue_; + + // Methods + + // Sends a command to the meter and receives its response + void send_command_(uint16_t command); + // Sends a message to the meter. A prefix/suffix and CRC are added + void send_message_(const uint8_t *msg, int msg_len); + // Clears and data that might be in the UART Rx buffer + void clear_uart_rx_buffer_(); + // Reads and validates the response to a send command + void read_command_(uint16_t command); + // Parses a received message + void parse_command_message_(uint16_t command, const uint8_t *msg, int msg_len); + // Sets the received value to the correct sensor + void set_sensor_value_(uint16_t command, float value, uint8_t unit_idx); +}; + +// "true" CCITT CRC-16 +uint16_t crc16_ccitt(const uint8_t *buffer, int len); + +} // namespace kamstrup_kmp +} // namespace esphome diff --git a/esphome/components/kamstrup_kmp/sensor.py b/esphome/components/kamstrup_kmp/sensor.py new file mode 100644 index 0000000000..c9024e4a2b --- /dev/null +++ b/esphome/components/kamstrup_kmp/sensor.py @@ -0,0 +1,132 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import sensor, uart +from esphome.const import ( + CONF_COMMAND, + CONF_CUSTOM, + CONF_FLOW, + CONF_ID, + CONF_POWER, + CONF_VOLUME, + DEVICE_CLASS_EMPTY, + DEVICE_CLASS_ENERGY, + DEVICE_CLASS_POWER, + DEVICE_CLASS_TEMPERATURE, + DEVICE_CLASS_VOLUME, + STATE_CLASS_MEASUREMENT, + STATE_CLASS_TOTAL_INCREASING, + UNIT_CELSIUS, + UNIT_CUBIC_METER, + UNIT_EMPTY, + UNIT_KELVIN, + UNIT_KILOWATT, +) + +CODEOWNERS = ["@cfeenstra1024"] +DEPENDENCIES = ["uart"] + +kamstrup_kmp_ns = cg.esphome_ns.namespace("kamstrup_kmp") +KamstrupKMPComponent = kamstrup_kmp_ns.class_( + "KamstrupKMPComponent", cg.PollingComponent, uart.UARTDevice +) + +CONF_HEAT_ENERGY = "heat_energy" +CONF_TEMP1 = "temp1" +CONF_TEMP2 = "temp2" +CONF_TEMP_DIFF = "temp_diff" + +UNIT_GIGA_JOULE = "GJ" +UNIT_LITRE_PER_HOUR = "l/h" + +# Note: The sensor units are set automatically based un the received data from the meter +CONFIG_SCHEMA = ( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(KamstrupKMPComponent), + cv.Optional(CONF_HEAT_ENERGY): sensor.sensor_schema( + accuracy_decimals=3, + device_class=DEVICE_CLASS_ENERGY, + state_class=STATE_CLASS_TOTAL_INCREASING, + unit_of_measurement=UNIT_GIGA_JOULE, + ), + cv.Optional(CONF_POWER): sensor.sensor_schema( + accuracy_decimals=3, + device_class=DEVICE_CLASS_POWER, + state_class=STATE_CLASS_MEASUREMENT, + unit_of_measurement=UNIT_KILOWATT, + ), + cv.Optional(CONF_TEMP1): sensor.sensor_schema( + accuracy_decimals=1, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + unit_of_measurement=UNIT_CELSIUS, + ), + cv.Optional(CONF_TEMP2): sensor.sensor_schema( + accuracy_decimals=1, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + unit_of_measurement=UNIT_CELSIUS, + ), + cv.Optional(CONF_TEMP_DIFF): sensor.sensor_schema( + accuracy_decimals=1, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + unit_of_measurement=UNIT_KELVIN, + ), + cv.Optional(CONF_FLOW): sensor.sensor_schema( + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLUME, + state_class=STATE_CLASS_MEASUREMENT, + unit_of_measurement=UNIT_LITRE_PER_HOUR, + ), + cv.Optional(CONF_VOLUME): sensor.sensor_schema( + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLUME, + state_class=STATE_CLASS_TOTAL_INCREASING, + unit_of_measurement=UNIT_CUBIC_METER, + ), + cv.Optional(CONF_CUSTOM): cv.ensure_list( + sensor.sensor_schema( + accuracy_decimals=1, + device_class=DEVICE_CLASS_EMPTY, + state_class=STATE_CLASS_MEASUREMENT, + unit_of_measurement=UNIT_EMPTY, + ).extend({cv.Required(CONF_COMMAND): cv.hex_uint16_t}) + ), + } + ) + .extend(cv.polling_component_schema("60s")) + .extend(uart.UART_DEVICE_SCHEMA) +) + +FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema( + "kamstrup_kmp", baud_rate=1200, require_rx=True, require_tx=True +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) + await uart.register_uart_device(var, config) + + # Standard sensors + for key in [ + CONF_HEAT_ENERGY, + CONF_POWER, + CONF_TEMP1, + CONF_TEMP2, + CONF_TEMP_DIFF, + CONF_FLOW, + CONF_VOLUME, + ]: + if key not in config: + continue + conf = config[key] + sens = await sensor.new_sensor(conf) + cg.add(getattr(var, f"set_{key}_sensor")(sens)) + + # Custom sensors + if CONF_CUSTOM in config: + for conf in config[CONF_CUSTOM]: + sens = await sensor.new_sensor(conf) + cg.add(var.add_custom_sensor(sens, conf[CONF_COMMAND])) diff --git a/esphome/components/media_player/__init__.py b/esphome/components/media_player/__init__.py index 80f5fc558a..86e038d76d 100644 --- a/esphome/components/media_player/__init__.py +++ b/esphome/components/media_player/__init__.py @@ -3,7 +3,7 @@ import esphome.config_validation as cv import esphome.codegen as cg from esphome.automation import maybe_simple_id -from esphome.const import CONF_ID, CONF_ON_STATE, CONF_TRIGGER_ID +from esphome.const import CONF_ID, CONF_ON_STATE, CONF_TRIGGER_ID, CONF_VOLUME from esphome.core import CORE from esphome.coroutine import coroutine_with_priority from esphome.cpp_helpers import setup_entity @@ -43,7 +43,6 @@ VolumeSetAction = media_player_ns.class_( ) -CONF_VOLUME = "volume" CONF_ON_IDLE = "on_idle" CONF_ON_PLAY = "on_play" CONF_ON_PAUSE = "on_pause" diff --git a/esphome/const.py b/esphome/const.py index 4e53970cdf..918cf94ed3 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -856,6 +856,7 @@ CONF_VISUAL = "visual" CONF_VOLTAGE = "voltage" CONF_VOLTAGE_ATTENUATION = "voltage_attenuation" CONF_VOLTAGE_DIVIDER = "voltage_divider" +CONF_VOLUME = "volume" CONF_WAIT_TIME = "wait_time" CONF_WAIT_UNTIL = "wait_until" CONF_WAKEUP_PIN = "wakeup_pin" diff --git a/tests/components/kamstrup_kmp/common.yaml b/tests/components/kamstrup_kmp/common.yaml new file mode 100644 index 0000000000..b348d03c72 --- /dev/null +++ b/tests/components/kamstrup_kmp/common.yaml @@ -0,0 +1,25 @@ +uart: + tx_pin: ${uart_tx_pin} + rx_pin: ${uart_rx_pin} + baud_rate: 1200 + stop_bits: 2 + +sensor: + - platform: kamstrup_kmp + heat_energy: + name: Heat Energy + power: + name: Power + temp1: + name: Temperature 1 + temp2: + name: Temperature 2 + temp_diff: + name: Temperature Difference + flow: + name: Flow + volume: + name: Volume + custom: + - name: Custom 1 + command: 0x1234 diff --git a/tests/components/kamstrup_kmp/test.esp32-idf.yaml b/tests/components/kamstrup_kmp/test.esp32-idf.yaml new file mode 100644 index 0000000000..adc2c4d24a --- /dev/null +++ b/tests/components/kamstrup_kmp/test.esp32-idf.yaml @@ -0,0 +1,5 @@ +substitutions: + uart_tx_pin: GPIO1 + uart_rx_pin: GPIO3 + +<<: !include common.yaml diff --git a/tests/components/kamstrup_kmp/test.esp32.yaml b/tests/components/kamstrup_kmp/test.esp32.yaml new file mode 100644 index 0000000000..adc2c4d24a --- /dev/null +++ b/tests/components/kamstrup_kmp/test.esp32.yaml @@ -0,0 +1,5 @@ +substitutions: + uart_tx_pin: GPIO1 + uart_rx_pin: GPIO3 + +<<: !include common.yaml diff --git a/tests/components/kamstrup_kmp/test.esp8266.yaml b/tests/components/kamstrup_kmp/test.esp8266.yaml new file mode 100644 index 0000000000..adc2c4d24a --- /dev/null +++ b/tests/components/kamstrup_kmp/test.esp8266.yaml @@ -0,0 +1,5 @@ +substitutions: + uart_tx_pin: GPIO1 + uart_rx_pin: GPIO3 + +<<: !include common.yaml From de436785254006cd84b490cefe2c55023ba75fc0 Mon Sep 17 00:00:00 2001 From: kev300 Date: Wed, 13 Mar 2024 04:25:38 +0100 Subject: [PATCH 098/189] =?UTF-8?q?add=20possibility=20to=20provide=20diff?= =?UTF-8?q?erent=20conversion=20times=20for=20Bus=20Voltage=E2=80=A6=20(#6?= =?UTF-8?q?327)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kevin Hübner --- esphome/components/ina226/ina226.cpp | 7 ++++--- esphome/components/ina226/ina226.h | 6 ++++-- esphome/components/ina226/sensor.py | 21 +++++++++++++++++++-- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/esphome/components/ina226/ina226.cpp b/esphome/components/ina226/ina226.cpp index 94016ad302..7a57c118af 100644 --- a/esphome/components/ina226/ina226.cpp +++ b/esphome/components/ina226/ina226.cpp @@ -55,10 +55,10 @@ void INA226Component::setup() { config.avg_samples = this->adc_avg_samples_; // Bus Voltage Conversion Time VBUSCT Bit Settings [8:6] (100 -> 1.1ms, 111 -> 8.244 ms) - config.bus_voltage_conversion_time = this->adc_time_; + config.bus_voltage_conversion_time = this->adc_time_voltage_; // Shunt Voltage Conversion Time VSHCT Bit Settings [5:3] (100 -> 1.1ms, 111 -> 8.244 ms) - config.shunt_voltage_conversion_time = this->adc_time_; + config.shunt_voltage_conversion_time = this->adc_time_current_; // Mode Settings [2:0] Combinations (111 -> Shunt and Bus, Continuous) config.mode = 0b111; @@ -93,7 +93,8 @@ void INA226Component::dump_config() { } LOG_UPDATE_INTERVAL(this); - ESP_LOGCONFIG(TAG, " ADC Conversion Time: %d", INA226_ADC_TIMES[this->adc_time_ & 0b111]); + ESP_LOGCONFIG(TAG, " ADC Conversion Time Bus Voltage: %d", INA226_ADC_TIMES[this->adc_time_voltage_ & 0b111]); + ESP_LOGCONFIG(TAG, " ADC Conversion Time Shunt Voltage: %d", INA226_ADC_TIMES[this->adc_time_current_ & 0b111]); ESP_LOGCONFIG(TAG, " ADC Averaging Samples: %d", INA226_ADC_AVG_SAMPLES[this->adc_avg_samples_ & 0b111]); LOG_SENSOR(" ", "Bus Voltage", this->bus_voltage_sensor_); diff --git a/esphome/components/ina226/ina226.h b/esphome/components/ina226/ina226.h index 2af9c8c195..61214fea0e 100644 --- a/esphome/components/ina226/ina226.h +++ b/esphome/components/ina226/ina226.h @@ -50,7 +50,8 @@ class INA226Component : public PollingComponent, public i2c::I2CDevice { void set_shunt_resistance_ohm(float shunt_resistance_ohm) { shunt_resistance_ohm_ = shunt_resistance_ohm; } void set_max_current_a(float max_current_a) { max_current_a_ = max_current_a; } - void set_adc_time(AdcTime time) { adc_time_ = time; } + void set_adc_time_voltage(AdcTime time) { adc_time_voltage_ = time; } + void set_adc_time_current(AdcTime time) { adc_time_current_ = time; } void set_adc_avg_samples(AdcAvgSamples samples) { adc_avg_samples_ = samples; } void set_bus_voltage_sensor(sensor::Sensor *bus_voltage_sensor) { bus_voltage_sensor_ = bus_voltage_sensor; } @@ -61,7 +62,8 @@ class INA226Component : public PollingComponent, public i2c::I2CDevice { protected: float shunt_resistance_ohm_; float max_current_a_; - AdcTime adc_time_{AdcTime::ADC_TIME_1100US}; + AdcTime adc_time_voltage_{AdcTime::ADC_TIME_1100US}; + AdcTime adc_time_current_{AdcTime::ADC_TIME_1100US}; AdcAvgSamples adc_avg_samples_{AdcAvgSamples::ADC_AVG_SAMPLES_4}; uint32_t calibration_lsb_; sensor::Sensor *bus_voltage_sensor_{nullptr}; diff --git a/esphome/components/ina226/sensor.py b/esphome/components/ina226/sensor.py index 32fca504a9..0accc58c00 100644 --- a/esphome/components/ina226/sensor.py +++ b/esphome/components/ina226/sensor.py @@ -16,6 +16,7 @@ from esphome.const import ( UNIT_VOLT, UNIT_AMPERE, UNIT_WATT, + CONF_VOLTAGE, ) DEPENDENCIES = ["i2c"] @@ -92,7 +93,15 @@ CONFIG_SCHEMA = ( cv.Optional(CONF_MAX_CURRENT, default=3.2): cv.All( cv.current, cv.Range(min=0.0) ), - cv.Optional(CONF_ADC_TIME, default="1100 us"): validate_adc_time, + cv.Optional(CONF_ADC_TIME, default="1100 us"): cv.Any( + validate_adc_time, + cv.Schema( + { + cv.Required(CONF_VOLTAGE): validate_adc_time, + cv.Required(CONF_CURRENT): validate_adc_time, + } + ), + ), cv.Optional(CONF_ADC_AVERAGING, default=4): cv.enum( ADC_AVG_SAMPLES, int=True ), @@ -110,7 +119,15 @@ async def to_code(config): cg.add(var.set_shunt_resistance_ohm(config[CONF_SHUNT_RESISTANCE])) cg.add(var.set_max_current_a(config[CONF_MAX_CURRENT])) - cg.add(var.set_adc_time(config[CONF_ADC_TIME])) + + adc_time_config = config[CONF_ADC_TIME] + if isinstance(adc_time_config, dict): + cg.add(var.set_adc_time_voltage(adc_time_config[CONF_VOLTAGE])) + cg.add(var.set_adc_time_current(adc_time_config[CONF_CURRENT])) + else: + cg.add(var.set_adc_time_voltage(adc_time_config)) + cg.add(var.set_adc_time_current(adc_time_config)) + cg.add(var.set_adc_avg_samples(config[CONF_ADC_AVERAGING])) if CONF_BUS_VOLTAGE in config: From bbf7e2be28ba0c01fd82f5ce02cf01b3e15f2a2c Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 13 Mar 2024 16:33:43 +1300 Subject: [PATCH 099/189] Bump version to 2024.4.0-dev --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index 918cf94ed3..8e3fd59ff0 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2024.3.0-dev" +__version__ = "2024.4.0-dev" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = ( From dbf50381f1ddbf9ab6a92ca78301f2edced55d03 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Thu, 14 Mar 2024 13:42:54 +1100 Subject: [PATCH 100/189] SPI: Revert clk_pin to standard output pin schema (#6368) --- esphome/components/spi/__init__.py | 17 ++--------------- tests/components/spi/test.esp32-s3-idf.yaml | 3 ++- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/esphome/components/spi/__init__.py b/esphome/components/spi/__init__.py index c2335bd92a..2847c5bfa1 100644 --- a/esphome/components/spi/__init__.py +++ b/esphome/components/spi/__init__.py @@ -29,7 +29,6 @@ from esphome.const import ( PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_RP2040, - CONF_ALLOW_OTHER_USES, CONF_DATA_PINS, ) from esphome.core import ( @@ -199,8 +198,6 @@ def get_hw_spi(config, available): def validate_spi_config(config): available = list(range(len(get_hw_interface_list()))) for spi in config: - # map pin number to schema - spi[CONF_CLK_PIN] = pins.gpio_output_pin_schema(spi[CONF_CLK_PIN]) interface = spi[CONF_INTERFACE] if interface == "software": pass @@ -257,21 +254,11 @@ def get_spi_interface(index): return "new SPIClass(HSPI)" -# Do not use a pin schema for the number, as that will trigger a pin reuse error due to duplication of the -# clock pin in the standard and quad schemas. -clk_pin_validator = cv.maybe_simple_value( - { - cv.Required(CONF_NUMBER): cv.Any(cv.int_, cv.string), - cv.Optional(CONF_ALLOW_OTHER_USES): cv.boolean, - }, - key=CONF_NUMBER, -) - SPI_SCHEMA = cv.All( cv.Schema( { cv.GenerateID(): cv.declare_id(SPIComponent), - cv.Required(CONF_CLK_PIN): clk_pin_validator, + cv.Required(CONF_CLK_PIN): pins.gpio_output_pin_schema, cv.Optional(CONF_MISO_PIN): pins.gpio_input_pin_schema, cv.Optional(CONF_MOSI_PIN): pins.gpio_output_pin_schema, cv.Optional(CONF_FORCE_SW): cv.invalid( @@ -291,7 +278,7 @@ SPI_QUAD_SCHEMA = cv.All( cv.Schema( { cv.GenerateID(): cv.declare_id(QuadSPIComponent), - cv.Required(CONF_CLK_PIN): clk_pin_validator, + cv.Required(CONF_CLK_PIN): pins.gpio_output_pin_schema, cv.Required(CONF_DATA_PINS): cv.All( cv.ensure_list(pins.internal_gpio_output_pin_number), cv.Length(min=4, max=4), diff --git a/tests/components/spi/test.esp32-s3-idf.yaml b/tests/components/spi/test.esp32-s3-idf.yaml index 3aae21cbeb..8db934023a 100644 --- a/tests/components/spi/test.esp32-s3-idf.yaml +++ b/tests/components/spi/test.esp32-s3-idf.yaml @@ -2,7 +2,8 @@ spi: - id: spi_id_1 type: single clk_pin: - number: GPIO7 + number: GPIO0 + ignore_strapping_warning: true allow_other_uses: false mosi_pin: GPIO6 interface: hardware From df5dfb8087ebb78d85e8789ab88e543f3e683b39 Mon Sep 17 00:00:00 2001 From: Attila Farago Date: Thu, 14 Mar 2024 03:56:17 +0100 Subject: [PATCH 101/189] Allow button press action in web_server to be executed via GET method (#5938) --- esphome/components/web_server/web_server.cpp | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index ba787239da..69d601ed49 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -486,7 +486,7 @@ void WebServer::handle_switch_request(AsyncWebServerRequest *request, const UrlM if (obj->get_object_id() != match.id) continue; - if (request->method() == HTTP_GET) { + if (request->method() == HTTP_GET && match.method.empty()) { std::string data = this->switch_json(obj, obj->state, DETAIL_STATE); request->send(200, "application/json", data.c_str()); } else if (match.method == "toggle") { @@ -517,7 +517,7 @@ void WebServer::handle_button_request(AsyncWebServerRequest *request, const UrlM for (button::Button *obj : App.get_buttons()) { if (obj->get_object_id() != match.id) continue; - if (request->method() == HTTP_POST && match.method == "press") { + if (match.method == "press") { this->schedule_([obj]() { obj->press(); }); request->send(200); return; @@ -572,7 +572,7 @@ void WebServer::handle_fan_request(AsyncWebServerRequest *request, const UrlMatc if (obj->get_object_id() != match.id) continue; - if (request->method() == HTTP_GET) { + if (request->method() == HTTP_GET && match.method.empty()) { std::string data = this->fan_json(obj, DETAIL_STATE); request->send(200, "application/json", data.c_str()); } else if (match.method == "toggle") { @@ -630,7 +630,7 @@ void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMa if (obj->get_object_id() != match.id) continue; - if (request->method() == HTTP_GET) { + if (request->method() == HTTP_GET && match.method.empty()) { std::string data = this->light_json(obj, DETAIL_STATE); request->send(200, "application/json", data.c_str()); } else if (match.method == "toggle") { @@ -736,7 +736,7 @@ void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMa if (obj->get_object_id() != match.id) continue; - if (request->method() == HTTP_GET) { + if (request->method() == HTTP_GET && match.method.empty()) { std::string data = this->cover_json(obj, DETAIL_STATE); request->send(200, "application/json", data.c_str()); continue; @@ -805,7 +805,7 @@ void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlM if (obj->get_object_id() != match.id) continue; - if (request->method() == HTTP_GET) { + if (request->method() == HTTP_GET && match.method.empty()) { std::string data = this->number_json(obj, obj->state, DETAIL_STATE); request->send(200, "application/json", data.c_str()); return; @@ -910,7 +910,7 @@ void WebServer::handle_text_request(AsyncWebServerRequest *request, const UrlMat if (obj->get_object_id() != match.id) continue; - if (request->method() == HTTP_GET) { + if (request->method() == HTTP_GET && match.method.empty()) { std::string data = this->text_json(obj, obj->state, DETAIL_STATE); request->send(200, "text/json", data.c_str()); return; @@ -961,7 +961,7 @@ void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlM if (obj->get_object_id() != match.id) continue; - if (request->method() == HTTP_GET) { + if (request->method() == HTTP_GET && match.method.empty()) { auto detail = DETAIL_STATE; auto *param = request->getParam("detail"); if (param && param->value() == "all") { @@ -1016,7 +1016,7 @@ void WebServer::handle_climate_request(AsyncWebServerRequest *request, const Url if (obj->get_object_id() != match.id) continue; - if (request->method() == HTTP_GET) { + if (request->method() == HTTP_GET && match.method.empty()) { std::string data = this->climate_json(obj, DETAIL_STATE); request->send(200, "application/json", data.c_str()); return; @@ -1162,7 +1162,7 @@ void WebServer::handle_lock_request(AsyncWebServerRequest *request, const UrlMat if (obj->get_object_id() != match.id) continue; - if (request->method() == HTTP_GET) { + if (request->method() == HTTP_GET && match.method.empty()) { std::string data = this->lock_json(obj, obj->state, DETAIL_STATE); request->send(200, "application/json", data.c_str()); } else if (match.method == "lock") { @@ -1201,7 +1201,7 @@ void WebServer::handle_alarm_control_panel_request(AsyncWebServerRequest *reques if (obj->get_object_id() != match.id) continue; - if (request->method() == HTTP_GET) { + if (request->method() == HTTP_GET && match.method.empty()) { std::string data = this->alarm_control_panel_json(obj, obj->get_state(), DETAIL_STATE); request->send(200, "application/json", data.c_str()); return; @@ -1251,7 +1251,7 @@ bool WebServer::canHandle(AsyncWebServerRequest *request) { #endif #ifdef USE_BUTTON - if (request->method() == HTTP_POST && match.domain == "button") + if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "button") return true; #endif From 72d1fa67fa212558696398d685f3af84fe2dc7fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 17:26:10 +1300 Subject: [PATCH 102/189] Bump docker/login-action from 3.0.0 to 3.1.0 (#6367) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 61f5ba4b23..0771aa0f20 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -91,12 +91,12 @@ jobs: uses: docker/setup-qemu-action@v3.0.0 - name: Log in to docker hub - uses: docker/login-action@v3.0.0 + uses: docker/login-action@v3.1.0 with: username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Log in to the GitHub container registry - uses: docker/login-action@v3.0.0 + uses: docker/login-action@v3.1.0 with: registry: ghcr.io username: ${{ github.actor }} @@ -167,13 +167,13 @@ jobs: - name: Log in to docker hub if: matrix.registry == 'dockerhub' - uses: docker/login-action@v3.0.0 + uses: docker/login-action@v3.1.0 with: username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Log in to the GitHub container registry if: matrix.registry == 'ghcr' - uses: docker/login-action@v3.0.0 + uses: docker/login-action@v3.1.0 with: registry: ghcr.io username: ${{ github.actor }} From fa4adb61f4a29347cd585b97c591b4a490f8034f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 17:28:05 +1300 Subject: [PATCH 103/189] Bump peter-evans/create-pull-request from 6.0.1 to 6.0.2 (#6361) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/sync-device-classes.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync-device-classes.yml b/.github/workflows/sync-device-classes.yml index ef3c04b595..36fce2bbcf 100644 --- a/.github/workflows/sync-device-classes.yml +++ b/.github/workflows/sync-device-classes.yml @@ -37,7 +37,7 @@ jobs: python ./script/sync-device_class.py - name: Commit changes - uses: peter-evans/create-pull-request@v6.0.1 + uses: peter-evans/create-pull-request@v6.0.2 with: commit-message: "Synchronise Device Classes from Home Assistant" committer: esphomebot From d3842a7ab49c32813185d00e4b6d8399c2b1dad7 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Wed, 13 Mar 2024 22:08:57 -0700 Subject: [PATCH 104/189] fix servo restore (#6370) --- esphome/components/servo/servo.cpp | 35 +++++++++++++++++++++++++----- esphome/components/servo/servo.h | 22 +++++-------------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/esphome/components/servo/servo.cpp b/esphome/components/servo/servo.cpp index 666c017dea..18e8c8087e 100644 --- a/esphome/components/servo/servo.cpp +++ b/esphome/components/servo/servo.cpp @@ -19,13 +19,28 @@ void Servo::dump_config() { ESP_LOGCONFIG(TAG, " run duration: %" PRIu32 " ms", this->transition_length_); } +void Servo::setup() { + float v; + if (this->restore_) { + this->rtc_ = global_preferences->make_preference(global_servo_id); + global_servo_id++; + if (this->rtc_.load(&v)) { + this->target_value_ = v; + this->internal_write(v); + this->state_ = STATE_ATTACHED; + this->start_millis_ = millis(); + return; + } + } + this->detach(); +} + void Servo::loop() { // check if auto_detach_time_ is set and servo reached target if (this->auto_detach_time_ && this->state_ == STATE_TARGET_REACHED) { if (millis() - this->start_millis_ > this->auto_detach_time_) { this->detach(); this->start_millis_ = 0; - this->state_ = STATE_DETACHED; ESP_LOGD(TAG, "Servo detached on auto_detach_time"); } } @@ -54,8 +69,11 @@ void Servo::loop() { void Servo::write(float value) { value = clamp(value, -1.0f, 1.0f); - if (this->target_value_ == value) + if ((this->state_ == STATE_DETACHED) && (this->target_value_ == value)) { this->internal_write(value); + } else { + this->save_level_(value); + } this->target_value_ = value; this->source_value_ = this->current_value_; this->state_ = STATE_ATTACHED; @@ -72,11 +90,18 @@ void Servo::internal_write(float value) { level = lerp(value, this->idle_level_, this->max_level_); } this->output_->set_level(level); - if (this->target_value_ == this->current_value_) { - this->save_level_(level); - } this->current_value_ = value; } +void Servo::detach() { + this->state_ = STATE_DETACHED; + this->output_->set_level(0.0f); +} + +void Servo::save_level_(float v) { + if (this->restore_) + this->rtc_.save(&v); +} + } // namespace servo } // namespace esphome diff --git a/esphome/components/servo/servo.h b/esphome/components/servo/servo.h index e2e3823158..13a7472ae5 100644 --- a/esphome/components/servo/servo.h +++ b/esphome/components/servo/servo.h @@ -17,22 +17,8 @@ class Servo : public Component { void loop() override; void write(float value); void internal_write(float value); - void detach() { - this->output_->set_level(0.0f); - this->save_level_(0.0f); - } - void setup() override { - float v; - if (this->restore_) { - this->rtc_ = global_preferences->make_preference(global_servo_id); - global_servo_id++; - if (this->rtc_.load(&v)) { - this->output_->set_level(v); - return; - } - } - this->detach(); - } + void detach(); + void setup() override; void dump_config() override; float get_setup_priority() const override { return setup_priority::DATA; } void set_min_level(float min_level) { min_level_ = min_level; } @@ -42,8 +28,10 @@ class Servo : public Component { void set_auto_detach_time(uint32_t auto_detach_time) { auto_detach_time_ = auto_detach_time; } void set_transition_length(uint32_t transition_length) { transition_length_ = transition_length; } + bool has_reached_target() { return this->current_value_ == this->target_value_; } + protected: - void save_level_(float v) { this->rtc_.save(&v); } + void save_level_(float v); output::FloatOutput *output_; float min_level_ = 0.0300f; From 4e850c3f325d8083a586020a5aa64cc1fe08f006 Mon Sep 17 00:00:00 2001 From: Jimmy Hedman Date: Thu, 14 Mar 2024 21:26:29 +0100 Subject: [PATCH 105/189] Don't try to get IPv6 addresses when disabled (#6366) --- esphome/components/wifi/wifi_component_esp32_arduino.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/wifi/wifi_component_esp32_arduino.cpp b/esphome/components/wifi/wifi_component_esp32_arduino.cpp index d7241fb66c..35e6c57e62 100644 --- a/esphome/components/wifi/wifi_component_esp32_arduino.cpp +++ b/esphome/components/wifi/wifi_component_esp32_arduino.cpp @@ -157,7 +157,7 @@ network::IPAddresses WiFiComponent::wifi_sta_ip_addresses() { } else { addresses[0] = network::IPAddress(&ip.ip); } -#if LWIP_IPV6 +#if USE_NETWORK_IPV6 ip6_addr_t ipv6; err = tcpip_adapter_get_ip6_global(TCPIP_ADAPTER_IF_STA, &ipv6); if (err != ESP_OK) { @@ -171,7 +171,7 @@ network::IPAddresses WiFiComponent::wifi_sta_ip_addresses() { } else { addresses[2] = network::IPAddress(&ipv6); } -#endif /* LWIP_IPV6 */ +#endif /* USE_NETWORK_IPV6 */ return addresses; } From b7af94c76fde3f92a403755117bd8faeae9acf43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 12:39:32 +1300 Subject: [PATCH 106/189] Bump docker/build-push-action from 5.2.0 to 5.3.0 in /.github/actions/build-image (#6373) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/build-image/action.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/build-image/action.yaml b/.github/actions/build-image/action.yaml index f93cf61abb..838bc362a1 100644 --- a/.github/actions/build-image/action.yaml +++ b/.github/actions/build-image/action.yaml @@ -36,7 +36,7 @@ runs: - name: Build and push to ghcr by digest id: build-ghcr - uses: docker/build-push-action@v5.2.0 + uses: docker/build-push-action@v5.3.0 with: context: . file: ./docker/Dockerfile @@ -67,7 +67,7 @@ runs: - name: Build and push to dockerhub by digest id: build-dockerhub - uses: docker/build-push-action@v5.2.0 + uses: docker/build-push-action@v5.3.0 with: context: . file: ./docker/Dockerfile From e42ab710291e50b9a1cdd81355cea086a8cd38e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 12:42:38 +1300 Subject: [PATCH 107/189] Bump docker/setup-buildx-action from 3.1.0 to 3.2.0 (#6372) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-docker.yml | 2 +- .github/workflows/release.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-docker.yml b/.github/workflows/ci-docker.yml index 1637f69954..8a7b35fe33 100644 --- a/.github/workflows/ci-docker.yml +++ b/.github/workflows/ci-docker.yml @@ -46,7 +46,7 @@ jobs: with: python-version: "3.9" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.1.0 + uses: docker/setup-buildx-action@v3.2.0 - name: Set up QEMU uses: docker/setup-qemu-action@v3.0.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0771aa0f20..6b567b5b6f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -85,7 +85,7 @@ jobs: python-version: "3.9" - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.1.0 + uses: docker/setup-buildx-action@v3.2.0 - name: Set up QEMU if: matrix.platform != 'linux/amd64' uses: docker/setup-qemu-action@v3.0.0 @@ -163,7 +163,7 @@ jobs: name: digests-${{ matrix.image.target }}-${{ matrix.registry }} path: /tmp/digests - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.1.0 + uses: docker/setup-buildx-action@v3.2.0 - name: Log in to docker hub if: matrix.registry == 'dockerhub' From 6e8760eba0dd1b183a38cc3105a6e9b563885e99 Mon Sep 17 00:00:00 2001 From: Federico Ferretti Date: Sat, 16 Mar 2024 02:17:01 +0100 Subject: [PATCH 108/189] Fix deep_sleep for ESP32-C6 (#6377) --- esphome/components/deep_sleep/deep_sleep_component.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/deep_sleep/deep_sleep_component.cpp b/esphome/components/deep_sleep/deep_sleep_component.cpp index 328e972e6b..97fdf11366 100644 --- a/esphome/components/deep_sleep/deep_sleep_component.cpp +++ b/esphome/components/deep_sleep/deep_sleep_component.cpp @@ -81,7 +81,7 @@ void DeepSleepComponent::set_wakeup_pin_mode(WakeupPinMode wakeup_pin_mode) { #endif #if defined(USE_ESP32) -#if !defined(USE_ESP32_VARIANT_ESP32C3) +#if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32C6) void DeepSleepComponent::set_ext1_wakeup(Ext1Wakeup ext1_wakeup) { this->ext1_wakeup_ = ext1_wakeup; } @@ -121,7 +121,7 @@ void DeepSleepComponent::begin_sleep(bool manual) { App.run_safe_shutdown_hooks(); #if defined(USE_ESP32) -#if !defined(USE_ESP32_VARIANT_ESP32C3) +#if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32C6) if (this->sleep_duration_.has_value()) esp_sleep_enable_timer_wakeup(*this->sleep_duration_); if (this->wakeup_pin_ != nullptr) { @@ -140,7 +140,7 @@ void DeepSleepComponent::begin_sleep(bool manual) { esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); } #endif -#ifdef USE_ESP32_VARIANT_ESP32C3 +#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) if (this->sleep_duration_.has_value()) esp_sleep_enable_timer_wakeup(*this->sleep_duration_); if (this->wakeup_pin_ != nullptr) { From 5d96b5c52befc30e8649a929c3d6f0fd29229e72 Mon Sep 17 00:00:00 2001 From: "Federico G. Schwindt" Date: Sat, 16 Mar 2024 01:21:44 +0000 Subject: [PATCH 109/189] Use AQI device class (#6376) --- esphome/components/sen5x/sensor.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/esphome/components/sen5x/sensor.py b/esphome/components/sen5x/sensor.py index 4bc4a138a3..67bd627f7f 100644 --- a/esphome/components/sen5x/sensor.py +++ b/esphome/components/sen5x/sensor.py @@ -14,13 +14,12 @@ from esphome.const import ( CONF_PM_4_0, CONF_STORE_BASELINE, CONF_TEMPERATURE, + DEVICE_CLASS_AQI, DEVICE_CLASS_HUMIDITY, - DEVICE_CLASS_NITROUS_OXIDE, DEVICE_CLASS_PM1, DEVICE_CLASS_PM10, DEVICE_CLASS_PM25, DEVICE_CLASS_TEMPERATURE, - DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS, ICON_CHEMICAL_WEAPON, ICON_RADIATOR, ICON_THERMOMETER, @@ -132,13 +131,13 @@ CONFIG_SCHEMA = ( cv.Optional(CONF_VOC): sensor.sensor_schema( icon=ICON_RADIATOR, accuracy_decimals=0, - device_class=DEVICE_CLASS_VOLATILE_ORGANIC_COMPOUNDS, + device_class=DEVICE_CLASS_AQI, state_class=STATE_CLASS_MEASUREMENT, ).extend(GAS_SENSOR), cv.Optional(CONF_NOX): sensor.sensor_schema( icon=ICON_RADIATOR, accuracy_decimals=0, - device_class=DEVICE_CLASS_NITROUS_OXIDE, + device_class=DEVICE_CLASS_AQI, state_class=STATE_CLASS_MEASUREMENT, ).extend(GAS_SENSOR), cv.Optional(CONF_STORE_BASELINE, default=True): cv.boolean, From 1148d41a66f37dcb3b37bb10feb9ba8d52348824 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Sat, 16 Mar 2024 14:22:34 +1300 Subject: [PATCH 110/189] Fix list-components when PR is not targeting dev (#6375) --- .github/workflows/ci.yml | 15 ++++++++++----- script/helpers.py | 4 ++-- script/list-components.py | 11 ++++++++++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c3de879176..47709739dc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -398,6 +398,7 @@ jobs: runs-on: ubuntu-latest needs: - common + if: github.event_name == 'pull_request' outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: @@ -406,10 +407,14 @@ jobs: with: # Fetch enough history so `git merge-base refs/remotes/origin/dev HEAD` works. fetch-depth: 500 - - name: Fetch dev branch + - name: Get target branch + id: target-branch run: | - git -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules --depth=1 origin +refs/heads/dev*:refs/remotes/origin/dev* +refs/tags/dev*:refs/tags/dev* - git merge-base refs/remotes/origin/dev HEAD + echo "branch=${{ github.event.pull_request.base.ref }}" >> $GITHUB_OUTPUT + - name: Fetch ${{ steps.target-branch.outputs.branch }} branch + run: | + git -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules --depth=1 origin +refs/heads/${{ steps.target-branch.outputs.branch }}:refs/remotes/origin/${{ steps.target-branch.outputs.branch }} + git merge-base refs/remotes/origin/${{ steps.target-branch.outputs.branch }} HEAD - name: Restore Python uses: ./.github/actions/restore-python with: @@ -419,7 +424,7 @@ jobs: id: set-matrix run: | . venv/bin/activate - echo "matrix=$(script/list-components.py --changed | jq -R -s -c 'split("\n")[:-1]')" >> $GITHUB_OUTPUT + echo "matrix=$(script/list-components.py --changed --branch ${{ steps.target-branch.outputs.branch }} | jq -R -s -c 'split("\n")[:-1]')" >> $GITHUB_OUTPUT test-build-components: name: Component test ${{ matrix.file }} @@ -427,7 +432,7 @@ jobs: needs: - common - list-components - if: ${{ needs.list-components.outputs.matrix != '[]' && needs.list-components.outputs.matrix != '' }} + if: ${{ github.event_name == 'pull_request' && needs.list-components.outputs.matrix != '[]' && needs.list-components.outputs.matrix != '' }} strategy: fail-fast: false max-parallel: 2 diff --git a/script/helpers.py b/script/helpers.py index a971fdf475..52b0658fb6 100644 --- a/script/helpers.py +++ b/script/helpers.py @@ -70,11 +70,11 @@ def splitlines_no_ends(string): return [s.strip() for s in string.splitlines()] -def changed_files(): +def changed_files(branch="dev"): check_remotes = ["upstream", "origin"] check_remotes.extend(splitlines_no_ends(get_output("git", "remote"))) for remote in check_remotes: - command = ["git", "merge-base", f"refs/remotes/{remote}/dev", "HEAD"] + command = ["git", "merge-base", f"refs/remotes/{remote}/{branch}", "HEAD"] try: merge_base = splitlines_no_ends(get_output(*command))[0] break diff --git a/script/list-components.py b/script/list-components.py index 3e55c0e5f7..8e2d47c6b3 100755 --- a/script/list-components.py +++ b/script/list-components.py @@ -120,13 +120,22 @@ def main(): parser.add_argument( "-c", "--changed", action="store_true", help="Only run on changed files" ) + parser.add_argument( + "-b", "--branch", help="Branch to compare changed files against" + ) args = parser.parse_args() + if args.branch and not args.changed: + parser.error("--branch requires --changed") + files = git_ls_files() files = filter(filter_component_files, files) if args.changed: - changed = changed_files() + if args.branch: + changed = changed_files(args.branch) + else: + changed = changed_files() files = [f for f in files if f in changed] components = extract_component_names_array_from_files_array(files) From 4f59b14ab09f1581cb15b475f6d4f47d3a5fa93b Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Sat, 16 Mar 2024 00:18:51 -0500 Subject: [PATCH 111/189] Fix keeloq for IDF 5+ (#6382) --- esphome/components/remote_base/keeloq_protocol.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/esphome/components/remote_base/keeloq_protocol.cpp b/esphome/components/remote_base/keeloq_protocol.cpp index 77a2f9be6c..09d9ea4f53 100644 --- a/esphome/components/remote_base/keeloq_protocol.cpp +++ b/esphome/components/remote_base/keeloq_protocol.cpp @@ -1,6 +1,8 @@ #include "keeloq_protocol.h" #include "esphome/core/log.h" +#include + namespace esphome { namespace remote_base { @@ -34,7 +36,8 @@ transmitter and nutton command is decoded. void KeeloqProtocol::encode(RemoteTransmitData *dst, const KeeloqData &data) { uint32_t out_data = 0x0; - ESP_LOGD(TAG, "Send Keeloq: address=%07x command=%03x encrypted=%08x", data.address, data.command, data.encrypted); + ESP_LOGD(TAG, "Send Keeloq: address=%07" PRIx32 " command=%03x encrypted=%08" PRIx32, data.address, data.command, + data.encrypted); ESP_LOGV(TAG, "Send Keeloq: data bits (%d + %d)", NBITS_ENCRYPTED_DATA, NBITS_FIXED_DATA); // Preamble = '01' x 12 @@ -181,7 +184,7 @@ optional KeeloqProtocol::decode(RemoteReceiveData src) { } void KeeloqProtocol::dump(const KeeloqData &data) { - ESP_LOGD(TAG, "Received Keeloq: address=0x%08X, command=0x%02x", data.address, data.command); + ESP_LOGD(TAG, "Received Keeloq: address=0x%08" PRIx32 ", command=0x%02x", data.address, data.command); } } // namespace remote_base From e753ac3a97aa0d51695a880137f7d4078d57f088 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Sat, 16 Mar 2024 06:19:25 +0100 Subject: [PATCH 112/189] Fix Nextion set_component_picture call (#6378) This fixes the call to the Nextion display to change the pic id from a component. It was previously changing the attribute `val`, which is related to something else. In addition, I've changed the parameter for picture_id to be uint_8, as Nextion requires an integer from 0 to 255 on this attribute. --- esphome/components/nextion/nextion.h | 6 +++--- esphome/components/nextion/nextion_commands.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/esphome/components/nextion/nextion.h b/esphome/components/nextion/nextion.h index eef2c61638..f9f01de72c 100644 --- a/esphome/components/nextion/nextion.h +++ b/esphome/components/nextion/nextion.h @@ -82,16 +82,16 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe /** * Set the picture of an image component. * @param component The component name. - * @param value The picture name. + * @param value The picture id. * * Example: * ```cpp - * it.set_component_picture("pic", "4"); + * it.set_component_picture("pic", 4); * ``` * * This will change the image of the component `pic` to the image with ID `4`. */ - void set_component_picture(const char *component, const char *picture); + void set_component_picture(const char *component, uint8_t picture_id); /** * Set the background color of a component. * @param component The component name. diff --git a/esphome/components/nextion/nextion_commands.cpp b/esphome/components/nextion/nextion_commands.cpp index c4849d6050..e378111376 100644 --- a/esphome/components/nextion/nextion_commands.cpp +++ b/esphome/components/nextion/nextion_commands.cpp @@ -197,8 +197,8 @@ void Nextion::disable_component_touch(const char *component) { this->add_no_result_to_queue_with_printf_("disable_component_touch", "tsw %s,0", component); } -void Nextion::set_component_picture(const char *component, const char *picture) { - this->add_no_result_to_queue_with_printf_("set_component_picture", "%s.val=%s", component, picture); +void Nextion::set_component_picture(const char *component, uint8_t picture_id) { + this->add_no_result_to_queue_with_printf_("set_component_picture", "%s.pic=%d", component, picture_id); } void Nextion::set_component_text(const char *component, const char *text) { From 23f8498ff972b0c67d0cd4f708e728c11d5a0630 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Sun, 17 Mar 2024 12:10:47 -0700 Subject: [PATCH 113/189] allow negative ppm for sensair (#6385) --- esphome/components/senseair/senseair.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/senseair/senseair.cpp b/esphome/components/senseair/senseair.cpp index e0504eb2b9..e58ee157f7 100644 --- a/esphome/components/senseair/senseair.cpp +++ b/esphome/components/senseair/senseair.cpp @@ -54,9 +54,9 @@ void SenseAirComponent::update() { this->status_clear_warning(); const uint8_t length = response[2]; const uint16_t status = (uint16_t(response[3]) << 8) | response[4]; - const uint16_t ppm = (uint16_t(response[length + 1]) << 8) | response[length + 2]; + const int16_t ppm = int16_t((response[length + 1] << 8) | response[length + 2]); - ESP_LOGD(TAG, "SenseAir Received CO₂=%uppm Status=0x%02X", ppm, status); + ESP_LOGD(TAG, "SenseAir Received CO₂=%dppm Status=0x%02X", ppm, status); if (this->co2_sensor_ != nullptr) this->co2_sensor_->publish_state(ppm); } From 9f121e6016921591d26d08dbe5340d6e5e3766be Mon Sep 17 00:00:00 2001 From: Kevin Ahrendt Date: Sun, 17 Mar 2024 15:13:55 -0400 Subject: [PATCH 114/189] microWakeWord - add new ops and small improvements (#6360) --- .../micro_wake_word/micro_wake_word.cpp | 66 ++++++++----------- .../micro_wake_word/micro_wake_word.h | 3 +- 2 files changed, 27 insertions(+), 42 deletions(-) diff --git a/esphome/components/micro_wake_word/micro_wake_word.cpp b/esphome/components/micro_wake_word/micro_wake_word.cpp index 7321e5b05b..f637f8b2bb 100644 --- a/esphome/components/micro_wake_word/micro_wake_word.cpp +++ b/esphome/components/micro_wake_word/micro_wake_word.cpp @@ -93,11 +93,18 @@ int MicroWakeWord::read_microphone_() { return 0; } - size_t bytes_written = this->ring_buffer_->write((void *) this->input_buffer_, bytes_read); - if (bytes_written != bytes_read) { - ESP_LOGW(TAG, "Failed to write some data to ring buffer (written=%d, expected=%d)", bytes_written, bytes_read); + size_t bytes_free = this->ring_buffer_->free(); + + if (bytes_free < bytes_read) { + ESP_LOGW(TAG, + "Not enough free bytes in ring buffer to store incoming audio data (free bytes=%d, incoming bytes=%d). " + "Resetting the ring buffer. Wake word detection accuracy will be reduced.", + bytes_free, bytes_read); + + this->ring_buffer_->reset(); } - return bytes_written; + + return this->ring_buffer_->write((void *) this->input_buffer_, bytes_read); } void MicroWakeWord::loop() { @@ -206,12 +213,6 @@ bool MicroWakeWord::initialize_models() { return false; } - this->preprocessor_stride_buffer_ = audio_samples_allocator.allocate(HISTORY_SAMPLES_TO_KEEP); - if (this->preprocessor_stride_buffer_ == nullptr) { - ESP_LOGE(TAG, "Could not allocate the audio preprocessor's stride buffer."); - return false; - } - this->preprocessor_model_ = tflite::GetModel(G_AUDIO_PREPROCESSOR_INT8_TFLITE); if (this->preprocessor_model_->version() != TFLITE_SCHEMA_VERSION) { ESP_LOGE(TAG, "Wake word's audio preprocessor model's schema is not supported"); @@ -225,7 +226,7 @@ bool MicroWakeWord::initialize_models() { } static tflite::MicroMutableOpResolver<18> preprocessor_op_resolver; - static tflite::MicroMutableOpResolver<14> streaming_op_resolver; + static tflite::MicroMutableOpResolver<17> streaming_op_resolver; if (!this->register_preprocessor_ops_(preprocessor_op_resolver)) return false; @@ -329,7 +330,6 @@ bool MicroWakeWord::detect_wake_word_() { } // Perform inference - uint32_t streaming_size = micros(); float streaming_prob = this->perform_streaming_inference_(); // Add the most recent probability to the sliding window @@ -357,6 +357,9 @@ bool MicroWakeWord::detect_wake_word_() { for (auto &prob : this->recent_streaming_probabilities_) { prob = 0; } + + ESP_LOGD(TAG, "Wake word sliding average probability is %.3f and most recent probability is %.3f", + sliding_window_average, streaming_prob); return true; } @@ -371,23 +374,6 @@ void MicroWakeWord::set_sliding_window_average_size(size_t size) { bool MicroWakeWord::slice_available_() { size_t available = this->ring_buffer_->available(); - size_t free = this->ring_buffer_->free(); - - if (free < NEW_SAMPLES_TO_GET * sizeof(int16_t)) { - // If the ring buffer is within one audio slice of being full, then wake word detection will have issues. - // If this is constantly occuring, then some possibilities why are - // 1) there are too many other slow components configured - // 2) the ESP32 isn't fast enough; e.g., an ESP32 is much slower than an ESP32-S3 at inferences. - // 3) the model is too large - // 4) the model uses operations that are not optimized - ESP_LOGW(TAG, - "Audio buffer is nearly full. Wake word detection may be less accurate and have slower reponse times. " -#if !defined(USE_ESP32_VARIANT_ESP32S3) - "microWakeWord is designed for the ESP32-S3. The current platform is too slow for this model." -#endif - ); - } - return available > (NEW_SAMPLES_TO_GET * sizeof(int16_t)); } @@ -396,13 +382,12 @@ bool MicroWakeWord::stride_audio_samples_(int16_t **audio_samples) { return false; } - // Copy 320 bytes (160 samples over 10 ms) into preprocessor_audio_buffer_ from history in - // preprocessor_stride_buffer_ - memcpy((void *) (this->preprocessor_audio_buffer_), (void *) (this->preprocessor_stride_buffer_), + // Copy the last 320 bytes (160 samples over 10 ms) from the audio buffer to the start of the audio buffer + memcpy((void *) (this->preprocessor_audio_buffer_), (void *) (this->preprocessor_audio_buffer_ + NEW_SAMPLES_TO_GET), HISTORY_SAMPLES_TO_KEEP * sizeof(int16_t)); - // Copy 640 bytes (320 samples over 20 ms) from the ring buffer - // The first 320 bytes (160 samples over 10 ms) will be from history + // Copy 640 bytes (320 samples over 20 ms) from the ring buffer into the audio buffer offset 320 bytes (160 samples + // over 10 ms) size_t bytes_read = this->ring_buffer_->read((void *) (this->preprocessor_audio_buffer_ + HISTORY_SAMPLES_TO_KEEP), NEW_SAMPLES_TO_GET * sizeof(int16_t), pdMS_TO_TICKS(200)); @@ -415,11 +400,6 @@ bool MicroWakeWord::stride_audio_samples_(int16_t **audio_samples) { return false; } - // Copy the last 320 bytes (160 samples over 10 ms) from the audio buffer into history stride buffer for the next - // iteration - memcpy((void *) (this->preprocessor_stride_buffer_), (void *) (this->preprocessor_audio_buffer_ + NEW_SAMPLES_TO_GET), - HISTORY_SAMPLES_TO_KEEP * sizeof(int16_t)); - *audio_samples = this->preprocessor_audio_buffer_; return true; } @@ -480,7 +460,7 @@ bool MicroWakeWord::register_preprocessor_ops_(tflite::MicroMutableOpResolver<18 return true; } -bool MicroWakeWord::register_streaming_ops_(tflite::MicroMutableOpResolver<14> &op_resolver) { +bool MicroWakeWord::register_streaming_ops_(tflite::MicroMutableOpResolver<17> &op_resolver) { if (op_resolver.AddCallOnce() != kTfLiteOk) return false; if (op_resolver.AddVarHandle() != kTfLiteOk) @@ -509,6 +489,12 @@ bool MicroWakeWord::register_streaming_ops_(tflite::MicroMutableOpResolver<14> & return false; if (op_resolver.AddQuantize() != kTfLiteOk) return false; + if (op_resolver.AddDepthwiseConv2D() != kTfLiteOk) + return false; + if (op_resolver.AddAveragePool2D() != kTfLiteOk) + return false; + if (op_resolver.AddMaxPool2D() != kTfLiteOk) + return false; return true; } diff --git a/esphome/components/micro_wake_word/micro_wake_word.h b/esphome/components/micro_wake_word/micro_wake_word.h index 27d05c3e09..1d7c18d686 100644 --- a/esphome/components/micro_wake_word/micro_wake_word.h +++ b/esphome/components/micro_wake_word/micro_wake_word.h @@ -128,7 +128,6 @@ class MicroWakeWord : public Component { // Stores audio fed into feature generator preprocessor int16_t *preprocessor_audio_buffer_; - int16_t *preprocessor_stride_buffer_; bool detected_{false}; @@ -181,7 +180,7 @@ class MicroWakeWord : public Component { bool register_preprocessor_ops_(tflite::MicroMutableOpResolver<18> &op_resolver); /// @brief Returns true if successfully registered the streaming model's TensorFlow operations - bool register_streaming_ops_(tflite::MicroMutableOpResolver<14> &op_resolver); + bool register_streaming_ops_(tflite::MicroMutableOpResolver<17> &op_resolver); }; template class StartAction : public Action, public Parented { From c24946e09ff964d76ae44011638ef2c35280f525 Mon Sep 17 00:00:00 2001 From: Stefan Rado <628587+kroimon@users.noreply.github.com> Date: Sun, 17 Mar 2024 22:00:07 +0100 Subject: [PATCH 115/189] Fix compilation for uponor_smatrix without time component (#6389) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/components/uponor_smatrix/uponor_smatrix.cpp | 2 ++ esphome/components/uponor_smatrix/uponor_smatrix.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/esphome/components/uponor_smatrix/uponor_smatrix.cpp b/esphome/components/uponor_smatrix/uponor_smatrix.cpp index 10cd787c7f..df81691fb1 100644 --- a/esphome/components/uponor_smatrix/uponor_smatrix.cpp +++ b/esphome/components/uponor_smatrix/uponor_smatrix.cpp @@ -61,9 +61,11 @@ void UponorSmatrixComponent::loop() { // Send packets during bus silence if ((now - this->last_rx_ > 300) && (now - this->last_poll_start_ < 9500) && (now - this->last_tx_ > 200)) { +#ifdef USE_TIME // Only build time packet when bus is silent and queue is empty to make sure we can send it right away if (this->send_time_requested_ && this->tx_queue_.empty() && this->do_send_time_()) this->send_time_requested_ = false; +#endif // Send the next packet in the queue if (!this->tx_queue_.empty()) { auto packet = std::move(this->tx_queue_.front()); diff --git a/esphome/components/uponor_smatrix/uponor_smatrix.h b/esphome/components/uponor_smatrix/uponor_smatrix.h index b6675199b5..b7667b5b87 100644 --- a/esphome/components/uponor_smatrix/uponor_smatrix.h +++ b/esphome/components/uponor_smatrix/uponor_smatrix.h @@ -4,6 +4,8 @@ #include "esphome/core/component.h" #include "esphome/core/helpers.h" +#include "esphome/core/defines.h" + #ifdef USE_TIME #include "esphome/components/time/real_time_clock.h" #include "esphome/core/time.h" From 0b9a022ef6c430671ec6d906968634c4af8343fb Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Sun, 17 Mar 2024 22:01:25 +0100 Subject: [PATCH 116/189] Shows component operation time in `ms` (#6388) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- esphome/core/component.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/esphome/core/component.cpp b/esphome/core/component.cpp index b0406e6502..d737ec0ae3 100644 --- a/esphome/core/component.cpp +++ b/esphome/core/component.cpp @@ -5,6 +5,7 @@ #include "esphome/core/helpers.h" #include "esphome/core/log.h" #include +#include namespace esphome { @@ -211,8 +212,8 @@ WarnIfComponentBlockingGuard::~WarnIfComponentBlockingGuard() { uint32_t now = millis(); if (now - started_ > 50) { const char *src = component_ == nullptr ? "" : component_->get_component_source(); - ESP_LOGW(TAG, "Component %s took a long time for an operation (%.2f s).", src, (now - started_) / 1e3f); - ESP_LOGW(TAG, "Components should block for at most 20-30ms."); + ESP_LOGW(TAG, "Component %s took a long time for an operation (%" PRIu32 " ms).", src, (now - started_)); + ESP_LOGW(TAG, "Components should block for at most 30 ms."); ; } } From 72c6563a3b4fafffa08f82765e3b8853bc88ccc9 Mon Sep 17 00:00:00 2001 From: Jimmy Hedman Date: Sun, 17 Mar 2024 22:06:02 +0100 Subject: [PATCH 117/189] IPv6 can't be enabled for libretiny (#6387) --- esphome/components/network/__init__.py | 38 ++++++++++++++++---------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/esphome/components/network/__init__.py b/esphome/components/network/__init__.py index 4e87ff1c12..36144ff0a4 100644 --- a/esphome/components/network/__init__.py +++ b/esphome/components/network/__init__.py @@ -6,6 +6,9 @@ from esphome.components.esp32 import add_idf_sdkconfig_option from esphome.const import ( CONF_ENABLE_IPV6, CONF_MIN_IPV6_ADDR_COUNT, + PLATFORM_ESP32, + PLATFORM_ESP8266, + PLATFORM_RP2040, ) CODEOWNERS = ["@esphome/core"] @@ -16,25 +19,30 @@ IPAddress = network_ns.class_("IPAddress") CONFIG_SCHEMA = cv.Schema( { - cv.Optional(CONF_ENABLE_IPV6, default=False): cv.boolean, + cv.SplitDefault(CONF_ENABLE_IPV6): cv.All( + cv.boolean, cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_RP2040]) + ), cv.Optional(CONF_MIN_IPV6_ADDR_COUNT, default=0): cv.positive_int, } ) async def to_code(config): - cg.add_define("USE_NETWORK_IPV6", config[CONF_ENABLE_IPV6]) - cg.add_define("USE_NETWORK_MIN_IPV6_ADDR_COUNT", config[CONF_MIN_IPV6_ADDR_COUNT]) - if CORE.using_esp_idf: - add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", config[CONF_ENABLE_IPV6]) - add_idf_sdkconfig_option( - "CONFIG_LWIP_IPV6_AUTOCONFIG", config[CONF_ENABLE_IPV6] + if CONF_ENABLE_IPV6 in config: + cg.add_define("USE_NETWORK_IPV6", config[CONF_ENABLE_IPV6]) + cg.add_define( + "USE_NETWORK_MIN_IPV6_ADDR_COUNT", config[CONF_MIN_IPV6_ADDR_COUNT] ) - else: - if config[CONF_ENABLE_IPV6]: - cg.add_build_flag("-DCONFIG_LWIP_IPV6") - cg.add_build_flag("-DCONFIG_LWIP_IPV6_AUTOCONFIG") - if CORE.is_rp2040: - cg.add_build_flag("-DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6") - if CORE.is_esp8266: - cg.add_build_flag("-DPIO_FRAMEWORK_ARDUINO_LWIP2_IPV6_LOW_MEMORY") + if CORE.using_esp_idf: + add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", config[CONF_ENABLE_IPV6]) + add_idf_sdkconfig_option( + "CONFIG_LWIP_IPV6_AUTOCONFIG", config[CONF_ENABLE_IPV6] + ) + else: + if config[CONF_ENABLE_IPV6]: + cg.add_build_flag("-DCONFIG_LWIP_IPV6") + cg.add_build_flag("-DCONFIG_LWIP_IPV6_AUTOCONFIG") + if CORE.is_rp2040: + cg.add_build_flag("-DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6") + if CORE.is_esp8266: + cg.add_build_flag("-DPIO_FRAMEWORK_ARDUINO_LWIP2_IPV6_LOW_MEMORY") From 8fd10d6859ca3013c72820a64f3853a2fed89622 Mon Sep 17 00:00:00 2001 From: Daniel Eisterhold Date: Sun, 17 Mar 2024 18:51:46 -0500 Subject: [PATCH 118/189] Add line_at_angle method to Display component (#6381) --- esphome/components/display/display.cpp | 15 ++++++++++ esphome/components/display/display.h | 7 +++++ tests/components/display/test.esp32.yaml | 35 ++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 tests/components/display/test.esp32.yaml diff --git a/esphome/components/display/display.cpp b/esphome/components/display/display.cpp index 8ae1ee46aa..010e6eca0b 100644 --- a/esphome/components/display/display.cpp +++ b/esphome/components/display/display.cpp @@ -36,6 +36,21 @@ void HOT Display::line(int x1, int y1, int x2, int y2, Color color) { } } +void Display::line_at_angle(int x, int y, int angle, int length, Color color) { + this->line_at_angle(x, y, angle, 0, length, color); +} + +void Display::line_at_angle(int x, int y, int angle, int start_radius, int stop_radius, Color color) { + // Calculate start and end points + int x1 = (start_radius * cos(angle * M_PI / 180)) + x; + int y1 = (start_radius * sin(angle * M_PI / 180)) + y; + int x2 = (stop_radius * cos(angle * M_PI / 180)) + x; + int y2 = (stop_radius * sin(angle * M_PI / 180)) + y; + + // Draw line + this->line(x1, y1, x2, y2, color); +} + void Display::draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, ColorOrder order, ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) { size_t line_stride = x_offset + w + x_pad; // length of each source line in pixels diff --git a/esphome/components/display/display.h b/esphome/components/display/display.h index 21954ebb71..a30ba976b4 100644 --- a/esphome/components/display/display.h +++ b/esphome/components/display/display.h @@ -258,6 +258,13 @@ class Display : public PollingComponent { /// Draw a straight line from the point [x1,y1] to [x2,y2] with the given color. void line(int x1, int y1, int x2, int y2, Color color = COLOR_ON); + /// Draw a straight line at the given angle based on the origin [x, y] for a specified length with the given color. + void line_at_angle(int x, int y, int angle, int length, Color color = COLOR_ON); + + /// Draw a straight line at the given angle based on the origin [x, y] from a specified start and stop radius with the + /// given color. + void line_at_angle(int x, int y, int angle, int start_radius, int stop_radius, Color color = COLOR_ON); + /// Draw a horizontal line from the point [x,y] to [x+width,y] with the given color. void horizontal_line(int x, int y, int width, Color color = COLOR_ON); diff --git a/tests/components/display/test.esp32.yaml b/tests/components/display/test.esp32.yaml new file mode 100644 index 0000000000..a22aa76780 --- /dev/null +++ b/tests/components/display/test.esp32.yaml @@ -0,0 +1,35 @@ +spi: + - id: spi_main_lcd + clk_pin: 16 + mosi_pin: 17 + miso_pin: 15 + +display: + - platform: ili9xxx + id: main_lcd + model: ili9342 + cs_pin: 12 + dc_pin: 13 + reset_pin: 21 + lambda: |- + // Draw an analog clock in the center of the screen + int centerX = it.get_width() / 2; + int centerY = it.get_height() / 2; + int radius = min(it.get_width(), it.get_height()) / 4; + + // Draw border + it.circle(centerX, centerY, radius); + + // Draw hour ticks + for(int h = 0; h < 12; h++) { + int hourAngle = (h * 30) - 90; + + it.line_at_angle(centerX, centerY, hourAngle, radius - 10, radius); + } + + // Draw minute ticks + for(int m = 0; m < 60; m++) { + int minuteAngle = (m * 6) - 90; + + it.line_at_angle(centerX, centerY, minuteAngle, radius - 5, radius); + } From 687553a285fc13d4b17a75a84050e5c0e6ba2cb1 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Mon, 18 Mar 2024 13:00:59 +1300 Subject: [PATCH 119/189] Replace name and friendly name in full adopted configs (#4456) --- .../components/dashboard_import/__init__.py | 130 +++++++++--------- esphome/dashboard/web_server.py | 3 +- requirements.txt | 1 + 3 files changed, 68 insertions(+), 66 deletions(-) diff --git a/esphome/components/dashboard_import/__init__.py b/esphome/components/dashboard_import/__init__.py index e0994be6a0..b1b22b816b 100644 --- a/esphome/components/dashboard_import/__init__.py +++ b/esphome/components/dashboard_import/__init__.py @@ -2,8 +2,10 @@ import base64 import secrets from pathlib import Path from typing import Optional +import re import requests +from ruamel.yaml import YAML import esphome.codegen as cg import esphome.config_validation as cv @@ -11,7 +13,6 @@ import esphome.final_validate as fv from esphome import git from esphome.components.packages import validate_source_shorthand from esphome.const import CONF_REF, CONF_WIFI, CONF_ESPHOME, CONF_PROJECT -from esphome.wizard import wizard_file from esphome.yaml_util import dump dashboard_import_ns = cg.esphome_ns.namespace("dashboard_import") @@ -94,75 +95,74 @@ def import_config( if p.exists(): raise FileExistsError - if project_name == "esphome.web": - if "esp32c3" in import_url: - board = "esp32-c3-devkitm-1" - platform = "ESP32" - elif "esp32s2" in import_url: - board = "esp32-s2-saola-1" - platform = "ESP32" - elif "esp32s3" in import_url: - board = "esp32-s3-devkitc-1" - platform = "ESP32" - elif "esp32" in import_url: - board = "esp32dev" - platform = "ESP32" - elif "esp8266" in import_url: - board = "esp01_1m" - platform = "ESP8266" - elif "pico-w" in import_url: - board = "pico-w" - platform = "RP2040" + git_file = git.GitFile.from_shorthand(import_url) - kwargs = { - "name": name, - "friendly_name": friendly_name, - "platform": platform, - "board": board, - "ssid": "!secret wifi_ssid", - "psk": "!secret wifi_password", + if git_file.query and "full_config" in git_file.query: + url = git_file.raw_url + try: + req = requests.get(url, timeout=30) + req.raise_for_status() + except requests.exceptions.RequestException as e: + raise ValueError(f"Error while fetching {url}: {e}") from e + + contents = req.text + yaml = YAML() + loaded_yaml = yaml.load(contents) + if ( + "name_add_mac_suffix" in loaded_yaml["esphome"] + and loaded_yaml["esphome"]["name_add_mac_suffix"] + ): + loaded_yaml["esphome"]["name_add_mac_suffix"] = False + name_val = loaded_yaml["esphome"]["name"] + sub_pattern = re.compile(r"\$\{?([a-zA-Z-_]+)\}?") + if match := sub_pattern.match(name_val): + name_sub = match.group(1) + if name_sub in loaded_yaml["substitutions"]: + loaded_yaml["substitutions"][name_sub] = name + else: + raise ValueError( + f"Name substitution {name_sub} not found in substitutions" + ) + else: + loaded_yaml["esphome"]["name"] = name + if friendly_name is not None: + friendly_name_val = loaded_yaml["esphome"]["friendly_name"] + if match := sub_pattern.match(friendly_name_val): + friendly_name_sub = match.group(1) + if friendly_name_sub in loaded_yaml["substitutions"]: + loaded_yaml["substitutions"][friendly_name_sub] = friendly_name + else: + raise ValueError( + f"Friendly name substitution {friendly_name_sub} not found in substitutions" + ) + else: + loaded_yaml["esphome"]["friendly_name"] = friendly_name + + with p.open("w", encoding="utf8") as f: + yaml.dump(loaded_yaml, f) + else: + with p.open("w", encoding="utf8") as f: + f.write(contents) + + else: + substitutions = {"name": name} + esphome_core = {"name": "${name}", "name_add_mac_suffix": False} + if friendly_name: + substitutions["friendly_name"] = friendly_name + esphome_core["friendly_name"] = "${friendly_name}" + config = { + "substitutions": substitutions, + "packages": {project_name: import_url}, + "esphome": esphome_core, } if encryption: noise_psk = secrets.token_bytes(32) key = base64.b64encode(noise_psk).decode() - kwargs["api_encryption_key"] = key + config["api"] = {"encryption": {"key": key}} - p.write_text( - wizard_file(**kwargs), - encoding="utf8", - ) - else: - git_file = git.GitFile.from_shorthand(import_url) + output = dump(config) - if git_file.query and "full_config" in git_file.query: - url = git_file.raw_url - try: - req = requests.get(url, timeout=30) - req.raise_for_status() - except requests.exceptions.RequestException as e: - raise ValueError(f"Error while fetching {url}: {e}") from e + if network == CONF_WIFI: + output += WIFI_CONFIG - p.write_text(req.text, encoding="utf8") - - else: - substitutions = {"name": name} - esphome_core = {"name": "${name}", "name_add_mac_suffix": False} - if friendly_name: - substitutions["friendly_name"] = friendly_name - esphome_core["friendly_name"] = "${friendly_name}" - config = { - "substitutions": substitutions, - "packages": {project_name: import_url}, - "esphome": esphome_core, - } - if encryption: - noise_psk = secrets.token_bytes(32) - key = base64.b64encode(noise_psk).decode() - config["api"] = {"encryption": {"key": key}} - - output = dump(config) - - if network == CONF_WIFI: - output += WIFI_CONFIG - - p.write_text(output, encoding="utf8") + p.write_text(output, encoding="utf8") diff --git a/esphome/dashboard/web_server.py b/esphome/dashboard/web_server.py index de3fe6e8ae..3de1d69115 100644 --- a/esphome/dashboard/web_server.py +++ b/esphome/dashboard/web_server.py @@ -516,7 +516,8 @@ class ImportRequestHandler(BaseHandler): self.set_status(500) self.write("File already exists") return - except ValueError: + except ValueError as e: + _LOGGER.error(e) self.set_status(422) self.write("Invalid package url") return diff --git a/requirements.txt b/requirements.txt index 32955bf6e7..9b5e06fc59 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,6 +16,7 @@ esphome-dashboard==20231107.0 aioesphomeapi==23.1.1 zeroconf==0.131.0 python-magic==0.4.27 +ruamel.yaml==0.18.6 # dashboard_import # esp-idf requires this, but doesn't bundle it by default # https://github.com/espressif/esp-idf/blob/220590d599e134d7a5e7f1e683cc4550349ffbf8/requirements.txt#L24 From f3f7bdc4e11a006b6305a48740b85a68b9d31be5 Mon Sep 17 00:00:00 2001 From: swoboda1337 <154711427+swoboda1337@users.noreply.github.com> Date: Mon, 18 Mar 2024 02:35:06 -0400 Subject: [PATCH 120/189] Fix bug in `remote_base` conditional (#6281) Co-authored-by: Jonathan Swoboda --- esphome/components/remote_base/remote_base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/remote_base/remote_base.cpp b/esphome/components/remote_base/remote_base.cpp index 095f95053f..f3e86aaab6 100644 --- a/esphome/components/remote_base/remote_base.cpp +++ b/esphome/components/remote_base/remote_base.cpp @@ -16,7 +16,7 @@ RemoteRMTChannel::RemoteRMTChannel(uint8_t mem_block_num) : mem_block_num_(mem_b } void RemoteRMTChannel::config_rmt(rmt_config_t &rmt) { - if (rmt_channel_t(int(this->channel_) + this->mem_block_num_) >= RMT_CHANNEL_MAX) { + if (rmt_channel_t(int(this->channel_) + this->mem_block_num_) > RMT_CHANNEL_MAX) { this->mem_block_num_ = int(RMT_CHANNEL_MAX) - int(this->channel_); ESP_LOGW(TAG, "Not enough RMT memory blocks available, reduced to %i blocks.", this->mem_block_num_); } From 1e5dc159724a330b4f28616a310e026d76c80281 Mon Sep 17 00:00:00 2001 From: Stefan Rado <628587+kroimon@users.noreply.github.com> Date: Mon, 18 Mar 2024 19:04:53 +0100 Subject: [PATCH 121/189] Fix sending packets to uponor_smatrix devices (#6392) --- esphome/components/uponor_smatrix/uponor_smatrix.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/esphome/components/uponor_smatrix/uponor_smatrix.cpp b/esphome/components/uponor_smatrix/uponor_smatrix.cpp index df81691fb1..a7014dc96c 100644 --- a/esphome/components/uponor_smatrix/uponor_smatrix.cpp +++ b/esphome/components/uponor_smatrix/uponor_smatrix.cpp @@ -173,7 +173,9 @@ bool UponorSmatrixComponent::send(uint16_t device_address, const UponorSmatrixDa return false; // Assemble packet for send queue. All fields are big-endian except for the little-endian checksum. - std::vector packet(6 + 3 * data_len); + std::vector packet; + packet.reserve(6 + 3 * data_len); + packet.push_back(this->address_ >> 8); packet.push_back(this->address_ >> 0); packet.push_back(device_address >> 8); From 55677bb68e285aa2b076c1ff0e54d5fd83ff7814 Mon Sep 17 00:00:00 2001 From: Stefan Rado <628587+kroimon@users.noreply.github.com> Date: Mon, 18 Mar 2024 19:06:17 +0100 Subject: [PATCH 122/189] Fix wrong initialization of vectors in ade7953_i2c (#6393) --- .../components/ade7953_i2c/ade7953_i2c.cpp | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/esphome/components/ade7953_i2c/ade7953_i2c.cpp b/esphome/components/ade7953_i2c/ade7953_i2c.cpp index 572337428a..ae381824db 100644 --- a/esphome/components/ade7953_i2c/ade7953_i2c.cpp +++ b/esphome/components/ade7953_i2c/ade7953_i2c.cpp @@ -13,29 +13,29 @@ void AdE7953I2c::dump_config() { ade7953_base::ADE7953::dump_config(); } bool AdE7953I2c::ade_write_8(uint16_t reg, uint8_t value) { - std::vector data(3); - data.push_back(reg >> 8); - data.push_back(reg >> 0); - data.push_back(value); - return this->write(data.data(), data.size()) != i2c::ERROR_OK; + uint8_t data[3]; + data[0] = reg >> 8; + data[1] = reg >> 0; + data[2] = value; + return this->write(data, 3) != i2c::ERROR_OK; } bool AdE7953I2c::ade_write_16(uint16_t reg, uint16_t value) { - std::vector data(4); - data.push_back(reg >> 8); - data.push_back(reg >> 0); - data.push_back(value >> 8); - data.push_back(value >> 0); - return this->write(data.data(), data.size()) != i2c::ERROR_OK; + uint8_t data[4]; + data[0] = reg >> 8; + data[1] = reg >> 0; + data[2] = value >> 8; + data[3] = value >> 0; + return this->write(data, 4) != i2c::ERROR_OK; } bool AdE7953I2c::ade_write_32(uint16_t reg, uint32_t value) { - std::vector data(6); - data.push_back(reg >> 8); - data.push_back(reg >> 0); - data.push_back(value >> 24); - data.push_back(value >> 16); - data.push_back(value >> 8); - data.push_back(value >> 0); - return this->write(data.data(), data.size()) != i2c::ERROR_OK; + uint8_t data[6]; + data[0] = reg >> 8; + data[1] = reg >> 0; + data[2] = value >> 24; + data[3] = value >> 16; + data[4] = value >> 8; + data[5] = value >> 0; + return this->write(data, 6) != i2c::ERROR_OK; } bool AdE7953I2c::ade_read_8(uint16_t reg, uint8_t *value) { uint8_t reg_data[2]; From e7fe2a2816f6bc45ae46f8d17efc1cb20222bd74 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Tue, 19 Mar 2024 07:15:52 +1300 Subject: [PATCH 123/189] Check generated proto files are as expected if any are modified in PRs (#6254) --- .github/workflows/ci-api-proto.yml | 81 ++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 .github/workflows/ci-api-proto.yml diff --git a/.github/workflows/ci-api-proto.yml b/.github/workflows/ci-api-proto.yml new file mode 100644 index 0000000000..038ef3a587 --- /dev/null +++ b/.github/workflows/ci-api-proto.yml @@ -0,0 +1,81 @@ +name: API Proto CI + +# yamllint disable-line rule:truthy +on: + pull_request: + paths: + - "esphome/components/api/api.proto" + - "esphome/components/api/api_pb2.cpp" + - "esphome/components/api/api_pb2.h" + - "esphome/components/api/api_pb2_service.cpp" + - "esphome/components/api/api_pb2_service.h" + - "script/api_protobuf/api_protobuf.py" + - ".github/workflows/ci-api-proto.yml" + +permissions: + contents: read + pull-requests: write + +jobs: + check: + name: Check generated files + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4.1.1 + - name: Set up Python + uses: actions/setup-python@v5.0.0 + with: + python-version: "3.11" + + - name: Install apt dependencies + run: | + sudo apt update + sudo apt-cache show protobuf-compiler + sudo apt install -y protobuf-compiler + protoc --version + - name: Install python dependencies + run: pip install aioesphomeapi -c requirements.txt -r requirements_dev.txt + - name: Generate files + run: script/api_protobuf/api_protobuf.py + - name: Check for changes + run: | + if ! git diff --quiet; then + echo "## Job Failed" | tee -a $GITHUB_STEP_SUMMARY + echo "You have altered the generated proto files but they do not match what is expected." | tee -a $GITHUB_STEP_SUMMARY + echo "Please run 'script/api_protobuf/api_protobuf.py' and commit the changes." | tee -a $GITHUB_STEP_SUMMARY + exit 1 + fi + - if: failure() + name: Review PR + uses: actions/github-script@v7.0.1 + with: + script: | + await github.rest.pulls.createReview({ + pull_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + event: 'REQUEST_CHANGES', + body: 'You have altered the generated proto files but they do not match what is expected.\nPlease run "script/api_protobuf/api_protobuf.py" and commit the changes.' + }) + - if: success() + name: Dismiss review + uses: actions/github-script@v7.0.1 + with: + script: | + let reviews = await github.rest.pulls.listReviews({ + pull_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo + }); + for (let review of reviews.data) { + if (review.user.login === 'github-actions[bot]' && review.state === 'CHANGES_REQUESTED') { + await github.rest.pulls.dismissReview({ + pull_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + review_id: review.id, + message: 'Files now match the expected proto files.' + }); + } + } From d692b5404cc40af1bf6394bcc26574847e1727bc Mon Sep 17 00:00:00 2001 From: Mike La Spina Date: Mon, 18 Mar 2024 13:26:39 -0500 Subject: [PATCH 124/189] ld2420: Firmware v1.5.4+ bug workaround (#6168) --- esphome/components/ld2420/ld2420.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/esphome/components/ld2420/ld2420.cpp b/esphome/components/ld2420/ld2420.cpp index bda1764cfc..bf1412ee9f 100644 --- a/esphome/components/ld2420/ld2420.cpp +++ b/esphome/components/ld2420/ld2420.cpp @@ -211,10 +211,11 @@ void LD2420Component::factory_reset_action() { void LD2420Component::restart_module_action() { ESP_LOGCONFIG(TAG, "Restarting LD2420 module..."); this->send_module_restart(); - delay_microseconds_safe(45000); - this->set_config_mode(true); - this->set_system_mode(system_mode_); - this->set_config_mode(false); + this->set_timeout(250, [this]() { + this->set_config_mode(true); + this->set_system_mode(system_mode_); + this->set_config_mode(false); + }); ESP_LOGCONFIG(TAG, "LD2420 Restarted."); } @@ -527,18 +528,16 @@ int LD2420Component::send_cmd_from_array(CmdFrameT frame) { this->write_byte(cmd_buffer[index]); } - delay_microseconds_safe(500); // give the module a moment to process it error = 0; if (frame.command == CMD_RESTART) { - delay_microseconds_safe(25000); // Wait for the restart - return 0; // restart does not reply exit now + return 0; // restart does not reply exit now } while (!this->cmd_reply_.ack) { while (available()) { this->readline_(read(), ack_buffer, sizeof(ack_buffer)); } - delay_microseconds_safe(250); + delay_microseconds_safe(1450); if (loop_count <= 0) { error = LD2420_ERROR_TIMEOUT; retry--; From f5695733bc615fa3e6c1ab3c4c5b3d95ce25461c Mon Sep 17 00:00:00 2001 From: Andres Vahter Date: Mon, 18 Mar 2024 20:28:15 +0200 Subject: [PATCH 125/189] ld2420: fix energy mode documentation (#6225) --- esphome/components/ld2420/ld2420.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/esphome/components/ld2420/ld2420.cpp b/esphome/components/ld2420/ld2420.cpp index bf1412ee9f..58c9a289a3 100644 --- a/esphome/components/ld2420/ld2420.cpp +++ b/esphome/components/ld2420/ld2420.cpp @@ -40,9 +40,9 @@ There are three documented parameters for modes: 00 04 = Energy output mode This mode outputs detailed signal energy values for each gate and the target distance. The data format consist of the following. - Header HH, Length LL, Persence PP, Distance DD, Range Gate GG, 16 Gate Energies EE, Footer FF - HH HH HH HH LL LL PP DD DD GG GG EE EE .. 16x .. FF FF FF FF - F4 F3 F2 F1 00 23 00 00 00 00 01 00 00 .. .. .. .. F8 F7 F6 F5 + Header HH, Length LL, Persence PP, Distance DD, 16 Gate Energies EE, Footer FF + HH HH HH HH LL LL PP DD DD EE EE .. 16x .. FF FF FF FF + F4 F3 F2 F1 23 00 00 00 00 00 00 .. .. .. .. F8 F7 F6 F5 00 00 = debug output mode This mode outputs detailed values consisting of 20 Dopplers, 16 Ranges for a total 20 * 16 * 4 bytes The data format consist of the following. From cb731926be637a6b6c1344df877f49fe2c35bc30 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Mon, 18 Mar 2024 16:00:06 -0500 Subject: [PATCH 126/189] Add actions for component tests A, B and C (#6256) --- tests/components/api/test.esp32-c3-idf.yaml | 13 +++++++++++++ tests/components/api/test.esp32-c3.yaml | 13 +++++++++++++ tests/components/api/test.esp32-idf.yaml | 13 +++++++++++++ tests/components/api/test.esp32.yaml | 13 +++++++++++++ tests/components/api/test.esp8266.yaml | 13 +++++++++++++ tests/components/api/test.rp2040.yaml | 13 +++++++++++++ 6 files changed, 78 insertions(+) diff --git a/tests/components/api/test.esp32-c3-idf.yaml b/tests/components/api/test.esp32-c3-idf.yaml index 8e7ca0fb06..3c56811b95 100644 --- a/tests/components/api/test.esp32-c3-idf.yaml +++ b/tests/components/api/test.esp32-c3-idf.yaml @@ -1,3 +1,16 @@ +esphome: + on_boot: + then: + - homeassistant.event: + event: esphome.button_pressed + data: + message: Button was pressed + - homeassistant.service: + service: notify.html5 + data: + message: Button was pressed + - homeassistant.tag_scanned: pulse + wifi: ssid: MySSID password: password1 diff --git a/tests/components/api/test.esp32-c3.yaml b/tests/components/api/test.esp32-c3.yaml index 8e7ca0fb06..3c56811b95 100644 --- a/tests/components/api/test.esp32-c3.yaml +++ b/tests/components/api/test.esp32-c3.yaml @@ -1,3 +1,16 @@ +esphome: + on_boot: + then: + - homeassistant.event: + event: esphome.button_pressed + data: + message: Button was pressed + - homeassistant.service: + service: notify.html5 + data: + message: Button was pressed + - homeassistant.tag_scanned: pulse + wifi: ssid: MySSID password: password1 diff --git a/tests/components/api/test.esp32-idf.yaml b/tests/components/api/test.esp32-idf.yaml index 8e7ca0fb06..3c56811b95 100644 --- a/tests/components/api/test.esp32-idf.yaml +++ b/tests/components/api/test.esp32-idf.yaml @@ -1,3 +1,16 @@ +esphome: + on_boot: + then: + - homeassistant.event: + event: esphome.button_pressed + data: + message: Button was pressed + - homeassistant.service: + service: notify.html5 + data: + message: Button was pressed + - homeassistant.tag_scanned: pulse + wifi: ssid: MySSID password: password1 diff --git a/tests/components/api/test.esp32.yaml b/tests/components/api/test.esp32.yaml index 8e7ca0fb06..3c56811b95 100644 --- a/tests/components/api/test.esp32.yaml +++ b/tests/components/api/test.esp32.yaml @@ -1,3 +1,16 @@ +esphome: + on_boot: + then: + - homeassistant.event: + event: esphome.button_pressed + data: + message: Button was pressed + - homeassistant.service: + service: notify.html5 + data: + message: Button was pressed + - homeassistant.tag_scanned: pulse + wifi: ssid: MySSID password: password1 diff --git a/tests/components/api/test.esp8266.yaml b/tests/components/api/test.esp8266.yaml index 8e7ca0fb06..3c56811b95 100644 --- a/tests/components/api/test.esp8266.yaml +++ b/tests/components/api/test.esp8266.yaml @@ -1,3 +1,16 @@ +esphome: + on_boot: + then: + - homeassistant.event: + event: esphome.button_pressed + data: + message: Button was pressed + - homeassistant.service: + service: notify.html5 + data: + message: Button was pressed + - homeassistant.tag_scanned: pulse + wifi: ssid: MySSID password: password1 diff --git a/tests/components/api/test.rp2040.yaml b/tests/components/api/test.rp2040.yaml index 8e7ca0fb06..3c56811b95 100644 --- a/tests/components/api/test.rp2040.yaml +++ b/tests/components/api/test.rp2040.yaml @@ -1,3 +1,16 @@ +esphome: + on_boot: + then: + - homeassistant.event: + event: esphome.button_pressed + data: + message: Button was pressed + - homeassistant.service: + service: notify.html5 + data: + message: Button was pressed + - homeassistant.tag_scanned: pulse + wifi: ssid: MySSID password: password1 From d5a8bea8e94a6ea4114ecf3e9cf79946b10f198e Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Mon, 18 Mar 2024 16:42:03 -0500 Subject: [PATCH 127/189] Add some components to the new testing framework (V) (#6231) --- tests/components/vbus/test.esp32-c3-idf.yaml | 42 ++++++++++++++ tests/components/vbus/test.esp32-c3.yaml | 42 ++++++++++++++ tests/components/vbus/test.esp32-idf.yaml | 42 ++++++++++++++ tests/components/vbus/test.esp32.yaml | 42 ++++++++++++++ tests/components/vbus/test.esp8266.yaml | 42 ++++++++++++++ tests/components/vbus/test.rp2040.yaml | 42 ++++++++++++++ .../veml3235/test.esp32-c3-idf.yaml | 15 +++++ tests/components/veml3235/test.esp32-c3.yaml | 15 +++++ tests/components/veml3235/test.esp32-idf.yaml | 15 +++++ tests/components/veml3235/test.esp32.yaml | 15 +++++ tests/components/veml3235/test.esp8266.yaml | 15 +++++ tests/components/veml3235/test.rp2040.yaml | 15 +++++ .../components/version/test.esp32-c3-idf.yaml | 3 + tests/components/version/test.esp32-c3.yaml | 3 + tests/components/version/test.esp32-idf.yaml | 3 + tests/components/version/test.esp32.yaml | 3 + tests/components/version/test.esp8266.yaml | 3 + tests/components/version/test.rp2040.yaml | 3 + .../components/vl53l0x/test.esp32-c3-idf.yaml | 12 ++++ tests/components/vl53l0x/test.esp32-c3.yaml | 12 ++++ tests/components/vl53l0x/test.esp32-idf.yaml | 12 ++++ tests/components/vl53l0x/test.esp32.yaml | 12 ++++ tests/components/vl53l0x/test.esp8266.yaml | 12 ++++ tests/components/vl53l0x/test.rp2040.yaml | 12 ++++ .../voice_assistant/test.esp32-c3-idf.yaml | 57 +++++++++++++++++++ .../voice_assistant/test.esp32-c3.yaml | 57 +++++++++++++++++++ .../voice_assistant/test.esp32-idf.yaml | 57 +++++++++++++++++++ .../voice_assistant/test.esp32.yaml | 57 +++++++++++++++++++ 28 files changed, 660 insertions(+) create mode 100644 tests/components/vbus/test.esp32-c3-idf.yaml create mode 100644 tests/components/vbus/test.esp32-c3.yaml create mode 100644 tests/components/vbus/test.esp32-idf.yaml create mode 100644 tests/components/vbus/test.esp32.yaml create mode 100644 tests/components/vbus/test.esp8266.yaml create mode 100644 tests/components/vbus/test.rp2040.yaml create mode 100644 tests/components/veml3235/test.esp32-c3-idf.yaml create mode 100644 tests/components/veml3235/test.esp32-c3.yaml create mode 100644 tests/components/veml3235/test.esp32-idf.yaml create mode 100644 tests/components/veml3235/test.esp32.yaml create mode 100644 tests/components/veml3235/test.esp8266.yaml create mode 100644 tests/components/veml3235/test.rp2040.yaml create mode 100644 tests/components/version/test.esp32-c3-idf.yaml create mode 100644 tests/components/version/test.esp32-c3.yaml create mode 100644 tests/components/version/test.esp32-idf.yaml create mode 100644 tests/components/version/test.esp32.yaml create mode 100644 tests/components/version/test.esp8266.yaml create mode 100644 tests/components/version/test.rp2040.yaml create mode 100644 tests/components/vl53l0x/test.esp32-c3-idf.yaml create mode 100644 tests/components/vl53l0x/test.esp32-c3.yaml create mode 100644 tests/components/vl53l0x/test.esp32-idf.yaml create mode 100644 tests/components/vl53l0x/test.esp32.yaml create mode 100644 tests/components/vl53l0x/test.esp8266.yaml create mode 100644 tests/components/vl53l0x/test.rp2040.yaml create mode 100644 tests/components/voice_assistant/test.esp32-c3-idf.yaml create mode 100644 tests/components/voice_assistant/test.esp32-c3.yaml create mode 100644 tests/components/voice_assistant/test.esp32-idf.yaml create mode 100644 tests/components/voice_assistant/test.esp32.yaml diff --git a/tests/components/vbus/test.esp32-c3-idf.yaml b/tests/components/vbus/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..67ee542031 --- /dev/null +++ b/tests/components/vbus/test.esp32-c3-idf.yaml @@ -0,0 +1,42 @@ +uart: + - id: uart_vbus + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +vbus: + +binary_sensor: + - platform: vbus + model: deltasol_bs_plus + relay1: + name: Relay 1 On + relay2: + name: Relay 2 On + sensor1_error: + name: Sensor 1 Error + - platform: vbus + model: custom + command: 0x100 + source: 0x1234 + dest: 0x10 + binary_sensors: + - id: vcustom_b + name: VBus Custom Binary Sensor + lambda: return x[0] & 1; + +sensor: + - platform: vbus + model: deltasol c + temperature_1: + name: Temperature 1 + temperature_2: + name: Temperature 2 + temperature_3: + name: Temperature 3 + operating_hours_1: + name: Operating Hours 1 + heat_quantity: + name: Heat Quantity + time: + name: System Time diff --git a/tests/components/vbus/test.esp32-c3.yaml b/tests/components/vbus/test.esp32-c3.yaml new file mode 100644 index 0000000000..67ee542031 --- /dev/null +++ b/tests/components/vbus/test.esp32-c3.yaml @@ -0,0 +1,42 @@ +uart: + - id: uart_vbus + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +vbus: + +binary_sensor: + - platform: vbus + model: deltasol_bs_plus + relay1: + name: Relay 1 On + relay2: + name: Relay 2 On + sensor1_error: + name: Sensor 1 Error + - platform: vbus + model: custom + command: 0x100 + source: 0x1234 + dest: 0x10 + binary_sensors: + - id: vcustom_b + name: VBus Custom Binary Sensor + lambda: return x[0] & 1; + +sensor: + - platform: vbus + model: deltasol c + temperature_1: + name: Temperature 1 + temperature_2: + name: Temperature 2 + temperature_3: + name: Temperature 3 + operating_hours_1: + name: Operating Hours 1 + heat_quantity: + name: Heat Quantity + time: + name: System Time diff --git a/tests/components/vbus/test.esp32-idf.yaml b/tests/components/vbus/test.esp32-idf.yaml new file mode 100644 index 0000000000..a0e5ca42cc --- /dev/null +++ b/tests/components/vbus/test.esp32-idf.yaml @@ -0,0 +1,42 @@ +uart: + - id: uart_vbus + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + +vbus: + +binary_sensor: + - platform: vbus + model: deltasol_bs_plus + relay1: + name: Relay 1 On + relay2: + name: Relay 2 On + sensor1_error: + name: Sensor 1 Error + - platform: vbus + model: custom + command: 0x100 + source: 0x1234 + dest: 0x10 + binary_sensors: + - id: vcustom_b + name: VBus Custom Binary Sensor + lambda: return x[0] & 1; + +sensor: + - platform: vbus + model: deltasol c + temperature_1: + name: Temperature 1 + temperature_2: + name: Temperature 2 + temperature_3: + name: Temperature 3 + operating_hours_1: + name: Operating Hours 1 + heat_quantity: + name: Heat Quantity + time: + name: System Time diff --git a/tests/components/vbus/test.esp32.yaml b/tests/components/vbus/test.esp32.yaml new file mode 100644 index 0000000000..a0e5ca42cc --- /dev/null +++ b/tests/components/vbus/test.esp32.yaml @@ -0,0 +1,42 @@ +uart: + - id: uart_vbus + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + +vbus: + +binary_sensor: + - platform: vbus + model: deltasol_bs_plus + relay1: + name: Relay 1 On + relay2: + name: Relay 2 On + sensor1_error: + name: Sensor 1 Error + - platform: vbus + model: custom + command: 0x100 + source: 0x1234 + dest: 0x10 + binary_sensors: + - id: vcustom_b + name: VBus Custom Binary Sensor + lambda: return x[0] & 1; + +sensor: + - platform: vbus + model: deltasol c + temperature_1: + name: Temperature 1 + temperature_2: + name: Temperature 2 + temperature_3: + name: Temperature 3 + operating_hours_1: + name: Operating Hours 1 + heat_quantity: + name: Heat Quantity + time: + name: System Time diff --git a/tests/components/vbus/test.esp8266.yaml b/tests/components/vbus/test.esp8266.yaml new file mode 100644 index 0000000000..67ee542031 --- /dev/null +++ b/tests/components/vbus/test.esp8266.yaml @@ -0,0 +1,42 @@ +uart: + - id: uart_vbus + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +vbus: + +binary_sensor: + - platform: vbus + model: deltasol_bs_plus + relay1: + name: Relay 1 On + relay2: + name: Relay 2 On + sensor1_error: + name: Sensor 1 Error + - platform: vbus + model: custom + command: 0x100 + source: 0x1234 + dest: 0x10 + binary_sensors: + - id: vcustom_b + name: VBus Custom Binary Sensor + lambda: return x[0] & 1; + +sensor: + - platform: vbus + model: deltasol c + temperature_1: + name: Temperature 1 + temperature_2: + name: Temperature 2 + temperature_3: + name: Temperature 3 + operating_hours_1: + name: Operating Hours 1 + heat_quantity: + name: Heat Quantity + time: + name: System Time diff --git a/tests/components/vbus/test.rp2040.yaml b/tests/components/vbus/test.rp2040.yaml new file mode 100644 index 0000000000..67ee542031 --- /dev/null +++ b/tests/components/vbus/test.rp2040.yaml @@ -0,0 +1,42 @@ +uart: + - id: uart_vbus + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +vbus: + +binary_sensor: + - platform: vbus + model: deltasol_bs_plus + relay1: + name: Relay 1 On + relay2: + name: Relay 2 On + sensor1_error: + name: Sensor 1 Error + - platform: vbus + model: custom + command: 0x100 + source: 0x1234 + dest: 0x10 + binary_sensors: + - id: vcustom_b + name: VBus Custom Binary Sensor + lambda: return x[0] & 1; + +sensor: + - platform: vbus + model: deltasol c + temperature_1: + name: Temperature 1 + temperature_2: + name: Temperature 2 + temperature_3: + name: Temperature 3 + operating_hours_1: + name: Operating Hours 1 + heat_quantity: + name: Heat Quantity + time: + name: System Time diff --git a/tests/components/veml3235/test.esp32-c3-idf.yaml b/tests/components/veml3235/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..1f79c5f50c --- /dev/null +++ b/tests/components/veml3235/test.esp32-c3-idf.yaml @@ -0,0 +1,15 @@ +i2c: + - id: i2c_veml3235 + scl: 5 + sda: 4 + +sensor: + - platform: veml3235 + id: veml3235_sensor + name: VEML3235 Light Sensor + auto_gain: true + auto_gain_threshold_high: 90% + auto_gain_threshold_low: 15% + digital_gain: 1X + gain: 1X + integration_time: 50ms diff --git a/tests/components/veml3235/test.esp32-c3.yaml b/tests/components/veml3235/test.esp32-c3.yaml new file mode 100644 index 0000000000..1f79c5f50c --- /dev/null +++ b/tests/components/veml3235/test.esp32-c3.yaml @@ -0,0 +1,15 @@ +i2c: + - id: i2c_veml3235 + scl: 5 + sda: 4 + +sensor: + - platform: veml3235 + id: veml3235_sensor + name: VEML3235 Light Sensor + auto_gain: true + auto_gain_threshold_high: 90% + auto_gain_threshold_low: 15% + digital_gain: 1X + gain: 1X + integration_time: 50ms diff --git a/tests/components/veml3235/test.esp32-idf.yaml b/tests/components/veml3235/test.esp32-idf.yaml new file mode 100644 index 0000000000..3442fa4317 --- /dev/null +++ b/tests/components/veml3235/test.esp32-idf.yaml @@ -0,0 +1,15 @@ +i2c: + - id: i2c_veml3235 + scl: 16 + sda: 17 + +sensor: + - platform: veml3235 + id: veml3235_sensor + name: VEML3235 Light Sensor + auto_gain: true + auto_gain_threshold_high: 90% + auto_gain_threshold_low: 15% + digital_gain: 1X + gain: 1X + integration_time: 50ms diff --git a/tests/components/veml3235/test.esp32.yaml b/tests/components/veml3235/test.esp32.yaml new file mode 100644 index 0000000000..3442fa4317 --- /dev/null +++ b/tests/components/veml3235/test.esp32.yaml @@ -0,0 +1,15 @@ +i2c: + - id: i2c_veml3235 + scl: 16 + sda: 17 + +sensor: + - platform: veml3235 + id: veml3235_sensor + name: VEML3235 Light Sensor + auto_gain: true + auto_gain_threshold_high: 90% + auto_gain_threshold_low: 15% + digital_gain: 1X + gain: 1X + integration_time: 50ms diff --git a/tests/components/veml3235/test.esp8266.yaml b/tests/components/veml3235/test.esp8266.yaml new file mode 100644 index 0000000000..1f79c5f50c --- /dev/null +++ b/tests/components/veml3235/test.esp8266.yaml @@ -0,0 +1,15 @@ +i2c: + - id: i2c_veml3235 + scl: 5 + sda: 4 + +sensor: + - platform: veml3235 + id: veml3235_sensor + name: VEML3235 Light Sensor + auto_gain: true + auto_gain_threshold_high: 90% + auto_gain_threshold_low: 15% + digital_gain: 1X + gain: 1X + integration_time: 50ms diff --git a/tests/components/veml3235/test.rp2040.yaml b/tests/components/veml3235/test.rp2040.yaml new file mode 100644 index 0000000000..1f79c5f50c --- /dev/null +++ b/tests/components/veml3235/test.rp2040.yaml @@ -0,0 +1,15 @@ +i2c: + - id: i2c_veml3235 + scl: 5 + sda: 4 + +sensor: + - platform: veml3235 + id: veml3235_sensor + name: VEML3235 Light Sensor + auto_gain: true + auto_gain_threshold_high: 90% + auto_gain_threshold_low: 15% + digital_gain: 1X + gain: 1X + integration_time: 50ms diff --git a/tests/components/version/test.esp32-c3-idf.yaml b/tests/components/version/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..7713afc37c --- /dev/null +++ b/tests/components/version/test.esp32-c3-idf.yaml @@ -0,0 +1,3 @@ +text_sensor: + - platform: version + name: "ESPHome Version" diff --git a/tests/components/version/test.esp32-c3.yaml b/tests/components/version/test.esp32-c3.yaml new file mode 100644 index 0000000000..7713afc37c --- /dev/null +++ b/tests/components/version/test.esp32-c3.yaml @@ -0,0 +1,3 @@ +text_sensor: + - platform: version + name: "ESPHome Version" diff --git a/tests/components/version/test.esp32-idf.yaml b/tests/components/version/test.esp32-idf.yaml new file mode 100644 index 0000000000..7713afc37c --- /dev/null +++ b/tests/components/version/test.esp32-idf.yaml @@ -0,0 +1,3 @@ +text_sensor: + - platform: version + name: "ESPHome Version" diff --git a/tests/components/version/test.esp32.yaml b/tests/components/version/test.esp32.yaml new file mode 100644 index 0000000000..7713afc37c --- /dev/null +++ b/tests/components/version/test.esp32.yaml @@ -0,0 +1,3 @@ +text_sensor: + - platform: version + name: "ESPHome Version" diff --git a/tests/components/version/test.esp8266.yaml b/tests/components/version/test.esp8266.yaml new file mode 100644 index 0000000000..7713afc37c --- /dev/null +++ b/tests/components/version/test.esp8266.yaml @@ -0,0 +1,3 @@ +text_sensor: + - platform: version + name: "ESPHome Version" diff --git a/tests/components/version/test.rp2040.yaml b/tests/components/version/test.rp2040.yaml new file mode 100644 index 0000000000..7713afc37c --- /dev/null +++ b/tests/components/version/test.rp2040.yaml @@ -0,0 +1,3 @@ +text_sensor: + - platform: version + name: "ESPHome Version" diff --git a/tests/components/vl53l0x/test.esp32-c3-idf.yaml b/tests/components/vl53l0x/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..832f7dcfbc --- /dev/null +++ b/tests/components/vl53l0x/test.esp32-c3-idf.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_vl53l0x + scl: 5 + sda: 4 + +sensor: + - platform: vl53l0x + name: VL53L0x Distance + address: 0x29 + enable_pin: 3 + timeout: 200us + update_interval: 60s diff --git a/tests/components/vl53l0x/test.esp32-c3.yaml b/tests/components/vl53l0x/test.esp32-c3.yaml new file mode 100644 index 0000000000..832f7dcfbc --- /dev/null +++ b/tests/components/vl53l0x/test.esp32-c3.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_vl53l0x + scl: 5 + sda: 4 + +sensor: + - platform: vl53l0x + name: VL53L0x Distance + address: 0x29 + enable_pin: 3 + timeout: 200us + update_interval: 60s diff --git a/tests/components/vl53l0x/test.esp32-idf.yaml b/tests/components/vl53l0x/test.esp32-idf.yaml new file mode 100644 index 0000000000..8f35de0e72 --- /dev/null +++ b/tests/components/vl53l0x/test.esp32-idf.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_vl53l0x + scl: 16 + sda: 17 + +sensor: + - platform: vl53l0x + name: VL53L0x Distance + address: 0x29 + enable_pin: 3 + timeout: 200us + update_interval: 60s diff --git a/tests/components/vl53l0x/test.esp32.yaml b/tests/components/vl53l0x/test.esp32.yaml new file mode 100644 index 0000000000..8f35de0e72 --- /dev/null +++ b/tests/components/vl53l0x/test.esp32.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_vl53l0x + scl: 16 + sda: 17 + +sensor: + - platform: vl53l0x + name: VL53L0x Distance + address: 0x29 + enable_pin: 3 + timeout: 200us + update_interval: 60s diff --git a/tests/components/vl53l0x/test.esp8266.yaml b/tests/components/vl53l0x/test.esp8266.yaml new file mode 100644 index 0000000000..832f7dcfbc --- /dev/null +++ b/tests/components/vl53l0x/test.esp8266.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_vl53l0x + scl: 5 + sda: 4 + +sensor: + - platform: vl53l0x + name: VL53L0x Distance + address: 0x29 + enable_pin: 3 + timeout: 200us + update_interval: 60s diff --git a/tests/components/vl53l0x/test.rp2040.yaml b/tests/components/vl53l0x/test.rp2040.yaml new file mode 100644 index 0000000000..832f7dcfbc --- /dev/null +++ b/tests/components/vl53l0x/test.rp2040.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_vl53l0x + scl: 5 + sda: 4 + +sensor: + - platform: vl53l0x + name: VL53L0x Distance + address: 0x29 + enable_pin: 3 + timeout: 200us + update_interval: 60s diff --git a/tests/components/voice_assistant/test.esp32-c3-idf.yaml b/tests/components/voice_assistant/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..248ae4d0dc --- /dev/null +++ b/tests/components/voice_assistant/test.esp32-c3-idf.yaml @@ -0,0 +1,57 @@ +esphome: + on_boot: + then: + - voice_assistant.start + - voice_assistant.start_continuous + - voice_assistant.stop + +wifi: + ssid: MySSID + password: password1 + +api: + +i2s_audio: + i2s_lrclk_pin: 6 + i2s_bclk_pin: 7 + i2s_mclk_pin: 5 + +microphone: + - platform: i2s_audio + id: mic_id_external + i2s_din_pin: 3 + adc_type: external + pdm: false + +speaker: + - platform: i2s_audio + id: speaker_id + dac_type: external + i2s_dout_pin: 2 + mode: mono + +voice_assistant: + microphone: mic_id_external + speaker: speaker_id + on_listening: + - logger.log: "Voice assistant microphone listening" + on_start: + - logger.log: "Voice assistant started" + on_stt_end: + - logger.log: + format: "Voice assistant STT ended with result %s" + args: [x.c_str()] + on_tts_start: + - logger.log: + format: "Voice assistant TTS started with text %s" + args: [x.c_str()] + on_tts_end: + - logger.log: + format: "Voice assistant TTS ended with url %s" + args: [x.c_str()] + on_end: + - logger.log: "Voice assistant ended" + on_error: + - logger.log: + format: "Voice assistant error - code %s, message: %s" + args: [code.c_str(), message.c_str()] diff --git a/tests/components/voice_assistant/test.esp32-c3.yaml b/tests/components/voice_assistant/test.esp32-c3.yaml new file mode 100644 index 0000000000..248ae4d0dc --- /dev/null +++ b/tests/components/voice_assistant/test.esp32-c3.yaml @@ -0,0 +1,57 @@ +esphome: + on_boot: + then: + - voice_assistant.start + - voice_assistant.start_continuous + - voice_assistant.stop + +wifi: + ssid: MySSID + password: password1 + +api: + +i2s_audio: + i2s_lrclk_pin: 6 + i2s_bclk_pin: 7 + i2s_mclk_pin: 5 + +microphone: + - platform: i2s_audio + id: mic_id_external + i2s_din_pin: 3 + adc_type: external + pdm: false + +speaker: + - platform: i2s_audio + id: speaker_id + dac_type: external + i2s_dout_pin: 2 + mode: mono + +voice_assistant: + microphone: mic_id_external + speaker: speaker_id + on_listening: + - logger.log: "Voice assistant microphone listening" + on_start: + - logger.log: "Voice assistant started" + on_stt_end: + - logger.log: + format: "Voice assistant STT ended with result %s" + args: [x.c_str()] + on_tts_start: + - logger.log: + format: "Voice assistant TTS started with text %s" + args: [x.c_str()] + on_tts_end: + - logger.log: + format: "Voice assistant TTS ended with url %s" + args: [x.c_str()] + on_end: + - logger.log: "Voice assistant ended" + on_error: + - logger.log: + format: "Voice assistant error - code %s, message: %s" + args: [code.c_str(), message.c_str()] diff --git a/tests/components/voice_assistant/test.esp32-idf.yaml b/tests/components/voice_assistant/test.esp32-idf.yaml new file mode 100644 index 0000000000..2e0209311d --- /dev/null +++ b/tests/components/voice_assistant/test.esp32-idf.yaml @@ -0,0 +1,57 @@ +esphome: + on_boot: + then: + - voice_assistant.start + - voice_assistant.start_continuous + - voice_assistant.stop + +wifi: + ssid: MySSID + password: password1 + +api: + +i2s_audio: + i2s_lrclk_pin: 16 + i2s_bclk_pin: 17 + i2s_mclk_pin: 15 + +microphone: + - platform: i2s_audio + id: mic_id_external + i2s_din_pin: 13 + adc_type: external + pdm: false + +speaker: + - platform: i2s_audio + id: speaker_id + dac_type: external + i2s_dout_pin: 12 + mode: mono + +voice_assistant: + microphone: mic_id_external + speaker: speaker_id + on_listening: + - logger.log: "Voice assistant microphone listening" + on_start: + - logger.log: "Voice assistant started" + on_stt_end: + - logger.log: + format: "Voice assistant STT ended with result %s" + args: [x.c_str()] + on_tts_start: + - logger.log: + format: "Voice assistant TTS started with text %s" + args: [x.c_str()] + on_tts_end: + - logger.log: + format: "Voice assistant TTS ended with url %s" + args: [x.c_str()] + on_end: + - logger.log: "Voice assistant ended" + on_error: + - logger.log: + format: "Voice assistant error - code %s, message: %s" + args: [code.c_str(), message.c_str()] diff --git a/tests/components/voice_assistant/test.esp32.yaml b/tests/components/voice_assistant/test.esp32.yaml new file mode 100644 index 0000000000..2e0209311d --- /dev/null +++ b/tests/components/voice_assistant/test.esp32.yaml @@ -0,0 +1,57 @@ +esphome: + on_boot: + then: + - voice_assistant.start + - voice_assistant.start_continuous + - voice_assistant.stop + +wifi: + ssid: MySSID + password: password1 + +api: + +i2s_audio: + i2s_lrclk_pin: 16 + i2s_bclk_pin: 17 + i2s_mclk_pin: 15 + +microphone: + - platform: i2s_audio + id: mic_id_external + i2s_din_pin: 13 + adc_type: external + pdm: false + +speaker: + - platform: i2s_audio + id: speaker_id + dac_type: external + i2s_dout_pin: 12 + mode: mono + +voice_assistant: + microphone: mic_id_external + speaker: speaker_id + on_listening: + - logger.log: "Voice assistant microphone listening" + on_start: + - logger.log: "Voice assistant started" + on_stt_end: + - logger.log: + format: "Voice assistant STT ended with result %s" + args: [x.c_str()] + on_tts_start: + - logger.log: + format: "Voice assistant TTS started with text %s" + args: [x.c_str()] + on_tts_end: + - logger.log: + format: "Voice assistant TTS ended with url %s" + args: [x.c_str()] + on_end: + - logger.log: "Voice assistant ended" + on_error: + - logger.log: + format: "Voice assistant error - code %s, message: %s" + args: [code.c_str(), message.c_str()] From 95443a43540306ef68cf8ec3fe09cf8d83c92e8c Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Mon, 18 Mar 2024 18:49:00 -0500 Subject: [PATCH 128/189] Add some components to the new testing framework (X,Y,Z) (#6233) --- tests/components/x9c/test.esp32-c3-idf.yaml | 7 ++++ tests/components/x9c/test.esp32-c3.yaml | 7 ++++ tests/components/x9c/test.esp32-idf.yaml | 7 ++++ tests/components/x9c/test.esp32.yaml | 7 ++++ tests/components/x9c/test.esp8266.yaml | 7 ++++ tests/components/x9c/test.rp2040.yaml | 7 ++++ .../xgzp68xx/test.esp32-c3-idf.yaml | 12 +++++++ tests/components/xgzp68xx/test.esp32-c3.yaml | 12 +++++++ tests/components/xgzp68xx/test.esp32-idf.yaml | 12 +++++++ tests/components/xgzp68xx/test.esp32.yaml | 12 +++++++ tests/components/xgzp68xx/test.esp8266.yaml | 12 +++++++ tests/components/xgzp68xx/test.rp2040.yaml | 12 +++++++ .../xiaomi_ble/test.esp32-c3-idf.yaml | 3 ++ .../components/xiaomi_ble/test.esp32-c3.yaml | 3 ++ .../components/xiaomi_ble/test.esp32-idf.yaml | 3 ++ tests/components/xiaomi_ble/test.esp32.yaml | 3 ++ .../xiaomi_cgd1/test.esp32-c3-idf.yaml | 12 +++++++ .../components/xiaomi_cgd1/test.esp32-c3.yaml | 12 +++++++ .../xiaomi_cgd1/test.esp32-idf.yaml | 12 +++++++ tests/components/xiaomi_cgd1/test.esp32.yaml | 12 +++++++ .../xiaomi_cgdk2/test.esp32-c3-idf.yaml | 12 +++++++ .../xiaomi_cgdk2/test.esp32-c3.yaml | 12 +++++++ .../xiaomi_cgdk2/test.esp32-idf.yaml | 12 +++++++ tests/components/xiaomi_cgdk2/test.esp32.yaml | 12 +++++++ .../xiaomi_cgg1/test.esp32-c3-idf.yaml | 12 +++++++ .../components/xiaomi_cgg1/test.esp32-c3.yaml | 12 +++++++ .../xiaomi_cgg1/test.esp32-idf.yaml | 12 +++++++ tests/components/xiaomi_cgg1/test.esp32.yaml | 12 +++++++ .../xiaomi_cgpr1/test.esp32-c3-idf.yaml | 13 ++++++++ .../xiaomi_cgpr1/test.esp32-c3.yaml | 13 ++++++++ .../xiaomi_cgpr1/test.esp32-idf.yaml | 13 ++++++++ tests/components/xiaomi_cgpr1/test.esp32.yaml | 13 ++++++++ .../xiaomi_gcls002/test.esp32-c3-idf.yaml | 13 ++++++++ .../xiaomi_gcls002/test.esp32-c3.yaml | 13 ++++++++ .../xiaomi_gcls002/test.esp32-idf.yaml | 13 ++++++++ .../components/xiaomi_gcls002/test.esp32.yaml | 13 ++++++++ .../xiaomi_hhccjcy01/test.esp32-c3-idf.yaml | 15 +++++++++ .../xiaomi_hhccjcy01/test.esp32-c3.yaml | 15 +++++++++ .../xiaomi_hhccjcy01/test.esp32-idf.yaml | 15 +++++++++ .../xiaomi_hhccjcy01/test.esp32.yaml | 15 +++++++++ .../xiaomi_hhccpot002/test.esp32-c3-idf.yaml | 9 +++++ .../xiaomi_hhccpot002/test.esp32-c3.yaml | 9 +++++ .../xiaomi_hhccpot002/test.esp32-idf.yaml | 9 +++++ .../xiaomi_hhccpot002/test.esp32.yaml | 9 +++++ .../xiaomi_jqjcy01ym/test.esp32-c3-idf.yaml | 13 ++++++++ .../xiaomi_jqjcy01ym/test.esp32-c3.yaml | 13 ++++++++ .../xiaomi_jqjcy01ym/test.esp32-idf.yaml | 13 ++++++++ .../xiaomi_jqjcy01ym/test.esp32.yaml | 13 ++++++++ .../xiaomi_lywsd02/test.esp32-c3-idf.yaml | 11 +++++++ .../xiaomi_lywsd02/test.esp32-c3.yaml | 11 +++++++ .../xiaomi_lywsd02/test.esp32-idf.yaml | 11 +++++++ .../components/xiaomi_lywsd02/test.esp32.yaml | 11 +++++++ .../xiaomi_lywsd03mmc/test.esp32-c3-idf.yaml | 12 +++++++ .../xiaomi_lywsd03mmc/test.esp32-c3.yaml | 12 +++++++ .../xiaomi_lywsd03mmc/test.esp32-idf.yaml | 12 +++++++ .../xiaomi_lywsd03mmc/test.esp32.yaml | 12 +++++++ .../xiaomi_lywsdcgq/test.esp32-c3-idf.yaml | 11 +++++++ .../xiaomi_lywsdcgq/test.esp32-c3.yaml | 11 +++++++ .../xiaomi_lywsdcgq/test.esp32-idf.yaml | 11 +++++++ .../xiaomi_lywsdcgq/test.esp32.yaml | 11 +++++++ .../xiaomi_mhoc303/test.esp32-c3-idf.yaml | 11 +++++++ .../xiaomi_mhoc303/test.esp32-c3.yaml | 11 +++++++ .../xiaomi_mhoc303/test.esp32-idf.yaml | 11 +++++++ .../components/xiaomi_mhoc303/test.esp32.yaml | 11 +++++++ .../xiaomi_mhoc401/test.esp32-c3-idf.yaml | 12 +++++++ .../xiaomi_mhoc401/test.esp32-c3.yaml | 12 +++++++ .../xiaomi_mhoc401/test.esp32-idf.yaml | 12 +++++++ .../components/xiaomi_mhoc401/test.esp32.yaml | 12 +++++++ .../test.esp32-c3-idf.yaml | 9 +++++ .../xiaomi_miscale copy/test.esp32-c3.yaml | 9 +++++ .../xiaomi_miscale copy/test.esp32-idf.yaml | 9 +++++ .../xiaomi_miscale copy/test.esp32.yaml | 9 +++++ .../xiaomi_miscale/test.esp32-c3-idf.yaml | 9 +++++ .../xiaomi_miscale/test.esp32-c3.yaml | 9 +++++ .../xiaomi_miscale/test.esp32-idf.yaml | 9 +++++ .../components/xiaomi_miscale/test.esp32.yaml | 9 +++++ .../xiaomi_mjyd02yla/test.esp32-c3-idf.yaml | 13 ++++++++ .../xiaomi_mjyd02yla/test.esp32-c3.yaml | 13 ++++++++ .../xiaomi_mjyd02yla/test.esp32-idf.yaml | 13 ++++++++ .../xiaomi_mjyd02yla/test.esp32.yaml | 13 ++++++++ .../xiaomi_mue4094rt/test.esp32-c3-idf.yaml | 7 ++++ .../xiaomi_mue4094rt/test.esp32-c3.yaml | 7 ++++ .../xiaomi_mue4094rt/test.esp32-idf.yaml | 7 ++++ .../xiaomi_mue4094rt/test.esp32.yaml | 7 ++++ .../xiaomi_rtcgq02lm/test.esp32-c3-idf.yaml | 22 +++++++++++++ .../xiaomi_rtcgq02lm/test.esp32-c3.yaml | 22 +++++++++++++ .../xiaomi_rtcgq02lm/test.esp32-idf.yaml | 22 +++++++++++++ .../xiaomi_rtcgq02lm/test.esp32.yaml | 22 +++++++++++++ .../xiaomi_wx08zm/test.esp32-c3-idf.yaml | 10 ++++++ .../xiaomi_wx08zm/test.esp32-c3.yaml | 10 ++++++ .../xiaomi_wx08zm/test.esp32-idf.yaml | 10 ++++++ .../components/xiaomi_wx08zm/test.esp32.yaml | 10 ++++++ .../components/xl9535/test.esp32-c3-idf.yaml | 26 +++++++++++++++ tests/components/xl9535/test.esp32-c3.yaml | 26 +++++++++++++++ tests/components/xl9535/test.esp32-idf.yaml | 26 +++++++++++++++ tests/components/xl9535/test.esp32.yaml | 26 +++++++++++++++ tests/components/xl9535/test.esp8266.yaml | 26 +++++++++++++++ tests/components/xl9535/test.rp2040.yaml | 26 +++++++++++++++ .../components/xpt2046/test.esp32-c3-idf.yaml | 33 +++++++++++++++++++ tests/components/xpt2046/test.esp32-c3.yaml | 33 +++++++++++++++++++ tests/components/xpt2046/test.esp32-idf.yaml | 33 +++++++++++++++++++ tests/components/xpt2046/test.esp32.yaml | 33 +++++++++++++++++++ tests/components/xpt2046/test.esp8266.yaml | 33 +++++++++++++++++++ tests/components/xpt2046/test.rp2040.yaml | 33 +++++++++++++++++++ .../components/yashima/test.esp32-c3-idf.yaml | 7 ++++ tests/components/yashima/test.esp32-c3.yaml | 7 ++++ tests/components/yashima/test.esp32-idf.yaml | 7 ++++ tests/components/yashima/test.esp32.yaml | 7 ++++ tests/components/yashima/test.esp8266.yaml | 7 ++++ .../components/zhlt01/test.esp32-c3-idf.yaml | 7 ++++ tests/components/zhlt01/test.esp32-c3.yaml | 7 ++++ tests/components/zhlt01/test.esp32-idf.yaml | 7 ++++ tests/components/zhlt01/test.esp32.yaml | 7 ++++ tests/components/zhlt01/test.esp8266.yaml | 7 ++++ .../zio_ultrasonic/test.esp32-c3-idf.yaml | 9 +++++ .../zio_ultrasonic/test.esp32-c3.yaml | 9 +++++ .../zio_ultrasonic/test.esp32-idf.yaml | 9 +++++ .../components/zio_ultrasonic/test.esp32.yaml | 9 +++++ .../zio_ultrasonic/test.esp8266.yaml | 9 +++++ .../zio_ultrasonic/test.rp2040.yaml | 9 +++++ .../components/zyaura/test.esp32-c3-idf.yaml | 10 ++++++ tests/components/zyaura/test.esp32-c3.yaml | 10 ++++++ tests/components/zyaura/test.esp32-idf.yaml | 10 ++++++ tests/components/zyaura/test.esp32.yaml | 10 ++++++ tests/components/zyaura/test.esp8266.yaml | 10 ++++++ tests/components/zyaura/test.rp2040.yaml | 10 ++++++ 126 files changed, 1568 insertions(+) create mode 100644 tests/components/x9c/test.esp32-c3-idf.yaml create mode 100644 tests/components/x9c/test.esp32-c3.yaml create mode 100644 tests/components/x9c/test.esp32-idf.yaml create mode 100644 tests/components/x9c/test.esp32.yaml create mode 100644 tests/components/x9c/test.esp8266.yaml create mode 100644 tests/components/x9c/test.rp2040.yaml create mode 100644 tests/components/xgzp68xx/test.esp32-c3-idf.yaml create mode 100644 tests/components/xgzp68xx/test.esp32-c3.yaml create mode 100644 tests/components/xgzp68xx/test.esp32-idf.yaml create mode 100644 tests/components/xgzp68xx/test.esp32.yaml create mode 100644 tests/components/xgzp68xx/test.esp8266.yaml create mode 100644 tests/components/xgzp68xx/test.rp2040.yaml create mode 100644 tests/components/xiaomi_ble/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_ble/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_ble/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_ble/test.esp32.yaml create mode 100644 tests/components/xiaomi_cgd1/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_cgd1/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_cgd1/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_cgd1/test.esp32.yaml create mode 100644 tests/components/xiaomi_cgdk2/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_cgdk2/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_cgdk2/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_cgdk2/test.esp32.yaml create mode 100644 tests/components/xiaomi_cgg1/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_cgg1/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_cgg1/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_cgg1/test.esp32.yaml create mode 100644 tests/components/xiaomi_cgpr1/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_cgpr1/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_cgpr1/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_cgpr1/test.esp32.yaml create mode 100644 tests/components/xiaomi_gcls002/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_gcls002/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_gcls002/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_gcls002/test.esp32.yaml create mode 100644 tests/components/xiaomi_hhccjcy01/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_hhccjcy01/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_hhccjcy01/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_hhccjcy01/test.esp32.yaml create mode 100644 tests/components/xiaomi_hhccpot002/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_hhccpot002/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_hhccpot002/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_hhccpot002/test.esp32.yaml create mode 100644 tests/components/xiaomi_jqjcy01ym/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_jqjcy01ym/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_jqjcy01ym/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_jqjcy01ym/test.esp32.yaml create mode 100644 tests/components/xiaomi_lywsd02/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_lywsd02/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_lywsd02/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_lywsd02/test.esp32.yaml create mode 100644 tests/components/xiaomi_lywsd03mmc/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_lywsd03mmc/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_lywsd03mmc/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_lywsd03mmc/test.esp32.yaml create mode 100644 tests/components/xiaomi_lywsdcgq/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_lywsdcgq/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_lywsdcgq/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_lywsdcgq/test.esp32.yaml create mode 100644 tests/components/xiaomi_mhoc303/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_mhoc303/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_mhoc303/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_mhoc303/test.esp32.yaml create mode 100644 tests/components/xiaomi_mhoc401/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_mhoc401/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_mhoc401/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_mhoc401/test.esp32.yaml create mode 100644 tests/components/xiaomi_miscale copy/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_miscale copy/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_miscale copy/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_miscale copy/test.esp32.yaml create mode 100644 tests/components/xiaomi_miscale/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_miscale/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_miscale/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_miscale/test.esp32.yaml create mode 100644 tests/components/xiaomi_mjyd02yla/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_mjyd02yla/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_mjyd02yla/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_mjyd02yla/test.esp32.yaml create mode 100644 tests/components/xiaomi_mue4094rt/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_mue4094rt/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_mue4094rt/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_mue4094rt/test.esp32.yaml create mode 100644 tests/components/xiaomi_rtcgq02lm/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_rtcgq02lm/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_rtcgq02lm/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_rtcgq02lm/test.esp32.yaml create mode 100644 tests/components/xiaomi_wx08zm/test.esp32-c3-idf.yaml create mode 100644 tests/components/xiaomi_wx08zm/test.esp32-c3.yaml create mode 100644 tests/components/xiaomi_wx08zm/test.esp32-idf.yaml create mode 100644 tests/components/xiaomi_wx08zm/test.esp32.yaml create mode 100644 tests/components/xl9535/test.esp32-c3-idf.yaml create mode 100644 tests/components/xl9535/test.esp32-c3.yaml create mode 100644 tests/components/xl9535/test.esp32-idf.yaml create mode 100644 tests/components/xl9535/test.esp32.yaml create mode 100644 tests/components/xl9535/test.esp8266.yaml create mode 100644 tests/components/xl9535/test.rp2040.yaml create mode 100644 tests/components/xpt2046/test.esp32-c3-idf.yaml create mode 100644 tests/components/xpt2046/test.esp32-c3.yaml create mode 100644 tests/components/xpt2046/test.esp32-idf.yaml create mode 100644 tests/components/xpt2046/test.esp32.yaml create mode 100644 tests/components/xpt2046/test.esp8266.yaml create mode 100644 tests/components/xpt2046/test.rp2040.yaml create mode 100644 tests/components/yashima/test.esp32-c3-idf.yaml create mode 100644 tests/components/yashima/test.esp32-c3.yaml create mode 100644 tests/components/yashima/test.esp32-idf.yaml create mode 100644 tests/components/yashima/test.esp32.yaml create mode 100644 tests/components/yashima/test.esp8266.yaml create mode 100644 tests/components/zhlt01/test.esp32-c3-idf.yaml create mode 100644 tests/components/zhlt01/test.esp32-c3.yaml create mode 100644 tests/components/zhlt01/test.esp32-idf.yaml create mode 100644 tests/components/zhlt01/test.esp32.yaml create mode 100644 tests/components/zhlt01/test.esp8266.yaml create mode 100644 tests/components/zio_ultrasonic/test.esp32-c3-idf.yaml create mode 100644 tests/components/zio_ultrasonic/test.esp32-c3.yaml create mode 100644 tests/components/zio_ultrasonic/test.esp32-idf.yaml create mode 100644 tests/components/zio_ultrasonic/test.esp32.yaml create mode 100644 tests/components/zio_ultrasonic/test.esp8266.yaml create mode 100644 tests/components/zio_ultrasonic/test.rp2040.yaml create mode 100644 tests/components/zyaura/test.esp32-c3-idf.yaml create mode 100644 tests/components/zyaura/test.esp32-c3.yaml create mode 100644 tests/components/zyaura/test.esp32-idf.yaml create mode 100644 tests/components/zyaura/test.esp32.yaml create mode 100644 tests/components/zyaura/test.esp8266.yaml create mode 100644 tests/components/zyaura/test.rp2040.yaml diff --git a/tests/components/x9c/test.esp32-c3-idf.yaml b/tests/components/x9c/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..a0480aa68f --- /dev/null +++ b/tests/components/x9c/test.esp32-c3-idf.yaml @@ -0,0 +1,7 @@ +output: + - platform: x9c + id: test_x9c + cs_pin: 3 + inc_pin: 4 + ud_pin: 5 + initial_value: 0.5 diff --git a/tests/components/x9c/test.esp32-c3.yaml b/tests/components/x9c/test.esp32-c3.yaml new file mode 100644 index 0000000000..a0480aa68f --- /dev/null +++ b/tests/components/x9c/test.esp32-c3.yaml @@ -0,0 +1,7 @@ +output: + - platform: x9c + id: test_x9c + cs_pin: 3 + inc_pin: 4 + ud_pin: 5 + initial_value: 0.5 diff --git a/tests/components/x9c/test.esp32-idf.yaml b/tests/components/x9c/test.esp32-idf.yaml new file mode 100644 index 0000000000..28b18f7a92 --- /dev/null +++ b/tests/components/x9c/test.esp32-idf.yaml @@ -0,0 +1,7 @@ +output: + - platform: x9c + id: test_x9c + cs_pin: 13 + inc_pin: 14 + ud_pin: 15 + initial_value: 0.5 diff --git a/tests/components/x9c/test.esp32.yaml b/tests/components/x9c/test.esp32.yaml new file mode 100644 index 0000000000..28b18f7a92 --- /dev/null +++ b/tests/components/x9c/test.esp32.yaml @@ -0,0 +1,7 @@ +output: + - platform: x9c + id: test_x9c + cs_pin: 13 + inc_pin: 14 + ud_pin: 15 + initial_value: 0.5 diff --git a/tests/components/x9c/test.esp8266.yaml b/tests/components/x9c/test.esp8266.yaml new file mode 100644 index 0000000000..28b18f7a92 --- /dev/null +++ b/tests/components/x9c/test.esp8266.yaml @@ -0,0 +1,7 @@ +output: + - platform: x9c + id: test_x9c + cs_pin: 13 + inc_pin: 14 + ud_pin: 15 + initial_value: 0.5 diff --git a/tests/components/x9c/test.rp2040.yaml b/tests/components/x9c/test.rp2040.yaml new file mode 100644 index 0000000000..a0480aa68f --- /dev/null +++ b/tests/components/x9c/test.rp2040.yaml @@ -0,0 +1,7 @@ +output: + - platform: x9c + id: test_x9c + cs_pin: 3 + inc_pin: 4 + ud_pin: 5 + initial_value: 0.5 diff --git a/tests/components/xgzp68xx/test.esp32-c3-idf.yaml b/tests/components/xgzp68xx/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..25df8cc225 --- /dev/null +++ b/tests/components/xgzp68xx/test.esp32-c3-idf.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_xgzp68xx + scl: 5 + sda: 4 + +sensor: + - platform: xgzp68xx + k_value: 4096 + temperature: + name: Pressure Temperature + pressure: + name: Differential pressure diff --git a/tests/components/xgzp68xx/test.esp32-c3.yaml b/tests/components/xgzp68xx/test.esp32-c3.yaml new file mode 100644 index 0000000000..25df8cc225 --- /dev/null +++ b/tests/components/xgzp68xx/test.esp32-c3.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_xgzp68xx + scl: 5 + sda: 4 + +sensor: + - platform: xgzp68xx + k_value: 4096 + temperature: + name: Pressure Temperature + pressure: + name: Differential pressure diff --git a/tests/components/xgzp68xx/test.esp32-idf.yaml b/tests/components/xgzp68xx/test.esp32-idf.yaml new file mode 100644 index 0000000000..fb55421123 --- /dev/null +++ b/tests/components/xgzp68xx/test.esp32-idf.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_xgzp68xx + scl: 16 + sda: 17 + +sensor: + - platform: xgzp68xx + k_value: 4096 + temperature: + name: Pressure Temperature + pressure: + name: Differential pressure diff --git a/tests/components/xgzp68xx/test.esp32.yaml b/tests/components/xgzp68xx/test.esp32.yaml new file mode 100644 index 0000000000..fb55421123 --- /dev/null +++ b/tests/components/xgzp68xx/test.esp32.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_xgzp68xx + scl: 16 + sda: 17 + +sensor: + - platform: xgzp68xx + k_value: 4096 + temperature: + name: Pressure Temperature + pressure: + name: Differential pressure diff --git a/tests/components/xgzp68xx/test.esp8266.yaml b/tests/components/xgzp68xx/test.esp8266.yaml new file mode 100644 index 0000000000..25df8cc225 --- /dev/null +++ b/tests/components/xgzp68xx/test.esp8266.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_xgzp68xx + scl: 5 + sda: 4 + +sensor: + - platform: xgzp68xx + k_value: 4096 + temperature: + name: Pressure Temperature + pressure: + name: Differential pressure diff --git a/tests/components/xgzp68xx/test.rp2040.yaml b/tests/components/xgzp68xx/test.rp2040.yaml new file mode 100644 index 0000000000..25df8cc225 --- /dev/null +++ b/tests/components/xgzp68xx/test.rp2040.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_xgzp68xx + scl: 5 + sda: 4 + +sensor: + - platform: xgzp68xx + k_value: 4096 + temperature: + name: Pressure Temperature + pressure: + name: Differential pressure diff --git a/tests/components/xiaomi_ble/test.esp32-c3-idf.yaml b/tests/components/xiaomi_ble/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..9d10393177 --- /dev/null +++ b/tests/components/xiaomi_ble/test.esp32-c3-idf.yaml @@ -0,0 +1,3 @@ +esp32_ble_tracker: + +xiaomi_ble: diff --git a/tests/components/xiaomi_ble/test.esp32-c3.yaml b/tests/components/xiaomi_ble/test.esp32-c3.yaml new file mode 100644 index 0000000000..9d10393177 --- /dev/null +++ b/tests/components/xiaomi_ble/test.esp32-c3.yaml @@ -0,0 +1,3 @@ +esp32_ble_tracker: + +xiaomi_ble: diff --git a/tests/components/xiaomi_ble/test.esp32-idf.yaml b/tests/components/xiaomi_ble/test.esp32-idf.yaml new file mode 100644 index 0000000000..9d10393177 --- /dev/null +++ b/tests/components/xiaomi_ble/test.esp32-idf.yaml @@ -0,0 +1,3 @@ +esp32_ble_tracker: + +xiaomi_ble: diff --git a/tests/components/xiaomi_ble/test.esp32.yaml b/tests/components/xiaomi_ble/test.esp32.yaml new file mode 100644 index 0000000000..9d10393177 --- /dev/null +++ b/tests/components/xiaomi_ble/test.esp32.yaml @@ -0,0 +1,3 @@ +esp32_ble_tracker: + +xiaomi_ble: diff --git a/tests/components/xiaomi_cgd1/test.esp32-c3-idf.yaml b/tests/components/xiaomi_cgd1/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..94ed09e8f2 --- /dev/null +++ b/tests/components/xiaomi_cgd1/test.esp32-c3-idf.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_cgd1 + mac_address: A4:C1:38:D1:61:7D + bindkey: c99d2313182473b38001086febf781bd + temperature: + name: Xiaomi CGD1 Temperature + humidity: + name: Xiaomi CGD1 Humidity + battery_level: + name: Xiaomi CGD1 Battery Level diff --git a/tests/components/xiaomi_cgd1/test.esp32-c3.yaml b/tests/components/xiaomi_cgd1/test.esp32-c3.yaml new file mode 100644 index 0000000000..94ed09e8f2 --- /dev/null +++ b/tests/components/xiaomi_cgd1/test.esp32-c3.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_cgd1 + mac_address: A4:C1:38:D1:61:7D + bindkey: c99d2313182473b38001086febf781bd + temperature: + name: Xiaomi CGD1 Temperature + humidity: + name: Xiaomi CGD1 Humidity + battery_level: + name: Xiaomi CGD1 Battery Level diff --git a/tests/components/xiaomi_cgd1/test.esp32-idf.yaml b/tests/components/xiaomi_cgd1/test.esp32-idf.yaml new file mode 100644 index 0000000000..94ed09e8f2 --- /dev/null +++ b/tests/components/xiaomi_cgd1/test.esp32-idf.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_cgd1 + mac_address: A4:C1:38:D1:61:7D + bindkey: c99d2313182473b38001086febf781bd + temperature: + name: Xiaomi CGD1 Temperature + humidity: + name: Xiaomi CGD1 Humidity + battery_level: + name: Xiaomi CGD1 Battery Level diff --git a/tests/components/xiaomi_cgd1/test.esp32.yaml b/tests/components/xiaomi_cgd1/test.esp32.yaml new file mode 100644 index 0000000000..94ed09e8f2 --- /dev/null +++ b/tests/components/xiaomi_cgd1/test.esp32.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_cgd1 + mac_address: A4:C1:38:D1:61:7D + bindkey: c99d2313182473b38001086febf781bd + temperature: + name: Xiaomi CGD1 Temperature + humidity: + name: Xiaomi CGD1 Humidity + battery_level: + name: Xiaomi CGD1 Battery Level diff --git a/tests/components/xiaomi_cgdk2/test.esp32-c3-idf.yaml b/tests/components/xiaomi_cgdk2/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..dddca56222 --- /dev/null +++ b/tests/components/xiaomi_cgdk2/test.esp32-c3-idf.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_cgdk2 + mac_address: A4:C1:38:D1:61:7D + bindkey: c99d2313182473b38001086febf781bd + temperature: + name: Xiaomi CGD1 Temperature + humidity: + name: Xiaomi CGD1 Humidity + battery_level: + name: Xiaomi CGD1 Battery Level diff --git a/tests/components/xiaomi_cgdk2/test.esp32-c3.yaml b/tests/components/xiaomi_cgdk2/test.esp32-c3.yaml new file mode 100644 index 0000000000..dddca56222 --- /dev/null +++ b/tests/components/xiaomi_cgdk2/test.esp32-c3.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_cgdk2 + mac_address: A4:C1:38:D1:61:7D + bindkey: c99d2313182473b38001086febf781bd + temperature: + name: Xiaomi CGD1 Temperature + humidity: + name: Xiaomi CGD1 Humidity + battery_level: + name: Xiaomi CGD1 Battery Level diff --git a/tests/components/xiaomi_cgdk2/test.esp32-idf.yaml b/tests/components/xiaomi_cgdk2/test.esp32-idf.yaml new file mode 100644 index 0000000000..dddca56222 --- /dev/null +++ b/tests/components/xiaomi_cgdk2/test.esp32-idf.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_cgdk2 + mac_address: A4:C1:38:D1:61:7D + bindkey: c99d2313182473b38001086febf781bd + temperature: + name: Xiaomi CGD1 Temperature + humidity: + name: Xiaomi CGD1 Humidity + battery_level: + name: Xiaomi CGD1 Battery Level diff --git a/tests/components/xiaomi_cgdk2/test.esp32.yaml b/tests/components/xiaomi_cgdk2/test.esp32.yaml new file mode 100644 index 0000000000..dddca56222 --- /dev/null +++ b/tests/components/xiaomi_cgdk2/test.esp32.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_cgdk2 + mac_address: A4:C1:38:D1:61:7D + bindkey: c99d2313182473b38001086febf781bd + temperature: + name: Xiaomi CGD1 Temperature + humidity: + name: Xiaomi CGD1 Humidity + battery_level: + name: Xiaomi CGD1 Battery Level diff --git a/tests/components/xiaomi_cgg1/test.esp32-c3-idf.yaml b/tests/components/xiaomi_cgg1/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..170aebfbde --- /dev/null +++ b/tests/components/xiaomi_cgg1/test.esp32-c3-idf.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_cgg1 + mac_address: A4:C1:38:D1:61:7D + bindkey: c99d2313182473b38001086febf781bd + temperature: + name: Xiaomi CGD1 Temperature + humidity: + name: Xiaomi CGD1 Humidity + battery_level: + name: Xiaomi CGD1 Battery Level diff --git a/tests/components/xiaomi_cgg1/test.esp32-c3.yaml b/tests/components/xiaomi_cgg1/test.esp32-c3.yaml new file mode 100644 index 0000000000..170aebfbde --- /dev/null +++ b/tests/components/xiaomi_cgg1/test.esp32-c3.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_cgg1 + mac_address: A4:C1:38:D1:61:7D + bindkey: c99d2313182473b38001086febf781bd + temperature: + name: Xiaomi CGD1 Temperature + humidity: + name: Xiaomi CGD1 Humidity + battery_level: + name: Xiaomi CGD1 Battery Level diff --git a/tests/components/xiaomi_cgg1/test.esp32-idf.yaml b/tests/components/xiaomi_cgg1/test.esp32-idf.yaml new file mode 100644 index 0000000000..170aebfbde --- /dev/null +++ b/tests/components/xiaomi_cgg1/test.esp32-idf.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_cgg1 + mac_address: A4:C1:38:D1:61:7D + bindkey: c99d2313182473b38001086febf781bd + temperature: + name: Xiaomi CGD1 Temperature + humidity: + name: Xiaomi CGD1 Humidity + battery_level: + name: Xiaomi CGD1 Battery Level diff --git a/tests/components/xiaomi_cgg1/test.esp32.yaml b/tests/components/xiaomi_cgg1/test.esp32.yaml new file mode 100644 index 0000000000..170aebfbde --- /dev/null +++ b/tests/components/xiaomi_cgg1/test.esp32.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_cgg1 + mac_address: A4:C1:38:D1:61:7D + bindkey: c99d2313182473b38001086febf781bd + temperature: + name: Xiaomi CGD1 Temperature + humidity: + name: Xiaomi CGD1 Humidity + battery_level: + name: Xiaomi CGD1 Battery Level diff --git a/tests/components/xiaomi_cgpr1/test.esp32-c3-idf.yaml b/tests/components/xiaomi_cgpr1/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..48082a886c --- /dev/null +++ b/tests/components/xiaomi_cgpr1/test.esp32-c3-idf.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_cgpr1 + name: CGPR1 Motion + mac_address: "12:34:56:12:34:56" + bindkey: 48403ebe2d385db8d0c187f81e62cb64 + battery_level: + name: CGPR1 battery Level + idle_time: + name: CGPR1 Idle Time + illuminance: + name: CGPR1 Illuminance diff --git a/tests/components/xiaomi_cgpr1/test.esp32-c3.yaml b/tests/components/xiaomi_cgpr1/test.esp32-c3.yaml new file mode 100644 index 0000000000..48082a886c --- /dev/null +++ b/tests/components/xiaomi_cgpr1/test.esp32-c3.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_cgpr1 + name: CGPR1 Motion + mac_address: "12:34:56:12:34:56" + bindkey: 48403ebe2d385db8d0c187f81e62cb64 + battery_level: + name: CGPR1 battery Level + idle_time: + name: CGPR1 Idle Time + illuminance: + name: CGPR1 Illuminance diff --git a/tests/components/xiaomi_cgpr1/test.esp32-idf.yaml b/tests/components/xiaomi_cgpr1/test.esp32-idf.yaml new file mode 100644 index 0000000000..48082a886c --- /dev/null +++ b/tests/components/xiaomi_cgpr1/test.esp32-idf.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_cgpr1 + name: CGPR1 Motion + mac_address: "12:34:56:12:34:56" + bindkey: 48403ebe2d385db8d0c187f81e62cb64 + battery_level: + name: CGPR1 battery Level + idle_time: + name: CGPR1 Idle Time + illuminance: + name: CGPR1 Illuminance diff --git a/tests/components/xiaomi_cgpr1/test.esp32.yaml b/tests/components/xiaomi_cgpr1/test.esp32.yaml new file mode 100644 index 0000000000..48082a886c --- /dev/null +++ b/tests/components/xiaomi_cgpr1/test.esp32.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_cgpr1 + name: CGPR1 Motion + mac_address: "12:34:56:12:34:56" + bindkey: 48403ebe2d385db8d0c187f81e62cb64 + battery_level: + name: CGPR1 battery Level + idle_time: + name: CGPR1 Idle Time + illuminance: + name: CGPR1 Illuminance diff --git a/tests/components/xiaomi_gcls002/test.esp32-c3-idf.yaml b/tests/components/xiaomi_gcls002/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..32990708cc --- /dev/null +++ b/tests/components/xiaomi_gcls002/test.esp32-c3-idf.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_gcls002 + mac_address: 94:2B:FF:5C:91:61 + temperature: + name: GCLS02 Temperature + moisture: + name: GCLS02 Moisture + conductivity: + name: GCLS02 Soil Conductivity + illuminance: + name: GCLS02 Illuminance diff --git a/tests/components/xiaomi_gcls002/test.esp32-c3.yaml b/tests/components/xiaomi_gcls002/test.esp32-c3.yaml new file mode 100644 index 0000000000..32990708cc --- /dev/null +++ b/tests/components/xiaomi_gcls002/test.esp32-c3.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_gcls002 + mac_address: 94:2B:FF:5C:91:61 + temperature: + name: GCLS02 Temperature + moisture: + name: GCLS02 Moisture + conductivity: + name: GCLS02 Soil Conductivity + illuminance: + name: GCLS02 Illuminance diff --git a/tests/components/xiaomi_gcls002/test.esp32-idf.yaml b/tests/components/xiaomi_gcls002/test.esp32-idf.yaml new file mode 100644 index 0000000000..32990708cc --- /dev/null +++ b/tests/components/xiaomi_gcls002/test.esp32-idf.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_gcls002 + mac_address: 94:2B:FF:5C:91:61 + temperature: + name: GCLS02 Temperature + moisture: + name: GCLS02 Moisture + conductivity: + name: GCLS02 Soil Conductivity + illuminance: + name: GCLS02 Illuminance diff --git a/tests/components/xiaomi_gcls002/test.esp32.yaml b/tests/components/xiaomi_gcls002/test.esp32.yaml new file mode 100644 index 0000000000..32990708cc --- /dev/null +++ b/tests/components/xiaomi_gcls002/test.esp32.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_gcls002 + mac_address: 94:2B:FF:5C:91:61 + temperature: + name: GCLS02 Temperature + moisture: + name: GCLS02 Moisture + conductivity: + name: GCLS02 Soil Conductivity + illuminance: + name: GCLS02 Illuminance diff --git a/tests/components/xiaomi_hhccjcy01/test.esp32-c3-idf.yaml b/tests/components/xiaomi_hhccjcy01/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..0def909488 --- /dev/null +++ b/tests/components/xiaomi_hhccjcy01/test.esp32-c3-idf.yaml @@ -0,0 +1,15 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_hhccjcy01 + mac_address: 94:2B:FF:5C:91:61 + temperature: + name: Xiaomi HHCCJCY01 Temperature + moisture: + name: Xiaomi HHCCJCY01 Moisture + illuminance: + name: Xiaomi HHCCJCY01 Illuminance + conductivity: + name: Xiaomi HHCCJCY01 Soil Conductivity + battery_level: + name: Xiaomi HHCCJCY01 Battery Level diff --git a/tests/components/xiaomi_hhccjcy01/test.esp32-c3.yaml b/tests/components/xiaomi_hhccjcy01/test.esp32-c3.yaml new file mode 100644 index 0000000000..0def909488 --- /dev/null +++ b/tests/components/xiaomi_hhccjcy01/test.esp32-c3.yaml @@ -0,0 +1,15 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_hhccjcy01 + mac_address: 94:2B:FF:5C:91:61 + temperature: + name: Xiaomi HHCCJCY01 Temperature + moisture: + name: Xiaomi HHCCJCY01 Moisture + illuminance: + name: Xiaomi HHCCJCY01 Illuminance + conductivity: + name: Xiaomi HHCCJCY01 Soil Conductivity + battery_level: + name: Xiaomi HHCCJCY01 Battery Level diff --git a/tests/components/xiaomi_hhccjcy01/test.esp32-idf.yaml b/tests/components/xiaomi_hhccjcy01/test.esp32-idf.yaml new file mode 100644 index 0000000000..0def909488 --- /dev/null +++ b/tests/components/xiaomi_hhccjcy01/test.esp32-idf.yaml @@ -0,0 +1,15 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_hhccjcy01 + mac_address: 94:2B:FF:5C:91:61 + temperature: + name: Xiaomi HHCCJCY01 Temperature + moisture: + name: Xiaomi HHCCJCY01 Moisture + illuminance: + name: Xiaomi HHCCJCY01 Illuminance + conductivity: + name: Xiaomi HHCCJCY01 Soil Conductivity + battery_level: + name: Xiaomi HHCCJCY01 Battery Level diff --git a/tests/components/xiaomi_hhccjcy01/test.esp32.yaml b/tests/components/xiaomi_hhccjcy01/test.esp32.yaml new file mode 100644 index 0000000000..0def909488 --- /dev/null +++ b/tests/components/xiaomi_hhccjcy01/test.esp32.yaml @@ -0,0 +1,15 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_hhccjcy01 + mac_address: 94:2B:FF:5C:91:61 + temperature: + name: Xiaomi HHCCJCY01 Temperature + moisture: + name: Xiaomi HHCCJCY01 Moisture + illuminance: + name: Xiaomi HHCCJCY01 Illuminance + conductivity: + name: Xiaomi HHCCJCY01 Soil Conductivity + battery_level: + name: Xiaomi HHCCJCY01 Battery Level diff --git a/tests/components/xiaomi_hhccpot002/test.esp32-c3-idf.yaml b/tests/components/xiaomi_hhccpot002/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..2e5fa14620 --- /dev/null +++ b/tests/components/xiaomi_hhccpot002/test.esp32-c3-idf.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_hhccpot002 + mac_address: 94:2B:FF:5C:91:61 + moisture: + name: HHCCPOT002 Moisture + conductivity: + name: HHCCPOT002 Soil Conductivity diff --git a/tests/components/xiaomi_hhccpot002/test.esp32-c3.yaml b/tests/components/xiaomi_hhccpot002/test.esp32-c3.yaml new file mode 100644 index 0000000000..2e5fa14620 --- /dev/null +++ b/tests/components/xiaomi_hhccpot002/test.esp32-c3.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_hhccpot002 + mac_address: 94:2B:FF:5C:91:61 + moisture: + name: HHCCPOT002 Moisture + conductivity: + name: HHCCPOT002 Soil Conductivity diff --git a/tests/components/xiaomi_hhccpot002/test.esp32-idf.yaml b/tests/components/xiaomi_hhccpot002/test.esp32-idf.yaml new file mode 100644 index 0000000000..2e5fa14620 --- /dev/null +++ b/tests/components/xiaomi_hhccpot002/test.esp32-idf.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_hhccpot002 + mac_address: 94:2B:FF:5C:91:61 + moisture: + name: HHCCPOT002 Moisture + conductivity: + name: HHCCPOT002 Soil Conductivity diff --git a/tests/components/xiaomi_hhccpot002/test.esp32.yaml b/tests/components/xiaomi_hhccpot002/test.esp32.yaml new file mode 100644 index 0000000000..2e5fa14620 --- /dev/null +++ b/tests/components/xiaomi_hhccpot002/test.esp32.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_hhccpot002 + mac_address: 94:2B:FF:5C:91:61 + moisture: + name: HHCCPOT002 Moisture + conductivity: + name: HHCCPOT002 Soil Conductivity diff --git a/tests/components/xiaomi_jqjcy01ym/test.esp32-c3-idf.yaml b/tests/components/xiaomi_jqjcy01ym/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..54c4b33dcd --- /dev/null +++ b/tests/components/xiaomi_jqjcy01ym/test.esp32-c3-idf.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_jqjcy01ym + mac_address: 7A:80:8E:19:36:BA + temperature: + name: JQJCY01YM Temperature + humidity: + name: JQJCY01YM Humidity + formaldehyde: + name: JQJCY01YM Formaldehyde + battery_level: + name: JQJCY01YM Battery Level diff --git a/tests/components/xiaomi_jqjcy01ym/test.esp32-c3.yaml b/tests/components/xiaomi_jqjcy01ym/test.esp32-c3.yaml new file mode 100644 index 0000000000..54c4b33dcd --- /dev/null +++ b/tests/components/xiaomi_jqjcy01ym/test.esp32-c3.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_jqjcy01ym + mac_address: 7A:80:8E:19:36:BA + temperature: + name: JQJCY01YM Temperature + humidity: + name: JQJCY01YM Humidity + formaldehyde: + name: JQJCY01YM Formaldehyde + battery_level: + name: JQJCY01YM Battery Level diff --git a/tests/components/xiaomi_jqjcy01ym/test.esp32-idf.yaml b/tests/components/xiaomi_jqjcy01ym/test.esp32-idf.yaml new file mode 100644 index 0000000000..54c4b33dcd --- /dev/null +++ b/tests/components/xiaomi_jqjcy01ym/test.esp32-idf.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_jqjcy01ym + mac_address: 7A:80:8E:19:36:BA + temperature: + name: JQJCY01YM Temperature + humidity: + name: JQJCY01YM Humidity + formaldehyde: + name: JQJCY01YM Formaldehyde + battery_level: + name: JQJCY01YM Battery Level diff --git a/tests/components/xiaomi_jqjcy01ym/test.esp32.yaml b/tests/components/xiaomi_jqjcy01ym/test.esp32.yaml new file mode 100644 index 0000000000..54c4b33dcd --- /dev/null +++ b/tests/components/xiaomi_jqjcy01ym/test.esp32.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_jqjcy01ym + mac_address: 7A:80:8E:19:36:BA + temperature: + name: JQJCY01YM Temperature + humidity: + name: JQJCY01YM Humidity + formaldehyde: + name: JQJCY01YM Formaldehyde + battery_level: + name: JQJCY01YM Battery Level diff --git a/tests/components/xiaomi_lywsd02/test.esp32-c3-idf.yaml b/tests/components/xiaomi_lywsd02/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..3e40ab8d70 --- /dev/null +++ b/tests/components/xiaomi_lywsd02/test.esp32-c3-idf.yaml @@ -0,0 +1,11 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_lywsd02 + mac_address: 3F:5B:7D:82:58:4E + temperature: + name: Xiaomi LYWSD02 Temperature + humidity: + name: Xiaomi LYWSD02 Humidity + battery_level: + name: Xiaomi LYWSD02 Battery Level diff --git a/tests/components/xiaomi_lywsd02/test.esp32-c3.yaml b/tests/components/xiaomi_lywsd02/test.esp32-c3.yaml new file mode 100644 index 0000000000..3e40ab8d70 --- /dev/null +++ b/tests/components/xiaomi_lywsd02/test.esp32-c3.yaml @@ -0,0 +1,11 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_lywsd02 + mac_address: 3F:5B:7D:82:58:4E + temperature: + name: Xiaomi LYWSD02 Temperature + humidity: + name: Xiaomi LYWSD02 Humidity + battery_level: + name: Xiaomi LYWSD02 Battery Level diff --git a/tests/components/xiaomi_lywsd02/test.esp32-idf.yaml b/tests/components/xiaomi_lywsd02/test.esp32-idf.yaml new file mode 100644 index 0000000000..3e40ab8d70 --- /dev/null +++ b/tests/components/xiaomi_lywsd02/test.esp32-idf.yaml @@ -0,0 +1,11 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_lywsd02 + mac_address: 3F:5B:7D:82:58:4E + temperature: + name: Xiaomi LYWSD02 Temperature + humidity: + name: Xiaomi LYWSD02 Humidity + battery_level: + name: Xiaomi LYWSD02 Battery Level diff --git a/tests/components/xiaomi_lywsd02/test.esp32.yaml b/tests/components/xiaomi_lywsd02/test.esp32.yaml new file mode 100644 index 0000000000..3e40ab8d70 --- /dev/null +++ b/tests/components/xiaomi_lywsd02/test.esp32.yaml @@ -0,0 +1,11 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_lywsd02 + mac_address: 3F:5B:7D:82:58:4E + temperature: + name: Xiaomi LYWSD02 Temperature + humidity: + name: Xiaomi LYWSD02 Humidity + battery_level: + name: Xiaomi LYWSD02 Battery Level diff --git a/tests/components/xiaomi_lywsd03mmc/test.esp32-c3-idf.yaml b/tests/components/xiaomi_lywsd03mmc/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..d10a859c56 --- /dev/null +++ b/tests/components/xiaomi_lywsd03mmc/test.esp32-c3-idf.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_lywsd03mmc + mac_address: A4:C1:38:4E:16:78 + bindkey: e9efaa6873f9f9c87a5e75a5f814801c + temperature: + name: Xiaomi LYWSD03MMC Temperature + humidity: + name: Xiaomi LYWSD03MMC Humidity + battery_level: + name: Xiaomi LYWSD03MMC Battery Level diff --git a/tests/components/xiaomi_lywsd03mmc/test.esp32-c3.yaml b/tests/components/xiaomi_lywsd03mmc/test.esp32-c3.yaml new file mode 100644 index 0000000000..d10a859c56 --- /dev/null +++ b/tests/components/xiaomi_lywsd03mmc/test.esp32-c3.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_lywsd03mmc + mac_address: A4:C1:38:4E:16:78 + bindkey: e9efaa6873f9f9c87a5e75a5f814801c + temperature: + name: Xiaomi LYWSD03MMC Temperature + humidity: + name: Xiaomi LYWSD03MMC Humidity + battery_level: + name: Xiaomi LYWSD03MMC Battery Level diff --git a/tests/components/xiaomi_lywsd03mmc/test.esp32-idf.yaml b/tests/components/xiaomi_lywsd03mmc/test.esp32-idf.yaml new file mode 100644 index 0000000000..d10a859c56 --- /dev/null +++ b/tests/components/xiaomi_lywsd03mmc/test.esp32-idf.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_lywsd03mmc + mac_address: A4:C1:38:4E:16:78 + bindkey: e9efaa6873f9f9c87a5e75a5f814801c + temperature: + name: Xiaomi LYWSD03MMC Temperature + humidity: + name: Xiaomi LYWSD03MMC Humidity + battery_level: + name: Xiaomi LYWSD03MMC Battery Level diff --git a/tests/components/xiaomi_lywsd03mmc/test.esp32.yaml b/tests/components/xiaomi_lywsd03mmc/test.esp32.yaml new file mode 100644 index 0000000000..d10a859c56 --- /dev/null +++ b/tests/components/xiaomi_lywsd03mmc/test.esp32.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_lywsd03mmc + mac_address: A4:C1:38:4E:16:78 + bindkey: e9efaa6873f9f9c87a5e75a5f814801c + temperature: + name: Xiaomi LYWSD03MMC Temperature + humidity: + name: Xiaomi LYWSD03MMC Humidity + battery_level: + name: Xiaomi LYWSD03MMC Battery Level diff --git a/tests/components/xiaomi_lywsdcgq/test.esp32-c3-idf.yaml b/tests/components/xiaomi_lywsdcgq/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..d8422b4c0c --- /dev/null +++ b/tests/components/xiaomi_lywsdcgq/test.esp32-c3-idf.yaml @@ -0,0 +1,11 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_lywsdcgq + mac_address: 7A:80:8E:19:36:BA + temperature: + name: Xiaomi LYWSDCGQ Temperature + humidity: + name: Xiaomi LYWSDCGQ Humidity + battery_level: + name: Xiaomi LYWSDCGQ Battery Level diff --git a/tests/components/xiaomi_lywsdcgq/test.esp32-c3.yaml b/tests/components/xiaomi_lywsdcgq/test.esp32-c3.yaml new file mode 100644 index 0000000000..d8422b4c0c --- /dev/null +++ b/tests/components/xiaomi_lywsdcgq/test.esp32-c3.yaml @@ -0,0 +1,11 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_lywsdcgq + mac_address: 7A:80:8E:19:36:BA + temperature: + name: Xiaomi LYWSDCGQ Temperature + humidity: + name: Xiaomi LYWSDCGQ Humidity + battery_level: + name: Xiaomi LYWSDCGQ Battery Level diff --git a/tests/components/xiaomi_lywsdcgq/test.esp32-idf.yaml b/tests/components/xiaomi_lywsdcgq/test.esp32-idf.yaml new file mode 100644 index 0000000000..d8422b4c0c --- /dev/null +++ b/tests/components/xiaomi_lywsdcgq/test.esp32-idf.yaml @@ -0,0 +1,11 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_lywsdcgq + mac_address: 7A:80:8E:19:36:BA + temperature: + name: Xiaomi LYWSDCGQ Temperature + humidity: + name: Xiaomi LYWSDCGQ Humidity + battery_level: + name: Xiaomi LYWSDCGQ Battery Level diff --git a/tests/components/xiaomi_lywsdcgq/test.esp32.yaml b/tests/components/xiaomi_lywsdcgq/test.esp32.yaml new file mode 100644 index 0000000000..d8422b4c0c --- /dev/null +++ b/tests/components/xiaomi_lywsdcgq/test.esp32.yaml @@ -0,0 +1,11 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_lywsdcgq + mac_address: 7A:80:8E:19:36:BA + temperature: + name: Xiaomi LYWSDCGQ Temperature + humidity: + name: Xiaomi LYWSDCGQ Humidity + battery_level: + name: Xiaomi LYWSDCGQ Battery Level diff --git a/tests/components/xiaomi_mhoc303/test.esp32-c3-idf.yaml b/tests/components/xiaomi_mhoc303/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..e4353d3c6a --- /dev/null +++ b/tests/components/xiaomi_mhoc303/test.esp32-c3-idf.yaml @@ -0,0 +1,11 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_mhoc303 + mac_address: E7:50:59:32:A0:1C + temperature: + name: MHO-C303 Temperature + humidity: + name: MHO-C303 Humidity + battery_level: + name: MHO-C303 Battery Level diff --git a/tests/components/xiaomi_mhoc303/test.esp32-c3.yaml b/tests/components/xiaomi_mhoc303/test.esp32-c3.yaml new file mode 100644 index 0000000000..e4353d3c6a --- /dev/null +++ b/tests/components/xiaomi_mhoc303/test.esp32-c3.yaml @@ -0,0 +1,11 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_mhoc303 + mac_address: E7:50:59:32:A0:1C + temperature: + name: MHO-C303 Temperature + humidity: + name: MHO-C303 Humidity + battery_level: + name: MHO-C303 Battery Level diff --git a/tests/components/xiaomi_mhoc303/test.esp32-idf.yaml b/tests/components/xiaomi_mhoc303/test.esp32-idf.yaml new file mode 100644 index 0000000000..e4353d3c6a --- /dev/null +++ b/tests/components/xiaomi_mhoc303/test.esp32-idf.yaml @@ -0,0 +1,11 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_mhoc303 + mac_address: E7:50:59:32:A0:1C + temperature: + name: MHO-C303 Temperature + humidity: + name: MHO-C303 Humidity + battery_level: + name: MHO-C303 Battery Level diff --git a/tests/components/xiaomi_mhoc303/test.esp32.yaml b/tests/components/xiaomi_mhoc303/test.esp32.yaml new file mode 100644 index 0000000000..e4353d3c6a --- /dev/null +++ b/tests/components/xiaomi_mhoc303/test.esp32.yaml @@ -0,0 +1,11 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_mhoc303 + mac_address: E7:50:59:32:A0:1C + temperature: + name: MHO-C303 Temperature + humidity: + name: MHO-C303 Humidity + battery_level: + name: MHO-C303 Battery Level diff --git a/tests/components/xiaomi_mhoc401/test.esp32-c3-idf.yaml b/tests/components/xiaomi_mhoc401/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..ae378f5604 --- /dev/null +++ b/tests/components/xiaomi_mhoc401/test.esp32-c3-idf.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_mhoc401 + mac_address: E7:50:59:32:A0:1C + bindkey: "eef418daf699a0c188f3bfd17e4565d9" + temperature: + name: MHO-C303 Temperature + humidity: + name: MHO-C303 Humidity + battery_level: + name: MHO-C303 Battery Level diff --git a/tests/components/xiaomi_mhoc401/test.esp32-c3.yaml b/tests/components/xiaomi_mhoc401/test.esp32-c3.yaml new file mode 100644 index 0000000000..ae378f5604 --- /dev/null +++ b/tests/components/xiaomi_mhoc401/test.esp32-c3.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_mhoc401 + mac_address: E7:50:59:32:A0:1C + bindkey: "eef418daf699a0c188f3bfd17e4565d9" + temperature: + name: MHO-C303 Temperature + humidity: + name: MHO-C303 Humidity + battery_level: + name: MHO-C303 Battery Level diff --git a/tests/components/xiaomi_mhoc401/test.esp32-idf.yaml b/tests/components/xiaomi_mhoc401/test.esp32-idf.yaml new file mode 100644 index 0000000000..ae378f5604 --- /dev/null +++ b/tests/components/xiaomi_mhoc401/test.esp32-idf.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_mhoc401 + mac_address: E7:50:59:32:A0:1C + bindkey: "eef418daf699a0c188f3bfd17e4565d9" + temperature: + name: MHO-C303 Temperature + humidity: + name: MHO-C303 Humidity + battery_level: + name: MHO-C303 Battery Level diff --git a/tests/components/xiaomi_mhoc401/test.esp32.yaml b/tests/components/xiaomi_mhoc401/test.esp32.yaml new file mode 100644 index 0000000000..ae378f5604 --- /dev/null +++ b/tests/components/xiaomi_mhoc401/test.esp32.yaml @@ -0,0 +1,12 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_mhoc401 + mac_address: E7:50:59:32:A0:1C + bindkey: "eef418daf699a0c188f3bfd17e4565d9" + temperature: + name: MHO-C303 Temperature + humidity: + name: MHO-C303 Humidity + battery_level: + name: MHO-C303 Battery Level diff --git a/tests/components/xiaomi_miscale copy/test.esp32-c3-idf.yaml b/tests/components/xiaomi_miscale copy/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..89f32ad199 --- /dev/null +++ b/tests/components/xiaomi_miscale copy/test.esp32-c3-idf.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_miscale + mac_address: '5C:CA:D3:70:D4:A2' + weight: + name: "Xiaomi Mi Scale Weight" + impedance: + name: "Xiaomi Mi Scale Impedance" diff --git a/tests/components/xiaomi_miscale copy/test.esp32-c3.yaml b/tests/components/xiaomi_miscale copy/test.esp32-c3.yaml new file mode 100644 index 0000000000..89f32ad199 --- /dev/null +++ b/tests/components/xiaomi_miscale copy/test.esp32-c3.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_miscale + mac_address: '5C:CA:D3:70:D4:A2' + weight: + name: "Xiaomi Mi Scale Weight" + impedance: + name: "Xiaomi Mi Scale Impedance" diff --git a/tests/components/xiaomi_miscale copy/test.esp32-idf.yaml b/tests/components/xiaomi_miscale copy/test.esp32-idf.yaml new file mode 100644 index 0000000000..89f32ad199 --- /dev/null +++ b/tests/components/xiaomi_miscale copy/test.esp32-idf.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_miscale + mac_address: '5C:CA:D3:70:D4:A2' + weight: + name: "Xiaomi Mi Scale Weight" + impedance: + name: "Xiaomi Mi Scale Impedance" diff --git a/tests/components/xiaomi_miscale copy/test.esp32.yaml b/tests/components/xiaomi_miscale copy/test.esp32.yaml new file mode 100644 index 0000000000..89f32ad199 --- /dev/null +++ b/tests/components/xiaomi_miscale copy/test.esp32.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_miscale + mac_address: '5C:CA:D3:70:D4:A2' + weight: + name: "Xiaomi Mi Scale Weight" + impedance: + name: "Xiaomi Mi Scale Impedance" diff --git a/tests/components/xiaomi_miscale/test.esp32-c3-idf.yaml b/tests/components/xiaomi_miscale/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..89f32ad199 --- /dev/null +++ b/tests/components/xiaomi_miscale/test.esp32-c3-idf.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_miscale + mac_address: '5C:CA:D3:70:D4:A2' + weight: + name: "Xiaomi Mi Scale Weight" + impedance: + name: "Xiaomi Mi Scale Impedance" diff --git a/tests/components/xiaomi_miscale/test.esp32-c3.yaml b/tests/components/xiaomi_miscale/test.esp32-c3.yaml new file mode 100644 index 0000000000..89f32ad199 --- /dev/null +++ b/tests/components/xiaomi_miscale/test.esp32-c3.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_miscale + mac_address: '5C:CA:D3:70:D4:A2' + weight: + name: "Xiaomi Mi Scale Weight" + impedance: + name: "Xiaomi Mi Scale Impedance" diff --git a/tests/components/xiaomi_miscale/test.esp32-idf.yaml b/tests/components/xiaomi_miscale/test.esp32-idf.yaml new file mode 100644 index 0000000000..89f32ad199 --- /dev/null +++ b/tests/components/xiaomi_miscale/test.esp32-idf.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_miscale + mac_address: '5C:CA:D3:70:D4:A2' + weight: + name: "Xiaomi Mi Scale Weight" + impedance: + name: "Xiaomi Mi Scale Impedance" diff --git a/tests/components/xiaomi_miscale/test.esp32.yaml b/tests/components/xiaomi_miscale/test.esp32.yaml new file mode 100644 index 0000000000..89f32ad199 --- /dev/null +++ b/tests/components/xiaomi_miscale/test.esp32.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +sensor: + - platform: xiaomi_miscale + mac_address: '5C:CA:D3:70:D4:A2' + weight: + name: "Xiaomi Mi Scale Weight" + impedance: + name: "Xiaomi Mi Scale Impedance" diff --git a/tests/components/xiaomi_mjyd02yla/test.esp32-c3-idf.yaml b/tests/components/xiaomi_mjyd02yla/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..dffcef84c4 --- /dev/null +++ b/tests/components/xiaomi_mjyd02yla/test.esp32-c3-idf.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_mjyd02yla + name: MJYD02YL-A Motion + mac_address: 50:EC:50:CD:32:02 + bindkey: 48403ebe2d385db8d0c187f81e62cb64 + idle_time: + name: MJYD02YL-A Idle Time + light: + name: MJYD02YL-A Light Status + battery_level: + name: MJYD02YL-A Battery Level diff --git a/tests/components/xiaomi_mjyd02yla/test.esp32-c3.yaml b/tests/components/xiaomi_mjyd02yla/test.esp32-c3.yaml new file mode 100644 index 0000000000..dffcef84c4 --- /dev/null +++ b/tests/components/xiaomi_mjyd02yla/test.esp32-c3.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_mjyd02yla + name: MJYD02YL-A Motion + mac_address: 50:EC:50:CD:32:02 + bindkey: 48403ebe2d385db8d0c187f81e62cb64 + idle_time: + name: MJYD02YL-A Idle Time + light: + name: MJYD02YL-A Light Status + battery_level: + name: MJYD02YL-A Battery Level diff --git a/tests/components/xiaomi_mjyd02yla/test.esp32-idf.yaml b/tests/components/xiaomi_mjyd02yla/test.esp32-idf.yaml new file mode 100644 index 0000000000..dffcef84c4 --- /dev/null +++ b/tests/components/xiaomi_mjyd02yla/test.esp32-idf.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_mjyd02yla + name: MJYD02YL-A Motion + mac_address: 50:EC:50:CD:32:02 + bindkey: 48403ebe2d385db8d0c187f81e62cb64 + idle_time: + name: MJYD02YL-A Idle Time + light: + name: MJYD02YL-A Light Status + battery_level: + name: MJYD02YL-A Battery Level diff --git a/tests/components/xiaomi_mjyd02yla/test.esp32.yaml b/tests/components/xiaomi_mjyd02yla/test.esp32.yaml new file mode 100644 index 0000000000..dffcef84c4 --- /dev/null +++ b/tests/components/xiaomi_mjyd02yla/test.esp32.yaml @@ -0,0 +1,13 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_mjyd02yla + name: MJYD02YL-A Motion + mac_address: 50:EC:50:CD:32:02 + bindkey: 48403ebe2d385db8d0c187f81e62cb64 + idle_time: + name: MJYD02YL-A Idle Time + light: + name: MJYD02YL-A Light Status + battery_level: + name: MJYD02YL-A Battery Level diff --git a/tests/components/xiaomi_mue4094rt/test.esp32-c3-idf.yaml b/tests/components/xiaomi_mue4094rt/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..4f0e5ccbae --- /dev/null +++ b/tests/components/xiaomi_mue4094rt/test.esp32-c3-idf.yaml @@ -0,0 +1,7 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_mue4094rt + name: MUE4094RT Motion + mac_address: 7A:80:8E:19:36:BA + timeout: 5s diff --git a/tests/components/xiaomi_mue4094rt/test.esp32-c3.yaml b/tests/components/xiaomi_mue4094rt/test.esp32-c3.yaml new file mode 100644 index 0000000000..4f0e5ccbae --- /dev/null +++ b/tests/components/xiaomi_mue4094rt/test.esp32-c3.yaml @@ -0,0 +1,7 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_mue4094rt + name: MUE4094RT Motion + mac_address: 7A:80:8E:19:36:BA + timeout: 5s diff --git a/tests/components/xiaomi_mue4094rt/test.esp32-idf.yaml b/tests/components/xiaomi_mue4094rt/test.esp32-idf.yaml new file mode 100644 index 0000000000..4f0e5ccbae --- /dev/null +++ b/tests/components/xiaomi_mue4094rt/test.esp32-idf.yaml @@ -0,0 +1,7 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_mue4094rt + name: MUE4094RT Motion + mac_address: 7A:80:8E:19:36:BA + timeout: 5s diff --git a/tests/components/xiaomi_mue4094rt/test.esp32.yaml b/tests/components/xiaomi_mue4094rt/test.esp32.yaml new file mode 100644 index 0000000000..4f0e5ccbae --- /dev/null +++ b/tests/components/xiaomi_mue4094rt/test.esp32.yaml @@ -0,0 +1,7 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_mue4094rt + name: MUE4094RT Motion + mac_address: 7A:80:8E:19:36:BA + timeout: 5s diff --git a/tests/components/xiaomi_rtcgq02lm/test.esp32-c3-idf.yaml b/tests/components/xiaomi_rtcgq02lm/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..a2e0c66ba5 --- /dev/null +++ b/tests/components/xiaomi_rtcgq02lm/test.esp32-c3-idf.yaml @@ -0,0 +1,22 @@ +esp32_ble_tracker: + +xiaomi_rtcgq02lm: + - id: motion_rtcgq02lm + mac_address: 01:02:03:04:05:06 + bindkey: "48403ebe2d385db8d0c187f81e62cb64" + +binary_sensor: + - platform: xiaomi_rtcgq02lm + id: motion_rtcgq02lm + motion: + name: Mi Motion Sensor 2 + light: + name: Mi Motion Sensor 2 Light + button: + name: Mi Motion Sensor 2 Button + +sensor: + - platform: xiaomi_rtcgq02lm + id: motion_rtcgq02lm + battery_level: + name: Mi Motion Sensor 2 Battery level diff --git a/tests/components/xiaomi_rtcgq02lm/test.esp32-c3.yaml b/tests/components/xiaomi_rtcgq02lm/test.esp32-c3.yaml new file mode 100644 index 0000000000..a2e0c66ba5 --- /dev/null +++ b/tests/components/xiaomi_rtcgq02lm/test.esp32-c3.yaml @@ -0,0 +1,22 @@ +esp32_ble_tracker: + +xiaomi_rtcgq02lm: + - id: motion_rtcgq02lm + mac_address: 01:02:03:04:05:06 + bindkey: "48403ebe2d385db8d0c187f81e62cb64" + +binary_sensor: + - platform: xiaomi_rtcgq02lm + id: motion_rtcgq02lm + motion: + name: Mi Motion Sensor 2 + light: + name: Mi Motion Sensor 2 Light + button: + name: Mi Motion Sensor 2 Button + +sensor: + - platform: xiaomi_rtcgq02lm + id: motion_rtcgq02lm + battery_level: + name: Mi Motion Sensor 2 Battery level diff --git a/tests/components/xiaomi_rtcgq02lm/test.esp32-idf.yaml b/tests/components/xiaomi_rtcgq02lm/test.esp32-idf.yaml new file mode 100644 index 0000000000..a2e0c66ba5 --- /dev/null +++ b/tests/components/xiaomi_rtcgq02lm/test.esp32-idf.yaml @@ -0,0 +1,22 @@ +esp32_ble_tracker: + +xiaomi_rtcgq02lm: + - id: motion_rtcgq02lm + mac_address: 01:02:03:04:05:06 + bindkey: "48403ebe2d385db8d0c187f81e62cb64" + +binary_sensor: + - platform: xiaomi_rtcgq02lm + id: motion_rtcgq02lm + motion: + name: Mi Motion Sensor 2 + light: + name: Mi Motion Sensor 2 Light + button: + name: Mi Motion Sensor 2 Button + +sensor: + - platform: xiaomi_rtcgq02lm + id: motion_rtcgq02lm + battery_level: + name: Mi Motion Sensor 2 Battery level diff --git a/tests/components/xiaomi_rtcgq02lm/test.esp32.yaml b/tests/components/xiaomi_rtcgq02lm/test.esp32.yaml new file mode 100644 index 0000000000..a2e0c66ba5 --- /dev/null +++ b/tests/components/xiaomi_rtcgq02lm/test.esp32.yaml @@ -0,0 +1,22 @@ +esp32_ble_tracker: + +xiaomi_rtcgq02lm: + - id: motion_rtcgq02lm + mac_address: 01:02:03:04:05:06 + bindkey: "48403ebe2d385db8d0c187f81e62cb64" + +binary_sensor: + - platform: xiaomi_rtcgq02lm + id: motion_rtcgq02lm + motion: + name: Mi Motion Sensor 2 + light: + name: Mi Motion Sensor 2 Light + button: + name: Mi Motion Sensor 2 Button + +sensor: + - platform: xiaomi_rtcgq02lm + id: motion_rtcgq02lm + battery_level: + name: Mi Motion Sensor 2 Battery level diff --git a/tests/components/xiaomi_wx08zm/test.esp32-c3-idf.yaml b/tests/components/xiaomi_wx08zm/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..3e83ad3e95 --- /dev/null +++ b/tests/components/xiaomi_wx08zm/test.esp32-c3-idf.yaml @@ -0,0 +1,10 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_wx08zm + name: WX08ZM Activation State + mac_address: 74:a3:4a:b5:07:34 + tablet: + name: WX08ZM Tablet Resource + battery_level: + name: WX08ZM Battery Level diff --git a/tests/components/xiaomi_wx08zm/test.esp32-c3.yaml b/tests/components/xiaomi_wx08zm/test.esp32-c3.yaml new file mode 100644 index 0000000000..3e83ad3e95 --- /dev/null +++ b/tests/components/xiaomi_wx08zm/test.esp32-c3.yaml @@ -0,0 +1,10 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_wx08zm + name: WX08ZM Activation State + mac_address: 74:a3:4a:b5:07:34 + tablet: + name: WX08ZM Tablet Resource + battery_level: + name: WX08ZM Battery Level diff --git a/tests/components/xiaomi_wx08zm/test.esp32-idf.yaml b/tests/components/xiaomi_wx08zm/test.esp32-idf.yaml new file mode 100644 index 0000000000..3e83ad3e95 --- /dev/null +++ b/tests/components/xiaomi_wx08zm/test.esp32-idf.yaml @@ -0,0 +1,10 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_wx08zm + name: WX08ZM Activation State + mac_address: 74:a3:4a:b5:07:34 + tablet: + name: WX08ZM Tablet Resource + battery_level: + name: WX08ZM Battery Level diff --git a/tests/components/xiaomi_wx08zm/test.esp32.yaml b/tests/components/xiaomi_wx08zm/test.esp32.yaml new file mode 100644 index 0000000000..3e83ad3e95 --- /dev/null +++ b/tests/components/xiaomi_wx08zm/test.esp32.yaml @@ -0,0 +1,10 @@ +esp32_ble_tracker: + +binary_sensor: + - platform: xiaomi_wx08zm + name: WX08ZM Activation State + mac_address: 74:a3:4a:b5:07:34 + tablet: + name: WX08ZM Tablet Resource + battery_level: + name: WX08ZM Battery Level diff --git a/tests/components/xl9535/test.esp32-c3-idf.yaml b/tests/components/xl9535/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..178adf870e --- /dev/null +++ b/tests/components/xl9535/test.esp32-c3-idf.yaml @@ -0,0 +1,26 @@ +i2c: + - id: i2c_xl9535 + scl: 5 + sda: 4 + +xl9535: + - id: xl9535_hub + address: 0x20 + +binary_sensor: + - platform: gpio + name: XL9535 Pin 0 + pin: + xl9535: xl9535_hub + number: 0 + mode: + input: true + inverted: false + - platform: gpio + name: XL9535 Pin 17 + pin: + xl9535: xl9535_hub + number: 17 + mode: + input: true + inverted: false diff --git a/tests/components/xl9535/test.esp32-c3.yaml b/tests/components/xl9535/test.esp32-c3.yaml new file mode 100644 index 0000000000..178adf870e --- /dev/null +++ b/tests/components/xl9535/test.esp32-c3.yaml @@ -0,0 +1,26 @@ +i2c: + - id: i2c_xl9535 + scl: 5 + sda: 4 + +xl9535: + - id: xl9535_hub + address: 0x20 + +binary_sensor: + - platform: gpio + name: XL9535 Pin 0 + pin: + xl9535: xl9535_hub + number: 0 + mode: + input: true + inverted: false + - platform: gpio + name: XL9535 Pin 17 + pin: + xl9535: xl9535_hub + number: 17 + mode: + input: true + inverted: false diff --git a/tests/components/xl9535/test.esp32-idf.yaml b/tests/components/xl9535/test.esp32-idf.yaml new file mode 100644 index 0000000000..a65aae890e --- /dev/null +++ b/tests/components/xl9535/test.esp32-idf.yaml @@ -0,0 +1,26 @@ +i2c: + - id: i2c_xl9535 + scl: 16 + sda: 17 + +xl9535: + - id: xl9535_hub + address: 0x20 + +binary_sensor: + - platform: gpio + name: XL9535 Pin 0 + pin: + xl9535: xl9535_hub + number: 0 + mode: + input: true + inverted: false + - platform: gpio + name: XL9535 Pin 17 + pin: + xl9535: xl9535_hub + number: 17 + mode: + input: true + inverted: false diff --git a/tests/components/xl9535/test.esp32.yaml b/tests/components/xl9535/test.esp32.yaml new file mode 100644 index 0000000000..a65aae890e --- /dev/null +++ b/tests/components/xl9535/test.esp32.yaml @@ -0,0 +1,26 @@ +i2c: + - id: i2c_xl9535 + scl: 16 + sda: 17 + +xl9535: + - id: xl9535_hub + address: 0x20 + +binary_sensor: + - platform: gpio + name: XL9535 Pin 0 + pin: + xl9535: xl9535_hub + number: 0 + mode: + input: true + inverted: false + - platform: gpio + name: XL9535 Pin 17 + pin: + xl9535: xl9535_hub + number: 17 + mode: + input: true + inverted: false diff --git a/tests/components/xl9535/test.esp8266.yaml b/tests/components/xl9535/test.esp8266.yaml new file mode 100644 index 0000000000..178adf870e --- /dev/null +++ b/tests/components/xl9535/test.esp8266.yaml @@ -0,0 +1,26 @@ +i2c: + - id: i2c_xl9535 + scl: 5 + sda: 4 + +xl9535: + - id: xl9535_hub + address: 0x20 + +binary_sensor: + - platform: gpio + name: XL9535 Pin 0 + pin: + xl9535: xl9535_hub + number: 0 + mode: + input: true + inverted: false + - platform: gpio + name: XL9535 Pin 17 + pin: + xl9535: xl9535_hub + number: 17 + mode: + input: true + inverted: false diff --git a/tests/components/xl9535/test.rp2040.yaml b/tests/components/xl9535/test.rp2040.yaml new file mode 100644 index 0000000000..178adf870e --- /dev/null +++ b/tests/components/xl9535/test.rp2040.yaml @@ -0,0 +1,26 @@ +i2c: + - id: i2c_xl9535 + scl: 5 + sda: 4 + +xl9535: + - id: xl9535_hub + address: 0x20 + +binary_sensor: + - platform: gpio + name: XL9535 Pin 0 + pin: + xl9535: xl9535_hub + number: 0 + mode: + input: true + inverted: false + - platform: gpio + name: XL9535 Pin 17 + pin: + xl9535: xl9535_hub + number: 17 + mode: + input: true + inverted: false diff --git a/tests/components/xpt2046/test.esp32-c3-idf.yaml b/tests/components/xpt2046/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..38a1da74ae --- /dev/null +++ b/tests/components/xpt2046/test.esp32-c3-idf.yaml @@ -0,0 +1,33 @@ +spi: + - id: spi_xpt2046 + clk_pin: 6 + mosi_pin: 7 + miso_pin: 5 + +display: + - platform: ili9xxx + id: xpt_display + dimensions: 320x240 + model: TFT 2.4 + cs_pin: 8 + dc_pin: 9 + reset_pin: 10 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: xpt2046 + id: xpt_touchscreen + cs_pin: 4 + interrupt_pin: 3 + display: xpt_display + update_interval: 50ms + threshold: 400 + calibration_x_min: 3860 + calibration_x_max: 280 + calibration_y_min: 340 + calibration_y_max: 3860 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/xpt2046/test.esp32-c3.yaml b/tests/components/xpt2046/test.esp32-c3.yaml new file mode 100644 index 0000000000..38a1da74ae --- /dev/null +++ b/tests/components/xpt2046/test.esp32-c3.yaml @@ -0,0 +1,33 @@ +spi: + - id: spi_xpt2046 + clk_pin: 6 + mosi_pin: 7 + miso_pin: 5 + +display: + - platform: ili9xxx + id: xpt_display + dimensions: 320x240 + model: TFT 2.4 + cs_pin: 8 + dc_pin: 9 + reset_pin: 10 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: xpt2046 + id: xpt_touchscreen + cs_pin: 4 + interrupt_pin: 3 + display: xpt_display + update_interval: 50ms + threshold: 400 + calibration_x_min: 3860 + calibration_x_max: 280 + calibration_y_min: 340 + calibration_y_max: 3860 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/xpt2046/test.esp32-idf.yaml b/tests/components/xpt2046/test.esp32-idf.yaml new file mode 100644 index 0000000000..7f8617d176 --- /dev/null +++ b/tests/components/xpt2046/test.esp32-idf.yaml @@ -0,0 +1,33 @@ +spi: + - id: spi_xpt2046 + clk_pin: 16 + mosi_pin: 17 + miso_pin: 15 + +display: + - platform: ili9xxx + id: xpt_display + dimensions: 320x240 + model: TFT 2.4 + cs_pin: 13 + dc_pin: 14 + reset_pin: 21 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: xpt2046 + id: xpt_touchscreen + cs_pin: 18 + interrupt_pin: 19 + display: xpt_display + update_interval: 50ms + threshold: 400 + calibration_x_min: 3860 + calibration_x_max: 280 + calibration_y_min: 340 + calibration_y_max: 3860 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/xpt2046/test.esp32.yaml b/tests/components/xpt2046/test.esp32.yaml new file mode 100644 index 0000000000..7f8617d176 --- /dev/null +++ b/tests/components/xpt2046/test.esp32.yaml @@ -0,0 +1,33 @@ +spi: + - id: spi_xpt2046 + clk_pin: 16 + mosi_pin: 17 + miso_pin: 15 + +display: + - platform: ili9xxx + id: xpt_display + dimensions: 320x240 + model: TFT 2.4 + cs_pin: 13 + dc_pin: 14 + reset_pin: 21 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: xpt2046 + id: xpt_touchscreen + cs_pin: 18 + interrupt_pin: 19 + display: xpt_display + update_interval: 50ms + threshold: 400 + calibration_x_min: 3860 + calibration_x_max: 280 + calibration_y_min: 340 + calibration_y_max: 3860 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/xpt2046/test.esp8266.yaml b/tests/components/xpt2046/test.esp8266.yaml new file mode 100644 index 0000000000..a998d2df14 --- /dev/null +++ b/tests/components/xpt2046/test.esp8266.yaml @@ -0,0 +1,33 @@ +spi: + - id: spi_xpt2046 + clk_pin: 14 + mosi_pin: 13 + miso_pin: 12 + +display: + - platform: ili9xxx + id: xpt_display + dimensions: 320x240 + model: TFT 2.4 + cs_pin: 15 + dc_pin: 4 + reset_pin: 5 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: xpt2046 + id: xpt_touchscreen + cs_pin: 0 + interrupt_pin: 16 + display: xpt_display + update_interval: 50ms + threshold: 400 + calibration_x_min: 3860 + calibration_x_max: 280 + calibration_y_min: 340 + calibration_y_max: 3860 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/xpt2046/test.rp2040.yaml b/tests/components/xpt2046/test.rp2040.yaml new file mode 100644 index 0000000000..3e5d602247 --- /dev/null +++ b/tests/components/xpt2046/test.rp2040.yaml @@ -0,0 +1,33 @@ +spi: + - id: spi_xpt2046 + clk_pin: 2 + mosi_pin: 3 + miso_pin: 4 + +display: + - platform: ili9xxx + id: xpt_display + dimensions: 320x240 + model: TFT 2.4 + cs_pin: 8 + dc_pin: 9 + reset_pin: 10 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: xpt2046 + id: xpt_touchscreen + cs_pin: 5 + interrupt_pin: 6 + display: xpt_display + update_interval: 50ms + threshold: 400 + calibration_x_min: 3860 + calibration_x_max: 280 + calibration_y_min: 340 + calibration_y_max: 3860 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/yashima/test.esp32-c3-idf.yaml b/tests/components/yashima/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..4b6d6daee4 --- /dev/null +++ b/tests/components/yashima/test.esp32-c3-idf.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: yashima + name: Yashima Climate diff --git a/tests/components/yashima/test.esp32-c3.yaml b/tests/components/yashima/test.esp32-c3.yaml new file mode 100644 index 0000000000..4b6d6daee4 --- /dev/null +++ b/tests/components/yashima/test.esp32-c3.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: yashima + name: Yashima Climate diff --git a/tests/components/yashima/test.esp32-idf.yaml b/tests/components/yashima/test.esp32-idf.yaml new file mode 100644 index 0000000000..4b6d6daee4 --- /dev/null +++ b/tests/components/yashima/test.esp32-idf.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: yashima + name: Yashima Climate diff --git a/tests/components/yashima/test.esp32.yaml b/tests/components/yashima/test.esp32.yaml new file mode 100644 index 0000000000..4b6d6daee4 --- /dev/null +++ b/tests/components/yashima/test.esp32.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: yashima + name: Yashima Climate diff --git a/tests/components/yashima/test.esp8266.yaml b/tests/components/yashima/test.esp8266.yaml new file mode 100644 index 0000000000..296a7ede25 --- /dev/null +++ b/tests/components/yashima/test.esp8266.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 5 + carrier_duty_percent: 50% + +climate: + - platform: yashima + name: Yashima Climate diff --git a/tests/components/zhlt01/test.esp32-c3-idf.yaml b/tests/components/zhlt01/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..d1dc3b4926 --- /dev/null +++ b/tests/components/zhlt01/test.esp32-c3-idf.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: zhlt01 + name: ZH/LT-01 Climate diff --git a/tests/components/zhlt01/test.esp32-c3.yaml b/tests/components/zhlt01/test.esp32-c3.yaml new file mode 100644 index 0000000000..d1dc3b4926 --- /dev/null +++ b/tests/components/zhlt01/test.esp32-c3.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: zhlt01 + name: ZH/LT-01 Climate diff --git a/tests/components/zhlt01/test.esp32-idf.yaml b/tests/components/zhlt01/test.esp32-idf.yaml new file mode 100644 index 0000000000..d1dc3b4926 --- /dev/null +++ b/tests/components/zhlt01/test.esp32-idf.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: zhlt01 + name: ZH/LT-01 Climate diff --git a/tests/components/zhlt01/test.esp32.yaml b/tests/components/zhlt01/test.esp32.yaml new file mode 100644 index 0000000000..d1dc3b4926 --- /dev/null +++ b/tests/components/zhlt01/test.esp32.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: zhlt01 + name: ZH/LT-01 Climate diff --git a/tests/components/zhlt01/test.esp8266.yaml b/tests/components/zhlt01/test.esp8266.yaml new file mode 100644 index 0000000000..40a00bc458 --- /dev/null +++ b/tests/components/zhlt01/test.esp8266.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 5 + carrier_duty_percent: 50% + +climate: + - platform: zhlt01 + name: ZH/LT-01 Climate diff --git a/tests/components/zio_ultrasonic/test.esp32-c3-idf.yaml b/tests/components/zio_ultrasonic/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..36e1697a38 --- /dev/null +++ b/tests/components/zio_ultrasonic/test.esp32-c3-idf.yaml @@ -0,0 +1,9 @@ +i2c: + - id: i2c_zio_ultrasonic + scl: 5 + sda: 4 + +sensor: + - platform: zio_ultrasonic + name: "Distance" + update_interval: 60s diff --git a/tests/components/zio_ultrasonic/test.esp32-c3.yaml b/tests/components/zio_ultrasonic/test.esp32-c3.yaml new file mode 100644 index 0000000000..36e1697a38 --- /dev/null +++ b/tests/components/zio_ultrasonic/test.esp32-c3.yaml @@ -0,0 +1,9 @@ +i2c: + - id: i2c_zio_ultrasonic + scl: 5 + sda: 4 + +sensor: + - platform: zio_ultrasonic + name: "Distance" + update_interval: 60s diff --git a/tests/components/zio_ultrasonic/test.esp32-idf.yaml b/tests/components/zio_ultrasonic/test.esp32-idf.yaml new file mode 100644 index 0000000000..ad4050307e --- /dev/null +++ b/tests/components/zio_ultrasonic/test.esp32-idf.yaml @@ -0,0 +1,9 @@ +i2c: + - id: i2c_zio_ultrasonic + scl: 16 + sda: 17 + +sensor: + - platform: zio_ultrasonic + name: "Distance" + update_interval: 60s diff --git a/tests/components/zio_ultrasonic/test.esp32.yaml b/tests/components/zio_ultrasonic/test.esp32.yaml new file mode 100644 index 0000000000..ad4050307e --- /dev/null +++ b/tests/components/zio_ultrasonic/test.esp32.yaml @@ -0,0 +1,9 @@ +i2c: + - id: i2c_zio_ultrasonic + scl: 16 + sda: 17 + +sensor: + - platform: zio_ultrasonic + name: "Distance" + update_interval: 60s diff --git a/tests/components/zio_ultrasonic/test.esp8266.yaml b/tests/components/zio_ultrasonic/test.esp8266.yaml new file mode 100644 index 0000000000..36e1697a38 --- /dev/null +++ b/tests/components/zio_ultrasonic/test.esp8266.yaml @@ -0,0 +1,9 @@ +i2c: + - id: i2c_zio_ultrasonic + scl: 5 + sda: 4 + +sensor: + - platform: zio_ultrasonic + name: "Distance" + update_interval: 60s diff --git a/tests/components/zio_ultrasonic/test.rp2040.yaml b/tests/components/zio_ultrasonic/test.rp2040.yaml new file mode 100644 index 0000000000..36e1697a38 --- /dev/null +++ b/tests/components/zio_ultrasonic/test.rp2040.yaml @@ -0,0 +1,9 @@ +i2c: + - id: i2c_zio_ultrasonic + scl: 5 + sda: 4 + +sensor: + - platform: zio_ultrasonic + name: "Distance" + update_interval: 60s diff --git a/tests/components/zyaura/test.esp32-c3-idf.yaml b/tests/components/zyaura/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..90205c468c --- /dev/null +++ b/tests/components/zyaura/test.esp32-c3-idf.yaml @@ -0,0 +1,10 @@ +sensor: + - platform: zyaura + clock_pin: 5 + data_pin: 4 + co2: + name: ZyAura CO2 + temperature: + name: ZyAura Temperature + humidity: + name: ZyAura Humidity diff --git a/tests/components/zyaura/test.esp32-c3.yaml b/tests/components/zyaura/test.esp32-c3.yaml new file mode 100644 index 0000000000..90205c468c --- /dev/null +++ b/tests/components/zyaura/test.esp32-c3.yaml @@ -0,0 +1,10 @@ +sensor: + - platform: zyaura + clock_pin: 5 + data_pin: 4 + co2: + name: ZyAura CO2 + temperature: + name: ZyAura Temperature + humidity: + name: ZyAura Humidity diff --git a/tests/components/zyaura/test.esp32-idf.yaml b/tests/components/zyaura/test.esp32-idf.yaml new file mode 100644 index 0000000000..29116a978b --- /dev/null +++ b/tests/components/zyaura/test.esp32-idf.yaml @@ -0,0 +1,10 @@ +sensor: + - platform: zyaura + clock_pin: 16 + data_pin: 17 + co2: + name: ZyAura CO2 + temperature: + name: ZyAura Temperature + humidity: + name: ZyAura Humidity diff --git a/tests/components/zyaura/test.esp32.yaml b/tests/components/zyaura/test.esp32.yaml new file mode 100644 index 0000000000..29116a978b --- /dev/null +++ b/tests/components/zyaura/test.esp32.yaml @@ -0,0 +1,10 @@ +sensor: + - platform: zyaura + clock_pin: 16 + data_pin: 17 + co2: + name: ZyAura CO2 + temperature: + name: ZyAura Temperature + humidity: + name: ZyAura Humidity diff --git a/tests/components/zyaura/test.esp8266.yaml b/tests/components/zyaura/test.esp8266.yaml new file mode 100644 index 0000000000..90205c468c --- /dev/null +++ b/tests/components/zyaura/test.esp8266.yaml @@ -0,0 +1,10 @@ +sensor: + - platform: zyaura + clock_pin: 5 + data_pin: 4 + co2: + name: ZyAura CO2 + temperature: + name: ZyAura Temperature + humidity: + name: ZyAura Humidity diff --git a/tests/components/zyaura/test.rp2040.yaml b/tests/components/zyaura/test.rp2040.yaml new file mode 100644 index 0000000000..90205c468c --- /dev/null +++ b/tests/components/zyaura/test.rp2040.yaml @@ -0,0 +1,10 @@ +sensor: + - platform: zyaura + clock_pin: 5 + data_pin: 4 + co2: + name: ZyAura CO2 + temperature: + name: ZyAura Temperature + humidity: + name: ZyAura Humidity From 61f11386a94424f892e70fbc7bf86afc60f38c9f Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Mon, 18 Mar 2024 18:52:40 -0500 Subject: [PATCH 129/189] Add some components to the new testing framework (E) (#6176) --- tests/components/e131/test.esp32-c3-idf.yaml | 18 ++++++ tests/components/e131/test.esp32-c3.yaml | 18 ++++++ tests/components/e131/test.esp32-idf.yaml | 18 ++++++ tests/components/e131/test.esp32.yaml | 18 ++++++ tests/components/e131/test.esp8266.yaml | 17 ++++++ tests/components/e131/test.rp2040.yaml | 17 ++++++ tests/components/ee895/test.esp32-c3-idf.yaml | 14 +++++ tests/components/ee895/test.esp32-c3.yaml | 14 +++++ tests/components/ee895/test.esp32-idf.yaml | 14 +++++ tests/components/ee895/test.esp32.yaml | 14 +++++ tests/components/ee895/test.esp8266.yaml | 14 +++++ tests/components/ee895/test.rp2040.yaml | 14 +++++ .../ektf2232/test.esp32-c3-idf.yaml | 24 ++++++++ tests/components/ektf2232/test.esp32-c3.yaml | 24 ++++++++ tests/components/ektf2232/test.esp32-idf.yaml | 24 ++++++++ tests/components/ektf2232/test.esp32.yaml | 24 ++++++++ tests/components/ektf2232/test.esp8266.yaml | 24 ++++++++ tests/components/ektf2232/test.rp2040.yaml | 24 ++++++++ .../components/emc2101/test.esp32-c3-idf.yaml | 25 ++++++++ tests/components/emc2101/test.esp32-c3.yaml | 25 ++++++++ tests/components/emc2101/test.esp32-idf.yaml | 25 ++++++++ tests/components/emc2101/test.esp32.yaml | 25 ++++++++ tests/components/emc2101/test.esp8266.yaml | 25 ++++++++ tests/components/emc2101/test.rp2040.yaml | 25 ++++++++ .../components/endstop/test.esp32-c3-idf.yaml | 33 ++++++++++ tests/components/endstop/test.esp32-c3.yaml | 33 ++++++++++ tests/components/endstop/test.esp32-idf.yaml | 33 ++++++++++ tests/components/endstop/test.esp32.yaml | 33 ++++++++++ tests/components/endstop/test.esp8266.yaml | 33 ++++++++++ tests/components/endstop/test.rp2040.yaml | 33 ++++++++++ .../components/ens160/test.esp32-c3-idf.yaml | 13 ++++ tests/components/ens160/test.esp32-c3.yaml | 13 ++++ tests/components/ens160/test.esp32-idf.yaml | 13 ++++ tests/components/ens160/test.esp32.yaml | 13 ++++ tests/components/ens160/test.esp8266.yaml | 13 ++++ tests/components/ens160/test.rp2040.yaml | 13 ++++ .../components/ens210/test.esp32-c3-idf.yaml | 12 ++++ tests/components/ens210/test.esp32-c3.yaml | 12 ++++ tests/components/ens210/test.esp32-idf.yaml | 12 ++++ tests/components/ens210/test.esp32.yaml | 12 ++++ tests/components/ens210/test.esp8266.yaml | 12 ++++ tests/components/ens210/test.rp2040.yaml | 12 ++++ .../esp32_ble/test.esp32-c3-idf.yaml | 2 + tests/components/esp32_ble/test.esp32-c3.yaml | 2 + .../components/esp32_ble/test.esp32-idf.yaml | 2 + tests/components/esp32_ble/test.esp32.yaml | 2 + .../esp32_ble_beacon/test.esp32-c3-idf.yaml | 3 + .../esp32_ble_beacon/test.esp32-c3.yaml | 3 + .../esp32_ble_beacon/test.esp32-idf.yaml | 3 + .../esp32_ble_beacon/test.esp32.yaml | 3 + .../esp32_ble_client/test.esp32-c3-idf.yaml | 5 ++ .../esp32_ble_client/test.esp32-c3.yaml | 5 ++ .../esp32_ble_client/test.esp32-idf.yaml | 5 ++ .../esp32_ble_client/test.esp32.yaml | 5 ++ .../esp32_ble_server/test.esp32-c3-idf.yaml | 3 + .../esp32_ble_server/test.esp32-c3.yaml | 3 + .../esp32_ble_server/test.esp32-idf.yaml | 3 + .../esp32_ble_server/test.esp32.yaml | 3 + .../esp32_ble_tracker/test.esp32-c3-idf.yaml | 41 +++++++++++++ .../esp32_ble_tracker/test.esp32-c3.yaml | 41 +++++++++++++ .../esp32_ble_tracker/test.esp32-idf.yaml | 41 +++++++++++++ .../esp32_ble_tracker/test.esp32.yaml | 41 +++++++++++++ .../esp32_camera/test.esp32-idf.yaml | 28 +++++++++ tests/components/esp32_camera/test.esp32.yaml | 28 +++++++++ .../test.esp32-idf.yaml | 34 +++++++++++ .../esp32_camera_web_server/test.esp32.yaml | 34 +++++++++++ .../esp32_can/test.esp32-c3-idf.yaml | 45 ++++++++++++++ tests/components/esp32_can/test.esp32-c3.yaml | 45 ++++++++++++++ .../components/esp32_can/test.esp32-idf.yaml | 45 ++++++++++++++ tests/components/esp32_can/test.esp32.yaml | 45 ++++++++++++++ .../components/esp32_dac/test.esp32-idf.yaml | 4 ++ tests/components/esp32_dac/test.esp32.yaml | 4 ++ .../components/esp32_hall/test.esp32-idf.yaml | 3 + tests/components/esp32_hall/test.esp32.yaml | 3 + .../esp32_improv/test.esp32-c3-idf.yaml | 18 ++++++ .../esp32_improv/test.esp32-c3.yaml | 18 ++++++ .../esp32_improv/test.esp32-idf.yaml | 18 ++++++ tests/components/esp32_improv/test.esp32.yaml | 18 ++++++ .../test.esp32-c3-idf.yaml | 18 ++++++ .../esp32_rmt_led_strip/test.esp32-c3.yaml | 18 ++++++ .../esp32_rmt_led_strip/test.esp32-idf.yaml | 18 ++++++ .../esp32_rmt_led_strip/test.esp32.yaml | 18 ++++++ .../esp32_touch/test.esp32-idf.yaml | 16 +++++ tests/components/esp32_touch/test.esp32.yaml | 16 +++++ .../components/esp8266_pwm/test.esp8266.yaml | 8 +++ tests/components/ethernet/test.esp32-idf.yaml | 12 ++++ tests/components/ethernet/test.esp32.yaml | 12 ++++ .../ethernet_info/test.esp32-idf.yaml | 17 ++++++ .../components/ethernet_info/test.esp32.yaml | 17 ++++++ .../test.esp32-c3-idf.yaml | 9 +++ .../exposure_notifications/test.esp32-c3.yaml | 9 +++ .../test.esp32-idf.yaml | 9 +++ .../exposure_notifications/test.esp32.yaml | 9 +++ .../test.esp32-c3-idf.yaml | 6 ++ .../external_components/test.esp32-c3.yaml | 6 ++ .../external_components/test.esp32-idf.yaml | 6 ++ .../external_components/test.esp32.yaml | 6 ++ .../external_components/test.esp8266.yaml | 6 ++ .../external_components/test.rp2040.yaml | 6 ++ tests/components/ezo/test.esp32-c3-idf.yaml | 10 +++ tests/components/ezo/test.esp32-c3.yaml | 10 +++ tests/components/ezo/test.esp32-idf.yaml | 10 +++ tests/components/ezo/test.esp32.yaml | 10 +++ tests/components/ezo/test.esp8266.yaml | 10 +++ tests/components/ezo/test.rp2040.yaml | 10 +++ .../components/ezo_pmp/test.esp32-c3-idf.yaml | 61 +++++++++++++++++++ tests/components/ezo_pmp/test.esp32-c3.yaml | 61 +++++++++++++++++++ tests/components/ezo_pmp/test.esp32-idf.yaml | 61 +++++++++++++++++++ tests/components/ezo_pmp/test.esp32.yaml | 61 +++++++++++++++++++ tests/components/ezo_pmp/test.esp8266.yaml | 61 +++++++++++++++++++ tests/components/ezo_pmp/test.rp2040.yaml | 61 +++++++++++++++++++ 111 files changed, 2106 insertions(+) create mode 100644 tests/components/e131/test.esp32-c3-idf.yaml create mode 100644 tests/components/e131/test.esp32-c3.yaml create mode 100644 tests/components/e131/test.esp32-idf.yaml create mode 100644 tests/components/e131/test.esp32.yaml create mode 100644 tests/components/e131/test.esp8266.yaml create mode 100644 tests/components/e131/test.rp2040.yaml create mode 100644 tests/components/ee895/test.esp32-c3-idf.yaml create mode 100644 tests/components/ee895/test.esp32-c3.yaml create mode 100644 tests/components/ee895/test.esp32-idf.yaml create mode 100644 tests/components/ee895/test.esp32.yaml create mode 100644 tests/components/ee895/test.esp8266.yaml create mode 100644 tests/components/ee895/test.rp2040.yaml create mode 100644 tests/components/ektf2232/test.esp32-c3-idf.yaml create mode 100644 tests/components/ektf2232/test.esp32-c3.yaml create mode 100644 tests/components/ektf2232/test.esp32-idf.yaml create mode 100644 tests/components/ektf2232/test.esp32.yaml create mode 100644 tests/components/ektf2232/test.esp8266.yaml create mode 100644 tests/components/ektf2232/test.rp2040.yaml create mode 100644 tests/components/emc2101/test.esp32-c3-idf.yaml create mode 100644 tests/components/emc2101/test.esp32-c3.yaml create mode 100644 tests/components/emc2101/test.esp32-idf.yaml create mode 100644 tests/components/emc2101/test.esp32.yaml create mode 100644 tests/components/emc2101/test.esp8266.yaml create mode 100644 tests/components/emc2101/test.rp2040.yaml create mode 100644 tests/components/endstop/test.esp32-c3-idf.yaml create mode 100644 tests/components/endstop/test.esp32-c3.yaml create mode 100644 tests/components/endstop/test.esp32-idf.yaml create mode 100644 tests/components/endstop/test.esp32.yaml create mode 100644 tests/components/endstop/test.esp8266.yaml create mode 100644 tests/components/endstop/test.rp2040.yaml create mode 100644 tests/components/ens160/test.esp32-c3-idf.yaml create mode 100644 tests/components/ens160/test.esp32-c3.yaml create mode 100644 tests/components/ens160/test.esp32-idf.yaml create mode 100644 tests/components/ens160/test.esp32.yaml create mode 100644 tests/components/ens160/test.esp8266.yaml create mode 100644 tests/components/ens160/test.rp2040.yaml create mode 100644 tests/components/ens210/test.esp32-c3-idf.yaml create mode 100644 tests/components/ens210/test.esp32-c3.yaml create mode 100644 tests/components/ens210/test.esp32-idf.yaml create mode 100644 tests/components/ens210/test.esp32.yaml create mode 100644 tests/components/ens210/test.esp8266.yaml create mode 100644 tests/components/ens210/test.rp2040.yaml create mode 100644 tests/components/esp32_ble/test.esp32-c3-idf.yaml create mode 100644 tests/components/esp32_ble/test.esp32-c3.yaml create mode 100644 tests/components/esp32_ble/test.esp32-idf.yaml create mode 100644 tests/components/esp32_ble/test.esp32.yaml create mode 100644 tests/components/esp32_ble_beacon/test.esp32-c3-idf.yaml create mode 100644 tests/components/esp32_ble_beacon/test.esp32-c3.yaml create mode 100644 tests/components/esp32_ble_beacon/test.esp32-idf.yaml create mode 100644 tests/components/esp32_ble_beacon/test.esp32.yaml create mode 100644 tests/components/esp32_ble_client/test.esp32-c3-idf.yaml create mode 100644 tests/components/esp32_ble_client/test.esp32-c3.yaml create mode 100644 tests/components/esp32_ble_client/test.esp32-idf.yaml create mode 100644 tests/components/esp32_ble_client/test.esp32.yaml create mode 100644 tests/components/esp32_ble_server/test.esp32-c3-idf.yaml create mode 100644 tests/components/esp32_ble_server/test.esp32-c3.yaml create mode 100644 tests/components/esp32_ble_server/test.esp32-idf.yaml create mode 100644 tests/components/esp32_ble_server/test.esp32.yaml create mode 100644 tests/components/esp32_ble_tracker/test.esp32-c3-idf.yaml create mode 100644 tests/components/esp32_ble_tracker/test.esp32-c3.yaml create mode 100644 tests/components/esp32_ble_tracker/test.esp32-idf.yaml create mode 100644 tests/components/esp32_ble_tracker/test.esp32.yaml create mode 100644 tests/components/esp32_camera/test.esp32-idf.yaml create mode 100644 tests/components/esp32_camera/test.esp32.yaml create mode 100644 tests/components/esp32_camera_web_server/test.esp32-idf.yaml create mode 100644 tests/components/esp32_camera_web_server/test.esp32.yaml create mode 100644 tests/components/esp32_can/test.esp32-c3-idf.yaml create mode 100644 tests/components/esp32_can/test.esp32-c3.yaml create mode 100644 tests/components/esp32_can/test.esp32-idf.yaml create mode 100644 tests/components/esp32_can/test.esp32.yaml create mode 100644 tests/components/esp32_dac/test.esp32-idf.yaml create mode 100644 tests/components/esp32_dac/test.esp32.yaml create mode 100644 tests/components/esp32_hall/test.esp32-idf.yaml create mode 100644 tests/components/esp32_hall/test.esp32.yaml create mode 100644 tests/components/esp32_improv/test.esp32-c3-idf.yaml create mode 100644 tests/components/esp32_improv/test.esp32-c3.yaml create mode 100644 tests/components/esp32_improv/test.esp32-idf.yaml create mode 100644 tests/components/esp32_improv/test.esp32.yaml create mode 100644 tests/components/esp32_rmt_led_strip/test.esp32-c3-idf.yaml create mode 100644 tests/components/esp32_rmt_led_strip/test.esp32-c3.yaml create mode 100644 tests/components/esp32_rmt_led_strip/test.esp32-idf.yaml create mode 100644 tests/components/esp32_rmt_led_strip/test.esp32.yaml create mode 100644 tests/components/esp32_touch/test.esp32-idf.yaml create mode 100644 tests/components/esp32_touch/test.esp32.yaml create mode 100644 tests/components/esp8266_pwm/test.esp8266.yaml create mode 100644 tests/components/ethernet/test.esp32-idf.yaml create mode 100644 tests/components/ethernet/test.esp32.yaml create mode 100644 tests/components/ethernet_info/test.esp32-idf.yaml create mode 100644 tests/components/ethernet_info/test.esp32.yaml create mode 100644 tests/components/exposure_notifications/test.esp32-c3-idf.yaml create mode 100644 tests/components/exposure_notifications/test.esp32-c3.yaml create mode 100644 tests/components/exposure_notifications/test.esp32-idf.yaml create mode 100644 tests/components/exposure_notifications/test.esp32.yaml create mode 100644 tests/components/external_components/test.esp32-c3-idf.yaml create mode 100644 tests/components/external_components/test.esp32-c3.yaml create mode 100644 tests/components/external_components/test.esp32-idf.yaml create mode 100644 tests/components/external_components/test.esp32.yaml create mode 100644 tests/components/external_components/test.esp8266.yaml create mode 100644 tests/components/external_components/test.rp2040.yaml create mode 100644 tests/components/ezo/test.esp32-c3-idf.yaml create mode 100644 tests/components/ezo/test.esp32-c3.yaml create mode 100644 tests/components/ezo/test.esp32-idf.yaml create mode 100644 tests/components/ezo/test.esp32.yaml create mode 100644 tests/components/ezo/test.esp8266.yaml create mode 100644 tests/components/ezo/test.rp2040.yaml create mode 100644 tests/components/ezo_pmp/test.esp32-c3-idf.yaml create mode 100644 tests/components/ezo_pmp/test.esp32-c3.yaml create mode 100644 tests/components/ezo_pmp/test.esp32-idf.yaml create mode 100644 tests/components/ezo_pmp/test.esp32.yaml create mode 100644 tests/components/ezo_pmp/test.esp8266.yaml create mode 100644 tests/components/ezo_pmp/test.rp2040.yaml diff --git a/tests/components/e131/test.esp32-c3-idf.yaml b/tests/components/e131/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..25304cd3b4 --- /dev/null +++ b/tests/components/e131/test.esp32-c3-idf.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +e131: + +light: + - platform: esp32_rmt_led_strip + id: led_matrix_32x8 + default_transition_length: 500ms + chipset: ws2812 + rgb_order: GRB + num_leds: 256 + pin: 2 + rmt_channel: 0 + effects: + - e131: + universe: 1 diff --git a/tests/components/e131/test.esp32-c3.yaml b/tests/components/e131/test.esp32-c3.yaml new file mode 100644 index 0000000000..25304cd3b4 --- /dev/null +++ b/tests/components/e131/test.esp32-c3.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +e131: + +light: + - platform: esp32_rmt_led_strip + id: led_matrix_32x8 + default_transition_length: 500ms + chipset: ws2812 + rgb_order: GRB + num_leds: 256 + pin: 2 + rmt_channel: 0 + effects: + - e131: + universe: 1 diff --git a/tests/components/e131/test.esp32-idf.yaml b/tests/components/e131/test.esp32-idf.yaml new file mode 100644 index 0000000000..25304cd3b4 --- /dev/null +++ b/tests/components/e131/test.esp32-idf.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +e131: + +light: + - platform: esp32_rmt_led_strip + id: led_matrix_32x8 + default_transition_length: 500ms + chipset: ws2812 + rgb_order: GRB + num_leds: 256 + pin: 2 + rmt_channel: 0 + effects: + - e131: + universe: 1 diff --git a/tests/components/e131/test.esp32.yaml b/tests/components/e131/test.esp32.yaml new file mode 100644 index 0000000000..25304cd3b4 --- /dev/null +++ b/tests/components/e131/test.esp32.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +e131: + +light: + - platform: esp32_rmt_led_strip + id: led_matrix_32x8 + default_transition_length: 500ms + chipset: ws2812 + rgb_order: GRB + num_leds: 256 + pin: 2 + rmt_channel: 0 + effects: + - e131: + universe: 1 diff --git a/tests/components/e131/test.esp8266.yaml b/tests/components/e131/test.esp8266.yaml new file mode 100644 index 0000000000..54245014a5 --- /dev/null +++ b/tests/components/e131/test.esp8266.yaml @@ -0,0 +1,17 @@ +wifi: + ssid: MySSID + password: password1 + +e131: + +light: + - platform: neopixelbus + name: Neopixelbus Light + pin: 1 + type: GRBW + variant: SK6812 + method: ESP8266_UART0 + num_leds: 256 + effects: + - e131: + universe: 1 diff --git a/tests/components/e131/test.rp2040.yaml b/tests/components/e131/test.rp2040.yaml new file mode 100644 index 0000000000..0ae31f5403 --- /dev/null +++ b/tests/components/e131/test.rp2040.yaml @@ -0,0 +1,17 @@ +wifi: + ssid: MySSID + password: password1 + +e131: + +light: + - platform: rp2040_pio_led_strip + id: led_strip + pin: 2 + pio: 0 + num_leds: 256 + rgb_order: GRB + chipset: WS2812 + effects: + - e131: + universe: 1 diff --git a/tests/components/ee895/test.esp32-c3-idf.yaml b/tests/components/ee895/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..4a36117fab --- /dev/null +++ b/tests/components/ee895/test.esp32-c3-idf.yaml @@ -0,0 +1,14 @@ +i2c: + - id: i2c_ee895 + scl: 5 + sda: 4 + +sensor: + - platform: ee895 + address: 0x5F + co2: + name: EE895 CO2 + temperature: + name: EE895 Temperature + pressure: + name: EE895 Pressure diff --git a/tests/components/ee895/test.esp32-c3.yaml b/tests/components/ee895/test.esp32-c3.yaml new file mode 100644 index 0000000000..4a36117fab --- /dev/null +++ b/tests/components/ee895/test.esp32-c3.yaml @@ -0,0 +1,14 @@ +i2c: + - id: i2c_ee895 + scl: 5 + sda: 4 + +sensor: + - platform: ee895 + address: 0x5F + co2: + name: EE895 CO2 + temperature: + name: EE895 Temperature + pressure: + name: EE895 Pressure diff --git a/tests/components/ee895/test.esp32-idf.yaml b/tests/components/ee895/test.esp32-idf.yaml new file mode 100644 index 0000000000..241bdb9574 --- /dev/null +++ b/tests/components/ee895/test.esp32-idf.yaml @@ -0,0 +1,14 @@ +i2c: + - id: i2c_ee895 + scl: 16 + sda: 17 + +sensor: + - platform: ee895 + address: 0x5F + co2: + name: EE895 CO2 + temperature: + name: EE895 Temperature + pressure: + name: EE895 Pressure diff --git a/tests/components/ee895/test.esp32.yaml b/tests/components/ee895/test.esp32.yaml new file mode 100644 index 0000000000..241bdb9574 --- /dev/null +++ b/tests/components/ee895/test.esp32.yaml @@ -0,0 +1,14 @@ +i2c: + - id: i2c_ee895 + scl: 16 + sda: 17 + +sensor: + - platform: ee895 + address: 0x5F + co2: + name: EE895 CO2 + temperature: + name: EE895 Temperature + pressure: + name: EE895 Pressure diff --git a/tests/components/ee895/test.esp8266.yaml b/tests/components/ee895/test.esp8266.yaml new file mode 100644 index 0000000000..4a36117fab --- /dev/null +++ b/tests/components/ee895/test.esp8266.yaml @@ -0,0 +1,14 @@ +i2c: + - id: i2c_ee895 + scl: 5 + sda: 4 + +sensor: + - platform: ee895 + address: 0x5F + co2: + name: EE895 CO2 + temperature: + name: EE895 Temperature + pressure: + name: EE895 Pressure diff --git a/tests/components/ee895/test.rp2040.yaml b/tests/components/ee895/test.rp2040.yaml new file mode 100644 index 0000000000..4a36117fab --- /dev/null +++ b/tests/components/ee895/test.rp2040.yaml @@ -0,0 +1,14 @@ +i2c: + - id: i2c_ee895 + scl: 5 + sda: 4 + +sensor: + - platform: ee895 + address: 0x5F + co2: + name: EE895 CO2 + temperature: + name: EE895 Temperature + pressure: + name: EE895 Pressure diff --git a/tests/components/ektf2232/test.esp32-c3-idf.yaml b/tests/components/ektf2232/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..371f2795a2 --- /dev/null +++ b/tests/components/ektf2232/test.esp32-c3-idf.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_ektf2232 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ektf2232 + interrupt_pin: 6 + rts_pin: 7 + display: ssd1306_display + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ektf2232/test.esp32-c3.yaml b/tests/components/ektf2232/test.esp32-c3.yaml new file mode 100644 index 0000000000..371f2795a2 --- /dev/null +++ b/tests/components/ektf2232/test.esp32-c3.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_ektf2232 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ektf2232 + interrupt_pin: 6 + rts_pin: 7 + display: ssd1306_display + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ektf2232/test.esp32-idf.yaml b/tests/components/ektf2232/test.esp32-idf.yaml new file mode 100644 index 0000000000..9c6eef8bb3 --- /dev/null +++ b/tests/components/ektf2232/test.esp32-idf.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_ektf2232 + scl: 16 + sda: 17 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ektf2232 + interrupt_pin: 14 + rts_pin: 15 + display: ssd1306_display + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ektf2232/test.esp32.yaml b/tests/components/ektf2232/test.esp32.yaml new file mode 100644 index 0000000000..9c6eef8bb3 --- /dev/null +++ b/tests/components/ektf2232/test.esp32.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_ektf2232 + scl: 16 + sda: 17 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ektf2232 + interrupt_pin: 14 + rts_pin: 15 + display: ssd1306_display + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ektf2232/test.esp8266.yaml b/tests/components/ektf2232/test.esp8266.yaml new file mode 100644 index 0000000000..03f18f7184 --- /dev/null +++ b/tests/components/ektf2232/test.esp8266.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_ektf2232 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ektf2232 + interrupt_pin: 12 + rts_pin: 13 + display: ssd1306_display + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ektf2232/test.rp2040.yaml b/tests/components/ektf2232/test.rp2040.yaml new file mode 100644 index 0000000000..371f2795a2 --- /dev/null +++ b/tests/components/ektf2232/test.rp2040.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_ektf2232 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ektf2232 + interrupt_pin: 6 + rts_pin: 7 + display: ssd1306_display + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/emc2101/test.esp32-c3-idf.yaml b/tests/components/emc2101/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..d95bc1b001 --- /dev/null +++ b/tests/components/emc2101/test.esp32-c3-idf.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_emc2101 + scl: 5 + sda: 4 + +emc2101: + pwm: + resolution: 8 + +output: + - platform: emc2101 + id: fan_duty_cycle + +sensor: + - platform: emc2101 + internal_temperature: + id: internal_temperature_sensor + name: Internal Temperature Sensor + speed: + id: speed_sensor + name: Speed Sensor + duty_cycle: + id: duty_cycle_sensor + name: Duty Cycle Sensor + update_interval: 5s diff --git a/tests/components/emc2101/test.esp32-c3.yaml b/tests/components/emc2101/test.esp32-c3.yaml new file mode 100644 index 0000000000..d95bc1b001 --- /dev/null +++ b/tests/components/emc2101/test.esp32-c3.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_emc2101 + scl: 5 + sda: 4 + +emc2101: + pwm: + resolution: 8 + +output: + - platform: emc2101 + id: fan_duty_cycle + +sensor: + - platform: emc2101 + internal_temperature: + id: internal_temperature_sensor + name: Internal Temperature Sensor + speed: + id: speed_sensor + name: Speed Sensor + duty_cycle: + id: duty_cycle_sensor + name: Duty Cycle Sensor + update_interval: 5s diff --git a/tests/components/emc2101/test.esp32-idf.yaml b/tests/components/emc2101/test.esp32-idf.yaml new file mode 100644 index 0000000000..34a7d22b71 --- /dev/null +++ b/tests/components/emc2101/test.esp32-idf.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_emc2101 + scl: 16 + sda: 17 + +emc2101: + pwm: + resolution: 8 + +output: + - platform: emc2101 + id: fan_duty_cycle + +sensor: + - platform: emc2101 + internal_temperature: + id: internal_temperature_sensor + name: Internal Temperature Sensor + speed: + id: speed_sensor + name: Speed Sensor + duty_cycle: + id: duty_cycle_sensor + name: Duty Cycle Sensor + update_interval: 5s diff --git a/tests/components/emc2101/test.esp32.yaml b/tests/components/emc2101/test.esp32.yaml new file mode 100644 index 0000000000..34a7d22b71 --- /dev/null +++ b/tests/components/emc2101/test.esp32.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_emc2101 + scl: 16 + sda: 17 + +emc2101: + pwm: + resolution: 8 + +output: + - platform: emc2101 + id: fan_duty_cycle + +sensor: + - platform: emc2101 + internal_temperature: + id: internal_temperature_sensor + name: Internal Temperature Sensor + speed: + id: speed_sensor + name: Speed Sensor + duty_cycle: + id: duty_cycle_sensor + name: Duty Cycle Sensor + update_interval: 5s diff --git a/tests/components/emc2101/test.esp8266.yaml b/tests/components/emc2101/test.esp8266.yaml new file mode 100644 index 0000000000..d95bc1b001 --- /dev/null +++ b/tests/components/emc2101/test.esp8266.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_emc2101 + scl: 5 + sda: 4 + +emc2101: + pwm: + resolution: 8 + +output: + - platform: emc2101 + id: fan_duty_cycle + +sensor: + - platform: emc2101 + internal_temperature: + id: internal_temperature_sensor + name: Internal Temperature Sensor + speed: + id: speed_sensor + name: Speed Sensor + duty_cycle: + id: duty_cycle_sensor + name: Duty Cycle Sensor + update_interval: 5s diff --git a/tests/components/emc2101/test.rp2040.yaml b/tests/components/emc2101/test.rp2040.yaml new file mode 100644 index 0000000000..d95bc1b001 --- /dev/null +++ b/tests/components/emc2101/test.rp2040.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_emc2101 + scl: 5 + sda: 4 + +emc2101: + pwm: + resolution: 8 + +output: + - platform: emc2101 + id: fan_duty_cycle + +sensor: + - platform: emc2101 + internal_temperature: + id: internal_temperature_sensor + name: Internal Temperature Sensor + speed: + id: speed_sensor + name: Speed Sensor + duty_cycle: + id: duty_cycle_sensor + name: Duty Cycle Sensor + update_interval: 5s diff --git a/tests/components/endstop/test.esp32-c3-idf.yaml b/tests/components/endstop/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..341fbf7260 --- /dev/null +++ b/tests/components/endstop/test.esp32-c3-idf.yaml @@ -0,0 +1,33 @@ +binary_sensor: + - platform: template + id: bin1 + lambda: |- + if (millis() > 10000) { + return true; + } else { + return false; + } + +switch: + - platform: template + id: template_switch1 + optimistic: true + - platform: template + id: template_switch2 + optimistic: true + +cover: + - platform: endstop + id: endstop_cover + name: Endstop Cover + stop_action: + - switch.turn_on: template_switch1 + open_endstop: bin1 + open_action: + - switch.turn_on: template_switch1 + open_duration: 5min + close_endstop: bin1 + close_action: + - switch.turn_on: template_switch2 + close_duration: 4.5min + max_duration: 10min diff --git a/tests/components/endstop/test.esp32-c3.yaml b/tests/components/endstop/test.esp32-c3.yaml new file mode 100644 index 0000000000..341fbf7260 --- /dev/null +++ b/tests/components/endstop/test.esp32-c3.yaml @@ -0,0 +1,33 @@ +binary_sensor: + - platform: template + id: bin1 + lambda: |- + if (millis() > 10000) { + return true; + } else { + return false; + } + +switch: + - platform: template + id: template_switch1 + optimistic: true + - platform: template + id: template_switch2 + optimistic: true + +cover: + - platform: endstop + id: endstop_cover + name: Endstop Cover + stop_action: + - switch.turn_on: template_switch1 + open_endstop: bin1 + open_action: + - switch.turn_on: template_switch1 + open_duration: 5min + close_endstop: bin1 + close_action: + - switch.turn_on: template_switch2 + close_duration: 4.5min + max_duration: 10min diff --git a/tests/components/endstop/test.esp32-idf.yaml b/tests/components/endstop/test.esp32-idf.yaml new file mode 100644 index 0000000000..341fbf7260 --- /dev/null +++ b/tests/components/endstop/test.esp32-idf.yaml @@ -0,0 +1,33 @@ +binary_sensor: + - platform: template + id: bin1 + lambda: |- + if (millis() > 10000) { + return true; + } else { + return false; + } + +switch: + - platform: template + id: template_switch1 + optimistic: true + - platform: template + id: template_switch2 + optimistic: true + +cover: + - platform: endstop + id: endstop_cover + name: Endstop Cover + stop_action: + - switch.turn_on: template_switch1 + open_endstop: bin1 + open_action: + - switch.turn_on: template_switch1 + open_duration: 5min + close_endstop: bin1 + close_action: + - switch.turn_on: template_switch2 + close_duration: 4.5min + max_duration: 10min diff --git a/tests/components/endstop/test.esp32.yaml b/tests/components/endstop/test.esp32.yaml new file mode 100644 index 0000000000..341fbf7260 --- /dev/null +++ b/tests/components/endstop/test.esp32.yaml @@ -0,0 +1,33 @@ +binary_sensor: + - platform: template + id: bin1 + lambda: |- + if (millis() > 10000) { + return true; + } else { + return false; + } + +switch: + - platform: template + id: template_switch1 + optimistic: true + - platform: template + id: template_switch2 + optimistic: true + +cover: + - platform: endstop + id: endstop_cover + name: Endstop Cover + stop_action: + - switch.turn_on: template_switch1 + open_endstop: bin1 + open_action: + - switch.turn_on: template_switch1 + open_duration: 5min + close_endstop: bin1 + close_action: + - switch.turn_on: template_switch2 + close_duration: 4.5min + max_duration: 10min diff --git a/tests/components/endstop/test.esp8266.yaml b/tests/components/endstop/test.esp8266.yaml new file mode 100644 index 0000000000..341fbf7260 --- /dev/null +++ b/tests/components/endstop/test.esp8266.yaml @@ -0,0 +1,33 @@ +binary_sensor: + - platform: template + id: bin1 + lambda: |- + if (millis() > 10000) { + return true; + } else { + return false; + } + +switch: + - platform: template + id: template_switch1 + optimistic: true + - platform: template + id: template_switch2 + optimistic: true + +cover: + - platform: endstop + id: endstop_cover + name: Endstop Cover + stop_action: + - switch.turn_on: template_switch1 + open_endstop: bin1 + open_action: + - switch.turn_on: template_switch1 + open_duration: 5min + close_endstop: bin1 + close_action: + - switch.turn_on: template_switch2 + close_duration: 4.5min + max_duration: 10min diff --git a/tests/components/endstop/test.rp2040.yaml b/tests/components/endstop/test.rp2040.yaml new file mode 100644 index 0000000000..341fbf7260 --- /dev/null +++ b/tests/components/endstop/test.rp2040.yaml @@ -0,0 +1,33 @@ +binary_sensor: + - platform: template + id: bin1 + lambda: |- + if (millis() > 10000) { + return true; + } else { + return false; + } + +switch: + - platform: template + id: template_switch1 + optimistic: true + - platform: template + id: template_switch2 + optimistic: true + +cover: + - platform: endstop + id: endstop_cover + name: Endstop Cover + stop_action: + - switch.turn_on: template_switch1 + open_endstop: bin1 + open_action: + - switch.turn_on: template_switch1 + open_duration: 5min + close_endstop: bin1 + close_action: + - switch.turn_on: template_switch2 + close_duration: 4.5min + max_duration: 10min diff --git a/tests/components/ens160/test.esp32-c3-idf.yaml b/tests/components/ens160/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..29f48e812f --- /dev/null +++ b/tests/components/ens160/test.esp32-c3-idf.yaml @@ -0,0 +1,13 @@ +i2c: + - id: i2c_ens160 + scl: 5 + sda: 4 + +sensor: + - platform: ens160 + eco2: + name: ENS160 eCO2 + tvoc: + name: ENS160 Total Volatile Organic Compounds + aqi: + name: ENS160 Air Quality Index diff --git a/tests/components/ens160/test.esp32-c3.yaml b/tests/components/ens160/test.esp32-c3.yaml new file mode 100644 index 0000000000..29f48e812f --- /dev/null +++ b/tests/components/ens160/test.esp32-c3.yaml @@ -0,0 +1,13 @@ +i2c: + - id: i2c_ens160 + scl: 5 + sda: 4 + +sensor: + - platform: ens160 + eco2: + name: ENS160 eCO2 + tvoc: + name: ENS160 Total Volatile Organic Compounds + aqi: + name: ENS160 Air Quality Index diff --git a/tests/components/ens160/test.esp32-idf.yaml b/tests/components/ens160/test.esp32-idf.yaml new file mode 100644 index 0000000000..23f7674aef --- /dev/null +++ b/tests/components/ens160/test.esp32-idf.yaml @@ -0,0 +1,13 @@ +i2c: + - id: i2c_ens160 + scl: 16 + sda: 17 + +sensor: + - platform: ens160 + eco2: + name: ENS160 eCO2 + tvoc: + name: ENS160 Total Volatile Organic Compounds + aqi: + name: ENS160 Air Quality Index diff --git a/tests/components/ens160/test.esp32.yaml b/tests/components/ens160/test.esp32.yaml new file mode 100644 index 0000000000..23f7674aef --- /dev/null +++ b/tests/components/ens160/test.esp32.yaml @@ -0,0 +1,13 @@ +i2c: + - id: i2c_ens160 + scl: 16 + sda: 17 + +sensor: + - platform: ens160 + eco2: + name: ENS160 eCO2 + tvoc: + name: ENS160 Total Volatile Organic Compounds + aqi: + name: ENS160 Air Quality Index diff --git a/tests/components/ens160/test.esp8266.yaml b/tests/components/ens160/test.esp8266.yaml new file mode 100644 index 0000000000..29f48e812f --- /dev/null +++ b/tests/components/ens160/test.esp8266.yaml @@ -0,0 +1,13 @@ +i2c: + - id: i2c_ens160 + scl: 5 + sda: 4 + +sensor: + - platform: ens160 + eco2: + name: ENS160 eCO2 + tvoc: + name: ENS160 Total Volatile Organic Compounds + aqi: + name: ENS160 Air Quality Index diff --git a/tests/components/ens160/test.rp2040.yaml b/tests/components/ens160/test.rp2040.yaml new file mode 100644 index 0000000000..29f48e812f --- /dev/null +++ b/tests/components/ens160/test.rp2040.yaml @@ -0,0 +1,13 @@ +i2c: + - id: i2c_ens160 + scl: 5 + sda: 4 + +sensor: + - platform: ens160 + eco2: + name: ENS160 eCO2 + tvoc: + name: ENS160 Total Volatile Organic Compounds + aqi: + name: ENS160 Air Quality Index diff --git a/tests/components/ens210/test.esp32-c3-idf.yaml b/tests/components/ens210/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..bacb71f9f8 --- /dev/null +++ b/tests/components/ens210/test.esp32-c3-idf.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_ens210 + scl: 5 + sda: 4 + +sensor: + - platform: ens210 + temperature: + name: ENS210 Temperature + humidity: + name: ENS210 Humidity + update_interval: 15s diff --git a/tests/components/ens210/test.esp32-c3.yaml b/tests/components/ens210/test.esp32-c3.yaml new file mode 100644 index 0000000000..bacb71f9f8 --- /dev/null +++ b/tests/components/ens210/test.esp32-c3.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_ens210 + scl: 5 + sda: 4 + +sensor: + - platform: ens210 + temperature: + name: ENS210 Temperature + humidity: + name: ENS210 Humidity + update_interval: 15s diff --git a/tests/components/ens210/test.esp32-idf.yaml b/tests/components/ens210/test.esp32-idf.yaml new file mode 100644 index 0000000000..8b2d29cc25 --- /dev/null +++ b/tests/components/ens210/test.esp32-idf.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_ens210 + scl: 16 + sda: 17 + +sensor: + - platform: ens210 + temperature: + name: ENS210 Temperature + humidity: + name: ENS210 Humidity + update_interval: 15s diff --git a/tests/components/ens210/test.esp32.yaml b/tests/components/ens210/test.esp32.yaml new file mode 100644 index 0000000000..8b2d29cc25 --- /dev/null +++ b/tests/components/ens210/test.esp32.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_ens210 + scl: 16 + sda: 17 + +sensor: + - platform: ens210 + temperature: + name: ENS210 Temperature + humidity: + name: ENS210 Humidity + update_interval: 15s diff --git a/tests/components/ens210/test.esp8266.yaml b/tests/components/ens210/test.esp8266.yaml new file mode 100644 index 0000000000..bacb71f9f8 --- /dev/null +++ b/tests/components/ens210/test.esp8266.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_ens210 + scl: 5 + sda: 4 + +sensor: + - platform: ens210 + temperature: + name: ENS210 Temperature + humidity: + name: ENS210 Humidity + update_interval: 15s diff --git a/tests/components/ens210/test.rp2040.yaml b/tests/components/ens210/test.rp2040.yaml new file mode 100644 index 0000000000..bacb71f9f8 --- /dev/null +++ b/tests/components/ens210/test.rp2040.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_ens210 + scl: 5 + sda: 4 + +sensor: + - platform: ens210 + temperature: + name: ENS210 Temperature + humidity: + name: ENS210 Humidity + update_interval: 15s diff --git a/tests/components/esp32_ble/test.esp32-c3-idf.yaml b/tests/components/esp32_ble/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..76b35fc8f8 --- /dev/null +++ b/tests/components/esp32_ble/test.esp32-c3-idf.yaml @@ -0,0 +1,2 @@ +esp32_ble: + io_capability: keyboard_only diff --git a/tests/components/esp32_ble/test.esp32-c3.yaml b/tests/components/esp32_ble/test.esp32-c3.yaml new file mode 100644 index 0000000000..76b35fc8f8 --- /dev/null +++ b/tests/components/esp32_ble/test.esp32-c3.yaml @@ -0,0 +1,2 @@ +esp32_ble: + io_capability: keyboard_only diff --git a/tests/components/esp32_ble/test.esp32-idf.yaml b/tests/components/esp32_ble/test.esp32-idf.yaml new file mode 100644 index 0000000000..76b35fc8f8 --- /dev/null +++ b/tests/components/esp32_ble/test.esp32-idf.yaml @@ -0,0 +1,2 @@ +esp32_ble: + io_capability: keyboard_only diff --git a/tests/components/esp32_ble/test.esp32.yaml b/tests/components/esp32_ble/test.esp32.yaml new file mode 100644 index 0000000000..76b35fc8f8 --- /dev/null +++ b/tests/components/esp32_ble/test.esp32.yaml @@ -0,0 +1,2 @@ +esp32_ble: + io_capability: keyboard_only diff --git a/tests/components/esp32_ble_beacon/test.esp32-c3-idf.yaml b/tests/components/esp32_ble_beacon/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..aafb0341d7 --- /dev/null +++ b/tests/components/esp32_ble_beacon/test.esp32-c3-idf.yaml @@ -0,0 +1,3 @@ +esp32_ble_beacon: + type: iBeacon + uuid: 'c29ce823-e67a-4e71-bff2-abaa32e77a98' diff --git a/tests/components/esp32_ble_beacon/test.esp32-c3.yaml b/tests/components/esp32_ble_beacon/test.esp32-c3.yaml new file mode 100644 index 0000000000..aafb0341d7 --- /dev/null +++ b/tests/components/esp32_ble_beacon/test.esp32-c3.yaml @@ -0,0 +1,3 @@ +esp32_ble_beacon: + type: iBeacon + uuid: 'c29ce823-e67a-4e71-bff2-abaa32e77a98' diff --git a/tests/components/esp32_ble_beacon/test.esp32-idf.yaml b/tests/components/esp32_ble_beacon/test.esp32-idf.yaml new file mode 100644 index 0000000000..aafb0341d7 --- /dev/null +++ b/tests/components/esp32_ble_beacon/test.esp32-idf.yaml @@ -0,0 +1,3 @@ +esp32_ble_beacon: + type: iBeacon + uuid: 'c29ce823-e67a-4e71-bff2-abaa32e77a98' diff --git a/tests/components/esp32_ble_beacon/test.esp32.yaml b/tests/components/esp32_ble_beacon/test.esp32.yaml new file mode 100644 index 0000000000..aafb0341d7 --- /dev/null +++ b/tests/components/esp32_ble_beacon/test.esp32.yaml @@ -0,0 +1,3 @@ +esp32_ble_beacon: + type: iBeacon + uuid: 'c29ce823-e67a-4e71-bff2-abaa32e77a98' diff --git a/tests/components/esp32_ble_client/test.esp32-c3-idf.yaml b/tests/components/esp32_ble_client/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..33b7205bf2 --- /dev/null +++ b/tests/components/esp32_ble_client/test.esp32-c3-idf.yaml @@ -0,0 +1,5 @@ +esp32_ble_tracker: + +ble_client: + - mac_address: 01:02:03:04:05:06 + id: blec diff --git a/tests/components/esp32_ble_client/test.esp32-c3.yaml b/tests/components/esp32_ble_client/test.esp32-c3.yaml new file mode 100644 index 0000000000..33b7205bf2 --- /dev/null +++ b/tests/components/esp32_ble_client/test.esp32-c3.yaml @@ -0,0 +1,5 @@ +esp32_ble_tracker: + +ble_client: + - mac_address: 01:02:03:04:05:06 + id: blec diff --git a/tests/components/esp32_ble_client/test.esp32-idf.yaml b/tests/components/esp32_ble_client/test.esp32-idf.yaml new file mode 100644 index 0000000000..33b7205bf2 --- /dev/null +++ b/tests/components/esp32_ble_client/test.esp32-idf.yaml @@ -0,0 +1,5 @@ +esp32_ble_tracker: + +ble_client: + - mac_address: 01:02:03:04:05:06 + id: blec diff --git a/tests/components/esp32_ble_client/test.esp32.yaml b/tests/components/esp32_ble_client/test.esp32.yaml new file mode 100644 index 0000000000..33b7205bf2 --- /dev/null +++ b/tests/components/esp32_ble_client/test.esp32.yaml @@ -0,0 +1,5 @@ +esp32_ble_tracker: + +ble_client: + - mac_address: 01:02:03:04:05:06 + id: blec diff --git a/tests/components/esp32_ble_server/test.esp32-c3-idf.yaml b/tests/components/esp32_ble_server/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..29a5407f84 --- /dev/null +++ b/tests/components/esp32_ble_server/test.esp32-c3-idf.yaml @@ -0,0 +1,3 @@ +esp32_ble_server: + id: ble + manufacturer_data: [0x72, 0x4, 0x00, 0x23] diff --git a/tests/components/esp32_ble_server/test.esp32-c3.yaml b/tests/components/esp32_ble_server/test.esp32-c3.yaml new file mode 100644 index 0000000000..29a5407f84 --- /dev/null +++ b/tests/components/esp32_ble_server/test.esp32-c3.yaml @@ -0,0 +1,3 @@ +esp32_ble_server: + id: ble + manufacturer_data: [0x72, 0x4, 0x00, 0x23] diff --git a/tests/components/esp32_ble_server/test.esp32-idf.yaml b/tests/components/esp32_ble_server/test.esp32-idf.yaml new file mode 100644 index 0000000000..29a5407f84 --- /dev/null +++ b/tests/components/esp32_ble_server/test.esp32-idf.yaml @@ -0,0 +1,3 @@ +esp32_ble_server: + id: ble + manufacturer_data: [0x72, 0x4, 0x00, 0x23] diff --git a/tests/components/esp32_ble_server/test.esp32.yaml b/tests/components/esp32_ble_server/test.esp32.yaml new file mode 100644 index 0000000000..29a5407f84 --- /dev/null +++ b/tests/components/esp32_ble_server/test.esp32.yaml @@ -0,0 +1,3 @@ +esp32_ble_server: + id: ble + manufacturer_data: [0x72, 0x4, 0x00, 0x23] diff --git a/tests/components/esp32_ble_tracker/test.esp32-c3-idf.yaml b/tests/components/esp32_ble_tracker/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..ef23635c9e --- /dev/null +++ b/tests/components/esp32_ble_tracker/test.esp32-c3-idf.yaml @@ -0,0 +1,41 @@ +esphome: + on_boot: + then: + - esp32_ble_tracker.start_scan + - esp32_ble_tracker.stop_scan + +esp32_ble_tracker: + on_ble_advertise: + - mac_address: + - AA:BB:CC:DD:EE:FF + - FF:EE:DD:CC:BB:AA + then: + # yamllint disable rule:line-length + - lambda: !lambda |- + ESP_LOGD("main", "The device address (%s) exists in list", x.address_str().c_str()); + # yamllint enable rule:line-length + - mac_address: AC:37:43:77:5F:4C + then: + # yamllint disable rule:line-length + - lambda: !lambda |- + ESP_LOGD("main", "The device address is %s", x.address_str().c_str()); + # yamllint enable rule:line-length + - then: + # yamllint disable rule:line-length + - lambda: !lambda |- + ESP_LOGD("main", "The device address is %s", x.address_str().c_str()); + # yamllint enable rule:line-length + on_ble_service_data_advertise: + - service_uuid: ABCD + then: + - lambda: !lambda |- + ESP_LOGD("main", "Length of service data is %i", x.size()); + on_ble_manufacturer_data_advertise: + - manufacturer_id: ABCD + then: + - lambda: !lambda |- + ESP_LOGD("main", "Length of manufacturer data is %i", x.size()); + on_scan_end: + - then: + - lambda: |- + ESP_LOGD("ble_auto", "The scan has ended!"); diff --git a/tests/components/esp32_ble_tracker/test.esp32-c3.yaml b/tests/components/esp32_ble_tracker/test.esp32-c3.yaml new file mode 100644 index 0000000000..ef23635c9e --- /dev/null +++ b/tests/components/esp32_ble_tracker/test.esp32-c3.yaml @@ -0,0 +1,41 @@ +esphome: + on_boot: + then: + - esp32_ble_tracker.start_scan + - esp32_ble_tracker.stop_scan + +esp32_ble_tracker: + on_ble_advertise: + - mac_address: + - AA:BB:CC:DD:EE:FF + - FF:EE:DD:CC:BB:AA + then: + # yamllint disable rule:line-length + - lambda: !lambda |- + ESP_LOGD("main", "The device address (%s) exists in list", x.address_str().c_str()); + # yamllint enable rule:line-length + - mac_address: AC:37:43:77:5F:4C + then: + # yamllint disable rule:line-length + - lambda: !lambda |- + ESP_LOGD("main", "The device address is %s", x.address_str().c_str()); + # yamllint enable rule:line-length + - then: + # yamllint disable rule:line-length + - lambda: !lambda |- + ESP_LOGD("main", "The device address is %s", x.address_str().c_str()); + # yamllint enable rule:line-length + on_ble_service_data_advertise: + - service_uuid: ABCD + then: + - lambda: !lambda |- + ESP_LOGD("main", "Length of service data is %i", x.size()); + on_ble_manufacturer_data_advertise: + - manufacturer_id: ABCD + then: + - lambda: !lambda |- + ESP_LOGD("main", "Length of manufacturer data is %i", x.size()); + on_scan_end: + - then: + - lambda: |- + ESP_LOGD("ble_auto", "The scan has ended!"); diff --git a/tests/components/esp32_ble_tracker/test.esp32-idf.yaml b/tests/components/esp32_ble_tracker/test.esp32-idf.yaml new file mode 100644 index 0000000000..ef23635c9e --- /dev/null +++ b/tests/components/esp32_ble_tracker/test.esp32-idf.yaml @@ -0,0 +1,41 @@ +esphome: + on_boot: + then: + - esp32_ble_tracker.start_scan + - esp32_ble_tracker.stop_scan + +esp32_ble_tracker: + on_ble_advertise: + - mac_address: + - AA:BB:CC:DD:EE:FF + - FF:EE:DD:CC:BB:AA + then: + # yamllint disable rule:line-length + - lambda: !lambda |- + ESP_LOGD("main", "The device address (%s) exists in list", x.address_str().c_str()); + # yamllint enable rule:line-length + - mac_address: AC:37:43:77:5F:4C + then: + # yamllint disable rule:line-length + - lambda: !lambda |- + ESP_LOGD("main", "The device address is %s", x.address_str().c_str()); + # yamllint enable rule:line-length + - then: + # yamllint disable rule:line-length + - lambda: !lambda |- + ESP_LOGD("main", "The device address is %s", x.address_str().c_str()); + # yamllint enable rule:line-length + on_ble_service_data_advertise: + - service_uuid: ABCD + then: + - lambda: !lambda |- + ESP_LOGD("main", "Length of service data is %i", x.size()); + on_ble_manufacturer_data_advertise: + - manufacturer_id: ABCD + then: + - lambda: !lambda |- + ESP_LOGD("main", "Length of manufacturer data is %i", x.size()); + on_scan_end: + - then: + - lambda: |- + ESP_LOGD("ble_auto", "The scan has ended!"); diff --git a/tests/components/esp32_ble_tracker/test.esp32.yaml b/tests/components/esp32_ble_tracker/test.esp32.yaml new file mode 100644 index 0000000000..ef23635c9e --- /dev/null +++ b/tests/components/esp32_ble_tracker/test.esp32.yaml @@ -0,0 +1,41 @@ +esphome: + on_boot: + then: + - esp32_ble_tracker.start_scan + - esp32_ble_tracker.stop_scan + +esp32_ble_tracker: + on_ble_advertise: + - mac_address: + - AA:BB:CC:DD:EE:FF + - FF:EE:DD:CC:BB:AA + then: + # yamllint disable rule:line-length + - lambda: !lambda |- + ESP_LOGD("main", "The device address (%s) exists in list", x.address_str().c_str()); + # yamllint enable rule:line-length + - mac_address: AC:37:43:77:5F:4C + then: + # yamllint disable rule:line-length + - lambda: !lambda |- + ESP_LOGD("main", "The device address is %s", x.address_str().c_str()); + # yamllint enable rule:line-length + - then: + # yamllint disable rule:line-length + - lambda: !lambda |- + ESP_LOGD("main", "The device address is %s", x.address_str().c_str()); + # yamllint enable rule:line-length + on_ble_service_data_advertise: + - service_uuid: ABCD + then: + - lambda: !lambda |- + ESP_LOGD("main", "Length of service data is %i", x.size()); + on_ble_manufacturer_data_advertise: + - manufacturer_id: ABCD + then: + - lambda: !lambda |- + ESP_LOGD("main", "Length of manufacturer data is %i", x.size()); + on_scan_end: + - then: + - lambda: |- + ESP_LOGD("ble_auto", "The scan has ended!"); diff --git a/tests/components/esp32_camera/test.esp32-idf.yaml b/tests/components/esp32_camera/test.esp32-idf.yaml new file mode 100644 index 0000000000..366f601657 --- /dev/null +++ b/tests/components/esp32_camera/test.esp32-idf.yaml @@ -0,0 +1,28 @@ +esp32_camera: + name: ESP32 Camera + data_pins: + - number: 17 + - number: 35 + - number: 34 + - number: 5 + - number: 39 + - number: 18 + - number: 36 + - number: 19 + vsync_pin: 22 + href_pin: 26 + pixel_clock_pin: 21 + external_clock: + pin: 27 + frequency: 20MHz + i2c_pins: + sda: 25 + scl: 23 + reset_pin: 15 + power_down_pin: 1 + resolution: 640x480 + jpeg_quality: 10 + on_image: + then: + - lambda: |- + ESP_LOGD("main", "image len=%d, data=%c", image.length, image.data[0]); diff --git a/tests/components/esp32_camera/test.esp32.yaml b/tests/components/esp32_camera/test.esp32.yaml new file mode 100644 index 0000000000..366f601657 --- /dev/null +++ b/tests/components/esp32_camera/test.esp32.yaml @@ -0,0 +1,28 @@ +esp32_camera: + name: ESP32 Camera + data_pins: + - number: 17 + - number: 35 + - number: 34 + - number: 5 + - number: 39 + - number: 18 + - number: 36 + - number: 19 + vsync_pin: 22 + href_pin: 26 + pixel_clock_pin: 21 + external_clock: + pin: 27 + frequency: 20MHz + i2c_pins: + sda: 25 + scl: 23 + reset_pin: 15 + power_down_pin: 1 + resolution: 640x480 + jpeg_quality: 10 + on_image: + then: + - lambda: |- + ESP_LOGD("main", "image len=%d, data=%c", image.length, image.data[0]); diff --git a/tests/components/esp32_camera_web_server/test.esp32-idf.yaml b/tests/components/esp32_camera_web_server/test.esp32-idf.yaml new file mode 100644 index 0000000000..14b7bd5c34 --- /dev/null +++ b/tests/components/esp32_camera_web_server/test.esp32-idf.yaml @@ -0,0 +1,34 @@ +esp32_camera: + name: ESP32 Camera + data_pins: + - number: 17 + - number: 35 + - number: 34 + - number: 5 + - number: 39 + - number: 18 + - number: 36 + - number: 19 + vsync_pin: 22 + href_pin: 26 + pixel_clock_pin: 21 + external_clock: + pin: 27 + frequency: 20MHz + i2c_pins: + sda: 25 + scl: 23 + reset_pin: 15 + power_down_pin: 1 + resolution: 640x480 + jpeg_quality: 10 + on_image: + then: + - lambda: |- + ESP_LOGD("main", "image len=%d, data=%c", image.length, image.data[0]); + +esp32_camera_web_server: + - port: 8080 + mode: stream + - port: 8081 + mode: snapshot diff --git a/tests/components/esp32_camera_web_server/test.esp32.yaml b/tests/components/esp32_camera_web_server/test.esp32.yaml new file mode 100644 index 0000000000..14b7bd5c34 --- /dev/null +++ b/tests/components/esp32_camera_web_server/test.esp32.yaml @@ -0,0 +1,34 @@ +esp32_camera: + name: ESP32 Camera + data_pins: + - number: 17 + - number: 35 + - number: 34 + - number: 5 + - number: 39 + - number: 18 + - number: 36 + - number: 19 + vsync_pin: 22 + href_pin: 26 + pixel_clock_pin: 21 + external_clock: + pin: 27 + frequency: 20MHz + i2c_pins: + sda: 25 + scl: 23 + reset_pin: 15 + power_down_pin: 1 + resolution: 640x480 + jpeg_quality: 10 + on_image: + then: + - lambda: |- + ESP_LOGD("main", "image len=%d, data=%c", image.length, image.data[0]); + +esp32_camera_web_server: + - port: 8080 + mode: stream + - port: 8081 + mode: snapshot diff --git a/tests/components/esp32_can/test.esp32-c3-idf.yaml b/tests/components/esp32_can/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..b4fd34cf51 --- /dev/null +++ b/tests/components/esp32_can/test.esp32-c3-idf.yaml @@ -0,0 +1,45 @@ +esphome: + on_boot: + then: + - canbus.send: + # Extended ID explicit + use_extended_id: true + can_id: 0x100 + data: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08] + - canbus.send: + # Standard ID by default + can_id: 0x100 + data: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08] + +canbus: + - platform: esp32_can + id: esp32_internal_can + rx_pin: 4 + tx_pin: 5 + can_id: 4 + bit_rate: 50kbps + on_frame: + - can_id: 500 + then: + - lambda: |- + std::string b(x.begin(), x.end()); + ESP_LOGD("canid 500", "%s", b.c_str() ); + - can_id: 0b00000000000000000000001000000 + can_id_mask: 0b11111000000000011111111000000 + use_extended_id: true + then: + - lambda: |- + auto pdo_id = can_id >> 14; + switch (pdo_id) + { + case 117: + ESP_LOGD("canbus", "exhaust_fan_duty"); + break; + case 118: + ESP_LOGD("canbus", "supply_fan_duty"); + break; + case 119: + ESP_LOGD("canbus", "supply_fan_flow"); + break; + // to be continued... + } diff --git a/tests/components/esp32_can/test.esp32-c3.yaml b/tests/components/esp32_can/test.esp32-c3.yaml new file mode 100644 index 0000000000..b4fd34cf51 --- /dev/null +++ b/tests/components/esp32_can/test.esp32-c3.yaml @@ -0,0 +1,45 @@ +esphome: + on_boot: + then: + - canbus.send: + # Extended ID explicit + use_extended_id: true + can_id: 0x100 + data: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08] + - canbus.send: + # Standard ID by default + can_id: 0x100 + data: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08] + +canbus: + - platform: esp32_can + id: esp32_internal_can + rx_pin: 4 + tx_pin: 5 + can_id: 4 + bit_rate: 50kbps + on_frame: + - can_id: 500 + then: + - lambda: |- + std::string b(x.begin(), x.end()); + ESP_LOGD("canid 500", "%s", b.c_str() ); + - can_id: 0b00000000000000000000001000000 + can_id_mask: 0b11111000000000011111111000000 + use_extended_id: true + then: + - lambda: |- + auto pdo_id = can_id >> 14; + switch (pdo_id) + { + case 117: + ESP_LOGD("canbus", "exhaust_fan_duty"); + break; + case 118: + ESP_LOGD("canbus", "supply_fan_duty"); + break; + case 119: + ESP_LOGD("canbus", "supply_fan_flow"); + break; + // to be continued... + } diff --git a/tests/components/esp32_can/test.esp32-idf.yaml b/tests/components/esp32_can/test.esp32-idf.yaml new file mode 100644 index 0000000000..159a695853 --- /dev/null +++ b/tests/components/esp32_can/test.esp32-idf.yaml @@ -0,0 +1,45 @@ +esphome: + on_boot: + then: + - canbus.send: + # Extended ID explicit + use_extended_id: true + can_id: 0x100 + data: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08] + - canbus.send: + # Standard ID by default + can_id: 0x100 + data: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08] + +canbus: + - platform: esp32_can + id: esp32_internal_can + rx_pin: 13 + tx_pin: 14 + can_id: 4 + bit_rate: 50kbps + on_frame: + - can_id: 500 + then: + - lambda: |- + std::string b(x.begin(), x.end()); + ESP_LOGD("canid 500", "%s", b.c_str() ); + - can_id: 0b00000000000000000000001000000 + can_id_mask: 0b11111000000000011111111000000 + use_extended_id: true + then: + - lambda: |- + auto pdo_id = can_id >> 14; + switch (pdo_id) + { + case 117: + ESP_LOGD("canbus", "exhaust_fan_duty"); + break; + case 118: + ESP_LOGD("canbus", "supply_fan_duty"); + break; + case 119: + ESP_LOGD("canbus", "supply_fan_flow"); + break; + // to be continued... + } diff --git a/tests/components/esp32_can/test.esp32.yaml b/tests/components/esp32_can/test.esp32.yaml new file mode 100644 index 0000000000..159a695853 --- /dev/null +++ b/tests/components/esp32_can/test.esp32.yaml @@ -0,0 +1,45 @@ +esphome: + on_boot: + then: + - canbus.send: + # Extended ID explicit + use_extended_id: true + can_id: 0x100 + data: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08] + - canbus.send: + # Standard ID by default + can_id: 0x100 + data: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08] + +canbus: + - platform: esp32_can + id: esp32_internal_can + rx_pin: 13 + tx_pin: 14 + can_id: 4 + bit_rate: 50kbps + on_frame: + - can_id: 500 + then: + - lambda: |- + std::string b(x.begin(), x.end()); + ESP_LOGD("canid 500", "%s", b.c_str() ); + - can_id: 0b00000000000000000000001000000 + can_id_mask: 0b11111000000000011111111000000 + use_extended_id: true + then: + - lambda: |- + auto pdo_id = can_id >> 14; + switch (pdo_id) + { + case 117: + ESP_LOGD("canbus", "exhaust_fan_duty"); + break; + case 118: + ESP_LOGD("canbus", "supply_fan_duty"); + break; + case 119: + ESP_LOGD("canbus", "supply_fan_flow"); + break; + // to be continued... + } diff --git a/tests/components/esp32_dac/test.esp32-idf.yaml b/tests/components/esp32_dac/test.esp32-idf.yaml new file mode 100644 index 0000000000..225627f5af --- /dev/null +++ b/tests/components/esp32_dac/test.esp32-idf.yaml @@ -0,0 +1,4 @@ +output: + - platform: esp32_dac + id: dac_output + pin: 25 diff --git a/tests/components/esp32_dac/test.esp32.yaml b/tests/components/esp32_dac/test.esp32.yaml new file mode 100644 index 0000000000..225627f5af --- /dev/null +++ b/tests/components/esp32_dac/test.esp32.yaml @@ -0,0 +1,4 @@ +output: + - platform: esp32_dac + id: dac_output + pin: 25 diff --git a/tests/components/esp32_hall/test.esp32-idf.yaml b/tests/components/esp32_hall/test.esp32-idf.yaml new file mode 100644 index 0000000000..f8429f5aa0 --- /dev/null +++ b/tests/components/esp32_hall/test.esp32-idf.yaml @@ -0,0 +1,3 @@ +sensor: + - platform: esp32_hall + name: ESP32 Hall Sensor diff --git a/tests/components/esp32_hall/test.esp32.yaml b/tests/components/esp32_hall/test.esp32.yaml new file mode 100644 index 0000000000..f8429f5aa0 --- /dev/null +++ b/tests/components/esp32_hall/test.esp32.yaml @@ -0,0 +1,3 @@ +sensor: + - platform: esp32_hall + name: ESP32 Hall Sensor diff --git a/tests/components/esp32_improv/test.esp32-c3-idf.yaml b/tests/components/esp32_improv/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..7eb3f9c0be --- /dev/null +++ b/tests/components/esp32_improv/test.esp32-c3-idf.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +binary_sensor: + - platform: gpio + pin: 0 + id: io0_button + +output: + - platform: gpio + pin: 2 + id: built_in_led + +esp32_improv: + authorizer: io0_button + authorized_duration: 1min + status_indicator: built_in_led diff --git a/tests/components/esp32_improv/test.esp32-c3.yaml b/tests/components/esp32_improv/test.esp32-c3.yaml new file mode 100644 index 0000000000..7eb3f9c0be --- /dev/null +++ b/tests/components/esp32_improv/test.esp32-c3.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +binary_sensor: + - platform: gpio + pin: 0 + id: io0_button + +output: + - platform: gpio + pin: 2 + id: built_in_led + +esp32_improv: + authorizer: io0_button + authorized_duration: 1min + status_indicator: built_in_led diff --git a/tests/components/esp32_improv/test.esp32-idf.yaml b/tests/components/esp32_improv/test.esp32-idf.yaml new file mode 100644 index 0000000000..7eb3f9c0be --- /dev/null +++ b/tests/components/esp32_improv/test.esp32-idf.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +binary_sensor: + - platform: gpio + pin: 0 + id: io0_button + +output: + - platform: gpio + pin: 2 + id: built_in_led + +esp32_improv: + authorizer: io0_button + authorized_duration: 1min + status_indicator: built_in_led diff --git a/tests/components/esp32_improv/test.esp32.yaml b/tests/components/esp32_improv/test.esp32.yaml new file mode 100644 index 0000000000..7eb3f9c0be --- /dev/null +++ b/tests/components/esp32_improv/test.esp32.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +binary_sensor: + - platform: gpio + pin: 0 + id: io0_button + +output: + - platform: gpio + pin: 2 + id: built_in_led + +esp32_improv: + authorizer: io0_button + authorized_duration: 1min + status_indicator: built_in_led diff --git a/tests/components/esp32_rmt_led_strip/test.esp32-c3-idf.yaml b/tests/components/esp32_rmt_led_strip/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..b226d1de06 --- /dev/null +++ b/tests/components/esp32_rmt_led_strip/test.esp32-c3-idf.yaml @@ -0,0 +1,18 @@ +light: + - platform: esp32_rmt_led_strip + id: led_strip + pin: 4 + num_leds: 60 + rmt_channel: 0 + rgb_order: GRB + chipset: ws2812 + - platform: esp32_rmt_led_strip + id: led_strip2 + pin: 5 + num_leds: 60 + rmt_channel: 1 + rgb_order: RGB + bit0_high: 100us + bit0_low: 100us + bit1_high: 100us + bit1_low: 100us diff --git a/tests/components/esp32_rmt_led_strip/test.esp32-c3.yaml b/tests/components/esp32_rmt_led_strip/test.esp32-c3.yaml new file mode 100644 index 0000000000..b226d1de06 --- /dev/null +++ b/tests/components/esp32_rmt_led_strip/test.esp32-c3.yaml @@ -0,0 +1,18 @@ +light: + - platform: esp32_rmt_led_strip + id: led_strip + pin: 4 + num_leds: 60 + rmt_channel: 0 + rgb_order: GRB + chipset: ws2812 + - platform: esp32_rmt_led_strip + id: led_strip2 + pin: 5 + num_leds: 60 + rmt_channel: 1 + rgb_order: RGB + bit0_high: 100us + bit0_low: 100us + bit1_high: 100us + bit1_low: 100us diff --git a/tests/components/esp32_rmt_led_strip/test.esp32-idf.yaml b/tests/components/esp32_rmt_led_strip/test.esp32-idf.yaml new file mode 100644 index 0000000000..d51a66451f --- /dev/null +++ b/tests/components/esp32_rmt_led_strip/test.esp32-idf.yaml @@ -0,0 +1,18 @@ +light: + - platform: esp32_rmt_led_strip + id: led_strip + pin: 13 + num_leds: 60 + rmt_channel: 6 + rgb_order: GRB + chipset: ws2812 + - platform: esp32_rmt_led_strip + id: led_strip2 + pin: 14 + num_leds: 60 + rmt_channel: 2 + rgb_order: RGB + bit0_high: 100us + bit0_low: 100us + bit1_high: 100us + bit1_low: 100us diff --git a/tests/components/esp32_rmt_led_strip/test.esp32.yaml b/tests/components/esp32_rmt_led_strip/test.esp32.yaml new file mode 100644 index 0000000000..d51a66451f --- /dev/null +++ b/tests/components/esp32_rmt_led_strip/test.esp32.yaml @@ -0,0 +1,18 @@ +light: + - platform: esp32_rmt_led_strip + id: led_strip + pin: 13 + num_leds: 60 + rmt_channel: 6 + rgb_order: GRB + chipset: ws2812 + - platform: esp32_rmt_led_strip + id: led_strip2 + pin: 14 + num_leds: 60 + rmt_channel: 2 + rgb_order: RGB + bit0_high: 100us + bit0_low: 100us + bit1_high: 100us + bit1_low: 100us diff --git a/tests/components/esp32_touch/test.esp32-idf.yaml b/tests/components/esp32_touch/test.esp32-idf.yaml new file mode 100644 index 0000000000..691cce8d86 --- /dev/null +++ b/tests/components/esp32_touch/test.esp32-idf.yaml @@ -0,0 +1,16 @@ +esp32_touch: + setup_mode: false + iir_filter: 10ms + sleep_duration: 27ms + measurement_duration: 8ms + low_voltage_reference: 0.5V + high_voltage_reference: 2.7V + voltage_attenuation: 1.5V + +binary_sensor: + - platform: esp32_touch + name: ESP32 Touch Pad + pin: 27 + threshold: 1000 + on_press: + - logger.log: "I'm touched!" diff --git a/tests/components/esp32_touch/test.esp32.yaml b/tests/components/esp32_touch/test.esp32.yaml new file mode 100644 index 0000000000..691cce8d86 --- /dev/null +++ b/tests/components/esp32_touch/test.esp32.yaml @@ -0,0 +1,16 @@ +esp32_touch: + setup_mode: false + iir_filter: 10ms + sleep_duration: 27ms + measurement_duration: 8ms + low_voltage_reference: 0.5V + high_voltage_reference: 2.7V + voltage_attenuation: 1.5V + +binary_sensor: + - platform: esp32_touch + name: ESP32 Touch Pad + pin: 27 + threshold: 1000 + on_press: + - logger.log: "I'm touched!" diff --git a/tests/components/esp8266_pwm/test.esp8266.yaml b/tests/components/esp8266_pwm/test.esp8266.yaml new file mode 100644 index 0000000000..52b290f91b --- /dev/null +++ b/tests/components/esp8266_pwm/test.esp8266.yaml @@ -0,0 +1,8 @@ +output: + - platform: esp8266_pwm + id: out + pin: 4 + frequency: 50Hz + - platform: esp8266_pwm + id: out2 + pin: 5 diff --git a/tests/components/ethernet/test.esp32-idf.yaml b/tests/components/ethernet/test.esp32-idf.yaml new file mode 100644 index 0000000000..b9ed9cb036 --- /dev/null +++ b/tests/components/ethernet/test.esp32-idf.yaml @@ -0,0 +1,12 @@ +ethernet: + type: LAN8720 + mdc_pin: 23 + mdio_pin: 25 + clk_mode: GPIO0_IN + phy_addr: 0 + power_pin: 26 + manual_ip: + static_ip: 192.168.178.56 + gateway: 192.168.178.1 + subnet: 255.255.255.0 + domain: .local diff --git a/tests/components/ethernet/test.esp32.yaml b/tests/components/ethernet/test.esp32.yaml new file mode 100644 index 0000000000..b9ed9cb036 --- /dev/null +++ b/tests/components/ethernet/test.esp32.yaml @@ -0,0 +1,12 @@ +ethernet: + type: LAN8720 + mdc_pin: 23 + mdio_pin: 25 + clk_mode: GPIO0_IN + phy_addr: 0 + power_pin: 26 + manual_ip: + static_ip: 192.168.178.56 + gateway: 192.168.178.1 + subnet: 255.255.255.0 + domain: .local diff --git a/tests/components/ethernet_info/test.esp32-idf.yaml b/tests/components/ethernet_info/test.esp32-idf.yaml new file mode 100644 index 0000000000..c5da2bb666 --- /dev/null +++ b/tests/components/ethernet_info/test.esp32-idf.yaml @@ -0,0 +1,17 @@ +ethernet: + type: LAN8720 + mdc_pin: 23 + mdio_pin: 25 + clk_mode: GPIO0_IN + phy_addr: 0 + power_pin: 26 + manual_ip: + static_ip: 192.168.178.56 + gateway: 192.168.178.1 + subnet: 255.255.255.0 + domain: .local + +text_sensor: + - platform: ethernet_info + ip_address: + name: IP Address diff --git a/tests/components/ethernet_info/test.esp32.yaml b/tests/components/ethernet_info/test.esp32.yaml new file mode 100644 index 0000000000..c5da2bb666 --- /dev/null +++ b/tests/components/ethernet_info/test.esp32.yaml @@ -0,0 +1,17 @@ +ethernet: + type: LAN8720 + mdc_pin: 23 + mdio_pin: 25 + clk_mode: GPIO0_IN + phy_addr: 0 + power_pin: 26 + manual_ip: + static_ip: 192.168.178.56 + gateway: 192.168.178.1 + subnet: 255.255.255.0 + domain: .local + +text_sensor: + - platform: ethernet_info + ip_address: + name: IP Address diff --git a/tests/components/exposure_notifications/test.esp32-c3-idf.yaml b/tests/components/exposure_notifications/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..faba5bb2d1 --- /dev/null +++ b/tests/components/exposure_notifications/test.esp32-c3-idf.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +exposure_notifications: + on_exposure_notification: + then: + - lambda: | + ESP_LOGD("main", "Got notification:"); + ESP_LOGD("main", " RPI: %s", format_hex(x.rolling_proximity_identifier).c_str()); + ESP_LOGD("main", " RSSI: %d", x.rssi); diff --git a/tests/components/exposure_notifications/test.esp32-c3.yaml b/tests/components/exposure_notifications/test.esp32-c3.yaml new file mode 100644 index 0000000000..faba5bb2d1 --- /dev/null +++ b/tests/components/exposure_notifications/test.esp32-c3.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +exposure_notifications: + on_exposure_notification: + then: + - lambda: | + ESP_LOGD("main", "Got notification:"); + ESP_LOGD("main", " RPI: %s", format_hex(x.rolling_proximity_identifier).c_str()); + ESP_LOGD("main", " RSSI: %d", x.rssi); diff --git a/tests/components/exposure_notifications/test.esp32-idf.yaml b/tests/components/exposure_notifications/test.esp32-idf.yaml new file mode 100644 index 0000000000..faba5bb2d1 --- /dev/null +++ b/tests/components/exposure_notifications/test.esp32-idf.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +exposure_notifications: + on_exposure_notification: + then: + - lambda: | + ESP_LOGD("main", "Got notification:"); + ESP_LOGD("main", " RPI: %s", format_hex(x.rolling_proximity_identifier).c_str()); + ESP_LOGD("main", " RSSI: %d", x.rssi); diff --git a/tests/components/exposure_notifications/test.esp32.yaml b/tests/components/exposure_notifications/test.esp32.yaml new file mode 100644 index 0000000000..faba5bb2d1 --- /dev/null +++ b/tests/components/exposure_notifications/test.esp32.yaml @@ -0,0 +1,9 @@ +esp32_ble_tracker: + +exposure_notifications: + on_exposure_notification: + then: + - lambda: | + ESP_LOGD("main", "Got notification:"); + ESP_LOGD("main", " RPI: %s", format_hex(x.rolling_proximity_identifier).c_str()); + ESP_LOGD("main", " RSSI: %d", x.rssi); diff --git a/tests/components/external_components/test.esp32-c3-idf.yaml b/tests/components/external_components/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..2b51267ec6 --- /dev/null +++ b/tests/components/external_components/test.esp32-c3-idf.yaml @@ -0,0 +1,6 @@ +external_components: + - source: github://esphome/esphome@dev + refresh: 1d + components: [bh1750] + - source: ../../../esphome/components + components: [sntp] diff --git a/tests/components/external_components/test.esp32-c3.yaml b/tests/components/external_components/test.esp32-c3.yaml new file mode 100644 index 0000000000..2b51267ec6 --- /dev/null +++ b/tests/components/external_components/test.esp32-c3.yaml @@ -0,0 +1,6 @@ +external_components: + - source: github://esphome/esphome@dev + refresh: 1d + components: [bh1750] + - source: ../../../esphome/components + components: [sntp] diff --git a/tests/components/external_components/test.esp32-idf.yaml b/tests/components/external_components/test.esp32-idf.yaml new file mode 100644 index 0000000000..2b51267ec6 --- /dev/null +++ b/tests/components/external_components/test.esp32-idf.yaml @@ -0,0 +1,6 @@ +external_components: + - source: github://esphome/esphome@dev + refresh: 1d + components: [bh1750] + - source: ../../../esphome/components + components: [sntp] diff --git a/tests/components/external_components/test.esp32.yaml b/tests/components/external_components/test.esp32.yaml new file mode 100644 index 0000000000..2b51267ec6 --- /dev/null +++ b/tests/components/external_components/test.esp32.yaml @@ -0,0 +1,6 @@ +external_components: + - source: github://esphome/esphome@dev + refresh: 1d + components: [bh1750] + - source: ../../../esphome/components + components: [sntp] diff --git a/tests/components/external_components/test.esp8266.yaml b/tests/components/external_components/test.esp8266.yaml new file mode 100644 index 0000000000..2b51267ec6 --- /dev/null +++ b/tests/components/external_components/test.esp8266.yaml @@ -0,0 +1,6 @@ +external_components: + - source: github://esphome/esphome@dev + refresh: 1d + components: [bh1750] + - source: ../../../esphome/components + components: [sntp] diff --git a/tests/components/external_components/test.rp2040.yaml b/tests/components/external_components/test.rp2040.yaml new file mode 100644 index 0000000000..2b51267ec6 --- /dev/null +++ b/tests/components/external_components/test.rp2040.yaml @@ -0,0 +1,6 @@ +external_components: + - source: github://esphome/esphome@dev + refresh: 1d + components: [bh1750] + - source: ../../../esphome/components + components: [sntp] diff --git a/tests/components/ezo/test.esp32-c3-idf.yaml b/tests/components/ezo/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..93ceb9efd3 --- /dev/null +++ b/tests/components/ezo/test.esp32-c3-idf.yaml @@ -0,0 +1,10 @@ +i2c: + - id: i2c_ezo + scl: 5 + sda: 4 + +sensor: + - platform: ezo + id: ph_ezo + address: 99 + unit_of_measurement: pH diff --git a/tests/components/ezo/test.esp32-c3.yaml b/tests/components/ezo/test.esp32-c3.yaml new file mode 100644 index 0000000000..93ceb9efd3 --- /dev/null +++ b/tests/components/ezo/test.esp32-c3.yaml @@ -0,0 +1,10 @@ +i2c: + - id: i2c_ezo + scl: 5 + sda: 4 + +sensor: + - platform: ezo + id: ph_ezo + address: 99 + unit_of_measurement: pH diff --git a/tests/components/ezo/test.esp32-idf.yaml b/tests/components/ezo/test.esp32-idf.yaml new file mode 100644 index 0000000000..61a8d2b25f --- /dev/null +++ b/tests/components/ezo/test.esp32-idf.yaml @@ -0,0 +1,10 @@ +i2c: + - id: i2c_ezo + scl: 16 + sda: 17 + +sensor: + - platform: ezo + id: ph_ezo + address: 99 + unit_of_measurement: pH diff --git a/tests/components/ezo/test.esp32.yaml b/tests/components/ezo/test.esp32.yaml new file mode 100644 index 0000000000..61a8d2b25f --- /dev/null +++ b/tests/components/ezo/test.esp32.yaml @@ -0,0 +1,10 @@ +i2c: + - id: i2c_ezo + scl: 16 + sda: 17 + +sensor: + - platform: ezo + id: ph_ezo + address: 99 + unit_of_measurement: pH diff --git a/tests/components/ezo/test.esp8266.yaml b/tests/components/ezo/test.esp8266.yaml new file mode 100644 index 0000000000..93ceb9efd3 --- /dev/null +++ b/tests/components/ezo/test.esp8266.yaml @@ -0,0 +1,10 @@ +i2c: + - id: i2c_ezo + scl: 5 + sda: 4 + +sensor: + - platform: ezo + id: ph_ezo + address: 99 + unit_of_measurement: pH diff --git a/tests/components/ezo/test.rp2040.yaml b/tests/components/ezo/test.rp2040.yaml new file mode 100644 index 0000000000..93ceb9efd3 --- /dev/null +++ b/tests/components/ezo/test.rp2040.yaml @@ -0,0 +1,10 @@ +i2c: + - id: i2c_ezo + scl: 5 + sda: 4 + +sensor: + - platform: ezo + id: ph_ezo + address: 99 + unit_of_measurement: pH diff --git a/tests/components/ezo_pmp/test.esp32-c3-idf.yaml b/tests/components/ezo_pmp/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..fa047de3de --- /dev/null +++ b/tests/components/ezo_pmp/test.esp32-c3-idf.yaml @@ -0,0 +1,61 @@ +i2c: + - id: i2c_ezo_pmp + scl: 5 + sda: 4 + +ezo_pmp: + id: hcl_pump + update_interval: 1s + +binary_sensor: + - platform: ezo_pmp + pump_state: + name: Pump State + is_paused: + name: Is Paused + +sensor: + - platform: ezo_pmp + current_volume_dosed: + name: Current Volume Dosed + total_volume_dosed: + name: Total Volume Dosed + absolute_total_volume_dosed: + name: Absolute Total Volume Dosed + pump_voltage: + name: Pump Voltage + last_volume_requested: + name: Last Volume Requested + max_flow_rate: + name: Max Flow Rate + +text_sensor: + - platform: ezo_pmp + dosing_mode: + name: Dosing Mode + calibration_status: + name: Calibration Status + on_value: + - ezo_pmp.dose_volume: + id: hcl_pump + volume: 10 + - ezo_pmp.dose_volume_over_time: + id: hcl_pump + volume: 10 + duration: 2 + - ezo_pmp.dose_with_constant_flow_rate: + id: hcl_pump + volume_per_minute: 10 + duration: 2 + - ezo_pmp.set_calibration_volume: + id: hcl_pump + volume: 10 + - ezo_pmp.find: hcl_pump + - ezo_pmp.dose_continuously: hcl_pump + - ezo_pmp.clear_total_volume_dosed: hcl_pump + - ezo_pmp.clear_calibration: hcl_pump + - ezo_pmp.pause_dosing: hcl_pump + - ezo_pmp.stop_dosing: hcl_pump + - ezo_pmp.arbitrary_command: + id: hcl_pump + command: D,? diff --git a/tests/components/ezo_pmp/test.esp32-c3.yaml b/tests/components/ezo_pmp/test.esp32-c3.yaml new file mode 100644 index 0000000000..fa047de3de --- /dev/null +++ b/tests/components/ezo_pmp/test.esp32-c3.yaml @@ -0,0 +1,61 @@ +i2c: + - id: i2c_ezo_pmp + scl: 5 + sda: 4 + +ezo_pmp: + id: hcl_pump + update_interval: 1s + +binary_sensor: + - platform: ezo_pmp + pump_state: + name: Pump State + is_paused: + name: Is Paused + +sensor: + - platform: ezo_pmp + current_volume_dosed: + name: Current Volume Dosed + total_volume_dosed: + name: Total Volume Dosed + absolute_total_volume_dosed: + name: Absolute Total Volume Dosed + pump_voltage: + name: Pump Voltage + last_volume_requested: + name: Last Volume Requested + max_flow_rate: + name: Max Flow Rate + +text_sensor: + - platform: ezo_pmp + dosing_mode: + name: Dosing Mode + calibration_status: + name: Calibration Status + on_value: + - ezo_pmp.dose_volume: + id: hcl_pump + volume: 10 + - ezo_pmp.dose_volume_over_time: + id: hcl_pump + volume: 10 + duration: 2 + - ezo_pmp.dose_with_constant_flow_rate: + id: hcl_pump + volume_per_minute: 10 + duration: 2 + - ezo_pmp.set_calibration_volume: + id: hcl_pump + volume: 10 + - ezo_pmp.find: hcl_pump + - ezo_pmp.dose_continuously: hcl_pump + - ezo_pmp.clear_total_volume_dosed: hcl_pump + - ezo_pmp.clear_calibration: hcl_pump + - ezo_pmp.pause_dosing: hcl_pump + - ezo_pmp.stop_dosing: hcl_pump + - ezo_pmp.arbitrary_command: + id: hcl_pump + command: D,? diff --git a/tests/components/ezo_pmp/test.esp32-idf.yaml b/tests/components/ezo_pmp/test.esp32-idf.yaml new file mode 100644 index 0000000000..9fc929b365 --- /dev/null +++ b/tests/components/ezo_pmp/test.esp32-idf.yaml @@ -0,0 +1,61 @@ +i2c: + - id: i2c_ezo_pmp + scl: 16 + sda: 17 + +ezo_pmp: + id: hcl_pump + update_interval: 1s + +binary_sensor: + - platform: ezo_pmp + pump_state: + name: Pump State + is_paused: + name: Is Paused + +sensor: + - platform: ezo_pmp + current_volume_dosed: + name: Current Volume Dosed + total_volume_dosed: + name: Total Volume Dosed + absolute_total_volume_dosed: + name: Absolute Total Volume Dosed + pump_voltage: + name: Pump Voltage + last_volume_requested: + name: Last Volume Requested + max_flow_rate: + name: Max Flow Rate + +text_sensor: + - platform: ezo_pmp + dosing_mode: + name: Dosing Mode + calibration_status: + name: Calibration Status + on_value: + - ezo_pmp.dose_volume: + id: hcl_pump + volume: 10 + - ezo_pmp.dose_volume_over_time: + id: hcl_pump + volume: 10 + duration: 2 + - ezo_pmp.dose_with_constant_flow_rate: + id: hcl_pump + volume_per_minute: 10 + duration: 2 + - ezo_pmp.set_calibration_volume: + id: hcl_pump + volume: 10 + - ezo_pmp.find: hcl_pump + - ezo_pmp.dose_continuously: hcl_pump + - ezo_pmp.clear_total_volume_dosed: hcl_pump + - ezo_pmp.clear_calibration: hcl_pump + - ezo_pmp.pause_dosing: hcl_pump + - ezo_pmp.stop_dosing: hcl_pump + - ezo_pmp.arbitrary_command: + id: hcl_pump + command: D,? diff --git a/tests/components/ezo_pmp/test.esp32.yaml b/tests/components/ezo_pmp/test.esp32.yaml new file mode 100644 index 0000000000..9fc929b365 --- /dev/null +++ b/tests/components/ezo_pmp/test.esp32.yaml @@ -0,0 +1,61 @@ +i2c: + - id: i2c_ezo_pmp + scl: 16 + sda: 17 + +ezo_pmp: + id: hcl_pump + update_interval: 1s + +binary_sensor: + - platform: ezo_pmp + pump_state: + name: Pump State + is_paused: + name: Is Paused + +sensor: + - platform: ezo_pmp + current_volume_dosed: + name: Current Volume Dosed + total_volume_dosed: + name: Total Volume Dosed + absolute_total_volume_dosed: + name: Absolute Total Volume Dosed + pump_voltage: + name: Pump Voltage + last_volume_requested: + name: Last Volume Requested + max_flow_rate: + name: Max Flow Rate + +text_sensor: + - platform: ezo_pmp + dosing_mode: + name: Dosing Mode + calibration_status: + name: Calibration Status + on_value: + - ezo_pmp.dose_volume: + id: hcl_pump + volume: 10 + - ezo_pmp.dose_volume_over_time: + id: hcl_pump + volume: 10 + duration: 2 + - ezo_pmp.dose_with_constant_flow_rate: + id: hcl_pump + volume_per_minute: 10 + duration: 2 + - ezo_pmp.set_calibration_volume: + id: hcl_pump + volume: 10 + - ezo_pmp.find: hcl_pump + - ezo_pmp.dose_continuously: hcl_pump + - ezo_pmp.clear_total_volume_dosed: hcl_pump + - ezo_pmp.clear_calibration: hcl_pump + - ezo_pmp.pause_dosing: hcl_pump + - ezo_pmp.stop_dosing: hcl_pump + - ezo_pmp.arbitrary_command: + id: hcl_pump + command: D,? diff --git a/tests/components/ezo_pmp/test.esp8266.yaml b/tests/components/ezo_pmp/test.esp8266.yaml new file mode 100644 index 0000000000..fa047de3de --- /dev/null +++ b/tests/components/ezo_pmp/test.esp8266.yaml @@ -0,0 +1,61 @@ +i2c: + - id: i2c_ezo_pmp + scl: 5 + sda: 4 + +ezo_pmp: + id: hcl_pump + update_interval: 1s + +binary_sensor: + - platform: ezo_pmp + pump_state: + name: Pump State + is_paused: + name: Is Paused + +sensor: + - platform: ezo_pmp + current_volume_dosed: + name: Current Volume Dosed + total_volume_dosed: + name: Total Volume Dosed + absolute_total_volume_dosed: + name: Absolute Total Volume Dosed + pump_voltage: + name: Pump Voltage + last_volume_requested: + name: Last Volume Requested + max_flow_rate: + name: Max Flow Rate + +text_sensor: + - platform: ezo_pmp + dosing_mode: + name: Dosing Mode + calibration_status: + name: Calibration Status + on_value: + - ezo_pmp.dose_volume: + id: hcl_pump + volume: 10 + - ezo_pmp.dose_volume_over_time: + id: hcl_pump + volume: 10 + duration: 2 + - ezo_pmp.dose_with_constant_flow_rate: + id: hcl_pump + volume_per_minute: 10 + duration: 2 + - ezo_pmp.set_calibration_volume: + id: hcl_pump + volume: 10 + - ezo_pmp.find: hcl_pump + - ezo_pmp.dose_continuously: hcl_pump + - ezo_pmp.clear_total_volume_dosed: hcl_pump + - ezo_pmp.clear_calibration: hcl_pump + - ezo_pmp.pause_dosing: hcl_pump + - ezo_pmp.stop_dosing: hcl_pump + - ezo_pmp.arbitrary_command: + id: hcl_pump + command: D,? diff --git a/tests/components/ezo_pmp/test.rp2040.yaml b/tests/components/ezo_pmp/test.rp2040.yaml new file mode 100644 index 0000000000..fa047de3de --- /dev/null +++ b/tests/components/ezo_pmp/test.rp2040.yaml @@ -0,0 +1,61 @@ +i2c: + - id: i2c_ezo_pmp + scl: 5 + sda: 4 + +ezo_pmp: + id: hcl_pump + update_interval: 1s + +binary_sensor: + - platform: ezo_pmp + pump_state: + name: Pump State + is_paused: + name: Is Paused + +sensor: + - platform: ezo_pmp + current_volume_dosed: + name: Current Volume Dosed + total_volume_dosed: + name: Total Volume Dosed + absolute_total_volume_dosed: + name: Absolute Total Volume Dosed + pump_voltage: + name: Pump Voltage + last_volume_requested: + name: Last Volume Requested + max_flow_rate: + name: Max Flow Rate + +text_sensor: + - platform: ezo_pmp + dosing_mode: + name: Dosing Mode + calibration_status: + name: Calibration Status + on_value: + - ezo_pmp.dose_volume: + id: hcl_pump + volume: 10 + - ezo_pmp.dose_volume_over_time: + id: hcl_pump + volume: 10 + duration: 2 + - ezo_pmp.dose_with_constant_flow_rate: + id: hcl_pump + volume_per_minute: 10 + duration: 2 + - ezo_pmp.set_calibration_volume: + id: hcl_pump + volume: 10 + - ezo_pmp.find: hcl_pump + - ezo_pmp.dose_continuously: hcl_pump + - ezo_pmp.clear_total_volume_dosed: hcl_pump + - ezo_pmp.clear_calibration: hcl_pump + - ezo_pmp.pause_dosing: hcl_pump + - ezo_pmp.stop_dosing: hcl_pump + - ezo_pmp.arbitrary_command: + id: hcl_pump + command: D,? From 9b7438a56d0ebace3979c9d55e79093e3dd94469 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Tue, 19 Mar 2024 13:39:01 +1300 Subject: [PATCH 130/189] Require xsrf/csrf when using a password (#6396) --- esphome/dashboard/web_server.py | 6 ++++++ requirements.txt | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/esphome/dashboard/web_server.py b/esphome/dashboard/web_server.py index 3de1d69115..9ee2312781 100644 --- a/esphome/dashboard/web_server.py +++ b/esphome/dashboard/web_server.py @@ -688,6 +688,11 @@ class MainRequestHandler(BaseHandler): @authenticated def get(self) -> None: begin = bool(self.get_argument("begin", False)) + if settings.using_password: + # Simply accessing the xsrf_token sets the cookie for us + self.xsrf_token # pylint: disable=pointless-statement + else: + self.clear_cookie("_xsrf") self.render( "index.template.html", @@ -1102,6 +1107,7 @@ def make_app(debug=get_bool_env(ENV_DEV)) -> tornado.web.Application: "log_function": log_function, "websocket_ping_interval": 30.0, "template_path": get_base_frontend_path(), + "xsrf_cookies": settings.using_password, } rel = settings.relative_url return tornado.web.Application( diff --git a/requirements.txt b/requirements.txt index 9b5e06fc59..4b7e501e97 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ pyserial==3.5 platformio==6.1.13 # When updating platformio, also update Dockerfile esptool==4.7.0 click==8.1.7 -esphome-dashboard==20231107.0 +esphome-dashboard==20240319.0 aioesphomeapi==23.1.1 zeroconf==0.131.0 python-magic==0.4.27 From 19022ace12595295fadcc3fbb36c69a8d5c846f4 Mon Sep 17 00:00:00 2001 From: Jimmy Hedman Date: Tue, 19 Mar 2024 03:56:36 +0100 Subject: [PATCH 131/189] Make SPI compile with IDF >= 5.0 (#6383) Co-authored-by: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> --- esphome/components/spi_device/spi_device.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/esphome/components/spi_device/spi_device.cpp b/esphome/components/spi_device/spi_device.cpp index 4e0b72ae60..1f579cb802 100644 --- a/esphome/components/spi_device/spi_device.cpp +++ b/esphome/components/spi_device/spi_device.cpp @@ -1,6 +1,7 @@ #include "spi_device.h" #include "esphome/core/log.h" #include "esphome/core/hal.h" +#include namespace esphome { namespace spi_device { @@ -18,9 +19,9 @@ void SPIDeviceComponent::dump_config() { LOG_PIN(" CS pin: ", this->cs_); ESP_LOGCONFIG(TAG, " Mode: %d", this->mode_); if (this->data_rate_ < 1000000) { - ESP_LOGCONFIG(TAG, " Data rate: %dkHz", this->data_rate_ / 1000); + ESP_LOGCONFIG(TAG, " Data rate: %" PRId32 "kHz", this->data_rate_ / 1000); } else { - ESP_LOGCONFIG(TAG, " Data rate: %dMHz", this->data_rate_ / 1000000); + ESP_LOGCONFIG(TAG, " Data rate: %" PRId32 "MHz", this->data_rate_ / 1000000); } } From af3fb615ead27b90c8c98fdbaf33e80e6eaf87f4 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Tue, 19 Mar 2024 00:18:03 -0500 Subject: [PATCH 132/189] Fix esp32-camera test yaml (#6398) * Fix esp32-camera test yaml * Fix esp32-camera test yaml, take 2 --- .../components/esp32_camera/test.esp32-idf.yaml | 16 ++++++++-------- tests/components/esp32_camera/test.esp32.yaml | 16 ++++++++-------- .../esp32_camera_web_server/test.esp32-idf.yaml | 16 ++++++++-------- .../esp32_camera_web_server/test.esp32.yaml | 16 ++++++++-------- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/tests/components/esp32_camera/test.esp32-idf.yaml b/tests/components/esp32_camera/test.esp32-idf.yaml index 366f601657..2f5f792f1c 100644 --- a/tests/components/esp32_camera/test.esp32-idf.yaml +++ b/tests/components/esp32_camera/test.esp32-idf.yaml @@ -3,12 +3,12 @@ esp32_camera: data_pins: - number: 17 - number: 35 - - number: 34 - - number: 5 - - number: 39 - - number: 18 - - number: 36 - - number: 19 + - number: 34 + - number: 5 + - number: 39 + - number: 18 + - number: 36 + - number: 19 vsync_pin: 22 href_pin: 26 pixel_clock_pin: 21 @@ -24,5 +24,5 @@ esp32_camera: jpeg_quality: 10 on_image: then: - - lambda: |- - ESP_LOGD("main", "image len=%d, data=%c", image.length, image.data[0]); + - lambda: |- + ESP_LOGD("main", "image len=%d, data=%c", image.length, image.data[0]); diff --git a/tests/components/esp32_camera/test.esp32.yaml b/tests/components/esp32_camera/test.esp32.yaml index 366f601657..2f5f792f1c 100644 --- a/tests/components/esp32_camera/test.esp32.yaml +++ b/tests/components/esp32_camera/test.esp32.yaml @@ -3,12 +3,12 @@ esp32_camera: data_pins: - number: 17 - number: 35 - - number: 34 - - number: 5 - - number: 39 - - number: 18 - - number: 36 - - number: 19 + - number: 34 + - number: 5 + - number: 39 + - number: 18 + - number: 36 + - number: 19 vsync_pin: 22 href_pin: 26 pixel_clock_pin: 21 @@ -24,5 +24,5 @@ esp32_camera: jpeg_quality: 10 on_image: then: - - lambda: |- - ESP_LOGD("main", "image len=%d, data=%c", image.length, image.data[0]); + - lambda: |- + ESP_LOGD("main", "image len=%d, data=%c", image.length, image.data[0]); diff --git a/tests/components/esp32_camera_web_server/test.esp32-idf.yaml b/tests/components/esp32_camera_web_server/test.esp32-idf.yaml index 14b7bd5c34..5edefdf0a8 100644 --- a/tests/components/esp32_camera_web_server/test.esp32-idf.yaml +++ b/tests/components/esp32_camera_web_server/test.esp32-idf.yaml @@ -3,12 +3,12 @@ esp32_camera: data_pins: - number: 17 - number: 35 - - number: 34 - - number: 5 - - number: 39 - - number: 18 - - number: 36 - - number: 19 + - number: 34 + - number: 5 + - number: 39 + - number: 18 + - number: 36 + - number: 19 vsync_pin: 22 href_pin: 26 pixel_clock_pin: 21 @@ -24,8 +24,8 @@ esp32_camera: jpeg_quality: 10 on_image: then: - - lambda: |- - ESP_LOGD("main", "image len=%d, data=%c", image.length, image.data[0]); + - lambda: |- + ESP_LOGD("main", "image len=%d, data=%c", image.length, image.data[0]); esp32_camera_web_server: - port: 8080 diff --git a/tests/components/esp32_camera_web_server/test.esp32.yaml b/tests/components/esp32_camera_web_server/test.esp32.yaml index 14b7bd5c34..5edefdf0a8 100644 --- a/tests/components/esp32_camera_web_server/test.esp32.yaml +++ b/tests/components/esp32_camera_web_server/test.esp32.yaml @@ -3,12 +3,12 @@ esp32_camera: data_pins: - number: 17 - number: 35 - - number: 34 - - number: 5 - - number: 39 - - number: 18 - - number: 36 - - number: 19 + - number: 34 + - number: 5 + - number: 39 + - number: 18 + - number: 36 + - number: 19 vsync_pin: 22 href_pin: 26 pixel_clock_pin: 21 @@ -24,8 +24,8 @@ esp32_camera: jpeg_quality: 10 on_image: then: - - lambda: |- - ESP_LOGD("main", "image len=%d, data=%c", image.length, image.data[0]); + - lambda: |- + ESP_LOGD("main", "image len=%d, data=%c", image.length, image.data[0]); esp32_camera_web_server: - port: 8080 From f0936dd22dd2c6ce62f75f3afe42964d578340c6 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Wed, 20 Mar 2024 10:53:01 +1100 Subject: [PATCH 133/189] AHT10: Use state machine to avoid blocking delay (#6401) --- esphome/components/aht10/aht10.cpp | 107 +++++++++++++++-------------- esphome/components/aht10/aht10.h | 5 ++ 2 files changed, 61 insertions(+), 51 deletions(-) diff --git a/esphome/components/aht10/aht10.cpp b/esphome/components/aht10/aht10.cpp index 57102e6d27..d5af06c2a2 100644 --- a/esphome/components/aht10/aht10.cpp +++ b/esphome/components/aht10/aht10.cpp @@ -36,6 +36,7 @@ static const uint8_t AHT10_INIT_ATTEMPTS = 10; static const uint8_t AHT10_STATUS_BUSY = 0x80; void AHT10Component::setup() { + this->read_delay_ = this->humidity_sensor_ != nullptr ? AHT10_HUMIDITY_DELAY : AHT10_DEFAULT_DELAY; if (this->write(AHT10_SOFTRESET_CMD, sizeof(AHT10_SOFTRESET_CMD)) != i2c::ERROR_OK) { ESP_LOGE(TAG, "Reset AHT10 failed!"); } @@ -83,74 +84,78 @@ void AHT10Component::setup() { ESP_LOGV(TAG, "AHT10 initialization"); } -void AHT10Component::update() { - if (this->write(AHT10_MEASURE_CMD, sizeof(AHT10_MEASURE_CMD)) != i2c::ERROR_OK) { - ESP_LOGE(TAG, "Communication with AHT10 failed!"); - this->status_set_warning(); - return; - } - uint8_t data[6]; - uint8_t delay_ms = AHT10_DEFAULT_DELAY; - if (this->humidity_sensor_ != nullptr) - delay_ms = AHT10_HUMIDITY_DELAY; - bool success = false; - for (int i = 0; i < AHT10_ATTEMPTS; ++i) { - ESP_LOGVV(TAG, "Attempt %d at %6" PRIu32, i, millis()); - delay(delay_ms); - if (this->read(data, 6) != i2c::ERROR_OK) { - ESP_LOGD(TAG, "Communication with AHT10 failed, waiting..."); - continue; - } - - if ((data[0] & 0x80) == 0x80) { // Bit[7] = 0b1, device is busy - ESP_LOGD(TAG, "AHT10 is busy, waiting..."); - } else if (data[1] == 0x0 && data[2] == 0x0 && (data[3] >> 4) == 0x0) { - // Unrealistic humidity (0x0) - if (this->humidity_sensor_ == nullptr) { - ESP_LOGVV(TAG, "ATH10 Unrealistic humidity (0x0), but humidity is not required"); - break; - } else { - ESP_LOGD(TAG, "ATH10 Unrealistic humidity (0x0), retrying..."); - if (this->write(AHT10_MEASURE_CMD, sizeof(AHT10_MEASURE_CMD)) != i2c::ERROR_OK) { - ESP_LOGE(TAG, "Communication with AHT10 failed!"); - this->status_set_warning(); - return; - } - } - } else { - // data is valid, we can break the loop - ESP_LOGVV(TAG, "Answer at %6" PRIu32, millis()); - success = true; - break; - } - } - if (!success || (data[0] & 0x80) == 0x80) { +void AHT10Component::restart_read_() { + if (this->read_count_ == AHT10_ATTEMPTS) { + this->read_count_ = 0; ESP_LOGE(TAG, "Measurements reading timed-out!"); - this->status_set_warning(); + this->status_set_error(); + return; + } + this->read_count_++; + this->set_timeout(this->read_delay_, [this]() { this->read_data_(); }); +} + +void AHT10Component::read_data_() { + uint8_t data[6]; + ESP_LOGD(TAG, "Read attempt %d at %ums", this->read_count_, (unsigned) (millis() - this->start_time_)); + if (this->read(data, 6) != i2c::ERROR_OK) { + ESP_LOGD(TAG, "Communication with AHT10 failed, waiting..."); + this->restart_read_(); return; } + if ((data[0] & 0x80) == 0x80) { // Bit[7] = 0b1, device is busy + ESP_LOGD(TAG, "AHT10 is busy, waiting..."); + this->restart_read_(); + return; + } + if (data[1] == 0x0 && data[2] == 0x0 && (data[3] >> 4) == 0x0) { + // Unrealistic humidity (0x0) + if (this->humidity_sensor_ == nullptr) { + ESP_LOGV(TAG, "ATH10 Unrealistic humidity (0x0), but humidity is not required"); + } else { + ESP_LOGD(TAG, "ATH10 Unrealistic humidity (0x0), retrying..."); + if (this->write(AHT10_MEASURE_CMD, sizeof(AHT10_MEASURE_CMD)) != i2c::ERROR_OK) { + ESP_LOGE(TAG, "Communication with AHT10 failed!"); + this->status_set_warning(); + } + this->restart_read_(); + return; + } + } + ESP_LOGD(TAG, "Success at %ums", (unsigned) (millis() - this->start_time_)); uint32_t raw_temperature = ((data[3] & 0x0F) << 16) | (data[4] << 8) | data[5]; uint32_t raw_humidity = ((data[1] << 16) | (data[2] << 8) | data[3]) >> 4; - float temperature = ((200.0f * (float) raw_temperature) / 1048576.0f) - 50.0f; - float humidity; - if (raw_humidity == 0) { // unrealistic value - humidity = NAN; - } else { - humidity = (float) raw_humidity * 100.0f / 1048576.0f; - } - if (this->temperature_sensor_ != nullptr) { + float temperature = ((200.0f * (float) raw_temperature) / 1048576.0f) - 50.0f; this->temperature_sensor_->publish_state(temperature); } if (this->humidity_sensor_ != nullptr) { + float humidity; + if (raw_humidity == 0) { // unrealistic value + humidity = NAN; + } else { + humidity = (float) raw_humidity * 100.0f / 1048576.0f; + } if (std::isnan(humidity)) { ESP_LOGW(TAG, "Invalid humidity! Sensor reported 0%% Hum"); } this->humidity_sensor_->publish_state(humidity); } this->status_clear_warning(); + this->read_count_ = 0; +} +void AHT10Component::update() { + if (this->read_count_ != 0) + return; + this->start_time_ = millis(); + if (this->write(AHT10_MEASURE_CMD, sizeof(AHT10_MEASURE_CMD)) != i2c::ERROR_OK) { + ESP_LOGE(TAG, "Communication with AHT10 failed!"); + this->status_set_warning(); + return; + } + this->restart_read_(); } float AHT10Component::get_setup_priority() const { return setup_priority::DATA; } diff --git a/esphome/components/aht10/aht10.h b/esphome/components/aht10/aht10.h index 3840609d56..76f051878e 100644 --- a/esphome/components/aht10/aht10.h +++ b/esphome/components/aht10/aht10.h @@ -26,6 +26,11 @@ class AHT10Component : public PollingComponent, public i2c::I2CDevice { sensor::Sensor *temperature_sensor_{nullptr}; sensor::Sensor *humidity_sensor_{nullptr}; AHT10Variant variant_{}; + unsigned read_count_{}; + unsigned read_delay_{}; + void read_data_(); + void restart_read_(); + uint32_t start_time_{}; }; } // namespace aht10 From 774cbde1b6c6d121a8b2a92a2aa53f79a77f320f Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Wed, 20 Mar 2024 10:56:43 +1100 Subject: [PATCH 134/189] Show component warnings and errors in the log; (#6400) --- esphome/core/component.cpp | 29 +++++++++++++++++++++++------ esphome/core/component.h | 8 ++++---- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/esphome/core/component.cpp b/esphome/core/component.cpp index d737ec0ae3..b9a7697015 100644 --- a/esphome/core/component.cpp +++ b/esphome/core/component.cpp @@ -141,18 +141,35 @@ bool Component::is_ready() { (this->component_state_ & COMPONENT_STATE_MASK) == COMPONENT_STATE_SETUP; } bool Component::can_proceed() { return true; } -bool Component::status_has_warning() { return this->component_state_ & STATUS_LED_WARNING; } -bool Component::status_has_error() { return this->component_state_ & STATUS_LED_ERROR; } -void Component::status_set_warning() { +bool Component::status_has_warning() const { return this->component_state_ & STATUS_LED_WARNING; } +bool Component::status_has_error() const { return this->component_state_ & STATUS_LED_ERROR; } +void Component::status_set_warning(const char *message) { + // Don't spam the log. This risks missing different warning messages though. + if ((this->component_state_ & STATUS_LED_WARNING) != 0) + return; this->component_state_ |= STATUS_LED_WARNING; App.app_state_ |= STATUS_LED_WARNING; + ESP_LOGW(this->get_component_source(), "Warning set: %s", message); } -void Component::status_set_error() { +void Component::status_set_error(const char *message) { + if ((this->component_state_ & STATUS_LED_ERROR) != 0) + return; this->component_state_ |= STATUS_LED_ERROR; App.app_state_ |= STATUS_LED_ERROR; + ESP_LOGE(this->get_component_source(), "Error set: %s", message); +} +void Component::status_clear_warning() { + if ((this->component_state_ & STATUS_LED_WARNING) == 0) + return; + this->component_state_ &= ~STATUS_LED_WARNING; + ESP_LOGW(this->get_component_source(), "Warning cleared"); +} +void Component::status_clear_error() { + if ((this->component_state_ & STATUS_LED_ERROR) == 0) + return; + this->component_state_ &= ~STATUS_LED_ERROR; + ESP_LOGE(this->get_component_source(), "Error cleared"); } -void Component::status_clear_warning() { this->component_state_ &= ~STATUS_LED_WARNING; } -void Component::status_clear_error() { this->component_state_ &= ~STATUS_LED_ERROR; } void Component::status_momentary_warning(const std::string &name, uint32_t length) { this->status_set_warning(); this->set_timeout(name, length, [this]() { this->status_clear_warning(); }); diff --git a/esphome/core/component.h b/esphome/core/component.h index deefedf3d8..4f244e5fcb 100644 --- a/esphome/core/component.h +++ b/esphome/core/component.h @@ -124,13 +124,13 @@ class Component { virtual bool can_proceed(); - bool status_has_warning(); + bool status_has_warning() const; - bool status_has_error(); + bool status_has_error() const; - void status_set_warning(); + void status_set_warning(const char *message = "unspecified"); - void status_set_error(); + void status_set_error(const char *message = "unspecified"); void status_clear_warning(); From 7e8e658999d169757c0a00b56d97cbde09113a60 Mon Sep 17 00:00:00 2001 From: RFDarter Date: Wed, 20 Mar 2024 04:37:18 +0100 Subject: [PATCH 135/189] web_server support for v3 (#6203) --- esphome/components/web_server/__init__.py | 9 +++++++-- esphome/components/web_server/web_server.cpp | 2 +- esphome/components/web_server/web_server.h | 2 +- tests/test10.yaml | 3 +++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/esphome/components/web_server/__init__.py b/esphome/components/web_server/__init__.py index 2708b5d06e..bbd5bc662e 100644 --- a/esphome/components/web_server/__init__.py +++ b/esphome/components/web_server/__init__.py @@ -44,6 +44,11 @@ def default_url(config): config[CONF_CSS_URL] = "" if not (CONF_JS_URL in config): config[CONF_JS_URL] = "https://oi.esphome.io/v2/www.js" + if config[CONF_VERSION] == 3: + if not (CONF_CSS_URL in config): + config[CONF_CSS_URL] = "" + if not (CONF_JS_URL in config): + config[CONF_JS_URL] = "https://oi.esphome.io/v3/www.js" return config @@ -64,7 +69,7 @@ CONFIG_SCHEMA = cv.All( { cv.GenerateID(): cv.declare_id(WebServer), cv.Optional(CONF_PORT, default=80): cv.port, - cv.Optional(CONF_VERSION, default=2): cv.one_of(1, 2, int=True), + cv.Optional(CONF_VERSION, default=2): cv.one_of(1, 2, 3, int=True), cv.Optional(CONF_CSS_URL): cv.string, cv.Optional(CONF_CSS_INCLUDE): cv.file_, cv.Optional(CONF_JS_URL): cv.string, @@ -152,7 +157,7 @@ async def to_code(config): cg.add_define("USE_WEBSERVER") cg.add_define("USE_WEBSERVER_PORT", config[CONF_PORT]) cg.add_define("USE_WEBSERVER_VERSION", version) - if version == 2: + if version >= 2: # Don't compress the index HTML as the data sizes are almost the same. add_resource_as_progmem("INDEX_HTML", build_index_html(config), compress=False) else: diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index 69d601ed49..f065dc6684 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -358,7 +358,7 @@ void WebServer::handle_index_request(AsyncWebServerRequest *request) { stream->print(F("")); request->send(stream); } -#elif USE_WEBSERVER_VERSION == 2 +#elif USE_WEBSERVER_VERSION >= 2 void WebServer::handle_index_request(AsyncWebServerRequest *request) { AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", ESPHOME_WEBSERVER_INDEX_HTML, ESPHOME_WEBSERVER_INDEX_HTML_SIZE); diff --git a/esphome/components/web_server/web_server.h b/esphome/components/web_server/web_server.h index 06c59ecaca..57cbbe1339 100644 --- a/esphome/components/web_server/web_server.h +++ b/esphome/components/web_server/web_server.h @@ -13,7 +13,7 @@ #include #endif -#if USE_WEBSERVER_VERSION == 2 +#if USE_WEBSERVER_VERSION >= 2 extern const uint8_t ESPHOME_WEBSERVER_INDEX_HTML[] PROGMEM; extern const size_t ESPHOME_WEBSERVER_INDEX_HTML_SIZE; #endif diff --git a/tests/test10.yaml b/tests/test10.yaml index 7e3a685b36..854173cfe9 100644 --- a/tests/test10.yaml +++ b/tests/test10.yaml @@ -23,6 +23,9 @@ logger: api: reboot_timeout: 10min +web_server: + version: 3 + time: - platform: sntp From afbaf56c0bdc90d6b6894b334dc7247ae9a17d95 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 21:14:15 +1300 Subject: [PATCH 136/189] Bump pytest-asyncio from 0.23.5.post1 to 0.23.6 (#6402) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements_test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_test.txt b/requirements_test.txt index 29e5420d78..8fb59683b4 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -8,6 +8,6 @@ pre-commit pytest==8.1.1 pytest-cov==4.1.0 pytest-mock==3.12.0 -pytest-asyncio==0.23.5.post1 +pytest-asyncio==0.23.6 asyncmock==0.4.2 hypothesis==6.92.1 From bdb6881cd5a700b65d8aef312ac45f1cc20bfdcc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 21:14:52 +1300 Subject: [PATCH 137/189] Bump actions/cache from 4.0.1 to 4.0.2 in /.github/actions/restore-python (#6403) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/restore-python/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/restore-python/action.yml b/.github/actions/restore-python/action.yml index 756e279635..aa4f7ba887 100644 --- a/.github/actions/restore-python/action.yml +++ b/.github/actions/restore-python/action.yml @@ -22,7 +22,7 @@ runs: python-version: ${{ inputs.python-version }} - name: Restore Python virtual environment id: cache-venv - uses: actions/cache/restore@v4.0.1 + uses: actions/cache/restore@v4.0.2 with: path: venv # yamllint disable-line rule:line-length From b12ccd460b4a9b530475e3dc9e01c866d4b7b711 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 21:15:03 +1300 Subject: [PATCH 138/189] Bump actions/cache from 4.0.1 to 4.0.2 (#6404) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 47709739dc..871f2e72c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: python-version: ${{ env.DEFAULT_PYTHON }} - name: Restore Python virtual environment id: cache-venv - uses: actions/cache@v4.0.1 + uses: actions/cache@v4.0.2 with: path: venv # yamllint disable-line rule:line-length @@ -367,7 +367,7 @@ jobs: python-version: ${{ env.DEFAULT_PYTHON }} cache-key: ${{ needs.common.outputs.cache-key }} - name: Cache platformio - uses: actions/cache@v4.0.1 + uses: actions/cache@v4.0.2 with: path: ~/.platformio # yamllint disable-line rule:line-length From 7d9fc3ceaab4db660a8aeddb55499d640b549cbe Mon Sep 17 00:00:00 2001 From: Jimmy Hedman Date: Wed, 20 Mar 2024 09:16:10 +0100 Subject: [PATCH 139/189] Bump ESP8266 Arduino versions (#5359) --- esphome/components/esp8266/__init__.py | 12 ++++++++---- esphome/components/mqtt/mqtt_client.cpp | 4 ---- esphome/components/wifi/wifi_component_esp8266.cpp | 10 +++++++++- esphome/core/defines.h | 2 +- platformio.ini | 4 ++-- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/esphome/components/esp8266/__init__.py b/esphome/components/esp8266/__init__.py index 5336842b9d..00729921a3 100644 --- a/esphome/components/esp8266/__init__.py +++ b/esphome/components/esp8266/__init__.py @@ -83,20 +83,22 @@ def _format_framework_arduino_version(ver: cv.Version) -> str: # The default/recommended arduino framework version # - https://github.com/esp8266/Arduino/releases # - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-arduinoespressif8266 -RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(3, 0, 2) +RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(3, 1, 2) # The platformio/espressif8266 version to use for arduino 2 framework versions # - https://github.com/platformio/platform-espressif8266/releases # - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif8266 ARDUINO_2_PLATFORM_VERSION = cv.Version(2, 6, 3) # for arduino 3 framework versions ARDUINO_3_PLATFORM_VERSION = cv.Version(3, 2, 0) +# for arduino 4 framework versions +ARDUINO_4_PLATFORM_VERSION = cv.Version(4, 2, 1) def _arduino_check_versions(value): value = value.copy() lookups = { - "dev": (cv.Version(3, 0, 2), "https://github.com/esp8266/Arduino.git"), - "latest": (cv.Version(3, 0, 2), None), + "dev": (cv.Version(3, 1, 2), "https://github.com/esp8266/Arduino.git"), + "latest": (cv.Version(3, 1, 2), None), "recommended": (RECOMMENDED_ARDUINO_FRAMEWORK_VERSION, None), } @@ -116,7 +118,9 @@ def _arduino_check_versions(value): platform_version = value.get(CONF_PLATFORM_VERSION) if platform_version is None: - if version >= cv.Version(3, 0, 0): + if version >= cv.Version(3, 1, 0): + platform_version = _parse_platform_version(str(ARDUINO_4_PLATFORM_VERSION)) + elif version >= cv.Version(3, 0, 0): platform_version = _parse_platform_version(str(ARDUINO_3_PLATFORM_VERSION)) elif version >= cv.Version(2, 5, 0): platform_version = _parse_platform_version(str(ARDUINO_2_PLATFORM_VERSION)) diff --git a/esphome/components/mqtt/mqtt_client.cpp b/esphome/components/mqtt/mqtt_client.cpp index 0f5f49abc1..abcbb414d9 100644 --- a/esphome/components/mqtt/mqtt_client.cpp +++ b/esphome/components/mqtt/mqtt_client.cpp @@ -187,11 +187,7 @@ void MQTTClientComponent::start_dnslookup_() { default: case ERR_ARG: { // error -#if defined(USE_ESP8266) - ESP_LOGW(TAG, "Error resolving MQTT broker IP address: %ld", err); -#else ESP_LOGW(TAG, "Error resolving MQTT broker IP address: %d", err); -#endif break; } } diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index f274e37a9f..838250972b 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -21,10 +21,14 @@ extern "C" { #include #if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(3, 0, 0) #include "LwipDhcpServer.h" +#if USE_ARDUINO_VERSION_CODE < VERSION_CODE(3, 1, 0) +#include +#include "ESP8266WiFiAP.h" #define wifi_softap_set_dhcps_lease(lease) dhcpSoftAP.set_dhcps_lease(lease) #define wifi_softap_set_dhcps_lease_time(time) dhcpSoftAP.set_dhcps_lease_time(time) #define wifi_softap_set_dhcps_offer_option(offer, mode) dhcpSoftAP.set_dhcps_offer_option(offer, mode) #endif +#endif } #include "esphome/core/helpers.h" @@ -721,7 +725,7 @@ bool WiFiComponent::wifi_ap_ip_config_(optional manual_ip) { return false; } -#if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(3, 0, 0) +#if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(3, 0, 0) && USE_ARDUINO_VERSION_CODE < VERSION_CODE(3, 1, 0) dhcpSoftAP.begin(&info); #endif @@ -745,12 +749,16 @@ bool WiFiComponent::wifi_ap_ip_config_(optional manual_ip) { return false; } +#if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(3, 1, 0) + ESP8266WiFiClass::softAPDhcpServer().setRouter(true); // send ROUTER option with netif's gateway IP +#else uint8_t mode = 1; // bit0, 1 enables router information from ESP8266 SoftAP DHCP server. if (!wifi_softap_set_dhcps_offer_option(OFFER_ROUTER, &mode)) { ESP_LOGV(TAG, "wifi_softap_set_dhcps_offer_option failed!"); return false; } +#endif if (!wifi_softap_dhcps_start()) { ESP_LOGV(TAG, "Starting SoftAP DHCPS failed!"); diff --git a/esphome/core/defines.h b/esphome/core/defines.h index 86f89e7bf6..501dccc6fa 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -98,7 +98,7 @@ // ESP8266-specific feature flags #ifdef USE_ESP8266 #define USE_ADC_SENSOR_VCC -#define USE_ARDUINO_VERSION_CODE VERSION_CODE(3, 0, 2) +#define USE_ARDUINO_VERSION_CODE VERSION_CODE(3, 1, 2) #define USE_ESP8266_PREFERENCES_FLASH #define USE_HTTP_REQUEST_ESP8266_HTTPS #define USE_SOCKET_IMPL_LWIP_TCP diff --git a/platformio.ini b/platformio.ini index 8ba8b8a2cf..b326c9722e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -80,9 +80,9 @@ build_flags = ; This are common settings for the ESP8266 using Arduino. [common:esp8266-arduino] extends = common:arduino -platform = platformio/espressif8266@3.2.0 +platform = platformio/espressif8266@4.2.1 platform_packages = - platformio/framework-arduinoespressif8266@~3.30002.0 + platformio/framework-arduinoespressif8266@~3.30102.0 framework = arduino lib_deps = From b95a7f6438461e1b46f8eb95871345d2be246cf6 Mon Sep 17 00:00:00 2001 From: cvwillegen Date: Wed, 20 Mar 2024 09:16:52 +0100 Subject: [PATCH 140/189] Allow accept/reject delta to be specified. (#5060) --- esphome/components/remote_base/__init__.py | 3 +++ esphome/components/remote_base/pronto_protocol.cpp | 5 +++-- esphome/components/remote_base/pronto_protocol.h | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/esphome/components/remote_base/__init__.py b/esphome/components/remote_base/__init__.py index 1d8c6e0967..08652bbfc9 100644 --- a/esphome/components/remote_base/__init__.py +++ b/esphome/components/remote_base/__init__.py @@ -32,6 +32,7 @@ from esphome.const import ( CONF_MAGNITUDE, CONF_WAND_ID, CONF_LEVEL, + CONF_DELTA, ) from esphome.core import coroutine from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor @@ -792,6 +793,7 @@ async def pioneer_action(var, config, args): PRONTO_SCHEMA = cv.Schema( { cv.Required(CONF_DATA): cv.string, + cv.Optional(CONF_DELTA, default=-1): cv.int_, } ) @@ -803,6 +805,7 @@ def pronto_binary_sensor(var, config): cg.StructInitializer( ProntoData, ("data", config[CONF_DATA]), + ("delta", config[CONF_DELTA]), ) ) ) diff --git a/esphome/components/remote_base/pronto_protocol.cpp b/esphome/components/remote_base/pronto_protocol.cpp index ccae64449a..625af76235 100644 --- a/esphome/components/remote_base/pronto_protocol.cpp +++ b/esphome/components/remote_base/pronto_protocol.cpp @@ -49,13 +49,13 @@ bool ProntoData::operator==(const ProntoData &rhs) const { for (std::vector::size_type i = 0; i < data1.size() - 1; ++i) { int diff = data2[i] - data1[i]; diff *= diff; - if (diff > 9) + if (rhs.delta == -1 && diff > 9) return false; total_diff += diff; } - return total_diff <= data1.size() * 3; + return total_diff <= (rhs.delta == -1 ? data1.size() * 3 : rhs.delta); } // DO NOT EXPORT from this file @@ -222,6 +222,7 @@ optional ProntoProtocol::decode(RemoteReceiveData src) { prontodata += compensate_and_dump_sequence_(data, timebase); out.data = prontodata; + out.delta = -1; return out; } diff --git a/esphome/components/remote_base/pronto_protocol.h b/esphome/components/remote_base/pronto_protocol.h index 8b2163af12..e600834d1a 100644 --- a/esphome/components/remote_base/pronto_protocol.h +++ b/esphome/components/remote_base/pronto_protocol.h @@ -12,6 +12,7 @@ std::vector encode_pronto(const std::string &str); struct ProntoData { std::string data; + int delta; bool operator==(const ProntoData &rhs) const; }; @@ -40,10 +41,12 @@ DECLARE_REMOTE_PROTOCOL(Pronto) template class ProntoAction : public RemoteTransmitterActionBase { public: TEMPLATABLE_VALUE(std::string, data) + TEMPLATABLE_VALUE(int, delta) void encode(RemoteTransmitData *dst, Ts... x) override { ProntoData data{}; data.data = this->data_.value(x...); + data.delta = this->delta_.value(x...); ProntoProtocol().encode(dst, data); } }; From b0db7319f90452f66bfaecd6e16a0bc3d8e730d3 Mon Sep 17 00:00:00 2001 From: Gagootron Date: Wed, 20 Mar 2024 09:17:32 +0100 Subject: [PATCH 141/189] Allow setting htop for ledc (#6340) --- esphome/components/ledc/ledc_output.cpp | 14 ++++++++++++-- esphome/components/ledc/ledc_output.h | 2 ++ esphome/components/ledc/output.py | 6 ++++++ tests/components/cwww/test.esp32-c3-idf.yaml | 3 +++ tests/components/cwww/test.esp32-idf.yaml | 3 +++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/esphome/components/ledc/ledc_output.cpp b/esphome/components/ledc/ledc_output.cpp index dfb84c1e76..0533143d37 100644 --- a/esphome/components/ledc/ledc_output.cpp +++ b/esphome/components/ledc/ledc_output.cpp @@ -96,6 +96,12 @@ esp_err_t configure_timer_frequency(ledc_mode_t speed_mode, ledc_timer_t timer_n } #endif +#ifdef USE_ESP_IDF +constexpr int ledc_angle_to_htop(float angle, uint8_t bit_depth) { + return static_cast(angle * ((1U << bit_depth) - 1) / 360.); +} +#endif // USE_ESP_IDF + void LEDCOutput::write_state(float state) { if (!initialized_) { ESP_LOGW(TAG, "LEDC output hasn't been initialized yet!"); @@ -117,7 +123,8 @@ void LEDCOutput::write_state(float state) { #ifdef USE_ESP_IDF auto speed_mode = get_speed_mode(channel_); auto chan_num = static_cast(channel_ % 8); - ledc_set_duty(speed_mode, chan_num, duty); + int hpoint = ledc_angle_to_htop(this->phase_angle_, this->bit_depth_); + ledc_set_duty_with_hpoint(speed_mode, chan_num, duty, hpoint); ledc_update_duty(speed_mode, chan_num); #endif } @@ -143,8 +150,10 @@ void LEDCOutput::setup() { this->status_set_error(); return; } + int hpoint = ledc_angle_to_htop(this->phase_angle_, this->bit_depth_); ESP_LOGV(TAG, "Configured frequency %f with a bit depth of %u bits", this->frequency_, this->bit_depth_); + ESP_LOGV(TAG, "Angle of %.1f° results in hpoint %u", this->phase_angle_, hpoint); ledc_channel_config_t chan_conf{}; chan_conf.gpio_num = pin_->get_pin(); @@ -153,7 +162,7 @@ void LEDCOutput::setup() { chan_conf.intr_type = LEDC_INTR_DISABLE; chan_conf.timer_sel = timer_num; chan_conf.duty = inverted_ == pin_->is_inverted() ? 0 : (1U << bit_depth_); - chan_conf.hpoint = 0; + chan_conf.hpoint = hpoint; ledc_channel_config(&chan_conf); initialized_ = true; this->status_clear_error(); @@ -165,6 +174,7 @@ void LEDCOutput::dump_config() { LOG_PIN(" Pin ", this->pin_); ESP_LOGCONFIG(TAG, " LEDC Channel: %u", this->channel_); ESP_LOGCONFIG(TAG, " PWM Frequency: %.1f Hz", this->frequency_); + ESP_LOGCONFIG(TAG, " Phase angle: %.1f°", this->phase_angle_); ESP_LOGCONFIG(TAG, " Bit depth: %u", this->bit_depth_); ESP_LOGV(TAG, " Max frequency for bit depth: %f", ledc_max_frequency_for_bit_depth(this->bit_depth_)); ESP_LOGV(TAG, " Min frequency for bit depth: %f", diff --git a/esphome/components/ledc/ledc_output.h b/esphome/components/ledc/ledc_output.h index a78bf440a9..f04543bc5b 100644 --- a/esphome/components/ledc/ledc_output.h +++ b/esphome/components/ledc/ledc_output.h @@ -19,6 +19,7 @@ class LEDCOutput : public output::FloatOutput, public Component { void set_channel(uint8_t channel) { this->channel_ = channel; } void set_frequency(float frequency) { this->frequency_ = frequency; } + void set_phase_angle(float angle) { this->phase_angle_ = angle; } /// Dynamically change frequency at runtime void update_frequency(float frequency) override; @@ -35,6 +36,7 @@ class LEDCOutput : public output::FloatOutput, public Component { InternalGPIOPin *pin_; uint8_t channel_{}; uint8_t bit_depth_{}; + float phase_angle_{0.0f}; float frequency_{}; float duty_{0.0f}; bool initialized_ = false; diff --git a/esphome/components/ledc/output.py b/esphome/components/ledc/output.py index f6dc89cd9b..32c68f8d24 100644 --- a/esphome/components/ledc/output.py +++ b/esphome/components/ledc/output.py @@ -3,6 +3,7 @@ from esphome.components import output import esphome.config_validation as cv import esphome.codegen as cg from esphome.const import ( + CONF_PHASE_ANGLE, CONF_CHANNEL, CONF_FREQUENCY, CONF_ID, @@ -46,6 +47,9 @@ CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend( cv.Required(CONF_PIN): pins.internal_gpio_output_pin_schema, cv.Optional(CONF_FREQUENCY, default="1kHz"): cv.frequency, cv.Optional(CONF_CHANNEL): cv.int_range(min=0, max=15), + cv.Optional(CONF_PHASE_ANGLE): cv.All( + cv.only_with_esp_idf, cv.angle, cv.float_range(min=0.0, max=360.0) + ), } ).extend(cv.COMPONENT_SCHEMA) @@ -58,6 +62,8 @@ async def to_code(config): if CONF_CHANNEL in config: cg.add(var.set_channel(config[CONF_CHANNEL])) cg.add(var.set_frequency(config[CONF_FREQUENCY])) + if CONF_PHASE_ANGLE in config: + cg.add(var.set_phase_angle(config[CONF_PHASE_ANGLE])) @automation.register_action( diff --git a/tests/components/cwww/test.esp32-c3-idf.yaml b/tests/components/cwww/test.esp32-c3-idf.yaml index c829ca2a2b..2760a167ee 100644 --- a/tests/components/cwww/test.esp32-c3-idf.yaml +++ b/tests/components/cwww/test.esp32-c3-idf.yaml @@ -2,9 +2,12 @@ output: - platform: ledc id: light_output_1 pin: 1 + channel: 0 - platform: ledc id: light_output_2 pin: 2 + channel: 1 + phase_angle: 180° light: - platform: cwww diff --git a/tests/components/cwww/test.esp32-idf.yaml b/tests/components/cwww/test.esp32-idf.yaml index f108d96ad3..27fa160e56 100644 --- a/tests/components/cwww/test.esp32-idf.yaml +++ b/tests/components/cwww/test.esp32-idf.yaml @@ -2,9 +2,12 @@ output: - platform: ledc id: light_output_1 pin: 12 + channel: 0 - platform: ledc id: light_output_2 pin: 13 + channel: 1 + phase_angle: 180° light: - platform: cwww From 98466cb7f5edf1dd4540efc76ff1a5f6f7b21ff8 Mon Sep 17 00:00:00 2001 From: Jasper Albering Date: Wed, 20 Mar 2024 09:17:59 +0100 Subject: [PATCH 142/189] sm2135: add separate_modes option to support different chip variants (#6152) --- esphome/components/sm2135/__init__.py | 3 +++ esphome/components/sm2135/sm2135.cpp | 31 +++++++++++++++++---------- esphome/components/sm2135/sm2135.h | 3 +++ 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/esphome/components/sm2135/__init__.py b/esphome/components/sm2135/__init__.py index ce78d5337f..52128f1f24 100644 --- a/esphome/components/sm2135/__init__.py +++ b/esphome/components/sm2135/__init__.py @@ -15,6 +15,7 @@ SM2135 = sm2135_ns.class_("SM2135", cg.Component) CONF_RGB_CURRENT = "rgb_current" CONF_CW_CURRENT = "cw_current" +CONF_SEPARATE_MODES = "separate_modes" SM2135Current = sm2135_ns.enum("SM2135Current") @@ -51,6 +52,7 @@ CONFIG_SCHEMA = cv.Schema( cv.Required(CONF_CLOCK_PIN): pins.gpio_output_pin_schema, cv.Optional(CONF_RGB_CURRENT, "20mA"): cv.enum(DRIVE_STRENGTHS_RGB), cv.Optional(CONF_CW_CURRENT, "10mA"): cv.enum(DRIVE_STRENGTHS_CW), + cv.Optional(CONF_SEPARATE_MODES, default=True): cv.boolean, } ).extend(cv.COMPONENT_SCHEMA) @@ -66,3 +68,4 @@ async def to_code(config): cg.add(var.set_rgb_current(config[CONF_RGB_CURRENT])) cg.add(var.set_cw_current(config[CONF_CW_CURRENT])) + cg.add(var.set_separate_modes(config[CONF_SEPARATE_MODES])) diff --git a/esphome/components/sm2135/sm2135.cpp b/esphome/components/sm2135/sm2135.cpp index f9cd4235ed..9a576859ac 100644 --- a/esphome/components/sm2135/sm2135.cpp +++ b/esphome/components/sm2135/sm2135.cpp @@ -97,23 +97,32 @@ void SM2135::loop() { this->write_byte_(SM2135_ADDR_MC); this->write_byte_(current_mask_); - if (this->update_channel_ == 3 || this->update_channel_ == 4) { - // No color so must be Cold/Warm + if (this->separate_modes_) { + if (this->update_channel_ == 3 || this->update_channel_ == 4) { + // No color so must be Cold/Warm - this->write_byte_(SM2135_CW); - this->sm2135_stop_(); - delay(1); - this->sm2135_start_(); - this->write_byte_(SM2135_ADDR_C); - this->write_byte_(this->pwm_amounts_[4]); // Warm - this->write_byte_(this->pwm_amounts_[3]); // Cold + this->write_byte_(SM2135_CW); + this->sm2135_stop_(); + delay(1); + this->sm2135_start_(); + this->write_byte_(SM2135_ADDR_C); + this->write_byte_(this->pwm_amounts_[4]); // Warm + this->write_byte_(this->pwm_amounts_[3]); // Cold + } else { + // Color + + this->write_byte_(SM2135_RGB); + this->write_byte_(this->pwm_amounts_[1]); // Green + this->write_byte_(this->pwm_amounts_[0]); // Red + this->write_byte_(this->pwm_amounts_[2]); // Blue + } } else { - // Color - this->write_byte_(SM2135_RGB); this->write_byte_(this->pwm_amounts_[1]); // Green this->write_byte_(this->pwm_amounts_[0]); // Red this->write_byte_(this->pwm_amounts_[2]); // Blue + this->write_byte_(this->pwm_amounts_[4]); // Warm + this->write_byte_(this->pwm_amounts_[3]); // Cold } this->sm2135_stop_(); diff --git a/esphome/components/sm2135/sm2135.h b/esphome/components/sm2135/sm2135.h index a557fc3287..6f207d093a 100644 --- a/esphome/components/sm2135/sm2135.h +++ b/esphome/components/sm2135/sm2135.h @@ -39,6 +39,8 @@ class SM2135 : public Component { this->current_mask_ = (this->rgb_current_ << 4) | this->cw_current_; } + void set_separate_modes(bool separate_modes) { this->separate_modes_ = separate_modes; } + void setup() override; void dump_config() override; @@ -78,6 +80,7 @@ class SM2135 : public Component { uint8_t current_mask_; SM2135Current rgb_current_; SM2135Current cw_current_; + bool separate_modes_; uint8_t update_channel_; std::vector pwm_amounts_; bool update_{true}; From 0cb1cc9e1c1ee2ada27b81b7f6fad54f6b2fea63 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Wed, 20 Mar 2024 19:20:42 +1100 Subject: [PATCH 143/189] AHT10: fix temperature-only operation; add warning/error messages (#6405) --- esphome/components/aht10/aht10.cpp | 23 ++++++++++------------- esphome/components/aht10/aht10.h | 1 - 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/esphome/components/aht10/aht10.cpp b/esphome/components/aht10/aht10.cpp index d5af06c2a2..d812d8ef2d 100644 --- a/esphome/components/aht10/aht10.cpp +++ b/esphome/components/aht10/aht10.cpp @@ -15,7 +15,6 @@ #include "aht10.h" #include "esphome/core/log.h" #include "esphome/core/hal.h" -#include namespace esphome { namespace aht10 { @@ -27,7 +26,7 @@ static const uint8_t AHT10_MEASURE_CMD[] = {0xAC, 0x33, 0x00}; static const uint8_t AHT10_SOFTRESET_CMD[] = {0xBA}; static const uint8_t AHT10_DEFAULT_DELAY = 5; // ms, for initialization and temperature measurement -static const uint8_t AHT10_HUMIDITY_DELAY = 30; // ms +static const uint8_t AHT10_READ_DELAY = 80; // ms, time to wait for conversion result static const uint8_t AHT10_SOFTRESET_DELAY = 30; // ms static const uint8_t AHT10_ATTEMPTS = 3; // safety margin, normally 3 attempts are enough: 3*30=90ms @@ -36,7 +35,6 @@ static const uint8_t AHT10_INIT_ATTEMPTS = 10; static const uint8_t AHT10_STATUS_BUSY = 0x80; void AHT10Component::setup() { - this->read_delay_ = this->humidity_sensor_ != nullptr ? AHT10_HUMIDITY_DELAY : AHT10_DEFAULT_DELAY; if (this->write(AHT10_SOFTRESET_CMD, sizeof(AHT10_SOFTRESET_CMD)) != i2c::ERROR_OK) { ESP_LOGE(TAG, "Reset AHT10 failed!"); } @@ -87,19 +85,19 @@ void AHT10Component::setup() { void AHT10Component::restart_read_() { if (this->read_count_ == AHT10_ATTEMPTS) { this->read_count_ = 0; - ESP_LOGE(TAG, "Measurements reading timed-out!"); - this->status_set_error(); + this->status_set_error("Measurements reading timed-out!"); return; } this->read_count_++; - this->set_timeout(this->read_delay_, [this]() { this->read_data_(); }); + this->set_timeout(AHT10_READ_DELAY, [this]() { this->read_data_(); }); } void AHT10Component::read_data_() { uint8_t data[6]; - ESP_LOGD(TAG, "Read attempt %d at %ums", this->read_count_, (unsigned) (millis() - this->start_time_)); + if (this->read_count_ > 1) + ESP_LOGD(TAG, "Read attempt %d at %ums", this->read_count_, (unsigned) (millis() - this->start_time_)); if (this->read(data, 6) != i2c::ERROR_OK) { - ESP_LOGD(TAG, "Communication with AHT10 failed, waiting..."); + this->status_set_warning("AHT10 read failed, retrying soon"); this->restart_read_(); return; } @@ -116,14 +114,14 @@ void AHT10Component::read_data_() { } else { ESP_LOGD(TAG, "ATH10 Unrealistic humidity (0x0), retrying..."); if (this->write(AHT10_MEASURE_CMD, sizeof(AHT10_MEASURE_CMD)) != i2c::ERROR_OK) { - ESP_LOGE(TAG, "Communication with AHT10 failed!"); - this->status_set_warning(); + this->status_set_warning("Communication with AHT10 failed!"); } this->restart_read_(); return; } } - ESP_LOGD(TAG, "Success at %ums", (unsigned) (millis() - this->start_time_)); + if (this->read_count_ > 1) + ESP_LOGD(TAG, "Success at %ums", (unsigned) (millis() - this->start_time_)); uint32_t raw_temperature = ((data[3] & 0x0F) << 16) | (data[4] << 8) | data[5]; uint32_t raw_humidity = ((data[1] << 16) | (data[2] << 8) | data[3]) >> 4; @@ -151,8 +149,7 @@ void AHT10Component::update() { return; this->start_time_ = millis(); if (this->write(AHT10_MEASURE_CMD, sizeof(AHT10_MEASURE_CMD)) != i2c::ERROR_OK) { - ESP_LOGE(TAG, "Communication with AHT10 failed!"); - this->status_set_warning(); + this->status_set_warning("Communication with AHT10 failed!"); return; } this->restart_read_(); diff --git a/esphome/components/aht10/aht10.h b/esphome/components/aht10/aht10.h index 76f051878e..a3320c77e0 100644 --- a/esphome/components/aht10/aht10.h +++ b/esphome/components/aht10/aht10.h @@ -27,7 +27,6 @@ class AHT10Component : public PollingComponent, public i2c::I2CDevice { sensor::Sensor *humidity_sensor_{nullptr}; AHT10Variant variant_{}; unsigned read_count_{}; - unsigned read_delay_{}; void read_data_(); void restart_read_(); uint32_t start_time_{}; From b637fb3adc8dc0d0620f706dc3f20b5cbb53fcbe Mon Sep 17 00:00:00 2001 From: DAVe3283 Date: Wed, 20 Mar 2024 17:57:27 -0600 Subject: [PATCH 144/189] Fix logger compile error on ESP32-C6 (#6323) --- esphome/components/logger/logger_esp32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/logger/logger_esp32.cpp b/esphome/components/logger/logger_esp32.cpp index 7c4d6781c9..740e086f92 100644 --- a/esphome/components/logger/logger_esp32.cpp +++ b/esphome/components/logger/logger_esp32.cpp @@ -129,7 +129,7 @@ void Logger::pre_setup() { this->uart_num_ = UART_NUM_2; break; #endif -#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) +#ifdef USE_LOGGER_USB_CDC case UART_SELECTION_USB_CDC: this->uart_num_ = -1; break; From 13059805d074173878132501c58727be286a3d54 Mon Sep 17 00:00:00 2001 From: Moriah Morgan Date: Wed, 20 Mar 2024 19:40:14 -0500 Subject: [PATCH 145/189] Add support for new modes in Tuya Climate (#5159) * Add support support for new modes Added support for Fan Only Mode, Dry Mode, Swing Mode and Fan Speed Control. Also added/fixed support for entity states syncing with current operation mode. * Add support for more climate modes in climate.tuya Added support for Fan Only Mode, Dry Mode, Swing Mode and Fan Speed Control. Also added/fixed support for entity states syncing with current operation mode. This commit fixes the namespace, because I uploaded the test files to start with. * Code Formatting Changes per Clang format. * More clang formatting fixes. * Breaking Change: Group YAML entries by type Add grouping to Preset, Swing Mode, Fan Speed and Active State. This is a breaking change. * Formatting Changes for validation Formatting changes to be compliant with black and flake8. Also changed constants to match expected format. * More constant value fixes * Final black formatting check? * Changes to init.py according to reviewer requests Make changes to _init_.py according to https://github.com/esphome/esphome/pull/5159/files/649b923804c05fa6ee750e824e3d7d70fadeabd9#r1278620976, https://github.com/esphome/esphome/pull/5159/files/649b923804c05fa6ee750e824e3d7d70fadeabd9#r1278621039, https://github.com/esphome/esphome/pull/5159/files/649b923804c05fa6ee750e824e3d7d70fadeabd9#r1278620904, and https://github.com/esphome/esphome/pull/5159/files/649b923804c05fa6ee750e824e3d7d70fadeabd9#r1278620549 Also put Sleep preset in its own config block to be consistent with other presets and fix logic for validate_cooling_values function to better align with existing documentation. * Commit reviewed change Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> * update deprecated config option wording * add "this->" to member variables that were missed adding "this->" to some member variables in the swing_mode function. * Update _init_.py to use Python 3.8 Walrus operator Adding Walrus Operator in the to_code function for _init_.py similar to https://github.com/esphome/esphome/pull/5181 * Fix Temperature_Multiplier config entry for code generation --------- Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Co-authored-by: Keith Burzinski --- esphome/components/tuya/climate/__init__.py | 246 ++++++++++++------ .../components/tuya/climate/tuya_climate.cpp | 241 ++++++++++++++++- .../components/tuya/climate/tuya_climate.h | 42 +++ 3 files changed, 449 insertions(+), 80 deletions(-) diff --git a/esphome/components/tuya/climate/__init__.py b/esphome/components/tuya/climate/__init__.py index 199c2eabeb..b3d401e5a4 100644 --- a/esphome/components/tuya/climate/__init__.py +++ b/esphome/components/tuya/climate/__init__.py @@ -7,15 +7,22 @@ from esphome.const import ( CONF_SWITCH_DATAPOINT, CONF_SUPPORTS_COOL, CONF_SUPPORTS_HEAT, + CONF_PRESET, + CONF_SWING_MODE, + CONF_FAN_MODE, + CONF_TEMPERATURE, ) from .. import tuya_ns, CONF_TUYA_ID, Tuya DEPENDENCIES = ["tuya"] CODEOWNERS = ["@jesserockz"] -CONF_ACTIVE_STATE_DATAPOINT = "active_state_datapoint" -CONF_ACTIVE_STATE_HEATING_VALUE = "active_state_heating_value" -CONF_ACTIVE_STATE_COOLING_VALUE = "active_state_cooling_value" +CONF_ACTIVE_STATE = "active_state" +CONF_DATAPOINT = "datapoint" +CONF_HEATING_VALUE = "heating_value" +CONF_COOLING_VALUE = "cooling_value" +CONF_DRYING_VALUE = "drying_value" +CONF_FANONLY_VALUE = "fanonly_value" CONF_HEATING_STATE_PIN = "heating_state_pin" CONF_COOLING_STATE_PIN = "cooling_state_pin" CONF_TARGET_TEMPERATURE_DATAPOINT = "target_temperature_datapoint" @@ -23,9 +30,17 @@ CONF_CURRENT_TEMPERATURE_DATAPOINT = "current_temperature_datapoint" CONF_TEMPERATURE_MULTIPLIER = "temperature_multiplier" CONF_CURRENT_TEMPERATURE_MULTIPLIER = "current_temperature_multiplier" CONF_TARGET_TEMPERATURE_MULTIPLIER = "target_temperature_multiplier" -CONF_ECO_DATAPOINT = "eco_datapoint" -CONF_ECO_TEMPERATURE = "eco_temperature" +CONF_ECO = "eco" +CONF_SLEEP = "sleep" +CONF_SLEEP_DATAPOINT = "sleep_datapoint" CONF_REPORTS_FAHRENHEIT = "reports_fahrenheit" +CONF_VERTICAL_DATAPOINT = "vertical_datapoint" +CONF_HORIZONTAL_DATAPOINT = "horizontal_datapoint" +CONF_LOW_VALUE = "low_value" +CONF_MEDIUM_VALUE = "medium_value" +CONF_MIDDLE_VALUE = "middle_value" +CONF_HIGH_VALUE = "high_value" +CONF_AUTO_VALUE = "auto_value" TuyaClimate = tuya_ns.class_("TuyaClimate", climate.Climate, cg.Component) @@ -67,30 +82,73 @@ def validate_temperature_multipliers(value): return value -def validate_active_state_values(value): - if CONF_ACTIVE_STATE_DATAPOINT not in value: - if CONF_ACTIVE_STATE_COOLING_VALUE in value: - raise cv.Invalid( - f"{CONF_ACTIVE_STATE_DATAPOINT} required if using " - f"{CONF_ACTIVE_STATE_COOLING_VALUE}" - ) - else: - if value[CONF_SUPPORTS_COOL] and CONF_ACTIVE_STATE_COOLING_VALUE not in value: - raise cv.Invalid( - f"{CONF_ACTIVE_STATE_COOLING_VALUE} required if using " - f"{CONF_ACTIVE_STATE_DATAPOINT} and device supports cooling" - ) +def validate_cooling_values(value): + if CONF_SUPPORTS_COOL in value: + cooling_supported = value[CONF_SUPPORTS_COOL] + if not cooling_supported and CONF_ACTIVE_STATE in value: + active_state_config = value[CONF_ACTIVE_STATE] + if ( + CONF_COOLING_VALUE in active_state_config + or CONF_COOLING_STATE_PIN in value + ): + raise cv.Invalid( + f"Device does not support cooling, but {CONF_COOLING_VALUE} or {CONF_COOLING_STATE_PIN} specified." + f" Please add '{CONF_SUPPORTS_COOL}: true' to your configuration." + ) + elif cooling_supported and CONF_ACTIVE_STATE in value: + active_state_config = value[CONF_ACTIVE_STATE] + if ( + CONF_COOLING_VALUE not in active_state_config + and CONF_COOLING_STATE_PIN not in value + ): + raise cv.Invalid( + f"Either {CONF_ACTIVE_STATE} {CONF_COOLING_VALUE} or {CONF_COOLING_STATE_PIN} is required if" + f" {CONF_SUPPORTS_COOL}: true' is in your configuration." + ) return value -def validate_eco_values(value): - if CONF_ECO_TEMPERATURE in value and CONF_ECO_DATAPOINT not in value: - raise cv.Invalid( - f"{CONF_ECO_DATAPOINT} required if using {CONF_ECO_TEMPERATURE}" - ) - return value +ACTIVE_STATES = cv.Schema( + { + cv.Required(CONF_DATAPOINT): cv.uint8_t, + cv.Optional(CONF_HEATING_VALUE, default=1): cv.uint8_t, + cv.Optional(CONF_COOLING_VALUE): cv.uint8_t, + cv.Optional(CONF_DRYING_VALUE): cv.uint8_t, + cv.Optional(CONF_FANONLY_VALUE): cv.uint8_t, + }, +) +PRESETS = cv.Schema( + { + cv.Optional(CONF_ECO): { + cv.Required(CONF_DATAPOINT): cv.uint8_t, + cv.Optional(CONF_TEMPERATURE): cv.temperature, + }, + cv.Optional(CONF_SLEEP): { + cv.Required(CONF_DATAPOINT): cv.uint8_t, + }, + }, +) + +FAN_MODES = cv.Schema( + { + cv.Required(CONF_DATAPOINT): cv.uint8_t, + cv.Optional(CONF_AUTO_VALUE): cv.uint8_t, + cv.Optional(CONF_LOW_VALUE): cv.uint8_t, + cv.Optional(CONF_MEDIUM_VALUE): cv.uint8_t, + cv.Optional(CONF_MIDDLE_VALUE): cv.uint8_t, + cv.Optional(CONF_HIGH_VALUE): cv.uint8_t, + } +) + +SWING_MODES = cv.Schema( + { + cv.Optional(CONF_VERTICAL_DATAPOINT): cv.uint8_t, + cv.Optional(CONF_HORIZONTAL_DATAPOINT): cv.uint8_t, + }, +) + CONFIG_SCHEMA = cv.All( climate.CLIMATE_SCHEMA.extend( { @@ -99,9 +157,7 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_SUPPORTS_HEAT, default=True): cv.boolean, cv.Optional(CONF_SUPPORTS_COOL, default=False): cv.boolean, cv.Optional(CONF_SWITCH_DATAPOINT): cv.uint8_t, - cv.Optional(CONF_ACTIVE_STATE_DATAPOINT): cv.uint8_t, - cv.Optional(CONF_ACTIVE_STATE_HEATING_VALUE, default=1): cv.uint8_t, - cv.Optional(CONF_ACTIVE_STATE_COOLING_VALUE): cv.uint8_t, + cv.Optional(CONF_ACTIVE_STATE): ACTIVE_STATES, cv.Optional(CONF_HEATING_STATE_PIN): pins.gpio_input_pin_schema, cv.Optional(CONF_COOLING_STATE_PIN): pins.gpio_input_pin_schema, cv.Optional(CONF_TARGET_TEMPERATURE_DATAPOINT): cv.uint8_t, @@ -109,17 +165,32 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_TEMPERATURE_MULTIPLIER): cv.positive_float, cv.Optional(CONF_CURRENT_TEMPERATURE_MULTIPLIER): cv.positive_float, cv.Optional(CONF_TARGET_TEMPERATURE_MULTIPLIER): cv.positive_float, - cv.Optional(CONF_ECO_DATAPOINT): cv.uint8_t, - cv.Optional(CONF_ECO_TEMPERATURE): cv.temperature, cv.Optional(CONF_REPORTS_FAHRENHEIT, default=False): cv.boolean, + cv.Optional(CONF_PRESET): PRESETS, + cv.Optional(CONF_FAN_MODE): FAN_MODES, + cv.Optional(CONF_SWING_MODE): SWING_MODES, + cv.Optional("active_state_datapoint"): cv.invalid( + "'active_state_datapoint' has been moved inside of the 'active_state' config block as 'datapoint'" + ), + cv.Optional("active_state_heating_value"): cv.invalid( + "'active_state_heating_value' has been moved inside of the 'active_state' config block as 'heating_value'" + ), + cv.Optional("active_state_cooling_value"): cv.invalid( + "'active_state_cooling_value' has been moved inside of the 'active_state' config block as 'cooling_value'" + ), + cv.Optional("eco_datapoint"): cv.invalid( + "'eco_datapoint' has been moved inside of the 'eco' config block under 'preset' as 'datapoint'" + ), + cv.Optional("eco_temperature"): cv.invalid( + "'eco_temperature' has been moved inside of the 'eco' config block under 'preset' as 'temperature'" + ), } ).extend(cv.COMPONENT_SCHEMA), cv.has_at_least_one_key(CONF_TARGET_TEMPERATURE_DATAPOINT, CONF_SWITCH_DATAPOINT), validate_temperature_multipliers, - validate_active_state_values, - cv.has_at_most_one_key(CONF_ACTIVE_STATE_DATAPOINT, CONF_HEATING_STATE_PIN), - cv.has_at_most_one_key(CONF_ACTIVE_STATE_DATAPOINT, CONF_COOLING_STATE_PIN), - validate_eco_values, + validate_cooling_values, + cv.has_at_most_one_key(CONF_ACTIVE_STATE, CONF_HEATING_STATE_PIN), + cv.has_at_most_one_key(CONF_ACTIVE_STATE, CONF_COOLING_STATE_PIN), ) @@ -133,61 +204,78 @@ async def to_code(config): cg.add(var.set_supports_heat(config[CONF_SUPPORTS_HEAT])) cg.add(var.set_supports_cool(config[CONF_SUPPORTS_COOL])) - if CONF_SWITCH_DATAPOINT in config: - cg.add(var.set_switch_id(config[CONF_SWITCH_DATAPOINT])) - if CONF_ACTIVE_STATE_DATAPOINT in config: - cg.add(var.set_active_state_id(config[CONF_ACTIVE_STATE_DATAPOINT])) - if CONF_ACTIVE_STATE_HEATING_VALUE in config: - cg.add( - var.set_active_state_heating_value( - config[CONF_ACTIVE_STATE_HEATING_VALUE] - ) - ) - if CONF_ACTIVE_STATE_COOLING_VALUE in config: - cg.add( - var.set_active_state_cooling_value( - config[CONF_ACTIVE_STATE_COOLING_VALUE] - ) - ) + if switch_datapoint := config.get(CONF_SWITCH_DATAPOINT): + cg.add(var.set_switch_id(switch_datapoint)) + + if active_state_config := config.get(CONF_ACTIVE_STATE): + cg.add(var.set_active_state_id(CONF_DATAPOINT)) + if (heating_value := active_state_config.get(CONF_HEATING_VALUE)) is not None: + cg.add(var.set_active_state_heating_value(heating_value)) + if (cooling_value := active_state_config.get(CONF_COOLING_VALUE)) is not None: + cg.add(var.set_active_state_cooling_value(cooling_value)) + if (drying_value := active_state_config.get(CONF_DRYING_VALUE)) is not None: + cg.add(var.set_active_state_drying_value(drying_value)) + if (fanonly_value := active_state_config.get(CONF_FANONLY_VALUE)) is not None: + cg.add(var.set_active_state_fanonly_value(fanonly_value)) else: - if CONF_HEATING_STATE_PIN in config: + if heating_state_pin_config := config.get(CONF_HEATING_STATE_PIN): heating_state_pin = await cg.gpio_pin_expression( - config[CONF_HEATING_STATE_PIN] + config(heating_state_pin_config) ) cg.add(var.set_heating_state_pin(heating_state_pin)) - if CONF_COOLING_STATE_PIN in config: + if cooling_state_pin_config := config.get(CONF_COOLING_STATE_PIN): cooling_state_pin = await cg.gpio_pin_expression( - config[CONF_COOLING_STATE_PIN] + config(cooling_state_pin_config) ) cg.add(var.set_cooling_state_pin(cooling_state_pin)) - if CONF_TARGET_TEMPERATURE_DATAPOINT in config: - cg.add(var.set_target_temperature_id(config[CONF_TARGET_TEMPERATURE_DATAPOINT])) - if CONF_CURRENT_TEMPERATURE_DATAPOINT in config: - cg.add( - var.set_current_temperature_id(config[CONF_CURRENT_TEMPERATURE_DATAPOINT]) - ) - if CONF_TEMPERATURE_MULTIPLIER in config: - cg.add( - var.set_target_temperature_multiplier(config[CONF_TEMPERATURE_MULTIPLIER]) - ) - cg.add( - var.set_current_temperature_multiplier(config[CONF_TEMPERATURE_MULTIPLIER]) - ) + + if target_temperature_datapoint := config.get(CONF_TARGET_TEMPERATURE_DATAPOINT): + cg.add(var.set_target_temperature_id(target_temperature_datapoint)) + if current_temperature_datapoint := config.get(CONF_CURRENT_TEMPERATURE_DATAPOINT): + cg.add(var.set_current_temperature_id(current_temperature_datapoint)) + + if temperature_multiplier := config.get(CONF_TEMPERATURE_MULTIPLIER): + cg.add(var.set_target_temperature_multiplier(temperature_multiplier)) + cg.add(var.set_current_temperature_multiplier(temperature_multiplier)) else: - cg.add( - var.set_current_temperature_multiplier( - config[CONF_CURRENT_TEMPERATURE_MULTIPLIER] + if current_temperature_multiplier := config.get( + CONF_CURRENT_TEMPERATURE_MULTIPLIER + ): + cg.add( + var.set_current_temperature_multiplier(current_temperature_multiplier) ) - ) - cg.add( - var.set_target_temperature_multiplier( - config[CONF_TARGET_TEMPERATURE_MULTIPLIER] - ) - ) - if CONF_ECO_DATAPOINT in config: - cg.add(var.set_eco_id(config[CONF_ECO_DATAPOINT])) - if CONF_ECO_TEMPERATURE in config: - cg.add(var.set_eco_temperature(config[CONF_ECO_TEMPERATURE])) + if target_temperature_multiplier := config.get( + CONF_TARGET_TEMPERATURE_MULTIPLIER + ): + cg.add(var.set_target_temperature_multiplier(target_temperature_multiplier)) if config[CONF_REPORTS_FAHRENHEIT]: cg.add(var.set_reports_fahrenheit()) + + if preset_config := config.get(CONF_PRESET, {}): + if eco_config := preset_config.get(CONF_ECO, {}): + cg.add(var.set_eco_id(CONF_DATAPOINT)) + if eco_temperature := eco_config.get(CONF_TEMPERATURE): + cg.add(var.set_eco_temperature(eco_temperature)) + if CONF_SLEEP in preset_config: + cg.add(var.set_sleep_id(CONF_DATAPOINT)) + + if swing_mode_config := config.get(CONF_SWING_MODE): + if swing_vertical_datapoint := swing_mode_config.get(CONF_VERTICAL_DATAPOINT): + cg.add(var.set_swing_vertical_id(swing_vertical_datapoint)) + if swing_horizontal_datapoint := swing_mode_config.get( + CONF_HORIZONTAL_DATAPOINT + ): + cg.add(var.set_swing_horizontal_id(swing_horizontal_datapoint)) + if fan_mode_config := config.get(CONF_FAN_MODE): + cg.add(var.set_fan_speed_id(CONF_DATAPOINT)) + if (fan_auto_value := fan_mode_config.get(CONF_AUTO_VALUE)) is not None: + cg.add(var.set_fan_speed_auto_value(fan_auto_value)) + if (fan_low_value := fan_mode_config.get(CONF_LOW_VALUE)) is not None: + cg.add(var.set_fan_speed_low_value(fan_low_value)) + if (fan_medium_value := fan_mode_config.get(CONF_MEDIUM_VALUE)) is not None: + cg.add(var.set_fan_speed_medium_value(fan_medium_value)) + if (fan_middle_value := fan_mode_config.get(CONF_MIDDLE_VALUE)) is not None: + cg.add(var.set_fan_speed_middle_value(fan_middle_value)) + if (fan_high_value := fan_mode_config.get(CONF_HIGH_VALUE)) is not None: + cg.add(var.set_fan_speed_high_value(fan_high_value)) diff --git a/esphome/components/tuya/climate/tuya_climate.cpp b/esphome/components/tuya/climate/tuya_climate.cpp index 687764e30f..274e19a69e 100644 --- a/esphome/components/tuya/climate/tuya_climate.cpp +++ b/esphome/components/tuya/climate/tuya_climate.cpp @@ -75,6 +75,41 @@ void TuyaClimate::setup() { this->publish_state(); }); } + if (this->sleep_id_.has_value()) { + this->parent_->register_listener(*this->sleep_id_, [this](const TuyaDatapoint &datapoint) { + this->sleep_ = datapoint.value_bool; + ESP_LOGV(TAG, "MCU reported sleep is: %s", ONOFF(this->sleep_)); + this->compute_preset_(); + this->compute_target_temperature_(); + this->publish_state(); + }); + } + if (this->swing_vertical_id_.has_value()) { + this->parent_->register_listener(*this->swing_vertical_id_, [this](const TuyaDatapoint &datapoint) { + this->swing_vertical_ = datapoint.value_bool; + ESP_LOGV(TAG, "MCU reported vertical swing is: %s", ONOFF(datapoint.value_bool)); + this->compute_swingmode_(); + this->publish_state(); + }); + } + + if (this->swing_horizontal_id_.has_value()) { + this->parent_->register_listener(*this->swing_horizontal_id_, [this](const TuyaDatapoint &datapoint) { + this->swing_horizontal_ = datapoint.value_bool; + ESP_LOGV(TAG, "MCU reported horizontal swing is: %s", ONOFF(datapoint.value_bool)); + this->compute_swingmode_(); + this->publish_state(); + }); + } + + if (this->fan_speed_id_.has_value()) { + this->parent_->register_listener(*this->fan_speed_id_, [this](const TuyaDatapoint &datapoint) { + ESP_LOGV(TAG, "MCU reported Fan Speed Mode is: %u", datapoint.value_enum); + this->fan_state_ = datapoint.value_enum; + this->compute_fanmode_(); + this->publish_state(); + }); + } } void TuyaClimate::loop() { @@ -110,8 +145,22 @@ void TuyaClimate::control(const climate::ClimateCall &call) { const bool switch_state = *call.get_mode() != climate::CLIMATE_MODE_OFF; ESP_LOGV(TAG, "Setting switch: %s", ONOFF(switch_state)); this->parent_->set_boolean_datapoint_value(*this->switch_id_, switch_state); + const climate::ClimateMode new_mode = *call.get_mode(); + + if (new_mode == climate::CLIMATE_MODE_HEAT && this->supports_heat_) { + this->parent_->set_enum_datapoint_value(*this->active_state_id_, *this->active_state_heating_value_); + } else if (new_mode == climate::CLIMATE_MODE_COOL && this->supports_cool_) { + this->parent_->set_enum_datapoint_value(*this->active_state_id_, *this->active_state_cooling_value_); + } else if (new_mode == climate::CLIMATE_MODE_DRY && this->active_state_drying_value_.has_value()) { + this->parent_->set_enum_datapoint_value(*this->active_state_id_, *this->active_state_drying_value_); + } else if (new_mode == climate::CLIMATE_MODE_FAN_ONLY && this->active_state_fanonly_value_.has_value()) { + this->parent_->set_enum_datapoint_value(*this->active_state_id_, *this->active_state_fanonly_value_); + } } + control_swing_mode_(call); + control_fan_mode_(call); + if (call.get_target_temperature().has_value()) { float target_temperature = *call.get_target_temperature(); if (this->reports_fahrenheit_) @@ -129,6 +178,106 @@ void TuyaClimate::control(const climate::ClimateCall &call) { ESP_LOGV(TAG, "Setting eco: %s", ONOFF(eco)); this->parent_->set_boolean_datapoint_value(*this->eco_id_, eco); } + if (this->sleep_id_.has_value()) { + const bool sleep = preset == climate::CLIMATE_PRESET_SLEEP; + ESP_LOGV(TAG, "Setting sleep: %s", ONOFF(sleep)); + this->parent_->set_boolean_datapoint_value(*this->sleep_id_, sleep); + } + } +} + +void TuyaClimate::control_swing_mode_(const climate::ClimateCall &call) { + bool vertical_swing_changed = false; + bool horizontal_swing_changed = false; + + if (call.get_swing_mode().has_value()) { + const auto swing_mode = *call.get_swing_mode(); + + switch (swing_mode) { + case climate::CLIMATE_SWING_OFF: + if (swing_vertical_ || swing_horizontal_) { + this->swing_vertical_ = false; + this->swing_horizontal_ = false; + vertical_swing_changed = true; + horizontal_swing_changed = true; + } + break; + + case climate::CLIMATE_SWING_BOTH: + if (!swing_vertical_ || !swing_horizontal_) { + this->swing_vertical_ = true; + this->swing_horizontal_ = true; + vertical_swing_changed = true; + horizontal_swing_changed = true; + } + break; + + case climate::CLIMATE_SWING_VERTICAL: + if (!swing_vertical_ || swing_horizontal_) { + this->swing_vertical_ = true; + this->swing_horizontal_ = false; + vertical_swing_changed = true; + horizontal_swing_changed = true; + } + break; + + case climate::CLIMATE_SWING_HORIZONTAL: + if (swing_vertical_ || !swing_horizontal_) { + this->swing_vertical_ = false; + this->swing_horizontal_ = true; + vertical_swing_changed = true; + horizontal_swing_changed = true; + } + break; + + default: + break; + } + } + + if (vertical_swing_changed && this->swing_vertical_id_.has_value()) { + ESP_LOGV(TAG, "Setting vertical swing: %s", ONOFF(swing_vertical_)); + this->parent_->set_boolean_datapoint_value(*this->swing_vertical_id_, swing_vertical_); + } + + if (horizontal_swing_changed && this->swing_horizontal_id_.has_value()) { + ESP_LOGV(TAG, "Setting horizontal swing: %s", ONOFF(swing_horizontal_)); + this->parent_->set_boolean_datapoint_value(*this->swing_horizontal_id_, swing_horizontal_); + } + + // Publish the state after updating the swing mode + this->publish_state(); +} + +void TuyaClimate::control_fan_mode_(const climate::ClimateCall &call) { + if (call.get_fan_mode().has_value()) { + climate::ClimateFanMode fan_mode = *call.get_fan_mode(); + + uint8_t tuya_fan_speed; + switch (fan_mode) { + case climate::CLIMATE_FAN_LOW: + tuya_fan_speed = *fan_speed_low_value_; + break; + case climate::CLIMATE_FAN_MEDIUM: + tuya_fan_speed = *fan_speed_medium_value_; + break; + case climate::CLIMATE_FAN_MIDDLE: + tuya_fan_speed = *fan_speed_middle_value_; + break; + case climate::CLIMATE_FAN_HIGH: + tuya_fan_speed = *fan_speed_high_value_; + break; + case climate::CLIMATE_FAN_AUTO: + tuya_fan_speed = *fan_speed_auto_value_; + break; + default: + tuya_fan_speed = 0; + break; + } + + if (this->fan_speed_id_.has_value()) { + this->parent_->set_enum_datapoint_value(*this->fan_speed_id_, tuya_fan_speed); + } } } @@ -140,10 +289,46 @@ climate::ClimateTraits TuyaClimate::traits() { traits.add_supported_mode(climate::CLIMATE_MODE_HEAT); if (supports_cool_) traits.add_supported_mode(climate::CLIMATE_MODE_COOL); + if (this->active_state_drying_value_.has_value()) + traits.add_supported_mode(climate::CLIMATE_MODE_DRY); + if (this->active_state_fanonly_value_.has_value()) + traits.add_supported_mode(climate::CLIMATE_MODE_FAN_ONLY); if (this->eco_id_.has_value()) { - traits.add_supported_preset(climate::CLIMATE_PRESET_NONE); traits.add_supported_preset(climate::CLIMATE_PRESET_ECO); } + if (this->sleep_id_.has_value()) { + traits.add_supported_preset(climate::CLIMATE_PRESET_SLEEP); + } + if (this->sleep_id_.has_value() || this->eco_id_.has_value()) { + traits.add_supported_preset(climate::CLIMATE_PRESET_NONE); + } + if (this->swing_vertical_id_.has_value() && this->swing_horizontal_id_.has_value()) { + std::set supported_swing_modes = { + climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_BOTH, climate::CLIMATE_SWING_VERTICAL, + climate::CLIMATE_SWING_HORIZONTAL}; + traits.set_supported_swing_modes(std::move(supported_swing_modes)); + } else if (this->swing_vertical_id_.has_value()) { + std::set supported_swing_modes = {climate::CLIMATE_SWING_OFF, + climate::CLIMATE_SWING_VERTICAL}; + traits.set_supported_swing_modes(std::move(supported_swing_modes)); + } else if (this->swing_horizontal_id_.has_value()) { + std::set supported_swing_modes = {climate::CLIMATE_SWING_OFF, + climate::CLIMATE_SWING_HORIZONTAL}; + traits.set_supported_swing_modes(std::move(supported_swing_modes)); + } + + if (fan_speed_id_) { + if (fan_speed_low_value_) + traits.add_supported_fan_mode(climate::CLIMATE_FAN_LOW); + if (fan_speed_medium_value_) + traits.add_supported_fan_mode(climate::CLIMATE_FAN_MEDIUM); + if (fan_speed_middle_value_) + traits.add_supported_fan_mode(climate::CLIMATE_FAN_MIDDLE); + if (fan_speed_high_value_) + traits.add_supported_fan_mode(climate::CLIMATE_FAN_HIGH); + if (fan_speed_auto_value_) + traits.add_supported_fan_mode(climate::CLIMATE_FAN_AUTO); + } return traits; } @@ -166,16 +351,56 @@ void TuyaClimate::dump_config() { if (this->eco_id_.has_value()) { ESP_LOGCONFIG(TAG, " Eco has datapoint ID %u", *this->eco_id_); } + if (this->sleep_id_.has_value()) { + ESP_LOGCONFIG(TAG, " Sleep has datapoint ID %u", *this->sleep_id_); + } + if (this->swing_vertical_id_.has_value()) { + ESP_LOGCONFIG(TAG, " Swing Vertical has datapoint ID %u", *this->swing_vertical_id_); + } + if (this->swing_horizontal_id_.has_value()) { + ESP_LOGCONFIG(TAG, " Swing Horizontal has datapoint ID %u", *this->swing_horizontal_id_); + } } void TuyaClimate::compute_preset_() { if (this->eco_) { this->preset = climate::CLIMATE_PRESET_ECO; + } else if (this->sleep_) { + this->preset = climate::CLIMATE_PRESET_SLEEP; } else { this->preset = climate::CLIMATE_PRESET_NONE; } } +void TuyaClimate::compute_swingmode_() { + if (this->swing_vertical_ && this->swing_horizontal_) { + this->swing_mode = climate::CLIMATE_SWING_BOTH; + } else if (this->swing_vertical_) { + this->swing_mode = climate::CLIMATE_SWING_VERTICAL; + } else if (this->swing_horizontal_) { + this->swing_mode = climate::CLIMATE_SWING_HORIZONTAL; + } else { + this->swing_mode = climate::CLIMATE_SWING_OFF; + } +} + +void TuyaClimate::compute_fanmode_() { + if (this->fan_speed_id_.has_value()) { + // Use state from MCU datapoint + if (this->fan_speed_auto_value_.has_value() && this->fan_state_ == this->fan_speed_auto_value_) { + this->fan_mode = climate::CLIMATE_FAN_AUTO; + } else if (this->fan_speed_high_value_.has_value() && this->fan_state_ == this->fan_speed_high_value_) { + this->fan_mode = climate::CLIMATE_FAN_HIGH; + } else if (this->fan_speed_medium_value_.has_value() && this->fan_state_ == this->fan_speed_medium_value_) { + this->fan_mode = climate::CLIMATE_FAN_MEDIUM; + } else if (this->fan_speed_middle_value_.has_value() && this->fan_state_ == this->fan_speed_middle_value_) { + this->fan_mode = climate::CLIMATE_FAN_MIDDLE; + } else if (this->fan_speed_low_value_.has_value() && this->fan_state_ == this->fan_speed_low_value_) { + this->fan_mode = climate::CLIMATE_FAN_LOW; + } + } +} + void TuyaClimate::compute_target_temperature_() { if (this->eco_ && this->eco_temperature_.has_value()) { this->target_temperature = *this->eco_temperature_; @@ -202,16 +427,28 @@ void TuyaClimate::compute_state_() { if (this->supports_heat_ && this->active_state_heating_value_.has_value() && this->active_state_ == this->active_state_heating_value_) { target_action = climate::CLIMATE_ACTION_HEATING; + this->mode = climate::CLIMATE_MODE_HEAT; } else if (this->supports_cool_ && this->active_state_cooling_value_.has_value() && this->active_state_ == this->active_state_cooling_value_) { target_action = climate::CLIMATE_ACTION_COOLING; + this->mode = climate::CLIMATE_MODE_COOL; + } else if (this->active_state_drying_value_.has_value() && + this->active_state_ == this->active_state_drying_value_) { + target_action = climate::CLIMATE_ACTION_DRYING; + this->mode = climate::CLIMATE_MODE_DRY; + } else if (this->active_state_fanonly_value_.has_value() && + this->active_state_ == this->active_state_fanonly_value_) { + target_action = climate::CLIMATE_ACTION_FAN; + this->mode = climate::CLIMATE_MODE_FAN_ONLY; } } else if (this->heating_state_pin_ != nullptr || this->cooling_state_pin_ != nullptr) { // Use state from input pins if (this->heating_state_) { target_action = climate::CLIMATE_ACTION_HEATING; + this->mode = climate::CLIMATE_MODE_HEAT; } else if (this->cooling_state_) { target_action = climate::CLIMATE_ACTION_COOLING; + this->mode = climate::CLIMATE_MODE_COOL; } } else { // Fallback to active state calc based on temp and hysteresis @@ -219,8 +456,10 @@ void TuyaClimate::compute_state_() { if (std::abs(temp_diff) > this->hysteresis_) { if (this->supports_heat_ && temp_diff > 0) { target_action = climate::CLIMATE_ACTION_HEATING; + this->mode = climate::CLIMATE_MODE_HEAT; } else if (this->supports_cool_ && temp_diff < 0) { target_action = climate::CLIMATE_ACTION_COOLING; + this->mode = climate::CLIMATE_MODE_COOL; } } } diff --git a/esphome/components/tuya/climate/tuya_climate.h b/esphome/components/tuya/climate/tuya_climate.h index 7c18625c4e..d6258c21e1 100644 --- a/esphome/components/tuya/climate/tuya_climate.h +++ b/esphome/components/tuya/climate/tuya_climate.h @@ -18,8 +18,22 @@ class TuyaClimate : public climate::Climate, public Component { void set_active_state_id(uint8_t state_id) { this->active_state_id_ = state_id; } void set_active_state_heating_value(uint8_t value) { this->active_state_heating_value_ = value; } void set_active_state_cooling_value(uint8_t value) { this->active_state_cooling_value_ = value; } + void set_active_state_drying_value(uint8_t value) { this->active_state_drying_value_ = value; } + void set_active_state_fanonly_value(uint8_t value) { this->active_state_fanonly_value_ = value; } void set_heating_state_pin(GPIOPin *pin) { this->heating_state_pin_ = pin; } void set_cooling_state_pin(GPIOPin *pin) { this->cooling_state_pin_ = pin; } + void set_swing_vertical_id(uint8_t swing_vertical_id) { this->swing_vertical_id_ = swing_vertical_id; } + void set_swing_horizontal_id(uint8_t swing_horizontal_id) { this->swing_horizontal_id_ = swing_horizontal_id; } + void set_fan_speed_id(uint8_t fan_speed_id) { this->fan_speed_id_ = fan_speed_id; } + void set_fan_speed_low_value(uint8_t fan_speed_low_value) { this->fan_speed_low_value_ = fan_speed_low_value; } + void set_fan_speed_medium_value(uint8_t fan_speed_medium_value) { + this->fan_speed_medium_value_ = fan_speed_medium_value; + } + void set_fan_speed_middle_value(uint8_t fan_speed_middle_value) { + this->fan_speed_middle_value_ = fan_speed_middle_value; + } + void set_fan_speed_high_value(uint8_t fan_speed_high_value) { this->fan_speed_high_value_ = fan_speed_high_value; } + void set_fan_speed_auto_value(uint8_t fan_speed_auto_value) { this->fan_speed_auto_value_ = fan_speed_auto_value; } void set_target_temperature_id(uint8_t target_temperature_id) { this->target_temperature_id_ = target_temperature_id; } @@ -34,6 +48,7 @@ class TuyaClimate : public climate::Climate, public Component { } void set_eco_id(uint8_t eco_id) { this->eco_id_ = eco_id; } void set_eco_temperature(float eco_temperature) { this->eco_temperature_ = eco_temperature; } + void set_sleep_id(uint8_t sleep_id) { this->sleep_id_ = sleep_id; } void set_reports_fahrenheit() { this->reports_fahrenheit_ = true; } @@ -43,6 +58,12 @@ class TuyaClimate : public climate::Climate, public Component { /// Override control to change settings of the climate device. void control(const climate::ClimateCall &call) override; + /// Override control to change settings of swing mode. + void control_swing_mode_(const climate::ClimateCall &call); + + /// Override control to change settings of fan mode. + void control_fan_mode_(const climate::ClimateCall &call); + /// Return the traits of this controller. climate::ClimateTraits traits() override; @@ -55,6 +76,12 @@ class TuyaClimate : public climate::Climate, public Component { /// Re-compute the state of this climate controller. void compute_state_(); + /// Re-Compute the swing mode of this climate controller. + void compute_swingmode_(); + + /// Re-Compute the fan mode of this climate controller. + void compute_fanmode_(); + /// Switch the climate device to the given climate mode. void switch_to_action_(climate::ClimateAction action); @@ -65,6 +92,8 @@ class TuyaClimate : public climate::Climate, public Component { optional active_state_id_{}; optional active_state_heating_value_{}; optional active_state_cooling_value_{}; + optional active_state_drying_value_{}; + optional active_state_fanonly_value_{}; GPIOPin *heating_state_pin_{nullptr}; GPIOPin *cooling_state_pin_{nullptr}; optional target_temperature_id_{}; @@ -73,12 +102,25 @@ class TuyaClimate : public climate::Climate, public Component { float target_temperature_multiplier_{1.0f}; float hysteresis_{1.0f}; optional eco_id_{}; + optional sleep_id_{}; optional eco_temperature_{}; uint8_t active_state_; + uint8_t fan_state_; + optional swing_vertical_id_{}; + optional swing_horizontal_id_{}; + optional fan_speed_id_{}; + optional fan_speed_low_value_{}; + optional fan_speed_medium_value_{}; + optional fan_speed_middle_value_{}; + optional fan_speed_high_value_{}; + optional fan_speed_auto_value_{}; + bool swing_vertical_{false}; + bool swing_horizontal_{false}; bool heating_state_{false}; bool cooling_state_{false}; float manual_temperature_; bool eco_; + bool sleep_; bool reports_fahrenheit_{false}; }; From 1d6f245ced851d5875eac1e691fbda2cf2a692be Mon Sep 17 00:00:00 2001 From: Mat931 <49403702+Mat931@users.noreply.github.com> Date: Thu, 21 Mar 2024 03:23:30 +0000 Subject: [PATCH 146/189] Add sun_gtil2 component (for SUN-1000G2 / SUN-2000G2 grid tie inverters) (#4958) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- CODEOWNERS | 1 + esphome/components/sun_gtil2/__init__.py | 26 ++++ esphome/components/sun_gtil2/sensor.py | 87 +++++++++++ esphome/components/sun_gtil2/sun_gtil2.cpp | 135 ++++++++++++++++++ esphome/components/sun_gtil2/sun_gtil2.h | 58 ++++++++ esphome/components/sun_gtil2/text_sensor.py | 31 ++++ .../sun_gtil2/test.esp32-c3-idf.yaml | 44 ++++++ tests/components/sun_gtil2/test.esp32-c3.yaml | 44 ++++++ .../components/sun_gtil2/test.esp32-idf.yaml | 44 ++++++ tests/components/sun_gtil2/test.esp32.yaml | 44 ++++++ tests/components/sun_gtil2/test.esp8266.yaml | 44 ++++++ tests/components/sun_gtil2/test.rp2040.yaml | 44 ++++++ 12 files changed, 602 insertions(+) create mode 100644 esphome/components/sun_gtil2/__init__.py create mode 100644 esphome/components/sun_gtil2/sensor.py create mode 100644 esphome/components/sun_gtil2/sun_gtil2.cpp create mode 100644 esphome/components/sun_gtil2/sun_gtil2.h create mode 100644 esphome/components/sun_gtil2/text_sensor.py create mode 100644 tests/components/sun_gtil2/test.esp32-c3-idf.yaml create mode 100644 tests/components/sun_gtil2/test.esp32-c3.yaml create mode 100644 tests/components/sun_gtil2/test.esp32-idf.yaml create mode 100644 tests/components/sun_gtil2/test.esp32.yaml create mode 100644 tests/components/sun_gtil2/test.esp8266.yaml create mode 100644 tests/components/sun_gtil2/test.rp2040.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 4c24096faa..2c1b8f04ae 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -345,6 +345,7 @@ esphome/components/st7789v/* @kbx81 esphome/components/st7920/* @marsjan155 esphome/components/substitutions/* @esphome/core esphome/components/sun/* @OttoWinter +esphome/components/sun_gtil2/* @Mat931 esphome/components/switch/* @esphome/core esphome/components/t6615/* @tylermenezes esphome/components/tca9548a/* @andreashergert1984 diff --git a/esphome/components/sun_gtil2/__init__.py b/esphome/components/sun_gtil2/__init__.py new file mode 100644 index 0000000000..f4d46fade7 --- /dev/null +++ b/esphome/components/sun_gtil2/__init__.py @@ -0,0 +1,26 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import uart +from esphome.const import CONF_ID + +CODEOWNERS = ["@Mat931"] +MULTI_CONF = True +DEPENDENCIES = ["uart"] + +CONF_SUN_GTIL2_ID = "sun_gtil2_id" + +sun_gtil2_ns = cg.esphome_ns.namespace("sun_gtil2") + +SunGTIL2Component = sun_gtil2_ns.class_("SunGTIL2", cg.Component, uart.UARTDevice) + +CONFIG_SCHEMA = cv.Schema( + { + cv.GenerateID(): cv.declare_id(SunGTIL2Component), + } +).extend(uart.UART_DEVICE_SCHEMA) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) + await uart.register_uart_device(var, config) diff --git a/esphome/components/sun_gtil2/sensor.py b/esphome/components/sun_gtil2/sensor.py new file mode 100644 index 0000000000..6d1be9c740 --- /dev/null +++ b/esphome/components/sun_gtil2/sensor.py @@ -0,0 +1,87 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import sensor +from esphome.const import ( + DEVICE_CLASS_VOLTAGE, + DEVICE_CLASS_POWER, + DEVICE_CLASS_TEMPERATURE, + ICON_FLASH, + UNIT_VOLT, + ICON_THERMOMETER, + UNIT_WATT, + UNIT_CELSIUS, + CONF_TEMPERATURE, +) +from . import SunGTIL2Component, CONF_SUN_GTIL2_ID + +CONF_AC_VOLTAGE = "ac_voltage" +CONF_DC_VOLTAGE = "dc_voltage" +CONF_AC_POWER = "ac_power" +CONF_DC_POWER = "dc_power" +CONF_LIMITER_POWER = "limiter_power" + +CONFIG_SCHEMA = cv.All( + cv.Schema( + { + cv.GenerateID(CONF_SUN_GTIL2_ID): cv.use_id(SunGTIL2Component), + cv.Optional(CONF_AC_VOLTAGE): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + icon=ICON_FLASH, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, + ), + cv.Optional(CONF_DC_VOLTAGE): sensor.sensor_schema( + unit_of_measurement=UNIT_VOLT, + icon=ICON_FLASH, + accuracy_decimals=1, + device_class=DEVICE_CLASS_VOLTAGE, + ), + cv.Optional(CONF_AC_POWER): sensor.sensor_schema( + unit_of_measurement=UNIT_WATT, + icon=ICON_FLASH, + accuracy_decimals=1, + device_class=DEVICE_CLASS_POWER, + ), + cv.Optional(CONF_DC_POWER): sensor.sensor_schema( + unit_of_measurement=UNIT_WATT, + icon=ICON_FLASH, + accuracy_decimals=1, + device_class=DEVICE_CLASS_POWER, + ), + cv.Optional(CONF_LIMITER_POWER): sensor.sensor_schema( + unit_of_measurement=UNIT_WATT, + icon=ICON_FLASH, + accuracy_decimals=1, + device_class=DEVICE_CLASS_POWER, + ), + cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema( + unit_of_measurement=UNIT_CELSIUS, + icon=ICON_THERMOMETER, + accuracy_decimals=1, + device_class=DEVICE_CLASS_TEMPERATURE, + ), + } + ).extend(cv.COMPONENT_SCHEMA) +) + + +async def to_code(config): + hub = await cg.get_variable(config[CONF_SUN_GTIL2_ID]) + if ac_voltage_config := config.get(CONF_AC_VOLTAGE): + sens = await sensor.new_sensor(ac_voltage_config) + cg.add(hub.set_ac_voltage(sens)) + if dc_voltage_config := config.get(CONF_DC_VOLTAGE): + sens = await sensor.new_sensor(dc_voltage_config) + cg.add(hub.set_dc_voltage(sens)) + if ac_power_config := config.get(CONF_AC_POWER): + sens = await sensor.new_sensor(ac_power_config) + cg.add(hub.set_ac_power(sens)) + if dc_power_config := config.get(CONF_DC_POWER): + sens = await sensor.new_sensor(dc_power_config) + cg.add(hub.set_dc_power(sens)) + if limiter_power_config := config.get(CONF_LIMITER_POWER): + sens = await sensor.new_sensor(limiter_power_config) + cg.add(hub.set_limiter_power(sens)) + if temperature_config := config.get(CONF_TEMPERATURE): + sens = await sensor.new_sensor(temperature_config) + cg.add(hub.set_temperature(sens)) diff --git a/esphome/components/sun_gtil2/sun_gtil2.cpp b/esphome/components/sun_gtil2/sun_gtil2.cpp new file mode 100644 index 0000000000..1653f937dd --- /dev/null +++ b/esphome/components/sun_gtil2/sun_gtil2.cpp @@ -0,0 +1,135 @@ +#include "sun_gtil2.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace sun_gtil2 { + +static const char *const TAG = "sun_gtil2"; + +static const double NTC_A = 0.0011591051055979914; +static const double NTC_B = 0.00022878183547845582; +static const double NTC_C = 1.0396291358342124e-07; +static const float PULLUP_RESISTANCE = 10000.0f; +static const uint16_t ADC_MAX = 1023; // ADC of the inverter controller, not the ESP + +struct SunGTIL2Message { + uint16_t sync; + uint8_t ac_waveform[277]; + uint8_t frequency; + uint16_t ac_voltage; + uint16_t ac_power; + uint16_t dc_voltage; + uint8_t state; + uint8_t unknown1; + uint8_t unknown2; + uint8_t unknown3; + uint8_t limiter_mode; + uint8_t unknown4; + uint16_t temperature; + uint32_t limiter_power; + uint16_t dc_power; + char serial_number[10]; + uint8_t unknown5; + uint8_t end[39]; +} __attribute__((packed)); + +static const uint16_t MESSAGE_SIZE = sizeof(SunGTIL2Message); + +static_assert(MESSAGE_SIZE == 350, "Expected the message size to be 350 bytes"); + +void SunGTIL2::setup() { this->rx_message_.reserve(MESSAGE_SIZE); } + +void SunGTIL2::loop() { + while (this->available()) { + uint8_t c; + this->read_byte(&c); + this->handle_char_(c); + } +} + +std::string SunGTIL2::state_to_string_(uint8_t state) { + switch (state) { + case 0x02: + return "Starting voltage too low"; + case 0x07: + return "Working"; + default: + return str_sprintf("Unknown (0x%02x)", state); + } +} + +float SunGTIL2::calculate_temperature_(uint16_t adc_value) { + if (adc_value >= ADC_MAX || adc_value == 0) { + return NAN; + } + + float ntc_resistance = PULLUP_RESISTANCE / ((static_cast(ADC_MAX) / adc_value) - 1.0f); + double lr = log(double(ntc_resistance)); + double v = NTC_A + NTC_B * lr + NTC_C * lr * lr * lr; + return float(1.0 / v - 273.15); +} + +void SunGTIL2::handle_char_(uint8_t c) { + if (this->rx_message_.size() > 1 || c == 0x07) { + this->rx_message_.push_back(c); + } else if (!this->rx_message_.empty()) { + this->rx_message_.clear(); + } + if (this->rx_message_.size() < MESSAGE_SIZE) { + return; + } + + SunGTIL2Message msg; + memcpy(&msg, this->rx_message_.data(), MESSAGE_SIZE); + this->rx_message_.clear(); + + if (!((msg.end[0] == 0) && (msg.end[38] == 0x08))) + return; + + ESP_LOGVV(TAG, "Frequency raw value: %02x", msg.frequency); + ESP_LOGVV(TAG, "Unknown values: %02x %02x %02x %02x %02x", msg.unknown1, msg.unknown2, msg.unknown3, msg.unknown4, + msg.unknown5); + +#ifdef USE_SENSOR + if (this->ac_voltage_ != nullptr) + this->ac_voltage_->publish_state(__builtin_bswap16(msg.ac_voltage) / 10.0f); + if (this->dc_voltage_ != nullptr) + this->dc_voltage_->publish_state(__builtin_bswap16(msg.dc_voltage) / 8.0f); + if (this->ac_power_ != nullptr) + this->ac_power_->publish_state(__builtin_bswap16(msg.ac_power) / 10.0f); + if (this->dc_power_ != nullptr) + this->dc_power_->publish_state(__builtin_bswap16(msg.dc_power) / 10.0f); + if (this->limiter_power_ != nullptr) + this->limiter_power_->publish_state(static_cast(__builtin_bswap32(msg.limiter_power)) / 10.0f); + if (this->temperature_ != nullptr) + this->temperature_->publish_state(calculate_temperature_(__builtin_bswap16(msg.temperature))); +#endif +#ifdef USE_TEXT_SENSOR + if (this->state_ != nullptr) { + this->state_->publish_state(this->state_to_string_(msg.state)); + } + if (this->serial_number_ != nullptr) { + std::string serial_number; + serial_number.assign(msg.serial_number, 10); + this->serial_number_->publish_state(serial_number); + } +#endif +} + +void SunGTIL2::dump_config() { +#ifdef USE_SENSOR + LOG_SENSOR("", "AC Voltage", this->ac_voltage_); + LOG_SENSOR("", "DC Voltage", this->dc_voltage_); + LOG_SENSOR("", "AC Power", this->ac_power_); + LOG_SENSOR("", "DC Power", this->dc_power_); + LOG_SENSOR("", "Limiter Power", this->limiter_power_); + LOG_SENSOR("", "Temperature", this->temperature_); +#endif +#ifdef USE_TEXT_SENSOR + LOG_TEXT_SENSOR("", "State", this->state_); + LOG_TEXT_SENSOR("", "Serial Number", this->serial_number_); +#endif +} + +} // namespace sun_gtil2 +} // namespace esphome diff --git a/esphome/components/sun_gtil2/sun_gtil2.h b/esphome/components/sun_gtil2/sun_gtil2.h new file mode 100644 index 0000000000..0c29ae695d --- /dev/null +++ b/esphome/components/sun_gtil2/sun_gtil2.h @@ -0,0 +1,58 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/core/defines.h" + +#ifdef USE_SENSOR +#include "esphome/components/sensor/sensor.h" +#endif +#ifdef USE_TEXT_SENSOR +#include "esphome/components/text_sensor/text_sensor.h" +#endif +#include "esphome/components/uart/uart.h" + +namespace esphome { +namespace sun_gtil2 { + +class SunGTIL2 : public Component, public uart::UARTDevice { + public: + float get_setup_priority() const override { return setup_priority::LATE; } + void setup() override; + void loop() override; + void dump_config() override; + +#ifdef USE_SENSOR + void set_ac_voltage(sensor::Sensor *sensor) { ac_voltage_ = sensor; } + void set_dc_voltage(sensor::Sensor *sensor) { dc_voltage_ = sensor; } + void set_ac_power(sensor::Sensor *sensor) { ac_power_ = sensor; } + void set_dc_power(sensor::Sensor *sensor) { dc_power_ = sensor; } + void set_limiter_power(sensor::Sensor *sensor) { limiter_power_ = sensor; } + void set_temperature(sensor::Sensor *sensor) { temperature_ = sensor; } +#endif +#ifdef USE_TEXT_SENSOR + void set_state(text_sensor::TextSensor *text_sensor) { state_ = text_sensor; } + void set_serial_number(text_sensor::TextSensor *text_sensor) { serial_number_ = text_sensor; } +#endif + + protected: + std::string state_to_string_(uint8_t state); +#ifdef USE_SENSOR + sensor::Sensor *ac_voltage_{nullptr}; + sensor::Sensor *dc_voltage_{nullptr}; + sensor::Sensor *ac_power_{nullptr}; + sensor::Sensor *dc_power_{nullptr}; + sensor::Sensor *limiter_power_{nullptr}; + sensor::Sensor *temperature_{nullptr}; +#endif +#ifdef USE_TEXT_SENSOR + text_sensor::TextSensor *state_{nullptr}; + text_sensor::TextSensor *serial_number_{nullptr}; +#endif + + float calculate_temperature_(uint16_t adc_value); + void handle_char_(uint8_t c); + std::vector rx_message_; +}; + +} // namespace sun_gtil2 +} // namespace esphome diff --git a/esphome/components/sun_gtil2/text_sensor.py b/esphome/components/sun_gtil2/text_sensor.py new file mode 100644 index 0000000000..d9d3e3ca66 --- /dev/null +++ b/esphome/components/sun_gtil2/text_sensor.py @@ -0,0 +1,31 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import text_sensor +from esphome.const import CONF_STATE +from . import SunGTIL2Component, CONF_SUN_GTIL2_ID + +CONF_SERIAL_NUMBER = "serial_number" + +CONFIG_SCHEMA = cv.All( + cv.Schema( + { + cv.GenerateID(CONF_SUN_GTIL2_ID): cv.use_id(SunGTIL2Component), + cv.Optional(CONF_STATE): text_sensor.text_sensor_schema( + text_sensor.TextSensor + ), + cv.Optional(CONF_SERIAL_NUMBER): text_sensor.text_sensor_schema( + text_sensor.TextSensor + ), + } + ).extend(cv.COMPONENT_SCHEMA) +) + + +async def to_code(config): + hub = await cg.get_variable(config[CONF_SUN_GTIL2_ID]) + if state_config := config.get(CONF_STATE): + sens = await text_sensor.new_text_sensor(state_config) + cg.add(hub.set_state(sens)) + if serial_number_config := config.get(CONF_SERIAL_NUMBER): + sens = await text_sensor.new_text_sensor(serial_number_config) + cg.add(hub.set_serial_number(sens)) diff --git a/tests/components/sun_gtil2/test.esp32-c3-idf.yaml b/tests/components/sun_gtil2/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..6ec834db98 --- /dev/null +++ b/tests/components/sun_gtil2/test.esp32-c3-idf.yaml @@ -0,0 +1,44 @@ +uart: + - id: control_to_display + rx_pin: + number: 5 + baud_rate: 9600 + +sun_gtil2: + uart_id: control_to_display + +sensor: + - platform: sun_gtil2 + temperature: + id: gtil_temperature + name: "Heatsink Temperature" + filters: + - throttle_average: 30s + dc_voltage: + id: gtil_dc_voltage + name: "DC Voltage" + filters: + - throttle_average: 30s + ac_voltage: + id: gtil_ac_voltage + name: "AC Voltage" + filters: + - throttle_average: 30s + ac_power: + id: gtil_ac_power + name: "AC Power" + dc_power: + id: gtil_dc_power + name: "DC Power" + limiter_power: + id: gtil_limiter_power + internal: true + +text_sensor: + - platform: sun_gtil2 + state: + id: gtil_state + name: "State" + serial_number: + id: gtil_serial_number + internal: true diff --git a/tests/components/sun_gtil2/test.esp32-c3.yaml b/tests/components/sun_gtil2/test.esp32-c3.yaml new file mode 100644 index 0000000000..6ec834db98 --- /dev/null +++ b/tests/components/sun_gtil2/test.esp32-c3.yaml @@ -0,0 +1,44 @@ +uart: + - id: control_to_display + rx_pin: + number: 5 + baud_rate: 9600 + +sun_gtil2: + uart_id: control_to_display + +sensor: + - platform: sun_gtil2 + temperature: + id: gtil_temperature + name: "Heatsink Temperature" + filters: + - throttle_average: 30s + dc_voltage: + id: gtil_dc_voltage + name: "DC Voltage" + filters: + - throttle_average: 30s + ac_voltage: + id: gtil_ac_voltage + name: "AC Voltage" + filters: + - throttle_average: 30s + ac_power: + id: gtil_ac_power + name: "AC Power" + dc_power: + id: gtil_dc_power + name: "DC Power" + limiter_power: + id: gtil_limiter_power + internal: true + +text_sensor: + - platform: sun_gtil2 + state: + id: gtil_state + name: "State" + serial_number: + id: gtil_serial_number + internal: true diff --git a/tests/components/sun_gtil2/test.esp32-idf.yaml b/tests/components/sun_gtil2/test.esp32-idf.yaml new file mode 100644 index 0000000000..ed1e68e574 --- /dev/null +++ b/tests/components/sun_gtil2/test.esp32-idf.yaml @@ -0,0 +1,44 @@ +uart: + - id: control_to_display + rx_pin: + number: 16 + baud_rate: 9600 + +sun_gtil2: + uart_id: control_to_display + +sensor: + - platform: sun_gtil2 + temperature: + id: gtil_temperature + name: "Heatsink Temperature" + filters: + - throttle_average: 30s + dc_voltage: + id: gtil_dc_voltage + name: "DC Voltage" + filters: + - throttle_average: 30s + ac_voltage: + id: gtil_ac_voltage + name: "AC Voltage" + filters: + - throttle_average: 30s + ac_power: + id: gtil_ac_power + name: "AC Power" + dc_power: + id: gtil_dc_power + name: "DC Power" + limiter_power: + id: gtil_limiter_power + internal: true + +text_sensor: + - platform: sun_gtil2 + state: + id: gtil_state + name: "State" + serial_number: + id: gtil_serial_number + internal: true diff --git a/tests/components/sun_gtil2/test.esp32.yaml b/tests/components/sun_gtil2/test.esp32.yaml new file mode 100644 index 0000000000..ed1e68e574 --- /dev/null +++ b/tests/components/sun_gtil2/test.esp32.yaml @@ -0,0 +1,44 @@ +uart: + - id: control_to_display + rx_pin: + number: 16 + baud_rate: 9600 + +sun_gtil2: + uart_id: control_to_display + +sensor: + - platform: sun_gtil2 + temperature: + id: gtil_temperature + name: "Heatsink Temperature" + filters: + - throttle_average: 30s + dc_voltage: + id: gtil_dc_voltage + name: "DC Voltage" + filters: + - throttle_average: 30s + ac_voltage: + id: gtil_ac_voltage + name: "AC Voltage" + filters: + - throttle_average: 30s + ac_power: + id: gtil_ac_power + name: "AC Power" + dc_power: + id: gtil_dc_power + name: "DC Power" + limiter_power: + id: gtil_limiter_power + internal: true + +text_sensor: + - platform: sun_gtil2 + state: + id: gtil_state + name: "State" + serial_number: + id: gtil_serial_number + internal: true diff --git a/tests/components/sun_gtil2/test.esp8266.yaml b/tests/components/sun_gtil2/test.esp8266.yaml new file mode 100644 index 0000000000..6ec834db98 --- /dev/null +++ b/tests/components/sun_gtil2/test.esp8266.yaml @@ -0,0 +1,44 @@ +uart: + - id: control_to_display + rx_pin: + number: 5 + baud_rate: 9600 + +sun_gtil2: + uart_id: control_to_display + +sensor: + - platform: sun_gtil2 + temperature: + id: gtil_temperature + name: "Heatsink Temperature" + filters: + - throttle_average: 30s + dc_voltage: + id: gtil_dc_voltage + name: "DC Voltage" + filters: + - throttle_average: 30s + ac_voltage: + id: gtil_ac_voltage + name: "AC Voltage" + filters: + - throttle_average: 30s + ac_power: + id: gtil_ac_power + name: "AC Power" + dc_power: + id: gtil_dc_power + name: "DC Power" + limiter_power: + id: gtil_limiter_power + internal: true + +text_sensor: + - platform: sun_gtil2 + state: + id: gtil_state + name: "State" + serial_number: + id: gtil_serial_number + internal: true diff --git a/tests/components/sun_gtil2/test.rp2040.yaml b/tests/components/sun_gtil2/test.rp2040.yaml new file mode 100644 index 0000000000..6ec834db98 --- /dev/null +++ b/tests/components/sun_gtil2/test.rp2040.yaml @@ -0,0 +1,44 @@ +uart: + - id: control_to_display + rx_pin: + number: 5 + baud_rate: 9600 + +sun_gtil2: + uart_id: control_to_display + +sensor: + - platform: sun_gtil2 + temperature: + id: gtil_temperature + name: "Heatsink Temperature" + filters: + - throttle_average: 30s + dc_voltage: + id: gtil_dc_voltage + name: "DC Voltage" + filters: + - throttle_average: 30s + ac_voltage: + id: gtil_ac_voltage + name: "AC Voltage" + filters: + - throttle_average: 30s + ac_power: + id: gtil_ac_power + name: "AC Power" + dc_power: + id: gtil_dc_power + name: "DC Power" + limiter_power: + id: gtil_limiter_power + internal: true + +text_sensor: + - platform: sun_gtil2 + state: + id: gtil_state + name: "State" + serial_number: + id: gtil_serial_number + internal: true From d0ced3471e8acce2c72e11458005d870ee5eb88c Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Thu, 21 Mar 2024 14:25:11 +1100 Subject: [PATCH 147/189] SPI: Make some validation failures give more useful messages. (#6413) --- esphome/components/spi/__init__.py | 9 +++++++++ tests/components/xpt2046/test.esp32-c3-idf.yaml | 9 +++++---- tests/components/xpt2046/test.esp32-c3.yaml | 9 +++++---- tests/components/xpt2046/test.esp32-idf.yaml | 9 +++++---- tests/components/xpt2046/test.esp32.yaml | 9 +++++---- tests/components/xpt2046/test.esp8266.yaml | 9 +++++---- tests/components/xpt2046/test.rp2040.yaml | 9 +++++---- 7 files changed, 39 insertions(+), 24 deletions(-) diff --git a/esphome/components/spi/__init__.py b/esphome/components/spi/__init__.py index 2847c5bfa1..fdf19bb56e 100644 --- a/esphome/components/spi/__init__.py +++ b/esphome/components/spi/__init__.py @@ -268,6 +268,9 @@ SPI_SCHEMA = cv.All( *sum(get_hw_interface_list(), ["software", "hardware", "any"]), lower=True, ), + cv.Optional(CONF_DATA_PINS): cv.invalid( + "'data_pins' should be used with 'type: quad' only" + ), } ), cv.has_at_least_one_key(CONF_MISO_PIN, CONF_MOSI_PIN), @@ -287,6 +290,12 @@ SPI_QUAD_SCHEMA = cv.All( *sum(get_hw_interface_list(), ["hardware"]), lower=True, ), + cv.Optional(CONF_MISO_PIN): cv.invalid( + "'miso_pin' should not be used with quad SPI" + ), + cv.Optional(CONF_MOSI_PIN): cv.invalid( + "'mosi_pin' should not be used with quad SPI" + ), } ), cv.only_on([PLATFORM_ESP32]), diff --git a/tests/components/xpt2046/test.esp32-c3-idf.yaml b/tests/components/xpt2046/test.esp32-c3-idf.yaml index 38a1da74ae..f3a2cf9aae 100644 --- a/tests/components/xpt2046/test.esp32-c3-idf.yaml +++ b/tests/components/xpt2046/test.esp32-c3-idf.yaml @@ -23,10 +23,11 @@ touchscreen: display: xpt_display update_interval: 50ms threshold: 400 - calibration_x_min: 3860 - calibration_x_max: 280 - calibration_y_min: 340 - calibration_y_max: 3860 + calibration: + x_min: 3860 + x_max: 280 + y_min: 340 + y_max: 3860 on_touch: - logger.log: format: Touch at (%d, %d) diff --git a/tests/components/xpt2046/test.esp32-c3.yaml b/tests/components/xpt2046/test.esp32-c3.yaml index 38a1da74ae..f3a2cf9aae 100644 --- a/tests/components/xpt2046/test.esp32-c3.yaml +++ b/tests/components/xpt2046/test.esp32-c3.yaml @@ -23,10 +23,11 @@ touchscreen: display: xpt_display update_interval: 50ms threshold: 400 - calibration_x_min: 3860 - calibration_x_max: 280 - calibration_y_min: 340 - calibration_y_max: 3860 + calibration: + x_min: 3860 + x_max: 280 + y_min: 340 + y_max: 3860 on_touch: - logger.log: format: Touch at (%d, %d) diff --git a/tests/components/xpt2046/test.esp32-idf.yaml b/tests/components/xpt2046/test.esp32-idf.yaml index 7f8617d176..bb166866f4 100644 --- a/tests/components/xpt2046/test.esp32-idf.yaml +++ b/tests/components/xpt2046/test.esp32-idf.yaml @@ -23,10 +23,11 @@ touchscreen: display: xpt_display update_interval: 50ms threshold: 400 - calibration_x_min: 3860 - calibration_x_max: 280 - calibration_y_min: 340 - calibration_y_max: 3860 + calibration: + x_min: 3860 + x_max: 280 + y_min: 340 + y_max: 3860 on_touch: - logger.log: format: Touch at (%d, %d) diff --git a/tests/components/xpt2046/test.esp32.yaml b/tests/components/xpt2046/test.esp32.yaml index 7f8617d176..bb166866f4 100644 --- a/tests/components/xpt2046/test.esp32.yaml +++ b/tests/components/xpt2046/test.esp32.yaml @@ -23,10 +23,11 @@ touchscreen: display: xpt_display update_interval: 50ms threshold: 400 - calibration_x_min: 3860 - calibration_x_max: 280 - calibration_y_min: 340 - calibration_y_max: 3860 + calibration: + x_min: 3860 + x_max: 280 + y_min: 340 + y_max: 3860 on_touch: - logger.log: format: Touch at (%d, %d) diff --git a/tests/components/xpt2046/test.esp8266.yaml b/tests/components/xpt2046/test.esp8266.yaml index a998d2df14..a917290e8e 100644 --- a/tests/components/xpt2046/test.esp8266.yaml +++ b/tests/components/xpt2046/test.esp8266.yaml @@ -23,10 +23,11 @@ touchscreen: display: xpt_display update_interval: 50ms threshold: 400 - calibration_x_min: 3860 - calibration_x_max: 280 - calibration_y_min: 340 - calibration_y_max: 3860 + calibration: + x_min: 3860 + x_max: 280 + y_min: 340 + y_max: 3860 on_touch: - logger.log: format: Touch at (%d, %d) diff --git a/tests/components/xpt2046/test.rp2040.yaml b/tests/components/xpt2046/test.rp2040.yaml index 3e5d602247..a7a49309ac 100644 --- a/tests/components/xpt2046/test.rp2040.yaml +++ b/tests/components/xpt2046/test.rp2040.yaml @@ -23,10 +23,11 @@ touchscreen: display: xpt_display update_interval: 50ms threshold: 400 - calibration_x_min: 3860 - calibration_x_max: 280 - calibration_y_min: 340 - calibration_y_max: 3860 + calibration: + x_min: 3860 + x_max: 280 + y_min: 340 + y_max: 3860 on_touch: - logger.log: format: Touch at (%d, %d) From a3b0ddf6864bfdd2142d2c5f532d1de3136fdce4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Mar 2024 16:31:20 +1300 Subject: [PATCH 148/189] Bump aioesphomeapi from 23.1.1 to 23.2.0 (#6412) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4b7e501e97..702127eca8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ platformio==6.1.13 # When updating platformio, also update Dockerfile esptool==4.7.0 click==8.1.7 esphome-dashboard==20240319.0 -aioesphomeapi==23.1.1 +aioesphomeapi==23.2.0 zeroconf==0.131.0 python-magic==0.4.27 ruamel.yaml==0.18.6 # dashboard_import From 380146258994f699e505906ec846f697eec756ad Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Fri, 22 Mar 2024 19:32:37 +1100 Subject: [PATCH 149/189] Add check for use of GPIOXX in config (#6419) --- esphome/pins.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/esphome/pins.py b/esphome/pins.py index 87f7084d4f..d02ad357a0 100644 --- a/esphome/pins.py +++ b/esphome/pins.py @@ -311,10 +311,18 @@ def gpio_base_schema( map(lambda m: (cv.Optional(m, default=mode_default), cv.boolean), modes) ) + def _number_validator(value): + if isinstance(value, str) and value.upper().startswith("GPIOX"): + raise cv.Invalid( + f"Found placeholder '{value}' when expecting a GPIO pin number.\n" + "You must replace this with an actual pin number." + ) + return number_validator(value) + schema = cv.Schema( { cv.GenerateID(): cv.declare_id(pin_type), - cv.Required(CONF_NUMBER): number_validator, + cv.Required(CONF_NUMBER): _number_validator, cv.Optional(CONF_ALLOW_OTHER_USES): cv.boolean, cv.Optional(CONF_MODE, default={}): cv.All(mode_dict, mode_validator), } From bd8f9db037d36fac6e71724df41cb751a41b53b2 Mon Sep 17 00:00:00 2001 From: Simone Rossetto Date: Sun, 24 Mar 2024 23:21:04 +0100 Subject: [PATCH 150/189] WireGuard for esp8266 (#6365) --- esphome/components/wireguard/__init__.py | 4 +- esphome/components/wireguard/wireguard.cpp | 72 +++---------------- esphome/components/wireguard/wireguard.h | 4 -- platformio.ini | 5 +- .../wireguard/test.esp32-idf.yaml} | 22 ------ tests/components/wireguard/test.esp32.yaml | 62 ++++++++++++++++ tests/components/wireguard/test.esp8266.yaml | 62 ++++++++++++++++ 7 files changed, 139 insertions(+), 92 deletions(-) rename tests/{test10.yaml => components/wireguard/test.esp32-idf.yaml} (84%) create mode 100644 tests/components/wireguard/test.esp32.yaml create mode 100644 tests/components/wireguard/test.esp8266.yaml diff --git a/esphome/components/wireguard/__init__.py b/esphome/components/wireguard/__init__.py index b59a6011cd..2d68cd001e 100644 --- a/esphome/components/wireguard/__init__.py +++ b/esphome/components/wireguard/__init__.py @@ -22,7 +22,7 @@ CONF_PEER_ALLOWED_IPS = "peer_allowed_ips" CONF_PEER_PERSISTENT_KEEPALIVE = "peer_persistent_keepalive" CONF_REQUIRE_CONNECTION_TO_PROCEED = "require_connection_to_proceed" -DEPENDENCIES = ["time", "esp32"] +DEPENDENCIES = ["time"] CODEOWNERS = ["@lhoracek", "@droscy", "@thomas0bernard"] # The key validation regex has been described by Jason Donenfeld himself @@ -120,7 +120,7 @@ async def to_code(config): # the '+1' modifier is relative to the device's own address that will # be automatically added to the provided list. cg.add_build_flag(f"-DCONFIG_WIREGUARD_MAX_SRC_IPS={len(allowed_ips) + 1}") - cg.add_library("droscy/esp_wireguard", "0.3.2") + cg.add_library("droscy/esp_wireguard", "0.4.0") await cg.register_component(var, config) diff --git a/esphome/components/wireguard/wireguard.cpp b/esphome/components/wireguard/wireguard.cpp index cca30d4310..17ebc701e3 100644 --- a/esphome/components/wireguard/wireguard.cpp +++ b/esphome/components/wireguard/wireguard.cpp @@ -1,7 +1,5 @@ #include "wireguard.h" -#ifdef USE_ESP32 - #include #include #include @@ -11,26 +9,20 @@ #include "esphome/core/time.h" #include "esphome/components/network/util.h" -#include - #include - -// includes for resume/suspend wdt -#if defined(USE_ESP_IDF) -#include -#if ESP_IDF_VERSION_MAJOR >= 5 -#include -#endif -#elif defined(USE_ARDUINO) -#include -#endif +#include namespace esphome { namespace wireguard { static const char *const TAG = "wireguard"; -static const char *const LOGMSG_PEER_STATUS = "WireGuard remote peer is %s (latest handshake %s)"; +/* + * Cannot use `static const char*` for LOGMSG_PEER_STATUS on esp8266 platform + * because log messages in `Wireguard::update()` method fail. + */ +#define LOGMSG_PEER_STATUS "WireGuard remote peer is %s (latest handshake %s)" + static const char *const LOGMSG_ONLINE = "online"; static const char *const LOGMSG_OFFLINE = "offline"; @@ -257,20 +249,13 @@ void Wireguard::start_connection_() { } ESP_LOGD(TAG, "starting WireGuard connection..."); - - /* - * The function esp_wireguard_connect() contains a DNS resolution - * that could trigger the watchdog, so before it we suspend (or - * increase the time, it depends on the platform) the wdt and - * then we resume the normal timeout. - */ - suspend_wdt(); - ESP_LOGV(TAG, "executing esp_wireguard_connect"); this->wg_connected_ = esp_wireguard_connect(&(this->wg_ctx_)); - resume_wdt(); if (this->wg_connected_ == ESP_OK) { ESP_LOGI(TAG, "WireGuard connection started"); + } else if (this->wg_connected_ == ESP_ERR_RETRY) { + ESP_LOGD(TAG, "WireGuard is waiting for endpoint IP address to be available"); + return; } else { ESP_LOGW(TAG, "cannot start WireGuard connection, error code %d", this->wg_connected_); return; @@ -300,44 +285,7 @@ void Wireguard::stop_connection_() { } } -void suspend_wdt() { -#if defined(USE_ESP_IDF) -#if ESP_IDF_VERSION_MAJOR >= 5 - ESP_LOGV(TAG, "temporarily increasing wdt timeout to 15000 ms"); - esp_task_wdt_config_t wdtc; - wdtc.timeout_ms = 15000; - wdtc.idle_core_mask = 0; - wdtc.trigger_panic = false; - esp_task_wdt_reconfigure(&wdtc); -#else - ESP_LOGV(TAG, "temporarily increasing wdt timeout to 15 seconds"); - esp_task_wdt_init(15, false); -#endif -#elif defined(USE_ARDUINO) - ESP_LOGV(TAG, "temporarily disabling the wdt"); - disableLoopWDT(); -#endif -} - -void resume_wdt() { -#if defined(USE_ESP_IDF) -#if ESP_IDF_VERSION_MAJOR >= 5 - wdtc.timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000; - esp_task_wdt_reconfigure(&wdtc); - ESP_LOGV(TAG, "wdt resumed with %" PRIu32 " ms timeout", wdtc.timeout_ms); -#else - esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, false); - ESP_LOGV(TAG, "wdt resumed with %d seconds timeout", CONFIG_ESP_TASK_WDT_TIMEOUT_S); -#endif -#elif defined(USE_ARDUINO) - enableLoopWDT(); - ESP_LOGV(TAG, "wdt resumed"); -#endif -} - std::string mask_key(const std::string &key) { return (key.substr(0, 5) + "[...]="); } } // namespace wireguard } // namespace esphome - -#endif // USE_ESP32 diff --git a/esphome/components/wireguard/wireguard.h b/esphome/components/wireguard/wireguard.h index 7753a8dfc2..a0e9e27a1b 100644 --- a/esphome/components/wireguard/wireguard.h +++ b/esphome/components/wireguard/wireguard.h @@ -1,7 +1,5 @@ #pragma once -#ifdef USE_ESP32 - #include #include #include @@ -172,5 +170,3 @@ template class WireguardDisableAction : public Action, pu } // namespace wireguard } // namespace esphome - -#endif // USE_ESP32 diff --git a/platformio.ini b/platformio.ini index b326c9722e..db5fb3a544 100644 --- a/platformio.ini +++ b/platformio.ini @@ -94,6 +94,7 @@ lib_deps = ESP8266mDNS ; mdns (Arduino built-in) DNSServer ; captive_portal (Arduino built-in) crankyoldgit/IRremoteESP8266@~2.8.4 ; heatpumpir + droscy/esp_wireguard@0.4.0 ; wireguard build_flags = ${common:arduino.build_flags} -Wno-nonnull-compare @@ -123,7 +124,7 @@ lib_deps = DNSServer ; captive_portal (Arduino built-in) esphome/ESP32-audioI2S@2.0.7 ; i2s_audio crankyoldgit/IRremoteESP8266@~2.8.4 ; heatpumpir - droscy/esp_wireguard@0.3.2 ; wireguard + droscy/esp_wireguard@0.4.0 ; wireguard build_flags = ${common:arduino.build_flags} -DUSE_ESP32 @@ -142,7 +143,7 @@ framework = espidf lib_deps = ${common:idf.lib_deps} espressif/esp32-camera@1.0.0 ; esp32_camera - droscy/esp_wireguard@0.3.2 ; wireguard + droscy/esp_wireguard@0.4.0 ; wireguard build_flags = ${common:idf.build_flags} -Wno-nonnull-compare diff --git a/tests/test10.yaml b/tests/components/wireguard/test.esp32-idf.yaml similarity index 84% rename from tests/test10.yaml rename to tests/components/wireguard/test.esp32-idf.yaml index 854173cfe9..9ea7f00bdb 100644 --- a/tests/test10.yaml +++ b/tests/components/wireguard/test.esp32-idf.yaml @@ -1,36 +1,14 @@ ---- -esphome: - name: test10 - build_path: build/test10 - -esp32: - board: esp32doit-devkit-v1 - framework: - type: arduino - wifi: ssid: "MySSID1" password: "password1" - reboot_timeout: 3min - power_save_mode: high network: enable_ipv6: true -logger: - level: VERBOSE - -api: - reboot_timeout: 10min - -web_server: - version: 3 - time: - platform: sntp wireguard: - id: vpn address: 172.16.34.100 netmask: 255.255.255.0 # NEVER use the following keys for your vpn, they are now public! diff --git a/tests/components/wireguard/test.esp32.yaml b/tests/components/wireguard/test.esp32.yaml new file mode 100644 index 0000000000..9ea7f00bdb --- /dev/null +++ b/tests/components/wireguard/test.esp32.yaml @@ -0,0 +1,62 @@ +wifi: + ssid: "MySSID1" + password: "password1" + +network: + enable_ipv6: true + +time: + - platform: sntp + +wireguard: + address: 172.16.34.100 + netmask: 255.255.255.0 + # NEVER use the following keys for your vpn, they are now public! + private_key: wPBMxtNYH3mChicrbpsRpZIasIdPq3yZuthn23FbGG8= + peer_public_key: Hs2JfikvYU03/Kv3YoAs1hrUIPPTEkpsZKSPUljE9yc= + peer_preshared_key: 20fjM5GRnSolGPC5SRj9ljgIUyQfruv0B0bvLl3Yt60= + peer_endpoint: wg.server.example + peer_persistent_keepalive: 25s + peer_allowed_ips: + - 172.16.34.0/24 + - 192.168.4.0/24 + +binary_sensor: + - platform: wireguard + status: + name: 'WireGuard Status' + enabled: + name: 'WireGuard Enabled' + +sensor: + - platform: wireguard + latest_handshake: + name: 'WireGuard Latest Handshake' + +text_sensor: + - platform: wireguard + address: + name: 'WireGuard Address' + +button: + - platform: template + name: 'Toggle WireGuard' + entity_category: config + on_press: + - if: + condition: wireguard.enabled + then: + - wireguard.disable: + else: + - wireguard.enable: + + - platform: template + name: 'Log WireGuard status' + entity_category: config + on_press: + - if: + condition: wireguard.peer_online + then: + - logger.log: 'wireguard remote peer is online' + else: + - logger.log: 'wireguard remote peer is offline' diff --git a/tests/components/wireguard/test.esp8266.yaml b/tests/components/wireguard/test.esp8266.yaml new file mode 100644 index 0000000000..9ea7f00bdb --- /dev/null +++ b/tests/components/wireguard/test.esp8266.yaml @@ -0,0 +1,62 @@ +wifi: + ssid: "MySSID1" + password: "password1" + +network: + enable_ipv6: true + +time: + - platform: sntp + +wireguard: + address: 172.16.34.100 + netmask: 255.255.255.0 + # NEVER use the following keys for your vpn, they are now public! + private_key: wPBMxtNYH3mChicrbpsRpZIasIdPq3yZuthn23FbGG8= + peer_public_key: Hs2JfikvYU03/Kv3YoAs1hrUIPPTEkpsZKSPUljE9yc= + peer_preshared_key: 20fjM5GRnSolGPC5SRj9ljgIUyQfruv0B0bvLl3Yt60= + peer_endpoint: wg.server.example + peer_persistent_keepalive: 25s + peer_allowed_ips: + - 172.16.34.0/24 + - 192.168.4.0/24 + +binary_sensor: + - platform: wireguard + status: + name: 'WireGuard Status' + enabled: + name: 'WireGuard Enabled' + +sensor: + - platform: wireguard + latest_handshake: + name: 'WireGuard Latest Handshake' + +text_sensor: + - platform: wireguard + address: + name: 'WireGuard Address' + +button: + - platform: template + name: 'Toggle WireGuard' + entity_category: config + on_press: + - if: + condition: wireguard.enabled + then: + - wireguard.disable: + else: + - wireguard.enable: + + - platform: template + name: 'Log WireGuard status' + entity_category: config + on_press: + - if: + condition: wireguard.peer_online + then: + - logger.log: 'wireguard remote peer is online' + else: + - logger.log: 'wireguard remote peer is offline' From 2997964b72f45dc923bed8d166c08df4768fddc7 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Sun, 24 Mar 2024 23:41:53 +0100 Subject: [PATCH 151/189] setup.cfg: drop duplicate, underintended trove classifier (#6421) --- setup.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 755cef47c0..b3cfbba6a1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,7 +13,6 @@ classifier = Programming Language :: C++ Programming Language :: Python :: 3 Topic :: Home Automation -Topic :: Home Automation [flake8] max-line-length = 120 From e87727aed33c5637d2c2dc64bd76845ea77f6b3b Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Mon, 25 Mar 2024 09:44:05 +1100 Subject: [PATCH 152/189] AHT10: Fix bug (#6409) --- esphome/components/aht10/aht10.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/esphome/components/aht10/aht10.cpp b/esphome/components/aht10/aht10.cpp index d812d8ef2d..332218b9e9 100644 --- a/esphome/components/aht10/aht10.cpp +++ b/esphome/components/aht10/aht10.cpp @@ -40,19 +40,18 @@ void AHT10Component::setup() { } delay(AHT10_SOFTRESET_DELAY); - const uint8_t *init_cmd; + i2c::ErrorCode error_code = i2c::ERROR_INVALID_ARGUMENT; switch (this->variant_) { case AHT10Variant::AHT20: - init_cmd = AHT20_INITIALIZE_CMD; ESP_LOGCONFIG(TAG, "Setting up AHT20"); + error_code = this->write(AHT20_INITIALIZE_CMD, sizeof(AHT20_INITIALIZE_CMD)); break; case AHT10Variant::AHT10: - default: - init_cmd = AHT10_INITIALIZE_CMD; ESP_LOGCONFIG(TAG, "Setting up AHT10"); + error_code = this->write(AHT10_INITIALIZE_CMD, sizeof(AHT10_INITIALIZE_CMD)); + break; } - - if (this->write(init_cmd, sizeof(init_cmd)) != i2c::ERROR_OK) { + if (error_code != i2c::ERROR_OK) { ESP_LOGE(TAG, "Communication with AHT10 failed!"); this->mark_failed(); return; From 121bd84854fbf8ea33daabdbb320e6508c9ad0d4 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Tue, 26 Mar 2024 09:03:51 +1100 Subject: [PATCH 153/189] Store preferences in disk file on host platform (#6428) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: H. Árkosi Róbert Co-authored-by: clydeps --- esphome/components/host/preferences.cpp | 75 +++++++++++++++++++++---- esphome/components/host/preferences.h | 53 +++++++++++++++++ 2 files changed, 116 insertions(+), 12 deletions(-) diff --git a/esphome/components/host/preferences.cpp b/esphome/components/host/preferences.cpp index bf45893e40..7b939cdebb 100644 --- a/esphome/components/host/preferences.cpp +++ b/esphome/components/host/preferences.cpp @@ -1,36 +1,87 @@ #ifdef USE_HOST +#include +#include #include "preferences.h" -#include -#include "esphome/core/preferences.h" -#include "esphome/core/helpers.h" -#include "esphome/core/log.h" -#include "esphome/core/defines.h" +#include "esphome/core/application.h" namespace esphome { namespace host { +namespace fs = std::filesystem; static const char *const TAG = "host.preferences"; -class HostPreferences : public ESPPreferences { - public: - ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash) override { return {}; } +void HostPreferences::setup_() { + if (this->setup_complete_) + return; + this->filename_.append(getenv("HOME")); + this->filename_.append("/.esphome"); + this->filename_.append("/prefs"); + fs::create_directories(this->filename_); + this->filename_.append("/"); + this->filename_.append(App.get_name()); + this->filename_.append(".prefs"); + FILE *fp = fopen(this->filename_.c_str(), "rb"); + if (fp != nullptr) { + while (!feof((fp))) { + uint32_t key; + uint8_t len; + if (fread(&key, sizeof(key), 1, fp) != 1) + break; + if (fread(&len, sizeof(len), 1, fp) != 1) + break; + uint8_t data[len]; + if (fread(data, sizeof(uint8_t), len, fp) != len) + break; + std::vector vec(data, data + len); + this->data[key] = vec; + } + fclose(fp); + } + this->setup_complete_ = true; +} - ESPPreferenceObject make_preference(size_t length, uint32_t type) override { return {}; } +bool HostPreferences::sync() { + this->setup_(); + FILE *fp = fopen(this->filename_.c_str(), "wb"); + std::map>::iterator it; - bool sync() override { return true; } - bool reset() override { return true; } + for (it = this->data.begin(); it != this->data.end(); ++it) { + fwrite(&it->first, sizeof(uint32_t), 1, fp); + uint8_t len = it->second.size(); + fwrite(&len, sizeof(len), 1, fp); + fwrite(it->second.data(), sizeof(uint8_t), it->second.size(), fp); + } + fclose(fp); + return true; +} + +bool HostPreferences::reset() { + host_preferences->data.clear(); + return true; +} + +ESPPreferenceObject HostPreferences::make_preference(size_t length, uint32_t type, bool in_flash) { + auto backend = new HostPreferenceBackend(type); + return ESPPreferenceObject(backend); }; void setup_preferences() { auto *pref = new HostPreferences(); // NOLINT(cppcoreguidelines-owning-memory) + host_preferences = pref; global_preferences = pref; } +bool HostPreferenceBackend::save(const uint8_t *data, size_t len) { + return host_preferences->save(this->key_, data, len); +} + +bool HostPreferenceBackend::load(uint8_t *data, size_t len) { return host_preferences->load(this->key_, data, len); } + +HostPreferences *host_preferences; } // namespace host ESPPreferences *global_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) - } // namespace esphome #endif // USE_HOST diff --git a/esphome/components/host/preferences.h b/esphome/components/host/preferences.h index 7462360ec3..6707366517 100644 --- a/esphome/components/host/preferences.h +++ b/esphome/components/host/preferences.h @@ -2,10 +2,63 @@ #ifdef USE_HOST +#include "esphome/core/preferences.h" +#include + namespace esphome { namespace host { +class HostPreferenceBackend : public ESPPreferenceBackend { + public: + explicit HostPreferenceBackend(uint32_t key) { this->key_ = key; } + + bool save(const uint8_t *data, size_t len) override; + bool load(uint8_t *data, size_t len) override; + + protected: + uint32_t key_{}; +}; + +class HostPreferences : public ESPPreferences { + public: + bool sync() override; + bool reset() override; + + ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash) override; + ESPPreferenceObject make_preference(size_t length, uint32_t type) override { + return make_preference(length, type, false); + } + + bool save(uint32_t key, const uint8_t *data, size_t len) { + if (len > 255) + return false; + this->setup_(); + std::vector vec(data, data + len); + this->data[key] = vec; + return true; + } + + bool load(uint32_t key, uint8_t *data, size_t len) { + if (len > 255) + return false; + this->setup_(); + if (this->data.count(key) == 0) + return false; + auto vec = this->data[key]; + if (vec.size() != len) + return false; + memcpy(data, vec.data(), len); + return true; + } + + protected: + void setup_(); + bool setup_complete_{}; + std::string filename_{}; + std::map> data{}; +}; void setup_preferences(); +extern HostPreferences *host_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) } // namespace host } // namespace esphome From f5ac1bd90598701cf579c22aaeb9b740e396cb67 Mon Sep 17 00:00:00 2001 From: ebw44 Date: Tue, 26 Mar 2024 11:20:15 +1300 Subject: [PATCH 154/189] microWakeWord: Fix model path joining (#6426) --- esphome/components/micro_wake_word/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/micro_wake_word/__init__.py b/esphome/components/micro_wake_word/__init__.py index 209a1412ca..9073d103f1 100644 --- a/esphome/components/micro_wake_word/__init__.py +++ b/esphome/components/micro_wake_word/__init__.py @@ -287,7 +287,7 @@ def _load_model_data(manifest_path: Path): except cv.Invalid as e: raise EsphomeError(f"Invalid manifest file: {e}") from e - model_path = urljoin(str(manifest_path), manifest[CONF_MODEL]) + model_path = manifest_path.parent / manifest[CONF_MODEL] with open(model_path, "rb") as f: model = f.read() From 7cb8f99884d6af18efd1b08e47634c488815f1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Poczkodi?= Date: Mon, 25 Mar 2024 23:34:47 +0100 Subject: [PATCH 155/189] Don't compile strptime unless its required (#6424) --- esphome/core/time.cpp | 6 ++++++ esphome/core/time.h | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/esphome/core/time.cpp b/esphome/core/time.cpp index 2e46a611e6..ae4fabac52 100644 --- a/esphome/core/time.cpp +++ b/esphome/core/time.cpp @@ -1,4 +1,6 @@ +#ifdef USE_DATETIME #include +#endif #include "helpers.h" #include "time.h" // NOLINT @@ -64,6 +66,8 @@ std::string ESPTime::strftime(const std::string &format) { return timestr; } +#ifdef USE_DATETIME + bool ESPTime::strptime(const std::string &time_to_parse, ESPTime &esp_time) { // clang-format off std::regex dt_regex(R"(^ @@ -102,6 +106,8 @@ bool ESPTime::strptime(const std::string &time_to_parse, ESPTime &esp_time) { return true; } +#endif + void ESPTime::increment_second() { this->timestamp++; if (!increment_time_value(this->second, 0, 60)) diff --git a/esphome/core/time.h b/esphome/core/time.h index 4300cf26b7..738a0261c7 100644 --- a/esphome/core/time.h +++ b/esphome/core/time.h @@ -67,6 +67,8 @@ struct ESPTime { this->day_of_year < 367 && this->month > 0 && this->month < 13; } +#ifdef USE_DATETIME + /** Convert a string to ESPTime struct as specified by the format argument. * @param time_to_parse null-terminated c string formatet like this: 2020-08-25 05:30:00. * @param esp_time an instance of a ESPTime struct @@ -74,6 +76,8 @@ struct ESPTime { */ static bool strptime(const std::string &time_to_parse, ESPTime &esp_time); +#endif + /// Convert a C tm struct instance with a C unix epoch timestamp to an ESPTime instance. static ESPTime from_c_tm(struct tm *c_tm, time_t c_time); From 2345e7606a1ef2d1ec89e36d487666e9be8b2496 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 25 Mar 2024 21:24:58 -1000 Subject: [PATCH 156/189] Fix editor live validation (#6431) --- esphome/config.py | 24 ++++++++++++----------- esphome/config_helpers.py | 24 ----------------------- esphome/vscode.py | 41 +++++++++++++++++++++++++++++++++------ esphome/yaml_util.py | 25 ++++++++++++++---------- 4 files changed, 63 insertions(+), 51 deletions(-) diff --git a/esphome/config.py b/esphome/config.py index f5a1ebb8d7..c5764dd4f2 100644 --- a/esphome/config.py +++ b/esphome/config.py @@ -1,10 +1,11 @@ +from __future__ import annotations import abc import functools import heapq import logging import re -from typing import Optional, Union +from typing import Union, Any from contextlib import contextmanager import contextvars @@ -76,7 +77,7 @@ def _path_begins_with(path: ConfigPath, other: ConfigPath) -> bool: @functools.total_ordering class _ValidationStepTask: - def __init__(self, priority: float, id_number: int, step: "ConfigValidationStep"): + def __init__(self, priority: float, id_number: int, step: ConfigValidationStep): self.priority = priority self.id_number = id_number self.step = step @@ -130,7 +131,7 @@ class Config(OrderedDict, fv.FinalValidateConfig): ) self.errors.append(error) - def add_validation_step(self, step: "ConfigValidationStep"): + def add_validation_step(self, step: ConfigValidationStep): id_num = self._validation_tasks_id self._validation_tasks_id += 1 heapq.heappush( @@ -172,7 +173,7 @@ class Config(OrderedDict, fv.FinalValidateConfig): conf = conf[key] conf[path[-1]] = value - def get_error_for_path(self, path: ConfigPath) -> Optional[vol.Invalid]: + def get_error_for_path(self, path: ConfigPath) -> vol.Invalid | None: for err in self.errors: if self.get_deepest_path(err.path) == path: self.errors.remove(err) @@ -181,7 +182,7 @@ class Config(OrderedDict, fv.FinalValidateConfig): def get_deepest_document_range_for_path( self, path: ConfigPath, get_key: bool = False - ) -> Optional[ESPHomeDataBase]: + ) -> ESPHomeDataBase | None: data = self doc_range = None for index, path_item in enumerate(path): @@ -733,7 +734,9 @@ class PinUseValidationCheck(ConfigValidationStep): pins.PIN_SCHEMA_REGISTRY.final_validate(result) -def validate_config(config, command_line_substitutions) -> Config: +def validate_config( + config: dict[str, Any], command_line_substitutions: dict[str, Any] +) -> Config: result = Config() loader.clear_component_meta_finders() @@ -897,24 +900,23 @@ class InvalidYAMLError(EsphomeError): self.base_exc = base_exc -def _load_config(command_line_substitutions): +def _load_config(command_line_substitutions: dict[str, Any]) -> Config: + """Load the configuration file.""" try: config = yaml_util.load_yaml(CORE.config_path) except EsphomeError as e: raise InvalidYAMLError(e) from e try: - result = validate_config(config, command_line_substitutions) + return validate_config(config, command_line_substitutions) except EsphomeError: raise except Exception: _LOGGER.error("Unexpected exception while reading configuration:") raise - return result - -def load_config(command_line_substitutions): +def load_config(command_line_substitutions: dict[str, Any]) -> Config: try: return _load_config(command_line_substitutions) except vol.Invalid as err: diff --git a/esphome/config_helpers.py b/esphome/config_helpers.py index ac52c6ede2..7b47e097c8 100644 --- a/esphome/config_helpers.py +++ b/esphome/config_helpers.py @@ -1,9 +1,4 @@ -import json -import os - from esphome.const import CONF_ID -from esphome.core import CORE -from esphome.helpers import read_file class Extend: @@ -38,25 +33,6 @@ class Remove: return isinstance(b, Remove) and self.value == b.value -def read_config_file(path: str) -> str: - if CORE.vscode and ( - not CORE.ace or os.path.abspath(path) == os.path.abspath(CORE.config_path) - ): - print( - json.dumps( - { - "type": "read_file", - "path": path, - } - ) - ) - data = json.loads(input()) - assert data["type"] == "file_response" - return data["content"] - - return read_file(path) - - def merge_config(full_old, full_new): def merge(old, new): if isinstance(new, dict): diff --git a/esphome/vscode.py b/esphome/vscode.py index cb2f51976f..8198d2659a 100644 --- a/esphome/vscode.py +++ b/esphome/vscode.py @@ -1,20 +1,22 @@ +from __future__ import annotations import json import os +from io import StringIO +from typing import Any -from typing import Optional - -from esphome.config import load_config, _format_vol_invalid, Config +from esphome.yaml_util import parse_yaml +from esphome.config import validate_config, _format_vol_invalid, Config from esphome.core import CORE, DocumentRange import esphome.config_validation as cv -def _get_invalid_range(res: Config, invalid: cv.Invalid) -> Optional[DocumentRange]: +def _get_invalid_range(res: Config, invalid: cv.Invalid) -> DocumentRange | None: return res.get_deepest_document_range_for_path( invalid.path, invalid.error_message == "extra keys not allowed" ) -def _dump_range(range: Optional[DocumentRange]) -> Optional[dict]: +def _dump_range(range: DocumentRange | None) -> dict | None: if range is None: return None return { @@ -56,6 +58,25 @@ class VSCodeResult: ) +def _read_file_content_from_json_on_stdin() -> str: + """Read the content of a json encoded file from stdin.""" + data = json.loads(input()) + assert data["type"] == "file_response" + return data["content"] + + +def _print_file_read_event(path: str) -> None: + """Print a file read event.""" + print( + json.dumps( + { + "type": "read_file", + "path": path, + } + ) + ) + + def read_config(args): while True: CORE.reset() @@ -68,9 +89,17 @@ def read_config(args): CORE.config_path = os.path.join(args.configuration, f) else: CORE.config_path = data["file"] + + file_name = CORE.config_path + _print_file_read_event(file_name) + raw_yaml = _read_file_content_from_json_on_stdin() + command_line_substitutions: dict[str, Any] = ( + dict(args.substitution) if args.substitution else {} + ) vs = VSCodeResult() try: - res = load_config(dict(args.substitution) if args.substitution else {}) + config = parse_yaml(file_name, StringIO(raw_yaml)) + res = validate_config(config, command_line_substitutions) except Exception as err: # pylint: disable=broad-except vs.add_yaml_error(str(err)) else: diff --git a/esphome/yaml_util.py b/esphome/yaml_util.py index 60705082b6..c7aa78201f 100644 --- a/esphome/yaml_util.py +++ b/esphome/yaml_util.py @@ -417,20 +417,25 @@ def load_yaml(fname: str, clear_secrets: bool = True) -> Any: return _load_yaml_internal(fname) +def parse_yaml(file_name: str, file_handle: TextIOWrapper) -> Any: + """Parse a YAML file.""" + try: + return _load_yaml_internal_with_type(ESPHomeLoader, file_name, file_handle) + except EsphomeError: + # Loading failed, so we now load with the Python loader which has more + # readable exceptions + # Rewind the stream so we can try again + file_handle.seek(0, 0) + return _load_yaml_internal_with_type( + ESPHomePurePythonLoader, file_name, file_handle + ) + + def _load_yaml_internal(fname: str) -> Any: """Load a YAML file.""" try: with open(fname, encoding="utf-8") as f_handle: - try: - return _load_yaml_internal_with_type(ESPHomeLoader, fname, f_handle) - except EsphomeError: - # Loading failed, so we now load with the Python loader which has more - # readable exceptions - # Rewind the stream so we can try again - f_handle.seek(0, 0) - return _load_yaml_internal_with_type( - ESPHomePurePythonLoader, fname, f_handle - ) + return parse_yaml(fname, f_handle) except (UnicodeDecodeError, OSError) as err: raise EsphomeError(f"Error reading file {fname}: {err}") from err From 952ccf554be11d4505db833c62186cfd8ae3eb1b Mon Sep 17 00:00:00 2001 From: X-Ryl669 Date: Tue, 26 Mar 2024 23:51:56 +0100 Subject: [PATCH 157/189] Add support for AT581x component (#6297) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- CODEOWNERS | 1 + esphome/components/at581x/__init__.py | 224 ++++++++++++++++++ esphome/components/at581x/at581x.cpp | 195 +++++++++++++++ esphome/components/at581x/at581x.h | 62 +++++ esphome/components/at581x/automation.h | 71 ++++++ esphome/components/at581x/switch/__init__.py | 31 +++ .../components/at581x/switch/rf_switch.cpp | 12 + esphome/components/at581x/switch/rf_switch.h | 15 ++ .../components/at581x/test.esp32-c3-idf.yaml | 38 +++ tests/components/at581x/test.esp32-c3.yaml | 38 +++ tests/components/at581x/test.esp32-idf.yaml | 38 +++ tests/components/at581x/test.esp32.yaml | 38 +++ tests/components/at581x/test.esp8266.yaml | 38 +++ tests/components/at581x/test.rp2040.yaml | 38 +++ 14 files changed, 839 insertions(+) create mode 100644 esphome/components/at581x/__init__.py create mode 100644 esphome/components/at581x/at581x.cpp create mode 100644 esphome/components/at581x/at581x.h create mode 100644 esphome/components/at581x/automation.h create mode 100644 esphome/components/at581x/switch/__init__.py create mode 100644 esphome/components/at581x/switch/rf_switch.cpp create mode 100644 esphome/components/at581x/switch/rf_switch.h create mode 100644 tests/components/at581x/test.esp32-c3-idf.yaml create mode 100644 tests/components/at581x/test.esp32-c3.yaml create mode 100644 tests/components/at581x/test.esp32-idf.yaml create mode 100644 tests/components/at581x/test.esp32.yaml create mode 100644 tests/components/at581x/test.esp8266.yaml create mode 100644 tests/components/at581x/test.rp2040.yaml diff --git a/CODEOWNERS b/CODEOWNERS index 2c1b8f04ae..b924f55d0b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -42,6 +42,7 @@ esphome/components/as5600/* @ammmze esphome/components/as5600/sensor/* @ammmze esphome/components/as7341/* @mrgnr esphome/components/async_tcp/* @OttoWinter +esphome/components/at581x/* @X-Ryl669 esphome/components/atc_mithermometer/* @ahpohl esphome/components/atm90e26/* @danieltwagner esphome/components/b_parasite/* @rbaron diff --git a/esphome/components/at581x/__init__.py b/esphome/components/at581x/__init__.py new file mode 100644 index 0000000000..2860d21f6c --- /dev/null +++ b/esphome/components/at581x/__init__.py @@ -0,0 +1,224 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome import automation, core +from esphome.components import i2c +from esphome.automation import maybe_simple_id +from esphome.const import ( + CONF_ID, + CONF_FREQUENCY, +) + + +CODEOWNERS = ["@X-Ryl669"] +DEPENDENCIES = ["i2c"] +MULTI_CONF = True + + +at581x_ns = cg.esphome_ns.namespace("at581x") +AT581XComponent = at581x_ns.class_("AT581XComponent", cg.Component, i2c.I2CDevice) + + +CONF_AT581X_ID = "at581x_id" + + +CONF_SENSING_DISTANCE = "sensing_distance" +CONF_SENSITIVITY = "sensitivity" +CONF_POWERON_SELFCHECK_TIME = "poweron_selfcheck_time" +CONF_PROTECT_TIME = "protect_time" +CONF_TRIGGER_BASE = "trigger_base" +CONF_TRIGGER_KEEP = "trigger_keep" +CONF_STAGE_GAIN = "stage_gain" +CONF_POWER_CONSUMPTION = "power_consumption" +CONF_HW_FRONTEND_RESET = "hw_frontend_reset" + +RADAR_ALLOWED_FREQ = [ + 5696e6, + 5715e6, + 5730e6, + 5748e6, + 5765e6, + 5784e6, + 5800e6, + 5819e6, + 5836e6, + 5851e6, + 5869e6, + 5888e6, +] +RADAR_ALLOWED_CUR_CONSUMPTION = [ + 48e-6, + 56e-6, + 63e-6, + 70e-6, + 77e-6, + 91e-6, + 105e-6, + 115e-6, + 40e-6, + 44e-6, + 47e-6, + 51e-6, + 54e-6, + 61e-6, + 68e-6, + 78e-6, +] + +CONFIG_SCHEMA = cv.Schema( + { + cv.GenerateID(): cv.declare_id(AT581XComponent), + } +) + +CONFIG_SCHEMA = cv.All( + CONFIG_SCHEMA.extend(i2c.i2c_device_schema(0x28)).extend(cv.COMPONENT_SCHEMA) +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) + await i2c.register_i2c_device(var, config) + + +# Actions +AT581XResetAction = at581x_ns.class_("AT581XResetAction", automation.Action) +AT581XSettingsAction = at581x_ns.class_("AT581XSettingsAction", automation.Action) + + +@automation.register_action( + "at581x.reset", + AT581XResetAction, + maybe_simple_id( + { + cv.Required(CONF_ID): cv.use_id(AT581XComponent), + } + ), +) +async def at581x_reset_to_code(config, action_id, template_arg, args): + var = cg.new_Pvariable(action_id, template_arg) + await cg.register_parented(var, config[CONF_ID]) + + return var + + +RADAR_SETTINGS_SCHEMA = cv.Schema( + { + cv.Required(CONF_ID): cv.use_id(AT581XComponent), + cv.Optional(CONF_HW_FRONTEND_RESET): cv.templatable(cv.boolean), + cv.Optional(CONF_FREQUENCY, default="5800MHz"): cv.templatable( + cv.All(cv.frequency, cv.one_of(*RADAR_ALLOWED_FREQ)) + ), + cv.Optional(CONF_SENSING_DISTANCE, default=823): cv.templatable( + cv.int_range(min=0, max=1023) + ), + cv.Optional(CONF_POWERON_SELFCHECK_TIME, default="2000ms"): cv.templatable( + cv.All( + cv.positive_time_period_milliseconds, + cv.Range(max=core.TimePeriod(milliseconds=65535)), + ) + ), + cv.Optional(CONF_POWER_CONSUMPTION, default="70uA"): cv.templatable( + cv.All(cv.current, cv.one_of(*RADAR_ALLOWED_CUR_CONSUMPTION)) + ), + cv.Optional(CONF_PROTECT_TIME, default="1000ms"): cv.templatable( + cv.All( + cv.positive_time_period_milliseconds, + cv.Range( + min=core.TimePeriod(milliseconds=1), + max=core.TimePeriod(milliseconds=65535), + ), + ) + ), + cv.Optional(CONF_TRIGGER_BASE, default="500ms"): cv.templatable( + cv.All( + cv.positive_time_period_milliseconds, + cv.Range( + min=core.TimePeriod(milliseconds=1), + max=core.TimePeriod(milliseconds=65535), + ), + ) + ), + cv.Optional(CONF_TRIGGER_KEEP, default="1500ms"): cv.templatable( + cv.All( + cv.positive_time_period_milliseconds, + cv.Range( + min=core.TimePeriod(milliseconds=1), + max=core.TimePeriod(milliseconds=65535), + ), + ) + ), + cv.Optional(CONF_STAGE_GAIN, default=3): cv.templatable( + cv.int_range(min=0, max=12) + ), + } +).add_extra( + cv.has_at_least_one_key( + CONF_HW_FRONTEND_RESET, + CONF_FREQUENCY, + CONF_SENSING_DISTANCE, + ) +) + + +@automation.register_action( + "at581x.settings", + AT581XSettingsAction, + RADAR_SETTINGS_SCHEMA, +) +async def at581x_settings_to_code(config, action_id, template_arg, args): + var = cg.new_Pvariable(action_id, template_arg) + await cg.register_parented(var, config[CONF_ID]) + + # Radar configuration + if frontend_reset := config.get(CONF_HW_FRONTEND_RESET): + template_ = await cg.templatable(frontend_reset, args, int) + cg.add(var.set_hw_frontend_reset(template_)) + + if freq := config.get(CONF_FREQUENCY): + template_ = await cg.templatable(freq, args, float) + template_ = int(template_ / 1000000) + cg.add(var.set_frequency(template_)) + + if sens_dist := config.get(CONF_SENSING_DISTANCE): + template_ = await cg.templatable(sens_dist, args, int) + cg.add(var.set_sensing_distance(template_)) + + if selfcheck := config.get(CONF_POWERON_SELFCHECK_TIME): + template_ = await cg.templatable(selfcheck, args, float) + if isinstance(template_, cv.TimePeriod): + template_ = template_.total_milliseconds + template_ = int(template_) + cg.add(var.set_poweron_selfcheck_time(template_)) + + if protect := config.get(CONF_PROTECT_TIME): + template_ = await cg.templatable(protect, args, float) + if isinstance(template_, cv.TimePeriod): + template_ = template_.total_milliseconds + template_ = int(template_) + cg.add(var.set_protect_time(template_)) + + if trig_base := config.get(CONF_TRIGGER_BASE): + template_ = await cg.templatable(trig_base, args, float) + if isinstance(template_, cv.TimePeriod): + template_ = template_.total_milliseconds + template_ = int(template_) + cg.add(var.set_trigger_base(template_)) + + if trig_keep := config.get(CONF_TRIGGER_KEEP): + template_ = await cg.templatable(trig_keep, args, float) + if isinstance(template_, cv.TimePeriod): + template_ = template_.total_milliseconds + template_ = int(template_) + cg.add(var.set_trigger_keep(template_)) + + if stage_gain := config.get(CONF_STAGE_GAIN): + template_ = await cg.templatable(stage_gain, args, int) + cg.add(var.set_stage_gain(template_)) + + if power := config.get(CONF_POWER_CONSUMPTION): + template_ = await cg.templatable(power, args, float) + template_ = int(template_ * 1000000) + cg.add(var.set_power_consumption(template_)) + + return var diff --git a/esphome/components/at581x/at581x.cpp b/esphome/components/at581x/at581x.cpp new file mode 100644 index 0000000000..eef457f985 --- /dev/null +++ b/esphome/components/at581x/at581x.cpp @@ -0,0 +1,195 @@ +#include "at581x.h" +#include "esphome/core/log.h" + +/* Select gain for AT581X (3dB per step for level1, 6dB per step for level 2), high value = small gain. (p12) */ +const uint8_t GAIN_ADDR_TABLE[] = {0x5c, 0x63}; +const uint8_t GAIN5C_TABLE[] = {0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8, 0xb8, 0xc8}; +const uint8_t GAIN63_TABLE[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; +const uint8_t GAIN61_VALUE = 0xCA; // 0xC0 | 0x02 (freq present) | 0x08 (gain present) + +/*!< Power consumption configuration table (p12). */ +const uint8_t POWER_TABLE[] = {48, 56, 63, 70, 77, 91, 105, 115, 40, 44, 47, 51, 54, 61, 68, 78}; +const uint8_t POWER67_TABLE[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7}; +const uint8_t POWER68_TABLE[] = {0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, + 24, 24, 24, 24, 24, 24, 24, 24}; // See Page 12, shift by 3 bits + +/*!< Frequency Configuration table (p14/15 of datasheet). */ +const uint8_t FREQ_ADDR = 0x61; +const uint16_t FREQ_TABLE[] = {5696, 5715, 5730, 5748, 5765, 5784, 5800, 5819, 5836, 5851, 5869, 5888}; +const uint8_t FREQ5F_TABLE[] = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x40, 0x41, 0x42, 0x43}; +const uint8_t FREQ60_TABLE[] = {0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9e}; + +/*!< Value for RF and analog modules switch (p10). */ +const uint8_t RF_OFF_TABLE[] = {0x46, 0xaa, 0x50}; +const uint8_t RF_ON_TABLE[] = {0x45, 0x55, 0xA0}; +const uint8_t RF_REG_ADDR[] = {0x5d, 0x62, 0x51}; + +/*!< Registers of Lighting delay time. Unit: ms, min 2s (p8) */ +const uint8_t HIGH_LEVEL_DELAY_CONTROL_ADDR = 0x41; /*!< Time_flag_out_ctrl 0x01 */ +const uint8_t HIGH_LEVEL_DELAY_VALUE_ADDR = 0x42; /*!< Time_flag_out_1 Bit<7:0> */ + +const uint8_t RESET_ADDR = 0x00; + +/*!< Sensing distance address */ +const uint8_t SIGNAL_DETECTION_THRESHOLD_ADDR_LO = 0x10; +const uint8_t SIGNAL_DETECTION_THRESHOLD_ADDR_HI = 0x11; + +/*!< Bit field value for power registers */ +const uint8_t POWER_THRESHOLD_ADDR_HI = 0x68; +const uint8_t POWER_THRESHOLD_ADDR_LO = 0x67; +const uint8_t PWR_WORK_TIME_EN = 8; // Reg 0x67 +const uint8_t PWR_BURST_TIME_EN = 32; // Reg 0x68 +const uint8_t PWR_THRESH_EN = 64; // Reg 0x68 +const uint8_t PWR_THRESH_VAL_EN = 128; // Reg 0x67 + +/*!< Times */ +const uint8_t TRIGGER_BASE_TIME_ADDR = 0x3D; // 4 bytes, so up to 0x40 +const uint8_t PROTECT_TIME_ADDR = 0x4E; // 2 bytes, up to 0x4F +const uint8_t TRIGGER_KEEP_TIME_ADDR = 0x42; // 4 bytes, so up to 0x45 +const uint8_t TIME41_VALUE = 1; +const uint8_t SELF_CHECK_TIME_ADDR = 0x38; // 2 bytes, up to 0x39 + +namespace esphome { +namespace at581x { + +static const char *const TAG = "at581x"; + +bool AT581XComponent::i2c_write_reg(uint8_t addr, uint8_t data) { + return this->write_register(addr, &data, 1) == esphome::i2c::NO_ERROR; +} +bool AT581XComponent::i2c_write_reg(uint8_t addr, uint32_t data) { + return this->i2c_write_reg(addr + 0, uint8_t(data & 0xFF)) && + this->i2c_write_reg(addr + 1, uint8_t((data >> 8) & 0xFF)) && + this->i2c_write_reg(addr + 2, uint8_t((data >> 16) & 0xFF)) && + this->i2c_write_reg(addr + 3, uint8_t((data >> 24) & 0xFF)); +} +bool AT581XComponent::i2c_write_reg(uint8_t addr, uint16_t data) { + return this->i2c_write_reg(addr, uint8_t(data & 0xFF)) && this->i2c_write_reg(addr + 1, uint8_t((data >> 8) & 0xFF)); +} + +bool AT581XComponent::i2c_read_reg(uint8_t addr, uint8_t &data) { + return this->read_register(addr, &data, 1) == esphome::i2c::NO_ERROR; +} + +void AT581XComponent::setup() { ESP_LOGCONFIG(TAG, "Setting up AT581X..."); } +void AT581XComponent::dump_config() { LOG_I2C_DEVICE(this); } +#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0])) +bool AT581XComponent::i2c_write_config() { + ESP_LOGCONFIG(TAG, "Writing new config for AT581X..."); + ESP_LOGCONFIG(TAG, "Frequency: %dMHz", this->freq_); + ESP_LOGCONFIG(TAG, "Sensing distance: %d", this->delta_); + ESP_LOGCONFIG(TAG, "Power: %dµA", this->power_); + ESP_LOGCONFIG(TAG, "Gain: %d", this->gain_); + ESP_LOGCONFIG(TAG, "Trigger base time: %dms", this->trigger_base_time_ms_); + ESP_LOGCONFIG(TAG, "Trigger keep time: %dms", this->trigger_keep_time_ms_); + ESP_LOGCONFIG(TAG, "Protect time: %dms", this->protect_time_ms_); + ESP_LOGCONFIG(TAG, "Self check time: %dms", this->self_check_time_ms_); + + // Set frequency point + if (!this->i2c_write_reg(FREQ_ADDR, GAIN61_VALUE)) { + ESP_LOGE(TAG, "Failed to write AT581X Freq mode"); + return false; + } + // Find the current frequency from the table to know what value to write + for (size_t i = 0; i < ARRAY_SIZE(FREQ_TABLE) + 1; i++) { + if (i == ARRAY_SIZE(FREQ_TABLE)) { + ESP_LOGE(TAG, "Set frequency not found"); + return false; + } + if (FREQ_TABLE[i] == this->freq_) { + if (!this->i2c_write_reg(0x5F, FREQ5F_TABLE[i]) || !this->i2c_write_reg(0x60, FREQ60_TABLE[i])) { + ESP_LOGE(TAG, "Failed to write AT581X Freq value"); + return false; + } + break; + } + } + + // Set distance + if (!this->i2c_write_reg(SIGNAL_DETECTION_THRESHOLD_ADDR_LO, (uint8_t) (this->delta_ & 0xFF)) || + !this->i2c_write_reg(SIGNAL_DETECTION_THRESHOLD_ADDR_HI, (uint8_t) (this->delta_ >> 8))) { + ESP_LOGE(TAG, "Failed to write AT581X sensing distance low"); + return false; + } + + // Set power setting + uint8_t pwr67 = PWR_THRESH_VAL_EN | PWR_WORK_TIME_EN, pwr68 = PWR_BURST_TIME_EN | PWR_THRESH_EN; + for (size_t i = 0; i < ARRAY_SIZE(POWER_TABLE) + 1; i++) { + if (i == ARRAY_SIZE(POWER_TABLE)) { + ESP_LOGE(TAG, "Set power not found"); + return false; + } + if (POWER_TABLE[i] == this->power_) { + pwr67 |= POWER67_TABLE[i]; + pwr68 |= POWER68_TABLE[i]; // See Page 12 + break; + } + } + + if (!this->i2c_write_reg(POWER_THRESHOLD_ADDR_LO, pwr67) || !this->i2c_write_reg(POWER_THRESHOLD_ADDR_HI, pwr68)) { + ESP_LOGE(TAG, "Failed to write AT581X power registers"); + return false; + } + + // Set gain + if (!this->i2c_write_reg(GAIN_ADDR_TABLE[0], GAIN5C_TABLE[this->gain_]) || + !this->i2c_write_reg(GAIN_ADDR_TABLE[1], GAIN63_TABLE[this->gain_ >> 1])) { + ESP_LOGE(TAG, "Failed to write AT581X gain registers"); + return false; + } + + // Set times + if (!this->i2c_write_reg(TRIGGER_BASE_TIME_ADDR, (uint32_t) this->trigger_base_time_ms_)) { + ESP_LOGE(TAG, "Failed to write AT581X trigger base time registers"); + return false; + } + if (!this->i2c_write_reg(TRIGGER_KEEP_TIME_ADDR, (uint32_t) this->trigger_keep_time_ms_)) { + ESP_LOGE(TAG, "Failed to write AT581X trigger keep time registers"); + return false; + } + + if (!this->i2c_write_reg(PROTECT_TIME_ADDR, (uint16_t) this->protect_time_ms_)) { + ESP_LOGE(TAG, "Failed to write AT581X protect time registers"); + return false; + } + if (!this->i2c_write_reg(SELF_CHECK_TIME_ADDR, (uint16_t) this->self_check_time_ms_)) { + ESP_LOGE(TAG, "Failed to write AT581X self check time registers"); + return false; + } + + if (!this->i2c_write_reg(0x41, TIME41_VALUE)) { + ESP_LOGE(TAG, "Failed to enable AT581X time registers"); + return false; + } + + // Don't know why it's required in other code, it's not in datasheet + if (!this->i2c_write_reg(0x55, (uint8_t) 0x04)) { + ESP_LOGE(TAG, "Failed to enable AT581X"); + return false; + } + + // Ok, config is written, let's reset the chip so it's using the new config + return this->reset_hardware_frontend(); +} + +// float AT581XComponent::get_setup_priority() const { return 0; } +bool AT581XComponent::reset_hardware_frontend() { + if (!this->i2c_write_reg(RESET_ADDR, (uint8_t) 0) || !this->i2c_write_reg(RESET_ADDR, (uint8_t) 1)) { + ESP_LOGE(TAG, "Failed to reset AT581X hardware frontend"); + return false; + } + return true; +} + +void AT581XComponent::set_rf_mode(bool enable) { + const uint8_t *p = enable ? &RF_ON_TABLE[0] : &RF_OFF_TABLE[0]; + for (size_t i = 0; i < ARRAY_SIZE(RF_REG_ADDR); i++) { + if (!this->i2c_write_reg(RF_REG_ADDR[i], p[i])) { + ESP_LOGE(TAG, "Failed to write AT581X RF mode"); + return; + } + } +} + +} // namespace at581x +} // namespace esphome diff --git a/esphome/components/at581x/at581x.h b/esphome/components/at581x/at581x.h new file mode 100644 index 0000000000..6c637d08c5 --- /dev/null +++ b/esphome/components/at581x/at581x.h @@ -0,0 +1,62 @@ +#pragma once + +#include + +#include "esphome/core/component.h" +#include "esphome/core/hal.h" +#include "esphome/core/defines.h" +#ifdef USE_SWITCH +#include "esphome/components/switch/switch.h" +#endif +#include "esphome/components/i2c/i2c.h" + +namespace esphome { +namespace at581x { + +class AT581XComponent : public Component, public i2c::I2CDevice { +#ifdef USE_SWITCH + protected: + switch_::Switch *rf_power_switch_{nullptr}; + + public: + void set_rf_power_switch(switch_::Switch *s) { + this->rf_power_switch_ = s; + s->turn_on(); + } +#endif + + void setup() override; + void dump_config() override; + // float get_setup_priority() const override; + + void set_sensing_distance(int distance) { this->delta_ = 1023 - distance; } + + void set_rf_mode(bool enabled); + void set_frequency(int frequency) { this->freq_ = frequency; } + void set_poweron_selfcheck_time(int value) { this->self_check_time_ms_ = value; } + void set_protect_time(int value) { this->protect_time_ms_ = value; } + void set_trigger_base(int value) { this->trigger_base_time_ms_ = value; } + void set_trigger_keep(int value) { this->trigger_keep_time_ms_ = value; } + void set_stage_gain(int value) { this->gain_ = value; } + void set_power_consumption(int value) { this->power_ = value; } + + bool i2c_write_config(); + bool reset_hardware_frontend(); + bool i2c_write_reg(uint8_t addr, uint8_t data); + bool i2c_write_reg(uint8_t addr, uint32_t data); + bool i2c_write_reg(uint8_t addr, uint16_t data); + bool i2c_read_reg(uint8_t addr, uint8_t &data); + + protected: + int freq_; + int self_check_time_ms_; /*!< Power-on self-test time, range: 0 ~ 65536 ms */ + int protect_time_ms_; /*!< Protection time, recommended 1000 ms */ + int trigger_base_time_ms_; /*!< Default: 500 ms */ + int trigger_keep_time_ms_; /*!< Total trig time = TRIGGER_BASE_TIME + DEF_TRIGGER_KEEP_TIME, minimum: 1 */ + int delta_; /*!< Delta value: 0 ~ 1023, the larger the value, the shorter the distance */ + int gain_; /*!< Default: 9dB */ + int power_; /*!< In µA */ +}; + +} // namespace at581x +} // namespace esphome diff --git a/esphome/components/at581x/automation.h b/esphome/components/at581x/automation.h new file mode 100644 index 0000000000..4863a87565 --- /dev/null +++ b/esphome/components/at581x/automation.h @@ -0,0 +1,71 @@ +#pragma once + +#include "esphome/core/automation.h" +#include "esphome/core/helpers.h" + +#include "at581x.h" + +namespace esphome { +namespace at581x { + +template class AT581XResetAction : public Action, public Parented { + public: + void play(Ts... x) { this->parent_->reset_hardware_frontend(); } +}; + +template class AT581XSettingsAction : public Action, public Parented { + public: + TEMPLATABLE_VALUE(int8_t, hw_frontend_reset) + TEMPLATABLE_VALUE(int, frequency) + TEMPLATABLE_VALUE(int, sensing_distance) + TEMPLATABLE_VALUE(int, poweron_selfcheck_time) + TEMPLATABLE_VALUE(int, power_consumption) + TEMPLATABLE_VALUE(int, protect_time) + TEMPLATABLE_VALUE(int, trigger_base) + TEMPLATABLE_VALUE(int, trigger_keep) + TEMPLATABLE_VALUE(int, stage_gain) + + void play(Ts... x) { + if (this->frequency_.has_value()) { + int v = this->frequency_.value(x...); + this->parent_->set_frequency(v); + } + if (this->sensing_distance_.has_value()) { + int v = this->sensing_distance_.value(x...); + this->parent_->set_sensing_distance(v); + } + if (this->poweron_selfcheck_time_.has_value()) { + int v = this->poweron_selfcheck_time_.value(x...); + this->parent_->set_poweron_selfcheck_time(v); + } + if (this->power_consumption_.has_value()) { + int v = this->power_consumption_.value(x...); + this->parent_->set_power_consumption(v); + } + if (this->protect_time_.has_value()) { + int v = this->protect_time_.value(x...); + this->parent_->set_protect_time(v); + } + if (this->trigger_base_.has_value()) { + int v = this->trigger_base_.value(x...); + this->parent_->set_trigger_base(v); + } + if (this->trigger_keep_.has_value()) { + int v = this->trigger_keep_.value(x...); + this->parent_->set_trigger_keep(v); + } + if (this->stage_gain_.has_value()) { + int v = this->stage_gain_.value(x...); + this->parent_->set_stage_gain(v); + } + + // This actually perform all the modification on the system + this->parent_->i2c_write_config(); + + if (this->hw_frontend_reset_.has_value() && this->hw_frontend_reset_.value(x...) == true) { + this->parent_->reset_hardware_frontend(); + } + } +}; +} // namespace at581x +} // namespace esphome diff --git a/esphome/components/at581x/switch/__init__.py b/esphome/components/at581x/switch/__init__.py new file mode 100644 index 0000000000..c441b381a3 --- /dev/null +++ b/esphome/components/at581x/switch/__init__.py @@ -0,0 +1,31 @@ +import esphome.codegen as cg +from esphome.components import switch +import esphome.config_validation as cv +from esphome.const import ( + DEVICE_CLASS_SWITCH, + ICON_WIFI, +) +from .. import CONF_AT581X_ID, AT581XComponent, at581x_ns + +DEPENDENCIES = ["at581x"] + +RFSwitch = at581x_ns.class_("RFSwitch", switch.Switch) + +CONFIG_SCHEMA = switch.switch_schema( + RFSwitch, + device_class=DEVICE_CLASS_SWITCH, + icon=ICON_WIFI, +).extend( + cv.Schema( + { + cv.GenerateID(CONF_AT581X_ID): cv.use_id(AT581XComponent), + } + ) +) + + +async def to_code(config): + at581x_component = await cg.get_variable(config[CONF_AT581X_ID]) + s = await switch.new_switch(config) + await cg.register_parented(s, config[CONF_AT581X_ID]) + cg.add(at581x_component.set_rf_power_switch(s)) diff --git a/esphome/components/at581x/switch/rf_switch.cpp b/esphome/components/at581x/switch/rf_switch.cpp new file mode 100644 index 0000000000..f1d03dc8a5 --- /dev/null +++ b/esphome/components/at581x/switch/rf_switch.cpp @@ -0,0 +1,12 @@ +#include "rf_switch.h" + +namespace esphome { +namespace at581x { + +void RFSwitch::write_state(bool state) { + this->publish_state(state); + this->parent_->set_rf_mode(state); +} + +} // namespace at581x +} // namespace esphome diff --git a/esphome/components/at581x/switch/rf_switch.h b/esphome/components/at581x/switch/rf_switch.h new file mode 100644 index 0000000000..920ddbb66a --- /dev/null +++ b/esphome/components/at581x/switch/rf_switch.h @@ -0,0 +1,15 @@ +#pragma once + +#include "esphome/components/switch/switch.h" +#include "../at581x.h" + +namespace esphome { +namespace at581x { + +class RFSwitch : public switch_::Switch, public Parented { + protected: + void write_state(bool state) override; +}; + +} // namespace at581x +} // namespace esphome diff --git a/tests/components/at581x/test.esp32-c3-idf.yaml b/tests/components/at581x/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..b49a283eca --- /dev/null +++ b/tests/components/at581x/test.esp32-c3-idf.yaml @@ -0,0 +1,38 @@ +esphome: + on_boot: + then: + - at581x.settings: + id: "Waveradar" + hw_frontend_reset: false + frequency: 5800MHz + sensing_distance: 200 + poweron_selfcheck_time: 2s + protect_time: 1s + trigger_base: 500ms + trigger_keep: 10s + stage_gain: 3 + power_consumption: 70uA + - at581x.reset: + id: "Waveradar" + +at581x: + id: "Waveradar" + i2c_id: i2c_bus + +i2c: + sda: 8 + scl: 9 + scan: true + frequency: 100kHz + setup_priority: -100 + id: i2c_bus + +binary_sensor: + - platform: gpio + pin: GPIO21 + name: "Radar motion" + +switch: + - platform: at581x + at581x_id: "Waveradar" + name: "Enable Radar" diff --git a/tests/components/at581x/test.esp32-c3.yaml b/tests/components/at581x/test.esp32-c3.yaml new file mode 100644 index 0000000000..b49a283eca --- /dev/null +++ b/tests/components/at581x/test.esp32-c3.yaml @@ -0,0 +1,38 @@ +esphome: + on_boot: + then: + - at581x.settings: + id: "Waveradar" + hw_frontend_reset: false + frequency: 5800MHz + sensing_distance: 200 + poweron_selfcheck_time: 2s + protect_time: 1s + trigger_base: 500ms + trigger_keep: 10s + stage_gain: 3 + power_consumption: 70uA + - at581x.reset: + id: "Waveradar" + +at581x: + id: "Waveradar" + i2c_id: i2c_bus + +i2c: + sda: 8 + scl: 9 + scan: true + frequency: 100kHz + setup_priority: -100 + id: i2c_bus + +binary_sensor: + - platform: gpio + pin: GPIO21 + name: "Radar motion" + +switch: + - platform: at581x + at581x_id: "Waveradar" + name: "Enable Radar" diff --git a/tests/components/at581x/test.esp32-idf.yaml b/tests/components/at581x/test.esp32-idf.yaml new file mode 100644 index 0000000000..ff84e61e1e --- /dev/null +++ b/tests/components/at581x/test.esp32-idf.yaml @@ -0,0 +1,38 @@ +esphome: + on_boot: + then: + - at581x.settings: + id: "Waveradar" + hw_frontend_reset: false + frequency: 5800MHz + sensing_distance: 200 + poweron_selfcheck_time: 2s + protect_time: 1s + trigger_base: 500ms + trigger_keep: 10s + stage_gain: 3 + power_consumption: 70uA + - at581x.reset: + id: "Waveradar" + +at581x: + id: "Waveradar" + i2c_id: i2c_bus + +i2c: + sda: 14 + scl: 15 + scan: true + frequency: 100kHz + setup_priority: -100 + id: i2c_bus + +binary_sensor: + - platform: gpio + pin: GPIO21 + name: "Radar motion" + +switch: + - platform: at581x + at581x_id: "Waveradar" + name: "Enable Radar" diff --git a/tests/components/at581x/test.esp32.yaml b/tests/components/at581x/test.esp32.yaml new file mode 100644 index 0000000000..ff84e61e1e --- /dev/null +++ b/tests/components/at581x/test.esp32.yaml @@ -0,0 +1,38 @@ +esphome: + on_boot: + then: + - at581x.settings: + id: "Waveradar" + hw_frontend_reset: false + frequency: 5800MHz + sensing_distance: 200 + poweron_selfcheck_time: 2s + protect_time: 1s + trigger_base: 500ms + trigger_keep: 10s + stage_gain: 3 + power_consumption: 70uA + - at581x.reset: + id: "Waveradar" + +at581x: + id: "Waveradar" + i2c_id: i2c_bus + +i2c: + sda: 14 + scl: 15 + scan: true + frequency: 100kHz + setup_priority: -100 + id: i2c_bus + +binary_sensor: + - platform: gpio + pin: GPIO21 + name: "Radar motion" + +switch: + - platform: at581x + at581x_id: "Waveradar" + name: "Enable Radar" diff --git a/tests/components/at581x/test.esp8266.yaml b/tests/components/at581x/test.esp8266.yaml new file mode 100644 index 0000000000..a7b0069045 --- /dev/null +++ b/tests/components/at581x/test.esp8266.yaml @@ -0,0 +1,38 @@ +esphome: + on_boot: + then: + - at581x.settings: + id: "Waveradar" + hw_frontend_reset: false + frequency: 5800MHz + sensing_distance: 200 + poweron_selfcheck_time: 2s + protect_time: 1s + trigger_base: 500ms + trigger_keep: 10s + stage_gain: 3 + power_consumption: 70uA + - at581x.reset: + id: "Waveradar" + +at581x: + id: "Waveradar" + i2c_id: i2c_bus + +i2c: + sda: 14 + scl: 15 + scan: true + frequency: 100kHz + setup_priority: -100 + id: i2c_bus + +binary_sensor: + - platform: gpio + pin: GPIO4 + name: "Radar motion" + +switch: + - platform: at581x + at581x_id: "Waveradar" + name: "Enable Radar" diff --git a/tests/components/at581x/test.rp2040.yaml b/tests/components/at581x/test.rp2040.yaml new file mode 100644 index 0000000000..b49a283eca --- /dev/null +++ b/tests/components/at581x/test.rp2040.yaml @@ -0,0 +1,38 @@ +esphome: + on_boot: + then: + - at581x.settings: + id: "Waveradar" + hw_frontend_reset: false + frequency: 5800MHz + sensing_distance: 200 + poweron_selfcheck_time: 2s + protect_time: 1s + trigger_base: 500ms + trigger_keep: 10s + stage_gain: 3 + power_consumption: 70uA + - at581x.reset: + id: "Waveradar" + +at581x: + id: "Waveradar" + i2c_id: i2c_bus + +i2c: + sda: 8 + scl: 9 + scan: true + frequency: 100kHz + setup_priority: -100 + id: i2c_bus + +binary_sensor: + - platform: gpio + pin: GPIO21 + name: "Radar motion" + +switch: + - platform: at581x + at581x_id: "Waveradar" + name: "Enable Radar" From 0948a3c30690f71f6a16c3e28f29edccb68872ba Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Tue, 26 Mar 2024 20:06:57 -0500 Subject: [PATCH 158/189] Add some components to the new testing framework (F) (#6177) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- .../factory_reset/test.esp32-c3-idf.yaml | 3 + .../factory_reset/test.esp32-c3.yaml | 3 + .../factory_reset/test.esp32-idf.yaml | 3 + .../components/factory_reset/test.esp32.yaml | 3 + .../factory_reset/test.esp8266.yaml | 3 + .../components/factory_reset/test.rp2040.yaml | 3 + .../fastled_clockless/test.esp32.yaml | 71 +++++++++++++++++++ tests/components/fastled_spi/test.esp32.yaml | 71 +++++++++++++++++++ .../feedback/test.esp32-c3-idf.yaml | 39 ++++++++++ tests/components/feedback/test.esp32-c3.yaml | 39 ++++++++++ tests/components/feedback/test.esp32-idf.yaml | 39 ++++++++++ tests/components/feedback/test.esp32.yaml | 39 ++++++++++ tests/components/feedback/test.esp8266.yaml | 39 ++++++++++ tests/components/feedback/test.rp2040.yaml | 39 ++++++++++ .../fingerprint_grow/test.esp32-c3-idf.yaml | 56 +++++++++++++++ .../fingerprint_grow/test.esp32-c3.yaml | 56 +++++++++++++++ .../fingerprint_grow/test.esp32-idf.yaml | 56 +++++++++++++++ .../fingerprint_grow/test.esp32.yaml | 56 +++++++++++++++ .../fingerprint_grow/test.esp8266.yaml | 56 +++++++++++++++ .../fingerprint_grow/test.rp2040.yaml | 56 +++++++++++++++ tests/components/font/test.esp32-c3-idf.yaml | 19 +++++ tests/components/font/test.esp32-c3.yaml | 19 +++++ tests/components/font/test.esp32-idf.yaml | 19 +++++ tests/components/font/test.esp8266.yaml | 19 +++++ tests/components/font/test.rp2040.yaml | 19 +++++ .../components/fs3000/test.esp32-c3-idf.yaml | 10 +++ tests/components/fs3000/test.esp32-c3.yaml | 10 +++ tests/components/fs3000/test.esp32-idf.yaml | 10 +++ tests/components/fs3000/test.esp32.yaml | 10 +++ tests/components/fs3000/test.esp8266.yaml | 10 +++ tests/components/fs3000/test.rp2040.yaml | 10 +++ .../components/ft5x06/test.esp32-c3-idf.yaml | 21 ++++++ tests/components/ft5x06/test.esp32-c3.yaml | 21 ++++++ tests/components/ft5x06/test.esp32-idf.yaml | 21 ++++++ tests/components/ft5x06/test.esp32.yaml | 21 ++++++ tests/components/ft5x06/test.esp8266.yaml | 21 ++++++ tests/components/ft5x06/test.rp2040.yaml | 21 ++++++ .../components/ft63x6/test.esp32-c3-idf.yaml | 21 ++++++ tests/components/ft63x6/test.esp32-c3.yaml | 21 ++++++ tests/components/ft63x6/test.esp32-idf.yaml | 21 ++++++ tests/components/ft63x6/test.esp8266.yaml | 21 ++++++ tests/components/ft63x6/test.rp2040.yaml | 21 ++++++ .../fujitsu_general/test.esp32-c3-idf.yaml | 7 ++ .../fujitsu_general/test.esp32-c3.yaml | 7 ++ .../fujitsu_general/test.esp32-idf.yaml | 7 ++ .../fujitsu_general/test.esp32.yaml | 7 ++ .../fujitsu_general/test.esp8266.yaml | 7 ++ 47 files changed, 1151 insertions(+) create mode 100644 tests/components/factory_reset/test.esp32-c3-idf.yaml create mode 100644 tests/components/factory_reset/test.esp32-c3.yaml create mode 100644 tests/components/factory_reset/test.esp32-idf.yaml create mode 100644 tests/components/factory_reset/test.esp32.yaml create mode 100644 tests/components/factory_reset/test.esp8266.yaml create mode 100644 tests/components/factory_reset/test.rp2040.yaml create mode 100644 tests/components/fastled_clockless/test.esp32.yaml create mode 100644 tests/components/fastled_spi/test.esp32.yaml create mode 100644 tests/components/feedback/test.esp32-c3-idf.yaml create mode 100644 tests/components/feedback/test.esp32-c3.yaml create mode 100644 tests/components/feedback/test.esp32-idf.yaml create mode 100644 tests/components/feedback/test.esp32.yaml create mode 100644 tests/components/feedback/test.esp8266.yaml create mode 100644 tests/components/feedback/test.rp2040.yaml create mode 100644 tests/components/fingerprint_grow/test.esp32-c3-idf.yaml create mode 100644 tests/components/fingerprint_grow/test.esp32-c3.yaml create mode 100644 tests/components/fingerprint_grow/test.esp32-idf.yaml create mode 100644 tests/components/fingerprint_grow/test.esp32.yaml create mode 100644 tests/components/fingerprint_grow/test.esp8266.yaml create mode 100644 tests/components/fingerprint_grow/test.rp2040.yaml create mode 100644 tests/components/font/test.esp32-c3-idf.yaml create mode 100644 tests/components/font/test.esp32-c3.yaml create mode 100644 tests/components/font/test.esp32-idf.yaml create mode 100644 tests/components/font/test.esp8266.yaml create mode 100644 tests/components/font/test.rp2040.yaml create mode 100644 tests/components/fs3000/test.esp32-c3-idf.yaml create mode 100644 tests/components/fs3000/test.esp32-c3.yaml create mode 100644 tests/components/fs3000/test.esp32-idf.yaml create mode 100644 tests/components/fs3000/test.esp32.yaml create mode 100644 tests/components/fs3000/test.esp8266.yaml create mode 100644 tests/components/fs3000/test.rp2040.yaml create mode 100644 tests/components/ft5x06/test.esp32-c3-idf.yaml create mode 100644 tests/components/ft5x06/test.esp32-c3.yaml create mode 100644 tests/components/ft5x06/test.esp32-idf.yaml create mode 100644 tests/components/ft5x06/test.esp32.yaml create mode 100644 tests/components/ft5x06/test.esp8266.yaml create mode 100644 tests/components/ft5x06/test.rp2040.yaml create mode 100644 tests/components/ft63x6/test.esp32-c3-idf.yaml create mode 100644 tests/components/ft63x6/test.esp32-c3.yaml create mode 100644 tests/components/ft63x6/test.esp32-idf.yaml create mode 100644 tests/components/ft63x6/test.esp8266.yaml create mode 100644 tests/components/ft63x6/test.rp2040.yaml create mode 100644 tests/components/fujitsu_general/test.esp32-c3-idf.yaml create mode 100644 tests/components/fujitsu_general/test.esp32-c3.yaml create mode 100644 tests/components/fujitsu_general/test.esp32-idf.yaml create mode 100644 tests/components/fujitsu_general/test.esp32.yaml create mode 100644 tests/components/fujitsu_general/test.esp8266.yaml diff --git a/tests/components/factory_reset/test.esp32-c3-idf.yaml b/tests/components/factory_reset/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..ad3abd603e --- /dev/null +++ b/tests/components/factory_reset/test.esp32-c3-idf.yaml @@ -0,0 +1,3 @@ +button: + - platform: factory_reset + name: Reset to Factory Default Settings diff --git a/tests/components/factory_reset/test.esp32-c3.yaml b/tests/components/factory_reset/test.esp32-c3.yaml new file mode 100644 index 0000000000..ad3abd603e --- /dev/null +++ b/tests/components/factory_reset/test.esp32-c3.yaml @@ -0,0 +1,3 @@ +button: + - platform: factory_reset + name: Reset to Factory Default Settings diff --git a/tests/components/factory_reset/test.esp32-idf.yaml b/tests/components/factory_reset/test.esp32-idf.yaml new file mode 100644 index 0000000000..ad3abd603e --- /dev/null +++ b/tests/components/factory_reset/test.esp32-idf.yaml @@ -0,0 +1,3 @@ +button: + - platform: factory_reset + name: Reset to Factory Default Settings diff --git a/tests/components/factory_reset/test.esp32.yaml b/tests/components/factory_reset/test.esp32.yaml new file mode 100644 index 0000000000..ad3abd603e --- /dev/null +++ b/tests/components/factory_reset/test.esp32.yaml @@ -0,0 +1,3 @@ +button: + - platform: factory_reset + name: Reset to Factory Default Settings diff --git a/tests/components/factory_reset/test.esp8266.yaml b/tests/components/factory_reset/test.esp8266.yaml new file mode 100644 index 0000000000..ad3abd603e --- /dev/null +++ b/tests/components/factory_reset/test.esp8266.yaml @@ -0,0 +1,3 @@ +button: + - platform: factory_reset + name: Reset to Factory Default Settings diff --git a/tests/components/factory_reset/test.rp2040.yaml b/tests/components/factory_reset/test.rp2040.yaml new file mode 100644 index 0000000000..ad3abd603e --- /dev/null +++ b/tests/components/factory_reset/test.rp2040.yaml @@ -0,0 +1,3 @@ +button: + - platform: factory_reset + name: Reset to Factory Default Settings diff --git a/tests/components/fastled_clockless/test.esp32.yaml b/tests/components/fastled_clockless/test.esp32.yaml new file mode 100644 index 0000000000..8b1447a17a --- /dev/null +++ b/tests/components/fastled_clockless/test.esp32.yaml @@ -0,0 +1,71 @@ +light: + - platform: fastled_clockless + id: addr1 + chipset: WS2811 + pin: 13 + num_leds: 100 + rgb_order: BRG + max_refresh_rate: 20ms + color_correct: [75%, 100%, 50%] + name: FastLED WS2811 Light + effects: + - addressable_color_wipe: + - addressable_color_wipe: + name: Color Wipe Effect With Custom Values + colors: + - red: 100% + green: 100% + blue: 100% + num_leds: 1 + - red: 0% + green: 0% + blue: 0% + num_leds: 1 + add_led_interval: 100ms + reverse: false + - addressable_scan: + - addressable_scan: + name: Scan Effect With Custom Values + move_interval: 100ms + - addressable_twinkle: + - addressable_twinkle: + name: Twinkle Effect With Custom Values + twinkle_probability: 5% + progress_interval: 4ms + - addressable_random_twinkle: + - addressable_random_twinkle: + name: Random Twinkle Effect With Custom Values + twinkle_probability: 5% + progress_interval: 32ms + - addressable_fireworks: + - addressable_fireworks: + name: Fireworks Effect With Custom Values + update_interval: 32ms + spark_probability: 10% + use_random_color: false + fade_out_rate: 120 + - addressable_flicker: + - addressable_flicker: + name: Flicker Effect With Custom Values + update_interval: 16ms + intensity: 5% + - addressable_lambda: + name: Test For Custom Lambda Effect + lambda: |- + if (initial_run) { + it[0] = current_color; + } + - automation: + name: Custom Effect + sequence: + - light.addressable_set: + id: addr1 + red: 100% + green: 100% + blue: 0% + - delay: 100ms + - light.addressable_set: + id: addr1 + red: 0% + green: 100% + blue: 0% diff --git a/tests/components/fastled_spi/test.esp32.yaml b/tests/components/fastled_spi/test.esp32.yaml new file mode 100644 index 0000000000..f6f7c5553b --- /dev/null +++ b/tests/components/fastled_spi/test.esp32.yaml @@ -0,0 +1,71 @@ +light: + - platform: fastled_spi + id: addr1 + chipset: WS2801 + clock_pin: 22 + data_pin: 23 + data_rate: 2MHz + num_leds: 60 + rgb_order: BRG + name: FastLED SPI Light + effects: + - addressable_color_wipe: + - addressable_color_wipe: + name: Color Wipe Effect With Custom Values + colors: + - red: 100% + green: 100% + blue: 100% + num_leds: 1 + - red: 0% + green: 0% + blue: 0% + num_leds: 1 + add_led_interval: 100ms + reverse: false + - addressable_scan: + - addressable_scan: + name: Scan Effect With Custom Values + move_interval: 100ms + - addressable_twinkle: + - addressable_twinkle: + name: Twinkle Effect With Custom Values + twinkle_probability: 5% + progress_interval: 4ms + - addressable_random_twinkle: + - addressable_random_twinkle: + name: Random Twinkle Effect With Custom Values + twinkle_probability: 5% + progress_interval: 32ms + - addressable_fireworks: + - addressable_fireworks: + name: Fireworks Effect With Custom Values + update_interval: 32ms + spark_probability: 10% + use_random_color: false + fade_out_rate: 120 + - addressable_flicker: + - addressable_flicker: + name: Flicker Effect With Custom Values + update_interval: 16ms + intensity: 5% + - addressable_lambda: + name: Test For Custom Lambda Effect + lambda: |- + if (initial_run) { + it[0] = current_color; + } + - automation: + name: Custom Effect + sequence: + - light.addressable_set: + id: addr1 + red: 100% + green: 100% + blue: 0% + - delay: 100ms + - light.addressable_set: + id: addr1 + red: 0% + green: 100% + blue: 0% diff --git a/tests/components/feedback/test.esp32-c3-idf.yaml b/tests/components/feedback/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..f93d54e8b6 --- /dev/null +++ b/tests/components/feedback/test.esp32-c3-idf.yaml @@ -0,0 +1,39 @@ +binary_sensor: + - platform: template + id: open_endstop_sensor + - platform: template + id: open_sensor + - platform: template + id: open_obstacle_sensor + - platform: template + id: close_endstop_sensor + - platform: template + id: close_sensor + - platform: template + id: close_obstacle_sensor + +cover: + - platform: feedback + name: Feedback Cover + id: gate + device_class: gate + infer_endstop_from_movement: false + has_built_in_endstop: false + max_duration: 30s + direction_change_wait_time: 300ms + acceleration_wait_time: 150ms + obstacle_rollback: 10% + open_duration: 22.1s + open_endstop: open_endstop_sensor + open_sensor: open_sensor + open_obstacle_sensor: open_obstacle_sensor + close_duration: 22.4s + close_endstop: close_endstop_sensor + close_sensor: close_sensor + close_obstacle_sensor: close_obstacle_sensor + open_action: + - logger.log: Open Action + close_action: + - logger.log: Close Action + stop_action: + - logger.log: Stop Action diff --git a/tests/components/feedback/test.esp32-c3.yaml b/tests/components/feedback/test.esp32-c3.yaml new file mode 100644 index 0000000000..f93d54e8b6 --- /dev/null +++ b/tests/components/feedback/test.esp32-c3.yaml @@ -0,0 +1,39 @@ +binary_sensor: + - platform: template + id: open_endstop_sensor + - platform: template + id: open_sensor + - platform: template + id: open_obstacle_sensor + - platform: template + id: close_endstop_sensor + - platform: template + id: close_sensor + - platform: template + id: close_obstacle_sensor + +cover: + - platform: feedback + name: Feedback Cover + id: gate + device_class: gate + infer_endstop_from_movement: false + has_built_in_endstop: false + max_duration: 30s + direction_change_wait_time: 300ms + acceleration_wait_time: 150ms + obstacle_rollback: 10% + open_duration: 22.1s + open_endstop: open_endstop_sensor + open_sensor: open_sensor + open_obstacle_sensor: open_obstacle_sensor + close_duration: 22.4s + close_endstop: close_endstop_sensor + close_sensor: close_sensor + close_obstacle_sensor: close_obstacle_sensor + open_action: + - logger.log: Open Action + close_action: + - logger.log: Close Action + stop_action: + - logger.log: Stop Action diff --git a/tests/components/feedback/test.esp32-idf.yaml b/tests/components/feedback/test.esp32-idf.yaml new file mode 100644 index 0000000000..f93d54e8b6 --- /dev/null +++ b/tests/components/feedback/test.esp32-idf.yaml @@ -0,0 +1,39 @@ +binary_sensor: + - platform: template + id: open_endstop_sensor + - platform: template + id: open_sensor + - platform: template + id: open_obstacle_sensor + - platform: template + id: close_endstop_sensor + - platform: template + id: close_sensor + - platform: template + id: close_obstacle_sensor + +cover: + - platform: feedback + name: Feedback Cover + id: gate + device_class: gate + infer_endstop_from_movement: false + has_built_in_endstop: false + max_duration: 30s + direction_change_wait_time: 300ms + acceleration_wait_time: 150ms + obstacle_rollback: 10% + open_duration: 22.1s + open_endstop: open_endstop_sensor + open_sensor: open_sensor + open_obstacle_sensor: open_obstacle_sensor + close_duration: 22.4s + close_endstop: close_endstop_sensor + close_sensor: close_sensor + close_obstacle_sensor: close_obstacle_sensor + open_action: + - logger.log: Open Action + close_action: + - logger.log: Close Action + stop_action: + - logger.log: Stop Action diff --git a/tests/components/feedback/test.esp32.yaml b/tests/components/feedback/test.esp32.yaml new file mode 100644 index 0000000000..f93d54e8b6 --- /dev/null +++ b/tests/components/feedback/test.esp32.yaml @@ -0,0 +1,39 @@ +binary_sensor: + - platform: template + id: open_endstop_sensor + - platform: template + id: open_sensor + - platform: template + id: open_obstacle_sensor + - platform: template + id: close_endstop_sensor + - platform: template + id: close_sensor + - platform: template + id: close_obstacle_sensor + +cover: + - platform: feedback + name: Feedback Cover + id: gate + device_class: gate + infer_endstop_from_movement: false + has_built_in_endstop: false + max_duration: 30s + direction_change_wait_time: 300ms + acceleration_wait_time: 150ms + obstacle_rollback: 10% + open_duration: 22.1s + open_endstop: open_endstop_sensor + open_sensor: open_sensor + open_obstacle_sensor: open_obstacle_sensor + close_duration: 22.4s + close_endstop: close_endstop_sensor + close_sensor: close_sensor + close_obstacle_sensor: close_obstacle_sensor + open_action: + - logger.log: Open Action + close_action: + - logger.log: Close Action + stop_action: + - logger.log: Stop Action diff --git a/tests/components/feedback/test.esp8266.yaml b/tests/components/feedback/test.esp8266.yaml new file mode 100644 index 0000000000..f93d54e8b6 --- /dev/null +++ b/tests/components/feedback/test.esp8266.yaml @@ -0,0 +1,39 @@ +binary_sensor: + - platform: template + id: open_endstop_sensor + - platform: template + id: open_sensor + - platform: template + id: open_obstacle_sensor + - platform: template + id: close_endstop_sensor + - platform: template + id: close_sensor + - platform: template + id: close_obstacle_sensor + +cover: + - platform: feedback + name: Feedback Cover + id: gate + device_class: gate + infer_endstop_from_movement: false + has_built_in_endstop: false + max_duration: 30s + direction_change_wait_time: 300ms + acceleration_wait_time: 150ms + obstacle_rollback: 10% + open_duration: 22.1s + open_endstop: open_endstop_sensor + open_sensor: open_sensor + open_obstacle_sensor: open_obstacle_sensor + close_duration: 22.4s + close_endstop: close_endstop_sensor + close_sensor: close_sensor + close_obstacle_sensor: close_obstacle_sensor + open_action: + - logger.log: Open Action + close_action: + - logger.log: Close Action + stop_action: + - logger.log: Stop Action diff --git a/tests/components/feedback/test.rp2040.yaml b/tests/components/feedback/test.rp2040.yaml new file mode 100644 index 0000000000..f93d54e8b6 --- /dev/null +++ b/tests/components/feedback/test.rp2040.yaml @@ -0,0 +1,39 @@ +binary_sensor: + - platform: template + id: open_endstop_sensor + - platform: template + id: open_sensor + - platform: template + id: open_obstacle_sensor + - platform: template + id: close_endstop_sensor + - platform: template + id: close_sensor + - platform: template + id: close_obstacle_sensor + +cover: + - platform: feedback + name: Feedback Cover + id: gate + device_class: gate + infer_endstop_from_movement: false + has_built_in_endstop: false + max_duration: 30s + direction_change_wait_time: 300ms + acceleration_wait_time: 150ms + obstacle_rollback: 10% + open_duration: 22.1s + open_endstop: open_endstop_sensor + open_sensor: open_sensor + open_obstacle_sensor: open_obstacle_sensor + close_duration: 22.4s + close_endstop: close_endstop_sensor + close_sensor: close_sensor + close_obstacle_sensor: close_obstacle_sensor + open_action: + - logger.log: Open Action + close_action: + - logger.log: Close Action + stop_action: + - logger.log: Stop Action diff --git a/tests/components/fingerprint_grow/test.esp32-c3-idf.yaml b/tests/components/fingerprint_grow/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..e7ac08eb28 --- /dev/null +++ b/tests/components/fingerprint_grow/test.esp32-c3-idf.yaml @@ -0,0 +1,56 @@ +esphome: + on_boot: + then: + - fingerprint_grow.enroll: + finger_id: 2 + num_scans: 2 + - fingerprint_grow.cancel_enroll: + - fingerprint_grow.delete: + finger_id: 2 + - fingerprint_grow.delete_all: + +uart: + - id: uart_fingerprint_grow + tx_pin: 4 + rx_pin: 5 + baud_rate: 57600 + +fingerprint_grow: + sensing_pin: 6 + password: 0x12FE37DC + new_password: 0xA65B9840 + on_finger_scan_start: + - logger.log: test_fingerprint_grow_finger_scan_start + on_finger_scan_invalid: + - logger.log: test_fingerprint_grow_finger_scan_invalid + on_finger_scan_matched: + - logger.log: test_fingerprint_grow_finger_scan_matched + on_finger_scan_unmatched: + - logger.log: test_fingerprint_grow_finger_scan_unmatched + on_finger_scan_misplaced: + - logger.log: test_fingerprint_grow_finger_scan_misplaced + on_enrollment_scan: + - logger.log: test_fingerprint_grow_enrollment_scan + on_enrollment_done: + - logger.log: test_fingerprint_grow_node_enrollment_done + on_enrollment_failed: + - logger.log: test_fingerprint_grow_enrollment_failed + +binary_sensor: + - platform: fingerprint_grow + name: Fingerprint Enrolling + +sensor: + - platform: fingerprint_grow + fingerprint_count: + name: Fingerprint Count + status: + name: Fingerprint Status + capacity: + name: Fingerprint Capacity + security_level: + name: Fingerprint Security Level + last_finger_id: + name: Fingerprint Last Finger ID + last_confidence: + name: Fingerprint Last Confidence diff --git a/tests/components/fingerprint_grow/test.esp32-c3.yaml b/tests/components/fingerprint_grow/test.esp32-c3.yaml new file mode 100644 index 0000000000..e7ac08eb28 --- /dev/null +++ b/tests/components/fingerprint_grow/test.esp32-c3.yaml @@ -0,0 +1,56 @@ +esphome: + on_boot: + then: + - fingerprint_grow.enroll: + finger_id: 2 + num_scans: 2 + - fingerprint_grow.cancel_enroll: + - fingerprint_grow.delete: + finger_id: 2 + - fingerprint_grow.delete_all: + +uart: + - id: uart_fingerprint_grow + tx_pin: 4 + rx_pin: 5 + baud_rate: 57600 + +fingerprint_grow: + sensing_pin: 6 + password: 0x12FE37DC + new_password: 0xA65B9840 + on_finger_scan_start: + - logger.log: test_fingerprint_grow_finger_scan_start + on_finger_scan_invalid: + - logger.log: test_fingerprint_grow_finger_scan_invalid + on_finger_scan_matched: + - logger.log: test_fingerprint_grow_finger_scan_matched + on_finger_scan_unmatched: + - logger.log: test_fingerprint_grow_finger_scan_unmatched + on_finger_scan_misplaced: + - logger.log: test_fingerprint_grow_finger_scan_misplaced + on_enrollment_scan: + - logger.log: test_fingerprint_grow_enrollment_scan + on_enrollment_done: + - logger.log: test_fingerprint_grow_node_enrollment_done + on_enrollment_failed: + - logger.log: test_fingerprint_grow_enrollment_failed + +binary_sensor: + - platform: fingerprint_grow + name: Fingerprint Enrolling + +sensor: + - platform: fingerprint_grow + fingerprint_count: + name: Fingerprint Count + status: + name: Fingerprint Status + capacity: + name: Fingerprint Capacity + security_level: + name: Fingerprint Security Level + last_finger_id: + name: Fingerprint Last Finger ID + last_confidence: + name: Fingerprint Last Confidence diff --git a/tests/components/fingerprint_grow/test.esp32-idf.yaml b/tests/components/fingerprint_grow/test.esp32-idf.yaml new file mode 100644 index 0000000000..0950145a05 --- /dev/null +++ b/tests/components/fingerprint_grow/test.esp32-idf.yaml @@ -0,0 +1,56 @@ +esphome: + on_boot: + then: + - fingerprint_grow.enroll: + finger_id: 2 + num_scans: 2 + - fingerprint_grow.cancel_enroll: + - fingerprint_grow.delete: + finger_id: 2 + - fingerprint_grow.delete_all: + +uart: + - id: uart_fingerprint_grow + tx_pin: 17 + rx_pin: 16 + baud_rate: 57600 + +fingerprint_grow: + sensing_pin: 18 + password: 0x12FE37DC + new_password: 0xA65B9840 + on_finger_scan_start: + - logger.log: test_fingerprint_grow_finger_scan_start + on_finger_scan_invalid: + - logger.log: test_fingerprint_grow_finger_scan_invalid + on_finger_scan_matched: + - logger.log: test_fingerprint_grow_finger_scan_matched + on_finger_scan_unmatched: + - logger.log: test_fingerprint_grow_finger_scan_unmatched + on_finger_scan_misplaced: + - logger.log: test_fingerprint_grow_finger_scan_misplaced + on_enrollment_scan: + - logger.log: test_fingerprint_grow_enrollment_scan + on_enrollment_done: + - logger.log: test_fingerprint_grow_node_enrollment_done + on_enrollment_failed: + - logger.log: test_fingerprint_grow_enrollment_failed + +binary_sensor: + - platform: fingerprint_grow + name: Fingerprint Enrolling + +sensor: + - platform: fingerprint_grow + fingerprint_count: + name: Fingerprint Count + status: + name: Fingerprint Status + capacity: + name: Fingerprint Capacity + security_level: + name: Fingerprint Security Level + last_finger_id: + name: Fingerprint Last Finger ID + last_confidence: + name: Fingerprint Last Confidence diff --git a/tests/components/fingerprint_grow/test.esp32.yaml b/tests/components/fingerprint_grow/test.esp32.yaml new file mode 100644 index 0000000000..0950145a05 --- /dev/null +++ b/tests/components/fingerprint_grow/test.esp32.yaml @@ -0,0 +1,56 @@ +esphome: + on_boot: + then: + - fingerprint_grow.enroll: + finger_id: 2 + num_scans: 2 + - fingerprint_grow.cancel_enroll: + - fingerprint_grow.delete: + finger_id: 2 + - fingerprint_grow.delete_all: + +uart: + - id: uart_fingerprint_grow + tx_pin: 17 + rx_pin: 16 + baud_rate: 57600 + +fingerprint_grow: + sensing_pin: 18 + password: 0x12FE37DC + new_password: 0xA65B9840 + on_finger_scan_start: + - logger.log: test_fingerprint_grow_finger_scan_start + on_finger_scan_invalid: + - logger.log: test_fingerprint_grow_finger_scan_invalid + on_finger_scan_matched: + - logger.log: test_fingerprint_grow_finger_scan_matched + on_finger_scan_unmatched: + - logger.log: test_fingerprint_grow_finger_scan_unmatched + on_finger_scan_misplaced: + - logger.log: test_fingerprint_grow_finger_scan_misplaced + on_enrollment_scan: + - logger.log: test_fingerprint_grow_enrollment_scan + on_enrollment_done: + - logger.log: test_fingerprint_grow_node_enrollment_done + on_enrollment_failed: + - logger.log: test_fingerprint_grow_enrollment_failed + +binary_sensor: + - platform: fingerprint_grow + name: Fingerprint Enrolling + +sensor: + - platform: fingerprint_grow + fingerprint_count: + name: Fingerprint Count + status: + name: Fingerprint Status + capacity: + name: Fingerprint Capacity + security_level: + name: Fingerprint Security Level + last_finger_id: + name: Fingerprint Last Finger ID + last_confidence: + name: Fingerprint Last Confidence diff --git a/tests/components/fingerprint_grow/test.esp8266.yaml b/tests/components/fingerprint_grow/test.esp8266.yaml new file mode 100644 index 0000000000..1d00d977b9 --- /dev/null +++ b/tests/components/fingerprint_grow/test.esp8266.yaml @@ -0,0 +1,56 @@ +esphome: + on_boot: + then: + - fingerprint_grow.enroll: + finger_id: 2 + num_scans: 2 + - fingerprint_grow.cancel_enroll: + - fingerprint_grow.delete: + finger_id: 2 + - fingerprint_grow.delete_all: + +uart: + - id: uart_fingerprint_grow + tx_pin: 4 + rx_pin: 5 + baud_rate: 57600 + +fingerprint_grow: + sensing_pin: 16 + password: 0x12FE37DC + new_password: 0xA65B9840 + on_finger_scan_start: + - logger.log: test_fingerprint_grow_finger_scan_start + on_finger_scan_invalid: + - logger.log: test_fingerprint_grow_finger_scan_invalid + on_finger_scan_matched: + - logger.log: test_fingerprint_grow_finger_scan_matched + on_finger_scan_unmatched: + - logger.log: test_fingerprint_grow_finger_scan_unmatched + on_finger_scan_misplaced: + - logger.log: test_fingerprint_grow_finger_scan_misplaced + on_enrollment_scan: + - logger.log: test_fingerprint_grow_enrollment_scan + on_enrollment_done: + - logger.log: test_fingerprint_grow_node_enrollment_done + on_enrollment_failed: + - logger.log: test_fingerprint_grow_enrollment_failed + +binary_sensor: + - platform: fingerprint_grow + name: Fingerprint Enrolling + +sensor: + - platform: fingerprint_grow + fingerprint_count: + name: Fingerprint Count + status: + name: Fingerprint Status + capacity: + name: Fingerprint Capacity + security_level: + name: Fingerprint Security Level + last_finger_id: + name: Fingerprint Last Finger ID + last_confidence: + name: Fingerprint Last Confidence diff --git a/tests/components/fingerprint_grow/test.rp2040.yaml b/tests/components/fingerprint_grow/test.rp2040.yaml new file mode 100644 index 0000000000..e7ac08eb28 --- /dev/null +++ b/tests/components/fingerprint_grow/test.rp2040.yaml @@ -0,0 +1,56 @@ +esphome: + on_boot: + then: + - fingerprint_grow.enroll: + finger_id: 2 + num_scans: 2 + - fingerprint_grow.cancel_enroll: + - fingerprint_grow.delete: + finger_id: 2 + - fingerprint_grow.delete_all: + +uart: + - id: uart_fingerprint_grow + tx_pin: 4 + rx_pin: 5 + baud_rate: 57600 + +fingerprint_grow: + sensing_pin: 6 + password: 0x12FE37DC + new_password: 0xA65B9840 + on_finger_scan_start: + - logger.log: test_fingerprint_grow_finger_scan_start + on_finger_scan_invalid: + - logger.log: test_fingerprint_grow_finger_scan_invalid + on_finger_scan_matched: + - logger.log: test_fingerprint_grow_finger_scan_matched + on_finger_scan_unmatched: + - logger.log: test_fingerprint_grow_finger_scan_unmatched + on_finger_scan_misplaced: + - logger.log: test_fingerprint_grow_finger_scan_misplaced + on_enrollment_scan: + - logger.log: test_fingerprint_grow_enrollment_scan + on_enrollment_done: + - logger.log: test_fingerprint_grow_node_enrollment_done + on_enrollment_failed: + - logger.log: test_fingerprint_grow_enrollment_failed + +binary_sensor: + - platform: fingerprint_grow + name: Fingerprint Enrolling + +sensor: + - platform: fingerprint_grow + fingerprint_count: + name: Fingerprint Count + status: + name: Fingerprint Status + capacity: + name: Fingerprint Capacity + security_level: + name: Fingerprint Security Level + last_finger_id: + name: Fingerprint Last Finger ID + last_confidence: + name: Fingerprint Last Confidence diff --git a/tests/components/font/test.esp32-c3-idf.yaml b/tests/components/font/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..b63b4d025a --- /dev/null +++ b/tests/components/font/test.esp32-c3-idf.yaml @@ -0,0 +1,19 @@ +i2c: + - id: i2c_font + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +font: + - file: "gfonts://Roboto" + id: roboto + size: 20 diff --git a/tests/components/font/test.esp32-c3.yaml b/tests/components/font/test.esp32-c3.yaml new file mode 100644 index 0000000000..b63b4d025a --- /dev/null +++ b/tests/components/font/test.esp32-c3.yaml @@ -0,0 +1,19 @@ +i2c: + - id: i2c_font + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +font: + - file: "gfonts://Roboto" + id: roboto + size: 20 diff --git a/tests/components/font/test.esp32-idf.yaml b/tests/components/font/test.esp32-idf.yaml new file mode 100644 index 0000000000..dcf8fb49d5 --- /dev/null +++ b/tests/components/font/test.esp32-idf.yaml @@ -0,0 +1,19 @@ +i2c: + - id: i2c_font + scl: 16 + sda: 17 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +font: + - file: "gfonts://Roboto" + id: roboto + size: 20 diff --git a/tests/components/font/test.esp8266.yaml b/tests/components/font/test.esp8266.yaml new file mode 100644 index 0000000000..b63b4d025a --- /dev/null +++ b/tests/components/font/test.esp8266.yaml @@ -0,0 +1,19 @@ +i2c: + - id: i2c_font + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +font: + - file: "gfonts://Roboto" + id: roboto + size: 20 diff --git a/tests/components/font/test.rp2040.yaml b/tests/components/font/test.rp2040.yaml new file mode 100644 index 0000000000..b63b4d025a --- /dev/null +++ b/tests/components/font/test.rp2040.yaml @@ -0,0 +1,19 @@ +i2c: + - id: i2c_font + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +font: + - file: "gfonts://Roboto" + id: roboto + size: 20 diff --git a/tests/components/fs3000/test.esp32-c3-idf.yaml b/tests/components/fs3000/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..69de83b463 --- /dev/null +++ b/tests/components/fs3000/test.esp32-c3-idf.yaml @@ -0,0 +1,10 @@ +i2c: + - id: i2c_fs3000 + scl: 5 + sda: 4 + +sensor: + - platform: fs3000 + name: Air Velocity + model: 1005 + update_interval: 60s diff --git a/tests/components/fs3000/test.esp32-c3.yaml b/tests/components/fs3000/test.esp32-c3.yaml new file mode 100644 index 0000000000..69de83b463 --- /dev/null +++ b/tests/components/fs3000/test.esp32-c3.yaml @@ -0,0 +1,10 @@ +i2c: + - id: i2c_fs3000 + scl: 5 + sda: 4 + +sensor: + - platform: fs3000 + name: Air Velocity + model: 1005 + update_interval: 60s diff --git a/tests/components/fs3000/test.esp32-idf.yaml b/tests/components/fs3000/test.esp32-idf.yaml new file mode 100644 index 0000000000..53b49cc9a2 --- /dev/null +++ b/tests/components/fs3000/test.esp32-idf.yaml @@ -0,0 +1,10 @@ +i2c: + - id: i2c_fs3000 + scl: 16 + sda: 17 + +sensor: + - platform: fs3000 + name: Air Velocity + model: 1005 + update_interval: 60s diff --git a/tests/components/fs3000/test.esp32.yaml b/tests/components/fs3000/test.esp32.yaml new file mode 100644 index 0000000000..53b49cc9a2 --- /dev/null +++ b/tests/components/fs3000/test.esp32.yaml @@ -0,0 +1,10 @@ +i2c: + - id: i2c_fs3000 + scl: 16 + sda: 17 + +sensor: + - platform: fs3000 + name: Air Velocity + model: 1005 + update_interval: 60s diff --git a/tests/components/fs3000/test.esp8266.yaml b/tests/components/fs3000/test.esp8266.yaml new file mode 100644 index 0000000000..69de83b463 --- /dev/null +++ b/tests/components/fs3000/test.esp8266.yaml @@ -0,0 +1,10 @@ +i2c: + - id: i2c_fs3000 + scl: 5 + sda: 4 + +sensor: + - platform: fs3000 + name: Air Velocity + model: 1005 + update_interval: 60s diff --git a/tests/components/fs3000/test.rp2040.yaml b/tests/components/fs3000/test.rp2040.yaml new file mode 100644 index 0000000000..69de83b463 --- /dev/null +++ b/tests/components/fs3000/test.rp2040.yaml @@ -0,0 +1,10 @@ +i2c: + - id: i2c_fs3000 + scl: 5 + sda: 4 + +sensor: + - platform: fs3000 + name: Air Velocity + model: 1005 + update_interval: 60s diff --git a/tests/components/ft5x06/test.esp32-c3-idf.yaml b/tests/components/ft5x06/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..4fa9532f53 --- /dev/null +++ b/tests/components/ft5x06/test.esp32-c3-idf.yaml @@ -0,0 +1,21 @@ +i2c: + - id: i2c_ft5x06 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ft5x06 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ft5x06/test.esp32-c3.yaml b/tests/components/ft5x06/test.esp32-c3.yaml new file mode 100644 index 0000000000..4fa9532f53 --- /dev/null +++ b/tests/components/ft5x06/test.esp32-c3.yaml @@ -0,0 +1,21 @@ +i2c: + - id: i2c_ft5x06 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ft5x06 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ft5x06/test.esp32-idf.yaml b/tests/components/ft5x06/test.esp32-idf.yaml new file mode 100644 index 0000000000..648929896d --- /dev/null +++ b/tests/components/ft5x06/test.esp32-idf.yaml @@ -0,0 +1,21 @@ +i2c: + - id: i2c_ft5x06 + scl: 16 + sda: 17 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 18 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ft5x06 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ft5x06/test.esp32.yaml b/tests/components/ft5x06/test.esp32.yaml new file mode 100644 index 0000000000..648929896d --- /dev/null +++ b/tests/components/ft5x06/test.esp32.yaml @@ -0,0 +1,21 @@ +i2c: + - id: i2c_ft5x06 + scl: 16 + sda: 17 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 18 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ft5x06 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ft5x06/test.esp8266.yaml b/tests/components/ft5x06/test.esp8266.yaml new file mode 100644 index 0000000000..4fa9532f53 --- /dev/null +++ b/tests/components/ft5x06/test.esp8266.yaml @@ -0,0 +1,21 @@ +i2c: + - id: i2c_ft5x06 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ft5x06 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ft5x06/test.rp2040.yaml b/tests/components/ft5x06/test.rp2040.yaml new file mode 100644 index 0000000000..4fa9532f53 --- /dev/null +++ b/tests/components/ft5x06/test.rp2040.yaml @@ -0,0 +1,21 @@ +i2c: + - id: i2c_ft5x06 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ft5x06 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ft63x6/test.esp32-c3-idf.yaml b/tests/components/ft63x6/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..19ca4cfc19 --- /dev/null +++ b/tests/components/ft63x6/test.esp32-c3-idf.yaml @@ -0,0 +1,21 @@ +i2c: + - id: i2c_ft63x6 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ft63x6 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ft63x6/test.esp32-c3.yaml b/tests/components/ft63x6/test.esp32-c3.yaml new file mode 100644 index 0000000000..19ca4cfc19 --- /dev/null +++ b/tests/components/ft63x6/test.esp32-c3.yaml @@ -0,0 +1,21 @@ +i2c: + - id: i2c_ft63x6 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ft63x6 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ft63x6/test.esp32-idf.yaml b/tests/components/ft63x6/test.esp32-idf.yaml new file mode 100644 index 0000000000..5ceb107e31 --- /dev/null +++ b/tests/components/ft63x6/test.esp32-idf.yaml @@ -0,0 +1,21 @@ +i2c: + - id: i2c_ft63x6 + scl: 16 + sda: 17 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 18 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ft63x6 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ft63x6/test.esp8266.yaml b/tests/components/ft63x6/test.esp8266.yaml new file mode 100644 index 0000000000..19ca4cfc19 --- /dev/null +++ b/tests/components/ft63x6/test.esp8266.yaml @@ -0,0 +1,21 @@ +i2c: + - id: i2c_ft63x6 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ft63x6 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/ft63x6/test.rp2040.yaml b/tests/components/ft63x6/test.rp2040.yaml new file mode 100644 index 0000000000..19ca4cfc19 --- /dev/null +++ b/tests/components/ft63x6/test.rp2040.yaml @@ -0,0 +1,21 @@ +i2c: + - id: i2c_ft63x6 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: ft63x6 + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/fujitsu_general/test.esp32-c3-idf.yaml b/tests/components/fujitsu_general/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..b4146f2a18 --- /dev/null +++ b/tests/components/fujitsu_general/test.esp32-c3-idf.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: fujitsu_general + name: Fujitsu General Climate diff --git a/tests/components/fujitsu_general/test.esp32-c3.yaml b/tests/components/fujitsu_general/test.esp32-c3.yaml new file mode 100644 index 0000000000..b4146f2a18 --- /dev/null +++ b/tests/components/fujitsu_general/test.esp32-c3.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: fujitsu_general + name: Fujitsu General Climate diff --git a/tests/components/fujitsu_general/test.esp32-idf.yaml b/tests/components/fujitsu_general/test.esp32-idf.yaml new file mode 100644 index 0000000000..b4146f2a18 --- /dev/null +++ b/tests/components/fujitsu_general/test.esp32-idf.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: fujitsu_general + name: Fujitsu General Climate diff --git a/tests/components/fujitsu_general/test.esp32.yaml b/tests/components/fujitsu_general/test.esp32.yaml new file mode 100644 index 0000000000..b4146f2a18 --- /dev/null +++ b/tests/components/fujitsu_general/test.esp32.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: fujitsu_general + name: Fujitsu General Climate diff --git a/tests/components/fujitsu_general/test.esp8266.yaml b/tests/components/fujitsu_general/test.esp8266.yaml new file mode 100644 index 0000000000..2a05bdde6b --- /dev/null +++ b/tests/components/fujitsu_general/test.esp8266.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 5 + carrier_duty_percent: 50% + +climate: + - platform: fujitsu_general + name: Fujitsu General Climate From 58de8a4ee6cea6df248a904bde7e4a6dcf041a70 Mon Sep 17 00:00:00 2001 From: Ben Kristinsson Date: Wed, 27 Mar 2024 02:13:41 +0100 Subject: [PATCH 159/189] Add get_contrast() and get_brightness() to SSD1306 class to get protected variables (#6435) --- esphome/components/ssd1306_base/ssd1306_base.cpp | 2 ++ esphome/components/ssd1306_base/ssd1306_base.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/esphome/components/ssd1306_base/ssd1306_base.cpp b/esphome/components/ssd1306_base/ssd1306_base.cpp index 749c3511c1..90b805a79f 100644 --- a/esphome/components/ssd1306_base/ssd1306_base.cpp +++ b/esphome/components/ssd1306_base/ssd1306_base.cpp @@ -236,6 +236,7 @@ void SSD1306::set_invert(bool invert) { // Inverse display mode (0xA6, 0xA7) this->command(SSD1306_COMMAND_NORMAL_DISPLAY | this->invert_); } +float SSD1306::get_contrast() { return this->contrast_; }; void SSD1306::set_contrast(float contrast) { // validation this->contrast_ = clamp(contrast, 0.0F, 1.0F); @@ -243,6 +244,7 @@ void SSD1306::set_contrast(float contrast) { this->command(SSD1306_COMMAND_SET_CONTRAST); this->command(int(SSD1306_MAX_CONTRAST * (this->contrast_))); } +float SSD1306::get_brightness() { return this->brightness_; }; void SSD1306::set_brightness(float brightness) { // validation if (!this->is_ssd1305_()) diff --git a/esphome/components/ssd1306_base/ssd1306_base.h b/esphome/components/ssd1306_base/ssd1306_base.h index 2e09755863..14ec309ae0 100644 --- a/esphome/components/ssd1306_base/ssd1306_base.h +++ b/esphome/components/ssd1306_base/ssd1306_base.h @@ -36,7 +36,9 @@ class SSD1306 : public display::DisplayBuffer { void set_reset_pin(GPIOPin *reset_pin) { this->reset_pin_ = reset_pin; } void set_external_vcc(bool external_vcc) { this->external_vcc_ = external_vcc; } void init_contrast(float contrast) { this->contrast_ = contrast; } + float get_contrast(); void set_contrast(float contrast); + float get_brightness(); void init_brightness(float brightness) { this->brightness_ = brightness; } void set_brightness(float brightness); void init_flip_x(bool flip_x) { this->flip_x_ = flip_x; } From 94e9476838368cb3b896fc58fe8bcb70ff6177cf Mon Sep 17 00:00:00 2001 From: Mafus1 Date: Wed, 27 Mar 2024 02:14:23 +0100 Subject: [PATCH 160/189] Add new Component: Ultrasonic Distance Sensor JSN-SR04T (#6023) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- CODEOWNERS | 1 + esphome/components/jsn_sr04t/__init__.py | 1 + esphome/components/jsn_sr04t/jsn_sr04t.cpp | 58 +++++++++++++++++++ esphome/components/jsn_sr04t/jsn_sr04t.h | 28 +++++++++ esphome/components/jsn_sr04t/sensor.py | 44 ++++++++++++++ .../jsn_sr04t/test.esp32-c3-idf.yaml | 14 +++++ tests/components/jsn_sr04t/test.esp32-c3.yaml | 14 +++++ .../components/jsn_sr04t/test.esp32-idf.yaml | 14 +++++ tests/components/jsn_sr04t/test.esp32.yaml | 14 +++++ tests/components/jsn_sr04t/test.esp8266.yaml | 14 +++++ tests/components/jsn_sr04t/test.rp2040.yaml | 14 +++++ 11 files changed, 216 insertions(+) create mode 100644 esphome/components/jsn_sr04t/__init__.py create mode 100644 esphome/components/jsn_sr04t/jsn_sr04t.cpp create mode 100644 esphome/components/jsn_sr04t/jsn_sr04t.h create mode 100644 esphome/components/jsn_sr04t/sensor.py create mode 100644 tests/components/jsn_sr04t/test.esp32-c3-idf.yaml create mode 100644 tests/components/jsn_sr04t/test.esp32-c3.yaml create mode 100644 tests/components/jsn_sr04t/test.esp32-idf.yaml create mode 100644 tests/components/jsn_sr04t/test.esp32.yaml create mode 100644 tests/components/jsn_sr04t/test.esp8266.yaml create mode 100644 tests/components/jsn_sr04t/test.rp2040.yaml diff --git a/CODEOWNERS b/CODEOWNERS index b924f55d0b..d6ec3843a5 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -173,6 +173,7 @@ esphome/components/inkplate6/* @jesserockz esphome/components/integration/* @OttoWinter esphome/components/internal_temperature/* @Mat931 esphome/components/interval/* @esphome/core +esphome/components/jsn_sr04t/* @Mafus1 esphome/components/json/* @OttoWinter esphome/components/kamstrup_kmp/* @cfeenstra1024 esphome/components/key_collector/* @ssieb diff --git a/esphome/components/jsn_sr04t/__init__.py b/esphome/components/jsn_sr04t/__init__.py new file mode 100644 index 0000000000..ef6335f316 --- /dev/null +++ b/esphome/components/jsn_sr04t/__init__.py @@ -0,0 +1 @@ +CODEOWNERS = ["@Mafus1"] diff --git a/esphome/components/jsn_sr04t/jsn_sr04t.cpp b/esphome/components/jsn_sr04t/jsn_sr04t.cpp new file mode 100644 index 0000000000..70e21a137d --- /dev/null +++ b/esphome/components/jsn_sr04t/jsn_sr04t.cpp @@ -0,0 +1,58 @@ +#include "jsn_sr04t.h" +#include "esphome/core/helpers.h" +#include "esphome/core/log.h" + +#include + +// Very basic support for JSN_SR04T V3.0 distance sensor in mode 2 + +namespace esphome { +namespace jsn_sr04t { + +static const char *const TAG = "jsn_sr04t.sensor"; + +void Jsnsr04tComponent::update() { + this->write_byte(0x55); + ESP_LOGV(TAG, "Request read out from sensor"); +} + +void Jsnsr04tComponent::loop() { + while (this->available() > 0) { + uint8_t data; + this->read_byte(&data); + + ESP_LOGV(TAG, "Read byte from sensor: %x", data); + + if (this->buffer_.empty() && data != 0xFF) + continue; + + this->buffer_.push_back(data); + if (this->buffer_.size() == 4) + this->check_buffer_(); + } +} + +void Jsnsr04tComponent::check_buffer_() { + uint8_t checksum = this->buffer_[0] + this->buffer_[1] + this->buffer_[2]; + if (this->buffer_[3] == checksum) { + uint16_t distance = encode_uint16(this->buffer_[1], this->buffer_[2]); + if (distance > 250) { + float meters = distance / 1000.0f; + ESP_LOGV(TAG, "Distance from sensor: %" PRIu32 "mm, %.3fm", distance, meters); + this->publish_state(meters); + } else { + ESP_LOGW(TAG, "Invalid data read from sensor: %s", format_hex_pretty(this->buffer_).c_str()); + } + } else { + ESP_LOGW(TAG, "checksum failed: %02x != %02x", checksum, this->buffer_[3]); + } + this->buffer_.clear(); +} + +void Jsnsr04tComponent::dump_config() { + LOG_SENSOR("", "JST_SR04T Sensor", this); + LOG_UPDATE_INTERVAL(this); +} + +} // namespace jsn_sr04t +} // namespace esphome diff --git a/esphome/components/jsn_sr04t/jsn_sr04t.h b/esphome/components/jsn_sr04t/jsn_sr04t.h new file mode 100644 index 0000000000..bd43252be8 --- /dev/null +++ b/esphome/components/jsn_sr04t/jsn_sr04t.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include "esphome/core/component.h" +#include "esphome/components/sensor/sensor.h" +#include "esphome/components/uart/uart.h" + +namespace esphome { +namespace jsn_sr04t { + +class Jsnsr04tComponent : public sensor::Sensor, public PollingComponent, public uart::UARTDevice { + public: + // Nothing really public. + + // ========== INTERNAL METHODS ========== + void update() override; + void loop() override; + void dump_config() override; + + protected: + void check_buffer_(); + + std::vector buffer_; +}; + +} // namespace jsn_sr04t +} // namespace esphome diff --git a/esphome/components/jsn_sr04t/sensor.py b/esphome/components/jsn_sr04t/sensor.py new file mode 100644 index 0000000000..4b062e81e9 --- /dev/null +++ b/esphome/components/jsn_sr04t/sensor.py @@ -0,0 +1,44 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import sensor, uart +from esphome.const import ( + STATE_CLASS_MEASUREMENT, + UNIT_METER, + ICON_ARROW_EXPAND_VERTICAL, +) + +CODEOWNERS = ["@Mafus1"] +DEPENDENCIES = ["uart"] + +jsn_sr04t_ns = cg.esphome_ns.namespace("jsn_sr04t") +Jsnsr04tComponent = jsn_sr04t_ns.class_( + "Jsnsr04tComponent", sensor.Sensor, cg.PollingComponent, uart.UARTDevice +) + +CONFIG_SCHEMA = ( + sensor.sensor_schema( + Jsnsr04tComponent, + unit_of_measurement=UNIT_METER, + icon=ICON_ARROW_EXPAND_VERTICAL, + accuracy_decimals=3, + state_class=STATE_CLASS_MEASUREMENT, + ) + .extend(cv.polling_component_schema("60s")) + .extend(uart.UART_DEVICE_SCHEMA) +) + +FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema( + "jsn_sr04t", + baud_rate=9600, + require_tx=True, + require_rx=True, + data_bits=8, + parity=None, + stop_bits=1, +) + + +async def to_code(config): + var = await sensor.new_sensor(config) + await cg.register_component(var, config) + await uart.register_uart_device(var, config) diff --git a/tests/components/jsn_sr04t/test.esp32-c3-idf.yaml b/tests/components/jsn_sr04t/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..5a37418a7d --- /dev/null +++ b/tests/components/jsn_sr04t/test.esp32-c3-idf.yaml @@ -0,0 +1,14 @@ +uart: + - id: uart_jsn_sr04t + tx_pin: + number: 4 + rx_pin: + number: 5 + baud_rate: 9600 + +sensor: + - platform: jsn_sr04t + id: jsn_sr04t_sensor + name: "jsn_sr04t Distance" + uart_id: uart_jsn_sr04t + update_interval: 1s diff --git a/tests/components/jsn_sr04t/test.esp32-c3.yaml b/tests/components/jsn_sr04t/test.esp32-c3.yaml new file mode 100644 index 0000000000..5a37418a7d --- /dev/null +++ b/tests/components/jsn_sr04t/test.esp32-c3.yaml @@ -0,0 +1,14 @@ +uart: + - id: uart_jsn_sr04t + tx_pin: + number: 4 + rx_pin: + number: 5 + baud_rate: 9600 + +sensor: + - platform: jsn_sr04t + id: jsn_sr04t_sensor + name: "jsn_sr04t Distance" + uart_id: uart_jsn_sr04t + update_interval: 1s diff --git a/tests/components/jsn_sr04t/test.esp32-idf.yaml b/tests/components/jsn_sr04t/test.esp32-idf.yaml new file mode 100644 index 0000000000..32b4221b3f --- /dev/null +++ b/tests/components/jsn_sr04t/test.esp32-idf.yaml @@ -0,0 +1,14 @@ +uart: + - id: uart_jsn_sr04t + tx_pin: + number: 17 + rx_pin: + number: 16 + baud_rate: 9600 + +sensor: + - platform: jsn_sr04t + id: jsn_sr04t_sensor + name: "jsn_sr04t Distance" + uart_id: uart_jsn_sr04t + update_interval: 1s diff --git a/tests/components/jsn_sr04t/test.esp32.yaml b/tests/components/jsn_sr04t/test.esp32.yaml new file mode 100644 index 0000000000..32b4221b3f --- /dev/null +++ b/tests/components/jsn_sr04t/test.esp32.yaml @@ -0,0 +1,14 @@ +uart: + - id: uart_jsn_sr04t + tx_pin: + number: 17 + rx_pin: + number: 16 + baud_rate: 9600 + +sensor: + - platform: jsn_sr04t + id: jsn_sr04t_sensor + name: "jsn_sr04t Distance" + uart_id: uart_jsn_sr04t + update_interval: 1s diff --git a/tests/components/jsn_sr04t/test.esp8266.yaml b/tests/components/jsn_sr04t/test.esp8266.yaml new file mode 100644 index 0000000000..5a37418a7d --- /dev/null +++ b/tests/components/jsn_sr04t/test.esp8266.yaml @@ -0,0 +1,14 @@ +uart: + - id: uart_jsn_sr04t + tx_pin: + number: 4 + rx_pin: + number: 5 + baud_rate: 9600 + +sensor: + - platform: jsn_sr04t + id: jsn_sr04t_sensor + name: "jsn_sr04t Distance" + uart_id: uart_jsn_sr04t + update_interval: 1s diff --git a/tests/components/jsn_sr04t/test.rp2040.yaml b/tests/components/jsn_sr04t/test.rp2040.yaml new file mode 100644 index 0000000000..5a37418a7d --- /dev/null +++ b/tests/components/jsn_sr04t/test.rp2040.yaml @@ -0,0 +1,14 @@ +uart: + - id: uart_jsn_sr04t + tx_pin: + number: 4 + rx_pin: + number: 5 + baud_rate: 9600 + +sensor: + - platform: jsn_sr04t + id: jsn_sr04t_sensor + name: "jsn_sr04t Distance" + uart_id: uart_jsn_sr04t + update_interval: 1s From eee71466142dafb573c8578923b75d0712a99792 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Tue, 26 Mar 2024 20:22:01 -0500 Subject: [PATCH 161/189] Add some components to the new testing framework (G) (#6178) --- tests/components/gcja5/test.esp32-c3-idf.yaml | 25 ++++ tests/components/gcja5/test.esp32-c3.yaml | 25 ++++ tests/components/gcja5/test.esp32-idf.yaml | 25 ++++ tests/components/gcja5/test.esp32.yaml | 25 ++++ tests/components/gcja5/test.esp8266.yaml | 25 ++++ tests/components/gcja5/test.rp2040.yaml | 25 ++++ .../components/globals/test.esp32-c3-idf.yaml | 28 ++++ tests/components/globals/test.esp32-c3.yaml | 28 ++++ tests/components/globals/test.esp32-idf.yaml | 28 ++++ tests/components/globals/test.esp32.yaml | 28 ++++ tests/components/globals/test.esp8266.yaml | 28 ++++ tests/components/globals/test.rp2040.yaml | 28 ++++ .../components/gp8403/test.esp32-c3-idf.yaml | 20 +++ tests/components/gp8403/test.esp32-c3.yaml | 20 +++ tests/components/gp8403/test.esp32-idf.yaml | 20 +++ tests/components/gp8403/test.esp32.yaml | 20 +++ tests/components/gp8403/test.esp8266.yaml | 20 +++ tests/components/gp8403/test.rp2040.yaml | 20 +++ tests/components/gpio/test.esp32-c3-idf.yaml | 14 ++ tests/components/gpio/test.esp32-c3.yaml | 14 ++ tests/components/gpio/test.esp32-idf.yaml | 14 ++ tests/components/gpio/test.esp32.yaml | 14 ++ tests/components/gpio/test.esp8266.yaml | 14 ++ tests/components/gpio/test.rp2040.yaml | 14 ++ tests/components/gps/test.esp32-c3.yaml | 14 ++ tests/components/gps/test.esp32.yaml | 14 ++ tests/components/gps/test.esp8266.yaml | 14 ++ tests/components/gps/test.rp2040.yaml | 14 ++ tests/components/graph/test.esp32-c3-idf.yaml | 25 ++++ tests/components/graph/test.esp32-c3.yaml | 25 ++++ tests/components/graph/test.esp32-idf.yaml | 25 ++++ tests/components/graph/test.esp32.yaml | 25 ++++ tests/components/graph/test.esp8266.yaml | 25 ++++ tests/components/graph/test.rp2040.yaml | 25 ++++ .../test.esp32-c3-idf.yaml | 120 ++++++++++++++++++ .../graphical_display_menu/test.esp32-c3.yaml | 120 ++++++++++++++++++ .../test.esp32-idf.yaml | 120 ++++++++++++++++++ .../graphical_display_menu/test.esp32.yaml | 120 ++++++++++++++++++ .../graphical_display_menu/test.esp8266.yaml | 120 ++++++++++++++++++ .../graphical_display_menu/test.rp2040.yaml | 120 ++++++++++++++++++ tests/components/gree/test.esp32-c3-idf.yaml | 8 ++ tests/components/gree/test.esp32-c3.yaml | 8 ++ tests/components/gree/test.esp32-idf.yaml | 8 ++ tests/components/gree/test.esp32.yaml | 8 ++ tests/components/gree/test.esp8266.yaml | 8 ++ .../grove_tb6612fng/test.esp32-c3-idf.yaml | 23 ++++ .../grove_tb6612fng/test.esp32-c3.yaml | 23 ++++ .../grove_tb6612fng/test.esp32-idf.yaml | 23 ++++ .../grove_tb6612fng/test.esp32.yaml | 23 ++++ .../grove_tb6612fng/test.esp8266.yaml | 23 ++++ .../grove_tb6612fng/test.rp2040.yaml | 23 ++++ .../growatt_solar/test.esp32-c3-idf.yaml | 62 +++++++++ .../growatt_solar/test.esp32-c3.yaml | 62 +++++++++ .../growatt_solar/test.esp32-idf.yaml | 62 +++++++++ .../components/growatt_solar/test.esp32.yaml | 62 +++++++++ .../growatt_solar/test.esp8266.yaml | 62 +++++++++ .../components/growatt_solar/test.rp2040.yaml | 62 +++++++++ tests/components/gt911/test.esp32-c3-idf.yaml | 24 ++++ tests/components/gt911/test.esp32-c3.yaml | 24 ++++ tests/components/gt911/test.esp32-idf.yaml | 24 ++++ tests/components/gt911/test.esp32.yaml | 24 ++++ tests/components/gt911/test.esp8266.yaml | 24 ++++ tests/components/gt911/test.rp2040.yaml | 24 ++++ 63 files changed, 2142 insertions(+) create mode 100644 tests/components/gcja5/test.esp32-c3-idf.yaml create mode 100644 tests/components/gcja5/test.esp32-c3.yaml create mode 100644 tests/components/gcja5/test.esp32-idf.yaml create mode 100644 tests/components/gcja5/test.esp32.yaml create mode 100644 tests/components/gcja5/test.esp8266.yaml create mode 100644 tests/components/gcja5/test.rp2040.yaml create mode 100644 tests/components/globals/test.esp32-c3-idf.yaml create mode 100644 tests/components/globals/test.esp32-c3.yaml create mode 100644 tests/components/globals/test.esp32-idf.yaml create mode 100644 tests/components/globals/test.esp32.yaml create mode 100644 tests/components/globals/test.esp8266.yaml create mode 100644 tests/components/globals/test.rp2040.yaml create mode 100644 tests/components/gp8403/test.esp32-c3-idf.yaml create mode 100644 tests/components/gp8403/test.esp32-c3.yaml create mode 100644 tests/components/gp8403/test.esp32-idf.yaml create mode 100644 tests/components/gp8403/test.esp32.yaml create mode 100644 tests/components/gp8403/test.esp8266.yaml create mode 100644 tests/components/gp8403/test.rp2040.yaml create mode 100644 tests/components/gpio/test.esp32-c3-idf.yaml create mode 100644 tests/components/gpio/test.esp32-c3.yaml create mode 100644 tests/components/gpio/test.esp32-idf.yaml create mode 100644 tests/components/gpio/test.esp32.yaml create mode 100644 tests/components/gpio/test.esp8266.yaml create mode 100644 tests/components/gpio/test.rp2040.yaml create mode 100644 tests/components/gps/test.esp32-c3.yaml create mode 100644 tests/components/gps/test.esp32.yaml create mode 100644 tests/components/gps/test.esp8266.yaml create mode 100644 tests/components/gps/test.rp2040.yaml create mode 100644 tests/components/graph/test.esp32-c3-idf.yaml create mode 100644 tests/components/graph/test.esp32-c3.yaml create mode 100644 tests/components/graph/test.esp32-idf.yaml create mode 100644 tests/components/graph/test.esp32.yaml create mode 100644 tests/components/graph/test.esp8266.yaml create mode 100644 tests/components/graph/test.rp2040.yaml create mode 100644 tests/components/graphical_display_menu/test.esp32-c3-idf.yaml create mode 100644 tests/components/graphical_display_menu/test.esp32-c3.yaml create mode 100644 tests/components/graphical_display_menu/test.esp32-idf.yaml create mode 100644 tests/components/graphical_display_menu/test.esp32.yaml create mode 100644 tests/components/graphical_display_menu/test.esp8266.yaml create mode 100644 tests/components/graphical_display_menu/test.rp2040.yaml create mode 100644 tests/components/gree/test.esp32-c3-idf.yaml create mode 100644 tests/components/gree/test.esp32-c3.yaml create mode 100644 tests/components/gree/test.esp32-idf.yaml create mode 100644 tests/components/gree/test.esp32.yaml create mode 100644 tests/components/gree/test.esp8266.yaml create mode 100644 tests/components/grove_tb6612fng/test.esp32-c3-idf.yaml create mode 100644 tests/components/grove_tb6612fng/test.esp32-c3.yaml create mode 100644 tests/components/grove_tb6612fng/test.esp32-idf.yaml create mode 100644 tests/components/grove_tb6612fng/test.esp32.yaml create mode 100644 tests/components/grove_tb6612fng/test.esp8266.yaml create mode 100644 tests/components/grove_tb6612fng/test.rp2040.yaml create mode 100644 tests/components/growatt_solar/test.esp32-c3-idf.yaml create mode 100644 tests/components/growatt_solar/test.esp32-c3.yaml create mode 100644 tests/components/growatt_solar/test.esp32-idf.yaml create mode 100644 tests/components/growatt_solar/test.esp32.yaml create mode 100644 tests/components/growatt_solar/test.esp8266.yaml create mode 100644 tests/components/growatt_solar/test.rp2040.yaml create mode 100644 tests/components/gt911/test.esp32-c3-idf.yaml create mode 100644 tests/components/gt911/test.esp32-c3.yaml create mode 100644 tests/components/gt911/test.esp32-idf.yaml create mode 100644 tests/components/gt911/test.esp32.yaml create mode 100644 tests/components/gt911/test.esp8266.yaml create mode 100644 tests/components/gt911/test.rp2040.yaml diff --git a/tests/components/gcja5/test.esp32-c3-idf.yaml b/tests/components/gcja5/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..ec8765be52 --- /dev/null +++ b/tests/components/gcja5/test.esp32-c3-idf.yaml @@ -0,0 +1,25 @@ +uart: + - id: uart_gcja5 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + parity: EVEN + +sensor: + - platform: gcja5 + pm_1_0: + name: "Particulate Matter <1.0µm Concentration" + pm_2_5: + name: "Particulate Matter <2.5µm Concentration" + pm_10_0: + name: "Particulate Matter <10.0µm Concentration" + pmc_0_5: + name: "PMC 0.5" + pmc_1_0: + name: "PMC 1.0" + pmc_2_5: + name: "PMC 2.5" + pmc_5_0: + name: "PMC 5.0" + pmc_10_0: + name: "PMC 10.0" diff --git a/tests/components/gcja5/test.esp32-c3.yaml b/tests/components/gcja5/test.esp32-c3.yaml new file mode 100644 index 0000000000..ec8765be52 --- /dev/null +++ b/tests/components/gcja5/test.esp32-c3.yaml @@ -0,0 +1,25 @@ +uart: + - id: uart_gcja5 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + parity: EVEN + +sensor: + - platform: gcja5 + pm_1_0: + name: "Particulate Matter <1.0µm Concentration" + pm_2_5: + name: "Particulate Matter <2.5µm Concentration" + pm_10_0: + name: "Particulate Matter <10.0µm Concentration" + pmc_0_5: + name: "PMC 0.5" + pmc_1_0: + name: "PMC 1.0" + pmc_2_5: + name: "PMC 2.5" + pmc_5_0: + name: "PMC 5.0" + pmc_10_0: + name: "PMC 10.0" diff --git a/tests/components/gcja5/test.esp32-idf.yaml b/tests/components/gcja5/test.esp32-idf.yaml new file mode 100644 index 0000000000..bc0f89eb9e --- /dev/null +++ b/tests/components/gcja5/test.esp32-idf.yaml @@ -0,0 +1,25 @@ +uart: + - id: uart_gcja5 + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + parity: EVEN + +sensor: + - platform: gcja5 + pm_1_0: + name: "Particulate Matter <1.0µm Concentration" + pm_2_5: + name: "Particulate Matter <2.5µm Concentration" + pm_10_0: + name: "Particulate Matter <10.0µm Concentration" + pmc_0_5: + name: "PMC 0.5" + pmc_1_0: + name: "PMC 1.0" + pmc_2_5: + name: "PMC 2.5" + pmc_5_0: + name: "PMC 5.0" + pmc_10_0: + name: "PMC 10.0" diff --git a/tests/components/gcja5/test.esp32.yaml b/tests/components/gcja5/test.esp32.yaml new file mode 100644 index 0000000000..bc0f89eb9e --- /dev/null +++ b/tests/components/gcja5/test.esp32.yaml @@ -0,0 +1,25 @@ +uart: + - id: uart_gcja5 + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + parity: EVEN + +sensor: + - platform: gcja5 + pm_1_0: + name: "Particulate Matter <1.0µm Concentration" + pm_2_5: + name: "Particulate Matter <2.5µm Concentration" + pm_10_0: + name: "Particulate Matter <10.0µm Concentration" + pmc_0_5: + name: "PMC 0.5" + pmc_1_0: + name: "PMC 1.0" + pmc_2_5: + name: "PMC 2.5" + pmc_5_0: + name: "PMC 5.0" + pmc_10_0: + name: "PMC 10.0" diff --git a/tests/components/gcja5/test.esp8266.yaml b/tests/components/gcja5/test.esp8266.yaml new file mode 100644 index 0000000000..ec8765be52 --- /dev/null +++ b/tests/components/gcja5/test.esp8266.yaml @@ -0,0 +1,25 @@ +uart: + - id: uart_gcja5 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + parity: EVEN + +sensor: + - platform: gcja5 + pm_1_0: + name: "Particulate Matter <1.0µm Concentration" + pm_2_5: + name: "Particulate Matter <2.5µm Concentration" + pm_10_0: + name: "Particulate Matter <10.0µm Concentration" + pmc_0_5: + name: "PMC 0.5" + pmc_1_0: + name: "PMC 1.0" + pmc_2_5: + name: "PMC 2.5" + pmc_5_0: + name: "PMC 5.0" + pmc_10_0: + name: "PMC 10.0" diff --git a/tests/components/gcja5/test.rp2040.yaml b/tests/components/gcja5/test.rp2040.yaml new file mode 100644 index 0000000000..ec8765be52 --- /dev/null +++ b/tests/components/gcja5/test.rp2040.yaml @@ -0,0 +1,25 @@ +uart: + - id: uart_gcja5 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + parity: EVEN + +sensor: + - platform: gcja5 + pm_1_0: + name: "Particulate Matter <1.0µm Concentration" + pm_2_5: + name: "Particulate Matter <2.5µm Concentration" + pm_10_0: + name: "Particulate Matter <10.0µm Concentration" + pmc_0_5: + name: "PMC 0.5" + pmc_1_0: + name: "PMC 1.0" + pmc_2_5: + name: "PMC 2.5" + pmc_5_0: + name: "PMC 5.0" + pmc_10_0: + name: "PMC 10.0" diff --git a/tests/components/globals/test.esp32-c3-idf.yaml b/tests/components/globals/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..224a91a270 --- /dev/null +++ b/tests/components/globals/test.esp32-c3-idf.yaml @@ -0,0 +1,28 @@ +esphome: + on_boot: + then: + - globals.set: + id: glob_int + value: "10" + +globals: + - id: glob_int + type: int + restore_value: true + initial_value: "0" + - id: glob_float + type: float + restore_value: true + initial_value: "0.0f" + - id: glob_bool + type: bool + restore_value: false + initial_value: "true" + - id: glob_string + type: std::string + restore_value: false + # initial_value: "" + - id: glob_bool_processed + type: bool + restore_value: false + initial_value: "false" diff --git a/tests/components/globals/test.esp32-c3.yaml b/tests/components/globals/test.esp32-c3.yaml new file mode 100644 index 0000000000..224a91a270 --- /dev/null +++ b/tests/components/globals/test.esp32-c3.yaml @@ -0,0 +1,28 @@ +esphome: + on_boot: + then: + - globals.set: + id: glob_int + value: "10" + +globals: + - id: glob_int + type: int + restore_value: true + initial_value: "0" + - id: glob_float + type: float + restore_value: true + initial_value: "0.0f" + - id: glob_bool + type: bool + restore_value: false + initial_value: "true" + - id: glob_string + type: std::string + restore_value: false + # initial_value: "" + - id: glob_bool_processed + type: bool + restore_value: false + initial_value: "false" diff --git a/tests/components/globals/test.esp32-idf.yaml b/tests/components/globals/test.esp32-idf.yaml new file mode 100644 index 0000000000..224a91a270 --- /dev/null +++ b/tests/components/globals/test.esp32-idf.yaml @@ -0,0 +1,28 @@ +esphome: + on_boot: + then: + - globals.set: + id: glob_int + value: "10" + +globals: + - id: glob_int + type: int + restore_value: true + initial_value: "0" + - id: glob_float + type: float + restore_value: true + initial_value: "0.0f" + - id: glob_bool + type: bool + restore_value: false + initial_value: "true" + - id: glob_string + type: std::string + restore_value: false + # initial_value: "" + - id: glob_bool_processed + type: bool + restore_value: false + initial_value: "false" diff --git a/tests/components/globals/test.esp32.yaml b/tests/components/globals/test.esp32.yaml new file mode 100644 index 0000000000..224a91a270 --- /dev/null +++ b/tests/components/globals/test.esp32.yaml @@ -0,0 +1,28 @@ +esphome: + on_boot: + then: + - globals.set: + id: glob_int + value: "10" + +globals: + - id: glob_int + type: int + restore_value: true + initial_value: "0" + - id: glob_float + type: float + restore_value: true + initial_value: "0.0f" + - id: glob_bool + type: bool + restore_value: false + initial_value: "true" + - id: glob_string + type: std::string + restore_value: false + # initial_value: "" + - id: glob_bool_processed + type: bool + restore_value: false + initial_value: "false" diff --git a/tests/components/globals/test.esp8266.yaml b/tests/components/globals/test.esp8266.yaml new file mode 100644 index 0000000000..224a91a270 --- /dev/null +++ b/tests/components/globals/test.esp8266.yaml @@ -0,0 +1,28 @@ +esphome: + on_boot: + then: + - globals.set: + id: glob_int + value: "10" + +globals: + - id: glob_int + type: int + restore_value: true + initial_value: "0" + - id: glob_float + type: float + restore_value: true + initial_value: "0.0f" + - id: glob_bool + type: bool + restore_value: false + initial_value: "true" + - id: glob_string + type: std::string + restore_value: false + # initial_value: "" + - id: glob_bool_processed + type: bool + restore_value: false + initial_value: "false" diff --git a/tests/components/globals/test.rp2040.yaml b/tests/components/globals/test.rp2040.yaml new file mode 100644 index 0000000000..224a91a270 --- /dev/null +++ b/tests/components/globals/test.rp2040.yaml @@ -0,0 +1,28 @@ +esphome: + on_boot: + then: + - globals.set: + id: glob_int + value: "10" + +globals: + - id: glob_int + type: int + restore_value: true + initial_value: "0" + - id: glob_float + type: float + restore_value: true + initial_value: "0.0f" + - id: glob_bool + type: bool + restore_value: false + initial_value: "true" + - id: glob_string + type: std::string + restore_value: false + # initial_value: "" + - id: glob_bool_processed + type: bool + restore_value: false + initial_value: "false" diff --git a/tests/components/gp8403/test.esp32-c3-idf.yaml b/tests/components/gp8403/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..fbc40b948b --- /dev/null +++ b/tests/components/gp8403/test.esp32-c3-idf.yaml @@ -0,0 +1,20 @@ +i2c: + - id: i2c_gp8403 + scl: 5 + sda: 4 + +gp8403: + - id: gp8403_5v + voltage: 5V + - id: gp8403_10v + voltage: 10V + +output: + - platform: gp8403 + id: gp8403_output_0 + gp8403_id: gp8403_5v + channel: 0 + - platform: gp8403 + gp8403_id: gp8403_10v + id: gp8403_output_1 + channel: 1 diff --git a/tests/components/gp8403/test.esp32-c3.yaml b/tests/components/gp8403/test.esp32-c3.yaml new file mode 100644 index 0000000000..fbc40b948b --- /dev/null +++ b/tests/components/gp8403/test.esp32-c3.yaml @@ -0,0 +1,20 @@ +i2c: + - id: i2c_gp8403 + scl: 5 + sda: 4 + +gp8403: + - id: gp8403_5v + voltage: 5V + - id: gp8403_10v + voltage: 10V + +output: + - platform: gp8403 + id: gp8403_output_0 + gp8403_id: gp8403_5v + channel: 0 + - platform: gp8403 + gp8403_id: gp8403_10v + id: gp8403_output_1 + channel: 1 diff --git a/tests/components/gp8403/test.esp32-idf.yaml b/tests/components/gp8403/test.esp32-idf.yaml new file mode 100644 index 0000000000..8470a303e1 --- /dev/null +++ b/tests/components/gp8403/test.esp32-idf.yaml @@ -0,0 +1,20 @@ +i2c: + - id: i2c_gp8403 + scl: 16 + sda: 17 + +gp8403: + - id: gp8403_5v + voltage: 5V + - id: gp8403_10v + voltage: 10V + +output: + - platform: gp8403 + id: gp8403_output_0 + gp8403_id: gp8403_5v + channel: 0 + - platform: gp8403 + gp8403_id: gp8403_10v + id: gp8403_output_1 + channel: 1 diff --git a/tests/components/gp8403/test.esp32.yaml b/tests/components/gp8403/test.esp32.yaml new file mode 100644 index 0000000000..8470a303e1 --- /dev/null +++ b/tests/components/gp8403/test.esp32.yaml @@ -0,0 +1,20 @@ +i2c: + - id: i2c_gp8403 + scl: 16 + sda: 17 + +gp8403: + - id: gp8403_5v + voltage: 5V + - id: gp8403_10v + voltage: 10V + +output: + - platform: gp8403 + id: gp8403_output_0 + gp8403_id: gp8403_5v + channel: 0 + - platform: gp8403 + gp8403_id: gp8403_10v + id: gp8403_output_1 + channel: 1 diff --git a/tests/components/gp8403/test.esp8266.yaml b/tests/components/gp8403/test.esp8266.yaml new file mode 100644 index 0000000000..fbc40b948b --- /dev/null +++ b/tests/components/gp8403/test.esp8266.yaml @@ -0,0 +1,20 @@ +i2c: + - id: i2c_gp8403 + scl: 5 + sda: 4 + +gp8403: + - id: gp8403_5v + voltage: 5V + - id: gp8403_10v + voltage: 10V + +output: + - platform: gp8403 + id: gp8403_output_0 + gp8403_id: gp8403_5v + channel: 0 + - platform: gp8403 + gp8403_id: gp8403_10v + id: gp8403_output_1 + channel: 1 diff --git a/tests/components/gp8403/test.rp2040.yaml b/tests/components/gp8403/test.rp2040.yaml new file mode 100644 index 0000000000..fbc40b948b --- /dev/null +++ b/tests/components/gp8403/test.rp2040.yaml @@ -0,0 +1,20 @@ +i2c: + - id: i2c_gp8403 + scl: 5 + sda: 4 + +gp8403: + - id: gp8403_5v + voltage: 5V + - id: gp8403_10v + voltage: 10V + +output: + - platform: gp8403 + id: gp8403_output_0 + gp8403_id: gp8403_5v + channel: 0 + - platform: gp8403 + gp8403_id: gp8403_10v + id: gp8403_output_1 + channel: 1 diff --git a/tests/components/gpio/test.esp32-c3-idf.yaml b/tests/components/gpio/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..3ca285117d --- /dev/null +++ b/tests/components/gpio/test.esp32-c3-idf.yaml @@ -0,0 +1,14 @@ +binary_sensor: + - platform: gpio + pin: 2 + id: gpio_binary_sensor + +output: + - platform: gpio + pin: 3 + id: gpio_output + +switch: + - platform: gpio + pin: 4 + id: gpio_switch diff --git a/tests/components/gpio/test.esp32-c3.yaml b/tests/components/gpio/test.esp32-c3.yaml new file mode 100644 index 0000000000..3ca285117d --- /dev/null +++ b/tests/components/gpio/test.esp32-c3.yaml @@ -0,0 +1,14 @@ +binary_sensor: + - platform: gpio + pin: 2 + id: gpio_binary_sensor + +output: + - platform: gpio + pin: 3 + id: gpio_output + +switch: + - platform: gpio + pin: 4 + id: gpio_switch diff --git a/tests/components/gpio/test.esp32-idf.yaml b/tests/components/gpio/test.esp32-idf.yaml new file mode 100644 index 0000000000..30dfa94b68 --- /dev/null +++ b/tests/components/gpio/test.esp32-idf.yaml @@ -0,0 +1,14 @@ +binary_sensor: + - platform: gpio + pin: 12 + id: gpio_binary_sensor + +output: + - platform: gpio + pin: 13 + id: gpio_output + +switch: + - platform: gpio + pin: 14 + id: gpio_switch diff --git a/tests/components/gpio/test.esp32.yaml b/tests/components/gpio/test.esp32.yaml new file mode 100644 index 0000000000..30dfa94b68 --- /dev/null +++ b/tests/components/gpio/test.esp32.yaml @@ -0,0 +1,14 @@ +binary_sensor: + - platform: gpio + pin: 12 + id: gpio_binary_sensor + +output: + - platform: gpio + pin: 13 + id: gpio_output + +switch: + - platform: gpio + pin: 14 + id: gpio_switch diff --git a/tests/components/gpio/test.esp8266.yaml b/tests/components/gpio/test.esp8266.yaml new file mode 100644 index 0000000000..30dfa94b68 --- /dev/null +++ b/tests/components/gpio/test.esp8266.yaml @@ -0,0 +1,14 @@ +binary_sensor: + - platform: gpio + pin: 12 + id: gpio_binary_sensor + +output: + - platform: gpio + pin: 13 + id: gpio_output + +switch: + - platform: gpio + pin: 14 + id: gpio_switch diff --git a/tests/components/gpio/test.rp2040.yaml b/tests/components/gpio/test.rp2040.yaml new file mode 100644 index 0000000000..3ca285117d --- /dev/null +++ b/tests/components/gpio/test.rp2040.yaml @@ -0,0 +1,14 @@ +binary_sensor: + - platform: gpio + pin: 2 + id: gpio_binary_sensor + +output: + - platform: gpio + pin: 3 + id: gpio_output + +switch: + - platform: gpio + pin: 4 + id: gpio_switch diff --git a/tests/components/gps/test.esp32-c3.yaml b/tests/components/gps/test.esp32-c3.yaml new file mode 100644 index 0000000000..031f45b873 --- /dev/null +++ b/tests/components/gps/test.esp32-c3.yaml @@ -0,0 +1,14 @@ +uart: + - id: uart_gps + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + parity: EVEN + +gps: + +time: + - platform: gps + on_time_sync: + then: + logger.log: "It's time!" diff --git a/tests/components/gps/test.esp32.yaml b/tests/components/gps/test.esp32.yaml new file mode 100644 index 0000000000..c4e4cf9f6f --- /dev/null +++ b/tests/components/gps/test.esp32.yaml @@ -0,0 +1,14 @@ +uart: + - id: uart_gps + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + parity: EVEN + +gps: + +time: + - platform: gps + on_time_sync: + then: + logger.log: "It's time!" diff --git a/tests/components/gps/test.esp8266.yaml b/tests/components/gps/test.esp8266.yaml new file mode 100644 index 0000000000..031f45b873 --- /dev/null +++ b/tests/components/gps/test.esp8266.yaml @@ -0,0 +1,14 @@ +uart: + - id: uart_gps + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + parity: EVEN + +gps: + +time: + - platform: gps + on_time_sync: + then: + logger.log: "It's time!" diff --git a/tests/components/gps/test.rp2040.yaml b/tests/components/gps/test.rp2040.yaml new file mode 100644 index 0000000000..031f45b873 --- /dev/null +++ b/tests/components/gps/test.rp2040.yaml @@ -0,0 +1,14 @@ +uart: + - id: uart_gps + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + parity: EVEN + +gps: + +time: + - platform: gps + on_time_sync: + then: + logger.log: "It's time!" diff --git a/tests/components/graph/test.esp32-c3-idf.yaml b/tests/components/graph/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..8ce40e84ac --- /dev/null +++ b/tests/components/graph/test.esp32-c3-idf.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_graph + scl: 5 + sda: 4 + +sensor: + - platform: template + id: some_sensor + +graph: + - id: some_graph + sensor: some_sensor + duration: 1h + width: 100 + height: 100 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); diff --git a/tests/components/graph/test.esp32-c3.yaml b/tests/components/graph/test.esp32-c3.yaml new file mode 100644 index 0000000000..8ce40e84ac --- /dev/null +++ b/tests/components/graph/test.esp32-c3.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_graph + scl: 5 + sda: 4 + +sensor: + - platform: template + id: some_sensor + +graph: + - id: some_graph + sensor: some_sensor + duration: 1h + width: 100 + height: 100 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); diff --git a/tests/components/graph/test.esp32-idf.yaml b/tests/components/graph/test.esp32-idf.yaml new file mode 100644 index 0000000000..8c0c0d4c9e --- /dev/null +++ b/tests/components/graph/test.esp32-idf.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_graph + scl: 16 + sda: 17 + +sensor: + - platform: template + id: some_sensor + +graph: + - id: some_graph + sensor: some_sensor + duration: 1h + width: 100 + height: 100 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); diff --git a/tests/components/graph/test.esp32.yaml b/tests/components/graph/test.esp32.yaml new file mode 100644 index 0000000000..8c0c0d4c9e --- /dev/null +++ b/tests/components/graph/test.esp32.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_graph + scl: 16 + sda: 17 + +sensor: + - platform: template + id: some_sensor + +graph: + - id: some_graph + sensor: some_sensor + duration: 1h + width: 100 + height: 100 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); diff --git a/tests/components/graph/test.esp8266.yaml b/tests/components/graph/test.esp8266.yaml new file mode 100644 index 0000000000..33318355d5 --- /dev/null +++ b/tests/components/graph/test.esp8266.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_graph + scl: 5 + sda: 4 + +sensor: + - platform: template + id: some_sensor + +graph: + - id: some_graph + sensor: some_sensor + duration: 1h + width: 100 + height: 100 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); diff --git a/tests/components/graph/test.rp2040.yaml b/tests/components/graph/test.rp2040.yaml new file mode 100644 index 0000000000..8ce40e84ac --- /dev/null +++ b/tests/components/graph/test.rp2040.yaml @@ -0,0 +1,25 @@ +i2c: + - id: i2c_graph + scl: 5 + sda: 4 + +sensor: + - platform: template + id: some_sensor + +graph: + - id: some_graph + sensor: some_sensor + duration: 1h + width: 100 + height: 100 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); diff --git a/tests/components/graphical_display_menu/test.esp32-c3-idf.yaml b/tests/components/graphical_display_menu/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..23acd4e4d9 --- /dev/null +++ b/tests/components/graphical_display_menu/test.esp32-c3-idf.yaml @@ -0,0 +1,120 @@ +i2c: + - id: i2c_graphical_display_menu + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +font: + - file: "gfonts://Roboto" + id: roboto + size: 20 + +number: + - platform: template + id: test_number + min_value: 0 + step: 1 + max_value: 10 + optimistic: true + +select: + - platform: template + id: test_select + options: + - one + - two + optimistic: true + +switch: + - platform: template + id: test_switch + optimistic: true + +graphical_display_menu: + id: test_graphical_display_menu + display: ssd1306_display + font: roboto + active: false + mode: rotary + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "root enter");' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "root leave");' + items: + - type: back + text: "Back" + - type: label + - type: menu + text: "Submenu 1" + items: + - type: back + text: "Back" + - type: menu + text: "Submenu 21" + items: + - type: back + text: "Back" + - type: command + text: "Show Main" + on_value: + then: + - display_menu.show_main: test_graphical_display_menu + - type: select + text: "Enum Item" + immediate_edit: true + select: test_select + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: number + text: "Number" + number: test_number + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: command + text: "Hide" + on_value: + then: + - display_menu.hide: test_graphical_display_menu + - type: switch + text: "Switch" + switch: test_switch + on_text: "Bright" + off_text: "Dark" + immediate_edit: false + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "switch value: %s", it->get_value_text().c_str());' + - type: custom + text: !lambda 'return "Custom";' + value_lambda: 'return "Val";' + on_next: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "custom next: %s", it->get_text().c_str());' + on_prev: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "custom prev: %s", it->get_text().c_str());' diff --git a/tests/components/graphical_display_menu/test.esp32-c3.yaml b/tests/components/graphical_display_menu/test.esp32-c3.yaml new file mode 100644 index 0000000000..23acd4e4d9 --- /dev/null +++ b/tests/components/graphical_display_menu/test.esp32-c3.yaml @@ -0,0 +1,120 @@ +i2c: + - id: i2c_graphical_display_menu + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +font: + - file: "gfonts://Roboto" + id: roboto + size: 20 + +number: + - platform: template + id: test_number + min_value: 0 + step: 1 + max_value: 10 + optimistic: true + +select: + - platform: template + id: test_select + options: + - one + - two + optimistic: true + +switch: + - platform: template + id: test_switch + optimistic: true + +graphical_display_menu: + id: test_graphical_display_menu + display: ssd1306_display + font: roboto + active: false + mode: rotary + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "root enter");' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "root leave");' + items: + - type: back + text: "Back" + - type: label + - type: menu + text: "Submenu 1" + items: + - type: back + text: "Back" + - type: menu + text: "Submenu 21" + items: + - type: back + text: "Back" + - type: command + text: "Show Main" + on_value: + then: + - display_menu.show_main: test_graphical_display_menu + - type: select + text: "Enum Item" + immediate_edit: true + select: test_select + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: number + text: "Number" + number: test_number + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: command + text: "Hide" + on_value: + then: + - display_menu.hide: test_graphical_display_menu + - type: switch + text: "Switch" + switch: test_switch + on_text: "Bright" + off_text: "Dark" + immediate_edit: false + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "switch value: %s", it->get_value_text().c_str());' + - type: custom + text: !lambda 'return "Custom";' + value_lambda: 'return "Val";' + on_next: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "custom next: %s", it->get_text().c_str());' + on_prev: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "custom prev: %s", it->get_text().c_str());' diff --git a/tests/components/graphical_display_menu/test.esp32-idf.yaml b/tests/components/graphical_display_menu/test.esp32-idf.yaml new file mode 100644 index 0000000000..a0897536d7 --- /dev/null +++ b/tests/components/graphical_display_menu/test.esp32-idf.yaml @@ -0,0 +1,120 @@ +i2c: + - id: i2c_graphical_display_menu + scl: 16 + sda: 17 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +font: + - file: "gfonts://Roboto" + id: roboto + size: 20 + +number: + - platform: template + id: test_number + min_value: 0 + step: 1 + max_value: 10 + optimistic: true + +select: + - platform: template + id: test_select + options: + - one + - two + optimistic: true + +switch: + - platform: template + id: test_switch + optimistic: true + +graphical_display_menu: + id: test_graphical_display_menu + display: ssd1306_display + font: roboto + active: false + mode: rotary + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "root enter");' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "root leave");' + items: + - type: back + text: "Back" + - type: label + - type: menu + text: "Submenu 1" + items: + - type: back + text: "Back" + - type: menu + text: "Submenu 21" + items: + - type: back + text: "Back" + - type: command + text: "Show Main" + on_value: + then: + - display_menu.show_main: test_graphical_display_menu + - type: select + text: "Enum Item" + immediate_edit: true + select: test_select + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: number + text: "Number" + number: test_number + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: command + text: "Hide" + on_value: + then: + - display_menu.hide: test_graphical_display_menu + - type: switch + text: "Switch" + switch: test_switch + on_text: "Bright" + off_text: "Dark" + immediate_edit: false + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "switch value: %s", it->get_value_text().c_str());' + - type: custom + text: !lambda 'return "Custom";' + value_lambda: 'return "Val";' + on_next: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "custom next: %s", it->get_text().c_str());' + on_prev: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "custom prev: %s", it->get_text().c_str());' diff --git a/tests/components/graphical_display_menu/test.esp32.yaml b/tests/components/graphical_display_menu/test.esp32.yaml new file mode 100644 index 0000000000..a0897536d7 --- /dev/null +++ b/tests/components/graphical_display_menu/test.esp32.yaml @@ -0,0 +1,120 @@ +i2c: + - id: i2c_graphical_display_menu + scl: 16 + sda: 17 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +font: + - file: "gfonts://Roboto" + id: roboto + size: 20 + +number: + - platform: template + id: test_number + min_value: 0 + step: 1 + max_value: 10 + optimistic: true + +select: + - platform: template + id: test_select + options: + - one + - two + optimistic: true + +switch: + - platform: template + id: test_switch + optimistic: true + +graphical_display_menu: + id: test_graphical_display_menu + display: ssd1306_display + font: roboto + active: false + mode: rotary + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "root enter");' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "root leave");' + items: + - type: back + text: "Back" + - type: label + - type: menu + text: "Submenu 1" + items: + - type: back + text: "Back" + - type: menu + text: "Submenu 21" + items: + - type: back + text: "Back" + - type: command + text: "Show Main" + on_value: + then: + - display_menu.show_main: test_graphical_display_menu + - type: select + text: "Enum Item" + immediate_edit: true + select: test_select + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: number + text: "Number" + number: test_number + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: command + text: "Hide" + on_value: + then: + - display_menu.hide: test_graphical_display_menu + - type: switch + text: "Switch" + switch: test_switch + on_text: "Bright" + off_text: "Dark" + immediate_edit: false + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "switch value: %s", it->get_value_text().c_str());' + - type: custom + text: !lambda 'return "Custom";' + value_lambda: 'return "Val";' + on_next: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "custom next: %s", it->get_text().c_str());' + on_prev: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "custom prev: %s", it->get_text().c_str());' diff --git a/tests/components/graphical_display_menu/test.esp8266.yaml b/tests/components/graphical_display_menu/test.esp8266.yaml new file mode 100644 index 0000000000..28c1a7298d --- /dev/null +++ b/tests/components/graphical_display_menu/test.esp8266.yaml @@ -0,0 +1,120 @@ +i2c: + - id: i2c_graphical_display_menu + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +font: + - file: "gfonts://Roboto" + id: roboto + size: 20 + +number: + - platform: template + id: test_number + min_value: 0 + step: 1 + max_value: 10 + optimistic: true + +select: + - platform: template + id: test_select + options: + - one + - two + optimistic: true + +switch: + - platform: template + id: test_switch + optimistic: true + +graphical_display_menu: + id: test_graphical_display_menu + display: ssd1306_display + font: roboto + active: false + mode: rotary + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "root enter");' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "root leave");' + items: + - type: back + text: "Back" + - type: label + - type: menu + text: "Submenu 1" + items: + - type: back + text: "Back" + - type: menu + text: "Submenu 21" + items: + - type: back + text: "Back" + - type: command + text: "Show Main" + on_value: + then: + - display_menu.show_main: test_graphical_display_menu + - type: select + text: "Enum Item" + immediate_edit: true + select: test_select + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: number + text: "Number" + number: test_number + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: command + text: "Hide" + on_value: + then: + - display_menu.hide: test_graphical_display_menu + - type: switch + text: "Switch" + switch: test_switch + on_text: "Bright" + off_text: "Dark" + immediate_edit: false + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "switch value: %s", it->get_value_text().c_str());' + - type: custom + text: !lambda 'return "Custom";' + value_lambda: 'return "Val";' + on_next: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "custom next: %s", it->get_text().c_str());' + on_prev: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "custom prev: %s", it->get_text().c_str());' diff --git a/tests/components/graphical_display_menu/test.rp2040.yaml b/tests/components/graphical_display_menu/test.rp2040.yaml new file mode 100644 index 0000000000..23acd4e4d9 --- /dev/null +++ b/tests/components/graphical_display_menu/test.rp2040.yaml @@ -0,0 +1,120 @@ +i2c: + - id: i2c_graphical_display_menu + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +font: + - file: "gfonts://Roboto" + id: roboto + size: 20 + +number: + - platform: template + id: test_number + min_value: 0 + step: 1 + max_value: 10 + optimistic: true + +select: + - platform: template + id: test_select + options: + - one + - two + optimistic: true + +switch: + - platform: template + id: test_switch + optimistic: true + +graphical_display_menu: + id: test_graphical_display_menu + display: ssd1306_display + font: roboto + active: false + mode: rotary + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "root enter");' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "root leave");' + items: + - type: back + text: "Back" + - type: label + - type: menu + text: "Submenu 1" + items: + - type: back + text: "Back" + - type: menu + text: "Submenu 21" + items: + - type: back + text: "Back" + - type: command + text: "Show Main" + on_value: + then: + - display_menu.show_main: test_graphical_display_menu + - type: select + text: "Enum Item" + immediate_edit: true + select: test_select + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: number + text: "Number" + number: test_number + on_enter: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: command + text: "Hide" + on_value: + then: + - display_menu.hide: test_graphical_display_menu + - type: switch + text: "Switch" + switch: test_switch + on_text: "Bright" + off_text: "Dark" + immediate_edit: false + on_value: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "switch value: %s", it->get_value_text().c_str());' + - type: custom + text: !lambda 'return "Custom";' + value_lambda: 'return "Val";' + on_next: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "custom next: %s", it->get_text().c_str());' + on_prev: + then: + lambda: 'ESP_LOGI("graphical_display_menu", "custom prev: %s", it->get_text().c_str());' diff --git a/tests/components/gree/test.esp32-c3-idf.yaml b/tests/components/gree/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..91491d7e16 --- /dev/null +++ b/tests/components/gree/test.esp32-c3-idf.yaml @@ -0,0 +1,8 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: gree + name: GREE + model: generic diff --git a/tests/components/gree/test.esp32-c3.yaml b/tests/components/gree/test.esp32-c3.yaml new file mode 100644 index 0000000000..91491d7e16 --- /dev/null +++ b/tests/components/gree/test.esp32-c3.yaml @@ -0,0 +1,8 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: gree + name: GREE + model: generic diff --git a/tests/components/gree/test.esp32-idf.yaml b/tests/components/gree/test.esp32-idf.yaml new file mode 100644 index 0000000000..91491d7e16 --- /dev/null +++ b/tests/components/gree/test.esp32-idf.yaml @@ -0,0 +1,8 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: gree + name: GREE + model: generic diff --git a/tests/components/gree/test.esp32.yaml b/tests/components/gree/test.esp32.yaml new file mode 100644 index 0000000000..91491d7e16 --- /dev/null +++ b/tests/components/gree/test.esp32.yaml @@ -0,0 +1,8 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: gree + name: GREE + model: generic diff --git a/tests/components/gree/test.esp8266.yaml b/tests/components/gree/test.esp8266.yaml new file mode 100644 index 0000000000..d0542973ce --- /dev/null +++ b/tests/components/gree/test.esp8266.yaml @@ -0,0 +1,8 @@ +remote_transmitter: + pin: 5 + carrier_duty_percent: 50% + +climate: + - platform: gree + name: GREE + model: generic diff --git a/tests/components/grove_tb6612fng/test.esp32-c3-idf.yaml b/tests/components/grove_tb6612fng/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..ef6dff6539 --- /dev/null +++ b/tests/components/grove_tb6612fng/test.esp32-c3-idf.yaml @@ -0,0 +1,23 @@ +esphome: + on_boot: + then: + - grove_tb6612fng.run: + channel: 1 + speed: 255 + direction: BACKWARD + id: test_motor + - grove_tb6612fng.stop: + channel: 1 + id: test_motor + - grove_tb6612fng.break: + channel: 1 + id: test_motor + +i2c: + - id: i2c_grove_tb6612fng + scl: 5 + sda: 4 + +grove_tb6612fng: + id: test_motor + address: 0x14 diff --git a/tests/components/grove_tb6612fng/test.esp32-c3.yaml b/tests/components/grove_tb6612fng/test.esp32-c3.yaml new file mode 100644 index 0000000000..ef6dff6539 --- /dev/null +++ b/tests/components/grove_tb6612fng/test.esp32-c3.yaml @@ -0,0 +1,23 @@ +esphome: + on_boot: + then: + - grove_tb6612fng.run: + channel: 1 + speed: 255 + direction: BACKWARD + id: test_motor + - grove_tb6612fng.stop: + channel: 1 + id: test_motor + - grove_tb6612fng.break: + channel: 1 + id: test_motor + +i2c: + - id: i2c_grove_tb6612fng + scl: 5 + sda: 4 + +grove_tb6612fng: + id: test_motor + address: 0x14 diff --git a/tests/components/grove_tb6612fng/test.esp32-idf.yaml b/tests/components/grove_tb6612fng/test.esp32-idf.yaml new file mode 100644 index 0000000000..3271fb754f --- /dev/null +++ b/tests/components/grove_tb6612fng/test.esp32-idf.yaml @@ -0,0 +1,23 @@ +esphome: + on_boot: + then: + - grove_tb6612fng.run: + channel: 1 + speed: 255 + direction: BACKWARD + id: test_motor + - grove_tb6612fng.stop: + channel: 1 + id: test_motor + - grove_tb6612fng.break: + channel: 1 + id: test_motor + +i2c: + - id: i2c_grove_tb6612fng + scl: 16 + sda: 17 + +grove_tb6612fng: + id: test_motor + address: 0x14 diff --git a/tests/components/grove_tb6612fng/test.esp32.yaml b/tests/components/grove_tb6612fng/test.esp32.yaml new file mode 100644 index 0000000000..3271fb754f --- /dev/null +++ b/tests/components/grove_tb6612fng/test.esp32.yaml @@ -0,0 +1,23 @@ +esphome: + on_boot: + then: + - grove_tb6612fng.run: + channel: 1 + speed: 255 + direction: BACKWARD + id: test_motor + - grove_tb6612fng.stop: + channel: 1 + id: test_motor + - grove_tb6612fng.break: + channel: 1 + id: test_motor + +i2c: + - id: i2c_grove_tb6612fng + scl: 16 + sda: 17 + +grove_tb6612fng: + id: test_motor + address: 0x14 diff --git a/tests/components/grove_tb6612fng/test.esp8266.yaml b/tests/components/grove_tb6612fng/test.esp8266.yaml new file mode 100644 index 0000000000..ef6dff6539 --- /dev/null +++ b/tests/components/grove_tb6612fng/test.esp8266.yaml @@ -0,0 +1,23 @@ +esphome: + on_boot: + then: + - grove_tb6612fng.run: + channel: 1 + speed: 255 + direction: BACKWARD + id: test_motor + - grove_tb6612fng.stop: + channel: 1 + id: test_motor + - grove_tb6612fng.break: + channel: 1 + id: test_motor + +i2c: + - id: i2c_grove_tb6612fng + scl: 5 + sda: 4 + +grove_tb6612fng: + id: test_motor + address: 0x14 diff --git a/tests/components/grove_tb6612fng/test.rp2040.yaml b/tests/components/grove_tb6612fng/test.rp2040.yaml new file mode 100644 index 0000000000..ef6dff6539 --- /dev/null +++ b/tests/components/grove_tb6612fng/test.rp2040.yaml @@ -0,0 +1,23 @@ +esphome: + on_boot: + then: + - grove_tb6612fng.run: + channel: 1 + speed: 255 + direction: BACKWARD + id: test_motor + - grove_tb6612fng.stop: + channel: 1 + id: test_motor + - grove_tb6612fng.break: + channel: 1 + id: test_motor + +i2c: + - id: i2c_grove_tb6612fng + scl: 5 + sda: 4 + +grove_tb6612fng: + id: test_motor + address: 0x14 diff --git a/tests/components/growatt_solar/test.esp32-c3-idf.yaml b/tests/components/growatt_solar/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..3b5e2e4ce4 --- /dev/null +++ b/tests/components/growatt_solar/test.esp32-c3-idf.yaml @@ -0,0 +1,62 @@ +uart: + - id: uart_growatt_solar + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +modbus: + flow_control_pin: 3 + +sensor: + - platform: growatt_solar + update_interval: 10s + protocol_version: RTU + inverter_status: + name: Growatt Status Code + phase_a: + voltage: + name: Growatt Voltage Phase A + current: + name: Growatt Current Phase A + active_power: + name: Growatt Power Phase A + phase_b: + voltage: + name: Growatt Voltage Phase B + current: + name: Growatt Current Phase B + active_power: + name: Growatt Power Phase B + phase_c: + voltage: + name: Growatt Voltage Phase C + current: + name: Growatt Current Phase C + active_power: + name: Growatt Power Phase C + pv1: + voltage: + name: Growatt PV1 Voltage + current: + name: Growatt PV1 Current + active_power: + name: Growatt PV1 Active Power + pv2: + voltage: + name: Growatt PV2 Voltage + current: + name: Growatt PV2 Current + active_power: + name: Growatt PV2 Active Power + active_power: + name: Growatt Grid Active Power + pv_active_power: + name: Growatt PV Active Power + frequency: + name: Growatt Frequency + energy_production_day: + name: Growatt Today's Generation + total_energy_production: + name: Growatt Total Energy Production + inverter_module_temp: + name: Growatt Inverter Module Temp diff --git a/tests/components/growatt_solar/test.esp32-c3.yaml b/tests/components/growatt_solar/test.esp32-c3.yaml new file mode 100644 index 0000000000..3b5e2e4ce4 --- /dev/null +++ b/tests/components/growatt_solar/test.esp32-c3.yaml @@ -0,0 +1,62 @@ +uart: + - id: uart_growatt_solar + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +modbus: + flow_control_pin: 3 + +sensor: + - platform: growatt_solar + update_interval: 10s + protocol_version: RTU + inverter_status: + name: Growatt Status Code + phase_a: + voltage: + name: Growatt Voltage Phase A + current: + name: Growatt Current Phase A + active_power: + name: Growatt Power Phase A + phase_b: + voltage: + name: Growatt Voltage Phase B + current: + name: Growatt Current Phase B + active_power: + name: Growatt Power Phase B + phase_c: + voltage: + name: Growatt Voltage Phase C + current: + name: Growatt Current Phase C + active_power: + name: Growatt Power Phase C + pv1: + voltage: + name: Growatt PV1 Voltage + current: + name: Growatt PV1 Current + active_power: + name: Growatt PV1 Active Power + pv2: + voltage: + name: Growatt PV2 Voltage + current: + name: Growatt PV2 Current + active_power: + name: Growatt PV2 Active Power + active_power: + name: Growatt Grid Active Power + pv_active_power: + name: Growatt PV Active Power + frequency: + name: Growatt Frequency + energy_production_day: + name: Growatt Today's Generation + total_energy_production: + name: Growatt Total Energy Production + inverter_module_temp: + name: Growatt Inverter Module Temp diff --git a/tests/components/growatt_solar/test.esp32-idf.yaml b/tests/components/growatt_solar/test.esp32-idf.yaml new file mode 100644 index 0000000000..a0670fdbd6 --- /dev/null +++ b/tests/components/growatt_solar/test.esp32-idf.yaml @@ -0,0 +1,62 @@ +uart: + - id: uart_growatt_solar + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + +modbus: + flow_control_pin: 13 + +sensor: + - platform: growatt_solar + update_interval: 10s + protocol_version: RTU + inverter_status: + name: Growatt Status Code + phase_a: + voltage: + name: Growatt Voltage Phase A + current: + name: Growatt Current Phase A + active_power: + name: Growatt Power Phase A + phase_b: + voltage: + name: Growatt Voltage Phase B + current: + name: Growatt Current Phase B + active_power: + name: Growatt Power Phase B + phase_c: + voltage: + name: Growatt Voltage Phase C + current: + name: Growatt Current Phase C + active_power: + name: Growatt Power Phase C + pv1: + voltage: + name: Growatt PV1 Voltage + current: + name: Growatt PV1 Current + active_power: + name: Growatt PV1 Active Power + pv2: + voltage: + name: Growatt PV2 Voltage + current: + name: Growatt PV2 Current + active_power: + name: Growatt PV2 Active Power + active_power: + name: Growatt Grid Active Power + pv_active_power: + name: Growatt PV Active Power + frequency: + name: Growatt Frequency + energy_production_day: + name: Growatt Today's Generation + total_energy_production: + name: Growatt Total Energy Production + inverter_module_temp: + name: Growatt Inverter Module Temp diff --git a/tests/components/growatt_solar/test.esp32.yaml b/tests/components/growatt_solar/test.esp32.yaml new file mode 100644 index 0000000000..a0670fdbd6 --- /dev/null +++ b/tests/components/growatt_solar/test.esp32.yaml @@ -0,0 +1,62 @@ +uart: + - id: uart_growatt_solar + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + +modbus: + flow_control_pin: 13 + +sensor: + - platform: growatt_solar + update_interval: 10s + protocol_version: RTU + inverter_status: + name: Growatt Status Code + phase_a: + voltage: + name: Growatt Voltage Phase A + current: + name: Growatt Current Phase A + active_power: + name: Growatt Power Phase A + phase_b: + voltage: + name: Growatt Voltage Phase B + current: + name: Growatt Current Phase B + active_power: + name: Growatt Power Phase B + phase_c: + voltage: + name: Growatt Voltage Phase C + current: + name: Growatt Current Phase C + active_power: + name: Growatt Power Phase C + pv1: + voltage: + name: Growatt PV1 Voltage + current: + name: Growatt PV1 Current + active_power: + name: Growatt PV1 Active Power + pv2: + voltage: + name: Growatt PV2 Voltage + current: + name: Growatt PV2 Current + active_power: + name: Growatt PV2 Active Power + active_power: + name: Growatt Grid Active Power + pv_active_power: + name: Growatt PV Active Power + frequency: + name: Growatt Frequency + energy_production_day: + name: Growatt Today's Generation + total_energy_production: + name: Growatt Total Energy Production + inverter_module_temp: + name: Growatt Inverter Module Temp diff --git a/tests/components/growatt_solar/test.esp8266.yaml b/tests/components/growatt_solar/test.esp8266.yaml new file mode 100644 index 0000000000..fed27ffda1 --- /dev/null +++ b/tests/components/growatt_solar/test.esp8266.yaml @@ -0,0 +1,62 @@ +uart: + - id: uart_growatt_solar + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +modbus: + flow_control_pin: 13 + +sensor: + - platform: growatt_solar + update_interval: 10s + protocol_version: RTU + inverter_status: + name: Growatt Status Code + phase_a: + voltage: + name: Growatt Voltage Phase A + current: + name: Growatt Current Phase A + active_power: + name: Growatt Power Phase A + phase_b: + voltage: + name: Growatt Voltage Phase B + current: + name: Growatt Current Phase B + active_power: + name: Growatt Power Phase B + phase_c: + voltage: + name: Growatt Voltage Phase C + current: + name: Growatt Current Phase C + active_power: + name: Growatt Power Phase C + pv1: + voltage: + name: Growatt PV1 Voltage + current: + name: Growatt PV1 Current + active_power: + name: Growatt PV1 Active Power + pv2: + voltage: + name: Growatt PV2 Voltage + current: + name: Growatt PV2 Current + active_power: + name: Growatt PV2 Active Power + active_power: + name: Growatt Grid Active Power + pv_active_power: + name: Growatt PV Active Power + frequency: + name: Growatt Frequency + energy_production_day: + name: Growatt Today's Generation + total_energy_production: + name: Growatt Total Energy Production + inverter_module_temp: + name: Growatt Inverter Module Temp diff --git a/tests/components/growatt_solar/test.rp2040.yaml b/tests/components/growatt_solar/test.rp2040.yaml new file mode 100644 index 0000000000..3b5e2e4ce4 --- /dev/null +++ b/tests/components/growatt_solar/test.rp2040.yaml @@ -0,0 +1,62 @@ +uart: + - id: uart_growatt_solar + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +modbus: + flow_control_pin: 3 + +sensor: + - platform: growatt_solar + update_interval: 10s + protocol_version: RTU + inverter_status: + name: Growatt Status Code + phase_a: + voltage: + name: Growatt Voltage Phase A + current: + name: Growatt Current Phase A + active_power: + name: Growatt Power Phase A + phase_b: + voltage: + name: Growatt Voltage Phase B + current: + name: Growatt Current Phase B + active_power: + name: Growatt Power Phase B + phase_c: + voltage: + name: Growatt Voltage Phase C + current: + name: Growatt Current Phase C + active_power: + name: Growatt Power Phase C + pv1: + voltage: + name: Growatt PV1 Voltage + current: + name: Growatt PV1 Current + active_power: + name: Growatt PV1 Active Power + pv2: + voltage: + name: Growatt PV2 Voltage + current: + name: Growatt PV2 Current + active_power: + name: Growatt PV2 Active Power + active_power: + name: Growatt Grid Active Power + pv_active_power: + name: Growatt PV Active Power + frequency: + name: Growatt Frequency + energy_production_day: + name: Growatt Today's Generation + total_energy_production: + name: Growatt Total Energy Production + inverter_module_temp: + name: Growatt Inverter Module Temp diff --git a/tests/components/gt911/test.esp32-c3-idf.yaml b/tests/components/gt911/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..43f7ac5902 --- /dev/null +++ b/tests/components/gt911/test.esp32-c3-idf.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_gt911 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: gt911 + display: ssd1306_display + interrupt_pin: 6 + +binary_sensor: + - platform: gt911 + id: touch_key_911 + index: 0 diff --git a/tests/components/gt911/test.esp32-c3.yaml b/tests/components/gt911/test.esp32-c3.yaml new file mode 100644 index 0000000000..43f7ac5902 --- /dev/null +++ b/tests/components/gt911/test.esp32-c3.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_gt911 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: gt911 + display: ssd1306_display + interrupt_pin: 6 + +binary_sensor: + - platform: gt911 + id: touch_key_911 + index: 0 diff --git a/tests/components/gt911/test.esp32-idf.yaml b/tests/components/gt911/test.esp32-idf.yaml new file mode 100644 index 0000000000..a47f7bf260 --- /dev/null +++ b/tests/components/gt911/test.esp32-idf.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_gt911 + scl: 16 + sda: 17 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: gt911 + display: ssd1306_display + interrupt_pin: 14 + +binary_sensor: + - platform: gt911 + id: touch_key_911 + index: 0 diff --git a/tests/components/gt911/test.esp32.yaml b/tests/components/gt911/test.esp32.yaml new file mode 100644 index 0000000000..a47f7bf260 --- /dev/null +++ b/tests/components/gt911/test.esp32.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_gt911 + scl: 16 + sda: 17 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: gt911 + display: ssd1306_display + interrupt_pin: 14 + +binary_sensor: + - platform: gt911 + id: touch_key_911 + index: 0 diff --git a/tests/components/gt911/test.esp8266.yaml b/tests/components/gt911/test.esp8266.yaml new file mode 100644 index 0000000000..8b76eff29e --- /dev/null +++ b/tests/components/gt911/test.esp8266.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_gt911 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: gt911 + display: ssd1306_display + interrupt_pin: 12 + +binary_sensor: + - platform: gt911 + id: touch_key_911 + index: 0 diff --git a/tests/components/gt911/test.rp2040.yaml b/tests/components/gt911/test.rp2040.yaml new file mode 100644 index 0000000000..43f7ac5902 --- /dev/null +++ b/tests/components/gt911/test.rp2040.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_gt911 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: gt911 + display: ssd1306_display + interrupt_pin: 6 + +binary_sensor: + - platform: gt911 + id: touch_key_911 + index: 0 From ca6020e11a801b65f334c268a3638ae73b629f66 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Tue, 26 Mar 2024 20:22:54 -0500 Subject: [PATCH 162/189] Add some components to the new testing framework (K) (#6186) --- .../key_collector/test.esp32-c3-idf.yaml | 28 +++++++++++++++++++ .../key_collector/test.esp32-c3.yaml | 28 +++++++++++++++++++ .../key_collector/test.esp32-idf.yaml | 28 +++++++++++++++++++ .../components/key_collector/test.esp32.yaml | 28 +++++++++++++++++++ .../key_collector/test.esp8266.yaml | 28 +++++++++++++++++++ .../components/key_collector/test.rp2040.yaml | 28 +++++++++++++++++++ .../kmeteriso/test.esp32-c3-idf.yaml | 12 ++++++++ tests/components/kmeteriso/test.esp32-c3.yaml | 12 ++++++++ .../components/kmeteriso/test.esp32-idf.yaml | 12 ++++++++ tests/components/kmeteriso/test.esp32.yaml | 12 ++++++++ tests/components/kmeteriso/test.esp8266.yaml | 12 ++++++++ tests/components/kmeteriso/test.rp2040.yaml | 12 ++++++++ .../components/kuntze/test.esp32-c3-idf.yaml | 15 ++++++++++ tests/components/kuntze/test.esp32-c3.yaml | 15 ++++++++++ tests/components/kuntze/test.esp32-idf.yaml | 15 ++++++++++ tests/components/kuntze/test.esp32.yaml | 15 ++++++++++ tests/components/kuntze/test.esp8266.yaml | 15 ++++++++++ tests/components/kuntze/test.rp2040.yaml | 15 ++++++++++ 18 files changed, 330 insertions(+) create mode 100644 tests/components/key_collector/test.esp32-c3-idf.yaml create mode 100644 tests/components/key_collector/test.esp32-c3.yaml create mode 100644 tests/components/key_collector/test.esp32-idf.yaml create mode 100644 tests/components/key_collector/test.esp32.yaml create mode 100644 tests/components/key_collector/test.esp8266.yaml create mode 100644 tests/components/key_collector/test.rp2040.yaml create mode 100644 tests/components/kmeteriso/test.esp32-c3-idf.yaml create mode 100644 tests/components/kmeteriso/test.esp32-c3.yaml create mode 100644 tests/components/kmeteriso/test.esp32-idf.yaml create mode 100644 tests/components/kmeteriso/test.esp32.yaml create mode 100644 tests/components/kmeteriso/test.esp8266.yaml create mode 100644 tests/components/kmeteriso/test.rp2040.yaml create mode 100644 tests/components/kuntze/test.esp32-c3-idf.yaml create mode 100644 tests/components/kuntze/test.esp32-c3.yaml create mode 100644 tests/components/kuntze/test.esp32-idf.yaml create mode 100644 tests/components/kuntze/test.esp32.yaml create mode 100644 tests/components/kuntze/test.esp8266.yaml create mode 100644 tests/components/kuntze/test.rp2040.yaml diff --git a/tests/components/key_collector/test.esp32-c3-idf.yaml b/tests/components/key_collector/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..a186d4fa23 --- /dev/null +++ b/tests/components/key_collector/test.esp32-c3-idf.yaml @@ -0,0 +1,28 @@ +matrix_keypad: + id: keypad + rows: + - pin: 1 + - pin: 2 + columns: + - pin: 3 + - pin: 4 + keys: "1234" + has_pulldowns: true + +key_collector: + - id: reader + source_id: keypad + min_length: 4 + max_length: 4 + on_progress: + - logger.log: + format: "input progress: '%s', started by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + on_result: + - logger.log: + format: "input result: '%s', started by '%c', ended by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ] + on_timeout: + - logger.log: + format: "input timeout: '%s', started by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] diff --git a/tests/components/key_collector/test.esp32-c3.yaml b/tests/components/key_collector/test.esp32-c3.yaml new file mode 100644 index 0000000000..a186d4fa23 --- /dev/null +++ b/tests/components/key_collector/test.esp32-c3.yaml @@ -0,0 +1,28 @@ +matrix_keypad: + id: keypad + rows: + - pin: 1 + - pin: 2 + columns: + - pin: 3 + - pin: 4 + keys: "1234" + has_pulldowns: true + +key_collector: + - id: reader + source_id: keypad + min_length: 4 + max_length: 4 + on_progress: + - logger.log: + format: "input progress: '%s', started by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + on_result: + - logger.log: + format: "input result: '%s', started by '%c', ended by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ] + on_timeout: + - logger.log: + format: "input timeout: '%s', started by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] diff --git a/tests/components/key_collector/test.esp32-idf.yaml b/tests/components/key_collector/test.esp32-idf.yaml new file mode 100644 index 0000000000..d357b33279 --- /dev/null +++ b/tests/components/key_collector/test.esp32-idf.yaml @@ -0,0 +1,28 @@ +matrix_keypad: + id: keypad + rows: + - pin: 12 + - pin: 13 + columns: + - pin: 14 + - pin: 15 + keys: "1234" + has_pulldowns: true + +key_collector: + - id: reader + source_id: keypad + min_length: 4 + max_length: 4 + on_progress: + - logger.log: + format: "input progress: '%s', started by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + on_result: + - logger.log: + format: "input result: '%s', started by '%c', ended by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ] + on_timeout: + - logger.log: + format: "input timeout: '%s', started by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] diff --git a/tests/components/key_collector/test.esp32.yaml b/tests/components/key_collector/test.esp32.yaml new file mode 100644 index 0000000000..d357b33279 --- /dev/null +++ b/tests/components/key_collector/test.esp32.yaml @@ -0,0 +1,28 @@ +matrix_keypad: + id: keypad + rows: + - pin: 12 + - pin: 13 + columns: + - pin: 14 + - pin: 15 + keys: "1234" + has_pulldowns: true + +key_collector: + - id: reader + source_id: keypad + min_length: 4 + max_length: 4 + on_progress: + - logger.log: + format: "input progress: '%s', started by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + on_result: + - logger.log: + format: "input result: '%s', started by '%c', ended by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ] + on_timeout: + - logger.log: + format: "input timeout: '%s', started by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] diff --git a/tests/components/key_collector/test.esp8266.yaml b/tests/components/key_collector/test.esp8266.yaml new file mode 100644 index 0000000000..d357b33279 --- /dev/null +++ b/tests/components/key_collector/test.esp8266.yaml @@ -0,0 +1,28 @@ +matrix_keypad: + id: keypad + rows: + - pin: 12 + - pin: 13 + columns: + - pin: 14 + - pin: 15 + keys: "1234" + has_pulldowns: true + +key_collector: + - id: reader + source_id: keypad + min_length: 4 + max_length: 4 + on_progress: + - logger.log: + format: "input progress: '%s', started by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + on_result: + - logger.log: + format: "input result: '%s', started by '%c', ended by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ] + on_timeout: + - logger.log: + format: "input timeout: '%s', started by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] diff --git a/tests/components/key_collector/test.rp2040.yaml b/tests/components/key_collector/test.rp2040.yaml new file mode 100644 index 0000000000..a186d4fa23 --- /dev/null +++ b/tests/components/key_collector/test.rp2040.yaml @@ -0,0 +1,28 @@ +matrix_keypad: + id: keypad + rows: + - pin: 1 + - pin: 2 + columns: + - pin: 3 + - pin: 4 + keys: "1234" + has_pulldowns: true + +key_collector: + - id: reader + source_id: keypad + min_length: 4 + max_length: 4 + on_progress: + - logger.log: + format: "input progress: '%s', started by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + on_result: + - logger.log: + format: "input result: '%s', started by '%c', ended by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ] + on_timeout: + - logger.log: + format: "input timeout: '%s', started by '%c'" + args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] diff --git a/tests/components/kmeteriso/test.esp32-c3-idf.yaml b/tests/components/kmeteriso/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..7780cfea32 --- /dev/null +++ b/tests/components/kmeteriso/test.esp32-c3-idf.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_kmeteriso + scl: 5 + sda: 4 + +sensor: + - platform: kmeteriso + temperature: + name: Outside Temperature + internal_temperature: + name: Internal Temperature + update_interval: 15s diff --git a/tests/components/kmeteriso/test.esp32-c3.yaml b/tests/components/kmeteriso/test.esp32-c3.yaml new file mode 100644 index 0000000000..7780cfea32 --- /dev/null +++ b/tests/components/kmeteriso/test.esp32-c3.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_kmeteriso + scl: 5 + sda: 4 + +sensor: + - platform: kmeteriso + temperature: + name: Outside Temperature + internal_temperature: + name: Internal Temperature + update_interval: 15s diff --git a/tests/components/kmeteriso/test.esp32-idf.yaml b/tests/components/kmeteriso/test.esp32-idf.yaml new file mode 100644 index 0000000000..2c375dda31 --- /dev/null +++ b/tests/components/kmeteriso/test.esp32-idf.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_kmeteriso + scl: 16 + sda: 17 + +sensor: + - platform: kmeteriso + temperature: + name: Outside Temperature + internal_temperature: + name: Internal Temperature + update_interval: 15s diff --git a/tests/components/kmeteriso/test.esp32.yaml b/tests/components/kmeteriso/test.esp32.yaml new file mode 100644 index 0000000000..2c375dda31 --- /dev/null +++ b/tests/components/kmeteriso/test.esp32.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_kmeteriso + scl: 16 + sda: 17 + +sensor: + - platform: kmeteriso + temperature: + name: Outside Temperature + internal_temperature: + name: Internal Temperature + update_interval: 15s diff --git a/tests/components/kmeteriso/test.esp8266.yaml b/tests/components/kmeteriso/test.esp8266.yaml new file mode 100644 index 0000000000..7780cfea32 --- /dev/null +++ b/tests/components/kmeteriso/test.esp8266.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_kmeteriso + scl: 5 + sda: 4 + +sensor: + - platform: kmeteriso + temperature: + name: Outside Temperature + internal_temperature: + name: Internal Temperature + update_interval: 15s diff --git a/tests/components/kmeteriso/test.rp2040.yaml b/tests/components/kmeteriso/test.rp2040.yaml new file mode 100644 index 0000000000..7780cfea32 --- /dev/null +++ b/tests/components/kmeteriso/test.rp2040.yaml @@ -0,0 +1,12 @@ +i2c: + - id: i2c_kmeteriso + scl: 5 + sda: 4 + +sensor: + - platform: kmeteriso + temperature: + name: Outside Temperature + internal_temperature: + name: Internal Temperature + update_interval: 15s diff --git a/tests/components/kuntze/test.esp32-c3-idf.yaml b/tests/components/kuntze/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..08278c3c82 --- /dev/null +++ b/tests/components/kuntze/test.esp32-c3-idf.yaml @@ -0,0 +1,15 @@ +uart: + - id: uart_kuntze + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +modbus: + flow_control_pin: 3 + +sensor: + - platform: kuntze + ph: + name: Kuntze pH + temperature: + name: Kuntze temperature diff --git a/tests/components/kuntze/test.esp32-c3.yaml b/tests/components/kuntze/test.esp32-c3.yaml new file mode 100644 index 0000000000..08278c3c82 --- /dev/null +++ b/tests/components/kuntze/test.esp32-c3.yaml @@ -0,0 +1,15 @@ +uart: + - id: uart_kuntze + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +modbus: + flow_control_pin: 3 + +sensor: + - platform: kuntze + ph: + name: Kuntze pH + temperature: + name: Kuntze temperature diff --git a/tests/components/kuntze/test.esp32-idf.yaml b/tests/components/kuntze/test.esp32-idf.yaml new file mode 100644 index 0000000000..6b6c638971 --- /dev/null +++ b/tests/components/kuntze/test.esp32-idf.yaml @@ -0,0 +1,15 @@ +uart: + - id: uart_kuntze + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + +modbus: + flow_control_pin: 13 + +sensor: + - platform: kuntze + ph: + name: Kuntze pH + temperature: + name: Kuntze temperature diff --git a/tests/components/kuntze/test.esp32.yaml b/tests/components/kuntze/test.esp32.yaml new file mode 100644 index 0000000000..6b6c638971 --- /dev/null +++ b/tests/components/kuntze/test.esp32.yaml @@ -0,0 +1,15 @@ +uart: + - id: uart_kuntze + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + +modbus: + flow_control_pin: 13 + +sensor: + - platform: kuntze + ph: + name: Kuntze pH + temperature: + name: Kuntze temperature diff --git a/tests/components/kuntze/test.esp8266.yaml b/tests/components/kuntze/test.esp8266.yaml new file mode 100644 index 0000000000..eba6cddc2d --- /dev/null +++ b/tests/components/kuntze/test.esp8266.yaml @@ -0,0 +1,15 @@ +uart: + - id: uart_kuntze + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +modbus: + flow_control_pin: 13 + +sensor: + - platform: kuntze + ph: + name: Kuntze pH + temperature: + name: Kuntze temperature diff --git a/tests/components/kuntze/test.rp2040.yaml b/tests/components/kuntze/test.rp2040.yaml new file mode 100644 index 0000000000..08278c3c82 --- /dev/null +++ b/tests/components/kuntze/test.rp2040.yaml @@ -0,0 +1,15 @@ +uart: + - id: uart_kuntze + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +modbus: + flow_control_pin: 3 + +sensor: + - platform: kuntze + ph: + name: Kuntze pH + temperature: + name: Kuntze temperature From 9779989f674a19e1475a31728accd5e10438d434 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Tue, 26 Mar 2024 20:24:32 -0500 Subject: [PATCH 163/189] Add some components to the new testing framework (N) (#6210) --- .../components/neopixelbus/test.esp32-c3.yaml | 19 ++++++ tests/components/neopixelbus/test.esp32.yaml | 17 ++++++ .../components/neopixelbus/test.esp8266.yaml | 17 ++++++ .../components/network/test.esp32-c3-idf.yaml | 6 ++ tests/components/network/test.esp32-c3.yaml | 6 ++ tests/components/network/test.esp32-idf.yaml | 6 ++ tests/components/network/test.esp32.yaml | 6 ++ tests/components/network/test.esp8266.yaml | 6 ++ tests/components/network/test.rp2040.yaml | 6 ++ .../components/nextion/test.esp32-c3-idf.yaml | 60 +++++++++++++++++++ tests/components/nextion/test.esp32-c3.yaml | 60 +++++++++++++++++++ tests/components/nextion/test.esp32-idf.yaml | 60 +++++++++++++++++++ tests/components/nextion/test.esp32.yaml | 60 +++++++++++++++++++ tests/components/nextion/test.esp8266.yaml | 60 +++++++++++++++++++ tests/components/nextion/test.rp2040.yaml | 55 +++++++++++++++++ .../components/noblex/test.esp32-c3-idf.yaml | 20 +++++++ tests/components/noblex/test.esp32-c3.yaml | 20 +++++++ tests/components/noblex/test.esp32-idf.yaml | 20 +++++++ tests/components/noblex/test.esp32.yaml | 20 +++++++ tests/components/noblex/test.esp8266.yaml | 20 +++++++ tests/components/ntc/test.esp32-c3.yaml | 26 ++++++++ tests/components/ntc/test.esp32-idf.yaml | 26 ++++++++ tests/components/ntc/test.esp32-s2.yaml | 26 ++++++++ tests/components/ntc/test.esp32-s3.yaml | 26 ++++++++ tests/components/ntc/test.esp32.yaml | 26 ++++++++ tests/components/ntc/test.esp8266.yaml | 25 ++++++++ tests/components/ntc/test.rp2040.yaml | 25 ++++++++ 27 files changed, 724 insertions(+) create mode 100644 tests/components/neopixelbus/test.esp32-c3.yaml create mode 100644 tests/components/neopixelbus/test.esp32.yaml create mode 100644 tests/components/neopixelbus/test.esp8266.yaml create mode 100644 tests/components/network/test.esp32-c3-idf.yaml create mode 100644 tests/components/network/test.esp32-c3.yaml create mode 100644 tests/components/network/test.esp32-idf.yaml create mode 100644 tests/components/network/test.esp32.yaml create mode 100644 tests/components/network/test.esp8266.yaml create mode 100644 tests/components/network/test.rp2040.yaml create mode 100644 tests/components/nextion/test.esp32-c3-idf.yaml create mode 100644 tests/components/nextion/test.esp32-c3.yaml create mode 100644 tests/components/nextion/test.esp32-idf.yaml create mode 100644 tests/components/nextion/test.esp32.yaml create mode 100644 tests/components/nextion/test.esp8266.yaml create mode 100644 tests/components/nextion/test.rp2040.yaml create mode 100644 tests/components/noblex/test.esp32-c3-idf.yaml create mode 100644 tests/components/noblex/test.esp32-c3.yaml create mode 100644 tests/components/noblex/test.esp32-idf.yaml create mode 100644 tests/components/noblex/test.esp32.yaml create mode 100644 tests/components/noblex/test.esp8266.yaml create mode 100644 tests/components/ntc/test.esp32-c3.yaml create mode 100644 tests/components/ntc/test.esp32-idf.yaml create mode 100644 tests/components/ntc/test.esp32-s2.yaml create mode 100644 tests/components/ntc/test.esp32-s3.yaml create mode 100644 tests/components/ntc/test.esp32.yaml create mode 100644 tests/components/ntc/test.esp8266.yaml create mode 100644 tests/components/ntc/test.rp2040.yaml diff --git a/tests/components/neopixelbus/test.esp32-c3.yaml b/tests/components/neopixelbus/test.esp32-c3.yaml new file mode 100644 index 0000000000..f2b53ab1e9 --- /dev/null +++ b/tests/components/neopixelbus/test.esp32-c3.yaml @@ -0,0 +1,19 @@ +light: + - platform: neopixelbus + id: addr3 + name: Neopixelbus Light + gamma_correct: 2.8 + color_correct: [0.0, 0.0, 0.0, 0.0] + default_transition_length: 10s + effects: + - addressable_flicker: + name: Flicker Effect With Custom Values + update_interval: 16ms + intensity: 5% + type: GRBW + variant: SK6812 + method: + type: esp32_rmt + channel: 0 + num_leds: 5 + pin: 4 diff --git a/tests/components/neopixelbus/test.esp32.yaml b/tests/components/neopixelbus/test.esp32.yaml new file mode 100644 index 0000000000..fd468586e0 --- /dev/null +++ b/tests/components/neopixelbus/test.esp32.yaml @@ -0,0 +1,17 @@ +light: + - platform: neopixelbus + id: addr3 + name: Neopixelbus Light + gamma_correct: 2.8 + color_correct: [0.0, 0.0, 0.0, 0.0] + default_transition_length: 10s + effects: + - addressable_flicker: + name: Flicker Effect With Custom Values + update_interval: 16ms + intensity: 5% + type: GRBW + variant: SK6812 + method: ESP32_I2S_0 + num_leds: 5 + pin: 4 diff --git a/tests/components/neopixelbus/test.esp8266.yaml b/tests/components/neopixelbus/test.esp8266.yaml new file mode 100644 index 0000000000..2c1f16a38c --- /dev/null +++ b/tests/components/neopixelbus/test.esp8266.yaml @@ -0,0 +1,17 @@ +light: + - platform: neopixelbus + id: addr3 + name: Neopixelbus Light + gamma_correct: 2.8 + color_correct: [0.0, 0.0, 0.0, 0.0] + default_transition_length: 10s + effects: + - addressable_flicker: + name: Flicker Effect With Custom Values + update_interval: 16ms + intensity: 5% + type: GRBW + variant: SK6812 + method: esp8266_uart + num_leds: 5 + pin: 2 diff --git a/tests/components/network/test.esp32-c3-idf.yaml b/tests/components/network/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..147afd1e81 --- /dev/null +++ b/tests/components/network/test.esp32-c3-idf.yaml @@ -0,0 +1,6 @@ +wifi: + ssid: MySSID + password: password1 + +network: + enable_ipv6: true diff --git a/tests/components/network/test.esp32-c3.yaml b/tests/components/network/test.esp32-c3.yaml new file mode 100644 index 0000000000..147afd1e81 --- /dev/null +++ b/tests/components/network/test.esp32-c3.yaml @@ -0,0 +1,6 @@ +wifi: + ssid: MySSID + password: password1 + +network: + enable_ipv6: true diff --git a/tests/components/network/test.esp32-idf.yaml b/tests/components/network/test.esp32-idf.yaml new file mode 100644 index 0000000000..147afd1e81 --- /dev/null +++ b/tests/components/network/test.esp32-idf.yaml @@ -0,0 +1,6 @@ +wifi: + ssid: MySSID + password: password1 + +network: + enable_ipv6: true diff --git a/tests/components/network/test.esp32.yaml b/tests/components/network/test.esp32.yaml new file mode 100644 index 0000000000..147afd1e81 --- /dev/null +++ b/tests/components/network/test.esp32.yaml @@ -0,0 +1,6 @@ +wifi: + ssid: MySSID + password: password1 + +network: + enable_ipv6: true diff --git a/tests/components/network/test.esp8266.yaml b/tests/components/network/test.esp8266.yaml new file mode 100644 index 0000000000..147afd1e81 --- /dev/null +++ b/tests/components/network/test.esp8266.yaml @@ -0,0 +1,6 @@ +wifi: + ssid: MySSID + password: password1 + +network: + enable_ipv6: true diff --git a/tests/components/network/test.rp2040.yaml b/tests/components/network/test.rp2040.yaml new file mode 100644 index 0000000000..147afd1e81 --- /dev/null +++ b/tests/components/network/test.rp2040.yaml @@ -0,0 +1,6 @@ +wifi: + ssid: MySSID + password: password1 + +network: + enable_ipv6: true diff --git a/tests/components/nextion/test.esp32-c3-idf.yaml b/tests/components/nextion/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..5881d6e165 --- /dev/null +++ b/tests/components/nextion/test.esp32-c3-idf.yaml @@ -0,0 +1,60 @@ +wifi: + ssid: MySSID + password: password1 + +uart: + - id: uart_nextion + tx_pin: 4 + rx_pin: 5 + baud_rate: 115200 + +binary_sensor: + - platform: nextion + page_id: 0 + component_id: 2 + name: Nextion Touch Component + - platform: nextion + id: r0_sensor + name: R0 Sensor + component_name: page0.r0 + +sensor: + - platform: nextion + id: testnumber + name: testnumber + variable_name: testnumber + - platform: nextion + id: testwave + name: testwave + component_id: 2 + wave_channel_id: 1 + +switch: + - platform: nextion + id: r0 + name: R0 Switch + component_name: page0.r0 + +text_sensor: + - platform: nextion + name: text0 + id: text0 + update_interval: 4s + component_name: text0 + +display: + - platform: nextion + tft_url: http://esphome.io/default35.tft + update_interval: 5s + on_sleep: + then: + lambda: 'ESP_LOGD("display","Display went to sleep");' + on_wake: + then: + lambda: 'ESP_LOGD("display","Display woke up");' + on_setup: + then: + lambda: 'ESP_LOGD("display","Display setup completed");' + on_page: + then: + lambda: 'ESP_LOGD("display","Display shows new page %u", x);' diff --git a/tests/components/nextion/test.esp32-c3.yaml b/tests/components/nextion/test.esp32-c3.yaml new file mode 100644 index 0000000000..5881d6e165 --- /dev/null +++ b/tests/components/nextion/test.esp32-c3.yaml @@ -0,0 +1,60 @@ +wifi: + ssid: MySSID + password: password1 + +uart: + - id: uart_nextion + tx_pin: 4 + rx_pin: 5 + baud_rate: 115200 + +binary_sensor: + - platform: nextion + page_id: 0 + component_id: 2 + name: Nextion Touch Component + - platform: nextion + id: r0_sensor + name: R0 Sensor + component_name: page0.r0 + +sensor: + - platform: nextion + id: testnumber + name: testnumber + variable_name: testnumber + - platform: nextion + id: testwave + name: testwave + component_id: 2 + wave_channel_id: 1 + +switch: + - platform: nextion + id: r0 + name: R0 Switch + component_name: page0.r0 + +text_sensor: + - platform: nextion + name: text0 + id: text0 + update_interval: 4s + component_name: text0 + +display: + - platform: nextion + tft_url: http://esphome.io/default35.tft + update_interval: 5s + on_sleep: + then: + lambda: 'ESP_LOGD("display","Display went to sleep");' + on_wake: + then: + lambda: 'ESP_LOGD("display","Display woke up");' + on_setup: + then: + lambda: 'ESP_LOGD("display","Display setup completed");' + on_page: + then: + lambda: 'ESP_LOGD("display","Display shows new page %u", x);' diff --git a/tests/components/nextion/test.esp32-idf.yaml b/tests/components/nextion/test.esp32-idf.yaml new file mode 100644 index 0000000000..27568ebc2a --- /dev/null +++ b/tests/components/nextion/test.esp32-idf.yaml @@ -0,0 +1,60 @@ +wifi: + ssid: MySSID + password: password1 + +uart: + - id: uart_nextion + tx_pin: 17 + rx_pin: 16 + baud_rate: 115200 + +binary_sensor: + - platform: nextion + page_id: 0 + component_id: 2 + name: Nextion Touch Component + - platform: nextion + id: r0_sensor + name: R0 Sensor + component_name: page0.r0 + +sensor: + - platform: nextion + id: testnumber + name: testnumber + variable_name: testnumber + - platform: nextion + id: testwave + name: testwave + component_id: 2 + wave_channel_id: 1 + +switch: + - platform: nextion + id: r0 + name: R0 Switch + component_name: page0.r0 + +text_sensor: + - platform: nextion + name: text0 + id: text0 + update_interval: 4s + component_name: text0 + +display: + - platform: nextion + tft_url: http://esphome.io/default35.tft + update_interval: 5s + on_sleep: + then: + lambda: 'ESP_LOGD("display","Display went to sleep");' + on_wake: + then: + lambda: 'ESP_LOGD("display","Display woke up");' + on_setup: + then: + lambda: 'ESP_LOGD("display","Display setup completed");' + on_page: + then: + lambda: 'ESP_LOGD("display","Display shows new page %u", x);' diff --git a/tests/components/nextion/test.esp32.yaml b/tests/components/nextion/test.esp32.yaml new file mode 100644 index 0000000000..27568ebc2a --- /dev/null +++ b/tests/components/nextion/test.esp32.yaml @@ -0,0 +1,60 @@ +wifi: + ssid: MySSID + password: password1 + +uart: + - id: uart_nextion + tx_pin: 17 + rx_pin: 16 + baud_rate: 115200 + +binary_sensor: + - platform: nextion + page_id: 0 + component_id: 2 + name: Nextion Touch Component + - platform: nextion + id: r0_sensor + name: R0 Sensor + component_name: page0.r0 + +sensor: + - platform: nextion + id: testnumber + name: testnumber + variable_name: testnumber + - platform: nextion + id: testwave + name: testwave + component_id: 2 + wave_channel_id: 1 + +switch: + - platform: nextion + id: r0 + name: R0 Switch + component_name: page0.r0 + +text_sensor: + - platform: nextion + name: text0 + id: text0 + update_interval: 4s + component_name: text0 + +display: + - platform: nextion + tft_url: http://esphome.io/default35.tft + update_interval: 5s + on_sleep: + then: + lambda: 'ESP_LOGD("display","Display went to sleep");' + on_wake: + then: + lambda: 'ESP_LOGD("display","Display woke up");' + on_setup: + then: + lambda: 'ESP_LOGD("display","Display setup completed");' + on_page: + then: + lambda: 'ESP_LOGD("display","Display shows new page %u", x);' diff --git a/tests/components/nextion/test.esp8266.yaml b/tests/components/nextion/test.esp8266.yaml new file mode 100644 index 0000000000..5881d6e165 --- /dev/null +++ b/tests/components/nextion/test.esp8266.yaml @@ -0,0 +1,60 @@ +wifi: + ssid: MySSID + password: password1 + +uart: + - id: uart_nextion + tx_pin: 4 + rx_pin: 5 + baud_rate: 115200 + +binary_sensor: + - platform: nextion + page_id: 0 + component_id: 2 + name: Nextion Touch Component + - platform: nextion + id: r0_sensor + name: R0 Sensor + component_name: page0.r0 + +sensor: + - platform: nextion + id: testnumber + name: testnumber + variable_name: testnumber + - platform: nextion + id: testwave + name: testwave + component_id: 2 + wave_channel_id: 1 + +switch: + - platform: nextion + id: r0 + name: R0 Switch + component_name: page0.r0 + +text_sensor: + - platform: nextion + name: text0 + id: text0 + update_interval: 4s + component_name: text0 + +display: + - platform: nextion + tft_url: http://esphome.io/default35.tft + update_interval: 5s + on_sleep: + then: + lambda: 'ESP_LOGD("display","Display went to sleep");' + on_wake: + then: + lambda: 'ESP_LOGD("display","Display woke up");' + on_setup: + then: + lambda: 'ESP_LOGD("display","Display setup completed");' + on_page: + then: + lambda: 'ESP_LOGD("display","Display shows new page %u", x);' diff --git a/tests/components/nextion/test.rp2040.yaml b/tests/components/nextion/test.rp2040.yaml new file mode 100644 index 0000000000..a1c5848ce6 --- /dev/null +++ b/tests/components/nextion/test.rp2040.yaml @@ -0,0 +1,55 @@ +uart: + - id: uart_nextion + tx_pin: 4 + rx_pin: 5 + baud_rate: 115200 + +binary_sensor: + - platform: nextion + page_id: 0 + component_id: 2 + name: Nextion Touch Component + - platform: nextion + id: r0_sensor + name: R0 Sensor + component_name: page0.r0 + +sensor: + - platform: nextion + id: testnumber + name: testnumber + variable_name: testnumber + - platform: nextion + id: testwave + name: testwave + component_id: 2 + wave_channel_id: 1 + +switch: + - platform: nextion + id: r0 + name: R0 Switch + component_name: page0.r0 + +text_sensor: + - platform: nextion + name: text0 + id: text0 + update_interval: 4s + component_name: text0 + +display: + - platform: nextion + update_interval: 5s + on_sleep: + then: + lambda: 'ESP_LOGD("display","Display went to sleep");' + on_wake: + then: + lambda: 'ESP_LOGD("display","Display woke up");' + on_setup: + then: + lambda: 'ESP_LOGD("display","Display setup completed");' + on_page: + then: + lambda: 'ESP_LOGD("display","Display shows new page %u", x);' diff --git a/tests/components/noblex/test.esp32-c3-idf.yaml b/tests/components/noblex/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..f5e471a9a7 --- /dev/null +++ b/tests/components/noblex/test.esp32-c3-idf.yaml @@ -0,0 +1,20 @@ +remote_receiver: + id: rcvr + pin: 4 + dump: all + +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +sensor: + - platform: template + id: noblex_ac_sensor + lambda: "return 21;" + +climate: + - platform: noblex + name: AC Living + id: noblex_ac + sensor: noblex_ac_sensor + receiver_id: rcvr diff --git a/tests/components/noblex/test.esp32-c3.yaml b/tests/components/noblex/test.esp32-c3.yaml new file mode 100644 index 0000000000..f5e471a9a7 --- /dev/null +++ b/tests/components/noblex/test.esp32-c3.yaml @@ -0,0 +1,20 @@ +remote_receiver: + id: rcvr + pin: 4 + dump: all + +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +sensor: + - platform: template + id: noblex_ac_sensor + lambda: "return 21;" + +climate: + - platform: noblex + name: AC Living + id: noblex_ac + sensor: noblex_ac_sensor + receiver_id: rcvr diff --git a/tests/components/noblex/test.esp32-idf.yaml b/tests/components/noblex/test.esp32-idf.yaml new file mode 100644 index 0000000000..f5e471a9a7 --- /dev/null +++ b/tests/components/noblex/test.esp32-idf.yaml @@ -0,0 +1,20 @@ +remote_receiver: + id: rcvr + pin: 4 + dump: all + +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +sensor: + - platform: template + id: noblex_ac_sensor + lambda: "return 21;" + +climate: + - platform: noblex + name: AC Living + id: noblex_ac + sensor: noblex_ac_sensor + receiver_id: rcvr diff --git a/tests/components/noblex/test.esp32.yaml b/tests/components/noblex/test.esp32.yaml new file mode 100644 index 0000000000..f5e471a9a7 --- /dev/null +++ b/tests/components/noblex/test.esp32.yaml @@ -0,0 +1,20 @@ +remote_receiver: + id: rcvr + pin: 4 + dump: all + +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +sensor: + - platform: template + id: noblex_ac_sensor + lambda: "return 21;" + +climate: + - platform: noblex + name: AC Living + id: noblex_ac + sensor: noblex_ac_sensor + receiver_id: rcvr diff --git a/tests/components/noblex/test.esp8266.yaml b/tests/components/noblex/test.esp8266.yaml new file mode 100644 index 0000000000..f5e471a9a7 --- /dev/null +++ b/tests/components/noblex/test.esp8266.yaml @@ -0,0 +1,20 @@ +remote_receiver: + id: rcvr + pin: 4 + dump: all + +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +sensor: + - platform: template + id: noblex_ac_sensor + lambda: "return 21;" + +climate: + - platform: noblex + name: AC Living + id: noblex_ac + sensor: noblex_ac_sensor + receiver_id: rcvr diff --git a/tests/components/ntc/test.esp32-c3.yaml b/tests/components/ntc/test.esp32-c3.yaml new file mode 100644 index 0000000000..c0edb83d9d --- /dev/null +++ b/tests/components/ntc/test.esp32-c3.yaml @@ -0,0 +1,26 @@ +sensor: + - platform: adc + id: my_sensor + pin: 4 + attenuation: 11db + - platform: resistance + sensor: my_sensor + configuration: DOWNSTREAM + resistor: 10kΩ + reference_voltage: 3.3V + name: Resistance + id: resist + - platform: ntc + sensor: resist + name: NTC Sensor + calibration: + b_constant: 3950 + reference_resistance: 10k + reference_temperature: 25°C + - platform: ntc + sensor: resist + name: NTC Sensor2 + calibration: + - 10.0kOhm -> 25°C + - 27.219kOhm -> 0°C + - 14.674kOhm -> 15°C diff --git a/tests/components/ntc/test.esp32-idf.yaml b/tests/components/ntc/test.esp32-idf.yaml new file mode 100644 index 0000000000..3e0e901b6e --- /dev/null +++ b/tests/components/ntc/test.esp32-idf.yaml @@ -0,0 +1,26 @@ +sensor: + - platform: adc + id: my_sensor + pin: 32 + attenuation: 11db + - platform: resistance + sensor: my_sensor + configuration: DOWNSTREAM + resistor: 10kΩ + reference_voltage: 3.3V + name: Resistance + id: resist + - platform: ntc + sensor: resist + name: NTC Sensor + calibration: + b_constant: 3950 + reference_resistance: 10k + reference_temperature: 25°C + - platform: ntc + sensor: resist + name: NTC Sensor2 + calibration: + - 10.0kOhm -> 25°C + - 27.219kOhm -> 0°C + - 14.674kOhm -> 15°C diff --git a/tests/components/ntc/test.esp32-s2.yaml b/tests/components/ntc/test.esp32-s2.yaml new file mode 100644 index 0000000000..c0edb83d9d --- /dev/null +++ b/tests/components/ntc/test.esp32-s2.yaml @@ -0,0 +1,26 @@ +sensor: + - platform: adc + id: my_sensor + pin: 4 + attenuation: 11db + - platform: resistance + sensor: my_sensor + configuration: DOWNSTREAM + resistor: 10kΩ + reference_voltage: 3.3V + name: Resistance + id: resist + - platform: ntc + sensor: resist + name: NTC Sensor + calibration: + b_constant: 3950 + reference_resistance: 10k + reference_temperature: 25°C + - platform: ntc + sensor: resist + name: NTC Sensor2 + calibration: + - 10.0kOhm -> 25°C + - 27.219kOhm -> 0°C + - 14.674kOhm -> 15°C diff --git a/tests/components/ntc/test.esp32-s3.yaml b/tests/components/ntc/test.esp32-s3.yaml new file mode 100644 index 0000000000..c0edb83d9d --- /dev/null +++ b/tests/components/ntc/test.esp32-s3.yaml @@ -0,0 +1,26 @@ +sensor: + - platform: adc + id: my_sensor + pin: 4 + attenuation: 11db + - platform: resistance + sensor: my_sensor + configuration: DOWNSTREAM + resistor: 10kΩ + reference_voltage: 3.3V + name: Resistance + id: resist + - platform: ntc + sensor: resist + name: NTC Sensor + calibration: + b_constant: 3950 + reference_resistance: 10k + reference_temperature: 25°C + - platform: ntc + sensor: resist + name: NTC Sensor2 + calibration: + - 10.0kOhm -> 25°C + - 27.219kOhm -> 0°C + - 14.674kOhm -> 15°C diff --git a/tests/components/ntc/test.esp32.yaml b/tests/components/ntc/test.esp32.yaml new file mode 100644 index 0000000000..3e0e901b6e --- /dev/null +++ b/tests/components/ntc/test.esp32.yaml @@ -0,0 +1,26 @@ +sensor: + - platform: adc + id: my_sensor + pin: 32 + attenuation: 11db + - platform: resistance + sensor: my_sensor + configuration: DOWNSTREAM + resistor: 10kΩ + reference_voltage: 3.3V + name: Resistance + id: resist + - platform: ntc + sensor: resist + name: NTC Sensor + calibration: + b_constant: 3950 + reference_resistance: 10k + reference_temperature: 25°C + - platform: ntc + sensor: resist + name: NTC Sensor2 + calibration: + - 10.0kOhm -> 25°C + - 27.219kOhm -> 0°C + - 14.674kOhm -> 15°C diff --git a/tests/components/ntc/test.esp8266.yaml b/tests/components/ntc/test.esp8266.yaml new file mode 100644 index 0000000000..370d16d3f7 --- /dev/null +++ b/tests/components/ntc/test.esp8266.yaml @@ -0,0 +1,25 @@ +sensor: + - platform: adc + id: my_sensor + pin: A0 + - platform: resistance + sensor: my_sensor + configuration: DOWNSTREAM + resistor: 10kΩ + reference_voltage: 3.3V + name: Resistance + id: resist + - platform: ntc + sensor: resist + name: NTC Sensor + calibration: + b_constant: 3950 + reference_resistance: 10k + reference_temperature: 25°C + - platform: ntc + sensor: resist + name: NTC Sensor2 + calibration: + - 10.0kOhm -> 25°C + - 27.219kOhm -> 0°C + - 14.674kOhm -> 15°C diff --git a/tests/components/ntc/test.rp2040.yaml b/tests/components/ntc/test.rp2040.yaml new file mode 100644 index 0000000000..9c7ba7b539 --- /dev/null +++ b/tests/components/ntc/test.rp2040.yaml @@ -0,0 +1,25 @@ +sensor: + - platform: adc + id: my_sensor + pin: 26 + - platform: resistance + sensor: my_sensor + configuration: DOWNSTREAM + resistor: 10kΩ + reference_voltage: 3.3V + name: Resistance + id: resist + - platform: ntc + sensor: resist + name: NTC Sensor + calibration: + b_constant: 3950 + reference_resistance: 10k + reference_temperature: 25°C + - platform: ntc + sensor: resist + name: NTC Sensor2 + calibration: + - 10.0kOhm -> 25°C + - 27.219kOhm -> 0°C + - 14.674kOhm -> 15°C From c36d7c0c3c758849ad3af52144aaccd6de6491ba Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Tue, 26 Mar 2024 20:25:02 -0500 Subject: [PATCH 164/189] Add some components to the new testing framework (Q) (#6218) --- .../qmc5883l/test.esp32-c3-idf.yaml | 19 +++++++++++++++++++ tests/components/qmc5883l/test.esp32-c3.yaml | 19 +++++++++++++++++++ tests/components/qmc5883l/test.esp32-idf.yaml | 19 +++++++++++++++++++ tests/components/qmc5883l/test.esp32.yaml | 19 +++++++++++++++++++ tests/components/qmc5883l/test.esp8266.yaml | 19 +++++++++++++++++++ tests/components/qmc5883l/test.rp2040.yaml | 19 +++++++++++++++++++ .../components/qmp6988/test.esp32-c3-idf.yaml | 16 ++++++++++++++++ tests/components/qmp6988/test.esp32-c3.yaml | 16 ++++++++++++++++ tests/components/qmp6988/test.esp32-idf.yaml | 16 ++++++++++++++++ tests/components/qmp6988/test.esp32.yaml | 16 ++++++++++++++++ tests/components/qmp6988/test.esp8266.yaml | 16 ++++++++++++++++ tests/components/qmp6988/test.rp2040.yaml | 16 ++++++++++++++++ .../components/qr_code/test.esp32-c3-idf.yaml | 17 +++++++++++++++++ tests/components/qr_code/test.esp32-c3.yaml | 17 +++++++++++++++++ tests/components/qr_code/test.esp32-idf.yaml | 17 +++++++++++++++++ tests/components/qr_code/test.esp32.yaml | 17 +++++++++++++++++ tests/components/qr_code/test.esp8266.yaml | 17 +++++++++++++++++ tests/components/qr_code/test.rp2040.yaml | 17 +++++++++++++++++ .../qwiic_pir/test.esp32-c3-idf.yaml | 8 ++++++++ tests/components/qwiic_pir/test.esp32-c3.yaml | 8 ++++++++ .../components/qwiic_pir/test.esp32-idf.yaml | 8 ++++++++ tests/components/qwiic_pir/test.esp32.yaml | 8 ++++++++ tests/components/qwiic_pir/test.esp8266.yaml | 8 ++++++++ tests/components/qwiic_pir/test.rp2040.yaml | 8 ++++++++ 24 files changed, 360 insertions(+) create mode 100644 tests/components/qmc5883l/test.esp32-c3-idf.yaml create mode 100644 tests/components/qmc5883l/test.esp32-c3.yaml create mode 100644 tests/components/qmc5883l/test.esp32-idf.yaml create mode 100644 tests/components/qmc5883l/test.esp32.yaml create mode 100644 tests/components/qmc5883l/test.esp8266.yaml create mode 100644 tests/components/qmc5883l/test.rp2040.yaml create mode 100644 tests/components/qmp6988/test.esp32-c3-idf.yaml create mode 100644 tests/components/qmp6988/test.esp32-c3.yaml create mode 100644 tests/components/qmp6988/test.esp32-idf.yaml create mode 100644 tests/components/qmp6988/test.esp32.yaml create mode 100644 tests/components/qmp6988/test.esp8266.yaml create mode 100644 tests/components/qmp6988/test.rp2040.yaml create mode 100644 tests/components/qr_code/test.esp32-c3-idf.yaml create mode 100644 tests/components/qr_code/test.esp32-c3.yaml create mode 100644 tests/components/qr_code/test.esp32-idf.yaml create mode 100644 tests/components/qr_code/test.esp32.yaml create mode 100644 tests/components/qr_code/test.esp8266.yaml create mode 100644 tests/components/qr_code/test.rp2040.yaml create mode 100644 tests/components/qwiic_pir/test.esp32-c3-idf.yaml create mode 100644 tests/components/qwiic_pir/test.esp32-c3.yaml create mode 100644 tests/components/qwiic_pir/test.esp32-idf.yaml create mode 100644 tests/components/qwiic_pir/test.esp32.yaml create mode 100644 tests/components/qwiic_pir/test.esp8266.yaml create mode 100644 tests/components/qwiic_pir/test.rp2040.yaml diff --git a/tests/components/qmc5883l/test.esp32-c3-idf.yaml b/tests/components/qmc5883l/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..c638f7e5be --- /dev/null +++ b/tests/components/qmc5883l/test.esp32-c3-idf.yaml @@ -0,0 +1,19 @@ +i2c: + - id: i2c_qmc5883l + scl: 5 + sda: 4 + +sensor: + - platform: qmc5883l + address: 0x0D + field_strength_x: + name: QMC5883L Field Strength X + field_strength_y: + name: QMC5883L Field Strength Y + field_strength_z: + name: QMC5883L Field Strength Z + heading: + name: QMC5883L Heading + range: 800uT + oversampling: 256x + update_interval: 15s diff --git a/tests/components/qmc5883l/test.esp32-c3.yaml b/tests/components/qmc5883l/test.esp32-c3.yaml new file mode 100644 index 0000000000..c638f7e5be --- /dev/null +++ b/tests/components/qmc5883l/test.esp32-c3.yaml @@ -0,0 +1,19 @@ +i2c: + - id: i2c_qmc5883l + scl: 5 + sda: 4 + +sensor: + - platform: qmc5883l + address: 0x0D + field_strength_x: + name: QMC5883L Field Strength X + field_strength_y: + name: QMC5883L Field Strength Y + field_strength_z: + name: QMC5883L Field Strength Z + heading: + name: QMC5883L Heading + range: 800uT + oversampling: 256x + update_interval: 15s diff --git a/tests/components/qmc5883l/test.esp32-idf.yaml b/tests/components/qmc5883l/test.esp32-idf.yaml new file mode 100644 index 0000000000..1aafa86cfa --- /dev/null +++ b/tests/components/qmc5883l/test.esp32-idf.yaml @@ -0,0 +1,19 @@ +i2c: + - id: i2c_qmc5883l + scl: 16 + sda: 17 + +sensor: + - platform: qmc5883l + address: 0x0D + field_strength_x: + name: QMC5883L Field Strength X + field_strength_y: + name: QMC5883L Field Strength Y + field_strength_z: + name: QMC5883L Field Strength Z + heading: + name: QMC5883L Heading + range: 800uT + oversampling: 256x + update_interval: 15s diff --git a/tests/components/qmc5883l/test.esp32.yaml b/tests/components/qmc5883l/test.esp32.yaml new file mode 100644 index 0000000000..1aafa86cfa --- /dev/null +++ b/tests/components/qmc5883l/test.esp32.yaml @@ -0,0 +1,19 @@ +i2c: + - id: i2c_qmc5883l + scl: 16 + sda: 17 + +sensor: + - platform: qmc5883l + address: 0x0D + field_strength_x: + name: QMC5883L Field Strength X + field_strength_y: + name: QMC5883L Field Strength Y + field_strength_z: + name: QMC5883L Field Strength Z + heading: + name: QMC5883L Heading + range: 800uT + oversampling: 256x + update_interval: 15s diff --git a/tests/components/qmc5883l/test.esp8266.yaml b/tests/components/qmc5883l/test.esp8266.yaml new file mode 100644 index 0000000000..c638f7e5be --- /dev/null +++ b/tests/components/qmc5883l/test.esp8266.yaml @@ -0,0 +1,19 @@ +i2c: + - id: i2c_qmc5883l + scl: 5 + sda: 4 + +sensor: + - platform: qmc5883l + address: 0x0D + field_strength_x: + name: QMC5883L Field Strength X + field_strength_y: + name: QMC5883L Field Strength Y + field_strength_z: + name: QMC5883L Field Strength Z + heading: + name: QMC5883L Heading + range: 800uT + oversampling: 256x + update_interval: 15s diff --git a/tests/components/qmc5883l/test.rp2040.yaml b/tests/components/qmc5883l/test.rp2040.yaml new file mode 100644 index 0000000000..c638f7e5be --- /dev/null +++ b/tests/components/qmc5883l/test.rp2040.yaml @@ -0,0 +1,19 @@ +i2c: + - id: i2c_qmc5883l + scl: 5 + sda: 4 + +sensor: + - platform: qmc5883l + address: 0x0D + field_strength_x: + name: QMC5883L Field Strength X + field_strength_y: + name: QMC5883L Field Strength Y + field_strength_z: + name: QMC5883L Field Strength Z + heading: + name: QMC5883L Heading + range: 800uT + oversampling: 256x + update_interval: 15s diff --git a/tests/components/qmp6988/test.esp32-c3-idf.yaml b/tests/components/qmp6988/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..bcd87ae6b8 --- /dev/null +++ b/tests/components/qmp6988/test.esp32-c3-idf.yaml @@ -0,0 +1,16 @@ +i2c: + - id: i2c_qmp6988 + scl: 5 + sda: 4 + +sensor: + - platform: qmp6988 + temperature: + name: QMP6988 Temperature + oversampling: 32x + pressure: + name: QMP6988 Pressure + oversampling: 2x + address: 0x70 + update_interval: 30s + iir_filter: 16x diff --git a/tests/components/qmp6988/test.esp32-c3.yaml b/tests/components/qmp6988/test.esp32-c3.yaml new file mode 100644 index 0000000000..bcd87ae6b8 --- /dev/null +++ b/tests/components/qmp6988/test.esp32-c3.yaml @@ -0,0 +1,16 @@ +i2c: + - id: i2c_qmp6988 + scl: 5 + sda: 4 + +sensor: + - platform: qmp6988 + temperature: + name: QMP6988 Temperature + oversampling: 32x + pressure: + name: QMP6988 Pressure + oversampling: 2x + address: 0x70 + update_interval: 30s + iir_filter: 16x diff --git a/tests/components/qmp6988/test.esp32-idf.yaml b/tests/components/qmp6988/test.esp32-idf.yaml new file mode 100644 index 0000000000..f3fbf75bbe --- /dev/null +++ b/tests/components/qmp6988/test.esp32-idf.yaml @@ -0,0 +1,16 @@ +i2c: + - id: i2c_qmp6988 + scl: 16 + sda: 17 + +sensor: + - platform: qmp6988 + temperature: + name: QMP6988 Temperature + oversampling: 32x + pressure: + name: QMP6988 Pressure + oversampling: 2x + address: 0x70 + update_interval: 30s + iir_filter: 16x diff --git a/tests/components/qmp6988/test.esp32.yaml b/tests/components/qmp6988/test.esp32.yaml new file mode 100644 index 0000000000..f3fbf75bbe --- /dev/null +++ b/tests/components/qmp6988/test.esp32.yaml @@ -0,0 +1,16 @@ +i2c: + - id: i2c_qmp6988 + scl: 16 + sda: 17 + +sensor: + - platform: qmp6988 + temperature: + name: QMP6988 Temperature + oversampling: 32x + pressure: + name: QMP6988 Pressure + oversampling: 2x + address: 0x70 + update_interval: 30s + iir_filter: 16x diff --git a/tests/components/qmp6988/test.esp8266.yaml b/tests/components/qmp6988/test.esp8266.yaml new file mode 100644 index 0000000000..bcd87ae6b8 --- /dev/null +++ b/tests/components/qmp6988/test.esp8266.yaml @@ -0,0 +1,16 @@ +i2c: + - id: i2c_qmp6988 + scl: 5 + sda: 4 + +sensor: + - platform: qmp6988 + temperature: + name: QMP6988 Temperature + oversampling: 32x + pressure: + name: QMP6988 Pressure + oversampling: 2x + address: 0x70 + update_interval: 30s + iir_filter: 16x diff --git a/tests/components/qmp6988/test.rp2040.yaml b/tests/components/qmp6988/test.rp2040.yaml new file mode 100644 index 0000000000..bcd87ae6b8 --- /dev/null +++ b/tests/components/qmp6988/test.rp2040.yaml @@ -0,0 +1,16 @@ +i2c: + - id: i2c_qmp6988 + scl: 5 + sda: 4 + +sensor: + - platform: qmp6988 + temperature: + name: QMP6988 Temperature + oversampling: 32x + pressure: + name: QMP6988 Pressure + oversampling: 2x + address: 0x70 + update_interval: 30s + iir_filter: 16x diff --git a/tests/components/qr_code/test.esp32-c3-idf.yaml b/tests/components/qr_code/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..3e875c026c --- /dev/null +++ b/tests/components/qr_code/test.esp32-c3-idf.yaml @@ -0,0 +1,17 @@ +spi: + - id: spi_main_lcd + clk_pin: 6 + mosi_pin: 7 + miso_pin: 5 + +display: + - platform: ili9xxx + id: main_lcd + model: ili9342 + cs_pin: 8 + dc_pin: 9 + reset_pin: 10 + +qr_code: + - id: homepage_qr + value: https://esphome.io/index.html diff --git a/tests/components/qr_code/test.esp32-c3.yaml b/tests/components/qr_code/test.esp32-c3.yaml new file mode 100644 index 0000000000..3e875c026c --- /dev/null +++ b/tests/components/qr_code/test.esp32-c3.yaml @@ -0,0 +1,17 @@ +spi: + - id: spi_main_lcd + clk_pin: 6 + mosi_pin: 7 + miso_pin: 5 + +display: + - platform: ili9xxx + id: main_lcd + model: ili9342 + cs_pin: 8 + dc_pin: 9 + reset_pin: 10 + +qr_code: + - id: homepage_qr + value: https://esphome.io/index.html diff --git a/tests/components/qr_code/test.esp32-idf.yaml b/tests/components/qr_code/test.esp32-idf.yaml new file mode 100644 index 0000000000..b354a3f512 --- /dev/null +++ b/tests/components/qr_code/test.esp32-idf.yaml @@ -0,0 +1,17 @@ +spi: + - id: spi_main_lcd + clk_pin: 16 + mosi_pin: 17 + miso_pin: 15 + +display: + - platform: ili9xxx + id: main_lcd + model: ili9342 + cs_pin: 12 + dc_pin: 13 + reset_pin: 21 + +qr_code: + - id: homepage_qr + value: https://esphome.io/index.html diff --git a/tests/components/qr_code/test.esp32.yaml b/tests/components/qr_code/test.esp32.yaml new file mode 100644 index 0000000000..b354a3f512 --- /dev/null +++ b/tests/components/qr_code/test.esp32.yaml @@ -0,0 +1,17 @@ +spi: + - id: spi_main_lcd + clk_pin: 16 + mosi_pin: 17 + miso_pin: 15 + +display: + - platform: ili9xxx + id: main_lcd + model: ili9342 + cs_pin: 12 + dc_pin: 13 + reset_pin: 21 + +qr_code: + - id: homepage_qr + value: https://esphome.io/index.html diff --git a/tests/components/qr_code/test.esp8266.yaml b/tests/components/qr_code/test.esp8266.yaml new file mode 100644 index 0000000000..dd0d75c472 --- /dev/null +++ b/tests/components/qr_code/test.esp8266.yaml @@ -0,0 +1,17 @@ +spi: + - id: spi_main_lcd + clk_pin: 14 + mosi_pin: 13 + miso_pin: 12 + +display: + - platform: ili9xxx + id: main_lcd + model: ili9342 + cs_pin: 5 + dc_pin: 15 + reset_pin: 16 + +qr_code: + - id: homepage_qr + value: https://esphome.io/index.html diff --git a/tests/components/qr_code/test.rp2040.yaml b/tests/components/qr_code/test.rp2040.yaml new file mode 100644 index 0000000000..b0e046d275 --- /dev/null +++ b/tests/components/qr_code/test.rp2040.yaml @@ -0,0 +1,17 @@ +spi: + - id: spi_main_lcd + clk_pin: 2 + mosi_pin: 3 + miso_pin: 4 + +display: + - platform: ili9xxx + id: main_lcd + model: ili9342 + cs_pin: 20 + dc_pin: 21 + reset_pin: 22 + +qr_code: + - id: homepage_qr + value: https://esphome.io/index.html diff --git a/tests/components/qwiic_pir/test.esp32-c3-idf.yaml b/tests/components/qwiic_pir/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..ad52ac91c5 --- /dev/null +++ b/tests/components/qwiic_pir/test.esp32-c3-idf.yaml @@ -0,0 +1,8 @@ +i2c: + - id: i2c_qwiic_pir + scl: 5 + sda: 4 + +binary_sensor: + - platform: qwiic_pir + name: Qwiic PIR Motion Sensor diff --git a/tests/components/qwiic_pir/test.esp32-c3.yaml b/tests/components/qwiic_pir/test.esp32-c3.yaml new file mode 100644 index 0000000000..ad52ac91c5 --- /dev/null +++ b/tests/components/qwiic_pir/test.esp32-c3.yaml @@ -0,0 +1,8 @@ +i2c: + - id: i2c_qwiic_pir + scl: 5 + sda: 4 + +binary_sensor: + - platform: qwiic_pir + name: Qwiic PIR Motion Sensor diff --git a/tests/components/qwiic_pir/test.esp32-idf.yaml b/tests/components/qwiic_pir/test.esp32-idf.yaml new file mode 100644 index 0000000000..da2e275cf3 --- /dev/null +++ b/tests/components/qwiic_pir/test.esp32-idf.yaml @@ -0,0 +1,8 @@ +i2c: + - id: i2c_qwiic_pir + scl: 16 + sda: 17 + +binary_sensor: + - platform: qwiic_pir + name: Qwiic PIR Motion Sensor diff --git a/tests/components/qwiic_pir/test.esp32.yaml b/tests/components/qwiic_pir/test.esp32.yaml new file mode 100644 index 0000000000..da2e275cf3 --- /dev/null +++ b/tests/components/qwiic_pir/test.esp32.yaml @@ -0,0 +1,8 @@ +i2c: + - id: i2c_qwiic_pir + scl: 16 + sda: 17 + +binary_sensor: + - platform: qwiic_pir + name: Qwiic PIR Motion Sensor diff --git a/tests/components/qwiic_pir/test.esp8266.yaml b/tests/components/qwiic_pir/test.esp8266.yaml new file mode 100644 index 0000000000..ad52ac91c5 --- /dev/null +++ b/tests/components/qwiic_pir/test.esp8266.yaml @@ -0,0 +1,8 @@ +i2c: + - id: i2c_qwiic_pir + scl: 5 + sda: 4 + +binary_sensor: + - platform: qwiic_pir + name: Qwiic PIR Motion Sensor diff --git a/tests/components/qwiic_pir/test.rp2040.yaml b/tests/components/qwiic_pir/test.rp2040.yaml new file mode 100644 index 0000000000..ad52ac91c5 --- /dev/null +++ b/tests/components/qwiic_pir/test.rp2040.yaml @@ -0,0 +1,8 @@ +i2c: + - id: i2c_qwiic_pir + scl: 5 + sda: 4 + +binary_sensor: + - platform: qwiic_pir + name: Qwiic PIR Motion Sensor From dc071bed24bd5ee29f386c2eddd70c972a61fdf5 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Tue, 26 Mar 2024 20:26:50 -0500 Subject: [PATCH 165/189] Add some components to the new testing framework (U) (#6230) --- tests/components/uart/test.esp32-c3-idf.yaml | 15 ++++++++++ tests/components/uart/test.esp32-c3.yaml | 15 ++++++++++ tests/components/uart/test.esp32-idf.yaml | 15 ++++++++++ tests/components/uart/test.esp32.yaml | 15 ++++++++++ tests/components/uart/test.esp8266.yaml | 15 ++++++++++ tests/components/uart/test.rp2040.yaml | 15 ++++++++++ .../ufire_ec/test.esp32-c3-idf.yaml | 25 ++++++++++++++++ tests/components/ufire_ec/test.esp32-c3.yaml | 25 ++++++++++++++++ tests/components/ufire_ec/test.esp32-idf.yaml | 25 ++++++++++++++++ tests/components/ufire_ec/test.esp32.yaml | 25 ++++++++++++++++ tests/components/ufire_ec/test.esp8266.yaml | 25 ++++++++++++++++ tests/components/ufire_ec/test.rp2040.yaml | 25 ++++++++++++++++ .../ufire_ise/test.esp32-c3-idf.yaml | 25 ++++++++++++++++ tests/components/ufire_ise/test.esp32-c3.yaml | 25 ++++++++++++++++ .../components/ufire_ise/test.esp32-idf.yaml | 25 ++++++++++++++++ tests/components/ufire_ise/test.esp32.yaml | 25 ++++++++++++++++ tests/components/ufire_ise/test.esp8266.yaml | 25 ++++++++++++++++ tests/components/ufire_ise/test.rp2040.yaml | 25 ++++++++++++++++ .../components/uln2003/test.esp32-c3-idf.yaml | 29 +++++++++++++++++++ tests/components/uln2003/test.esp32-c3.yaml | 29 +++++++++++++++++++ tests/components/uln2003/test.esp32-idf.yaml | 29 +++++++++++++++++++ tests/components/uln2003/test.esp32.yaml | 29 +++++++++++++++++++ tests/components/uln2003/test.esp8266.yaml | 29 +++++++++++++++++++ tests/components/uln2003/test.rp2040.yaml | 29 +++++++++++++++++++ .../ultrasonic/test.esp32-c3-idf.yaml | 7 +++++ .../components/ultrasonic/test.esp32-c3.yaml | 7 +++++ .../components/ultrasonic/test.esp32-idf.yaml | 7 +++++ tests/components/ultrasonic/test.esp32.yaml | 7 +++++ tests/components/ultrasonic/test.esp8266.yaml | 7 +++++ tests/components/ultrasonic/test.rp2040.yaml | 7 +++++ .../components/uptime/test.esp32-c3-idf.yaml | 3 ++ tests/components/uptime/test.esp32-c3.yaml | 3 ++ tests/components/uptime/test.esp32-idf.yaml | 3 ++ tests/components/uptime/test.esp32.yaml | 3 ++ tests/components/uptime/test.esp8266.yaml | 3 ++ tests/components/uptime/test.rp2040.yaml | 3 ++ 36 files changed, 624 insertions(+) create mode 100644 tests/components/uart/test.esp32-c3-idf.yaml create mode 100644 tests/components/uart/test.esp32-c3.yaml create mode 100644 tests/components/uart/test.esp32-idf.yaml create mode 100644 tests/components/uart/test.esp32.yaml create mode 100644 tests/components/uart/test.esp8266.yaml create mode 100644 tests/components/uart/test.rp2040.yaml create mode 100644 tests/components/ufire_ec/test.esp32-c3-idf.yaml create mode 100644 tests/components/ufire_ec/test.esp32-c3.yaml create mode 100644 tests/components/ufire_ec/test.esp32-idf.yaml create mode 100644 tests/components/ufire_ec/test.esp32.yaml create mode 100644 tests/components/ufire_ec/test.esp8266.yaml create mode 100644 tests/components/ufire_ec/test.rp2040.yaml create mode 100644 tests/components/ufire_ise/test.esp32-c3-idf.yaml create mode 100644 tests/components/ufire_ise/test.esp32-c3.yaml create mode 100644 tests/components/ufire_ise/test.esp32-idf.yaml create mode 100644 tests/components/ufire_ise/test.esp32.yaml create mode 100644 tests/components/ufire_ise/test.esp8266.yaml create mode 100644 tests/components/ufire_ise/test.rp2040.yaml create mode 100644 tests/components/uln2003/test.esp32-c3-idf.yaml create mode 100644 tests/components/uln2003/test.esp32-c3.yaml create mode 100644 tests/components/uln2003/test.esp32-idf.yaml create mode 100644 tests/components/uln2003/test.esp32.yaml create mode 100644 tests/components/uln2003/test.esp8266.yaml create mode 100644 tests/components/uln2003/test.rp2040.yaml create mode 100644 tests/components/ultrasonic/test.esp32-c3-idf.yaml create mode 100644 tests/components/ultrasonic/test.esp32-c3.yaml create mode 100644 tests/components/ultrasonic/test.esp32-idf.yaml create mode 100644 tests/components/ultrasonic/test.esp32.yaml create mode 100644 tests/components/ultrasonic/test.esp8266.yaml create mode 100644 tests/components/ultrasonic/test.rp2040.yaml create mode 100644 tests/components/uptime/test.esp32-c3-idf.yaml create mode 100644 tests/components/uptime/test.esp32-c3.yaml create mode 100644 tests/components/uptime/test.esp32-idf.yaml create mode 100644 tests/components/uptime/test.esp32.yaml create mode 100644 tests/components/uptime/test.esp8266.yaml create mode 100644 tests/components/uptime/test.rp2040.yaml diff --git a/tests/components/uart/test.esp32-c3-idf.yaml b/tests/components/uart/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..09178f1663 --- /dev/null +++ b/tests/components/uart/test.esp32-c3-idf.yaml @@ -0,0 +1,15 @@ +esphome: + on_boot: + then: + - uart.write: 'Hello World' + - uart.write: [0x00, 0x20, 0x42] + +uart: + - id: uart_uart + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + data_bits: 8 + rx_buffer_size: 512 + parity: EVEN + stop_bits: 2 diff --git a/tests/components/uart/test.esp32-c3.yaml b/tests/components/uart/test.esp32-c3.yaml new file mode 100644 index 0000000000..09178f1663 --- /dev/null +++ b/tests/components/uart/test.esp32-c3.yaml @@ -0,0 +1,15 @@ +esphome: + on_boot: + then: + - uart.write: 'Hello World' + - uart.write: [0x00, 0x20, 0x42] + +uart: + - id: uart_uart + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + data_bits: 8 + rx_buffer_size: 512 + parity: EVEN + stop_bits: 2 diff --git a/tests/components/uart/test.esp32-idf.yaml b/tests/components/uart/test.esp32-idf.yaml new file mode 100644 index 0000000000..bef5b460ab --- /dev/null +++ b/tests/components/uart/test.esp32-idf.yaml @@ -0,0 +1,15 @@ +esphome: + on_boot: + then: + - uart.write: 'Hello World' + - uart.write: [0x00, 0x20, 0x42] + +uart: + - id: uart_uart + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + data_bits: 8 + rx_buffer_size: 512 + parity: EVEN + stop_bits: 2 diff --git a/tests/components/uart/test.esp32.yaml b/tests/components/uart/test.esp32.yaml new file mode 100644 index 0000000000..bef5b460ab --- /dev/null +++ b/tests/components/uart/test.esp32.yaml @@ -0,0 +1,15 @@ +esphome: + on_boot: + then: + - uart.write: 'Hello World' + - uart.write: [0x00, 0x20, 0x42] + +uart: + - id: uart_uart + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + data_bits: 8 + rx_buffer_size: 512 + parity: EVEN + stop_bits: 2 diff --git a/tests/components/uart/test.esp8266.yaml b/tests/components/uart/test.esp8266.yaml new file mode 100644 index 0000000000..09178f1663 --- /dev/null +++ b/tests/components/uart/test.esp8266.yaml @@ -0,0 +1,15 @@ +esphome: + on_boot: + then: + - uart.write: 'Hello World' + - uart.write: [0x00, 0x20, 0x42] + +uart: + - id: uart_uart + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + data_bits: 8 + rx_buffer_size: 512 + parity: EVEN + stop_bits: 2 diff --git a/tests/components/uart/test.rp2040.yaml b/tests/components/uart/test.rp2040.yaml new file mode 100644 index 0000000000..09178f1663 --- /dev/null +++ b/tests/components/uart/test.rp2040.yaml @@ -0,0 +1,15 @@ +esphome: + on_boot: + then: + - uart.write: 'Hello World' + - uart.write: [0x00, 0x20, 0x42] + +uart: + - id: uart_uart + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + data_bits: 8 + rx_buffer_size: 512 + parity: EVEN + stop_bits: 2 diff --git a/tests/components/ufire_ec/test.esp32-c3-idf.yaml b/tests/components/ufire_ec/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..aa72c992b8 --- /dev/null +++ b/tests/components/ufire_ec/test.esp32-c3-idf.yaml @@ -0,0 +1,25 @@ +esphome: + on_boot: + then: + - ufire_ec.calibrate_probe: + id: ufire_ec_board + solution: 0.146 + temperature: !lambda "return id(test_sensor).state;" + - ufire_ec.reset: + +i2c: + - id: i2c_ufire_ec + scl: 5 + sda: 4 + +sensor: + - platform: template + id: test_sensor + lambda: "return 21;" + - platform: ufire_ec + id: ufire_ec_board + ec: + name: Ufire EC + temperature_sensor: test_sensor + temperature_compensation: 20.0 + temperature_coefficient: 0.019 diff --git a/tests/components/ufire_ec/test.esp32-c3.yaml b/tests/components/ufire_ec/test.esp32-c3.yaml new file mode 100644 index 0000000000..aa72c992b8 --- /dev/null +++ b/tests/components/ufire_ec/test.esp32-c3.yaml @@ -0,0 +1,25 @@ +esphome: + on_boot: + then: + - ufire_ec.calibrate_probe: + id: ufire_ec_board + solution: 0.146 + temperature: !lambda "return id(test_sensor).state;" + - ufire_ec.reset: + +i2c: + - id: i2c_ufire_ec + scl: 5 + sda: 4 + +sensor: + - platform: template + id: test_sensor + lambda: "return 21;" + - platform: ufire_ec + id: ufire_ec_board + ec: + name: Ufire EC + temperature_sensor: test_sensor + temperature_compensation: 20.0 + temperature_coefficient: 0.019 diff --git a/tests/components/ufire_ec/test.esp32-idf.yaml b/tests/components/ufire_ec/test.esp32-idf.yaml new file mode 100644 index 0000000000..5e6a0daa9e --- /dev/null +++ b/tests/components/ufire_ec/test.esp32-idf.yaml @@ -0,0 +1,25 @@ +esphome: + on_boot: + then: + - ufire_ec.calibrate_probe: + id: ufire_ec_board + solution: 0.146 + temperature: !lambda "return id(test_sensor).state;" + - ufire_ec.reset: + +i2c: + - id: i2c_ufire_ec + scl: 16 + sda: 17 + +sensor: + - platform: template + id: test_sensor + lambda: "return 21;" + - platform: ufire_ec + id: ufire_ec_board + ec: + name: Ufire EC + temperature_sensor: test_sensor + temperature_compensation: 20.0 + temperature_coefficient: 0.019 diff --git a/tests/components/ufire_ec/test.esp32.yaml b/tests/components/ufire_ec/test.esp32.yaml new file mode 100644 index 0000000000..5e6a0daa9e --- /dev/null +++ b/tests/components/ufire_ec/test.esp32.yaml @@ -0,0 +1,25 @@ +esphome: + on_boot: + then: + - ufire_ec.calibrate_probe: + id: ufire_ec_board + solution: 0.146 + temperature: !lambda "return id(test_sensor).state;" + - ufire_ec.reset: + +i2c: + - id: i2c_ufire_ec + scl: 16 + sda: 17 + +sensor: + - platform: template + id: test_sensor + lambda: "return 21;" + - platform: ufire_ec + id: ufire_ec_board + ec: + name: Ufire EC + temperature_sensor: test_sensor + temperature_compensation: 20.0 + temperature_coefficient: 0.019 diff --git a/tests/components/ufire_ec/test.esp8266.yaml b/tests/components/ufire_ec/test.esp8266.yaml new file mode 100644 index 0000000000..aa72c992b8 --- /dev/null +++ b/tests/components/ufire_ec/test.esp8266.yaml @@ -0,0 +1,25 @@ +esphome: + on_boot: + then: + - ufire_ec.calibrate_probe: + id: ufire_ec_board + solution: 0.146 + temperature: !lambda "return id(test_sensor).state;" + - ufire_ec.reset: + +i2c: + - id: i2c_ufire_ec + scl: 5 + sda: 4 + +sensor: + - platform: template + id: test_sensor + lambda: "return 21;" + - platform: ufire_ec + id: ufire_ec_board + ec: + name: Ufire EC + temperature_sensor: test_sensor + temperature_compensation: 20.0 + temperature_coefficient: 0.019 diff --git a/tests/components/ufire_ec/test.rp2040.yaml b/tests/components/ufire_ec/test.rp2040.yaml new file mode 100644 index 0000000000..aa72c992b8 --- /dev/null +++ b/tests/components/ufire_ec/test.rp2040.yaml @@ -0,0 +1,25 @@ +esphome: + on_boot: + then: + - ufire_ec.calibrate_probe: + id: ufire_ec_board + solution: 0.146 + temperature: !lambda "return id(test_sensor).state;" + - ufire_ec.reset: + +i2c: + - id: i2c_ufire_ec + scl: 5 + sda: 4 + +sensor: + - platform: template + id: test_sensor + lambda: "return 21;" + - platform: ufire_ec + id: ufire_ec_board + ec: + name: Ufire EC + temperature_sensor: test_sensor + temperature_compensation: 20.0 + temperature_coefficient: 0.019 diff --git a/tests/components/ufire_ise/test.esp32-c3-idf.yaml b/tests/components/ufire_ise/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..36aec73113 --- /dev/null +++ b/tests/components/ufire_ise/test.esp32-c3-idf.yaml @@ -0,0 +1,25 @@ +esphome: + on_boot: + then: + - ufire_ise.calibrate_probe_high: + id: ufire_ise_sensor + solution: 7.0 + - ufire_ise.calibrate_probe_low: + id: ufire_ise_sensor + solution: 4.0 + - ufire_ise.reset: + +i2c: + - id: i2c_ufire_ise + scl: 5 + sda: 4 + +sensor: + - platform: template + id: test_sensor + lambda: "return 21;" + - platform: ufire_ise + id: ufire_ise_sensor + temperature_sensor: test_sensor + ph: + name: Ufire pH diff --git a/tests/components/ufire_ise/test.esp32-c3.yaml b/tests/components/ufire_ise/test.esp32-c3.yaml new file mode 100644 index 0000000000..36aec73113 --- /dev/null +++ b/tests/components/ufire_ise/test.esp32-c3.yaml @@ -0,0 +1,25 @@ +esphome: + on_boot: + then: + - ufire_ise.calibrate_probe_high: + id: ufire_ise_sensor + solution: 7.0 + - ufire_ise.calibrate_probe_low: + id: ufire_ise_sensor + solution: 4.0 + - ufire_ise.reset: + +i2c: + - id: i2c_ufire_ise + scl: 5 + sda: 4 + +sensor: + - platform: template + id: test_sensor + lambda: "return 21;" + - platform: ufire_ise + id: ufire_ise_sensor + temperature_sensor: test_sensor + ph: + name: Ufire pH diff --git a/tests/components/ufire_ise/test.esp32-idf.yaml b/tests/components/ufire_ise/test.esp32-idf.yaml new file mode 100644 index 0000000000..9ed0ac433a --- /dev/null +++ b/tests/components/ufire_ise/test.esp32-idf.yaml @@ -0,0 +1,25 @@ +esphome: + on_boot: + then: + - ufire_ise.calibrate_probe_high: + id: ufire_ise_sensor + solution: 7.0 + - ufire_ise.calibrate_probe_low: + id: ufire_ise_sensor + solution: 4.0 + - ufire_ise.reset: + +i2c: + - id: i2c_ufire_ise + scl: 16 + sda: 17 + +sensor: + - platform: template + id: test_sensor + lambda: "return 21;" + - platform: ufire_ise + id: ufire_ise_sensor + temperature_sensor: test_sensor + ph: + name: Ufire pH diff --git a/tests/components/ufire_ise/test.esp32.yaml b/tests/components/ufire_ise/test.esp32.yaml new file mode 100644 index 0000000000..9ed0ac433a --- /dev/null +++ b/tests/components/ufire_ise/test.esp32.yaml @@ -0,0 +1,25 @@ +esphome: + on_boot: + then: + - ufire_ise.calibrate_probe_high: + id: ufire_ise_sensor + solution: 7.0 + - ufire_ise.calibrate_probe_low: + id: ufire_ise_sensor + solution: 4.0 + - ufire_ise.reset: + +i2c: + - id: i2c_ufire_ise + scl: 16 + sda: 17 + +sensor: + - platform: template + id: test_sensor + lambda: "return 21;" + - platform: ufire_ise + id: ufire_ise_sensor + temperature_sensor: test_sensor + ph: + name: Ufire pH diff --git a/tests/components/ufire_ise/test.esp8266.yaml b/tests/components/ufire_ise/test.esp8266.yaml new file mode 100644 index 0000000000..36aec73113 --- /dev/null +++ b/tests/components/ufire_ise/test.esp8266.yaml @@ -0,0 +1,25 @@ +esphome: + on_boot: + then: + - ufire_ise.calibrate_probe_high: + id: ufire_ise_sensor + solution: 7.0 + - ufire_ise.calibrate_probe_low: + id: ufire_ise_sensor + solution: 4.0 + - ufire_ise.reset: + +i2c: + - id: i2c_ufire_ise + scl: 5 + sda: 4 + +sensor: + - platform: template + id: test_sensor + lambda: "return 21;" + - platform: ufire_ise + id: ufire_ise_sensor + temperature_sensor: test_sensor + ph: + name: Ufire pH diff --git a/tests/components/ufire_ise/test.rp2040.yaml b/tests/components/ufire_ise/test.rp2040.yaml new file mode 100644 index 0000000000..36aec73113 --- /dev/null +++ b/tests/components/ufire_ise/test.rp2040.yaml @@ -0,0 +1,25 @@ +esphome: + on_boot: + then: + - ufire_ise.calibrate_probe_high: + id: ufire_ise_sensor + solution: 7.0 + - ufire_ise.calibrate_probe_low: + id: ufire_ise_sensor + solution: 4.0 + - ufire_ise.reset: + +i2c: + - id: i2c_ufire_ise + scl: 5 + sda: 4 + +sensor: + - platform: template + id: test_sensor + lambda: "return 21;" + - platform: ufire_ise + id: ufire_ise_sensor + temperature_sensor: test_sensor + ph: + name: Ufire pH diff --git a/tests/components/uln2003/test.esp32-c3-idf.yaml b/tests/components/uln2003/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..2d19d4dba3 --- /dev/null +++ b/tests/components/uln2003/test.esp32-c3-idf.yaml @@ -0,0 +1,29 @@ +esphome: + on_boot: + then: + - stepper.report_position: + id: uln2003_stepper + position: 250 + - stepper.set_target: + id: uln2003_stepper + target: 250 + - stepper.set_acceleration: + id: uln2003_stepper + acceleration: 250 steps/s^2 + - stepper.set_deceleration: + id: uln2003_stepper + deceleration: 250 steps/s^2 + - stepper.set_speed: + id: uln2003_stepper + speed: 250 steps/s + +stepper: + - platform: uln2003 + id: uln2003_stepper + pin_a: 0 + pin_b: 1 + pin_c: 2 + pin_d: 3 + max_speed: 250 steps/s + acceleration: 100 steps/s^2 + deceleration: 200 steps/s^2 diff --git a/tests/components/uln2003/test.esp32-c3.yaml b/tests/components/uln2003/test.esp32-c3.yaml new file mode 100644 index 0000000000..2d19d4dba3 --- /dev/null +++ b/tests/components/uln2003/test.esp32-c3.yaml @@ -0,0 +1,29 @@ +esphome: + on_boot: + then: + - stepper.report_position: + id: uln2003_stepper + position: 250 + - stepper.set_target: + id: uln2003_stepper + target: 250 + - stepper.set_acceleration: + id: uln2003_stepper + acceleration: 250 steps/s^2 + - stepper.set_deceleration: + id: uln2003_stepper + deceleration: 250 steps/s^2 + - stepper.set_speed: + id: uln2003_stepper + speed: 250 steps/s + +stepper: + - platform: uln2003 + id: uln2003_stepper + pin_a: 0 + pin_b: 1 + pin_c: 2 + pin_d: 3 + max_speed: 250 steps/s + acceleration: 100 steps/s^2 + deceleration: 200 steps/s^2 diff --git a/tests/components/uln2003/test.esp32-idf.yaml b/tests/components/uln2003/test.esp32-idf.yaml new file mode 100644 index 0000000000..61a6e94396 --- /dev/null +++ b/tests/components/uln2003/test.esp32-idf.yaml @@ -0,0 +1,29 @@ +esphome: + on_boot: + then: + - stepper.report_position: + id: uln2003_stepper + position: 250 + - stepper.set_target: + id: uln2003_stepper + target: 250 + - stepper.set_acceleration: + id: uln2003_stepper + acceleration: 250 steps/s^2 + - stepper.set_deceleration: + id: uln2003_stepper + deceleration: 250 steps/s^2 + - stepper.set_speed: + id: uln2003_stepper + speed: 250 steps/s + +stepper: + - platform: uln2003 + id: uln2003_stepper + pin_a: 12 + pin_b: 13 + pin_c: 14 + pin_d: 15 + max_speed: 250 steps/s + acceleration: 100 steps/s^2 + deceleration: 200 steps/s^2 diff --git a/tests/components/uln2003/test.esp32.yaml b/tests/components/uln2003/test.esp32.yaml new file mode 100644 index 0000000000..61a6e94396 --- /dev/null +++ b/tests/components/uln2003/test.esp32.yaml @@ -0,0 +1,29 @@ +esphome: + on_boot: + then: + - stepper.report_position: + id: uln2003_stepper + position: 250 + - stepper.set_target: + id: uln2003_stepper + target: 250 + - stepper.set_acceleration: + id: uln2003_stepper + acceleration: 250 steps/s^2 + - stepper.set_deceleration: + id: uln2003_stepper + deceleration: 250 steps/s^2 + - stepper.set_speed: + id: uln2003_stepper + speed: 250 steps/s + +stepper: + - platform: uln2003 + id: uln2003_stepper + pin_a: 12 + pin_b: 13 + pin_c: 14 + pin_d: 15 + max_speed: 250 steps/s + acceleration: 100 steps/s^2 + deceleration: 200 steps/s^2 diff --git a/tests/components/uln2003/test.esp8266.yaml b/tests/components/uln2003/test.esp8266.yaml new file mode 100644 index 0000000000..61a6e94396 --- /dev/null +++ b/tests/components/uln2003/test.esp8266.yaml @@ -0,0 +1,29 @@ +esphome: + on_boot: + then: + - stepper.report_position: + id: uln2003_stepper + position: 250 + - stepper.set_target: + id: uln2003_stepper + target: 250 + - stepper.set_acceleration: + id: uln2003_stepper + acceleration: 250 steps/s^2 + - stepper.set_deceleration: + id: uln2003_stepper + deceleration: 250 steps/s^2 + - stepper.set_speed: + id: uln2003_stepper + speed: 250 steps/s + +stepper: + - platform: uln2003 + id: uln2003_stepper + pin_a: 12 + pin_b: 13 + pin_c: 14 + pin_d: 15 + max_speed: 250 steps/s + acceleration: 100 steps/s^2 + deceleration: 200 steps/s^2 diff --git a/tests/components/uln2003/test.rp2040.yaml b/tests/components/uln2003/test.rp2040.yaml new file mode 100644 index 0000000000..2d19d4dba3 --- /dev/null +++ b/tests/components/uln2003/test.rp2040.yaml @@ -0,0 +1,29 @@ +esphome: + on_boot: + then: + - stepper.report_position: + id: uln2003_stepper + position: 250 + - stepper.set_target: + id: uln2003_stepper + target: 250 + - stepper.set_acceleration: + id: uln2003_stepper + acceleration: 250 steps/s^2 + - stepper.set_deceleration: + id: uln2003_stepper + deceleration: 250 steps/s^2 + - stepper.set_speed: + id: uln2003_stepper + speed: 250 steps/s + +stepper: + - platform: uln2003 + id: uln2003_stepper + pin_a: 0 + pin_b: 1 + pin_c: 2 + pin_d: 3 + max_speed: 250 steps/s + acceleration: 100 steps/s^2 + deceleration: 200 steps/s^2 diff --git a/tests/components/ultrasonic/test.esp32-c3-idf.yaml b/tests/components/ultrasonic/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..f1f673d918 --- /dev/null +++ b/tests/components/ultrasonic/test.esp32-c3-idf.yaml @@ -0,0 +1,7 @@ +sensor: + - platform: ultrasonic + id: ultrasonic_sensor1 + name: Ultrasonic Sensor + echo_pin: 4 + trigger_pin: 5 + timeout: 5.5m diff --git a/tests/components/ultrasonic/test.esp32-c3.yaml b/tests/components/ultrasonic/test.esp32-c3.yaml new file mode 100644 index 0000000000..f1f673d918 --- /dev/null +++ b/tests/components/ultrasonic/test.esp32-c3.yaml @@ -0,0 +1,7 @@ +sensor: + - platform: ultrasonic + id: ultrasonic_sensor1 + name: Ultrasonic Sensor + echo_pin: 4 + trigger_pin: 5 + timeout: 5.5m diff --git a/tests/components/ultrasonic/test.esp32-idf.yaml b/tests/components/ultrasonic/test.esp32-idf.yaml new file mode 100644 index 0000000000..f1f673d918 --- /dev/null +++ b/tests/components/ultrasonic/test.esp32-idf.yaml @@ -0,0 +1,7 @@ +sensor: + - platform: ultrasonic + id: ultrasonic_sensor1 + name: Ultrasonic Sensor + echo_pin: 4 + trigger_pin: 5 + timeout: 5.5m diff --git a/tests/components/ultrasonic/test.esp32.yaml b/tests/components/ultrasonic/test.esp32.yaml new file mode 100644 index 0000000000..f1f673d918 --- /dev/null +++ b/tests/components/ultrasonic/test.esp32.yaml @@ -0,0 +1,7 @@ +sensor: + - platform: ultrasonic + id: ultrasonic_sensor1 + name: Ultrasonic Sensor + echo_pin: 4 + trigger_pin: 5 + timeout: 5.5m diff --git a/tests/components/ultrasonic/test.esp8266.yaml b/tests/components/ultrasonic/test.esp8266.yaml new file mode 100644 index 0000000000..f1f673d918 --- /dev/null +++ b/tests/components/ultrasonic/test.esp8266.yaml @@ -0,0 +1,7 @@ +sensor: + - platform: ultrasonic + id: ultrasonic_sensor1 + name: Ultrasonic Sensor + echo_pin: 4 + trigger_pin: 5 + timeout: 5.5m diff --git a/tests/components/ultrasonic/test.rp2040.yaml b/tests/components/ultrasonic/test.rp2040.yaml new file mode 100644 index 0000000000..f1f673d918 --- /dev/null +++ b/tests/components/ultrasonic/test.rp2040.yaml @@ -0,0 +1,7 @@ +sensor: + - platform: ultrasonic + id: ultrasonic_sensor1 + name: Ultrasonic Sensor + echo_pin: 4 + trigger_pin: 5 + timeout: 5.5m diff --git a/tests/components/uptime/test.esp32-c3-idf.yaml b/tests/components/uptime/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..872a0e7402 --- /dev/null +++ b/tests/components/uptime/test.esp32-c3-idf.yaml @@ -0,0 +1,3 @@ +sensor: + - platform: uptime + name: Uptime Sensor diff --git a/tests/components/uptime/test.esp32-c3.yaml b/tests/components/uptime/test.esp32-c3.yaml new file mode 100644 index 0000000000..872a0e7402 --- /dev/null +++ b/tests/components/uptime/test.esp32-c3.yaml @@ -0,0 +1,3 @@ +sensor: + - platform: uptime + name: Uptime Sensor diff --git a/tests/components/uptime/test.esp32-idf.yaml b/tests/components/uptime/test.esp32-idf.yaml new file mode 100644 index 0000000000..872a0e7402 --- /dev/null +++ b/tests/components/uptime/test.esp32-idf.yaml @@ -0,0 +1,3 @@ +sensor: + - platform: uptime + name: Uptime Sensor diff --git a/tests/components/uptime/test.esp32.yaml b/tests/components/uptime/test.esp32.yaml new file mode 100644 index 0000000000..872a0e7402 --- /dev/null +++ b/tests/components/uptime/test.esp32.yaml @@ -0,0 +1,3 @@ +sensor: + - platform: uptime + name: Uptime Sensor diff --git a/tests/components/uptime/test.esp8266.yaml b/tests/components/uptime/test.esp8266.yaml new file mode 100644 index 0000000000..872a0e7402 --- /dev/null +++ b/tests/components/uptime/test.esp8266.yaml @@ -0,0 +1,3 @@ +sensor: + - platform: uptime + name: Uptime Sensor diff --git a/tests/components/uptime/test.rp2040.yaml b/tests/components/uptime/test.rp2040.yaml new file mode 100644 index 0000000000..872a0e7402 --- /dev/null +++ b/tests/components/uptime/test.rp2040.yaml @@ -0,0 +1,3 @@ +sensor: + - platform: uptime + name: Uptime Sensor From 54a68bf069fc11d582f7c50b143b6f428f385e3f Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Wed, 27 Mar 2024 02:15:50 -0500 Subject: [PATCH 166/189] Fix spacing in new test yaml (#6441) --- .../growatt_solar/test.esp32-c3-idf.yaml | 30 +++++++++---------- .../growatt_solar/test.esp32-c3.yaml | 30 +++++++++---------- .../growatt_solar/test.esp32-idf.yaml | 30 +++++++++---------- .../components/growatt_solar/test.esp32.yaml | 30 +++++++++---------- .../growatt_solar/test.esp8266.yaml | 30 +++++++++---------- .../components/growatt_solar/test.rp2040.yaml | 30 +++++++++---------- .../key_collector/test.esp32-c3-idf.yaml | 6 ++-- .../key_collector/test.esp32-c3.yaml | 6 ++-- .../key_collector/test.esp32-idf.yaml | 6 ++-- .../components/key_collector/test.esp32.yaml | 6 ++-- .../key_collector/test.esp8266.yaml | 6 ++-- .../components/key_collector/test.rp2040.yaml | 6 ++-- 12 files changed, 108 insertions(+), 108 deletions(-) diff --git a/tests/components/growatt_solar/test.esp32-c3-idf.yaml b/tests/components/growatt_solar/test.esp32-c3-idf.yaml index 3b5e2e4ce4..7e73897856 100644 --- a/tests/components/growatt_solar/test.esp32-c3-idf.yaml +++ b/tests/components/growatt_solar/test.esp32-c3-idf.yaml @@ -15,39 +15,39 @@ sensor: name: Growatt Status Code phase_a: voltage: - name: Growatt Voltage Phase A + name: Growatt Voltage Phase A current: - name: Growatt Current Phase A + name: Growatt Current Phase A active_power: - name: Growatt Power Phase A + name: Growatt Power Phase A phase_b: voltage: - name: Growatt Voltage Phase B + name: Growatt Voltage Phase B current: - name: Growatt Current Phase B + name: Growatt Current Phase B active_power: - name: Growatt Power Phase B + name: Growatt Power Phase B phase_c: voltage: - name: Growatt Voltage Phase C + name: Growatt Voltage Phase C current: - name: Growatt Current Phase C + name: Growatt Current Phase C active_power: - name: Growatt Power Phase C + name: Growatt Power Phase C pv1: voltage: - name: Growatt PV1 Voltage + name: Growatt PV1 Voltage current: - name: Growatt PV1 Current + name: Growatt PV1 Current active_power: - name: Growatt PV1 Active Power + name: Growatt PV1 Active Power pv2: voltage: - name: Growatt PV2 Voltage + name: Growatt PV2 Voltage current: - name: Growatt PV2 Current + name: Growatt PV2 Current active_power: - name: Growatt PV2 Active Power + name: Growatt PV2 Active Power active_power: name: Growatt Grid Active Power pv_active_power: diff --git a/tests/components/growatt_solar/test.esp32-c3.yaml b/tests/components/growatt_solar/test.esp32-c3.yaml index 3b5e2e4ce4..7e73897856 100644 --- a/tests/components/growatt_solar/test.esp32-c3.yaml +++ b/tests/components/growatt_solar/test.esp32-c3.yaml @@ -15,39 +15,39 @@ sensor: name: Growatt Status Code phase_a: voltage: - name: Growatt Voltage Phase A + name: Growatt Voltage Phase A current: - name: Growatt Current Phase A + name: Growatt Current Phase A active_power: - name: Growatt Power Phase A + name: Growatt Power Phase A phase_b: voltage: - name: Growatt Voltage Phase B + name: Growatt Voltage Phase B current: - name: Growatt Current Phase B + name: Growatt Current Phase B active_power: - name: Growatt Power Phase B + name: Growatt Power Phase B phase_c: voltage: - name: Growatt Voltage Phase C + name: Growatt Voltage Phase C current: - name: Growatt Current Phase C + name: Growatt Current Phase C active_power: - name: Growatt Power Phase C + name: Growatt Power Phase C pv1: voltage: - name: Growatt PV1 Voltage + name: Growatt PV1 Voltage current: - name: Growatt PV1 Current + name: Growatt PV1 Current active_power: - name: Growatt PV1 Active Power + name: Growatt PV1 Active Power pv2: voltage: - name: Growatt PV2 Voltage + name: Growatt PV2 Voltage current: - name: Growatt PV2 Current + name: Growatt PV2 Current active_power: - name: Growatt PV2 Active Power + name: Growatt PV2 Active Power active_power: name: Growatt Grid Active Power pv_active_power: diff --git a/tests/components/growatt_solar/test.esp32-idf.yaml b/tests/components/growatt_solar/test.esp32-idf.yaml index a0670fdbd6..654f2ccedf 100644 --- a/tests/components/growatt_solar/test.esp32-idf.yaml +++ b/tests/components/growatt_solar/test.esp32-idf.yaml @@ -15,39 +15,39 @@ sensor: name: Growatt Status Code phase_a: voltage: - name: Growatt Voltage Phase A + name: Growatt Voltage Phase A current: - name: Growatt Current Phase A + name: Growatt Current Phase A active_power: - name: Growatt Power Phase A + name: Growatt Power Phase A phase_b: voltage: - name: Growatt Voltage Phase B + name: Growatt Voltage Phase B current: - name: Growatt Current Phase B + name: Growatt Current Phase B active_power: - name: Growatt Power Phase B + name: Growatt Power Phase B phase_c: voltage: - name: Growatt Voltage Phase C + name: Growatt Voltage Phase C current: - name: Growatt Current Phase C + name: Growatt Current Phase C active_power: - name: Growatt Power Phase C + name: Growatt Power Phase C pv1: voltage: - name: Growatt PV1 Voltage + name: Growatt PV1 Voltage current: - name: Growatt PV1 Current + name: Growatt PV1 Current active_power: - name: Growatt PV1 Active Power + name: Growatt PV1 Active Power pv2: voltage: - name: Growatt PV2 Voltage + name: Growatt PV2 Voltage current: - name: Growatt PV2 Current + name: Growatt PV2 Current active_power: - name: Growatt PV2 Active Power + name: Growatt PV2 Active Power active_power: name: Growatt Grid Active Power pv_active_power: diff --git a/tests/components/growatt_solar/test.esp32.yaml b/tests/components/growatt_solar/test.esp32.yaml index a0670fdbd6..654f2ccedf 100644 --- a/tests/components/growatt_solar/test.esp32.yaml +++ b/tests/components/growatt_solar/test.esp32.yaml @@ -15,39 +15,39 @@ sensor: name: Growatt Status Code phase_a: voltage: - name: Growatt Voltage Phase A + name: Growatt Voltage Phase A current: - name: Growatt Current Phase A + name: Growatt Current Phase A active_power: - name: Growatt Power Phase A + name: Growatt Power Phase A phase_b: voltage: - name: Growatt Voltage Phase B + name: Growatt Voltage Phase B current: - name: Growatt Current Phase B + name: Growatt Current Phase B active_power: - name: Growatt Power Phase B + name: Growatt Power Phase B phase_c: voltage: - name: Growatt Voltage Phase C + name: Growatt Voltage Phase C current: - name: Growatt Current Phase C + name: Growatt Current Phase C active_power: - name: Growatt Power Phase C + name: Growatt Power Phase C pv1: voltage: - name: Growatt PV1 Voltage + name: Growatt PV1 Voltage current: - name: Growatt PV1 Current + name: Growatt PV1 Current active_power: - name: Growatt PV1 Active Power + name: Growatt PV1 Active Power pv2: voltage: - name: Growatt PV2 Voltage + name: Growatt PV2 Voltage current: - name: Growatt PV2 Current + name: Growatt PV2 Current active_power: - name: Growatt PV2 Active Power + name: Growatt PV2 Active Power active_power: name: Growatt Grid Active Power pv_active_power: diff --git a/tests/components/growatt_solar/test.esp8266.yaml b/tests/components/growatt_solar/test.esp8266.yaml index fed27ffda1..a1cf8267ae 100644 --- a/tests/components/growatt_solar/test.esp8266.yaml +++ b/tests/components/growatt_solar/test.esp8266.yaml @@ -15,39 +15,39 @@ sensor: name: Growatt Status Code phase_a: voltage: - name: Growatt Voltage Phase A + name: Growatt Voltage Phase A current: - name: Growatt Current Phase A + name: Growatt Current Phase A active_power: - name: Growatt Power Phase A + name: Growatt Power Phase A phase_b: voltage: - name: Growatt Voltage Phase B + name: Growatt Voltage Phase B current: - name: Growatt Current Phase B + name: Growatt Current Phase B active_power: - name: Growatt Power Phase B + name: Growatt Power Phase B phase_c: voltage: - name: Growatt Voltage Phase C + name: Growatt Voltage Phase C current: - name: Growatt Current Phase C + name: Growatt Current Phase C active_power: - name: Growatt Power Phase C + name: Growatt Power Phase C pv1: voltage: - name: Growatt PV1 Voltage + name: Growatt PV1 Voltage current: - name: Growatt PV1 Current + name: Growatt PV1 Current active_power: - name: Growatt PV1 Active Power + name: Growatt PV1 Active Power pv2: voltage: - name: Growatt PV2 Voltage + name: Growatt PV2 Voltage current: - name: Growatt PV2 Current + name: Growatt PV2 Current active_power: - name: Growatt PV2 Active Power + name: Growatt PV2 Active Power active_power: name: Growatt Grid Active Power pv_active_power: diff --git a/tests/components/growatt_solar/test.rp2040.yaml b/tests/components/growatt_solar/test.rp2040.yaml index 3b5e2e4ce4..7e73897856 100644 --- a/tests/components/growatt_solar/test.rp2040.yaml +++ b/tests/components/growatt_solar/test.rp2040.yaml @@ -15,39 +15,39 @@ sensor: name: Growatt Status Code phase_a: voltage: - name: Growatt Voltage Phase A + name: Growatt Voltage Phase A current: - name: Growatt Current Phase A + name: Growatt Current Phase A active_power: - name: Growatt Power Phase A + name: Growatt Power Phase A phase_b: voltage: - name: Growatt Voltage Phase B + name: Growatt Voltage Phase B current: - name: Growatt Current Phase B + name: Growatt Current Phase B active_power: - name: Growatt Power Phase B + name: Growatt Power Phase B phase_c: voltage: - name: Growatt Voltage Phase C + name: Growatt Voltage Phase C current: - name: Growatt Current Phase C + name: Growatt Current Phase C active_power: - name: Growatt Power Phase C + name: Growatt Power Phase C pv1: voltage: - name: Growatt PV1 Voltage + name: Growatt PV1 Voltage current: - name: Growatt PV1 Current + name: Growatt PV1 Current active_power: - name: Growatt PV1 Active Power + name: Growatt PV1 Active Power pv2: voltage: - name: Growatt PV2 Voltage + name: Growatt PV2 Voltage current: - name: Growatt PV2 Current + name: Growatt PV2 Current active_power: - name: Growatt PV2 Active Power + name: Growatt PV2 Active Power active_power: name: Growatt Grid Active Power pv_active_power: diff --git a/tests/components/key_collector/test.esp32-c3-idf.yaml b/tests/components/key_collector/test.esp32-c3-idf.yaml index a186d4fa23..1f133c5cd8 100644 --- a/tests/components/key_collector/test.esp32-c3-idf.yaml +++ b/tests/components/key_collector/test.esp32-c3-idf.yaml @@ -17,12 +17,12 @@ key_collector: on_progress: - logger.log: format: "input progress: '%s', started by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)"] on_result: - logger.log: format: "input result: '%s', started by '%c', ended by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)"] on_timeout: - logger.log: format: "input timeout: '%s', started by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)"] diff --git a/tests/components/key_collector/test.esp32-c3.yaml b/tests/components/key_collector/test.esp32-c3.yaml index a186d4fa23..1f133c5cd8 100644 --- a/tests/components/key_collector/test.esp32-c3.yaml +++ b/tests/components/key_collector/test.esp32-c3.yaml @@ -17,12 +17,12 @@ key_collector: on_progress: - logger.log: format: "input progress: '%s', started by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)"] on_result: - logger.log: format: "input result: '%s', started by '%c', ended by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)"] on_timeout: - logger.log: format: "input timeout: '%s', started by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)"] diff --git a/tests/components/key_collector/test.esp32-idf.yaml b/tests/components/key_collector/test.esp32-idf.yaml index d357b33279..7cbe9c0fc1 100644 --- a/tests/components/key_collector/test.esp32-idf.yaml +++ b/tests/components/key_collector/test.esp32-idf.yaml @@ -17,12 +17,12 @@ key_collector: on_progress: - logger.log: format: "input progress: '%s', started by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)"] on_result: - logger.log: format: "input result: '%s', started by '%c', ended by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)"] on_timeout: - logger.log: format: "input timeout: '%s', started by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)"] diff --git a/tests/components/key_collector/test.esp32.yaml b/tests/components/key_collector/test.esp32.yaml index d357b33279..7cbe9c0fc1 100644 --- a/tests/components/key_collector/test.esp32.yaml +++ b/tests/components/key_collector/test.esp32.yaml @@ -17,12 +17,12 @@ key_collector: on_progress: - logger.log: format: "input progress: '%s', started by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)"] on_result: - logger.log: format: "input result: '%s', started by '%c', ended by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)"] on_timeout: - logger.log: format: "input timeout: '%s', started by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)"] diff --git a/tests/components/key_collector/test.esp8266.yaml b/tests/components/key_collector/test.esp8266.yaml index d357b33279..7cbe9c0fc1 100644 --- a/tests/components/key_collector/test.esp8266.yaml +++ b/tests/components/key_collector/test.esp8266.yaml @@ -17,12 +17,12 @@ key_collector: on_progress: - logger.log: format: "input progress: '%s', started by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)"] on_result: - logger.log: format: "input result: '%s', started by '%c', ended by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)"] on_timeout: - logger.log: format: "input timeout: '%s', started by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)"] diff --git a/tests/components/key_collector/test.rp2040.yaml b/tests/components/key_collector/test.rp2040.yaml index a186d4fa23..1f133c5cd8 100644 --- a/tests/components/key_collector/test.rp2040.yaml +++ b/tests/components/key_collector/test.rp2040.yaml @@ -17,12 +17,12 @@ key_collector: on_progress: - logger.log: format: "input progress: '%s', started by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)"] on_result: - logger.log: format: "input result: '%s', started by '%c', ended by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)", "(end == 0 ? '~' : end)"] on_timeout: - logger.log: format: "input timeout: '%s', started by '%c'" - args: [ 'x.c_str()', "(start == 0 ? '~' : start)" ] + args: ['x.c_str()', "(start == 0 ? '~' : start)"] From 0630cdded376eeefd3a628cfa19d70b1f2e764c7 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Wed, 27 Mar 2024 02:15:59 -0500 Subject: [PATCH 167/189] Add some components to the new testing framework (W) (#6232) Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --- .../components/wake_on_lan/test.esp32-c3.yaml | 9 ++ tests/components/wake_on_lan/test.esp32.yaml | 9 ++ .../components/wake_on_lan/test.esp8266.yaml | 9 ++ tests/components/wake_on_lan/test.rp2040.yaml | 9 ++ .../waveshare_epaper/test.esp32-c3-idf.yaml | 107 ++++++++++++++++++ .../waveshare_epaper/test.esp32-c3.yaml | 107 ++++++++++++++++++ .../waveshare_epaper/test.esp32-idf.yaml | 107 ++++++++++++++++++ .../waveshare_epaper/test.esp8266.yaml | 107 ++++++++++++++++++ .../waveshare_epaper/test.rp2040.yaml | 107 ++++++++++++++++++ .../web_server/test.esp32-c3-idf.yaml | 7 ++ .../components/web_server/test.esp32-c3.yaml | 7 ++ .../components/web_server/test.esp32-idf.yaml | 7 ++ tests/components/web_server/test.esp32.yaml | 7 ++ tests/components/web_server/test.esp8266.yaml | 7 ++ .../whirlpool/test.esp32-c3-idf.yaml | 7 ++ tests/components/whirlpool/test.esp32-c3.yaml | 7 ++ .../components/whirlpool/test.esp32-idf.yaml | 7 ++ tests/components/whirlpool/test.esp32.yaml | 7 ++ tests/components/whirlpool/test.esp8266.yaml | 7 ++ .../components/whynter/test.esp32-c3-idf.yaml | 7 ++ tests/components/whynter/test.esp32-c3.yaml | 7 ++ tests/components/whynter/test.esp32-idf.yaml | 7 ++ tests/components/whynter/test.esp32.yaml | 7 ++ tests/components/whynter/test.esp8266.yaml | 7 ++ .../components/wiegand/test.esp32-c3-idf.yaml | 10 ++ tests/components/wiegand/test.esp32-c3.yaml | 10 ++ tests/components/wiegand/test.esp32-idf.yaml | 10 ++ tests/components/wiegand/test.esp32.yaml | 10 ++ tests/components/wiegand/test.esp8266.yaml | 10 ++ tests/components/wiegand/test.rp2040.yaml | 10 ++ tests/components/wifi/test.esp32-c3-idf.yaml | 9 ++ tests/components/wifi/test.esp32-c3.yaml | 9 ++ tests/components/wifi/test.esp32-idf.yaml | 9 ++ tests/components/wifi/test.esp32.yaml | 9 ++ tests/components/wifi/test.esp8266.yaml | 9 ++ tests/components/wifi/test.rp2040.yaml | 9 ++ .../wifi_info/test.esp32-c3-idf.yaml | 18 +++ tests/components/wifi_info/test.esp32-c3.yaml | 18 +++ .../components/wifi_info/test.esp32-idf.yaml | 18 +++ tests/components/wifi_info/test.esp32.yaml | 18 +++ tests/components/wifi_info/test.esp8266.yaml | 18 +++ tests/components/wifi_info/test.rp2040.yaml | 18 +++ .../wifi_signal/test.esp32-c3-idf.yaml | 8 ++ .../components/wifi_signal/test.esp32-c3.yaml | 8 ++ .../wifi_signal/test.esp32-idf.yaml | 8 ++ tests/components/wifi_signal/test.esp32.yaml | 8 ++ .../components/wifi_signal/test.esp8266.yaml | 8 ++ tests/components/wifi_signal/test.rp2040.yaml | 8 ++ .../wireguard/test.esp32-c3-idf.yaml | 60 ++++++++++ tests/components/wireguard/test.esp32-c3.yaml | 60 ++++++++++ .../components/wl_134/test.esp32-c3-idf.yaml | 10 ++ tests/components/wl_134/test.esp32-c3.yaml | 10 ++ tests/components/wl_134/test.esp32-idf.yaml | 10 ++ tests/components/wl_134/test.esp32.yaml | 10 ++ tests/components/wl_134/test.esp8266.yaml | 10 ++ tests/components/wl_134/test.rp2040.yaml | 10 ++ tests/components/wled/test.esp32-c3.yaml | 17 +++ tests/components/wled/test.esp32.yaml | 17 +++ tests/components/wled/test.esp8266.yaml | 17 +++ 59 files changed, 1177 insertions(+) create mode 100644 tests/components/wake_on_lan/test.esp32-c3.yaml create mode 100644 tests/components/wake_on_lan/test.esp32.yaml create mode 100644 tests/components/wake_on_lan/test.esp8266.yaml create mode 100644 tests/components/wake_on_lan/test.rp2040.yaml create mode 100644 tests/components/waveshare_epaper/test.esp32-c3-idf.yaml create mode 100644 tests/components/waveshare_epaper/test.esp32-c3.yaml create mode 100644 tests/components/waveshare_epaper/test.esp32-idf.yaml create mode 100644 tests/components/waveshare_epaper/test.esp8266.yaml create mode 100644 tests/components/waveshare_epaper/test.rp2040.yaml create mode 100644 tests/components/web_server/test.esp32-c3-idf.yaml create mode 100644 tests/components/web_server/test.esp32-c3.yaml create mode 100644 tests/components/web_server/test.esp32-idf.yaml create mode 100644 tests/components/web_server/test.esp32.yaml create mode 100644 tests/components/web_server/test.esp8266.yaml create mode 100644 tests/components/whirlpool/test.esp32-c3-idf.yaml create mode 100644 tests/components/whirlpool/test.esp32-c3.yaml create mode 100644 tests/components/whirlpool/test.esp32-idf.yaml create mode 100644 tests/components/whirlpool/test.esp32.yaml create mode 100644 tests/components/whirlpool/test.esp8266.yaml create mode 100644 tests/components/whynter/test.esp32-c3-idf.yaml create mode 100644 tests/components/whynter/test.esp32-c3.yaml create mode 100644 tests/components/whynter/test.esp32-idf.yaml create mode 100644 tests/components/whynter/test.esp32.yaml create mode 100644 tests/components/whynter/test.esp8266.yaml create mode 100644 tests/components/wiegand/test.esp32-c3-idf.yaml create mode 100644 tests/components/wiegand/test.esp32-c3.yaml create mode 100644 tests/components/wiegand/test.esp32-idf.yaml create mode 100644 tests/components/wiegand/test.esp32.yaml create mode 100644 tests/components/wiegand/test.esp8266.yaml create mode 100644 tests/components/wiegand/test.rp2040.yaml create mode 100644 tests/components/wifi/test.esp32-c3-idf.yaml create mode 100644 tests/components/wifi/test.esp32-c3.yaml create mode 100644 tests/components/wifi/test.esp32-idf.yaml create mode 100644 tests/components/wifi/test.esp32.yaml create mode 100644 tests/components/wifi/test.esp8266.yaml create mode 100644 tests/components/wifi/test.rp2040.yaml create mode 100644 tests/components/wifi_info/test.esp32-c3-idf.yaml create mode 100644 tests/components/wifi_info/test.esp32-c3.yaml create mode 100644 tests/components/wifi_info/test.esp32-idf.yaml create mode 100644 tests/components/wifi_info/test.esp32.yaml create mode 100644 tests/components/wifi_info/test.esp8266.yaml create mode 100644 tests/components/wifi_info/test.rp2040.yaml create mode 100644 tests/components/wifi_signal/test.esp32-c3-idf.yaml create mode 100644 tests/components/wifi_signal/test.esp32-c3.yaml create mode 100644 tests/components/wifi_signal/test.esp32-idf.yaml create mode 100644 tests/components/wifi_signal/test.esp32.yaml create mode 100644 tests/components/wifi_signal/test.esp8266.yaml create mode 100644 tests/components/wifi_signal/test.rp2040.yaml create mode 100644 tests/components/wireguard/test.esp32-c3-idf.yaml create mode 100644 tests/components/wireguard/test.esp32-c3.yaml create mode 100644 tests/components/wl_134/test.esp32-c3-idf.yaml create mode 100644 tests/components/wl_134/test.esp32-c3.yaml create mode 100644 tests/components/wl_134/test.esp32-idf.yaml create mode 100644 tests/components/wl_134/test.esp32.yaml create mode 100644 tests/components/wl_134/test.esp8266.yaml create mode 100644 tests/components/wl_134/test.rp2040.yaml create mode 100644 tests/components/wled/test.esp32-c3.yaml create mode 100644 tests/components/wled/test.esp32.yaml create mode 100644 tests/components/wled/test.esp8266.yaml diff --git a/tests/components/wake_on_lan/test.esp32-c3.yaml b/tests/components/wake_on_lan/test.esp32-c3.yaml new file mode 100644 index 0000000000..6a5351b624 --- /dev/null +++ b/tests/components/wake_on_lan/test.esp32-c3.yaml @@ -0,0 +1,9 @@ +wifi: + ssid: MySSID + password: password1 + +button: + - platform: wake_on_lan + id: wol_1 + name: wol_test_1 + target_mac_address: 12:34:56:78:90:ab diff --git a/tests/components/wake_on_lan/test.esp32.yaml b/tests/components/wake_on_lan/test.esp32.yaml new file mode 100644 index 0000000000..6a5351b624 --- /dev/null +++ b/tests/components/wake_on_lan/test.esp32.yaml @@ -0,0 +1,9 @@ +wifi: + ssid: MySSID + password: password1 + +button: + - platform: wake_on_lan + id: wol_1 + name: wol_test_1 + target_mac_address: 12:34:56:78:90:ab diff --git a/tests/components/wake_on_lan/test.esp8266.yaml b/tests/components/wake_on_lan/test.esp8266.yaml new file mode 100644 index 0000000000..6a5351b624 --- /dev/null +++ b/tests/components/wake_on_lan/test.esp8266.yaml @@ -0,0 +1,9 @@ +wifi: + ssid: MySSID + password: password1 + +button: + - platform: wake_on_lan + id: wol_1 + name: wol_test_1 + target_mac_address: 12:34:56:78:90:ab diff --git a/tests/components/wake_on_lan/test.rp2040.yaml b/tests/components/wake_on_lan/test.rp2040.yaml new file mode 100644 index 0000000000..6a5351b624 --- /dev/null +++ b/tests/components/wake_on_lan/test.rp2040.yaml @@ -0,0 +1,9 @@ +wifi: + ssid: MySSID + password: password1 + +button: + - platform: wake_on_lan + id: wol_1 + name: wol_test_1 + target_mac_address: 12:34:56:78:90:ab diff --git a/tests/components/waveshare_epaper/test.esp32-c3-idf.yaml b/tests/components/waveshare_epaper/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..1c4547b7b4 --- /dev/null +++ b/tests/components/waveshare_epaper/test.esp32-c3-idf.yaml @@ -0,0 +1,107 @@ +spi: + - id: spi_waveshare_epaper + clk_pin: 6 + mosi_pin: 7 + miso_pin: 5 + +display: + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.13in-ttgo-b1 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.90in + full_update_every: 30 + reset_duration: 200ms + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.90inv2 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.70in-b + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.70in-bv2 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 1.54in-m5coreink-m09 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); diff --git a/tests/components/waveshare_epaper/test.esp32-c3.yaml b/tests/components/waveshare_epaper/test.esp32-c3.yaml new file mode 100644 index 0000000000..1c4547b7b4 --- /dev/null +++ b/tests/components/waveshare_epaper/test.esp32-c3.yaml @@ -0,0 +1,107 @@ +spi: + - id: spi_waveshare_epaper + clk_pin: 6 + mosi_pin: 7 + miso_pin: 5 + +display: + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.13in-ttgo-b1 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.90in + full_update_every: 30 + reset_duration: 200ms + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.90inv2 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.70in-b + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.70in-bv2 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 1.54in-m5coreink-m09 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); diff --git a/tests/components/waveshare_epaper/test.esp32-idf.yaml b/tests/components/waveshare_epaper/test.esp32-idf.yaml new file mode 100644 index 0000000000..b6082fcfbf --- /dev/null +++ b/tests/components/waveshare_epaper/test.esp32-idf.yaml @@ -0,0 +1,107 @@ +spi: + - id: spi_bme280 + clk_pin: 16 + mosi_pin: 17 + miso_pin: 15 + +display: + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.13in-ttgo-b1 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.90in + full_update_every: 30 + reset_duration: 200ms + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.90inv2 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.70in-b + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.70in-bv2 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 1.54in-m5coreink-m09 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); diff --git a/tests/components/waveshare_epaper/test.esp8266.yaml b/tests/components/waveshare_epaper/test.esp8266.yaml new file mode 100644 index 0000000000..1f076a67be --- /dev/null +++ b/tests/components/waveshare_epaper/test.esp8266.yaml @@ -0,0 +1,107 @@ +spi: + - id: spi_bme280 + clk_pin: 14 + mosi_pin: 13 + miso_pin: 12 + +display: + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.13in-ttgo-b1 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.90in + full_update_every: 30 + reset_duration: 200ms + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.90inv2 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.70in-b + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 2.70in-bv2 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 4 + dc_pin: + allow_other_uses: true + number: 4 + busy_pin: + allow_other_uses: true + number: 4 + reset_pin: + allow_other_uses: true + number: 4 + model: 1.54in-m5coreink-m09 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); diff --git a/tests/components/waveshare_epaper/test.rp2040.yaml b/tests/components/waveshare_epaper/test.rp2040.yaml new file mode 100644 index 0000000000..6050062d7e --- /dev/null +++ b/tests/components/waveshare_epaper/test.rp2040.yaml @@ -0,0 +1,107 @@ +spi: + - id: spi_bme280 + clk_pin: 2 + mosi_pin: 3 + miso_pin: 4 + +display: + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 5 + dc_pin: + allow_other_uses: true + number: 5 + busy_pin: + allow_other_uses: true + number: 5 + reset_pin: + allow_other_uses: true + number: 5 + model: 2.13in-ttgo-b1 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 5 + dc_pin: + allow_other_uses: true + number: 5 + busy_pin: + allow_other_uses: true + number: 5 + reset_pin: + allow_other_uses: true + number: 5 + model: 2.90in + full_update_every: 30 + reset_duration: 200ms + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 5 + dc_pin: + allow_other_uses: true + number: 5 + busy_pin: + allow_other_uses: true + number: 5 + reset_pin: + allow_other_uses: true + number: 5 + model: 2.90inv2 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 5 + dc_pin: + allow_other_uses: true + number: 5 + busy_pin: + allow_other_uses: true + number: 5 + reset_pin: + allow_other_uses: true + number: 5 + model: 2.70in-b + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 5 + dc_pin: + allow_other_uses: true + number: 5 + busy_pin: + allow_other_uses: true + number: 5 + reset_pin: + allow_other_uses: true + number: 5 + model: 2.70in-bv2 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: + allow_other_uses: true + number: 5 + dc_pin: + allow_other_uses: true + number: 5 + busy_pin: + allow_other_uses: true + number: 5 + reset_pin: + allow_other_uses: true + number: 5 + model: 1.54in-m5coreink-m09 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); diff --git a/tests/components/web_server/test.esp32-c3-idf.yaml b/tests/components/web_server/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..94388726c3 --- /dev/null +++ b/tests/components/web_server/test.esp32-c3-idf.yaml @@ -0,0 +1,7 @@ +wifi: + ssid: MySSID + password: password1 + +web_server: + port: 8080 + version: 2 diff --git a/tests/components/web_server/test.esp32-c3.yaml b/tests/components/web_server/test.esp32-c3.yaml new file mode 100644 index 0000000000..94388726c3 --- /dev/null +++ b/tests/components/web_server/test.esp32-c3.yaml @@ -0,0 +1,7 @@ +wifi: + ssid: MySSID + password: password1 + +web_server: + port: 8080 + version: 2 diff --git a/tests/components/web_server/test.esp32-idf.yaml b/tests/components/web_server/test.esp32-idf.yaml new file mode 100644 index 0000000000..94388726c3 --- /dev/null +++ b/tests/components/web_server/test.esp32-idf.yaml @@ -0,0 +1,7 @@ +wifi: + ssid: MySSID + password: password1 + +web_server: + port: 8080 + version: 2 diff --git a/tests/components/web_server/test.esp32.yaml b/tests/components/web_server/test.esp32.yaml new file mode 100644 index 0000000000..94388726c3 --- /dev/null +++ b/tests/components/web_server/test.esp32.yaml @@ -0,0 +1,7 @@ +wifi: + ssid: MySSID + password: password1 + +web_server: + port: 8080 + version: 2 diff --git a/tests/components/web_server/test.esp8266.yaml b/tests/components/web_server/test.esp8266.yaml new file mode 100644 index 0000000000..94388726c3 --- /dev/null +++ b/tests/components/web_server/test.esp8266.yaml @@ -0,0 +1,7 @@ +wifi: + ssid: MySSID + password: password1 + +web_server: + port: 8080 + version: 2 diff --git a/tests/components/whirlpool/test.esp32-c3-idf.yaml b/tests/components/whirlpool/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..4d0afc39a4 --- /dev/null +++ b/tests/components/whirlpool/test.esp32-c3-idf.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: whirlpool + name: Whirlpool Climate diff --git a/tests/components/whirlpool/test.esp32-c3.yaml b/tests/components/whirlpool/test.esp32-c3.yaml new file mode 100644 index 0000000000..4d0afc39a4 --- /dev/null +++ b/tests/components/whirlpool/test.esp32-c3.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: whirlpool + name: Whirlpool Climate diff --git a/tests/components/whirlpool/test.esp32-idf.yaml b/tests/components/whirlpool/test.esp32-idf.yaml new file mode 100644 index 0000000000..4d0afc39a4 --- /dev/null +++ b/tests/components/whirlpool/test.esp32-idf.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: whirlpool + name: Whirlpool Climate diff --git a/tests/components/whirlpool/test.esp32.yaml b/tests/components/whirlpool/test.esp32.yaml new file mode 100644 index 0000000000..4d0afc39a4 --- /dev/null +++ b/tests/components/whirlpool/test.esp32.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: whirlpool + name: Whirlpool Climate diff --git a/tests/components/whirlpool/test.esp8266.yaml b/tests/components/whirlpool/test.esp8266.yaml new file mode 100644 index 0000000000..efd530c160 --- /dev/null +++ b/tests/components/whirlpool/test.esp8266.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 5 + carrier_duty_percent: 50% + +climate: + - platform: whirlpool + name: Whirlpool Climate diff --git a/tests/components/whynter/test.esp32-c3-idf.yaml b/tests/components/whynter/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..dc8fb9584d --- /dev/null +++ b/tests/components/whynter/test.esp32-c3-idf.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: whynter + name: Whynter Climate diff --git a/tests/components/whynter/test.esp32-c3.yaml b/tests/components/whynter/test.esp32-c3.yaml new file mode 100644 index 0000000000..dc8fb9584d --- /dev/null +++ b/tests/components/whynter/test.esp32-c3.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: whynter + name: Whynter Climate diff --git a/tests/components/whynter/test.esp32-idf.yaml b/tests/components/whynter/test.esp32-idf.yaml new file mode 100644 index 0000000000..dc8fb9584d --- /dev/null +++ b/tests/components/whynter/test.esp32-idf.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: whynter + name: Whynter Climate diff --git a/tests/components/whynter/test.esp32.yaml b/tests/components/whynter/test.esp32.yaml new file mode 100644 index 0000000000..dc8fb9584d --- /dev/null +++ b/tests/components/whynter/test.esp32.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + +climate: + - platform: whynter + name: Whynter Climate diff --git a/tests/components/whynter/test.esp8266.yaml b/tests/components/whynter/test.esp8266.yaml new file mode 100644 index 0000000000..a656a7427d --- /dev/null +++ b/tests/components/whynter/test.esp8266.yaml @@ -0,0 +1,7 @@ +remote_transmitter: + pin: 5 + carrier_duty_percent: 50% + +climate: + - platform: whynter + name: Whynter Climate diff --git a/tests/components/wiegand/test.esp32-c3-idf.yaml b/tests/components/wiegand/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..4e15a44b89 --- /dev/null +++ b/tests/components/wiegand/test.esp32-c3-idf.yaml @@ -0,0 +1,10 @@ +wiegand: + - id: test_wiegand + d0: 5 + d1: 4 + on_key: + - lambda: ESP_LOGI("KEY", "Received key %d", x); + on_tag: + - lambda: ESP_LOGI("TAG", "Received tag %s", x.c_str()); + on_raw: + - lambda: ESP_LOGI("RAW", "Received raw %d bits, value %llx", bits, value); diff --git a/tests/components/wiegand/test.esp32-c3.yaml b/tests/components/wiegand/test.esp32-c3.yaml new file mode 100644 index 0000000000..4e15a44b89 --- /dev/null +++ b/tests/components/wiegand/test.esp32-c3.yaml @@ -0,0 +1,10 @@ +wiegand: + - id: test_wiegand + d0: 5 + d1: 4 + on_key: + - lambda: ESP_LOGI("KEY", "Received key %d", x); + on_tag: + - lambda: ESP_LOGI("TAG", "Received tag %s", x.c_str()); + on_raw: + - lambda: ESP_LOGI("RAW", "Received raw %d bits, value %llx", bits, value); diff --git a/tests/components/wiegand/test.esp32-idf.yaml b/tests/components/wiegand/test.esp32-idf.yaml new file mode 100644 index 0000000000..4e15a44b89 --- /dev/null +++ b/tests/components/wiegand/test.esp32-idf.yaml @@ -0,0 +1,10 @@ +wiegand: + - id: test_wiegand + d0: 5 + d1: 4 + on_key: + - lambda: ESP_LOGI("KEY", "Received key %d", x); + on_tag: + - lambda: ESP_LOGI("TAG", "Received tag %s", x.c_str()); + on_raw: + - lambda: ESP_LOGI("RAW", "Received raw %d bits, value %llx", bits, value); diff --git a/tests/components/wiegand/test.esp32.yaml b/tests/components/wiegand/test.esp32.yaml new file mode 100644 index 0000000000..4e15a44b89 --- /dev/null +++ b/tests/components/wiegand/test.esp32.yaml @@ -0,0 +1,10 @@ +wiegand: + - id: test_wiegand + d0: 5 + d1: 4 + on_key: + - lambda: ESP_LOGI("KEY", "Received key %d", x); + on_tag: + - lambda: ESP_LOGI("TAG", "Received tag %s", x.c_str()); + on_raw: + - lambda: ESP_LOGI("RAW", "Received raw %d bits, value %llx", bits, value); diff --git a/tests/components/wiegand/test.esp8266.yaml b/tests/components/wiegand/test.esp8266.yaml new file mode 100644 index 0000000000..4e15a44b89 --- /dev/null +++ b/tests/components/wiegand/test.esp8266.yaml @@ -0,0 +1,10 @@ +wiegand: + - id: test_wiegand + d0: 5 + d1: 4 + on_key: + - lambda: ESP_LOGI("KEY", "Received key %d", x); + on_tag: + - lambda: ESP_LOGI("TAG", "Received tag %s", x.c_str()); + on_raw: + - lambda: ESP_LOGI("RAW", "Received raw %d bits, value %llx", bits, value); diff --git a/tests/components/wiegand/test.rp2040.yaml b/tests/components/wiegand/test.rp2040.yaml new file mode 100644 index 0000000000..4e15a44b89 --- /dev/null +++ b/tests/components/wiegand/test.rp2040.yaml @@ -0,0 +1,10 @@ +wiegand: + - id: test_wiegand + d0: 5 + d1: 4 + on_key: + - lambda: ESP_LOGI("KEY", "Received key %d", x); + on_tag: + - lambda: ESP_LOGI("TAG", "Received tag %s", x.c_str()); + on_raw: + - lambda: ESP_LOGI("RAW", "Received raw %d bits, value %llx", bits, value); diff --git a/tests/components/wifi/test.esp32-c3-idf.yaml b/tests/components/wifi/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..003f6347be --- /dev/null +++ b/tests/components/wifi/test.esp32-c3-idf.yaml @@ -0,0 +1,9 @@ +esphome: + on_boot: + then: + - wifi.disable + - wifi.enable + +wifi: + ssid: MySSID + password: password1 diff --git a/tests/components/wifi/test.esp32-c3.yaml b/tests/components/wifi/test.esp32-c3.yaml new file mode 100644 index 0000000000..003f6347be --- /dev/null +++ b/tests/components/wifi/test.esp32-c3.yaml @@ -0,0 +1,9 @@ +esphome: + on_boot: + then: + - wifi.disable + - wifi.enable + +wifi: + ssid: MySSID + password: password1 diff --git a/tests/components/wifi/test.esp32-idf.yaml b/tests/components/wifi/test.esp32-idf.yaml new file mode 100644 index 0000000000..003f6347be --- /dev/null +++ b/tests/components/wifi/test.esp32-idf.yaml @@ -0,0 +1,9 @@ +esphome: + on_boot: + then: + - wifi.disable + - wifi.enable + +wifi: + ssid: MySSID + password: password1 diff --git a/tests/components/wifi/test.esp32.yaml b/tests/components/wifi/test.esp32.yaml new file mode 100644 index 0000000000..003f6347be --- /dev/null +++ b/tests/components/wifi/test.esp32.yaml @@ -0,0 +1,9 @@ +esphome: + on_boot: + then: + - wifi.disable + - wifi.enable + +wifi: + ssid: MySSID + password: password1 diff --git a/tests/components/wifi/test.esp8266.yaml b/tests/components/wifi/test.esp8266.yaml new file mode 100644 index 0000000000..003f6347be --- /dev/null +++ b/tests/components/wifi/test.esp8266.yaml @@ -0,0 +1,9 @@ +esphome: + on_boot: + then: + - wifi.disable + - wifi.enable + +wifi: + ssid: MySSID + password: password1 diff --git a/tests/components/wifi/test.rp2040.yaml b/tests/components/wifi/test.rp2040.yaml new file mode 100644 index 0000000000..003f6347be --- /dev/null +++ b/tests/components/wifi/test.rp2040.yaml @@ -0,0 +1,9 @@ +esphome: + on_boot: + then: + - wifi.disable + - wifi.enable + +wifi: + ssid: MySSID + password: password1 diff --git a/tests/components/wifi_info/test.esp32-c3-idf.yaml b/tests/components/wifi_info/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..cf5ea563ba --- /dev/null +++ b/tests/components/wifi_info/test.esp32-c3-idf.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +text_sensor: + - platform: wifi_info + scan_results: + name: Scan Results + ip_address: + name: IP Address + ssid: + name: SSID + bssid: + name: BSSID + mac_address: + name: Mac Address + dns_address: + name: DNS ADdress diff --git a/tests/components/wifi_info/test.esp32-c3.yaml b/tests/components/wifi_info/test.esp32-c3.yaml new file mode 100644 index 0000000000..cf5ea563ba --- /dev/null +++ b/tests/components/wifi_info/test.esp32-c3.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +text_sensor: + - platform: wifi_info + scan_results: + name: Scan Results + ip_address: + name: IP Address + ssid: + name: SSID + bssid: + name: BSSID + mac_address: + name: Mac Address + dns_address: + name: DNS ADdress diff --git a/tests/components/wifi_info/test.esp32-idf.yaml b/tests/components/wifi_info/test.esp32-idf.yaml new file mode 100644 index 0000000000..cf5ea563ba --- /dev/null +++ b/tests/components/wifi_info/test.esp32-idf.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +text_sensor: + - platform: wifi_info + scan_results: + name: Scan Results + ip_address: + name: IP Address + ssid: + name: SSID + bssid: + name: BSSID + mac_address: + name: Mac Address + dns_address: + name: DNS ADdress diff --git a/tests/components/wifi_info/test.esp32.yaml b/tests/components/wifi_info/test.esp32.yaml new file mode 100644 index 0000000000..cf5ea563ba --- /dev/null +++ b/tests/components/wifi_info/test.esp32.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +text_sensor: + - platform: wifi_info + scan_results: + name: Scan Results + ip_address: + name: IP Address + ssid: + name: SSID + bssid: + name: BSSID + mac_address: + name: Mac Address + dns_address: + name: DNS ADdress diff --git a/tests/components/wifi_info/test.esp8266.yaml b/tests/components/wifi_info/test.esp8266.yaml new file mode 100644 index 0000000000..cf5ea563ba --- /dev/null +++ b/tests/components/wifi_info/test.esp8266.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +text_sensor: + - platform: wifi_info + scan_results: + name: Scan Results + ip_address: + name: IP Address + ssid: + name: SSID + bssid: + name: BSSID + mac_address: + name: Mac Address + dns_address: + name: DNS ADdress diff --git a/tests/components/wifi_info/test.rp2040.yaml b/tests/components/wifi_info/test.rp2040.yaml new file mode 100644 index 0000000000..cf5ea563ba --- /dev/null +++ b/tests/components/wifi_info/test.rp2040.yaml @@ -0,0 +1,18 @@ +wifi: + ssid: MySSID + password: password1 + +text_sensor: + - platform: wifi_info + scan_results: + name: Scan Results + ip_address: + name: IP Address + ssid: + name: SSID + bssid: + name: BSSID + mac_address: + name: Mac Address + dns_address: + name: DNS ADdress diff --git a/tests/components/wifi_signal/test.esp32-c3-idf.yaml b/tests/components/wifi_signal/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..58d1cab244 --- /dev/null +++ b/tests/components/wifi_signal/test.esp32-c3-idf.yaml @@ -0,0 +1,8 @@ +wifi: + ssid: MySSID + password: password1 + +sensor: + - platform: wifi_signal + name: WiFi Signal Sensor + update_interval: 15s diff --git a/tests/components/wifi_signal/test.esp32-c3.yaml b/tests/components/wifi_signal/test.esp32-c3.yaml new file mode 100644 index 0000000000..58d1cab244 --- /dev/null +++ b/tests/components/wifi_signal/test.esp32-c3.yaml @@ -0,0 +1,8 @@ +wifi: + ssid: MySSID + password: password1 + +sensor: + - platform: wifi_signal + name: WiFi Signal Sensor + update_interval: 15s diff --git a/tests/components/wifi_signal/test.esp32-idf.yaml b/tests/components/wifi_signal/test.esp32-idf.yaml new file mode 100644 index 0000000000..58d1cab244 --- /dev/null +++ b/tests/components/wifi_signal/test.esp32-idf.yaml @@ -0,0 +1,8 @@ +wifi: + ssid: MySSID + password: password1 + +sensor: + - platform: wifi_signal + name: WiFi Signal Sensor + update_interval: 15s diff --git a/tests/components/wifi_signal/test.esp32.yaml b/tests/components/wifi_signal/test.esp32.yaml new file mode 100644 index 0000000000..58d1cab244 --- /dev/null +++ b/tests/components/wifi_signal/test.esp32.yaml @@ -0,0 +1,8 @@ +wifi: + ssid: MySSID + password: password1 + +sensor: + - platform: wifi_signal + name: WiFi Signal Sensor + update_interval: 15s diff --git a/tests/components/wifi_signal/test.esp8266.yaml b/tests/components/wifi_signal/test.esp8266.yaml new file mode 100644 index 0000000000..58d1cab244 --- /dev/null +++ b/tests/components/wifi_signal/test.esp8266.yaml @@ -0,0 +1,8 @@ +wifi: + ssid: MySSID + password: password1 + +sensor: + - platform: wifi_signal + name: WiFi Signal Sensor + update_interval: 15s diff --git a/tests/components/wifi_signal/test.rp2040.yaml b/tests/components/wifi_signal/test.rp2040.yaml new file mode 100644 index 0000000000..58d1cab244 --- /dev/null +++ b/tests/components/wifi_signal/test.rp2040.yaml @@ -0,0 +1,8 @@ +wifi: + ssid: MySSID + password: password1 + +sensor: + - platform: wifi_signal + name: WiFi Signal Sensor + update_interval: 15s diff --git a/tests/components/wireguard/test.esp32-c3-idf.yaml b/tests/components/wireguard/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..37d1727842 --- /dev/null +++ b/tests/components/wireguard/test.esp32-c3-idf.yaml @@ -0,0 +1,60 @@ +wifi: + ssid: MySSID + password: password1 + +time: + - platform: sntp + +wireguard: + id: vpn + address: 172.16.34.100 + netmask: 255.255.255.0 + # NEVER use the following keys for your vpn, they are now public! + private_key: wPBMxtNYH3mChicrbpsRpZIasIdPq3yZuthn23FbGG8= + peer_public_key: Hs2JfikvYU03/Kv3YoAs1hrUIPPTEkpsZKSPUljE9yc= + peer_preshared_key: 20fjM5GRnSolGPC5SRj9ljgIUyQfruv0B0bvLl3Yt60= + peer_endpoint: wg.server.example + peer_persistent_keepalive: 25s + peer_allowed_ips: + - 172.16.34.0/24 + - 192.168.4.0/24 + +binary_sensor: + - platform: wireguard + status: + name: 'WireGuard Status' + enabled: + name: 'WireGuard Enabled' + +sensor: + - platform: wireguard + latest_handshake: + name: 'WireGuard Latest Handshake' + +text_sensor: + - platform: wireguard + address: + name: 'WireGuard Address' + +button: + - platform: template + name: 'Toggle WireGuard' + entity_category: config + on_press: + - if: + condition: wireguard.enabled + then: + - wireguard.disable: + else: + - wireguard.enable: + + - platform: template + name: 'Log WireGuard status' + entity_category: config + on_press: + - if: + condition: wireguard.peer_online + then: + - logger.log: 'wireguard remote peer is online' + else: + - logger.log: 'wireguard remote peer is offline' diff --git a/tests/components/wireguard/test.esp32-c3.yaml b/tests/components/wireguard/test.esp32-c3.yaml new file mode 100644 index 0000000000..37d1727842 --- /dev/null +++ b/tests/components/wireguard/test.esp32-c3.yaml @@ -0,0 +1,60 @@ +wifi: + ssid: MySSID + password: password1 + +time: + - platform: sntp + +wireguard: + id: vpn + address: 172.16.34.100 + netmask: 255.255.255.0 + # NEVER use the following keys for your vpn, they are now public! + private_key: wPBMxtNYH3mChicrbpsRpZIasIdPq3yZuthn23FbGG8= + peer_public_key: Hs2JfikvYU03/Kv3YoAs1hrUIPPTEkpsZKSPUljE9yc= + peer_preshared_key: 20fjM5GRnSolGPC5SRj9ljgIUyQfruv0B0bvLl3Yt60= + peer_endpoint: wg.server.example + peer_persistent_keepalive: 25s + peer_allowed_ips: + - 172.16.34.0/24 + - 192.168.4.0/24 + +binary_sensor: + - platform: wireguard + status: + name: 'WireGuard Status' + enabled: + name: 'WireGuard Enabled' + +sensor: + - platform: wireguard + latest_handshake: + name: 'WireGuard Latest Handshake' + +text_sensor: + - platform: wireguard + address: + name: 'WireGuard Address' + +button: + - platform: template + name: 'Toggle WireGuard' + entity_category: config + on_press: + - if: + condition: wireguard.enabled + then: + - wireguard.disable: + else: + - wireguard.enable: + + - platform: template + name: 'Log WireGuard status' + entity_category: config + on_press: + - if: + condition: wireguard.peer_online + then: + - logger.log: 'wireguard remote peer is online' + else: + - logger.log: 'wireguard remote peer is offline' diff --git a/tests/components/wl_134/test.esp32-c3-idf.yaml b/tests/components/wl_134/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..7cda1ba060 --- /dev/null +++ b/tests/components/wl_134/test.esp32-c3-idf.yaml @@ -0,0 +1,10 @@ +uart: + - id: uart_wl_134 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +text_sensor: + - platform: wl_134 + name: Transponder Code + reset: true diff --git a/tests/components/wl_134/test.esp32-c3.yaml b/tests/components/wl_134/test.esp32-c3.yaml new file mode 100644 index 0000000000..7cda1ba060 --- /dev/null +++ b/tests/components/wl_134/test.esp32-c3.yaml @@ -0,0 +1,10 @@ +uart: + - id: uart_wl_134 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +text_sensor: + - platform: wl_134 + name: Transponder Code + reset: true diff --git a/tests/components/wl_134/test.esp32-idf.yaml b/tests/components/wl_134/test.esp32-idf.yaml new file mode 100644 index 0000000000..d517889d28 --- /dev/null +++ b/tests/components/wl_134/test.esp32-idf.yaml @@ -0,0 +1,10 @@ +uart: + - id: uart_wl_134 + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + +text_sensor: + - platform: wl_134 + name: Transponder Code + reset: true diff --git a/tests/components/wl_134/test.esp32.yaml b/tests/components/wl_134/test.esp32.yaml new file mode 100644 index 0000000000..d517889d28 --- /dev/null +++ b/tests/components/wl_134/test.esp32.yaml @@ -0,0 +1,10 @@ +uart: + - id: uart_wl_134 + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + +text_sensor: + - platform: wl_134 + name: Transponder Code + reset: true diff --git a/tests/components/wl_134/test.esp8266.yaml b/tests/components/wl_134/test.esp8266.yaml new file mode 100644 index 0000000000..7cda1ba060 --- /dev/null +++ b/tests/components/wl_134/test.esp8266.yaml @@ -0,0 +1,10 @@ +uart: + - id: uart_wl_134 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +text_sensor: + - platform: wl_134 + name: Transponder Code + reset: true diff --git a/tests/components/wl_134/test.rp2040.yaml b/tests/components/wl_134/test.rp2040.yaml new file mode 100644 index 0000000000..7cda1ba060 --- /dev/null +++ b/tests/components/wl_134/test.rp2040.yaml @@ -0,0 +1,10 @@ +uart: + - id: uart_wl_134 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +text_sensor: + - platform: wl_134 + name: Transponder Code + reset: true diff --git a/tests/components/wled/test.esp32-c3.yaml b/tests/components/wled/test.esp32-c3.yaml new file mode 100644 index 0000000000..a24f28e154 --- /dev/null +++ b/tests/components/wled/test.esp32-c3.yaml @@ -0,0 +1,17 @@ +wifi: + ssid: MySSID + password: password1 + +wled: + +light: + - platform: esp32_rmt_led_strip + id: led_matrix_32x8 + default_transition_length: 500ms + chipset: ws2812 + rgb_order: GRB + num_leds: 256 + pin: 2 + rmt_channel: 0 + effects: + - wled: diff --git a/tests/components/wled/test.esp32.yaml b/tests/components/wled/test.esp32.yaml new file mode 100644 index 0000000000..a24f28e154 --- /dev/null +++ b/tests/components/wled/test.esp32.yaml @@ -0,0 +1,17 @@ +wifi: + ssid: MySSID + password: password1 + +wled: + +light: + - platform: esp32_rmt_led_strip + id: led_matrix_32x8 + default_transition_length: 500ms + chipset: ws2812 + rgb_order: GRB + num_leds: 256 + pin: 2 + rmt_channel: 0 + effects: + - wled: diff --git a/tests/components/wled/test.esp8266.yaml b/tests/components/wled/test.esp8266.yaml new file mode 100644 index 0000000000..e291af927c --- /dev/null +++ b/tests/components/wled/test.esp8266.yaml @@ -0,0 +1,17 @@ +wifi: + ssid: MySSID + password: password1 + +wled: + +light: + - platform: neopixelbus + id: addr + name: Neopixelbus Light + method: esp8266_uart + num_leds: 5 + pin: 2 + type: GRBW + variant: SK6812 + effects: + - wled: From 92b3d94cc70c52ce18fd92204259c16507036540 Mon Sep 17 00:00:00 2001 From: Keith Burzinski Date: Wed, 27 Mar 2024 02:30:13 -0500 Subject: [PATCH 168/189] Add some components to the new testing framework (L) (#6195) --- .../lcd_gpio/test.esp32-c3-idf.yaml | 13 ++ tests/components/lcd_gpio/test.esp32-c3.yaml | 13 ++ tests/components/lcd_gpio/test.esp32-idf.yaml | 13 ++ tests/components/lcd_gpio/test.esp32.yaml | 13 ++ tests/components/lcd_gpio/test.esp8266.yaml | 13 ++ tests/components/lcd_gpio/test.rp2040.yaml | 13 ++ .../lcd_menu/test.esp32-c3-idf.yaml | 118 ++++++++++++ tests/components/lcd_menu/test.esp32-c3.yaml | 118 ++++++++++++ tests/components/lcd_menu/test.esp32-idf.yaml | 118 ++++++++++++ tests/components/lcd_menu/test.esp32.yaml | 118 ++++++++++++ tests/components/lcd_menu/test.esp8266.yaml | 118 ++++++++++++ tests/components/lcd_menu/test.rp2040.yaml | 118 ++++++++++++ .../lcd_pcf8574/test.esp32-c3-idf.yaml | 22 +++ .../components/lcd_pcf8574/test.esp32-c3.yaml | 22 +++ .../lcd_pcf8574/test.esp32-idf.yaml | 22 +++ tests/components/lcd_pcf8574/test.esp32.yaml | 22 +++ .../components/lcd_pcf8574/test.esp8266.yaml | 22 +++ tests/components/lcd_pcf8574/test.rp2040.yaml | 22 +++ .../components/ld2410/test.esp32-c3-idf.yaml | 169 ++++++++++++++++++ tests/components/ld2410/test.esp32-c3.yaml | 169 ++++++++++++++++++ tests/components/ld2410/test.esp32-idf.yaml | 169 ++++++++++++++++++ tests/components/ld2410/test.esp32.yaml | 169 ++++++++++++++++++ tests/components/ld2410/test.esp8266.yaml | 169 ++++++++++++++++++ tests/components/ld2410/test.rp2040.yaml | 169 ++++++++++++++++++ .../components/ld2420/test.esp32-c3-idf.yaml | 132 ++++++++++++++ tests/components/ld2420/test.esp32-c3.yaml | 132 ++++++++++++++ tests/components/ld2420/test.esp32-idf.yaml | 132 ++++++++++++++ tests/components/ld2420/test.esp32.yaml | 132 ++++++++++++++ tests/components/ld2420/test.esp8266.yaml | 132 ++++++++++++++ tests/components/ld2420/test.rp2040.yaml | 132 ++++++++++++++ tests/components/ledc/test.esp32-c3-idf.yaml | 11 ++ tests/components/ledc/test.esp32-c3.yaml | 11 ++ tests/components/ledc/test.esp32-idf.yaml | 11 ++ tests/components/ledc/test.esp32.yaml | 11 ++ tests/components/light/test.esp32-c3-idf.yaml | 132 ++++++++++++++ tests/components/light/test.esp32-c3.yaml | 132 ++++++++++++++ tests/components/light/test.esp32-idf.yaml | 132 ++++++++++++++ tests/components/light/test.esp32.yaml | 132 ++++++++++++++ tests/components/light/test.esp8266.yaml | 132 ++++++++++++++ tests/components/light/test.rp2040.yaml | 132 ++++++++++++++ .../components/lightwaverf/test.esp8266.yaml | 13 ++ .../lilygo_t5_47/test.esp32-c3-idf.yaml | 24 +++ .../lilygo_t5_47/test.esp32-c3.yaml | 24 +++ .../lilygo_t5_47/test.esp32-idf.yaml | 24 +++ tests/components/lilygo_t5_47/test.esp32.yaml | 24 +++ .../components/lilygo_t5_47/test.esp8266.yaml | 24 +++ .../components/lilygo_t5_47/test.rp2040.yaml | 24 +++ tests/components/lock/test.esp32-c3-idf.yaml | 36 ++++ tests/components/lock/test.esp32-c3.yaml | 36 ++++ tests/components/lock/test.esp32-idf.yaml | 36 ++++ tests/components/lock/test.esp32.yaml | 36 ++++ tests/components/lock/test.esp8266.yaml | 36 ++++ tests/components/lock/test.rp2040.yaml | 36 ++++ .../components/logger/test.esp32-c3-idf.yaml | 7 + tests/components/logger/test.esp32-c3.yaml | 7 + tests/components/logger/test.esp32-idf.yaml | 7 + tests/components/logger/test.esp32.yaml | 7 + tests/components/logger/test.esp8266.yaml | 7 + tests/components/logger/test.rp2040.yaml | 7 + .../components/ltr390/test.esp32-c3-idf.yaml | 20 +++ tests/components/ltr390/test.esp32-c3.yaml | 20 +++ tests/components/ltr390/test.esp32-idf.yaml | 20 +++ tests/components/ltr390/test.esp32.yaml | 20 +++ tests/components/ltr390/test.esp8266.yaml | 20 +++ tests/components/ltr390/test.rp2040.yaml | 20 +++ 65 files changed, 4095 insertions(+) create mode 100644 tests/components/lcd_gpio/test.esp32-c3-idf.yaml create mode 100644 tests/components/lcd_gpio/test.esp32-c3.yaml create mode 100644 tests/components/lcd_gpio/test.esp32-idf.yaml create mode 100644 tests/components/lcd_gpio/test.esp32.yaml create mode 100644 tests/components/lcd_gpio/test.esp8266.yaml create mode 100644 tests/components/lcd_gpio/test.rp2040.yaml create mode 100644 tests/components/lcd_menu/test.esp32-c3-idf.yaml create mode 100644 tests/components/lcd_menu/test.esp32-c3.yaml create mode 100644 tests/components/lcd_menu/test.esp32-idf.yaml create mode 100644 tests/components/lcd_menu/test.esp32.yaml create mode 100644 tests/components/lcd_menu/test.esp8266.yaml create mode 100644 tests/components/lcd_menu/test.rp2040.yaml create mode 100644 tests/components/lcd_pcf8574/test.esp32-c3-idf.yaml create mode 100644 tests/components/lcd_pcf8574/test.esp32-c3.yaml create mode 100644 tests/components/lcd_pcf8574/test.esp32-idf.yaml create mode 100644 tests/components/lcd_pcf8574/test.esp32.yaml create mode 100644 tests/components/lcd_pcf8574/test.esp8266.yaml create mode 100644 tests/components/lcd_pcf8574/test.rp2040.yaml create mode 100644 tests/components/ld2410/test.esp32-c3-idf.yaml create mode 100644 tests/components/ld2410/test.esp32-c3.yaml create mode 100644 tests/components/ld2410/test.esp32-idf.yaml create mode 100644 tests/components/ld2410/test.esp32.yaml create mode 100644 tests/components/ld2410/test.esp8266.yaml create mode 100644 tests/components/ld2410/test.rp2040.yaml create mode 100644 tests/components/ld2420/test.esp32-c3-idf.yaml create mode 100644 tests/components/ld2420/test.esp32-c3.yaml create mode 100644 tests/components/ld2420/test.esp32-idf.yaml create mode 100644 tests/components/ld2420/test.esp32.yaml create mode 100644 tests/components/ld2420/test.esp8266.yaml create mode 100644 tests/components/ld2420/test.rp2040.yaml create mode 100644 tests/components/ledc/test.esp32-c3-idf.yaml create mode 100644 tests/components/ledc/test.esp32-c3.yaml create mode 100644 tests/components/ledc/test.esp32-idf.yaml create mode 100644 tests/components/ledc/test.esp32.yaml create mode 100644 tests/components/light/test.esp32-c3-idf.yaml create mode 100644 tests/components/light/test.esp32-c3.yaml create mode 100644 tests/components/light/test.esp32-idf.yaml create mode 100644 tests/components/light/test.esp32.yaml create mode 100644 tests/components/light/test.esp8266.yaml create mode 100644 tests/components/light/test.rp2040.yaml create mode 100644 tests/components/lightwaverf/test.esp8266.yaml create mode 100644 tests/components/lilygo_t5_47/test.esp32-c3-idf.yaml create mode 100644 tests/components/lilygo_t5_47/test.esp32-c3.yaml create mode 100644 tests/components/lilygo_t5_47/test.esp32-idf.yaml create mode 100644 tests/components/lilygo_t5_47/test.esp32.yaml create mode 100644 tests/components/lilygo_t5_47/test.esp8266.yaml create mode 100644 tests/components/lilygo_t5_47/test.rp2040.yaml create mode 100644 tests/components/lock/test.esp32-c3-idf.yaml create mode 100644 tests/components/lock/test.esp32-c3.yaml create mode 100644 tests/components/lock/test.esp32-idf.yaml create mode 100644 tests/components/lock/test.esp32.yaml create mode 100644 tests/components/lock/test.esp8266.yaml create mode 100644 tests/components/lock/test.rp2040.yaml create mode 100644 tests/components/logger/test.esp32-c3-idf.yaml create mode 100644 tests/components/logger/test.esp32-c3.yaml create mode 100644 tests/components/logger/test.esp32-idf.yaml create mode 100644 tests/components/logger/test.esp32.yaml create mode 100644 tests/components/logger/test.esp8266.yaml create mode 100644 tests/components/logger/test.rp2040.yaml create mode 100644 tests/components/ltr390/test.esp32-c3-idf.yaml create mode 100644 tests/components/ltr390/test.esp32-c3.yaml create mode 100644 tests/components/ltr390/test.esp32-idf.yaml create mode 100644 tests/components/ltr390/test.esp32.yaml create mode 100644 tests/components/ltr390/test.esp8266.yaml create mode 100644 tests/components/ltr390/test.rp2040.yaml diff --git a/tests/components/lcd_gpio/test.esp32-c3-idf.yaml b/tests/components/lcd_gpio/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..b89715a755 --- /dev/null +++ b/tests/components/lcd_gpio/test.esp32-c3-idf.yaml @@ -0,0 +1,13 @@ +display: + - platform: lcd_gpio + id: my_lcd_gpio + dimensions: 18x4 + data_pins: + - number: 1 + - number: 2 + - number: 3 + - number: 4 + enable_pin: 5 + rs_pin: 6 + lambda: |- + it.print("Hello World!"); diff --git a/tests/components/lcd_gpio/test.esp32-c3.yaml b/tests/components/lcd_gpio/test.esp32-c3.yaml new file mode 100644 index 0000000000..b89715a755 --- /dev/null +++ b/tests/components/lcd_gpio/test.esp32-c3.yaml @@ -0,0 +1,13 @@ +display: + - platform: lcd_gpio + id: my_lcd_gpio + dimensions: 18x4 + data_pins: + - number: 1 + - number: 2 + - number: 3 + - number: 4 + enable_pin: 5 + rs_pin: 6 + lambda: |- + it.print("Hello World!"); diff --git a/tests/components/lcd_gpio/test.esp32-idf.yaml b/tests/components/lcd_gpio/test.esp32-idf.yaml new file mode 100644 index 0000000000..d2b33aeb3a --- /dev/null +++ b/tests/components/lcd_gpio/test.esp32-idf.yaml @@ -0,0 +1,13 @@ +display: + - platform: lcd_gpio + id: my_lcd_gpio + dimensions: 18x4 + data_pins: + - number: 12 + - number: 13 + - number: 14 + - number: 15 + enable_pin: 16 + rs_pin: 5 + lambda: |- + it.print("Hello World!"); diff --git a/tests/components/lcd_gpio/test.esp32.yaml b/tests/components/lcd_gpio/test.esp32.yaml new file mode 100644 index 0000000000..d2b33aeb3a --- /dev/null +++ b/tests/components/lcd_gpio/test.esp32.yaml @@ -0,0 +1,13 @@ +display: + - platform: lcd_gpio + id: my_lcd_gpio + dimensions: 18x4 + data_pins: + - number: 12 + - number: 13 + - number: 14 + - number: 15 + enable_pin: 16 + rs_pin: 5 + lambda: |- + it.print("Hello World!"); diff --git a/tests/components/lcd_gpio/test.esp8266.yaml b/tests/components/lcd_gpio/test.esp8266.yaml new file mode 100644 index 0000000000..d2b33aeb3a --- /dev/null +++ b/tests/components/lcd_gpio/test.esp8266.yaml @@ -0,0 +1,13 @@ +display: + - platform: lcd_gpio + id: my_lcd_gpio + dimensions: 18x4 + data_pins: + - number: 12 + - number: 13 + - number: 14 + - number: 15 + enable_pin: 16 + rs_pin: 5 + lambda: |- + it.print("Hello World!"); diff --git a/tests/components/lcd_gpio/test.rp2040.yaml b/tests/components/lcd_gpio/test.rp2040.yaml new file mode 100644 index 0000000000..b89715a755 --- /dev/null +++ b/tests/components/lcd_gpio/test.rp2040.yaml @@ -0,0 +1,13 @@ +display: + - platform: lcd_gpio + id: my_lcd_gpio + dimensions: 18x4 + data_pins: + - number: 1 + - number: 2 + - number: 3 + - number: 4 + enable_pin: 5 + rs_pin: 6 + lambda: |- + it.print("Hello World!"); diff --git a/tests/components/lcd_menu/test.esp32-c3-idf.yaml b/tests/components/lcd_menu/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..39d2278d3d --- /dev/null +++ b/tests/components/lcd_menu/test.esp32-c3-idf.yaml @@ -0,0 +1,118 @@ +number: + - platform: template + id: test_number + min_value: 0 + step: 1 + max_value: 10 + optimistic: true + +select: + - platform: template + id: test_select + options: + - one + - two + optimistic: true + +switch: + - platform: template + name: Template Switch + id: my_switch + optimistic: true + +display: + - platform: lcd_gpio + id: my_lcd_gpio + dimensions: 18x4 + data_pins: + - number: 1 + - number: 2 + - number: 3 + - number: 4 + enable_pin: 5 + rs_pin: 6 + lambda: |- + it.print("Hello World!"); + +lcd_menu: + id: test_lcd_menu + display_id: my_lcd_gpio + mark_back: 0x5e + mark_selected: 0x3e + mark_editing: 0x2a + mark_submenu: 0x7e + active: false + mode: rotary + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "root enter");' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "root leave");' + items: + - type: back + text: Back + - type: label + - type: menu + text: Submenu 1 + items: + - type: back + text: Back + - type: menu + text: Submenu 21 + items: + - type: back + text: Back + - type: command + text: Show Main + on_value: + then: + - display_menu.show_main: test_lcd_menu + - type: select + text: Enum Item + immediate_edit: true + select: test_select + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: number + text: Number + number: test_number + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: command + text: Hide + on_value: + then: + - display_menu.hide: test_lcd_menu + - type: switch + text: Switch + switch: my_switch + on_text: Bright + off_text: Dark + immediate_edit: false + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "switch value: %s", it->get_value_text().c_str());' + - type: custom + text: !lambda 'return "Custom";' + value_lambda: 'return "Val";' + on_next: + then: + lambda: 'ESP_LOGI("lcd_menu", "custom next: %s", it->get_text().c_str());' + on_prev: + then: + lambda: 'ESP_LOGI("lcd_menu", "custom prev: %s", it->get_text().c_str());' diff --git a/tests/components/lcd_menu/test.esp32-c3.yaml b/tests/components/lcd_menu/test.esp32-c3.yaml new file mode 100644 index 0000000000..39d2278d3d --- /dev/null +++ b/tests/components/lcd_menu/test.esp32-c3.yaml @@ -0,0 +1,118 @@ +number: + - platform: template + id: test_number + min_value: 0 + step: 1 + max_value: 10 + optimistic: true + +select: + - platform: template + id: test_select + options: + - one + - two + optimistic: true + +switch: + - platform: template + name: Template Switch + id: my_switch + optimistic: true + +display: + - platform: lcd_gpio + id: my_lcd_gpio + dimensions: 18x4 + data_pins: + - number: 1 + - number: 2 + - number: 3 + - number: 4 + enable_pin: 5 + rs_pin: 6 + lambda: |- + it.print("Hello World!"); + +lcd_menu: + id: test_lcd_menu + display_id: my_lcd_gpio + mark_back: 0x5e + mark_selected: 0x3e + mark_editing: 0x2a + mark_submenu: 0x7e + active: false + mode: rotary + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "root enter");' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "root leave");' + items: + - type: back + text: Back + - type: label + - type: menu + text: Submenu 1 + items: + - type: back + text: Back + - type: menu + text: Submenu 21 + items: + - type: back + text: Back + - type: command + text: Show Main + on_value: + then: + - display_menu.show_main: test_lcd_menu + - type: select + text: Enum Item + immediate_edit: true + select: test_select + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: number + text: Number + number: test_number + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: command + text: Hide + on_value: + then: + - display_menu.hide: test_lcd_menu + - type: switch + text: Switch + switch: my_switch + on_text: Bright + off_text: Dark + immediate_edit: false + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "switch value: %s", it->get_value_text().c_str());' + - type: custom + text: !lambda 'return "Custom";' + value_lambda: 'return "Val";' + on_next: + then: + lambda: 'ESP_LOGI("lcd_menu", "custom next: %s", it->get_text().c_str());' + on_prev: + then: + lambda: 'ESP_LOGI("lcd_menu", "custom prev: %s", it->get_text().c_str());' diff --git a/tests/components/lcd_menu/test.esp32-idf.yaml b/tests/components/lcd_menu/test.esp32-idf.yaml new file mode 100644 index 0000000000..833ea2169a --- /dev/null +++ b/tests/components/lcd_menu/test.esp32-idf.yaml @@ -0,0 +1,118 @@ +number: + - platform: template + id: test_number + min_value: 0 + step: 1 + max_value: 10 + optimistic: true + +select: + - platform: template + id: test_select + options: + - one + - two + optimistic: true + +switch: + - platform: template + name: Template Switch + id: my_switch + optimistic: true + +display: + - platform: lcd_gpio + id: my_lcd_gpio + dimensions: 18x4 + data_pins: + - number: 12 + - number: 13 + - number: 14 + - number: 15 + enable_pin: 16 + rs_pin: 5 + lambda: |- + it.print("Hello World!"); + +lcd_menu: + id: test_lcd_menu + display_id: my_lcd_gpio + mark_back: 0x5e + mark_selected: 0x3e + mark_editing: 0x2a + mark_submenu: 0x7e + active: false + mode: rotary + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "root enter");' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "root leave");' + items: + - type: back + text: Back + - type: label + - type: menu + text: Submenu 1 + items: + - type: back + text: Back + - type: menu + text: Submenu 21 + items: + - type: back + text: Back + - type: command + text: Show Main + on_value: + then: + - display_menu.show_main: test_lcd_menu + - type: select + text: Enum Item + immediate_edit: true + select: test_select + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: number + text: Number + number: test_number + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: command + text: Hide + on_value: + then: + - display_menu.hide: test_lcd_menu + - type: switch + text: Switch + switch: my_switch + on_text: Bright + off_text: Dark + immediate_edit: false + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "switch value: %s", it->get_value_text().c_str());' + - type: custom + text: !lambda 'return "Custom";' + value_lambda: 'return "Val";' + on_next: + then: + lambda: 'ESP_LOGI("lcd_menu", "custom next: %s", it->get_text().c_str());' + on_prev: + then: + lambda: 'ESP_LOGI("lcd_menu", "custom prev: %s", it->get_text().c_str());' diff --git a/tests/components/lcd_menu/test.esp32.yaml b/tests/components/lcd_menu/test.esp32.yaml new file mode 100644 index 0000000000..833ea2169a --- /dev/null +++ b/tests/components/lcd_menu/test.esp32.yaml @@ -0,0 +1,118 @@ +number: + - platform: template + id: test_number + min_value: 0 + step: 1 + max_value: 10 + optimistic: true + +select: + - platform: template + id: test_select + options: + - one + - two + optimistic: true + +switch: + - platform: template + name: Template Switch + id: my_switch + optimistic: true + +display: + - platform: lcd_gpio + id: my_lcd_gpio + dimensions: 18x4 + data_pins: + - number: 12 + - number: 13 + - number: 14 + - number: 15 + enable_pin: 16 + rs_pin: 5 + lambda: |- + it.print("Hello World!"); + +lcd_menu: + id: test_lcd_menu + display_id: my_lcd_gpio + mark_back: 0x5e + mark_selected: 0x3e + mark_editing: 0x2a + mark_submenu: 0x7e + active: false + mode: rotary + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "root enter");' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "root leave");' + items: + - type: back + text: Back + - type: label + - type: menu + text: Submenu 1 + items: + - type: back + text: Back + - type: menu + text: Submenu 21 + items: + - type: back + text: Back + - type: command + text: Show Main + on_value: + then: + - display_menu.show_main: test_lcd_menu + - type: select + text: Enum Item + immediate_edit: true + select: test_select + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: number + text: Number + number: test_number + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: command + text: Hide + on_value: + then: + - display_menu.hide: test_lcd_menu + - type: switch + text: Switch + switch: my_switch + on_text: Bright + off_text: Dark + immediate_edit: false + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "switch value: %s", it->get_value_text().c_str());' + - type: custom + text: !lambda 'return "Custom";' + value_lambda: 'return "Val";' + on_next: + then: + lambda: 'ESP_LOGI("lcd_menu", "custom next: %s", it->get_text().c_str());' + on_prev: + then: + lambda: 'ESP_LOGI("lcd_menu", "custom prev: %s", it->get_text().c_str());' diff --git a/tests/components/lcd_menu/test.esp8266.yaml b/tests/components/lcd_menu/test.esp8266.yaml new file mode 100644 index 0000000000..833ea2169a --- /dev/null +++ b/tests/components/lcd_menu/test.esp8266.yaml @@ -0,0 +1,118 @@ +number: + - platform: template + id: test_number + min_value: 0 + step: 1 + max_value: 10 + optimistic: true + +select: + - platform: template + id: test_select + options: + - one + - two + optimistic: true + +switch: + - platform: template + name: Template Switch + id: my_switch + optimistic: true + +display: + - platform: lcd_gpio + id: my_lcd_gpio + dimensions: 18x4 + data_pins: + - number: 12 + - number: 13 + - number: 14 + - number: 15 + enable_pin: 16 + rs_pin: 5 + lambda: |- + it.print("Hello World!"); + +lcd_menu: + id: test_lcd_menu + display_id: my_lcd_gpio + mark_back: 0x5e + mark_selected: 0x3e + mark_editing: 0x2a + mark_submenu: 0x7e + active: false + mode: rotary + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "root enter");' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "root leave");' + items: + - type: back + text: Back + - type: label + - type: menu + text: Submenu 1 + items: + - type: back + text: Back + - type: menu + text: Submenu 21 + items: + - type: back + text: Back + - type: command + text: Show Main + on_value: + then: + - display_menu.show_main: test_lcd_menu + - type: select + text: Enum Item + immediate_edit: true + select: test_select + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: number + text: Number + number: test_number + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: command + text: Hide + on_value: + then: + - display_menu.hide: test_lcd_menu + - type: switch + text: Switch + switch: my_switch + on_text: Bright + off_text: Dark + immediate_edit: false + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "switch value: %s", it->get_value_text().c_str());' + - type: custom + text: !lambda 'return "Custom";' + value_lambda: 'return "Val";' + on_next: + then: + lambda: 'ESP_LOGI("lcd_menu", "custom next: %s", it->get_text().c_str());' + on_prev: + then: + lambda: 'ESP_LOGI("lcd_menu", "custom prev: %s", it->get_text().c_str());' diff --git a/tests/components/lcd_menu/test.rp2040.yaml b/tests/components/lcd_menu/test.rp2040.yaml new file mode 100644 index 0000000000..39d2278d3d --- /dev/null +++ b/tests/components/lcd_menu/test.rp2040.yaml @@ -0,0 +1,118 @@ +number: + - platform: template + id: test_number + min_value: 0 + step: 1 + max_value: 10 + optimistic: true + +select: + - platform: template + id: test_select + options: + - one + - two + optimistic: true + +switch: + - platform: template + name: Template Switch + id: my_switch + optimistic: true + +display: + - platform: lcd_gpio + id: my_lcd_gpio + dimensions: 18x4 + data_pins: + - number: 1 + - number: 2 + - number: 3 + - number: 4 + enable_pin: 5 + rs_pin: 6 + lambda: |- + it.print("Hello World!"); + +lcd_menu: + id: test_lcd_menu + display_id: my_lcd_gpio + mark_back: 0x5e + mark_selected: 0x3e + mark_editing: 0x2a + mark_submenu: 0x7e + active: false + mode: rotary + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "root enter");' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "root leave");' + items: + - type: back + text: Back + - type: label + - type: menu + text: Submenu 1 + items: + - type: back + text: Back + - type: menu + text: Submenu 21 + items: + - type: back + text: Back + - type: command + text: Show Main + on_value: + then: + - display_menu.show_main: test_lcd_menu + - type: select + text: Enum Item + immediate_edit: true + select: test_select + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "select enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "select leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "select value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: number + text: Number + number: test_number + on_enter: + then: + lambda: 'ESP_LOGI("lcd_menu", "number enter: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_leave: + then: + lambda: 'ESP_LOGI("lcd_menu", "number leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "number value: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());' + - type: command + text: Hide + on_value: + then: + - display_menu.hide: test_lcd_menu + - type: switch + text: Switch + switch: my_switch + on_text: Bright + off_text: Dark + immediate_edit: false + on_value: + then: + lambda: 'ESP_LOGI("lcd_menu", "switch value: %s", it->get_value_text().c_str());' + - type: custom + text: !lambda 'return "Custom";' + value_lambda: 'return "Val";' + on_next: + then: + lambda: 'ESP_LOGI("lcd_menu", "custom next: %s", it->get_text().c_str());' + on_prev: + then: + lambda: 'ESP_LOGI("lcd_menu", "custom prev: %s", it->get_text().c_str());' diff --git a/tests/components/lcd_pcf8574/test.esp32-c3-idf.yaml b/tests/components/lcd_pcf8574/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..41eba26950 --- /dev/null +++ b/tests/components/lcd_pcf8574/test.esp32-c3-idf.yaml @@ -0,0 +1,22 @@ +i2c: + - id: i2c_lcd_pcf8574 + scl: 5 + sda: 4 + +display: + - platform: lcd_pcf8574 + dimensions: 18x4 + address: 0x3F + user_characters: + - position: 0 + data: + - 0b00000 + - 0b01010 + - 0b00000 + - 0b00100 + - 0b00100 + - 0b10001 + - 0b01110 + - 0b00000 + lambda: |- + it.print("Hello World!"); diff --git a/tests/components/lcd_pcf8574/test.esp32-c3.yaml b/tests/components/lcd_pcf8574/test.esp32-c3.yaml new file mode 100644 index 0000000000..41eba26950 --- /dev/null +++ b/tests/components/lcd_pcf8574/test.esp32-c3.yaml @@ -0,0 +1,22 @@ +i2c: + - id: i2c_lcd_pcf8574 + scl: 5 + sda: 4 + +display: + - platform: lcd_pcf8574 + dimensions: 18x4 + address: 0x3F + user_characters: + - position: 0 + data: + - 0b00000 + - 0b01010 + - 0b00000 + - 0b00100 + - 0b00100 + - 0b10001 + - 0b01110 + - 0b00000 + lambda: |- + it.print("Hello World!"); diff --git a/tests/components/lcd_pcf8574/test.esp32-idf.yaml b/tests/components/lcd_pcf8574/test.esp32-idf.yaml new file mode 100644 index 0000000000..9d7d475f30 --- /dev/null +++ b/tests/components/lcd_pcf8574/test.esp32-idf.yaml @@ -0,0 +1,22 @@ +i2c: + - id: i2c_lcd_pcf8574 + scl: 16 + sda: 17 + +display: + - platform: lcd_pcf8574 + dimensions: 18x4 + address: 0x3F + user_characters: + - position: 0 + data: + - 0b00000 + - 0b01010 + - 0b00000 + - 0b00100 + - 0b00100 + - 0b10001 + - 0b01110 + - 0b00000 + lambda: |- + it.print("Hello World!"); diff --git a/tests/components/lcd_pcf8574/test.esp32.yaml b/tests/components/lcd_pcf8574/test.esp32.yaml new file mode 100644 index 0000000000..9d7d475f30 --- /dev/null +++ b/tests/components/lcd_pcf8574/test.esp32.yaml @@ -0,0 +1,22 @@ +i2c: + - id: i2c_lcd_pcf8574 + scl: 16 + sda: 17 + +display: + - platform: lcd_pcf8574 + dimensions: 18x4 + address: 0x3F + user_characters: + - position: 0 + data: + - 0b00000 + - 0b01010 + - 0b00000 + - 0b00100 + - 0b00100 + - 0b10001 + - 0b01110 + - 0b00000 + lambda: |- + it.print("Hello World!"); diff --git a/tests/components/lcd_pcf8574/test.esp8266.yaml b/tests/components/lcd_pcf8574/test.esp8266.yaml new file mode 100644 index 0000000000..41eba26950 --- /dev/null +++ b/tests/components/lcd_pcf8574/test.esp8266.yaml @@ -0,0 +1,22 @@ +i2c: + - id: i2c_lcd_pcf8574 + scl: 5 + sda: 4 + +display: + - platform: lcd_pcf8574 + dimensions: 18x4 + address: 0x3F + user_characters: + - position: 0 + data: + - 0b00000 + - 0b01010 + - 0b00000 + - 0b00100 + - 0b00100 + - 0b10001 + - 0b01110 + - 0b00000 + lambda: |- + it.print("Hello World!"); diff --git a/tests/components/lcd_pcf8574/test.rp2040.yaml b/tests/components/lcd_pcf8574/test.rp2040.yaml new file mode 100644 index 0000000000..41eba26950 --- /dev/null +++ b/tests/components/lcd_pcf8574/test.rp2040.yaml @@ -0,0 +1,22 @@ +i2c: + - id: i2c_lcd_pcf8574 + scl: 5 + sda: 4 + +display: + - platform: lcd_pcf8574 + dimensions: 18x4 + address: 0x3F + user_characters: + - position: 0 + data: + - 0b00000 + - 0b01010 + - 0b00000 + - 0b00100 + - 0b00100 + - 0b10001 + - 0b01110 + - 0b00000 + lambda: |- + it.print("Hello World!"); diff --git a/tests/components/ld2410/test.esp32-c3-idf.yaml b/tests/components/ld2410/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..afcaa81b3e --- /dev/null +++ b/tests/components/ld2410/test.esp32-c3-idf.yaml @@ -0,0 +1,169 @@ +uart: + - id: uart_ld2410 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +ld2410: + id: my_ld2410 + +binary_sensor: + - platform: ld2410 + has_target: + name: presence + has_moving_target: + name: movement + has_still_target: + name: still + out_pin_presence_status: + name: out pin presence status + +button: + - platform: ld2410 + factory_reset: + name: factory reset + restart: + name: restart + query_params: + name: query params + +number: + - platform: ld2410 + light_threshold: + name: light threshold + timeout: + name: timeout + max_move_distance_gate: + name: max move distance gate + max_still_distance_gate: + name: max still distance gate + g0: + move_threshold: + name: g0 move threshold + still_threshold: + name: g0 still threshold + g1: + move_threshold: + name: g1 move threshold + still_threshold: + name: g1 still threshold + g2: + move_threshold: + name: g2 move threshold + still_threshold: + name: g2 still threshold + g3: + move_threshold: + name: g3 move threshold + still_threshold: + name: g3 still threshold + g4: + move_threshold: + name: g4 move threshold + still_threshold: + name: g4 still threshold + g5: + move_threshold: + name: g5 move threshold + still_threshold: + name: g5 still threshold + g6: + move_threshold: + name: g6 move threshold + still_threshold: + name: g6 still threshold + g7: + move_threshold: + name: g7 move threshold + still_threshold: + name: g7 still threshold + g8: + move_threshold: + name: g8 move threshold + still_threshold: + name: g8 still threshold + +select: + - platform: ld2410 + distance_resolution: + name: distance resolution + baud_rate: + name: baud rate + light_function: + name: light function + out_pin_level: + name: out ping level + +sensor: + - platform: ld2410 + light: + name: light + moving_distance: + name: Moving distance + still_distance: + name: Still Distance + moving_energy: + name: Move Energy + still_energy: + name: Still Energy + detection_distance: + name: Distance Detection + g0: + move_energy: + name: g0 move energy + still_energy: + name: g0 still energy + g1: + move_energy: + name: g1 move energy + still_energy: + name: g1 still energy + g2: + move_energy: + name: g2 move energy + still_energy: + name: g2 still energy + g3: + move_energy: + name: g3 move energy + still_energy: + name: g3 still energy + g4: + move_energy: + name: g4 move energy + still_energy: + name: g4 still energy + g5: + move_energy: + name: g5 move energy + still_energy: + name: g5 still energy + g6: + move_energy: + name: g6 move energy + still_energy: + name: g6 still energy + g7: + move_energy: + name: g7 move energy + still_energy: + name: g7 still energy + g8: + move_energy: + name: g8 move energy + still_energy: + name: g8 still energy + +switch: + - platform: ld2410 + engineering_mode: + name: control ld2410 engineering mode + bluetooth: + name: control ld2410 bluetooth + +text_sensor: + - platform: ld2410 + version: + name: presenece sensor version + mac_address: + name: presenece sensor mac address diff --git a/tests/components/ld2410/test.esp32-c3.yaml b/tests/components/ld2410/test.esp32-c3.yaml new file mode 100644 index 0000000000..afcaa81b3e --- /dev/null +++ b/tests/components/ld2410/test.esp32-c3.yaml @@ -0,0 +1,169 @@ +uart: + - id: uart_ld2410 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +ld2410: + id: my_ld2410 + +binary_sensor: + - platform: ld2410 + has_target: + name: presence + has_moving_target: + name: movement + has_still_target: + name: still + out_pin_presence_status: + name: out pin presence status + +button: + - platform: ld2410 + factory_reset: + name: factory reset + restart: + name: restart + query_params: + name: query params + +number: + - platform: ld2410 + light_threshold: + name: light threshold + timeout: + name: timeout + max_move_distance_gate: + name: max move distance gate + max_still_distance_gate: + name: max still distance gate + g0: + move_threshold: + name: g0 move threshold + still_threshold: + name: g0 still threshold + g1: + move_threshold: + name: g1 move threshold + still_threshold: + name: g1 still threshold + g2: + move_threshold: + name: g2 move threshold + still_threshold: + name: g2 still threshold + g3: + move_threshold: + name: g3 move threshold + still_threshold: + name: g3 still threshold + g4: + move_threshold: + name: g4 move threshold + still_threshold: + name: g4 still threshold + g5: + move_threshold: + name: g5 move threshold + still_threshold: + name: g5 still threshold + g6: + move_threshold: + name: g6 move threshold + still_threshold: + name: g6 still threshold + g7: + move_threshold: + name: g7 move threshold + still_threshold: + name: g7 still threshold + g8: + move_threshold: + name: g8 move threshold + still_threshold: + name: g8 still threshold + +select: + - platform: ld2410 + distance_resolution: + name: distance resolution + baud_rate: + name: baud rate + light_function: + name: light function + out_pin_level: + name: out ping level + +sensor: + - platform: ld2410 + light: + name: light + moving_distance: + name: Moving distance + still_distance: + name: Still Distance + moving_energy: + name: Move Energy + still_energy: + name: Still Energy + detection_distance: + name: Distance Detection + g0: + move_energy: + name: g0 move energy + still_energy: + name: g0 still energy + g1: + move_energy: + name: g1 move energy + still_energy: + name: g1 still energy + g2: + move_energy: + name: g2 move energy + still_energy: + name: g2 still energy + g3: + move_energy: + name: g3 move energy + still_energy: + name: g3 still energy + g4: + move_energy: + name: g4 move energy + still_energy: + name: g4 still energy + g5: + move_energy: + name: g5 move energy + still_energy: + name: g5 still energy + g6: + move_energy: + name: g6 move energy + still_energy: + name: g6 still energy + g7: + move_energy: + name: g7 move energy + still_energy: + name: g7 still energy + g8: + move_energy: + name: g8 move energy + still_energy: + name: g8 still energy + +switch: + - platform: ld2410 + engineering_mode: + name: control ld2410 engineering mode + bluetooth: + name: control ld2410 bluetooth + +text_sensor: + - platform: ld2410 + version: + name: presenece sensor version + mac_address: + name: presenece sensor mac address diff --git a/tests/components/ld2410/test.esp32-idf.yaml b/tests/components/ld2410/test.esp32-idf.yaml new file mode 100644 index 0000000000..48ed179d93 --- /dev/null +++ b/tests/components/ld2410/test.esp32-idf.yaml @@ -0,0 +1,169 @@ +uart: + - id: uart_ld2410 + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + +ld2410: + id: my_ld2410 + +binary_sensor: + - platform: ld2410 + has_target: + name: presence + has_moving_target: + name: movement + has_still_target: + name: still + out_pin_presence_status: + name: out pin presence status + +button: + - platform: ld2410 + factory_reset: + name: factory reset + restart: + name: restart + query_params: + name: query params + +number: + - platform: ld2410 + light_threshold: + name: light threshold + timeout: + name: timeout + max_move_distance_gate: + name: max move distance gate + max_still_distance_gate: + name: max still distance gate + g0: + move_threshold: + name: g0 move threshold + still_threshold: + name: g0 still threshold + g1: + move_threshold: + name: g1 move threshold + still_threshold: + name: g1 still threshold + g2: + move_threshold: + name: g2 move threshold + still_threshold: + name: g2 still threshold + g3: + move_threshold: + name: g3 move threshold + still_threshold: + name: g3 still threshold + g4: + move_threshold: + name: g4 move threshold + still_threshold: + name: g4 still threshold + g5: + move_threshold: + name: g5 move threshold + still_threshold: + name: g5 still threshold + g6: + move_threshold: + name: g6 move threshold + still_threshold: + name: g6 still threshold + g7: + move_threshold: + name: g7 move threshold + still_threshold: + name: g7 still threshold + g8: + move_threshold: + name: g8 move threshold + still_threshold: + name: g8 still threshold + +select: + - platform: ld2410 + distance_resolution: + name: distance resolution + baud_rate: + name: baud rate + light_function: + name: light function + out_pin_level: + name: out ping level + +sensor: + - platform: ld2410 + light: + name: light + moving_distance: + name: Moving distance + still_distance: + name: Still Distance + moving_energy: + name: Move Energy + still_energy: + name: Still Energy + detection_distance: + name: Distance Detection + g0: + move_energy: + name: g0 move energy + still_energy: + name: g0 still energy + g1: + move_energy: + name: g1 move energy + still_energy: + name: g1 still energy + g2: + move_energy: + name: g2 move energy + still_energy: + name: g2 still energy + g3: + move_energy: + name: g3 move energy + still_energy: + name: g3 still energy + g4: + move_energy: + name: g4 move energy + still_energy: + name: g4 still energy + g5: + move_energy: + name: g5 move energy + still_energy: + name: g5 still energy + g6: + move_energy: + name: g6 move energy + still_energy: + name: g6 still energy + g7: + move_energy: + name: g7 move energy + still_energy: + name: g7 still energy + g8: + move_energy: + name: g8 move energy + still_energy: + name: g8 still energy + +switch: + - platform: ld2410 + engineering_mode: + name: control ld2410 engineering mode + bluetooth: + name: control ld2410 bluetooth + +text_sensor: + - platform: ld2410 + version: + name: presenece sensor version + mac_address: + name: presenece sensor mac address diff --git a/tests/components/ld2410/test.esp32.yaml b/tests/components/ld2410/test.esp32.yaml new file mode 100644 index 0000000000..48ed179d93 --- /dev/null +++ b/tests/components/ld2410/test.esp32.yaml @@ -0,0 +1,169 @@ +uart: + - id: uart_ld2410 + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + +ld2410: + id: my_ld2410 + +binary_sensor: + - platform: ld2410 + has_target: + name: presence + has_moving_target: + name: movement + has_still_target: + name: still + out_pin_presence_status: + name: out pin presence status + +button: + - platform: ld2410 + factory_reset: + name: factory reset + restart: + name: restart + query_params: + name: query params + +number: + - platform: ld2410 + light_threshold: + name: light threshold + timeout: + name: timeout + max_move_distance_gate: + name: max move distance gate + max_still_distance_gate: + name: max still distance gate + g0: + move_threshold: + name: g0 move threshold + still_threshold: + name: g0 still threshold + g1: + move_threshold: + name: g1 move threshold + still_threshold: + name: g1 still threshold + g2: + move_threshold: + name: g2 move threshold + still_threshold: + name: g2 still threshold + g3: + move_threshold: + name: g3 move threshold + still_threshold: + name: g3 still threshold + g4: + move_threshold: + name: g4 move threshold + still_threshold: + name: g4 still threshold + g5: + move_threshold: + name: g5 move threshold + still_threshold: + name: g5 still threshold + g6: + move_threshold: + name: g6 move threshold + still_threshold: + name: g6 still threshold + g7: + move_threshold: + name: g7 move threshold + still_threshold: + name: g7 still threshold + g8: + move_threshold: + name: g8 move threshold + still_threshold: + name: g8 still threshold + +select: + - platform: ld2410 + distance_resolution: + name: distance resolution + baud_rate: + name: baud rate + light_function: + name: light function + out_pin_level: + name: out ping level + +sensor: + - platform: ld2410 + light: + name: light + moving_distance: + name: Moving distance + still_distance: + name: Still Distance + moving_energy: + name: Move Energy + still_energy: + name: Still Energy + detection_distance: + name: Distance Detection + g0: + move_energy: + name: g0 move energy + still_energy: + name: g0 still energy + g1: + move_energy: + name: g1 move energy + still_energy: + name: g1 still energy + g2: + move_energy: + name: g2 move energy + still_energy: + name: g2 still energy + g3: + move_energy: + name: g3 move energy + still_energy: + name: g3 still energy + g4: + move_energy: + name: g4 move energy + still_energy: + name: g4 still energy + g5: + move_energy: + name: g5 move energy + still_energy: + name: g5 still energy + g6: + move_energy: + name: g6 move energy + still_energy: + name: g6 still energy + g7: + move_energy: + name: g7 move energy + still_energy: + name: g7 still energy + g8: + move_energy: + name: g8 move energy + still_energy: + name: g8 still energy + +switch: + - platform: ld2410 + engineering_mode: + name: control ld2410 engineering mode + bluetooth: + name: control ld2410 bluetooth + +text_sensor: + - platform: ld2410 + version: + name: presenece sensor version + mac_address: + name: presenece sensor mac address diff --git a/tests/components/ld2410/test.esp8266.yaml b/tests/components/ld2410/test.esp8266.yaml new file mode 100644 index 0000000000..afcaa81b3e --- /dev/null +++ b/tests/components/ld2410/test.esp8266.yaml @@ -0,0 +1,169 @@ +uart: + - id: uart_ld2410 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +ld2410: + id: my_ld2410 + +binary_sensor: + - platform: ld2410 + has_target: + name: presence + has_moving_target: + name: movement + has_still_target: + name: still + out_pin_presence_status: + name: out pin presence status + +button: + - platform: ld2410 + factory_reset: + name: factory reset + restart: + name: restart + query_params: + name: query params + +number: + - platform: ld2410 + light_threshold: + name: light threshold + timeout: + name: timeout + max_move_distance_gate: + name: max move distance gate + max_still_distance_gate: + name: max still distance gate + g0: + move_threshold: + name: g0 move threshold + still_threshold: + name: g0 still threshold + g1: + move_threshold: + name: g1 move threshold + still_threshold: + name: g1 still threshold + g2: + move_threshold: + name: g2 move threshold + still_threshold: + name: g2 still threshold + g3: + move_threshold: + name: g3 move threshold + still_threshold: + name: g3 still threshold + g4: + move_threshold: + name: g4 move threshold + still_threshold: + name: g4 still threshold + g5: + move_threshold: + name: g5 move threshold + still_threshold: + name: g5 still threshold + g6: + move_threshold: + name: g6 move threshold + still_threshold: + name: g6 still threshold + g7: + move_threshold: + name: g7 move threshold + still_threshold: + name: g7 still threshold + g8: + move_threshold: + name: g8 move threshold + still_threshold: + name: g8 still threshold + +select: + - platform: ld2410 + distance_resolution: + name: distance resolution + baud_rate: + name: baud rate + light_function: + name: light function + out_pin_level: + name: out ping level + +sensor: + - platform: ld2410 + light: + name: light + moving_distance: + name: Moving distance + still_distance: + name: Still Distance + moving_energy: + name: Move Energy + still_energy: + name: Still Energy + detection_distance: + name: Distance Detection + g0: + move_energy: + name: g0 move energy + still_energy: + name: g0 still energy + g1: + move_energy: + name: g1 move energy + still_energy: + name: g1 still energy + g2: + move_energy: + name: g2 move energy + still_energy: + name: g2 still energy + g3: + move_energy: + name: g3 move energy + still_energy: + name: g3 still energy + g4: + move_energy: + name: g4 move energy + still_energy: + name: g4 still energy + g5: + move_energy: + name: g5 move energy + still_energy: + name: g5 still energy + g6: + move_energy: + name: g6 move energy + still_energy: + name: g6 still energy + g7: + move_energy: + name: g7 move energy + still_energy: + name: g7 still energy + g8: + move_energy: + name: g8 move energy + still_energy: + name: g8 still energy + +switch: + - platform: ld2410 + engineering_mode: + name: control ld2410 engineering mode + bluetooth: + name: control ld2410 bluetooth + +text_sensor: + - platform: ld2410 + version: + name: presenece sensor version + mac_address: + name: presenece sensor mac address diff --git a/tests/components/ld2410/test.rp2040.yaml b/tests/components/ld2410/test.rp2040.yaml new file mode 100644 index 0000000000..afcaa81b3e --- /dev/null +++ b/tests/components/ld2410/test.rp2040.yaml @@ -0,0 +1,169 @@ +uart: + - id: uart_ld2410 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +ld2410: + id: my_ld2410 + +binary_sensor: + - platform: ld2410 + has_target: + name: presence + has_moving_target: + name: movement + has_still_target: + name: still + out_pin_presence_status: + name: out pin presence status + +button: + - platform: ld2410 + factory_reset: + name: factory reset + restart: + name: restart + query_params: + name: query params + +number: + - platform: ld2410 + light_threshold: + name: light threshold + timeout: + name: timeout + max_move_distance_gate: + name: max move distance gate + max_still_distance_gate: + name: max still distance gate + g0: + move_threshold: + name: g0 move threshold + still_threshold: + name: g0 still threshold + g1: + move_threshold: + name: g1 move threshold + still_threshold: + name: g1 still threshold + g2: + move_threshold: + name: g2 move threshold + still_threshold: + name: g2 still threshold + g3: + move_threshold: + name: g3 move threshold + still_threshold: + name: g3 still threshold + g4: + move_threshold: + name: g4 move threshold + still_threshold: + name: g4 still threshold + g5: + move_threshold: + name: g5 move threshold + still_threshold: + name: g5 still threshold + g6: + move_threshold: + name: g6 move threshold + still_threshold: + name: g6 still threshold + g7: + move_threshold: + name: g7 move threshold + still_threshold: + name: g7 still threshold + g8: + move_threshold: + name: g8 move threshold + still_threshold: + name: g8 still threshold + +select: + - platform: ld2410 + distance_resolution: + name: distance resolution + baud_rate: + name: baud rate + light_function: + name: light function + out_pin_level: + name: out ping level + +sensor: + - platform: ld2410 + light: + name: light + moving_distance: + name: Moving distance + still_distance: + name: Still Distance + moving_energy: + name: Move Energy + still_energy: + name: Still Energy + detection_distance: + name: Distance Detection + g0: + move_energy: + name: g0 move energy + still_energy: + name: g0 still energy + g1: + move_energy: + name: g1 move energy + still_energy: + name: g1 still energy + g2: + move_energy: + name: g2 move energy + still_energy: + name: g2 still energy + g3: + move_energy: + name: g3 move energy + still_energy: + name: g3 still energy + g4: + move_energy: + name: g4 move energy + still_energy: + name: g4 still energy + g5: + move_energy: + name: g5 move energy + still_energy: + name: g5 still energy + g6: + move_energy: + name: g6 move energy + still_energy: + name: g6 still energy + g7: + move_energy: + name: g7 move energy + still_energy: + name: g7 still energy + g8: + move_energy: + name: g8 move energy + still_energy: + name: g8 still energy + +switch: + - platform: ld2410 + engineering_mode: + name: control ld2410 engineering mode + bluetooth: + name: control ld2410 bluetooth + +text_sensor: + - platform: ld2410 + version: + name: presenece sensor version + mac_address: + name: presenece sensor mac address diff --git a/tests/components/ld2420/test.esp32-c3-idf.yaml b/tests/components/ld2420/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..5e0b9db1c2 --- /dev/null +++ b/tests/components/ld2420/test.esp32-c3-idf.yaml @@ -0,0 +1,132 @@ +uart: + - id: uart_ld2420 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +ld2420: + id: my_ld2420 + +binary_sensor: + - platform: ld2420 + has_target: + name: Presence + +button: + - platform: ld2420 + apply_config: + name: Apply Config + factory_reset: + name: Factory Reset + restart_module: + name: Restart Module + revert_config: + name: Undo Edits + +number: + - platform: ld2420 + presence_timeout: + name: Detection Presence Timeout + min_gate_distance: + name: Detection Gate Minimum + max_gate_distance: + name: Detection Gate Maximum + gate_move_sensitivity: + name: Move Calibration Sensitivity Factor + gate_still_sensitivity: + name: Still Calibration Sensitivity Factor + gate_0: + move_threshold: + name: Gate 0 Move Threshold + still_threshold: + name: Gate 0 Still Threshold + gate_1: + move_threshold: + name: Gate 1 Move Threshold + still_threshold: + name: Gate 1 Still Threshold + gate_2: + move_threshold: + name: Gate 2 Move Threshold + still_threshold: + name: Gate 2 Still Threshold + gate_3: + move_threshold: + name: Gate 3 Move Threshold + still_threshold: + name: Gate 3 Still Threshold + gate_4: + move_threshold: + name: Gate 4 Move Threshold + still_threshold: + name: Gate 4 Still Threshold + gate_5: + move_threshold: + name: Gate 5 Move Threshold + still_threshold: + name: Gate 5 Still Threshold + gate_6: + move_threshold: + name: Gate 6 Move Threshold + still_threshold: + name: Gate 6 Still Threshold + gate_7: + move_threshold: + name: Gate 7 Move Threshold + still_threshold: + name: Gate 7 Still Threshold + gate_8: + move_threshold: + name: Gate 8 Move Threshold + still_threshold: + name: Gate 8 Still Threshold + gate_9: + move_threshold: + name: Gate 9 Move Threshold + still_threshold: + name: Gate 9 Still Threshold + gate_10: + move_threshold: + name: Gate 10 Move Threshold + still_threshold: + name: Gate 10 Still Threshold + gate_11: + move_threshold: + name: Gate 11 Move Threshold + still_threshold: + name: Gate 11 Still Threshold + gate_12: + move_threshold: + name: Gate 12 Move Threshold + still_threshold: + name: Gate 12 Still Threshold + gate_13: + move_threshold: + name: Gate 13 Move Threshold + still_threshold: + name: Gate 13 Still Threshold + gate_14: + move_threshold: + name: Gate 14 Move Threshold + still_threshold: + name: Gate 14 Still Threshold + gate_15: + move_threshold: + name: Gate 15 Move Threshold + still_threshold: + name: Gate 15 Still Threshold + +select: + - platform: ld2420 + operating_mode: + name: Operating Mode + +sensor: + - platform: ld2420 + moving_distance: + name: "Moving distance (cm)" + +text_sensor: + - platform: ld2420 + fw_version: + name: LD2420 Firmware diff --git a/tests/components/ld2420/test.esp32-c3.yaml b/tests/components/ld2420/test.esp32-c3.yaml new file mode 100644 index 0000000000..5e0b9db1c2 --- /dev/null +++ b/tests/components/ld2420/test.esp32-c3.yaml @@ -0,0 +1,132 @@ +uart: + - id: uart_ld2420 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +ld2420: + id: my_ld2420 + +binary_sensor: + - platform: ld2420 + has_target: + name: Presence + +button: + - platform: ld2420 + apply_config: + name: Apply Config + factory_reset: + name: Factory Reset + restart_module: + name: Restart Module + revert_config: + name: Undo Edits + +number: + - platform: ld2420 + presence_timeout: + name: Detection Presence Timeout + min_gate_distance: + name: Detection Gate Minimum + max_gate_distance: + name: Detection Gate Maximum + gate_move_sensitivity: + name: Move Calibration Sensitivity Factor + gate_still_sensitivity: + name: Still Calibration Sensitivity Factor + gate_0: + move_threshold: + name: Gate 0 Move Threshold + still_threshold: + name: Gate 0 Still Threshold + gate_1: + move_threshold: + name: Gate 1 Move Threshold + still_threshold: + name: Gate 1 Still Threshold + gate_2: + move_threshold: + name: Gate 2 Move Threshold + still_threshold: + name: Gate 2 Still Threshold + gate_3: + move_threshold: + name: Gate 3 Move Threshold + still_threshold: + name: Gate 3 Still Threshold + gate_4: + move_threshold: + name: Gate 4 Move Threshold + still_threshold: + name: Gate 4 Still Threshold + gate_5: + move_threshold: + name: Gate 5 Move Threshold + still_threshold: + name: Gate 5 Still Threshold + gate_6: + move_threshold: + name: Gate 6 Move Threshold + still_threshold: + name: Gate 6 Still Threshold + gate_7: + move_threshold: + name: Gate 7 Move Threshold + still_threshold: + name: Gate 7 Still Threshold + gate_8: + move_threshold: + name: Gate 8 Move Threshold + still_threshold: + name: Gate 8 Still Threshold + gate_9: + move_threshold: + name: Gate 9 Move Threshold + still_threshold: + name: Gate 9 Still Threshold + gate_10: + move_threshold: + name: Gate 10 Move Threshold + still_threshold: + name: Gate 10 Still Threshold + gate_11: + move_threshold: + name: Gate 11 Move Threshold + still_threshold: + name: Gate 11 Still Threshold + gate_12: + move_threshold: + name: Gate 12 Move Threshold + still_threshold: + name: Gate 12 Still Threshold + gate_13: + move_threshold: + name: Gate 13 Move Threshold + still_threshold: + name: Gate 13 Still Threshold + gate_14: + move_threshold: + name: Gate 14 Move Threshold + still_threshold: + name: Gate 14 Still Threshold + gate_15: + move_threshold: + name: Gate 15 Move Threshold + still_threshold: + name: Gate 15 Still Threshold + +select: + - platform: ld2420 + operating_mode: + name: Operating Mode + +sensor: + - platform: ld2420 + moving_distance: + name: "Moving distance (cm)" + +text_sensor: + - platform: ld2420 + fw_version: + name: LD2420 Firmware diff --git a/tests/components/ld2420/test.esp32-idf.yaml b/tests/components/ld2420/test.esp32-idf.yaml new file mode 100644 index 0000000000..8c883664ec --- /dev/null +++ b/tests/components/ld2420/test.esp32-idf.yaml @@ -0,0 +1,132 @@ +uart: + - id: uart_ld2420 + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + +ld2420: + id: my_ld2420 + +binary_sensor: + - platform: ld2420 + has_target: + name: Presence + +button: + - platform: ld2420 + apply_config: + name: Apply Config + factory_reset: + name: Factory Reset + restart_module: + name: Restart Module + revert_config: + name: Undo Edits + +number: + - platform: ld2420 + presence_timeout: + name: Detection Presence Timeout + min_gate_distance: + name: Detection Gate Minimum + max_gate_distance: + name: Detection Gate Maximum + gate_move_sensitivity: + name: Move Calibration Sensitivity Factor + gate_still_sensitivity: + name: Still Calibration Sensitivity Factor + gate_0: + move_threshold: + name: Gate 0 Move Threshold + still_threshold: + name: Gate 0 Still Threshold + gate_1: + move_threshold: + name: Gate 1 Move Threshold + still_threshold: + name: Gate 1 Still Threshold + gate_2: + move_threshold: + name: Gate 2 Move Threshold + still_threshold: + name: Gate 2 Still Threshold + gate_3: + move_threshold: + name: Gate 3 Move Threshold + still_threshold: + name: Gate 3 Still Threshold + gate_4: + move_threshold: + name: Gate 4 Move Threshold + still_threshold: + name: Gate 4 Still Threshold + gate_5: + move_threshold: + name: Gate 5 Move Threshold + still_threshold: + name: Gate 5 Still Threshold + gate_6: + move_threshold: + name: Gate 6 Move Threshold + still_threshold: + name: Gate 6 Still Threshold + gate_7: + move_threshold: + name: Gate 7 Move Threshold + still_threshold: + name: Gate 7 Still Threshold + gate_8: + move_threshold: + name: Gate 8 Move Threshold + still_threshold: + name: Gate 8 Still Threshold + gate_9: + move_threshold: + name: Gate 9 Move Threshold + still_threshold: + name: Gate 9 Still Threshold + gate_10: + move_threshold: + name: Gate 10 Move Threshold + still_threshold: + name: Gate 10 Still Threshold + gate_11: + move_threshold: + name: Gate 11 Move Threshold + still_threshold: + name: Gate 11 Still Threshold + gate_12: + move_threshold: + name: Gate 12 Move Threshold + still_threshold: + name: Gate 12 Still Threshold + gate_13: + move_threshold: + name: Gate 13 Move Threshold + still_threshold: + name: Gate 13 Still Threshold + gate_14: + move_threshold: + name: Gate 14 Move Threshold + still_threshold: + name: Gate 14 Still Threshold + gate_15: + move_threshold: + name: Gate 15 Move Threshold + still_threshold: + name: Gate 15 Still Threshold + +select: + - platform: ld2420 + operating_mode: + name: Operating Mode + +sensor: + - platform: ld2420 + moving_distance: + name: "Moving distance (cm)" + +text_sensor: + - platform: ld2420 + fw_version: + name: LD2420 Firmware diff --git a/tests/components/ld2420/test.esp32.yaml b/tests/components/ld2420/test.esp32.yaml new file mode 100644 index 0000000000..8c883664ec --- /dev/null +++ b/tests/components/ld2420/test.esp32.yaml @@ -0,0 +1,132 @@ +uart: + - id: uart_ld2420 + tx_pin: 17 + rx_pin: 16 + baud_rate: 9600 + +ld2420: + id: my_ld2420 + +binary_sensor: + - platform: ld2420 + has_target: + name: Presence + +button: + - platform: ld2420 + apply_config: + name: Apply Config + factory_reset: + name: Factory Reset + restart_module: + name: Restart Module + revert_config: + name: Undo Edits + +number: + - platform: ld2420 + presence_timeout: + name: Detection Presence Timeout + min_gate_distance: + name: Detection Gate Minimum + max_gate_distance: + name: Detection Gate Maximum + gate_move_sensitivity: + name: Move Calibration Sensitivity Factor + gate_still_sensitivity: + name: Still Calibration Sensitivity Factor + gate_0: + move_threshold: + name: Gate 0 Move Threshold + still_threshold: + name: Gate 0 Still Threshold + gate_1: + move_threshold: + name: Gate 1 Move Threshold + still_threshold: + name: Gate 1 Still Threshold + gate_2: + move_threshold: + name: Gate 2 Move Threshold + still_threshold: + name: Gate 2 Still Threshold + gate_3: + move_threshold: + name: Gate 3 Move Threshold + still_threshold: + name: Gate 3 Still Threshold + gate_4: + move_threshold: + name: Gate 4 Move Threshold + still_threshold: + name: Gate 4 Still Threshold + gate_5: + move_threshold: + name: Gate 5 Move Threshold + still_threshold: + name: Gate 5 Still Threshold + gate_6: + move_threshold: + name: Gate 6 Move Threshold + still_threshold: + name: Gate 6 Still Threshold + gate_7: + move_threshold: + name: Gate 7 Move Threshold + still_threshold: + name: Gate 7 Still Threshold + gate_8: + move_threshold: + name: Gate 8 Move Threshold + still_threshold: + name: Gate 8 Still Threshold + gate_9: + move_threshold: + name: Gate 9 Move Threshold + still_threshold: + name: Gate 9 Still Threshold + gate_10: + move_threshold: + name: Gate 10 Move Threshold + still_threshold: + name: Gate 10 Still Threshold + gate_11: + move_threshold: + name: Gate 11 Move Threshold + still_threshold: + name: Gate 11 Still Threshold + gate_12: + move_threshold: + name: Gate 12 Move Threshold + still_threshold: + name: Gate 12 Still Threshold + gate_13: + move_threshold: + name: Gate 13 Move Threshold + still_threshold: + name: Gate 13 Still Threshold + gate_14: + move_threshold: + name: Gate 14 Move Threshold + still_threshold: + name: Gate 14 Still Threshold + gate_15: + move_threshold: + name: Gate 15 Move Threshold + still_threshold: + name: Gate 15 Still Threshold + +select: + - platform: ld2420 + operating_mode: + name: Operating Mode + +sensor: + - platform: ld2420 + moving_distance: + name: "Moving distance (cm)" + +text_sensor: + - platform: ld2420 + fw_version: + name: LD2420 Firmware diff --git a/tests/components/ld2420/test.esp8266.yaml b/tests/components/ld2420/test.esp8266.yaml new file mode 100644 index 0000000000..5e0b9db1c2 --- /dev/null +++ b/tests/components/ld2420/test.esp8266.yaml @@ -0,0 +1,132 @@ +uart: + - id: uart_ld2420 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +ld2420: + id: my_ld2420 + +binary_sensor: + - platform: ld2420 + has_target: + name: Presence + +button: + - platform: ld2420 + apply_config: + name: Apply Config + factory_reset: + name: Factory Reset + restart_module: + name: Restart Module + revert_config: + name: Undo Edits + +number: + - platform: ld2420 + presence_timeout: + name: Detection Presence Timeout + min_gate_distance: + name: Detection Gate Minimum + max_gate_distance: + name: Detection Gate Maximum + gate_move_sensitivity: + name: Move Calibration Sensitivity Factor + gate_still_sensitivity: + name: Still Calibration Sensitivity Factor + gate_0: + move_threshold: + name: Gate 0 Move Threshold + still_threshold: + name: Gate 0 Still Threshold + gate_1: + move_threshold: + name: Gate 1 Move Threshold + still_threshold: + name: Gate 1 Still Threshold + gate_2: + move_threshold: + name: Gate 2 Move Threshold + still_threshold: + name: Gate 2 Still Threshold + gate_3: + move_threshold: + name: Gate 3 Move Threshold + still_threshold: + name: Gate 3 Still Threshold + gate_4: + move_threshold: + name: Gate 4 Move Threshold + still_threshold: + name: Gate 4 Still Threshold + gate_5: + move_threshold: + name: Gate 5 Move Threshold + still_threshold: + name: Gate 5 Still Threshold + gate_6: + move_threshold: + name: Gate 6 Move Threshold + still_threshold: + name: Gate 6 Still Threshold + gate_7: + move_threshold: + name: Gate 7 Move Threshold + still_threshold: + name: Gate 7 Still Threshold + gate_8: + move_threshold: + name: Gate 8 Move Threshold + still_threshold: + name: Gate 8 Still Threshold + gate_9: + move_threshold: + name: Gate 9 Move Threshold + still_threshold: + name: Gate 9 Still Threshold + gate_10: + move_threshold: + name: Gate 10 Move Threshold + still_threshold: + name: Gate 10 Still Threshold + gate_11: + move_threshold: + name: Gate 11 Move Threshold + still_threshold: + name: Gate 11 Still Threshold + gate_12: + move_threshold: + name: Gate 12 Move Threshold + still_threshold: + name: Gate 12 Still Threshold + gate_13: + move_threshold: + name: Gate 13 Move Threshold + still_threshold: + name: Gate 13 Still Threshold + gate_14: + move_threshold: + name: Gate 14 Move Threshold + still_threshold: + name: Gate 14 Still Threshold + gate_15: + move_threshold: + name: Gate 15 Move Threshold + still_threshold: + name: Gate 15 Still Threshold + +select: + - platform: ld2420 + operating_mode: + name: Operating Mode + +sensor: + - platform: ld2420 + moving_distance: + name: "Moving distance (cm)" + +text_sensor: + - platform: ld2420 + fw_version: + name: LD2420 Firmware diff --git a/tests/components/ld2420/test.rp2040.yaml b/tests/components/ld2420/test.rp2040.yaml new file mode 100644 index 0000000000..5e0b9db1c2 --- /dev/null +++ b/tests/components/ld2420/test.rp2040.yaml @@ -0,0 +1,132 @@ +uart: + - id: uart_ld2420 + tx_pin: 4 + rx_pin: 5 + baud_rate: 9600 + +ld2420: + id: my_ld2420 + +binary_sensor: + - platform: ld2420 + has_target: + name: Presence + +button: + - platform: ld2420 + apply_config: + name: Apply Config + factory_reset: + name: Factory Reset + restart_module: + name: Restart Module + revert_config: + name: Undo Edits + +number: + - platform: ld2420 + presence_timeout: + name: Detection Presence Timeout + min_gate_distance: + name: Detection Gate Minimum + max_gate_distance: + name: Detection Gate Maximum + gate_move_sensitivity: + name: Move Calibration Sensitivity Factor + gate_still_sensitivity: + name: Still Calibration Sensitivity Factor + gate_0: + move_threshold: + name: Gate 0 Move Threshold + still_threshold: + name: Gate 0 Still Threshold + gate_1: + move_threshold: + name: Gate 1 Move Threshold + still_threshold: + name: Gate 1 Still Threshold + gate_2: + move_threshold: + name: Gate 2 Move Threshold + still_threshold: + name: Gate 2 Still Threshold + gate_3: + move_threshold: + name: Gate 3 Move Threshold + still_threshold: + name: Gate 3 Still Threshold + gate_4: + move_threshold: + name: Gate 4 Move Threshold + still_threshold: + name: Gate 4 Still Threshold + gate_5: + move_threshold: + name: Gate 5 Move Threshold + still_threshold: + name: Gate 5 Still Threshold + gate_6: + move_threshold: + name: Gate 6 Move Threshold + still_threshold: + name: Gate 6 Still Threshold + gate_7: + move_threshold: + name: Gate 7 Move Threshold + still_threshold: + name: Gate 7 Still Threshold + gate_8: + move_threshold: + name: Gate 8 Move Threshold + still_threshold: + name: Gate 8 Still Threshold + gate_9: + move_threshold: + name: Gate 9 Move Threshold + still_threshold: + name: Gate 9 Still Threshold + gate_10: + move_threshold: + name: Gate 10 Move Threshold + still_threshold: + name: Gate 10 Still Threshold + gate_11: + move_threshold: + name: Gate 11 Move Threshold + still_threshold: + name: Gate 11 Still Threshold + gate_12: + move_threshold: + name: Gate 12 Move Threshold + still_threshold: + name: Gate 12 Still Threshold + gate_13: + move_threshold: + name: Gate 13 Move Threshold + still_threshold: + name: Gate 13 Still Threshold + gate_14: + move_threshold: + name: Gate 14 Move Threshold + still_threshold: + name: Gate 14 Still Threshold + gate_15: + move_threshold: + name: Gate 15 Move Threshold + still_threshold: + name: Gate 15 Still Threshold + +select: + - platform: ld2420 + operating_mode: + name: Operating Mode + +sensor: + - platform: ld2420 + moving_distance: + name: "Moving distance (cm)" + +text_sensor: + - platform: ld2420 + fw_version: + name: LD2420 Firmware diff --git a/tests/components/ledc/test.esp32-c3-idf.yaml b/tests/components/ledc/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..70352b4519 --- /dev/null +++ b/tests/components/ledc/test.esp32-c3-idf.yaml @@ -0,0 +1,11 @@ +esphome: + on_boot: + then: + - output.ledc.set_frequency: + id: test_ledc + frequency: 100Hz + +output: + - platform: ledc + id: test_ledc + pin: 4 diff --git a/tests/components/ledc/test.esp32-c3.yaml b/tests/components/ledc/test.esp32-c3.yaml new file mode 100644 index 0000000000..70352b4519 --- /dev/null +++ b/tests/components/ledc/test.esp32-c3.yaml @@ -0,0 +1,11 @@ +esphome: + on_boot: + then: + - output.ledc.set_frequency: + id: test_ledc + frequency: 100Hz + +output: + - platform: ledc + id: test_ledc + pin: 4 diff --git a/tests/components/ledc/test.esp32-idf.yaml b/tests/components/ledc/test.esp32-idf.yaml new file mode 100644 index 0000000000..70352b4519 --- /dev/null +++ b/tests/components/ledc/test.esp32-idf.yaml @@ -0,0 +1,11 @@ +esphome: + on_boot: + then: + - output.ledc.set_frequency: + id: test_ledc + frequency: 100Hz + +output: + - platform: ledc + id: test_ledc + pin: 4 diff --git a/tests/components/ledc/test.esp32.yaml b/tests/components/ledc/test.esp32.yaml new file mode 100644 index 0000000000..70352b4519 --- /dev/null +++ b/tests/components/ledc/test.esp32.yaml @@ -0,0 +1,11 @@ +esphome: + on_boot: + then: + - output.ledc.set_frequency: + id: test_ledc + frequency: 100Hz + +output: + - platform: ledc + id: test_ledc + pin: 4 diff --git a/tests/components/light/test.esp32-c3-idf.yaml b/tests/components/light/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..8e1709838a --- /dev/null +++ b/tests/components/light/test.esp32-c3-idf.yaml @@ -0,0 +1,132 @@ +esphome: + on_boot: + then: + - light.toggle: test_binary_light + - light.turn_off: test_rgb_light + - light.turn_on: + id: test_rgb_light + brightness: 100% + red: 100% + green: 100% + blue: 1.0 + - light.control: + id: test_monochromatic_light + state: on + - light.dim_relative: + id: test_monochromatic_light + relative_brightness: 5% + +output: + - platform: gpio + id: test_binary + pin: 0 + - platform: ledc + id: test_ledc_1 + pin: 1 + - platform: ledc + id: test_ledc_2 + pin: 2 + - platform: ledc + id: test_ledc_3 + pin: 3 + - platform: ledc + id: test_ledc_4 + pin: 4 + - platform: ledc + id: test_ledc_5 + pin: 5 + +light: + - platform: binary + id: test_binary_light + name: Binary Light + output: test_binary + effects: + - strobe: + on_state: + - logger.log: Binary light state changed + - platform: monochromatic + id: test_monochromatic_light + name: Monochromatic Light + output: test_ledc_1 + gamma_correct: 2.8 + default_transition_length: 2s + effects: + - strobe: + - flicker: + - flicker: + name: My Flicker + alpha: 98% + intensity: 1.5% + - lambda: + name: My Custom Effect + update_interval: 1s + lambda: |- + static int state = 0; + state += 1; + if (state == 4) + state = 0; + - pulse: + transition_length: 10s + update_interval: 20s + min_brightness: 10% + max_brightness: 90% + - pulse: + name: pulse2 + transition_length: + on_length: 10s + off_length: 5s + update_interval: 15s + min_brightness: 10% + max_brightness: 90% + - platform: rgb + id: test_rgb_light + name: RGB Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + - platform: rgbw + id: test_rgbw_light + name: RGBW Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + white: test_ledc_4 + color_interlock: true + - platform: rgbww + id: test_rgbww_light + name: RGBWW Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + cold_white: test_ledc_4 + warm_white: test_ledc_5 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + color_interlock: true + - platform: rgbct + id: test_rgbct_light + name: RGBCT Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + color_temperature: test_ledc_4 + white_brightness: test_ledc_5 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + color_interlock: true + - platform: cwww + id: test_cwww_light + name: CWWW Light + cold_white: test_ledc_1 + warm_white: test_ledc_2 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + constant_brightness: true + - platform: color_temperature + id: test_color_temperature_light + name: CT Light + color_temperature: test_ledc_1 + brightness: test_ledc_2 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds diff --git a/tests/components/light/test.esp32-c3.yaml b/tests/components/light/test.esp32-c3.yaml new file mode 100644 index 0000000000..8e1709838a --- /dev/null +++ b/tests/components/light/test.esp32-c3.yaml @@ -0,0 +1,132 @@ +esphome: + on_boot: + then: + - light.toggle: test_binary_light + - light.turn_off: test_rgb_light + - light.turn_on: + id: test_rgb_light + brightness: 100% + red: 100% + green: 100% + blue: 1.0 + - light.control: + id: test_monochromatic_light + state: on + - light.dim_relative: + id: test_monochromatic_light + relative_brightness: 5% + +output: + - platform: gpio + id: test_binary + pin: 0 + - platform: ledc + id: test_ledc_1 + pin: 1 + - platform: ledc + id: test_ledc_2 + pin: 2 + - platform: ledc + id: test_ledc_3 + pin: 3 + - platform: ledc + id: test_ledc_4 + pin: 4 + - platform: ledc + id: test_ledc_5 + pin: 5 + +light: + - platform: binary + id: test_binary_light + name: Binary Light + output: test_binary + effects: + - strobe: + on_state: + - logger.log: Binary light state changed + - platform: monochromatic + id: test_monochromatic_light + name: Monochromatic Light + output: test_ledc_1 + gamma_correct: 2.8 + default_transition_length: 2s + effects: + - strobe: + - flicker: + - flicker: + name: My Flicker + alpha: 98% + intensity: 1.5% + - lambda: + name: My Custom Effect + update_interval: 1s + lambda: |- + static int state = 0; + state += 1; + if (state == 4) + state = 0; + - pulse: + transition_length: 10s + update_interval: 20s + min_brightness: 10% + max_brightness: 90% + - pulse: + name: pulse2 + transition_length: + on_length: 10s + off_length: 5s + update_interval: 15s + min_brightness: 10% + max_brightness: 90% + - platform: rgb + id: test_rgb_light + name: RGB Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + - platform: rgbw + id: test_rgbw_light + name: RGBW Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + white: test_ledc_4 + color_interlock: true + - platform: rgbww + id: test_rgbww_light + name: RGBWW Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + cold_white: test_ledc_4 + warm_white: test_ledc_5 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + color_interlock: true + - platform: rgbct + id: test_rgbct_light + name: RGBCT Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + color_temperature: test_ledc_4 + white_brightness: test_ledc_5 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + color_interlock: true + - platform: cwww + id: test_cwww_light + name: CWWW Light + cold_white: test_ledc_1 + warm_white: test_ledc_2 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + constant_brightness: true + - platform: color_temperature + id: test_color_temperature_light + name: CT Light + color_temperature: test_ledc_1 + brightness: test_ledc_2 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds diff --git a/tests/components/light/test.esp32-idf.yaml b/tests/components/light/test.esp32-idf.yaml new file mode 100644 index 0000000000..7e5718d8d4 --- /dev/null +++ b/tests/components/light/test.esp32-idf.yaml @@ -0,0 +1,132 @@ +esphome: + on_boot: + then: + - light.toggle: test_binary_light + - light.turn_off: test_rgb_light + - light.turn_on: + id: test_rgb_light + brightness: 100% + red: 100% + green: 100% + blue: 1.0 + - light.control: + id: test_monochromatic_light + state: on + - light.dim_relative: + id: test_monochromatic_light + relative_brightness: 5% + +output: + - platform: gpio + id: test_binary + pin: 12 + - platform: ledc + id: test_ledc_1 + pin: 13 + - platform: ledc + id: test_ledc_2 + pin: 14 + - platform: ledc + id: test_ledc_3 + pin: 15 + - platform: ledc + id: test_ledc_4 + pin: 16 + - platform: ledc + id: test_ledc_5 + pin: 17 + +light: + - platform: binary + id: test_binary_light + name: Binary Light + output: test_binary + effects: + - strobe: + on_state: + - logger.log: Binary light state changed + - platform: monochromatic + id: test_monochromatic_light + name: Monochromatic Light + output: test_ledc_1 + gamma_correct: 2.8 + default_transition_length: 2s + effects: + - strobe: + - flicker: + - flicker: + name: My Flicker + alpha: 98% + intensity: 1.5% + - lambda: + name: My Custom Effect + update_interval: 1s + lambda: |- + static int state = 0; + state += 1; + if (state == 4) + state = 0; + - pulse: + transition_length: 10s + update_interval: 20s + min_brightness: 10% + max_brightness: 90% + - pulse: + name: pulse2 + transition_length: + on_length: 10s + off_length: 5s + update_interval: 15s + min_brightness: 10% + max_brightness: 90% + - platform: rgb + id: test_rgb_light + name: RGB Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + - platform: rgbw + id: test_rgbw_light + name: RGBW Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + white: test_ledc_4 + color_interlock: true + - platform: rgbww + id: test_rgbww_light + name: RGBWW Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + cold_white: test_ledc_4 + warm_white: test_ledc_5 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + color_interlock: true + - platform: rgbct + id: test_rgbct_light + name: RGBCT Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + color_temperature: test_ledc_4 + white_brightness: test_ledc_5 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + color_interlock: true + - platform: cwww + id: test_cwww_light + name: CWWW Light + cold_white: test_ledc_1 + warm_white: test_ledc_2 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + constant_brightness: true + - platform: color_temperature + id: test_color_temperature_light + name: CT Light + color_temperature: test_ledc_1 + brightness: test_ledc_2 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds diff --git a/tests/components/light/test.esp32.yaml b/tests/components/light/test.esp32.yaml new file mode 100644 index 0000000000..7e5718d8d4 --- /dev/null +++ b/tests/components/light/test.esp32.yaml @@ -0,0 +1,132 @@ +esphome: + on_boot: + then: + - light.toggle: test_binary_light + - light.turn_off: test_rgb_light + - light.turn_on: + id: test_rgb_light + brightness: 100% + red: 100% + green: 100% + blue: 1.0 + - light.control: + id: test_monochromatic_light + state: on + - light.dim_relative: + id: test_monochromatic_light + relative_brightness: 5% + +output: + - platform: gpio + id: test_binary + pin: 12 + - platform: ledc + id: test_ledc_1 + pin: 13 + - platform: ledc + id: test_ledc_2 + pin: 14 + - platform: ledc + id: test_ledc_3 + pin: 15 + - platform: ledc + id: test_ledc_4 + pin: 16 + - platform: ledc + id: test_ledc_5 + pin: 17 + +light: + - platform: binary + id: test_binary_light + name: Binary Light + output: test_binary + effects: + - strobe: + on_state: + - logger.log: Binary light state changed + - platform: monochromatic + id: test_monochromatic_light + name: Monochromatic Light + output: test_ledc_1 + gamma_correct: 2.8 + default_transition_length: 2s + effects: + - strobe: + - flicker: + - flicker: + name: My Flicker + alpha: 98% + intensity: 1.5% + - lambda: + name: My Custom Effect + update_interval: 1s + lambda: |- + static int state = 0; + state += 1; + if (state == 4) + state = 0; + - pulse: + transition_length: 10s + update_interval: 20s + min_brightness: 10% + max_brightness: 90% + - pulse: + name: pulse2 + transition_length: + on_length: 10s + off_length: 5s + update_interval: 15s + min_brightness: 10% + max_brightness: 90% + - platform: rgb + id: test_rgb_light + name: RGB Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + - platform: rgbw + id: test_rgbw_light + name: RGBW Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + white: test_ledc_4 + color_interlock: true + - platform: rgbww + id: test_rgbww_light + name: RGBWW Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + cold_white: test_ledc_4 + warm_white: test_ledc_5 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + color_interlock: true + - platform: rgbct + id: test_rgbct_light + name: RGBCT Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + color_temperature: test_ledc_4 + white_brightness: test_ledc_5 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + color_interlock: true + - platform: cwww + id: test_cwww_light + name: CWWW Light + cold_white: test_ledc_1 + warm_white: test_ledc_2 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + constant_brightness: true + - platform: color_temperature + id: test_color_temperature_light + name: CT Light + color_temperature: test_ledc_1 + brightness: test_ledc_2 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds diff --git a/tests/components/light/test.esp8266.yaml b/tests/components/light/test.esp8266.yaml new file mode 100644 index 0000000000..4611fb374a --- /dev/null +++ b/tests/components/light/test.esp8266.yaml @@ -0,0 +1,132 @@ +esphome: + on_boot: + then: + - light.toggle: test_binary_light + - light.turn_off: test_rgb_light + - light.turn_on: + id: test_rgb_light + brightness: 100% + red: 100% + green: 100% + blue: 1.0 + - light.control: + id: test_monochromatic_light + state: on + - light.dim_relative: + id: test_monochromatic_light + relative_brightness: 5% + +output: + - platform: gpio + id: test_binary + pin: 4 + - platform: esp8266_pwm + id: test_ledc_1 + pin: 12 + - platform: esp8266_pwm + id: test_ledc_2 + pin: 13 + - platform: esp8266_pwm + id: test_ledc_3 + pin: 14 + - platform: esp8266_pwm + id: test_ledc_4 + pin: 15 + - platform: esp8266_pwm + id: test_ledc_5 + pin: 16 + +light: + - platform: binary + id: test_binary_light + name: Binary Light + output: test_binary + effects: + - strobe: + on_state: + - logger.log: Binary light state changed + - platform: monochromatic + id: test_monochromatic_light + name: Monochromatic Light + output: test_ledc_1 + gamma_correct: 2.8 + default_transition_length: 2s + effects: + - strobe: + - flicker: + - flicker: + name: My Flicker + alpha: 98% + intensity: 1.5% + - lambda: + name: My Custom Effect + update_interval: 1s + lambda: |- + static int state = 0; + state += 1; + if (state == 4) + state = 0; + - pulse: + transition_length: 10s + update_interval: 20s + min_brightness: 10% + max_brightness: 90% + - pulse: + name: pulse2 + transition_length: + on_length: 10s + off_length: 5s + update_interval: 15s + min_brightness: 10% + max_brightness: 90% + - platform: rgb + id: test_rgb_light + name: RGB Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + - platform: rgbw + id: test_rgbw_light + name: RGBW Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + white: test_ledc_4 + color_interlock: true + - platform: rgbww + id: test_rgbww_light + name: RGBWW Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + cold_white: test_ledc_4 + warm_white: test_ledc_5 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + color_interlock: true + - platform: rgbct + id: test_rgbct_light + name: RGBCT Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + color_temperature: test_ledc_4 + white_brightness: test_ledc_5 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + color_interlock: true + - platform: cwww + id: test_cwww_light + name: CWWW Light + cold_white: test_ledc_1 + warm_white: test_ledc_2 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + constant_brightness: true + - platform: color_temperature + id: test_color_temperature_light + name: CT Light + color_temperature: test_ledc_1 + brightness: test_ledc_2 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds diff --git a/tests/components/light/test.rp2040.yaml b/tests/components/light/test.rp2040.yaml new file mode 100644 index 0000000000..0215a17e71 --- /dev/null +++ b/tests/components/light/test.rp2040.yaml @@ -0,0 +1,132 @@ +esphome: + on_boot: + then: + - light.toggle: test_binary_light + - light.turn_off: test_rgb_light + - light.turn_on: + id: test_rgb_light + brightness: 100% + red: 100% + green: 100% + blue: 1.0 + - light.control: + id: test_monochromatic_light + state: on + - light.dim_relative: + id: test_monochromatic_light + relative_brightness: 5% + +output: + - platform: gpio + id: test_binary + pin: 0 + - platform: rp2040_pwm + id: test_ledc_1 + pin: 1 + - platform: rp2040_pwm + id: test_ledc_2 + pin: 2 + - platform: rp2040_pwm + id: test_ledc_3 + pin: 3 + - platform: rp2040_pwm + id: test_ledc_4 + pin: 4 + - platform: rp2040_pwm + id: test_ledc_5 + pin: 5 + +light: + - platform: binary + id: test_binary_light + name: Binary Light + output: test_binary + effects: + - strobe: + on_state: + - logger.log: Binary light state changed + - platform: monochromatic + id: test_monochromatic_light + name: Monochromatic Light + output: test_ledc_1 + gamma_correct: 2.8 + default_transition_length: 2s + effects: + - strobe: + - flicker: + - flicker: + name: My Flicker + alpha: 98% + intensity: 1.5% + - lambda: + name: My Custom Effect + update_interval: 1s + lambda: |- + static int state = 0; + state += 1; + if (state == 4) + state = 0; + - pulse: + transition_length: 10s + update_interval: 20s + min_brightness: 10% + max_brightness: 90% + - pulse: + name: pulse2 + transition_length: + on_length: 10s + off_length: 5s + update_interval: 15s + min_brightness: 10% + max_brightness: 90% + - platform: rgb + id: test_rgb_light + name: RGB Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + - platform: rgbw + id: test_rgbw_light + name: RGBW Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + white: test_ledc_4 + color_interlock: true + - platform: rgbww + id: test_rgbww_light + name: RGBWW Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + cold_white: test_ledc_4 + warm_white: test_ledc_5 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + color_interlock: true + - platform: rgbct + id: test_rgbct_light + name: RGBCT Light + red: test_ledc_1 + green: test_ledc_2 + blue: test_ledc_3 + color_temperature: test_ledc_4 + white_brightness: test_ledc_5 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + color_interlock: true + - platform: cwww + id: test_cwww_light + name: CWWW Light + cold_white: test_ledc_1 + warm_white: test_ledc_2 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds + constant_brightness: true + - platform: color_temperature + id: test_color_temperature_light + name: CT Light + color_temperature: test_ledc_1 + brightness: test_ledc_2 + cold_white_color_temperature: 153 mireds + warm_white_color_temperature: 500 mireds diff --git a/tests/components/lightwaverf/test.esp8266.yaml b/tests/components/lightwaverf/test.esp8266.yaml new file mode 100644 index 0000000000..8f983a3cca --- /dev/null +++ b/tests/components/lightwaverf/test.esp8266.yaml @@ -0,0 +1,13 @@ +lightwaverf: + read_pin: 5 + write_pin: 4 + +button: + - platform: template + name: "Turn off sofa" + id: light_off_ceiling_sofa + on_press: + lightwaverf.send_raw: + code: [0x04, 0x00, 0x00, 0x00, 0x0f, 0x03, 0x0d, 0x09, 0x08, 0x08] + name: "Sofa" + repeat: 1 diff --git a/tests/components/lilygo_t5_47/test.esp32-c3-idf.yaml b/tests/components/lilygo_t5_47/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..41e81103ac --- /dev/null +++ b/tests/components/lilygo_t5_47/test.esp32-c3-idf.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_lilygo_t5_47 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: lilygo_t5_47 + id: lilygo_touchscreen + interrupt_pin: 6 + display: ssd1306_display + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/lilygo_t5_47/test.esp32-c3.yaml b/tests/components/lilygo_t5_47/test.esp32-c3.yaml new file mode 100644 index 0000000000..41e81103ac --- /dev/null +++ b/tests/components/lilygo_t5_47/test.esp32-c3.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_lilygo_t5_47 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: lilygo_t5_47 + id: lilygo_touchscreen + interrupt_pin: 6 + display: ssd1306_display + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/lilygo_t5_47/test.esp32-idf.yaml b/tests/components/lilygo_t5_47/test.esp32-idf.yaml new file mode 100644 index 0000000000..35eb3df022 --- /dev/null +++ b/tests/components/lilygo_t5_47/test.esp32-idf.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_lilygo_t5_47 + scl: 16 + sda: 17 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: lilygo_t5_47 + id: lilygo_touchscreen + interrupt_pin: 14 + display: ssd1306_display + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/lilygo_t5_47/test.esp32.yaml b/tests/components/lilygo_t5_47/test.esp32.yaml new file mode 100644 index 0000000000..35eb3df022 --- /dev/null +++ b/tests/components/lilygo_t5_47/test.esp32.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_lilygo_t5_47 + scl: 16 + sda: 17 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 13 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: lilygo_t5_47 + id: lilygo_touchscreen + interrupt_pin: 14 + display: ssd1306_display + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/lilygo_t5_47/test.esp8266.yaml b/tests/components/lilygo_t5_47/test.esp8266.yaml new file mode 100644 index 0000000000..766c492b12 --- /dev/null +++ b/tests/components/lilygo_t5_47/test.esp8266.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_lilygo_t5_47 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: lilygo_t5_47 + id: lilygo_touchscreen + interrupt_pin: 12 + display: ssd1306_display + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/lilygo_t5_47/test.rp2040.yaml b/tests/components/lilygo_t5_47/test.rp2040.yaml new file mode 100644 index 0000000000..41e81103ac --- /dev/null +++ b/tests/components/lilygo_t5_47/test.rp2040.yaml @@ -0,0 +1,24 @@ +i2c: + - id: i2c_lilygo_t5_47 + scl: 5 + sda: 4 + +display: + - platform: ssd1306_i2c + id: ssd1306_display + model: SSD1306_128X64 + reset_pin: 3 + pages: + - id: page1 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); + +touchscreen: + - platform: lilygo_t5_47 + id: lilygo_touchscreen + interrupt_pin: 6 + display: ssd1306_display + on_touch: + - logger.log: + format: Touch at (%d, %d) + args: [touch.x, touch.y] diff --git a/tests/components/lock/test.esp32-c3-idf.yaml b/tests/components/lock/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..82297a3da4 --- /dev/null +++ b/tests/components/lock/test.esp32-c3-idf.yaml @@ -0,0 +1,36 @@ +esphome: + on_boot: + then: + - lock.lock: test_lock1 + - lock.unlock: test_lock1 + - lock.open: test_lock1 + +output: + - platform: gpio + id: test_binary + pin: 4 + +lock: + - platform: template + id: test_lock1 + name: Template Lock + lambda: |- + if (millis() > 10000) { + return LOCK_STATE_LOCKED; + } else { + return LOCK_STATE_UNLOCKED; + } + optimistic: true + assumed_state: false + on_unlock: + - lock.template.publish: + id: test_lock1 + state: !lambda "return LOCK_STATE_UNLOCKED;" + on_lock: + - lock.template.publish: + id: test_lock1 + state: !lambda "return LOCK_STATE_LOCKED;" + - platform: output + name: Generic Output Lock + id: test_lock2 + output: test_binary diff --git a/tests/components/lock/test.esp32-c3.yaml b/tests/components/lock/test.esp32-c3.yaml new file mode 100644 index 0000000000..82297a3da4 --- /dev/null +++ b/tests/components/lock/test.esp32-c3.yaml @@ -0,0 +1,36 @@ +esphome: + on_boot: + then: + - lock.lock: test_lock1 + - lock.unlock: test_lock1 + - lock.open: test_lock1 + +output: + - platform: gpio + id: test_binary + pin: 4 + +lock: + - platform: template + id: test_lock1 + name: Template Lock + lambda: |- + if (millis() > 10000) { + return LOCK_STATE_LOCKED; + } else { + return LOCK_STATE_UNLOCKED; + } + optimistic: true + assumed_state: false + on_unlock: + - lock.template.publish: + id: test_lock1 + state: !lambda "return LOCK_STATE_UNLOCKED;" + on_lock: + - lock.template.publish: + id: test_lock1 + state: !lambda "return LOCK_STATE_LOCKED;" + - platform: output + name: Generic Output Lock + id: test_lock2 + output: test_binary diff --git a/tests/components/lock/test.esp32-idf.yaml b/tests/components/lock/test.esp32-idf.yaml new file mode 100644 index 0000000000..82297a3da4 --- /dev/null +++ b/tests/components/lock/test.esp32-idf.yaml @@ -0,0 +1,36 @@ +esphome: + on_boot: + then: + - lock.lock: test_lock1 + - lock.unlock: test_lock1 + - lock.open: test_lock1 + +output: + - platform: gpio + id: test_binary + pin: 4 + +lock: + - platform: template + id: test_lock1 + name: Template Lock + lambda: |- + if (millis() > 10000) { + return LOCK_STATE_LOCKED; + } else { + return LOCK_STATE_UNLOCKED; + } + optimistic: true + assumed_state: false + on_unlock: + - lock.template.publish: + id: test_lock1 + state: !lambda "return LOCK_STATE_UNLOCKED;" + on_lock: + - lock.template.publish: + id: test_lock1 + state: !lambda "return LOCK_STATE_LOCKED;" + - platform: output + name: Generic Output Lock + id: test_lock2 + output: test_binary diff --git a/tests/components/lock/test.esp32.yaml b/tests/components/lock/test.esp32.yaml new file mode 100644 index 0000000000..82297a3da4 --- /dev/null +++ b/tests/components/lock/test.esp32.yaml @@ -0,0 +1,36 @@ +esphome: + on_boot: + then: + - lock.lock: test_lock1 + - lock.unlock: test_lock1 + - lock.open: test_lock1 + +output: + - platform: gpio + id: test_binary + pin: 4 + +lock: + - platform: template + id: test_lock1 + name: Template Lock + lambda: |- + if (millis() > 10000) { + return LOCK_STATE_LOCKED; + } else { + return LOCK_STATE_UNLOCKED; + } + optimistic: true + assumed_state: false + on_unlock: + - lock.template.publish: + id: test_lock1 + state: !lambda "return LOCK_STATE_UNLOCKED;" + on_lock: + - lock.template.publish: + id: test_lock1 + state: !lambda "return LOCK_STATE_LOCKED;" + - platform: output + name: Generic Output Lock + id: test_lock2 + output: test_binary diff --git a/tests/components/lock/test.esp8266.yaml b/tests/components/lock/test.esp8266.yaml new file mode 100644 index 0000000000..82297a3da4 --- /dev/null +++ b/tests/components/lock/test.esp8266.yaml @@ -0,0 +1,36 @@ +esphome: + on_boot: + then: + - lock.lock: test_lock1 + - lock.unlock: test_lock1 + - lock.open: test_lock1 + +output: + - platform: gpio + id: test_binary + pin: 4 + +lock: + - platform: template + id: test_lock1 + name: Template Lock + lambda: |- + if (millis() > 10000) { + return LOCK_STATE_LOCKED; + } else { + return LOCK_STATE_UNLOCKED; + } + optimistic: true + assumed_state: false + on_unlock: + - lock.template.publish: + id: test_lock1 + state: !lambda "return LOCK_STATE_UNLOCKED;" + on_lock: + - lock.template.publish: + id: test_lock1 + state: !lambda "return LOCK_STATE_LOCKED;" + - platform: output + name: Generic Output Lock + id: test_lock2 + output: test_binary diff --git a/tests/components/lock/test.rp2040.yaml b/tests/components/lock/test.rp2040.yaml new file mode 100644 index 0000000000..82297a3da4 --- /dev/null +++ b/tests/components/lock/test.rp2040.yaml @@ -0,0 +1,36 @@ +esphome: + on_boot: + then: + - lock.lock: test_lock1 + - lock.unlock: test_lock1 + - lock.open: test_lock1 + +output: + - platform: gpio + id: test_binary + pin: 4 + +lock: + - platform: template + id: test_lock1 + name: Template Lock + lambda: |- + if (millis() > 10000) { + return LOCK_STATE_LOCKED; + } else { + return LOCK_STATE_UNLOCKED; + } + optimistic: true + assumed_state: false + on_unlock: + - lock.template.publish: + id: test_lock1 + state: !lambda "return LOCK_STATE_UNLOCKED;" + on_lock: + - lock.template.publish: + id: test_lock1 + state: !lambda "return LOCK_STATE_LOCKED;" + - platform: output + name: Generic Output Lock + id: test_lock2 + output: test_binary diff --git a/tests/components/logger/test.esp32-c3-idf.yaml b/tests/components/logger/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..70b485daac --- /dev/null +++ b/tests/components/logger/test.esp32-c3-idf.yaml @@ -0,0 +1,7 @@ +esphome: + on_boot: + then: + - logger.log: Hello world + +logger: + level: DEBUG diff --git a/tests/components/logger/test.esp32-c3.yaml b/tests/components/logger/test.esp32-c3.yaml new file mode 100644 index 0000000000..70b485daac --- /dev/null +++ b/tests/components/logger/test.esp32-c3.yaml @@ -0,0 +1,7 @@ +esphome: + on_boot: + then: + - logger.log: Hello world + +logger: + level: DEBUG diff --git a/tests/components/logger/test.esp32-idf.yaml b/tests/components/logger/test.esp32-idf.yaml new file mode 100644 index 0000000000..70b485daac --- /dev/null +++ b/tests/components/logger/test.esp32-idf.yaml @@ -0,0 +1,7 @@ +esphome: + on_boot: + then: + - logger.log: Hello world + +logger: + level: DEBUG diff --git a/tests/components/logger/test.esp32.yaml b/tests/components/logger/test.esp32.yaml new file mode 100644 index 0000000000..70b485daac --- /dev/null +++ b/tests/components/logger/test.esp32.yaml @@ -0,0 +1,7 @@ +esphome: + on_boot: + then: + - logger.log: Hello world + +logger: + level: DEBUG diff --git a/tests/components/logger/test.esp8266.yaml b/tests/components/logger/test.esp8266.yaml new file mode 100644 index 0000000000..70b485daac --- /dev/null +++ b/tests/components/logger/test.esp8266.yaml @@ -0,0 +1,7 @@ +esphome: + on_boot: + then: + - logger.log: Hello world + +logger: + level: DEBUG diff --git a/tests/components/logger/test.rp2040.yaml b/tests/components/logger/test.rp2040.yaml new file mode 100644 index 0000000000..70b485daac --- /dev/null +++ b/tests/components/logger/test.rp2040.yaml @@ -0,0 +1,7 @@ +esphome: + on_boot: + then: + - logger.log: Hello world + +logger: + level: DEBUG diff --git a/tests/components/ltr390/test.esp32-c3-idf.yaml b/tests/components/ltr390/test.esp32-c3-idf.yaml new file mode 100644 index 0000000000..fee0f37ce1 --- /dev/null +++ b/tests/components/ltr390/test.esp32-c3-idf.yaml @@ -0,0 +1,20 @@ +i2c: + - id: i2c_ltr390 + scl: 5 + sda: 4 + +sensor: + - platform: ltr390 + uv: + name: LTR390 UV + uv_index: + name: LTR390 UVI + light: + name: LTR390 Light + ambient_light: + name: LTR390 ALS + gain: X3 + resolution: 18 + window_correction_factor: 1.0 + address: 0x53 + update_interval: 60s diff --git a/tests/components/ltr390/test.esp32-c3.yaml b/tests/components/ltr390/test.esp32-c3.yaml new file mode 100644 index 0000000000..fee0f37ce1 --- /dev/null +++ b/tests/components/ltr390/test.esp32-c3.yaml @@ -0,0 +1,20 @@ +i2c: + - id: i2c_ltr390 + scl: 5 + sda: 4 + +sensor: + - platform: ltr390 + uv: + name: LTR390 UV + uv_index: + name: LTR390 UVI + light: + name: LTR390 Light + ambient_light: + name: LTR390 ALS + gain: X3 + resolution: 18 + window_correction_factor: 1.0 + address: 0x53 + update_interval: 60s diff --git a/tests/components/ltr390/test.esp32-idf.yaml b/tests/components/ltr390/test.esp32-idf.yaml new file mode 100644 index 0000000000..9786c7dac3 --- /dev/null +++ b/tests/components/ltr390/test.esp32-idf.yaml @@ -0,0 +1,20 @@ +i2c: + - id: i2c_ltr390 + scl: 16 + sda: 17 + +sensor: + - platform: ltr390 + uv: + name: LTR390 UV + uv_index: + name: LTR390 UVI + light: + name: LTR390 Light + ambient_light: + name: LTR390 ALS + gain: X3 + resolution: 18 + window_correction_factor: 1.0 + address: 0x53 + update_interval: 60s diff --git a/tests/components/ltr390/test.esp32.yaml b/tests/components/ltr390/test.esp32.yaml new file mode 100644 index 0000000000..9786c7dac3 --- /dev/null +++ b/tests/components/ltr390/test.esp32.yaml @@ -0,0 +1,20 @@ +i2c: + - id: i2c_ltr390 + scl: 16 + sda: 17 + +sensor: + - platform: ltr390 + uv: + name: LTR390 UV + uv_index: + name: LTR390 UVI + light: + name: LTR390 Light + ambient_light: + name: LTR390 ALS + gain: X3 + resolution: 18 + window_correction_factor: 1.0 + address: 0x53 + update_interval: 60s diff --git a/tests/components/ltr390/test.esp8266.yaml b/tests/components/ltr390/test.esp8266.yaml new file mode 100644 index 0000000000..fee0f37ce1 --- /dev/null +++ b/tests/components/ltr390/test.esp8266.yaml @@ -0,0 +1,20 @@ +i2c: + - id: i2c_ltr390 + scl: 5 + sda: 4 + +sensor: + - platform: ltr390 + uv: + name: LTR390 UV + uv_index: + name: LTR390 UVI + light: + name: LTR390 Light + ambient_light: + name: LTR390 ALS + gain: X3 + resolution: 18 + window_correction_factor: 1.0 + address: 0x53 + update_interval: 60s diff --git a/tests/components/ltr390/test.rp2040.yaml b/tests/components/ltr390/test.rp2040.yaml new file mode 100644 index 0000000000..fee0f37ce1 --- /dev/null +++ b/tests/components/ltr390/test.rp2040.yaml @@ -0,0 +1,20 @@ +i2c: + - id: i2c_ltr390 + scl: 5 + sda: 4 + +sensor: + - platform: ltr390 + uv: + name: LTR390 UV + uv_index: + name: LTR390 UVI + light: + name: LTR390 Light + ambient_light: + name: LTR390 ALS + gain: X3 + resolution: 18 + window_correction_factor: 1.0 + address: 0x53 + update_interval: 60s From 6b7f9b15ea52ba15a48f37e22e70c6a49dbdc8d7 Mon Sep 17 00:00:00 2001 From: MagicBear Date: Thu, 28 Mar 2024 02:56:19 +0800 Subject: [PATCH 169/189] feat: Add Daikin ARC (tested on Daikin ARC472A62) (#6429) --- CODEOWNERS | 1 + esphome/components/daikin_arc/__init__.py | 1 + esphome/components/daikin_arc/climate.py | 18 + esphome/components/daikin_arc/daikin_arc.cpp | 487 ++++++++++++++++++ esphome/components/daikin_arc/daikin_arc.h | 76 +++ tests/components/daikin_arc/test.esp32.yaml | 19 + tests/components/daikin_arc/test.esp8266.yaml | 19 + 7 files changed, 621 insertions(+) create mode 100644 esphome/components/daikin_arc/__init__.py create mode 100644 esphome/components/daikin_arc/climate.py create mode 100644 esphome/components/daikin_arc/daikin_arc.cpp create mode 100644 esphome/components/daikin_arc/daikin_arc.h create mode 100644 tests/components/daikin_arc/test.esp32.yaml create mode 100644 tests/components/daikin_arc/test.esp8266.yaml diff --git a/CODEOWNERS b/CODEOWNERS index d6ec3843a5..7c1f7ff70b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -87,6 +87,7 @@ esphome/components/cst816/* @clydebarrow esphome/components/ct_clamp/* @jesserockz esphome/components/current_based/* @djwmarcx esphome/components/dac7678/* @NickB1 +esphome/components/daikin_arc/* @MagicBear esphome/components/daikin_brc/* @hagak esphome/components/daly_bms/* @s1lvi0 esphome/components/dashboard_import/* @esphome/core diff --git a/esphome/components/daikin_arc/__init__.py b/esphome/components/daikin_arc/__init__.py new file mode 100644 index 0000000000..f9164fb02b --- /dev/null +++ b/esphome/components/daikin_arc/__init__.py @@ -0,0 +1 @@ +CODEOWNERS = ["@MagicBear"] diff --git a/esphome/components/daikin_arc/climate.py b/esphome/components/daikin_arc/climate.py new file mode 100644 index 0000000000..51f253e9cb --- /dev/null +++ b/esphome/components/daikin_arc/climate.py @@ -0,0 +1,18 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import climate_ir +from esphome.const import CONF_ID + +AUTO_LOAD = ["climate_ir"] + +daikin_arc_ns = cg.esphome_ns.namespace("daikin_arc") +DaikinArcClimate = daikin_arc_ns.class_("DaikinArcClimate", climate_ir.ClimateIR) + +CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend( + {cv.GenerateID(): cv.declare_id(DaikinArcClimate)} +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await climate_ir.register_climate_ir(var, config) diff --git a/esphome/components/daikin_arc/daikin_arc.cpp b/esphome/components/daikin_arc/daikin_arc.cpp new file mode 100644 index 0000000000..f806463d00 --- /dev/null +++ b/esphome/components/daikin_arc/daikin_arc.cpp @@ -0,0 +1,487 @@ +#include "daikin_arc.h" + +#include + +#include "esphome/components/remote_base/remote_base.h" +#include "esphome/core/log.h" + +namespace esphome { +namespace daikin_arc { + +static const char *const TAG = "daikin.climate"; + +void DaikinArcClimate::setup() { + climate_ir::ClimateIR::setup(); + + // Never send nan to HA + if (std::isnan(this->target_humidity)) + this->target_humidity = 0; + if (std::isnan(this->current_temperature)) + this->current_temperature = 0; + if (std::isnan(this->current_humidity)) + this->current_humidity = 0; +} + +void DaikinArcClimate::transmit_query_() { + uint8_t remote_header[8] = {0x11, 0xDA, 0x27, 0x00, 0x84, 0x87, 0x20, 0x00}; + + // Calculate checksum + for (int i = 0; i < sizeof(remote_header) - 1; i++) { + remote_header[sizeof(remote_header) - 1] += remote_header[i]; + } + + auto transmit = this->transmitter_->transmit(); + auto *data = transmit.get_data(); + data->set_carrier_frequency(DAIKIN_IR_FREQUENCY); + + data->mark(DAIKIN_ARC_PRE_MARK); + data->space(DAIKIN_ARC_PRE_SPACE); + + data->mark(DAIKIN_HEADER_MARK); + data->space(DAIKIN_HEADER_SPACE); + + for (uint8_t i : remote_header) { + for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask + data->mark(DAIKIN_BIT_MARK); + bool bit = i & mask; + data->space(bit ? DAIKIN_ONE_SPACE : DAIKIN_ZERO_SPACE); + } + } + data->mark(DAIKIN_BIT_MARK); + data->space(0); + + transmit.perform(); +} + +void DaikinArcClimate::transmit_state() { + // 0x11, 0xDA, 0x27, 0x00, 0xC5, 0x00, 0x00, 0xD7, 0x11, 0xDA, 0x27, 0x00, + // 0x42, 0x49, 0x05, 0xA2, + uint8_t remote_header[20] = {0x11, 0xDA, 0x27, 0x00, 0x02, 0xd0, 0x02, 0x03, 0x80, 0x03, 0x82, 0x30, 0x41, 0x1f, 0x82, + 0xf4, + /* とつど */ + /* 0x13 */ + 0x00, 0x24, 0x00, 0x00}; + + // 05 0 [1:3]MODE 1 [OFF TMR] [ON TMR] Power + // 06-07 TEMP + // 08 [0:3] SPEED [4:7] Swing + // 09 00 + // 10 00 + // 11, 12: timer + // 13 [0:6] 0000000 [7] POWERMODE + // 14 0a + // 15 c4 + // 16 [0:3] 8 00 [6:7] SENSOR WIND = 11 / NORMAL = 00 + // 17 24 + + uint8_t remote_state[19] = { + 0x11, 0xDA, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x60, 0x00, 0x0a, 0xC4, + /* MODE TEMP HUMD FANH FANL + パワフル音声応答 */ + /* ON + 0x01入 0x0a */ + /* OF + 0x00切 0x02 */ + 0x80, 0x24, 0x00 + /* センサー風 */ + /* ON 0x83 */ + /* OF 0x80 */ + }; + + remote_state[5] = this->operation_mode_() | 0x08; + remote_state[6] = this->temperature_(); + remote_state[7] = this->humidity_(); + static uint8_t last_humidity = 0x66; + if (remote_state[7] != last_humidity && this->mode != climate::CLIMATE_MODE_OFF) { + ESP_LOGD(TAG, "Set Humditiy: %d, %d\n", (int) this->target_humidity, (int) remote_state[7]); + remote_header[9] |= 0x10; + last_humidity = remote_state[7]; + } + uint16_t fan_speed = this->fan_speed_(); + remote_state[8] = fan_speed >> 8; + remote_state[9] = fan_speed & 0xff; + + // Calculate checksum + for (int i = 0; i < sizeof(remote_header) - 1; i++) { + remote_header[sizeof(remote_header) - 1] += remote_header[i]; + } + + // Calculate checksum + for (int i = 0; i < DAIKIN_STATE_FRAME_SIZE - 1; i++) { + remote_state[DAIKIN_STATE_FRAME_SIZE - 1] += remote_state[i]; + } + + auto transmit = this->transmitter_->transmit(); + auto *data = transmit.get_data(); + data->set_carrier_frequency(DAIKIN_IR_FREQUENCY); + + data->mark(DAIKIN_ARC_PRE_MARK); + data->space(DAIKIN_ARC_PRE_SPACE); + + data->mark(DAIKIN_HEADER_MARK); + data->space(DAIKIN_HEADER_SPACE); + + for (uint8_t i : remote_header) { + for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask + data->mark(DAIKIN_BIT_MARK); + bool bit = i & mask; + data->space(bit ? DAIKIN_ONE_SPACE : DAIKIN_ZERO_SPACE); + } + } + data->mark(DAIKIN_BIT_MARK); + data->space(DAIKIN_MESSAGE_SPACE); + + data->mark(DAIKIN_HEADER_MARK); + data->space(DAIKIN_HEADER_SPACE); + + for (uint8_t i : remote_state) { + for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask + data->mark(DAIKIN_BIT_MARK); + bool bit = i & mask; + data->space(bit ? DAIKIN_ONE_SPACE : DAIKIN_ZERO_SPACE); + } + } + data->mark(DAIKIN_BIT_MARK); + data->space(0); + + transmit.perform(); +} + +uint8_t DaikinArcClimate::operation_mode_() { + uint8_t operating_mode = DAIKIN_MODE_ON; + switch (this->mode) { + case climate::CLIMATE_MODE_COOL: + operating_mode |= DAIKIN_MODE_COOL; + break; + case climate::CLIMATE_MODE_DRY: + operating_mode |= DAIKIN_MODE_DRY; + break; + case climate::CLIMATE_MODE_HEAT: + operating_mode |= DAIKIN_MODE_HEAT; + break; + case climate::CLIMATE_MODE_HEAT_COOL: + operating_mode |= DAIKIN_MODE_AUTO; + break; + case climate::CLIMATE_MODE_FAN_ONLY: + operating_mode |= DAIKIN_MODE_FAN; + break; + case climate::CLIMATE_MODE_OFF: + default: + operating_mode = DAIKIN_MODE_OFF; + break; + } + + return operating_mode; +} + +uint16_t DaikinArcClimate::fan_speed_() { + uint16_t fan_speed; + switch (this->fan_mode.value()) { + case climate::CLIMATE_FAN_LOW: + fan_speed = DAIKIN_FAN_1 << 8; + break; + case climate::CLIMATE_FAN_MEDIUM: + fan_speed = DAIKIN_FAN_3 << 8; + break; + case climate::CLIMATE_FAN_HIGH: + fan_speed = DAIKIN_FAN_5 << 8; + break; + case climate::CLIMATE_FAN_AUTO: + default: + fan_speed = DAIKIN_FAN_AUTO << 8; + } + + // If swing is enabled switch first 4 bits to 1111 + switch (this->swing_mode) { + case climate::CLIMATE_SWING_VERTICAL: + fan_speed |= 0x0F00; + break; + case climate::CLIMATE_SWING_HORIZONTAL: + fan_speed |= 0x000F; + break; + case climate::CLIMATE_SWING_BOTH: + fan_speed |= 0x0F0F; + break; + default: + break; + } + return fan_speed; +} + +uint8_t DaikinArcClimate::temperature_() { + // Force special temperatures depending on the mode + switch (this->mode) { + case climate::CLIMATE_MODE_FAN_ONLY: + return 0x32; + case climate::CLIMATE_MODE_HEAT_COOL: + case climate::CLIMATE_MODE_DRY: + return 0xc0; + default: + float new_temp = clamp(this->target_temperature, DAIKIN_TEMP_MIN, DAIKIN_TEMP_MAX); + uint8_t temperature = (uint8_t) floor(new_temp); + return temperature << 1 | (new_temp - temperature > 0 ? 0x01 : 0); + } +} + +uint8_t DaikinArcClimate::humidity_() { + if (this->target_humidity == 39) { + return 0; + } else if (this->target_humidity <= 40 || this->target_humidity == 44) { + return 40; + } else if (this->target_humidity <= 45 || this->target_humidity == 49) // 41 - 45 + { + return 45; + } else if (this->target_humidity <= 50 || this->target_humidity == 52) // 45 - 50 + { + return 50; + } else { + return 0xff; + } +} + +climate::ClimateTraits DaikinArcClimate::traits() { + climate::ClimateTraits traits = climate_ir::ClimateIR::traits(); + traits.set_supports_current_temperature(true); + traits.set_supports_current_humidity(false); + traits.set_supports_target_humidity(true); + traits.set_visual_min_humidity(38); + traits.set_visual_max_humidity(52); + return traits; +} + +bool DaikinArcClimate::parse_state_frame_(const uint8_t frame[]) { + uint8_t checksum = 0; + for (int i = 0; i < (DAIKIN_STATE_FRAME_SIZE - 1); i++) { + checksum += frame[i]; + } + if (frame[DAIKIN_STATE_FRAME_SIZE - 1] != checksum) { + ESP_LOGI(TAG, "checksum error"); + return false; + } + + char buf[DAIKIN_STATE_FRAME_SIZE * 3 + 1] = {0}; + for (size_t i = 0; i < DAIKIN_STATE_FRAME_SIZE; i++) { + sprintf(buf, "%s%02x ", buf, frame[i]); + } + ESP_LOGD(TAG, "FRAME %s", buf); + + uint8_t mode = frame[5]; + if (mode & DAIKIN_MODE_ON) { + switch (mode & 0xF0) { + case DAIKIN_MODE_COOL: + this->mode = climate::CLIMATE_MODE_COOL; + break; + case DAIKIN_MODE_DRY: + this->mode = climate::CLIMATE_MODE_DRY; + break; + case DAIKIN_MODE_HEAT: + this->mode = climate::CLIMATE_MODE_HEAT; + break; + case DAIKIN_MODE_AUTO: + this->mode = climate::CLIMATE_MODE_HEAT_COOL; + break; + case DAIKIN_MODE_FAN: + this->mode = climate::CLIMATE_MODE_FAN_ONLY; + break; + } + } else { + this->mode = climate::CLIMATE_MODE_OFF; + } + uint8_t temperature = frame[6]; + if (!(temperature & 0xC0)) { + this->target_temperature = temperature >> 1; + this->target_temperature += (temperature & 0x1) ? 0.5 : 0; + } + this->target_humidity = frame[7]; // 0, 40, 45, 50, 0xff + uint8_t fan_mode = frame[8]; + uint8_t swing_mode = frame[9]; + if (fan_mode & 0xF && swing_mode & 0xF) { + this->swing_mode = climate::CLIMATE_SWING_BOTH; + } else if (fan_mode & 0xF) { + this->swing_mode = climate::CLIMATE_SWING_VERTICAL; + } else if (swing_mode & 0xF) { + this->swing_mode = climate::CLIMATE_SWING_HORIZONTAL; + } else { + this->swing_mode = climate::CLIMATE_SWING_OFF; + } + switch (fan_mode & 0xF0) { + case DAIKIN_FAN_1: + case DAIKIN_FAN_2: + case DAIKIN_FAN_SILENT: + this->fan_mode = climate::CLIMATE_FAN_LOW; + break; + case DAIKIN_FAN_3: + this->fan_mode = climate::CLIMATE_FAN_MEDIUM; + break; + case DAIKIN_FAN_4: + case DAIKIN_FAN_5: + this->fan_mode = climate::CLIMATE_FAN_HIGH; + break; + case DAIKIN_FAN_AUTO: + this->fan_mode = climate::CLIMATE_FAN_AUTO; + break; + } + /* + 05 0 [1:3]MODE 1 [OFF TMR] [ON TMR] Power + 06-07 TEMP + 08 [0:3] SPEED [4:7] Swing + 09 00 + 10 00 + 11, 12: timer + 13 [0:6] 0000000 [7] POWERMODE + 14 0a + 15 c4 + 16 [0:3] 8 00 [6:7] SENSOR WIND = 11 / NORMAL = 00 + 17 24 + 05 06 07 08 09 10 11 12 13 14 15 16 17 18 + None FRAME 11 da 27 00 00 49 2e 00 b0 00 00 06 60 00 0a c4 80 24 11 + 1H FRAME 11 da 27 00 00 4d 2e 00 b0 00 00 c6 30 00 2a c4 80 24 c5 + 1H30 FRAME 11 da 27 00 00 4d 2e 00 b0 00 00 a6 32 00 2a c4 80 24 a7 + 2H FRAME 11 da 27 00 00 4d 2e 00 b0 00 00 86 34 00 2a c4 80 24 89 + + */ + this->publish_state(); + return true; +} + +bool DaikinArcClimate::on_receive(remote_base::RemoteReceiveData data) { + uint8_t state_frame[DAIKIN_STATE_FRAME_SIZE] = {}; + + bool valid_daikin_frame = false; + if (data.expect_item(DAIKIN_HEADER_MARK, DAIKIN_HEADER_SPACE)) { + valid_daikin_frame = true; + int bytes_count = data.size() / 2 / 8; + std::unique_ptr buf(new char[bytes_count * 3 + 1]); + buf[0] = '\0'; + for (size_t i = 0; i < bytes_count; i++) { + uint8_t byte = 0; + for (int8_t bit = 0; bit < 8; bit++) { + if (data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ONE_SPACE)) { + byte |= 1 << bit; + } else if (!data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ZERO_SPACE)) { + valid_daikin_frame = false; + break; + } + } + sprintf(buf.get(), "%s%02x ", buf.get(), byte); + } + ESP_LOGD(TAG, "WHOLE FRAME %s size: %d", buf.get(), data.size()); + } + if (!valid_daikin_frame) { + char sbuf[16 * 10 + 1]; + sbuf[0] = '\0'; + for (size_t j = 0; j < data.size(); j++) { + if ((j - 2) % 16 == 0) { + if (j > 0) { + ESP_LOGD(TAG, "DATA %04x: %s", (j - 16 > 0xffff ? 0 : j - 16), sbuf); + } + sbuf[0] = '\0'; + } + char type_ch = ' '; + // debug_tolerance = 25% + + if (DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_MARK) <= data[j] && data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_MARK)) + type_ch = 'P'; + if (DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_SPACE)) + type_ch = 'a'; + if (DAIKIN_DBG_LOWER(DAIKIN_HEADER_MARK) <= data[j] && data[j] <= DAIKIN_DBG_UPPER(DAIKIN_HEADER_MARK)) + type_ch = 'H'; + if (DAIKIN_DBG_LOWER(DAIKIN_HEADER_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_HEADER_SPACE)) + type_ch = 'h'; + if (DAIKIN_DBG_LOWER(DAIKIN_BIT_MARK) <= data[j] && data[j] <= DAIKIN_DBG_UPPER(DAIKIN_BIT_MARK)) + type_ch = 'B'; + if (DAIKIN_DBG_LOWER(DAIKIN_ONE_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ONE_SPACE)) + type_ch = '1'; + if (DAIKIN_DBG_LOWER(DAIKIN_ZERO_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ZERO_SPACE)) + type_ch = '0'; + + if (abs(data[j]) > 100000) { + sprintf(sbuf, "%s%-5d[%c] ", sbuf, data[j] > 0 ? 99999 : -99999, type_ch); + } else { + sprintf(sbuf, "%s%-5d[%c] ", sbuf, (int) (round(data[j] / 10.) * 10), type_ch); + } + if (j == data.size() - 1) { + ESP_LOGD(TAG, "DATA %04x: %s", (j - 8 > 0xffff ? 0 : j - 8), sbuf); + } + } + } + + data.reset(); + + if (!data.expect_item(DAIKIN_HEADER_MARK, DAIKIN_HEADER_SPACE)) { + ESP_LOGI(TAG, "non daikin_arc expect item"); + return false; + } + + for (uint8_t pos = 0; pos < DAIKIN_STATE_FRAME_SIZE; pos++) { + uint8_t byte = 0; + for (int8_t bit = 0; bit < 8; bit++) { + if (data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ONE_SPACE)) { + byte |= 1 << bit; + } else if (!data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ZERO_SPACE)) { + ESP_LOGI(TAG, "non daikin_arc expect item pos: %d", pos); + return false; + } + } + state_frame[pos] = byte; + if (pos == 0) { + // frame header + if (byte != 0x11) { + ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte); + return false; + } + } else if (pos == 1) { + // frame header + if (byte != 0xDA) { + ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte); + return false; + } + } else if (pos == 2) { + // frame header + if (byte != 0x27) { + ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte); + return false; + } + } else if (pos == 3) { // NOLINT(bugprone-branch-clone) + // frame header + if (byte != 0x00) { + ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte); + return false; + } + } else if (pos == 4) { + // frame type + if (byte != 0x00) { + ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte); + return false; + } + } else if (pos == 5) { + if (data.size() == 385) { + /* + 11 da 27 00 00 1a 0c 04 2c 21 61 07 00 07 0c 00 18 00 0e 3c 00 6c 1b 61 + Inside Temp + Outside Temp + Humdidity + + */ + this->current_temperature = state_frame[5]; // Inside temperature + // this->current_temperature = state_frame[6]; // Outside temperature + this->publish_state(); + return true; + } else if ((byte & 0x40) != 0x40) { + ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte); + return false; + } + } + } + return this->parse_state_frame_(state_frame); +} + +void DaikinArcClimate::control(const climate::ClimateCall &call) { + if (call.get_target_humidity().has_value()) { + this->target_humidity = *call.get_target_humidity(); + } + climate_ir::ClimateIR::control(call); +} + +} // namespace daikin_arc +} // namespace esphome diff --git a/esphome/components/daikin_arc/daikin_arc.h b/esphome/components/daikin_arc/daikin_arc.h new file mode 100644 index 0000000000..6cfffd4725 --- /dev/null +++ b/esphome/components/daikin_arc/daikin_arc.h @@ -0,0 +1,76 @@ +#pragma once + +#include "esphome/components/climate_ir/climate_ir.h" + +namespace esphome { +namespace daikin_arc { + +// Values for Daikin ARC43XXX IR Controllers +// Temperature +const uint8_t DAIKIN_TEMP_MIN = 10; // Celsius +const uint8_t DAIKIN_TEMP_MAX = 30; // Celsius + +// Modes +const uint8_t DAIKIN_MODE_AUTO = 0x00; +const uint8_t DAIKIN_MODE_COOL = 0x30; +const uint8_t DAIKIN_MODE_HEAT = 0x40; +const uint8_t DAIKIN_MODE_DRY = 0x20; +const uint8_t DAIKIN_MODE_FAN = 0x60; +const uint8_t DAIKIN_MODE_OFF = 0x00; +const uint8_t DAIKIN_MODE_ON = 0x01; + +// Fan Speed +const uint8_t DAIKIN_FAN_AUTO = 0xA0; +const uint8_t DAIKIN_FAN_SILENT = 0xB0; +const uint8_t DAIKIN_FAN_1 = 0x30; +const uint8_t DAIKIN_FAN_2 = 0x40; +const uint8_t DAIKIN_FAN_3 = 0x50; +const uint8_t DAIKIN_FAN_4 = 0x60; +const uint8_t DAIKIN_FAN_5 = 0x70; + +// IR Transmission +const uint32_t DAIKIN_IR_FREQUENCY = 38000; +const uint32_t DAIKIN_ARC_PRE_MARK = 9950; +const uint32_t DAIKIN_ARC_PRE_SPACE = 25100; +const uint32_t DAIKIN_HEADER_MARK = 3450; +const uint32_t DAIKIN_HEADER_SPACE = 1760; +const uint32_t DAIKIN_BIT_MARK = 400; +const uint32_t DAIKIN_ONE_SPACE = 1300; +const uint32_t DAIKIN_ZERO_SPACE = 480; +const uint32_t DAIKIN_MESSAGE_SPACE = 35000; + +const uint8_t DAIKIN_DBG_TOLERANCE = 25; +#define DAIKIN_DBG_LOWER(x) ((100 - DAIKIN_DBG_TOLERANCE) * (x) / 100U) +#define DAIKIN_DBG_UPPER(x) ((100 + DAIKIN_DBG_TOLERANCE) * (x) / 100U) + +// State Frame size +const uint8_t DAIKIN_STATE_FRAME_SIZE = 19; + +class DaikinArcClimate : public climate_ir::ClimateIR { + public: + DaikinArcClimate() + : climate_ir::ClimateIR(DAIKIN_TEMP_MIN, DAIKIN_TEMP_MAX, 0.5f, true, true, + {climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM, + climate::CLIMATE_FAN_HIGH}, + {climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL, + climate::CLIMATE_SWING_HORIZONTAL, climate::CLIMATE_SWING_BOTH}) {} + + void setup() override; + + protected: + void control(const climate::ClimateCall &call) override; + // Transmit via IR the state of this climate controller. + void transmit_query_(); + void transmit_state() override; + climate::ClimateTraits traits() override; + uint8_t operation_mode_(); + uint16_t fan_speed_(); + uint8_t temperature_(); + uint8_t humidity_(); + // Handle received IR Buffer + bool on_receive(remote_base::RemoteReceiveData data) override; + bool parse_state_frame_(const uint8_t frame[]); +}; + +} // namespace daikin_arc +} // namespace esphome diff --git a/tests/components/daikin_arc/test.esp32.yaml b/tests/components/daikin_arc/test.esp32.yaml new file mode 100644 index 0000000000..a8556e8576 --- /dev/null +++ b/tests/components/daikin_arc/test.esp32.yaml @@ -0,0 +1,19 @@ +remote_transmitter: + pin: 2 + carrier_duty_percent: 50% + id: tsvr + +remote_receiver: + id: rcvr + pin: + number: 27 + inverted: true + mode: + input: true + pullup: true + tolerance: 40% + +climate: + - platform: daikin_arc + name: "AC" + receiver_id: rcvr diff --git a/tests/components/daikin_arc/test.esp8266.yaml b/tests/components/daikin_arc/test.esp8266.yaml new file mode 100644 index 0000000000..abf1b34a6e --- /dev/null +++ b/tests/components/daikin_arc/test.esp8266.yaml @@ -0,0 +1,19 @@ +remote_transmitter: + pin: 5 + carrier_duty_percent: 50% + id: tsvr + +remote_receiver: + id: rcvr + pin: + number: 2 + inverted: true + mode: + input: true + pullup: true + tolerance: 40% + +climate: + - platform: daikin_arc + name: "AC" + receiver_id: rcvr From 0ff543ffe5c38509ab1f8cd7ddcaffb4617b1a99 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Thu, 28 Mar 2024 10:20:51 +1300 Subject: [PATCH 170/189] Disable truthy yamllint rule (#6442) --- .github/workflows/ci-api-proto.yml | 1 - .github/workflows/ci-docker.yml | 2 +- .github/workflows/ci.yml | 1 - .github/workflows/lock.yml | 1 - .github/workflows/needs-docs.yml | 1 - .github/workflows/release.yml | 1 - .github/workflows/stale.yml | 1 - .github/workflows/sync-device-classes.yml | 1 - .github/workflows/yaml-lint.yml | 1 - .yamllint | 1 + tests/components/lightwaverf/test.esp8266.yaml | 2 +- 11 files changed, 3 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-api-proto.yml b/.github/workflows/ci-api-proto.yml index 038ef3a587..0b2465d1aa 100644 --- a/.github/workflows/ci-api-proto.yml +++ b/.github/workflows/ci-api-proto.yml @@ -1,6 +1,5 @@ name: API Proto CI -# yamllint disable-line rule:truthy on: pull_request: paths: diff --git a/.github/workflows/ci-docker.yml b/.github/workflows/ci-docker.yml index 8a7b35fe33..f02efadf4d 100644 --- a/.github/workflows/ci-docker.yml +++ b/.github/workflows/ci-docker.yml @@ -2,7 +2,7 @@ name: CI for docker images # Only run when docker paths change -# yamllint disable-line rule:truthy + on: push: branches: [dev, beta, release] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 871f2e72c8..b0ac840972 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,6 @@ --- name: CI -# yamllint disable-line rule:truthy on: push: branches: [dev, beta, release] diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index e3d75f6d58..ee10f49f61 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -1,7 +1,6 @@ --- name: Lock -# yamllint disable-line rule:truthy on: schedule: - cron: "30 0 * * *" diff --git a/.github/workflows/needs-docs.yml b/.github/workflows/needs-docs.yml index 6a66e5769c..628b5cc5e3 100644 --- a/.github/workflows/needs-docs.yml +++ b/.github/workflows/needs-docs.yml @@ -1,6 +1,5 @@ name: Needs Docs -# yamllint disable-line rule:truthy on: pull_request: types: [labeled, unlabeled] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6b567b5b6f..16469c904b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,6 @@ --- name: Publish Release -# yamllint disable-line rule:truthy on: workflow_dispatch: release: diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 5f510ffe75..95f275e5a4 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,7 +1,6 @@ --- name: Stale -# yamllint disable-line rule:truthy on: schedule: - cron: "30 0 * * *" diff --git a/.github/workflows/sync-device-classes.yml b/.github/workflows/sync-device-classes.yml index 36fce2bbcf..3f8af4249a 100644 --- a/.github/workflows/sync-device-classes.yml +++ b/.github/workflows/sync-device-classes.yml @@ -1,7 +1,6 @@ --- name: Synchronise Device Classes from Home Assistant -# yamllint disable-line rule:truthy on: workflow_dispatch: schedule: diff --git a/.github/workflows/yaml-lint.yml b/.github/workflows/yaml-lint.yml index 3694436866..a3c1937e56 100644 --- a/.github/workflows/yaml-lint.yml +++ b/.github/workflows/yaml-lint.yml @@ -1,7 +1,6 @@ --- name: YAML lint -# yamllint disable-line rule:truthy on: push: branches: [dev, beta, release] diff --git a/.yamllint b/.yamllint index 9cd1482869..22e9237f61 100644 --- a/.yamllint +++ b/.yamllint @@ -16,3 +16,4 @@ rules: indent-sequences: true check-multi-line-strings: false line-length: disable + truthy: disable diff --git a/tests/components/lightwaverf/test.esp8266.yaml b/tests/components/lightwaverf/test.esp8266.yaml index 8f983a3cca..7ed8000271 100644 --- a/tests/components/lightwaverf/test.esp8266.yaml +++ b/tests/components/lightwaverf/test.esp8266.yaml @@ -8,6 +8,6 @@ button: id: light_off_ceiling_sofa on_press: lightwaverf.send_raw: - code: [0x04, 0x00, 0x00, 0x00, 0x0f, 0x03, 0x0d, 0x09, 0x08, 0x08] + code: [0x04, 0x00, 0x00, 0x00, 0x0f, 0x03, 0x0d, 0x09, 0x08, 0x08] name: "Sofa" repeat: 1 From 9194f7eb27f503e0f712d3e6407e48a16fc4ef99 Mon Sep 17 00:00:00 2001 From: Daniel Eisterhold Date: Wed, 27 Mar 2024 18:56:26 -0500 Subject: [PATCH 171/189] Add get_size method to QR Code header (#6430) --- esphome/components/qr_code/qr_code.cpp | 12 ++++++++++++ esphome/components/qr_code/qr_code.h | 2 ++ tests/components/qr_code/test.esp32-c3-idf.yaml | 7 +++++++ tests/components/qr_code/test.esp32-c3.yaml | 7 +++++++ tests/components/qr_code/test.esp32-idf.yaml | 7 +++++++ tests/components/qr_code/test.esp32.yaml | 7 +++++++ tests/components/qr_code/test.esp8266.yaml | 7 +++++++ tests/components/qr_code/test.rp2040.yaml | 7 +++++++ 8 files changed, 56 insertions(+) diff --git a/esphome/components/qr_code/qr_code.cpp b/esphome/components/qr_code/qr_code.cpp index aecf7628dc..b60e60a4b0 100644 --- a/esphome/components/qr_code/qr_code.cpp +++ b/esphome/components/qr_code/qr_code.cpp @@ -51,5 +51,17 @@ void QrCode::draw(display::Display *buff, uint16_t x_offset, uint16_t y_offset, } } } + +uint8_t QrCode::get_size() { + if (this->needs_update_) { + this->generate_qr_code(); + this->needs_update_ = false; + } + + uint8_t size = qrcodegen_getSize(this->qr_); + + return size; +} + } // namespace qr_code } // namespace esphome diff --git a/esphome/components/qr_code/qr_code.h b/esphome/components/qr_code/qr_code.h index d88e0aa09a..ab4c587b6d 100644 --- a/esphome/components/qr_code/qr_code.h +++ b/esphome/components/qr_code/qr_code.h @@ -24,6 +24,8 @@ class QrCode : public Component { void generate_qr_code(); + uint8_t get_size(); + protected: std::string value_; qrcodegen_Ecc ecc_; diff --git a/tests/components/qr_code/test.esp32-c3-idf.yaml b/tests/components/qr_code/test.esp32-c3-idf.yaml index 3e875c026c..63973b1aa2 100644 --- a/tests/components/qr_code/test.esp32-c3-idf.yaml +++ b/tests/components/qr_code/test.esp32-c3-idf.yaml @@ -11,6 +11,13 @@ display: cs_pin: 8 dc_pin: 9 reset_pin: 10 + lambda: |- + // Draw a QR code in the center of the screen + auto scale = 2; + auto size = id(homepage_qr).get_size() * scale; + auto x = (it.get_width() / 2) - (size / 2); + auto y = (it.get_height() / 2) - (size / 2); + it.qr_code(x, y, id(homepage_qr), Color(255,255,255), scale); qr_code: - id: homepage_qr diff --git a/tests/components/qr_code/test.esp32-c3.yaml b/tests/components/qr_code/test.esp32-c3.yaml index 3e875c026c..63973b1aa2 100644 --- a/tests/components/qr_code/test.esp32-c3.yaml +++ b/tests/components/qr_code/test.esp32-c3.yaml @@ -11,6 +11,13 @@ display: cs_pin: 8 dc_pin: 9 reset_pin: 10 + lambda: |- + // Draw a QR code in the center of the screen + auto scale = 2; + auto size = id(homepage_qr).get_size() * scale; + auto x = (it.get_width() / 2) - (size / 2); + auto y = (it.get_height() / 2) - (size / 2); + it.qr_code(x, y, id(homepage_qr), Color(255,255,255), scale); qr_code: - id: homepage_qr diff --git a/tests/components/qr_code/test.esp32-idf.yaml b/tests/components/qr_code/test.esp32-idf.yaml index b354a3f512..3e70d3258f 100644 --- a/tests/components/qr_code/test.esp32-idf.yaml +++ b/tests/components/qr_code/test.esp32-idf.yaml @@ -11,6 +11,13 @@ display: cs_pin: 12 dc_pin: 13 reset_pin: 21 + lambda: |- + // Draw a QR code in the center of the screen + auto scale = 2; + auto size = id(homepage_qr).get_size() * scale; + auto x = (it.get_width() / 2) - (size / 2); + auto y = (it.get_height() / 2) - (size / 2); + it.qr_code(x, y, id(homepage_qr), Color(255,255,255), scale); qr_code: - id: homepage_qr diff --git a/tests/components/qr_code/test.esp32.yaml b/tests/components/qr_code/test.esp32.yaml index b354a3f512..3e70d3258f 100644 --- a/tests/components/qr_code/test.esp32.yaml +++ b/tests/components/qr_code/test.esp32.yaml @@ -11,6 +11,13 @@ display: cs_pin: 12 dc_pin: 13 reset_pin: 21 + lambda: |- + // Draw a QR code in the center of the screen + auto scale = 2; + auto size = id(homepage_qr).get_size() * scale; + auto x = (it.get_width() / 2) - (size / 2); + auto y = (it.get_height() / 2) - (size / 2); + it.qr_code(x, y, id(homepage_qr), Color(255,255,255), scale); qr_code: - id: homepage_qr diff --git a/tests/components/qr_code/test.esp8266.yaml b/tests/components/qr_code/test.esp8266.yaml index dd0d75c472..3c304d7575 100644 --- a/tests/components/qr_code/test.esp8266.yaml +++ b/tests/components/qr_code/test.esp8266.yaml @@ -11,6 +11,13 @@ display: cs_pin: 5 dc_pin: 15 reset_pin: 16 + lambda: |- + // Draw a QR code in the center of the screen + auto scale = 2; + auto size = id(homepage_qr).get_size() * scale; + auto x = (it.get_width() / 2) - (size / 2); + auto y = (it.get_height() / 2) - (size / 2); + it.qr_code(x, y, id(homepage_qr), Color(255,255,255), scale); qr_code: - id: homepage_qr diff --git a/tests/components/qr_code/test.rp2040.yaml b/tests/components/qr_code/test.rp2040.yaml index b0e046d275..94cb772ba3 100644 --- a/tests/components/qr_code/test.rp2040.yaml +++ b/tests/components/qr_code/test.rp2040.yaml @@ -11,6 +11,13 @@ display: cs_pin: 20 dc_pin: 21 reset_pin: 22 + lambda: |- + // Draw a QR code in the center of the screen + auto scale = 2; + auto size = id(homepage_qr).get_size() * scale; + auto x = (it.get_width() / 2) - (size / 2); + auto y = (it.get_height() / 2) - (size / 2); + it.qr_code(x, y, id(homepage_qr), Color(255,255,255), scale); qr_code: - id: homepage_qr From 731dcc40bcbadb197f0f2a091c4d3790f28e5980 Mon Sep 17 00:00:00 2001 From: mrtoy-me <118446898+mrtoy-me@users.noreply.github.com> Date: Thu, 28 Mar 2024 12:19:27 +1000 Subject: [PATCH 172/189] Minor change to support sht85 sensor (#6415) --- CODEOWNERS | 1 + esphome/components/sht3xd/sensor.py | 6 ++++-- esphome/components/sht3xd/sht3xd.cpp | 21 ++++++++++++++++----- esphome/components/sht3xd/sht3xd.h | 1 + 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 7c1f7ff70b..fafbaae6c6 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -309,6 +309,7 @@ esphome/components/sfa30/* @ghsensdev esphome/components/sgp40/* @SenexCrenshaw esphome/components/sgp4x/* @SenexCrenshaw @martgras esphome/components/shelly_dimmer/* @edge90 @rnauber +esphome/components/sht3xd/* @mrtoy-me esphome/components/sht4x/* @sjtrny esphome/components/shutdown/* @esphome/core @jsuanet esphome/components/sigma_delta_output/* @Cat-Ion diff --git a/esphome/components/sht3xd/sensor.py b/esphome/components/sht3xd/sensor.py index 80e15a1ab9..1286489b29 100644 --- a/esphome/components/sht3xd/sensor.py +++ b/esphome/components/sht3xd/sensor.py @@ -14,6 +14,8 @@ from esphome.const import ( CONF_HEATER_ENABLED = "heater_enabled" +CODEOWNERS = ["@mrtoy-me"] + DEPENDENCIES = ["i2c"] AUTO_LOAD = ["sensirion_common"] @@ -26,13 +28,13 @@ CONFIG_SCHEMA = ( cv.Schema( { cv.GenerateID(): cv.declare_id(SHT3XDComponent), - cv.Required(CONF_TEMPERATURE): sensor.sensor_schema( + cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema( unit_of_measurement=UNIT_CELSIUS, accuracy_decimals=1, device_class=DEVICE_CLASS_TEMPERATURE, state_class=STATE_CLASS_MEASUREMENT, ), - cv.Required(CONF_HUMIDITY): sensor.sensor_schema( + cv.Optional(CONF_HUMIDITY): sensor.sensor_schema( unit_of_measurement=UNIT_PERCENT, accuracy_decimals=1, device_class=DEVICE_CLASS_HUMIDITY, diff --git a/esphome/components/sht3xd/sht3xd.cpp b/esphome/components/sht3xd/sht3xd.cpp index 25332165c0..888e954c6b 100644 --- a/esphome/components/sht3xd/sht3xd.cpp +++ b/esphome/components/sht3xd/sht3xd.cpp @@ -6,7 +6,11 @@ namespace sht3xd { static const char *const TAG = "sht3xd"; -static const uint16_t SHT3XD_COMMAND_READ_SERIAL_NUMBER = 0x3780; +// use read serial number register with clock stretching disabled as per other SHT3XD_COMMAND registers +// which provides support for SHT85 sensor +// SHT85 does not support clock stretching and uses same registers as SHT3xd with clock stretching disabled +static const uint16_t SHT3XD_COMMAND_READ_SERIAL_NUMBER = 0x3682; + static const uint16_t SHT3XD_COMMAND_READ_STATUS = 0xF32D; static const uint16_t SHT3XD_COMMAND_CLEAR_STATUS = 0x3041; static const uint16_t SHT3XD_COMMAND_HEATER_ENABLE = 0x306D; @@ -22,25 +26,32 @@ void SHT3XDComponent::setup() { this->mark_failed(); return; } + this->serial_number_ = (uint32_t(raw_serial_number[0]) << 16) | uint32_t(raw_serial_number[1]); + if (!this->write_command(heater_enabled_ ? SHT3XD_COMMAND_HEATER_ENABLE : SHT3XD_COMMAND_HEATER_DISABLE)) { this->mark_failed(); return; } - uint32_t serial_number = (uint32_t(raw_serial_number[0]) << 16) | uint32_t(raw_serial_number[1]); - ESP_LOGV(TAG, " Serial Number: 0x%08" PRIX32, serial_number); } + void SHT3XDComponent::dump_config() { ESP_LOGCONFIG(TAG, "SHT3xD:"); - LOG_I2C_DEVICE(this); if (this->is_failed()) { - ESP_LOGE(TAG, "Communication with SHT3xD failed!"); + ESP_LOGE(TAG, " Communication with SHT3xD failed!"); + return; } + ESP_LOGD(TAG, " Serial Number: 0x%08" PRIX32, this->serial_number_); + ESP_LOGD(TAG, " Heater Enabled: %s", this->heater_enabled_ ? "true" : "false"); + + LOG_I2C_DEVICE(this); LOG_UPDATE_INTERVAL(this); LOG_SENSOR(" ", "Temperature", this->temperature_sensor_); LOG_SENSOR(" ", "Humidity", this->humidity_sensor_); } + float SHT3XDComponent::get_setup_priority() const { return setup_priority::DATA; } + void SHT3XDComponent::update() { if (this->status_has_warning()) { ESP_LOGD(TAG, "Retrying to reconnect the sensor."); diff --git a/esphome/components/sht3xd/sht3xd.h b/esphome/components/sht3xd/sht3xd.h index 4133bf7b93..d1a3360e69 100644 --- a/esphome/components/sht3xd/sht3xd.h +++ b/esphome/components/sht3xd/sht3xd.h @@ -25,6 +25,7 @@ class SHT3XDComponent : public PollingComponent, public sensirion_common::Sensir sensor::Sensor *temperature_sensor_{nullptr}; sensor::Sensor *humidity_sensor_{nullptr}; bool heater_enabled_{true}; + uint32_t serial_number_{0}; }; } // namespace sht3xd From dc0a7b1e205f5fa4e25fd1cadd507c27173636e1 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Thu, 28 Mar 2024 12:51:01 -0700 Subject: [PATCH 173/189] Add missing ethernet types (#6444) --- esphome/components/ethernet/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esphome/components/ethernet/__init__.py b/esphome/components/ethernet/__init__.py index de6040339a..ade94cb9f5 100644 --- a/esphome/components/ethernet/__init__.py +++ b/esphome/components/ethernet/__init__.py @@ -155,6 +155,8 @@ CONFIG_SCHEMA = cv.All( "DP83848": RMII_SCHEMA, "IP101": RMII_SCHEMA, "JL1101": RMII_SCHEMA, + "KSZ8081": RMII_SCHEMA, + "KSZ8081RNA": RMII_SCHEMA, "W5500": SPI_SCHEMA, }, upper=True, From f4e8a8972635bd99c72b47a69cde7c6a19cf61bb Mon Sep 17 00:00:00 2001 From: Jimmy Hedman Date: Mon, 1 Apr 2024 01:40:11 +0200 Subject: [PATCH 174/189] IPv6 string representation follows RFC5952 (#6449) --- esphome/components/network/ip_address.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esphome/components/network/ip_address.h b/esphome/components/network/ip_address.h index b02c358a77..30a426e458 100644 --- a/esphome/components/network/ip_address.h +++ b/esphome/components/network/ip_address.h @@ -4,6 +4,7 @@ #include #include #include "esphome/core/macros.h" +#include "esphome/core/helpers.h" #if defined(USE_ESP_IDF) || defined(USE_LIBRETINY) || USE_ARDUINO_VERSION_CODE > VERSION_CODE(3, 0, 0) #include @@ -116,7 +117,7 @@ struct IPAddress { bool is_set() { return !ip_addr_isany(&ip_addr_); } bool is_ip4() { return IP_IS_V4(&ip_addr_); } bool is_ip6() { return IP_IS_V6(&ip_addr_); } - std::string str() const { return ipaddr_ntoa(&ip_addr_); } + std::string str() const { return str_lower_case(ipaddr_ntoa(&ip_addr_)); } bool operator==(const IPAddress &other) const { return ip_addr_cmp(&ip_addr_, &other.ip_addr_); } bool operator!=(const IPAddress &other) const { return !ip_addr_cmp(&ip_addr_, &other.ip_addr_); } IPAddress &operator+=(uint8_t increase) { From 1207eda4ca19bce2db574f84d9f30f3068183856 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 12:41:43 +1300 Subject: [PATCH 175/189] Bump actions/setup-python from 5.0.0 to 5.1.0 (#6437) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-api-proto.yml | 2 +- .github/workflows/ci-docker.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 4 ++-- .github/workflows/sync-device-classes.yml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-api-proto.yml b/.github/workflows/ci-api-proto.yml index 0b2465d1aa..40766ad728 100644 --- a/.github/workflows/ci-api-proto.yml +++ b/.github/workflows/ci-api-proto.yml @@ -23,7 +23,7 @@ jobs: - name: Checkout uses: actions/checkout@v4.1.1 - name: Set up Python - uses: actions/setup-python@v5.0.0 + uses: actions/setup-python@v5.1.0 with: python-version: "3.11" diff --git a/.github/workflows/ci-docker.yml b/.github/workflows/ci-docker.yml index f02efadf4d..d8fd4efa0e 100644 --- a/.github/workflows/ci-docker.yml +++ b/.github/workflows/ci-docker.yml @@ -42,7 +42,7 @@ jobs: steps: - uses: actions/checkout@v4.1.1 - name: Set up Python - uses: actions/setup-python@v5.0.0 + uses: actions/setup-python@v5.1.0 with: python-version: "3.9" - name: Set up Docker Buildx diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0ac840972..7df57acb08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: run: echo key="${{ hashFiles('requirements.txt', 'requirements_optional.txt', 'requirements_test.txt') }}" >> $GITHUB_OUTPUT - name: Set up Python ${{ env.DEFAULT_PYTHON }} id: python - uses: actions/setup-python@v5.0.0 + uses: actions/setup-python@v5.1.0 with: python-version: ${{ env.DEFAULT_PYTHON }} - name: Restore Python virtual environment diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 16469c904b..cb7defc2b0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,7 @@ jobs: steps: - uses: actions/checkout@v4.1.1 - name: Set up Python - uses: actions/setup-python@v5.0.0 + uses: actions/setup-python@v5.1.0 with: python-version: "3.x" - name: Set up python environment @@ -79,7 +79,7 @@ jobs: steps: - uses: actions/checkout@v4.1.1 - name: Set up Python - uses: actions/setup-python@v5.0.0 + uses: actions/setup-python@v5.1.0 with: python-version: "3.9" diff --git a/.github/workflows/sync-device-classes.yml b/.github/workflows/sync-device-classes.yml index 3f8af4249a..c12f1f31b5 100644 --- a/.github/workflows/sync-device-classes.yml +++ b/.github/workflows/sync-device-classes.yml @@ -22,7 +22,7 @@ jobs: path: lib/home-assistant - name: Setup Python - uses: actions/setup-python@v5.0.0 + uses: actions/setup-python@v5.1.0 with: python-version: 3.11 From 3a49e91ce03201c13133dee1a2bf0f474805682d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 12:42:02 +1300 Subject: [PATCH 176/189] Bump actions/setup-python from 5.0.0 to 5.1.0 in /.github/actions/restore-python (#6438) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/restore-python/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/restore-python/action.yml b/.github/actions/restore-python/action.yml index aa4f7ba887..4ad9e2eaed 100644 --- a/.github/actions/restore-python/action.yml +++ b/.github/actions/restore-python/action.yml @@ -17,7 +17,7 @@ runs: steps: - name: Set up Python ${{ inputs.python-version }} id: python - uses: actions/setup-python@v5.0.0 + uses: actions/setup-python@v5.1.0 with: python-version: ${{ inputs.python-version }} - name: Restore Python virtual environment From 1be5d14fd946b708bb1016bc26158bdc2e20d1f2 Mon Sep 17 00:00:00 2001 From: NewoPL <27411874+NewoPL@users.noreply.github.com> Date: Mon, 1 Apr 2024 01:43:49 +0200 Subject: [PATCH 177/189] fix: changing the content source when playing is paused blocks the player (#6454) --- .../i2s_audio/media_player/i2s_audio_media_player.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp b/esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp index 9e2e3f136a..6e07983920 100644 --- a/esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +++ b/esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp @@ -12,12 +12,12 @@ static const char *const TAG = "audio"; void I2SAudioMediaPlayer::control(const media_player::MediaPlayerCall &call) { if (call.get_media_url().has_value()) { this->current_url_ = call.get_media_url(); - - if (this->state == media_player::MEDIA_PLAYER_STATE_PLAYING && this->audio_ != nullptr) { + if (this->i2s_state_ != I2S_STATE_STOPPED && this->audio_ != nullptr) { if (this->audio_->isRunning()) { this->audio_->stopSong(); } this->audio_->connecttohost(this->current_url_.value().c_str()); + this->state = media_player::MEDIA_PLAYER_STATE_PLAYING; } else { this->start(); } From 63db07a156756b30aa2fdc9b35e14f9d4c0ed16f Mon Sep 17 00:00:00 2001 From: tronikos Date: Mon, 1 Apr 2024 13:21:53 -0700 Subject: [PATCH 178/189] Optimize QMC5883L: Read registers only for enabled sensors (#6458) --- esphome/components/qmc5883l/qmc5883l.cpp | 45 +++++++++++++++++------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/esphome/components/qmc5883l/qmc5883l.cpp b/esphome/components/qmc5883l/qmc5883l.cpp index f03b6af191..4052b395f9 100644 --- a/esphome/components/qmc5883l/qmc5883l.cpp +++ b/esphome/components/qmc5883l/qmc5883l.cpp @@ -76,15 +76,8 @@ void QMC5883LComponent::dump_config() { float QMC5883LComponent::get_setup_priority() const { return setup_priority::DATA; } void QMC5883LComponent::update() { uint8_t status = false; - this->read_byte(QMC5883L_REGISTER_STATUS, &status); - - uint16_t raw_x, raw_y, raw_z; - if (!this->read_byte_16_(QMC5883L_REGISTER_DATA_X_LSB, &raw_x) || - !this->read_byte_16_(QMC5883L_REGISTER_DATA_Y_LSB, &raw_y) || - !this->read_byte_16_(QMC5883L_REGISTER_DATA_Z_LSB, &raw_z)) { - this->status_set_warning(); - return; - } + if (ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG) + this->read_byte(QMC5883L_REGISTER_STATUS, &status); float mg_per_bit; switch (this->range_) { @@ -99,11 +92,37 @@ void QMC5883LComponent::update() { } // in µT - const float x = int16_t(raw_x) * mg_per_bit * 0.1f; - const float y = int16_t(raw_y) * mg_per_bit * 0.1f; - const float z = int16_t(raw_z) * mg_per_bit * 0.1f; + float x = NAN, y = NAN, z = NAN; + if (this->x_sensor_ != nullptr || this->heading_sensor_ != nullptr) { + uint16_t raw_x; + if (!this->read_byte_16_(QMC5883L_REGISTER_DATA_X_LSB, &raw_x)) { + this->status_set_warning(); + return; + } + x = int16_t(raw_x) * mg_per_bit * 0.1f; + } + if (this->y_sensor_ != nullptr || this->heading_sensor_ != nullptr) { + uint16_t raw_y; + if (!this->read_byte_16_(QMC5883L_REGISTER_DATA_Y_LSB, &raw_y)) { + this->status_set_warning(); + return; + } + y = int16_t(raw_y) * mg_per_bit * 0.1f; + } + if (this->z_sensor_ != nullptr) { + uint16_t raw_z; + if (!this->read_byte_16_(QMC5883L_REGISTER_DATA_Z_LSB, &raw_z)) { + this->status_set_warning(); + return; + } + z = int16_t(raw_z) * mg_per_bit * 0.1f; + } + + float heading = NAN; + if (this->heading_sensor_ != nullptr) { + heading = atan2f(0.0f - x, y) * 180.0f / M_PI; + } - float heading = atan2f(0.0f - x, y) * 180.0f / M_PI; ESP_LOGD(TAG, "Got x=%0.02fµT y=%0.02fµT z=%0.02fµT heading=%0.01f° status=%u", x, y, z, heading, status); if (this->x_sensor_ != nullptr) From 6deb253fa68879d8b03b05be97644d05cf572fd3 Mon Sep 17 00:00:00 2001 From: Leland Sindt Date: Mon, 1 Apr 2024 21:32:40 -0500 Subject: [PATCH 179/189] minor refactor to allow commit hash as ref value. (#6446) --- esphome/git.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/esphome/git.py b/esphome/git.py index 4f0911233e..e41777f425 100644 --- a/esphome/git.py +++ b/esphome/git.py @@ -59,17 +59,14 @@ def clone_or_update( ) repo_dir = _compute_destination_path(key, domain) - fetch_pr_branch = ref is not None and ref.startswith("pull/") if not repo_dir.is_dir(): _LOGGER.info("Cloning %s", key) _LOGGER.debug("Location: %s", repo_dir) cmd = ["git", "clone", "--depth=1"] - if ref is not None and not fetch_pr_branch: - cmd += ["--branch", ref] cmd += ["--", url, str(repo_dir)] run_git_command(cmd) - if fetch_pr_branch: + if ref is not None: # We need to fetch the PR branch first, otherwise git will complain # about missing objects _LOGGER.info("Fetching %s", ref) From e32b8296702539e2d5cfafa4dbefae280a1abc06 Mon Sep 17 00:00:00 2001 From: mrtoy-me <118446898+mrtoy-me@users.noreply.github.com> Date: Tue, 2 Apr 2024 12:35:59 +1000 Subject: [PATCH 180/189] TMP117 fix polling period config (#6452) --- esphome/components/tmp117/sensor.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/esphome/components/tmp117/sensor.py b/esphome/components/tmp117/sensor.py index fb97258bc1..82d099cf12 100644 --- a/esphome/components/tmp117/sensor.py +++ b/esphome/components/tmp117/sensor.py @@ -30,37 +30,37 @@ CONFIG_SCHEMA = cv.All( def determine_config_register(polling_period): - if polling_period >= 16.0: + if polling_period >= 16000: # 64 averaged conversions, max conversion time # 0000 00 111 11 00000 # 0000 0011 1110 0000 return 0x03E0 - if polling_period >= 8.0: + if polling_period >= 8000: # 64 averaged conversions, high conversion time # 0000 00 110 11 00000 # 0000 0011 0110 0000 return 0x0360 - if polling_period >= 4.0: + if polling_period >= 4000: # 64 averaged conversions, mid conversion time # 0000 00 101 11 00000 # 0000 0010 1110 0000 return 0x02E0 - if polling_period >= 1.0: + if polling_period >= 1000: # 64 averaged conversions, min conversion time # 0000 00 000 11 00000 # 0000 0000 0110 0000 return 0x0060 - if polling_period >= 0.5: + if polling_period >= 500: # 32 averaged conversions, min conversion time # 0000 00 000 10 00000 # 0000 0000 0100 0000 return 0x0040 - if polling_period >= 0.25: + if polling_period >= 250: # 8 averaged conversions, mid conversion time # 0000 00 010 01 00000 # 0000 0001 0010 0000 return 0x0120 - if polling_period >= 0.125: + if polling_period >= 125: # 8 averaged conversions, min conversion time # 0000 00 000 01 00000 # 0000 0000 0010 0000 @@ -76,5 +76,5 @@ async def to_code(config): await cg.register_component(var, config) await i2c.register_i2c_device(var, config) - update_period = config[CONF_UPDATE_INTERVAL].total_seconds + update_period = config[CONF_UPDATE_INTERVAL].total_milliseconds cg.add(var.set_config(determine_config_register(update_period))) From ec32501d405a462bb8120d94ae504265d7832f15 Mon Sep 17 00:00:00 2001 From: Jimmy Hedman Date: Tue, 2 Apr 2024 05:00:47 +0200 Subject: [PATCH 181/189] Bump Arduino Pico Framework to 3.7.2 and Platform to 1.12.0 (#6386) --- esphome/components/rp2040/__init__.py | 4 ++-- platformio.ini | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/esphome/components/rp2040/__init__.py b/esphome/components/rp2040/__init__.py index d027f48244..b262a068fb 100644 --- a/esphome/components/rp2040/__init__.py +++ b/esphome/components/rp2040/__init__.py @@ -74,12 +74,12 @@ def _format_framework_arduino_version(ver: cv.Version) -> str: # The default/recommended arduino framework version # - https://github.com/earlephilhower/arduino-pico/releases # - https://api.registry.platformio.org/v3/packages/earlephilhower/tool/framework-arduinopico -RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(3, 6, 0) +RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(3, 7, 2) # The platformio/raspberrypi version to use for arduino frameworks # - https://github.com/platformio/platform-raspberrypi/releases # - https://api.registry.platformio.org/v3/packages/platformio/platform/raspberrypi -ARDUINO_PLATFORM_VERSION = cv.Version(1, 10, 0) +ARDUINO_PLATFORM_VERSION = cv.Version(1, 12, 0) def _arduino_check_versions(value): diff --git a/platformio.ini b/platformio.ini index db5fb3a544..5fedd14086 100644 --- a/platformio.ini +++ b/platformio.ini @@ -154,13 +154,12 @@ extra_scripts = post:esphome/components/esp32/post_build.py.script ; These are common settings for the RP2040 using Arduino. [common:rp2040-arduino] extends = common:arduino -board_build.core = earlephilhower board_build.filesystem_size = 0.5m platform = https://github.com/maxgerhardt/platform-raspberrypi.git platform_packages = ; earlephilhower/framework-arduinopico@~1.20602.0 ; Cannot use the platformio package until old releases stop getting deleted - earlephilhower/framework-arduinopico@https://github.com/earlephilhower/arduino-pico/releases/download/3.6.0/rp2040-3.6.0.zip + earlephilhower/framework-arduinopico@https://github.com/earlephilhower/arduino-pico/releases/download/3.7.2/rp2040-3.7.2.zip framework = arduino lib_deps = From 4fcb26d69dd4b245023df25d63946e5a974a391c Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 3 Apr 2024 07:33:18 +1300 Subject: [PATCH 182/189] Display menu: Allow "left" key to exit current menu if not editing (#6460) --- esphome/components/display_menu_base/display_menu_base.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esphome/components/display_menu_base/display_menu_base.cpp b/esphome/components/display_menu_base/display_menu_base.cpp index 0bfee338ca..5502623607 100644 --- a/esphome/components/display_menu_base/display_menu_base.cpp +++ b/esphome/components/display_menu_base/display_menu_base.cpp @@ -60,6 +60,8 @@ void DisplayMenuComponent::left() { if (this->editing_) { this->finish_editing_(); changed = true; + } else { + changed = this->leave_menu_(); } break; case MENU_MODE_JOYSTICK: From 02632f0cad8a6026225765e9da48ffb5ff353a26 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 3 Apr 2024 15:16:38 +1300 Subject: [PATCH 183/189] Fix NOLINT on inclusive-language check (#6464) --- esphome/components/pmsx003/pmsx003.h | 9 +++++---- script/ci-custom.py | 26 +++++++++++++++++++------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/esphome/components/pmsx003/pmsx003.h b/esphome/components/pmsx003/pmsx003.h index eb33f66909..cb5c16aecf 100644 --- a/esphome/components/pmsx003/pmsx003.h +++ b/esphome/components/pmsx003/pmsx003.h @@ -1,16 +1,17 @@ #pragma once -#include "esphome/core/component.h" #include "esphome/components/sensor/sensor.h" #include "esphome/components/uart/uart.h" +#include "esphome/core/component.h" namespace esphome { namespace pmsx003 { // known command bytes -#define PMS_CMD_AUTO_MANUAL 0xE1 // data=0: perform measurement manually, data=1: perform measurement automatically -#define PMS_CMD_TRIG_MANUAL 0xE2 // trigger a manual measurement -#define PMS_CMD_ON_STANDBY 0xE4 // data=0: go to standby mode, data=1: go to normal mode +static const uint8_t PMS_CMD_AUTO_MANUAL = + 0xE1; // data=0: perform measurement manually, data=1: perform measurement automatically +static const uint8_t PMS_CMD_TRIG_MANUAL = 0xE2; // trigger a manual measurement +static const uint8_t PMS_CMD_ON_STANDBY = 0xE4; // data=0: go to standby mode, data=1: go to normal mode static const uint16_t PMS_STABILISING_MS = 30000; // time taken for the sensor to become stable after power on diff --git a/script/ci-custom.py b/script/ci-custom.py index 422fdf52f0..1ad44dc930 100755 --- a/script/ci-custom.py +++ b/script/ci-custom.py @@ -57,6 +57,7 @@ file_types = ( "", ) cpp_include = ("*.h", "*.c", "*.cpp", "*.tcc") +py_include = ("*.py",) ignore_types = (".ico", ".png", ".woff", ".woff2", "") LINT_FILE_CHECKS = [] @@ -265,7 +266,8 @@ def lint_end_newline(fname, content): return None -CPP_RE_EOL = r"\s*?(?://.*?)?$" +CPP_RE_EOL = r".*?(?://.*?)?$" +PY_RE_EOL = r".*?(?:#.*?)?$" def highlight(s): @@ -273,7 +275,7 @@ def highlight(s): @lint_re_check( - r"^#define\s+([a-zA-Z0-9_]+)\s+([0-9bx]+)" + CPP_RE_EOL, + r"^#define\s+([a-zA-Z0-9_]+)\s+(0b[10]+|0x[0-9a-fA-F]+|\d+)\s*?(?:\/\/.*?)?$", include=cpp_include, exclude=[ "esphome/core/log.h", @@ -574,11 +576,6 @@ def lint_pragma_once(fname, content): return None -@lint_re_check( - r"(whitelist|blacklist|slave)", - exclude=["script/ci-custom.py"], - flags=re.IGNORECASE | re.MULTILINE, -) def lint_inclusive_language(fname, match): # From https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=49decddd39e5f6132ccd7d9fdc3d7c470b0061bb return ( @@ -596,6 +593,21 @@ def lint_inclusive_language(fname, match): ) +lint_re_check( + r"(whitelist|blacklist|slave)" + PY_RE_EOL, + include=py_include, + exclude=["script/ci-custom.py"], + flags=re.IGNORECASE | re.MULTILINE, +)(lint_inclusive_language) + + +lint_re_check( + r"(whitelist|blacklist|slave)" + CPP_RE_EOL, + include=cpp_include, + flags=re.IGNORECASE | re.MULTILINE, +)(lint_inclusive_language) + + @lint_re_check(r"[\t\r\f\v ]+$") def lint_trailing_whitespace(fname, match): return "Trailing whitespace detected" From be8d188a558cc0cf239b11133789f9f42c69c57b Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Wed, 3 Apr 2024 15:16:59 +1300 Subject: [PATCH 184/189] Add yamllint to dev requirements (#6466) --- requirements_dev.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements_dev.txt b/requirements_dev.txt index 6b6319d0a0..6bfa015c6f 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,3 +1,4 @@ # Useful stuff when working in a development environment clang-format==13.0.1 clang-tidy==14.0.6 +yamllint==1.35.1 From 96f4c70b6b256fb43420f9f5431f3d5bc6df7c67 Mon Sep 17 00:00:00 2001 From: tronikos Date: Tue, 2 Apr 2024 19:57:05 -0700 Subject: [PATCH 185/189] Add temperature for QMC5883L (#6456) --- esphome/components/qmc5883l/qmc5883l.cpp | 16 +++++++++++++++- esphome/components/qmc5883l/qmc5883l.h | 2 ++ esphome/components/qmc5883l/sensor.py | 13 +++++++++++++ tests/components/qmc5883l/test.esp32-c3-idf.yaml | 2 ++ tests/components/qmc5883l/test.esp32-c3.yaml | 2 ++ tests/components/qmc5883l/test.esp32-idf.yaml | 2 ++ tests/components/qmc5883l/test.esp32.yaml | 2 ++ tests/components/qmc5883l/test.esp8266.yaml | 2 ++ tests/components/qmc5883l/test.rp2040.yaml | 2 ++ 9 files changed, 42 insertions(+), 1 deletion(-) diff --git a/esphome/components/qmc5883l/qmc5883l.cpp b/esphome/components/qmc5883l/qmc5883l.cpp index 4052b395f9..4946ad1b77 100644 --- a/esphome/components/qmc5883l/qmc5883l.cpp +++ b/esphome/components/qmc5883l/qmc5883l.cpp @@ -72,6 +72,7 @@ void QMC5883LComponent::dump_config() { LOG_SENSOR(" ", "Y Axis", this->y_sensor_); LOG_SENSOR(" ", "Z Axis", this->z_sensor_); LOG_SENSOR(" ", "Heading", this->heading_sensor_); + LOG_SENSOR(" ", "Temperature", this->temperature_sensor_); } float QMC5883LComponent::get_setup_priority() const { return setup_priority::DATA; } void QMC5883LComponent::update() { @@ -123,7 +124,18 @@ void QMC5883LComponent::update() { heading = atan2f(0.0f - x, y) * 180.0f / M_PI; } - ESP_LOGD(TAG, "Got x=%0.02fµT y=%0.02fµT z=%0.02fµT heading=%0.01f° status=%u", x, y, z, heading, status); + float temp = NAN; + if (this->temperature_sensor_ != nullptr) { + uint16_t raw_temp; + if (!this->read_byte_16_(QMC5883L_REGISTER_TEMPERATURE_LSB, &raw_temp)) { + this->status_set_warning(); + return; + } + temp = int16_t(raw_temp) * 0.01f; + } + + ESP_LOGD(TAG, "Got x=%0.02fµT y=%0.02fµT z=%0.02fµT heading=%0.01f° temperature=%0.01f°C status=%u", x, y, z, heading, + temp, status); if (this->x_sensor_ != nullptr) this->x_sensor_->publish_state(x); @@ -133,6 +145,8 @@ void QMC5883LComponent::update() { this->z_sensor_->publish_state(z); if (this->heading_sensor_ != nullptr) this->heading_sensor_->publish_state(heading); + if (this->temperature_sensor_ != nullptr) + this->temperature_sensor_->publish_state(temp); } bool QMC5883LComponent::read_byte_16_(uint8_t a_register, uint16_t *data) { diff --git a/esphome/components/qmc5883l/qmc5883l.h b/esphome/components/qmc5883l/qmc5883l.h index 15ef435ce5..b0c0af40d2 100644 --- a/esphome/components/qmc5883l/qmc5883l.h +++ b/esphome/components/qmc5883l/qmc5883l.h @@ -40,6 +40,7 @@ class QMC5883LComponent : public PollingComponent, public i2c::I2CDevice { void set_y_sensor(sensor::Sensor *y_sensor) { y_sensor_ = y_sensor; } void set_z_sensor(sensor::Sensor *z_sensor) { z_sensor_ = z_sensor; } void set_heading_sensor(sensor::Sensor *heading_sensor) { heading_sensor_ = heading_sensor; } + void set_temperature_sensor(sensor::Sensor *temperature_sensor) { temperature_sensor_ = temperature_sensor; } protected: QMC5883LDatarate datarate_{QMC5883L_DATARATE_10_HZ}; @@ -49,6 +50,7 @@ class QMC5883LComponent : public PollingComponent, public i2c::I2CDevice { sensor::Sensor *y_sensor_{nullptr}; sensor::Sensor *z_sensor_{nullptr}; sensor::Sensor *heading_sensor_{nullptr}; + sensor::Sensor *temperature_sensor_{nullptr}; enum ErrorCode { NONE = 0, COMMUNICATION_FAILED, diff --git a/esphome/components/qmc5883l/sensor.py b/esphome/components/qmc5883l/sensor.py index b819fecfe1..24e1019507 100644 --- a/esphome/components/qmc5883l/sensor.py +++ b/esphome/components/qmc5883l/sensor.py @@ -6,12 +6,15 @@ from esphome.const import ( CONF_FIELD_STRENGTH_X, CONF_FIELD_STRENGTH_Y, CONF_FIELD_STRENGTH_Z, + CONF_TEMPERATURE, CONF_ID, CONF_OVERSAMPLING, CONF_RANGE, + DEVICE_CLASS_TEMPERATURE, ICON_MAGNET, STATE_CLASS_MEASUREMENT, UNIT_MICROTESLA, + UNIT_CELSIUS, UNIT_DEGREES, ICON_SCREEN_ROTATION, CONF_UPDATE_INTERVAL, @@ -79,6 +82,12 @@ heading_schema = sensor.sensor_schema( icon=ICON_SCREEN_ROTATION, accuracy_decimals=1, ) +temperature_schema = sensor.sensor_schema( + unit_of_measurement=UNIT_CELSIUS, + accuracy_decimals=1, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, +) CONFIG_SCHEMA = ( cv.Schema( @@ -95,6 +104,7 @@ CONFIG_SCHEMA = ( cv.Optional(CONF_FIELD_STRENGTH_Y): field_strength_schema, cv.Optional(CONF_FIELD_STRENGTH_Z): field_strength_schema, cv.Optional(CONF_HEADING): heading_schema, + cv.Optional(CONF_TEMPERATURE): temperature_schema, } ) .extend(cv.polling_component_schema("60s")) @@ -131,3 +141,6 @@ async def to_code(config): if CONF_HEADING in config: sens = await sensor.new_sensor(config[CONF_HEADING]) cg.add(var.set_heading_sensor(sens)) + if CONF_TEMPERATURE in config: + sens = await sensor.new_sensor(config[CONF_TEMPERATURE]) + cg.add(var.set_temperature_sensor(sens)) diff --git a/tests/components/qmc5883l/test.esp32-c3-idf.yaml b/tests/components/qmc5883l/test.esp32-c3-idf.yaml index c638f7e5be..841bbd5d1e 100644 --- a/tests/components/qmc5883l/test.esp32-c3-idf.yaml +++ b/tests/components/qmc5883l/test.esp32-c3-idf.yaml @@ -14,6 +14,8 @@ sensor: name: QMC5883L Field Strength Z heading: name: QMC5883L Heading + temperature: + name: QMC5883L Temperature range: 800uT oversampling: 256x update_interval: 15s diff --git a/tests/components/qmc5883l/test.esp32-c3.yaml b/tests/components/qmc5883l/test.esp32-c3.yaml index c638f7e5be..841bbd5d1e 100644 --- a/tests/components/qmc5883l/test.esp32-c3.yaml +++ b/tests/components/qmc5883l/test.esp32-c3.yaml @@ -14,6 +14,8 @@ sensor: name: QMC5883L Field Strength Z heading: name: QMC5883L Heading + temperature: + name: QMC5883L Temperature range: 800uT oversampling: 256x update_interval: 15s diff --git a/tests/components/qmc5883l/test.esp32-idf.yaml b/tests/components/qmc5883l/test.esp32-idf.yaml index 1aafa86cfa..9acd391497 100644 --- a/tests/components/qmc5883l/test.esp32-idf.yaml +++ b/tests/components/qmc5883l/test.esp32-idf.yaml @@ -14,6 +14,8 @@ sensor: name: QMC5883L Field Strength Z heading: name: QMC5883L Heading + temperature: + name: QMC5883L Temperature range: 800uT oversampling: 256x update_interval: 15s diff --git a/tests/components/qmc5883l/test.esp32.yaml b/tests/components/qmc5883l/test.esp32.yaml index 1aafa86cfa..9acd391497 100644 --- a/tests/components/qmc5883l/test.esp32.yaml +++ b/tests/components/qmc5883l/test.esp32.yaml @@ -14,6 +14,8 @@ sensor: name: QMC5883L Field Strength Z heading: name: QMC5883L Heading + temperature: + name: QMC5883L Temperature range: 800uT oversampling: 256x update_interval: 15s diff --git a/tests/components/qmc5883l/test.esp8266.yaml b/tests/components/qmc5883l/test.esp8266.yaml index c638f7e5be..841bbd5d1e 100644 --- a/tests/components/qmc5883l/test.esp8266.yaml +++ b/tests/components/qmc5883l/test.esp8266.yaml @@ -14,6 +14,8 @@ sensor: name: QMC5883L Field Strength Z heading: name: QMC5883L Heading + temperature: + name: QMC5883L Temperature range: 800uT oversampling: 256x update_interval: 15s diff --git a/tests/components/qmc5883l/test.rp2040.yaml b/tests/components/qmc5883l/test.rp2040.yaml index c638f7e5be..841bbd5d1e 100644 --- a/tests/components/qmc5883l/test.rp2040.yaml +++ b/tests/components/qmc5883l/test.rp2040.yaml @@ -14,6 +14,8 @@ sensor: name: QMC5883L Field Strength Z heading: name: QMC5883L Heading + temperature: + name: QMC5883L Temperature range: 800uT oversampling: 256x update_interval: 15s From 5cc3d60feef8e674342f5d6c97f76f1b6a7305e2 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Thu, 4 Apr 2024 11:13:59 +1300 Subject: [PATCH 186/189] web_server: Return early if no clients connected (#6467) --- .../components/web_server/list_entities.cpp | 30 +++++++++++++++++ esphome/components/web_server/web_server.cpp | 32 ++++++++++++++++++- .../web_server_idf/web_server_idf.h | 6 ++-- 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/esphome/components/web_server/list_entities.cpp b/esphome/components/web_server/list_entities.cpp index 197af1eb14..2252f55008 100644 --- a/esphome/components/web_server/list_entities.cpp +++ b/esphome/components/web_server/list_entities.cpp @@ -12,6 +12,8 @@ ListEntitiesIterator::ListEntitiesIterator(WebServer *web_server) : web_server_( #ifdef USE_BINARY_SENSOR bool ListEntitiesIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_sensor) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send( this->web_server_->binary_sensor_json(binary_sensor, binary_sensor->state, DETAIL_ALL).c_str(), "state"); return true; @@ -19,30 +21,40 @@ bool ListEntitiesIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_ #endif #ifdef USE_COVER bool ListEntitiesIterator::on_cover(cover::Cover *cover) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send(this->web_server_->cover_json(cover, DETAIL_ALL).c_str(), "state"); return true; } #endif #ifdef USE_FAN bool ListEntitiesIterator::on_fan(fan::Fan *fan) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send(this->web_server_->fan_json(fan, DETAIL_ALL).c_str(), "state"); return true; } #endif #ifdef USE_LIGHT bool ListEntitiesIterator::on_light(light::LightState *light) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send(this->web_server_->light_json(light, DETAIL_ALL).c_str(), "state"); return true; } #endif #ifdef USE_SENSOR bool ListEntitiesIterator::on_sensor(sensor::Sensor *sensor) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send(this->web_server_->sensor_json(sensor, sensor->state, DETAIL_ALL).c_str(), "state"); return true; } #endif #ifdef USE_SWITCH bool ListEntitiesIterator::on_switch(switch_::Switch *a_switch) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send(this->web_server_->switch_json(a_switch, a_switch->state, DETAIL_ALL).c_str(), "state"); return true; @@ -50,12 +62,16 @@ bool ListEntitiesIterator::on_switch(switch_::Switch *a_switch) { #endif #ifdef USE_BUTTON bool ListEntitiesIterator::on_button(button::Button *button) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send(this->web_server_->button_json(button, DETAIL_ALL).c_str(), "state"); return true; } #endif #ifdef USE_TEXT_SENSOR bool ListEntitiesIterator::on_text_sensor(text_sensor::TextSensor *text_sensor) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send( this->web_server_->text_sensor_json(text_sensor, text_sensor->state, DETAIL_ALL).c_str(), "state"); return true; @@ -63,6 +79,8 @@ bool ListEntitiesIterator::on_text_sensor(text_sensor::TextSensor *text_sensor) #endif #ifdef USE_LOCK bool ListEntitiesIterator::on_lock(lock::Lock *a_lock) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send(this->web_server_->lock_json(a_lock, a_lock->state, DETAIL_ALL).c_str(), "state"); return true; } @@ -70,6 +88,8 @@ bool ListEntitiesIterator::on_lock(lock::Lock *a_lock) { #ifdef USE_CLIMATE bool ListEntitiesIterator::on_climate(climate::Climate *climate) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send(this->web_server_->climate_json(climate, DETAIL_ALL).c_str(), "state"); return true; } @@ -77,6 +97,8 @@ bool ListEntitiesIterator::on_climate(climate::Climate *climate) { #ifdef USE_NUMBER bool ListEntitiesIterator::on_number(number::Number *number) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send(this->web_server_->number_json(number, number->state, DETAIL_ALL).c_str(), "state"); return true; } @@ -84,6 +106,8 @@ bool ListEntitiesIterator::on_number(number::Number *number) { #ifdef USE_DATETIME_DATE bool ListEntitiesIterator::on_date(datetime::DateEntity *date) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send(this->web_server_->date_json(date, DETAIL_ALL).c_str(), "state"); return true; } @@ -91,6 +115,8 @@ bool ListEntitiesIterator::on_date(datetime::DateEntity *date) { #ifdef USE_TEXT bool ListEntitiesIterator::on_text(text::Text *text) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send(this->web_server_->text_json(text, text->state, DETAIL_ALL).c_str(), "state"); return true; } @@ -98,6 +124,8 @@ bool ListEntitiesIterator::on_text(text::Text *text) { #ifdef USE_SELECT bool ListEntitiesIterator::on_select(select::Select *select) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send(this->web_server_->select_json(select, select->state, DETAIL_ALL).c_str(), "state"); return true; } @@ -105,6 +133,8 @@ bool ListEntitiesIterator::on_select(select::Select *select) { #ifdef USE_ALARM_CONTROL_PANEL bool ListEntitiesIterator::on_alarm_control_panel(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) { + if (this->web_server_->events_.count() == 0) + return true; this->web_server_->events_.send( this->web_server_->alarm_control_panel_json(a_alarm_control_panel, a_alarm_control_panel->get_state(), DETAIL_ALL) .c_str(), diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index f065dc6684..4e6797ae1f 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -416,6 +416,8 @@ void WebServer::handle_js_request(AsyncWebServerRequest *request) { #ifdef USE_SENSOR void WebServer::on_sensor_update(sensor::Sensor *obj, float state) { + if (this->events_.count() == 0) + return; this->events_.send(this->sensor_json(obj, state, DETAIL_STATE).c_str(), "state"); } void WebServer::handle_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match) { @@ -449,6 +451,8 @@ std::string WebServer::sensor_json(sensor::Sensor *obj, float value, JsonDetail #ifdef USE_TEXT_SENSOR void WebServer::on_text_sensor_update(text_sensor::TextSensor *obj, const std::string &state) { + if (this->events_.count() == 0) + return; this->events_.send(this->text_sensor_json(obj, state, DETAIL_STATE).c_str(), "state"); } void WebServer::handle_text_sensor_request(AsyncWebServerRequest *request, const UrlMatch &match) { @@ -471,6 +475,8 @@ std::string WebServer::text_sensor_json(text_sensor::TextSensor *obj, const std: #ifdef USE_SWITCH void WebServer::on_switch_update(switch_::Switch *obj, bool state) { + if (this->events_.count() == 0) + return; this->events_.send(this->switch_json(obj, state, DETAIL_STATE).c_str(), "state"); } std::string WebServer::switch_json(switch_::Switch *obj, bool value, JsonDetail start_config) { @@ -532,6 +538,8 @@ void WebServer::handle_button_request(AsyncWebServerRequest *request, const UrlM #ifdef USE_BINARY_SENSOR void WebServer::on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool state) { + if (this->events_.count() == 0) + return; this->events_.send(this->binary_sensor_json(obj, state, DETAIL_STATE).c_str(), "state"); } std::string WebServer::binary_sensor_json(binary_sensor::BinarySensor *obj, bool value, JsonDetail start_config) { @@ -553,7 +561,11 @@ void WebServer::handle_binary_sensor_request(AsyncWebServerRequest *request, con #endif #ifdef USE_FAN -void WebServer::on_fan_update(fan::Fan *obj) { this->events_.send(this->fan_json(obj, DETAIL_STATE).c_str(), "state"); } +void WebServer::on_fan_update(fan::Fan *obj) { + if (this->events_.count() == 0) + return; + this->events_.send(this->fan_json(obj, DETAIL_STATE).c_str(), "state"); +} std::string WebServer::fan_json(fan::Fan *obj, JsonDetail start_config) { return json::build_json([obj, start_config](JsonObject root) { set_json_icon_state_value(root, obj, "fan-" + obj->get_object_id(), obj->state ? "ON" : "OFF", obj->state, @@ -623,6 +635,8 @@ void WebServer::handle_fan_request(AsyncWebServerRequest *request, const UrlMatc #ifdef USE_LIGHT void WebServer::on_light_update(light::LightState *obj) { + if (this->events_.count() == 0) + return; this->events_.send(this->light_json(obj, DETAIL_STATE).c_str(), "state"); } void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMatch &match) { @@ -729,6 +743,8 @@ std::string WebServer::light_json(light::LightState *obj, JsonDetail start_confi #ifdef USE_COVER void WebServer::on_cover_update(cover::Cover *obj) { + if (this->events_.count() == 0) + return; this->events_.send(this->cover_json(obj, DETAIL_STATE).c_str(), "state"); } void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMatch &match) { @@ -798,6 +814,8 @@ std::string WebServer::cover_json(cover::Cover *obj, JsonDetail start_config) { #ifdef USE_NUMBER void WebServer::on_number_update(number::Number *obj, float state) { + if (this->events_.count() == 0) + return; this->events_.send(this->number_json(obj, state, DETAIL_STATE).c_str(), "state"); } void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlMatch &match) { @@ -856,6 +874,8 @@ std::string WebServer::number_json(number::Number *obj, float value, JsonDetail #ifdef USE_DATETIME_DATE void WebServer::on_date_update(datetime::DateEntity *obj) { + if (this->events_.count() == 0) + return; this->events_.send(this->date_json(obj, DETAIL_STATE).c_str(), "state"); } void WebServer::handle_date_request(AsyncWebServerRequest *request, const UrlMatch &match) { @@ -903,6 +923,8 @@ std::string WebServer::date_json(datetime::DateEntity *obj, JsonDetail start_con #ifdef USE_TEXT void WebServer::on_text_update(text::Text *obj, const std::string &state) { + if (this->events_.count() == 0) + return; this->events_.send(this->text_json(obj, state, DETAIL_STATE).c_str(), "state"); } void WebServer::handle_text_request(AsyncWebServerRequest *request, const UrlMatch &match) { @@ -954,6 +976,8 @@ std::string WebServer::text_json(text::Text *obj, const std::string &value, Json #ifdef USE_SELECT void WebServer::on_select_update(select::Select *obj, const std::string &state, size_t index) { + if (this->events_.count() == 0) + return; this->events_.send(this->select_json(obj, state, DETAIL_STATE).c_str(), "state"); } void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlMatch &match) { @@ -1008,6 +1032,8 @@ std::string WebServer::select_json(select::Select *obj, const std::string &value #ifdef USE_CLIMATE void WebServer::on_climate_update(climate::Climate *obj) { + if (this->events_.count() == 0) + return; this->events_.send(this->climate_json(obj, DETAIL_STATE).c_str(), "state"); } @@ -1149,6 +1175,8 @@ std::string WebServer::climate_json(climate::Climate *obj, JsonDetail start_conf #ifdef USE_LOCK void WebServer::on_lock_update(lock::Lock *obj) { + if (this->events_.count() == 0) + return; this->events_.send(this->lock_json(obj, obj->state, DETAIL_STATE).c_str(), "state"); } std::string WebServer::lock_json(lock::Lock *obj, lock::LockState value, JsonDetail start_config) { @@ -1185,6 +1213,8 @@ void WebServer::handle_lock_request(AsyncWebServerRequest *request, const UrlMat #ifdef USE_ALARM_CONTROL_PANEL void WebServer::on_alarm_control_panel_update(alarm_control_panel::AlarmControlPanel *obj) { + if (this->events_.count() == 0) + return; this->events_.send(this->alarm_control_panel_json(obj, obj->get_state(), DETAIL_STATE).c_str(), "state"); } std::string WebServer::alarm_control_panel_json(alarm_control_panel::AlarmControlPanel *obj, diff --git a/esphome/components/web_server_idf/web_server_idf.h b/esphome/components/web_server_idf/web_server_idf.h index 750f890fc7..2ead5e3f03 100644 --- a/esphome/components/web_server_idf/web_server_idf.h +++ b/esphome/components/web_server_idf/web_server_idf.h @@ -3,11 +3,11 @@ #include -#include #include -#include #include #include +#include +#include namespace esphome { namespace web_server_idf { @@ -251,6 +251,8 @@ class AsyncEventSource : public AsyncWebHandler { void send(const char *message, const char *event = nullptr, uint32_t id = 0, uint32_t reconnect = 0); + size_t count() const { return this->sessions_.size(); } + protected: std::string url_; std::set sessions_; From f09bfa731181e7dce43165d9d2a2b886053c5afd Mon Sep 17 00:00:00 2001 From: Faidon Liambotis Date: Thu, 4 Apr 2024 02:55:24 +0300 Subject: [PATCH 187/189] ESP32 Arduino WiFi: misc bug fixes (#6470) --- esphome/components/wifi/wifi_component_esp32_arduino.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/components/wifi/wifi_component_esp32_arduino.cpp b/esphome/components/wifi/wifi_component_esp32_arduino.cpp index 35e6c57e62..44d77b4eed 100644 --- a/esphome/components/wifi/wifi_component_esp32_arduino.cpp +++ b/esphome/components/wifi/wifi_component_esp32_arduino.cpp @@ -582,14 +582,14 @@ void WiFiComponent::wifi_pre_setup_() { } WiFiSTAConnectStatus WiFiComponent::wifi_sta_connect_status_() { auto status = WiFiClass::status(); - if (status == WL_CONNECTED) { - return WiFiSTAConnectStatus::CONNECTED; - } else if (status == WL_CONNECT_FAILED || status == WL_CONNECTION_LOST) { + if (status == WL_CONNECT_FAILED || status == WL_CONNECTION_LOST) { return WiFiSTAConnectStatus::ERROR_CONNECT_FAILED; } else if (status == WL_NO_SSID_AVAIL) { return WiFiSTAConnectStatus::ERROR_NETWORK_NOT_FOUND; } else if (s_sta_connecting) { return WiFiSTAConnectStatus::CONNECTING; + } else if (status == WL_CONNECTED) { + return WiFiSTAConnectStatus::CONNECTED; } return WiFiSTAConnectStatus::IDLE; } @@ -707,7 +707,7 @@ bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) { *conf.ap.password = 0; } else { conf.ap.authmode = WIFI_AUTH_WPA2_PSK; - strncpy(reinterpret_cast(conf.ap.password), ap.get_password().c_str(), sizeof(conf.ap.ssid)); + strncpy(reinterpret_cast(conf.ap.password), ap.get_password().c_str(), sizeof(conf.ap.password)); } conf.ap.pairwise_cipher = WIFI_CIPHER_TYPE_CCMP; From 0148ebcaa604f929aba06b6722697bb1b6e4c83c Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Thu, 4 Apr 2024 13:41:41 +1300 Subject: [PATCH 188/189] Replace std::regex with sscanf calls (#6468) * Replace std::regex with sscanf calls * Fix CI * Use regular formatting placeholders * Fix --- esphome/core/time.cpp | 77 +++++++++++++++++++++---------------------- esphome/core/time.h | 4 --- 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/esphome/core/time.cpp b/esphome/core/time.cpp index ae4fabac52..0004fc7e8e 100644 --- a/esphome/core/time.cpp +++ b/esphome/core/time.cpp @@ -1,9 +1,7 @@ -#ifdef USE_DATETIME -#include -#endif - -#include "helpers.h" #include "time.h" // NOLINT +#include "helpers.h" + +#include namespace esphome { @@ -66,48 +64,47 @@ std::string ESPTime::strftime(const std::string &format) { return timestr; } -#ifdef USE_DATETIME - bool ESPTime::strptime(const std::string &time_to_parse, ESPTime &esp_time) { - // clang-format off - std::regex dt_regex(R"(^ - ( - (\d{4})-(\d{1,2})-(\d{1,2}) - (?:\s(?=.+)) - )? - ( - (\d{1,2}):(\d{2}) - (?::(\d{2}))? - )? - $)"); - // clang-format on + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; + int num; - std::smatch match; - if (std::regex_match(time_to_parse, match, dt_regex) == 0) + if (sscanf(time_to_parse.c_str(), "%04hu-%02hhu-%02hhu %02hhu:%02hhu:%02hhu %n", &year, &month, &day, // NOLINT + &hour, // NOLINT + &minute, // NOLINT + &second, &num) == 6 && // NOLINT + num == time_to_parse.size()) { + esp_time.year = year; + esp_time.month = month; + esp_time.day_of_month = day; + esp_time.hour = hour; + esp_time.minute = minute; + esp_time.second = second; + } else if (sscanf(time_to_parse.c_str(), "%02hhu:%02hhu:%02hhu %n", &hour, &minute, &second, &num) == 3 && // NOLINT + num == time_to_parse.size()) { + esp_time.hour = hour; + esp_time.minute = minute; + esp_time.second = second; + } else if (sscanf(time_to_parse.c_str(), "%02hhu:%02hhu %n", &hour, &minute, &num) == 2 && // NOLINT + num == time_to_parse.size()) { + esp_time.hour = hour; + esp_time.minute = minute; + esp_time.second = 0; + } else if (sscanf(time_to_parse.c_str(), "%04hu-%02hhu-%02hhu %n", &year, &month, &day, &num) == 3 && // NOLINT + num == time_to_parse.size()) { + esp_time.year = year; + esp_time.month = month; + esp_time.day_of_month = day; + } else { return false; - - if (match[1].matched) { // Has date parts - - esp_time.year = parse_number(match[2].str()).value_or(0); - esp_time.month = parse_number(match[3].str()).value_or(0); - esp_time.day_of_month = parse_number(match[4].str()).value_or(0); } - if (match[5].matched) { // Has time parts - - esp_time.hour = parse_number(match[6].str()).value_or(0); - esp_time.minute = parse_number(match[7].str()).value_or(0); - if (match[8].matched) { - esp_time.second = parse_number(match[8].str()).value_or(0); - } else { - esp_time.second = 0; - } - } - return true; } -#endif - void ESPTime::increment_second() { this->timestamp++; if (!increment_time_value(this->second, 0, 60)) diff --git a/esphome/core/time.h b/esphome/core/time.h index 738a0261c7..4300cf26b7 100644 --- a/esphome/core/time.h +++ b/esphome/core/time.h @@ -67,8 +67,6 @@ struct ESPTime { this->day_of_year < 367 && this->month > 0 && this->month < 13; } -#ifdef USE_DATETIME - /** Convert a string to ESPTime struct as specified by the format argument. * @param time_to_parse null-terminated c string formatet like this: 2020-08-25 05:30:00. * @param esp_time an instance of a ESPTime struct @@ -76,8 +74,6 @@ struct ESPTime { */ static bool strptime(const std::string &time_to_parse, ESPTime &esp_time); -#endif - /// Convert a C tm struct instance with a C unix epoch timestamp to an ESPTime instance. static ESPTime from_c_tm(struct tm *c_tm, time_t c_time); From 2c67d83976305e21ae2bcd93f0412db0a6e13814 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Fri, 5 Apr 2024 15:21:56 +1100 Subject: [PATCH 189/189] Include "Failed" status in config log. (#6482) --- esphome/core/component.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/esphome/core/component.cpp b/esphome/core/component.cpp index b9a7697015..803bc11e02 100644 --- a/esphome/core/component.cpp +++ b/esphome/core/component.cpp @@ -76,7 +76,12 @@ bool Component::cancel_timeout(const std::string &name) { // NOLINT void Component::call_loop() { this->loop(); } void Component::call_setup() { this->setup(); } -void Component::call_dump_config() { this->dump_config(); } +void Component::call_dump_config() { + this->dump_config(); + if (this->is_failed()) { + ESP_LOGE(this->get_component_source(), " Component is marked FAILED"); + } +} uint32_t Component::get_component_state() const { return this->component_state_; } void Component::call() {