RF_ROUTER, save command retains old config file order

git-svn-id: svn://svn.code.sf.net/p/fhem/code/trunk@484 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig
2009-11-22 19:16:16 +00:00
parent 9025e52d50
commit ba353aabbb
10 changed files with 82 additions and 110 deletions

View File

@@ -542,3 +542,5 @@
- feature: 21_OWTEMP.pm for 1-Wire Digital Thermometer added (Martin Fischer) - feature: 21_OWTEMP.pm for 1-Wire Digital Thermometer added (Martin Fischer)
- feature: CUL_FHTTK from Kai - feature: CUL_FHTTK from Kai
- feature: pgm3: Google-Weather, Battery-Check, Log-View added (MartinH) - 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

View File

@@ -188,8 +188,6 @@ CM11_Define($$)
$hash->{MOBILE} = 1 if($a[4] && $a[4] eq "mobile"); $hash->{MOBILE} = 1 if($a[4] && $a[4] eq "mobile");
$hash->{STATE} = "defined"; $hash->{STATE} = "defined";
$attr{$name}{savefirst} = 1;
if($dev eq "none") { if($dev eq "none") {
Log 1, "CM11 device is none, commands will be echoed only"; Log 1, "CM11 device is none, commands will be echoed only";
$attr{$name}{dummy} = 1; $attr{$name}{dummy} = 1;

View File

@@ -28,7 +28,6 @@ my %gets = (
"ccconf" => "=", "ccconf" => "=",
"uptime" => "t", "uptime" => "t",
"file" => "", "file" => "",
"time" => "c03",
"fhtbuf" => "T03" "fhtbuf" => "T03"
); );
@@ -66,7 +65,7 @@ CUL_Initialize($)
"6:CUL_EM" => "^E0.................\$", "6:CUL_EM" => "^E0.................\$",
"7:HMS" => "^810e04....(1|5|9).a001", "7:HMS" => "^810e04....(1|5|9).a001",
"8:CUL_FHTTK" => "^T........", "8:CUL_FHTTK" => "^T........",
"9:CUL_RFR" => "^[0-9][0-9]U...", "9:CUL_RFR" => "^[0-9A-F]{4}U.",
); );
$hash->{MatchList} = \%mc; $hash->{MatchList} = \%mc;
$hash->{ReadyFn} = "CUL_Ready"; $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]$/); if(uc($a[3]) !~ m/^[0-6][0-9A-F][0-6][0-9A-F]$/);
$hash->{FHTID} = uc($a[3]); $hash->{FHTID} = uc($a[3]);
$attr{$name}{savefirst} = 1;
if($dev eq "none") { if($dev eq "none") {
Log 1, "CUL device is none, commands will be echoed only"; Log 1, "CUL device is none, commands will be echoed only";
$attr{$name}{dummy} = 1; $attr{$name}{dummy} = 1;
@@ -297,8 +294,9 @@ sub
CUL_Get($@) CUL_Get($@)
{ {
my ($hash, @a) = @_; 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) return "Unknown argument $a[1], choose one of " . join(" ", sort keys %gets)
if(!defined($gets{$a[1]})); if(!defined($gets{$a[1]}));
@@ -321,7 +319,7 @@ CUL_Get($@)
$msg = sprintf("freq:%.3fMHz bWidth:%dKHz rAmpl:%ddB sens:%ddB", $msg = sprintf("freq:%.3fMHz bWidth:%dKHz rAmpl:%ddB sens:%ddB",
26*(($r{"0D"}*256+$r{"0E"})*256+$r{"0F"})/65536, #Freq 26*(($r{"0D"}*256+$r{"0E"})*256+$r{"0F"})/65536, #Freq
26000/(8 * (4+(($r{"10"}>>4)&3)) * (1 << (($r{"10"}>>6)&3))), #Bw 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 4+4*($r{"1D"}&3) #Sens
); );
@@ -483,10 +481,14 @@ CUL_DoInit($)
##################################### #####################################
# This is a direct read for commands like get # This is a direct read for commands like get
# Anydata is used by read file to get the filesize
sub sub
CUL_ReadAnswer($$$) CUL_ReadAnswer($$$)
{ {
my ($hash, $arg, $anydata) = @_; my ($hash, $arg, $anydata) = @_;
my $type = $hash->{TYPE};
$hash = $hash->{IODev} if($type eq "CUL_RFR");
return ("No FD", undef) return ("No FD", undef)
if(!$hash || ($^O !~ /Win/ && !defined($hash->{FD}))); if(!$hash || ($^O !~ /Win/ && !defined($hash->{FD})));
@@ -520,14 +522,17 @@ CUL_ReadAnswer($$$)
if($nfound == 0); if($nfound == 0);
$buf = CUL_SimpleRead($hash); $buf = CUL_SimpleRead($hash);
return ("No data", undef) if(!defined($buf)); return ("No data", undef) if(!defined($buf));
} }
if($buf) { if($buf) {
Log 5, "CUL/RAW: $buf"; Log 5, "CUL/RAW: $buf";
$mculdata .= $buf; $mculdata .= $buf;
} }
$mculdata = CUL_RFR_DelPrefix($mculdata) if($type eq "CUL_RFR");
return (undef, $mculdata) if($mculdata =~ m/\r\n/ || $anydata); return (undef, $mculdata) if($mculdata =~ m/\r\n/ || $anydata);
} }
} }
##################################### #####################################
@@ -598,28 +603,7 @@ CUL_Write($$$)
my ($hash,$fn,$msg) = @_; my ($hash,$fn,$msg) = @_;
($fn, $msg) = CUL_WriteTranslate($hash, $fn, $msg); ($fn, $msg) = CUL_WriteTranslate($hash, $fn, $msg);
ZZZZZZZZZ return if(!defined($fn));
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;
}
Log 5, "CUL sending $fn$msg"; Log 5, "CUL sending $fn$msg";
my $bstring = "$fn$msg"; my $bstring = "$fn$msg";
@@ -738,7 +722,7 @@ CUL_Parse($$$$$)
#Translate Message from CUL to FHZ #Translate Message from CUL to FHZ
next if(!$dmsg || length($dmsg) < 1); # Bogus messages 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); Dispatch($hash, $dmsg, undef);
return; return;
} }
@@ -824,26 +808,18 @@ CUL_Ready($)
return ($InBytes>0); 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 sub
CUL_SimpleWrite(@) CUL_SimpleWrite(@)
{ {
my ($hash, $msg, $noapp) = @_; my ($hash, $msg, $nonl) = @_;
return if(!$hash); 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}); $hash->{USBDev}->write($msg . "\n") if($hash->{USBDev});
syswrite($hash->{TCPDev}, $msg) if($hash->{TCPDev}); syswrite($hash->{TCPDev}, $msg) if($hash->{TCPDev});
@@ -990,7 +966,7 @@ CUL_Disconnected($)
my $dev = $hash->{DeviceName}; my $dev = $hash->{DeviceName};
my $name = $hash->{NAME}; 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"; Log 1, "$dev disconnected, waiting to reappear";
CUL_CloseDev($hash); CUL_CloseDev($hash);

