Dans la partie précédente, nous avons terminé la visualisation de la vanne et créé un script simple qui simule son comportement.
Nous avons un panneau appelé Flap, qui affiche et envoie des commandes pour une vanne - Flap1. Ce point de données est spécifié dans tous les scripts de ce panneau. Une question naturelle se pose: que faire s'il y a plus d'une valve? Et même pas deux. Et plusieurs dizaines, centaines et même milliers (pour un système distribué WinCC OA et plusieurs millions de signaux ne sont pas un frein, on regarde le Large Hadron Collider, où ce système est utilisé, et on envie).
L'option évidente est de créer plusieurs dizaines, centaines et milliers de panneaux, où chaque point de données est donné explicitement, nous le balançons - c'est long, gênant et menace d'énormes coûts de main-d'œuvre en cas de moindre changement inévitable pendant le NDP.
Une autre option, mais pas la seule, consiste à créer un modèle basé sur un panneau existant. Créons une copie du panneau Flap existant en sélectionnant l'élément de menu Panneau → Enregistrer le panneau sous. Définissons le nom Panel_ref.pnl (la fin _ref implique une référence, c'est-à-dire un lien, ou, si vous le souhaitez, un modèle)
Ouvrons le panneau Flap_ref (il devrait quand même être ouvert après l'enregistrement). Modifions les scripts du panneau en choisissant Edition → Modifier les scripts du panneau dans le menu. Une fenêtre s'ouvrira contenant tous les scripts de toutes les primitives graphiques de ce panneau.
, , . , .. : 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»). , .
Du fait que nous avons une configuration avec une fonction définie sur la position DPE, la troisième vanne n'est pas encore affichée à l'écran (en fait, je l'ai en vain ajoutée au modèle).