Modified patch for vane support.

Starting from https://github.com/geoffdavis/esphome-mitsubishiheatpump/pull/103 by @seime,
extract the vane implementation code and format according to existing style.
Leave behind all the reformatting.
This commit is contained in:
Nathan J. Williams 2023-08-03 09:58:53 -04:00
parent 0c3742c05d
commit 53c3d88e55
5 changed files with 248 additions and 9 deletions

View File

@ -231,6 +231,11 @@ climate:
- platform: mitsubishi_heatpump
name: "${friendly_name}"
horizontal_vane_select:
name: Horizontal Vane
vertical_vane_select:
name: Vertical Vane
# ESP32 only - change UART0 to UART1 or UART2 and remove the
# logging:baud_rate above to allow the built-in UART0 to function for
# logging.
@ -318,6 +323,11 @@ climate:
- platform: mitsubishi_heatpump
name: "${friendly_name}"
horizontal_vane_select:
name: Horizontal Vane
vertical_vane_select:
name: Vertical Vane
# ESP32 only - change UART0 to UART1 or UART2 and remove the
# logging:baud_rate above to allow the built-in UART0 to function for
# logging.
@ -341,8 +351,7 @@ climate:
supports:
mode: ["HEAT_COOL", "COOL", "HEAT", "FAN_ONLY"]
fan_mode: ["AUTO", "LOW", "MEDIUM", "HIGH"]
swing_mode: ["OFF", "VERTICAL"]
swing_mode: ["OFF", "VERTICAL", "HORIZONTAL", "BOTH"]
visual:
min_temperature: 16
max_temperature: 31
@ -371,7 +380,7 @@ climate:
* *fan_mode* (_Optional_, list): Supported fan speeds for the HeatPump.
Default: `['AUTO', 'DIFFUSE', 'LOW', 'MEDIUM', 'MIDDLE', 'HIGH']`
* *swing_mode* (_Optional_, list): Supported fan swing modes. Most Mitsubishi
units only support the default. Default: `['OFF', 'VERTICAL']`
units only support the default. Default: `['OFF', 'VERTICAL', 'HORIZONTAL', 'BOTH']`
## Other configuration

View File

