FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: RomanticBoy83 am 11 September 2015, 20:38:33

Titel: Feineinstellung - mehrere Events führen ungewollt zu mehrfacher Ausführung
Beitrag von: RomanticBoy83 am 11 September 2015, 20:38:33
Hallo liebe Gemeinde
nun habe ich nach vielem lesen und erfolgreichen programieren doch eine Frage!

Ausgangsstellung:
Meine Rollosteuerung mit Homematic ist soweit fertig eingerichtet und wird von mir nun nur noch optimiert. Leider habe ich einen "Fehler" festgestellt, welchen ich nicht recht zu händel weiß.
Events:
2015-09-11 20:07:33 CUL_HM wz_ro_tuer level: set_0
2015-09-11 20:07:33 CUL_HM wz_ro_tuer set_0
2015-09-11 20:07:33 CUL_HM wz_ro_tuer level: set_0
2015-09-11 20:07:33 CUL_HM wz_ro_tuer set_0
2015-09-11 20:07:33 readingsGroup rg_Rollosteuerung du_Tageslicht: 0
2015-09-11 20:07:33 dummy du_Tageslicht 0

Logs:
2015.09.11 20:07:33 3: CUL_HM set wz_ro_tuer 0
2015.09.11 20:07:33 3: CUL_HM set wz_ro_tuer 0


Frage:
Wie verhindere ich, dass das Kommando "set wz_ro_tuer 0" zweimal aufgerufen wird.

Erklärung:
Der Ursprung kann nur in diesem at liegen, bei welchem du_Tageslicht verändert wird.
*{sunset(0,"18:00","22:00")} set wz_ro_essecke 0; set wz_ro_sofa 0; set ke_ro 0; set ba_ro 0; set ku_ro 0; set du_Tageslicht 0
Leider gibt es zwei Events, weshalb mein notify nt_WzGriff
wz_gr_tuer:(open|closed)|du_Tageslicht:.*{
  if (Value("du_xx_ro_auto") eq "an"){
    if (Value("wz_gr_tuer") eq "closed" && Value("du_Tageslicht") == 0){
        fhem "set wz_ro_tuer 0"
    } elsif (Value("wz_gr_tuer") eq "open" && Value("wz_ro_tuer") ne "offen"){
        fhem "set wz_ro_tuer 100"
    }
  }
}
zweimal ausgeführt wird.
Die Stelle  du_Tageslicht:.* ist also nach meiner Meinung nicht ganz 100%. Leider habe ich keine Idee, wie ich die beiden Events
2015-09-11 20:07:33 readingsGroup rg_Rollosteuerung du_Tageslicht: 0
2015-09-11 20:07:33 dummy du_Tageslicht 0
auseinander halten kann.

Anmerkung:
Der Griff löst bei jeder Bewegung vier Events aus, weshalb ich im notify nun das "oder" für wz_gr_tuer:(open|closed) gesetzt hatte um diese auseinander zu halten. Das Problem war also ein ähnliches, was sich jedoch auf den Platzhalter beschränkte
Titel: Antw:Feineinstellung - mehrere Events führen zu mehrfachen Ausführungen
Beitrag von: marvin78 am 11 September 2015, 20:41:01
Schau dir event-on-change reading an.
Titel: Antw:Feineinstellung - mehrere Events führen zu mehrfachen Ausführungen
Beitrag von: Puschel74 am 11 September 2015, 20:42:43
ZitatLeider habe ich keine Idee, wie ich die beiden Events
Über das Device behaupte ich mal.

Einmal ist es die RG und einmal der Dummy.

(wz_gr_tuer|<Name_des_dummy>):(open|closed|du_Tageslicht):.*{
wäre einen Versuch wert.
Titel: Antw:Feineinstellung - mehrere Events führen zu mehrfachen Ausführungen
Beitrag von: Puschel74 am 11 September 2015, 20:43:16
Zitat von: marvin78 am 11 September 2015, 20:41:01
Schau dir event-on-change reading an.
Wird wohl nichts bringen bei 2 Device.
Für jedes Device setzen bringt das durchaus was  ::)

