mutliple buffer finished

git-svn-id: https://fhem.svn.sourceforge.net/svnroot/fhem/trunk/fhem@147 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig
2008-01-19 19:02:30 +00:00
parent 5498ddc406
commit 8d7d0dbab1
6 changed files with 238 additions and 175 deletions

View File

@@ -378,7 +378,8 @@
- bugfix: 99_SUNRISE_EL.pm: may schedule double events - bugfix: 99_SUNRISE_EL.pm: may schedule double events
- bugfix: 62_EMEM.pl, contrib/em1010.pl: correct readings for energy_kWh - bugfix: 62_EMEM.pl, contrib/em1010.pl: correct readings for energy_kWh
and energy_kWh_w (Boris, 06.01.08) and energy_kWh_w (Boris, 06.01.08)
- feature: gloabl attr allowfrom, as wished by Holger (8.1.2008) - feature: global attr allowfrom, as wished by Holger (8.1.2008)
- feature: FHT: multiple commands, softbuffer changes, cmd rename, doc
- TODO - TODO
emem -2.5kW / getDevData for emwz -1 emem -2.5kW / getDevData for emwz -1

View File

@@ -142,7 +142,7 @@ FHZ_Get($@)
my $v = join(" ", @a); my $v = join(" ", @a);
my $name = $hash->{NAME}; my $name = $hash->{NAME};
Log GetLogLevel($name,2), "FHZ get $name $v"; Log GetLogLevel($name,2), "FHZ get $v";
FHZ_Write($hash, $fn, $arg) if(!IsDummy("FHZ")); FHZ_Write($hash, $fn, $arg) if(!IsDummy("FHZ"));

View File

