Hallo Zusammen,
ich muss einen OPC UA Client in C# programmieren.
Leider komm ich mit den Samples nicht so gut klar.
Kann hier jemand mich unterstützen bzw. eine detailierte Anleitung nennen?
Mti einem fertigen "Client" komme ich schon auf den SErver drauf.
Aber wie ich jetzt starten soll bei der programmierung habe ich keinen Plan, bei dem Thema OPC.
Vorallem in Bezug welche spezielle DLL muss eingebunden werden.
Was benötige ich genau für Aufbau der Verbindung. usw.
Hab bis jetzt nur "kleine" Änderungen oder ganz einfache Programme in C# gelöst. Komme aus der SPS Programmierung.
Danke
thetrock
Hallo,
auf Github sind einige Lib und Examples, vielleicht hilft dir das.
**:::
Hi vbprogger,
danke für die schnelle Antwort.
Ich komm mit dem Samples/Lib nicht so gut zurecht,
weiß nicht was genau ich da einnbinden muss oder auch nicht.
Bräuchte am besten Info, welche Lib/Sample wie eingesetz wird und dann wie die Befehle implementiert werden müssen.
Hi hab jetzt von
https://github.com/convertersystems/...App/Program.cs
den Code benutzt.
wie kann ich jetzt auf Variablen genau zugreifen?
Hab folgende nodeid ns=3;s="DbInfo"."Parameter"."Station1"
Dein Link geht nicht; und da https://github.com/convertersystems viele Samples hat weiß hier keiner, welches Du meinst.
Aber im Zweifel einfach das Repo Clonen und die Projekte / Solutions in Visual Studio laden.
Ich habe in der Vergangenheit mehrfach genau diesen GitHub User für/in OPC UA Schulungen verwendet / gezeigt.
Daher kann ich Dir aus Erfahrung sagen: das Zeug läuft und lief auch ohne Probleme bei den Schulungsteilnehmern.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Bezogen auf das Beispiel verlinkt von T-Virus bekommt man alle Informationen der Anfrage im browseRequest
Objekt vom Typ BrowseResponse
(ähnlich wie es bei HTTP eben HttpResponse
verhält).
Ganz normales Service Behavior-Verhalten.
Was versendet wird sieht man in https://github.com/convertersystems/opc-ua-samples/tree/master/RobotServer
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo zusammen,
Hier die Anfrage an den Server
browseRequest = new BrowseRequest
{
NodesToBrowse = new BrowseDescription[] { new BrowseDescription { NodeId = ExpandedNodeId.ToNodeId(rd2.NodeId, channel.NamespaceUris), BrowseDirection = BrowseDirection.Forward, ReferenceTypeId = NodeId.Parse(ReferenceTypeIds.HierarchicalReferences), NodeClassMask = (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, IncludeSubtypes = true, ResultMask = (uint)BrowseResultMask.All } },
};
browseResponse = await channel.BrowseAsync(browseRequest);
foreach (var rd3 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
wie kann ich rd2.NodeId ersetzten?
Was bewirkt die Zeilte (sieh unten) genau?
browseResponse = await channel.BrowseAsync(browseRequest);
foreach (var rd3 in browseResponse.Results[0].References ?? new ReferenceDescription[0])
wie kann ich rd2.NodeId ersetzten?
Die Frage ist unklar. Gib halt was anderes an....? 🤔
Was bewirkt die Zeilte (sieh unten) genau?
null
sein sollte).- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Ich hab rd2.NodeID ausgelesen und hier steht
ns=3;s=PLC
wenn ich das dort als string eingebe übersetzt er es nicht.
Wie kann ich jetzt das rd2.NodeID richtig ersetzten???
Als nächstes, wollte ich eine spezielle Variable auslesen. ID ist bekannt.
wie lautet dan dazu der Befehlt.
Gibt es hierfür auch eine Literatur oder ähnliches?
Danke Gruß thetrock
Die Node-ID kommt vom Server, die brauchst du auch zur Zuordnung.
Nach dem Browsen solltest du ja alle Node-ID's haben, du gibst ja beim Browsen an, das du auch die Variablen haben möchtest.
Browsen und setzen von Werten sind aber zwei unterschiedliche Dinge.
Normalerweise must du ein Property des OPC-Items setzen.
Danke für die schnelle Antwort.
Kann es sein, dass ich gar nicht Browsen muss???
Der Browse Requeste, lässt alle daten darstellen.
soweit verstanden.
Wie kann ich jetzt genau eine spezielles Objet darstellen
ID
ns=3;s="DbTest"."Test".Data1
bzw. muss ich ein Objetk anlegen mit der ID und kann dann auf die einzelenen Attribute zugrefein (NodeClass, BrowseName,Value, ...)
wie kann ich rd2.NodeId ersetzten?
konnte jetzt ersetz werden
NodeId.Parse("ns=3;s=PLC")
Wenn du die Node-ID kennst must du nicht zwangsweise browsen.
Du must die Items, die du benötigst, beim Server abonieren, damit bekommst du die Wertänderungen.
Wenn der Server ein Schreiben des Wertes zulässt, kannst du dann auch den Wert ändern.
Hier wird das Abo erstellt
Console.WriteLine("Step 5 - Create a subscription.");
var subscriptionRequest = new CreateSubscriptionRequest
{
RequestedPublishingInterval = 1000,
RequestedMaxKeepAliveCount = 10,
RequestedLifetimeCount = 30,
PublishingEnabled = true
};
var subscriptionResponse = await channel.CreateSubscriptionAsync(subscriptionRequest);
var id = subscriptionResponse.SubscriptionId;
JEtzt muss ich nur noch die Variablen/Items dem Abo hinzufügen.
Console.WriteLine("Step 6 - Add items to the subscription.");
var itemsToCreate = new MonitoredItemCreateRequest[]
{
new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=3;s=SerialNumber"), AttributeId = AttributeIds.Value }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 12345, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }
};
var itemsRequest = new CreateMonitoredItemsRequest
{
SubscriptionId = id,
ItemsToCreate = itemsToCreate,
};
var itemsResponse = await channel.CreateMonitoredItemsAsync(itemsRequest);
Den Part verstehe ich nur noch nicht.
Wenn ich die NodeID hier eingebe bekomme ich keine Output raus
Console.WriteLine("Step 7 - Subscribe to PublishResponse stream.");
122 var token = channel.Where(pr => pr.SubscriptionId == id).Subscribe(pr =>
123 {
124 // loop thru all the data change notifications
125 var dcns = pr.NotificationMessage.NotificationData.OfType<DataChangeNotification>();
126 foreach (var dcn in dcns)
127 {
128 foreach (var min in dcn.MonitoredItems)
129 {
130 Console.WriteLine($"sub: {pr.SubscriptionId}; handle: {min.ClientHandle}; value: {min.Value}");
131 }
132 }
133 });
So, jetzt bekomme ich schon ein Value zurück.
aber wenn meine node ID wiefolgt aussieht
ns=3;s="DbMachineConfiguration"."Parameter"."Bedienung"
bringt er mir ein Fehler, da ja mehrere Strings sind.
Daher meine Frage wie kann ich das lösen und wie kann ich mehrere Items anlegen um das Value und Name auszulesen zu können.
die NodeID ist die "Adresse" des OPC Items.
Hier hast du Strings, die NodeID kann aber auch ein INT oder eine GUID sein.
Das Item hat dann verschiedene Properties.
Ein Property ist "Value", wo der Wert drin steht.
Das ansprechen via NodeId funktioniert für ns=3;s=DeviceManual
aber wenn ich andere Daten auslesen will, ist hat die NodeId wiefolgt
ns=3;s="DbMachineConfiguration"."Parameter"."Bedienung"
aber das geht ja nicht, da es mehrer Strings sind.
Wie kann ich das lösen?
Kann es sein, das bei dem Sample ich nicht so viele Attribute auslesen kann?
ns=3;s="DbMachineConfiguration"."Parameter"."Bedienung"
aber das geht ja nicht, da es mehrer Strings sind.
Warum mehrere Strings?
" ist einfach ein Zeichen mehr nicht.
Folgender Code geht
NodeId.Parse("ns=3;s=DeviceManual")
Folgender Code geht nicht
NodeId.Parse("ns=3;s="DbMachineConfiguration"."Parameter"."Laser"")
--> aber die NodeID wird mir so angezeigt
Du übernimmst die Anführungszeichen nicht richtig. Die sind Teil des Strings.
Du must den String richtig zusammenbauen. Das sind aber Grundlagen.
NodeId.Parse("ns=3;s=\"DbMachineConfiguration\".\"Parameter\".\"Laser\"")
@MartinH vielen Dank.
Console.WriteLine("Step 6 - Add items to the subscription.");
var itemsToCreate = new MonitoredItemCreateRequest[]
{
new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=3;s=\"DbMachineConfiguration\".\"Parameter\".\"Lasertime\"") , AttributeId = AttributeIds.Value }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 12345, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }
};
var itemsRequest = new CreateMonitoredItemsRequest
{
SubscriptionId = id,
ItemsToCreate = itemsToCreate,
};
var itemsResponse = await channel.CreateMonitoredItemsAsync(itemsRequest);
Console.WriteLine("Step 7 - Subscribe to PublishResponse stream.");
var token = channel.Where(pr => pr.SubscriptionId == id).Subscribe(pr =>
{
// loop thru all the data change notifications
var dcns = pr.NotificationMessage.NotificationData.OfType<DataChangeNotification>();
foreach (var dcn in dcns)
{
foreach (var min in dcn.MonitoredItems)
{
Console.WriteLine($" value: {min.Value}");
}
}
});
Jetzt stellt sich mir die Frage, wo ich mehrer Imtes anlegen kann fürs auslesen?
Das kann ich dir auch nicht sagen, ich kenne die LIB nicht.
Ich arbeite da mit den Softing Toolkits.
Kann hier noch jemand weiterhelfen ´mit der LIB
bzw. kennt jemand einen guten opensource LIB mit Beschreibung?
Der Quellcode ist doch offen.
Wenn die Dokumentation nicht ausreicht, dann schau Dir den Quellcode an.
Alternativ den Entwickler fragen und auf Antwort hoffen.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hab leider zu der Lib keine Dokumentation gefunden.
Wenn es so leicht wäre, würde ich hier nicht fragen.
Vielleicht kann trotzdem jemand mir noch weiterhelfen
Jetzt stellt sich mir die Frage, wo ich mehrer Imtes anlegen kann fürs auslesen?
Gruß thetrock
Das hast du doch da:
var itemsToCreate = new MonitoredItemCreateRequest[]
{
new MonitoredItemCreateRequest { ItemToMonitor = new ReadValueId { NodeId = NodeId.Parse("ns=3;s=\"DbMachineConfiguration\".\"Parameter\".\"Lasertime\"") , AttributeId = AttributeIds.Value }, MonitoringMode = MonitoringMode.Reporting, RequestedParameters = new MonitoringParameters { ClientHandle = 12345, SamplingInterval = -1, QueueSize = 0, DiscardOldest = true } }
da MonitoredItemCreateRequest ein Array ist, kannst du doch da einfach mehrere Items anlegen.
Items anlegen hat funktioniert.
Leider kann ich nur den Inhalt der Variable auslesen, wie kann ich auf weiter Eigentschaften zugreifen?
Wie schaut der Vorgang aus, wenn ich den Wert verändern will.
Sollte das mit dem auslesen begrenzt sein, kann jemand eine ander LIB empfehlen.
thetrock