Last active
March 29, 2022 22:26
-
-
Save jasonsnell/caeff4fef6978f8271780f40da58db9c to your computer and use it in GitHub Desktop.
WeatherCat storm log generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/local/bin/python3 | |
# Storm Log script | |
# For WeatherCat - https://trixology.com | |
# By Jason Snell <[email protected]> | |
import re | |
from collections import defaultdict | |
import datetime | |
# Path to folder containing WeatherCat data files in year-folder format | |
# It's usually '/Users/[your-username]/Library/WeatherCatData/[your-location]/' | |
weatherCatPath = '/Users/admin/Library/WeatherCatData/Location1/' | |
# Path to folder where you want image to be saved | |
savePath = '/Library/Webserver/Documents/snellzone/weather/' | |
maxprecip = defaultdict(lambda: -99999) | |
diff = {} | |
today = datetime.date.today() | |
month = int(today.strftime('%m')) | |
monthstr = str(month + 100)[-2:] | |
day = today.strftime('%d') | |
year = today.strftime('%Y') | |
datelist = [] | |
stormList = [] | |
stormStart = [] | |
stormEnd = [] | |
theOutput = '' | |
newLine = '\n' | |
datapoint = re.compile(r't:([0-9]{2})[0-9]{4}') | |
rainpoint = re.compile(r'P:([0-9]{1,3}\.[0-9]{2})') | |
if month > 7: | |
monthStart = 7 | |
else: | |
monthStart = -5 | |
for i in range(monthStart, month+1, 1): | |
if i < 1 : | |
yearcode = str(int(year) - 1) | |
monthcode = 12 + i | |
else: | |
monthcode = i | |
yearcode = year | |
filepath = (weatherCatPath + f'{yearcode}/{monthcode}_WeatherCatData.cat') | |
file = open(filepath, 'r') | |
monthstring = str(monthcode + 100)[-2:] | |
for count, line in enumerate(file): | |
if count > 10: | |
theday = datapoint.search(line) | |
todayDay = (f'{yearcode}-{monthstring}-' + (theday.group(1))) | |
therain = rainpoint.search(line) | |
rainfloat = float(therain.group(1)) | |
maxprecip[todayDay] = round(rainfloat * 0.03937007874, 2) | |
file.close() | |
# now loop through from monthstring + day | |
# plucking values for 7 days and putting them in a new list or dict | |
theRain = list(maxprecip.values()) | |
theDates = list(maxprecip.keys()) | |
theCounter = 0 | |
totalRain = 0 | |
# Loops through all rain days but the current day | |
for i in range(1,len(theRain)-1): | |
# If there was rain on this day, it updates the total rain count. | |
# If this is the first day of rain, it marks this as the start. | |
# It's marked as the end date, but that isn't used unless the | |
# next date has no rain. | |
if theRain[i] > 0 : | |
if totalRain == 0 : | |
sequenceStart = theDates[i] | |
totalRain += theRain[i] | |
if i == len(theRain)-1 : | |
pass | |
else: | |
sequenceEnd = theDates[i] | |
else: | |
# If there was no rain, but total rain is non-zero, mark this | |
# as the end of the rain and add all the results to the stack. | |
# Thus ends this storm entry. | |
if (totalRain > 0 ): | |
totalRain += theRain[i] | |
totalRain = round(totalRain,2) | |
if i != len(theRain)-1 : | |
# don't save storm total if rain continued on last day | |
stormList.append(totalRain) | |
stormEnd.append(sequenceEnd) | |
stormStart.append(sequenceStart) | |
totalRain = 0 | |
# This handles the current day and wraps it all up. | |
if theRain[-1] > 0 : | |
if totalRain == 0 : | |
# If there was rain on the current day but not before | |
sequenceStart = theDates[-1] | |
stormStart.append(sequenceStart) | |
totalRain += theRain[-1] | |
sequenceEnd = theDates[-1] | |
totalRain = round(totalRain,2) | |
stormStart.append(sequenceStart) | |
stormList.append(totalRain) | |
stormEnd.append(f'{year}-{monthstr}-{day}') | |
else: | |
# there's no rain on the current day. | |
if (totalRain > 0 ): | |
# if there was an ongoing storm, close it out | |
totalRain = round(totalRain,2) | |
stormList.append(totalRain) | |
stormEnd.append(theDates[-2]) | |
stormStart.append(sequenceStart) | |
# Now we're outputting the storm log, but removing low-precip storms. | |
for i in range((len(stormList)-1), 0, -1): | |
if stormList[i] > .09: | |
startDate = datetime.datetime.strptime(stormStart[i], '%Y-%m-%d') | |
endDate = datetime.datetime.strptime(stormEnd[i], '%Y-%m-%d') | |
difference = endDate - startDate | |
startDatePretty = startDate.strftime('%b %e') | |
endDatePretty = endDate.strftime('%b %e') | |
totalDays = difference.days + 1 | |
if totalDays > 1 : | |
theOutput = theOutput + (f'<li>{stormList[i]}" {startDatePretty}-{endDatePretty} ({totalDays} days)</li>') | |
else: | |
theOutput = theOutput + (f'<li>{stormList[i]}" {startDatePretty}</li>') | |
lastStorm = datetime.datetime.strptime(stormEnd[-1], '%Y-%m-%d') | |
stormDifference = datetime.datetime.now() - lastStorm | |
if stormDifference.days < 2: | |
theOutputPrefix = (str(stormList[-1]) + ' inches in current storm.</p>' + | |
'<p><img width="400" src="/weather/rainhistory.png"></p>' | |
'<p><a href="https://abclocal.go.com/kgo/doppler?id=5750606&' | |
'mapnum=1&anim=true"><img src="https://cdn.abclocal.go.com/three/' | |
'kgo/weather/maps/nbay1_1280.jpg" width="400"></a></p>' | |
'<h3>Storm Log</h3>') | |
else: | |
theOutputPrefix = '</p><h3>Storm Log</h3>' | |
if stormDifference.days < 14: | |
theOutputPrefix = (theOutputPrefix + | |
'<p>Last two weeks of rain:</p><p><img ' | |
'src="/weather/latestrain1.png" width="400" /></p><p><img ' | |
'src="/weather/latestrain2.png" width="400" /></p>') | |
if theOutput: | |
theOutput = '<p>Rain events:</p><ul>' + theOutput + '</ul>' | |
outFile = open((savePath + 'stormlog.txt'), 'w') | |
outFile.write(theOutputPrefix + theOutput) | |
outFile.close() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment