SEARCH

Enter your search query in the box above ^, or use the forum search tool.

You are not logged in.

#101 2014-07-08 00:16:02

batman51
Member
Registered: 2014-06-29
Posts: 14

Re: arclances conky weather script - v6.2.1

Thank you very much good sir, with your help it began to function. Now I wish to address the placement on the screen. How can I adjust that?it appears low and to the right.Which parameter do I change, nevermind, I'll google it and maybe learn something. Thank you again for all your help everyone big_smile

Offline

Help fund CrunchBang, donate to the project!

#102 2014-07-08 00:20:41

arclance
#! Die Hard
Registered: 2012-03-29
Posts: 987

Re: arclances conky weather script - v6.2.1

In the file "conkyrc_conkyWeather_arclance" you edit theses values

### Position ###
alignment bottom_left
gap_x 622
gap_y 31

to change to position of the conky window.

You can find the documentation on those settings here in case your search does not turn up anything.

Offline

#103 2014-07-08 00:34:05

batman51
Member
Registered: 2014-06-29
Posts: 14

Re: arclances conky weather script - v6.2.1

judge today not by the harvest you reap,  but by the seeds you  sow

Last edited by batman51 (2014-07-08 00:38:14)

Offline

#104 2014-07-08 00:39:55

batman51
Member
Registered: 2014-06-29
Posts: 14

Re: arclances conky weather script - v6.2.1

can I enlarge the radar picture?

Offline

#105 2014-07-08 01:40:45

arclance
#! Die Hard
Registered: 2012-03-29
Posts: 987

Re: arclances conky weather script - v6.2.1

^ Click the

R
A
D
/
S
A
T

button to the left of the radar and satellite images.
It will switch to a view with the radar and satellite images displayed at 272x272 pixel size.
conkyWeather_arclance_v6.1_2012-09-03_Screenshot_LGIMG_Normal_resized_0.67_bicubic.png
Click the

D
A
I
L
Y

button to go back original layout.

They could be displayed larger than that but you would have to make the conky window larger which affects the layout of everything.
The positions of almost everything is determined relative to the position of something else starting from how far down from the top of the window the weather alert and current time bar starts.

Offline

#106 2014-07-09 02:20:15

batman51
Member
Registered: 2014-06-29
Posts: 14

Re: arclances conky weather script - v6.2.1

My conky does not change at all when I click on any of the tabs.Is it possible that I overlooked something?

Offline

#107 2014-07-09 02:31:37

arclance
#! Die Hard
Registered: 2012-03-29
Posts: 987

Re: arclances conky weather script - v6.2.1

^ Yes, you might need to change some settings depending on what window manager you are using.
What window manager (or desktop environment) are you using?

Offline

#108 2014-07-09 02:42:11

batman51
Member
Registered: 2014-06-29
Posts: 14

Re: arclances conky weather script - v6.2.1

r4unning linux mint 17 with cinnamon

Offline

#109 2014-07-09 03:16:18

arclance
#! Die Hard
Registered: 2012-03-29
Posts: 987

Re: arclances conky weather script - v6.2.1

^ I don't know the settings for cinnamon.
It has never been run on that before that I know of.
I will have to look into cinnamon tomorrow before I can try to figure out what the proper settings are.

You can do some preliminary tests before that though.

1. Kill all your running conkys.

pkill -9 conky

2. Kill xdotool to make sure it has stopped.

pkill -9 xdotool

3. Change to Workspace 1.
4. Start the weather conky in a terminal without leaving Workspace 1.
5. Click on one of the buttons on the weather conky.
6. Wait 5 seconds.
7. Copy all terminal output since you started the conky in Step 4 and post it here.

If Cinnamons window manger/compositor is anything like Compiz (and I believe it is) the buttons may work but only in Workspace 1 right now.

Last edited by arclance (2014-07-09 03:17:03)

Offline

#110 2014-07-09 03:30:56

batman51
Member
Registered: 2014-06-29
Posts: 14

Re: arclances conky weather script - v6.2.1

O.K. working now but no NOAA image did not enable it in setting it up.Also installed mutter because cinnamon uses muffin, a fork of mutter. Will check on my laptop later to see if that was needed or not and will report back. big_smile

Offline

#111 2014-07-09 03:33:26

batman51
Member
Registered: 2014-06-29
Posts: 14

Re: arclances conky weather script - v6.2.1

forgot the code,sorry...

bob@Timmy ~ $ conky -c ~/conkyWeather_arclance_v6.2.1_2012-09-26/conkyrc_conkyWeather_arclance
installDirectory = /home/bob/conkyWeather_arclance_v6.2.1_2012-09-26
conkyWeather_arclance_v6.2
true
Conky: desktop window (1600033) is subwindow of root window (7d)
Conky: window type - normal
Conky: drawing to created window (0x3200001)
Conky: drawing to double buffer
abstlx: 0 abstly: 30 winNum_Parent: 125 winNum_2: 52428801
isNight = true

abstlx: 0 abstly: 30 winNum_Parent: 125 winNum_2: 52428801
abstlx: 0 abstly: 30 winNum_Parent: 125 winNum_2: 52428801
abstlx: 0 abstly: 30 winNum_Parent: 125 winNum_2: 52428801

Offline

#112 2014-07-09 03:41:48

batman51
Member
Registered: 2014-06-29
Posts: 14

Re: arclances conky weather script - v6.2.1

sorry... false alarm everything good

Offline

#113 2015-02-14 10:37:39

jed
#! CrunchBanger
From: Detachment 7
Registered: 2012-08-28
Posts: 200
Website

Re: arclances conky weather script - v6.2.1

Hey arclance hope your doing well.  Was just wondering if the acrlance conky weather script was still working?  Let me know if you don't mind...

Thanks a-lot!


Proud user of VSDIO: Jedi!  You can download it from here...  I'm on  the web at NixNut.com!

Offline

#114 2015-02-14 15:17:43

arclance
#! Die Hard
Registered: 2012-03-29
Posts: 987

Re: arclances conky weather script - v6.2.1

Yes it still works.
Wunderground has stated that they will only add things to their API not change or remove them.
So things don't need updated when the site changes like many other weather scripts that parse web pages.

Offline

#115 2015-02-16 04:53:41

jed
#! CrunchBanger
From: Detachment 7
Registered: 2012-08-28
Posts: 200
Website

Re: arclances conky weather script - v6.2.1

OK, I'll admit when I posted above that I was already failing miserably.  :8   After successfully using this script for a long time, I strayed.  Started trying a couple of days ago to get it to work again, to no avail.  I have a valid api key, and followed the readme meticulously and still can't get it.  8.(

Terminal output when running the python script;

jedi@jedsdesk:~$ python /home/jedi/conkyWeather_arclance_v6.2.1_2012-09-26/conkyWeather_arclance_v6.2.py &
[1] 3771
jedi@jedsdesk:~$ using cPickle
conkyWeather_arclance_v6.2
installLocation = /home/jedi/conkyWeather_arclance_v6.2.1_2012-09-26
no pull yet

timeDifference = 1424061333.86
pulling data
geolookup/conditions/forecast10day/hourly/astronomy/alerts/history_20150215
Pulling -- WU Data -- Location = 04769
tryconnect Error: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)>
Pulling -- Intellicast Data
Pulling -- WU Radar
tryconnect Error: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)>
Pulling -- WU Radar - Wide
tryconnect Error: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)>
Pulling -- WU Satellite
stderr = 
Pulling -- WU Satellite - Wide
stderr = 
Traceback (most recent call last):
  File "/home/jedi/conkyWeather_arclance_v6.2.1_2012-09-26/conkyWeather_arclance_v6.2.py", line 1016, in <module>
    conkyWeather()
  File "/home/jedi/conkyWeather_arclance_v6.2.1_2012-09-26/conkyWeather_arclance_v6.2.py", line 520, in conkyWeather
    backupCopy = open(logDirectory + "/wuAPI_json_current_pickled.txt", "r") # load the backup file for reading
IOError: [Errno 2] No such file or directory: '/home/jedi/conkyWeather_arclance_v6.2.1_2012-09-26/log/wuAPI_json_current_pickled.txt'

[1]+  Exit 1                  python /home/jedi/conkyWeather_arclance_v6.2.1_2012-09-26/conkyWeather_arclance_v6.2.py
jedi@jedsdesk:~$ 

and here is my .py modified for my location, minus my api for security reasons;

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
"""
Name : conkyWeather_arclance v6.2.1
Author: arclance
Date_Created:2011-10-29
Date_Updated:2012-09-26
	
Reads current weather information from the Wunderground API and formats it for display parsing by a lua script.

ChangeLog
v6.1.3 - 2012-09-26
	added installLocation information to startup debug output
	added check for radarWU_API_LAT and radarWU_API_LON not being numbers (catch non-number characters)

v6.1.2 - 2012-09-23
	added version information to startup debug output

v6.1.1 - 2012-09-08
	get data collection start time at the right place in the code
	fixes following user specified update interval (was running long)
	use https for WU API. Get 10 day forecast instead of 7 day forecast.

v6.1 - 2012-09-01
	add toggle to show radar and satallite images with a larger radius
	fix detection of satallite image connection failure

v6.0 - 2012-08-13
	Initial Release
	
v6.X - pre release
	2012-07-22
	fiveDay weather code completely converted to lua, remove all code that is now in the lua script.
	improve stability of download code (add catcher for httplib.BadStatusLine to tryconnect)
	drop support for all weather image sources except VClouds
		old python functions for other image sources could be converted to lua by using the VClouds code as an example
	
	2012-07-23
	added hourly weather output to lua script using buttons
		converted last of the five day code to lua (image selection, moon phase calculation)

	2012-07-25
	remove scrolling alerts code, now have working lua function to replace ${scroll} from conky

	2012-07-28
	change settings for sattelite image thanks to guide from API
	
	2012-07-29
	get history data for today (has better rain/snow amount data)
	
	2012-07-30
	use dateutil.parser and calendar.timegm to convert no epoch times to the current locales time
		replaces function I wrote that only worked for UTC-4 to UTC+5 to Eastern time.
	remove last of old code that is no longer used
	
	2012-08-01
	remove last of leftover image setting variables
	
	2012-08-03
	add empty list to output when not using NOAA data to preserve the position of other data in the list
	
	2012-08-04
	send all the intellicast data to the lua script instead of just the snow chance data.

#################################################
v5.2.4 - 2012-07-17 - start of lua conversion
	setup VCLOUDS_STRING images to be drawn by lua script
	setup radar and sattelite images to be drawn by lua script
	
v5.2.3
	setup logging so conky can dispaly something if the script fails to update (due to script crash or lockup)
	check if WU API server sends html error document (encountered "High Load" error document crashed script because its is not json format)
v5.2.2
	removed textwrap import, I am not seeing the 80 character wrapping in output files without it anymore
v5.2.1
	Try to catch gifsicle errors indicating something is wrong with the gif retreived from Weather Underground (Did Not Work Error Message Not Caught)
		My not have been catching stderr added stderr=PIPE
		Yes now it works
	Fix For Weather Stations That Report No Value (To Weather Underground) Instead of Zero For Days Without Rain (api gives negative values instead of 0 or N/A)
	Fix Heat Index Temperature Horizontal Alignment
v5.2
	More Connection Error Handling Improvements - Looks Good So Far
		try around opening of data pulled from internet
		increase default timeout, increase timeout for json and image files

######################################
Requires
Font
	DejaVu Sans Mono - recommended may work with other monospace fonts

Weather Icons - Included
	VClouds Weather Icons - http://vclouds.deviantart.com/art/VClouds-Weather-Icons-179152045
	moonicons from conkyForecast - http://ubuntuforums.org/showthread.php?t=869328

luajson - http://www.eharning.us/wiki/luajson/
	json interpreter for lua
	package in Debian is "lua-json" (only in Wheezy and Sid)

python2.7
	Libraries used
	cPickle or pickle (cPickle is faster use it if possible)
	urllib2
	httplib
	socket
	json
	time
	datetime
	dateutil
	calendar
	subprocess
	
	packages in Debian are (only in Wheezy and Sid)
		python2.7 
		python-dateutil

gifsicle - http://www.lcdf.org/gifsicle/
	used to break the animated radar and satellite gifs into individual images for use in conky
	package in Debian is "gifsicle"

conky
	v1.9.0 or higher recommended.
	May work with v1.8.0.
	
	Do Not Use v1.8.1. Several things were broken in this release.
	
	lua support with cairo and imlib2 bindings required.
"""

try:
	import cPickle as pickle
	print "using cPickle"
except ImportError:
	import pickle
	print "using pickle"
#endtry
import urllib2
import httplib
import socket
import json
import time
import datetime
from dateutil import parser
from calendar import timegm
from subprocess import Popen, PIPE
### need gifsicle for animated radar ###

def tryconnect(turl, timer=4, retries=3):
	for tried in xrange(retries):
		try:
			return urllib2.urlopen(turl, None, timer)
		except (urllib2.URLError, socket.timeout, httplib.BadStatusLine), e:
			print "tryconnect Error: " + str(e)
		else:
			break
		#endtry
	#endfor
	return None
#enddef

def openURL(request_url, timer=30, retries=3):
	urlopener = tryconnect(request_url, timer, retries)
	if urlopener:
		try:
			return urlopener
		except (httplib.IncompleteRead, httplib.BadStatusLine, socket.timeout), e:
			print "openURL Error: " + str(e)
			return None
		#endtry
	else:
		return None
	#endif
#enddef

class latlon_ValueError(Exception):
	def __init__(self, value):
		self.value = value
	#enddef
	def __str__(self):
		return repr(self.value)
	#enddef
#endclass

