Установка триггеров программно
Людмила; 26.10.04

Проблема такая: есть gscAction, при определенных условиях он не должен вызываться, а при других условиях должен отрабатывать каждые 10 секунд.

Сейчас проверка условия идет внутри gscAction, но таких функций много и это по моему грузит проект. У кого-нибудь есть опыт установки триггера программно, через кнопку на рисунке?
Re: Установка триггеров программно
Alexis; 27.10.04

Вопрос интересный - непонятно только наличие большого множества таких Actions, неужели нельзя уменьшить их количество? Непонятна задача и требования к этим Action, поэтому сразу трудно предложить путь изврата.

Как вариант:
есть одна циклическая action (ваши 10 секунд) которая смотрит на тэг взводимый с картинки и в случае взвода начинает изменять фронт второго тэга - а на изменение второго тэга и подвешаны ваши actions. Подойдет?
Re: Установка триггеров программно
Людмила; 27.10.04

Мысль очень интересная, как вариант это лучше, чем было, спасибо. Попробую. Просто проект не мой, поэтому больших переделок делать не хотелось бы.

В ODK я раскопала очень интересную функцию. Ее использование, по-моему, более эффективно:

LPACTION GSCGenDeleteTrigger (
LPGSC_TRIGGER pGenGT,
AllocAppMem lpfnAllocAppMem,
LPCMN_ERROR lpdmError)

Но у меня она не работает. Примера нет, и я не понимаю, второй параметр.
WinCC ругается: 'GSCGenDeleteTrigger': unresolved external function
====================================OnErrorExecute====================================
dwErrorCode1: (ThreadId 3100) 1007001
dwErrorCode2: (ThreadId 3100) 4099
szErrorText: (ThreadId 3100) Exception in Action
szErrorTextException: (ThreadId 3100) unresolved external function or variable
szApplicationName: (ThreadId 3100) PDLRuntimeSystem
bCycle: (ThreadId 3100) acycle

Может надо как-то объявить ее, может дополнительно какие-то действия нужны. Очень хотелось бы узнать.
Re: Установка триггеров программно
Alexis; 27.10.04

А таким образом объявлять не пробовали:

#pragma code("gscgen.dll")
#include "capigsc.h"
#pragma code()

Второй параметр - это
typedef LPVOID (* OUTSIDE AllocAppMem)(size_t nSize);
те Вам надо передать указатель на функцию, которая заведует захватом памяти, что-то типа стандартного:
void* malloc(size_t size);
это для того чтобы выбитая память в GSCGenDeleteTrigger (и другими подобными фунцайками) была освобождена Вами по заданным Вами же законам, например стандартная связка malloc/free.

Скажу сразу, я с этим семейством функций не работал, и работать не собираюсь, так как предпочитаю использовать вместо недоразвитых скриптов внешний код.
Re: Установка триггеров программно
Людмила; 27.10.04

Объявляла я именно так как Вы пишете.

А вот второй параметр я указала неверно. А "внешний код" вы имеете ввиду собственные dll или даже exe написанные на VB, VC++, Builder, Delphi? Все равно вы, наверное, при этом используете функции ODK?
А задача у меня такая: куча контроллеров опрашивается в цикле. Иногда необходимо установить с одним из них связь и опрашивать каждые 10 сек. Соответствующий action этого контроллера обновляет теги,
делает кое-какие расчеты и т.д. На данный момент каждый такой action вызывается каждые 10 сек и в теле проверяется отрабатывать или закончить работу. Мысль такая: триггеры не ставлю, пока нет постоянной связи. Как только появилась необходимость поддержать постоянную связь с контроллером, устанавливаю на соответствующий action триггер с циклом опроса 10 сек.
Re: Установка триггеров программно
Людмила; 27.10.04

Если есть возможность, не приведете ли пример по фразе: Второй параметр - это

typedef LPVOID (* OUTSIDE AllocAppMem)(size_t nSize); Не могу понять суть: а сколько памяти надо отвалить? Размер передаваемой структуры?

Re: Установка триггеров программно
Alexis; 27.10.04

Внешний - это естественно свои exe, dll, ocx; и естественно все взаимодействие с WinCC через ODK.


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

В случае GlobalScript необходимо предоставить функции для работы с памятью, например у WinCC есть внутренние стандартные (см Internal\allocate) функции:
void* SysMalloc(unsigned long int size);
void SysFree(void* lpFree);
то есть Вы можете передавать SysMalloc в качестве второго параметра, и очищать возвращаемый Вам указатель используя SysFree.

А как в WinCC связь с контроллерами то организована?
Re: Установка триггеров программно
Людмила; 27.10.04

Если есть возможность, не приведете ли пример по фразе: Второй параметр - это

typedef LPVOID (* OUTSIDE AllocAppMem)(size_t nSize); Не могу понять суть: а сколько памяти надо отвалить? Размер передаваемой структуры?

Re: Установка триггеров программно
Людмила; 27.10.04

Спасибо, ситуация проясняется. Только пока все равно не могу понять сколько памяти я должна захватить, ведь void* SysMalloc(unsigned long int size);в качестве параметра требует указать размер.


А в WinCC связь с контроллерами через ОРС сторонних организаций. Сами конроллеры подключены в локалку.

Re: Установка триггеров программно
Alexis; 27.10.04

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


Заглянул в ОДКу, там есть какие-то функции типа APActive/APInactive, APStart и APTransAct - может они вам нужны? Правда неразжеваны они нифига, надо методом научного тыка их изучать :))
Re: Установка триггеров программно
Людмила; 27.10.04

Про эти функции я тоже думала, но они еще более непонятны. Примера нет. А так может быть их даже более удобно было бы использовать.Вот, например, второй параметр "Number of actions". Я например незнаю, как получить этот номер. Такую тему я подняла в форуме, но пока никто не ответил. Хоть бы малюсенький примерчик.

Alexis, большое вам спасибо, теперь я хоть знаю ( или кажется, что знаю ) направление куда двигаться. Сейчас буду пробовать применить полученные знания.
Re: Установка триггеров программно
Людмила; 27.10.04

Спасибо, ситуация проясняется. Только пока все равно не могу понять сколько памяти я должна захватить, ведь void* SysMalloc(unsigned long int size);в качестве параметра требует указать размер.


А в WinCC связь с контроллерами через ОРС сторонних организаций. Сами конроллеры подключены в локалку.

Re: Установка триггеров программно
Alexis; 27.10.04

Заинтересовали Вы меня этими стартами-остановами...

Попробовал такую штуку - крутится циклический action и мне удалось усыпить и востановить его циклическую работу с помощью связки функций ApInactive/ApInactive. Единственное, это удалось через ID, через имя пока не получается... Либо надо где-то взять ID :), либо заставить его проглотить имя...
Re: Установка триггеров программно
Людмила; 27.10.04

А где Вы взяли ID для ApInactive/ApInactive? Примерчик скиньте, хоть по e-mail. А я функцию GSCGenDeleteTrigger вставила в Global Action ( до этого я ее пихала в project function), теперь WINCC не ругается, но выскакивает ошибка глобальная Script.exe out memory


int gscAction( void )
{
#pragma code("gscgen.dll")
#include "capigsc.h"
#pragma code()


GSC_TRIGGER GenGT;
CMN_ERROR pError;
LPACTION pvAction;

SYSTEMTIME date;
memset( &GenGT, 0, sizeof(GenGT) );
memset( &date, 0, sizeof(date) );

GenGT.ptGSCDateTime = &date;
GenGT.pAction = "Test.pas";
GenGT.pszTriggerName = "10 s";
GenGT.dwGSCTriggerType = AP_TT_USER_DEF;

pvAction = GSCGenDeleteTrigger( &GenGT, malloc, &pError);

return 0;
}
Re: Установка триггеров программно
Alexis; 28.10.04

