/lib/instruments.py
https://github.com/pruan/TestDepot · Python · 2725 lines · 2074 code · 375 blank · 276 comment · 304 complexity · e41fb248beb7871b14689746d524b862 MD5 · raw file
Large files are truncated click here to view the full file
- #!/usr/bin/python
- # -*- coding: ascii -*-
- # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
- #
- # Copyright (C) 1999-2005 Stratalight Communications.
- #
- """
- Module where instrument objects are defined. These are persistent objects that
- can be stored in the Stratatest storage.
- """
- __all__ = ['InstrumentError', 'VISASyntaxError', 'GPIBInvalidCommand',
- 'VISAResource', 'GPIBResource', 'Bitfield', 'EventStatusEnableRegister',
- 'ServiceRequestEnableRegister', 'Block', 'Boolean', 'Identity', 'SCPIFloat',
- 'GpibInstrumentWrapper', 'Instrument', 'InstrumentChassis', 'InstrumentModule',
- 'InstrumentPort', 'DMM', 'RFSignalGenerator', 'Oscilloscope', 'HP53131A',
- 'FunctionGenerator', 'DCPower', 'SpectrumAnalyzer', 'OpticalSpectrumAnalyzer',
- 'PowerMeter', 'OpticalSignalGenerator', 'OpticalPowerAmp', 'OpticalPowerMeter',
- 'OpticalAttenuator', 'FIBERAMP', 'HP8163A', 'HP8163B', 'HP81635A', 'HP81635APort',
- 'HP81591A', 'HP81594B', 'HP8159xPort', 'MAP', 'OpticalAttenuator_JDSU',
- 'HP81570A', 'HP81570APort',
- 'HP81576A', 'HP81576APort',
- 'HP81663A', 'HP81689A', 'HP816xxAPort', 'HP81689APort', 'HP81663APort',
- 'HP86120C', 'HP8156A', 'HP34401A', 'HP86100A', 'HP34970A', 'HP33120A',
- 'HP6674A', 'HP81619A', 'HP81619APort', 'HP81633A', 'HP81633APort',
- 'HP83650L', 'AQ6317B', 'AQ6370',
- 'GP700', 'IA3',
- 'Graph', 'Marker', 'Modulation', 'plug_module',
- 'unplug_module', 'get_quantity', 'update_instruments', 'get_class',
- 'get_devices', 'clear_controller', 'KEOPSYSAMP']
- from copy import copy
- import sys
- from time import clock, sleep
- from netobjects import PersistentList, PersistentDict, PersistentData, MANDATORY, CONTAINER
- import scheduler
- import stratabuiltins # only needs to be imported, nothing more.
- import slstorage
- import pyvisa.visa as visa
- import pyvisa.vpp43 as vpp43
- import pyvisa.visa_exceptions as visa_exceptions
- import time
- import math
- from dataAnalysisLib import avg
- # instrument exceptions
- class InstrumentError(ValueError):
- pass
- class VISASyntaxError(InstrumentError):
- pass
- class GPIBInvalidCommand(InstrumentError):
- pass
- add_exception(InstrumentError)
- add_exception(VISASyntaxError)
- add_exception(GPIBInvalidCommand)
- # VISA objects
- class VISAResource(object):
- pass
- class GPIBResource(VISAResource):
- """GPIB[board]::primary address[::secondary address][::INSTR]"""
- def __init__(self, board=0, address=0, secondary=None):
- self.board = int(board)
- self.address = int(address)
- self.secondary = secondary
- def __repr__(self):
- return "%s(%r, %r, %r)" % (self.__class__.__name__, self.board, self.address, self.secondary)
- def __str__(self):
- if secondary is None:
- return "GPIB%s::%s::INSTR" % (self.board, self.address)
- else:
- return "GPIB%s::%s::%s::INSTR" % (self.board, self.address, self.secondary)
- def parse(self, text):
- parts = text.split("::")
- if len(parts) == 4:
- self.board, self.address, self.secondary = int(parts[0][4:]), int(parts[1]), int(parts[2])
- elif len(parts) in (2, 3):
- self.board, self.address, self.secondary = int(parts[0][4:]), int(parts[1]), None
- else:
- raise VISASyntaxError, "invalid GPIB resource: %s" % (text,)
- class Bitfield(object):
- "Mutable set of bits that also looks like an integer."
- _NAMES = {
- }
- def __init__(self, init_bits=0, numbits=32):
- self.bits = int(init_bits)
- if numbits < 1 or numbits > 32:
- raise ValueError, "bits must be 1:32"
- self._size = numbits
- def getbit(self, bit):
- return self.bits & (1 << bit)
- def setbit(self, bit):
- self.bits |= (1 << bit)
- def clearbit(self, bit):
- self.bits &= ~(1 << bit)
- def __str__(self):
- s = ["Bits set:"]
- names = self._NAMES
- for bit in range(self._size):
- if self.bits & 2**bit:
- name = names.get(bit)
- if name:
- s.append(name)
- else:
- s.append("Bit %d" % (bit,))
- return "\n".join(s)
- def __int__(self):
- return self.bits & ~(0xffffffff << self._size)
- def __getitem__(self, bit):
- return self.bits & (1 << bit)
- def __setitem__(self, bit, val):
- if bool(val):
- self.bits |= (1 << bit)
- else:
- self.bits &= ~(1 << bit)
-
- class EventStatusEnableRegister(Bitfield):
- _NAMES = {
- 7: "Power On",
- 6: "User Request",
- 5: "Command Error",
- 4: "Execution Error",
- 3: "Device dependent Error",
- 2: "Query Error",
- 1: "Request Control",
- 0: "Operation Complete",
- }
- def __init__(self, init_bits=0):
- super(EventStatusEnableRegister, self).__init__(init_bits, 8)
- class ServiceRequestEnableRegister(Bitfield):
- _NAMES = {
- 7: "Operation Status",
- 6: "Request Status",
- 5: "Event Status Byte",
- 4: "Message Available",
- 3: "Questionable Status",
- }
- def __init__(self, init_bits=0):
- super(ServiceRequestEnableRegister, self).__init__(init_bits, 8)
- class Block(object):
- def __init__(self, data):
- self.parse(data)
- def __str__(self):
- l = len(self.data)
- H = len(str(l))
- return "#%d%d%s" % (H, l, self.data)
- def parse(self, string):
- if string.startswith("#"):
- H = int(string[1])
- l = int(string[2:2+H])
- self.data = string[l+2:l]
- else:
- self.data = string
- class Boolean(object):
- def __init__(self, data):
- try:
- self.value = bool(int(data))
- except ValueError:
- if type(data) is str:
- data = data.lower()
- if data in ("on", "yes", "true", "enable", "ok"):
- self.value = True
- elif data in ("off", "no", "false", "disable", "notok"):
- self.value = False
- else:
- raise ValueError, "invalid value for Boolean: %s" % (data,)
- def __str__(self):
- return IF(self.value, "ON", "OFF")
- def __repr__(self):
- return "Boolean(%r)" % (self.value,)
- def __nonzero__(self):
- return self.value
- def __int__(self):
- return int(self.value)
- class Identity(object):
- """An equipment Identity. Returned from identify() instrument method."""
- def __init__(self, idtext=None):
- if idtext:
- idtext = idtext.strip()
- if idtext:
- self.parse(idtext)
- else:
- self.clear()
- else:
- self.clear()
- def clear(self):
- self.manufacturer = None
- self.model = None
- self.serial = None
- self.firmware = None
- def __str__(self):
- return """IDN: MFG: %s Model: %s Serial: %s Firmware: %s""" % (self.manufacturer, self.model, self.serial, self.firmware)
- # some equipment have five fields, most have four.
- def parse(self, text):
- commas = text.count(",")
- if commas > 3:
- self.manufacturer, model1, model2, self.serial, self.firmware = self._chop(text, 4)
- self.model = model1+model2
- elif commas > 2:
- self.manufacturer, self.model, self.serial, self.firmware = self._chop(text, 3)
- else:
- raise ValueError, "identity string appears invalid: %r" % (text,)
- def _chop(self, text, commas):
- return map(lambda s: s.replace(" ", ""), text.split(",",commas))
- # JDSU module ID is NOT standard IEEE
- class Identity_JDSU(object):
- """An equipment Identity. Returned from identify() instrument method."""
- def __init__(self, idtext=None):
- if idtext:
- idtext = idtext.strip()
- if idtext:
- #print "JDSU IDTEXT: %s" % idtext
- self.parse(idtext)
- else:
- self.clear()
- else:
- self.clear()
- def clear(self):
- self.manufacturer = None
- self.model = None
- self.serial = None
- self.firmware = None
- def __str__(self):
- return """IDN: MFG: %s Model: %s Serial: %s Firmware: %s""" % (self.manufacturer, self.model, self.serial, self.firmware)
- # some equipment have five fields, most have four.
- def parse(self, text):
- commas = text.count(",")
- if commas > 3:
- self.serial, self.model, model2, junk, self.firmware = self._chop(text, 4)
- self.manufacturer = 'JDSU'
- print " === model: %s" % self.model
- elif commas > 2:
- self.serial, self.model, self.firmware = self._chop(text, 3)
- self.manufacturer = 'JDSU'
- print "**** model: %s" % self.model
- else:
- raise ValueError, "identity string appears invalid: %r" % (text,)
- def _chop(self, text, commas):
- return map(lambda s: s.replace(" ", ""), text.split(",",commas))
-
- # a float with special values defined by SCPI
- class SCPIFloat(float):
- def __str__(self):
- if self == 9.9e37:
- return "INF"
- elif self == -9.9e37:
- return "NINF"
- elif self == 9.91e37:
- return "NaN"
- else:
- return float.__str__(self)
- ### constants and enumerations ###
- ### Some Instrument object attributes may be set to one of these values.
- DEFAULT = "DEF"
- MIN = "MIN"
- MAX = "MAX"
- ON = Enum(1, "ON")
- OFF = Enum(0, "OFF")
- SWEEP_STOP = Enum(0, "SWEEP_STOP")
- SWEEP_SINGLE = Enum(1, "SWEEP_SINGLE")
- SWEEP_CONTINUOUS = Enum(2, "SWEEP_CONTINUOUS") # same as REPEAT
- SWEEP_AUTO = Enum(3, "SWEEP_AUTO")
- SWEEP_SEGMENTMEASURE = Enum(4, "SWEEP_SEGMENTMEASURE")
- INF = SCPIFloat(9.9e37)
- NINF = SCPIFloat(-9.9e37)
- NaN = SCPIFloat(9.91e37)
- ## support for general modulation parameters ##
- # modulation types
- DC = NOMOD = Enum(0, "DC")
- AM = Enum(1, "AM")
- FM = Enum(2, "FM")
- PSK = Enum(3, "PSK")
- FSK = Enum(4, "FSK")
- # modulation subtypes
- SBSC = Enum(0, "SBSC") # FM subtype
- # modulation sources
- INT = Enum(0, "INT") # internal digital modulation
- INT1 = Enum(0, "INT1")
- INT2 = COHC = Enum(1, "INT2") # coherence control
- EXT = AEXT = Enum(2, "EXT") # external analog modulation
- DEXT = Enum(3, "DEXT") # external digital modulation
- WVLL = Enum(5, "WVLL") # wavelength locking
- BACK = Enum(6, "BACK") # backplane - external digital modulation using Input Trigger Connector
- # laser source selection
- LASER_EXTERNAL = Enum(0, "EXT")
- LASER_LOWER = Enum(1, "LOW")
- LASER_UPPER = Enum(2, "UPP")
- LASER_BOTH = Enum(3, "BOTH")
- # oscilloscope and spectrum analyzer control values
- PEAK = Enum(100, "PEAK")
- CENTER = Enum(101, "CENTER")
- REFERENCE = Enum(102, "REFERENCE")
- SCALE_WAVELENGTH = Enum(0, "SCALE_WAVELENGTH")
- SCALE_FREQUENCY = Enum(1, "SCALE_FREQUENCY")
- class GpibInstrumentWrapper(object):
- """Wrapper for VISA sessions that allows logging."""
- def __init__(self, inst, logfile):
- self._inst = inst
- self._logfile = logfile
- self._use_srq = False
- def __getattr__(self, key):
- return getattr(self._inst, key)
- def set_logfile(self, logfile):
- self._logfile = logfile
- def read(self):
- if self._use_srq:
- self.wait_for_srq()
- rv = self._inst.read()
- if self._logfile:
- self._logfile.write("VISA read: %s: %r\n" % (self._inst.resource_name, rv))
- return rv
- def write(self, text, wait=False):
- if self._logfile:
- self._logfile.write("VISA write: %s: %r\n" % (self._inst.resource_name, text))
- self._inst.write(text)
- if wait:
- cmd = "*OPC?"
- retries = 10
- while retries > 0:
- # do the command again
- self._inst.write(text)
- comp = int(self.ask(cmd))
- #print "comp: %s, retries: %s" % (comp, retries)
- if comp:
- break
- else:
- #print "resource: %s" % self._inst.resource_name
- self._inst.write(text)
- comp = int(self.ask(cmd))
- time.sleep(1)
- retries -= 1
- if not comp:
- raise InstrumentError, "Operation %r did not complete." % (text,)
- def ask(self, cmd):
- self._inst.write(cmd)
- if self._use_srq:
- self.wait_for_srq()
- rv = self._inst.read()
- if self._logfile:
- self._logfile.write("VISA ask: %s: %r -> %r\n" % (self._inst.resource_name, cmd, rv))
- return rv
- def _get_stb(self):
- return vpp43.read_stb(self._inst.vi)
- STB = property(_get_stb, None, None, "Status byte (STB)")
- def use_srq(self, flag=True):
- self._use_srq = bool(flag)
- srquse = property(lambda s: s._use_srq, use_srq, None, "SRQ line in use? Set to True to use SRQ line.")
- def wait_for_srq(self, timeout=250):
- vpp43.enable_event(self._inst.vi, vpp43.VI_EVENT_SERVICE_REQ, vpp43.VI_QUEUE)
- if timeout and not(0 <= timeout <= 4294967):
- raise ValueError, "timeout value is invalid"
- starting_time = clock()
- try:
- while True:
- if timeout is None:
- adjusted_timeout = vpp43.VI_TMO_INFINITE
- else:
- adjusted_timeout = max(0, int((starting_time + timeout - clock()) * 1000))
- event_type, context = vpp43.wait_on_event(self._inst.vi, vpp43.VI_EVENT_SERVICE_REQ, adjusted_timeout)
- vpp43.close(context)
- if vpp43.read_stb(self._inst.vi) & 0x40:
- break
- finally:
- vpp43.discard_events(self._inst.vi, vpp43.VI_EVENT_SERVICE_REQ, vpp43.VI_QUEUE)
- def get_SRE(self):
- res = self.ask("*SRE?")
- return ServiceRequestEnableRegister(int(res))
- def set_SRE(self, val):
- val = int(val) & 0xFF
- self.write("*SRE %d" % (val,))
- SRE = property(get_SRE, set_SRE, None, "SRE value")
- def get_ESE(self):
- res = self.ask("*ESE?")
- return EventStatusEnableRegister(int(res))
- def set_ESE(self, val):
- val = int(val) & 0xFF
- self.write("*ESE %d" % (val,))
- ESE = property(get_ESE, set_ESE)
- # abstract base class for instruments. Don't use this directly. This is a
- # persistent object that is also stored in the configuration.
- class Instrument(PersistentData):
- "A generic virtual instrument. It holds the base attributes."
- _ATTRS = {
- "name": (str, "unknown"),
- "manufacturer": (str, "unknown"),
- "modelNumber": (str, "unknown"),
- "serialNumber": (str, "unknown"),
- "firmware": (str, "unknown"),
- "password": (str, "1234"),
- "visa_resource": (str, ""), # e.g.'GPIB2::22'
- }
- def __str__(self):
- return "%s: %s %s (SN: %s)" % (self.name, self.manufacturer, self.modelNumber, self.serialNumber)
- def get_agent(self, logfile=None):
- """Returns a VISA Instrument instance to control the instrument."""
- try:
- return self._cache["_agent"]
- except KeyError:
- if self.visa_resource:
- a = scheduler.get_scheduler().timeout(visa.GpibInstrument, args=(self.visa_resource,))
- else:
- raise ValueError, "Instrument: visa_resource not set."
- a = GpibInstrumentWrapper(a, logfile or self._cache.get("_logfile"))
- self._cache["_agent"] = a
- self.initialize(a)
- return a
- def clear_agent(self):
- try:
- a = self._cache.pop("_agent")
- except KeyError:
- pass
- else:
- a.clear()
- a.close()
- # override if agent needs initialization after creation
- def initialize(self, agent):
- pass
- def set_logfile(self, lf):
- self._cache["_logfile"] = lf
- def clear_controller(self):
- self.clear_agent()
- clear_controller(self.visa_resource)
- def update(self):
- eqid = self.identify()
- self.manufacturer = eqid.manufacturer
- self.modelNumber = eqid.model
- self.serialNumber = eqid.serial
- self.firmware = eqid.firmware
- self.clear_agent()
- #print eqid
- def identify(self):
- return Identity(self.get_agent().ask("*IDN?"))
-
- def options(self):
- if self.name.startswith('MAP'):
- #print "Gettting GPIB address..."
- #cmd = "SYST:GPIB?"
- #print "CMD: %s" % cmd
- #print "GPIB: %s" % self.get_agent().ask(cmd)
- #cmd = "*IDN?"
- cmd = "SYST:LAY? 1"
- #cmd = ":SLOT1:IDN?"
- #cmd = "SYSTem:LAYout? 1"
- #cmd = "SYST:CARD:INFO? 1,1"
- #print "CMD: %s" % cmd
- raw = self.get_agent().ask(cmd)
- #print "raw: %s" % raw
-
- else:
- raw = self.get_agent().ask("*OPT?")
- print "RAW: %s" % raw
- return map(str.strip, raw.split(","))
- def test_result(self):
- res = self.get_agent().ask("*TST?")
- return int(res) # XXX
- def reset(self):
- self.get_agent().write("*RST")
- def clear_status(self):
- self.get_agent().write("*CLS")
- def wait(self):
- self.get_agent().write("*WAI")
-
- class InstrumentChassis(Instrument):
- """Instrument that is a chassis for holding other instrument modules."""
- _ATTRS = Instrument._ATTRS.copy()
- _ATTRS.update({
- "slots": (PersistentDict, CONTAINER), # slot maps to list index
- })
- SLOTBASE = 0
- # make the storage look like reality.
- def update(self):
- super(InstrumentChassis, self).update()
- for i, opt in enumerate(self.options()):
- if not opt:
- continue
- if (opt.endswith('BBS')) or (opt.endswith('EMP')) or (opt.endswith('UVL')):
- continue
- print "i: %s, opt: %s" % (i, opt)
- model = opt.split()[-1] # get rid of extraneous prefixes
- cls = get_class(model) # XXX true for all OPT? need spec...
- if cls is not None:
- #print "**** cls: %s" % cls
- inst = cls(visa_resource=self.visa_resource)
- try:
- plug_module(self, inst, i+self.SLOTBASE)
- except InstrumentError:
- unplug_module(self, i+self.SLOTBASE)
- plug_module(self, inst, i+self.SLOTBASE)
- inst.update()
- inst.name = "%s_%s" % (opt.strip(), inst.serialNumber)
- #print "xxx inst name: %s" % inst.name
- else:
- self.clear_agent()
- raise InstrumentError, "no instrument object defined for model: %s" % (model,)
- self.clear_agent()
- def plug_module(self, module, slot):
- return plug_module(self, module, slot)
- def unplug_module(self, module, slot):
- return unplug_module(self, module, slot)
- def is_empty(self, slot):
- "Indicate is given slot is empty or not."
- return bool(int(self.get_agent().ask(":SLOT%d:EMPT?" % (slot,))))
- def has_module(self, slot):
- "Indicate if a slot has something."
- return not self.is_empty()
- def get_slots(self):
- return self.slots.items()
- def get_modules(self, model=None):
- """Return a list of module with the given model name, or all modules if no model given."""
- if model is None:
- return self.slots.values()
- else:
- rv = []
- model = str(model)
- for slot, module in self.slots.items():
- if module.__class__.__name__.find(model) >= 0:
- rv.append(module)
- return rv
- def get_module(self, name):
- """Search for an installed module by model name. Returns module object,
- or None if not found."""
- if type(name) is int:
- return self.slots[name+self.SLOTBASE]
- for slot, module in self.slots.items():
- if module.__class__.__name__.find(name) >= 0:
- break
- else:
- return None # not found
- return module
- def __getitem__(self, name):
- mod = self.get_module(name)
- if mod:
- return mod
- else:
- raise KeyError, "module model name or index not found."
- class InstrumentModule(Instrument):
- """Instrument that is a module that fits into an InstrumentChassis."""
- _ATTRS = Instrument._ATTRS.copy()
- _ATTRS.update({
- "chassis": (InstrumentChassis, None), # parent object actually holding this module instance
- "slot": (int, 0), # slot
- })
- PORTBASE = 0
- def identify(self):
- if type(self) is IA3:
- #print "### Calling Identity_JDSU()..."
- self.name = 'IA3'
- return Identity_JDSU(self.get_agent().ask("SYST:CARD:INFO? 1,%s" %
- (self.slot,)), )
- else:
- #print "### Caling normal Identity()..."
- return Identity(self.get_agent().ask(":SLOT%d:IDN?" % (self.slot,)))
- def is_empty_head(self, head=0): # ack! I hope not!
- "Query if the port is is present."
- return int(self.get_agent().ask(":SLOT%d:HEAD%d:EMPT?" % (self.slot, head+self.PORTBASE)))
-
- def get_slot(self, slot=0):
- return self.slot
- def get_port(self, port=0):
- """Return a generic port. You probably want to override this in a subclass"""
- return self._get_port(InstrumentPort, port)
- def _get_master_port(self, portclass):
- if portclass.MASTER >= 0:
- return self._get_port(portclass, portclass.MASTER)
- else:
- return None
- def _get_port(self, portclass, port):
- #print "portclass: %s, port: %s" % (portclass, port)
- #print "portbase: %s" % self.PORTBASE
- if type (port) is int:
- return portclass(self, port+self.PORTBASE)
- elif type (port) is str and port.startswith("port"):
- port = int(port[4:])
- return portclass(self, port)
- else:
- raise ValueError, "invalid port number or name"
- def __getitem__(self, port):
- try:
- return self.get_port(port)
- except ValueError, err:
- raise KeyError, err
- def options(self):
- """Return connector options and instrument options"""
- return map(str.strip, self.get_agent().ask(":SLOT%d:OPT?" % (self.slot,)).split(","))
- # ports don't need to be stored and are non-persistent. they need an active session.
- class InstrumentPort(object):
- """Instrument that is a module that fits into an InstrumentChassis."""
- MASTER = -1 # some instruments have "master" ports that control settings for all ports.
- # a -1 value here means "no master". zero or greater indicates
- # the port number of the master.
- def __init__(self, module, port):
- self._agent = module.get_agent()
- self.slot = module.slot
- self.port = int(port)
- self.name = "%s.port%s" % (module.name, port)
- self.initialize()
- def __str__(self):
- return self.name
- def __del__(self):
- self.finalize()
- def is_master(self):
- if self.MASTER >= 0:
- return self.port == self.MASTER
- else:
- return True
- def initialize(self):
- pass
- def finalize(self):
- pass
- def identify(self):
- raw = self._agent.ask(":SLOT%d:HEAD%d:IDN?" % (self.slot,self.port)).strip()
- if raw:
- return Identity(raw)
- raw = self._agent.ask(":SLOT%d:IDN?" % (self.slot,)).strip()
- if raw:
- return Identity(raw)
- else:
- return Identity()
- def options(self):
- return self._agent.ask(":SLOT%d:HEAD%d:OPT?" % (self.slot,self.port))
- # virtually plug a module into a chassis...
- def plug_module(chassis, module, slot):
- #print "Calling plug...chassis: %s, module:%s, slot:%s" % (chassis, module, slot)
- if chassis.slots.has_key(slot):
- raise InstrumentError, "There's something in slot %s already." % (slot,)
- chassis.slots[slot] = module
- module.chassis = chassis
- module.slot = slot
- # unplug whatever is in slot from chassis object.
- def unplug_module(chassis, slot):
- module = chassis.slots.get(slot)
- if module:
- module.slot = -1
- del module.chassis
- del chassis.slots[slot]
- # classes for generic VISA equipment objects follow.
-
- class DMM(Instrument): # works with 34401A at least
- "A generic DMM object."
- def read_voltage(self, ac=False, range=20, resolution=0.001):
- a = self.get_agent()
- a.write(':MEASure:VOLTAGE:%s? %s,%s' % (IF(ac, "AC", "DC"), range, resolution))
- val = float(a.read())
- return PhysicalQuantity(round(val, 3), "V") # XXX fix round value
- def read_current(self, ac=False, range=1, resolution=0.001):
- a = self.get_agent()
- a.write(':MEASure:CURRENT:%s? %s,%s' % (IF(ac, "AC", "DC"), range, resolution))
- val = float(a.read())
- return PhysicalQuantity(round(val, 3), "A")
- class RFSignalGenerator(Instrument):
- "A generic RF signal generator."
- class Oscilloscope(Instrument):
- "A generic oscilloscope."
- class FunctionGenerator(Instrument):
- "A generic function generator."
- def _apply(self, function, frequency=DEFAULT, amplitude=DEFAULT, offset=DEFAULT):
- a = self.get_agent()
- return a.write("APPL:%s %s, %s, %s" % (function, frequency, amplitude, offset))
- def sinusoid(self, frequency=DEFAULT, amplitude=DEFAULT, offset=DEFAULT):
- return self._apply("SIN", frequency, amplitude, offset)
- def square(self, frequency=DEFAULT, amplitude=DEFAULT, offset=DEFAULT):
- return self._apply("SQU", frequency, amplitude, offset)
- def triangle(self, frequency=DEFAULT, amplitude=DEFAULT, offset=DEFAULT):
- return self._apply("TRI", frequency, amplitude, offset)
- def ramp(self, frequency=DEFAULT, amplitude=DEFAULT, offset=DEFAULT):
- return self._apply("RAMP", frequency, amplitude, offset)
- def noise(self, amplitude=DEFAULT, offset=DEFAULT):
- return self._apply("NOIS", DEFAULT, amplitude, offset)
- def DC(self, offset):
- return self._apply("DC", DEFAULT, DEFAULT, offset)
- def user(self, frequency=DEFAULT, amplitude=DEFAULT, offset=DEFAULT):
- return self._apply("USER", frequency, amplitude, offset)
- def output_load(self, imp):
- """output_load <impedence>
- Sets the output impedence to 50 ohms if impedenace is 50, open-circuit otherwise."""
- a = self.get_agent()
- if int(imp) != 50:
- imp = "INF"
- return a.write("OUT:LOAD %s" % (imp, ))
-
- def query(self):
- """Query the function generator and return:
- wave function, frequency, amplitude, dc offset, and output impedence."""
- a = self.get_agent()
- val = a.ask("APPLy?")[1:-1]
- imp = a.ask("OUT:LOAD?")
- fr, amp, offset = val.split(",")
- func, freq = fr.split()
- return func, float(freq), float(amp), float(offset), float(imp)
- class DCPower(Instrument):
- "A geneeric DC power supply."
- class SpectrumAnalyzer(Instrument):
- "A generic spectrum analyzer."
- class OpticalSpectrumAnalyzer(Instrument):
- "A generic optical spectrum analyzer."
- class PowerMeter(Instrument):
- "A generic power meter."
- class OpticalSignalGenerator(Instrument):
- "A generic optical signal generator."
- def initialize(self, agent):
- self.unlock()
-
- def is_locked(self):
- "Return state of laser lock."
- val = self.get_agent().ask(":LOCK?")
- return Boolean(val)
- def lock(self, tf=True, passwd=None):
- "Lock or unlock the laser functioning."
- tf = Boolean(tf)
- pw = passwd or self.password
- self.get_agent().write(":LOCK %s,%s" % (tf, pw[:4]))
- def unlock(self, passwd=None):
- self.lock(False, passwd)
-
- class OpticalPowerAmp(Instrument):
- "A generic optical power amplifier."
-
- class OpticalPowerMeter(Instrument):
- "A generic optical power meter (SCPI commands)."
- def initialize(self, agent):
- agent.write(":UNIT:POW dBm")
- class OpticalHeadInterface(Instrument):
- "A generic optical head interface"
- def initialize(self, agent):
- agent.write(":UNIT:POW dBm")
- class OpticalSwitch(Instrument):
- """A generic optical switch """
- class OpticalAttenuator(Instrument):
- "A generic optical attenuator"
- def _get_attenuation(self):
- raw = self.get_agent().ask(":INP:ATT?")
- return PhysicalQuantity(SCPIFloat(raw), "dB")
- def _set_attenuation(self, atten):
- atten = get_quantity(atten, "dB")
- self.get_agent().write(":INP:ATT %.2f" % (atten,), wait=True)
- #self.get_agent().write(":INP:ATT %.2f" % (atten,), wait=True)
- def _no_attenuation(self):
- self.get_agent().write(":INP:ATT MIN", wait=True)
- attenuation = property(_get_attenuation, _set_attenuation, _no_attenuation, "attenuation factor (dB)")
- def _get_max(self):
- raw = self.get_agent().ask(":INP:ATT? MAX")
- return PhysicalQuantity(SCPIFloat(raw), "dB")
- maximum_attenuation = property(_get_max, None, None, "Maximum possible attenuation.")
- def _get_min(self):
- raw = self.get_agent().ask(":INP:ATT? MIN")
- return PhysicalQuantity(SCPIFloat(raw), "dB")
- minimum_attenuation = property(_get_min, None, None, "Minimum possible attenuation.")
- def _get_wavelength(self):
- raw = self.get_agent().ask(":INP:WAV?") # in meters
- return PhysicalQuantity(SCPIFloat(raw), "m").inUnitsOf("nm")
- def _set_wavelength(self, wl):
- wl = get_quantity(wl, "nm")
- self.get_agent().write(":INP:WAV %s NM" % (wl._value,), wait=True)
- wavelength = property(_get_wavelength, _set_wavelength, None, "wavelengh in nM")
- def _get_output(self):
- return Boolean(self.get_agent().ask(":OUTP:STAT?"))
- def _set_output(self, flag):
- flag = Boolean(flag)
- self.get_agent().write(":OUTP:STAT %s" % (flag,), wait=True)
- output = property(_get_output, _set_output, None, "state of output shutter")
- state = output # alias
- def on(self):
- self._set_output(ON)
- def off(self):
- self._set_output(OFF)
- class OpticalAttenuator_JDSU(Instrument):
- "A generic optical attenuator"
-
- def _get_attenuation(self):
- addr_params = "%s,%s,%s" % (self.chassis_addr, self.slot_addr, self.device_addr)
- cmd = ":OUTP:ATT? %s" % (addr_params)
- raw = self.get_agent().ask("%s" % cmd)
- return PhysicalQuantity(SCPIFloat(raw), "dB")
-
- def _set_attenuation(self, atten):
- atten = get_quantity(atten, "dB")
- addr_params = "%s,%s,%s" % (self.chassis_addr, self.slot_addr, self.device_addr)
- cmd = ":OUTP:ATT %s,%.2f" % (addr_params, atten)
- print "att cmd: %s" % cmd
- self.get_agent().write("%s" % (cmd, ),)
- time.sleep(1) # JSDU voa need a time delay after set_attenuation
- def _no_attenuation(self):
- addr_params = "%s,%s,%s" % (self.chassis_addr, self.slot_addr, self.device_addr)
- cmd = ":OUTP:ATT %s,%.2f" % (addr_params, 0.0)
- self.get_agent().write(cmd, wait=True)
- attenuation = property(_get_attenuation, _set_attenuation, _no_attenuation, "attenuation factor (dB)")
- def _get_wavelength(self):
- addr_params = "%s,%s,%s" % (self.chassis_addr, self.slot_addr, self.device_addr)
- raw = self.get_agent().ask(":OUTP:WAV? %s" % addr_params) # in meters
- return PhysicalQuantity(SCPIFloat(raw), "m").inUnitsOf("nm")
- def _set_wavelength(self, wl):
- addr_params = "%s,%s,%s" % (self.chassis_addr, self.slot_addr, self.device_addr)
- wl = get_quantity(wl, "nm")
- cmd = ":OUTP:WAV %s,%s" % (addr_params,wl._value)
- self.get_agent().write("%s" % (cmd,), wait=True)
- wavelength = property(_get_wavelength, _set_wavelength, None, "wavelengh in nM")
- def _get_output(self):
- addr_params = "%s,%s,%s" % (self.chassis_addr, self.slot_addr, self.device_addr)
- cmd = ":OUTP:BBLock? %s" % addr_params
- return Boolean(self.get_agent().ask(cmd))
- def _set_output(self, state):
- addr_params = "%s,%s,%s" % (self.chassis_addr, self.slot_addr, self.device_addr)
- if state=='ON':
- cmd = ":OUTP:BBLock %s,0" % (addr_params)
- else:
- cmd = ":OUTP:BBLock %s,1" % (addr_params)
- self.get_agent().write(cmd, wait=True)
- output = property(_get_output, _set_output, None, "state of output shutter")
- state = output # alias
- def on(self):
- self._set_output(ON)
- def off(self):
- self._set_output(OFF)
- # specific instruments
- class FIBERAMP(OpticalPowerAmp):
- "A PHOTONETICS FIBERAMP BT1400 (EDFA)."
- def initialize(self, agent):
- agent.write("*SRE=17") # use SRQ line
- agent.use_srq()
- def _get_value(self, cmd):
- a = self.get_agent()
- try:
- raw = a.ask(cmd)
- except visa_exceptions.VisaIOError, err:
- if err.error_code == vpp43.VI_ERROR_TMO and a.STB == 3: # invalid command
- raise GPIBInvalidCommand, "%s: %s" % (self.visa_resource, cmd)
- else:
- raise
- if raw == "disabled":
- raise InstrumentError, "device is disabled"
- name, val = raw.split("=",1)
- return name, float(val)
- def _write(self, cmd):
- a = self.get_agent()
- a.write(cmd)
- a.wait_for_srq()
- def _get_current(self):
- name, val = self._get_value("I?")
- return PhysicalQuantity(val, "mA")
- def _set_current(self, mA):
- if str(mA).upper().startswith("MAX"):
- name, mA = self._get_value("ILIMIT?")
- else:
- mA = float(get_quantity(mA, "mA"))
- self._write("I=%0.1f" % (mA,))
- current = property(_get_current, _set_current, None, "constant current mode, current in mA")
- def _get_ilimit(self):
- name, mA = self._get_value("ILIMIT?")
- return PhysicalQuantity(mA, "mA")
- max_current = property(_get_ilimit)
- def _get_power(self):
- name, val = self._get_value("P?")
- return PhysicalQuantity(val, "mW")
- def _set_power(self, p):
- p = get_quantity(p, "mW")
- self._write("P=%0.f" % (p._value,))
- power = property(_get_power, _set_power, None, "constant power mode, power in mW")
- def enable(self):
- "Enable output"
- self._write("ENABLE")
- def disable(self):
- "Disable output"
- self._write("DISABLE")
- def _get_state(self):
- raw = self.get_agent().ask("P?")
- if raw == "disabled":
- return Boolean(0)
- else:
- return Boolean(1)
- def _set_state(self, state):
- state = Boolean(state)
- if state:
- self.enable()
- else:
- self.disable()
- state = property(_get_state, _set_state, None, "operating state")
- output = state # alias
- def is_locked(self):
- "Return state of interlock."
- val = self.get_agent().ask("INTERLOCK?")
- return Boolean(val)
- locked = property(is_locked)
- def _get_APC(self):
- val = self.get_agent().ask("APC?")
- return Boolean(val)
- def _set_APC(self, mode):
- mode = Boolean(mode)
- if mode: # true = APC on
- self._write("APCON")
- else:
- self._write("APCOFF")
- def _del_APC(self): # deleting APC is same as setting it off
- self._write("APCOFF")
- constant_power = property(_get_APC, _set_APC, _del_APC, "constant power (APC) mode control")
- def _get_temp(self):
- val = self.get_agent().ask("ERRORT?")
- return Boolean(val)
- temperature_error = property(_get_temp, None, None, "true if there is a Temperature Error condition.")
- def _get_ID(self):
- a = self.get_agent()
- raw = a.ask("*IDN?")
- #print "raw %s" %(raw,)
- return raw
- ID = property(_get_ID, None, None, "Instrument identification")
- class KEOPSYSAMP(OpticalPowerAmp):
- "A KEOPSYSAMP 18dBm FIBER AMPLIFIER (Model: OI-BT-C-18-sd-B-GP-FA)"
- def initialize(self, agent):
- agent.write("REM") # set to remote mode
- #agent.use_srq()
- def _get_value(self, cmd):
- a = self.get_agent()
- try:
- raw = a.ask(cmd)
- except visa_exceptions.VisaIOError, err:
- if err.error_code == vpp43.VI_ERROR_TMO and a.STB == 3: # invalid command
- raise GPIBInvalidCommand, "%s: %s" % (self.visa_resource, cmd)
- else:
- raise
- if raw == "disabled":
- raise InstrumentError, "device is disabled"
- name, val = raw.split("=",1)
- return name, float(val)
- def _write(self, cmd):
- a = self.get_agent()
- a.write(cmd)
- #a.wait_for_srq()
- def _get_current(self):
- name, val = self._get_value("RA1")
- print "name %s, val %s" %(name, val)
- return PhysicalQuantity(((val/4095) * 2.50)*1000, "mA") #Real value = (nnnn * full sclae) / (4095)
- def _set_current(self, mA):
- mA = float(get_quantity(mA, "mA"))
- mA = mA * 4095 / 2500
- self._write("SA1:%04d" % (mA,)) #Nearest integer(nnnn) = (real value * 4095) / fullscale
- sleep(2)
- current = property(_get_current, _set_current, None, "constant current mode, current in mA")
- def _get_power(self):
- name, val = self._get_value("RA1")
- print "name %s, val %s" %(name, val)
- return PhysicalQuantity(((val/4095) * 22.0), "dBm") #Real value = (nnnn * full sclae) / (4095)
- def _set_power(self, dbm):
- dbm = float(get_quantity(dbm, "dBm"))
- dbm = dbm * 4095 / 22.0
- self._write("SA1:%d" % (dbm,)) #Nearest integer(nnnn) = (real value * 4095) / fullscale
- power = property(_get_power, _set_power, None, "constant output power mode, power in dBm")
- def _get_ID(self):
- a = self.get_agent()
- raw = a.ask("ID")
- #print "raw %s" %(raw,)
- return raw
- ID = property(_get_ID, None, None, "Instrument identification")
- def _get_temp(self):
- name, val = self._get_value("RA2")
- print "name %s, val %s" %(name, val)
- return val
- temperature = property(_get_temp, None, None, "constant current mode, current in mA")
-
- def enable(self):
- "Enable output"
- self._write("K1")
- def disable(self):
- "Disable output"
- self._write("K0")
- def _set_state(self, state):
- state = Boolean(state)
- if state:
- self.enable()
- else:
- self.disable()
- state = property(_set_state, None, "operating state")
- output = state # alias
- def set_localmode(self):
- "Set to local mode"
- self._write("GTL")
- class MAP(InstrumentChassis):
- SLOTBASE = 1
-
- class HP8163A(InstrumentChassis):
- "A HEWLETT-PACKARD HP8163A optical measurement chassis"
- SLOTBASE = 1
- class HP8163B(InstrumentChassis):
- "A HP8163B just inherits HP8163A"
- SLOTBASE = 1
- class HP81635A(InstrumentModule, OpticalPowerMeter):
- "A HEWLETT-PACKARD HP81635A optical power module"
- PORTBASE = 1
- def get_port(self, port):
- return self._get_port(HP81635APort, port)
- class HP81635APort(InstrumentPort):
- """HP81635A dual power meter for HP8163A chassis"""
- MASTER = 1
- def initialize(self):
- self._currentunit = self._get_unit()
- if self._currentunit is None:
- raise InstrumentError, "could not initialize HP81635APort"
- def _set_unit(self, unit):
- assert unit in ("dBm", "DBM", "Watts", "W")
- self._agent.write(':SENSE%d:CHAN%d:POW:UNIT %s' % (self.slot, self.port, unit) )
- self._currentunit = self._get_unit()
- def _get_unit(self):
- val = int(self._agent.ask(':SENSE%d:CHAN%d:POW:UNIT?' % (self.slot, self.port) ))
- if val == 0:
- return "dBm"
- elif val == 1:
- return "W"
- unit = property(_get_unit, _set_unit, None, "Measurement unit: dBm or Watts")
- def _set_wavelength(self, wl):
- wl = get_quantity(wl, "m")
- self._agent.write(':SENSE%d:CHAN%d:POW:WAV %sM' % (self.slot,self.port, wl._value) )
- def _get_wavelength(self):
- val = self._agent.ask(':SENSE%d:CHAN%d:POW:WAV?' % (self.slot,self.port) )
- return PhysicalQuantity(SCPIFloat(val), "m")
- wavelength = property(_get_wavelength, _set_wavelength, None, "Wavelength in M")
- def _set_averaging(self, tm):
- tm = get_quantity(tm, "s")
- if self.is_master():
- self._agent.write(':SENSE%d:CHAN%d:POW:ATIM %sS' % (self.slot, self.port, tm._value))
- else:
- raise InstrumentError, "invalid operation on non-master port"
- def _get_averaging(self):
- val = self._agent.ask(':SENSE%d:CHAN%d:POW:ATIM?' % (self.slot,self.port))
- return PhysicalQuantity(SCPIFloat(val), "s")
- averaging_time = property(_get_averaging, _set_averaging, None, "Averaging time in S")
- def _set_continuous(self, state):
- if self.is_master():
- state = Boolean(state)
- self._agent.write(':INIT%d:CHAN%d:CONT %s' % (self.slot,self.port,state) )
- else:
- raise InstrumentError, "invalid operation on non-master port"
- def _get_continuous(self):
- return Boolean(self._agent.ask(':INIT%d:CHAN%d:CONT?' % (self.slot,self.port)))
- continuous = property(_get_continuous, _set_continuous, None, "continuous measurement mode?")
- def _get_power(self):
- val = self._agent.ask(':FETCH%d:CHAN%d:SCAL:POW?' % (self.slot,self.port) )
- return PhysicalQuantity(SCPIFloat(val), self._currentunit)
- power = property(_get_power, None, None, "Power in current units.")
- class HP81619A(InstrumentModule, OpticalHeadInterface):
- "A HEWLETT-PACKARD HP81635A optical power module"
- PORTBASE = 1
- def get_port(self, port):
- return self._get_port(HP81619APort, port)
-
- class HP81619APort(HP81635APort):
- "Same as a HP81635APort"
- pass
- class HP81633A(HP81635A):
- "Same as a HP81635A, except with only one port"
- pass
- class HP81633APort(HP81635APort):
- "Same as a HP81635APort"
- pass
- class HP81570A(InstrumentModule, OpticalAttenuator):
- "A HEWLETT-PACKARD HP81635A optical power module"
- PORTBASE = 1
- def get_port(self, port):
- return self._get_port(HP81570APort, port)
- class HP81570APort(HP81635APort):
- "Same as a HP81635APort"
- pass
- class HP81576A(InstrumentModule, OpticalAttenuator, OpticalPowerMeter):
- "A HEWLETT-PACKARD HP81635A optical power module"
- PORTBASE = 1
- def get_port(self, port):
- return self._get_port(HP81635APort, port)
- def _get_power(self):
- self._agent = self.get_agent()
- val = self._agent.ask(':FETCH%d:SCAL:POW?' % (self.slot,))
- #val = self._agent.ask(':FETCH%d:CHAN%d:SCAL:POW?' % (self.slot,self.port))
- return PhysicalQuantity(SCPIFloat(val), self._currentunit)
- power = property(_get_power, None, None, "Power in current units.")
-
- class HP81576APort(HP81635APort):
- "Same as a HP81635APort"
- pass
- class IA3(InstrumentModule, OpticalAttenuator_JDSU):
- _ATTRS = Instrument._ATTRS.copy()
- _ATTRS.update({
- "chassis_addr" : (str, "1"),
- "slot_addr" : (str, "1"),
- "device_addr" : (str, "1"), # slot maps to list index
- })
- pass
- class IA3Port(InstrumentPort):
- pass
- class OA(IA3):
- pass
- class OAPort(InstrumentPort):
- pass
-
- class HP81663A(InstrumentModule, OpticalSignalGenerator):
- "A HEWLETT-PACKARD HP81663A optical source"
- PORTBASE = 1
- def initialize(self, agent):
- self.unlock()
-
- def get_port(self, port=0):
- return self._get_port(HP81663APort, port)
- def _get_wavelength(self):
- from instrumentdata.HP81663A import HP81663_opt2wl
- modopt = self.options()[1]
- return PhysicalQuantity(HP81663_opt2wl[modopt], "nm")
- wavelength = property(_get_wavelength, None, None, "modules wavelength option")
- class HP81662A(HP81663A):
- pass
- class HP81591A(InstrumentModule, OpticalSwitch):# xxx:change type later
- """ Agilent HP 8159A 780 to 1350nm 2x1 Optical Switch """
- PORTBASE = 1
- def get_port(self, port=0):
- return self._get_port(HP8159xPort, port)
- class HP81591APort(InstrumentPort):
- """HP81591A/HP81591B dual power meter for HP8163A chassis"""
- MASTER = 1
- # signal routing functionalities
- def _get_switch_conf(self):
- """
- Queries the switch configuration of the instrument
- """
- # a = self._agent
- a = self.get_agent()
- cmd = ':ROUT%d:CHAN%d:CONF?' % (self.slot, 1)
- print "cmd: %s" % cmd
- val = a.ask(cmd)
- print "val: %s" % val
- return val
- def _get_switch_route(self, chan=1):
- """
- Queries the switch configuration of the instrument
- """
- a = self.get_agent()
- cmd = ':ROUT%d:CHAN%d:CONF:ROUT?' % (self.slot, chan)
- print "cmd: %s" % cmd
- val = a.ask(cmd)
- return val
- def _get_route_chan(self, m=1):
- """
- Queries the current channel route of the switch for a specific module
- and switch channel.
- n: the slot number of the switch module
- m: the switch channel within the selected switch module, default is 1
- """
- #a = self._agent
- a = self.get_agent()
- cmd = ':ROUT%d:CHAN%d?' % (self.slot, m)
- print "cmd: %s" % cmd
- #self.info("xxx", 1)
- val = a.ask(cmd)
- return val
- def _set_route_chan(self, chan='A', m=2):
- """
- Sets the channel route between two ports.
- format:
- :ROUTe[n]:[CHANnel[m]]<wsp><channel_list>
-
- n: the slot number of the switch module
- m: the switch channel within the selected switch module.
- e.g. for dual 1 x 2 module m = 1 for switch 1; m = 2 for switch 2
- the route between left and right ports.
- channel_list format: [A....Z],[1....n]
- """
- a = self.get_agent()
- chan_map = {1: 2, 2: 1}
-
- cmd = ':ROUT%d:CHAN%d %s,%d' % (self.slot, chan_map[m], chan, m)
- #print "cmd: %s" % cmd
- val = a.ask(cmd)
- return val
- def do_ask(self, cmd):
- a = self._agent
- #a = self.get_agent()
- #print "cmd: %s" % cmd
- val = a.ask(cmd)
- return val
- def do_write(self, cmd):
- a = self._agent
- #print "cmd: %s" % cmd
- val = a.write(cmd)
- #print "val: %s" % val
- return val
- def set_default_switch(self, chn=1):
- cmd = ":ROUT%d:CHAN%d A,%d" % (chn, chn, chn)
- return self.do_write(cmd)
- def set_switch_for_tx(self):
- cmd = ":ROUT1:CHAN1 A,2"
- return self.do_write(cmd)
-
- def get_route_config(self, chn=1):
- cmd = ":ROUT%d:CONF:rout?" % chn
- return self.do_ask(cmd)
- def get_port(self, port=0):
- return self._get_port(HP8159xPort, port)
- class HP81591B(InstrumentModule, OpticalSwitch):# xxx:change type later
- """ Agilent HP 8159A 780 to 1350nm 2x1 Optical Switch """
- PORTBASE = 1
- def get_port(self, port=0):
- return self._get_port(HP81591BPort, port)
- class HP81591BPort(InstrumentPort):
- """HP81591A/HP81591B dual power meter for HP8163A chassis"""
- MASTER = 1
- # signal routing functionalities
- def _get_switch_conf(self):
- """
- Queries the switch configuration of the instrument
- """
- a = self._agent
- # a = self.get_agent()
- cmd = ':ROUT%d:CHAN%d:CONF?' % (self.slot, 1)
- print "cmd: %s" % cmd
- val = a.ask(cmd)
- print "val: %s" % val
- return val
- def _get_switch_route(self, chan=1):
- """
- Queries the switch configuration of the instrument
- """
- a = self.get_agent()
- cmd = ':ROUT%d:CHAN%d:CONF:ROUT?' % (self.slot, chan)
- print "cmd: %s" % cmd
- val = a.ask(cmd)
- return val
- def _get_route_chan(self, m=1):
- """
- Queries the current channel route of the switch for a specific module
- and switch channel.
- n: the slot number of the switch module
- m: the switch channel within the selected switch module, default is 1
- """
- a = self._agent
- #a = self.get_agent()
- cmd = ':ROUT%d:CHAN%d?' % (self.slot, m)
- print "cmd: %s" % cmd
- #self.info("xxx", 1)
- val = a.ask(cmd)
- return val
- def _set_route_chan(self, chan='A', m=2):
- """
- Sets the channel route between two ports.
- format:
- :ROUTe[n]:[CHANnel[m]]<wsp><channel_list>
-
- n: the slot number of the switch module
- m: the switch channel within the selected switch module.
- e.g. for dual 1 x 2 module m = 1 for switch 1; m = 2 for switch 2
- the route between left and right ports.
- channel_list format: [A....Z],[1....n]
- """
- a = self.get_agent()
- chan_map = {1: 2, 2: 1}
-
- cmd = ':ROUT%d:CHAN%d %s,%d' % (self.slot, chan_map[m], chan, m)
- #print "cmd: %s" % cmd
- val = a.ask(cmd)
- return val
- def do_ask(self, cmd):
- a = self._agent
- #a = self.get_agent()
- #print "cmd: %s" % cmd
- val = a.ask(cmd)
- return val
- def do_write(self, cmd):
- a = self._agent
- #print "cmd: %s" % cmd
- val = a.write(cmd)
- #print "val: %s" % val
- return val
- def set_default_switch(self, chn=1):
- cmd = ":ROUT%d:CHAN%d A,%d" % (chn, chn, chn)
- return self.do_write(cmd)
- def set_switch_for_tx(self):
- cmd = ":ROUT1:CHAN1 A,2"
- return self.do_write(cmd)
-
- def get_route_config(self, chn=1):
- cmd = ":ROUT%d:CONF:rout?" % chn
- return self.do_ask(cmd)
- def get_port(self, port=0):
- return self._get_port(HP8159xPort, port)
- #class HP81591B(HP81591A):
- # pass
-
- c…