Using the Tag Helper and Gateway Tags

I've been looking at the Tag Helper included in these tools and I'm trying to understand how best to use it to store data from tags.

Is there a recommended way to get live data on a tag from the gateway to put into these python Tag objects? If, for example, we wanted to test that a button had set the correct boolean tag in the gateway.

I also noticed some comments in the Tag Helper about 'a self.tags list returned from an Ignition Gateway' (e.g. in get_member_tag). How do we get this list from the gateway?

The Tag Helper does no in any way connect to or retrieve data from the Gateway. It's intended purpose is only to store data in the same shape as a Tag, and also to provide enumerated values which would be used to refer to data types in a manner Ignition would understand.

Our use cases for this Helper usually include simplifying variables within a test file. We'll usually have a page which returns Tag information as part of a JSON object. This leads to patterns like this:

TESTING_TAG_NAME = "sine1"
TESTING_TAG_PROVIDER = "[QAProvider]"
KNOWN_PATH_OF_TAG = "something:provider/deviceName/directory"
# some logic
# building this necessary path is prone to errors
self.page_object.chart_tag_in_power_chart(full_path=self.TESTING_TAG_PROVIDER + self.KNOWN_PATH_OF_TAG + "/" + self.TESTING_TAG_NAME)

# and accessing data from json/dictionary is a hassle
tag_data = self.page_object.get_tag_data_as_json()
assert tag_data["enabled"]
assert tag_data["eng_unit"] == "F"
# and so on

These patterns are repetitive, prone to typos, and require that anyone writing a test in this area have extensive knowledge regarding the keys available within the dictionary.

The Tag.py Helper file allows for something along these lines:

# using
tag = Tag(name="sine1", provider="[QAProvider]", path="something:provider/deviceName/directory")
self.page_object.chart_tag_in_power_chart(tag=tag)

# and accessing
tag = TagHelper.build_tag_from_dictionary(tag_configs=self.page_object.get_tag_data_as_json())
# now, you don't need to know about potential keys, because the class exposes all available attributes of the object.
assert tag.enabled
assert tag.eng_unit == "F"

Encapsulating the attributes in a class/object allows for much better access with less worrying about typos and allows more users to test tags without extensive knowledge of what attributes might be available in a dictionary.

An example we had a long time ago (it was not actually a Tag, but same idea):

tag = self.page_object.get_tag_data_as_json()
assert tag.get("en_unit") != "F"

This assertion would pass even if the associated engineering unit was indeed "F", because the automation engineer has accessed the dictionary with a key which does not exist. The usage would always return None, which is obviously not "F", and therefore is resulting in a false positive. Use of the Tag object (and by extension the TagHelper) helps us avoid these pitfalls.

1 Like

It should also be noted that we leverage WebDev to create a resource that invoke the system.tag functions and return the output. The Tag helper functions allow for us to construct an object that can interact with these resources (payloads and responses).

Garth

1 Like