def conkyWeather():
	global logDirectory, pullAtempted, use_NOAA
	##################################
	print("conkyWeather_arclance_v6.2")
	##### user defined variables #####
	#### System Variables ####
	installLocation = "/home/jedi/conkyWeather_arclance_v6.2.1_2012-09-26" # location of the conkyWeather_arclance_v6.2.py file
	print("installLocation = " + installLocation)
	pollInterval = float(900) # time between data pulls from the API (in seconds) as a float
	logDirectory = installLocation + "/log" # directory to put working and log files in
	#### System Variables ####
	
	#### Wunderground API Variables	####
	APIKEY = "don't want anyone to see it here.  I'll PM it to you if you'd like to try it..." # the user specific API access key
	location = "04769" # string specifying location to pull weather data for
	forecastSource = 1 # 1 = Weather Underground BestForecast | 0 = other source (National Weather Service in United States)
	usePersonalStations = 1 # use personal weather stations for condtions | 1 = true | 0 = false
	#### End Wunderground API Variables ####
	
	#### Wunderground API Radar ####
	radarWU_API_FEATURE = "animatedradar"
	radarWU_API_FORMAT = "gif"
	radarWU_API_LAT = "46.69" # your latitude here. Should be just a number.
	radarWU_API_LON =  "67.99" # your longitude here. Should be just a number.
	try:
		radtest = float(radarWU_API_LAT)
	except Exception, e:
		raise latlon_ValueError("Latitude is not a number: " + str(radarWU_API_LAT))
	#endtry
	try:
		radtest = float(radarWU_API_LON)
	except Exception, e:
		raise latlon_ValueError("Longitude is not a number: " + str(radarWU_API_LON))
	#endtry
	radarWU_API_RADIUS = 150
	radarWU_API_SIZE = 500
	radarWU_API_NUMFRAMES = 15
	radarWU_API_TIMEPOSY = radarWU_API_SIZE - 5
	radarWU_API_PARAMS = "centerlat=" + str(radarWU_API_LAT) + "&centerlon=" + str(radarWU_API_LON) + "&radunits=km&radius=" + str(radarWU_API_RADIUS) + "&width=" + str(radarWU_API_SIZE) + "&height=" + str(radarWU_API_SIZE) + "&newmaps=1&rainsnow=1&reproj.automerc=1&num=" + str(radarWU_API_NUMFRAMES) + "&delay=75&timelabel=1&timelabel.x=0&timelabel.y=" + str(radarWU_API_TIMEPOSY)
	radarWU_API_URL = "https://api.wunderground.com/api/" + APIKEY + "/" + radarWU_API_FEATURE + "/image." + radarWU_API_FORMAT + "?" + radarWU_API_PARAMS
	#print radarWU_API_URL
	radarWU_API_RADIUS_WIDE = 300
	radarWU_API_PARAMS = "centerlat=" + str(radarWU_API_LAT) + "&centerlon=" + str(radarWU_API_LON) + "&radunits=km&radius=" + str(radarWU_API_RADIUS_WIDE) + "&width=" + str(radarWU_API_SIZE) + "&height=" + str(radarWU_API_SIZE) + "&newmaps=1&rainsnow=1&reproj.automerc=1&num=" + str(radarWU_API_NUMFRAMES) + "&delay=75&timelabel=1&timelabel.x=0&timelabel.y=" + str(radarWU_API_TIMEPOSY)
	radarWU_API_URL_WIDE = "https://api.wunderground.com/api/" + APIKEY + "/" + radarWU_API_FEATURE + "/image." + radarWU_API_FORMAT + "?" + radarWU_API_PARAMS
	##### End Wunderground API Radar ####
	
	#### Wunderground Website Satellite ####
	satelliteWU_Animated_LAT = radarWU_API_LAT # your latitude here
	satelliteWU_Animated_LON = radarWU_API_LON # your longitude here
	satelliteWU_Animated_RADIUS = 150
	satelliteWU_Animated_SIZE = radarWU_API_SIZE
	satelliteWU_Animated_NUMFRAMES = 15
	satelliteWU_Animated_TIMEPOSY = satelliteWU_Animated_SIZE - 5
	satelliteWU_Animated_TYPE = "sat_ir4_thumb" # type of satellite image to request
	satelliteWU_Animated_GTT = 107 # ground temperature threshhold. Level to cutoff and leave transparent. 107 is a reasonable value to show clouds but hide land.
	satelliteWUAnimated_URL = "http://wublast.wunderground.com/cgi-bin/WUBLAST?lat=" + str(satelliteWU_Animated_LAT) + "&lon=" + str(satelliteWU_Animated_LON) + "&radunits=km&radius=" + str(satelliteWU_Animated_RADIUS) + "&width=" + str(satelliteWU_Animated_SIZE) + "&height=" + str(satelliteWU_Animated_SIZE) + "&key=" + satelliteWU_Animated_TYPE + "&gtt=" + str(satelliteWU_Animated_GTT) + "&extension=gif&proj=me&num=" + str(satelliteWU_Animated_NUMFRAMES) + "&delay=75&timelabel=1&timelabel.x=0&timelabel.y=" + str(satelliteWU_Animated_TIMEPOSY) + "&basemap=1&borders=1&theme=WUNIDS&api_key=" + APIKEY #&rand=1330554982"
	#print(satelliteWUAnimated_URL)
	satelliteWU_Animated_RADIUS_WIDE = 300
	satelliteWUAnimated_URL_WIDE = "http://wublast.wunderground.com/cgi-bin/WUBLAST?lat=" + str(satelliteWU_Animated_LAT) + "&lon=" + str(satelliteWU_Animated_LON) + "&radunits=km&radius=" + str(satelliteWU_Animated_RADIUS_WIDE) + "&width=" + str(satelliteWU_Animated_SIZE) + "&height=" + str(satelliteWU_Animated_SIZE) + "&key=" + satelliteWU_Animated_TYPE + "&gtt=" + str(satelliteWU_Animated_GTT) + "&extension=gif&proj=me&num=" + str(satelliteWU_Animated_NUMFRAMES) + "&delay=75&timelabel=1&timelabel.x=0&timelabel.y=" + str(satelliteWU_Animated_TIMEPOSY) + "&basemap=1&borders=1&theme=WUNIDS&api_key=" + APIKEY #&rand=1330554982"
	#print(satelliteWUAnimated_URL_WIDE)
	#### End Wunderground Website Satellite ####
	
	#### Intellicast variables ####
	intellicast_url = "http://www.intellicast.com/Local/Forecast.aspx?location=USME0330" # extended forcast url for intellicast.com
	#### End Intellicast Variables ####
	
	#### NOAA Variables ####
	use_NOAA = False # Get NOAA Floodstage Data | False = No , True = Yes
	NOAA_FloodstageURL = "NOAA Floodstage Graph URL" # River Level Floodstage Graph from NOAA
	NOAA_FloodstageTable = "NOAA Floodstage Table URL" # River Level Tabluated Data
	#### End NOAA Variables ####
	##### end user defined variables #####
	pullAtempted = False # stores if the first pull attempt has been made or not
	firstLoop = True # stores if this is the first time the loop has run
	pullfailure = False # set pullfailure to false (no pulls made yet)
	while True: # run script until the process is killed
		if pullAtempted == False and firstLoop == True: # check if no pulls have been made and this is the first pass through the loop (only need to load backup lastPull time once)
			#lastPull = 0
			print "no pull yet"
			lastPullBackup = open(logDirectory + "/lastPullBackup.txt", "r") # file for keeping local copy of weather information incase of program/internet errors and to keep track of lastPull if the program is stopped
			lastPull = pickle.load(lastPullBackup) # read the last time an update was pulled from the api from the localBackup file (used to prevent exessive updates)
			lastPullBackup.close()
			errorCountLog = open((logDirectory + "/wuRadarPullErrorCountLog.txt"), 'r')
			errorCount = pickle.load(errorCountLog)
			errorCountLog.close()
			firstLoop = False # set firstLoop to false
		#endif
		currentTime = time.time() # the current time
		timeDifference = currentTime - lastPull
		print "\ntimeDifference = " + str(timeDifference)
		if timeDifference >= pollInterval: # if it has been longer than pollInterval since the last update, update the data
			print "pulling data"
			backupUsed = False
			##### WU DATA #####
			#### Wunderground API Variables ####
			infoString = "geolookup/conditions/forecast10day/hourly/astronomy/alerts" # specifies what data is pulled from the Wunderground API
			infoString = infoString + time.strftime("/history_%Y%m%d", time.localtime(time.time()))
			print infoString
			WU_API_URL = ('https://api.wunderground.com/api/' + APIKEY + "/" + infoString + "/bestfct:" + str(forecastSource) + "/pws:" + str(usePersonalStations) + "/q/" + location + ".json") # make the url request string
			#### End Wunderground API Variables ####
			print("Pulling -- WU Data -- Location = " + location)
			#############################################################
			## Mark Start of First Pull
			lastPull = time.time() # update last pull to the current time
			#print "updating at : " + time.strftime(' | %I:%M:%S %p %Z' ,time.localtime(float(lastPull))) # convert epoch to localtime of lastPull
			#############################################################
			weatherData = openURL(WU_API_URL, 100, 1) # read WU Weather Data
			if weatherData:
				try:
					####
					json_string = weatherData.read()
					json_split = json_string.split("\n")
					if json_split[0].strip() == "<html>": # not a json file (server sent error document)
						pullfailure = True
						if json_split[1].strip() == "<head><title>High Load</title>":
							print "WU API ERROR -- HIGH LOAD"
						else:
							print "WU API ERROR -- UNKNOWN ERROR"
						#endif
						wuapiErrorLog = open(logDirectory + "/wuapiErrorLog.txt", "w")
						wuapiErrorLog.write(json_string)
						wuapiErrorLog.close()
					else:
						localBackup = open(logDirectory + "/wuAPI_json_current_pickled.txt", "w") # file for keeping local copy of weather information incase of program/internet errors and to keep track of lastPull if the program is stopped
						pickle.dump(json_string, localBackup)
						localBackup.close()
						localBackupReadable = open(logDirectory + "/wuAPI_json_current_log.txt", "w") # readable json for determination of possible calls
						localBackupReadable.write(json_string)
						localBackupReadable.close()
						pullfailure = False
					#endif
					weatherData.close()
					####
				except (httplib.IncompleteRead, socket.timeout, socket.error), e:
					print "json_string Read Error"
					print str(e)
					pullfailure = True
				#endtry
			else:
				pullfailure = True
			#endif
			##### END WU DATA #####
			##### Intellicast Data #####
			print "Pulling -- Intellicast Data"
			web_Data = openURL(intellicast_url) # read Intellicast Weather Data
			if web_Data:
				try:
					####
					webData = web_Data.read()				
					backupCopy2 = open(logDirectory + "/IntellicastForecast_LocalCopy.txt", "w") # load the backup file for writeing
					pickle.dump(webData, backupCopy2)
					intellicastData = intellicastForecast(webData)
					backupCopy2.close()
					web_Data.close()
					####
					pullfailure2 = False
				except (httplib.IncompleteRead, socket.timeout, socket.error), e:
					print "intellicast Read Error"
					print str(e)
					pullfailure2 = True
				#endtry
			else:
				pullfailure2 = True
			#endif
			##### END Intellicast Data #####
			##### Radar/Satellite Data #####
			print "Pulling -- WU Radar"
			##### Radar Image From WU API #####
			radar_Data = openURL(radarWU_API_URL, 100, 1)
			if radar_Data:
				try:
					radarImage = radar_Data.read()
					radarFile = open((logDirectory + "/Images/radarImageA.gif"), 'wb')
					radarFile.write(radarImage)
					radarFile.close()
					(stdout, stderr) = Popen(["gifsicle", "--unoptimize", "--explode", (logDirectory + "/Images/radarImageA.gif"), "--output", (logDirectory + "/Images/radarImage_temp.gif")], stdout=PIPE, stderr=PIPE, close_fds=True).communicate()
					radar_Data.close()
					print "stderr = " + str(stderr).strip()
					if stderr != "":
						print "gifscile error"
						errorCount = errorCount + 1
						errorCountLog = open((logDirectory + "/wuRadarPullErrorCountLog.txt"), 'w')
						pickle.dump(errorCount, errorCountLog)
						errorCountLog.close()
						radarErrorOutput = ("Error Number - " + str(errorCount) + "\nError Time - " + time.strftime('%Y-%m-%d | %I:%M:%S %p %Z' ,time.localtime(float(time.time()))) +"\nError Document\n" + str(radarImage) + "\n")
						radarErrorFile = open((logDirectory + "/wuRadarPullErrorLog.txt"), 'a')
						radarErrorFile.write(radarErrorOutput)
						radarErrorFile.close()
						pullfailure3 = True
						backupUsed = True
					else:
						pullfailure3 = False
					#endif
				except (httplib.IncompleteRead, socket.timeout, socket.error), e:
					print "radarImage Read Error"
					print str(e)
					pullfailure3 = True
					backupUsed = True
				#endtry
			else:
				pullfailure3 = True
				backupUsed = True
			#endif
			##### Radar Image From WU API WIDE #####
			print "Pulling -- WU Radar - Wide"
			radar_Data = openURL(radarWU_API_URL_WIDE, 100, 1)
			if radar_Data:
				try:
					radarImage = radar_Data.read()
					radarFile = open((logDirectory + "/Images/radarImageA_Wide.gif"), 'wb')
					radarFile.write(radarImage)
					radarFile.close()
					(stdout, stderr) = Popen(["gifsicle", "--unoptimize", "--explode", (logDirectory + "/Images/radarImageA_Wide.gif"), "--output", (logDirectory + "/Images/radarImage_Wide_temp.gif")], stdout=PIPE, stderr=PIPE, close_fds=True).communicate()
					radar_Data.close()
					print "stderr = " + str(stderr).strip()
					if stderr != "":
						print "gifscile error"
						errorCount = errorCount + 1
						errorCountLog = open((logDirectory + "/wuRadarPullErrorCountLog.txt"), 'w')
						pickle.dump(errorCount, errorCountLog)
						errorCountLog.close()
						radarErrorOutput = ("Error Number - " + str(errorCount) + "\nError Time - " + time.strftime('%Y-%m-%d | %I:%M:%S %p %Z' ,time.localtime(float(time.time()))) +"\nError Document\n" + str(radarImage) + "\n")
						radarErrorFile = open((logDirectory + "/wuRadarPullErrorLog.txt"), 'a')
						radarErrorFile.write(radarErrorOutput)
						radarErrorFile.close()
						pullfailure3_2 = True
						backupUsed = True
					else:
						pullfailure3_2 = False
					#endif
				except (httplib.IncompleteRead, socket.timeout, socket.error), e:
					print "radarImage Read Error"
					print str(e)
					pullfailure3_2 = True
					backupUsed = True
				#endtry
			else:
				pullfailure3_2 = True
				backupUsed = True
			#endif
			##### Satellite Image From WU #####
			print "Pulling -- WU Satellite"
			satellite_Data = openURL(satelliteWUAnimated_URL, 100, 1)
			if satellite_Data:
				try:
					satelliteImage = satellite_Data.read()
					satelliteFile = open((logDirectory + "/Images/satelliteImageA.gif"), 'wb')
					satelliteFile.write(satelliteImage)
					satelliteFile.close()
					satellite_Data.close()
					(stdout, stderr) = Popen(["gifsicle", "--unoptimize", "--explode", (logDirectory + "/Images/satelliteImageA.gif"), "--output", (logDirectory + "/Images/satelliteImage_temp.gif")], stdout=PIPE, stderr=PIPE, close_fds=True).communicate()
					print "stderr = " + str(stderr).strip()
					if stderr != "":
						print "gifscile error"
						pullfailureSAT = True
						backupUsed = True
					else:
						pullfailureSAT = False
					#endif
				except (httplib.IncompleteRead, socket.timeout, socket.error), e:
					print "satelliteImage Read Error"
					print str(e)
					pullfailureSAT = True
					backupUsed = True
				#endtry
			else:
				pullfailureSAT = True
				backupUsed = True
			#endif
			##### Satellite Image From WU Wide #####
			print "Pulling -- WU Satellite - Wide"
			satellite_Data = openURL(satelliteWUAnimated_URL_WIDE, 100, 1)
			if satellite_Data:
				try:
					satelliteImage = satellite_Data.read()
					satelliteFile = open((logDirectory + "/Images/satelliteImageA_Wide.gif"), 'wb')
					satelliteFile.write(satelliteImage)
					satelliteFile.close()
					satellite_Data.close()
					(stdout, stderr) = Popen(["gifsicle", "--unoptimize", "--explode", (logDirectory + "/Images/satelliteImageA_Wide.gif"), "--output", (logDirectory + "/Images/satelliteImage_Wide_temp.gif")], stdout=PIPE, stderr=PIPE, close_fds=True).communicate()
					print "stderr = " + str(stderr).strip()
					if stderr != "":
						print "gifscile error"
						pullfailureSAT_2 = True
						backupUsed = True
					else:
						pullfailureSAT_2 = False
					#endif
				except (httplib.IncompleteRead, socket.timeout, socket.error), e:
					print "satelliteImage Read Error"
					print str(e)
					pullfailureSAT_2 = True
					backupUsed = True
				#endtry
			else:
				pullfailureSAT_2 = True
				backupUsed = True
			#endif
			##### END Radar/Satellite Data #####
			##### NOAA Floodstage Data #####
			if use_NOAA == True:
				print "Pulling -- NOAA Floodstage Image"
				riverData = openURL(NOAA_FloodstageURL) # read current River Floodstage Graph
				if riverData:
					try:
						riverLevelImage = riverData.read()
						riverFile = open((logDirectory + "/Images/riverLevelImage.png"), 'wb')
						riverFile.write(riverLevelImage)
						riverFile.close()
						riverData.close()
					except (httplib.IncompleteRead, socket.timeout, socket.error), e:
						print "riverLevelImage Read Error"
						print str(e)
					#endtry
				else:
					pass
				#endif
				print "Pulling -- NOAA Floodstage Table"
				riverTable = openURL(NOAA_FloodstageTable, 10, 4) # read current River Floodstage Level Info
				if riverTable:
					try:
						riverLevelTable = riverTable.read()
						riverTable.close()
						pullfailure4 = False
					except (httplib.IncompleteRead, socket.timeout, socket.error), e:
						print "riverLevelTable Read Error"
						print str(e)
						pullfailure4 = True
					#endtry
				else:
					pullfailure4 = True
				#endif
			#endif
			##### END NOAA Floodstage Data #####
			######
			if pullfailure == True:
				#display results with warning about using backup data
				backupCopy = open(logDirectory + "/wuAPI_json_current_pickled.txt", "r") # load the backup file for reading
				weatherData = pickle.load(backupCopy) # read the backup data
				backupCopy.close()
				backupUsed = True
			else:
				#lastPull = time.time() # update last pull to the current time
				lastPullBackup = open(logDirectory + "/lastPullBackup.txt", "w") # open lastPullBackup.txt for writeing
				pickle.dump(lastPull, lastPullBackup) # write the new last poll time to the log file
				lastPullBackup.close()
			#endif
			#######
			if pullfailure2 == True:
				## Intelicast
				# read from localBackup
				backupCopy2 = open(logDirectory + "/IntellicastForecast_LocalCopy.txt", "r") # load the backup file for reading
				webData = pickle.load(backupCopy2) # read the backup data
				intellicastData = intellicastForecast(webData)
				backupCopy2.close()
				backupUsed = True
			else:
				pass
			#endif
			#######
			if use_NOAA == True:
				if pullfailure4 == True:
					riverLevelBackup = open(logDirectory + "/NOAA_RiverLevelTable_LocalCopy.txt", "r")
					riverLevelTable = pickle.load(riverLevelBackup)
					riverLevelBackup.close()
					backupUsed = True
				else:
					riverLevelBackup = open(logDirectory + "/NOAA_RiverLevelTable_LocalCopy.txt", "w")
					pickle.dump(riverLevelTable, riverLevelBackup)
					riverLevelBackup.close()
				#endif
			else:
				riverLevelTable = ""
				pullfailure4 = False
			#endif
			#######
			print "Just Pulled -- Makeing Output"
			try:
				outputString = makeOutput(json_string, intellicastData, lastPull, riverLevelTable, backupUsed, pullfailure, pullfailure2, pullfailure3, pullfailure4, pullfailureSAT)
				#print outputString
			except (httplib.IncompleteRead, socket.timeout, socket.error), e:
				print "Makeing Output Error"
				print str(e)
			else:
				weatherOutput = open(logDirectory + "/conkyWeather_arclance_lua_log.txt", "w") # load output file for writeing
				weatherOutput.write(outputString) # write output to text file for parsing by conky
				weatherOutput.close()
				print "Output Written"
				#break
			#endtry
			pullAtempted = True # set pullAtempted to true
		elif pullAtempted == False:
			print "using backup"
			#read from localBackup
			#display results with warning about using backup data
			backupCopy = open(logDirectory + "/wuAPI_json_current_pickled.txt", "r") # load the backup file for reading
			json_string = pickle.load(backupCopy) # read the backup data
			backupCopy.close()
			## Intelicast
			# read from localBackup
			backupCopy2 = open(logDirectory + "/IntellicastForecast_LocalCopy.txt", "r") # load the backup file for reading
			webData = pickle.load(backupCopy2) # read the backup data
			intellicastData = intellicastForecast(webData)
			backupCopy2.close()
			###
			if use_NOAA == True:
				riverLevelBackup = open(logDirectory + "/NOAA_RiverLevelTable_LocalCopy.txt", "r")
				riverLevelTable = pickle.load(riverLevelBackup)
				riverLevelBackup.close()
			else:
				riverLevelTable = ""
			#endif		
			# make output
			outputString = makeOutput(json_string, intellicastData, lastPull, riverLevelTable, True)
			weatherOutput = open(logDirectory + "/conkyWeather_arclance_lua_log.txt", "w") # load output file for writeing
			weatherOutput.write(outputString) # write output to text file for parsing by conky
			weatherOutput.close()					
			#print outputString
			print "Output Written"
		#endif
		time.sleep(5) # sleep for 5 seconds due to time measurement errors (just being safe)
		try: # catch errors returned by time.sleep() for debugging
			if pullfailure == True: # check if the pull failed
				nextUpdateSeconds = float(time.time() + (5*60))
				nextUpdateTime_Log = open (logDirectory + "/nextUpdateTime_Pickled.txt", "w")
				pickle.dump(nextUpdateSeconds, nextUpdateTime_Log)
				nextUpdateTime_Log.close()
				#nextUpdate = time.strftime('%Y-%m-%d | %I:%M:%S %p %Z' ,time.localtime(float(time.time() + (5*60)))) # convert epoch to localtime of lastPull
				nextUpdate = time.strftime('%Y-%m-%d | %I:%M:%S %p %Z', time.localtime(nextUpdateSeconds)) # convert epoch to localtime of lastPull
				print "Next Update At: " + nextUpdate
				time.sleep(5*60) # wait five minutes until next check if Wunderground Weather Data pull failed
			else: # calculate amount of time to wait until next update
				currentTime = time.time() # the current time
				timeDifference = float(currentTime) - float(lastPull)
				print "timeDifference = " + str(timeDifference)
				if timeDifference < pollInterval:
					print "waiting for " + str(pollInterval - timeDifference) + " s"
					nextUpdateSeconds = float(time.time() + (pollInterval - timeDifference)) # for logging
					nextUpdateTime_Log = open (logDirectory + "/nextUpdateTime_Pickled.txt", "w")
					pickle.dump(nextUpdateSeconds, nextUpdateTime_Log)
					nextUpdateTime_Log.close()
					#nextUpdate = time.strftime('%Y-%m-%d | %I:%M:%S %p %Z' ,time.localtime(float(time.time() + (pollInterval - timeDifference)))) # convert epoch to localtime of lastPull
					nextUpdate = time.strftime('%Y-%m-%d | %I:%M:%S %p %Z', time.localtime(nextUpdateSeconds)) # convert epoch to localtime of lastPull
					print "Next Update At: " + nextUpdate
					time.sleep(pollInterval - timeDifference) # wait until next schedualed update interval
				#endif
			#endif
		except (IOError), e:
			print "Invalid time.sleep() Argument Error -- " + str(e)
			print "currentTime = " + str(float(currentTime))
			print "lastPull = " + str(float(lastPull))
			print "timeDifference = " + str(timeDifference)
			print "pollInterval = " + str(pollInterval)
			print "pollInterval - timeDifference = " + str(pollInterval - timeDifference)
			nextUpdateSeconds = float(time.time() + (10*60))
			nextUpdateTime_Log = open (logDirectory + "/nextUpdateTime_Pickled.txt", "w")
			pickle.dump(nextUpdateSeconds, nextUpdateTime_Log)
			nextUpdateTime_Log.close()
			nextUpdate = time.strftime('%Y-%m-%d | %I:%M:%S %p %Z', time.localtime(nextUpdateSeconds)) # convert epoch to localtime of lastPull
			print "Next Update At: " + nextUpdate
			time.sleep(10*60) # wait 10 minuets until next check if time.sleep(pollInterval - timeDifference) returns an error
		#endtry	
	#endwhile
#enddef

def makeOutput(json_string, intellicastData, lastPull, riverLevelTable, backupUsed = False, pullFailure = False, pullFailure2 = False, pullFailure3 = False, pullFailure4 = False, pullFailureSAT = False): # makes the output string
	print 'backupUsed: ' + str(backupUsed)
	print 'pullFailure: ' + str(pullFailure)
	print 'pullFailure2: ' + str(pullFailure2)
	print 'pullFailure3: ' + str(pullFailure3)
	print 'pullFailure4: ' + str(pullFailure4)
	print 'pullFailureSAT: ' + str(pullFailureSAT)
	############
	luaOutput = []
	##### River Level (Flood Monitoring) #####
	if use_NOAA == True:
		riverLevelTableSplit = riverLevelTable.split('\n')
		dateSplit = [0,0,0]
		dateSplit[0] = (time.strftime('%Y' ,time.localtime(float(lastPull))))
		dateStart = riverLevelTableSplit[36].find("<td nowrap>") + len("<td nowrap>")
		dateEnd = riverLevelTableSplit[36].find("</td>")
		dateString = riverLevelTableSplit[36][dateStart:dateEnd]
		dateSplit[1] = (dateString.split(' ')[0].split('/')[0])
		dateSplit[2] = (dateString.split(' ')[0].split('/')[1])
		timeUTCSplit = dateString.split(' ')[1].split(':')
		[localTime, localDate, AMorPM] = convertTime_to_Eastern(timeUTCSplit, dateSplit) #
		currentRiverReading_Date = "-".join(localDate)
		currentRiverReading_Time12hr = ":".join(localTime) + " " + AMorPM # make local time string
		currentRiverReading_Level = riverLevelTableSplit[37][21:27].strip('ft</') + ' ft'
		print currentRiverReading_Date + " " + str(currentRiverReading_Time12hr) + " " + str(currentRiverReading_Level)
		localTime.append(AMorPM)
		riverDataLua = [currentRiverReading_Level,localDate,localTime]
		luaOutput.append(riverDataLua)
	else:
		luaOutput.append([])
	#endif
	#### End River Level (Flood Monitoring) ####
	#### make final output string ####
	lastUpdate = time.strftime(' | %I:%M:%S %p %Z' ,time.localtime(float(lastPull))) # convert epoch to localtime of lastPull
	print "lastUpdate = " + lastUpdate
	networkStateLua = [[0,[0,0,0,0,0]],[0,[0,0,0,0,0]]] ## [[backupUsed,[W,I,R,S,N]],[connState,[W,I,R,S,N]]]
	### Make backupString ###
	if backupUsed == True:
		networkStateLua[0][0] = 1
		if pullAtempted == False:
			networkStateLua[0][1] = [1,1,1,1,1]
		else:
			if pullFailure == True:
				networkStateLua[0][1][0] = 1
			#endif
			if pullFailure2 == True:
				networkStateLua[0][1][1] = 1
			#endif
			if pullFailure3 == True:
				networkStateLua[0][1][2] = 1
			#endif
			if pullFailureSAT == True:
				networkStateLua[0][1][3] = 1
			#endif
			if pullFailure4 == True:
				networkStateLua[0][1][4] = 1
			#endif
		#endif
	#endif
	### Make connectionString ###
	if pullAtempted == True and ((pullFailure == True) or (pullFailure2 == True) or (pullFailure3 == True) or (pullFailure4 == True) or (pullFailureSAT == True)):
		networkStateLua[1][0] = 1
		if pullFailure == True:
			networkStateLua[1][1][0] = 1
		#endif
		if pullFailure2 == True:
			networkStateLua[1][1][1] = 1
		#endif
		if pullFailure3 == True:
			networkStateLua[1][1][2] = 1
		#endif
		if pullFailureSAT == True:
			networkStateLua[1][1][3] = 1
		#endif
		if pullFailure4 == True:
			networkStateLua[1][1][4] = 1
		#endif
	#endif
	luaOutput.append(networkStateLua)
	####
	iCast_Lua = []
	for i in xrange(len(intellicastData)):
		iCast_Lua.append([intellicastData[i].getConditions(), intellicastData[i].getHiTemp(), intellicastData[i].getLowTemp(), intellicastData[i].getSunrise(), intellicastData[i].getSunset(), intellicastData[i].getMoonrise(), intellicastData[i].getMoonset(), intellicastData[i].getUVLevel(), intellicastData[i].getHumidity(), intellicastData[i].getPrecipChance(), intellicastData[i].getSnowChance(), intellicastData[i].getCloudCoverage(), intellicastData[i].getMoonPhase(), intellicastData[i].getWindSpeed(), intellicastData[i].getWindDirection()])
	#endfor
	luaOutput.append(iCast_Lua)
	luaOutput = str(luaOutput).replace("[","{").replace("]","}").replace("'{","{").replace("}'","}").replace("'\"","'").replace("\"'","'")
	return "return " + luaOutput
#enddef

