diff --git a/esphome/components/api/api.proto b/esphome/components/api/api.proto index b9b56d3f8e..d21e82f50c 100644 --- a/esphome/components/api/api.proto +++ b/esphome/components/api/api.proto @@ -555,9 +555,10 @@ enum LogLevel { LOG_LEVEL_ERROR = 1; LOG_LEVEL_WARN = 2; LOG_LEVEL_INFO = 3; - LOG_LEVEL_DEBUG = 4; - LOG_LEVEL_VERBOSE = 5; - LOG_LEVEL_VERY_VERBOSE = 6; + LOG_LEVEL_CONFIG = 4; + LOG_LEVEL_DEBUG = 5; + LOG_LEVEL_VERBOSE = 6; + LOG_LEVEL_VERY_VERBOSE = 7; } message SubscribeLogsRequest { option (id) = 28; @@ -572,7 +573,6 @@ message SubscribeLogsResponse { option (no_delay) = false; LogLevel level = 1; - string tag = 2; string message = 3; bool send_failed = 4; } diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 5fba549a57..4a31f15e77 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -310,22 +310,15 @@ bool APIConnection::send_light_state(light::LightState *light) { resp.key = light->get_object_id_hash(); resp.state = values.is_on(); resp.color_mode = static_cast(color_mode); - if (color_mode & light::ColorCapability::BRIGHTNESS) - resp.brightness = values.get_brightness(); - if (color_mode & light::ColorCapability::RGB) { - resp.color_brightness = values.get_color_brightness(); - resp.red = values.get_red(); - resp.green = values.get_green(); - resp.blue = values.get_blue(); - } - if (color_mode & light::ColorCapability::WHITE) - resp.white = values.get_white(); - if (color_mode & light::ColorCapability::COLOR_TEMPERATURE) - resp.color_temperature = values.get_color_temperature(); - if (color_mode & light::ColorCapability::COLD_WARM_WHITE) { - resp.cold_white = values.get_cold_white(); - resp.warm_white = values.get_warm_white(); - } + resp.brightness = values.get_brightness(); + resp.color_brightness = values.get_color_brightness(); + resp.red = values.get_red(); + resp.green = values.get_green(); + resp.blue = values.get_blue(); + resp.white = values.get_white(); + resp.color_temperature = values.get_color_temperature(); + resp.cold_white = values.get_cold_white(); + resp.warm_white = values.get_warm_white(); if (light->supports_effects()) resp.effect = light->get_effect_name(); return this->send_light_state_response(resp); @@ -701,8 +694,6 @@ bool APIConnection::send_log_message(int level, const char *tag, const char *lin auto buffer = this->create_buffer(); // LogLevel level = 1; buffer.encode_uint32(1, static_cast(level)); - // string tag = 2; - // buffer.encode_string(2, tag, strlen(tag)); // string message = 3; buffer.encode_string(3, line, strlen(line)); // SubscribeLogsResponse - 29 diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index eecba7a68e..aaeef57324 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -120,6 +120,8 @@ template<> const char *proto_enum_to_string(enums::LogLevel val return "LOG_LEVEL_WARN"; case enums::LOG_LEVEL_INFO: return "LOG_LEVEL_INFO"; + case enums::LOG_LEVEL_CONFIG: + return "LOG_LEVEL_CONFIG"; case enums::LOG_LEVEL_DEBUG: return "LOG_LEVEL_DEBUG"; case enums::LOG_LEVEL_VERBOSE: @@ -2334,10 +2336,6 @@ bool SubscribeLogsResponse::decode_varint(uint32_t field_id, ProtoVarInt value) } bool SubscribeLogsResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) { switch (field_id) { - case 2: { - this->tag = value.as_string(); - return true; - } case 3: { this->message = value.as_string(); return true; @@ -2348,7 +2346,6 @@ bool SubscribeLogsResponse::decode_length(uint32_t field_id, ProtoLengthDelimite } void SubscribeLogsResponse::encode(ProtoWriteBuffer buffer) const { buffer.encode_enum(1, this->level); - buffer.encode_string(2, this->tag); buffer.encode_string(3, this->message); buffer.encode_bool(4, this->send_failed); } @@ -2360,10 +2357,6 @@ void SubscribeLogsResponse::dump_to(std::string &out) const { out.append(proto_enum_to_string(this->level)); out.append("\n"); - out.append(" tag: "); - out.append("'").append(this->tag).append("'"); - out.append("\n"); - out.append(" message: "); out.append("'").append(this->message).append("'"); out.append("\n"); diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index be32488391..2395a4bec3 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -58,9 +58,10 @@ enum LogLevel : uint32_t { LOG_LEVEL_ERROR = 1, LOG_LEVEL_WARN = 2, LOG_LEVEL_INFO = 3, - LOG_LEVEL_DEBUG = 4, - LOG_LEVEL_VERBOSE = 5, - LOG_LEVEL_VERY_VERBOSE = 6, + LOG_LEVEL_CONFIG = 4, + LOG_LEVEL_DEBUG = 5, + LOG_LEVEL_VERBOSE = 6, + LOG_LEVEL_VERY_VERBOSE = 7, }; enum ServiceArgType : uint32_t { SERVICE_ARG_TYPE_BOOL = 0, @@ -627,7 +628,6 @@ class SubscribeLogsRequest : public ProtoMessage { class SubscribeLogsResponse : public ProtoMessage { public: enums::LogLevel level{}; - std::string tag{}; std::string message{}; bool send_failed{false}; void encode(ProtoWriteBuffer buffer) const override; diff --git a/esphome/components/mqtt/mqtt_sensor.cpp b/esphome/components/mqtt/mqtt_sensor.cpp index c106a95902..ce7e89c584 100644 --- a/esphome/components/mqtt/mqtt_sensor.cpp +++ b/esphome/components/mqtt/mqtt_sensor.cpp @@ -61,6 +61,9 @@ void MQTTSensorComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryCo if (this->sensor_->get_force_update()) root["force_update"] = true; + if (this->sensor_->state_class == sensor::STATE_CLASS_MEASUREMENT) + root["state_class"] = "measurement"; + config.command_topic = false; } bool MQTTSensorComponent::send_initial_state() { diff --git a/esphome/components/thermostat/thermostat_climate.cpp b/esphome/components/thermostat/thermostat_climate.cpp index d9d8b106ea..a75713cbb9 100644 --- a/esphome/components/thermostat/thermostat_climate.cpp +++ b/esphome/components/thermostat/thermostat_climate.cpp @@ -57,29 +57,34 @@ void ThermostatClimate::refresh() { } bool ThermostatClimate::climate_action_change_delayed() { + bool state_mismatch = this->action != this->compute_action_(true); + switch (this->compute_action_(true)) { case climate::CLIMATE_ACTION_OFF: case climate::CLIMATE_ACTION_IDLE: - return !this->idle_action_ready_(); + return state_mismatch && (!this->idle_action_ready_()); case climate::CLIMATE_ACTION_COOLING: - return !this->cooling_action_ready_(); + return state_mismatch && (!this->cooling_action_ready_()); case climate::CLIMATE_ACTION_HEATING: - return !this->heating_action_ready_(); + return state_mismatch && (!this->heating_action_ready_()); case climate::CLIMATE_ACTION_FAN: - return !this->fanning_action_ready_(); + return state_mismatch && (!this->fanning_action_ready_()); case climate::CLIMATE_ACTION_DRYING: - return !this->drying_action_ready_(); + return state_mismatch && (!this->drying_action_ready_()); default: break; } return false; } -bool ThermostatClimate::fan_mode_change_delayed() { return !this->fan_mode_ready_(); } +bool ThermostatClimate::fan_mode_change_delayed() { + bool state_mismatch = this->fan_mode.value_or(climate::CLIMATE_FAN_ON) != this->prev_fan_mode_; + return state_mismatch && (!this->fan_mode_ready_()); +} climate::ClimateAction ThermostatClimate::delayed_climate_action() { return this->compute_action_(true); } -climate::ClimateFanMode ThermostatClimate::delayed_fan_mode() { return this->desired_fan_mode_; } +climate::ClimateFanMode ThermostatClimate::locked_fan_mode() { return this->prev_fan_mode_; } bool ThermostatClimate::hysteresis_valid() { if ((this->supports_cool_ || (this->supports_fan_only_ && this->supports_fan_only_cooling_)) && @@ -510,7 +515,7 @@ void ThermostatClimate::switch_to_fan_mode_(climate::ClimateFanMode fan_mode) { // already in target mode return; - this->desired_fan_mode_ = fan_mode; // needed for timer callback + this->fan_mode = fan_mode; if (this->fan_mode_ready_()) { Trigger<> *trig = this->fan_mode_auto_trigger_; @@ -564,7 +569,6 @@ void ThermostatClimate::switch_to_fan_mode_(climate::ClimateFanMode fan_mode) { this->start_timer_(thermostat::TIMER_FAN_MODE); assert(trig != nullptr); trig->trigger(); - this->fan_mode = fan_mode; this->prev_fan_mode_ = fan_mode; this->prev_fan_mode_trigger_ = trig; } @@ -733,7 +737,7 @@ void ThermostatClimate::cooling_on_timer_callback_() { void ThermostatClimate::fan_mode_timer_callback_() { ESP_LOGVV(TAG, "fan_mode timer expired"); this->timer_[thermostat::TIMER_FAN_MODE].active = false; - this->switch_to_fan_mode_(this->desired_fan_mode_); + this->switch_to_fan_mode_(this->fan_mode.value_or(climate::CLIMATE_FAN_ON)); if (this->supports_fan_only_action_uses_fan_mode_timer_) this->switch_to_action_(this->compute_action_()); } diff --git a/esphome/components/thermostat/thermostat_climate.h b/esphome/components/thermostat/thermostat_climate.h index 1a5fd82ac0..60777e7c81 100644 --- a/esphome/components/thermostat/thermostat_climate.h +++ b/esphome/components/thermostat/thermostat_climate.h @@ -136,8 +136,8 @@ class ThermostatClimate : public climate::Climate, public Component { bool fan_mode_change_delayed(); /// Returns the climate action that is being delayed (check climate_action_change_delayed(), first!) climate::ClimateAction delayed_climate_action(); - /// Returns the fan mode that is being delayed (check fan_mode_change_delayed(), first!) - climate::ClimateFanMode delayed_fan_mode(); + /// Returns the fan mode that is locked in (check fan_mode_change_delayed(), first!) + climate::ClimateFanMode locked_fan_mode(); /// Set point and hysteresis validation bool hysteresis_valid(); // returns true if valid void validate_target_temperature(); @@ -377,9 +377,6 @@ class ThermostatClimate : public climate::Climate, public Component { Trigger<> *prev_mode_trigger_{nullptr}; Trigger<> *prev_swing_mode_trigger_{nullptr}; - /// Desired fan_mode -- used to store desired mode for callback when switching is delayed - climate::ClimateFanMode desired_fan_mode_{climate::CLIMATE_FAN_ON}; - /// Store previously-known states /// /// These are used to determine when a trigger/action needs to be called diff --git a/esphome/const.py b/esphome/const.py index 2b9418a81c..89be4b7fd7 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "1.21.0b1" +__version__ = "1.21.0b2" ESP_PLATFORM_ESP32 = "ESP32" ESP_PLATFORM_ESP8266 = "ESP8266"