Comments (11)
Currently there is not an easy way to read and entire structure (UDT) in one read, for example. You have to do it one member at a time. I'll break it down into 3 main thoughts:
-
I know of one user who has written their own code to parse a L5K file to understand a UDT's structure, then wrote a function that would read each all the data, one element at a time and return it in a format that made sense to him.
-
It is possible to make a change in how data is returned to you when reading tags that are data structures. Essentially it would return the raw value bytes, it would be up to you to know how the data is packed into the bytes and unpack them. I have experimented with this idea with some degree of success. Basically I write a class that represents a timer, with and unpack function that. Writing the class and unpack would be up to the user.
3a)For me to discover the makeup of a tag "automatically" with only the tag name requires a ton of overhead. First you have to request the entire tag database, find the instance ID of the tag, request instance of the template (UDT), then request the UDT structure. With nested UDT's, you have to add more requests into the mix. Then I have to return the data to you in some useful way.
3b)I have also experimented with various ways of doing what I described above, all of which were using GetTagList() rather than Read(). In my test program, I had a few dozen tags which were made up of a few nested UDT's. Some of the tag instances were arrays of these UDT's. The printout of the complete tag list quickly turned into 25k lines when it was broken down to the basic elements.
The change to return the raw bytes is pretty simple, so I may implement that and add a couple of examples on how I would go about using it. In the long term, I may add the ability to include an option to grab the UDT structure with GetTagList().
Let me know your thoughts.
from pylogix.
I can only speak for our company, but we use the same UDTs for all our projects. Which means that there are basically only 25 known UDTs to choose from. This would make it extremely convenient if I could read the "Alias For" or "Base Tag" or "Data Type" in raw text. Because that would define the entire structure of the tag. Don't think you answered that question. Is that possible?
I have made one implementation so far. Usually I am not interested in the entire UDT just certain data.
For example for Analog inputs, it's nice to know the raw Input from the sensor, as well as the scaled Output from the Tag. I have made a program that can trend basically any tag on the PLC only by knowing the Tagname.
The program works as follows, first you specify the tag and what info you want to trend (input, output etc.). When you press the Log Data, the program will then take the Tag name and add the a path extension to it. For example if you specify "Input", it will cycle through a list of known "input paths" and try to read it from the PLC. If it gets a ValueError, it will continue with the next path in the list, but if it find the tag. It will add that tag to the list of tags to be read during trending and do the same for the next tag on the list. When all the tagpaths had been found, it will start trending data as normal.
Thoughts on further implementation of UDTs:
Since i guess most people use general UDTs and know the structures of them. It should be possible to read the entire structure quite easily. By defining the different structures in another file.
Step 1: Extract UDT stuctures (copy/paste) from Studio 5000:
eks. UDT_Timer:
Name (Data Type)
i_ENABLE (BOOL)
io_TIMER (TIMER)
--PRE (DINT)
--ACC (DINT)
--EN (BOOL)
--TT (BOOL)
--DN (BOOL)
FB FB_TIMER
--EnableIn (BOOL)
--EnableOut (BOOL)
--i_ENABLE (BOOL)
Step 2: Turn it into a list/dict.
known_UDTs = {UDT_timer: ["i_ENABLE", "io_TIMER", "io_TIMER.PRE", "io_TIMER.ACC", "io_TIMER.EN", "io_TIMER.TT", "io_TIMER.DN", "FB", "FB.EnableIn", "FB.EnableOut", "FB.i_ENABLE"]
UDT_different: ["..."]
}
}
UDT_timer = {(i_ENABLE, BOOL,),
(io_TIMER, TIMER),
(io_TIMER.PRE, DINT),
(io_TIMER.ACC, DINT),
(io_TIMER.EN, BOOL),
(io_TIMER.TT, BOOL),
(io_TIMER.DN, BOOL),
(FB, FB_TIMER),
(FB.EnableIn, BOOL),
(FB.EnableOut, BOOL),
(FB.i_ENABLE, BOOL)}
Step 3: When reading the Tag, add the Tagname+all the filepaths to the list, to the tags to be read.
This still requires you to know what UDT the tag though.
from pylogix.
Great explanation, I just want to make sure I fully understand you so please forgive the extra questions.
You plan on having some additional files that define all 25 of your data structures that you typically have. No need for the driver to figure out what that data structure is since you are defining that up front. However you would like to pass a tag name (for example) and identify what UDT actually is so that you know which one of your defined UDT files to use. More specifically, pass "MyTagName" and get "UDT_timer" in return.
In a nutshell, that is what would be helpful correct?
from pylogix.
Yes exactly!
from pylogix.
Okay, great. Sorry for the scenic route on this, your original question is pretty clear.
Currently, there is no way to do this. However there is a way, the functionality is 90% written, 100% ugly and the solution is not as good as I wish it could be. I will work on implementing it and try to explain how it will work.
Getting the UDT name will have to be part of the GetTagList, since that is the only way to get the necessary information for getting the UDT name. Maybe I'll add a parameter to GetTagList that will do the extra work to get the UDT's, so for people that don't care about them, they can save the extra time/traffic that it takes to get the UDT's.
In a perfect world, you'd be able to just request this of a single tag without reading the entire tag database but the only documented object that returns the necessary information to do this is the object that GetTagList uses. You will have to do this once and I will keep it saved in a list so you can access it. I imagine there will probably be a list of tags and a list of UDT's, then you look up the UDT name using the tag data type.
I just have to do some more testing with it and clean it up. Hopefully I can push something out by next week.
from pylogix.
That would be awesome! I have a couple of other questions as well, not related to the same issue though. Is it possible to read out the program currently running on the PLC? And will the GetModuleProperties command also work with modules in a DLR?
from pylogix.
GetModuleProperties will only get the properties of modules in a PLC rack. It won't get properties of non PLC devices on the network. Discover will get you properties of other devices on the network. Network layout (DLR, star, linear) shouldn't matter.
I do have an "audit" script that I'm going to push to my examples. Basically, it discovers all of the devices on the network, any one that is a PLC, it will audit the rack, requesting all of the properties of the modules.
You cannot read out the program. That would take a massive amount of reverse engineering that I'm not capable of. Certainly not with a job and a family! :)
As for the more complete data type, I think I can still get it done in a few days. In the end, when you request the tag list, .DataType will give you the name as a string.
from pylogix.
I finally got around to pushing the changes out to have the DataType be a string. Try it out and let me know what you think.
from pylogix.
Did this end up working out for you tobiasht?
from pylogix.
Hello. Sorry for the late response, I just got back from holidays. I`ve just tested out the new code and it works flawlessly. Exactly what I needed. Thank you so much!!! Keep up the good work.
from pylogix.
Great, thanks for the update!
from pylogix.
Related Issues (20)
- read tag from 80 sets of plc HOT 22
- Double read packets? HOT 6
- cannot import name 'Adapter' from 'pylogix' HOT 23
- Tag Write falsely reports Success HOT 7
- "Forward open failed" when trying to read tags from Berghof PLC HOT 8
- .GetDeviceProperties always returns DeviceType of "None" HOT 5
- Issues connecting to emulate HOT 7
- micro850 connection HOT 5
- Return data gets jumbled up on a multi write when the tags don't exist. HOT 13
- The return value is different when using a multi write compared to a single write for a string. HOT 4
- cannot get a tag list HOT 3
- Is it possible to inhibit a periodic task? HOT 2
- pylogix - returning a tag list as a row of values HOT 7
- PLC REAL values HOT 5
- Pylogix - compare a previously acquired tag list with the current one HOT 5
- Discover does not work while running pylogix in docker HOT 10
- Invalid Continuation Byte HOT 5
- Abnormal code termination. HOT 8
- Do I need to use routing? HOT 20
- PLC connection best practice HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pylogix.