.. note::

    Hallo und willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Gemeinschaft auf Facebook! Tauchen Sie tiefer ein in die Welt von Raspberry Pi, Arduino und ESP32 mit anderen Enthusiasten.

    **Warum beitreten?**

    - **Expertenunterstützung**: Lösen Sie Nachverkaufsprobleme und technische Herausforderungen mit Hilfe unserer Gemeinschaft und unseres Teams.
    - **Lernen & Teilen**: Tauschen Sie Tipps und Anleitungen aus, um Ihre Fähigkeiten zu verbessern.
    - **Exklusive Vorschauen**: Erhalten Sie frühzeitigen Zugang zu neuen Produktankündigungen und exklusiven Einblicken.
    - **Spezialrabatte**: Genießen Sie exklusive Rabatte auf unsere neuesten Produkte.
    - **Festliche Aktionen und Gewinnspiele**: Nehmen Sie an Gewinnspielen und Feiertagsaktionen teil.

    👉 Sind Sie bereit, mit uns zu erkunden und zu erschaffen? Klicken Sie auf [|link_sf_facebook|] und treten Sie heute bei!

.. _4.1.19_py:

4.1.19 Anwesenheitssystem
================================

Einführung
---------------

Lassen Sie uns ein einfaches Anwesenheitssystem erstellen. Wenn wir die Karte scannen, wird der Raspberry Pi unsere Daten aufnehmen und eine CSV-Datei erstellen.

Benötigte Komponenten
------------------------------

Für dieses Projekt benötigen wir folgende Bauteile.

.. image:: ../img/4.1.20components2.png

Es ist definitiv praktisch, ein ganzes Kit zu kaufen, hier ist der Link:

.. list-table::
    :widths: 20 20 20
    :header-rows: 1

    *   - Name	
        - ARTIKEL IN DIESEM KIT
        - LINK
    *   - Raphael Kit
        - 337
        - |link_Raphael_kit|

Sie können diese auch einzeln über die untenstehenden Links kaufen.

.. list-table::
    :widths: 30 20
    :header-rows: 1

    *   - BAUTEILBESCHREIBUNG
        - KAUF-LINK

    *   - :ref:`cpn_gpio_board`
        - |link_gpio_board_buy|
    *   - :ref:`cpn_breadboard`
        - |link_breadboard_buy|
    *   - :ref:`cpn_wires`
        - |link_wires_buy|
    *   - :ref:`cpn_audio_speaker`
        - \-
    *   - :ref:`cpn_dot_matrix`
        - |link_led_matrix_buy|
    *   - :ref:`cpn_mfrc522`
        - |link_mfrc522_rfid_buy|

Schaltplan
----------------------

============ ======== ======== ====
T-Board Name physical wiringPi BCM
GPIO25       Pin 22   6        25
SPIMOSI      Pin 19   12       MOSI
SPIMISO      Pin 19   12       MISO
SPICE0       pin 24   10       CE0
SPICE1       pin 26   11       CE1
SPISCLK      Pin 23   14       SCLK
============ ======== ======== ====

.. image:: ../img/4.1.20_schematic.png
   :align: center

Experimentelle Verfahren
----------------------------

.. note::

    Aktivieren Sie das SPI, bevor Sie mit dem Experiment beginnen. Einzelheiten finden Sie unter :ref:`spi_configuration`.
    
    Die :ref:`Luma.LED_Matrix` und die :ref:`Spidev und MFRC522` Bibliotheken werden ebenfalls benötigt.

Schritt 1: Schalten Sie den Schaltkreis zusammen.

.. image:: ../img/atten1.png

Schritt 2: Führen Sie die Datei ``2.2.10_write.py`` aus, um den Inhalt der RFID-Karte zu ändern.

.. raw:: html

   <run></run>

.. code-block:: 

    cd ~/raphael-kit/python
    sudo python3 2.2.10_write.py

Schritt 3: Geben Sie den Namen ein (hier verwenden wir ``John`` als Beispiel) und drücken Sie ``Enter``, um zu bestätigen. Legen Sie dann die Karte auf das MFRC522-Modul, warten Sie, bis "Datenbeschreibung abgeschlossen" erscheint, und nehmen Sie die Karte weg, oder schreiben Sie die Nachricht auf eine andere Karte um und beenden Sie mit ``Ctrl+C``.

.. image:: ../img/write_card.png

Schritt 4: Navigieren Sie in den Ordner des Codes und führen Sie ihn aus.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/python
    sudo python3 4.1.19_Attendance_Machine.py

Nach dem Starten des Programms legen wir die RFID-Karte nahe am MFRC522 RFID-Modul an, und der Raspberry Pi wird eine Begrüßung aussenden und diese auf der LED-Matrix anzeigen.

In demselben Verzeichnis finden wir auch eine ``.csv``-Datei, die die Zeit und Liste aufzeichnet. Öffnen Sie diese mit dem Nano-Befehl und Sie werden den soeben erstellten Eintrag sehen.

.. raw:: html

   <run></run>

.. code-block::

    sudo nano attendance_sheet.2021.06.29.csv

