Если подключить к Яндекс-станции кучу датчиков, исполнительных устройств и настроить нужные сценарии, то жить в доме становится значительно приятнее, но каждый раз спрашивать Алису какая температура на улице и открыто ли окно — это неудобно. Хочется, чтобы одним взглядом можно было узнать основные показатели датчиков и оценить текущее состояние Умного Дома Яндекс (УДЯ).
Воодушевившись статьей Уважаемого Вадима @tzirulnicov: «Подключение самодельных устройств к умному дому Яндекса с Алисой» я решил попробовать сделать себе мини‑экран, показывающий текущую температуру на улице и в комнате, содержание в комнате углекислого газа, а также состояние окна, обогревателя и сценария, который автоматически открывает окно когда становится душно.
В отличие от оригинальной статьи, все датчики у меня уже есть, так что ничего припаивать я не стал — это просто монитор для моего УДЯ.
Теоретически, кроме покупки SmartTV Ultra от GeekMagic больше ничего не нужно, так как мой скетч можно загрузить через web‑интерфейс прошивки, которая идет «из коробки», а в нем предусмотрено обновление через WiFi (OTA).
Только если загружаемая прошивка не сможет подключиться к Вашему WiFi, то обновлять ее придется «по проводу» — режима AP в моем скетче пока нет, но я планирую его добавить в будущем.
Содержание:
-
Введение
-
Отличия моего скетча от исходного, написанного Вадимом @tzirulnicov
-
Получение токена для чтения данных УДЯ
-
Выяснение ID устройств
-
Установка и настройка Arduino IDE
-
Скачивание и редактирование скетча
-
Загрузка новой прошивки на устройство
-
Используемое у меня оборудование
-
Эпилог: замечания и рассуждения, а также планы
Введение
Сразу скажу, чтоэто мой первый опыт и написания статьи на Хабре и программирования микроконтроллеров, так что двойной дебют.
Надеюсь, что я ничего не нарушил, а если что‑то не так, то прошу отнестись с пониманием. Я правда старался;‑)
Для начала, как я уже написал выше, нужно иметь Умный Дом Яндекс (УДЯ) со всеми датчиками и исполнительными устройствами, состояние которых мы хотим видеть на нашем мини‑экране.
У меня это: Яндекс Станция Мини 3 Про с Климатическим Модулем (с него я беру температуру, влажность и содержание углекислого газа в комнате), уличный датчик температуры, «умный» обогреватель и сервопривод открывания окна.
А еще у меня работают сценарии «Окно — открытие» и «Окно — закрытие» — первый, если в комнате достаточно тепло, открывает окно наполовину при превышении уровня CO2, а второй закрывает его если CO2 понижается до нужного уровня или если в комнате становится слишком холодно.
Кроме этого, есть сценарий «Выключи все», который вызывается при нажатии на кнопку возле входной двери или командой: «Алиса, я ушел» и выключает свет, телевизор и др., включая обогреватель, закрывает окно и отключает сценарий «Окно — открытие», о котором я написал выше.
А еще есть сценарий «Включи все», который тоже вызывается нажатием на кнопку возле входной двери или командой: «Алиса, я пришел». Он включает свет и включает сценарий «Окно — открытие».
Состояние сценария «Окно — открытие» также отображается на мини-экране – если он неактивен, то иконки окна и обогревателя зачеркиваются.
Вот так:
В конце статьи я приведу список используемого оборудования со ссылками – не для рекламы, а чтобы упростить подбор оборудования.
Можно использовать любые датчики, подключенные к Алисе, но потребуется править код скетча.
Например, все данные о состоянии воздуха в комнате у меня получаются одним запросом к одному датчику, но можно использовать обычный датчик температуры и влажности + отдельный датчик CO2. Просто тогда потребуется добавить в прошивку отдельный запрос для его получения.
Исходный код я выложил на отечественный GitFlick
Я не программист, так что за качество этого кода прошу меня сильно не ругать, но конструктивные предложения по его оптимизации приму с благодарностью.
Также, буду очень рад Вашим вопросам и комментариям, но у меня на ноутбуке давно установлен AstraLinux SE и в своей профессиональной деятельности я регулярно участвую в проектах импортозамещения, поэтому выкладывать код на Майкрософтовский github.com (https://habr.com/ru/articles/413215/) я не буду и прошу в комментариях политические вопросы не поднимать.
На приведенных выше фотографиях SmallTV Ultra — «GeekMagic Ultra Smart WiFi Weather Station Bed Clock with Photo Album Gif Animation Desktop Decoration». Когда я ее покупал, то была какая-то распродажа и мне она обошлась в 659 рублей вместе с доставкой. Именно это сумма и указана в заголовке статьи.
Кроме нее, мой скетч работает на GiftTV Crystal Cube — «GeekMagic GIFTV Crystal Holographic Desktop Decoration Smart Weather Station» – там та же самая микросхема ESP-12F и такой же экран, но изображение нужно выводить зеркально, чтобы после отражения в стеклянном кубике оно стало нормальным.
Кроме этого, на Crystal Cube мой скетч не понижает яркость экрана, так как он, в отличии от Ultra, и так выглядит бледным.
В общем, я пожалел, что отдал за нее 1 739 рублей — в реальности она выглядит сильно хуже, чем на фотографии AliExpress: угол обзора совсем никакой — нужно смотреть только прямо, экран маленький, яркость низкая, а цена относительно высокая.
Впрочем, если переделать отображение: сделать большие рамки (не использовать весь дисплей, а рисовать время в центре) и отображать значения датчиков по очереди, то должно получиться вполне прилично.
Отличия моего скетча от исходного, написанного Вадимом @tzirulnicov
Сразу скажу, что код переписан на 90-99%, но все, что касается управления железом, взято у Вадима, а про то, чего у него в прошивке не было, я у него спрашивал и в результате сделал по его советам.
Ключевое отличие в том, что я не вносил и не планировал вносить никаких изменений в железку – я трезво оценил свои возможности по перепайке (последний раз держал паяльник в руках более 30 лет назад, и тогда я вполне успешно ремонтировал ламповые телевизоры «Кварц» и транзисторные магнитофоны «Нота», но это было давно и там были гораздо менее нежные платы), так что я сразу купил Зажим для печатной платы Your Cee Test stand PCB clip, который мне порекомендовал Вадим.
Зато, я добавил обновление по сети (OTA) — если все сделать правильно, подключаться к плате ESP-12F по USB вообще не потребуется, но есть нюансы, о которых я напишу ниже.
Собственно основные отличия:
-
Не требуется ничего припаивать – просто нужно загрузить новую прошивку.
-
Не требуется свой внешний web-сервер, получающий данные со SmallTV и передающий их Яндексу. Т.е. все, что лежит у Вадима в каталоге django_web_service нам не нужно.
-
Написаны более-менее универсальные функции для получения данных с УДЯ. В большинстве случаев, изменение кол-ва датчиков или названий их параметров не потребует изменения кода самих этих функций. Достаточно поменять названия параметров.
-
Добавлена возможность подключения к нескольким WiFi-сетям.
-
Реализована возможность обновления по WiFi (OTA)
-
Для работы нужно указать токен УДЯ, а также ID всех устройств и сценария ими управляющего.
Главный нюанс тут в том, что Яндекс дает токен со сроком жизни 365 дней. Т.е. через год железка работать перестанет и, чтобы восстановить ее работу потребуется получить новый токен, прописать его в скетч и загрузить эту новую прошивку на железку.
Я планирую сделать автоматическое продление токена, но сначала нужно реализовать его получение средствами самой железки, а для этого нужно, чтобы у нее было хранилище данных, которое бы сохранялось после перепрошивки. Тогда и выбор ID устройств можно будет сделать через Web.
В общем, это пока планы — см. последний раздел этой статьи.
-
Более красивая картинка на экране
У Вадима в каждом цикле экран полностью стирается, а потом рисуется заново, а у меня статичные элементы рисуются в setup(), а в loop() стираются и рисуются только области, в которые выводятся динамические данные.
-
Поддержка Crystal Cube
Тут только два момента: выводим изображение зеркально и не уменьшаем яркость экрана.
-
Табличка известных устройств (knownBoards)
Чтобы каждый раз не менять исходный код при подключении другой железки, я сделал таблицу имеющихся у меня железок.
Она помогает в двух вещах:
-
По MAC-адресу определяется тип: Crystal Cube или Ultra – чтобы понять нужно зеркалировать экран или нет.
-
По тому же MAC-адресу устанавливается hostname – его видно в Arduino IDE при обновлении и понятно на какую железку мы запишем новую прошивку.
Получение токена для чтения данных УДЯ
Процесс получения токена описан в документации Яндекс:
Коротко:
-
Заходим на https://oauth.yandex.ru/?dialog=create-client-entry
-
Выбираем второй пункт: «Для доступа к API или отладки»
-
Заполняем поля: придумываем имя, меняем, если нужно, почту, а в поле «Доступ к данным» пишем «iot» и выбираем пункт: «Просмотр списка устройств умного дома».
-
В поле «Redirect URI для веб-сервисов» оставляем значение по умолчанию: «https://oauth.yandex.ru/verification_code»
-
Нажимаем на кнопку «Создать приложение»
-
Выбираем справа пункт «Ваши приложения», открываем только что созданное «приложение» и копируем поле «ClientID».
-
Открываем в браузере https://oauth.yandex.ru/authorize?response_type=token&client_id=<идентификатор_приложения>, заменив «<идентификатор_приложения>» на «ClientID», полученный на предыдущем шаге
-
Видим строчку вроде «y0__XXXXXXXXXXXXXXXXXXXXXXXXX» и сохраняем ее – это и есть токен для чтения данных с Вашего УДЯ, действительный 365 дней.
Выяснение ID устройств
Это можно сделать скопировав строчки либо из программы Умный Дом Яндекс либо со странички: https://yandex.ru/iot:
-
Выбираем нужное устройство и нажимаем на шестеренку в правом верхнем углу.
-
В открывшемся окне «Настройки устройства» выбираем пункт «Об устройстве», а там смотрим пункт «Идентификатор устройства».
-
Его можно скопировать в буфер обмена нажав на иконку в конце строки.
Похожим образом можно узнать ID сценария: нажать на три точки в правом верхнем углу и выбрать «Скопировать ID».
Обращаю Ваше внимание на то, что скопированные строчки содержат префикс, а в программу нужно вставлять только сам ID.
Например: пункт «Скопировать ID» вставит в буфер обмена «scenario_id:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx», а в скетч, в переменную thApiIdCtlSc нужно вставлять только «xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx» без префикса.
Другой вариант получения всех ID: запустить команду «curl -s ‘https://api.iot.yandex.net/v1.0/user/info‘ -H ‘Authorization: Bearer <TOKEN>’ |jq ‘.’», заменив «<TOKEN>» на полученный в предыдущем разделе.
В результате должен получиться JSON-файл со всеми Вашими настройками УДЯ, включая ID всех устройств и сценариев.
Теперь все необходимые данные для получения информации с Ваших датчиков у Вас есть.
Осталось установить Arduino IDE, скачать и открыть в нем мой скетч, поправить его, откомпилировать и загрузить в железку.
Установка и настройка Arduino IDE
Как я уже написал в первой части, я использую AstraLinux SE 1.8.
Если Вы используете MS Windows, то лучше сразу посмотреть раздел «Загрузка скетча в нашу метеостанцию» из статьи Уважаемого Вадима @tzirulnicov «Подключение самодельных устройств к умному дому Яндекса с Алисой».
Если у Вас Linux,
то себя могу сказать, что на AstraLinux SE 1.8 Arduino IDE можно поставить двумя способами:
-
Подключить репозиторий Debian 12 и установить пакет arduino
Тут все просто, но Вы получите версию 1.8.19 – она не такая удобная, как современные версии, но для целей этой статьи прекрасно подходит.
-
Скачать новую версию для Linux x64 с сайта https://www.arduino.cc/en/software.
Хороший вариант, но доступ к этому сайту с IP-адресов, расположенных в РФ закрыт, а еще, сразу после установки, у Вас не будет иконки в меню «Пуск» и запускать Arduino IDE потребуется руками, после перехода в нужный каталог.
А еще у меня в меню был очень большой шрифт, что делало использование очень неудобным. Поэтому я запускаю новую Arduino IDE с ключем «‑force‑device‑scale‑factor=0.94»
Далее действуем по инструкции Вадима @tzirulnicov
Запускаем Ардуино, открываем через Файл-Параметры окно параметров, в поле «Дополнительные ссылки для Менеджера плат» указываем «http://arduino.esp8266.com/stable/package_esp8266com_index.json,https://dl.espressif.com/dl/package_esp32_index.json«.
Далее выбираем в Инструменты-Плата:
esp8266 -> Generic ESP8266 Module (в случае метеостанции с esp-12f)
esp32 -> ESP32 Dev Module (в случае метеостанции с esp32)
Далее выбираем Инструменты-Порт-порт, в которому подключена метеостанция
Устанавливаем необходимые библиотеки через Инструменты-Управление библиотеками: …
Но ставим только библиотеки: NTPClient, Adafruit_ST7789, ArduinoJson, Adafruit GFX Library, Time, ArduinoHTTPClient и ArduinoBearSSL, а OpenWeather и Sensirion I2C SCD30 нам не потребуются.
Скачивание и редактирование скетча
После этого скачиваем мой скетч: «git clone https://gitflic.ru/project/stacez/yamon.git»
Открываем yamon_esp12f.ino в Arduino IDE и редактируем его.
У меня основные параметры задаются в файле Secret.h, но, по вполне понятным причинам, выкладывать его в Git я не стал.
Вы можете либо сделать свой Secret.h, приписав в него нужные параметры, либо закомментировать строчку «#include «Secret.h»» и прописать эти параметры ниже, следуя примерам и моим комментариям.
Сначала я повторил здесь этот код, но получилось очень длинно и я решил заменить его картинкой:
Самое главное: указать имя и пароль WiFi сети.
Так как я ношу железку с собой и правлю этот код в разных местах, то вместо двух строк у меня два массива, чтобы можно было указать несколько WiFi-сетей.
Важно: Кол-во паролей должно совпадать с кол-вом сетей иначе (скорее всего, но я не проверял), прошивка будет падать и перезагружаться в момент подключения к сети.
Для интеграции с УДЯ, нужно прописать токен и ID, полученные выше: Строчки в переменных th*Url менять не нужно, в thApiToken нужно заменить «XXX» на токен (оставив в начале «Bearer »), а в остальные переменные прописать ID опрашиваемых устройств (без префикса и двоеточия).
Отдельно напишу что делать, если у Вас другие датчики или вам нужны другие параметры:
В функции displayYandexTH() нужно исправить вызов функций getYandexState() и getYandexInfo(), а если нужно опрашивать больше датчиков, то добавить такие же блоки кода.
Вроде бы, в комментариях все подробно описано.
Только скажу почему так сложно: при возврате указателей на String у меня появились какие-то утечки памяти, которые я сходу убрать не смог, так что через некоторое время железка падала из-за нехватки свободной памяти.
Данный способ утечек не дает и все работает вполне стабильно. Хоть и приходится сначала конвертировать String в char*, а потом обратно, что явно «не по фэншую».
Поясню работу этой функции на примере уличного датчика:
Выводим на экран в строку состояния сообщение о том, что конкретно мы сейчас будем делать
setStatusText("Яндекс: Улица...");
Запрашиваем с устройства thApiIdOut значения параметров temperature и humidity из секции properties
int r = getYandexState("Out", "properties", thApiIdOut, "temperature", c_temp_out, "humidity", c_hum_out, NULL, NULL);
Проверяем успешность. Если неудача, то просто ничего не делаем: ошибка уже написана на экране красным цветом, а подробности выведены на Serial.
if (r < 0) {
return;
}
Проверяем, что мы получили какое-то значение температуры и конвертируем его в числовой тип.
if (strlen(c_temp_out) > 0) {
String t = c_temp_out;
f_temp_out = t.toFloat();
} else {
setErrorText("Yandex Out Error: NULL temp state returned");
return;
}
Повторяем те же действия со значением влажности
Еще поясню код, рисующий эти цифры на экране. Опять картинкой:
Функция getYandexInfo() имеет похожий синтаксис, так что ее подробно описывать не буду.
Укажу только несколько нюансов:
-
Я не смог найти способа запросить состояние конкретного сценария, как это делается с устройствами, и пришлось получать это информацию из общего описания УДЯ.
-
У железки всего 64кБ ОЗУ, а описание моего УДЯ занимает >370кБ, так что пришлось делать фильтр нужных мне значений и парсить JSON прямо из потока HTTPS.
-
Работает это долго – у меня секунд 15, так что пришлось отказаться от отображения на экране времени с секундами.
-
Зато, вроде бы, получилось сделать более-менее универсальную функцию для получения данных из описания УДЯ, но сейчас она протестирована только со сценариями.
После редактирования скетча можно переходить к его тестированию на реальной железке.
Загрузка новой прошивки на устройство
Есть два варианта:
1) Подключение по USB
Подробно это описано в уже многократно упоминавшейся мою выше статье Вадима @tzirulnicov: “Подключение самодельных устройств к умному дому Яндекса с Алисой” .
2) Загрузка прошивки по WiFi
Это позволяет обойтись без покупки «Зажима» и платы «CG Programmer», но Вы не увидите отладочных сообщений и в случае ошибки Ваша железка превратится в «кирпич». Впрочем, ее можно будет «оживить», если подключить по USB.
Сначала про второй вариант:
Самое главное: указать правильное имя и пароль WiFi-сети и правильно выбрать формат разбивки Flash-памяти.
Формат разбивки Flash-памяти должен быть достаточным местом под OTA («Инструменты» -> «Flash size» – у меня выбрано «4MB(FS:1MB OTA:~1019KB)»). После этого, можно получить файл прошивки: «Скетч» -> «Экспортировать скомпилированный бинарный файл» — рядом со каталогом скетча должен появиться файл «yamon_esp12f.ino.bin».
Потом можно зайти в web-интерфейс оригинальной прошивки от GeekMagic, выбрать обновление прошивки и загрузить этот файл.
Если все все сделано правильно и ПК, на котором запущена Arduino IDE, подключен к той же сети, то на экране железки появится картинка, а через пару минут в списке «Инструменты» -> «порт» вы увидите свою SmallTV.
Если не увидели, то где-то была ошибка. Скорее всего, ее можно будет исправить только подключившись к железке через USB (п.1).
А если увидели, то ее можно выбрать и дальнейшие изменения прошивки будут загружаться на железку по WiFi также, как и по USB: просто при выборе «Скетч» -> «Загрузить на плату» или после нажатия на «стрелочку вправо» под меню.
Только если Вы не угадали форматом разбивки Flash-памяти или если Вам досталась железка с другим размером Flash (а я не знаю как его посмотреть без подключения по USB), то Вы получите сообщение об ошибке обновления через ОТА – и тут тоже без подключения по USB не обойтись.
Важный нюанс, на который я потратил кучу времени: Arduino 2.x, в отличии от 1.x, при обновлении по OTA запрашивает пароль, хотя в моем скетче пароль не установлен. Оказалось, что можно ввести в качестве пароля любую строчку и обновление запустится.
Правильно, конечно, прописать пароль в скетче и тогда при следующем обновлении нужно будет указывать именно его.
А теперь про первый вариант:
Если у Вас есть и «Зажим» и плата «CG Programmer», то достаточно соединить их между собой по схеме из статьи Вадима:
У меня это выглядит вот так:
А если указать строчку «#define GUI_ROTATE_DEBUG true», то вот так:
Изображение повернулось на 90 градусов и теперь гораздо удобнее на него смотреть.
С Crystal Cube все еще хитрее – вот так выглядит экран без стеклянного кубика в нормальном режиме и с включенным GUI_ROTATE_DEBUG – экран не только переворачивается, но и перестает рисоваться зеркально.:
Используемое у меня оборудование
Тут я собрал ссылки на железки, которые используются у меня – т.е. мой скетч писался именно под них и с ними проблем точно возникнуть не должно. Это не значит, что нельзя использовать другое – просто я тестировал скетч именно на этом. По возможности, я привожу ссылки на их описания и даже Internet-магазины. Повторюсь: это не реклама – они мне ничего не платят. Напротив, это я им заплатил когда покупал эти железки.
Тут три отдельных раздела:
1) Железки УДЯ, с которых берется информация у меня
-
POK005L Уличный ZigBee датчик температуры и влажности с увеличенной батарей
-
Tuya Smart CO2 Sensor DCR-LCD – это отдельный Zigbee датчик CO2, который тоже у меня есть и работает с Алисой, что само по себе большая редкость.
Если у Вас нет «Климатического модуля», который работает только с Мини 3 Про, то, теоретически, можно использовать его. В качестве датчика температуры и влажности тогда подойдет почти любой с AliExpress, кроме Xiaomi – я их купил десяток, в расчете на то, что штуки три будут работать с Алисой, а заработали без вопросов все, кроме датчика Xiaomi, которому обязательно нужен хаб от Xiaomi.
2) Устройства GeekMagic
3) Приспособления для удобной их перепрошивки.
-
Зажим для печатной платы Your Cee Test stand PCB clip
Это чтобы подключиться к плате без паяльника – рекомендовал Вадим @tzirulnicov, за что ему огромное Спасибо!
Можно использовать любой адаптер CH340G, который может выдать на железку 3.3В, но потребуется вручную в правильном порядке подключать контакты GPIO0 и RST к земле.
Подробности написаны в статье Вадима, на которую я уже много раз ссылался.
У меня адаптер CH340G был, так что я сначала пошел именно по этому пути, но на третий день сдался – решил, что проще купить эту платку и не париться.
Эпилог: замечания и рассуждения, а также планы
В целом, лично меня результат устраивает, но я это делал больше для того, чтобы изучить программирование IoT и возможности общения с УДЯ, а не только ради получения мини-экрана УДЯ.
Поэтому мои планы на будущее (roadmap) достаточно сумбурны. Не воспринимайте их как обещание.
Это чем я хочу заняться, когда в следующий раз появится много времени:
-
Сделать хранение параметров отдельно от кода (LittleFs?)
-
Сделать режим AP для первоначальной настройки – аналогично тому, как это работает на оригинальной прошивке GeekMagic.
-
Сделать на железке Web-сервер, который позволит менять настройки (для начала, только яркость) и загружать прошивку из браузера.
-
Сделать получения токена УДЯ средствами скетча:
Либо показывать QR-код на экране, который можно сфотографировать с телефона, либо сделать авторизацию через web-сервер.
-
Сделать автоматическое получение нового токена, чтобы не требовалось переавторизовываться каждый год.
-
Сделать выбор датчиков из списка имеющихся в Вашем УДЯ.
Если реализовать все вышеперечисленное, то железку можно будет использовать обычным пользователям – в прошивке не будет ничего индивидуального, так что ей будет пользоваться не сложнее, чем оригинальной от GeekMagic.
Если кто-то даст мне в комментариях ссылку на готовый код, в котором можно подсмотреть как реализовать перечисленные функции (кроме LittleFs, описанной в примерах Arduino IDE), то буду очень благодарен.
Наверное, кто-то что-то подобное для УДЯ уже делал и, возможно, выложил исходный код, но сходу я его нашел.
Другое:
-
Сделать отдельную «Тему» для Crystal Cube: показывать время ближе к центру, увеличив размер шрифта, а данные с датчиков по очереди. По несколько секунд каждый.
Этим будет не так удобно пользоваться, но раз уж у меня эта железка есть и она красивая, то почему не сделать. Новый экран на AliExpress я уже купил. Едет. Надеюсь, что подойдет.
-
Попробовать этот скетч на SmallTV Pro
У нее более мощный SoC (ESP32-WROOM-32), а еще есть сенсорная кнопка, которой можно переключать режим отображения.
Например, можно сделать, чтобы сразу показывалось то же, что сейчас, но после нажатия кнопки показывались другие датчики или прогноз погоды.
А еще к ней много что можно припаять;‑)
-
Портировать его на какую‑нибудь железку с экраном 4–10«, которую можно прикрутить или приклеить к стене.»
Чтобы сделать не мини, а полноформатный экран для УДЯ.
Почти у всех такая железка есть, а у Яндекс нет. Или я не нашел.
Прошу предлагать в комментариях Ваши идеи.
Возможно, они меня заинтересуют и я их добавлю в этот список. Может быть, даже первыми 😉
ссылка на оригинал статьи https://habr.com/ru/articles/1025884/