Professional OPC
Development Tools

logos

Online Forums

Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.

Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.

Do not use the Contact page for technical issues.

DUE TO ADMINISTRATIVE REASONS, WE MAY NOT BE ABLE TO RESPOND (OR TO RESPOND AS QUICKLY AS USUAL) BETWEEN August 19 - August 30, 2022. WE APOLOGIZE FOR INCONVENIENCE.

Problem with mapping arrays

More
03 Aug 2018 13:30 #6588 by support
Replied by support on topic Problem with mapping arrays
It would be better is the type of ModeCumulativeTimeException was Exception, and the type of ModeCumulativeTimeStatusInfo was StatusInfo.

OK, if these do not give an error indication, please proceed with trying to see if there aren't other kinds of errors, as indicated in the article opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...n%20the%20Mapper%20Object.html .

That is, please hook a handler to the mapper's UpdateFailure event, and check if it doesn't called, and if so, what error data it receives.

Best regards

Please Log in or Create an account to join the conversation.

More
03 Aug 2018 11:33 #6587 by ab
Replied by ab on topic Problem with mapping arrays
I made changes proposed by you in code. Now it looks like this:
public void testArray()
        {
            UAClientMapper mapper = new UAClientMapper();
            TestArray device = new TestArray(); //{ BrowswerPath = "[ObjectsFolder]/PLC1500/Device1/Program_blocks/UM01_przyklad/Data/UM01_PackTags/Admin" };//"program_blocks/UM01_przyklad/Data/UM01_PackTags" };
 
            UANodeDescriptor uANodeDescriptor = new UANodeDescriptor
            {
                BrowsePath = UABrowsePath.Parse("[ObjectsFolder]/PLC1500/Device1/Program_blocks/UM01_przyklad/Data/UM01_PackTags/Admin", "KEPServerEX")
 
            };
 
            UAEndpointDescriptor uAEndpointDescriptor = new UAEndpointDescriptor("opc.tcp://127.0.0.1:49320");
            var uaNodeElementCollection = mapper.Client.BrowseDataNodes(uAEndpointDescriptor);
 
            mapper.Map(device, new UAMappingContext
            {
                EndpointDescriptor = uAEndpointDescriptor,
                NodeDescriptor = uANodeDescriptor,
                MonitoringParameters = 1000
            });
 
            mapper.Read();
 
            var easyUAClient = new EasyUAClient { Isolated = true };
            var a = easyUAClient.Read(uAEndpointDescriptor, "nsu=KEPServerEX;ns=2;s=PLC1500.Device1.Program_blocks.UM01_przyklad.Data.UM01_PackTags.Admin.ModeCumulativeTime");
 
            var b = device.ModeCumulativeTime;
        }
 
[UAType]
    [UANamespace("KEPServerEX")]
    public class TestArray : IBrowsePath
    {
        public TestArray()
        {
            ModeCumulativeTime = new long[6];
        }
 
 
        [UANode(BrowsePath = "[ObjectsFolder]/PLC1500/Device1/Program_blocks/UM01_przyklad/Data/UM01_PackTags/Admin/ModeCumulativeTime"), UAData]
        public long[] ModeCumulativeTime { get; set; }
 
        [UANode(BrowsePath = "[ObjectsFolder]/PLC1500/Device1/Program_blocks/UM01_przyklad/Data/UM01_PackTags/Admin/ModeCumulativeTime"), UAData(Kind = UADataMappingKind.ErrorMessage )]
        public string ModeCumulativeTimeErrorMessage { get; set; }
 
        [UANode(BrowsePath = "[ObjectsFolder]/PLC1500/Device1/Program_blocks/UM01_przyklad/Data/UM01_PackTags/Admin/ModeCumulativeTime"), UAData(Kind = UADataMappingKind.Exception )]
        public string ModeCumulativeTimeException { get; set; }
 
        [UANode(BrowsePath = "[ObjectsFolder]/PLC1500/Device1/Program_blocks/UM01_przyklad/Data/UM01_PackTags/Admin/ModeCumulativeTime"), UAData(Kind = UADataMappingKind.StatusInfo)]
        public string ModeCumulativeTimeStatusInfo { get; set; }
 
 
        public string BrowswerPath { get; set; }
}

Unfortunately, nothing has changed. Still, "b" array is full of zeros.
ModeCumulativeTimeErrorMessage is empty string.
ModeCumulativeTimeException is empty string.
ModeCumulativeTimeStatusInfo is "Normal".

Please Log in or Create an account to join the conversation.

