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

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

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

Simple Scada

  • Глобальный модератор
  • *****
  • Сообщений: 233
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1500 : 18 Апреля 2024, 17:46:19 »
Здравствуйте.

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

Код: (delphi)
begin
  if Dicount2.AsInt  = 0 then
    Speedbotle_min.Value := 0
  else
    Speedbotle_min.Value := Dicount2.AsInt - Speedbotle_temp.AsInt;
  Speedbotle_temp.Value := Dicount2.AsInt;
end.
« Изменён: 18 Апреля 2024, 17:49:47 от Simple_Scada »

Lisov_R

  • Новичок
  • *
  • Сообщений: 3
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1501 : 24 Апреля 2024, 04:08:28 »
Добрый день!
Начал только знакомиться с данной SCADA системой. У меня задача вроди бы простая, но прочитав мануал (не исключено что нужное упустил) тривиального решения не нашел. Есть большое количество однотипных агрегатов у которых 8 переменных по которым определяется аварийное и рабочее состояние. Задача заключается в создании шаблона который менял цвет в зависимости от 5 переменных, в шаблонном окне по нажатию кнопки сбрасывались 4 булевские переменные, остальное (пуск/стоп, отображение отдельных параметров) интуитивно понятно. Переменные берутся с OPC-UA на ПЛК.  Я так понимаю что в скриптах нельзя использовать подстановку? Использовать скрипт по изменению переменной из списка тоже не имеет смысл, это уже не будет шаблоном. Создавать класс для агрегата и инициализировать туда все переменные из сервера тоже не вижу смысла когда их более 600. И как создать скрипт чтобы он постоянно выполнялся, не каждую секунду, минуту, час, а постоянно в цикле программы.

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1278
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1502 : 24 Апреля 2024, 16:35:43 »
Здравствуйте.

Работа с шаблонами описана по ссылке. Работа с шаблонами из скриптов по ссылке

Если требуется менять цвет объекта по значениям пяти переменных, то проще всего будет создать на контроллере переменную общей аварии и использовать в скада-системе одну переменную вместо пяти. Если из этих переменных формируется состояние агрегата (например: работа, разгон, торможение, авария, предупреждение), то на контроллере следует использовать одну целочисленную переменную, каждое значение которой будет соответствовать требуемому состоянию. Тогда можно будет применить универсальный скрипт. Примеры универсальных скриптов можно найти по ссылке.

Если на ПЛК возможности свести множество переменных в общую аварию (или состояние) нет, то нужно будет свести требуемые переменные в одну в скада-системе. Для этого нужно использовать скрипт с типом события "Изменились переменные". При однотипном наименовании переменных можно создать универсальный скрипт. Вы можете написать нам на почту support@simple-scada.com, вышлем пример такого скрипта.

Цитировать
И как создать скрипт чтобы он постоянно выполнялся, не каждую секунду, минуту, час, а постоянно в цикле программы.
Такой скрипт создать нельзя. Скрипт можно создать только по одному из доступных событий.

pan2000

  • Постоялец
  • ***
  • Сообщений: 196
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1503 : 24 Апреля 2024, 22:36:33 »
  Здравствуйте.

...Есть большое количество однотипных агрегатов у которых 8 переменных по которым определяется аварийное и рабочее состояние. Задача заключается в создании шаблона который менял цвет в зависимости от 5 переменных, в шаблонном окне по нажатию кнопки сбрасывались 4 булевские переменные, ...
Как правильно заметили разработчики Simple-Scada, то что можно следует загонять в ПЛК. Однако, если такой возможности нет, а количество агрегатов большое, то можно использовать шаблоны.
При проектировании шаблона следует стремиться к минимуму подстановок, количеству и объёму скриптов. Собственно подстановки шаблона сводятся к подстановкам в объекты этого шаблона.
Минимальный набор подстановок объекта включает основную и дополнительную переменную (имена переменных), свойства Tag (целое число) и Hint (строка). По изменению переменных возможен вызов соответствующих скриптов.
Для минимизации подстановок переменных следует использовать для каждого агрегата однотипные наборы имен, включающие поле номера агрегата, тогда единственной подстановкой будет только номер агрегата.
Пример построения шаблона с тремя отображаемыми отдельными параметрами и некоторой групповой логикой от 5-ти булевых переменных (упрощенная модель координатного стола: пуск/стоп, выход за границы, координаты):
- для отображения параметров используются три объекта "Поле" с подстановкой основной переменной, скрипт не требуется;
- три из 5-ти булевых переменных используют подстановку в дополнительные переменные объектов "Поле", а две оставшиеся подстановку в переменные объекта "Текст". Т.е. шаблон содержит четыре объекта с однотипными именами TempObj_<i=1..4>.
Булевы переменные по изменению (основной и дополнительной) собираются в вектор скриптом:
Код: (delphi)
var i, j: integer;
begin
  j := SetBit(0, 0, GetTemplateObject('TempObj_1').AsBool);   // младший бит вкл./выкл.
  for i := 1 to 4 do
    with GetTemplateObject('TempObj_' + IntToStr(i)) do
      j := SetBit(j, i, VariableEx.AsBool);              // собрать весь вектор
