From 05da21c4f322a90caa400b7a024759c03cded5d6 Mon Sep 17 00:00:00 2001 From: Artem Sheremet Date: Wed, 27 May 2026 12:57:34 +0000 Subject: [PATCH] Remove and expand macros.h --- components/ratgdo/macros.h | 129 --------------------- components/ratgdo/ratgdo.h | 2 +- components/ratgdo/ratgdo_state.h | 188 ++++++++++++++++++++++++++----- components/ratgdo/secplus2.h | 46 ++++++-- 4 files changed, 194 insertions(+), 171 deletions(-) delete mode 100644 components/ratgdo/macros.h diff --git a/components/ratgdo/macros.h b/components/ratgdo/macros.h deleted file mode 100644 index 14bea5b..0000000 --- a/components/ratgdo/macros.h +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once - -#include -#include - -#include "esphome/core/log.h" - -#define PARENS () - -// Rescan macro tokens 256 times -#define EXPAND(...) EXPAND4(EXPAND4(EXPAND4(EXPAND4(__VA_ARGS__)))) -#define EXPAND4(...) EXPAND3(EXPAND3(EXPAND3(EXPAND3(__VA_ARGS__)))) -#define EXPAND3(...) EXPAND2(EXPAND2(EXPAND2(EXPAND2(__VA_ARGS__)))) -#define EXPAND2(...) EXPAND1(EXPAND1(EXPAND1(EXPAND1(__VA_ARGS__)))) -#define EXPAND1(...) __VA_ARGS__ - -#define FOR_EACH(macro, name, ...) \ - __VA_OPT__(EXPAND(FOR_EACH_HELPER(macro, name, __VA_ARGS__))) -#define FOR_EACH_HELPER(macro, name, a1, ...) \ - macro(name, a1) \ - __VA_OPT__(FOR_EACH_AGAIN PARENS(macro, name, __VA_ARGS__)) -#define FOR_EACH_AGAIN() FOR_EACH_HELPER - -#define ENUM_VARIANT0(name, val) name = val, -#define ENUM_VARIANT(name, tuple) ENUM_VARIANT0 tuple - -#define TUPLE(x, y) x, y - -#define LPAREN ( - -#define TO_STRING_IF0(type, name, val) \ - if (_e == type::name) \ - return #name; -#define TO_STRING_IF(type, tuple) TO_STRING_IF0 LPAREN type, TUPLE tuple) - -#define FROM_INT_CASE0(type, name, val) \ - case val: \ - return type::name; -#define FROM_INT_CASE(type, tuple) FROM_INT_CASE0 LPAREN type, TUPLE tuple) - -// String blob helpers for packed enum-to-string lookup tables -#define STR_BLOB_ENTRY0(type, name, val) #name "\0" -#define STR_BLOB_ENTRY(type, tuple) STR_BLOB_ENTRY0 LPAREN type, TUPLE tuple) - -#define COUNT_ONE0(type, name, val) +1 -#define COUNT_ONE(name, tuple) COUNT_ONE0 LPAREN name, TUPLE tuple) - -namespace esphome::ratgdo { -namespace detail { - - template - struct EnumStringOffsets { - uint8_t data[N]; - }; - - template - constexpr EnumStringOffsets compute_enum_string_offsets(const char (&blob)[BlobSize]) - { - EnumStringOffsets result { }; - result.data[0] = 0; - size_t entry = 1; - for (size_t i = 0; i < BlobSize - 1 && entry < Count; ++i) { - if (blob[i] == '\0') { - result.data[entry++] = static_cast(i + 1); - } - } - return result; - } - -} // namespace detail -} // namespace esphome::ratgdo - -// Platform-specific helpers for enum string return types -#define ENUM_STR_RET const char* -#define ENUM_STR_UNKNOWN "UNKNOWN" -#define ENUM_BLOB_ATTR -#define ENUM_BLOB_RETURN(blob, offset) (&(blob)[offset]) - -// ENUM: packed string blob with O(1) offset lookup (for contiguous 0-based enums with uint8_t type) -#define ENUM(name, type, ...) \ - enum class name : type { \ - FOR_EACH(ENUM_VARIANT, name, __VA_ARGS__) \ - }; \ - static_assert(sizeof(type) == 1, "ENUM() requires uint8_t type; use ENUM_SPARSE() for wider types"); \ - inline ENUM_STR_RET \ - name##_to_string(name _e) \ - { \ - static constexpr size_t _n = (0 FOR_EACH(COUNT_ONE, name, __VA_ARGS__)); \ - static const char _b[] ENUM_BLOB_ATTR = FOR_EACH(STR_BLOB_ENTRY, name, __VA_ARGS__); \ - static_assert(sizeof(_b) <= 256, "ENUM() string blob exceeds 255 bytes; use shorter names"); \ - static constexpr auto _o = ::esphome::ratgdo::detail::compute_enum_string_offsets<_n>( \ - FOR_EACH(STR_BLOB_ENTRY, name, __VA_ARGS__)); \ - auto _i = static_cast(_e); \ - if (_i >= _n) \ - return ENUM_STR_UNKNOWN; \ - return ENUM_BLOB_RETURN(_b, _o.data[_i]); \ - } \ - inline name \ - to_##name(type _t, name _unknown) \ - { \ - switch (_t) { \ - FOR_EACH(FROM_INT_CASE, name, __VA_ARGS__) \ - default: \ - return _unknown; \ - } \ - } - -// ENUM_SPARSE: if-chain lookup (for non-contiguous enum values, avoids CSWTCH) -#define ENUM_SPARSE(name, type, ...) \ - enum class name : type { \ - FOR_EACH(ENUM_VARIANT, name, __VA_ARGS__) \ - }; \ - inline ENUM_STR_RET \ - name##_to_string(name _e) \ - { \ - FOR_EACH(TO_STRING_IF, name, __VA_ARGS__) \ - return ENUM_STR_UNKNOWN; \ - } \ - inline name \ - to_##name(type _t, name _unknown) \ - { \ - switch (_t) { \ - FOR_EACH(FROM_INT_CASE, name, __VA_ARGS__) \ - default: \ - return _unknown; \ - } \ - } - - diff --git a/components/ratgdo/ratgdo.h b/components/ratgdo/ratgdo.h index cd84295..382c862 100644 --- a/components/ratgdo/ratgdo.h +++ b/components/ratgdo/ratgdo.h @@ -22,7 +22,7 @@ #include #include "callbacks.h" -#include "macros.h" + #include "observable.h" #include "protocol.h" #include "ratgdo_state.h" diff --git a/components/ratgdo/ratgdo_state.h b/components/ratgdo/ratgdo_state.h index 8932140..082a7af 100644 --- a/components/ratgdo/ratgdo_state.h +++ b/components/ratgdo/ratgdo_state.h @@ -13,50 +13,176 @@ #pragma once #include "esphome/core/defines.h" -#include "macros.h" #include namespace esphome::ratgdo { -ENUM(DoorState, uint8_t, - (UNKNOWN, 0), - (OPEN, 1), - (CLOSED, 2), - (STOPPED, 3), - (OPENING, 4), - (CLOSING, 5)) +enum class DoorState : uint8_t { + UNKNOWN = 0, + OPEN = 1, + CLOSED = 2, + STOPPED = 3, + OPENING = 4, + CLOSING = 5 +}; + +inline const char* DoorState_to_string(DoorState e) { + switch (e) { + case DoorState::UNKNOWN: return "UNKNOWN"; + case DoorState::OPEN: return "OPEN"; + case DoorState::CLOSED: return "CLOSED"; + case DoorState::STOPPED: return "STOPPED"; + case DoorState::OPENING: return "OPENING"; + case DoorState::CLOSING: return "CLOSING"; + default: return "UNKNOWN"; + } +} + +inline DoorState to_DoorState(uint8_t t, DoorState unknown) { + switch (t) { + case static_cast(DoorState::UNKNOWN): return DoorState::UNKNOWN; + case static_cast(DoorState::OPEN): return DoorState::OPEN; + case static_cast(DoorState::CLOSED): return DoorState::CLOSED; + case static_cast(DoorState::STOPPED): return DoorState::STOPPED; + case static_cast(DoorState::OPENING): return DoorState::OPENING; + case static_cast(DoorState::CLOSING): return DoorState::CLOSING; + default: return unknown; + } +} /// Enum for all states a the light can be in. -ENUM(LightState, uint8_t, - (OFF, 0), - (ON, 1), - (UNKNOWN, 2)) +enum class LightState : uint8_t { + OFF = 0, + ON = 1, + UNKNOWN = 2 +}; + +inline const char* LightState_to_string(LightState e) { + switch (e) { + case LightState::OFF: return "OFF"; + case LightState::ON: return "ON"; + case LightState::UNKNOWN: return "UNKNOWN"; + default: return "UNKNOWN"; + } +} + +inline LightState to_LightState(uint8_t t, LightState unknown) { + switch (t) { + case static_cast(LightState::OFF): return LightState::OFF; + case static_cast(LightState::ON): return LightState::ON; + case static_cast(LightState::UNKNOWN): return LightState::UNKNOWN; + default: return unknown; + } +} + LightState light_state_toggle(LightState state); /// Enum for all states a the lock can be in. -ENUM(LockState, uint8_t, - (UNLOCKED, 0), - (LOCKED, 1), - (UNKNOWN, 2)) +enum class LockState : uint8_t { + UNLOCKED = 0, + LOCKED = 1, + UNKNOWN = 2 +}; + +inline const char* LockState_to_string(LockState e) { + switch (e) { + case LockState::UNLOCKED: return "UNLOCKED"; + case LockState::LOCKED: return "LOCKED"; + case LockState::UNKNOWN: return "UNKNOWN"; + default: return "UNKNOWN"; + } +} + +inline LockState to_LockState(uint8_t t, LockState unknown) { + switch (t) { + case static_cast(LockState::UNLOCKED): return LockState::UNLOCKED; + case static_cast(LockState::LOCKED): return LockState::LOCKED; + case static_cast(LockState::UNKNOWN): return LockState::UNKNOWN; + default: return unknown; + } +} // actions -ENUM(LightAction, uint8_t, - (OFF, 0), - (ON, 1), - (TOGGLE, 2), - (UNKNOWN, 3)) +enum class LightAction : uint8_t { + OFF = 0, + ON = 1, + TOGGLE = 2, + UNKNOWN = 3 +}; -ENUM(LockAction, uint8_t, - (UNLOCK, 0), - (LOCK, 1), - (UNKNOWN, 3)) +inline const char* LightAction_to_string(LightAction e) { + switch (e) { + case LightAction::OFF: return "OFF"; + case LightAction::ON: return "ON"; + case LightAction::TOGGLE: return "TOGGLE"; + case LightAction::UNKNOWN: return "UNKNOWN"; + default: return "UNKNOWN"; + } +} -ENUM(DoorAction, uint8_t, - (CLOSE, 0), - (OPEN, 1), - (TOGGLE, 2), - (STOP, 3), - (UNKNOWN, 4)) +inline LightAction to_LightAction(uint8_t t, LightAction unknown) { + switch (t) { + case static_cast(LightAction::OFF): return LightAction::OFF; + case static_cast(LightAction::ON): return LightAction::ON; + case static_cast(LightAction::TOGGLE): return LightAction::TOGGLE; + case static_cast(LightAction::UNKNOWN): return LightAction::UNKNOWN; + default: return unknown; + } +} + +enum class LockAction : uint8_t { + UNLOCK = 0, + LOCK = 1, + UNKNOWN = 3 +}; + +inline const char* LockAction_to_string(LockAction e) { + switch (e) { + case LockAction::UNLOCK: return "UNLOCK"; + case LockAction::LOCK: return "LOCK"; + case LockAction::UNKNOWN: return "UNKNOWN"; + default: return "UNKNOWN"; + } +} + +inline LockAction to_LockAction(uint8_t t, LockAction unknown) { + switch (t) { + case static_cast(LockAction::UNLOCK): return LockAction::UNLOCK; + case static_cast(LockAction::LOCK): return LockAction::LOCK; + case static_cast(LockAction::UNKNOWN): return LockAction::UNKNOWN; + default: return unknown; + } +} + +enum class DoorAction : uint8_t { + CLOSE = 0, + OPEN = 1, + TOGGLE = 2, + STOP = 3, + UNKNOWN = 4 +}; + +inline const char* DoorAction_to_string(DoorAction e) { + switch (e) { + case DoorAction::CLOSE: return "CLOSE"; + case DoorAction::OPEN: return "OPEN"; + case DoorAction::TOGGLE: return "TOGGLE"; + case DoorAction::STOP: return "STOP"; + case DoorAction::UNKNOWN: return "UNKNOWN"; + default: return "UNKNOWN"; + } +} + +inline DoorAction to_DoorAction(uint8_t t, DoorAction unknown) { + switch (t) { + case static_cast(DoorAction::CLOSE): return DoorAction::CLOSE; + case static_cast(DoorAction::OPEN): return DoorAction::OPEN; + case static_cast(DoorAction::TOGGLE): return DoorAction::TOGGLE; + case static_cast(DoorAction::STOP): return DoorAction::STOP; + case static_cast(DoorAction::UNKNOWN): return DoorAction::UNKNOWN; + default: return unknown; + } +} struct Openings { uint16_t count; diff --git a/components/ratgdo/secplus2.h b/components/ratgdo/secplus2.h index 5b8f492..ddec648 100644 --- a/components/ratgdo/secplus2.h +++ b/components/ratgdo/secplus2.h @@ -28,18 +28,44 @@ namespace secplus2 { static const uint8_t PACKET_LENGTH = 19; typedef uint8_t WirePacket[PACKET_LENGTH]; - ENUM_SPARSE(CommandType, uint16_t, - (UNKNOWN, 0x000), - (GET_STATUS, 0x080), - (STATUS, 0x081), + enum class CommandType : uint16_t { + UNKNOWN = 0x000, + GET_STATUS = 0x080, + STATUS = 0x081, + LOCK = 0x18c, + DOOR_ACTION = 0x280, + LIGHT = 0x281, + GET_OPENINGS = 0x48b, + OPENINGS = 0x48c // openings = (byte1<<8)+byte2 + }; - (LOCK, 0x18c), - (DOOR_ACTION, 0x280), - (LIGHT, 0x281), + inline const char* CommandType_to_string(CommandType e) { + switch (e) { + case CommandType::UNKNOWN: return "UNKNOWN"; + case CommandType::GET_STATUS: return "GET_STATUS"; + case CommandType::STATUS: return "STATUS"; + case CommandType::LOCK: return "LOCK"; + case CommandType::DOOR_ACTION: return "DOOR_ACTION"; + case CommandType::LIGHT: return "LIGHT"; + case CommandType::GET_OPENINGS: return "GET_OPENINGS"; + case CommandType::OPENINGS: return "OPENINGS"; + default: return "UNKNOWN"; + } + } - (GET_OPENINGS, 0x48b), - (OPENINGS, 0x48c), // openings = (byte1<<8)+byte2 - ) + inline CommandType to_CommandType(uint16_t t, CommandType unknown) { + switch (t) { + case static_cast(CommandType::UNKNOWN): return CommandType::UNKNOWN; + case static_cast(CommandType::GET_STATUS): return CommandType::GET_STATUS; + case static_cast(CommandType::STATUS): return CommandType::STATUS; + case static_cast(CommandType::LOCK): return CommandType::LOCK; + case static_cast(CommandType::DOOR_ACTION): return CommandType::DOOR_ACTION; + case static_cast(CommandType::LIGHT): return CommandType::LIGHT; + case static_cast(CommandType::GET_OPENINGS): return CommandType::GET_OPENINGS; + case static_cast(CommandType::OPENINGS): return CommandType::OPENINGS; + default: return unknown; + } + } inline bool operator==(const uint16_t cmd_i, const CommandType& cmd_e) { return cmd_i == static_cast(cmd_e); } inline bool operator==(const CommandType& cmd_e, const uint16_t cmd_i) { return cmd_i == static_cast(cmd_e); }