11static constexpr uint32_t FOLLOWUP_TIMEOUT_ID = 0;
13static constexpr uint32_t STATUS_INTERVAL_MS = 30000;
14static constexpr uint32_t NETWORK_INTERVAL_MS = 10000;
15static constexpr uint32_t FOLLOWUP_DELAY_MS = 1500;
17static constexpr uint32_t RX_TIMEOUT_MS = 100;
20static constexpr size_t FRAME_OVERHEAD = 12;
21static constexpr size_t MAX_TX_PAYLOAD = 24;
23static constexpr float MIN_TARGET_TEMP = 16.0f;
24static constexpr float MAX_TARGET_TEMP = 30.0f;
29static constexpr uint8_t MODULE_FRAME[31] PROGMEM = {0xAA, 0x1E, 0xAC, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01,
30 0x01, 0x04, 0xC0, 0xA8, 0xB2, 0x72, 0x00, 0x00, 0x00, 0x01, 0x01,
31 0x01, 0x28, 0x09, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00};
32static constexpr uint8_t STATUS_QUERY[12] PROGMEM = {0x41, 0x21, 0x00, 0xFF, 0x03, 0xFF,
33 0x00, 0x02, 0x00, 0x00, 0x00, 0x00};
35static constexpr uint8_t CAPS_0[] PROGMEM = {0xB5, 0x01, 0x00};
36static constexpr uint8_t CAPS_1[]
PROGMEM = {0xB5, 0x01, 0x01, 0x01};
112 while ((n = std::min((
size_t) this->
available(),
sizeof(buf))) != 0 && this->
read_array(buf, n)) {
113 for (
size_t i = 0; i < n; i++)
123 ESP_LOGCONFIG(TAG,
"Midea PortaSplit:");
161 if (
call.get_mode().has_value()) {
171 const float target = clamp(*
call.get_target_temperature(), MIN_TARGET_TEMP, MAX_TARGET_TEMP);
174 if (
call.get_fan_mode().has_value())
175 this->
st_fan_ = fan_mode_to_midea(*
call.get_fan_mode());
176 if (
call.get_swing_mode().has_value())
178 if (
call.get_preset().has_value()) {
193 uint8_t f[FRAME_OVERHEAD + MAX_TX_PAYLOAD] = {0};
194 const size_t total = FRAME_OVERHEAD +
len;
196 f[1] = (uint8_t) (total - 1);
205#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
212 uint8_t p[MAX_TX_PAYLOAD] = {0};
219 p[2] = (uint8_t) ((this->
st_mode_ << 5) | (half ? 0x10 : 0x00) | ((whole - 16) & 0x0F));
226 p[9] = (uint8_t) ((this->
st_ion_ ? 0x20 : 0x00) | (this->
st_eco_ ? 0x80 : 0x00));
228 p[18] = (uint8_t) ((whole - 12) & 0x1F);
239 uint8_t p[
sizeof(STATUS_QUERY)];
246 this->
send_frame_(0x03, 0x03, CAPS_0,
sizeof(CAPS_0));
251 uint8_t f[
sizeof(MODULE_FRAME)];
261 if (this->
rx_len_ == 0 && b != 0xAA)
266 const size_t total = (size_t) this->
rx_[1] + 1;
268 if (this->
rx_len_ == 3 && (total < FRAME_OVERHEAD || total >
MAX_FRAME || this->
rx_[2] != 0xAC)) {
275 if (
checksum(this->
rx_.data(), total - 1) != this->rx_[total - 1]) {
276 ESP_LOGW(TAG,
"RX checksum mismatch, dropping frame");
279#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
289 }
else if (f[9] == 0x05 && f[10] == 0xB5) {
292 }
else if (f[10] == 0xC0) {
300 const uint8_t
mode = (f[12] >> 5) & 0x07;
301 const uint8_t target_half = (uint8_t) ((((f[12] & 0x0F) + 16) << 1) | ((f[12] & 0x10) ? 1 : 0));
308 this->
st_fan_ = fan_mode_to_midea(fan);
309 this->
st_swing_ = (f[17] & 0x0F) == 0x0C;
314 this->
st_frost_ = len > 31 && (f[31] & 0x80);
BedjetMode mode
BedJet operating mode.
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
void set_timeout(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a const char* name.
void set_interval(const char *name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a const char* name.
This class is used to encode all control actions on a climate device.
const optional< ClimateSwingMode > & get_swing_mode() const
const optional< float > & get_target_temperature() const
ClimateMode mode
The active mode of the climate device.
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
float target_temperature
The target temperature of the climate device.
void dump_traits_(const char *tag)
ClimateSwingMode swing_mode
The active swing mode of the climate device.
float current_temperature
The current temperature of the climate device, as reported from the integration.
void publish_state()
Publish the state of the climate device, to be called from integrations.
optional< ClimatePreset > preset
The active preset of the climate device.
void set_visual_max_temperature(float visual_max_temperature)
void add_feature_flags(uint32_t feature_flags)
void set_visual_temperature_step(float temperature_step)
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 set_supported_fan_modes(ClimateFanModeMask modes)
void handle_frame_(const uint8_t *f, size_t len)
void send_status_query_()
void handle_c0_(const uint8_t *f, size_t len)
climate::ClimateTraits traits() override
void send_capability_queries_()
void dump_config() override
static constexpr size_t MAX_FRAME
void control(const climate::ClimateCall &call) override
std::array< uint8_t, MAX_FRAME > rx_
void send_module_frame_(uint8_t type, uint8_t counter, uint8_t wifi_flags)
void send_frame_(uint8_t proto, uint8_t type, const uint8_t *payload, size_t len)
optional< std::array< uint8_t, N > > read_array()
void write_array(const uint8_t *data, size_t len)
constexpr float BME680_GAS_LOOKUP_TABLE_1[16] PROGMEM
@ CLIMATE_SUPPORTS_CURRENT_TEMPERATURE
ClimatePreset
Enum for all preset modes NOTE: If adding values, update ClimatePresetMask in climate_traits....
@ CLIMATE_PRESET_NONE
No preset is active.
@ CLIMATE_PRESET_AWAY
Device is in away preset.
@ CLIMATE_PRESET_BOOST
Device is in boost preset.
@ CLIMATE_PRESET_SLEEP
Device is prepared for sleep.
@ CLIMATE_PRESET_ECO
Device is running an energy-saving preset.
@ CLIMATE_SWING_OFF
The swing mode is set to Off.
@ CLIMATE_SWING_VERTICAL
The fan mode is set to Vertical.
ClimateMode
Enum for all modes a climate device can be in.
@ CLIMATE_MODE_DRY
The climate device is set to dry/humidity mode.
@ CLIMATE_MODE_FAN_ONLY
The climate device only has the fan enabled, no heating or cooling is taking place.
@ CLIMATE_MODE_HEAT
The climate device is set to heat to reach the target temperature.
@ CLIMATE_MODE_COOL
The climate device is set to cool to reach the target temperature.
@ CLIMATE_MODE_HEAT_COOL
The climate device is set to heat/cool to reach the target temperature.
@ CLIMATE_MODE_OFF
The climate device is off.
ClimateFanMode
NOTE: If adding values, update ClimateFanModeMask in climate_traits.h to use the new last value.
@ 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_QUIET
The fan mode is set to Quiet.
@ CLIMATE_FAN_HIGH
The fan mode is set to High.
ESPHOME_LOG_TAG(TAG, "midea_portasplit")
constexpr uint8_t sum_bytes(const uint8_t *data, size_t len, uint8_t sum=0)
Add up the bytes of data with size len, truncated to 8 bits: the checksum many serial and IR protocol...
void progmem_memcpy(void *dst, const void *src, size_t len)
char * format_hex_pretty_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length, char separator)
Format byte array as uppercase hex to buffer (base implementation).
constexpr size_t format_hex_pretty_size(size_t byte_count)
Calculate buffer size needed for format_hex_pretty_to with separator: "XX:XX:...:XX\0".
uint8_t crc8(const uint8_t *data, uint8_t len, uint8_t crc, uint8_t poly, bool msb_first)
Calculate a CRC-8 checksum of data with size len.
Application App
Global storage of Application pointer - only one Application can exist.