Merge pull request #2523 from esphome/bump-2021.10.0b3

2021.10.0b3
This commit is contained in:
Jesse Hills 2021-10-15 10:15:26 +13:00 committed by GitHub
commit ec683fc227
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 143 additions and 41 deletions

View file

@ -2,6 +2,7 @@ import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.components import i2c from esphome.components import i2c
from esphome.const import CONF_ID from esphome.const import CONF_ID
from esphome.core import CORE
CODEOWNERS = ["@trvrnrth"] CODEOWNERS = ["@trvrnrth"]
DEPENDENCIES = ["i2c"] DEPENDENCIES = ["i2c"]
@ -44,7 +45,8 @@ CONFIG_SCHEMA = cv.Schema(
cv.Optional( cv.Optional(
CONF_STATE_SAVE_INTERVAL, default="6hours" CONF_STATE_SAVE_INTERVAL, default="6hours"
): cv.positive_time_period_minutes, ): cv.positive_time_period_minutes,
} },
cv.only_with_arduino,
).extend(i2c.i2c_device_schema(0x76)) ).extend(i2c.i2c_device_schema(0x76))
@ -60,5 +62,9 @@ async def to_code(config):
var.set_state_save_interval(config[CONF_STATE_SAVE_INTERVAL].total_milliseconds) var.set_state_save_interval(config[CONF_STATE_SAVE_INTERVAL].total_milliseconds)
) )
if CORE.is_esp32:
# Although this component does not use SPI, the BSEC library requires the SPI library
cg.add_library("SPI", None)
cg.add_define("USE_BSEC") cg.add_define("USE_BSEC")
cg.add_library("BSEC Software Library", "1.6.1480") cg.add_library("BSEC Software Library", "1.6.1480")

View file

@ -21,12 +21,16 @@ from esphome.core import CORE, HexInt
import esphome.config_validation as cv import esphome.config_validation as cv
import esphome.codegen as cg import esphome.codegen as cg
from .const import ( from .const import ( # noqa
KEY_BOARD, KEY_BOARD,
KEY_ESP32, KEY_ESP32,
KEY_SDKCONFIG_OPTIONS, KEY_SDKCONFIG_OPTIONS,
KEY_VARIANT, KEY_VARIANT,
VARIANT_ESP32,
VARIANT_ESP32S2,
VARIANT_ESP32S3,
VARIANT_ESP32C3, VARIANT_ESP32C3,
VARIANT_ESP32H2,
VARIANTS, VARIANTS,
) )

View file

