I have a need to create a tank overview page with over 50 tanks. I was taking the UDT route to minimize the pain of creating repeated tasks.
As shown in the image, 1, 2, 3 are connections to three different PLCs in the field.
I was wondering if there is a way to switch the opc path based on the Tank number? or may PLC path dynamic to switch to the right PLC.
PLC-1 = 33 tanks
PLC-2 = 23 Tanks
PLC-3 = about 11 tanks
I hate to create a separate udt based on PLC. but if that is the only viable route then I will do it. My problem was I could work with only 1 PLC. could not switch based on Tank type
Maybe I'm missing something here, but could you just have custom parameters for both the tank number and the PLC base path? Then dynamically get the OPC path based on both of those.
I have the tank number as input parameter. Based on the Tank number, the PLCprogramName is a memory tag I created under the configuration folder gets the value from a lookup function. I could not pass the tag value to the _edge_Plc udt to make the path dynamic.
You're going to need parameters for the PLCs like {DeviceName} that you'll use as part of your OPC path.
@michael.flagler I hope my understanding is correct, I should create 3 parameters PLC1, PLC2 and PLC3 as UDT parameters? Then use if condition to make the selection in the opc path ?
No, make 1 UDT parameter named "DeviceName" then for each tag specify the device name parameter value as shown under your OPC Devices which could be "PLC1", "PLC2", and "PLC3".
Your OPC Item Path would be something similar to this depending on your tag structure:
ns=1;s=[{DeviceName}]Tank{TankNum}.Level
Not memory tag, but a second custom parameter just like you already have for edgeTankNo
.
With Michael's example if you called it DeviceName
your full OPC Item Path would be:
ns=1;s=[{DeviceName}]Tank{edgeTankNo}.Scanner.Out.Level
assuming there's nothing else on the end of that OPC path.
@Mark_Minuth - When I create the udt instance, I would have to provide the {DeviceName} text in the parameter. Based on that value it will construct the opc path. Is it correct?
What I was looking was to get the {DeviceName} from a lookup table and construct the path. I got the lookup working but could not pass the value to {DeviceName}
Parameter was a static text, that needs to be changed at the instant usage level
Yes, that is correct, Use the string @Mark_Minuth gave you that is using 2 parameters in the OPC item path. You'll need to specify for each instance the tank number (edgeTankNo) and device name (DeviceName) parameters, but they'll dynamically replace the placeholders and it will work fine.
Grabbing the PLC name from a database or lookup table based on the tank number isn't necessarily a difficult task, but an easy solution for doing that on UDT creation isn't immediately obvious to me.
It sounds like you were binding a tag in the UDT to the plc name based on a lookup from the tank number custom property? I don't think you can use tags in a dynamic path binding, only the properties. You could potentially do it with an initial change script or something on that plc name tag, but really there's only 55 tanks, and you're creating a lot more complication and potential issues than you're solving.
If there were 10000 tanks with 100 different PLCs, I would probably still use two properties, DeviceName
and TankNo
, and just write a python script or something to create all the tanks based on that lookup table.
I was taking the lookup route because that way I need to make only one change. Update the dataset and all the paths should update. I am not super comfortable with scripting yet. The last alternative is to manually make 72 connections. which defeats the purpose of having a udt. But I see the stupidity of my approach, passing a tag value to a property is probably not a good idea
@Mark_Minuth Can you please give some pointers on how to use scripting to create the instances based on the lookup table. Thank you appreciate your help
Consider not including the tanks in the the device's overview UDT. Just use a folder with separate single "core" and multiple "tank" UDT instances.
You cannot make a UDT with a variable number of members, of any kind.
Also: You asked a form of this question over here:
Asking in a new topic won't change that answer.
I always have the PLC connection name as a parameter to my UDTs, regardless of how many PLCs are in the project.
@pturmel these two are two different applications. They are not same from what I was thinking. The other question was to dynamically populate instances of a sub element of udt based on number of fill heads in the filler. However here I was dynamically trying to change the path of the PLC
You can feed parameters down through child UDTs from the parent UDT. This is one reason that I always suffix my UDTs with some sort of identifier that is unique to the UDT.
I'm not quite sure what tags are all within your _edge_PLC
member, but this should be fairly simple.
If you want the device name for all of the tanks within the PLC to be automatically updated for all tanks at once, create a parent UDT with an instance of the Tank_udt
for each tank and feed the device name down to the Tank_udt
instances from the PLC_Tanks_udt
.
@amarks so if you have 3 tags in a udt that are pulling info from 3 different PLCs. would you create 3 parameters? passing 1 parameter like PLC1 will not be any good for 2 other tags talking to different PLC. Because parameter is a static text for each instance of udt
Why do you have tags from different PLCs in the same UDT? That seems a bit odd to me.
Thats how the site has it, level comes from one PLC. formula is from another PLC and so on.