diff --git a/fhem/FHEM/92_FileLog.pm b/fhem/FHEM/92_FileLog.pm index 48eda5a13..c84cf89c1 100755 --- a/fhem/FHEM/92_FileLog.pm +++ b/fhem/FHEM/92_FileLog.pm @@ -80,7 +80,7 @@ FileLog_Log($$) if($n =~ m/^$re$/ || "$n:$s" =~ m/^$re$/) { my $t = TimeNow(); $t = $dev->{CHANGETIME}[$i] if(defined($dev->{CHANGETIME}[$i])); - $t =~ s/ /_/; # Makes it easier to parse with gnuplot + $t =~ s/ /_/o; # Makes it easier to parse with gnuplot my $fh = $log->{FH}; my @t = localtime; @@ -182,7 +182,7 @@ FileLog_Get($@) if($inf eq "-") { $inf = $hash->{currentlogfile}; } else { - my $linf = "$1/$inf" if($hash->{currentlogfile} =~ m,^(.*)/[^/]*$,); + my $linf = "$1/$inf" if($hash->{currentlogfile} =~ m,^(.*)/[^/]*$,o); if(!-f $linf) { $linf = $attr{$hash->{NAME}}{archivedir} . "/" . $inf; return "Error: File-not-found" if(!-f $linf); @@ -214,7 +214,7 @@ FileLog_Get($@) $h{didx} = 10 if($fld[3] && $fld[3] eq "delta-d"); # delta idx, substr len $h{didx} = 13 if($fld[3] && $fld[3] eq "delta-h"); - if($fld[0] =~ m/"(.*)"/) { + if($fld[0] =~ m/"(.*)"/o) { $h{col} = $1; $h{type} = 0; } else { @@ -281,7 +281,7 @@ FileLog_Get($@) $lastdate{$hd} = $fld[0]; } elsif($t == 3) { # int function - $val = $1 if($fld[$col] =~ m/^([0-9]+).*/); + $val = $1 if($fld[$col] =~ m/^(\d+).*/o); } else { # evaluate $val = eval($h->{fn}); @@ -380,7 +380,7 @@ seekTo($$$$) $last = $next; last; } - if($data !~ m/^\d\d\d\d-\d\d-\d\d_\d\d:\d\d:\d\d /) { + if($data !~ m/^\d\d\d\d-\d\d-\d\d_\d\d:\d\d:\d\d /o) { $next = $fh->tell; $data = <$fh>; if(!$data) { diff --git a/fhem/FHEM/98_autocreate.pm b/fhem/FHEM/98_autocreate.pm new file mode 100644 index 000000000..4d45b4469 --- /dev/null +++ b/fhem/FHEM/98_autocreate.pm @@ -0,0 +1,173 @@ +############################################## +package main; + +use strict; +use warnings; + +# Problems: +# - Not all CUL_EM devices return a power +# - Not all CUL_WS devices return a temperature +# - No plot files for BS/CUL_FHTTK/USF1000/X10/WS300 +# - check "UNDEFINED" parameters for BS/USF1000/X10 + +my %flogpar = ( + "CUL_EM:.*" => { GPLOT => "cul_em:Power,", FILTER => "%NAME:CNT:.*" }, + "CUL_WS:.*" => { GPLOT => "cul_ws:Temp,", FILTER => "%NAME" }, + "FHT:.*" => { GPLOT => "fht:Temp/Act,", FILTER => "%NAME" }, + "HMS:HMS100T.*" => { GPLOT => "hms:Temp/Hum,", FILTER => "%NAME:T:.*" }, + "KS300:.*" => { GPLOT => "ks300:Temp/Rain,ks300_2:Wind/Hum,", + FILTER => "%NAME:T:.*" }, +); + +##################################### +sub +autocreate_Initialize($) +{ + my ($hash) = @_; + $hash->{DefFn} = "autocreate_Define"; + $hash->{NotifyFn} = "autocreate_Notify"; + $hash->{AttrList}= "loglevel:0,1,2,3,4,5,6 " . + "autosave filelog device_room weblink weblink_room"; +} + +##################################### +sub +autocreate_Define($$) +{ + my ($hash, $def) = @_; + my $name = $hash->{NAME}; + $hash->{STATE} = "active"; + $attr{global}{autoload_undefined_devices} = 1; # Make sure we work correctly + return undef; +} + +sub +replace_wildcards($$) +{ + my ($hash, $str) = @_; + return "" if(!$str); + my $t = $hash->{TYPE}; $str =~ s/%TYPE/$t/g; + my $n = $hash->{NAME}; $str =~ s/%NAME/$n/g; + return $str; +} + +##################################### +sub +autocreate_Notify($$) +{ + my ($ntfy, $dev) = @_; + + my $me = $ntfy->{NAME}; + my $max = int(@{$dev->{CHANGED}}); + my $ret = ""; + my $nrcreated; + + for (my $i = 0; $i < $max; $i++) { + + my $s = $dev->{CHANGED}[$i]; + $s = "" if(!defined($s)); + + ################ + if($s =~ m/^UNDEFINED ([^ ]*) ([^ ]*) (.*)$/) { + my ($name, $type, $arg) = ($1, $2, $3); + my $lctype = lc($type); + + #################### + my $cmd = "$name $type $arg"; + Log GetLogLevel($me,2), "autocreate: define $cmd"; + my $ret = CommandDefine(undef, $cmd); + if($ret) { + Log GetLogLevel($me,1), "ERROR: $ret"; + last; + } + my $hash = $defs{$name}; + $nrcreated++; + my $room = replace_wildcards($hash, $attr{$me}{device_room}); + $attr{$name}{room} = $room if($room); + + #################### + my $fl = replace_wildcards($hash, $attr{$me}{filelog}); + next if(!$fl); + my $flname = "FileLog_$name"; + my ($gplot, $filter) = ("", $name); + foreach my $k (keys %flogpar) { + next if("$type:$name" !~ m/^$k$/); + $gplot = $flogpar{$k}{GPLOT}; + $filter = replace_wildcards($hash, $flogpar{$k}{FILTER}); + } + $cmd = "$flname FileLog $fl $filter"; + Log GetLogLevel($me,2), "autocreate: define $cmd"; + $ret = CommandDefine(undef, $cmd); + if($ret) { + Log GetLogLevel($me,1), "ERROR: $ret"; + last; + } + $attr{$flname}{room} = $room if($room); + $attr{$flname}{logtype} = "${gplot}text"; + + + #################### + next if(!$attr{$me}{weblink} || !$gplot); + $room = replace_wildcards($hash, $attr{$me}{weblink_room}); + my $wlname = "weblink_$name"; + $cmd = "$wlname weblink fileplot $flname:$lctype:CURRENT"; + Log GetLogLevel($me,2), "autocreate: define $cmd"; + $ret = CommandDefine(undef, $cmd); + if($ret) { + Log GetLogLevel($me,1), "ERROR: $ret"; + last; + } + $attr{$wlname}{room} = $room if($room); + $attr{$wlname}{label} = '"' . $name . + ' Min $data{min1}, Max $data{max1}, Last $data{currval1}"'; + } + + + ################ + if($s =~ m/^RENAMED ([^ ]*) ([^ ]*)$/) { + my ($old, $new) = ($1, $2); + + if($defs{"FileLog_$old"}) { + CommandRename(undef, "FileLog_$old FileLog_$new"); + my $hash = $defs{"FileLog_$new"}; + my $oldlogfile = $hash->{currentlogfile}; + + $hash->{REGEXP} =~ s/$old/$new/g; + $hash->{logfile} =~ s/$old/$new/g; + $hash->{currentlogfile} =~ s/$old/$new/g; + $hash->{DEF} =~ s/$old/$new/g; + + rename($oldlogfile, $hash->{currentlogfile}); + Log GetLogLevel($me,2), + "autocreate: renamed FileLog_$old to FileLog_$new"; + $nrcreated++; + } + + if($defs{"weblink_$old"}) { + CommandRename(undef, "weblink_$old weblink_$new"); + my $hash = $defs{"weblink_$new"}; + $hash->{LINK} =~ s/$old/$new/g; + $hash->{DEF} =~ s/$old/$new/g; + $attr{"weblink_$new"}{label} =~ s/$old/$new/g; + Log GetLogLevel($me,2), + "autocreate: renamed weblink_$old to weblink_$new"; + $nrcreated++; + } + } + + } + + CommandSave(undef, undef) if(!$ret && $nrcreated && $attr{$me}{autosave}); + return $ret; +} + +##################################### +# Test code. Use {dp "xxx"} to fake a device specific message +# FS20: 81xx04yy0101a00180c1020013 +sub +dp($) +{ + Dispatch($defs{CUL}, shift, undef); +} + +1; diff --git a/fhem/Makefile b/fhem/Makefile index 057e83157..166853ec1 100644 --- a/fhem/Makefile +++ b/fhem/Makefile @@ -2,8 +2,8 @@ BINDIR=/usr/local/bin MODDIR=/usr/local/lib VARDIR=/var/log/fhem -VERS=4.8 -DATE=2009-11-28 +VERS=4.9 +DATE=2009-12-23 all: @echo Nothing to do for all. diff --git a/fhem/contrib/crc.pl b/fhem/contrib/crc.pl index 7066c2811..d3cff2138 100755 --- a/fhem/contrib/crc.pl +++ b/fhem/contrib/crc.pl @@ -1,4 +1,4 @@ -die("Usage: crc HEX-MESSAGE\n") if(int(@ARGV) != 2); +die("Usage: crc \n") if(int(@ARGV) != 2); my $msg = $ARGV[0]; $msg =~ s/ //g; diff --git a/fhem/docs/HOWTO.html b/fhem/docs/HOWTO.html index 45d539c6e..1e271be3a 100644 --- a/fhem/docs/HOWTO.html +++ b/fhem/docs/HOWTO.html @@ -6,7 +6,7 @@

FHEMWEB Howto

Starting
- Attaching an FHZ device
+ Attaching an FHZ/CUL
Configuring FS20 receivers
Configuring FS20 transmitters
Configuring FHT devices
@@ -41,7 +41,7 @@ -

Attaching an FHZ device

+

Attaching an FHZ/CUL

+ +

Automatically creating transmitters

+
+

Configuring FS20 receivers

diff --git a/fhem/docs/commandref.html b/fhem/docs/commandref.html index 9e332af5a..45f625223 100644 --- a/fhem/docs/commandref.html +++ b/fhem/docs/commandref.html @@ -32,6 +32,7 @@
modify   quit   reload   + rename   rereadcfg   save   set   @@ -93,12 +94,14 @@ PachLog   SUNRISE_EL   at   + autocreate   dummy   dumpdef   holiday   notify   watchdog   weblink   +
@@ -365,7 +368,9 @@ A line ending with \ will be concatenated with the next one, so long lines Define a device. You need devices if you want to manipulate them (e.g. set on/off), and the logfile is also more readable if it contains e.g. "lamp off" instead of "Device 5673, Button 00, Code 00 (off)".
- Use "define <name> ?" to get a list of possible types. + Use "define <name> ?" to get a list of possible types.
+ After definition, the global event "DEFINED" will be generated, see the + notify section for details.


Each device takes different additional arguments at definition, see the @@ -401,6 +406,8 @@ A line ending with \ will be concatenated with the next one, so long lines Delete something created with the define command. See the Device specification section for details on <devspec>.
+ After deletion, the global event "DELETED" will be generated, see the notify + section for details.
Examples: + +

rename

+ + +

rereadcfg

Set
@@ -3575,6 +3608,82 @@ A line ending with \ will be concatenated with the next one, so long lines + +

autocreate

+ +

holiday

@@ -4032,7 +4141,7 @@ A line ending with \ will be concatenated with the next one, so long lines define FileLog fhtlog1 fht1:.*(temp|actuator).* /var/log/fht1-%Y-%U.log -
  • ks300_1
    +
  • ks300
    Plots the temperature and rain (per hour and per day) of a ks300. The corresponding filelog definitions (for the KS300 device named ks300) looks like:
    diff --git a/fhem/examples/04_log b/fhem/examples/04_log index 204e81d6a..5ac7e1a87 100644 --- a/fhem/examples/04_log +++ b/fhem/examples/04_log @@ -26,7 +26,7 @@ attr wzlog logtype fht:Temp # ks300 log define kslog FileLog /var/log/wz-%Y-%U.log ks1:.*H:.* define avglog FileLog /var/log/avg.log ks1:.*avg.* -attr kslog logtype ks300_1:Temp/Hum,ks300_2:Rain/Wind +attr kslog logtype ks300:Temp/Hum,ks300_2:Rain/Wind ############################## # Alternative log method. It does the same, but it is somewhat slower as it diff --git a/fhem/examples/sample_pgm2 b/fhem/examples/sample_pgm2 index 8a7762578..36a4f2696 100644 --- a/fhem/examples/sample_pgm2 +++ b/fhem/examples/sample_pgm2 @@ -1,15 +1,25 @@ # -# Minimalistic fhem.pl & pgm2 configfile. Take a look at the other examples for -# more. +# pgm2 / autocreate configfile. Take a look at the other examples for more. # attr global logfile /tmp/fhem-%Y-%m.log +attr global modpath . # where our FHEM directory is +attr global port 7072 # our TCP/IP port (localhost only) attr global statefile /tmp/fhem.save # where to save the state of the devices attr global verbose 3 # "normal" verbosity (min 1, max 5) -attr global port 7072 # our TCP/IP port (localhost only) -attr global modpath . # where our FHEM directory is + +#define CUL CUL /dev/ttyACM0 +#define FHEM FHEM /dev/USB0 define WEB FHEMWEB 8083 global attr WEB plotmode SVG +attr WEB plotsize 800,160 # Fake logfile, to access the global log define Logfile FileLog /tmp/fhem-%Y-%m.log fakelog + +define autocreate autocreate +attr autocreate autosave +attr autocreate device_room %TYPE +attr autocreate filelog /tmp/%NAME-%Y.log +attr autocreate weblink +attr autocreate weblink_room Plots diff --git a/fhem/fhem.pl b/fhem/fhem.pl index b1dd575e1..c9162c0cd 100755 --- a/fhem/fhem.pl +++ b/fhem/fhem.pl @@ -157,7 +157,7 @@ my $nextat; # Time when next timer will be triggered. my $intAtCnt=0; my %duplicate; # Pool of received msg for multi-fhz/cul setups my $duplidx=0; # helper for the above pool -my $cvsid = '$Id: fhem.pl,v 1.92 2009-12-21 18:03:56 rudolfkoenig Exp $'; +my $cvsid = '$Id: fhem.pl,v 1.93 2009-12-22 11:00:54 rudolfkoenig Exp $'; my $namedef = "where is either:\n" . "- a single device name\n" . @@ -863,29 +863,20 @@ CommandSave($$) return "Cannot open $param: $!"; } - my $oldroom = ""; foreach my $d (sort { $defs{$a}{NR} <=> $defs{$b}{NR} } keys %defs) { next if($defs{$d}{TEMPORARY} || # e.g. WEBPGM connections $defs{$d}{VOLATILE}); # e.g at, will be saved to the statefile - my $room = ($attr{$d} ? $attr{$d}{room} : ""); - $room = "" if(!$room); - if($room ne $oldroom) { - print SFH "\nsetdefaultattr" . ($room ? " room $room" : "") . "\n"; - $oldroom = $room; - } - if($d ne "global") { if($defs{$d}{DEF}) { my $def = $defs{$d}{DEF}; $def =~ s/;/;;/g; - print SFH "define $d $defs{$d}{TYPE} $def\n"; + print SFH "\ndefine $d $defs{$d}{TYPE} $def\n"; } else { - print SFH "define $d $defs{$d}{TYPE}\n"; + print SFH "\ndefine $d $defs{$d}{TYPE}\n"; } } foreach my $a (sort keys %{$attr{$d}}) { - next if($a eq "room"); next if($d eq "global" && ($a eq "configfile" || $a eq "version")); print SFH "attr $d $a $attr{$d}{$a}\n"; diff --git a/fhem/webfrontend/pgm2/cul_em.gplot b/fhem/webfrontend/pgm2/cul_em.gplot index 7ae328e61..779741683 100644 --- a/fhem/webfrontend/pgm2/cul_em.gplot +++ b/fhem/webfrontend/pgm2/cul_em.gplot @@ -1,8 +1,7 @@ ############################ # Display the power reported by the EM1010 # Corresponding FileLog definition: -# define ememlog FileLog /var/log/fhem/em-%Y.log emem:power.* -# define emwzlog FileLog /var/log/fhem/em-%Y.log emwz:power.* +# define FileLog /var/log/fhem/em-%Y.log :CNT:.* set terminal png transparent size crop set output '.png' @@ -10,7 +9,7 @@ set xdata time set timefmt "%Y-%m-%d_%H:%M:%S" set xlabel " " -set title '' +set title '' set ylabel "Power (KW)" set y2label "Power (KW)" set grid @@ -19,8 +18,6 @@ set y2tics set format y "%.1f" set format y2 "%.1f" -#FileLog 8:emem:0: -#FileLog 8:emwz:0: +#FileLog 8::0: -plot "" using 1:8 title 'EMEM' with lines,\ - "" using 1:8 title 'EMWZ' with lines +plot "" using 1:8 title 'Power' with lines diff --git a/fhem/webfrontend/pgm2/cul_emem.gplot b/fhem/webfrontend/pgm2/cul_emem.gplot index 152109146..c085e4e7b 100644 --- a/fhem/webfrontend/pgm2/cul_emem.gplot +++ b/fhem/webfrontend/pgm2/cul_emem.gplot @@ -8,7 +8,7 @@ set xdata time set timefmt "%Y-%m-%d_%H:%M:%S" set xlabel "Energiemonitor EM1000EM" -set title '' +set title '' set ylabel "Power (kW)" set y2label "Power (kWh)" set grid diff --git a/fhem/webfrontend/pgm2/cul_ws.gplot b/fhem/webfrontend/pgm2/cul_ws.gplot index bc6e2db98..56c57d033 100644 --- a/fhem/webfrontend/pgm2/cul_ws.gplot +++ b/fhem/webfrontend/pgm2/cul_ws.gplot @@ -1,7 +1,7 @@ ############################ # Display the s300th data reported by the CUL # Corresponding FileLog definition: -# define ememlog FileLog /var/log/fhem/s300th-%Y.log s300th.* +# define FileLog /var/log/fhem/s300th-%Y.log set terminal png transparent size crop set output '.png' @@ -9,7 +9,7 @@ set xdata time set timefmt "%Y-%m-%d_%H:%M:%S" set xlabel " " -set title '' +set title '' set ylabel "Temp (C)" set y2label "Temp (C)" set grid @@ -18,10 +18,6 @@ set y2tics set format y "%.1f" set format y2 "%.1f" -#FileLog 4:s300th1:0: -#FileLog 4:s300th3:0: -#FileLog 4:s300th5:0: +#FileLog 4::0: -plot "" using 1:8 title '1' with lines,\ - "" using 1:8 title '3' with lines,\ - "" using 1:8 title '5' with lines +plot "" using 1:4 title 'Temperature' with lines diff --git a/fhem/webfrontend/pgm2/fht.gplot b/fhem/webfrontend/pgm2/fht.gplot index 9bebc1a83..2bbb8adf8 100644 --- a/fhem/webfrontend/pgm2/fht.gplot +++ b/fhem/webfrontend/pgm2/fht.gplot @@ -1,7 +1,7 @@ ############################ # Display the measured temp and the actuator. # Corresponding FileLog definition: -# define fhtlog1 FileLog /var/log/fhem/fht1-%Y-%U.log fht1:.*(temp|actuator).* +# define FileLog /var/log/fhem/fht-%Y.log set terminal png transparent size crop set output '.png' @@ -11,19 +11,15 @@ set xlabel " " set ytics nomirror set y2tics #set ytics -set title '' +set title '' set grid xtics y2tics set y2label "Temperature in C" set ylabel "Actuator (%)" #FileLog 4:measured:0: -##FileLog 4:desired:0: #FileLog 4:actuator.*[0-9]+%:0:int -# "< awk '/desired/ {print $1, $4+0}' "\ -# using 1:2 axes x1y2 title 'Desired temperature' with steps,\ - plot \ "< awk '/measured/{print $1, $4}' "\ using 1:2 axes x1y2 title 'Measured temperature' with lines lw 2,\ diff --git a/fhem/webfrontend/pgm2/hms.gplot b/fhem/webfrontend/pgm2/hms.gplot index 104b26b6e..92a49a4ce 100644 --- a/fhem/webfrontend/pgm2/hms.gplot +++ b/fhem/webfrontend/pgm2/hms.gplot @@ -1,9 +1,7 @@ # # Display the measured temp and the humidity. # FileLog definition: -# define UGHygrolog FileLog /var/tmp/UGHygro.log UGHygro:.*T:.* -# attr UGHygrolog logtype hms_tf -# define wl_11 weblink fileplot UGHygrolog:hms_tf:CURRENT +# define FileLog /var/log/fhem/hmsname-%Y.log :T:.* # # Logfile record example: # 2008-07-24_02:20:57 UGHygro T: 17.2 H: 77.6 Bat: ok @@ -21,7 +19,7 @@ set xlabel " " set ytics nomirror set y2tics #set ytics -set title '' +set title '' set grid xtics y2tics set y2label "Temperature in C" @@ -35,7 +33,3 @@ plot \ using 1:2 axes x1y2 title 'Measured temperature' with lines lw 2,\ "< awk '/H:/ {print $1, $6}' "\ using 1:2 axes x1y1 title 'Humidity (%)' with lines lw 1\ - - - - diff --git a/fhem/webfrontend/pgm2/ks300.gplot b/fhem/webfrontend/pgm2/ks300.gplot index 87c38616a..b1283faf2 100644 --- a/fhem/webfrontend/pgm2/ks300.gplot +++ b/fhem/webfrontend/pgm2/ks300.gplot @@ -1,9 +1,7 @@ ############################ # Display the temperature and the humidity values of a KS300. # Corresponding FileLog definition: -# define ks300log FileLog /var/log/fhem/ks300-%Y-%U.log ks300:.*H:.* -# or (SVG/gnuplot-scroll) -# define ks300log FileLog /var/log/fhem/ks300-%Y.log ks300:.*H:.* +# define FileLog /var/log/fhem/hms-%Y.log :T:.* set terminal png transparent size crop set output '.png' @@ -12,7 +10,7 @@ set timefmt "%Y-%m-%d_%H:%M:%S" set xlabel " " set ytics nomirror set y2tics -set title '' +set title '' set grid set y2label "Temperature in C" diff --git a/fhem/webfrontend/pgm2/ks300_2.gplot b/fhem/webfrontend/pgm2/ks300_2.gplot index 45d9d6c00..f0f3cd73a 100644 --- a/fhem/webfrontend/pgm2/ks300_2.gplot +++ b/fhem/webfrontend/pgm2/ks300_2.gplot @@ -1,9 +1,7 @@ ############################ # Display the Wind and the Rain values of a KS300. # Corresponding FileLog definition: -# define ks300log FileLog /var/log/fhem/ks300-%Y-%U.log ks300:.*H:.* -# or (SVG/gnuplot-scroll) -# define ks300log FileLog /var/log/fhem/ks300-%Y.log ks300:.*H:.* +# define FileLog /var/log/fhem/hms-%Y.log :T:.* set terminal png transparent size crop set output '.png'