ECMDDevice Frage zu Rückgabewert

Begonnen von texel, 07 Oktober 2016, 18:48:34

Vorheriges Thema - Nächstes Thema

texel

Hallo,

das ECMDDevice funktioniert bei meiner EBUS Steuerung mittlerweile sehr gut.

Allerdings hänge ich momentan an einer Stelle. Ich möchte per Set-Befehl eine Temperatur setzen. Dies wird auch ausgeführt - allerdings wird das Kommando vom eBus mit "done" bestätigt. Wie bekomme ich nun nach dem Set-Befehl die gesetzte Temperatur in das State (bzw. Value) reading?

fhem.cfg:
define Hc1DayTemp ECMDDevice Hc1DayTemp.class Hc1DayTemp
attr Hc1DayTemp IODev EBUS
attr Hc1DayTemp group Vaillant
attr Hc1DayTemp room Vaillant


class-datei:
#!/usr/bin/perl

params ucmd

get value cmd {"r -f %ucmd\n"}
get value expect "\d+\.\d+\n\n"
get value postproc { Vaillant_Split_5_1("1;".$_); }
set value postproc {\
my $hash  = $defs{%NAME};\
readingsSingleUpdate($hash, "state", $_, 1);\
readingsSingleUpdate($hash, "value", $_, 1);\

}




# state value

set value cmd {"w -c 470 %ucmd %temp1\n"}
set value params temp1
set value expect "done\n\n"
# set value postproc { $_ }
set value postproc {\
my $hash  = $defs{%NAME};\
my $temperature = $temp1;\
readingsSingleUpdate($hash, "value", $temperature, 1);\
readingsSingleUpdate($hash, "state", "%temp1", 1);\
}


reading value match "\d+\.\d+"
reading value postproc { $_ }


Bei readingsSingleUpdate habe ich schon alle möglichen Parameter getestet. Bei obigem Beispiel, kommt nun die Fehlermeldung
value Global symbol "$temp1" requires explicit package name at (eval 104) line 1.

Kennt jemand einen Weg, um einfach den Wert, der bei Set reinkommt auch anschliessend in die readings zu schreiben (elegant wäre natürlich, wenn nur in die readings geschrieben wird, wenn der Rückgabewert "done" ist).

Viele Grüße,

Texel

Reinhart

#1
Hallo Texel!

eigentlich gibt es schon genug Beispiele über das Handling von ECMD Devices speziell für den eBus, aber ich möchte dir das hier noch kurz erklären.

Beispiel Heizkurve vom eBus auslesen:
# Heizkurve lesen
get HKurve cmd {"r -f Hc1HeatCurve\n"}
get HKurve expect "\d+\.\d+\n"
get HKurve postproc { sprintf("%3.1f",$_) }

im "state" steht dann "HKurve xx"

attr HKurve stateFormat state
wenn du nur "xx" in state haben willst musst du ihn noch mit stateFormat in den state kopieren, das erspart das splitten.

Beispiel Heizkurve setzen:
# HeizkurveSchreiben
get HeizkurveSchreiben cmd {"write -c 430 Hc1HeatCurve ".Value("HeizkurveEinstellen")."\n"}
get HeizkurveSchreiben expect ".*\n\n"
get HeizkurveSchreiben postproc  { $_ }


wenn du nun wissen willst was nun tatsächlich im eBus Register steht, dann frag doch einfach nach ein paar Sekunden wieder ab (nicht sofort, weil der eBus ein bisschen braucht um den Wert in das Register zu schreiben). Das ist die einzige sichere Methode um wirklich die Bestätigung zu bekommen das der Wert auch tatsächlich gesetzt wurde.

define HeizkurveEinstellen dummy
attr HeizkurveEinstellen group Heizkurve_Einstellen
attr HeizkurveEinstellen icon temp_control
attr HeizkurveEinstellen room Vaillant,Heizung
attr HeizkurveEinstellen setList state:0.20,0.40,0.50,0.60,0.70,0.80,0.90,1.00,1.10,1.20,1.30,1.40,1.50,1.60,1.70
attr HeizkurveEinstellen stateFormat state
attr HeizkurveEinstellen webCmd state

define HeizkurveSchreiben_Click notify HeizkurveEinstellen {\
  fhem("get HeizkurveSchreiben HeizkurveSchreiben");;\
  fhem("define Pause1 at +00:00:02 get HKurve HKurve");;\
  fhem("define Pause2 at +00:00:04 get VorlaufSoll VorlaufSoll");;\
  fhem("define Pause3 at +00:00:06 get VorlaufSoll VorlaufSoll");;\
}
attr HeizkurveSchreiben_Click room Vaillant

nachdem der Wert nun geschrieben wurde, wird über den notify der Wert nochmals aus dem eBus gelesen. Zuerst nach 2 Sekunden die HKurve, dann nach weiteren 2 Sekunden der VorlaufSoll 2 x zeitversetzt weil dieser fast 6 Sekunden braucht bis der neue Sollwert im Register landet.

