diff --git a/fhem/FHEM/01_FHEMWEB.pm b/fhem/FHEM/01_FHEMWEB.pm index 76f807e40..55998bcb9 100644 --- a/fhem/FHEM/01_FHEMWEB.pm +++ b/fhem/FHEM/01_FHEMWEB.pm @@ -213,8 +213,6 @@ FHEMWEB_Initialize($) $FW_fhemwebjs = join(",", map { $_ = ~m/^fhemweb_(.*).js$/; $1 } grep { /fhemweb_(.*).js$/ } readdir(DH)); - $data{FWEXT}{"readingsGroup" }{SCRIPT} = "fhemweb_readingsGroup.js"; - $data{FWEXT}{"readingsHistory"}{SCRIPT} = "fhemweb_readingsHistory.js"; @FW_fhemwebjs = ("fhemweb.js"); closedir(DH); } @@ -3929,119 +3927,13 @@ FW_widgetOverride($$) i.e the default http address is http://localhost:8083/fhem
- -
  • widgetOverride
    - Space spearate list of name:modifier pairs, to override the widget + Space separated list of name:modifier pairs, to override the widget for a set/get/attribute specified by the module author. + Following is the list of known modifier: - If this attribute is specified for a FHEMWEB instance, then it is - applied to all devices shown. Examples: -

  • @@ -4718,145 +4610,11 @@ FW_widgetOverride($$)
  • widgetOverride
    Leerzeichen separierte Liste von Name/Modifier Paaren, mit dem man den vom Modulautor für einen bestimmten Parameter (Set/Get/Attribut) - vorgesehene Widgets ändern kann. + vorgesehene Widgets ändern kann. Folgendes ist die Liste der + bekannten Modifier: - Falls das Attribut für eine WEB Instanz gesetzt wurde, dann wird - es bei allen von diesem Web-Instan angezeigten Geräten angewendet. - Beispiele: - -

  • + + diff --git a/fhem/contrib/commandref_join.pl b/fhem/contrib/commandref_join.pl index b50febbde..d2eaff87d 100755 --- a/fhem/contrib/commandref_join.pl +++ b/fhem/contrib/commandref_join.pl @@ -1,5 +1,8 @@ #!/usr/bin/perl +# Usage: +# if called with FHEM/XX.pm, than only this file will be checked + # MAXWI # With pre: 1320, without 1020 (content only) # pre { white-space: pre-wrap; } : 900 @@ -14,7 +17,7 @@ my ($verify) = grep $_ =~ /\.pm$/ , @ARGV; use constant TAGS => qw{ul li code b i u table tr td div}; -sub generateModuleCommandref($$;$); +sub generateModuleCommandref($$;$$); my %mods; my %modIdx; @@ -31,14 +34,15 @@ if(!$verify) { $l =~ s/^[0-9][0-9]_//; $mods{$l} = "$modDir/$of"; $modIdx{$l} = "device"; - open(MOD, "$modDir/$of") || die("Cant open $modDir/$l"); - while(my $cl = ) { + my $modFh; + open($modFh, "$modDir/$of") || die("Cant open $modDir/$l"); + while(my $cl = <$modFh>) { if($cl =~ m/^=item\s+(helper|command|device)/) { $modIdx{$l} = $1; last; } } - close(MOD); + close($modFh); } } @@ -114,26 +118,29 @@ foreach my $lang (@lang) { ############################# # read a module file and check/print the commandref -sub generateModuleCommandref($$;$) +sub +generateModuleCommandref($$;$$) { - my ($mod, $lang, $fh) = @_; + my ($mod, $lang, $fh, $jsFile) = @_; + my $fPath = $mods{$mod} ? $mods{$mod} : $mod; my $tag; my $suffix = ($lang eq "EN" ? "" : "_$lang"); my %tagcount= (); map { $tagcount{$_} = 0 } TAGS; my %llwct = (); # Last line with closed tag - open(MOD, $mods{$mod}) || die("Cant open $mods{$mod}:$!\n"); + my $modFh; + open($modFh, $fPath) || die("Cant open $fPath:$!\n"); my $skip = 1; my $line = 0; my $docCount = 0; my $hasLink = 0; my $dosMode = 0; - while(my $l = ) { + while(my $l = <$modFh>) { $line++; $dosMode = 1 if($l =~ m/^=begin html$suffix.*\r/); if($l =~ m/^=begin html$suffix$/) { - $l = ; # skip one line, to be able to repeat join+split + $l = <$modFh>; # skip one line, to be able to repeat join+split print "*** $lang $mod: nonempty line after =begin html ignored\n" if($l =~ m/^...*$/); $skip = 0; $line++; @@ -150,14 +157,25 @@ sub generateModuleCommandref($$;$) $tagcount{$tag} -=()= ($l =~ /<\/$tag>/gi) if($tagcount{$tag} > 0); $llwct{$tag} = $line if(!$tagcount{$tag}); } + + if($l =~ m,INSERT_DOC_FROM: ([^ ]+)/([^ /]+) ,) { + my ($dir, $re) = ($1, $2); + if(opendir(DH, $dir)) { + foreach my $file (grep { m/^$2$/ } readdir(DH)) { + generateModuleCommandref("$dir/$file", $lang, $fh, 1); + } + closedir(DH); + } + } } } - close(MOD); - print "*** $lang $mods{$mod}: ignoring text due to DOS encoding\n" + close($modFh); + print "*** $lang $fPath: ignoring text due to DOS encoding\n" if($dosMode); - print "*** $lang $mods{$mod}: No document text found\n" - if(!$suffix && !$docCount && !$dosMode && $mods{$mod} !~ m,/99_,); - if($suffix && !$docCount && !$dosMode) { +# TODO: add doc to each $jsfile + print "*** $lang $fPath: No document text found\n" + if(!$jsFile && !$suffix && !$docCount && !$dosMode && $fPath !~ m,/99_,); + if(!$jsFile && $suffix && !$docCount && !$dosMode) { if($lang eq "DE" && $fh) { print $fh < @@ -169,11 +187,11 @@ sub generateModuleCommandref($$;$) EOF } } - print "*** $lang $mods{$mod}: No a-tag with name=\"$mod\" \n" - if(!$suffix && $docCount && !$hasLink && !$noWarnings); + print "*** $lang $fPath: No a-tag with name=\"$mod\" \n" + if(!$jsFile && !$suffix && $docCount && !$hasLink && !$noWarnings); foreach $tag (TAGS) { - print("*** $lang $mods{$mod}: Unbalanced $tag ". + print("*** $lang $fPath: Unbalanced $tag ". "($tagcount{$tag}, last line ok: $llwct{$tag})\n") if($tagcount{$tag} && !$noWarnings); } diff --git a/fhem/contrib/commandref_split.pl b/fhem/contrib/commandref_split.pl deleted file mode 100644 index 37ea641cc..000000000 --- a/fhem/contrib/commandref_split.pl +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -my @lang = ("EN", "DE"); -my @modDir = ("FHEM"); - -my %mods; -foreach my $modDir (@modDir) { - opendir(DH, $modDir) || die "Cant open $modDir: $!\n"; - while(my $l = readdir DH) { - next if($l !~ m/^\d\d_.*\.pm$/); - my $of = $l; - $l =~ s/.pm$//; - $l =~ s/^[0-9][0-9]_//; - $mods{lc($l)} = "$modDir/$of" if(!$mods{lc($l)}); - } -} - - -my %doc; -my %fnd; -my $modFileName; -foreach my $lang (@lang) { - my $suffix = ($lang eq "EN" ? "" : "_$lang"); - - my $docIn = "docs/commandref$suffix.html"; - my $docOut = "docs/commandref_frame$suffix.html"; - #my @modDir = ("FHEM", "contrib", "webfrontend/pgm5"); - - open(IN, "$docIn") || die "Cant open $docIn: $!\n"; - open(OUT, ">$docOut") || die "Cant open $docOut: $!\n"; - - my $content = ""; - my $skipping; - - while(my $l = ) { - $l =~ s/[\r\n]//g; - if($l =~ m,^$,) { - if($modFileName) { - $doc{$modFileName}{$lang} = $content; - $content = ""; - } - my $mod = lc($1); - if($mods{$mod}) { - print "Double-Fnd: $mod\n" if($fnd{$mod}); - $fnd{$mod} = 1; - $modFileName = $mods{$mod}; - } else { - print "Not a module: $mod\n" if($lang eq "EN"); - $modFileName = ""; - } - } - if($l =~ m,href="#global",) { - print OUT "$l\n"; - $skipping = 1; - next; - } - $skipping = 0 if($skipping && $l =~ m,,); - next if($skipping); - - if($modFileName){ - $content .= "$l\n"; - } else { - print OUT "$l\n"; - } - } -} - -foreach my $mod (sort {$mods{$a} cmp $mods{$b}} keys %mods) { - print "Missing doc for $mods{$mod}\n" if(!$fnd{$mod}); - $modFileName = $mods{$mod}; - open(IN, "$modFileName") || die("$modFileName: $!\n"); - open(OUT, ">$modFileName.NEW") || die("$modFileName.NEW: $!\n"); - while(my $l = ) { - print OUT $l; - if($l =~ m/^1;/) { - if($doc{$modFileName}) { - print OUT "\n=pod\n\n"; - foreach my $lang (@lang) { - next if(!$doc{$modFileName}{$lang}); - my $suffix = ($lang eq "EN" ? "" : "_$lang"); - print OUT "=begin html$suffix\n\n"; - print OUT $doc{$modFileName}{$lang}; - print OUT "=end html$suffix\n\n"; - } - print OUT "=cut\n"; - } - last; - } - } - close(IN); - close(OUT); - rename("$modFileName.NEW", $modFileName); -} diff --git a/fhem/fhem.pl b/fhem/fhem.pl index 05ba8df78..20558f799 100755 --- a/fhem/fhem.pl +++ b/fhem/fhem.pl @@ -4958,6 +4958,8 @@ fhemFork() return 0; } +# Return the next element from the string (list) for each consecutive call. +# The index for the next call is stored in the device hash sub Each($$;$) # can be used e.g. in at, Forum #40022 { diff --git a/fhem/www/pgm2/fhemweb.js b/fhem/www/pgm2/fhemweb.js index 6e8694537..52f7ae0ae 100644 --- a/fhem/www/pgm2/fhemweb.js +++ b/fhem/www/pgm2/fhemweb.js @@ -23,9 +23,11 @@ var FW_widgets = { time: { createFn:FW_createTime }, noArg: { createFn:FW_createNoArg }, multiple: { createFn:FW_createMultiple }, - "multiple-strict": { createFn:FW_createMultiple }, - textfield: { createFn:FW_createTextField }, - "textfield-long": { createFn:FW_createTextField } + "multiple-strict": { createFn:FW_createMultiple, second:true }, + textField: { createFn:FW_createTextField }, + textFieldNL: { createFn:FW_createTextField, second:true }, + "textField-long": { createFn:FW_createTextField, second:true }, + "textFieldNL-long":{ createFn:FW_createTextField, second:true } }; window.onbeforeunload = function(e) @@ -882,15 +884,17 @@ FW_doUpdate(evt) }); } + // updateLine is deprecated, use setValueFn for(var w in FW_widgets) - if(FW_widgets[w].updateLine) // updateLine is deprecated, use setValueFn + if(FW_widgets[w].updateLine && !FW_widgets[w].second) FW_widgets[w].updateLine(d); devs.push(d); } + // used for SVG to avoid double-reloads for(var w in FW_widgets) - if(FW_widgets[w].updateDevs) // used for SVG to avoid double-reloads + if(FW_widgets[w].updateDevs && !FW_widgets[w].second) FW_widgets[w].updateDevs(devs); // reset the connection to avoid memory problems @@ -1045,7 +1049,7 @@ function FW_callCreateFn(elName, devName, vArr, currVal, set, params, cmd, finishFn) { for(var wn in FW_widgets) { - if(FW_widgets[wn].createFn) { + if(FW_widgets[wn].createFn && !FW_widgets[wn].second) { var newEl = FW_widgets[wn].createFn(elName, devName, vArr, currVal, set, params, cmd); if(newEl) @@ -1721,9 +1725,12 @@ FW_getSVG(emb) =pod =begin html +
  • :noArg - show no input field.
  • -
  • :time - show a JavaScript driven timepicker.
  • -
  • :textField - show an input field.
  • +
  • :time - show a JavaScript driven timepicker.
    + Example: attr FS20dev widgetOverride on-till:time
  • +
  • :textField - show an input field.
    + Example: attr WEB widgetOverride room:textField
  • :textFieldNL - show the input field and hide the label.
  • :textField-long - show an input-field, but upon clicking on the input field open a textArea (60x25).
  • @@ -1736,12 +1743,24 @@ FW_getSVG(emb) additional textfield. The result is comman separated.
  • :multiple-strict,val1,val2,... - like :multiple, but without the textfield.
  • +
  • :selectnumbers,<min>,<step>,<max>,<number of + digits after decimal point>,lin|log10" - display a select widget + generated with values from min to max with step.
    + lin generates a constantly increasing series. log10 generates an + exponentially increasing series to base 10, step is related to the + exponent, e.g. 0.0625.
  • +
  • :select,val1,val2,... - show a dropdown with all values. + NOTE: this is also the fallback, if no modifier is found.
  • + =end html =begin html_DE +
  • :noArg - es wird kein weiteres Eingabefeld angezeigt.
  • -
  • :time - zeigt ein Zeitauswahlmenü.
  • -
  • :textField - zeigt ein Eingabefeld.
  • +
  • :time - zeigt ein Zeitauswahlmenü. + Beispiel: attr FS20dev widgetOverride on-till:time
  • +
  • :textField - zeigt ein Eingabefeld.
    + Beispiel: attr WEB widgetOverride room:textField
  • :textField-long - ist wie textField, aber beim Click im Eingabefeld wird ein Dialog mit einer HTML textarea (60x25) wird geöffnet.
  • :slider,<min>,<step>,<max>[,1] - zeigt einen @@ -1750,7 +1769,18 @@ FW_getSVG(emb)
  • :multiple,val1,val2,... - zeigt eine Mehrfachauswahl mit einem zusätzlichen Eingabefeld. Das Ergebnis ist Komma separiert.
  • :multiple-strict,val1,val2,... - ist wie :multiple, bloß ohne - Eingabefeld.
  • + Eingabefeld. +
  • :selectnumbers,<min>,<step>,<max>,<number of + digits after decimal point>,lin|log10" zeigt ein HTML-select mit einer + Zahlenreihe vom Wert min bis Wert max mit Schritten von step + angezeigt.
    + Die Angabe lin erzeugt eine konstant ansteigende Reihe. Die Angabe + log10 erzeugt eine exponentiell ansteigende Reihe zur Basis 10, + step bezieht sich auf den Exponenten, z.B. 0.0625.
  • +
  • :select,val1,val2,... - zeigt ein HTML select mit allen Werten. + Achtung: so ein Widget wird auch dann angezeigt, falls kein + passender Modifier gefunden wurde.
  • + =end html_DE =cut diff --git a/fhem/www/pgm2/fhemweb_knob.js b/fhem/www/pgm2/fhemweb_knob.js index 549a1404a..033cf5440 100644 --- a/fhem/www/pgm2/fhemweb_knob.js +++ b/fhem/www/pgm2/fhemweb_knob.js @@ -36,3 +36,31 @@ FW_knobCreate(elName, devName, vArr, currVal, set, params, cmd) return newEl; } + +/* +=pod + +=begin html + +
  • :knob,min:1,max:100,... - shows the jQuery knob widget. The parameters + are a comma separated list of key:value pairs, where key does not have to + contain the "data-" prefix. For details see the jQuery-knob + definition.
    Example: + attr dimmer widgetOverride dim:knob,min:1,max:100,step:1,linecap:round +
  • + +=end html + +=begin html_DE + +
  • :knob,min:1,max:100,... - zeigt das jQuery knob Widget.Die Parameter + werden als eine Komma separierte Liste von Key:Value Paaren spezifiziert, + wobei das data- Präfix entfällt.Für Details siehe die + jQuery knob Dokumentation.
    Beispiel: + attr dimmer widgetOverride dim:knob,min:1,max:100,step:1,linecap:round +
  • + +=end html_DE + +=cut +*/ diff --git a/fhem/www/pgm2/fhemweb_sortable.js b/fhem/www/pgm2/fhemweb_sortable.js index 2c395eda9..7e9076de3 100644 --- a/fhem/www/pgm2/fhemweb_sortable.js +++ b/fhem/www/pgm2/fhemweb_sortable.js @@ -186,4 +186,50 @@ FW_sortableCreateTable(elements, selected) } +/* +=pod +=begin html + +
  • :sortable,val1,val2,... - create a new list from the elements of the + given list, can add new elements by entering a text, or delete some from + the list. This new list can be sorted via drag & drop. The result is + a comma separated list.
  • + +
  • :sortable-strict,val1,val2,... - it behaves like :sortable, without the + possibility to enter text.
  • + +
  • :sortable-given,val1,val2,... - the specified list can be sorted via drag + & drop, no elements can be added or deleted.
  • + +=end html + +=begin html_DE + +
  • :sortable,val1,val2,... - damit ist es möglich aus den gegebenen + Werten eine Liste der gewünschten Werte durch Drag & Drop + zusammenzustellen. Die Reihenfolge der Werte kann dabei entsprechend + geändert werden. Es müssen keine Werte explizit vorgegeben + werden, das Widget kann auch ohne vorgegebenen Werte benutzt werden. Es + können eigene Werte zur Liste hinzugefügt und einsortiert + werden. Das Ergebnis ist Komma-separiert entsprechend aufsteigend + sortiert.
  • + +
  • :sortable-strict,val1,val2,... - damit ist es möglich aus den + gegebenen Werten eine Liste der gewünschten Werte durch Drag & + Drop zusammenzustellen. Die Reihenfolge der Werte kann dabei entsprechend + geändert werden. Es können jedoch keine eigenen Werte zur + Liste hinzugefügt werden. Das Ergebnis ist Komma-separiert + entsprechend aufsteigend sortiert.
  • + +
  • :sortable-given,val1,val2,... - damit ist es möglich aus den + gegebenen Werten eine sortierte Liste der gewünschten Werte durch + Drag & Drop zusammenzustellen. Es können keine Elemente + gelöscht und hinzugefügt werden. Es müssen alle gegeben + Werte benutzt und entsprechend sortiert sein. Das Ergebnis ist + Komma-separiert entsprechend aufsteigend sortiert.
  • + +=end html_DE + +=cut +*/ diff --git a/fhem/www/pgm2/fhemweb_uzsu.js b/fhem/www/pgm2/fhemweb_uzsu.js index e6a34c02f..e1bfc75ce 100644 --- a/fhem/www/pgm2/fhemweb_uzsu.js +++ b/fhem/www/pgm2/fhemweb_uzsu.js @@ -594,3 +594,109 @@ FW_uzsuCreate(elName, devName, vArr, currVal, set, params, cmd) return newEl; } + +/* +=pod + +=begin html + +
  • :uzsuToggle,state1,state2 - dispay a toggle button with two possible + states. the first is the active state.
  • + +
  • :uzsuSelect,val1,val2,... - display a button bar with a button per value + from which multiple values can be selected. the result is comma + separated.
  • + +
  • :uzsuSelectRadio,val1,val2,... - display a button bar with a button per + value from which only one value can be selected.
  • + +
  • :uzsuDropDown,val1,val2,... - display a dropdown with all values.
  • + +
  • :uzsuTimerEntry[,modifier2] - combine uzsuSelect, uzsuDropDown and + uzsuToggle into a single line display to select a timer entry. an + optional modifier can be given to select the switching value. see + examples below. the result is a comma separated list of days followed by + a time, an enabled indicator and the switching value all separated by a|. + eg: Mo,Di,Sa,So|00:00|enabled|19.5
  • + +
  • :uzsu[,modifier2] - combine multiple uzsuTimerEntry widets to allow the + setting of multiple switching times an optional modifier can be given to + select the switching value. see examples below. the result is a space + separeted list of uzsuTimerEntry results. Examples: +
      + attr myToggle widgetOverride state:uzsuToggle,123,xyz
      + attr mySelect widgetOverride state:uzsuSelect,abc,123,456,xyz
      + attr myTemp widgetOverride state:uzsuDropDown,18,18.5,19,19.5,20,20.5,21,21.5,22,22.5,23
      + attr myTimerEntry widgetOverride state:uzsuTimerEntry
      + attr myTimer widgetOverride state:uzsu
      +
      + the following gives some examples of for the modifier2 parameter of uzsuTimerEntry and uzsu to + combine the setting of a timer with another widget to select the switching value : +
      +... widgetOverride state:uzsu,slider,0,5,100                                         -> a slider
      +... widgetOverride state:uzsu,uzsuToggle,off,on                                      -> a on/off button
      +... widgetOverride state:uzsu,uzsuDropDown,18,19,20,21,22,23                         -> a dropDownMenue
      +... widgetOverride state:uzsu,knob,min:18,max:24,step:0.5,linecap:round,fgColor:red  -> a knob widget
      +... widgetOverride state:uzsu,colorpicker                                            -> a colorpicker
      +... widgetOverride state:uzsu,colorpicker,CT,2700,50,5000                            -> a colortemperature selector
      +        
      +
    +
  • + +=end html + +=begin html_DE + +
  • :uzsuToggle,zust1,zust2 - damit ist es möglich mit einem + Toggle-Button zwischen zwei Zuständen zu wählen. Der Erste ist + der aktive Zustand.
  • + +
  • :uzsuSelect,val1,val2,... - damit ist es mögliche in einer + Buttonleiste meherere Werte auszuwählen. Das Ergebnis ist + Komma-separiert.
  • + +
  • :uzsuSelectRadio,val1,val2,... - damit ist es mögliche in einer + Buttonleiste einen aus meherere Werten auszuwählen.
  • + +
  • :uzsuDropDown,val1,val2,... - damit ist es mögliche mit einem + DropDown Menü einen der Werte auszuwählen.
  • + +
  • :uzsuTimerEntry[,modifier2] - damit werden je ein uzsuSelect, + uzsuDropDown und uzsuToggle Widget kombiniert um einen Schaltzeitpunkt + auszuwählen. Über den optionalen modifier2 kann ein Widget zur + Auswahl des Schaltwertes angegeben werden. Siehe Beispiele unten. Das + Ergebniss is eine komma-separiert Liste von Wochentagen gefolgt vom + Zeitpunkt, eine Aktiv-Indikator und dem Schaltwert, jeweils durch | + abetrennt. Zum Beispiel: Mo,Di,Sa,So|00:00|enabled|19.5
  • + +
  • :uzsu[,modifier2] - damit werden mehrere uzsuTimerEntry Widets kombiniert + um eine beliebige Anzahl an Schaltzeiten einzugeben. Über den + optionalen modifier2 kann ein Widget zur Auswahl des Schaltwertes + angegeben werden. Siehe Beispiele unten. Das Ergebiss ist eine durch + leerzeichen getrennte Liste von uzsuTimerEntry Ergebnissen.
    + Beispiele: +
      + attr myToggle widgetOverride state:uzsuToggle,123,xyz
      + attr mySelect widgetOverride state:uzsuSelect,abc,123,456,xyz
      + attr myTemp widgetOverride + state:uzsuDropDown,18,18.5,19,19.5,20,20.5,21,21.5,22,22.5,23
      + attr myTimerEntry widgetOverride state:uzsuTimerEntry
      + attr myTimer widgetOverride state:uzsu
      +
      + Im Folgenden wird die Verwendung des modifier2 parameters von + uzsuTimerEntry und uzsu gezeigt um die Auswahl des Schaltzeitpunktes + mit der Auswahl des Schaltwertes zu kombinieren: +
      +      ... widgetOverride state:uzsu,slider,0,5,100                                         -> ein slider
      +      ... widgetOverride state:uzsu,uzsuToggle,off,on                                      -> ein on/off button
      +      ... widgetOverride state:uzsu,uzsuDropDown,18,19,20,21,22,23                         -> ein dropDownMenue
      +      ... widgetOverride state:uzsu,knob,min:18,max:24,step:0.5,linecap:round,fgColor:red  -> ein knob widget
      +      ... widgetOverride state:uzsu,colorpicker                                            -> ein colorpicker
      +      ... widgetOverride state:uzsu,colorpicker,CT,2700,50,5000                            -> ein colortemperature slider
      +        
      +
  • + +=end html_DE + +=cut +*/