Delevelop alarm system based on amazing ESP-RFID Github project

I just saw this amazing GitHub project based on ESP8266 and RFID (PN532):

Project: https://github.com/omersiar/esp-rfid
Tutorial/setup: https://www.youtube.com/watch?v=ENMul9eAB00

I am planing to use it as an alarm system. I just need to understand how to modify the code to add some leds to turn on/off when status change + use it in conjunction with Alarm control panel in Home Assistant.

Anyone has worked on this project or has an slight idea on how to acomplish this?

I’ve played with it annnnd.

It works via MQTT so you could use that unfortunately it’s a bit bare as right now it doesn’t support the ability to define your topics(dev is still trying to figure that out). It doesn’t even support IN vs OUT, its just a badge swipe to trigger a relay and fire off a message so you’d have to (re)write that. You’d probably be better off finding something else.

I know people have been asking for ESPEasy to include an RFID sensor and if it did that would be the way to go, but I haven’t seen support yet. Unless they’ve done it recently.

EDIT: ESPEasy does support 2 RFID devices (Here)[https://www.letscontrolit.com/wiki/index.php/Devices] so if you use those that would be my choice.

Be aware that rfid is not particularly secure.

So basically you are proposing to flash a NodeMCU or similar with ESEasy and edit a little bit of code to acomplish this, sounds good!

Quick question, my setup should be:

1 NodeMCU + 1 RFID + 3 leds (for status, alarm ON and alarom OFF). Then the HA will run the logic behind. Do you think this is fesable? (kind of worried with the leds part).

As long as nodemcu has enough io pins to run 3 leds as well as the rfid device, and you don’t mind programming the alarm/led stuff it should be fine.

What puzzles me is how the system knows how to arm or disarm the alarm.

1 Like

I’ve already written a sketch for this a few months ago based on a few things which I found online.
I haven’t got an alarm status led set up but I do have an led which flashes green if the card has been accepted.
If you’re interested in this, I’ll share the code tonight as I don’t have access to my computer right now.

That would be awesome! An I can try to add the other leds from there.
Thanks a lot.

Thanks!

You can always go with Nest: https://nest.com/alarm-system/overview/
Seems a good product, and I believe you can’t disable alarm through the API or any other means that is not “Nest native”. Only problem is he price.

Actually, this might be exactly what you are looking for:

I’m aware of this one, but it’s not working properly for me (getting stuck after some hours). So I was looking for something more developed and tested. And using something based on an existent project like ESPEasy souns good to me.

The code you said is the one you posted or is it another one? I rally would like to check this code to see if it feet my needs.

Thanks a lot!

So here is my code. As I have already said, it really is a mix of multiple sketches which I found online.

How it works:
When a card if scanned, it sends the card ID via MQTT on the home/rfid topic.
Then an automation checks if it is the correct card. If it is it disarms the alarm and sends accept to home/alarm/rfid. If the card it refused, it sends refuse to home/alarm/rfid.

The hardware:
ESP8266
MFRC-522
RGB LED

Here is the code:

//RFID FIRMWARE FOR ESP8266 WITH MFRC522 WITH LEDS  

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <SPI.h>
#include <MFRC522.h>

/* wiring the MFRC522 to ESP8266
Red     = D0
Green   = D1
Blue    = D2
RST     = D3
SCK     = D5
MISO    = D6
MOSI    = D7
SDA(SS) = D8
GND     = GND
3.3V    = 3.3V
 */
 
#define RST_PIN  D3 // RST-PIN
#define SS_PIN  D8  // SDA-PIN 
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance

//Define RGB LED pins
const int redPin = D0;
const int greenPin = D1;
const int bluePin = D2;

// Wifi Connection details
const char* ssid = "";
const char* password = "";

const char* mqtt_server = "";  // mqtt IP
const char* mqtt_user = "";  // mqtt user
const char* mqtt_password = "";  // mqtt password
const char* clientID = "RFID";  // rfid name
const char* rfid_topic = "home/rfid";  // rfid path

WiFiClient espClient;
PubSubClient client(espClient);

long lastMsg = 0;
char msg[50];

void setup() {
  Serial.begin(115200);
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  Serial.begin(115200);
  delay(10);
  SPI.begin();           // Init SPI bus
  mfrc522.PCD_Init();    // Init MFRC522
  delay(2);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  reconnect();
}

// Connect to Wifi
void setup_wifi() {
  //Turn off Access Point
  WiFi.mode(WIFI_STA);
  analogWrite(redPin, 238);
  analogWrite(greenPin, 130);
  analogWrite(bluePin, 238); 
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  analogWrite(redPin, 0);
  analogWrite(greenPin, 0);
  analogWrite(bluePin, 200); 
}
// Check for incoming messages
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.println("");
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  char s[20];
  
  sprintf(s, "%s", payload);

    if ( (strcmp(topic,"home/alarm/rfid")==0))
  {
    payload[length] = '\0';
    String sp = String((char*)payload);

  // Green LED if card accepted 
	if (sp == "accept")
    {
    Serial.println();
    Serial.print("RFID Accepted");
    Serial.println();  
    analogWrite(redPin, 0);
    analogWrite(greenPin, 255);
    analogWrite(bluePin, 0);
    delay(2000);  
    analogWrite(redPin, 0);
    analogWrite(greenPin, 0);
    analogWrite(bluePin, 0); 
  }   
  // Red LED if card refused
    else if (sp == "refuse")
    {
    Serial.println();
    Serial.print("RFID Refused");
    Serial.println(); 
    analogWrite(redPin, 255);
    analogWrite(greenPin, 0);
    analogWrite(bluePin, 0); 
    delay(2000);
    analogWrite(redPin, 0);
    analogWrite(greenPin, 0);
    analogWrite(bluePin, 0); 
  }  
 }
}
/* interpret the ascii digits in[0] and in[1] as hex
* notation and convert to an integer 0..255.
*/
int hex8(byte *in)
{
   char c, h;

   c = (char)in[0];

   if (c <= '9' && c >= '0') {  c -= '0'; }
   else if (c <= 'f' && c >= 'a') { c -= ('a' - 0x0a); }
   else if (c <= 'F' && c >= 'A') { c -= ('A' - 0x0a); }
   else return(-1);

   h = c;

   c = (char)in[1];

   if (c <= '9' && c >= '0') {  c -= '0'; }
   else if (c <= 'f' && c >= 'a') { c -= ('a' - 0x0a); }
   else if (c <= 'F' && c >= 'A') { c -= ('A' - 0x0a); }
   else return(-1);

   return ( h<<4 | c);
}
// Reconnect to wifi if connection lost
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {;
    analogWrite(redPin, 0);
    analogWrite(greenPin, 0);
    analogWrite(bluePin, 200); 
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(clientID, mqtt_user, mqtt_password)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("home/rfid", "connected");
      // ... and resubscribe
      client.subscribe("home/alarm/rfid");
     analogWrite(redPin, 0);
     analogWrite(greenPin, 200);
     analogWrite(bluePin, 0);
     delay(500);
     analogWrite(redPin, 0);
     analogWrite(greenPin, 0);
     analogWrite(bluePin, 0);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

// Main functions
void loop() {
  if (!client.connected()) {
    software_Reset();
  }
  client.loop();
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    delay(50);
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    delay(50);
    return;
  }
  // Show some details of the PICC (that is: the tag/card)
  Serial.println("");
  Serial.print(F("Card UID:"));
  dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
  Serial.println();
  //digitalWrite(idPin, HIGH);
  delay(500);
  //digitalWrite(idPin, LOW);
  delay(500);
  // Send data to MQTT
  String rfidUid = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    rfidUid += String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : "");
    rfidUid += String(mfrc522.uid.uidByte[i], HEX);
  }
  const char* id = rfidUid.c_str();
  client.publish("home/rfid", id);
  delay(3000);
}
// Helper routine to dump a byte array as hex values to Serial
void dump_byte_array(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}

