Universal symbol

Then I recommend running the browse operation by hand in the script console, printing out the tag paths you need. Paste those in a decent text editor to reformat (via regex) into expression syntax, and paste into the expression editor.

1 Like

Can I do the same just in expression?

No.

Please, can you write example ?

The example I gave should have been enough to start. Unfortunately, system.tag.browse() does not allow filtering by the full path. This one is modified to allow it.
As stated before, I’d split this into two separate scripts.
Two scripts.

  1. This example will write the tags names to a Document memory tag. I would use this as a Gateway Startup Script.
def browseTags(path, filter):
	''' 
	   system.tag.browse() does not allow filtering by fullPath. 
	   This script allows a fullPath key in the filter dictionary.
	'''
	import fnmatch
	# Pops the fullPath filter, if it exists.
	fullPathFilter = filter.pop('fullPath', '')
	
	def tagBrowse(path, filter, fullPathFilter):
		# First, browse for anything that can have children (Folders and UDTs, generally)
		results = system.tag.browse(path)
		for branch in results.getResults():    
			if branch['hasChildren']:
				# If something has a child node, then call this function again so we can search deeper.
				# Include the filter, so newer instances of this call will have the same filter.
				tagBrowse(branch['fullPath'], filter, fullPathFilter)
 

		# Call this function again at the current path, but apply the filter.
		results = system.tag.browse(path, filter)

		for result in results.getResults():
    	    # Here's where you'd want to do something useful.
			resultString = str(result['fullPath'])
			
			if fullPathFilter == '':
				#print resultString
				tagListOut.append(resultString)
			else:
				# Check if fullPath filter is in the result string
				if fnmatch.fnmatch(resultString, fullPathFilter):
					#print resultString
					tagListOut.append(resultString)

	tagListOut = []
	tagBrowse(path, filter, fullPathFilter)
	return tagListOut
         

tagList = browseTags('[default]', {'fullPath':'*/HMI/Alarm/Jammed', 'tagType':'AtomicTag'})

jsonOut = system.util.jsonEncode(tagList)

system.tag.writeBlocking(['[default]JammedTagTracker'], [jsonOut])
  1. Read the values of the tag list crated above and check to see if any are true. Result is written to a Boolean memory tag. I would use this in a Gateway Timer Script.
tagList = list(system.tag.readBlocking(['[default]JammedTagTracker'])[0].value)
tagValues = [tag.value for tag in system.tag.readBlocking(tagList)]
system.tag.writeBlocking(['[default]AnyJams'], [any(tagValues)])
1 Like

thanks everyone for help, i will look today!

if i do with expression tag this task, then my gateway won`t work slower?

This should be done for zones 5-15 pieces. Each zone will have 5-20-40 tags, if not more. Is your option still the best in this situation?


can there be a mistake?

It’s always possible; however it has been tested on my own system.

Background: On our assembly lines, there are sensors for poka yoke (mistakeproofs) to assist the operators. Occasionally, a sensor will fail, because entropy happens. If the repair is going to take a longer length of time to repair, we can bypass it, with the operator doing a visual check and another visual check downstream until it can be repaired at lunchtime or between shifts.

Example 1: All bypass tags.

tagList = browseTags('[default]', {'fullPath':'*/Bypass/*', 'dataType':'Boolean', 'tagType':'AtomicTag'})
for tag in tagList:
	print tag

Output:

[default]Assembly/3425/Bypass/40_50/accept_sprial_spring_seated
[default]Assembly/3425/Bypass/40_50/airbag_barcode
[default]Assembly/3425/Bypass/40_50/airbag_movement
[default]Assembly/3425/Bypass/40_50/airbag_presence
[default]Assembly/3425/Bypass/40_50/bumper_inserter_long
[default]Assembly/3425/Bypass/40_50/bumper_inserter_short
[default]Assembly/3425/Bypass/40_50/cap_crimp_check
[default]Assembly/3425/Bypass/40_50/dcm_barcode
[default]Assembly/3425/Bypass/40_50/dcm_foam_pad
[default]Assembly/3425/Bypass/40_50/dcm_movement
[default]Assembly/3425/Bypass/40_50/t_slot_chipping
[default]Assembly/3425/Bypass/140/coax_tape
[default]Assembly/3425/Bypass/140/flock_tape
[default]Assembly/3425/Bypass/140/long_black_pad_check
[default]Assembly/3425/Bypass/140/long_white_pad
[default]Assembly/3425/Bypass/140/short_c_bridge_tape
[default]Assembly/3425/Bypass/140/short_pvc_tape
[default]Assembly/3425/Bypass/150/abs_connector
[default]Assembly/3425/Bypass/150/abs_resistance
[default]Assembly/3425/Bypass/150/access_hole_grommet
[default]Assembly/3425/Bypass/150/brake_spring
[default]Assembly/3425/Bypass/150/cable_in_clip
[default]Assembly/3425/Bypass/150/carrier_offset
[default]Assembly/3425/Bypass/150/casing_cap
[default]Assembly/3425/Bypass/150/handle_torque_effort
[default]Assembly/3425/Bypass/150/longhorn_harness_check
[default]Assembly/3425/Bypass/150/motor_connector
[default]Assembly/3425/Bypass/150/nedd
[default]Assembly/3425/Bypass/150/passive_entry
[default]Assembly/3425/Bypass/150/ship_position
[default]Assembly/3425/Bypass/150/speaker_resistance
[default]Assembly/3425/Bypass/150/stall_current
[default]Assembly/3425/Bypass/150/stall_force
[default]Assembly/3425/Bypass/150/up_current
[default]Assembly/3425/Bypass/150/up_time
[default]Assembly/3425/Bypass/160/casing_cap
[default]Assembly/3425/Bypass/160/cross_cable
[default]Assembly/3425/Bypass/160/door_ajar_off
[default]Assembly/3425/Bypass/160/door_ajar_release
[default]Assembly/3425/Bypass/160/handle_bumper
[default]Assembly/3425/Bypass/160/handle_bumper_insertion
[default]Assembly/3425/Bypass/160/handle_color
[default]Assembly/3425/Bypass/160/handle_pull_effort
[default]Assembly/3425/Bypass/160/handle_rod_check
[default]Assembly/3425/Bypass/160/inside_handle_clip
[default]Assembly/3425/Bypass/160/latch_check
[default]Assembly/3425/Bypass/160/latch_connector
[default]Assembly/3425/Bypass/160/latch_presenter_pad
[default]Assembly/3425/Bypass/160/lb_color
[default]Assembly/3425/Bypass/160/lb_presence
[default]Assembly/3425/Bypass/160/lb_pull_force
[default]Assembly/3425/Bypass/160/lb_push_force
[default]Assembly/3425/Bypass/160/lock_coil
[default]Assembly/3425/Bypass/160/lock_rod_check
[default]Assembly/3425/Bypass/160/passive_entry
[default]Assembly/3425/Bypass/160/pressure_sensor_hole
[default]Assembly/3425/Bypass/160/tension
[default]Assembly/3425/Bypass/160/white_foam_pad
[default]Assembly/3425/Bypass/160/white_pvc_tape
[default]Assembly/3425/Bypass/160/xmas_tree
[default]Assembly/3425/Bypass/170/bsr_pad_wet
[default]Assembly/3425/Bypass/170/c_bridge_foam_pad
[default]Assembly/3425/Bypass/170/cable_in_tower
[default]Assembly/3425/Bypass/170/cable_routing
[default]Assembly/3425/Bypass/170/glass_bumper
[default]Assembly/3425/Bypass/170/mirror_tab
[default]Assembly/3425/Bypass/170/push_nut
[default]Assembly/3425/Bypass/170/snap_clip_orientation
[default]Assembly/3425/Bypass/170/speaker_height
[default]Assembly/3425/Bypass/170/speaker_type
[default]Assembly/3425/Bypass/170/wire_harness_dry_1
[default]Assembly/3425/Bypass/170/wire_harness_dry_2
[default]Assembly/3425/Bypass/170/wire_harness_dry_3
[default]Assembly/3425/Bypass/170/wire_harness_dry_4
[default]Assembly/3425/Bypass/170/wire_harness_dry_5
[default]Assembly/3425/Bypass/170/wire_harness_dry_6
[default]Assembly/3425/Bypass/170/wire_harness_dry_7
[default]Assembly/3425/Bypass/170/wire_harness_dry_8
[default]Assembly/3425/Bypass/170/wire_harness_dry_9
[default]Assembly/3425/Bypass/170/wire_harness_wet_1
[default]Assembly/3425/Bypass/170/wire_harness_wet_2
[default]Assembly/3425/Bypass/170/wire_harness_wet_3
[default]Assembly/3425/Bypass/170/wire_harness_wet_4
[default]Assembly/3425/Bypass/170/wire_harness_wet_5
[default]Assembly/3425/Bypass/170/xmas_tree
[default]Assembly/3426/Bypass/40_50/accept_sprial_spring_seated
[default]Assembly/3426/Bypass/40_50/airbag_barcode
[default]Assembly/3426/Bypass/40_50/airbag_movement
[default]Assembly/3426/Bypass/40_50/airbag_presence
[default]Assembly/3426/Bypass/40_50/bumper_inserter_long
[default]Assembly/3426/Bypass/40_50/bumper_inserter_short
[default]Assembly/3426/Bypass/40_50/cap_crimp_check
[default]Assembly/3426/Bypass/40_50/dcm_barcode
[default]Assembly/3426/Bypass/40_50/dcm_foam_pad
[default]Assembly/3426/Bypass/40_50/dcm_movement
[default]Assembly/3426/Bypass/40_50/t_slot_chipping
[default]Assembly/3426/Bypass/140/coax_tape
[default]Assembly/3426/Bypass/140/flock_tape
[default]Assembly/3426/Bypass/140/long_black_pad_check
[default]Assembly/3426/Bypass/140/long_white_pad
[default]Assembly/3426/Bypass/140/short_c_bridge_tape
[default]Assembly/3426/Bypass/140/short_pvc_tape
[default]Assembly/3426/Bypass/150/abs_connector
[default]Assembly/3426/Bypass/150/abs_resistance
[default]Assembly/3426/Bypass/150/access_hole_grommet
[default]Assembly/3426/Bypass/150/brake_spring
[default]Assembly/3426/Bypass/150/cable_in_clip
[default]Assembly/3426/Bypass/150/carrier_offset
[default]Assembly/3426/Bypass/150/casing_cap
[default]Assembly/3426/Bypass/150/handle_torque_effort
[default]Assembly/3426/Bypass/150/longhorn_harness_check
[default]Assembly/3426/Bypass/150/motor_connector
[default]Assembly/3426/Bypass/150/nedd
[default]Assembly/3426/Bypass/150/passive_entry
[default]Assembly/3426/Bypass/150/ship_position
[default]Assembly/3426/Bypass/150/speaker_resistance
[default]Assembly/3426/Bypass/150/stall_current
[default]Assembly/3426/Bypass/150/stall_force
[default]Assembly/3426/Bypass/150/up_current
[default]Assembly/3426/Bypass/150/up_time
[default]Assembly/3426/Bypass/160/casing_cap
[default]Assembly/3426/Bypass/160/cross_cable
[default]Assembly/3426/Bypass/160/door_ajar_off
[default]Assembly/3426/Bypass/160/door_ajar_release
[default]Assembly/3426/Bypass/160/handle_bumper
[default]Assembly/3426/Bypass/160/handle_bumper_insertion
[default]Assembly/3426/Bypass/160/handle_color
[default]Assembly/3426/Bypass/160/handle_pull_effort
[default]Assembly/3426/Bypass/160/handle_rod_check
[default]Assembly/3426/Bypass/160/inside_handle_clip
[default]Assembly/3426/Bypass/160/latch_check
[default]Assembly/3426/Bypass/160/latch_connector
[default]Assembly/3426/Bypass/160/latch_presenter_pad
[default]Assembly/3426/Bypass/160/lb_color
[default]Assembly/3426/Bypass/160/lb_presence
[default]Assembly/3426/Bypass/160/lb_pull_force
[default]Assembly/3426/Bypass/160/lb_push_force
[default]Assembly/3426/Bypass/160/lock_coil
[default]Assembly/3426/Bypass/160/lock_rod_check
[default]Assembly/3426/Bypass/160/passive_entry
[default]Assembly/3426/Bypass/160/pressure_sensor_hole
[default]Assembly/3426/Bypass/160/tension
[default]Assembly/3426/Bypass/160/white_foam_pad
[default]Assembly/3426/Bypass/160/white_pvc_tape
[default]Assembly/3426/Bypass/160/xmas_tree
[default]Assembly/3426/Bypass/170/bsr_pad_wet
[default]Assembly/3426/Bypass/170/c_bridge_foam_pad
[default]Assembly/3426/Bypass/170/cable_in_tower
[default]Assembly/3426/Bypass/170/cable_routing
[default]Assembly/3426/Bypass/170/glass_bumper
[default]Assembly/3426/Bypass/170/mirror_tab
[default]Assembly/3426/Bypass/170/push_nut
[default]Assembly/3426/Bypass/170/snap_clip_orientation
[default]Assembly/3426/Bypass/170/speaker_height
[default]Assembly/3426/Bypass/170/speaker_type
[default]Assembly/3426/Bypass/170/wire_harness_dry_1
[default]Assembly/3426/Bypass/170/wire_harness_dry_2
[default]Assembly/3426/Bypass/170/wire_harness_dry_3
[default]Assembly/3426/Bypass/170/wire_harness_dry_4
[default]Assembly/3426/Bypass/170/wire_harness_dry_5
[default]Assembly/3426/Bypass/170/wire_harness_dry_6
[default]Assembly/3426/Bypass/170/wire_harness_dry_7
[default]Assembly/3426/Bypass/170/wire_harness_dry_8
[default]Assembly/3426/Bypass/170/wire_harness_dry_9
[default]Assembly/3426/Bypass/170/wire_harness_wet_1
[default]Assembly/3426/Bypass/170/wire_harness_wet_2
[default]Assembly/3426/Bypass/170/wire_harness_wet_3
[default]Assembly/3426/Bypass/170/wire_harness_wet_4
[default]Assembly/3426/Bypass/170/wire_harness_wet_5
[default]Assembly/3426/Bypass/170/xmas_tree
[default]Assembly/3427/Bypass/140/flock_tape
[default]Assembly/3427/Bypass/140/pvc_tape
[default]Assembly/3427/Bypass/140/short_c_bridge_tape
[default]Assembly/3427/Bypass/150/access_hole_grommet
[default]Assembly/3427/Bypass/150/carrier_offset
[default]Assembly/3427/Bypass/150/nedd
[default]Assembly/3427/Bypass/150/ship_position
[default]Assembly/3427/Bypass/150/speaker_resistance
[default]Assembly/3427/Bypass/150/stall_current
[default]Assembly/3427/Bypass/150/stall_force
[default]Assembly/3427/Bypass/150/up_current
[default]Assembly/3427/Bypass/150/up_time
[default]Assembly/3427/Bypass/160/door_ajar_release
[default]Assembly/3427/Bypass/160/door_ajar_sw_off
[default]Assembly/3427/Bypass/160/handle_bumper_insertion
[default]Assembly/3427/Bypass/160/handle_color
[default]Assembly/3427/Bypass/160/handle_effort
[default]Assembly/3427/Bypass/160/handle_rod
[default]Assembly/3427/Bypass/160/latch_check
[default]Assembly/3427/Bypass/160/latch_connector
[default]Assembly/3427/Bypass/160/lb_color
[default]Assembly/3427/Bypass/160/lb_distance
[default]Assembly/3427/Bypass/160/lb_height
[default]Assembly/3427/Bypass/160/lb_presence
[default]Assembly/3427/Bypass/160/lb_pull_force
[default]Assembly/3427/Bypass/160/lb_push_force
[default]Assembly/3427/Bypass/160/lock_coil
[default]Assembly/3427/Bypass/160/lock_rod_check
[default]Assembly/3427/Bypass/160/longhorn_harness_check
[default]Assembly/3427/Bypass/170_1/bell_crank
[default]Assembly/3427/Bypass/170_1/bell_crank_clip
[default]Assembly/3427/Bypass/170_1/glass_bumper
[default]Assembly/3427/Bypass/170_1/handle_bumper
[default]Assembly/3427/Bypass/170_1/inside_handle_clip
[default]Assembly/3427/Bypass/170_1/speaker_height
[default]Assembly/3427/Bypass/170_1/speaker_type
[default]Assembly/3427/Bypass/170_1/tension
[default]Assembly/3427/Bypass/170_1/xmas_tree
[default]Assembly/3427/Bypass/170_2/connector_check
[default]Assembly/3427/Bypass/170_2/push_nut
[default]Assembly/3428/Bypass/140/flock_tape
[default]Assembly/3428/Bypass/140/pvc_tape
[default]Assembly/3428/Bypass/140/short_c_bridge_tape
[default]Assembly/3428/Bypass/150/access_hole_grommet
[default]Assembly/3428/Bypass/150/carrier_offset
[default]Assembly/3428/Bypass/150/nedd
[default]Assembly/3428/Bypass/150/ship_position
[default]Assembly/3428/Bypass/150/speaker_resistance
[default]Assembly/3428/Bypass/150/stall_current
[default]Assembly/3428/Bypass/150/stall_force
[default]Assembly/3428/Bypass/150/up_current
[default]Assembly/3428/Bypass/150/up_time
[default]Assembly/3428/Bypass/160/door_ajar_release
[default]Assembly/3428/Bypass/160/door_ajar_sw_off
[default]Assembly/3428/Bypass/160/handle_bumper_insertion
[default]Assembly/3428/Bypass/160/handle_color
[default]Assembly/3428/Bypass/160/handle_effort
[default]Assembly/3428/Bypass/160/handle_rod
[default]Assembly/3428/Bypass/160/latch_check
[default]Assembly/3428/Bypass/160/latch_connector
[default]Assembly/3428/Bypass/160/lb_color
[default]Assembly/3428/Bypass/160/lb_distance
[default]Assembly/3428/Bypass/160/lb_height
[default]Assembly/3428/Bypass/160/lb_presence
[default]Assembly/3428/Bypass/160/lb_pull_force
[default]Assembly/3428/Bypass/160/lb_push_force
[default]Assembly/3428/Bypass/160/lock_coil
[default]Assembly/3428/Bypass/160/lock_rod_check
[default]Assembly/3428/Bypass/160/longhorn_harness_check
[default]Assembly/3428/Bypass/170_1/bell_crank
[default]Assembly/3428/Bypass/170_1/bell_crank_clip
[default]Assembly/3428/Bypass/170_1/glass_bumper
[default]Assembly/3428/Bypass/170_1/handle_bumper
[default]Assembly/3428/Bypass/170_1/inside_handle_clip
[default]Assembly/3428/Bypass/170_1/speaker_height
[default]Assembly/3428/Bypass/170_1/speaker_type
[default]Assembly/3428/Bypass/170_1/tension
[default]Assembly/3428/Bypass/170_1/xmas_tree
[default]Assembly/3428/Bypass/170_2/connector_check
[default]Assembly/3428/Bypass/170_2/push_nut

Exampe 2: Bypasses with ‘clip’ in the name:

tagList = browseTags('[default]', {'fullPath':'*/Bypass/*', 'name':'*clip*', 'dataType':'Boolean', 'tagType':'AtomicTag'})
for tag in tagList:
	print tag

Output:

[default]Assembly/3425/Bypass/150/cable_in_clip
[default]Assembly/3425/Bypass/160/inside_handle_clip
[default]Assembly/3425/Bypass/170/snap_clip_orientation
[default]Assembly/3426/Bypass/150/cable_in_clip
[default]Assembly/3426/Bypass/160/inside_handle_clip
[default]Assembly/3426/Bypass/170/snap_clip_orientation
[default]Assembly/3427/Bypass/170_1/bell_crank_clip
[default]Assembly/3427/Bypass/170_1/inside_handle_clip
[default]Assembly/3428/Bypass/170_1/bell_crank_clip
[default]Assembly/3428/Bypass/170_1/inside_handle_clip

Either direction you take will not make your gateway "work" slower.

What @JordanCClark meant with this statement was that the more tags you need to browse through, the longer the script is going to take to run.

So potentially 600+ tags? This number will be static once the system is built?

If this is the case, I would do as @pturmel suggested run a browse in the script console, take the output and run it through a text editor (if needed) to format the paths for an expression, and then make an expression tag for each zone.

I have learned to never count on that. It's why I recommend an infrequent browse to compile the tag list. Like in a Gateway Startup Script, or call it from the script console, for instance.

YMMV, but, using my above example with a total of approximately 14.5K tags/folders/UDTs took about 13 seconds to compile the tag list. The number of found tags doesn't matter because it still has to go through all 14.5K.

Reading the values of the compiled tag list is much faster.

For a test, I compiled a list of all of the atomic tags on [default].

start = system.date.now()
print 'Compile start time:', start
tagList = browseTags('[default]', {'tagType':'AtomicTag'})
print len(tagList), 'tags compiled'
system.tag.writeBlocking(['[Test]TagTracker'], [system.util.jsonEncode(tagList)])
print 'Elapsed time: ',system.date.millisBetween(start, system.date.now())/1000.0, 'sec'
print ' '
print '-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-'
print ' '
# Read the tag list, the read the tags
start = start = system.date.now()
print 'Tag read start time:', start
tagList = list(system.tag.readBlocking(['[Test]TagTracker'])[0].value)
tagValues = [tag.value for tag in system.tag.readBlocking(tagList)]
# Check if any value is True
print 'Any true?: ', any(tagValues)
print 'Elapsed time: ',system.date.millisBetween(start, system.date.now())/1000.0, 'sec'

Output:

Compile start time: Tue Feb 23 11:35:12 EST 2021
13228 tags compiled
[Good]
Elapsed time:  13.828 sec
 
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
 
Tag read start time: Tue Feb 23 11:35:26 EST 2021
Any true?:  True
Elapsed time:  1.569 sec

To scale it back to my 250 bypass tags:

Compile start time: Tue Feb 23 11:25:06 EST 2021
250 tags compiled
[Good]
Elapsed time:  12.892 sec
 
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
 
Tag read start time: Tue Feb 23 11:25:19 EST 2021
Any true?:  True
Elapsed time:  0.027 sec
2 Likes

I’m guessing you’re just not using it for the example but if you haven’t written a timer decorator yet you’re missing out

You’d be correct, Chason. More for compare and contrast than for accuracy.

1 Like

I agree, that's why there were question marks.

I have a tendency in my own projects to default to scripting, but I also try to remember that not everyone is as comfortable with it as I am.

Sorry for being away for a long time. Can you tell me how we can you track the tags used on the window? in perspective

You can’t really, the best you do is to copy the View as json (hold… Shift? And right click on the View) and then use something like notepad++ to find the patterns of your tags. It doesn’t really help for embedded views though where you’re passing a base tag path to or just bits and pieces of a tag path. You should be able to easily find static tag use though directly on the View. To find dynamic uses, you would need to build a parser to parse your expressions that build and read dynamic tag paths, and if you’re using python scripts… Good luck! :sweat_smile:

No kidding.

If I understand correctly from this post

This is a customer requirement and you’re trying to do this at runtime? What I can’t wrap my head around is why this is a requirement? Most of the time the end user doesn’t need to know or even care about where the tags are used. Or even that there are such things as tags.

I can of course understand wanting a cross reference from a designers point of view, it’s been an often requested feature for sometime. The implementation of such a feature is...shall we say far from trivial.

I understand that not trivial task, but why this function need I don`t understand. They want, so it must be done(((( I wrote on forum hoping to get a hint to perform this non-trivial task. If you have any ideas, I will be very glad to see them!

I think, short of creating your own custom module with considerable effort to do this automatically, your next best solution would be to expose the tag paths that you’re using within each component (embedded View) in a custom prop object. This object must contain all tag paths used within the component, and then you could open a popup to show these tag paths which wouldn’t be that difficult to do. This obviously means making this change to every single one of your Views. In the popup, you could have a flex repeater with a View that reads the OpcItemPath property of the tag in order to get the PLC address, as well as anything else you might want (EngMax, EngMin, EngUnit, FormatString, etc.).

I actually don’t think this would be such a bad solution, and our engineers coming from other platforms that have this functionality inbuilt have asked me about it in Ignition. I may end up doing something like this in the future… that way, you the designer also has a view of all tags used in the template Views as well