WinCC Tags in CSV schreiben

winnman

Level-3
Beiträge
2.212
Reaktionspunkte
396
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Kollegen,

Ich bin nach 15 Jahren mal wieder am WinCC dran (V7.5)

Ich soll Variablen alle 15min an eine CSV anhängen.

Hab jetzt nach Handbuch bzw. Info von Siemens folgendes probiert:

in Global Script eine Aktion eingebaut, da mal testweise standardTrigger 10s vorgegeben.

jetzt zum Script:

Laut Handbuch:
Code:
[#include "apdefap.h"
int gscAction( void )
{

#define MaxLineLength 80
char FILE 
Filename_Logfile_Durchflüsse; "d:/Durfluesse.csv";

FILE *fpFile;
   char *strTag[3] = {"WF_Beereben_Q_Restwasser", "WF_Karbach_Q_Restwasser", "WF_Gaisbach_Q_Restwasser" }; 
   char *pTmp;
   char buffer[MaxLineLength];
   double  dVal;
   int i;
   fpFile = fopen(GetTagChar("Filename_Logfile_Durchflüsse"), "w+" ); //open file to write
   printf ("C-Script: write file: %s\r\n", GetTagChar("Filename_Logfile_Durchflüsse"));
   if (fpFile !=NULL)
   {
       for (i=0; i<=2; i++){
          dVal = GetTagDouble(strTag[i]);
          sprintf(buffer, "%s;%lf\n", strTag[i],dVal);
          // Search for '.' and replace with ','
          pTmp  = strchr(buffer, (int)'.');
          if (pTmp != NULL){
               *pTmp = ',';
          }
          fputs(buffer,fpFile);
          printf("%s\r\r\n", buffer);
       }
       fclose(fpFile); //close file
   } else {
       printf ("Error: File not found!\r\n");
   }

return 0; 
}

/CODE]
bringt mir aber jede Menge Fehler:
[ATTACH=CONFIG]49385._xfImport[/ATTACH]

hab testweise mal FILE schon als Char definiert.

Ich hab mit Scripten keinerlei Erfahrung.

Wer kann mir da bitte etwas unter die Arme Greifen.

Danke im Voraus

Winnman