.. image:: ../img/atten3.png
  :width: 400

**Code**

.. note::
    Sie können den untenstehenden Code **Ändern/Zurücksetzen/Kopieren/Ausführen/Stoppen**. Zuvor müssen Sie jedoch zum Quellcodepfad, wie z.B. ``raphael-kit/python``, navigieren. Nach der Code-Modifikation können Sie diesen direkt ausführen, um den Effekt zu sehen.

.. raw:: html

    <run></run>

.. code-block:: python

    import time
    from tts import TTS
    import RPi.GPIO as GPIO
    from mfrc522 import SimpleMFRC522
    from luma.core.interface.serial import spi, noop
    from luma.core.render import canvas
    from luma.core.virtual import viewport
    from luma.led_matrix.device import max7219
    from luma.core.legacy import text
    from luma.core.legacy.font import proportional, CP437_FONT, LCD_FONT

    serial = spi(port=0, device=1, gpio=noop())
    device = max7219(serial, rotate=1)
    virtual = viewport(device, width=200, height=400)

    reader = SimpleMFRC522()

    tts = TTS(engine="espeak")
    tts.lang('en-US')

    attendance_statistics = {}

    def get_time():
        time.time()
        year = str(time.strftime('%Y',time.localtime(time.time())))
        month = str(time.strftime('%m',time.localtime(time.time())))
        day = str(time.strftime('%d',time.localtime(time.time())))
        hour = str(time.strftime('%H',time.localtime(time.time())))
        minute = str(time.strftime('%M',time.localtime(time.time())))
        second = str(time.strftime('%S',time.localtime(time.time())))
        present_time = year + '.' + month + '.' + day + '.' + hour + '.' + minute + '.' + second
        present_date = year + '.' + month + '.' + day
        return present_date, present_time

    def main():
        while True:
            print("Reading...Please place the card...")
            id, name = reader.read()
            print(id,name)
            greeting = name.rstrip() + ", Welcome!"
            present_date, present_time = get_time()
            attendance_statistics[name.rstrip()] = present_time
            tts.say(greeting)
            with open('attendance_sheet.' + present_date + '.csv', 'w') as f:
                [f.write('{0}  {1}\n'.format(key, value)) for key, value in attendance_statistics.items()]
            with canvas(virtual) as draw:
                text(draw, (0, 0), greeting, fill="white", font=proportional(CP437_FONT))
            for offset in range(95):
                virtual.set_position((offset,0))
                time.sleep(0.1)

    def destroy():
        GPIO.cleanup()
        pass

    if __name__ == '__main__':
        try:
            main()
        except KeyboardInterrupt:
            destroy()

**Code-Erklärung**

Um das Programm besser zu verstehen, sollten Sie zuerst :ref:`1.1.6_py`, :ref:`2.2.10_py` und :ref:`3.1.4_py` abschließen.

.. code-block:: python

    def get_time():
	    time.time()
	    year = str(time.strftime('%Y',time.localtime(time.time())))
	    month = str(time.strftime('%m',time.localtime(time.time())))
	    day = str(time.strftime('%d',time.localtime(time.time())))
	    hour = str(time.strftime('%H',time.localtime(time.time())))
	    minute = str(time.strftime('%M',time.localtime(time.time())))
	    second = str(time.strftime('%S',time.localtime(time.time())))
	    present_time = year + '.' + month + '.' + day + '.' + hour + '.' + minute + '.' + second
	    present_date = year + '.' + month + '.' + day
	    return present_date, present_time

Nutzen Sie die Funktion ``get_time()`` um den aktuellen Zeitstempel zu erhalten und zwei Werte zurückzugeben.
Dabei ist ``present_date`` bis zum aktuellen Datum genau und ``present_time`` bis zur Sekunde des aktuellen Zeitstempels genau.

.. code-block:: python

    id, name = reader.read()
    greeting = name.rstrip() + ", Welcome!"
    present_date, present_time = get_time()
    attendance_statistics[name.rstrip()] = present_time

Die Funktion ``reader.read()`` liest die Nameninformation und erstellt dann einen Begrüßungstext.
Danach wird ein Wörterbuch ``attendance_statistics`` erstellt, in dem ``name.rstrip()`` und ``present_time`` als Schlüssel und Werte gespeichert werden.

.. code-block:: python

    tts.say(greeting)

Begrüßung über den Lautsprecher aussprechen.

.. code-block:: python

    with open('attendance_sheet.' + present_date + '.csv', 'w') as f:
        [f.write('{0}  {1}\n'.format(key, value)) for key, value in attendance_statistics.items()]

Schreiben Sie die ``attendance_statistics`` in die .csv Datei.

.. code-block:: python

    with canvas(virtual) as draw:
        text(draw, (0, 0), greeting, fill="white", font=proportional(CP437_FONT))
    for offset in range(95):
        virtual.set_position((offset,0))
        time.sleep(0.1)

Rollend diese Begrüßung anzeigen.


Phänomen-Bild
--------------------

.. image:: ../img/attend_system.JPG
