1
0
mirror of https://github.com/esphome/esphome.git synced 2025-03-15 07:08:20 +00:00

[remote_base] NEC, change

This commit is contained in:
Djordje 2025-02-18 20:08:25 +01:00
parent 75cd50e7d9
commit f6d33a7ab3
3 changed files with 31 additions and 26 deletions

View File

@ -49,8 +49,8 @@ CONF_FIRST = "first"
# NEC # NEC
CONF_REPEATS = "repeats" CONF_REPEATS = "repeats"
TYPE_FRAME = "frame" TYPE_FRAME_WITH_REPEATS = "frame_with_repeats"
TYPE_REPEAT = "repeat" TYPE_REPEATS_ONLY = "repeats_only"
ns = remote_base_ns = cg.esphome_ns.namespace("remote_base") ns = remote_base_ns = cg.esphome_ns.namespace("remote_base")
RemoteProtocol = ns.class_("RemoteProtocol") RemoteProtocol = ns.class_("RemoteProtocol")
@ -753,8 +753,8 @@ async def keeloq_action(var, config, args):
NECData, NECBinarySensor, NECTrigger, NECAction, NECDumper = declare_protocol("NEC") NECData, NECBinarySensor, NECTrigger, NECAction, NECDumper = declare_protocol("NEC")
nec_code_type_enum_class = ns.enum("NECCodeType", is_class=True) nec_code_type_enum_class = ns.enum("NECCodeType", is_class=True)
NEC_CODE_TYPES = { NEC_CODE_TYPES = {
TYPE_FRAME: nec_code_type_enum_class.FRAME, TYPE_FRAME_WITH_REPEATS: nec_code_type_enum_class.FRAME_WITH_REPEATS,
TYPE_REPEAT: nec_code_type_enum_class.REPEAT, TYPE_REPEATS_ONLY: nec_code_type_enum_class.REPEATS_ONLY,
} }
NEC_SCHEMA = cv.Schema( NEC_SCHEMA = cv.Schema(
@ -762,7 +762,9 @@ NEC_SCHEMA = cv.Schema(
cv.Required(CONF_ADDRESS): cv.hex_uint16_t, cv.Required(CONF_ADDRESS): cv.hex_uint16_t,
cv.Required(CONF_COMMAND): cv.hex_uint16_t, cv.Required(CONF_COMMAND): cv.hex_uint16_t,
cv.Optional(CONF_REPEATS, default=0): cv.uint16_t, cv.Optional(CONF_REPEATS, default=0): cv.uint16_t,
cv.Optional(CONF_TYPE, default=TYPE_FRAME): cv.enum(NEC_CODE_TYPES, lower=True), cv.Optional(CONF_TYPE, default=TYPE_FRAME_WITH_REPEATS): cv.enum(
NEC_CODE_TYPES, lower=True
),
} }
) )

View File

