Skip to main content

Home Automation - Garage Door Security

Description:

This is the research project to understand the home automation system which I would like to develop when I'm building my own house in the future. Burglary is a common threat while living in South Auckland. My wife's mountain bike was stolen from the garage in our first year living in the South Auckland. Even though we have moved to different house and living in better neighbourhood now, always worried and paranoid about the garage door. So this project developed to monitor the garage door and alert if the door is open.

Some of the terminology used in this post: 

Home Assistant Home Assistant is an open-source home automation platform running on Python 3. Track and control all devices at home and automate control. Many components are supported well by Home assistant community (Wemo, Amazon Echo, Google Home, Google Assistant, Zigbee, MQTT, IFTT, etc..)

MQTT (aka MQ Telemetry Transport) is a machine-to-machine or “Internet of Things” connectivity protocol on top of TCP/IP.


ESP8266 NodeMcu v3 wifi module development control board, accepts Arduino.

AWS - Amazon Web Service - various development tools, products and services are offered. First year subscription is free. 

Hardware Components:

  1. ESP8266 NodeMcu v3 wifi module development control board ( ~ $4 from Aliexpress)
  2. Magnetic Reed Switch MC-38 (~$2 from Aliexpress)
  3. Enclosure box (~$2 from Aliexpress)
  4. Female to Female Jumper Wire 
  5. USB Charger Cable (Recycled from house)
  6. Power Bank (Recycled from the house) - identified that it only survives for two days. better to use the plug point if you have one near the door. in my case i do not have one.

 Building the door sensor

Below steps describes the step by step procedure for building the door sensor. This is completely inspired by Simpleiothings.com (check out he has some pretty cool stuff)


  1. Create an opening in the rear of the enclosure for the micro-usb power cable and in the front of the enclosure for the jumper wires.
  2. Take two jumper wires, at the end of each wire is a plastic housing covering some metal. Remove the plastic housing using a needle or safety pin, and find a small tab in the plastic housing. Lifted up on the plastic tab. Once lifted up, smoothly removed the wire from the plastic housing. This is for one side only.
  3. Take MC-38  sensor,  exposed wires and connected female jumper wires to these exposed sensor wires by crimping (compress with pliers to create a firm connection), use tape to insulate the exposed wires. plug the other end of the jumper wire into D5 and GND on the development board. 
  4. Connect the micro-usb cable for powering up the bo
This is how it looks after everything connected. 


                       

Software 

Note: Below software components was developed using macOS. 

Pre-requisties

Following software should be installed:

MQTT Broker

First step is to get MQTT and Home Assistant working is to choose a broker. Home Assistant contains an embedded MQTT broker called HBMQTT. but Home assistant issued an  warning that there is an memory leak issue. So I have decided to use mosquitto platform until this issue has been fixed.

For better security, create your own MQTT broker. This can be done using amazon web services - EC2 Instance, helps to run Linux based Virtual Machine and host MQTT broker on the same. EC2 instance uses key pair to securely access  Linux instance using SSH. AWS stores the public part of the key pair which is just like a house lock, download and use the private part of the key pair which is just like a house key. Step by step procedure for creating own MQTT broker is explained in the medium post here

To use the MQTT broker, Linux need to be running in the machine. use the following code in terminal window (MacOS)

xxxxxxMBP3:~ foldername$ ssh -i ~/.ssh/MyKeyPair.pem username@aa.bb.cc.dd (ip address).

Sensor specific software with Arduino

Originally  code was developed for monitoring the status of the garage door as well as operating it. At the moment this post only covers the status of the garage door, Just ignore the nuisance for relay if there is any.

[code]

