Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?

Официальный форум Simple-Scada.

Автор Тема: Периодический отчёт из своего источника с разбивкой на интервалы  (Прочитано 2431 раз)

Timothy Clement

  • Постоялец
  • ***
  • Сообщений: 149
  • ОАО Борисовский завод "Металлист"
    • Просмотр профиля
    • Полымя
Добрый день!
Стоит задача сделать отчёт из архивных данных таблицы trends_data. Туда пишут показания счётчики, необходимо построить отчёт за период, выбрав показания на начало интервала, на конец интервала и разницу за интервал (расход) в рамках периода. С отчётом из стандартного источника всё понятно, задаём переменные начала, конца и интервала и добавляем архивные теги с нужной выборкой, всё красиво. НО, появилась необходимость сделать отчёт гибко настраиваемый пользователем, в котором заранее неизвестно сколько переменных будет использоваться - может 1, а может 25. И их можно постоянно менять из интерфейса программы. Тут уже стандартный источник не подходит, т.к. даже если задать динамическую адресацию, количество переменных фиксированное и просто будет оставаться куча пустых строк. Создавать десятки отчётов на все возможные варианты тоже не решение, поэтому было решено использовать источник MySQL и запрос:
Код: (sql)
SELECT round(MIN(value),2) AS minVal, round(MAX(value),2) AS maxVal, 
   round(MAX(value),2) - round(MIN(value),2) AS aEnergy    
FROM trends_data
WHERE id IN(
   SELECT idvar FROM areas WHERE idarea = @area
)
&& timestamp BETWEEN @tstart AND @tend
&& quality = 1
GROUP BY id
В запросе получаем значение на начало периода, конец периода и разницу значений. ID переменных получаем вложенным запросом из своей таблицы (в ней то и будет пользователь выбирать нужные ему счётчики). Отчёт строится, например за час, но как сделать отчёт за сутки с разбивкой на заданные интервалы (например час)? Понимаю что нужно вычислить для каждого интервала какое-то общее значение времени в рамках часа например и группировать по нему. Но как реализовать пока непонятно, жду ваших предложений.
« Изменён: 16 Ноября 2021, 08:53:43 от Timothy Clement »

Серега

  • Постоялец
  • ***
  • Сообщений: 209
    • Просмотр профиля
Добрый день!
Может вот это подойдет:
https://simple-scada.com/help/report/timeperiodic.html

Timothy Clement

  • Постоялец
  • ***
  • Сообщений: 149
  • ОАО Борисовский завод "Металлист"
    • Просмотр профиля
    • Полымя
Добрый день!
Может вот это подойдет:
https://simple-scada.com/help/report/timeperiodic.html
Нет, в руководстве ответов не нашел. Задача состоит в том, чтобы воспроизвести Периодический отчёт с помощью sql-запроса, разделив период на заданные интервалы

pan2000

  • Постоялец
  • ***
  • Сообщений: 170
    • Просмотр профиля
   Здравствуйте.

Использование минимума и максимума значений кое-как приемлемо для всего периода. Разделение периода на интервалы приведет к тому, что сумма расходов будет меньше расхода за период, т.к. максимум значения показаний счетчика в предыдущем интервале будет меньше минимума показаний в последующем (для возрастающей последовательности).
Как вариант решения - временная таблица, генерируемая скриптом (скриптами), который повторяет "кухню" построения периодического отчета:
- организация цикла по ID пользовательской таблицы;
- получение архивных значений переменной на границах интервалов;
- запись необходимых данных очередного интервала в таблицу.
При фиксированных значениях границ интервала (например, на начало каждого часа) можно использовать постоянную таблицу, данные в которую добавляются каждый час.

Timothy Clement

  • Постоялец
  • ***
  • Сообщений: 149
  • ОАО Борисовский завод "Металлист"
    • Просмотр профиля
    • Полымя
При фиксированных значениях границ интервала (например, на начало каждого часа) можно использовать постоянную таблицу, данные в которую добавляются каждый час.
В таблице trends_data у меня содержатся и архивные данные записанные из скады, и данные которые я туда пишу скриптами каждые полчаса с фиксированной меткой времени 00, 30 минут.
Я немного модифицировал запрос, чтобы сгруппировать данные по часам - разделил метки времени переведенные в число на 3600 и оставил целую часть. Получились часы, но туда входят данные до 59:59, а следующее значение записано в 00:00 и в нужный интервал не попадает.
Код: (sql)
SELECT round(MIN(value),2) AS minVal, round(MAX(value),2) AS maxVal, 
round(MAX(value),2) - round(MIN(value),2) AS aEnergy,
timestamp,
floor(time_to_sec(timestamp)/3600) as period    
FROM trends_data
WHERE id IN(
  SELECT idvar FROM areas WHERE idarea = @area
)
&& timestamp BETWEEN @tstart AND @tend
&& quality = 1
GROUP BY id, period

