Na parte anterior, concluímos a visualização da válvula e criamos um script simples que simula seu comportamento.
Temos um painel chamado Flap que exibe e envia comandos para uma válvula - Flap1. Este ponto de dados é especificado em todos os scripts neste painel. Surge uma pergunta natural - o que fazer se houver mais de uma válvula? E nem mesmo dois. E várias dezenas, centenas e até milhares (para um sistema distribuído WinCC OA e vários milhões de sinais não são um obstáculo, olhamos para o Grande Colisor de Hádrons, onde este sistema é usado, e invejamos).
A opção óbvia é criar várias dezenas, centenas e milhares de painéis, onde cada ponto de dados é fornecido explicitamente, nós o colocamos de lado - é longo, problemático e ameaça com enormes custos de mão de obra no caso das menores mudanças inevitáveis durante o NDP.
Outra opção, mas não a única, é criar um modelo baseado em um painel existente. Vamos criar uma cópia do painel Flap existente selecionando o item de menu Painel → Salvar painel como. Vamos definir o nome Panel_ref.pnl (a terminação _ref implica referência, ou seja, um link ou, se desejar, um modelo)
Vamos abrir o painel Flap_ref (ele deve ser aberto de qualquer maneira após salvar). Vamos editar os scripts de painel escolhendo Editar → Editar scripts de painel no menu. Uma janela será aberta contendo todos os scripts de todas as primitivas gráficas deste painel.
, , . , .. : Flap1, Flap2 Flap3 . , , Flap1 , $- ( «-»). Find&Replace . .
────────────────────────────────────────────────────────────────────────────────────────────────────
─// [RECTANGLE3] [3] - [Initialize]
// SimpleCtrlScriptStart {invalid}
main()
{
EP_setRotation();
}
void EP_setRotation()
{
dyn_errClass err;
if( !dpExists( "System1:" + $dp + ".Inputs.Position:_online.._value") )
{
setValue("", "color", "_dpdoesnotexist");
return;
}
dpConnect("EP_setRotationCB",
"System1:" + $dp + ".Inputs.Position:_online.._value");
err = getLastError();
if (dynlen(err) > 0)
setValue("", "color", "_dpdoesnotexist");
}
void EP_setRotationCB(string dp1, int iNewValue)
{
float MIN_VALUE = 0;
float MAX_VALUE = 90;
float MIN_ROTATION = 0;
float MAX_ROTATION = 90;
float fRotation;
fRotation = ( 1.0 * (MAX_ROTATION - MIN_ROTATION) / (MAX_VALUE - MIN_VALUE)) *
(iNewValue - MIN_VALUE) + MIN_ROTATION;
if (fRotation > MAX_ROTATION) fRotation = MAX_ROTATION;
else if (fRotation < MIN_ROTATION) fRotation = MIN_ROTATION;
setValue("", "rotation", fRotation);
}
// SimpleCtrlScript {EP_setRotation}
// DP {System1:" + $dp + ".Inputs.Position}
// DPConfig {:_online.._value}
// DPType {int}
// PVSSRange {0}
// Min {0}
// Max {90}
// MinRotation {0}
// MaxRotation {90}
// SimpleCtrlScriptEnd {EP_setRotation}
════════════════════════════════════════════════════════════════════════════════════════════════════
─// [PUSH_BUTTON1] [4] - [Clicked]
main(mapping event)
{
dpSet("System1:" + $dp + ".Commands.Open", 1, "System1:" + $dp + ".Commands.Close", 0);
}
════════════════════════════════════════════════════════════════════════════════════════════════════
─// [PUSH_BUTTON2] [5] - [Clicked]
main(mapping event)
{
dpSet("System1:" + $dp + ".Commands.Open", 0, "System1:" + $dp + ".Commands.Close", 1);
}
════════════════════════════════════════════════════════════════════════════════════════════════════
:
System1:Flap1.Inputs.Position:online..value
:
System1:" + $dp + ".Inputs.Position:online..value
, , (System1), $dp, , , .. — . + . . , , . $dp (Flap2, ) .
, $- . , , .
. Flaps. .
Flap_ref Flaps. $- — .
, $dp Flap1. «Save and Run in QuickTest Mode» , 1 Open Close — , . , -, , ( , , , , ).
Flap2
. (), - . ? , ( ) Flap1. .
, . , , -. dpConnect callback-, callback-. .
Control Manager (, «-num 2»). , .
Devido ao fato de termos um config com uma função definida na Posição DPE, a terceira válvula ainda não é exibida na tela (na verdade, em vão a adicionei ao modelo).