Примеры
Для демонстрации работы с платформой создан отдельный проект, пополняемый новыми примерами.
Также в указанном проекте можно создавать новые задачи с запросами на новые примеры.
Здесь рассмотрим самый простой пример.
Простой пример с одним объектом
Для демонстрации работы с объектами, тегами, методами и экранами Grafana сделаем следующий пример.
Допустим, у нас есть лампочка и мы можем тем или иным способом получить данные по току и напряжению (работу с коннекторами рассмотрим в следующих примерах).
Кроме тока и напряжения у лампочки есть третий, расчётный тег - мощность.
При изменении силы тока или напряжения мощность должна перерасчитываться.
1. Объект
Открываем конфигуратор, выбираем папку «Объекты» и нажимаем кнопку «Новый объект»:
В появившемся окне свойств меняем имя объекта на «Лампочка»…
…и, нажав кнопку «Записать», сохраняем изменения:
2. Теги
Оставляя текущим объектом «Лампочку», нажимаем кнопку «Новый тег»:
Меняем имя тега и единицы измерения…
…и, нажав кнопку «Записать», сохраняем изменения:
Аналогичным образом создаём ещё два тега, U и P:
3. Запись/чтение данных
Проверим, что данные в теги записываются и читаются.
Выберем тег «I» и откроем панель «Данные тега»:
В поле «Значение» впишем 0.
В поле «body» можно посмотреть сформированное тело запроса на запись.
Нажимаем кнопку «Записать», затем «Получить данные».
В таблице «Значение-время-качество» появится текущее значение тега «I»:
4. Расчётный метод
Создадим метод для расчёта мощности лампочки.
Для этого выберем тег «P» и нажмём кнопку «Новый метод»:
Затем:
Изменим имя метода
В поле «Адрес» введём название метода, под которым он будет зарегистрирован в системе для вызовов. Запомним это имя -
power
:Блок «Инициаторы». Очень важный блок, в котором мы выбираем, какие события могут инициировать выполнение расчётного метода.
Здесь выберем оба предложенных тега: I и U, то есть изменения обоих этих тегов будут приводить к перерасчёту мощности.
Внимание
Обратите внимание, что в списке возможных инициаторов расчёта нет самого тега «P»: изменение тега не может приводить к перерасчёту его самого, так как это вызовет бесконечный цикл расчётов.
Укажем, какие данные необходимо передать методу для расчёта.
Данные, передаваемые в метод в каждом параметре - это результат запроса
получения данных
.Для расчёта мощности нужны текущие значения двух тегов: силы тока и напряжения. Поэтому создаём два параметра, дважды нажав на синюю кнопку с плюсом. Заполняем данные параметров как показано на картинке:
Здесь мы указали, что в метод передаются два параметра: первым (индекс = 1) - сила тока.
Вторым (индекс = 2) - напряжение.
Поле «Конфигурация» заполняется автоматически после выбора тега в поле «Тег».
Внимание
После изучения документации на запрос
получения данных
можно вручную править поле «Конфигурация», составляя сколь угодно сложные запросы получения данных. Поле «Конфигурация» можно расширять для удобства ввода текста.Внимание
Очень важный момент, относящийся к расчётам значений тегов: тег мощности рассчитывается, когда изменяется значение тегов «I» и «U». Допустим, расчёт инициируется изменением тега «I» и метка времени нового значения «I» - «2024-10-27 10:00:00+03:00». В этом случае запрос данных в параметрах будет производиться также на метку времени «2024-10-27 10:00:00+03:00» и новое рассчитанное значение тега мощности также будет записано с этой меткой времени, не смотря на то, что сам расчёт, возможно, будет производиться в другое время.
Нажимаем кнопку «Записать» для сохранения изменений:
Теперь напишем код метода.
В папке methods
проекта https://github.com/Vovaman/peresvet уже написан метод для этого примера.
Откроем файл methods/test_method.py
и рассмотрим метод calc_power
:
@rpc("power")
async def calc_power(I: dict, U: dict) -> float:
"""Метод возвращает произведение двух параметров.
"""
print(f"I: {json.dumps(I, indent=4)}")
print(f"U: {json.dumps(U, indent=4)}")
cur_I = I["data"][0]["data"][0][0]
cur_U = U["data"][0]["data"][0][0]
if cur_I == None or cur_U == None:
return 0
return cur_I * cur_U
Внимание
Первая строка: @rpc("power")
: именно «power» мы вводили в поле
«Адрес» при создании метода!
Далее - строка объявления метода: async def calc_power(I: dict, U: dict) -> float:
.
Первым параметром указана сила тока, вторым - напряжение. Точно так же, как мы указывали
индексы у параметров.
Далее метод просто для удобства выводит в консоль пришедшие данные, затем рассчитывает мощность как произведение двух параметров.
5. Запуск расчётного метода
Для запуска метода необходимо установить пакеты, указанные в файле methods/requirements.txt
либо
для всех пользователей:
$ pip3 install -r requirements.txt
Либо создав виртуальную среду проекта.
После установки пакетов запускаем в терминале скрипт в папке methods
:
$ python3 test_method.py
Результат должен быть примерно таким:
6. Проверим расчёт
Помним, что расчёт мощности инициируется изменениями значений тока и напряжения.
Запишем в тег «U» значение 230.
Для этого выберем в иерархии тег «U» и запишем в него требуемое значение:
В консоли, в которой мы запустили метод, появится вывод:
Проверим значение тега мощности «P». Оно должно быть равно 0, так как перед этим в тег «I» мы записали 0:
Теперь запишем в тег «I» значение 1:
И проверим значение мощности, которое должно быть равно 230 Вт:
Примечание
В следующих примерах будет показано, как настроить получение данных в теги из внешних источников.
7. Отображение данных в Grafana
Примечание
Данные из платформы можно получать
описанным в документации запросом
.
Данные тегов (как, впрочем, и всё общение с платформой) приходят в виде json и для манипулирования этими данными в Grafan’е рекомендуется изучить языки манипулирования json-данными JSONata или JSONPath.
Предпочтительнее JSONata, так как обладает большими возможностями.
Настроим отображение:
текущих значений тегов «I», «U» и «P»;
трендов значений этих тегов;
Создадим новую доску данных.
Для этого заходим в меню «Home –> Dashboards» и нажимаем кнопку «New»
Выбрав в выпадающем меню команду «New dashboard», попадаем на экран создания новой панели:
…и выбираем источник данных «peresvet»:
В появившемся окне настройки панели выберем тип панели «Stat».
Настроим путь для получения данных, вписав
/data/
на закладкеPath
.Примечание
По умолчанию в источнике данных «peresvet» настроен путь к платформе:
http://<server>/v1/
. Добавляя к этому пути расширенияdata
,objects
,tags
и т.д., мы получаем возможность работать не только с данными, но и вообще со всеми сущностями платформы.Настроим запросы получения данных.
Для того, чтобы не писать запрос вручную, его можно скопировать из конфигуратора.
Открываем конфигуратор, выбираем тег «I» и копируем запрос получения текущего значения тега.
В окне настройки панели выбираем закладку «Params» и добавляем новый ключ «q». Значение ключа - скопированный нами запрос:
Окончательная настройка панели.
После настройки данных значения напряжения и мощности отображаются красным цветом. Так выставлены настройки по умолчанию.
Чтобы все значения отражались зелёным цветом, уберём порог значения «80»;
Переименуем панель и нажмем кнопку «Save»:
Появится окно, в котором нужно задать имя доски данных.
Предупреждение
Чтобы на панели рядом с именем тега не отображался 0, введите в поля
Alias
пробел:Выровняем новую панель на экране и создадим новую панель, с трендом, для чего выберем команду «Add –> Visualization»:
Настройка панели с трендом.
Тип панели оставим по умолчанию - «Time series».
Получение данных настроим похоже предыдущей панели, за исключением того, что ключ запроса «q» будет включать функции Grafan’ы
$__isoFrom()
и$__isoTo()
, обозначающие начало и конец запрашиваемого временного периода:q={"tagId":"2d95d0a6-28c7-103f-9c49-d763ac5895e8","format":true,"start":"$__isoFrom()","finish":"$__isoTo()"}
.Закладки «Fields» у всех трёх запросов должны быть такого вида:
Выбор временных периодов.
Настроив панель с трендом для отображения трёх тегов, приведём доску данных приблизительно к такому виду и выберем диапазон времени для отображения на экране, а также периодичность обновления данных:
Проверим работу модели. Для чего записываем новые значения в теги «I» и «U» и наблюдаем изменение данных на панели с электрическими параметрами: