SOAP über VB.NET "Step by Step"

Hallo alle zusammen,

aus gegebenen Anlass möchte ich mit diesem Thread nochmals alles zusammentragen was zum einrichten der SOAP-Schnittstelle unter VB.NET zu tun ist. Also:

Einrichten der SOAP-Schnittstelle unter VB.NET „Step by Step“

Inhalt:
#1: Inhalt und Einleitung
#2: Einrichten der SOAP-Schnittstelle
#3: Das Programm -> Basics für IIPSVariableManager, IIPSHMDevice
#4: Starten von IPS-Scripte über SOAP
#5: Grundsätzliche Vorgehensweise bei der SOAP-Schnittstelle
#7: Variablenänderungen über SOAP oder „Hey, whats up“
#8: „Späte Bindung“ der SOAP-Schnittstelle

Einleitung:

Mit der SOAP-Schnittstelle habe ich die Möglichkeit auf IPS zuzugreifen.

Zitat IPS:
Dank der SOAP Schnittstelle haben Sie die selben Möglichkeiten wie in PHP. Alle Funktionen und Befehle können Sie aus Ihrer Lieblingsprogrammiersprache aufrufen. Dank der der Selbstbeschreibenden Schnittstelle (über WSDL) sind Funktionen aus IP-Symcon in Ihrer Software verfügbar.

Bei der Einrichtung der Schnittstelle gibt es jedoch ein paar Stolpersteine die Umgangen werden wollen. Die SOAP-Schnittstelle unter IPS ist sehr umfangreich. Ich werde zur Einführung nur auf folgende Schnittstellen eingehen:

IIPSVariableManager
IIPSHMDevice (ich habe nur HomeMatic)

Dieser Thread kann aber von anderen nach belieben erweitert werden.

Software:

Das von mir benutzte Programm in den Beispielen ist „Microsoft Visual Basic 2008 Express Edition“.

(Sooooo…. Genug geschwafelt. Wie heißt es immer bei Lehrgängen von Siemens: „Und nun, Hand an die Maus“)

Änderungshitorie:

0.00 |01.09.2010| ------ Draft Version ------ | Schablone
0.01 |03.09.2010| -------- Tidy up --------- | Schablone
0.02 |03.09.2010| -Starten von IPS-Scripte- | Schablone
1.00 |04.09.2010| ------ Final Version ---- – | Schablone
1.01 |30.06.2011| --Variablenänderung ----- | Schablone

Einrichten der SOAP-Schnittstelle:

Als erstes starten wir VB.NET (ich kann es kaum glauben das ich so anfange)

Neues Projekt anlegen mit dem Namen „SOAP_Interface_IPS“ oä

Projekt speichern

Projekte -> Dienstverweis hinzufügen

In dem Fenster „Dienstverweise hinzufügen“ unten den Button „Erweiterte“ klicken.

In den erweiterten Einstellungen unter Kompatibilität den Button „Webverweis hinzufügen“ anklicken.

Die SOAP Schnittstelle/WSDL Beschreibungen können über folgende Adresse erreicht werden:
http://localhost:3773/
Also bei „URL“ http://<IP-ADRESSE IPS>:3773/ eingeben.
Um sicher zu gehen würde ich auf jeden Fall die IP-Adresse vor „localhost“ bevorzugen.

Danach werden alle Webdienste von IPS angezeigt.

Um IPS Variablen zu schreiben/lesen muss der Webservice „IIPSVariableManager“ über die Auswahl WSDL angewählt werden.

Nun muss noch ein Webverweisnahme deklariert werden. Danach kann mit dem Button „Verweis erstellen“ dem Projekt die Web Reference zufügen.

Zur Info:
Es ist wichtig die SOAP-Schnittstelle von IPS über einen Webverweis einzubinden. Dienstverweise funktionieren nicht immer!!!

Mit einem Rechtsklick auf den Ordner Web References können weitere Referenzen erzeugt werden.

Da ich HomeMatic Geräte im Einsatz habe, wurde von mir noch eine Web Reference auf die „IIPSHMDevice“ erstellt.

Nach Abschluss dieser Einbindung würde ich das Projekt noch einmal speichern.

Damit ist schon das Schlimmste geschehen!!!
Und noch mal: Ihr müsst die Webverweise nehmen. Nicht die Dienstverweise.

SOAP_01.jpg

SOAP_07.jpg

SOAP_08.jpg

SOAP_09.jpg

Das Programm:

Basics:
Zum lesen und schreiben von Variablen in IPS muss die IIPSVariableManagerservice-Klasse instanziert werden. Also schreiben wir nach Public Class Form1 (oä)


Public IPSVariablen As New IIPSVariableManager.IIPSVariableManagerservice

Beispiel → schreiben einer String Variablen in IPS


IPSVariablen.WriteVariableString(IPS-ID, “Ich bin ein String”)

IPS-ID → ist natürlich die Variablen ID aus IPS

Beispiel → lesen einer String Variablen aus IPS


tbString.Text = IPSVariablen.ReadVariableString(IPS-ID)

Beispiel → schreiben einer Integer Variablen in IPS


IPSVariablen.WriteVariableInteger(IPS-ID, 12345)

Beispiel → lesen einer Integer Variablen aus IPS


tbString.Text = IPSVariablen.ReadVariableInteger(IPS-ID)

Beispiel → schreiben einer Float Variablen in IPS


IPSVariablen.WriteVariableFloat(IPS-ID, 123,45)

Beispiel → lesen einer Float Variablen aus IPS


tbString.Text = IPSVariablen.ReadVariableFloat(IPS-ID)

Beispiel → schreiben einer Boolean Variablen in IPS


IPSVariablen.WriteVariableBoolean(IPS-ID, cbBoolean.Checked)

Beispiel → lesen einer Boolean Variablen aus IPS


cbBoolean.Checked = IPSVariablen.ReadVariableBoolean(IPS-ID)

Wie man sehen kann eigentlich recht simpel. Aber auch das ansprechen der Hardware in IPS ist unwesentlich länger.

Basics:
Zum setzen der Hardware für HomeMatic muss die IIPSHMDeviceservice-Klasse instanziert werden. Also schreiben wir nach Public Class Form1 (oä)


Public IPSHMDevice As New IIPSHMDevice.IIPSHMDeviceservice

Für Modulbefehle muss der TIDHeader mit gesendet werden. Dieser TIDHeader ist nichts anderes als die anzusprechende InstanzID in IPS.

Beispiel → Schalten einer Lampe
Als erstes muss die TIDHeader-Klasse instanziert werden.


Dim TID_Header As New IIPSHMDevice.TIDHeader

Der Eigenschaft “ID” muss die InstanzID der Hardware übergeben warden. In meinem Beispiel ist es die „29234“.


TID_Header.ID = 29234

Und nun kommt das wichtigste. Unserer IPSHMDevice Instanz muss dieser TIDHeader übergeben werden. Das geht so:


IPSHMDevice.TIDHeaderValue = TID_Header

Nun kommt endlich das was wir wollen → Einschalten!


IPSHMDevice.WriteValueBoolean("STATE", True)

Hier mal als vergleich der Befehl in IPS:


HM_WriteValueBoolean(29234, "STATE", True);

Fällt euch was auf?

Als letztes muss noch der TIDHeader wieder frei gegeben werden. Das geschieht mit.


TID_Header = Nothing

So das war‘s! Ich hoffe das, das für einige hilfreich ist um den Einstig in die SOAP-Schnittstelle zu bekommen. Ich würde mir wünschen das dieser Thread von anderen mit leben gefüllt wird. Die SOAP-Schnittstelle ist sehr umfangreich und es gibt noch eine menge zu erzählen.

Bis dann

Martin

SOAP_10.jpg

Starten von IPS-Scripte über SOAP

Über die SOAP-Schnittstelle ist es möglich Skripte in IPS zu starten. Für diese Funktion benötigen wir eine Web-Reference auf „IIPSScriptEngine“.

Einbinden des Webverweis:

Wie bereits unter „Einrichten der SOAP-Schnittstelle“ beschrieben können mit einem Rechtsklick auf den Ordner Web References weitere Referenzen erzeugt werden.

Also:

Rechtsklick auf Web-References im Projektmappen Explorer.

Bei „URL“ http://<IP-ADRESSE IPS>:3773/ eingeben.

Den Webservice „IIPSScriptEngine“ über die Auswahl WSDL anwählen.

Einen Webverweisnahme deklarieren und mit dem Button „Verweis erstellen“ dem Projekt die Web Reference zufügen.

Das Programm:

Basics:
Um ein IPS-Skript zu starten muss die IIPSScriptEngineservice-Klasse instanziert werden. Also schreiben wir nach Public Class Form1 (oä)


Public IPSScript As New IIPSScriptEngine.IIPSScriptEngineservice

Mit dieser Zeile wird dann das Script mit der entsprechenden IPS-ID gestartet.


IPSScript.ExecuteScript(IPS-ID, True)

In meinem Fall ist also IPS-ID = 53828

Bis dann

Martin

SOAP_20.jpg

SOAP_21.jpg

SOAP_22.jpg

Grundsätzliche Vorgehensweise bei der SOAP-Schnittstelle

Hier nun jeden Befehl der SOAP-Schnittstelle zu erläutern würde zu weit führen. Dazu gibt es ja die überdurchschnittlich gute Dokumentation von IPS.

In der Dokumentation zu der SOAP-Schnittstelle steht, Zitat IPS:

Alle Befehle der SOAP Schnittstelle verhalten sich äquivalent zu denen in PHP. Dadurch kann die normale Befehlsreferenz/Modulreferenz als Dokumentationsgrundlage verwendet werden.

Nun mag der genervte Leser denken:
Man Steiner! Da hast Du dir das Leben wieder verdammt einfach gemacht!

Das er aber recht hat, soll dieses kleine Beispiel zeigen.

Wir werden über die SOAP-Schnittstelle eine neue Kategorie erstellen. Diese Kategorie bekommt den Namen „.SOAP_Interface“. Danach werden wir eine Variable vom Typ „String“ mit dem Namen „SOAP_String“ erstellen. Diese Variable werden wir in die Kategorie „.SOAP_Interface“ verschieben.

Welche Befehle werden dazu benötigt?

Wir beginnen mit „Erstellen einer neuen Kategorie“.

Wir wechseln in die IPS-Dokumentation unter Befehlsreferenz.

Dort gibt es die „Kategorieverwaltung“. In der Kategorieverwaltung finden wir den Befehl: „IPS_CreateCategory“

Mit diesem Befehl wird eine neue Kategorie mit dem Namen „Unnamed Object“ angelegt. Als Rückgabewert bekommt man die IPS_ID der neuen Kategorie.

Wie finde ich nun diesen Befehl in der SOAP-Schnittstelle? Welchen Webservice muss ich als Web-Reference einbinden?
Um das heraus zu finden nutze ich meinen Webbrowser. In der Adresszeile gebe ich folgendes ein:

http://IP-ADRESSE IPS:3773/

Nun werden mir alle Web-Services von IPS angezeigt. Von dem Befehl „IPS_CreateCategory“ suche ich lediglich „CreateCategory“. Den Web-Service oberhalb des gefundenen Befehls muss ich per Klick auf das WSDL auswählen.

In dem nachfolgendem Fenster ist der Name der Klasse die wir später im Programm instanzieren müssen angezeigt.

Die Einbindung erfolgt wie unter „Einrichten der SOAP-Schnittstelle“ beschrieben.

Das Programm:

Zum anlegen einer neuen Kategorie muss die Klasse IIPSCategoryManagerservice instanziert werden. Also schreiben wir nach Public Class Form1 (oä)


Public IPSCategory As New IIPSCategoryManager.IIPSCategoryManagerservice

Zum erzeugen einer neuen Kategorie schreiben wir:


Dim IPS_ID As UShort
IPS_ID = IPSCategory.CreateCategory()

Wenn wir nun die Maus über den Befehl halten bekommen wir exakt die gleiche Beschreibung des Befehls wie in der IPS Befehlsreferenz.

Nach dem ausführen haben wir in IPS eine neue Kategorie mit dem Namen „Unnamed Object…“.

Holy Fuck! Thats magic!

Bevor wir weiter machen löschen wir erst die entstandene Kategorie. (Wer will schon Datenmüll !!)

