manuelles überschreiben einer automatischen entscheidung

Begonnen von abc2006, 15 März 2018, 10:56:13

Vorheriges Thema - Nächstes Thema

abc2006

Hi,
ich habe in der myUtils eine sub geschrieben, die anhand unzähliger Parameter eine Entscheidung trifft, ob ein Aktor ein-, oder ausgeschaltet werden soll.
Diese Funktion wird alle 60 Sekunden aufgerufen.

Das funktioniert soweit, jetzt habe ich nur den Wunsch (weil ich als Bediener eh alles besser weiss und kann als die automatik:P) dass ich manuell die Entscheidung übersteuern kann.
Mit dem Befehl "set Aktor on" kann ich den aktor jetzt auch manuell einschalten, sobald die subroutine ausgeführt wird, stellt sie fest, dass die ausschaltbedingung gegeben ist und schaltet den Aktor wieder aus.

Mir fallen auf anhieb einige Lösungsansätze ein (zusätzliche Dummys, Doifs, notifies), aber da erscheint mir eine umständlicher als die andere.
Deshalb wollte ich mal von euch wissen, ob ihr so ein Problem auch schon mal hattet, und wie ihr es gelöst habt (oder lösen würdet).

Danke für euren Input,
Grüße,
Stephan
FHEM nightly auf Intel Atom (lubuntu) mit VDSL 50000 ;-)
Nutze zur Zeit OneWire und KNX

Wernieman

Du hast dabei immer Grundsätzlich das Problem: Woher weiß die Automatik, das Du sie übersteuerst?

Also wirst Du um ein Zusätzliches Element nicht drum rum kommen ...
- 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

abc2006

Zitat von: Wernieman am 15 März 2018, 10:59:24
Woher weiß die Automatik, das Du sie übersteuerst?

Ja, eben. Aber wie löst man das am geschicktesten, mit wenig Overhead, wenigen zusätzlichen Events ...

Grüße,
Stephan
FHEM nightly auf Intel Atom (lubuntu) mit VDSL 50000 ;-)
Nutze zur Zeit OneWire und KNX

Beta-User

Zitat von: Wernieman am 15 März 2018, 10:59:24
Du hast dabei immer Grundsätzlich das Problem: Woher weiß die Automatik, das Du sie übersteuerst?

Also wirst Du um ein Zusätzliches Element nicht drum rum kommen ...
Das könnte aber uU. schon vorhanden sein, z.B. das readingsAge() eines auslösenden Tastendrucks (damit könnte man die Automatik für eine gewisse Zeit übergehen oder Prüfen, ob dann wieder manuell ausgeschaltet wurde (Vergleich mit readingsAge einer anderen Taste).

Kommt eben drauf an, was schon vorhanden ist, das solltest du uns dann mitteilen....
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

Eisix

Hallo,

habe ich mit einem reading eines Dummy's gelöst in dem die Betriebsart drin steht. Bei mir ist es die Heizung (automatik, manuell, boost, aus). Sobald ich manuell einen Wert eingebe wird auch der dummy auf manuell gestellt. Nachts setze ich alles wieder auf Automatik.
Deine Subroutine sollte dann prüfen ob das reading auf Automatik steht.

Gruß
Eisix

Beta-User

Na ja, das hatte er ja oben schon geschrieben, dass ihm das klar war.

Was evtl. auch ginge: Die routine wird ja irgendwie jede Minute angestupst. Wenn das ein at ist: einfach disable/enable verwenden oder da beim Ein- und Ausschalten ein Attribut o. Reading setzen, das du mit abfragst - das spart wenigstens den dummy...
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

CoolTux

Zitat von: Eisix am 15 März 2018, 11:23:41
Hallo,

habe ich mit einem reading eines Dummy's gelöst in dem die Betriebsart drin steht. Bei mir ist es die Heizung (automatik, manuell, boost, aus). Sobald ich manuell einen Wert eingebe wird auch der dummy auf manuell gestellt. Nachts setze ich alles wieder auf Automatik.
Deine Subroutine sollte dann prüfen ob das reading auf Automatik steht.

Gruß
Eisix

Bei mir genau das selbe. Dummy anlegen und dann diesen abfragen.
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

abc2006

Hi,

ZitatreadingsAge() eines auslösenden Tastendrucks

Innovative Idee! genau solchen Input hatte ich mir erhofft.

ZitatWenn das ein at ist: einfach disable/enable verwenden oder da beim Ein- und Ausschalten ein Attribut o. Reading setzen, das du mit abfragst - das spart wenigstens den dummy...

So hab ichs momentan (quick and dirty) gebaut, allerdings mit einem DOIF anstatt einem AT. Geht auch.

ZitatKommt eben drauf an, was schon vorhanden ist, das solltest du uns dann mitteilen....

Nagut, hier die komplette situation. Möchte aber darauf hinweisen, dass ich nach generischen Lösungsansätzen/ideen suche und keine Schritt-für-schritt-Anleitung für meine persönliche Situation... je nachdem, was mir morgen so einfällt, kann das ganze ganz schnell wieder anders aussehen  ::)