Насчет ID - их можно посмотреть в стандартном элементике GSC Run Time.

Насчет ApActive/ApInactive - я еще покопаюсь, потом сюда примерчик закину.

А насчет Вашего примерчика:
LPACTION pvAction=NULL;
...
pvAction = GSCGenDeleteTrigger( &GenGT, malloc, &pError);
if ( pvAction!=NULL )
{
// я думаю это надо зачищать
free(pvAction);
}
Re: Установка триггеров программно
Людмила; 28.10.04

Я поставила отладочные сообщения до и после вызова этой функции:

printf("111111 \r\n");
pvAction = GSCGenDeleteTrigger( &GenGT, malloc, &pError);
printf("222222 \r\n");
так сообщение "out of memory" выходит между ними. Значит ошибка где-то в параметрах.
А ID Вы впихиваете вручную, уже после запуска, когда можно их увидеть?
Re: Установка триггеров программно
Alexis; 28.10.04

ID-шники присваиваются при старте проекта, так как я их пока не могу получить программно, то естественно приходится загонять их ручками.

Кстати, может попробуете вместо malloc передать SysMalloc...

Вот вам примерчик с ApActive/ApInactive, надо передать ID и FALSE - остановка, TRUE - запуск
//-----------------------------------
BOOL actionMgr(DWORD dwID, BOOL bActive)
{
#pragma code("apclient.dll")
#include "ap_def.h"
#pragma code()

CMN_ERROR dmError;
AP_ACT_KEY apk;
BOOL bRet=FALSE;

printf("ap-connecting...\r\n");
memset(&dmError,0,sizeof(CMN_ERROR));
if ( APConnect("AktSteu",NULL,NULL,NULL,&dmError)==FALSE )
{
printf("ap-connect failed:\r\n");
printf("E1=0x%X E2=0x%X E3=0x%X E4=0x%X E5=0x%X\r\n",dmError.dwError1,dmError.dwError2,dmError.dwError3,dmError.dwError4,dmError.dwError5);
printf("Text: %s\r\n",dmError.szErrorText);
return bRet;
}
else printf("ap-connect OK\r\n");

memset(&apk,0,sizeof(AP_ACT_KEY));
apk.dwKeyType=AP_ID_TYPE;
apk.dwID=dwID;

if ( bActive )
{
printf("ap-activing...\r\n");
memset(&dmError,0,sizeof(CMN_ERROR));
if ( ApActive(&apk,1,NULL,NULL,NULL,&dmError)==FALSE )
{
printf("ap-active failed:\r\n");
printf("E1=0x%X E2=0x%X E3=0x%X E4=0x%X E5=0x%X\r\n",dmError.dwError1,dmError.dwError2,dmError.dwError3,dmError.dwError4,dmError.dwError5);
printf("Text: %s\r\n",dmError.szErrorText);
}
else { printf("ap-active OK\r\n"); bRet=TRUE; }
}
else
{
printf("ap-inactiving...\r\n");
memset(&dmError,0,sizeof(CMN_ERROR));
if ( ApInactive(&apk,1,NULL,NULL,NULL,&dmError)==FALSE )
{
printf("ap-inactive failed:\r\n");
printf("E1=0x%X E2=0x%X E3=0x%X E4=0x%X E5=0x%X\r\n",dmError.dwError1,dmError.dwError2,dmError.dwError3,dmError.dwError4,dmError.dwError5);
printf("Text: %s\r\n",dmError.szErrorText);
}
else { printf("ap-inactive OK\r\n"); bRet=TRUE; }
}

printf("ap-disconnecting...\r\n");
memset(&dmError,0,sizeof(CMN_ERROR));
if ( APDisconnect(NULL,NULL,NULL,&dmError)==FALSE )
{
printf("ap-disconnect failed:\r\n");
printf("E1=0x%X E2=0x%X E3=0x%X E4=0x%X E5=0x%X\r\n",dmError.dwError1,dmError.dwError2,dmError.dwError3,dmError.dwError4,dmError.dwError5);
printf("Text: %s\r\n",dmError.szErrorText);
}
else printf("ap-disconnect OK\r\n");

return bRet;
}
//-----------------------------------

