Licht schalten bei Abwesenheit Code-check

Begonnen von Dodger, 29 November 2021, 13:59:55

Vorheriges Thema - Nächstes Thema

Dodger

Hi Leute,

so langsam fühle ich mich etwas sicherer im Umgang mit FHEM.

Heute habe ich einen Shelly 1 in die Wohnzimmerbeleuchtung eingebaut und in FHEM eingebunden.
Funktioniert soweit auch alles.
Nun möchte ich, dass das Licht automatisch eingeschaltet wird, wenn es:
a) dunkel ist
b) niemand zu Hause ist
c) die Uhrzeit zwischen 16:00 und 22:00 Uhr liegt.

Dafür hab ich mir folgenden Code zusammengeschnorrt:
define Wohnzimmerlicht_an notify SMATripower:avg_power_lastminutes_15.* {\
my $hm = sprintf("%02d:%02d", $hour, $min);;\
if( $hm gt "16:00" && $hm lt "22:00" &&\
   $value{SMATripower:avg_power_lastminutes_15} eq "0" &&\
   $value{Anwesenheit_a} eq "absent" &&\
   $value{Anwesenheit_b} eq "absent" &&\
   $value{Anwesenheit_c} eq "absent" &&\
   $value{Anwesenheit_d} eq "absent") {\
  fhem "set Shelly_Wohnzimmer on";;\ 
}\
}


Mein Helligkeitssensor ist meine PV Anlage. Sobald der über 15 Minuten gemittelte Wert = 0 ist gehe ich davon aus, dass es dunkel ist.
"Anwesenheit_a..." wird mit der Presence Funktion aus der Fritzbox abgeleitet.
Wenn ich das richtig verstanden habe, dann läuft die Prüfung immer dann, wenn der Wert "SMATripower:avg_power_lastminutes_15.*" aktualisiert wird?

Würde das so fliegen?
Kann man so etwas in FHEM debuggen? Quasi Schritt-für-Schritt durchgehen?

Gruß
Dodger

Otto123

Hi,

agesehen davon, dass im $EVENT der Inhalt von avg_power_lastminutes_15 stehen müsste, kannst Du gleich nur bei 0 triggern:
SMATripower:avg_power_lastminutes_15:.0 müsstest Du aber mal im Eventmonitor prüfen!

Die ganze absent Prüfung würde ich "außen" über eine structure vorher zusammenfassen. -> "KeinerDa" brauchst Du vielleicht auch an anderer Stelle?

Den Schaltbefehl an den Shelly sollte man nur absetzen, wenn er nötig ist. Das geht mit Filter:
set Shelly_Wohnzimmer:FILTER=state!=on on

Und zu guter Letzt: die Zeitsteuerung geht auch mit diabledForIntervals

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

rabehd

ZitatDie ganze absent Prüfung würde ich "außen" über eine structure vorher zusammenfassen. -> "KeinerDa" brauchst Du vielleicht auch an anderer Stelle?
Habe ich auch so und kann es empfehlen.
Eine Struktur mit "jemandda" und "niemandda" ist übersichtlich und an vielen Stellen einsetzbar.
Auch funktionierende Lösungen kann man hinterfragen.

TomLee

Ist zwar mehr Code in der Definition als mit structure, ein weiteres PRESENCE-Device im funktion-Modus wäre auch noch eine Alternative.

Beispielhaft für zwei Devices:
defmod sp_Thomas PRESENCE function {ReadingsVal('sp_Thomas_FB','presence','present') eq 'absent' && ReadingsVal('sp_Thomas_UF','presence','present') eq 'absent' ? '0' : '1'} 60 60

(Wie man diese immer gleichen Vergleiche mit ReadingsVal, in der sich ja nur der Name ändert, kürzer umsetzen kann das treibt mir seit letzter Woche im Kopf um, jemand dazu einen Vorschlag/Idee ? )

Dodger

Zunächst mal Danke für die Tipps!

Hab auf die Schnelle mal zwei neue Geräte erzeugt, eines gibt den Status "alle_da" und das andere den Status "alle_weg".

Das neue Notify sieht dann so aus:
define Wohnzimmerlicht_an notify SMATripower:avg_power_lastminutes_15:.0 {\
if( $value{Anwesenheit_alle_weg} eq "1") {fhem "set Shelly_Wohnzimmer:FILTER=state!=on on";;}\
}


Falls das so jetzt stimmt, ist es doch um einiges kürzer geworden :-)

Für die Zeitsteuerung nehme ich das Attribut disabledForIntervals wie von Otto123 vorgeschlagen.

Gruß
Dodger

Wernieman

Das Problem ist, wie willst Du wieder ausschalten.
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

Dodger

#6
erstmal hab ich das Problem, dass es sich nicht einschaltet :-)

