#!/bin/bash
# Peri's sump pump daemon
# For Beldandi
# $Id: sumpd 9 2018-07-16 03:31:39Z perette $

STATION=KROC
# METARSITE="www.wunderground.com/Aviation/index.html?query=$STATION"
# METARSITE="http://aviationweather.gov/metar/data?ids=KROC&format=raw&date=0&hours=0"
METARSITE=http://www.aviationweather.gov/adds/dataserver_current/current/metars.cache.csv.gz
BASE_RUNTIME=5
# WEATHER_FILE="/var/www/html/weather.txt"
WEATHER_FILE="$HOME/Sites/weather.txt"

function get_metar_data
{
	typeset place="/var/tmp/$arg0.$$.metar" status=1 D="[0-9]" metar
	lynx -source "$METARSITE" > $place
	if [ $? -eq 0 -a -s "$place" ]
	then
		# wrapper_tag="code"
		# cat $place 1>&2
		# metar=$(egrep "<$wrapper_tag>($STATION .*)</$wrapper_tag>" "$place")
		metar=$(gunzip -c "$place" | grep "^$STATION " | cut -d, -f1)
		if [ $? -eq 0 -a "$metar" != "" ]
		then
			echo "METAR $metar"
			# | sed -e "s/\($STATION [0-9][0-9][0-9][0-9][0-9][0-9]Z [^<]*\).*/METAR \\1/"
			status=0
		fi
	fi
	rm "$place"
	return $status
}



