Weird behavior when accessing tag data via readBlocking

I'm trying to use system.tag.readBlocking to access a dataset at a given tag path. However, my transform script is behaving oddly when I try to access the data. Specifically: Python treats my line_states variable like a Dataset object only in return statements. Otherwise, when I try to perform typical database operations on the line_states variable, I get errors treating it like a NoneType object.

def transform(self, value, quality, timestamp):
	item = {
  		"id": "",
  		"label": "New Item",
 		"iconConfig": {
    		"path": "",
    		"color": "",
    		"style": {}
  		},
  		"headerStyle": {
    		"classes": ""
  		},
  		"rowStyle": {
    		"classes": ""
  		}
	}
	
	items = []
	
	for line in value:
		item["id"] = line["value"]
		item["label"] = line["label"]
		
		line_states_qualified_value = system.tag.readBlocking(str(line["EquipmentPath"]) + "/config/stateDS")[0]
		line_states = line_states_qualified_value.value
		state_code_qualified_value = system.tag.readBlocking(str(line["EquipmentPath"]) + "/OEE_Events/state")[0]
		state_code = state_code_qualified_value.value
		state_data = []
		
		line_states_row_count = line_states.getRowCount()
		return line_states_row_count
		
		if line_states_row_count > 0 and state_code:
			for i in range(line_states_row_count):
				if int(line_states.getValueAt(i, "ReasonCode")) == int(state_code):
					line_states_column_count = line_states.getColumnCount()
					for j in range(line_states_column_count):
						states_data.append(line_states.getValueAt(i, j))
					item["iconConfig"]["path"] = line_states.getValueAt()
					item["iconConfig"]["color"] = ""
					item["iconConfig"]["style"] = ""
		
		items.append(item.copy())
	
	return items

For example, the code above returns 28 because of the return line_states_row_count line. However, if said line is removed, the preceding line line_states_row_count = line_states.getRowCount() generates the following error:

'NoneType' object has no attribute 'getRowCount'

Maybe because removing the early return causes you to iterate through the entire value sequence, and eventually you end up with a line that results in None after this:

		line_states_qualified_value = system.tag.readBlocking(str(line["EquipmentPath"]) + "/config/stateDS")[0]
		line_states = line_states_qualified_value.value

add some print statements to debug.

2 Likes

Also, for optimization, you should have 2 loops. One for building a list of all the tags you need to read, then doing a single system.tag.readBlockingstatement to read them in a single call. Then use those results as part of your iteration on the second loop with something like for i, line in enumerate(value): to pull the index and reference the 2 values using tagValues[i*2].value and tagValues[i*2+1].value for line_states and state_data respectively.

3 Likes

If that's the case, what change would you recommend adding to my code?

Add print statements to print the equipment path of the item, so you can Identify which one is returning a null value for its line states. Last one to be printed before the error is the one with the issue.

1 Like