2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-16 10:46:03 +00:00

KM271: Bugfix for multiple KM271 instances. Moved timerprogram hash from class to instance variable.

git-svn-id: https://svn.fhem.de/fhem/trunk@8000 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
physikus 2015-02-15 19:10:54 +00:00
parent 459d46bf20
commit f06f7172d3

View File

@ -284,9 +284,6 @@ my %km271_set_day = (
"so" => 0xc0, "so" => 0xc0,
); );
# Internal hash for storing actual timing parameter of heater, populated by "logmode" command
my %km271_timer;
##################################### #####################################
sub sub
KM271_Initialize($) KM271_Initialize($)
@ -302,9 +299,7 @@ KM271_Initialize($)
$hash->{UndefFn} = "KM271_Undef"; $hash->{UndefFn} = "KM271_Undef";
$hash->{SetFn} = "KM271_Set"; $hash->{SetFn} = "KM271_Set";
$hash->{AttrFn} = "KM271_Attr"; $hash->{AttrFn} = "KM271_Attr";
$hash->{AttrList}= "do_not_notify:1,0 all_km271_events loglevel:0,1,2,3,4,5,6 ww_timermode:automatik,tag readingsFilter"; $hash->{AttrList}= "do_not_notify:1,0 loglevel:0,1,2,3,4,5,6 all_km271_events ww_timermode:automatik,tag readingsFilter $readingFnAttributes";
my @a = ();
$hash->{SENDBUFFER} = \@a;
%km271_rev = (); %km271_rev = ();
foreach my $k (sort keys %km271_tr) { # Reverse map foreach my $k (sort keys %km271_tr) { # Reverse map
@ -334,7 +329,13 @@ KM271_Define($$)
} }
$hash->{DeviceName} = $dev; $hash->{DeviceName} = $dev;
my $ret = DevIo_OpenDev($hash, 0, "KM271_DoInit"); my @a = ();
$hash->{SENDBUFFER} = \@a;
# Internal hash for storing actual timing parameter of heater, populated by "logmode" command
my %b = ();
$hash->{PRG_TIMER} = \%b;
my $ret = DevIo_OpenDev($hash, 0, "KM271_DoInit");
return $ret; return $ret;
} }
@ -445,64 +446,66 @@ KM271_Set($@)
return "On- and off timepoints must not be identical" if(substr($val, 2, 2) eq substr($offval, 2, 2) && $onday == $offday); return "On- and off timepoints must not be identical" if(substr($val, 2, 2) eq substr($offval, 2, 2) && $onday == $offday);
} }
# Calculate offsets for command and internal timer hash # Calculate offsets for command and internal timer hash
my $km271Timer = $hash->{PRG_TIMER};
my $offset = int(($pos*2 + 1)/3)*7; my $offset = int(($pos*2 + 1)/3)*7;
my $keyoffset = $offset + ($a[1] =~ m/^hk1/ ? 0 : 15)*7; my $keyoffset = $offset + ($a[1] =~ m/^hk1/ ? 0 : 15)*7;
my $key = sprintf("01%02x", $keyoffset); my $key = sprintf("01%02x", $keyoffset);
# Are two updates needed (interval is spread over two lines)? # Are two updates needed (interval is spread over two lines)?
if (($pos + 1) % 3 == 0) { if (($pos + 1) % 3 == 0) {
my $key2 = sprintf("01%02x", $keyoffset + 7); my $key2 = sprintf("01%02x", $keyoffset + 7);
return "Internal timer-hash is not populated, use logmode command and try again later" return "Internal timer-hash is not populated, use logmode command and try again later"
if (!defined($km271_timer{$key}{0}) || !defined($km271_timer{$key}{1}) || !defined($km271_timer{$key2}{1}) || !defined($km271_timer{$key2}{2})); if (!defined($km271Timer->{$key}{0}) || !defined($km271Timer->{$key}{1}) || !defined($km271Timer->{$key2}{1}) || !defined($km271Timer->{$key2}{2}));
# Check if update for key2 is needed # Check if update for key2 is needed
if (defined($km271_timer{$key2}{0}) && $km271_timer{$key2}{0} eq $offval) { if (defined($km271Timer->{$key2}{0}) && $km271Timer->{$key2}{0} eq $offval) {
Log 4, "$name: Update for second timer-part not needed"; Log 4, "$name: Update for second timer-part not needed";
} else { } else {
# Update internal hash # Update internal hash
$km271_timer{$key2}{0} = $offval; $km271Timer->{$key2}{0} = $offval;
$offval .= $km271_timer{$key2}{1} . $km271_timer{$key2}{2}; $offval .= $km271Timer->{$key2}{1} . $km271Timer->{$key2}{2};
# Dirty trick: Changes of the timer are not notified by the heater, so internal notification is added after the colon # Dirty trick: Changes of the timer are not notified by the heater, so internal notification is added after the colon
$offval = sprintf("%02x%s:%s%s", $offset + 7, $offval, $key2, $offval); $offval = sprintf("%02x%s:%s%s", $offset + 7, $offval, $key2, $offval);
# Push first command # Push first command
push @{$hash->{SENDBUFFER}}, sprintf($fmt, $offval); push @{$hash->{SENDBUFFER}}, sprintf($fmt, $offval);
} }
# Check if update for key is needed # Check if update for key is needed
if (defined($km271_timer{$key}{2}) && $km271_timer{$key}{2} eq $val) { if (defined($km271Timer->{$key}{2}) && $km271Timer->{$key}{2} eq $val) {
Log 4, "$name: Update for first timer-part not needed"; Log 4, "$name: Update for first timer-part not needed";
goto END_SET; goto END_SET;
} else { } else {
# Update internal hash # Update internal hash
$km271_timer{$key}{2} = $val; $km271Timer->{$key}{2} = $val;
} }
} else { } else {
# Only one update needed # Only one update needed
if ($pos % 3 == 1) { if ($pos % 3 == 1) {
return "Internal timer-hash is not populated, use logmode command and try again later" if (!defined($km271_timer{$key}{2})); return "Internal timer-hash is not populated, use logmode command and try again later" if (!defined($km271Timer->{$key}{2}));
# Check if update for key is needed # Check if update for key is needed
if (defined($km271_timer{$key}{0}) && defined($km271_timer{$key}{1}) && $km271_timer{$key}{0} eq $val && $km271_timer{$key}{1} eq $offval) { if (defined($km271Timer->{$key}{0}) && defined($km271Timer->{$key}{1}) && $km271Timer->{$key}{0} eq $val && $km271Timer->{$key}{1} eq $offval) {
Log 4, "$name: Update for timer not needed"; Log 4, "$name: Update for timer not needed";
goto END_SET; goto END_SET;
} else { } else {
# Update internal hash # Update internal hash
$km271_timer{$key}{0} = $val; $km271Timer->{$key}{0} = $val;
$km271_timer{$key}{1} = $offval; $km271Timer->{$key}{1} = $offval;
} }
} else { } else {
return "Internal timer-hash is not populated, use logmode command and try again later" if (!defined($km271_timer{$key}{0})); return "Internal timer-hash is not populated, use logmode command and try again later" if (!defined($km271Timer->{$key}{0}));
# Check if update for key is needed # Check if update for key is needed
if (defined($km271_timer{$key}{1}) && defined($km271_timer{$key}{2}) && $km271_timer{$key}{1} eq $val && $km271_timer{$key}{2} eq $offval) { if (defined($km271Timer->{$key}{1}) && defined($km271Timer->{$key}{2}) && $km271Timer->{$key}{1} eq $val && $km271Timer->{$key}{2} eq $offval) {
Log 4, "$name: Update for timer not needed"; Log 4, "$name: Update for timer not needed";
goto END_SET; goto END_SET;
} else { } else {
# Update internal hash # Update internal hash
$km271_timer{$key}{1} = $val; $km271Timer->{$key}{1} = $val;
$km271_timer{$key}{2} = $offval; $km271Timer->{$key}{2} = $offval;
} }
} }
} }
$val = $km271_timer{$key}{0} . $km271_timer{$key}{1} . $km271_timer{$key}{2}; $val = $km271Timer->{$key}{0} . $km271Timer->{$key}{1} . $km271Timer->{$key}{2};
# Dirty trick: Changes of the timer are not notified by the heater, so internal notification is added after the colon # Dirty trick: Changes of the timer are not notified by the heater, so internal notification is added after the colon
$val = sprintf("%02x%s:%s%s", $offset, $val, $key, $val); $val = sprintf("%02x%s:%s%s", $offset, $val, $key, $val);
} }
@ -638,6 +641,7 @@ KM271_Read($)
my $all_events = AttrVal($name, "all_km271_events", ""); my $all_events = AttrVal($name, "all_km271_events", "");
if($msghash) { if($msghash) {
my $km271Timer = $hash->{PRG_TIMER};
foreach my $off (keys %{$msghash}) { foreach my $off (keys %{$msghash}) {
my $key = $msghash->{$off}; my $key = $msghash->{$off};
@ -662,9 +666,9 @@ KM271_Read($)
, KM271_setprg(hex(substr($arg, ($off+2)*2, 2)), hex(substr($arg, ($off+3)*2, 2))) , KM271_setprg(hex(substr($arg, ($off+2)*2, 2)), hex(substr($arg, ($off+3)*2, 2)))
, KM271_setprg(hex(substr($arg, ($off+4)*2, 2)), hex(substr($arg, ($off+5)*2, 2)))); , KM271_setprg(hex(substr($arg, ($off+4)*2, 2)), hex(substr($arg, ($off+5)*2, 2))));
# Fill internal timer hash # Fill internal timer hash
$km271_timer{$fn}{0} = substr($arg, 0, 4); $km271Timer->{$fn}{0} = substr($arg, 0, 4);
$km271_timer{$fn}{1} = substr($arg, 4, 4); $km271Timer->{$fn}{1} = substr($arg, 4, 4);
$km271_timer{$fn}{2} = substr($arg, 8, 4); } $km271Timer->{$fn}{2} = substr($arg, 8, 4); }
elsif($f eq "eh") { $val = KM271_seterror($arg); } elsif($f eq "eh") { $val = KM271_seterror($arg); }
} }
$key = ucfirst($key); # Hack to match the original and the fake reading $key = ucfirst($key); # Hack to match the original and the fake reading
@ -826,7 +830,7 @@ KM271_crc($)
sub sub
KM271_SetReading($$$$) KM271_SetReading($$$$)
{ {
my ($hash,$key,$val,$ntfy) = @_; my ($hash, $key, $val, $ntfy) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $filter = AttrVal($name, 'readingsFilter', ''); my $filter = AttrVal($name, 'readingsFilter', '');
return if ($filter && $key !~ m/$filter/s); return if ($filter && $key !~ m/$filter/s);
@ -983,7 +987,7 @@ KM271_SetReading($$$$)
</li> </li>
<a name="readingsFilter"></a> <a name="readingsFilter"></a>
<li>readingsFilter<br> <li>readingsFilter<br>
Regular expression for selection of desired readings:<br> Regular expression for selection of desired readings.<br>
Only readings which will match the regular expression will be used. All other readings are Only readings which will match the regular expression will be used. All other readings are
suppressed in the device and even in the logfile. suppressed in the device and even in the logfile.
</li> </li>