Wildcard Attribute in Fhemweb

Begonnen von StefanStrobel, 04 Dezember 2014, 21:53:50

Vorheriges Thema - Nächstes Thema

StefanStrobel

Hallo,

Ich verwende in mehreren Modulen (z.B. HTTPMOD und FReplacer) Attribute mit Namen wie ReadingsName.* oder Reading[0-9]+Regex. Nun kam von Anwendern der nachvollziehbare Wunsch, dass man auch auf solche Attribute in Fhemweb klicken kann um sie zu bearbeiten.
Leider stecke ich in JavaScript nicht so drin um hier einen Patch anbieten zu können.
Kann hier jemand helfen? Wäre das eine größere Änderung?

Gruss / Thanx
   Stefan

rudolfkoenig

Das Problem ist nicht wirklich JavaScript: das angeklickte Attribut muss im Select vorkommen. Und diese Liste wird vom getAllAttr() der HTTPMOD-Instanz vorgegeben. Und es gibt z.Zt. nur eine Moeglichkeit, eine instanz-abhaengige Attributliste zu produzieren, naemlich mit userattr fuer diese Instanz.

D.h. HTTPMOD muesste dafuer sorgen, dass bereits angelegte Attribute einer HTTPMOD-Instanz in der Hilfe (bzw. getAllAttr) auftauchen, indem man diese Attribute als userattr fuer diese Instanz definiert.
Dann kann man diese auch im Dropdown auswaehlen.

StefanStrobel

Vielen Dank!

das war wirklich einfacher als ich dachte.
Ich habs bei FReplacer und HTTPMOD (beta) eingebaut.

Gruss
   Stefan

StefanStrobel

Kann es sein, dass man inzwischen darauf verzichten kann, Ausprägungen von Wildcard-Attributen an userattt anzuhängen?
Beim Klicken auf ein gesetztes readings03Name o.ä. kann man den Wert offenbar auch ändern wenn userattr leer ist.
Dann würde ich das bei HTTPMOD wieder entfernen.

Gruß
    Stefan

rudolfkoenig

Das kann zwar sein, aber ich kann es weder nachstellen, noch durch Codelesen vorstellen => Bitte eine genaue Anleitung zum Nachstellen.

StefanStrobel

Hallo,

Ich habe es so getestet:
primitives (aus Modbus) zusammengekürztes Modul, welches nur ein Regex-Attribut obj-[cdih][0-9]+-reading erlaubt und nichts macht:


package RegexAttrTest;

use strict;
use warnings;
use GPUtils         qw(:all);
use Time::HiRes     qw(gettimeofday tv_interval sleep);     # work with floats, not just full seconds
use DevIo;

use Exporter ('import');
our @EXPORT_OK = qw();
our %EXPORT_TAGS = (all => [@EXPORT_OK]);

BEGIN {
    GP_Import( qw(
        CommandAttr
        CommandDeleteAttr
        CommandDelete
        addToDevAttrList
        AttrVal
        ReadingsVal
        ReadingsTimestamp
        readingsSingleUpdate
        readingsBeginUpdate
        readingsBulkUpdate
        readingsEndUpdate
        InternalVal
        makeReadingName
        goodReadingName
   
        Log3
        RemoveInternalTimer
        InternalTimer
        IsDisabled

        gettimeofday
        FmtDateTime
        GetTimeSpec
        fhemTimeLocal
        time_str2num

        featurelevel
        defs
        modules
        attr
        init_done
    ));

    GP_Export( qw(
        Initialize
    ));
};

my $Attrs = join (' ',
        'obj-[cdih][0-9]+-reading',
);
       
   
###########################################################
# _initialize
sub Initialize {
    my $modHash = shift;

    $modHash->{DefFn}    = \&RegexAttrTest::DefineFn;

    $modHash->{AttrList} = join (' ',
        'do_not_notify:1,0',
        $Attrs,
        $main::readingFnAttributes);
    return;
}


###########################################################################
# Define
sub DefineFn {
    my $ioHash = shift;                     # new hash of the device to be created
    my $def    = shift;                     # definition string
    my @a      = split(/\s+/, $def);
    my $name   = shift @a;                  # name of the device to be created
    my $type   = shift @a;                  # type / module to be used
    my $dev    = shift @a;                  # serial device

    return "wrong syntax: define <name> $type [tty-devicename|none]" if (!$dev);

    Log3 $name, 3, "$name: defined as $dev";
    return;                             
}


damit dann

define RTest RegexAttrTest none
attr RTest obj-h100-reading Test


Wenn man dann in Fhemweb auf das Attribut obj-h100-reading klickt, erscheint das Attribut samt Wert in der Eingabebox für Attribute.
Das ist ja erfreulich, ich habe nur verpasst, dass das möglich geworden ist.

Früher musste dafür im Modul in der Attr-Funktion obj-h100-reading in die Liste der userAttrs aufnehmen, sonst ist beim Klicken auf das Attribut nichts passiert.

Gruss
    Stefan

StefanStrobel

#6
Hallo,

