# Siemens 840dsl Alarme auslesen



## Hans54216 (3 April 2017)

*Siemens 840dsl Alarme per NoDave auslesen*

Hallo zusammen,

ich hab eine 840dsl mit einer CPU 317F-3 PN/DP und möchte die aktuellen Alarme auslesen.

Bevorzugt per Lib NoDave und C# Programm.

Kennt sich jemand mit dem Auslesen der Alarme aus dem Alarm Server oder des Alarm-Puffers aus?

Das hab ich bis jetzt in der DocOnCD gefunden:


----------



## gravieren (3 April 2017)

Hi

Im DB2 stehen die Fehlerbits  !
Die dazugehörigen Fehlertexte sind auf der PCU zu finden !


----------



## Hans54216 (4 April 2017)

Das ist mir soweit auch bekannt. Ich möchte nur nicht zyklisch den kompletten DB2 weg kopieren und diesen dann auf Änderungen Vergleichen. Außerdem wird dabei sicher die ein oder andere Störung übersehen werden, die nur kurz ansteht aber noch nicht quittiert ist.

Im Alarm Server sollte auch die Zeit des kommen und gehen des Fehlers protokolliert sein.

Ähnlich der NC Variablen für Störungen. In diesen sind jedoch nur NC Störungen enthalten.


----------



## Peter Gedöns (4 April 2017)

im HMI OA Programmier Paket ist der Zugriff auf den Alarmserver beschrieben, explizit dazu gibt es ein Beispiel.


----------



## Boxy (4 April 2017)

Wie wäre es mit dem AlarmLog von der Steuerung?

Am besten wäre aus einmal mehr Informationen zu geben was genau die Frage bzw. Wunsch ist?
Alarme auslesen ist sehr relativ und lässt viel Spielraum für ein entsprechenden Hinweis ...


----------



## Hans54216 (4 April 2017)

Auf das Sinumerik Operatre Programmier Paket bin ich inzwischen auch gestoßen. Dies hat jedoch einige Nachteile: z.B. setzt die Installation eines pseudo HMI auf meinem PC voraus, Anzahl der Maschinen auf die Zugegriffen werden kann ist sehr begrenzt ...  

@Boxy:
Was meinst du mit AlarmLog von der Steuerung?


Als Nachtrag:
Ich möchte per C# und TCP/IP auf die Alarme zugreifen. Am liebsten per LibNoDave.


----------



## Peter Gedöns (4 April 2017)

wenn du doch das Programmier Paket hast kannst du dir doch einen Adapter schreiben (SO)  der dir  deine  Anfragen von außen  beantwortet .
Das HMI OA ist nun mal für Anwendungen gedacht die das HMI ersetzen oder erweitern das zu ist dann natürlich auch die Basis des HMI notwendig (pseudo HMI externer PC ) ober wo ist die Anzahl der Maschinen begrenzt ?


----------



## Hans54216 (4 April 2017)

Das HMI läuft bei den Maschinen auf der 840dsl als Embedded. Die Basis des HMI kann meines Wissens nach nur zu max. 5 Maschinen eine Verbindung aufbauen. Das heißt, dass immer für bis zu 5 Maschinen ein PC gesetzt werden muss.


----------



## Peter Gedöns (4 April 2017)

Ich habe jetzt kein Lust dir das innen Leben der 840Dsl bis ins kleinste Detail zu erklären.
Mein Vorschlag war das du dir ein stück Software schreibst das du in der (NCU ) 840Dsl als OA Anwendung startest. Dieses Stück Software bedienst du von außen mit deinen Anfragen z.b gibMirAllleAktiveAlarme, intern nutzt du die im OA beschriebenen Funktionen hier halt den Alarmserver und reichst das nach außen an deine Anwendung . Ist halt etwas Arbeit aber dann haste was ordentliches was du auch verkaufen kannst. Du kannst natürlich auch versuchen mit Hilfe der Kollegen hier das über (Port 102 )Libnodave und  Wireshark Logs  zu bewerkstelligen.
Da ich aber nicht weiß was du da für ein Projekt treibst bin ich erstmal raus. bei OpenSource würde ich vielleicht drüber nach denken.


----------



## Hans54216 (5 April 2017)

