Как сделать умный дом своими руками, ч. 1: выбор технологий, управление светом

8 July 2018, 03:20 MSK
Последнее время я увлекаюсь системами умного дома и хотел бы поделиться накопившимся опытом. В серии постов на эту тему я расскажу как о попытке сделать свою систему с нуля, так и о готовых решениях.
smart-home
Педантичный читатель обязательно придерётся к термину «умный дом». Конечно, правильнее называть это домашней автоматизацией, но я позволю себе использовать хоть и неверную, но устоявшуюся формулировку.
Сейчас на рынке присутствует очень много разрозненных решений. Ради эксперимента мне захотелось попробовать сделать что-нибудь самому.
Хороший проект всегда начинается с требований к конечному результату, вот мои:
  1. Нафиг километры проводов. У меня в квартире сделан ремонт, поэтому заново штробить стены желания совсем нет. Пусть умный дом будет обмениваться данными по радио-каналу.
  2. Нафиг бредовые идеи. Встроить айпад с интерфейсом в стену? Отправлять данные на народный мониторинг? Ну уж нет, спасибо, обойдёмся без этого.
  3. Нафиг пульты. Пульты всегда теряются и ломаются. Лучший пульт — тот, который всегда с тобой. Это телефон или часы (привет, Сири!). Также не забудем оставить классические элементы управления (настенный выключатель, ггг) для менее продвинутых домочадцев.
Теперь подумаем над архитектурой. Философия моего умного дома будет такой (привет, Юникс!):
Одно устройство должно делать только одну вещь, но должно делать её хорошо.
Такой подход лаконичен и позволяет не смешивать всё в одну кучу, не усложнять архитектуру системы, превращая устройства в многофункциональные комбайны.
Как я вижу примерное устройства умного дома:
схема умного дома
Теперь подробнее. Итак, должен быть некий центральный узел — контроллер (или сервер), который будет хранить информацию обо всех других устройствах, а также реагировать на команды от пользователя, предоставляя ему удобный интерфейс. Периферийные устройства при этом ничего не будут знать друг о друге и о пользователе, общаясь только с центральным узлом. Таким образом, всё взаимодействие будет происходить через контроллер.
В качестве основы для контроллера умного дома я выбрал одноплатник Raspberry Pi 3 Model B (далее буду называть его «Малина»), вот так он выглядит:
raspberry pi
Малина хороша надёжностью, открытостью, маленькими размерами, ценой (35$ по карте Мастеркард) и удобством разработки (внутри — обычный Линукс).
Периферийные устройства решил делать на Arduino. Бывалый железячник здесь должен высказать своё «фи», но всё же Ардуина — оптимальная платформа для новичков в электронике и микроконтроллерах, опять же таки преимущества: открытая архитектура, низкий порог входа, простота изучения, низкая цена.
И у Малины, и у Ардуины огромное число последователей по всему миру, поэтому многие проблемы обычно уже решены до вас и легко гуглятся при наличии минимального уровня английского.
Осталось решить, каким образом будет организовано взаимодействие между Малиной и несколькими Ардуинами. Напомню, от проводов я отказался, поэтому выбираем между беспроводными технологиями. От 433 МГц я отказался в виду отсутствия шифрования и перегруженности частоты в городах. От ZigBee я отказался, потому что их модули стоят неоправданно дорого (50-60$), а мне хотелось сделать бюджетное решение. От Z-Wave я отказался ввиду проприетарности протокола и сложности коннекта с Ардуиной.
Собственно, выбрал я Wi-Fi, и вот почему. Wi-Fi обеспечивает хорошую безопасность и легко встраивается в существующую инфраструктуру. Роутер Wi-Fi есть в каждом доме и обычно покрывает всю площадь помещения. Если дальности не хватает — можно поставить несколько роутеров или репитеров. С Wi-Fi не придётся заморачиваться с низкоуровневыми протоколами (есть TCP/IP), но придётся придумать свой высокоуровневый протокол для обмена данными между устройствами и контроллером (это не сложно).
Ещё большой плюс Wi-Fi — мощные, но очень дешёвые модули ESP8266 (3-4$), позволяющие подключить любое самодельное устройство к сети. Модули очень маленькие, но с богатыми возможностями (умеют создавать свою сеть, а не только подключаться к существующим). Причём, в них есть свой микроконтроллер, и его можно прошивать (через Arduino IDE). То есть, теоретически можно было бы обойтись без Ардуины, но для этого нужна другая модификация модуля, например, ESP-12E (на нём просто больше GPIO-выводов), а я использовал модификацию ESP-01 в силу куда большей распространённости и простоты для новичка.
Итак, с технологиями и примерной архитектурой определились, теперь перейдём к созданию первого устройства. Любой умный дом, как правило, начинается с освещения, мы тоже не будем отклоняться от этой традиции — будем делать умную лампочку (или умный выключатель), которой можно будет управлять с телефона или компьютера.
Обычный выключатель замыкает или размыкает электрическую цепь механически. Для того, чтобы замыкать и размыкать цепь не механически, а электронно, будем использовать реле: подали управляющий сигнал — цепь замкнулась (и лампочка зажглась), убрали сигнал — цепь разомкнулась (и лампочка погасла).
Вот так выглядит прототип устройства:
умный выключатель на макетной плате
Синий кабель — питание 5В, в качестве микроконтроллера Искра Нео (можно юзать Искру Мини) — российский аналог Ардуино, в разрыв цепи лампочки (230В) вставлено реле, также на схеме присутствуют модуль ESP8266, кнопка (чтобы можно было включать/выключать лампочку не только с телефона, но и руками) и светодиод (для тестирования, пока не была подключена лампочка). Все компоненты можно купить как в России, так и заказать из Китая на Алиэкспрессе.
На самом деле, так как Ардуина работает от 5В, а ESP8266 от 3.3В, ему нужно было собрать некоторую обвязку, а не подключать напрямую. Несмотря на то, что все статьи в интернете уверяют, что модуль сгорит от 5В, я подключил его напрямую и не наблюдаю проблем в течение года при постоянном использовании. По-хорошему, конечно, нужно собрать стабилизатор питания (например, на схеме LM317).
Если вы хотите этот прототип превратить в работающий умный выключатель, то для организации питания Арудины проще всего разобрать недорогой китайский блок питания на 5В и вынуть из него внутренности.
Проводка в квартире находится под высоким напряжением (~230В), работа с которым представляет большую опасность для здоровья и жизни. Например, прикосновение даже к некоторым участкам включённого реле приведёт к неминуемому поражению электрическим током, которое может повлечь серьёзные травмы и даже смерть. Неправильное подключение блока питания или других устройств к сети может привести к возгоранию. Люди, не имеющие необходимой квалификации, не должны каким-либо образом производить описанные в данной статье действия. Если у вас есть хоть малейшие сомнения в работе с электрическими сетями, остановитесь. Всё, что вы делаете, вы делаете на ваш страх и риск. Автор статьи не несёт ответственности за любые ваши действия.
Принципиальная схема моего умного выключателя:
принципиальная схема умного выключателя
Здесь всё очень просто. Реле подсоединяется к контроллеру через 3 контакта: питание, земля, сигнал. С другой стороны расположен клеммник, на котором есть как нормально закрытый (NC), так и нормально открытый (NO) контакты. При подаче управляющего сигнала NC-контакт открывается и пропускает ток, а NO-контакт закрывается. Подключение светодиода и кнопки — это первое, что пробуют все начинающие ардуинщики, так что на этом останавливаться не будем. ESP8266 подключается по UART интерфейсу (RX к TX, TX к RX), в нём залита штатная прошивка на AT-командах.
Для удобства отладки прототипа я использую Искру Нео — аналог Ардуино Леонардо (у них USB работает через виртуальный Serial-порт).
Логика работы устройства следующая:
  • При получении по Wi-Fi команды о включении/выключении света — замыкаем/размыкаем реле;
  • При нажатии на кнопку — меняем положение реле, отправляем по Wi-Fi сообщение о смене статуса.
