Calling function on another gateway?

Cool, thanks! I was sure I’d seen something before but never used it before.

I created a message handler that accepts a string path to the system function to call so I can use it generically for calling any system function on the other gateway:

	"""	
	Arguments:
		payload: A dictionary with the following structure:
		If the function accepts keyword args:
			{'function': 'subLibrary.functionName',
			 'args': {'arg1': 'val1', 'argN': valN'}
			}
		If the function doesn't accept keyword args:
			{'function': 'subLibrary.functionName',
			 'args': ['arg1Val', 'argNVal']
			}
		Note: The function string appended to "system." will be the resulting function call executed.
		      Passing in the full system.subLibrary.functionName will also work but system. is otherwise
		      assumed.
	"""
	import traceback
	functionWhiteList = []
	functionWhiteList.extend(['device.listDevices', 'device.setDeviceEnabled'])
	
	try:
		functionPartialString = payload['function']
	except KeyError:
		return traceback.format_exc()
	
	# remove 'system.' from the start if it exists
	if functionPartialString.startswith('system.'):
		functionPartialString = functionPartialString[len('system.'):]
	
	if not any([functionPartialString == func for func in functionWhiteList]):
		raise KeyError('Function not included in whitelist.')
	
	function = system
	for part in functionPartialString.split('.'):
		function = getattr(function, part)
	
	args = payload.get('args', {})
	if isinstance(args, dict):
		ret = function(**args)
	else:
		ret = function(*args)
	
	return ret

and calling it on the other gateway:

project = 'dummy'
msgType = 'systemFunction'
payload = {'function': 'system.device.listDevices'}
remoteGWName = 'OtherGWName'

print system.util.sendRequest(project, msgType, payload, remoteGWName)

UPDATED: added a whitelist by popular demand / the firing squad made me do it

4 Likes