Skip to content

Commit

Permalink
automatic pairing on first boot, docs updated
Browse files Browse the repository at this point in the history
  • Loading branch information
frickelzeugs committed Feb 9, 2022
1 parent dfb2f27 commit 75dff34
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 26 deletions.
42 changes: 35 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -119,31 +119,59 @@ When in WiFi config mode FingerprintDoorbell will act as an AccessPoint an creat

<img src="https://raw.githubusercontent.com/frickelzeugs/FingerprintDoorbell/master/doc/images/web-wificonfig.png" width="300">

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
<img src="https://raw.githubusercontent.com/frickelzeugs/FingerprintDoorbell/master/doc/images/web-manage.png" width="300">

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.

<img src="https://raw.githubusercontent.com/frickelzeugs/FingerprintDoorbell/master/doc/images/web-settings.png" width="300">

## 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 |
| -------- | -------- | -------- |
| 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.
Binary file modified doc/bootloader.zip
Binary file not shown.
Binary file modified doc/images/web-wificonfig.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 28 additions & 19 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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!!!
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit 75dff34

Please sign in to comment.