В ESP8266 предварительно прописаны следующие AT-команды:
AT+CWMODE_DEF=1
AT+CWJAP_DEF="имя вашей Wi-Fi сети","пароль вашей Wi-Fi сети"
О том, как устроен контроллер моего умного дома, я расскажу позже, но пока важно отметить следующее. Контроллер умеет отправлять управляющие команды устройствам, а также принимать команды от них.
Команды на включение/выключение лампочки выглядит так:
^#00000001#111111#status#on#$
^#00000001#111111#status#off#$
Когда лампочка включена/выключена кнопкой, она отправляет контроллеру такие же команды:
^#00000001#111111#status#on#$
^#00000001#111111#status#off#$
Здесь 00000001 — ID устройства, 111111 — пароль доступа, status — название команды, on/off — пароль команды.
В следующей заметке я подробно расскажу об этом простейшем протоколе, а также об устройстве контролера моего умного дома.
Исходный код скетча для Ардуины приведён ниже:
#define ESP Serial1
// уникальный ID устройства String devUniq = "00000001";
// тип устройства String devType = "switch1";
// пароль доступа String homePassword = "111111";
// IP-адрес контроллера String homeServer = "192.168.1.100";
// нумерация PIN'ов #define PIN_REL 4  // реле #define PIN_LED 5  // светодиод #define PIN_BTN 8  // кнопка
// статус лампочки (true - вкл, false - выкл) boolean myStatus = false;
// инициализация устройства void setup() {
  // подготавливаем Serial порт и ESP   Serial.begin(115200);   ESP.begin(115200);   while (!ESP);   delay(5000);
  // настраиваем TCP/IP-сервер на ESP на порт 777   ESP.println("AT+CIPMUX=1");   delay(100);   ESP.println("AT+CIPSERVER=1,777");   ESP.println("AT+CIPSTO=10");
  // настраиваем PIN'ы на ввод/вывод   pinMode(PIN_LED, OUTPUT);   digitalWrite(PIN_LED, myStatus);
  pinMode(PIN_REL, OUTPUT);   digitalWrite(PIN_REL, myStatus);
  pinMode(PIN_BTN, INPUT);    }
// обработка команд для устройства void process(String cmd, String prm) {   if (cmd == "status") {     if (prm == "on") myStatus = true;     if (prm == "off") myStatus = false;     digitalWrite(PIN_LED, myStatus);     digitalWrite(PIN_REL, myStatus);   } }
// обработка нажатий кнопки boolean btn_flag = false; long btn_time = 0; void btn_pressed() {
  // меняем статус лампочки   myStatus = !myStatus;   digitalWrite(PIN_LED, myStatus);   digitalWrite(PIN_REL, myStatus);
  // отправляем команду контроллеру   String data = "";   data = "^#" + devUniq + "#" + homePassword + "#status#" + (myStatus ? "on" : "off") + "#$";   int len = data.length();   ESP.println("AT+CIPSTART=2,\"TCP\",\"" + homeServer + "\",7777");   if (ESP.find("Error")) {     Serial.println("connection error");     return;   }   ESP.print("AT+CIPSEND=2,");   ESP.println(len);   delay(10);   if (!ESP.find(">")) {     ESP.println("AT+CIPCLOSE=2");     Serial.println("timeout error");     return;   }   ESP.print(data);   ESP.println("AT+CIPCLOSE=2");    }
// основной цикл программы String pack = ""; void loop() {   String id, pw, cmd, prm;   int i, l, q;
  // для отладки из монитора порта   if (Serial.available()) {     ESP.write(Serial.read());   }
  // получили данные с контроллера - вызываем обработчик   if (ESP.available()) {     char c = ESP.read();     Serial.write(c);     switch (c) {       case '+':         pack = "";       break;       case '^':         pack = "";       break;       case '$':         id = "";         pw = "";         cmd = "";         prm = "";         i = 0, q = 0;         l = pack.length();         if (!l) break;         while (i < l) {           c = pack[i++];           if (c == '#') {             q++;             continue;           }           switch (q) {             case 1: id += c; break;             case 2: pw += c; break;             case 3: cmd += c; break;             case 4: prm += c; break;           }         }         if (id != devUniq) break;         if (pw != homePassword) break;         process(cmd, prm);       break;       default:         pack += c;       break;     }       }
  // была нажата кнопка - вызываем обработчик   int pressed = !digitalRead(PIN_BTN);   if (pressed && !btn_flag) {     btn_flag = true;     btn_time = millis();     btn_pressed();   }   if (millis() - btn_time > 200 && !pressed) {     btn_flag = false;   }    }
При получении команды лампочка включается:
умный выключатель в работе
Если вам интересно продолжение, подписывайтесь на мой блог через РСС, Телеграм, Твиттер или на меня в соц. сетях: ВКонтакте, Фейсбук, Инстаграм. Дальше я расскажу, как сделать управление обычным кондиционером с телефона, покажу интерфейс управления умным домом, а также расскажу, как я интегрировал его с Apple Homekit и Siri. Не стесняйтесь писать комментарии или сообщения в личку — я с радостью отвечу на вопросы, учту замечания или просто пообщаюсь на интересные темы.
Поделиться
Телеграмнуть
Вотсапнуть