MQTT-RFID Reader
Allgemein
Das Projekt beschreibt ein RFID Lesegerät welches über MQTT in einer IT-Infrastruktur für offene Werkstätten eingebunden werden kann, z. B. für die Freischaltung von Maschinen.
Ansatz:
- Mit einer RFID-Karte sich eine Person an einem Lesegerät in einem MQTT-Netzwerk identifizieren. In Abhängigkeit der damit verbundene Anwendungen können hiermit Maschinen freigeschaltet, Türen / Fächer aufgeschlossen oder Programme angesteuert werden. Dabei stellt das Lesegerät nur die Kommunikation mit der RFID-Karte und mit dem Anwender (Über ein Display) zur Verfügung. Aktuatoren und Netzschalter sind nicht vorgesehen.
Funktionsumfang:
- Lesen von UID und Identifikation von RFID-Karten verschiedener Bauart (Mifare Classic, DESFire, Ultralight C)
- Beschreiben von Mifare Classic mit einem Zeitstempel
- Kommunikation der Daten über MQTT (JSON Objekt) an Broker
- Anzeige von Statusmeldungen (intern) und Nachrichtigen (über MQTT empfangen)
- Konfiguration (Netzwerkeinstellung, Funktionalität) über HTML in Access Point Modus
- Anbindung über Wifi oder Ethernet
- Einbindung einer Taste zur Interaktion mit dem Anwender (z. B. zur Besätigung o. ä.)
- Buzzer
Aufbau:
- RC522 standard Modul
- '0.96 OLED Display
- ENC28J60 LAN Modul
- ESP-12 Modul (ESP8266)
- Interface-Platine
- 3D Druck Gehäuse
- ESP-01 Programmierer (nur zum Programmieren)
Funktion
Des Konzept lässt sich in mehrere Teilbereiche unterteilen:
1. Kommunikation mit RFID-Karten
Das Ziel ist, ein System zur Verfügung zu stellen, welches möglichst wenig anfällig für misbrauch ist, aber dennoch preiswert bleibt. Hierzu gitb es folgende Konzepte:
- Verwendung von Mifare Classic Karten - Die Karten sind klonbar und bieten daher die geringste Sicherheit
- Verwendung von Mifare Classic Karten mit Zeitstempel der in einer Datenbank abgelegt wird. Sicherer, da eine geklonte Karte nur einmal verwendet werden kann. Dannach weichen der Zeitstempel auf dem Original und dem Klon von einander ab, und das Vorhandensein zweier Karten kann erkannt werden. Das ganze setzt eine stabile Kommunikation zwischen Lesegerät und Datenbank voraus.
- Verwendung von DESFire Karten. Karten sind teuer und die Empfindlichkeit des Lesegerätes verringert sich. Die Kommunikation mit den DESFire Karten erfolgt OTA (Over The Air), d.h. der Server kommuniziert direkt mit der Karte, der Reader schiebt nur die Anfragen und Antworten hin nund her, der Reader versteht diese (teilweise verschlüsselte) Kommunikation nicht.
- Verwendung von Mifare Ultralight C Karten. Die Karten sind günstiger, auch hier leidet die Empfindlichkeit. Da auch normale Mifare Ultralight Karten geklont werden können, muss die Ultralight "C" Karte mit dem Werkstatt eigenen Schlüssel gesperrt sein. Dieser Schlüssel muss dem Reader vom Server vorher zugeschickt werden (wird also nicht auf der Reader eingespeichert).
Alle 4 Optionen werden vom Lesegerät unterstützt. Die Option kann über die Konfigurationsseite des Lesegerätes eingestellt werden.
Das Szenario, dass die Karte unerlaubt weitergegeben wird, läßt sich alleine über die Wahl der RFID Technologie lösen, daher bleibt ein gewisses Restrisiko von Missbrauch.
Zur Zeit wird die Karte einmal gelesen und dann vom Lesegerät abgeschaltet. Eine Option, dass die Anwesenheit der Karte kontinuierlich überprüft wird, könnte bei Bedarf hinzugefügt werden.
2. Kommunikation über MQTT
Das Lesegerät kann über die Konfigurationsseite entweder über LAN oder über WLAN in einem Netzwerk eingebunden werden. Die IP-Adresse des Brokers muss, zusammen mit der Geräte-ID ebenfalls manuell über die Konfigurationsseite eingegeben werden. Über standardisierte Adressen (Topics), in der die ID des Lesegerätes enthalten ist, werden Nachrichten (Payload) verschickt. Das Gerät abonniert ebenfalls ein standardisiertes Topic um Nachrichten empfangen zu können. Die Kommunikation von Nachrichten erfolgt als JSON Objekt. Nur die UID kann auch als Klartext übermittelt werden (über die Konfigurationsseite einstellbar). Nach erfolgreichem Lesen der RFID Karte wird die UID und, wenn eingestellt der alte und neue Zeitstempel an den Broker übermittelt. Das Lesegerät kann eine Reihe von standard-Nachrichten anzeigen (die intern auf das Display passend hinterlegt wurden) oder kann auch Klartext-Nachrichten empfangen und anzeigen. Hierzu enthält die empfangene MQTT-Nachricht immer ein "identifizierer" der Nachricht und eine Klartextnachricht. Je nachdem ob der Identifizierer im Lesegerät belegt ist, wird die passend formatierte Nachricht angezeigt oder die unformatierte Klartextnachricht. Jede Nachricht hat ebenfalls einen Zusatztext, mit dem zusätzliche Varibale Informationen wie Dauer, Uhrzeit, User etc. zu einer Nachricht gezeigt werden können.
JSON object = {"Cmd": "message", "MssgID": 4 , "ClrTxt":"Hello World" , "AddnTxt":"3:00"}
3. Konfiguration des Gerätes
Das Gerät verfügt über einen Eingang zum Anschluss eines Tasters. Wird diese Taste während des Bootvorgangs betätigt, startet das Lesegerät im Web-AP Modus. Nach Anmeldung in das Netzwerk (mit den im Quellcode festgelegten Daten) findet man auf der Home-Webseite des Gerätes (192.168.4.1/) eine leere Konfigurationsseite. Hier können SSID und Passwort des Werkstatt-Netzwerks, Broker-IP, Geräte-ID, LAN/WLAN und RFID Optionen definiert werden. Die Optionen werden gespeichert und werden beim nächsten Bootvorgang verwendet.
4. MQTT-Befehle und Parameter
Nachrichten werden immer als JSON paket übermittelt. Dabei ist der Befehl "Cmd" immer das erste Element. Folgende Befehle sind für "Cmd" definiert:
- "message" - Nachricht auf dem Display zeigen
- "sendPICC" - Daten an DESFire Karte im APDU format schicken
- "haltPICC" - DESFire Karte wird abgemeldet
- "Key" - Zugriffschlüssel für den Zugriff auf Mifare C Karten
- "ConfirmUser" - Reader fordert den Nutzer (durch Fiepen) auf, seine Anwesenheit bei der Maschine zu besätigen (TODO)
"message"
Nachricht auf dem Display. Beispiel: {"Cmd": "message", "MssgID": 4 , "ClrTxt":"Hello World" , "AddnTxt":"3:00"}
Befehl | Parameter | Format | Bedeutung |
---|---|---|---|
"Cmd" | "message" | String | Nachricht auf dem Display anzeigen |
"MssgID" | zahl | int | vordefinierte Nachricht anzeigen. Die Nachricht wird im QUellcode definiert. Hier wird eine, zum verendeten Display sinnvollen Zeilenumbruch definiert. |
"ClrTxt" | Freitext | String | Nachricht in Klartext. Wird ignoriert wenn die Nachricht im Reader vordefiniert ist. Ansonsten wird die Nachricht "irgendwie" auf dem Display angezeigt. |
"AddnTxt" | Freitext | String | Zusatztext, der auf dem Display angezeigt werden soll. Hier können zusätzlich zu fest definierte Nachrichten Ergänzungen wie Uhrzeit, Dauer, Nutzungskosten oder User angezeigt werden. ACHTUNG: das € Zeichen wird auf einige Displays nicht dargestellt. |
Vordefinierte Nachrichten sind:
Nr. | Anzeigetext | Zeilenumbruch | englischen Text |
---|---|---|---|
0 | "verfügbar", | 0 | equipment available |
1 | "reserviert", | 0 | equipment reserved |
2 | "reserviert ab", | 13 | reserved starting from |
3 | "in Benutzung", | 0 | equipment in use |
4 | "freigegeben", | 0 | access granted |
5 | "Anmeld. fehlgeschlagen", | 8 | login error |
6 | "Nutzungsgebühr ", | 15 | usage fee |
7 | "Nutzung nicht erlaubt", | 13 | operation not allowed |
8 | "Nutzung auf eigenem Risiko", | 11 | operation at own risk |
9 | "gesperrt durch", | 14 | equipment locked by |
10 | "freizugeben durch", | 11 | to be released by |
11 | "außerhalb der Nutzungzeit", | 14 | outside ooperating hours |
12 | "Nutzungsdauer", | 13 | duration of use |
13 | "abgemeldet", | 0 | logged out |
14 | "abschalten in", | 13 | equipment will lock down |
15 | "Karte gesperrt", | 0 | card locked |
16 | "Karte unbekannt", | 0 | card unknown |
17 | "Berechtigung endet", | 12 | training to expire |
18 | "Ruhemodus"}; | 0 | sleep mode |
"sendPICC"
Nachricht auf dem Display. Beispiel: {"Cmd": "sendPICC", "data": "9060000000"} - getVersion Befehl 0x60
Befehl | Parameter | Format | Bedeutung |
---|---|---|---|
"Cmd" | "sendPICC" | String | Daten als APDU kommando an DESFire Karte schicken |
"data" | APDU Paket | String | Komplettes APDU Paket als lesbarer Hex-Zeichen. für A bis F können Groß- oder Kleinbuchstaben verwendet werden. |
Der Reader antwortet mit einem APDU-Paket z.B. {"Cmd":"readPICC","data":"04010112001A0591AF"}. Dabei sind die letzten zwei Bytes die Statusbytes (0x91AF = es gibt noch mehr Daten -> DESFire Statusmeldungen)
"haltPICC"
Die kommunikation mit der DESFire Karte wird beendet. Dieser Befehl ist nur bei DESFire Karten notwendig, da Mifare Classic und Mifare Ultralight C Karten automatisch abgemeldet werden. Beispiel: {"Cmd": "haltPICC"}
Befehl | Parameter | Format | Bedeutung |
---|---|---|---|
"Cmd" | "haltPICC" | String | Kommunkation zwischen Reader und DESFire Karte wird beendet |
- communicate with reader - JSON object = {"Cmd": "haltPICC"}
- recieve auth Key - JSON object = {"Cmd": "Key", "data": 0123456789ABCDEF} // data in ASCII
- Confirm User attendence - JSON object = {"Cmd": "ConfirmUser"}