Вопросы по скриптам в Simple-Scada 2

Автор Simple-Scada, 29 января 2016, 15:19:20

Simple_Scada

Здравствуйте.

Для такой задачи сложно подобрать максимально простое решение. Во вложении пример проекта основанного на "первой переменой" и на двух универсальных скриптах по изменению основной и доп. переменной связанной с объектом. На каждый объект создана внутренняя переменная для подсчета изменений - данная переменная должна быть указана в качестве дополнительной для объекта. Имена переменных имеют однотипные названия, для упрощения работы в скриптах и шаблонах. В секундном скрипте значения счетчиков уменьшаются. В скрипте по изменению основной переменной счетчик изменений увеличивается. По достижении установленного значения(в примере через 5 сек.) выдается сообщение и изменяется цвет объекта. Переход в норму также происходит с задержкой, т.к. по другому не определить, было единичное изменение переменной или она постоянно меняется 0/1. Какой-то более простой способ решения подобрать не получилось, но даже при 1000 переменных описанный способ не должен сказаться на производительности.

Цитироватьизменение состояния первой может в какой-то момент синхронизироваться с частотой опроса и в этом случае скада будет считать, что устройство в первом или втором состоянии
Как Вы указали: " 0 и 1 сменяют друг друга с периодом в 1 секунду". Значит Вам нужно установить частоту опроса данных переменных = 500мс., тогда описанная ситуация никогда не возникнет и не нужно будет использовать вторую переменную.

quarian

Здравствуйте.
Спасибо за простое и изящное решение :). Взял его как основу.
Вы помогли мне выбраться из своей собственной зацикленности) Попытка отказаться от выполнения скриптов по времени, действительно, привела меня в тупик.

Вячеслав

#1157
Здравствуйте! Подскажите как решить такой вопрос. Из OPC считывается значение температуры и выводится на экран. Но есть одна особенность-отрицательная температура вычисляется как Треал=Тполуч-65536. Для этого я создал скрипт по изменению переменной Тполуч.:
Код: pascal
var
a: integer;
S: String;
begin
{ условия для поля }
  if Sender is TM_Field then     // проверяем, что Sender это поле
    with Sender as TM_Field do   // приводим Sender к типу "TM_Field"
       if AsInt > 100 then       // если значение температуры больше 100 то
        begin                    // температура отрицательная и вычисляем ее значение
          a:=0;                  // сбрасываем старое значение временной переменной
          a:=AsInt-65536;        // вычисляем отрицательную разницу температуры
          S:= IntToStr(a);       // преобразуем значение с минусом в текстовую строку
          Text:= S;              // выдаем строку в свойство текста элемента поля
         end;
end.
Но с ним обнаружилась одна проблема. Все работает только когда экранная форма с элементом Поле открыта. Если форму закрыть и вернуться обратно то элемент Поле показывает значение Тполуч. То есть скрипт не запускается так как переменная Тполуч. за это время не изменилась.

Simple_Scada

Здравствуйте.

В каком диапазоне может меняться значение приходящее с датчика температуры и какая шкала должна быть в скаде? Например, с датчика приходит значение в шкале 0 - 100, а необходимо его отображать в шкале 0 - 150, тогда нужно использовать режим масштабирования - см. описание опции "Сдвиг запятой". Это наиболее правильный способ, не требующий использования скриптов. Если режим масштабирования не подходит, то см. другие варианты ниже.

Чтобы описанные расчеты работали корректно, нужно назначить полю доп. переменную = Тполуч, а основную переменную не назначать и написать скрипт по событию OnDataChangeEx(изменилась доп. переменная):
Код: pascal
 begin
{ условия для поля }
  if Sender is TM_Field then     // проверяем, что Sender это поле
    with Sender as TM_Field do   // приводим Sender к типу "TM_Field"
       if VariableEx.AsInt > 100 then       // если значение температуры больше 100 то
         Text:= IntToStr(VariableEx.AsInt - 65536)
       else
         Text:= IntToStr(VariableEx.AsInt);
end.
Но, если требуется архивировать рассчитанное значение переменной(или например использовать его в других скриптах), то лучше создать внутреннюю переменную и записывать результат расчета в нее. Тогда можно будет при необходимости использовать эту переменную в трендах, скриптах, отчетах и т.д. Для такого способа нужно указать в основной переменной поля нашу внутреннюю переменную(при этом доп. переменная поля = Тполуч) и внести небольшие изменения в скрипт:   
Код: pascal
begin
{ условия для поля }
  if Sender is TM_Field then     // проверяем, что Sender это поле
    with Sender as TM_Field do   // приводим Sender к типу "TM_Field"
       if VariableEx.AsInt > 100 then       // если значение температуры больше 100 то
         Value := VariableEx.AsInt - 65536
       else
         Value:= VariableEx.AsInt;
