Найти тему
НТР от Никитоса

Умная теплица в Telegram

Добрый день. На нашем участке имеется теплица. Её главная проблема — перегрев в жаркое время, т.к. рассчитана в первую очередь на сибирскую весну. Единственный выход — постоянно открывать/закрывать двери и окна, чтобы поддерживать температуру. Но это не всегда возможно. А если это не сделать, то температура поднимается до +50 градусов, что явно не хорошо. А вечером всё можно заморозить. Так и началась её автоматизация.

В первую очередь мы купили Raspberry Pi 2. Разобравшись с ним, подключили датчик DS18B20 по этой статье. Затем были куплены два б/у автомобильных стеклоподъёмника. Как и все DC двигатели, они движутся в зависимости от полярности. Поэтому к каждому двигателю подключаем два реле: одно для открытия, другое для закрытия. Эти реле уже через транзисторы подключаем к самим портам GPIO. И питаем это всё дело аккумулятором 12V. Так же, чтобы не сжечь двигатели, в крайних положениях окна были установлены концевые выключатели, и в случае, если окно открылось/закрылось полностью рвут сеть.

-2
-3

А для связи мы используем WiFi адаптер TP-LINK с усовершенствованной антенной «Двойной квадрат» для уверенного приёма домашнего WIFI роутера, который находится на расстояние 40 метров.

-4

Теперь пишем программу для управления этими приводами. Был выбран язык Python, т. к. у него нормальная поддержка Raspberry Pi и конкретно GPIO портов. Для того, чтобы открыть окно, нам нужно подать +3.3V на транзистор, который активирует реле, и то начнёт открывать окно. Чтобы его закрыть, делаем то же самое, только в это случаем наше реле подключено наоборот к приводу. Но на Raspberry мы просто подаём ток то на один порт, то на другой. Мы решили, что если температура больше 26 открываем окно в течение 1 секунды. Затем ждём 3 минуты. Если опять жарко, то открываем второе окно в течение секунды. Ждём опять 3 минуты, и делаем заново. То же самое с закрытием, только тут температура должна быть ниже 24 градусов. А вот и код.

А теперь начинается шоу для тех, кому физика не интересна.

Установив Apache на дистрибутив Raspbian, мы в течение месяца не могли достучаться до странички из интернета. Что только не делали. Настраивали порты, открывали их, ничего не помогала. Причём в локальной сети всё работали. Потом мы узнали печальную правду: мы находимся за NAT. И услуг по выделенному IP наш оператор не предоставляет (Привет сотрудникам Регион Телекома). Перебирали много обходных методов, но ничего не выходило. Пытался сделать веб интерфейс на хостинге, но для синхронизации базы данных тоже нужен IP. Брокер IPv6 к тому времени уже закрылся. А делать VPN дорого, ведь хочется всё бесплатно. И тут решили использовать Telegram бота. Как оказалось он имеет два режима: постоянный опрос сервера и отправка сообщений прямо к нам. Первый вариант подходил, т.к. не требует от нам IP адреса. Покопавшись в интернете нашёл библиотеку: pytelegrambotapi. И принялся за написание кода. Правда выходили и проблемы. Еле найденная MySQL библиотека отказывалась писать в базу данных, но при это читала из неё всё нормально. Пришлось делать костыль: передавать данные в файл, хранящийся в ОЗУ, затем запускать bash скрипт, который считает данные и занесёт в БД.
Делаем файл config.ini, туда кидаем:

[mysql]
host = localhost
database = telegram
user = root
password = secret

Не забываем данные заменить на свои.

Так же нам нужен этот и этот файл.

Теперь мы всё подготовили для работы с БД.

Отвлечёмся немного от базы данных и перейдём непосредственно к общению с ботом. Ну как обычно, пишем @BotFather, и берём у него токен. Создаём файл config.py, и пишем в него две строчки:

# -*- coding: utf-8 -*-
token = 'Ваш токен'

Я решил реализовать в боте три функции:

  • Получение температуры
  • Получение снимков
  • Управление окнами

С первым всё просто, по запросу читаем файл с температурой, и отправляем это пользователю.

Со снимками посложнее. Я использую утилиту Motion. В её параметрах проси класть в папку в оперативной памяти снимки, ну допустим каждые 30 секунд. И делаем файлы с одинаковыми имена, и они просто заменяют друг друга. А потом по запросу отправляем файл пользователю.

