diff --git a/fhem/CHANGED b/fhem/CHANGED index 025474834..e2bb7cd9b 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -542,3 +542,5 @@ - feature: 21_OWTEMP.pm for 1-Wire Digital Thermometer added (Martin Fischer) - feature: CUL_FHTTK from Kai - feature: pgm3: Google-Weather, Battery-Check, Log-View added (MartinH) + - feature: CUL_RFR (RF_ROUTING) added + - feature: Command save retains now the order of the old config file diff --git a/fhem/FHEM/00_CM11.pm b/fhem/FHEM/00_CM11.pm index c540e841d..ef462bf5a 100755 --- a/fhem/FHEM/00_CM11.pm +++ b/fhem/FHEM/00_CM11.pm @@ -188,8 +188,6 @@ CM11_Define($$) $hash->{MOBILE} = 1 if($a[4] && $a[4] eq "mobile"); $hash->{STATE} = "defined"; - $attr{$name}{savefirst} = 1; - if($dev eq "none") { Log 1, "CM11 device is none, commands will be echoed only"; $attr{$name}{dummy} = 1; diff --git a/fhem/FHEM/00_CUL.pm b/fhem/FHEM/00_CUL.pm index 9c5c20745..6eb79f68a 100755 --- a/fhem/FHEM/00_CUL.pm +++ b/fhem/FHEM/00_CUL.pm @@ -28,7 +28,6 @@ my %gets = ( "ccconf" => "=", "uptime" => "t", "file" => "", - "time" => "c03", "fhtbuf" => "T03" ); @@ -66,7 +65,7 @@ CUL_Initialize($) "6:CUL_EM" => "^E0.................\$", "7:HMS" => "^810e04....(1|5|9).a001", "8:CUL_FHTTK" => "^T........", - "9:CUL_RFR" => "^[0-9][0-9]U...", + "9:CUL_RFR" => "^[0-9A-F]{4}U.", ); $hash->{MatchList} = \%mc; $hash->{ReadyFn} = "CUL_Ready"; @@ -101,8 +100,6 @@ CUL_Define($$) if(uc($a[3]) !~ m/^[0-6][0-9A-F][0-6][0-9A-F]$/); $hash->{FHTID} = uc($a[3]); - $attr{$name}{savefirst} = 1; - if($dev eq "none") { Log 1, "CUL device is none, commands will be echoed only"; $attr{$name}{dummy} = 1; @@ -297,8 +294,9 @@ sub CUL_Get($@) { my ($hash, @a) = @_; + my $type = $hash->{TYPE}; - return "\"get CUL\" needs at least one parameter" if(@a < 2); + return "\"get $type\" needs at least one parameter" if(@a < 2); return "Unknown argument $a[1], choose one of " . join(" ", sort keys %gets) if(!defined($gets{$a[1]})); @@ -321,7 +319,7 @@ CUL_Get($@) $msg = sprintf("freq:%.3fMHz bWidth:%dKHz rAmpl:%ddB sens:%ddB", 26*(($r{"0D"}*256+$r{"0E"})*256+$r{"0F"})/65536, #Freq 26000/(8 * (4+(($r{"10"}>>4)&3)) * (1 << (($r{"10"}>>6)&3))), #Bw - $ampllist[$r{"1B"}], + $ampllist[$r{"1B"}&7], 4+4*($r{"1D"}&3) #Sens ); @@ -483,10 +481,14 @@ CUL_DoInit($) ##################################### # This is a direct read for commands like get +# Anydata is used by read file to get the filesize sub CUL_ReadAnswer($$$) { my ($hash, $arg, $anydata) = @_; + my $type = $hash->{TYPE}; + + $hash = $hash->{IODev} if($type eq "CUL_RFR"); return ("No FD", undef) if(!$hash || ($^O !~ /Win/ && !defined($hash->{FD}))); @@ -520,14 +522,17 @@ CUL_ReadAnswer($$$) if($nfound == 0); $buf = CUL_SimpleRead($hash); return ("No data", undef) if(!defined($buf)); + } if($buf) { Log 5, "CUL/RAW: $buf"; $mculdata .= $buf; } + $mculdata = CUL_RFR_DelPrefix($mculdata) if($type eq "CUL_RFR"); return (undef, $mculdata) if($mculdata =~ m/\r\n/ || $anydata); } + } ##################################### @@ -598,28 +603,7 @@ CUL_Write($$$) my ($hash,$fn,$msg) = @_; ($fn, $msg) = CUL_WriteTranslate($hash, $fn, $msg); -ZZZZZZZZZ - my $name = $hash->{NAME}; - - ################### - # Rewrite message from FHZ -> CUL - if(length($fn) <= 1) { # CUL Native - ; - - } elsif($fn eq "04" && substr($msg,0,6) eq "010101") { # FS20 - $fn = "F"; - AddDuplicate($hash->{NAME}, - "0101a001" . substr($msg, 6, 6) . "00" . substr($msg, 12)); - $msg = substr($msg,6); - - } elsif($fn eq "04" && substr($msg,0,6) eq "020183") { # FHT - $fn = "T"; - $msg = substr($msg,6,4) . substr($msg,10); - - } else { - Log GetLogLevel($name,2), "CUL cannot translate $fn $msg"; - return; - } + return if(!defined($fn)); Log 5, "CUL sending $fn$msg"; my $bstring = "$fn$msg"; @@ -738,7 +722,7 @@ CUL_Parse($$$$$) #Translate Message from CUL to FHZ next if(!$dmsg || length($dmsg) < 1); # Bogus messages - if($dmsg =~ m/^[0-9][0-9]U.../) { # RF_ROUTER + if($dmsg =~ m/^[0-9A-F]{4}U./) { # RF_ROUTER Dispatch($hash, $dmsg, undef); return; } @@ -824,26 +808,18 @@ CUL_Ready($) return ($InBytes>0); } -sub -CUL_SendCurMsg($$$) -{ - my ($hash,$id,$msg) = @_; - - $msg = substr($msg, 0, 12) if(length($msg) > 12); - my $rmsg = "F" . $id . unpack('H*', $msg); - Log 1, "CUL_SendCurMsg: $id:$msg / $rmsg"; - sleep(1); # Poor mans CSMA/CD - CUL_SimpleWrite($hash, $rmsg); -} - ######################## sub CUL_SimpleWrite(@) { - my ($hash, $msg, $noapp) = @_; + my ($hash, $msg, $nonl) = @_; return if(!$hash); - $msg .= "\n" unless($noapp); + if($hash->{TYPE} eq "CUL_RFR") { + $msg = CUL_RFR_AddPrefix($hash, $msg); + $hash = $hash->{IODev}; + } + $msg .= "\n" unless($nonl); $hash->{USBDev}->write($msg . "\n") if($hash->{USBDev}); syswrite($hash->{TCPDev}, $msg) if($hash->{TCPDev}); @@ -990,7 +966,7 @@ CUL_Disconnected($) my $dev = $hash->{DeviceName}; my $name = $hash->{NAME}; - return if(!defined($hash->{FD})); # Already deleted. + return if(!defined($hash->{FD})); # Already deleted or RFR Log 1, "$dev disconnected, waiting to reappear"; CUL_CloseDev($hash); diff --git a/fhem/FHEM/00_FHZ.pm b/fhem/FHEM/00_FHZ.pm index 45a7d5aab..172c917e7 100755 --- a/fhem/FHEM/00_FHZ.pm +++ b/fhem/FHEM/00_FHZ.pm @@ -308,7 +308,6 @@ FHZ_Define($$) $hash->{MOBILE} = 1 if($a[4] && $a[4] eq "mobile"); $hash->{STATE} = "defined"; - $attr{$name}{savefirst} = 1; $attr{$name}{fhtsoftbuffer} = 0; if($dev eq "none") { diff --git a/fhem/FHEM/16_CUL_RFR.pm b/fhem/FHEM/16_CUL_RFR.pm index 187bb563d..76e849b93 100755 --- a/fhem/FHEM/16_CUL_RFR.pm +++ b/fhem/FHEM/16_CUL_RFR.pm @@ -18,15 +18,22 @@ CUL_RFR_Initialize($) # Message is like # K41350270 - $hash->{WriteFn} = "CUL_RFR_Write"; - $hash->{Clients} = $modules{CUL}->{Clients}; - $hash->{Match} = "^[0-9][0-9]U..."; + my $cl = $modules{CUL}->{Clients}; + $cl =~ s/CUL_RFR//; # Dont want to be my own client. + + $hash->{Clients} = $cl; + $hash->{Match} = "^[0-9A-F]{4}U."; $hash->{DefFn} = "CUL_RFR_Define"; $hash->{UndefFn} = "CUL_RFR_Undef"; $hash->{ParseFn} = "CUL_RFR_Parse"; $hash->{AttrList} = "IODev do_not_notify:0,1 model:CUL,CUN,CUR loglevel"; + + $hash->{WriteFn} = "CUL_RFR_Write"; + $hash->{GetFn} = "CUL_Get"; + $hash->{SetFn} = "CUL_Set"; } + ##################################### sub CUL_RFR_Define($$) @@ -34,10 +41,13 @@ CUL_RFR_Define($$) my ($hash, $def) = @_; my @a = split("[ \t][ \t]*", $def); - return "wrong syntax: define CUL_RFR " - if(int(@a) != 3 || $a[2] !~ m/[0-9][0-9]/); - $hash->{CODE} = $a[2]; - $defptr{$a[2]} = $hash; + return "wrong syntax: define CUL_RFR " + if(int(@a) != 4 || + $a[2] !~ m/[0-9A-F]{2}/i || + $a[3] !~ m/[0-9A-F]{2}/i); + $hash->{ID} = $a[2]; + $hash->{ROUTERID} = $a[3]; + $defptr{"$a[2]$a[3]"} = $hash; AssignIoPort($hash); return undef; } @@ -47,6 +57,11 @@ sub CUL_RFR_Write($$) { my ($hash,$fn,$msg) = @_; + + ($fn, $msg) = CUL_WriteTranslate($hash, $fn, $msg); + return if(!defined($fn)); + $msg = $hash->{ID} . $hash->{ROUTERID} . $fn . $msg; + IOWrite($hash, "u", $msg); } ##################################### @@ -66,16 +81,33 @@ CUL_RFR_Parse($$) # 0123456789012345678 # E01012471B80100B80B -> Type 01, Code 01, Cnt 10 - my ($cde, $omsg) = split("U", $msg, 2); + $msg =~ m/^([0-9AF]{2})([0-9AF]{2})U(.*)/; + my ($rid, $id, $smsg) = ($1,$2,$3); + my $cde = "${id}${rid}"; + if(!$defptr{$cde}) { - Log 1, "CUL_RFR detected, Code $cde, MSG $omsg"; + Log 1, "CUL_RFR detected, Id $id, Router $rid, MSG $smsg"; return; } my $hash = $defptr{$cde}; my $name = $hash->{NAME}; - CUL_Parse($hash, $iohash, $hash->{NAME}, $omsg, "X21"); + CUL_Parse($hash, $iohash, $hash->{NAME}, $smsg, "X21"); return ""; } +sub +CUL_RFR_DelPrefix($) +{ + my ($prefix, $msg) = split("U", shift); + return $msg; +} + +sub +CUL_RFR_AddPrefix($$) +{ + my ($hash, $msg) = @_; + return "u" . $hash->{ID} . $hash->{ROUTERID} . $msg; +} + 1; diff --git a/fhem/FHEM/50_WS300.pm b/fhem/FHEM/50_WS300.pm index 0fcb08157..345675ad3 100644 --- a/fhem/FHEM/50_WS300.pm +++ b/fhem/FHEM/50_WS300.pm @@ -158,7 +158,6 @@ WS300_Define($$) $hash->{READINGS}{WS300Device}{TIME} = TimeNow; CommandDefine(undef,"WS300Device_timer at +*00:00:05 get WS300Device data"); Log 1,"WS300 Device $a[2] opened"; - $attr{$a[0]}{savefirst} = 1; return undef; } return "wrong syntax: define WS300 \n0-7=ASH2200\n8=KS300\n9=WS300" if(int(@a) < 3); diff --git a/fhem/FHEM/60_EM.pm b/fhem/FHEM/60_EM.pm index 20cd44e18..70998211a 100755 --- a/fhem/FHEM/60_EM.pm +++ b/fhem/FHEM/60_EM.pm @@ -48,8 +48,6 @@ EM_Define($$) my $name = $a[0]; my $dev = $a[2]; - $attr{$name}{savefirst} = 1; - if($dev eq "none") { Log 1, "EM device is none, commands will be echoed only"; $attr{$name}{dummy} = 1; diff --git a/fhem/FHEM/80_M232.pm b/fhem/FHEM/80_M232.pm index 64ce19051..128646009 100644 --- a/fhem/FHEM/80_M232.pm +++ b/fhem/FHEM/80_M232.pm @@ -44,8 +44,6 @@ M232_Define($$) $hash->{STATE} = "Initialized"; my $dev = $a[2]; - $attr{$a[0]}{savefirst} = 1; - if($dev eq "none") { Log 1, "M232 device is none, commands will be echoed only"; return undef; diff --git a/fhem/FHEM/87_WS2000.pm b/fhem/FHEM/87_WS2000.pm index 947664b66..279c6feaf 100644 --- a/fhem/FHEM/87_WS2000.pm +++ b/fhem/FHEM/87_WS2000.pm @@ -4,7 +4,7 @@ package main; # Modul for FHEM # # contributed by thomas dressler 2008 -# $Id: 87_WS2000.pm,v 1.6 2009-04-10 09:54:37 rudolfkoenig Exp $ +# $Id: 87_WS2000.pm,v 1.7 2009-11-22 19:16:16 rudolfkoenig Exp $ # corr. negativ temps / peterp ########################### use strict; @@ -55,7 +55,6 @@ WS2000_Define($$) my $name=$hash->{NAME}; my $PortName = $a[2]; my $PortObj; - $attr{$a[0]}{savefirst} = 1; if($PortName eq "none") { Log 1, "WS2000 device is none, commands will be echoed only"; diff --git a/fhem/fhem.pl b/fhem/fhem.pl index 6c81c305f..4e9909c7a 100755 --- a/fhem/fhem.pl +++ b/fhem/fhem.pl @@ -155,7 +155,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.84 2009-11-20 11:10:07 rudolfkoenig Exp $'; +my $cvsid = '$Id: fhem.pl,v 1.85 2009-11-22 19:16:16 rudolfkoenig Exp $'; my $namedef = "where is either:\n" . "- a single device name\n" . @@ -859,47 +859,19 @@ CommandSave($$) return "Cannot open $param: $!"; } - # Sort the devices by room - my (%rooms, %savefirst); - foreach my $d (sort keys %defs) { - next if($d eq "global"); - my $r = ($attr{$d} && $attr{$d}{room}) ? $attr{$d}{room} : "~"; - $rooms{$r}{$d} = 1; - $savefirst{$d} = $r if($attr{$d} && $attr{$d}{savefirst}); - } + 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 - # First the global definitions - my $t = localtime; - print SFH "#$t\n\n"; - print SFH "attr global userattr $attr{global}{userattr}\n" - if($attr{global}{userattr}); - foreach my $a (sort keys %{$attr{global}}) { - next if($a eq "configfile" || $a eq "version" || $a eq "userattr"); - print SFH "attr global $a $attr{global}{$a}\n"; - } - print SFH "\n"; - - # then the "important" ones (FHZ, WS300Device) - foreach my $d (sort { $defs{$a}{NR} <=> $defs{$b}{NR} } keys %savefirst) { - my $r = $savefirst{$d}; - delete $rooms{$r}{$d}; - delete $rooms{$r} if(! %{$rooms{$r}}); - next if(!$defs{$d}); - my $def = $defs{$d}{DEF}; - $def =~ s/;/;;/g; - print SFH "define $d $defs{$d}{TYPE} $def\n"; - foreach my $a (sort keys %{$attr{$d}}) { - next if($a eq "savefirst"); - print SFH "attr $d $a $attr{$d}{$a}\n"; + my $room = ($attr{$d} ? $attr{$d}{room} : ""); + $room = "" if(!$room); + if($room ne $oldroom) { + print SFH "\nsetdefaultattr" . ($room ? " room $room" : "") . "\n"; + $oldroom = $room; } - } - foreach my $r (sort keys %rooms) { - print SFH "\nsetdefaultattr" . ($r ne "~" ? " room $r" : "") . "\n"; - foreach my $d (sort keys %{$rooms{$r}} ) { - next if(!$defs{$d}); - next if($defs{$d}{TEMPORARY}); - next if($defs{$d}{VOLATILE}); + if($d ne "global") { if($defs{$d}{DEF}) { my $def = $defs{$d}{DEF}; $def =~ s/;/;;/g; @@ -907,15 +879,14 @@ CommandSave($$) } else { print SFH "define $d $defs{$d}{TYPE}\n"; } - foreach my $a (sort keys %{$attr{$d}}) { - next if($a eq "room"); - print SFH "attr $d $a $attr{$d}{$a}\n"; - } + } + foreach my $a (sort keys %{$attr{$d}}) { + next if($a eq "room"); + next if($d eq "global" && + ($a eq "configfile" || $a eq "version" || $a eq "userattr")); + print SFH "attr $d $a $attr{$d}{$a}\n"; } } - - print SFH "setdefaultattr\n"; # Delete the last default attribute. - print SFH "include $attr{global}{lastinclude}\n" if($attr{global}{lastinclude});