Der Weg über Wireshark und unter Verwendung von LibNoDave ist genau der, den ich vor hab zu gehen.
Die Frage zielte auch darauf, ob sich schon jemand die Mühe gemacht hat.

Dann mach ich mich mal ans auswerten der Wireshark Logs.


----------



## Hans54216 (8 April 2017)

Ich hab gerade ein Wireshark Log vom Hochlauf der HMI gemacht.
Darin hab ich auch was mit ALARM query gefunden, was sich erstmal vielversprechend anhört.

Kann da einer mehr dazu sagen?

Anhang anzeigen Alarme_20170408.rar


----------



## Thomas_v2.1 (8 April 2017)

Das scheinen die ganz normalen Bausteinmeldungen im Alarm_S Verfahren zu sein, wie sie die S7-300 beherrscht. 
Der Client meldet sich zum Empfang von bestimmten Meldungen bei der SPS an, und bekommt diese dann automatisch zugeschickt. Dann können die Meldungen vom Client aus auch quittiert werden. Außerdem besteht die Möglichkeit, die anstehenden Meldungen abzufragen. Bei Alarm_S bekommst du die dann mit Zeitstempel, bei Alarm_8 z.B. nur ohne. Darum zeigt wenn du ein WinCC (Scada) bei anstehenden Meldungen neustartest, die Meldungen mit einem durchgestrichenen Zeitstempel an, weil es nicht weiß wann diese gekommen ist.

Um die Alarme interpretieren zu können, benötigst du eine Übersetzungstabelle für die Meldungs-IDs, denn nur diese werden verschickt. Bei Step7 bekommst du diese aus dem Offline-Projekt.

Wenn du Step7 hast, dann solltest du dich  aus dem Simatic-Manager heraus mit der Funktion "CPU Meldungen" testweise für Meldungen bei der SPS anmelden können, und bekommst diese dann zugeschickt.
Bibliotheken wie libnodave oder Snap7 unterstützen diese Funktion nicht.


----------



## Thomas_v2.1 (8 April 2017)

Wobei, werden in der Aufzeichnung denn auch Alarme ausgelöst?
Es werden zwar anfangs Alarme abgefragt, aber später in der Aufzeichnung keine Alarmübertragung so wie ich sie bisher kenne. Es sind aber etliche Telegramme vorhanden die ich in Wireshark noch falsch dekodiere (die mit Malformed packet), weil ich den Aufbau so noch nie gesehen habe. Vielleicht funktioniert es doch ganz anders.


----------



## Hans54216 (8 April 2017)

Währ super wenn du mich beim analysieren der Logs wieder unterstützen würdest. Hat das letzte mal Super funktioniert.

Aktuelles Ziel währe es alle anstehenden Fehler IDs (event. mit Datum, Quitierungs Info) auszulesen. Die Fehlertexte kommen aus XML-Files die der Maschinenhersteller oder bereits Siemens in der HMI hinterlegt.

Ob die "CPU Meldungen" die richtige Quelle für dies ist, weiß ich nicht.

Die NC Alarme können z.B. über diese Variablen gelesen werden (was bereits gut funktioniert):


----------



## Thomas_v2.1 (8 April 2017)

Hast du denn in der xml-Beschreibung einen Text für die ID 410151?

In deiner angehängten Aufzeichnung oben steht bei Start keine Alarmmeldung an, und währenddessen wird auch nichts per Alarm_S übertragen.

Aber es gibt ein neues mir unbekanntes Format, muss ich mich nachher mal ransetzen was da los ist.


----------



## Hans54216 (8 April 2017)

Hier der Text aus dem HMI: (Alarm Source muss ich später suchen)


----------



## Thomas_v2.1 (8 April 2017)

Mach doch bitte nochmal eine Wireshark-Aufzeichnung von einem Alarm, wenn du mit der Funktion "CPU Melden" angemeldet bist. Dann kann man sehen ob es Standard ist, oder etwas anderes.

Ich habe mir die Funktionen der verschiedenen Meldeverfahren (Alarm_S, Alarm_8, Alarm_8p) und deren Aufbau irgendwann mal zusammengereimt. Zumindest die Funktionen die ich mit einer 300er und 400er SPS generieren konnte.

