esprfid / esp-rfid

ESP8266 RFID (RC522, PN532, Wiegand, RDM6300) Access Control system featuring WebSocket, JSON, NTP Client, Javascript, SPIFFS
MIT License
1.36k stars 423 forks source link

Wiegand keypad support? #132

Closed koffienl closed 1 year ago

koffienl commented 6 years ago

I stumbled upon this project and it looks very promising. In some spare time I'n building something similar but it's not as extended as this project. I'm using a wiegand RFID with keypad reader in my project. Looking at the demo and source code it looks like there is no keypad support yet? Is this something that will be added in the future? Looking through the issues I also saw some questions about support for buzzer, would be a very nice to have to enable. With buzzer support you could send a command to the ESP to start buzzing so the user is notified to enter a code / tag. Also after accepting a code it could start buzzing to notify the user the system is armed.

Some code snippets I use for keypad support:"

  int timeout = 10000;
  long KeyTimer = 0;
  int keylength = 4;

  // Keep an eye on timeout waiting for keypress after starting with a *
  // Clear code and timer when timeout is reached
  if (KeyTimer > 0 && millis() - KeyTimer >= timeout)
  {
    Serial.println("Keycode timeout");
    CurrentInput = "";
  }

  // When * is pressed start keytimer to capture code
  if (String(wg.getWiegandType()) == "4" && String(wg.getCode(), HEX) == "1b")
  {
    Serial.println("Start capture keycode . . .");
    KeyTimer = millis();
  }

  // When key is pressed AND timer is running AND CurrentInput < keylength AND key is not * or #
  // Then add key to the current input
  if (String(wg.getWiegandType()) == "4" && KeyTimer > 0 && CurrentInput.length() < keylength && String(wg.getCode(), HEX) != "d"  && String(wg.getCode(), HEX) != "1b")
  {
    CurrentInput = CurrentInput + String(wg.getCode());
    KeyTimer = millis();
  }

  // When captured code equals predefined keylength, stop timer and check given code
  if (CurrentInput.length() == keylength)
  {
    Serial.println("Stop capture keycode . . .");
    Serial.println(CurrentInput);
  }

This snippet has a hardcoded length for keypad input, but you could change it to not only start with a * but also end with a # . Further this snippet uses a timeout to prevent the code to wait endless for the user to finish the pincode.

nardev commented 5 years ago

@akeilox i was able ti test it with 100 cards. However, it was short period of time. It was working fine but i had problems with adding new users, reading logs etc.

akeilox commented 5 years ago

thanks for the feedback @nardev do you think the problems you encountered was related to the flash chip quality or architecture limitations ?

ver2go commented 5 years ago

First thanks for the work and contributions. I currently have 1.0.1 working with an Essex KTP keypad. I can press *# and ESP-RFID will read the input as a single value and assign to a UID. Working exactly as I want it to. I can't tell from this feature request if this should be working without patch on 1.0.1 or not? Did I just get lucky due to how my Keypad sends the output.

Secondly, because this is working, I went ahead and purchased another wiegand keypad https://www.amazon.com/gp/product/B01MSZC2AP/ But from debug, this one is not working because of each keypress is being sent individually as a single key to esp-rfid.

My question is what is the expected behavior? If so what is the feature called so it sends as a single value from Essex keypad so I can get another (less expensive) keypad to work with ESP-RFID?

Thanks in advance.

nardev commented 5 years ago

@ver2go

If you are using the build with OFFICIALBOARD and if you want to handle keypad inputs, you can do it with this.

Add this in the top, next to other globals in main.cpp

String uid = ""; String pin = ""; // String cardid = ""; // int inputtype = 0; // rfid read or card read??? String keypadInputStack = ""; // Only for Wiegand Readers!!! int keypadInputDelay = 2000; unsigned long previousKeyTime = 0; unsigned long keypadTimer = 0; String type = "";

And add following code in rfid.esp, around line 200, instead of existing OFFICIALBOARD segment.

