A Banana Pro Weather Logger

weather-logger.sh; process, format and log data.


The Bash script weather-logger.sh is run as a cron job every 15 minutes. In the first block of code below note that I use awk to parse the data from the line of data returned by get_w_data and the Bash built-in printf to round the two decimal data to single decimal. Lo

Local_hPa is the air pressure as measured where I live in hectopascals (hPa) and will have to be converted to air pressure at mean sea level (MSL-hPa). The number of bucket tips (BKT_TIPS) will have to be converted to millimetres of water.

#!/bin/bash
##########################################################################
# /usr/local/weather-logger.sh RM20190503
#
# Run as a cron job every 15 minutes. Add this line to crontab:
# 0,15,30,45 * * * * /usr/local/bin/weather-logger.sh 1> /dev/null 
#
# Used to process and format weather data polled from a LeoStick using 
# /usr/local/bin/get_w_data. This script creates a line of comma
# delimited data and appends it to a .csv file.
#
# Requires: wl_jobs, get_w_data, links, awk, bc
##########################################################################
#
# Config file
. /etc/weather-logger.conf
#
# Get total number of bucket tips from TIP_COUNT and
# parse weather data from  TEMP_DATA file using awk.
Parse_Data()
{
    BKT_TIPS=$(cat $TIP_COUNT)

    TC=$(cat $TEMP_DATA | awk -F "," '{print $1}')
    TC=$(printf "%0.1f" "$TC")
    tc=$(printf "%.0f" "$TC")
    
    Rh=$(cat $TEMP_DATA | awk -F "," '{print $2}')
    Rh=$(printf "%0.1f" "$Rh")
    
    # If temperature is less than 27 degrees heat index
    # will not be valid. Change HEAT_NDX to 0.0.
    tc=$(printf "%.0f" "$TC")
    if [ "$tc" -lt "27" ] || [ "$rh" -lt "40" ]
    	 then
	    HEAT_NDX=0.0
	else
	    HEAT_NDX=$(cat $TEMP_DATA | awk -F "," '{print $3}')
	    HEAT_NDX=$(printf "%0.1f" "$HEAT_NDX")
    fi

    LOCAL_hPa=$(cat $TEMP_DATA | awk -F "," '{print $4}')
}	

I used awk to calculate the dew point using the current temperature (TC) and relative humidity (Rh). To calculate the MSL-hPa add PRSSR_ADJST from weather-logger.conf to LOCAL_hPa. Actual air pressure changes with air temperature but my method is good enough to never be more than 0.5 hPa different to air pressure at an airport 21km away from our home.

When I first started playing with this circuit and poll-weather-data.ino I would occasionally have get_w_data return a "nan" for air pressure so I created that if else statement to get the air pressure from the nearest airport. I believe the problem was due to polling the Leostick immediately after the Leostick polled the sensors and putting a delay (usleep(2000);) in get_w_data seems to have remedied the problem but I'll leave that if else statement there for now.

# Calculate current Dew Point using Humidity and Temperature.
Calc_Dew_Point() 
{
    # Calculate saturation vapour pressure (es)
    es="$(awk -v x=$TC 'BEGIN { print 6.11*10.0^(7.5*x/(237.7+x)) }')"
    # Calculate actual vapour pressure (e)
    e=$(echo "($Rh*$es)/100" | bc -l)
    # Calculate dewpoint temperature (tdc).
    tdc=$(echo "(-430.22+237.7*l($e))/(-l($e)+19.08)" | bc -l)
    DEW_POINT=$(printf "%0.1f" "$tdc")
}
# Adjust local air pressure to mean sea level air pressure
Calc_MSL_hPa()
{
    # If the air pressure is returned as 'nan' use air pressure
    # from Moorabin airport.
    if [ "$LOCAL_hPa" == "nan" ] 
    then
    	MSL_hPa=$(links -anonymous -dump http://reg.bom.gov.au/vic/observations/melbourne.shtml | grep Moorabbin | awk -F "|" '{print $14;}')
    else
		MSL_hPa=$(echo "$LOCAL_hPa+$PRSSR_ADJST" | bc -l)
		MSL_hPa=$(printf "%0.1f" "$MSL_hPa")
    fi
}
	

In this final codeblock there is a function to calculate total amount of rainfall for the period and a function that appends a new line of data to the file weather-data.csv.

Following the function Log_Data(), wl_jobs -p writes a new set of data to the file TEMP_DATA then the above functions are called in order. After all the data is processed and logged the green LED blinks to indicate activity and then the file TIP_COUNT is set back to 0 for the start of a new 15 minute logging period.

# Convert bucket tips to milimetres of rainfall.
Calc_Rainfall()
{
    RAINFALL=$(echo "$BKT_TIPS*$RPT" | bc -l)
    RAINFALL=$(printf "%0.1f" "$RAINFALL")
}
# Create time stamp and enter current readings into weather-data.csv
Log_Data()
{
    date_time=$(date +%d/%m/%Y,%H:%M)
    echo "$date_time,$TC,$Rh,$DEW_POINT,$HEAT_NDX,$MSL_hPa,$RAINFALL" >> $DATA_CSV
}

############################################################
/usr/local/bin/wl_jobs -p > $TEMP_DATA
Parse_Data
Calc_Dew_Point 
Calc_MSL_hPa
Calc_Rainfall
Log_Data   
/usr/local/bin/wl_jobs -b
echo "0" > $TIP_COUNT
	


What's up?