[GELÖST] - notify - Strom Messung und Reaktion (Trockner / Waschmaschine)

Begonnen von 87insane, 13 August 2019, 08:24:09

Vorheriges Thema - Nächstes Thema

87insane

Hallo zusammen,

ich habe mein Waschmaschinen und Trockner notify angepasst und ein wenig optimiert. Nun denke ich aber es geht besser und ich habe ggf was übersehen. Hinzu habe ich das Problem, dass es zu oft triggert. Nicht der ausführende Teil aber zumindest das trigger Regex.

Trockner: Soll triggern bei 45 oder mehr / weniger als 45
Waschmaschine: Soll triggern bei 4 oder mehr / weniger als 4
Das muss ich noch einbauen....

Nun habe ich an der Messdose von Waschmaschine im Reading "power" immer etwas über 0,8W. Das Reading ändert sich immer wieder von z.B. 0,8 auf 0,7 usw. Somit triggert das notify immer (ein wenig). Es bleibt dann bei den IFs hängen. Kann man das irgendwie besser machen?

PS: An sich ging das "Script" immer aber ich denke zum einen ist es ggf. sinnlos und geht besser und zum anderen erhoffe ich mir an in diesem Trigger vorbei zu kommen.

Waschmaschine: Geht nie UNTER 4 wenn sie im Betrieb ist.
Trockner: Geht nie unter 45 im Betrieb.


MQTT2_shellyplug_s_040C7E:power.*|s_trockner:power:.* {

# Gerätewahl
     if (ReadingsNum("$NAME", "power", 0) > 4 && ReadingsVal("$NAME", "running", "false") eq "false") {
         
          my $dev = "";
          if ("MQTT2_shellyplug_s_040C7E" eq $NAME) {$dev = 'Die Waschmaschine';}
          elsif ("s_trockner" eq $NAME) {$dev = 'Der Trockner';}

          # Texte / Ausgaben
          my $txts = "set p.nachrichten message | ".strftime("%H:%M", localtime)." Uhr: $dev startet";

          fhem("setreading $NAME running true");
  fhem("set [a-z][a-z]_sonos Speak 50 de $dev startet");
          fhem("$txts");
          fhem("$txts | NAMEeinerPERSON");
     }

     elsif (ReadingsNum("$NAME", "power", 0) < 4 && ReadingsVal("$NAME", "running", "false") eq "true") {
         
          my $dev = ""; my $gang = "";
          if ("MQTT2_shellyplug_s_040C7E" eq $NAME) {$dev = 'Die Waschmaschine'; $gang = 'waschgang';}
          elsif ("s_trockner" eq $NAME) {$dev = 'Der Trockner'; $gang = 'trocknungsgang';}

my $txte = "set p.nachrichten message Verbrauch: ".sprintf("%.2f",ReadingsVal("$NAME","$gang",""))." kWh. Das sind ca. ".sprintf("%.2f",ReadingsVal("$NAME","$gang",0)*0.29)." €. Zeit: ".strftime("%H:%M", localtime(ReadingsAge('$NAME','total_temp',0)-3600))." Std. | ".strftime("%H:%M", localtime)." Uhr: $dev ist fertig";
          fhem("setreading $NAME running false");
          fhem("set klingel_vorne on");
  fhem("set [a-z][a-z]_sonos Speak 50 de $dev ist fertig");
  fhem("$txte");
          fhem("$txte | NAMEeinerPERSON");
     }
}



Danke schon mal!

DasQ

Fhem on MacMini/Ubuntu.
Absoluter Befürworter der Konsequenten-Kleinschreibung https://de.wikipedia.org/wiki/Kleinschreibung
Infos zu Klimawandel http://www.globalcarbonatlas.org

87insane

#2
Okay - DOIF macht das, was ich im notify sonst mit Regex machen müsste. Hmm... Jetzt muss ich mir das DOIF mal genauer ansehen um zu verstehen wie dieses arbeitet. Ich z.B. habe keinen Dummy und mache lieber ein Reading dafür um entsprechendem Gerät. Das geht aber ja auch mit dem DOIF.

Hast du dein aktuelles und laufendes DOIF zufällig zur Hand und kannst es posten? Am besten mit den Abhängigkeiten. Ich hab die 4 Seiten überflogen und weiß nicht 100% wo ihr, wann etwas angepasst habt und was das beste davon ist.

