[gelöst]Ablaufsteuerung mit Perl, wie?

Begonnen von matze1999, 17 Juni 2022, 10:22:37

Vorheriges Thema - Nächstes Thema

matze1999

Hallo,

mal eine Frage an die Experten, wie realisiert man am Besten eine Ablaufsteuerung.

Beispiel:

Ein Ventil soll abhängig von einer Vorgabe 1 - 5 mal für 2 Min öffnen und dann für eine  übergebene Zeit offen bleiben, danach noch einmal 2 - 6 mal für 2 min öffnen.

Hintergrund, ich habe einen Gardena Verteiler, wenn ich dort einzelne Stränge ansprechen möchte, muss ich die vorhergehenden für min. 2 Min öffnen, damit per Wasserdruck weiter geschaltet wird, am Ende muss ich dann wieder in die Ausgangsposition "fahren".

Ich möchte das gern automatisieren per Zeitsteuerung, aber auch die manuelle Auswahl eines Stranges und der benötigten Bewässserungszeit realisieren.

Meine ersten Gedanken waren, die Weiterschaltung mit "Blink" zu realisieren, danach dann das Ventil für die übergebene Zeit öffnen, und danach per Blink in die Ausgangspos. zurück fahren. Mein Problem ist das"danach" in FHEM zu realisieren.

Leider weiss ich nicht so recht, wie ich das in fhem mache.

matze1999

Beta-User

Vorschlag:
defmod Beregnung dummy
attr Beregnung readingList 1 2 3 4 5 6
attr Beregnung setList 1:selectnumbers,10,10,60,0,lin 2:selectnumbers,10,10,60,0,lin 3:selectnumbers,10,10,60,0,lin 4:selectnumbers,10,10,60,0,lin 5:selectnumbers,10,10,60,0,lin 6:selectnumbers,10,10,60,0,lin
attr Beregnung webCmd :

defmod n_Beregnung notify Beregnung:.* {\
my @times;;\
my $read = $EVTPART0;;\
chop $read;;\
for my $nr (1..6){\
    if ( $nr ne $read ) {\
           $times[$nr] = 180;;\
    } else {\
           $times[$nr] = $EVTPART1*60;;\
    }\
}\
my $slp = q{sleep 300 HUEDevice8 quiet};;\
fhem("set HUEDevice8 on-for-timer $times[1];;$slp;;set HUEDevice8 on-for-timer $times[2];;$slp;;set HUEDevice8 on-for-timer $times[3];;$slp;;set HUEDevice8 on-for-timer $times[4];;$slp;;set HUEDevice8 on-for-timer $times[5];;$slp;;set HUEDevice8 on-for-timer $times[6]");;\
}

Hinweise:
- der dummy hat gleich entsprechende Minuten-setter, damit muss dann aber der Doppelpunkt aus dem $EVTPART0 (=>chop)
- die sleep-Anweisung ist benannt, dann kann man die notfalls auch abbrechen (siehe https://forum.fhem.de/index.php/topic,128070.0.html), muss sich dann aber "irgendwo" merken, auf welcher Stufe man war.

(Irgendwie scheinen grade die Bewässerungscodes aus dem Boden zu schießen, siehe auch https://forum.fhem.de/index.php/topic,128087.msg1225451.html#msg1225451).

Das mit den arrays musst du dir nochmal ansehen, und Doppelposts sind nicht gerne gesehen (https://forum.fhem.de/index.php/topic,128110.0.html), ganz davon abgesehen, dass das andere keinen "aussagekräftigen Titel" hat und insgesamt eher in der "Perl für FHEM-User"-Ecke aufgehoben wäre (da gibt es auch bereits einige Infos zum Umgang mit arrays!)...

Ups, der andere Beitrag war doch vorhin noch Teil von diesem Post :o ...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

Zitatund Doppelposts sind nicht gerne gesehen

Ups, der andere Beitrag war doch vorhin noch Teil von diesem Post :o ...

ich hatte zwischendurch einen neuen Thread mit eindeutigem Namen gestartet und den mod per PN gebeten diesen Beitrag zu löschen, weil ich nur meine Antworten löschen konnte.

Vielen Dank!

Folgende Fragen hätte ich dazu:

was bedeutet ;;\
und chop $read;;\
und vor allem
my $slp = q{sleep 300 HUEDevice8 quiet};;\

matze1999

matze1999

... folgende Fehlermeldung beim anlegen des notify:

Experimental aliasing via reference not enabled at (eval 11107) line 1.

matze1999

Beta-User

Die Formatierung ist für RAW-Import gedacht, da kommst dann sowas her:;;\

"chop" ist ein Befehl, um das letzte Zeichen zu entfernen (Event-Monitor beim Setzen über meine dummy-Version anschauen).
das mit dem "q" ist eine spezielle Form eines einfachen Anführungszeichens, siehe https://www.perlmonks.org/?node_id=401006.
Wollte mir Schreibarbeit sparen :) .

Was "hinten rauskommt", kannst du auch bequem mit einem Log-Befehl (statt fhem()) rausfinden ;) .

Zitat von: matze1999 am 20 Juni 2022, 13:01:56
... folgende Fehlermeldung beim anlegen des notify:

Experimental aliasing via reference not enabled at (eval 11107) line 1.
a) wie legst du den an? RAW-Import?
b) welche Perl-Version ist das bei dir? (ich hatte das unter aktuellem FHEM+Perl 5.32 getestet).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

#5
Hallo,

ich hab das defmod komplett kopiert und in der Kommandozeile von fhem ausgeführt?

meine Perl Version: v.5.32.1
fhem version: 26155

ich hab jetzt mal über den eventmonitor ein notify angelegt udn das ganze o.g. komplett dort in der def eingetragen, sicher muss ich da so was wie ;;\ "übersetzemn"

/edit on

damit gehts jetzt

/edit off
matze1999

Beta-User

Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

#7
noch nicht, sleep soll ja immer um 120 sec länger sein als der on-for-timer Wert, weil es sich sonst "überholt":
also das nächste on-for-timer soll 120 sec nach dem letzten on-for-timer aufgerufen werden.

matze

Beta-User

#8
Zitat von: matze1999 am 20 Juni 2022, 13:41:04
noch nicht, sleep soll ja immer um 120 sec länger sein als on-for-timer, weil es sich sonst "überholt":
also das nächste on-for-timer soll 120 sec nach dem letzten  on-for-timer aufgerufen werden.

matze
Anleitung: Bastel ein zweites Array für die sleep-Anweisungen (statt des festen Werts) und fülle auch das innerhalb der for-Schleife ;) .

Wenn du einen Versuch gemacht hast, schaue ich es mir gerne an, bitte als RAW posten (ganz unten in der Detailansicht).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

#9
so mag ich das ;-)

so hab ich es jetzt, und es geht nicht:
defmod Beregnung_notify_1 notify Beregnung:.* {\
my @times;;\
my @wait;;\
my @slp;;\
\
\
my $read = $EVTPART0;;\
chop $read;;\
for my $nr (1..6){\
    if ( $nr ne $read ) {\
           $times[$nr] = 180;;\
           $wait[$nr] = $times[$nr]+120;;\
           $slp[$nr] = q{sleep $wait[$nr] MQTT2_DVES_6C3AB1_CH2 quiet};;\
    } else {\
           $times[$nr] = $EVTPART1*60;;\
           $wait[$nr] = $times[$nr]+120;;\
           $slp[$nr] = q{sleep $wait[$nr] MQTT2_DVES_6C3AB1_CH2 quiet};;\
    }\
}\
fhem("set MQTT2_DVES_6C3AB1_CH2 on-for-timer $times[1];;$slp[1];;set MQTT2_DVES_6C3AB1_CH2 on-for-timer $times[2];;$slp[2];;set MQTT2_DVES_6C3AB1_CH2 on-for-timer $times[3];;$slp[3];;set MQTT2_DVES_6C3AB1_CH2 on-for-timer $times[4];;$slp[4];;set MQTT2_DVES_6C3AB1_CH2 on-for-timer $times[5];;$slp[5];;set MQTT2_DVES_6C3AB1_CH2 on-for-timer $times[6]");;\
}


matze1999

Beta-User

Klar, dass es nicht geht :P , schau nach "Quotes in Perl" und dem Unterschied zwischen "q" und "qq"

Würde mal das hier ins Rennen werfen:
defmod Beregnung_notify_1 notify Beregnung:.* {\
my @times;;\
my $wait;;\
my @slp;;\
\
my $read = $EVTPART0;;\
chop $read;;\
for my $nr (1..6){\
    if ( $nr ne $read ) {\
           $times[$nr] = 180;;\
    } else {\
           $times[$nr] = $EVTPART1*60;;\
    }\
    $wait = $times[$nr]+120;;\
    $slp[$nr]   = qq{sleep $wait MQTT2_DVES_6C3AB1_CH2 quiet};;\
    $times[$nr] = qq{set MQTT2_DVES_6C3AB1_CH2 on-for-timer $times[$nr]};;\
}\
fhem("$times[1];;$slp[1];;$times[2];;$slp[2];;$times[3];;$slp[3];;$times[4];;$slp[4];;$times[5];;$slp[5];;$times[6]");;\
}
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

hallo,

habe das:

$times[$nr] = qq{set MQTT2_DVES_6C3AB1_CH2 on-for-timer $times[1]};;\

gegen das getauscht  8):

$times[$nr] = qq{set MQTT2_DVES_6C3AB1_CH2 on-for-timer $times[$nr]};;\

und teste jetzt.

matze1999

matze1999


Prof. Dr. Peter Henning

Die ideale Realisierung dieses System wäre mit einem Zustandsautomaten, der als digitaler Zwilling des Verteilers arbeitet. Wir hatten doch mal ein Modul in Arbeit, das beliebige Zustandsautomaten erzeugen können sollte - was ist daraus denn geworden?

Ansonsten würde ich das tatsächlich als Zustandsautomat in Perl realisieren.

LG

pah

Beta-User

Zitat von: Prof. Dr. Peter Henning am 20 Juni 2022, 16:09:34
Die ideale Realisierung dieses System wäre mit einem Zustandsautomaten, der als digitaler Zwilling des Verteilers arbeitet. Wir hatten doch mal ein Modul in Arbeit, das beliebige Zustandsautomaten erzeugen können sollte - was ist daraus denn geworden?
Soweit mir das in Erinnerung ist (war vor meiner Zeit), ist das im Sande verlaufen, am ehesten kommt dem wohl der Modulvorschlag von justme1968 namens "combine" am nächsten.

