Всем привет! Уверен что вы по мне скучали — теперь я продолжу радовать вас ежедневными обновлениями.
Небольшое дополнение к недавней статье «Домашняя метеостанция».
Мне интересно видеть не только текущие данные, но и историю изменения их во времени — добавим к веб-странице график.
Содержание:
Хранение данных
Используем базу данных 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 записей.
Итоговый результат можно смотреть на странице моей домашней метеостанции.