2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2024-11-22 09:49:50 +00:00
fhem-mirror/fhem/contrib/90_EIBUPDOWN.pm
hotmaz f00a346204 bugfixes thanks to patch from tosti
git-svn-id: https://svn.fhem.de/fhem/trunk@926 2b470e98-0d58-463d-a4d8-8e2adae1ed80
2011-06-30 17:42:12 +00:00

212 lines
5.0 KiB
Perl

##############################################
package main;
use strict;
use warnings;
my %eib_c2b1 = (
"alloff" => "00",
"off" => "01",
"on" => "00",
"up" => "01",
"down" => "00",
"up-for-timer" => "01",
"down-for-timer" => "00",
);
my %eib_c2b2 = (
"alloff" => "00",
"off" => "00",
"on" => "01",
"up" => "00",
"down" => "01",
"up-for-timer" => "00",
"down-for-timer" => "01",
);
my %readonly = (
"dummy" => 1,
);
my $eib_simple ="alloff off on up down up-for-timer down-for-timer";
my %models = (
);
sub
EIBUPDOWN_Initialize($)
{
my ($hash) = @_;
$hash->{Match} = "^B.*";
$hash->{SetFn} = "EIBUPDOWN_Set";
$hash->{StateFn} = "EIBUPDOWN_SetState";
$hash->{DefFn} = "EIBUPDOWN_Define";
$hash->{UndefFn} = "EIBUPDOWN_Undef";
$hash->{ParseFn} = "EIBUPDOWN_Parse";
$hash->{AttrList} = "IODev do_not_notify:1,0 ignore:0,1 dummy:1,0 showtime:1,0 model:EIB loglevel:0,1,2,3,4,5,6";
}
#############################
sub
EIBUPDOWN_Define($$)
{
my ($hash, $def) = @_;
my @a = split("[ \t][ \t]*", $def);
my $u = "wrong syntax: define <name> EIBUPDOWN <up group name> <down group name>";
return $u if(int(@a) < 4);
return "Define $a[0]: wrong up group name format: specify as 0-255/0-255/0-255"
if( ($a[2] !~ m/^[0-9]{1,3}\/[0-9]{1,3}\/[0-9]{1,3}$/i));
return "Define $a[0]: wrong down group name format: specify as 0-255/0-255/0-255"
if( ($a[3] !~ m/^[0-9]{1,3}\/[0-9]{1,3}\/[0-9]{1,3}$/i));
my $groupname_up = eibupdown_name2hex($a[2]);
my $groupname_down = eibupdown_name2hex($a[3]);
$hash->{GROUP_UP} = lc($groupname_up);
$hash->{GROUP_DOWN} = lc($groupname_down);
my $code = "$groupname_up$groupname_down";
my $ncode = 1;
my $name = $a[0];
$hash->{CODE}{$ncode++} = $code;
$modules{EIB}{defptr}{$code}{$name} = $hash;
AssignIoPort($hash);
}
#############################
sub
EIBUPDOWN_Undef($$)
{
my ($hash, $name) = @_;
foreach my $c (keys %{ $hash->{CODE} } ) {
$c = $hash->{CODE}{$c};
# As after a rename the $name may be different from the $defptr{$c}{$n}
# we look for the hash.
foreach my $dname (keys %{ $modules{EIB}{defptr}{$c} }) {
delete($modules{EIB}{defptr}{$c}{$dname})
if($modules{EIB}{defptr}{$c}{$dname} == $hash);
}
}
return undef;
}
#####################################
sub
EIBUPDOWN_SetState($$$$)
{
my ($hash, $tim, $vt, $val) = @_;
$val = $1 if($val =~ m/^(.*) \d+$/);
return "Undefined value $val" if(!defined($eib_c2b1{$val}));
return undef;
}
###################################
sub
EIBUPDOWN_Set($@)
{
my ($hash, @a) = @_;
my $ret = undef;
my $na = int(@a);
return "no set value specified" if($na < 2 || $na > 3);
return "Readonly value $a[1]" if(defined($readonly{$a[1]}));
my $c_off = $eib_c2b1{"alloff"};
my $c_up = $eib_c2b1{$a[1]};
my $c_down = $eib_c2b2{$a[1]};
if(!defined($c_off) || !defined($c_up) || !defined($c_down)) {
return "Unknown argument $a[1], choose one of " .
join(" ", sort keys %eib_c2b1);
}
my $v = join(" ", @a);
Log GetLogLevel($a[0],2), "EIB set $v";
(undef, $v) = split(" ", $v, 2); # Not interested in the name...
# first of all switch off all channels
# just for being sure
IOWrite($hash, "B", "w" . $hash->{GROUP_UP} . $c_off);
select(undef,undef,undef,0.5);
IOWrite($hash, "B", "w" . $hash->{GROUP_DOWN} . $c_off);
select(undef,undef,undef,0.5);
# now switch on the right channel
if($c_up ne $c_off) {
IOWrite($hash, "B", "w" . $hash->{GROUP_UP} . $c_up);
}
elsif($c_down ne $c_off) {
IOWrite($hash, "B", "w" . $hash->{GROUP_DOWN} . $c_down);
}
###########################################
# Delete any timer for on-for_timer
if($modules{EIB}{ldata}{$a[0]}) {
CommandDelete(undef, $a[0] . "_timer");
delete $modules{EIB}{ldata}{$a[0]};
}
###########################################
# Add a timer if any for-timer command has been chosen
if($a[1] =~ m/for-timer/ && $na == 3) {
my $dur = $a[2];
my $to = sprintf("%02d:%02d:%02d", $dur/3600, ($dur%3600)/60, $dur%60);
$modules{EIB}{ldata}{$a[0]} = $to;
Log 4, "Follow: +$to set $a[0] alloff";
CommandDefine(undef, $a[0] . "_timer at +$to set $a[0] alloff");
}
##########################
# Look for all devices with the same code, and set state, timestamp
my $code = "$hash->{GROUP_UP}$hash->{GROUP_DOWN}";
my $tn = TimeNow();
foreach my $n (keys %{ $modules{EIB}{defptr}{$code} }) {
my $lh = $modules{EIB}{defptr}{$code}{$n};
$lh->{CHANGED}[0] = $v;
$lh->{STATE} = $v;
$lh->{READINGS}{state}{TIME} = $tn;
$lh->{READINGS}{state}{VAL} = $v;
}
return $ret;
}
sub
EIBUPDOWN_Parse($$)
{
my ($hash, $msg) = @_;
Log(5,"EIBUPDOWN_Parse is not defined. msg: $msg");
}
#############################
sub
eibupdown_name2hex($)
{
my $v = shift;
my $r = $v;
Log(5, "name2hex: $v");
if($v =~ /^([0-9]{1,2})\/([0-9]{1,2})\/([0-9]{1,3})$/) {
$r = sprintf("%01x%01x%02x",$1,$2,$3);
}
elsif($v =~ /^([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,3})$/) {
$r = sprintf("%01x%01x%02x",$1,$2,$3);
}
return $r;
}
1;