Danke!

PS: Mit dem DOIF, wenn ich das korrekt verstehe, muss ich zwei DOIF machen. Also für beide Geräte ein separates. Wollte am liebsten beide Geräte in einem haben. Aber wenn z.B. der Trockner läuft würde die Waschmaschine das gleiche DOIF nicht mehr triggern.
Hänge hier ein wenig fest seit ich das vereint habe..

Otto123

Zitat von: 87insane am 13 August 2019, 08:24:09
Nun habe ich an der Messdose von Waschmaschine im Reading "power" immer etwas über 0,8W. Das Reading ändert sich immer wieder von z.B. 0,8 auf 0,7 usw. Somit triggert das notify immer (ein wenig). Es bleibt dann bei den IFs hängen. Kann man das irgendwie besser machen?
Das geht eigentlich gar nicht anders. Das Reading power ändert sich, es gibt einen Event und irgendwer muss nachschauen und bewerten. Also trigger und ein Vergleich, egal mit welchen Mitteln.
Ich würde den Trigger so schreiben:(MQTT2_shellyplug_s_040C7E:|s_trockner:)power:.*
Den Powerwert hast Du damit im notify schon übergeben ($EVENT,$EVTPARTx) brauchst Du also normalerweise nicht nochmal mit ReadingsVal auslesen.
Die Abfrage mit $dev könntest Du noch kürzer machen, in dem du den Inhalt von dev einfach in ein Reading am Gerät schreibst und einheitlich mit ReadingsVal($NAME,"Reading","" einfach ausliest und nicht ermittelst.

Gruß  Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

87insane

Hi Otto,

schön das du auch wieder dabei bist :)

ZitatIch würde den Trigger so schreiben:
Code: [Auswählen]
(MQTT2_shellyplug_s_040C7E:|s_trockner:)power:.*
Angepasst und macht ja Sinn!