###### Intellicast Section ######
def intellicastForecast(web_data):
	web_dataSplit = web_data.split("\n")
	daynum = -1
	for i in xrange(len(web_dataSplit)):
		currentLine = web_dataSplit[i].strip()
		checkConditions = currentLine.find('<td style="padding-top:15px;">')
		checkHiTemp = currentLine.find('<td><span class="Hi">')
		checkRise = currentLine.find("Rise:</strong>")
		checkSet = currentLine.find("Set:</strong>")
		checkUV = currentLine.find('<strong>UV Index:</strong>')
		checkHumidity = currentLine.find('Relative Humidity:</strong>')
		checkPrecipChance = currentLine.find('Precipitation:</strong>')
		checkSnowChance = currentLine.find('Snow Probability:</strong>')
		checkCloudCoverage = currentLine.find('Cloud Coverage:</strong>')
		checkMoonPhase = currentLine.find('Moon Phase:</strong>')
		checkWindSpeed = currentLine.find('Wind Speed:</strong>')
		checkWindDirection = currentLine.find('Wind Direction:</strong>')	
		if currentLine == '<table id="extended">':
			daynum = daynum + 1
			makeDataObj = "day" + str(daynum) + " = forecastData()"
			exec makeDataObj
			makeGlobal = "global day" + str(daynum)
			exec makeGlobal
			riseType = 0
			setType = 0
		elif checkConditions != (-1):
			checkConditionsStart = currentLine.find('<br />')
			stringStart = int(checkConditionsStart + len('<br />'))
			stringEnd = currentLine.find('</td>')
			conditions = currentLine[stringStart:stringEnd].strip()
			setDataObj = "day" + str(daynum) + ".setConditions(conditions)"
			exec setDataObj
		elif checkHiTemp != (-1):
			stringStart = int(checkHiTemp + len('<td><span class="Hi">'))
			stringEnd = currentLine.find('</span><br /><span class="Lo">')
			hightemp = currentLine[stringStart:stringEnd].strip('&deg')
			setDataObj = "day" + str(daynum) + ".setHiTemp(hightemp)"
			exec setDataObj
			findLowTemp = currentLine.find('<span class="Lo">')
			stringStart = int(findLowTemp + len('<span class="Lo">'))
			stringEnd = currentLine.find('</span></td>')
			lowtemp = currentLine[stringStart:stringEnd].strip('&deg;')
			setDataObj = "day" + str(daynum) + ".setLowTemp(lowtemp)"
			exec setDataObj
		elif checkRise != (-1):
			stringStart = int(checkRise + len("Rise:</strong>"))
			stringEnd = currentLine.find('</td>')
			if riseType == 0:
				sunRise = currentLine[stringStart:stringEnd].strip()
				setDataObj = "day" + str(daynum) + ".setSunrise(sunRise)"
				exec setDataObj
				riseType += 1
			elif riseType == 1:
				moonRise = currentLine[stringStart:stringEnd].strip()
				setDataObj = "day" + str(daynum) + ".setMoonrise(moonRise)"
				exec setDataObj
			#endif
		elif checkSet != (-1):
			stringStart = int(checkSet + len("Rise:</strong>"))
			stringEnd = currentLine.find('</td>')
			if setType == 0:
				sunSet = currentLine[stringStart:stringEnd].strip()
				setDataObj = "day" + str(daynum) + ".setSunset(sunSet)"
				exec setDataObj
				setType += 1
			elif setType == 1:
				moonSet = currentLine[stringStart:stringEnd].strip()
				setDataObj = "day" + str(daynum) + ".setMoonset(moonSet)"
				exec setDataObj			
			#endif
		elif checkUV != (-1):
			stringStart = int(checkUV + len('<strong>UV Index:</strong>'))
			stringEnd = currentLine.find('<br />')
			UVLevel = currentLine[stringStart:stringEnd].strip()
			setDataObj = "day" + str(daynum) + ".setUVLevel(UVLevel)"
			exec setDataObj
		elif checkHumidity != (-1):
			stringStart = int(checkHumidity + len('Relative Humidity:</strong>'))
			stringEnd = currentLine.find('<br />')
			humidity = currentLine[stringStart:stringEnd].strip()
			setDataObj = "day" + str(daynum) + ".setHumidity(humidity)"
			exec setDataObj				
		elif checkPrecipChance != (-1):
			stringStart = int(checkPrecipChance + len('Precipitation:</strong>'))
			stringEnd = currentLine.find('<br />')
			precipChance = currentLine[stringStart:stringEnd].strip()
			setDataObj = "day" + str(daynum) + ".setPrecipChance(precipChance)"
			exec setDataObj					
		elif checkSnowChance != (-1):
			snowChance = str(web_dataSplit[i+1]).strip().strip(" <br/>")
			setDataObj = "day" + str(daynum) + ".setSnowChance(snowChance)"
			exec setDataObj		
		elif checkCloudCoverage != (-1):
			stringStart = int(checkCloudCoverage + len('Cloud Coverage:</strong>'))
			stringEnd = currentLine.find('<br />')
			cloudCoverage = currentLine[stringStart:stringEnd].strip()
			setDataObj = "day" + str(daynum) + ".setCloudCoverage(cloudCoverage)"
			exec setDataObj					
		elif checkMoonPhase != (-1):
			stringStart = int(checkMoonPhase + len('Moon Phase:</strong>'))
			stringEnd = currentLine.find('<br />')
			moonPhase = currentLine[stringStart:stringEnd].strip()
			setDataObj = "day" + str(daynum) + ".setMoonPhase(moonPhase)"
			exec setDataObj		
		elif checkWindSpeed != (-1):
			stringStart = int(checkWindSpeed + len('Wind Speed:</strong>'))
			stringEnd = currentLine.find('(')
			windSpeed = currentLine[stringStart:stringEnd].strip(' Mph') # in mph
			setDataObj = "day" + str(daynum) + ".setWindSpeed(windSpeed)"
			exec setDataObj
		elif checkWindDirection != (-1):
			stringStart = int(checkWindDirection + len('Wind Direction:</strong>'))
			stringEnd = currentLine.find('(')
			windDirectionDeg = currentLine[stringStart:stringEnd].strip(' &deg;') # in degrees
			stringStart = stringEnd + 1
			stringEnd = currentLine.find(')')
			windDirectionCard = currentLine[stringStart:stringEnd].strip() # in degrees
			setDataObj = "day" + str(daynum) + ".setWindDirection(windDirectionDeg, windDirectionCard)"
			exec setDataObj											
		#endif		
	#endfor
	return [day0,day1,day2,day3,day4,day5,day6,day7,day8,day9]
#enddef	
	
class forecastData():
	
	def __init__(self):
		self._Conditions = "N/A"
		self._highTemp = "N/A"
		self._lowTemp = "N/A"
		self._sunRiseTime = "N/A"
		self._sunSetTime = "N/A"
		self._moonRiseTime = "N/A"
		self._moonSetTime = "N/A"
		self._UVLevel =  "N/A"
		self._Humidity =  "N/A"
		self._precipChance =  "N/A"
		self._snowChance =  "N/A"
		self._cloudCoverage =  "N/A"
		self._moonPhase =  "N/A"
		self._windSpeed =  "N/A"
		self._windDirDeg = "N/A"
		self._windDirCard = "N/A"
	#enddef
	
	def setConditions(self, conditions):
		self._Conditions = conditions
	#enddef
	
	def getConditions(self):
		return self._Conditions
	#enddef		
	
	def setHiTemp(self, highTemp):
		self._highTemp = highTemp
	#enddef
	
	def getHiTemp(self):
		return self._highTemp
	#enddef	
	
	def setLowTemp(self, lowTemp):
		self._lowTemp = lowTemp
	#enddef
	
	def getLowTemp(self):
		return self._lowTemp
	#enddef
	
	def setSunrise(self, sunRiseTime):
		self._sunRiseTime = sunRiseTime
	#enddef
	
	def getSunrise(self):
		return self._sunRiseTime
	#enddef
	
	def setSunset(self, sunSetTime):
		self._sunSetTime = sunSetTime
	#enddef
	
	def	getSunset(self):
		return self._sunSetTime
	#enddef
	
	def setMoonrise(self, moonRiseTime):
		self._moonRiseTime = moonRiseTime
	#enddef
	
	def getMoonrise(self):
		return self._moonRiseTime
	#enddef	
	
	def setMoonset(self, moonSetTime):
		self._moonSetTime = moonSetTime
	#enddef
	
	def getMoonset(self):
		return self._moonSetTime
	#enddef
	
	def setUVLevel(self, UVLevel):
		self._UVLevel = UVLevel
	#enddef
	
	def getUVLevel(self):
		return self._UVLevel
	#enddef
	
	def setHumidity(self, Humidity):
		self._Humidity = Humidity
	#enddef	
	
	def getHumidity(self):
		return self._Humidity
	#enddef
	
	def setPrecipChance(self, precipChance):
		self._precipChance = precipChance
	#enddef
	
	def getPrecipChance(self):
		return self._precipChance
	#enddef
	
	def setSnowChance(self, snowChance):
		self._snowChance = snowChance
	#enddef
	
	def getSnowChance(self):
		return self._snowChance
	#enddef
	
	def setCloudCoverage(self, cloudCoverage):
		self._cloudCoverage = cloudCoverage
	#enddef
	
	def getCloudCoverage(self):
		return self._cloudCoverage
	#enddef
	
	def setMoonPhase(self, moonPhase):
		self._moonPhase = moonPhase
	#enddef
	
	def getMoonPhase(self):
		return self._moonPhase
	#enddef
	
	def setWindSpeed(self, windSpeed):
		self._windSpeed = windSpeed
	#enddef
	
	def getWindSpeed(self):
		return self._windSpeed
	#enddef
	
	def setWindDirection(self, windDirDeg, windDirCard):
		self._windDirDeg = windDirDeg
		self._windDirCard = windDirCard
	#enddef
	
	def getWindDirection(self):
		return [self._windDirDeg,self._windDirCard]
	#enddef
#enddef
#### End Intellicast Section ####

def convertTime_to_Eastern(timeUTCSplit, dateSplit):
	timeStruct = parser.parse(dateSplit[0] + "-" + dateSplit[1] + "-" + dateSplit[2] + " " + timeUTCSplit[0] + ":" + timeUTCSplit[1]).utctimetuple()
	timeEpoch = timegm(timeStruct)
	localStruct = time.localtime(timeEpoch)
	localTime = time.strftime("%I:%M",localStruct)
	localDate = time.strftime("%y-%m-%d",localStruct)
	AMorPM = time.strftime("%p",localStruct)
	return [localTime.split(":"), localDate.split("-"), AMorPM]
#enddef

conkyWeather()

and the .lua file with my input;

--[[
conky_Weather_arclance v6.2.1 by arclance

own_window_title weatherConky

created     : 2012-07
last updated: 2012-09-26

Changelog
v1.8.3 - 2012-09-26
	added installDirectory information to startup debug output

v1.8.2 - 2012-09-23
	added version information to startup debug output

v1.8.1 - 2012-09-14
	update button script to work with more window managers
	fix some mistakenly global variables
	fix undeclared global variables
	remove unecessary variable firstBackup from the line2_UpdateMonitor() function

v1.8 - 2012-09-03
	get 10 day forecast (don't always get 10 days) show all that there are, up to 9 days

v1.7 - 2012-09-01
	add toggle to show radar and satallite images with a larger radius

v1.6 - 2012-08-06
	add conky_stop_xdotool() to kill xdotool if this conky is the last running conky using buttons.

v1.5 - 2012-08-04
	add option to specify lua background color in script instead of external text file.
	clean up and consitently format code.
	
v1.4 - 2012-08-03
	change buttons to have also store position and size variables in the "buttons" global variable.
		makes resizable/moveable buttons more smooth and allows buttons to positioned relative to each other more easily.
	make NOAA floodstage data optional. Controlled by use_NOAA variable

v1.3.2 - 2012-08-01
	use "icon_url" in hourly data to detrmine if night or day images should be used
	
v1.3.1 - 2012-07-31
	added dependency list
	
v1.3 - 2012-07-30
	add large radar image mode
	fix scrolling alerts for all stringAdvance values
	only use one function for fiveDayWeather columns

v1.2 - 2012-07-25
	added scrolling alert message lua function

v1.1 - 2012-07-23
	added hourly display by button
	update button script
	move processing/calculations of/on the json data that needs to be done every time it is parsed to update section so it does not run every update
		store global data in the weatherData table (psuedo object)
	
v1.0 - 2012-07-22
	finshed fiveday weather output
	
v0.3 - 2012-07-20
	started fiveday weather output
	only parse json when it changes (when the python script updates it)
		doubles cpu use if parsed every update
	
v0.2
	added weather images
v0.1
	added radar and satellite images

######################################
Requires
Font
	DejaVu Sans Mono - recommended may work with other monospace fonts
	
Weather Icons - Included
	VClouds Weather Icons - http://vclouds.deviantart.com/art/VClouds-Weather-Icons-179152045
	moonicons from conkyForecast - http://ubuntuforums.org/showthread.php?t=869328

luajson - http://www.eharning.us/wiki/luajson/
	json interpreter for lua
	package in Debian is "lua-json" (only in Wheezy and Sid)

python2.7
	Libraries used
	cPickle or pickle (cPickle is faster use it if possible)
	urllib2
	httplib
	socket
	json
	time
	datetime
	dateutil
	calendar
	subprocess
	
	packages in Debian are (only in Wheezy and Sid)
		python2.7 
		python-dateutil

gifsicle - http://www.lcdf.org/gifsicle/
	used to break the animated radar and satellite gifs into individual images for use in conky
	package in Debian is "gifsicle"
	
xdotool & libxdo - http://www.semicomplete.com/projects/xdotool/
	version >= 2.20110530.1 (only in Sid (also in #! repository))
	packages in Debian are "xdotool" and "libxdo2"

xwininfo
	is in the "x11-utils" package in Debian.

conky
	v1.9.0 or higher recommended.
	May work with v1.8.0.
	
	Do Not Use v1.8.1. Several things were broken in this release.
	
	lua support with cairo and imlib2 bindings required.

#############################################
Warnings
I use a development version of conky (v1.9.1_pre2429 right now) you may not see identical results if you are using the conky package from your distro.

---> Do not use conky v1.8.1 it is broken. <----

The luajson package is not in Debian Squeeze.
python 2.7 is not in Debian Squeeze.
The required version of xdotool and libxdo are not in Debian Squeeze or Wheezy but they are in Sid and the #! repository.
]]

require 'cairo'
require 'imlib2'
require 'json'

--######################
scrotMode = false
use_NOAA = false --# Show NOAA floodstage data or not.
luaBG_cType = false --# if luaBG color settings are imported from external file set to true | if set to false the value from luaBG_Color below is used.
--######################
installDirectory = "/home/jedi/conkyWeather_arclance_v6.2.1_2012-09-26" --# location of the conkyWeather_arclance_v6.2.py file
print("installDirectory = "..installDirectory)
logDirectory = installDirectory.."/log"
moonImageLocation = installDirectory.."/images/moonicons"
weatherImageLocation = installDirectory.."/images/weather-icons_VClouds/"
if luaBG_cType == true then
	luaBG_Settings_Location = ""
else
	luaBG_Color = {0,0,0,0}
end --# if luaBG_cType == true then
--######################
color0_R,color0_G,color0_B,color0_A = (204/255),(153/255),0,1 -- Yellow #CC9900
color1_R,color1_G,color1_B,color1_A = (238/255),(118/255),0,1 -- Orange #EE7600
color3_R,color3_G,color3_B,color3_A = (139/255),0,0,1 -- Shade Color #8B0000
font = "DejaVu Sans Mono"
fSize = 13
bfSize = 12
if tonumber(conky_parse('${updates}')) < 2 then --# don't reset these global variables if reloading the lua script
	print("conkyWeather_arclance_v6.2")
	--#### Setup Buttons ####
	buttons = {}--this table initially holds the values from the buttons
	buttons["rad/sat_toggle"] = {state=0,width=20,height=74,bl_x=902}
	buttons["daily_hourly"] = {state=0,width=20,height=63,bl_x=902}
	buttons["daily_toggle1"] = {state=0,width=20,height=36,bl_x=902}
	buttons["hourly_toggle1"] = {state=0,width=20,height=36,bl_x=902}
	buttons["small_Close/Wide"] = {state=0,width=136,height=272,bl_x=923,bl_y=273}
	buttons["large_Close/Wide"] = {state=0}
	conkyWindowTitle = "weatherConky" --# the title of the conky window (own_window_title) to make it easier to configure
	tempFileName = "xdo" --# the name of the temporary file to store mouse click locations in (makes configuring for use in more than one conky easier)
	--###### Non-User Configurable Button Settings ######
	xdotool_window_number = nil
	xdotool_window_number2 = nil
	abstlx = nil
	abstly = nil
	--###### End Setup Buttons ######
	--###### Setup Protected Global Variables ######
	updateCheck = 0
	impass_data = nil
	nextUpdateSeconds_Old = nil
	wuAPI_Parsed = nil
	weatherData = {}
	weatherData.alertString_Start = 1
	weatherData.alertString_End = 1
	weatherData.headerEnd_Y = 0
	local f = io.open((logDirectory.."/moonStateBackup.txt"), "r")
	moonState = f:read("*l")
	f:close()
	f = nil
	print(moonState)
	--###### End Setup Protected Global Variables ######
end --# if tonumber(conky_parse('${updates}')) < 2 then
--######################

function conky_main()
	if conky_window == nil then return end
	local cs = cairo_xlib_surface_create(conky_window.display, conky_window.drawable, conky_window.visual, conky_window.width, conky_window.height)
	local cr = cairo_create(cs)
	local localx,localy,localnowx,localnowy = clickfunction()--this line activates the clickfunction and sets the click coordinates
	--#################################################################################################
	cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE)
	local extents = cairo_text_extents_t:create()
	tolua.takeownership(extents)
	cr = draw_bg(cr)
	local currentTime = os.time()
	--#################################################################
	cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL)
	cairo_set_font_size (cr, fSize)
	--#################################################################
	local nextUpdateTime_Log = io.open(logDirectory.."/nextUpdateTime_Pickled.txt", "r")
	local nextUpdateSeconds = tonumber(((nextUpdateTime_Log:read("*l")):gsub("F","")))
	nextUpdateTime_Log:close()
	nextUpdateTime_Log = nil
	if (nextUpdateSeconds ~= nextUpdateSeconds_Old) then --# only parse json data if it has changed (parsing is cpu intensive)
		nextUpdateSeconds_Old = nextUpdateSeconds
		local wuAPI_File = io.open((logDirectory.."/wuAPI_json_current_log.txt"),"r")
		local wuAPI_Raw = wuAPI_File:read("*a")
		wuAPI_File:close()
		wuAPI_File = nil
		wuAPI_Parsed = json.decode(wuAPI_Raw)
		weatherData.stateData = assert(loadfile(logDirectory.."/conkyWeather_arclance_lua_log.txt"))()
		--###### Format Data That Is Not Used Raw #####
		local observationTime_Epoch = tonumber(wuAPI_Parsed['current_observation']["observation_epoch"])
		weatherData.obsDate = os.date('%y-%m-%d',observationTime_Epoch)
		weatherData.obsTime = os.date('%I:%M:%S %p',observationTime_Epoch)
		weatherData.lastUpdate = os.date('%I:%M:%S %p',tonumber(wuAPI_Parsed['current_observation']["local_epoch"]))
		weatherData.SunsetHour = tonumber(wuAPI_Parsed['moon_phase']['sunset']['hour'])
		weatherData.SunsetMin = wuAPI_Parsed['moon_phase']['sunset']['minute']
		weatherData.SunsetTime_Seconds = (weatherData.SunsetHour*3600) + (tonumber(weatherData.SunsetMin)*60)
		if weatherData.SunsetHour > 12 then
			weatherData.SunsetHour = (weatherData.SunsetHour - 12)
			weatherData.Sunset_AMorPM = 'PM'
		else
			weatherData.Sunset_AMorPM = 'AM'
		end --# if weatherData.SunsetHour > 12 then
		weatherData.SunriseHour = tonumber(wuAPI_Parsed['moon_phase']['sunrise']['hour'])
		weatherData.SunriseMin = wuAPI_Parsed['moon_phase']['sunrise']['minute']
		weatherData.SunriseTime_Seconds = (weatherData.SunriseHour*3600) + (tonumber(weatherData.SunriseMin)*60)
		if weatherData.SunriseHour > 12 then
			weatherData.SunriseHour = (weatherData.SunriseHour - 12)
			weatherData.Sunrise_AMorPM = 'PM'
		else
			weatherData.Sunrise_AMorPM = 'AM'
		end --# if weatherData.SunriseHour > 12 then
		weatherData.AstronHour = wuAPI_Parsed['moon_phase']['current_time']['hour']
		weatherData.AstronMin = wuAPI_Parsed['moon_phase']['current_time']['minute']
		weatherData.AstronTime_Seconds = (tonumber(weatherData.AstronHour)*3600) + (tonumber(weatherData.AstronMin)*60)
		weatherData.isNight = false
		if (weatherData.AstronTime_Seconds) > (weatherData.SunsetTime_Seconds) then
			weatherData.isNight = true
		elseif (weatherData.AstronTime_Seconds) < (weatherData.SunriseTime_Seconds) then
			weatherData.isNight = true
		else
			weatherData.isNight = false	
		end --# if (weatherData.AstronTime_Seconds) > (weatherData.SunsetTime_Seconds) then
		print("isNight = "..tostring(weatherData.isNight).."\n")
		weatherData.moon_Percent = wuAPI_Parsed['moon_phase']['percentIlluminated']
		weatherData.moon_Age = wuAPI_Parsed['moon_phase']['ageOfMoon']
		weatherData.moon_Phase,weatherData.moon_Image = convertMoonPhase(tonumber(weatherData.moon_Percent),moonState)
		--#################################################################
		weatherData.Alerts = wuAPI_Parsed['alerts']
		weatherData.alertString = ""
		if #weatherData.Alerts > 0 then
			for i = 1, #weatherData.Alerts do
				weatherData.alertString = weatherData.alertString..weatherData.Alerts[i]['message']:gsub("\u000A","\n"):gsub("\n ","\n"):gsub(" \n","\n"):gsub("\n\n\n\n\n\n","\n"):gsub("\n\n\n\n\n","\n"):gsub("\n\n\n\n","\n"):gsub("\n\n\n","\n"):gsub("\n\n","\n"):gsub("\n","",1)
				weatherData.alertString = (weatherData.alertString:sub(0, (#weatherData.alertString - 3)))..((weatherData.alertString:sub((#weatherData.alertString - 2),#weatherData.alertString)):gsub("\n","")).."||" -- string trailing newlines
			end --# for i = 1, #weatherData.Alerts do
			weatherData.alertString = weatherData.alertString:gsub("\n","|")
			--print(weatherData.alertString)
		end --# if #weatherData.Alerts > 0 then
		weatherData.alertString_Start = 1
		weatherData.alertString_End = 1
		--#################################################################
		weatherData.historyToday = wuAPI_Parsed['history']
	end --# if (wuAPI_Raw ~= wuAPI_Raw_New) then
	--######### Line 1 (Scrolling Alert) ##############################
	local blx = 0
	local bly = 24
	local weatherArea_Width = 900
	if buttons["rad/sat_toggle"]["state"] == 0 then
		cr,blx,bly = scrollingAlerts(cr, extents, wuAPI_Parsed, weatherData, blx, bly, 10 , 115)
		--######### End Line 1 ############################################
		--######### Line 2 ################################################
		cr,blx,bly = line2_UpdateMonitor(cr, blx, bly, extents, weatherArea_Width, currentTime, nextUpdateSeconds)
		weatherData.headerEnd_Y = bly
	else
		bly = weatherData.headerEnd_Y
	end --# if buttons["rad/sat_toggle"] == 0 then
	--######### End Line 2 ###########################################
	local color = nil
	local fill = nil
	local button_name = "daily_hourly"
	if buttons[button_name]["bl_y"] == nil then
		buttons[button_name]["bl_y"] = bly + buttons[button_name]["height"] + 2
	end --# if buttons[button_name]["bl_y"] == nil then
	--###### calculate if click was inside box and set actions #######
	if buttons["rad/sat_toggle"]["state"] == 0 then
		if (localx >= buttons[button_name]["bl_x"]) and (localx <= (buttons[button_name]["bl_x"] + buttons[button_name]["width"])) and (localy <= buttons[button_name]["bl_y"]) and (localy >= (buttons[button_name]["bl_y"] - buttons[button_name]["height"])) then
			if buttons[button_name]["state"] ~= 1 then
				buttons[button_name]["state"] = 1
				buttons[button_name]["height"] = 54
				buttons[button_name]["bl_y"] = bly + buttons[button_name]["height"] + 2
			elseif buttons[button_name]["state"] == 1 then
				buttons[button_name]["state"] = 0
				buttons[button_name]["height"] = 63
				buttons[button_name]["bl_y"] = bly + buttons[button_name]["height"] + 2
			end --# if buttons[button_name]["state"] ~= 1 then
		elseif buttons[button_name]["state"] == nil then
			buttons[button_name]["state"] = 0
			buttons[button_name]["height"] = 63
			buttons[button_name]["bl_y"] = bly + buttons[button_name]["height"] + 2
		end --# if (localx >= buttons[button_name]["bl_x"]) and (localx <= (buttons[button_name]["bl_x"] + buttons[button_name]["width"])) and (localy <= buttons[button_name]["bl_y"]) and (localy >= (buttons[button_name]["bl_y"] - buttons[button_name]["height"])) then
		--###### use the output of the button to set other conditions #########
		if buttons[button_name]["state"] == 1 then
			color = {color1_R,color1_G,color1_B,color1_A}--if button is clicked on it will be drawn red
			fill = 0
			--#################################################################
			cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
			cairo_set_font_size (cr, bfSize)
			local text_offset = 5
			cr = draw_shaded_text(cr, "D", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 11), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "A", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 21), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "I", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 31), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "L", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 41), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "Y", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 51), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = hourly_Weather(cr, extents, wuAPI_Parsed, weatherData, blx, bly, localx, localy, localnowx, localnowy)
		else --# default setting
			color = {color0_R,color0_G,color0_B,color0_A}
			fill = 0
			--#################################################################
			cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
			cairo_set_font_size (cr, bfSize)
			local text_offset = 5
			cr = draw_shaded_text(cr, "H", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 11), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "O", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 21), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "U", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 31), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "R", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 41), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "L", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 51), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "Y", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 61), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			--cr = fiveDay_Weather(cr, extents, wuAPI_Parsed, weatherData, blx, bly, localx, localy, localnowx, localnowy)
		end --# if buttons[button_name]["state"] == 1 then
		--####### draw the button ####################
		cr = buttondraw(cr, buttons[button_name]["bl_x"], buttons[button_name]["bl_y"], buttons[button_name]["height"], buttons[button_name]["width"], color, fill, 1)
	end --# if buttons["rad/sat_toggle"]["state"] == 0 then
	--#################################################################
	button_name = "rad/sat_toggle"
	if buttons[button_name]["bl_y"] == nil then
		buttons[button_name]["bl_y"] = buttons["daily_hourly"]["bl_y"] + buttons["daily_toggle1"]["height"] + buttons[button_name]["height"] + 4
	end --# if buttons[button_name]["bl_y"] == nil then
	--###### calculate if click was inside box and set actions #######
	if buttons["daily_hourly"]["state"] == 0 then --# only show with fiveDayWeather Output
		if (localx >= buttons[button_name]["bl_x"]) and (localx <= (buttons[button_name]["bl_x"] + buttons[button_name]["width"])) and (localy <= buttons[button_name]["bl_y"]) and (localy >= (buttons[button_name]["bl_y"] - buttons[button_name]["height"])) then
			if buttons[button_name]["state"] == 0 then
				buttons[button_name]["state"] = 1
				buttons[button_name]["width"] = 20
				buttons[button_name]["height"] = 54
				buttons[button_name]["bl_x"] = (conky_window.width - buttons[button_name]["width"] - 60)
				buttons[button_name]["bl_y"] = (((conky_window.height - buttons[button_name]["height"] - 2)/2) + buttons[button_name]["height"])
			elseif buttons[button_name]["state"] == 1 then
				buttons[button_name]["state"] = 0
				buttons[button_name]["width"] = 20
				buttons[button_name]["height"] = 74
				buttons[button_name]["bl_x"] = 902
				buttons[button_name]["bl_y"] = buttons["daily_hourly"]["bl_y"] + buttons["daily_toggle1"]["height"] + buttons[button_name]["height"] + 4
				--### prevent triggering another button that runs after this one is clicked when in "state" is 1 (buttons are in the same place but in a different view)
				localx = -1
				localy = -1
			end --# if buttons[button_name]["state"] == 0 then
		elseif buttons[button_name]["state"] == nil then
			buttons[button_name]["state"] = 0
			buttons[button_name]["width"] = 20
			buttons[button_name]["height"] = 74
			buttons[button_name]["bl_x"] = 902
			buttons[button_name]["bl_y"] = buttons["daily_hourly"]["bl_y"] + buttons["daily_toggle1"]["height"] + buttons[button_name]["height"] + 4
		end --# if (localx >= buttons[button_name]["bl_x"]) and (localx <= (buttons[button_name]["bl_x"] + buttons[button_name]["width"])) and (localy <= buttons[button_name]["bl_y"]) and (localy >= (buttons[button_name]["bl_y"] - buttons[button_name]["height"])) then
		--###### use the output of the button to set other conditions #########
		if buttons[button_name]["state"] == 1 then
			color = {color1_R,color1_G,color1_B,color1_A}--if button is clicked on it will be drawn red
			fill = 0
			--#################################################################
			cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
			cairo_set_font_size (cr, bfSize)
			local text_offset = 5
			cr = draw_shaded_text(cr, "D", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 11), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "A", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 21), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "I", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 31), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "L", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 41), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "Y", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 51), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_set_font_size (cr, fSize)
			cr = drawRad_Sat_Large(cr, 0, -1, 272, localx, localy)
		else --# default setting
			color = {color0_R,color0_G,color0_B,color0_A}
			fill = 0
			--#################################################################
			cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
			cairo_set_font_size (cr, bfSize)
			local text_offset = 5
			cr = draw_shaded_text(cr, "R", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 11), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "A", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 21), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "D", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 31), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "/", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 41), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "S", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 51), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "A", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 61), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cr = draw_shaded_text(cr, "T", (buttons[button_name]["bl_x"] + text_offset),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 71), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_set_font_size (cr, fSize)
			--cr = fiveDay_Weather(cr, extents, wuAPI_Parsed, weatherData, blx, bly, localx, localy, localnowx, localnowy)
		end --# if buttons[button_name]["state"] == 1 then
		--####### draw the button ####################
		cr = buttondraw(cr, buttons[button_name]["bl_x"], buttons[button_name]["bl_y"], buttons[button_name]["height"], buttons[button_name]["width"], color, fill, 1)
	end --# if buttons["daily_hourly"]["state"] == 0 then
	--##########################################################
	if ((buttons["daily_hourly"]["state"] == 0) and (buttons["rad/sat_toggle"]["state"] == 0)) then
		cr = fiveDay_Weather(cr, extents, wuAPI_Parsed, weatherData, blx, bly, localx, localy, localnowx, localnowy)
	end --# if ((buttons["daily_hourly"]["state"] == 0) and (buttons["rad/sat_toggle"]["state"] == 0)) then
	if buttons["rad/sat_toggle"]["state"] == 0 then
		cr,blx,bly = drawRad_Sat_Small(cr, blx, bly, localx, localy)
	end --# if buttons["rad/sat_toggle"]["state"] == 0 then
	if updateCheck < 14 then
		updateCheck = updateCheck + 1
	else
		updateCheck = 0
	end --# if updateCheck < 14 then
	--######################################################
	cairo_destroy(cr)
	cairo_surface_destroy(cs)
	cr = nil
	cs = nil
	local gcollect = collectgarbage ("collect")