@ -1,6 +1,6 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import climate
from esphome.components import climate, select
from esphome.components.logger import HARDWARE_UART_TO_SERIAL
from esphome.const import (
CONF_ID,
@ -15,17 +15,32 @@ from esphome.const import (
)
from esphome.core import CORE, coroutine
AUTO_LOAD = ["climate"]
AUTO_LOAD = ["climate", "select"]
CONF_SUPPORTS = "supports"
CONF_HORIZONTAL_SWING_SELECT = "horizontal_vane_select"
CONF_VERTICAL_SWING_SELECT = "vertical_vane_select"
DEFAULT_CLIMATE_MODES = ["HEAT_COOL", "COOL", "HEAT", "DRY", "FAN_ONLY"]
DEFAULT_FAN_MODES = ["AUTO", "DIFFUSE", "LOW", "MEDIUM", "MIDDLE", "HIGH"]
DEFAULT_SWING_MODES = ["OFF", "VERTICAL"]
DEFAULT_SWING_MODES = ["OFF", "VERTICAL", "HORIZONTAL", "BOTH"]
HORIZONTAL_SWING_OPTIONS = [
"auto",
"swing",
"left",
"left_center",
"center",
"right_center",
"right",
]
VERTICAL_SWING_OPTIONS = ["swing", "auto", "up", "up_center", "center", "down_center", "down"]
MitsubishiHeatPump = cg.global_ns.class_(
"MitsubishiHeatPump", climate.Climate, cg.PollingComponent
)
MitsubishiACSelect = cg.global_ns.class_(
"MitsubishiACSelect", select.Select, cg.Component
)
def valid_uart(uart):
if CORE.is_esp8266:
@ -38,6 +53,10 @@ def valid_uart(uart):
return cv.one_of(*uarts, upper=True)(uart)
SELECT_SCHEMA = select.SELECT_SCHEMA.extend(
{cv.GenerateID(CONF_ID): cv.declare_id(MitsubishiACSelect)}
)
CONFIG_SCHEMA = climate.CLIMATE_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(MitsubishiHeatPump),
@ -50,6 +69,9 @@ CONFIG_SCHEMA = climate.CLIMATE_SCHEMA.extend(
cv.Optional(CONF_UPDATE_INTERVAL, default="500ms"): cv.All(
cv.update_interval, cv.Range(max=cv.TimePeriod(milliseconds=9000))
),
# Add selects for vertical and horizontal vane positions
cv.Optional(CONF_HORIZONTAL_SWING_SELECT): SELECT_SCHEMA,
cv.Optional(CONF_VERTICAL_SWING_SELECT): SELECT_SCHEMA,
# Optionally override the supported ClimateTraits.
cv.Optional(CONF_SUPPORTS, default={}): cv.Schema(
{
@ -95,6 +117,18 @@ def to_code(config):
climate.CLIMATE_SWING_MODES[mode]
))
if CONF_HORIZONTAL_SWING_SELECT in config:
conf = config[CONF_HORIZONTAL_SWING_SELECT]
swing_select = yield select.new_select(conf, options=HORIZONTAL_SWING_OPTIONS)
yield cg.register_component(swing_select, conf)
cg.add(var.set_horizontal_vane_select(swing_select))
if CONF_VERTICAL_SWING_SELECT in config:
conf = config[CONF_VERTICAL_SWING_SELECT]
swing_select = yield select.new_select(conf, options=VERTICAL_SWING_OPTIONS)
yield cg.register_component(swing_select, conf)
cg.add(var.set_vertical_vane_select(swing_select))
yield cg.register_component(var, config)
yield climate.register_climate(var, config)
cg.add_library(

View File

@ -105,6 +105,117 @@ climate::ClimateTraits& MitsubishiHeatPump::config_traits() {
return traits_;
}
void MitsubishiHeatPump::update_swing_horizontal(const std::string &swing) {
this->horizontal_swing_state_ = swing;
if (this->horizontal_vane_select_ != nullptr &&
this->horizontal_vane_select_->state != this->horizontal_swing_state_) {
this->horizontal_vane_select_->publish_state(
this->horizontal_swing_state_); // Set current horizontal swing
// position
}
}
void MitsubishiHeatPump::update_swing_vertical(const std::string &swing) {
this->vertical_swing_state_ = swing;
if (this->vertical_vane_select_ != nullptr &&
this->vertical_vane_select_->state != this->vertical_swing_state_) {
this->vertical_vane_select_->publish_state(
this->vertical_swing_state_); // Set current vertical swing position
}
}
void MitsubishiHeatPump::set_vertical_vane_select(
select::Select *vertical_vane_select) {
this->vertical_vane_select_ = vertical_vane_select;
this->vertical_vane_select_->add_on_state_callback(
[this](const std::string &value, size_t index) {
if (value == this->vertical_swing_state_) return;
this->on_vertical_swing_change(value);
});
}
void MitsubishiHeatPump::set_horizontal_vane_select(
select::Select *horizontal_vane_select) {
this->horizontal_vane_select_ = horizontal_vane_select;
this->horizontal_vane_select_->add_on_state_callback(
[this](const std::string &value, size_t index) {
if (value == this->horizontal_swing_state_) return;
this->on_horizontal_swing_change(value);
});
}
void MitsubishiHeatPump::on_vertical_swing_change(const std::string &swing) {
ESP_LOGD(TAG, "Setting vertical swing position");
bool updated = false;
if (swing == "swing") {
hp->setVaneSetting("SWING");
updated = true;
} else if (swing == "auto") {
hp->setVaneSetting("AUTO");
updated = true;
} else if (swing == "up") {
hp->setVaneSetting("1");
updated = true;
} else if (swing == "up_center") {
hp->setVaneSetting("2");
updated = true;
} else if (swing == "center") {
hp->setVaneSetting("3");
updated = true;
} else if (swing == "down_center") {
hp->setVaneSetting("4");
updated = true;
} else if (swing == "down") {
hp->setVaneSetting("5");
updated = true;
} else {
ESP_LOGW(TAG, "Invalid vertical vane position %s", swing);
}
ESP_LOGD(TAG, "Vertical vane - Was HeatPump updated? %s", YESNO(updated));
// and the heat pump:
hp->update();
}
void MitsubishiHeatPump::on_horizontal_swing_change(const std::string &swing) {
ESP_LOGD(TAG, "Setting horizontal swing position");
bool updated = false;
if (swing == "swing") {
hp->setWideVaneSetting("SWING");
updated = true;
} else if (swing == "auto") {
hp->setWideVaneSetting("<>");
updated = true;
} else if (swing == "left") {
hp->setWideVaneSetting("<<");
updated = true;
} else if (swing == "left_center") {
hp->setWideVaneSetting("<");
updated = true;
} else if (swing == "center") {
hp->setWideVaneSetting("|");
updated = true;
} else if (swing == "right_center") {
hp->setWideVaneSetting(">");
updated = true;
} else if (swing == "right") {
hp->setWideVaneSetting(">>");
updated = true;
} else {
ESP_LOGW(TAG, "Invalid horizontal vane position %s", swing);
}
ESP_LOGD(TAG, "Horizontal vane - Was HeatPump updated? %s", YESNO(updated));
// and the heat pump:
hp->update();
}
/**
* Implement control of a MitsubishiHeatPump.
*
@ -240,10 +351,22 @@ void MitsubishiHeatPump::control(const climate::ClimateCall &call) {
switch(*call.get_swing_mode()) {
case climate::CLIMATE_SWING_OFF:
hp->setVaneSetting("AUTO");
hp->setWideVaneSetting("|");
updated = true;
break;
case climate::CLIMATE_SWING_VERTICAL:
hp->setVaneSetting("SWING");
hp->setWideVaneSetting("|");
updated = true;
break;
case climate::CLIMATE_SWING_HORIZONTAL:
hp->setVaneSetting("3");
hp->setWideVaneSetting("SWING");
updated = true;
break;
case climate::CLIMATE_SWING_BOTH:
hp->setVaneSetting("SWING");
hp->setWideVaneSetting("SWING");
updated = true;
break;
default:
@ -346,15 +469,52 @@ void MitsubishiHeatPump::hpSettingsChanged() {
/* ******** HANDLE MITSUBISHI VANE CHANGES ********
* const char* VANE_MAP[7] = {"AUTO", "1", "2", "3", "4", "5", "SWING"};
*/
if (strcmp(currentSettings.vane, "SWING") == 0) {
if (strcmp(currentSettings.vane, "SWING") == 0 &&
strcmp(currentSettings.wideVane, "SWING") == 0) {
this->swing_mode = climate::CLIMATE_SWING_BOTH;
} else if (strcmp(currentSettings.vane, "SWING") == 0) {
this->swing_mode = climate::CLIMATE_SWING_VERTICAL;
}
else {
} else if (strcmp(currentSettings.wideVane, "SWING") == 0) {
this->swing_mode = climate::CLIMATE_SWING_HORIZONTAL;
} else {
this->swing_mode = climate::CLIMATE_SWING_OFF;
}
ESP_LOGI(TAG, "Swing mode is: %i", this->swing_mode);
if (strcmp(currentSettings.vane, "SWING") == 0) {
this->update_swing_vertical("swing");
} else if (strcmp(currentSettings.vane, "AUTO") == 0) {
this->update_swing_vertical("auto");
} else if (strcmp(currentSettings.vane, "1") == 0) {
this->update_swing_vertical("up");
} else if (strcmp(currentSettings.vane, "2") == 0) {
this->update_swing_vertical("up_center");
} else if (strcmp(currentSettings.vane, "3") == 0) {
this->update_swing_vertical("center");
} else if (strcmp(currentSettings.vane, "4") == 0) {
this->update_swing_vertical("down_center");
} else if (strcmp(currentSettings.vane, "5") == 0) {
this->update_swing_vertical("down");
}
ESP_LOGI(TAG, "Vertical vane mode is: %s", currentSettings.vane);
if (strcmp(currentSettings.wideVane, "SWING") == 0) {
this->update_swing_horizontal("swing");
} else if (strcmp(currentSettings.wideVane, "<>") == 0) {
this->update_swing_horizontal("auto");
} else if (strcmp(currentSettings.wideVane, "<<") == 0) {
this->update_swing_horizontal("left");
} else if (strcmp(currentSettings.wideVane, "<") == 0) {
this->update_swing_horizontal("left_center");
} else if (strcmp(currentSettings.wideVane, "|") == 0) {
this->update_swing_horizontal("center");
} else if (strcmp(currentSettings.wideVane, ">") == 0) {
this->update_swing_horizontal("right_center");
} else if (strcmp(currentSettings.wideVane, ">>") == 0) {
this->update_swing_horizontal("right");
}
ESP_LOGI(TAG, "Horizontal vane mode is: %s", currentSettings.wideVane);
/*
* ******** HANDLE TARGET TEMPERATURE CHANGES ********
@ -444,6 +604,8 @@ void MitsubishiHeatPump::setup() {
this->target_temperature = NAN;
this->fan_mode = climate::CLIMATE_FAN_OFF;
this->swing_mode = climate::CLIMATE_SWING_OFF;
this->vertical_swing_state_ = "auto";
this->horizontal_swing_state_ = "auto";
#ifdef USE_CALLBACKS
hp->setSettingsChangedCallback(

View File

@ -18,6 +18,7 @@
#define USE_CALLBACKS
#include "esphome.h"
#include "esphome/components/select/select.h"
#include "esphome/core/preferences.h"
#include "HeatPump.h"
@ -99,6 +100,9 @@ class MitsubishiHeatPump : public esphome::PollingComponent, public esphome::cli
// set_remote_temp(0) to switch back to the internal sensor.
void set_remote_temperature(float);
void set_vertical_vane_select(select::Select *vertical_vane_select);
void set_horizontal_vane_select(select::Select *horizontal_vane_select);
protected:
// HeatPump object using the underlying Arduino library.
HeatPump* hp;
@ -106,6 +110,12 @@ class MitsubishiHeatPump : public esphome::PollingComponent, public esphome::cli
// The ClimateTraits supported by this HeatPump.
esphome::climate::ClimateTraits traits_;
// Vane position
void update_swing_horizontal(const std::string &swing);
void update_swing_vertical(const std::string &swing);
std::string vertical_swing_state_;
std::string horizontal_swing_state_;
// Allow the HeatPump class to use get_hw_serial_
friend class HeatPump;
@ -131,6 +141,15 @@ class MitsubishiHeatPump : public esphome::PollingComponent, public esphome::cli
static void save(float value, esphome::ESPPreferenceObject& storage);
static esphome::optional<float> load(esphome::ESPPreferenceObject& storage);
select::Select *vertical_vane_select_ =
nullptr; // Select to store manual position of vertical swing
select::Select *horizontal_vane_select_ =
nullptr; // Select to store manual position of horizontal swing
// When received command to change the vane positions
void on_horizontal_swing_change(const std::string &swing);
void on_vertical_swing_change(const std::string &swing);
private:
// Retrieve the HardwareSerial pointer from friend and subclasses.
HardwareSerial *hw_serial_;

View File

@ -0,0 +1,15 @@
#pragma once
#include "esphome/components/select/select.h"
#include "esphome/core/component.h"
namespace esphome {
class MitsubishiACSelect : public select::Select, public Component {
protected:
void control(const std::string &value) override {
this->publish_state(value);
}
};
} // namespace esphome