1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-04 00:51:49 +00:00

Compare commits

..

23 Commits

Author SHA1 Message Date
Jesse Hills
9caf5f8b31 Merge pull request #7663 from esphome/bump-2024.10.2
2024.10.2
2024-10-24 08:04:29 +13:00
Jesse Hills
127acfde64 Bump version to 2024.10.2 2024-10-24 07:15:40 +13:00
Kevin Ahrendt
156ad773c9 [voice_assistant] Bugfix: Fix crash on start (#7662) 2024-10-24 07:15:40 +13:00
Clyde Stubbs
8d90d256bf [lvgl] Some properties were not templatable (Bugfix) (#7655) 2024-10-24 07:15:40 +13:00
Kyle Cascade
833565feb9 Humanized the missing MQTT log topic error message (#7634) 2024-10-24 07:15:40 +13:00
Jesse Hills
dfd174e1a5 Merge pull request #7651 from esphome/bump-2024.10.1
2024.10.1
2024-10-22 13:59:49 +13:00
Jesse Hills
735c04cd69 Bump version to 2024.10.1 2024-10-22 12:57:17 +13:00
Michael Hansen
d95b370998 Move setting global voice assistant to constructor (#7630)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2024-10-22 12:57:17 +13:00
Clyde Stubbs
3ebdd62c67 [lvgl] Remove states from style definitions (Bugfix) (#7645) 2024-10-22 12:57:17 +13:00
Clyde Stubbs
c26c96b8f4 [config] Ensure user-supplied build flags don't get silently overwritten (#7622) 2024-10-22 12:57:17 +13:00
Keith Burzinski
748256b3ee [wifi] Support custom MAC on Arduino, too (#7644) 2024-10-22 12:57:17 +13:00
Samuel Sieb
10791db82e auto-load preferences (#7642)
Co-authored-by: Samuel Sieb <samuel@sieb.net>
2024-10-22 12:57:17 +13:00
Lennart
3dd34f6628 Fix broken ibeacon_uuid config in ble_rssi (#7640) 2024-10-22 12:57:17 +13:00
Clyde Stubbs
7004053538 [config] Fix crash with empty substitutions block (#7612) 2024-10-22 12:57:17 +13:00
Jesse Hills
d6b96ad51d Merge pull request #7609 from esphome/bump-2024.10.0
2024.10.0
2024-10-16 16:18:27 +13:00
Jesse Hills
9b4b50a3a6 Bump version to 2024.10.0 2024-10-16 14:29:17 +13:00
Jesse Hills
ef87a6657a Merge pull request #7599 from esphome/bump-2024.10.0b2
2024.10.0b2
2024-10-14 10:57:15 +13:00
Clyde Stubbs
27e1233fc0 [CI] failures when installing using apt-get. (#7593) 2024-10-14 09:51:43 +13:00
Jesse Hills
d24ad2e0e7 Bump version to 2024.10.0b2 2024-10-14 09:31:16 +13:00
Niclas Larsson
dda27d9de4 Fix update sequence when update is set to false (#5225) (#7407) 2024-10-14 09:31:16 +13:00
Clyde Stubbs
f52136338d [touchscreen] Fix coordinates when using rotation (#7591) 2024-10-14 09:31:15 +13:00
RFDarter
bafb0ad688 [web_server] Event component grouping (#7586) 2024-10-14 09:31:15 +13:00
Samuel Sieb
b617b92758 fix uart settings check (#7573) 2024-10-14 09:31:15 +13:00
23 changed files with 163 additions and 104 deletions

View File

@@ -315,7 +315,9 @@ jobs:
key: platformio-${{ matrix.pio_cache_key }}
- name: Install clang-tidy
run: sudo apt-get install clang-tidy-14
run: |
sudo apt-get update
sudo apt-get install clang-tidy-14
- name: Register problem matchers
run: |
@@ -397,7 +399,9 @@ jobs:
file: ${{ fromJson(needs.list-components.outputs.components) }}
steps:
- name: Install dependencies
run: sudo apt-get install libsdl2-dev
run: |
sudo apt-get update
sudo apt-get install libsdl2-dev
- name: Check out code from GitHub
uses: actions/checkout@v4.1.7
@@ -451,7 +455,9 @@ jobs:
run: echo ${{ matrix.components }}
- name: Install dependencies
run: sudo apt-get install libsdl2-dev
run: |
sudo apt-get update
sudo apt-get install libsdl2-dev
- name: Check out code from GitHub
uses: actions/checkout@v4.1.7

View File

@@ -45,7 +45,7 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid,
cv.Optional(CONF_IBEACON_MAJOR): cv.uint16_t,
cv.Optional(CONF_IBEACON_MINOR): cv.uint16_t,
cv.Optional(CONF_IBEACON_UUID): cv.uuid,
cv.Optional(CONF_IBEACON_UUID): esp32_ble_tracker.bt_uuid,
}
)
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
@@ -79,7 +79,7 @@ async def to_code(config):
cg.add(var.set_service_uuid128(uuid128))
if ibeacon_uuid := config.get(CONF_IBEACON_UUID):
ibeacon_uuid = esp32_ble_tracker.as_hex_array(str(ibeacon_uuid))
ibeacon_uuid = esp32_ble_tracker.as_reversed_hex_array(ibeacon_uuid)
cg.add(var.set_ibeacon_uuid(ibeacon_uuid))
if (ibeacon_major := config.get(CONF_IBEACON_MAJOR)) is not None:

View File

@@ -244,7 +244,7 @@ void CSE7766Component::dump_config() {
LOG_SENSOR(" ", "Apparent Power", this->apparent_power_sensor_);
LOG_SENSOR(" ", "Reactive Power", this->reactive_power_sensor_);
LOG_SENSOR(" ", "Power Factor", this->power_factor_sensor_);
this->check_uart_settings(4800);
this->check_uart_settings(4800, 1, uart::UART_CONFIG_PARITY_EVEN);
}
} // namespace cse7766

View File

@@ -395,6 +395,13 @@ ARDUINO_FRAMEWORK_SCHEMA = cv.All(
cv.Optional(CONF_VERSION, default="recommended"): cv.string_strict,
cv.Optional(CONF_SOURCE): cv.string_strict,
cv.Optional(CONF_PLATFORM_VERSION): _parse_platform_version,
cv.Optional(CONF_ADVANCED, default={}): cv.Schema(
{
cv.Optional(
CONF_IGNORE_EFUSE_CUSTOM_MAC, default=False
): cv.boolean,
}
),
}
),
_arduino_check_versions,
@@ -494,6 +501,9 @@ async def to_code(config):
conf = config[CONF_FRAMEWORK]
cg.add_platformio_option("platform", conf[CONF_PLATFORM_VERSION])
if CONF_ADVANCED in conf and conf[CONF_ADVANCED][CONF_IGNORE_EFUSE_CUSTOM_MAC]:
cg.add_define("USE_ESP32_IGNORE_EFUSE_CUSTOM_MAC")
add_extra_script(
"post",
"post_build.py",
@@ -540,8 +550,6 @@ async def to_code(config):
for name, value in conf[CONF_SDKCONFIG_OPTIONS].items():
add_idf_sdkconfig_option(name, RawSdkconfigValue(value))
if conf[CONF_ADVANCED][CONF_IGNORE_EFUSE_CUSTOM_MAC]:
cg.add_define("USE_ESP32_IGNORE_EFUSE_CUSTOM_MAC")
if conf[CONF_ADVANCED].get(CONF_IGNORE_EFUSE_MAC_CRC):
add_idf_sdkconfig_option("CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR", True)
if (framework_ver.major, framework_ver.minor) >= (4, 4):

View File

@@ -1,6 +1,6 @@
from esphome import automation
import esphome.codegen as cg
from esphome.components import mqtt
from esphome.components import mqtt, web_server
import esphome.config_validation as cv
from esphome.const import (
CONF_DEVICE_CLASS,
@@ -11,6 +11,7 @@ from esphome.const import (
CONF_MQTT_ID,
CONF_ON_EVENT,
CONF_TRIGGER_ID,
CONF_WEB_SERVER,
DEVICE_CLASS_BUTTON,
DEVICE_CLASS_DOORBELL,
DEVICE_CLASS_EMPTY,
@@ -40,17 +41,21 @@ EventTrigger = event_ns.class_("EventTrigger", automation.Trigger.template())
validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
EVENT_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMPONENT_SCHEMA).extend(
{
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTEventComponent),
cv.GenerateID(): cv.declare_id(Event),
cv.Optional(CONF_DEVICE_CLASS): validate_device_class,
cv.Optional(CONF_ON_EVENT): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(EventTrigger),
}
),
}
EVENT_SCHEMA = (
cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA)
.extend(cv.MQTT_COMPONENT_SCHEMA)
.extend(
{
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTEventComponent),
cv.GenerateID(): cv.declare_id(Event),
cv.Optional(CONF_DEVICE_CLASS): validate_device_class,
cv.Optional(CONF_ON_EVENT): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(EventTrigger),
}
),
}
)
)
_UNDEF = object()
@@ -97,6 +102,9 @@ async def setup_event_core_(var, config, *, event_types: list[str]):
mqtt_ = cg.new_Pvariable(mqtt_id, var)
await mqtt.register_mqtt_component(mqtt_, config)
if web_server_config := config.get(CONF_WEB_SERVER):
await web_server.add_entity_config(var, web_server_config)
async def register_event(var, config, *, event_types: list[str]):
if not CORE.has_id(config[CONF_ID]):

View File

@@ -16,7 +16,7 @@ from .const import KEY_HOST
from .gpio import host_pin_to_code # noqa
CODEOWNERS = ["@esphome/core", "@clydebarrow"]
AUTO_LOAD = ["network"]
AUTO_LOAD = ["network", "preferences"]
def set_core_data(config):

View File

@@ -46,7 +46,7 @@ from .const import (
_LOGGER = logging.getLogger(__name__)
CODEOWNERS = ["@kuba2k2"]
AUTO_LOAD = []
AUTO_LOAD = ["preferences"]
def _detect_variant(value):

View File

@@ -33,7 +33,7 @@ from .schemas import (
FLEX_OBJ_SCHEMA,
GRID_CELL_SCHEMA,
LAYOUT_SCHEMAS,
STATE_SCHEMA,
STYLE_SCHEMA,
WIDGET_TYPES,
any_widget_schema,
container_schema,
@@ -323,7 +323,7 @@ CONFIG_SCHEMA = (
),
cv.Optional(df.CONF_STYLE_DEFINITIONS): cv.ensure_list(
cv.Schema({cv.Required(CONF_ID): cv.declare_id(lv_style_t)})
.extend(STATE_SCHEMA)
.extend(STYLE_SCHEMA)
.extend(
{
cv.Optional(df.CONF_GRID_CELL_X_ALIGN): grid_alignments,

View File

@@ -267,6 +267,9 @@ def angle(value):
return int(cv.float_range(0.0, 360.0)(cv.angle(value)) * 10)
lv_angle = LValidator(angle, uint32)
@schema_extractor("one_of")
def size_validator(value):
"""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_float = LValidator(cv.float_, cg.float_)
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))

View File

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

View File

@@ -26,7 +26,7 @@ from .gpio import rp2040_pin_to_code # noqa
_LOGGER = logging.getLogger(__name__)
CODEOWNERS = ["@jesserockz"]
AUTO_LOAD = []
AUTO_LOAD = ["preferences"]
def set_core_data(config):

View File

@@ -64,46 +64,46 @@ uint16_t shelly_dimmer_checksum(const uint8_t *buf, int len) {
return std::accumulate<decltype(buf), uint16_t>(buf, buf + len, 0);
}
bool ShellyDimmer::is_running_configured_version() const {
return this->version_major_ == USE_SHD_FIRMWARE_MAJOR_VERSION &&
this->version_minor_ == USE_SHD_FIRMWARE_MINOR_VERSION;
}
void ShellyDimmer::handle_firmware() {
// Reset the STM32 and check the firmware version.
this->reset_normal_boot_();
this->send_command_(SHELLY_DIMMER_PROTO_CMD_VERSION, nullptr, 0);
ESP_LOGI(TAG, "STM32 current firmware version: %d.%d, desired version: %d.%d", this->version_major_,
this->version_minor_, USE_SHD_FIRMWARE_MAJOR_VERSION, USE_SHD_FIRMWARE_MINOR_VERSION);
if (!is_running_configured_version()) {
#ifdef USE_SHD_FIRMWARE_DATA
if (!this->upgrade_firmware_()) {
ESP_LOGW(TAG, "Failed to upgrade firmware");
this->mark_failed();
return;
}
this->reset_normal_boot_();
this->send_command_(SHELLY_DIMMER_PROTO_CMD_VERSION, nullptr, 0);
if (!is_running_configured_version()) {
ESP_LOGE(TAG, "STM32 firmware upgrade already performed, but version is still incorrect");
this->mark_failed();
return;
}
#else
ESP_LOGW(TAG, "Firmware version mismatch, put 'update: true' in the yaml to flash an update.");
#endif
}
}
void ShellyDimmer::setup() {
this->pin_nrst_->setup();
this->pin_boot0_->setup();
ESP_LOGI(TAG, "Initializing Shelly Dimmer...");
// Reset the STM32 and check the firmware version.
for (int i = 0; i < 2; i++) {
this->reset_normal_boot_();
this->send_command_(SHELLY_DIMMER_PROTO_CMD_VERSION, nullptr, 0);
ESP_LOGI(TAG, "STM32 current firmware version: %d.%d, desired version: %d.%d", this->version_major_,
this->version_minor_, USE_SHD_FIRMWARE_MAJOR_VERSION, USE_SHD_FIRMWARE_MINOR_VERSION);
if (this->version_major_ != USE_SHD_FIRMWARE_MAJOR_VERSION ||
this->version_minor_ != USE_SHD_FIRMWARE_MINOR_VERSION) {
#ifdef USE_SHD_FIRMWARE_DATA
// Update firmware if needed.
ESP_LOGW(TAG, "Unsupported STM32 firmware version, flashing");
if (i > 0) {
// Upgrade was already performed but the reported version is still not right.
ESP_LOGE(TAG, "STM32 firmware upgrade already performed, but version is still incorrect");
this->mark_failed();
return;
}
if (!this->upgrade_firmware_()) {
ESP_LOGW(TAG, "Failed to upgrade firmware");
this->mark_failed();
return;
}
// Firmware upgrade completed, do the checks again.
continue;
#else
ESP_LOGW(TAG, "Firmware version mismatch, put 'update: true' in the yaml to flash an update.");
this->mark_failed();
return;
#endif
}
break;
}
this->handle_firmware();
this->send_settings_();
// Do an immediate poll to refresh current state.

View File

@@ -20,6 +20,8 @@ class ShellyDimmer : public PollingComponent, public light::LightOutput, public
public:
float get_setup_priority() const override { return setup_priority::LATE; }
bool is_running_configured_version() const;
void handle_firmware();
void setup() override;
void update() override;
void dump_config() override;

View File

@@ -18,8 +18,8 @@ void Touchscreen::attach_interrupt_(InternalGPIOPin *irq_pin, esphome::gpio::Int
void Touchscreen::call_setup() {
if (this->display_ != nullptr) {
this->display_width_ = this->display_->get_native_width();
this->display_height_ = this->display_->get_native_height();
this->display_width_ = this->display_->get_width();
this->display_height_ = this->display_->get_height();
}
PollingComponent::call_setup();
}

View File

@@ -23,6 +23,8 @@ static const size_t SEND_BUFFER_SIZE = INPUT_BUFFER_SIZE * sizeof(int16_t);
static const size_t RECEIVE_SIZE = 1024;
static const size_t SPEAKER_BUFFER_SIZE = 16 * RECEIVE_SIZE;
VoiceAssistant::VoiceAssistant() { global_voice_assistant = this; }
float VoiceAssistant::get_setup_priority() const { return setup_priority::AFTER_CONNECTION; }
bool VoiceAssistant::start_udp_socket_() {
@@ -68,12 +70,6 @@ bool VoiceAssistant::start_udp_socket_() {
return true;
}
void VoiceAssistant::setup() {
ESP_LOGCONFIG(TAG, "Setting up Voice Assistant...");
global_voice_assistant = this;
}
bool VoiceAssistant::allocate_buffers_() {
if (this->send_buffer_ != nullptr) {
return true; // Already allocated
@@ -437,16 +433,18 @@ void VoiceAssistant::loop() {
#ifdef USE_SPEAKER
void VoiceAssistant::write_speaker_() {
if (this->speaker_buffer_size_ > 0) {
size_t write_chunk = std::min<size_t>(this->speaker_buffer_size_, 4 * 1024);
size_t written = this->speaker_->play(this->speaker_buffer_, write_chunk);
if (written > 0) {
memmove(this->speaker_buffer_, this->speaker_buffer_ + written, this->speaker_buffer_size_ - written);
this->speaker_buffer_size_ -= written;
this->speaker_buffer_index_ -= written;
this->set_timeout("speaker-timeout", 5000, [this]() { this->speaker_->stop(); });
} else {
ESP_LOGV(TAG, "Speaker buffer full, trying again next loop");
if ((this->speaker_ != nullptr) && (this->speaker_buffer_ != nullptr)) {
if (this->speaker_buffer_size_ > 0) {
size_t write_chunk = std::min<size_t>(this->speaker_buffer_size_, 4 * 1024);
size_t written = this->speaker_->play(this->speaker_buffer_, write_chunk);
if (written > 0) {
memmove(this->speaker_buffer_, this->speaker_buffer_ + written, this->speaker_buffer_size_ - written);
this->speaker_buffer_size_ -= written;
this->speaker_buffer_index_ -= written;
this->set_timeout("speaker-timeout", 5000, [this]() { this->speaker_->stop(); });
} else {
ESP_LOGV(TAG, "Speaker buffer full, trying again next loop");
}
}
}
}
@@ -776,16 +774,20 @@ 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->defer([this] { this->tts_stream_start_trigger_->trigger(); });
if (this->speaker_ != nullptr) {
this->wait_for_stream_end_ = true;
ESP_LOGD(TAG, "TTS stream start");
this->defer([this] { this->tts_stream_start_trigger_->trigger(); });
}
#endif
break;
}
case api::enums::VOICE_ASSISTANT_TTS_STREAM_END: {
#ifdef USE_SPEAKER
this->stream_ended_ = true;
ESP_LOGD(TAG, "TTS stream end");
if (this->speaker_ != nullptr) {
this->stream_ended_ = true;
ESP_LOGD(TAG, "TTS stream end");
}
#endif
break;
}
@@ -806,14 +808,16 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &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
if (this->speaker_buffer_index_ + msg.data.length() < SPEAKER_BUFFER_SIZE) {
memcpy(this->speaker_buffer_ + this->speaker_buffer_index_, msg.data.data(), msg.data.length());
this->speaker_buffer_index_ += msg.data.length();
this->speaker_buffer_size_ += msg.data.length();
this->speaker_bytes_received_ += msg.data.length();
ESP_LOGV(TAG, "Received audio: %u bytes from API", msg.data.length());
} else {
ESP_LOGE(TAG, "Cannot receive audio, buffer is full");
if ((this->speaker_ != nullptr) && (this->speaker_buffer_ != nullptr)) {
if (this->speaker_buffer_index_ + msg.data.length() < SPEAKER_BUFFER_SIZE) {
memcpy(this->speaker_buffer_ + this->speaker_buffer_index_, msg.data.data(), msg.data.length());
this->speaker_buffer_index_ += msg.data.length();
this->speaker_buffer_size_ += msg.data.length();
this->speaker_bytes_received_ += msg.data.length();
ESP_LOGV(TAG, "Received audio: %u bytes from API", msg.data.length());
} else {
ESP_LOGE(TAG, "Cannot receive audio, buffer is full");
}
}
#endif
}

View File

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

View File

@@ -1443,7 +1443,7 @@ void WebServer::on_event(event::Event *obj, const std::string &event_type) {
}
std::string WebServer::event_json(event::Event *obj, const std::string &event_type, JsonDetail start_config) {
return json::build_json([obj, event_type, start_config](JsonObject root) {
return json::build_json([this, obj, event_type, start_config](JsonObject root) {
set_json_id(root, obj, "event-" + obj->get_object_id(), start_config);
if (!event_type.empty()) {
root["event_type"] = event_type;
@@ -1454,6 +1454,12 @@ std::string WebServer::event_json(event::Event *obj, const std::string &event_ty
event_types.add(event_type);
}
root["device_class"] = obj->get_device_class();
if (this->sorting_entitys_.find(obj) != this->sorting_entitys_.end()) {
root["sorting_weight"] = this->sorting_entitys_[obj].weight;
if (this->sorting_groups_.find(this->sorting_entitys_[obj].group_id) != this->sorting_groups_.end()) {
root["sorting_group"] = this->sorting_groups_[this->sorting_entitys_[obj].group_id].name;
}
}
}
});
}

View File

@@ -34,6 +34,11 @@ static esp_netif_t *s_ap_netif = nullptr; // NOLINT(cppcoreguidelines-avoid-non
static bool s_sta_connecting = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
void WiFiComponent::wifi_pre_setup_() {
uint8_t mac[6];
if (has_custom_mac_address()) {
get_mac_address_raw(mac);
set_mac_address(mac);
}
auto f = std::bind(&WiFiComponent::wifi_event_callback_, this, std::placeholders::_1, std::placeholders::_2);
WiFi.onEvent(f);
WiFi.persistent(false);

View File

@@ -782,7 +782,7 @@ def validate_config(
from esphome.components import substitutions
result[CONF_SUBSTITUTIONS] = {
**config.get(CONF_SUBSTITUTIONS, {}),
**(config.get(CONF_SUBSTITUTIONS) or {}),
**command_line_substitutions,
}
result.add_output_path([CONF_SUBSTITUTIONS], CONF_SUBSTITUTIONS)

View File

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

View File

@@ -318,6 +318,8 @@ async def add_includes(includes):
async def _add_platformio_options(pio_options):
# Add includes at the very end, so that they override everything
for key, val in pio_options.items():
if key == "build_flags" and not isinstance(val, list):
val = [val]
cg.add_platformio_option(key, val)

View File

@@ -209,6 +209,12 @@ def show_logs(config, topic=None, username=None, password=None, client_id=None):
elif CONF_MQTT in config:
conf = config[CONF_MQTT]
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]
elif CONF_TOPIC_PREFIX in config[CONF_MQTT]:
topic = f"{config[CONF_MQTT][CONF_TOPIC_PREFIX]}/debug"

View File

@@ -299,6 +299,13 @@ lvgl:
id: button_button
width: 20%
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:
bg_color: light_blue
checkable: true