Skip to content
Snippets Groups Projects
Commit 73bbc660 authored by Bruce Flynn's avatar Bruce Flynn
Browse files

Few more small fixes.

parent fcabd10f
No related branches found
No related tags found
No related merge requests found
from collections import OrderedDict import os
from datetime import datetime, timedelta from datetime import datetime, timedelta
import rrdtool import rrdtool
import numpy as np import numpy as np
from .time import to_unix_timestamp from .time import to_unix_timestamp
from .wind import mean_wind_vector_degrees from .wind import wind_vector_degrees
def dewpoint(tempC, relhum): def dewpoint(tempC, relhum):
...@@ -19,23 +19,39 @@ def dewpoint(tempC, relhum): ...@@ -19,23 +19,39 @@ def dewpoint(tempC, relhum):
gasconst = 461.5 gasconst = 461.5
latheat = 2500800.0 latheat = 2500800.0
dp = (1.0 / (1.0 / (273.15 + tempC) dp = (1.0 / (1.0 / (273.15 + tempC) - gasconst * np.log((0.0 + relhum) / 100) / (latheat - tempC * 2397.5)))
- gasconst * np.log((0.0 + relhum) / 100) / (latheat - tempC * 2397.5)))
return np.minimum(dp - 273.15, tempC) return np.minimum(dp - 273.15, tempC)
class RrdModel(object): class RrdModel(object):
keys = ['air_temp', 'rh', 'dewpoint', keys = ('air_temp', 'rh', 'dewpoint',
'wind_speed', 'winddir_north', 'winddir_east', 'wind_speed', 'winddir_north', 'winddir_east',
'pressure', 'precip', 'accum_precip', 'solar_flux', 'pressure', 'precip', 'accum_precip', 'solar_flux',
'altimeter'] 'altimeter')
def __init__(self, filepath): def __init__(self, filepath):
self._filepath = filepath self._filepath = filepath
self._averages = tuple()
@property
def averaging_intervals(self):
"""Lazy load averaging intervals from database.
"""
if not self._averages:
averages = []
info = rrdtool.info(self._filepath)
for key in info.keys():
if key.startswith('rra') and key.endswith('pdp_per_row'):
averages.append(int(info[key]*info['step']))
averages.sort()
self._averages = tuple(averages)
return self._averages
def initialize(self, start=None): def initialize(self, start=None):
assert not os.path.exists(self._filepath)
start = start or datetime.now() - timedelta(days=365) start = start or datetime.now() - timedelta(days=365)
secs = to_unix_timestamp(start) secs = to_unix_timestamp(start)
rrdtool.create(self._filepath, rrdtool.create(self._filepath,
...@@ -63,8 +79,17 @@ class RrdModel(object): ...@@ -63,8 +79,17 @@ class RrdModel(object):
values = '{:d}:{}'.format(to_unix_timestamp(stamp), values) values = '{:d}:{}'.format(to_unix_timestamp(stamp), values)
print values print values
def add_record(self, record):
pass
def get_slice(self, start, end, names=None, average=5): def get_slice(self, start, end, names=None, average=5):
"""Get a slice of data from the database.
:param start: Start time as datetime
:param end: Inclusive end time as datetime
:param names: Names to query for, defaults to all available, see ``keys``
:param average: Averaging interval supported by the database, see ``averaging_intervals``.
"""
names = names or self.keys[:] names = names or self.keys[:]
if isinstance(start, datetime): if isinstance(start, datetime):
...@@ -100,7 +125,7 @@ class RrdModel(object): ...@@ -100,7 +125,7 @@ class RrdModel(object):
elif name == 'wind_dir': elif name == 'wind_dir':
east = src_data[:,self.keys.index('winddir_east')].astype(np.float64) east = src_data[:,self.keys.index('winddir_east')].astype(np.float64)
north = src_data[:,self.keys.index('winddir_north')].astype(np.float64) north = src_data[:,self.keys.index('winddir_north')].astype(np.float64)
dst_data[:,dst_idx] = mean_wind_vector_degrees(east, north) dst_data[:,dst_idx] = wind_vector_degrees(east, north)
times = np.array([np.arange(start, end + average, average)]) times = np.array([np.arange(start, end + average, average)])
return np.concatenate((times.T, dst_data), axis=1) return np.concatenate((times.T, dst_data), axis=1)
......
...@@ -3,7 +3,7 @@ from datetime import datetime, timedelta ...@@ -3,7 +3,7 @@ from datetime import datetime, timedelta
import numpy import numpy
from .time import hhmm_to_secs from .time import hhmm_to_offset
symbols = { symbols = {
'TIME': {'type': numpy.int32}, 'TIME': {'type': numpy.int32},
...@@ -47,15 +47,16 @@ def parse_v0_record(line): ...@@ -47,15 +47,16 @@ def parse_v0_record(line):
if len(parts) != 32: if len(parts) != 32:
msg = "Expected 32 line parts, got {:d}".format(len(parts)) msg = "Expected 32 line parts, got {:d}".format(len(parts))
raise LineParseError(msg) raise LineParseError(msg)
raw_data = {k:v for k, v in zip(parts[0::2], parts[1::2])} raw_data = {k: v for k, v in zip(parts[0::2], parts[1::2])}
time_str = raw_data['TIME'] time_str = raw_data['TIME']
try: try:
unix_time = int(time_str) unix_time = int(time_str)
except ValueError as err: except ValueError as err:
msg = "Could not parse unix time from {}".format(time_str) msg = "Could not parse unix time from {}".format(time_str)
LineParseError.raise_wrapped(err, msg) LineParseError.raise_wrapped(err, msg)
stamp = datetime.utcfromtimestamp(unix_time) else:
return stamp, raw_data stamp = datetime.utcfromtimestamp(unix_time)
return stamp, raw_data
class RecordV1(dict): class RecordV1(dict):
...@@ -113,7 +114,7 @@ class RecordV1(dict): ...@@ -113,7 +114,7 @@ class RecordV1(dict):
year = int(self['year']) year = int(self['year'])
doy = int(self['doy']) doy = int(self['doy'])
dt = datetime.strptime('{:d}.{:03d}'.format(int(year), int(doy)), '%Y.%j') dt = datetime.strptime('{:d}.{:03d}'.format(int(year), int(doy)), '%Y.%j')
secs = hhmm_to_secs(self['hhmm']) secs = hhmm_to_offset(self['hhmm'])
secs += float(self['sec']) secs += float(self['sec'])
secs -= (secs % 5) secs -= (secs % 5)
dt += timedelta(seconds=secs) dt += timedelta(seconds=secs)
......
...@@ -7,9 +7,9 @@ def test_to_unix_timestamp(): ...@@ -7,9 +7,9 @@ def test_to_unix_timestamp():
def test_hhmm_to_secs(): def test_hhmm_to_secs():
from aosstower.time import hhmm_to_secs from aosstower.time import hhmm_to_offset
assert hhmm_to_secs('2400') == 86400, "Can't handle > 23:59" assert hhmm_to_offset('2400') == 86400, "Can't handle > 23:59"
assert hhmm_to_secs('2401') == 86460, "Can't handle > 23:59" assert hhmm_to_offset('2401') == 86460, "Can't handle > 23:59"
assert hhmm_to_secs('0') == 0, "Can't handle short times" assert hhmm_to_offset('0') == 0, "Can't handle short times"
assert hhmm_to_secs('001') == 60, "Can't handle leading 0" assert hhmm_to_offset('001') == 60, "Can't handle leading 0"
...@@ -7,8 +7,10 @@ def to_unix_timestamp(dt): ...@@ -7,8 +7,10 @@ def to_unix_timestamp(dt):
return int(timegm(dt.utctimetuple())) return int(timegm(dt.utctimetuple()))
def hhmm_to_secs(hhmm): def hhmm_to_offset(hhmm):
val = int(hhmm) """Convert a string time, possibly with missing hours and minutes, to an
offset of seconds.
"""
hhmm = '{:04d}'.format(int(hhmm)) hhmm = '{:04d}'.format(int(hhmm))
return timedelta(hours=int(hhmm[0:2]), return timedelta(hours=int(hhmm[0:2]),
minutes=int(hhmm[2:])).total_seconds() minutes=int(hhmm[2:])).total_seconds()
...@@ -33,7 +33,7 @@ if __name__ == '__main__': ...@@ -33,7 +33,7 @@ if __name__ == '__main__':
windspd = float(record['wind_speed']) windspd = float(record['wind_speed'])
winddir = float(record['wind_dir']) winddir = float(record['wind_dir'])
u_e, u_n, spd = wind.mean_wind_vector_components(windspd, winddir) u_e, u_n, spd = wind.wind_vector_components(windspd, winddir)
record['winddir_east'] = u_e record['winddir_east'] = u_e
record['winddir_north'] = u_n record['winddir_north'] = u_n
record['wind_speed'] = spd record['wind_speed'] = spd
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment