Add variable bit width for Samsung protocol (#1927)

This commit is contained in:
Keith Burzinski 2021-06-17 20:54:46 -05:00 committed by GitHub
parent f9a31c1abb
commit 04d926af39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 14 deletions

View File

@ -60,6 +60,7 @@ from esphome.cpp_types import ( # noqa
uint8, uint8,
uint16, uint16,
uint32, uint32,
uint64,
int32, int32,
const_char_ptr, const_char_ptr,
NAN, NAN,

View File

@ -866,7 +866,8 @@ def rc_switch_dumper(var, config):
) = declare_protocol("Samsung") ) = declare_protocol("Samsung")
SAMSUNG_SCHEMA = cv.Schema( SAMSUNG_SCHEMA = cv.Schema(
{ {
cv.Required(CONF_DATA): cv.hex_uint32_t, cv.Required(CONF_DATA): cv.hex_uint64_t,
cv.Optional(CONF_NBITS, default=32): cv.int_range(32, 64),
} }
) )
@ -878,6 +879,7 @@ def samsung_binary_sensor(var, config):
cg.StructInitializer( cg.StructInitializer(
SamsungData, SamsungData,
("data", config[CONF_DATA]), ("data", config[CONF_DATA]),
("nbits", config[CONF_NBITS]),
) )
) )
) )
@ -895,8 +897,10 @@ def samsung_dumper(var, config):
@register_action("samsung", SamsungAction, SAMSUNG_SCHEMA) @register_action("samsung", SamsungAction, SAMSUNG_SCHEMA)
async def samsung_action(var, config, args): async def samsung_action(var, config, args):
template_ = await cg.templatable(config[CONF_DATA], args, cg.uint32) template_ = await cg.templatable(config[CONF_DATA], args, cg.uint64)
cg.add(var.set_data(template_)) cg.add(var.set_data(template_))
template_ = await cg.templatable(config[CONF_NBITS], args, cg.uint8)
cg.add(var.set_nbits(template_))
# Samsung36 # Samsung36

View File

@ -6,7 +6,6 @@ namespace remote_base {
static const char *const TAG = "remote.samsung"; static const char *const TAG = "remote.samsung";
static const uint8_t NBITS = 32;
static const uint32_t HEADER_HIGH_US = 4500; static const uint32_t HEADER_HIGH_US = 4500;
static const uint32_t HEADER_LOW_US = 4500; static const uint32_t HEADER_LOW_US = 4500;
static const uint32_t BIT_HIGH_US = 560; static const uint32_t BIT_HIGH_US = 560;
@ -17,12 +16,12 @@ static const uint32_t FOOTER_LOW_US = 560;
void SamsungProtocol::encode(RemoteTransmitData *dst, const SamsungData &data) { void SamsungProtocol::encode(RemoteTransmitData *dst, const SamsungData &data) {
dst->set_carrier_frequency(38000); dst->set_carrier_frequency(38000);
dst->reserve(4 + NBITS * 2u); dst->reserve(4 + data.nbits * 2u);
dst->item(HEADER_HIGH_US, HEADER_LOW_US); dst->item(HEADER_HIGH_US, HEADER_LOW_US);
for (uint32_t mask = 1UL << (NBITS - 1); mask != 0; mask >>= 1) { for (uint8_t bit = data.nbits; bit > 0; bit--) {
if (data.data & mask) if ((data.data >> (bit - 1)) & 1)
dst->item(BIT_HIGH_US, BIT_ONE_LOW_US); dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
else else
dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US); dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
@ -33,16 +32,20 @@ void SamsungProtocol::encode(RemoteTransmitData *dst, const SamsungData &data) {
optional<SamsungData> SamsungProtocol::decode(RemoteReceiveData src) { optional<SamsungData> SamsungProtocol::decode(RemoteReceiveData src) {
SamsungData out{ SamsungData out{
.data = 0, .data = 0,
.nbits = 0,
}; };
if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US)) if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US))
return {}; return {};
for (uint8_t i = 0; i < NBITS; i++) { for (out.nbits = 0; out.nbits < 64; out.nbits++) {
out.data <<= 1UL;
if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) { if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) {
out.data |= 1UL; out.data = (out.data << 1) | 1;
} else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) { } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
out.data |= 0UL; out.data = (out.data << 1) | 0;
} else if (out.nbits >= 31) {
if (!src.expect_mark(FOOTER_HIGH_US))
return {};
return out;
} else { } else {
return {}; return {};
} }
@ -52,7 +55,9 @@ optional<SamsungData> SamsungProtocol::decode(RemoteReceiveData src) {
return {}; return {};
return out; return out;
} }
void SamsungProtocol::dump(const SamsungData &data) { ESP_LOGD(TAG, "Received Samsung: data=0x%08X", data.data); } void SamsungProtocol::dump(const SamsungData &data) {
ESP_LOGD(TAG, "Received Samsung: data=0x%" PRIX64 ", nbits=%d", data.data, data.nbits);
}
} // namespace remote_base } // namespace remote_base
} // namespace esphome } // namespace esphome

