1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-01 15:41:52 +00:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Jesse Hills
cadbf7463e Merge pull request #5816 from esphome/bump-2023.11.3
2023.11.3
2023-11-22 13:37:10 +13:00
Jesse Hills
3f40e32eba Bump version to 2023.11.3 2023-11-22 11:08:47 +13:00
Keith Burzinski
b421fccc08 Add some additional VA triggers, part 2 (#5811) 2023-11-22 11:08:47 +13:00
Jesse Hills
10ca05b686 Early return when there are no wifi scan results (#5797) 2023-11-22 11:08:46 +13:00
CVan
d0ac202a3f fix: compile errors with fonts (#5808) 2023-11-22 11:08:46 +13:00
Cody Cutrer
1c4b06700f include payload_open when a lock supports OPEN (#5809) 2023-11-22 11:08:21 +13:00
J. Nick Koston
47d42afda3 dashboard: Fix online status when api is disabled (#5791) 2023-11-21 13:15:32 +13:00
Jesse Hills
1a9f66e630 Merge pull request #5787 from esphome/bump-2023.11.2
2023.11.2
2023-11-18 22:25:00 +13:00
Jesse Hills
8fb6b8f1a2 Bump version to 2023.11.2 2023-11-18 21:15:56 +13:00
Keith Burzinski
22eef036c7 Add 2MB option for partitions.csv generation and restore use of user-defined partitions (#5779) 2023-11-18 21:15:56 +13:00
Samuel Sieb
625ce2b8eb fix 32-bit arm (#5781) 2023-11-18 21:15:56 +13:00
dependabot[bot]
e5e3b253bc Bump aioesphomeapi from 18.4.1 to 18.5.2 (#5780)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-18 21:15:51 +13:00
dependabot[bot]
c369443263 Bump aioesphomeapi from 18.4.0 to 18.4.1 (#5767)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-18 21:14:50 +13:00
11 changed files with 126 additions and 14 deletions

View File

@@ -48,6 +48,8 @@ RUN \
libfreetype-dev=2.12.1+dfsg-5 \
libssl-dev=3.0.11-1~deb12u2 \
libffi-dev=3.4.4-1 \
libopenjp2-7=2.5.0-2 \
libtiff6=4.5.0-6 \
cargo=0.66.0+ds1-1 \
pkg-config=1.8.1-1 \
gcc-arm-linux-gnueabihf=4:12.2.0-3; \
@@ -68,7 +70,7 @@ ENV \
# See: https://unix.stackexchange.com/questions/553743/correct-way-to-add-lib-ld-linux-so-3-in-debian
RUN \
if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
ln -s /lib/arm-linux-gnueabihf/ld-linux.so.3 /lib/ld-linux.so.3; \
ln -s /lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 /lib/ld-linux.so.3; \
fi
RUN \

View File

@@ -3,23 +3,26 @@ from typing import Union, Optional
from pathlib import Path
import logging
import os
import esphome.final_validate as fv
from esphome.helpers import copy_file_if_changed, write_file_if_changed, mkdir_p
from esphome.const import (
CONF_ADVANCED,
CONF_BOARD,
CONF_COMPONENTS,
CONF_ESPHOME,
CONF_FRAMEWORK,
CONF_IGNORE_EFUSE_MAC_CRC,
CONF_NAME,
CONF_PATH,
CONF_PLATFORMIO_OPTIONS,
CONF_REF,
CONF_REFRESH,
CONF_SOURCE,
CONF_TYPE,
CONF_URL,
CONF_VARIANT,
CONF_VERSION,
CONF_ADVANCED,
CONF_REFRESH,
CONF_PATH,
CONF_URL,
CONF_REF,
CONF_IGNORE_EFUSE_MAC_CRC,
KEY_CORE,
KEY_FRAMEWORK_VERSION,
KEY_NAME,
@@ -327,6 +330,32 @@ def _detect_variant(value):
return value
def final_validate(config):
if CONF_PLATFORMIO_OPTIONS not in fv.full_config.get()[CONF_ESPHOME]:
return config
pio_flash_size_key = "board_upload.flash_size"
pio_partitions_key = "board_build.partitions"
if (
CONF_PARTITIONS in config
and pio_partitions_key
in fv.full_config.get()[CONF_ESPHOME][CONF_PLATFORMIO_OPTIONS]
):
raise cv.Invalid(
f"Do not specify '{pio_partitions_key}' in '{CONF_PLATFORMIO_OPTIONS}' with '{CONF_PARTITIONS}' in esp32"
)
if (
pio_flash_size_key
in fv.full_config.get()[CONF_ESPHOME][CONF_PLATFORMIO_OPTIONS]
):
raise cv.Invalid(
f"Please specify {CONF_FLASH_SIZE} within esp32 configuration only"
)
return config
CONF_PLATFORM_VERSION = "platform_version"
ARDUINO_FRAMEWORK_SCHEMA = cv.All(
@@ -387,6 +416,7 @@ FRAMEWORK_SCHEMA = cv.typed_schema(
FLASH_SIZES = [
"2MB",
"4MB",
"8MB",
"16MB",
@@ -394,6 +424,7 @@ FLASH_SIZES = [
]
CONF_FLASH_SIZE = "flash_size"
CONF_PARTITIONS = "partitions"
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
@@ -401,6 +432,7 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_FLASH_SIZE, default="4MB"): cv.one_of(
*FLASH_SIZES, upper=True
),
cv.Optional(CONF_PARTITIONS): cv.file_,
cv.Optional(CONF_VARIANT): cv.one_of(*VARIANTS, upper=True),
cv.Optional(CONF_FRAMEWORK, default={}): FRAMEWORK_SCHEMA,
}
@@ -410,6 +442,9 @@ CONFIG_SCHEMA = cv.All(
)
FINAL_VALIDATE_SCHEMA = cv.Schema(final_validate)
async def to_code(config):
cg.add_platformio_option("board", config[CONF_BOARD])
cg.add_platformio_option("board_upload.flash_size", config[CONF_FLASH_SIZE])
@@ -462,7 +497,10 @@ async def to_code(config):
add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0", False)
add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1", False)
cg.add_platformio_option("board_build.partitions", "partitions.csv")
if CONF_PARTITIONS in config:
cg.add_platformio_option("board_build.partitions", config[CONF_PARTITIONS])
else:
cg.add_platformio_option("board_build.partitions", "partitions.csv")
for name, value in conf[CONF_SDKCONFIG_OPTIONS].items():
add_idf_sdkconfig_option(name, RawSdkconfigValue(value))
@@ -507,7 +545,10 @@ async def to_code(config):
[f"platformio/framework-arduinoespressif32@{conf[CONF_SOURCE]}"],
)
cg.add_platformio_option("board_build.partitions", "partitions.csv")
if CONF_PARTITIONS in config:
cg.add_platformio_option("board_build.partitions", config[CONF_PARTITIONS])
else:
cg.add_platformio_option("board_build.partitions", "partitions.csv")
cg.add_define(
"USE_ARDUINO_VERSION_CODE",
@@ -518,6 +559,7 @@ async def to_code(config):
APP_PARTITION_SIZES = {
"2MB": 0x0C0000, # 768 KB
"4MB": 0x1C0000, # 1792 KB
"8MB": 0x3C0000, # 3840 KB
"16MB": 0x7C0000, # 7936 KB

View File

@@ -40,6 +40,8 @@ const EntityBase *MQTTLockComponent::get_entity() const { return this->lock_; }
void MQTTLockComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
if (this->lock_->traits.get_assumed_state())
root[MQTT_OPTIMISTIC] = true;
if (this->lock_->traits.get_supports_open())
root[MQTT_PAYLOAD_OPEN] = "OPEN";
}
bool MQTTLockComponent::send_initial_state() { return this->publish_state(); }

View File

@@ -29,6 +29,8 @@ CONF_ON_STT_VAD_END = "on_stt_vad_end"
CONF_ON_STT_VAD_START = "on_stt_vad_start"
CONF_ON_TTS_END = "on_tts_end"
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_SILENCE_DETECTION = "silence_detection"
@@ -56,6 +58,17 @@ IsRunningCondition = voice_assistant_ns.class_(
"IsRunningCondition", automation.Condition, cg.Parented.template(VoiceAssistant)
)
def tts_stream_validate(config):
if CONF_SPEAKER not in config and (
CONF_ON_TTS_STREAM_START in config or CONF_ON_TTS_STREAM_END in config
):
raise cv.Invalid(
f"{CONF_SPEAKER} is required when using {CONF_ON_TTS_STREAM_START} and/or {CONF_ON_TTS_STREAM_END}"
)
return config
CONFIG_SCHEMA = cv.All(
cv.Schema(
{
@@ -105,8 +118,15 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_ON_STT_VAD_END): automation.validate_automation(
single=True
),
cv.Optional(CONF_ON_TTS_STREAM_START): automation.validate_automation(
single=True
),
cv.Optional(CONF_ON_TTS_STREAM_END): automation.validate_automation(
single=True
),
}
).extend(cv.COMPONENT_SCHEMA),
tts_stream_validate,
)
@@ -222,6 +242,20 @@ async def to_code(config):
config[CONF_ON_STT_VAD_END],
)
if CONF_ON_TTS_STREAM_START in config:
await automation.build_automation(
var.get_tts_stream_start_trigger(),
[],
config[CONF_ON_TTS_STREAM_START],
)
if CONF_ON_TTS_STREAM_END in config:
await automation.build_automation(
var.get_tts_stream_end_trigger(),
[],
config[CONF_ON_TTS_STREAM_END],
)
cg.add_define("USE_VOICE_ASSISTANT")

View File

@@ -632,11 +632,17 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) {
case api::enums::VOICE_ASSISTANT_TTS_STREAM_START: {
#ifdef USE_SPEAKER
this->wait_for_stream_end_ = true;
ESP_LOGD(TAG, "TTS stream start");
this->tts_stream_start_trigger_->trigger();
#endif
break;
}
case api::enums::VOICE_ASSISTANT_TTS_STREAM_END: {
this->set_state_(State::RESPONSE_FINISHED, State::IDLE);
#ifdef USE_SPEAKER
ESP_LOGD(TAG, "TTS stream end");
this->tts_stream_end_trigger_->trigger();
#endif
break;
}
case api::enums::VOICE_ASSISTANT_STT_VAD_START:

View File

@@ -107,6 +107,10 @@ class VoiceAssistant : public Component {
Trigger<> *get_start_trigger() const { return this->start_trigger_; }
Trigger<> *get_stt_vad_end_trigger() const { return this->stt_vad_end_trigger_; }
Trigger<> *get_stt_vad_start_trigger() const { return this->stt_vad_start_trigger_; }
#ifdef USE_SPEAKER
Trigger<> *get_tts_stream_start_trigger() const { return this->tts_stream_start_trigger_; }
Trigger<> *get_tts_stream_end_trigger() const { return this->tts_stream_end_trigger_; }
#endif
Trigger<> *get_wake_word_detected_trigger() const { return this->wake_word_detected_trigger_; }
Trigger<std::string> *get_stt_end_trigger() const { return this->stt_end_trigger_; }
Trigger<std::string> *get_tts_end_trigger() const { return this->tts_end_trigger_; }
@@ -135,6 +139,10 @@ class VoiceAssistant : public Component {
Trigger<> *start_trigger_ = new Trigger<>();
Trigger<> *stt_vad_start_trigger_ = new Trigger<>();
Trigger<> *stt_vad_end_trigger_ = new Trigger<>();
#ifdef USE_SPEAKER
Trigger<> *tts_stream_start_trigger_ = new Trigger<>();
Trigger<> *tts_stream_end_trigger_ = new Trigger<>();
#endif
Trigger<> *wake_word_detected_trigger_ = new Trigger<>();
Trigger<std::string> *stt_end_trigger_ = new Trigger<std::string>();
Trigger<std::string> *tts_end_trigger_ = new Trigger<std::string>();

View File

@@ -674,6 +674,11 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
return;
}
if (it.number == 0) {
// no results
return;
}
uint16_t number = it.number;
std::vector<wifi_ap_record_t> records(number);
err = esp_wifi_scan_get_ap_records(&number, records.data());

View File

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

View File

@@ -973,6 +973,7 @@ class MDNSStatusThread(threading.Thread):
self.host_name_to_filename: dict[str, str] = {}
# This is a set of host names to track (i.e no_mdns = false)
self.host_name_with_mdns_enabled: set[set] = set()
self.zc: EsphomeZeroconf | None = None
self._refresh_hosts()
def _refresh_hosts(self):
@@ -996,7 +997,14 @@ class MDNSStatusThread(threading.Thread):
# If we just adopted/imported this host, we likely
# already have a state for it, so we should make sure
# to set it so the dashboard shows it as online
if name in host_mdns_state:
if self.zc and (
entry.loaded_integrations and "api" not in entry.loaded_integrations
):
# No api available so we have to poll since
# the device won't respond to a request to ._esphomelib._tcp.local.
PING_RESULT[filename] = bool(self.zc.resolve_host(entry.name))
elif name in host_mdns_state:
# We already have a state for this host
PING_RESULT[filename] = host_mdns_state[name]
# Make sure the mapping is up to date
@@ -1007,7 +1015,8 @@ class MDNSStatusThread(threading.Thread):
def run(self):
global IMPORT_RESULT
zc = EsphomeZeroconf()
self.zc = EsphomeZeroconf()
zc = self.zc
host_mdns_state = self.host_mdns_state
host_name_to_filename = self.host_name_to_filename
host_name_with_mdns_enabled = self.host_name_with_mdns_enabled

View File

@@ -150,7 +150,11 @@ class EsphomeZeroconf(Zeroconf):
def resolve_host(self, host: str, timeout: float = 3.0) -> str | None:
"""Resolve a host name to an IP address."""
name = host.partition(".")[0]
info = HostResolver(ESPHOME_SERVICE_TYPE, f"{name}.{ESPHOME_SERVICE_TYPE}")
info = HostResolver(
ESPHOME_SERVICE_TYPE,
f"{name}.{ESPHOME_SERVICE_TYPE}",
server=f"{name}.local.",
)
if (
info.load_from_cache(self)
or (timeout and info.request(self, timeout * 1000))

View File

@@ -10,7 +10,7 @@ platformio==6.1.11 # When updating platformio, also update Dockerfile
esptool==4.6.2
click==8.1.7
esphome-dashboard==20231107.0
aioesphomeapi==18.4.0
aioesphomeapi==18.5.2
zeroconf==0.123.0
# esp-idf requires this, but doesn't bundle it by default