-2

Actually asked for this once but seems like no one gave me the expected answer :( I'm trying to create a OPC UA Client in Unity3D. To be more specific, it will be something like: a simple scene with only a Text. That Text shows the value of a variable read from OPC UA Server. I added this code (found on stackoverflow) but it didn't work.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Opc.Ua; 
using Opc.Ua.Client;
using Opc.Ua.Configuration;

public class main : MonoBehaviour
{

private async void Start()
{
    Console.WriteLine("Step 1 - Create a config.");
    var config = new ApplicationConfiguration()
    {
        ApplicationName = "test-opc",
        ApplicationType = ApplicationType.Client,
        SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier() },
        TransportConfigurations = new TransportConfigurationCollection(),
        TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
        ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 }
    };
    await config.Validate(ApplicationType.Client);
    if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates)
    {
        config.CertificateValidator.CertificateValidation += (s, e) => { e.Accept = (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted); };
    }

    Console.WriteLine("Step 2 - Create a session with your server.");
    using (var session = await Session.Create(config, new ConfiguredEndpoint(null, new EndpointDescription("opc.tcp://localhost:4841")), true, "", 60000, null, null))
    {
        Console.WriteLine("Step 3 - Browse the server namespace.");
        ReferenceDescriptionCollection refs;
        byte[] cp;
        session.Browse(null, null, ObjectIds.ObjectsFolder, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out cp, out refs);
        Console.WriteLine("DisplayName: BrowseName, NodeClass");
        foreach (var rd in refs)
        {
            Console.WriteLine(rd.DisplayName + ": " + rd.BrowseName + ", " + rd.NodeClass);
            ReferenceDescriptionCollection nextRefs;
            byte[] nextCp;
            session.Browse(null, null, ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out nextCp, out nextRefs);
            foreach (var nextRd in nextRefs)
            {
                Console.WriteLine("+ " + nextRd.DisplayName + ": " + nextRd.BrowseName + ", " + nextRd.NodeClass);
            }
        }

        Console.WriteLine("Step 4 - Create a subscription. Set a faster publishing interval if you wish.");
        var subscription = new Subscription(session.DefaultSubscription) { PublishingInterval = 1000 };

        Console.WriteLine("Step 5 - Add a list of items you wish to monitor to the subscription.");
        var list = new List<MonitoredItem> {
            new MonitoredItem(subscription.DefaultItem) { DisplayName = "aaatime", StartNodeId = "i=10004" } };
        list.ForEach(i => i.Notification += OnNotification);
        subscription.AddItems(list);

        Console.WriteLine("Step 6 - Add the subscription to the session.");
        session.AddSubscription(subscription);
        subscription.Create();

        Console.WriteLine("Finished client initialization");
    }
}

private static void OnNotification(MonitoredItem item, MonitoredItemNotificationEventArgs e)
{
    foreach (var value in item.DequeueValues())
    {
        Console.WriteLine("{0}: {1}, {2}, {3}", item.DisplayName, value.Value, value.SourceTimestamp, value.StatusCode);
    }
}
}

For my expectation, it will be something like: when I press Play, the Unity app run and connect to my OPC UA Server, then, it reads the value of a variable from Server, and displays that value in Text. So what I do is create a Unity project -> a scene -> a canvas -> a text, a C# Script (code above). But when I add the Script to the Canvas, it is a notification like: can't add script, make sure there are no compiler error and file name and class name are matched. I think I have already checked all of them, but there is not any errors.
Can you suggest me some solution with my problems?
P/S: the code was from this thread: Create a very simple OPC client in Unity3d with opc ua .net library

mononaro
  • 13
  • 5
  • Please given more details. What does "It didn't work" mean? What did you expect? What did you observe? – Klaus Gütter May 27 '20 at 15:01
  • Hi Klaus. For my expectation, it will be something like: when I press Play, the Unity app run and connect to my OPC UA Server, then, it reads the value of a variable from Server, and displays that value in Text. So what I do is create a Unity project -> a scene -> a canvas -> a text, a C# Script (code above). But when I add the Script to the Canvas, it is a notification like: can't add script, make sure there are no compiler error and file name and class name are matched. I think I have already checked all of them, but there is not any errors. – mononaro May 27 '20 at 15:18
  • Please add this information to your question instead of posting it as comment. Comments will be easily overlooked. – Klaus Gütter May 27 '20 at 15:20
  • Thank you for your feedback. I have already editted my post. – mononaro May 27 '20 at 15:27

2 Answers2

0

One solution would be to kick the opc-ua client and make REST requests if you are not familiar with opc-ua. This could be achieved with a opc-ua to rest translator like Konektilo (https://konektilo.de/) and a rest client for unity (https://assetstore.unity.com/packages/tools/network/rest-client-for-unity-102501).

I also made the experience, that some opc-ua clients are not working on all platforms on which you can run unity applications.

M.List
  • 1
  • 1
  • I'm afraid that OPC UA is the key requirement. Do you have any solutions to match OPC UA to my Unity project? – mononaro May 27 '20 at 15:29
0

i created a working opc ua client for unity with the example from OPC UA : minimal code that browses the root node of a server

But also I like the idea of @M.List with his Rest-OPC UA-Gateway, becaue unity has a own libary for REST-Communication.

But if its an requirement for you to use opc ua, following a short explanation how i could get it run in my project I first tried the example in a normal console app in visual studio. After succesfull testing i copied all dll's of my console app into a own created plugins folder in unity. If you create in your unity project a Folder named Plugins, you can put there dll's which unity autonomous includes into your project for usage. You need all those dll's Afterwards i created a script "opcUaClient" with the code from the example. The Start up Method of Unity is the Main Method and the Update Method is the OnNotification Method of the example Till now i only could accomplish to run this client in unity when pressing the play button. I could not deploy it to android or hololens.

But the easiest way is to the OPC UA-Client from games4automation in the unity asset store. I tried it and it works great.

Regards Stefan

  • Hi Stefan, firstly I have to say that I need sometime to digest all your instruction so do you mind continue helping me after a few days? Secondly, I actually need to make an Android app by Unity, so if I choose to use REST like @M.List, is that possible? Thirly, I have seen the package made by games4automation but it is paid, right? Unfortunately I'm just doing my thesis and I cannot afford $350 for it :( – mononaro May 28 '20 at 15:56