Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rfid support #146

Closed
wants to merge 21 commits into from
Closed

Conversation

Olverine
Copy link
Contributor

@Olverine Olverine commented Feb 12, 2021

RFID

RFID tags can be used to start the station. This can be done either by storing the UID of the RFID tag in the EEPROM or by sending the UID to a MQTT topic so that the station can be started remotely.

Prerequisites

In order to use RFID, a PN532 RFID scanner module is required. The module should be connected to the ESP32 board on pins 21 (SDA) and 22 (SCL). Make sure the module is set to use I2C for communication.

Set up

  • In the web gui, click the System tab
  • Toggle the “Enabled” switch in the RFID box to on

The RFID module should now be activated. When the station is paused, a message should be displayed on the LCD every few seconds saying “Scan RFID tag to start”.

RFID handling through MQTT

When the station detects an RFID tag, the unique UID of the tag will be sent to the MQTT topic: <base-topic\>/rfid. A subscriber can then authenticate the tag and start the station remotely.

Offline RFID handling

If MQTT is unavailable, RFID tags can be authenticated offline. In order to do this, the UID of any authorized tags need to be stored in advance.

Storing an authorized tag

  • In the web gui, click the System tab
  • In the RFID box, click the “Scan” button under “Manage scanned tag”
  • Place your RFID tag on the RFID scanner module
  • When the UID of the tag shows up underneath the “Scan” button in the web gui, click the “Register tag” button.

Removing an authorized tag

If the UID of the tag is known:

  • In the web gui, click the System tab
  • In the RFID box, find the UID in the list of registered tags
  • Click “Remove” to the right of the UID you would like to remove

If the UID of the tag is unknown:

  • In the web gui, click the System tab
  • In the RFID box, click the “Scan” button under “Manage scanned tag”
  • Place your RFID tag on the RFID scanner module
  • When the UID of the tag shows up underneath the “Scan” button in the web gui, click the “Remove tag” button.

@jeremypoulter
Copy link
Collaborator

Hi, thanks for the PR, RFID is a long awaited feature. Unfortunately the timer code is a bit of a problem. I have been working on major changes in that area as part of #139. In theory this should remove the need for adding the timer code from this PR, it should just be able to sit on top of the new scheduler module.

If you are willing please could you re-base your code on the jeremypoulter/issue5 branch? I appreciate that this is still pre-alpha code but would be great to include this in the new v4 firmware. Happy to help where needed.

.gitmodules Outdated Show resolved Hide resolved
src/rfid.cpp Outdated Show resolved Hide resolved
src/rfid.cpp Outdated
lcd_display("Waiting for RFID", 0, 0, seconds * 1000, LCD_CLEAR_LINE);
}

DynamicJsonDocument rfid_poll() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better to setup the JSON doc outside the function and pass it in by reference, I am not sure if returning it like this will leak memory and/or be an expensive operation (in terms of speed)

}

