From 1bb81a49821d3939de191c679af6cd569c38c548 Mon Sep 17 00:00:00 2001 From: vge Date: Tue, 24 Dec 2024 08:20:40 -0800 Subject: [PATCH] Add a feature to republish the remote temperature at a given time interval --- components/mitsubishi_heatpump/climate.py | 5 +++ components/mitsubishi_heatpump/espmhp.cpp | 46 +++++++++++++++++++---- components/mitsubishi_heatpump/espmhp.h | 11 ++++++ 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/components/mitsubishi_heatpump/climate.py b/components/mitsubishi_heatpump/climate.py index da16834..ea1cb49 100644 --- a/components/mitsubishi_heatpump/climate.py +++ b/components/mitsubishi_heatpump/climate.py @@ -36,6 +36,7 @@ VERTICAL_SWING_OPTIONS = ["swing", "auto", "up", "up_center", "center", "down_center", "down"] # Remote temperature timeout configuration +CONF_REMOTE_PUBLISH_FREQUENCY = "remote_publish_frequency_seconds" CONF_REMOTE_OPERATING_TIMEOUT = "remote_temperature_operating_timeout_minutes" CONF_REMOTE_IDLE_TIMEOUT = "remote_temperature_idle_timeout_minutes" CONF_REMOTE_PING_TIMEOUT = "remote_temperature_ping_timeout_minutes" @@ -68,6 +69,7 @@ def valid_uart(uart): cv.GenerateID(): cv.declare_id(MitsubishiHeatPump), cv.Optional(CONF_HARDWARE_UART, default="UART0"): valid_uart, cv.Optional(CONF_BAUD_RATE): cv.positive_int, + cv.Optional(CONF_REMOTE_PUBLISH_FREQUENCY): cv.positive_int, cv.Optional(CONF_REMOTE_OPERATING_TIMEOUT): cv.positive_int, cv.Optional(CONF_REMOTE_IDLE_TIMEOUT): cv.positive_int, cv.Optional(CONF_REMOTE_PING_TIMEOUT): cv.positive_int, @@ -110,6 +112,9 @@ def to_code(config): if CONF_TX_PIN in config: cg.add(var.set_tx_pin(config[CONF_TX_PIN])) + if CONF_REMOTE_PUBLISH_FREQUENCY in config: + cg.add(var.set_remote_publish_frequency_seconds(config[CONF_REMOTE_PUBLISH_FREQUENCY])) + if CONF_REMOTE_OPERATING_TIMEOUT in config: cg.add(var.set_remote_operating_timeout_minutes(config[CONF_REMOTE_OPERATING_TIMEOUT])) diff --git a/components/mitsubishi_heatpump/espmhp.cpp b/components/mitsubishi_heatpump/espmhp.cpp index 2f789c0..8c4244e 100644 --- a/components/mitsubishi_heatpump/espmhp.cpp +++ b/components/mitsubishi_heatpump/espmhp.cpp @@ -85,6 +85,7 @@ void MitsubishiHeatPump::update() { this->hpStatusChanged(currentStatus); #endif this->enforce_remote_temperature_sensor_timeout(); + this->set_remote_temperature(this->remote_temperature); } void MitsubishiHeatPump::set_baud_rate(int baud) { @@ -620,15 +621,38 @@ void MitsubishiHeatPump::hpStatusChanged(heatpumpStatus currentStatus) { } void MitsubishiHeatPump::set_remote_temperature(float temp) { - ESP_LOGD(TAG, "Setting remote temp: %.1f", temp); - if (temp > 0) { - last_remote_temperature_sensor_update_ = - std::chrono::steady_clock::now(); - } else { - last_remote_temperature_sensor_update_.reset(); + + bool isTempNew = (this->remote_temperature != temp); + + if (isTempNew) { + if (temp > 0) { + this->remote_temperature = temp; + + last_remote_temperature_sensor_update_ = + std::chrono::steady_clock::now(); + } else { + this->remote_temperature = 0; + last_remote_temperature_sensor_update_.reset(); + } } - this->hp->setRemoteTemperature(temp); + auto time_since_last_remote_temperature_publish = + last_remote_temperature_publish_.has_value() ? + (std::chrono::steady_clock::now() - last_remote_temperature_publish_.value()) : + std::chrono::seconds(99999999); + + bool refreshRemoteTemp = remote_publish_frequency_.has_value() ? + (time_since_last_remote_temperature_publish >= remote_publish_frequency_.value()) : + false; + + // Do not send zeros UNLESS the zero is new, which means it wasn't zero at one point + // and now we need to update the HP to be zero once. This zero check also prevents + // us from telling the HP about a remote temperature if there is none + if (isTempNew || (refreshRemoteTemp && this->remote_temperature != 0)) { + ESP_LOGD(TAG, "Setting remote temp: %.1f", this->remote_temperature); + this->hp->setRemoteTemperature(this->remote_temperature); + last_remote_temperature_publish_ = std::chrono::steady_clock::now(); + } } void MitsubishiHeatPump::ping() { @@ -636,6 +660,11 @@ void MitsubishiHeatPump::ping() { last_ping_request_ = std::chrono::steady_clock::now(); } +void MitsubishiHeatPump::set_remote_publish_frequency_seconds(int seconds) { + ESP_LOGD(TAG, "Setting remote publish frequency: %d seconds", seconds); + remote_publish_frequency_ = std::chrono::seconds(seconds); +} + void MitsubishiHeatPump::set_remote_operating_timeout_minutes(int minutes) { ESP_LOGD(TAG, "Setting remote operating timeout time: %d minutes", minutes); remote_operating_timeout_ = std::chrono::minutes(minutes); @@ -692,6 +721,7 @@ void MitsubishiHeatPump::setup() { ESP_LOGCONFIG(TAG, "Initializing new HeatPump object."); this->hp = new HeatPump(); this->current_temperature = NAN; + this->remote_temperature = 0; this->target_temperature = NAN; this->fan_mode = climate::CLIMATE_FAN_OFF; this->swing_mode = climate::CLIMATE_SWING_OFF; @@ -792,4 +822,4 @@ void MitsubishiHeatPump::log_packet(byte* packet, unsigned int length, char* pac } ESP_LOGV(TAG, "PKT: [%s] %s", packetDirection, packetHex.c_str()); -} \ No newline at end of file +} diff --git a/components/mitsubishi_heatpump/espmhp.h b/components/mitsubishi_heatpump/espmhp.h index 110d6be..828ed74 100644 --- a/components/mitsubishi_heatpump/espmhp.h +++ b/components/mitsubishi_heatpump/espmhp.h @@ -108,6 +108,12 @@ class MitsubishiHeatPump : public esphome::PollingComponent, public esphome::cli // and this heatpump. void ping(); + // Number of seconds to tell the HP about the remote temperature (if set). + // Newer HP seem to forget the remote temperature much faster and therefore + // require the remote temp to set even if there isn't a change. Anecdottaly, + // they seem to forget the temperature every 60s or so. + void set_remote_publish_frequency_seconds(int seconds); + // Number of minutes before the heatpump reverts back to the internal // temperature sensor if the machine is currently operating. void set_remote_operating_timeout_minutes(int); @@ -127,6 +133,9 @@ class MitsubishiHeatPump : public esphome::PollingComponent, public esphome::cli // The ClimateTraits supported by this HeatPump. esphome::climate::ClimateTraits traits_; + // Remote Temperature + float remote_temperature{0}; + // Vane position void update_swing_horizontal(const std::string &swing); void update_swing_vertical(const std::string &swing); @@ -182,6 +191,8 @@ class MitsubishiHeatPump : public esphome::PollingComponent, public esphome::cli std::optional>> remote_operating_timeout_; std::optional>> remote_idle_timeout_; std::optional>> remote_ping_timeout_; + std::optional>> remote_publish_frequency_; + std::optional> last_remote_temperature_publish_; std::optional> last_remote_temperature_sensor_update_; std::optional> last_ping_request_; };