Удаленный мониторинг состояния квартиры и управление домашними устройствами

image-loader.svg

Наиболее частыми задачами, стоящими перед любыми домовладельцами, являются наблюдение за его жилищем в момент физического отсутствия, например, когда человек находится на работе, а также необходимость автоматического исполнения некоторых задач, среди которых особо можно выделить полив домашних цветов.

В рамках этой статьи мы попробуем рассмотреть, как можно было бы создать систему домашнего мониторинга и удалённого управления, используя минимальные средства. Несмотря на некоторую ограниченность системы, она является в достаточной степени функциональной и даёт широкие возможности её создателю.

Попробуем кратко охарактеризовать комплекс задач, стоящих перед разработчиком системы:

  • Большое количество различных бытовых несчастий происходит ввиду того, что случаются разнообразные техногенные катастрофы бытового масштаба. Среди них можно выделить: протечки в системе отопления, забытые включёнными краны холодной и горячей воды, случайное возгорание объектов. Последний пункт является особо любопытным, так как зачастую такие случаи возникают даже из-за невинной капли воды, оставшейся на подоконнике, которая, по сути, является собирающей линзой. В яркий солнечный день эта водяная линза легко концентрирует солнечные лучи в поджигающую точку (точно так же, как многие баловались в детстве, выжигая всякие надписи на деревянных предметах). Поэтому наблюдение за температурой и влажностью в квартире является крайне важным, так как эксцессы на базе этих двух пунктов могут произойти даже совершенно случайно, без особой вины владельца. Поэтому создаваемая нами система должна будет иметь возможность мониторить уровень влажности и температуры в квартире.
  • Многие люди, уезжая даже на непродолжительный отпуск, сталкиваются с необходимостью полива домашних цветов. Поэтому создание такой системы будет вполне актуальным и нужным для большинства людей. Наличие подобного устройства дома развязывает руки владельцу и позволяет ему отсутствовать продолжительное время.
  • Каждый собственник в момент своего отсутствия достаточно сильно переживает о том, не было ли совершено проникновение в его жилище. Установка профессиональных систем сигнализации является, конечно, предпочтительным вариантом, однако такое действие несколько затратно. Поэтому мы постараемся создать свою систему, которая, несмотря на свою доступность, сможет быть вполне функциональный и позволит в режиме реального времени мониторить жилище на отсутствие/наличие взлома и проникновения в него.


Для реализации всего вышесказанного видится наиболее целесообразным создать систему, состоящую из двух функциональных блоков:

  • Блок мониторинга за состоянием жилища.
  • Блок оповещения владельца о возникновении внештатных ситуаций.


В качестве блока мониторинга мы будем использовать mqtt-брокер, в соответствующие топики которого система будет публиковать отчёты о состоянии отслеживаемых параметров. Для наблюдения за этими параметрами со стороны владельца вполне рационально использовать то или иное приложение под смартфон, которое позволит производить мониторинг параметров в реальном времени.

Для физической реализации мониторинга мы будем использовать датчик влажности и температуры DHT22, в то время как для мониторинга за проникновением в жилище мы будем использовать пару из цифрового датчика Холла KY-003 и неодимового магнита.

Для оповещения владельца мы создадим систему отправки предупреждающих e-mail сообщений, так как этот способ является одним из наиболее доступных. Как альтернативу ему можно было рассмотреть написание некого приложения под смартфон, которое будет мониторить топики, в которые система будет публиковать сообщения о внештатных ситуациях, при возникновении которых смартфон будет подавать звуковой или иной сигнал. Однако рассмотрение этого не входит в рамки этой статьи, поэтому создание такой системы оповещения можно отложить на перспективу.

В качестве ещё одного интересного варианта оповещения владельца можно было бы рассмотреть вариант отправки сервисных SMS сообщений. Здесь возможны тоже несколько вариантов. Среди которых можно перечислить такие, как:

  • Отправка смс-сообщения непосредственно с аппаратного устройства.
  • Использование соответствующих интернет-сервисов, когда отправка данных позволяет преобразовать их в SMS сообщение для адресата. Такой способ является тоже весьма интересным и может быть проработан в рамках создания будущих устройств.


Общая схема системы и её работы показана на рисунке ниже (кликабельно, большая):

51hpjwbmtbyqdw2d7hrtg_kx3r0.jpeg

«Мозг» системы будет построен на основе известного микроконтроллера Espressif ESP32.
Программирование системы будет осуществлено в рамках среды разработки Arduino IDE, с использованием языка Arduino C.

Для удобства работы с кодом и чёткого его структурирования мы его раздели на пять блоков, которые будут разнесены на пять необходимых вкладок Arduino IDE в виде соответствующих функций. Рассмотрим вкратце содержимое каждой из них:

gwigl1ir0aixv-nt7yi_3calul0.jpeg


Для начала нам необходимо сконфигурировать свою домашнюю сеть роутера, к которому будет подключаться по wi-fi в наш микроконтроллер:

const char* ssid = ""; //сюда название вашей домашней wifi-сети роутера
const char* password = "";//сюда пароль от wifi-сети роутера


Далее нам необходимо сконфигурировать параметры доступа к mqtt-брокеру. Для лучшего понимания кода мы снабдили его положенными пояснениями:

const char* mqtt_server = "vashbroker.com";//сюда адрес вашего брокера
#define mqtt_port 1883 //порт вашего брокера
#define MQTT_USER ""   //сюда имя пользователя MQTT,
                       //если система должна иметь пользователя и пароль
#define MQTT_PASSWORD "" //сюда пароль пользователя MQTT,
                       //если система должна иметь пользователя и пароль


Далее мы создаём топики для публикации в них как сообщений от микроконтроллера:

#define MQTT_PUBLISHING_CHANNEL "/Kvartira/Reports"
#define MQTT_PUBLISHING_CHANNEL_2 "/Kvartira/Humidity"
#define MQTT_PUBLISHING_CHANNEL_3 "/Kvartira/Temperature"


Так и для публикации «приказов» на выполнение от смартфона:

#define MQTT_RECEIVER_CHANNEL_1 "Kvartira/Orders"


К слову сказать, насчёт топиков, их количество может быть произвольным, и вы можете создать свои собственные как для отправки сообщений на исполнение, так и для получения данных о происходящем от микроконтроллера.

Далее мы устанавливаем переменные процесса отправки e-mail сообщений. Для пример взята почта gmail:

#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465

#define AUTHOR_EMAIL "nekayapochta@gmail.com" //адрес электронной почты,
                                              //ОТКУДА будет отправляться сообщение
#define AUTHOR_PASSWORD "parol" //пароль электронной почты,
                                //ОТКУДА будет отправляться сообщение
#define RECIPIENT_EMAIL "vashapochta@mail.ru" //адрес электронной почты,
                                              //КУДА будет отправляться сообщение 

SMTPSession smtp; // объект SMTP-сессии, используемый для отправки e-mail сообщения
void smtpCallback(SMTP_Status status); // Функция обратного вызова, чтобы получать статус
                                      //состояния отправки e-mail сообщения

String EmailMessageType = ""; //В эту строку будет писаться, какое сообщение отправить
       const uint32_t SendingPeriod = 30000; //интервал, между отправкой почты
                                             //(чтобы сильно часто не спамить)
       uint32_t lastSendingTime = 0; //время, когда было отправлено последнее сообщение


Также определяем переменные датчиков:

#define DHTPIN 4      // Пин, к которому подключён датчик
#define DHTTYPE DHT22 // Используемый датчик DHT 22
  DHT dht1 (DHTPIN, DHTTYPE); // Инициализируем датчик
      float humiditySensor1 = 0;  //влажность, считанная с датчика 1

 //критическая влажность, при которой идёт отправка сообщения на e-mail:
      float ALARM_for_HumiditySensors = 100;

      float temperatureSensor1 = 0;  //температура, считанная с датчика 1

//критическая температура, в градусах Цельсия, при которой
//идёт отправка сообщения на e-mail:
      float ALARM_for_temperatureSensors = 50;

//интервал между считываниями данных с датчика 1:      
      const uint32_t DelayPeriod = 2000; 

//когда в последний раз были прочитаны данные с датчика 1:     
      uint32_t Sensor1LastReadingTime = 0;

// Пин, к которому подключён датчик Холла, на входной двери:
#define HALLPIN 13 
int value ; // переменная для хранения значения с датчика  


И установим переменные управляющих контактов. Здесь под управляющими контактами подразумеваются те, что будут управлять транзисторными ключами и могут быть подключены к абсолютно разным устройствам: полива цветов, проветривания комнаты или теплицы и т.д. Для примера указан только один вариант, вы же можете установить нужное вам количество, создав их в необходимой для вас конфигурации:

// Пин, к которому подключён транзисторный ключ полива цветов:
const int mosfetPin = 19;

//начало времени работы двигателя полива цветов:
uint32_t pauseStartTime = 0;

//количество миллисекунд работы двигателя полива:
const uint32_t WORKperiod = 8000;


