1
0
mirror of https://github.com/esphome/esphome.git synced 2025-03-14 06:38:17 +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
CONF_REPEATS = "repeats"
TYPE_FRAME = "frame"
TYPE_REPEAT = "repeat"
TYPE_FRAME_WITH_REPEATS = "frame_with_repeats"
TYPE_REPEATS_ONLY = "repeats_only"
ns = remote_base_ns = cg.esphome_ns.namespace("remote_base")
RemoteProtocol = ns.class_("RemoteProtocol")
@ -753,8 +753,8 @@ async def keeloq_action(var, config, args):
NECData, NECBinarySensor, NECTrigger, NECAction, NECDumper = declare_protocol("NEC")
nec_code_type_enum_class = ns.enum("NECCodeType", is_class=True)
NEC_CODE_TYPES = {
TYPE_FRAME: nec_code_type_enum_class.FRAME,
TYPE_REPEAT: nec_code_type_enum_class.REPEAT,
TYPE_FRAME_WITH_REPEATS: nec_code_type_enum_class.FRAME_WITH_REPEATS,
TYPE_REPEATS_ONLY: nec_code_type_enum_class.REPEATS_ONLY,
}
NEC_SCHEMA = cv.Schema(
@ -762,7 +762,9 @@ NEC_SCHEMA = cv.Schema(
cv.Required(CONF_ADDRESS): cv.hex_uint16_t,
cv.Required(CONF_COMMAND): cv.hex_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.");
}
if (data.repeats == 0 && data.type != NECCodeType::FRAME) {
ESP_LOGE(TAG, "NECData repeat count must be greater than 0 for type NECCodeType::REPEAT.");
if (data.repeats == 0 && data.type != NECCodeType::FRAME_WITH_REPEATS) {
ESP_LOGE(TAG, "NECData repeat count must be greater than 0 for type NECCodeType::FRAME_WITH_REPEATS.");
}
// Repeat codes (4 per repeat)
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 += 32; // Address 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->set_carrier_frequency(38222);
if (data.type == NECCodeType::FRAME) {
if (data.type == NECCodeType::FRAME_WITH_REPEATS) {
// Send the AGC Header (start of frame)
dst->item(AGC_HIGH_US, LONG_PAUSE_LOW_US);
@ -90,7 +90,7 @@ optional<NECData> NECProtocol::decode(RemoteReceiveData src) {
.address = 0,
.command = 0,
.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)
@ -158,17 +158,17 @@ void NECProtocol::dump(const NECData &data) {
std::string NECProtocol::get_protocol_type_and_fields(const NECData &data) const {
std::string debug_message = "NEC ";
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);
break;
case NECCodeType::REPEAT:
case NECCodeType::REPEATS_ONLY:
debug_message += "Repeat Code:";
break;
default:
debug_message += "Unknown";
}
if (data.type == NECCodeType::FRAME) {
if (data.type == NECCodeType::FRAME_WITH_REPEATS) {
debug_message += ": address=0x";
if (this->is_extended(data)) {
debug_message += str_sprintf("%04X", data.address);

View File

@ -5,10 +5,10 @@
namespace esphome {
namespace remote_base {
/// @brief NEC protocol frame types
/// @brief NEC protocol code types
enum class NECCodeType : uint8_t {
FRAME, ///< Frame with address, command and repeats
REPEAT ///< Repeat code without address and command
FRAME_WITH_REPEATS, ///< Frame with address, command and repeats
REPEATS_ONLY ///< Repeat code without address and command
};
/// @brief Struct to store NEC protocol data
@ -40,9 +40,9 @@ struct NECData {
}
switch (type) {
case NECCodeType::REPEAT:
case NECCodeType::REPEATS_ONLY:
return repeats == rhs.repeats;
case NECCodeType::FRAME:
case NECCodeType::FRAME_WITH_REPEATS:
return address == rhs.address && command == rhs.command && repeats == rhs.repeats;
default:
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> {
public:
/// @brief Encodes `NECData` into `RemoteTransmitData`.
/// @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,
/// and the specified number of repeat codes.
/// - If `data.type` is `NECCodeType::REPEAT`, 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.
/// - If `data.type` is `NECCodeType::FRAME_WITH_REPEATS`, it encodes a full NEC frame with address, command,
/// stop bit, and the specified number of repeat codes.
/// - If `data.type` is `NECCodeType::REPEATS_ONLY`, it encodes just repeat codes without frame.
/// @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.
/// @param[out] dst Destination `RemoteTransmitData` for the encoded signal.
/// @param[in] data NEC data containing type, address, command, and repeat count.
void encode(RemoteTransmitData *dst, const NECData &data) override;
/// @brief Decodes `NECData` from `RemoteReceiveData`.
/// @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 `NECCodeType::REPEAT` code is detected, it returns a predefined `NEC_REPEAT_CODE_DATA` instance.
/// @note A `NECCodeType::FRAME` is always decoded with `repeats = 0`, as repeat codes are processed separately.
/// - If a valid `NECCodeType::FRAME_WITH_REPEATS` is detected, it extracts the address, command.
/// - If a `NECCodeType::REPEATS_ONLY` code is detected, it returns a predefined `NEC_REPEAT_CODE_DATA`
/// 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.
/// @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.