Anwesenheitserfassung mittels RFID und Raspberry

  • Hallo zusammen,
    ich bin aktuell noch nicht sonderlich erfahren im Umgang mit Raspberrys und hoffe deshalb vorab zu meinem Projekt Unterstützung zu finden. Die letzten Tage habe ich mich schon in diversen Foren informiert und jetzt folgendes vor:



    Mein Raspberry ist mit einer Antenne zum lesen von RFID-Transpondern verbunden. Dabei wird der folgende Standard verwendet I-Code SLI ISO15693 13,56 MHz.
    Ich möchte nun quasi einen Anwesenheitserfassung basteln.
    Dabei soll die jeweilige Personen ihren RFID-Transponder an die Antenne halten und dabei auf an- oder abwesend geschaltet werden.
    Diese Information soll dabei nach Möglichkeit auf einen Laptop in eine Excel oder CSV-Datei gespeichert werden.


    Im Idealfall, wird dann die Person beim ersten einlesen über die Antenne in der Liste angelegt. Beim erneuten scannen des Transponders soll dann nur noch der Status zwischen "anwesend" bzw. "abwesend" hin und her wechseln.


    Wie gehe ich dieses Projekt am besten an? Wie erreiche ich es, dass der Raspberry die Informationen in die Datei auf dem Laptop schreibt? Kennt sich zufällig jemand mit vergleichbaren Projekten aus und kann mir nützliche Tipps geben?


    Vielen Dank im Voraus
    Gruß Chester :)

  • Hallo,


    auf dem Transponderchip ist standardmäßig sowieso nur eine ID Nummer gespeichert.
    Bei erstmaligen verwenden Bedarf es dadurch sowieso ein "Registrierungsverfahren" um die Information zur Person in der Datenbank bzw. CSV Datei zu hinterlegen.
    Bei meinem Projekt für den RFID Reader RC522 benutze dieses Python Modul


    Nachdem du die Chip angelegt hast, musst du über dein Skript den aktuellen Stand erfassen (anwesend|abwesend) und es dementsprechend ins gegenteilige abändern und wieder speichern, nachdem ein Chip an den Reader gehalten worden ist. Wie genau, das hängt davon ab wo die Dateien gespeichert werden. CSV, toml, sqlite etc.


    Warum willst du die Datei lokal auf ein Notebook ablegen?
    Somit müssen immer Notebook und Raspberry Pi zugleich laufen damit dein System funktioniert.
    Wäre es nicht besser die Datein auf dem Pi zu speichern, und bspw. via Samba dem Notebook zur Verfügung zu stellen.

  • Hallo Hofei,


    vielen Dank für die schnelle Antwort.
    Kann ich das Python Modul was du in deinem Projekt verwendet hast auch verwenden?


    Die Datei kann ruhig auf dem PI liegen und das Notebook greift dann auf die Datei zu. Das Notebook dient quasi nur als Oberfläche um sich dort anzeigen zu lassen, welche Karten bzw. damit verbundene Personen sich im Status anwesend bzw. abwesend befinden.
    Das Notebook wird also so oder so zeitgleich laufen. Jetzt ist nur die Frage was von der Umsetzung her leichter oder sinnvoller ist?


    Gruß Chester

  • Hallo Chester.


    herzlich willkommen im Forum.


    Schu dir mal die folgende Anleitung an: https://codingworld.io/project/rfid-grundlagen


    da ist, wie ich finde, ziemlich gut beschrieben wie mit dem RFID-Leser und den entsprechenden Karten umgegenagen werden kann.


    Das Thema: [Andere] Alarmanlage mit RFID steuern Wie? geht einen ziemlich ähnlichen Weg, da habe ich auch noch dreiDatein hinzugefügt welche ich selber verwende (Tür ver- und entriegeln, Sowie Karten beschreiben und auslesen)


    Darf ich fragen wleche Informatinene du benötigst? immer nur den aktuellen (Angemeldet / abgemeldet) oder möchtest du die vergangenheit auch noch wissen?


    Falls du die Vergangenheit noch wissen möchtest empfehle ich dir das ganze in einer DB zu speichern.


    Ist die Übertragung /Abfrage auf ein Laptop zwingend nötig? Reicht es nicht aus, wenn man vom Netzwerk auf den Pi zugreift und so die Stati sieht?


    Hoffe das diese Fragen Tipps hilfreich sind und du etwas weiter kommst, falls du weitere Fragen hast, einfach fragen.


    Gruss Dani

  • Hallo Dani,


    vielen Dank für die Anleitung. Allerdings ist mein Projekt etwas eingeschränkt, da die Antenne für I-Code SLI ausgelegt sein muss und ich deshalb einen etwas anderen Aufbau verwende. Trotzdem kann ich viel davon gebrauchen, danke.
    Die Vergangenheit ist nicht wichtig, vorerst werde ich versuchen einfach mit den zwei Status "anwesend" und "abwesend" zu arbeiten. Sollte ich in dem Projekt noch weiter voran kommen, könnte man es erweitern und evt. noch zeiten einbauen, wie zum Beispiel "Abwesend für 30 Minuten" usw.
    Die Abfrage mit einem Laptop ist nicht zwingend notwendig, ich bin nur damals davon ausgegangen, dass es so am leichtesten ist. Man kann natürlich auch die Informationen auf dem PI speichern und diese von dort über einen Monitor oder ähnliches ausgeben.
    Die Lösung soll als standalone Lösung gedacht sein, der Raspberry muss bzw. soll nicht unbedingt im Netzwerk sein. Eine Ausgabe wo man den aktuellen Status der Person/ RFID-Karte sehen kann reicht völlig.


    Gruß Chester

  • Sali Chester.


    Also wenn du es als Stand-Alone Lösung betreiben willst, dann würde ich definitiv alles über den PI laufen lassen, je nach dem wie viel informationen angezeigt werden müssen kannst du dasoffizielle 7" Touch Display verwenden.


    Gruss Dani

  • Quote from "Chester1191" pid='295278' dateline='1502689608'

    Kann ich das Python Modul was du in deinem Projekt verwendet hast auch verwenden?


    Sofern dein RFID Leser dafür geeignet ist - natürlich :thumbs1:
    Ist ja auch nicht mein privates Modul, sondern dieses hat auch jemand anders geschrieben und zur Verfügung gestellt.



    Quote

    Also wenn du es als Stand-Alone Lösung betreiben willst, dann würde ich definitiv alles über den PI laufen lassen, je nach dem wie viel informationen angezeigt werden müssen kannst du dasoffizielle 7" Touch Display verwenden.


    Genau, und mit tkinter oder ähnlichen kannst du dir deine GUI zur Anzeige mit Python erstellen.

  • Vielen Dank für eure Hilfe und die ganzen Tipps.
    Ich werde jetzt alles auf dem Raspberry laufen lassen. Ich denke das sollte die beste Möglichkeit sein.


    Ich bin mit meinem Projekt auch schon ganz gut vorangekommen. Aktuell liest mein Reader / Raspberry die Transponder aus und schreibt den Code in eine CSV-Datei. Leider überschreibt die Schleife aber immer wieder die Nummer in der CSV. Kann mir dabei jemand helfen und weiß vielleicht, wie ich es schaffe die Zeilen in der CSV mit hoch zu zählen. Der dafür wichtige Quellcode habe ich mal gepostet. Dabei wird wenn die variable returnid nicht leer ist, die returnid in der Konsole ausgegeben und in die CSV-Datei geschrieben. Danach wird nur noch eine Blaue LED an und aus gemacht damit man sieht das der Reader reagiert.


  • Fehlt hier nicht ein Teil des Codes?


    Dir ist bewusst dass "wb" das csv file jedesmal überschreibt, wenn du an die Codezeile angelangst?

    Code
    with open("/test/test.csv", "wb") as csv_file:



    Nachtrag folgt bald, bin gerade für dich was am testen
    Automatisch zusammengefügt:[hr]
    Versprochener Nachtrag:


    Folgende Fragen musst du dir stellen:

    • Soll nach jedem RFID Zugriff die CSV (nennen wir so aktuell mal so) sofort aktualisiert werden oder reicht es bspw. auch jede Minute sofern ein Zugriff stattfand (kann unter umständen den Schreibzugriff reduzieren)
    • Was passiert bei einem Neustart? Alle User ausgeloggt oder alter Status von der Datei. Sofern wieder Frage 1 muss die Datei sofort aktualisiert werden?


    Dies hat bestimmte Auswirkungen, wann man die Funktion zum schreiben der Datei aufruft.


    So nun zum Dateityp, habe das gerade nochmals getestet. In meinen Augen würde sich für dich sehr gut das toml Modul eignen. Toml Format Allgemein


    Beispiel zum toml File einlesen:

    Code
    with open("testfile.toml") as tomlfile:
       rfid_dict = toml.loads(tomlfile.read())


    Beispiel zum toml File schreiben:

    Code
    with open("testfile.toml", "w") as file:
    ausgabe = toml.dumps(rfid_dict)
       file.write(ausgabe)


    Achtung, Skript und toml File müssen sich im selben Ordner befinden, ansonsten Pfadangabe ergänzen


    Ein toml File ist, wie ich finde, mit einem normalen Editor sehr gut lesbar, weshalb es überflüssig wird eine CSV zu schreiben. (Beispiel im Anhang)
    Mit dem Lesebefehl kannst du den Inhalt des tomlfiles in eine Variable ablegen, welche man wiederum über Dictonarys gezielt anzeigen und bearbeiten kann.
    Genau das ist der Punkt warum ich finde, dass sich dies für dich gut eignen würd. Ich versuch das ganze wiederum in ein Codebeispiel zu zeigen was ich meine:


    Auch hast du hierbei die Möglichkeit, dir entweder eine Chipregistierfunktion zu programmieren, oder aber du änderst/ergänzt die tomldatei mit dem Editor wenn du neuen Benutzer anlegen möchtest
    Auch hast du natürlich die Möglichkeit noch mehr Daten zu hinterlegen, wie z.B wann gekommen|wann gegangen soetwas fällt aber dann unter Zeiterfassung und muss natürlich sofern betrieblich mit Betriebsrat abgesprochen sein :thumbs1:


    Für weiter Fragen oder Hilfestellungen stehe ich gerne zur Verfügung



    Hoffe ich habs einigermaßen verständlich rüber gebracht... :geek:



    Da der Dateityp toml als Anhang nicht erlaubt ist, hier der Inhalt der Datei:
    [code=php][123]
    name = "Max Mustermann"
    status = 0
    [456]
    name = "Max1 Mustermann1"
    status = 0
    [/php]
    Einfach kopieren, mit Notepad++ (oder ähnlichen) eine neue Datei erstellen mit dem Namen "testfile.toml" und den Inhalt einfügen um obiges Beispiel ausprobieren zu können

  • Hallo Hofei,


    vielen Dank für die ausführliche Antwort und das Angebot das ich bei Fragen weiter auf dich zukommen kann.


    • Um deine zwei Fragen zu beantworten, ich denke es ist sinnvoll die Datei immer sofort zu aktualisieren und den Status zu hinterlegen.
    • Beim Neustart können die hinterlegten Status ihren Zustand behalten, es muss also nicht noch extra jeder ausgeloggt werden.


    Ich hab leider aktuell Probleme deinen Programmcode komplett zu verstehen und in mein Programm zu integrieren.
    Vorab nochmal kurz wie ich es jetzt lösen möchte. die TOML-Datei kann ich vorab erstellen, das heißt ich würde dort die UID der Transponder mit dem Namen der Leute hinterlegen. Das Programm müssten dann nur noch den Status ändern und die automatische Registrierfunktion wäre erst mal raus.


    Nun zu meinen Fragen zum Code.

    • Ich bekomme aktuell immer den Fehler "ImportError: No module named toml" muss ich hier vorab noch was machen oder reicht im Python-Code die Zeile "import toml"?
    • Habe ich deinen Programmcode richtig einen vorhanden Code eingesetzt? Vorallem mit der Funktion war ich mir nicht sicher ob ich das richtig gemacht habe. Muss mich dabei unbedingt noch besser einlesen da mir dort einiges an Verständnis fehlt. Ich poste nochmal meinen Code, vielleicht kannst du mir ja erneut helfen :-).



    Vielen Dank für alles
    Gruß Chester

  • Quote from "Chester1191" pid='296221' dateline='1503303040'
    • Ich bekomme aktuell immer den Fehler "ImportError: No module named toml" muss ich hier vorab noch was machen oder reicht im Python-Code die Zeile "import toml"?


    Hast du das Modul schon vorab installiert?

    Code
    pip3 install toml


    Alles weitere schauen wir uns dann danach an

  • Hey ;),
    Habe es jetzt erneut installiert und jetzt kommt der Import-Fehler nicht mehr. Denke der Fehler geht auf mich, hatte vorher probleme mit der Internet-Verbindung weshalb die Installation nicht funktioniert hat :wallbash: .


    Somit kann es weitergehen ;-), wenn du schon in den Programmcode von mir rein geschaut hast, wirst du mit Sicherheit erkannt haben, dass ich das mit den Funktionen nicht ganz verstanden habe. Ebenso mit der rfid_dict, dort befinden sich dann irgendwann alle hinterlegten UIDs der Tabelle?


    LG Chester

  • Hast du eventuell mit pip und nicht mit pip3 installiert?


    Ist der Code von dir selbst geschrieben?


    Ja, rfid_dict ist ein Dictionary, dieses beinhaltet alle Informationen aus dem toml File.


    Am besten du spielst dich mal mit jupyter notebook o.ä. um das Verhalten der einzelnen Schritte zu erkennen.


    Hast du noch Fehlermeldungen? Was funktioniert im Detail nicht? Was ist dir unklar um selbst zu einer Lösung zu kommen?

  • Ich hab pip installiert - nicht pip 3 - ist das ein Problem?


    Der Code ist zum Teil von mir und zum Teil von einem Programm was eine Zugangskontrolle per RFID steuert.


    Jupyter Notebook werde ich mir dann mal in Ruhe anschauen, Danke für den Tipp.


    Unklar sind mir leider ein paar Dinge: (Ich beziehe mich auf deinen Code von unten)

    • Wofür genau brauch ich die Funktion und was genau muss alles in ihr drin stehen? Die Funktion schreibt also den Zustand 1 oder 0 zur entsprechenden UID in die TOML-Datei? Warum kann man den Schreibbefehl nicht einfach weiter unten mit aufrufen?
    • Wann genau sollte das Programm die TOML-Datei auslesen? Noch in der Funktion oder weiter unten, bevor dann die Schleife mit der Abfrage des Zustandes aufgemacht wird?
    • In deinem Beispiel schreibst du "uid = str(123)", das bedeutet doch, dass die Schleife nur den Eintrag bei [123] also Max Mustermann kontrolliert oder? Bei mir müsste ich das ja so dynamisch hin bekommen, dass die Schleife alle hinterlegen UIDs durchgeht. Oder hab ich da grundsätzlich was komplett falsch verstanden. (Beispiel für eine UID auf meinem Transponder E004015047686EA8)


    Hoffe du kannst mir hierbei noch weiterhelfen. Ich versuche selbst mein bestes aber leider ist es mein erstes Projekt mit dem Raspberry und Python, somit bin ich leider doch auf relativ viel Hilfe angewiesen.

  • Quote from "Chester1191" pid='296258' dateline='1503318859'


    Ich hab pip installiert - nicht pip 3 - ist das ein Problem?


    pip = Python2.x
    pip3 = Python3.x
    weiter Infos zu pip



    Quote from "Chester1191" pid='296258' dateline='1503318859'

    Der Code ist zum Teil von mir und zum Teil von einem Programm was eine Zugangskontrolle per RFID steuert.


    Was mir bei deinem Code noch etwas unklar ist, für was wird ein TCP Server benötigt? Für was Threading und Sockets?


    Quote from "Chester1191" pid='296258' dateline='1503318859'


    Unklar sind mir leider ein paar Dinge: (Ich beziehe mich auf deinen Code von unten)

    • Wofür genau brauch ich die Funktion und was genau muss alles in ihr drin stehen? Die Funktion schreibt also den Zustand 1 oder 0 zur entsprechenden UID in die TOML-Datei? Warum kann man den Schreibbefehl nicht einfach weiter unten mit aufrufen?
    • Wann genau sollte das Programm die TOML-Datei auslesen? Noch in der Funktion oder weiter unten, bevor dann die Schleife mit der Abfrage des Zustandes aufgemacht wird?
    • In deinem Beispiel schreibst du "uid = str(123)", das bedeutet doch, dass die Schleife nur den Eintrag bei [123] also Max Mustermann kontrolliert oder? Bei mir müsste ich das ja so dynamisch hin bekommen, dass die Schleife alle hinterlegen UIDs durchgeht. Oder hab ich da grundsätzlich was komplett falsch verstanden. (Beispiel für eine UID auf meinem Transponder E004015047686EA8)


    Zu Frage 1:
    Du hast jetzt nur meine 2 Codebeispiele zu einer Funktion zusammengefügt, beides sind 2 unterschiedliche Sachen, das eine benötigst du zum schreiben einer toml Datei das andere zum lesen der toml Datei.
    Da du den Schreibbefehl öfters als 1 mal benötigst ist es sinnvoller dafür eine Funktion zu erstellen, und wenn man den Befehl benötigt nur die Funktion aufzurufen


    Zu Frage 2:
    Die Tomldatei musst du bei start deines Programmes auslesen, während des Programms muss sie geschrieben werden damit zu jeder Zeit (wie von dir gewünscht) die Daten nach neustart wieder zur Verfügung stehen


    Frage 3:
    Ja die UID mit "123" ist ein Beispiel, dieses muss natürlich mit einer Variable ersetzt werden, welche dein RFID Reader dann ermittelt. So wie du eben schon geschrieben hast z.B: E004015047686EA8


    Zur Ermittlung deiner UID (Transponder Nummer) kann ich dir direkt nicht helfen, ich habe bei meinem Projekt dieses hier verwendet: ebay: RC522
    Welches Produkt hast du? Sollte das auslesen nicht gelingen, wäre es eine Option für dich ebenfalls dieses Modul einzusetzen?


    Grundsätzlich weiteres, da dies ja dein erstes Projekt ist....
    solltest du generell Intresse am Python Programmieren haben hier mal eine Seite wo du gut die grundlegenden Sachen erlernen kannst:


    Mein Einstieg wurde damals zum Python3 programmmieren begleitet von:
    https://cscircles.cemc.uwaterloo.ca/de/
    Dort werden die Basics sehr verständlich erklärt, und dazu immer wieder Aufgaben gestellt. Außerdem sieht man hier anfangs auch mal wie sich die Variablen etc. Schrittweise verändern.
    Kann ich dir zu Beginn nur Empfehlen.


    Als Nachschlagewerk verwende ich meist diese 2 Bücher:
    https://www.rheinwerk-verlag.de/python-3_3789/
    https://www.amazon.de/Raspberry-umfassen...e+handbuch (Affiliate-Link)

  • Quote

    pip = Python2.x / pip3 = Python3.x


    Dann ist pip ja für mein Projekt richtig.


    Quote

    Was mir bei deinem Code noch etwas unklar ist, für was wird ein TCP Server benötigt? Für was Threading und Sockets?


    Ich werde sie gar nicht brauchen, das sind Überbleibsel von dem Programm was ich quasi als Basis für mein Projekt genommen habe. (Vorteil an dem Programm ist das es mit meinem Reader läuft und somit die UIDs ausliest)


    Quote

    Sollte das auslesen nicht gelingen, wäre es eine Option für dich ebenfalls dieses Modul einzusetzen?


    Das auslesen gelingt! Wenn einen Transponder an den Reader halte wird die UID in der Konsole ausgegeben. Hab auch eine Version wo die UID ausgegeben wird und er sie in die CSV-Datei schreibt. Danach hab ich dann angefangen auf deinen Rat es mit der TOML-Datei zu versuchen. Das funktioniert allerdings leider noch nicht. Zusätzlich glaub ich das der RC522 kein I-Code SLI unterstützt, was für mein Projekt notwendig ist.


    Quote

    Grundsätzlich weiteres, da dies ja dein erstes Projekt ist....
    solltest du generell Intresse am Python Programmieren haben hier mal eine Seite wo du gut die grundlegenden Sachen erlernen kannst:


    Ich habe definitiv Interesse mich damit zu beschäftigen und hoffe ich werde auch noch einiges lernen. Was ich allerdings leider auch dazu sagen muss: ich denke, dass ich mich als erstes Projekt mit dieser Aufgabe wahrscheinlich übernommen habe. Ich hätte besser erstmal kleiner Projekte angehen sollen um so die Basics und das Grundverständnis leichter zu erlernen.


    Jetzt habe ich allerdings das Projekt angefangen und möchte es auch gerne Fertig bekommen :thumbs1: . Ich hoffe ich stell nicht zu dumme Fragen oder belästige dich/euch zu viel. Der Stand aktuell ist, dass die UIDs ausgelesen werden und somit der Reader funktioniert. Sollten wir es jetzt noch schaffen, dass in der TOML-Datei der Status zu hinterlegten UID umgeschaltet wird und dementsprechend die Ausgabe ist, wäre ich schon sehr zufrieden. Ich hoffe du / ihr helft mir dabei noch weiterhin so gut :helpnew: .
    Ich werde jetzt nochmal was versuchen und dann ggbf. nochmals konkret dazu Fragen.


    Vielen Dank für all die Hilfe bist jetzt :danke_ATDE: .

  • Ok dann versuchen wir es so:
    Poste nochmal den Code welcher lauffähig ist, ohne die Versuche mit toml oder csv. Versuche auch gleich die ganze unnötigen Sachen zu entfernen. Anschließend arbeiten wir uns gemeinsam Schritt für Schritt ans Ziel.


    Den Code bitte mit Kommentaren versehen, insbesondere an der Stelle wo die uid im wie variable übergeben wird.


    PS Die Grundlagen (beispielsweise auf der genannten Seite) zu erlernen schadet trotzdem nicht, so kommen wir auch leichter zum Ziel deines Projektes


    PPS jedlicher Code von mir bezieht sich auf Python3

  • Hey Hofei, vorab schonmal vielen vielen Dank. Finde es echt super, dass du mir so bei meinem Projekt hilfst!!! Die Grundlagen werde ich mir auf jeden Fall noch anschauen und aneignen, das nächste Projekt will ich mit deutlich weniger Fragen schaffen ;-).


    Hier ist der Code der aktuell lauffähig ist. Alle unnötigen Sachen die nicht die Funktion beeinträchtigen wurden von mir entfernt. Jedoch werden bestimmt noch Teile drin sein die raus können, allerdings habe ich es nicht geschafft diese zu entfernen ohne das Programm dabei zu beschädigen. (Zum Beispiel das mit dem mysocketserver).
    Den Code habe ich soweit es mir möglich war kommentiert.


  • NACHTRAG:


    So ich bin ein bisschen weitergekommen ;-). Das Programm läuft jetzt und gibt den richtigen Status in der Konsole aus :bravo2: .
    Zu diesem Erfolg wäre ich ohne dich nicht gekommen, dafür erneut vielen Dank.


    Solltest du die Zeit finden, wäre es super wenn du dir das Programm mal anschaust und überflüssige Passagen mit mir diskutierst bzw. streichst.
    Bin mal gespannt wo mich mein Projekt noch hinführt ;) .


    Hier das lauffähige Programm:


    Wenn das Projekt fertig ist, bin ich gerne bereit eine Zusammenfassung zu schreiben wovon auch andere User mit ähnlichen Projekten im Forum profitieren können.

  • Versuch mal ob dies lauffähig ist


    Auch noch vll n kleiner Hinweis für dich, solange programmiere ich selbst auch noch nicht :angel:
    Fehlermeldung kannst du mir auch gern per PN weiter reichen