XML-RPC init

Nutzung von XML RPC, Remote Script, JSON RPC, XMLAPI

Moderator: Co-Administratoren

Marcel Payne
Beiträge: 14
Registriert: 04.11.2015, 10:35

XML-RPC init

Beitrag von Marcel Payne » 04.11.2015, 10:41

Guten Morgen,

für mein Semesterprojekt suche ich ein Beispiel für die init Anweisung und der Umgang mit den gesendeten Nachrichten der CCU2.

listDevice, getValue und setValue habe ich zum laufen gebracht, aber der init ist mir noch nicht ganz klar geworden.

Eigentlich programmiere ich mit WPF (vb.net), aber nach langer Suche im Netz hab ich ein vb.net Beispiel aufgegeben. Also kann das Beispiel auch gerne in C#, Java, PHP/HTML sein, da bin ich mittlerweile flexibel geworden.

Danke schon einmal für eure Antworten
Gruß
Marcel

Benutzeravatar
thkl
Beiträge: 2765
Registriert: 15.07.2013, 13:32
Wohnort: dickes B
Danksagung erhalten: 5 Mal

Re: XML-RPC init

Beitrag von thkl » 11.11.2015, 20:47

Nabend,

also .. mit Init meldest Du deinen eigenen Webserver als Empfänger für Nachrichten des Schnittstellenprozesses an.
Du übergibst mit dem init Call als Argument der CCU eine URL die sie ab dem Zeitpunkt immer aufruft wenn sich ein beliebiger Datenpunkt auf der Schnittstelle geändert hat. Das von der CCU verwendete Sendeformat ist ebenso xml-rpc. Wichtig wenn sich mehrere Datenpunkte innerhalb kürzester Zeit geändert haben, werden die Events zu einem multicall zusammengefasst.

Beispiel https://raw.githubusercontent.com/thkl/ ... aticRPC.js

Achja das erste Argument für Init ist die Url , das zweite ein beliebiger Name unter dem die CCU den Server der sich bei ihr anmeldet führt.
Wenn Du init mit der gleichen URL aber leerem Argument für den Namen aufrufst, meldest Du Dich wieder ab, und bekommst ab dem Zeitpunkt keine Calls mehr

Marcel Payne
Beiträge: 14
Registriert: 04.11.2015, 10:35

Re: XML-RPC init

Beitrag von Marcel Payne » 17.11.2015, 20:00

Danke thkl,

beim ersten groben Überfliegen sieht dein gepostetes Beispiel sehr vielversprechend aus. Ich bedanke mich für die ausführliche Antwort.
Sollte noch was unklar sein, melde ich mich wieder.

Noch eine andere Frage. Mein Wandthermostat (HM-TC-IT-WM-W-EU / Version 1.3) und der Heizkörperthermostat (HM-CC-RT-DN / Version 1.3) geben mir immer ein -1 [Failure] als Exception beim setzen der Solltemperatur zurück. Und auch der Modus lässt sich nicht umschalten. :roll: Alle anderen Aktoren machen keinerlei Probleme, beim setzen von irgendwelchen Werten und auch das auslesen der beiden Aktoren ist kein Problem.

Könnte mir da jemand behilflich sein, dieses Problem in den Griff zu bekommen. Im Netz steht immer was von Aktoren updaten, aber viel weiter lassen sich die beiden ja aktuell nicht updaten.

Gruß
Marcel

Marcel Payne
Beiträge: 14
Registriert: 04.11.2015, 10:35

Re: XML-RPC init

Beitrag von Marcel Payne » 09.02.2016, 20:09

So,

nach einer langen Pause, komm ich an meinem Projekt auch weiter.
Ich hab jetzt mit dem init nur ein ganz komisches Problem.

Zu erst bekomme ich eine Timeout-Exception bei der Ausführung von init, obwohl ich meinen Timeout schon auf 30.000ms gesetzt habe.

Code: Alles auswählen

Ausnahme ausgelöst: "System.Net.WebException" in CookComputing.XmlRpcV2.dll
System.Net.WebException: Die Anfrage wurde abgebrochen: Timeout für Vorgang überschritten.
   bei System.Net.HttpWebRequest.GetResponse()
   bei CookComputing.XmlRpc.XmlRpcClientProtocol.GetWebResponse(WebRequest request)
   bei CookComputing.XmlRpc.XmlRpcClientProtocol.Invoke(Object clientObj, MethodInfo mi, Object[] parameters)
   bei CookComputing.XmlRpc.XmlRpcClientProtocol.Invoke(MethodInfo mi, Object[] Parameters)
   bei XmlRpcProxyc4be376d-0a0d-4e44-8425-508efb01a2e7.Init(String url, String interface_id)
   bei XMatic.MainWindowViewModel.ConnectToPuCommandExecute() in C:\Users\Marcel\Source\Workspaces\Arbeitsbereich\XMatic\XMatic\ViewModel\MainWindowViewModel.vb:Zeile 193.