Zitat
Ansonsten würde ich das tatsächlich als Zustandsautomat in Perl realisieren.
Ich würde vermutlich $SELF bemühen und ein (paar?) Reading(s) an dem notify selbst setzen, damit man zumindest abgespeichert hat, wo das Ding zuletzt stand... Insgesamt ist das aber keine Hardware, die ich mir antun würde, es gibt mit Tobias "Modulfamilie" für die Bewässerung wohl nicht nur passende Software in FHEM, sondern auch Ventilsteuerungslösungen in Hardware (ich habe immer noch ein paar Pearl-Ventile rumliegen, die ich mal mit einem Stepper-Treiber verheiraten und an mein MySensors-Netz anbinden wollte...).

Zitat von: matze1999 am 20 Juni 2022, 14:34:50
gegen das getauscht...
Da warst du zu schnell mit dem Kopieren, das war mir dann auch aufgefallen...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

Hallo,

eine letzte Frage noch:

ich hab jetzt diese definition:

defmod Beregnung.manuell dummy
attr Beregnung.manuell group Schalter-Schalter
attr Beregnung.manuell icon sani_irrigation
attr Beregnung.manuell readingList 1 2 3 4 5 6
attr Beregnung.manuell room Bewässerung,Garten,Schalter
attr Beregnung.manuell setList 1:selectnumbers,10,10,60,0,lin 2:selectnumbers,10,10,60,0,lin 3:selectnumbers,10,10,60,0,lin 4:selectnumbers,10,10,60,0,lin 5:selectnumbers,10,10,60,0,lin 6:selectnumbers,10,10,60,0,lin
attr Beregnung.manuell webCmd 1:2:3:4:5:6


leider kann ich mit diesem webcmd die "10" nicht auswählen, weil da nicht "ausgelöst" wird, alle anderen Werte funktionieren.

Weiterhin steht ganz vorn im webif eine "1", und ich weiss nicht wo diese herkommt, und ich hätte vor den DropDown Menüs gerne eien Bezeichnung stehen.

matze1999

Beta-User

#16
Zitat von: matze1999 am 21 Juni 2022, 11:16:36
leider kann ich mit diesem webcmd die "10" nicht auswählen, weil da nicht "ausgelöst" wird, alle anderen Werte funktionieren.
Sobald für das betreffende Reading was anderes ausgewählt war, geht auch die "10".

ZitatWeiterhin steht ganz vorn im webif eine "1", und ich weiss nicht wo diese herkommt,
Schätze, das ist "state"?

Zitat
und ich hätte vor den DropDown Menüs gerne eien Bezeichnung stehen.

