Skip to content

[P190] Add Security - Fingerprint (Grow R503/R307) plugin - #5671

Open
alexbn71 wants to merge 24 commits into
letscontrolit:megafrom
alexbn71:feature/P190-fingerprint
Open

alexbn71 wants to merge 24 commits into
letscontrolit:megafrom
alexbn71:feature/P190-fingerprint

Conversation

@alexbn71

@alexbn71 alexbn71 commented Oct 23, 2026 •

Copy link
Copy Markdown

[P190] Security - Fingerprint (Grow R503/R307)

New plugin for the Grow fingerprint modules on a serial port: R503 (with RGB LED ring), R307, R502, ZFM-20, AS608 and compatibles. Plugin ID 190 as reserved in #3839 (see #5670).

Resolves #5670

Features

  • Recognises a finger and sends its slot ID and score to controllers and rules (<task>#ID, -1 = not recognised)
  • Enrol / delete / count / list fingers with commands; fingerprint,enroll without ID uses the first free slot
  • Enrolment progress as task value and events; JSON answers for fingerprint,list and fingerprint,enroll over HTTP
  • R503 LED ring feedback and fingerprint,led command
  • Touch detection on the WAKEUP pin, or polling
  • Non-blocking state machine, uses the ESPEasy serial helper
  • Device page shows the module state and the used templates (via TaskValuesWriterHelper)

Changes

  • src/_P190_Fingerprint.ino, src/src/PluginStructs/P190_*
  • define_plugin_sets.h: added to PLUGIN_SET_MAX (ESP32 only) and to the PLUGIN_USES_SERIAL list; Custom-sample.h entry
  • Documentation: P190.rst, commands and events (also included in the Command and Events reference), plugin list, _plugin_substitutions_p19x.repl, MAX build set overview

Testing

  • Builds with a minimal custom build (custom_ESP32_4M316k) against the current mega
  • Hardware: ESP32 with an R503 clone on HW Serial2 at 57600 baud, firmware built from mega-20260720 with this plugin (P190): recognition, enrolment at the first free slot and at a given slot, fingerprint,list, fingerprint,delete, fingerprint,led and the automatic LED ring feedback. Not tested on hardware: fingerprint,deleteall.
  • Documentation builds with Sphinx without new warnings.

Notes / questions

  • Category: new Security category in _plugin_categories.repl and _Plugin.rst (as suggested in the review).
  • Build sets: only MAX for now. Let me know if it should go into a COLLECTION set as well.
  • The code was written with the help of an AI assistant (Claude), then built, tested on hardware and reviewed by me.

New plugin for the Grow fingerprint modules on a serial port: R503 (with RGB
LED ring), R307, R502, ZFM-20, AS608 and compatibles. Plugin ID 190 as
reserved in letscontrolit#3839 (see letscontrolit#5670).

- Recognise a finger: slot ID and score to controllers and rules
- Enrol (first free slot or given slot), delete, count and list fingers with
  commands, JSON answers over HTTP for list and enroll
- Enrolment progress as task value and events
- R503 LED ring feedback and fingerprint,led command
- Touch detection on the WAKEUP pin, or polling; non-blocking state machine
- Added to PLUGIN_SET_MAX (ESP32) and the PLUGIN_USES_SERIAL list
- Documentation: plugin page, commands, events, plugin lists

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tonhuisman

Copy link
Copy Markdown
Contributor

Great, I'll have a look at the code asap.
One thing that makes developers life on GH easier is coupling this PR to the issue, so the issue will auto-close on merge, by adding a line in the opening message with Resolves #5670 👍

@alexbn71

Copy link
Copy Markdown
Author

Done, thanks! The PR now resolves #5670.

Comment thread docs/source/Plugin/_plugin_categories.repl Outdated
Comment thread docs/source/Plugin/_plugin_sets_overview.repl Outdated
- New Plugin_Security category with P190 and a matching Security section in
  the plugin list, instead of listing it under RFID
- Drop the hand-added row from _plugin_sets_overview.repl, it is regenerated
  for ReadTheDocs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/src/PluginStructs/P190_data_struct.h Outdated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/src/PluginStructs/P190_protocol.h Outdated
Comment thread src/src/PluginStructs/P190_protocol.h
P190_protocol.h now holds only the constants and the declarations. The .cpp
is built with the plugin (USES_P190), or on its own with P190_HOST_TEST for
the host unit tests of the protocol.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/_P190_Fingerprint.ino Outdated
The serial GPIOs must be selected in the settings like for the other serial
plugins; drops the settings page script, the defaults applied on save and on
init, and the related documentation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/_P190_Fingerprint.ino Outdated
Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
At most P190_MAX_READ_BYTES (64, a full acknowledge is 52 bytes) are handled
per call, and dropping stale bytes before a command only reads those already
received, so a module (or noise) that keeps sending can't block ESPEasy. A
missing acknowledge still ends with the response timeout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/src/PluginStructs/P190_data_struct.cpp
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tonhuisman

Copy link
Copy Markdown
Contributor

There is one thing missing still, but it's not very obvious: Source formatting. (It's mentioned in the developer documentation though)
We use Uncrustify for (C++) source formatting. and that involves installing an extra tool, uncrustify, either on Windows, Mac or Linux/WSL. And setting it as the default formatting tool in VSCode (should work also in VSCode-derived AI harnesses like Cursor, Codex, etc.).
When configured correctly, it will add quite some formatting changes. Formatting can be done in VSCode by using the standard shortcut <Alt>-<Shift>-F

