def trace_power_flow():
	# 1. Define the network structure in order from left to right
	# This makes it easy to find neighbors.
	ds_names = ["DS-1A2", "DS-1B2"]
	
	# 2. Build the list of all tags we need to read
	# Using readBlocking for a single, efficient tag read
	tag_paths_to_read = [
		'[Ignition_Common_IO_Gtwy]Cables/SES/SESA_Out2',  # Assumes a tag for the source status
		'[Ignition_Common_IO_Gtwy]Cables/SES/SESB_Out2'
		]
	for name in ds_names:
		# Assuming your UDT instances are in a folder named 'DS'
		base_path = "[Ignition_Common_IO_Gtwy]Yard/SATB1_YARD_{}".format(name)
		tag_paths_to_read.append("{}/Breaker Closed Way 01".format(base_path))
		tag_paths_to_read.append("{}/Breaker Closed Way 02".format(base_path))
		# 3. Read all tags at once
	try:
		tag_values = system.tag.readBlocking(tag_paths_to_read)
	except Exception as e:
		# Log error if tags can't be read
		system.util.getLogger("PowerTrace").error("Error reading tags: {}".format(e))
		return

	# Create a dictionary for easy access to tag values
	# e.g., values['UT-HS1']['Switch_L_Status']
	values = {}
	values['SESA-FRD2_Live'] = tag_values[0].value
	values['SESB-FRD2_Live'] = tag_values[1].value
	
	read_idx = 2
	for name in ds_names:
		values[name] = {
			'Way01': tag_values[read_idx].value,
			'Way02': tag_values[read_idx + 1].value
			}
		read_idx += 2

	# 4. The Tracing Algorithm
	# This dictionary will store the final state: e.g., energized_state['UT P1.2'] = 'DS-1A1'
	energized_state = {}
	
	# A queue for our BFS traversal, storing (ut_name, source)
	# Using a list as a queue: append to add, pop(0) to remove from front
	q = []
	
	# Initialize the queue with active sources
	if values['SESA-FRD2_Live']:
		q.append( ("DS-1A2", "SESA-FRD2") )
	if values['SESB-FRD2_Live']:
		q.append( ("DS-1B2", "SESB-FRD2") )

	# Process the queue until it's empty
	visited = set() # Keep track of UTs we've already processed to prevent infinite loops
	while q:
		current_ds_name, source = q.pop(0)
		
		if current_ds_name in visited:
			continue
		
		visited.add(current_ds_name)
		energized_state[current_ds_name] = source
		
		current_ut_index = ds_names.index(current_ds_name)
		
		# Check for propagation to the RIGHT (-->)
		if current_ut_index < len(ds_names) - 1:
			neighbor_name = ds_names[current_ut_index + 1]
			# Condition: Current UT's right switch is closed AND Neighbor's left switch is closed
			if values[current_ds_name]['Way02'] and values[neighbor_name]['Way02']:
				if neighbor_name not in visited:
					q.append( (neighbor_name, source) )
		
		# Check for propagation to the LEFT (<--)
		if current_ut_index > 0:
			neighbor_name = ds_names[current_ut_index - 1]
			# Condition: Current UT's left switch is closed AND Neighbor's right switch is closed
			if values[current_ds_name]['Way02'] and values[neighbor_name]['Way02']:
				if neighbor_name not in visited:
					q.append( (neighbor_name, source) )
	print energized_state
	
	# 5. Prepare and write the results back to Ignition tags
	tag_paths_to_write = []
	values_to_write = []
	
	# Set UT states
	for name in ds_names:
		is_energized = name in energized_state
		power_source = energized_state.get(name, 'None')
		
		tag_paths_to_write.append("[Ignition_Common_IO_Gtwy]Yard/SATB1_YARD_{}/Data/isEnergized".format(name))
		values_to_write.append(is_energized)
		
		tag_paths_to_write.append("[Ignition_Common_IO_Gtwy]Yard/SATB1_YARD_{}/Data/PowerSource".format(name))
		values_to_write.append(power_source)
		
	# Write all values in a single, efficient call
	if tag_paths_to_write:
		system.tag.writeBlocking(tag_paths_to_write, values_to_write)