def test_commands(): commands = Commands( { '*CLS': FuncCmd(doc='clear status'), '*ESE': IntCmd(doc='standard event status enable register'), '*ESR': IntCmdRO(doc='standard event event status register'), '*IDN': IDNCmd(), '*OPC': IntCmdRO(set=None, doc='operation complete'), '*OPT': IntCmdRO(doc='return model number of any installed options'), '*RCL': IntCmdWO(set=int, doc='return to user saved setup'), '*RST': FuncCmd(doc='reset'), '*SAV': IntCmdWO(doc='save the preset setup as the user-saved setup'), '*SRE': IntCmdWO(doc='service request enable register'), '*STB': StrCmdRO(doc='status byte register'), '*TRG': FuncCmd(doc='bus trigger'), '*TST': Cmd(get=lambda x: not decode_OnOff(x), doc='self-test query'), '*WAI': FuncCmd(doc='wait to continue'), 'SYSTem:ERRor[:NEXT]': ErrCmd(doc='return and clear oldest system error'), }, { 'MEASure[:CURRent[:DC]]': FloatCmdRO(get=lambda x: float(x[:-1])), }) assert '*idn' in commands assert commands['*idn'] is commands['*IDN'] assert commands.get('idn') == None assert 'SYST:ERR' in commands assert 'SYSTEM:ERROR:NEXT' in commands assert 'syst:error' in commands assert commands['SYST:ERR'] is commands['system:error:next'] assert commands['MEAS'] is commands['measure:current:dc'] assert commands[':*idn']['min_command'] == '*IDN' assert commands['system:error:next']['min_command'] == 'SYST:ERR' with pytest.raises(KeyError) as err: commands['IDN'] assert 'IDN' in str(err.value)
def test_commands(): commands = Commands({ '*CLS': FuncCmd(doc='clear status'), '*ESE': IntCmd(doc='standard event status enable register'), '*ESR': IntCmdRO(doc='standard event event status register'), '*IDN': IDNCmd(), '*OPC': IntCmdRO(set=None, doc='operation complete'), '*OPT': IntCmdRO(doc='return model number of any installed options'), '*RCL': IntCmdWO(set=int, doc='return to user saved setup'), '*RST': FuncCmd(doc='reset'), '*SAV': IntCmdWO(doc='save the preset setup as the user-saved setup'), '*SRE': IntCmdWO(doc='service request enable register'), '*STB': StrCmdRO(doc='status byte register'), '*TRG': FuncCmd(doc='bus trigger'), '*TST': Cmd(get=lambda x : not decode_OnOff(x), doc='self-test query'), '*WAI': FuncCmd(doc='wait to continue'), 'SYSTem:ERRor[:NEXT]': ErrCmd(doc='return and clear oldest system error'), }, { 'MEASure[:CURRent[:DC]]': FloatCmdRO(get=lambda x: float(x[:-1])), }) assert '*idn' in commands assert commands['*idn'] is commands['*IDN'] assert commands.get('idn') == None assert 'SYST:ERR' in commands assert 'SYSTEM:ERROR:NEXT' in commands assert 'syst:error' in commands assert commands['SYST:ERR'] is commands['system:error:next'] assert commands['MEAS'] is commands['measure:current:dc'] assert commands[':*idn']['min_command'] == '*IDN' assert commands['system:error:next']['min_command'] == 'SYST:ERR' with pytest.raises(KeyError) as err: commands['IDN'] assert 'IDN' in str(err.value)
class SCPI(BaseDevice): """ Base class for :term:`SCPI` based bliss emulator devices """ Manufacturer = 'Bliss Team' Model = 'Generic SCPI Device' Version = '0' Firmware = '0.1.0' IDNFieldSep = ', ' def __init__(self, name, **opts): super_kwargs = dict(newline=opts.pop('newline', self.DEFAULT_NEWLINE)) super(SCPI, self).__init__(name, **super_kwargs) self._data = {} self._error_stack = collections.deque() self._commands = Commands(opts.get('commands', {})) for cmd_expr, cmd_info in self._commands.command_expressions.items(): min_name = cmd_info['min_command'].lower().replace('*', '').replace(':', '_') func = getattr(self, min_name, None) if func: cmd_info['func'] = func if 'default' in cmd_info: cmd_info['value'] = cmd_info['default'] def handle_line(self, line): self._log.info("processing line %r", line) line = line.strip() responses = [] for cmd in line.split(';'): cmd = cmd.strip() response = self.handle_command(cmd) if isinstance(response, SCPIError): self._error_stack.append(response) elif response is not None: responses.append(str(response)) if responses: return ';'.join(responses) + '\n' def handle_command(self, cmd): self._log.debug("processing cmd %r", cmd) cmd = cmd.strip() args = cmd.split(' ') instr = args[0].lower() args = args[1:] is_query = instr.endswith('?') instr = instr.rstrip('?') cmd_info = self._commands.get(instr) attr = cmd_info.get('func') result = None if attr is None: if 'value' in cmd_info: result = cmd_info['value'] if is_query: result = self.query(cmd_info['min_command'], *args) else: result = self.write(cmd_info['min_command'], *args) elif callable(attr): fargs = inspect.getargspec(attr).args if len(fargs) > 1 and fargs[1] == 'is_query': args = [is_query] + args result = attr(*args) else: if is_query: result = attr if result: self._log.debug("answering cmd %r with %r", cmd, result) else: self._log.debug("finished cmd %r", cmd) return result def query(self, instr, *args): try: cmd = self._commands.get(instr) return cmd.get('set', str)(cmd['value']) except KeyError: return SCPIError.ExecutionError def write(self, instr, *args): if args: self._log.debug('set %r to %r', instr, args[0]) self._commands.get(instr)['value'] = args[0] def idn(self): args = map(str, (self.Manufacturer, self.Model, self.Version, self.Firmware)) return self.IDNFieldSep.join(args) def cls(self): self._log.debug('clear') # clear SESR # clear OPERation Status Register # clear QUEStionable Status Register self._error_stack.clear() def opc(self, is_query): if is_query: return '1' def syst_err(self): pass