[gelöst] event-on-change-reading Attribut Leerzeichen ermöglichen?

Begonnen von Waldmensch, 09 März 2019, 18:46:22

Vorheriges Thema - Nächstes Thema

Waldmensch

Hallo,

Ich weiß nicht, wo man Feature Requests posten kann, Im Anfängerbereich wird es niemandem wehtun.

Wäre es möglich in den Attributen, die kommagetrennte Ketten verwenden, generell Leerzeichen zu ermöglichen? Speziell in event-on-change-reading zerhaut es die komplette Webansicht, weil der Browser ohne Leerzeichen nicht umbricht. Das zieht dann das gesamte Layout auf die Breite des Attributes. Sobald man irgendwo ein Leerzeichen hinter einem Komma setzt, bricht der Browser dort um, aber der betreffende Eintrag wird ignoriert. Im Perl sollte es doch sowas wie ein trim() geben, was man nach dem split() ausführen kann um Leerzeichen vor der Verwendung der Einzelwerte zu entfernen. Oder als Delimiter im Split ein (,|, ) als dirty Fix.

Die Krux ist ja, dass man bei Nutzung von event-on-change-reading alle Readings eintragen muss. Ich habe mal ein Beispiel angehängt.




Wzut

Zitat von: Waldmensch am 09 März 2019, 18:46:22
Die Krux ist ja, dass man bei Nutzung von event-on-change-reading alle Readings eintragen muss.
sagt wer ? RegEx ist das Zauberwort ... :)
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

Waldmensch

Ich will aber nicht alle Readings auf on-change. Ein paar sollen auf on-update und ein paar sollen gar nicht. Wie soll ich das mit regex machen?


Gesendet von iPhone mit Tapatalk

Wzut

RegEx ist nicht immer nur .* und damit alles es geht auch mit Teilen wie (wind.*|temp.*|heinz.*|willi.*|karl.*) - wird auf jeden Fall um einiges kürzer 
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

Waldmensch

Zitat von: Wzut am 09 März 2019, 19:07:39
RegEx ist nicht immer nur .* und damit alles es geht auch mit Teilen wie (wind.*|temp.*|heinz.*|willi.*|karl.*) - wird auf jeden Fall um einiges kürzer

Das ist nicht sehr praktikabel, Leerzeichen gehen auch dort nicht und false positives sind vorprogrammiert. Allein bei wind.* hätte ich Minimum 5 Readings zu viel, die mich gar nicht interessieren und nur die db zumüllen. Ergo wäre eine Liste mit Regex nur unwesentlich kürzer und würde auch nicht umbrechen.


Gesendet von iPhone mit Tapatalk

Otto123

Hi Waldmensch,

Du nimmst die event-xxx attr als Logging Filter?

Bei filelog gibt es ignoreregexp, gibt es sowas für die DB nicht auch?
Nur als Idee ...

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

Waldmensch

Nicht nur als Logging Filter. Natürlich könnte man auch bei dblog eine riesige exclude Liste führen, dann würden aber immernoch die events getriggert.
Ich halte es für sinnvoller, die Definitionen in den einzelnen Devices vorzunehmen. Im Fehlerfall sucht man sich sonst wahrscheinlich einen Wolf. Bestes Beispiel sind irgendwelche RSSI Werte. Die braucht man ja eigentlich nie, aber manchmal eben doch, wenn man ein Device ,,auf dem Kieker hat". Also wäre es falsch, RSSI generell im dblog auszufiltern.


Gesendet von iPhone mit Tapatalk

herrmannj

wenn es um das loggen geht ist mMn der einzige richtige Weg die logfile Definition richtig anzulegen.

Waldmensch

Nein, es geht vorrangig um Events. Die Wetterstation kommt alle 30Sekunden, was auch gut ist. Allerdings brauche ich die meisten Events halt nur, wenn sie sich ändern. Ich kann sie also nicht vom Log ausschließen, weil ich sie ja loggen will. Viele Readings der Station brauche ich nicht. Wenn ich sie nur vom logging ausschließen würde, würden trotzdem die Events generiert. An der granularen Pflege der on-change und on-update Attribute führt hier kein Weg vorbei.


Gesendet von iPhone mit Tapatalk

Otto123

dann mach .* und den Rest im Logging.
Und Wetter ändert sich nicht in 30 sec, Wetterwerte in dieser Frequenz sind Unfug.

Ob jetzt das holen dieser Werte die Last erzeugt oder die unnötigen Events?
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

Waldmensch

In welchem Abstand Werte für mich Sinn machen, ist bitte meine Sache.
Der Abruf läuft entkoppelt von FHEM, die Events werden allerdings im Kontext von FHEM ausgeführt. Das heißt, verbundene Notify und DOIF werden ausgeführt, das Webinterface und FTUI wird aktualisiert obwohl nur nötig bei on-change