Ich habe einen KNX-Aktor, der eine Ladepumpe steuert. mit dieser lade ich heisses wasser von einem in einen anderen Pufferspeicher (ein großer, damit ich die Wärme vom Holzvergaser schnell genug weg schaffe, und ein kleiner für den "täglichen Bedarf (Warmwasser, Solar, Heizung, Gas, usw) als Heizzentrale.
Nun habe ich eine subroutine geschrieben, die mir anhand diverser Bedingungen (erwarteter Solarertrag, erwarteter Energieverbrauch durch Heizung, mindestladung damit ich warmes Wasser habe, Laufzeit des HV, Füllstand des großen Puffers (quasi als Notkühlung, falls ich mich mal vertan hab) entscheidet, ob die Pumpe läuft.
Dann schicke ich aus der sub den Befehl
fhem("set pumpe on")

Hm. Ich könnte ja auch den code posten... warum ist mir das nicht gleich eingefallen .. die Grippe hat doch mehr zerstört, als ich dachte ;P
Hier:


sub move_heat {

my %temps = getHashTemps();
my $HV_VL = ReadingsNum("RE_TEMP_HV_VL","temperature",0);
my $VLtemp = ReadingsNum("RE_TEMP_VorlaufHK","temperature",0);
my $log_name = "move_heat()";
my $subloglevel = 3;
my $previous_loglevel = AttrVal("global","verboseTelegram",0);
if ($previous_loglevel != $subloglevel){
fhem("attr global verboseTelegram $subloglevel");
}
my $pump3to1 = "off";
my $pump1to3 = "off";

##if($HV_)

## Aussentemperaturgeregelt
my $ps1500_border_sensor;
my $AT = ReadingsNum("RE_TEMP_AUSSEN","temperature",0);
my $value = int(($AT*0.15)+5);
log_telegram("5",$log_name,"Grenze laut AT auf $value","remotebot");



################ Solarprognosengeregelt

my $ertrag = ReadingsNum("wetter_prop","fc0_prg_ges",0);

if($ertrag < 10)
{
$value = 2;
log_telegram("5",$log_name,"Solarertrag $ertrag kWh < 10: Grenze auf $value","remotebot");
}
elsif ($ertrag < 40 && $value < 4)
{
$value = int($ertrag/10);
log_telegram("5",$log_name,"Solarertrag $ertrag kWh < 40: Grenze auf $value","remotebot");
}
elsif ($ertrag > 40)
{
## entscheidung wird nach AT gefällt
log_telegram("5",$log_name,"Solarertrag $ertrag kWh > 40: Grenze auf $value","remotebot");
}
# Grenze mindestens auf 2, damit ich noch Reserve habe.
$value = $value < 3 ? 3:$value;
$value = $value > 8 ? 8:$value;

my $grenzfuehler = $value > 9 ? "15":"150" ;
log_telegram("5",$log_name,"gf: $grenzfuehler","remotebot");
$grenzfuehler .= $value;
log_telegram("5",$log_name,"gf: $grenzfuehler","remotebot");

my $test = $temps{$grenzfuehler+1};
my $test2 = $temps{$grenzfuehler-1};
log_telegram("5",$log_name,"test: $test - $test2","remotebot");

log_telegram("5",$log_name,"Temperatur grenzfühler: $grenzfuehler: $temps{$grenzfuehler}","remotebot");
## Pumpen oder nicht pumpen, das ist hier die Frage
if($temps{'3002'} > 40 && $temps{'1501'} < 40){ ## wenn 3000 unten > 40 und im 1500er ist noch platz
$pump3to1 = "on";
log_telegram("4",$log_name,"1: $temps{'3002'} > 40 && $temps{'1501'} < 40\n Pumpe ein","remotebot");
} elsif ($temps{$grenzfuehler-1} > $VLtemp){ ## Wenn genug Wärme im 1500er ist, Grenze ist variabel
$pump3to1 = "off";
log_telegram("4",$log_name,"2: gf-1: $temps{$grenzfuehler-1} > VLtemp: $VLtemp\n Pumpe aus","remotebot");
log_telegram("5",$log_name,"gf $grenzfuehler","remotebot");
} elsif($temps{$grenzfuehler+1} < $VLtemp){
$pump3to1 = "on";
log_telegram("4",$log_name,"3:gf+1: $temps{$grenzfuehler+1} < VLtemp: $VLtemp\n Pumpe ein","remotebot");
} elsif($temps{'3011'} > $temps{'1509'} && $temps{'3011'} > $temps{'1510'}){
$pump3to1 = "on";
log_telegram("4",$log_name,"4: $temps{'3011'} > $temps{'1510'}\n Pumpe ein","remotebot");
}
## Wenn die Pumpe schon das tut, was sie soll, brauchen wir sie nicht schalten
my $pumpstate = ReadingsVal("KNX02.O08_Aktor_UWP_3000_1500","state",0);
log_telegram("5",$log_name,"pumpstate $pumpstate","remotebot");
if($pumpstate eq $pump3to1){
log_telegram("4",$log_name,"Pumpe ist bereits: _ $pumpstate _, tue nichts.","remotebot");
}else {
log_telegram("3",$log_name,"schalte Pumpe _ $pump3to1 _","remotebot");
fhem("set KNX02.O08_Aktor_UWP_3000_1500 $pump3to1");
}

if ($previous_loglevel != $subloglevel){
fhem("attr global verboseTelegram $previous_loglevel");
}

}



Da sich subroutinen leider nicht selbst aufrufen können, hab ich das mit einem DOIF alle 60 sekunden getan:
( nur die Kurzfassung, da ich in der zwischenzeit auch ein bisschen rumgebastelt hab :
([+60])({
move_heat();
})


Damit ich sehen kann, ob die Pumpe gerade läuft oder nicht, hab ich mir in der tabletUI ein widget angelegt, welches mir den aktuellen Status von KNX02.O08_Aktor_UWP_3000_1500 anzeigt. Damit ich auch schalten kann, habe ich ein switch-widget angelegt und schalte damit direkt den Aktor.
Da ist natürlich keine Kommunikation zwischen dem DOIF, der sub und mir vorhanden. Mit der "ReadingsAge()" -Idee könnte man zumindest raten, ob der letzte schaltbefehl vor %60 Sekunden kam (also vom PC) oder ich von Hand eingeschaltet habe. Lässt zwar immernoch eine gewisse Wahrscheinlichkeit zu, dass ich genau im richtigen Moment geklickt hab....

Da ich aber bereits des öfteren mit der "mach noch ein dummy, mach noch ein notify" -policy etwas hadere (ich setze z.B. mittlerweile auch die Tasterevents von KNX in einer großen sub um, anstatt für jeden Taster ein eigenes notify zu haben - da habe ich mehrfach den Überblick verloren... ) möchte ich das gerne möglichst einfach lösen.
Am liebsten wäre mir, wenn das in perl ginge. Leider kann man innerhalb der subs keine Variablen speichern, so dass ich ebenfalls bereits darüber nachgedacht habe, ein Device als "Storage" anzulegen und dort benötigte Variablen abzulegen und wieder zu holen. Dagegen spricht, dass keine Gruppierung möglich ist (ausser, mit mehreren Devices) und dass ich nicht weiss, ob ein "ReadingsVal(), rechne was, setreading xy" weniger Rechenintensiv ist als zusätzliche Events durch zusätzliche Devices...

In der Zwischenzeit hab ich mein DOIF wie folgt umgebaut:

Internals:
   DEF        ([+60] && [$SELF:pump_mode] eq "auto")({
move_heat();
})
DOELSEIF ([$SELF:pump_mode] eq "man_on")
(
set KNX02.O08_Aktor_UWP_3000_1500 on,
setreading $SELF pump_mode man_on
)
(
setreading $SELF pump_mode auto
)
DOELSEIF ([$SELF:pump_mode] eq "man_off")
(
set KNX02.O08_Aktor_UWP_3000_1500 off,
setreading $SELF pump_mode man_off
)
(
setreading $SELF pump_mode auto
)
DOELSEIF ([$SELF:pump_mode] eq "auto")
(
setreading $SELF pump_mode auto
)
   NAME       DF_Speicher_Umladen
   NR         648
   NTFY_ORDER 50-DF_Speicher_Umladen
   STATE      auto
   TYPE       DOIF
   READINGS:
     2017-10-24 15:45:35   Pumpe_3000_1500 off
     2018-03-15 12:36:59   cmd             1
     2018-03-15 12:36:59   cmd_event       timer_1
     2018-03-15 12:36:59   cmd_nr          1
     2018-03-15 11:37:59   mode            enabled
     2018-03-15 11:38:46   pump_mode       auto
     2018-03-15 12:36:59   state           auto
     2018-03-15 12:36:59   timer_01_c01    15.03.2018 12:37:59
     2018-03-15 11:39:04   wait_timer      no timer
   Regex:
   condition:
     0          DOIF_time_once($hash,0,$wday) && ReadingValDoIf($hash,'DF_Speicher_Umladen','pump_mode') eq "auto"
     1          ReadingValDoIf($hash,'DF_Speicher_Umladen','pump_mode') eq "man_on"
     2          ReadingValDoIf($hash,'DF_Speicher_Umladen','pump_mode') eq "man_off"
     3          ReadingValDoIf($hash,'DF_Speicher_Umladen','pump_mode') eq "auto"
   days:
   devices:
     0           DF_Speicher_Umladen
     1           DF_Speicher_Umladen
     2           DF_Speicher_Umladen
     3           DF_Speicher_Umladen
     all         DF_Speicher_Umladen
   do:
     0:
       0          { move_heat(); }
     1:
       0           set KNX02.O08_Aktor_UWP_3000_1500 on, setreading DF_Speicher_Umladen pump_mode man_on
       1           setreading DF_Speicher_Umladen pump_mode auto
     2:
       0           set KNX02.O08_Aktor_UWP_3000_1500 off, setreading DF_Speicher_Umladen pump_mode man_off
       1           setreading DF_Speicher_Umladen pump_mode auto
     3:
       0           setreading DF_Speicher_Umladen pump_mode auto
     4:
   helper:
     DOIF_Readings_events
     DOIF_eventas
     event      timer_1
     globalinit 1
     last_timer 1
     sleepdevice set_cmd_2
     sleepsubtimer 1
     sleeptimer -1
     timerdev   
     timerevent timer_1
     timereventsState
     triggerDev
     timerevents:
       timer_1
     triggerEvents:
       timer_1
   internals:
   interval:
   itimer:
   localtime:
     0          1521113879
   readings:
     0           DF_Speicher_Umladen:pump_mode
     1           DF_Speicher_Umladen:pump_mode
     2           DF_Speicher_Umladen:pump_mode
     3           DF_Speicher_Umladen:pump_mode
     all         DF_Speicher_Umladen:pump_mode
   realtime:
     0          12:37:59
   time:
     0          +60
   timeCond:
     0          0
   timer:
     0          0
   timers:
     0           0
   triggertime:
     1521113879:
       localtime  1521113879
       hash:
   uiState:
   uiTable:
Attributes:
   DbLogInclude Pumpe_3000_1500
   cmdState   auto|an1,an2|aus1,aus2|auto
   do         always
   event-on-change-reading Pumpe_3000_1500
   room       Heizung,HolzVergaser,_doif
   wait       0:0,3600:0,3600:0
   widgetOverride cmdState:textField-long


Das ist der (zumindest für diese Situation) einfachste mir bekannte Weg.
Habt ihr Alternativen?

Grüße,
Stephan
FHEM nightly auf Intel Atom (lubuntu) mit VDSL 50000 ;-)
Nutze zur Zeit OneWire und KNX

Beta-User

Danke für das deutlich mehr an Infos, soviel wäre dann auch wieder nicht erforderlich gewesen; ist halt nicht so lustig zu raten, was denn jetzt an FHEM-Devices vorhanden ist und was die ggf. an Optionen und vorhandenen Infos bieten ;) .

Da du den Aktor direkt schaltest, geht das mit readingsAge eher nicht, es sei denn, du würdest prüfen, ob weniger als 58 sek. durch sind, um dann ein reading "manual" beim Aktor zu setzen (? mit toggle-Funktion).

Grundsätzlich wage ich als Perl-noob zu behaupten, dass ein reading...update() das System deutlich weniger belastet, als Events zu produzieren (mit Attribut oder als set für einen dummy).

Und die Häufigkeit des Durchlaufs deiner Funktion kommt mir auch eher hoch vor, aber das nur nebenbei. Kann nicht sagen, ob das für diesen Anwendungsfall gut ist und gg. einer Reaktion auf (mehrere alternative) Events Aufwand spart.

Interessante Sache jedenfalls!

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

abc2006

Zitat von: Beta-User am 15 März 2018, 13:38:25
soviel wäre dann auch wieder nicht erforderlich gewesen;
Da ist jemand nicht zufriedenzustellen :)  ;D