`#ifdef OFFICIALBOARD if (wg.available()) { if (wg.getWiegandType() == 4) { if (currentMillis - previousKeyTime >= keypadInputDelay) { keypadInputStack = ""; } previousKeyTime = millis();

ifdef DEBUG

        Serial.print("Key pressed:"); // put this in debug only!
        Serial.println(wg.getCode()); // put this in debug only!
        Serial.println("==============================="); // put this in debug only!

endif

        // If key is not ESC (27) or ENT (13) put it on stack!
                    // if ((wg.getCode() != 13) && (wg.getCode() != 27))
                    if (wg.getCode() < 10) // this way only one compare
        {
          keypadInputStack += String(wg.getCode());

                        Serial.print("STACK:"); // put this in debug only!
                        Serial.println(keypadInputStack); // put this in debug only!
                        return;
        }

                    // If the ESC (27) is pressed, then the keypadInputStack is cleared!
        if (wg.getCode() == 27) {

ifdef DEBUG

                Serial.print("Entered PIN is cancecled: "); // put this in debug only!
                Serial.println(keypadInputStack); // put this in debug only!

endif

                keypadInputStack = "";
                                    return;
        }

        // If the key is ENT (13) then the pin is complete and should be checked!
        if (wg.getCode() == 13) {

ifdef DEBUG

                Serial.print("Keypad entered PIN: "); // put this in debug only!
                Serial.println(keypadInputStack); // put this in debug only!

endif

                                    if (keypadInputStack == "") {
                                        return;
                                    } else {
                                        uid = keypadInputStack;
                                    }

                keypadInputStack = "";
                                    type = String(wg.getWiegandType(), HEX); // this as it is!!!
                                    cooldown = millis() + 2000;
        }

} else if (wg.getWiegandType() == 26 || wg.getWiegandType() == 34) {

ifdef DEBUG

        Serial.println("Card/Token swiped: "); // -
        Serial.print(wg.getCode()); // -

endif

                    // @nardev: to be used with card+pin version
        // inputtype = 2;

        uid = String(wg.getCode(), DEC); // make this cardid
        // cardid = String(wg.getCode(), DEC); // make this cardid
        type = String(wg.getWiegandType(), HEX); // this as it is!!!
        cooldown = millis() + 2000;

}
}
else
{
    delay(50);
    return;
}

endif`

That way, once you enter the pi, you need to finish it with "ENT" and it will be passed to a controller as if you swiped the card.

However, if more that 2 seconds pass between keys pressed of if you press "ESC" key, the previously entered keys/numbers will be erased.

Contact me via slact https://esp-rfid.slack.com if you get any problems while build.

ver2go commented 5 years ago

@nardev Thank you. I was able to use your patch. I'm not sure if I should report my findings here, so apologies in advance.

With my original keypad, I was able to use esp-rfid without patching. I would press *-pin code-# and then the keypad outputs to esp-rfid as wiegand 26-bit format. Keypad used: http://www.keyless.com/ktp-series-thinline-2x6/

Then I tried the Chinese ones from Amazon. Each key press would send 4 bits per keypress so it required @nardev 's patch. But the values of the key press did not match the number pressed. I think "1" was like 14 dec. "*" was 5 dec, "#" was 4 dec, so I had to change the patch. From looking at what I have, the patch, and what I ordered from Amazon, there seems to be 3 variations of how W26 is being handled by each type of keypads.

Any interest in looking into this any further? If so, let me know what I should log.

Thanks again for everyone's contributions.

nardev commented 5 years ago

@ver2go i think that you mixed wires so you got those crazy values. : )

ver2go commented 5 years ago

@nardev confirmed. User error was the cause of the crazy values on the other keypads. The final tally, I have keypad that will do 26bit burst that doesn't need patch. A keypad that does 4bit burst, one that does 8bit (W8 according to getWiegandType). All working now. Thanks.

peteshoard commented 5 years ago

Is this feature now in the latest core build?

nardev commented 5 years ago

@peteshoard no, send me an email, i'll send you the version which has that included and some more mqtt options.

frenchie71 commented 5 years ago

First of all many thanks for our great software and efforts. I have implemented and tested keypad support with my Gelikom XK1 in the stable branch of my fork of your project based on the suggestions here - feel free to use it. Unfortunately I can't submit pull requests that easily because I did a couple of changes w/r to magic numbers and initially wanted to do HMAC TOTP stuff with Pins over MQTT but abandonned it. here

omersiar commented 5 years ago

@frenchie71 Hello, thanks for your hard work. If you want to push your code to mainstream repository, you should consider working on dev branch. It still can possible to merge them on the stable branch but this will require me to do additional arrangements. Anyway, thanks in advance.

nardev commented 5 years ago

@frenchie71 please, refer the code that i have sent you as from @nardev

frenchie71 commented 5 years ago

Hi @nardev , I am not sure if I understand your request - you say that you have sent me code ? When and how did you send it ? Or are you referring to the discussions in this issue ? What exactly is your request ? Are you claiming copyright for portions of the code mentioned in this threat ?

nardev commented 5 years ago

