В связке метеостанции и telegram нет ничего нового, всё таки этот способ легко покрывает нужды переброски данных в сеть для быстрого к ним доступа. Моё же творение было вдохновлено идеей быстрого создания устройства, привязанного к Яндекс колонке, но под конец вылилась в минималистичные настольные часы-метеостанцию и относительно универсальный способ подключения к Алисе DIY IOT устройств без баз данных, только на контроллере и telegram API.
Перед началом необходимо упомянуть, что этот способ не подходит для устройств, релевантные данные с которых нужно получать с задержкой 0.5 секунды или меньше, для этого более подходящим решением будет использование Blynk или хостингом на внешнем сервере (например так), в общем данную статью стоит рассматривать как экспериментальный опыт разработки навыков Алисы для электронных самоделок.
Кейс
Имеется: Яндекс.Станция Мини, ESP8266, датчик PM2.5 и PM10 sds011, датчик CO2 MH-Z19B (или MH-Z14A, тестировалось с обеими моделями) и модуль BME280.
Желаемый результат: метеостанция, данные которой можно получить через telegram и запросить их через Алису.
Архитектура решения
Всю архитектуру решения можно разделить на 2 раздела: решение на железе и навык Алисы.
Создание устройства
В качестве подопытного мной был разработан мини-проект EcoWatch - настольные часы-метеостанция. Управление и вывод данных производятся при помощи одной сенсорной кнопки и сегментного дисплея на чипе TM1637.
Корпус был спроектирован в Autodesk Inventor и состоит из 3 частей: основа (нижняя часть + стенки), перегородка и крышка. Датчик PM2.5 и PM10 занимает дно корпуса, к нему же ставится BME280 (для уменьшения влияния нагрева от ESP), далее вставляется перегородка, на которой закрепляются уже ESP и датчик CO2.
Кнопка находится в углублении на внутренней стороне стенки, а дисплей прямо над ней.
Файлы для печати можно найти тут.
Для удобства подключения ESP была взята уже на готовом модуле NodeMCU, питание организовано от контакта VIN на контроллере (5V с USB, прошедшее через диод шоттки), но это было сделано ввиду невысокого уровня потребления модулей, правильнее будет подключать к пину VU.
Таблица подключений:
MH-Z19B PWM |
D3 |
PM2.5 PWM |
D0 |
PM10 PWM |
D8 |
Sensor button |
D7 |
BME SDA |
D2 |
BME SCL |
D1 |
Display CLK |
D5 |
Display DIO |
D6 |
Если использовать другие датчики, то нужно смотреть, что ESP сможет запуститься с ними - некоторые пины требуют определённого уровня сигнала на старте.
Код был написан в VS Code, используя фреймворк Platformio: ссылка на GitHub.
Для заполнения пропусков под себя потребуется сначала создать бота https://tlgrm.ru/docs/bots#botfather
Теперь необходимо создать группу, в которую будет входить наш бот и любой из ботов, позволяющий узнать chat_id группы. Лично мой выбор пал на @myidbot, которому нужно адресовать команду /getgroupid@myidbot, но перед выполнением команды необходимо назначить нашего созданного бота администратором группы.
Для того, чтобы не видеть периодические уведомления от группы можно переместить его в архив, предварительно выключив уведомления и скрыть сам архив из списка чатов.
Через бота @username_to_id_bot узнаём id всех людей, кому будет предоставлен доступ к боту и не забываем узнать свой собственный id.
Все необходимые данные собраны, надо подставлять их в код:
#define WIFI_SSID "name"
#define WIFI_PASS "pass"
#define BOT_TOKEN "token" // токен нашего бота
Код рассчитан на 3х пользователей, но их количество не ограничено, главное не забыть добавить соответствующие ячейки массива к обработчику сообщений
String white_id_list[3] = {" ", // enter your ids
" ",
" "};
String admin_id = " "; // id, на который будут бот шлёт предупреждения
В качестве последнего аргумента функции bot.setChatTitle()
вставляем id группы, в которую мы включили бота
bot.setChatTitle(String(bot_temp) + " " + String(bot_humid) + " " + String(bot_pres) + " " + String(bot_co2) + " " + String(bot_pm25) + " " + String(bot_pm10), "chat id");d");
Итого: имеем функционирующую метеостанцию-часы и бота, через которого можно узнать данные с неё.
Настройка сервисов Яндекса
Для более глубокого понимания процесса можно изучить доки и статьи, посвящённые данному процессу в общих чертах. Ну а если не вдаваться в подробности, то настройка производится в 3 шага: создание скрипта в облаке, создание своего навыка для Алисы и прописывание сценариев для своих устройств (в данном случае умной колонки).
Шаг 1:
Заходим на платформу https://console.cloud.yandex.ru и регистрируемся там (вносим платёжные данные (хост функций, которые будут использоваться для навыков Алисы, бесплатен)), заходим во вкладку cloud functions
Жмём Создать функцию, задаём ей имя и выбираем опции как на скриншоте
В корне функции создаём дополнительный файл requirements.txt, в который записываем: pytelegrambotapi == 4.6.0
А код в py файле меняем на такой:
index.py
import telebot
token = 'your token'
bot = telebot.TeleBot(token)
def handler(event, context):
if 'request' in event and \
'original_utterance' in event['request'] \
and len(event['request']['original_utterance']) > 0:
ui = event['request']['original_utterance']
text = bot.get_chat(xxxxxxxxxxx).title # your chat id
text = str.replace(text, '.', ',', 3)
if(ui == '0'):
text = text.split()[0]
text +=' градусов'
elif (ui == '1'):
text = text.split()[1]
text +=' процентов'
elif (ui == '2'):
text = text.split()[2]
text +=' килопаскалей'
elif (ui == '3'):
text = text.split()[3]
text +=' ppm'
elif (ui == '4'):
text = text.split()[4] +' и '+ text.split()[5]
else:
text = str.replace(text, '.', ',', 3)
text = str.replace(text, '', '*Температура*', 1)
text = str.replace(text, ' ', '*градусов*Влажность*', 1)
text = str.replace(text, ' ', '*процентов*Давление*', 1)
text = str.replace(text, ' ', '*килопаскалей*Це*о*два*', 1)
text = str.replace(text, ' ', '*ppm*Количество*частиц*', 1)
text = str.replace(text, ' ', '*и*', 1)
text = str.replace(text, '*', ' ', 19)
return {
'version': event['version'],
'session': event['session'],
'response': {
'text': text,
#finish the session after this response.
'end_session': 'true'
},
}
Не забывая записать токен бота и вставить id группы(где сидит бот) в функцию bot.get_chat(xxxxxxxxxxx).title
Для проверки, что всё работает можно перейти во вкладку навыка Тестирование:
После запуска теста в разделе результата можно будет увидеть что-то подобное:
В случае возникновения ошибок
2 основных сценария возникновения ошибок:
Бот на устройстве не был запущен правильно. Значит и название чата не пришло в вид, что программа ожидает на вход. Решается, соответственно проверкой, что само устройство работает и название чата меняется соответственно с показаниями датчиков
Код метеостанции (ответственный за отправку данных)/состав датчиков был изменён. В таком случае нужно убедиться, что строка, которая собирается на esp в аргументе функции
bot.setChatTitle()
не будет вызывать ошибок при разбивании её на части функцией в облаке. Крайне рекомендую в данном случае тестировать код функции без обработки строки, то есть оставить толькоtext = bot.get_chat(xxxxxxxxxxx).title
, а остальные действия закомментировать/удалить.
В случае, если это проблемы не решило, то следует отталкиваться от того факта, что написанный код обработки и отправки данных на обеих сторонах не является гибким и нуждается в перепроверке перед запуском.
Шаг 2:
Перейдите на платформу Яндекс.Диалоги и создайте новый диалог
Тип диалога - Навык в Алисе:
Заполняем все обязательные поля навыка, выбирая тип доступа Приватный в целях безопасности:
В разделе Backend выбираем пункт Функция в Яндекс.Облаке и в списке находим нашу функцию:
Жмём снизу большую кнопку Сохранить и затем публикуем навык. Публикация занимает некоторое время. Когда статус меняется на "Диалог опубликован" - можно дополнительно протестировать работу навыка (вкладка Тестирование):
Шаг 3:
Осталось только разработать сценарии для Алисы - здесь уже можно кастомизировать по полной, так что дальнейшее описание можно расценивать как базовый пример функционала.
Заходим на сервис Устройства через мобильный браузер Яндекса и создаём навык (для начала - общий запрос, где мы получаем все данные за раз):
Структура запроса состоит из 2 частей: вызов навыка и команда навыку:
Скажи "название навыка" "команда"
В случае, использования кода без изменения, команд всего 6:
"0" - температура;
"1" - влажность;
"2" - давление;
"3" - данные с датчика CO2;
"4" - Данные с датчика частиц;
Любой другой запрос - все данные.
Например, запрос для получения влажности будет выглядеть как: Скажи Eco get 1.
Итого: получаем апгрейд функционала умной колонки, опыт интеграции устройств в экосистему умного дома Яндекса и метеостанцию-часы, которые неплохо вписались бы в фильмы серии Звёздных войн.
Демонстрация работы:
Бот в telegram и прямое обращение к навыку через Алису:
Демонстрация работы устройства в сборке:
Заключение
Данный проект был моим первым опытом как в создании tg ботов, использования платформы Yandex.Cloud, так и в принципе работы с ESP8266, выполняющим функцию контроллера, так что я полностью открыт к предложениям относительно проекта и конструктивной критике решения.
После завершения ещё нескольких проектов с большой вероятностью возьмусь за полноценное решение для умного дома в качестве пет проекта, а также добавлю сюда автоматическое выполнение большинства действий по первоначальной настройке telegram и сервисов Яндекса, так что скорее всего данная тема в будущем продолжится в моих статьях и будет содержать изобретение новых моделей велосипедов, которые едут только за счёт костылей, так что не переключайтесь.
Полезные ссылки
Умный дом на основе API Telegram
Комментарии (2)
IvanG
08.07.2022 02:08Можно попробовать без тг, неправославный гугл док даёт возможность выполнять скрипты (в том числе с публичным эндпоинтами, тригерящимися на хттп реквесты) и писать/читать в документы.
Но использование тг как канала передачи данных интересно, возьму на заметку
Lector-ED
Очень интересно, до сего дня не был даже в курсе что можно писать свой софт под Алису.