SNMP Kommunikation über SNMP_Service_SL Bibliothek WAGO PFC

.K.

Level-2
Beiträge
193
Reaktionspunkte
30
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leut's,
Frage1:
Kennt sich jemand mit SNMP Kommunikation über CaodeSys aus, speziell mit der im Header genannten Bibliothek? Alternativ nehme ich auch Vorschläge für andere Bibliotheken an. Z.B. die WAGO Lösung mit der "WagoAppSNMP". Aber hier bin ich sehr auf den WAGO Support angewiesen, der damit scheinbar selbst überfordert ist.
Deswegen würde ich es jetzt mit der SNMP_Service_SL Bibliothek versuchen.
Hierzu
Frage2:
Die Reihenfolge wäre:
1. User anlegen. (https://content.helpme-codesys.com/...emV3/USM/Users/CreateRWUser.html#createrwuser)
2. den SNMP_Agent anlegen und Starten (https://content.helpme-codesys.com/...ction-Blocks/Agent/SNMP_AGENT.html#snmp-agent)
Wann muss ich den SNMP_AGENT starten und was genau macht der dann? Muss der so lange aktiv sein, wie ich etwas lesen/schreiben möchte?

Frage3:
Wenn ich einen Wert abfragen möchte, zum Beispiel einen Sollwert (Wassertemperatur), der vom Leitsystem kommt. Dann brauche ich die OID von diesem Datenpunkt und die IP vom Server, soweit klar. Aber was sind die asOIDs?
Ein String-Array ALLER OIDS? Woher soll ich denn wissen, was es da alles für OIDs gibt? Kann ich nicht einfach nur den einen Datenpunkt abfragen?
Ich habe hier schon versucht, das wie im Beispielprojekt anzulegen, aber das wird rot unterstrichen, sogar im Beispielprojekt:
1726640029196.jpeg



Hardware/Software - informationen:
WAGO PFC200 750-8212 (Auf der PFC ist witzigerweise nur Codesys V2 installiert und man muss erst ein Softwareupdate machen :cautious:)
WAGO Touchpanel TP-600 7.0 800x480 POI1
Codesys V3.5 SP19 Patch7
Gesteuert werden sollen zwei Wärmepumpen die als Gebäudeheizung dienen. Es werden Daten bezüglich Laufzeit, Energieaufnahme, Temperaturen, Druck, etc. als Soll- und Istwerte ausgetauscht.

Soweit erstmal, vielen Dank an Alle, die sich die Mühe machen das durchzulesen und bereit sind mir zu helfen, ich stecke echt in der Klemme :cry:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

zu der Bibliothek von Wago, hast Du Dir schon den Anwendungshinweis a500850 angesehen. Der erklärt einiges wie es von Wago realisiert wird und läßt sich auch auf Codesys 3.5 anwenden.

Ansonsten auch mal generell zu SNMP informiert?
simple Einsteigerinfo - https://www.thomas-krenn.com/de/wiki/SNMP_Grundlagen https://checkmk.com/de/guides/was-ist-snmp


Agent - Slave/Server der Daten bereitstellt, die von einem Manager abgerufen oder geschrieben werden

Manager - Master/Client der Daten von einem Agent abruft oder ihm zuweist

Der Agent (als TrapSender) kann auch unverlangt Daten an einen feste Adresse (TrapReceiver) versenden.

Du mußt also zunächst einmal festlegen wie zwischen den Geräten kommuniziert werden soll, z.B. die Steuerung Agent und das Leitsystem der Manager. Dann fragt das Leitsystem regelmäßig die Istwerte von der Steuerung ab und sendet ihr die Sollwerte. Umgekehrt entsprechend.

Der Agent muß also dauerhaft laufen, um Anfragen des Managers beantworten zu können. Der Manager dagegen holt sich oder gibt dagegen mehr oder weniger regelmäßig, also nur bei Bedarf, die Daten.

Die Datenpunkte werden in einer hierarchischen Struktur, definiert in den OIDs, abgelegt. Da gibt es bestimmte Festlegungen, andere darunter sind durch Dich festzulegen, s. Auch den Anwendungshinweis.

Zu Frage 3:
asOIDs - das ist ein Array of String. Das wird in dem Beispiel zunächst einmal mit der OID aus der Visu gefüllt. Dann wird der Wert abgefragt. Du kannst dort auch mehrere OIDs ablegen die dann nacheinander abgefragt werden. Bei diesem Beispiel wird aber durch den Requesttype GET_NEXT_REQUEST aber automatisch durch die verschiedenen Zweige durchiteriert.

Die OIDs mußt entweder Du festlegen, wenn Du der Agent bist, oder Dir zur Verfügung gestellt werden.

Gruß
 
Danke Thruser für deine Antwort.

Zu deinen ersten beiden Fragen: Ja

Die WAGO Steuerung wird doch über das Web-based Management als Manager festgelegt oder?
Also müsste das Leitsystem ein Agent sein, der Daten liest oder schreibt, die vom Manager abgerufen oder bearbeitet werden.

Allerdings steht im Web-based Management, dass ich einen User und einen Trap Reciever anlegen kann.
Von Master oder Agent steht da ja nichts.
User brauche ich, um mich im SNMP V3 zu identifizieren, das ist klar. Und der Trap Reciever fragt (dauerhaft?) die angegebene OID beim Host ab?
Denn das alte Programm (Codesys V2) sah so aus:
1726726524724.png

Bei der OID verstehe ich alles bis ..13576.. das ist die WAGO ID. Danach hab ich keine Ahnung, wie es zu dieser Zusammenstellung an Nummern kommt. Die müsste der Programmierer selbst erstellt haben oder?
Und wie lege ich dann Fest, welche Daten auf dieser OID stehen? Also, wenn ich jetzt die Sammelstörung der Anlage als OID an einen Agent (wie es mir hier scheint) schicken möchte, dann brauche ich dessen IP (check) und die community (='publi' → check) und den Start Befehl (check) und dann die OID. Da check ich nix mehr.

Frage:
Wie lege ich wo die OID fest und wie kann ich in Codesys über die WagoAppSNMP-Bibliothek festlegen, welche Daten auf die OID geschrieben werden?
 
Hi,

Nein, die Daten im WBM sind für die Nutzung als Agent. Die Steuerung wird dann also vom Manager angesprochen und liefert die Daten zurück. Im WBM werden dafür die Benutzer etc. festgelegt, sowie ein paar Grundlegende SNMP Daten, s. Kapitel 4.2 aus dem Anwendungshinweis oben. Das wird dann alles durch die Firmware des Controllers im Hintergrund verwaltet

Deine eigenen Datenpunkte mußt Du dann mit der Funktion FuSnmpAgent_CustomOIDRegister registrieren. Wennn Du dann wissen willst welche Daten Dir der SNMP Manager geschickt hat mußt Du die entsprechende OID (den Datenpunkt) über die Funktion FuSnmpAgent_CustomOIDGet vom Hintergrundservice abfragen. Mit der Funktion FuSnmpAgent_CustomOIDSet übergibst Du Werte an den Hintergundservice die derManager dann abfragen kann.

Für Deine Istwerte verwendest Du also FuSnmpAgent_CustomOIDSet, für die Sollwerte FuSnmpAgent_CustomOIDGet.

Die Funktion die SNMP_GET die Du dort zeigst ist eine Manager Funktion. Das Programm arbeitet dort also als Manager, zumindest in diesem Abschnitt. Die Funktion ist so auch in der WagoAppSNMP vorhanden (FbSnmpManager_Get, bzw. FbSnmpManager_Get_Timed wegen des Time-Out). Wenn Du SNMP V3 verwenden willst ist die entsprechende Funktion vorhanden (FbSnmpManager_Get_V3 bzw. FbSnmpManager_Get_V3_Timed). Du kannst das also fast 1:1 übersetzen, Du mußt nur den Community String durch die entsprechenden V3 Informationen ersetzen.

Durch die MIB Datei im Anwendungshinweis habe ich die oben verwendete OID gefunden. Das ist ein Bereich, den Wago in den alten Controller als Austauschbereich für Lesen und Schreiben von Daten festgelegt hat. Hier mal ein Auszug aus dem Handbuch zum 881 Controller, der SNMP Daten noch fest hinterlegt hat
1726773834611.png

Der Controller aus Deinem Screenshot ruft also Daten von einem anderen ab. Da hat jemand dann willkürlich? festgelegt welche Daten unter welchem Unterpunkt abgelegt sind.

Trap Reciever etc. benötigst Du nur, wenn Dein Agent eine spezielle Nachricht an den Manager schicken soll, die nicht vom Manager abgefragt werden. Kann ja sein, daß der Manager Daten nur alle 60s abfragt, zwischendurch entsteht aber ein Alarmzustand, dann kann der Agent den Manage unabhängig von der Abfrage darüber informieren.

Das sollte Dir erst einmal weiterhelfen.

Gruß
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Vielen Dank, das hilift mir sehr weiter. Jetzt muss ich nur noch den Betreiber des Leitsystems fragen, ob er sich als Manager sieht.
Und ich war kurz verwirrt, weil auch die WagoAppSNMP Bibliothek ständig Fehler gebracht hat beim Anwenden. Aber auch hier ist das Problem, dass sie sich nur in ST ohne Fehlermeldungen aufrufen lässt, wie hier von dir schon mal festgestellt.
Deswegen ist auch das Beispiel scheinbar komplett in ST programmiert.
 
Hui, also übersichtlich und einfach zu verstehen finde ich das Beispiel jetzt nicht gerade aber ich versuche meine Erkenntnis mal prüfen zu lassen:

Code:
1            //Initialise TLV variable with datatype "STRING" and set value to "sModel"
2            SNMP_STRING_TO_TLV(sInput:= sType, eDatatype:= SNMP_TLV_STRING, typData:= typData);
3                
4            // Register OID as readonly           
5            FuSnmpAgent_CustomOIDRegister(sOID:= '.1.3.6.1.4.1.65535.1.1.1.0', typDefaultData:= typData, xReadOnly:= TRUE);
6        
7            // Update OID value
8            SNMP_STRING_TO_TLV(sInput:= sType, eDatatype:= SNMP_TLV_STRING, typData:= typData);
9            FuSnmpAgent_CustomOIDSet(sOID:= sOidType, typData:= typData);

In Zeile 2 wird der Wert, den ich auf die OID mappen möchte in TLV gewandelt (vermutlich das Vormat, mit dem das SNMP Protokoll arbeiten kann). typeData is eine In-Out-Variable. Also der String sType wird in SNMP_TLV_STRING gewandelt und an typeData geschrieben.
In Zeile 5 wird mit sOID die OID vergeben und als ReadOnly festgelegt. Heißt, der Manager kann die Daten nur lesen, nicht ändern?
In Zeile 8 wird typeData in TLV gewandelt und
in Zeile 9 auf die OID geschrieben.
Soweit verstanden... hoffe ich =)

Wenn ich zwei Steuerungen habe, die beide nicht der Manager sind, können diese dann Daten untereinander austauschen?
Also Steuerung 1 registriert die OID wie oben gezeigt und mit oSnmpManager_Set werden Daten auf die OID geschrieben. Dann registriert Steuerung 2 die OID ebenfalls um festzulegen, auf welche Adresse sie dort geschrieben wird. Steuerung 2 kann dann mit SnmpManager_Get die daten der OID lesen?

Und reicht es, die OID 1x pro Steuerung zu registrieren oder muss das immer weider geschehen? Also bei einem Neustart der PFC muss keine erneute Registrierung erfolgen?

Und meine vorerst letzte Frage:
Das Beispiel ist SNMP V3? Weil von Verschlüsselung habe ich da jetzt noch nichts gesehen... :unsure:
 
Moin,

TLV, Type-Length-Value, damit werden die zu übermittelnden Daten kodiert.

Keine Ahnung warum in dem Beispiel noch FuSnmpAgent_CustomOIDSet verwendet wird, da darüber beim Registrieren der Wert auch bereits als default Wert gesetzt wird. Der Aufruf muß nur jedes mal getätigt werden wenn sich der Wert geändert hat.

Die Registrierung sollte meiner Meinung nach nur einmal notwendig sein. Mach Dir da am besten eine INI Phase beim Startup. Später muß dann nur regelmäßig mit Set die Werte aktualisiert werden bzw. die aktualisierten Werte mit Get abgerufen werden. Da kann man auch überlegen, ob man das Get zu Programmanfang und das Set zu Programmende durchfühhrt.

Das Beispiel ist SNMP V1, V2 und V3. Das bestimmst Du durch das WBM. In welchem Bereich Du dort User/Zugangsdaten etc. anlegst.

Wenn beide Steuerunge Agents kommunizieren die nicht miteinander, da sie jeweils darauf warten von der anderen Steuerung angesprochen zu werden (als Manager). Höchstens per Trap können sie kommunizieren, wenn die jeweils andere Steuerung als Trap Receiver fungiert. Bei den Funktionen sehe ich aber nur Send Funktionen, keine Receive.

Gruß
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hm hm hmmmmm....

Innerhalbt einer PFC kann ich den Wert setzen und lesen, das ist schon mal super. Heißt nämlich, die OID ist registriert und lässt sich beschreiben und auslesen. Aber wie bekomme ich den Wert jetzt von einer zweiten Steuerung gelesen oder geschrieben?
Also mein Versuchsaufbau sind 2 identische CPUs (PLCs, PFCs, wie auch immer die bei Wago das nennen wollen...) die direkt miteinander verbinden sind (Ethernet Kabel). IP-Bereich und alles passt.
In Steuerung 1 wird die OID registriert, in Steuerung 2 soll die OID ausgelesen werden.
Wie ist da jetzt das vorgehen?

Innerhalb von Steuerung 1 funktioniert registrieren, schreiben und lesen so:
Code:
//Registrieren
IF NOT OidsRegistriert THEN
       //     diOid umwandeln in TLV Format:
       SNMP_DINT_TO_TLV(diInput:= diOid, eDatatype:= SNMP_TLV_INTEGER, typData:= tlvSollwert);
       //     OID Registrieren und mit diOid im TLV Format beschreiben:
       FuSnmpAgent_CustomOIDRegister(sOID:= '.1.3.6.1.4.1.13576.1.1.1.0', typDefaultData:= tlvSollwert, xReadOnly:= FALSE);
       //     Registrierung abschliessen
       OidsRegistriert := TRUE;
END_IF;

//SET
IF xSetStart THEN
            SNMP_DINT_TO_TLV(diInput:= GvlAppSnmp.qdiOid, eDatatype:= SNMP_TLV_INTEGER, typData:= GetSetValue);
            FuSnmpAgent_CustomOIDSet(sOID:= '.1.3.6.1.4.1.13576.1.1.1.0', typData:= GetSetValue);
            xSetStart := FALSE;
END_IF

//GET
IF xGetStart THEN
            FuSnmpAgent_CustomOIDGet(sOID:= '.1.3.6.1.4.1.13576.1.1.1.0', typData:= GetSetValue);
            // Convert TLV to DINT
            SnmpGetTyp := SNMP_TLV_GET_TYPE(typData := GetSetValue);
            CASE SnmpGetTyp OF
                        SNMP_TLV_INTEGER:
                        SNMP_TLV_TO_DINT(typData:= GetSetValue, diValue:= GvlAppSnmp.qdiGetValue);                                 
            END_CASE                               
            xGetStart := FALSE;
END_IF

Lesen / Schreiben aus Steuerung 2 sollte entweder mit oSnmpManager oder dem FbSnmpManager funktionieren. TUt es aber nicht.
Aus dem Beispiel habe ich folgende Zeilen übernommen und erfolglos ausprobiert:


oSnmpManager:
Code:
//         ╔══════════════════════════════════╗
//         ║          ##################################    ║
//         ║          ########## oSnmpManager   ##########    ║
//         ║          ##################################    ║
//         ╚══════════════════════════════════╝

oSnmpManager_Get(
            sHost:= '10.31.197.16',
            sOID:= '.1.3.6.1.4.1.13576.1.1.1.0',
            sCommunity:= 'public');

oSnmpManager_Set(
            sHost:= '10.31.197.16',
            sOID:= '.1.3.6.1.4.1.13576.1.1.1.0',
            sCommunity:= 'public');

IF GvlAppSnmp.xSnmpReset THEN
            iState := 0;
            iStep := 0;
            GvlAppSnmp.xSnmpReset := FALSE;
END_IF

//         ┌----------------------------------------┐
//         |           ##########    SET       ##########    |
//         └----------------------------------------┘

CASE iState OF
            0:
                        IF GvlAppSnmp.xSnmpStart AND NOT oSnmpManager_Set.xBusy THEN
                                    GvlAppSnmp.xSnmpStart := FALSE;
                                    iState := 10;
                        END_IF
            10:
                        SNMP_DINT_TO_TLV(diInput:= GvlAppSnmp.qdiOid, eDatatype:= SNMP_TLV_INTEGER, typData:= oSnmpManager_Set.typData);
                        iState := 20;
            20:
                        oSnmpManager_Set.xExecute := TRUE;
                        iState := 30;
            30:
                        IF NOT oSnmpManager_Set.xBusy THEN
                                    IF oSnmpManager_Set.xError THEN
                                               (* Something went wrong: Check oStatus for details *)
                                               oStatus := oSnmpManager_Set.oStatus;
                                               iState := 999;
                                    ELSIF oSnmpManager_Set.xDone THEN
                                               iState := 900;
                                    END_IF
                                    oSnmpManager_Set.xExecute := FALSE;
                        END_IF

END_CASE

//         ┌-----------------------------------┐
//         |           ##########    GET                  ##########    |
//         └-----------------------------------┘

CASE iStep OF
            0:
                        IF xGetStart THEN
                                    xGetStart := FALSE;
                                    iStep := 10;
                        END_IF
            10:
                        oSnmpManager_Get.xExecute := TRUE;
                        iStep := 20;
            20:
                        IF NOT oSnmpManager_Get.xBusy THEN
                                    IF oSnmpManager_Get.xDone THEN
                                               iStep := 30;
                                    ELSE
                                               oStatus := oSnmpManager_Get.oStatus;
                                               iStep := 999;
                                    END_IF
                                    oSnmpManager_Get.xExecute := FALSE;
                        END_IF
            30:
                        SnmpGetTyp := SNMP_TLV_GET_TYPE(typData:=oSnmpManager_Get.typData);
                        SNMP_TLV_TO_DINT(typData:= oSnmpManager_Get.typData, diValue:= GvlAppSnmp.qdiGetValue);
                        iStep := 900;
//                     ELSE
//                                 iStep := 910;
//             END_IF
                        oSnmpManager_Get.xExecute := FALSE;

            // Wenn Schritt >900 dann Errorcode:
            // 900   =          Abfrage erfolgreich, Wert steht in GvlAppSnmp...
            // 910   =          Rückgabewert nicht vom Typ Int
            // 999   =          oStatus beachten                                             
END_CASE

Und so das Beispiel des FbSnmpManager:

Code:
//     ╔═════════════════════════════════════╗
//     ║ ################################### ║
//     ║ ########## FbSnmpManager ########## ║
//     ║ ################################### ║
//     ╚═════════════════════════════════════╝

FbSnmpManager_Get(
       sHost:= '10.31.197.16',
       sOID:= '.1.3.6.1.4.1.13576.1.1.1.0',
       sCommunity:= 'public',);
      
FbSnmpManager_Get(
       sHost:= '10.31.197.16',
       sOID:= '.1.3.6.1.4.1.13576.1.1.1.0',
       sCommunity:= 'public',);

//blk(ixStart:= TRUE, itOn:= GvlAppSnmp.tBlkTakt, itOff:= GvlAppSnmp.tBlkTakt, qxBlkTakt=> GvlAppSnmp.xSnmpStart);

//     ┌-------------------------------------┐
//     |      ##########   SET    ##########   |
//     └-------------------------------------┘

CASE iStepSet OF
       0:
             IF GvlAppSnmp.xSnmpStart AND NOT FbSnmpManager_Set.xBusy THEN
                    GvlAppSnmp.xSnmpStart := FALSE;
                    iStepSet := 10;
             END_IF
       10:
             SNMP_DINT_TO_TLV(diInput:= GvlAppSnmp.qdiOid, eDatatype:= SNMP_TLV_INTEGER, typData:= FbSnmpManager_Set.typData);
             iStepSet := 20;
       20:
             FbSnmpManager_Set.xExecute := TRUE;
             iStepSet := 30;
       30:
             IF NOT FbSnmpManager_Set.xBusy THEN
                    IF FbSnmpManager_Set.xError THEN
                           (* Something went wrong: Check oStatus for details *)
                           oStatus := FbSnmpManager_Set.oStatus;
                           iStepSet := 999;
                    ELSIF FbSnmpManager_Set.xDone THEN
                           iStepSet := 900;
                    END_IF
                    FbSnmpManager_Set.xExecute := FALSE;
             END_IF

END_CASE

IF GvlAppSnmp.xSnmpReset THEN
       iStepSet := 0;
       iStepGet := 0;
       GvlAppSnmp.xSnmpReset := FALSE;
END_IF

//     ┌-------------------------------------┐
//     |      ##########   GET    ##########   |
//     └-------------------------------------┘

CASE iStepGet OF
       0:
             IF xGetStart THEN
                    xGetStart := FALSE;
                    iStepGet := 10;
             END_IF
       10:
             FbSnmpManager_Get.xExecute := TRUE;
             iStepGet := 20;
       20:
             IF NOT FbSnmpManager_Get.xBusy THEN
                    IF FbSnmpManager_Get.xDone THEN
                           iStepGet := 30;
                    ELSE
                           oStatus := FbSnmpManager_Get.oStatus;
                           iStepGet := 999;
                    END_IF
                    FbSnmpManager_Get.xExecute := FALSE;
             END_IF
       30:
             SnmpGetTyp := SNMP_TLV_GET_TYPE(typData:=FbSnmpManager_Get.typData);
             SNMP_TLV_TO_DINT(typData:= FbSnmpManager_Get.typData, diValue:= GvlAppSnmp.qdiGetValue);
             iStepGet := 900;
//           ELSE
//                  iStepGet := 910;
//         END_IF
             FbSnmpManager_Get.xExecute := FALSE;

       // Wenn Schritt >900 dann Errorcode:
       // 900 =      Abfrage erfolgreich, Wert steht in GvlAppSnmp...
       // 910 =      Rückgabewert nicht vom Typ Int
       // 999 =      oStatus beachten                       
END_CASE
 
Hi,

sehe im zweiten Beispiel, daß Du FbSnmpManager_Get zweimal aufrufst (Copy/Paste Fehler?). Außerdem rufst Du den FB aus der Bibliothek direkt auf? Da mußt Du eigentlich erst eine Instanz von erzeugen.
Code:
VAR
    FbSnmpManagerGet : FbSnmpManager_Get;
END_VAR
Nur die Fu... Funktionen kannst Du direkt aufrufen.

Ist denn in oStatus irgendetwas?

Im WBM ist auch SNMP v1 aktiviert und als community 'public' eingetragen?

Gruß
 
Hi,

boah danke ey für dein Engagement!!! :love:

sehe im zweiten Beispiel, daß Du FbSnmpManager_Get zweimal aufrufst (Copy/Paste Fehler?).
Ja, ist ein Kopierfehler

Außerdem rufst Du den FB aus der Bibliothek direkt auf? Da mußt Du eigentlich erst eine Instanz von erzeugen.
Also, oSnmpManager_Get/Set wird mit
Code:
    oSnmpManager_Get: FbSnmpManager_Get;
    oSnmpManager_Set: FbSnmpManager_Set;
    oStatus : FbResult;
Instanziert.

Fehler bringt er folgenden:
1727157502727.png
ID = 211 → Timeout
Er bekommt also keine Verbindung -.-

Das mit Snmp V3 und V2c verstehe ich auch nicht so ganz, aber hier sind die Einstellungen des WebBasedManagement (WBM):
1727159237900.png
1727159265628.png
1727159286420.png
1727159304842.png

So, ziemlich viel Information.
Mein Verständnis ist, dass die Verbindung von Steuerung 1 zu 2 nicht zustande kommt, weil die SNMP Verbindung an den Einstellungen im WBM scheitert. Kann das sein?

Und ähm Thruser, ein unmoralisches angebot:
Stehst du für Telefonsupport zur Verfügung? Der Wagosupport ist mir nämlich keine große Hilfe. Ich schick dir auch n Kasten Bier vorbei =)

Grüße,

K.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ok, zum Beispiel habe ich grundlegende Fragen:
  1. Brauche ich einen SNMP Manager oder können beide Steuerungen als Agents miteinander kommunizieren?
  2. Sind die Steuerungen über das WBM als Agents parametriert und ist das richtig, was ich da gemacht habe?
  3. Falls ich einen SNMP Maste brauche, kann ich eine Steuerung auch als SNMP Master anlegen? Wenn ja, wie?
  4. Was ist ein SendTrap und wie funktioniert das?
    Grundlegen hierzu: Get / Set verstehe ich. Aber das funktioniert ja nur innerhalb einer Steuerung. Wenn ich von einer Steuerung zur anderen Senden / Empfangen möchte, wie ist da das vorgehen?
    Ich dachte, Steuerung 1 schreibt die OID und Steuerung 2 liest sie aus. Das scheint so einfach aber nicht zu funktionieren. Irgendwie muss Steuerung 1 zulassen, das der OID Wert gelesen wird (Trap???) und Steuerung 2 muss eine Leseanforderung schicken?
    Und was ist hierbei der Trap Receiver im WBM?
    Den Teil verstehe ich NULL.
  5. Welche Funktion brauche ich nun um die Daten auf Steuerung 1 zum Lesen bereit zu stellen und sie dann mit Steuerung 2 zu lesen?
 
Hi,

bin leider gerade mit einer Abnahme beschäftigt.

Habe gestern noch mal kurz etwas ausprobiert mit den Daten aus dem Anwendungshinweis. Dazu habe ich auch wie im Anwendungshinweis mit dem MIB Browser getestet und konnte Daten austauschen. Auch habe ich es kurz mit dem Get auf derselben Steuerung getestet. Für Set und zweiter Steuerung war keine zeit mehr, sollte aber ähnlich funktionieren.

SNMP Agent
Code:
PROGRAM PrgCustomMIB
(*
    This project demonstrates how to implement a custom specific SNMP-MIB. According to the example scenario in application note a500850 a airconditioning system is equipped with SNMP functionality:
    
    Four data points are published through SNMP:
    -----------------------------------------------------------------------------------
    |    Description        |  SNMP Name  | OID                        | Datatype | Access|
    -----------------------------------------------------------------------------------
      Type                  acsType        .1.3.6.1.4.1.65535.1.1.1.0     STRING        R
      Version              acsVersion    .1.3.6.1.4.1.65535.1.1.2.0     STRING        R
      Temp. actual value  acsActTemp    .1.3.6.1.4.1.65535.1.1.3.0     INT32        R
      Temp. set value     acsSetTemp    .1.3.6.1.4.1.65535.1.1.4.0     INT32        R/W
 *)

