#!/usr/bin/python
#
# weather.py
#
#
#  Read and records values from an Oregon Scientific WMR968 Weather Station
#
#
# Much code based on wxlog.bas     (c) K. J. Turner <kjt@cs.stir.ac.uk>    2nd November 2004
#
#  (He knew all the interface logic)
#
#
Version	= "0.65a"
Author	= "J R Casey Bralla"
Program	= "weather.py"


# Import some standard python modules
import os		# misc operating system calls.
import sys		# More misc operating system calls
import time		# Time & Date functions
import serial		# serial I/O routines
import curses		# CRT Manipulation routines
import traceback	# Add traceback functions for error handling
import math		# mathematical functions


# Create all the variables

# Current Weather COnditions
IndoorTemp = 0
IndoorHumidity = 0
OutdoorTemp = 0
OutdoorHumidity = 0
WindChill = 0
Pressure = 0
WindSpeed = 0
WindSpeedAverage = 0
WindDirection = 0
RainTotal = 0
RainRate = 0

SeaLevelOffset = 12.863   	# Add this mbar value to get "sea level" Barometer. (compensate for actual altitude)
				#  NOTE:  All data is stored with this offset applied!


# Historical Weather Data
RainLastHour = 0
RainLastDay = 0
RainLastWeek = 0
RainHourOld = ""
RainMinuteOld = ""
RainTotalOld = 0
RainTotalNew = 0
RainTotalMinute = 0
RainTotalHour = 0
RainTotalDay = 0
RainTotalWeek = 0
PressureHour = 0
PressureTrend = ""
RainTotalHourMinus01 = 0
RainTotalHourMinus02 = 0
RainTotalHourMinus03 = 0
RainTotalHourMinus04 = 0
RainTotalHourMinus05 = 0
RainTotalHourMinus06 = 0
RainTotalHourMinus07 = 0
RainTotalHourMinus08 = 0
RainTotalHourMinus09 = 0
RainTotalHourMinus10 = 0
RainTotalHourMinus11 = 0
RainTotalHourMinus12 = 0
RainTotalHourMinus13 = 0
RainTotalHourMinus14 = 0
RainTotalHourMinus15 = 0
RainTotalHourMinus16 = 0
RainTotalHourMinus17 = 0
RainTotalHourMinus18 = 0
RainTotalHourMinus19 = 0
RainTotalHourMinus20 = 0
RainTotalHourMinus21 = 0
RainTotalHourMinus22 = 0
RainTotalHourMinus23 = 0
RainTotalDayMinus01 = 0
RainTotalDayMinus02 = 0
RainTotalDayMinus03 = 0
RainTotalDayMinus04 = 0
RainTotalDayMinus05 = 0
RainTotalDayMinus06 = 0
RainTotalDayWeekMinus01 = 0
PressureHourMinus01 = 0
PressureHourMinus02 = 0
PressureHourMinus03 = 0
PressureHourMinus04 = 0
PressureHourMinus05 = 0
PressureHourMinus06 = 0
PressureHourMinus07 = 0
PressureHourMinus08 = 0
PressureHourMinus09 = 0
PressureHourMinus10 = 0
PressureHourMinus11 = 0
PressureHourMinus12 = 0
PressureHourMinus13 = 0
PressureHourMinus14 = 0
PressureHourMinus15 = 0
PressureHourMinus16 = 0
PressureHourMinus17 = 0
PressureHourMinus18 = 0
PressureHourMinus19 = 0
PressureHourMinus20 = 0
PressureHourMinus21 = 0
PressureHourMinus22 = 0
PressureHourMinus23 = 0
PressureRisingFalling = "Steady"



# Program data
StartCode = chr(0xFF) + chr(0xFF)
WXDataMultiList = ""


##################################################################################################################
##################################################################################################################
#
# Functions
#
#
##################################################################################################################
##################################################################################################################



##################################################################################################################
# Log current summary data for each minute
def LogWXData():
			
	# 
	TimeString = time.strftime("%Y-%m-%d %H:%M:%S", LocalTimeNow)
	#
	WXLogString = TimeString + ":  "
	WXLogString = WXLogString + "Indoor: "
	WXLogString = WXLogString + "%4.1f C, %2d%%, " 		% (IndoorTemp, IndoorHumidity)
	WXLogString = WXLogString + "Outdoor: "
	WXLogString = WXLogString + "%4.1f C, %2d%%, " 		% (OutdoorTemp, OutdoorHumidity)
	WXLogString = WXLogString + "%4d mbar, " 		% (Pressure)
	WXLogString = WXLogString + "%4.1f m/s, " 		% (WindSpeed)
	WXLogString = WXLogString + "%4.1f m/s ave, @ " 	% (WindSpeedAverage)
	WXLogString = WXLogString + "%3d deg, " 		% (WindDirection)
	WXLogString = WXLogString + "%4.1f C chill, " 		% (WindChill)
	WXLogString = WXLogString + "%4d mm/hr, " 		% (RainRate)
	WXLogString = WXLogString + "%3d mm minute" 		% (RainTotalMinute)
	#
	#
	WXDataLoggingFile    = open("WXLog.dat","a")			# Open the data file
	#
	WXDataLoggingFile.write(WXLogString)			#
	WXDataLoggingFile.write ("\n")				#
	#
	# Close the file
	WXDataLoggingFile.close()




##################################################################################################################
# Display the Current data on the screen
def DisplayWXData():
	#
	# Calculate Starting Column
	StartColumn = int(MaxScreenWidth/40)
	RainRow = int(MaxScreenHeight * .6087)
	PressureRow = int(MaxScreenHeight * .9130)
	#
	screen.addstr(2, StartColumn, ("   Current Date & Time: "+ TimeString						))
	screen.addstr(3, StartColumn, ("    Indoor Temperature: %3.1f F " 	% (float(IndoorTemp)*1.8 + 32)		))
	screen.addstr(4, StartColumn, ("       Indoor Humidity: %2d%% " 		% IndoorHumidity			))
	screen.addstr(5, StartColumn, ("   Outdoor Temperature: %3.1f F" 		% (float(OutdoorTemp)*1.8 + 32)		))
	screen.addstr(6, StartColumn, ("      Outdoor Humidity: %2d%% " 		%  OutdoorHumidity			))
	screen.addstr(7, StartColumn, ("   Barometric Pressure: %5.2f in Hg " 	% (float(Pressure)*0.02953007)		) + PressureRisingFalling)
	screen.addstr(8, StartColumn, ("  Wind Speed (Gusting): %3.1f mph " 	% (float(WindSpeed)*2.236936)		))
	screen.addstr(9, StartColumn, ("  Wind Speed (Average): %3.1f mph " 	% (float(WindSpeedAverage)*2.236936)	))
	screen.addstr(10, StartColumn, ("        Wind Direction: %3d degrees " 	% WindDirection				))
	screen.addstr(11, StartColumn, ("Wind Chill Temperature: %3.1f F " 	% (float(WindChill)*1.8 + 32)		))
	#print "            Total Rain: %3.2f inches" 	% (float(RainTotal)*0.03937)
	screen.addstr(13, StartColumn, ("     Current Rain Rate: %3.2f inches/hour " % (float(RainRate)*0.03937)		))
	#print "      Rain This Minute: %3.2f inches" 	% (float(RainTotalMinute)*0.03937)
	#
	screen.addstr(RainRow, StartColumn, ("Past Rain: %3.2f  %3.2f  %3.2f  %3.2f  %3.2f  %3.2f  %3.2f  %3.2f  %3.2f  %3.2f  %3.2f" % ((float(RainTotalHourMinus10)*0.03937),(float(RainTotalHourMinus09)*0.03937),(float(RainTotalHourMinus08)*0.03937),(float(RainTotalHourMinus07)*0.03937),(float(RainTotalHourMinus06)*0.03937),(float(RainTotalHourMinus05)*0.03937),(float(RainTotalHourMinus04)*0.03937),(float(RainTotalHourMinus03)*0.03937),(float(RainTotalHourMinus02)*0.03937),(float(RainTotalHourMinus01)*0.03937),(float(RainTotalHour)*0.03937))))
	screen.addstr(RainRow+1, StartColumn, ("    Hours: -10    -9    -8    -7    -6    -5    -4    -3    -2    -1   This"))
	#
	screen.addstr(RainRow+3, StartColumn, ("Past Rain: %3.2f  %3.2f  %3.2f  %3.2f  %3.2f  %3.2f  %3.2f" % ((float(RainTotalDayMinus06)*0.03937),(float(RainTotalDayMinus05)*0.03937),(float(RainTotalDayMinus04)*0.03937),(float(RainTotalDayMinus03)*0.03937),(float(RainTotalDayMinus02)*0.03937),(float(RainTotalDayMinus01)*0.03937),(float(RainTotalDay)*0.03937))))
	screen.addstr(RainRow+4, StartColumn, ("     Days:  -6    -5    -4    -3    -2    -1   Today"))
	#
	screen.addstr(PressureRow, StartColumn, ("Barometer: %5.2f  %5.2f  %5.2f  %5.2f  %5.2f  %5.2f  %5.2f  %5.2f  %3.2f" % ((float(PressureHourMinus08)*0.02953007),(float(PressureHourMinus07)*0.02953007),(float(PressureHourMinus06)*0.02953007),(float(PressureHourMinus05)*0.02953007),(float(PressureHourMinus04)*0.02953007),(float(PressureHourMinus03)*0.02953007),(float(PressureHourMinus02)*0.02953007),(float(PressureHourMinus01)*0.02953007),(float(Pressure)*0.02953007))))
	screen.addstr(PressureRow+1, StartColumn, ("    Hours:  -8     -7     -6     -5     -4     -3     -2     -1     Now"))
	
	
	DisplayWindData()
	screen.refresh()
	