View File

@ -7,9 +7,10 @@ namespace esphome {
namespace remote_base { namespace remote_base {
struct SamsungData { struct SamsungData {
uint32_t data; uint64_t data;
uint8_t nbits;
bool operator==(const SamsungData &rhs) const { return data == rhs.data; } bool operator==(const SamsungData &rhs) const { return data == rhs.data && nbits == rhs.nbits; }
}; };
class SamsungProtocol : public RemoteProtocol<SamsungData> { class SamsungProtocol : public RemoteProtocol<SamsungData> {
@ -23,11 +24,13 @@ DECLARE_REMOTE_PROTOCOL(Samsung)
template<typename... Ts> class SamsungAction : public RemoteTransmitterActionBase<Ts...> { template<typename... Ts> class SamsungAction : public RemoteTransmitterActionBase<Ts...> {
public: public:
TEMPLATABLE_VALUE(uint32_t, data) TEMPLATABLE_VALUE(uint64_t, data)
TEMPLATABLE_VALUE(uint8_t, nbits)
void encode(RemoteTransmitData *dst, Ts... x) override { void encode(RemoteTransmitData *dst, Ts... x) override {
SamsungData data{}; SamsungData data{};
data.data = this->data_.value(x...); data.data = this->data_.value(x...);
data.nbits = this->nbits_.value(x...);
SamsungProtocol().encode(dst, data); SamsungProtocol().encode(dst, data);
} }
}; };

View File

@ -1018,9 +1018,11 @@ def requires_component(comp):
uint8_t = int_range(min=0, max=255) uint8_t = int_range(min=0, max=255)
uint16_t = int_range(min=0, max=65535) uint16_t = int_range(min=0, max=65535)
uint32_t = int_range(min=0, max=4294967295) uint32_t = int_range(min=0, max=4294967295)
uint64_t = int_range(min=0, max=18446744073709551615)
hex_uint8_t = hex_int_range(min=0, max=255) hex_uint8_t = hex_int_range(min=0, max=255)
hex_uint16_t = hex_int_range(min=0, max=65535) hex_uint16_t = hex_int_range(min=0, max=65535)
hex_uint32_t = hex_int_range(min=0, max=4294967295) hex_uint32_t = hex_int_range(min=0, max=4294967295)
hex_uint64_t = hex_int_range(min=0, max=18446744073709551615)
i2c_address = hex_uint8_t i2c_address = hex_uint8_t

View File

@ -13,6 +13,7 @@ std_vector = std_ns.class_("vector")
uint8 = global_ns.namespace("uint8_t") uint8 = global_ns.namespace("uint8_t")
uint16 = global_ns.namespace("uint16_t") uint16 = global_ns.namespace("uint16_t")
uint32 = global_ns.namespace("uint32_t") uint32 = global_ns.namespace("uint32_t")
uint64 = global_ns.namespace("uint64_t")
int32 = global_ns.namespace("int32_t") int32 = global_ns.namespace("int32_t")
const_char_ptr = global_ns.namespace("const char *") const_char_ptr = global_ns.namespace("const char *")
NAN = global_ns.namespace("NAN") NAN = global_ns.namespace("NAN")