@ -79,7 +79,7 @@ optional<LightColorValues> AddressableLightTransformer::apply() {
// dynamically-calculated alpha values to match the look. // dynamically-calculated alpha values to match the look.
float denom = (1.0f - smoothed_progress); float denom = (1.0f - smoothed_progress);
float alpha = denom == 0.0f ? 0.0f : (smoothed_progress - this->last_transition_progress_) / denom; float alpha = denom == 0.0f ? 1.0f : (smoothed_progress - this->last_transition_progress_) / denom;
// We need to use a low-resolution alpha here which makes the transition set in only after ~half of the length // We need to use a low-resolution alpha here which makes the transition set in only after ~half of the length
// We solve this by accumulating the fractional part of the alpha over time. // We solve this by accumulating the fractional part of the alpha over time.

View file

@ -16,24 +16,94 @@ class AddressableLightWrapper : public light::AddressableLight {
void clear_effect_data() override { this->wrapper_state_[4] = 0; } void clear_effect_data() override { this->wrapper_state_[4] = 0; }
light::LightTraits get_traits() override { return this->light_state_->get_traits(); } light::LightTraits get_traits() override {
LightTraits traits;
// Choose which color mode to use.
// This is ordered by how closely each color mode matches the underlying RGBW data structure used in LightPartition.
ColorMode color_mode_precedence[] = {ColorMode::RGB_WHITE,
ColorMode::RGB_COLD_WARM_WHITE,
ColorMode::RGB_COLOR_TEMPERATURE,
ColorMode::RGB,
ColorMode::WHITE,
ColorMode::COLD_WARM_WHITE,
ColorMode::COLOR_TEMPERATURE,
ColorMode::BRIGHTNESS,
ColorMode::ON_OFF,
ColorMode::UNKNOWN};
LightTraits parent_traits = this->light_state_->get_traits();
for (auto cm : color_mode_precedence) {
if (parent_traits.supports_color_mode(cm)) {
this->color_mode_ = cm;
break;
}
}
// Report a color mode that's compatible with both the partition and the underlying light
switch (this->color_mode_) {
case ColorMode::RGB_WHITE:
case ColorMode::RGB_COLD_WARM_WHITE:
case ColorMode::RGB_COLOR_TEMPERATURE:
traits.set_supported_color_modes({light::ColorMode::RGB_WHITE});
break;
case ColorMode::RGB:
traits.set_supported_color_modes({light::ColorMode::RGB});
break;
case ColorMode::WHITE:
case ColorMode::COLD_WARM_WHITE:
case ColorMode::COLOR_TEMPERATURE:
case ColorMode::BRIGHTNESS:
traits.set_supported_color_modes({light::ColorMode::BRIGHTNESS});
break;
case ColorMode::ON_OFF:
traits.set_supported_color_modes({light::ColorMode::ON_OFF});
break;
default:
traits.set_supported_color_modes({light::ColorMode::UNKNOWN});
}
return traits;
}
void write_state(light::LightState *state) override { void write_state(light::LightState *state) override {
// Don't overwrite state if the underlying light is turned on
if (this->light_state_->remote_values.is_on()) {
this->mark_shown_();
return;
}
float gamma = this->light_state_->get_gamma_correct(); float gamma = this->light_state_->get_gamma_correct();
float r = gamma_uncorrect(this->wrapper_state_[0] / 255.0f, gamma); float r = gamma_uncorrect(this->wrapper_state_[0] / 255.0f, gamma);
float g = gamma_uncorrect(this->wrapper_state_[1] / 255.0f, gamma); float g = gamma_uncorrect(this->wrapper_state_[1] / 255.0f, gamma);
float b = gamma_uncorrect(this->wrapper_state_[2] / 255.0f, gamma); float b = gamma_uncorrect(this->wrapper_state_[2] / 255.0f, gamma);
float w = gamma_uncorrect(this->wrapper_state_[3] / 255.0f, gamma); float w = gamma_uncorrect(this->wrapper_state_[3] / 255.0f, gamma);
float brightness = fmaxf(r, fmaxf(g, b));
auto call = this->light_state_->make_call(); auto call = this->light_state_->make_call();
float color_brightness = fmaxf(r, fmaxf(g, b));
float brightness = fmaxf(color_brightness, w);
if (brightness == 0.0f) {
call.set_state(false);
} else {
color_brightness /= brightness;
w /= brightness;
call.set_state(true); call.set_state(true);
call.set_brightness_if_supported(1.0f); call.set_color_mode_if_supported(this->color_mode_);
call.set_color_brightness_if_supported(brightness); call.set_brightness_if_supported(brightness);
call.set_color_brightness_if_supported(color_brightness);
call.set_red_if_supported(r); call.set_red_if_supported(r);
call.set_green_if_supported(g); call.set_green_if_supported(g);
call.set_blue_if_supported(b); call.set_blue_if_supported(b);
call.set_white_if_supported(w); call.set_white_if_supported(w);
call.set_warm_white_if_supported(w);
call.set_cold_white_if_supported(w);
}
call.set_transition_length_if_supported(0); call.set_transition_length_if_supported(0);
call.set_publish(false); call.set_publish(false);
call.set_save(false); call.set_save(false);
@ -50,6 +120,7 @@ class AddressableLightWrapper : public light::AddressableLight {
light::LightState *light_state_; light::LightState *light_state_;
uint8_t *wrapper_state_; uint8_t *wrapper_state_;
ColorMode color_mode_{ColorMode::UNKNOWN};
}; };
} // namespace light } // namespace light

View file

@ -39,7 +39,15 @@ class LightTransformer {
protected: protected:
/// The progress of this transition, on a scale of 0 to 1. /// The progress of this transition, on a scale of 0 to 1.
float get_progress_() { return clamp((millis() - this->start_time_) / float(this->length_), 0.0f, 1.0f); } float get_progress_() {
uint32_t now = esphome::millis();
if (now < this->start_time_)
return 0.0f;
if (now >= this->start_time_ + this->length_)
return 1.0f;
return clamp((now - this->start_time_) / float(this->length_), 0.0f, 1.0f);
}
uint32_t start_time_; uint32_t start_time_;
uint32_t length_; uint32_t length_;

View file

@ -18,10 +18,13 @@ class LightTransitionTransformer : public LightTransformer {
this->start_values_.set_brightness(0.0f); this->start_values_.set_brightness(0.0f);
} }
// When turning light off from on state, use source state and only decrease brightness to zero. // When turning light off from on state, use source state and only decrease brightness to zero. Use a second
// variable for transition end state, as overwriting target_values breaks LightState logic.
if (this->start_values_.is_on() && !this->target_values_.is_on()) { if (this->start_values_.is_on() && !this->target_values_.is_on()) {
this->target_values_ = LightColorValues(this->start_values_); this->end_values_ = LightColorValues(this->start_values_);
this->target_values_.set_brightness(0.0f); this->end_values_.set_brightness(0.0f);
} else {
this->end_values_ = LightColorValues(this->target_values_);
} }
// When changing color mode, go through off state, as color modes are orthogonal and there can't be two active. // When changing color mode, go through off state, as color modes are orthogonal and there can't be two active.
@ -43,7 +46,7 @@ class LightTransitionTransformer : public LightTransformer {
} }
LightColorValues &start = this->changing_color_mode_ && p > 0.5f ? this->intermediate_values_ : this->start_values_; LightColorValues &start = this->changing_color_mode_ && p > 0.5f ? this->intermediate_values_ : this->start_values_;
LightColorValues &end = this->changing_color_mode_ && p < 0.5f ? this->intermediate_values_ : this->target_values_; LightColorValues &end = this->changing_color_mode_ && p < 0.5f ? this->intermediate_values_ : this->end_values_;
if (this->changing_color_mode_) if (this->changing_color_mode_)
p = p < 0.5f ? p * 2 : (p - 0.5) * 2; p = p < 0.5f ? p * 2 : (p - 0.5) * 2;
@ -57,6 +60,7 @@ class LightTransitionTransformer : public LightTransformer {
static float smoothed_progress(float x) { return x * x * x * (x * (x * 6.0f - 15.0f) + 10.0f); } static float smoothed_progress(float x) { return x * x * x * (x * (x * 6.0f - 15.0f) + 10.0f); }
bool changing_color_mode_{false}; bool changing_color_mode_{false};
LightColorValues end_values_{};
LightColorValues intermediate_values_{}; LightColorValues intermediate_values_{};
}; };
@ -69,9 +73,7 @@ class LightFlashTransformer : public LightTransformer {
if (this->transition_length_ * 2 > this->length_) if (this->transition_length_ * 2 > this->length_)
this->transition_length_ = this->length_ / 2; this->transition_length_ = this->length_ / 2;
// do not create transition if length is 0 this->begun_lightstate_restore_ = false;
if (this->transition_length_ == 0)
return;
// first transition to original target // first transition to original target
this->transformer_ = this->state_.get_output()->create_default_transition(); this->transformer_ = this->state_.get_output()->create_default_transition();
@ -79,40 +81,45 @@ class LightFlashTransformer : public LightTransformer {
} }
optional<LightColorValues> apply() override { optional<LightColorValues> apply() override {
// transition transformer does not handle 0 length as progress returns nan optional<LightColorValues> result = {};
if (this->transition_length_ == 0)
return this->target_values_; if (this->transformer_ == nullptr && millis() > this->start_time_ + this->length_ - this->transition_length_) {
// second transition back to start value
this->transformer_ = this->state_.get_output()->create_default_transition();
this->transformer_->setup(this->state_.current_values, this->get_start_values(), this->transition_length_);
this->begun_lightstate_restore_ = true;
}
if (this->transformer_ != nullptr) { if (this->transformer_ != nullptr) {
if (!this->transformer_->is_finished()) { result = this->transformer_->apply();
return this->transformer_->apply();
} else { if (this->transformer_->is_finished()) {
this->transformer_->stop(); this->transformer_->stop();
this->transformer_ = nullptr; this->transformer_ = nullptr;
} }
} }
if (millis() > this->start_time_ + this->length_ - this->transition_length_) { return result;
// second transition back to start value
this->transformer_ = this->state_.get_output()->create_default_transition();
this->transformer_->setup(this->state_.current_values, this->get_start_values(), this->transition_length_);
}
// once transition is complete, don't change states until next transition
return optional<LightColorValues>();
} }
// Restore the original values after the flash. // Restore the original values after the flash.
void stop() override { void stop() override {
if (this->transformer_ != nullptr) {
this->transformer_->stop();
this->transformer_ = nullptr;
}
this->state_.current_values = this->get_start_values(); this->state_.current_values = this->get_start_values();
this->state_.remote_values = this->get_start_values(); this->state_.remote_values = this->get_start_values();
this->state_.publish_state(); this->state_.publish_state();
} }
bool is_finished() override { return this->begun_lightstate_restore_ && LightTransformer::is_finished(); }
protected: protected:
LightState &state_; LightState &state_;
uint32_t transition_length_; uint32_t transition_length_;
std::unique_ptr<LightTransformer> transformer_{nullptr}; std::unique_ptr<LightTransformer> transformer_{nullptr};
bool begun_lightstate_restore_;
}; };
} // namespace light } // namespace light

