# # # 66_ECMDDevice.pm # written by Dr. Boris Neubert 2011-01-15 # e-mail: omega at online dot de # ############################################## # $Id$ package main; use strict; use warnings; use Time::HiRes qw(gettimeofday); sub ECMDDevice_Get($@); sub ECMDDevice_Set($@); sub ECMDDevice_Define($$); my %gets= ( ); my %sets= ( ); ################################### sub ECMDDevice_Initialize($) { my ($hash) = @_; $hash->{GetFn} = "ECMDDevice_Get"; $hash->{SetFn} = "ECMDDevice_Set"; $hash->{DefFn} = "ECMDDevice_Define"; $hash->{AttrList} = "loglevel 0,1,2,3,4,5"; } ################################### sub ECMDDevice_AnalyzeCommand($) { my ($ecmd)= @_; Log 5, "ECMDDevice: Analyze command >$ecmd<"; return AnalyzePerlCommand(undef, $ecmd); } ############################# sub ECMDDevice_GetDeviceParams($) { my ($hash)= @_; my $classname= $hash->{fhem}{classname}; my $IOhash= $hash->{IODev}; if(defined($IOhash->{fhem}{classDefs}{$classname}{params})) { my $params= $IOhash->{fhem}{classDefs}{$classname}{params}; return split("[ \t]+", $params); } return; } sub ECMDDevice_DeviceParams2Specials($) { my ($hash)= @_; my %specials= ( "%NAME" => $hash->{NAME}, "%TYPE" => $hash->{TYPE} ); my @deviceparams= ECMDDevice_GetDeviceParams($hash); foreach my $param (@deviceparams) { $specials{"%".$param}= $hash->{fhem}{params}{$param}; } return %specials; } ################################### sub ECMDDevice_Changed($$$) { my ($hash, $cmd, $value)= @_; readingsBeginUpdate($hash); readingsUpdate($hash, $cmd, $value); readingsEndUpdate($hash, 1); $hash->{STATE} = "$cmd $value"; my $name= $hash->{NAME}; Log GetLogLevel($name, 4), "ECMDDevice $name $cmd: $value"; return $hash->{STATE}; } ################################### sub ECMDDevice_PostProc($$$) { my ($hash, $postproc, $value)= @_; # the following lines are commented out because we do not want specials to be evaluated # this is mainly due to the unwanted substitution of single semicolons by double semicolons #my %specials= ECMDDevice_DeviceParams2Specials($hash); #my $command= EvalSpecials($postproc, %specials); # we pass the command verbatim instead # my $command= $postproc; if($postproc) { my %specials= ECMDDevice_DeviceParams2Specials($hash); my $command= EvalSpecials($postproc, %specials); $_= $value; Log 5, "Postprocessing $value with perl command $command."; $value= AnalyzePerlCommand(undef, $command); } return $value; } ################################### sub ECMDDevice_Get($@) { my ($hash, @a)= @_; my $name= $hash->{NAME}; my $type= $hash->{TYPE}; return "get $name needs at least one argument" if(int(@a) < 2); my $cmdname= $a[1]; my $IOhash= $hash->{IODev}; my $classname= $hash->{fhem}{classname}; if(!defined($IOhash->{fhem}{classDefs}{$classname}{gets}{$cmdname})) { return "$name error: unknown command $cmdname"; } my $ecmd= $IOhash->{fhem}{classDefs}{$classname}{gets}{$cmdname}{cmd}; my $params= $IOhash->{fhem}{classDefs}{$classname}{gets}{$cmdname}{params}; my $postproc= $IOhash->{fhem}{classDefs}{$classname}{gets}{$cmdname}{postproc}; my %specials= ECMDDevice_DeviceParams2Specials($hash); # add specials for command if($params) { shift @a; shift @a; my @params= split('[\s]+', $params); return "Wrong number of parameters." if($#a != $#params); my $i= 0; foreach my $param (@params) { Log 5, "Parameter %". $param . " is " . $a[$i]; $specials{"%".$param}= $a[$i++]; } } $ecmd= EvalSpecials($ecmd, %specials); my $r = ECMDDevice_AnalyzeCommand($ecmd); my $v= IOWrite($hash, $r); $v= ECMDDevice_PostProc($hash, $postproc, $v); return ECMDDevice_Changed($hash, $cmdname, $v); } ############################# sub ECMDDevice_Set($@) { my ($hash, @a)= @_; my $name= $hash->{NAME}; my $type= $hash->{TYPE}; return "set $name needs at least one argument" if(int(@a) < 2); my $cmdname= $a[1]; my $IOhash= $hash->{IODev}; my $classname= $hash->{fhem}{classname}; if(!defined($IOhash->{fhem}{classDefs}{$classname}{sets}{$cmdname})) { my $sets= $IOhash->{fhem}{classDefs}{$classname}{sets}; return "Unknown argument ?, choose one of " . join(' ', keys %$sets); } my $ecmd= $IOhash->{fhem}{classDefs}{$classname}{sets}{$cmdname}{cmd}; my $params= $IOhash->{fhem}{classDefs}{$classname}{sets}{$cmdname}{params}; my $postproc= $IOhash->{fhem}{classDefs}{$classname}{sets}{$cmdname}{postproc}; my %specials= ECMDDevice_DeviceParams2Specials($hash); # add specials for command if($params) { shift @a; shift @a; my @params= split('[\s]+', $params); return "Wrong number of parameters." if($#a != $#params); my $i= 0; foreach my $param (@params) { $specials{"%".$param}= $a[$i++]; } } $ecmd= EvalSpecials($ecmd, %specials); my $r = ECMDDevice_AnalyzeCommand($ecmd); my $v= IOWrite($hash, $r); $v= ECMDDevice_PostProc($hash, $postproc, $v); # $v= join(" ", @a) if($params); return ECMDDevice_Changed($hash, $cmdname, $v); } ############################# sub ECMDDevice_Define($$) { my ($hash, $def) = @_; my @a = split("[ \t]+", $def); return "Usage: define ECMDDevice [...]" if(int(@a) < 3); my $name= $a[0]; my $classname= $a[2]; AssignIoPort($hash); my $IOhash= $hash->{IODev}; if(!defined($IOhash->{fhem}{classDefs}{$classname}{filename})) { my $err= "$name error: unknown class $classname."; Log 1, $err; return $err; } $hash->{fhem}{classname}= $classname; my @prms= ECMDDevice_GetDeviceParams($hash); my $numparams= 0; $numparams= $#prms+1 if(defined($prms[0])); #Log 5, "ECMDDevice $classname requires $numparams parameter(s): ". join(" ", @prms); # keep only the parameters shift @a; shift @a; shift @a; # verify identical number of parameters if($numparams != $#a+1) { my $err= "$name error: wrong number of parameters"; Log 1, $err; return $err; } # set parameters for(my $i= 0; $i< $numparams; $i++) { $hash->{fhem}{params}{$prms[$i]}= $a[$i]; } return undef; } 1; =pod =begin html

ECMDDevice

=end html =cut