@@ -6,11 +6,15 @@ use warnings;
sub doSoftBuffer($); sub doSoftBuffer($);
sub softBufferTimer($); sub softBufferTimer($);
sub sendCommand($$$$); sub getFhtMin($);
sub getFhtBuffer($);
my %codes = ( my %codes = (
"0000.6" => "actuator", "0000.6" => "actuator",
"00002a" => "lime-protection",
"00002c" => "synctime", # Not verified "00002c" => "synctime", # Not verified
"0000aa" => "code_0000aa",
"0000ba" => "code_0000ba",
"0100.6" => "actuator1", # Not verified (1-8) "0100.6" => "actuator1", # Not verified (1-8)
"0200.6" => "actuator2", "0200.6" => "actuator2",
"0300.6" => "actuator3", "0300.6" => "actuator3",
@@ -19,6 +23,7 @@ my %codes = (
"0600.6" => "actuator6", "0600.6" => "actuator6",
"0700.6" => "actuator7", "0700.6" => "actuator7",
"0800.6" => "actuator8", "0800.6" => "actuator8",
"140069" => "mon-from1", "140069" => "mon-from1",
"150069" => "mon-to1", "150069" => "mon-to1",
"160069" => "mon-from2", "160069" => "mon-from2",
@@ -47,33 +52,34 @@ my %codes = (
"2d0069" => "sun-to1", "2d0069" => "sun-to1",
"2e0069" => "sun-from2", "2e0069" => "sun-from2",
"2f0069" => "sun-to2", "2f0069" => "sun-to2",
"3e0069" => "mode", "3e0069" => "mode",
"3f0069" => "holiday1", # Not verified "3f0069" => "holiday1", # Not verified
"400069" => "holiday2", # Not verified "400069" => "holiday2", # Not verified
"410069" => "desired-temp", "410069" => "desired-temp",
"XX0069" => "measured-temp", # sum of next. two, never "really" sent "XX0069" => "measured-temp", # sum of next. two, never really sent
"420069" => "measured-low", "420069" => "measured-low",
"430069" => "measured-high", "430069" => "measured-high",
"430079" => "code_430079",
"440069" => "warnings", "440069" => "warnings",
"450069" => "manu-temp", # Manuelle Temperatur keine ahnung was das bewirkt "440079" => "code_440079",
"450069" => "manu-temp", # No clue what it does.
"..0067" => "repeat1", # repeat the last data (?)
"..0077" => "repeat2",
"600069" => "year", "600069" => "year",
"610069" => "month", "610069" => "month",
"620069" => "day", "620069" => "day",
"630069" => "hour", "630069" => "hour",
"640069" => "minute", "640069" => "minute",
"650069" => "init", "650069" => "refresh",
"660069" => "init", # ?
"820069" => "day-temp", "820069" => "day-temp",
"840069" => "night-temp", "840069" => "night-temp",
"850069" => "lowtemp-offset", # Alarm-Temp.-Differenz "850069" => "lowtemp-offset", # Alarm-Temp.-Differenz
"8a0069" => "windowopen-temp", "8a0069" => "windowopen-temp",
"00002a" => "lime-protection",
"0000aa" => "code_0000aa",
"0000ba" => "code_0000ba",
"430079" => "code_430079",
"440079" => "code_440079",
"4b0067" => "code_4b0067",
"4b0077" => "code_4b0077",
"7e0067" => "code_7e0067",
); );
my %cantset = ( my %cantset = (
@@ -91,26 +97,23 @@ my %cantset = (
"measured-high" => 1, "measured-high" => 1,
"measured-low" => 1, "measured-low" => 1,
"warnings" => 1, "warnings" => 1,
"init" => 1,
"lime-protection"=>1, "lime-protection"=>1,
"repeat1" => 1,
"repeat2" => 1,
"code_0000aa" => 1, "code_0000aa" => 1,
"code_0000ba" => 1, "code_0000ba" => 1,
"code_430079" => 1, "code_430079" => 1,
"code_440079" => 1, "code_440079" => 1,
"code_4b0067" => 1,
"code_4b0077" => 1,
"code_7e0067" => 1,
); );
my %nosetarg = ( my %nosetarg = (
"refreshvalues" => 1,
); );
my %priority = ( my %priority = (
"desired-temp"=> 1, "desired-temp"=> 1,
"mode" => 2, "mode" => 2,
"refreshvalues"=> 3, "refresh" => 3,
"holiday1" => 4, "holiday1" => 4,
"holiday2" => 5, "holiday2" => 5,
"day-temp" => 6, "day-temp" => 6,
@@ -123,7 +126,7 @@ my %c2b; # command->button hash (reverse of codes)
my %c2bset; # Setteable values my %c2bset; # Setteable values
my %defptr; my %defptr;
my $minFhzHardwareBuffer = 10; # min fhtbuf free bytes before sending commands my $defmin = 0; # min fhtbuf free bytes before sending commands
my $retryafter = 240; # in seconds, only when fhtsoftbuffer is active my $retryafter = 240; # in seconds, only when fhtsoftbuffer is active
my $cmdcount = 0; my $cmdcount = 0;
@@ -141,7 +144,6 @@ FHT_Initialize($)
foreach my $k (keys %c2m) { foreach my $k (keys %c2m) {
$m2c{$c2m{$k}} = $k; $m2c{$c2m{$k}} = $k;
} }
$c2bset{refreshvalues} = "65ff66ff";
# 810c0426 0909a001 1111 1600 # 810c0426 0909a001 1111 1600
# 810c04b3 0909a001 1111 44006900 # 810c04b3 0909a001 1111 44006900
@@ -155,7 +157,7 @@ FHT_Initialize($)
$hash->{UndefFn} = "FHT_Undef"; $hash->{UndefFn} = "FHT_Undef";
$hash->{ParseFn} = "FHT_Parse"; $hash->{ParseFn} = "FHT_Parse";
$hash->{AttrList} = "do_not_notify:0,1 model;fht80b dummy:0,1 " . $hash->{AttrList} = "do_not_notify:0,1 model;fht80b dummy:0,1 " .
"showtime:0,1 loglevel:0,1,2,3,4,5,6 retrycount"; "showtime:0,1 loglevel:0,1,2,3,4,5,6 retrycount minfhtbuffer";
} }
@@ -168,34 +170,38 @@ FHT_Set($@)
return "\"set $a[0]\" needs at least two parameters" if(@a < 2); return "\"set $a[0]\" needs at least two parameters" if(@a < 2);
my $name = shift(@a); my $name = shift(@a);
# Backward compatibility, replace refreshvalues with refresh and init.
for(my $i = 0; $i < @a; $i++) {
splice(@a,$i,1,("refresh","255","init","255"))
if($a[$i] eq "refreshvalues");
}
my $ncmd = 0; my $ncmd = 0;
my $arg = "020183" . $hash->{CODE}; my $arg = "020183" . $hash->{CODE};
my ($cmd, $val) = ("", ""); my ($cmd, $allcmd, $val) = ("", "", "");
while(@a) { while(@a) {
my $lcmd = shift(@a); $cmd = shift(@a);
$cmd .=" " if($cmd); $allcmd .=" " if($allcmd);
$cmd .= $lcmd; $allcmd .= $cmd;
return "Unknown argument $lcmd, choose one of " . return "Unknown argument $cmd, choose one of " .
join(" ", sort {$c2bset{$a} cmp $c2bset{$b} } keys %c2bset) join(" ", sort {$c2bset{$a} cmp $c2bset{$b} } keys %c2bset)
if(!defined($c2bset{$lcmd})); if(!defined($c2bset{$cmd}));
return "\"set $name\" needs a parameters" return "\"set $name\" needs a parameters"
if(@a < 1 && !$nosetarg{$lcmd}); if(@a < 1 && !$nosetarg{$cmd});
$ncmd++; $ncmd++;
if(!$nosetarg{$lcmd}) { if($nosetarg{$cmd}) {
$val = shift(@a);
$cmd .= " $val";
} else {
$val = undef; $val = undef;
} else {
$val = shift(@a);
} }
$arg .= $c2bset{$lcmd}; $arg .= $c2bset{$cmd};
if ($lcmd =~ m/-temp/) { if ($cmd =~ m/-temp/) {
return "Invalid temperature, use NN.N" if($val !~ m/^\d*\.?\d+$/); return "Invalid temperature, use NN.N" if($val !~ m/^\d*\.?\d+$/);
return "Invalid temperature, must between 5.5 and 30.5" return "Invalid temperature, must between 5.5 and 30.5"
@@ -205,7 +211,7 @@ FHT_Set($@)
$ret = sprintf("Rounded temperature to %.1f", $a/2) if($a/2 != $val); $ret = sprintf("Rounded temperature to %.1f", $a/2) if($a/2 != $val);
$val = sprintf("%.1f", $a/2); $val = sprintf("%.1f", $a/2);
} elsif($lcmd =~ m/-from/ || $lcmd =~ m/-to/) { } elsif($cmd =~ m/-from/ || $cmd =~ m/-to/) {
return "Invalid timeformat, use HH:MM" return "Invalid timeformat, use HH:MM"
if($val !~ m/^([0-2]\d):([0-5]\d)/); if($val !~ m/^([0-2]\d):([0-5]\d)/);
@@ -216,13 +222,13 @@ FHT_Set($@)
$ret = "Rounded time to $nt" if($nt ne $val); $ret = "Rounded time to $nt" if($nt ne $val);
$val = $nt; $val = $nt;
} elsif($lcmd eq "mode") { } elsif($cmd eq "mode") {
return "Invalid mode, use one of " . join(" ", sort keys %m2c) return "Invalid mode, use one of " . join(" ", sort keys %m2c)
if(!defined($m2c{$val})); if(!defined($m2c{$val}));
$arg .= sprintf("%02x", $m2c{$val}); $arg .= sprintf("%02x", $m2c{$val});
} elsif ($lcmd eq "lowtemp-offset") { } elsif ($cmd eq "lowtemp-offset") {
return "Invalid lowtemperature-offset, must between 1 and 5" return "Invalid lowtemperature-offset, must between 1 and 5"
if($val !~ m/^[1-5]$/); if($val !~ m/^[1-5]$/);
@@ -234,19 +240,17 @@ FHT_Set($@)
$arg .= sprintf("%02x", $val) if(defined($val)); $arg .= sprintf("%02x", $val) if(defined($val));
} }
$allcmd .= " $val" if($val);
} }
$val = "" if (!defined($val) || $ncmd > 1); return "Too many commands specified, an FHT only supports up to 8"
if($ncmd > 8);
my $ioname = ""; my $ioname = "";
$ioname = $hash->{IODev}->{NAME} if($hash->{IODev}); $ioname = $hash->{IODev}->{NAME} if($hash->{IODev});
if($attr{$ioname} && $attr{$ioname}{fhtsoftbuffer}) { if($attr{$ioname} && $attr{$ioname}{fhtsoftbuffer}) {
if($ncmd > 1) {
return "Cannot accept multiple FHT commands with fhtsoftbuffer enabled";
}
my $io = $hash->{IODev}; my $io = $hash->{IODev};
my %h = (HASH => $hash, CMD => $cmd, VAL => $val, ARG => $arg); my %h = (HASH => $hash, CMD => $allcmd, ARG => $arg);
my $prio = $priority{$cmd}; my $prio = $priority{$cmd};
$prio = "9" if(!$prio); $prio = "9" if(!$prio);
@@ -257,7 +261,8 @@ FHT_Set($@)
} else { } else {
sendCommand($hash, $cmd, $val, $arg); IOWrite($hash, "04", $arg) if(!IsDummy($name));
Log GetLogLevel($name,2), "FHT set $name $allcmd";
} }
@@ -297,7 +302,7 @@ FHT_Define($$)
AssignIoPort($hash); AssignIoPort($hash);
Log GetLogLevel($a[0],2),"Asking the FHT device $a[0]/$a[2] to send its data"; Log GetLogLevel($a[0],2),"Asking the FHT device $a[0]/$a[2] to send its data";
FHT_Set($hash, ($a[0], "refreshvalues")); FHT_Set($hash, ($a[0], "init", "255", "refresh", "255"));
return undef; return undef;
} }
@@ -430,17 +435,18 @@ FHT_Parse($$)
Log 4, "FHT $name $type: $val"; Log 4, "FHT $name $type: $val";
################################ ################################
# Softbuffer: deleted confirmed commands # Softbuffer: delete confirmed commands
if($confirm) { if($confirm) {
my $found; my $found;
my $io = $def->{IODev}; my $io = $def->{IODev};
foreach my $key (sort keys %{$io->{SOFTBUFFER}}) { foreach my $key (sort keys %{$io->{SOFTBUFFER}}) {
my $h = $io->{SOFTBUFFER}{$key}; my $h = $io->{SOFTBUFFER}{$key};
my $hcmd = $h->{CMD}; my $hcmd = $h->{CMD};
$hcmd = "init" if($hcmd eq "refreshvalues"); my $hname = $h->{HASH}->{NAME};
Log 5, "FHT check $h->{HASH}->{NAME} eq $name && $hcmd eq $type"; Log 4, "FHT softbuffer check: $hname / $hcmd";
if($h->{HASH}->{NAME} eq $name && $hcmd eq $type) { if($hname eq $name && $hcmd =~ m/^$type $val/) {
$found = $key; $found = $key;
Log 4, "FHT softbuffer found";
last; last;
} }
} }
@@ -471,17 +477,21 @@ doSoftBuffer($)
next if($now-$h->{SENDTIME} < $retryafter); next if($now-$h->{SENDTIME} < $retryafter);
my $retry = $attr{$name}{retrycount}; my $retry = $attr{$name}{retrycount};
if($h->{NSENT} > $retry) { if($h->{NSENT} > $retry) {
Log GetLogLevel($name,2), "$name set $h->{CMD} $h->{VAL}: ". Log GetLogLevel($name,2), "$name set $h->{CMD}: ".
"no confirmation after $h->{NSENT} tries, giving up"; "no confirmation after $h->{NSENT} tries, giving up";
delete($io->{SOFTBUFFER}{$key}); delete($io->{SOFTBUFFER}{$key});
next; next;
} }
} }
$fhzbuflen = getFhzBuffer($io) if($fhzbuflen == -999); $fhzbuflen = getFhtBuffer($io) if($fhzbuflen == -999);
next if($fhzbuflen < $minFhzHardwareBuffer); my $arglen = length($h->{ARG})/2 - 2; # Length in bytes
sendCommand($h->{HASH}, $h->{CMD}, $h->{VAL}, $h->{ARG});
$fhzbuflen -= ($h->{CMD} eq "refreshvalues" ? 7 : 5); next if($fhzbuflen < $arglen || $fhzbuflen < getFhtMin($io));
IOWrite($h->{HASH}, "04", $h->{ARG}) if(!IsDummy($name));
Log GetLogLevel($name,2), "FHT set $name $h->{CMD}";
$fhzbuflen -= $arglen;
$h->{SENDTIME} = $now; $h->{SENDTIME} = $now;
$h->{NSENT}++; $h->{NSENT}++;
@@ -503,50 +513,35 @@ softBufferTimer($)
doSoftBuffer($io); doSoftBuffer($io);
} }
#####################################
sub
getFhtMin($)
{
my ($io) = @_;
my $ioname = $io->{NAME};
return $attr{$ioname}{minfhtbuffer}
if($attr{$ioname} && $attr{$ioname}{minfhtbuffer});
return $defmin;
}
##################################### #####################################
# get the FHZ hardwarebuffer without logentry as decimal value # get the FHZ hardwarebuffer without logentry as decimal value
sub sub
getFhzBuffer($) getFhtBuffer($)
{ {
my ($io) = @_; my ($io) = @_;
my $count = 0; my $count = 0;
return $minFhzHardwareBuffer if(IsDummy($io->{NAME})); return getFhtMin($io) if(IsDummy($io->{NAME}));
for(;;) { for(;;) {
FHZ_Write($io, "04", "c90185"); FHZ_Write($io, "04", "c90185");
my $msg = FHZ_ReadAnswer($io, "fhtbuf"); my $msg = FHZ_ReadAnswer($io, "fhtbuf");
Log 5, "getFhzBuffer: $count $msg"; Log 5, "getFhtBuffer: $count $msg";
return hex(substr($msg, 16, 2)) if($msg && $msg =~ m/^[0-9A-F]+$/i); return hex(substr($msg, 16, 2)) if($msg && $msg =~ m/^[0-9A-F]+$/i);
return 0 if($count++ > 5); return 0 if($count++ > 5);
} }
} }
#####################################
# Send FHZ command
sub
sendCommand($$$$)
{
my ($hash, $cmd, $val, $arg) = @_;
my $name = $hash->{NAME};
if($cmd eq "refreshvalues") {
# This is special. Without the sleep the next FHT won't send its data
if(!IsDummy($name)) {
my $havefhz = ($hash->{IODev} && defined($hash->{IODev}->{FD}));
IOWrite($hash, "04", $arg);
sleep(1) if($havefhz);
}
} else {
IOWrite($hash, "04", $arg) if(!IsDummy($name));
}
Log GetLogLevel($name,2), "FHT set $name $cmd $val";
}
1; 1;

