merge wiegand changes from branch

This commit is contained in:
Samuel Sieb
2023-02-09 21:42:57 -08:00
4 changed files with 54 additions and 20 deletions

View File

@@ -13,6 +13,8 @@ wiegand:
d1: 5
on_tag:
- lambda: ESP_LOGD("TEST", "received tag %s", x.c_str());
on_raw:
- lambda: ESP_LOGD("TEST", "received raw %d bits, value %llx", bits, value);
on_key:
- lambda: ESP_LOGD("TEST", "received key %d", x);
```

View File

@@ -14,6 +14,9 @@ Wiegand = wiegand_ns.class_('Wiegand', key_provider.KeyProvider, cg.Component)
WiegandTagTrigger = wiegand_ns.class_(
"WiegandTagTrigger", automation.Trigger.template(cg.std_string)
)
WiegandRawTrigger = wiegand_ns.class_(
"WiegandRawTrigger", automation.Trigger.template(cg.uint8, cg.uint64)
)
WiegandKeyTrigger = wiegand_ns.class_(
"WiegandKeyTrigger", automation.Trigger.template(cg.uint8)
)
@@ -21,6 +24,7 @@ WiegandKeyTrigger = wiegand_ns.class_(
CONF_D0 = "d0"
CONF_D1 = "d1"
CONF_ON_KEY = "on_key"
CONF_ON_RAW = "on_raw"
CONFIG_SCHEMA = cv.Schema(
{
@@ -32,6 +36,11 @@ CONFIG_SCHEMA = cv.Schema(
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(WiegandTagTrigger),
}
),
cv.Optional(CONF_ON_RAW): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(WiegandRawTrigger),
}
),
cv.Optional(CONF_ON_KEY): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(WiegandKeyTrigger),
@@ -54,6 +63,11 @@ async def to_code(config):
cg.add(var.register_tag_trigger(trigger))
await automation.build_automation(trigger, [(cg.std_string, "x")], conf)
for conf in config.get(CONF_ON_RAW, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID])
cg.add(var.register_raw_trigger(trigger))
await automation.build_automation(trigger, [(cg.uint8, "bits"), (cg.uint64, "value")], conf)
for conf in config.get(CONF_ON_KEY, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID])
cg.add(var.register_key_trigger(trigger))

View File

@@ -35,6 +35,24 @@ void Wiegand::setup() {
this->d1_pin_->attach_interrupt(WiegandStore::d1_gpio_intr, &this->store_, gpio::INTERRUPT_FALLING_EDGE);
}
bool check_eparity(uint64_t value, int start, int length) {
int parity = 0;
uint64_t mask = 1LL << start;
for (int i = 0; i <= length; i++, mask <<= 1)
if (value & i)
parity++;
return !(parity & 1);
}
bool check_oparity(uint64_t value, int start, int length) {
int parity = 0;
uint64_t mask = 1LL << start;
for (int i = 0; i <= length; i++, mask <<= 1)
if (value & i)
parity++;
return parity & 1;
}
void Wiegand::loop() {
if (this->store_.done)
return;
@@ -46,19 +64,13 @@ void Wiegand::loop() {
this->store_.value = 0;
this->store_.done = true;
ESP_LOGV(TAG, "received %d-bit value: %llx", count, value);
for (auto *trigger : this->raw_triggers_)
trigger->trigger(count, value);
if (count == 26) {
std::string tag = to_string((value >> 1) & 0xffffff);
ESP_LOGD(TAG, "received 26-bit tag: %s", tag.c_str());
int eparity = 0;
for (uint32_t i = 1 << 13; i <= (1 << 26); i <<= 1)
if (value & i)
eparity++;
int oparity = 0;
for (uint32_t i = 1; i <= (1 << 12); i <<= 1)
if (value & i)
oparity++;
if ((eparity & 1) || !(oparity & 1)) {
ESP_LOGD(TAG, "invalid parity");
if (!check_eparity(value, 13, 13) || !check_oparity(value, 0, 13)) {
ESP_LOGW(TAG, "invalid parity");
return;
}
for (auto *trigger : this->tag_triggers_)
@@ -66,16 +78,17 @@ void Wiegand::loop() {
} else if (count == 34) {
std::string tag = to_string((value >> 1) & 0xffffffff);
ESP_LOGD(TAG, "received 34-bit tag: %s", tag.c_str());
int eparity = 0;
for (uint64_t i = 1 << 17; i <= (1LL << 33); i <<= 1)
if (value & i)
eparity++;
int oparity = 0;
for (uint64_t i = 1; i <= (1 << 16); i <<= 1)
if (value & i)
oparity++;
if ((eparity & 1) || !(oparity & 1)) {
ESP_LOGD(TAG, "invalid parity");
if (!check_eparity(value, 17, 17) || !check_oparity(value, 0, 17)) {
ESP_LOGW(TAG, "invalid parity");
return;
}
for (auto *trigger : this->tag_triggers_)
trigger->trigger(tag);
} else if (count == 37) {
std::string tag = to_string((value >> 1) & 0x7ffffffff);
ESP_LOGD(TAG, "received 37-bit tag: %s", tag.c_str());
if (!check_eparity(value, 18, 19) || !check_oparity(value, 0, 19)) {
ESP_LOGW(TAG, "invalid parity");
return;
}
for (auto *trigger : this->tag_triggers_)

View File

@@ -25,6 +25,9 @@ struct WiegandStore {
class WiegandTagTrigger : public Trigger<std::string> {
};
class WiegandRawTrigger : public Trigger<uint8_t, uint64_t> {
};
class WiegandKeyTrigger : public Trigger<uint8_t> {
};
@@ -38,6 +41,7 @@ class Wiegand : public key_provider::KeyProvider, public Component {
void set_d0_pin(InternalGPIOPin *pin) { this->d0_pin_ = pin; };
void set_d1_pin(InternalGPIOPin *pin) { this->d1_pin_ = pin; };
void register_tag_trigger(WiegandTagTrigger *trig) { this->tag_triggers_.push_back(trig); }
void register_raw_trigger(WiegandRawTrigger *trig) { this->raw_triggers_.push_back(trig); }
void register_key_trigger(WiegandKeyTrigger *trig) { this->key_triggers_.push_back(trig); }
protected:
@@ -45,6 +49,7 @@ class Wiegand : public key_provider::KeyProvider, public Component {
InternalGPIOPin *d1_pin_;
WiegandStore store_{};
std::vector<WiegandTagTrigger *> tag_triggers_;
std::vector<WiegandRawTrigger *> raw_triggers_;
std::vector<WiegandKeyTrigger *> key_triggers_;
};