# Iterating selectively through Tag Folders to build Power Table

**URL:** <https://forum.inductiveautomation.com/t/iterating-selectively-through-tag-folders-to-build-power-table/109600>\
**Category:** Ignition\
**Tags:** scripting\
**Created:** [August 11, 2025, 5:43pm UTC](https://forum.inductiveautomation.com/t/iterating-selectively-through-tag-folders-to-build-power-table/109600 "2025-08-11T17:43:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![robertm](https://avatars.discourse-cdn.com/v4/letter/r/ea5d25/32.png) [@robertm](https://forum.inductiveautomation.com/u/robertm)\
**Post date:** [August 11, 2025, 5:43pm UTC](https://forum.inductiveautomation.com/t/iterating-selectively-through-tag-folders-to-build-power-table/109600/1 "2025-08-11T17:43:51Z")

</div>

I have some scripting that iterates through the Gateway Devices folder hierarchy and populates a power table showing the Device Name, Enable Status and Connection Status. My Python skills are kindergarten level and it takes me hours of reading, trial and error, searches, etc. I marvel at the ease of some of your coding skills. To that end, the following two scripts accomplish the same thing. I started with the 1st one, but realize it wasn’t optimum due to the numerous read blocks.

So I developed the 2nd one, but I think my counter method is hokey, and there has to be a better way. I’m effectively going through the sub folders and picking out the three items I want and discarding the one I don’t (Description).

While you’re laughing at my feeble attempts, could someone please point me in a direction that looks more like someone who knows what they are doing? I find I learn easier by visual cues, and comparing what I do wrong to what should be done.

```python
tags_in_folder = system.tag.browseTags('[System]/Gateway/Devices', recursive=True)
tag_data = []
for tag_info in tags_in_folder:
	if tag_info.isFolder():
		tag_enabled = tag_info.fullPath + '/Enabled'
		tag_name = tag_info.fullPath + '/Name'
		tag_status = tag_info.fullPath + '/Status'
		enabled_value = system.tag.readBlocking(tag_enabled)[0].value
		name_value = system.tag.readBlocking(tag_name)[0].value
		status_value = system.tag.readBlocking(tag_status)[0].value
		new_row = [name_value,enabled_value,status_value]
		tag_data.append(new_row)
headers = ["Name", "Enabled", "Status"]
dataset = system.dataset.toDataSet(headers, tag_data)
event.source.parent.getComponent('Group Device Status').getComponent('Power Table').data = dataset

```

```python
tags_in_folder = system.tag.browseTags('[System]/Gateway/Devices', recursive=True)
tag_data = []
tags_path_list = []
for tag_info in tags_in_folder:
	if not tag_info.isFolder():
		tags_path_list.append(tag_info.fullPath)
tag_values = system.tag.readBlocking(tags_path_list)
z = 0
for i in range(len(tag_values)):
	if z == 2:
		name_value = tag_values[i].value
	elif z == 1:
		enabled_value = tag_values[i].value
	elif z == 3:
		status_value = tag_values[i].value
	z = z+1
	if z == 4:
		new_row = [name_value,enabled_value,status_value]
		print new_row
		tag_data.append(new_row)
		z = 0
headers = ["Name", "Enabled", "Status"]
dataset = system.dataset.toDataSet(headers, tag_data)
event.source.parent.getComponent('Group Device Status 1').getComponent('Power Table').data = dataset

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [August 11, 2025, 6:09pm UTC](https://forum.inductiveautomation.com/t/iterating-selectively-through-tag-folders-to-build-power-table/109600/2 "2025-08-11T18:09:39Z")

</div>

I never remember this off the top of my head, but I'd highly recommend saving the snippet in this SO post into your project library somewhere you'll remember it:

> <https://stackoverflow.com/questions/312443/how-do-i-split-a-list-into-equally-sized-chunks/312464#312464>

Specifically:

```python
def chunks(lst, n):
    """Yield successive n-sized chunks from lst."""
    for i in xrange(0, len(lst), n):
        yield lst[i:i + n]

```

I gave your code, that snippet, and some prompting to an LLM:

> 1. List all devices in folder using browse (_not_ recursive)
> 2. Create a list of attributes you care about (name, enabled, status)
> 3. Create a full list of tags to read, the cross product of devices \* attributes
> 4. Go through the list of return values, chunking into lists of size (len(attributes))
> 5. Create a dataset out of the results, using the attribute names from the earlier list

And got this, which looks correct enough:

```python
# Helper function to group items in a list into n-sized chunks
def chunks(lst, n):
 	"""Yield successive n-sized chunks from lst."""
 	for i in xrange(0, len(lst), n):
 		yield lst[i:i + n]

# 1. List all devices in the folder (non-recursively)
# We browse the path for folders, as each folder represents a device.
device_folder_path = '[System]/Gateway/Devices'
devices = system.tag.browse(path=device_folder_path, filter={'tagType': 'Folder'}).getResults()

# 2. Define the attributes (tag names) we care about
# This list will also serve as our dataset headers.
headers = ["name", "enabled", "status"]

# 3. Create the full list of tag paths to read
# This builds the cross product of all devices and their desired attributes.
tag_paths_to_read = []
for device in devices:
	device_path = str(device.getFullPath())
	for attribute in headers:
		tag_paths_to_read.append(device_path + '/' + attribute)

# Read all tag values in a single efficient, blocking call
qualified_values = system.tag.readBlocking(tag_paths_to_read)

# Extract just the raw .value from each QualifiedValue object
values = [qv.value for qv in qualified_values]

# 4. Chunk the flat list of values into rows for our dataset
# The chunk size is the number of attributes we read per device.
data_rows = list(chunks(values, len(headers)))

# 5. Create a dataset from the headers and the chunked data
dataset = system.dataset.toDataSet(headers, data_rows)

# Assign the new dataset to the target Power Table component
event.source.parent.getComponent('Group Device Status 1').getComponent('Power Table').data = dataset

```

---

<div class="post-metadata">

**Author:** ![robertm](https://avatars.discourse-cdn.com/v4/letter/r/ea5d25/32.png) [@robertm](https://forum.inductiveautomation.com/u/robertm)\
**Post date:** [August 11, 2025, 6:39pm UTC](https://forum.inductiveautomation.com/t/iterating-selectively-through-tag-folders-to-build-power-table/109600/3 "2025-08-11T18:39:08Z")

</div>

Thanks!

The dictionary path is the wrong syntax

```python
for device in devices: device_path = str(device.getFullPath())

```

This worked

```python
for device in devices:
	device_path = str(device['FullPath'])

```

I’m going to study this. I see where I was close, and where I could have done better. I just couldn’t figure out the filtering by the values I needed, using the attribute in headers segment.
