############################################# package main; use strict; use warnings; use vars qw(%fht8v_c2b); # would Peter like to access it from outside too? ;-) # defptr{XMIT BTN}{DEVNAME} -> Ptr to global defs entry for this device my %defptr; # my %follow; sub FHT8V_Initialize($) { my ($hash) = @_; # $hash->{Match} = "^([0-9]{2}:2[0-9A-F]{3} )*([0-9]{2}:2[0-9A-F]{3})\$"; $hash->{SetFn} = "FHT8V_Set"; $hash->{DefFn} = "FHT8V_Define"; $hash->{UndefFn} = "FHT8V_Undef"; $hash->{AttrList} = "IODev do_not_notify:1,0 dummy:1,0 showtime:1,0 loglevel:0,1,2,3,4,5,6"; } ################################### sub FHT8V_valve_position(@) { my ($hash, @a) = @_; my $na = int(@a); my $v; my $arg2_percent=0; if ( $na > 3 ) { $arg2_percent=$a[3] eq "%"; } if ( $a[2] =~ m/^[0-9]{1,3}%$/ || $a[2] =~ m/^[0-9]{1,3}$/ && $arg2_percent ) { my $num; if ( $arg2_percent ) { $num=$a[2]; } else { $num=substr($a[2],0,-1); } return "Out of range." if ( $num > 100 || $num < 0 ); $num=255 if ( $num == 100 ); $v=sprintf("%.0f",2.56*$num); } else { return "Argument hast invalid value \"$a[2]\"." if ( $a[2] !~ m/^[0-9]{1,3}$/ ); return "Out of range. Range: 0..255." if ( $a[2] > 255 || $a[2] < 0 ); $v = $a[2]; } Log GetLogLevel($a[2],2), "FHT8V $a[0]: v: $v"; IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X26%02X",$hash->{NO}, $v)) # CUL hack if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL"); $hash->{STATE}=sprintf("%d%%", $v*0.390625); return undef; } sub FHT8V_beep(@) { my ($hash, @a) = @_; IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X2E00",$hash->{NO})) # CUL hack if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL"); $hash->{STATE}="beep"; return undef; } sub FHT8V_open(@) { my ($hash, @a) = @_; IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X2100",$hash->{NO})) # CUL hack if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL"); $hash->{STATE}="open"; return undef; } sub FHT8V_off(@) { my ($hash, @a) = @_; IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X2000",$hash->{NO})) # CUL hack if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL"); $hash->{STATE}="off"; return undef; } sub FHT8V_close(@) { my ($hash, @a) = @_; IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X2200",$hash->{NO})) # CUL hack if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL"); $hash->{STATE}="close"; return undef; } sub FHT8V_assign(@) { my ($hash, @a) = @_; my $na = int(@a); my $v = 0; if ( $na > 2 ) { return "Parameter \"".$a[3]."\" defining offset must be numerical." if ( $a[3] !~ /[0-9]+/ ); $v=int($a[3]); } IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X2F%02X",$hash->{NO},$v)) # CUL hack if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL"); # not sure if this is nessesary but I saw it in the documentation... IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X2600",$hash->{NO},$v)) # CUL hack if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL"); $hash->{STATE}="assigning"; return undef; } sub FHT8V_Set($@) { my ($hash, @a) = @_; my $na = int(@a); return "Parameter missing" if ( $na < 2 ); if ( $_[2] eq "valve" ) { return FHT8V_valve_position(@_); } if ( $_[2] eq "open" ) { return FHT8V_open(@_); } if ( $_[2] eq "close" ) { return FHT8V_close(@_); } if ( $_[2] eq "beep" ) { return FHT8V_beep(@_); } if ( $_[2] eq "assign" ) { return FHT8V_assign(@_); } if ( $_[2] eq "off" ) { return FHT8V_off(@_); } return "Could not set undefined parameter \"".$_[2]."\"."; } ############################# sub FHT8V_Define($$) { my ($hash, $def) = @_; my @a = split("[ \t][ \t]*", $def); my $na = int(@a); my $u = "wrong syntax: define FHT8V housecode " . "addr"; return $u if( $na < 3 ); return "Define $a[0]: wrong housecode format: specify a 4 digit hex value ". "or an 8 digit quad value" if( ($a[2] !~ m/^[a-f0-9]{4}$/i) && ($a[2] !~ m/^[1-4]{8}$/i) ); if ( $na > 3 ) { return "Define $a[0]: wrong valve address format: specify a 2 digit hex value " . "or a 4 digit quad value" if( ($a[3] !~ m/^[a-f0-9]{2}$/i) && ($a[3] !~ m/^[1-4]{4}$/i) ); } my $housecode = $a[2]; $housecode = four2hex($housecode,4) if (length($housecode) == 8); my $valve_number = 1; if ( $na > 3 ) { my $valve_number = $a[3]; $valve_number = four2hex($valve_number,2) if (length($valve_number) == 4); } $hash->{XMIT} = lc($housecode); $hash->{NO} = lc($valve_number); my $code = "$housecode $valve_number"; my $ncode = 1; my $name = $a[0]; $hash->{CODE}{$ncode++} = $code; $defptr{$code}{$name} = $hash; for(my $i = 4; $i < int(@a); $i += 2) { return "No address specified for $a[$i]" if($i == int(@a)-1); $a[$i] = lc($a[$i]); if($a[$i] eq "fg") { return "Bad fg address for $name, see the doc" if( ($a[$i+1] !~ m/^f[a-f0-9]$/) && ($a[$i+1] !~ m/^44[1-4][1-4]$/)); } elsif($a[$i] eq "lm") { return "Bad lm address for $name, see the doc" if( ($a[$i+1] !~ m/^[a-f0-9]f$/) && ($a[$i+1] !~ m/^[1-4][1-4]44$/)); } elsif($a[$i] eq "gm") { return "Bad gm address for $name, must be ff" if( ($a[$i+1] ne "ff") && ($a[$i+1] ne "4444")); } else { return $u; } my $grpcode = $a[$i+1]; if (length($grpcode) == 4) { $grpcode = four2hex($grpcode,2); } $code = "$housecode $grpcode"; $hash->{CODE}{$ncode++} = $code; $defptr{$code}{$name} = $hash; } $hash->{TYPE}="FHT8V"; AssignIoPort($hash); } ############################# sub FHT8V_Undef($$) { my ($hash, $name) = @_; foreach my $c (keys %{ $hash->{CODE} } ) { $c = $hash->{CODE}{$c}; # As after a rename the $name my be different from the $defptr{$c}{$n} # we look for the hash. foreach my $dname (keys %{ $defptr{$c} }) { delete($defptr{$c}{$dname}) if($defptr{$c}{$dname} == $hash); } } return undef; } 1;