diff --git a/fhem/FHEM/70_SCIVT.pm b/fhem/FHEM/70_SCIVT.pm index cd4f743f2..134f1e286 100644 --- a/fhem/FHEM/70_SCIVT.pm +++ b/fhem/FHEM/70_SCIVT.pm @@ -5,6 +5,11 @@ use strict; use warnings; use Device::SerialPort; +my %sets = ( + "cmd" => "", + "freq" => "", +); + ##################################### sub SCIVT_Initialize($) @@ -14,7 +19,8 @@ SCIVT_Initialize($) # Consumer $hash->{DefFn} = "SCIVT_Define"; $hash->{GetFn} = "SCIVT_Get"; - $hash->{AttrList}= "model:SCD loglevel:0,1,2,3,4,5,6"; + $hash->{SetFn} = "SCIVT_Set"; + $hash->{AttrList}= "model:SCD10,SCD20,SCD30 loglevel:0,1,2,3,4,5,6"; } ##################################### @@ -34,105 +40,181 @@ SCIVT_Define($$) if($dev eq "none"); if($dev ne "none") { - Log 2, "SCIVT opening device $dev"; + Log 3, "SCIVT opening device $dev"; my $po = new Device::SerialPort ($dev); - return "Can't open $dev: $!" if(!$po); + return "SCIVT Can't open $dev: $!" if(!$po); Log 2, "SCIVT opened device $dev"; $po->close(); } $hash->{DeviceName} = $dev; + $hash->{Timer} = 900; # call every 15 min + $hash->{Cmd} = 'F'; # get all data, min/max unchanged + my $tn = TimeNow(); + $hash->{READINGS}{"freq"}{TIME} = $tn; + $hash->{READINGS}{"freq"}{VAL} = $hash->{Timer}; + $hash->{READINGS}{"cmd"}{TIME} = $tn; + $hash->{READINGS}{"cmd"}{VAL} = $hash->{Cmd}; + $hash->{CHANGED}[0] = "freq: $hash->{Timer}"; + $hash->{CHANGED}[1] = "cmd: $hash->{Cmd}"; + + # InternalTimer blocks if init_done is not true + my $oid = $init_done; + $init_done = 1; SCIVT_GetStatus($hash); + $init_done = $oid; return undef; } +##################################### +sub +SCIVT_Set($@) +{ +my ($hash, @a) = @_; + return "\"set SCIVT\" needs at least two parameter" if(@a < 3); +my $name = $hash->{NAME}; +Log GetLogLevel($name,4), "SCIVT Set request $a[1] $a[2], old: Timer:$hash->{Timer} Cmd: $hash->{Cmd}"; +return "Unknown argument $a[1], choose one of " . join(" ", sort keys %sets) + if(!defined($sets{$a[1]})); + +$name = shift @a; +my $type = shift @a; +my $arg = join("", @a); +my $tn = TimeNow(); + +if($type eq "freq") + { + if ($arg > 0) + { + $hash->{Timer} = $arg * 60; + $hash->{READINGS}{$type}{TIME} = $tn; + $hash->{READINGS}{$type}{VAL} = $hash->{Timer}; + $hash->{CHANGED}[0] = "$type: $hash->{Timer}"; + } + } + +if($type eq "cmd") + { + if ($arg eq "F") + { + $hash->{Cmd} = 'F'; # F : get all data + } + if ($arg eq "L") # L : get all data and clear min-/max values + { + $hash->{Cmd} = 'L'; + } + $hash->{READINGS}{$type}{TIME} = $tn; + $hash->{READINGS}{$type}{VAL} = $hash->{Cmd}; + $hash->{CHANGED}[0] = "$type: $hash->{Cmd}"; + } + +DoTrigger($name, undef) if($init_done); + +Log GetLogLevel($name,3), "SCIVT Set result Timer:$hash->{Timer} sec Cmd:$hash->{Cmd}"; +return "SCIVT => Timer:$hash->{Timer} Cmd:$hash->{Cmd}"; +} ##################################### sub SCIVT_Get($@) { - my ($hash, @a) = @_; +my ($hash, @a) = @_; +return "get for an SCIVT device needs exactly one parameter" if(@a != 2); +my $name = $hash->{NAME}; - return "get for an SCIVT device needs exactly one parameter" if(@a != 2); +my $v; +if($a[1] eq "data") + { + $v = SCIVT_GetLine($hash->{DeviceName}, $hash->{Cmd}); + if(!defined($v)) + { + Log GetLogLevel($name,2), "SCIVT Get $a[1] error"; + return "$a[0] $a[1] => Error"; + } + $v =~ s/[\r\n]//g; # Delete the NewLine + $hash->{READINGS}{$a[1]}{VAL} = $v; + $hash->{READINGS}{$a[1]}{TIME} = TimeNow(); + } +else + { + if($a[1] eq "param") + { + $v = "$hash->{DeviceName} $hash->{Timer} $hash->{Cmd}"; + } + else + { + return "Unknown argument $a[1], must be data or param"; + } + } - my $v; - if($a[1] eq "data") { - $v = SCIVT_GetLine($hash->{DeviceName}); - $v =~ s/[\r\n]//g; # Delete the NewLine - } else { - return "Unknown argument $a[1], must be data"; - } - - $hash->{READINGS}{$a[1]}{VAL} = $v; - $hash->{READINGS}{$a[1]}{TIME} = TimeNow(); - - return "$a[0] $a[1] => $v"; +Log GetLogLevel($name,3), "SCIVT Get $a[1] $v"; +return "$a[0] $a[1] => $v"; } ##################################### sub SCIVT_GetStatus($) { - my ($hash) = @_; +my ($hash) = @_; +my $dnr = $hash->{DEVNR}; +my $name = $hash->{NAME}; - # Call us in 5 minutes again. - InternalTimer(gettimeofday()+300, "SCIVT_GetStatus", $hash, 0); +# Call us in n minutes again. +InternalTimer(gettimeofday()+ $hash->{Timer}, "SCIVT_GetStatus", $hash,1); - my $dnr = $hash->{DEVNR}; - my $name = $hash->{NAME}; +my %vals; +my $result = SCIVT_GetLine($hash->{DeviceName}, $hash->{Cmd}); - my %vals; - my $result = SCIVT_GetLine($hash->{DeviceName}); +if(!defined($result)) + { + Log GetLogLevel($name,4), "SCIVT read error, retry $hash->{DeviceName}, $hash->{Cmd}"; + $result = SCIVT_GetLine($hash->{DeviceName}, $hash->{Cmd}); + } - if(!defined($result)) - { - Log GetLogLevel($name,2), "SCIVT read error, retry"; - $result = SCIVT_GetLine($hash->{DeviceName}); - } +if(!defined($result)) + { + Log GetLogLevel($name,2), "SCIVT read error, abort $hash->{DeviceName}, $hash->{Cmd}"; + $hash->{STATE} = "timeout"; + return $hash->{STATE}; + } +if (length($result) < 10) + { + Log GetLogLevel($name,2), "SCIVT incomplete line ($result)"; + $hash->{STATE} = "incomplete"; + } +else + { + $result =~ s/^.*R://; + $result =~ s/[\r\n ]//g; + Log GetLogLevel($name,3), "SCIVT $result (raw)"; + $result=~ s/,/./g; + my @data = split(";", $result); - if(!defined($result)) - { - Log GetLogLevel($name,2), "SCIVT read error, abort"; - $hash->{STATE} = "timeout"; - return $hash->{STATE}; - } - if (length($result) < 10) - { - Log GetLogLevel($name,2), "SCIVT incomplete line ($result)"; - $hash->{STATE} = "incomplete"; - } - else - { - $result =~ s/^.*R://; - $result =~ s/[\r\n ]//g; - Log GetLogLevel($name,2), "SCIVT $result (raw)"; - $result=~ s/,/./g; - my @data = split(";", $result); - - my @names = ("Vs", "Is", "Temp", "minV", "maxV", "minI", "maxI"); - my $tn = TimeNow(); - for(my $i = 0; $i < int(@names); $i++) { + my @names = ("Vs", "Is", "Temp", "minV", "maxV", "minI", "maxI"); + my $tn = TimeNow(); + for(my $i = 0; $i < int(@names); $i++) + { $hash->{CHANGED}[$i] = "$names[$i]: $data[$i]"; $hash->{READINGS}{$names[$i]}{TIME} = $tn; $hash->{READINGS}{$names[$i]}{VAL} = $data[$i]; - } - - DoTrigger($name, undef) if($init_done); + } - $result =~ s/;/ /g; - $hash->{STATE} = "$result"; - } + DoTrigger($name, undef) if($init_done); - return $hash->{STATE}; + $result =~ s/;/ /g; + $hash->{STATE} = "$result"; + } + +return $hash->{STATE}; } ##################################### sub -SCIVT_GetLine($) +SCIVT_GetLine($$) { - my $retry = 0; - my ($dev) = @_; +my $retry = 0; +my ($dev,$cmd) = @_; return "R:13,66; 0,0;30;13,62;15,09;- 0,2; 2,8;\n" if($dev eq "none"); # Fake-mode @@ -152,7 +234,7 @@ SCIVT_GetLine($) my $rm = "SCIVT timeout reading the answer"; my $data=""; - $serport->write('F'); + $serport->write($cmd); sleep(1); for(;;)