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

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

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

metamorphogenesis

  • Пользователь
  • **
  • Сообщений: 58
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1230 : 19 Июля 2021, 22:18:37 »
Доброго дня, ув. разработчики и коллеги! Возник такой вопрос.

В скаде расставлены барграфы, шкалу которых я хочу размечать однотипно по одному и тому же принципу. Для этой цели был написан один универсальный скрипт, который  по крайним значениям шкалы переменной барграфа рассчитывает, сколько нужно меток, чтобы шкала барграфа получилась красивой и с нужным шагом.

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

Можете порекомендовать какой-то альтернативный способ однократно обновить одним скриптом свойство каждого объекта исходя из индивидуальных параметров каждого из них?


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

Разработчики, подскажите, эффективнее ли в теории такой подход, чем полноценное выполнение скрипта (в котором 20 строк, несколько математических операций и несколько уровней вложенности условий)?
« Изменён: 21 Июля 2021, 11:02:32 от metamorphogenesis »

pan2000

  • Постоялец
  • ***
  • Сообщений: 226
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1231 : 20 Июля 2021, 16:45:47 »
    Здравствуйте.
... но разметить барграф нужно по сути только один раз ...
...  единственный способ применить этот скрипт к барграфу, который я нашел - это событие onDataChange ...
1. Если у барграфа не используется дополнительная переменная, то достаточно назначить скрипт разметки на событие по изменению доп. переменной, в качестве которой используется одна новая переменная. При ее инициализации (запуск проекта) для каждого барграфа будет однократно выполнен скрипт разметки.

2. Можно назначить скрипт разметки на событие по двойному клику мыши и однократно вызывать скрипт для всех барграфов при запуске проекта. Скрипт "Полностью запущен" (барграфы задаются перечислением или в цикле):
Код: (delphi)
var i: integer;
begin
  Bargraph1.OnDblClickEvent;
  Bargraph2.OnDblClickEvent;
  . . .
  Bargraph100500.OnDblClickEvent;
// или
  for i := 1 to 100500 do GetObjectByName('Bargraph' + IntToStr(i)).OnDblClickEvent;  // это только пример
end.
« Изменён: 05 Августа 2021, 06:32:22 от pan2000 »

metamorphogenesis

  • Пользователь
  • **
  • Сообщений: 58
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1232 : 21 Июля 2021, 11:01:57 »
Большое спасибо, есть из чего выбрать)

metamorphogenesis

  • Пользователь
  • **
  • Сообщений: 58
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1233 : 21 Июля 2021, 21:51:27 »
Еще вопрос.Сейчас рефакторится метод, и ссылки на объекты, с которыми работаю внутри, я теперь получаю по имени, которое скармливаю методу.

до рефакторинга:
Код: (delphi)
procedure refreshSettings(const productsNames: TM_StringList);  //  вызывается refreshSettings(sl800ProductsNames)
begin
    ...
    productsNames.Clear;                                        // очищается sl800ProductsNames
    ...
end;
после рефакторинга:
Код: (delphi)
procedure refreshSettings(const lineName: string);                               //  вызывается refreshSettings('sl800')
var
    productsNames: TM_StringList;
begin
    ...
    productsNames := TM_StringList(getObjectByName(lineName + 'ProductsNames')); // из имени получается ссылка на sl800ProductsNames
    productsNames.Clear;                                                         // EXCEPTION
    ...
end;

Проблема в том, что после рефакторинга я ловлю исключение
Unhandled exception in module "global" at line 570. Access violation at address 01776AFB in module 'Server.exe'. Read of address 00000004

Что я делаю не так? Благодарю за помощь.
« Изменён: 21 Июля 2021, 22:02:28 от metamorphogenesis »

Timothy Clement

  • Постоялец
  • ***
  • Сообщений: 166
  • ОАО Борисовский завод "Металлист"
    • Просмотр профиля
    • Полымя
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1234 : 22 Июля 2021, 08:06:40 »
Проблема в том, что после рефакторинга я ловлю исключение
Unhandled exception in module "global" at line 570. Access violation at address 01776AFB in module 'Server.exe'. Read of address 00000004

Что я делаю не так? Благодарю за помощь.

При попытке получить объект по имени, скрипт наткнулся на имя которого не существует в проекте, отсюда и исключение.

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3214
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1235 : 22 Июля 2021, 09:48:32 »
Все функции поиска описанные по этой ссылке работают с объектами мнемосхем, окнами и переменными (созданными в меню редактирования переменных). Они никак не связаны с теми переменными и объектами, которые Вы создаёте в скриптах. Поэтому при попытке найти StringList функция getObjectByName вернёт нулевой указатель (nil), а при попытке к нему обратиться будет выдана Access violation.

