[TUTORIAL] Badge-Leser in einem RPI-Gehäuse (oder anderem) mit Alarmzustandsrückmeldung erstellen

Hallo zusammen, ein kleines Tutorial, um einen Badge-Leser zu erstellen, den ich in ein Raspberry-Gehäuse eingebaut habe. Die LED wechselt von grün zu rot je nach Alarmzustand. Grün bedeutet entwaffnet, rot bewaffnet. Blaue LED in der Mitte zur Bestätigung der Badge-Lektüre.



Da jeder Badge von Gladys gelesen und übertragen wird, können Sie alle Szenen erstellen, die Sie möchten, basierend auf jeder Person, die den Badge scannt.

Funktionsweise:
Wenn das Modul mit Strom versorgt wird, sendet es den Code 000 an das im Code genannte Topic(1) und liest den Wert des Alarm-Topics(2), um die entsprechende LED-Farbe anzuzeigen (Alarm aktiv oder nicht).
Wenn Sie den Wert des Buzzers auf D3 ändern, piept es beim Start dreimal: zweimal kurz und einmal lang.
Wenn Sie einen Badge scannen, leuchtet das blaue Licht auf und der Buzzer ertönt einmal, um die Lektüre zu bestätigen. Der Badge-Code wird an das Topic(1) gesendet. Die Szene, die Sie erstellt haben, übernimmt dann…

Voraussetzungen
Sie benötigen:







Software-Seite:
Arduino. Sie können es hier herunterladen:
https://www.arduino.cc/en/software

Fügen Sie die folgenden Bibliotheken hinzu:

  • ESP8266WiFi.h
  • ESP8266WiFiMulti.h
  • PubSubClient.h
  • SPI.h
  • MFRC522.h
  • NTPClient.h
  • WiFiUdp.h

Verbinden Sie Ihren ESP8266 und stellen Sie sicher, dass er korrekt erkannt wird.
Der Treiber für ESP8266-Kopien auf Aliexpress kann hier gefunden werden:

Folgen Sie dem Installations-Tutorial.
In Arduino, wählen Sie den COM-Port, der Ihrem kleinen Biest entspricht:

Wählen Sie Ihre Karte aus (Für Kopien von ESP8266-Karten verwende ich diese Kartenreferenz):

Programmierung
Damit der Leser den gelesenen Code an Gladys übermitteln kann, müssen Sie 2 MQTT-Fake-Geräte erstellen.
In der MQTT-Integration erstellen Sie 2 „Fake-Geräte“ wie folgt:

  1. Lese den Alarmcode, den Sie auf 0 bis 1000000000000 einstellen müssen. Dies ermöglicht eine breite (sehr breite) Öffnung für die empfangenen Codes. Ich habe den Typ „Zugangskontrolle“ verwendet.

→ In Lien1 im Code angegeben

  1. Ein Alarmschalter, der sich auf 0 oder 1 aktiviert, je nach Alarmzustand. Ich habe den Typ „Power“ verwendet.

→ In Lien2 im Code angegeben

Integration:

Fake-Geräte:

Stellen Sie sicher, dass Sie die Topic-Adressen abrufen, die Sie im Code für den ESP8266 angeben müssen.

Code:
Er enthält wahrscheinlich grobe Fehler, die einigen Augen Tränen in die Augen treiben werden, aber ich habe es mit meinen begrenzten Codierkenntnissen zum Laufen gebracht, was ein großes Kunststück ist! :exploding_head: Er ist also sehr verbesserungsfähig ..
Ich habe einen Neustart alle 24 Stunden hinzugefügt, da der Code aus irgendeinem Grund nach einer Weile erschöpft ist und das Modul keine Badges mehr erkennt. Wenn einer von Ihnen das Problem versteht ..

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h> 
#includeeinschließen<PubSubClient.h> 
#include <SPI.h>
#include <MFRC522.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

int Buzzer = D4; //für ESP8266-Mikrocontroller
#define SS_PIN D8
#define RST_PIN D0

#define alarme_code " Lien1"  //Gladys-Alarmcodetopic

MFRC522 rfid(SS_PIN, RST_PIN); // Instanz der Klasse

MFRC522::MIFARE_Key key;

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);

long lastMsg = 0;   //Zeitstempel der letzten MQTT-Nachricht
long lastRecu = 0;

// Initialisieren Sie das Array, das die neue NUID speichert
byte nuidPICC[4];

//WIFI
const char* ssid = "Ihr SSID-Netzwerkname";
const char* password = "Ihr WLAN-Code";
const char* code = "";