// интерпретация вектора - по таблице, case - оператором или набором условных операторов
end.
 
Во вложении пример для 4-х моделей агрегатов, которые связаны через встроенный OPC UA сервер собственно с шаблонами.

Lisov_R

  • Новичок
  • *
  • Сообщений: 3
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1504 : 25 Апреля 2024, 17:33:19 »
Спасибо большое!
Наверное буду экспериментировать с байтами. Заганю входные и выходные булевы переменные в байт и попробую с ним работать.

Lisov_R

  • Новичок
  • *
  • Сообщений: 3
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1505 : 26 Апреля 2024, 13:52:06 »
Возникает следующий вопрос. Агрегаты должны запускаться и останавливаться по ранее созданному маршруту с определенным интервалом времени. В иных ПО я это реализовывал простым способом, через цикл с паузой в скрипте который запускался по кнопке. В разных ПО это можно было реализовать по разному, где то скрипт выполнялся по условию постоянно и отслеживалось системное время, где то можно было засунуть без последствий таймер или паузу. Но тут у меня фантазии не хватает. Не существует постоянно выполняющегося скрипта, application.processmessages в скрипте не понимает, а без него виснет сервер. Дайте пендель в нужном направлении.
Желательно не предлагать реализовать это в ПЛК. Можно конечно на ПЛК загнать и это вместе с запросами SQL, но тогда вообще проще создать web виализацию на ПЛК и SCADA не нужна.

ZWolol

  • Новичок
  • *
  • Сообщений: 28
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1506 : 27 Апреля 2024, 05:32:02 »
Если интервалы времени не кратны 1с, то наверно ни как.
Иначе делаешь секундный скрипт, в котором проверяешь состояние переменной агрегата 0/1/2...
1-запуск цикла, по нему фиксируешь время начала, присваиваешь 2 и дальше проверяешь интервал
при достижении необходимых времен производишь нужные действия и увеличиваешь переменную
по окончании цикла переменной присваиваешь 0-стоп

pan2000

  • Постоялец
  • ***
  • Сообщений: 196
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1507 : 27 Апреля 2024, 10:10:31 »
    Здравствуйте.

... Агрегаты должны запускаться и останавливаться по ранее созданному маршруту с определенным интервалом времени...
  Simple-Scada может обеспечить управление агрегатами с шагом длительности в 1 сек и разбросом длительности в пределах 1-2 сек.
  1. Варианты независимого управления агрегатами с возможностью настройки (по усложнению реализации).
- маршрут на сутки или неделю - объект "Расписание", маршрут привязан к началу суток/недели;
- циклический (фиксированные времена включенного и выключенного состояния агрегата) - скрипт по таймеру 1 сек;
- последовательность временных меток изменения состояния агрегата с единым таймером. Для фиксированного маршрута - массив констант, для изменяемого - файл или база данных.
  2. Зависимая работа группы агрегатов - решение существенно зависит от характера взаимодействия агрегатов. Например, к одному "Расписанию" можно подключить несколько агрегатов, работающих синхронно или с настраиваемыми задержками.
Во вложении пример для первых двух вариантов независимого управления.

teplocom

  • Новичок
  • *
  • Сообщений: 47
  • с чувством уверенности в завтрашнем дне
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1508 : 18 Мая 2024, 08:45:08 »
Доброго
Задача вручную собрать битовую маску из разных битовых переменных.
Код и результат ниже. Почему не 4294967295?
Bitmaska тип данных LongWord, bit0...31 это bool.
Код: (delphi)
begin
 Bitmaska.Value:=bit0.Value*Power(2,0)
+bit1.Value*Power(2,1)
+bit2.Value*Power(2,2)
+bit3.Value*Power(2,3)
+bit4.Value*Power(2,4)
+bit5.Value*Power(2,5)
+bit6.Value*Power(2,6)
+bit7.Value*Power(2,7)
+bit8.Value*Power(2,8)
+bit9.Value*Power(2,9)
+bit10.Value*Power(2,10)
+bit11.Value*Power(2,11)
+bit12.Value*Power(2,12)
+bit13.Value*Power(2,13)
+bit14.Value*Power(2,14)
+bit15.Value*Power(2,15)
+bit16.Value*Power(2,16)
+bit17.Value*Power(2,17)
+bit18.Value*Power(2,18)
+bit19.Value*Power(2,19)
+bit20.Value*Power(2,20)
+bit21.Value*Power(2,21)
+bit22.Value*Power(2,22)
+bit23.Value*Power(2,23)
+bit24.Value*Power(2,24)
+bit25.Value*Power(2,25)
+bit26.Value*Power(2,26)
+bit27.Value*Power(2,27)
+bit28.Value*Power(2,28)
+bit29.Value*Power(2,29)
+bit30.Value*Power(2,30)
+bit31.Value*Power(2,31);
end.
« Изменён: 18 Мая 2024, 08:50:24 от teplocom »

teplocom

  • Новичок
  • *
  • Сообщений: 47
  • с чувством уверенности в завтрашнем дне
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1509 : 18 Мая 2024, 10:30:42 »
На данный момент удалось решить проблему вычисления добавлением строчки в конце:
Bitmaska.Value shr 1;

Но всё-равно не получилось решить задачу сбора.
С локальными/внутренними битовыми переменными маску собирает работает корректно, а с внешними переменными (битами из @bit00) все по нулям, при ненулевых внешних битах.

Такой вариант тоже работает только с внутренним переменными
Код: (delphi)
begin
 SetBit(Bitmaska.Value,0,bit0.Value)
 SetBit(Bitmaska.Value,1,bit1.Value)
 SetBit(Bitmaska.Value,2,bit2.Value)
 SetBit(Bitmaska.Value,3,bit3.Value)
 SetBit(Bitmaska.Value,4,bit4.Value)
...
 SetBit(Bitmaska.Value,31,bit31.Value)
end.
« Изменён: 18 Мая 2024, 12:03:37 от teplocom »

teplocom

  • Новичок
  • *
  • Сообщений: 47
  • с чувством уверенности в завтрашнем дне
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1510 : 18 Мая 2024, 15:15:01 »
В общем добились, того, что нужно, но вариант получился такой:
Код: (delphi)
var q,w,e,r,t,y,u,i,o,p,a,s,d,f,g,h,j,k,l,q1,w1,e1,r1,t1,y1,u1,i1,o1,p1,a1,s1,d1,f1,g1,h1,j1,k1,l1,z1,c1 : Integer;
 begin
 q:=bit_00.Value; w:=bit_01.Value; e:=bit_02.Value; r:=bit_03.Value; t:=bit_04.Value; y:=bit_05.Value; u:=bit_06.Value;
 i:=bit_07.Value; o:=bit_08.Value; p:=bit_09.Value; a:=bit_10.Value; s:=bit_11.Value; d:=bit_12.Value; f:=bit_13.Value;
 g:=bit_14.Value; h:=bit_15.Value; j:=bit_16.Value; k:=bit_17.Value; l:=bit_18.Value;
 Bitmaska.Value:=Abs(q)*Power(2,0)
+Abs(w)*Power(2,1)
+ 0*Power(2,2)
+ 0*Power(2,3)
+Abs(e)*Power(2,4)
+Abs(r)*Power(2,5)
+Abs(t)*Power(2,6)
+Abs(y)*Power(2,7)
+Abs(u)*Power(2,8)
+Abs(i)*Power(2,9)
+Abs(o)*Power(2,10)
+ 0*Power(2,1)
+ 0*Power(2,12)
+Abs(p)*Power(2,13)
+ 0*Power(2,14)
+ 0*Power(2,15)
+ 0*Power(2,16)
+ 0*Power(2,17)
+Abs(a)*Power(2,18)
+ 0*Power(2,19)
+ 0*Power(2,20)
+Abs(s)*Power(2,21)
+Abs(d)*Power(2,22)
+Abs(f)*Power(2,23)
+Abs(g)*Power(2,24)
+Abs(h)*Power(2,25)
+Abs(j)*Power(2,26)
+Abs(k)*Power(2,27)
+Abs(l)*Power(2,28)
+0*Power(2,29)
+0*Power(2,30)
+0*Power(2,31) ;
 Bitmaska.Value shr 1;

внешние биты стали правильно записываться в маску, только при присвоении их через промежуточные локальные переменные
значения должны быть взяты по модулю (потому что экспериментальным путем было замечено, что в них вместо значения 1, записывалось -1)
и в конце сдвиг регистра вправо на 1 бит.

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3146
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1511 : 18 Мая 2024, 18:40:30 »
Здравствуйте.

