Controlling House Alarm From HA

thaijames,

I’m interested in what you have accomplished, but would like to take it one step further without the RFID and replace my current alarm system with a rpi gpio and HA based alarm system.

I would like to replace my keypad with cheap android tablet which will also be hooked up to a front door camera. PIR sensors would trigger the alarm when active and a relay would set off the siren and strobe and pushbullet a message or maybe an sms gateway

I’m interested in how you setup the PIR sensors on the rpi but your attachments don’t seem to load. Can you please repost the photos.

Thanks,

Mark

Thanks for this @thaijames I’ve just set this up and it work brilliantly! I’m very please. Not installed it yet but in testing it’s been working well!

Just wondering, what LED did you use and how did you wire it to the NodeMCU? This is the only part I dont have working yet. Not critical but would be nice to have!

Many thanks!

Hi Guys

I liked the idea of an RFID with the status lights attached and tested this code. The RFID ids are now sent to HA and this part is OK. The code I`am struggeling with is the part below. If the Alarm is armed (armed_home) the message is received and activates the “// Alarm is on” loop. The same for “// Alarm is off” loop. But nothing happens when “pending” is received. Has something changed in HA since this code were made? If anyone is kind enough, could someone please explain what this means: ((char)payload[2] == ‘m’)

[quote=“thaijames, post:7, topic:67”]
// Alarm is on
if ((char)payload[1] == ‘n’) {
Serial.println();
Serial.print(“Alarm is on”);
Serial.println();
on_red_led();
}
// Alarm is off
if ((char)payload[1] == ‘f’) {
Serial.println();
Serial.print(“Alarm is off”);
Serial.println();
on_green_led();
}
// Alarm is arming
if ((char)payload[2] == ‘m’) {
Serial.println();
Serial.print(“Alarm is arming”);
Serial.println();
flash_red_led();
}
// Alarm is disarming
if ((char)payload[2] == ‘s’) {
Serial.println();
Serial.print(“Alarm is disarming”);
Serial.println();
flash_green_led();
[/quote]

I figured it out. Let me know if anyone else needs the code :slight_smile:

Yes. Please share. :slight_smile:

Hi

I choose to not use the flashing leds, since it stop any other actions from the Node MCU.
Works as intended on the following code:

#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

RGB LED Setup
Red LED   = D1
Ground    = GND
Gr. LED   = D2
Blue LED  = D0
*/
#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 = "xxxxx";
const char* password = "xxxxxx";

const char* mqtt_server = "xxxxxxx";
const char* mqtt_user = "xxxxxxx";
const char* mqtt_password = "xxxxxxxx";
const char* clientID = "RFID";
const char* rfid_topic = "home/rfid";
const int redPin = D1;
const int greenPin = D2;
const int idPin = D0;

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
  pinMode(redPin, OUTPUT); // Red LED
  pinMode(redPin, HIGH); 
  pinMode(greenPin, OUTPUT); // Green :LED
  pinMode(greenPin, HIGH);
  pinMode(idPin, OUTPUT); // ID :LED
  pinMode(idPin, HIGH);
  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();
    off_both_led();    
  }   
  // Alarm is Armed Home    
    else if (sp == "armed_home")
    {
    Serial.println();
    Serial.print("Alarm is set to Armed Home");
    Serial.println();
    on_green_led();     
  } 
  // Alarm is arming
      else if (sp == "pending")
    {
    Serial.println();
    Serial.print("Alarm set to Pending");
    Serial.println();
    on_both_led();    
  }   
  // Alarm is Armed Away
    else if (sp == "armed_away")
    {
    Serial.println();
    Serial.print("Alarm set to Armed Away");
    Serial.println();
    on_green_led();    
  } 
  // Alarm is Triggered
    else if (sp == "triggered")
    {
    Serial.println();
    Serial.print("Alarm is triggered!!");
    Serial.println();
    on_red_led();    
  }
}}
/* 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);
}
// LED Loop
void off_both_led(){
  Serial.println("Turning off all led");
  digitalWrite(greenPin, LOW);
  digitalWrite(redPin, LOW);
}
void flash_green_led(){
  Serial.println("Flashing Green LED");
  digitalWrite(greenPin, LOW);
  // Flash 15 times:
  for(int i = 0; i < 14; i++)
  {
  digitalWrite(greenPin, HIGH);
  delay(1000);
  digitalWrite(greenPin, LOW);
  delay(500);
}}
void flash_red_led(){
  Serial.println("Flashing Red LED");
  digitalWrite(redPin, LOW);
  // Flash 20 times:
  for(int i = 0; i < 19; i++)
  {
  digitalWrite(redPin, HIGH);
  delay(1000);
  digitalWrite(redPin, LOW);
  delay(500);
}}
void on_green_led(){
  Serial.println("Turning on green led");
  digitalWrite(redPin, LOW);
  digitalWrite(greenPin, HIGH);
}
void on_red_led(){
  Serial.println("Turning on red led");
  digitalWrite(greenPin, LOW);
  digitalWrite(redPin, HIGH);
}
void on_both_led(){
  Serial.println("Turning on both led");
  digitalWrite(greenPin, HIGH);
  digitalWrite(redPin, HIGH);
}
// 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);
  }
}
1 Like

Hi, this project is very interesting, actually I’m using this Alarm System (https://github.com/runningman84/home-assistant-apps) made by runningman84.
I wish to use a RFID card or tag only to arm or disarm alarm.
I need only the part of code to program ESP8266 to send to HA the authorized badge/tag to arm or disarm alarm.
Can you help me?

Hi. Do you mean the yaml part in HA?

Hi Rune, I use this Alarm System (https://github.com/runningman84/home-assistant-apps/blob/master/apps/alarm.py) that automatically arm and disarm alarm based on device_tracker recognition of my smartphone (when works fine). I wish an alternative way to arm and disarm it using RFID badge or tag.
I’ve a RC522, a Nodemcu V3 Lolin and I wish to use the firmware and scripts created by thaijames to integrate them in my Home Assistant.
I’m a newbie please help me…

There is a firmware to flash in Nodemcu to send RFID token to HA
(Controlling House Alarm From HA)

There is a code to interface RFID reader to HA …I suppose to put in a file like… rfid.py
(Controlling House Alarm From HA)
Where should this file be put?

Then there is some automation to put in configuration.yaml to arm or disarm alarm

My alarm code is based on appdaemon and is located in /config/appdaemon/apps/alarm.py
Usually I arm or disarm it using automations…

  action:
      - service: alarm_control_panel.alarm_arm_home
        data: {"entity_id":"alarm_control_panel.ha_alarm","code":"12345678"}

or

  action:
      - service: alarm_control_panel.alarm_disarm
        data: {"entity_id":"alarm_control_panel.ha_alarm","code":"12345678"}

To simplify operations at the moment I wish to exclude the management of the LEDs
Can you help me?

I uploaded the sketch I used to the NodeMCU and then received RFID ids as MQTT messages to HA. Based on these ids I made automations to turn on if off and off if on. No fancy stuff ;) I only use the LEDs to show if the alarm is on or off. If you dont want to use LEDs just dont connect anything to these outputs.

I filled mqtt server data and flashed the Nodemcu commenting the code about leds management…
and now?
how to integrate it in HA?
How to authorize only my rdif badge?
How to do to arm/disarm my alarm?

My firmware version now is…

#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
*/
#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-12345678";
const char* password = "aabbccddeeffgghhiijjkkll";

const char* mqtt_server = "192.168.1.2";
const char* mqtt_user = "user";
const char* mqtt_password = "12345";
const char* clientID = "RFID";
const char* rfid_topic = "home/rfid";

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();
    //off_both_led();    
  }   
  // Alarm is Armed Home    
    else if (sp == "armed_home")
    {
    Serial.println();
    Serial.print("Alarm is set to Armed Home");
    Serial.println();
    //on_green_led();     
  } 
  // Alarm is arming
      else if (sp == "pending")
    {
    Serial.println();
    Serial.print("Alarm set to Pending");
    Serial.println();
    //on_both_led();    
  }   
  // Alarm is Armed Away
    else if (sp == "armed_away")
    {
    Serial.println();
    Serial.print("Alarm set to Armed Away");
    Serial.println();
    //on_green_led();    
  } 
  // Alarm is Triggered
    else if (sp == "triggered")
    {
    Serial.println();
    Serial.print("Alarm is triggered!!");
    Serial.println();
    //on_red_led();    
  }
}}
/* 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);
  }
}

Hi, I will find my old configuration and automations and put it here (I removed my RFID since I got my device tracker working properly). Could you confirm that you have hass.io and Mosquitto MQTT broker? The alarm also needs to be Manual alarm with MQTT.

Yes, I use Hassio and Mosquitto MQTT broker.
I can arm or disarm alarm manually… usually I ise a Xiaomi wireless switch with a automation like this…

  - alias: SystemAlarm Disarmed Manually
    trigger:
      platform: event
      event_type: click
      event_data:
        event_id: binary_sensor.switch_123456789123456789
        click_type: double
    action:
      service: alarm_control_panel.alarm_disarm
      data: {"entity_id":"alarm_control_panel.ha_alarm","code":"12345"}

After flashing Nodemcu what will be his IP?
I do not see it in my wifi network… it is strange…

When you flash it with the sketch you can have the log open, there you will see if it connects and which IP it receives.

After flashing in serial monitor of Arduino IDE it printed… ⸮8⸮⸮⸮

I fear there is something wrong with the firmware

Hi, did you remember to set it to speed to 115200? If this is your first time using arduino watch this video. It helped me alot: https://www.youtube.com/watch?v=jpjfVc-9IrQ&t=662s

I used many time Arduino IDE, I flashed with Tasmota 8 Sonoff switches few months ago.
Serial speed is 115200

huh. Then I dont get it. It works fine for me on NodeMCU. I can retry the sketch a bit later tonight and see what I find. I remember all my sketches always start with some like ???something, but then goes over to normal.

Hi Rune, I solved the problem… the Nodemcu V3 was partially broken… I flashed the blink sketch and it do not blink the led.
Now I tested with a ESP8266 D1 mini and it works fine and is recognized from my wifi network and assigned a IP. If I use a badge or tag it show me its code in the Arduino serial monitor.
Mosquitto MQTT view it… “New client connected from 192.168.1.133 as RFID (c1, k15, u’vpomax’).”
Now I need to make the code HA side.

I used the sensor to have a view of what I received in HA and the automation below for the alarm. Just replace RFIDxxxxxx with the ID that shows in the sensor. Goodluck :slight_smile:

Sensor:
      - platform: mqtt
        state_topic: "home/rfid"
        name: RFID

Automation:
    - alias: RFID 1 Alarm off
      trigger:
        platform: mqtt
        topic: "home/rfid"
        payload: 'RFIDxxxxxx'
      condition:
        condition: or
        conditions:
          - condition: state
            entity_id: youralarmhere
            state: armed_home
          - condition: state
            entity_id: youralarmhere
            state: armed_away
      action:
        - service: notify.ios_yourphone
          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: youralarmhere
            code: myalarmpassword
    - alias: RFID 1 Alarm on
      trigger:
        platform: mqtt
        topic: "home/rfid"
        payload: 'RFIDxxxxxx'
      condition:
        - condition: state
          entity_id: youralarmhere
          state: disarmed
      action:
        - service: notify.ios_xxxxx
          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: youralarmhere
            code: youralarmpassword