WinCC Bildwechsel bei inaktivem User

NewbieSPS

Level-1
Beiträge
19
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Sehr geehrte Forumsgemeinde,
ich habe ein neues Projekt bekommen und noch keinen richtigen Ansatz gefunden (Randnotiz: das ist mein erstes WinCC-Projekt). Deshalb bitte ich euch um eure Unterstützung.
Folgende Aufgabenstellung für WinCC V7.3+SP10:
Ich soll ein Skript erstellen, welches dazu dient auf 4 Monitoren einen zyklischen Bildwechsel durchzuführen, sobald der Benutzer inaktiv wird, also die Maus eine gewisse Zeit nicht bewegt wurde oder etwas in diese Richtung. Der Bildwechsel soll folgendem Schema folgen: Monitor 1: Bild 1; M2: B2; M3: B3; M4: B4; ->(10Minuten) M1: B2; M2: B3; M3: B4; M4: B5 usw..
Dass die Benutzerinaktivität nicht ohne Weiteres als Trigger umsetzbar ist, habe ich schon festgestellt. Falls aber jemand eine Idee hat, wäre ich durchaus nicht abgeneigt. Aber um mich mit diesem Thema nicht zu lange aufzuhalten habe ich mich dafür entschieden, dass Skript vorerst über einen Button zu triggern.
Mein nächster Problempunkt an der Geschichte ist, wie kann ich beim Bildwechsel sagen, dass das neue Bild auf einem spezifischen Bildschirm ausgegeben werden sollen?
Und mein letztes Problem ist die Wartezeit zwischen den einzelnen Bildwechseln, ich habe mir überlegt es mit einem ThreadSleep um zusetzen bis ich genauer nachgedacht habe. Denn die Bilder sollen natürlich immer noch beobachtbar sein. Kann das vielleicht mit einem Timer oder ähnlichem umgesetzt werden. (Ich kann das SPS-Programm nicht ändern)
Ich weis es scheinen Anfängerfragen zu sein, aber ich muss sagen in meiner Grundlagenschulung wurde nichts davon konkret behandelt. Deshalb bitte ich um etwas Nachsicht und eure Hilfe.
Ich bin für jeden Vorschlag dankbar.

MfG NewbieSPS
 
Ohne mich jetzt in WinCC genau auszukennen würde ich das in etwa so angehen :
Ein Tastendruck schreibt deine Delayzeit in eine Hilfsvariable.
Im Hintergrund läßt du zyklisch ein Script ablaufen, das deine Hilfsvariable dekrementiert wenn größer 0. Wurde sie dabei gleich 0 dann startest du dein Bildwechsel-Programm.
Auf diese Weise bleibt deine Anwendung weiter aktiv und responsiv.

Zu dem Teil mit dem "welches Bild auf welchen Monitor" kann ich dir leider nichts sagen ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn es um WinCC-SCADA (v7, Professional) geht dann könntest du via c-Skript auch die aktuelle Mausposition auslesen.
Zyklisch prüfen, keine Änderung, Zähler erhöhen, usw.
 