12
HISTORY
View File

@@ -197,3 +197,15 @@
- feature: attr global allowfrom <ip-adresses/hostnames> - feature: attr global allowfrom <ip-adresses/hostnames>
If set, only connects from these addresses are allowed. This is to If set, only connects from these addresses are allowed. This is to
"simulate" a little bit of security. "simulate" a little bit of security.
- Rudi Sat Jan 19 18:04:12 MET 2008
- FHT: multiple commands
Up to 8 commands in one set, these are transmitted at once to the FHT
- softbuffer changes
minfhtbuffer attribute, as otherwise nearly everything will be sent to
the FHT buffer, so ordering won't take effect.
- cmd rename
repeat1,repeat2. refreshvalues changed to refresh and init. refreshvalues
won't be advertized but still replaced to "refresh 255 init 255"
- extensive documentation update for the FHT

View File

@@ -448,22 +448,34 @@ split in multiple lines<br><br>
time.</li><br> time.</li><br>
<a name="fhtsoftbuffer"></a> <a name="fhtsoftbuffer"></a>
<li>fhtsoftbuffer<br /> <li>fhtsoftbuffer<br/>
Can be applied to FHZ devices.<br /> Can be applied to FHZ devices.<br/>
As the FHZ command buffer for FHT devices is limited, and commands As the FHZ command buffer for FHT devices is limited (see fhtbuf),
are only sent to the FHT devices every 150 seconds, the hardware and commands are only sent to the FHT device every 120 seconds,
buffer may overflow and FHT commands get lost. Setting this attribute the hardware buffer may overflow and FHT commands get lost.
to 1 implements an "unlimited" software buffer<br> Setting this attribute implements an "unlimited" software buffer<br>
Default is disabled (i.e. not set or set to 0).</li><br> Default is disabled (i.e. not set or set to 0).</li><br>
<a name="retrycount"></a> <a name="retrycount"></a>
<li>retrycount<br /> <li>retrycount<br/>
Can be applied to FHT devices.<br /> Can be applied to FHT devices.<br/>
If the <a href="#fhtsoftbuffer">fhtsoftbuffer</a> attribute is set, then If the <a href="#fhtsoftbuffer">fhtsoftbuffer</a> attribute is set, then
resend commands <code>retrycount</code> times if after 240 seconds resend commands <code>retrycount</code> times if after 240 seconds
no confirmation message is rececived from the corresponding FHT no confirmation message is rececived from the corresponding FHT
device.<br> device.<br>
Default is 3.</li><br> Default is 3.</li><br>
<a name="minfhtbuffer"></a>
<li>minfhtbuffer<br/>
Can be applied to FHT devices.<br/>
FHEM wont send commands to the FHZ if its fhtbuffer is below
this value, default is 0. If this value is low, then the ordering of
fht commands (see the note in the FHT section of <a href="#set">set</a>)
has little effect, as only commands in the softbuffer can be
prioritized. The maximum value should be 7 below the hardware maximum
(see fhtbuf).
</li><br>
</li> </li>
</ul> </ul>
@@ -472,11 +484,11 @@ split in multiple lines<br><br>
<code>attr global verbose 3</code><br> <code>attr global verbose 3</code><br>
<code>attr lamp room kitchen</code><br> <code>attr lamp room kitchen</code><br>
<code>attr lamp dummy</code><br> <code>attr lamp dummy</code><br>
<code>attr lamp loglevel 6</code><br /> <code>attr lamp loglevel 6</code><br/>
<br> <br>
<code>attr FHZ fhtsoftbuffer 0 # disable the fhtsoftbuffer for FHT devices</code><br /> <code>attr FHZ fhtsoftbuffer 0 # disable the fhtsoftbuffer</code><br/>
<code>attr FHZ softrepeat 300 # resend failed commands to FHT devices after 300 seconds </code><br /> <code>attr FHZ retrycount 4 # resend commands to FHT devices at most 4 times.</code>
<code>attr FHZ softmaxretry 4 # stop resending failed commands to FHT devices after 4 retries.</code> </ul> </ul>
<br> <br>
Notes:<br> Notes:<br>
@@ -617,7 +629,7 @@ split in multiple lines<br><br>
<code>define wz FHT 3232</code><br> <code>define wz FHT 3232</code><br>
</ul> </ul>
<br> <br>
See the section <a href="#set">set</a> for more. See the FHT section in <a href="#set">set</a> for more.
</ul> </ul>
<br> <br>
@@ -1229,11 +1241,17 @@ split in multiple lines<br><br>
<li>The answer for a command is also displayed by <code>list FHZ</code> <li>The answer for a command is also displayed by <code>list FHZ</code>
</li> </li>
<li> <li>
The FHZ1000PC has a message buffer for the FHT, as it The FHZ1x00PC has a message buffer for the FHT (see the FHT entry in
only can send messages to it every 2 (or so) minutes. If the buffer the <a href="#set">set</a> section). If the buffer is full, then newly
is full, then newly issued ones will be dropped. <code>fhtbuf</code> issued commands will be dropped, if the attribute <a
returns the free memory in this buffer (in hex), my maximum is 2c (42 href="#fhtsoftbuffer">fhtsoftbuffer</a> is not set.
bytes).</code></li> <code>fhtbuf</code> returns the free memory in this buffer (in hex),
an empty buffer in the FHZ1000 is 2c (42 bytes), in the FHZ1300 is 4a
(74 bytes). A message occupies 3 + 2x(number of FHT commands) bytes,
this is the second reason why sending multiple FHT commands with one
<a href="#set"> set</a> is a good idea. The first reason is, that
these FHT commands are sent at once to the FHT.
</li>
</ul> </ul>
</ul> </ul>
@@ -1395,8 +1413,8 @@ split in multiple lines<br><br>
2006-11-02 04:13:27 wed-from1 06:00 2006-11-02 04:13:27 wed-from1 06:00
2006-11-02 04:13:28 wed-to1 23:00 2006-11-02 04:13:28 wed-to1 23:00
2006-11-02 04:13:36 windowopen-temp 12.0 (Celsius) 2006-11-02 04:13:36 windowopen-temp 12.0 (Celsius)
Send buffer:<br /> 2007-10-19 00:31:24 desired-temp 22.5 Send buffer:<br/> 2007-10-19 00:31:24 desired-temp 22.5
2007-10-19 00:33:20 mode auto<br /> 2007-10-19 00:33:20 mode auto<br/>
</code></pre> </code></pre>
</ul> </ul>
@@ -1617,56 +1635,73 @@ Send buffer:<br /> 2007-10-19 00:31:24 desired-temp 22.5
<br><br> <br><br>
where <code>value</code> is one of:<br> where <code>value</code> is one of:<br>
<pre> <pre>
mon-from1
mon-to1
mon-from2
mon-to2
tue-from1
tue-to1
tue-from2
tue-to2
wed-from1
wed-to1
wed-from2
wed-to2
thu-from1
thu-to1
thu-from2
thu-to2
fri-from1
fri-to1
fri-from2
fri-to2
sat-from1
sat-to1
sat-from2
sat-to2
sun-from1
sun-to1
sun-from2
sun-to2
mode
holiday1
holiday2
desired-temp desired-temp
day-temp day-temp night-temp
night-temp refresh
year init
month mode
day holiday1 holiday2 # Not verified
hour manu-temp # No clue what it does.
minute year month day hour minute
refreshvalues lowtemp-offset # Alarm-Temp.-Differenz
lowtemp-offset windowopen-temp
mon-from1 mon-to1 mon-from2 mon-to2
tue-from1 tue-to1 tue-from2 tue-to2
wed-from1 wed-to1 wed-from2 wed-to2
thu-from1 thu-to1 thu-from2 thu-to2
fri-from1 fri-to1 fri-from2 fri-to2
sat-from1 sat-to1 sat-from2 sat-to2
sun-from1 sun-to1 sun-from2 sun-to2
</pre> </pre>
Examples:
<ul>
<code>set wz desired-temp 22.5</code><br>
<code>set fl desired-temp 20.5 day-temp 19.0 night-temp 16.0</code><br>
</ul>
<br>
Notes: Notes:
<ul> <ul>
<li>Following events are reported (more or less regularly) from each FHT
device: <code>measured-temp actuator lime-protection synctime
actuator1...actuator8 warnings</code><br>
You can use these strings for <a href="#notify">notify</a> or
<a href="#FileLog">FileLog</a> definitions.
<ul>
<li>actuator is only sent, if it one of them is open
(normally not during the summer time).</li>
<li>actuator1..actuator8 is only sent, if the actuator offset
for this actuator is not 0</li>
<li>lime-protection is sent when the lime-protection is running.
</li>
<li>I don't know when the synctime is sent.
</li>
<li>warnings can contain following strings:
none, Battery low,Temperature too low, Window open,
Fault on window sensor
</li>
</ul>
<br>
<li>The FHT is very economical (or lazy), it accepts one message from the
FHZ1x00 every 2 minutes (or so). Don't be surprized if your command
is only accepted 10 minutes later by the device. FHT commands are
buffered in the FHZ1x00 till they are sent to the FHT, see the related
<code>fhtbuf</code> entry in the <code><a href="#get">get</a></code>
section.<br>
You can send up to 8 commands in one message at once to the FHT if
you specify them all as arguments to the same set command, see the
example above.<br><br>
<li>All <code>*-temp</code> values need a temperature <li>All <code>*-temp</code> values need a temperature
as argument, which will be rounded to 0.5 Celsius.<br /> as argument, which will be rounded to 0.5 Celsius.<br/>
Temperature values Temperature values must between 5.5 and 30.5 Celsius. Value 5.5 set
must between 5.5 and 30.5 Celsius. Value 5.5 set the actuator to OFF, value 30.5 set the actuator to ON </li> the actuator to OFF, value 30.5 set the actuator to ON<br><br>
<li><code>mode</code> is one of <code>auto, manual, holiday or <li><code>mode</code> is one of <code>auto, manual, holiday or
holiday_short.<br>If the mode is holiday, then holiday_short.</code><br>
If the mode is holiday, then
<ul> <ul>
<li>holiday1 sets the end-day of the holiday</li> <li>holiday1 sets the end-day of the holiday</li>
<li>holiday2 sets the end-month of the holiday</li> <li>holiday2 sets the end-month of the holiday</li>
@@ -1676,30 +1711,50 @@ must between 5.5 and 30.5 Celsius. Value 5.5 set the actuator to OFF, value 30.
<li>holiday1 sets the time, in 10-minute steps</li> <li>holiday1 sets the time, in 10-minute steps</li>
<li>holiday2 sets number of days from now on.</li> <li>holiday2 sets number of days from now on.</li>
</ul> </ul>
</li> <br>
<li>The <code>*-from1/*-from2/*-to1/*-to2</code> valuetypes need a time <li>The <code>*-from1/*-from2/*-to1/*-to2</code> valuetypes need a time
spec as argument in the HH:MM format. They define the periods, where spec as argument in the HH:MM format. They define the periods, where
the day-temp is valid. The minute (MM) will be rounded to 10, and the day-temp is valid. The minute (MM) will be rounded to 10, and
24:00 means off.</li> 24:00 means off.
<li><code>refreshvalues</code> does not need an argument, but sends a <br><br>
plea to the FHT device, so it may send its parameters. If you want
to get these values regularly, then schedule:<br> <li>The <code>refresh</code> parameter should be 255. It requests
<code>at +*01:00:00 set &lt;name&gt; refreshvalues</code></li> the FHT to resend all parameter values. As the FHT stops sending
the values every 5-10 days, it is adviseable to schedule following
command regularly:<br>
<code>define fht_refresh at +*06:00:00
set &lt;name&gt; refresh 255 init 255</code>
<br>
For the technically inclined: The argument 240 (0xf0) requests the
actuator, fri,sat,sun,measured-temp and warnings values, the argument
15 (0x0f) the actuator,mon,tue,wed and thu values and all other
arguments does not seem to work.
<br><br>
<li><code>lowtemp-offset</code> need a temperature <li><code>lowtemp-offset</code> need a temperature
as argument, which will be rounded to 1.0 Celsius.<br /> as argument, which will be rounded to 1.0 Celsius.<br/>
Temperature values must between 1.0 and 5.0 Celsius.<br /> Temperature values must between 1.0 and 5.0 Celsius.<br/>
The The <code>lowtemp-offset</code> is used for temperature warning
<code>lowtemp-offset</code> is used for temperature warning (to low temperature in a room within more than 1,5 hours after the last desired-temp changing). The low temperatur warning it relates to the actual desired temperature.<br> (to low temperature in a room within more than 1,5 hours after the
</li> last desired-temp changing). The low temperatur warning it relates to
<li>The FHT is very economical (or lazy), it receives messages from the the actual desired temperature.
FHZ1x00 every 2 minutes (or so). Don't be surprized if your command <br><br>
is accepted 10 minutes later by the device. See the related
<code>fhtbuf</code> entry in the <code><a href="#get">get</a></code> <li>FHEM optionally has an internal software buffer for FHT devices.
section.<br /> This buffer should prevent transmission errors. If there is no
<li>For FHT devices, FHEM have an internal software buffer for sending commands step by step. This buffer should prevent lost commands. In case of transmission failures FHEM tries to resend commands. You can see the queued unsent and the failed commands with the <a href="#list">list</a> command. If a command don't picked up from a FHT device within a <a href="#softrepeat">given time</a>, the command sends again until <a href="#softmaxretry">softmaxretry</a> reached. <br /> confirmation for a given period, FHEM resends the command. You can
<li>To prevent long time waiting for sending important command, there is a priority list. Commands send in this importance:<br /> see the queued commands with <a href="#list">list</a>
<code>desired-temp, mode, refreshvalues,holiday1,holiday2,day-temp,night-temp, [all other commands]</code> <br /> &lt;fht-device&gt;.
<br /> See the <a href="#fhtsoftbuffer">fhtsoftbuffer</a>,
<a href="#retrycount">retrycount</a> and
<a href="#minfhtbuffer">minfhtbuffer</a> attributes for details.
<br><br>
<li>If a buffer is still in the softbuffer, it will be sent in the
following order:<br/> <code>desired-temp,mode,refresh,holiday1,holiday2,day-temp,night-temp, [all other commands]</code>
<br><br>
</ul> </ul>
</ul> </ul>

View File

@@ -138,7 +138,7 @@ my %intAt; # Internal at timer hash.
my $intAtCnt=0; my $intAtCnt=0;
my $reread_active = 0; my $reread_active = 0;
my $AttrList = "room comment"; my $AttrList = "room comment";
my $cvsid = '$Id: fhem.pl,v 1.37 2008-01-08 20:15:58 rudolfkoenig Exp $'; my $cvsid = '$Id: fhem.pl,v 1.38 2008-01-19 19:02:30 rudolfkoenig Exp $';
$init_done = 0; $init_done = 0;
@@ -1388,11 +1388,11 @@ CommandAttr($$)
{ {
my ($cl, $param) = @_; my ($cl, $param) = @_;
my $ret = undef; my $ret = undef;
my @a;
@a = split(" ", $param, 3) if($param);
my @a = split(" ", $param, 3);
return "Usage: attr <name> <attrname> [<attrvalue>]\n" . return "Usage: attr <name> <attrname> [<attrvalue>]\n" .
"$namedef" if(@a < 2); "$namedef" if(@a && @a < 2);
my @rets; my @rets;
foreach my $sdev (devspec2array($a[0])) { foreach my $sdev (devspec2array($a[0])) {