Bei Ihr altes Netzteil smartphone-kontrollierbar machen haben wir einem alten Netzteil neues Leben eingehaucht, indem wir ihm IoT-Fähigkeiten verliehen haben. In diesem Artikel werden wir uns eine effizientere Methode anschauen, um all Ihren Laborgeräten IoT-Fähigkeiten zu verleihen (speziell solchen, die über VISA gesteuert werden). Anstatt alles von Grund auf neu zu bauen, werden wir Generative KI nutzen, um den größten Teil der Arbeit zu erledigen. Nachdem Sie dieses Tutorial durchgearbeitet haben, sollten Sie in der Lage sein, diese Konzepte zu übernehmen, um webfähige Treiber für all Ihre Laborgeräte zu erstellen und Ihre gesamte Entwicklung ebenfalls zu beschleunigen.
In diesem Artikel konzentrieren wir uns darauf, den Webdienst zusammenzustellen, der als Vermittler zwischen dem Instrument selbst und dem Internet dient. Folgend ist eine Illustration der End-to-End-Verbindung zwischen dem Instrument und dem Internet dargestellt (d.h. Zugriff über eine Webseite).
Abbildung 1: End-to-End-Kommunikation zwischen dem Instrument und dem Internet
Bevor wir das tun, ist es wichtig festzustellen, dass es nicht unbedingt notwendig ist, alle Instrumententreiber selbst zu schreiben. Wir können das nutzen, was bereits online von den Herstellern gemacht wurde, oder wir können auf Open-Source-Repositories zurückgreifen. Um der Kürze willen werde ich das nutzen, was ich bereits online gefunden habe, aber generative KI verwenden, um ein Framework zusammenzustellen, mit dem ich zufrieden bin.
Ich verwende das DP832-Netzteil und die DL3021-Elektroniklast von Rigol. Nach einer schnellen Suche auf GitHub fand ich Python-Bibliotheken für das DP832-Netzteil, die alle notwendigen SCPI-Befehle enthalten, um zu beginnen. Ein alternativer Ansatz wäre, eine Liste von SCPI-Befehlen aus dem DP832-Handbuch zu nehmen, sie einem großen Sprachmodell (LLM), zum Beispiel ChatGPT oder Gemini, zu übergeben und es die Funktionen für mich generieren zu lassen. Ich bin ein wenig wählerisch, also werde ich meinen eigenen PyVISA-Einrichtungsprozess definieren und dann das meiste nutzen, was bereits gemacht wurde. Hier ist mein generischer PyVISA-Einrichtungsprozess (in einer separaten Klasse gekapselt):
class CommBase:
USBConnType = Literal["USBTMC", "VISA", "Socket"]
def __init__(self, usb_conn_type: USBConnType, vid: int = None, pid: int = None, visa_resource_prefix: str = None):
self.visa_resource_prefix = visa_resource_prefix
self.usb_conn_type = usb_conn_type
wenn usb_conn_type == "USBTMC":
self.configure_usbtmc(vid, pid)
elif usb_conn_type == "VISA":
self.configure_visa(vid, pid)
elif usb_conn_type == "Socket":
pass
else:
raise ValueError(f"Ungültiger USB-Verbindungstyp: {usb_conn_type}. Gültige Typen sind {self.VALID_USB_CONN_TYPES}")
def configure_usbtmc(self, vid: int, pid: int):
self.inst = usbtmc.Instrument(vid, pid)
def configure_visa(self, vid: int, pid: int):
self.rm = pyvisa.ResourceManager()
instrument_list = self.rm.list_resources()
visa_address = self.find_visa_resource(vid, pid, instrument_list, prefix=self.visa_resource_prefix)
wenn visa_address nicht None ist:
self.inst = self.rm.open_resource(visa_address, read_termination="\n")
sonst:
raise IOError(f'Keine VISA-Geräte gefunden mit vid "{vid}" und pid "{pid}", aber die folgenden VISA-Geräte wurden gefunden: {instrument_list}')
@staticmethod
def find_visa_resource(vid: int, pid: int, resource_strings: list, prefix: str) -> str:
hex_vid, hex_pid = f"0x{vid:X}", f"0x{pid:X}"
dec_vid, dec_pid = str(vid), str(pid)
for resource in resource_strings:
parts = resource.split("::")
wenn die Länge von parts >= 4 ist:
serial_and_more = parts[3]
wenn (any(x in resource for x in (hex_vid, dec_vid)) und any(x in resource for x in (hex_pid, dec_pid)) und serial_and_more.startswith(prefix)):
return resource
return None
def query_device(self, command: str) -> str:
wenn self.usb_conn_type == "USBTMC":
return self.inst.ask(command)
elif self.usb_conn_type == "VISA":
return self.inst.query(command)
else:
raise NotImplementedError(f"Abfragemethode für {self.usb_conn_type} nicht gefunden.")
def write_device(self, command: str):
self.inst.write(command)
def close(self):
self.inst.close()
if self.usb_conn_type == "VISA":
self.rm.close()
def id(self) -> dict:
id_str = self.query_device("*IDN?").strip().split(",")
return {
"Hersteller": id_str[0],
"Modell": id_str[1],
"Seriennummer": id_str[2],
"Version": id_str[3],
}
Ich habe alle Kommentare, zusätzlichen Leerzeichen und sogar einige Einrichtungssequenzen (wie Logging) zur Kürze entfernt. Wie Sie sehen können, habe ich einige generische Funktionen sowie Unterstützung für PyVISA und USBTMC. Die meisten auf SCPI basierenden Python-Bibliotheken, die Sie online finden, werden diese grundlegende Funktionalität nicht haben. Das ist in Ordnung, denn ich kann diese Klasse in meine neue Klasse erweitern:
from base.CommBase import CommBase
class DP(CommBase):
def channel_check(self, channel):
assert NotImplementedError
def get_output_mode(self, channel: int) -> str:
self.channel_check(channel)
return self.query_device(f":OUTP:MODE? CH{channel}").strip()
# … Code wurde der Kürze halber entfernt
def measure_current(self, channel):
self.channel_check(channel)
meas = self.query_device(f":MEAS:CURR? CH{channel}").strip()
return float(meas)
def measure_voltage(self, channel):
self.channel_check(channel)
meas = self.query_device(f":MEAS? CH{channel}").strip()
return float(meas)
def measure_all(self, channel):
self.channel_check(channel)
meas = self.query_device(f":MEAS:ALL? CH{channel}").strip().split(",")
return {
"voltage": float(meas[0]),
"strom": float(meas[1]),
"leistung": float(meas[2]),
}
class DP712(DP):
def channel_check(self, channel):
assert channel in [1, ""], f"Ausgabekanal {channel} wird nicht unterstützt"
class DP821(DP):
def channel_check(self, channel):
assert channel in [1, 2, ""], f"Ausgabekanal {channel} wird nicht unterstützt"
class DP832(DP):
def channel_check(self, channel):
assert channel in [1, 2, 3, ""], f"Ausgabekanal {channel} wird nicht unterstützt"
Ich habe einige verschiedene Beispiele online genommen und sie in ChatGPT eingegeben. Ich habe es aufgefordert:
Die Nutzung von generativer KI für diese Aufgabe hat eine mehrstündige Arbeit auf 60 Sekunden reduziert. Außerdem konnte ich sehr schnell die Treiber, die ich online gefunden habe, durch die automatisch generierten Tests, die ChatGPT für mich geschrieben hat, validieren. Zum Beispiel entdeckte ich sehr schnell, dass eines der SCPI-Kommandos für den DL3021, um den Betriebsmodus der elektronischen Last einzustellen, tatsächlich falsch war. Beim Beobachten der Tests in Echtzeit bemerkte ich, dass sich der Modus an meinem Instrument nicht änderte. Ein schneller Blick in das SCPI-Handbuch und ich konnte es korrigieren.
An diesem Punkt haben wir eine gute Grundlage für unsere Python-Bibliothek, um unsere Instrumente zu steuern. Das Ziel ist jetzt, einen Webdienst vor die Instrumentenbibliothek zu stellen, der es uns ermöglicht, sie über das Web zu steuern. Angenommen, ich weiß nichts über Web-Frameworks, kann ich einfach ChatGPT (oder jedes andere LLM) bitten, die gesamte Funktion für mich auszuführen. Hier ist der Prompt, den ich verwendet habe, um loszulegen:
Ich muss einen Webdienst erstellen, der mein Instrument über einfache URLs (über einen Webbrowser) steuert. Ich weiß nicht viel über Webdienste oder Frameworks, aber ich kenne mich mit Python aus. Schreiben Sie den vollständigen Python-Code, um diese Aufgabe zu erfüllen.
Hier ist die Klasse, die mein Instrument steuert:
```
{obiger Code}
```
Und die (teilweise Antwort):
Abbildung 2: Antwort vom ChatGPT-Prompt
Mein Lieblingsteil an den ausgefeilten (bezahlten) LLMs ist, dass sie die Aufgabe wirklich aufschlüsseln, dich bilden und eine ziemlich schöne Lösung als ersten Durchlauf bieten. In Gemini vs. ChatGPT: Wer schreibt besseren Code? habe ich die beiden LLMs gegeneinander antreten lassen und (Spoiler-Alarm) herausgefunden, dass die neueste, fortschrittlichste Version von Googles Gemini tatsächlich ziemlich gut war (wenn nicht sogar auf Augenhöhe mit ChatGPT 4). Die Verwendung eines dieser LLMs wird ein ähnliches Ergebnis wie das oben gezeigte liefern.
Wenn ich dies in eine Klasse einfügen oder umformatieren möchte, kann ich einfach auf den Chat antworten und meine Anfrage stellen. Möchtest du, dass dein Code kommentiert wird? Kein Problem, frag einfach nach!
Aufforderung: Füge jedem Funktionen Dokumentationskommentarblöcke im Stil von Docstrings hinzu. Schreibe die gesamte Klasse als Ergebnis um, sodass ich sie zurück in meinen Code-Editor kopieren und einfügen kann.
Abbildung 3: Nächste Antwort auf die ChatGPT-Aufforderung
Testen
Nachdem wir Generative KI das Python-Modul erstellen ließen, können wir entweder darum bitten, dass es Tests für uns schreibt oder uns zeigen, wie wir manuell testen:
Abbildung 4: URL für manuellen Test von ChatGPT
Abbildung 5: Automatisierter Test, geschrieben von ChatGPT
Nachdem wir diese Tests durchgeführt (oder angepasst und dann durchgeführt) haben, sollten wir in der Lage sein, unser neues Python-Modul zu validieren, das zwischen dem Web und unserem Instrument vermittelt.
Schlussfolgerung
In diesem Artikel haben wir ein Python-Modul zusammengestellt, das unser Instrument unter Nutzung vorhandener Codes im Web und Generativer KI steuerte. Nachdem unser LLM das Modul fertiggestellt hatte, führten wir ein neues Modul ein, das als Vermittler zwischen dem Internet und dem Instrument selbst fungierte (über einen Webdienst). Wir haben auch kurz betrachtet, wie Generative KI uns durch den gesamten Prozess führen kann, einschließlich manueller oder automatisierter Tests. Das Beste an dieser Übung ist, dass sie, wenn richtig durchgeführt, sehr wenig Zeit in Anspruch nehmen sollte. Das erste Mal könnte etwas mehr Aufwand erfordern, aber diesen Prozess für viele Instrumente zu wiederholen, sollte ein Kinderspiel sein (und sehr wenig Entwicklungszeit in Anspruch nehmen). Es ist klar, dass Generative KI die Landschaft für uns alle vollständig verändert hat, und dieser Artikel demonstriert das wirklich. Hoffentlich werden Sie inspiriert, die nächste Reihe von Instrumentenbibliotheken unter Nutzung Generativer KI zu erstellen und sie der restlichen Gemeinschaft zurückzugeben.
Der gesamte in diesem Projekt verwendete Quellcode ist zu finden unter: https://gitlab.com/ai-examples/instrument-controllables.