//MQTT
#define MQTT_BROKER       "Broker-IP-Adresse"
#define MQTT_BROKER_PORT  1883
#define MQTT_USERNAME     "MQTT-Broker-Benutzername"
#define MQTT_KEY          "Broker-Passwort" 


ESP8266WiFiMulti WiFiMulti;
WiFiClient espClient;
PubSubClient client(espClient);


void setup() {
  Serial.begin(115200);
  setup_wifi();
  setup_mqtt();
  setup_RFID();
  
  pinMode (Buzzer, OUTPUT);
client.setCallback(callback);

pinMode(D1, OUTPUT);
pinMode(D2, OUTPUT);
pinMode(D3, OUTPUT);
     digitalWrite(D1,LOW);
     digitalWrite(D2,LOW);
     digitalWrite(D3,LOW);
          delay(200); 
     digitalWrite (Buzzer, HIGH); //Buzzer einschalten
          delay(200); 
      digitalWrite (Buzzer, LOW);  //Buzzer ausschalten
         delay(200); 
     digitalWrite (Buzzer, HIGH); //Buzzer einschalten
          delay(200); 
      digitalWrite (Buzzer, LOW);  //Buzzer ausschalten
          delay(500); 
    digitalWrite (Buzzer, HIGH); //Buzzer einschalten
          delay(500); 
     digitalWrite (Buzzer, LOW);  //Buzzer ausschalten

  // Abonnement des MQTT-Alarmtopics per Knopf
  client.subscribe("Lien2 ");

 client.publish(alarme_code, "000", true);   //Veröffentlicht einen Code auf dem alarme_code-Topic
  
   }
   
void restartESP() {
  ESP.restart(); //Software-Neustart des ESP8266
}

void setup_wifi(){
  //WLAN-Verbindung
  WiFiMulti.addAP(ssid, password);
  while ( WiFiMulti.run() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }
  Serial.println("");
  Serial.println("WLAN verbunden");
  Serial.print("MAC : ");
  Serial.println(WiFi.macAddress());
  Serial.print("IP-Adresse : ");
  Serial.println(WiFi.localIP());
    
}
void setup_mqtt(){
  client.setServer(MQTT_BROKER, MQTT_BROKER_PORT);
  client.setCallback(callback);//Deklaration der Abonnementfunktion
  reconnect();
}

/**   
 *    Hilfsroutine zum Ausgeben eines Byte-Arrays als Hex-Werte an den Serial-Port.
*/
void printHex(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

void setup_RFID(){
  SPI.begin(); // Initialisieren Sie den SPI-Bus
  rfid.PCD_Init(); // Initialisieren Sie MFRC522
  Serial.println();
  Serial.print(F("Reader :"));
  rfid.PCD_DumpVersionToSerial();

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }
  Serial.println();
  Serial.println(F("Dieser Code scannt die MIFARE Classic NUID."));
  Serial.print(F("Verwendung des folgenden Schlüssels:"));
  printHex(key.keyByte, MFRC522::MF_KEY_SIZE); 
}

void callback(char* topic, byte* payload, unsigned int length) {
  String value = "";
  for (int i = 0; i < length; i++) {
    value += (char)payload[i];
  }
  Serial.print("Aktueller Wert = ");
  Serial.println(value);
       
  Serial.println("-------Neue Nachricht vom MQTT-Broker-----");
   Serial.print("Kanal:");
   Serial.println(topic);
   Serial.print("Daten:");
   Serial.write(payload, length);
   Serial.println();
   if ((char)payload[0] == '1') { //A Einstellen zum Einschalten oder Ausschalten der LED
     Serial.println("LED EIN");
      digitalWrite(D2,LOW);
      digitalWrite(D1,HIGH);
      digitalWrite (Buzzer, HIGH); //Buzzer einschalten 
      delay(1000); 
     digitalWrite (Buzzer, LOW); //Buzzer ausschalten
      Serial.println("Alarmanlage einschalten");
           
   } else if ((char)payload[0] == '0'){
     Serial.println("LED AUS");
     digitalWrite(D1,LOW);
      digitalWrite(D2,HIGH);
      digitalWrite (Buzzer, HIGH); //Buzzer einschalten 
     delay(1000); 
     digitalWrite (Buzzer, LOW); //Buzzer ausschalten
     Serial.println("Alarmanlage ausschalten");
    
   }
 }


