Esempio n. 1
0
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)
Esempio n. 2
0
 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']
Esempio n. 3
0
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)
Esempio n. 4
0
def test_SCPI(interface):
    scpi = SCPI(interface=interface)
    assert scpi['*IDN'] == interface.idn_obj
    assert scpi('*IDN?')[0][1] == interface.idn_obj

    scpi('*CLS')
    assert interface.commands == ['*CLS\n']

    scpi('*RST')
    assert interface.commands == ['*CLS\n', '*RST\n']

    cmds = Commands(
        COMMANDS,
        {'MEASure[:CURRent[:DC]]': FloatCmdRO(get=lambda x: float(x[:-1]))})
    meas_scpi = SCPI(interface=interface, commands=cmds)

    with pytest.raises(KeyError):
        scpi['MEAS']

    assert meas_scpi['MEAS'] == interface.meas
def __get_display_commands(window='[:WINDow1]'):
    r = {}
    for k, v in _display_commands.items():
        k = k.format(window=window)
        r[k] = v
    return r

__get_mXb_commands = partial(__get_commands, _mXb_commands)
__get_offset_commands = partial(__get_commands, _offset_commands)
__get_limits_commands = partial(__get_commands, _limits_commands)
__get_buffer_config_commands = partial(__get_commands, _buffer_config_commands)
__get_ratio_commands = partial(__get_commands, _ratio_commands)
__get_sens_commands = partial(__get_commands, _sens_commands)

_6482_commands = Commands()
_6482_commands.update(__get_mXb_commands('CALCulate[1]:'))
_6482_commands.update(__get_mXb_commands('CALCulate2:'))
_6482_commands.update(__get_offset_commands('CALCulate3:'))
_6482_commands.update(__get_offset_commands('CALCulate4:'))
_6482_commands.update(__get_ratio_commands('CALCulate5:'))
_6482_commands.update(__get_ratio_commands('CALCulate6:'))
_6482_commands.update(__get_limits_commands('CALCulate7:')) # TODO missing LIMitX, CLIMITs
_6482_commands.update(__get_buffer_config_commands('CALCulate8:'))
_6482_commands.update(__get_display_commands('[:WINDow1]'))
_6482_commands.update(__get_display_commands('[:WINDow2]'))
_6482_commands.update(__get_sens_commands('[SENSe[1]:]'))
_6482_commands.update(__get_sens_commands('SENSe2:'))

_6485_commands = Commands()
_6485_commands.update(__get_mXb_commands('CALCulate[1]:'))
Esempio n. 6
0
COMMANDS = Commands(
    _COMMANDS,
    {
        '*IDN':
        Cmd(get=decode_IDN, doc='identification query'),
        'REN':
        FuncCmd(doc='goes into remote when next addressed to listen'),
        'IFC':
        FuncCmd(
            doc=
            'reset interface; all devices go into talker and listener idle states'
        ),
        'LLO':
        FuncCmd(doc='LOCAL key locked out'),
        'GTL':
        FuncCmd(doc='cancel remote; restore front panel operation'),
        'DCL':
        FuncCmd(doc='return all devices to known conditions'),
        'INITiate':
        FuncCmd(doc='trigger reading'),
        'ABORt':
        FuncCmd(doc='abort'),
        'READ':
        FloatArrayCmdRO(doc='trigger and return reading',
                        func_name='read_data'),
        'FETCh':
        FloatArrayCmdRO(doc='request the latest reading(s)',
                        func_name='fetch_data'),
        'CONFigure[:CURRent[:DC]]':
        StrCmd(set=None,
               doc='places instrument in *one-shot* measurement mode'),
        'MEASure[:CURRent[:DC]]':
        FloatArrayCmdRO(doc='single measurement mode (= CONF + READ?',
                        func_name='measure'),
        'SYSTem:ZCHeck[:STATe]':
        OnOffCmd(doc='zero check', default=True),
        'SYSTem:ZCORrect[:STATe]':
        OnOffCmd(doc='zero correct', default=False),
        'SYSTem:ZCORrect:ACQuire':
        FuncCmd(doc='acquire a new correct value'),
        'SYSTem:PRESet':
        FuncCmd(doc='return system to preset defaults'),
        'SYSTem:LFRequency':
        IntCmd(doc='power line frequency (Hz)', default=60),
        'SYSTem:LFRequency:AUTO[:STATe]':
        OnOffCmd(doc='auto frequency detection', default=True),
        'SYSTem:AZERo[:STATe]':
        OnOffCmd(doc='auto zero', default=True),
        'SYSTem:TIME:RESet':
        FuncCmd(doc='reset timestamp to 0s'),
        'SYSTem:POSetup':
        StrCmd(doc='power-on setup (RST,PRES, SAVx (x=0..2)', default='PRES'),
        'SYSTem:VERSion':
        StrCmdRO(doc='return SCPI revision level'),
        'SYSTem:ERRor:ALL':
        ErrArrayCmd(doc='read and clear oldest errors'),
        'SYSTem:ERRor:COUNt':
        IntCmdRO(doc='return number of error messages in queue'),
        'SYSTem:ERRor:CODE[:NEXT]':
        IntCmdRO(doc='return and clear oldest error code'),
        'SYSTem:ERRor:CODE:ALL':
        IntArrayCmdRO(doc='return and clear all error codes'),
        'SYSTem:CLEar':
        FuncCmd(doc='clear messages from error queue'),
        'SYSTem:KEY':
        IntCmd(doc='get last pressed key; simulate a key-press'),
        'SYSTem:LOCal':
        FuncCmd(
            doc=
            'while in LLO, removes LLO and places model in local (RS-232 only)'
        ),
        'SYSTem:REMote':
        FuncCmd(doc='places model in remote if not in LLO (RS-232 only)'),
        'SYSTem:RWLock':
        FuncCmd(doc='places model in local lockout (RS-232 only)'),

        # status
        'STATus:MEASurement[:EVENt]':
        IntCmdRO(doc='read event register'),
        'STATus:MEASurement:ENABle':
        IntCmd(doc='program enable register'),
        'STATus:MEASurement:CONDition':
        IntCmdRO(doc='return condition register'),
        'STATus:OPERation:EVENT':
        IntCmdRO(doc='read event register'),
        'STATus:OPERation:ENABLe':
        IntCmd(doc='program event register (<NDN> or <NRf>)'),
        'STATus:QUEStionable[:EVENt]':
        IntCmdRO(doc='read event register'),
        'STATus:QUEStionable:CONDition':
        IntCmdRO(doc='condition register'),
        'STATus:QUEStionable:ENABLe':
        IntCmd(doc='program event register (<NDN> or <NRf>)'),
        'STATus:PRESet':
        FuncCmd(doc='return status registers to default values'),
        'STATus:QUEue[:NEXT]':
        ErrCmd(doc='return and clear oldest error code'),
        'STATus:QUEue:CLEar':
        FuncCmd(doc='clear messages from error queue'),
        # TODO missing STATUS:QUEUE:ENABLE,DISABLE

        # range, auto range and display
        'CURRent:RANGe[:UPPer]':
        FloatCmd(doc='measure current range selection'),
        'CURRent:RANGe:AUTO':
        OnOffCmd(doc='measure current auto range'),
        'CURRent:RANGe:AUTO:ULIMt':
        FloatCmd(doc='measure current upper range limit for auto range'),
        'CURRent:RANGe:AUTO:LLIMt':
        FloatCmd(doc='measure current lower range limit for auto range'),

        # buffer (TRACE == DATA subsystem)
        'TRACe:DATA':
        StrCmdRO(doc='read all readings in buffer'),
        'TRACe:CLEar':
        FuncCmd(doc='clear readings from buffer'),
        'TRACe:FREE':
        IntArrayCmdRO(doc='bytes available and bytes in use'),
        'TRACe:POINts':
        IntCmd(doc='number of reading (1..2500)', default=100),
        'TRACe:POINts:ACTual':
        IntCmdRO(doc='number of readings actually stored in buffer'),
        'TRACe:FEED':
        StrCmd(doc='source of readings (SENSe1, CALCulate1 or CALCulate2)',
               default='SENSe1'),
        'TRACe:FEED:CONTrol':
        StrCmd(doc='buffer control mode (NEV or NEXT)', default='NEV'),
        'TRACe:TST:FORMat':
        StrCmd(doc='timestamp format (ABS, DELT)', default='ABS'),
        'FORMat:ELEMents':
        StrArrayCmd(
            doc=
            'data elements for TRACe:DATA? response message (list of READ,UNIT,TIME,STATe)',
            default=['READ', 'UNIT', 'TIME', 'STATe']),
        'FORMat[:DATA]':
        StrCmd(doc='data format (ASCii, REAL, 32, SREal)', default='ASC'),
        'FORMat:BORDer':
        StrCmd(doc='byte order (NORMal, SWAPped)'),
        'FORMat:SREGister':
        StrCmd(
            doc=
            'data format for status registers (ASCii, HEXadecimal, OCTal or BINary',
            default='ASC'),

        # triggering
        'ARM[:SEQuence1][:LAYer1]:SOURce':
        StrCmd(doc='control source (IMM, TIMer, BUS, TLIN, MAN)',
               default='IMM'),
        'ARM[:SEQuence1][:LAYer1]:COUNt':
        IntCmd(doc='measure count (1..2500 or INF)', default=1),
        'ARM[:SEQuence1][:LAYer1]:TIMer':
        FloatCmd(doc='timer interval (s) (0.001..99999.99)', default="0.1"),
        'ARM[:SEQuence1][:LAYer1][:TCONfigure]:DIRection':
        StrCmd(doc='enable (SOURce) or disable (ACC) bypass', default='ACC'),
        'ARM[:SEQuence1][:LAYer1][:TCONfigure][:ASYNchronous]:ILINe':
        IntCmd(doc='input trigger line (1..6)', default=1),
        'ARM[:SEQuence1][:LAYer1][:TCONfigure][:ASYNchronous]:OLINe':
        IntCmd(doc='output trigger line (1..6)', default=2),
        'ARM[:SEQuence1][:LAYer1][:TCONfigure][:ASYNchronous]:OUTPut':
        StrCmd(doc='output trigger (TRIGger) or not at all (NONE)',
               default='NONE'),
        'TRIGger:CLEar':
        FuncCmd(doc='clear pending input trigger immediately'),
        'TRIGger[:SEQuence1]:SOURce':
        StrCmd(doc='control source (IMM, TLIN)', default='IMM'),
        'TRIGger[:SEQuence1]:COUNt':
        IntCmd(doc='measure count (1..2500 or INF)', default=1),
        'TRIGger[:SEQuence1]:DELay':
        FloatCmd(doc='trigger delay (s) (0..999.9998)', default=0.),
        'TRIGger[:SEQuence1]:DELay:AUTO':
        OnOffCmd(doc='enable or disable auto delay', default='OFFset'),
        'TRIGger[:SEQuence1][:TCONfigure]:DIRection':
        Cmd(doc='enable (SOURce) or disable (ACC) bypass', default='ACC'),
        'TRIGger[:SEQuence1][:TCONfigure][:ASYNchronous]:ILINe':
        IntCmd(doc='input trigger line (1..6)', default=1),
        'TRIGger[:SEQuence1][:TCONfigure][:ASYNchronous]:OLINe':
        IntCmd(doc='output trigger line (1..6)', default=2),
        'TRIGger[:SEQuence1][:TCONfigure][:ASYNchronous]:OUTPut':
        StrCmd(
            doc='output trigger after measurement (SENS) or not at all (NONE)',
            default='NONE'),

        # display
    })
Esempio n. 7
0
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
Esempio n. 8
0
 def __init__(self, *args, **kwargs):
     commands = SCPICommands(SCPI_COMMANDS)
     model = str(kwargs.pop('model'))
     commands.update(SCPI_MODEL_COMMANDS.get(model, {}))
     kwargs['commands'] = commands
     super(KeithleySCPI, self).__init__(*args, **kwargs)
Esempio n. 9
0
 def __init__(self, *args, **kwargs):
     commands = SCPICommands(SCPI_COMMANDS)
     model = str(kwargs.pop('model'))
     commands.update(SCPI_MODEL_COMMANDS.get(model, {}))
     kwargs['commands'] = commands
     super(KeithleySCPI, self).__init__(*args, **kwargs)
Esempio n. 10
0
 def __init__(self, *args, **kwargs):
     kwargs['commands'] = Commands(COMMANDS, MODEL_COMMANDS['6485'])
     super(Keithley6485, self).__init__(*args, **kwargs)