ESP8266 NodeMCU: Монитор состояния двери с уведомлениями по электронной почте (IFTTT)

В этом проекте вы будете отслеживать состояние двери с помощью платы ESP8266 NodeMCU и магнитного герконового переключателя (magnetic reed switch). Вы будете получать уведомление по электронной почте каждый раз, когда дверь меняет состояние: открыта или закрыта. Уведомления по электронной почте будут отправляться с помощью IFTTT, а плата ESP8266 будет запрограммирована с использованием Arduino IDE.

ESP8266 NodeMCU Монитор состояния двери с уведомлениями по электронной почте IFTTT Arduino IDE

Вместо отправки уведомлений по электронной почте с помощью IFTTT вы можете использовать SMTP-сервер. Чтобы узнать, как отправлять электронные письма с вашего ESP8266 с помощью SMTP-сервера, вы можете следовать следующему руководству:

Если хотите, вы также можете отправлять уведомления в свой аккаунт Telegram. Узнайте, как использовать Telegram с ESP8266 в следующем руководстве:

У нас есть аналогичное руководство для платы ESP32: Монитор состояния двери с уведомлениями по электронной почте (IFTTT)

Обзор проекта

В этом проекте вы будете отправлять уведомление по электронной почте каждый раз, когда дверь меняет состояние. Для обнаружения изменения мы будем использовать магнитный контактный переключатель. Для отправки электронного письма мы будем использовать IFTTT.

Магнитный контактный переключатель — это, по сути, герконовый переключатель (reed switch), заключённый в пластиковый корпус, чтобы его можно было легко прикрепить к двери, окну или ящику для определения того, открыта дверь или закрыта.

Магнитный контактный переключатель (герконовый переключатель)

Электрическая цепь замкнута, когда магнит находится рядом с переключателем — дверь закрыта. Когда магнит находится далеко от переключателя — дверь открыта — цепь разомкнута. Смотрите рисунок ниже.

Принцип работы магнитного герконового переключателя

Мы можем подключить герконовый переключатель к GPIO ESP8266 для обнаружения изменений его состояния.

Отправка электронных писем с помощью IFTTT

Для отправки электронных писем с ESP8266 мы будем использовать бесплатный* сервис под названием IFTTT, что расшифровывается как «If This Then That» (Если Это, То То).

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

Мне нравится сервис IFTTT, и как только вы поймёте, как он работает, им легко пользоваться. Однако мне не очень нравится компоновка их веб-сайта и тот факт, что она постоянно меняется.

* в настоящее время в бесплатной версии можно одновременно иметь три активных апплета.

Создание учётной записи IFTTT

Создание учётной записи на IFTTT бесплатно!

Перейдите на официальный сайт: https://ifttt.com/ и нажмите кнопку Get Started в верхней части страницы или Signup, если у вас уже есть учётная запись.

Начальная страница IFTTT Get Started

Создание апплета

Сначала вам нужно создать апплет (Applet) в IFTTT. Апплет соединяет два или более приложений или устройств вместе (например, ESP8266 и отправку электронного письма).

Апплеты состоят из триггеров и действий:

  • Триггеры (Triggers) сообщают апплету о начале работы. ESP8266 отправит запрос (webhooks), который запустит апплет.

  • Действия (Actions) — это конечный результат работы апплета. В нашем случае — отправка электронного письма.

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

1) Нажмите на эту ссылку, чтобы начать создание апплета.

2) Нажмите на кнопку Add.

IFTTT Создание апплета

3) Найдите «Webhooks» и выберите его.

IFTTT Создание апплета - выбор сервиса

4) Выберите опцию «Receive a web request».

IFTTT Создание апплета - webhooks получение веб-запроса

5) Введите имя события, например, door_status. Вы можете назвать его как угодно, но если вы измените его, вам также нужно будет изменить его в коде, предоставленном далее.

IFTTT Создание апплета - получение веб-запроса

6) Затем вам нужно нажать кнопку Add в меню «Then that», чтобы выбрать, что произойдёт при срабатывании предыдущего события.

IFTTT Создание апплета - создание собственного

7) Найдите email и выберите опцию email.

IFTTT Создание апплета - выбор сервиса email

8) Нажмите на Send me an email.

IFTTT Создание апплета - выбор действия

9) Затем напишите тему и тело письма. Вы можете оставить сообщение по умолчанию или изменить его на что угодно. {{EventName}} — это заполнитель для имени события, в данном случае это door_status. {{OccuredAt}} — это заполнитель для временной метки, когда событие было вызвано. {{Value1}} — это заполнитель для фактического состояния двери. Таким образом, вы можете использовать эти заполнители для написания собственного сообщения. Когда закончите, нажмите на Create action.

IFTTT Создание апплета - настройка полей действия eventName

10) Теперь вы можете нажать на Continue.

IFTTT Создание апплета - создание собственного

11) Наконец, нажмите на Finish.

IFTTT Создание апплета - обзор и завершение

12) Вы будете перенаправлены на похожую страницу — как показано ниже.

IFTTT Создание апплета - подключено

Ваш апплет был успешно создан. Теперь давайте его протестируем.

Тестирование вашего апплета

Перейдите по этому URL: https://ifttt.com/maker_webhooks и откройте вкладку «Documentation».

Вы получите доступ к веб-странице, где можете вызвать событие для его тестирования и получить доступ к вашему API-ключу (выделен красным). Сохраните ваш API-ключ в безопасном месте, потому что он понадобится вам позже.

Тестирование апплета IFTTT

Теперь давайте запустим событие для его тестирования. В заполнителе {event} напишите событие, которое вы создали ранее. В нашем случае это door_status. Кроме того, добавьте значение в поле value1, например open. Затем нажмите кнопку Test It.

Тестирование апплета IFTTT

Вы должны получить сообщение об успехе «Event has been triggered», и вы должны получить электронное письмо в свой почтовый ящик, информирующее вас о том, что событие было вызвано.

Апплет IFTTT успешно протестирован

Если вы получили электронное письмо, ваш апплет работает как ожидалось. Вы можете перейти к следующему разделу. Мы запрограммируем ESP8266 для запуска вашего апплета при изменении состояния двери.

Список необходимых компонентов

Вот оборудование, которое вам нужно для завершения этого проекта:

Компонент

Количество

ESP8266 — читайте Лучшие платы разработки ESP8266 Wi-Fi

1

Магнитный герконовый переключатель (Magnetic Reed Switch)

1

Резистор 10 кОм

1

Макетная плата (breadboard)

1

Соединительные провода (jumper wires)

1 комплект

Вы можете использовать ссылки выше или перейти непосредственно на MakerAdvisor.com/tools, чтобы найти все компоненты для ваших проектов по лучшей цене!

Схема — ESP8266 NodeMCU с герконовым переключателем

Мы подключили герконовый переключатель к GPIO 4 (D2), но вы можете подключить его к любому подходящему GPIO.

Схема подключения ESP8266 NodeMCU с герконовым переключателем

Код

Скопируйте скетч ниже в вашу Arduino IDE. Замените SSID, пароль и API-ключ IFTTT на ваши собственные учётные данные.

/*********
  Rui Santos & Sara Santos - Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/door-status-monitor-using-the-esp8266/
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/

#include <ESP8266WiFi.h>

// Set GPIOs for LED and reedswitch
const int reedSwitch = 4;
const int led = 2; //optional

// Detects whenever the door changed state
bool changeState = false;

// Holds reedswitch state (1=opened, 0=close)
bool state;
String doorState;

// Auxiliary variables (it will only detect changes that are 1500 milliseconds apart)
unsigned long previousMillis = 0;
const long interval = 1500;

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
const char* host = "maker.ifttt.com";
const char* apiKey = "REPLACE_WITH_YOUR_IFTTT_API_KEY";

// Runs whenever the reedswitch changes state
ICACHE_RAM_ATTR void changeDoorStatus() {
  Serial.println("State changed");
  changeState = true;
}

void setup() {
  // Serial port for debugging purposes
  Serial.begin(115200);

  // Read the current door state
  pinMode(reedSwitch, INPUT_PULLUP);
  state = digitalRead(reedSwitch);

  // Set LED state to match door state
  pinMode(led, OUTPUT);
  digitalWrite(led, state);

  // Set the reedswitch pin as interrupt, assign interrupt function and set CHANGE mode
  attachInterrupt(digitalPinToInterrupt(reedSwitch), changeDoorStatus, CHANGE);

  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
}

void loop() {
  if (changeState){
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      // If a state has occurred, invert the current door state
      state = !state;
      if(state) {
        doorState = "closed";
      }
      else{
        doorState = "open";
      }
      digitalWrite(led, state);
      changeState = false;
      Serial.println(state);
      Serial.println(doorState);

      //Send email
      Serial.print("connecting to ");
      Serial.println(host);
      WiFiClient client;
      const int httpPort = 80;
      if (!client.connect(host, httpPort)) {
        Serial.println("connection failed");
        return;
      }

      String url = "/trigger/door_status/with/key/";
      url += apiKey;

      Serial.print("Requesting URL: ");
      Serial.println(url);
      client.print(String("POST ") + url + " HTTP/1.1\r\n" +
                          "Host: " + host + "\r\n" +
                          "Content-Type: application/x-www-form-urlencoded\r\n" +
                          "Content-Length: 13\r\n\r\n" +
                          "value1=" + doorState + "\r\n");
    }
  }
}

Посмотреть исходный код

У вас должно быть установлено дополнение платы ESP8266 в вашей Arduino IDE. Если нет, следуйте следующему руководству:

Как работает код

Продолжайте читать, чтобы узнать, как работает код, или перейдите к разделу Демонстрация.

Сначала вам нужно подключить библиотеку ESP8266WiFi, чтобы ESP8266 мог подключиться к вашей сети для взаимодействия с сервисами IFTTT.

#include <ESP8266WiFi.h>

Установите GPIO для герконового переключателя и светодиода (встроенный светодиод — GPIO 2). Мы будем включать встроенный светодиод, когда дверь открыта.

const int reedSwitch = 4;
const int led = 2; //optional

Булевая переменная changeState указывает, изменилось ли состояние двери.

bool changeState = false;

Переменная state будет хранить состояние герконового переключателя, а doorState, как следует из названия, будет хранить состояние двери — закрыта или открыта.

bool state;
String doorState;

Следующие переменные таймера позволяют нам устранить дребезг переключателя. Будут учитываться только изменения, произошедшие с интервалом не менее 1500 миллисекунд.

unsigned long previousMillis = 0;
const long interval = 1500;

Введите ваш SSID и пароль в следующие переменные, чтобы ESP8266 мог подключиться к интернету.

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Введите ваш собственный API-ключ IFTTT в переменную apiKey — тот, который вы получили на этом шаге.

const char* apiKey = "REPLACE_WITH_YOUR_IFTTT_API_KEY";

Функция changeDoorStatus() будет запускаться каждый раз, когда обнаруживается изменение состояния двери. Эта функция просто меняет переменную changeState на true. Затем в loop() мы обработаем, что происходит при изменении состояния (инвертируем предыдущее состояние двери и отправим электронное письмо).

ICACHE_RAM_ATTR void changeDoorStatus() {
  Serial.println("State changed");
  changeState = true;
}

setup()

В setup() инициализируйте монитор последовательного порта для целей отладки:

Serial.begin(115200);

Установите герконовый переключатель как INPUT. И сохраните текущее состояние при первом запуске ESP8266.

pinMode(reedSwitch, INPUT_PULLUP);
state = digitalRead(reedSwitch);

Установите светодиод как OUTPUT и установите его состояние в соответствии с состоянием герконового переключателя (цепь замкнута — светодиод выключен; цепь разомкнута — светодиод включен).

pinMode(led, OUTPUT);
digitalWrite(led, state);
  • дверь закрыта –> ESP8266 считывает сигнал HIGH –> выключить встроенный светодиод (отправить сигнал HIGH*)

  • дверь открыта –> ESP8266 считывает сигнал LOW –> включить встроенный светодиод (отправить сигнал LOW*)

Встроенный светодиод ESP8266 работает с инвертированной логикой — отправьте сигнал HIGH, чтобы его выключить, и сигнал LOW, чтобы его включить.

Настройка прерывания

Установите герконовый переключатель как прерывание.

attachInterrupt(digitalPinToInterrupt(reedSwitch), changeDoorStatus, CHANGE);

Чтобы установить прерывание в Arduino IDE, вы используете функцию attachInterrupt(), которая принимает в качестве аргументов: GPIO-пин прерывания, имя функции для выполнения и режим.

Первый аргумент — это GPIO прерывания. Вы должны использовать digitalPinToInterrupt(GPIO) для установки фактического GPIO в качестве пина прерывания.

Второй аргумент функции attachInterrupt() — это имя функции, которая будет вызываться каждый раз при срабатывании прерывания — функция обработки прерывания (ISR). В данном случае это функция changeDoorStatus.

Функция ISR должна быть как можно проще, чтобы процессор быстро вернулся к выполнению основной программы.

Третий аргумент — это режим. Мы устанавливаем его в CHANGE, чтобы прерывание срабатывало каждый раз, когда пин меняет значение — например, с HIGH на LOW или с LOW на HIGH.

Чтобы узнать больше о прерываниях с ESP8266, прочитайте следующее руководство:

Инициализация Wi-Fi

Следующие строки подключают ESP8266 к Wi-Fi.

WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");

loop()

В loop() мы будем читать переменную changeState и, если произошло изменение, отправим электронное письмо с помощью IFTTT.

Сначала проверяем, произошло ли изменение:

if (changeState){

Затем проверяем, прошло ли хотя бы 1500 миллисекунд с момента последнего изменения состояния.

if(currentMillis - previousMillis >= interval) {

Если это так, сбрасываем таймер и инвертируем текущее состояние переключателя:

state = !state;

Если состояние герконового переключателя равно 1 (true), дверь закрыта. Поэтому мы меняем переменную doorState на closed.

if(state) {
  doorState = "closed";
}

Если оно равно 0 (false), дверь открыта.

else{
  doorState = "open";
}

Устанавливаем состояние светодиода соответственно и выводим состояние двери в монитор последовательного порта.

digitalWrite(led, state);
changeState = false;
Serial.println(state);
Serial.println(doorState);

Наконец, следующие строки отправляют запрос в IFTTT с текущим состоянием двери для события (door_status), которое мы создали ранее.

// Send email
Serial.print("connecting to ");
Serial.println(host);
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
  Serial.println("connection failed");
  return;
}

String url = "/trigger/door_status/with/key/";
url += apiKey;

Serial.print("Requesting URL: ");
Serial.println(url);
client.print(String("POST ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Content-Type: application/x-www-form-urlencoded\r\n" +
               "Content-Length: 13\r\n\r\n" +
               "value1=" + doorState + "\r\n");

Когда IFTTT получает этот запрос, он запускает действие по отправке электронного письма.

Демонстрация

После изменения скетча с включением ваших сетевых учётных данных и API-ключа загрузите его на ваш ESP8266. Перейдите в Tools > Board и выберите вашу плату ESP8266. Затем перейдите в Tools > Port и выберите COM-порт, к которому подключен ESP8266.

Откройте монитор последовательного порта на скорости 115200 бод, чтобы проверить, обнаруживаются ли изменения и может ли ESP8266 подключиться к IFTTT.

Тестирование IFTTT с ESP8266 NodeMCU

Для прототипирования/тестирования вы можете прикрепить магнитный герконовый переключатель к двери с помощью липучки Velcro.

Тестирование IFTTT с ESP8266 NodeMCU

Теперь, когда кто-то открывает/закрывает вашу дверь, вы получаете уведомление по электронной почте.

Состояние двери - полученное письмо IFTTT ESP8266 NodeMCU

Смотрите видео-демонстрацию

Мы записали это видео несколько лет назад (извините за плохое качество).

Подведение итогов

В этом руководстве вы узнали, как вызвать событие при изменении состояния герконового переключателя. Это может быть полезно для определения того, была ли дверь, окно или ящик открыт или закрыт. Вы также узнали, как использовать IFTTT для отправки электронного письма при срабатывании события.

Вместо отправки электронного письма вы можете захотеть отправить сообщение в Telegram, например.

Мы надеемся, что это руководство было полезным для вас. Если вы хотите узнать больше о плате ESP8266, ознакомьтесь с нашими ресурсами:

Спасибо за чтение.