13static const char *
const TAG =
"haier.climate";
25 haier_protocol::FrameType message_type,
26 const uint8_t *data,
size_t data_size) {
27 haier_protocol::HandlerError result =
28 this->
answer_preprocess_(request_type, haier_protocol::FrameType::CONTROL, message_type,
30 if (result == haier_protocol::HandlerError::HANDLER_OK) {
32 if (result != haier_protocol::HandlerError::HANDLER_OK) {
33 ESP_LOGW(TAG,
"Error %d while parsing Status packet", (
int) result);
42 ESP_LOGW(TAG,
"Status packet too small: %d (should be >= %d)", data_size,
47 ESP_LOGI(TAG,
"First HVAC status received");
76 haier_protocol::FrameType request_type, haier_protocol::FrameType message_type,
const uint8_t *data,
78 if (request_type != haier_protocol::FrameType::GET_DEVICE_VERSION)
79 return haier_protocol::HandlerError::UNSUPPORTED_MESSAGE;
81 return haier_protocol::HandlerError::UNEXPECTED_MESSAGE;
83 if ((message_type == haier_protocol::FrameType::GET_DEVICE_VERSION_RESPONSE) && (data_size >= 39) &&
84 ((data[37] & 0x04) != 0)) {
85 ESP_LOGW(TAG,
"It looks like your ESPHome Haier climate configuration is wrong. You should use the hOn protocol "
86 "instead of smartAir2");
89 return haier_protocol::HandlerError::HANDLER_OK;
93 haier_protocol::FrameType message_type) {
96 ESP_LOGI(TAG,
"Answer timeout for command %02X, phase %s", (uint8_t) message_type,
102 return haier_protocol::HandlerError::HANDLER_OK;
108 haier_protocol::FrameType::GET_DEVICE_VERSION,
110 std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
112 haier_protocol::FrameType::CONTROL,
114 std::placeholders::_3, std::placeholders::_4));
116 haier_protocol::FrameType::REPORT_NETWORK_STATUS,
118 std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
125 ESP_LOGCONFIG(TAG,
" Protocol version: smartAir2");
138 uint8_t module_capabilities[2] = {0b00000000, 0b00000111};
139 static const haier_protocol::HaierMessage DEVICE_VERSION_REQUEST(
140 haier_protocol::FrameType::GET_DEVICE_VERSION, module_capabilities,
sizeof(module_capabilities));
150 static const haier_protocol::HaierMessage STATUS_REQUEST(haier_protocol::FrameType::CONTROL, 0x4D01);
182 ESP_LOGI(TAG,
"Sending control packet");
198 ESP_LOGW(TAG,
"SENDING_ACTION_COMMAND phase without action request!");
209 (std::chrono::duration_cast<std::chrono::milliseconds>(now - this->
last_signal_request_).count() >
216 ESP_LOGE(TAG,
"Wrong protocol handler state: %s (%d), resetting communication",
225 static haier_protocol::HaierMessage power_on_message(haier_protocol::FrameType::CONTROL, 0x4D02);
226 return power_on_message;
228 static haier_protocol::HaierMessage power_off_message(haier_protocol::FrameType::CONTROL, 0x4D03);
229 return power_off_message;
271 ESP_LOGE(
"Control",
"Unsupported climate mode");
292 ESP_LOGE(
"Control",
"Unsupported fan mode");
340 out_data->
set_point = ((int) target_temp) - 16;
341 out_data->
half_degree = (target_temp - ((int) target_temp) >= 0.49) ? 1 : 0;
371 ESP_LOGE(
"Control",
"Unsupported preset");
383 return haier_protocol::HaierMessage(haier_protocol::FrameType::CONTROL, 0x4D5F, control_out_buffer,
389 return haier_protocol::HandlerError::WRONG_MESSAGE_STRUCTURE;
391 memcpy(&packet, packet_buffer, size);
392 bool should_publish =
false;
411 should_publish = should_publish || (old_target_temperature != this->
target_temperature);
436 should_publish =
true;
461 }
else if ((((uint8_t) this->
health_mode_) & 0b10) == 0) {
470 should_publish = should_publish || (old_health_mode != this->
get_health_mode());
497 should_publish = should_publish || (old_mode != this->
mode);
530 should_publish = should_publish || (old_swing_mode != this->
swing_mode);
533 if (should_publish) {
536 if (should_publish) {
537 ESP_LOGI(TAG,
"HVAC values changed");
539 int log_level = should_publish ? ESPHOME_LOG_LEVEL_INFO : ESPHOME_LOG_LEVEL_DEBUG;
545 return haier_protocol::HandlerError::HANDLER_OK;
send_message_t send_message_
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.
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.
ProtocolPhases protocol_phase_
SwitchState display_status_
bool get_health_mode() const
bool is_message_interval_exceeded_(std::chrono::steady_clock::time_point now)
CallbackManager< void(const char *, size_t)> status_message_callback_
bool forced_request_status_
bool is_protocol_initialisation_interval_exceeded_(std::chrono::steady_clock::time_point now)
bool is_status_request_interval_exceeded_(std::chrono::steady_clock::time_point now)
haier_protocol::HandlerError answer_preprocess_(haier_protocol::FrameType request_message_type, haier_protocol::FrameType expected_request_message_type, haier_protocol::FrameType answer_message_type, haier_protocol::FrameType expected_answer_message_type, ProtocolPhases expected_phase)
haier_protocol::ProtocolHandler haier_protocol_
const char * phase_to_string_(ProtocolPhases phase)
@ SENDING_UPDATE_SIGNAL_REQUEST
@ SENDING_ALARM_STATUS_REQUEST
@ SENDING_FIRST_STATUS_REQUEST
@ SENDING_FIRST_ALARM_STATUS_REQUEST
std::unique_ptr< uint8_t[]> last_status_message_
haier_protocol::HandlerError report_network_status_answer_handler_(haier_protocol::FrameType request_type, haier_protocol::FrameType message_type, const uint8_t *data, size_t data_size)
bool can_send_message() const
bool get_display_state() const
std::chrono::steady_clock::time_point last_valid_status_timestamp_
haier_protocol::HaierMessage get_wifi_signal_message_()
haier_protocol::HandlerError timeout_default_handler_(haier_protocol::FrameType request_type)
bool is_control_message_interval_exceeded_(std::chrono::steady_clock::time_point now)
uint8_t other_modes_fan_speed_
esphome::optional< PendingAction > action_request_
std::chrono::steady_clock::time_point last_status_request_
HvacSettings current_hvac_settings_
void dump_config() override
virtual void set_phase(ProtocolPhases phase)
std::chrono::steady_clock::time_point last_signal_request_
haier_protocol::HandlerError status_handler_(haier_protocol::FrameType request_type, haier_protocol::FrameType message_type, const uint8_t *data, size_t data_size)
haier_protocol::HaierMessage get_control_message() override
bool use_alternative_swing_control_
haier_protocol::HandlerError get_device_version_answer_handler_(haier_protocol::FrameType request_type, haier_protocol::FrameType message_type, const uint8_t *data, size_t data_size)
haier_protocol::HandlerError messages_timeout_handler_with_cycle_for_init_(haier_protocol::FrameType message_type)
haier_protocol::HandlerError process_status_message_(const uint8_t *packet, uint8_t size)
void set_handlers() override
void dump_config() override
haier_protocol::HaierMessage get_power_message(bool state) override
void set_alternative_swing_control(bool swing_control)
void process_phase(std::chrono::steady_clock::time_point now) override
value_type const & value() const
@ CLIMATE_PRESET_NONE
No preset is active.
@ CLIMATE_PRESET_COMFORT
Device is in comfort preset.
@ CLIMATE_PRESET_AWAY
Device is in away preset.
@ CLIMATE_PRESET_BOOST
Device is in boost preset.
ClimateSwingMode
Enum for all modes a climate swing can be in.
@ CLIMATE_SWING_OFF
The swing mode is set to Off.
@ CLIMATE_SWING_HORIZONTAL
The fan mode is set to Horizontal.
@ CLIMATE_SWING_VERTICAL
The fan mode is set to Vertical.
@ CLIMATE_SWING_BOTH
The fan mode is set to Both.
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.
@ 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.
constexpr uint8_t CONTROL_MESSAGE_RETRIES
constexpr std::chrono::milliseconds CONTROL_MESSAGE_RETRIES_INTERVAL
constexpr uint8_t INIT_REQUESTS_RETRY
constexpr std::chrono::milliseconds INIT_REQUESTS_RETRY_INTERVAL
constexpr size_t SIGNAL_LEVEL_UPDATE_INTERVAL_MS
Providing packet encoding functions for exchanging data with a remote host.
void HOT esp_log_printf_(int level, const char *tag, int line, const char *format,...)
esphome::optional< esphome::climate::ClimateFanMode > fan_mode
esphome::optional< esphome::climate::ClimateSwingMode > swing_mode
esphome::optional< esphome::climate::ClimateMode > mode
esphome::optional< esphome::climate::ClimatePreset > preset
esphome::optional< float > target_temperature
HaierPacketControl control