Aber der TCPListener in einem anderen Thread bekommt trotzdem eine Nachricht von der CCU2 geschickt.

Code: Alles auswählen

POST /RPC2 HTTP/1.1
User-Agent: XMLRPC++ 0.7
Host: 192.168.2.107:5555
Content-Type: text/xml
Content-length: 146

<?xml version="1.0"?>
<methodCall><methodName>system.listMethods</methodName>
<params><param><value>CCU2</value></param></params></methodCall>
Solltet ihr noch irgendeinen Quellcode oder sowas brauchen, werde ich das natürlich schnellstmöglich nachreichen.

Gruß
Marcel

peex
Beiträge: 5
Registriert: 08.06.2015, 16:03

Re: XML-RPC init

Beitrag von peex » 10.02.2016, 19:20

Wichtig ist, dass du die system.listMethods-Anfrage auf jeden Fall beantwortest. Dort fragt die CCU ab, welche Methoden dein XML-RPC-Server zur Verfügung stellt und ruft diese gegebenenfalls auch noch auf.

Dein init-Aufruf muss also entweder in einem separaten Thread laufen oder du wartest erst gar nicht auf eine Antwort.

Marcel Payne
Beiträge: 14
Registriert: 04.11.2015, 10:35

Re: XML-RPC init

Beitrag von Marcel Payne » 11.02.2016, 18:08

peex hat geschrieben:Wichtig ist, dass du die system.listMethods-Anfrage auf jeden Fall beantwortest. Dort fragt die CCU ab, welche Methoden dein XML-RPC-Server zur Verfügung stellt und ruft diese gegebenenfalls auch noch auf.

Dein init-Aufruf muss also entweder in einem separaten Thread laufen oder du wartest erst gar nicht auf eine Antwort.
Ah, sehr informativ, der TCPListener ist in einem eigenen Thread.

Wie würde eine solche Nachricht aussehen?

Marcel Payne
Beiträge: 14
Registriert: 04.11.2015, 10:35

Re: XML-RPC init

Beitrag von Marcel Payne » 15.02.2016, 18:53

Ok ich hab es soweit geschafft. (Vollständige Umsetzung poste ich wenn alles so funktioniert wie ich mir das vorstelle)

Aber ich hab das Gefühl, Homematic ohne Probleme geht nicht :roll:

Leider schickt mir die CCU2 nur ungefähr eine Minute lang Nachrichten. Ist das ein bekanntes Verhalten und eine Einstellungssache in der WebUi oder eher untypisch und wahrscheinlich ein Problem im Code?

Gruß
Marcel

peex
Beiträge: 5
Registriert: 08.06.2015, 16:03

Re: XML-RPC init

Beitrag von peex » 24.02.2016, 17:16

Du kennst ja bestimmt http://www.eq-3.de/Downloads/Software/H ... pc_API.pdf dort ist nicht nur beschrieben, welche XML-RPC-Methoden du aufrufen kannst, sondern auch, welche du bereitstellen musst bzw. kannst (nicht alle sind zwingend nötig).