Beispiel (auch mit der Option, IsDisabled() abzufragen, siehe meine Anmerkung in https://forum.fhem.de/index.php/topic,128070.msg1225588.html#msg1225588):
defmod Beregnung.manuell dummy
attr Beregnung.manuell group Schalter-Schalter
attr Beregnung.manuell icon sani_irrigation
attr Beregnung.manuell readingList 1 2 3 4 5 6
attr Beregnung.manuell room Bewässerung,Garten,Schalter
attr Beregnung.manuell setList active inactive 1:selectnumbers,10,10,60,0,lin 2:selectnumbers,10,10,60,0,lin 3:selectnumbers,10,10,60,0,lin 4:selectnumbers,10,10,60,0,lin 5:selectnumbers,10,10,60,0,lin 6:selectnumbers,10,10,60,0,lin
attr Beregnung.manuell webCmd 1:2:3:4:5:6
attr Beregnung.manuell webCmdLabel 1:2:3:4:5:6

setstate Beregnung.manuell inactive
setstate Beregnung.manuell 2022-06-21 10:35:52 1 20
setstate Beregnung.manuell 2022-06-21 10:38:05 2 10
setstate Beregnung.manuell 2022-06-21 10:38:14 3 30
setstate Beregnung.manuell 2022-06-21 10:36:47 state inactive


EDIT: Jetzt habe ich das mit dem "nicht auswählen können" auch verstanden, es geht darum, nicht zweimal nacheinander denselben Wert auswählen zu können, um den Prozess zu starten...

So sollte es gehen:
defmod Beregnung.manuell dummy
attr Beregnung.manuell group Schalter-Schalter
attr Beregnung.manuell icon sani_irrigation
attr Beregnung.manuell readingList 1 2 3 4 5 6
attr Beregnung.manuell room Bewässerung,Garten,Schalter
attr Beregnung.manuell setList active inactive 1:slider,10,10,60 2:slider,10,10,60 3:slider,10,10,60 4:slider,10,10,60 5:slider,10,10,60 6:slider,10,10,60
attr Beregnung.manuell webCmd 1:2:3:4:5:6
attr Beregnung.manuell webCmdLabel 1\
:2\
:3\
:4\
:5\
:6

setstate Beregnung.manuell inactive
setstate Beregnung.manuell 2022-06-21 10:56:51 1 10
setstate Beregnung.manuell 2022-06-21 10:57:46 2 10
setstate Beregnung.manuell 2022-06-21 10:38:14 3 30
setstate Beregnung.manuell 2022-06-21 10:36:47 state inactive
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

ZitatEDIT: Jetzt habe ich das mit dem "nicht auswählen können" auch verstanden, es geht darum, nicht zweimal nacheinander denselben Wert auswählen zu können, um den Prozess zu starten...

Nein, eher

Sobald für das betreffende Reading was anderes ausgewählt war, geht auch die "10".

genau, ist die "10" im Dropdown Menü, kann diese nicht ausgewählt werden, erst eine ander Minutenzahl löst aus, aber man kann somit nicht zweimal die gleiche Minutenzahl hintereinander (im Abstand von Tagen) auslösen, sondern muss erst mal eine andere nehmen. Schöner wäre es, wenn standardmäßig, nach einer ausführung z.B. "0" drin stehen würde. Geht so etwas?

matze1999

Beta-User

Zitat von: matze1999 am 21 Juni 2022, 15:52:18
Schöner wäre es, wenn standardmäßig, nach einer ausführung z.B. "0" drin stehen würde. Geht so etwas?
"Prinzipiell" kennst du die Antwort: Ja, geht.
Die dropdown-Liste (oder den slider) zu ergänzen, bekommst du ohne Hilfe hin.

ABER: Wenn du nach dem Ablauf dann wieder ein "setreading" ausführst, hast du wieder einen Event => andere Anweisung (komplizierter), oder du must das "0-Event" gesondert vorab rausfiltern...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

so habe ich die "0" drin

defmod Beregnung.manuell dummy
attr Beregnung.manuell group Schalter-Schalter
attr Beregnung.manuell icon sani_irrigation
attr Beregnung.manuell readingList 1 2 3 4 5 6
attr Beregnung.manuell room Bewässerung,Garten,Schalter
attr Beregnung.manuell setList active inactive 1:selectnumbers,0,10,60,0,lin 2:selectnumbers,0,10,60,0,lin 3:selectnumbers,0,10,60,0,lin 4:selectnumbers,0,10,60,0,lin 5:selectnumbers,0,10,60,0,lin 6:selectnumbers,0,10,60,0,lin
attr Beregnung.manuell webCmd 1:2:3:4:5:6


damit rauscht das notify (hoffentlich) einmal mit min. Werten durch, wenn 0 gewählt wurde.durch

defmod Beregnung_notify_1 notify Beregnung.manuell:.* {\
my @times;;\
my $wait;;\
my @slp;;\
\
my $read = $EVTPART0;;\
chop $read;;\
for my $nr (1..6){\
    if ( $nr ne $read ) {\
           $times[$nr] = 30;;\
    } elsif ( ($nr eq $read) && ($EVTPART1 != 0) ) {\
           $times[$nr] = $EVTPART1*60;;\
    } else { \
           $times[$nr] = 30;;\
    }        \
    $wait = $times[$nr]+300;;\
    $slp[$nr]   = qq{sleep $wait HUEDevice8 quiet};;\
    $times[$nr] = qq{set HUEDevice8 on-for-timer $times[$nr]};;\
}\
fhem("$times[1];;$slp[1];;$times[2];;$slp[2];;$times[3];;$slp[3];;$times[4];;$slp[4];;$times[5];;$slp[5];;$times[6]");;\
}


Leider bekomme ich es irgendwie nicht hin, dass wenn "0" gewählt wurde, das notify einfach beendet wird, um dann neu auszuwählen.

matze1999

matze1999

#20
dann doch lieber so:

defmod Beregnung_notify_1 notify Beregnung.manuell:.* { if ($EVTPART1 != 0) {\
my @times;;\
my $wait;;\
my @slp;;\
\
my $read = $EVTPART0;;\
chop $read;;\
for my $nr (1..6){\
    if ( $nr ne $read ) {\
           $times[$nr] = 30;;\
    } else  {\
           $times[$nr] = $EVTPART1*60;;\
    }        \
    $wait = $times[$nr]+300;;\
    $slp[$nr]   = qq{sleep $wait HUEDevice8 quiet};;\
    $times[$nr] = qq{set HUEDevice8 on-for-timer $times[$nr]};;\
}\
fhem("$times[1];;$slp[1];;$times[2];;$slp[2];;$times[3];;$slp[3];;$times[4];;$slp[4];;$times[5];;$slp[5];;$times[6]");;\
}}\


Damit nach der ausführung wieder die "0" im Dropdown Menü steht, müsste ich jetzt noch irgendwo ein

chop $read;;\
for my $nr (1..6){\
{\
fhem (setreading $nr 0)\
}\


einfügen

matze1999

Beta-User

Zitat von: matze1999 am 21 Juni 2022, 16:22:07
Leider bekomme ich es irgendwie nicht hin, dass wenn "0" gewählt wurde, das notify einfach beendet wird, um dann neu auszuwählen.

Wenn du es in Worten beschreiben kannst, sollte es auch zu vercoden gehen, nämlich genau so - "wenn 0 ausgewählt => mache nichts". Das ist (in der kürzest möglichen Fassung):
return if !$EVTPART1;;\

Komplett mit "reset" am Ende:
defmod Beregnung_notify_1 notify Beregnung.manuell:.* {\
return if !$EVTPART1;;\
my @times;;\
my $wait;;\
my @slp;;\
\
my $read = $EVTPART0;;\
chop $read;;\
for my $nr (1..6){\
    if ( $nr ne $read ) {\
           $times[$nr] = 30;;\
    } elsif ( $nr eq $read ) {\
           $times[$nr] = $EVTPART1*60;;\
    } else { \
           $times[$nr] = 30;;\
    }        \
    $wait = $times[$nr]+300;;\
    $slp[$nr]   = qq{sleep $wait HUEDevice8 quiet};;\
    $times[$nr] = qq{set HUEDevice8 on-for-timer $times[$nr]};;\
}\
fhem("$times[1];;$slp[1];;$times[2];;$slp[2];;$times[3];;$slp[3];;$times[4];;$slp[4];;$times[5];;$slp[5];;$times[6];;setreading $NAME $read 0");;\
}
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

#22
da fehlen mir einfach die Vokabeln in Perl, um meine Ausführungen einfach zu übersetzen:

return if !$EVTPART1;;\

$NAME $read

$NAME ist das Dummy Device? und müsste $read nicht innerhalb der for Schleife stehen und eigentlich hätte nach meinem Verständnis $read nur einen Wert?

Danke!

matze1999

Beta-User

Zitat von: matze1999 am 21 Juni 2022, 16:51:09
da fehlen mir einfach die Vokabeln in Perl, um meine Ausführungen einfach zu übersetzen:
Jo. Deswegen machen wir ja die Vokabelübung hier ;) .

Zitat
$NAME ist das Dummy Device?
Wie $NAME im Kontext von notify interpretiert wird, steht in der ziemlich übersichtlichen commandref zu dem Modul.
Bitte die Vokabel da selbst nachschlagen :P .

Zitat
und müsste $read nicht innerhalb der for Schleife stehen und eigentlich hätte nach meinem Verständnis $read nur einen Wert?
$read wird nur einmal verändert, und ja, es hat genau einen Wert. Die letzte Anweisung heißt übersetzt:
"Setze den Wert des auslösenden Readings nach dem Durchlauf der kompletten 'sleep'-Schleife wieder auf 0".

Du musst das aber nicht dynamisch machen und könntest auch wahllos "alle readings" auf "0" setzen, oder die Zeile ziemlich zu Anfang reinfrickeln, oder...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

noch eine Frage,

könnte ich für ein Ventil über ein elseif die  $wait = $times[$nr]+300;;\ auf  $wait = $times[$nr]+600;;\ erhöhen, wo müsste ich das einfügen sicher nach der Zeile $slp[$nr]   = qq{sleep $wait HUEDevice8 quiet};;\

matze1999

Beta-User

Zitat von: matze1999 am 21 Juni 2022, 21:49:11
sicher nach der Zeile $slp[$nr]   = qq{sleep $wait HUEDevice8 quiet};;\
Wieso denn "nach" dieser Zeile?!? Da ist "der Fisch doch geputzt" (also der _extrapolierte_ Text in das Array geschrieben)...
Das muss selbstverständlich vorher passieren, damit $wait zum Zeitpunkt der Extrapolation den erwünschten Wert hat ;) .

