Blynk based smart home – simple door alarm

In the past I have used Sonoff based door alarm sensor but for some reason the Sonoff App stopped to inform me in case the door was opened. So I started to look for a cost effective alternative and at the end decided to build my own. The main reason was also to keep the control about the system in my hands. For the realization I have already had the required hardware, so I could solder the whole system within few minutes. My Idea was to enable the Wemos just for the time of the notification. The rest of the time the Wemos should stay in the deepSleep mode, to consume less power as possible. The magnet must be placed in a position, that it’s just trigger the RESET pin of the ESP8266 while opening and closing the door and not holding the ESP in reset state in case the door is closed.

Here you can see the source code I made for my door alarm.

#include 
#include 
#include 
#include 
#include 
//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// Access Data
// WiFi SSID and PW

const char* ssid     = "MyWIFI";
const char* password = "WifiPass";

// Blynk Auth token, generateed by app
const char* blynk_auth_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// Create WiFi Client Object
WiFiClient client;

#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  255   // Header tag for serial time sync message

//'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
// NTP
#define NTP_SERVER_PORT 123
#define NTP_CLIENT_PORT 2390
IPAddress NTPServerIP;
WiFiUDP udp;
signed int UTCOffset = 1; // Timezone-Offset in hours
byte NTPData[48];
unsigned long TimeStamp = 0;
void NTPrequest(IPAddress& NTPServerIP);
const char* NTPServerName = "3.de.pool.ntp.org";

//*********************************************************************************************
//                      NTP TIME Request
//*********************************************************************************************
// send an NTP request to the time server at the given address
void NTPrequest (IPAddress& ServerAddr) {
  //Serial.println("NTP time request");
  udp.beginPacket(ServerAddr, NTP_SERVER_PORT);
  memset(NTPData, 0, 48);
  byte NTPData[16] = {0xE3, 0, 0x06, 0xEC, 0, 0, 0, 0, 0, 0, 0, 0, 0x31, 0x4E, 0x31, 0x34};
  // request timestamp:
  udp.write(NTPData, 48);
  udp.endPacket();
}
//*********************************************************************************************
//                      NTP Receive Data
//*********************************************************************************************
void NTPGetTime() {

  WiFi.hostByName(NTPServerName, NTPServerIP);
  NTPrequest(NTPServerIP); // send an request packet to a time server
  int NTPParser = udp.parsePacket();

  if (NTPParser) {
    udp.read(NTPData, 48); // read the packet into the buffer
    unsigned long HalfWord1 = word(NTPData[40], NTPData[41]);
    unsigned long HalfWord2 = word(NTPData[42], NTPData[43]);
    // combine the four bytes (two words) into a long integer
    unsigned long secsSince1900 = HalfWord1 << 16 | HalfWord2;
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    if (UTCOffset < 0) {
      TimeStamp = (secsSince1900 - seventyYears) - (UTCOffset * 3600);
    }
    else {
      TimeStamp = (secsSince1900 - seventyYears) + (UTCOffset * 3600);
    }
  }
}
//*********************************************************************************************
//                      Display Time
//*********************************************************************************************
String PrintTime() {

  String TimeString;
  TimeString = ((TimeStamp  % 86400L) / 3600); // print the hour (86400 equals secs per day)
  TimeString += ":";
  if ( ((TimeStamp % 3600) / 60) < 10 ) {
    TimeString += "0";   // In the first 10 minutes of each hour, we'll want a leading '0'
  }
  TimeString += ((TimeStamp  % 3600) / 60); // print the minute (3600 equals secs per minute)
  TimeString += " " + String(day(TimeStamp)) + "." + month(TimeStamp) + "." + (year(TimeStamp));

  return TimeString;
}

//*********************************************************************************************
//          ############        SETUP FUNCTION            ############
//*********************************************************************************************
void setup()
{
  WiFi.persistent(false);  // work arround for a bug, to disable access point...
  WiFi.hostname("Door Access");

  //%%%%%%%%% Initialize Serial Interface
  Serial.begin(115200);
  Serial.println("\r\n\r\nDoor Access");
  Blynk.begin(blynk_auth_token, ssid, password); //insert here your SSID and password
  Blynk.connect(10000);
}
//*********************************************************************************************
//             ############   ENDLESS LOOP - MAIN      ############
//*********************************************************************************************
void loop() {

  static uint8_t Trials = 20;
  int ADCValue;
  float BattVoltage;
  String BattVOut = "";

  if (Blynk.connected()) {
      // request Time Data
      udp.begin(NTP_CLIENT_PORT);
      do {
        NTPGetTime();
        Trials--;
        delay(1000);
      } while ((TimeStamp < 100) && (Trials > 0));
      udp.stop();

      Blynk.notify(PrintTime());
      Blynk.virtualWrite(V10, PrintTime());

      ADCValue = analogRead(A0);
      BattVoltage = ADCValue * (4.25 / 1023.0);
      BattVOut = String(BattVoltage) + "V";
      Blynk.virtualWrite(V30, BattVOut);
      delay(100);
      Serial.println("Sucessfully notified, go to sleep...");
      ESP.deepSleep(0);
    }
  else {
    Serial.println("Blynk Connection failed, try again...");
    Blynk.begin(blynk_auth_token, ssid, password); 
    Blynk.connect(10000);
    if (Blynk.connected() == false)   ESP.deepSleep(0);
  }
  Blynk.run();
}

For the notification on my mobile phone I preferred to use the Blynk App (available for IOs and Android), since I’ve made a very good experience with, in the past.
Within the App you will need two Value Display widgets and one Notification widget.
For the the Battery status I’ve used the V30 (Virtual Pin 30) as Input and the the last door entry V10 (Virtual Pin 10).

Conclusion:

The Wemos Module is not realy optimized for low-power applications, since the module is equipped with a USB-serial converter and a DC/DC controller which has a power dissipation of ~ 250mW. You will not have a system which is running for months. Furthermore there are also some pull-up resistors we don’t need for this project but which are “burning” also some power. In my case the system works at least 3 weeks at a daily opening rate of 10-15 times.

ToDo: Depends on the daylight saving time you will need to redefine the UTCOffset (signed int UTCOffset = 1; ), would be good to do this automatically within the code.

Click to rate this post!
[Total: 2 Average: 5]
Posted in IOT

One thought on “Blynk based smart home – simple door alarm”

  1. Well done Artur!
    The Idee behind it is really great: having the Wemo in deep sleep mode and start it up by RESET when somebody opens the door to send out the notification and put it back into deep sleep again once the job is done – this is really clever and saves a lot of battery power.
    Thanks a lot for this good article and for posting the source code.

    Regards
    Thomas

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.