Simple-Scada forum

Simple-Scada 2 => Ваши вопросы => Тема начата: Daniil от 21 Июля 2024, 08:00:08

Название: Скрипт через некоторое время перестает менять объект.
Отправлено: Daniil от 21 Июля 2024, 08:00:08
Здравствуйте!
Присутствует странная проблема, и хотелось бы получить от вас помощь.
Ситуация следующая - в случайный момент объект перестает реагировать на изменение привязанного тега и не меняет состояние по скрипту.
Причем сначала все работает штатно(то есть скрипт обрабатывает все значения и меняет объект на мнемосхеме)- и только с течением времени рандомно выплывает такая ошибка.
Судя по трендам и логу того же скрипта все происходит штатно (скрипт завершается корректно и все значения переменной получает в нужное время)- однако это не так.
Скриншот с текущим значением переменной и "неправильным" отображением тоже прикладываю (3 - охлаждение, на рисунке состояние "Пауза", значение 7).
Сам скрипт простейший:
Код: (delphi)
begin
   if not (Sender is TM_Text) then 
    Exit;

   with Sender as TM_Text do
    Log_Add("ВОП изменился статус - старт скрипта " +  Variable.Name + " - " + IntToStr(Variable.AsInt), true);

   with Sender as TM_Text do
       case AsInt of                 
         0: begin Text:='Отключен'; Color:= clDarkGray; end;
         1: begin Text := 'Отвод паро-жидкости'; Color:= clSlateGray; end;           
         2: begin Text:= 'Подача жидкости'; Color:= clDarkCyan; end;             
         3: begin Text:='Охлаждение'; Color:= clDarkCyan; end;
         4: begin Text := 'Завершение охлаждения'; Color:= clSlateGray; end;       
         5: begin Text:= 'Закрытие паро-жидкости'; Color:= clSlateGray; end;         
         6: begin Text:= 'Оттаивание'; Color:= clLightSalmon; end;
         7: begin Text:='Пауза'; Color:= clSilver; end;
         8: begin Text:='Поддержание'; Color:= clSilver; end;
         253: begin Text := 'Сервисный режим'; Color:= clMaroon; end;
         254: begin Text := 'Нет готовности'; Color:= clRed; end;
         255: begin Text:= 'Неисправность'; Color:= clRed; end;
       else
        begin Text := 'Неизвестное'; Color:= clWhite; end;
       end;
   with Sender as TM_Text do
    Log_Add("ВОП изменился статус - конец скрипта " + Variable.Name, true);

end.
Дополняю пост ссылкой на лог:
https://disk.yandex.ru/d/5Ulh_UYw7rynyA
Название: Re: Скрипт через некоторое время перестает менять объект.
Отправлено: Simple_Scada от 22 Июля 2024, 11:03:28
Здравствуйте.

