From b3ca71c6fb0d3f68228e522824c272d671292089 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Wed, 13 Sep 2023 18:13:55 -0500 Subject: [PATCH 01/14] Add patch to apt install (#5389) --- docker/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index bf64897af7..a0bb007641 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -29,7 +29,8 @@ RUN \ curl=7.74.0-1.3+deb11u7 \ openssh-client=1:8.4p1-5+deb11u1 \ python3-cffi=1.14.5-1 \ - libcairo2=1.16.0-5; \ + libcairo2=1.16.0-5 \ + patch=2.7.6-7; \ if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \ apt-get install -y --no-install-recommends \ build-essential=12.9 \ From ec20778d83dd7bf10d8f32c49ff0dfd7102a0ade Mon Sep 17 00:00:00 2001 From: phoenixswiss <52887628+phoenixswiss@users.noreply.github.com> Date: Thu, 14 Sep 2023 08:20:21 +0200 Subject: [PATCH 02/14] Fix Waveshare 7.5v2 epaper screens are always powered on (#5283) --- .../waveshare_epaper/waveshare_epaper.cpp | 66 ++++++++++++++++--- .../waveshare_epaper/waveshare_epaper.h | 4 ++ 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/esphome/components/waveshare_epaper/waveshare_epaper.cpp b/esphome/components/waveshare_epaper/waveshare_epaper.cpp index 73c2680add..f52808d295 100644 --- a/esphome/components/waveshare_epaper/waveshare_epaper.cpp +++ b/esphome/components/waveshare_epaper/waveshare_epaper.cpp @@ -1561,6 +1561,23 @@ void WaveshareEPaper7P5In::dump_config() { LOG_PIN(" Busy Pin: ", this->busy_pin_); LOG_UPDATE_INTERVAL(this); } +bool WaveshareEPaper7P5InV2::wait_until_idle_() { + if (this->busy_pin_ == nullptr) { + return true; + } + + const uint32_t start = millis(); + while (this->busy_pin_->digital_read()) { + this->command(0x71); + if (millis() - start > this->idle_timeout_()) { + ESP_LOGE(TAG, "Timeout while displaying image!"); + return false; + } + App.feed_wdt(); + delay(10); + } + return true; +} void WaveshareEPaper7P5InV2::initialize() { // COMMAND POWER SETTING this->command(0x01); @@ -1568,10 +1585,21 @@ void WaveshareEPaper7P5InV2::initialize() { this->data(0x07); this->data(0x3f); this->data(0x3f); - this->command(0x04); + + // We don't want the display to be powered at this point delay(100); // NOLINT this->wait_until_idle_(); + + // COMMAND VCOM AND DATA INTERVAL SETTING + this->command(0x50); + this->data(0x10); + this->data(0x07); + + // COMMAND TCON SETTING + this->command(0x60); + this->data(0x22); + // COMMAND PANEL SETTING this->command(0x00); this->data(0x1F); @@ -1582,19 +1610,30 @@ void WaveshareEPaper7P5InV2::initialize() { this->data(0x20); this->data(0x01); this->data(0xE0); - // COMMAND ...? + + // COMMAND DUAL SPI MM_EN, DUSPI_EN this->command(0x15); this->data(0x00); - // COMMAND VCOM AND DATA INTERVAL SETTING - this->command(0x50); - this->data(0x10); - this->data(0x07); - // COMMAND TCON SETTING - this->command(0x60); - this->data(0x22); + + // COMMAND POWER DRIVER HAT DOWN + // This command will turn off booster, controller, source driver, gate driver, VCOM, and + // temperature sensor, but register data will be kept until VDD turned OFF or Deep Sleep Mode. + // Source/Gate/Border/VCOM will be released to floating. + this->command(0x02); } void HOT WaveshareEPaper7P5InV2::display() { uint32_t buf_len = this->get_buffer_length_(); + + // COMMAND POWER ON + ESP_LOGI(TAG, "Power on the display and hat"); + + // This command will turn on booster, controller, regulators, and temperature sensor will be + // activated for one-time sensing before enabling booster. When all voltages are ready, the + // BUSY_N signal will return to high. + this->command(0x04); + delay(200); // NOLINT + this->wait_until_idle_(); + // COMMAND DATA START TRANSMISSION NEW DATA this->command(0x13); delay(2); @@ -1602,14 +1641,23 @@ void HOT WaveshareEPaper7P5InV2::display() { this->data(~(this->buffer_[i])); } + delay(100); // NOLINT + this->wait_until_idle_(); + // COMMAND DISPLAY REFRESH this->command(0x12); delay(100); // NOLINT this->wait_until_idle_(); + + ESP_LOGV(TAG, "Before command(0x02) (>> power off)"); + this->command(0x02); + this->wait_until_idle_(); + ESP_LOGV(TAG, "After command(0x02) (>> power off)"); } int WaveshareEPaper7P5InV2::get_width_internal() { return 800; } int WaveshareEPaper7P5InV2::get_height_internal() { return 480; } +uint32_t WaveshareEPaper7P5InV2::idle_timeout_() { return 10000; } void WaveshareEPaper7P5InV2::dump_config() { LOG_DISPLAY("", "Waveshare E-Paper", this); ESP_LOGCONFIG(TAG, " Model: 7.5inV2rev2"); diff --git a/esphome/components/waveshare_epaper/waveshare_epaper.h b/esphome/components/waveshare_epaper/waveshare_epaper.h index 315af9ea82..b3325d69eb 100644 --- a/esphome/components/waveshare_epaper/waveshare_epaper.h +++ b/esphome/components/waveshare_epaper/waveshare_epaper.h @@ -472,6 +472,8 @@ class WaveshareEPaper7P5InBC : public WaveshareEPaper { class WaveshareEPaper7P5InV2 : public WaveshareEPaper { public: + bool wait_until_idle_(); + void initialize() override; void display() override; @@ -491,6 +493,8 @@ class WaveshareEPaper7P5InV2 : public WaveshareEPaper { int get_width_internal() override; int get_height_internal() override; + + uint32_t idle_timeout_() override; }; class WaveshareEPaper7P5InV2alt : public WaveshareEPaper7P5InV2 { From d76f18b4f24fe8cd554e2e9ed2f24bcd601e63ae Mon Sep 17 00:00:00 2001 From: rmmacias <46213351+rmmacias@users.noreply.github.com> Date: Sun, 17 Sep 2023 07:18:51 +0200 Subject: [PATCH 03/14] Update radon_eye_listener.cpp (#5401) New devices identifiers do not star by the hardcoded string. FR:RE222 is the 8-char length string of my devices bought in 2023. This proposal aims at solve the topic by making the detection track devices starting only by FR:R --- esphome/components/radon_eye_ble/radon_eye_listener.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/radon_eye_ble/radon_eye_listener.cpp b/esphome/components/radon_eye_ble/radon_eye_listener.cpp index b10986c9cb..340322c188 100644 --- a/esphome/components/radon_eye_ble/radon_eye_listener.cpp +++ b/esphome/components/radon_eye_ble/radon_eye_listener.cpp @@ -10,7 +10,7 @@ static const char *const TAG = "radon_eye_ble"; bool RadonEyeListener::parse_device(const esp32_ble_tracker::ESPBTDevice &device) { if (not device.get_name().empty()) { - if (device.get_name().rfind("FR:R20:SN", 0) == 0) { + if (device.get_name().rfind("FR:R", 0) == 0) { // This is an RD200, I think ESP_LOGD(TAG, "Found Radon Eye RD200 device Name: %s (MAC: %s)", device.get_name().c_str(), device.address_str().c_str()); From 4622ef770d8a62232eddc8a1315699f91ef1952c Mon Sep 17 00:00:00 2001 From: Trevor North Date: Sun, 17 Sep 2023 06:20:31 +0100 Subject: [PATCH 04/14] Add shelly-dimmer-stm32 51.7 to known versions (#5400) This version removes support for no-neutral setups in favor of fixing flickering some users have experienced. --- esphome/components/shelly_dimmer/light.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/esphome/components/shelly_dimmer/light.py b/esphome/components/shelly_dimmer/light.py index 467a3c3531..5bdb54baf5 100644 --- a/esphome/components/shelly_dimmer/light.py +++ b/esphome/components/shelly_dimmer/light.py @@ -57,6 +57,10 @@ KNOWN_FIRMWARE = { "https://github.com/jamesturton/shelly-dimmer-stm32/releases/download/v51.6/shelly-dimmer-stm32_v51.6.bin", "eda483e111c914723a33f5088f1397d5c0b19333db4a88dc965636b976c16c36", ), + "51.7": ( + "https://github.com/jamesturton/shelly-dimmer-stm32/releases/download/v51.7/shelly-dimmer-stm32_v51.7.bin", + "7a20f1c967c469917368a79bc56498009045237080408cef7190743e08031889", + ), } From 2fa7f8c5112333a65c1a5c2de85cc28687f0d1c7 Mon Sep 17 00:00:00 2001 From: Philipp Helo Rehs Date: Sun, 17 Sep 2023 07:30:52 +0200 Subject: [PATCH 05/14] Add E-Trailer Gaslevel support to Mopeka Std Check (#5397) * Add E-Trailer Gaslevel support to Mopeka Std Check Signed-off-by: Philipp Helo Rehs * fix format --------- Signed-off-by: Philipp Helo Rehs Co-authored-by: Philipp Helo Rehs --- esphome/components/mopeka_std_check/mopeka_std_check.cpp | 3 ++- esphome/components/mopeka_std_check/mopeka_std_check.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/esphome/components/mopeka_std_check/mopeka_std_check.cpp b/esphome/components/mopeka_std_check/mopeka_std_check.cpp index 67e749c68b..9dd1718cb2 100644 --- a/esphome/components/mopeka_std_check/mopeka_std_check.cpp +++ b/esphome/components/mopeka_std_check/mopeka_std_check.cpp @@ -71,7 +71,8 @@ bool MopekaStdCheck::parse_device(const esp32_ble_tracker::ESPBTDevice &device) const auto *mopeka_data = (const mopeka_std_package *) manu_data.data.data(); const u_int8_t hardware_id = mopeka_data->data_1 & 0xCF; - if (static_cast(hardware_id) != STANDARD && static_cast(hardware_id) != XL) { + if (static_cast(hardware_id) != STANDARD && static_cast(hardware_id) != XL && + static_cast(hardware_id) != ETRAILER) { ESP_LOGE(TAG, "[%s] Unsupported Sensor Type (0x%X)", device.address_str().c_str(), hardware_id); return false; } diff --git a/esphome/components/mopeka_std_check/mopeka_std_check.h b/esphome/components/mopeka_std_check/mopeka_std_check.h index e4d81afbd7..ee588c8e5f 100644 --- a/esphome/components/mopeka_std_check/mopeka_std_check.h +++ b/esphome/components/mopeka_std_check/mopeka_std_check.h @@ -14,6 +14,7 @@ namespace mopeka_std_check { enum SensorType { STANDARD = 0x02, XL = 0x03, + ETRAILER = 0x46, }; // 4 values in one struct so it aligns to 8 byte. One `mopeka_std_values` is 40 bit long. From e8862620556008834356669be14f93a2b3395d62 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Wed, 20 Sep 2023 14:20:54 -0700 Subject: [PATCH 06/14] fix disabled wifi power on 8266 (#5409) Co-authored-by: Samuel Sieb --- esphome/components/wifi/wifi_component_esp8266.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index 1afa439567..6e7c491967 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -98,6 +98,7 @@ bool WiFiComponent::wifi_apply_power_save_() { power_save = NONE_SLEEP_T; break; } + wifi_fpm_auto_sleep_set_in_null_mode(1); return wifi_set_sleep_type(power_save); } From e55636ed521bc2feda4ce690c9b6eba50a8cf1cb Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Wed, 20 Sep 2023 14:25:16 -0700 Subject: [PATCH 07/14] fix handling of web server version (#5405) Co-authored-by: Samuel Sieb --- esphome/components/web_server/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/web_server/__init__.py b/esphome/components/web_server/__init__.py index c6d9c31e93..966c978836 100644 --- a/esphome/components/web_server/__init__.py +++ b/esphome/components/web_server/__init__.py @@ -59,7 +59,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), + cv.Optional(CONF_VERSION, default=2): cv.one_of(1, 2, int=True), cv.Optional(CONF_CSS_URL): cv.string, cv.Optional(CONF_CSS_INCLUDE): cv.file_, cv.Optional(CONF_JS_URL): cv.string, From 8f1ce8c7f7a6a86b0e9d98e9324f9ab6ff0e41e2 Mon Sep 17 00:00:00 2001 From: Joris S <100357138+Jorre05@users.noreply.github.com> Date: Wed, 20 Sep 2023 23:28:03 +0200 Subject: [PATCH 08/14] Climate preset fix (#5407) --- esphome/components/thermostat/thermostat_climate.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esphome/components/thermostat/thermostat_climate.cpp b/esphome/components/thermostat/thermostat_climate.cpp index 51da663a0c..386e13dc37 100644 --- a/esphome/components/thermostat/thermostat_climate.cpp +++ b/esphome/components/thermostat/thermostat_climate.cpp @@ -986,6 +986,7 @@ void ThermostatClimate::change_preset_(climate::ClimatePreset preset) { // Fire any preset changed trigger if defined Trigger<> *trig = this->preset_change_trigger_; assert(trig != nullptr); + this->preset = preset; trig->trigger(); this->refresh(); @@ -1010,6 +1011,7 @@ void ThermostatClimate::change_custom_preset_(const std::string &custom_preset) // Fire any preset changed trigger if defined Trigger<> *trig = this->preset_change_trigger_; assert(trig != nullptr); + this->custom_preset = custom_preset; trig->trigger(); this->refresh(); From 41c829fa32ec2b13eab7647ed806575e0f5897a4 Mon Sep 17 00:00:00 2001 From: Anthony Date: Wed, 20 Sep 2023 16:30:22 -0500 Subject: [PATCH 09/14] Remove Wi-Fi dependency from Midea component (#5394) --- esphome/components/midea/climate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/components/midea/climate.py b/esphome/components/midea/climate.py index 80b1461576..074ab8abb2 100644 --- a/esphome/components/midea/climate.py +++ b/esphome/components/midea/climate.py @@ -35,7 +35,7 @@ from esphome.components.climate import ( ) CODEOWNERS = ["@dudanov"] -DEPENDENCIES = ["climate", "uart", "wifi"] +DEPENDENCIES = ["climate", "uart"] AUTO_LOAD = ["sensor"] CONF_OUTDOOR_TEMPERATURE = "outdoor_temperature" CONF_POWER_USAGE = "power_usage" From 7ebe6a5894da94d1dd9c4c2e711e2c0ce8a087d3 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Wed, 20 Sep 2023 18:02:29 -0400 Subject: [PATCH 10/14] http_request: Cleanups and safety improvements (#5360) --- .../components/http_request/http_request.h | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/esphome/components/http_request/http_request.h b/esphome/components/http_request/http_request.h index 0958c07683..b885de18e6 100644 --- a/esphome/components/http_request/http_request.h +++ b/esphome/components/http_request/http_request.h @@ -80,8 +80,6 @@ template class HttpRequestSendAction : public Action { TEMPLATABLE_VALUE(std::string, url) TEMPLATABLE_VALUE(const char *, method) TEMPLATABLE_VALUE(std::string, body) - TEMPLATABLE_VALUE(const char *, useragent) - TEMPLATABLE_VALUE(uint16_t, timeout) void add_header(const char *key, TemplatableValue value) { this->headers_.insert({key, value}); } @@ -105,25 +103,18 @@ template class HttpRequestSendAction : public Action { auto f = std::bind(&HttpRequestSendAction::encode_json_func_, this, x..., std::placeholders::_1); this->parent_->set_body(json::build_json(f)); } - if (this->useragent_.has_value()) { - this->parent_->set_useragent(this->useragent_.value(x...)); - } - if (this->timeout_.has_value()) { - this->parent_->set_timeout(this->timeout_.value(x...)); - } - if (!this->headers_.empty()) { - std::list
headers; - for (const auto &item : this->headers_) { - auto val = item.second; - Header header; - header.name = item.first; - header.value = val.value(x...); - headers.push_back(header); - } - this->parent_->set_headers(headers); + std::list
headers; + for (const auto &item : this->headers_) { + auto val = item.second; + Header header; + header.name = item.first; + header.value = val.value(x...); + headers.push_back(header); } + this->parent_->set_headers(headers); this->parent_->send(this->response_triggers_); this->parent_->close(); + this->parent_->set_body(""); } protected: From 807c47a076e202d681affe65414b49c40a0015d5 Mon Sep 17 00:00:00 2001 From: Trent Houliston Date: Thu, 21 Sep 2023 08:04:03 +1000 Subject: [PATCH 11/14] Make the pulse meter timeout on startup when no pulses are received (#5388) --- .../pulse_meter/pulse_meter_sensor.cpp | 35 +++++++++++++------ .../pulse_meter/pulse_meter_sensor.h | 3 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/esphome/components/pulse_meter/pulse_meter_sensor.cpp b/esphome/components/pulse_meter/pulse_meter_sensor.cpp index 7eef18e5e0..be5fad6fe5 100644 --- a/esphome/components/pulse_meter/pulse_meter_sensor.cpp +++ b/esphome/components/pulse_meter/pulse_meter_sensor.cpp @@ -11,6 +11,9 @@ void PulseMeterSensor::setup() { this->pin_->setup(); this->isr_pin_ = pin_->to_isr(); + // Set the last processed edge to now for the first timeout + this->last_processed_edge_us_ = micros(); + if (this->filter_mode_ == FILTER_EDGE) { this->pin_->attach_interrupt(PulseMeterSensor::edge_intr, this, gpio::INTERRUPT_RISING_EDGE); } else if (this->filter_mode_ == FILTER_PULSE) { @@ -38,12 +41,16 @@ void PulseMeterSensor::loop() { } // We need to detect at least two edges to have a valid pulse width - if (!this->initialized_) { - this->initialized_ = true; - } else { - uint32_t delta_us = this->get_->last_detected_edge_us_ - this->last_processed_edge_us_; - float pulse_width_us = delta_us / float(this->get_->count_); - this->publish_state((60.0f * 1000000.0f) / pulse_width_us); + switch (this->meter_state_) { + case MeterState::INITIAL: + case MeterState::TIMED_OUT: { + this->meter_state_ = MeterState::RUNNING; + } break; + case MeterState::RUNNING: { + uint32_t delta_us = this->get_->last_detected_edge_us_ - this->last_processed_edge_us_; + float pulse_width_us = delta_us / float(this->get_->count_); + this->publish_state((60.0f * 1000000.0f) / pulse_width_us); + } break; } this->last_processed_edge_us_ = this->get_->last_detected_edge_us_; @@ -53,10 +60,18 @@ void PulseMeterSensor::loop() { const uint32_t now = micros(); const uint32_t time_since_valid_edge_us = now - this->last_processed_edge_us_; - if (this->initialized_ && time_since_valid_edge_us > this->timeout_us_) { - ESP_LOGD(TAG, "No pulse detected for %us, assuming 0 pulses/min", time_since_valid_edge_us / 1000000); - this->initialized_ = false; - this->publish_state(0.0f); + switch (this->meter_state_) { + // Running and initial states can timeout + case MeterState::INITIAL: + case MeterState::RUNNING: { + if (time_since_valid_edge_us > this->timeout_us_) { + this->meter_state_ = MeterState::TIMED_OUT; + ESP_LOGD(TAG, "No pulse detected for %us, assuming 0 pulses/min", time_since_valid_edge_us / 1000000); + this->publish_state(0.0f); + } + } break; + default: + break; } } } diff --git a/esphome/components/pulse_meter/pulse_meter_sensor.h b/esphome/components/pulse_meter/pulse_meter_sensor.h index ddd42c2ed5..f376ea48a5 100644 --- a/esphome/components/pulse_meter/pulse_meter_sensor.h +++ b/esphome/components/pulse_meter/pulse_meter_sensor.h @@ -38,7 +38,8 @@ class PulseMeterSensor : public sensor::Sensor, public Component { InternalFilterMode filter_mode_{FILTER_EDGE}; // Variables used in the loop - bool initialized_ = false; + enum class MeterState { INITIAL, RUNNING, TIMED_OUT }; + MeterState meter_state_ = MeterState::INITIAL; uint32_t total_pulses_ = 0; uint32_t last_processed_edge_us_ = 0; From d7e267eca53e47beec3496e9458ccce151d25ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Thu, 21 Sep 2023 00:09:23 +0200 Subject: [PATCH 12/14] Wizard: fix colored text in input prompts (#5313) --- esphome/util.py | 14 ++++++++++---- esphome/wizard.py | 18 ++++++++++-------- tests/unit_tests/test_wizard.py | 12 ++++++------ 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/esphome/util.py b/esphome/util.py index 0d60212f50..480618aca0 100644 --- a/esphome/util.py +++ b/esphome/util.py @@ -57,7 +57,7 @@ class SimpleRegistry(dict): return decorator -def safe_print(message=""): +def safe_print(message="", end="\n"): from esphome.core import CORE if CORE.dashboard: @@ -67,20 +67,26 @@ def safe_print(message=""): pass try: - print(message) + print(message, end=end) return except UnicodeEncodeError: pass try: - print(message.encode("utf-8", "backslashreplace")) + print(message.encode("utf-8", "backslashreplace"), end=end) except UnicodeEncodeError: try: - print(message.encode("ascii", "backslashreplace")) + print(message.encode("ascii", "backslashreplace"), end=end) except UnicodeEncodeError: print("Cannot print line because of invalid locale!") +def safe_input(prompt=""): + if prompt: + safe_print(prompt, end="") + return input() + + def shlex_quote(s): if not s: return "''" diff --git a/esphome/wizard.py b/esphome/wizard.py index aa05e513a7..1308338ad0 100644 --- a/esphome/wizard.py +++ b/esphome/wizard.py @@ -11,7 +11,7 @@ from esphome.core import CORE from esphome.helpers import get_bool_env, write_file from esphome.log import Fore, color from esphome.storage_json import StorageJSON, ext_storage_path -from esphome.util import safe_print +from esphome.util import safe_input, safe_print CORE_BIG = r""" _____ ____ _____ ______ / ____/ __ \| __ \| ____| @@ -252,7 +252,7 @@ def safe_print_step(step, big): def default_input(text, default): safe_print() safe_print(f"Press ENTER for default ({default})") - return input(text.format(default)) or default + return safe_input(text.format(default)) or default # From https://stackoverflow.com/a/518232/8924614 @@ -306,7 +306,7 @@ def wizard(path): ) safe_print() sleep(1) - name = input(color(Fore.BOLD_WHITE, "(name): ")) + name = safe_input(color(Fore.BOLD_WHITE, "(name): ")) while True: try: @@ -343,7 +343,9 @@ def wizard(path): while True: sleep(0.5) safe_print() - platform = input(color(Fore.BOLD_WHITE, f"({'/'.join(wizard_platforms)}): ")) + platform = safe_input( + color(Fore.BOLD_WHITE, f"({'/'.join(wizard_platforms)}): ") + ) try: platform = vol.All(vol.Upper, vol.Any(*wizard_platforms))(platform.upper()) break @@ -397,7 +399,7 @@ def wizard(path): boards.append(board_id) while True: - board = input(color(Fore.BOLD_WHITE, "(board): ")) + board = safe_input(color(Fore.BOLD_WHITE, "(board): ")) try: board = vol.All(vol.Lower, vol.Any(*boards))(board) break @@ -423,7 +425,7 @@ def wizard(path): sleep(1.5) safe_print(f"For example \"{color(Fore.BOLD_WHITE, 'Abraham Linksys')}\".") while True: - ssid = input(color(Fore.BOLD_WHITE, "(ssid): ")) + ssid = safe_input(color(Fore.BOLD_WHITE, "(ssid): ")) try: ssid = cv.ssid(ssid) break @@ -449,7 +451,7 @@ def wizard(path): safe_print() safe_print(f"For example \"{color(Fore.BOLD_WHITE, 'PASSWORD42')}\"") sleep(0.5) - psk = input(color(Fore.BOLD_WHITE, "(PSK): ")) + psk = safe_input(color(Fore.BOLD_WHITE, "(PSK): ")) safe_print( "Perfect! WiFi is now set up (you can create static IPs and so on later)." ) @@ -466,7 +468,7 @@ def wizard(path): safe_print() sleep(0.25) safe_print("Press ENTER for no password") - password = input(color(Fore.BOLD_WHITE, "(password): ")) + password = safe_input(color(Fore.BOLD_WHITE, "(password): ")) if not wizard_write( path=path, diff --git a/tests/unit_tests/test_wizard.py b/tests/unit_tests/test_wizard.py index 8bbce08ae5..46700a3ba8 100644 --- a/tests/unit_tests/test_wizard.py +++ b/tests/unit_tests/test_wizard.py @@ -319,7 +319,7 @@ def test_wizard_accepts_default_answers_esp8266(tmpdir, monkeypatch, wizard_answ config_file = tmpdir.join("test.yaml") input_mock = MagicMock(side_effect=wizard_answers) monkeypatch.setattr("builtins.input", input_mock) - monkeypatch.setattr(wz, "safe_print", lambda t=None: 0) + monkeypatch.setattr(wz, "safe_print", lambda t=None, end=None: 0) monkeypatch.setattr(wz, "sleep", lambda _: 0) monkeypatch.setattr(wz, "wizard_write", MagicMock()) @@ -341,7 +341,7 @@ def test_wizard_accepts_default_answers_esp32(tmpdir, monkeypatch, wizard_answer config_file = tmpdir.join("test.yaml") input_mock = MagicMock(side_effect=wizard_answers) monkeypatch.setattr("builtins.input", input_mock) - monkeypatch.setattr(wz, "safe_print", lambda t=None: 0) + monkeypatch.setattr(wz, "safe_print", lambda t=None, end=None: 0) monkeypatch.setattr(wz, "sleep", lambda _: 0) monkeypatch.setattr(wz, "wizard_write", MagicMock()) @@ -371,7 +371,7 @@ def test_wizard_offers_better_node_name(tmpdir, monkeypatch, wizard_answers): config_file = tmpdir.join("test.yaml") input_mock = MagicMock(side_effect=wizard_answers) monkeypatch.setattr("builtins.input", input_mock) - monkeypatch.setattr(wz, "safe_print", lambda t=None: 0) + monkeypatch.setattr(wz, "safe_print", lambda t=None, end=None: 0) monkeypatch.setattr(wz, "sleep", lambda _: 0) monkeypatch.setattr(wz, "wizard_write", MagicMock()) @@ -394,7 +394,7 @@ def test_wizard_requires_correct_platform(tmpdir, monkeypatch, wizard_answers): config_file = tmpdir.join("test.yaml") input_mock = MagicMock(side_effect=wizard_answers) monkeypatch.setattr("builtins.input", input_mock) - monkeypatch.setattr(wz, "safe_print", lambda t=None: 0) + monkeypatch.setattr(wz, "safe_print", lambda t=None, end=None: 0) monkeypatch.setattr(wz, "sleep", lambda _: 0) monkeypatch.setattr(wz, "wizard_write", MagicMock()) @@ -416,7 +416,7 @@ def test_wizard_requires_correct_board(tmpdir, monkeypatch, wizard_answers): config_file = tmpdir.join("test.yaml") input_mock = MagicMock(side_effect=wizard_answers) monkeypatch.setattr("builtins.input", input_mock) - monkeypatch.setattr(wz, "safe_print", lambda t=None: 0) + monkeypatch.setattr(wz, "safe_print", lambda t=None, end=None: 0) monkeypatch.setattr(wz, "sleep", lambda _: 0) monkeypatch.setattr(wz, "wizard_write", MagicMock()) @@ -438,7 +438,7 @@ def test_wizard_requires_valid_ssid(tmpdir, monkeypatch, wizard_answers): config_file = tmpdir.join("test.yaml") input_mock = MagicMock(side_effect=wizard_answers) monkeypatch.setattr("builtins.input", input_mock) - monkeypatch.setattr(wz, "safe_print", lambda t=None: 0) + monkeypatch.setattr(wz, "safe_print", lambda t=None, end=None: 0) monkeypatch.setattr(wz, "sleep", lambda _: 0) monkeypatch.setattr(wz, "wizard_write", MagicMock()) From 5b46088ae4089fa8f8c02f3a54a86d2f9da0bb24 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Wed, 20 Sep 2023 15:26:36 -0700 Subject: [PATCH 13/14] support keypads with pulldowns (#5404) Co-authored-by: Samuel Sieb --- esphome/components/matrix_keypad/__init__.py | 4 ++++ .../components/matrix_keypad/matrix_keypad.cpp | 17 +++++++++++------ .../components/matrix_keypad/matrix_keypad.h | 2 ++ tests/test5.yaml | 1 + 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/esphome/components/matrix_keypad/__init__.py b/esphome/components/matrix_keypad/__init__.py index 1c549007b9..5250a45732 100644 --- a/esphome/components/matrix_keypad/__init__.py +++ b/esphome/components/matrix_keypad/__init__.py @@ -21,6 +21,7 @@ CONF_COLUMNS = "columns" CONF_KEYS = "keys" CONF_DEBOUNCE_TIME = "debounce_time" CONF_HAS_DIODES = "has_diodes" +CONF_HAS_PULLDOWNS = "has_pulldowns" def check_keys(obj): @@ -45,6 +46,7 @@ CONFIG_SCHEMA = cv.All( cv.Optional(CONF_KEYS): cv.string, cv.Optional(CONF_DEBOUNCE_TIME, default=1): cv.int_range(min=1, max=100), cv.Optional(CONF_HAS_DIODES): cv.boolean, + cv.Optional(CONF_HAS_PULLDOWNS): cv.boolean, } ), check_keys, @@ -69,3 +71,5 @@ async def to_code(config): cg.add(var.set_debounce_time(config[CONF_DEBOUNCE_TIME])) if CONF_HAS_DIODES in config: cg.add(var.set_has_diodes(config[CONF_HAS_DIODES])) + if CONF_HAS_PULLDOWNS in config: + cg.add(var.set_has_pulldowns(config[CONF_HAS_PULLDOWNS])) diff --git a/esphome/components/matrix_keypad/matrix_keypad.cpp b/esphome/components/matrix_keypad/matrix_keypad.cpp index 4f8962a782..902e574846 100644 --- a/esphome/components/matrix_keypad/matrix_keypad.cpp +++ b/esphome/components/matrix_keypad/matrix_keypad.cpp @@ -11,11 +11,16 @@ void MatrixKeypad::setup() { if (!has_diodes_) { pin->pin_mode(gpio::FLAG_INPUT); } else { - pin->digital_write(true); + pin->digital_write(!has_pulldowns_); + } + } + for (auto *pin : this->columns_) { + if (has_pulldowns_) { + pin->pin_mode(gpio::FLAG_INPUT); + } else { + pin->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP); } } - for (auto *pin : this->columns_) - pin->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP); } void MatrixKeypad::loop() { @@ -28,9 +33,9 @@ void MatrixKeypad::loop() { for (auto *row : this->rows_) { if (!has_diodes_) row->pin_mode(gpio::FLAG_OUTPUT); - row->digital_write(false); + row->digital_write(has_pulldowns_); for (auto *col : this->columns_) { - if (!col->digital_read()) { + if (col->digital_read() == has_pulldowns_) { if (key != -1) { error = true; } else { @@ -39,7 +44,7 @@ void MatrixKeypad::loop() { } pos++; } - row->digital_write(true); + row->digital_write(!has_pulldowns_); if (!has_diodes_) row->pin_mode(gpio::FLAG_INPUT); } diff --git a/esphome/components/matrix_keypad/matrix_keypad.h b/esphome/components/matrix_keypad/matrix_keypad.h index 9f5942be9a..d506040b7c 100644 --- a/esphome/components/matrix_keypad/matrix_keypad.h +++ b/esphome/components/matrix_keypad/matrix_keypad.h @@ -28,6 +28,7 @@ class MatrixKeypad : public key_provider::KeyProvider, public Component { void set_keys(std::string keys) { keys_ = std::move(keys); }; void set_debounce_time(int debounce_time) { debounce_time_ = debounce_time; }; void set_has_diodes(int has_diodes) { has_diodes_ = has_diodes; }; + void set_has_pulldowns(int has_pulldowns) { has_pulldowns_ = has_pulldowns; }; void register_listener(MatrixKeypadListener *listener); @@ -37,6 +38,7 @@ class MatrixKeypad : public key_provider::KeyProvider, public Component { std::string keys_; int debounce_time_ = 0; bool has_diodes_{false}; + bool has_pulldowns_{false}; int pressed_key_ = -1; std::vector listeners_{}; diff --git a/tests/test5.yaml b/tests/test5.yaml index 274570aad6..5727d30e61 100644 --- a/tests/test5.yaml +++ b/tests/test5.yaml @@ -667,6 +667,7 @@ matrix_keypad: - pin: 17 - pin: 16 keys: "1234" + has_pulldowns: true key_collector: - id: reader From 90835ab917ec52e2e9de464477f9e24988392be0 Mon Sep 17 00:00:00 2001 From: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Date: Thu, 21 Sep 2023 10:35:38 +1200 Subject: [PATCH 14/14] Bump version to 2023.9.0b2 --- esphome/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esphome/const.py b/esphome/const.py index cbb31e0ec6..8a10776c4a 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2023.9.0b1" +__version__ = "2023.9.0b2" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" VALID_SUBSTITUTIONS_CHARACTERS = (