metamorphogenesis

  • Пользователь
  • **
  • Сообщений: 58
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1236 : 22 Июля 2021, 18:49:38 »
Спасибо. Важное уточнение, думал что к объектам относятся все объекты без исключения. Тогда отменить/передумать рефакторинг.

На всякий случай дополните статью в справке об этом. Но если вы добавите возможность искать и такие объекты - будет вообще превосходно!  :)

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3214
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1237 : 25 Июля 2021, 21:44:26 »
Цитировать
Но если вы добавите возможность искать и такие объекты - будет вообще превосходно!
Такой возможности точно не будет, т.к. она слишком расточительна в плане производительности и на наш взгляд бессмысленна. Также она потребует добавления строкового представления имени в оперативной памяти реальному адресу объекта. Из 100% объектов Вы скорее всего будете использовать очень малый процент, а большинство других пользователей вообще не используют поиск по имени. В целом, если Вы пришли к тому, что приходится использовать поиск объектов по имени в скриптах, то с большой вероятностью структуры данных в Вашем коде плохо организованы или использован неправильный подход для решения задачи. Например, мы при создании скады никогда не использовали поиска объектов/переменных по имени, хотя однотипных структур очень много. У других программистов тоже никогда не видели кода в котором для обращения к объекту выполнялся бы его поиск по имени.
Если у Вас нет других вариантов, то можно создать свой список и заносить в него соответствие объект -> имя в виде строки, а затем выполнять поиск по имени с помощью этого списка.

Timothy Clement

  • Постоялец
  • ***
  • Сообщений: 166
  • ОАО Борисовский завод "Металлист"
    • Просмотр профиля
    • Полымя
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1238 : 26 Июля 2021, 13:47:35 »
В целом, если Вы пришли к тому, что приходится использовать поиск объектов по имени в скриптах, то с большой вероятностью структуры данных в Вашем коде плохо организованы или использован неправильный подход для решения задачи.

Это обусловлено ресурсоёмкостью функции поиска объектов? Просто я использую поиск по имени в каждом проекте. Может я делаю неправильно, но возьмём самую распространенную задачу - Изменение цвета по биту переменной.
В руководстве она описана так:
Код: (delphi)
begin
  if Sender is TM_Image then        // сначала убедимся, что скрипт вызван объектом "Изображение"
    with Sender as TM_Image do      // далее будем работать с объектом Sender, как с изображением
      begin
        {меняем цвет изображения по основной переменной}
        if GetBit(AsInt, 3) = TRUE then Color := clGreen else Color := clRed;
        {меняем скорость анимации изображения по доп. переменной "VariableEx"}
        if GetBit(VariableEx.AsInt, 1) = TRUE then AnimSpeed := 10 else AnimSpeed := 0;
      end;
end.
То есть к каждому изображению нужно привязать переменную и назначить 2 события по изменению переменной.

Либо можно назначить изображениям однотипные имена вроде "m0", "m1" .. "m15" и искать их в цикле скрипта "Изменились переменные".
Код: (delphi)
var
  obj: TM_Image;
  i: Integer;
begin
  for i:=0 to 63 do                               
   begin
     obj := GetImageByName('m'+IntToStr(i));
     if obj <> nil then
      if GetBit(int1.Value,i) then obj.Color:= clLime else obj.Color:= clNone;
      if GetBit(int2.Value,i) then obj.Animspeed := 10 else obj.Animspeed := 0;
   end;
end.
То есть если у нас 2 переменные по 64 бита, и 64 объекта на мнемосхеме, универсальный скрипт выполнится 64(128) раз при изменении 1 бита в каждом слове? Либо 1(2) раза выполнится скрипт "Изменились переменные". Если поиск настолько ресурсоёмкий, то может мне стоит пересмотреть свой подход в реализации этих задач. Поправьте если ошибся, может это работает иначе чем я описал.
« Изменён: 26 Июля 2021, 13:52:46 от Timothy Clement »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3214
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1239 : 26 Июля 2021, 16:38:08 »
В нашем предыдущем сообщении речь шла о добавлении функции поиска для всех объектов, включая объекты объявленные пользователем в скриптах, это было бы действительно ресурсоёмко.
Если говорить только о существующих функциях поиска, как "GetImageByName" и т.п., то они работают максимально быстро (используется поиск по хеш-таблице). Но и эти функции пользователи чаще всего используют там, где без них можно обойтись. Если рассматривать задачу с битами, которую Вы привели, то вариант с "GetImageByName" будет работать быстрее и в данном случае использование "GetImageByName" оправдано. Это пример правильного использования функции поиска по имени, к сожалению мы встречаем такое редко в проектах пользователей.

KungLao

  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля
Вопросы по скриптам в Simple-Scada 2
« Ответ #1240 : 26 Июля 2021, 19:16:20 »
Добрый вечер. Подскажите пожалуйста, возникла необходимость управлять релейными выходами коонтроллера. Для того, чтобы получить доступ к управлению ними, необходимо ввести пароль (записать 5 значений в 5 регистров). Пароль нужно вводить, только если в регистре №121 содержится "0", если "1" - то пароль был введен и сессия активна. Как только сессия становится не активной и в регистре 121 - "0", то нужно опять повторять ввод пароля (в пять регистров записывать 5 значений.) В OPC сервере если руками выставить значения этих переменных, то как бы все работает на стороне контроллера. Но как это сделать в скада? я импортировал эти 6 переменных и не знаю как это реализовать. Возможен ли скрипт: при изменении переменной с "1" в "0", записать в 5 переменных 5 значений и чтобы это делалось автоматически. Либо чтобы при нажатии одной кнопки записывалось 5 переменных. Если это очень просто, прошу сильно не ругать, я только начинаю первые шаги в освоении SCADA, скрипты тоже никогда не писал к сожалению.

metamorphogenesis

  • Пользователь
  • **
  • Сообщений: 58
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1241 : 27 Июля 2021, 08:37:41 »
Возможен ли скрипт: при изменении переменной с "1" в "0", записать в 5 переменных 5 значений и чтобы это делалось автоматически. Либо чтобы при нажатии одной кнопки записывалось 5 переменных.


Конечно. Вы можете создать скрипт с типом "изменилась переменная", затем справа вверху выбрать переменную, изменение с 1 в 0 которой вы отслеживаете, а в скрипте выполнить простую проверку и запись значений
Код: (delphi)
begin
    if variable.AsInt = 0 then
    begin
        var1.value := ...;
        var2.value := ...;
        var3.value := ...;
        var4.value := ...;
        var5.value := ...;
        // действия, когда сессия неактивна
{ если вам нужно действие, когда сессия активна, удалите строки 10 и 14
    end
    else begin
        // действия, когда сессия активна
}
    end;
end.

Во второй строке вы проверяете значение той переменной, изменение которой вызвало скрипт. Вы можете явно проверять значение переменной по ее имени, но это лучше делать, если вы уверены, что вам это необходимо (то есть изменилась одна переменная и вызвала скрипт, в котором вы проверяете значение, например, совершенно другой переменной). Так же учтите, что если вы добавите в скрипт какие-то другие переменные, то скрипт будет вызван и их изменением тоже, и поведение программы может оказаться отличным от ожидаемого.Чтобы записать переменные нажатием кнопки, перейдите во вкладку событий объекта (кнопки/картинки  и т.д.), в строке события onClick нажмите на кнопку "...", при этом создастся новый скрипт, который будет вызван по нажатию на объект. В тело скрипта вставьте само действие - строки 4-8 из выше приведенного примера.
« Изменён: 27 Июля 2021, 08:42:15 от metamorphogenesis »

KungLao

  • Новичок
  • *
  • Сообщений: 9
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1242 : 27 Июля 2021, 12:01:01 »
Спасибо огромное, все получилось и все работает. Но теперь я думаю, что лучше такой скрипт реализовать в OPC сервере, чтобы можно было управлять контроллером даже при если скада не запущена.
« Изменён: 27 Июля 2021, 20:57:00 от Simple_Scada »

metamorphogenesis

  • Пользователь
  • **
  • Сообщений: 58
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1243 : 28 Июля 2021, 06:56:43 »
Лучше это реализовать прямо в контроллере, чтобы контроллер мог принимать меры предосторожности даже если ОРС не запущен/нет связи с ним.
« Изменён: 30 Июля 2021, 20:45:18 от Simple_Scada »

strs

  • Новичок
  • *
  • Сообщений: 36
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1244 : 04 Августа 2021, 11:15:41 »
Здравствуйте. Подскажите пожалуйста, в скриптах с типом события "изменились переменные" можно обратиться к этой самой переменной не по имени? Если нет, возможно ли добавить такую возможность? Поясняю: у меня есть в проекте много однотипных скриптов типа:
Код
if (B24_220.Value = false)   and  (IsFirstChange() = false) then
     AddMessageToGroup(Now, mkAlarm, 4, 'Котельная 24 - нет сети 220В!', true, true);       
Скрипт выполняется по изменению переменной "B24_220" и не смотря на то, что она уже указана в редакторе скрипта, я вынужден писать ее имя в коде. [Если такой возможности нет], было бы гораздо удобнее, если бы можно было просто написать:
Код
if (var0.Value = false)   and  (IsFirstChange() = false) then
     AddMessageToGroup(Now, mkAlarm, 4, 'Котельная 24 - нет сети 220В!', true, true);       
Чтобы компилятор понимал, что var0 - это первая переменная из списка, var1 - вторая и т.д. Тогда скрипт можно было бы просто копировать, заменяя сообщение и выбирая разные переменные.