Ich habe eine Simple Frage gestellt, einen Feature Request, ob man das nicht so bauen kann, dass Leerzeichen im Attribut ignoriert werden. Das lässt sich vermutlich mit einer codezeile, einem regex.Replace() o.ä. (Keine Ahnung, was Perl da für Möglichkeiten bietet) lösen.


Gesendet von iPhone mit Tapatalk

CoolTux

Zitat von: Waldmensch am 09 März 2019, 18:46:22
Wäre es möglich in den Attributen, die kommagetrennte Ketten verwenden, generell Leerzeichen zu ermöglichen?

Nein dies ist nicht Möglich!
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

Waldmensch

Ich habe mir mal den Source von fhem.pl angeschaut. Dort werden die Delimiter als "s" spezifiziert.

Zitatmy %ra = (
  "suppressReading"            => { s=>"\n" },
  "event-aggregator"           => { s=>",", c=>".attraggr" },
  "event-on-update-reading"    => { s=>",", c=>".attreour" },
  "event-on-change-reading"    => { s=>",", c=>".attreocr",   r=>":.*" },
  "timestamp-on-change-reading"=> { s=>",", c=>".attrtocr" },
  "event-min-interval"         => { s=>",", c=>".attrminint", r=>":.*" },
  "oldreadings"                => { s=>",", c=>".or" },
  "devStateIcon"               => { s=>" ", r=>":.*", p=>"^{.*}\$",
                                    pv=>{"%name"=>1, "%state"=>1, "%type"=>1} },
);

Im sub CommandAttr($$) in Zeile 2856 wird dann ein
my @a = split($ra{$attrName}{s}, $lval) ; ausgeführt, wo das "s" als Pattern wieder auftaucht. Nach Perl Spezifikation (https://perldoc.perl.org/functions/split.html) ist die Kombination von mehreren Delimitern im Pattern möglich (s. verlinkte Seite ganz unten)
    split(/-|,/, "1-10,20", 3)
    # ('1', '10', '20')


Was spricht also dagegen, Den Delimiter als (,|, ) auszulegen in dieser Zeile?
"event-on-change-reading"    => { s=>",", c=>".attreocr",   r=>":.*" },
also
"event-on-change-reading"    => { s=>",|, ", c=>".attreocr",   r=>":.*" },

Waldmensch

#13
Natürlich wäre es sauberer, den Delimiter bei Komma zu belassen wie es ist (also den Vorpost ignorieren),
use Text::Trim qw(trim);
Zu importieren und in Zeile 2858 aus
my $v = $v; # resolve the reference to avoid changing @a itself
das
my $v = trim($v); # resolve the reference to avoid changing @a itself
zu machen

Alternativ, statt dem zusätzlichen Import geht natürlich auch eine simple eigene Funktion
sub  trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };

Dann wäre es egal wie viele Leerzeichen sich da in der Zeichenkette tummeln. Als Bonus würde es sich auf alle diese kommaseparierten Attribute der Liste (Vorpost) auswirken. Da das trim() erst nach dem split() stattfindet, gibt es IMHO auch kein Problem bei Attributen, die ein Leerzeichen als Delimiter haben.

Waldmensch

#14
Okay, ich habe es jetzt mal im Selbstversuch getestet. In fhem.pl unten eine Funktion "trim" angefügt. Keine Ahnung ob ein Import von trim() effizienter wäre, das wissen andere Leute sicher besser.
sub 
trim
{
  my $s = shift;
  $s =~ s/^\s+|\s+$//g;
  return $s
};


Dann in der Schleife ab Zeile 2857 @a mit $v = trim($v); modifizieren

        my @a = split($ra{$attrName}{s}, $lval) ;
        for my $v (@a) {
          $v = trim($v); #remove spaces in single item in @a which left eventually after split
          my $v = $v; # resolve the reference to avoid changing @a itself
          #Log 1, "Split $attrName Item $v";
          $v =~ s/$ra{$attrName}{r}// if($ra{$attrName}{r});
          my $err ="Argument $v for attr $sdev $attrName is not a valid regexp";
          return "$err: use .* instead of *" if($v =~ /^\*/); # no err in eval!?
          eval { "Hallo" =~ m/^$v$/ };
          return "$err: $@" if($@);
        }


Funktioniert bei mir einwandfrei. Folgendes Attribut wird erfolgreich eingelesen und die Events werden normal getriggert
attr Wetterstation event-on-change-reading brightness, dewPoint, heatIndex, humidity, humidityInside, pressureAbs, pressureRel, pressureRel_calculated, rainPerDay, rainPerMonth, rainPerWeek, rainPerYear, rainTotal, temperature, temperatureInside, uv, uvIndex, wind, windChill, windDirection, windGusts, windkmh, windGustskmh, brightness30k, rain24h, isBrightness_above_5k, isBrightness_below_100

Ich bin jetzt kein Perl Guru und vielleicht gibt es auch einen besseren Ansatz. Falls es so oder anders in FHEM einfließt, fänd ich es toll, ansonsten bau ichs mir nach jedem Update halt selbst wieder ein. Ist ja jetzt nicht so ein großer Aufwand