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); 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]); 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(); 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 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<>(); 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 = (