From 75dff341c86c36374e9544ce6a0bf99d7251f763 Mon Sep 17 00:00:00 2001 From: frickelzeugs Date: Wed, 9 Feb 2022 21:38:59 +0100 Subject: [PATCH] automatic pairing on first boot, docs updated --- README.md | 42 +++++++++++++++++++++++++----- doc/bootloader.zip | Bin 11496 -> 11723 bytes doc/images/web-wificonfig.png | Bin 34038 -> 33820 bytes src/main.cpp | 47 ++++++++++++++++++++-------------- 4 files changed, 63 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 6b56022..179adfc 100644 --- a/README.md +++ b/README.md @@ -47,11 +47,11 @@ Now that esptool.py is available you can continue to flash the firmware. To star - bootloader_dio_40m.bin - boot_app0.bin +- partitions.bin download [here](https://raw.githubusercontent.com/frickelzeugs/FingerprintDoorbell/master/doc/bootloader.zip) - firmware.bin -- partitions.bin - spiffs.bin contained in the [Release packages](https://github.com/frickelzeugs/FingerprintDoorbell/releases) @@ -119,22 +119,43 @@ When in WiFi config mode FingerprintDoorbell will act as an AccessPoint an creat -Enter your settings and click "Save and restart" to bring the device back to normal operation mode. If everything had worked the LED ring should first flash blue while bootup and starts breathing blue if connection to your wifi is running. +Enter your settings and click "Save and restart" to bring the device back to normal operation mode. If everything had worked the LED ring should first flash blue while bootup and starts breathing blue if connection to your WiFi is running. When connected to your WiFi the WebUI of Fingerprintdoorbell should be available under http://fingerprintdoorbell (if you used the default hostname in WiFi configuration). Now you can start enrolling ("teaching") your fingerprints. + +## Managing fingerprints +The sensor has the capacity for storing up to 200 fingerprints. Theses memory slots are used as ID together with a name to increase human readability. To enroll new fingerprints enter a ID and name (optional) in the "Add/Replace fingerprint" section and click "Start enrollment". Now the system asks you to place and lift your finger to the sensor for 5 times. The 5 passes of scanning helps the sensor to improve its recognition rate. Don't try to vary your placing/position too much, because the enrollment process may fail if the 5 preceeding scans differ too much from each other and cannot be combined to one fingerprint template. -## Enroll your fingerprints +If enrollment has completed successfull you can now test if your fingerprint matches. + ## Configure MQTT connection +Matching fingerprints (and also ring events) are published as messages to your MQTT broker at certain topics. For this you will have to configure your MQTT Broker settings in FingerprintDoorbell. If your broker does not need authentification by username and password just leave this fields empty. You can also specify a custom root topic under which FingerprintDoorbell publishes its messages or leave the default "fingerprintDoorbell" if you're fine with that. + -## Firmware Update -If you've managed to walk the bumpy path of flashing the firmware on the ESP32 for the first time, be calmed: every further firmware update will be a piece of cake. FingerprintDoorbell is using the really cool Library [AsyncElegantOTA](https://github.com/ayushsharma82/AsyncElegantOTA) to make this as handy as possible. You don't even have to pull the microcontroller out of the wall and connect it to your computer, because the "OTA" in "AsyncElegantOTA" is for "Over-the-air" updates. All you need to do is to browse to the settings page of the WebUI and hit "Firmware update". In the following Dialog you have to upload 2 files +| MQTT Topic | Action | Values | +| ------------------------------------ | --------- | -------- | +| fingerprintDoorbell/ring | publish | "off" by default, on a ring event switching to "on" for 1s | +| fingerprintDoorbell/matchId | publish | "-1" by default, if a match was found the value holds the matching id (e.g. "27") for 3s | +| fingerprintDoorbell/matchName | publish | "" by default, if a match was found the value holds the matching name for 3s | +| fingerprintDoorbell/matchConfidence | publish | "" by default, if a match was found the value holds the conficence (number between "1" and "400", 1=low, 400=very high) for 3s | +| fingerprintDoorbell/ignoreTouchRing | subscribe | read by FingerprintDoorbell and enables/disables the touch ring (see FAQ below for details) | + +## Advanced Actions +### Firmware Update +If you've managed to walk the bumpy path of flashing the firmware on the ESP32 for the first time, dont't worry: every further firmware update will be a piece of cake. FingerprintDoorbell is using the really cool Library [AsyncElegantOTA](https://github.com/ayushsharma82/AsyncElegantOTA) to make this as handy as possible. You don't even have to pull the microcontroller out of the wall and connect it to your computer, because the "OTA" in "AsyncElegantOTA" is for "Over-the-air" updates. All you need to do is to browse to the settings page of the WebUI and hit "Firmware update". In the following Dialog you have to upload 2 files - firmware.bin for the "Firmware" radio button - spiffs.bin for the "Filesystem" radio button Done. Reboot your system to get the new firmware live. +### Pairing a new Sensor +For security reasons the ESP32 and Sensor will be coupled together, so if the sensor is replaced (e.g. an attackers connects his own sensor to the ESP32 with his fingerprints on it) this will be detected. In this case the pairing will be marked as broken and no further match events are sent by MQTT from now on (even if you connect the old sensor again). But keep calm, the doorbell function will still continue to work and ring events are sent by MQTT so you don't miss your long awaited package delivery. You'll see an error message in the log window that requests you to renew the pairing. If the sensor replacement was done by yourself or no attack took place please choose the option "Pairing a new Sensor" to pair the sensor with the ESP32. + +### Factory Reset +As the name already says this will delete all your settings and fingerprints from the device. You'll have a blank device in WiFi Config mode when choosing this option. Be careful! + # FAQ ## What does the different colors/blinking styles of the LED ring mean? |LED ring color| sequence | Meaning | @@ -142,8 +163,15 @@ Done. Reboot your system to get the new firmware live. | red | permanent | System is in error state | | red | breathing | System in WiFi config mode | | red | flashing | Finger on sensor detected (no match found yet) | -| blue | permanent | System ready (touch ring disabled) | -| blue | breathing | System ready (touch ring enabled) | +| blue | permanent | System ready (touch ring ignored) | +| blue | breathing | System ready (touch ring active) | | blue | flashing | System startup (not ready yet) | | purple | solid | Fingerprint match found or when in enrollment mode this means pass is finished, lift your finger | | purple | flashing | Enrollment active (waiting for finger) | + +## What is the MQTT topic "fingerprintDoorbell/ignoreTouchRing" for and how to use it? +If your sensor is mounted in a dry environment and cannot be hit by rain you can skip this section. Otherwise please read further. The sensor consists mainly of two parts: the black sensor surface and a metal ring divided by the led ring around the sensor surface. The sensor surface will only recognize a finger touch if the larger part of the finger was on the sensor and not only a small tip. Also only short touches are not recognizes, because no image could be captured in this short timespan. Because a visitor who just wants to ring the bell doesn't pay particular attention to putting his finger completely on the sensor, I do not only evaluate the image sensor itself, but also consider the finger detection signal (pin 5) the sensor is providing. This signal is already triggered if you slightly touch the sensor and even if you only touch the metal ring and not yet the sensor surface. + +This ring is a capacitive touch sensor that works similar to the touch display of your smartphone. And if you may know touch displays and rain drops are not best friends, because they can lead to false inputs. This will usually be a problem if your sensor is mounted in a place exposed to rain and even if it's mounted under the roof overhang it may be hit by horizontal rain during a storm and causing false ring events. And believe me: your wife will not be happy if the storm rings on your door at 3 AM ;-) + +So after this experience I could have added an option to disable this ring permanent in the settings but I decided to go another way and make this option conditional. Why? Because in >95% of the cases I really want this high sensitivity of the sensor, just not on stormy and rainy days. Fortunately I already had the current weather conditions available in my smart home via a rain sensor. So I added the MQTT topic "fingerprintDoorbell/ignoreTouchRing" which can be set to "on" or "off". In my case OpenHAB sets this value to "on" when it's raining and wind speed is over a certain level. Since then I have had no more problems with disturbing the peace at night. \ No newline at end of file diff --git a/doc/bootloader.zip b/doc/bootloader.zip index 8879b08319b6f4e7c269daad54fa1b7f5f5a248e..d8ec0fa16b4713db215e5dfd7b709f903c0eb658 100644 GIT binary patch delta 259 zcmaD6c{+MSs7^gIiwFY)0|&#g1(|U+lwHG>kdjcrkfLE=@MOBmGL>m6i%uGI7#J{IHRv!<5fhO} zc$F@Yk|5A}Qab6Bv6-Pk22d{UUNhsLtd+I`tx~Yz#oa1cdcKI#>t90|2SS2J`>` diff --git a/doc/images/web-wificonfig.png b/doc/images/web-wificonfig.png index 7dd836797fd46f6d7b570b2b7daa4d98515f7f62..8143bfe984c72d917a2d77043ebd7b232385e3b7 100644 GIT binary patch literal 33820 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 H?MMF~lG#hl literal 34038 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 diff --git a/src/main.cpp b/src/main.cpp index 99fc6c0..d896371 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,7 +15,7 @@ enum class Mode { scan, enroll, wificonfig, maintenance }; -const char* VersionInfo = "0.2"; +const char* VersionInfo = "0.3"; // =================================================================================================================== // Caution: below are not the credentials for connecting to your home network, they are for the Access Point mode!!! @@ -149,12 +149,36 @@ void updateClientsFingerlist(String fingerlist) { events.send(fingerlist.c_str(),"fingerlist",millis(),1000); } + +bool doPairing() { + String newPairingCode = settingsManager.generateNewPairingCode(); + + if (fingerManager.setPairingCode(newPairingCode)) { + AppSettings settings = settingsManager.getAppSettings(); + settings.sensorPairingCode = newPairingCode; + settings.sensorPairingValid = true; + settingsManager.saveAppSettings(settings); + notifyClients("Pairing successful."); + return true; + } else { + notifyClients("Pairing failed."); + return false; + } + +} + + bool checkPairingValid() { AppSettings settings = settingsManager.getAppSettings(); if (!settings.sensorPairingValid) { - Serial.println("Pairing has been invalidated previously."); - return false; + if (settings.sensorPairingCode.isEmpty()) { + // first boot, do pairing automatically so the user does not have to do this manually + return doPairing(); + } else { + Serial.println("Pairing has been invalidated previously."); + return false; + } } String actualSensorPairingCode = fingerManager.getPairingCode(); @@ -177,21 +201,6 @@ bool checkPairingValid() { } -void doPairing() { - String newPairingCode = settingsManager.generateNewPairingCode(); - - if (fingerManager.setPairingCode(newPairingCode)) { - AppSettings settings = settingsManager.getAppSettings(); - settings.sensorPairingCode = newPairingCode; - settings.sensorPairingValid = true; - settingsManager.saveAppSettings(settings); - notifyClients("Pairing successful."); - } else { - notifyClients("Pairing failed."); - } - -} - bool initWifi() { // Connect to Wi-Fi WifiSettings wifiSettings = settingsManager.getWifiSettings(); @@ -482,7 +491,7 @@ void doScan() } break; case ScanResult::matchFound: - notifyClients( String("Match Found ID #") + match.matchId + " with confidence of " + match.matchConfidence ); + notifyClients( String("Match Found: ") + match.matchId + " - " + match.matchName + " with confidence of " + match.matchConfidence ); if (match.scanResult != lastMatch.scanResult) { if (checkPairingValid()) { mqttClient.publish((String(mqttRootTopic) + "/ring").c_str(), "off");