View File

@@ -308,7 +308,6 @@ FHZ_Define($$)
$hash->{MOBILE} = 1 if($a[4] && $a[4] eq "mobile"); $hash->{MOBILE} = 1 if($a[4] && $a[4] eq "mobile");
$hash->{STATE} = "defined"; $hash->{STATE} = "defined";
$attr{$name}{savefirst} = 1;
$attr{$name}{fhtsoftbuffer} = 0; $attr{$name}{fhtsoftbuffer} = 0;
if($dev eq "none") { if($dev eq "none") {

View File

@@ -18,15 +18,22 @@ CUL_RFR_Initialize($)
# Message is like # Message is like
# K41350270 # K41350270
$hash->{WriteFn} = "CUL_RFR_Write"; my $cl = $modules{CUL}->{Clients};
$hash->{Clients} = $modules{CUL}->{Clients}; $cl =~ s/CUL_RFR//; # Dont want to be my own client.
$hash->{Match} = "^[0-9][0-9]U...";
$hash->{Clients} = $cl;
$hash->{Match} = "^[0-9A-F]{4}U.";
$hash->{DefFn} = "CUL_RFR_Define"; $hash->{DefFn} = "CUL_RFR_Define";
$hash->{UndefFn} = "CUL_RFR_Undef"; $hash->{UndefFn} = "CUL_RFR_Undef";
$hash->{ParseFn} = "CUL_RFR_Parse"; $hash->{ParseFn} = "CUL_RFR_Parse";
$hash->{AttrList} = "IODev do_not_notify:0,1 model:CUL,CUN,CUR loglevel"; $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 sub
CUL_RFR_Define($$) CUL_RFR_Define($$)
@@ -34,10 +41,13 @@ CUL_RFR_Define($$)
my ($hash, $def) = @_; my ($hash, $def) = @_;
my @a = split("[ \t][ \t]*", $def); my @a = split("[ \t][ \t]*", $def);
return "wrong syntax: define <name> CUL_RFR <code>" return "wrong syntax: define <name> CUL_RFR <id> <routerid>"
if(int(@a) != 3 || $a[2] !~ m/[0-9][0-9]/); if(int(@a) != 4 ||
$hash->{CODE} = $a[2]; $a[2] !~ m/[0-9A-F]{2}/i ||
$defptr{$a[2]} = $hash; $a[3] !~ m/[0-9A-F]{2}/i);
$hash->{ID} = $a[2];
$hash->{ROUTERID} = $a[3];
$defptr{"$a[2]$a[3]"} = $hash;
AssignIoPort($hash); AssignIoPort($hash);
return undef; return undef;
} }
@@ -47,6 +57,11 @@ sub
CUL_RFR_Write($$) CUL_RFR_Write($$)
{ {
my ($hash,$fn,$msg) = @_; 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 # 0123456789012345678
# E01012471B80100B80B -> Type 01, Code 01, Cnt 10 # 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}) { if(!$defptr{$cde}) {
Log 1, "CUL_RFR detected, Code $cde, MSG $omsg"; Log 1, "CUL_RFR detected, Id $id, Router $rid, MSG $smsg";
return; return;
} }
my $hash = $defptr{$cde}; my $hash = $defptr{$cde};
my $name = $hash->{NAME}; my $name = $hash->{NAME};
CUL_Parse($hash, $iohash, $hash->{NAME}, $omsg, "X21"); CUL_Parse($hash, $iohash, $hash->{NAME}, $smsg, "X21");
return ""; 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; 1;

