mirror of
https://github.com/GrKoR/esphome_aux_ac_component.git
synced 2025-12-11 05:57:01 +03:00
unfinished
This commit is contained in:
148
components/aux_ac/aux_frame.h
Normal file
148
components/aux_ac/aux_frame.h
Normal file
@@ -0,0 +1,148 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h> // for memcpy and memset, move to .cpp later if needed
|
||||
|
||||
namespace esphome
|
||||
{
|
||||
namespace aux_ac
|
||||
{
|
||||
|
||||
class AuxFrame
|
||||
{
|
||||
private:
|
||||
// CRC of the AUX frame
|
||||
// https://github.com/GrKoR/AUX_HVAC_Protocol#packet_crc
|
||||
union frame_crc_t
|
||||
{
|
||||
uint16_t crc16;
|
||||
uint8_t crc[2];
|
||||
};
|
||||
|
||||
// frame header
|
||||
// https://github.com/GrKoR/AUX_HVAC_Protocol#packet_header
|
||||
struct frame_header_t
|
||||
{
|
||||
uint8_t startByte;
|
||||
uint8_t _unknown1;
|
||||
uint8_t frameType;
|
||||
uint8_t wifi;
|
||||
uint8_t pingAnswer;
|
||||
uint8_t _unknown2;
|
||||
uint8_t bodyLength;
|
||||
uint8_t _unknown3;
|
||||
};
|
||||
|
||||
uint8_t *_rawData = nullptr;
|
||||
frame_header_t *_header = nullptr;
|
||||
uint8_t *_body = nullptr;
|
||||
frame_crc_t *_crc = nullptr;
|
||||
|
||||
bool _isValid = false;
|
||||
|
||||
uint8_t const AC_PACKET_START_BYTE = 0xBB;
|
||||
uint8_t const AC_HEADER_SIZE = 8;
|
||||
uint8_t const AC_BODY_LENGTH_OFFSET = 6;
|
||||
|
||||
uint8_t const AC_BUFFER_SIZE = 35; // TODO: integrate it with aux_uart.h
|
||||
|
||||
uint16_t _CRC16(uint8_t *data, uint8_t len)
|
||||
{
|
||||
uint32_t crc = 0;
|
||||
|
||||
uint8_t _crcBuffer[AC_BUFFER_SIZE];
|
||||
memset(_crcBuffer, 0, AC_BUFFER_SIZE);
|
||||
memcpy(_crcBuffer, data, len);
|
||||
|
||||
if ((len % 2) == 1)
|
||||
len++;
|
||||
|
||||
uint32_t word = 0;
|
||||
for (uint8_t i = 0; i < len; i += 2)
|
||||
{
|
||||
word = (_crcBuffer[i] << 8) + _crcBuffer[i + 1];
|
||||
crc += word;
|
||||
}
|
||||
crc = (crc >> 16) + (crc & 0xFFFF);
|
||||
crc = ~crc;
|
||||
|
||||
return crc & 0xFFFF;
|
||||
}
|
||||
|
||||
bool _checkCRC()
|
||||
{
|
||||
frame_crc_t crc;
|
||||
crc.crc16 = _CRC16(this->_rawData, AC_HEADER_SIZE + this->_rawData[AC_BODY_LENGTH_OFFSET]);
|
||||
|
||||
return ((this->_crc->crc[0] == crc.crc[1]) && (this->_crc->crc[1] == crc.crc[0]));
|
||||
}
|
||||
|
||||
void _checkFrame()
|
||||
{
|
||||
this->_isValid = false;
|
||||
if (this->_rawData == nullptr)
|
||||
return;
|
||||
|
||||
if (this->_header->startByte != AC_PACKET_START_BYTE)
|
||||
return;
|
||||
|
||||
if (!this->_checkCRC())
|
||||
return;
|
||||
|
||||
this->_isValid = true;
|
||||
}
|
||||
|
||||
public:
|
||||
AuxFrame() = default;
|
||||
~AuxFrame() {};
|
||||
|
||||
void set_data(uint8_t *data)
|
||||
{
|
||||
clearData();
|
||||
if (data == nullptr)
|
||||
return;
|
||||
|
||||
this->_rawData = data;
|
||||
this->_header = (frame_header_t *)this->_rawData;
|
||||
this->_crc = (frame_crc_t *)(this->_rawData + AC_HEADER_SIZE + this->_header->bodyLength);
|
||||
if (this->_header->bodyLength > 0)
|
||||
this->_body = this->_rawData + AC_HEADER_SIZE;
|
||||
else
|
||||
this->_body = nullptr;
|
||||
this->_checkFrame();
|
||||
}
|
||||
|
||||
void clearData()
|
||||
{
|
||||
this->_rawData = nullptr;
|
||||
this->_header = nullptr;
|
||||
this->_crc = nullptr;
|
||||
this->_body = nullptr;
|
||||
this->_isValid = false;
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return this->_isValid;
|
||||
};
|
||||
|
||||
uint8_t frameSize() const
|
||||
{
|
||||
if (!this->isValid())
|
||||
return 0;
|
||||
|
||||
return AC_HEADER_SIZE + this->_header->bodyLength + 2;
|
||||
}
|
||||
|
||||
uint8_t bodyLength() const
|
||||
{
|
||||
if (!this->isValid())
|
||||
return 0;
|
||||
|
||||
return this->_header->bodyLength;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux_ac
|
||||
|
||||
} // namespace esphome
|
||||
Reference in New Issue
Block a user