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