Edith: Im Forum gibt es bereits eine Diskussion das RG auch Events (mehrere) auslöst - ich hab den aber nicht weiter verfolgt.
Titel: Antw:Feineinstellung - mehrere Events führen ungewollt zu mehrfacher Ausführung
Beitrag von: RomanticBoy83 am 11 September 2015, 20:47:11
Vielen Dank für deinen Tip! Leider kann mir diese Idee vermutlich keinen Fortschritt bringen, da der Dummy du_Tageslicht nur ein einziges reading hat und somit der Tip nicht hier her passt.
Die beiden Events sind ein state und ein reading. Auf beide reagiert das notify (von mir ungewollt).
Titel: Antw:Feineinstellung - mehrere Events führen ungewollt zu mehrfacher Ausführung
Beitrag von: Puschel74 am 11 September 2015, 20:48:26
Zitat von: RomanticBoy83 am 11 September 2015, 20:47:11
Vielen Dank für deinen Tip! Leider kann mir diese Idee vermutlich keinen Fortschritt bringen, da der Dummy du_Tageslicht nur ein einziges reading hat und somit der Tip nicht hier her passt.
Die beiden Events sind ein state und ein reading. Auf beide reagiert das notify (von mir ungewollt).
Aber du versuchst es auch nicht - ok.
Dann eben nicht.
Titel: Antw:Feineinstellung - mehrere Events führen ungewollt zu mehrfacher Ausführung
Beitrag von: RomanticBoy83 am 11 September 2015, 21:12:11
Boh die Antwortfunktion - gewöhnungsbedürftig!!!

zu marvin78:
Vielen Dank für deinen Tip! Leider kann mir diese Idee vermutlich keinen Fortschritt bringen, da der Dummy du_Tageslicht nur ein einziges reading hat und somit der Tip nicht hier her passt.
Die beiden Events sind ein state und ein reading. Auf beide reagiert das notify (von mir ungewollt).