More
03 Aug 2018 07:05 #6582 by support
Replied by support on topic Problem with mapping arrays
To the last part of your question ("can I map array of objects): If, what you mean, are multiple individual OPC UA nodes that "look like" an array of nodes, the answer is No - there is nothing special for that in Live Mapping. The reason for that is that there is no such thing as "array of nodes" in OPC UA - it would be completely vendor-specific construct, but to OPC UA, it is just a bunch of nodes - even if their names or IDs are constructed in some kind of consistent way (containing an index).

If you need to access this kind of OPC UA address space structure, it might be better to use the traditional approach and not the Live Mapping.

Please Log in or Create an account to join the conversation.

More
03 Aug 2018 07:02 #6581 by support
Replied by support on topic Problem with mapping arrays
Hello.

The reason you get all zeroes is most likely because all zeroes is the initial contents, and no *successful* Read has actually taken place.

First to do when troubleshooting problems with Live Mapping is to understand which kind of errors can happen and how they are reported. You normally do not get any exceptions thrown with Live Mapping, so you need to take care of the error detection yourself. Read this: opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...n%20the%20Mapper%20Object.html .

IN your case, the "D. Mapping source problems" is probably what matters. Add a mapping with mapping kind e.g. Exception or ErrorMessage, for the same node, to see what the error is (opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...rame.html#Mapping%20Kinds.html) .

But, from looking at your program, it is kind of clear that it cannot work. It is not doing any true mapping at all. It looks like that you are somehow trying to define the browse path from the code by setting it into your BrowsePath property. But Live Mapping has no idea that it is where the browse path is. In Live Mapping, you need to specify the browse path in the DANode attribute - see e.g. the example here: opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...#Live%20Mapping%20Example.html .

If you have a requirement to map the same object multiple times, using different "start browse paths", that should be doable too, and we can help wit that - but first start with the "static" approach and make it work. Also, at least in on of your posts, I have noticed that the BrowsePat was incrrect (was missing a starting '').

Two-dimensional arrays are mapped the same as anything else. As long as you read/write/subscribe to the array as a whole, it does not matter (mapping-wise) what the actual type is, because the value is transferred as one a whole.

Best regards

Please Log in or Create an account to join the conversation.

More
03 Aug 2018 06:15 #6578 by ab
Hello

I have a problem with reading tables from the OPC UA server.
I do not know why, but if I use mapping objects, their values are always zeros after reading from opc.
If I read them directly, the values in the array are valid.
What am I doing wrong?

The following example illustrates the problem.
public void testArray()
{
	UAClientMapper mapper = new UAClientMapper();
	TestArray device = new TestArray { BrowswerPath = "[ObjectsFolder]/PLC1500/Device1/Program_blocks/UM01_przyklad/Data/UM01_PackTags" };//"program_blocks/UM01_przyklad/Data/UM01_PackTags" };
 
	UANodeDescriptor uANodeDescriptor = new UANodeDescriptor
	{
		BrowsePath = UABrowsePath.Parse(device.BrowswerPath, "KEPServerEX")
 
	};
 
	UAEndpointDescriptor uAEndpointDescriptor = new UAEndpointDescriptor("opc.tcp://127.0.0.1:49320");
	var uaNodeElementCollection = mapper.Client.BrowseDataNodes(uAEndpointDescriptor);
 
	mapper.Map(device, new UAMappingContext
	{
		EndpointDescriptor = uAEndpointDescriptor,
		NodeDescriptor = uANodeDescriptor,
		MonitoringParameters = 1000
	});
 
	mapper.Read();
 
	var easyUAClient = new EasyUAClient { Isolated = true };
	var a = easyUAClient.Read(uAEndpointDescriptor, "nsu=KEPServerEX;ns=2;s=PLC1500.Device1.Program_blocks.UM01_przyklad.Data.UM01_PackTags.Admin.ModeCumulativeTime");
 
	var b = device.ModeCumulativeTime;
}
 
[UAType]
[UANamespace("KEPServerEX")]
public class TestArray : IBrowsePath
{
	public TestArray()
	{
		ModeCumulativeTime = new long[6];
	}
 
	[UAData]
	[UANode]
	public long[] ModeCumulativeTime { get; set; }
 
	public string BrowswerPath { get; set; }
}
After executing the code, the values for the variable "a" are for example [1, 2, 3, 10, 100, 5] and for "b" are always [0, 0.0,0,0,0], why? It's the same array in opc.

What should mapping look like if we have a two-dimensional array? Can I easily map an array of objects, for example: MyClass[]?

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.081 seconds