Zitat
ist halt nicht so lustig zu raten, was denn jetzt an FHEM-Devices vorhanden ist und was die ggf. an Optionen und vorhandenen Infos bieten ;)

Da hast du recht. Anscheinend kam mein Anliegen dann nicht so richtig raus: ich wollte absichtlich keine "auf meine Situation" angepasste Lösung, sondern Ideen, die Problematik der "viel zu vielen Devices" in den Griff zu kriegen.

Hab z.B. meine KNX-Taster (bisher glaub 48 Stück) nicht mehr über 48 Notifies geschaltet, sondern verwende nur eines, was auf KNX* hört, und entscheide in einer sub, was passieren soll. Damit habe ich viel mehr Flexibilität und Übersicht...

Grüße,
Stephan
FHEM nightly auf Intel Atom (lubuntu) mit VDSL 50000 ;-)
Nutze zur Zeit OneWire und KNX

Beta-User

Zitat von: abc2006 am 15 März 2018, 13:45:26
Da ist jemand nicht zufriedenzustellen :) ;D
8)
Zitat von: abc2006 am 15 März 2018, 13:45:26
ich wollte absichtlich keine "auf meine Situation" angepasste Lösung, sondern Ideen, die Problematik der "viel zu vielen Devices" in den Griff zu kriegen.
Den Ansatz finde ich auch gut, meine "Kritik" zielte ja nur darauf, dass es einen Unterschied macht, ob man einen Taster verwendet, der Events wirft (und auch ein readingsAge() dazu), um einen Aktor zu schalten, oder ob man - wie sich dann nachträglich rausgestellt hat - den Aktor direkt über die Weboberfläche schaltet. Dann hat man nur die Werte am Aktor, aber auch daraus läßt sich was basteln (siehe letzter Beitrag ;) ).

