Files
esphome-lsm6ds/esphome/components/mitsubishi_cn105/mitsubishi_cn105_climate.cpp
T

160 lines
5.1 KiB
C++

#include <cinttypes>
#include "mitsubishi_cn105_climate.h"
#include "esphome/core/log.h"
namespace esphome::mitsubishi_cn105 {
static const char *const TAG = "mitsubishi_cn105.climate";
static constexpr std::array MODE_MAP{
std::pair{MitsubishiCN105::Mode::AUTO, climate::CLIMATE_MODE_AUTO},
std::pair{MitsubishiCN105::Mode::HEAT, climate::CLIMATE_MODE_HEAT},
std::pair{MitsubishiCN105::Mode::DRY, climate::CLIMATE_MODE_DRY},
std::pair{MitsubishiCN105::Mode::COOL, climate::CLIMATE_MODE_COOL},
std::pair{MitsubishiCN105::Mode::FAN_ONLY, climate::CLIMATE_MODE_FAN_ONLY},
};
static constexpr std::array FAN_MODE_MAP{
std::pair{MitsubishiCN105::FanMode::AUTO, climate::CLIMATE_FAN_AUTO},
std::pair{MitsubishiCN105::FanMode::QUIET, climate::CLIMATE_FAN_QUIET},
std::pair{MitsubishiCN105::FanMode::SPEED_1, climate::CLIMATE_FAN_LOW},
std::pair{MitsubishiCN105::FanMode::SPEED_2, climate::CLIMATE_FAN_MEDIUM},
std::pair{MitsubishiCN105::FanMode::SPEED_3, climate::CLIMATE_FAN_MIDDLE},
std::pair{MitsubishiCN105::FanMode::SPEED_4, climate::CLIMATE_FAN_HIGH},
};
template<typename A, typename B, std::size_t N>
static bool map_lookup(const std::array<std::pair<A, B>, N> &map, A key, B &out) {
for (const auto &[from, to] : map) {
if (from == key) {
out = to;
return true;
}
}
return false;
}
template<typename Left, typename Right, std::size_t N>
static constexpr std::optional<Left> reverse_map_lookup(const std::array<std::pair<Left, Right>, N> &map, Right key) {
for (const auto &entry : map) {
if (entry.second == key) {
return entry.first;
}
}
return std::nullopt;
}
template<typename Left, typename Right, std::size_t N>
static constexpr std::optional<Left> reverse_map_lookup(const std::array<std::pair<Left, Right>, N> &map,
const std::optional<Right> &key) {
return key.has_value() ? reverse_map_lookup(map, *key) : std::nullopt;
}
void MitsubishiCN105Climate::dump_config() {
LOG_CLIMATE("", "Mitsubishi CN105 Climate", this);
if (this->hp_.is_room_temperature_enabled()) {
ESP_LOGCONFIG(TAG, " Current temperature min interval: %" PRIu32 " ms",
this->hp_.get_room_temperature_min_interval());
} else {
ESP_LOGCONFIG(TAG, " Current temperature: disabled");
}
ESP_LOGCONFIG(TAG,
" Update interval: %" PRIu32 " ms\n"
" UART: baud_rate=%" PRIu32 " data_bits=%u parity=%s stop_bits=%u",
this->hp_.get_update_interval(), this->parent_->get_baud_rate(), this->parent_->get_data_bits(),
LOG_STR_ARG(parity_to_str(this->parent_->get_parity())), this->parent_->get_stop_bits());
}
void MitsubishiCN105Climate::setup() { this->hp_.initialize(); }
void MitsubishiCN105Climate::loop() {
if (this->hp_.update()) {
this->apply_values_();
}
}
climate::ClimateTraits MitsubishiCN105Climate::traits() {
climate::ClimateTraits traits;
traits.set_supported_modes({
climate::CLIMATE_MODE_OFF,
climate::CLIMATE_MODE_COOL,
climate::CLIMATE_MODE_HEAT,
climate::CLIMATE_MODE_DRY,
climate::CLIMATE_MODE_FAN_ONLY,
climate::CLIMATE_MODE_AUTO,
});
traits.set_supported_fan_modes({
climate::CLIMATE_FAN_AUTO,
climate::CLIMATE_FAN_QUIET,
climate::CLIMATE_FAN_LOW,
climate::CLIMATE_FAN_MEDIUM,
climate::CLIMATE_FAN_MIDDLE,
climate::CLIMATE_FAN_HIGH,
});
traits.set_visual_min_temperature(16.0f);
traits.set_visual_max_temperature(31.0f);
traits.set_visual_temperature_step(1.0f);
if (this->hp_.is_room_temperature_enabled()) {
traits.add_feature_flags(climate::CLIMATE_SUPPORTS_CURRENT_TEMPERATURE);
traits.set_visual_current_temperature_step(0.5f);
}
return traits;
}
void MitsubishiCN105Climate::control(const climate::ClimateCall &call) {
if (const auto target_temperature = call.get_target_temperature()) {
this->hp_.set_target_temperature(*target_temperature);
}
if (const auto mode = call.get_mode()) {
if (*mode == climate::CLIMATE_MODE_OFF) {
this->hp_.set_power(false);
} else if (const auto mapped = reverse_map_lookup(MODE_MAP, *mode)) {
this->hp_.set_power(true);
this->hp_.set_mode(*mapped);
}
}
if (const auto fan_mode = reverse_map_lookup(FAN_MODE_MAP, call.get_fan_mode())) {
this->hp_.set_fan_mode(*fan_mode);
}
if (this->hp_.is_status_initialized()) {
this->apply_values_();
}
}
void MitsubishiCN105Climate::apply_values_() {
const auto &status = this->hp_.status();
this->target_temperature = status.target_temperature;
if (this->hp_.is_room_temperature_enabled()) {
this->current_temperature = status.room_temperature;
}
if (status.power_on) {
if (!map_lookup(MODE_MAP, status.mode, this->mode)) {
ESP_LOGD(TAG, "Unable to map mode");
}
} else {
this->mode = climate::CLIMATE_MODE_OFF;
}
climate::ClimateFanMode fan_mode;
if (map_lookup(FAN_MODE_MAP, status.fan_mode, fan_mode)) {
this->fan_mode = fan_mode;
} else {
ESP_LOGD(TAG, "Unable to map fan mode");
}
this->publish_state();
}
} // namespace esphome::mitsubishi_cn105