ich habe versucht es nochmal etwas besser aufzubereiten.
Angefügt ist ein nochmal vereinfachtes Mini-Modul, das die folgenden Regex-Attribute jeweils mit Hints 1,2,3 definiert.

    $modHash->{AttrList} =
        'attr1.*:1,2,3 ' .
        'attr2.*:1,2,3 ' .      # attr2b will be added to userattr with different hints
        'attr3.*:1,2,3 ' .      # attr3c will be added in .AttrList and userattr with different hints
        'attr4.*:1,2,3 ' .      # attr4d will be added in .AttrList
        'attr5.*:1,2,3 ' .
        $readingFnAttributes;


in der Define-Funktion werden zum Test ein paar davon mit anderen Hints konkretisiert:

$hash->{'.AttrList'} = $modules{$hash->{TYPE}}{AttrList} . ' attr3c:dotAc1,dotAc2,dotAc3 attr4d:dotAd1,dotAd2,dotAd3';


In der Konfiguration werden folgende Attribute gesetzt:

attr RTest attr1a 1
attr RTest attr2b 1
attr RTest attr3c 1
attr RTest attr4d 1
attr RTest userattr attr2b:ub1,ub2,ub3 attr3c:uc1,uc2,uc3


Wenn man jetzt im Browser auf attr1a klickt, erscheint das Attribut in der Attribut-Eingabe mit seinem Wert 1 aber ohne Auswahlliste. Früher ist beim Klick gar nichts passiert, daher ist das ein Fortschritt. Leider wird der Hint 1,2,3 nicht berücksichtigt. Deshalb müsste ein Modul immer noch zusätzlich beim Setzen der Ausprägung eines Regex-Attributs (hier attr1a:1,2,3 für das ursprüngliche Regex-Attribut attr1.*:1,2,3) z.B. einen userattr-Eintrag mit der Auswahlliste als Hint erzeugen.

Wenn man im Browser auf attr2b klickt, dann erscheint das Attribut mit dem Hint aus dem userattr (ub1,ub2,ub3). Das ist auch gut und der Benutzer könnte theoretisch sogar das userattr anpassen um andere Werte in die Auswahl zu setzen.
Wenn ein Modul wie HTTPMOD oder Modbus jetzt aber beim Setzen von attr2b automatisch ein userattr erzeugt (so wie bei HTTPMOD etc. bisher), dann beschweren sich die Benutzer, dass ihre Änderung am userattr verloren gehen (so bin ich auf das Thema aufmerksam geworden).

Also dachte ich dass es evt. ein eleganterer Weg wäre, aus dem Modul heraus statt userattr-Einträge zu erzeugen in $hash->{.AttrList} zu schreiben. Das verhält sich aber nochmal anders:

Wenn man im Browser auf attr3c klickt (dafür gibt es sowohl einen Eintrag in .AttrList als auch im userattr, dann hat die .AttrList offenbar Priorität und der Hint aus dem userattr wird nicht verwendet. Das ist also auch nicht die Lösung, da manche Anwender gerne die vorgegebenen Werte überschreiben würden.

Ich kann jetzt natürlich im Modul versuchen die Konflikte zwischen benutzerdefinierten Hints in userattr-Einträgen und solchen, die aus dem Modul kommen zu priorisieren. Im Zweifel wird der Hint vom Benutzer behalten. Aber so richtig schön ist das auch nicht.
Am besten würde es mir gefallen, wenn das Modul die userattr-Einträge nicht anfassen müsste und sie dem Namen entsprechend dem Benutzer lassen würde. Dann müsste aber Fhemweb die Hints auch aus Regex-Attributen berücksichtigen.

Gruss
    Stefan

rudolfkoenig

Ich habe fhemweb.js umgestellt bei der Suche nach den Attribut-Parameter vom Stringvergleich auf Regexp.
Ich hoffe, dass es keine Nebeneffekte hat, bitte testen.

StefanStrobel

Die Attribut-Parameter werden jetzt aus der Regex-Spezifikation im Modul-Hash verwendet.
Allerdings scheinen diese jetzt Priorität gegenüber den Parametern aus .AttrList im Gerät und auch gegenüber userattr zu haben.
So kann ein Benutzer die Vorgaben leider nicht überschreiben.
Beim Matchen müsste vermutlich zunächst in userattr, dann im Gerät und zuletzt im Modul gesucht werden.

Gruss / Thanx
   Stefan


rudolfkoenig

Die Liste der Attribute wird in dieser Reihenfolge zusammengestellt (siehe fhem.pl/getAllAttr):
- globale Attribute (room/comment, etc)
- falls vorhanden, instanzspezifische Attribute ($defs{dev}{".AttrList"}), sonst modulspezifische Attribute ($modules{mod}{AttrList})
- globale userattr Werte
- instanzspezifische userattr Werte
- userattr selbst

Bei der Suche in der Liste wurde bis gestern beim ersten Finden eines passenden Wertes abgebrochen.
Ich habe jetzt diesen Abbruch entfernt. Wenn das nicht passt, bitte ein konkretes Beispiel zum Nachstellen bauen.

StefanStrobel

Bei mir klappt so alles bestens.

Gruss und vielen Dank!
   Stefan