Zitat von: abc2006 am 15 März 2018, 13:45:26
Hab z.B. meine KNX-Taster (bisher glaub 48 Stück) nicht mehr über 48 Notifies geschaltet, sondern verwende nur eines, was auf KNX* hört, und entscheide in einer sub, was passieren soll. Damit habe ich viel mehr Flexibilität und Übersicht...
Sowas finde ich auch gut. Z.B. meine Rolläden und Fensterkontakte haben teilweise userattr, damit ich bei einem Event von einem der Devices nachsehen kann, ob ein "softgepeertes" anderes Device (sind alles HM-BidCoS-Geräte) auch was tun soll. Dazu reicht ein notify ;) . Bin zwar noch nicht ganz fertig, aber vom Prinzip her ist das viel einfacher als jedes Teil mit einem eigenen notify&co zu versorgen.
Da frage ich übrigens auch ab, ob der jeweilige Rolladenaktor ein "set_.*" mit einem gewissen readingsAge hat, um zu verhindern, dass sich die Funktion selber in einer Endlosschleife triggert...
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

abc2006

Zitatob man einen Taster verwendet, der Events wirft (und auch ein readingsAge() dazu), um einen Aktor zu schalten, oder ob man - wie sich dann nachträglich rausgestellt hat - den Aktor direkt über die Weboberfläche schaltet.

