Attemping to store API values in tag

I am trying to expand on my API calls and store them in tags, and have a timer update them ever so often. One problem I am running into is storing the array of data i get back from the API. Example below

def getPMList(building):
	res = {}
	client = system.net.httpClient()
	response = client.get("https://api.megamation.com/clm/DL/workorder?STATUS=S&TYPE=PM&BUILDING_ID="+building, username="<>", password="<>")
	res = [
		{
			'wo_no': key['wo_no'],
			'date': key['date'],
			'building_id': key['building_id'],
			'work_request_description': key['work_request_description'],
			'type': key['type']
		}
		for key in response.json['_embedded']['WorkOrder']
	]
	system.tag.writeBlocking("maintenance/megamation/number_open_pms", len(res))
	system.tag.writeBlocking("maintenance/megamation/pmList", res) 
	return res

I am getting a length error on the array memory tag though.

File "module:getPMList", line 17, in getPMList
ValueError: Length of values does not match length of paths.

system.tag.writeBlocking expects a list of paths and values to write to [1]. In your final call, you're passing a single path, but a list of values - so the function throws an error because it doesn't know how to marshal your results to the tag path provided.

[1] - There's a convenience overload that accepts a single path and single value, outside of a list, to save syntax overload in simple scenarios and for training classes; that's the only reason your first call to number_open_pms works.

You should only issue one call to writeBlocking (also, do you actually need to write this blocking, or could you write this asynchronously?


def getPMList(building):
	client = system.net.httpClient()
	params = {
		"STATUS": "S",
		"TYPE": "PM",
		"BUILDING_ID": building
	}
	response = client.get("https://api.megamation.com/clm/DL/workorder", params=params, username="<>", password="<>")
	res = [
		{
			'wo_no': key['wo_no'],
			'date': key['date'],
			'building_id': key['building_id'],
			'work_request_description': key['work_request_description'],
			'type': key['type']
		}
		for key in response.json['_embedded']['WorkOrder']
	]
	system.tag.writeBlocking(
		["maintenance/megamation/number_open_pms", "maintenance/megamation/pmList"],
		[len(res), res]
	)
	return res
1 Like

No it didn't need to be a blocking call. I was reading the page on "reading and writing tags" and didn't see the Asynchronous calls. Thank you again for your advice.

I wanted to add that I was able to clean this up and store the data in a tag as a dataset instead of a string array as above, which will link to a perspective table directly.

def getPMList(building):
	client = system.net.httpClient()
	response = client.get("https://api.megamation.com/clm/DL/workorder?STATUS=S&TYPE=PM&BUILDING_ID="+building, username="<>", password="<>")
	data = []
	for key in response.json['_embedded']['WorkOrder']:
		data.append([key['wo_no'], key['date'], key['building_id'], key['work_request_description']])

	
	headers = ['wo_no', 'date', 'building_id', 'work_request_description']	
	listing = system.dataset.toDataSet(headers, data)
	system.tag.writeAsync(["maintenance/megamation/number_open_pms","maintenance/megamation/pmList"], [len(data), listing])
1 Like