Feineinstellung - mehrere Events führen ungewollt zu mehrfacher Ausführung

Begonnen von RomanticBoy83, 11 September 2015, 20:38:33

Vorheriges Thema - Nächstes Thema

RomanticBoy83

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

marvin78


Puschel74

#2
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.
Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

Puschel74

#3
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.
Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

RomanticBoy83

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).

Puschel74

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.
Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

RomanticBoy83

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

Puschel74

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  ;)
Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

RomanticBoy83

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.

Puschel74

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.
Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

RomanticBoy83

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");
}

Puschel74

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  :-[
Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

RomanticBoy83

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"
    }
  }
}

Puschel74

Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

RomanticBoy83

#14
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