Из интересных моментов стоит отметить ещё и функцию прерывания, которая содержится в методе setup (). Дело здесь в следующем: так как (предположительно) событие проникновения в квартиру является довольно краткосрочным, то есть гипотетический вор быстро откроет дверь и так же быстро её закроет, поэтому мы устанавливаем функцию прерывания, которая прерывает исполнение кода и отправляет сообщение о взломе в любой момент работы программы. Это позволит не пропустить соответствующее изменение состояния датчика. Другими словами, при открытии двери сигнал от цифрового датчика Холла изменится на HIGH и будет вызвана функция Email_ handler:

  attachInterrupt(digitalPinToInterrupt (HALLPIN), Email_handler, HIGH);


Благодаря чёткому разделению программы на функциональные блоки, мы можем видеть, что метод loop () весьма разгружен и является очень лаконичным и легко понимаемым:

void loop(){

 //проверка и реконнект при потере связи:
   ConnectionsChecker ();

 //чтение показателей датчиков:   
   SensorsReader ();   

//проверка - нет ли новых сообщений на исполнение с MQTT-брокера:   
   client.loop();

// отправка сообщения на Email при возникновении критических ситуаций:   
   Email_handler(); 
}


Рассмотрим составные его элементы подробнее

Как можно видеть, функция ConnectionsChecker — отвечает за две операции: восстановление связи с роутером при её потере и за восстановление связи с mqtt-брокером при пропадании таковой:

void ConnectionsChecker () 
{
    //если разрыв соединения с точкой доступа — восстанавливаем связь:
  if (WiFi.status() != WL_CONNECTED)
     {
           setup_wifi(); 
     }
   
  //если разрыв соединения с MQTT-брокером — восстанавливаем связь: 
  if (!client.connected()) 
     {
      reconnect();
     }
}


Функция Email_ handler отвечает за отправку соответствующих e-mail сообщений при возникновении определённых условий:

      String textMsg = "";

      if (humiditySensor1>=ALARM_for_HumiditySensors)
      {
        textMsg = "ОПАСНОСТЬ! Превышение уровня влажности в квартире!";
      }
      else if (temperatureSensor1>=ALARM_for_temperatureSensors)
      {
        textMsg = "ОПАСНОСТЬ! Опасная температура в квартире!";        
      }
      else
      {
        textMsg = "ОПАСНОСТЬ-ВЗЛОМ! Проникновение через дверь!";        
      }


Функция MQTT_handler служит для обработки сообщений, которые были получены микроконтроллером и должны быть исполнены. Здесь также для примера приведён только один вариант сообщения — получение цифры 0, при таком варианте включается электродвигатель насоса и происходит полив цветов. Вы же можете раскомментировать необходимые строки, либо даже добавить количество условий для вашего конкретного случая:

              if(ch[0]=='0')
              { 
                Serial.println("Полить цветы");
                pauseStartTime = millis();

                //включаем двигатель полива цветов:               
                digitalWrite(mosfetPin, HIGH);

                //ничего не делаем, просто ждём:
                while ( (millis() - pauseStartTime)


И последняя функция SensorsReader занимается обработкой показателей от датчика влажности и температуры. В данную функцию также возможно добавить большее количество датчиков, например, для отслеживания температуры и влажности в различных комнатах. Здесь же для примера приведён только один датчик.

Интересным моментом этой функции является то, что она после считывания параметров публикует их в подходящие топики mqtt-брокера, после чего эти показатели могут быть считаны приложением на смартфоне в любой момент. Таким образом, владелец всегда может быть осведомлён о состоянии «погоды» в квартире:

    client.publish(MQTT_PUBLISHING_CHANNEL_2, dtostrf(humiditySensor1, 5, 2, humidity) );
    client.publish(MQTT_PUBLISHING_CHANNEL_3, dtostrf(temperatureSensor1, 5, 2, temperature) );


В качестве приложения для смартфона можно использовать, например, MQTT Dash или любое другое по вкусу.

Файл проекта Arduino IDE в архиве, можно скачать здесь.

НЛО прилетело и оставило здесь промокоды для читателей нашего блога:

HABRFIRSTVDS — скидка 15% на все тарифы VDS, кроме VDS Прогрев, на сайте firstvds.ru.

HABRFIRSTDEDIC — скидка 20% на гибкие конфигурации выделенных серверов на базе процессоров AMD Ryzen и Intel Core на сайте 1dedic.ru.

Скидка применяется на весь оплаченный период (1, 3, 6 или 12 месяцев) и распространяется только на ресурсы сервера. Воспользоваться промокодом можно до 31.12.21 при заказе любого количества новых серверов.

© Habrahabr.ru