Кому-то нравится украшать дом фоторамками, а кому-то — цифровым прогнозом погоды. Если вы из числа последних, то читайте, как собрать своё собственное метеотабло.
Что мы хотим узнать, выходя из квартиры? Правильно, стоит ли взять куртку потеплее? Намотать шарф, или и так сойдёт? Захватить ли зонт? Каждый раз лезть в телефон (который ещё найти надо!) не очень удобно. Уличный термометр тоже есть не у всех, да и привирает он часто.
Я решил сделать метеорологический дисплей с электронными чернилами и питанием от батареи. После изучения вопроса я определил для себя несколько целей:
Наглядный прогноз погоды, который можно расположить на видном месте. Избавляет от необходимости искать телефон.
Выглядит как коммерческое изделие, а не детская поделка. Должен вписываться в интерьер.
Работает на батарейке. Не хотелось бы, чтобы из прибора торчал кабель, а замуровать его в стену не получится.
Текст должен быть хорошо виден, но при этом табло не должно светиться ночью. Так я пришёл к использованию электронных чернил.
Должен подходить, в первую очередь, для меня, но иметь возможность настройки под других. Например, опцию смены пользовательского местоположения и часового пояса. Конечный результат в итоге привязан к Финляндии из-за использования API Финского метеорологического института, но я предусмотрел и другие варианты.
Поставленные цели сопряжены с проблемами:
Время автономной работы ограничено. К счастью, дисплеи с электронными чернилами обладают интересным свойством: изображение остаётся видимым, даже если все кабели отключены. Для сохранения изображения не требуется никакого питания.
Низкая скорость обновления данных из-за ограничения времени работы. Мой план состоял в том, чтобы экран обновлялся один-два раза в день. Это ставит передо мной интересные дизайнерские задачи. Как показать, что данные отображаются не в реальном времени? Что следует показывать в качестве дневной температуры: среднюю или максимальную за день?
Физические ограничения рамки. В идеале прибор должен располагаться вровень со стеной.
План
Устройство должно “проснуться” рано утром, получить актуальную информацию о прогнозе погоды, обновить информацию на дисплее и вернуться в глубокий сон до следующего дня.
Таким образом, у нас будет свежий прогноз погоды на день при минимальном расходе заряда батареи.
Теперь перейдём к исполнению.
Исполнение
Сначала я разработал интерфейс в Figma. Это заняло около 2-х дней (а точнее 2 вечера после работы).
Это был дизайн для 7,5-дюймового дисплея Waveshare с электронными чернилами. После того, как я заказал дисплей, я начал искать шрифты, которые будут хорошо отображаться на 1-битном (черно-белом) экране. На удивление трудно оказалось найти настоящие 1-битные экранные шрифты, поэтому я протестировал несколько вариантов с обычными веб-шрифтами с постобработкой и без неё:
Меня они не слишком устроили... Устройство будет находиться в самом сердце квартиры, поэтому экран должен выглядеть красиво.
Немного подумав, я дополнительно заказал 10,3-дюймовый 16-битный дисплей, который позволяет сглаживать текст. Контуры букв стали намного более плавными. Можно было жить и с 1-битным дисплеем, но я решил использовать его для чего-нибудь другого в будущем.
В тот же день я также заказал кучу другого оборудования: SD-карту, чип и аккумулятор PiJuice, стопорные винты, кабели GPIO и адаптеры. К счастью, у моего друга был запасной Raspberry PI Zero, которым он со мной поделился.
После того, как дизайн в Figma был готов, я начал создавать HTML-страницу, которая будет использоваться для визуализации пользовательского интерфейса. Многие существующие проекты используют библиотеки более низкого уровня вроде Python Imaging Library, но я выбрал HTML и CSS. Разработка идёт быстрее, когда можно редактировать HTML и сразу видеть результат без рендеринга растрового изображения после каждой итерации.
Разработка UI заняла примерно 1-2 недели, с учётом того, что я работал только по вечерам и выходным.
Детали по настройке вы найдёте в репозитории GitHub (перевод в конце статьи).
Когда я закончил разработку, как раз прибыло оборудование. Наконец-то я смог увидеть, как выглядит интерфейс не на моем экране с разрешением 1872x1404, а в бою. Установка и настройка Raspberry PI заняла довольно много времени, но это стоило того. Удивительно было видеть, как интерфейс впервые появляется на e-ink дисплее.
До этого момента всё шло на удивление гладко. Но потом я собрал все части воедино и понял, что рамка безбожно мала.
Мне очень не хотелось делать толстый корпус, поэтому пришлось вернуться к чертежам. Я пытался уместить всё в рамке, тестируя всевозможные комбинации. Этот чудовищный кабель GPIO + переходник 1/2 почти справились со своей задачей:
Но даже после того, как я срезал все лишние пластиковые куски с кабелей, установить раму заподлицо со стеной не удалось.
Затем я понял, что на демонстрационной странице Waveshare есть приложение для Windows, которое подключается к контроллеру через интерфейс micro-USB. Можно ли использовать его для управления дисплеем? Не было никаких примеров того, как это сделать в Linux.
К счастью, некоторые великие умы уже задумались об этом. Я подключил контроллер с помощью USB-кабеля, скомпилировал код C на Raspberry PI и в качестве теста попытался очистить дисплей. Сработало! Какое облегчение. Кабели USB намного меньше, чем 40-контактные кабели и разъёмы GPIO.
Теперь, когда я был уверен в USB-стратегии, мне нужно было избавиться от разъёма GPIO контроллера IT851, потому что он всё ещё не влезал в рамку. К счастью, в Хельсинки есть замечательная библиотека Oodi (хакерское пространство, которое представляет собой смесь библиотеки, игрового кафе и места для встреч), куда я мог пойти и бесплатно отпаять разъём.
Уму непостижимо, насколько крут Oodi не только в плане архитектуры, но и с точки зрения функциональности.
К сожалению, паяю я не блестяще. Жене сказал, что работа займёт около 20 минут, но даже спустя 1,5 часа работы (и активного гугления) я не смог удалить разъем с чипа. Моё время в паяльной лаборатории истекло.
Следующей стратегией было применение грубой силы. Я взял бокорезы и просто отрезал половину жатки. Единственное, на что я мог надеяться, это на то, что после моего акта вандализма чип заработает. С разъёмом GPIO, разрезанным пополам, все детали, наконец, прекрасно влезли в рамку от IKEA!
Непонятные проблемы в программном обеспечении были решены, и можно было начинать окончательную сборку. Я прикрепил все к рамке ИКЕА с помощью винтов и термоклея. Дисплей очень тонкий, а задняя крышка слегка прогибается, поэтому я разместил винты так, чтобы они не повредили дисплей при переноске устройства.
Та-дам! Все составные части почти идеально вписались в рамку ИКЕА толщиной 2,9 см.
Я очень беспокоился, что повредил компоненты в процессе целого часа непрофессиональной распайки, но, к счастью, всё работало.
Наконец, я протестировал всё на ошибки.
Готово, пришло время крепить раму к стене.
Мне очень нравится итоговый результат. Рамка ИКЕА имеет белую картонную вставку, которую я обрезал по размеру экрана. Чтобы не было несоответствия пропорций вставки и самой рамки, я пожертвовал несколькими вертикальными пикселями e-ink дисплея. Отверстие вставки по вертикали короче, чем у дисплея с электронными чернилами, поэтому некоторые Y-пиксели остаются неиспользованными. Немного стыдно, но общий вид важнее всего!
Один из вариантов, который я рассматривал — распилить рамку таким образом, чтобы она идеально подходила под экран. Но получится фигня, к тому же дополнительное пространство внутри позволило мне уместить там все компоненты.
Проект занял 3 недели. Даже удивительно, что так быстро. Я намеренно выбрал знакомое оборудование и программное обеспечение, чтобы упростить разработку. Идея состояла в том, чтобы действительно закончить проект, хотя и покопаться в нём было полезно и интересно.
Вот и все, было весело!
Список оборудования для справки
Raspberry PI Zero W
Аккумулятор PiJuice 12000 мАч . Как можно большей ёмкости, чтобы не приходилось часто заряжать устройство.
10,3-дюймовый дисплей Waveshare с электронными чернилами и разрешением 1872x1404 с Raspberry PI HAT . Поддерживает 16 оттенков черного и белого.
Инструмент для установки Geekworm Raspberry Pi, 132 шт. Для набора прокладок и винтов, которые прекрасно подходят для проектов Raspberry PI.
Переходник с micro-USB на USB
Кабель micro-USB на USB
Рамка IKEA Hovsta Frame
Разные строительные штуки: термоклей, резинка для волос, чтобы держать аккумулятор, настенные монтажные крючки, небольшая пластиковая коробка, разрезанная на части, чтобы поддерживать аккумулятор снизу, и, конечно же, клейкая лента.
Из репозитория GIT
Проект состоит из двух составляющих: render и rasp.
render
На этом этапе создаётся HTML, который в конечном итоге будет отображаться как PNG. Изображение содержит прогноз погоды. Render предоставляется через Google Cloud Function. Это идеальный инструмент для такого рода задач. Эндпоинт вызывается редко, а задержки не имеют большого значения.
Данные о погоде извлекаются из API-интерфейсов Финского метеорологического института (ФМИ) и Open Meteo. API ФМИ имел некоторые ограничения, поэтому я дополнил данные информацией с Open Meteo.
HTML, CSS и Headless Chrome используются для создания файла PNG. Эту часть можно было бы реализовать с помощью низкоуровневого подхода, но использовать для разметки CSS очень удобно.
Отображается вcё одним примитивным HTML-файлом, который содержит фиктивные данные для упрощения разработки. Фиктивные данные будут заменены реальными с использованием идентификаторов DOM. Отсутствие инструмента сборки устраняет множество ненужных сложностей.
Все даты в системе указаны в формате UTC, при рендеринге они конвертируются в местное время.
rasp
Работает на Raspberry Pi Zero.
Сюда входит весь код, относящийся к оборудованию, которое будет отображать погоду. Эта часть ничего не знает о погоде, она просто загружает PNG с заданного URL-адреса и отображает его на дисплее e-Ink.
Извлекается PNG из заданного URL-адреса, он отображается на дисплее e-Ink и происходит возврат в режим ожидания.
Должно потребляться как можно меньше энергии
Могло бы хватить микроконтроллера, но мне хотелось бы закончить проект до конца своей жизни
Код IT8951-ePaper скопирован с https://github.com/waveshare/IT8951-ePaper/
Монтаж
Примечание: это примерное руководство, написанное по памяти.
Большая часть программного обеспечения находится в облаке Google. Это снимает большую часть нагрузки с устройства Raspberry Pi, что позволяет увеличить время автономной работы. Развёртывание выполняется с помощью GitHub Actions, но первоначальная настройка была примерно такой:
Создать новый проект GCP
Создайте учётную запись службы развёртывания с ролью развёртывания Cloud Function. Установите ключ JSON как GCP_SERVICE_ACCOUNT_KEY secret.
Создайте ещё одну учётную запись службы для устройства Raspberry PI. Добавьте права записи для Cloud Logging. Таким образом, журналы могут быть отправлены в GCP для отладки, потому что в режиме сна Raspberry PI не использует батарею питания.
Создайте облачную функцию Google с исходным кодом hello world. К переменным окружения добавьте NODE_ENV=production и API_KEY=<new random key>. Ключ API предназначен только для предотвращения случайных вызовов http, потребляющих квоты GCP. Рендеринг Headless Chrome, кажется, хорошо работает с 1 ГБ памяти.
Настройка Raspberry PI
Загрузите правильный образ отсюда: https://www.raspberrypi.com/software/operating-systems/b
Залейте его на SD-карту с помощью balenaEtcher https://www.balena.io/etcher/ (или другой программы для записи образов)
Загрузите Raspberry и выполните первоначальную настройку
-
sudo raspi-config
Настройка SSID и пароля Wi-Fi (параметры системы)
Обновление языка системы, часовых поясов и т. д. (параметры локализации)
Включение SSH-сервера (параметры интерфейса)
Включение overlayfs (параметры производительности), чтобы сделать FS доступной только для чтения.
В вашем маршрутизаторе обязательно назначьте статический локальный IP-адрес для устройства.
Установите код обновления дисплея
Скачайте архив
curl -H "Authorization: token <token>" -L https://api.github.com/repos/kimmobrunfeldt/eink-weather-display/zipball/main > main.zip
или sudo apt install git и
git clone https://<user>:<personal_access_token>@github.com/kimmobrunfeldt/eink-weather-display.git
Вы можете создать ограниченный токен личного доступа Github, который может клонировать это repo. Git мне показался самым простым, можно просто сделать git pull для внесения любых изменений.
sudo apt install python3-pip
Мне не удалось заставить pipenv работать благодаря тому, что pijuice является общесистемным пакетом.
cd eink-weather-display && pip install Pillow==9.3.0 google-cloud-logging requests python-dotenv
Установка пакетов Python
Настройте переменные env: cp .env.example .env и заполните детали
Следуйте инструкциям по установке с https://www.waveshare.com/wiki/10.3inch_e-Paper_HAT, чтобы заставить дисплей E-Ink работать.
После установки проверьте, работает ли демонстрационное программное обеспечение (на языке C).
sudo apt install pijuice-base
-
Включите интерфейс I2C
Дополнительная информация об отладке: Чтобы разрешить PIJuice включаться без питания от батареи, перейдите в общие настройки и включите «Turn on without battery» или аналогичную опцию.
Убедитесь, что вы используете правильный профиль батареи PIJuice (у меня PJLIPO_12000)
Если используете pijuice_cli, не забудьте применить изменения! Кнопка запрятана внизу.Проверьте, работает ли PIJuice и от батареи.
cd rasp/IT8951 и следуйте инструкциям по установке
-
Настройте Pijuice с использованием pijuice_cli. Не забудьте сохранить изменения внутри каждого экрана настройки!
Системные события
Будильник: каждый день в 04:00 UTC (6:00 по хельсинкскому времени зимой, 7:00 летом)
После этого вы можете протестировать дисплей PiJuice + E-Ink.
-
Настройте crontab. Запустите обновление при загрузке и выключите устройство, если оно работает от батареи.
@reboot cd /home/pi/eink-weather-display/rasp && python main.py
# Every minute
* * * * * cd /home/pi/eink-weather-display/rasp && python shutdown_if_on_battery.py
Примечание: Всё, что было сделано выше, я делал с использованием пинов Raspberry PI GPIO. Однако они оказались слишком высокими для рамы. Вместо того, чтобы перепаивать пины GPIO, я решил использовать контроллер IT8951 через USB-интерфейс.
-
Установите https://git.sr.ht/~martijnbraam/it8951 в каталог /home/pi/usb-it8591 и скомпилируйте его в Raspberry.
Найдите, какой /dev/sdX является вашим USB-устройством, и измените все команды main.py соответственно
sudo apt install imagemagick
Отредактируйте main.py, указав правильные отступы. Из-за особенностей конструкции видны не все пиксели дисплея E-Ink.
Разработка с данными-заполнителями
npm i
npm start
Откройте http://127.0.0.1:8080/ , чтобы настроить визуальные элементы со значениями заполнителей, жёстко запрограммированными в src/templates/index.html.
Отображение реальных значений
Откройте http://127.0.0.1:8080/render.html.
npm run render для запуска инструмента CLI, который отображает HTML вsrc/templates/render.html
Вызов облачной функции
Облачная функция и интерфейс командной строки поддерживают основные операции с изображениями, чтобы выгрузить эту работу из Raspberry: rotate, flip, flip, padding(Top|Right|Bottom|Left), resizeToWidth, resizeToHeight. См. Sharp для их документов. Например --flip с CLI или ?flip=true с CF.
LAT="60.222"
LON="24.83"
LOCATION="Espoo"
BATTERY="100"
TIMEZONE="Europe/Helsinki"
curl -vv -o weather.png \
-H "x-api-key: $API_KEY" \
"https://europe-west3-weather-display-367406.cloudfunctions.net/weather-display?lat=$LAT&lon=$LON&locationName=$LOCATION&batteryLevel=$BATTERY&timezone=$TIMEZONE"
Что ещё интересного есть в блоге Cloud4Y
→ Информационная безопасность и глупость: необычные примеры
→ It's Alive! Аккордеон из двух Commodore 64 и дискет
→ Как распечатать цветной механический телевизор на 3D-принтере
→ WD-40: средство, которое может почти всё
→ Подержите моё пиво, или как я сделал RGBeeb, перенеся BBC Micro в современный корпус
Подписывайтесь на наш Telegram-канал, чтобы не пропустить очередную статью. Пишем только по делу. А ещё напоминаем про второй сезон нашего сериала ITить-колотить. Его можно посмотреть на YouTube и ВКонтакте.
Комментарии (33)
gibson_dev
16.11.2022 11:34+15Мне кажется что esp32 был бы гораздо энергоэфективней и занимает меньше места
blind_oracle
16.11.2022 14:32+1Да, товарищ явно перемудрил. У меня есть копеечные погодные станции с небольшим TFT и ESP32 собранные на коленке - работает идеально и стоит баксов 10 :)
megasuperlexa
17.11.2022 13:17+2ну он вроде написал свою мотивацию - красивый внешний вид с возможностью самому его задизайнить
blind_oracle
17.11.2022 13:44+2Ну мы тут не про дизайн, а про то что Raspberry тут явный оверкилл. ESP32 ценой в три бакса делает всё то же гораздо проще и кушает энергии копейки.
А в его случае нужно по RTC несколько раз в день будить Малину, загружать линух, запускать скрипты чтобы обновить погоду... в общем, из пушки по воробьям.
xface
16.11.2022 12:01+39Я сделал на готовом устройстве LILYGO® TTGO T5-4.7(ESP32)
корпус распечатал сам и прошивку взял готовую(ссылку потерял).
Использует яндекс API, 50 запросов в сутки хватает, батарею держит долго, так как после запроса погоды засыпает.RealBeria
16.11.2022 12:53+11красиво и лаконично у Вас получилось! А проект из статьи похож на "у меня была raspberry, и я не знал куда ее засунуть".
nixtonixto
16.11.2022 17:10+2Я бы не рекомендовал заряжать аккумулятор до 4,4 В, даже если это разрешено в документации. Лучше ограничиться 4,1...4,2 В.
xface
16.11.2022 17:314.4 вольта показывает, когда идет зарядка. На фото он подключен к USB разъему ПК
blind_oracle
17.11.2022 21:12По идее даже при зарядке столько не должно быть. Хотя где вольтаж он показывает - входной или на батарее - хз...
AlexVWill
16.11.2022 12:57+1Красиво получилось. Чего точно не хватает - это внешнего датчика наружной температуры и датчика атмосферного давления, но это было бы намного сложнее реализовать.
redmanmale
16.11.2022 12:58+15Не могу
смиритьсяпривыкнуть, что для отображения погоды нужен полноценный компьютер с операционкой и прочим.Где-то мы свернули не туда.
Iv38
16.11.2022 14:42+7С этой задачей с огромным запасом справляется ESP32 (или ESP 8266). Автор использует компьютер только потому, что иначе не умеет.
mordotron
17.11.2022 09:20+3автор, походу, вообще мало чего умеет, особенно в планирование - начинать проект полностью завязанный на железо и электронику не имея паяльника и даже не умея паять, это какое-то особое финское кунг-фу.
В итоге вся статья больше смахивает на попытку собрать из лего полноценную конструкцию с преодолеванием сопутствующих проблем, при этом из навыков обладая только навыками сборки лего.
sav13
16.11.2022 13:21+1А нет ли платы (или схемы) подключения 6" экранов от электронных читалок?
tklim
17.11.2022 09:19+2https://github.com/vroland/epdiy - ESP32, в качестве "драйвера" используется I2S интерфейс.
Корпус - тут. В интерьере смотрится норм. Хотя можно было бы лучше обработать и лучше покрасить.
laminar
17.11.2022 15:08I2S ???
tklim
17.11.2022 17:08https://github.com/vroland/epdiy/blob/master/src/epd_driver/i2s_data_bus.h
/** * Implements a 8bit parallel interface to transmit pixel * data to the display, based on the I2S peripheral. */
AotD
16.11.2022 14:31Спасибо за статью, явно лучше чем новость https://habr.com/ru/news/t/581388/
Тут по крайней мере полный разбор, хотя база компонентная и, похоже, программная одна и та же.
aborouhin
16.11.2022 15:30+2Автор - явно дизайнер, которому прежде всего хотелось сделать красиво :) Респект за внимание к деталям и всё такое...
Но если подумать про юзабилити - то потребность посмотреть на погоду возникает не у входной двери, а в спальне/гардеробной, чтобы определиться, надевать нам футболку, рубашку или свитер. В прихожей мы уже определяемся с курткой, обувью и зонтиком. Но там неплохо бы заодно и посмотреть на пробки (или расписание прибытия транспорта), список ближайших встреч в календаре, нет ли свежих срочных сообщений, которые вынудят изменить планы... В общем всё, что нам обычно и показывает смартфон. И вот всё это дублировать в красивых рамочках, мягко говоря, очень трудоёмко и не очень эффективно.
Достать из кармана смартфон - не такая уж непосильная задача. Или обзавестись умными часами. Ну или если очень хочется повесить что-то стенку - то повесить туда обычный планшет, на начальный экран которого вывести уже готовые виджеты. Мешает подсветка - ну сделать пробуждение по тапу на экран. Проштробить, замазать и перекрасить эту стенку, чтобы обеспечить его постоянным питанием, право, быстрее и проще, чем всё описанное в статье :)
vadimk91
16.11.2022 17:50По поводу "проштробить, замазать": в многоквартирных финских домах просто так нельзя, нужно согласовывать. Это в России наверное каждый новый владелец квартиры считает свои долгом сделать не только косметический ремонт, а ещё и перепланировки на свой вкус, зачастую без каких-либо разрешений.
QuAzI
16.11.2022 18:55E-ink это всегда весело и интересно, но я нигде не могу найти ответ на вопрос, как, например, из браузеров через всякие css media query определять что на железке e-ink и что он умеет. Например, у меня читалка с color e-ink и я её отличить от планшета могу только по весьма косвенным признакам, которые у других железок с e-ink не факт что сойдутся.
Maxim-8
17.11.2022 09:18+1Пишут что вот это работает почти везде:
boolean isEInk() {
return getWindowManager().getDefaultDisplay().getRefreshRate() < 5.0;
}QuAzI
17.11.2022 20:29А где пишут? У меня летит `Uncaught ReferenceError: getWindowManager is not defined`, а поиск по ошибке выдаёт только статьи про аппликуны под Android, а не про браузер читалки
shornikov
16.11.2022 20:53+1Красиво, но дорого. Даже если малинку заменить.
Если только про погоду говорить, то по цене экрана (а то и деревянной рамки) можно "Алиса, чё за бортом?"
Geek_and_Cat
16.11.2022 21:45Спасибо за статью, получилось очень аккуратно. Присоединяюсь к комментариям, что для этих целей хватило бы и микроконтроллера типа ESP.
У меня была идея сделать аналогичный девайс, где помимо погоды выводились бы предупреждения от датчиков умного дома о не выключенном свете, плите и пр. Хотя и в ваше устройство такой функционал при желании можно добавить.
overmind88
17.11.2022 12:56Если кто хочет дёшево и сердито, то древний планшет на андроиде с wi-fi и программа whatweather отлично справляются
vit1252
17.11.2022 14:41Два чаю этому господину. Респект и уважение. А устройство в производство.
Я серьезно предложите идею IKEA. С удовольствием куплю такую рамку.
divinity2000
Интересно узнать -- на какой период хватит заряда аккумулятора :)
AlexVWill
У меня есть обычная погодная станция с жидко-кристаллическим дисплеем и радиодатчиком наружной температуры. Там 2 пальчиковые батарейки АА, их хватает примерно на 5 месяцев (точно не замерял), в самом датчике 2 AAA (примерно на год работы). Если тут примерно та же история, то очень неплохо...
HardWrMan
У меня стоит метеостанция с 3мя компонентами: блок наружних датчиков, блок внутренних датчиков и табло. Табло питается от БП, а блоки датчиков на батарейках. Причём, табло показывает в каком датчике батарейки садятся. Во внутреннем датчике 2х ААА, а в наружнем 3х АА. Так вот, за 4 года внеший датчик я ещё ни разу не менял, хотя был готов через год туда залезть (я поставил хорошие Varta + на блоке датчиков есть небольшая солнечная батарея, она днём измеряет освещённость и подпитывает блок), а вот во внутреннем уже раза 3 менял.
Если говорить за eInk устройства, то моя 9" книга имеет примерно такой же аккумулятор, как у описываемой рамки, её хватает на почти год в дежурном режиме, где демонстрируется слайдшоу со сменой кадров 1 раз в час примерно. Хотя точно я не замерял, может немного и меньше.
yarkovoy
Подскажите какую станцию вы используете?