void reconnect(){
  while (!client.connected()) {
    Serial.println("Verbindung zum MQTT-Server ...");
    if (client.connect("ESPClient", MQTT_USERNAME, MQTT_KEY)) {
      Serial.println("MQTT verbunden");
          }
    else {
      Serial.print("Fehlgeschlagen, Fehlercode= ");
      Serial.println(client.state());
      Serial.println("Neuer Versuch in 2s");
    delay(2000);
    }
  }
  client.subscribe("Lien2");// Abonnement des MQTT-Alarmstatus-Topics
}

/**
   Hilfsroutine zum Ausgeben eines Byte-Arrays als Dezimalwerte an den Serial-Port.
*/
void printDec(byte *buffer, byte bufferSize) {
  String payload = "";
  String topic = " Lien1";
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : "");
    Serial.print(buffer[i], DEC);
    payload += String(buffer[i]); // Hinzufügen des ChatGPT-Skripts
      if (i != bufferSize - 1) { // Hinzufügen des ChatGPT-Skripts
        payload += ""; // Hinzufügen des ChatGPT-Skripts
      }
  }
client.publish(topic.c_str(), payload.c_str());
}


void loop() {
    if (millis() >= 86400000) { // Überprüfen, ob 24 Stunden vergangen sind (86.400.000 Millisekunden)
  Serial.print ("24 Stunden vergangen");
    ESP.restart(); // Funktion zum Neustarten des ESP8266 aufrufen
  }
  reconnect();
  client.loop();  
  float temp = 0;
  // Zurücksetzen der Schleife, wenn keine neue Karte am Sensor/Leser vorhanden ist. Dies spart den gesamten Prozess im Leerlauf.
  if ( ! rfid.PICC_IsNewCardPresent())
    return;

  // Überprüfen, ob die NUID gelesen wurde
  if ( ! rfid.PICC_ReadCardSerial())
    return;

  Serial.print(F("PICC-Typ: "));
  MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
  Serial.println(rfid.PICC_GetTypeName(piccType));

  // Überprüfen, ob der PICC vom Typ MIFARE Classic ist
  if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
      piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
      piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
    Serial.println(F("Ihr Tag ist nicht vom Typ MIFARE Classic."));
    return;
  }
    Serial.println(F("Eine neue Karte wurde erkannt."));
    // Speichern der NUID in das nuidPICC-Array
    for (byte i = 0; i < 4; i++) {
      nuidPICC[i] = rfid.uid.uidByte[i];
    }
    Serial.println(F("Der NUID-Tag lautet:"));
    Serial.print(F("In Hex: "));
    printHex(rfid.uid.uidByte, rfid.uid.size);
    Serial.println();
    Serial.print(F("In Dez: "));
    printDec(rfid.uid.uidByte, rfid.uid.size);
    Serial.println();
    
      digitalWrite(D3,HIGH); // Blaue LED einschalten
      digitalWrite (Buzzer, HIGH); //Buzzer einschalten 
      delay(1000); 
      digitalWrite (Buzzer, LOW); //Buzzer ausschalten 
      digitalWrite(D3,LOW); // Blaue LED ausschalten
      
 long now = millis();    
 if (now - lastMsg > 1000 * 60) {
    lastMsg = now;

 }
  // PICC anhalten
  rfid.PICC_HaltA();

  // Kryptografie auf PCD stoppen
  rfid.PCD_StopCrypto1();
}

Denken Sie daran, diese Werte entsprechend Ihrer eigenen Installation zu ändern:
• const char* ssid = « Ihr SSID-Netzwerkname »;
• const char* password = « Ihr WLAN-Code »;
• #define MQTT_BROKER « Broker-IP-Adresse »
• #define MQTT_BROKER_PORT 1883
• #define MQTT_USERNAME « MQTT-Broker-Benutzername »
• #define MQTT_KEY « Broker-Passwort »

Die Verbindung:

Der Buzzer ist mit der blauen LED verbunden, um Sie visuell und akustisch zu informieren.
Wenn Sie beim Starten des Moduls ein Blinken der blauen LED/des Buzzers wünschen, ändern Sie den Wert D4 in D3 hier:
int Buzzer = D4



Sie zeigen die Boxen „Zugangskontrolle“ auf Ihrem Dashboard an, Sie versorgen Ihren Badgeleser mit Strom und Sie halten einen Badge vor. Normalerweise hören Sie das Piepen, sehen das blaue Licht und erhalten den gelesenen Code auf dem Dashboard.
Aus Sicherheitsgründen sollte die Anzeige des Codes nicht auf dem Dashboard belassen werden, sie dient nur dazu, die Werte im Einstellungsmodus abzurufen.

Gladys-Szenen:
Schließlich müssen Sie, um mit dem neuen Alarmsystem von Gladys zu funktionieren, 2 umgekehrte Szenen erstellen.
Aktivierung des Alarms durch Badge:

  • Wenn der gelesene Code (Fake-Gerät Zugangskontrolle 1) gleich (Wert Ihres Badges) ist, dann,
  • Wenn das Haus nicht gesichert ist
    • Sicherung des Hauses
    • „Ein Gerät steuern“ (Fake-Gerät Power 2) und auf 1 setzen

Deaktivierung des Alarms durch Badge:

  • Wenn der gelesene Code (Fake-Gerät Zugangskontrolle 1) gleich (Wert Ihres Badges) ist, dann,
  • Wenn das Haus gesichert ist
    • Entsicherung des Hauses
    • „Ein Gerät steuern“ (Fake-Gerät Power 2) und auf 0 setzen

Im Auslöser können Sie mehrere Code-Boxen zur Überprüfung hinzufügen.
Sie können eine Verzögerung in Ihrer Aktivierungsszene per Badge zwischen dem Lesen des Badges und der Sicherung des Hauses hinzufügen, um Ihnen Zeit zum Verlassen zu geben.
Persönlich habe ich Google Home-Nachrichten hinzugefügt, die beim Aktivieren des Badges, 3 Minuten danach, 4 Minuten danach und beim Sichern des Hauses warnen, das Haus zu verlassen.

Ich hoffe, ich bin klar genug und es wird Ihren Anforderungen entsprechen.

Jetzt sind Sie dran und viel Erfolg ..

Danke für das Tutorial, es ist super nett, solche Projekte zu entdecken :slight_smile:

Was deinen Code angeht, seit einiger Zeit entwickle ich VBA-Makros (und Office Scripts, wenn ich kann, ich bevorzuge sie) um bestimmte Aufgaben zu automatisieren. Da ich VBA nicht kenne, nutze ich viel https://bard.google.com/ (das « ChatGPT » von Google) oder https://chat.openai.com/ (ChatGPT) um mir Codebeispiele zu liefern.

Manchmal haben diese beiden KIs total funktionierenden Code, manchmal nicht so sehr :sweat_smile:
In jedem Fall kann das auch helfen, bestimmte Probleme zu beheben, besonders wenn man nicht viel davon versteht.

Vielen Dank für dieses tolle Tutorial!!! :+1:
Das ist genau die Art von Dingen, bei denen ich gerne einsteigen würde.

Danke für dein Feedback. Ich bin kein VBA-Experte, aber ich schlage mich ganz gut mit dem Erstellen von Makros in Excel, die mir beruflich viel Zeit sparen. Was ChatGPT betrifft, stell dir vor, dass ich es auch genutzt habe, um den Code zu „stabilisieren“ :sweat_smile:
Manchmal verschlimmerte es die Dinge allerdings und entschuldigte sich jedes Mal dafür.. :yum:

Ich habe auch eine Weile herumgespielt, aber ich wollte meine 433-Centrale ersetzen, weil Gladys irgendwann eine etwas wackelige Schnittstelle zwischen Zigbee-Detektoren und 433-Fernbedienungen wurde. Jetzt ist es einfach, modular und wird von der Familie geschätzt, die nicht ständig in der Gladys-Installation herumstöbert.
Mir bleibt noch, ein SMS-System (super Tutorial von Checconio) im Falle eines WLAN-Absturzes einzurichten (auch wenn bereits alles an einem USV hängt) und eine Zigbee-Sirene.

Ja, manchmal muss man so etwas wie „Prompt-Hacking“ beherrschen oder sogar erkennen, wenn es Unsinn macht.
Ich wechsle zwischen Internetrecherchen und ChatGPT für den Code.

Kurz gesagt, gut gemacht für das Tutorial! Nutzt du es, um deine Alarmanlage zu aktivieren?

@lmilcent
Ja.
Ich scanne den Ein-/Ausgangs-Badge oder aktiviere ihn über den neuen Gladys-Button.
Der feine Unterschied ist, dass diese beiden Aktionen eine Countdown-Szene auslösen, die mir Zeit lässt, das Haus zu verlassen, kombiniert mit Google Home-Nachrichten, die mich höflich auffordern, schnell zu gehen :yum:
Dann wird ein Fake-Gerät aktiviert, das bewaffnet/entwaffnet wird, und dies ist das Gerät, das im Falle eines Einbruchs überprüft wird.
Auch eine sofortige Überprüfung offener Buchten bei der Aktivierung des Badges oder des Buttons.