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

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

Автор Тема: Как создать внутреннюю (виртуальную) переменную, зависящую от переменных из ОРС  (Прочитано 8755 раз)

asnik

  • Новичок
  • *
  • Сообщений: 12
    • Просмотр профиля
Получаю например несколько переменных (аварий) из ОРС сервера, из них мне нужно сформировать обобщенную переменную (аварию) во внутренних переменных. Вроде того, что пока есть хотя бы одна авария, будет взведена общая авария объекта

kknm

  • Новичок
  • *
  • Сообщений: 16
    • Просмотр профиля
Я думаю, что по OnDataChange проверять выходы из границ - затем обычный счетчик увеличивать.
Или использовать границы в шкалах переменных, приходящих от датчиков так нагляднее.

Simple_Scada

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

asnik, для решения этой задачи создадим внутреннюю переменную (назовем ее, например Time_Count) с типом данных Word. Далее, необходимо создать скрипт с типом события "Прошла секунда" и написать скрипт:

Код
begin
  Time_Count.Value := Time_Count.Value + 1; // увеличиваем счетчик на 1

  if Time_Count.AsInt >= 5 then   // если прошло 5 секунд
    if (MyVar1.AsInt > 99) or (MyVar2.AsInt < 35) or (MyVar3.AsInt = 55) then // если любое из условий выполнилось, то
      Shape1.Color := clRed       // изменить цвет фигуры на красный
    else                          // иначе
      Shape1.Color := clGreen     // изменить цвет фигуры на зеленый
end.

Вместо MyVar1, MyVar2, MyVar3 подставьте свои переменные. В приведенном примере условия будут проверяться раз в пять секунд - можно изменить этот интервал в соответствии с требованиями Вашего проекта.
« Изменён: 28 Сентября 2017, 13:23:29 от Simple-Scada »

asnik

  • Новичок
  • *
  • Сообщений: 12
    • Просмотр профиля
Спасибо за помощь. Пока ждал ответов, городил свой огород. По аварии отдельного механизма, взводилась общая авария объекта, куда входил этот механизм. Вроде получилось, можно ли эту конструкцию упростить:
Код
begin
  SetFlashInterval(fit500ms);  // изменить частоту мигания на 500мс

  if Sender is TM_Object then   // проверяем, что Sender это объект
    with Sender as TM_Object do // приводим Sender к типу "TM_Object"
      if AsInt = 1 then         // если значение переменной объекта равно 1, то
      begin
        obob_avar.value := true;  // обобщенной аварии присвоить 1
        FlashColor := clRed;      // изменить цвет объекта и моргать красным
      end else                    // иначе
        begin
          obob_avar.value := false;
          FlashColor := clNone;    // отменить моргание
        end;
end.
                           
« Изменён: 28 Сентября 2017, 13:22:50 от Simple-Scada »

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1407
    • Просмотр профиля
Если поставить этот скрипт на событие OnDataChange нескольких объектов, то общая авария(obob_avar) будет срабатывать неправильно. Допустим, имеется три переменных А,В,С, по изменению которых будет выполняться Ваш скрипт. Если А и В стали равны 1, то взведется общая переменная аварии(obob_avar). Затем, переменная А становится равна 0, скрипт выполняется и общая переменная аварии сбрасывается, хотя должна остаться взведенной, т.к. переменная В все еще находится в состоянии 1. Но, это не учтется, так скрипт работает по изменению переменных, а переменная В при этом не меняла своего значения. Чем больше объектов будет работать по этому скрипту тем непредсказуемее будет изменяться переменная общей аварии - obob_avar. Для Вашей задачи необходимо использовать скрипт с типом события "Прошла секунда", пример которого мы привели в предыдущем сообщении.

asnik

  • Новичок
  • *
  • Сообщений: 12
    • Просмотр профиля
Да, именно, возникает неопределенность состояния obob_avar. Поэтому в таком виде применять этот скрипт нельзя. Ваш подход правильнее.
Намного проще организовать такую переменную в контроллере, но не всегда есть связь с разработчиками. Поэтому на такой случай должна быть возможность писать логику в скаде. Иногда приходилось  писать скрипты в ОРС сервере.
Не хватает краткого пособия по синтаксису скриптов (делфи).

Teodor

  • Старожил
  • ****
  • Сообщений: 256
    • Просмотр профиля
А если создать 2 переменных (VarAlarm)BOOL и (VarAlarmCode)DWORD(INT64).
На отдельную страниицу вывести поля с основными переменной VarOPCErr_ХХ и дополнительной VarAlarmCode и установить им теги от 0 по 31(63).
На Onchange добавить им всем один скриптик:

 if Sender is TM_Object then 
    with Sender as TM_Object do
        VariableEx.Value := SetBit(VariableEx.Value,Tag,Value);     

if VarAlarmCode.Value>0 then
    VarAlarm.Value = true
else
    VarAlarm.Value = false;

Cуть: в переменную AlarmCode вписываем значение алармов с ОPC в виде битов по адресам указанным в поле Тег. Если есть любая авария, то и глобальную ставим. Заодно в архиве AlarmCode будет хранить все аварии в побитном варианте и не дергаться, пока состояние на входе не меняется.
« Изменён: 04 Октября 2017, 17:26:13 от Teodor »