осталось только ID определить, либо заставить ApActive/ApInactive через имя работать :))
Кстати, я пиво люблю...
Re: Установка триггеров программно
Людмила; 28.10.04

SysMalloc я тоже вставляла, та же петрушка. Здесь надо, видимо, идти другим путем. Может структуру триггера определяю неправильно. В этом направлении повозиться.

А как любой программер, не люблю ничего вводить ручками. Это не есть хорошо. Программа должна сама все делать после одного щелчка мышки.
А пиво - это хорошо, только Вы ж не до конца программу доделали :((. Правда, идеи Вы подкидывали интересные, спасибо. Так мне как через интернет-магазин бежать за пивом или по телефону можно?
Re: Установка триггеров программно
Alexis; 28.10.04

Виртуальное пиво - это не серьезно :))

На счет моей фунцайки:
вместо -
memset(&apk,0,sizeof(AP_ACT_KEY));
apk.dwKeyType=AP_ID_TYPE;
apk.dwID=dwID;
можно определять так -
memset(&apk,0,sizeof(AP_ACT_KEY));
apk.dwKeyType=AP_NAME_TYPE;
strcpy(apk.szActionName,"имя!");
НО ТРАБЛ! Непонятно как правильно задать имя, типа actionname.pas или actionname не прокатывает.
Надо в wincc-hotline писать, вдруг да они знают :))
Re: Установка триггеров программно
Alexis; 29.10.04

Как это не печально, но я временно прекращаю ковырятся в данном направлении:

- во первых, на мой вопрос в hotline, как для Action-Name получить Action-ID и почему ApActive/ApInactive не работают с AP_ACT_KEY.dwKeyType=AP_NAME_TYPE, пришел как всегда исчерпывающий ответ "It seems it is a bug. I contact the WinCC development an give you a feedback as soon as possible." - подождем...
- а во вторых - я в отпуск ухожу...

На счет моей - BOOL actionMgr(DWORD dwID, BOOL bActive) - будем считать ее доделанной, естественно только для Action-ID :))
Кстати, из той же серии функций, есть хорошая функция APStart - которая просто позволяет запускать скрипты, и что самое важное, откуда угодно (в смысле как изнутри WinCC, так и из внешних приложений) - в общем хорошо, что Вы развели меня на изучение данного раздела ОДКи :))
Re: Установка триггеров программно
Людмила; 29.10.04

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

А если Вам пришлют оттуда (hotline) ответ, все равно мы узнаем об этом только после Вашего отпуска? Очень надеюсь, что Вы нас не забудете, и если Вам пришлют информацию даже после отпуска, Вы ею поделитесь с нами на страницах этого замечательного форума.
А вообще я удивлена, что никого не заинтересовала эта тема. Ведь можно получить очень гибкий проект. Я сейчас копаюсь над этими функциями в VC++ 6.0. Раскопала ихний пример на VC++5. Он очень огромный и выдает ошибки с самого начала. Ошибка вылезает в wingdi.cpp. А по исходникам читаю, что параметры предлагают загонять ручками. А как раз затык-то в параметрах. Пока успехов нет. Желаю всего хорошего. Еще раз спасибо за участие в моей судьбе.
Re: Установка триггеров программно
Людмила; 29.10.04

В догонку:

Alexis, не могли бы вы дать ссылку на hotline ( быстро не смогла найти где это, а интернета мало чтобы долго искать ). Хочу спросить все-таки про GSCGenDeleteTrigger. А им нужно писать на каком языке вопрос?
Re: Установка триггеров программно
Alexis; 29.10.04

