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

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

Автор Тема: Вопросы по скриптам в Simple-Scada 2  (Прочитано 314383 раз)

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2997
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #225 : 13 Марта 2017, 21:53:02 »
Можно оба пункта решить одним секундным скриптом. Допустим переменные тегов называются соответственно Tag1, Tag2 ... Tag32.
Тогда скрипт будет таким:
Код: (delphi)
var
  aGoodCount, aBadCount: Byte;
  a61447, a61493: Byte;

  procedure Check(AQuality: Boolean; var ATag: TM_Variable);
  begin
    { если нужно проверять качество }
    if AQuality = TRUE then
      if ATag.IsGoodQuality then
        Inc(aGoodCount)
      else
        Inc(aBadCount);

    { если нужно проверять значение }
    if AQuality = FALSE then
      if ATag.AsInt = 61447 then
        Inc(a61447)
      else
        if ATag.AsInt = 61493 then
          Inc(a61493);
  end;

  { проверяет восемь тегов на качество (при AQuality = TRUE)
    или на значение (при AQuality = FALSE) }
  procedure GoodOrBad(AQuality: Boolean; var T1, T2, T3, T4, T5, T6, T7, T8: TM_Variable);
  begin
    aGoodCount := 0;
    aBadCount := 0;
    a61447 := 0;
    a61493 := 0;
   
    Check(AQuality, T1);
    Check(AQuality, T2);
    Check(AQuality, T3);
    Check(AQuality, T4);
    Check(AQuality, T5);
    Check(AQuality, T6);
    Check(AQuality, T7);
    Check(AQuality, T8);
  end;

begin
  { проверяем качество 8 тегов первого устройства }
  GoodOrBad(TRUE, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7, Tag8);

  { если все 8 тегов с плохим качеством }
  if aBadCount = 8 then
    AddMessage(Now, mkAlarm, 'Устройство 1. Нет связи!', TRUE, TRUE);

  { если все 8 тегов с хорошим качеством }
  if aGoodCount = 8 then
  begin
    { проверяем значение тегов 17..24 }
    GoodOrBad(FALSE, Tag17, Tag18, Tag19, Tag20, Tag21, Tag22, Tag23, Tag24);

    if a61447 = 8 then  // все равны 61447
      AddMessage(Now, mkAlarm, 'Устройство 1. Датчик отключен!', TRUE, TRUE);

    if a61493 = 8 then  // все равны 61493
      AddMessage(Now, mkAlarm, 'Устройство 1. Обрыв датчика!', TRUE, TRUE);
  end;


  //////   далее тот же код, но для тегов второго устройства   //////


  { проверяем качество 8 тегов второго устройства }
  GoodOrBad(TRUE, Tag9, Tag10, Tag11, Tag12, Tag13, Tag14, Tag15, Tag16);

  { если все 8 тегов с плохим качеством }
  if aBadCount = 8 then
    AddMessage(Now, mkAlarm, 'Устройство 2. Нет связи!', TRUE, TRUE);

  { если все 8 тегов с хорошим качеством }
  if aGoodCount = 8 then
  begin
    { проверяем значение тегов 25..32 }
    GoodOrBad(FALSE, Tag25, Tag26, Tag27, Tag28, Tag29, Tag30, Tag31, Tag32);

    if a61447 = 8 then  // все равны 61447
      AddMessage(Now, mkAlarm, 'Устройство 2. Датчик отключен!', TRUE, TRUE);

    if a61493 = 8 then  // все равны 61493
      AddMessage(Now, mkAlarm, 'Устройство 2. Обрыв датчика!', TRUE, TRUE);
  end;
end.

Для сокращения кода используется две подпроцедуры:
  • Check: проверяет качество переменной (если параметр AQuality = TRUE) или значение (если AQuality = FALSE). Если тег с плохим качеством, то увеличивается счетчик aBadCount, если с хорошим, то увеличивается счетчик aGoodCount. Если идет проверка на значение, то увеличиваются счетчики a61447 и a61493 соответственно;
  • GoodOrBad: обнуляет счетчики, получает восемь тегов и передаёт их для проверки качества, либо для проверки значений.
« Изменён: 22 Июня 2018, 11:28:20 от Simple-Scada »

AutoCY

  • Пользователь
  • **
  • Сообщений: 92
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #226 : 14 Марта 2017, 14:25:27 »
    Здравствуйте! Помогите разобраться.

1. Задача: если переменная var1 (byte) принимает значение больше нуля, то переменная var2 (byte) (вентилятор) принимает значение 16.
var1 - Field1, var2 - Image1.

Код
Код:
begin
if Field1.AsInt > 0 then
    Image1.AnimSpeed := 16
  else
    Image1.AnimSpeed := 0;
end. 
       
При изменении значения Field1 - ничего не происходит.

Анимация начинает срабатывать только в таком случае, при var1 - Field1, Image1:

Код
begin
if Image1.AsInt > 0 then
    Image1.AnimSpeed := 16
  else
    Image1.AnimSpeed := 0;
end.

2.   Задача: написать скрипт таймера наработки оборудования с функциями ПУСК, СТОП и ПАУЗА, работающего от системного времени.   
Как будет выглядеть код?

Спасибо.
     
« Изменён: 14 Марта 2017, 15:00:54 от Simple_Scada »

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1165
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #227 : 14 Марта 2017, 15:16:42 »
Здравствуйте!

Вы этот код:

Код
begin
if Field1.AsInt > 0 then
    Image1.AnimSpeed := 16
  else
    Image1.AnimSpeed := 0;
end.

написали для события OnDataChange Изображения? Если да, то скрипт не будет работать, так как для изображения он будет выполняться только при изменении переменной связанной с изображением - "var2".

Цитировать
Анимация начинает срабатывать только в таком случае, при var1 - Field1, Image1

Все верно. Если Вам нужно, чтобы запускалась/останавливалась анимация изображения при изменении переменной "var1", то ее нужно связать и с полем и с изображением и не нужно использовать две переменных.

Цитировать
Задача: написать скрипт таймера наработки оборудования с функциями ПУСК, СТОП и ПАУЗА, работающего от системного времени.   
Как будет выглядеть код?

Пример таймера наработки с функциями ПУСК, СТОП и ПАУЗА Вы можете найти в демо-проекте: Страница "Скрипты" -> подстраница "Простые скрипты(1)" -> пример №8 "Пример секундомера".

Guchi

  • Новичок
  • *
  • Сообщений: 5
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #228 : 15 Марта 2017, 08:44:44 »
Код
begin
  {  обрабатываем первый таймер }
 
  if Tag11.IsGoodQuality = False then
  if Tag12.IsGoodQuality = False then
  if Tag13.IsGoodQuality = False then
  if Tag14.IsGoodQuality = False then
  if Tag15.IsGoodQuality = False then
  if Tag16.IsGoodQuality = False then
  if Tag17.IsGoodQuality = False then
  if Tag18.IsGoodQuality = False then

  begin
    vrTimer_1.Value := vrTimer_1.Value + 1;
    begin
    if vrTimer_1.AsInt = 1 then
      AddMessage(Now, mkMessage, 'Отсутсвует связь. Устройство 1!', TRUE, FALSE);
    if vrTimer_1.AsInt = 60 then
      AddMessage(Now, mkWarning, 'Отсутсвует связь. Устройство 1!', TRUE, FALSE);
    if vrTimer_1.AsInt = 180 then
      AddMessage(Now, mkAlarm, 'Нет связи. Устройство 1 !', TRUE, TRUE);
      end;
   end else
    vrTimer_1.Value := 0;




  {  обрабатываем второй таймер }
 
  if Tag21.IsGoodQuality = False then
  if Tag22.IsGoodQuality = False then
  if Tag23.IsGoodQuality = False then
  if Tag24.IsGoodQuality = False then
  if Tag25.IsGoodQuality = False then
  if Tag26.IsGoodQuality = False then
  if Tag27.IsGoodQuality = False then
  if Tag28.IsGoodQuality = False then
  begin
    vrTimer_2.Value := vrTimer_2.Value + 1;
    begin
    if vrTimer_2.AsInt = 1 then
      AddMessage(Now, mkMessage, 'Отсутсвует связь. Устройство 2!', TRUE, FALSE);
    if vrTimer_2.AsInt = 60 then
      AddMessage(Now, mkWarning, 'Отсутсвует связь. Устройство 2!', TRUE, FALSE);
    if vrTimer_2.AsInt = 180 then
      AddMessage(Now, mkAlarm, 'Нет связи. Устройство 2 !', TRUE, TRUE);
    end;
  end else
    vrTimer_2.Value := 0
end.

секундный скрипт проверяет 8 переменных на качество и если все 8 плохого качества то по таймеру выдает сообщение...скрипт мой (выстраданный с Вашей помощью...за что я Вам очень благодарен) вроде бы  работает...как его можно упростить ? потому как переменных может быть и не 8 8))) возможно применить процедуру Check...
Идет просто проверка на связь с Устройством...по всем переменным...возможно и по одному (любому)