VAR
        xEnable        : BOOL;                         (* Enable function *)
        sHost         : STRING := '192.168.1.94';        (* IP address of trap receiver (SNMP Manager) *)        

        sType         : STRING := 'AirCon ACS 4711';    (* Type description of air conditioning system *)
        sVersion    : STRING := '1.0';                (* Version number of air conditioning system *)
        diActTemp    : DINT   := 23;                    (* Actual temperature: In real life this would be a reading from e.g. 750-458 (Thermocouple) *)            
        diSetTemp    : DINT   := 20;                    (* Set value: This value is received via SNMP (default: 20°C)*)
        
        sOidType    : STRING := '.1.3.6.1.4.1.65535.1.1.1.0'; 
        sOidVersion    : STRING := '.1.3.6.1.4.1.65535.1.1.2.0';
        sOidActTemp    : STRING := '.1.3.6.1.4.1.65535.1.1.3.0';
        sOidSetTemp    : STRING := '.1.3.6.1.4.1.65535.1.1.4.0';
        sCommunity    : STRING := 'public'; (* Name of SNMP community *)
        typData      : typSNMP_TLV; (* TLV variable that holds the converted DINT value. *)
        iState        : INT;            (* State machine *)
        typTLV         : eSNMP_TLV_DATATYPE;
        
        eSnmp_ResultCode2: eSnmp_ResultCode;