/****reset***/
void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
{
Serial.print("resetting");
ESP.reset(); 
}
1 Like

And how do you turn the alarm back on?

I guess with either the same RFID or from HA alarm control panel.

Uou, didn’t knew these RGB leds even existed, very smart.

Could you also share the Home Assistant part of the code? I really would like to give it a try!

Thanks.

I’d love to share the Home Assistant part but I’m not at home this week so I don’t have access to the code of my HA instance. So I won’t be able to share it until next Monday.

In the meantime, I’ve tried to quickly write down my code from memory. However I’m not sure the syntax is correct.

automation:
  trigger:
    - platform: mqtt
      topic: home/rfid
  condition:
    - condition: state
      entity_id: alarm_control_panel.house
      state: 'armed_away'
  action:
    - service: mqtt.publish
      data_template:
        topic: "home/alarm/rfid"
        payload_template: "{% if trigger.payload == 'CARD ID' %}accept{% else %}refuse{% endif %}"
    - platform: alarm_control_panel.disarm
      data_template:
        entity_id: "{% if trigger.payload == 'CARD ID' %}alarm_control_panel.house{% endif %}"
        code: '0000'

I have a wall mounted tablet next to my RFID ready which I use to arm the alarm and to disarm it using a code.

However, it would be very easy to add an automation to arm the alarm using rfid using conditions.

Now my code is also causing this issue.
Did you find any other functional way to accomplish this ?

I believe this could be related to the device temporary losing wifi connectivity and not being able to reconnect after that.

I’ve improved my APs by upgrading to a newer model and changing the location, and seems it is kind of working now.

Anyway, I just bought this new Arduino model, with integrated ethernet. I will need to connect it through an ethernet cable, but should solve the issue:

https://es.rs-online.com/web/p/kits-de-desarrollo-de-procesador-y-microcontrolador/1763648/?relevancy-data=636F3D3126696E3D4931384E4C446573635461786F6E6F6D794272616E645365617263685465726D325F74656D70266C753D6573266D6D3D6D617463687061727469616C6D617826706D3D5E5B5C707B4C7D5C707B4E647D3F5C707B5A737D2D2C2F255C2E5D2B2426706F3D31313326736E3D592673723D2673743D4B4559574F52445F4D554C54495F414C5048415F414E445F4D554C54495F414C5048415F4E554D455249432673633D592677633D4E4F4E45267573743D41726475696E6F204D4B522045544820536869656C64267374613D41726475696E6F204D4B522045544820536869656C6426

Seems they are going to finally add status LED + Buzzer support for this amazing project!