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.
Mapping collection
- miron
- Topic Author
- Visitor
Thank you.
Please Log in or Create an account to join the conversation.
You can probably achieve the goal by mapping the known objects first, and then invoke the mapping repeatedly for the objects that should reside in the collection and put them into the collection yourself, similarly as you have don in the example you have provided in the beginning.
Best regards
Please Log in or Create an account to join the conversation.
- miron
- Topic Author
- Visitor
2. It could be e.g.: List<T>, Array<T>[]
3. Yes, number of instances is not know during compilation time
4. There is some key of naming branches for items .e.g.: dev1, dev2, ....
Bigger example:
[DAType]
public class DeviceA
{
[DASubPath]
public string DeviceIdCode {get;set;}
[DANode()]
[DAItem()]
public int SomeStatus {get;set;}
}
[DAType]
public class DeviceB
{
[DASubPath]
public string DeviceIdCode {get;set;}
[DANode()]
[DAItem()]
public int SomeStatus {get;set;}
}
[DAType]
public class ProductionLine
{
[DANode()]
[DAItem()]
public int OtherSomeStatuses {get;set;}
[DANode()] //<--- ??????
public List<DeviceA> DevicesA {get;set;}
[DANode()] //<--- ??????
public List<DeviceB> DevicesB {get;set;}
}
And question is:
How I could mapp this type.
//1. Loading devices from configuration
ProductionLine pl = LoadFromConfiguration();
//now "pl" contains e.g. 10 devices A and 15 devices B.
//2. Now I would like mapp this object (with out loop)
var mapper = new DAClientMapper();
mapper.Map(pl, new DAMappingContext
{
ServerDescriptor = sd, // local OPC server
NodeDescriptor = new DANodeDescriptor
{ BrowsePath = "/TestChannel/MainGroup/ProductionLine/"},
GroupParameters = 1000,
});
}
Goal would be that I could send "pl" (ProductionLine) to mapper,
and mapper could work with object in collection, and make mapping by some key.
It could use e.g. some property which contain "sub path" for each property.
I have added [DASubPath] attribute.
Please Log in or Create an account to join the conversation.
Please Log in or Create an account to join the conversation.
- miron
- Topic Author
- Visitor
What is good practice of mapping C# collection?
Maybe I could use attribute DANode or DAItemIdTemplate to mark collection?
That means the main question is: how to pass information to mapper about how to map item of collection?.
(I have made investigation and it works when I add object to mapping to one instance of mapper or to separate).
Please Log in or Create an account to join the conversation.
- miron
- Topic Author
- Visitor
I have made mistake with addressing simulation tag.
Variables are type of 'long' but address which I put overlapped addresses.
And one write was interfered to another. I am sorry.
Linq Pad is very useful to quick scrat code. File Linq beside C# code, also contains
reference to assembly and declaration of namespaces.
To execute code it is not necessary build code.
Please Log in or Create an account to join the conversation.
To Question 2: If you meant to use separate mapper instances, then the answer is negative: It should not be necessary.
I will run your code when I get back to the office (tomorrow, likely), and let you know my findings then.
One last thing: Please switch to latest version (5.32).
Best regards
BTW, just in case we need it in future, I have enabled the .CSV a .LINQ file extensions on the forums now.
Please Log in or Create an account to join the conversation.
- miron
- Topic Author
- Visitor
Question 1. I have question about best practice in mapping collection by live mapping.
I have made simple example in linq pad.
Generally: I have one class Line which could contain several object of type Device.
public class Line
{
public List<Device> Devices {get;set;}
}
In my example I have created mapping for each object of Device. Maybe there is another good way to do this.
I also could observed strange behavior. It looked that some values was not initialized correct value after
execution procedure.See screens.
When I crate simple loop in the end of program I have seen some randomize values.
for(int x = 0; i < 20; i++)
{
mapper.Write();
Thread.Sleep(2000);
}
Question 2:
Maybe several object of the same type should be mapped by separate instance?
C# example which could be run in LiqPad:
=================================================
[DAType]
public class Device
{
public string DeviceCode {get;set;}
[DANode()]
[DAItem()]
public bool IsRunning {get;set;}
[DANode()]
[DAItem()]
public int Speed {get;set;}
[DANode()]
[DAItem()]
public int Position {get;set;}
}
public class LineDef
{
public LineDef()
{
Devices = new List<Device>();
}
public List<Device> Devices {get;set;}
}
void Main()
{
var sd = "Kepware.KEPServerEX.V5";
//initialization object
var line = new LineDef();
line.Devices.Add(new Device() { DeviceCode="dev1"});
line.Devices.Add(new Device() { DeviceCode="dev2"});
line.Devices.Add(new Device() { DeviceCode="dev3"});
line.Devices.Add(new Device() { DeviceCode="dev4"});
line.Devices.Add(new Device() { DeviceCode="dev5"});
//preparing mapping
var mapper = new DAClientMapper();
foreach(var dev in line.Devices)
{
mapper.Map(dev, new DAMappingContext
{
ServerDescriptor = sd, // local OPC server
NodeDescriptor = new DANodeDescriptor { BrowsePath = "/TestChannel/MainGroup/Line1/" + dev.DeviceCode},
GroupParameters = 1000,
});
}
mapper.Read();
var i = 1;
foreach(var dev in line.Devices)
{
dev.IsRunning = true;
dev.Position = 10 * i;
dev.Speed = 30;
i++;
}
mapper.Write();
}
I have attached:
- C# example - which could be run directly in linq pad (www.linqpad.net/) (changed extension to txt)
- Picutre with not correct values from opc client
- csv definition exported from OPCKeepServer (changed extension to txt)
Please Log in or Create an account to join the conversation.