Привет, коллеги.
В общем, да, еще один маленький пост про python. Спойлер. Скоро будет много интересного про сети, обещаю. Сегодня про домашние часы... хочу просто поделиться.
Как, наверное, у многих у меня есть Raspberry Pi. Девайсом я всячески доволен и последние несколько лет "пишка" служила мне домашними часами с возможностью изменять температуру и влажность. До тех пор, пока на ней не сдохла флешка. Некоторое время у меня не доходили руки её восстановить, но очень хотелось. В итоге, я собрался с мыслями и решил все переделать с нуля добавив много всяких интересных функций.
Дано
- Raspberry Pi 1 Model B
- Два семисегментных дисплея
- Сенсор температуры
- Сенсор влажности
- Сенсор атмосферного давления
Цели
- Замер показателей и отображение информации с сенсоров
- Хранение данных для последующего анализа
- Возможность строить и просматривать графики через web
- Ах, да... часы
Мысли по реализации
Прошлая реализация была написана мной в далекие годы, когда программировал я ещё хуже, чем сейчас... Поэтому тогда это был один python скрипт, который содержал в себе весь функционал. Его правда было не так много. Стало быстро понятно, что такой подход в моем случае уже не подходит.
Было решено разделить все "решение" на модули, каждый из которых делает только одну задачу.
- Опрос датчиков
- Отображение данных на дисплее
- Веб фронтенд
- Запись данных в базу для хранения
Я довольно быстро столкнулся с проблемой передачи данных между всеми процессами. Писать в локальный файл не хотелось (помним прошлую сдохшую флешку), импортировать модули и исполнять из одного скрипта еще худшая идея. Мало того, что это не масштабируется (масштабирование в часах...), так еще и "фризы" в работе появляются. Когда делаешь часы фризы очень заметны... )
Попробовав несколько решений, я решил хранить данные в памяти с помощью memcahced. Возможно, это слишком громоздкое решение, однако задачу свою выполняет оно прекрасно.
Для графиков сразу же был выбран pygal за простоту и svg файл в "выхлопе".
В качестве фронтенда выступает Flask, очень классный и простой микрофреймфорк с достаточным количеством плюшек.
Хранить файлы нужно структурировано и красиво, а значит нужна SQL база. sqlite подошел как нельзя лучше.
В итоге получаем довольно тривиальный список:
- flask
- sqlite3
- memcached
Для датчиков используем соответствующее драйвера:
- Luma.LED_Matrix: драйвер дисплея MAX7219
- Adafruit_DHT: AM2302 (для температуры и влажности)
- Adafruit_BMP: BMP085 (для давления)
В итоге схема взаимодействия выглядит примерно так (кликабельно).
Хотя мне больше нравится такая версия. Как-то она больше отражает суть дела. Как видно Web модуль имеет возможность обращаться не только к базе, но и к памяти для отображения текущий показателей.
Реализация
Честно говоря, не уверен, что стоит расписывать конкретные функции. Во-первых, все можно посмотреть на GitHub. Во-вторых, кода все больше и описать его все сложнее и сложнее.
Поэтому просто опишу каждый модуль с пояснениями и особенностями.
Опрашивает датчики каждые 10 секунд и кладет данные в память. Здесь же ставим таймер на 300 секунд. Если процесс упадет и данные не обновятся, они будут удалены из памяти. Очень хотелось получать еще и температуру за окном, поэтому забираю прогноз отсюда http://wttr.in/?format=3.
Берет данные из памяти и отображает на дисплее. На гифке в начале поста виден пример. Правая часть всегда показывает часы, а левая меняется каждые 3 секунды.
В файле с модулями есть несколько функций
get_db_data - вынимает данные из базы за определенный период
graph_from_data - забирает данные и строит по ним график
db_to_graph - объединение прошлых двух функций, идем и в базу и строим график
В самом модуле описана простая "web-морда". Фреймфорк "слушает" два пути
/ - в случае GET генерируется старичка по jinja-шаблону на которой отображается форма с вводами дат для которых нужно построить график. Так же здесь отображаются текущие показатели выдернутые из памяти. В случае POST выполняется функция db_to_graph из прошлого пункта.
/today - на странице есть ссылка на график за сегодня. Скрипт вычисляет сегодняшнюю дату и строит график по данным из базы. Картинка кешится на 1 час.
Тут все совсем тривиально. Берем данные из памяти и пишем в базу.
Все скрипты запускаются как systemd сервисы (файлики), кроме последнего, который стартует по крону.
Заключение
В общем-то все. Хотелось поделиться. Конечно, немного сложновато для часов, но, блин, OSPF, PIM и IPv6 тоже не особо нужно дома, но как же без них... Думаю прикупить датчик CO2 и наружный датчик температуры еще. Спасибо тем, кто дочитал до конца. Если есть чем прокомментировать, прошу.
В качестве благодарности тем, кто все же смог доскролить до конца. Недавно со мной на связь вышли ребята из Cumulus Linux после того, как я скачал их виртуальный образ на потестить. Очень приятно пообщались. Горю энтузиазмом собрать лабу и хорошенько все погонять. Так что надеюсь что в скором будущем, порадую сетевую аудиторию интересными сетевыми постами.
Комментариев нет:
Отправить комментарий