Sprachassistent Amazon Alexa + CODESYS Anwendung
Sprachassistent Amazon Alexa ist einer der neuen persönlichen Assistenten, die großartiges für die Zukunft versprechen. Mit dieser neuen Technologie konnten Amazon, Google und Apple im Handumdrehen unsere Wohnzimmer erobern. Ich möchte euch hier nun meine Vision der Sprachassistenten für die digitale Fabrik der Zukunft zeigen. Was wäre, wenn die Mitarbeiter in der Produktion auf die Unterstützung eines digitalen Assistenten zurückgreifen könnten? Es könnten Arbeitsanweisungen leichter bereitgestellt werden, ein Support-Mitarbeiter könnte sich über die Sprachfunktion von Amazon Alexa direkt mit dem Kollegen in der Produktion vernetzten, die nächsten Produktionsziele könnten kommuniziert und durch die Interaktion mit unterstützenden Roboter können schwere Arbeitsschritte per Zuruf gestartet werden.
Ich möchte im Folgenden, einen Überblick bieten, wie ich meinen Skill für den Sprachassistenten Amazon Alexa mit CODESYS verbinde. So stelle ich mir einen Teil der Zusammenarbeit, in der Montage der Zukunft, vor. Wobei die CODESYS Soft-SPS hier natürlich nur das Interface darstellt und keine Produktionsanlage. Aber der Fantasie sind keine Grenzen gesetzt.
Voraussetzungen
Damit Ihr einen Alexa Skill erstellen könnt sind einige Voraussetzungen zu erfüllen. Zunächst braucht Ihr natürlich eine Amazon Alexa fähiges Endgerät. Hier bietet Amazon mehrere Sprachassistenten aus der Amazon Echo Serie. Alternativ könnt Ihr auch die Alexa App auf eurem Smartphone installieren.
Ich empfehle euch jedoch einen Lautsprecher der Echo Reihe einzusetzen. Dieser kann euch sogar von der anderen Seite des Raumes, oder in sehr lauten Umgebungen, ohne Probleme hören und auf eure Stimmkommandos reagieren.
Als nächstes benötigt Ihr einen Amazon Developer Account. Diesen könnt Ihr Kostenlos unter developer.amazon.com erstellen. Damit habt Ihr dann Zugriff auf die Entwicklerkonsole von Amazon. Hier findet Ihr dann den Bereich für die Alexa Skill Entwicklung. Übrigens muss dieser Account auch mit eurem Alexa Lautsprecher verbunden sein.
Architektur und Vernetzung
Der Aufbau hochwertiger Alexa-Kenntnisse für Amazon Echo Devices erfordert einiges an Einarbeitung und kostet entsprechend viel Zeit. Aus diesem Grunde nutze ich Flask-Ask. Dieses Alexa Skill Kit, auf Basis des Python Microframeworks Flask, macht es sehr einfach einen Alexa Skill zu erstellen. Für unser einfaches Beispiel nutze ich ebenfalls ngrok um das Deployment zu vereinfachen. Damit sind wir um nuh fertig und können dank des Skills unsere Arbeit schnell erledigen.
Das sind aber nur einige der Bausteine, die wir für dieses Beispiel nutzen werden. So werden wir einen Flask-Webserver für das Hosting nutzen und mithilfe von OPC-UA die Befehle von der Flask Anwendung an unsere CODESYS Steuerung übertragen.
Das nachfolgende Schema beschreibt die Architektur und Vernetzung der einzelnen Software Komponenten bis hin zu meiner CODESYS Soft-SPS oder z.B. einem RaspberryPi.
Zuerst wird ein Sprachkommando an den Amazon Voice Services (AVS) gesendet, wo der gewünschte Alexa-Skill ausgewählt und dann gestartet wird. Wenn zum Beispiel eine bestimmte Aktion genannt wurde, wird diese, zusammen mit potenziell bereitgestellten Variablen, an die ausgewählte Alexa Skill-Implementierung gesendet. Wurde keine Aktion angegeben, z.B. das Öffnen der Anwendung, wird die grundlegende Funktion aufgerufen.
Als nächstes wird, basierend auf der angegebenen Aktion, eine bestimmte Methode im eingesetzten Flask-Ask-Server aufgerufen. Diese Methode wird z.B. ein bestimmtes Kommando auf Basis der angegebenen Variablen an die SPS senden und eine entsprechende Antwort formulieren. Diese Antwort wird dann über das AVS an das Amazon Echo-Gerät zurückgesendet.
CODESYS Anwendung bereitstellen und Zugriffsvariable definieren
Die CODESYS Anwendung für dieses Beispiel wird hier relativ einfach sein. Ich möchte hier kein komlexes Programm generieren, das z.B. einen Roboter steuert. Aus diesem Grund wir das Programm nur einige Interface Variablen bereitstellen die über die oben erwähnte OPC-UA Schnittstelle gesteuert werden können. Hier sind der Fantasie natürlich keine Grenzen gesetzt. Ihr könnt diese Leitstelle natürlich so gestalten, dass Ihr eine Vielzahl von Produktionsanlagen über eine zentrale CODESYS Instanz steuern könnt. Allerdings muss es in diesem Falle nicht ausschließlich CODESYS sein. Ihr könnt natürlich aus dem Flask-Webserver per OPC-UA jegliche andere Client-Server Architektur ansprechen, oder gänzlich auf CODESYS verzichten.
Variablen hinzufügen
Für mein Beispiel nutze ich einige einfache Variablen um die grundlegende Funktionsweise zu demonstrieren. Hierzu habe ich eine Globale Variablenliste in meinem CODESYS Projekt angelt, die über OPC UA bereitgestellt werden sollen.
Wähle ⇒
Deklariert anschließend nun in dieser GVL folgende Variablen:
VAR_GLOBAL bStartJob:BOOL:=FALSE; uiProductionCode:INT:=0; uiNumberOfScrews:INT:=0; END_VAR
Als nächstes müssen wir in CODESYS die OPC UA-Funktionalität und die Bereitstellung der Variablen aktivieren.
Wähle ⇒Im nachfolgenden Dialog (Symbolkonfiguration hinzufügen) müssen wir nun die OPC UA-Funktionalität aktivieren. Hierzu müsst Ihr einfach die passende Checkbox anklicken
HinzufügenIm Editor für die Symbolkonfiguration seht Ihr zunächst einmal… NICHTS. Bevor Ihr die Variablen für OPC UA freigeben könnt, müsst Ihr (wie im eingeblendeten Hinweis) einmal das Projekt erstellen (siehe blaue Markierung).
Anschließen könnt Ihr, wie im abgebildeten Dialog, einige Variablen selektieren und über die OPC UA-Server Funktionalität bereitstellen. Über einen Klick auf die Icons in der Spalte – Zugriffsrechte könnt Ihr einstellen ob die Variable nur gelesen werden kann, oder ob Lese- und Schreibzugriff erlaubt ist.
ANMERKUNG: Vermutlich werden die Variablen nicht mit der GVL in der Liste auftauchen. Hier werden nur Variablen gelistet, die in CODESYS auch verwendet werden. Dazu müsst ihr einfach im PLC_PRG „bStartJob;“ und „uiNumberOfScrews;“ schreiben oder die Variablen in einem Programm verwenden.
Nachfolgend erhaltet Ihr nochmal einen Überblick über das gesamte CODESYS Programm:
Unseren ersten Alexa Skill erstellen
Vorbereitungen
Um zu beginnen, müssen wir Python installieren. Wenn Ihr eine aktuelle Version von MacOS oder Linux verwenden, wird Python vorinstalliert sein. Unter Windows findet Ihr hier eine gute Anleitung. Vermutlich müsst Ihr auch pip installieren. Um pip zu installieren, folgt der offiziellen Pip-Installationsanleitung. Dabei installiert Ihr automatisch die neueste Version. Öffnen wir nun cmd.exe bzw. ein Terminal. Für die Vorbereitung installieren wir über pip die beiden folgenden Elemente:
pip install flask pip install flask-ask
Jetzt können wir mit unserem Python-Skript beginnen. Da Flask-Ask eine Flask-Erweiterung ist, sieht der Code wie eine Flask-Webanwendung aus. Alle wichtigen Infos über das Flak Microframework findet Ihr hier auf der offiziellen Seite, oder hier im Flask Mega Tutorial von Miguel Grinberg. Zum Beispiel, seht Ihr hier eine super einfache Flask-Anwendung:
from flask import Flask app = Flask(__name__) @app.route('/') def homepage(): return "Hi from CODESYS-Blog" if __name__ == '__main__': app.run(debug=True)
Ihr könnt diese Flask-Anwendung lokal auf dem Entwicklungsserver ausführen, der mit Flask geliefert wird. Führt den obigen Code aus, und Ihr haben einen Server, der auf http://127.0.0.1:5000 gehostet wird. Ihr können diese Adresse einfach in Eurem Browser aufrufen.
Mehr möchte ich zu den Grundlagen von Flask zunächst einmal nicht sagen. Aber wie oben schon erwähnt, könnt Ihr euch die Tutorial Seite von Miguel Grinberg ansehen.
Implementierung
Basierend auf diesem einfachen Flask-Webserver werden wir nun mit dem Alexa-Skill-Kit unsere Alexa-Anfragen verarbeiten und an die entsprechenden Routen weiterleiten. Denn im Grunde ist eine Alexa-Fertigkeit ähnlich wie eine Webseite, nur dass der Benutzer, anstatt auf einen Button zu klicken, mündlich mit dem Gerät interagiert. Alexa Skills bezeichnen diese Interaktionen als „Intent“, denn durch die Entscheidung (Intent) des Anwenders wird eine neue Funktion ausgeführt.
Um mit der Implementierung unserer Anwendung zu starten, werden wir den oben gezeigten Python Code nun um die Alexa Skill Komponenten erweitern. Zuerst importieren wir die benötigten Bibliotheken (welche Ihr zu Beginn dieses Kapitels installiert habt), um die Alexa-Fertigkeit zu verwenden. Außerdem müssen wir unseren OPC-UA Client bereitstellen und mit der Soft-SPS auf meinem Computer verbinden (darum localhost).
from flask import Flask, render_template from flask_ask import Ask, statement, question, session from opcua import Client from opcua import ua client = Client("opc.tcp://localhost:4840")
Als nächstes müssen wir die Alexa-Fertigkeit initialisieren und eine erste Begrüßungsnachricht bereitstellen. Die Initialisierung dieses Endpunktes erfolgt unter der Hauptdomain /. Durch den Dekorator @ask.launch landen wir beim Start der Anwendung direkt hier bei unserer Wilkommensnachricht und der Frage.
app = Flask(__name__) ask = Ask(app, "/") @ask.launch def new_Produktion(): logging.info("Read/Write variable with OPC-UA by Amazon Alexa voice command") welcome_msg = render_template('welcome') return question(welcome_msg)
Die notwendigen Sprachausgaben werde ich über ein Jinja-Template bereitstellen und über die Funktion render_template von unserer Flask-Anwendung verarbeiten lassen. Hierzu muss eine YAML-Datei namens templates.yaml im root Verzeichnis erzeugt werden.
Intents erzeugen
Betrachten wir also den Fall, bei dem ein Benutzer „ja“ sagt, wenn er gefragt wird, ob er die Produktion starten möchte. Wir nennen das ein YesIntent. Hierzu legen wir einen Pfad mit folgendem Dekorator an: @ask.intent(„YesIntent“). Außerdem müssen wir natürlich auch entsprechend mit einem NoIntent auf ein „nein“ reagieren @ask.intent(„NoIntent“).
@ask.intent("YesIntent") def get_Job(): client.connect() root = client.get_root_node() var = client.get_node("ns=4;s=|var|CODESYS Control Win V3 x64.Application.GVL.bStartJob") var.set_value(True) whichnumber_msg = render_template('whichnumber') return question(whichnumber_msg) @ask.intent("NoIntent") def end_Job(): end_msg = render_template('bye') return statement(end_msg)
Bei einem „Ja“ werden wir über OPC-UA die Variable bStartJob in unserer CODESYS SPS auf TRUE setzten und dann Alexa Fragen lassen welche Komponenten und in welcher Menge der Anwender für die Produktion benötigt. Dazu wird über das Jinja-Template die Ausgabe für „whichnumber“ aktiviert.
@ask.intent("GetScrewIntent", convert={'count': int}) def answer(count): var = client.get_node("ns=4;s=|var|CODESYS Control Win V3 x64.Application.GVL.uiNumberOfScrews") var.set_value(count, ua.VariantType.Int16) msg = render_template('deliverPart') return statement(msg)
Nachdem wir über Alexa mitgeteilt haben welche Anzahl von Schrauben wir benötigen wird diese im „GetScrewIntent“ über OPC-UA an meine CODESYS SPS übertragen. Hier habe ich beispielhaft ein Intent für Schrauben angelegt. Natürlich können hier noch mehrere Produkte oder eine generische Abfrage erstellt werden.
Damit haben wir nun die Funktionalität unseres Backends implementiert. Den Code findet Ihr hier auf meine GitHub Repository.
https://github.com/Matthias-Gehring/Amazon-Alexa-meets-CODESYS
Als nächstes müssen wir uns um die Parametrierung des Amazon Voice Service kümmern.
Anlegen des Voice Skills
Um mit Alexa Befehle auszuführen, sagt man normalerweise so etwas wie Alexa, starte „Anwendung“. Damit wird der Alexa-Skill ausgeführt. Dazu müssen wir den Skill in der Developer Console von Amazon erstellen.
Öffne dazu das Developer Portal: https://developer.amazon.com/de/
Nachdem du dich auf der „Developer Console“ eingeloggt hast – Klick auf „Alexa“ (1) im Menü.
Jetzt müsst Ihr entscheiden ob Ihr einen „Alexa Skills Kit“ oder einen „Alexa Voice Service“ erstellen wollt. IN unserem Fall wollen wir einen neuen Skill – also neue sprach App – anlegen. Beim Alexa Voice Service handelt es sich um die Option, die Ihr auswählen müsst, wenn Ihr Alexa in ein Gerät integrieren wollt. Klicke im Header auf „Deine Alexa Konsole“ – Skills (1) und anschließend auf „Create Skill“ (2).
Es öffnet sich ein Formular zum Anlegen eines neuen Skills. Hier werdet Ihr nach dem Skill Namen, der Sprache und dem Skill Typ gefragt:
Hier solltet Ihr unter Punkt (1) allgemeine Daten eintragen. Diese bedürften wohl keiner Erklärung. Punkt (2) hingegen möchte ich kurz erläutern. Hier gibt es mehrere Typen zur Auswahl. Wir wählen hier den Typ „Custom“, da wir hier unsere Nutzerinteraktion selbst definieren können. Das ist in den anderen Skills eingeschränkt. Abschließend betätigt Ihr den Button „Create Skill (3)“.
Jetzt wird es Spannend. Es gibt in unserem Skill builder nun zwei Bereiche, die wir bearbeiten müssen. Zum einen müssen wir unsere Intents und Utterances erzeugen und zum anderen müssen wir den Amazon Voice Service mit unserem Flask-Ask backend verbinden.
Beginnen wir zunächst mit den Intents
Die Abarbeitung des Intents habt Ihr weiter oben schon kennengelernt. Im Prinzip handelt es sich dabei um die Entscheidung des Anwenders eine Aktion auszuführen. Diese kann auf unterschiedliche Arten gestartet werden. Das sind dann die Varianten/Utterances.
z.B. Kann ein Intent zum Starten der Produktion über die folgenden Funktionen aufgerufen werden:
- Starte Produktion
- Lass uns mit der Produktion starten
- Alexa ich möchte Anfangen
Wir müssen nun für alle Intents, die wir bereits im Backend realisiert haben das Gegenstück in der Entwicklerkonsole anlegen. Das könnt Ihr durchführen, indem Ihr im Menü (1) die ganzen Aktionen durchführt, oder Ihr macht euch mit der Definition des JSON Files bekannt, welches die ganzen Intents/Utterances und Slots definiert (2). Als Nerd und Programmierer habe ich mich natürlich für letzteres entschieden.
Der JSON-Code erklärt sich eigentlich von selbst darum gehen wir nur exemplarisch ein paar Punkte zusammen durch. Ganz wichtig ist der Punkt – „invocationName“. Damit startet Ihr den Skill. z.B. „Amazon starte neue Ventil Produktion“. Im Array der intents sind die folgenden Felder interessant:
- „names“: Das ist der Name der im flask-ask code z.b. für @ask.intent(„YesIntent“) hinterlegt wurde.
- „samples“: Das sind die verschiedenen Ausprägungen mit denen der Intent angesprochen wird.
{ "interactionModel": { "languageModel": { "invocationName": "neue ventil produktion", "intents": [ { "name": "YesIntent", "slots": [], "samples": [ "Natürlich", "Ja", "yes", "sure" ] }, { "name": "NoIntent", "slots": [], "samples": [ "Nein", "No" ] }, { "name": "GetScrewIntent", "slots": [ { "name": "getScrewCount", "type": "AMAZON.NUMBER", "samples": [ "{count}" ] }, { "name": "count", "type": "AMAZON.NUMBER" } ], "samples": [ "Bitte gebe mir {count} Schrauben." ] } ], "types": [ { "name": "Product", "values": [ { "name": { "value": "ventil" } }, { "name": { "value": "motor" } } ] } ] }, "dialog": { "intents": [ { "name": "GetScrewIntent", "confirmationRequired": true, "prompts": { "confirmation": "Confirm.Intent.1256626599551" }, "slots": [ { "name": "getScrewCount", "type": "AMAZON.NUMBER", "confirmationRequired": false, "elicitationRequired": true, "prompts": { "elicitation": "Elicit.Slot.1256626599551.121065955672" } }, { "name": "count", "type": "AMAZON.NUMBER", "confirmationRequired": false, "elicitationRequired": false, "prompts": {} } ] }, { "name": "YesIntent", "confirmationRequired": false, "prompts": {}, "slots": [] } ] }, "prompts": [ { "id": "Elicit.Slot.1077773249414.837823495911", "variations": [ { "type": "PlainText", "value": "Wieviel Schrauben sind erforderlich?" } ] }, { "id": "Elicit.Slot.1256626599551.121065955672", "variations": [ { "type": "PlainText", "value": "Wieviele Schrauben benötigst du?" } ] }, { "id": "Confirm.Intent.1256626599551", "variations": [ { "type": "PlainText", "value": "Wieviele {getScrewCount}" } ] } ] } }
Das einfachste ist nun, wenn Ihr mein JSON-Code kopiert einfügt, und Speichern drückt. Dann sind zunächst mal alle Interaktionen importiert. Nun könnt Ihr auch in der Baumstruktur Änderungen grafisch durchführen.
Abschließend müsst Ihr noch den Endpunkt konfigurieren (1)
Da ich keine Lust habe den AWS Lambda Service zu nutzen und zu konfigurieren, bleibt mir nur die Möglichkeit einen HTTPS-Server aufzusetzen. Aber wie oben schon erwähnt nutzen wir hierfür das Tool „ngrok“. Dazu im nächsten Kapitel mehr. Passt nun die Einstellungen wie im oben dargestellten Screenshot an und klickt auf „Save Endpoint“. Die URL für Punkt (3) ergibt sich erst beim Einsatz von ngrok im nächsten Kapitel. Da ich aber die kostenlose Variante von ngrok nutze, muss ich eh bei jedem Start des Tools, die URL neu kopieren und einfügen.
Wo hoste ich meinen Alexa Skill?
Wenn Ihr das Python Script ausführt, startet der Entwicklungsserver auf http://127.0.0.1:5000/. Damit ist der Alexa Skill fast fertig und Ihr müsst nur noch, wie oben erwähnt, den Endpunkt, im Amazon Developer Portal konfigurieren.
Hier schreibt Amazon vor, dass der Skill hinter einem öffentlichen HTTPS-Server oder einer AWS-Lambda-Funktion ausgeführt wird. Beide Forderungen sind allerdings ein Hindernis. Ich könnte zwar den Skill auf meine CODESYS-Blog.com Seite hochladen, oder mir für Versuche ein AWS Zugang beantragen, aber es gibt noch eine weitaus einfachere Lösung, um unseren Skill zu testen. Wie oben schon erwähnt, nutzen wir ngrock. Dabei handelt es sich um ein Kommandozeilenprogramm, das einen sicheren Tunnel zu localhost öffnet und diesen Tunnel hinter einem HTTPS-Endpunkt freigibt. Dadurch wird es möglich, dass Alexa direkt mit unserem code kommunizieren kann. Ngrock erfordert keine Installation, sondern muss lediglich heruntergeladen, entpackt und ausgeführt werden.
.\ngrok.exe http 5000
Ihr werdet nun ähnlich wie bei mir, folgende Statusmeldung erhalten. Merkt euch den HTTPS Endpunkt. Diesen müssen wir nun im Amazon Developer Portal eintragen um unseren Skill bereitzustellen. Führt dazu einfach nochmals die Schritte im vorherigen Abschnitt durch.
Skill bereitstellen und Zugriff Absichern
Lasst uns den Skill testen
Nun ist es an der Zeit, unseren Alexa-Skill mit der folgenden Interaktionssequenz zu testen. Ich habe hierzu den ersten Video Beitrag für diesen Blog erstellt. Mir erscheint das die beste Möglichkeit zu sein, wie ich euch zeigen kann wie der ganze Aufbau funktioniert. Das Video beinhaltet nicht den ganzen Aufbau, sondern nur die Live-Demo. Eventuell werde ich aber auch noch die ganze Parametrierung bzw. Programmierung in einem Video aufnehmen. Bin mal gespannt, wie das ganze ankommt. Über Rückmeldungen würde ich mich sehr freuen.
Fazit
Themen wie Datenschutz und IT-Security wurden hier in diesem Artikel nur am Rande behandelt. Natürlich sind das zwei wichtige Bausteine einer digitalen Fabrik und auch beim Thema Industrie 4.0 eine grundlegende Problematik, mit der sich viele Unternehmen auseinandersetzen müssen. Aber die zuständigen Personen in eurer Organisation wissen um die Schwierigkeiten und können so optimal für einen sicheren und datenschutzkonformen Einsatz innerhalb eures Unternehmens sorgen.
Die Möglichkeiten, die sich durch den Einsatz der digitalen Sprachassistenten ergeben sind phänomenal, und wir kennen mit Sicherheit noch nicht alle Einsatzgebiete, da sich unsere Vorstellungskraft, erst noch an diese neue Technologie gewöhnen muss. Ich hoffe, dass ich mit diesem Artikel, den Ein oder anderen von euch zu neuen Ideen anregen konnte. Habt Ihr gute Ideen, wie Ihr einen Sprachassistent im Unternehmensbereich einsetzten wollt? Dann lasst es mich Wissen.
Ich möchte hier abschließend allerdings noch einige Bedenken äußern. Schließlich handelt es sich bei den Sprachassistenten um nichts anderes als moderne Wanzen mit Internet-Anbindung. Amazon Echo und Google Home lauschen permanent mit und warten auf ihren Einsatz. Wer kontrolliert die Unternehmen dahinter? Können wir Ihnen trauen? Diese Frage sollte sich jeder selbst Stellen und selbst beantworten. Im Hinblick auf die jüngsten Datenvergehen ist zumindest keine einfache Antwort möglich.
Klasse, Matthias, schöne Darstellung.
Bin überzeugt, dass Kommunikation über natürliche Sprache in der Fertigungsautomatisierung kommen wird. Menschen, die zusammen arbeiten, reden ja auch miteinander, um sich zu koordinieren. Dann wird es eine „Alexa-Funktion“ für den Industriebereich geben, die kommt dann von einem Automatisierungshersteller. Vielleicht werden wir das bald erleben. Und ja, mit den Geräten, die heute kommerziell verfügbar sind, würde ich in der eigenen Fertigung auch eher vorsichtig sein.
Hallo Matthias,
ganz genau. Das ist logischerweise der nächste Schritt. Hier hat IBM auf der Think 2018 gezeigt, was der neue Watson Assistant kann. Das ist meiner Meinung nach ein Sprachassistent, der Amazon und Google durchaus Konkurrenz machen kann. Ganz Besonders ist hier das Versprechen hervorzuheben, dass die Daten der Nutzer nicht automatisch auf den Servern von IBM landen. Freuen wir uns auf eine Spannende Zukunft 🙂