88_IPWE.pm 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. package main;
  2. ##############################################
  3. # 88_IPWE.pm
  4. # Modul for FHEM
  5. #
  6. # contributed by thomas dressler 2008
  7. # $Id: 88_IPWE.pm 2076 2012-11-04 13:49:43Z rudolfkoenig $
  8. use strict;
  9. use warnings;
  10. use IO::Socket::INET;
  11. use vars qw {%attr $init_done}; #make komodo happy
  12. sub Log($$);
  13. #####################################
  14. sub
  15. IPWE_Initialize($)
  16. {
  17. my ($hash) = @_;
  18. # Consumer
  19. $hash->{DefFn} = "IPWE_Define";
  20. $hash->{GetFn} = "IPWE_Get";
  21. $hash->{AttrList}= "model:ipwe delay loglevel:0,1,2,3,4,5,6";
  22. }
  23. #####################################
  24. sub
  25. IPWE_Define($$)
  26. {
  27. my ($hash, $def) = @_;
  28. my $name=$hash->{NAME};
  29. my @a = split("[ \t][ \t]*", $def);
  30. Log 5, "IPWE Define: $a[0] $a[1] $a[2] $a[3]";
  31. return "Define the host as a parameter i.e. ipwe" if(@a < 3);
  32. my $host = $a[2];
  33. my $delay=$a[3];
  34. $attr{$name}{delay}=$delay if $delay;
  35. Log 1, "ipwe device is none, commands will be echoed only" if($host eq "none");
  36. my $socket = IO::Socket::INET->new(PeerAddr=>$host,
  37. PeerPort=>80, #http
  38. timeout=>2,
  39. blocking=>1
  40. );
  41. if (!$socket) {
  42. $hash->{STATE} = "error opening device";
  43. Log 1,"$name: Error opening Connection to $host";
  44. return "Can't Connect to $host -> $@ ( $!)\n";
  45. }
  46. $socket->close;
  47. $hash->{Host} = $host;
  48. $hash->{STATE} = "Initialized";
  49. InternalTimer(gettimeofday()+$delay, "IPWE_GetStatus", $hash, 0);
  50. return undef;
  51. }
  52. sub IPWE_Get($@)
  53. {
  54. my ($hash, @a) = @_;
  55. return "argument is missing" if(int(@a) != 2);
  56. my $msg;
  57. $hash->{LOCAL} = 1;
  58. my $v = IPWE_GetStatus($hash);
  59. delete $hash->{LOCAL};
  60. my @data=split (/\n/, $v);
  61. if($a[1] eq "status") {
  62. $msg= "$a[0] $a[1] =>".$/."$v";
  63. }else {
  64. my ($l)= grep {/$a[1]/}@data;
  65. chop($l);
  66. $msg="$a[0] $a[1] =>$l";
  67. }
  68. $msg="$a[0]: Unknown get command $a[1]" if (!$msg);
  69. return $msg;
  70. }
  71. #####################################
  72. sub
  73. IPWE_GetStatus($)
  74. {
  75. my ($hash) = @_;
  76. my $buf;
  77. Log 5, "IPWE_GetStatus";
  78. my $name = $hash->{NAME};
  79. my $host = $hash->{Host};
  80. my $text='';
  81. my $alldata='';
  82. my $delay=$attr{$name}{delay}||300;
  83. InternalTimer(gettimeofday()+$delay, "IPWE_GetStatus", $hash, 0);
  84. my $socket = IO::Socket::INET->new(PeerAddr=>$host,
  85. PeerPort=>80, #http
  86. timeout=>2,
  87. blocking=>1
  88. );
  89. if (!$socket) {
  90. $hash->{STATE} = "error opening device";
  91. Log 1,"$name: Error opening Connection to $host";
  92. return "Can't Connect to $host -> $@ ( $!)\n";
  93. }
  94. Log 5, "$name: Connected to $host";
  95. $socket->autoflush(1);
  96. $socket->write("GET /ipwe.cgi HTTP/1.0\r\n");
  97. my @lines=$socket->getlines();
  98. close $socket;
  99. Log 5,"$name: Data received";
  100. my $allines=join('',@lines);
  101. my (@tables)= ($allines=~m#<tbody>(?:(?!<tbody>).)*</tbody>#sgi);
  102. my ($datatable)=grep{/Sensortyp/} @tables;
  103. my (@rows)=($datatable=~m#<tr>(?:(?!<tr>).)*</tr>#sgi);
  104. foreach my $l(@rows) {
  105. next if ($l=~/Sensortyp/); #headline
  106. my ($typ,$id,$sensor,$temp,$hum,$wind,$rain)=($l=~m#<td.*?>(.*?)<br></td>#sgi);
  107. next if ($typ=~/^\s+$/);
  108. $text= "Typ: $typ, ID: $id, Name $sensor, T: $temp H: $hum";
  109. if ($id == 8) {
  110. $text.= ",W: $wind, R: $rain";
  111. }
  112. Log 5,"$name: $text";
  113. if (!$hash->{local}){
  114. $hash->{CHANGED}[0] = $text;
  115. $hash->{READINGS}{$sensor}{TIME} = TimeNow();
  116. $hash->{READINGS}{$sensor}{VAL} = $text;;
  117. DoTrigger($name, undef) if($init_done);
  118. }
  119. $alldata.="$text\n";
  120. }
  121. return $alldata;
  122. }
  123. 1;
  124. =pod
  125. =begin html
  126. <a name="IPWE"></a>
  127. <h3>IPWE</h3>
  128. <ul>
  129. <br>
  130. <a name="IPWEdefine"></a>
  131. <b>Define</b>
  132. <ul>
  133. <code>define &lt;name&gt; IPWE &lt;hostname&gt; [&lt;delay&gt;]</code>
  134. <br><br>
  135. Define a IPWE network attached weather data receiver device sold by ELV. Details see <a
  136. href="http://www.elv.de/output/controller.aspx?cid=74&detail=10&detail2=21508">here</a>.
  137. It's intended to receive the same sensors as WS300 (8 T/H-Sensors and one kombi sensor),
  138. but can be accessed via http and telnet.
  139. <br>
  140. For unknown reason, my try to use the telnet interface was not working neither with raw sockets
  141. nor with Net::Telnet module. Therefore i choosed here the "easy" way
  142. to simple readout the http page and extract all data from the offered table. For this reason this module doesnt
  143. contain any option to configure this device.
  144. <br><br><b>Note:</b> You should give your sensors a name within the web interface, once they a received the first time.
  145. <br>To extract a single sensor simply match for this name or sensor id<br>
  146. <br>
  147. Attributes:
  148. <ul>
  149. <li><code>delay</code>: seconds between read accesses(default 300s)</li>
  150. </ul>
  151. <br>
  152. Example:
  153. <ul>
  154. <code>define ipwe IPWE ipwe1 120</code><br>
  155. </ul>
  156. <ul>
  157. <code>attr ipwe delay 600</code> : 10min between readouts<br>
  158. </ul>
  159. <br>
  160. </ul>
  161. <b>Set</b> <ul>N/A</ul><br>
  162. <a name="IPWEget"></a>
  163. <b>Get</b>
  164. <ul>
  165. <code>get &lt;name&gt; status</code>
  166. <br><br>
  167. Gets actual data from device for sensors with data
  168. <br><br>
  169. <code>get &lt;name&gt; &lt;sensorname&gt; </code>
  170. <br><br>
  171. will grep output from device for this sensorname
  172. <br><br>
  173. </ul>
  174. <a name="IPWEattr"></a>
  175. <b>Attributes</b>
  176. <ul>
  177. <li><a href="#model">model</a> (ipwe)</li>
  178. <li>delay</li>
  179. <li><a href="#loglevel">loglevel</a></li>
  180. </ul>
  181. <br>
  182. </ul>
  183. =end html
  184. =cut