In libnodave ist das aber nicht so einfach zu integrieren, weil das Bausteinmeldeverfahren ereignisorientiert ist. Bei den bisherigen Funktionen gibt es immer das Schema: Anfrage stellen und auf Antwort warten. D.h. du musst dann einen Hintergrunddienst starten der auf Empfang geht.


----------



## Hans54216 (8 April 2017)

Hab jetzt einmal ein Paket von der HMI:
Störung löschen, neue Störungen + Bild

Einmal Step7 Anfrage CPU Melden. Dabei wird doch eine Anfrage geschickt und anschließend die Antwort angezeigt. Sollte doch vom Prinzip her ähnlich sein wie die normalen noDave Methoden?

Anhang anzeigen Alarme_20170408_2.rar
Anhang anzeigen CPU Melden.rar


----------



## Thomas_v2.1 (8 April 2017)

Das scheint in beiden Aufzeichnungen unterschiedlich zu funktionieren.

In "HMI-Alarme.pcapng" werden keine Alarme über das Bausteinmeldeverfahren übertragen. Entweder das Übertragen geschieht über den Standard d.h. Lesen von bestimmten Datenbereichen, oder über die zyklischen Variablendienste die dort auch vorkommen. Bei den zyklischen Variablendiensten kannst du dich bei einer SPS anmelden, dass diese dir in einem bestimmten Intervall ohne weitere Anfrage bestimmte Daten automatisch zusendet, dann entfällt das Pollen.
Wenn du weißt wo die Informationen stehen, dann kannst du diese Daten auch weiterhin pollend abfragen. Wenn in den Datensätzen die Zeitstempel vorhanden sind, dann macht das auch keinen Unterschied.
Bis auf die zyklischen Variablendiensten wäre das in libnodave schon vorhanden.

In der "CPU Melden_IP" Aufzeichnung wird das Standard-Bausteinmeldeverfahren Alarm_S angewendet. Das müsstest du komplett neu programmieren.


----------



## Thomas_v2.1 (8 April 2017)

Ich habe mir die "Malformed packets" mal vorgenommen, denn da steckt so wie es aussieht relevantes drin. Das mit den zyklischen Daten scheint bei der NCK etwas anders zu funktionieren als bei einer SPS.
Auf jeden Fall stecken in den Daten nicht Antwortdaten von der SPS, sondern so wie es aussieht Anfragen vom Client. Und wie das bei den Push Nachrichten üblich ist, wird so eine Anfrage nicht bestätigt.

In deinem ersten Logfile steckt da u.a. eine Anfrage an das NCK Modul "SALUC - Alarm actions: List in reverse chronological order" drin, und dann gibt es einen mehrere Antworten darauf von der NCK. Was da drin steckt weiß ich nicht, könnte sein dass dort Zeitstempel vorhanden sind. Du könntest ja mal testweise diese Daten per normaler Anfrage wie sie ja auch mit der modifizierten libnodave möglich sind lesen.
Vielleicht kann man sich damit auch für neue Alarme anmelden, die dann im NCK-Format zurückkommen. 

In deinem zweiten "HMI-Alarme" fehlt der Anlauf, bei dem evtl. solche Variablen angemeldet werden. Bzw. weiß ich noch nicht ob das bei der NCK überhaupt so etwas wie ein Anmelden ist.


----------



## Hans54216 (8 April 2017)

Hab beim zweiten Paket extra den Anfang weg gelassen, da dieses ja sonst identisch zum ersten währe und damit es möglichst kurz ist.

NCK Module "SALUC" kenne ich nicht. Laut NC-Var Selektor gibt es die folgenden Alarmbereiche:

N_SALA_alarmNo       0x77
N_SALAC_alarmNo     0x54
N_SALAL_alarmNo     0x75
N_SALAP_alarmNo     0x76

Wobei da das Module 0x54 "SALAC" heißt und keine Variable für Spalte 0 vorhanden ist.


Was muss ich machen, damit WireShark mir auch die NCK Struktur anzeigt. Hab schon auf die neueste Version aktualisiert, wird jedoch nicht dargestellt.


----------



## Thomas_v2.1 (8 April 2017)

Das kannst du in Wireshark nicht umstellen, ich könnte dir aber meine Entwicklungsversion zukommen lassen.

Ich weiß auch noch nicht wozu die zwei eingeschobenen Bytes sein sollen (im Screenshot werden die nicht angezeigt). Bei einer S7-SPS gibt es bei den Telegrammen für den Datenteil einen Returncode, und da steht 0xff bei Erfolg.
Bei deinen Telegrammen habe ich 3 verschiedene Kombinationen gesehen:
- 0x00, 0x12
- 0x0d, 0x11
- 0x0d, 0x12

Das habe ich zur Zeit als fixe Prüfung eingebaut damit man mal sehen kann was danach kommt. Wenn diese beiden Werte folgen, dann wird das nicht als Datenteil sondern als Parameterteil decodiert.
Das sieht mir irgendwie reingefrickelt aus, da das überhaupt nicht zu den S7-SPS Funktionen passt.


----------



## Hans54216 (8 April 2017)

Hab gerade ne Anfrage an die SALAL Spalte 0 geschickt, da von SALAC 0 zurück gekommen ist.

Scheint so, das das Ergebnis ein Binärer Upload aller anstehender Alarme dieses Bereichs beinhaltet.

Anhang anzeigen SALAL.rar


----------



## Thomas_v2.1 (8 April 2017)

Ich glaube die Funktionsnamen habe ich mit freundlicher Genehmigung von Deltalogic aus einer Header-Datei von aglink entnehmen dürfen.
Wenn du da eine bessere / offizielle Siemens Dokumentation hast, dann sage ich dazu nicht nein.

Der Datensatz aus deinem letzten Anhang sieht ähnlich aus wie aus deinem ersten Anhang als Antwort auf 0x54. Da bekamst du aber mehr als eine Antwort, evtl. standen da mehr als ein Alarm an?
Die Länge ist jedoch unterschiedlich, aber so wie es aussieht sind dort auch Strings enthalten.

Aber ich denke die interessanten Sachen dürften sich aus dem Datensatz einfacher extrahieren lassen, als ein Alarm_S-System auf Basis von libnodave oder komplett neu aufzusetzen.


----------



## Hans54216 (8 April 2017)

Aktuell anstehende Alarme meines Teststandes:

N_SALAC_textIndex1: 0
N_SALAC_textIndex2: 0
N_SALAC_textIndex3: 0
N_SALAC_textIndex4: 0
N_SALAC_textIndex5: 0
N_SALAC_textIndex6: 0
N_SALAC_textIndex7: 0
N_SALAC_textIndex8: 0
N_SALAC_textIndex9: 0
N_SALAC_textIndex10: 0
N_SALAC_textIndex11: 0
N_SALAC_textIndex12: 0
N_SALAC_textIndex13: 0
N_SALAC_textIndex14: 0
N_SALAC_textIndex15: 0
N_SALAL_textIndex1: 8081
N_SALAL_textIndex2: 8081
N_SALAL_textIndex3: 8081
N_SALAL_textIndex4: 8081
N_SALAL_textIndex5: 8081
N_SALAL_textIndex6: 8081
N_SALAL_textIndex7: 8081
N_SALAL_textIndex8: 8081
N_SALAL_textIndex9: 8081
N_SALAL_textIndex10: 8081
N_SALAL_textIndex11: 380500
N_SALAL_textIndex12: 380500
N_SALAL_textIndex13: 25201
N_SALAL_textIndex14: 25201
N_SALAL_textIndex15: 0
N_SALAP_textIndex1: 8081
N_SALAP_textIndex2: 8081
N_SALAP_textIndex3: 8081
N_SALAP_textIndex4: 8081
N_SALAP_textIndex5: 8081
N_SALAP_textIndex6: 8081
N_SALAP_textIndex7: 8081
N_SALAP_textIndex8: 8081
N_SALAP_textIndex9: 8081
N_SALAP_textIndex10: 8081
N_SALAP_textIndex11: 380500
N_SALAP_textIndex12: 380500
N_SALAP_textIndex13: 25201
N_SALAP_textIndex14: 25201
N_SALAP_textIndex15: 0
N_SALA_textIndex1: 25201
N_SALA_textIndex2: 25201
N_SALA_textIndex3: 380500
N_SALA_textIndex4: 380500
N_SALA_textIndex5: 8081
N_SALA_textIndex6: 8081
N_SALA_textIndex7: 8081
N_SALA_textIndex8: 8081
N_SALA_textIndex9: 8081
N_SALA_textIndex10: 8081
N_SALA_textIndex11: 8081
N_SALA_textIndex12: 8081
N_SALA_textIndex13: 8081
N_SALA_textIndex14: 8081
N_SALA_textIndex15: 0