I just opened the commits that you have made regarding the keypad and i noticed some similarities. Because i made that months ago and that is the fw that i'm shipping on the official boards.

Also i mixed you with @peteshoard so i thought you started merging that code.

Anyway, forget about that.

Regarding the arduino fixing on the current state, i don't think it's solved, also, jsonarduino had major changes. I thought those are most important to be fixed.

frenchie71 commented 5 years ago

OK, I see. I was not aware of any functionality that you may have in your official board with that regard. What I did, was to take code out of this thread, Test and improve it and put it into the commit. However, if you have developed and or published it before me, I am totally happy for you to take the credits. I just needed that functionality for my installation and I saw that nobody would push it, so I did.

nardev commented 5 years ago

@frenchie71 i definitely didn't sound ok. I'm glad that you contributed. Thnx.

I'll review and see what to add an how on top of your changes. Do you have some more things going on?

I had "type of locks" so you could use local(gpio pin), remote (http) and remote (mqtt) topic lock.

For example, that was one of changes i had.

I also wanted to make bit more decoupled situation with different segments. To separate things a bit because it's pretty messy now in the code.

Do you have email/slack. Can we discuss somewhere else?

frenchie71 commented 5 years ago

Sounds good to me, I have nothing going on in special - wrote everything on the fly - but coupling/decoupling/commenting/documentation seems to be a good approach at this stage of the project - also to help potential contributors to understand the code. I'll send you an e-mail :-)

evazzoler commented 4 years ago

Please, consider the users that don't want to use a RFID tag but pin only.

Bryan76 commented 4 years ago

Please, consider the users that don't want to use a RFID tag but pin only.

