This is a very simple alternative way to manually control alarm system by RFID reader using a badge or a tag.
Usually I arm and disarm it using device_tracker with both wifi and bt but sometimes it do not recognize my smartphone in time before it triggers the alarm, so I decided to try an alternative way to control AlarmSystem and disarm it.
I tested it successfully and I share it to anyone is interested to improve it in a better system.
Hardware needed:
- RFID reader MFRC-522 with a badge and a tag (6 eur)
- D1 Mini NodeMCU ESP8266 (5 eur)
- Logic Level Converter Bi Directional 3.3V 5V Step Up Down (8 eur 5 pcs)
- Samsung ETA-U90EWEGSTD usb charger for smartphones (6 eur)
- USB-MicroUSB 10cm cable (9 eur 2 pcs)
Follow this wiring scheme: http://lazyzero.de/elektronik/esp8266/rfid_mqtt/start
in this project MFRC-522 is linked to 3v of D1 Mini… but I suggest to use a Logic Level Converter Bi Directional 3.3V 5V Step Up Down to link 5v of D1 Mini to a real 3v for MFRC-522
I put all these components in a electric box wall mounted… the result is very fine.
Flash the D1 Mini with this firmware…
// SIMPLIFIED FIRMWARE FOR ESP8266 WITH MFRC522 WITHOUT LEDS
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <SPI.h>
#include <MFRC522.h>
/* wiring the MFRC522 to ESP8266 (ESP-12)
RST = GPIO4
SDA(SS) = GPIO2
MOSI = GPIO13
MISO = GPIO12
SCK = GPIO14
GND = GND
3.3V = 3.3V
*/
/* wiring the MFRC522 to D1 Mini ESP8266 (ESP - 12)
RST = D3
SDA(SS) = D8
MOSI = D7
MISO = D6
SCK = D5
GND = GND
3.3V = 3.3V
*/
#define RST_PIN D3 // RST-PIN GPIO4
#define SS_PIN D8 // SDA-PIN GPIO2
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
// Wifi Connection details
const char* ssid = "TIM-90987215";
const char* password = "V7Dlk4I9RWSsPNAKfOxUlGwO";
const char* mqtt_server = "192.168.1.1"; // mqtt IP
const char* mqtt_user = "userxxx"; // mqtt user
const char* mqtt_password = "12345"; // 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);
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
delay(2);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
// Connect to Wifi
void setup_wifi() {
//Turn off Access Point
WiFi.mode(WIFI_STA);
delay(10);
// 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());
}
// 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")==0))
{
payload[length] = '\0';
String sp = String((char*)payload);
// Alarm is off
if (sp == "disarmed")
{
Serial.println();
Serial.print("Alarm is set to Disarmed");
Serial.println();
}
// Alarm is Armed Home
else if (sp == "armed_home")
{
Serial.println();
Serial.print("Alarm is set to Armed Home");
Serial.println();
}
// Alarm is arming
else if (sp == "pending")
{
Serial.println();
Serial.print("Alarm set to Pending");
Serial.println();
}
// Alarm is Armed Away
else if (sp == "armed_away")
{
Serial.println();
Serial.print("Alarm set to Armed Away");
Serial.println();
}
// Alarm is Triggered
else if (sp == "triggered")
{
Serial.println();
Serial.print("Alarm is triggered!!");
Serial.println();
}
}}
/* 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()) {
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");
} 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()) {
reconnect();
}
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);
}
}
In Home Assistant configuration.yaml add this…
sensor:
- platform: mqtt
state_topic: "home/rfid"
name: RFID c
and in automation.yaml add this…
- alias: RFID 1 Alarm off
trigger:
platform: mqtt
topic: "home/rfid"
payload: 'abbccdd' // the badge or tag code
condition:
condition: or
conditions:
- condition: state
entity_id: alarm_control_panel.ha_alarm
state: armed_home
- condition: state
entity_id: alarm_control_panel.ha_alarm
state: armed_away
- condition: state
entity_id: alarm_control_panel.ha_alarm
state: pending
action:
- service: notify.mail
data:
message: "RFID 1 -> Alarm off!"
- service: logbook.log
data_template:
name: >-
{{ MQTT }}
message: RFID 1 -> Alarm off!
- service: alarm_control_panel.alarm_disarm
data: {"entity_id":"alarm_control_panel.ha_alarm","code":"12345"}
- alias: RFID 1 Alarm on
trigger:
platform: mqtt
topic: "home/rfid"
payload: 'abbccdd' // the badge or tag code
condition:
- condition: state
entity_id: alarm_control_panel.ha_alarm
state: disarmed
action:
- service: notify.hassio
data:
message: "RFID 1 -> Alarm on!"
- service: logbook.log
data_template:
name: >-
{{ MQTT }}
message: RFID 1 -> Alarm on!
- service: alarm_control_panel.alarm_arm_home
data: {"entity_id":"alarm_control_panel.ha_alarm","code":"12345"}
Many thanks to thaijames for the original project and a special thanks to Rune for support to adapt this project to AlarmSystem