# The METAR parser is tuned to US metar reports.
# Changes will be necessary for international use, but
# it's probably a good starting point if needed.
# The parser is probably also doomed if it gets a TAF report
# instead of a METAR, which has a few different fields.
function parse_metar_data
{
	typeset file="$1" D="[0-9]"
	set $(egrep "^[ 	]*(SPECI|METAR|TAF|AMD) $STATION " "$file" | tail -1)

	# TAF - weather report; TAF AMD - amended weather
	# METAR - hourly report; SPECI - special; TESTM - test
	[ "$1" = "TESTM" ] && return 1
	[ "$1" = "SPECI" -o "$1" = "METAR" -o "$1" = "TAF" ] && shift
	[ "$1" = "AMD" ] && shift

	if ! expr "$2" : "$D$D$D$D$D${D}Z\$" >/dev/null
	then
		log "parse_metar_data: $2: Invalid timestamp."
		return 1
	fi
	METAR_DAY=$(echo $2 | cut -c1-2)
	METAR_HOUR=$(echo $2 | cut -c3-4)
	METAR_MINUTE=$(echo $2 | cut -c5-6)
	let "METAR_SEC = ${METAR_MINUTE#0} * 60 + ${METAR_HOUR#0} * 3600 + ${METAR_DAY#0} * 86400"

	# Possible AUTOmated or CORrected observations
	[ "$3" = "AUTO" -o "$3" = "COR" ] && shift
	if expr "$3" : "$D$D$D$D${D}KT\$" >/dev/null ||
	   expr "$3" : "VRB$D${D}KT\$" >/dev/null
	then
		# 12035KT = 120 degrees @ 35 knotts
		METAR_GUST=""
	elif expr "$3" : "$D$D$D$D${D}G$D${D}KT\$" >/dev/null
	then
		# 12035G38KT = 120 degrees @ 35 knotts, 38 knott gusts
		METAR_GUST=$(echo $3 | cut -c7-8)
	else
		log "parse_metar_data: $3: Not a valid windspeed."
		return 1
	fi
	METAR_WINDDIR=$(echo $3 | cut -c1-3)
	METAR_WINDSPEED=$(echo $3 | cut -c4-5)
	[ "$METAR_WINDDIR" = "VRB" ] && METAR_WINDDIR="Variable"

	# If variable wind direction, then there might be a 150V210
	# indicating variable winds between 150 and 210 degrees.
	expr "$4" : "$D$D${D}V$D$D$D" >/dev/null && shift

	# Visibility might be 1/4SM or 10SM or 2 1/2SM
	if expr "$4" : "$D/${D}SM\$" >/dev/null
	then
		METAR_VISIBILITY=0
	elif expr "$4" : "$D$D*SM\$" >/dev/null
	then
		METAR_VISIBILITY=$(echo $4 | cut -dS -f1)
	elif expr "$4" : "$D$D*\$" >/dev/null &&
	     expr "$5" : "$D/${D}SM\$" >/dev/null
	then
		METAR_VISIBILITY="$4"
		shift 1
	else
		log "parse_metar_data: $4: Not a valid visibility."
		return 1
	fi

	shift 4

	# Sometimes there is a Runway visibility listing.
	# Not always though.
	if expr "$1" : "R$D${D}[LCR]*/.*\$" >/dev/null
	then
		shift
	fi

	METAR_PRECIP_LEV=""
	METAR_PRECIP_INTENSITY=""
	METAR_PRECIP_DESCRIPTOR=""
	METAR_PRECIP_DESC=""
	METAR_PRECIP_TYPE=""
	METAR_PRECIP_TY=""
	METAR_PRECIP_OBSCURATION=""
	METAR_PRECIP_OBSC=""
	METAR_PRECIP_OTHER=""
	METAR_PRECIP_OTH=""

	# Precipitation status!
	# If there are multiple precipitation statuses reported, use
	# the first one which is the dominating one.
	if expr "$1" : '[+-]\{0,1\}\([A-Z][A-Z]\)\{1,5\}$' >/dev/null
	then
		typeset showers="$1"
		shift
		case "$showers" in
			-*)
				METAR_PRECIP_INTENSITY="Light"
				METAR_PRECIP_LEV="-"
				showers=$(echo "$showers" | cut -c2-)
				;;
			+*)
				METAR_PRECIP_INTENSITY="Heavy"
				METAR_PRECIP_LEV="+"
				showers=$(echo "$showers" | cut -c2-)
				;;
		esac

		while [ "$showers" != "" ]
		do
			typeset sc=$(echo "$showers" | cut -c1-2)
			case "$sc" in
				MI|PR|BC|DR|BL|SH|TS|FZ)
					METAR_PRECIP_DESC="$sc" ;;
				DZ|RA|SN|SG|IC|PL|GR|GS|UP)
					METAR_PRECIP_TY="$sc" ;;
				BR|FG|FU|VA|DU|SA|HZ|PY)
					METAR_PRESCIP_OBSC="$sc" ;;
				PO|SQ|FC|SS|DS)
					METAR_PRESCIP_OTH="$sc" ;;
			esac
			case "$sc" in
				VC) METAR_PRECIP_INTENSITY="In vicinity" ;;
				MI) METAR_PRECIP_DESCRIPTOR="Shallow" ;;
				PR) METAR_PRECIP_DESCRIPTOR="Partial" ;;
				BC) METAR_PRECIP_DESCRIPTOR="Broken" ;;
				DR) METAR_PRECIP_DESCRIPTOR="Low drifting" ;;
				BL) METAR_PRECIP_DESCRIPTOR="Blowing" ;;
				SH) METAR_PRECIP_DESCRIPTOR="Showers" ;;
				TS) METAR_PRECIP_DESCRIPTOR="Thunderstorm" ;;
				FZ) METAR_PRECIP_DESCRIPTOR="Freezing" ;;

				DZ) METAR_PRECIP_TYPE="Drizzle" ;;
				RA) METAR_PRECIP_TYPE="Rain" ;;
				SN) METAR_PRECIP_TYPE="Snow" ;;
				SG) METAR_PRECIP_TYPE="Snow grains" ;;
				IC) METAR_PRECIP_TYPE="Ice crystals" ;;
				PL) METAR_PRECIP_TYPE="Ice pellets" ;;
				GR) METAR_PRECIP_TYPE="Hail" ;;
				GS) METAR_PRECIP_TYPE="Small hail or snow pellets" ;;
				UP) METAR_PRECIP_TYPE="Unknown precipitation" ;;

				BR) METAR_PRECIP_OBSCURATION="Mist" ;;
				FG) METAR_PRECIP_OBSCURATION="Fog" ;;
				FU) METAR_PRECIP_OBSCURATION="Smoke" ;;
				VA) METAR_PRECIP_OBSCURATION="Volcanic ash" ;;
				DU) METAR_PRECIP_OBSCURATION="Widespread dust" ;;
				SA) METAR_PRECIP_OBSCURATION="Sand" ;;
				HZ) METAR_PRECIP_OBSCURATION="Haze" ;;
				PY) METAR_PRECIP_OBSCURATION="Spray" ;;

				PO) METAR_PRECIP_OTHER="Well-developed dust/sand whirls" ;;
				SQ) METAR_PRECIP_OTHER="Squalls" ;;
				FC) METAR_PRECIP_OTHER="Funnel cloud" ;;
				SS) METAR_PRECIP_OTHER="Sandstorm" ;;
				DS) METAR_PRECIP_OTHER="Duststorm" ;;
			esac
			showers=$(echo "$showers" | cut -c3-)
		done
	fi

	# Ignore any additional precipitation statuses.
	while expr "$1" : '[+-]\{0,1\}\([A-Z][A-Z]\)\{1,5\}$' >/dev/null
	do
		shift
	done

	# Cloud level entries: CLR or OVC020, BKN150, etc.
	while [ "$1" = "CLR" -o "$1" = "SKC" ] ||
	      expr "$1" : "[A-Z][A-Z][A-Z]$D$D${D}[A-Z]*\$" >/dev/null ||
	      expr "$1" : "VV$D$D$D\$" >/dev/null
	do
		shift
	done

	if ! expr "$1" : "M*$D$D*/M*$D$D*\$" >/dev/null
	then
		log "parse_metar_data: $1: Not valid temperature & dewpoint."
		return 1
	fi
	METAR_TEMPERATURE=$(echo $1 | cut -d/ -f1 | sed 's/M/-/')
	METAR_DEWPOINT=$(echo $1 | cut -d/ -f2 | sed 's/M/-/')

	if ! expr "$2" : "A$D$D$D$D*\$" >/dev/null
	then
		log "parse_metar_data: $1: Not a valid altimeter."
		return 1
	fi
	METAR_ALTIMETER="$(echo $2 | cut -c2-3).$(echo $2 | cut -c4-5)"
	return 0
}