Selbst austesten (statt fhem eine Log-Anweisung?) wäre hilfreich, um in diese Zusammenhänge erst mal reinzufinden. Wenn man das an eher mittel-schwierigen Beispielen wie hier versucht zu lernen, ist das eher suboptimal...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

Hallo,

war nicht mehr nötig, deshalb habe ich es nicht weiter verfolgt, einzelne $wait Zeiten zuzuordnen.

Vielen Dank nochmal

matze1999


matze1999

ich habe mir überlegt, mit der Dokumentation der aktuellen Ventilstellung noch weiter "vorn" anzufangen, nämlich im Ventil Device selbst, dazu habe ich mir folgendes überlegt:

im Ventil Device ein userreading anzulegen, das bei jeder Ventilöffnung eins hoch zählt bis 6 und dann wieder von vorn. Damit hätte ich auch das manuelle Öffnen am Ventil abgefangen.

dieses userreading kann ich dann überall nutzen, um den Zustand abzufragen.

Das muss ich nur noch irgendwie umsetzen.

matze1999


Beta-User

In die Richtung userReadings hatte ich auch erst überlegt, glaube aber zum einen nicht, dass das vorbehaltslos zielführend ist (welche Bedingungen könnten wann geprüft werden?), und zum anderen, dass es nicht hin und wieder nötig sein wird, das manuell auf einen korrigierten Wert zu setzen (was aber ein userReadings nicht ausschließen würde).

Meine Idee wäre gewesen, das vor/bei jeder Anweisung "nimm das nächste Ventil" (= die kurzen "Zwischensleeps"?) per setreading zu setzen, der Ablauf der Frist wäre dann der "trigger" für die nächste Prüfung, ob gleich (überhaupt) weitergeschaltet werden muss, bzw. wie lange dann dieser Kreis bewässert werden soll. So kannst du dann "im Prinzip" endlos weitermachen, bis halt dann wieder alle "solange soll bewässert werden"-Angaben auf allen Kreisen dann "0" sind.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

das ist relativ simple, der Trigger ist der state vom Bewässerungs Device:

nternals:
   DEF        8  IODev=CONBEE
   FUUID      62af1ee1-f33f-214e-00c7-f981d442d0bde8d0
   FVERSION   31_HUEDevice.pm:0.260120/2022-05-01
   ID         8
   INTERVAL   
   IODev      CONBEE
   NAME       HUEDevice8
   NR         472
   STATE      off
   TYPE       HUEDevice
   desired    0
   eventCount 2245
   has_events 1
   lastannounced 2022-06-19T13:11:06Z
   manufacturername _TZ3210_eymunffl
   modelid    TS0101
   name       Bewässerung
   type       Smart plug
   uniqueid   84:ba:20:ff:fe:40:36:40-01
   READINGS:
     2022-06-29 19:24:44   IODev           CONBEE
     2022-06-29 19:24:49   alert           none
     2022-07-01 08:38:05   lastseen        2022-06-29T03:47Z
     2022-07-01 05:27:30   onoff           0
     2022-07-01 05:27:30   pct             0
     2022-07-01 05:22:01   reachable       1
     2022-07-01 05:27:30   state           off
   helper:
     alert      none
     battery    -1
     bri        -1
     colormode 
     ct         -1
     devtype   
     dynamics_status
     effect     
     hue        -1
     lastseen   
     mode       
     on         0
     pct        0
     reachable  1
     rgb       
     sat        -1
     update_timeout -1
     v2effect   
     xy         
     helper:
     json:
       etag       4523f3239def3bf329a852772cb97135
       lastannounced 2022-06-19T13:11:06Z
       lastseen   2022-06-29T03:47Z
       manufacturername _TZ3210_eymunffl
       modelid    TS0101
       name       Bewässerung
       swversion 
       type       Smart plug
       uniqueid   84:ba:20:ff:fe:40:36:40-01
       state:
         alert      none
Attributes:
   IODev      CONBEE
   alexaName  Bewässerung
   alias      Bewässerung
   color-icons 2
   devStateIcon {(HUEDevice_devStateIcon($name),"toggle")} :sani_water_tap
   group      HUEDevice
   icon       sani_sprinkling
   model      TS0101
   room       Bewässerung,Garten,HUEDevice