zu Puschel74:
Vielen Dank für dein Codeschnipsel. Leider ist die Syntax des codes falsch. Wenn ich es jedoch richtig interpretiere, dann ist es nur eine andere Schreibweise, welche mit der Boolschenalgebra erreicht wurde.
(wz_gr_tuer|<Name_des_dummy>):(open|closed|du_Tageslicht):.*{
soll warscheinlich heißen (der Wert von du_Tageslicht kann 0 oder 100 sein):
   (wz_gr_tuer|du_Tageslicht):(open|closed|0|100){
(  wz_gr_tuer:(open|closed|0|100) | du_Tageslicht:(open|closed|0|100)  ) {
(  wz_gr_tuer:(open|closed) | du_Tageslicht:(0|100)  ) {
(  wz_gr_tuer:(open|closed) | du_Tageslicht:.*  ) {

Das wäre also das, was ich bereits implementiert hätte.

Meine Idee:
Ich versuche die ganze Zeit mit einem +,? etc als präfix zu arbeiten. Das habe ich bereits in der readinggroups getan, wodurch man die verschiedenen internals, readings, attributes auseinanderhalten konnte
Titel: Antw:Feineinstellung - mehrere Events führen ungewollt zu mehrfacher Ausführung
Beitrag von: Puschel74 am 11 September 2015, 21:15:43
Das <Name_des_dummy> musst du durch den Namen deines Dummy ersetzen.
Ich hätte den gerne für dich eingesetzt aber ich hab den Namen nicht gefunden.
Edith: Sinnvolle Namensgebung setze ich mal voraus  ;)
Titel: Antw:Feineinstellung - mehrere Events führen ungewollt zu mehrfacher Ausführung
Beitrag von: RomanticBoy83 am 11 September 2015, 21:20:59
An Puschel74:
Das habe ich auch schon so verstanden. Der Name des Dummy lautet du_Tageslicht.
Wenn ich den so einsetze, und die Syntax anpasse, dann kommt die von mir verfasste Rechnung zum gleichen Ergebnis, welches ich bereits implementiert habe.
Titel: Antw:Feineinstellung - mehrere Events führen ungewollt zu mehrfacher Ausführung
Beitrag von: Puschel74 am 11 September 2015, 21:34:02
Und das:
(wz_gr_tuer|du_Tageslicht):(open|closed).*:.*{

Mit dem regexp musst du noch spielen - es kann (und wird vermutlich auch) sein das der .* VOR dem : noch mit einem | in die Klammer muss.
Blödsinn - dann triggert das regexp ja wieder auf jedes Event.
Gib dem Dummy doch ein Reading und nimm dieses in das regexp mit auf - das wäre einfacher und würde auch eher klappen.

Edith: Aus dem set du_Tageslicht muss dann ein setreading du_Tageslicht <Name_des_Reading> Wertwerden.
Und aus dem regexp dann ein(wz_gr_tuer|du_Tageslicht):(open|closed|<Name_des_Reading_von_du_Tageslicht>).*{

Edith:
Zitatsoll warscheinlich heißen (der Wert von du_Tageslicht kann 0 oder 100 sein):
Nö, das heisst nur das du_Tageslicht irgendwas schickt - egal was.
Das kann auch on oder Wupp oder 27 sein.
Ich schlag aber mal vor du stellst einen Code-Zustand her auf dessen Ebene wir hier weiter helfen können und postest diesen auch bitte.
Titel: Antw:Feineinstellung - mehrere Events führen ungewollt zu mehrfacher Ausführung
Beitrag von: RomanticBoy83 am 11 September 2015, 22:03:06
OK, jetzt kommen wir der Sache schon sehr viel näher. Den Gedanken kann ich nachvollziehen.

Problem:
Das "set" kommt bei mir aus einer sub-Methode(Perlcode), welches natürlich für das "Allgemeine" programmiert ist und deshalb nicht einfach so in "setirgendetwasanderes" verändert werden kann. Grund sind die Rolloaktoren, welche mit dem Kommando "set" gefahren werden.

Frage:
Kann ich einem Rolloaktor (HM-LC-Bl1PBU-FM) mehrere eigene readings verpassen?
Grund für meine Frage ist, dass ich nicht weiß, wie ich den Satz:
ZitatGib dem Dummy doch ein Reading und nimm dieses in das regexp mit auf - das wäre einfacher und würde auch eher klappen.
umsetzen kann. Ich muss mich also ersteinmal belesen.

Zum Verständnis hier meine Funktion, welches das Notify erzeugt:
################################################################################
### Rollosteuerung #############################################################
################################################################################

sub makeAutoRolloAts() {
  Log(3,"Rebuild all at_autoRolloXX to control the window-shutters!");
  fhem("delete at_autoRollo.");
  if (Value("du_xx_ro_auto") eq "an"){
    my $upTime = "{sunrise(0,\"06:00\",\"07:30\")}";
    my $downTime = "{sunset(0,\"18:00\",\"22:00\")}";
    my @devices = (#["wz_ro_tuer",Value("du_wz_ro_auto"),Value("du_wz_ro_schatten"),Value("du_wz_ro_hoch"),Value("du_wz_ro_runter"),"ost"],
                   ["wz_ro_essecke",Value("du_wz_ro_auto"),Value("du_wz_ro_schatten"),Value("du_wz_ro_hoch"),Value("du_wz_ro_runter"),"ost"],
                   ["wz_ro_sofa",Value("du_wz_ro_auto"),Value("du_wz_ro_schatten"),Value("du_wz_ro_hoch"),Value("du_wz_ro_runter"),"ost"],
                   ["ke_ro",Value("du_ke_ro_auto"),Value("du_ke_ro_schatten"),Value("du_ke_ro_hoch"),Value("du_ke_ro_runter"),"ost"],
                   ["kz_ro",Value("du_kz_ro_auto"),Value("du_kz_ro_schatten"),Value("du_kz_ro_hoch"),Value("du_kz_ro_runter"),"west"],
                   ["ba_ro",Value("du_ba_ro_auto"),Value("du_ba_ro_schatten"),Value("du_ba_ro_hoch"),Value("du_ba_ro_runter"),"west"],
                   ["ku_ro",Value("du_ku_ro_auto"),Value("du_ku_ro_schatten"),Value("du_ku_ro_hoch"),Value("du_ku_ro_runter"),"west"],
                   ["du_Tageslicht","auto","aus","auto","auto",""]
                   );
                   # alle rolladen, welche keine automatik aktiviert haben löschen
                   for (my $index = 0; $index < @devices;){
                     if ( $devices[$index][1] eq "aus" ){
                       splice(@devices,$index,1); # lösche device
                     }else{
                       if ( $devices[$index][3] eq "auto" ) { $devices[$index][3] = $upTime; }
                       if ( $devices[$index][4] eq "auto" ) { $devices[$index][4] = $downTime; }
                       $index++;
                     }
                   }
    my @devicesUp = @devices; # copy to remove used devices
    my @devicesDown = @devices; # copy to remove used devices
    my @events; # list of all events for fhem
    my $eventsCounter = -1; # how many events are existing in the list
    my $currentTime;
    # Events zum Hochfahren erstellen
    while(@devicesUp > 0){
      $currentTime = $devicesUp[0][3];
      # füge alle mit gleicher "hoch" Zeit als ein Event hinzu
      push(@events,[$currentTime]);
      $eventsCounter++;
      for (my $index = 0; $index < @devicesUp;){
        if ($devicesUp[$index][3] eq $currentTime){
          # Beschattung berücksichtigen
          if ($devicesUp[$index][5] eq "ost" && $devicesUp[$index][2] ne "aus"){
            push($events[$eventsCounter],"set ".$devicesUp[$index][0]." ".getAbsPosRollo($devicesUp[$index][0],$devicesUp[$index][2]));
          }else{
            # Beschattung ist "aus"
            push($events[$eventsCounter],"set ".$devicesUp[$index][0]." 100");
          }
          splice(@devicesUp,$index,1); #lösche das aktuell hinzugefügte Rollo aus der Liste
        }else{
          $index++;
        }
      }
      # Rest der Liste($devicesUp) hat andere Zeit zum hochfahren
    }
    # Events zum Herunterfahren erstellen
    while(@devicesDown > 0){
      $currentTime = $devicesDown[0][4];
      # füge alle mit gleicher "herunter" Zeit als ein Event hinzu
      push(@events,[$currentTime]);
      $eventsCounter++;
      for (my $index = 0; $index < @devicesDown;){
        if ($devicesDown[$index][4] eq $currentTime){
          push($events[$eventsCounter],"set ".$devicesDown[$index][0]." 0");
          splice(@devicesDown,$index,1); #lösche das aktuell hinzugefügte Rollo aus der Liste
        }else{
          $index++;
        }
      }
      # Rest der Liste($devicesDown) hat spezielle Zeit zum herunterfahren
    }
    # Event zum Beschattungswechsel erstellen
    for (my $index = 0; $index < @devices;){
      if ( $devices[$index][2] eq "aus" ){
        splice(@devices,$index,1); # lösche device
      }else{
        $index++;
      }
    }
    if (@devices > 0){
      push(@events,["12:00"]);
      $eventsCounter++;
      foreach my $currentDevice (@devices) {
        if (@$currentDevice[5] eq "ost") {
          push($events[$eventsCounter],"set ".@$currentDevice[0]." 100");
        }else{
          push($events[$eventsCounter],"set ".@$currentDevice[0]." ".getAbsPosRollo(@$currentDevice[0],@$currentDevice[2]));
        }
      }
    }
    # erstelle alle events als at
    $eventsCounter = 0;
    foreach my $currentEvent (@events){
      $currentTime = shift(@$currentEvent);
      fhem( "define at_autoRollo".$eventsCounter." at *".$currentTime." ".(join(";; ",@$currentEvent)."\n") );
      $eventsCounter++;
    }
    fhem ("attr at_autoRollo. group Rolladensteuerung");
    fhem ("attr at_autoRollo. room Server");
  }
  fhem ("save");
}
Titel: Antw:Feineinstellung - mehrere Events führen ungewollt zu mehrfacher Ausführung
Beitrag von: Puschel74 am 11 September 2015, 22:07:49
Mit setreading kannst du jedem Device eigene Readings zuweisen und diese mit <Wert> füllen.
Versuch macht kluch  ;)
Mit ReadingsVal kannst du diese Readings auch wieder auslesen und weiter verarbeiten.

Edith: Auch ein Dummy darf Readings haben - und nicht nur einen state.
Diesen kannst du aber mit stateFormat beeinflussen.

Edith1: Grad getestet - setreading löst ja kein Event aus. Was ja logisch ist und auch so gedacht ist  ::)
Mist - tut mir leid aber ich lag mit meiner Idee leider daneben  :-[
Titel: Antw:Feineinstellung - mehrere Events führen ungewollt zu mehrfacher Ausführung
Beitrag von: RomanticBoy83 am 11 September 2015, 22:33:07
Jetzt wo du es mir sagst - kann ich mich wage dran erinnern, dass ich damit einmal herumgespielt habe um die Beschattungsposition in die Aktoren zu bekommen.

Hab' ich gerade auch ein wenig mit herumgedoktort, das Ergebnis bleibt ersteinmal gleich.

Weiterführung:
Das Problem liegt ein wenig versteckter: Die ReadingGroup mit dem Namen rg_Rollosteuerung.
Das hätten wir auch aus dem eventlog ganz am Anfang sehen können.
Sowol der Dummy du_Tageslicht als auch die ReadingGroup rg_Rollosteuerung, welche den state des du_Tageslicht beinhaltet, lösen ein Event aus, welches den gleichen Namen hat.
2015-09-11 20:07:33 readingsGroup rg_Rollosteuerung du_Tageslicht: 0
2015-09-11 20:07:33 dummy du_Tageslicht 0


Mein Versuch wird sein, das notify dahingehend zu ändern, dass ich die erste Zeile abänder in genau den String, welcher im Eventmonitor auftaucht und berücksichtigt werden soll:
wz_gr_tuer:(open|closed)|du_Tageslicht:.*{ #ändern in wz_gr_tuer:(open|closed)|dummy du_Tageslicht:.*{
  if (Value("du_xx_ro_auto") eq "an"){
    if (Value("wz_gr_tuer") eq "closed" && Value("du_Tageslicht") == 0){
        fhem "set wz_ro_tuer 0"
    } elsif (Value("wz_gr_tuer") eq "open" && Value("wz_ro_tuer") ne "offen"){
        fhem "set wz_ro_tuer 100"
    }
  }
}
Titel: Antw:Feineinstellung - mehrere Events führen zu mehrfachen Ausführungen
Beitrag von: Puschel74 am 11 September 2015, 22:35:39
Zitat von: Puschel74 am 11 September 2015, 20:42:43

Einmal ist es die RG und einmal der Dummy.

Hab ich aber geschrieben  :P
Titel: Antw:Feineinstellung - mehrere Events führen ungewollt zu mehrfacher Ausführung
Beitrag von: RomanticBoy83 am 11 September 2015, 23:08:13
Zitat von: Puschel74 am 11 September 2015, 22:35:39
Hab ich aber geschrieben  :P
Schön - hab' ich wohl ganz schnell gelesen - zu schnell um es zu verarbeiten!

Zusammenfassung:
Das notify reagiert ungewollt auf zwei events, welche Zeitgleich erscheinen. Deshalb wird etwas zweimal ausgeführt, was unnötig ist (Stichwort DutyCycle, Rechenzeit etc).
Auf die Markierten Stellen reagiert das notify (Platzhalter ist extra unterstrichen)
du_Tageslicht:.*
2015-09-11 20:07:33 readingsGroup rg_Rollosteuerung du_Tageslicht: 0
2015-09-11 20:07:33 dummy du_Tageslicht 0

Die Lösung:
Ich habe das notify dahingehend geändert, dass ich jedes Event expliziet angebe (keine Platzhalter) und mit "oder" verknüpfe. Ohne den Platzhalter rutscht der "dumme" Doppelpunkt nun zum Glück durch.
wz_gr_tuer:open|wz_gr_tuer:closed|du_Tageslicht:0|du_Tageslicht:100 {
2015-09-11 20:07:33 readingsGroup rg_Rollosteuerung du_Tageslicht: 0
2015-09-11 20:07:33 dummy du_Tageslicht 0