Der Alarm "410151" (von der PLC) fehlt jedoch. (Soweit war ich ja bis jetzt schon.)


----------



## Thomas_v2.1 (8 April 2017)

Dein HMI meldet sich in deinem "HMI-Hochlauf_filter" aber auch für die Alarm_S Meldungen an. Wenn es möglich wäre sich alle Meldungen über die NCK-Datensätze zu holen, dann wäre das eigentlich nicht nötig.
Wobei dein HMI sich da auch für System-Meldungen wie CPU-Stop/Start usw. anmeldet.

Ich kenne mich mit dem NCK nicht aus, inwieweit SPS und NCK da voneinander getrennt sind.


----------



## Hans54216 (8 April 2017)

Thomas_v2.1 schrieb:


> Ich glaube die Funktionsnamen habe ich mit freundlicher Genehmigung von Deltalogic aus einer Header-Datei von aglink entnehmen dürfen.
> Wenn du da eine bessere / offizielle Siemens Dokumentation hast, dann sage ich dazu nicht nein.



Da geht´s halt Deltalogic nicht anders als der Siemens doku, die auch immer wieder falsch geschriebene Wörter(teils je nach dem welches Dokument) enthält.



Thomas_v2.1 schrieb:


> Der Datensatz aus deinem letzten Anhang sieht ähnlich aus wie aus deinem ersten Anhang als Antwort auf 0x54. Da bekamst du aber mehr als eine Antwort, evtl. standen da mehr als ein Alarm an?
> Die Länge ist jedoch unterschiedlich, aber so wie es aussieht sind dort auch Strings enthalten.
> 
> Aber ich denke die interessanten Sachen dürften sich aus dem Datensatz einfacher extrahieren lassen, als ein Alarm_S-System auf Basis von libnodave oder komplett neu aufzusetzen.



Das auslesen dieses Paketes erspart mir zwar das lesen jedes einzelnen Eintrags, jedoch habe ich dennoch nur die NC-Alarme und keine der PLC.
Hab mir gerade das aglink GUI angesehen. Dieses scheint das jedoch auch nicht (noch nicht) zu können. Wobei ich von IFM weiß, dass diese zusammen mit Deltalogic von einem "Alarm Server" die Daten bekommen wollen. Ob Sie es inzwischen geschafft haben weiß ich nicht.


----------



## Hans54216 (8 April 2017)

Thomas_v2.1 schrieb:


> Dein HMI meldet sich in deinem "HMI-Hochlauf_filter" aber auch für die Alarm_S Meldungen an. Wenn es möglich wäre sich alle Meldungen über die NCK-Datensätze zu holen, dann wäre das eigentlich nicht nötig.
> Wobei dein HMI sich da auch für System-Meldungen wie CPU-Stop/Start usw. anmeldet.
> 
> Ich kenne mich mit dem NCK nicht aus, inwieweit SPS und NCK da voneinander getrennt sind.



Nach meiner bereits mehrjährigen Erfahrung mit der 840dsl würde ich sagen, Siemens hat einfach ne "normale" SPS (meistens 317)  und ne CPU für nen NC-Kern auf eine Platine gesetzt. Damit diese dann mit einander Arbeiten können wurden so Bausteine wie der FB1 (unter anderem Parametrieren der NC-Kommunikation und behandeln von M, H, ... Funktionen), FB15(Schnittstelle nach draußen z.B zur NC)  programmiert.

Die HMI scheint nun die Alarme der NC und der "normalen" SPS einzusammeln und anzuzeigen. Somit komme ich wohl um die Alarm_S nicht herum.


----------



## Thomas_v2.1 (8 April 2017)

So "schwer" ist das mit dem Alarm Server nun auch nicht, den Aufbau der Datensätze habe ich in Wireshark vollständig  für Alarm_S, Alarm_SQ, Alarm_8 und Notify. Aber wenn du so was mal anfängst, dann sollte es auch den ganzen Zoo von Meldungstypen unterstützen. Und mit dem Testen der verschiedenen Varianten in allen Ausprägungen ist das dann doch etwas Aufwand, der sich bei einem kommerziellen Produkt auch irgendwann rechnen muss.