END_VAR
Code:
IF xEnable THEN
    CASE iState OF
        
        //------------------------------------------------------------------------------------------------------------ 
        // Register OID  (Type, acsType, .1.3.6.1.4.1.65535.1.1.1.0, STRING,R)
        //------------------------------------------------------------------------------------------------------------
        0:           
            //Initialise TLV variable with datatype "STRING" and set value to "sModel"
            SNMP_STRING_TO_TLV(sInput:= sType, eDatatype:= SNMP_TLV_STRING, typData:= typData);
                
            // Register OID as readonly            
            FuSnmpAgent_CustomOIDRegister(sOID:= sOidType, typDefaultData:= typData, xReadOnly:= TRUE); 
        
            // Update OID value
            SNMP_STRING_TO_TLV(sInput:= sType, eDatatype:= SNMP_TLV_STRING, typData:= typData);
            FuSnmpAgent_CustomOIDSet(sOID:= sOidType, typData:= typData);
            
            iState := 1;
        
            
        //------------------------------------------------------------------------------------------------------------ 
        // Register OID  (Version, acsVersion, .1.3.6.1.4.1.65535.1.1.2.0, STRING, R)
        //------------------------------------------------------------------------------------------------------------
        1:           
            //Initialise TLV variable with datatype "STRING" and set value to "sVersion"
            SNMP_STRING_TO_TLV(sInput:= sVersion, eDatatype:= SNMP_TLV_STRING, typData:= typData);
                
            // Register OID as readonly            
            FuSnmpAgent_CustomOIDRegister(sOID:= sOidVersion, typDefaultData:= typData, xReadOnly:= TRUE);
    
            // Update OID value 
            SNMP_STRING_TO_TLV(sInput:= sVersion, eDatatype:= SNMP_TLV_STRING, typData:= typData);
            FuSnmpAgent_CustomOIDSet(sOID:= sOidVersion, typData:= typData); 
        
            iState := 2;    
        
        //------------------------------------------------------------------------------------------------------------ 
        // Register OID  (Actual value, acsActTemp, .1.3.6.1.4.1.65535.1.1.3.0, INT32, R)
        //------------------------------------------------------------------------------------------------------------
        2:           
            //Initialise TLV variable with datatype "DINT" and set value to "diActTemp"
            SNMP_DINT_TO_TLV(diInput:= diActTemp, eDatatype:= SNMP_TLV_INTEGER, typData:= typData);
                
            // Register OID as readonly            
            FuSnmpAgent_CustomOIDRegister(sOID:= sOidActTemp, typDefaultData:= typData, xReadOnly:= TRUE); 
        
            iState := 3;    
            
        //------------------------------------------------------------------------------------------------------------ 
        // Register OID  (Set value, acsSetTemp, .1.3.6.1.4.1.65535.1.1.4.0, INT32, R/W)
        //------------------------------------------------------------------------------------------------------------
        3:           
            //Initialise TLV variable with datatype "DINT" and set value to "diSetTemp"
            SNMP_DINT_TO_TLV(diInput:= diSetTemp, eDatatype:= SNMP_TLV_INTEGER, typData:= typData);
                
            // Register OID as read/write
            FuSnmpAgent_CustomOIDRegister(sOID:= sOidSetTemp, typDefaultData:= typData, xReadOnly:= FALSE); 
        
            iState := 4;    
        
        //------------------------------------------------------------------------------------------------------------ 
        // Get set value from OID .1.3.6.1.4.1.65535.1.1.4.0 (Temperature set value): This value is received via SNMP
        //------------------------------------------------------------------------------------------------------------
        4:    
            // Read value from OID        
            FuSnmpAgent_CustomOIDGet(sOID:= sOidSetTemp, typData:= typData);
        
            // Convert TLV to DINT
            typTLV := SNMP_TLV_GET_TYPE(typData:=typData);
            CASE typTLV OF
                SNMP_TLV_INTEGER:
                    SNMP_TLV_TO_DINT(typData:= typData, diValue:= diSetTemp);            
            END_CASE            
        
            iState := 5;    
            
        //------------------------------------------------------------------------------------------------------------ 
        // Set values of OID .1.3.6.1.4.1.65535.1.1.3.0 (Temperature current value):  This value is readable via SNMP
        //------------------------------------------------------------------------------------------------------------
        5:
            // Write value to OID
            SNMP_DINT_TO_TLV(diInput:= diActTemp, eDatatype:= SNMP_TLV_INTEGER, typData:= typData);
            FuSnmpAgent_CustomOIDSet(sOID:= sOidActTemp, typData:= typData);
                
            iState := 4;
    END_CASE
    
    (* Here you can insert the code for air conditioning control *)
    (* ...                                                          *)
    (* Use "diActTemp" as setpoint for your temperature control  *)
    (* ...                                                          *)
    
    (* Send a V1 trap to SNMP Manager if current temperatur exeeds 40°C *)
    
    diActTemp := diSetTemp+10;
    
ELSE
        iState := 0;
END_IF

SNMP Manager mit FbSnmpManager_Get als CFC (ging schneller)
Code:
PROGRAM PrgGet
VAR
    FbSnmpManagerGet : FbSnmpManager_Get;
    xEnable : BOOL;
    typData : typSNMP_TLV;
    sHost : STRING := 'localhost';
    sCommunity : STRING := 'public';
    sOidActTemp    : STRING := '.1.3.6.1.4.1.65535.1.1.3.0';
    xError : BOOL;
    xBusy : BOOL;
    xDone : BOOL;
    oStatus : FbResult;
    diTemp: DINT;
    R_TRIG_0: R_TRIG;
END_VAR
1727160366235.png
Beide Programme aus dem Haupttask aufgerufen und die xEnable mit Debug per Werte schreiben gesetzt.

Wie schon geschrieben, Lesen und Schreiben funktionierte mit dem MIB Browser und der MIB Datei aus dem Anwendungshinweis.

Alles per SNMP v1. Das sieht soweit auch richtig aus, unter general SNMP aktivieren und die default Werte unter SNMP v1

Gruß
 
Per Definition können Agents nicht untereinander kommunizieren. Dazu müssen sie auch Manager Funktion erfüllen.

Also entweder Du definierst eine Steuerung als Manager/Master und die andere als Agent/Slave, oder du konfigurierst beide als Manager und Agent. Letzteres ist natürlich aufwendiger und Du mußt zusätzlich festlegen, ob jeweils beiede Steuerunge sowohl Lesen als auch Schreiben, beide nur Lesen oder beide nur Schreiben sollen.