PS, Hab da auch noch ein paar andere Probleme: 
Wie kann ich für WEB Kameras eine Crome Browser Fenster aufmachen und dann gleichzeitig Passwort für die Kamera übergeben (hab den eingebauten "Explorer probiert, da mault aber die Kamera das die nur mit ektuellem Crome, Firefox, . . . funktioniert
Wie kann ich über einen Button ein Excel File öffnen? mit execute hab ich das Probiert, da passiert aber genau gar nichts (muss ich ev. den Pfad/Filnamen in einer speziellen Form eingeben?)
 

Anhänge

  • Fehler.jpg
    Fehler.jpg
    88,6 KB · Aufrufe: 34
Zuviel Werbung?
-> Hier kostenlos registrieren
kann ich fast nicht glauben.

Wie geschrieben, das ist eigentlich das fast unveränderte Beispiel das Siemens da liefert. (hab nur die Anzahl der Tags reduziert und mein Log File angegeben.

Ich hab auch testweise mal vor das FILE mal char geschrieben, da geht dann zwar dieser eine Fehler weg, alle anderen bleiben aber.

Was ich nicht verstehe, warum gibt es Beispielfiles die dann nicht funktionieren?

Das einzige was ich noch geändert hab: Beispiel war für Click auf irgendwas, ich habs als Aktion hier eingebaut. kann das der Fehler sein? Muss das ev. als Prozedur irgendwo hin und ruf das in der Action dann auf?
 
Code:
#include "apdefap.h"
int gscAction( void )
{

#define MaxLineLength 80
[COLOR="#FF0000"]char FILE 
Filename_Logfile_Durchflüsse; "d:/Durfluesse.csv";[/COLOR]
Das rote ergibt in C keinen Sinn.
Ist "Filename_Logfile_Durchflüsse" eine globale WinCC-Variable? Dann laß die 2 Zeilen einfach weg.
Falls in der Variable noch kein Dateiname drinsteht, dann kannst Du der Variable vor der Verwendung einen Text/Dateiname zuweisen:
Code:
   [COLOR="#0000FF"]SetTagChar("Filename_Logfile_Durchflüsse","d:/Durfluesse.csv");[/COLOR]

   FILE *fpFile;
//...
   int i;

   fpFile = fopen(GetTagChar("Filename_Logfile_Durchflüsse"), "w+" ); //open file to write
   printf ("C-Script: write file: %s\r\n", GetTagChar("Filename_Logfile_Durchflüsse"));
Tipp: in Variablennamen besser keine Umlaute verwenden, auch wenn es bei Siemens vielleicht geht.

Hier die originale Siemens Vorlage (Beispiel 3):
Wie können Sie Runtime-Daten von WinCC exportieren und wieder importieren?

Wie aktuell sollen die Werte in den Variablen sein? Spontan würde ich sagen, anstatt "GetTagDouble(strTag)" würde ich vermutlich GetTagDoubleWait(..) verwenden.

Harald
 
Die Wait-Funktionen sollte man nur in absoluten Ausnahmefällen verwenden. Wenn man nicht aufpasst holt man sich damit einen großen Zeitfresser ins Haus, Scripte reagieren nicht, Bedienung hängt usw.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die Wait-Funktionen sollte man nur in absoluten Ausnahmefällen verwenden.
Weiß ich.
Andererseits: wie stellt man sicher, daß der Wert der verwendeten Tags vor dem Schreiben in die csv-Datei aktualisiert ist? Er will nur alle 15 Minuten die Werte von 3 Variablen schreiben.

Harald
 
Muss das morgen mal an der Anlage noch genauer prüfen.

Die 3 Variablen sind derzeit nur ein Test, am Ende werden es so ca. 15 sein.

Die Variablen werden derzeit zyklisch erfasst, werden auch in Taglogging sauber dargestellt.

Es ist da nichts wirklich Zeitkritisch, das sind Durchflusswerte aus US Messungen, ein paar % +- sind da nicht das Problem (muss ich ev. sogar noch Mittelwerte bilden).

Zum Variablennamen: ich kenne eigentlich bisher nur D:\.... in dem Handbuch von Big S steht aber D:/.... Was ist da jetzt richtig?

Mein Hauptproblem ist derzeit, dass ich das Beispiel einfach da reinkopiert habe ein paar (meiner Meinung nach nicht zu den Fehlermeldungen führenden Änderungen gemacht habe) und jetzt da grundlegend scheitere.

"Filename_Logfile_Durchflüsse" soll eigentlich nur zur Versorgung des Global Script dienen (also nur im Script selbst) (ich hab das aber testweise auch als Variable im WinCC mal angelegt als 8 Bit String, . . . das ist aber nicht mein derzeitige Problem (könnte aber noch kommen :) ).

Leider hab ich gar keine Erfahrung mit C oder VBS oder ähnlichem, ich komme ursprünglich aus dem Energiebereich.

Kann ev. wer ein funktionierendes Script schicken?

Sorry, aber ich hänge da wirklich an den Grundlagen und Danke für alle die mir helfen.

Winnman
 
Zuletzt bearbeitet:
Andererseits: wie stellt man sicher, daß der Wert der verwendeten Tags vor dem Schreiben in die csv-Datei aktualisiert ist? Er will nur alle 15 Minuten die Werte von 3 Variablen schreiben.

Darum kümmert sich der Datenmanager, die Daten werden auch wenn sie nur in einem Script gelesen werden neu an der SPS angefordert.
Die beste wenn auch aufwändigste Variante für den Anwendungsfall ist meiner Meinung nach mit GetTagMultiWait zu lesen, dann erfolgt wirklich nur ein Mal eine Anfrage an die SPS mit allen Variablen und nicht alle einzeln nacheinander.

Bei Real-Variablen mit je 4 Bytes ist das jetzt vielleicht nicht das Problem, aber es hatte doch schon Mal jemand im Forum das Problem, dass er in einer Schleife 20 Strings gelesen hat, und das Script dann 5 Minuten benötigt hat weil WinCC beim ersten Aufruf String 1, dann String 1+2, dann String 1+2+3 usw. gelesen hat. Ich meine das passiert aber auch beim Lesen mit den Nicht-Wait Funktionen, vielleicht hat Siemens bei neueren WinCC Versionen schon etwas dahingehend behoben.
 
Ich kopier jetz nochmal das original Script ohne irgend welche Änderungen hier rein:
Code:
#include "apdefap.h"
void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)
{
   #define MaxLineLength 80
   FILE *fpFile;
   char *strTag[5] = { "TagA", "TagB", "TagC", "TagD", "TagE" }; 
   char *pTmp;
   char buffer[MaxLineLength];
   double  dVal;
   int i;
   fpFile = fopen(GetTagChar("Filename"), "w+" ); //open file to write
   printf ("C-Script: write file: %s\r\n", GetTagChar("Filename"));
   if (fpFile !=NULL)
   {
       for (i=0; i<=4; i++){
          dVal = GetTagDouble(strTag[i]);
          sprintf(buffer, "%s;%lf\n", strTag[i],dVal);
          // Search for '.' and replace with ','
          pTmp  = strchr(buffer, (int)'.');
          if (pTmp != NULL){
               *pTmp = ',';
          }
          fputs(buffer,fpFile);
          printf("%s\r\r\n", buffer);
       }
       fclose(fpFile); //close file
   } else {
       printf ("Error: File not found!\r\n");
   }
}

Vielleicht kann da mal wer drüberschauen was da bei mir nicht richtig ist.

Danke Winnman
 
so bin einen Schritt weiter, fehlerlos compiliert nach dem ich ein bisschen gespielt hab:
Fehler weg.jpg

aber jetzt geht es ans eingemachte:
Error File unknown.PNG
da stimmt also was mit der Zuweisung nicht, aber was?
 
Hallo Harald, danke, es stellen sich erste Erfolge ein.

jetzt schreib er mir jeden Aufruf die Werte so wie m Bild rein, aber immer auf die selbe Stelle.

Ich bräuchte aber das so wie im Bild rechts, das er jeweils eine neue Zeile anfügt.

erste erfolge.jpg

hoffe ich bin nicht zu aufdringlich, aber C und so ist nicht das meine und ich hab sonst niemand der mir das abnehmen kann :(

Winnman
 
Für Hinzufügen von Zeilen müsstest Du die Datei im "append" Mode öffnen
Code:
   fpFile = fopen(GetTagChar("Filename_Logfile_Durchfluesse"), "a" ); //open file for append
und die Kopfzeile mit den Variablennamen nur beim ersten Mal (beim neu Anlegen) schreiben. Dazu müsstest Du zunächst testen ob die Datei schon existiert (oder ob sie sich direkt für append öffnen läßt?). Wie das in Standard C programmiert wird habe ich vergessen... ist bei mir zu lange her.
Weiters müsstest Du die Schleife und das sprintf für das Zusammenbasteln der csv-Zeile ändern (keine Variablennamen, Zeilenschaltung "\n" nur am Ende der Zeile nach allen Werten). Hast Du in Deiner Firma niemanden der C programmieren kann?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Harald,

Ich bin jetzt auf der Suche bei uns in der Fa. (>2000 Mitarbeiter), aber wenn ich Frage "C" kommt meist "was ist das" oder hab ich mal vor x Jahren in der Ausbildung mal gehabt, . . .

Hab aber eventuell jetzt einen Kollegen an der Angel.

Besten Dank für die bisherige Hilfe. Ev. muss ich doch noch mal nachfragen.

Winnman
 
Also in Kurzform mit GetTagMultiWait für 15 Variablen:
Code:
// WINCC:TAGNAME_SECTION_START
#define TAGDATEINAME "intern_8BitTextTag_DateinameMitPfad"
#define TAG01 "Var01"
#define TAG02 "Var02"
#define TAG03 "Var03"
#define TAG04 "Var04"
#define TAG05 "Var05"
#define TAG06 "Var06"
#define TAG07 "Var07"
#define TAG08 "Var08"
#define TAG09 "Var09"
#define TAG10 "Var10"
#define TAG11 "Var11"
#define TAG12 "Var12"
#define TAG13 "Var13"
#define TAG14 "Var14"
#define TAG15 "Var15"
// WINCC:TAGNAME_SECTION_END

double val[15];
char* pDateiname;
long int size;
BOOL ok;
FILE* pFile;

ok = GetTagMultiWait("%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f", 
  TAG01, &val[0],
  TAG02, &val[1],
  TAG03, &val[2],
  TAG04, &val[3],
  TAG05, &val[4],
  TAG06, &val[5],
  TAG07, &val[6],
  TAG08, &val[7],
  TAG09, &val[8],
  TAG10, &val[9],
  TAG11, &val[10],
  TAG12, &val[11],
  TAG13, &val[12],
  TAG14, &val[13],
  TAG15, &val[14]
);
// ok wertet nicht aus ob die Variablen wirklich aus der SPS gelesen werden konnte, sondern nur ob die Funktion ausgeführt werden konnte
if (!ok) {
  printf("Fehler: GetTagMultiWait Aufruf war nicht erfolgreich!\n");
} else {
  // Datei verarbeiten
  pDateiname = GetTagChar(TAGDATEINAME);
  if (pDateiname) {
    pFile = fopen(pDateiname, "a");
    if (pFile) {
      fseek(pFile, 0, SEEK_END);
      size = ftell(pFile);
      // Wenn Dateigroesse 0, dann Header schreiben
      if (size == 0) {
        fprintf(pFile, "%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s\n",
          TAG01, TAG02, TAG03, TAG04, TAG05, TAG06, TAG07, TAG08,
          TAG09, TAG10, TAG11, TAG12, TAG13, TAG14, TAG15);
      }
      fprintf(pFile, "%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
          val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7],
          val[8], val[9], val[10], val[11], val[12], val[13], val[14]);
      fclose(pFile);
      printf("Erfolg: Die Daten wurden in Datei '%s' geschrieben\n", pDateiname);
    } else {
      printf("Fehler: Die Datei '%s' konnte nicht geoeffnet werden!\n", pDateiname);
    }
  } else {
    printf("Fehler: Dateiname konnte mit GetTagChar nicht gelesen werden!\n");
  }
}

Hinter die #defines musst du deine Tagnamen eintragen. Der Tag für den Dateinamen muss eine 8 Bit Textvariable sein, und muss den ganzen Pfad enthalten. Hier musst du nicht 'escapen', also ein Eintrag wie C:\temp\export.csv sollte funktionieren.

Die Punkt/Komma-Ersetzung muss beim aktuellen WinCC soweit ich weiß nicht mehr vorgenommen werden, da WinCC ich meine seit 7.2 die Lokaleinstellungen vom Betriebssystem verwendet. Also wenn du ein Deutsches Windows hast, dann sollte auch ein Komma ausgegeben werden.

Wenn du mehr oder weniger Variablen hast, dann sollte ersichtlich sein an welchen Stellen die Anpassungen vorgenommen werden müssen.
 
Hallo Thomas,

besten Dank, das ist genau das was ich brauche und es macht das hervorragend.


ich trau mich ja fast nicht zu fragen aber kannst du mir bei den folgenden Punkten auch noch helfen?

Wie kann ich für WEB Kameras eine Crome Browser Fenster aufmachen und dann gleichzeitig Passwort für die Kamera übergeben (hab den eingebauten "Explorer probiert, da mault aber die Kamera das die nur mit ektuellem Crome, Firefox, . . . funktioniert

Wie kann ich über einen Button ein Excel File öffnen? mit execute hab ich das Probiert, da passiert aber genau gar nichts (muss ich ev. den Pfad/Filnamen in einer speziellen Form eingeben?)
sg Winnman
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie kann ich für WEB Kameras eine Crome Browser Fenster aufmachen und dann gleichzeitig Passwort für die Kamera übergeben (hab den eingebauten "Explorer probiert, da mault aber die Kamera das die nur mit ektuellem Crome, Firefox, . . . funktioniert

Da müsstest du prüfen wie das Passwort übermittelt wird. Wenn per http-get, dann wird das Passwort als Parameter an die URL angehängt, sowas wie http://1.2.3.4/web.html?password=abc. Das macht aber heutzutage eigentlich keiner mehr, weil das Passwort dann im Klartext übermittelt wird. Bei Firefox existiert eine Option um Formularfelder automatisch ausfüllen zu lassen, würde ich mal probieren ob das weiterhilft.

Manche Kameras geben den Stream im RTSP Format aus. Das kann z.B. der VLC-Player abspielen, für den es auch ein Plugin gibt was wohl auch mal mit WinCC kompatibel war. Für den RTSP Stream ließ sich dann in VLC Benutzername und Passwort mit angeben.
 
Hallo Noch mal an alle die bis jetzt geholfen haben besten Dank.

Hier jetzt mal meine derzeitigen Lösungen:

1. Mal ein VBA Script, der die Local Time in entsprechende Variablen Schreibt (Triggere ich alle 1s):
Code:
Option Explicit
Function actionDim mDatum_Zeit
Dim Datum_Zeit
Dim Jahr
Dim Monat
Dim Tag
Dim Stunde
Dim Minuten
Datum_Zeit = Now
Set mDatum_Zeit = HMIRuntime.Tags("iDatum_Zeit")
mDatum_Zeit.Read
mDatum_Zeit.Value = Datum_Zeit
mDatum_Zeit.Write
Set Jahr = HMIRuntime.Tags("iJahr")
Jahr.Read
Jahr.Value = Year(Now)
Jahr.Write
Set Monat = HMIRuntime.Tags("iMonat")
Monat.Read
Monat.Value = Month(Now)
Monat.Write
Set Tag = HMIRuntime.Tags("iTag")
Tag.Read
Tag.Value = Day(Now)
Tag.Write
Set Stunde = HMIRuntime.Tags("iStunde")
Stunde.Read
Stunde.Value = Hour(Now)
Stunde.Write
Set Minuten = HMIRuntime.Tags("iMinute")
Minuten.Read
Minuten.Value = Minute(Now)
Minuten.Write
'HMIRuntime.Trace "OK geschrieben " & Datum_Zeit & "  " & vbCrLf  'für testzwecke

End Function

Und jetzt das Hauptscript als C Aktion, wird jede Minute aufgerufen (paar Variablen sind da noch nicht im Endstadium, darum werden da derzeit auch noch sinnlose Werte geschrieben):
Code:
#include "apdefap.h"
int gscAction( void )
{

// WINCC:TAGNAME_SECTION_START
#define TAGDATEINAME "Filename_Logfile_Durchfluesse"
#define TAG01 "iDatum_Zeit"
#define TAG02 "iJahr"
#define TAG03 "iMonat"
#define TAG04 "iTag"
#define TAG05 "iStunde"
#define TAG06 "iMinute"
#define TAG07 "WF_Gaisbach_Q_Restwasser"
#define TAG08 "WF_Gaisbach_Q_Restwasser"
#define TAG09 "WF_Gaisbach_Q_Restwasser"
#define TAG10 "WF_Gaisbach_Q_Restwasser"
#define TAG11 "WF_Gaisbach_Q_Restwasser"
#define TAG12 "WF_Gaisbach_Q_Restwasser"
#define TAG13 "WF_Beereben_Q_Restwasser"
#define TAG14 "WF_Karbach_Q_Restwasser"
#define TAG15 "WF_Gaisbach_Q_Restwasser"
// WINCC:TAGNAME_SECTION_END
double val[15];    //Anzahl anpassen!
double iMinute;
char* pDateiname;
long int size;
BOOL ok;
FILE* pFile;
SetTagChar("Filename_Logfile_Durchfluesse","d:\\durchfluesse.csv"); //Return-Type: BOOL 
 
iMinute = GetTagDouble("iMinute"); //Return-Type: double 
if (iMinute == 0 || iMinute == 15 || iMinute == 30 || iMinute == 45 ) //soll nur bei ganzer 1/4 Stunde den Rest ausführen
{
ok = GetTagMultiWait("%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f", 
  TAG01, &val[0],
  TAG02, &val[1],
  TAG03, &val[2],
  TAG04, &val[3],
  TAG05, &val[4],
  TAG06, &val[5],
  TAG07, &val[6],
  TAG08, &val[7],
  TAG09, &val[8],
  TAG10, &val[9],
  TAG11, &val[10],
  TAG12, &val[11],
  TAG13, &val[12],
  TAG14, &val[13],
  TAG15, &val[14]
);
// ok wertet nicht aus ob die Variablen wirklich aus der SPS gelesen werden konnte, sondern nur ob die Funktion ausgeführt werden konnte
if (!ok) {
  printf("Fehler: GetTagMultiWait Aufruf war nicht erfolgreich!\n");
} else {
  
// Datei verarbeiten
  pDateiname = GetTagChar(TAGDATEINAME);
  if (pDateiname) {
    pFile = fopen(pDateiname, "a");
    if (pFile) {
      fseek(pFile, 0, SEEK_END);
      size = ftell(pFile);
      
      // Wenn Dateigroesse 0, dann Header schreiben
      if (size == 0) {
        fprintf(pFile, "%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s\n",
          TAG01, TAG02, TAG03, TAG04, TAG05, TAG06, TAG07, TAG08,
          TAG09, TAG10, TAG11, TAG12, TAG13, TAG14, TAG15);
      }
      fprintf(pFile, "%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
          val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7],
          val[8], val[9], val[10], val[11], val[12], val[13], val[14]);
      fclose(pFile);
      printf("Erfolg: Die Daten wurden in Datei '%s' geschrieben\n", pDateiname);
    } else {
      printf("Fehler: Die Datei '%s' konnte nicht geoeffnet werden!\n", pDateiname);
    }
  } else {
    printf("Fehler: Dateiname konnte mit GetTagChar nicht gelesen werden!\n");
  }
}
}
else {
printf("keine volle 1/4 Stunde \n"); //zu Tetzwecken wenn es öfter aufgerufen wird
}
 
return 0; 
}
 
Zurück
Oben