end.

Вячеслав

 ;)Спасибо за помощь! Первый вариант кода работает именно так как необходимо. Просто в голову не приходило что скрипт можно запустить только с дополнительной переменной.

mihanikus45rus

Добрый день. При создании скрипта скада не видит имя обьекта, и при компиляции пишет что не обьявленный. Обьект(например Shape49) расположен в окне №2. Причём в окне №1 все работает. То есть в окне №2 10 обьектов, и ни один не виден при создании скрипта. Перенёс обьект из окна №2 в окно №1 - стал видимым для скрипта. Версия скады 2.4.0.12 demo time. Может я что то упустил?

Simple-Scada

#1161
Здравствуйте.

Возможно Вы создали шаблонное окно, тогда объекты в нём действительно не будут видны в скриптах и это правильно, т.к. на основе шаблонного окна может быть создать множество окон с множеством отдельных объектов (о которых скада не знает на этапе компиляции). Если окно обычное, но объекты всё равно не видны, то вышлите проект для проверки на support@simple-scada.com.

mihanikus45rus

Спасибо, действительно шаблонное. Всё работает.

dima_k

#1163
пытаюсь создать модальное окно (почти, чтобы для оператора не было возможности тыкать в то, что видно за пределами окна).
Кладу bg:TM_Shape на всю закладку. и когда надо показать окно - есть кнопка Btn1 с событием OnClick:
  bg.Visible:=true;
  bg.Layer:=9999;
  WinRecipe.ShowAll;
в закладке есть еще кнопка со скриптом перехода на главное окно
PageMain.GoToPageAll;     
(bg - это объект TM_Shape, WinRecipe - окно)
окно WinRecipe появляется, но все другие объекты, которые по идее находятся под bd продолжают получать фокус ввода.
в окне WinRecipe есть кнопка у нее скрипт по click:
  bg.Visible:=false;
  bg.Layer:=1;
  WinRecipe.CloseAll;

После нажатия на эту кнопку окно WinRecipe скрывается и дальше чертичто. Клавиша Btn1 срабатывает со второго раза, клавиша перехода на главное окно вообще не работает.


P.S. Как бы сделать модальные окна?

PPS RowIndex у таблицы  давно хотелось бы самому устанавливать.

Simple_Scada

Здравствуйте.

Модальное окно реализовать не получится, в том числе методом, которым Вы пытаетесь это сделать. Также, следует учитывать, что изменения свойств объектов применяются для всех клиентов, т.е. если скрыть объект "Фигура", то он будет скрыт на всех клиентах, независимо от того, на каком клиенте нажали кнопку выполняющую скрипт скрытия объекта. Поэтому, при наличии более 1 клиента данный способ абсолютно не рабочий.

ЦитироватьКлавиша Btn1 срабатывает со второго раза, клавиша перехода на главное окно вообще не работает.
При желании, Вы можете прислать нам для проверки проект из директории "...\Simple-Scada 2\Projects\Имя_проекта" и мы скажем почему именно это происходит.

pan2000

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

Для нескольких клиентов можно определить правила вызова окна (только один клиент, несколько, для конкретного пользователя ...).

Пример во вложении (процесс создания шторок в комментарии скрипта).

dima_k

Прикольное решение.

Может кто подскажет, как в таблице передвигать фокус ввода на нужную клетку или хотя бы строку?
Свойство RowIndex у таблицы readOnly.

lipvasko

Доброго дня,  второй раз сталкиваюсь с  некорректной обработкой  оператора not , условие  такое
 if not  aaa.value then   нормально не обрабатывается ,  ааа- переменная bool

Simple-Scada

#1168
Здравствуйте.

Оператор not всегда работает правильно. Дело в том, что свойство Value переменной является типом Variant и может интерпретироваться компилятором, например, как число. Если Вам известен тип данных, то берите значение в этом типе, например:
Код: pascal
if not aaa.AsBool then 
или
Код: pascal
if aaa.AsBool = false then 

Также, рекомендуем ознакомиться с описанием частых ошибок в скриптах - ссылка. Данная ошибка там также рассмотрена - см. пример №2.

lipvasko

#1169
Это понятно, но всегда использовал if aaa.value then, и всегда компилятор , понимал , что  true  , это та же 1, а  вот  с falsе, так не выходит,  а почему тогда работает  if aaa.value = false then, понятно, что лучше использовать  AsBool и т.д.,но это часто неудобно.