Klar macht das einen Unterschied. Aber nichtmal ich selbst weiss, ob ich nicht morgen auf die Idee komme, dass ein Taster an der Wand nicht doch besser ist als so eine Web-Oberfläche. Und wenn ich dann dafür alles umbauen muss ... das meinte ich mit generisch.

Ich kämpfe zum beispiel schon ewig mit der Messung von Wärmeleistung in Flüssigkeiten.
Also: Thermometer VL, Thermometer RL, Durchfluss.
Für den Durchfluss musste ich bereits 4 verschiedene Geräte ausprobieren. Anfangs habe ich die Berechnung der Leistung im Durchfluss-Device vorgenommen. Mit dem Erfolg, dass ich jedes mal alle Erwähnungen umbenennen musste, wenn ich das Device geändert hab. Jetzt gibts ein (zusätzliches) Dummy-Device D_WMZ_Heizung, welches extern gespeist wird, dann userReadings berechnet und abgefragt wird. Dann ists egal, woher die Werte kommen. Hätt ich das nur mal früher gewusst.... :)

Solche Ideen sinds, die mir manchmal fehlen....

Zitat
... userattr, damit ich bei einem Event von einem der Devices nachsehen kann, ob ein "softgepeertes" anderes Device auch was tun soll.
versteh ich grad nicht. Könntest du ja mal posten, wenn du durch bist. Vielleicht kann ich mir ne Anregung holen.

Grüße,
Stephan
FHEM nightly auf Intel Atom (lubuntu) mit VDSL 50000 ;-)
Nutze zur Zeit OneWire und KNX

Beta-User

Kurzfassung, um das Prinzip zu erläutern:

Jalousie:
define Jalousie_Mitte CUL_HM 2A4820
attr Jalousie_Mitte userattr room_map structexclude WindowContactAssociated WindowContactOnHoldState WindowContactOpenMaxClosed WindowContactTiltedMaxClosed WindowContactTiltedMaxClosed JalousieTurnValue JalousieTurnValue WindowContactTiltedMaxClosed
attr Jalousie_Mitte JalousieTurnValue 3
attr Jalousie_Mitte WindowContactAssociated Terrassentuer_EZ
attr Jalousie_Mitte WindowContactOpenMaxClosed 85
attr Jalousie_Mitte WindowContactTiltedMaxClosed 40


Zugehöriger Fensterkontakt:
define Terrassentuer_EZ CUL_HM 2ADF5C
attr Terrassentuer_EZ userattr ShutterAssociated
attr Terrassentuer_EZ ShutterAssociated Jalousie_Mitte


notify:
define n_Rolladen_Window notify .*(closed|open|tilted)|(Rolladen_.*|Jalousie_.*).(motor:.stop.*|set_.*|motor..down.*) { HM_ShutterUtils_Notify($NAME,$EVENT) }