Принимая во внимание Ваше время появления в форуме и дождь за окном, я начинаю подозревать, что мы находимся чуть ли не в одном городе :) а это вселяет надежду на невиртуальное пиво :)

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

А что за примерчик раскопали?
Re: Установка триггеров программно
Alexis; 29.10.04

Ну я обычно пишу на wincc.odk-hotline@siemens.com и естно на английском.

Re: Установка триггеров программно
GorA; 29.10.04

Возвращаясь к начальному вопросу

"...У кого-нибудь есть опыт установки триггера программно, через кнопку на рисунке?"
Можно сделать проще - создать локальный ТЭГ (или сколько нужно ТЭГов) и по кнопке записывать туда "1", "0", что хотите, а затем использовать в других программах и скриптах.
Re: Установка триггеров программно
Людмила; 29.10.04

GorA: Вы потеряли идею, предлагая такой вариант. Да, я могу запустить action по изменению тега, определяя это в триггере. Но мне не это нужно. У меня есть action, который иногда должен вызываться каждые 10 секунд (ставлю триггер Timer->Cyclic->10 s), а некоторое время вообще не вызываться. Я, наверное, не правильно поставила вопрос о кнопке. Скорее так: установка триггера через функции ODK.

Re: Установка триггеров программно
Людмила; 29.10.04



Re: Установка триггеров программно
Alexis; 29.10.04

Ха! они признались "...it is a bug in ODK..." дык значит этот баг уже лет пять кочует от версии к версии...


2 Людмила: То что версия у Вас 5.1 - это не страшно, должно работать. Мне же интересны идеи и предложения - стоит ли вообще проект продолжать... Кстати, запуск/останов actions я уже намерен туда вставить, вещь иногда полезная...
А примерчика я такого что-то не видел...
Re: Установка триггеров программно
Людмила; 29.10.04

А может с функцией GSCGenDeleteTrigger тоже баг. Может никто этим вообще не занимался. Все выкручивались как могли подручными средствами. А когда они исправят? А не могут ли они подсказать тогда как найти через функции этот самый ID для AP_ID_TYPE?

Re: Установка триггеров программно
Alexis; 29.10.04

Скорее всего никто и не занимался - Вы первая :)

А вот как найти ID - это вопрос... Ихний GSC Run Time откуда-то их берет... Но этим я уже только через пару недель займусь... А может Вы уже найдете... Рекоммендую с хотлайном пообщаться.
Re: Установка триггеров программно
Людмила; 29.10.04

В догонку: Кстати с Вашим, Alexis, примерчиком ApActive/ApInactive, Вы заметили, что в стандартном элементике GSC Run Time при отключении action, ее статус не меняется. Это конечно не страшно, но неправильно.

Re: Установка триггеров программно
Людмила; 29.10.04

с хотлайном пообщаться хорошо, но я понимать-понимаю по-англицки, а вот сказать плохо могу. Правописание у меня хорошее, но почему-то хромает. Не знаете, как это они воспримут?

Re: Установка триггеров программно
Alexis; 29.10.04

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


А Вы попробуйте в GSC Run Time застопорить акцию, ее статус изменится на deactivated и в конткстной менюшке будет разрешенно только стартовать данную акцию. Теперь если закрыть GSC Run Time, а потом снова открыть, то оно будет в наглую считать, что акция работает и будет предлагать только останов. Эт я к чему, они похоже сами точно не знают в каком состоянии их actions... В их APCLIENT.DLL есть две неописанные функции APGetNotify/APSetNotify причем насколько я понял GSC Run Time работает именно через них, посколько GSCRTCLI.DLL (а это и есть GSC Run Time) явно использует APSetNotify.
Re: Установка триггеров программно
GorA; 29.10.04

Как раз все и нормально.

