51_BBB_BMP180.pm 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. # $Id: 51_BBB_BMP180.pm 4929 2014-02-15 03:26:20Z betateilchen $
  2. ##############################################################################
  3. #
  4. # 51_BBB_BMP180.pm
  5. #
  6. # An FHEM Perl module to retrieve pressure data from a BMP085/BMP180
  7. # sensor connected to I2C bus
  8. #
  9. # Copyright: betateilchen ®
  10. # e-mail : fhem.development@betateilchen.de
  11. #
  12. # This file is part of fhem.
  13. #
  14. # Fhem is free software: you can redistribute it and/or modify
  15. # it under the terms of the GNU General Public License as published by
  16. # the Free Software Foundation, either version 2 of the License, or
  17. # (at your option) any later version.
  18. #
  19. # Fhem is distributed in the hope that it will be useful,
  20. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. # GNU General Public License for more details.
  23. #
  24. # You should have received a copy of the GNU General Public License
  25. # along with fhem. If not, see <http://www.gnu.org/licenses/>.
  26. #
  27. ##############################################################################
  28. package main;
  29. use strict;
  30. use warnings;
  31. use feature qw/say switch/;
  32. use Time::HiRes qw(gettimeofday);
  33. sub BBB_BMP180_Initialize($){
  34. my ($hash) = @_;
  35. $hash->{DefFn} = "BBB_BMP180_Define";
  36. $hash->{UndefFn} = "BBB_BMP180_Undefine";
  37. $hash->{GetFn} = "BBB_BMP180_Get";
  38. $hash->{AttrFn} = "BBB_BMP180_Attr";
  39. $hash->{NotifyFn} = "BBB_BMP180_Notify";
  40. $hash->{ShutdownFn} = "BBB_BMP180_Shutdown";
  41. $hash->{AttrList} = "bbbRoundPressure:0,1 ".
  42. "bbbRoundTemperature:0,1 ".
  43. "bbbInterval ".
  44. $readingFnAttributes;
  45. }
  46. sub BBB_BMP180_Define($$){
  47. my ($hash, $def) = @_;
  48. my $name = $hash->{NAME};
  49. my @a = split("[ \t][ \t]*", $def);
  50. Log3($name, 3, "BBB_BMP180 $name: created");
  51. readingsSingleUpdate($hash, "state", "active",1);
  52. $hash->{helper}{i2cbus} = '1';
  53. $hash->{helper}{i2cbus} = $a[2] if(defined($a[2]));
  54. # check sensor presence
  55. my $bmpTest = '/sys/bus/i2c/drivers/bmp085/'.$hash->{helper}{i2cbus}.'-0077/pressure0_input';
  56. return 'BBB_BMP180: sensor not found!' unless -e $bmpTest;
  57. $bmpTest = '/sys/bus/i2c/drivers/bmp085/'.$hash->{helper}{i2cbus}.'-0077/temp0_input';
  58. return 'BBB_BMP180: sensor not found!' unless -e $bmpTest;
  59. if( $init_done ) {
  60. delete $modules{openweathermap}->{NotifyFn};
  61. bbb_getValues($hash,0);
  62. } else {
  63. readingsSingleUpdate($hash, "state", "defined",1);
  64. }
  65. return undef;
  66. }
  67. sub BBB_BMP180_Undefine($$){
  68. my($hash, $name) = @_;
  69. RemoveInternalTimer($hash);
  70. return;
  71. }
  72. sub BBB_BMP180_Shutdown($) {
  73. my ($hash) = @_;
  74. my $name = $hash->{NAME};
  75. Log3 ($name,4,"BBB_BMP180 $name: shutdown requested");
  76. return undef;
  77. }
  78. sub BBB_BMP180_Get($@){
  79. my ($hash, @a) = @_;
  80. my $name = $hash->{NAME};
  81. my ($cmd) = $a[1];
  82. my $usage = "Unknown argument $cmd, choose one of readValues:noArg";
  83. return $usage if($cmd eq "?");
  84. given($cmd) {
  85. when("readValues") {
  86. bbb_getValues($hash,1);
  87. }
  88. default {return}
  89. }
  90. return;
  91. }
  92. sub BBB_BMP180_Attr($@){
  93. my @a = @_;
  94. my $hash = $defs{$a[1]};
  95. my (undef, $name, $attrName, $attrValue) = @a;
  96. given($attrName){
  97. when("bbbInterval"){
  98. RemoveInternalTimer($hash);
  99. my $next = gettimeofday()+$attrValue;
  100. InternalTimer($next, "bbb_getValues", $hash, 0);
  101. break;
  102. }
  103. default {$attr{$name}{$attrName} = $attrValue;}
  104. }
  105. return "";
  106. }
  107. sub BBB_BMP180_Notify($$) {
  108. my ($hash,$dev) = @_;
  109. if( grep(m/^INITIALIZED$/, @{$dev->{CHANGED}}) ) {
  110. delete $modules{BBB_BMP180}->{NotifyFn};
  111. foreach my $d (keys %defs) {
  112. next if($defs{$d}{TYPE} ne "openweathermap");
  113. bbb_getValues($hash,0);
  114. }
  115. }
  116. }
  117. sub bbb_getValues($$){
  118. my ($hash,$local) = @_;
  119. my $name = $hash->{NAME};
  120. my $a = AttrVal('global','altitude',undef);
  121. my $t = bbb_temp($hash);
  122. my $pa = bbb_absDruck($hash);
  123. my $pr = bbb_relDruck($hash,$a) if(defined($a));
  124. if(AttrVal($name,'bbbRoundPressure',undef)){
  125. $pa = sprintf("%.0f", $pa);
  126. $pr = sprintf("%.0f", $pr) if(defined($a));
  127. } else {
  128. $pa = sprintf("%.2f", $pa);
  129. $pr = sprintf("%.2f", $pr) if(defined($a));
  130. }
  131. if(AttrVal($name,'bbbRoundTemperature',undef)){
  132. $t = sprintf("%.0f", $t);
  133. } else {
  134. $t = sprintf("%.1f", $t);
  135. }
  136. my $s = "T: $t P: $pa";
  137. $s .= " P-nn: $pr" if(defined($a));
  138. readingsBeginUpdate($hash);
  139. readingsBulkUpdate($hash, 'temperature', $t);
  140. readingsBulkUpdate($hash, 'pressure', $pa);
  141. readingsBulkUpdate($hash, 'pressure-nn', $pr) if(defined($a));
  142. readingsBulkUpdate($hash, 'state', $s) if(defined($a));
  143. readingsEndUpdate($hash, 1);
  144. my $next = gettimeofday()+AttrVal($name,'bbbInterval',300);
  145. InternalTimer($next, "bbb_getValues", $hash, 0) unless $local;
  146. return;
  147. }
  148. sub bbb_temp($){
  149. my ($hash) = @_;
  150. my $bmpT = '/sys/bus/i2c/drivers/bmp085/'.$hash->{helper}{i2cbus}.'-0077/temp0_input';
  151. my $temp;
  152. open (IN,"<$bmpT");
  153. while (<IN>){
  154. $temp = $_;
  155. last;
  156. }
  157. close IN;
  158. $temp = substr($temp,0,length($temp)-1);
  159. return $temp/10;
  160. }
  161. sub bbb_absDruck($){
  162. my ($hash) = @_;
  163. my $bmpP = '/sys/bus/i2c/drivers/bmp085/'.$hash->{helper}{i2cbus}.'-0077/pressure0_input';
  164. my $p;
  165. open (IN,"<$bmpP");
  166. while (<IN>){
  167. $p = $_;
  168. last;
  169. }
  170. close IN;
  171. $p = substr($p,0,length($p)-1);
  172. return $p/100;
  173. }
  174. sub bbb_relDruck($$){
  175. my($hash,$Alti) = @_;
  176. my $Pa = bbb_absDruck($hash);
  177. my $Temp = bbb_temp($hash);
  178. # Konstanten
  179. my $g0 = 9.80665;
  180. my $R = 287.05;
  181. my $T = 273.15;
  182. my $Ch = 0.12;
  183. my $a = 0.065;
  184. my $E = 0;
  185. if($Temp < 9.1){
  186. $E = 5.6402*(-0.0916 + exp(0.06 * $Temp));
  187. }
  188. else {
  189. $E = 18.2194*(1.0463 - exp(-0.0666 * $Temp));
  190. }
  191. my $xp = $Alti * $g0 / ($R*($T+$Temp + $Ch*$E + $a*$Alti/2));
  192. my $Pr = $Pa*exp($xp);
  193. return $Pr;
  194. }
  195. 1;
  196. =pod
  197. not to be translated
  198. =begin html
  199. <a name="BBB_BMP180"></a>
  200. <h3>BBB_BMP180</h3>
  201. <ul>
  202. <b>Prerequesits</b>
  203. <ul>
  204. <br/>
  205. Module was developed for use with Beaglebone Black.<br/><br/>
  206. To create the device, run the following command on system console:<br/><br/>
  207. <code>echo bmp085 0x77 > /sys/class/i2c-adapter/i2c-1/new_device</code><br/><br/>
  208. To check if successful:<br/><br/>
  209. <code>
  210. dmesg | grep bmp<br/>
  211. [ 76.989945] i2c i2c-1: new_device: Instantiated device bmp085 at 0x77<br/>
  212. [ 77.040606] bmp085 1-0077: Successfully initialized bmp085!<br/>
  213. </code>
  214. <br/>
  215. </ul>
  216. <br/><br/>
  217. <a name="BBB_BMP180define"></a>
  218. <b>Define</b>
  219. <ul>
  220. <br/>
  221. <code>define &lt;name&gt; BBB_BMP180 [bus]</code>
  222. <br/><br/>
  223. This module provides air pressure measurement by a BMP180 sensor connected to I2C bus.<br/>
  224. Optional parameter [bus] defines number of I2C-bus in your hardware (default = 1).<br/>
  225. <br/>
  226. </ul>
  227. <br/><br/>
  228. <a name="BBB_BMP180set"></a>
  229. <b>Set-Commands</b><br/>
  230. <ul>
  231. <br/>
  232. No set commands implemented.<br/>
  233. <br/>
  234. </ul>
  235. <br/><br/>
  236. <a name="BBB_BMP180get"></a>
  237. <b>Get-Commands</b><br/>
  238. <ul>
  239. <br/>
  240. <code>get &lt;name&gt; readValues</code>
  241. <br/><br/>
  242. <ul>
  243. Update all values immediately.
  244. </ul>
  245. </ul>
  246. <br/><br/>
  247. <a name="BBB_BMP180attr"></a>
  248. <b>Attributes</b><br/><br/>
  249. <ul>
  250. <li><b>bbbInterval</b> - Interval for readings update (default = 300 seconds)</li>
  251. <li><b>bbbRoundPressure</b> - If set to 1 = pressure value will be presented without decimals (default = 2 decimals)</li>
  252. <li><b>bbbRoundTemperatue</b> - If set to 1 = temperature value will be presented without decimals (default = 1 decimal)</li>
  253. <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
  254. </ul>
  255. <br/><br/>
  256. <b>Generated Readings/Events:</b>
  257. <br/><br/>
  258. <ul>
  259. <li><b>temperature</b> - temperature at sensor</li>
  260. <li><b>pressure</b> - pressure (absolute)</li>
  261. <li><b>pressure-nn</b> - pressure (relative), global attribute altitude needed for calculation</li>
  262. </ul>
  263. <br/><br/>
  264. <b>Author's notes</b><br/><br/>
  265. <ul>
  266. <li>Have fun!</li><br/>
  267. </ul>
  268. </ul>
  269. =end html
  270. =begin html_DE
  271. <a name="BBB_BMP180"></a>
  272. <h3>BBB_BMP180</h3>
  273. <ul>
  274. Sorry, keine deutsche Dokumentation vorhanden.<br/><br/>
  275. Die englische Doku gibt es hier: <a href='http://fhem.de/commandref.html#BBB_BMP180'>BBB_BMP180</a><br/>
  276. </ul>
  277. =end html_DE
  278. =cut