Als Agent benötigst Du die Einstellungen im WBM und die Funktionen
FuSnmpAgent_CustomOIDRegister - zum registrien der OID für den SNMP Service der Steuerung
FuSnmpAgent_CustomOIDGet - zum Lesen der Werte aus dem SNMP Service, die Dir der Manager geschickt hat
FuSnmpAgent_CustomOIDSet - zum Schreiben der Werte in den SNMP Service - die dann der Manager anholt

Als Manager benötigst Du nur die beiden Funktionsbausteine in der benötigten Version V1 oder V3, mit oder ohne Time Out Funktion
FbSnmpManager_Get - zum Abfragen der Werte vom Agent
FbSnmpManager_Set - zum Setzen der Werte im Agent

Da der Manager die Daten immer vom Agent abrufen muß, ist es vom Abfrageintervall abhängig, wann er bestimmte Informationen bekommt. Wenn er also nur alle Stunde abfragt, bekommt er auch nur alle Stunde neue Informationen. Falls etwas dazwischen passiert bekommt er es nicht mit.

Daher gibt es noch zusätzlic die trap Funktion, darüber kann der Agent dem trap Receiver von sich aus melden, daß ein bestimmtes Ereignis eigetreten ist.

Das hilft Dir hier aber nicht, da mit der Bibliothek kein Trap receiver zur Verfügung gestellt wird.

