2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 16:56:54 +00:00

38_CO20: identify devices by id / serial number

git-svn-id: https://svn.fhem.de/fhem/trunk@13992 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
moises 2017-04-14 17:20:59 +00:00
parent 4c0f7b6449
commit 771abe0589
2 changed files with 177 additions and 62 deletions

View File

@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it. # Do not insert empty lines here, update check depends on it.
- update: 38_CO20: identify devices by id / serial number
- update: 38_netatmo: dynamic update intervals for devices - update: 38_netatmo: dynamic update intervals for devices
- update: 98_weekprofile: update reading profile_count after save profiles - update: 98_weekprofile: update reading profile_count after save profiles
- feature: 98_weekprofile: new attribute widgetTranslations for translations - feature: 98_weekprofile: new attribute widgetTranslations for translations

View File

@ -27,8 +27,8 @@ CO20_Initialize($)
$hash->{SetFn} = "CO20_Set"; $hash->{SetFn} = "CO20_Set";
$hash->{GetFn} = "CO20_Get"; $hash->{GetFn} = "CO20_Get";
$hash->{AttrFn} = "CO20_Attr"; $hash->{AttrFn} = "CO20_Attr";
$hash->{AttrList} = "disable:1 ". $hash->{AttrList} = "disable:1,0 ".
"advanced:1 ". "advanced:1,0 ".
"interval ". "interval ".
"retries ". "retries ".
"timeout ". "timeout ".
@ -49,18 +49,35 @@ CO20_Define($$)
delete $hash->{ID}; delete $hash->{ID};
my $name = $a[0]; my $name = $a[0];
#$hash->{ID} = undef;
$hash->{SERIALNUMBER} = undef;
$hash->{helper}{defined} = "none";
$hash->{tag} = undef; if( defined($a[2]))
$hash->{ID} = $a[2] if( defined($a[2])); {
if($a[2] =~ m/(\d.*):(\d.*)/)
{
$hash->{ID} = $a[2];
$hash->{helper}{defined} = "id";
}
elsif($a[2] =~ m/(\d.*)/)
{
$hash->{SERIALNUMBER} = $a[2];
$hash->{helper}{defined} = "serial";
}
}
$hash->{NAME} = $name; $hash->{NAME} = $name;
$hash->{fail} = 0; $hash->{FAIL} = 0;
$hash->{seq2} = 0x67; $hash->{helper}{seq2} = 0x67;
$hash->{seq4} = 0x0001; $hash->{helper}{seq4} = 0x0001;
$hash->{NOTIFYDEV} = "global"; $hash->{NOTIFYDEV} = "global";
$hash->{helper}{retries} = AttrVal($name,"retries",3);
$hash->{helper}{timeout} = AttrVal($name,"timeout",1000);
if( $init_done ) { if( $init_done ) {
CO20_Disconnect($hash); CO20_Disconnect($hash);
CO20_Connect($hash); CO20_Connect($hash);
@ -148,30 +165,98 @@ CO20_Connect($)
return undef if( AttrVal($name, "disable", 0 ) == 1 ); return undef if( AttrVal($name, "disable", 0 ) == 1 );
$hash->{USB} = Device::USB->new() if( !$hash->{USB} ); Log3 $name, 5, "$name: start CO20 connect";
if( $hash->{ID} && $hash->{ID} =~ m/(\d.*):(\d.*)/ ) { delete $hash->{DEV};
Log3 $name, 5, "$name: delete CO20 dev";
$hash->{USB} = Device::USB->new() if( !$hash->{USB} );
Log3 $name, 3, "$name: CO20 USB connect";
if( $hash->{helper}{defined} eq "id" && $hash->{ID} && $hash->{ID} =~ m/(\d.*):(\d.*)/ ) {
my $dirname = $1; my $dirname = $1;
my $filename = $2; my $filename = $2;
delete $hash->{DEV}; foreach my $bus ($hash->{USB}->list_busses())
foreach my $bus ($hash->{USB}->list_busses()) { {
next if( $bus->{dirname} != $dirname ); next if( $bus->{dirname} != $dirname );
foreach my $device (@{$bus->{devices}}) { foreach my $device (@{$bus->{devices}}) {
next if( $device->idVendor() != $VENDOR ); next if( $device->idVendor() != $VENDOR );
next if( $device->idProduct() != $PRODUCT ); next if( $device->idProduct() != $PRODUCT );
next if( $device->{filename} != $filename ); next if( $device->{filename} != $filename );
Log3 $name, 5, "$name: found CO20 device with id";
$hash->{DEV} = $device; $hash->{DEV} = $device;
last; last;
} }
last if( $hash->{DEV} ); last if( $hash->{DEV} );
} }
}
elsif( $hash->{helper}{defined} eq "serial" && !$hash->{DEV} && $hash->{SERIALNUMBER} )
{
foreach my $bus ($hash->{USB}->list_busses())
{
foreach my $device (@{$bus->{devices}}) {
next if( $device->idVendor() != $VENDOR );
next if( $device->idProduct() != $PRODUCT );
$hash->{DEV} = $device;
$hash->{DEV}->open();
$hash->{manufacturer} = $hash->{DEV}->manufacturer();
$hash->{product} = $hash->{DEV}->product();
$hash->{DEV}->detach_kernel_driver_np(0) if( $hash->{DEV}->get_driver_np(0) );
my $ret = $hash->{DEV}->claim_interface( 0 );
if( $ret == -16 ) {
Log3 $name, 2, "$name: USB timeout for CO20 device on identify";
return;
} elsif( $ret != 0 ) {
Log3 $name, 2, "$name: failed to claim CO20 device on identify";
CO20_Disconnect($hash);
return;
}
Log3 $name, 5, "$name: claimed CO20 device on identify";
my $buf;
$hash->{DEV}->interrupt_read(0x00000081, $buf, 0x0000010, 1000);
Log3 $name, 5, "$name: read CO20 device on identify";
my $currentid = CO20_identify($hash);
Log3 $name, 2, "$name: found CO20 device with id $currentid while looking for ".$hash->{SERIALNUMBER};
last if($currentid eq $hash->{SERIALNUMBER});
$hash->{DEV}->release_interface(0);
Log3 $name, 5, "$name: released interface on identify";
} else { delete $hash->{DEV};
delete $hash->{manufacturer};
delete $hash->{product};
}
last if( $hash->{DEV} );
}
}
else
{
Log3 $name, 5, "$name: searching CO20 device on identify";
$hash->{DEV} = $hash->{USB}->find_device( $VENDOR, $PRODUCT ); $hash->{DEV} = $hash->{USB}->find_device( $VENDOR, $PRODUCT );
Log3 $name, 5, "$name: found CO20 device on identify";
} }
if( $hash->{DEV} ) { if( !$hash->{DEV} ) {
Log3 $name, 2, "$name: failed to find CO20 device";
CO20_Disconnect($hash);
return undef;
}
else
{
Log3 $name, 5, "$name: found one CO20 device on identify";
if( !$hash->{ID} ) {
foreach my $bus ($hash->{USB}->list_busses()) {
foreach my $device (@{$bus->{devices}}) {
next if( $device->idVendor() != $VENDOR );
next if( $device->idProduct() != $PRODUCT );
next if( $device->{filename} != $hash->{DEV}->{filename} );
$hash->{ID} = $bus->{dirname} . ":" . $device->{filename};
last if( $hash->{ID} );
}
last if( $hash->{ID} );
}}
#
$hash->{STATE} = "found"; $hash->{STATE} = "found";
Log3 $name, 3, "$name: CO20 device found"; Log3 $name, 3, "$name: CO20 device found";
@ -179,6 +264,7 @@ CO20_Connect($)
$hash->{manufacturer} = $hash->{DEV}->manufacturer(); $hash->{manufacturer} = $hash->{DEV}->manufacturer();
$hash->{product} = $hash->{DEV}->product(); $hash->{product} = $hash->{DEV}->product();
$hash->{SERIAL} = $hash->{DEV}->serial_number() if($hash->{DEV}->serial_number() ne "?");
if( $hash->{manufacturer} && $hash->{product} ) { if( $hash->{manufacturer} && $hash->{product} ) {
$hash->{DEV}->detach_kernel_driver_np(0) if( $hash->{DEV}->get_driver_np(0) ); $hash->{DEV}->detach_kernel_driver_np(0) if( $hash->{DEV}->get_driver_np(0) );
@ -197,13 +283,12 @@ CO20_Connect($)
Log3 $name, 3, "$name: CO20 device opened"; Log3 $name, 3, "$name: CO20 device opened";
$hash->{INTERVAL} = AttrVal($name, "interval", 300); $hash->{INTERVAL} = AttrVal($name, "interval", 300);
$hash->{retries} = AttrVal($name,"retries",3);
$hash->{timeout} = AttrVal($name,"timeout",1000);
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+10, "CO20_poll", $hash, 0); InternalTimer(gettimeofday()+10, "CO20_poll", $hash, 0);
Log3 $name, 5, "$name: polling CO20 device on identify";
my $buf; my $buf;
$hash->{DEV}->interrupt_read(0x00000081, $buf, 0x0000010, 1000); $hash->{DEV}->interrupt_read(0x00000081, $buf, 0x0000010, 1000);
@ -211,9 +296,8 @@ CO20_Connect($)
Log3 $name, 3, "$name: failed to open CO20 device"; Log3 $name, 3, "$name: failed to open CO20 device";
CO20_Disconnect($hash); CO20_Disconnect($hash);
} }
} else {
Log3 $name, 3, "$name: failed to find CO20 device";
} }
return undef;
} }
sub sub
@ -224,22 +308,35 @@ CO20_Disconnect($)
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
return if( !$hash->{USB} );
if( !$hash->{USB} )
{
$hash->{STATE} = "disconnected";
if( $hash->{manufacturer} && $hash->{product} ) { if( $hash->{manufacturer} && $hash->{product} ) {
$hash->{DEV}->release_interface(0); Log3 $name, 5, "$name: disconnected release";
$hash->{DEV}->release_interface(0) if($hash->{DEV});
}
return;
}
if( $hash->{manufacturer} && $hash->{product} ) {
Log3 $name, 5, "$name: disconnect release";
$hash->{DEV}->release_interface(0) if($hash->{DEV});
} }
delete( $hash->{USB} ); delete( $hash->{USB} ) if($hash->{USB});
delete( $hash->{DEV} ); delete( $hash->{DEV} ) if($hash->{DEV});
delete( $hash->{manufacturer} ); delete( $hash->{manufacturer} );
delete( $hash->{product} ); delete( $hash->{product} );
delete( $hash->{BLOCKED} ); delete( $hash->{BLOCKED} );
delete $hash->{FIRMWARE}; delete $hash->{FIRMWARE};
CO20_SetStickData($hash,"X");
$hash->{STATE} = "disconnected"; $hash->{STATE} = "disconnected";
Log3 $name, 3, "$name: disconnected"; Log3 $name, 3, "$name: disconnected";
CO20_SetStickData($hash,"X");
return undef;
} }
sub sub
@ -248,7 +345,7 @@ CO20_Undefine($$)
my ($hash, $arg) = @_; my ($hash, $arg) = @_;
CO20_Disconnect($hash); CO20_Disconnect($hash);
$hash->{fail} = 0; $hash->{FAIL} = 0;
return undef; return undef;
} }
@ -257,7 +354,7 @@ sub
CO20_identify($) CO20_identify($)
{ {
my ($hash) = @_; my ($hash) = @_;
CO20_dataread($hash,"stickdata"); CO20_dataread($hash,"stickdata",1);
} }
sub sub
@ -277,44 +374,46 @@ CO20_poll($)
if( $hash->{manufacturer} && $hash->{product} ) { if( $hash->{manufacturer} && $hash->{product} ) {
my $buf = "@".sprintf("%c",$hash->{seq2})."TRF?\n@@@@@@@@@"; my $buf = "@".sprintf("%c",$hash->{helper}{seq2})."TRF?\n@@@@@@@@@";
Log3 $name, 5, "$name: sent $buf / ".ord(substr($buf,0,1)); Log3 $name, 5, "$name: sent $buf / ".ord(substr($buf,0,1));
my $ret = $hash->{DEV}->interrupt_write(0x00000002, $buf, 0x0000010, $hash->{timeout}); my $ret = $hash->{DEV}->interrupt_write(0x00000002, $buf, 0x0000010, $hash->{helper}{timeout});
if( $ret != 16 ) { if( $ret != 16 ) {
my $ret2 = $hash->{DEV}->interrupt_write(0x00000002, "@@@@@@@@@@@@@@@@", 0x0000010, $hash->{timeout}); $hash->{STATE} = "error";
$hash->{fail} = $hash->{fail}+1; my $ret2 = $hash->{DEV}->interrupt_write(0x00000002, "@@@@@@@@@@@@@@@@", 0x0000010, $hash->{helper}{timeout});
Log3 $name, 4, "$name: write error $ret/$ret2 ($hash->{fail})"; $hash->{FAIL} = $hash->{FAIL}+1;
Log3 $name, 3, "$name: write error $ret/$ret2 ($hash->{FAIL})";
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+30, "CO20_poll", $hash, 1); InternalTimer(gettimeofday()+30, "CO20_poll", $hash, 1);
if($hash->{fail} >= $hash->{retries}) { if($hash->{FAIL} >= $hash->{helper}{retries}) {
$hash->{fail} = 0; $hash->{FAIL} = 0;
CO20_Disconnect($hash); CO20_Disconnect($hash);
$hash->{RECONNECT} = 1; $hash->{RECONNECT} = 1;
CO20_Connect($hash); CO20_Connect($hash);
} }
return undef; return undef;
} }
if ($hash->{seq2} < 0xFF){ $hash->{seq2}++} else {$hash->{seq2} = 0x67}; if ($hash->{helper}{seq2} < 0xFF){ $hash->{helper}{seq2}++} else {$hash->{helper}{seq2} = 0x67};
my $data=""; my $data="";
for( $a = 1; $a <= 3; $a = $a + 1 ) { for( $a = 1; $a <= 3; $a = $a + 1 ) {
$ret=$hash->{DEV}->interrupt_read(0x00000081, $buf, 0x0000010, $hash->{timeout}); $ret=$hash->{DEV}->interrupt_read(0x00000081, $buf, 0x0000010, $hash->{helper}{timeout});
if( $ret != 16 and $ret != 0 ) { if( $ret != 16 and $ret != 0 ) {
Log3 $name, 4, "$name: read error $ret"; Log3 $name, 4, "$name: read error $ret";
} }
$data.=$buf; $data.=$buf;
} }
Log3 $name, 4, "$name got $data / ".length($data)." / ".ord(substr($data,0,1)); Log3 $name, 4, "$name got ".unpack('H*', $data)." / ".length($data)." / ".ord(substr($data,0,1));
if( $ret != 16 and $ret != 0 and length($data) < 16 ) { if( $ret != 16 and $ret != 0 and length($data) < 16 ) {
$hash->{fail} = $hash->{fail}+1; $hash->{STATE} = "error";
$hash->{FAIL} = $hash->{FAIL}+1;
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
InternalTimer(gettimeofday()+30, "CO20_poll", $hash, 1); InternalTimer(gettimeofday()+30, "CO20_poll", $hash, 1);
Log3 $name, 4, "$name: readloop error $ret ($hash->{fail})"; Log3 $name, 4, "$name: readloop error $ret ($hash->{FAIL})";
if($hash->{fail} >= $hash->{retries}) { if($hash->{FAIL} >= $hash->{helper}{retries}) {
$hash->{fail} = 0; $hash->{FAIL} = 0;
CO20_Disconnect($hash); CO20_Disconnect($hash);
$hash->{RECONNECT} = 1; $hash->{RECONNECT} = 1;
CO20_Connect($hash); CO20_Connect($hash);
@ -327,7 +426,7 @@ CO20_poll($)
$data = "@".$data if(ord(substr($data,0,1)) > 64); $data = "@".$data if(ord(substr($data,0,1)) > 64);
$hash->{fail} = 0; $hash->{FAIL} = 0;
my $voc = ord(substr($data,3,1))*256 + ord(substr($data,2,1)); my $voc = ord(substr($data,3,1))*256 + ord(substr($data,2,1));
my $dbg = ord(substr($data,5,1))*256 + ord(substr($data,4,1)); my $dbg = ord(substr($data,5,1))*256 + ord(substr($data,4,1));
my $pwm = ord(substr($data,7,1))*256 + ord(substr($data,6,1)); my $pwm = ord(substr($data,7,1))*256 + ord(substr($data,6,1));
@ -347,10 +446,11 @@ CO20_poll($)
# Log3 $name, 5, "$name: read 1 success\n$bufdec"; # Log3 $name, 5, "$name: read 1 success\n$bufdec";
} else { } else {
$hash->{fail} = $hash->{fail}+1; $hash->{STATE} = "error";
Log3 $name, 2, "$name: read failed $ret ($hash->{fail})"; $hash->{FAIL} = $hash->{FAIL}+1;
if($hash->{fail} >= $hash->{retries}) { Log3 $name, 2, "$name: read failed $ret ($hash->{FAIL})";
$hash->{fail} = 0; if($hash->{FAIL} >= $hash->{helper}{retries}) {
$hash->{FAIL} = 0;
CO20_Disconnect($hash); CO20_Disconnect($hash);
$hash->{RECONNECT} = 1; $hash->{RECONNECT} = 1;
CO20_Connect($hash); CO20_Connect($hash);
@ -360,7 +460,7 @@ CO20_poll($)
$hash->{LAST_POLL} = FmtDateTime( gettimeofday() ); $hash->{LAST_POLL} = FmtDateTime( gettimeofday() );
} else { } else {
Log3 $name, 2, "$name: no device"; Log3 $name, 2, "$name: no device";
$hash->{fail} = 0; $hash->{FAIL} = 0;
CO20_Disconnect($hash); CO20_Disconnect($hash);
$hash->{RECONNECT} = 1; $hash->{RECONNECT} = 1;
CO20_Connect($hash); CO20_Connect($hash);
@ -369,11 +469,16 @@ CO20_poll($)
sub sub
CO20_dataread($$) CO20_dataread($$;$)
{ {
my ($hash, $readingstype) = @_; my ($hash, $readingstype, $identify) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
if(!defined($hash->{DEV}))
{
Log3 $name, 1, "$name: no device";
return undef;
}
my $reqstr = ""; my $reqstr = "";
my $retcount = 16; my $retcount = 16;
@ -395,12 +500,12 @@ CO20_dataread($$)
if( $hash->{manufacturer} && $hash->{product} ) { if( $hash->{manufacturer} && $hash->{product} ) {
my $seq = sprintf("%04X",$hash->{seq4}); my $seq = sprintf("%04X",$hash->{helper}{seq4});
my $seqstr = sprintf("%c",hex substr($seq,2,2)).sprintf("%c",hex substr($seq,0,2)); my $seqstr = sprintf("%c",hex substr($seq,2,2)).sprintf("%c",hex substr($seq,0,2));
$hash->{seq4} = ($hash->{seq4} +1) & 0xFFFF; $hash->{helper}{seq4} = ($hash->{helper}{seq4} +1) & 0xFFFF;
my $buf = substr("@".$seq.$reqstr."\n@@@@@@@@@@@@@@@@",0,16); my $buf = substr("@".$seq.$reqstr."\n@@@@@@@@@@@@@@@@",0,16);
my $ret = $hash->{DEV}->interrupt_write(0x00000002, $buf, 0x0000010, $hash->{timeout}); my $ret = $hash->{DEV}->interrupt_write(0x00000002, $buf, 0x0000010, $hash->{helper}{timeout}) if(defined($hash->{DEV}));
Log3 $name, 4, "getdata write $ret" if($ret != 16); Log3 $name, 4, "getdata write $ret" if($ret != 16);
@ -408,7 +513,7 @@ CO20_dataread($$)
my $intdata = ""; my $intdata = "";
if($ret == 16) { if($ret == 16) {
for( $a = 1; $a <= $retcount; $a = $a + 1 ){ for( $a = 1; $a <= $retcount; $a = $a + 1 ){
$hash->{DEV}->interrupt_read(0x00000081, $buf, 0x0000010, $hash->{timeout}); $hash->{DEV}->interrupt_read(0x00000081, $buf, 0x0000010, $hash->{helper}{timeout});
$data.=$buf; $data.=$buf;
Log3 $name, 4, "getdata read $ret" if($ret != 16); Log3 $name, 4, "getdata read $ret" if($ret != 16);
$intdata = ord(substr($buf,0,1))." ".ord(substr($buf,1,1))." ".ord(substr($buf,2,1))." ".ord(substr($buf,3,1))." ".ord(substr($buf,4,1))." ".ord(substr($buf,5,1))." ".ord(substr($buf,6,1))." ".ord(substr($buf,7,1))." ".ord(substr($buf,8,1))." ".ord(substr($buf,9,1))." ".ord(substr($buf,10,1))." ".ord(substr($buf,11,1))." ".ord(substr($buf,12,1))." ".ord(substr($buf,13,1))." ".ord(substr($buf,14,1))." ".ord(substr($buf,15,1)) if(length($buf) > 15); $intdata = ord(substr($buf,0,1))." ".ord(substr($buf,1,1))." ".ord(substr($buf,2,1))." ".ord(substr($buf,3,1))." ".ord(substr($buf,4,1))." ".ord(substr($buf,5,1))." ".ord(substr($buf,6,1))." ".ord(substr($buf,7,1))." ".ord(substr($buf,8,1))." ".ord(substr($buf,9,1))." ".ord(substr($buf,10,1))." ".ord(substr($buf,11,1))." ".ord(substr($buf,12,1))." ".ord(substr($buf,13,1))." ".ord(substr($buf,14,1))." ".ord(substr($buf,15,1)) if(length($buf) > 15);
@ -423,10 +528,14 @@ CO20_dataread($$)
} elsif ($readingstype eq "flagdata") { } elsif ($readingstype eq "flagdata") {
CO20_SetStickData($hash,$data); CO20_SetStickData($hash,$data);
} elsif ($readingstype eq "stickdata") { } elsif ($readingstype eq "stickdata") {
if ($data =~ /\bStick\b(.*?)\bMCU\b/) { if ($data =~ /\b;\b(.*?)\b \$;;MCU\b/) {
$hash->{FIRMWARE} = $1; my $fwstr = $1;
$fwstr =~ s/;C;/, Firmware: /g;
$fwstr =~ s/\$//g;
$hash->{FIRMWARE} = $fwstr;
} }
if ($data =~ /\bS\/N:\b(.*?)\b;bI\b/) { if ($data =~ /\bS\/N:\b(.*?)\b;bI\b/) {
return $1 if($identify);
$hash->{SERIALNUMBER} = $1; $hash->{SERIALNUMBER} = $1;
} }
} }
@ -498,6 +607,10 @@ CO20_dataset($$$)
$reqstr = "FLAGSET;RESET BASELINE="; # 0180 $reqstr = "FLAGSET;RESET BASELINE="; # 0180
} elsif($cmd eq "reset_device") { } elsif($cmd eq "reset_device") {
$reqstr = "*RST"; $reqstr = "*RST";
} elsif($cmd eq "reconnect") {
CO20_Disconnect($hash);
CO20_Connect($hash);
return undef;
} }
RemoveInternalTimer($hash); RemoveInternalTimer($hash);
@ -505,8 +618,8 @@ CO20_dataset($$$)
if( $hash->{manufacturer} && $hash->{product} ) { if( $hash->{manufacturer} && $hash->{product} ) {
my $seq = sprintf("%04X",$hash->{seq4}); my $seq = sprintf("%04X",$hash->{helper}{seq4});
$hash->{seq4} = ($hash->{seq4} +1) & 0xFFFF; $hash->{helper}{seq4} = ($hash->{helper}{seq4} +1) & 0xFFFF;
my $buf = "@".$seq.$reqstr; my $buf = "@".$seq.$reqstr;
if($cmd ne "reset_device") { if($cmd ne "reset_device") {
@ -528,23 +641,23 @@ CO20_dataset($$$)
$buf .= "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"; $buf .= "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@";
my $ret = $hash->{DEV}->interrupt_write(0x00000002, substr($buf,0,16), 0x0000010, $hash->{timeout}); my $ret = $hash->{DEV}->interrupt_write(0x00000002, substr($buf,0,16), 0x0000010, $hash->{helper}{timeout});
Log3 $name, 4, "setdata write $ret" if($ret != 16); Log3 $name, 4, "setdata write $ret" if($ret != 16);
if($ret == 16 and ($buflen > 16 or $cmd eq "reset_device")) { if($ret == 16 and ($buflen > 16 or $cmd eq "reset_device")) {
$ret = $hash->{DEV}->interrupt_write(0x00000002, substr($buf,16,16), 0x0000010, $hash->{timeout}); $ret = $hash->{DEV}->interrupt_write(0x00000002, substr($buf,16,16), 0x0000010, $hash->{helper}{timeout});
Log3 $name, 4, "setdata write $ret" if($ret != 16); Log3 $name, 4, "setdata write $ret" if($ret != 16);
} }
if($ret == 16 and $buflen > 32) { if($ret == 16 and $buflen > 32) {
$ret = $hash->{DEV}->interrupt_write(0x00000002, substr($buf,32,16), 0x0000010, $hash->{timeout}); $ret = $hash->{DEV}->interrupt_write(0x00000002, substr($buf,32,16), 0x0000010, $hash->{helper}{timeout});
Log3 $name, 4, "setdata write $ret" if($ret != 16); Log3 $name, 4, "setdata write $ret" if($ret != 16);
} }
if($ret == 16 and $buflen > 15) { if($ret == 16 and $buflen > 15) {
$hash->{DEV}->interrupt_read(0x00000081, $buf, 0x0000010, $hash->{timeout}); $hash->{DEV}->interrupt_read(0x00000081, $buf, 0x0000010, $hash->{helper}{timeout});
$buflen = length($buf); $buflen = length($buf);
Log3 $name, 5, "getdata read $ret"; Log3 $name, 5, "getdata read $ret";
if($buflen > 15) if($buflen > 15)
@ -601,7 +714,7 @@ CO20_Set($$$$)
my ($hash, $name, $cmd, $val) = @_; my ($hash, $name, $cmd, $val) = @_;
my $list = ""; my $list = "";
$list = "knob_CO2/VOC_level_warn1 knob_CO2/VOC_level_warn2 knob_Reg_Set knob_Reg_P knob_Reg_I knob_Reg_D knob_LogInterval knob_ui16StartupBits recalibrate_heater:noArg reset_baseline:noArg reset_device:noArg" if( AttrVal($name, "advanced", 0 ) == 1 ); $list = "knob_CO2/VOC_level_warn1 knob_CO2/VOC_level_warn2 knob_Reg_Set knob_Reg_P knob_Reg_I knob_Reg_D knob_LogInterval knob_ui16StartupBits recalibrate_heater:noArg reset_baseline:noArg reset_device:noArg reconnect:noArg" if( AttrVal($name, "advanced", 0 ) == 1 );
if (index($list, $cmd) != -1) { if (index($list, $cmd) != -1) {
$hash->{BLOCKED} = 1; $hash->{BLOCKED} = 1;
CO20_dataset($hash,$cmd,$val); CO20_dataset($hash,$cmd,$val);
@ -617,6 +730,7 @@ CO20_Attr($$$)
{ {
my ($cmd, $name, $attrName, $attrVal) = @_; my ($cmd, $name, $attrName, $attrVal) = @_;
return undef if(!defined($defs{$name}));
my $orig = $attrVal; my $orig = $attrVal;
$attrVal = int($attrVal) if($attrName eq "interval" || $attrName eq "retries" || $attrName eq "timeout"); $attrVal = int($attrVal) if($attrName eq "interval" || $attrName eq "retries" || $attrName eq "timeout");
$attrVal = 10 if($attrName eq "interval" && $attrVal < 10 && $attrVal != 0); $attrVal = 10 if($attrName eq "interval" && $attrVal < 10 && $attrVal != 0);
@ -640,10 +754,10 @@ CO20_Attr($$$)
CO20_poll($hash) if( $init_done ); CO20_poll($hash) if( $init_done );
} elsif( $attrName eq "retries" ) { } elsif( $attrName eq "retries" ) {
my $hash = $defs{$name}; my $hash = $defs{$name};
$hash->{retries} = $attrVal; $hash->{helper}{retries} = $attrVal;
} elsif( $attrName eq "timeout" ) { } elsif( $attrName eq "timeout" ) {
my $hash = $defs{$name}; my $hash = $defs{$name};
$hash->{timeout} = $attrVal; $hash->{helper}{timeout} = $attrVal;
} }
if( $cmd eq "set" ) { if( $cmd eq "set" ) {