Closed ccscpanici closed 3 years ago
Right now that is not built-in, but I like the idea of adding a helper method that would return that. That data is available in the tag list, but you would have handle getting it out.
Something like:
typ = plc.tags['Tag1']['internal_tags']['Temp']['internal_tags']['Scl']['data_type']
Obviously, a method that loops looks thru each sub-element until it gets to the end would be much nicer. I'm been thinking about adding some utility functions to simplify stuff like this and this is a good example of one. If not included in the library, having them in the examples would good too.
Have a look at this? I've tried to format this correctly, but it will not for some reason...so sorry about that.
def get_data_type(plc_name, a_tag): #
# plc_name = the string form of the controllogix plc variable
# a_tag = a valid tag string. This supports arrays and sub-arrays.
#
# example:
# get_data_type("plc", "System1.Burner.Temperature1") -> "REAL"
#
# tag pattern
#plc.tags['base_tag']['data_type']['internal_tags']['data_type']
# this line splits the tag up using the dot
# as the delimeter
a_tag_array = a_tag.split('.')
# this chunck of code gets rid of any tag
# indexing.
buffer = []
for i in a_tag_array:
if i.__contains__("[") and i.__contains__("]"):
buffer.append(i[0:i.find("[")])
else:
buffer.append(i)
# this forms the indexing string
s = plc_name + ".tags"
for i in range(0, len(buffer)):
if i < len(buffer) - 1:
s = s + "['" + buffer[i] + "']['data_type']['internal_tags']"
else:
s = s + "['" + buffer[i] + "']['data_type']"
try:
dt_string = eval(s)
except Exception as ex:
print("ERROR: Could not get data type for tag %s" % a_tag)
print(ex)
# end try
return dt_string
Even making a more general utility function:
import pycomm3
def get_tag_indexing_string(a_tag):
# as the delimeter
a_tag_array = a_tag.split('.')
# this chunck of code gets rid of any tag
# indexing.
buffer = []
for i in a_tag_array:
if i.__contains__("[") and i.__contains__("]"):
buffer.append(i[0:i.find("[")])
else:
buffer.append(i)
# this forms the indexing string
s = ""
for i in range(0, len(buffer)):
if i < len(buffer) - 1:
s = s + "['" + buffer[i] + "']['data_type']['internal_tags']"
else:
s = s + "['" + buffer[i] + "']['data_type']"
return s
if name == 'main':
print(get_tag_indexing_string("SequenceData.COND1[0]"))
print(get_tag_indexing_string("PoolArea.System1.Boiler.Temperature1"))
I should have looked closer in my initial reply, there is a private method for LogixDriver that would simplify this a lot.
Here is what I would do:
def get_tag_dataype(plc, tag_name):
base, *attrs = tag_name.split('.')
definition = plc._get_tag_info(base, attrs)
if definition['tag_type'] == 'struct':
return definition['data_type']['name']
else:
return definition['data_type']
A couple just general programming tips as well. You should not be calling the dunder methods yourself, like doing i.__contains__("[")
can be replaced with "[" in i
. And I would definitely shy away from using eval()
, there are much better and safer ways to accomplish what you're trying to do. I understand where you're going with it and how that'd be useful, but I would avoid this method as much as possible.
The private method I used above uses a recursive function to step all the way down to the last item in the request and return that attribute/tag's definition, then from that definition we just need to pick out the data type. This method works examples where the final tag is an atomic type (DINT, REAL, etc) or a structure (UDT, AOI, TIMER, etc). I can add a public method to return this data as well, but for now that function should get you want you need.
Good tips, thanks. The code I pasted was just an example to "get the ball rolling". Thanks for your help. I will use the method that you suggested.
Is there an easy way of finding out the datatype of a known tag using the tag list? For example, can I give the system a tag "Tag1[40].Temp.Scl" and have it spit back "Float"? Or even the tag in the list? I am not opposed to converting it to a "path" either like "Tag1\40\Temp\Scl"...
Is there anything like that I can use?
CJ