- PVSM.RU - https://www.pvsm.ru -
Под Новый Год ко мне приходит желание разработать что-нибудь нестандартное. В этот раз я решил начать собирать и обрабатывать погодные данные возле своего дома. И, конечно, выбрал Arduino в качестве железа, а вот в качестве хранилища и инструмента просмотра и анализа — упоминавшийся недавно на Хабрахабре [1] конструктор бизнес-приложений Orienteer. Тем что получилось, я поделюсь в этой заметке.
Почему именно эта связка, ведь можно сделать без Arduino на голом Atmel микроконтроллере и в качестве хранилища использовать связку PHP/MySQL? Всё просто: не хотелось возится с ЛУТ [2]ом, ибо лазерного принтера под рукой небыло, да и PHP порядком надоел. А самое главное — хотелось попробовать этот самый Orienteer [3] в боевых условиях, а не тыкать кнопки в демонстрационном приложении [4].
Принцип работы прост: опрашиваем датчики, формируем и отправляем REST запрос в Orienteer.
В связи с небольшим количеством железа под Arduino в моем арсенале была выбрана следующая связка железа:
Как видно схема подключения очень проста, обвязки для датчика не требуется. Берем Arduino, подключаем Ethernet шилд, подключаем датчик. Я использовал датчик DHT22, он измеряет температуру и процент влажности, вы можете использовать любой, который есть у вас под рукой.
Перейдем к коду скетча [5] для Arduino. В самом начале все стандартно: подключаются необходимые библиотеки. В моем случае потребовались: Adafruit Unified Sensor Driver [6] и Adafruit DHT Humidity & Temperature Unified Sensor Library [7], а также библиотеки для работы с Ethernet.
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#include <SPI.h>
#include <Ethernet.h>
Далее объявляются константы для быстрого редактирования, названия сами говорят за себя, но для новичков в Arduino поясню:
Дальше также все стандартно — инициализация датчика, Ehternet шилда. Для отправки данных по REST в Orienteer нужно подготовить JSON с информацией — класс и данные. Код для отправки запроса я вынес в отдельную функцию. Стоит обратить внимание на отправку POST запроса и базовую авторизацию, если вы недавно изучаете Arduino.
sprintf(outBuf,"POST %s HTTP/1.1",page);
client.println(outBuf);
sprintf(outBuf,"Authorization: Basic %s", AUTH_BASE64);
client.println(outBuf);
sprintf(outBuf,"Host: %s",domainBuffer);
client.println(outBuf);
client.println(F("Connection: closernContent-Type: application/x-www-form-urlencoded"));
Генерация JSON для отправки данных формируется с помощью функции sprintf():
sprintf(params,"{'@class':'Weather', 'temperature':%i, 'humidity':%i, 'device':'%s'}", temperature, humidity, DEVICE_ID);
Интервал для отправки реализован с помощью функции millis(). В случае ошибки ругаемся в последовательный интерфейс.
Вот и подошли к серверной части. Запустим и настроим платформу Orienteer для получения данных и вывода графиков.
Запустить платформу можно из исходников [9], а можно и Docker контейнер [10] (подробнее в официальной документации [11]). Спасибо авторам что упаковали все это дело в контейнер, очень удобный способ доставки приложения. Для разворачивания предположим что Docker [12] у вас установлен и есть минимальные навыки работы с ним, такие как запуск и остановка контейнера. Если это не так, то вам сюда [13] и сюда [14].
Для начала скачаем свежий образ контейнера с приложением, я работал на ОС Ubuntu:
sudo docker pull orienteer/orienteer
Вы увидите следующее:
Немного подождав, образ скачается и его можно будет запустить:
sudo docker run -p 8080:8080 orienteer/orienteer
Заходим на адрес localhost:8080 в браузере, входим с парой логин-пароль: admin/admin. Выберем в меню Schema → Classes → +Create для создания класса модели данных и укажем название класса — Weather. Не забудем сохранить новый класс:
Теперь создадим свойства класса. Нам нужно сохранять: температуру, процент влажности, имя устройства и время обращение устройства. На странице свойств класса (localhost:8080/class/Weather) добавим свойства:
У свойства dateTime в качестве значения по умолчанию укажем функцию sysdate() для получения текущего времени в момент прихода данных от устройства. Погрешность даже в несколько секунд не критична в нашем случае.
Готово, проверим — приходят наши данные? Все отлично, есть контакт!
Но, как мы видим — данные не в очень удобном виде нам подаются. Не беда, в Orienteer есть замечательные виджеты Pivot Table, HTML/JS и даже можно создать свою страницу для отображения, но остановимся на виджетах. Нам необходимо отображать последние пришедшие данные: температуру, процент влажности, время последнего обновления; средние показатели за дни.
Для добавления виджета перейдем Schema → Weather → Browse Class и нажмем на значок шестеренки в верхнем правом углу. Нажмем Add widget и добавим виджет Html Js Pane. Сохраним состояние виджета нажатием Save. Далее перейдем в настройки виджета по Actions → Settings, нажмем кнопку Edit.
Добавим ресурс для отображения — Weather(это значит, что данный виджет будет показываться только если мы находимся на странице просмотра объектов данного класса), укажем HTML и JS коды виджета.
<h1 id="last-temp">Update...</h1>
<h1 id="last-hum">Update...</h1>
<span id="last-datetime"></span>
function getWeather(){
var url = "/orientdb/query/db/sql/SELECT temperature, humidity, dateTime.format('dd.MM.yyyy HH:mm') AS dt FROM Weather ORDER BY dateTime.asLong() DESC LIMIT 1/1?rnd="+Math.random();
$.getJSON( url, {})
.done(function( data ) {
$('#last-temp').html(data.result[0].temperature + '°');
$('#last-hum').html(data.result[0].humidity+ '%');
$('#last-datetime').html(data.result[0].dt);
});
}
(function() {
getWeather();
})();
И сохраним — жмем Save.
Аналогичными действиями добавляем виджеты Pivot Table для отображения графиков. В одном для отображения средней температуры за сутки в настройках укажем SQL запрос для средней температуры:
SELECT dateTime, AVG(temperature) AS temp AS hum FROM Weather LET $day = dateTime.format('yyyy-MM-dd') GROUP BY $day
В режиме редактирования виджетов зададим конфигурацию графику:
А во втором виджете для отображения среднего процента влажности за сутки следующий SQL:
SELECT dateTime, AVG(humidity) AS hum FROM Weather LET $day = dateTime.format('yyyy-MM-dd') GROUP BY $day
Но в конфигурации графика укажем значение hum с результата SQL запроса:
И в итоге у нас получилась отличная система для сбора и отображения погодных данных.
В планах:
Все обновления будут на GitHub [16]. А я тем временем полез на Aliexpress заказывать железо для совершенствования своей системы. Хочется еще попробовать Orienteer в качестве backend приложения для AngularJS или Android приложения, но это тема отдельной статьи.
Автор: IvanSCM
Источник [17]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/arduino/234478
Ссылки в тексте:
[1] Хабрахабре: https://habrahabr.ru/company/orienteer/blog/312844/
[2] ЛУТ: http://easyelectronics.ru/sozdanie-pechatnoj-platy-metodom-lazernogo-utyuga.html
[3] Orienteer: http://orienteer.org/
[4] демонстрационном приложении: http://demo.orienteer.org/
[5] коду скетча: https://github.com/ivanscm/orienteer-weather-arduino/blob/master/Orienteer-weather.ino
[6] Adafruit Unified Sensor Driver: https://github.com/adafruit/Adafruit_Sensor
[7] Adafruit DHT Humidity & Temperature Unified Sensor Library: https://github.com/adafruit/DHT-sensor-library
[8] Basic HTTP: https://en.wikipedia.org/wiki/Basic_access_authentication
[9] исходников: https://github.com/OrienteerBAP/Orienteer
[10] Docker контейнер: https://hub.docker.com/r/orienteer/orienteer/
[11] официальной документации: https://orienteer.gitbooks.io/orienteer/content/installation.html
[12] Docker: https://www.docker.com/
[13] сюда: https://docs.docker.com/engine/installation/
[14] сюда: https://docs.docker.com/engine/getstarted/step_one
[15] CO2: https://geektimes.ru/post/258874/
[16] GitHub: https://github.com/ivanscm/orienteer-weather-arduino
[17] Источник: https://habrahabr.ru/post/319746/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox
Нажмите здесь для печати.