diff --git a/esphome/components/dht/dht.cpp b/esphome/components/dht/dht.cpp index 988a5300dd..9626260cf2 100644 --- a/esphome/components/dht/dht.cpp +++ b/esphome/components/dht/dht.cpp @@ -32,19 +32,19 @@ void DHT::dump_config() { void DHT::update() { float temperature, humidity; - bool error; + bool success; if (this->model_ == DHT_MODEL_AUTO_DETECT) { this->model_ = DHT_MODEL_DHT22; - error = this->read_sensor_(&temperature, &humidity, false); - if (error) { + success = this->read_sensor_(&temperature, &humidity, false); + if (!success) { this->model_ = DHT_MODEL_DHT11; return; } } else { - error = this->read_sensor_(&temperature, &humidity, true); + success = this->read_sensor_(&temperature, &humidity, true); } - if (error) { + if (success) { ESP_LOGD(TAG, "Got Temperature=%.1f°C Humidity=%.1f%%", temperature, humidity); if (this->temperature_sensor_ != nullptr) diff --git a/esphome/components/max7219/display.py b/esphome/components/max7219/display.py index 0657f3f042..05b383004d 100644 --- a/esphome/components/max7219/display.py +++ b/esphome/components/max7219/display.py @@ -9,11 +9,14 @@ max7219_ns = cg.esphome_ns.namespace('max7219') MAX7219Component = max7219_ns.class_('MAX7219Component', cg.PollingComponent, spi.SPIDevice) MAX7219ComponentRef = MAX7219Component.operator('ref') +CONF_REVERSE_ENABLE = 'reverse_enable' + CONFIG_SCHEMA = display.BASIC_DISPLAY_SCHEMA.extend({ cv.GenerateID(): cv.declare_id(MAX7219Component), cv.Optional(CONF_NUM_CHIPS, default=1): cv.int_range(min=1, max=255), cv.Optional(CONF_INTENSITY, default=15): cv.int_range(min=0, max=15), + cv.Optional(CONF_REVERSE_ENABLE, default=False): cv.boolean, }).extend(cv.polling_component_schema('1s')).extend(spi.spi_device_schema()) @@ -25,6 +28,7 @@ def to_code(config): cg.add(var.set_num_chips(config[CONF_NUM_CHIPS])) cg.add(var.set_intensity(config[CONF_INTENSITY])) + cg.add(var.set_reverse(config[CONF_REVERSE_ENABLE])) if CONF_LAMBDA in config: lambda_ = yield cg.process_lambda(config[CONF_LAMBDA], [(MAX7219ComponentRef, 'it')], diff --git a/esphome/components/max7219/max7219.cpp b/esphome/components/max7219/max7219.cpp index 99eca6c14f..f58f203442 100644 --- a/esphome/components/max7219/max7219.cpp +++ b/esphome/components/max7219/max7219.cpp @@ -142,9 +142,11 @@ void MAX7219Component::dump_config() { void MAX7219Component::display() { for (uint8_t i = 0; i < 8; i++) { this->enable(); - for (uint8_t j = 0; j < this->num_chips_; j++) { - this->send_byte_(8 - i, this->buffer_[j * 8 + i]); - } + for (uint8_t j = 0; j < this->num_chips_; j++) + if (reverse_) + this->send_byte_(8 - i, buffer_[(num_chips_ - j - 1) * 8 + i]); + else + this->send_byte_(8 - i, buffer_[j * 8 + i]); this->disable(); } } diff --git a/esphome/components/max7219/max7219.h b/esphome/components/max7219/max7219.h index 1920268ba4..47b54a4c50 100644 --- a/esphome/components/max7219/max7219.h +++ b/esphome/components/max7219/max7219.h @@ -34,6 +34,7 @@ class MAX7219Component : public PollingComponent, void set_intensity(uint8_t intensity); void set_num_chips(uint8_t num_chips); + void set_reverse(bool reverse) { this->reverse_ = reverse; }; /// Evaluate the printf-format and print the result at the given position. uint8_t printf(uint8_t pos, const char *format, ...) __attribute__((format(printf, 3, 4))); @@ -60,6 +61,7 @@ class MAX7219Component : public PollingComponent, uint8_t intensity_{15}; /// Intensity of the display from 0 to 15 (most) uint8_t num_chips_{1}; uint8_t *buffer_; + bool reverse_{false}; optional writer_{}; }; diff --git a/esphome/components/ota/__init__.py b/esphome/components/ota/__init__.py index e4b6946116..8956227c17 100644 --- a/esphome/components/ota/__init__.py +++ b/esphome/components/ota/__init__.py @@ -1,3 +1,4 @@ +from esphome.cpp_generator import RawExpression import esphome.codegen as cg import esphome.config_validation as cv from esphome.const import ( @@ -31,7 +32,9 @@ def to_code(config): yield cg.register_component(var, config) if config[CONF_SAFE_MODE]: - cg.add(var.start_safe_mode(config[CONF_NUM_ATTEMPTS], config[CONF_REBOOT_TIMEOUT])) + condition = var.should_enter_safe_mode(config[CONF_NUM_ATTEMPTS], + config[CONF_REBOOT_TIMEOUT]) + cg.add(RawExpression(f"if ({condition}) return")) if CORE.is_esp8266: cg.add_library('Update', None) diff --git a/esphome/components/ota/ota_component.cpp b/esphome/components/ota/ota_component.cpp index b614139e07..c8221d1bdf 100644 --- a/esphome/components/ota/ota_component.cpp +++ b/esphome/components/ota/ota_component.cpp @@ -355,7 +355,7 @@ void OTAComponent::set_auth_password(const std::string &password) { this->passwo float OTAComponent::get_setup_priority() const { return setup_priority::AFTER_WIFI; } uint16_t OTAComponent::get_port() const { return this->port_; } void OTAComponent::set_port(uint16_t port) { this->port_ = port; } -void OTAComponent::start_safe_mode(uint8_t num_attempts, uint32_t enable_time) { +bool OTAComponent::should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time) { this->has_safe_mode_ = true; this->safe_mode_start_time_ = millis(); this->safe_mode_enable_time_ = enable_time; @@ -380,12 +380,11 @@ void OTAComponent::start_safe_mode(uint8_t num_attempts, uint32_t enable_time) { ESP_LOGI(TAG, "Waiting for OTA attempt."); - while (true) { - App.loop(); - } + return true; } else { // increment counter this->write_rtc_(this->safe_mode_rtc_value_ + 1); + return false; } } void OTAComponent::write_rtc_(uint32_t val) { this->rtc_.save(&val); } diff --git a/esphome/components/ota/ota_component.h b/esphome/components/ota/ota_component.h index 65d44482b8..f16725e324 100644 --- a/esphome/components/ota/ota_component.h +++ b/esphome/components/ota/ota_component.h @@ -47,7 +47,7 @@ class OTAComponent : public Component { /// Manually set the port OTA should listen on. void set_port(uint16_t port); - void start_safe_mode(uint8_t num_attempts, uint32_t enable_time); + bool should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time); // ========== INTERNAL METHODS ========== // (In most use cases you won't need these) diff --git a/esphome/components/waveshare_epaper/display.py b/esphome/components/waveshare_epaper/display.py index da2e30de00..fcbbc0a500 100644 --- a/esphome/components/waveshare_epaper/display.py +++ b/esphome/components/waveshare_epaper/display.py @@ -27,6 +27,7 @@ MODELS = { '2.13in-ttgo': ('a', WaveshareEPaperTypeAModel.TTGO_EPAPER_2_13_IN), '2.13in-ttgo-b73': ('a', WaveshareEPaperTypeAModel.TTGO_EPAPER_2_13_IN_B73), '2.90in': ('a', WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN), + '2.90inv2': ('a', WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN_V2), '2.70in': ('b', WaveshareEPaper2P7In), '2.90in-b': ('b', WaveshareEPaper2P9InB), '4.20in': ('b', WaveshareEPaper4P2In), @@ -41,7 +42,7 @@ def validate_full_update_every_only_type_a(value): return value if MODELS[value[CONF_MODEL]][0] != 'a': raise cv.Invalid("The 'full_update_every' option is only available for models " - "'1.54in', '2.13in' and '2.90in'.") + "'1.54in', '2.13in', '2.90in', and '2.90inV2'.") return value diff --git a/esphome/components/waveshare_epaper/waveshare_epaper.cpp b/esphome/components/waveshare_epaper/waveshare_epaper.cpp index d57b814bb2..fa0cf6aa4f 100644 --- a/esphome/components/waveshare_epaper/waveshare_epaper.cpp +++ b/esphome/components/waveshare_epaper/waveshare_epaper.cpp @@ -178,6 +178,13 @@ void WaveshareEPaperTypeA::initialize() { // COMMAND DATA ENTRY MODE SETTING this->command(0x11); this->data(0x03); // from top left to bottom right + + if (this->model_ == WAVESHARE_EPAPER_2_9_IN_V2) { + // RAM content option for Display Update + this->command(0x21); + this->data(0x00); + this->data(0x80); + } } void WaveshareEPaperTypeA::dump_config() { LOG_DISPLAY("", "Waveshare E-Paper", this); @@ -197,6 +204,9 @@ void WaveshareEPaperTypeA::dump_config() { case WAVESHARE_EPAPER_2_9_IN: ESP_LOGCONFIG(TAG, " Model: 2.9in"); break; + case WAVESHARE_EPAPER_2_9_IN_V2: + ESP_LOGCONFIG(TAG, " Model: 2.9inV2"); + break; } ESP_LOGCONFIG(TAG, " Full Update Every: %u", this->full_update_every_); LOG_PIN(" Reset Pin: ", this->reset_pin_); @@ -205,14 +215,15 @@ void WaveshareEPaperTypeA::dump_config() { LOG_UPDATE_INTERVAL(this); } void HOT WaveshareEPaperTypeA::display() { + bool full_update = this->at_update_ == 0; + bool prev_full_update = this->at_update_ == 1; + if (!this->wait_until_idle_()) { this->status_set_warning(); return; } if (this->full_update_every_ >= 2) { - bool prev_full_update = this->at_update_ == 1; - bool full_update = this->at_update_ == 0; if (full_update != prev_full_update) { if (this->model_ == TTGO_EPAPER_2_13_IN) { this->write_lut_(full_update ? FULL_UPDATE_LUT_TTGO : PARTIAL_UPDATE_LUT_TTGO, LUT_SIZE_TTGO); @@ -258,7 +269,12 @@ void HOT WaveshareEPaperTypeA::display() { // COMMAND DISPLAY UPDATE CONTROL 2 this->command(0x22); - this->data(0xC4); + if (this->model_ == WAVESHARE_EPAPER_2_9_IN_V2) { + this->data(full_update ? 0xF7 : 0xFF); + } else { + this->data(0xC4); + } + // COMMAND MASTER ACTIVATION this->command(0x20); // COMMAND TERMINATE FRAME READ WRITE @@ -278,6 +294,8 @@ int WaveshareEPaperTypeA::get_width_internal() { return 128; case WAVESHARE_EPAPER_2_9_IN: return 128; + case WAVESHARE_EPAPER_2_9_IN_V2: + return 128; } return 0; } @@ -293,6 +311,8 @@ int WaveshareEPaperTypeA::get_height_internal() { return 250; case WAVESHARE_EPAPER_2_9_IN: return 296; + case WAVESHARE_EPAPER_2_9_IN_V2: + return 296; } return 0; } diff --git a/esphome/components/waveshare_epaper/waveshare_epaper.h b/esphome/components/waveshare_epaper/waveshare_epaper.h index 01b162fd35..8ea73d053a 100644 --- a/esphome/components/waveshare_epaper/waveshare_epaper.h +++ b/esphome/components/waveshare_epaper/waveshare_epaper.h @@ -67,6 +67,7 @@ enum WaveshareEPaperTypeAModel { WAVESHARE_EPAPER_1_54_IN = 0, WAVESHARE_EPAPER_2_13_IN, WAVESHARE_EPAPER_2_9_IN, + WAVESHARE_EPAPER_2_9_IN_V2, TTGO_EPAPER_2_13_IN, TTGO_EPAPER_2_13_IN_B73, }; @@ -82,8 +83,14 @@ class WaveshareEPaperTypeA : public WaveshareEPaper { void display() override; void deep_sleep() override { - // COMMAND DEEP SLEEP MODE - this->command(0x10); + if (this->model_ == WAVESHARE_EPAPER_2_9_IN_V2) { + // COMMAND DEEP SLEEP MODE + this->command(0x10); + this->data(0x01); + } else { + // COMMAND DEEP SLEEP MODE + this->command(0x10); + } this->wait_until_idle_(); } diff --git a/esphome/const.py b/esphome/const.py index b66d3a141a..5313fe5413 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -2,7 +2,7 @@ MAJOR_VERSION = 1 MINOR_VERSION = 16 -PATCH_VERSION = '1' +PATCH_VERSION = '2' __short_version__ = f'{MAJOR_VERSION}.{MINOR_VERSION}' __version__ = f'{__short_version__}.{PATCH_VERSION}' diff --git a/tests/test1.yaml b/tests/test1.yaml index a4cf1e42dc..f274defc46 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -1785,6 +1785,15 @@ display: full_update_every: 30 lambda: |- it.rectangle(0, 0, it.get_width(), it.get_height()); + - platform: waveshare_epaper + cs_pin: GPIO23 + dc_pin: GPIO23 + busy_pin: GPIO23 + reset_pin: GPIO23 + model: 2.90inv2 + full_update_every: 30 + lambda: |- + it.rectangle(0, 0, it.get_width(), it.get_height()); - platform: st7789v cs_pin: GPIO5 dc_pin: GPIO16