Три года назад я рассказал, как сделал приставку к импульсным счётчикам воды Ватериус. Устройство считает импульсы счётчиков воды, раз в сутки просыпается и по Wi-Fi шлёт на сервер данные.
Следующим этапом мы запустили сайт — сервис по передаче показаний в управляющие компании. Чтобы компетентно отвечать пользователям, что с их устройствами, была настроена база данных временных рядов InfluxDB и Grafana для рисования графиков.
Сейчас к сайту подключено около 1600 устройств — есть что «помониторить»...
В Grafana 4 дашборда:
мониторинг состояния сервера
мониторинг состояния тестового сервера
графики по устройству
статистика и бизнес метрики
Ниже рассказ, какую информацию об устройствах видит техподдержка сайта и зачем.
Сперва покажу личный кабинет пользователя Ватериуса в стиле «минимализм»:
Можно включить статистику по месяцам
И настроить отправку показаний в разные места:
.
Устройства шлют на сервер гораздо больше данных (подробное описание полей на github).
В первой версии были следующие поля:
количество импульсов;
показания счётчика, кубометры;
разница показаний с предыдущим пробуждением, литры;
причина загрузки attiny85 (значение регистра);
версии прошивок микроконтроллеров attiny и ESP;
количество перезагрузок;
вес импульса в счётчике (1 или 10 литров).
Мы их видели на административной странице Django. Но графики там не нарисуешь, поэтому обратились к Grafana.
Дашборд начинается с показаний двух каналов Ватериуса, уровня сигнала роутера и кол-во перезагрузок. Уровень сигнала полезен, если устройство регулярно теряет связь. Количество перезагрузок указывает на замену батареек или проблемы.
Для выбора устройства в БД служат комбобоксы email и token.
Графики потребления полезны, если настройка отклонилась от инструкции и показания убегают вперёд или отстают.
Администратор видит, что горячая вода потребляется сильно больше, чем холодная и может сделать вывод, что счетчик горячей воды на 1л/имп, а Ватериус решил, что на 10.
Однажды Ватериус за неделю насчитал знакомому 20 кубометров. Я испугался, а когда пришёл чинить, обнаружил, что провода счётчиков не были зафиксированы в разъёме.
В прошивку тут же был добавлен уровень сигнала на входе микроконтроллера (analogRead) в момент замыкания геркона. По нему можно судить о качестве подсоединения Ватериуса к счётчикам. Если значение прыгает — провод не закреплён.
На графике ниже ADC меняется в пределах погрешности измерения 103—104, что говорит о хорошем контакте.
Вот здесь на Горячей воде мы видим плохой контакт провода с Ватериусом:
Позднее я добавил длительность пробуждения wi-fi Ватериуса (waketime), чтобы судить о его взаимоотношениях с роутером. А продолжительность настройки Ватериуса пользователем (setuptime) позволяет узнать, когда и сколько раз он его настраивал.
На дашборде Grafana администратор переключается между устройствами по email пользователя и по уникальному номеру Ватериуса. Если устройств несколько, то они все отобразятся в всплывающем списке.
Чтобы сделать такие комбобоксы, используем переменные дашборда:
Ниже пример графиков, когда что-то нехорошее происходило с устройством. Ватериус очень часто выходил на связь, затем кончились батарейки, через неделю пользователь поставил новые и перепрошил микроконтроллер — количество перезагрузок сбросилось (boot).
В Ватериусе для упрощения конструкции отсутствует вольтметр. Напряжение измеряется в ESP уже после стабилизатора. Во время включения вай-фая происходят скачки. Если начертить их график(voltage_diff), то видно, что они становятся частыми к окончанию жизни батареек. Когда батарейки умрут — мы оповестим по электронной почте (устройство не выходит на связь 5 дней). Любопытно, что при этом Ватериус продолжит считать показания — напряжения хватает для питания attiny, но не хватает для включения вай-фая.
Настройки виджетов Grafana однотипные:
Виджет Stat текущего значения счётчика воды:
SELECT mean("ch0") FROM "infinity"."waterius" WHERE ("email" =~ /^$email$/ AND "token" =~ /^$token$/) AND $timeFilter GROUP BY time($__interval)
Виджет Graph (old) разницы в литрах:
SELECT mean("delta0") FROM "infinity"."waterius" WHERE ("email" =~ /^$email$/ AND "token" =~ /^$token$/) AND $timeFilter GROUP BY time($__interval)
Код на python, который шлёт информацию в Базу данных InfluxDB:
client = InfluxDBClient(host, port,
INFLUXDB_USERNAME, INFLUXDB_PASS,
INFLUXDB_DB, ssl=ssl, verify_ssl=True, timeout=3.0)
def influx_send(data):
try:
point = {
'measurement': 'waterius',
'tags': {},
'fields': {}
}
tags = ['version', 'version_esp', 'email', 'f'] # + key
fields = ['delta0', 'delta1', 'good', 'boot', 'ch0', 'ch1', 'imp0', 'imp1',
'voltage', 'resets', 'voltage_low', 'voltage_diff', 'rssi',
'waketime', 'setuptime', 'adc0', 'adc1']
for name in tags:
if name in data:
point['tags'][name] = data[name]
for name in fields:
if name in data:
point['fields'][name] = data[name]
if 'key' in data:
point['tags']['token'] = data['key'] # influxdb 'key' is a keyword
if not client.write_points([point, ]):
log.error('InfluxDBClient influx_send error')
except Exception:
log.error('InfluxDB data error: ' + traceback.format_exc())
В следующей статье, могу рассказать про визуализацию бизнес-показателей и статистики пользователей.
Если вы знаете, как сделать доступ к дашборду Grafana пользователям, чтобы они видели только свои устройства — напишите, мы попробуем это реализовать.
Спасибо всей команде проекта, пользователям и тем, кто помогает проекту!
Чат проекта в телеграм.