Учитывайте, что при получении значения через myVar.Value Вы получите значение с универсальным типом Variant, как описано в руководстве. Этот тип будет хранить значения в собственном формате и будет преобразовываться в другие типы автоматически компилятором. Чтобы всегда получать ожидаемый результат рекомендуется брать значение в нужном типе. Например: myVar.AsBool вернёт boolean значение переменной, т.е. true / false. myVar.AsInt вернёт значение переведенное в тип Integer и т.д.

Цитировать
было замечено, что в них вместо значения 1, записывалось -1
Верно, в типе Variant значение boolean хранится как true = -1, false = 0. Краткое описание типа Variant по ссылке.

В коде с SetBit Вы не получаете результат ни в какую переменную, поэтому он работать не будет.
Правильный вариант кода ниже:
Код: (delphi)
var
  res: LongWord;
begin
  // все биты локальной переменной res устанавливаем в 0
  res := 0;
  // устанавливаем биты в переменной res
  res := SetBit(res, 0, bit0.AsBool);
  res := SetBit(res, 1, bit1.AsBool);
  res := SetBit(res, 2, bit2.AsBool);
  res := SetBit(res, 3, bit3.AsBool);
  res := SetBit(res, 4, bit4.AsBool);
  res := SetBit(res, 5, bit5.AsBool);
  res := SetBit(res, 6, bit6.AsBool);
  res := SetBit(res, 7, bit7.AsBool);
  res := SetBit(res, 8, bit8.AsBool);
  res := SetBit(res, 9, bit9.AsBool);
  res := SetBit(res, 10, bit10.AsBool);
  res := SetBit(res, 11, bit11.AsBool);
  res := SetBit(res, 12, bit12.AsBool);
  res := SetBit(res, 13, bit13.AsBool);
  res := SetBit(res, 14, bit14.AsBool);
  res := SetBit(res, 15, bit15.AsBool);
  res := SetBit(res, 16, bit16.AsBool);
  res := SetBit(res, 17, bit17.AsBool);
  res := SetBit(res, 18, bit18.AsBool);
  res := SetBit(res, 19, bit19.AsBool);
  res := SetBit(res, 20, bit20.AsBool);
  res := SetBit(res, 21, bit21.AsBool);
  res := SetBit(res, 22, bit22.AsBool);
  res := SetBit(res, 23, bit23.AsBool);
  res := SetBit(res, 24, bit24.AsBool);
  res := SetBit(res, 25, bit25.AsBool);
  res := SetBit(res, 26, bit26.AsBool);
  res := SetBit(res, 27, bit27.AsBool);
  res := SetBit(res, 28, bit28.AsBool);
  res := SetBit(res, 29, bit29.AsBool);
  res := SetBit(res, 30, bit30.AsBool);
  res := SetBit(res, 31, bit31.AsBool);

  // записываем результат в Bitmaska
  Bitmaska.Value := res;
end.
« Изменён: 18 Мая 2024, 18:51:42 от Simple-Scada »

teplocom

  • Новичок
  • *
  • Сообщений: 47
  • с чувством уверенности в завтрашнем дне
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1512 : 20 Мая 2024, 20:29:48 »
Cпасибо за подсказку, всё завелось.
Так и знал, что в школе нужно было хорошо учиться.  ;D

Juan Esteban

  • Новичок
  • *
  • Сообщений: 1
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1513 : 29 Мая 2024, 11:54:18 »
Здравствуйте.

Вопрос такой. Хочу использовать скрипт по событию Ошибка SQL-запроса. В документации написано, что в нем содержится параметр SQLErrorData c тремя свойствами. Но при компиляции кода примера подобного скрипта из документации выдается ошибка - он не знает такого параметра. Как же правильно получить информацию об ошибке запроса?

AndreyA

  • Новичок
  • *
  • Сообщений: 35
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1514 : 29 Мая 2024, 14:27:58 »
Здравствуйте, необходимо создать  кнопки (+1) и (-1) для уставки в частотный привод, есть ли что то подобное с установкой значения переменной через готовую процедуру типа SetValue?
Спасибо!
Сделал пока так через событие OnClick
Код: (delphi)
begin
   if Sender is TM_Object then     // проверяем, что Sender это объект
     with Sender as TM_Object do   // приводим Sender к типу "TM_Object"
       begin
       if Variable.Value < 100 then
          Variable.Value := Variable.Value +1;
       end
end.
Вопрос снят.
« Изменён: 29 Мая 2024, 16:12:22 от Simple_Scada »