11_FHT8V.pm 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #############################################
  2. package main;
  3. use strict;
  4. use warnings;
  5. use vars qw(%fht8v_c2b); # would Peter like to access it from outside too? ;-)
  6. # defptr{XMIT BTN}{DEVNAME} -> Ptr to global defs entry for this device
  7. my %defptr;
  8. # my %follow;
  9. sub
  10. FHT8V_Initialize($)
  11. {
  12. my ($hash) = @_;
  13. # $hash->{Match} = "^([0-9]{2}:2[0-9A-F]{3} )*([0-9]{2}:2[0-9A-F]{3})\$";
  14. $hash->{SetFn} = "FHT8V_Set";
  15. $hash->{DefFn} = "FHT8V_Define";
  16. $hash->{UndefFn} = "FHT8V_Undef";
  17. $hash->{AttrList} = "IODev do_not_notify:1,0 dummy:1,0 showtime:1,0 loglevel:0,1,2,3,4,5,6";
  18. }
  19. ###################################
  20. sub FHT8V_valve_position(@)
  21. {
  22. my ($hash, @a) = @_;
  23. my $na = int(@a);
  24. my $v;
  25. my $arg2_percent=0;
  26. if ( $na > 3 ) {
  27. $arg2_percent=$a[3] eq "%";
  28. }
  29. if ( $a[2] =~ m/^[0-9]{1,3}%$/ || $a[2] =~ m/^[0-9]{1,3}$/ && $arg2_percent ) {
  30. my $num;
  31. if ( $arg2_percent ) {
  32. $num=$a[2];
  33. } else {
  34. $num=substr($a[2],0,-1);
  35. }
  36. return "Out of range." if ( $num > 100 || $num < 0 );
  37. $num=255 if ( $num == 100 );
  38. $v=sprintf("%.0f",2.56*$num);
  39. } else {
  40. return "Argument hast invalid value \"$a[2]\"." if ( $a[2] !~ m/^[0-9]{1,3}$/ );
  41. return "Out of range. Range: 0..255." if ( $a[2] > 255 || $a[2] < 0 );
  42. $v = $a[2];
  43. }
  44. Log GetLogLevel($a[2],2), "FHT8V $a[0]: v: $v";
  45. IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X26%02X",$hash->{NO}, $v)) # CUL hack
  46. if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL");
  47. $hash->{STATE}=sprintf("%d%%", $v*0.390625);
  48. return undef;
  49. }
  50. sub FHT8V_beep(@)
  51. {
  52. my ($hash, @a) = @_;
  53. IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X2E00",$hash->{NO})) # CUL hack
  54. if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL");
  55. $hash->{STATE}="beep";
  56. return undef;
  57. }
  58. sub FHT8V_open(@)
  59. {
  60. my ($hash, @a) = @_;
  61. IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X2100",$hash->{NO})) # CUL hack
  62. if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL");
  63. $hash->{STATE}="open";
  64. return undef;
  65. }
  66. sub FHT8V_off(@)
  67. {
  68. my ($hash, @a) = @_;
  69. IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X2000",$hash->{NO})) # CUL hack
  70. if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL");
  71. $hash->{STATE}="off";
  72. return undef;
  73. }
  74. sub FHT8V_close(@)
  75. {
  76. my ($hash, @a) = @_;
  77. IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X2200",$hash->{NO})) # CUL hack
  78. if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL");
  79. $hash->{STATE}="close";
  80. return undef;
  81. }
  82. sub
  83. FHT8V_assign(@)
  84. {
  85. my ($hash, @a) = @_;
  86. my $na = int(@a);
  87. my $v = 0;
  88. if ( $na > 2 ) {
  89. return "Parameter \"".$a[3]."\" defining offset must be numerical." if ( $a[3] !~ /[0-9]+/ );
  90. $v=int($a[3]);
  91. }
  92. IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X2F%02X",$hash->{NO},$v)) # CUL hack
  93. if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL");
  94. # not sure if this is nessesary but I saw it in the documentation...
  95. IOWrite($hash, "", sprintf("T".$hash->{XMIT}."%02X2600",$hash->{NO},$v)) # CUL hack
  96. if($hash->{IODev} && $hash->{IODev}->{TYPE} eq "CUL");
  97. $hash->{STATE}="assigning";
  98. return undef;
  99. }
  100. sub
  101. FHT8V_Set($@)
  102. {
  103. my ($hash, @a) = @_;
  104. my $na = int(@a);
  105. return "Parameter missing" if ( $na < 2 );
  106. if ( $_[2] eq "valve" ) {
  107. return FHT8V_valve_position(@_);
  108. }
  109. if ( $_[2] eq "open" ) {
  110. return FHT8V_open(@_);
  111. }
  112. if ( $_[2] eq "close" ) {
  113. return FHT8V_close(@_);
  114. }
  115. if ( $_[2] eq "beep" ) {
  116. return FHT8V_beep(@_);
  117. }
  118. if ( $_[2] eq "assign" ) {
  119. return FHT8V_assign(@_);
  120. }
  121. if ( $_[2] eq "off" ) {
  122. return FHT8V_off(@_);
  123. }
  124. return "Could not set undefined parameter \"".$_[2]."\".";
  125. }
  126. #############################
  127. sub
  128. FHT8V_Define($$)
  129. {
  130. my ($hash, $def) = @_;
  131. my @a = split("[ \t][ \t]*", $def);
  132. my $na = int(@a);
  133. my $u = "wrong syntax: define <name> FHT8V housecode " .
  134. "addr";
  135. return $u if( $na < 3 );
  136. return "Define $a[0]: wrong housecode format: specify a 4 digit hex value ".
  137. "or an 8 digit quad value"
  138. if( ($a[2] !~ m/^[a-f0-9]{4}$/i) && ($a[2] !~ m/^[1-4]{8}$/i) );
  139. if ( $na > 3 ) {
  140. return "Define $a[0]: wrong valve address format: specify a 2 digit hex value " .
  141. "or a 4 digit quad value"
  142. if( ($a[3] !~ m/^[a-f0-9]{2}$/i) && ($a[3] !~ m/^[1-4]{4}$/i) );
  143. }
  144. my $housecode = $a[2];
  145. $housecode = four2hex($housecode,4) if (length($housecode) == 8);
  146. my $valve_number = 1;
  147. if ( $na > 3 ) {
  148. my $valve_number = $a[3];
  149. $valve_number = four2hex($valve_number,2) if (length($valve_number) == 4);
  150. }
  151. $hash->{XMIT} = lc($housecode);
  152. $hash->{NO} = lc($valve_number);
  153. my $code = "$housecode $valve_number";
  154. my $ncode = 1;
  155. my $name = $a[0];
  156. $hash->{CODE}{$ncode++} = $code;
  157. $defptr{$code}{$name} = $hash;
  158. for(my $i = 4; $i < int(@a); $i += 2) {
  159. return "No address specified for $a[$i]" if($i == int(@a)-1);
  160. $a[$i] = lc($a[$i]);
  161. if($a[$i] eq "fg") {
  162. return "Bad fg address for $name, see the doc"
  163. if( ($a[$i+1] !~ m/^f[a-f0-9]$/) && ($a[$i+1] !~ m/^44[1-4][1-4]$/));
  164. } elsif($a[$i] eq "lm") {
  165. return "Bad lm address for $name, see the doc"
  166. if( ($a[$i+1] !~ m/^[a-f0-9]f$/) && ($a[$i+1] !~ m/^[1-4][1-4]44$/));
  167. } elsif($a[$i] eq "gm") {
  168. return "Bad gm address for $name, must be ff"
  169. if( ($a[$i+1] ne "ff") && ($a[$i+1] ne "4444"));
  170. } else {
  171. return $u;
  172. }
  173. my $grpcode = $a[$i+1];
  174. if (length($grpcode) == 4) {
  175. $grpcode = four2hex($grpcode,2);
  176. }
  177. $code = "$housecode $grpcode";
  178. $hash->{CODE}{$ncode++} = $code;
  179. $defptr{$code}{$name} = $hash;
  180. }
  181. $hash->{TYPE}="FHT8V";
  182. AssignIoPort($hash);
  183. }
  184. #############################
  185. sub
  186. FHT8V_Undef($$)
  187. {
  188. my ($hash, $name) = @_;
  189. foreach my $c (keys %{ $hash->{CODE} } ) {
  190. $c = $hash->{CODE}{$c};
  191. # As after a rename the $name my be different from the $defptr{$c}{$n}
  192. # we look for the hash.
  193. foreach my $dname (keys %{ $defptr{$c} }) {
  194. delete($defptr{$c}{$dname}) if($defptr{$c}{$dname} == $hash);
  195. }
  196. }
  197. return undef;
  198. }
  199. 1;