Internals
DEF SMATripower:avg_power_lastminutes_15:.0 {if( $value{Anwesenheit_alle_weg} eq "present") {fhem "set Shelly_Wohnzimmer:FILTER=state!=on on";}}
FUUID 61a4e8aa-f33f-c598-ee1d-84eb08fe323c08a3
NAME Wohnzimmerlicht_an
NOTIFYDEV SMATripower
NR 78519
NTFY_ORDER 50-Wohnzimmerlicht_an
REGEXP SMATripower:avg_power_lastminutes_15:.0
STATE 2021-11-29 16:07:17
TRIGGERTIME 1638198437.65429
TYPE notify

Readings
state active 2021-11-29 16:05:54
triggeredByDev SMATripower 2021-11-29 16:07:17
triggeredByEvent avg_power_lastminutes_15: 0 2021-11-29 16:07:17


Probably associated with
Anwesenheit_alle_weg present PRESENCE
SMATripower 0 SMAInverter
Shelly_Wohnzimmer off Shelly


Eigentlich sind alle Bedingungen erfüllt.
Wie prüfe ich am sinnvollsten auf den Status "presence"? Ich dachte, das entspricht einer "1"... oder doch "presence"?

Gruß
Dodger


***EDIT***
hab die Bedingung geändert auf:
SMATripower:avg_power_lastminutes_15:.0 {if( ReadingsVal('Anwesenheit_alle_weg','presence','absent') eq 'present') {fhem "set Shelly_Wohnzimmer:FILTER=state!=on on";}}
jetzt geht das Licht wie gewollt an

rabehd

#7
ZitatHab auf die Schnelle mal zwei neue Geräte erzeugt, eines gibt den Status "alle_da" und das andere den Status "alle_weg".

Was bedeuten kann Du bist gleichzeitig da und weg.  :o
Warum nicht ein Device, welches entweder den Status "da" oder "weg" hat?
Auch funktionierende Lösungen kann man hinterfragen.

Otto123

Zitat$value{Anwesenheit_alle_weg}
das gab es natürlch gar nicht, hast Du aber schon gemerkt :)
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

Dodger

@rabehd
Mir ist tatsächlich nicht eingefallen, wie ich die vier Variablen alle auf "0" oder "1" prüfe.
Vor allem nicht, wie man das Ergebnis nennt, wenn eines der Ereignisse "wahr" ist.
Man bräuchte also eine Funktion, die als Ergebnis "Aale da" und "alle weg" hat.
Was zeigt sie bei den Zwischenstufen an?
Z.B. nur einer ist da?
Also bräuchte man 3 Zustände.

Gruß
Dodger

CoolTux

Schau Dir mal Residents an und damit Verbunden Roommate. Das fasst alles an "Bewohner" zusammen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Wernieman

Warum brauchst Du ein "alle_da"?
Es reicht doch ein "alle_weg" oder "alle_nicht_weg", was nur eine negierung von "alle_weg" ist ....
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

rabehd

Zitat von: Dodger am 29 November 2021, 18:52:36
@rabehd
Mir ist tatsächlich nicht eingefallen, wie ich die vier Variablen alle auf "0" oder "1" prüfe.
Vor allem nicht, wie man das Ergebnis nennt, wenn eines der Ereignisse "wahr" ist.
Man bräuchte also eine Funktion, die als Ergebnis "Aale da" und "alle weg" hat.
Was zeigt sie bei den Zwischenstufen an?
Z.B. nur einer ist da?
Also bräuchte man 3 Zustände.

Gruß
Dodger

Und was hatte ich geschrieben? Eine Struktur.
https://commandref.fhem.de/#structure
Auch funktionierende Lösungen kann man hinterfragen.

Dodger

#13
Okay, funktioniert leider doch nicht....
Grund:
die Triggerbedingung "SMATripower:avg_power_lastminutes_15:.0" kommt nicht mehr, sobald der Ertrag weg ist.
Das Reading wird im Device SMATripower nicht mehr aktualisiert.
Dafür gibt es aber ein Reading "state" welches entweder den Ertrag ausgibt oder "done" sofern kein Ertrag mehr vorhanden ist.
Also habe ich die Definition folgendermaßen geändert:
SMATripower:state:.* {if( (ReadingsVal('Anwesenheit_alle_weg','presence','absent') eq 'present') && (ReadingsVal('SMATripower','avg_power_lastminutes_15','1') eq '0')) {fhem "set Shelly_Wohnzimmer:FILTER=state!=on on";}}
Das Reading "state" wird zyklisch alle 2  Minuten aktualisiert.
Daher hätte ich erwartet, dass in meine Funktion alle 2 Minuten aufgerufen wird.
In den Readings der Funktion steht aber nur:
triggeredByDev SMATripower 2021-12-01 20:10:51
triggeredByEvent done 2021-12-01 20:10:51

Wie man sieht, wurde es nur einmalig getriggert...

Was mache ich falsch?

Gruß
Dodger

****EDIT****
bin aber auch ein Deppchen.... hab ja das Attribut "DisabledForIntervals" gesetzt.....