Код
var
  aGoodCount, aBadCount: Byte;
  a61447, a61493: Byte;

  procedure Check(AQuality: Boolean; var ATag: TM_Variable);
  begin
    { если нужно проверять качество }
    if AQuality = TRUE then
      if ATag.IsGoodQuality then
        Inc(aGoodCount)
      else
        Inc(aBadCount);

    { если нужно проверять значение }
    if AQuality = FALSE then
      if ATag.AsInt = 61447 then
        Inc(a61447)
      else
        if ATag.AsInt = 61493 then
          Inc(a61493);
  end;

  { проверяет восемь тегов на качество (при AQuality = TRUE)
    или на значение (при AQuality = FALSE) }
  procedure GoodOrBad(AQuality: Boolean; var T1, T2, T3, T4, T5, T6, T7, T8: TM_Variable);
  begin
    aGoodCount := 0;
    aBadCount := 0;
    a61447 := 0;
    a61493 := 0;
   
    Check(AQuality, T1);
    Check(AQuality, T2);
    Check(AQuality, T3);
    Check(AQuality, T4);
    Check(AQuality, T5);
    Check(AQuality, T6);
    Check(AQuality, T7);
    Check(AQuality, T8);
  end;

begin
  { проверяем качество 8 тегов первого устройства }
  GoodOrBad(TRUE, Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7, Tag8);

  { если все 8 тегов с плохим качеством }
  if aBadCount = 8 then
    AddMessage(Now, mkAlarm, 'Устройство 1. Нет связи!', TRUE, TRUE);

  { если все 8 тегов с хорошим качеством }
  if aGoodCount = 8 then
  begin
    { проверяем значение тегов 17..24 }
    GoodOrBad(FALSE, Tag17, Tag18, Tag19, Tag20, Tag21, Tag22, Tag23, Tag24);

    if a61447 = 8 then  // все равны 61447
      AddMessage(Now, mkAlarm, 'Устройство 1. Датчик отключен!', TRUE, TRUE);

    if a61493 = 8 then  // все равны 61493
      AddMessage(Now, mkAlarm, 'Устройство 1. Обрыв датчика!', TRUE, TRUE);
  end;


  //////   далее тот же код, но для тегов второго устройства   //////


  { проверяем качество 8 тегов второго устройства }
  GoodOrBad(TRUE, Tag9, Tag10, Tag11, Tag12, Tag13, Tag14, Tag15, Tag16);

  { если все 8 тегов с плохим качеством }
  if aBadCount = 8 then
    AddMessage(Now, mkAlarm, 'Устройство 2. Нет связи!', TRUE, TRUE);

  { если все 8 тегов с хорошим качеством }
  if aGoodCount = 8 then
  begin
    { проверяем значение тегов 25..32 }
    GoodOrBad(FALSE, Tag25, Tag26, Tag27, Tag28, Tag29, Tag30, Tag31, Tag32);

    if a61447 = 8 then  // все равны 61447
      AddMessage(Now, mkAlarm, 'Устройство 2. Датчик отключен!', TRUE, TRUE);

    if a61493 = 8 then  // все равны 61493
      AddMessage(Now, mkAlarm, 'Устройство 2. Обрыв датчика!', TRUE, TRUE);
  end;
end.
вышеописанный скрипт с Check процедурой выдавал каждую секунду что "Нет связи с Устройством 1", "Нет связи с Устройством 2".
Насчет проверки по значению- эту часть скрипта можно убрать...только по качеству
« Изменён: 15 Марта 2017, 09:19:03 от Guchi »

AutoCY

  • Пользователь
  • **
  • Сообщений: 92
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #229 : 15 Марта 2017, 11:55:55 »
Цитировать
Пример таймера наработки с функциями ПУСК, СТОП и ПАУЗА Вы можете найти в демо-проекте: Страница "Скрипты" -> подстраница "Простые скрипты(1)" -> пример №8 "Пример секундомера".

Попробовал повторить таймер представленный в demo в своем проекте - пока ничего не получается.
Последовательность действий следующая:
1. Создал виртуальные переменные:
vrTimerState (состояние таймера), тип Byte;
vrIntervalInSec (интервал в сек), тип Int64, шкала - время;
vrTime (хранение отмеренного времени), тип DataTime, шкала - время.
2. Создал кнопку ПУСК. Присвоил переменную - vrTimerState. В событиях OnClick установил скрипт:
Код
begin
      if vrTimerState.AsInt = 0 then
         vrTime.Value := IncSecond(Now, -vrIntervalInSec.AsInt)
      else
         vrIntervalInSec.Value := SecondsBetween(Now, vrTime.Value);
end.

3. Создал кнопку СТОП. В событиях OnClick установил скрипт:
Код
begin
  vrTimerState.Value := 0;
  vrIntervalInSec.Value := 0;
  txtTimer.Text := '0 дней 00:00:00';
end.
4. Создал тект. В свойствах текста указал - 0 дней 00:00:00
5. Написал скрипт
Код
begin
  { Код для таймера. Если таймер запущен выводим накопленное время }
     if vrTimerState.AsInt = 1 then
        txtTimer.Text := IntToStr(DaysBetween(Now, vrTime.Value))  + ' дней ' + TimeToStr(Now -       vrTime.Value);
end.   
   
Подскажите, пожалуйста, где я что не учел?
« Изменён: 15 Марта 2017, 13:07:42 от AutoCY »

Teodor

  • Старожил
  • ****
  • Сообщений: 256
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #230 : 15 Марта 2017, 12:11:53 »
5. Написал срипт
А когда этот скрипт и чем вызывается?

AutoCY

  • Пользователь
  • **
  • Сообщений: 92
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #231 : 15 Марта 2017, 13:06:53 »
5. Написал скрипт
А когда этот скрипт и чем вызывается?
Да я ввел этот скрипт, в надежде, что он как-то выведет информацию о текущем времени, но к чему его "прикрутить" не знаю  ???
« Изменён: 15 Марта 2017, 13:16:31 от AutoCY »

Teodor

  • Старожил
  • ****
  • Сообщений: 256
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #232 : 15 Марта 2017, 13:16:47 »
Да я ввел этот скрипт, в надежде, что он как-то выведет информацию о текущем времени, но к чему его "прикрутить" незнаю  ???
Например сделать его секундным, или часовым, или по событию (по кнопке). Я ж не знаю как вам надо :)
Но если скрипт не вызывать, он точно не исполнится.
« Изменён: 15 Марта 2017, 13:27:54 от Teodor »

AutoCY

  • Пользователь
  • **
  • Сообщений: 92
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #233 : 15 Марта 2017, 13:59:14 »
Цитировать
Например сделать его секундным, или часовым, или по событию (по кнопке). Я ж не знаю как вам надо :) Но если скрипт не вызывать, он точно не исполнится.

При условии, когда две переменных становятся больше нуля, включается таймер, если в процессе условие не соблюдается - таймер переходит в режим ПАУЗЫ.

В общем, поставил скрипт пятого пункта на кнопку ПУСК. Теперь таймер отображает значения, но пока обновляет данные только при условии нажатия кнопки.
« Изменён: 15 Марта 2017, 14:01:20 от AutoCY »

AutoCY

  • Пользователь
  • **
  • Сообщений: 92
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #234 : 15 Марта 2017, 14:27:18 »
Цитировать
Например сделать его секундным, или часовым, или по событию (по кнопке). Я ж не знаю как вам надо :) Но если скрипт не вызывать, он точно не исполнится.

Получилось. При создании скрипта выбрал событие: прошла секунда.

AutoCY

  • Пользователь
  • **
  • Сообщений: 92
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #235 : 15 Марта 2017, 16:27:13 »

Цитировать
При условии, когда две переменных становятся больше нуля, включается таймер, если в процессе условие не соблюдается - таймер переходит в режим ПАУЗЫ.

На строке  else программа не хочет компилироваться.

Код
begin
      if vr_4.Value >  0 and vr_5.Value > 0  then
      begin
         { если выполнено условие, то включается таймер }
         vrIntervalInSec_2.Value := SecondsBetween(Now, vrTime_2.Value);
         { При включении таймера выводим накопленное время }
         txtTimer_2.Text := IntToStr(DaysBetween(Now, vrTime_2.Value))  + ' дней ' + TimeToStr(Now - vrTime_2.Value);
      end;
      else
         { если таймер ещё не включен }
         vrTime_2.Value := IncSecond(Now, -vrIntervalInSec_2.AsInt);
  end.
           

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2997
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #236 : 15 Марта 2017, 16:28:51 »
AutoCY, лишняя точка с запятой после end, должно быть:

Код
...
      txtTimer_2.Text := IntToStr(DaysBetween(Now, vrTime_2.Value))  + ' дней ' + TimeToStr(Now - vrTime_2.Value);
    end else
      { если таймер ещё не включен }
...

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2997
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #237 : 15 Марта 2017, 17:10:42 »
Цитировать
вышеописанный скрипт с Check процедурой выдавал каждую секунду что "Нет связи с Устройством 1", "Нет связи с Устройством 2".
Насчет проверки по значению- эту часть скрипта можно убрать...только по качеству
Да, забыли учесть таймеры. Если добавить таймер и убрать проверку на значение, то скрипт будет таким:

Код
var
  aGoodCount, aBadCount: Byte;

  procedure Check(var ATag: TM_Variable);
  begin
    if ATag.IsGoodQuality then
      Inc(aGoodCount)
    else
      Inc(aBadCount);
  end;

  procedure GoodOrBad(var T1, T2, T3, T4, T5, T6, T7, T8: TM_Variable);
  begin
    aGoodCount := 0;
    aBadCount := 0;
   
    Check(T1);  Check(T2);
    Check(T3);  Check(T4);
    Check(T5);  Check(T6);
    Check(T7);  Check(T8);
  end;

begin
  { проверяем качество 8 тегов первого устройства }
  GoodOrBad(Tag1, Tag2, Tag3, Tag4, Tag5, Tag6, Tag7, Tag8);

  { если все 8 тегов с плохим качеством }
  if aBadCount = 8 then
  begin
    vrTimer_1.Value := vrTimer_1.Value + 1;
    case vrTimer_1.AsInt of
        1: AddMessage(Now, mkMessage, 'Отсутствует связь. Устройство 1!', TRUE, FALSE);
       60: AddMessage(Now, mkWarning, 'Отсутствует связь. Устройство 1!', TRUE, FALSE);
      180: AddMessage(Now, mkAlarm, 'Нет связи. Устройство 1!', TRUE, TRUE);
    end;
  end else
    vrTimer_1.Value := 0;


  //////   далее тот же код, но для тегов второго устройства   //////

  { проверяем качество 8 тегов второго устройства }
  GoodOrBad(Tag9, Tag10, Tag11, Tag12, Tag13, Tag14, Tag15, Tag16);

  { если все 8 тегов с плохим качеством }
  if aBadCount = 8 then
  begin
    vrTimer_2.Value := vrTimer_2.Value + 1;
    case vrTimer_2.AsInt of
        1: AddMessage(Now, mkMessage, 'Отсутствует связь. Устройство 2!', TRUE, FALSE);
       60: AddMessage(Now, mkWarning, 'Отсутствует связь. Устройство 2!', TRUE, FALSE);
      180: AddMessage(Now, mkAlarm, 'Нет связи. Устройство 2!', TRUE, TRUE);
    end;
  end else
    vrTimer_2.Value := 0;
end.

pan-nn

  • Новичок
  • *
  • Сообщений: 30
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #238 : 15 Марта 2017, 19:03:14 »
Новый затык со скриптами.
Как из переменной TDateTime вытащить только время?   Нужно сравнивать две переменных только  с учетом времени.
В Делфи есть AsTime и TimeToStr, а как тут сделать?

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2997
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #239 : 15 Марта 2017, 20:13:08 »
Цитировать
В Делфи есть AsTime и TimeToStr, а как тут сделать?
Можно так же как в Delphi перевести в строку только время используя TimeToStr и затем сделать сравнение строк. TimeToStr вытащит из TDateTime только время, без даты. Например:

Код
var
  dt1, dt2: TDateTime;
  Time1, Time2: string;
begin
  dt1 := Now;
  dt2 := Now;

  Time1 := TimeToStr(dt1);
  Time2 := TimeToStr(dt2);

  if Time1 = Time2 then
  begin
    // время в dt1 равно времени dt2!
  end;
end.

Этот способ работает. Но так так TimeToStr зависит от формата времени, то правильнее сравнивать время извлекая часы, минуты и секунды. Вот так:

Код
var
  dt1, dt2: TDateTime;
begin
  dt1 := Now;
  dt2 := Now;

  { если часы, минуты и секунды у dt1 и dt2 равны }
  if (HourOf(dt1) = HourOf(dt2)) and
     (MinuteOf(dt1) = MinuteOf(dt2)) and
     (SecondOf(dt1) = SecondOf(dt2)) then
  begin
    // время в dt1 равно времени dt2!
  end;
end.