View File

@@ -158,7 +158,6 @@ WS300_Define($$)
$hash->{READINGS}{WS300Device}{TIME} = TimeNow; $hash->{READINGS}{WS300Device}{TIME} = TimeNow;
CommandDefine(undef,"WS300Device_timer at +*00:00:05 get WS300Device data"); CommandDefine(undef,"WS300Device_timer at +*00:00:05 get WS300Device data");
Log 1,"WS300 Device $a[2] opened"; Log 1,"WS300 Device $a[2] opened";
$attr{$a[0]}{savefirst} = 1;
return undef; return undef;
} }
return "wrong syntax: define <name> WS300 <sensor (0-9)>\n0-7=ASH2200\n8=KS300\n9=WS300" if(int(@a) < 3); return "wrong syntax: define <name> WS300 <sensor (0-9)>\n0-7=ASH2200\n8=KS300\n9=WS300" if(int(@a) < 3);

View File

@@ -48,8 +48,6 @@ EM_Define($$)
my $name = $a[0]; my $name = $a[0];
my $dev = $a[2]; my $dev = $a[2];
$attr{$name}{savefirst} = 1;
if($dev eq "none") { if($dev eq "none") {
Log 1, "EM device is none, commands will be echoed only"; Log 1, "EM device is none, commands will be echoed only";
$attr{$name}{dummy} = 1; $attr{$name}{dummy} = 1;

View File

@@ -44,8 +44,6 @@ M232_Define($$)
$hash->{STATE} = "Initialized"; $hash->{STATE} = "Initialized";
my $dev = $a[2]; my $dev = $a[2];
$attr{$a[0]}{savefirst} = 1;
if($dev eq "none") { if($dev eq "none") {
Log 1, "M232 device is none, commands will be echoed only"; Log 1, "M232 device is none, commands will be echoed only";
return undef; return undef;

View File

@@ -4,7 +4,7 @@ package main;
# Modul for FHEM # Modul for FHEM
# #
# contributed by thomas dressler 2008 # 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 # corr. negativ temps / peterp
########################### ###########################
use strict; use strict;
@@ -55,7 +55,6 @@ WS2000_Define($$)
my $name=$hash->{NAME}; my $name=$hash->{NAME};
my $PortName = $a[2]; my $PortName = $a[2];
my $PortObj; my $PortObj;
$attr{$a[0]}{savefirst} = 1;
if($PortName eq "none") { if($PortName eq "none") {
Log 1, "WS2000 device is none, commands will be echoed only"; Log 1, "WS2000 device is none, commands will be echoed only";

View File

@@ -155,7 +155,7 @@ my $nextat; # Time when next timer will be triggered.
my $intAtCnt=0; my $intAtCnt=0;
my %duplicate; # Pool of received msg for multi-fhz/cul setups my %duplicate; # Pool of received msg for multi-fhz/cul setups
my $duplidx=0; # helper for the above pool 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 = my $namedef =
"where <name> is either:\n" . "where <name> is either:\n" .
"- a single device name\n" . "- a single device name\n" .
@@ -859,47 +859,19 @@ CommandSave($$)
return "Cannot open $param: $!"; return "Cannot open $param: $!";
} }
# Sort the devices by room my $oldroom = "";
my (%rooms, %savefirst); foreach my $d (sort { $defs{$a}{NR} <=> $defs{$b}{NR} } keys %defs) {
foreach my $d (sort keys %defs) { next if($defs{$d}{TEMPORARY} || # e.g. WEBPGM connections
next if($d eq "global"); $defs{$d}{VOLATILE}); # e.g at, will be saved to the statefile
my $r = ($attr{$d} && $attr{$d}{room}) ? $attr{$d}{room} : "~";
$rooms{$r}{$d} = 1;
$savefirst{$d} = $r if($attr{$d} && $attr{$d}{savefirst});
}
# First the global definitions my $room = ($attr{$d} ? $attr{$d}{room} : "");
my $t = localtime; $room = "" if(!$room);
print SFH "#$t\n\n"; if($room ne $oldroom) {
print SFH "attr global userattr $attr{global}{userattr}\n" print SFH "\nsetdefaultattr" . ($room ? " room $room" : "") . "\n";
if($attr{global}{userattr}); $oldroom = $room;
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";
} }
}
foreach my $r (sort keys %rooms) { if($d ne "global") {
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($defs{$d}{DEF}) { if($defs{$d}{DEF}) {
my $def = $defs{$d}{DEF}; my $def = $defs{$d}{DEF};
$def =~ s/;/;;/g; $def =~ s/;/;;/g;
@@ -907,15 +879,14 @@ CommandSave($$)
} else { } else {
print SFH "define $d $defs{$d}{TYPE}\n"; print SFH "define $d $defs{$d}{TYPE}\n";
} }
foreach my $a (sort keys %{$attr{$d}}) { }
next if($a eq "room"); foreach my $a (sort keys %{$attr{$d}}) {
print SFH "attr $d $a $attr{$d}{$a}\n"; 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" print SFH "include $attr{global}{lastinclude}\n"
if($attr{global}{lastinclude}); if($attr{global}{lastinclude});