Erstmal danke für die Vorschläge die haben mich definitiv ein Stück weitergebracht.
Also meine Strategie ist jetzt ich werde alle Benutzer nach 10 Minuten Inaktivität ausloggen und einen Dummie-User der nur Rechte zum Bildwechseln und Beobachten hat über eine Aktion anmelden. Also die Aktion wird von @CurrentUser getriggert, sollte sie dann leer sein wird die Aktion ihn anmelden.
Eine zweite Aktion wird zyklisch aufgerufen und zählt dabei eine interne Variable hoch so bald der Dummie-User angemeldet ist. Über den Zähler regle ich dann meinen Pausen für den Bildwechsel.
Jetzt habe ich eigentlich nur noch das Problem mit dem Bildwechsel. Weis jemand, ob ich mit dem Befehl "SSMWorkField(SSMGetScreen(IpszPictureName), PIC_0,True)" da irgendwie weiter komme? Ich hab mir den Befehl nämlich vom Dynamic-Wizard erzeugen lassen. Allerdings weis ich jetzt nicht welchen Teil ich wie ersetzen muss, damit ich den Bildwechsel auf einem spezifischen Bildschirm durchführen kann.
Was auch gut zu wissen wäre, kann man Bildnamen (mit #define auf einen Namen PIC_0 geschrieben) in ein Array schreiben, um etwas mehr Dynamik hinzubekommen?
 
Ich habe meine C-Aktion jetzt fertig, allerdings würde ich im Bildwechselbereich des Codes gerne noch etwas ändern, weiß aber nicht genau wie ich das machen kann.
Mein Bildwechsel funktioniert mit dem Standardbefehl
Code:
 BOOL SSMChangeWorkField(TCHAR Screen, TCHAR *PictureName, BOOL Store);

Um die verschiedenen Bildern verschiedenen Zeitpunkten zu zuordnen verwende ich momentan einen "Switch-case"-Befehl. Da ich den Bereich aber gerne etwas dynamischer hätte wollte ich das mit einer Schleife lösen. Ist etwas schwer nachzuvollziehen und zu erklären warum ich das möchte, aber es ist nun einmal so.
Mein momentaner Code sieht in gekürzter Form wie folgt aus:

Code:
#define PIC_0 "Bildname0.pdl"
#define PIC_1 "Bildname1.pdl"
...
#define PIC_9 "Bildname9.pdl"

Switch(Laufvariable)
case 0: SSMChangeWorkField('1', PIC_0, TRUE);
case 1: SSMChangeWorkField('1', PIC_1, TRUE);
...
case 9: SSMChangeWorkField('1', PIC_9, TRUE);

Ich würde das jetzt gerne mit einem Array und einer Schleife lösen. So circa in dieser Art und Weise:

Code:
#define PIC_0 "Bildname0.pdl"
#define PIC_1 "Bildname1.pdl"
...
#define PIC_9 "Bildname9.pdl"

Array[0] = PIC_0;
Array[1] = PIC_1;
...
Array[9] = PIC_9;

for (int i = 0; i < 10; i++)
     SSMChangeWorkField('1',Array[i], TRUE);

Wenn ich den Grundbefehl verstanden habe dann müsste der 2. Übergabeparameter irgendetwas mit Pointern zu tun haben und ich muss gestehen, dass ich auf diesem Thema nicht sonderlich fit bin.
Also falls jemand eine Idee oder sogar die nötigen Befehle hat, um zu diesem oder einem ähnlichen Ergebnis zu kommen, wäre ich sehr dankbar.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn du eh schon Basic Process Control verwendest, dann wäre auch eine Option die gespeicherten Bildzusammenstellungen für deine Bildwechsel zu verwenden, und diese Zusammenstellungen dann abzurufen. Dann könnte der Bediener auch noch die Zusammenstellungen selber anpassen, wenn dafür vorgegebene Namen (z.B. Diashow1, Diashow2, ...) verwendet werden. D.h. er lädt sich die Bilder die er haben möchte auf seine Monitore, speichert die Zusammenstellung dann unter dem passenden Namen.

Vom BPC wird u.a. automatisch eine globale Aktion eingefügt die aufgerufen wird wenn sich ein Benutzer anmeldet. Dazu wird dann die Zusammenstellung mit Namen "default" verwendet. Da siehst du wie das prinzipiell funktioniert.
 
Ich würde das jetzt gerne mit einem Array und einer Schleife lösen. So circa in dieser Art und Weise:

Code:
#define PIC_0 "Bildname0.pdl"
#define PIC_1 "Bildname1.pdl"
...
#define PIC_9 "Bildname9.pdl"

Array[0] = PIC_0;
Array[1] = PIC_1;
...
Array[9] = PIC_9;

for (int i = 0; i < 10; i++)
     SSMChangeWorkField('1',Array[i], TRUE);

Wenn ich den Grundbefehl verstanden habe dann müsste der 2. Übergabeparameter irgendetwas mit Pointern zu tun haben und ich muss gestehen, dass ich auf diesem Thema nicht

sonderlich fit bin.
Also falls jemand eine Idee oder sogar die nötigen Befehle hat, um zu diesem oder einem ähnlichen Ergebnis zu kommen, wäre ich sehr dankbar.

PictureName ist ein Zeiger auf ein char bzw. TCHAR (d.h. Unicode) Array. Ist das Array nullterminiert, dann ist das in C ein String.
Für dein Vorhaben benötigst du also ein Array mit Zeigern auf char-Arrays, oder auch Array mit Zeigern auf Strings.

Dein Ansatz wäre insofern richtig, wenn du Array wie folgt definierst:
Code:
char *Array[10]; /* Ein Array mit Speicherplatz für 10 Zeiger auf ein char */

Array[0] = PIC_0; /* Array[0] zeigt nun auf die Adresse des char-Arrays bzw. Strings "Bildname0.pdl"
Array[1] = PIC_1; /* Array[1] zeigt nun auf die Adresse des char-Arrays bzw. Strings "Bildname1.pdl"

Oder du kannst die Zeiger auch direkt bei der Initialisierung mit angeben und den Compiler die Arraygröße mit leeren eckigen Klammern berechnen lassen:
Code:
char *Array[] = {PIC_0, PIC_1, PIC_2, PIC_3, PIC_4, PIC_5, PIC_6, PIC_7, PIC_8, PIC_9};
Genaugenommen wären das eigentlich ein const char * weil auf die Strings nur lesend zugegriffen werden darf. Aber dann hätte Siemens das auch bei den Funktionsparametern von SSMChangeWorkField() so angeben müssen.

Wenn du durch die Elemente iterieren muss, bietet es sich an als letztes Element einen Zeiger auf NULL einzufügen, dann weißt du wenn Array == NULL, dann bist du beim letzten Element und musst wieder mit Index 0 beginnen. Dann musst du in deinem Programm nicht die Anzahl der Elemente im Array mitführen und kannst das Array recht einfach erweitern.

Solange du nicht mit chinesischen o.Ä. Sonderzeichen in deinen Bildnamen hantierst, kannst du den Umgang mit TCHAR auch vorerst ignorieren.
Ob WinCC da mittlerweile an allen Stellen wirklich Unicode-fähig ist weiß ich nicht, ich versuche das weitestgehend zu vermeiden. Irgendwo hakt es dann immer.
 
Zurück
Oben