diff --git a/Main.gd b/Main.gd
index d8d9c38..f280e65 100644
--- a/Main.gd
+++ b/Main.gd
@@ -1,5 +1,6 @@
extends Node
+#Variables
var city
var state
var stateCode
@@ -23,63 +24,103 @@ var AlertBase = "https://api.weather.gov/alerts/active/zone/"
var ActiveAlertURL
var Alerts
var AlertCount
+var EPAKey
+var EPABaseURL = "https://www.airnowapi.org/"
+var EPAObsURL = "aq/observation/zipCode/current/?format=application/json&zipCode="
+var EPADist = "&distance=50"
+var EPAAPIKey = "&API_KEY="
func _ready():
print("Program Starting")
+ #Set Alert Display to be invisble
$GUI/AlertDisplay.visible = false
+ #Show Forecasts Page
$GUI/Forecasts.visible = true
+ #More alert stuff. Invisible to start.
$GUI/Forecasts/Window/NowCast/Alert.visible = false
+ #Hide server failure message at start.
+ $GUI/ServerFailure.visible = false
+ #Hide Settings Menu
+ $GUI/Settings.visible = false
+ #Hide Air Quality Page
+ $GUI/AirQuality.visible = false
findLocation()
+ #Loads Settings
+ LoadSettings()
func findLocation():
+ #Request location data from the ip-api API
print("Finding Location...")
$NetworkController/Location.request(GeoAPI)
func _on_Location_request_completed(result, response_code, headers, body):
+ #ip-api response.
print("Location Found.")
var json = JSON.parse(body.get_string_from_utf8())
- city = json.result.city
- state = json.result.regionName
- stateCode = json.result.region
- zipCode = json.result.zip
- lat = json.result.lat
- long = json.result.lon
- #lat = 33.4025 #For Testing.
- #long = -84.522 #For Testing
- fullURL = str(baseURL, lat, ",", long)
- CityState = str(city," ",state)
- $GUI/Forecasts/Window/Header/Location.text = String(CityState)
- print("Lat:")
- print(lat)
- print("Long:")
- print(long)
- print("Full URL:")
- print(fullURL)
- print("Fetching Forecast URLs...")
- getGridPoints()
+ print(json.result.status)
+ #Validate return data
+ if json.result.status == "success":
+ #If a request is successful, do this:
+ city = json.result.city
+ state = json.result.regionName
+ stateCode = json.result.region
+ zipCode = json.result.zip
+ lat = json.result.lat
+ long = json.result.lon
+ #lat = 33.4025 #For Testing.
+ #long = -84.522 #For Testing
+ fullURL = str(baseURL, lat, ",", long)
+ CityState = str(city," ",state)
+ $GUI/Forecasts/Window/Header/Location.text = String(CityState)
+ print("Lat:")
+ print(lat)
+ print("Long:")
+ print(long)
+ print("Full URL:")
+ print(fullURL)
+ print("Fetching Forecast URLs...")
+ getGridPoints()
+ else:
+ print("Location API Server Failure")
+ #Otherwise, display server failure screen
+ $GUI/Forecasts.visible = false
+ $GUI/AlertDisplay.visible = false
+ $GUI/ServerFailure.visible = true
+ $GUI/ServerFailure/Body/Response.text = json.result.status
func getGridPoints():
+ #Find NWS gridpoints using the ip-api data
$NetworkController/Forecast.request(fullURL)
func _on_Forecast_request_completed(result, response_code, headers, body):
print("Forecast URLs Returned.")
var GPjson = JSON.parse(body.get_string_from_utf8())
- ForecastURL = GPjson.result.properties.forecast
- HForecastURL = GPjson.result.properties.forecastHourly
- CatForecastURL = str(ForecastURL,ImpUnits)
- ZoneURL = GPjson.result.properties.county
- print("Forecast URL:")
- print(ForecastURL)
- print("Hourly URL:")
- print(HForecastURL)
- print("Full Weekly URL:")
- print(CatForecastURL)
- print("Zone URL:")
- print(ZoneURL)
- print("Getting Weekly Forecast")
- getHourlyForecast()
- getWeeklyForecast()
- getZoneID()
+ #Validate return data
+ if response_code == 200:
+ #Build URLs needed for forecast requests
+ ForecastURL = GPjson.result.properties.forecast
+ HForecastURL = GPjson.result.properties.forecastHourly
+ CatForecastURL = str(ForecastURL,ImpUnits)
+ ZoneURL = GPjson.result.properties.county
+ print("Forecast URL:")
+ print(ForecastURL)
+ print("Hourly URL:")
+ print(HForecastURL)
+ print("Full Weekly URL:")
+ print(CatForecastURL)
+ print("Zone URL:")
+ print(ZoneURL)
+ print("Getting Weekly Forecast")
+ getHourlyForecast()
+ getWeeklyForecast()
+ getZoneID()
+ else:
+ print("Forecast URL Server Error")
+ #Display server failure page
+ $GUI/Forecasts.visible = false
+ $GUI/AlertDisplay.visible = false
+ $GUI/ServerFailure.visible = true
+ $GUI/ServerFailure/Body/Response.text = String(response_code)
func getHourlyForecast():
$NetworkController/HoulyForecast.request(HForecastURL)
@@ -92,31 +133,59 @@ func getZoneID():
func _on_HoulyForecast_request_completed(result, response_code, headers, body):
var HourlyForecastJSON = JSON.parse(body.get_string_from_utf8())
- HourlyForecastResult = HourlyForecastJSON.result.properties.periods
- PrintHourlyResults()
+ if response_code == 200:
+ HourlyForecastResult = HourlyForecastJSON.result.properties.periods
+ PrintHourlyResults()
+ else:
+ print("Hourly Forecast Server Failure")
+ $GUI/Forecasts.visible = false
+ $GUI/AlertDisplay.visible = false
+ $GUI/ServerFailure.visible = true
+ $GUI/ServerFailure/Body/Response.text = String(response_code)
func _on_WeeklyForecast_request_completed(result, response_code, headers, body):
var WeeklyForecastJSON = JSON.parse(body.get_string_from_utf8())
- WeeklyForecastResult = WeeklyForecastJSON.result.properties.periods
- PrintWeeklyResults()
+ if response_code == 200:
+ WeeklyForecastResult = WeeklyForecastJSON.result.properties.periods
+ PrintWeeklyResults()
+ else:
+ print("Weekly Forecast Server Failure")
+ $GUI/Forecasts.visible = false
+ $GUI/AlertDisplay.visible = false
+ $GUI/ServerFailure.visible = true
+ $GUI/ServerFailure/Body/Response.text = String(response_code)
func _on_ZoneIDRequest_request_completed(result, response_code, headers, body):
var ZoneIDRequestResult = JSON.parse(body.get_string_from_utf8())
- ZoneID = ZoneIDRequestResult.result.properties.id
- ActiveAlertURL = str(AlertBase,ZoneID)
- print("ZoneID:")
- print(ZoneID)
- print("Active Alerts URL:")
- print(ActiveAlertURL)
- getAlerts()
+ if response_code == 200:
+ ZoneID = ZoneIDRequestResult.result.properties.id
+ ActiveAlertURL = str(AlertBase,ZoneID)
+ print("ZoneID:")
+ print(ZoneID)
+ print("Active Alerts URL:")
+ print(ActiveAlertURL)
+ getAlerts()
+ else:
+ print("Zone ID Request Server Failure")
+ $GUI/Forecasts.visible = false
+ $GUI/AlertDisplay.visible = false
+ $GUI/ServerFailure.visible = true
+ $GUI/ServerFailure/Body/Response.text = String(response_code)
func getAlerts():
$NetworkController/AlertRequest.request(ActiveAlertURL)
func _on_AlertRequest_request_completed(result, response_code, headers, body):
var AlertJSON = JSON.parse(body.get_string_from_utf8())
- Alerts = AlertJSON.result.features
- AlertHandler()
+ if response_code == 200:
+ Alerts = AlertJSON.result.features
+ AlertHandler()
+ else:
+ print("Alert Request Server Failure")
+ $GUI/Forecasts.visible = false
+ $GUI/AlertDisplay.visible = false
+ $GUI/ServerFailure.visible = true
+ $GUI/ServerFailure/Body/Response.text = String(response_code)
func AlertHandler():
var AlertNumberUpdate
@@ -152,12 +221,12 @@ func alertProcessing():
for number in range(i):
#Make Instance
- print("Loop:", Counter)
+ #print("Loop:", Counter)
var NewInstance = scene.instance()
NewInstance.name = "AlertInfo" + String(Counter)
path.add_child(NewInstance)
- print("New Instance Name:")
- print(NewInstance.name)
+ #print("New Instance Name:")
+ #print(NewInstance.name)
NewInstance.get_node("Intro/AlertNum").text = String(AlertNumber)
NewInstance.get_node("Headline/HLabel").text = String(Alerts[Counter].properties.headline)
NewInstance.get_node("AlertInfo1/A1Status").text = String(Alerts[Counter].properties.severity)
@@ -194,7 +263,7 @@ func PrintHourlyResults():
$GUI/Forecasts/Window/NowCast/NowWind/WindSpeed.text = String(HourlyForecastResult[0].windSpeed)
$GUI/Forecasts/Window/NowCast/NowWind/Direction.text = String(HourlyForecastResult[0].windDirection)
$GUI/Forecasts/Window/NowCast/ShortCast.text = String(HourlyForecastResult[0].shortForecast)
- #Hourly Forecast for Next 24 Hours
+ #Hourly Forecast for Next 155 Hours
var Counter = 1
var HourlyCount = HourlyForecastResult.size()
var scene = ResourceLoader.load("res://T0.tscn")
@@ -205,14 +274,14 @@ func PrintHourlyResults():
print(HourlyCount)
print(Counter)
- for number in range(23):
- print("Loop:", Counter)
+ for number in range(155):
+ #print("Loop:", Counter)
var NewInstance = scene.instance()
var vInst = SepScene.instance()
NewInstance.name = "T" + String(Counter)
path.add_child(NewInstance)
- print("New Instance Name:")
- print(NewInstance.name)
+ #print("New Instance Name:")
+ #print(NewInstance.name)
#Handle Time
var DateTime = HourlyForecastResult[Counter].startTime
var Date = DateTime.split("T")[0].split("-")
@@ -245,7 +314,106 @@ func PrintHourlyResults():
path.add_child(vInst)
Counter = Counter + 1
+func _on_CloseApp_pressed():
+ get_tree().quit()
+#Settings
+func SaveSettings():
+ #Save User Settings
+ var file = File.new()
+ file.open("user://MiniWeatherSettings.dat", File.WRITE)
+ file.store_var(EPAKey)
+ file.close()
+
+func LoadSettings():
+ #Load User Settings
+ var file = File.new()
+ file.open("user://MiniWeatherSettings.dat", File.READ)
+ EPAKey = file.get_var()
+ file.close()
+ $GUI/Settings/Body/EPAKey/LineEdit.text = EPAKey
+
+func _on_Settings_pressed():
+ #Hide Everything, then show Settings page
+ $GUI/Forecasts.visible = false
+ $GUI/AlertDisplay.visible = false
+ $GUI/Settings.visible = true
+
+func _on_LineEdit_text_changed(new_text):
+ EPAKey = new_text
+ print("New Text:")
+ print(EPAKey)
+
+func _on_Return_pressed():
+ SaveSettings()
+ $GUI/Settings.visible = false
+ $GUI/Forecasts.visible = true
+
+#Air Quality
+func _on_AirQuality_pressed():
+ #Hide Everything
+ $GUI/AlertDisplay.visible = false
+ $GUI/Forecasts.visible = false
+ #Show Air Quality Page
+ $GUI/AirQuality.visible = true
+ EPAQuery()
+
+func EPAQuery():
+ #Cat EPA API URL Request
+ var EPAFullURL = str(EPABaseURL,EPAObsURL,zipCode,EPADist,EPAAPIKey,EPAKey)
+ print("Full EPA API URL:")
+ print(EPAFullURL)
+ $NetworkController/EPAReq.request(EPAFullURL)
+
+func _on_EPAReq_request_completed(result, response_code, headers, body):
+ var EPAResult = JSON.parse(body.get_string_from_utf8())
+ if response_code == 200:
+ var EPAJson = EPAResult.result
+ print(EPAJson)
+ $GUI/AirQuality/Body/DateTimeObs/Date.text = String(EPAJson[0].DateObserved)
+ $GUI/AirQuality/Body/DateTimeObs/Time.text = String(EPAJson[0].HourObserved)
+ $GUI/AirQuality/Body/DateTimeObs/TimeZone.text = String(EPAJson[0].LocalTimeZone)
+ $GUI/AirQuality/Body/Values/AQIValue/AQI2.text = String(EPAJson[0].AQI)
+ $GUI/AirQuality/Body/Values/CatNumVal/CatNumber2.text = String(EPAJson[0].Category.Number)
+ $GUI/AirQuality/Body/Values/CatNumVal/CatName.text = String(EPAJson[0].Category.Name)
+ #Modulate CatName Color
+ if EPAJson[0].Category.Number == 1:
+ $GUI/AirQuality/Body/Values/CatNumVal/CatName.modulate = Color(0,1,0,1)
+ elif EPAJson[0].Category.Number == 2:
+ $GUI/AirQuality/Body/Values/CatNumVal/CatName.modulate = Color(1,1,0,1)
+ elif EPAJson[0].Category.Number == 3:
+ $GUI/AirQuality/Body/Values/CatNumVal/CatName.modulate = Color(1,0.65,0,1)
+ elif EPAJson[0].Category.Number == 4:
+ $GUI/AirQuality/Body/Values/CatNumVal/CatName.modulate = Color(1,0,0,1)
+ elif EPAJson[0].Category.Number == 5:
+ $GUI/AirQuality/Body/Values/CatNumVal/CatName.modulate = Color(0.63,0.13,0.94,1)
+ elif EPAJson[0].Category.Number == 6:
+ $GUI/AirQuality/Body/Values/CatNumVal/CatName.modulate = Color(1,0,1,1)
+ #Convert HourObserved from 24h to 12h
+ var TimeStamp = EPAJson[0].HourObserved
+ if TimeStamp > 12:
+ TimeStamp = TimeStamp - 12
+ $GUI/AirQuality/Body/DateTimeObs/Time.text = String(TimeStamp)
+ $GUI/AirQuality/Body/DateTimeObs/Time3.text = "PM"
+ elif TimeStamp <= 12:
+ $GUI/AirQuality/Body/DateTimeObs/Time.text = String(TimeStamp)
+ $GUI/AirQuality/Body/DateTimeObs/Time3.text = "AM"
+ elif response_code == 401:
+ $GUI/AirQuality.visible = false
+ _on_Settings_pressed()
+ else:
+ print("EPA Request Server Failure")
+ $GUI/Forecasts.visible = false
+ $GUI/AlertDisplay.visible = false
+ $GUI/AirQuality.visible = false
+ $GUI/ServerFailure.visible = true
+ $GUI/ServerFailure/Body/Response.text = String(response_code)
+
+func _on_ReturnAQ_pressed():
+ #Hide Air Quality Page, show Forecasts
+ $GUI/AirQuality.visible = false
+ $GUI/Forecasts.visible = true
+
func PrintWeeklyResults():
$GUI/Forecasts/Window/WeeklyScroll.get_v_scrollbar().modulate = Color(0, 0, 0, 0) #Hide Scroll Bar
$GUI/Forecasts/Window/HourlyScroll.get_h_scrollbar().modulate = Color(0, 0, 0, 0)
diff --git a/Main.tscn b/Main.tscn
index f5311cd..bd94b32 100644
--- a/Main.tscn
+++ b/Main.tscn
@@ -9,16 +9,25 @@ script = ExtResource( 1 )
[node name="NetworkController" type="Node2D" parent="."]
[node name="Location" type="HTTPRequest" parent="NetworkController"]
+use_threads = true
[node name="Forecast" type="HTTPRequest" parent="NetworkController"]
+use_threads = true
[node name="WeeklyForecast" type="HTTPRequest" parent="NetworkController"]
+use_threads = true
[node name="HoulyForecast" type="HTTPRequest" parent="NetworkController"]
+use_threads = true
[node name="AlertRequest" type="HTTPRequest" parent="NetworkController"]
+use_threads = true
[node name="ZoneIDRequest" type="HTTPRequest" parent="NetworkController"]
+use_threads = true
+
+[node name="EPAReq" type="HTTPRequest" parent="NetworkController"]
+use_threads = true
[node name="GUI" type="CanvasLayer" parent="."]
follow_viewport_enable = true
@@ -30,7 +39,7 @@ anchor_bottom = 1.0
[node name="Forecasts" type="MarginContainer" parent="GUI"]
anchor_right = 1.0
anchor_bottom = 1.0
-custom_constants/margin_right = 10
+custom_constants/margin_right = 20
custom_constants/margin_top = 60
custom_constants/margin_left = 10
custom_constants/margin_bottom = 10
@@ -39,7 +48,7 @@ custom_constants/margin_bottom = 10
margin_left = 10.0
margin_top = 60.0
margin_right = 722.0
-margin_bottom = 1130.0
+margin_bottom = 1077.0
[node name="Header" type="VBoxContainer" parent="GUI/Forecasts/Window"]
margin_right = 712.0
@@ -49,7 +58,7 @@ margin_bottom = 60.0
margin_right = 712.0
margin_bottom = 28.0
custom_fonts/font = ExtResource( 2 )
-text = "Weather Forecast for"
+text = "National Weather Service Forecast"
align = 1
[node name="Location" type="Label" parent="GUI/Forecasts/Window/Header"]
@@ -57,7 +66,7 @@ margin_top = 32.0
margin_right = 712.0
margin_bottom = 60.0
custom_fonts/font = ExtResource( 2 )
-text = "CITY, State Location"
+text = "Loading Weather Data..."
align = 1
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window"]
@@ -69,7 +78,7 @@ margin_bottom = 68.0
margin_left = 256.0
margin_top = 72.0
margin_right = 456.0
-margin_bottom = 196.0
+margin_bottom = 227.0
size_flags_horizontal = 4
size_flags_vertical = 0
alignment = 1
@@ -88,16 +97,15 @@ margin_bottom = 60.0
alignment = 1
[node name="Temp" type="Label" parent="GUI/Forecasts/Window/NowCast/NowTemp"]
-margin_left = 77.0
-margin_right = 105.0
+margin_left = 91.0
+margin_right = 91.0
margin_bottom = 28.0
custom_fonts/font = ExtResource( 2 )
-text = "80"
align = 1
[node name="Unit" type="Label" parent="GUI/Forecasts/Window/NowCast/NowTemp"]
-margin_left = 109.0
-margin_right = 122.0
+margin_left = 95.0
+margin_right = 108.0
margin_bottom = 28.0
custom_fonts/font = ExtResource( 2 )
text = "F"
@@ -110,26 +118,24 @@ margin_bottom = 92.0
alignment = 1
[node name="WindSpeed" type="Label" parent="GUI/Forecasts/Window/NowCast/NowWind"]
-margin_left = 49.0
-margin_right = 126.0
+margin_left = 98.0
+margin_right = 98.0
margin_bottom = 28.0
custom_fonts/font = ExtResource( 2 )
-text = "10 mph"
[node name="Direction" type="Label" parent="GUI/Forecasts/Window/NowCast/NowWind"]
-margin_left = 130.0
-margin_right = 151.0
+margin_left = 102.0
+margin_right = 102.0
margin_bottom = 28.0
custom_fonts/font = ExtResource( 2 )
-text = "W"
[node name="ShortCast" type="Label" parent="GUI/Forecasts/Window/NowCast"]
margin_top = 96.0
margin_right = 200.0
-margin_bottom = 124.0
+margin_bottom = 155.0
rect_min_size = Vector2( 200, 25 )
custom_fonts/font = ExtResource( 2 )
-text = "A short forecast"
+text = "Loading... please wait."
align = 1
autowrap = true
@@ -142,14 +148,14 @@ rect_min_size = Vector2( 0, 50 )
text = "Weather Alert"
[node name="HSeparator2" type="HSeparator" parent="GUI/Forecasts/Window"]
-margin_top = 200.0
+margin_top = 231.0
margin_right = 712.0
-margin_bottom = 204.0
+margin_bottom = 235.0
[node name="HourlyScroll" type="ScrollContainer" parent="GUI/Forecasts/Window"]
-margin_top = 208.0
+margin_top = 239.0
margin_right = 712.0
-margin_bottom = 238.0
+margin_bottom = 269.0
rect_min_size = Vector2( 0, 30 )
scroll_vertical_enabled = false
@@ -157,27 +163,27 @@ scroll_vertical_enabled = false
alignment = 1
[node name="HSeparator3" type="HSeparator" parent="GUI/Forecasts/Window"]
-margin_top = 242.0
+margin_top = 273.0
margin_right = 712.0
-margin_bottom = 246.0
+margin_bottom = 277.0
[node name="WeeklyScroll" type="ScrollContainer" parent="GUI/Forecasts/Window"]
-margin_top = 250.0
+margin_top = 281.0
margin_right = 712.0
-margin_bottom = 1070.0
-rect_min_size = Vector2( 0, 820 )
+margin_bottom = 971.0
+rect_min_size = Vector2( 0, 690 )
size_flags_horizontal = 3
size_flags_vertical = 3
scroll_horizontal_enabled = false
[node name="WeekCast" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll"]
margin_right = 700.0
-margin_bottom = 3636.0
+margin_bottom = 1892.0
alignment = 1
[node name="W0" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -231,21 +237,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W0"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W0"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W1" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 260.0
+margin_top = 136.0
margin_right = 700.0
-margin_bottom = 516.0
+margin_bottom = 268.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -299,21 +305,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W1"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W1"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W2" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 520.0
+margin_top = 272.0
margin_right = 700.0
-margin_bottom = 776.0
+margin_bottom = 404.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -367,21 +373,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W2"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W2"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W3" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 780.0
+margin_top = 408.0
margin_right = 700.0
-margin_bottom = 1036.0
+margin_bottom = 540.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -435,21 +441,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W3"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W3"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W4" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 1040.0
+margin_top = 544.0
margin_right = 700.0
-margin_bottom = 1296.0
+margin_bottom = 676.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -503,21 +509,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W4"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W4"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W5" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 1300.0
+margin_top = 680.0
margin_right = 700.0
-margin_bottom = 1556.0
+margin_bottom = 812.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -571,21 +577,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W5"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W5"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W6" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 1560.0
+margin_top = 816.0
margin_right = 700.0
-margin_bottom = 1816.0
+margin_bottom = 948.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -639,21 +645,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W6"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W6"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W7" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 1820.0
+margin_top = 952.0
margin_right = 700.0
-margin_bottom = 2076.0
+margin_bottom = 1084.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -707,21 +713,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W7"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W7"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W8" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 2080.0
+margin_top = 1088.0
margin_right = 700.0
-margin_bottom = 2336.0
+margin_bottom = 1220.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -775,21 +781,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W8"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W8"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W9" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 2340.0
+margin_top = 1224.0
margin_right = 700.0
-margin_bottom = 2596.0
+margin_bottom = 1356.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -843,21 +849,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W9"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W9"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W10" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 2600.0
+margin_top = 1360.0
margin_right = 700.0
-margin_bottom = 2856.0
+margin_bottom = 1492.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -911,21 +917,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W10"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W10"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W11" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 2860.0
+margin_top = 1496.0
margin_right = 700.0
-margin_bottom = 3116.0
+margin_bottom = 1628.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -979,21 +985,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W11"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W11"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W12" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 3120.0
+margin_top = 1632.0
margin_right = 700.0
-margin_bottom = 3376.0
+margin_bottom = 1764.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -1047,21 +1053,21 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W12"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W12"]
-margin_top = 252.0
+margin_top = 128.0
margin_right = 700.0
-margin_bottom = 256.0
+margin_bottom = 132.0
[node name="W13" type="VBoxContainer" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast"]
-margin_top = 3380.0
+margin_top = 1768.0
margin_right = 700.0
-margin_bottom = 3636.0
+margin_bottom = 1892.0
rect_min_size = Vector2( 700, 0 )
alignment = 1
@@ -1115,16 +1121,37 @@ text = "W"
[node name="Forecast" type="Label" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W13"]
margin_top = 96.0
margin_right = 700.0
-margin_bottom = 248.0
+margin_bottom = 124.0
custom_fonts/font = ExtResource( 2 )
-text = "A chance of rain showers between 8am and 2pm, then showers and thunderstorms likely. Mostly sunny. High near 94, with temperatures falling to around 86 in the afternoon. West wind 1 to 5 mph. Chance of precipitation is 60%. New rainfall amounts between a quarter and half of an inch possible."
+text = "Loading... please wait."
align = 1
autowrap = true
-[node name="HSeparator" type="HSeparator" parent="GUI/Forecasts/Window/WeeklyScroll/WeekCast/W13"]
-margin_top = 252.0
-margin_right = 700.0
-margin_bottom = 256.0
+[node name="HSeparator4" type="HSeparator" parent="GUI/Forecasts/Window"]
+margin_top = 975.0
+margin_right = 712.0
+margin_bottom = 979.0
+
+[node name="Footer" type="HBoxContainer" parent="GUI/Forecasts/Window"]
+margin_top = 983.0
+margin_right = 712.0
+margin_bottom = 1017.0
+rect_min_size = Vector2( 600, 20 )
+alignment = 1
+
+[node name="AirQuality" type="Button" parent="GUI/Forecasts/Window/Footer"]
+margin_left = 241.0
+margin_right = 365.0
+margin_bottom = 34.0
+custom_fonts/font = ExtResource( 2 )
+text = "Air Quality"
+
+[node name="Settings" type="Button" parent="GUI/Forecasts/Window/Footer"]
+margin_left = 369.0
+margin_right = 471.0
+margin_bottom = 34.0
+custom_fonts/font = ExtResource( 2 )
+text = "Settings"
[node name="AlertDisplay" type="MarginContainer" parent="GUI"]
visible = false
@@ -1172,11 +1199,271 @@ rect_min_size = Vector2( 0, 50 )
custom_fonts/font = ExtResource( 2 )
text = "Close"
+[node name="ServerFailure" type="MarginContainer" parent="GUI"]
+visible = false
+margin_right = 40.0
+margin_bottom = 40.0
+rect_min_size = Vector2( 720, 1080 )
+custom_constants/margin_top = 60
+
+[node name="Body" type="VBoxContainer" parent="GUI/ServerFailure"]
+margin_top = 60.0
+margin_right = 720.0
+margin_bottom = 1080.0
+
+[node name="FailMessage" type="Label" parent="GUI/ServerFailure/Body"]
+margin_right = 720.0
+margin_bottom = 31.0
+custom_fonts/font = ExtResource( 2 )
+text = "Server Failure.
+Please try again in a few minutes."
+align = 1
+autowrap = true
+
+[node name="Response" type="Label" parent="GUI/ServerFailure/Body"]
+margin_top = 35.0
+margin_right = 720.0
+margin_bottom = 49.0
+custom_fonts/font = ExtResource( 2 )
+text = "Response Code"
+align = 1
+
+[node name="CloseApp" type="Button" parent="GUI/ServerFailure/Body"]
+margin_top = 53.0
+margin_right = 720.0
+margin_bottom = 73.0
+custom_fonts/font = ExtResource( 2 )
+text = "OK"
+
+[node name="Settings" type="MarginContainer" parent="GUI"]
+visible = false
+anchor_right = 1.0
+anchor_bottom = 1.0
+custom_constants/margin_right = 10
+custom_constants/margin_top = 60
+custom_constants/margin_left = 10
+custom_constants/margin_bottom = 10
+
+[node name="Body" type="VBoxContainer" parent="GUI/Settings"]
+margin_left = 10.0
+margin_top = 60.0
+margin_right = 710.0
+margin_bottom = 1070.0
+
+[node name="Header" type="Label" parent="GUI/Settings/Body"]
+margin_right = 700.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+text = "Settings"
+align = 1
+
+[node name="HSeparator" type="HSeparator" parent="GUI/Settings/Body"]
+margin_top = 32.0
+margin_right = 700.0
+margin_bottom = 36.0
+
+[node name="EPAHead" type="Label" parent="GUI/Settings/Body"]
+margin_top = 40.0
+margin_right = 700.0
+margin_bottom = 68.0
+custom_fonts/font = ExtResource( 2 )
+text = "EPA AirNow API"
+align = 1
+
+[node name="EPAExplain" type="Label" parent="GUI/Settings/Body"]
+margin_top = 72.0
+margin_right = 700.0
+margin_bottom = 193.0
+custom_fonts/font = ExtResource( 2 )
+text = "The Environmental Protection Agency Air Quality Monitoring Program requires an API key to access the data. You can request an API key for free at https://docs.airnowapi.org/account/request/ "
+autowrap = true
+
+[node name="EPAKey" type="HBoxContainer" parent="GUI/Settings/Body"]
+margin_top = 197.0
+margin_right = 700.0
+margin_bottom = 225.0
+alignment = 1
+
+[node name="EPALabel" type="Label" parent="GUI/Settings/Body/EPAKey"]
+margin_left = 140.0
+margin_right = 355.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+text = "EPA AirNow API Key:"
+align = 1
+
+[node name="LineEdit" type="LineEdit" parent="GUI/Settings/Body/EPAKey"]
+margin_left = 359.0
+margin_right = 559.0
+margin_bottom = 28.0
+rect_min_size = Vector2( 200, 20 )
+custom_fonts/font = ExtResource( 2 )
+align = 1
+placeholder_text = "Enter Key Here"
+
+[node name="HSeparator2" type="HSeparator" parent="GUI/Settings/Body"]
+margin_top = 229.0
+margin_right = 700.0
+margin_bottom = 233.0
+
+[node name="Return" type="Button" parent="GUI/Settings/Body"]
+margin_top = 237.0
+margin_right = 700.0
+margin_bottom = 271.0
+custom_fonts/font = ExtResource( 2 )
+text = "Save Settings"
+
+[node name="AirQuality" type="MarginContainer" parent="GUI"]
+visible = false
+anchor_right = 1.0
+anchor_bottom = 1.0
+custom_constants/margin_right = 10
+custom_constants/margin_top = 60
+custom_constants/margin_left = 10
+custom_constants/margin_bottom = 10
+
+[node name="Body" type="VBoxContainer" parent="GUI/AirQuality"]
+margin_left = 10.0
+margin_top = 60.0
+margin_right = 710.0
+margin_bottom = 1070.0
+
+[node name="EPAHead" type="Label" parent="GUI/AirQuality/Body"]
+margin_right = 700.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+text = "Environmental Protection Agency"
+align = 1
+
+[node name="Header" type="Label" parent="GUI/AirQuality/Body"]
+margin_top = 32.0
+margin_right = 700.0
+margin_bottom = 60.0
+custom_fonts/font = ExtResource( 2 )
+text = "Current Air Quality Report"
+align = 1
+
+[node name="HSeparator" type="HSeparator" parent="GUI/AirQuality/Body"]
+margin_top = 64.0
+margin_right = 700.0
+margin_bottom = 68.0
+
+[node name="DateTimeObs" type="HBoxContainer" parent="GUI/AirQuality/Body"]
+margin_top = 72.0
+margin_right = 700.0
+margin_bottom = 100.0
+alignment = 1
+
+[node name="Date" type="Label" parent="GUI/AirQuality/Body/DateTimeObs"]
+margin_left = 286.0
+margin_right = 286.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+
+[node name="Time" type="Label" parent="GUI/AirQuality/Body/DateTimeObs"]
+margin_left = 290.0
+margin_right = 290.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+
+[node name="Time2" type="Label" parent="GUI/AirQuality/Body/DateTimeObs"]
+margin_left = 294.0
+margin_right = 327.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+text = ":00"
+
+[node name="Time3" type="Label" parent="GUI/AirQuality/Body/DateTimeObs"]
+margin_left = 331.0
+margin_right = 409.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+text = "AM/PM"
+
+[node name="TimeZone" type="Label" parent="GUI/AirQuality/Body/DateTimeObs"]
+margin_left = 413.0
+margin_right = 413.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+
+[node name="Values" type="VBoxContainer" parent="GUI/AirQuality/Body"]
+margin_top = 104.0
+margin_right = 700.0
+margin_bottom = 164.0
+alignment = 1
+
+[node name="AQIValue" type="HBoxContainer" parent="GUI/AirQuality/Body/Values"]
+margin_right = 700.0
+margin_bottom = 28.0
+alignment = 1
+
+[node name="AQI" type="Label" parent="GUI/AirQuality/Body/Values/AQIValue"]
+margin_left = 235.0
+margin_right = 416.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+text = "Air Quality Index:"
+
+[node name="AQI2" type="Label" parent="GUI/AirQuality/Body/Values/AQIValue"]
+margin_left = 420.0
+margin_right = 465.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+text = "NaN"
+
+[node name="CatNumVal" type="HBoxContainer" parent="GUI/AirQuality/Body/Values"]
+margin_top = 32.0
+margin_right = 700.0
+margin_bottom = 60.0
+alignment = 1
+
+[node name="CatNumber" type="Label" parent="GUI/AirQuality/Body/Values/CatNumVal"]
+margin_left = 245.0
+margin_right = 340.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+text = "Severity:"
+
+[node name="CatNumber2" type="Label" parent="GUI/AirQuality/Body/Values/CatNumVal"]
+margin_left = 344.0
+margin_right = 389.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+text = "NaN"
+
+[node name="Com" type="Label" parent="GUI/AirQuality/Body/Values/CatNumVal"]
+margin_left = 393.0
+margin_right = 403.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+text = "-"
+
+[node name="CatName" type="Label" parent="GUI/AirQuality/Body/Values/CatNumVal"]
+margin_left = 407.0
+margin_right = 455.0
+margin_bottom = 28.0
+custom_fonts/font = ExtResource( 2 )
+text = "Text"
+
+[node name="ReturnAQ" type="Button" parent="GUI/AirQuality/Body"]
+margin_top = 168.0
+margin_right = 700.0
+margin_bottom = 202.0
+custom_fonts/font = ExtResource( 2 )
+text = "Return"
+
[connection signal="request_completed" from="NetworkController/Location" to="." method="_on_Location_request_completed"]
[connection signal="request_completed" from="NetworkController/Forecast" to="." method="_on_Forecast_request_completed"]
[connection signal="request_completed" from="NetworkController/WeeklyForecast" to="." method="_on_WeeklyForecast_request_completed"]
[connection signal="request_completed" from="NetworkController/HoulyForecast" to="." method="_on_HoulyForecast_request_completed"]
[connection signal="request_completed" from="NetworkController/AlertRequest" to="." method="_on_AlertRequest_request_completed"]
[connection signal="request_completed" from="NetworkController/ZoneIDRequest" to="." method="_on_ZoneIDRequest_request_completed"]
+[connection signal="request_completed" from="NetworkController/EPAReq" to="." method="_on_EPAReq_request_completed"]
[connection signal="pressed" from="GUI/Forecasts/Window/NowCast/Alert" to="." method="_on_Alert_pressed"]
+[connection signal="pressed" from="GUI/Forecasts/Window/Footer/AirQuality" to="." method="_on_AirQuality_pressed"]
+[connection signal="pressed" from="GUI/Forecasts/Window/Footer/Settings" to="." method="_on_Settings_pressed"]
[connection signal="pressed" from="GUI/AlertDisplay/Body/ForecastReturn" to="." method="_on_ForecastReturn_pressed"]
+[connection signal="pressed" from="GUI/ServerFailure/Body/CloseApp" to="." method="_on_CloseApp_pressed"]
+[connection signal="text_changed" from="GUI/Settings/Body/EPAKey/LineEdit" to="." method="_on_LineEdit_text_changed"]
+[connection signal="pressed" from="GUI/Settings/Body/Return" to="." method="_on_Return_pressed"]
+[connection signal="pressed" from="GUI/AirQuality/Body/ReturnAQ" to="." method="_on_ReturnAQ_pressed"]
diff --git a/README.md b/README.md
index 8d664e0..e41a192 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,60 @@
# MiniWeather
MiniMAL Weather App
-A minimal weather app that uses https://ip-api.com/ for location data and the National Weather Service API for forecast data.
+A minimal, text-only weather app for Android.
-*Ad Free
+## Features
-*No Trackers
+- Current, Hourly, and Weekly Forecasts
-*Android APK
+- Severe Weather Alerts (In-App. No push notifications.)
-Built in Godot with GDScript
+- Air Quality Reports
+
+- Free Forever - No Nagging, No Ads, No In-App Purchases or Microtransactions!
+
+- No Trackers, No Data Collection, and no selling your information to Data Brokers
+
+- Android APK
+
+## Instructions
+
+1. Install Android .apk
+
+2. Sign up for EPA AirNow API service to receive API Key: https://docs.airnowapi.org/account/request/
+
+3. Launch MiniWeather
+
+4. Click on "Settings" button in lower right corner of screen.
+
+5. Enter your AirNow API key.
+
+6. Done =)
+
+
+## Credits
+
+Built in Godot with GDScript
+
+Weather Data from National Weather Service API
+
+Air Quality Data from Environmental Protection Agency AirNow API
+
+Location Data from ip-api.org
Weather icons created by Eucalyp - Flaticon
+Font: Anek Latin by EkType Collective
+
+
+## Privacy Policies
+
+National Weather Service
+
+EPA Privacy and Security Policy
+
+ip-api.com Privacy Policy
+
+Godot Engine
-Font: Anek Latin https://github.com/EkType/Anek/
+###### Disclaimer
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION; OR LOSS OF LIFE OR PROPERTY) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/export_presets.cfg b/export_presets.cfg
index 109b2bf..122ceba 100644
--- a/export_presets.cfg
+++ b/export_presets.cfg
@@ -7,7 +7,7 @@ custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
-export_path="../../DevTools/Exports/Android/MiniWeather/MiniWeatherV0.2.apk"
+export_path="../../DevTools/Exports/Android/MiniWeather/MiniWeatherV0.5B.apk"
script_export_mode=1
script_encryption_key=""
@@ -35,7 +35,7 @@ version/target_sdk=30
package/unique_name="org.godotengine.$genname"
package/name=""
package/signed=true
-package/classify_as_game=true
+package/classify_as_game=false
package/retain_data_on_uninstall=false
package/exclude_from_recents=false
launcher_icons/main_192x192=""
diff --git a/project.godot b/project.godot
index 0607d6f..9b8a2df 100644
--- a/project.godot
+++ b/project.godot
@@ -10,7 +10,7 @@ config_version=4
[application]
-config/name="WeatherApp-Android"
+config/name="MiniWeather"
run/main_scene="res://Main.tscn"
config/icon="res://icon.png"