end --# function conky_main()

function drawRad_Sat_Small(cr, blx, bly, localx, localy)
	local button_name = "small_Close/Wide"
	if (localx >= buttons[button_name]["bl_x"]) and (localx <= (buttons[button_name]["bl_x"] + buttons[button_name]["width"])) and (localy <= buttons[button_name]["bl_y"]) and (localy >= (buttons[button_name]["bl_y"] - buttons[button_name]["height"])) then
		if buttons[button_name]["state"] == 0 then
			buttons[button_name]["state"] = 1
		elseif buttons[button_name]["state"] == 1 then
			buttons[button_name]["state"] = 0
		end --# if buttons[button_name]["state"] == 0 then
	elseif buttons[button_name]["state"] == nil then
		buttons[button_name]["state"] = 0
	end --# if (localx >= buttons[button_name]["bl_x"]) and (localx <= (buttons[button_name]["bl_x"] + buttons[button_name]["width"])) and (localy <= buttons[button_name]["bl_y"]) and (localy >= (buttons[button_name]["bl_y"] - buttons[button_name]["height"])) then
	--####
	local radarImage_Path = nil
	local satteliteImage_Path = nil
	if buttons[button_name]["state"] == 0 then
		radarImage_Path = logDirectory.."/Images/radarImage_temp.gif."..string.format("%03i",updateCheck)
		satteliteImage_Path = logDirectory.."/Images/satelliteImage_temp.gif."..string.format("%03i",updateCheck)
	else
		radarImage_Path = logDirectory.."/Images/radarImage_Wide_temp.gif."..string.format("%03i",updateCheck)
		satteliteImage_Path = logDirectory.."/Images/satelliteImage_Wide_temp.gif."..string.format("%03i",updateCheck)
	end --# if buttons[button_name]["state"] == 0 then
	image({x=(923),y=(1),w=136,h=136,file=radarImage_Path})
	image({x=(923),y=(137),w=136,h=136,file=satteliteImage_Path})
	--cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL)
	--cairo_set_font_size (cr, fSize)
	cr = draw_shaded_text(cr, (updateCheck + 1), 925, 12, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cr = draw_shaded_text(cr, (updateCheck + 1), 925, 149, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	return cr,blx,bly
end --# function drawRad_Sat_Small(cr, blx, bly)

function drawRad_Sat_Large(cr, blx, bly, imSize, localx, localy)
	local button_name = "large_Close/Wide"
	if buttons[button_name]["bl_x"] == nil then
		buttons[button_name]["bl_x"] = blx
		buttons[button_name]["bl_y"] = (bly + 1) + imSize
		buttons[button_name]["width"] = (blx + (imSize * 2) + 3) - blx
		buttons[button_name]["height"] = imSize
	end --# if buttons[button_name]["bl_x"] = nil then
	if (localx >= buttons[button_name]["bl_x"]) and (localx <= (buttons[button_name]["bl_x"] + buttons[button_name]["width"])) and (localy <= buttons[button_name]["bl_y"]) and (localy >= (buttons[button_name]["bl_y"] - buttons[button_name]["height"])) then
		if buttons[button_name]["state"] == 0 then
			buttons[button_name]["state"] = 1
		elseif buttons[button_name]["state"] == 1 then
			buttons[button_name]["state"] = 0
		end --# if buttons[button_name]["state"] == 0 then
	elseif buttons[button_name]["state"] == nil then
		buttons[button_name]["state"] = 0
	end --# if (localx >= buttons[button_name]["bl_x"]) and (localx <= (buttons[button_name]["bl_x"] + buttons[button_name]["width"])) and (localy <= buttons[button_name]["bl_y"]) and (localy >= (buttons[button_name]["bl_y"] - buttons[button_name]["height"])) then
	--####
	local radarImage_Path = nil
	local satteliteImage_Path = nil
	if buttons[button_name]["state"] == 0 then
		radarImage_Path = logDirectory.."/Images/radarImage_temp.gif."..string.format("%03i",updateCheck)
		satteliteImage_Path = logDirectory.."/Images/satelliteImage_temp.gif."..string.format("%03i",updateCheck)
	else
		radarImage_Path = logDirectory.."/Images/radarImage_Wide_temp.gif."..string.format("%03i",updateCheck)
		satteliteImage_Path = logDirectory.."/Images/satelliteImage_Wide_temp.gif."..string.format("%03i",updateCheck)
	end --# if buttons[button_name]["state"] == 0 then
	image({x=(blx),y=(bly + 1),w=imSize,h=imSize,file=radarImage_Path})
	cr = draw_horizontal_divider(cr, (blx + imSize + 1), (bly - 1), (blx + imSize + 1), (bly + imSize + 1), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	image({x=(blx + imSize + 2),y=(bly + 1),w=imSize,h=imSize,file=satteliteImage_Path})
	if use_NOAA == true then
		cr = draw_horizontal_divider(cr, (blx + (imSize * 2) + 3), (bly - 1), (blx + (imSize * 2) + 3), (bly + imSize + 1), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		image_cropped({x=(blx + (imSize * 2) + 4),y=(bly + 1),w=(imSize * (591/381)),h=imSize,file=(logDirectory.."/Images/riverLevelImage.png")},{2,59,591,381})
	end --# if use_NOAA == true then
	--cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL)
	--cairo_set_font_size (cr, fSize)
	cr = draw_shaded_text(cr, (updateCheck + 1), (blx + 1), (bly + 12), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cr = draw_shaded_text(cr, (updateCheck + 1), (blx + imSize + 3), (bly + 12), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	return cr
end --# function drawRad_Sat_Large(cr, blx, bly, imSize)

function line2_UpdateMonitor(cr, blx, bly, extents, weatherArea_Width, currentTime, nextUpdateSeconds)
	--######### Line 2 ################################################
	blx = 0
	bly = bly + 14
	cr = draw_shaded_text(cr, weatherData.obsDate, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, weatherData.obsDate, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, '|', blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, '|', extents)
	blx = blx + extents.x_advance - 1
	cr = draw_shaded_text(cr, weatherData.obsTime, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, weatherData.obsTime, extents)
	local blx_left = blx + extents.x_advance
	--#################################################################
	local countDown_Time = nil
	local countDown_Color = nil
	local countDown_shadeColor = nil
	if nextUpdateSeconds < currentTime then --# update should have occured
		local secondsLeft = currentTime - nextUpdateSeconds --# calculate seconds until the event
		--#hoursLeft = secondsLeft / 3600 # get hours left
		local minutesLeft = (secondsLeft % 3600) / 60 --# get minutes left
		local secLeft = ((secondsLeft % 3600) % 60)
		if (nextUpdateSeconds + 60) > currentTime then
			countDown_Color = {0,0.6,0,1}
			countDown_shadeColor = {0,0,0,1}
		elseif (nextUpdateSeconds + 300) > currentTime then
			countDown_Color = {0.93333,0.93333,0,1}
			countDown_shadeColor = {color3_R,color3_G,color3_B,color3_A}
		else
			countDown_Color = {1,0,0,1}
			countDown_shadeColor = {0.3,0.3,0.3,1}
		end --# if (nextUpdateSeconds + 60) > currentTime then
		countDown_Time = "-"..string.format("%02i:%02i",minutesLeft,secLeft)
	else --# not time to update yet
		local secondsLeft = nextUpdateSeconds - currentTime --# calculate seconds until the event
		--#hoursLeft = secondsLeft / 3600 # get hours left
		local minutesLeft = (secondsLeft % 3600) / 60 --# get minutes left
		local secLeft = ((secondsLeft % 3600) % 60)
		countDown_Color = {color0_R,color0_G,color0_B,color0_A}
		countDown_shadeColor = {color3_R,color3_G,color3_B,color3_A}
		countDown_Time = string.format("%02i:%02i",minutesLeft,secLeft)
	end --# if nextUpdateSeconds < currentTime then
	cairo_text_extents(cr, countDown_Time, extents)
	local countDown_x_advance = extents.x_advance
	cairo_text_extents(cr, '|', extents)
	local divider_x_advance = extents.x_advance - 1
	cairo_text_extents(cr, weatherData.lastUpdate, extents)
	local lastUpdate_x_advance = extents.x_advance
	blx = weatherArea_Width - countDown_x_advance - divider_x_advance - lastUpdate_x_advance - 1
	local blx_right = blx
	cr = draw_shaded_text(cr, countDown_Time, blx, bly, countDown_Color, countDown_shadeColor)
	blx = blx + countDown_x_advance + 1
	cr = draw_shaded_text(cr, '|', blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + divider_x_advance
	cr = draw_shaded_text(cr, weatherData.lastUpdate, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	local currentTime = os.date('%I:%M:%S %p')
	cairo_text_extents(cr, currentTime, extents)
	local currentTime_x_advance = extents.x_advance
	blx = blx_left + (((blx_right - blx_left) - currentTime_x_advance)/2)
	cr = draw_shaded_text(cr, currentTime, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	local blxTime_Start = blx
	local blxTime_End = blx + currentTime_x_advance
	--#################################################################
	if weatherData.stateData[2][1][1] == 1 then
		cairo_text_extents(cr, "/", extents)
	    local slash_x_advance = extents.x_advance
		local W_x_advance = nil
		local I_x_advance = nil
		local R_x_advance = nil
		local S_x_advance = nil
		local N_x_advance = nil
		local backupString_x_advance = 0
		local numBackup = 0
		for i = 1, 5 do
			if weatherData.stateData[2][1][2][i] == 1 then
				if i == 1 then
					cairo_text_extents(cr, "W", extents)
					W_x_advance = extents.x_advance
					backupString_x_advance = backupString_x_advance + W_x_advance
				elseif i == 2 then
					cairo_text_extents(cr, "I", extents)
					I_x_advance = extents.x_advance
					backupString_x_advance = backupString_x_advance + I_x_advance
				elseif i == 3 then
					cairo_text_extents(cr, "R", extents)
					R_x_advance = extents.x_advance
					backupString_x_advance = backupString_x_advance + R_x_advance
				elseif i == 4 then
					cairo_text_extents(cr, "S", extents)
					S_x_advance = extents.x_advance
					backupString_x_advance = backupString_x_advance + S_x_advance
				elseif i == 5 then
					cairo_text_extents(cr, "N", extents)
					N_x_advance = extents.x_advance
					backupString_x_advance = backupString_x_advance + N_x_advance
				end --# if i == 1 then
				backupString_x_advance = backupString_x_advance + slash_x_advance
				numBackup = numBackup + 1
			end --# if weatherData.stateData[2][1][2][i] == 1 then
			--print(backupString_x_advance)
		end --# for i = 1, 5 do
		--print(backupString_x_advance)
		cairo_text_extents(cr, "Backup Used ", extents)
		local backup_x_advance = extents.x_advance
		--print(backup_x_advance)
		backupString_x_advance = backupString_x_advance + backup_x_advance - slash_x_advance
		--print(backupString_x_advance)
		blx = blxTime_End + (((blx_right - blxTime_End) - backupString_x_advance)/2)
		cr = draw_shaded_text(cr, "Backup Used", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		blx = blx + backup_x_advance
		local numBackup2 = 0
		for i = 1, 5 do
			if weatherData.stateData[2][1][2][i] == 1 then
				if i == 1 then
					cr = draw_shaded_text(cr, "W", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
					blx = blx + W_x_advance
				elseif i == 2 then
					cr = draw_shaded_text(cr, "I", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
					blx = blx + I_x_advance
				elseif i == 3 then
					cr = draw_shaded_text(cr, "R", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
					blx = blx + R_x_advance
				elseif i == 4 then
					cr = draw_shaded_text(cr, "S", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
					blx = blx + S_x_advance
				elseif i == 5 then
					cr = draw_shaded_text(cr, "N", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
					blx = blx + N_x_advance
				end --# if i == 1 then
				numBackup2 = numBackup2 + 1
				if numBackup2 ~= numBackup then
					cr = draw_shaded_text(cr, "/", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
					blx = blx + slash_x_advance
				end --# if numBackup2 ~= numBackup then
			end --# if weatherData.stateData[2][1][2][i] == 1 then
		end --# for i = 1, 5 do
	end --# if weatherData.stateData[2][1][1] == 1 then
	--#################################################################
	if weatherData.stateData[2][2][1] == 1 then
		cairo_text_extents(cr, "/", extents)
	    local slash_x_advance = extents.x_advance
		local W_x_advance = nil
		local I_x_advance = nil
		local R_x_advance = nil
		local S_x_advance = nil
		local N_x_advance = nil
		local backupString_x_advance = 0
		local numBackup = 0
		--print(backupString_x_advance)
		for i = 1, 5 do
			--print(i)
			--print(weatherData.stateData[2][2][2][i])
			if weatherData.stateData[2][2][2][i] == 1 then
				if i == 1 then
					cairo_text_extents(cr, "W", extents)
					W_x_advance = extents.x_advance
					backupString_x_advance = backupString_x_advance + W_x_advance
				elseif i == 2 then
					cairo_text_extents(cr, "I", extents)
					I_x_advance = extents.x_advance
					backupString_x_advance = backupString_x_advance + I_x_advance
				elseif i == 3 then
					cairo_text_extents(cr, "R", extents)
					R_x_advance = extents.x_advance
					backupString_x_advance = backupString_x_advance + R_x_advance
				elseif i == 4 then
					cairo_text_extents(cr, "S", extents)
					S_x_advance = extents.x_advance
					backupString_x_advance = backupString_x_advance + S_x_advance
				elseif i == 5 then
					cairo_text_extents(cr, "N", extents)
					N_x_advance = extents.x_advance
					backupString_x_advance = backupString_x_advance + N_x_advance
				end --# if i == 1 then
				--print(i)
				--print(backupString_x_advance)
				backupString_x_advance = backupString_x_advance + slash_x_advance
				--print(backupString_x_advance)
				numBackup = numBackup + 1
			end --# if weatherData.stateData[2][2][2][i] == 1 then
			--print(backupString_x_advance)
		end --# for i = 1, 5 do
		--print(backupString_x_advance)
		cairo_text_extents(cr, "Conn Failure ", extents)
		local backup_x_advance = extents.x_advance
		--print(backup_x_advance)
		backupString_x_advance = backupString_x_advance + backup_x_advance - slash_x_advance
		--print(backupString_x_advance)
		blx = blx_left + (((blxTime_Start - blx_left) - backupString_x_advance)/2)
		cr = draw_shaded_text(cr, "Conn Failure", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		blx = blx + backup_x_advance
		local numBackup2 = 0
		for i = 1, 5 do
			if weatherData.stateData[2][2][2][i] == 1 then
				if i == 1 then
					cr = draw_shaded_text(cr, "W", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
					blx = blx + W_x_advance
				elseif i == 2 then
					cr = draw_shaded_text(cr, "I", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
					blx = blx + I_x_advance
				elseif i == 3 then
					cr = draw_shaded_text(cr, "R", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
					blx = blx + R_x_advance
				elseif i == 4 then
					cr = draw_shaded_text(cr, "S", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
					blx = blx + S_x_advance
				elseif i == 5 then
					cr = draw_shaded_text(cr, "N", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
					blx = blx + N_x_advance
				end --# if i == 1 then
				numBackup2 = numBackup2 + 1
				if numBackup2 ~= numBackup then
					cr = draw_shaded_text(cr, "/", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
					blx = blx + slash_x_advance
				end --# if numBackup2 ~= numBackup then
			end --# if weatherData.stateData[2][2][2][i] == 1 then
		end --# for i = 1, 5 do
	end --# if weatherData.stateData[2][2][1] == 1 then
	--######### End Line 2 ############################################
	bly = bly + 5
	cr = draw_horizontal_divider(cr,1, bly, (weatherArea_Width + 23), bly, 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	return cr,blx,bly
end --# function line2_UpdateMonitor(cr, blx, bly, extents, weatherArea_Width, currentTime, nextUpdateSeconds)

--######################################################################
--##### Start Hourly Weather Functions
function hourly_Weather(cr, extents, wuAPI_Parsed, weatherData, blx, bly, localx, localy, localnowx, localnowy)
	cairo_set_font_size (cr, fSize)
	local weatherArea_Height = 272
	local bly1 = bly --# remember divider height
	cr = draw_horizontal_divider(cr, 1, (bly1 - 1), 1, (bly1 + weatherArea_Height), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = 1
	--#################################################################
	local color = nil
	local fill = 0
	local button_name = "hourly_toggle1"
	if buttons[button_name]["bl_y"] == nil then
		buttons[button_name]["bl_y"] = buttons["daily_hourly"]["bl_y"] + buttons[button_name]["height"] + 2
	end --# if buttons[button_name]["bl_y"] == nil then
	--###### calculate if click was inside box and set actions #######
	if (localx >= buttons[button_name]["bl_x"]) and (localx <= (buttons[button_name]["bl_x"] + buttons[button_name]["width"])) and (localy <= buttons[button_name]["bl_y"]) and (localy >= (buttons[button_name]["bl_y"] - buttons[button_name]["height"])) then
		if buttons[button_name]["state"] == 0 then
			buttons[button_name]["state"] = 1
		elseif buttons[button_name]["state"] == 1 then
			buttons[button_name]["state"] = 2
		elseif buttons[button_name]["state"] == 2 then
			buttons[button_name]["state"] = 3
		elseif buttons[button_name]["state"] == 3 then
			buttons[button_name]["state"] = 4
		elseif buttons[button_name]["state"] == 4 then
			buttons[button_name]["state"] = 0
		end --# if buttons[button_name]["state"] == 0 then
	elseif buttons[button_name]["state"] == nil then
		buttons[button_name]["state"] = 0
	end --# if (localx >= buttons[button_name]["bl_x"]) and (localx <= (buttons[button_name]["bl_x"] + buttons[button_name]["width"])) and (localy <= buttons[button_name]["bl_y"]) and (localy >= (buttons[button_name]["bl_y"] - buttons[button_name]["height"])) then
	--###### use the output of the button to set other conditions #########
	if buttons[button_name]["state"] == 4 then
		color = {color1_R,color1_G,color1_B,color1_A}--if button is clicked on it will be drawn red
		--#################################################################
		cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
		cairo_set_font_size (cr, bfSize)
		cr = draw_shaded_text(cr, "36", (buttons[button_name]["bl_x"] + 2),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 12), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "^", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 25), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "33", (buttons[button_name]["bl_x"] + 2),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 32), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_set_font_size (cr, fSize)
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 33, 35)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 34, 36)
		cr = draw_horizontal_divider(cr, (blx), (bly), (900), (bly), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	elseif buttons[button_name]["state"] == 3 then
		color = {color1_R,color1_G,color1_B,color1_A}--if button is clicked on it will be drawn red
		--#################################################################
		cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
		cairo_set_font_size (cr, bfSize)
		cr = draw_shaded_text(cr, "32", (buttons[button_name]["bl_x"] + 2),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 12), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "^", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 25), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "25", (buttons[button_name]["bl_x"] + 2),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 32), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_set_font_size (cr, fSize)
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 25, 29)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 26, 30)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 27, 31)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 28, 32)
	elseif buttons[button_name]["state"] == 2 then
		color = {color1_R,color1_G,color1_B,color1_A}--if button is clicked on it will be drawn red
		--#################################################################
		cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
		cairo_set_font_size (cr, bfSize)
		cr = draw_shaded_text(cr, "24", (buttons[button_name]["bl_x"] + 2),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 12), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "^", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 25), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "17", (buttons[button_name]["bl_x"] + 2),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 32), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_set_font_size (cr, fSize)
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 17, 21)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 18, 22)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 19, 23)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 20, 24)
	elseif buttons[button_name]["state"] == 1 then
		color = {color1_R,color1_G,color1_B,color1_A}--if button is clicked on it will be drawn red
		--#################################################################
		cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
		cairo_set_font_size (cr, bfSize)
		cr = draw_shaded_text(cr, "16", (buttons[button_name]["bl_x"] + 2),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 12), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "^", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 25), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "9", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 32), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_set_font_size (cr, fSize)
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 9, 13)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 10, 14)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 11, 15)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 12, 16)
	else --# default setting
		color = {color0_R,color0_G,color0_B,color0_A}
		--#################################################################
		cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
		cairo_set_font_size (cr, bfSize)
		cr = draw_shaded_text(cr, "8", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 12), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "^", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 25), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "1", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 32), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_set_font_size (cr, fSize)
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 1, 5)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 2, 6)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 3, 7)
		bly = bly1
		cr,blx,bly = hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 4, 8)
	end --# if buttons[button_name]["state"] == 4 then
	--####### draw the button ####################
	cr = draw_horizontal_divider(cr, (900), (bly1 - 1), (900), (bly1 + weatherArea_Height), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cr = buttondraw(cr, buttons[button_name]["bl_x"], buttons[button_name]["bl_y"], buttons[button_name]["height"], buttons[button_name]["width"], color, fill, 1)
	--#################################################################
	cr,blx,bly = hourlyStats_Today(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height)
	--#################################################################
	return cr
end --# function hourly_Weather(cr, extents, wuAPI_Parsed, weatherData, blx, bly, localx, localy, localnowx, localnowy)

function hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, i, j)
	local blx1 = blx
	--cr = draw_horizontal_divider(cr, 1, (bly1 - 1), 1, (bly1 + weatherArea_Height), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	--######## Column1 ######################################################
	local columnWidth = 224.75
	bly = bly1 + 16
	blx = blx1
	cairo_text_extents(cr, "|", extents)
	local vBar_x_advance = extents.x_advance - 1
	--#################################################################
	local isNight = nil
	if string.find(wuAPI_Parsed["hourly_forecast"][i]["icon_url"], "nt_") ~= nil then --# use wunderground icon path to detrmine if day or night icon should be used
		isNight = true
	else
		isNight = false
	end --# string.find(wuAPI_Parsed["hourly_forecast"][i]["icon_url"], "nt_") ~= nil then
	local hour1_Conditions = wuAPI_Parsed["hourly_forecast"][i]["condition"]
	local hour1_imPath = weatherImageLocation..selectForecastIcon(hour1_Conditions,isNight)..".png"
	image({x=(blx1),y=(bly1 - 3),w=57,h=39,file=hour1_imPath})
	--##### 00:00 AM - Weekday
	local hour1_Epoch = tonumber(wuAPI_Parsed["hourly_forecast"][i]["FCTTIME"]["epoch"])
	local hour1_Hour = os.date("%I:", hour1_Epoch) --'%I:%M:%S %p'
	local hour1_Minute = os.date("%M", hour1_Epoch)
	local hour1_AMorPM = os.date("%p", hour1_Epoch)
	local hour1_Day = os.date("%A", hour1_Epoch)
	cairo_text_extents(cr, hour1_Hour, extents)
	local hour_x_advance = extents.x_advance - 1
	cairo_text_extents(cr, hour1_Minute, extents)
	local minute_x_advance = extents.x_advance + 4
	cairo_text_extents(cr, hour1_AMorPM, extents)
	local AMorPM_x_advance = extents.x_advance + 3
	cairo_text_extents(cr, hour1_Day, extents)
	local weekday_x_advance = extents.x_advance
	cairo_text_extents(cr, "-", extents)
	local dash_x_advance = extents.x_advance + 1
	local timeString_x_advance = hour_x_advance + minute_x_advance + AMorPM_x_advance + weekday_x_advance + dash_x_advance
	blx = blx1 + (columnWidth - timeString_x_advance)/2
	cr = draw_shaded_text(cr, hour1_Hour, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + hour_x_advance
	cr = draw_shaded_text(cr, hour1_Minute, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + minute_x_advance
	cr = draw_shaded_text(cr, hour1_AMorPM, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + AMorPM_x_advance
	cr = draw_shaded_text(cr, "-", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + dash_x_advance
	cr = draw_shaded_text(cr, hour1_Day, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	cairo_text_extents(cr, hour1_Conditions, extents)
	blx = blx1 + (columnWidth - extents.x_advance)/2
	bly = bly + 14
	cr = draw_shaded_text(cr, hour1_Conditions, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	local hour1TempF,hour1TempC,hour1TempK = convertTemp(wuAPI_Parsed["hourly_forecast"][i]["temp"]["english"])
	bly = bly + 16
	blx = blx1 + 5
	cr = draw_shaded_text(cr, "Temp:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Temp:", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, hour1TempF, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, hour1TempF, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	--[[
	cr = draw_shaded_text(cr, hour1TempC, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, hour1TempC, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	]]
	cr = draw_shaded_text(cr, hour1TempK, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	local hour1_Humidity = wuAPI_Parsed["hourly_forecast"][i]["humidity"]
	bly = bly + 14
	blx = blx1 + 5
	cr = draw_shaded_text(cr, "Humidity:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Humidity:", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, hour1_Humidity.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	local hour1_Precip = wuAPI_Parsed["hourly_forecast"][i]["pop"]
	bly = bly + 14
	blx = blx1 + 5
	cr = draw_shaded_text(cr, "Precip Chance:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Precip Chance:", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, hour1_Precip.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	local hour1_WindSpeed = wuAPI_Parsed["hourly_forecast"][i]["wspd"]["english"]
	local hour1_WindDir = wuAPI_Parsed["hourly_forecast"][i]["wdir"]
	bly = bly + 14
	blx = blx1 + 5
	cr = draw_shaded_text(cr, "Wind:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Wind:", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, hour1_WindDir["dir"], blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, hour1_WindDir["dir"], extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, "(", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "(", extents)
	blx = blx + extents.x_advance - 1
	cr = draw_shaded_text(cr, hour1_WindDir["degrees"], blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, hour1_WindDir["degrees"], extents)
	blx = blx + extents.x_advance
	cr = draw_shaded_text(cr, ")", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, ")", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, "at", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "at", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, hour1_WindSpeed, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, hour1_WindSpeed, extents)
	blx = blx + extents.x_advance + 4
	cr = draw_shaded_text(cr, "mph", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#######################################################################
	bly = bly + 6
	cr = draw_horizontal_divider(cr, (blx1), bly, (blx1 + (columnWidth - 1) + 0.5), bly, 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	--#######################################################################
	blx = blx1
	if string.find(wuAPI_Parsed["hourly_forecast"][j]["icon_url"], "nt_") ~= nil then --# use wunderground icon path to detrmine if day or night icon should be used
		isNight = true
	else
		isNight = false
	end --# string.find(wuAPI_Parsed["hourly_forecast"][j]["icon_url"], "nt_") ~= nil then
	hour1_Conditions = wuAPI_Parsed["hourly_forecast"][j]["condition"]
	hour1_imPath = weatherImageLocation..selectForecastIcon(hour1_Conditions,isNight)..".png"
	image({x=(blx1),y=(bly - 1),w=57,h=39,file=hour1_imPath})
	bly = bly + 16
	--##### 00:00 AM - Weekday
	hour1_Epoch = tonumber(wuAPI_Parsed["hourly_forecast"][j]["FCTTIME"]["epoch"])
	hour1_Hour = os.date("%I:", hour1_Epoch) --'%I:%M:%S %p'
	hour1_Minute = os.date("%M", hour1_Epoch)
	hour1_AMorPM = os.date("%p", hour1_Epoch)
	hour1_Day = os.date("%A", hour1_Epoch)
	cairo_text_extents(cr, hour1_Hour, extents)
	hour_x_advance = extents.x_advance - 1
	cairo_text_extents(cr, hour1_Minute, extents)
	minute_x_advance = extents.x_advance + 4
	cairo_text_extents(cr, hour1_AMorPM, extents)
	AMorPM_x_advance = extents.x_advance + 3
	cairo_text_extents(cr, hour1_Day, extents)
	weekday_x_advance = extents.x_advance
	cairo_text_extents(cr, "-", extents)
	dash_x_advance = extents.x_advance + 1
	timeString_x_advance = hour_x_advance + minute_x_advance + AMorPM_x_advance + weekday_x_advance + dash_x_advance
	blx = blx1 + (columnWidth - timeString_x_advance)/2
	cr = draw_shaded_text(cr, hour1_Hour, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + hour_x_advance
	cr = draw_shaded_text(cr, hour1_Minute, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + minute_x_advance
	cr = draw_shaded_text(cr, hour1_AMorPM, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + AMorPM_x_advance
	cr = draw_shaded_text(cr, "-", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + dash_x_advance
	cr = draw_shaded_text(cr, hour1_Day, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	cairo_text_extents(cr, hour1_Conditions, extents)
	blx = blx1 + (columnWidth - extents.x_advance)/2
	bly = bly + 14
	cr = draw_shaded_text(cr, hour1_Conditions, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	hour1TempF,hour1TempC,hour1TempK = convertTemp(wuAPI_Parsed["hourly_forecast"][j]["temp"]["english"])
	bly = bly + 16
	blx = blx1 + 5
	cr = draw_shaded_text(cr, "Temp:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Temp:", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, hour1TempF, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, hour1TempF, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	--[[
	cr = draw_shaded_text(cr, hour1TempC, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, hour1TempC, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	]]
	cr = draw_shaded_text(cr, hour1TempK, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	hour1_Humidity = wuAPI_Parsed["hourly_forecast"][j]["humidity"]
	bly = bly + 14
	blx = blx1 + 5
	cr = draw_shaded_text(cr, "Humidity:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Humidity:", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, hour1_Humidity.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	hour1_Precip = wuAPI_Parsed["hourly_forecast"][j]["pop"]
	bly = bly + 14
	blx = blx1 + 5
	cr = draw_shaded_text(cr, "Precip Chance:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Precip Chance:", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, hour1_Precip.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	hour1_WindSpeed = wuAPI_Parsed["hourly_forecast"][j]["wspd"]["english"]
	hour1_WindDir = wuAPI_Parsed["hourly_forecast"][j]["wdir"]
	bly = bly + 14
	blx = blx1 + 5
	cr = draw_shaded_text(cr, "Wind:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Wind:", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, hour1_WindDir["dir"], blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, hour1_WindDir["dir"], extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, "(", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "(", extents)
	blx = blx + extents.x_advance - 1
	cr = draw_shaded_text(cr, hour1_WindDir["degrees"], blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, hour1_WindDir["degrees"], extents)
	blx = blx + extents.x_advance
	cr = draw_shaded_text(cr, ")", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, ")", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, "at", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "at", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, hour1_WindSpeed, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, hour1_WindSpeed, extents)
	blx = blx + extents.x_advance + 4
	cr = draw_shaded_text(cr, "mph", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#######################################################################
	bly = bly + 6
	cr = draw_horizontal_divider(cr, blx1, bly, (blx1 + (columnWidth - 1) + 0.5), bly, 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	--#######################################################################
	cr = draw_horizontal_divider(cr, (blx1 + columnWidth), (bly1 - 1), (blx1 + columnWidth), (bly), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	--####### End Column1 ###################################################
	blx = blx1 + columnWidth
	return cr,blx,bly
end --# function hourly_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, i, j)

function hourlyStats_Today(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height)
	bly1 = bly
	local columnWidth = (224.75 * 4)
	bly = bly + 13
	blx = 6
	cairo_text_extents(cr, "|", extents)
	local vBar_x_advance = extents.x_advance - 1
	--#################################################################
	local minTemp,minTemp_f = xpcall(getMinTemp, debug.traceback)
	--print(minTemp_f)
	local minTemp_c = string.format("% 5s","N/A").."°C"
	local minTemp_k = string.format("% 6s","N/A").." K"
	if minTemp == false then
		minTemp_f = string.format("% 5s","N/A").."°F"
	elseif ((minTemp_f == nil) or (minTemp_f == "")) then
		minTemp_f = string.format("% 5s","N/A").."°F"
	else
		minTemp_f,minTemp_c,minTemp_k = convertTemp(minTemp_f)
	end --# if minTemp == false then
	cr = draw_shaded_text(cr, "MinTemp:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "MinTemp:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, minTemp_f, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, minTemp_f, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, minTemp_k, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	bly = bly + 13
	blx = 6
	local avgTemp_c = string.format("% 5s","N/A").."°C"
	local avgTemp_k = string.format("% 6s","N/A").." K"
	local avgTemp,avgTemp_f = xpcall(getAvgTemp, debug.traceback)
	if avgTemp == false then
		avgTemp_f = string.format("% 5s","N/A").."°F"
	elseif ((avgTemp_f == nil) or (avgTemp_f == "")) then
		avgTemp_f = string.format("% 5s","N/A").."°F"
	else
		avgTemp_f,avgTemp_c,avgTemp_k = convertTemp(avgTemp_f)
	end --# if avgTemp == false then
	cr = draw_shaded_text(cr, "AvgTemp:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "AvgTemp:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, avgTemp_f, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, avgTemp_f, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, avgTemp_k, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	bly = bly + 13
	blx = 6
	local maxTemp_c = string.format("% 5s","N/A").."°C"
	local maxTemp_k = string.format("% 6s","N/A").." K"
	local maxTemp,maxTemp_f = xpcall(getMaxTemp, debug.traceback)
	--print(maxTemp_f)
	if maxTemp == false then
		maxTemp_f = string.format("% 5s","N/A").."°F"
	elseif ((maxTemp_f == nil) or (maxTemp_f == "")) then
		maxTemp_f = string.format("% 5s","N/A").."°F"
	else
		maxTemp_f,maxTemp_c,maxTemp_k = convertTemp(maxTemp_f)
	end --# if maxTemp == false then
	cr = draw_shaded_text(cr, "MaxTemp:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "MaxTemp:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, maxTemp_f, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, maxTemp_f, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, maxTemp_k, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	local blx1 = 1
	cr = draw_horizontal_divider(cr, (blx1 + (columnWidth/4)), (bly1 - 1), (blx1 + (columnWidth/4)), (bly1 + (weatherArea_Height - bly1)), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	local blx1 = blx1 + (columnWidth/4)
	--#################################################################
	bly = bly1 + 13
	blx = blx1 + 6
	local minWSpeed,minWSpeed_mph = xpcall(getMinWSpeed, debug.traceback)
	if minWSpeed == false then
		minWSpeed_mph = "N/A"
	elseif ((minWSpeed_mph == nil) or (minWSpeed_mph == "")) then
		minWSpeed_mph = "N/A"
	end --# if minWSpeed == false then
	cr = draw_shaded_text(cr, "Min Wind Speed:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Min Wind Speed:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, minWSpeed_mph, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, minWSpeed_mph, extents)
	blx = blx + extents.x_advance + 4
	cr = draw_shaded_text(cr, "mph", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	bly = bly + 13
	blx = blx1 + 6
	local avgWSpeed,avgWSpeed_mph = xpcall(getAvgWSpeed, debug.traceback)
	if avgWSpeed == false then
		avgWSpeed_mph = "N/A"
	elseif ((avgWSpeed_mph == nil) or (avgWSpeed_mph == "")) then
		avgWSpeed_mph = "N/A"
	end --# if avgWSpeed == false then
	cr = draw_shaded_text(cr, "Avg Wind Speed:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Avg Wind Speed:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, avgWSpeed_mph, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, avgWSpeed_mph, extents)
	blx = blx + extents.x_advance + 4
	cr = draw_shaded_text(cr, "mph", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	bly = bly + 13
	blx = blx1 + 6
	local maxWSpeed,maxWSpeed_mph = xpcall(getMaxWSpeed, debug.traceback)
	if maxWSpeed == false then
		maxWSpeed_mph = "N/A"
	elseif ((maxWSpeed_mph == nil) or (maxWSpeed_mph == "")) then
		maxWSpeed_mph = "N/A"
	end --# if maxWSpeed == false then
	cr = draw_shaded_text(cr, "Max Wind Speed:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Max Wind Speed:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, maxWSpeed_mph, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, maxWSpeed_mph, extents)
	blx = blx + extents.x_advance + 4
	cr = draw_shaded_text(cr, "mph", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	local dividerAdvance = 189
	cr = draw_horizontal_divider(cr, (blx1 + dividerAdvance), (bly1 - 1), (blx1 + dividerAdvance), (bly1 + (weatherArea_Height - bly1)), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	local blx1 = blx1 + dividerAdvance
	--#################################################################
	bly = bly1 + 13
	blx = blx1 + 6
	local minHumidity,minHumidity_per = xpcall(getMinHumidity, debug.traceback)
	if minHumidity == false then
		minHumidity_per = "N/A"
	elseif ((minHumidity_per == nil) or (minHumidity_per == "")) then
		minHumidity_per = "N/A"
	end --# if minHumidity == false then
	cr = draw_shaded_text(cr, "Min Humidity:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Min Humidity:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, minHumidity_per.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	bly = bly + 13
	blx = blx1 + 6
	local avgHumidity,avgHumidity_per = xpcall(getAvgHumidity, debug.traceback)
	if avgHumidity == false then
		avgHumidity_per = "N/A"
	elseif ((avgHumidity_per == nil) or (avgHumidity_per == "")) then
		avgHumidity_per = "N/A"
	end --# if avgHumidity == false then
	cr = draw_shaded_text(cr, "Avg Humidity:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Avg Humidity:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, avgHumidity_per.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	bly = bly + 13
	blx = blx1 + 6
	local maxHumidity,maxHumidity_per = xpcall(getMaxHumidity, debug.traceback)
	if maxHumidity == false then
		maxHumidity_per = "N/A"
	elseif ((maxHumidity_per == nil) or (maxHumidity_per == "")) then
		maxHumidity_per = "N/A"
	end --# if maxHumidity == false then
	cr = draw_shaded_text(cr, "Max Humidity:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Max Humidity:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, maxHumidity_per.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	dividerAdvance = 155
	cr = draw_horizontal_divider(cr, (blx1 + dividerAdvance), (bly1 - 1), (blx1 + dividerAdvance), (bly1 + (weatherArea_Height - bly1)), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	local blx1 = blx1 + dividerAdvance
	--#################################################################
	local rainToday,rainToday_in = xpcall(getRainToday, debug.traceback)
	if rainToday == false then
		--print(tostring(rainToday_in))
		rainToday_in = "0.00"
	elseif ((rainToday_in == "-9999.00") or (rainToday_in == "") or (rainToday_in == nil)) then
		rainToday_in = "0.00"
	end --# if rainToday == false then
	bly = bly1 + 13
	blx = blx1 + 6
	cr = draw_shaded_text(cr, "Total Rain:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Total Rain:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, rainToday_in, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, rainToday_in, extents)
	blx = blx + extents.x_advance + 4
	cr = draw_shaded_text(cr, "in", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "in", extents)
	--#################################################################
	bly = bly + 13
	blx = blx1 + 6
	local snowToday,snowToday_in = xpcall(getSnowToday, debug.traceback)
	if snowToday == false then
		snowToday_in = "0.00"
	elseif ((snowToday_in == "-9999.00") or (snowToday_in == "") or (snowToday_in == nil)) then
		snowToday_in = "0.00"
	end --# if snowToday == false then
	cr = draw_shaded_text(cr, "Total Snow:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Total Snow:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, snowToday_in, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, snowToday_in, extents)
	blx = blx + extents.x_advance + 4
	cr = draw_shaded_text(cr, "in", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "in", extents)
	blx = blx + extents.x_advance + 7
	local snowDepth,snowDepth_in = xpcall(getSnowDepth, debug.traceback)
	if snowDepth == false then
		snowDepth_in = "0.00"
	elseif ((snowDepth_in == "-9999.00") or (snowDepth_in == "") or (snowDepth_in == nil)) then
		snowDepth_in = "0.00"
	end --# if snowDepth == false then
	cr = draw_shaded_text(cr, "Snow Depth:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Snow Depth:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, snowDepth_in, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, snowDepth_in, extents)
	blx = blx + extents.x_advance + 4
	cr = draw_shaded_text(cr, "in", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	return cr,blx,bly
end --# function hourlyStats_Today(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height)

--##### Hourly Weather Functions

--##### History Reading Functions #####

function getRainHour() --# handle errors due to non existant history entries at the begining of the day 
	local rainLastHour_in = weatherData.historyToday["observations"][#weatherData.historyToday["observations"]]["precipi"]
	return rainLastHour_in
end --# local function getRainHour()

function getRainToday() --# handle errors due to non existant history entries at the begining of the day
	local rainToday_in = weatherData.historyToday["dailysummary"][1]["precipi"]
	return rainToday_in
end --# local function getRainToday()

function getMaxTemp() --# handle errors due to non existant history entries at the begining of the day
	local maxTemp = weatherData.historyToday["dailysummary"][1]["maxtempi"]
	return maxTemp
end --# local function getMaxTemp()

function getAvgTemp() --# handle errors due to non existant history entries at the begining of the day
	local avgTemp = weatherData.historyToday["dailysummary"][1]["meantempi"]
	return avgTemp
end --# local function getAvgTemp()

function getMinTemp() --# handle errors due to non existant history entries at the begining of the day
	local minTemp = weatherData.historyToday["dailysummary"][1]["mintempi"]
	return minTemp
end --# local function getMinTemp()

function getSnowToday() --# handle errors due to non existant history entries at the begining of the day
	local snowToday = weatherData.historyToday["dailysummary"][1]["snowfalli"]
	return snowToday
end --# local function getSnowToday()

function getSnowDepth() --# handle errors due to non existant history entries at the begining of the day
	local snowDepth = weatherData.historyToday["dailysummary"][1]["snowdepthi"]
	return snowDepth
end --# local function getSnowDepth()

function getMaxWSpeed() --# handle errors due to non existant history entries at the begining of the day
	local maxWSpeed = weatherData.historyToday["dailysummary"][1]["maxwspdi"]
	return maxWSpeed
end --# local function getMaxWSpeed()

function getAvgWSpeed() --# handle errors due to non existant history entries at the begining of the day
	local avgWSpeed = weatherData.historyToday["dailysummary"][1]["meanwindspdi"]
	return avgWSpeed
end --# local function getAvgWSpeed()

function getMinWSpeed() --# handle errors due to non existant history entries at the begining of the day
	local minWSpeed = weatherData.historyToday["dailysummary"][1]["minwspdi"]
	return minWSpeed
end --# local function getMinWSpeed()

function getMaxHumidity() --# handle errors due to non existant history entries at the begining of the day
	local maxHumidity = weatherData.historyToday["dailysummary"][1]["maxhumidity"]
	return maxHumidity
end --# local function getMaxHumidity()

function getAvgHumidity() --# handle errors due to non existant history entries at the begining of the day
	local avgHumidity = weatherData.historyToday["dailysummary"][1]["humidity"]
	return avgHumidity
end --# local function getAvgHumidity()

function getMinHumidity() --# handle errors due to non existant history entries at the begining of the day
	local minHumidity = weatherData.historyToday["dailysummary"][1]["minhumidity"]
	return minHumidity
end --# local function getMinHumidity()

--##### End History Reading Functions #####

--##### fiveDay_Weather Functions #####
function fiveDay_Weather(cr, extents, wuAPI_Parsed, weatherData, blx, bly, localx, localy, localnowx, localnowy)
	cairo_set_font_size (cr, fSize)
	local weatherArea_Height = 272
	local bly1 = bly --# remember divider height
	cr,blx,bly = fiveDay_Column0(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height)
	bly = bly1
	local blx1 = blx
	--#################################################################
	local color = nil
	local fill = nil
	local button_name = "daily_toggle1"
	if buttons[button_name]["bl_y"] == nil then
		buttons[button_name]["bl_y"] = buttons["daily_hourly"]["bl_y"] + buttons[button_name]["height"] + 2
	end --# if buttons[button_name]["bl_y"] == nil then
	--###### calculate if click was inside box and set actions #######
	if (localx >= buttons[button_name]["bl_x"]) and (localx <= (buttons[button_name]["bl_x"] + buttons[button_name]["width"])) and (localy <= buttons[button_name]["bl_y"]) and (localy >= (buttons[button_name]["bl_y"] - buttons[button_name]["height"])) then
		if buttons[button_name]["state"] == 0 then
			buttons[button_name]["state"] = 1
		elseif buttons[button_name]["state"] == 1 then
			buttons[button_name]["state"] = 0
		end --# if buttons[button_name]["state"] == 0 then
	elseif buttons[button_name]["state"] == nil then
		buttons[button_name]["state"] = 0
	end --# if (localx >= buttons[button_name]["bl_x"]) and (localx <= (buttons[button_name]["bl_x"] + buttons[button_name]["width"])) and (localy <= buttons[button_name]["bl_y"]) and (localy >= (buttons[button_name]["bl_y"] - buttons[button_name]["height"])) then
	--###### use the output of the button to set other conditions #########
	local bly2 = nil
	local blx2 = nil
	if buttons[button_name]["state"] == 1 then
		color = {color1_R,color1_G,color1_B,color1_A}--if button is clicked on it will be drawn red
		fill = 0
		------
		cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
		cairo_set_font_size (cr, bfSize)
		cr = draw_shaded_text(cr, "9", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 12), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "^", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 25), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "6", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 32), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_set_font_size (cr, fSize)
		cr,blx,bly = fiveDay_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 6, 7)
		blx2 = blx
		bly2 = bly
		bly = bly1
		cr,blx,bly = fiveDay_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 8, 9)
		bly = bly2
		cr = draw_horizontal_divider(cr, (blx2), bly, (blx2 + (300 - 1)), bly, 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	else --# default setting
		color = {color0_R,color0_G,color0_B,color0_A}
		fill = 0
		------
		cairo_select_font_face (cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
		cairo_set_font_size (cr, bfSize)
		cr = draw_shaded_text(cr, "5", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 12), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "^", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 25), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cr = draw_shaded_text(cr, "2", (buttons[button_name]["bl_x"] + 5),(buttons[button_name]["bl_y"] - buttons[button_name]["height"] + 32), {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_set_font_size (cr, fSize)
		cr,blx,bly = fiveDay_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 2, 3)
		bly = bly1
		cr,blx,bly = fiveDay_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, 4, 5)
	end
	--####### draw the button ####################
	cr = draw_horizontal_divider(cr, (900), (bly1 - 1), (900), (bly1 + weatherArea_Height), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cr = buttondraw(cr, buttons[button_name]["bl_x"], buttons[button_name]["bl_y"], buttons[button_name]["height"], buttons[button_name]["width"], color, fill, 1)
	--#################################################################
	blx = blx1
	cr,blx,bly = alertsColumn(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height)
	return cr
end --# fiveDay_Weather(cr, extents, wuAPI_Parsed, weatherData, blx, bly, localx, localy, localnowx, localnowy)

function fiveDay_Column0(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height)
	cr = draw_horizontal_divider(cr, 1, (bly1 - 1), 1, (bly1 + weatherArea_Height), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	--######## Column1 ######################################################
	local columnWidth = 300
	local currentWeather = wuAPI_Parsed['current_observation']['weather']
	local currentWeather_imPath = weatherImageLocation..selectForecastIcon(currentWeather,weatherData.isNight)..".png"
	image({x=(0),y=(bly1 - 3),w=88,h=60,file=currentWeather_imPath})
	local currentForecast = wuAPI_Parsed['hourly_forecast'][1]['condition']
	local currentForecast_imPath = weatherImageLocation..selectForecastIcon(currentForecast,weatherData.isNight)..".png"
	image({x=(columnWidth - 100),y=(bly1 - 3),w=88,h=60,file=currentForecast_imPath})
	image({x=(columnWidth - 90),y=(154),w=90,h=90,file=weatherData.moon_Image})
	bly = bly1 + 16
	local dayString = "Today ("..(wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][1]['date']['weekday'])..")"
	cairo_text_extents(cr, dayString, extents)
	blx = (columnWidth - extents.x_advance)/2
	cr = draw_shaded_text(cr, dayString, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	bly = bly + 14
	cairo_text_extents(cr, currentWeather, extents)
	blx = (columnWidth - extents.x_advance)/2
	cr = draw_shaded_text(cr, currentWeather, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	bly = bly + 14
	cairo_text_extents(cr, currentForecast, extents)
	blx = (columnWidth - extents.x_advance)/2
	cr = draw_shaded_text(cr, currentForecast, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	local currTempF,currTempC,currTempK = convertTemp(wuAPI_Parsed['current_observation']['temp_f'])
	cairo_text_extents(cr, "|", extents)
	local vBar_x_advance = extents.x_advance - 1
	cairo_text_extents(cr, currTempF, extents)
	local tempF_x_advance = extents.x_advance
	cairo_text_extents(cr, currTempC, extents)
	local tempC_x_advance = extents.x_advance
	cairo_text_extents(cr, currTempK, extents)
	local tempK_x_advance = extents.x_advance
	blx = (columnWidth - tempF_x_advance - tempC_x_advance - tempK_x_advance - (2 * vBar_x_advance))/2
	bly = bly + 14
	cr = draw_shaded_text(cr, currTempF, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + tempF_x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, currTempC, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + tempC_x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, currTempK, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	local currentModTemp_f = nil
	local currentModTemp_c = nil
	local currentModTemp_k = nil
	local currentWindchill_f = wuAPI_Parsed['current_observation']['windchill_f']
	local currentHeatIndex_f = wuAPI_Parsed['current_observation']['heat_index_f']
	local currentModTemp_string = nil
	if currentWindchill_f == "NA" and currentHeatIndex_f == "NA" then
		currentModTemp_string = "N/A:      "
		currentModTemp_f = string.format("% 5s","N/A").."°F"
		currentModTemp_c = string.format("% 5s","N/A").."°C"
		currentModTemp_k = string.format("% 6s","N/A").." K"
	elseif currentWindchill_f == "NA" and currentHeatIndex_f ~= "NA" then
		currentModTemp_string = "Heat Index:"
		currentModTemp_f,currentModTemp_c,currentModTemp_k = convertTemp(currentHeatIndex_f)
	elseif currentHeatIndex_f == "NA" and currentWindchill_f ~= "NA" then
		currentModTemp_string = "Windchill:"
		currentModTemp_f,currentModTemp_c,currentModTemp_k = convertTemp(currentWindchill_f)
	end --# if currentWindchill_f == "NA" and currentHeatIndex_f == "NA" then
	bly = bly + 14
	blx = 6
	cr = draw_shaded_text(cr, currentModTemp_string, blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + 88
	cr = draw_shaded_text(cr, currentModTemp_f, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, currentModTemp_f, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, currentModTemp_c, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, currentModTemp_c, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, currentModTemp_k, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	local dewPointF,dewPointC,dewPointK = convertTemp(wuAPI_Parsed['current_observation']['dewpoint_f'])
	bly = bly + 14
	blx = 6
	cr = draw_shaded_text(cr, "Dew Point: ", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + 88
	cr = draw_shaded_text(cr, dewPointF, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, dewPointF, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, dewPointC, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, dewPointC, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, dewPointK, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	local highTempF,highTempC,highTempK = convertTemp(wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][1]['high']['fahrenheit'])
	bly = bly + 14
	blx = 6
	cr = draw_shaded_text(cr, "High Temp:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + 88
	cr = draw_shaded_text(cr, highTempF, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, highTempF, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, highTempC, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, highTempC, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, highTempK, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	local lowTempF,lowTempC,lowTempK = convertTemp(wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][1]['low']['fahrenheit'])
	bly = bly + 14
	blx = 6
	cr = draw_shaded_text(cr, "Low Temp:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + 88
	cr = draw_shaded_text(cr, lowTempF, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, lowTempF, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, lowTempC, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, lowTempC, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, lowTempK, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	local currentWindMPH = wuAPI_Parsed['current_observation']['wind_mph']
	local currentWindGustMPH = wuAPI_Parsed['current_observation']['wind_gust_mph']
	local currentWindDirection = wuAPI_Parsed['current_observation']['wind_dir']
	local currentWindDegrees = wuAPI_Parsed['current_observation']['wind_degrees']
	bly = bly + 14
	blx = 6
	cr = draw_shaded_text(cr, "Wind:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Wind:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, currentWindDirection, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, currentWindDirection, extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, "(", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "(", extents)
	blx = blx + extents.x_advance - 1
	cr = draw_shaded_text(cr, currentWindDegrees, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, currentWindDegrees, extents)
	blx = blx + extents.x_advance
	cr = draw_shaded_text(cr, ")", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, ")", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, "at", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "at", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, currentWindMPH, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, currentWindMPH, extents)
	blx = blx + extents.x_advance
	cr = draw_shaded_text(cr, "(", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "(", extents)
	blx = blx + extents.x_advance - 1
	cr = draw_shaded_text(cr, currentWindGustMPH, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, currentWindGustMPH, extents)
	blx = blx + extents.x_advance
	cr = draw_shaded_text(cr, ")", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, ")", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, "mph", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	local currentPressure_mbar = wuAPI_Parsed['current_observation']['pressure_mb']
	local currentPressureTrend = wuAPI_Parsed['current_observation']['pressure_trend']
	bly = bly + 14
	blx = 6
	cr = draw_shaded_text(cr, "Bar:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Bar:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, currentPressure_mbar, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, currentPressure_mbar, extents)
	blx = blx + extents.x_advance + 5
	cr = draw_shaded_text(cr, "mbar", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "mbar", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, "(", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "(", extents)
	blx = blx + extents.x_advance - 1
	cr = draw_shaded_text(cr, currentPressureTrend, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, currentPressureTrend, extents)
	blx = blx + extents.x_advance - 1
	cr = draw_shaded_text(cr, ")", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	local currentRelativeHumidity = wuAPI_Parsed['current_observation']['relative_humidity']
	local currentForecastHumidity = wuAPI_Parsed['hourly_forecast'][1]['humidity']
	bly = bly + 14
	blx = 6
	cr = draw_shaded_text(cr, "Humidity:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Humidity:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, currentRelativeHumidity, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, currentRelativeHumidity, extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, currentForecastHumidity.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	local currentVisability = wuAPI_Parsed['current_observation']['visibility_mi']
	bly = bly + 14
	blx = 6
	cr = draw_shaded_text(cr, "Visibility:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Visibility:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, currentVisability, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, currentVisability, extents)
	blx = blx + extents.x_advance + 4
	cr = draw_shaded_text(cr, "mi", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	local currentPrecipChance = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][1]['pop']
	local currentPrecipChance_Hourly = wuAPI_Parsed['hourly_forecast'][1]['pop']
	bly = bly + 14
	blx = 6
	cr = draw_shaded_text(cr, "Rain/Snow Chance:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Rain/Snow Chance:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, currentPrecipChance.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, currentPrecipChance.."%", extents)
	blx = blx + extents.x_advance + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, currentPrecipChance_Hourly.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	local rainLastHour,rainLastHour_in = xpcall(getRainHour, debug.traceback)
	if rainLastHour == false then
		--print(tostring(rainLastHour_in))
		rainLastHour_in = "0.00"
	elseif ((rainLastHour_in == "-9999.00") or (rainLastHour_in == "") or (rainLastHour_in == nil)) then
		rainLastHour_in = "0.00"
	end --# if rainLastHour == false then
	local rainToday,rainToday_in = xpcall(getRainToday, debug.traceback)
	if rainToday == false then
		--print(tostring(rainToday_in))
		rainToday_in = "0.00"
	elseif ((rainToday_in == "-9999.00") or (rainToday_in == "") or (rainToday_in == nil)) then
		rainToday_in = "0.00"
	end --# if rainToday == false then
	bly = bly + 14
	blx = 6
	cr = draw_shaded_text(cr, "Total Precip:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Total Precip:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, rainLastHour_in, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, rainLastHour_in, extents)
	blx = blx + extents.x_advance + 4
	cr = draw_shaded_text(cr, "in", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "in", extents)
	blx = blx + extents.x_advance + 2
	cr = draw_shaded_text(cr, "(", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "(", extents)
	blx = blx + extents.x_advance - 1
	cr = draw_shaded_text(cr, rainToday_in, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, rainToday_in, extents)
	blx = blx + extents.x_advance + 4
	cr = draw_shaded_text(cr, "in", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "in", extents)
	blx = blx + extents.x_advance
	cr = draw_shaded_text(cr, ")", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	bly = bly + 14
	blx = 6
	cr = draw_shaded_text(cr, "Sun Rise/Sun Set:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Sun Rise/Sun Set:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, weatherData.SunriseHour..":", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, weatherData.SunriseHour..":", extents)
	blx = blx + extents.x_advance - 1
	cr = draw_shaded_text(cr, weatherData.SunriseMin, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, weatherData.SunriseMin, extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, weatherData.Sunrise_AMorPM, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, weatherData.Sunrise_AMorPM, extents)
	blx = blx + extents.x_advance
	cr = draw_shaded_text(cr, "/", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "/", extents)
	blx = blx + extents.x_advance - 1 
	cr = draw_shaded_text(cr, weatherData.SunsetHour..":", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, weatherData.SunsetHour..":", extents)
	blx = blx + extents.x_advance - 1
	cr = draw_shaded_text(cr, weatherData.SunsetMin, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, weatherData.SunsetMin, extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, weatherData.Sunset_AMorPM, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	bly = bly + 14
	blx = 6
	cr = draw_shaded_text(cr, "Moon Phase:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "Moon Phase:", extents)
	blx = blx + extents.x_advance + 3
	cr = draw_shaded_text(cr, weatherData.moon_Percent.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, weatherData.moon_Percent.."%", extents)
	blx = blx + extents.x_advance
	cr = draw_shaded_text(cr, "/", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "/", extents)
	blx = blx + extents.x_advance - 1 
	cr = draw_shaded_text(cr, weatherData.moon_Age, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, weatherData.moon_Age, extents)
	blx = blx + extents.x_advance
	cr = draw_shaded_text(cr, "/", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	cairo_text_extents(cr, "/", extents)
	blx = blx + extents.x_advance - 1
	cr = draw_shaded_text(cr, weatherData.moon_Phase, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	--#################################################################
	cr = draw_horizontal_divider(cr, columnWidth, (bly1 - 1), columnWidth, (bly1 + weatherArea_Height), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	--####### End Column1 ###################################################
	blx = columnWidth
	return cr,blx,bly
end --# function fiveDay_Column0(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height)

function fiveDay_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, i, j)
	if #wuAPI_Parsed['forecast']['simpleforecast']['forecastday'] >= i then
		--######## Column2 ################################################
		local columnWidth = 300
		local blx1 = blx
		local bly1 = bly
		cairo_text_extents(cr, "|", extents)
		local vBar_x_advance = extents.x_advance - 1
		--#################################################################
		local plus1_Conditions = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][i]['conditions']
		local plus1_imPath = weatherImageLocation..selectForecastIcon(plus1_Conditions,weatherData.isNight)..".png"
		image({x=(blx1),y=(bly1 - 3),w=57,h=39,file=plus1_imPath})
		blx = blx1 + 5
		bly = bly1 + 16
		local dayString = ""
		if i == 2 then
			dayString = "Tommorow ("..(wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][i]['date']['weekday'])..")"
		else
			dayString = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][i]['date']['weekday']
		end --# if i == 2 then
		cairo_text_extents(cr, dayString, extents)
		blx = blx1 + ((columnWidth - extents.x_advance)/2)
		cr = draw_shaded_text(cr, dayString, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		bly = bly + 14
		cairo_text_extents(cr, plus1_Conditions, extents)
		blx = blx1 + ((columnWidth - extents.x_advance)/2)
		cr = draw_shaded_text(cr, plus1_Conditions, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		--#################################################################
		local highTempF,highTempC,highTempK = convertTemp(wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][i]['high']['fahrenheit'])
		bly = bly + 16
		blx = blx1 + 5
		cr = draw_shaded_text(cr, "High Temp:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		blx = blx + 88
		cr = draw_shaded_text(cr, highTempF, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_text_extents(cr, highTempF, extents)
		blx = blx + extents.x_advance + 1
		cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		blx = blx + vBar_x_advance
		cr = draw_shaded_text(cr, highTempC, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_text_extents(cr, highTempC, extents)
		blx = blx + extents.x_advance + 1
		cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		blx = blx + vBar_x_advance
		cr = draw_shaded_text(cr, highTempK, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		--#################################################################
		local lowTempF,lowTempC,lowTempK = convertTemp(wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][i]['low']['fahrenheit'])
		bly = bly + 14
		blx = blx1 + 5
		cr = draw_shaded_text(cr, "Low Temp:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		blx = blx + 88
		cr = draw_shaded_text(cr, lowTempF, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_text_extents(cr, lowTempF, extents)
		blx = blx + extents.x_advance + 1
		cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		blx = blx + vBar_x_advance
		cr = draw_shaded_text(cr, lowTempC, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_text_extents(cr, lowTempC, extents)
		blx = blx + extents.x_advance + 1
		cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		blx = blx + vBar_x_advance
		cr = draw_shaded_text(cr, lowTempK, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		--#################################################################
		local plus1AvgHumidity = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][i]['avehumidity']
		local plus1MaxHumidity = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][i]['maxhumidity']
		local plus1MinHumidity = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][i]['minhumidity']
		bly = bly + 14
		blx = blx1 + 5
		cr = draw_shaded_text(cr, "Humidity:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_text_extents(cr, "Humidity:", extents)
		blx = blx + extents.x_advance + 3
		cr = draw_shaded_text(cr, plus1MinHumidity.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_text_extents(cr, plus1MinHumidity.."%", extents)
		blx = blx + extents.x_advance
		cr = draw_shaded_text(cr, "/", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_text_extents(cr, "/", extents)
		blx = blx + extents.x_advance - 1 
		cr = draw_shaded_text(cr, plus1AvgHumidity.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_text_extents(cr, plus1AvgHumidity.."%", extents)
		blx = blx + extents.x_advance
		cr = draw_shaded_text(cr, "/", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_text_extents(cr, "/", extents)
		blx = blx + extents.x_advance - 1
		cr = draw_shaded_text(cr, plus1MaxHumidity.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		--#################################################################
		local plus1PrecipChance = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][i]['pop']
		bly = bly + 14
		blx = blx1 + 6
		cr = draw_shaded_text(cr, "Rain/Snow Chance:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		cairo_text_extents(cr, "Rain/Snow Chance:", extents)
		blx = blx + extents.x_advance + 3
		cr = draw_shaded_text(cr, plus1PrecipChance.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		--#################################################################
		bly = bly + 6
		cr = draw_horizontal_divider(cr, (blx1), bly, (blx1 + (columnWidth - 1)), bly, 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		--#################################################################
		if #wuAPI_Parsed['forecast']['simpleforecast']['forecastday'] >= j then
			plus1_Conditions = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][j]['conditions']
			plus1_imPath = weatherImageLocation..selectForecastIcon(plus1_Conditions,weatherData.isNight)..".png"
			image({x=(blx1),y=(bly - 3),w=57,h=39,file=plus1_imPath})
			blx = blx1 + 5
			bly = bly + 16
			dayString = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][j]['date']['weekday']
			cairo_text_extents(cr, dayString, extents)
			blx = blx1 + ((columnWidth - extents.x_advance)/2)
			cr = draw_shaded_text(cr, dayString, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			bly = bly + 14
			cairo_text_extents(cr, plus1_Conditions, extents)
			blx = blx1 + ((columnWidth - extents.x_advance)/2)
			cr = draw_shaded_text(cr, plus1_Conditions, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			--#################################################################
			highTempF,highTempC,highTempK = convertTemp(wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][j]['high']['fahrenheit'])
			bly = bly + 16
			blx = blx1 + 5
			cr = draw_shaded_text(cr, "High Temp:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			blx = blx + 88
			cr = draw_shaded_text(cr, highTempF, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_text_extents(cr, highTempF, extents)
			blx = blx + extents.x_advance + 1
			cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			blx = blx + vBar_x_advance
			cr = draw_shaded_text(cr, highTempC, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_text_extents(cr, highTempC, extents)
			blx = blx + extents.x_advance + 1
			cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			blx = blx + vBar_x_advance
			cr = draw_shaded_text(cr, highTempK, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			--#################################################################
			lowTempF,lowTempC,lowTempK = convertTemp(wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][j]['low']['fahrenheit'])
			bly = bly + 14
			blx = blx1 + 5
			cr = draw_shaded_text(cr, "Low Temp:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			blx = blx + 88
			cr = draw_shaded_text(cr, lowTempF, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_text_extents(cr, lowTempF, extents)
			blx = blx + extents.x_advance + 1
			cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			blx = blx + vBar_x_advance
			cr = draw_shaded_text(cr, lowTempC, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_text_extents(cr, lowTempC, extents)
			blx = blx + extents.x_advance + 1
			cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			blx = blx + vBar_x_advance
			cr = draw_shaded_text(cr, lowTempK, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			--#################################################################
			plus1AvgHumidity = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][j]['avehumidity']
			plus1MaxHumidity = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][j]['maxhumidity']
			plus1MinHumidity = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][j]['minhumidity']
			bly = bly + 14
			blx = blx1 + 5
			cr = draw_shaded_text(cr, "Humidity:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_text_extents(cr, "Humidity:", extents)
			blx = blx + extents.x_advance + 3
			cr = draw_shaded_text(cr, plus1MinHumidity.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_text_extents(cr, plus1MinHumidity.."%", extents)
			blx = blx + extents.x_advance
			cr = draw_shaded_text(cr, "/", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_text_extents(cr, "/", extents)
			blx = blx + extents.x_advance - 1 
			cr = draw_shaded_text(cr, plus1AvgHumidity.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_text_extents(cr, plus1AvgHumidity.."%", extents)
			blx = blx + extents.x_advance
			cr = draw_shaded_text(cr, "/", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_text_extents(cr, "/", extents)
			blx = blx + extents.x_advance - 1
			cr = draw_shaded_text(cr, plus1MaxHumidity.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			--#################################################################
			plus1PrecipChance = wuAPI_Parsed['forecast']['simpleforecast']['forecastday'][j]['pop']
			bly = bly + 14
			blx = blx1 + 6
			cr = draw_shaded_text(cr, "Rain/Snow Chance:", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_text_extents(cr, "Rain/Snow Chance:", extents)
			blx = blx + extents.x_advance + 3
			cr = draw_shaded_text(cr, plus1PrecipChance.."%", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			--#################################################################
			bly = bly + 6
			cr = draw_horizontal_divider(cr, (blx1), bly, (blx1 + (columnWidth - 1)), bly, 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			--#################################################################
		else
			bly = (bly1 + ((bly - bly1)*2))
			cr = draw_horizontal_divider(cr, (blx1), bly, (blx1 + (columnWidth - 1)), bly, 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		end --# if #wuAPI_Parsed['forecast']['simpleforecast']['forecastday'] >= j then
		cr = draw_horizontal_divider(cr, (blx1 + columnWidth), (bly1 -1), (blx1 + columnWidth), (bly), 1, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		--####### End Column2 #############################################
		blx = blx1 + columnWidth
	end --# if #wuAPI_Parsed['forecast']['simpleforecast']['forecastday'] >= i then
	return cr,blx,bly
end --# function fiveDay_Column1(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height, i, j)

function alertsColumn(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height)
	weatherData.Alerts = wuAPI_Parsed['alerts']
	local columnWidth = 600
	local blx1 = blx
	cairo_text_extents(cr, "|", extents)
	local vBar_x_advance = extents.x_advance - 1
	bly = bly + 17
	local alertsExtent = 0
	if #weatherData.Alerts == 0 then --# no alerts
		cairo_text_extents(cr, "No Alerts", extents)
		blx = blx1 + ((columnWidth - extents.x_advance)/2)
		cr = draw_shaded_text(cr, "No Alerts", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	else
		for i = 1 , #weatherData.Alerts do --#
			cairo_text_extents(cr, weatherData.Alerts[i]['description'], extents)
			alertsExtent = alertsExtent + extents.x_advance + 1 + vBar_x_advance
		end --# for i = 1 , #weatherData.Alerts do
		if alertsExtent < columnWidth then
			blx = blx1 + ((columnWidth - alertsExtent)/2)
		else
			blx = blx1 + 6
		end --# if alertsExtent < columnWidth then
		for i = 1 , #weatherData.Alerts do --#
			cr = draw_shaded_text(cr, weatherData.Alerts[i]['description'], blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			if i ~= #weatherData.Alerts then
				cairo_text_extents(cr, weatherData.Alerts[i]['description'], extents)
				blx = blx + extents.x_advance + 1
				cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
				blx = blx + vBar_x_advance
			end --# if i ~= #weatherData.Alerts then
		end --# for i = 1 , #weatherData.Alerts do
	end --# if #weatherData.Alerts == 0 then
	--#################################################################
	local observationLocation = nil
	local observationStation = nil
	if scrotMode == false then
		observationLocation = wuAPI_Parsed['current_observation']['observation_location']['full'] --# get the location the current observation data was recored at
		observationStation = wuAPI_Parsed['current_observation']['station_id'] --# get station id of the current observation was taken at.
	else
		observationLocation = "City, State"
		observationStation = "Station"
	end --# if scrotMode == false then
	bly = bly + 17
	cairo_text_extents(cr, observationLocation, extents)
	local location_x_advance = extents.x_advance + 1
	cairo_text_extents(cr, observationStation, extents)
	local station_x_advance = extents.x_advance + 1
	local floodLevel_x_advance = nil
	local floodHour_x_advance = nil
	local floodMinute_x_advance = nil
	local floodAMorPM_x_advance = nil
	local dash_x_advance = nil
	local line2_x_advance = nil
	if use_NOAA == true then --# using NOAA floodstage data
		cairo_text_extents(cr, weatherData.stateData[1][1], extents)
		floodLevel_x_advance = extents.x_advance + 3
		cairo_text_extents(cr, (weatherData.stateData[1][3][1])..":", extents)
		floodHour_x_advance = extents.x_advance
		cairo_text_extents(cr, weatherData.stateData[1][3][2], extents)
		floodMinute_x_advance = extents.x_advance + 7
		cairo_text_extents(cr, weatherData.stateData[1][3][3], extents)
		floodAMorPM_x_advance = extents.x_advance + 3
		cairo_text_extents(cr, "-", extents)
		dash_x_advance = extents.x_advance + 2
		line2_x_advance = location_x_advance + station_x_advance + floodLevel_x_advance + floodHour_x_advance + floodMinute_x_advance + floodAMorPM_x_advance + (vBar_x_advance * 2) + dash_x_advance
	else
		line2_x_advance = location_x_advance + station_x_advance + vBar_x_advance
	end --# if use_NOAA == true then
	--print (line2_x_advance.." "..columnWidth)
	if line2_x_advance < columnWidth then
		blx = blx1 + ((columnWidth - line2_x_advance)/2)
	else
		blx = blx1 + 6
	end --# if line2_x_advance < columnWidth then
	cr = draw_shaded_text(cr, observationStation, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + station_x_advance-- + 1
	cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
	blx = blx + vBar_x_advance
	cr = draw_shaded_text(cr, observationLocation, blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	if use_NOAA == true then --# using NOAA floodstage data
		blx = blx + location_x_advance-- + 1
		cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		blx = blx + vBar_x_advance
		local floodLevel_num = tonumber((weatherData.stateData[1][1]:gsub(" ft","")))
		local riverColor = nil
		local riverShade = nil
		if floodLevel_num >= 40 then
			riverColor = {0.8,0.2,1,1}
			riverShade = {0,0,0,1}
		elseif floodLevel_num >= 38 then
			riverColor = {0.93333,0,0,1}
			riverShade = {0,0,0,1}
		elseif floodLevel_num >= 35 then
			riverColor = {1,0.50196,0,1}
			riverShade = {color3_R,color3_G,color3_B,color3_A}
		elseif floodLevel_num >= 33 then
			riverColor = {0.93333,0.93333,0,1}
			riverShade = {color3_R,color3_G,color3_B,color3_A}
		else
			riverColor = {color0_R,color0_G,color0_B,color0_A}
			riverShade = {color3_R,color3_G,color3_B,color3_A}
		end --# if floodLevel_num >= 40 then
		cr = draw_shaded_text(cr, weatherData.stateData[1][1], blx, bly, riverColor, riverShade)
		blx = blx + floodLevel_x_advance-- + 3
		cr = draw_shaded_text(cr, "-", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
		blx = blx + dash_x_advance-- + 2
		cr = draw_shaded_text(cr, weatherData.stateData[1][3][1]..":", blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		blx = blx + floodHour_x_advance
		cr = draw_shaded_text(cr, weatherData.stateData[1][3][2], blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
		blx = blx + floodMinute_x_advance-- + 7
		cr = draw_shaded_text(cr, weatherData.stateData[1][3][3], blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
	end --# if use_NOAA == true then
	--#################################################################
	blx = blx1 + columnWidth
	return cr,blx,bly
end --# function alertsColumn(cr, extents, wuAPI_Parsed, weatherData, blx, bly, bly1, weatherArea_Height)
--#### End fiveDay_Weather Functions ####

--#### Start Scrolling Alerts Function ####
function scrollingAlerts(cr, extents, wuAPI_Parsed, weatherData, blx, bly, scrollAdvance, scrollDisplay_Length)
	cairo_text_extents(cr, "|", extents)
	local vBar_x_advance = extents.x_advance - 1
	--local scrollAdvance = 10 --# number of characters to advance scroll string by
	--local scrollDisplay_Length = 115 --# length of scrolling text in characters
	local displayString = ""
	--print("1\nweatherData.alertString_Start: "..weatherData.alertString_Start.."\nweatherData.alertString_End: "..weatherData.alertString_End.."\nDifference: "..(weatherData.alertString_End - weatherData.alertString_Start))
	weatherData.alertString_End = weatherData.alertString_End + scrollAdvance
	if weatherData.alertString_End > scrollDisplay_Length then
		--weatherData.alertString_Start = weatherData.alertString_Start + scrollAdvance
		weatherData.alertString_Start = weatherData.alertString_End - (scrollDisplay_Length - 1)
		if weatherData.alertString_Start > #weatherData.alertString then
			weatherData.alertString_Start = 1
			weatherData.alertString_End = 1 + scrollAdvance
			displayString = weatherData.alertString:sub(weatherData.alertString_Start, weatherData.alertString_End)
			cairo_text_extents(cr, " ", extents)
			blx = blx + (extents.x_advance * (scrollDisplay_Length - #displayString))
		else
			displayString = weatherData.alertString:sub(weatherData.alertString_Start, weatherData.alertString_End)
		end --# if weatherData.alertString_Start > #weatherData.alertString then
	else
		displayString = weatherData.alertString:sub(weatherData.alertString_Start, weatherData.alertString_End)
		if #displayString < scrollDisplay_Length then
			cairo_text_extents(cr, " ", extents)
			blx = blx + (extents.x_advance * (scrollDisplay_Length - #displayString))
		end --# if #displayString < scrollDisplay_Length then
	end --# if weatherData.alertString_End > scrollDisplay_Length then
	--print(displayString)
	--print(#displayString)
	local displaySplit = assert(loadstring(("return {'"..(displayString:gsub("||","','")).."'}")))()
	local displaySplit2 = {}
	for i = 1, #displaySplit do
		displaySplit2[i] = assert(loadstring(("return {'"..(displaySplit[i]:gsub("|","','")).."'}")))()
	end --# for i = 1, #displaySplit do
	--print(#displaySplit2)
	for i = 1, #displaySplit2 do
		if i > 1 then
			cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			blx = blx + vBar_x_advance
			cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
			blx = blx + vBar_x_advance
		end --# if i > 1 then
		for j = 1, #displaySplit2[i] do
			cr = draw_shaded_text(cr, displaySplit2[i][j], blx, bly, {color0_R,color0_G,color0_B,color0_A}, {color3_R,color3_G,color3_B,color3_A})
			cairo_text_extents(cr, displaySplit2[i][j], extents)
			blx = blx + extents.x_advance + 1
			if j ~= #displaySplit2[i] then
				cr = draw_shaded_text(cr, "|", blx, bly, {color1_R,color1_G,color1_B,color1_A}, {color3_R,color3_G,color3_B,color3_A})
				blx = blx + vBar_x_advance
			end --# if j ~= #displaySplit2[i] then
		end --# for j = 1, #displaySplit2[i] do
	end --# for i = 1, #displaySplit2 do
	--#################################################################
	return cr,blx,bly
end --# function scrollingAlerts(cr, extents, wuAPI_Parsed, weatherData, blx, bly, scrollAdvance, scrollDisplay_Length)
--#### End Scrolling Alerts Functtion #####
--################################################################################################################

function draw_bg(CR)
	local corner_r = 0 --# "corner_r" is the radius, in pixels, of the rounded corners. If you don't want rounded corners, use 0.
	local v = 0 --# stop height offset (negative offset)
	local w = conky_window.width
	local h = conky_window.height
	local s = 10 --# start height offset (positive offset)
	cairo_move_to(CR,corner_r,s)
	cairo_line_to(CR,w-corner_r,s)
	cairo_curve_to(CR,w,0,w,0,w,corner_r)
	cairo_line_to(CR,w,h+v-corner_r)
	cairo_curve_to(CR,w,h+v,w,h+v,w-corner_r,h+v)
	cairo_line_to(CR,corner_r,h+v)
	cairo_curve_to(CR,0,h+v,0,h+v,0,h+v-corner_r)
	cairo_line_to(CR,0,corner_r)
	cairo_curve_to(CR,0,0,0,0,corner_r,0)
	cairo_close_path(CR)
	local bgColor = nil
	if luaBG_cType == true then
		bgColor = assert(loadfile(luaBG_Settings_Location))()
	else
		bgColor = luaBG_Color
	end --# if luaBG_cType == true then
	cairo_set_source_rgba(CR,bgColor[1],bgColor[2],bgColor[3],bgColor[4])
	cairo_fill(CR)
	return CR
end --# function draw_bg()

function draw_shaded_text(CR, text, xpos, ypos, COLOR, shade_color)
	cairo_set_source_rgba (CR,shade_color[1],shade_color[2],shade_color[3],shade_color[4]) --# set shade color
	cairo_move_to (CR,(xpos + 1),(ypos + 1))
	cairo_show_text (CR,text)
	cairo_stroke (CR)
	cairo_set_source_rgba (CR,COLOR[1],COLOR[2],COLOR[3],COLOR[4]) --# set font color
	cairo_move_to (CR,xpos,ypos)
	cairo_show_text (CR,text)
	cairo_stroke (CR)
	return CR
end --# function cr = cr = draw_shaded_text(cr, cr, )

function draw_horizontal_divider(CR, xpos, ypos, xend, yend, lineWidth, COLOR, shade_color)
	--cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE) --# don't antialias outline it is too thin and gets blurred
	cairo_set_line_width (CR,lineWidth)
	--# draw shade
	cairo_set_source_rgba (CR,shade_color[1],shade_color[2],shade_color[3],shade_color[4]) --# set shade color
	cairo_move_to (CR, (xpos + 1), (ypos + 1))
	cairo_line_to (CR,(xend + 1), (yend + 1))
	cairo_stroke (CR)
	--# draw line
	cairo_set_source_rgba (CR,COLOR[1],COLOR[2],COLOR[3],COLOR[4]) --# set color
	cairo_move_to (CR, xpos, ypos)
	cairo_line_to (CR, xend, yend)
	cairo_stroke (CR)
	--cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT)
	return CR
end --# function cr = cr = draw_horizontal_divider(cr,cr, )

function image(im)
	local x = nil
	x = (im.x or 0)
	local y = nil
	y = (im.y or 0)
	local w = nil
	w = (im.w or default_image_width)
	local h = nil
	h = (im.h or default_image_height)
	local file = nil
	file = tostring(im.file)
	if file == nil then 
		print("set image file") 
	end --# if file == nil then 
	local show = imlib_load_image(file)
	if show == nil then 
		return 
	end --# if show == nil then 
	imlib_context_set_image(show)
	local WIDTH = nil
	if tonumber(w) == 0 then 
		WIDTH = imlib_image_get_width() 
	else
		WIDTH = tonumber(w)
	end --# if tonumber(w) == 0 then
	local HEIGHT = nil
	if tonumber(h) == 0 then 
		HEIGHT = imlib_image_get_height() 
	else
		HEIGHT = tonumber(h)
	end --# if tonumber(h) == 0 then 
	local scaled = imlib_create_cropped_scaled_image(0, 0, imlib_image_get_width(), imlib_image_get_height(), WIDTH, HEIGHT)
	imlib_free_image_and_decache()
	imlib_context_set_image(scaled)
	imlib_render_image_on_drawable(x, y)
	imlib_free_image_and_decache()
	show = nil
	WIDTH = nil
	HEIGHT = nil
	x = nil
	y = nil
	w = nil
	h = nil
	file = nil
	scaled = nil
end --# function image(im)

--# cropSettings = {xStart,yStart,cropWidth,cropHeight}
function image_cropped(im, cropSettings)
	local x = nil
	x = (im.x or 0)
	local y = nil
	y = (im.y or 0)
	local w = nil
	w = (im.w or default_image_width)
	local h = nil
	h = (im.h or default_image_height)
	local file = nil
	file = tostring(im.file)
	if file == nil then 
		print("set image file") 
	end --# if file == nil then 
	local show = imlib_load_image(file)
	if show == nil then 
		return 
	end --# if show == nil then 
	imlib_context_set_image(show)
	local WIDTH = nil
	if tonumber(w) == 0 then 
		WIDTH = imlib_image_get_width() 
	else
		WIDTH = tonumber(w)
	end --# if tonumber(w) == 0 then
	local HEIGHT = nil
	if tonumber(h) == 0 then 
		HEIGHT = imlib_image_get_height() 
	else
		HEIGHT = tonumber(h)
	end --# if tonumber(h) == 0 then 
	local scaled = imlib_create_cropped_scaled_image(cropSettings[1], cropSettings[2], cropSettings[3], cropSettings[4], WIDTH, HEIGHT)
	imlib_free_image_and_decache()
	imlib_context_set_image(scaled)
	imlib_render_image_on_drawable(x, y)
	imlib_free_image_and_decache()
	show = nil
	WIDTH = nil
	HEIGHT = nil
	x = nil
	y = nil
	w = nil
	h = nil
	file = nil
	scaled = nil
end --# function image_cropped(im, cropSettings)

--#### Button code based on interactive conky by mrpeachy ####
--#### http://crunchbanglinux.org/forums/topic/18419/interactive-conky/ ####
--# button drawing function
function buttondraw(CR, BLX,BLY,HEIGHT,WIDTH,COLOR,FILL,LINE_WIDTH)
	--cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER) --# in case of wacky defaults
	--cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE) --# don't antialias outline it is too thin and gets blurred
	cairo_set_line_width (CR,LINE_WIDTH)
	cairo_set_source_rgba (CR,color3_R,color3_G,color3_B,color3_A)
	cairo_rectangle (CR,(BLX + 1),(BLY + 1),WIDTH,-HEIGHT)
	if FILL == 0 then
		cairo_stroke (CR)
	elseif FILL == 1 then
		cairo_fill (CR)
	end --# if FILL == 0 then
	cairo_set_source_rgba (CR,COLOR[1],COLOR[2],COLOR[3],COLOR[4])
	cairo_rectangle (CR,BLX,BLY,WIDTH,-HEIGHT)
	if FILL == 0 then
		cairo_stroke (CR)
	elseif FILL == 1 then
		cairo_fill (CR)
	end --# if FILL == 0 then
	return CR
	--cairo_set_antialias (cr, CAIRO_ANTIALIAS_DEFAULT) --# reset antialias method to default
end --# function buttondraw(CR, BLX,BLY,HEIGHT,WIDTH,COLOR,FILL,LINE_WIDTH)

function clickfunction()
	--################################################################################################
	if tonumber(conky_parse('${updates}')) < 2 then
		local s = nil
		local f = io.popen("xwininfo -all -int -tree -name '"..conkyWindowTitle.."'")
		local winData = f:read("*a")
		f:close()
		f = nil
		s,f,xdotool_window_number2 = string.find(winData,"xwininfo.%s.indow%sid.%s(%d+)%s") --# some window mangers use this (Cinnamon, Compiz (Unity))
		s,f,xdotool_window_number = string.find(winData,"Parent%swindow%sid.%s(%d+)%s") --# some window managers use this (Fluxbox, Openbox)
		s,f,abstlx = string.find(winData,"Absolute%supper.left%sX%p%s*(%p*%d*)")
		s,f,abstly = string.find(winData,"Absolute%supper.left%sY%p%s*(%p*%d*)")
		print("abstlx: "..tostring(abstlx).." abstly: "..tostring(abstly).." winNum_Parent: "..tostring(xdotool_window_number).." winNum_2: "..tostring(xdotool_window_number2))
	end --# if tonumber(conky_parse('${updates}')) < 2 then
	--#################################################################################################
    --######### start click logging and calculations ##################################################
    local s = nil
    --######### Get Current Mouse Location ###################
	local f = io.popen("xdotool getmouselocation 2> /dev/null")
	local mousenow = f:read("*a")
	f:close()
	f = nil
	local mousenowx = nil
	local mousenowy = nil
	local mousex = nil
	local mousey = nil
	if ((mousenow == nil) or (mousenow == "")) then --# check for failure of xdotool getmouselocation command (crashes script but usually only lasts one or two updates)
		print("error: could not get mouse location")
		mousenowx = "0"
		mousenowy = "0"
		mousex = "0"
		mousey = "0"
	elseif ((string.find(mousenow, xdotool_window_number) ~= nil) or (string.find(mousenow, xdotool_window_number2) ~= nil)) then --# check if mouse is in this conky window
		--print("debug: mouse is in this window")
		s,f,mousenowx = string.find(mousenow,"x%p(%d*)%s")
		s,f,mousenowy = string.find(mousenow,"y%p(%d*)%s")
		--#### Get Click Location
		f = io.popen("tail --lines=1 /tmp/"..tempFileName)
		local click = f:read("*a")
		f:close()
		f = nil
		if ((click == nil) or (click == "")) then --# xdotool log file does not exist or is empty (prevents crash before first click or if you specify the wrong file)
			print("error: could not read xdotool logfile")
			mousex = "0"
			mousey = "0"
		elseif (click:gsub("\n","") == "Command failed.") then --# this is does not crash xdotool (probably a communication error between xdotool and some part of the system)
			print("error: xdotool error")
			mousex = "0"
			mousey = "0"
		else --# no problems reading the xdotool log file
			if ((string.find(click, xdotool_window_number) ~= nil) or (string.find(click, xdotool_window_number2) ~= nil)) then --# last click was in this window
				print("debug: click was in this window")
				s,f,mousex = string.find(click,"x%p(%d*)")
				s,f,mousey = string.find(click,"y%p(%d*)")
				--### Reset xdotool log file
				f = io.open("/tmp/"..tempFileName,"w")
				f:write("x:0 y:0 screen:0 window:0\n")
				f:close()
				f = nil
			else --# last click was not in this window
				--print("debug: click not in this window")
				mousex = "0"
				mousey = "0"
			end --# if string.find(click, xdotool_window_number) ~= nil then
		end --# if ((click == nil) or (click == "")) then
	else --# mouse not in this window
		mousenowx = "0"
		mousenowy = "0"
		mousex = "0"
		mousey = "0"
	end --# if string.find(mousenow, xdotool_window_number) then
	local localx = tonumber(mousex) - abstlx
	local localy = tonumber(mousey) - abstly
	local localnowx = tonumber(mousenowx) - abstlx
	local localnowy = tonumber(mousenowy) - abstly
    --END CLICK CALCULATIONS #################################
    return localx,localy,localnowx,localnowy
end --# function clickfunction()

function conky_start_xdotool()
    os.execute("pkill -f \"xdotool search --sync --classname conky behave %@ mouse-click getmouselocation\"")
    os.execute("xdotool search --sync --classname 'conky' behave %@ mouse-click getmouselocation 2> /dev/null >> /tmp/"..tempFileName.." &")
end --# function conky_start_xdotool()

function conky_stop_xdotool()
	local stdout = io.popen("ps --no-headers -C conky -O cmd")
	local conkyCount = 0
	local rconkyData = stdout:read("*l")
	while rconkyData ~= nil do
		if ((string.find(rconkyData,"conkyrc_conkyWeather_arclance") ~= nil)) then --# is one of the conkys to check for (could use something generic like "button" here)
			print("found")
			conkyCount = conkyCount + 1
		end --# if string.find("conkyrc_systemConky") ~= nil then
		rconkyData = stdout:read("*l")
	end --# while rconkyData ~= nil do
	stdout:close()
    if conkyCount == 1 then
		print("killing xdotool")
		os.execute("pkill -f \"xdotool search --sync --classname conky behave %@ mouse-click getmouselocation\"")
	end --# if conkyCount == 1 then
end --# function conky_stop_xdotool()

--################################################################

function convertTemp(tempF)
	local tempC = nil
	local tempK = nil
	if tempF == "" then --# handle empty variables
		tempF = string.format("% 5s","N/A").."°F"
		tempC = string.format("% 5s","N/A").."°C"
		tempK = string.format("% 6s","N/A").." K"
	else
		tempF = tonumber(tempF)
		tempC = (tempF - 32) * (5/9)
		tempK = tempC + 273.15
		tempF = string.format("%4.2f", tempF).."°F"
		tempC = string.format("%4.2f", tempC).."°C"
		tempK = string.format("%5.2f", tempK).." K"
	end --# if tempF == "" then
	return tempF,tempC,tempK
end --# function convertTemp(tempF)

function selectForecastIcon(iconString,isNight)
	local imageNumber = nil
	if string.find(iconString, "Freezing Drizzle") ~= nil then
		imageNumber = "5"
	elseif string.find(iconString, "Drizzle") ~= nil then
		imageNumber = "11"
	elseif string.find(iconString, "Thunderstorms and Rain") ~= nil then
		if isNight == true then
			imageNumber = "47"
		else
			imageNumber = "38"
		end --# if isNight == True then
	elseif string.find(iconString, "Thunderstorms and Snow") ~= nil then
		if isNight == true then
			imageNumber = "47"
		else
			imageNumber = "38"
		end --# if isNight == True then
	elseif string.find(iconString, "Thunderstorms and Ice Pellets") ~= nil then
		if isNight == true then
			imageNumber = "47"
		else
			imageNumber = "38"
		end --# if isNight == True then
	elseif string.find(iconString, "Thunderstorms with Hail") ~= nil then
		if isNight == true then
			imageNumber = "47"
		else
			imageNumber = "38"
		end --# if isNight == True then
	elseif string.find(iconString, "Thunderstorms with Small Hail") ~= nil then
		if isNight == true then
			imageNumber = "47"
		else
			imageNumber = "38"
		end --# if isNight == True then
	elseif string.find(iconString, "Thunderstorm") ~= nil then
		if isNight == true then
			imageNumber = "47"
		else
			imageNumber = "38"
		end --# if isNight == True then
	elseif string.find(iconString, "Rain Mist") ~= nil then
		if isNight == true then
			imageNumber = "45"
		else
			imageNumber = "39"
		end --# if isNight == True then
	elseif string.find(iconString, "Light Rain") ~= nil then
		if isNight == true then
			imageNumber = "45"
		else
			imageNumber = "39"
		end --# if isNight == True then
	elseif string.find(iconString, "Freezing Rain") ~= nil then
		imageNumber = "5"
	elseif string.find(iconString, "Rain Showers") ~= nil then
		if isNight == true then
			imageNumber = "45"
		else
			imageNumber = "39"
		end --# if isNight == True then
	elseif string.find(iconString, "Rain") ~= nil then
		if isNight == true then
			imageNumber = "45"
		else
			imageNumber = "39"
		end --# if isNight == True then
	elseif string.find(iconString, "Snow Grains") ~= nil then
		imageNumber = "18"
	elseif string.find(iconString, "Rain Showers") ~= nil then
		if isNight == true then
			imageNumber = "45"
		else
			imageNumber = "39"
		end --# if isNight == True then
	elseif string.find(iconString, "Snow") ~= nil then
		if isNight == true then
			imageNumber = "46"
		else
			imageNumber = "41"
		end --# if isNight == True then
	elseif string.find(iconString, "Ice Crystals") ~= nil then
		imageNumber = "18"
	elseif string.find(iconString, "Ice Pellet Showers") ~= nil then
		imageNumber = "6"
	elseif string.find(iconString, "Ice Pellets") ~= nil then
		imageNumber = "6"
	elseif string.find(iconString, "Small Hail Showers") ~= nil then
		imageNumber = "6"
	elseif string.find(iconString, "Hail Showers") ~= nil then
		imageNumber = "6"
	elseif string.find(iconString, "Hail") ~= nil then
		imageNumber = "6"
	elseif string.find(iconString, "Mist") ~= nil then
		imageNumber = "20"
	elseif string.find(iconString, "Freezing Fog") ~= nil then
		imageNumber = "20"
	elseif string.find(iconString, "Fog") ~= nil then
		imageNumber = "20"
	elseif string.find(iconString, "Smoke") ~= nil then
		imageNumber = "22"
	elseif string.find(iconString, "Volcanic Ash") ~= nil then
		imageNumber = "22"
	elseif string.find(iconString, "Widespread Dust") ~= nil then
		imageNumber = "19"
	elseif string.find(iconString, "Sand") ~= nil then
		imageNumber = "21"
	elseif string.find(iconString, "Haze") ~= nil then
		imageNumber = "19"
	elseif string.find(iconString, "Spray") ~= nil then
		imageNumber = "9"
	elseif string.find(iconString, "Dust Whirls") ~= nil then
		imageNumber = "19"
	elseif string.find(iconString, "Sandstorm") ~= nil then
		imageNumber = "21"
	elseif string.find(iconString, "Low Drifting Snow") ~= nil then
		imageNumber = "15"
	elseif string.find(iconString, "Low Drifting Widespread Dust") ~= nil then
		imageNumber = "19"
	elseif string.find(iconString, "Low Drifting Sand") ~= nil then
		imageNumber = "21"
	elseif string.find(iconString, "Blowing Snow") ~= nil then
		imageNumber = "15"
	elseif string.find(iconString, "Blowing Widespread Dust") ~= nil then
		imageNumber = "19"
	elseif string.find(iconString, "Blowing Sand") ~= nil then
		imageNumber = "21"
	elseif string.find(iconString, "Overcast") ~= nil then
		imageNumber = "26"
	elseif string.find(iconString, "Clear") ~= nil then
		if isNight == true then
			imageNumber = "31"
		else
			imageNumber = "32"
		end --# if isNight == True then
	elseif string.find(iconString, "Partly Cloudy") ~= nil then
		if isNight == true then
			imageNumber = "29"
		else
			imageNumber = "30"
		end --# if isNight == True then
	elseif string.find(iconString, "Mostly Cloudy") ~= nil then
		if isNight == true then
			imageNumber = "27"
		else
			imageNumber = "28"
		end --# if isNight == True then
	elseif string.find(iconString, "Scattered Clouds") ~= nil then
		if isNight == true then
			imageNumber = "33"
		else
			imageNumber = "34"
		end --# if isNight == True then
	else
		imageNumber = "44"
	end --#if string.find(iconString, "Freezing Drizzle") ~= nil then
	return imageNumber
end --# function selectForecastIcon(iconString,isNight)

function convertMoonPhase(percentIlluminated,moonState) --# convert moonState and percentIlluminated to the moonPhase string and deterimine the proper moon image to use
	local moonPhase = nil
	local moonImage = nil
	local lowPercent = nil
	local highPercent = nil
	if percentIlluminated == 0 then
		moonPhase = 'New Moon'
		moonImage = "24.png"
		moonState = "false" --# set moonState to false (new moon)
		local f = io.open((logDirectory.."/moonStateBackup.txt"), "w")
		f:write(moonState)
		f:close()
		f = nil
	elseif percentIlluminated == 100 then
		moonPhase = 'Full Moon'
		moonImage = "13.png"
		moonState = "true" --# set moonState to True (full moon)
		local f = io.open((logDirectory.."/moonStateBackup.txt"), "w")
		f:write(moonState)
		f:close()
		f = nil
	elseif moonState == "false" then
		if percentIlluminated < 50 then
			moonPhase = 'Waxing Crescent'
			lowPercent = -8
			for i = 1 , 7 do
				lowPercent = lowPercent + 8
				highPercent = lowPercent + 10
				if ((percentIlluminated > lowPercent) and (percentIlluminated < highPercent)) then
					moonImage = "0"..tonumber(i)..".png"
					break
				end --# if ((percentIlluminated > lowPercent) and (percentIlluminated < highPercent)) then
			end --#	for i = 1 , 7 do 
		elseif percentIlluminated == 50 then 
			moonPhase = 'First Quarter'
			moonImage = "07.png"
		elseif percentIlluminated < 100 then	
			moonPhase = 'Waxing Gibbous'
			if ((percentIlluminated > 50) and (percentIlluminated < 61)) then --# 51-60
				moonImage = '08.png'
			elseif ((percentIlluminated > 60) and (percentIlluminated < 71)) then --# 61-70
				moonImage = '09.png'
			elseif ((percentIlluminated > 70) and (percentIlluminated < 81)) then --# 71-80
				moonImage = '10.png'
			elseif ((percentIlluminated > 80) and (percentIlluminated < 91)) then --# 81-90
				moonImage = '11.png'
			elseif ((percentIlluminated > 90) and (percentIlluminated < 100)) then --# 91-99
				moonImage = '12.png'
			end --# if ((percentIlluminated > 50) and (percentIlluminated < 61)) then --# 51-60
		end --# if percentIlluminated < 50 then
	elseif moonState == "true" then
		if percentIlluminated < 50 then
			moonPhase = 'Waning Crescent'
			if ((percentIlluminated < 50) and (percentIlluminated > 36)) then --# 49-37
				moonImage = '20.png'
			elseif ((percentIlluminated < 37) and (percentIlluminated > 24)) then --# 36-25
				moonImage = '21.png'
			elseif ((percentIlluminated < 25) and (percentIlluminated > 12)) then --# 24-13
				moonImage = '22.png'
			elseif ((percentIlluminated < 13) and (percentIlluminated > 0)) then --# 12-1
				moonImage = '23.png'
			end --# if ((percentIlluminated < 50) and (percentIlluminated > 36)) then --# 49-37
		elseif percentIlluminated == 50 then
			moonPhase = 'Last Quarter'
			moonImage = '19.png'			
		elseif percentIlluminated < 100 then
			moonPhase = 'Waning Gibbous'
			if ((percentIlluminated < 100) and (percentIlluminated > 90)) then --# 99-91
				moonImage = '14.png'
			elseif ((percentIlluminated < 91) and (percentIlluminated > 80)) then --# 90-81
				moonImage = '15.png'
			elseif ((percentIlluminated < 81) and (percentIlluminated > 70)) then --# 80-71
				moonImage = '16.png'
			elseif ((percentIlluminated < 71) and (percentIlluminated > 60)) then --# 70-61
				moonImage = '17.png'
			elseif ((percentIlluminated < 61) and (percentIlluminated > 50)) then --# 60-51
				moonImage = '18.png'
			end --#	if ((percentIlluminated < 100) and (percentIlluminated > 90)) then --# 99-91	
		end --# if percentIlluminated < 50 then
	else --# prevents crash if non-vaild data is given as input
		moonPhase = "N/A"
		moonImage = "24.png"
	end --# if percentIlluminated == 0 then
	local moonImagePath = moonImageLocation.."/"..moonImage
	return moonPhase,moonImagePath	
end --#	function convertMoonPhase(percentIlluminated,moonState)

Yes I know, I'm an idiot!   :8  If there's no need to post all that code, my apologies in advance...


Proud user of VSDIO: Jedi!  You can download it from here...  I'm on  the web at NixNut.com!

Offline

#116 2015-02-16 14:12:38

arclance
#! Die Hard
Registered: 2012-03-29
Posts: 987

Re: arclances conky weather script - v6.2.1

Try changing

WU_API_URL = ('https://api.wunderground.com/api/' + APIKEY + "/" + infoString + "/bestfct:" + str(forecastSource) + "/pws:" + str(usePersonalStations) + "/q/" + location + ".json") # make the url request string

to

WU_API_URL = ('https://apissl.wunderground.com/api/' + APIKEY + "/" + infoString + "/bestfct:" + str(forecastSource) + "/pws:" + str(usePersonalStations) + "/q/" + location + ".json") # make the url request string

Sometimes there are problems with the caching server used by the first address and using the second one can fix that problem.

Offline

#117 2015-02-16 16:20:55

jed
#! CrunchBanger
From: Detachment 7
Registered: 2012-08-28
Posts: 200
Website

Re: arclances conky weather script - v6.2.1

arclance wrote:

Sometimes there are problems with the caching server used by the first address and using the second one can fix that problem.

Mr. arclance, sir you are a scholar and a gentleman!  Changing those three letters worked immediately.  big_smile

We've been going through some mind blowing weather here in the New England area, and your script is really thorough when it comes to up-to-date info including the radar and satellite images.

Anyway, thank you very much that definitely solved it.  It is much appreciated...  cool


Proud user of VSDIO: Jedi!  You can download it from here...  I'm on  the web at NixNut.com!

Offline

#118 2015-03-13 22:11:15

garpu
New Member
Registered: 2015-03-13
Posts: 8

Re: arclances conky weather script - v6.2.1

So I'm starting conky after configuring everything and I'm getting:

Conky: /home/me/src/conkyWeather_arclance_v6.2.1_2012-09-26/conkyrc_conkyWeather_arclance: 59: no such configuration: 'imlib_cache_size'
Conky: /home/me/src/conkyWeather_arclance_v6.2.1_2012-09-26/conkyrc_conkyWeather_arclance: 63: no such configuration: 'lua_load'
Conky: /home/me/src/conkyWeather_arclance_v6.2.1_2012-09-26/conkyrc_conkyWeather_arclance: 64: no such configuration: 'lua_draw_hook_pre'
Conky: /home/me/src/conkyWeather_arclance_v6.2.1_2012-09-26/conkyrc_conkyWeather_arclance: 65: no such configuration: 'lua_startup_hook'
Conky: /home/me/src/conkyWeather_arclance_v6.2.1_2012-09-26/conkyrc_conkyWeather_arclance: 66: no such configuration: 'lua_shutdown_hook'

Did I forget to configure something I should've?

Offline

#119 2015-03-14 12:58:42

garpu
New Member
Registered: 2015-03-13
Posts: 8

Re: arclances conky weather script - v6.2.1

OK, figured out my problem in post #118, but now I'm getting:

Conky: llua_load: /usr/share/lua/5.1/json/decode.lua:5: module 'lpeg' not found:
        no field package.preload['lpeg']
        no file './lpeg.lua'
        no file '/usr/share/lua/5.1/lpeg.lua'
        no file '/usr/share/lua/5.1/lpeg/init.lua'
        no file '/usr/lib64/lua/5.1/lpeg.lua'
        no file '/usr/lib64/lua/5.1/lpeg/init.lua'
        no file '/usr/lib64/conky/liblpeg.so'
        no file './lpeg.so'
        no file '/usr/lib64/lua/5.1/lpeg.so'
        no file '/usr/lib64/lua/5.1/loadall.so'

lpeg is installed.  (Via luarocks, as detailed in post 100.)  I've got lpeg 0.12-1 and luajson 1.3.3-1 installed.

Offline

#120 2015-03-15 04:17:26

arclance
#! Die Hard
Registered: 2012-03-29
Posts: 987

Re: arclances conky weather script - v6.2.1

If you are using Debian the lua-json package has been updated in testing and unstable so you don't need to use luarocks anymore.

If that does not apply to you without access to your system I can't say what your problem is for sure since diagnosing these types of dependency problems is hard to diagnose remotely.
You should make sure luarocks installed lua-lpeg and lua-json for Lua 5.1 and not Lua 5.2 or Lua 5.3 though.

Offline

#121 2015-07-17 02:14:34

jed
#! CrunchBanger
From: Detachment 7
Registered: 2012-08-28
Posts: 200
Website

Re: arclances conky weather script - v6.2.1

Hey arclance, hope this finds you well.  A new development with the advent of Conky 1.10.x
I have converted the conkyrc to the new syntax of Conky 1.10.x.  I also still have my original created by you.  Both conkyrc files result in the following error;

jedi@NixNut:~/Conky/Weather$ conky -c arclanceconkyrc &
[1] 10862
jedi@NixNut:~/Conky/Weather$ installDirectory = /home/jedi/Conky/Weather
conkyWeather_arclance_v6.2
true
conky: desktop window (289) is root window
X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  1 (X_CreateWindow)
  Value in failed request:  0x0
  Serial number of failed request:  468
  Current serial number in output stream:  473

I'm wondering if this is a result of running Fluxbox and how it interacts with X. (the new version of Conky)  Any advice appreciated.  I've grown quite fond of this particular weather program...

P.S. No code was changed from the original work you created.  The python script runs perfectly and without errors.


Proud user of VSDIO: Jedi!  You can download it from here...  I'm on  the web at NixNut.com!

Offline

#122 2015-07-17 02:54:46

arclance
#! Die Hard
Registered: 2012-03-29
Posts: 987

Re: arclances conky weather script - v6.2.1

It has nothing to do with Fluxbox that is what I use myself.
screenshot_2013_08_03_10_33_53_3840x1080_by_arclance-d6gga7o.png
I have actually been using what became Conky v1.10.x (the Master Branch) for several years now (the ${top X} stuff did not leak memory when called from Lua like v1.9.x did and probably still does) so I have my own .conkyrc for it.

--#####
--# conky configuration for conkyWeather_arclance_lua_v6.0 by arclance
--# displays weather data and images
--#####
conky.config = {
    alignment = "bottom_left",
    gap_x = 622, --# 622
    gap_y = 31, --# 31
    minimum_width = 1057,
    minimum_height = 270,
    maximum_width = 1057,
    border_inner_margin = 0,
    border_outer_margin = 0,
    border_width = 1,
    draw_borders = false,
    draw_graph_borders = true,
    draw_outline = false,
    draw_shades = false,
    own_window = true,
    own_window_transparent = true,
    --# argb transparency
    --own_window_argb_visual = false,
    --own_window_argb_value = 0,
    --# window type settings
    own_window_class = "conky",
    own_window_type = "normal",
    own_window_title = "weatherConky",
    own_window_hints = "undecorated,below,sticky,skip_taskbar,skip_pager",
    --# colors
    default_color = "CC9900",
    default_outline_color = "000000",
    default_shade_color = "8B0000",
    color0 = "EE7600",
    color1 = "8B0000",
    --# font
    use_xft = true,
    xftalpha = 1,
    font = "DejaVu Sans Mono:size=10",
    disable_auto_reload = false,
    double_buffer = true,
    background = false,
    update_interval = 1.0,
    cpu_avg_samples = 1,
    net_avg_samples = 1,
    diskio_avg_samples = 1,
    no_buffers = true,
    out_to_console = false,
    out_to_stderr = false,
    extra_newline = false,
    uppercase = false,
    use_spacer = "none",
    show_graph_scale = false,
    show_graph_range = false,
    text_buffer_size = 1000,
    default_bar_width = 350,
    default_bar_height = 6,
    imlib_cache_size = 0,
    top_name_width = 10,
    if_up_strictness = "address",
    --max_specials = 1000,
    lua_load = "",
    lua_draw_hook_pre = "main",
    lua_startup_hook = "start_xdotool",
    lua_shutdown_hook = "stop_xdotool"
}

conky.text = [[
]]

I believe the problem you have is one I ran into and reported two years ago.
The problem is that border_width cannot equal 0 the new version (it worked in the old version) or Conky tries to create a 0x0 size window at startup which is not possible in the X windows system.
The solution is to use

border_width = 1

instead of

border_width = 0

I don't know if the current version of conky in the Master branch (what was released as 1.10.x) is really usable for most people yet.
I know a lot of changes (many fixes and improvements) that went into 1.9.x did not go into the Master branch.
I would only use it for now if you have problems with v1.9.1 like I did and that problem only affected people calling ${top x} objects from inside Lua scripts.

The weather script should be compatible with v1.10.x as long as you build it against Lua 5.1 (the weather script should not be compatible with Lua 5.2 or 5.3 from what I have read about them.)
I don't know for sure if it will work since I have not had a need to update my conky since May 2013.
Not much happened to the Master Branch until this year and I do everything in Lua so I wrote replacements for missing features (${if_running}) I ran into.

Last edited by arclance (2015-07-17 03:22:44)

Offline

#123 2015-07-17 03:24:08

jed
#! CrunchBanger
From: Detachment 7
Registered: 2012-08-28
Posts: 200
Website

Re: arclances conky weather script - v6.2.1

Very nice!  @arclance, you're the best!  Just copied your conkyrc and am back to normal.  There were several differences between our conkyrc files.  I am going to study on mine to see what I had done wrong besides the 'border_width = 0' issue.  Your conkyrc posted above has several variables that mine did not have.  Thankfully you've been using this new version for a long time.  I'm using VSIDO (VastOne's distro based on Sid) and in doing a dist-upgrade a few weeks back, I upgraded Conky.  Too stubborn to roll it back, so thanks for the help!  AGAIN!!! You always come through!   smile

Last edited by jed (2015-07-17 03:45:50)


Proud user of VSDIO: Jedi!  You can download it from here...  I'm on  the web at NixNut.com!

Offline

#124 2015-07-17 03:44:37

arclance
#! Die Hard
Registered: 2012-03-29
Posts: 987

Re: arclances conky weather script - v6.2.1

There is probably some stuff left over from my generic .conkyrc I use on my systems.
I remove some things when I make the generic .conkyrc for releases so the things not in your .conkyrc probably don't matter.
It has been two years since I converted that .conkyrc and I may have forgotten something so I can't be sure though.

For example you don't really need "draw_graph_borders = true," because there are no graphs in the weather script.
It is a default leftover from when I used to use the graphs in conky and not the ones written in Lua I use now.

Last edited by arclance (2015-07-17 03:49:37)

Offline

Help fund CrunchBang, donate to the project!

#125 2015-07-17 03:59:16

jed
#! CrunchBanger
From: Detachment 7
Registered: 2012-08-28
Posts: 200
Website

Re: arclances conky weather script - v6.2.1

Had never saw the two below;

top_name_width = 10,
if_up_strictness = "address",

I've learned so much about Conky and LUA from you over the last 3 years that my forehead is now taller!!!  (actually that is probably due more to being 50 than anything else...)  8.(


Proud user of VSDIO: Jedi!  You can download it from here...  I'm on  the web at NixNut.com!

Offline

Board footer

Powered by FluxBB

Copyright © 2012 CrunchBang Linux.
Proudly powered by Debian. Hosted by Linode.
Debian is a registered trademark of Software in the Public Interest, Inc.
Server: acrobat

Debian Logo