kann mann perl code in userreadings einbinden (es geht um das "hochzählen bis 6"?

matze1999

Beta-User

Zitat von: matze1999 am 01 Juli 2022, 08:39:54
kann mann perl code in userreadings einbinden (es geht um das "hochzählen bis 6"?
In userReadings MUSS man mit Perl-Code arbeiten, und es gibt auch eine FHEM-Funktion "Each" (nicht: Perl-each!), mit der man sowas umsetzen könnte. Der Haken daran: der aktuelle Index-Wert wird als Internal verwaltet, was bedeutet, dass dieses Spiel von vorne losginge. Da wir es hier aber sowieso "nur" mit Zahlen zu tun haben, wäre der alte Reading-Wert der bessere Zwischenspeicher...

das ist relativ simple, der Trigger ist der state vom Bewässerungs Device:
Der Haken daran: als userReadings-trigger ist das nur dann geeignet, wenn es um _dasselbe_ Device geht.
Da das on/off am Bewässerungs-Device aber sowieso eine Folge aus dem ist, was du in der Bewässerungssteuerung machst, würde ich eher timer-basiert arbeiten, was aber ein Problem ist, wenn jemand das Bewässerungs-Device separat oder manuell/direkt vor Ort schaltet. Daher der Hinweis, dass es eine Möglichkeit geben muss, das wieder gradezuziehen (was wieder gegen eine Each-Lösung spräche bzw. die komplizierter machen würde).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

MadMax-FHEM

#31
Zitat von: matze1999 am 01 Juli 2022, 08:39:54

kann mann perl code in userreadings einbinden (es geht um das "hochzählen bis 6"?

matze1999

Klar, steht doch in der commandref ;)

Zitat von: https://fhem.de/commandref_DE.html
userReadings
Komma getrennte Liste von benutzerdefinierten Readings. Jede Definition hat folgendes Format:

    <reading>[:<trigger>] [<modifier>] { <perl code> }

Diese benutzerdefinierte Readings werden bei jeder Aktualisierung der Gerätereadings gesetzt, indem das spezifizierte perl code { <perl code> } ausgeführt wird, und dessen Wert dem Reading zugewiesen wird. Falls <trigger> spezifiziert ist, dann findet diese Ausführung nur dann statt, falls einer der aktualisierten Readings dem regexp <trigger> entspricht (matched).
Beispiele:

    attr myEnergyMeter userReadings energy { ReadingsVal("myEnergyMeter","counters.A",0)/1250.0;; }
    attr myMultiMeter userReadings energy1:counters.A.* {ReadingsVal("myMultiMeter","counters.A",0)/1250.0}, energy2:counters.B.* {ReadingsVal("myMultiMeter","counters.B",0)/1250.0}


<modifier> kann die folgenden Werte haben:

    none: als ob man es gar nicht spezifiziert hätte.
    difference: das Reading wird auf die Differenz zw. dem aktuellen und dem vorherigen Wert gesetzt.
    differential: das Reading wird auf die Differenz zw. dem aktuellen und dem vorherigen Wert, geteilt durch die Sekunden zw. der aktuellen Zeit und der letzten Auswertung, sekundengenau. Kein Wert wird berechnet, falls der Unterschied unter eine Sekunde liegt.
    integral: das Gegenteil von differential. Das Ergebnis wird um das Produkt aus der Zeit-Differenz und der Durschnittswert der letzten zwei Readings erhöht.
    result += (time - timeold) * (oldval + value) / 2
    offset: wenn der aktuellen Wert kleiner als der vorherige Wert ist wird der vorherige Wert zum Reading addiert. Das Reading kann dann als offset verwendet werden um einen Zähler der durch Sromverlust zurückgesetzt wird zu korrigieren.
    monotonic: wenn die Differenz zw. dem aktuellen und dem vorherigen Wert positiv ist wird diese Differenz zum Reading addiert. Damit lässt sich von einem Zähler der bei Stromverlust zurückgesetzt wird ein monoton wachsender Zähler ableiten.

Beispiel:

    attr myPowerMeter userReadings power differential { ReadingsVal("myPowerMeter","counters.A",0)/1250.0}

Achtung:

    Falls difference oder differential spezifiziert ist, dann werden für die Berechnung ältere Werte benötigt, d.h. der Wert wird frühestens beim zweiten Änderung gesetzt.
    der Name der definierten Readings besteht aus alphanumerischen Zeichen, Unterstrich (_) und Minus-Zeichen (-).


Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

matze1999

So, erster versuch, funktioniert nicht:

defmod Ventilstellung.nt notify MQTT2_DVES_6C3AB1_CH2:.* {\
return if !$EVENT;;\
my @ventil;;\
\
    if ( $EVENT eq "on" && @ventil eq 6 ) {\
           @ventil = 1;;\
    } elsif ( $EVENT eq "on" && @ventil < 6 ) {\
           @ventil = @ventil + 1;;\
    } \
fhem("setreading MQTT2_DVES_6C3AB1_CH2 ventilnr @ventil");;\
;;\
}
attr Ventilstellung.nt room Bewässerung,Garten,nt+di

setstate Ventilstellung.nt active
setstate Ventilstellung.nt 2022-07-03 12:27:54 state active
setstate Ventilstellung.nt 2022-07-03 12:25:46 triggeredByDev MQTT2_DVES_6C3AB1_CH2
setstate Ventilstellung.nt 2022-07-03 12:25:46 triggeredByEvent on


Damit @ventil auch ausserhalb der Routine verfügbar ist habe ich in 99_myUtils.pm

das eingefügt:


# Enter you functions below _this_ line.

use vars qw(@ventil);
@ventil = 1;
l

Ich hab erst mal ein notify geamcht, um das mit einer Lampe zu testen.

matze1999

Beta-User

Zitat von: matze1999 am 03 Juli 2022, 12:32:43
So, erster versuch, funktioniert nicht:
Hast du im Log geschaut, was fhem.pl dazu "anmeckert"?

Lese-/Such-Tipp: Perl Data Types.
Du willst keine Liste (Array) haben, sondern einen einzelnen Wert (Scalar)...

ZitatDamit @ventil auch ausserhalb der Routine verfügbar ist habe ich in 99_myUtils.pm
Mehrfach ungeschickter Ansatz:
- Variablennamen im Main-Kontext sollten unverwechselbar sein. Meine Empfehlung wäre (hier aber nicht!) irgendeinen "Präfix" davor zu machen, aus dem sich ergibt, dass das von User-Seite her kommt (myActiveValveNr)
- Es gibt aber bessere Varianten, um innerhalb FHEM Daten zwischenzuspeichern:
-- Readings (!). Das ist m.E. der richtige Weg für einzelnen Scalar, v.a. dann, wenn der Wert eigentlich irgendwo an ein FHEM-Device gehört (wie hier)...
-- %data. Kann auch genutzt werden für komplexere Datenstrukturen. Ist aber nach meinem Eindruck eher selten, dass man das wirklich braucht...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

neuer Versuch, funktioniert erst mal:

defmod Ventilstellung.nt notify MQTT2_DVES_6C3AB1_CH2:on {\
my $ventil = ReadingsVal("Ventilstellung.nt","ventilnr",0);;\
\
\
    if ( $ventil ne 6 ) {\
           $ventil = $ventil + 1;;\
    } elsif ( $ventil eq 6 ) {\
           $ventil = 1;;\
    } \
fhem("setreading Ventilstellung.nt ventilnr $ventil");;\
;;\
}


Irgendwas, was ich übersehen habe?

matze1999

matze1999

So, jetzt wollte ich das als userreading in das eigentliche Devce rein bringen:

attr HUEDevice8 userReadings HUEDevice8:off {\
my $ventil = ReadingsVal("HUEDevice8","VentilNr",1);;\
\
\
    if ( $ventil ne 6 ) {\
           $ventil = $ventil + 1;;\
    } elsif ( $ventil eq 6 ) {\
           $ventil = 1;;\
    } \
fhem("setreading HUEDevice8 VentilNr $ventil");;\
;;\
}


Dann kommt aber folgende Fehlermeldung im Log:

2022.07.03 15:44:12 4: parse status message for HUEDevice8
2022.07.03 15:44:12 5: Cmd: >setreading HUEDevice8 VentilNr 3<
2022.07.03 15:44:12 1: 'setreading HUEDevice8 VentilNr 3' called form userReadings is prohibited
2022.07.03 15:44:12 1: PERL WARNING: HUEDevice8 userReadings HUEDevice8 evaluated to undef at fhem.pl line 4917.
2022.07.03 15:44:12 3: eval: {
my $ventil = ReadingsVal("HUEDevice8","VentilNr",1);


    if ( $ventil ne 6 ) {
           $ventil = $ventil + 1;
    } elsif ( $ventil eq 6 ) {
           $ventil = 1;
    }
fhem("setreading HUEDevice8 VentilNr $ventil");
;
}


'setreading HUEDevice8 VentilNr 3' called form userReadings is prohibited

das geht wohl generell nicht, ich muss ein externes notify nehmen, dann sollte es gehen.

Und die Warnung verstehe ich nicht:

PERL WARNING: HUEDevice8 userReadings HUEDevice8 evaluated to undef at fhem.pl line 4917.

matze1999

MadMax-FHEM

#36
Damit soll verhindert werden, dass eine Event-Loop "von sich selbst aus" erneut triggert.

Weil du bist ja in einem notify/userReadings/... eines Devices und darin geht dann setreading Device Reading Wert nicht, weil du damit ja u.U. erneut triggerst usw. -> "Endlosschleife"...

Wenn du userReadings mit Trigger verwendest und dieser dafür sorgt, dass das nicht passiert, dann kannst du folgendes tun:


fhem("sleep0.1; setreading HUEDevice8 VentilNr $ventil");


EDIT: bzw. über Eingabe ALLES per FhemWeb-Eingabezeile, dann eben doppelte Strichpunkte... BTW: müssen die ganzen doppelten Strichpunkte am Ende wirklich?

Aber wie geschrieben: wenn du nicht sauber gearbeitet hast, dann "zerlegt" es dich ;)

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Beta-User

Zitat von: matze1999 am 03 Juli 2022, 15:50:06
das geht wohl generell nicht, ich muss ein externes notify nehmen, dann sollte es gehen.
Das ist so nicht richtig. setreading hatte ich vorgeschlagen, weil es an den dummy gehört, und eben nicht an den Aktor. Aber wenn man es richtig macht, braucht man auch den Umweg über das sleep hier (!) nicht...

Aber erst solltest du dich mit der Syntax von userReadings vertraut machen - das was du geschrieben hattest, klang nach einem mehrfachen Missverständnis, sowohl was den Namen des userReadings angeht, wie auch den trigger und den Rückgabewert...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

ich hab die Strichpunkte raus genommen und lass es bei dem notify.

ich würde gern noch einen "Informations" Dummy mit dem Reading versorgen, irgendwie gelingt mir das nicht, das habe ich mit Strichpunkten versucht.

1.
HUEDevice8:off {
my $ventil = ReadingsVal("HUEDevice8","VentilNr",0);


    if ( $ventil ne 6 ) {
           $ventil = $ventil + 1
    } elsif ( $ventil eq 6 ) {
           $ventil = 1
    }
fhem("setreading HUEDevice8 VentilNr $ventil ; set manuelle.Beregnung VentilNr $ventil")
}


HUEDevice8:off {
my $ventil = ReadingsVal("HUEDevice8","VentilNr",0);


    if ( $ventil ne 6 ) {
           $ventil = $ventil + 1
    } elsif ( $ventil eq 6 ) {
           $ventil = 1
    }
fhem("setreading HUEDevice8 VentilNr $ventil ;; set manuelle.Beregnung VentilNr $ventil")
}


matze1999

MadMax-FHEM

#39
Zitat von: Beta-User am 03 Juli 2022, 16:34:31
Das ist so nicht richtig. setreading hatte ich vorgeschlagen, weil es an den dummy gehört, und eben nicht an den Aktor. Aber wenn man es richtig macht, braucht man auch den Umweg über das sleep hier (!) nicht...

Ups, richtig ;)