function log
{
	if [ "$log_file" != "" ]
	then
		echo "$(date '+%Y-%m-%d %H:%M:%S'):" $@ >> "$log_file"
	else
		echo "$(date '+%Y-%m-%d %H:%M:%S'):" $@ 1>&2
	fi
}

function run_unit_test_now
{
	typeset status=0
	while read aline
	do
		echo "$aline" > "$temp"
		if ! parse_metar_data "$temp"
		then
			status=1
			echo "Failed to parse:"
			echo "$aline"
		fi
	done << EOF
METAR KROC 121354Z 23009KT 10SM CLR 19/16 A3018 RMK AO2 SLP217 T01940161
METAR KROC 131854Z 03010KT 10SM FEW250 21/15 A3026 RMK AO2 SLP244 T02060150
METAR KROC 131754Z VRB06KT 10SM FEW030 SCT250 22/14 A3027 RMK AO2 SLP248 8/101 T02170144 10217 20167 58007
METAR KROC 152318Z 04024G38KT 3SM RA FEW019 BKN030 OVC045 25/23 A2949 RMK AO2 PK WND 05041/2306 PRESFR P0004 TSNO
SPECI KROC 152318Z AUTO 04024G38KT 3SM RA BR FEW019 BKN030 OVC045 25/23 A2949 RMK AO2 PK WND 05041/2306 PRESFR P0004 TSNO
METAR KROC 160153Z AUTO 01032G41KT 4SM HZ SCT024 BKN030 OVC037 26/23 A2948 RMK AO2 PK WND 02045/0131 RAB27E40 SLP980 P0002 T02560228
METAR KROC 281154Z 00000KT 2 1/2SM BR BKN008 OVC065VV 15/14 A2993 RMK AO2 SLP136 8/6// T01500144 10167 20144 53003
METAR KROC 311654Z COR 27017G24KT 10SM BKN039 OVC047TCU 13/07 A2973 RMK AO2 PK WND 27031/1624 SLP067 BINOVC SW AND DSNT N T01330067
METAR KROC 061618Z 08012KT 1/2SM SN FZFG VV006 M03/M04 A3019 RMK AO2 P0000
METAR KROC 120954Z 28011KT 8SM -SN BKN014 OVC018 M01/M01 A2960 RMK AO2 SLP031 P0000 T10061011
METAR KROC 140505Z 34015G21KT 4SM -SN BR OVC016 M04/M06 A2991 RMK AO2 P0000
METAR KROC 140554Z 34010KT 10SM -SN OVC019 M06/M09 A2994 RMK AO2 SLP146 P0002 60013 931013 4/001 8/7// T10611089 10000 21061 51042
METAR KROC 151854Z 29011G18KT 10SM FEW070 26/11 A2991 RMK AO2 SLP124 T02560111 $
METAR KROC 030854Z 22006KT 6SM HZ SCT160 19/16 A2976 RMK AO2 SLP073 T01890161 58006
METAR KROC 101954Z 26018G23KT 1/4SM R04/2400VP6000FT +SN FZFG BLSN VV004 M04/M06 A2959 RMK AO2 PK WND 24031/1903 SLP026 SNINCR 1/3 P0001 T10441061
EOF
	return $status
}

