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.
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
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
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:
Specifically:
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:
- List all devices in folder using browse (not recursive)
- Create a list of attributes you care about (name, enabled, status)
- Create a full list of tags to read, the cross product of devices * attributes
- Go through the list of return values, chunking into lists of size (len(attributes))
- Create a dataset out of the results, using the attribute names from the earlier list
And got this, which looks correct enough:
# 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
Thanks!
The dictionary path is the wrong syntax
for device in devices: device_path = str(device.getFullPath())
This worked
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.