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:
3
CHANGED
3
CHANGED
@@ -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
|
||||||
|
|||||||
@@ -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"));
|
||||||
|
|
||||||
|
|||||||
163
FHEM/11_FHT.pm
163
FHEM/11_FHT.pm
@@ -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";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -167,35 +169,39 @@ 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
12
HISTORY
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
desired-temp
|
||||||
mon-to1
|
day-temp night-temp
|
||||||
mon-from2
|
refresh
|
||||||
mon-to2
|
init
|
||||||
tue-from1
|
mode
|
||||||
tue-to1
|
holiday1 holiday2 # Not verified
|
||||||
tue-from2
|
manu-temp # No clue what it does.
|
||||||
tue-to2
|
year month day hour minute
|
||||||
wed-from1
|
lowtemp-offset # Alarm-Temp.-Differenz
|
||||||
wed-to1
|
windowopen-temp
|
||||||
wed-from2
|
mon-from1 mon-to1 mon-from2 mon-to2
|
||||||
wed-to2
|
tue-from1 tue-to1 tue-from2 tue-to2
|
||||||
thu-from1
|
wed-from1 wed-to1 wed-from2 wed-to2
|
||||||
thu-to1
|
thu-from1 thu-to1 thu-from2 thu-to2
|
||||||
thu-from2
|
fri-from1 fri-to1 fri-from2 fri-to2
|
||||||
thu-to2
|
sat-from1 sat-to1 sat-from2 sat-to2
|
||||||
fri-from1
|
sun-from1 sun-to1 sun-from2 sun-to2
|
||||||
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
|
|
||||||
day-temp
|
|
||||||
night-temp
|
|
||||||
year
|
|
||||||
month
|
|
||||||
day
|
|
||||||
hour
|
|
||||||
minute
|
|
||||||
refreshvalues
|
|
||||||
lowtemp-offset
|
|
||||||
</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 <name> 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 <name> 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 />
|
<fht-device>.
|
||||||
<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>
|
||||||
|
|
||||||
|
|||||||
8
fhem.pl
8
fhem.pl
@@ -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])) {
|
||||||
|
|||||||
Reference in New Issue
Block a user