diff --git a/esphome/components/esp32_can/canbus.py b/esphome/components/esp32_can/canbus.py index 74f331f30b..f4ba032009 100644 --- a/esphome/components/esp32_can/canbus.py +++ b/esphome/components/esp32_can/canbus.py @@ -11,6 +11,7 @@ from esphome.components.esp32.const import ( VARIANT_ESP32S2, VARIANT_ESP32S3, VARIANT_ESP32C3, + VARIANT_ESP32C6, VARIANT_ESP32H2, ) @@ -47,6 +48,7 @@ CAN_SPEEDS_ESP32_S2 = { CAN_SPEEDS_ESP32_S3 = {**CAN_SPEEDS_ESP32_S2} CAN_SPEEDS_ESP32_C3 = {**CAN_SPEEDS_ESP32_S2} +CAN_SPEEDS_ESP32_C6 = {**CAN_SPEEDS_ESP32_S2} CAN_SPEEDS_ESP32_H2 = {**CAN_SPEEDS_ESP32_S2} CAN_SPEEDS = { @@ -54,6 +56,7 @@ CAN_SPEEDS = { VARIANT_ESP32S2: CAN_SPEEDS_ESP32_S2, VARIANT_ESP32S3: CAN_SPEEDS_ESP32_S3, VARIANT_ESP32C3: CAN_SPEEDS_ESP32_C3, + VARIANT_ESP32C6: CAN_SPEEDS_ESP32_C6, VARIANT_ESP32H2: CAN_SPEEDS_ESP32_H2, } diff --git a/esphome/components/gree/climate.py b/esphome/components/gree/climate.py index 02ce7b12d4..c88a428391 100644 --- a/esphome/components/gree/climate.py +++ b/esphome/components/gree/climate.py @@ -16,6 +16,7 @@ MODELS = { "yan": Model.GREE_YAN, "yaa": Model.GREE_YAA, "yac": Model.GREE_YAC, + "yac1fb9": Model.GREE_YAC1FB9, } CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend( diff --git a/esphome/components/gree/gree.cpp b/esphome/components/gree/gree.cpp index 1bbb443fce..cce2a8ffee 100644 --- a/esphome/components/gree/gree.cpp +++ b/esphome/components/gree/gree.cpp @@ -24,7 +24,7 @@ void GreeClimate::transmit_state() { remote_state[4] |= (this->horizontal_swing_() << 4); } - if (this->model_ == GREE_YAA || this->model_ == GREE_YAC) { + if (this->model_ == GREE_YAA || this->model_ == GREE_YAC || this->model_ == GREE_YAC1FB9) { remote_state[2] = 0x20; // bits 0..3 always 0000, bits 4..7 TURBO,LIGHT,HEALTH,X-FAN remote_state[3] = 0x50; // bits 4..7 always 0101 remote_state[6] = 0x20; // YAA1FB, FAA1FB1, YB1F2 bits 4..7 always 0010 @@ -53,7 +53,11 @@ void GreeClimate::transmit_state() { data->set_carrier_frequency(GREE_IR_FREQUENCY); data->mark(GREE_HEADER_MARK); - data->space(GREE_HEADER_SPACE); + if (this->model_ == GREE_YAC1FB9) { + data->space(GREE_YAC1FB9_HEADER_SPACE); + } else { + data->space(GREE_HEADER_SPACE); + } for (int i = 0; i < 4; i++) { for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask @@ -71,7 +75,11 @@ void GreeClimate::transmit_state() { data->space(GREE_ZERO_SPACE); data->mark(GREE_BIT_MARK); - data->space(GREE_MESSAGE_SPACE); + if (this->model_ == GREE_YAC1FB9) { + data->space(GREE_YAC1FB9_MESSAGE_SPACE); + } else { + data->space(GREE_MESSAGE_SPACE); + } for (int i = 4; i < 8; i++) { for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask diff --git a/esphome/components/gree/gree.h b/esphome/components/gree/gree.h index e7131a2b89..524a95aebd 100644 --- a/esphome/components/gree/gree.h +++ b/esphome/components/gree/gree.h @@ -41,6 +41,10 @@ const uint32_t GREE_YAC_HEADER_MARK = 6000; const uint32_t GREE_YAC_HEADER_SPACE = 3000; const uint32_t GREE_YAC_BIT_MARK = 650; +// Timing specific to YAC1FB9 +const uint32_t GREE_YAC1FB9_HEADER_SPACE = 4500; +const uint32_t GREE_YAC1FB9_MESSAGE_SPACE = 19980; + // State Frame size const uint8_t GREE_STATE_FRAME_SIZE = 8; @@ -67,7 +71,7 @@ const uint8_t GREE_HDIR_MRIGHT = 0x05; const uint8_t GREE_HDIR_RIGHT = 0x06; // Model codes -enum Model { GREE_GENERIC, GREE_YAN, GREE_YAA, GREE_YAC }; +enum Model { GREE_GENERIC, GREE_YAN, GREE_YAA, GREE_YAC, GREE_YAC1FB9 }; class GreeClimate : public climate_ir::ClimateIR { public: diff --git a/esphome/components/jsn_sr04t/jsn_sr04t.cpp b/esphome/components/jsn_sr04t/jsn_sr04t.cpp index b96bf8f762..077d4e58ea 100644 --- a/esphome/components/jsn_sr04t/jsn_sr04t.cpp +++ b/esphome/components/jsn_sr04t/jsn_sr04t.cpp @@ -31,7 +31,16 @@ void Jsnsr04tComponent::loop() { } void Jsnsr04tComponent::check_buffer_() { - uint8_t checksum = this->buffer_[0] + this->buffer_[1] + this->buffer_[2]; + uint8_t checksum = 0; + switch (this->model_) { + case JSN_SR04T: + checksum = this->buffer_[0] + this->buffer_[1] + this->buffer_[2]; + break; + case AJ_SR04M: + checksum = this->buffer_[1] + this->buffer_[2]; + break; + } + if (this->buffer_[3] == checksum) { uint16_t distance = encode_uint16(this->buffer_[1], this->buffer_[2]); if (distance > 250) { @@ -49,6 +58,14 @@ void Jsnsr04tComponent::check_buffer_() { void Jsnsr04tComponent::dump_config() { LOG_SENSOR("", "JST_SR04T Sensor", this); + switch (this->model_) { + case JSN_SR04T: + ESP_LOGCONFIG(TAG, " sensor model: jsn_sr04t"); + break; + case AJ_SR04M: + ESP_LOGCONFIG(TAG, " sensor model: aj_sr04m"); + break; + } LOG_UPDATE_INTERVAL(this); } diff --git a/esphome/components/jsn_sr04t/jsn_sr04t.h b/esphome/components/jsn_sr04t/jsn_sr04t.h index bd43252be8..2a22ff92ec 100644 --- a/esphome/components/jsn_sr04t/jsn_sr04t.h +++ b/esphome/components/jsn_sr04t/jsn_sr04t.h @@ -9,9 +9,14 @@ namespace esphome { namespace jsn_sr04t { +enum Model { + JSN_SR04T, + AJ_SR04M, +}; + class Jsnsr04tComponent : public sensor::Sensor, public PollingComponent, public uart::UARTDevice { public: - // Nothing really public. + void set_model(Model model) { this->model_ = model; } // ========== INTERNAL METHODS ========== void update() override; @@ -20,6 +25,7 @@ class Jsnsr04tComponent : public sensor::Sensor, public PollingComponent, public protected: void check_buffer_(); + Model model_; std::vector buffer_; }; diff --git a/esphome/components/jsn_sr04t/sensor.py b/esphome/components/jsn_sr04t/sensor.py index 4b062e81e9..682cf06570 100644 --- a/esphome/components/jsn_sr04t/sensor.py +++ b/esphome/components/jsn_sr04t/sensor.py @@ -5,6 +5,7 @@ from esphome.const import ( STATE_CLASS_MEASUREMENT, UNIT_METER, ICON_ARROW_EXPAND_VERTICAL, + CONF_MODEL, ) CODEOWNERS = ["@Mafus1"] @@ -14,6 +15,11 @@ jsn_sr04t_ns = cg.esphome_ns.namespace("jsn_sr04t") Jsnsr04tComponent = jsn_sr04t_ns.class_( "Jsnsr04tComponent", sensor.Sensor, cg.PollingComponent, uart.UARTDevice ) +Model = jsn_sr04t_ns.enum("Model") +MODEL = { + "jsn_sr04t": Model.JSN_SR04T, + "aj_sr04m": Model.AJ_SR04M, +} CONFIG_SCHEMA = ( sensor.sensor_schema( @@ -25,6 +31,11 @@ CONFIG_SCHEMA = ( ) .extend(cv.polling_component_schema("60s")) .extend(uart.UART_DEVICE_SCHEMA) + .extend( + { + cv.Optional(CONF_MODEL, default="jsn_sr04t"): cv.enum(MODEL, upper=False), + } + ) ) FINAL_VALIDATE_SCHEMA = uart.final_validate_device_schema( @@ -42,3 +53,5 @@ async def to_code(config): var = await sensor.new_sensor(config) await cg.register_component(var, config) await uart.register_uart_device(var, config) + + cg.add(var.set_model(config[CONF_MODEL])) diff --git a/esphome/components/restart/button/__init__.py b/esphome/components/restart/button/__init__.py index 1b2c991261..6aff8cb351 100644 --- a/esphome/components/restart/button/__init__.py +++ b/esphome/components/restart/button/__init__.py @@ -5,6 +5,7 @@ from esphome.const import ( CONF_ID, DEVICE_CLASS_RESTART, ENTITY_CATEGORY_CONFIG, + ICON_RESTART, ) restart_ns = cg.esphome_ns.namespace("restart") @@ -12,6 +13,7 @@ RestartButton = restart_ns.class_("RestartButton", button.Button, cg.Component) CONFIG_SCHEMA = button.button_schema( RestartButton, + icon=ICON_RESTART, device_class=DEVICE_CLASS_RESTART, entity_category=ENTITY_CATEGORY_CONFIG, ).extend(cv.COMPONENT_SCHEMA) diff --git a/esphome/components/voice_assistant/voice_assistant.cpp b/esphome/components/voice_assistant/voice_assistant.cpp index 8a8a9e92aa..e4f388db68 100644 --- a/esphome/components/voice_assistant/voice_assistant.cpp +++ b/esphome/components/voice_assistant/voice_assistant.cpp @@ -684,7 +684,9 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) { this->defer([this, text]() { this->tts_start_trigger_->trigger(text); #ifdef USE_SPEAKER - this->speaker_->start(); + if (this->speaker_ != nullptr) { + this->speaker_->start(); + } #endif }); break;