2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-26 22:25:43 +00:00
fhem-mirror/fhem/FHEM/67_ECMDDevice.pm
2012-07-02 18:42:02 +00:00

262 lines
6.9 KiB
Perl

#
#
# 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 <name> ECMDDevice <classname> [...]" 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;