From 495709b670bc8d492c16cf11910d95805523f4e0 Mon Sep 17 00:00:00 2001 From: Markus Zolliker Date: Tue, 6 Jul 2021 16:24:44 +0200 Subject: [PATCH] allow partial describe in addition to the SECoP standard Change-Id: If756e8d9d6a67d3194abc0fe2436cf7124713536 --- secop/protocol/dispatcher.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/secop/protocol/dispatcher.py b/secop/protocol/dispatcher.py index 2836342..2485004 100644 --- a/secop/protocol/dispatcher.py +++ b/secop/protocol/dispatcher.py @@ -172,10 +172,10 @@ class Dispatcher: self.log.debug('-> module is not to be exported!') return OrderedDict() - def get_descriptive_data(self): + def get_descriptive_data(self, specifier): """returns a python object which upon serialisation results in the descriptive data""" - # XXX: be lazy and cache this? - result = {'modules': OrderedDict()} + modules = {} + result = {'modules': modules} for modulename in self._export: module = self.get_module(modulename) if not module.export: @@ -184,11 +184,22 @@ class Dispatcher: mod_desc = {'accessibles': self.export_accessibles(modulename)} mod_desc.update(module.exportProperties()) mod_desc.pop('export', False) - result['modules'][modulename] = mod_desc - result['equipment_id'] = self.equipment_id - result['firmware'] = 'FRAPPY - The Python Framework for SECoP' - result['version'] = '2021.02' - result.update(self.nodeprops) + modules[modulename] = mod_desc + modname, _, pname = (specifier or '').partition(':') + if modname in modules: # extension to SECoP standard: description of a single module + result = modules[modname] + if pname in result['accessibles']: # extension to SECoP standard: description of a single accessible + # command is also accepted + result = result['accessibles'][pname] + elif pname: + raise NoSuchParameterError('Module %r has no parameter %r' % (modname, pname)) + elif not modname or modname == '.': + result['equipment_id'] = self.equipment_id + result['firmware'] = 'FRAPPY - The Python Framework for SECoP' + result['version'] = '2021.02' + result.update(self.nodeprops) + else: + raise NoSuchModuleError('Module %r does not exist' % modname) return result def _execute_command(self, modulename, exportedname, argument=None): @@ -288,7 +299,7 @@ class Dispatcher: return (IDENTREPLY, None, None) def handle_describe(self, conn, specifier, data): - return (DESCRIPTIONREPLY, '.', self.get_descriptive_data()) + return (DESCRIPTIONREPLY, specifier or '.', self.get_descriptive_data(specifier)) def handle_read(self, conn, specifier, data): if data: