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

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

Просмотр сообщений

В этом разделе можно просмотреть все сообщения, сделанные этим пользователем.


Сообщения - strs

Страницы: [1] 2 3
1
Понял, спасибо!

2
Здравствуйте!

Подскажите, можно ли перебрать несколько однотипных переменных (объявленных в редакторе переменных) по имени в цикле?

Например, есть переменные temp0, temp1, temp2 ... temp23 типа integer, нужно в цикле for сложить их значения.

Массивы ведь на запись использовать нельзя, или я путаю?

3
Вопрос к разработчикам.
Имеется несколько 16-битных переменных, которые нужно распаковать на булевы через функцию GetBit. Скажите пожалуйста, как будет рациональнее по использованию вычислительных ресурсов - сделать для каждой по отдельному скрипту "изменились переменные", либо сделать один скрипт и проверять, какая изменилась через "if variable.Name = 'xxx' "?

4
Поскольку процесс получения состояния службы периодический и не связан с действиями оператора (как в примере), то анализ файла можно смело перенести до 55 такта (секунды).
Так и сделаю пожалуй.

Вывод названия параметра на разных языках ("Состояние" <-> "STATE") это, предположительно, отголосок локализации ОС. Я бы проверял строку на наличие подстрок ": 4  RUNNING" и ": 1  STOPPED".
Проект работает на конкретном компьютере, универсальность не требуется, поэтому усложнять лишний раз не хочется.

И ещё одна особенность автомата при запуске проекта, с вероятностью 1/30 в течение первой минуты будет выдано сообщение "Ошибка получения статуса службы опроса модемов".
Для устранения этого можно использовать условие (начальное значение переменной - 0)
Совсем не критично, перезапуски - редкое явление. Но раз есть возможность улучшить - почему бы и нет.

Спасибо!

5
Файл результата открывается как перезаписываемый - т.е. новый замещает старый. Узнать что файл обновился можно по изменению даты записи файла, она должна быть больше чем дата начала выполнения скрипта.

Все равно не понял. Мы же и так можем узнать дату файла, зная имя. Ну да ладно, в итоге привел к такому виду, вроде все работает:

Код: (delphi)
var
    aPath: String;
    i: integer;
    tempString: String;
const
    servName:string = 'iRZ_Collector_Server';
begin

if SecondOf(Now) = 0 then begin    //проверяем статус службы и создаем файл с информацией 1 раз в минуту
  aPath := GetProjectPath + 'User Files\';
  StartTime.Value := NOW;                                       // начало ожидания