Formatted with the repository uncrustify.cfg (Uncrustify 0.79). One-line
loops and case statements are written on several lines, and the jobs
without parameters use a startJob(event, P190_Job) overload, so the
formatter output stays readable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread docs/source/Plugin/P190.rst Outdated
Comment thread docs/source/Plugin/P190.rst Outdated
@alexbn71

Copy link
Copy Markdown
Author

Thanks for the hint! I installed Uncrustify (0.79) and formatted the sources with the repository uncrustify.cfg in f99f6bc. A few one-line loops and case statements were rewritten so the formatted code stays readable.

Comment thread docs/source/Plugin/P190.rst
alexbn71 and others added 2 commits October 23, 2026 22:59
Any GPIO works for the serial port on ESP32, so the wiring table and the
Sensor section no longer suggest GPIO numbers. The docs now say that the
polling interval is the plugin's Scan interval setting (msec) and why the
regular task Interval isn't used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- PLUGIN_GET_DISCOVERY_VTYPES with the per-value custom VType, as in P026
- Screenshot of the Device Configuration page in the documentation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread docs/source/Plugin/P190_commands.repl Outdated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
…y size

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/src/PluginStructs/P190_data_struct.cpp
Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
…IDs, boolToString()

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
@tonhuisman

Copy link
Copy Markdown
Contributor

A request to keep stuff a bit organized: Can you resolve the comments that you've resolved/fixed/improved/etc.?

Comment thread src/src/PluginStructs/P190_data_struct.cpp Outdated
Comment thread docs/source/Plugin/P190.rst Outdated
…elling

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alexbn71

Copy link
Copy Markdown
Author

Sure, done: I resolved the threads that are fixed. The one about the minimum score is still open, as there I only partly followed your suggestion (see my reply there), so I leave that to you.

Comment thread docs/source/Plugin/P190.rst Outdated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/_P190_Fingerprint.ino Outdated
alexbn71 and others added 2 commits October 24, 2026 21:52
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tonhuisman

Copy link
Copy Markdown
Contributor

There are a few features that aren't available in the plugin, not sure if you have planned to add them, as they can be a bit tricky, or even risky, to implement, so don't start Claude yet 😃 but let's first discuss this:

  • Setting a different baud rate for the sensor
  • Changing the module address
  • Changing the password (and handling the required verify)

The baud rate and module address aren't that hard to implement, and they should also properly take care of updating the settings.
Changing the module address will allow to use multiple sensor on the same serial port, as long as they use the same serial settings.
Changing the password must be handled rather carefully, as it requires the password to be verified, and can cause the sensor to be bricked if you lose that password. And bricking could also happen if you lose the changed module address.

NB: There parameters are stored in flash memory in the sensor, and there is no way to do a factory reset on the sensor, so only a lucky guess or a brute-force trial and error, until the correct module address or password is found, can revive it.

These changes to the sensor configuration can also be set from an external application (Windows or mobile-app only, AFAICS), but come with the same risks, and should then also be updated in the plugin configuration.

@alexbn71

alexbn71 commented Oct 25, 2026 •

Copy link
Copy Markdown
Author

Thanks for raising this, I hadn't planned them for this first version, on purpose:

  • Baud rate: the safest of the three, as a mismatch can be recovered by trying the 5 possible rates. I'd add it in a follow-up PR, together with an automatic baud detection at init, so a module set to another rate (e.g. by the vendor app) is still found.
  • Address and password: as you say, losing either one bricks the module, so I'd rather not offer them from the web UI for now. They can be set with the vendor tools, and the plugin already has the matching Password and Address settings. I'll make the docs clearer about that, including the risk.
  • Multiple sensors on one serial port: with a plain UART the TX outputs of the modules would drive the same line, so it would need extra hardware (diodes / open drain), I don't think it's a common use case.

If you prefer to have any of them in this PR, let me know.

Docs updated in 51f76a1: the plugin settings say that baud rate, password and address must match the module and are not changed by the plugin, plus a warning about losing the password or address.

…lugin

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

[Plugin] P190 Fingerprint – Grow R503 / R307 / AS608 fingerprint readers (ESP32)

3 participants