- PVSM.RU - https://www.pvsm.ru -

Погодная станция из Arduino и Orienteer

Под Новый Год ко мне приходит желание разработать что-нибудь нестандартное. В этот раз я решил начать собирать и обрабатывать погодные данные возле своего дома. И, конечно, выбрал Arduino в качестве железа, а вот в качестве хранилища и инструмента просмотра и анализа — упоминавшийся недавно на Хабрахабре [1] конструктор бизнес-приложений Orienteer. Тем что получилось, я поделюсь в этой заметке.

Погодная станция из Arduino и Orienteer - 1

Почему именно эта связка, ведь можно сделать без Arduino на голом Atmel микроконтроллере и в качестве хранилища использовать связку PHP/MySQL? Всё просто: не хотелось возится с ЛУТ [2]ом, ибо лазерного принтера под рукой небыло, да и PHP порядком надоел. А самое главное — хотелось попробовать этот самый Orienteer [3] в боевых условиях, а не тыкать кнопки в демонстрационном приложении [4].

Принцип работы прост: опрашиваем датчики, формируем и отправляем REST запрос в Orienteer.

В связи с небольшим количеством железа под Arduino в моем арсенале была выбрана следующая связка железа:

  1. Arduino UNO R3 (точнее ее китайский клон с CH340)
  2. Датчик температуры и влажности DHT22
  3. Ethernet шилд
  4. Соединительные провода

Погодная станция из Arduino и Orienteer - 2

Аппаратная часть

Погодная станция из Arduino и Orienteer - 3

Как видно схема подключения очень проста, обвязки для датчика не требуется. Берем 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 поясню:

  • DHTPIN — разъем Arduino к которому подключен датчик
  • DHTTYPE — тип датчика, используется библиотекой Adafruit
  • DELAY_MILLIS — интервал отправки данных, по умолчанию значение 30000UL, что означает 30 секунд
  • REST — часть URL адреса для REST протокола
  • SERVER_NAME — IP адрес или хост сервера, где запущен Orienteer
  • SERVER_PORT — порт сервера
  • AUTH_BASE64 — закодированная в BASE64 кодировке строка login:password для Basic HTTP [8] аутентификации (в нашем случае admin:admin)
  • DEVICE_ID — идентификатор устройства сбора данных, то есть нашей Arduino, предполагается сбор с нескольких точек (например: дом/улица)

Дальше также все стандартно — инициализация датчика, Ehternet шилда. Для отправки данных по REST в Orienteer нужно подготовить JSON с информацией — класс и данные. Код для отправки запроса я вынес в отдельную функцию. Стоит обратить внимание на отправку POST запроса и базовую авторизацию, если вы недавно изучаете Arduino.

Отправка HTTP заголовков

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 и его настройка

Вот и подошли к серверной части. Запустим и настроим платформу Orienteer для получения данных и вывода графиков.

Запустить платформу можно из исходников [9], а можно и Docker контейнер [10] (подробнее в официальной документации [11]). Спасибо авторам что упаковали все это дело в контейнер, очень удобный способ доставки приложения. Для разворачивания предположим что Docker [12] у вас установлен и есть минимальные навыки работы с ним, такие как запуск и остановка контейнера. Если это не так, то вам сюда [13] и сюда [14].

Для начала скачаем свежий образ контейнера с приложением, я работал на ОС Ubuntu:

sudo docker pull orienteer/orienteer

Вы увидите следующее:

Погодная станция из Arduino и Orienteer - 4

Немного подождав, образ скачается и его можно будет запустить:

sudo docker run -p 8080:8080 orienteer/orienteer

Заходим на адрес localhost:8080 в браузере, входим с парой логин-пароль: admin/admin. Выберем в меню Schema → Classes → +Create для создания класса модели данных и укажем название класса — Weather. Не забудем сохранить новый класс:

Погодная станция из Arduino и Orienteer - 5

Теперь создадим свойства класса. Нам нужно сохранять: температуру, процент влажности, имя устройства и время обращение устройства. На странице свойств класса (localhost:8080/class/Weather) добавим свойства:

Погодная станция из Arduino и Orienteer - 6

У свойства dateTime в качестве значения по умолчанию укажем функцию sysdate() для получения текущего времени в момент прихода данных от устройства. Погрешность даже в несколько секунд не критична в нашем случае.

Готово, проверим — приходят наши данные? Все отлично, есть контакт!

Погодная станция из Arduino и Orienteer - 7

Но, как мы видим — данные не в очень удобном виде нам подаются. Не беда, в Orienteer есть замечательные виджеты Pivot Table, HTML/JS и даже можно создать свою страницу для отображения, но остановимся на виджетах. Нам необходимо отображать последние пришедшие данные: температуру, процент влажности, время последнего обновления; средние показатели за дни.

Для добавления виджета перейдем Schema → Weather → Browse Class и нажмем на значок шестеренки в верхнем правом углу. Нажмем Add widget и добавим виджет Html Js Pane. Сохраним состояние виджета нажатием Save. Далее перейдем в настройки виджета по Actions → Settings, нажмем кнопку Edit.

Погодная станция из Arduino и Orienteer - 8

Добавим ресурс для отображения — Weather(это значит, что данный виджет будет показываться только если мы находимся на странице просмотра объектов данного класса), укажем HTML и JS коды виджета.

HTML

<h1 id="last-temp">Update...</h1>
<h1 id="last-hum">Update...</h1>
<span id="last-datetime"></span>

JavaScript

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

В режиме редактирования виджетов зададим конфигурацию графику:

Погодная станция из Arduino и Orienteer - 9

А во втором виджете для отображения среднего процента влажности за сутки следующий SQL:

SELECT dateTime, AVG(humidity) AS hum FROM Weather LET $day = dateTime.format('yyyy-MM-dd') GROUP BY $day

Но в конфигурации графика укажем значение hum с результата SQL запроса:

Погодная станция из Arduino и Orienteer - 10

И в итоге у нас получилась отличная система для сбора и отображения погодных данных.

Длинный скриншот

Погодная станция из Arduino и Orienteer - 11

В планах:

  • Добавить дополнительные датчики: давления, CO2 [15], уровня освещенности
  • Добавить часы реального времени(корректная реализация, когда у нас время считывания, а не время получения данных)
  • Предварительное кеширование на SD карту памяти для выгрузки среза данных
  • Вывод на дисплей погодных данных и сообщений об ошибках датчиков или проблем со связью
    настройка виджета

Все обновления будут на 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