Ich muss aber sagen, dass ich selbst bei der SPS-Programmierung die Bausteinmeldungen nur im Zusammenhang mit PCS7 verwende. Ich habe darum weder berufliches noch persönliches Interesse an so einem Alarm-Server. Ich könnte da höchstens mit dem was ich weiß unterstützen wenn das jemand umsetzen will.


----------



## Hans54216 (9 April 2017)

Beim Testen und einfachen Debuggen sehe ich kein Problem, da der Zeitdruck noch eher gering ist.

Das größere Problem sehe ich für mich eher in der Programmierung in C (programmiere normalerweise SPS, NC oder C#) und vor allem den richtigen Netzwerkpaketen.


----------



## Thomas_v2.1 (9 April 2017)

Ich denke auch, dass es sinnvoll sein könnte so einen Alarmserver völlig losgelöst von anderen Bibliotheken zu programmieren. Es benötigt dann ggf. eine Verbindungsressource auf der CPU mehr.
Von Snap7 gibt es eine native C#-Portierung, wobei da die Trennung der verschiedenen Protokollebenen fehlt die in der C++ Version vorhanden sind. Wenn es nur für dich selber ist, dann kannst du sowas auch komplett in C# programmieren. Für eine Bibliothek würde ich sowas immer in C oder C++ machen, das ist einfach universell, und schnell.


----------



## Hans54216 (9 April 2017)

Wenn ich mir den Wireshark Log von CPU Melden so anschaue sieht es doch grundsätzlich aus wie beim File Upload von der NC. 

Hier wird halt das SubscribedEvents ALM gesetzt. Dann kommt die Bestätigung von der SPS. Anschließend wird das Alarm query empfangen und quittiert, bis "Last" == True kommt. Damit hab ich ja dann alle anstehenden Alarme.


----------



## Thomas_v2.1 (9 April 2017)

Bis dahin ist auch alles noch normal, nach Anfrage / Antwort.
Aber nachdem du dich bei der SPS für den Empfang von Alarmen angemeldet hast, sendet diese dir bei auftreten eines Alarms einfach so eine Nachricht zu. Und das ist was, das in libnodave überhaupt nicht vorgesehen ist. D.h. du musst ein Event generieren (z.B. muss ein Callback angemeldet werden), das deine Client-Anwendung implementiert wenn so eine Nachricht eintrifft. Und es können auch mehrere Meldungen gleichzeitig eintreffen.
Und dann sollte sich dieser Server auch automatisch wiederverbinden nach einer Netzwerkstörung, und sich auch ordnungsgemäß bei der SPS abmelden.

Du kannst es natürlich auch so machen, dass du z.B. alle 10s nur die Meldungen von der SPS abfragst und danach alles wieder abbaust. Dann sollte das recht einfach zu lösen sein, wenn du dich rein auf Alarm_S konzentrierst.
Dann geht dir der Vorteil des Bausteinmeldeverfahrens, nämlich der geringen Netzwerklast, aber abhanden. Bei Alarm_S ist das insofern auch kein Problem, als dass du auch bei Alarmen die du nicht "online" mitbekommen hast noch den Zeitstempel abfragen kannst. Bei Alarm_8 ist das z.B. nicht möglich. Deine Client-Anwendung muss das natürlich alles kombinieren können.

Beim Bausteinmeldeverfahren kommt selbst WinCC gelegentlich ins straucheln, nicht ohne Grund gibt es in der WinCC Alarmanzeige ein "Notquittieren" mit der man gelegentlich hängende Meldungen wegbekommt.


----------



## Hans54216 (9 April 2017)

Im ersten Schritt hab ich auf jeden Fall an zweiteres gedacht. Mir geht es zunächst nur darum, welche Alarme gerade anstehen. Ob ich die Alarme nun pollent abhole oder nur einmal wenn der Fehler Merker der PLC gesetzt wird weiß ich noch nicht. Ich brauch auch durch den Fehler keine Reaktion auslösen.

Kannst du mir bei der "einfachen" Lösung in C (libNoDave) helfen? Kann ja, wenn ich´s verstanden habe, versuchen den Listener selber in C# zu programmieren.


----------



## Hans54216 (9 April 2017)

Bevor ich alles in C oder QT programmiere, setzte ich lieber nen IPC. C ist vielleicht 50% schneller aber auch nur wenns richtig programmiert ist.


----------



## Thomas_v2.1 (9 April 2017)

Mit der zweiten Lösung kann es aber vorkommen, dass dir ein Alarm durch die Lappen geht wenn jemand diesen schnell genug an einem anderen HMI quittiert. Achso, ein Quittieren der Meldungen ist natürlich prinzipiell auch möglich. Ist die Frage ob du das benötigst?

Da ich Alarm_S auch bei mir zu Hause verfügbar habe könnte ich das mal probieren. Ich würde den Nachrichten-Datensatz für den Client aber trotzdem schonmal so aufbohren wollen, dass er auch für die anderen Nachrichtentypen funktioniert, man weiß ja nie.
Ich müsste aber auch erst mal nachsehen, wie man Funktionszeiger durch die .Net Abstraktionsebene durchbekommt.


----------



## Thomas_v2.1 (9 April 2017)

Mit der folgenden Funktion lassen sich bei einer S7-300 alle anstehenden ALARM_S Meldungen abfragen:

```
int DECL2 alarmQueryAlarm_S(daveConnection *dc, void *buffer, int buflen, int *number_of_alarms){
    int res, len, cpylen;
    int pa7;
    PDU p2;

    uc pa[] = { 0x00, 0x01, 0x12, 0x04, 0x11, 0x44, 0x13, 0x00};                          /* Parameter 1. Anfrage */
    uc da[] = { 0x00, 0x01, 0x12, 0x08, 0x1a, 0x00, 0x01, 0x34, 0x00, 0x00, 0x00, 0x04 }; /* Datenteil 1. Anfrage */
    uc pa2[]= { 0x00, 0x01, 0x12, 0x08, 0x12, 0x44, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00 }; /* Parameter weitere Anfragen */

    *number_of_alarms = 0;

    res = daveBuildAndSendPDU(dc, &p2,pa, sizeof(pa), da, sizeof(da));
    if (res != daveResOK) return res;

    len = 0;
    pa7 = p2.param[7];              /* Sequence number für weitere Abfragen */

    if (p2.udlen < 2) return daveEmptyResultError;
    /* Aufbau des 1. Antworttelegramms ist anders und besitzt noch einen 6 Byte Header */
    if (p2.udlen > 6 && p2.udata[1] == 1 && p2.udata[2] == 0xff) {
        *number_of_alarms += 1;
        cpylen = p2.udlen - 6;
        if (buffer != NULL) {
            if (len + cpylen > buflen) cpylen = buflen - len;
            if (cpylen > 0) memcpy((uc *)buffer+len, &(p2.udata[6]), cpylen);
            len += cpylen;
        }
    }
    
    if (p2.param[9] != 0) {
        pa2[7] = pa7;
        res = daveBuildAndSendPDU(dc, &p2, pa2, sizeof(pa2), NULL, 1);
        if (res != daveResOK) return res;
        
        while (p2.param[9] != 0) {      /* Last Data unit 0=Yes*/
            if (p2.udlen > 2) {
                *number_of_alarms += 1;
                cpylen = p2.udlen;
                if (buffer != NULL) {
                    if (len + cpylen > buflen) cpylen = buflen - len;
                    if (cpylen > 0) memcpy((uc *)buffer+len, p2.udata, cpylen);
                    len += cpylen;
                }
            }
            dc->resultPointer = p2.udata;
            dc->_resultPointer = p2.udata;
            pa2[7] = pa7;
            res = daveBuildAndSendPDU(dc, &p2, pa2, sizeof(pa2), NULL, 1);
            if (res != daveResOK) return res;
        }
    }

    dc->AnswLen = len;
    return res;
}
```
Die reinen Nachrichten-Objekte werden so wie du sie auch in Wireshark sehen kannst in den Buffer kopiert.

Die Nachrichten-Objekte können aufgrund der möglichen Begleitwerte unterschiedliche Längen besitzen. Zum Durchgehen der Objekte musst du darum nach jedem Objekt den Zeiger auf den Buffer um die Längenangabe + 2 weitersetzen. Der Buffer muss also auch entsprechend groß gewählt werden, bei der S7-300 lässt sich in den Systemdaten ablesen wie viele Alarm_S Meldungen gleichzeitig anstehen können, bei der IM151-8 PN/DP CPU sind das z.B 300. Wegen den Begleitwerten muss dieser dann entsprechend groß gewählt werden. Oder wir müssten die Funktion aufteilen, sodass nicht alle Meldungen in einem Rutsch in den Buffer kopiert werden, sondern mit zwei Einzelfunktionen. Aber Speicher ist auf einem PC ja nicht das Problem, da kannst du problemlos einen buffer[32767] angeben.

Evtl. habe ich da in meiner Wireshark Dekodierung noch etwas nicht ganz richtig, denn dort gebe ich die Längenangabe "Length of dataset" des Message-Objects mit nur einem Byte an. Das müssten aber eigentlich 2 Bytes sein, da es ansonsten mit der Gesamtlänge nicht zusammenpasst. Allerdings gäbe es dann hier eine andere Endianess, muss ich mir nochmal ansehen wie das aussieht wenn ich einen entsprechend großen Begleitwert übermittle.


----------



## Hans54216 (10 April 2017)

Danke!!!

Alarme werden gemeldet.

Kann ich bei dem Message Objekt davon ausgehen, dass die Struktur immer gleich ist? Länge ist noch abhängig von der Associated value(s).


----------



## Thomas_v2.1 (10 April 2017)

Bis zum ersten Begleitwert ist der Aufbau immer gleich. Um an den "gehenden Zeitstempel" zu kommen musst du auf jeden Fall die Begleitwerte korrekt verarbeiten. Wenn du nur EventID und alles bis zu "kommender Zeitstempel" benötigst, dann könntest du das auch überspringen.

Ich habe mal geguckt wie Siemens das macht. Prodave unterstützt keine Bausteinmeldungen, aber über Sapi-S7 ist das wohl möglich. Das gibt dir über die entsprechenden Funktionen auch eine Struktur mit den Message-Objekt-Daten zurück. Zwar nicht ganz so roh wie ich es mache, aber der Unterschied ist nicht mehr groß als dass es viel Arbeit ersparen würde.


----------



## Hans54216 (10 April 2017)

Hab mir jetzt mal ne Struktur gebastelt, die bis zum kommenden Zeitstempel geht und kopiere den Buffer darüber. Funktioniert auch recht gut.

Was bedeutet der EventState sowie AckState going/coming?

Den gehenden Zeitstempel bekomme ich sowie so nur wenn ich laufend die Alarme auslese. (Was ich nicht vor habe.)

Anderer seits muss ich jetzt mal schauen, wann ich die Alarme abhole. Entweder per Störungsmerker der SPS oder doch einen Listener programmieren.


----------



## Thomas_v2.1 (10 April 2017)

Muss mal sehen ob ich das noch zusammenbekomme. Die 8 Bits in dem Byte sind für die Alarm_8 Typen, bei Alarm_S hast du immer nur ein Signal pro EventID, d.h. es kommt bei allen immer nur SIG_1.

Vom Prinzip her kannst du über die Masken die Meldungszustände abbilden:
- K (gekommen, unquittiert)
- KG (gekommen, gegangen, unquittiert)
- KQ (gekommen, quittiert)
- KGQ (gekommen, gegangen, quittiert)

"EventState" sagt dir, dass die Meldung aktiv ist.
"Ackstate Going" habe ich bisher immer als true gesehen. Wahrscheinlich ist das nicht realisiert, weil du immer nur das Kommen der Meldung quittierst. Aber es gibt zumindest in der S7 verschiedene Bausteine (Alarm_S, Alarm_SQ, Alarm_D, Alarm_DQ) die sich bezüglich Quittierpflicht unterschiedlich verhalten.

Bei den Alarm-Events gibt es noch ein Feld mehr, aber rein bei der Abfrage der anstehenden Meldungen wäre die Verknüpfung meiner Meinung nach:

K = EventState==1 && AckStateComing==0
KG = EventState==0 && AckStateComing==0
KQ = EventState==1 && AckStateComing==0

Gehende Meldungen (d.h. KGQ) bekommst du mit dem Verfahren ja nicht mit, bzw. wäre es dann gegangen wenn es nicht mehr in der Liste ist.
Normalerweise bekommst du für alles ein Event von der SPS mit Zeitstempel, also kommend, quittiert, gegangen.


----------

