Skip to content

Instantly share code, notes, and snippets.

@kura
Last active November 3, 2023 17:47
Show Gist options
  • Save kura/21a8512ef73d17dab4cdfbe8a31a05a4 to your computer and use it in GitHub Desktop.
Save kura/21a8512ef73d17dab4cdfbe8a31a05a4 to your computer and use it in GitHub Desktop.
triplehelix.py
import datetime
import json
import os
import sys
import requests
apiKey = ""
stationID = ""
weatherUnits = ""
rainfallLog = "rainfallLog.csv"
lastTotalLog = "lastTotal"
now = datetime.datetime.now().time()
def calc(precipTotal):
if now.hour == 0:
lastTotal = 0.0
else:
with open(lastTotalLog, "r") as f:
lastTotal = float(f.readline())
return round(precipTotal - lastTotal, 2)
def create_empty_files():
if not os.path.isfile(lastTotalLog):
with open(lastTotalLog, "w") as f:
f.write("0")
if not os.path.isfile(rainfallLog):
with open(rainfallLog, "w") as f:
f.write("Time,Hourly Rainfall (mm)\n")
def get_weather_data_from_api():
r = requests.get(
f"https://api.weather.com/v2/pws/observations/current?stationId={stationID}8&format=json&units={weatherUnits}&apiKey={apiKey}"
)
r.raise_for_status()
return json.loads(r.text)
if __name__ == "__main__":
create_empty_files()
try:
weather = get_weather_data_from_api()
except requests.RequestException as e:
print(e)
sys.exit(1)
dataTime = weather["observations"][0]["obsTimeLocal"]
precipTotal = weather["observations"][0]["uk_hybrid"]["precipTotal"]
if weatherUnits == "h":
precipTotal *= 25.4 # API bug shows inch so convert to mm
hourlyRain = calc(precipTotal)
with open(rainfallLog, "a") as f:
f.write(f"{dataTime},{hourlyRain}\n")
with open(lastTotalLog, "w") as f:
f.write(precipTotal)
import datetime
import json
import os
from http.client import HTTPSConnection
API_KEY = ""
STATION_ID = ""
WEATHER_UNITS = "h"
CSV = "rainfall.csv"
def calc(current_value, last_value):
if current_value == 0 or last_value == 0:
return current_value
return round(last_value - current_value, 2)
def create_empty_files():
if os.path.exists(CSV):
return
one_hour_before = (
datetime.datetime.utcnow() - datetime.timedelta(hours=1)
).isoformat()
with open(CSV, "w") as f:
f.write("Time,Hourly Rainfall (mm)\n")
f.write(f"{one_hour_before},0.0\n")
def write_data(data):
dt = datetime.datetime.utcnow().isoformat()
with open(CSV, "a") as f:
f.write(f"{dt},{data}\n")
def get_last_entry():
with open(CSV) as f:
l = f.readlines()[-1].strip()
return float(l.partition(",")[2])
# API Call
def get_weather_data_from_api():
conn = HTTPSConnection("api.weather.com")
conn.request(
"GET",
f"/v2/pws/observations/current?stationId={STATION_ID}&format=json&units={WEATHER_UNITS}&apiKey={API_KEY}"
)
r = conn.getresponse()
return json.loads(r.read())["observations"][0]
if __name__ == "__main__": # The main routine
create_empty_files()
last_entry = get_last_entry()
try:
data = get_weather_data_from_api()
precipitation = calc(
float(data["uk_hybrid"]["precipTotal"]), last_entry
)
write_data(precipitation)
except (OSError, json.JSONDecodeError) as e:
print(e)
@tripplehelix
Copy link

OK! I think we have something. A quick test worked... time for midnight again.

Btw, thank you so much for all this help. It would have driven me crazy doing it all alone.

@kura
Copy link
Author

kura commented Nov 2, 2023

No need for an else, that func call bails early so the with is never hit.

No worries. :)

@tripplehelix
Copy link

You are well versed in python. It's these weird little rules that are fun to learn.

@kura
Copy link
Author

kura commented Nov 2, 2023

Most programming language allows you to return early from a function if a condition isn't met tbh. Sometimes it just looks odd or people don't think about doing it that way and wrap it in an else for no real gain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment