From 7790c7af54fdb47b605eb617333a7e25fe2b357f Mon Sep 17 00:00:00 2001 From: Pavlo Dudnytskyi Date: Thu, 7 Dec 2023 06:41:14 +0100 Subject: [PATCH] Added processing and confirmation for error messages for hOn protocol --- components/haier/hon_climate.cpp | 46 +++++++++++++++++++++++++- components/haier/hon_climate.h | 4 +++ components/haier/hon_packet.h | 56 ++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) diff --git a/components/haier/hon_climate.cpp b/components/haier/hon_climate.cpp index 795d3d5..fcaea79 100644 --- a/components/haier/hon_climate.cpp +++ b/components/haier/hon_climate.cpp @@ -256,7 +256,9 @@ haier_protocol::HandlerError HonClimate::get_alarm_status_answer_handler_(haier_ this->set_phase(ProtocolPhases::IDLE); return haier_protocol::HandlerError::UNEXPECTED_MESSAGE; } - memcpy(this->active_alarms_, data + 2, 8); + if (data_size < sizeof(active_alarms_) + 2) + return haier_protocol::HandlerError::WRONG_MESSAGE_STRUCTURE; + this->process_alarm_message_(data, data_size, this->protocol_phase_ >= ProtocolPhases::IDLE); this->set_phase(ProtocolPhases::IDLE); return haier_protocol::HandlerError::HANDLER_OK; } else { @@ -265,6 +267,16 @@ haier_protocol::HandlerError HonClimate::get_alarm_status_answer_handler_(haier_ } } +haier_protocol::HandlerError HonClimate::alarm_status_message_handler_(haier_protocol::FrameType type, const uint8_t* buffer, size_t size) { + haier_protocol::HandlerError result = haier_protocol::HandlerError::HANDLER_OK; + if (size < sizeof(this->active_alarms_) + 2) + // Log error but confirm anyway to avoid to many messages + result = haier_protocol::HandlerError::WRONG_MESSAGE_STRUCTURE; + this->process_alarm_message_(buffer, size, true); + this->haier_protocol_.send_answer(haier_protocol::HaierMessage(haier_protocol::FrameType::CONFIRM)); + return result; +} + void HonClimate::set_handlers() { // Set handlers this->haier_protocol_.set_answer_handler( @@ -291,6 +303,8 @@ void HonClimate::set_handlers() { haier_protocol::FrameType::REPORT_NETWORK_STATUS, std::bind(&HonClimate::report_network_status_answer_handler_, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); + this->haier_protocol_.set_message_handler(haier_protocol::FrameType::ALARM_STATUS, + std::bind(&HonClimate::alarm_status_message_handler_, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); } void HonClimate::dump_config() { @@ -604,6 +618,36 @@ haier_protocol::HaierMessage HonClimate::get_control_message() { control_out_buffer, sizeof(hon_protocol::HaierPacketControl)); } +void HonClimate::process_alarm_message_(const uint8_t *packet, uint8_t size, bool check_new) { + constexpr size_t active_alarms_size = sizeof(this->active_alarms_); + if (size >= active_alarms_size + 2) { + if (check_new) { + size_t alarm_code = 0; + for (int i = active_alarms_size - 1; i >= 0; i--) + if (packet[2 + i] != active_alarms_[i]) { + uint8_t alarm_bit = 1; + for (int b = 0; b < 8; b++) { + if ((packet[2 + i] & alarm_bit) != (this->active_alarms_[i] & alarm_bit)) { + bool alarm_status = (packet[2 + i] & alarm_bit) != 0; + int log_level = alarm_status ? ESPHOME_LOG_LEVEL_WARN : ESPHOME_LOG_LEVEL_INFO; + esp_log_printf_(log_level, TAG, __LINE__, "Alarm %s (%d): %s", + alarm_status ? "activated" : "deactivated", + alarm_code, + (alarm_code < esphome::haier::hon_protocol::HON_ALARMS_COUNT ? esphome::haier::hon_protocol::hon_alarm_messages[alarm_code].c_str() : "Unknown")); + } + alarm_bit <<= 1; + alarm_code++; + } + active_alarms_[i] = packet[2 + i]; + } + else + alarm_code += 8; + } + else + memcpy(this->active_alarms_, packet + 2, sizeof(this->active_alarms_)); + } +} + haier_protocol::HandlerError HonClimate::process_status_message_(const uint8_t *packet_buffer, uint8_t size) { if (size < hon_protocol::HAIER_STATUS_FRAME_SIZE + this->extra_control_packet_bytes_) return haier_protocol::HandlerError::WRONG_MESSAGE_STRUCTURE; diff --git a/components/haier/hon_climate.h b/components/haier/hon_climate.h index 1ba6a8e..e5bd335 100644 --- a/components/haier/hon_climate.h +++ b/components/haier/hon_climate.h @@ -77,8 +77,12 @@ class HonClimate : public HaierClimateBase { haier_protocol::HandlerError get_alarm_status_answer_handler_(haier_protocol::FrameType request_type, haier_protocol::FrameType message_type, const uint8_t *data, size_t data_size); + haier_protocol::HandlerError alarm_status_message_handler_(haier_protocol::FrameType type, + const uint8_t* packet, + size_t size); // Helper functions haier_protocol::HandlerError process_status_message_(const uint8_t *packet, uint8_t size); + void process_alarm_message_(const uint8_t *packet, uint8_t size, bool check_new); void fill_control_messages_queue_(); void clear_control_messages_queue_(); diff --git a/components/haier/hon_packet.h b/components/haier/hon_packet.h index 7724b43..a2b061c 100644 --- a/components/haier/hon_packet.h +++ b/components/haier/hon_packet.h @@ -163,6 +163,62 @@ enum class SubcommandsControl : uint16_t { // content: all values like in status packet) }; +const std::string hon_alarm_messages[] = { + "Outdoor module failure", + "Outdoor defrost sensor failure", + "Outdoor compressor exhaust sensor failure", + "Outdoor EEPROM abnormality", + "Indoor coil sensor failure", + "Indoor-outdoor communication failure", + "Power supply overvoltage protection", + "Communication failure between panel and indoor unit", + "Outdoor compressor overheat protection", + "Outdoor environmental sensor abnormality", + "Full water protection", + "Indoor EEPROM failure", + "Outdoor out air sensor failure", + "CBD and module communication failure", + "Indoor DC fan failure", + "Outdoor DC fan failure", + "Door switch failure", + "Dust filter needs cleaning reminder", + "Water shortage protection", + "Humidity sensor failure", + "Indoor temperature sensor failure", + "Manipulator limit failure", + "Indoor PM2.5 sensor failure", + "Outdoor PM2.5 sensor failure", + "Indoor heating overload/high load alarm", + "Outdoor AC current protection", + "Outdoor compressor operation abnormality", + "Outdoor DC current protection", + "Outdoor no-load failure", + "CT current abnormality", + "Indoor cooling freeze protection", + "High and low pressure protection", + "Compressor out air temperature is too high", + "Outdoor evaporator sensor failure", + "Outdoor cooling overload", + "Water pump drainage failure", + "Three-phase power supply failure", + "Four-way valve failure", + "External alarm/scraper flow switch failure", + "Temperature cutoff protection alarm", + "Different mode operation failure", + "Electronic expansion valve failure", + "Dual heat source sensor Tw failure", + "Communication failure with the wired controller", + "Indoor unit address duplication failure", + "50Hz zero crossing failure", + "Outdoor unit failure", + "Formaldehyde sensor failure", + "VOC sensor failure", + "CO2 sensor failure", + "Firewall failure", +}; + +constexpr size_t HON_ALARMS_COUNT = sizeof(hon_alarm_messages)/sizeof(hon_alarm_messages[0]); + } // namespace hon_protocol } // namespace haier } // namespace esphome