Merge pull request #7663 from esphome/bump-2024.10.2
Some checks failed
YAML lint / yamllint (push) Has been cancelled
CI / Create common environment (push) Has been cancelled
CI / Check black (push) Has been cancelled
CI / Check flake8 (push) Has been cancelled
CI / Check pylint (push) Has been cancelled
CI / Check pyupgrade (push) Has been cancelled
CI / Run script/ci-custom (push) Has been cancelled
CI / Run pytest (push) Has been cancelled
CI / Check clang-format (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 1/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 2/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 3/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 4/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 IDF (push) Has been cancelled
CI / Run script/clang-tidy for ESP8266 (push) Has been cancelled
CI / list-components (push) Has been cancelled
CI / Component test (push) Has been cancelled
CI / Split components for testing into 20 groups maximum (push) Has been cancelled
CI / Test split components (push) Has been cancelled
CI / CI Status (push) Has been cancelled

2024.10.2
This commit is contained in:
Jesse Hills 2024-10-24 08:04:29 +13:00 committed by GitHub
commit 9caf5f8b31
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 59 additions and 34 deletions

View file

@ -267,6 +267,9 @@ def angle(value):
return int(cv.float_range(0.0, 360.0)(cv.angle(value)) * 10) return int(cv.float_range(0.0, 360.0)(cv.angle(value)) * 10)
lv_angle = LValidator(angle, uint32)
@schema_extractor("one_of") @schema_extractor("one_of")
def size_validator(value): def size_validator(value):
"""A size in one axis - one of "size_content", a number (pixels) or a percentage""" """A size in one axis - one of "size_content", a number (pixels) or a percentage"""
@ -403,6 +406,7 @@ class TextValidator(LValidator):
lv_text = TextValidator() lv_text = TextValidator()
lv_float = LValidator(cv.float_, cg.float_) lv_float = LValidator(cv.float_, cg.float_)
lv_int = LValidator(cv.int_, cg.int_) lv_int = LValidator(cv.int_, cg.int_)
lv_positive_int = LValidator(cv.positive_int, cg.int_)
lv_brightness = LValidator(cv.percentage, cg.float_, retmapper=lambda x: int(x * 255)) lv_brightness = LValidator(cv.percentage, cg.float_, retmapper=lambda x: int(x * 255))

View file

@ -91,7 +91,7 @@ STYLE_PROPS = {
"arc_opa": lvalid.opacity, "arc_opa": lvalid.opacity,
"arc_color": lvalid.lv_color, "arc_color": lvalid.lv_color,
"arc_rounded": lvalid.lv_bool, "arc_rounded": lvalid.lv_bool,
"arc_width": cv.positive_int, "arc_width": lvalid.lv_positive_int,
"anim_time": lvalid.lv_milliseconds, "anim_time": lvalid.lv_milliseconds,
"bg_color": lvalid.lv_color, "bg_color": lvalid.lv_color,
"bg_grad": lv_gradient, "bg_grad": lv_gradient,
@ -111,7 +111,7 @@ STYLE_PROPS = {
"border_side": df.LvConstant( "border_side": df.LvConstant(
"LV_BORDER_SIDE_", "NONE", "TOP", "BOTTOM", "LEFT", "RIGHT", "INTERNAL" "LV_BORDER_SIDE_", "NONE", "TOP", "BOTTOM", "LEFT", "RIGHT", "INTERNAL"
).several_of, ).several_of,
"border_width": cv.positive_int, "border_width": lvalid.lv_positive_int,
"clip_corner": lvalid.lv_bool, "clip_corner": lvalid.lv_bool,
"color_filter_opa": lvalid.opacity, "color_filter_opa": lvalid.opacity,
"height": lvalid.size, "height": lvalid.size,
@ -134,11 +134,11 @@ STYLE_PROPS = {
"pad_right": lvalid.pixels, "pad_right": lvalid.pixels,
"pad_top": lvalid.pixels, "pad_top": lvalid.pixels,
"shadow_color": lvalid.lv_color, "shadow_color": lvalid.lv_color,
"shadow_ofs_x": cv.int_, "shadow_ofs_x": lvalid.lv_int,
"shadow_ofs_y": cv.int_, "shadow_ofs_y": lvalid.lv_int,
"shadow_opa": lvalid.opacity, "shadow_opa": lvalid.opacity,
"shadow_spread": cv.int_, "shadow_spread": lvalid.lv_int,
"shadow_width": cv.positive_int, "shadow_width": lvalid.lv_positive_int,
"text_align": df.LvConstant( "text_align": df.LvConstant(
"LV_TEXT_ALIGN_", "LEFT", "CENTER", "RIGHT", "AUTO" "LV_TEXT_ALIGN_", "LEFT", "CENTER", "RIGHT", "AUTO"
).one_of, ).one_of,
@ -150,7 +150,7 @@ STYLE_PROPS = {
"text_letter_space": cv.positive_int, "text_letter_space": cv.positive_int,
"text_line_space": cv.positive_int, "text_line_space": cv.positive_int,
"text_opa": lvalid.opacity, "text_opa": lvalid.opacity,
"transform_angle": lvalid.angle, "transform_angle": lvalid.lv_angle,
"transform_height": lvalid.pixels_or_percent, "transform_height": lvalid.pixels_or_percent,
"transform_pivot_x": lvalid.pixels_or_percent, "transform_pivot_x": lvalid.pixels_or_percent,
"transform_pivot_y": lvalid.pixels_or_percent, "transform_pivot_y": lvalid.pixels_or_percent,

View file

@ -433,16 +433,18 @@ void VoiceAssistant::loop() {
#ifdef USE_SPEAKER #ifdef USE_SPEAKER
void VoiceAssistant::write_speaker_() { void VoiceAssistant::write_speaker_() {
if (this->speaker_buffer_size_ > 0) { if ((this->speaker_ != nullptr) && (this->speaker_buffer_ != nullptr)) {
size_t write_chunk = std::min<size_t>(this->speaker_buffer_size_, 4 * 1024); if (this->speaker_buffer_size_ > 0) {
size_t written = this->speaker_->play(this->speaker_buffer_, write_chunk); size_t write_chunk = std::min<size_t>(this->speaker_buffer_size_, 4 * 1024);
if (written > 0) { size_t written = this->speaker_->play(this->speaker_buffer_, write_chunk);
memmove(this->speaker_buffer_, this->speaker_buffer_ + written, this->speaker_buffer_size_ - written); if (written > 0) {
this->speaker_buffer_size_ -= written; memmove(this->speaker_buffer_, this->speaker_buffer_ + written, this->speaker_buffer_size_ - written);
this->speaker_buffer_index_ -= written; this->speaker_buffer_size_ -= written;
this->set_timeout("speaker-timeout", 5000, [this]() { this->speaker_->stop(); }); this->speaker_buffer_index_ -= written;
} else { this->set_timeout("speaker-timeout", 5000, [this]() { this->speaker_->stop(); });
ESP_LOGV(TAG, "Speaker buffer full, trying again next loop"); } else {
ESP_LOGV(TAG, "Speaker buffer full, trying again next loop");
}
} }
} }
} }
@ -772,16 +774,20 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
} }
case api::enums::VOICE_ASSISTANT_TTS_STREAM_START: { case api::enums::VOICE_ASSISTANT_TTS_STREAM_START: {
#ifdef USE_SPEAKER #ifdef USE_SPEAKER
this->wait_for_stream_end_ = true; if (this->speaker_ != nullptr) {
ESP_LOGD(TAG, "TTS stream start"); this->wait_for_stream_end_ = true;
this->defer([this] { this->tts_stream_start_trigger_->trigger(); }); ESP_LOGD(TAG, "TTS stream start");
this->defer([this] { this->tts_stream_start_trigger_->trigger(); });
}
#endif #endif
break; break;
} }
case api::enums::VOICE_ASSISTANT_TTS_STREAM_END: { case api::enums::VOICE_ASSISTANT_TTS_STREAM_END: {
#ifdef USE_SPEAKER #ifdef USE_SPEAKER
this->stream_ended_ = true; if (this->speaker_ != nullptr) {
ESP_LOGD(TAG, "TTS stream end"); this->stream_ended_ = true;
ESP_LOGD(TAG, "TTS stream end");
}
#endif #endif
break; break;
} }
@ -802,14 +808,16 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
void VoiceAssistant::on_audio(const api::VoiceAssistantAudio &msg) { void VoiceAssistant::on_audio(const api::VoiceAssistantAudio &msg) {
#ifdef USE_SPEAKER // We should never get to this function if there is no speaker anyway #ifdef USE_SPEAKER // We should never get to this function if there is no speaker anyway
if (this->speaker_buffer_index_ + msg.data.length() < SPEAKER_BUFFER_SIZE) { if ((this->speaker_ != nullptr) && (this->speaker_buffer_ != nullptr)) {
memcpy(this->speaker_buffer_ + this->speaker_buffer_index_, msg.data.data(), msg.data.length()); if (this->speaker_buffer_index_ + msg.data.length() < SPEAKER_BUFFER_SIZE) {
this->speaker_buffer_index_ += msg.data.length(); memcpy(this->speaker_buffer_ + this->speaker_buffer_index_, msg.data.data(), msg.data.length());
this->speaker_buffer_size_ += msg.data.length(); this->speaker_buffer_index_ += msg.data.length();
this->speaker_bytes_received_ += msg.data.length(); this->speaker_buffer_size_ += msg.data.length();
ESP_LOGV(TAG, "Received audio: %u bytes from API", msg.data.length()); this->speaker_bytes_received_ += msg.data.length();
} else { ESP_LOGV(TAG, "Received audio: %u bytes from API", msg.data.length());
ESP_LOGE(TAG, "Cannot receive audio, buffer is full"); } else {
ESP_LOGE(TAG, "Cannot receive audio, buffer is full");
}
} }
#endif #endif
} }

View file

@ -250,7 +250,7 @@ class VoiceAssistant : public Component {
#ifdef USE_SPEAKER #ifdef USE_SPEAKER
void write_speaker_(); void write_speaker_();
speaker::Speaker *speaker_{nullptr}; speaker::Speaker *speaker_{nullptr};
uint8_t *speaker_buffer_; uint8_t *speaker_buffer_{nullptr};
size_t speaker_buffer_index_{0}; size_t speaker_buffer_index_{0};
size_t speaker_buffer_size_{0}; size_t speaker_buffer_size_{0};
size_t speaker_bytes_received_{0}; size_t speaker_bytes_received_{0};
@ -282,8 +282,8 @@ class VoiceAssistant : public Component {
float volume_multiplier_; float volume_multiplier_;
uint32_t conversation_timeout_; uint32_t conversation_timeout_;
uint8_t *send_buffer_; uint8_t *send_buffer_{nullptr};
int16_t *input_buffer_; int16_t *input_buffer_{nullptr};
bool continuous_{false}; bool continuous_{false};
bool silence_detection_; bool silence_detection_;

View file

@ -1,6 +1,6 @@
"""Constants used by esphome.""" """Constants used by esphome."""
__version__ = "2024.10.1" __version__ = "2024.10.2"
ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_"
VALID_SUBSTITUTIONS_CHARACTERS = ( VALID_SUBSTITUTIONS_CHARACTERS = (

View file

@ -209,6 +209,12 @@ def show_logs(config, topic=None, username=None, password=None, client_id=None):
elif CONF_MQTT in config: elif CONF_MQTT in config:
conf = config[CONF_MQTT] conf = config[CONF_MQTT]
if CONF_LOG_TOPIC in conf: if CONF_LOG_TOPIC in conf:
if config[CONF_MQTT][CONF_LOG_TOPIC] is None:
_LOGGER.error("MQTT log topic set to null, can't start MQTT logs")
return 1
if CONF_TOPIC not in config[CONF_MQTT][CONF_LOG_TOPIC]:
_LOGGER.error("MQTT log topic not available, can't start MQTT logs")
return 1
topic = config[CONF_MQTT][CONF_LOG_TOPIC][CONF_TOPIC] topic = config[CONF_MQTT][CONF_LOG_TOPIC][CONF_TOPIC]
elif CONF_TOPIC_PREFIX in config[CONF_MQTT]: elif CONF_TOPIC_PREFIX in config[CONF_MQTT]:
topic = f"{config[CONF_MQTT][CONF_TOPIC_PREFIX]}/debug" topic = f"{config[CONF_MQTT][CONF_TOPIC_PREFIX]}/debug"

View file

@ -299,6 +299,13 @@ lvgl:
id: button_button id: button_button
width: 20% width: 20%
height: 10% height: 10%
transform_angle: !lambda return 180*100;
arc_width: !lambda return 4;
border_width: !lambda return 6;
shadow_ofs_x: !lambda return 6;
shadow_ofs_y: !lambda return 6;
shadow_spread: !lambda return 6;
shadow_width: !lambda return 6;
pressed: pressed:
bg_color: light_blue bg_color: light_blue
checkable: true checkable: true