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 __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 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
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 })
def __init__(self, *args, **kwargs): kwargs['commands'] = Commands(COMMANDS, MODEL_COMMANDS['6485']) super(Keithley6485, self).__init__(*args, **kwargs)