##################################################################################################################
# Display the wind direction rose
def DisplayWindData():
	#
	RoseCenterY = int(MaxScreenHeight/3)
	RoseCenterX = int(MaxScreenWidth/1.4)
	RoseRadius  = int(MaxScreenHeight/4)
	AspectRatio = MaxScreenWidth/MaxScreenHeight
	WindDirectionString = ""
	#
	#
	# print RoseCenterX, RoseCenterY	
	screen.addstr(RoseCenterY,RoseCenterX, "+")	# Center of rose
	#
	#
	AngleY000 = int(RoseCenterY + (RoseRadius * .9 * -1.0000))	# Offsets from coordinates based on wind angle
	AngleY015 = int(RoseCenterY + (RoseRadius * .9 * -0.9659))
	AngleY030 = int(RoseCenterY + (RoseRadius * .9 * -0.8660))
	AngleY045 = int(RoseCenterY + (RoseRadius * .9 * -0.7071))
	AngleY060 = int(RoseCenterY + (RoseRadius * .9 * -0.5000))
	AngleY075 = int(RoseCenterY + (RoseRadius * .9 * -0.2588))
	AngleY090 = int(RoseCenterY + (RoseRadius * .9 *  0.0000))
	AngleY105 = int(RoseCenterY + (RoseRadius * .9 *  0.2588))
	AngleY120 = int(RoseCenterY + (RoseRadius * .9 *  0.5000))
	AngleY135 = int(RoseCenterY + (RoseRadius * .9 *  0.7071))
	AngleY150 = int(RoseCenterY + (RoseRadius * .9 *  0.8660))
	AngleY165 = int(RoseCenterY + (RoseRadius * .9 *  0.9659))
	AngleY180 = int(RoseCenterY + (RoseRadius * .9 *  1.0000))
	AngleY195 = int(RoseCenterY + (RoseRadius * .9 *  0.9659))
	AngleY210 = int(RoseCenterY + (RoseRadius * .9 *  0.8660))
	AngleY225 = int(RoseCenterY + (RoseRadius * .9 *  0.7071))
	AngleY240 = int(RoseCenterY + (RoseRadius * .9 *  0.5000))
	AngleY255 = int(RoseCenterY + (RoseRadius * .9 *  0.2588))
	AngleY270 = int(RoseCenterY + (RoseRadius * .9 *  0.0000))
	AngleY285 = int(RoseCenterY + (RoseRadius * .9 * -0.2588))
	AngleY300 = int(RoseCenterY + (RoseRadius * .9 * -0.5000))
	AngleY315 = int(RoseCenterY + (RoseRadius * .9 * -0.7071))
	AngleY330 = int(RoseCenterY + (RoseRadius * .9 * -0.8660))
	AngleY345 = int(RoseCenterY + (RoseRadius * .9 * -0.9659))
	#
	AngleX000 = int(RoseCenterX + (RoseRadius * .9 *  0.0000 * AspectRatio))# Offsets from coordinates based on wind angle
	AngleX015 = int(RoseCenterX + (RoseRadius * .9 *  0.2588 * AspectRatio))
	AngleX030 = int(RoseCenterX + (RoseRadius * .9 *  0.5000 * AspectRatio))
	AngleX045 = int(RoseCenterX + (RoseRadius * .9 *  0.7071 * AspectRatio))
	AngleX060 = int(RoseCenterX + (RoseRadius * .9 *  0.8660 * AspectRatio))
	AngleX075 = int(RoseCenterX + (RoseRadius * .9 *  0.9659 * AspectRatio))
	AngleX090 = int(RoseCenterX + (RoseRadius * .9 *  1.0000 * AspectRatio))
	AngleX105 = int(RoseCenterX + (RoseRadius * .9 *  0.9659 * AspectRatio))
	AngleX120 = int(RoseCenterX + (RoseRadius * .9 *  0.8660 * AspectRatio))
	AngleX135 = int(RoseCenterX + (RoseRadius * .9 *  0.7071 * AspectRatio))
	AngleX150 = int(RoseCenterX + (RoseRadius * .9 *  0.5000 * AspectRatio))
	AngleX165 = int(RoseCenterX + (RoseRadius * .9 *  0.2588 * AspectRatio))
	AngleX180 = int(RoseCenterX + (RoseRadius * .9 *  0.0000 * AspectRatio))
	AngleX195 = int(RoseCenterX + (RoseRadius * .9 * -0.2588 * AspectRatio))
	AngleX210 = int(RoseCenterX + (RoseRadius * .9 * -0.5000 * AspectRatio))
	AngleX225 = int(RoseCenterX + (RoseRadius * .9 * -0.7071 * AspectRatio))
	AngleX240 = int(RoseCenterX + (RoseRadius * .9 * -0.8660 * AspectRatio))
	AngleX255 = int(RoseCenterX + (RoseRadius * .9 * -0.9659 * AspectRatio))
	AngleX270 = int(RoseCenterX + (RoseRadius * .9 * -1.0000 * AspectRatio))
	AngleX285 = int(RoseCenterX + (RoseRadius * .9 * -0.9659 * AspectRatio))
	AngleX300 = int(RoseCenterX + (RoseRadius * .9 * -0.8660 * AspectRatio))
	AngleX315 = int(RoseCenterX + (RoseRadius * .9 * -0.7071 * AspectRatio))
	AngleX330 = int(RoseCenterX + (RoseRadius * .9 * -0.5000 * AspectRatio))
	AngleX345 = int(RoseCenterX + (RoseRadius * .9 * -0.2588 * AspectRatio))
	#
	#
	# Draw the rose
	#
	screen.addstr(AngleY000,AngleX000, "|")
	screen.addstr(AngleY015,AngleX015, ".")
	screen.addstr(AngleY030,AngleX030, ".")
	screen.addstr(AngleY045,AngleX045, ".")
	screen.addstr(AngleY060,AngleX060, ".")
	screen.addstr(AngleY075,AngleX075, ".")
	screen.addstr(AngleY090,AngleX090, "-")
	screen.addstr(AngleY105,AngleX105, ".")
	screen.addstr(AngleY120,AngleX120, ".")
	screen.addstr(AngleY135,AngleX135, ".")
	screen.addstr(AngleY150,AngleX150, ".")
	screen.addstr(AngleY165,AngleX165, ".")
	screen.addstr(AngleY180,AngleX180, "|")
	screen.addstr(AngleY195,AngleX195, ".")
	screen.addstr(AngleY210,AngleX210, ".")
	screen.addstr(AngleY225,AngleX225, ".")
	screen.addstr(AngleY240,AngleX240, ".")
	screen.addstr(AngleY255,AngleX255, ".")
	screen.addstr(AngleY270,AngleX270, "-")
	screen.addstr(AngleY285,AngleX285, ".")
	screen.addstr(AngleY300,AngleX300, ".")
	screen.addstr(AngleY315,AngleX315, ".")
	screen.addstr(AngleY330,AngleX330, ".")
	screen.addstr(AngleY345,AngleX345, ".")
		
	AngleY000 = int(RoseCenterY + (RoseRadius * .9 * -1.0000))	# Offsets from coordinates based on wind angle
	AngleY015 = int(RoseCenterY + (RoseRadius * .95 * -0.9659))
	AngleY030 = int(RoseCenterY + (RoseRadius * .95 * -0.8660))
	AngleY045 = int(RoseCenterY + (RoseRadius * .95 * -0.7071))
	AngleY060 = int(RoseCenterY + (RoseRadius * .95 * -0.5000))
	AngleY075 = int(RoseCenterY + (RoseRadius * .95 * -0.2588))
	AngleY090 = int(RoseCenterY + (RoseRadius * .95 *  0.0000))
	AngleY105 = int(RoseCenterY + (RoseRadius * .95 *  0.2588))
	AngleY120 = int(RoseCenterY + (RoseRadius * .95 *  0.5000))
	AngleY135 = int(RoseCenterY + (RoseRadius * .95 *  0.7071))
	AngleY150 = int(RoseCenterY + (RoseRadius * .95 *  0.8660))
	AngleY165 = int(RoseCenterY + (RoseRadius * .95 *  0.9659))
	AngleY180 = int(RoseCenterY + (RoseRadius * .95 *  1.0000))
	AngleY195 = int(RoseCenterY + (RoseRadius * .95 *  0.9659))
	AngleY210 = int(RoseCenterY + (RoseRadius * .95 *  0.8660))
	AngleY225 = int(RoseCenterY + (RoseRadius * .95 *  0.7071))
	AngleY240 = int(RoseCenterY + (RoseRadius * .95 *  0.5000))
	AngleY255 = int(RoseCenterY + (RoseRadius * .95 *  0.2588))
	AngleY270 = int(RoseCenterY + (RoseRadius * .95 *  0.0000))
	AngleY285 = int(RoseCenterY + (RoseRadius * .95 * -0.2588))
	AngleY300 = int(RoseCenterY + (RoseRadius * .95 * -0.5000))
	AngleY315 = int(RoseCenterY + (RoseRadius * .95 * -0.7071))
	AngleY330 = int(RoseCenterY + (RoseRadius * .95 * -0.8660))
	AngleY345 = int(RoseCenterY + (RoseRadius * .95 * -0.9659))
	#
	AngleX000 = int(RoseCenterX + (RoseRadius * .95 *  0.0000 * AspectRatio))# Offsets from coordinates based on wind angle
	AngleX015 = int(RoseCenterX + (RoseRadius * .95 *  0.2588 * AspectRatio))
	AngleX030 = int(RoseCenterX + (RoseRadius * .95 *  0.5000 * AspectRatio))
	AngleX045 = int(RoseCenterX + (RoseRadius * .95 *  0.7071 * AspectRatio))
	AngleX060 = int(RoseCenterX + (RoseRadius * .95 *  0.8660 * AspectRatio))
	AngleX075 = int(RoseCenterX + (RoseRadius * .95 *  0.9659 * AspectRatio))
	AngleX090 = int(RoseCenterX + (RoseRadius * .95 *  1.0000 * AspectRatio))
	AngleX105 = int(RoseCenterX + (RoseRadius * .95 *  0.9659 * AspectRatio))
	AngleX120 = int(RoseCenterX + (RoseRadius * .95 *  0.8660 * AspectRatio))
	AngleX135 = int(RoseCenterX + (RoseRadius * .95 *  0.7071 * AspectRatio))
	AngleX150 = int(RoseCenterX + (RoseRadius * .95 *  0.5000 * AspectRatio))
	AngleX165 = int(RoseCenterX + (RoseRadius * .95 *  0.2588 * AspectRatio))
	AngleX180 = int(RoseCenterX + (RoseRadius * .95 *  0.0000 * AspectRatio))
	AngleX195 = int(RoseCenterX + (RoseRadius * .95 * -0.2588 * AspectRatio))
	AngleX210 = int(RoseCenterX + (RoseRadius * .95 * -0.5000 * AspectRatio))
	AngleX225 = int(RoseCenterX + (RoseRadius * .95 * -0.7071 * AspectRatio))
	AngleX240 = int(RoseCenterX + (RoseRadius * .95 * -0.8660 * AspectRatio))
	AngleX255 = int(RoseCenterX + (RoseRadius * .95 * -0.9659 * AspectRatio))
	AngleX270 = int(RoseCenterX + (RoseRadius * .95 * -1.0000 * AspectRatio))
	AngleX285 = int(RoseCenterX + (RoseRadius * .95 * -0.9659 * AspectRatio))
	AngleX300 = int(RoseCenterX + (RoseRadius * .95 * -0.8660 * AspectRatio))
	AngleX315 = int(RoseCenterX + (RoseRadius * .95 * -0.7071 * AspectRatio))
	AngleX330 = int(RoseCenterX + (RoseRadius * .95 * -0.5000 * AspectRatio))
	AngleX345 = int(RoseCenterX + (RoseRadius * .95 * -0.2588 * AspectRatio))
	#
	#
	# Draw the rose
	#
	screen.addstr(AngleY000,AngleX000, "|")
	screen.addstr(AngleY015,AngleX015, ".")
	screen.addstr(AngleY030,AngleX030, ".")
	screen.addstr(AngleY045,AngleX045, ".")
	screen.addstr(AngleY060,AngleX060, ".")
	screen.addstr(AngleY075,AngleX075, ".")
	screen.addstr(AngleY090,AngleX090, "-")
	screen.addstr(AngleY105,AngleX105, ".")
	screen.addstr(AngleY120,AngleX120, ".")
	screen.addstr(AngleY135,AngleX135, ".")
	screen.addstr(AngleY150,AngleX150, ".")
	screen.addstr(AngleY165,AngleX165, ".")
	screen.addstr(AngleY180,AngleX180, "|")
	screen.addstr(AngleY195,AngleX195, ".")
	screen.addstr(AngleY210,AngleX210, ".")
	screen.addstr(AngleY225,AngleX225, ".")
	screen.addstr(AngleY240,AngleX240, ".")
	screen.addstr(AngleY255,AngleX255, ".")
	screen.addstr(AngleY270,AngleX270, "-")
	screen.addstr(AngleY285,AngleX285, ".")
	screen.addstr(AngleY300,AngleX300, ".")
	screen.addstr(AngleY315,AngleX315, ".")
	screen.addstr(AngleY330,AngleX330, ".")
	screen.addstr(AngleY345,AngleX345, ".")

		
		
	
	AngleY000 = int(RoseCenterY + (RoseRadius * -1.0000))	# Offsets from coordinates based on wind angle
	AngleY015 = int(RoseCenterY + (RoseRadius * -0.9659))
	AngleY030 = int(RoseCenterY + (RoseRadius * -0.8660))
	AngleY045 = int(RoseCenterY + (RoseRadius * -0.7071))
	AngleY060 = int(RoseCenterY + (RoseRadius * -0.5000))
	AngleY075 = int(RoseCenterY + (RoseRadius * -0.2588))
	AngleY090 = int(RoseCenterY + (RoseRadius *  0.0000))
	AngleY105 = int(RoseCenterY + (RoseRadius *  0.2588))
	AngleY120 = int(RoseCenterY + (RoseRadius *  0.5000))
	AngleY135 = int(RoseCenterY + (RoseRadius *  0.7071))
	AngleY150 = int(RoseCenterY + (RoseRadius *  0.8660))
	AngleY165 = int(RoseCenterY + (RoseRadius *  0.9659))
	AngleY180 = int(RoseCenterY + (RoseRadius *  1.0000))
	AngleY195 = int(RoseCenterY + (RoseRadius *  0.9659))
	AngleY210 = int(RoseCenterY + (RoseRadius *  0.8660))
	AngleY225 = int(RoseCenterY + (RoseRadius *  0.7071))
	AngleY240 = int(RoseCenterY + (RoseRadius *  0.5000))
	AngleY255 = int(RoseCenterY + (RoseRadius *  0.2588))
	AngleY270 = int(RoseCenterY + (RoseRadius *  0.0000))
	AngleY285 = int(RoseCenterY + (RoseRadius * -0.2588))
	AngleY300 = int(RoseCenterY + (RoseRadius * -0.5000))
	AngleY315 = int(RoseCenterY + (RoseRadius * -0.7071))
	AngleY330 = int(RoseCenterY + (RoseRadius * -0.8660))
	AngleY345 = int(RoseCenterY + (RoseRadius * -0.9659))
	#
	AngleX000 = int(RoseCenterX + (RoseRadius *  0.0000 * AspectRatio))	# Offsets from coordinates based on wind angle
	AngleX015 = int(RoseCenterX + (RoseRadius *  0.2588 * AspectRatio))
	AngleX030 = int(RoseCenterX + (RoseRadius *  0.5000 * AspectRatio))
	AngleX045 = int(RoseCenterX + (RoseRadius *  0.7071 * AspectRatio))
	AngleX060 = int(RoseCenterX + (RoseRadius *  0.8660 * AspectRatio))
	AngleX075 = int(RoseCenterX + (RoseRadius *  0.9659 * AspectRatio))
	AngleX090 = int(RoseCenterX + (RoseRadius *  1.0000 * AspectRatio))
	AngleX105 = int(RoseCenterX + (RoseRadius *  0.9659 * AspectRatio))
	AngleX120 = int(RoseCenterX + (RoseRadius *  0.8660 * AspectRatio))
	AngleX135 = int(RoseCenterX + (RoseRadius *  0.7071 * AspectRatio))
	AngleX150 = int(RoseCenterX + (RoseRadius *  0.5000 * AspectRatio))
	AngleX165 = int(RoseCenterX + (RoseRadius *  0.2588 * AspectRatio))
	AngleX180 = int(RoseCenterX + (RoseRadius *  0.0000 * AspectRatio))
	AngleX195 = int(RoseCenterX + (RoseRadius * -0.2588 * AspectRatio))
	AngleX210 = int(RoseCenterX + (RoseRadius * -0.5000 * AspectRatio))
	AngleX225 = int(RoseCenterX + (RoseRadius * -0.7071 * AspectRatio))
	AngleX240 = int(RoseCenterX + (RoseRadius * -0.8660 * AspectRatio))
	AngleX255 = int(RoseCenterX + (RoseRadius * -0.9659 * AspectRatio))
	AngleX270 = int(RoseCenterX + (RoseRadius * -1.0000 * AspectRatio))
	AngleX285 = int(RoseCenterX + (RoseRadius * -0.9659 * AspectRatio))
	AngleX300 = int(RoseCenterX + (RoseRadius * -0.8660 * AspectRatio))
	AngleX315 = int(RoseCenterX + (RoseRadius * -0.7071 * AspectRatio))
	AngleX330 = int(RoseCenterX + (RoseRadius * -0.5000 * AspectRatio))
	AngleX345 = int(RoseCenterX + (RoseRadius * -0.2588 * AspectRatio))
	#
	#
	# Draw the rose
	#
	screen.addstr(AngleY000,AngleX000, "|")
	screen.addstr(AngleY015,AngleX015, ".")
	screen.addstr(AngleY030,AngleX030, ".")
	screen.addstr(AngleY045,AngleX045, ".")
	screen.addstr(AngleY060,AngleX060, ".")
	screen.addstr(AngleY075,AngleX075, ".")
	screen.addstr(AngleY090,AngleX090, "-")
	screen.addstr(AngleY105,AngleX105, ".")
	screen.addstr(AngleY120,AngleX120, ".")
	screen.addstr(AngleY135,AngleX135, ".")
	screen.addstr(AngleY150,AngleX150, ".")
	screen.addstr(AngleY165,AngleX165, ".")
	screen.addstr(AngleY180,AngleX180, "|")
	screen.addstr(AngleY195,AngleX195, ".")
	screen.addstr(AngleY210,AngleX210, ".")
	screen.addstr(AngleY225,AngleX225, ".")
	screen.addstr(AngleY240,AngleX240, ".")
	screen.addstr(AngleY255,AngleX255, ".")
	screen.addstr(AngleY270,AngleX270, "-")
	screen.addstr(AngleY285,AngleX285, ".")
	screen.addstr(AngleY300,AngleX300, ".")
	screen.addstr(AngleY315,AngleX315, ".")
	screen.addstr(AngleY330,AngleX330, ".")
	screen.addstr(AngleY345,AngleX345, ".")
		
	#
	# Highlight the current wind angle
	#
	if abs(WindDirection - 000) <= 7.5:
		 screen.addstr(AngleY000,AngleX000, "*",curses.A_STANDOUT)
	if abs(WindDirection - 015) <= 7.5:
		 screen.addstr(AngleY015,AngleX015, "*",curses.A_STANDOUT)
	if abs(WindDirection - 030) <= 7.5:
		 screen.addstr(AngleY030,AngleX030, "*",curses.A_STANDOUT)
	if abs(WindDirection - 045) <= 7.5:
		 screen.addstr(AngleY045,AngleX045, "*",curses.A_STANDOUT)
	if abs(WindDirection - 060) <= 7.5:
		 screen.addstr(AngleY060,AngleX060, "*",curses.A_STANDOUT)
	if abs(WindDirection - 075) <= 7.5:
		 screen.addstr(AngleY075,AngleX075, "*",curses.A_STANDOUT)
	if abs(WindDirection -  90) <= 7.5:
		 screen.addstr(AngleY090,AngleX090, "*",curses.A_STANDOUT)
	if abs(WindDirection - 105) <= 7.5:
		 screen.addstr(AngleY105,AngleX105, "*",curses.A_STANDOUT)
	if abs(WindDirection - 120) <= 7.5:
		 screen.addstr(AngleY120,AngleX120, "*",curses.A_STANDOUT)
	if abs(WindDirection - 135) <= 7.5:
		 screen.addstr(AngleY135,AngleX135, "*",curses.A_STANDOUT)
	if abs(WindDirection - 150) <= 7.5:
		 screen.addstr(AngleY150,AngleX150, "*",curses.A_STANDOUT)
	if abs(WindDirection - 165) <= 7.5:
		 screen.addstr(AngleY165,AngleX165, "*",curses.A_STANDOUT)
	if abs(WindDirection - 180) <= 7.5:
		 screen.addstr(AngleY180,AngleX180, "*",curses.A_STANDOUT)
	if abs(WindDirection - 195) <= 7.5:
		 screen.addstr(AngleY195,AngleX195, "*",curses.A_STANDOUT)
	if abs(WindDirection - 210) <= 7.5:
		 screen.addstr(AngleY210,AngleX210, "*",curses.A_STANDOUT)
	if abs(WindDirection - 225) <= 7.5:
		 screen.addstr(AngleY225,AngleX225, "*",curses.A_STANDOUT)
	if abs(WindDirection - 240) <= 7.5:
		 screen.addstr(AngleY240,AngleX240, "*",curses.A_STANDOUT)
	if abs(WindDirection - 255) <= 7.5:
		 screen.addstr(AngleY255,AngleX255, "*",curses.A_STANDOUT)
	if abs(WindDirection - 270) <= 7.5:
		 screen.addstr(AngleY270,AngleX270, "*",curses.A_STANDOUT)
	if abs(WindDirection - 285) <= 7.5:
		 screen.addstr(AngleY285,AngleX285, "*",curses.A_STANDOUT)
	if abs(WindDirection - 300) <= 7.5:
		 screen.addstr(AngleY300,AngleX300, "*",curses.A_STANDOUT)
	if abs(WindDirection - 315) <= 7.5:
		 screen.addstr(AngleY315,AngleX315, "*",curses.A_STANDOUT)
	if abs(WindDirection - 330) <= 7.5:
		 screen.addstr(AngleY330,AngleX330, "*",curses.A_STANDOUT)
	if abs(WindDirection - 345) <= 7.5:
		 screen.addstr(AngleY345,AngleX345, "*",curses.A_STANDOUT)
	if abs(WindDirection - 360) <= 7.5:
		 screen.addstr(AngleY000,AngleX000, "*",curses.A_STANDOUT)
	
	WindDirectionString = CalculateWindHeadingText(WindDirection)
	
	DirectionLocation = CenterString(WindDirectionString,0) + RoseCenterX
	screen.addstr(RoseCenterY+1,DirectionLocation, WindDirectionString)


##################################################################################################################
# Log the current weather status
# This is for other programs to retrieve, but also to retreive when the program is restarted
def LogWXStatus():
			
	WXDataStatusFile = open("WXStat.dat","w")			# Open the data file
	WXDataStatusFile.write("# WMR968 Current Weather Data as of " + TimeString + "\n")
	WXDataStatusFile.write( str(IndoorTemp) 	+ "	# Indoor Temperature - degrees C\n")
	WXDataStatusFile.write( str(IndoorHumidity) 	+ "	# Indoor Humidity - %%\n")
	WXDataStatusFile.write( str(OutdoorTemp) 	+ "	# Outdoor Temperature - degrees C\n")
	WXDataStatusFile.write( str(OutdoorHumidity) 	+ "	# Outdoor Humidity - %%\n")
	WXDataStatusFile.write( str(Pressure) 		+ "	# Pressure - mbar\n")
	WXDataStatusFile.write( str(WindSpeed) 		+ "	# Wind Speed - m/s\n")
	WXDataStatusFile.write( str(WindSpeedAverage) 	+ "	# Average Wind Speed - m/s\n")
	WXDataStatusFile.write( str(WindDirection) 	+ "	# Wind Direction - degrees\n")
	WXDataStatusFile.write( str(WindChill) 		+ "	# Wind Chill - degrees C\n")
	WXDataStatusFile.write( str(RainRate) 		+ "	# Rainfall Rate - mm/hour\n")
	WXDataStatusFile.write( str(RainTotalOld) 	+ "	# Rain already accounted for - mm\n")	
	WXDataStatusFile.write( str(RainTotalMinute) 	+ "	# Rain this past minute - mm\n")
	WXDataStatusFile.write( str(RainTotalHour) 	+ "	# Rain this past hour - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus01)+ "	# Rain this past hour minus 01 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus02)+ "	# Rain this past hour minus 02 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus03)+ "	# Rain this past hour minus 03 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus04)+ "	# Rain this past hour minus 04 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus05)+ "	# Rain this past hour minus 05 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus06)+ "	# Rain this past hour minus 06 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus07)+ "	# Rain this past hour minus 07 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus08)+ "	# Rain this past hour minus 08 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus09)+ "	# Rain this past hour minus 09 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus10)+ "	# Rain this past hour minus 10 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus11)+ "	# Rain this past hour minus 11 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus12)+ "	# Rain this past hour minus 12 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus13)+ "	# Rain this past hour minus 13 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus14)+ "	# Rain this past hour minus 14 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus15)+ "	# Rain this past hour minus 15 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus16)+ "	# Rain this past hour minus 16 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus17)+ "	# Rain this past hour minus 17 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus18)+ "	# Rain this past hour minus 18 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus19)+ "	# Rain this past hour minus 19 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus20)+ "	# Rain this past hour minus 20 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus21)+ "	# Rain this past hour minus 21 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus22)+ "	# Rain this past hour minus 22 - mm\n")
	WXDataStatusFile.write( str(RainTotalHourMinus23)+ "	# Rain this past hour minus 23 - mm\n")
	WXDataStatusFile.write( str(RainTotalDay)	+ "	# Rain this past day - mm\n")
	WXDataStatusFile.write( str(RainTotalDayMinus01)+ "	# Rain this past day minus 01 - mm\n")
	WXDataStatusFile.write( str(RainTotalDayMinus02)+ "	# Rain this past day minus 02 - mm\n")
	WXDataStatusFile.write( str(RainTotalDayMinus03)+ "	# Rain this past day minus 03 - mm\n")
	WXDataStatusFile.write( str(RainTotalDayMinus04)+ "	# Rain this past day minus 04 - mm\n")
	WXDataStatusFile.write( str(RainTotalDayMinus05)+ "	# Rain this past day minus 05 - mm\n")
	WXDataStatusFile.write( str(RainTotalDayMinus06)+ "	# Rain this past day minus 06 - mm\n")
	WXDataStatusFile.write( str(RainTotalWeek)	+ "	# Rain this past week - mm\n")
	WXDataStatusFile.write( str(PressureHourMinus01)+ "	# Barometric Pressure this past hour minus 01 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus02)+ "	# Barometric Pressure this past hour minus 02 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus03)+ "	# Barometric Pressure this past hour minus 03 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus04)+ "	# Barometric Pressure this past hour minus 04 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus05)+ "	# Barometric Pressure this past hour minus 05 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus06)+ "	# Barometric Pressure this past hour minus 06 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus07)+ "	# Barometric Pressure this past hour minus 07 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus08)+ "	# Barometric Pressure this past hour minus 08 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus09)+ "	# Barometric Pressure this past hour minus 09 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus10)+ "	# Barometric Pressure this past hour minus 10 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus11)+ "	# Barometric Pressure this past hour minus 11 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus12)+ "	# Barometric Pressure this past hour minus 12 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus13)+ "	# Barometric Pressure this past hour minus 13 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus14)+ "	# Barometric Pressure this past hour minus 14 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus15)+ "	# Barometric Pressure this past hour minus 15 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus16)+ "	# Barometric Pressure this past hour minus 16 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus17)+ "	# Barometric Pressure this past hour minus 17 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus18)+ "	# Barometric Pressure this past hour minus 18 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus19)+ "	# Barometric Pressure this past hour minus 19 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus20)+ "	# Barometric Pressure this past hour minus 20 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus21)+ "	# Barometric Pressure this past hour minus 21 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus22)+ "	# Barometric Pressure this past hour minus 22 - mbar\n")
	WXDataStatusFile.write( str(PressureHourMinus23)+ "	# Barometric Pressure this past hour minus 23 - mbar\n")
	#
	WXDataStatusFile.close()
	#	
	





##################################################################################################################
# Create a basic web page with the critical current data

def MakeWebPageCurrentData():
	#
	#
	WXDataHTMLFile = open("WXStat.html","w")			# Open the data file
	#
	#
	# Setup the web page
	# WXDataHTMLFile.write( "Content-type: text/html\n\n")
	WXDataHTMLFile.write( "<HTML>")
	WXDataHTMLFile.write( "<Title>West Grove, PA Weather Conditions</Title>")
	WXDataHTMLFile.write( "<meta Name=\"Program\" Content=\"" + Program + "\">" )
	WXDataHTMLFile.write( "<meta Name=\"Version\" Content=\"" + Version + "\">")
	WXDataHTMLFile.write( "<meta Name=\"Author\" Content=\"" + Author + "\">" )
	WXDataHTMLFile.write( '<meta http-equiv="REFRESH" content="60">') 	# Update exvery 60 seconds
	WXDataHTMLFile.write( "<font face=\"arial,helvetica\" Size=1>")
	WXDataHTMLFile.write( "<Body Lang=\"en-US\" Text=\"#ffff00\" Link=\"#0000ee\" Vlink=\"#551a8b\" BGcolor=\"#000000\">")
	#
	# Create the table
	WXDataHTMLFile.write( '<table style="width: 100%; height: 176px; text-align: left; margin-left: auto; margin-right: auto;" border="0" cellpadding="2" cellspacing="2">' )
	WXDataHTMLFile.write( '<tbody><tr align="center">' )
	#
	# Header Row
	WXDataHTMLFile.write( '<tr align="center"><td colspan="2" rowspan="1"><big style="color: rgb(255, 255, 102);"><big><span style="font-weight: bold;">Local Conditions</span></big></big>')
	WXDataHTMLFile.write( '<br>as of<br><font color="#ffffff">' + LocalTimeDisplayString + '</font></td></tr>')
	#
	# Creatge formated strings for data
	StrOutdoorTemp 		= str( "%3.1f"	% (float(OutdoorTemp)*1.8 + 32))
	StrOutdoorHumidity 	= str( "%2d" 	%       (OutdoorHumidity))
	StrWindSpeed		= str( "%3.1f"	% (float(WindSpeed)*2.236936))
	StrWindDirection	= str(                  (WindDirection))
	StrPressure		= str( "%5.2f"	% (float(Pressure)*0.02953007))
	StrRainTotalDay		= str( "%3.2f"	% (float(RainTotalDay)*0.03937))
	StrRainTotalDayMinus01	= str( "%3.2f"	% (float(RainTotalDayMinus01)*0.03937))
	StrRainTotalWeek	= str( "%3.2f"	% (float(RainTotalWeek)*0.03937))
	#
	WXDataHTMLFile.write('<tr><td style="text-align: right; width: 50%; font-weight: bold;">Temperature:</td>' )
	WXDataHTMLFile.write('    <td><font color="#ffffff">' + StrOutdoorTemp + " F </font></tr>" )
	#
	WXDataHTMLFile.write('<tr><td style="text-align: right; width: 50%; font-weight: bold;">Humidity:</td>' )
	WXDataHTMLFile.write('    <td><font color="#ffffff"> ' + StrOutdoorHumidity + " % </font></tr>" )
	#
	WXDataHTMLFile.write('<tr><td style="text-align: right; width: 50%; font-weight: bold;">Wind Speed:</td>' )
	# WXDataHTMLFile.write('    <td><font color="#ffffff"> ' + StrWindSpeed + " MPH </font></tr>" )
	WXDataHTMLFile.write('    <td><font color="#ffffff"> ' + "Unavailable </font></tr>" )
	#
	WXDataHTMLFile.write('<tr><td style="text-align: right; width: 50%; font-weight: bold;">Wind Direction:</td>' )
	# WXDataHTMLFile.write('    <td><font color="#ffffff"> ' + StrWindDirection + ' degrees (' + CalculateWindHeadingText(WindDirection) + ')</font></tr>' )
	WXDataHTMLFile.write('    <td><font color="#ffffff"> ' + 'Unavailable' + '</font></tr>' )
	#
	WXDataHTMLFile.write('<tr><td style="text-align: right; width: 50%; font-weight: bold;">Atmospheric Pressure:</td>' )
	WXDataHTMLFile.write('    <td><font color="#ffffff"> ' + StrPressure + " in Hg " + PressureRisingFalling + "</font></tr>" )
	#
	WXDataHTMLFile.write('<tr><td style="text-align: right; width: 50%; font-weight: bold;">Rain Today:</td>' )
	WXDataHTMLFile.write('    <td><font color="#ffffff"> ' + StrRainTotalDay + " inches </font></tr>" )
	#
	#
	WXDataHTMLFile.write('<tr><td style="text-align: right; width: 50%; font-weight: bold;">Rain Yesterday:</td>' )
	WXDataHTMLFile.write('    <td><font color="#ffffff"> ' + StrRainTotalDayMinus01 + " inches </font></tr>" )
	#
	#
	WXDataHTMLFile.write('<tr><td style="text-align: right; width: 50%; font-weight: bold;">Rain Last 7 Days:</td>' )
	WXDataHTMLFile.write('    <td><font color="#ffffff"> ' + StrRainTotalWeek + " inches </font></tr>" )
	#
	#
	# End the table
	#
	WXDataHTMLFile.write('</tbody></table>')
	#
	#
	# Now close out the web page
	#
	WXDataHTMLFile.write('</html>')
	#
	#
	WXDataHTMLFile.close()
	#
	#
	
	



##################################################################################################################
# Get all the available data from the WMR968

def CalculateWindHeadingText(WindDirection):
	#
	#
	WindDirectionText = ""
	#
	#
	if abs(WindDirection - 000) <= 11.5:
		WindDirectionText = "       North        "
	if abs(WindDirection - 022) <= 11.5:
		WindDirectionText = "   North Northeast  "
	if abs(WindDirection - 045) <= 11.5:
		WindDirectionText = "     Northeast      "
	if abs(WindDirection - 067) <= 11.5:
		WindDirectionText = "   East Northeast   "
	if abs(WindDirection -  90) <= 11.5:
		WindDirectionText = "        East        "
	if abs(WindDirection - 112) <= 11.5:
		WindDirectionText = "   East Southeast   "
	if abs(WindDirection - 135) <= 11.5:
		WindDirectionText = "      Southeast     "
	if abs(WindDirection - 157) <= 11.5:
		WindDirectionText = "   South Southeast  "
	if abs(WindDirection - 180) <= 11.5:
		WindDirectionText = "        South       "
	if abs(WindDirection - 202) <= 11.5:
		WindDirectionText = "    South Southwest "
	if abs(WindDirection - 225) <= 11.5:
		WindDirectionText = "       Southwest    "
	if abs(WindDirection - 247) <= 11.5:
		WindDirectionText = "    West Southwest  "
	if abs(WindDirection - 270) <= 11.5:
		WindDirectionText = "        West        "
	if abs(WindDirection - 292) <= 11.5:
		WindDirectionText = "   West Northwest   "
	if abs(WindDirection - 315) <= 11.5:
		WindDirectionText = "      Northwest     "
	if abs(WindDirection - 337) <= 11.5:
		WindDirectionText = "   North Northwest  "
	if abs(WindDirection - 360) <= 11.5:
		WindDirectionText = "        North       "	

	# print WindDirection
	return WindDirectionText




##################################################################################################################
# Get all the available data from the WMR968

def GetWMR968Data():

	WXDataRawList = ""
	while 1 == 1:
		WXDataByte = serIO.read()	# Get as many characters as are ready
		#
		if len(WXDataByte) == 0:
			break	# Null data means the data is done
		#
		WXDataRawList = WXDataRawList + WXDataByte
		#
	# print WXDataRawList
	return WXDataRawList
	



##################################################################################################################
# Convert the provided string as a series of hex numbers
def ConvertToHexList(CharacterString):
	#
	HexCharacterString = ""
	for CharacterPointer in range(len(CharacterString)):
		#
		HexCharacterString = HexCharacterString + hex(ord(CharacterString[CharacterPointer])) + " "
	return HexCharacterString	




##################################################################################################################
# Calculate the starting location of a string to center it on the screen
def CenterString(String,ScreenWidth):
	#
	StringLength = len(String)
	StartingPosition = (ScreenWidth - StringLength)/2
	#
	return int(StartingPosition)




##################################################################################################################
# Convert the provided string to a list of numbers
def ConvertCharacterToInteger(CharacterString):
	#
	IntegerList = []
	for CharacterPointer in range(len(CharacterString)):
		#
		IntegerList.append(ord(CharacterString[CharacterPointer]))
	return IntegerList




##################################################################################################################
# Pull the number out of the commented line
def GetValue(String):
	#
	Location = String.find("#")
	ReturnedValueString = String[0:Location]
	ReturnedValue = float(ReturnedValueString)
	
	return ReturnedValue





##################################################################################################################
##################################################################################################################
#
# End of Functions
#
#
##################################################################################################################
##################################################################################################################










# Initialize Curses routines

if __name__=='__main__':			# This code from http://gnosis.cx/publish/programming/charming_python_6.html
	try:
		# Initialize curses
		stdscr=curses.initscr()
		# Turn off echoing of keys, and enter cbreak mode,
		# where no buffering is performed on keyboard input
		curses.noecho()
		curses.cbreak()

		# In keypad mode, escape sequences for special keys
		# (like the cursor keys) will be interpreted and
		# a special value like curses.KEY_LEFT will be returned
		stdscr.keypad(1)
		# main(stdscr)                    # Enter the main loop
		# Set everything back to normal
		# stdscr.keypad(0)
		# curses.echo()
		# curses.nocbreak()
		# curses.endwin()                 # Terminate curses
	except:
		# In event of error, restore terminal to sane state.
		stdscr.keypad(0)
		curses.echo()
		curses.nocbreak()
		curses.endwin()
		traceback.print_exc()           # Print the exception

# Set up the window using curses
WindowDims = stdscr.getmaxyx()
MaxScreenWidth = WindowDims[1]	# Maximum width of screen
MaxScreenHeight = WindowDims[0]	# Maximum height of screen
# MaxScreenWidth = 79
# MaxScreenHeight = 23
screen = stdscr.subwin(MaxScreenHeight, MaxScreenWidth, 0, 0)	# Create a window, filling the screen
screen.border()							# Draw a line around it
ScreenTitle = " Weather Data from the Oregon Scientific WMR968 weather station - Version " + Version + " "
ExitKeyString = " Press any key to exit "
screen.addstr(0,               CenterString(ScreenTitle  , MaxScreenWidth), ScreenTitle )
screen.addstr(MaxScreenHeight-1, CenterString(ExitKeyString, MaxScreenWidth), ExitKeyString)
screen.move(0,0)
curses.curs_set(0)	# Cursor is invisible
screen.refresh()
screen.nodelay(1)		# Don't wait for input






# open the serial port to the WMR-968
# (port, baudrate, bytesize, parity, stopbits, timeout, xonxoff, rtscts, writeTimeout, dsrdtre, interCharTimeout)
serIO = serial.Serial("/dev/ttyS0", 9600, 8, 'N', 1, timeout=1, xonxoff=True, rtscts=True, writeTimeout=0, dsrdtr=True)	# NOTE:  No CTS/RTS or XON/XOFF!  Only 9600 BPS!


# Open the data files
WXDataLoggingFileRaw = open("WXLog-raw.dat","a")		# Open the data file
WXDataLoggingFile    = open("WXLog.dat","a")			# Open the data file

WXLogHeaderString = "# Program restarted"
WXDataLoggingFile    = open("WXLog.dat","a")			# Open the data file
WXDataLoggingFile.write(WXLogHeaderString)			#
WXDataLoggingFile.write ("\n")					#
#
		
WXLogHeaderString = "# Program restarted"
WXDataLoggingFile    = open("WXLog-raw.dat","a")			# Open the data file
WXDataLoggingFile.write(WXLogHeaderString)			#
WXDataLoggingFile.write ("\n")					#
#
	
		
# Close the file
WXDataLoggingFile.close()





# Now retrieve data stored in the status file
WXDataStatusFile = open("WXStat.dat","r")			# Open the data file to read
TrashString 	= WXDataStatusFile.readline()
IndoorTemp 	= GetValue(WXDataStatusFile.readline())		# Indoor Temperature - degrees C\n)

IndoorHumidity		= GetValue(WXDataStatusFile.readline())		# Indoor Humidity - %%
OutdoorTemp 		= GetValue(WXDataStatusFile.readline())		# Outdoor Temperature - degrees C
OutdoorHumidity		= GetValue(WXDataStatusFile.readline())		# Outdoor Humidity - %%
Pressure		= GetValue(WXDataStatusFile.readline())		# Pressure - mbar
WindSpeed		= GetValue(WXDataStatusFile.readline())		# Wind Speed - m/s
WindSpeedAverage	= GetValue(WXDataStatusFile.readline())		# Average Wind Speed - m/s
WindDirection		= GetValue(WXDataStatusFile.readline())		# Wind Direction - degrees
WindChill		= GetValue(WXDataStatusFile.readline())		# Wind Chill - degrees C
RainRate		= GetValue(WXDataStatusFile.readline())		# Rainfall Rate - mm/hour
RainTotalOld		= GetValue(WXDataStatusFile.readline())		# Rain already accounted for - mm
RainTotalMinute		= GetValue(WXDataStatusFile.readline())		# Rain this past minute - mm
RainTotalHour		= GetValue(WXDataStatusFile.readline())		# Rain this past hour - mm
RainTotalHourMinus01	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 01 - mm
RainTotalHourMinus02	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 02 - mm
RainTotalHourMinus03	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 03 - mm
RainTotalHourMinus04	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 04 - mm
RainTotalHourMinus05	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 05 - mm
RainTotalHourMinus06	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 06 - mm
RainTotalHourMinus07	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 07 - mm
RainTotalHourMinus08	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 08 - mm
RainTotalHourMinus09	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 09 - mm
RainTotalHourMinus10	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 10 - mm
RainTotalHourMinus11	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 11 - mm
RainTotalHourMinus12	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 12 - mm
RainTotalHourMinus13	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 13 - mm
RainTotalHourMinus14	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 14 - mm
RainTotalHourMinus15	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 15 - mm
RainTotalHourMinus16	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 16 - mm
RainTotalHourMinus17	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 17 - mm
RainTotalHourMinus18	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 18 - mm
RainTotalHourMinus19	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 19 - mm
RainTotalHourMinus20	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 20 - mm
RainTotalHourMinus21	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 21 - mm
RainTotalHourMinus22	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 22 - mm
RainTotalHourMinus23	= GetValue(WXDataStatusFile.readline())		# Rain this past hour minus 23 - mm
RainTotalDay		= GetValue(WXDataStatusFile.readline())		# Rain this past day - mm
RainTotalDayMinus01	= GetValue(WXDataStatusFile.readline())		# Rain this past day minus 01 - mm
RainTotalDayMinus02	= GetValue(WXDataStatusFile.readline())		# Rain this past day minus 02 - mm
RainTotalDayMinus03	= GetValue(WXDataStatusFile.readline())		# Rain this past day minus 03 - mm
RainTotalDayMinus04	= GetValue(WXDataStatusFile.readline())		# Rain this past day minus 04 - mm
RainTotalDayMinus05	= GetValue(WXDataStatusFile.readline())		# Rain this past day minus 05 - mm
RainTotalDayMinus06	= GetValue(WXDataStatusFile.readline())		# Rain this past day minus 06 - mm
RainTotalWeek		= GetValue(WXDataStatusFile.readline())		# Rain this past week - mm
PressureHourMinus01	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 01 - mbar
PressureHourMinus02	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 02 - mbar
PressureHourMinus03	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 03 - mbar
PressureHourMinus04	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 04 - mbar
PressureHourMinus05	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 05 - mbar
PressureHourMinus06	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 06 - mbar
PressureHourMinus07	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 07 - mbar
PressureHourMinus08	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 08 - mbar
PressureHourMinus09	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 09 - mbar
PressureHourMinus10	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 10 - mbar
PressureHourMinus11	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 11 - mbar
PressureHourMinus12	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 12 - mbar
PressureHourMinus13	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 13 - mbar
PressureHourMinus14	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 14 - mbar
PressureHourMinus15	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 15 - mbar
PressureHourMinus16	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 16 - mbar
PressureHourMinus17	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 17 - mbar
PressureHourMinus18	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 18 - mbar
PressureHourMinus19	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 19 - mbar
PressureHourMinus20	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 20 - mbar
PressureHourMinus21	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 21 - mbar
PressureHourMinus22	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 22 - mbar
PressureHourMinus23	= GetValue(WXDataStatusFile.readline())		# Barometric Pressure this past hour minus 23 - mbar




TimeOld = time.time()

DataLogCount = 0
# WXDataList = GetWMR968Data()	# Get all the data currently in the pipeline and throw it away





while 1 == 1:		# Do this forever.   The main program loop
	#
	#
	#

	WXString = ""
	WXDataList = []
	WXDataByte = ""
	WXDataPosition = 0

	LocalTimeNow = time.localtime()
	TimeNow = time.time()
	TimeString = time.strftime("%Y-%m-%d %H:%M:%S  ", LocalTimeNow)
	LocalTimeDisplayString = time.strftime("%B %d, %Y   at   %I:%M %p", LocalTimeNow)

	WXDataMultiList = WXDataMultiList + GetWMR968Data()	# Get All the data & add it to the buffer
	# print WXDataMultiList
	
	# Determine how many data elements we have
	NumberOfElements = WXDataMultiList.count(StartCode)
	DataElement = ""
	
	# Separate out the data elements, and then call the evaluation subroutine
	if NumberOfElements >= 2:	# Only work on strings with multiple sets of data
		#
		DataElementStart = WXDataMultiList.find(StartCode,1)	# Find the start of the second occurance
		DataElement = WXDataMultiList[0:DataElementStart]	# Get the first occurance
		#
		# print "Original Item:", ConvertToHexList(WXDataMultiList)
		# print "Start Point:", DataElementStart
		# print "Executed Item:", ConvertToHexList(DataElement)
		# print " "
		#
		# Now remove the first element from the buffer
		WXDataMultiList = WXDataMultiList[DataElementStart: len(WXDataMultiList)]
		
				#

	if NumberOfElements == 1:				# Now we have a single item left
		#
		DataElement = WXDataMultiList
		WXDataMultiList = ""		# Zero out the buffer
		# print "No-Mod Item:", ConvertToHexList(DataElement)
		# print " No of Elem:", NumberOfElements
		# print " "
	#
	#
	NumberOfElements = DataElement.count(StartCode)
	if NumberOfElements == 1:	# Only work on strings with a start code
		#
		#
		#
		WXDataList = ConvertCharacterToInteger(DataElement)	# Make it a list, which is nicer to work with
		#
		# Set the global variables
		#
		#
		#
		# Do some error checking on the data.  Ignore any error-full data		
		#
		#
		CheckSumError 		= "  **CheckSum Error**  "
		DataElementCountError 	= "  **Data Element Length Error**  "
		#
		#
		DeviceCode = WXDataList[2]
		#
		#
		# Check the number of elements per record
		#
		NumberOfElements = len(WXDataList)
		#
		CheckSumByte = WXDataList[NumberOfElements-1]
		#
		if DeviceCode == (0) and NumberOfElements == 11:					# Wind
			DataElementCountError = ""
			#
		if DeviceCode == (1) and NumberOfElements == 16:					# Rain
			DataElementCountError = ""
			#
		if DeviceCode == (2):								# Unknown
			DataElementCountError = "  **Unknown Code** "
			CheckSumError = ""
			#
		if DeviceCode == (3) and (NumberOfElements == 8 or NumberOfElements == 9):	# Outdoor Temperature
			DataElementCountError = ""
			#
		if DeviceCode == (6) and NumberOfElements == 14:					# Indoor Temperature
			DataElementCountError = ""
			#
		if DeviceCode == (0x0E) and NumberOfElements == 5:				# Clock Minutes
			DataElementCountError = ""
			#
		if DeviceCode == (0x0F) and NumberOfElements == 9:				# Clock Hours
			DataElementCountError = ""
			#
		#
		#
		#
		# Calculate the checksum
		CheckSumCalculated = 0
		for ElementCounter in range(NumberOfElements - 3):
			#
			CheckSumCalculated = CheckSumCalculated + (WXDataList[ElementCounter + 2])
		CheckSumCalculated = CheckSumCalculated - 2
		CheckSumCalculated = (CheckSumCalculated & 0xFF)	# Bottom 8 bits (not 7 as stated in docs)
		#
		if CheckSumByte == CheckSumCalculated:
			CheckSumError = ""		
		#
		# print "Checksums: ", ConvertToHexList(DataElement), hex(CheckSumByte), hex(CheckSumCalculated)
		#
		#
		#
		# Log the raw data, as well as the quality check analysis		
		WXDataLoggingFileRaw = open("WXLog-raw.dat","a")		# Open the data file
		WXDataLoggingFileRaw.write(TimeString)				#
		WXDataLoggingFileRaw.write(ConvertToHexList(DataElement))	#
		WXDataLoggingFileRaw.write(DataElementCountError)		#
		WXDataLoggingFileRaw.write(CheckSumError)			#
		WXDataLoggingFileRaw.write ("\n")				#
		WXDataLoggingFileRaw.close()					# Close the data file
		
		if CheckSumError == "" and DataElementCountError == "":
			# 
			# Do the analysis only if there is no error condition
	
			
					
					
			###################   Wind   Wind   Wind   Wind   ###########################################
			###################   Wind   Wind   Wind   Wind   ###########################################
			###################   Wind   Wind   Wind   Wind   ###########################################
			###################   Wind   Wind   Wind   Wind   ###########################################
			
			# Device Code 0
			if DeviceCode == (0):	# Wind Gage
				#
				# Code Format:  FF FF 00 B0 D2D3 S3D1 S1S2 A2A3 WSA1 W1W2 C1C2
				#       Where:  FF==Start   B == Battery  S == Speed  A == Average speed  D == Direction  W == Wind Chill  C == Checksum
				#       Units:  meters/second & degrees
				#
				# print "Wind"
				#
				WindBattery = WXDataList[3]
				#
				# Tease out data from BCD-cded bytes
				WindD2 = (WXDataList[4] & (0xF0)) / 0x10  # bitwise and is "&"
				WindD3 = (WXDataList[4] & (0x0F))
				WindD1 = (WXDataList[5] & (0x0F))
				WindDirection = (WindD1 * 100) + (WindD2 * 10) + WindD3
				#
				WindS3 = (WXDataList[5] & (0xF0)) / 0x10  # bitwise and is "&"
				WindS1 = (WXDataList[6] & (0xF0)) / 0x10  # bitwise and is "&"
				WindS2 = (WXDataList[6] & (0x0F)) 
				WindSpeed = (WindS1 * 10) + (WindS2 * 1) + (float(WindS3) / 10)
				#
				WindA2 = (WXDataList[7] & (0xF0)) / 0x10  # bitwise and is "&"
				WindA3 = (WXDataList[7] & (0x0F)) 
				WindA1 = (WXDataList[8] & (0x0F)) 
				WindSpeedAverage = (WindA1 * 10) + (WindA2 * 1) + (float(WindA3) / 10)
				#
				WindChill1 = (WXDataList[9] & (0xF0)) / 0x10  # bitwise and is "&"
				WindChill2 = (WXDataList[9] & (0x0F)) 
				WindChillS = (WXDataList[8] & (0xF0)) / 0x10  # bitwise and is "&"
				WindChill = (WindChill1 * 10) + WindChill2
				if WindChillS > 1:
					WindChill = -WindChill	# Negate the sign
				# print ConvertToHexList(DataElement)
				# print WindChillS, WindChill1, WindChill2, WindChill
				# print WindSpeed, "(", WindSpeedAverage, ")","@", WindDirection
				
				
				
				
		
			# ##################   Rain   Rain   Rain   Rain   ########################################	
			# ##################   Rain   Rain   Rain   Rain   ########################################	
			# ##################   Rain   Rain   Rain   Rain   ########################################	
			# ##################   Rain   Rain   Rain   Rain   ########################################	
				
			if DeviceCode == 01:	# Rain Gage
				#
				# Code Format:  FF FF B0 R1R2 ?? T3T4  T1T2  Y3Y4  Y1Y2  (total start time ->>) M1M2  H1H2  D1D2  M1M2  Y1Y2 C1C2
				#       Where:  FF==Start   B == Battery  R == Rate   T == Total Rain  Y == Rain Yesterday  C == Checksum
				#       Units:  millimeters & millimeters/hour
				#        Note:	"Yesterday" refers to the previous 24 hour period (midnight to midnight)
				#        Note:  "Total" is the total stored in the unit untilt the memory is reset
				#
				# print "Rain"
				#
				#
				#
				RainTotalAdded = 0
				RainTotal3 = (WXDataList[6] & (0xF0)) / 0x10  # bitwise and is "&"
				RainTotal4 = (WXDataList[6] & (0x0F))
				RainTotal1 = (WXDataList[7] & (0xF0)) / 0x10  # bitwise and is "&"
				RainTotal2 = (WXDataList[7] & (0x0F))
				RainTotalNew = (RainTotal1 * 1000) + (RainTotal2 * 100) + (RainTotal3 * 10) + (RainTotal4 * 1)
				# print RainTotal1, RainTotal2, RainTotal3, RainTotal4, RainTotalNew
				if RainTotalNew >= RainTotalOld:	# Only update if it increases (otherwise may have been reset)
					RainTotalAdded = RainTotalNew - RainTotalOld
					RainTotalOld = RainTotalNew
					RainTotal = RainTotalNew
					# Add the additional rain to this minute & hour
					RainTotalMinute = RainTotalMinute + RainTotalAdded
					RainTotalHour   = RainTotalHour   + RainTotalAdded
					RainTotalDay	= RainTotalDay	  + RainTotalAdded
			
				#
				if RainTotalNew < RainTotalOld:	# Rain has been reset)
					RainTotalOld = RainTotalNew
				#
				#
				RainRate1 = (WXDataList[4] & (0xF0)) / 0x10  # bitwise and is "&"
				RainRate2 = (WXDataList[4] & (0x0F))
				RainRate = (RainRate1 * 10) + RainRate2
				# print RainRate1, RainRate2, RainRate
				#
				#
				# Do lots of totals for rainfall
				#
		
				#
		
					
				# print RainTotal
		
				
				
				
				
			# if DeviceCode == 02:	# Unknown Gage
				#
				# print "Unknown Code!!"
				# break
				
				
				
			##################   Outside   Outside   Outside   Outside   ###########################################
			##################   Outside   Outside   Outside   Outside   ###########################################
			##################   Outside   Outside   Outside   Outside   ###########################################
			##################   Outside   Outside   Outside   Outside   ###########################################
				
				
			if DeviceCode == 3:	# Outdoor Temp & Humidity
				#
				# Code Format:  FF FF 00 B0 T2T3 TST1 H1H2 D1D2 C1C2
				#       Where:  FF==Start   T == Temperature  H == Humidity   D == Dew point C == Checksum
				#       Units:  degrees C & percentage
				#        NOTE:  *Sometimes* the "B0" is dropped!  Gotta figure it both ways!
				#
				# print "Outdoor Temp & Humidity"
				#
				#
				#
				OutdoorT2 = (WXDataList[4] & (0xF0)) / 0x10  # bitwise and is "&"
				OutdoorT3 = (WXDataList[4] & (0x0F)) 
				OutdoorT1 = (WXDataList[5] & (0x0F)) 
				OutdoorTS = (WXDataList[5] & (0xF0)) / 0x10
				#
				OutdoorH1 = (WXDataList[6] & (0xF0)) / 0x10  # bitwise and is "&"
				OutdoorH2 = (WXDataList[6] & (0x0F)) 
				#
				OutdoorTemp = (OutdoorT1 * 10) + (OutdoorT2 * 1) + (float(OutdoorT3) / 10)
				if OutdoorTS > 1:
					OutdoorTemp = -OutdoorTemp	# Negate the sign				
				# print "Outdoor Temps:", OutdoorTS, OutdoorT1, OutdoorT2, OutdoorT3, OutdoorTemp
				# print ConvertToHexList(DataElement), len(WXDataList)
				#
				
				OutdoorHumidity = (OutdoorH1 * 10) + (OutdoorH2 * 1)
				# print OutdoorH1, OutdoorH2, OutdoorHumidity
				#
				# print OutdoorTemp, OutdoorHumidity, WXString, len(WXDataList)
			
				
				
				
			##################   Inside   Inside   Inside   Inside   ###########################################
			##################   Inside   Inside   Inside   Inside   ###########################################
			##################   Inside   Inside   Inside   Inside   ###########################################
			##################   Inside   Inside   Inside   Inside   ###########################################
						
						
			if DeviceCode == 6:	# Indoor temperature, humidity, and barometric pressure
				#
				# Code Format:  FF FF 06 B0 T2T3 TST1 H1H2 D1D2 P1P2 F1F2 ?? S3S4 S1S2 C1C2
				#       Where:  FF==Start   B == Battery  T == Temperature  H == Humidity  D == Dew Point  P == Pressure  F == Forecast   S == Sea Level offset   C == Checksum
				#       Units:  Degrees C, percent, Degrees C, Millibars-856, F Code, Milibars-600
				#        Note:  Pressure is coded as straight binary (not BCD format)
				#
				# print "Indoor Temperature & Humidity"
				#
				WindBattery = WXDataList[3]
				#
				IndoorT2 = (WXDataList[4] & (0xF0)) / 0x10  # bitwise and is "&"
				IndoorT3 = (WXDataList[4] & (0x0F)) 
				IndoorTS = (WXDataList[5] & (0xF0)) / 0x10
				IndoorT1 = (WXDataList[5] & (0x0F))
				#
				IndoorTemp = (IndoorT1 * 10) + (IndoorT2 * 1) + (float(IndoorT3) / 10)
				if IndoorTS > 1:
					IndoorTemp = -IndoorTemp	# Negate the sign
				# print IndoorT1, IndoorT2, IndoorT3, IndoorTS, IndoorTemp
				#
				IndoorH1 = (WXDataList[6] & (0xF0)) / 0x10  # bitwise and is "&"
				IndoorH2 = (WXDataList[6] & (0x0F)) 
				IndoorHumidity = (IndoorH1 * 10) + (IndoorH2 * 1)
				# print IndoorH1, IndoorH2, IndoorHumidity
				#
				PressureP1 = (WXDataList[8])
				Pressure = PressureP1 + 856 + SeaLevelOffset
				# print PressureP1, Pressure
				#
				
				
				
				
				
			if DeviceCode == 0x0E:	# Internal Clock Minutes
				#
				#		
				# Code Format:  FF FF 0E M1M2 C1C2
				#       Where:  FF==Start   M == Minutes  C == Checksum
				#       Units:  Minutes
				ClockM1 = (WXDataList[3] & (0xF0)) / 0x10  # bitwise and is "&"
				ClockM2 = (WXDataList[3] & (0x0F)) 		
				ClockMinutes = (ClockM1 * 10) + ClockM2
				# print ClockMinutes
								
								
								
								
								
	
	
	
	
	
	
	
	#
	# Calculate rising or falling (over a 2 hour period)
	#
	PressureRisingFalling = "(Steady) "
	#
	if (((Pressure + PressureHourMinus01)/2) - ((PressureHourMinus02 + PressureHourMinus03)/2)) < .1:
		PressureRisingFalling = "(Falling)"
		
	if (((Pressure + PressureHourMinus01)/2) - ((PressureHourMinus02 + PressureHourMinus03)/2)) > .1:
		PressureRisingFalling = "(Rising) "
				
	#
	# Update the data log & display info
	#
	DisplayWXData()	# Display the data on the screen
	#
	#
	#
	#
	TimeNowSeconds = int(time.strftime("%S", LocalTimeNow))
	TimeNowMinutes = int(time.strftime("%M", LocalTimeNow))
	TimeNowHours = int(time.strftime("%H", LocalTimeNow))
	ElapsedTime = TimeNow - TimeOld
	#
	#
	#
	#
	#
	if ElapsedTime >= 15 and TimeNowSeconds <= 10:	# Update the data log within 10 seconds of the minute
		#
		#	
		TimeOld = TimeNow
		#
		#
		#
		# Zero out the minute rain count
		RainTotalMinute = 0
		#
		#
		if TimeNowMinutes == 0:	# Shift the hourlies at the top of the hour
			#
			#
			# Shift the totals and update
			#
			RainTotalHourMinus23 = RainTotalHourMinus22
			RainTotalHourMinus22 = RainTotalHourMinus21
			RainTotalHourMinus21 = RainTotalHourMinus20
			RainTotalHourMinus20 = RainTotalHourMinus19
			RainTotalHourMinus19 = RainTotalHourMinus18
			RainTotalHourMinus18 = RainTotalHourMinus17
			RainTotalHourMinus17 = RainTotalHourMinus16
			RainTotalHourMinus16 = RainTotalHourMinus15
			RainTotalHourMinus15 = RainTotalHourMinus14
			RainTotalHourMinus14 = RainTotalHourMinus13
			RainTotalHourMinus13 = RainTotalHourMinus12
			RainTotalHourMinus12 = RainTotalHourMinus11
			RainTotalHourMinus11 = RainTotalHourMinus10
			RainTotalHourMinus10 = RainTotalHourMinus09
			RainTotalHourMinus09 = RainTotalHourMinus08
			RainTotalHourMinus08 = RainTotalHourMinus07
			RainTotalHourMinus07 = RainTotalHourMinus06
			RainTotalHourMinus06 = RainTotalHourMinus05
			RainTotalHourMinus05 = RainTotalHourMinus04
			RainTotalHourMinus04 = RainTotalHourMinus03
			RainTotalHourMinus03 = RainTotalHourMinus02
			RainTotalHourMinus02 = RainTotalHourMinus01
			RainTotalHourMinus01 = RainTotalHour
			RainTotalHour = 0
			#
			#
			PressureHourMinus23 = PressureHourMinus22
			PressureHourMinus23 = PressureHourMinus22
			PressureHourMinus22 = PressureHourMinus21
			PressureHourMinus21 = PressureHourMinus20
			PressureHourMinus20 = PressureHourMinus19
			PressureHourMinus19 = PressureHourMinus18
			PressureHourMinus18 = PressureHourMinus17
			PressureHourMinus17 = PressureHourMinus16
			PressureHourMinus16 = PressureHourMinus15
			PressureHourMinus15 = PressureHourMinus14
			PressureHourMinus14 = PressureHourMinus13
			PressureHourMinus13 = PressureHourMinus12
			PressureHourMinus12 = PressureHourMinus11
			PressureHourMinus11 = PressureHourMinus10
			PressureHourMinus10 = PressureHourMinus09
			PressureHourMinus09 = PressureHourMinus08
			PressureHourMinus08 = PressureHourMinus07
			PressureHourMinus07 = PressureHourMinus06
			PressureHourMinus06 = PressureHourMinus05
			PressureHourMinus05 = PressureHourMinus04
			PressureHourMinus04 = PressureHourMinus03
			PressureHourMinus03 = PressureHourMinus02
			PressureHourMinus02 = PressureHourMinus01
			PressureHourMinus01 = Pressure		
				

		#
		#
		if TimeNowHours == 0 and TimeNowMinutes == 0:	# Shift the dailies at midnight
			#
			#
			# Shift the totals and update
			#
			RainTotalDayMinus06 = RainTotalDayMinus05
			RainTotalDayMinus05 = RainTotalDayMinus04
			RainTotalDayMinus04 = RainTotalDayMinus03
			RainTotalDayMinus03 = RainTotalDayMinus02
			RainTotalDayMinus02 = RainTotalDayMinus01
			RainTotalDayMinus01 = RainTotalDay
			RainTotalDay = 0
		#
		#
		RainTotalWeek = RainTotalDayMinus06 + RainTotalDayMinus05 + RainTotalDayMinus04 + RainTotalDayMinus03 + RainTotalDayMinus02 + RainTotalDayMinus01 + RainTotalDay
		#
		DataLogCount = DataLogCount + 1
		#
		if DataLogCount > 0:	# Only log after 2 cycles to prevent getting garbage in the data set
			#
			LogWXData()	# Call logging function
			#
			LogWXStatus()	# Now save it to a status file
			#
			MakeWebPageCurrentData()	# Create a simple web page
			
			
			
			
			
	# Exit from the program if any key is pressed using the curses modules
	#
	KeyPress = screen.getch()
	if KeyPress > 0:			# Any key has been pressed (-1 if no key)
		#
		#
		LogWXStatus()	# save all the data
		#
		#
		# Set everything back to normal
		stdscr.keypad(0)
		curses.echo()
		curses.nocbreak()
		curses.curs_set(1)
		curses.endwin()                 # Terminate curses
		sys.exit()			# Terminate the program
		
	#
	#	
	time.sleep(.2)		# Sleep a little to let the CPU rest.
	