myUtils-Code (Auszug):

sub HM_ShutterUtils_Notify($$) {
    #Als Parameter muss der device-Name sowie der Event übergeben werden
    #notify-Definition:
    #defmod n_Rolladen_Window notify .*(closed|open|tilted)|(Rolladen_.*|Jalousie_.*).(motor:.stop.*|set_.*|motor..down.*) { HM_ShutterUtils_Notify($NAME,$EVENT) }
    my ($dev, $rawEvent) = @_;
   
    #Ein "set" löst zwei Events aus, einmal beim (logischen) Gerät direkt, und dann beim entsprechenden Aktor.
    #Wir brauchen nur einen (den ersten).
    if ($rawEvent =~ /level:/){
        Log3 $dev, 4, "Doppelevent: $rawEvent";
        return;
    }
   
    #Erst mal prüfen, ob das übergebene device überhaupt existiert
    if ($defs{$dev}) {
       
        #Als erstes brauchen wir die Info, welcher Rolladen bzw. welcher Fenster- bzw. Türkontakt
        #betroffen sind
        my $shutter=$dev;
        my $textEvent = "Rollo";
       
        if (AttrVal($shutter,'subType', undef) ne "blindActuator"){
            $shutter = AttrVal($dev,'ShutterAssociated',undef);
            $textEvent = "Window";
        }
        my $windowcontact = AttrVal($shutter,'WindowContactAssociated',"none");
        my $readingsAge = ReadingsAge($shutter,'WindowContactOnHoldState',60);
       
        if (!$shutter) {}
       
        #Ausfiltern von Selbsttriggern!
        elsif ($readingsAge < 2) {
            Log3 $dev, 4, "Most likely we are triggering ourself: $dev $rawEvent";
            return;
        }
   
        else {       
            #Wir speichern ein paar Infos, damit das nicht zu unübersichtlich wird
            my $position = ReadingsVal($shutter,'pct',0);
            my $winState = Value($windowcontact);
            my $maxPosOpen = AttrVal($shutter,'WindowContactOpenMaxClosed',100)+0.5;
            my $maxPosTilted = AttrVal($shutter,'WindowContactTiltedMaxClosed',100)+0.5;
            my $turnValue = AttrVal($shutter,'JalousieTurnValue',0);
            my $onHoldState = ReadingsVal($shutter,'WindowContactOnHoldState',"none");
            my $turnPosOpen = $maxPosOpen+$turnValue;
            my $turnPosTilted = $maxPosTilted+$turnValue;
            my $targetPosOpen = $maxPosOpen+$turnValue;
            my $targetPosTilted = $maxPosTilted+$turnValue;
            my $motorReading = ReadingsVal($shutter,'motor',0);
            my $event = "none";
              my $setPosition = $position;
            if($rawEvent =~ /set_/) {
                $setPosition = substr $rawEvent, 4, ; #FHEM-Befehl
                if ($setPosition eq "on") {$setPosition = 100;}
                elsif ($setPosition eq "off") {$setPosition = 0;}
                #dann war der Trigger über Tastendruck oder Motor-Bewegung
                }
elsif ($motorReading =~ /down/) { $setPosition = -1;}
.....
..

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