mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-23 14:46:24 +00:00
00_OW2S0SMSGUARD.pm:add crc check
git-svn-id: https://svn.fhem.de/fhem/trunk@23686 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
26f0fc0411
commit
3976c6a193
@ -201,7 +201,7 @@ sub AttrFn {
|
|||||||
if ($cmd eq 'del') {
|
if ($cmd eq 'del') {
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
$hash->{INTERVAL} = 0 if ($attrName eq 'interval');
|
$hash->{INTERVAL} = 0 if ($attrName eq 'interval');
|
||||||
InternalTimer(gettimeofday()+1, "FHEM::OW2S0SMSGUARD::GetUpdate", $hash, 0) if ($attrName eq 'disable');
|
InternalTimer(gettimeofday()+1, 'FHEM::OW2S0SMSGUARD::GetUpdate', $hash, 0) if ($attrName eq 'disable');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cmd eq 'set') {
|
if ($cmd eq 'set') {
|
||||||
@ -209,7 +209,7 @@ sub AttrFn {
|
|||||||
return "invalid value " if (int($attrVal) < 0);
|
return "invalid value " if (int($attrVal) < 0);
|
||||||
$hash->{INTERVAL} = int($attrVal);
|
$hash->{INTERVAL} = int($attrVal);
|
||||||
|
|
||||||
InternalTimer(gettimeofday()+1, "FHEM::OW2S0SMSGUARD::GetUpdate", $hash, 0) if ($hash->{INTERVAL});
|
InternalTimer(gettimeofday()+1, 'FHEM::OW2S0SMSGUARD::GetUpdate', $hash, 0) if ($hash->{INTERVAL});
|
||||||
readingsSingleUpdate($hash, 'state', 'disabled', 1) if (!$hash->{INTERVAL});
|
readingsSingleUpdate($hash, 'state', 'disabled', 1) if (!$hash->{INTERVAL});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +222,7 @@ sub AttrFn {
|
|||||||
}
|
}
|
||||||
if (int($attrVal) == 0) {
|
if (int($attrVal) == 0) {
|
||||||
$hash->{INTERVAL} = AttrNum($name, 'interval', 30);
|
$hash->{INTERVAL} = AttrNum($name, 'interval', 30);
|
||||||
InternalTimer(gettimeofday()+1, "FHEM::OW2S0SMSGUARD::GetUpdate", $hash, 0) if ($hash->{INTERVAL});
|
InternalTimer(gettimeofday()+1, 'FHEM::OW2S0SMSGUARD::GetUpdate', $hash, 0) if ($hash->{INTERVAL});
|
||||||
DevIo_CloseDev($hash);
|
DevIo_CloseDev($hash);
|
||||||
DevIo_OpenDev($hash, 1, \&DoInit) if ($hash->{INTERVAL}); #$hash, $reopen, $initfn, $callback
|
DevIo_OpenDev($hash, 1, \&DoInit) if ($hash->{INTERVAL}); #$hash, $reopen, $initfn, $callback
|
||||||
}
|
}
|
||||||
@ -274,18 +274,17 @@ sub read_OW {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
|
|
||||||
sub SetFn {
|
sub SetFn {
|
||||||
|
|
||||||
my $hash = shift;
|
my $hash = shift // return;
|
||||||
return if ($hash->{addr} ne 'master');
|
my $name = shift // return;
|
||||||
|
|
||||||
my $name = shift;
|
|
||||||
my $cmd = shift // '?';
|
my $cmd = shift // '?';
|
||||||
my $val = shift // .5;
|
my $val = shift // .5;
|
||||||
|
|
||||||
|
return if ($hash->{addr} ne 'master');
|
||||||
|
|
||||||
if ($cmd eq 'reset') {
|
if ($cmd eq 'reset') {
|
||||||
DevIo_CloseDev($hash);
|
DevIo_CloseDev($hash);
|
||||||
return DevIo_OpenDev($hash, 1, \&DoInit);
|
return DevIo_OpenDev($hash, 1, \&DoInit);
|
||||||
@ -294,7 +293,7 @@ sub SetFn {
|
|||||||
return SimpleWrite($hash, '$rez') if ($cmd eq 'S0-reset');
|
return SimpleWrite($hash, '$rez') if ($cmd eq 'S0-reset');
|
||||||
|
|
||||||
if ($cmd eq 'delay') {
|
if ($cmd eq 'delay') {
|
||||||
$hash->{DELAY} = $val;
|
$hash->{DELAY} = $val if (looks_like_number($val));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,12 +304,11 @@ sub SetFn {
|
|||||||
|
|
||||||
sub GetFn {
|
sub GetFn {
|
||||||
|
|
||||||
my $hash = shift;
|
my $hash = shift // return;
|
||||||
return if ($hash->{addr} ne 'master');
|
my $name = shift // return;
|
||||||
|
|
||||||
my $name = shift;
|
|
||||||
my $cmd = shift // '?';
|
my $cmd = shift // '?';
|
||||||
my $device = shift // 0;
|
|
||||||
|
return if ($hash->{addr} ne 'master');
|
||||||
|
|
||||||
if ($cmd eq 'OWdevicelist') {
|
if ($cmd eq 'OWdevicelist') {
|
||||||
my @devs;
|
my @devs;
|
||||||
@ -326,7 +324,7 @@ sub GetFn {
|
|||||||
|
|
||||||
sub formatOWList {
|
sub formatOWList {
|
||||||
|
|
||||||
my (@devs) = @_;
|
my @devs = @_;
|
||||||
|
|
||||||
# Type | Address | Name | Time
|
# Type | Address | Name | Time
|
||||||
# -------+------------------+--------+--------------------
|
# -------+------------------+--------+--------------------
|
||||||
@ -424,7 +422,7 @@ sub Parse {
|
|||||||
my @data = split(';', $rmsg);
|
my @data = split(';', $rmsg);
|
||||||
|
|
||||||
if (int(@data) < 3) {
|
if (int(@data) < 3) {
|
||||||
$txt = 'message is too short ['.int(@data).']';
|
$txt = 'message is too short -> '.int(@data);
|
||||||
Log3($name, 3, "$name, $txt");
|
Log3($name, 3, "$name, $txt");
|
||||||
readingsSingleUpdate($hash, 'error', $txt, 1);
|
readingsSingleUpdate($hash, 'error', $txt, 1);
|
||||||
return;
|
return;
|
||||||
@ -439,30 +437,69 @@ sub Parse {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $ok = (defined($data[1]) && ($data[1] eq 'o')) ? 1 : 0;
|
|
||||||
my $temp = '';
|
|
||||||
my $num = int($data[0]);
|
my $num = int($data[0]);
|
||||||
|
|
||||||
if ($num > 63) {
|
if (($num > 63) | ($num < 0)) {
|
||||||
$txt = "invalid OW number $num";
|
$txt = "invalid OW number $num";
|
||||||
Log3($name, 3, "$name, $txt");
|
Log3($name, 3, "$name, $txt");
|
||||||
readingsSingleUpdate($hash, 'error', $txt, 1);
|
readingsSingleUpdate($hash, 'error', $txt, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defined($data[2]) && (length($data[2]) == 16) && ( $data[2] =~ m{ [0-9A-F]+ }x )) {
|
my $ok = (defined($data[1]) && ($data[1] eq 'o')) ? 1 : 0;
|
||||||
delete $hash->{helper}{$num};
|
|
||||||
|
|
||||||
my $model = int(substr($data[2],0,2));
|
return decodeList($hash, $name, $num, $ok, @data) if (defined($data[2]) && (length($data[2]) == 16) && ( $data[2] =~ m{ [0-9A-F]+ }x ));
|
||||||
$model = -1 if (!$model || ($model > 28) );
|
return decodeVal($hash, $name, $num, @data) if ($ok && defined($data[11]) && exists($hash->{helper}{$num}));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
|
||||||
|
sub decodeList {
|
||||||
|
|
||||||
|
my ($hash, $name, $num, $ok, @data) = @_;
|
||||||
|
my $error;
|
||||||
|
|
||||||
|
delete $hash->{helper}{$num};
|
||||||
|
|
||||||
$hash->{helper}{$num}{state} = $ok;
|
$hash->{helper}{$num}{state} = $ok;
|
||||||
$hash->{helper}{$num}{time} = TimeNow();
|
$hash->{helper}{$num}{time} = TimeNow();
|
||||||
$hash->{helper}{$num}{addr} = $data[2];
|
$hash->{helper}{$num}{addr} = $data[2];
|
||||||
$hash->{helper}{$num}{fam} = $model;
|
|
||||||
$hash->{'OW-Dev'.$num} = $hash->{helper}{$num}{addr}." => $ok";
|
$hash->{'OW-Dev'.$num} = $hash->{helper}{$num}{addr}." => $ok";
|
||||||
$hash->{OWDEVICES} = ($num + 1);
|
$hash->{OWDEVICES} = ($num + 1);
|
||||||
|
|
||||||
|
if (!$ok) {
|
||||||
|
$error = "got NOK for OW device $num [".$data[2].']';
|
||||||
|
Log3($name, 3, "$name, $error");
|
||||||
|
readingsSingleUpdate($hash, 'error', $error, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $model = int(substr($data[2],0,2));
|
||||||
|
my $owid = substr($data[2],0,14);
|
||||||
|
my $owcrc = substr($data[2],14,2);
|
||||||
|
my $crc = 0;
|
||||||
|
|
||||||
|
for my $i (0,2,4,6,8,10,12) { # die ersten 7 Byte
|
||||||
|
my $byte = substr($owid, $i , 2);
|
||||||
|
for (my $bit=1; $bit<256; $bit=$bit*2) {
|
||||||
|
my $cbit = ((hex($byte) & $bit) == $bit) ? 1 : 0;
|
||||||
|
$crc= (($crc & 1) != $cbit) ? ($crc >> 1)^0x8c : $crc >> 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($crc != hex($owcrc)) {
|
||||||
|
$error = "CRC error OW device $num [$data[2]] : $owcrc != ". sprintf('%02x', $crc);
|
||||||
|
Log3($name, 3, "$name, $error");
|
||||||
|
readingsSingleUpdate($hash, 'error', $error, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$model = -1 if (!$model || ($model > 28) );
|
||||||
|
|
||||||
|
$hash->{helper}{$num}{fam} = $model;
|
||||||
|
|
||||||
if ($num == 0) {
|
if ($num == 0) {
|
||||||
for my $i (1..63) {delete $hash->{'OW-Dev'.$i} if (exists($hash->{'OW-Dev'.$i})); }
|
for my $i (1..63) {delete $hash->{'OW-Dev'.$i} if (exists($hash->{'OW-Dev'.$i})); }
|
||||||
}
|
}
|
||||||
@ -482,9 +519,9 @@ sub Parse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!defined($hash->{helper}{$num}{typ})) {
|
if (!defined($hash->{helper}{$num}{typ})) {
|
||||||
$txt = "unknown OW type, address $data[2]";
|
$error = "unknown OW type, address $data[2]";
|
||||||
Log3($name, 3, "$name, $txt");
|
Log3($name, 3, "$name, $error");
|
||||||
readingsSingleUpdate($hash, 'error', $txt, 1);
|
readingsSingleUpdate($hash, 'error', $error, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,17 +529,24 @@ sub Parse {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($ok && defined($data[11]) && exists($hash->{helper}{$num})) {
|
sub decodeVal {
|
||||||
|
|
||||||
|
my ($hash, $name, $num, @data) = @_;
|
||||||
|
my $error;
|
||||||
|
my $crc;
|
||||||
|
|
||||||
# das 10.Byte ist eine Checksumme für die serielle Übertragung
|
# das 10.Byte ist eine Checksumme für die serielle Übertragung
|
||||||
my $crc;
|
|
||||||
for my $i (2..10) { $crc += hex('0x'.$data[$i]); }
|
|
||||||
$crc = $crc & 0xFF;
|
|
||||||
|
|
||||||
if ($crc != hex('0x'.$data[11])) {
|
for my $i (2..10) {
|
||||||
$txt = "CRC error OW device $num : ".$data[11]. ' != '. sprintf('%02x', $crc);
|
$crc += hex($data[$i]) if (($data[$i] =~ m{ [0-9A-F]+ }x) && (length($data[$i]) == 2)) ;
|
||||||
Log3($name, 3, "$name, $txt");
|
}
|
||||||
readingsSingleUpdate($hash, 'error', $txt, 1);
|
$crc = $crc & 0xFF;
|
||||||
|
$data[11] = (($data[11] =~ m{ [0-9A-F]+ }x) && (length($data[11]) == 2)) ? hex($data[11]) : -1; # das CRC Byte selbst ist ungültig
|
||||||
|
|
||||||
|
if ($crc != $data[11]) {
|
||||||
|
$error = "CRC error OW device $num : $data[11] != $crc";
|
||||||
|
Log3($name, 3, "$name, $error");
|
||||||
|
readingsSingleUpdate($hash, 'error', $error, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -512,12 +556,12 @@ sub Parse {
|
|||||||
my $model = $hash->{helper}{$num}{typ};
|
my $model = $hash->{helper}{$num}{typ};
|
||||||
$hash->{helper}{$num}{raw} = join(' ' , @data);
|
$hash->{helper}{$num}{raw} = join(' ' , @data);
|
||||||
|
|
||||||
$temp = decodeTemperature($model, @data);
|
my $temp = decodeTemperature($model, @data);
|
||||||
|
|
||||||
if ($temp eq '') {
|
if ($temp eq '') {
|
||||||
$txt = "unable to decode data $hash->{helper}{$num}{raw} for model $model";
|
$error = "unable to decode data $hash->{helper}{$num}{raw} for model $model";
|
||||||
Log3($name, 3, "$name, $txt");
|
Log3($name, 3, "$name, $error");
|
||||||
readingsSingleUpdate($hash, 'error', $txt, 1);
|
readingsSingleUpdate($hash, 'error', $error, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,27 +574,23 @@ sub Parse {
|
|||||||
|
|
||||||
readingsSingleUpdate($hash, $hash->{helper}{$num}{name}, $temp, 0);
|
readingsSingleUpdate($hash, $hash->{helper}{$num}{name}, $temp, 0);
|
||||||
Dispatch($hash, "OW,$hash->{helper}{$num}{addr},$model,$temp,$num");
|
Dispatch($hash, "OW,$hash->{helper}{$num}{addr},$model,$temp,$num");
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#####################################
|
|
||||||
|
|
||||||
sub decodeTemperature {
|
sub decodeTemperature {
|
||||||
|
|
||||||
my ($model, @data) = @_;
|
my ($model, @data) = @_;
|
||||||
my $temp = '';
|
my $temp = '';
|
||||||
|
|
||||||
if ($model eq 'DS1820') {
|
if ($model eq 'DS1820') {
|
||||||
$temp = (( hex('0x'.$data[1]) << 8) + hex('0x'.$data[0])) << 3;
|
$temp = (( hex($data[1]) << 8) + hex($data[0])) << 3;
|
||||||
$temp = ($temp & 0xFFF0) +12 - hex('0x'.$data[6]) if ($data[7] eq '10');
|
$temp = ($temp & 0xFFF0) +12 - hex($data[6]) if ($data[7] eq '10');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($model eq 'DS18B20') || ($model eq 'DS1822')) {
|
if (($model eq 'DS18B20') || ($model eq 'DS1822')) {
|
||||||
$temp = (( hex('0x'.$data[1]) << 8) + hex('0x'.$data[0]));
|
$temp = (( hex($data[1]) << 8) + hex($data[0]));
|
||||||
|
|
||||||
my $cfg = (hex('0x'.$data[4]) & 0x60);
|
my $cfg = (hex($data[4]) & 0x60);
|
||||||
$temp = $temp << 3 if ($cfg == 0);
|
$temp = $temp << 3 if ($cfg == 0);
|
||||||
$temp = $temp << 2 if ($cfg == 0x20);
|
$temp = $temp << 2 if ($cfg == 0x20);
|
||||||
$temp = $temp << 1 if ($cfg == 0x40);
|
$temp = $temp << 1 if ($cfg == 0x40);
|
||||||
@ -558,7 +598,7 @@ sub decodeTemperature {
|
|||||||
|
|
||||||
if ($temp) {
|
if ($temp) {
|
||||||
$temp = $temp/16.0;
|
$temp = $temp/16.0;
|
||||||
$temp -= 4096 if (hex('0x'.$data[1]) > 127);
|
$temp -= 4096 if (hex($data[1]) > 127);
|
||||||
$temp = sprintf('%.1f', $temp);
|
$temp = sprintf('%.1f', $temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user