В отчете созданном из стандартного источника всё хорошо, с запросом беда  :'(

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2996
    • Просмотр профиля
    • Simple-Scada
Здравствуйте.

Как должен выглядеть отчет для нескольких переменных? Для каждой переменной должны добавляться новые колонки в отчет (т.е. он должен расти горизонтально, чем больше переменных, тем шире)?
Или должен расти вертикально? Т.е. сначала выводим данные для одной переменной, затем итог по ним, затем отступ и то же самое для другой переменной?

Timothy Clement

  • Постоялец
  • ***
  • Сообщений: 149
  • ОАО Борисовский завод "Металлист"
    • Просмотр профиля
    • Полымя
Данные будут расти вертикально, с группировкой всех переменных по интервалу:
Время 00:00 - 01:00
Переменная 1 - первое значение, последнее значение, разница
Переменная 2 - первое значение, последнее значение, разница
...
Переменная n - первое значение, последнее значение, разница
Итог сумма разницы всех переменных за период
Время 01:00 - 02:00  и т.д.

Есть готовый отчёт из стандартного источника, хочу реализовать так же с возможностью изменять переменные и их количество из интерфейса пользователем
« Изменён: 17 Ноября 2021, 15:11:39 от Simple-Scada »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2996
    • Просмотр профиля
    • Simple-Scada
Можно попробовать выполнять несколько выборок и затем объединять их в одну. Вот пример объединения двух простых выборок:
Код: (sql)
(
  select * from `trends_data`
  where (`id`=1) and (`timestamp` = '2021-11-14 12:50:02.325')
) UNION (
  select * from `trends_data`
  where (`id`=1) and (`timestamp` = '2021-11-14 12:50:06.335')
)
Какого-то простого решения для данной задачи мы не видим. Лучше всего было бы решить её используя стандартные источники, но для этой задачи они не предусмотрены и непонятно как можно было бы их улучшить, чтобы они подходили для решения (и при этом оставались простыми в настройке).

Timothy Clement

  • Постоялец
  • ***
  • Сообщений: 149
  • ОАО Борисовский завод "Металлист"
    • Просмотр профиля
    • Полымя
Хорошо, спасибо. Видимо придется оставить возможность формировать такой отчёт только за 1 отрезок - час, день, месяц без выборки периода. Надеюсь пользователей это устроит, на крайний случай сделаю 25-30 вариантов отчётов из стандартного источника с динамическими переменными с фиксированным количеством, и буду формировать нужный :) 

pan2000

  • Постоялец
  • ***
  • Сообщений: 170
    • Просмотр профиля
    Здравствуйте.
 
Отчет с произвольным количеством переменных можно создать с использованием промежуточных таблиц в Simple-Scada уже со статическими данными и последующим использованием их в редакторе отчетов.
Вначале строится таблица отфильтрованная по индексам переменных, качеству и временному периоду отчета. Далее - таблица минимального и максимального значений переменных на интервале. Окончательная фильтрация выполняется при построении отчета.
Во вложении пример такого отчета. Пример позволяет выбрать переменные и период построения отчета. Отчет содержит данные для двух первых часовых интервалов (это пример) и итоговые значения суммарного расхода по переменным. Таблица минимального и максимального значений доступна для просмотра.
И ещё раз об отдельной таблице для хранения значний переменных точно по границам учетных интервалов (например, часов), не положено записывать свои данные в таблицу trends_data:
Записывать какие-либо значения в таблицы скады нельзя - это может привести к нарушению структуры БД, проблемам в отображении трендов, проблемам в работе архивных функций и т.д. Если требуется сохранять какие-либо значения в БД, то для этого нужно создать свою таблицу в БД и работать с ней, например как описано по ссылке.
« Изменён: 14 Мая 2023, 16:58:05 от pan2000 »

Timothy Clement

  • Постоялец
  • ***
  • Сообщений: 149
  • ОАО Борисовский завод "Металлист"
    • Просмотр профиля
    • Полымя

И ещё раз об отдельной таблице для хранения значений переменных точно по границам учетных интервалов (например, часов), не положено записывать свои данные в таблицу trends_data


Добрый день, спасибо за пример. Т.к. максимально до 20 объектов в отчете, я уже сделал 20 разных отчётов с динамическими переменными. Все же выборка первого и последнего значения работает лучше чем MIN и MAX в запросе. И если не нужно будет строить тренды по этим архивным данным или использовать функции работы с архивом, то никаких проблем с записью в таблицу trends_data нет, это тоже озвучивалось администратором на форуме.
« Изменён: 23 Ноября 2021, 11:22:50 от Timothy Clement »

Nikso

  • Новичок
  • *
  • Сообщений: 41
    • Просмотр профиля
Можно покапать в сторону оконных функций