Управление задачами Vijeo Citect 7.40

Обсуждение SCADA-систем: Citect SCADA, Vijeo Citect, CitectSCADA, CitectFacilities, PowerLogic SCADA, PowerSCADA, MX4SCADA, Desigo Insight, Vijeo Look и HMI: Vijeo Designer, Operator Terminal Expert.
kvn
Сообщений в теме: 8
Сообщения: 105
Зарегистрирован: 08 сен 2015, 12:12
Откуда: Екатеринбург
Благодарил (а): 10 раз

Управление задачами Vijeo Citect 7.40

#1

Сообщение kvn » 08 сен 2015, 12:18

Добрый день!
Требуется выполнить остановку и последующий запуск функции.

• Функция idTask_Change_state запущена как задача с использованием TaskNew –

FUNCTION
idTask_Change_state(STRING sTP, STRING sRU, STRING sCN)
hTask = TaskNew("idChange_state_0","^""+sTP+"^",^""+sRU+"^",^""+sCN+"^"", 8);
END

• Остановка и последующий запуск idTask_Change_state должен выполняться в следующей функции idManual_Input -

INT hTask = -1;
FUNCTION
idManual_Input(STRING TP, STRING RU, STRING CN, STRING SH, INT nManual_input)

INT nSignal;

IF nManual_input = 2 THEN

//Остановка выполнения функции idTask_Change_state
nSignal = TaskGetSignal(hTask);
IF nSignal = 0 THEN
WHILE nSignal <> 1 DO
TaskSetSignal(hTask, 1);
nSignal = TaskGetSignal(hTask);
END
END

//---------Следуют выполнения необходимых действий при остановленной idTask_Change_state---

//Запуск функции после остановки
TaskSetSignal(hTask, 0);

//----------Следуют дальнейшие действия функции idManual_Input

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



Аватара пользователя
alex
Администратор
Сообщений в теме: 7
Сообщения: 1818
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 53 раза
Поблагодарили: 116 раз
Контактная информация:

Re: Управление задачами Vijeo Citect 7.40

#2

Сообщение alex » 09 сен 2015, 12:44

Вот вариант, как правильно использовать выше задействованные функции для работы с задачами в Vijeo Citect:
//
// (C) 2015 http://forum.proasutp.com
//

// Используемые константы

MODULE INT CONST_HANDLE_IS_BAD = -1;
MODULE INT CONST_HANDLE_IS_NOT_INIT = 0;

MODULE INT CONST_TASK_IS_OPERATE = 0;
MODULE INT CONST_TASK_IS_NOT_OPERATE = 1;

// Храним хендл запущенной задачи

MODULE INT hHandle = 0;

// Функия, которая будет выполняться в виде отдельной задачи. Просто инкремент тега

FUNCTION BackgroundTask (STRING TagName = "")

    INT TaskOperateStatus = 0;
   
    WHILE True DO
       
        IF TagName <> "" THEN

            TaskOperateStatus = TaskGetSignal(TaskHnd());
   
            IF TaskOperateStatus = CONST_TASK_IS_OPERATE THEN
   
                TagWrite(TagName, StrToInt(TagRead(TagName)) + 1);
               
            END
   
        END
   
    SleepMS (500);
   
    END
   
END

// Запуск функции в виде задачи

FUNCTION CreateBackgroundTask ()

    IF hHandle = CONST_HANDLE_IS_NOT_INIT THEN

        hHandle = TaskNew("BackgroundTask","Tag1",0);
       
    END

END

// Приостановка выполнения задачи

FUNCTION StopBackgroundTask ()

    INT TaskOperateStatus = 0;

    IF hHandle <> CONST_HANDLE_IS_BAD THEN
   
        TaskOperateStatus = TaskGetSignal(hHandle);
       
        IF TaskOperateStatus = CONST_TASK_IS_OPERATE THEN

            TaskSetSignal(hHandle,CONST_TASK_IS_NOT_OPERATE);

        END
       
    END
   
END

//Возобновление выполнения задачи

FUNCTION StartBackgroundTask ()

    INT TaskOperateStatus = 0;

    IF hHandle <> CONST_HANDLE_IS_BAD THEN
   
        TaskOperateStatus = TaskGetSignal(hHandle);
       
        IF TaskOperateStatus = CONST_TASK_IS_NOT_OPERATE THEN

            TaskSetSignal(hHandle,CONST_TASK_IS_OPERATE);

        END
       
    END

END



kvn
Сообщений в теме: 8
Сообщения: 105
Зарегистрирован: 08 сен 2015, 12:12
Откуда: Екатеринбург
Благодарил (а): 10 раз

Re: Управление задачами Vijeo Citect 7.40

#3

Сообщение kvn » 10 сен 2015, 08:08

ОК! Спасибо за пример!
Начинаю реализовывать на своей задаче.
А как понимать результат приостановки задачи (TaskSetSignal(hHandle,CONST_TASK_IS_NOT_OPERATE);)?
Задача приостановится когда функция запускаемая как задача BackgroundTask завершится на своем последнем END?
Или в непредсказуемом месте?



Аватара пользователя
alex
Администратор
Сообщений в теме: 7
Сообщения: 1818
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 53 раза
Поблагодарили: 116 раз
Контактная информация:

Re: Управление задачами Vijeo Citect 7.40

#4

Сообщение alex » 10 сен 2015, 08:48

В ниже следующем участке кода фоновой задачи:
TaskOperateStatus = TaskGetSignal(TaskHnd());        
 IF TaskOperateStatus = CONST_TASK_IS_OPERATE THEN
        TagWrite(TagName, StrToInt(TagRead(TagName)) + 1); // здесь можно разместить код, выполнением которого нужно управлять через сигналы.
 END

Контролируется состояние сигнала, установленного для этой функции, если Вы устанавливаете сигнал в значение CONST_TASK_IS_NOT_OPERATE (т.е. 1), следующий код конечно не выполняется, т.е. таким образом, Вы управляете выполнение того что находится внутри условного оператора IF ... THEN ... END. Что бы проинформировать внешнюю задачу об своей остановке, данная задача тоже может выставить, в свою очередь, сигнал внешней что она перешла в режим остановки. Думаю что идея понятна.



kvn
Сообщений в теме: 8
Сообщения: 105
Зарегистрирован: 08 сен 2015, 12:12
Откуда: Екатеринбург
Благодарил (а): 10 раз

Re: Управление задачами Vijeo Citect 7.40

#5

Сообщение kvn » 10 сен 2015, 15:28

Ваш пример у меня заработал.
А вот свою функцию с ее запуском-остановкой по аналогии с примером остановить не удается.
Функция idChange_state_0 производит отслеживание изменения состояния дискретного сигнала и при этом событии запускает функцию idEvtHandle_0 производящую операцию сравнения меток времени события (предыдущей и новой).

Код: Выделить всё

INT
FUNCTION
idChange_state_0(STRING sTP, STRING sRU, STRING sCN)
STRING sQF_on_off_field = sTP + "_" + sRU + "_" + sCN + "_QF_on_off.field";
INT TaskOperateStatus = 0;
INT subsHandle;
  WHILE True DO
  TaskOperateStatus = TaskGetSignal(TaskHnd());
        IF TaskOperateStatus = CONST_TASK_IS_OPERATE THEN     
            subsHandle = TagSubscribe(sQF_on_off_field, 500, "Eng", 0.1, "idEvtHandle_0", 0);
              RETURN subsHandle;
            TagUnsubscribe(subsHandle);
        END
    SleepMS (500);
  END           
END



Аватара пользователя
alex
Администратор
Сообщений в теме: 7
Сообщения: 1818
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 53 раза
Поблагодарили: 116 раз
Контактная информация:

Re: Управление задачами Vijeo Citect 7.40

#6

Сообщение alex » 11 сен 2015, 08:51

Благодаря этому:

Код: Выделить всё

RETURN subsHandle;

У Вас функция выполниться только один раз и то не до конца (не выполниться еще оператор TagUnsubscribe(subsHandle)).



kvn
Сообщений в теме: 8
Сообщения: 105
Зарегистрирован: 08 сен 2015, 12:12
Откуда: Екатеринбург
Благодарил (а): 10 раз

Re: Управление задачами Vijeo Citect 7.40

#7

Сообщение kvn » 11 сен 2015, 09:19

Да! Я момент не нужности возвращения SubsHandle тоже определил.
Спасибо.
А вот где выполнять отписку хендл TagUnsubscribe(subsHandle)?
После завершения функции idEvtHandle_0 наверное?
Пока не понимаю....
Задача теперь останавливается и запускается. Наблюдаю по увеличению на единицу через 500 мс значения hSubsHandle_0.
Код поправил - теперь он такой -

Код: Выделить всё

MODULE INT hSubsHandle_0 = 0;

FUNCTION
idChange_state_0(STRING sTP, STRING sRU, STRING sCN)
STRING sQF_on_off_field = sTP + "_" + sRU + "_" + sCN + "_QF_on_off.field";
INT TaskOperateStatus = 0;

  WHILE True DO
  TaskOperateStatus = TaskGetSignal(TaskHnd());
        IF TaskOperateStatus = CONST_TASK_IS_OPERATE THEN     
            hSubsHandle_0 = TagSubscribe(sQF_on_off_field, 500, "Eng", 0.1, "idEvtHandle_0", 0);                         
           
        END
    SleepMS (500);
  END           
END

Да, еще как вводится код в раскраске?



kvn
Сообщений в теме: 8
Сообщения: 105
Зарегистрирован: 08 сен 2015, 12:12
Откуда: Екатеринбург
Благодарил (а): 10 раз

Re: Управление задачами Vijeo Citect 7.40

#8

Сообщение kvn » 11 сен 2015, 10:41

TagUnsubscribe(hSubsHandle_0) выполнил в конце функции idEvtHandle_0.
Задача останавливается и запускается.
А как скажется на работе SCADA в целом изменение (увеличение на 1) hSubsHandle_0 при циклическом выполнении функции TagSubscribe?
Или это не создает больших нагрузок на сервер и нормально?
При этом я предполагаю еще запускать аналогичные Задачи (количеством 5- 10 шт)....



Аватара пользователя
alex
Администратор
Сообщений в теме: 7
Сообщения: 1818
Зарегистрирован: 05 апр 2010, 21:58
Откуда: Москва
Благодарил (а): 53 раза
Поблагодарили: 116 раз
Контактная информация:

Re: Управление задачами Vijeo Citect 7.40

#9

Сообщение alex » 11 сен 2015, 12:05

TagSubscribe и TagUnsubscribe - необходимы для однократной подписки и отписки на изменения тега, в цикле вызывать любую из них без другой неправильно. Регулярный вызов TagSubscribe и TagUnsubscribe для однократного отслеживания изменения тега не очень хорошая практика. С моей точки зрения более правильно построить логику так, чтобы Вы однажды (например при старте проекта) подписались на изменение нужных тегов (почему, кстати не использовать события Citect Project Editor -> System -> Events для отслеживания изменений тегов), а при завершении работы проекта отписались от них.

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

p.s. По поводу раскраски кода можно посмотреть как здесь.



kvn
Сообщений в теме: 8
Сообщения: 105
Зарегистрирован: 08 сен 2015, 12:12
Откуда: Екатеринбург
Благодарил (а): 10 раз

Re: Управление задачами Vijeo Citect 7.40

#10

Сообщение kvn » 11 сен 2015, 13:31

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

Если начну использовать штатные Events - каким образом получиться отключать визуализацию?
Исходя из этого - решил не использовать штатный механизм Events и создать собственный....




Если эта тема может быть полезна другим, поделитесь ссылкой:

Вернуться в «Citect SCADA, Vijeo Citect, CitectSCADA, CitectFacilities, PowerLogic SCADA, PowerSCADA, MX4SCADA, Desigo Insight, Vijeo Look, Vijeo Designer, Operator Terminal Expert»