DynamicJsonDocument rfid_poll() {
const size_t capacity = JSON_ARRAY_SIZE(3);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you may also need to add some space for the data

src/rfid.cpp Outdated
@@ -0,0 +1,199 @@
#define STATUS_NOT_ENABLED 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we encapsulate all this in a class? I am trying to do that for all newer code to make it easier to expand, eg to support multiple chargers/RFID card readers. Not saying you have to do this now, but just sticking everything in a class makes this much easier later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would be a good idea to make it into a MicroTask?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please, but I haven't really written any documentation, so I wasn't going to insist on it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you like to take a look at the current implementation? Am I using MicroTask correctly?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can not see anything obvious wrong from a quick scan, I will take a closer look. What issues are you seeing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues. I just wanted to make sure I understand the concept correctly

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good morning,
I have been using the OpenEVSE terminal for a while with RFID. it works well.
I ordered the ESP32-gateway card for the Ethernet connection. Where should I connect my PN532 RFID to my ESP32-gateway on the ESP32-gateway? (SCL / SDA?
Thanks for your help

src/rfid.cpp Outdated Show resolved Hide resolved
Oliver Norin and others added 7 commits February 15, 2021 08:55
Voltage is used by divert mode, as well as sent along to the OpenEVSE
module for power calculations.

Setting this to zero could result in a lot of issues. The divert code
would see divide by zero happen, and the energy montoring code on the
OpenEVSE module would result in the recorded energy usage being
incorrect.

While this shouldn't happen reguarly, I found myself in this situation
by sending a null/zero-length message to the relevant topic that the
ESP32 was listening on. Because there is no error checking in the float
parsing code, a null value parsed to zero, which resulted in the voltage
value being set to zero.

An alternative here would be to reset the voltage to `DEFAULT_VOLTAGE`
if a zero or invalid value was received. As written, this will simply do
nothing and ignore the invalid/zero value.
A value between 60 and 300 volts, while being a generous range, should
prevent issues where the value read from MQTT is read as a `0` or
erroneously specified in millivolts.
@Olverine
Copy link
Contributor Author

Thank you for reviewing our PR! I will re-base the branch and try to utilize the scheduler.

@Olverine Olverine changed the base branch from master to jeremypoulter/issue5 February 18, 2021 08:20
@Olverine Olverine changed the title Rfid and timer Rfid support Feb 18, 2021
@jeremypoulter
Copy link
Collaborator

I have put I little bit more thought in this. I think this use case should be using the EVSE manager to claim/release control of the EVSE rather than using the scheduler. Unfortunately I haven't written the particular bit do do the time based charging :(

Essentially you would do something like:

  // Lock the EVSE until RFID card presented
  EvseProperties props(EvseState::Disabled);
  evse.claim(EvseClient_OpenEVSE_RFID_Off, EvseManager_Priority_Lock, props);

  if(rfid_card_presented)
  {
    EvseProperties props(EvseState::Active);
    props.setTimeLimit(duration);
    evse.claim(EvseClient_OpenEVSE_RFID_On, EvseManager_Priority_Unlock, props);
  }

This would lock the EVSE by default until a card is presented and then allow charging for a given duration and then lock it again. The downside of doing it this way is that the priority would have to be higher than every other so would disable the schedule/PV divert... Maybe that is not a downside but a feature....

Anyway I will keep you updated.

@Olverine
Copy link
Contributor Author

Olverine commented Mar 3, 2021

This would lock the EVSE by default until a card is presented and then allow charging for a given duration and then lock it again. The downside of doing it this way is that the priority would have to be higher than every other so would disable the schedule/PV divert... Maybe that is not a downside but a feature....

We have been thinking about this issue as well. Since RFID is a form of access control, there should be no other way to activate the station as long as RFID is enabled. So we are thinking that it should have a higer priority than schedule/PV divert but perhaps there should be some kind of "authenticated state" that allows the scheduler an PV divert to activate the station when a tag has been authenticated. At the moment, scanning an RFID card will activate the station regardless of scheduler and PV divert settings which is probably a bad idea. It would be better if the station is activated when an RFID tag has been authenticated AND the scheduler is allowing the station to wake up. Do you agree?

I haven't looked into how this evse.claim method works very much but do you think it would be possible to keep the station disabled if it is unlocked by RFID but still locked by the scheduler and vice versa?

@jeremypoulter
Copy link
Collaborator

That is exactly the type of thing the claim is supposed to manage. If the RFID sets a high priority claim to disable the charger then lower level priorities can not override this. I am slowly moving everything over to the priority system so this should work well.

However from your description the example I gave above is slightly wrong, it you want the charger to work as it otherwise would then you need to release the claim for a period of time (or till the end of the charging session ?) then claim again. You could do this at the higher level for sure, but let me consider if there is a way to fit this in to the EVSE manager.

@jeremypoulter jeremypoulter deleted the branch OpenEVSE:jeremypoulter/issue5 March 7, 2021 16:17
@jeremypoulter
Copy link
Collaborator

@Olverine I think this got closed because the issue5 branch was deleted after merge, please re-open targeting master

@Olverine
Copy link
Contributor Author

Olverine commented Mar 8, 2021

@Olverine I think this got closed because the issue5 branch was deleted after merge, please re-open targeting master

I can't find a way to re-open the PR. It might be a permission problem or it could be that the target branch no longer exists. It doesn't seem like I can change the target branch at this point however. Is it possible for you to re-open?

@jeremypoulter
Copy link
Collaborator

Sadly not :( @chris1howell are you able to re-open and change the target branch to master?

@chris1howell
Copy link
Member

chris1howell commented Mar 8, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants