#!/usr/bin/env perl use strict; use Device::SerialPort; sub get_line($) { my $port = shift; my $ret = ""; while (1) { my ( $count, $byte ) = $port->read(1); if ( $count > 0 ) { $ret .= $byte; return $ret if $byte eq "\n"; } else { return $ret; } } } #from W. Wagner and A. Pruß:" The IAPWS Formulation 1995 for the Thermodynamic Properties of Ordinary Water Substance for General and Scientific Use ", Journal of Physical and Chemical Reference Data, June 2002 ,Volume 31, Issue 2, pp. 387535 sub pws($) { my $t = shift; my $tc = 647.096; # critical T in K my $pc = 22064000; # critical P in Pa; my @c = ( -7.85951783, 1.84408259, -11.7866497, 22.6807411, -15.9618719, 1.80122502 ); $t += 273.15; #into K my $v = 1. - ( $t / $tc ); my $pn = $c[0] * $v; $pn += $c[1] * ( $v**1.5 ); $pn += $c[2] * ( $v**3 ); $pn += $c[3] * ( $v**3.5 ); $pn += $c[4] * ( $v**4 ); $pn += $c[5] * ( $v**7.5 ); $pn *= $tc / $t; return $pc * exp($pn); } sub rh_to_pw($$) { my ( $t, $h ) = @_; return pws($t) * ( $h / 100. ); } sub pw_to_rh($$) { my ( $t, $pw ) = @_; return ( $pw / pws($t) ) * 100.; } sub rh_to_ah($$) { my ( $t, $h ) = @_; my $c = 0.00216679; #kg K /J return $c * rh_to_pw( $t, $h ) / ( $t + 273.15 ); } sub ah_to_rh($$) { my ( $t, $ah ) = @_; my $c = 0.00216679; #kg K /J return pw_to_rh( $t, $ah * ( $t + 273.15 ) / $c ); } sub fixup($$) { my ( $t, $h ) = @_; my $ah = rh_to_ah( $t, $h ); my $ct = $t - 1.15; my $ch = ah_to_rh( $ct, $ah ); # print "($t,$h) => ($ct,$ch)\n"; return ( $ct, $ch ); } sub display($$$$$$) { my ( $t, $h, $show_t, $show_h, $int, $mrtg ) = @_; if ( $int or $mrtg ) { $t = int( $t * 1000 ); $h = int( $h * 10 ); } if ($mrtg) { if ($show_t) { print "$t\n"; print "0\n"; print "long time\n"; print "temperature\n"; } if ($show_h) { print "$t\n"; print "0\n"; print "long time\n"; print "humidity\n"; } } else { print "$t\n" if $show_t; print "$h\n" if $show_h; } } my $keypad_port = "/dev/ttyS1"; my $keypad = new Device::SerialPort($keypad_port) || die "can't open $keypad_port\n"; $keypad->baudrate(115200); $keypad->parity("none"); $keypad->databits(8); $keypad->stopbits(1); $keypad->stty_icanon(0); $keypad->read_char_time(0); $keypad->read_const_time(1000); my $mrtg = 0; my $temp = 0; my $humid = 0; my $int = 0; for my $opt (@ARGV) { $mrtg = 1 if $opt eq '-m'; $temp = 1 if $opt eq '-t'; $humid = 1 if $opt eq '-h'; $int = 1 if $opt eq '-i'; } for ( my $tries = 0 ; $tries < 4 ; ++$tries ) { my $line = get_line($keypad); chomp $line; chomp $line; if ( $line =~ /\$SNTHD,([-.0-9]+),([-.0-9]+)/ ) { my ( $t, $h ) = fixup( $1, $2 ); display( $t, $h, $temp, $humid, $int, $mrtg ); exit 0; } sleep(int(rand(4))); } exit 1;