jens-maus / RaspberryMatic

:house: A feature-rich but lightweight, buildroot-based Linux operating system alternative for your CloudFree CCU3/ELV-Charly 'homematicIP CCU' IoT smarthome central. Running as a pure virtual appliance (ProxmoxVE, Home Assistant, LXC, Docker/OCI, Kubernetes/K8s, etc.) on a dedicated embedded device (RaspberryPi, etc.) or generic x86/ARM hardware.
https://raspberrymatic.de
Apache License 2.0
1.54k stars 188 forks source link

xmlrpc.PutParamset mit COMBINED_PARAMETER funktioniert nicht #1769

Open Baxxy13 opened 2 years ago

Baxxy13 commented 2 years ago

Describe the issue you are experiencing

Die COMBINED_PARAMETER diverser IP-Aktoren eignen sich gut um mehrere Befehle in einem Rutsch zu übertragen. (z.B. EINschalten mit EINschaltdauer)

Jetzt ist mir aufgefallen das xmlrpc.PutParamset angewandt auf einen COMBINED_PARAMETER - Datenpunkt nicht funktioniert und eine Fehlermeldung wirft.

Als Testobjekt dient Kanal:3 einer HmIP-PSM:

EINschalten über Datenpunkt STATE geht:

object interface = dom.GetObject("HmIP-RF");
xmlrpc.PutParamset(interface,"0001D3C99CA0D2:3","VALUES","STATE","true");

EINschalten über Datenpunkt COMBINED_PARAMETER geht nicht:

object interface = dom.GetObject("HmIP-RF");
xmlrpc.PutParamset(interface,"0001D3C99CA0D2:3","VALUES","COMBINED_PARAMETER","S=true");

Describe the behavior you expected

Idealerweise ließe sich auch der COMBINED_PARAMETER mittels xmlrpc.PutParamset setzen.

Steps to reproduce the issue

  1. Aktor mit COMBINED_PARAMETER rauspicken
  2. obiges Script anpassen und testen
  3. Fehlermeldungen im Logfile sehen ...

What is the version this bug report is based on?

3.61.7.20220318 - Nightly

Which base platform are you running?

rpi3 (RaspberryPi3)

Which HomeMatic/homematicIP radio module are you using?

RPI-RF-MOD

Anything in the logs that might be useful for us?