ZitatDie Abfrage mit $dev könntest Du noch kürzer machen, in dem du den Inhalt von dev einfach in ein Reading am Gerät schreibst und einheitlich mit ReadingsVal($NAME,"Reading","" einfach ausliest und nicht ermittelst.
Danke für die Idee. Das baue ich gleich ein.

ZitatDen Powerwert hast Du damit im notify schon übergeben ($EVENT,$EVTPARTx) brauchst Du also normalerweise nicht nochmal mit ReadingsVal auslesen.
Erst wollte ich hierzu schreiben, das ich diesen Teil nicht verstehe. Nun, beim dritten Wort im Satz ist mir aufgefallen was du meinst. Die IFs von Anfang und Ende. Baue ich auch gleich ein.

Im Moment würde das Script so anfangen:
(MQTT2_shellyplug_s_040C7E:|s_trockner:)power:.* {
my $wert
if ("MQTT2_shellyplug_s_040C7E" eq $NAME) {$wert = '4';}
elsif ("s_trockner" eq $NAME) {$wert = '45';}

# Gerätewahl
if (ReadingsNum("$NAME", "power", 0) > $wert && ReadingsVal("$NAME", "running", "false") eq "false") {

......


Die beiden Geräte wollen andere Werte da Waschmaschine neuer als Trockner. Nun würde ich die IFs mit EVTPRT anpassen anstelle des ReadingsVal. Allerdings dachte ich mir, wenn das notify jedes mal triggert und immer und immer wieder die Werte setzt für den Vergleich, dann ist das ja auch sinnloser Aufwand für den kleinen Raspi. Ich habe aber keine gute Idee, wie ich das so machen kann, dass es auch nur dann ausgeführt wird, wenn sinnig.

87insane

#5
Was sagt ihr hierzu? Ist noch nicht getestet aber Ottos Idee mit dem Reading ist genial und hat mir einiges vereinfacht. So kann ich das Script für alles mögliche nehmen....

(MQTT2_shellyplug_s_040C7E:|s_trockner:)power:.* {
if ($EVTPART1 > ReadingsVal("$NAME", "swerta", "") && ReadingsVal("$NAME", "running", "true") eq "false") {

# Texte / Ausgaben
my $txta = "set p.nachrichten message | ".strftime("%H:%M", localtime)." Uhr: ".ReadingsVal("$NAME", "aname", "")." startet";

fhem("setreading $NAME running true");
fhem("set [a-z][a-z]_sonos Speak 50 de ".ReadingsVal("$NAME", "aname", "")." startet");
fhem("$txta");
fhem("$txta | NAMEeinerPERSON");
}
elsif ($EVTPART1 < ReadingsVal("$NAME", "swerte", "") && ReadingsVal("$NAME", "running", "false") eq "true") {
         
my $txte = "set p.nachrichten message Verbrauch: ".sprintf("%.2f",ReadingsVal("$NAME","gang",""))." kWh. Das sind ca. ".sprintf("%.2f",ReadingsVal("$NAME","gang",0)*0.29)." €. Zeit: ".strftime("%H:%M", localtime(ReadingsAge('$NAME','total_temp',0)-3600))." Std. | ".strftime("%H:%M", localtime)." Uhr: ".ReadingsVal("$NAME", "aname", "")." ist fertig";

fhem("setreading $NAME running false");
fhem("set klingel_vorne on");
fhem("set [a-z][a-z]_sonos Speak 50 de ".ReadingsVal("$NAME", "aname", "")." ist fertig");
fhem("$txte");
fhem("$txte | NAMEeinerPERSON");
}
}

Otto123

#6
Naja irgendwer muss den Vergleich machen wenn sich ein Wert ändert. An welcher Stelle das passiert ist vom "Aufwand" her sicher ziemlich egal.
Man könnte noch etwas mit UserReadings machen, ob das am Ende von der Struktur her schöner ist weiß ich noch nicht.
Ich habe z.B. ein Userreading wenn die Sonne scheint:
scheint {(ReadingsNum($name,"temperature",0) > 2.9) ? 'on' : 'off' }Der schaut ob die Temperatur (Differenz zweier Fühler) einen gewissen Wert überschreitet und setzt dann das Reading "scheint" auf on oder off.
Das wäre sozusagen die minimalistischste  Vorprüfung ob Waschmachine läuft oder nicht.
Du könntest das in der Art für beide Maschinen machen und das notify auf dieses Reading triggern lassen und den Rest im notify abfragen.

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

87insane

#7
Poste mal das ganze Konstrukt. Macht sicher mehr Sinn....

Bin aber schon ganz zufrieden. Es scheint zu klappen und ist viel schlanker als vorher. Hinzu ist es nun etwas einfacher Geräte hinzu zu fügen. Ich könnte nun ohne großen Aufwand z.B. die Spülmaschine hinzufügen.

############################################################################################################################################################################################################
#
# Im Gerät müssen folgende Readings gesetzt werden:
# swerta  = Schwellwert beim starten des Gerätes in Sekunden
# swerte  = Schwellwert nach Beendigung des Programmes (z.B. Waschmaschine) in Sekunden
# aname   = Name für Benachrichtigungen (z.B. Die Waschmaschine)
#
# running = Wird für userReading im Gerät benötigt aber muss einmalig gesetzt werden (false)
# userReading Beispiel: total_temp:running.*true.* { ReadingsVal("$name","relay_0_energy",0) },gang:running.*false.* { ReadingsVal("$name","relay_0_energy",0) - ReadingsVal("$name","total_temp",0) }
# Das userReading setzt total_temp (Gesamt-Verbrauch vor dem z.B. Waschgang) und gang (Wert für z.B. einen Waschgang). Dient der Berechnung, der Werte für die Benachrichtigung.
#
#############################################################################################################################################################################################################


(MQTT2_shellyplug_s_040C7E:|s_trockner:)power:.* {
if ( $EVTPART1 > ReadingsVal("$NAME", "swerta", "") && ReadingsVal("$NAME", "running", "true") eq "false" ) {

# Texte / Ausgaben
my $txta = "set p.nachrichten message | ".strftime("%H:%M", localtime)." Uhr: ".ReadingsVal("$NAME", "aname", "")." startet";

fhem("setreading $NAME running true");
fhem("set [a-z][a-z]_sonos Speak 50 de ".ReadingsVal("$NAME", "aname", "")." startet");
fhem("$txta");
fhem("$txta | nameEinerPerson");
}
elsif ( $EVTPART1 < ReadingsVal("$NAME", "swerte", "") && ReadingsVal("$NAME", "running", "false") eq "true" ) {
         
# Texte / Ausgaben
my $txte = "set p.nachrichten message Verbrauch: ".sprintf("%.2f",ReadingsVal("$NAME","gang",""))." kWh. Das sind ca. ".sprintf("%.2f",ReadingsVal("$NAME","gang",0)*0.29)." €. Zeit: ".strftime("%H:%M", localtime(ReadingsAge('$NAME','total_temp',0)-3600))." Std. | ".strftime("%H:%M", localtime)." Uhr: ".ReadingsVal("$NAME", "aname", "")." ist fertig";

fhem("setreading $NAME running false");
fhem("set klingel_vorne on");
fhem("set [a-z][a-z]_sonos Speak 50 de ".ReadingsVal("$NAME", "aname", "")." ist fertig");
fhem("$txte");
fhem("$txte | nameEinerPerson");
}
}


GERNE nehme ich aber auch noch Verbesserungs-Vorschläge entgegen!
Man könnte hier in das UserReading noch running aufnehmen... running früft ja auch nur den Schwellwert. Bin mir aber nicht sicher was eleganter ist.

EDIT: Hab das Userreading mal erweitert. Erstmal nur zum testen. Kann ja sein das ein Geräte am Anfang und am Ende andere Werte hat. Deswegen hatte ich auch swerta und swerte mit drin. Dazu habe ich im Userreading aktuell keine Idee. Aktuell hat das Reading keinen Einfluss auf die Steuerung und läuft nur nebenbei mal mit, damit ich sehe wann es sich wie verhält...

userreading:
total_temp:running.*true.* { ReadingsVal("s_trockner","total",0) },
gang:running.*false.* { ReadingsVal("s_trockner","total",0) - ReadingsVal("s_trockner","total_temp",0) },
TESTrunning {(ReadingsVal("$name","power",0) > 45) ? 'true' : 'false'}

87insane

Für die Nachwelt...

So geht es bei mir gut!

notify:
(MQTT2_shellyplug_s_040C7E|s_trockner):running:.* {
if ( ReadingsVal("$NAME", "running", "false") eq "true" ) {

# Texte / Ausgaben
my $txta = "set p.nachrichten message | ".strftime("%H:%M", localtime)." Uhr: ".ReadingsVal("$NAME", "aname", "")." startet";

fhem("set [a-z][a-z]_sonos Speak 50 de ".ReadingsVal("$NAME", "aname", "")." startet");
fhem("$txta");
fhem("$txta | NAMEeinerPerson");
}
elsif ( ReadingsVal("$NAME", "running", "true") eq "false" ) {
         
# Texte / Ausgaben
my $txte = "set p.nachrichten message Verbrauch: ".sprintf("%.2f",ReadingsVal("$NAME","gang",""))." kWh. Das sind ca. ".sprintf("%.2f",ReadingsVal("$NAME","gang",0)*0.29)." €. Zeit: ".strftime("%H:%M", localtime(ReadingsAge('$NAME','total_temp',0)-3600))." Std. | ".strftime("%H:%M", localtime)." Uhr: ".ReadingsVal("$NAME", "aname", "")." ist fertig";

# fhem("set klingel_vorne on");
fhem("set [a-z][a-z]_sonos Speak 50 de ".ReadingsVal("$NAME", "aname", "")." ist fertig");
fhem("$txte");
fhem("$txte | NAMEeinerPerson");
}
}


Was FHEM dann tun soll, kann sich ja jeder selber zurecht basteln ;)

UserReadings:
total_temp:running.*true.* { ReadingsVal("$name","relay_0_energy",0) },
gang:running.*false.* { ReadingsVal("$name","relay_0_energy",0) - ReadingsVal("$name","total_temp",0) },
running {(ReadingsVal("$name","power",0) > ReadingsVal("$name","swerta",0)) ? 'true' : 'false'}


Gesamt Verbrauch bisher, ist bei mir relay_0_energy, in dem Gerät. Bitte anpassen, wenn es bei euch anders sein sollte.

Im Gerät müssen folgende Readings gesetzt werden:
# swerta  = Schwellwert beim starten des Gerätes in Watt - Bei mir hat die Waschmaschine dort z.B. 4 und der Trockner 45.
# aname   = Name für Benachrichtigungen (z.B. Die Waschmaschine)


Viel Spaß damit...