Skip to content
Snippets Groups Projects
Verified Commit ce196d93 authored by David Hoese's avatar David Hoese
Browse files

Add cgi-bin directory from old metobs site

parent 365d62d7
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/python
# data_data.py
# CGI retrieves RIG data in an ascii table.
#
# Author: Maciek Smuga-Otto <maciek@ssec.wisc.edu>
# Copyright 2003-2007 University of Wisconsin-Madison
#
# example invocation:
# .../data_data.py?start=2003-03-27+14:05:57&end=2003-03-27+15:05:57&symbols=TEMP41372:CS10162:PAROSCI
# if no end value provided, assume end = most recent sample.
# if no begin is provided, assume it is the same as end (return one value only).
# thus, calling with no begin OR end gives the single most recent sample.
#
CVS_ID="$Id: data_data.py,v 1.25 2009/04/29 18:36:57 brucef Exp $"
import cgi, os, sys # system/cgi utils
import math
import psycopg2 as db
from data_symbols import symalias, precision # symbol alias table and symbol precision table
from data_usage import usage
from dewpoint import dewpoint
DB = ('rig','rig_client','borabora.ssec.wisc.edu','wXn0w')
def get_slice(con, begin, end, resample, resolution, *symbols):
"""Get data for the specified list of symbols, every resample'th timestamp in the
range defined by [begin, end).
"""
begin, end = adjust_ts(con, begin, end, resolution)
#print 'begin:',begin, 'end:', end # DEBUG
# construct the wide query
dbsymbols, dbtables, dbwhereclause = ("", "", "")
c = con.cursor()
for symbol in symbols:
c.execute("SELECT symbol_id FROM symbols WHERE name='%s'" % symbol)
symbol_id = c.fetchone()[0]
dbsymbols += ", d_%s.value AS %s" % (symbol, symbol)
dbtables += ", data d_" + symbol
dbwhereclause += "AND samples.sample_id = d_%s.sample_id AND d_%s.symbol_id = %s " % \
(symbol, symbol, symbol_id)
# FIXME - this is a temporary patch to compensate for spurious error values written
# into the database for accurain, which will have to get fixed in the java ingest.
if symbol_id == 102:
dbwhereclause += "AND d_%s.value != -99999 " % symbol
query = "SELECT stamp%s FROM samples%s WHERE stamp >= '%s' AND stamp <= '%s' %s \
AND resolution = %s " % (dbsymbols, dbtables, begin, end, dbwhereclause, resolution)
if resample > 1:
query += "AND floor(extract( epoch from stamp::timestamp - stamp::date)/%s)::int %% (%s) = 0 "% (resolution, resample)
query += "ORDER BY stamp"
#print query # for debugging only
c.execute(query)
return c.fetchall()
def adjust_ts(dbconnection, begin, end, resolution):
if not end:
c = dbconnection.cursor()
if not begin:
c.execute("SELECT max(stamp), max(stamp) from samples where resolution=%s" % resolution)
return c.fetchone()
# the following several lines are for the case where begin timestamp is -hh:mm:ss
# indicating that the data be gathered for the past hh hours, mm minutes and ss seconds.
begin_seconds_ago = resolution
if '-' == begin[0]:
(hh,mm,ss) = [int(t) for t in begin[1:].split(':')]
begin_seconds_ago = max(ss + 60 * mm + 3600 * hh, resolution)
c.execute( "SELECT now(), now() - '%s seconds'::interval" % begin_seconds_ago )
(end, maybegin) = c.fetchone()
if '-' == begin[0]:
begin = maybegin
elif not begin:
c = dbconnection.cursor()
c.execute( "SELECT '%s'::timestamp - '%s seconds'::interval" % ( end, resolution ) )
begin = c.fetchone()[0]
return ( begin, end )
def cgiheader( html = None ):
if html:
print "Content-Type: text/html"
else:
print "Content-Type: text/plain"
print "Cache-control: private, no-cache"
print "Expires: Thu, 1 Aug 2002 12:23:00 GMT"
print "Pragma: no-cache"
print
def linearConvert( data, factor = 0, offset = 0 ):
return data * factor + offset
def normalize_rh(rh):
return rh > 100 and 100 or rh
#######################
# MAIN
def cgimain():
form = cgi.FieldStorage()
# process CGI input
if 'symbols' not in form.keys():
cgiheader(1)
usage()
sys.exit(0)
begin,end = '','' # begin, end timestamps
if 'begin' in form.keys():
begin = form['begin'].value
if 'end' in form.keys():
end = form['end'].value
altts = 0 # alternate timestamp display - replace dashes and colons with spaces
if 'altts' in form.keys():
altts = 1
separator = '' # separates individual fields in an output row. Defaults to aligned column output.
if 'separator' in form.keys():
separator = form['separator'].value
resolution = 5 # in seconds. Default for raw Campbell data, must be changed to get Ceilometer (15) or
# DB-averaged Campbell data.
if 'resolution' in form.keys():
resolution = int( form['resolution'].value )
resample = 1
if 'interval' in form.keys():
interval_str = form['interval'].value
interval_chunks = interval_str.split(':')
int_ss, int_mm, int_hh = 0, 0, 0
if len(interval_chunks) == 1:
int_ss = int(interval_chunks[0])
if len(interval_chunks) == 2:
int_mm = int(interval_chunks[0])
int_ss = int(interval_chunks[1])
if len(interval_chunks) > 2:
int_hh = int(interval_chunks[0])
int_mm = int(interval_chunks[1])
int_ss = int(interval_chunks[2])
resample = (int_ss + 60 * int_mm + 3600 * int_hh) / resolution
# symaliases are the aliases for (internal) symbols requested by the user (ex. 't' for 'TEMP41372')
symaliases = filter( lambda x: x in symalias.keys(), form['symbols'].value.split( ':' ))
symbols_raw = [symalias.get( s, None ) for s in symaliases ] # get associated symbols
symbols = filter( lambda x: x not in ('DEWPOINT',), symbols_raw ) # strip out DEWPOINT
# get around the database problem of hanging on too many symbols
symbols1 = symbols[:]
symbols2 = []
if len(symbols) >= 4:
symbols1 = symbols[:4]
symbols2 = symbols[4:]
###################################################################
# DB OPS
#
con = db.connect("dbname='%s' user='%s' host='%s' password='%s'" % DB)
dataset1 = get_slice(con, begin, end, resample, resolution, *symbols1)
if symbols2:
dataset2 = get_slice(con, begin, end, resample, resolution, *symbols2)
# dewpoint needs a little help...
if 'DEWPOINT' in symbols_raw:
dewdata_in = get_slice(con, begin, end, resample, resolution, 'TEMP41372', 'RH41372')
#print "dataset1: %s, dewdata_in: %s" % (len(dataset1), len(dewdata_in)) #DEBUG
dewdata = [dewpoint(temp,normalize_rh(relhum)) for (timestamp, temp, relhum) in dewdata_in]
con.close()
#
# END DB OPS
###################################################################
cgiheader()
# print column names
symstr= (separator or ' ').join(('YYYY-MM-DD','hh:mm:ss'))
if altts:
symstr= (separator or ' ').join(('YYYY','MM','DD','hh','mm','ss'))
for s in symaliases:
if separator:
symstr += "%s%s" % (separator, s)
else:
symstr += " %+7.7s" % s
print symstr
# print data
foldindex = 0 # index into fold-in (computed) arrays, such as dewpoint
for row in dataset1:
outstr = ''
date = row[0].strftime('%Y-%m-%d')
time = row[0].strftime('%H:%M:%S')
if altts: # replace dashes and colons with spaces
outstr = (separator or ' ').join(tuple(date.split('-') + time.split(':')))
else: # don't
outstr = "%s%s%s" % (date, separator or ' ', time)
for s in symbols_raw:
if s == 'DEWPOINT':
if foldindex < len(dewdata):
data = dewdata[foldindex] # fold in the dewdata array, one element at a time
else:
data = 0
# again, reading from the second dataset, to deal with the database bug
elif s in symbols2:
data = dataset2[foldindex][ symbols2.index(s)+1 ]
else:
data = row[ symbols1.index(s)+1 ]
if s in ( 'RAIN380M', 'ACCURAIN' ):
# every tick is 1/100th of an inch, not 1/10'th of a mm as initially supposed.
data = linearConvert( data, factor=0.1, offset=0 )
if s is 'RH41372': # force RH to be no greater than 100
data = normalize_rh(data)
if separator:
format_str = '%s%0' + precision( s ) + 'f'
outstr += format_str % (separator,data)
else:
format_str = ' %7' + precision( s ) + 'f'
outstr += format_str % data
print outstr
foldindex += 1
cgimain()
##### If database down, comment out above line, uncomment the code below
#cgiheader()
#print "Sorry, RIG data app temporarily out of service"
#print "Please email maciek@ssec.wisc.edu with any questions."
symalias = {
'box_p' : 'CS105',
'box_pressure' : 'CS105',
'box_rh' : 'CS10162',
'box_relative_humidity' : 'CS10162',
'spd' : 'WSPD05305',
'speed' : 'WSPD05305',
'dir' : 'WDIR05305',
'direction' : 'WDIR05305',
'rh' : 'RH41372',
'relative_humidity' : 'RH41372',
't' : 'TEMP41372',
'temperature' : 'TEMP41372',
'flux' : 'LI200X',
'average_solar_radiation_flux' : 'LI200X',
'precip' : 'RAIN380M',
'precipitation' : 'RAIN380M',
'accum_precip' : 'ACCURAIN',
'accumulated_precipitation' : 'ACCURAIN',
'box_t' : 'TEMP107_1',
'box_temperature' : 'TEMP107_1',
'outside_box_t' : 'TEMP107_2',
'outside_box_temperature' : 'TEMP107_2',
't_6.3m' : 'TEMP107_3',
'temperature_6.3_meter' : 'TEMP107_3',
't_14.5m' : 'TEMP107_4',
'temperature_14.5_meter' : 'TEMP107_4',
't_unk' : 'TEMP107_5',
'temperature_unknown' : 'TEMP107_5',
'td' : 'DEWPOINT',
'dewpoint' : 'DEWPOINT',
'dew_point' : 'DEWPOINT',
'p' : 'PAROSCI',
'pres' : 'PAROSCI',
'pressure' : 'PAROSCI',
}
temp_precision = '.1'
rh_precision = '.0'
press_precision = '.1'
windspd_precision = '.1'
winddir_precision = '.0'
solarrad_precision = '.1'
default_precision = '.3'
rain_precision = '.2'
ceil_precision = '.0'
def precision(symbol):
if symbol in ('CS105', 'PAROSCI'):
return press_precision
elif symbol in ('CS10162', 'RH41372'):
return rh_precision
elif symbol in ('TEMP41372', 'TEMP107_1', 'TEMP107_2', 'TEMP107_3', 'TEMP107_4', 'TEMP107_5', 'DEWPOINT'):
return temp_precision
elif symbol == 'WSPD05305':
return windspd_precision
elif symbol == 'WDIR05305':
return winddir_precision
elif symbol == 'LI200X':
return solarrad_precision
elif symbol in ('RAIN380M', 'ACCURAIN'):
return rain_precision
else:
return default_precision
#!/usr/bin/env python2
# usage for data_data.py
def usage():
print """
<html><body>
<em>
Usage: data_data.py?symbols=sym_1:sym_2:sym_3:...:sym_n&begin=start_timestamp&end=end_timestamp&interval=hh:mm:ss
</em><br>
<br>
example invocation:<br>
<br>
<a href=\"data_data.py?begin=2003-03-27+14:05:57&end=2003-03-27+15:05:57&symbols=t:p:speed:dir\">
<code>data_data.py?begin=2003-03-27+14:05:57&end=2003-03-27+15:05:57&symbols=t:p:speed:dir</code></a><br>
<br>
if no end value provided, assume end = now. For example<br>
(to use this, replace below timestamp with one nearer to the present date - else you'll get a lot of data):<br>
<br>
<code>data_data.py?begin=2003-03-27+14:05:57&symbols=t:p:speed:dir</code><br>
<br>
if no begin is provided, assume it is the same as end (return one value only). Example:<br>
<br>
<a href=\"data_data.py?end=2003-03-27+15:05:57&symbols=t:p:dewpoint:accum_precip\">
<code>data_data.py?end=2003-03-27+15:05:57&symbols=t:p:dewpoint:accum_precip</code></a><br>
<br>
thus, calling with no begin OR end gives the single most recent sample.<br>
<br>
<i>NEW as of 2006-07-26:</i>
If no end is provided, but begin is of the form -hh:mm:ss, then the most recent hh hours, mm minutes
and ss seconds of data are provided.
<br>
------------- Other Options --------------------------<br>
To separate the fields in the timestamp with spaces (useful for some automated scripts),
append <code>altts=1</code> to the CGI parameter list as follows:<br>
<br>
<a href=\"data_data.py?begin=2003-04-08+23:05:57&end=2003-04-09+01:15:57&symbols=t:rp:dewpoint:accum_precip&altts=1\">
<code>data_data.py?begin=2003-04-08+23:05:57&end=2003-04-09+01:15:57&symbols=t:rp:dewpoint:accum_precip&altts=1</code></a><br>
<br>
<br>
To separate the datafields with various characters (commas, spaces, etc) as opposed to constant-width
column output,
append <code>separator=,</code> (or <code>separator=+</code>, etc..) to the CGI parameter list as follows:<br>
<br>
<a href=\"data_data.py?begin=2003-04-08+23:05:57&end=2003-04-09+01:15:57&symbols=t:rp:dewpoint:accum_precip&separator=,\">
<code>data_data.py?begin=2003-04-08+23:05:57&end=2003-04-09+01:15:57&symbols=t:rp:dewpoint:accum_precip&separator=,</code></a><br>
<br>
<br>
It's also possible to get data at intervals greater than five seconds.
To do this, specify the interval time as one of<br>
<ul>
<li><code>interval=ss</code></li>
<li><code>interval=mm:ss</code></li>
<li><code>interval=hh:mm:ss</code></li>
</ul><br>
<br>
<em>For correct operation, only specify intervals which are multiples of 5 seconds</em>. \
For example:</br>
<br>
<a href=\"data_data.py?begin=2003-03-27+14:05:57&end=2003-03-27+15:05:57&symbols=t:p:speed:dir&interval=1:00\">
<code>data_data.py?begin=2003-03-27+14:05:57&end=2003-03-27+15:05:57&symbols=t:p:speed:dir&interval=1:00</code></a><br>
<br>
will give you one sample every minute.
<br>
<br>
<em>
A list of requested symbols (click on symbol to get latest value):<br>
</em>
<br>
------------- Standard Parameters --------------------<br>
* Temperature [deg C] (
<a href="data_data.py?symbols=temperature">temperature</a> or
<a href="data_data.py?symbols=t">t</a>)<br>
* Dew Point Temperature [deg C] (
<a href="data_data.py?symbols=dewpoint">dewpoint</a> or
<a href="data_data.py?symbols=dew_point">dew_point</a> or
<a href="data_data.py?symbols=td">td</a>)<br>
* Wind Direction [degrees] (
<a href="data_data.py?symbols=direction">direction</a> or
<a href="data_data.py?symbols=dir">dir</a>)<br>
* Wind Speed [mps] (
<a href="data_data.py?symbols=speed">speed</a> or
<a href="data_data.py?symbols=spd">spd</a>)<br>
* Pressure [hPa] (
<a href="data_data.py?symbols=pressure">pressure</a> or
<a href="data_data.py?symbols=pres">pres</a> or
<a href="data_data.py?symbols=p">p</a>)<br>
* Relative Humidity [percent] (
<a href="data_data.py?symbols=relative_humidity">relative_humidity</a> or
<a href="data_data.py?symbols=rh">rh</a>)<br>
* Precipitation [inches accumulated in last 5 seconds - thus not really useful] (
<a href="data_data.py?symbols=precipitation">precipitation</a> or
<a href="data_data.py?symbols=precip">precip</a>)<br>
* Accumlated Precipitation [inches accumulated since midnight] (
<a href="data_data.py?symbols=accumulated_precipitation">accumulated_precipitation</a> or
<a href="data_data.py?symbols=accum_precip">accum_precip</a>)<br>
* Solar radiation [W / m^2] (
<a href="data_data.py?symbols=average_solar_radiation_flux">average_solar_radiation_flux</a> or
<a href="data_data.py?symbols=flux">flux</a>)<br>
<br>
---------------- Other temperatures ---------------------<br>
* Temperature at 6.3m [deg C] (
<a href="data_data.py?symbols=temperature_6.3m">temperature_6.3m</a> or
<a href="data_data.py?symbols=t_6.3m">t_6.3m</a>)<br>
* Temperature at 14.5m [deg C] (
<a href="data_data.py?symbols=temperature_14.5m">temperature_14.5m</a> or
<a href="data_data.py?symbols=t_14.5m">t_14.5m</a>)<br>
* Temperature at (unknown) [deg C] (
<a href="data_data.py?symbols=temperature_unknown">temperature_unknown</a> or
<a href="data_data.py?symbols=t_unk">t_unk</a>)<br>
<br>
---------------- Box Values --------------------<br>
* Temperature of instrument box [deg C] (
<a href="data_data.py?symbols=box_temperature">box_temperature</a> or
<a href="data_data.py?symbols=box_t">box_t</a>)<br>
* pressure of the box [hPa] (
<a href="data_data.py?symbols=box_pressure">box_pressure</a> or
<a href="data_data.py?symbols=box_p">box_p</a>)<br>
* Temperature outside box [deg C] (
<a href="data_data.py?symbols=outside_box_t">outside_box_t</a>)<br>
* Box Relative Humidity [percent] (
<a href="data_data.py?symbols=box_relative_humidity">box_relative_humidity</a> or
<a href="data_data.py?symbols=box_rh">box_rh</a>)<br>
<br>
<br>
</body></html>
"""
# routines to access data from the penthouse database
DB_SERVER = 'bora2.ssec.wisc.edu'
DB_NAME = 'rig'
DB_USER = 'rig'
METEOROLOGY_GROUP_ID=-1
ENGINEERING_GROUP_ID=-2
import pgdb
import re
# make a connection to the database
def connect():
return pgdb.connect('%s:%s:%s' % (DB_SERVER, DB_NAME, DB_USER))
# close the connection
def disconnect(con):
con.close()
# get a dataset
def get_dataset(symbol, res, start, end):
con = connect()
c = con.cursor()
c.execute("SELECT symbol_id FROM symbols WHERE name='%s'" % symbol)
symbol_id = c.fetchone()[0]
c.execute("SELECT stamp, value " +
"FROM data NATURAL JOIN samples " +
("WHERE symbol_id=%d " % symbol_id) +
("AND stamp >= '%s' AND stamp <= '%s' " % (start, end)) +
("AND resolution=%d") % res)
tmp = c.fetchall()
disconnect(con)
return tmp
# get a daraset with the specified units (not checked for errors)
def get_dataset_with_units(symbol, res, start, end, units):
con = connect()
c = con.cursor()
c.execute("SELECT symbol_id FROM symbols WHERE name='%s'" % symbol)
symbol_id = c.fetchone()[0]
c.execute(("SELECT stamp, convert_units(value, '%s') " % units) +
"FROM data NATURAL JOIN samples " +
("WHERE symbol_id=%d " % symbol_id) +
("AND stamp >= '%s' AND stamp <= '%s' " % (start, end)) +
("AND resolution=%d") % res)
tmp = c.fetchall()
disconnect(con)
return tmp
# makes a text file from a dataset - ready for gnuplot
def makefile(dataset, filename):
f = open(filename, 'w')
#dataset = map(lambda x: (x[0][0:x[0].index('.')], x[1]), dataset)
for row in dataset:
f.write(row[0] + ' ' + str(row[1]) + '\n')
return (dataset[0][0], dataset[-1][0])
# returns data for the specified symbol
def get_symbol_data(symbol):
sym_dict = {}
con = connect()
c = con.cursor()
c.execute("SELECT * FROM symbols WHERE name='%s'" % symbol)
vals = c.fetchone()
for i in range(len(c.description)):
sym_dict[c.description[i][0]] = vals[i]
disconnect(con)
return sym_dict
# gets all symbol data in a dictionary keyed by name
# dictionary entries are: (id, long name, units, description)
def get_all_symbol_data():
sym_data = {}
con = connect()
c = con.cursor()
c.execute("SELECT name, symbol_id, long_name, units, description " +
"FROM symbols")
for row in c.fetchall():
sym_data[row[0]] = tuple(row[1:])
disconnect(con)
return sym_data
# returns the names of the symbols
def get_symbol_names():
sym_list = []
con = connect()
c = con.cursor()
c.execute("SELECT s.name FROM symbols s, group_items g " +
" WHERE g.symbol_id=s.symbol_id AND g.group_id > -3" +
" ORDER BY g.group_id DESC, g.list_order")
for l in c.fetchall():
if l[0] != "TIME":
sym_list.append(l[0])
disconnect(con)
return sym_list
# returns long-name data
def get_long_names():
names = {}
con = connect()
c = con.cursor()
c.execute("SELECT name, long_name FROM symbols")
for name, long_name in c.fetchall():
names[name] = long_name
disconnect(con)
return names
# gets possible units for the given symbols
def get_alternate_units(units):
con = connect()
c = con.cursor()
c.execute("SELECT type FROM units WHERE label='%s'" % units)
type = c.fetchone()[0]
c.execute("SELECT label FROM units WHERE type='%s'" % type)
tmp = map(lambda x: x[0], c.fetchall())
disconnect(con)
return tmp
# returns the names of the symbols for meteorology
def get_met_symbol_names():
return get_group_symbol_names(METEOROLOGY_GROUP_ID)
# returns the names of the symbols for engineering sensors
def get_eng_symbol_names():
return get_group_symbol_names(ENGINEERING_GROUP_ID)
def get_group_symbol_names(gid):
sym_list = []
con = connect()
c = con.cursor()
c.execute("SELECT s.name FROM symbols s, group_items g " +
" WHERE g.symbol_id=s.symbol_id AND g.group_id=%d" % gid +
" ORDER BY g.list_order")
for l in c.fetchall():
if l[0] != "TIME":
sym_list.append(l[0])
disconnect(con)
return sym_list
# returns units data
def get_units():
units_dict = {}
con = connect()
c = con.cursor()
c.execute("SELECT name, units FROM symbols")
for name, units in c.fetchall():
units_dict[name] = units
disconnect(con)
return units_dict
# returns current conditions tuple: (time_stamp, value_dict)
def get_current_conds():
data = {}
con = connect()
c = con.cursor()
c.execute("SELECT sample_id, stamp FROM samples WHERE resolution=60 " +
"ORDER BY stamp DESC LIMIT 1")
sample_id, stamp = tuple(c.fetchone())
c.execute("SELECT symbol_id, value from data WHERE sample_id=%d" %
sample_id)
for row in c.fetchall():
data[row[0]] = row[1]
disconnect(con)
return (stamp, data)
# returns a dictionary with global values
def get_globals():
gd = {}
con = connect()
c = con.cursor()
c.execute('SELECT * FROM globals')
vals = c.fetchone()
for i in range(len(c.description)):
gd[c.description[i][0]] = vals[i]
disconnect(con)
return gd
# Functions for calculating the dewpoint.
# $Id: dewpoint.py,v 1.1 2003/04/16 19:38:48 maciek Exp $
import math
def dewpoint(tempC, relhum):
""" algorithm from Tom Whittaker
tempC is the temperature in degrees Celsius,
relhum is the relative humidity as a percentage"""
gasconst = 461.5
latheat = 2500800.0
dp = 1.0 / ( 1.0 / ( 273.15 + tempC ) - gasconst * math.log( (0.0 + relhum) / 100 ) / \
( latheat - tempC * 2397.5 ))
return min(dp - 273.15, tempC)
def awips_dewpoint(tempC, relhum):
""" algorithm taken from http://meted.ucar.edu/awips/validate/dewpnt.htm
tempC is the temperature in degrees Celsius,
relhum is the relative humidity as a percentage"""
C15 = 26.66082
C1 = 0.0091379024
C2 = 6106.396
C3 = 223.1986
C4 = 0.0182758048
t = tempC + 273.15 # convert temperature to Kelvin
rh = relhum / 100 # convert relative humidity to ratio
es = math.exp( C15 - C1 * t - C2 / t ) # saturation vapor pressure
e = rh * es
b = C15 - math.log(e)
td = ( b - math.sqrt( b * b - C3 ) ) / C4
return min(td - 273.15, tempC)
#!/var/www/wsgi/python-env/metobs/bin/python
"""List available EyeQ Camera images.
See `print_usage()` for more information
"""
import cgi
import cgitb; cgitb.enable()
import os
import sys
from datetime import datetime
from datetime import timedelta
from metobs import mytime
form = cgi.FieldStorage()
def get(name, default=None):
if form.has_key(name):
return form[name].value
return default
def print_usage():
print "ContentType: text/plain"
print
print """Provides image listings of SSEC RIG EyeQ Camera images.
Because the images may not be exactly spaced, being that processing may increase
the interval, images are listed by searching between the date provided and that
date plus the image resolution.
Parameters
==========
cam - (required) Camera name. West, East, etc ...
d - Date of image in CST (YYYY-MM-DD HH:MM:SS). Defaults to current time.
"""
#: resolution at which images are generated
image_rez = 10
#: timezone for image filename times
image_tz = mytime.OffsetTimezone(6)
hostname = 'tahiti.ssec.wisc.edu'
#: convert a file path to a server path`
url_for = lambda fpth: "http://"+hostname+fpth.replace("/beach", "/pub")
def image_path(cam, dt):
"""Get a path for an image on disk.
:param cam: Name of the camera
:param dt: datetime of the image file used to parse the name
"""
basedir = '/beach/incoming/Instrument_Data/METOBS/RIG/Cameras'
return os.path.join(basedir, cam + dt.strftime('/%Y/%m/%d/%H_%M_%S.trig+00.jpg'))
#
#
# You shouldn't need to change anything below here
#
#
def redirect_to(url):
print "Status: 302 Moved"
print "Location: " + url
print
def file_not_found():
print "Status: 404 File Not Found"
print
def headers(typ='plain'):
print "ContentType: text/" + typ
print
def main():
# required parameter
camera = get('cam')
if not camera:
print_usage()
return 1
# parse data from parameter, defaulting to current time in the
# timezone specified
date = get('d')
if not date:
date = mytime.utc_now()
date = mytime.set_tz(date, tz=image_tz)
else:
date = mytime.parse_stamp(date)
date = mytime.set_tz(date, tz=image_tz)
# images may not be exactly the same interval appart, therefore we have
# to attempt to locate the image
url = ""
pths = []
for i in range(image_rez):
fpth = image_path(camera, date + timedelta(seconds=i))
pths.append(fpth)
if os.path.exists(fpth):
url = url_for(fpth)
break
# successfully found an image
if url:
redirect_to(url)
if form.has_key('debug'):
headers()
for pth in pths:
print pth
return 1
# we should only get here if the file was not found
file_not_found()
return 1
sys.exit(main())
#!/usr/bin/env python2
#
# Creates the SYMBOLS file which is used by the graphing applet
import re
import pgdb
DB_SERVER = 'bora2.ssec.wisc.edu'
DB_NAME = 'rig'
DB_USER = 'rig'
OUTPUT_FILE = '/home/brucef/public_html/rig_old/SYMBOLS'
if __name__ == '__main__':
output = open(OUTPUT_FILE, 'w')
con = pgdb.connect('%s:%s:%s' % (DB_SERVER, DB_NAME, DB_USER))
c = con.cursor()
c.execute("SELECT name, long_name, units FROM symbol")
for l in c.fetchall():
# symbol name
output.write(l[0] + ' ')
# long name
output.write(re.sub(' ', '+', l[1]) + ' ')
# units
output.write(re.sub(' ', '+', l[2]) + '\n')
#!/bin/ksh
echo "hello world"
#!/var/www/wsgi/python-env/metobs/bin/python
import cgi
# FOR DEBUG ONLY !!!!!
#import cgitb; cgitb.enable()
import sqlalchemy as sa
from sqlalchemy import orm
from metobs.data import *
from metobs import db, mytime
TXT = """ UW Lake Mendota Buoy
====================
As of: %(stamp)s
Atmosphere
-----------
Wind Dir: %(dir)d deg (%(dir2)s)
Wind Spd: %(spd).1f m/s (%(spd2).1f knts)
Air Temp: %(temp).1f degC (%(temp2).1f degF)
Water Temperature
-----------------
Surface %(surface).1f degC (%(surface2).1f degF)
-1m %(wt1).1f degC (%(wt1-2).1f degF)
-5m %(wt5).1f degC (%(wt5-2).1f degF)
-10m %(wt10).1f degC (%(wt10-2).1f degF)
-15m %(wt15).1f degC (%(wt15-2).1f degF)
-20m %(wt20).1f degC (%(wt20-2).1f degF)
"""
ERR_TXT = """
An Error Occured: Request could not be completed
"""
symbols = [
'WIND_DIRECTION_2.0',
'WIND_SPEED_2.0',
'AIR_TEMP',
'WATER_TEMP_0.0',
'WATER_TEMP_1.0',
'WATER_TEMP_5.0',
'WATER_TEMP_10.0',
'WATER_TEMP_15.0',
'WATER_TEMP_20.0']
def main():
form = cgi.FieldStorage()
try:
eng = sa.create_engine('postgres://buoy:vyit@tahiti.ssec.wisc.edu/buoy')
session = orm.create_session(bind=eng)
db.init_model()
station = session.query(db.Station, db.Station.name=='Mendota Buoy').one()[0]
tmp_syms = dict((s.name, s) for s in station.symbols)
qry_syms = [tmp_syms[s] for s in symbols]
stamp = db.max_stamp(session, station)
print stamp
data = db.get_slice(session, station, stamp, symbols=qry_syms)[1][-1]
stamp = stamp.astimezone(mytime.OffsetTimezone(6))
txt = TXT % {
'stamp':stamp.strftime('%Y-%m-%d %H:%M:%S CST'),
'dir':data[0], 'dir2':dir2txt(data[0]),
'spd':data[1], 'spd2':mps2knots(data[1]),
'temp':data[2], 'temp2':c2f(data[2]),
'surface':data[3], 'surface2':c2f(data[3]),
'wt1':data[4], 'wt1-2':c2f(data[4]),
'wt5':data[5], 'wt5-2':c2f(data[5]),
'wt10':data[6], 'wt10-2':c2f(data[6]),
'wt15':data[7], 'wt15-2':c2f(data[7]),
'wt20':data[8], 'wt20-2':c2f(data[8])}
except Exception, e:
txt = ERR_TXT
raise e
print "Content-Type: text/plain; charset=UTF-8"
print "Refresh: 120"
print "Cache-control: private, no-cache"
print "Expires: Thu, 1 Aug 2002 12:23:00 GMT"
print "Pragma: no-cache"
print
print txt
if __name__ == '__main__':
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment