ESPHome  2024.12.2
midea_ir.cpp
Go to the documentation of this file.
1 #include "midea_ir.h"
2 #include "midea_data.h"
3 #include "esphome/core/log.h"
4 #include "esphome/core/helpers.h"
6 
7 namespace esphome {
8 namespace midea_ir {
9 
10 static const char *const TAG = "midea_ir.climate";
11 
12 void ControlData::set_temp(float temp) {
13  uint8_t min;
14  if (this->get_fahrenheit()) {
15  min = MIDEA_TEMPF_MIN;
16  temp = esphome::clamp<float>(celsius_to_fahrenheit(temp), MIDEA_TEMPF_MIN, MIDEA_TEMPF_MAX);
17  } else {
18  min = MIDEA_TEMPC_MIN;
19  temp = esphome::clamp<float>(temp, MIDEA_TEMPC_MIN, MIDEA_TEMPC_MAX);
20  }
21  this->set_value_(2, lroundf(temp) - min, 31);
22 }
23 
24 float ControlData::get_temp() const {
25  const uint8_t temp = this->get_value_(2, 31);
26  if (this->get_fahrenheit())
27  return fahrenheit_to_celsius(static_cast<float>(temp + MIDEA_TEMPF_MIN));
28  return static_cast<float>(temp + MIDEA_TEMPC_MIN);
29 }
30 
32  // In FAN_AUTO, modes COOL, HEAT and FAN_ONLY bit #5 in byte #1 must be set
33  const uint8_t value = this->get_value_(1, 31);
34  if (value == 0 || value == 3 || value == 4)
35  this->set_mask_(1, true, 32);
36  // In FAN_ONLY mode we need to set all temperature bits
37  if (this->get_mode_() == MODE_FAN_ONLY)
38  this->set_mask_(2, true, 31);
39 }
40 
42  switch (mode) {
44  this->set_power_(false);
45  return;
47  this->set_mode_(MODE_COOL);
48  break;
50  this->set_mode_(MODE_DRY);
51  break;
53  this->set_mode_(MODE_FAN_ONLY);
54  break;
56  this->set_mode_(MODE_HEAT);
57  break;
58  default:
59  this->set_mode_(MODE_AUTO);
60  break;
61  }
62  this->set_power_(true);
63 }
64 
66  if (!this->get_power_())
68  switch (this->get_mode_()) {
69  case MODE_COOL:
71  case MODE_DRY:
73  case MODE_FAN_ONLY:
75  case MODE_HEAT:
77  default:
79  }
80 }
81 
83  switch (mode) {
85  this->set_fan_mode_(FAN_LOW);
86  break;
89  break;
91  this->set_fan_mode_(FAN_HIGH);
92  break;
93  default:
94  this->set_fan_mode_(FAN_AUTO);
95  break;
96  }
97 }
98 
100  switch (this->get_fan_mode_()) {
101  case FAN_LOW:
103  case FAN_MEDIUM:
105  case FAN_HIGH:
107  default:
109  }
110 }
111 
113  // swing and preset resets after unit powered off
114  if (call.get_mode() == climate::CLIMATE_MODE_OFF) {
117  } else if (call.get_swing_mode().has_value() && ((*call.get_swing_mode() == climate::CLIMATE_SWING_OFF &&
120  this->swing_mode == climate::CLIMATE_SWING_OFF))) {
121  this->swing_ = true;
122  } else if (call.get_preset().has_value() &&
124  (*call.get_preset() == climate::CLIMATE_PRESET_BOOST && this->preset == climate::CLIMATE_PRESET_NONE))) {
125  this->boost_ = true;
126  }
128 }
129 
131  data.finalize();
132  auto transmit = this->transmitter_->transmit();
133  remote_base::MideaProtocol().encode(transmit.get_data(), data);
134  transmit.perform();
135 }
136 
138  if (this->swing_) {
140  this->transmit_(data);
141  this->swing_ = false;
142  return;
143  }
144  if (this->boost_) {
146  this->transmit_(data);
147  this->boost_ = false;
148  return;
149  }
151  data.set_fahrenheit(this->fahrenheit_);
152  data.set_temp(this->target_temperature);
153  data.set_mode(this->mode);
156  data.fix();
157  this->transmit_(data);
158 }
159 
161  auto midea = remote_base::MideaProtocol().decode(data);
162  if (midea.has_value())
163  return this->on_midea_(*midea);
164  return coolix::CoolixClimate::on_coolix(this, data);
165 }
166 
168  ESP_LOGV(TAG, "Decoded Midea IR data: %s", data.to_string().c_str());
169  if (data.type() == MideaData::MIDEA_TYPE_CONTROL) {
170  const ControlData status = data;
172  this->target_temperature = status.get_temp();
173  this->mode = status.get_mode();
174  this->fan_mode = status.get_fan_mode();
175  if (status.get_sleep_preset()) {
177  } else if (this->preset == climate::CLIMATE_PRESET_SLEEP) {
179  }
180  this->publish_state();
181  return true;
182  }
183  if (data.type() == MideaData::MIDEA_TYPE_SPECIAL) {
184  switch (data[1]) {
188  break;
192  break;
193  }
194  this->publish_state();
195  return true;
196  }
197 
198  return false;
199 }
200 
201 } // namespace midea_ir
202 } // namespace esphome
This class is used to encode all control actions on a climate device.
Definition: climate.h:33
void transmit_state() override
Transmit via IR the state of this climate controller.
Definition: midea_ir.cpp:137
MideaDataType type() const
FanMode get_fan_mode_() const
Definition: midea_data.h:52
const uint8_t MIDEA_TEMPF_MIN
Definition: midea_ir.h:12
static const uint8_t TURBO_TOGGLE
Definition: midea_data.h:88
const optional< ClimateMode > & get_mode() const
Definition: climate.cpp:273
const uint8_t MIDEA_TEMPC_MAX
Definition: midea_ir.h:11
void set_power_(bool value)
Definition: midea_data.h:55
void control(const climate::ClimateCall &call) override
Override control to change settings of the climate device.
Definition: midea_ir.cpp:112
void encode(RemoteTransmitData *dst, const MideaData &src) override
bool has_value() const
Definition: optional.h:87
void set_sleep_preset(bool value)
Definition: midea_data.h:29
void control(const climate::ClimateCall &call) override
Override control to change settings of the climate device.
Definition: climate_ir.cpp:61
void set_value_(uint8_t idx, uint8_t value, uint8_t mask=255, uint8_t shift=0)
ClimateSwingMode swing_mode
Definition: climate.h:581
Device is prepared for sleep.
Definition: climate_mode.h:96
void set_fahrenheit(bool value)
Definition: midea_data.h:32
void transmit_(MideaData &data)
Definition: midea_ir.cpp:130
constexpr float celsius_to_fahrenheit(float value)
Convert degrees Celsius to degrees Fahrenheit.
Definition: helpers.h:474
const optional< ClimatePreset > & get_preset() const
Definition: climate.cpp:280
static bool on_coolix(climate::Climate *parent, remote_base::RemoteReceiveData data)
This static method can be used in other climate components that accept the Coolix protocol...
Definition: coolix.cpp:108
BedjetMode mode
BedJet operating mode.
Definition: bedjet_codec.h:183
uint8_t get_value_(uint8_t idx, uint8_t mask=255, uint8_t shift=0) const
static const uint8_t VSWING_TOGGLE
Definition: midea_data.h:87
The fan mode is set to Vertical.
Definition: climate_mode.h:76
std::string to_string() const
The swing mode is set to Off.
Definition: climate_mode.h:72
The climate device is off.
Definition: climate_mode.h:12
ClimateFanMode fan_mode
Definition: climate.h:573
optional< MideaData > decode(RemoteReceiveData src) override
uint8_t status
Definition: bl0942.h:74
Device is in boost preset.
Definition: climate_mode.h:90
void set_temp(float temp)
Definition: midea_ir.cpp:12
void set_mask_(uint8_t idx, bool state, uint8_t mask=255)
const optional< ClimateSwingMode > & get_swing_mode() const
Definition: climate.cpp:282
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void set_fan_mode(ClimateFanMode mode)
Definition: midea_ir.cpp:82
void set_mode(ClimateMode mode)
Definition: midea_ir.cpp:41
const uint8_t MIDEA_TEMPC_MIN
Definition: midea_ir.h:10
constexpr float fahrenheit_to_celsius(float value)
Convert degrees Fahrenheit to degrees Celsius.
Definition: helpers.h:476
The climate device only has the fan enabled, no heating or cooling is taking place.
Definition: climate_mode.h:20
bool on_midea_(const MideaData &data)
Definition: midea_ir.cpp:167
float target_temperature
Definition: climate.h:138
const uint8_t MIDEA_TEMPF_MAX
Definition: midea_ir.h:13
bool on_receive(remote_base::RemoteReceiveData data) override
Handle received IR Buffer.
Definition: midea_ir.cpp:160
ClimateMode get_mode() const
Definition: midea_ir.cpp:65
ClimatePreset preset
Definition: climate.h:578
void set_fan_mode_(FanMode mode)
Definition: midea_data.h:51
ClimateFanMode get_fan_mode() const
Definition: midea_ir.cpp:99