Sieh dir dazu einfach den Thread "eBus Schaltung in Betrieb nehmen!" genauer an, da wird alles mit Beispielen (zum rauskopieren) genau beschrieben. Auch gibt es im Wiki genug Beispiele oder benutze den automatischen Installer (der installiert die Basispakete inkl. aller notwendiger Konfigurationen).

LG
Reinhart
FHEM auf Raspy4 mit Bullseye + SSD, Homematic, ESP8266, ESP32, Sonoff, eBus, NanoCUL, MapleCUL, , MQTT2, Alexa

texel

Hallo Reinhart,

danke für die schnelle Antwort und die ausführlichen Beispiele. Diese funktionieren auch bei mir. Ich habe nur versucht, das Coding etwas zu optimieren (eben ohne notify, und ohne zwei Definitionen (Lesen, Schreiben)). Das funktioniert z.B. im Falle des Heizmodus setzen sehr gut:


# Hc1 operation mode
get value cmd {"r -f Hc1OPMode\n"}
get value expect "(summer|on|night|auto)\n\n"
get value postproc { $_ }

state value

set summer cmd {"w -c 470 Hc1OPMode summer\n"}
set summer expect "done\n\n"
set summer postproc {\
my $hash  = $defs{%NAME};\
readingsSingleUpdate($hash, "value", "summer", 1);\
readingsSingleUpdate($hash, "state", "summer", 1);\
}

set on cmd {"w -c 470 Hc1OPMode on\n"}
set on expect "done\n\n"
set on postproc {\
my $hash  = $defs{%NAME};\
readingsSingleUpdate($hash, "value", "on", 1);\
readingsSingleUpdate($hash, "state", "on", 1);\
}

set night cmd {"w -c 470 Hc1OPMode night\n"}
set night expect "done\n\n"
set night postproc {\
my $hash  = $defs{%NAME};\
readingsSingleUpdate($hash, "value", "night", 1);\
readingsSingleUpdate($hash, "state", "night", 1);\
}

set auto cmd {"w -c 470 Hc1OPMode auto\n"}
set auto expect "done\n\n"
set auto postproc {\
my $hash  = $defs{%NAME};\
readingsSingleUpdate($hash, "value", "auto", 1);\
readingsSingleUpdate($hash, "state", "auto", 1);\
}

reading value match "summer|on|night|auto"
reading value postproc { $_ }


Unterschied zu meinem Fall ist, dass der Wert beim "Set" vordefiniert ist (bspw. wenn "set auto" angefragt wird setzt die klassendefinition fix "auto" in state und value).

Aber gut, falls es keine Lösung gibt, den zu setzenden Wert direkt in value und state zu schreiben kann ich auch das Coding aus den Beispielen verwenden ...

Danke und viele Grüße,

Texel



jkriegl

#3
Ich unterscheide zwischen get und set ECMD-Befehlen, Beispiel
# Ferientemperatur
get T.Ferien cmd {"r -f RoomTempHoliday\n"}
get T.Ferien expect ".*\n\n"
get T.Ferien postproc { sprintf("%.1f",$_) }

set T.Ferien cmd { "w -c ui RoomTempHoliday %temp\n" }
set T.Ferien params temp
set T.Ferien expect "done\n"
set T.Ferien postproc { $_ }

In fhem wird get und set angezeigt. Im set steht das aktuelle reading das ich übertippe.
Zum Aktualisieren verwende ich ein notify
HK.Hz:T.Ferien.* get HK.Hz T.Ferien if ($EVPART1 ~= "done")

edit: es gibt im Forum eine Anfrage um im postproc etwas anderes zurückzugeben z.B. wenn alles geklappt hat, den gesetzten Wert (temp) zu übergeben. Nach meiner Erimmerung gibt es einen Patch dazu. Müsste suchen.
Rpi 3/4, buster, Fhem, Cul 868, HM-CC-RT-DN, HM-Sec-Sco, HM-ES-PMSw1-Pl, ebus (Vaillant), ECMD, Telegram, HTTPMOD, Xiaomi, Shelly

texel

Hallo jkriegl,

Danke für den Hinweis. Dann gehe ich mal auf die Suche nach dem Patch ..

VG. Texel.

texel

Hi,

besten Dank nochmal für den Hinweis.

Habe den Thread gefunden:
https://forum.fhem.de/index.php?topic=36252.0

Das Einfügen von
$postproc= ECMDDevice_ReplaceSpecials($postproc, %specials);

nach folgendem Befehl

$ecmd= ECMDDevice_ReplaceSpecials($ecmd, %specials);

in Sub ECMDDevice_Set und ECMDDevice_Get der Datei 67_ECMDDevice.pm wie von afloria vorgenommen löst genau das Problem.

--> Frage an Boris: Wäre es möglich dies in den Standard zu übernehmen?

Danke und VG, Texel

texel

Hallo nochmal,

habe gerade gesehen, dass das neueste Update diese Änderung bereits enthält.  :D

Fazit: Funktioniert alles bestens und updaten hilft manchmal...

LG Texel