Пожалуйста, включите JavaScript для просмотра этого сайта.

Скрипты Simple-Scada

Допустим в проекте имеются переменные, которые хранят нарастающее значение объема воды, показаний электроэнергии, веса или какой-либо другой нарастающей величины. Иногда на основе таких переменных требуется произвести расчет объема за сутки, час, минуту и т.д. Рассмотрим решение данной задачи на примере расчета объема воды за сутки.

Важно! Следует учитывать, что во время перезапусков сервера Simple-Scada(или когда проект остановлен) архивация не ведется, следовательно архивных данных за этот момент времени не будет. Поэтому, все расчеты приведенные ниже будут корректны только если проект будет работать стабильно и без перерывов. Если не нужна зависимость от работы скада-системы и ПК, то нужно производить подобные расчеты в программе контроллера.

Расчет объема за сутки:

Для решения задачи необходимо:

1.Включить архивацию "по-изменению" у переменной, на основе которой необходимо производить расчеты. В нашем случае это будет переменная расхода с именем "vrFlow";

2.Создать две отдельные внутренние переменные с тем же типом данных, что и у переменной "vrFlow". В них будут записываться архивные значения переменной vrFlow на начало и конец интервала расчета. Назовем их vrNowFlow и vrOldFlow;

3.Для извлечения значений из архива можно использовать процедуру ArchiveValueByTime;

4.Создать скрипт с типом события "Начало часа" и получить в нем архивные значения на начало и конец интервала расчета. Для этого используем такой код:

var
  aDate: TDateTime;
begin
  // если сейчас 00 часов, то запускаем вычисление расхода за последние сутки
  if HourOf(Now) = 0 then 
  begin
    aDate := RecodeTime(Now, 0000);  // текущее время/дата
    
    // добавляем все последующие вызовы архивных процедур в группу с тегом = 1 
    ArchiveGroupBegin(1);                     
    
    // извлечь из архива значение переменной "vrFlow" в отметке
    // времени "aDate" и записать результат в переменную "vrNowFlow" 
    ArchiveValueByTime(vrFlow, vrNowFlow, aDate);
 
    // извлечь из архива значение переменной "vrFlow" в отметке
    // времени "aDate" и записать результат в переменную "vrOldFlow"
    aDate := IncDay(aDate, -1);            // время/дата день назад
    ArchiveValueByTime(vrFlow, vrOldFlow, aDate);
    
    // заканчиваем группировку архивных процедур
    ArchiveGroupEnd;                                  
  end;
end.

Архивные процедуры не выполняются мгновенно - подробнее см. по ссылке. Поэтому нельзя работать с переменными результата(в нашем случае vrNowFlow и vrOldFlow) в том же скрипте, где вызываются архивные процедуры. Вместо этого необходимо использовать группировку архивных процедур через ArchiveGroupBegin/ArchiveGroupEnd и работать с результатами вычислений в скрипте с типом события "Выполнены архивные процедуры". В скрипте выше, все вызовы архивных процедур между ArchiveGroupBegin и ArchiveGroupEnd будут объединены в группу с заданым тегом (в данном случае = 1).

Созданный нами скрипт будет выполняться раз в сутки, в 00:00. После выполнения данного скрипта в переменную vrNowFlow будет записано значение расхода на время 00:00, а в переменную vrOldFlow значение расхода день назад, на тоже время. Для получения расхода за сутки необходимо вычесть значение vrOldFlow из vrNowFlow. Для этого нужно создать новый скрипт с типом события "Выполнены архивные процедуры" и написать код расчета:

begin
  // если группа архивных процедур с тегом = 1 выполнилась
  if ArcGroupTag = 1 then
  // рассчитываем объем воды за сутки
  vrVolume.Value := vrNowFlow.Value - vrOldFlow.Value;
end.

Задача решена, теперь каждые сутки в 00:00 будет производиться расчет объема воды и результат будет записываться в переменную vrVolume. Чтобы вычисленное значение объема сохранялось при перезапусках проекта, можно у переменной vrVolume включить опцию "Автоматическое восстановление".

 

Расчет объема за час:

Аналогично примеру выше, нужно создать скрипт с типом события "Начало часа" и извлекать в нем архивные значения на начало и конец часа, с применением группировки архивных процедур. Пример кода:

var
  aDate: TDateTime;
begin
  // добавляем все последующие вызовы архивных процедур в группу с тегом = 2 
  ArchiveGroupBegin(2);
 
  aDate := RecodeTime(Now, HourOf(Now), 000);  // текущее время/дата
  // извлечь из архива значение переменной "vrFlow" в отметке
  // времени "aDate" и записать результат в переменную "vrNowHourFlow"
  ArchiveValueByTime(vrFlow, vrNowHourFlow, aDate);
 
  // извлечь из архива значение переменной "vrFlow" в отметке
  // времени "aDate" и записать результат в переменную "vrOldHourFlow"
  aDate := IncHour(aDate, -1);                     // время/дата час назад
  ArchiveValueByTime(vrFlow, vrOldHourFlow, aDate);
  
  // заканчиваем группировку архивных процедур
  ArchiveGroupEnd;
end.

Данный скрипт будет выполняться в начале каждого часа. Расчет объема по переменным vrNowHourFlow и vrOldHourFlow производится аналогично примеру выше - нужно создать новый скрипт с типом события "Выполнены архивные процедуры" и написать код расчета, например:

begin
  // если группа архивных процедур с тегом = 2 выполнилась
  if ArcGroupTag = 2 then
  // рассчитываем объем воды за час
  vrHourVolume.Value := vrNowHourFlow.Value - vrOldHourFlow.Value;
end.

 

Расчет объема за минуту:

Для расчета объема за минуту, нужно создать скрипт с типом события "Таймер" (в параметре скрипта "Интервал" указать значение 60 сек.) и извлекать в нем архивные значения на начало и конец минуты, с применением группировки архивных процедур. Пример кода:

var
  aDate: TDateTime;
begin
  // добавляем все последующие вызовы архивных процедур в группу с тегом = 2 
  ArchiveGroupBegin(3);
 
  aDate := Now;               // текущее время/дата
  // извлечь из архива значение переменной "vrFlow" в отметке 
  // времени "aDate" и записать результат в переменную "vrNowMinuteFlow" }
  ArchiveValueByTime(vrFlow, vrNowMinuteFlow, aDate);
 
  aDate:= IncMinute(Now, -1); // текущее время/дата минуту назад
  // извлечь из архива значение переменной "vrFlow" в отметке 
  // времени "aDate" и записать результат в переменную "vrOldMinuteFlow" }
  ArchiveValueByTime(vrFlow, vrOldMinuteFlow, aDate);
 
  // заканчиваем группировку архивных процедур
  ArchiveGroupEnd;
end.

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

Расчет объема по переменным vrNowMinuteFlow и vrOldMinuteFlow производится аналогично примерам выше - нужно создать новый скрипт с типом события "Выполнены архивные процедуры" и написать код расчета, например:

begin
  // если группа архивных процедур с тегом = 3 выполнилась
  if ArcGroupTag = 3 then
  // рассчитываем объем воды за минуту
  vrMinuteVolume.Value := vrNowMinuteFlow.Value - vrOldMinuteFlow.Value;
end.