View file

@ -19,6 +19,7 @@ from esphome.const import (
CONF_TX_BUFFER_SIZE, CONF_TX_BUFFER_SIZE,
) )
from esphome.core import CORE, EsphomeError, Lambda, coroutine_with_priority from esphome.core import CORE, EsphomeError, Lambda, coroutine_with_priority
from esphome.components.esp32 import get_esp32_variant, VARIANT_ESP32S2, VARIANT_ESP32C3
CODEOWNERS = ["@esphome/core"] CODEOWNERS = ["@esphome/core"]
logger_ns = cg.esphome_ns.namespace("logger") logger_ns = cg.esphome_ns.namespace("logger")
@ -52,6 +53,10 @@ LOG_LEVEL_SEVERITY = [
"VERY_VERBOSE", "VERY_VERBOSE",
] ]
ESP32_REDUCED_VARIANTS = [VARIANT_ESP32C3, VARIANT_ESP32S2]
UART_SELECTION_ESP32_REDUCED = ["UART0", "UART1"]
UART_SELECTION_ESP32 = ["UART0", "UART1", "UART2"] UART_SELECTION_ESP32 = ["UART0", "UART1", "UART2"]
UART_SELECTION_ESP8266 = ["UART0", "UART0_SWAP", "UART1"] UART_SELECTION_ESP8266 = ["UART0", "UART0_SWAP", "UART1"]
@ -75,6 +80,8 @@ is_log_level = cv.one_of(*LOG_LEVELS, upper=True)
def uart_selection(value): def uart_selection(value):
if CORE.is_esp32: if CORE.is_esp32:
if get_esp32_variant() in ESP32_REDUCED_VARIANTS:
return cv.one_of(*UART_SELECTION_ESP32_REDUCED, upper=True)(value)
return cv.one_of(*UART_SELECTION_ESP32, upper=True)(value) return cv.one_of(*UART_SELECTION_ESP32, upper=True)(value)
if CORE.is_esp8266: if CORE.is_esp8266:
return cv.one_of(*UART_SELECTION_ESP8266, upper=True)(value) return cv.one_of(*UART_SELECTION_ESP8266, upper=True)(value)

