Simple-Scada forum

Simple-Scada 2 => Ваши вопросы => Тема начата: hojidor от 19 Июля 2023, 13:25:48

Название: Таймер изменения переменной
Отправлено: hojidor от 19 Июля 2023, 13:25:48
Добрый день.
Есть переменная Count, получаемая по OPC UA со счетчика.
Необходимо по изменению данной переменной выводить значение времени, когда она изменилась (т.е. время за которое изменилось значение переменной).
К примеру:
1) Значение переменной Cout изменилось через 3 секунды. Значит вывести показание как 3 сек.
2) Значение переменной Cout изменилось через 500 мс. Значит вывести показание как 500 мсек.
Как можно реализовать?

Создал переменную Count_Last, которая сохраняет значение до изменения (старое значение). Скрипт по событию "Изменились переменные" (изменение переменной Count)
Необходимо вывести время, которое прошло при изменении переменной с Count_Last до Count.
Название: Re: Таймер изменения переменной
Отправлено: Simple Scada от 19 Июля 2023, 16:58:45
Здравствуйте.

В данном случае можно создать внутреннюю переменную (https://simple-scada.com/help/manual/variable-new.html) с типом данных DateTime и в свойство "Начальное значение" указать "Now" –  для хранения времени последнего изменения переменной (например с именем "vrPrevTime"). Далее разместить на мнемосхеме компонент "Текст (https://simple-scada.com/help/manual/text.html)", в свойство "Переменная" указать переменную "Count", в свойство "Доп. переменная" указать переменную "vrPrevTime" и на событие "OnDataChange" (https://simple-scada.com/help/script/object-events.html) объекта Текст написать скрипт:
Код: (delphi)
var
  aSec : Integer;
begin
  if Sender is TM_Text then   // проверяем, что Sender это текст
    with Sender as TM_Text do // приводим Sender к типу "TM_Text"
      begin
        // получить кол-во секунд с последнего изменения переменной
        aSec := SecondsBetween(now, VariableEx.AsDateTime);

        if aSec > 0 then                   // если прошло более 1 секунды
          Text := IntToStr(aSec) + ' сек'  // то вывести время в секундах
        else                               // иначе в миллисекундах
          Text := IntToStr(MilliSecondsBetween(now, VariableEx.AsDateTime)) + ' мсек';
        VariableEx.Value := Now;
      end;
end.
Теперь при изменении значения переменной в компонент "Текст" будет выводиться время, за которое изменилось значение переменной. Данный скрипт универсальный (https://simple-scada.com/help/script/universal-event.html) и его можно назначить на событие "OnDataChange" (https://simple-scada.com/help/script/object-events.html) любых объектов "Текст", в которые требуется выводить время за которое изменилось значение переменной. При этом следует учитывать, что первое показание времени после запуска/перезапуска проекта будет неправильным – в этом случае будет отображаться время с момента запуска проекта до первого считывания значения переменной с OPC-сервера.
Название: Re: Таймер изменения переменной
Отправлено: Azat от 15 Апреля 2024, 11:25:09
Добрый день
Можно ли сюда сделать и вывод предыдущего значения переменной в отдельное поле (переменную)? если это не счетчик, например, а данные с датчика температуры, тогда я могу посмотреть сколько секунд назад было изменение и сравнив текущее значение с предыдущим и могу понять идет нагрев или охлаждение
Название: Re: Таймер изменения переменной
Отправлено: Simple Scada от 15 Апреля 2024, 17:30:23
Здравствуйте.

Получить предыдущее значение переменной можно только в скриптах с типами событий "Изменились переменны (https://simple-scada.com/help/script/changed-the-variables.html)е" и "Нарушена граница (https://simple-scada.com/help/script/borderviol.html)". См. функции PrevAsBool (https://simple-scada.com/help/script/prevasbool.html), PrevAsInt (https://simple-scada.com/help/script/prevasint.html), PrevAsFloat (https://simple-scada.com/help/script/prevasfloat.html), PrevAsStr (https://simple-scada.com/help/script/prevasstr.html).

Подобные вычисления лучше реализовать на контроллере. Для решения Вашей задачи в скада-системе можно создать отдельные внутренние переменные для всех переменных, по которым необходимо получать предыдущее значение. Имена внутренних переменных должны содержать: имя текущей переменной (например "vrMyVar1", "vrMyVar2" и тд.) + приставка (например "_Prev") =  "vrMyVar1_Prev", "vrMyVar2_Prev" и тд. Далее нужно создать скрипт с типом события "Изменились переменные (https://simple-scada.com/help/script/changed-the-variables.html)", в список скрипта указать все переменных, для которых необходимо получать предыдущее значение, и написать скрипт:
Код: (delphi)
var
  aVar: TM_Variable;
begin
  aVar := GetVariableByName(Variable.Name + '_Prev');  // ищем переменную, в которую нужно записать предыдущее значение
  if aVar <> nil then                                  // если переменная существует
    aVar.Value := PrevAsFloat;                         // записываем предыдущее значение переменной
end.
Теперь внутренние переменные "vrMyVar1_Prev", "vrMyVar2_Prev" и тд. можно вывести в поля на мнемосхему проекта.
Название: Re: Таймер изменения переменной
Отправлено: Azat от 16 Апреля 2024, 06:44:53
отлично спасибо
сделал два треугольника красный (Image16) и синий (Image15) и они соответственно появляются при повышении и понижении темературы
сделал разными скриптами, мне так проще чтобы не запутаться
Код: (delphi)
begin
  if d3_Prev.Value = 0 then Image16.Visible  := False else  // d3 - датчик температуры, d3_Prev - предыдущее значение
    begin
      if Image16.Value > 0 then Image16.Visible  := True else Image16.Visible  := False;   // красный треугольник вверх (мигающий)
    end;
end.
Код: (delphi)
begin
  if d3_Prev.Value = 0 then Image15.Visible  := False else  // d3 - датчик температуры, d3_Prev - предыдущее значение
    begin
      if Image15.Value < 0 then Image15.Visible  := True else Image15.Visible  := False;   // синий треугольник вниз (мигающий)
    end;
end.