Метеостанция с историей

Всем привет! Уверен что вы по мне скучали — теперь я продолжу радовать вас ежедневными обновлениями.

Небольшое дополнение к недавней статье «Домашняя метеостанция».

Мне интересно видеть не только текущие данные, но и историю изменения их во времени — добавим к веб-странице график.

meteo

Хранение данных

Используем базу данных MySQL с простейшей таблицей — ID, дата/время, температура в квартире, температура на улице, давление и влажность. Подключимся к ней из Node.js через модуль node-mysql, и при каждом опросе датчиков просто будем записывать новые данные с помощью такого кода:

setInterval(function() {connection.query('insert into meteo values (NULL, DEFAULT, '+thermo[0]+', '+thermo[1]+', '+thermo[2]+', 0);', function(){}); }, 60000);

То есть, каждую минуту складываем в базу новую запись с последними данными с датчиков.

Для получения последних N записей — используем запрос

select * from meteo order by id desc limit 30;

limit 30 ограничивает вывод 30 записями, а благодаря сортировке order by id DESC эти 30 записей отсчитываются с конца.

График

Используем библиотеку jquery.flot — она довольно удобна, красивый график можно сделать написав совсем немного кода.

Всё что вам нужно — подключить библиотеки jQuery и flot, разместить на странице div под график (не забудьте настроить его размеры), и выполнить такую строчку:

$.plot($("#placeholder"), [t1, t2], { xaxis: { mode: "time", timeformat: "%H:%M" }, yaxis: { tickDecimals: 1, labelWidth: 20 } });

В принципе, всё ясно из кода — но всё же немножко прокомментирую.

функция plot строит на выбранном div (который указывается первым параметром) графики наборов данных из второго параметра. На одном графике может быть несколько серий данных, и второй параметр устроен таким образом:

[
[
[x1_1, y1_1],
[x1_2, y1_2],
...
[x1_N, y1_N]
],
[
[x2_1, y2_1],
[x2_2, y2_2],
...
[x2_N, y2_N]
],
[
[x3_1, y3_1],
[x3_2, y3_2],
...
[x3_N, y3_N]
],
...
]

Если нужно отобразить только один набор данных — передайте функции массив [[[x1, y1], [x2, y2], … ]].

Третий аргумент — параметры графика. Можно настроить как общие параметры (название, содержание и размещение легенды) так и параметры осей (тип, формат отметок и значений, цвет и минимум/максимум, ширину поля значений). По умолчанию оси автоматически подстроятся под данные.

Обновление

Теперь нужно только периодически опрашивать сервер, забирая с него новые данные. Чтобы не обновлять страницу — воспользуемся технологией AJAX с помощью библиотеки jQuery. Сервер будет предоставлять два REST API интерфейса:

  • /thermo/new — для получения текущих показаний. Это просто JSON-объект со значениями температур и давления.
  • /thermo/log — для выгрузки истории показаний. Сервер отдаёт JSON-массив с показаниями и датой/временем каждого отчёта.

На клиенте установим два таймера: раз в секунду будем забирать новые показания и раз в 30 секунд — историю. Принятые данные будем отображать на панели текущих значений и на графиках.

Сглаживание

При выводе всех отчётов на график он становится довольно неряшливым и шумным. Простое решение — на сервере брать из базы только каждое десятое или сотое значение, а на клиенте — сгладить график, чтобы при меньшем числе точек он не стал угловатым.

Для сглаживания я использую плагин CurvedLines для библиотеки Flot. Для получения каждого сотого значения из базы — добавляю в SQL-запрос условие «WHERE ID % 100 = 0″, весь запрос теперь выглядит так:

select * from meteo where id%100 = 0 order by id desc limit 30;

То есть, запрос будет вытаскивать из базы каждую сотую запись с конца, и прекратит это делать лишь набрав 30 записей.

Итоговый результат можно смотреть на странице моей домашней метеостанции.