/*
   Garage Door
   ESP8266-based MQTT Garage Door Sensor
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <SoftwareSerial.h>

SoftwareSerial ESPserial(11, 12);


// Mapping NodeMCU Ports to Arduino GPIO Pins
// Allows use of NodeMCU Port nomenclature in config.h
#define D0 16
#define D1 5
#define D2 4
#define D3 0
#define D4 2
#define D5 14
#define D6 12
#define D7 13
#define D8 15

const char* ssid = "your wifi ssid";
const char* password = "your wifi password";

const boolean static_ip = true of false;
IPAddress ip(ip address);
IPAddress gateway(gateway);
IPAddress subnet(subnet);

const char* mqtt_broker = "your mqtt broker (i.e ip address)";
const char* mqtt_clientId = "Garage_Door";
const char* mqtt_username = "mqtt username";
const char* mqtt_password = "mqtt password";



const char* garagedoor_alias = "Garage Door";
const char* mqtt_garagedoor_status_topic = "garage/door/status";
const int garagedoor_statusPin = D5;
const char* garagedoor_statusSwitchLogic = "NO or NC"


int garagedoor_lastStatusValue = 2;
unsigned long garagedoor_lastSwitchTime = 0;
int debounceTime = 2000;

String availabilityBase = "Garage_Door";
String availabilitySuffix = "/availability";
String availabilityTopicStr = availabilityBase + availabilitySuffix;
const char* availabilityTopic = availabilityTopicStr.c_str();
const char* birthMessage = "online";
const char* lwtMessage = "offline";

WiFiClient espClient;
PubSubClient client(espClient);

// Wifi setup function

void setup_wifi() {

  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.print(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  if (static_ip) {
    WiFi.config(ip, gateway, subnet);
  }

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.print(" WiFi connected - IP address: ");
  Serial.println(WiFi.localIP());
}

// Callback when MQTT message is received;
 passing topic and payload as parameters

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");

  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }

  Serial.println();

  String topicToProcess = topic;
  payload[length] = '\0';
  String payloadToProcess = (char*)payload;
  triggerDoorAction(topicToProcess, payloadToProcess);
}

// Functions that check door status and publish an update when called

void publish_garagedoor_status() {
  if (digitalRead(garagedoor_statusPin) == LOW) {
    if (garagedoor_statusSwitchLogic == "NO") {
      Serial.print(garagedoor_alias);
      Serial.print(" closed! Publishing to ");
      Serial.print(mqtt_garagedoor_status_topic);
      Serial.println("...");
      client.publish(mqtt_garagedoor_status_topic, "closed", true);
    }
    else if (garagedoor_statusSwitchLogic == "NC") {
      Serial.print(garagedoor_alias);
      Serial.print(" open! Publishing to ");
      Serial.print(mqtt_garagedoor_status_topic);
      Serial.println("...");
      client.publish(mqtt_garagedoor_status_topic, "open", true);
    }
    else {
         Serial.println("Error! Specify only either NO or NC! Not publishing...");
    }
  }
  else {
    if (garagedoor_statusSwitchLogic == "NO") {
      Serial.print(garagedoor_alias);
      Serial.print(" open! Publishing to ");
      Serial.print(mqtt_garagedoor_status_topic);
      Serial.println("...");
      client.publish(mqtt_garagedoor_status_topic, "open", true);
    }
    else if (garagedoor_statusSwitchLogic == "NC") {
      Serial.print(garagedoor_alias);
      Serial.print(" closed! Publishing to ");
      Serial.print(mqtt_garagedoor_status_topic);
      Serial.println("...");
      client.publish(mqtt_garagedoor_status_topic, "closed", true);
    }
    else {
      Serial.println("Error! Specify only either NO or NC! Not publishing...");
    }
  }
}


// Functions that run in loop() to check each loop if garage door status (open/closed) has changed and call publish_garagedoor_status() to publish any change if so

void check_garagedoor_status() {
  int currentStatusValue = digitalRead(garagedoor_statusPin);
  if (currentStatusValue != garagedoor_lastStatusValue) {
    unsigned int currentTime = millis();
    if (currentTime - garagedoor_lastSwitchTime >= debounceTime) {
      publish_garagedoor_status();
      garagedoor_lastStatusValue = currentStatusValue;
      garagedoor_lastSwitchTime = currentTime;
    }
  }
}


// Function that publishes birthMessage

void publish_birth_message() {
  // Publish the birthMessage
  Serial.print("Publishing birth message \"");
  Serial.print(birthMessage);
  Serial.print("\" to ");
  Serial.print(availabilityTopic);
  Serial.println("...");
  client.publish(availabilityTopic, birthMessage, true);
}


// Function that runs in loop() to connect/reconnect to the MQTT broker, and publish the current door statuses on connect

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(mqtt_clientId, mqtt_username, mqtt_password, availabilityTopic, 0, true, lwtMessage)) {
      Serial.println("Connected!");

      // Publish the birth message on connect/reconnect
      publish_birth_message();

    }
    else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  // Set input pin to use internal pullup resistor
  pinMode(garagedoor_statusPin, INPUT_PULLUP);
  // Update variable with current door state
  garagedoor_lastStatusValue = digitalRead(garagedoor_statusPin);

  // Setup serial output, connect to wifi, connect to MQTT broker, set MQTT message callback
 Serial.begin(9600);
  ESPserial.begin(115200);
  ESPserial.println("AT+IPR=9600");
  delay(1000);

  // Start the software serial for communication with the ESP8266
  ESPserial.begin(9600);

  Serial.println("Ready");
  ESPserial.println("AT+GMR");

  setup_wifi();
  client.setServer(mqtt_broker, 1883);
  client.setCallback(callback);
}

void loop() {
  // Connect/reconnect to the MQTT broker and listen for messages
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  // Check door open/closed status each loop and publish changes
  check_garagedoor_status();
}

[/code]

Flash and upload the sketch into the controller

  • While pressing reset button, press the flash button in the ESP8266 board.
  • then release the reset button.
  • press upload the sketch under Sketch menu (Sketch>Upload)
Once sketch uploaded into the controller, select serial monitor under Tools menu for testing and press the reset button to listen to the controller.

Home-assistant

Setting up the home assistant is not covered in this post, refer to the website for installation and initial configuration.

Find .Homeassistant (hidden folder) in your user directory, open configuration .yaml file. set up your home location, latitude, longitude, elevation, unit system, time zone as follows

code :

homeassistant:
  # Name of the location where Home Assistant is running
  name: Home
  # Location required to calculate the time the sun rises and sets
  latitude: xx.xx
  longitude: yy.yy
  # Impacts weather/sunrise data (altitude above sea level in meters)
  elevation: zz
  # metric for Metric, imperial for Imperial
  unit_system: metric
  # Pick yours from here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  time_zone: Pacific/Auckland
  # Customization file
  customize: !include customize.yaml



There are some default options which you can either use it or un use it with # in front of the code line. i will just directly jump into the related code for this post. To configure MQTT, enter the code as follows in configuration,yaml:

# MQTT
mqtt:
 broker: aa.bb.cc.dd (ip address)
 port: 1883
 client_id: Garage_door
 username: username
 password: password

Configuration for sensor status using mqtt cover as follows. To know more about this click here


cover:
  - platform: mqtt
    name: "Garage_Door"
    state_topic: "garage/door/status"
    availability_topic: "Garage_door/availability"
    qos: 0
    payload_open: "OPEN"
    payload_close: "CLOSE"
    payload_available: "online"
    payload_not_available: "offline"


Notifications - I have used pushbullet service as notification service. i have tried using AWS SNS service. They worked pretty good as well. there are various options for notifications, click here to know more about them. Configuration for pushbullet notification as follows:

notify:
  platform: pushbullet
  api_key: "your API key"
  name: GarageDoorpushbullet

for AWS:

notify:
 platform: aws_sns
  aws_access_key_id: aws access key
  aws_secret_access_key: aws secret key
 region_name: region
   
So all the components are configured now. next step is to automate using the parameters. 
open animations.yaml and enter the below code


- id: garage_door_status

  alias: "Notify when garage door is open"
  trigger:
    - platform: state
      entity_id: cover.Garage_Door
      to: open

  action:
    - service: notify.GarageDoorpushbullet
      data_template:
        message: "Garage Door is Open"
        

Testing 

  1. Install the hardware components to the location
  2. Run the software 
    1. MQTT broker linux virtual machine 
    2. Home assistant in a separate terminal window
then type http://localhost:8123 in you browser to access the home assistant frontend.

See below video for the complete operation of system.






Inspired by : Matthieu Bila, Home Assistant and SimpleIOthings



Comments

Popular posts from this blog

Processing - playing with particles collections

Colourful ant-like particles description  Particles created, move, interact, grow from encounters and disappear. click and drag to create new particles Processing code: Automated vehicles reaching target and avoiding obstacles  description  Processing code: Coil spring description Processing code: Spring 2D description Processing code:

Processing - drawing interface good for kids

Drawing interface using processing 3 Description This sketch allows to draw shapes simply. Click once to activate the pen. An initial color is selected. Press an arrow button to select color and mix cyan, magenta, yellow, black using arrows. Press SPACE to get back to drawing. Draw as long as the pen is activated moving the mouse. Then click again to deactivate the pen. Each line can be erased by pressing SPACE. Erasing takes place in the reverse order of it being drawn. code Processing:

ABC game - letters sounds and rhymes

Audio interactive game for kids around letters and numbers learning Description Toddlers are attracted to computers, they want to play with it, press the keyboard all the time when their parents use it - pretty much for everything.  I was browsing the web for games designed to help kids learn their letters and ABC when I decided to take the opportunity to build a simple game allowing the child to discover the letters, while taking an active role in building the game it self. Here is the concept: The game displays a letter and at the same time plays an audio relating to the letter. If the player presses the right key at the first attempt, a congratulation sound is played and lots of progress is made. If the right letter / character is found after several attempts, less progress is made, no congrats sound is played. The child or the parents can record every sound matching the letters as well as the congrats messages. I got my daughter to record a short voice memo to match

Arduino projects, sensors and actuators

Moving average on analog input Description This small project shows how to implement a moving average with a lightweight form in order to smooth raw analog values. The value is then used to position a servo Image code Arduino: Using Ultrasonic sensor  Description In this project, we are using a US sensor. Very first step to understand the behaviour of the sensor through the serial interface. Image code Arduino:

Implementation 2 - use arduino uno acting as keyboard

concept:  Function A (input) performed by an arduino uno connected through USB and acting as a keyboard. Other function B C D actions performed by the same java programme as in first implementation. Image of hardware setup: Arduino wwith switches, USB link, Story In this implementation, we try to separate the input device from the device finally being controlled and performing the actions. Arduino uno is fitted with 5 inputs. To start with these inputs are switches. These switches are treated exactly as the keyboard keys in the first implementation. the switch pressed is considered as the 'keydown' event. Arduino sends the USB code representing a combination of keys pressed ( max 6 keys can be pressed simultaneously together). On the host side, the program still listens to key pressed and builds the "words" according to the rhythm at which the switches are pressed. Arduino code Specific trick to have Arduino Uno seen as a  keyboard by a co

Implementation 3 - use arduino uno and bluetooth link

concept:  Function A (input) performed by an arduino uno connected through bluetooth as using a serial communication. Other function B C D actions performed by a java programme. Image of hardware setup: Arduino with switches, bluetooth adapter, serial link The main benefits of this configuration is that the keyboard is not needed anymore as a link in the input chain. The host can then listen to the bluetooth data sent in the background, while the keyboard is being used for different purpose. Also, the application on the host does not need anymore to have the focus. Last, the input device can be split from the host computer or device.

Smart temperature sensor and client interface

Wifi enabled temperature and humidity sensor and client sending email notifications description This project was developed as part of a research to build a temperature automation system for our charming but cold Auckland home. Relying on electric oil heaters as sole source of heating in children's room, the aim was to monitor continuously the temperature at night and to turn on or off the heater according to the measured temperature. The project described in this post does the first half and mode demanding part of the job which is log a temperature, broadcast it to the web using the MQTT protocol through the house's wifi. A small and cheap ESP8266 Wifi board programmes using the Arduino language reads temperature and humidity through an DHT22 sensor and broadcasts the values to an MQTT server at set intervals. A custom client written in the java based Processing 3 and running on a computer located anywhere (Macbook in this case) displays the readings and sends not

MQTT and stuff

Journey through the internet of things world Wanted to explore and understand the ecosystem of internet of things. Started with some hardware ESP8266 ESP-01S is used in a range of relatively cheap board which can connect to a wifi network, handle some IOs and be programmed using the arduino language and software. Mated with a temperature sensor and a power regulator (supports 3.3v only), you get a small circuit  that can read data and publish it. libraries used : dht mqtt wifi Where to ? MQTT is a protocol used to handle object to object communications. Light and supported by free brokers and libraries for several languages, it takes a few hours to get started and publish the first message. broker used : hivemq also mosquitto and other In our basic example, the object sends data - publishes and we retrieve the data published on a phone or website. The broker is a middle ground where the data is made available. Using the data many free IOS apps out there that pr

Drive your lego model by voice

Voice controlled Lego merry-go-round Build a model using lego and a motor Drive the motor at various speed using an arduino board as variable frequency drive Send commands to the arduino board using your voice, through a Processing sketch on your computer and bluetooth That's it, and it works Description   hardware  A Lego motor - old motor from Lego technics - DC current - 4.5V Arduino - Uno in our case Bluetooth board - ref  Transistor Diode Breadboard and jumper cables Arduino code : Processing code :