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

Під Новий Рік до мене приходить бажання розробити щось нестандартне. В цей раз я вирішив почати збирати і обробляти погодні дані біля свого будинку. І, звичайно, вибрав Arduino в якості заліза, а от в якості сховища та інструменту перегляду та аналізу — згадуваний нещодавно на Хабрахабре конструктор бізнес-додатків Orienteer. Тим що вийшло, я поділюся в цій замітці.



Чому саме ця зв'язка, адже можна зробити без Arduino на голому Atmel мікроконтролері і в якості сховища використати зв'язку PHP/MySQL? Все просто: не хотілося возитися з ЛУТом, бо лазерного принтера під рукою не було, так і PHP порядком набрид. А найголовніше — хотілося спробувати цей самий Orienteer в бойових умовах, а не тикати кнопки демонстраційному додатку.

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

У зв'язку з невеликою кількістю заліза під Arduino в моєму арсеналі була обрана наступна зв'язка заліза:

  1. Arduino UNO R3 (точніше її китайський клон з CH340)
  2. Датчик температури і вологості DHT22
  3. Ethernet шилд
  4. З'єднувальні дроти


Апаратна частина


Як видно схема підключення дуже проста, обв'язки для датчика не потрібно. Беремо Arduino, підключаємо Ethernet шілд, підключаємо датчик. Я використовував датчик DHT22, він вимірює температуру і відсоток вологості, ви можете використовувати будь-який, який є у вас під рукою.

Перейдемо до кодом скетчу для Arduino. На самому початку все стандартно: підключаються необхідні бібліотеки. В моєму випадку потрібні: Adafruit Unified Sensor Driver і Adafruit DHT Humidity & Temperature Unified Sensor Library, а також бібліотеки для роботи з 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 аутентифікації (в нашому випадку 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: close\r\nContent-Type: application/x-www-form-urlencoded"));


Генерація JSON для відправки даних формується з допомогою функції sprintf():

sprintf(params,"{'@class':'Погода', 'temperature':%i, 'humidity':%i, 'device':'%s'}", temperature, humidity, DEVICE_ID);

Інтервал для відправки реалізовано за допомогою функції millis(). У випадку помилки лаємося в послідовний інтерфейс.

Orienteer і його налаштування
Ось і підійшли до серверної частини. Запустимо і налаштуємо платформу Orienteer для отримання даних і виводу графіків.

Запустити платформу можна з исходников, Docker контейнер (детальніше офіційній документації). Спасибі авторам що упакували все це справа в контейнер, дуже зручний спосіб доставки додатки. Для розгортання припустимо що Docker у вас встановлений і є мінімальні навички роботи з ним, такі як запуск і зупинка контейнера. Якщо це не так, то вам сюди і сюди.

Для початку завантажити свіжий образ контейнера з додатком, я працював на ОС 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 коди віджета.

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

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



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

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

Але в конфігурації графіка вкажемо значення hum з результату запиту SQL:



І в результаті у нас вийшла відмінна система для збору і відображення погодних даних.

Довгий скріншот

В планах:

  • Додати додаткові датчики: тиску, CO2, рівня освітленості
  • Додати годинник реального часу(коректна реалізація, коли у нас час зчитування, а не час отримання даних)
  • Попереднє кешування на SD карту пам'яті для вивантаження зрізу даних
  • Висновок на дисплей погодних даних і повідомлень про помилки датчиків або проблем зі зв'язком
    налаштування віджета
Усі оновлення будуть на GitHub. А я тим часом поліз на Aliexpress замовляти залізо для вдосконалення своєї системи. Хочеться ще спробувати Orienteer як backend програми для AngularJS або Android додатки, але це тема окремої статті.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.