Gruß
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Und eine Steuerung definiere ich als Manager in dem ich dort den FbSnmpManager... nutze und der Agent ist der, welcher die OIDs registrieren muss?
Oder muss ich da noch was im WBM einstellen?
 
ja also innerhalb einer Steuerung hab ich das auch hinbekommen, aber ich konnte den Wert aus der anderen Steuerung dann nicht lesen oder schreiben.
Aber ich versuche jetzt mal Steuerung 1 als Master mit FbSnmpManager_Get die Variable abzufragen, die ich in Steuerung 2 über FuSnmpAgent_CustomOIDRegister registriert habe.
Schauen wir mal, was dabei raus kommt.
Den Trap Receiver muss ich dann im WBM nicht anlegen?
 
Ok, es funktioniert.
Steuerung 1 registriert die OID und schreibt über FuSnmpAgent_CustomOIDSet einen Wert und kann ihn mit FuSnmpAgent_CustomOIDGet auch lesen.
Steuerung 2 liest den Wert mit FbSnmpManager_Get aus und kann den Wert mit FbSnmpManager_Set auch schreiben.

Ich bin schon mal überglücklich und viiiiiiiiel weiter. Aber leider noch nicht am Ziel 🏁
Ich müsste jetzt noch eine Verbindung zum Leitsystem 🖥️ herstellen, aber da bin ich nicht der Amdmin, das macht eine andere Firma -.-
Also, weiter geht die Reise... 🐌🐌

Aber ey Thruser, du wirst von mir auf jeden Fall zum User des Jahres vorgeschlagen! Hilfsbereit, freundlich und effektiv 🥳🍾
Ich frag mich nur immer wieder, wo ihr alle diese Zeit her nehmt so kompetent und ausführlich anderen zu helfen? =)
Freut mich auf jeden Fall, dass das Forum hier so gut funktioniert. 👍
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Schön, daß es jetzt funktioniert. Dann mußt Du jetzt ja nur das Interface für das Leitsystem festlegen.

Manchmal spricht einem ein Thema eben an. Mußte mich auch wegen eines anderen Auftrags etwas wegen SNMP beschäftigen. Das das so ausartet ;) konnte ich ja nicht ahnen. Datenaustausch bei einer SPS per SNMP ist denke ich auch eher etwas ungewöhnlich. Da denke ich eher an Modbus, Profinet/Profibus, CAN/openCAN, OPC, direkt per eigenem Protokoll etc.

Gruß
 
tja, Kundenwunsch ist Kundenwunsch.
Ist mir aber schon aufgefallen, dass es SNMP in der SPS Welt nicht so häufig gibt. Gibt kaum Experten dafür
Aber ist ja auch eine gute Übung =)
 
Zurück
Oben