Außerdem musst du system.listMethods (auf http://xmlrpc-c.sourceforge.net/introspection.html beschrieben) bereitstellen, sofern du nicht eine Library einsetzt, die das für dich übernimmt. Die Antwort darf natürlich nur die Methoden enthalten, die du auch tatsächlich anbietest. Im Anhang siehst du den Ablauf, falls ich es etwas unklar beschrieben habe. HM-Gateway entspricht deinem Programm.

RFD versucht mehrfach dich zu erreichen; klappt das jedoch nicht, bricht er die Verbindung irgendwann ab. Wenn du also zunächst etwas empfängt, er dann aber irgendwann nicht mehr sendet, liegt das wohl daran, dass er meint, dein Listener wäre nicht mehr aktiv. Beantwortest du die Anfragen von RFD richtig? Auch beim Rückgabetyp void (eigentlich keine Rückgabe) erwartet er eine (leere) Antwort:

Code: Alles auswählen

<?xml version="1.0" ?>
<methodResponse>
  <params>
    <param>
      <value />
    </param>
  </params>
</methodResponse>
Dateianhänge
init_komplett.png
init-Ablauf

Marcel Payne
Beiträge: 14
Registriert: 04.11.2015, 10:35

Re: XML-RPC init

Beitrag von Marcel Payne » 28.02.2016, 14:54

Danke peex.

Das Dokument ist mir bekannt, ja. Allerdings hatte ich noch die Version 1.502 und nicht die aktuelle Version 2.15. Ich sollte doch öfter mal nach neuen Versionen gucken.
In dem Dokument stehen ja 7 Methoden. Brauch ich die alle? Die einzige Methode, die mich erst einmal wirklich interessiert, ist die Event Methode.

Ich nutze aktuell libaries für die Verbindung zu Haussteuerung:

HMRemoting (https://sourceforge.net/projects/hmremoting/)
XML-RPC.Net (http://xml-rpc.net)

In HMRemoting gibt es ein Interface (IRpcServiceHandler) was einige der Methoden aus dem Dokument oben beschreibt.

Code: Alles auswählen

Public Interface IRpcServiceHandler
        Sub [Event](interfaceId As String, address As String, valueKey As String, value As Object)
        Sub NewDevices(interfaceId As String, devices() As IDeviceDescription)
        Sub DeleteDevices(interfaceId As String, devices() As String)

        Function ListDevices(interfaceId As String) As IDeviceDescription()

        Sub UpdateDevice(interfaceId As String, address As String, hint As Integer)
    End Interface
Ebenfalls in der dll wird dieses Interface in einer Klasse implementiert, RpcServiceHandler , von der ich geerbt habe.

Code: Alles auswählen

Public Class UpdateHandler
    Inherits RpcServiceHandler

    Private myDevices As ObservableCollection(Of Device)
    Private myProxy As IHomeMaticProxy
    Private Delegate Sub UpdateDelegate(address As String, valueKey As String, value As Object)

    Public Sub New(devices As ObservableCollection(Of Device), proxy As IHomeMaticProxy)
        myDevices = devices
        myProxy = proxy
    End Sub

    Public Overrides Sub [Event](interfaceId As String, address As String, valueKey As String, value As Object)
        If interfaceId = "CCU2" Then
            System.Windows.Application.Current.Dispatcher.BeginInvoke(New UpdateDelegate(AddressOf UpdateSub), address, valueKey, value)
        End If
    End Sub

    Private Sub UpdateSub(address As String, valueKey As String, value As Object)
        Dim tmpDevice As Device = (From tmpItem In myDevices Where address.StartsWith(tmpItem.Address)).FirstOrDefault
        If tmpDevice IsNot Nothing Then
            tmpDevice.PropertiesChanged(valueKey, value)
        End If
    End Sub
End Class
Das antworten auf die Methoden der Logikschicht übernimmt glaube ich die HMRemoting.dll, genau so wie die Methode listMethods.
Wobei die listMethods ja funktionieren zu scheint, sonst würde ich garkeine Meldung von der CCU bekommen.

Ich habe das Gefühl das die dll nicht aktuell ist und nicht auf alle Methoden, die bereit gestellt werden müssten, reagiert und antwortet.

Gruß
Marcel

Marcel Payne
Beiträge: 14
Registriert: 04.11.2015, 10:35

Re: XML-RPC init

Beitrag von Marcel Payne » 21.04.2016, 20:43

Guten Abend,

so langsam verzweifel ich an dieser Nummer hier. Peex, ich hoffe du kannst mir da etwas genauer weiterhelfen. Ich hab verstanden das ich bei der void Methode "Event" eine Antwort schicken muss, so wie von dir beschrieben:

Code: Alles auswählen

<?xml version="1.0" ?>
<methodResponse>
  <params>
    <param>
      <value />
    </param>
  </params>
</methodResponse>
Macht auch alles Sinn soweit. Meine Methode, die dieses Event aufnimmt und verarbeitet sieht so aus:

Code: Alles auswählen

[XmlRpcExposed]
        public void Event(string interfaceId, string address, string valueKey, object value)
        {
            //Do Something
        }
So damit ich nun eine Antwort an die CCU schicken könnte müsste ich ja einen return befehl (null) ausführen und mein void in einen Typen ändern. Der Typ der zurückgegeben wird.
Ich habe es wirklich mit allem möglichen ausprobiert (object, string, int,...), nichts funktioniert. Und laut deinem methodResponse hat der value ja auch gar keinen Typen.

Nun die alles entscheidende Preisfrage. Wie bekomme ich nun eine passende Antwort an die CCU geschickt?

Sie erwartet einen Response ohne Typen, ich kann in .NET mit Return aber nur antworten, wenn ich einen Typen angebe.

Ich hoffe ihr könnt mir da ein weiteres mal helfen.

Gruß
Marcel

Antworten

Zurück zu „Softwareentwicklung von externen Applikationen“