Ну и третий, самый сложный модуль: управление окнами. У меня главная задача: чтобы работала автоматика, но если нужно, то мы её можем отключить. Делал я это так. Создал в оперативной памяти очередной файл. Когда мы отправляем запрос на открытие/закрытие, приоткрытие, призакрытие окна или на включение/выключение автоматики бот пишет в этот файл номер команды. Каждые пять секунд программа управления окнами считывает этот файл, и если распознаёт команду, выполняет её. После выполнение в этот же файл пишет, что всё прошло успешно. Бот опять читает файл, и уведомляет нас, что команда выполнена.

Ну а теперь исходный код. Сначала та же самая программа для открывания окон, только уже переделанная под бота(temp.py).

Но а теперь поговорим про самого бота. Как я уже говорил, я использую библиотеку PyTelegramBotApi. Если обратиться к документации на GitHub, то можно понять что для обработки команд бот использует хендлеры. Хендлер — это событие в нашей программе, определяющие действие. В нашей случае это определенная фраза в сообщение. А действие это всё что мы можем сделать в языке python. В данном случае мы будет присылать пользователю какую-нибудь информацию пользователю или записывать команды для окон в файл. В основном наша программа состоит из этих самых хендлров и команды опроса сервера.

Но так же я сам написал и добавил ещё одно интересную вещь: блок авторизации. Ну как понятно из названия, он сделан для защиты нашей теплицы от несанкционированного доступа. Он работает просто. При первом подключение к боту он запрашивает у нас пароль. Если мы его вводим правильно, бот добавляет нас в базу данных, и при следующих подключениях нам уже авторизироваться не нужно. Бот узнаёт нас при помощи chat-id. Chat-id последнего пользователя храним в переменно, чтобы всё время не дёргать базу.

Теперь нам нужен этот файл.

Так же давайте сразу сделаем ещё несколько вспомогательных скриптов. Создаём файл newuser.sh и пишем в него:

#!/bin/bash
a=`cat /mnt/raw/user`
cat /dev/null > /mnt/raw/user
mysql -u root -pkoshak << EOF
use telegram;
INSERT INTO users(chatid) VALUES('$a');
EOF

И создадим два скрипта для запуска бота и программы окон:

#!/bin/bash
i=0
while [ $i = 0 ]
do
echo New python
sleep 5
python3 bot.py
done

И ещё один:

#!/bin/bash
i=0
while [ $i = 0 ]
do
echo New python
sleep 5
python3 temp.py
done

«Зачем мы это делаем?» спросите вы. А тут дело в том, что иногда из-за нестабильного интернет соединения, или ошибки на сервера Telegram программа может вылететь. А скрипт её гоняет в вечном цикле: вылетела — запустил через 5 секунд снова. А для окон я сделал это на всякий пожарный: вдруг тоже из-за сбоя программа вылетит, а нас в теплице нет, вернёмся и будет у нас томатный суп или помидорное мороженное.

Ну и теперь самое главное, скрипт самого бота.

Не забываем указать здесь id датчика, chat-id и путь к разделу в оперативной памяти. Теперь у нас почти всё готово. Качаем этот дамп, и заливаем базу данных на свой сервер, и не забываем смонтировать раздел в оперативной памяти, думаю 10 МБ хватит по горло. Запускаем два наших скрипта-стартера и радуемся. Пароль по умолчанию: telbot. Меняем его в таблице tkey базы данных.

СМС информирование

Так же сделал СМС информирование на случай перегрева. Качаем файл sms.py.

Регистрируемся на sms.ru и берём там API-key в разделе для программистов. Так же не забываем указать в скрипте ваш номер телефона.

В программе для управления окон объявляем переменную:

Vr=0

Затем вставляем в вечный цикл этот код:

d = datetime.today()

V = d.strftime('%H')

V = int(V)

if (t2>32 and Vr!=V):

print (V)

Vr=V

os.system('/home/samba/sms.py')

В данный момент температура порога 32, смс будут отправляться в случае высокой температуры раз в час, пока она не спадёт.

P.S. В планах на будущее установить управляемый обогреватель и сделать автоматический полив.

Спасибо всем тем, кто дочитал до конца.