mirror of
https://github.com/esphome/esphome.git
synced 2025-02-13 08:28:19 +00:00
158 lines
6.0 KiB
C++
158 lines
6.0 KiB
C++
#ifdef USE_ARDUINO
|
|
|
|
#include "esphome/core/log.h"
|
|
#include "air_conditioner.h"
|
|
#include "ac_adapter.h"
|
|
|
|
namespace esphome {
|
|
namespace midea {
|
|
namespace ac {
|
|
|
|
static void set_sensor(Sensor *sensor, float value) {
|
|
if (sensor != nullptr && (!sensor->has_state() || sensor->get_raw_state() != value))
|
|
sensor->publish_state(value);
|
|
}
|
|
|
|
template<typename T> void update_property(T &property, const T &value, bool &flag) {
|
|
if (property != value) {
|
|
property = value;
|
|
flag = true;
|
|
}
|
|
}
|
|
|
|
void AirConditioner::on_status_change() {
|
|
bool need_publish = false;
|
|
update_property(this->target_temperature, this->base_.getTargetTemp(), need_publish);
|
|
update_property(this->current_temperature, this->base_.getIndoorTemp(), need_publish);
|
|
auto mode = Converters::to_climate_mode(this->base_.getMode());
|
|
update_property(this->mode, mode, need_publish);
|
|
auto swing_mode = Converters::to_climate_swing_mode(this->base_.getSwingMode());
|
|
update_property(this->swing_mode, swing_mode, need_publish);
|
|
// Preset
|
|
auto preset = this->base_.getPreset();
|
|
if (Converters::is_custom_midea_preset(preset)) {
|
|
if (this->set_custom_preset_(Converters::to_custom_climate_preset(preset)))
|
|
need_publish = true;
|
|
} else if (this->set_preset_(Converters::to_climate_preset(preset))) {
|
|
need_publish = true;
|
|
}
|
|
// Fan mode
|
|
auto fan_mode = this->base_.getFanMode();
|
|
if (Converters::is_custom_midea_fan_mode(fan_mode)) {
|
|
if (this->set_custom_fan_mode_(Converters::to_custom_climate_fan_mode(fan_mode)))
|
|
need_publish = true;
|
|
} else if (this->set_fan_mode_(Converters::to_climate_fan_mode(fan_mode))) {
|
|
need_publish = true;
|
|
}
|
|
if (need_publish)
|
|
this->publish_state();
|
|
set_sensor(this->outdoor_sensor_, this->base_.getOutdoorTemp());
|
|
set_sensor(this->power_sensor_, this->base_.getPowerUsage());
|
|
set_sensor(this->humidity_sensor_, this->base_.getIndoorHum());
|
|
}
|
|
|
|
void AirConditioner::control(const ClimateCall &call) {
|
|
dudanov::midea::ac::Control ctrl{};
|
|
if (call.get_target_temperature().has_value())
|
|
ctrl.targetTemp = call.get_target_temperature().value();
|
|
if (call.get_swing_mode().has_value())
|
|
ctrl.swingMode = Converters::to_midea_swing_mode(call.get_swing_mode().value());
|
|
if (call.get_mode().has_value())
|
|
ctrl.mode = Converters::to_midea_mode(call.get_mode().value());
|
|
if (call.get_preset().has_value()) {
|
|
ctrl.preset = Converters::to_midea_preset(call.get_preset().value());
|
|
} else if (call.get_custom_preset().has_value()) {
|
|
ctrl.preset = Converters::to_midea_preset(call.get_custom_preset().value());
|
|
}
|
|
if (call.get_fan_mode().has_value()) {
|
|
ctrl.fanMode = Converters::to_midea_fan_mode(call.get_fan_mode().value());
|
|
} else if (call.get_custom_fan_mode().has_value()) {
|
|
ctrl.fanMode = Converters::to_midea_fan_mode(call.get_custom_fan_mode().value());
|
|
}
|
|
this->base_.control(ctrl);
|
|
}
|
|
|
|
ClimateTraits AirConditioner::traits() {
|
|
auto traits = ClimateTraits();
|
|
traits.set_supports_current_temperature(true);
|
|
traits.set_visual_min_temperature(17);
|
|
traits.set_visual_max_temperature(30);
|
|
traits.set_visual_temperature_step(0.5);
|
|
traits.set_supported_modes(this->supported_modes_);
|
|
traits.set_supported_swing_modes(this->supported_swing_modes_);
|
|
traits.set_supported_presets(this->supported_presets_);
|
|
traits.set_supported_custom_presets(this->supported_custom_presets_);
|
|
traits.set_supported_custom_fan_modes(this->supported_custom_fan_modes_);
|
|
/* + MINIMAL SET OF CAPABILITIES */
|
|
traits.add_supported_fan_mode(ClimateFanMode::CLIMATE_FAN_AUTO);
|
|
traits.add_supported_fan_mode(ClimateFanMode::CLIMATE_FAN_LOW);
|
|
traits.add_supported_fan_mode(ClimateFanMode::CLIMATE_FAN_MEDIUM);
|
|
traits.add_supported_fan_mode(ClimateFanMode::CLIMATE_FAN_HIGH);
|
|
if (this->base_.getAutoconfStatus() == dudanov::midea::AUTOCONF_OK)
|
|
Converters::to_climate_traits(traits, this->base_.getCapabilities());
|
|
if (!traits.get_supported_modes().empty())
|
|
traits.add_supported_mode(ClimateMode::CLIMATE_MODE_OFF);
|
|
if (!traits.get_supported_swing_modes().empty())
|
|
traits.add_supported_swing_mode(ClimateSwingMode::CLIMATE_SWING_OFF);
|
|
if (!traits.get_supported_presets().empty())
|
|
traits.add_supported_preset(ClimatePreset::CLIMATE_PRESET_NONE);
|
|
return traits;
|
|
}
|
|
|
|
void AirConditioner::dump_config() {
|
|
ESP_LOGCONFIG(Constants::TAG, "MideaDongle:");
|
|
ESP_LOGCONFIG(Constants::TAG, " [x] Period: %dms", this->base_.getPeriod());
|
|
ESP_LOGCONFIG(Constants::TAG, " [x] Response timeout: %dms", this->base_.getTimeout());
|
|
ESP_LOGCONFIG(Constants::TAG, " [x] Request attempts: %d", this->base_.getNumAttempts());
|
|
#ifdef USE_REMOTE_TRANSMITTER
|
|
ESP_LOGCONFIG(Constants::TAG, " [x] Using RemoteTransmitter");
|
|
#endif
|
|
if (this->base_.getAutoconfStatus() == dudanov::midea::AUTOCONF_OK) {
|
|
this->base_.getCapabilities().dump();
|
|
} else if (this->base_.getAutoconfStatus() == dudanov::midea::AUTOCONF_ERROR) {
|
|
ESP_LOGW(Constants::TAG,
|
|
"Failed to get 0xB5 capabilities report. Suggest to disable it in config and manually set your "
|
|
"appliance options.");
|
|
}
|
|
this->dump_traits_(Constants::TAG);
|
|
}
|
|
|
|
/* ACTIONS */
|
|
|
|
void AirConditioner::do_follow_me(float temperature, bool beeper) {
|
|
#ifdef USE_REMOTE_TRANSMITTER
|
|
IrFollowMeData data(static_cast<uint8_t>(lroundf(temperature)), beeper);
|
|
this->transmitter_.transmit(data);
|
|
#else
|
|
ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
|
|
#endif
|
|
}
|
|
|
|
void AirConditioner::do_swing_step() {
|
|
#ifdef USE_REMOTE_TRANSMITTER
|
|
IrSpecialData data(0x01);
|
|
this->transmitter_.transmit(data);
|
|
#else
|
|
ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
|
|
#endif
|
|
}
|
|
|
|
void AirConditioner::do_display_toggle() {
|
|
if (this->base_.getCapabilities().supportLightControl()) {
|
|
this->base_.displayToggle();
|
|
} else {
|
|
#ifdef USE_REMOTE_TRANSMITTER
|
|
IrSpecialData data(0x08);
|
|
this->transmitter_.transmit(data);
|
|
#else
|
|
ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
|
|
#endif
|
|
}
|
|
}
|
|
|
|
} // namespace ac
|
|
} // namespace midea
|
|
} // namespace esphome
|
|
|
|
#endif // USE_ARDUINO
|