Осциллограф в браузере
- Tutorial
Отрисовка графиков в реальном времени
Одно время я работал в компании, которая разрабатывала бесконтактные датчики, как на фото. И при установке этих датчиков, надо было правильно сориентировать антенну (белая штука на фото). И выглядело это так: один человек на объекте, где-то в Сибири, на морозе крутит антенну, а другой в Питере, в офисе, не видит того человека, но видит графики на мониторе. И вот они как слепой с глухим пытаются поставить антенну, один по графикам, по телефону говорит, что надо антенну повернуть, а другой пытается понять в какую сторону её крутить. Звучит как бред, правда? Но так и было.
Когда я это всё увидел, понял, что получать графики надо локально и прямо здесь и сейчас наблюдать всю картину, чтобы один и тот же человек видел сигнал и крутил антенну. И понял: надо пилить веб-интерфейс для этой железки. Опыта веб-разработки ноль, значит за одно и поучимся.
Техническое задание
Хоть NDA в той компании я не подписывал, всё же считаю, что разглашать какую-либо информации составляющую коммерческую тайну не имею права. Поэтому постараюсь рассказать в общих чертах.
Как видно на фото выше, мы устанавливали температурные датчики, на высоковольтные шины. Датчики пассивные, работают на фазовом сдвиге облучающей частоты (2,4 ГГц), и пассивно переизлучают эту частоту. Сдвиг частот мы фиксируем и улавливаем. К сожалению, у меня не осталось сырых данных того времени, но выглядят это как некоторые такие “горбы”.
Приёмник подключен к промышленному ПК по интерфейсу RS-485, и уже в нём идёт обсчёт и передача данных по интернету на центральный сервер. В целом, приёмник мог бы делать всё сам, но решили для надёжности реализовать таким образом.
Шкаф приёмного оборудования. ПромПК, блок питания, модем и антенна lte.
Таким образом, у нас есть точка входа: промышленный ПК, на котором стоит Linux. В качестве ПК было много различных вариантов использования: как обычные х86+Ubuntu, так и ARM-роутер на OpenWRT. Поэтому решение должно было быть максимально простым универсальным.
Данные со считывателя получала моя программа, которая работала на ПромПК и сохраняла их в csv-файл разделённых табуляциями, где каждый столбец был сигналом с отдельного канала.
Таким образом, надо было просто сделать WEB-интерфейс, и строить график в реальном времени по этому CSV-файлу. Эпизодически пиная считыватель на новую порцию данных.
Реализация
Основа всего алгоритма CGI-bash скрипт (о боже, CGI на bash), который очень прост:
#!/bin/bash
echo "Content-type: text/html;charset=utf-8"
echo
программа_дающая_данные > /var/www/html/result.dat
echo "true"
exit 0Следует помнить о том, что все операции происходят от пользователя и группы www-data:www-data (если для апача). Этот момент у меня попил много крови, вообще помните про свои права и права других пользователей, а также про обязанности.
Вызывая этот CGI-скрипт, я каждый раз получаю свежую порцию данных в файле result.dat, которые можем отобразить. Данные выглядят примерно таким образом:
2019 2010 2160 2006
2023 2052 2041 1992
2053 2048 2181 1991
2019 2054 2147 1968
2003 1977 2189 1982
2052 1987 2101 1961
....Дальше, мне нужно было этот сsv-файл превратить в json. Сделал это с помощью фреймворка Papa Parse, который парсит csv-файл. Построение графика я реализовал на фреймфорке Chart.js. Там громадное количество примеров на вкус и цвет, каждый сможет подобрать подходящее под свою задачу.
Один важный момент: не забывайте очищать массивы, перед внесением новой порции данных. Иначе начинает уплывать память. В момент отладки, на ночь оставил всё, без очищения. Утром пришёл на работу, а мышка уже не в состоянии ползать.
Соберём всё в кучку
Вроде всё просто, осталось всё собрать в единую кучку. Чтобы вам не тратить времени, этот проект я выложил на github github.com/dlinyj/realtime_graph_on_js
Поскольку хочу вам дать рабочий пример, а программа составляет коммерческую тайну, то сделал простенький питоновский скрипт, который генерирует случайные данные для отображения.
#!/usr/bin/env python3
import random
f = open("/var/www/html/result.dat", "w")
for i in range (20):
f.write("%d\t%d\t%d\t%d\t\n" % (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
f.close()Основа всего — это CGI на bash, о котором писал выше, который вызывает этот питоновский скрипт.
#!/bin/bash
echo "Content-type: text/html;charset=utf-8"
echo
/usr/bin/python3 /usr/lib/cgi-bin/test.py > /dev/null 2&>1
echo "true"
exit 0Исходный код всей веб-страницы можно посмотреть вот тут.
Вначале я конфигурирую параметры самого графика. Это всё взято из готовых примеров фреймворка Chart.js.
Обновление графика делается по таймеру. Каждые 2000 мс идёт вызов функции gen_graph(), которая вызывает CGI-скрипт, описанный выше.
var gen_graphUrl = "cgi-bin/gen_graph.sh";
function gen_graph() {
$.ajax({
url: gen_graphUrl,
success: function(result) {
parseData();
}
});
}
parseData();
var timerId = setInterval(function() {
gen_graph();
}, 2000);
function stop_reload () {
clearInterval(timerId);
};Функция parseData() осуществляет парсинг CSV-данных и преобразование из форматт json:
function parseData() {
Papa.parse("result.dat", {
download: true,
complete: function(results) {
createGraph(results.data);
}
});
}В результате, работа нашего тестового примера выглядит следующим образом:
Заключение
Конечно, весь этот WEB-интерфейс задумывался не только для установки одной антенны. Там было достаточно много другого функционала (прошивка, отладка, добавление коэффициентов), и благодаря этому научился хоть немного программированию на js (хоть понюхал, что это такое). В результате теперь для настройки оборудования нужен только кроссовый кабель и ноутбук. Подключаешь и работаешь в веб-интерфейсе как на обычном роутере. Так же, данный веб-интерфейс доступен по сети, и каждый объект можно отдельно конфигурировать через него, что стало весьма удобно даже людям, далёким от программирования.
Ну и напоследок видео реальных данных с устройства и то, как удобно пользоваться данными графиками.
Ссылки
- Репозиторий проекта github.com/dlinyj/realtime_graph_on_js
- Фреймворк для построения графиков www.chartjs.org
- Фреймворк для парсинга CSV www.papaparse.com
Комментарии 9
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.