Mar 20 14:11:43 RM-Test-Pi3Bplus-27 local0.warn ReGaHss: WARNING: XMLRPC 'putParamset': rpcClient.isFault() failed (url: xmlrpc://127.0.0.1:32010, params: {"0001D3C99CA0D2:3","VALUES",[COMBINED_PARAMETER:nil]}, result: [faultCode:-5,faultString:"Invalid parameter or value"]) [CallXmlrpcMethod():iseXmlRpc.cpp:2608]
Mar 20 14:11:43 RM-Test-Pi3Bplus-27 local0.err ReGaHss: ERROR: XMLRPC 'putParamset' call failed (interface: 1009, params: {"0001D3C99CA0D2:3","VALUES",[COMBINED_PARAMETER:nil]}) [CallPutParamset():iseXmlRpc.cpp:1356]

Additional information

Ich habe es auch mit externen Steuerungen wie Homassistant (siehe hier) und auch NodeRed probiert.

NodeRed wirft z.B. folgende Fehlermeldungen aus: unknown paramsetDescription HmIP-RF/HMIP-PS/2.6.2/4/SWITCH_VIRTUAL_RECEIVER/VALUES COMBINED_PARAMETER Error: XML-RPC fault: Invalid parameter or value

Bin mir nicht sicher ob es ein Bug ist, das ganze gar nicht implementiert ist oder ich den Wert falsch übergebe.

Das ganze hat eigentlich keine Relevanz, aber vielleicht wirfst du trotzdem mal irgendwann einen Blick drauf.

jp112sdl commented 2 years ago

Ist PutParamset nicht dafür gedacht, Einstellungen ans Gerät zu senden?

Wäre das Einschalten nicht so? channels.Get ("0001D3C99CA0D2:3").DPByHssDP ("COMBINED_PARAMETER").State("S=true");

Baxxy13 commented 2 years ago

Hmm, ich lese die Beschreibung von putParamset (Doku: HMIP_XmlRpc_API_Addendum) so, das damit alle Parameter in einem Parameter-Set (egal ob MASTER oder VALUES) geschrieben werden können. Also auch "normale" Parameter wie STATE oder ON_TIME. Das klappt ja grundsätzlich auch, nur bei COMBINED_PARAMETER eben nicht.

Lokal auf der Zentrale per (ReGa-) Scriptbefehl (wie von Dir gezeigt) ist das kein Problem den COMBINED_PARAMETER korrekt zu beschreiben.

Externe Anwendungen (Beispiel NodeRED) unterstützen den COMBINED_PARAMETER auf "normalem Wege" (value node, set value node) gar nicht, aber man kann eben auf die universelle rpc node (man wählt die rpc-Methode und übergibt die Parameter) ausweichen. Aber auch mit der funktioniert COMBINED_PARAMETER per putParamset nicht.

Was aber geht ist setValue, damit kommen Homeassistant und auch die (NodeRed) rpc node klar.

jens-maus commented 2 years ago

Externe Anwendungen (Beispiel NodeRED) unterstützen den COMBINED_PARAMETER auf "normalem Wege" (value node, set value node) gar nicht, aber man kann eben auf die universelle rpc node (man wählt die rpc-Methode und übergibt die Parameter) ausweichen. Aber auch mit der funktioniert COMBINED_PARAMETER per putParamset nicht.

Also ohne das ich das jetzt genauer debugged habe, aber über ioBroker scheint das einfache setzen des COMBINED_PARAMETER zu funktionieren. Dort kann ich im Objektbaum einfach S=true eingeben und schwubs wird der Schalter angeschalten. Nun weiss ich aber natürlich nicht über welche Methoden (xmlrpc oder anders) das in ioBroker gemacht wird. Meine Vermutung ist aber (weil das im Kontext des hm-rpc adapters stattfindet), das es dort in der Tat via xmlrpc passiert und das zeigt das es prinzipiell gehen muss. Ggf. muss man jedoch da irgendwas "escapen" oder so ähnlich. Aber vllt. probierst du es mal selbst via ioBroker zu debuggen.

Baxxy13 commented 2 years ago

Ich denke ioBroker nutzt für Statusänderungen setValue, zumindest liest sich das hier so: Custom commands

Set a value, like the adapter does on stateChange:

sendTo('hm-rpc.1', 'setValue', {ID: '000453D77B9EDF:1', paramType: 'SET_POINT_TEMPERATURE', params: 15}, res => {
log(JSON.stringify(res));
});

setValue funktioniert ja auch mit Homeassistant und NodeRed.

Es gibt auch ein Beispiel für putParamset, aber ich bekomme weder das noch setValue über ein Java-Script zum laufen. Komme also nicht so recht voran.

Sineos commented 2 years ago

Das hat bei mir in Node-Red funktioniert: https://github.com/rdmtc/node-red-contrib-ccu/issues/142#issuecomment-761031770

Zumindest als ich das das letzte Mal getestet habe.

Baxxy13 commented 2 years ago

Nunja, putParamset funktioniert auch bei allen von mir getesteten änderbaren Datenpunkten / Werten... außer eben bei COMBINED_PARAMETER bei IP-Aktoren.

Kannst du aber gerne mal testen wenn du z.B. PS/PSM/BSL (mit COMBINED_PARAMETER) usw. hast.

Baxxy13 commented 2 years ago

Also der ioBroker packt das auch nicht mit putParamset und COMBINED_PARAMETER

sendTo('hm-rpc.1', 'putParamset', {ID: '00021A498A4C88:3', paramType: 'VALUES', params: {'COMBINED_PARAMETER': 'S=true,OT=23'}}, res => {
    log(JSON.stringify(res));
});

19:30:44.520 | info | javascript.0 (6644) script.js.Skript_7: {"error":{"code":-5,"faultCode":-5,"faultString":"Invalid parameter or value"}}

Möglicherweise muss tatsächlich der String irgendwie escaped werden, da muss ich aber passsen. Oder putParamset wurde nicht an COMBINED_PARAMETER angepasst und funktioniert damit schlicht nicht weil halt ein String übergeben werden muss und nicht wie üblicherweise BOOLEAN / INTEGER / REAL.

jens-maus commented 2 years ago

Gibt es denn sowas wie COMBINED_PARAMETER nur bei HmIP? Weil ich könnte mir gut vorstellen das das ein Bug bzw. Limitation der Legacy XMLRPC schnittstelle im HmIPServer ist. Wenn man also einen Fall finden könnte wo solch ein string-basierter Parameter via xmlrpc an rfd/bidcos oder hs485d geschickt werden kann, dann hätte man dafür ein Ansatzpunkt.

Baxxy13 commented 2 years ago

Da fällt mir aktuell nur der SUBMIT vom HM-Dis-EP-WM55 ein. Da wird auch String etwa so... 0x02,0x0A,0x12,0x49,0x4E,0x3A,0x20... übergeben. Muss ich mal schauen ob das per putParamset geht. Der COMBINED_PARAMETER wurde ja auch erst nach und nach bei diversen Geräten eingeführt und hat es bisher nicht mal in die offizielle HmIP_Device_Documentation geschafft.

Baxxy13 commented 2 years ago

Also, der SUBMIT vom HM-Dis-EP-WM55 lässt sich via putParamset mit einem String beschreiben. Das klappt mit ioBroker und Homeasistant, mit HM-Script bekomme ich es nicht hin. Vermutlich wieder so eine Escaping-Geschichte. Beispiel aus ioBroker:

sendTo('hm-rpc.0', 'putParamset', {ID: 'NEQ1463378:3', paramType: 'VALUES', params: {'SUBMIT': '0x02,0x0A,0x12,0x49,0x4E,0x3A,0x20,0x32,0x32,0x2C,0x30,0x5e,0x43,0x0A,0x12,0x54,0x6F,0x72,0x3A,0x20,0x7A,0x75,0x13,0x83,0x0A,0x12,0x4F,0x75,0x74,0x3A,0x20,0x36,0x2C,0x35,0x5e,0x43,0x0A,0x14,0xC0,0x1C,0xD1,0x1D,0xE0,0x16,0xF0,0x03'}}, res => {
    log(JSON.stringify(res));
});
jp112sdl commented 2 years ago

Ich hab ja nur ein PCBS in meinem HmIP Fuhrpark. Aber wenn ich auf dem mal ein getParamset für VALUES und für MASTER mache, sehe ich beim ersten nix mit COMBINED_PARAMETER:

echo 'load tclrpc.so; puts [xmlrpc xmlrpc://127.0.0.1:32010/ getParamset [list string "000457098CEFA9:3"] [list string "VALUES"]  ]' |tclsh
PROCESS 0 SECTION 2 SECTION_STATUS 0 STATE 1

echo 'load tclrpc.so; puts [xmlrpc xmlrpc://127.0.0.1:32010/ getParamset [list string "000457098CEFA9:3"] [list string "MASTER"]  ]' |tclsh
COMBINED_PARAMETER {"S=true"} LOGIC_COMBINATION 1 POWERUP_JUMPTARGET 1 POWERUP_ONDELAY_UNIT 0 POWERUP_ONDELAY_VALUE 0 POWERUP_ONTIME_UNIT 0 POWERUP_ONTIME_VALUE 0

VALUES kann (beim PCBS) nur STATE. MASTER kann COMBINED_PARAMETER

Baxxy13 commented 2 years ago

Hmm, klappt leider auch nicht mit MASTER als paramset_key.

sendTo('hm-rpc.1', 'putParamset', {ID: '00021A498A4C88:3', paramType: 'MASTER', params: {'COMBINED_PARAMETER': 'S=true,OT=22'}}, res => {
    log(JSON.stringify(res));
}); 

23:00:43.524 | info | javascript.0 (6644) script.js.Skript_8: {"error":{"code":-5,"faultCode":-5,"faultString":"Invalid parameter or value"}}

Da ist was faul und ich bin kurz vor'm aufgeben. Glücklicherweise geht's ja mit setValues.

jp112sdl commented 2 years ago

Und wenn du '{S=true,OT=22}' übergibst?

Baxxy13 commented 2 years ago

Keine Chance, selber Fehler wie eins über dir bei MASTER und VALUES.

jens-maus commented 1 year ago

@Baxxy13 Kannst du mal bitte schauen ob das Problem hier inzwischen in den aktuellen nightly builds bereinigt wurde von eQ3?

Baxxy13 commented 1 year ago

Da hat sich erstmal nichts geändert. Aber es ist eher ein User-Problem und hat irgendwie mit dem Escaping zu tun. Black hatte mir mal ein funktionierendes Beispiel mit dem SDV generiert:

!- PutParamset Zuweisung vom SDV V4.09.04F LCL für Gerät: HmIP-PSM
string stdErr=""; string stdOut="";
string TCL="";
TCL= TCL # " {COMBINED_PARAMETER {string {S=true,OT=30}}}"; !- DatenTyp Integer beachten, Aufzählung: 0=OFF 1=ON_DELAY 2=ON 3=OFF_DELAY

object oCHANNEL= dom.GetObject (ID_CHANNELS).Get ("HMIP-PSM 0D2 Kanal :3 - Schaltaktor");
object oIFace= dom.GetObject (oCHANNEL.Interface () );
string sTCL= ^puts [xmlrpc ^ #oIFace.InterfaceUrl()# ^/ putParamset [list string \"^#oCHANNEL.Address()#^\"] [list string \"VALUES\"] [list struct \"^#TCL#^\"]]^;
system.Exec ("/bin/sh -c 'echo \"load tclrpc.so; " # sTCL # "\" |tclsh'",&stdOut,&stdErr);

Es ist also möglich COMBINED_PARAMETER per xmlrpc.PutParamset zu übergeben.

string sTCL sieht dann so aus: puts [xmlrpc xmlrpc://127.0.0.1:32010/ putParamset [list string \"0001D3C99CA0D2:3\"] [list string \"VALUES\"] [list struct \" {COMBINED_PARAMETER {string {S=true,OT=30}}}\"]]

Ich hab's aber bisher nicht geschafft das selbst so zu escapen das es mit dem obigen 2-Zeiler läuft.