from typing import Optional class KeithleySCPI: ### private ##################################################################### # _fm ... function_mode def _fm(unit: Optional[str], function: str) -> dict: return {'unit': unit, 'function': function} _modes: dict[str, dict[Optional[str], str]] = { "DCV": _fm("V", "VOLTage:DC"), "DCI": _fm("A", "CURRent:DC"), "ACV": _fm("V", "VOLTage:AC"), "ACI": _fm("A", "CURRent:AC"), "2W": _fm("Ω", "RESistance"), "4W": _fm("Ω", "FRESistance"), "Freq": _fm("Hz", "FREQuency"), "Period": _fm(None, "PERiod"), "Diode": _fm("V", "DIODe"), "Temp": _fm("°C", "TEMPerature"), "Cap": _fm("F", "CAPacitance"), "Digi V": _fm("V", "VOLTage"), "Digi I": _fm("A", "CURRent") } ################################################################################# # _fs ... function syntax def _fs(syntax: Optional[str]) -> dict: return {'syntax': syntax} # erweiterbare Funktionsliste, mittels Namen wird der hinterlegte SCPI Syntax ausgelesen _syntaxTable: dict[str, dict[Optional[str]]] = { "getTime": _fs(":SYSTem:TIME? 1"), # Reference Manual Seite 12-158 "setTime": _fs(":SYSTem:TIME "), # Reference Manual Seite 12-158 "setFunctionON": _fs(':SENSe:FUNCtion:ON "MESSMODE"'), "setDigitizeFunctionON": _fs(':SENSe:DIGItize:FUNCtion:ON "MESSMODE"'), "measure": _fs(":MEASure:MESSMODE?"), # Reference Manual Seite 12-137 "setMeasureCounts": _fs(":SENSe:COUNt "), # Reference Manual Seite 12-134 "setMeasureDigitizeCounts": _fs(":SENSe:DIGItize:COUNt "), # Reference Manual Seite 12-135 "setSampleRateDigitize": _fs(":SENSe:MESSMODE:SRATe "), # Reference Manual Seite 12-118 "read": _fs(":READ?"), # Reference Manual Seite 12-10 "lastBufferWriteIndex": _fs(":TRACe:ACTual:END?"), # Reference Manual Seite 12-160 "readBuffer": _fs(":TRACe:DATA?"), # Reference Manual Seite 12-165 "averageCount": _fs(":SENSE:MESSMODE:AVERage:COUNt "), "averageRepeat": _fs(":SENSE:MESSMODE:AVERage:TCONTrol REPeat"), "averageMoving": _fs(":SENSE:MESSMODE:AVERage:TCONTrol MOVing"), "averageHybrid": _fs(":SENSE:MESSMODE:AVERage:TCONTrol HYBRid"), "averageON": _fs(":SENSE:MESSMODE:AVERage ON"), "averageOFF": _fs(":SENSE:MESSMODE:AVERage OFF"), "deleteBuffer": _fs(":TRACe:CLEar"), # Reference Manual Seite 12-164 "localMode": _fs(":TRIGger:CONTinuous RESTart"), "None": _fs("None") } ################################################################################# # Konstruktor def __init__(self, model): self._deviceName: str = model self._unit: str = None self._function: str = None self._syntax:str = [] # Kopie von '_syntaxTable' def _updateTable (self, identifier: str): # Kopie erstellen und Platzhalter ersetzen self._syntax = { key: {"syntax": val["syntax"].replace("MESSMODE", identifier)} for key, val in self._syntaxTable.items() } ### public #################################################################### def setFunction(self, measure: str) -> str: try: mode = self._modes[measure] self._unit = mode["unit"] self._function = mode["function"] self._updateTable(self._function) return f'function found → {measure}' except KeyError: self._unit = None self._function = None return f'function unknown → {measure}' def scpiCommandSyntax (self, name: str) -> str: # "averageON" → ":SENSE:MESSMODE:AVERage ON" try: syntax = self._syntax[name]["syntax"] return syntax except KeyError: return f'command unknown → {name}' @property # Getter - Aufruf ohne () def function(self) -> str: return self._function @property # Getter - Aufruf ohne () def unit(self) -> str: return self._unit ### für Debug #### def modifiedTable (self): maxLength = max(len(key) for key in self._syntax) for t, s in self._syntax.items(): print(f"{t:<{maxLength}} → {s['syntax']}") ################################################################ k = KeithleySCPI("Keithley DMM6500") print(k.setFunction("2W")) print(k.function) print(k.unit) print(k.scpiCommandSyntax("measure")) print(k.setFunction("Tzemp")) print(k.function) print(k.unit) print(k.scpiCommandSyntax("measure")) print(k.scpiCommandSyntax("averageO"))