Als nächstes bekommt die Kategorie den Namen „SOAP_Interface“.

Wir wechseln in die IPS-Dokumentation unter Befehlsreferenz.

Dort gibt es die „Objektverwaltung“. In der Objektverwaltung finden wir den Befehl: „IPS_SetName“

In unserem Webbrowser suchen wir den Befehl „SetName“. Den Web-Service oberhalb des gefundenen Befehls muss ich per Klick auf das WSDL auswählen.

Die Einbindung erfolgt wie unter „Einrichten der SOAP-Schnittstelle“ beschrieben.

Das Programm:

Zum vergeben von Namen muss die Klasse IIPSObjectManagerservice instanziert werden. Also schreiben wir nach Public Class Form1 (oä)


Public IPSObjektManager As New IIPSObjectManager.IIPSObjectManagerservice

Unser Programm wird nun wie folgt abgeändert:


Dim IPS_ID As UShort
IPS_ID = IPSCategory.CreateCategory()
IPSObjektManager.SetName(IPS_ID, “.SOAP_Interface”)

Wenn wir nun die Maus über den Befehl halten bekommen wir nochmals exakt die gleiche Beschreibung des Befehls wie in der IPS Befehlsreferenz.

Nach dem ausführen des Programms haben wir eine neue Kategorie mit dem Namen „.SOAP_Interface“.

Nun werden wir eine Variable vom Typ „String“ mit dem Namen „SOAP_String“ erzeugen.

Wir wechseln in die IPS-Dokumentation unter Befehlsreferenz.

Dort gibt es die „Variablenverwaltung“. In der Variablenverwaltung finden wir den Befehl: „IPS_CreateVariable“

In unserem Webbrowser suchen wir den Befehl „CreateVariable“. Super! Wir brauchen nichts zu tun. Diesen Web-Service haben wir bereits im Kapittel „Einrichten der SOAP-Schnittstelle“ eingebunden.

Das Programm:


Dim IPS_ID As UShort
IPS_ID =  IPSVariablen.CreateVariable(3)
IPSObjektManager.SetName(IPS_ID, “SOAP_String”)

Nach dem ausführen des Programms haben wir eine neue Variable mit dem Namen „SOAP_String“. Und wieder ist die Befehlsbeschreibung in VB.NET die gleiche wie in der IPS Befehlsreferenz.

Zu guter letzt wollen wir noch die Variable in die neu erstellte Kategorie „.SOAP_Interface“ verschieben. Dazu löschen wir erst die gerade erzeugte Variable.

Wir wechseln in die IPS-Dokumentation unter Befehlsreferenz.

Dort gibt es die „Objektverwaltung“. In der Objektverwaltung finden wir den Befehl: „IPS_GetObjectIDByName“
(siehe SOAP_29)

In unserem Webbrowser suchen wir den Befehl „GetObjectIDByName“. Klasse! Auch für diesen Befehl brauchen wir nichts zu tun. Diesen Web-Service haben wir bereits.

Das Programm:


Dim IPS_ID As UShort
Dim IPS_ParentID As UShort

IPS_ID =  IPSVariablen.CreateVariable(3)
IPSObjektManager.SetName(IPS_ID, “SOAP_String”)

IPS_ParentID = IPSObjektManager.GetObjectIDByName(".SOAP_Interface", 0)
IPSObjektManager.SetParent(IPS_ID, IPS_ParentID)

Und wieder zeigt uns die VB.NET Befehlsbeschreibung das gleiche wie die IPS Befehlsbeschreibung.

Nach dem ausführen des Programms solltet Ihr eine Variable vom Typ „String“ mit dem Namen „SOAP_String“ in der Kategorie mit dem Namen „SOAP_Interface“ haben.

Und was sagt uns dieses Beispiel?

Wenn Herr Steiner sagt:

Alle Befehle der SOAP Schnittstelle verhalten sich äquivalent zu denen in PHP. Dadurch kann die normale Befehlsreferenz/Modulreferenz als Dokumentationsgrundlage verwendet werden.

Dann stimmt das auch. :wink:

In diesem sinne….

Bis dann

Martin

SOAP_24.jpg

SOAP_26.jpg

