mirror of
https://github.com/geoffdavis/esphome-mitsubishiheatpump
synced 2024-08-30 18:12:13 +00:00
Merge pull request #109 from nathanjw/unformat-select
Add vertical and horizontal vane position controls
This commit is contained in:
commit
2ac56d5a8e
16
README.md
16
README.md
@ -42,6 +42,8 @@ tested by the author on the following units:
|
||||
|
||||
* `MSZ-GL06NA`
|
||||
* `MFZ-KA09NA`
|
||||
* `MSZ-FH35V`
|
||||
* `MSZ-LN35VG2W`
|
||||
|
||||
## Usage
|
||||
|
||||
@ -240,6 +242,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.
|
||||
@ -327,6 +334,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.
|
||||
@ -350,8 +362,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
|
||||
@ -397,6 +408,7 @@ climate:
|
||||
request wasn't received from your ESPHome controller. This will result
|
||||
in the heatpump reverting to it's internal temperature sensor if the heatpump
|
||||
loses it's WiFi connection.
|
||||
equest.)
|
||||
|
||||
## Other configuration
|
||||
|
||||
|
@ -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,12 +15,24 @@ 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"]
|
||||
HORIZONTAL_SWING_OPTIONS = [
|
||||
"auto",
|
||||
"swing",
|
||||
"left",
|
||||
"left_center",
|
||||
"center",
|
||||
"right_center",
|
||||
"right",
|
||||
]
|
||||
VERTICAL_SWING_OPTIONS = ["swing", "auto", "up", "up_center", "center", "down_center", "down"]
|
||||
|
||||
# Remote temperature timeout configuration
|
||||
CONF_REMOTE_OPERATING_TIMEOUT = "remote_temperature_operating_timeout_minutes"
|
||||
@ -31,6 +43,9 @@ 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:
|
||||
@ -43,6 +58,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),
|
||||
@ -58,6 +77,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(
|
||||
{
|
||||
@ -113,6 +135,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(
|
||||
|
@ -111,6 +111,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.
|
||||
*
|
||||
@ -264,10 +375,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:
|
||||
@ -370,15 +493,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 ********
|
||||
@ -525,6 +685,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(
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define USE_CALLBACKS
|
||||
|
||||
#include "esphome.h"
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
#include <chrono>
|
||||
|
||||
@ -100,6 +101,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(esphome::select::Select *vertical_vane_select);
|
||||
void set_horizontal_vane_select(esphome::select::Select *horizontal_vane_select);
|
||||
|
||||
// Used to validate that a connection is present between the controller
|
||||
// and this heatpump.
|
||||
void ping();
|
||||
@ -123,6 +127,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;
|
||||
|
||||
@ -148,6 +158,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);
|
||||
|
||||
esphome::select::Select *vertical_vane_select_ =
|
||||
nullptr; // Select to store manual position of vertical swing
|
||||
esphome::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);
|
||||
|
||||
static void log_packet(byte* packet, unsigned int length, char* packetDirection);
|
||||
|
||||
private:
|
||||
|
15
components/mitsubishi_heatpump/mitsubishi_ac_select.h
Normal file
15
components/mitsubishi_heatpump/mitsubishi_ac_select.h
Normal 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
|
Loading…
Reference in New Issue
Block a user