function generate_report
{
	echo "Current conditions as of $(date '+%H:%M, %A %B %d')."
	echo "Temperature, $METAR_TEMPERATURE centigrade."
	if [ "$METAR_PRECIP_TYPE" = "" -a "$METAR_PRECIP_OBSCURATION" = "" ]
	then
		echo "No precipitation."
	else
		echo "$METAR_PRECIP_INTENSITY $METAR_PRECIP_DESCRIPTOR $METAR_PRECIP_TYPE, $METAR_PRECIP_OBSCURATION"
	fi
	[ "$METAR_PRECIP_OTHER" != "" ] &&
	     echo "with $METAR_PRECIP_OTHER"
	echo "Visibility $METAR_VISIBILITY miles."
	echo "Wind $METAR_WINDSPEED knots"
	[ "$METAR_GUST" != "" ] && echo "gusting to $METAR_GUST knots"
	echo "from the"
	case "$METAR_WINDDIR" in
		340|350|000|010|020)	echo "north." ;;
		030|040|050|060)	echo "north east." ;;
		070|080|090|100|110)	echo "east." ;;
		120|130|140|150)	echo "south east." ;;
		160|170|180|190|200)	echo "south." ;;
		210|220|230|240)	echo "south west." ;;
		250|260|270|280|290)	echo "west." ;;
		300|310|320|330)	echo "north west." ;;
		*)			echo "ass of God." ;;
	esac
}


arg0=$(basename $0)

temp="/var/tmp/$arg0.$$"
config="$HOME/.sumpdrc"

if [ "$1" = "TEST_GET_METAR_NOW" ]
then
	get_metar_data && echo "get_metar_data reports success."
	exit $?
fi

if [ "$1" = "RUN_UNIT_TEST_NOW" ]
then
	run_unit_test_now && echo "$arg0: All tests passed."
	exit $?
fi

if [ -f ~/x10iod.ini ]
then
	log_file=$(grep '^SumpLog=' ~/x10iod.ini | cut -d= -f2 |
		   awk '{print $1}')
fi

log 'sumpd $Revision: 1.27 $ started'

metar_cached=0
need_cooling=false
exhaust=false
hour=0

