mirror of
https://github.com/Threnklyn/esphome-dev.git
synced 2026-05-19 12:43:28 +02:00
f34c9b33fc
* Added support for Midea IoT climate devices via UART interface (USB-dongle) * Fixed lint checks * Fixed lint checks * CODEOWNERS update * Clang-format * Clang-format * Add network device notification message support (show WiFi sign on devices) * Make wifi_signal_sensor optional component * Some optimization * Optimizations and code formatting * Fixed lint checks * Fixed lint checks * Fixed sign error * Code changes * Network notify repeat every 10 min * Added log messages * Fixed lint checks * Refactoring: MideaClimate => MideaAC * Using enums instead literals in Midea states * Enum changed to be more correct * Shrink notify frame to 32 bytes * Fixed lint checks * Change notify frame appliance type to common broadcast * Control optimization * Fixed control error * Control command now don't reset others uncontrollable properties of device * Fixed lint checks * Some optimization * on_receive callback give const Frame * Fix control * Fixes * Some minor changes * Fixed lint error * No dependency from wifi_signal sensor for stretched WiFi icon. New option: stretched_icon instead wifi_signal_id. * Fix option name * Added export of outdoor temperature as sensor value * Fixed lint errors * Fixed pylint error * Minor fix * Fix temperature overflow in some cases * Added answer on QueryNetwork command from appliance. Now don't wait for ack on 0x0D command. * Fix lint error * Added humidity setpoint optional sensor * Added boolean options 'swing_horizontal' and 'swing_both' * Added debug frame output * Added debug frame output * Fix lints error * Some debug output optimization * Fix lint check * Some code optimization: adding templates * Fix lint error * Added sensors device classes * Python code reformatted with black formatter * RX frame debug message RX frame debug message now prints before checking * Remove CRC check for receiving frames * Added experimental power usage option * Added power usage option * Fixed lint errors * Major changes. See esp-docs. * Added tests in test4.yaml * Added tests in test1.yaml * Added wifi dependency * Fix test1.yaml * Some fix :) * One more refactoring * One more refactoring * One more refactoring
161 lines
4.8 KiB
C++
161 lines
4.8 KiB
C++
#include "midea_frame.h"
|
|
|
|
namespace esphome {
|
|
namespace midea_ac {
|
|
|
|
const uint8_t QueryFrame::INIT[] = {0xAA, 0x22, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x41, 0x00,
|
|
0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x68};
|
|
|
|
const uint8_t PowerQueryFrame::INIT[] = {0xAA, 0x22, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x41, 0x21,
|
|
0x01, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x17, 0x6A};
|
|
|
|
const uint8_t CommandFrame::INIT[] = {0xAA, 0x22, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x40, 0x00,
|
|
0x00, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
|
|
float PropertiesFrame::get_target_temp() const {
|
|
float temp = static_cast<float>((this->pbuf_[12] & 0x0F) + 16);
|
|
if (this->pbuf_[12] & 0x10)
|
|
temp += 0.5;
|
|
return temp;
|
|
}
|
|
|
|
void PropertiesFrame::set_target_temp(float temp) {
|
|
uint8_t tmp = static_cast<uint8_t>(temp * 16.0) + 4;
|
|
tmp = ((tmp & 8) << 1) | (tmp >> 4);
|
|
this->pbuf_[12] &= ~0x1F;
|
|
this->pbuf_[12] |= tmp;
|
|
}
|
|
|
|
static float i16tof(int16_t in) { return static_cast<float>(in - 50) / 2.0; }
|
|
float PropertiesFrame::get_indoor_temp() const { return i16tof(this->pbuf_[21]); }
|
|
float PropertiesFrame::get_outdoor_temp() const { return i16tof(this->pbuf_[22]); }
|
|
float PropertiesFrame::get_humidity_setpoint() const { return static_cast<float>(this->pbuf_[29] & 0x7F); }
|
|
|
|
climate::ClimateMode PropertiesFrame::get_mode() const {
|
|
if (!this->get_power_())
|
|
return climate::CLIMATE_MODE_OFF;
|
|
switch (this->pbuf_[12] >> 5) {
|
|
case MIDEA_MODE_AUTO:
|
|
return climate::CLIMATE_MODE_AUTO;
|
|
case MIDEA_MODE_COOL:
|
|
return climate::CLIMATE_MODE_COOL;
|
|
case MIDEA_MODE_DRY:
|
|
return climate::CLIMATE_MODE_DRY;
|
|
case MIDEA_MODE_HEAT:
|
|
return climate::CLIMATE_MODE_HEAT;
|
|
case MIDEA_MODE_FAN_ONLY:
|
|
return climate::CLIMATE_MODE_FAN_ONLY;
|
|
default:
|
|
return climate::CLIMATE_MODE_OFF;
|
|
}
|
|
}
|
|
|
|
void PropertiesFrame::set_mode(climate::ClimateMode mode) {
|
|
uint8_t m;
|
|
switch (mode) {
|
|
case climate::CLIMATE_MODE_AUTO:
|
|
m = MIDEA_MODE_AUTO;
|
|
break;
|
|
case climate::CLIMATE_MODE_COOL:
|
|
m = MIDEA_MODE_COOL;
|
|
break;
|
|
case climate::CLIMATE_MODE_DRY:
|
|
m = MIDEA_MODE_DRY;
|
|
break;
|
|
case climate::CLIMATE_MODE_HEAT:
|
|
m = MIDEA_MODE_HEAT;
|
|
break;
|
|
case climate::CLIMATE_MODE_FAN_ONLY:
|
|
m = MIDEA_MODE_FAN_ONLY;
|
|
break;
|
|
default:
|
|
this->set_power_(false);
|
|
return;
|
|
}
|
|
this->set_power_(true);
|
|
this->pbuf_[12] &= ~0xE0;
|
|
this->pbuf_[12] |= m << 5;
|
|
}
|
|
|
|
climate::ClimateFanMode PropertiesFrame::get_fan_mode() const {
|
|
switch (this->pbuf_[13]) {
|
|
case MIDEA_FAN_LOW:
|
|
return climate::CLIMATE_FAN_LOW;
|
|
case MIDEA_FAN_MEDIUM:
|
|
return climate::CLIMATE_FAN_MEDIUM;
|
|
case MIDEA_FAN_HIGH:
|
|
return climate::CLIMATE_FAN_HIGH;
|
|
default:
|
|
return climate::CLIMATE_FAN_AUTO;
|
|
}
|
|
}
|
|
|
|
void PropertiesFrame::set_fan_mode(climate::ClimateFanMode mode) {
|
|
uint8_t m;
|
|
switch (mode) {
|
|
case climate::CLIMATE_FAN_LOW:
|
|
m = MIDEA_FAN_LOW;
|
|
break;
|
|
case climate::CLIMATE_FAN_MEDIUM:
|
|
m = MIDEA_FAN_MEDIUM;
|
|
break;
|
|
case climate::CLIMATE_FAN_HIGH:
|
|
m = MIDEA_FAN_HIGH;
|
|
break;
|
|
default:
|
|
m = MIDEA_FAN_AUTO;
|
|
break;
|
|
}
|
|
this->pbuf_[13] = m;
|
|
}
|
|
|
|
climate::ClimateSwingMode PropertiesFrame::get_swing_mode() const {
|
|
switch (this->pbuf_[17] & 0x0F) {
|
|
case MIDEA_SWING_VERTICAL:
|
|
return climate::CLIMATE_SWING_VERTICAL;
|
|
case MIDEA_SWING_HORIZONTAL:
|
|
return climate::CLIMATE_SWING_HORIZONTAL;
|
|
case MIDEA_SWING_BOTH:
|
|
return climate::CLIMATE_SWING_BOTH;
|
|
default:
|
|
return climate::CLIMATE_SWING_OFF;
|
|
}
|
|
}
|
|
|
|
void PropertiesFrame::set_swing_mode(climate::ClimateSwingMode mode) {
|
|
uint8_t m;
|
|
switch (mode) {
|
|
case climate::CLIMATE_SWING_VERTICAL:
|
|
m = MIDEA_SWING_VERTICAL;
|
|
break;
|
|
case climate::CLIMATE_SWING_HORIZONTAL:
|
|
m = MIDEA_SWING_HORIZONTAL;
|
|
break;
|
|
case climate::CLIMATE_SWING_BOTH:
|
|
m = MIDEA_SWING_BOTH;
|
|
break;
|
|
default:
|
|
m = MIDEA_SWING_OFF;
|
|
break;
|
|
}
|
|
this->pbuf_[17] = 0x30 | m;
|
|
}
|
|
|
|
float PropertiesFrame::get_power_usage() const {
|
|
uint32_t power = 0;
|
|
const uint8_t *ptr = this->pbuf_ + 28;
|
|
for (uint32_t weight = 1;; weight *= 10, ptr--) {
|
|
power += (*ptr % 16) * weight;
|
|
weight *= 10;
|
|
power += (*ptr / 16) * weight;
|
|
if (weight == 100000)
|
|
return static_cast<float>(power) * 0.1;
|
|
}
|
|
}
|
|
|
|
} // namespace midea_ac
|
|
} // namespace esphome
|