import logging from base import HandlerBase from frappy.client import SecopClient # from frappy.lib.enum import EnumMember # from frappy.datatypes import get_datatype def convert_par(module, name, par): result = dict(type='input', name=module+":"+name, title=name) if par.get('readonly', True): result['type'] = 'rdonly' else: result['command'] = 'change %s:%s' % (module, name) if par['datainfo']['type'] == 'enum': result['enum_names'] = [dict(title=k, value=v) for k, v in par['datainfo']['members'].items()] result['type'] = 'enum' elif par['datainfo']['type'] == 'bool': result['type'] = 'checkbox' return result class SecopInteractor(SecopClient): prio_par = ["value", "status", "target"] hide_par = ["baseclass", "class", "pollinterval"] skip_par = ["status2"] def __init__(self, uri, node_map): super().__init__(uri) self.module_updates = set() self.param_updates = set() self.updates = {} self.connect() node_map.update({k: self for k in self.modules}) self.register_callback(None, updateItem=self.updateItem) def add_main_components(self, components): for name, desc in self.modules.items(): component = dict(type='rdlink', name=f'{name}:value', title=name) if 'status' in desc['parameters']: component['statusname'] = f'{name}:status' components.append(component) self.param_updates.add('value') self.param_updates.add('status') def get_components(self, path): module = self.modules[path] self.module_updates.add(path) # TODO: remove others? parameters = dict(module["parameters"]) components = [] for name in SecopInteractor.skip_par: if name in parameters: parameters.pop(name) for name in SecopInteractor.prio_par: if name in parameters: components.append(convert_par(path, name, parameters.pop(name))) components1 = [] for name in SecopInteractor.hide_par: if name in parameters: components1.append(convert_par(path, name, parameters.pop(name))) for name, p in parameters.items(): components.append(convert_par(path, name, parameters[name])) components.extend(components1) return dict(type='draw', path=path, title=path, components=components) def updateItem(self, module, parameter, entry): key = module, parameter # print(key, entry) if module in self.module_updates or parameter in self.param_updates: name = f'{module}:{parameter}' if entry.readerror: item = {'name': name, 'error': str(entry.readerror)} else: item = {'name': name, 'value': str(entry), 'formatted': entry.formatted()} # print(item) self.updates[key] = item def update_main(self): cache = self.cache for modname in self.modules: key = modname, 'value' if key in cache: self.updateItem(*key, cache[key]) def update_params(self, path): cache = self.cache for param in self.modules[path]['parameters']: key = path, param if key in cache: self.updateItem(*key, cache[key]) def handle_command(self, command): """handle command if we can, else return False""" if not command.strip(): return dict(type='accept-command') if command.startswith('change '): command = command[7:] modpar, _, strvalue = command.partition(' ') module, _, parameter = modpar.partition(':') if not parameter: parameter = 'target' if module not in self.modules: return False logging.info('SENDCOMMAND %r', command) try: self.setParameterFromString(module, parameter, strvalue) except Exception as e: print(f"{e!r} converting {strvalue} to {self.modules[module]['parameters'][parameter]['datatype']}") return True def get_updates(self): updates, self.updates = self.updates, {} return list(updates.values()) def info(self): return ["na"] # class SecopInstrument(HandlerBase): # # def __init__(self, inst_name, instrument_config): # super().__init__() # self.instrument_config = instrument_config # host_ports = instrument_config['hostport'] # self.logger_dir = instrument_config.get('logger_dir', '') # # test_day = instrument_config.get('test_day', None) # # self.test_day = [int(x) for x in test_day.split('-')] if test_day else None # self.title = inst_name # self.device = '' # self.nodes = [] # self.node_map = {} # for host_port in host_ports.split(','): # node = SecopClient(host_port) # node.connect() # self.nodes.append(node) # for name, mod in node.modules.items(): # self.node_map[name] = node # # def register(self, client): # print('OPEN') # for node in self.nodes: # node.register_callback(None, client.updateItem) # return super().register(client) # # def remove(self, client): # print('REMOVE') # for node in self.nodes: # node.unregister_callback(None, client.updateItem) # super().remove(client) # # def new_client(self): # return self.register(SecopClient(self))