| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- # $Id: 51_BBB_BMP180.pm 4929 2014-02-15 03:26:20Z betateilchen $
- ##############################################################################
- #
- # 51_BBB_BMP180.pm
- #
- # An FHEM Perl module to retrieve pressure data from a BMP085/BMP180
- # sensor connected to I2C bus
- #
- # Copyright: betateilchen ®
- # e-mail : fhem.development@betateilchen.de
- #
- # This file is part of fhem.
- #
- # Fhem is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 2 of the License, or
- # (at your option) any later version.
- #
- # Fhem is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with fhem. If not, see <http://www.gnu.org/licenses/>.
- #
- ##############################################################################
- package main;
- use strict;
- use warnings;
- use feature qw/say switch/;
- use Time::HiRes qw(gettimeofday);
- sub BBB_BMP180_Initialize($){
- my ($hash) = @_;
- $hash->{DefFn} = "BBB_BMP180_Define";
- $hash->{UndefFn} = "BBB_BMP180_Undefine";
- $hash->{GetFn} = "BBB_BMP180_Get";
- $hash->{AttrFn} = "BBB_BMP180_Attr";
- $hash->{NotifyFn} = "BBB_BMP180_Notify";
- $hash->{ShutdownFn} = "BBB_BMP180_Shutdown";
- $hash->{AttrList} = "bbbRoundPressure:0,1 ".
- "bbbRoundTemperature:0,1 ".
- "bbbInterval ".
- $readingFnAttributes;
- }
- sub BBB_BMP180_Define($$){
- my ($hash, $def) = @_;
- my $name = $hash->{NAME};
- my @a = split("[ \t][ \t]*", $def);
- Log3($name, 3, "BBB_BMP180 $name: created");
- readingsSingleUpdate($hash, "state", "active",1);
- $hash->{helper}{i2cbus} = '1';
- $hash->{helper}{i2cbus} = $a[2] if(defined($a[2]));
- # check sensor presence
- my $bmpTest = '/sys/bus/i2c/drivers/bmp085/'.$hash->{helper}{i2cbus}.'-0077/pressure0_input';
- return 'BBB_BMP180: sensor not found!' unless -e $bmpTest;
- $bmpTest = '/sys/bus/i2c/drivers/bmp085/'.$hash->{helper}{i2cbus}.'-0077/temp0_input';
- return 'BBB_BMP180: sensor not found!' unless -e $bmpTest;
- if( $init_done ) {
- delete $modules{openweathermap}->{NotifyFn};
- bbb_getValues($hash,0);
- } else {
- readingsSingleUpdate($hash, "state", "defined",1);
- }
- return undef;
- }
- sub BBB_BMP180_Undefine($$){
- my($hash, $name) = @_;
- RemoveInternalTimer($hash);
- return;
- }
- sub BBB_BMP180_Shutdown($) {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- Log3 ($name,4,"BBB_BMP180 $name: shutdown requested");
- return undef;
- }
- sub BBB_BMP180_Get($@){
- my ($hash, @a) = @_;
- my $name = $hash->{NAME};
- my ($cmd) = $a[1];
- my $usage = "Unknown argument $cmd, choose one of readValues:noArg";
- return $usage if($cmd eq "?");
- given($cmd) {
-
- when("readValues") {
- bbb_getValues($hash,1);
- }
-
- default {return}
- }
- return;
- }
- sub BBB_BMP180_Attr($@){
- my @a = @_;
- my $hash = $defs{$a[1]};
- my (undef, $name, $attrName, $attrValue) = @a;
- given($attrName){
- when("bbbInterval"){
- RemoveInternalTimer($hash);
- my $next = gettimeofday()+$attrValue;
- InternalTimer($next, "bbb_getValues", $hash, 0);
- break;
- }
- default {$attr{$name}{$attrName} = $attrValue;}
- }
- return "";
- }
- sub BBB_BMP180_Notify($$) {
- my ($hash,$dev) = @_;
- if( grep(m/^INITIALIZED$/, @{$dev->{CHANGED}}) ) {
- delete $modules{BBB_BMP180}->{NotifyFn};
- foreach my $d (keys %defs) {
- next if($defs{$d}{TYPE} ne "openweathermap");
- bbb_getValues($hash,0);
- }
- }
- }
- sub bbb_getValues($$){
- my ($hash,$local) = @_;
- my $name = $hash->{NAME};
- my $a = AttrVal('global','altitude',undef);
- my $t = bbb_temp($hash);
- my $pa = bbb_absDruck($hash);
- my $pr = bbb_relDruck($hash,$a) if(defined($a));
- if(AttrVal($name,'bbbRoundPressure',undef)){
- $pa = sprintf("%.0f", $pa);
- $pr = sprintf("%.0f", $pr) if(defined($a));
- } else {
- $pa = sprintf("%.2f", $pa);
- $pr = sprintf("%.2f", $pr) if(defined($a));
- }
- if(AttrVal($name,'bbbRoundTemperature',undef)){
- $t = sprintf("%.0f", $t);
- } else {
- $t = sprintf("%.1f", $t);
- }
- my $s = "T: $t P: $pa";
- $s .= " P-nn: $pr" if(defined($a));
- readingsBeginUpdate($hash);
- readingsBulkUpdate($hash, 'temperature', $t);
- readingsBulkUpdate($hash, 'pressure', $pa);
- readingsBulkUpdate($hash, 'pressure-nn', $pr) if(defined($a));
- readingsBulkUpdate($hash, 'state', $s) if(defined($a));
- readingsEndUpdate($hash, 1);
- my $next = gettimeofday()+AttrVal($name,'bbbInterval',300);
- InternalTimer($next, "bbb_getValues", $hash, 0) unless $local;
- return;
- }
- sub bbb_temp($){
- my ($hash) = @_;
- my $bmpT = '/sys/bus/i2c/drivers/bmp085/'.$hash->{helper}{i2cbus}.'-0077/temp0_input';
- my $temp;
- open (IN,"<$bmpT");
- while (<IN>){
- $temp = $_;
- last;
- }
- close IN;
- $temp = substr($temp,0,length($temp)-1);
- return $temp/10;
- }
- sub bbb_absDruck($){
- my ($hash) = @_;
- my $bmpP = '/sys/bus/i2c/drivers/bmp085/'.$hash->{helper}{i2cbus}.'-0077/pressure0_input';
- my $p;
- open (IN,"<$bmpP");
- while (<IN>){
- $p = $_;
- last;
- }
- close IN;
- $p = substr($p,0,length($p)-1);
- return $p/100;
- }
- sub bbb_relDruck($$){
- my($hash,$Alti) = @_;
- my $Pa = bbb_absDruck($hash);
- my $Temp = bbb_temp($hash);
- # Konstanten
- my $g0 = 9.80665;
- my $R = 287.05;
- my $T = 273.15;
- my $Ch = 0.12;
- my $a = 0.065;
- my $E = 0;
- if($Temp < 9.1){
- $E = 5.6402*(-0.0916 + exp(0.06 * $Temp));
- }
- else {
- $E = 18.2194*(1.0463 - exp(-0.0666 * $Temp));
- }
- my $xp = $Alti * $g0 / ($R*($T+$Temp + $Ch*$E + $a*$Alti/2));
- my $Pr = $Pa*exp($xp);
- return $Pr;
- }
- 1;
- =pod
- not to be translated
- =begin html
- <a name="BBB_BMP180"></a>
- <h3>BBB_BMP180</h3>
- <ul>
- <b>Prerequesits</b>
- <ul>
- <br/>
- Module was developed for use with Beaglebone Black.<br/><br/>
- To create the device, run the following command on system console:<br/><br/>
- <code>echo bmp085 0x77 > /sys/class/i2c-adapter/i2c-1/new_device</code><br/><br/>
- To check if successful:<br/><br/>
- <code>
- dmesg | grep bmp<br/>
- [ 76.989945] i2c i2c-1: new_device: Instantiated device bmp085 at 0x77<br/>
- [ 77.040606] bmp085 1-0077: Successfully initialized bmp085!<br/>
- </code>
- <br/>
- </ul>
- <br/><br/>
-
- <a name="BBB_BMP180define"></a>
- <b>Define</b>
- <ul>
- <br/>
- <code>define <name> BBB_BMP180 [bus]</code>
- <br/><br/>
- This module provides air pressure measurement by a BMP180 sensor connected to I2C bus.<br/>
- Optional parameter [bus] defines number of I2C-bus in your hardware (default = 1).<br/>
- <br/>
- </ul>
- <br/><br/>
- <a name="BBB_BMP180set"></a>
- <b>Set-Commands</b><br/>
- <ul>
- <br/>
- No set commands implemented.<br/>
- <br/>
- </ul>
- <br/><br/>
- <a name="BBB_BMP180get"></a>
- <b>Get-Commands</b><br/>
- <ul>
- <br/>
- <code>get <name> readValues</code>
- <br/><br/>
- <ul>
- Update all values immediately.
- </ul>
- </ul>
- <br/><br/>
- <a name="BBB_BMP180attr"></a>
- <b>Attributes</b><br/><br/>
- <ul>
- <li><b>bbbInterval</b> - Interval for readings update (default = 300 seconds)</li>
- <li><b>bbbRoundPressure</b> - If set to 1 = pressure value will be presented without decimals (default = 2 decimals)</li>
- <li><b>bbbRoundTemperatue</b> - If set to 1 = temperature value will be presented without decimals (default = 1 decimal)</li>
- <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
- </ul>
- <br/><br/>
- <b>Generated Readings/Events:</b>
- <br/><br/>
- <ul>
- <li><b>temperature</b> - temperature at sensor</li>
- <li><b>pressure</b> - pressure (absolute)</li>
- <li><b>pressure-nn</b> - pressure (relative), global attribute altitude needed for calculation</li>
- </ul>
- <br/><br/>
- <b>Author's notes</b><br/><br/>
- <ul>
- <li>Have fun!</li><br/>
- </ul>
- </ul>
- =end html
- =begin html_DE
- <a name="BBB_BMP180"></a>
- <h3>BBB_BMP180</h3>
- <ul>
- Sorry, keine deutsche Dokumentation vorhanden.<br/><br/>
- Die englische Doku gibt es hier: <a href='http://fhem.de/commandref.html#BBB_BMP180'>BBB_BMP180</a><br/>
- </ul>
- =end html_DE
- =cut
|