app-wx.py
'''\
Weather.
Developer@Sonnack.com
July 2017
'''
from __future__ import print_function
from sys import argv, stdout, stderr, path as syspath
from os import environ, path, listdir
from datetime import date, timedelta
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
from matplotlib.dates import DayLocator, DateFormatter
from logger import logger, info, debug, trace
from db_weather import BasePath, dbLocalClimateDataTable, dbWeatherStationTable, Queries
Log = logger('weather')
def classify_data (*args):
Log.info('Classify-Table-Data')
fn = args[0] if 0 < len(args) else 'data-types.out'
tbl = dbLocalClimateDataTable()
sql = 'SELECT * FROM "%s" ORDER BY date' % tbl.name
rs = tbl.db_query(sql)
if not rs: Log.warn('No Data!'); return []
accum = [[0,0,0,0,0] for n in tbl.col_headers]
for r in rs:
for cx,c in enumerate(r):
if isinstance(c,float):
accum[cx][4] += 1
continue
if isinstance(c,int):
accum[cx][3] += 1
continue
if isinstance(c,unicode):
if len(c) == 0:
accum[cx][1] += 1
continue
try:
n = int(c)
accum[cx][3] += 1
continue
except: pass
try:
n = float(c)
accum[cx][4] += 1
continue
except: pass
accum[cx][2] += 1
continue
accum[cx][0] += 1
h1 = 'Column Name DataType unkn empt text int float total\n'
h2 = '============================== ======== ====== ====== ====== ====== ====== =======\n'
fp = open(path.join(BasePath,fn), 'w')
fp.write(h1)
fp.write(h2)
for rcd in zip(tbl.col_headers, tbl.col_types, *zip(*accum)):
t = rcd+(sum(rcd[-5:]), )
fp.write('%-30s %-8s %6d %6d %6d %6d %6d %7d\n' % t)
fp.write(h2)
fp.close()
Log.info('wrote: %s' % fn)
return rs
def create_stations_table ():
Log.info('Make-Stations-Table')
tbl = dbWeatherStationTable()
tbl.create_table()
return tbl
def destroy_stations_table ():
Log.info('Drop-Stations-Table')
tbl = dbWeatherStationTable()
tbl.destroy_table()
return tbl
def list_stations_table (*args):
Log.info('List-Stations-Table: %s' % str(args))
tbl = dbWeatherStationTable()
return tbl.list_to_file()
def create_lcd_table ():
Log.info('Make-LCD-Table')
tbl = dbLocalClimateDataTable()
tbl.create_table()
return tbl
def destroy_lcd_table ():
Log.info('Drop-LCD-Table')
tbl = dbLocalClimateDataTable()
tbl.destroy_table()
return tbl
def list_lcd_table (*args):
Log.info('List-LCD-Table: %s' % str(args))
tbl = dbLocalClimateDataTable()
return tbl.list_to_file()
def add_records_lcd_table (*args):
fname = args[0] if 0 < len(args) else 'lcd_1990-1999.csv'
Log.info('Add2-LCD-Table')
tbl = dbLocalClimateDataTable()
tbl.load_records(fname)
return tbl
def do_chart_month_temps (*args):
Log.info('Chart/Month/Temps: %s' % str(args))
mo = args[0] if 0 < len(args) else '7'
yr = args[1] if 1 < len(args) else '2017'
tbl = dbLocalClimateDataTable()
return tbl.chart_month_temps(int(mo), int(yr))
def do_chart_month_precip (*args):
Log.info('Chart/Month/Precip: %s' % str(args))
mo = args[0] if 0 < len(args) else '7'
yr = args[1] if 1 < len(args) else '2017'
tbl = dbLocalClimateDataTable()
return tbl.chart_month_precip(int(mo), int(yr))
def do_chart_year_temps (*args):
Log.info('Chart/Year/Temps: %s' % str(args))
yr = args[0] if 0 < len(args) else '2017'
tbl = dbLocalClimateDataTable()
return tbl.chart_year_temps(int(yr))
def do_chart_year_precip (*args):
Log.info('Chart/Year/Precip: %s' % str(args))
yr = args[0] if 0 < len(args) else '2017'
tbl = dbLocalClimateDataTable()
return tbl.chart_year_precip(int(yr))
def do_chart_decade_temps (*args):
Log.info('Chart/Decade/Temps: %s' % str(args))
yr = args[0] if 0 < len(args) else '2006'
tbl = dbLocalClimateDataTable()
return tbl.chart_decade_temps(int(yr))
def do_chart_decade_precip (*args):
Log.info('Chart/Decade/Precip: %s' % str(args))
yr = args[0] if 0 < len(args) else '2006'
tbl = dbLocalClimateDataTable()
return tbl.chart_decade_precip(int(yr))
def do_chart_months_temps_hi (*args):
Log.info('Chart/Months/Temps/Hi: %s' % str(args))
mon = args[0] if 0 < len(args) else '9'
yr0 = args[1] if 1 < len(args) else '2010'
yr1 = args[2] if 2 < len(args) else '2017'
tbl = dbLocalClimateDataTable()
return tbl.chart_months_temps_hi(int(mon), int(yr0), int(yr1))
def do_chart_months_temps_lo (*args):
Log.info('Chart/Months/Temps/Lo: %s' % str(args))
mon = args[0] if 0 < len(args) else '9'
yr0 = args[1] if 1 < len(args) else '2010'
yr1 = args[2] if 2 < len(args) else '2017'
tbl = dbLocalClimateDataTable()
return tbl.chart_months_temps_lo(int(mon), int(yr0), int(yr1))
def do_chart_months_temps_hi_lo (*args):
Log.info('Chart/Months/Temps: %s' % str(args))
mon = args[0] if 0 < len(args) else '9'
yr0 = args[1] if 1 < len(args) else '2010'
yr1 = args[2] if 2 < len(args) else '2017'
tbl = dbLocalClimateDataTable()
return tbl.chart_months_temps_hi_lo(int(mon), int(yr0), int(yr1))
def do_chart_temp_min_max (*args):
Log.info('Chart/Temp/Min-Max: %s' % str(args))
tbl = dbLocalClimateDataTable()
return tbl.chart_temp_min_max(*args)
def do_chart_pressure (*args):
Log.info('Chart/Pressure: %s' % str(args))
tbl = dbLocalClimateDataTable()
return tbl.chart_pressure(*args)
def do_chart_rel_hum (*args):
Log.info('Chart/Rel-Hum: %s' % str(args))
tbl = dbLocalClimateDataTable()
return tbl.chart_rel_hum(*args)
SQL_CHRT = '''\
SELECT
cast(substr(date,1,4) as INTEGER) AS "dtY",
cast(substr(date,6,2) as INTEGER) AS "dtM",
cast(substr(date,9,2) as INTEGER) AS "dtD",
day_precip, day_snowfall
FROM "%s"
WHERE (report_type=?) AND (substr(date,1,4)=?)
ORDER BY date
'''
def do_chart (*args):
Log.info('chart/parameters: %s' % str(args))
yr = args[0] if 0 < len(args) else '2017'
fn = args[1] if 1 < len(args) else 'wx-chart.png'
ps = ['SOD', yr]
year = int(yr)
tbl = dbLocalClimateDataTable()
sql = SQL_CHRT % tbl.name
rs = tbl.db_query(sql, ps)
if not rs: Log.warn('No Data!'); return rs
rain = [(date(r[0],r[1],r[2]),r[3]) for r in rs if isinstance(r[3],float)]
snow = [(date(r[0],r[1],r[2]),r[4]) for r in rs if isinstance(r[4],float)]
rain_dts, rain_vals = zip(*rain)
snow_dts, snow_vals = zip(*snow)
xmin = date(year,1,1)
xmax = date(year+1,1,1) - timedelta(1)
ymin, ymax = 0.0, +2.5
xt0 = [date(year,m+1,1) for m in range(12)]+[date(year,12,31)]
xt1 = []
[xt1.extend(x) for x in [[date(year,m+1,d) for d in [7,14,21,28]] for m in range(12)]]
fig, ax = plt.subplots()
fig.suptitle('Rain & Snow %04d' % year, fontsize=13)
ax.set_ylabel('Precip (inches)', fontsize=11)
ax.xaxis_date()
ax.minorticks_on()
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
ax.set_xticks(xt0)
ax.set_xticks(xt1, minor=True)
ax.xaxis.set_major_formatter(DateFormatter('%b %d'))
ax.yaxis.set_major_locator(MultipleLocator(1.0))
ax.yaxis.set_minor_locator(MultipleLocator(0.25))
for tick in ax.xaxis.get_major_ticks():
tick.label1.set_rotation('vertical')
tick.label1.set_size(11)
ax.tick_params(which='major', axis='both', direction='out')
ax.tick_params(which='minor', axis='both', direction='out')
ax.grid(which='minor', axis='x', color='#afafaf', lw=0.8,ls='-', alpha=1.0, zorder=2)
ax.grid(which='minor', axis='y', color='#cfcfcf', lw=0.7,ls='-', alpha=1.0, zorder=2)
ax.grid(which='major', axis='x', color='#7f7f7f', lw=1.3,ls='-', alpha=1.0, zorder=4)
ax.grid(which='major', axis='y', color='#7f7f7f', lw=0.9,ls='-', alpha=1.0, zorder=4)
ax.fill_between(rain_dts,rain_vals,0, color='#007fbf', alpha=0.75, zorder=9)
ax.fill_between(snow_dts,snow_vals,0, color='#3f3f3f', alpha=0.75, zorder=8)
fig.set_figwidth(9.8)
fig.set_figheight(4.8)
fig.subplots_adjust(left=0.10, bottom=0.18, right=0.97, top=0.92)
fig.savefig(path.join(tbl.imgsPath,fn))
return rs
SQL_QRY = '''\
SELECT rowid, date,time, report_type, day_heat_deg_days
FROM "%s"
WHERE (0 < length(day_heat_deg_days)) AND (substr(day_heat_deg_days,-1) = 's')
ORDER BY date,time
'''
def do_query (*args):
Log.info('query/parameters: %s' % str(args))
fname = args[0] if 0 < len(args) else 'wx-query.out'
fn = path.join(BasePath,fname)
ps = []
tbl = dbLocalClimateDataTable()
sql = SQL_QRY % tbl.name
rs = tbl.db_query(sql, ps)
if not rs: Log.warn('No Data!'); return []
Log.info()
for r in rs:
Log.info(r)
Log.info()
Log.info(sql)
Log.info(ps)
Log.info()
return rs
SQL_UPDT = '''\
UPDATE "%s"
SET day_heat_deg_days = substr(day_heat_deg_days, 1, length(day_heat_deg_days)-1)
WHERE (substr(day_heat_deg_days,-1) = 's')
'''
def do_test (*args):
Log.info('test/parameters: %s' % str(args))
fname = args[0] if 0 < len(args) else 'wx-test.out'
fn = path.join(BasePath,fname)
ps = [123456]
sql = 'select * from %s where rowid=?'
tbl = dbLocalClimateDataTable()
sql = sql % tbl.name
rs = tbl.db_query(sql, ps)
if not rs: Log.warn('No Data!'); return []
for r in rs: Log.trace(r)
return rs
def do_main (*args):
Log.info('main/parameters: %s' % str(args))
fname = args[0] if 0 < len(args) else ''
tbl = dbLocalClimateDataTable()
Log.info('Database-Name: %s' % tbl.dbname)
Log.info('Table-Name: %s' % tbl.name)
Log.info()
Log.info('Column-Names: %s' % str(tbl.col_names))
Log.info()
Log.info('Column-Types: %s' % str(tbl.col_types))
Log.info()
Log.info('Header-Names: %s' % str(tbl.col_headers))
Log.info()
return tbl
def dispatch (cmd, *args):
Log.info('command: %s' % cmd)
Log.info('arguments: %d' % len(args))
if cmd == 'c.10.temp': return do_chart_decade_temps(*args)
if cmd == 'c.10.precip': return do_chart_decade_precip(*args)
if cmd == 'c.yr.temp': return do_chart_year_temps(*args)
if cmd == 'c.yr.precip': return do_chart_year_precip(*args)
if cmd == 'c.mn.temp': return do_chart_month_temps(*args)
if cmd == 'c.mn.precip': return do_chart_month_precip(*args)
if cmd == 'c.ms.temp': return do_chart_months_temps_hi_lo(*args)
if cmd == 'c.ms.temp.hi': return do_chart_months_temps_hi(*args)
if cmd == 'c.ms.temp.lo': return do_chart_months_temps_lo(*args)
if cmd == 'c.rel_hum': return do_chart_rel_hum(*args)
if cmd == 'c.pressure': return do_chart_pressure(*args)
if cmd == 'c.temps': return do_chart_temp_min_max(*args)
if cmd == 'chart': return do_chart(*args)
if cmd == 'query': return do_query(*args)
if cmd == 'test': return do_test(*args)
if cmd == 'main': return do_main(*args)
if cmd == 'classify': return classify_data()
if cmd == 'lcd.add2': return add_records_lcd_table(*args)
if cmd == 'lcd.list': return list_lcd_table(*args)
if cmd == 'lcd.make': return create_lcd_table(*args)
if cmd == 'lcd.drop': return destroy_lcd_table(*args)
if cmd == 'sta.list': return list_stations_table(*args)
if cmd == 'sta.make': return create_stations_table(*args)
if cmd == 'sta.drop': return destroy_stations_table(*args)
return [None, cmd, args]
if __name__ == '__main__':
print('autorun: %s' % argv[0])
Log.start(path.join(BasePath,'app-wx.log'))
Log.level(trace())
cmd = argv[1] if 1 < len(argv) else ''
etc = argv[2:] if 2 < len(argv) else []
try:
obj = dispatch(cmd, *etc)
print('exit')
Log.debug('exit')
except Exception as e:
print('ERROR! "%s"' % e, file=stderr)
Log.error(e)
raise
finally:
Log.end()
'''eof'''