Ja, man kann/sollte den Namen des gewünschten Readings nehmen und einfach zurückgeben: fertig 8)

@matze1999:

Zitat
fhem("setreading HUEDevice8 VentilNr $ventil ;; set manuelle.Beregnung VentilNr $ventil")

Also setreading DeviceName ReadingName Wert vs. set DeviceName Wert / fällt was auf?

Entweder setzt du bei deinem komischen manuell-Dummy ein Reading, dann eben wieder setreading oder es sollte (da dummy) eigentlich sogar VentilNr X (mit X = die entspr. "errechnete" Nummer) in state stehen...
EDIT: alternativ geht auch die setList des dummy entsprechend angeben, dann klappt auch der set ;)

Evtl. statt (einfach) trial & error etwas einlesen/einarbeiten und dein ganzes Konstrukt noch mal (in Ruhe) durchdenken? ;)

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Beta-User

Zitat von: matze1999 am 03 Juli 2022, 16:36:17
irgendwie gelingt mir das nicht, das habe ich mit Strichpunkten versucht.
Was steht im log?

Mein Tipp: es gibt in dem dummy dieses Reading nicht als setzbares Reading...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

matze1999

 ;D
funktioniert nun alles wie gewünscht:

defmod Ventilstellung.nt notify HUEDevice8:off {\
my $ventil = ReadingsVal("HUEDevice8","VentilNr",1);;\
\
\
    if ( $ventil < 6 ) {\
           $ventil = $ventil + 1\
    } elsif ( $ventil > 5 ) {\
           $ventil = 1\
    } \
fhem("setreading HUEDevice8,manuelle.Beregnung VentilNr $ventil")\
}


matze1999