SOAP_30.jpg

Bei Fragen und Anregungen zu diesem Beitrag - bitte hier posten:

Hallo alle zusammen,

Über die SOAP-Schnittstelle hat man die Möglichkeit Meldungen von IPS zu empfangen. Über diese Meldungen bekommt man auch mitgeteilt wenn sich eine Variable geändert hat. Über die mitgeschickte Variablen-ID kann man den Variablenwert auslesen.

Als erstes muss der Webverweis „IIPSSOAPServer“ eingebunden werden (siehe Screenshot).

Zum empfangen von IPS-Meldungen muss die IIPSSOAPServerservice-Klasse instanziert werden. Also schreiben wir nach Public Class Form1 (oä)

Public IPSSoapServer As New IIPSSOAPServer.IIPSSOAPServerservice

Da wir IPS kontinuierlich nach Meldungen abfragen, würde ich diesem Programmteil einen „BackgroundWorker“ (einen eigenen Thread) spendieren.

Den „Background_Worker“ starten wir mit:

BackgroundWorker.RunWorkerAsync()

Nun kommt das Programm in den BackgroundWorker. Also zwischen.

Private Sub BackgroundWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker.DoWork

End Sub

Als erstes starten wir die „Session“ mit IPS. Als Rückmeldung bekommen wir eine Session-ID die wir zum abfragen der Meldungen benötigen. Dazu schreiben wir:

    Dim IPS_SessionString As String
   'Starten der IPS-Session
    IPS_SessionString = IPSSoapServer.StartSession(IIPSSOAPServer.TIPSFilterType.ftExcludeFilter)

Da wir ab jetzt kontinuierlich die Meldungen abfragen kommt das folgende Programm in eine „While-Schleife“ die so aussieht:

While True

End While

Als Rückmeldung bekommen wir von IPS ein Array vom Typ „TIPSMessage“.
Also schreiben wir:

Dim tmp_msg() As IIPSSOAPServer.TIPSMessage
tmp_msg = IPSSoapServer.GetSessionMessages(IPS_SessionString)

In jeder Message (Array-Element) steckt eine Message-ID die aussagt was für eine Meldung enthalten ist. Wir durchlaufen also das Array und schauen uns die Message-ID an. Das sieht so aus:

If tmp_msg.Length > 0 Then

            'Durchlaufen der einzelnen Meldungen
            For Each msg As IIPSSOAPServer.TIPSMessage In tmp_msg

                Dim msg_id As Integer
                msg_id = msg.Message

            Next

End If

Welche Message-ID (Zahlenwert) was bedeutet ist im SDK in der Datei „UIPSKernel.pas“ zu finden. Bei einer Variablenänderung kommt die Message-ID „10603“. Also fragen wir nur die Meldungen mit der Message-ID „10603“ ab. Somit sieht das obere Programm nun so aus:

If tmp_msg.Length > 0 Then

            'Durchlaufen der einzelnen Meldungen
            For Each msg As IIPSSOAPServer.TIPSMessage In tmp_msg

                'bei einer MessageID von 10603 hat man eine Variablenänderung
                If msg.Message = 10603 Then

                    'Auslesen der Variablen-ID
                    ID = msg.SenderID

End If
Next
End If

In „ID“ steht nun die Variablen-ID der Variable die sich geändert hat.

Ich hoffe das ich das einigermaßen verständlich erklärt habe. Wenn da noch Fragen sind, meldet euch bitte.

Hallo alle zusammen,

Wenn man Programme schreibt die man weiter geben möchte (z.B. IgS) kommt man an einer späten Bindung der SOAP-Schnittstelle nicht vorbei. Das ist aber relativ einfach.

Nachdem man den/die Webverweise in seinem Projekt eingebunden hat muss jeder Verweis in den Eigenschaften auf „URL-Verhalten“ -> „Dynamisch“ gestellt werden.

In der Datei „app.config“ steht die URL.

Diese URL kann nun auch zur Laufzeit übergeben werden. Dazu schreibt man:

IPSVariablen.Url = „http://“ & tbIPS_IPAdress.Text & „:3773/soap/IIPSVariableManager“

Ganz kurz und schmerzfrei. :wink: