Недавно я столкнулся с задачей визуализации данных от датчиков (температура, влажность, частицы PM2.5). Для решения подобных задач существует несколько бесплатных инструментов, например, Grafana + InfluxDB. Найденные мной решения показались слишком сложными и требовательными к ресурсам сервера, поэтому я решил «изобрести свой велосипед», а точнее создать шаблон для Shopker.
Shopker — бесплатный движок для создания сайта, который использует PHP фреймворк Symfony (5+), JS фреймворк Angular (11+) и базу данных MongoDB (4+). Сайт проекта: https://shopker.org/.

Сначала я расскажу как быстро развернуть сайт и настроить приём данных от датчиков, а во второй части остановлюсь немного подробнее на исходном коде шаблона. Результат можно посмотреть здесь.
1. Установка Shopker
Этот пункт я не буду расписывать подробно, т.к. всё есть в документации. Рекомендую использовать Bash скрипт для установки на VDS сервере. В разделе «Уроки» есть видео.
2. Установка шаблона
Скачиваем shopker-templates.zip здесь. Или можно на своем сервере клонировать репозиторий и воспользоваться командой npm install
Распаковываем архив и по FTP загружаем папку «iot» в папку «/templates/», а папку «/assets/iot/» в «/public/», чтобы получилось «/public/assets/iot/».
Открываем админку, переходим в раздел «Настройки». В пункте «Тема шаблонов» вводим название новой темы — iot. Сохраняем.
3. Создание типа контента и коллекции в БД
Переходим в раздел «Каталог» -> «Типы контента», нажимаем кнопку «Добавить».
В поле «Заголовок» вводим «Датчики», системное имя — «sensors», коллекция — «sensors». Активируем чекбокс «Разрешено создание пользователями». Это нужно, чтобы иметь возможность сохранять новые данные через API. Далее создаем первое поле — «Температура, С». Системное имя — «temperature», тип ввода и тип вывода — «Число», группа — «Основное», чекбоксы — «Показывать в таблице», «Показывать на странице» и «Показывать в списке».

Повторяем операцию для всех полей, куда хотим сохранять показания датчиков. Последнее поле «Дата и время». Системное имя — «time», тип ввода и тип вывода — «Дата», группа — «Основное», чекбоксы — «Показывать в таблице», «Показывать в списке», «Показывать в фильтре». Последний чекбокс нужен, если мы хотим фильтровать данные по дате. Сохраняем.
4. Создание категории
Переходим в раздел «Каталог», в выпадающем меню нажимаем кнопку «Добавить новую категорию». Заголовок — «Датчики», системное имя — «sensors», тип контента — «Датчики».

Далее создаем дочернюю категорию «Устройство #1» (название Вашего устройства). В эту категорию будем сохранять данные от датчиков. Запомните ID этой категории, оно пригодится.

5. Отправка данных и сохранение
Для использования API нам нужен токен. Его можно создать через запрос, используя свой логин и пароль, а можно в разделе «Пользователи».

Вот пример использования API для Bash:
curl -X POST \ "http://your-domain.com/api/ru/user_content/19" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "X-AUTH-TOKEN: xxxxx" \ -d '{"temperature":23,"humidity":35}'
Если используете ESP2866 или подобный модуль wi-fi, то функция отправки данных будет примерно такая:
// Shopker settings char shopkerApiUrl[45] = "http://your-domain.com/api/ru/user_content/19";// 19 - ID категории char shopkerApiKey[121] = "c5f3a652f67c5d31a5cd39ec287bd3ba36e1b7737dc9e26ae697c4d467c8638a1f1bd62906b00f4a1f83f1214fad20fe3fbe49d135f263c10d64b137";// API токен ... void sendDataToShopker(float temp, float hum, int pm2, int pm10) { Serial.println("API URL: " + String(shopkerApiUrl)); String jsonString = "{"; jsonString += "\"temperature\":" + String(temp) + ", "; jsonString += "\"humidity\":" + String(hum) + ", "; jsonString += "\"pm25\":" + String(pm2) + ", "; jsonString += "\"pm10\":" + String(pm10); jsonString += "}"; Serial.println(jsonString); HTTPClient http; http.begin(shopkerApiUrl); http.addHeader("Content-Type", "application/json"); http.addHeader("Accept", "application/json"); http.addHeader("Content-Length", String(jsonString.length())); http.addHeader("X-AUTH-TOKEN", String(shopkerApiKey)); int httpCode = http.POST(jsonString); String response = http.getString(); Serial.println("Response code: " + String(httpCode)); Serial.println("Response: " + response); http.end(); }
6. Вывод значений на графиках
Чтобы по умолчанию выводились данные с конца (последняя страница), нужно в настройках указать отрицательное число в параметре «Число элементов на странице по умолчанию» (например «-50»), а сортировку указать — «id_asc» (по порядку по ID).
Технические подробности
Для вывода графиков на главной станице используется Twig-функция «contentList»:
{{ contentList('sensor_data', 'sensors', {"isActive": true, parentId: 19}, {"_id": "asc"}, -50) }}
Подробнее о ней в документации: https://shopker.org/documentation/content-display
«sensor_data» — это название шаблона, который находится в папке «/templates/iot/catalog» — «sensor_data.html.twig». В этот шаблон передается тип контента, из которого можно взять массив полей, которые отмечены для показа:
{% set fieldsOnPage = contentType.getFieldsByFlag('showOnPage') %}
Для вывода графиков используется JS-библиотека Plotly.
При желании можно выводить данные только для зарегистрированных пользователей:
{% if is_granted('ROLE_USER') %} Тут контент для зарегистрированных и авторизованных. {% endif %}
ссылка на оригинал статьи https://habr.com/ru/post/535158/
Добавить комментарий