View file

@ -153,13 +153,9 @@ void Logger::pre_setup() {
case UART_SELECTION_UART1: case UART_SELECTION_UART1:
this->hw_serial_ = &Serial1; this->hw_serial_ = &Serial1;
break; break;
#ifdef USE_ESP32 #if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32S2)
case UART_SELECTION_UART2: case UART_SELECTION_UART2:
#if !CONFIG_IDF_TARGET_ESP32S2 && !CONFIG_IDF_TARGET_ESP32C3
// FIXME: Validate in config that UART2 can't be set for ESP32-S2 (only has
// UART0-UART1)
this->hw_serial_ = &Serial2; this->hw_serial_ = &Serial2;
#endif
break; break;
#endif #endif
} }
@ -173,9 +169,11 @@ void Logger::pre_setup() {
case UART_SELECTION_UART1: case UART_SELECTION_UART1:
uart_num_ = UART_NUM_1; uart_num_ = UART_NUM_1;
break; break;
#if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32S2)
case UART_SELECTION_UART2: case UART_SELECTION_UART2:
uart_num_ = UART_NUM_2; uart_num_ = UART_NUM_2;
break; break;
#endif
} }
uart_config_t uart_config{}; uart_config_t uart_config{};
uart_config.baud_rate = (int) baud_rate_; uart_config.baud_rate = (int) baud_rate_;

View file

@ -24,7 +24,7 @@ namespace logger {
enum UARTSelection { enum UARTSelection {
UART_SELECTION_UART0 = 0, UART_SELECTION_UART0 = 0,
UART_SELECTION_UART1, UART_SELECTION_UART1,
#ifdef USE_ESP32 #if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32S2)
UART_SELECTION_UART2, UART_SELECTION_UART2,
#endif #endif
#ifdef USE_ESP8266 #ifdef USE_ESP8266

View file

@ -1,4 +1,5 @@
#include "sgp30.h" #include "sgp30.h"
#include "esphome/core/hal.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/application.h" #include "esphome/core/application.h"
#include <cinttypes> #include <cinttypes>

View file

@ -1,6 +1,6 @@
"""Constants used by esphome.""" """Constants used by esphome."""
__version__ = "2021.10.0b2" __version__ = "2021.10.0b3"
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"