ESPHome 2025.12.0-dev
Loading...
Searching...
No Matches
air_conditioner.cpp
Go to the documentation of this file.
1#ifdef USE_ARDUINO
2
4#include "esphome/core/log.h"
5#include "air_conditioner.h"
6#include "ac_adapter.h"
7#include <cmath>
8#include <cstdint>
9
10namespace esphome {
11namespace midea {
12namespace ac {
13
14static void set_sensor(Sensor *sensor, float value) {
15 if (sensor != nullptr && (!sensor->has_state() || sensor->get_raw_state() != value))
16 sensor->publish_state(value);
17}
18
19template<typename T> void update_property(T &property, const T &value, bool &flag) {
20 if (property != value) {
21 property = value;
22 flag = true;
23 }
24}
25
27 bool need_publish = false;
28 update_property(this->target_temperature, this->base_.getTargetTemp(), need_publish);
29 update_property(this->current_temperature, this->base_.getIndoorTemp(), need_publish);
30 auto mode = Converters::to_climate_mode(this->base_.getMode());
31 update_property(this->mode, mode, need_publish);
32 auto swing_mode = Converters::to_climate_swing_mode(this->base_.getSwingMode());
33 update_property(this->swing_mode, swing_mode, need_publish);
34 // Preset
35 auto preset = this->base_.getPreset();
38 need_publish = true;
40 need_publish = true;
41 }
42 // Fan mode
43 auto fan_mode = this->base_.getFanMode();
46 need_publish = true;
48 need_publish = true;
49 }
50 if (need_publish)
51 this->publish_state();
52 set_sensor(this->outdoor_sensor_, this->base_.getOutdoorTemp());
53 set_sensor(this->power_sensor_, this->base_.getPowerUsage());
54 set_sensor(this->humidity_sensor_, this->base_.getIndoorHum());
55}
56
58 dudanov::midea::ac::Control ctrl{};
59 if (call.get_target_temperature().has_value())
60 ctrl.targetTemp = call.get_target_temperature().value();
61 if (call.get_swing_mode().has_value())
62 ctrl.swingMode = Converters::to_midea_swing_mode(call.get_swing_mode().value());
63 if (call.get_mode().has_value())
64 ctrl.mode = Converters::to_midea_mode(call.get_mode().value());
65 if (call.get_preset().has_value()) {
66 ctrl.preset = Converters::to_midea_preset(call.get_preset().value());
67 } else if (call.has_custom_preset()) {
68 ctrl.preset = Converters::to_midea_preset(call.get_custom_preset());
69 }
70 if (call.get_fan_mode().has_value()) {
71 ctrl.fanMode = Converters::to_midea_fan_mode(call.get_fan_mode().value());
72 } else if (call.has_custom_fan_mode()) {
73 ctrl.fanMode = Converters::to_midea_fan_mode(call.get_custom_fan_mode());
74 }
75 this->base_.control(ctrl);
76}
77
79 auto traits = ClimateTraits();
87 if (!this->supported_custom_presets_.empty())
89 if (!this->supported_custom_fan_modes_.empty())
91 /* + MINIMAL SET OF CAPABILITIES */
96 if (this->base_.getAutoconfStatus() == dudanov::midea::AUTOCONF_OK)
97 Converters::to_climate_traits(traits, this->base_.getCapabilities());
104 return traits;
105}
106
108 ESP_LOGCONFIG(Constants::TAG,
109 "MideaDongle:\n"
110 " [x] Period: %dms\n"
111 " [x] Response timeout: %dms\n"
112 " [x] Request attempts: %d",
113 this->base_.getPeriod(), this->base_.getTimeout(), this->base_.getNumAttempts());
114#ifdef USE_REMOTE_TRANSMITTER
115 ESP_LOGCONFIG(Constants::TAG, " [x] Using RemoteTransmitter");
116#endif
117 if (this->base_.getAutoconfStatus() == dudanov::midea::AUTOCONF_OK) {
118 this->base_.getCapabilities().dump();
119 } else if (this->base_.getAutoconfStatus() == dudanov::midea::AUTOCONF_ERROR) {
120 ESP_LOGW(Constants::TAG,
121 "Failed to get 0xB5 capabilities report. Suggest to disable it in config and manually set your "
122 "appliance options.");
123 }
125}
126
127/* ACTIONS */
128
129void AirConditioner::do_follow_me(float temperature, bool use_fahrenheit, bool beeper) {
130#ifdef USE_REMOTE_TRANSMITTER
131 // Check if temperature is finite (not NaN or infinite)
132 if (!std::isfinite(temperature)) {
133 ESP_LOGW(Constants::TAG, "Follow me action requires a finite temperature, got: %f", temperature);
134 return;
135 }
136
137 // Round and convert temperature to long, then clamp and convert it to uint8_t
138 uint8_t temp_uint8 =
139 static_cast<uint8_t>(esphome::clamp<long>(std::lroundf(temperature), 0L, static_cast<long>(UINT8_MAX)));
140
141 char temp_symbol = use_fahrenheit ? 'F' : 'C';
142 ESP_LOGD(Constants::TAG, "Follow me action called with temperature: %.5f °%c, rounded to: %u °%c", temperature,
143 temp_symbol, temp_uint8, temp_symbol);
144
145 // Create and transmit the data
146 IrFollowMeData data(temp_uint8, use_fahrenheit, beeper);
147 this->transmitter_.transmit(data);
148#else
149 ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
150#endif
151}
152
154#ifdef USE_REMOTE_TRANSMITTER
155 IrSpecialData data(0x01);
156 this->transmitter_.transmit(data);
157#else
158 ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
159#endif
160}
161
163 if (this->base_.getCapabilities().supportLightControl()) {
164 this->base_.displayToggle();
165 } else {
166#ifdef USE_REMOTE_TRANSMITTER
167 IrSpecialData data(0x08);
168 this->transmitter_.transmit(data);
169#else
170 ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
171#endif
172 }
173}
174
175} // namespace ac
176} // namespace midea
177} // namespace esphome
178
179#endif // USE_ARDUINO
constexpr bool empty() const
Check if the set is empty.
This class is used to encode all control actions on a climate device.
Definition climate.h:33
ClimateMode mode
The active mode of the climate device.
Definition climate.h:256
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
Definition climate.h:250
float target_temperature
The target temperature of the climate device.
Definition climate.h:237
void dump_traits_(const char *tag)
Definition climate.cpp:696
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition climate.h:262
bool set_preset_(ClimatePreset preset)
Set preset. Reset custom preset. Return true if preset has been changed.
Definition climate.cpp:678
bool set_custom_preset_(const char *preset)
Set custom preset. Reset primary preset. Return true if preset has been changed.
Definition climate.cpp:680
bool set_fan_mode_(ClimateFanMode mode)
Set fan mode. Reset custom fan mode. Return true if fan mode has been changed.
Definition climate.cpp:666
float current_temperature
The current temperature of the climate device, as reported from the integration.
Definition climate.h:230
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition climate.cpp:426
optional< ClimatePreset > preset
The active preset of the climate device.
Definition climate.h:253
bool set_custom_fan_mode_(const char *mode)
Set custom fan mode. Reset primary fan mode. Return true if fan mode has been changed.
Definition climate.cpp:670
void set_visual_max_temperature(float visual_max_temperature)
void add_feature_flags(uint32_t feature_flags)
void add_supported_fan_mode(ClimateFanMode mode)
const ClimatePresetMask & get_supported_presets() const
const ClimateSwingModeMask & get_supported_swing_modes() const
void set_visual_temperature_step(float temperature_step)
void add_supported_preset(ClimatePreset preset)
void set_supported_presets(ClimatePresetMask presets)
void set_supported_swing_modes(ClimateSwingModeMask modes)
void set_visual_min_temperature(float visual_min_temperature)
void set_supported_modes(ClimateModeMask modes)
void add_supported_mode(ClimateMode mode)
void set_supported_custom_fan_modes(std::initializer_list< const char * > modes)
void set_supported_custom_presets(std::initializer_list< const char * > presets)
const ClimateModeMask & get_supported_modes() const
void add_supported_swing_mode(ClimateSwingMode mode)
std::vector< const char * > supported_custom_presets_
std::vector< const char * > supported_custom_fan_modes_
void do_follow_me(float temperature, bool use_fahrenheit, bool beeper=false)
ClimateSwingModeMask supported_swing_modes_
void control(const ClimateCall &call) override
static const char *const TAG
Definition ac_adapter.h:22
static ClimateFanMode to_climate_fan_mode(MideaFanMode fan_mode)
static ClimateSwingMode to_climate_swing_mode(MideaSwingMode mode)
static MideaSwingMode to_midea_swing_mode(ClimateSwingMode mode)
static MideaPreset to_midea_preset(ClimatePreset preset)
static const char * to_custom_climate_preset(MideaPreset preset)
static ClimateMode to_climate_mode(MideaMode mode)
static MideaFanMode to_midea_fan_mode(ClimateFanMode fan_mode)
static ClimatePreset to_climate_preset(MideaPreset preset)
static bool is_custom_midea_fan_mode(MideaFanMode fan_mode)
static const char * to_custom_climate_fan_mode(MideaFanMode fan_mode)
static bool is_custom_midea_preset(MideaPreset preset)
static MideaMode to_midea_mode(ClimateMode mode)
static void to_climate_traits(ClimateTraits &traits, const dudanov::midea::ac::Capabilities &capabilities)
@ CLIMATE_SUPPORTS_CURRENT_TEMPERATURE
@ CLIMATE_PRESET_NONE
No preset is active.
@ CLIMATE_SWING_OFF
The swing mode is set to Off.
@ CLIMATE_MODE_OFF
The climate device is off.
@ CLIMATE_FAN_MEDIUM
The fan mode is set to Medium.
@ CLIMATE_FAN_AUTO
The fan mode is set to Auto.
@ CLIMATE_FAN_LOW
The fan mode is set to Low.
@ CLIMATE_FAN_HIGH
The fan mode is set to High.
void update_property(T &property, const T &value, bool &flag)
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
uint16_t temperature
Definition sun_gtil2.cpp:12