Globale, flexible Fenster-/Tür-Offen-Meldungen

Begonnen von Benni, 20 April 2015, 20:19:31

Vorheriges Thema - Nächstes Thema

flummy1978

@eisman Von meiner Seite ein kleines Sorry - hatte hier keine Benachrichtigungen mehr aktiv und betraf mich auch nicht, aber denoch habe ich hier ja auch einigen gern helfen wollen:

Zitat von: eisman am 26 Oktober 2023, 09:32:43sub winOpenStart($;$) {
    my $dev=shift(@_)
entspricht Übergabe Device? ($;$) es wird aber nur ein Device übergeben.
sub winOpenStop($) {
    my ($dev)=@_;
entspricht Übergabe Device? ($) es wird ein Device übergeben.

Was ist der Unterschied zwischen den beiden Aufrufen?
Es ist richtig, dass in beiden Fällen das Device übergeben wird, ABER:
winOpenStart($;$)Übergibt einen Parameter und einen OPTIONALEN Parameter  - Die zweite Variante übergibt eben nur den einen. Hab es nicht mehr im Kopf, ob es da genutzt wurde, weil ich mittlerweile eine andere Funktion nutze, aber zum Verständnis hilft das sicher.

ZitatIch suche auch schon seit tagen nach einer Möglichkeit, meine Fensterprozedur zu verbessern.
Z.z. mache es mit mehreren Watchdog.

bisher bin ich dabei an zwei punkten gescheitert.
Watchdog mit flexibler Zeit. (aus einem Reading)
Device während der Laufzeit anlegen. (Es wird immer ein save verlangt)

Falls das noch aktuell ist und Du es immernoch ändern möchtest, kann ich meine Sache vorzeigen - muss allerdings dazu sagen, dass diese "etwas" ausgeartet ist. Dementsprechend ist auch der Perl Teil recht umfangreich.
Es ist eine "eierlegende" Zeitschaltuhr geworden, die sowohl Geräte als auch Fenster überwacht. Bei den meisten Geräten, geht es nach Zeit X aus (Garage,Abstellkammer etc). Bei einigen ist das Ausschalten an eine Bedingung geknüpft (z.B. damit das Kellerlicht ausgeschaltet wird, muss die Tür auch zu sein (sprich es ist keiner im Keller).
Bei Fenstern ist jeweils die Einschränkung Temperatur drin (d.h. es gibt nur eine Meldung wenn XX Grad unterschritten wurden) ABER es gibt für jedes Fenster / Gerät / Überwachung einen eigenen Timer - der als Attribut im Gerät gespeichert wird. Somit entfällt das ständige neue Geräte speichern.

VG
Andreas

eisman

Hi,

danke für die INFO, nein ich habe es jetzt geschafft,
das nach 30min eine Meldung kommt. Ich passe die Zeit
nicht an.

dennoch danke
gruss
1x FHEM Debian, Homematic,ZigBee,FS20 / 1X Raspberry, ConBee / 5x ESP
1x FHEM Debian, Homematic,ZigBee         / 1X Raspberry, ConBee / 5x ESP
1x FHEM Debian,MQTT                               / 1X Raspberry, i2c,onewire,gpio
1x auf Windows 2012 Hyper-V-S

MDietrich

Zitat von: flummy1978 am 13 Januar 2024, 16:12:37Falls das noch aktuell ist und Du es immernoch ändern möchtest, kann ich meine Sache vorzeigen - muss allerdings dazu sagen, dass diese "etwas" ausgeartet ist. Dementsprechend ist auch der Perl Teil recht umfangreich.
Es ist eine "eierlegende" Zeitschaltuhr geworden, die sowohl Geräte als auch Fenster überwacht. Bei den meisten Geräten, geht es nach Zeit X aus (Garage,Abstellkammer etc). Bei einigen ist das Ausschalten an eine Bedingung geknüpft (z.B. damit das Kellerlicht ausgeschaltet wird, muss die Tür auch zu sein (sprich es ist keiner im Keller).
Bei Fenstern ist jeweils die Einschränkung Temperatur drin (d.h. es gibt nur eine Meldung wenn XX Grad unterschritten wurden) ABER es gibt für jedes Fenster / Gerät / Überwachung einen eigenen Timer - der als Attribut im Gerät gespeichert wird. Somit entfällt das ständige neue Geräte speichern.

VG
Andreas

Hallo Andreas,
ich bin an deiner Lösung interessiert.

Danke im Voraus,
Matthias
FB 6591 Cable / Raspberry 3b+ (Bookworm) / 4xECHO DOT 4/ Homematic Thermostate, Fenster- und Fenster-Sensoren / Philips HUE / CUL-HM /  Zigbee Schalter und Lampen / Shelly 1

flummy1978

Holla,

Zitat von: MDietrich am 23 Januar 2024, 12:51:22ich bin an deiner Lösung interessiert.
Ich weiss nicht wie fit Du in Perl bist, ich versuchs mal im Schnellformat (was hier nicht gelingen wird) aber in Anbetracht dessen, dass das sehr sehr individuell für mich und sicher nicht auf dem höchsten Level programmiert:

Zunächst einmal muss im global device das Attr userattr um die Einträge: TIMER_announce TIMER_announcecond TIMER_announcemsg TIMER_announcetarget TIMER_set TIMER_setcond erweitert werden. Diese benötigt man später im Device. Codeauszüge der einzelnen Beispiel (hab alles unwichtige für die Übersichtlichkeit gelöscht):

1. Einfach nur nach Zeit ausschalten (in dem Beispiel ist noch ne Meldung drin, falls das Teil länger an ist als gewollt)
define EG_WZ_SD_03_infrarot MQTT2_DEVICE WZ_SD_Infrarot_B97CFE
attr EG_WZ_SD_03_infrarot TIMER_announce 1200
attr EG_WZ_SD_03_infrarot TIMER_announcemsg Infrarotheizung ist seit 20 Min an?
attr EG_WZ_SD_03_infrarot TIMER_set 900

2. Schaltet nach Zeit aus, nut Bedingung (Kellertür ist zu)
define Licht_KG_Decke MQTT2_DEVICE Shelly6_Kell_E2D78C
attr Licht_KG_Decke TIMER_announce 1800
attr Licht_KG_Decke TIMER_announcemsg Kellerlicht ist seit einer halben Stunde eingeschaltet, Absicht?
attr Licht_KG_Decke TIMER_set 2700
attr Licht_KG_Decke TIMER_setcond Licht_KG_Decke,off,TK_EG_FL_tuerkeller_innen,contact,true
attr Licht_KG_Decke alias Licht Keller

3. Schlafzimmerfenster (wird nur überwacht wenn Temperaturbedingungen unterschritten sind, in dem Fall mind. 19°)
define TK_OG_SZ_fenster1 MQTT2_DEVICE zigbee_TK_SZ_Fenster1
attr TK_OG_SZ_fenster1 TIMER_announce 1200
attr TK_OG_SZ_fenster1 TIMER_announcecond temperatur,dev_OG_SZ_Temp_Sensor,temperature,19
attr TK_OG_SZ_fenster1 TIMER_announcemsg Schlafzimmerfenster ist seit 30 Min offen (Sollte geschlossen werden)
attr TK_OG_SZ_fenster1 TIMER_announcetarget home

Diese geräte lösen ein notify aus, in dem dann my_Utils Routine ausgelöst wird:
(Hab nur die 3 Beispiele im Notify gelassen)

EG_WZ_SD_03_infrarot:state:.*|Licht_KG_Decke:POWER1:.*|TK_OG_GZ_fenster:state:.*  {

# Fensterkontakte in on / off simulieren
$EVTPART1 = "on" if $EVTPART1 eq "open";
$EVTPART1 = "off" if $EVTPART1 eq "closed";

auto_onfortimer($NAME,$EVTPART1);
}

auto_onfortimer in MyUtils

############################
#  On-for-Timer Automatik  #
############################

sub auto_onfortimer ($$){

my ($dev,$EVTPART0) = @_;

##########################################
# Abbrechen wenn Gerät über
# on-for-timer oder über on / off - till
# geschaltet wurde
RemoveInternalTimer($dev."_set");
RemoveInternalTimer($dev."_announce");

if (($defs{$dev."_set"}) or ($defs{$dev."_till"}) or ($defs{$dev."_intervalFrom"}) or ($defs{$dev."_intervalNext"}) or ($defs{$dev}->{TIMED_OnOff}->{CMD}))
{
fhem ("cancel $dev"."_set quiet");
fhem ("cancel $dev"."_announce quiet");
return undef;
}

# Notwendige Angaben prüfen ( $mainbutton ist für Push MSGs )
my $settimer=AttrVal($dev,'TIMER_set',0);
my $announcetimer=AttrVal($dev,'TIMER_announce',0);
my $mainbutton = " ( .MENUE. ) ";
# Bedingungen für Timer aufteilen
my @announcecondition =  split(",", AttrVal($dev,'TIMER_announcecond',0));

return return undef if (($settimer == 0) && ($announcetimer == 0));

# Vorhandene Timer für das Device abbrechen
fhem ("cancel $dev"."_set quiet");
fhem ("cancel $dev"."_announce quiet");
   
    if (($EVTPART0 eq "on") && ($announcetimer != 0))
    {

    # Zeitumrechnung auf Minuten und Stunden
    # Diese sind nur für Benachrichtigungen
    my $tmp=();
    $tmp =($announcetimer/3600)." Stunden" if ($announcetimer>3600);
    $tmp =sprintf("%.2f", ($announcetimer/60))." Minuten" if ($announcetimer<3600);

    # Nachrichtemempfänger vorbereiten
    my $destination ="@".ReadingsVal("RESIDENT_ALL", "residentsHomeNames", 'null');
    $destination =~ s/,\s/ @/gi; # @Zeichen voranstellen bei mehr als einem anwesenden

    # Ausschaltbutton in die Nachricht mit anhängen, wenn es sich nicht um ein Fenster handelt
    $mainbutton .= '( ❌ '.AttrVal($dev,'alias','0').' AUSSCHALTEN  ❌:'.$dev.') ' if ($dev !~ /TK_/);
   
    # Wenn Bedingungen eingetragen sind, prüfen ob es eine Temperatur-Bedingung ist
    if (!$announcecondition[0])
    {
    fhem ("sleep $announcetimer $dev"."_announce; { addmsg('".AttrVal($dev,'TIMER_announcemsg','home')."','residentsHomeNames','$mainbutton','".AttrVal($dev,'TIMER_announcemsg',$dev)."') } ");
    }
    elsif (($announcecondition[0] eq "temperatur") && ((ReadingsVal($announcecondition[1], $announcecondition[2], '0') <= $announcecondition[3])))
        {
        fhem ("sleep $announcetimer $dev"."_announce; { addmsg('".AttrVal($dev,'TIMER_announcemsg','home')."','residentsHomeNames','$mainbutton','".AttrVal($dev,'TIMER_announcemsg',$dev)."') } ");
        }

    }

    if (($EVTPART0 eq "on") && ($settimer != 0))
     {
    my %h = (dev => $dev, name => "_set", );
    InternalTimer( gettimeofday()+$settimer, 'settimer_option', $dev."_set");

    }
}

# Timer die optional verlängert werden können
# zb bei Lichtmeldungen die ein Türkontakt beinhalten
# So wird das Kellerlicht z.B. verlängert

sub settimer_option($) {
my $dev = shift;
$dev =~ s/_set//;

my @setcondition =  split(",", AttrVal($dev,'TIMER_setcond',0));
my $cond    = ReadingsVal($setcondition[2], $setcondition[3], "false");
my $settimer=AttrVal($dev,'TIMER_set',0);
my $off_cmd = "$dev off";
$off_cmd = $setcondition[0]." ".$setcondition[1] if (($setcondition[0] ne "") && ($setcondition[1] ne ""));

if ((!$setcondition[0]) || ($cond eq $setcondition[4])) { CommandSet(undef,$off_cmd); }
else { InternalTimer( gettimeofday()+$settimer, 'settimer_option', $dev."_set"); }
}

Hab es versucht soweit wie möglich zu kommentieren und so viel wie möglich raus zu löschen, was nicht gebraucht wird (ungetestet).

Bei Fragen, fragen, ansonsten viel Spaß mit der Lösung ;D

VG
Andreas

MDietrich

Danke, ich werde mich am Wochenende daran setzen.

Gruß,
Matthias
FB 6591 Cable / Raspberry 3b+ (Bookworm) / 4xECHO DOT 4/ Homematic Thermostate, Fenster- und Fenster-Sensoren / Philips HUE / CUL-HM /  Zigbee Schalter und Lampen / Shelly 1