В первую очередь рекомендуем проверять журнал сервера Simple-Scada (https://simple-scada.com/help/manual/server-journal.html) - в нем могут содержаться ошибки и предупреждения, которые подскажут причину проблем.

По логам видно, что в скриптах проекта имеются грубые ошибки (например бесконечные циклы, зацикленные друг на друга скрипты и т.д.), которые приводят к бесконечному росту очереди скриптов. Из-за этого очередь скриптов переполняется, очищается и скрипты накопленные в очереди не выполняются. Примитивный пример описан по ссылке (https://simple-scada.com/help/script/debugscripts.html?anchor=erroverflow).

В Вашем логе это выглядит следующим образом:
Код
23:05:25.356 | Мираторг Короча | Стек скриптов переполнен. Возможно допущена рекурсия, когда два скрипта вызывают друг друга. Очередь скриптов очищена. Информация о скриптах записана в лог.
AC_1M_3FLAP_2H_1AI_SecondsToTimeLeft: 19288
AC_1M_3FLAP_2H_1AI_SecondsToTime: 19272
AC_Ammony_Mini_TimeToLeft: 9644
GasDetectorTextColor: 6587
Как видно, чаще всего вызываются скрипты с именами "AC_1M_3FLAP_2H_1AI_SecondsToTimeLeft", "AC_1M_3FLAP_2H_1AI_SecondsToTime" (очередь более 19000) и "AC_Ammony_Mini_TimeToLeft"  (очередь более 9600). Поэтому, следует начать с проверки данных скриптов.

Также в логах встречаются ошибки, допущенные в скриптах:
Код
07:22:54.598 | Мираторг Короча | Ошибка в скрипте "RecieverInirWnd" в строке 35. Обращение к несуществующему объекту (01911D57 in module 'SrvService.exe'. Read of address 00000148)
07:22:54.613 | Мираторг Короча | Ошибка в скрипте "AirCoolerWTEN4WndInit" в строке 17. Обращение к несуществующему объекту (01911D57 in module 'SrvService.exe'. Read of address 00000148)
07:22:54.705 | Мираторг Короча | Ошибка в скрипте "GasDetectorTextColor" в строке 4. Обращение к несуществующему объекту (105ACA23. Read of address 1CFCE300)
07:22:57.391 | Мираторг Короча | Ошибка в скрипте "Reciever_10_1_CalcLevel" в строке 20. Invalid floating point operation
07:23:03.858 | Мираторг Короча | Ошибка в скрипте "COMPWndProirityText" в строке 7. Invalid typecast
И т.д.
В разделе "Отладка скриптов (https://simple-scada.com/help/script/debugscripts.html)" имеются примеры наиболее частых ошибок в скриптах и методы их устранения. Рекомендуем исправить ошибки, встречающиеся в логах.

Если самостоятельно разобраться не получится, то пришлите нам на support@simple-scada.com текущую версию Вашего проекта из директории "..\Simple-Scada 2\Projects\".
Название: Re: Скрипт через некоторое время перестает менять объект.
Отправлено: Daniil от 22 Июля 2024, 11:29:47
Спасибо за определение вероятных проблемных точек. Я обязательно подумаю как мне оптимизировать найденные Вами скрипты. Однако, боюсь, что это не является первоисточником проблемы, так как залипают далеко не все объекты, а лишь конкретные. Скорее всего тут происходит не переполнение очереди выполнения скриптов, иначе бы "встало колом" все. Более того, если на "залипшем" объекте произвести некоторые манипуляции, а именно вывести его программно из работы и обратно включить, то статусы начитают опять работать в режиме онлайн.
Название: Re: Скрипт через некоторое время перестает менять объект.
Отправлено: Simple-Scada от 22 Июля 2024, 12:41:27
Цитировать
иначе бы "встало колом" все.
У Вас в проекте уже всё "встало колом". Скрипты (в количестве более 60 тысяч) периодически не выполняются из-за переполнения очереди, это основная проблема и её нужно решать в первую очередь. Если она не заметна на взгляд для каких-то объектов, значит она "решается" повторным вызовом скрипта (сразу после очистки очереди), по какому либо событию. Для объектов у которых скрипт вызывается редко "проблема" сразу будет заметна.

Цитировать
Более того, если на "залипшем" объекте произвести некоторые манипуляции, а именно вывести его программно из работы и обратно включить, то статусы начитают опять работать в режиме онлайн.
Конечно, ведь этими действиями Вы принудительно вызываете скрипт, он ставится в очередь снова и вызывается, что выглядит как исправление "проблемы".
Название: Re: Скрипт через некоторое время перестает менять объект.
Отправлено: Daniil от 22 Июля 2024, 12:43:08
Проверил один из проблемных скриптов (выкладываю его код сюда).
Не вижу грубых ошибок и вероятных рекурсий.
Может опытный взгляд поможет?
Но да - он привязан к переменной - которая измеряет время до конца (или от начала) процесса в секундах. Отчего и часто вызывается.

Код: (delphi)
var
  time: TDateTime;
  textVOH, textVOM, textVOS, textVO: TM_Field;

begin
  textVOH := GetTemplateObject('txtAC_1M_3FLAP_2H_1AI_WndTimeLeftHours') as TM_Field;
  textVOM := GetTemplateObject('txtAC_1M_3FLAP_2H_1AI_WndTimeLeftMinutes') as TM_Field;
  textVOS := GetTemplateObject('txtAC_1M_3FLAP_2H_1AI_WndTimeLeftSeconds') as TM_Field;
  textVO := GetTemplateObject('txtAC_1M_3FLAP_2H_1AI_WndTimeLeft') as TM_Field;

  if (textVO <> nil) then
  begin
    with (Sender as TM_Object) do
      if (GetVariableByID(textVO.Variable.ID).Value <> 0) then
      begin
        time := SecondsToDateTime(GetVariableByID(textVO.Variable.ID).Value);
        textVOH.Text := inttostr(time.HourOf);
        textVOM.Text := inttostr(time.MinuteOf);
        textVOS.Text := inttostr(time.SecondOf);
      end
      else
      begin
        textVOH.Text := '0';
        textVOM.Text := '0';
        textVOS.Text := '0';
      end;
  end;

end.
Название: Re: Скрипт через некоторое время перестает менять объект.
Отправлено: Timothy Clement от 22 Июля 2024, 13:44:13
Добрый день. Криминала да, особо не видно. Так замечание, можно было использовать 1 поле для отображения времени и получать значение используя функцию SecondsToStr(). Время отображалось бы в виде ЧЧ:ММ:СС, если это приемлемо для вашего проекта.
Ещё можно не играться с шаблонными объектами, а попробовать просто сделать скрипт "Изменились переменные" и туда загнать все переменные времени
Название: Re: Скрипт через некоторое время перестает менять объект.
Отправлено: Simple_Scada от 26 Июля 2024, 11:17:42
Здравствуйте.

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

В приведенном Вами скрипте рекомендуем заменить "GetVariableByID(textVO.Variable.ID).Value" на "textVO.Value". В данном случае поиск переменной по ID не имеет смысла, т.к. переменная изначально известна и связана с объектом textVO.