Пишется первый скрипт, который вызывается раз в 10 секунд.
В нем анализируется ТЭГ включения требуемой акции, и если он, например, =TRUE - , то и вызывать нужную акцию, а если =FALSE - не вызывать.

Re: Установка триггеров программно
Людмила; 1.11.04

Если ничего так и не получиться узнать, почему правильно не работают ODK-шные функции, то так и придется сделать, как Вы, GorA, предлагаете. Это оптимальное решение. Но здесь есть но... Как вызывать нужную акцию. Если по изменению тега, то не всегда нужная Global action вызывается моментально при изменении тега, иногда доходит до минуты и более. Если только нужные функции в project functions затолкать. А самое главное - это нерационально, и не оптимально, что функция будет вызываться каждые 10 сек чаще всего в холостую. И может ей придется работать в холостую неделями. А так я бы ее отключила а когда надо включила. И если она мне в данный момент не нужна, лишние ресурсы бы не тратились, а использовались на другие задачи более рационально. Согласитесь, что это решение намного красивее.

Re: Установка триггеров программно
GorA; 1.11.04

Самое лучшее, на мой взгляд, всю логику управления перенести в PLC. И работа будет устойчевее и логику переключений, включений, вызовов реализовывать проще.

Re: Установка триггеров программно
Alexis; 2.11.04

2 GorA:

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

2 Людмила:
Как предлагает GorA - вызов функций по TRUE/FALSE - вроде как неопределенность получается, если основной "10-секундный распределитель задач" не успеет отработать за 10 секунд (типа на все сто контроллеров надо сделать запрос данных) - к чему это приведет? Я так до конца и не понял как работает ApActive/ApInactive - в смысле дожидается ли ДеАктивация остановки акции или происходит замораживание на полпути - тоже кстати интересный вопрос...
А так-то дело за малым - как из имени идешник получить - и тему можно закрывать...
Re: Установка триггеров программно
Людмила; 3.11.04

Для добавления триггера я использовала функцию GSCGenAddTrigger из "API functions of the Global Scripts editor", а есть функция AP_GEN_AddTrigger из раздела "Functions of the Script Programming CS", она тоже добавляет триггер. Может кто знает в каких случаях, какие функции надо использовать?

А ошибку в параметрах я нашла. Теперь функция GSCGenAddTrigger отрабатывает без ошибок, но триггер не появляется,т.е. action по триггеру не отрабатывает.

Re: Установка триггеров программно
Alexis; 3.11.04

Похоже функции вида GSCGen* только для CS предназначены и в RT бесполезны...

Re: Установка триггеров программно
Людмила; 3.11.04

для CS, т.е. при старте системы отрабатывают? Или когда они должны работать?

Re: Установка триггеров программно
Людмила; 3.11.04

Пусть отработает при старте. Мне интересно они вообще на что годны?

Re: Установка триггеров программно
Alexis; 3.11.04

Те по большей части они нужны для автоматизации разработки проекта.

Вы лучше узнавайте как из имени идешник сделать :)
Re: Установка триггеров программно
Людмила; 3.11.04

Да где же узнать. Я написала в "Центр технической поддержки по WinCC" wincc@industrialauto.ru. Но пока молчание. То ли вообще не получили почту, то ли не знают.

Re: Установка триггеров программно
Alexis; 3.11.04

Буржуи то не ведают что кодируют, а нашим то и подавно лень в этом разбираться...

Похоже все идет к тому, что спасение утопающих - дело рук самих утопающих...
Re: Установка триггеров программно
Людмила; 4.11.04

А если они ( wincc.odk-hotline@siemens.com )признались, что через имя у них глюк, то не могут ли они сообщить, как найти ID action. Такой вопрос Вы не задали?

Re: Установка триггеров программно
Alexis; 4.11.04

Задавал, не ответили...

Запросили мои персональные данные, я их послал, сказал что я анонимный тестер :) - наверное в черный список занесли...
Так что теперь Ваша очередь :) а я типа в отпуске...<<br>