Code Monkey home page Code Monkey logo

Comments (11)

dmroeder avatar dmroeder commented on July 18, 2024

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:

  1. 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.

  2. 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.

tobiasht avatar tobiasht commented on July 18, 2024

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.

image

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.

dmroeder avatar dmroeder commented on July 18, 2024

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.

tobiasht avatar tobiasht commented on July 18, 2024

Yes exactly!

from pylogix.

dmroeder avatar dmroeder commented on July 18, 2024

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.

tobiasht avatar tobiasht commented on July 18, 2024

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.

dmroeder avatar dmroeder commented on July 18, 2024

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.

dmroeder avatar dmroeder commented on July 18, 2024

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.

dmroeder avatar dmroeder commented on July 18, 2024

Did this end up working out for you tobiasht?

from pylogix.

tobiasht avatar tobiasht commented on July 18, 2024

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.

dmroeder avatar dmroeder commented on July 18, 2024

Great, thanks for the update!

from pylogix.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.