@ -26,13 +26,13 @@ void NECProtocol::encode(RemoteTransmitData *dst, const NECData &data) {
ESP_LOGW(TAG, "High repeat count may cause WDT timeout."); ESP_LOGW(TAG, "High repeat count may cause WDT timeout.");
} }
if (data.repeats == 0 && data.type != NECCodeType::FRAME) { if (data.repeats == 0 && data.type != NECCodeType::FRAME_WITH_REPEATS) {
ESP_LOGE(TAG, "NECData repeat count must be greater than 0 for type NECCodeType::REPEAT."); ESP_LOGE(TAG, "NECData repeat count must be greater than 0 for type NECCodeType::FRAME_WITH_REPEATS.");
} }
// Repeat codes (4 per repeat) // Repeat codes (4 per repeat)
uint32_t dst_len = data.repeats * 4; uint32_t dst_len = data.repeats * 4;
if (data.type == NECCodeType::FRAME) { if (data.type == NECCodeType::FRAME_WITH_REPEATS) {
dst_len += 2; // AGC Header (2) dst_len += 2; // AGC Header (2)
dst_len += 32; // Address bits (32) dst_len += 32; // Address bits (32)
dst_len += 32; // Command bits (32) dst_len += 32; // Command bits (32)
@ -41,7 +41,7 @@ void NECProtocol::encode(RemoteTransmitData *dst, const NECData &data) {
dst->reserve(dst_len); dst->reserve(dst_len);
dst->set_carrier_frequency(38222); dst->set_carrier_frequency(38222);
if (data.type == NECCodeType::FRAME) { if (data.type == NECCodeType::FRAME_WITH_REPEATS) {
// Send the AGC Header (start of frame) // Send the AGC Header (start of frame)
dst->item(AGC_HIGH_US, LONG_PAUSE_LOW_US); dst->item(AGC_HIGH_US, LONG_PAUSE_LOW_US);
@ -90,7 +90,7 @@ optional<NECData> NECProtocol::decode(RemoteReceiveData src) {
.address = 0, .address = 0,
.command = 0, .command = 0,
.repeats = 0, // Start with 0, as the first frame is counted explicitly .repeats = 0, // Start with 0, as the first frame is counted explicitly
.type = NECCodeType::FRAME, .type = NECCodeType::FRAME_WITH_REPEATS,
}; };
// Validate the AGC header (start of frame or repeat code) // Validate the AGC header (start of frame or repeat code)
@ -158,17 +158,17 @@ void NECProtocol::dump(const NECData &data) {
std::string NECProtocol::get_protocol_type_and_fields(const NECData &data) const { std::string NECProtocol::get_protocol_type_and_fields(const NECData &data) const {
std::string debug_message = "NEC "; std::string debug_message = "NEC ";
switch (data.type) { switch (data.type) {
case NECCodeType::FRAME: case NECCodeType::FRAME_WITH_REPEATS:
debug_message += str_sprintf("Frame (%u-bit address)", this->is_extended(data) ? 16 : 8); debug_message += str_sprintf("Frame (%u-bit address)", this->is_extended(data) ? 16 : 8);
break; break;
case NECCodeType::REPEAT: case NECCodeType::REPEATS_ONLY:
debug_message += "Repeat Code:"; debug_message += "Repeat Code:";
break; break;
default: default:
debug_message += "Unknown"; debug_message += "Unknown";
} }
if (data.type == NECCodeType::FRAME) { if (data.type == NECCodeType::FRAME_WITH_REPEATS) {
debug_message += ": address=0x"; debug_message += ": address=0x";
if (this->is_extended(data)) { if (this->is_extended(data)) {
debug_message += str_sprintf("%04X", data.address); debug_message += str_sprintf("%04X", data.address);

View File

@ -5,10 +5,10 @@
namespace esphome { namespace esphome {
namespace remote_base { namespace remote_base {
/// @brief NEC protocol frame types /// @brief NEC protocol code types
enum class NECCodeType : uint8_t { enum class NECCodeType : uint8_t {
FRAME, ///< Frame with address, command and repeats FRAME_WITH_REPEATS, ///< Frame with address, command and repeats
REPEAT ///< Repeat code without address and command REPEATS_ONLY ///< Repeat code without address and command
}; };
/// @brief Struct to store NEC protocol data /// @brief Struct to store NEC protocol data
@ -40,9 +40,9 @@ struct NECData {
} }
switch (type) { switch (type) {
case NECCodeType::REPEAT: case NECCodeType::REPEATS_ONLY:
return repeats == rhs.repeats; return repeats == rhs.repeats;
case NECCodeType::FRAME: case NECCodeType::FRAME_WITH_REPEATS:
return address == rhs.address && command == rhs.command && repeats == rhs.repeats; return address == rhs.address && command == rhs.command && repeats == rhs.repeats;
default: default:
return false; return false;
@ -50,25 +50,28 @@ struct NECData {
}; };
}; };
static const NECData NEC_REPEAT_CODE_DATA = {{0}, {0}, 1, NECCodeType::REPEAT}; /// @brief Predefined single repeat code `NECData` returned by `NECProtocol::decode`
static const NECData NEC_REPEAT_CODE_DATA = {{0}, {0}, 1, NECCodeType::REPEATS_ONLY};
class NECProtocol : public RemoteProtocol<NECData> { class NECProtocol : public RemoteProtocol<NECData> {
public: public:
/// @brief Encodes `NECData` into `RemoteTransmitData`. /// @brief Encodes `NECData` into `RemoteTransmitData`.
/// @details Generates an NEC IR signal based on the given `NECData`: /// @details Generates an NEC IR signal based on the given `NECData`:
/// - If `data.type` is `NECCodeType::FRAME`, it encodes a full NEC frame with address, command, stop bit, /// - If `data.type` is `NECCodeType::FRAME_WITH_REPEATS`, it encodes a full NEC frame with address, command,
/// and the specified number of repeat codes. /// stop bit, and the specified number of repeat codes.
/// - If `data.type` is `NECCodeType::REPEAT`, it encodes just repeat codes without frame. /// - If `data.type` is `NECCodeType::REPEATS_ONLY`, it encodes just repeat codes without frame.
/// @note `NECCodeType::REPEAT` `data.type` is invalid if `data.repeats` is 0, and no data will be encoded. /// @note `NECCodeType::REPEATS_ONLY` `data.type` is invalid if `data.repeats` is 0, and no data will be encoded.
/// @warning A high repeat count may cause a WDT timeout. /// @warning A high repeat count may cause a WDT timeout.
/// @param[out] dst Destination `RemoteTransmitData` for the encoded signal. /// @param[out] dst Destination `RemoteTransmitData` for the encoded signal.
/// @param[in] data NEC data containing type, address, command, and repeat count. /// @param[in] data NEC data containing type, address, command, and repeat count.
void encode(RemoteTransmitData *dst, const NECData &data) override; void encode(RemoteTransmitData *dst, const NECData &data) override;
/// @brief Decodes `NECData` from `RemoteReceiveData`. /// @brief Decodes `NECData` from `RemoteReceiveData`.
/// @details This function parses `NECData`, distinguishing between full message frames and repeat codes: /// @details This function parses `NECData`, distinguishing between full message frames and repeat codes:
/// - If a valid `NECCodeType::FRAME` is detected, it extracts the address, command. /// - If a valid `NECCodeType::FRAME_WITH_REPEATS` is detected, it extracts the address, command.
/// - If a `NECCodeType::REPEAT` code is detected, it returns a predefined `NEC_REPEAT_CODE_DATA` instance. /// - If a `NECCodeType::REPEATS_ONLY` code is detected, it returns a predefined `NEC_REPEAT_CODE_DATA`
/// @note A `NECCodeType::FRAME` is always decoded with `repeats = 0`, as repeat codes are processed separately. /// instance.
/// @note A `NECCodeType::FRAME_WITH_REPEATS` is always decoded with `repeats = 0`, as repeat codes are processed
/// separately.
/// @warning If the decoded command is invalid, a warning is logged. /// @warning If the decoded command is invalid, a warning is logged.
/// @param[in] src The received IR signal data to be decoded. /// @param[in] src The received IR signal data to be decoded.
/// @return An `optional<NECData>` containing the decoded NEC data, or an empty optional if decoding fails. /// @return An `optional<NECData>` containing the decoded NEC data, or an empty optional if decoding fails.