ESPHome  2024.12.2
air_conditioner.cpp
Go to the documentation of this file.
1 #ifdef USE_ARDUINO
2 
3 #include "esphome/core/log.h"
4 #include "air_conditioner.h"
5 #include "ac_adapter.h"
6 #include <cmath>
7 #include <cstdint>
8 
9 namespace esphome {
10 namespace midea {
11 namespace ac {
12 
13 static void set_sensor(Sensor *sensor, float value) {
14  if (sensor != nullptr && (!sensor->has_state() || sensor->get_raw_state() != value))
15  sensor->publish_state(value);
16 }
17 
18 template<typename T> void update_property(T &property, const T &value, bool &flag) {
19  if (property != value) {
20  property = value;
21  flag = true;
22  }
23 }
24 
26  bool need_publish = false;
27  update_property(this->target_temperature, this->base_.getTargetTemp(), need_publish);
28  update_property(this->current_temperature, this->base_.getIndoorTemp(), need_publish);
29  auto mode = Converters::to_climate_mode(this->base_.getMode());
30  update_property(this->mode, mode, need_publish);
31  auto swing_mode = Converters::to_climate_swing_mode(this->base_.getSwingMode());
32  update_property(this->swing_mode, swing_mode, need_publish);
33  // Preset
34  auto preset = this->base_.getPreset();
37  need_publish = true;
39  need_publish = true;
40  }
41  // Fan mode
42  auto fan_mode = this->base_.getFanMode();
45  need_publish = true;
47  need_publish = true;
48  }
49  if (need_publish)
50  this->publish_state();
51  set_sensor(this->outdoor_sensor_, this->base_.getOutdoorTemp());
52  set_sensor(this->power_sensor_, this->base_.getPowerUsage());
53  set_sensor(this->humidity_sensor_, this->base_.getIndoorHum());
54 }
55 
57  dudanov::midea::ac::Control ctrl{};
58  if (call.get_target_temperature().has_value())
59  ctrl.targetTemp = call.get_target_temperature().value();
60  if (call.get_swing_mode().has_value())
61  ctrl.swingMode = Converters::to_midea_swing_mode(call.get_swing_mode().value());
62  if (call.get_mode().has_value())
63  ctrl.mode = Converters::to_midea_mode(call.get_mode().value());
64  if (call.get_preset().has_value()) {
65  ctrl.preset = Converters::to_midea_preset(call.get_preset().value());
66  } else if (call.get_custom_preset().has_value()) {
67  ctrl.preset = Converters::to_midea_preset(call.get_custom_preset().value());
68  }
69  if (call.get_fan_mode().has_value()) {
70  ctrl.fanMode = Converters::to_midea_fan_mode(call.get_fan_mode().value());
71  } else if (call.get_custom_fan_mode().has_value()) {
73  }
74  this->base_.control(ctrl);
75 }
76 
78  auto traits = ClimateTraits();
88  /* + MINIMAL SET OF CAPABILITIES */
93  if (this->base_.getAutoconfStatus() == dudanov::midea::AUTOCONF_OK)
94  Converters::to_climate_traits(traits, this->base_.getCapabilities());
95  if (!traits.get_supported_modes().empty())
97  if (!traits.get_supported_swing_modes().empty())
99  if (!traits.get_supported_presets().empty())
101  return traits;
102 }
103 
105  ESP_LOGCONFIG(Constants::TAG, "MideaDongle:");
106  ESP_LOGCONFIG(Constants::TAG, " [x] Period: %dms", this->base_.getPeriod());
107  ESP_LOGCONFIG(Constants::TAG, " [x] Response timeout: %dms", this->base_.getTimeout());
108  ESP_LOGCONFIG(Constants::TAG, " [x] Request attempts: %d", this->base_.getNumAttempts());
109 #ifdef USE_REMOTE_TRANSMITTER
110  ESP_LOGCONFIG(Constants::TAG, " [x] Using RemoteTransmitter");
111 #endif
112  if (this->base_.getAutoconfStatus() == dudanov::midea::AUTOCONF_OK) {
113  this->base_.getCapabilities().dump();
114  } else if (this->base_.getAutoconfStatus() == dudanov::midea::AUTOCONF_ERROR) {
115  ESP_LOGW(Constants::TAG,
116  "Failed to get 0xB5 capabilities report. Suggest to disable it in config and manually set your "
117  "appliance options.");
118  }
120 }
121 
122 /* ACTIONS */
123 
124 void AirConditioner::do_follow_me(float temperature, bool beeper) {
125 #ifdef USE_REMOTE_TRANSMITTER
126  // Check if temperature is finite (not NaN or infinite)
127  if (!std::isfinite(temperature)) {
128  ESP_LOGW(Constants::TAG, "Follow me action requires a finite temperature, got: %f", temperature);
129  return;
130  }
131 
132  // Round and convert temperature to long, then clamp and convert it to uint8_t
133  uint8_t temp_uint8 =
134  static_cast<uint8_t>(std::max(0L, std::min(static_cast<long>(UINT8_MAX), std::lroundf(temperature))));
135 
136  ESP_LOGD(Constants::TAG, "Follow me action called with temperature: %f °C, rounded to: %u °C", temperature,
137  temp_uint8);
138 
139  // Create and transmit the data
140  IrFollowMeData data(temp_uint8, beeper);
141  this->transmitter_.transmit(data);
142 #else
143  ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
144 #endif
145 }
146 
148 #ifdef USE_REMOTE_TRANSMITTER
149  IrSpecialData data(0x01);
150  this->transmitter_.transmit(data);
151 #else
152  ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
153 #endif
154 }
155 
157  if (this->base_.getCapabilities().supportLightControl()) {
158  this->base_.displayToggle();
159  } else {
160 #ifdef USE_REMOTE_TRANSMITTER
161  IrSpecialData data(0x08);
162  this->transmitter_.transmit(data);
163 #else
164  ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
165 #endif
166  }
167 }
168 
169 } // namespace ac
170 } // namespace midea
171 } // namespace esphome
172 
173 #endif // USE_ARDUINO
This class is used to encode all control actions on a climate device.
Definition: climate.h:33
value_type const & value() const
Definition: optional.h:89
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition: climate.h:202
static ClimateFanMode to_climate_fan_mode(MideaFanMode fan_mode)
Definition: ac_adapter.cpp:88
static const char *const TAG
Definition: ac_adapter.h:22
void set_supported_custom_presets(std::set< std::string > supported_custom_presets)
void set_visual_temperature_step(float temperature_step)
std::set< std::string > supported_custom_presets_
const std::set< ClimateSwingMode > & get_supported_swing_modes() const
float target_temperature
The target temperature of the climate device.
Definition: climate.h:186
static const std::string & to_custom_climate_fan_mode(MideaFanMode fan_mode)
Definition: ac_adapter.cpp:111
const optional< ClimateMode > & get_mode() const
Definition: climate.cpp:273
This class contains all static data for climate devices.
static bool is_custom_midea_fan_mode(MideaFanMode fan_mode)
Definition: ac_adapter.cpp:101
void set_visual_min_temperature(float visual_min_temperature)
void do_follow_me(float temperature, bool beeper=false)
ClimateMode mode
The active mode of the climate device.
Definition: climate.h:173
static void to_climate_traits(ClimateTraits &traits, const dudanov::midea::ac::Capabilities &capabilities)
Definition: ac_adapter.cpp:158
float current_temperature
The current temperature of the climate device, as reported from the integration.
Definition: climate.h:179
bool has_value() const
Definition: optional.h:87
void set_supported_presets(std::set< ClimatePreset > presets)
std::set< ClimateSwingMode > supported_swing_modes_
void add_supported_preset(ClimatePreset preset)
static MideaPreset to_midea_preset(ClimatePreset preset)
Definition: ac_adapter.cpp:126
std::set< ClimatePreset > supported_presets_
void add_supported_swing_mode(ClimateSwingMode mode)
void transmit(IrData &data)
const optional< std::string > & get_custom_preset() const
Definition: climate.cpp:281
const optional< ClimatePreset > & get_preset() const
Definition: climate.cpp:280
optional< ClimatePreset > preset
The active preset of the climate device.
Definition: climate.h:208
static const std::string & to_custom_climate_preset(MideaPreset preset)
Definition: ac_adapter.cpp:154
const std::set< ClimateMode > & get_supported_modes() const
const std::set< climate::ClimatePreset > & get_supported_presets() const
void set_supported_modes(std::set< ClimateMode > modes)
void control(const ClimateCall &call) override
std::set< std::string > supported_custom_fan_modes_
static bool is_custom_midea_preset(MideaPreset preset)
Definition: ac_adapter.cpp:152
uint16_t temperature
Definition: sun_gtil2.cpp:26
void set_visual_max_temperature(float visual_max_temperature)
const optional< std::string > & get_custom_fan_mode() const
Definition: climate.cpp:279
void add_supported_fan_mode(ClimateFanMode mode)
const optional< float > & get_target_temperature() const
Definition: climate.cpp:274
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition: climate.cpp:395
bool set_custom_fan_mode_(const std::string &mode)
Set custom fan mode. Reset primary fan mode. Return true if fan mode has been changed.
Definition: climate.cpp:559
static ClimatePreset to_climate_preset(MideaPreset preset)
Definition: ac_adapter.cpp:139
static ClimateSwingMode to_climate_swing_mode(MideaSwingMode mode)
Definition: ac_adapter.cpp:49
std::set< ClimateMode > supported_modes_
static MideaSwingMode to_midea_swing_mode(ClimateSwingMode mode)
Definition: ac_adapter.cpp:62
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
Definition: climate.h:199
const optional< ClimateFanMode > & get_fan_mode() const
Definition: climate.cpp:278
bool set_custom_preset_(const std::string &preset)
Set custom preset. Reset primary preset. Return true if preset has been changed.
Definition: climate.cpp:565
ClimateTraits traits() override
void update_property(T &property, const T &value, bool &flag)
static MideaMode to_midea_mode(ClimateMode mode)
Definition: ac_adapter.cpp:32
const optional< ClimateSwingMode > & get_swing_mode() const
Definition: climate.cpp:282
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void set_supported_swing_modes(std::set< ClimateSwingMode > modes)
void dump_traits_(const char *tag)
Definition: climate.cpp:569
static ClimateMode to_climate_mode(MideaMode mode)
Definition: ac_adapter.cpp:15
void set_supports_current_temperature(bool supports_current_temperature)
void set_supported_custom_fan_modes(std::set< std::string > supported_custom_fan_modes)
bool set_preset_(ClimatePreset preset)
Set preset. Reset custom preset. Return true if preset has been changed.
Definition: climate.cpp:563
void add_supported_mode(ClimateMode mode)
esphome::sensor::Sensor * sensor
Definition: statsd.h:38
bool set_fan_mode_(ClimateFanMode mode)
Set fan mode. Reset custom fan mode. Return true if fan mode has been changed.
Definition: climate.cpp:555
static MideaFanMode to_midea_fan_mode(ClimateFanMode fan_mode)
Definition: ac_adapter.cpp:75