:: raises hand :: I would be one of those users. I wish to use this project but implement PIN only entrances. (obviously will need to guarantee multiple users don't pick the same PIN).

peteshoard commented 4 years ago

Please, consider the users that don't want to use a RFID tag but pin only.

:: raises hand :: I would be one of those users. I wish to use this project but implement PIN only entrances. (obviously will need to guarantee multiple users don't pick the same PIN).

I'd be happy implementing auth over MQTT separately, passing the uid /code in a kv pair and then sending back a MQTT to open the lock, could even set the delay in that message.

I'm not competent enough to compile myself, looking forward to the next release so I can upgrade.

evazzoler commented 4 years ago

I'd be happy implementing auth over MQTT separately, passing the uid /code in a kv pair and then sending back a MQTT to open the lock, could even set the delay in that message.

It is not a good idea to work synchronously with MQTT via WiFi connection. The authentication should always live on the device and MQTT should give/remove codes asynchronously only. This way your door will open even when wifi is down (for any reason, including jamming and deauth).

If you need a MQTT managed device, you can search trough the forks of this project. I remember something similar.

It would be nice if one day these very many forks were integrated into a single project. I don't understand why the situation has become so intricate.

omersiar commented 4 years ago

It would be nice if one day these very many forks were integrated into a single project. I don't understand why the situation has become so intricate.

Right, Arduino universe is not always consist from coders. I remember the first few months of this project.

I am currently working on pure REST API version of esp-rfid and probably ditch the MQTT entirely instead it will provide webhooks for events.

peteshoard commented 4 years ago

Rest will be a great edition, but I do use the MQTT door open and auth notifications to activate alarms, CCTV and insert data into a DB for display, without MQTT it won't be possible to do these things I'm guessing

omersiar commented 4 years ago

Does MQTT even reliable in your environment? I do not like the persistent connection nature of MQTT, please correct me if I'm wrong, MQTT require persistent socket connection (TCP) to the broker right?

evazzoler commented 4 years ago

Does MQTT even reliable in your environment? I do not like the persistent connection nature of MQTT, please correct me if I'm wrong, MQTT require persistent socket connection (TCP) to the broker right?

MQTT 5 was improved with a lot of feature present before but not so practical to use. They are a lot of QOS levels and a "Reconnect Handling" feature that permit to the user to manage broken connections. The "Session Present flag" may be used correctly for managing the reconnection and loos of data.

MQTT offers a lot of out-of-box features that give infinite possibility to the user. i.e. in your environment you can set different brokers, authenticated and not authenticated, public and private, and forward certain topics from one to another and/or vice-versa. They are million of mqtt libraries that are ready to be integrated everywhere (just think about nodered, php, etc.).

I think that persistent connection in a context of "access control system" is not so hard to mantain and will not introduce problems. MQTT was made for supporting a huge number of roaming clients (GPRS in "mobile" mode that loose connection every minutes) and its diffusion demonstrate that it is able to do it. Why to leave a robust, widespread, growing and well implemented protocol for adopting the old fading REST? Is it really so important to avoid well managed persistent connections?

frenchie71 commented 4 years ago

It would be nice if one day these very many forks were integrated into a single project. I don't understand why the situation has become so intricate.

hi @evazzoler , could you point me to some of the forks that have additional development please ? that would spare me the effort of scanning all 239. If I look back at myself when I started to pull stuff from Github and amend my own code I was struggling with the Github Fork-Branch-Pull Request work flow, i.e. I simply did not know how to properly submit Pull requests. Maybe it would be worth collecting the code from the forks, contacting the other coders and maybe implement back mainstream ? Happy to help here.

I am currently working on pure REST API version of esp-rfid and probably ditch the MQTT entirely instead it will provide webhooks for events.

@omersiar , With regards to MQTT / Rest API etc. I'd say it would be fatal if we removed features from the software - by my experience this will reduce the number of people using it. I think what we should maybe consider doing is open a separate threat on how to restructure the code in order to make available APIs (Socket, HTML, MQTT....) and readers etc. configurable. I had some talks around this with @nardev a couple of months ago - just thinking it would be worth opening the discussion to the community...

I mean, it would totally be OK to have a stripped down version - in a separate branch - or a separate version for the official board or for stand-alone readers with no network at all - but I would rather love to see everything streamlined in one repo than spread around... What I could imagine is adding the different build targets to the platformio file with -D defines...

frenchie71 commented 4 years ago

PS - MQTT works super duper fine in my environment ;-)

peteshoard commented 4 years ago

It would be nice if one day these very many forks were integrated into a single project. I don't understand why the situation has become so intricate.

hi @evazzoler , could you point me to some of the forks that have additional development please ? that would spare me the effort of scanning all 239. If I look back at myself when I started to pull stuff from Github and amend my own code I was struggling with the Github Fork-Branch-Pull Request work flow, i.e. I simply did not know how to properly submit Pull requests. Maybe it would be worth collecting the code from the forks, contacting the other coders and maybe implement back mainstream ? Happy to help here.

I am currently working on pure REST API version of esp-rfid and probably ditch the MQTT entirely instead it will provide webhooks for events.

@omersiar , With regards to MQTT / Rest API etc. I'd say it would be fatal if we removed features from the software - by my experience this will reduce the number of people using it. I think what we should maybe consider doing is open a separate threat on how to restructure the code in order to make available APIs (Socket, HTML, MQTT....) and readers etc. configurable. I had some talks around this with @nardev a couple of months ago - just thinking it would be worth opening the discussion to the community...

I mean, it would totally be OK to have a stripped down version - in a separate branch - or a separate version for the official board or for stand-alone readers with no network at all - but I would rather love to see everything streamlined in one repo than spread around... What I could imagine is adding the different build targets to the platformio file with -D defines...

I think that this should be turned into an extension of Tasmota, let the core of that project worry about MQTT and API stuff, then it's just additional features to slot in.

evazzoler commented 4 years ago

hi @evazzoler , could you point me to some of the forks that have additional development please ? that would spare me the effort of scanning all 239. If I look back at myself when I started to pull stuff from Github and amend my own code I was struggling with the Github Fork-Branch-Pull Request work flow, i.e. I simply did not know how to properly submit Pull requests. Maybe it would be worth collecting the code from the forks, contacting the other coders and maybe implement back mainstream ? Happy to help here.

here: https://github.com/marelab/esp-rfid

But I think it is an abandouned project. Pages on the site give a 404.

omersiar commented 4 years ago

For solely learning purposes, I am working on RESTful API version of esp-rfid. Base features are as below:

Backend

Frontend

Status: POC API boilerplate is ready. No ETA.

evazzoler commented 4 years ago

Great! I'm really excited by this news!

anethum commented 4 years ago

hello together, what is the current state.

does esp-rfid support Pins via keypad? Or only rfid via reader?

vrelk commented 4 years ago

The current code is confusing. The reader returns MSB values, but the code is checking for LSB values and it seems to work.

Reader returns 'A' while the code looks for '1b'. (*) Reader returns 'B' while the code looks for 'd'. (#)

matjack1 commented 2 years ago

Hello, I'm reviving this issue as I've added support for pincode here: https://github.com/esprfid/esp-rfid/pull/477

Each user has its own pincode on top of the RFID card.

If you have any questions let me know!

matjack1 commented 1 year ago

I'm closing this in favour of the more recent issue #492

Also now there's another PR open to cover different use cases of the pin code, here #551