Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure message delivery for NASA packets #93

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions components/samsung_ac/log.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace esphome
{
namespace samsung_ac
{
bool debug_log_packets = false;
bool debug_log_raw_bytes = false;

} // namespace samsung_ac
} // namespace esphome
28 changes: 28 additions & 0 deletions components/samsung_ac/log.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include "esphome/core/log.h"
#include "util.h"

#define LOGV(...) ESP_LOGV(TAG, __VA_ARGS__)
#define LOGD(...) ESP_LOGD(TAG, __VA_ARGS__)
#define LOGI(...) ESP_LOGI(TAG, __VA_ARGS__)
#define LOGW(...) ESP_LOGW(TAG, __VA_ARGS__)
#define LOGE(...) ESP_LOGE(TAG, __VA_ARGS__)
#define LOGC(...) ESP_LOGCONFIG(TAG, __VA_ARGS__)

#define LOG_STATE(...) LOGI(__VA_ARGS__)
#define LOG_RAW_SEND(inter, ...) ({ if (debug_log_raw_bytes) LOGW("<< +%d: %s", inter, bytes_to_hex(__VA_ARGS__).c_str()); })
#define LOG_RAW(inter, ...) ({ if (debug_log_raw_bytes) LOGD(">> +%d: %s", inter, bytes_to_hex(__VA_ARGS__).c_str()); })
#define LOG_RAW_DISCARDED(inter, ...) ({if (debug_log_raw_bytes) LOGV(">> +%d: %s", inter, bytes_to_hex(__VA_ARGS__).c_str()); })
#define LOG_PACKET_SEND(msg, packet) LOGI("%s: %s", msg, packet.to_string().c_str())
#define LOG_PACKET_RECV(msg, packet) ({ if (debug_log_packets) LOGD("%s: %s", msg, packet.to_string().c_str()); })

namespace esphome
{
namespace samsung_ac
{
extern bool debug_log_packets;
extern bool debug_log_raw_bytes;

} // namespace samsung_ac
} // namespace esphome
69 changes: 25 additions & 44 deletions components/samsung_ac/protocol.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <algorithm>
#include "esphome/core/log.h"
#include "protocol.h"
#include "util.h"
Expand All @@ -8,62 +9,42 @@ namespace esphome
{
namespace samsung_ac
{
bool debug_log_packets = false;
bool debug_log_raw_bytes = false;
uint16_t skip_data(std::vector<uint8_t> &data, int from)
{
// Skip over filler data or broken packets
// Example:
// 320037d8fedbff81cb7ffbfd808d00803f008243000082350000805e008031008248ffff801a0082d400000b6a34 f9f6f1f9f9 32000e200002
// Note that first part is a mangled packet, then regular filler data, then start of a new packet
// and that one new proper packet will continue with the next data read

// find next value of 0x32, and retry with that one
return std::find(data.begin() + from, data.end(), 0x32) - data.begin();
}

// This functions is designed to run after a new value was added
// to the data vector. One by one.
DataResult process_data(std::vector<uint8_t> &data, MessageTarget *target)
DecodeResult process_data(std::vector<uint8_t> &data, MessageTarget *target)
{
if (data.size() > 1500)
{
ESP_LOGV(TAG, "current packat exceeds the size limits: %s", bytes_to_hex(data).c_str());
return DataResult::Clear;
}
if (*data.begin() != 0x32)
return { DecodeResultType::Discard, skip_data(data, 0) };

// Check if its a decodeable NonNASA packat
if (data.size() == 7 /* duplicate addr package */ || data.size() == 14 /* generic package */)
auto result = try_decode_non_nasa_packet(data);
if (result.type == DecodeResultType::Processed)
{
const auto result = try_decode_non_nasa_packet(data);
if (result == DecodeResult::Ok)
{
if (debug_log_raw_bytes)
{
ESP_LOGW(TAG, "RAW: %s", bytes_to_hex(data).c_str());
}

process_non_nasa_packet(target);
return DataResult::Clear;
}
process_non_nasa_packet(target);
return result;
}

const auto result = try_decode_nasa_packet(data);
if (result == DecodeResult::SizeDidNotMatch || result == DecodeResult::UnexpectedSize)
return DataResult::Fill;

if (debug_log_raw_bytes)
result = try_decode_nasa_packet(data);
if (result.type == DecodeResultType::Processed)
{
ESP_LOGV(TAG, "RAW: %s", bytes_to_hex(data).c_str());
process_nasa_packet(target);
}

if (result == DecodeResult::InvalidStartByte)
{
ESP_LOGV(TAG, "invalid start byte: %s", bytes_to_hex(data).c_str());
return DataResult::Clear;
}
else if (result == DecodeResult::InvalidEndByte)
else if(result.type == DecodeResultType::Discard)
{
ESP_LOGV(TAG, "invalid end byte: %s", bytes_to_hex(data).c_str());
return DataResult::Clear;
return { DecodeResultType::Discard, skip_data(data, 1) };
}
else if (result == DecodeResult::CrcError)
{
// is logge dwithin decoder
return DataResult::Clear;
}

process_nasa_packet(target);
return DataResult::Clear;
return result;
}

bool is_nasa_address(const std::string &address)
Expand Down
29 changes: 12 additions & 17 deletions components/samsung_ac/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ namespace esphome
{
namespace samsung_ac
{
extern bool debug_log_packets;
extern bool debug_log_raw_bytes;
enum class DecodeResultType
{
Fill = 1,
Discard = 2,
Processed = 3
};

enum class DecodeResult
struct DecodeResult
{
Ok = 0,
InvalidStartByte = 1,
InvalidEndByte = 2,
SizeDidNotMatch = 3,
UnexpectedSize = 4,
CrcError = 5
DecodeResultType type;
uint16_t bytes; // when Processed
};

enum class Mode
Expand Down Expand Up @@ -63,7 +63,8 @@ namespace esphome
{
public:
virtual uint32_t get_miliseconds() = 0;
virtual void publish_data(std::vector<uint8_t> &data) = 0;
virtual void publish_data(uint8_t id, std::vector<uint8_t> &&data) = 0;
virtual void ack_data(uint8_t id) = 0;
virtual void register_address(const std::string address) = 0;
virtual void set_power(const std::string address, bool value) = 0;
virtual void set_room_temperature(const std::string address, float value) = 0;
Expand Down Expand Up @@ -95,13 +96,7 @@ namespace esphome
virtual void publish_request(MessageTarget *target, const std::string &address, ProtocolRequest &request) = 0;
};

enum class DataResult
{
Fill = 0,
Clear = 1
};

DataResult process_data(std::vector<uint8_t> &data, MessageTarget *target);
DecodeResult process_data(std::vector<uint8_t> &data, MessageTarget *target);

Protocol *get_protocol(const std::string &address);

Expand Down
Loading