while true
do
	# In case configuration has been changed, reread file
	# each period.
	# Snowpack is an approximation in millimeters
	if [ -s "$config" ]
	then
		snowpack=$(grep '^[ 	]*SNOWPACK[ 	]*=' "$config" | cut -d= -f2)
		expr "$snowpack" : '[0-9][0-9]*$' >/dev/null || snowpack=500
		cooling_temp=$(grep '^[ 	]*COOLING_TEMP[ 	]*=' "$config" | cut -d= -f2)
		expr "$cooling_temp" : '[0-9][0-9]*$' >/dev/null || cooling_temp=0
	else
		snowpack=500
		cooling_temp=0
	fi
	[ $cooling_temp -ne 0 ] && need_cooling=true

	last_run_sump="${run_sump:-true}"
	last_snowpack="$snowpack"
	last_cooling="$cooling_temp"
	last_hour=$hour
	cool_outside=false

	hour=$(date '+%H')
	hour=${hour#0}

	# Default actions to take:
	run_sump=true
	let "next_run = BASE_RUNTIME * 3"

	# See if it's time to get a new METAR, and try to get it.
	# BSD 'date' doesn't support +%1d to get single-digit values.
	eval "let metar_now=\"$(TZ="UTC+0" date '+ %d * 86400 + %H * 3600 + %M * 60 + %S' | sed 's/ 0/ /g')\""
	if [ $metar_cached -gt $metar_now -o \
	     $((metar_cached + 900)) -lt $metar_now ]
	then
		if get_metar_data > "$temp"
		then
			log "METAR: " "$(grep "$STATION " "$temp")"
			if parse_metar_data "$temp"
			then
				log "Dated $METAR_DAY @ $METAR_HOUR:$METAR_MINUTE UTC.  Temperature $METAR_TEMPERATURE dewpoint $METAR_DEWPOINT."
				log "Wind $METAR_WINDSPEED knots @ $METAR_WINDDIR, gusts ${METAR_GUST:-(none)}."
				log "Pressure $METAR_ALTIMETER, visibility $METAR_VISIBILITY miles."
				log "Precipitation report:" $METAR_PRECIP_INTENSITY $METAR_PRECIP_DESCRIPTOR $METAR_PRECIP_TYPE $METAR_PRECIP_OBSCURATION $METAR_PRECIP_OTHER
				metar_cached="$METAR_SEC"

				[ -w "$WEATHER_FILE" ] &&
					generate_report > "$WEATHER_FILE"
			else
				log "Can not parse METAR data."
				metar_cached=0

				[ -w "$WEATHER_FILE" ] && > "$WEATHER_FILE"
			fi
		fi
		rm "$temp"
	fi
			
	# If we have a valid METAR, react to it.
	if [ $metar_cached -gt 0 ]
	then
		cache=3600

		# Sump pump handing
		case "$METAR_PRECIP_LEV${METAR_PRECIP_TY:-none}" in
			-DZ)	let "next_run = BASE_RUNTIME * 6" ;;
			DZ)	let "next_run = BASE_RUNTIME * 5" ;;
			+DZ)	let "next_run = BASE_RUNTIME * 4" ;;
			-RA)	let "next_run = BASE_RUNTIME * 3" ;;
			RA)	let "next_run = BASE_RUNTIME * 2" ;;
			+RA)	let "next_run = BASE_RUNTIME" ;;
			+*)	run_sump=false
				next_run=60
				let "snowpack = snowpack + 8" ;;
			-*)	run_sump=false
				next_run=60
				let "snowpack = snowpack + 2" ;;
			none)	run_sump=false
				next_run=60 ;;
			*)	run_sump=false
				next_run=60
				let "snowpack = snowpack + 5" ;;
			
		esac
		if [ $METAR_TEMPERATURE -ge 0 -a $snowpack -gt 0 ]
		then
			# For every 2 degrees C, figure we'll melt
			# one mm of snow / 15 minutes.  More if it's
			# raining.  It's an approximation, though not
			# necessarily good one...  But hey, it just
			# makes the sump pump go.
			let "melt = ($METAR_TEMPERATURE / 2)"
			let "snowpack = snowpack - $melt"
			[ $next_run -gt 15 -a $melt -gt 0 ] && next_run=15
			[ $snowpack -lt 0 ] && snowpack=0
			run_sump=true
		fi

		if [ $METAR_TEMPERATURE -ge -2 -a $snowpack -gt 0 ]
		then
			# If there's snowpack melting, there might be
			# ice dams on the roof.  Turn the heater cord
			# on.  Unlike the sump pump, which runs
			# intermittently, the heater cord stays on for
			# long periods but only up to 3 hours per day.
			# Count the run time for today.
			hour_now="$(date '+%H')"
			if [ "$last_ice_melt_hour" != "$hour_now" ]
			then
				last_ice_melt_hour="$hour_now"
				day_now="$(date '+%d')"
				if [ "$last_ice_melt_day" != "$day_now" ]
				then
					last_ice_melt_day="$day_now"
					ice_melt_today=0
				else
					let ice_melt_today=ice_melt_today+1
				fi
			fi

			if [ $ice_melt_today -lt 3 ]
			then
				log "Enabling ice melter: run time today: $ice_melt_today"
				action turn ice_melter on
			else
				log "Disabling ice melter: Melt period today already finished."
				action turn ice_melter off
			fi
		else
			log "Disabling ice melter: no snow or too cold."
			action turn ice_melter off
			last_ice_melt_hour=""
		fi

		# Cooling/exhaust fan control
		# Determine what temperature to provide cooling at.
		if [ $METAR_TEMPERATURE -ge 24 ]
		then
			need_cooling=true
			let cool_at=METAR_TEMPERATURE-4
			[ $cool_at -lt 21 ] && cool_at=21
			if [ $cool_at -gt $cooling_temp ]
			then
				cooling_temp=$cool_at
				log "Cooling temperature set to $cooling_temp"
			fi
			exhaust=true
		elif [ $METAR_TEMPERATURE -le 16 ]
		then
			log "Shutting down any running fans due to cool temperatures."
			need_cooling=false
			action turn cooling_fan off
			cooling_temp=0
			exhaust=false
		elif [ $METAR_TEMPERATURE -le 21 ]
		then
			log "Cooling fan control disabled."
			need_cooling=false
		fi
		if $need_cooling && [ $METAR_TEMPERATURE -le $cooling_temp ]
		then
			log "Starting cooling fans."
			action turn cooling_fan on
			[ $hour -ne $last_hour ] &&
				let cooling_temp=cooling_temp-1
		elif [ $METAR_TEMPERATURE -gt $((cooling_temp + 2)) ]
		then
			log "Stopping cooling fans."
			action turn cooling_fan off
		fi

		# Check temperature and start/stop BOINC if necessary
		boinc_running="$(osascript -e 'tell application "Finder" to process "BOINCManager" exists')"
		boinc_run="dontcare"
		[ $METAR_TEMPERATURE -le 17 ] && boinc_run="true"
		[ $METAR_TEMPERATURE -gt 20 ] && boinc_run="false"
		if [ "$boinc_running" = "false" -a "$boinc_run" = "true" ]
		then
			log "Starting BOINC"
			open /Applications/BOINCManager.app
		elif [ "$boinc_running" = "true" -a "$boinc_run" = "false" ]
		then
			log "Shutting down BOINC"
			osascript -e 'tell application "BOINCManager" to quit'
		fi

		# If it look like it may rain soon, increase monitor frequency.
		if [ $METAR_DEWPOINT -ge $METAR_TEMPERATURE -a \
		  $METAR_TEMPERATURE -ge 0 -a $next_run -gt 20 ]
		then
			log "Possible rain: Higher-frequency monitoring enabled."
			next_run=16
		fi
	else
		log "Disabling ice melter: Current conditions unknown."
		action turn ice_melter off
	fi

	# If it's morning, turn the fans off.
	if [ $hour -ge 4 -a $hour -le 6 ]
	then
		log "Shutting down any running fans before daytime."
		need_cooling=false
		action turn cooling_fan off
		cooling_temp=0
		exhaust=false
	fi
	if [ "$exhaust" = "true" -a $hour -ne $last_hour ]
	then
		log "Running exhaust fan."
		action turn exhaust_fan on
		(sleep 600; action turn exhaust_fan off) &
	fi
			
	# If it's starting to rain and there's laundry out, tell me to go get it
	if [ "$METAR_PRECIP_TYPE" != "" -a -s ~/.laundry ]
	then
		log "Start of rain: Laundry reminder."
		announce "Information.  $METAR_PRECIP_INTENSITY $METAR_PRECIP_DESCRIPTOR $METAR_PRECIP_TYPE is starting.  Please take the clothes off the line."
		rm -f ~/.laundry
	fi

	if $run_sump || $last_run_sump
	then
		log "Running sump: run_sump=$run_sump, last_run_sump=$last_run_sump."
		action turn sump_pump on
		let "next_run = next_run - 1"
		sleep 60
	fi

	# Update the status file if any of the recorded values have changed
	if [ $snowpack -ne $last_snowpack -o $cooling_temp -ne $last_cooling ]
	then
		log "Snowpack is now estimated at $snowpack mm."
		echo "SNOWPACK=$snowpack" > $config
		echo "COOLING_TEMP=$cooling_temp" >> $config
	fi
	[ $next_run -gt 60 ] && next_run=60

	# In case it accidentally started, always turn the sump off again.
	action turn sump_pump off

	# Adjust next time to a few minutes after the hour, when new METAR
	# should be up.
	updatetime=$(( 61 - $(date '+%M' |  sed 's/^0//') ))

	# If there's laundry out, do more frequent updates.
	[ -s ~/.laundry -a $updatetime -gt 15 ] && updatetime=10

	[ $updatetime -gt 3 -a $updatetime -le $next_run -a $next_run -gt 15 ] &&
		next_run=$updatetime

	sleep $((next_run * 60))
done

exit 0

