2

im trying to read value from OPC over DA protocol. I have found that titanium-as is free, thats my condition. i'm using this manual, where is writen how to read values from OPC server, but only from groups which you made on OPC server with your own created variables. I wanna read values which are already on OPC server and create group from them so i can read their values.

SOLVED

Here is solution

 static void Main(string[] args)
    {
        TitaniumAS.Opc.Client.Bootstrap.Initialize();

        Uri url = UrlBuilder.Build("Kepware.KEPServerEX.V6");

        using (var server = new OpcDaServer(url))
        {
            server.Connect();
            OpcDaGroup MyGroup = server.AddGroup("MyGroup");
            MyGroup.IsActive = true;
            var browser = new OpcDaBrowserAuto(server);
            OpcDaBrowseElement[] MySimulation = browser.GetElements("Simulation.Functions");
            OpcDaItemDefinition[] definitions = new OpcDaItemDefinition[MySimulation.Count()];
            for (int i = 0; i < MySimulation.Count(); i++)
            {
                definitions[i] = new OpcDaItemDefinition { ItemId = MySimulation[i].ItemId, IsActive = true };
            }
            MyGroup.AddItems(definitions);
            MyGroup.ValuesChanged += OnGroupValuesChanged;
            MyGroup.UpdateRate = TimeSpan.FromMilliseconds(100); // ValuesChanged won't be triggered if zero           
        }
    }
    static void OnGroupValuesChanged(object sender, OpcDaItemValuesChangedEventArgs args)
    {
        // Output values.
        foreach (OpcDaItemValue value in args.Values)
        {
            Console.WriteLine("ItemId: {0}; Value: {1}; Quality: {2}; Timestamp: {3}",
                value.Item.ItemId, value.Value, value.Quality, value.Timestamp);
        }
    }

For forms you need to edit Program.cs like that

 static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// 
    /// </summary>
    //[STAThread]
    
    static void Main()
    {
        TitaniumAS.Opc.Client.Bootstrap.Initialize();
        var thread = new Thread(RunApplication);
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();  
    }
    static void RunApplication()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

Many thanks for any advise.

  • So creating a group is the problem? [docs](https://github.com/titanium-as/TitaniumAS.Opc.Client#creating-a-group-with-items) . Seems like you are missing some stuff like `OpcDaGroup group = server.AddGroup("MyGroup");` and `group.IsActive = true;`? – lordvlad30 Jul 01 '20 at 07:34
  • Adding items to group is my problem, i cant figure how to read items from OPC and this items add to my group – Jiří Poštulka Jul 01 '20 at 07:40
  • Seeing your code, you have not even initialised your group using the `MyGroup = server.AddGroup("MyGroup")` code. What error do you get when running? Give more details about the problem. – lordvlad30 Jul 01 '20 at 07:47
  • Forgive me, i think that its not initialization, but adding new group to OPC server. Error is on this line `definitions[i].ItemId = MySimulation[i].ItemId; ` it returns Object reference not set to an instance of an object. in variable `MySimulation` i got 17 items, but i cant transfer them to `definitions` – Jiří Poštulka Jul 01 '20 at 07:53
  • So you want to retrieve the structure from the server and read those values? For that you will need to write some recursive methods for browsing the structure tree: this is some sample code: [link](https://github.com/titanium-as/TitaniumAS.Opc.Client#browsing-elements) . When you get the `element` you can probably get the `ItemId` from it and create a new `OpcDaItemDefinition` and add that to your group. – lordvlad30 Jul 01 '20 at 08:00
  • Many thanks for your time, i have figure it out, i will update code. – Jiří Poštulka Jul 01 '20 at 08:03
  • Okay, I see, gonna give some sample code to fix that issue – lordvlad30 Jul 01 '20 at 08:03

1 Answers1

2

So the problem is when you iterate your definitionscollection you have not really added any items to it yet:

OpcDaItemDefinition[] definitions = new OpcDaItemDefinition[MySimulation.Count()];
for (int i = 0; i < MySimulation.Count(); i++)
{
      definitions[i] = new OpcDaItemDefinition(...);
      //definitions[i].ItemId = MySimulation[i].ItemId;
      //definitions[i].IsActive = true;
}
MyGroup.AddItems(definitions);

This should solve that error.

EDIT: just saw your edit, you solved it too.

lordvlad30
  • 391
  • 1
  • 17
  • Yes, this was a problem, sorry for my stupidity not seeing that. At least maybe this will help someone. – Jiří Poštulka Jul 01 '20 at 08:08
  • No problem, glad you found it. – lordvlad30 Jul 01 '20 at 08:17
  • i have found another problem ... what if i will try to move this solution to windows Forms app. i cant find place where to put `TitaniumAS.Opc.Client.Bootstrap.Initialize();` i have tried to put in to `static void Main()`, but this giving me error `ExternalException: CoInitializeSecurity: Security must be initialized before any interfaces are marshalled or unmarshalled. It cannot be changed once initialized.`. Thank you again for any advice. – Jiří Poštulka Jul 01 '20 at 09:05
  • Looking at the source code for that method it has some more information on how to use it: [source file](https://github.com/titanium-as/TitaniumAS.Opc.Client/blob/master/TitaniumAS.Opc.Client/Bootstrap.cs). – lordvlad30 Jul 01 '20 at 09:20
  • Thanks, i have edited my question. hopefully i done it right way – Jiří Poštulka Jul 01 '20 at 09:41
  • I have never needed this library but if your problems are solved by these changes then you should be fine. I would suggest to make different questions for each problem next time ;). – lordvlad30 Jul 01 '20 at 10:31