// чтение состояния службы через VB скрипт для подавления вывода окна командной строки
  TextFileOpen('Service.vbs', aPath, fomRewrite, fcpUTF8);
  TextFileWriteLn('Set WshShell = CreateObject("WScript.Shell")');
  TextFileWriteLn('WshShell.Run "cmd /A /C sc query ' + servName + '> ""'                // выполнить команду чтения состояния службы
  + 'D:\Service.txt""", 0');                                                             //  и записать результат в файл
  TextFileWriteLn('Set WshShell = Nothing');
  TextFileClose;
  RunApplication(SS_SERVER_NAME, aPath + 'Service.vbs', '');    // выполнить VBS-файл

  end;

  /////////////////////////////////////////////////

   if SecondOf(Now) = 2 then begin    //считываем файл для анализа через 2 секунды после создания

    if (FileExists('Service.txt', 'D:\')) and (SecondsBetween(FileAge('D:\Service.txt'), StartTime.AsDateTime) < 10) then begin  // условия корректности файла

       TextFileOpen('Service.txt', 'D:\', fomReset, fcpCyrillic_windows866); //открываем файл

       tempString := UTF8Encode(TextFileReadLn);     //переходим к требуемой строчке в файле
       tempString := UTF8Encode(TextFileReadLn);
       tempString := UTF8Encode(TextFileReadLn);
       tempString := UTF8Encode(TextFileReadLn);
           if tempString = '        Состояние          : 4  RUNNING ' then
             begin txtService.Text := 'Служба опроса модемов работает';
                   txtService.BorderColor := clLime;
             end
           else if tempString = '        STATE              : 1  STOPPED ' then
             begin txtService.Text := 'Служба опроса модемов остановлена';
                   txtService.BorderColor := clRed;
             end
           else
             begin txtService.Text := 'Ошибка получения статуса службы опроса модемов';    //в нужной строчке не те данные, которых мы ожидали
                   txtService.BorderColor := clYellow;
             end;

        TextFileClose;          // закрыть файл
    end
    else begin txtService.Text := 'Ошибка получения статуса службы опроса модемов'; //файл не существует либо слишком старый
               txtService.BorderColor := clYellow;
         end;

    end;   // if SecondOf(Now) = 2
end.

Спасибо!

6
Пример из вложения после ввода имени службы получает её состояние.
Спасибо! Была проблема, из-за русского имени пользователя в винде не создавался текстовый файл. Но с переездом в "D:\" все заработало.
Вопрос: а зачем сканировать директорию на наличие файла, если мы точно знаем как он называется и можем открыть его напрямую?

7
Здравствуйте!

Есть необходимость видеть в интерфейсе оператора, запущена ли служба опроса модемов. Нашел пример для Делфи (приведен ниже), но не знаю, можно ли его применить в скриптах скады или это невозможно.
При попытке вставить первую часть кода в скрипт типа "глобальный модуль", получаю ошибку File "WinSvc.PCU not found".

Если напрямую в скриптах скады это сделать невозможно, может посоветуете, как по-другому можно вывести статус службы в интерфейс?
Код: (delphi)
uses
  WinSvc;
 
function ServiceGetStatus(sMachine, sService: PChar): DWORD;
{******************************************}
  {*** Parameters: ***}
  {*** sService: specifies the name of the service to open
  {*** sMachine: specifies the name of the target computer
  {*** ***}
  {*** Return Values: ***}
  {*** -1 = Error opening service ***}
  {*** 1 = SERVICE_STOPPED ***}
  {*** 2 = SERVICE_START_PENDING ***}
  {*** 3 = SERVICE_STOP_PENDING ***}
  {*** 4 = SERVICE_RUNNING ***}
  {*** 5 = SERVICE_CONTINUE_PENDING ***}
  {*** 6 = SERVICE_PAUSE_PENDING ***}
  {*** 7 = SERVICE_PAUSED ***}
  {******************************************}
 
var
  SCManHandle, SvcHandle: SC_Handle;
  SS: TServiceStatus;
  dwStat: DWORD;
begin
  dwStat := 0;
  // Open service manager handle.
  SCManHandle := OpenSCManager(sMachine, nil, SC_MANAGER_CONNECT);
  if (SCManHandle > 0) then
  begin
    SvcHandle := OpenService(SCManHandle, sService, SERVICE_QUERY_STATUS);
    // if Service installed
    if (SvcHandle > 0) then
    begin
      // SS structure holds the service status (TServiceStatus);
      if (QueryServiceStatus(SvcHandle, SS)) then
        dwStat := ss.dwCurrentState;
      CloseServiceHandle(SvcHandle);
    end;
    CloseServiceHandle(SCManHandle);
  end;
  Result := dwStat;
end;
 
function ServiceRunning(sMachine, sService: PChar): Boolean;
begin
  Result := SERVICE_RUNNING = ServiceGetStatus(sMachine, sService);
end;

Код
if ServiceRunning(nil, 'Имя службы') then
begin
{Действия если служба запущена}
end else
begin
{Действия если служба не запущена}
end;


8
Еще очень бы хотелось увидеть такую фичу: чтобы у полей отображения и ввода, шкал и прочих элементов, которые выводят на схему значение переменой была галочка "отображать в качестве подсказки описание переменной" - дабы не прописывать одно и тоже дважды.
Ну или так: если галочка "отображать подсказку" стоит, а поле "подсказка" не заполнено, выводить в качестве подсказки описание привязанной переменной.

9
Здравствуйте!

1. Очень пользователи жалуются на непонятность журнала действий оператора. Например, оператор нажал на кнопку пуска насоса, в журнале написано:

"(время) | Вася | Кнопка "B04_N3_START", переменная "B04_DO_WRITE".4: Было 0, стало 1"

Было бы гораздо удобнее, если бы у кнопки имелось поле "описание", и если оно заполнено, то выдавалось бы сообщение вида:

"(время) | Вася | Нажата кнопка "Котельная 4 Насос 3 пуск", переменная "B04_DO_WRITE".4: Было 0, стало 1"

2. То же самое при редактировании значений переменных или их границ (хотя я об этом по-моему уже писал)

3. Когда оператор квитирует аварийное сообщение, можно ли потом где-то посмотреть, какой именно оператор это сделал?

10
Здравствуйте.
Сообщения можно добавлять/редактировать без использования скриптов, через меню сообщений. Для создания множества однотипных сообщений можно использовать шаблонные сообщения.
Но при перезапуске проекта они тут же все будут выданы. Тут ключевое "IsFirstChange() = false", не понимаю, почему этого нет в стандартном функционале сообщений, как и задержек на срабатывание.

При сравнении значения переменной лучше использовать явное приведение значения переменной к нужному типу. Например, при сравнении с True/False нужно брать значение переменной переведенное в тип Boolean(свойство AsBool)
Учту, спасибо.

Для получения доступа к переменной, изменение которой привело к выполнению скрипта "изменились переменные" можно использовать параметр Variable.

Код: (delphi)
 if (Variable.AsBool = false)   and  (IsFirstChange = false) then
     AddMessageToGroup(Now, mkAlarm, 4, 'Котельная 24 - нет сети 220В!', true, true);
Спасибо!

11
Здравствуйте. Подскажите пожалуйста, в скриптах с типом события "изменились переменные" можно обратиться к этой самой переменной не по имени? Если нет, возможно ли добавить такую возможность? Поясняю: у меня есть в проекте много однотипных скриптов типа:
Код
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 - вторая и т.д. Тогда скрипт можно было бы просто копировать, заменяя сообщение и выбирая разные переменные.

12
Здравствуйте! Подскажите, есть ли возможность исследовать признак качества переменной? Например, мы считываем отдельные биты из word-переменной из OPC-сервера во внутренние булевы переменные. Нужно, чтобы если качество исходной переменной "бэд",  то и у внутренних выставлялось "бэд".

13
Здравствуйте!

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

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

Возможно Вы создаете сообщения по нарушению границ переменной? Если это так, то у переменой можно задать границы, в опции "Сообщения о нарушении границ" выбрать к примеру "Для любых границ", тогда при нарушении границ переменной будут выдаваться автоматически генерируемые сообщения о нарушении граничных значений. Там же имеется возможность задать параметр "Зона нечувствительности" используемый для выдачи сообщений о нарушении границ переменной. Параметр предназначен для того, чтобы после выхода значения переменной из состояния аварии/предупреждения она не могла вернуться в него вследствие случайных колебаний значения переменной. В настройках проекта имеется возможность задать свой текст для автоматически генерируемых сообщений о нарушении границ. Также, при необходимости можно управлять границами переменных из клиента скады.
Нет, вопрос конкретно о сообщениях, которые строятся на основе дискретных переменных.
Например: в одном проекте заказчик хочет получить сообщение, если ни один из пары насосов не работает, но при этом они работают посменно и до 15 секунд отсутствия обратной связи от двух сразу (в момент смены) допустимы. Нужно выдавать сообщение, если оба насоса выключены более 30 секунд.
Другой пример: контроль связи с удаленным прибором, отсутствие связи до минуты - допустимо, если больше - требуется выдать сообщение.

Столкнулся еще с одной проблемой с сообщениями: есть крипт, который запускается по событию "изменились переменные", который разбирает 16-битную переменную на отдельные биты. С одним из них связано сообщение, если бит=0, выдать аварию. При перезапуске проекта сообщение всегда выдается, подозреваю, потому что сообщения обрабатываются раньше, чем считывается переменная из прибора и срабатывается скрипт. Задержка здесь так же помогла бы наверное.

Вообще, в скриптах я видел возможность не выдавать сообщение, пока переменная не изменится, но в интерфейсе сообщений что-то не нашел. Поправьте, если она там есть.

15
Простите, что пишу тут так много, но таки многих вещей мне в этой скаде не хватает после перехода с других.

Например, очень еще хотелось бы добавить сообщениям параметр "задержка", чтобы оно выдавалось не сразу, а через заданное время, если условие продолжает выполняться (антидребезг опять же). Знаю, что это можно сделать через скрипт, но когда сообщений много это очень неудобно.

Если это уже есть, а я просто не нашел, прошу прощения.

Страницы: [1] 2 3