00_TAHR.pm 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. ###############################################
  2. # Sample fhem module, one-level approach, controlling a single device like a
  3. # directly attached heating regulator.
  4. # The alternative is a two level approach, where a physical device like a CUL
  5. # is a bridge to a large number of logical devices (like FS20 actors, S300
  6. # sensors, etc)
  7. package main;
  8. use strict;
  9. use warnings;
  10. use Time::HiRes qw(gettimeofday);
  11. sub TAHR_Read($);
  12. sub TAHR_Ready($);
  13. sub TAHR_setbits($$);
  14. sub
  15. TAHR_Initialize($)
  16. {
  17. my ($hash) = @_;
  18. require "$attr{global}{modpath}/FHEM/DevIo.pm";
  19. $hash->{ReadFn} = "TAHR_Read";
  20. $hash->{ReadyFn} = "TAHR_Ready";
  21. $hash->{DefFn} = "TAHR_Define";
  22. $hash->{UndefFn} = "TAHR_Undef";
  23. $hash->{SetFn} = "TAHR_Set";
  24. $hash->{AttrList}= "loglevel:0,1,2,3,4,5,6 ".
  25. "do_not_notify:1,0 ignore:1,0 dummy:1,0 showtime:1,0 ".
  26. $readingFnAttributes;
  27. }
  28. #####################################
  29. sub
  30. TAHR_Define($$)
  31. {
  32. my ($hash, $def) = @_;
  33. my @a = split("[ \t][ \t]*", $def);
  34. return "wrong syntax: define <name> TAHR [devicename|none]"
  35. if(@a != 3);
  36. DevIo_CloseDev($hash);
  37. my $name = $a[0];
  38. my $dev = $a[2];
  39. if($dev eq "none") {
  40. Log 1, "TAHR device is none, commands will be echoed only";
  41. return undef;
  42. }
  43. $hash->{PARTIAL} = "";
  44. $hash->{DeviceName} = $dev;
  45. my $ret = DevIo_OpenDev($hash, 0, "TAHR_InitFn");
  46. return $ret;
  47. }
  48. #####################################
  49. sub
  50. TAHR_Undef($$)
  51. {
  52. my ($hash, $arg) = @_;
  53. DevIo_CloseDev($hash);
  54. RemoveInternalTimer($hash);
  55. return undef;
  56. }
  57. #####################################
  58. sub
  59. TAHR_Set($@)
  60. {
  61. my ($hash, @a) = @_;
  62. my %tahr_sets = (
  63. "ww_soll" => "0C07656565%02x6565",
  64. "ww_betriebsart" => "0C0E%02x6565656565",
  65. );
  66. return "\"set TAHR\" needs at least an argument" if(@a < 2);
  67. my $cmd = $tahr_sets{$a[1]};
  68. if(!defined($cmd)) {
  69. return SetExtensions($hash, join(" ", sort keys %tahr_sets), @a);
  70. }
  71. # FIXME
  72. DevIo_SimpleWrite($hash, sprintf($cmd, $a[2]));
  73. return undef;
  74. }
  75. #####################################
  76. # called from the global loop, when the select for hash->{FD} reports data
  77. sub
  78. TAHR_Read($)
  79. {
  80. my ($hash) = @_;
  81. my $name = $hash->{NAME};
  82. my ($data, $crc);
  83. my $ll5 = GetLogLevel($name,5);
  84. my $buf = DevIo_SimpleRead($hash);
  85. return "" if(!defined($buf));
  86. $buf = unpack('H*', $buf);
  87. Log $ll5, "RAW: $buf";
  88. $buf = $hash->{PARTIAL} . $buf;
  89. while($buf =~ m/^(.*?)\n(.*)$/) {
  90. my $line = $1;
  91. $buf = $2;
  92. ######################################
  93. # Analyze the data
  94. # FIXME
  95. Log $ll5, "LINE: $line";
  96. readingsSingleUpdate($hash, "LINE", $line, 1);
  97. }
  98. $hash->{PARTIAL} = $buf;
  99. }
  100. #####################################
  101. sub
  102. TAHR_Ready($)
  103. {
  104. my ($hash) = @_;
  105. return DevIo_OpenDev($hash, 1, "TAHR_InitFn")
  106. if($hash->{STATE} eq "disconnected");
  107. # This is relevant for windows/USB only
  108. my $po = $hash->{USBDev};
  109. my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags) = $po->status;
  110. return ($InBytes>0);
  111. }
  112. sub
  113. TAHR_InitFn($)
  114. {
  115. my $hash = shift;
  116. my $name = $hash->{NAME};
  117. DevIo_SetHwHandshake($hash) if($hash->{USBDev});
  118. $hash->{PARTIAL} = "";
  119. $hash->{STATE} = "Initialized";
  120. return undef;
  121. }
  122. 1;