Skip to content

Commit

Permalink
Added mechanism to send message without waiting for answer
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavlo Dudnytskyi committed Mar 15, 2024
1 parent e8f5d90 commit 04188a4
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 6 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/.vscode/
/bin/
build/

# Prerequisites
*.d
Expand Down
2 changes: 2 additions & 0 deletions include/protocol/haier_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class ProtocolHandler
void set_cooldown_interval(long long answer_timeout_miliseconds);
void set_cooldown_interval(std::chrono::milliseconds answer_timeout);
void send_message(const HaierMessage& message, bool use_crc, uint8_t num_retries = 0, std::chrono::milliseconds interval = std::chrono::milliseconds::zero());
void send_message_without_answer(const HaierMessage& message, bool use_crc);
void send_answer(const HaierMessage& answer);
void send_answer(const HaierMessage& answer, bool use_crc);
void set_message_handler(FrameType message_type, MessageHandler handler);
Expand All @@ -85,6 +86,7 @@ class ProtocolHandler
{
const HaierMessage message;
bool use_crc;
bool no_answer;
int number_of_retries;
std::chrono::milliseconds retry_interval;
};
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "HaierProtocol",
"version": "0.9.26",
"version": "0.9.27",
"description": "A library to control Haier smart appliances using serial protocol",
"keywords": "haier, hOn, air-conditioner, washing-machine, uart, serial",
"repository":
Expand Down
23 changes: 18 additions & 5 deletions src/protocol/haier_protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ void ProtocolHandler::loop()
}
else if (!this->answer_sent_)
{
HAIER_LOGW("No answer sent in incoming messages handler, message type %02X", msg_type);
HAIER_LOGI("No answer sent in incoming messages handler, message type %02X", msg_type);
}
}
{
Expand All @@ -84,9 +84,17 @@ void ProtocolHandler::loop()
if (this->write_message_(msg.message, msg.use_crc))
{
this->last_message_type_ = msg.message.get_frame_type();
this->state_ = ProtocolState::WAITING_FOR_ANSWER;
this->answer_time_point_ = now + this->answer_timeout_interval_;
this->retry_time_point_ = now + msg.retry_interval;
if (msg.no_answer)
{
this->outgoing_messages_.pop();
this->retry_time_point_ = now;
}
else
{
this->state_ = ProtocolState::WAITING_FOR_ANSWER;
this->answer_time_point_ = now + this->answer_timeout_interval_;
this->retry_time_point_ = now + msg.retry_interval;
}
}
msg.number_of_retries--;
} else {
Expand Down Expand Up @@ -193,7 +201,12 @@ void ProtocolHandler::set_cooldown_interval(std::chrono::milliseconds answer_tim

void ProtocolHandler::send_message(const HaierMessage& message, bool use_crc, uint8_t num_repeats, std::chrono::milliseconds interval)
{
this->outgoing_messages_.push({ message, use_crc, std::min(num_repeats, MAX_PACKET_RETRIES) + 1, interval });
this->outgoing_messages_.push({ message, use_crc, false, std::min(num_repeats, MAX_PACKET_RETRIES) + 1, interval });
}

void ProtocolHandler::send_message_without_answer(const HaierMessage& message, bool use_crc)
{
this->outgoing_messages_.push({ message, use_crc, true, 1, std::chrono::milliseconds::zero() });
}

void ProtocolHandler::send_answer(const HaierMessage &answer)
Expand Down
20 changes: 20 additions & 0 deletions test/hon_test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,26 @@ int main(int argc, char** argv) {
hon_client.loop();
hon_server.loop();
}
// Some of the appliances (washing machines) take longer than a second to send the status answer
// For these devices, it is better to request data without waiting for an answerand process the answer as the incoming message.
// Testing mechanism to request message without expecting answer and process answer as a new message
hon_client.set_message_handler(haier_protocol::FrameType::STATUS,
[] (haier_protocol::FrameType message_type, const uint8_t* data, size_t data_size) -> haier_protocol::HandlerError {
if (message_type == haier_protocol::FrameType::STATUS)
HAIER_LOGI("Received an answer as a new message, type 0x%02X", message_type);
else
return haier_protocol::default_message_handler(message_type, data, data_size);
return haier_protocol::HandlerError::HANDLER_OK;
});
std::this_thread::sleep_for(std::chrono::milliseconds(500));
{
const haier_protocol::HaierMessage status_request_message(haier_protocol::FrameType::CONTROL, (uint16_t)SubcommandsControl::GET_USER_DATA);
hon_client.send_message_without_answer(status_request_message, true);
hon_client.loop();
hon_server.loop();
hon_client.loop();
hon_server.loop();
}
if (memcmp(&ac_full_state.control, &get_ac_state_ref().control, sizeof(HaierPacketControl)) == 0) {
HAIER_LOGI("AC control processed correctly");
} else {
Expand Down

0 comments on commit 04188a4

Please sign in to comment.