Newer
Older
# coding=utf-8
from datetime import datetime, timedelta
import numpy
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
symbols = {
'TIME': {'type': numpy.int32},
'ACCURAIN': {'type': numpy.float32},
}
class LineParseError(BaseException):
"""Error parsing line of record data.
"""
@classmethod
def raise_wrapped(cls, exception, msg=None):
import sys
traceback = sys.exc_info()[2]
msg = msg or str(exception)
raise cls(msg), None, traceback
def parse_v0_record(line):
"""
Key/Value (Before June 2 2012)
==============================
TIME: Seconds since Jan 1, 1970
ACCURAIN: Accumulated precipitation (mm)
TEMP107_4: Auxillary temperature*
LI200X: Solar Flux (w/m^2)
TEMP107_1: Box temperature*
RH41372: Relative humidity (%)
TEMP107_5: Auxillary temperature*
CS105: Box pressure*
PAROSCI: Pressure (hPa)
WSPD05305: Wind speed (m/s)
TEMP107_3: Axullary temperature*
CS10162: Box relative humidity*
RAIN380M: Precipitation (0.01in)
TEMP107_2: Outside box temperature*
TEMP41372: Air temperature (ºC)
WDIR05305: Wind direction (degrees)
"""
parts = line.split()
if len(parts) != 32:
msg = "Expected 32 line parts, got {:d}".format(len(parts))
raise LineParseError(msg)
raw_data = {k: v for k, v in zip(parts[0::2], parts[1::2])}
time_str = raw_data['TIME']
try:
unix_time = int(time_str)
except ValueError as err:
msg = "Could not parse unix time from {}".format(time_str)
LineParseError.raise_wrapped(err, msg)
else:
stamp = datetime.utcfromtimestamp(unix_time)
return stamp, raw_data
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
class RecordV1(dict):
"""
CSV (June 2 2012 to ...)
============================
StationId*
Year
Day of year
HourMinute
Seconds
Box Presure*
ParoSci Air Temperature period*
ParoSci Pressure period*
ParoSci Air Temperature*
Pressure (hPa)
ParoSci Calc. Sig.*
Box relative humidity*
Box air temperature*
Auxillary Air Temp2*
Auxillary Air Temp3*
Auxillary Air Temp4*
Wind Speed (m/s)
Wind Direction (degrees)
RH Shield Freq.*
Relative Humidity (%)
Air Temperature 6.3m (ºC)
Dewpoint (ºC)
RTD Shield Freq.*
Air temperature (ºC)
Solar Flux (w/m^s)
Precipitation (.01in)
Acumulated Precip (mm) *reset at 0z
Altimeter (inHg)
"""
names = ['station_id', 'year', 'doy', 'hhmm', 'sec', 'box_pressure',
'paro_air_temp_period', 'paro_pressure_period', 'paro_air_temp',
'pressure', 'paro_cal_sig', 'box_rh', 'box_air_temp',
'air_temp_2', 'air_temp_3', 'air_temp_4', 'wind_speed', 'wind_dir',
'rh_shield_freq', 'rh', 'air_temp_6-3m', 'dewpoint',
'rtd_shield_freq', 'air_temp', 'solar_flux', 'precip',
'accum_precip', 'altimeter']
def __init__(self, line):
super(self.__class__, self).__init__()
parts = line.split(',')
if len(parts) != 29:
raise LineParseError("Expected 29 parts, got {:d}".format(len(parts)))
self.update({k: v for k, v in zip(self.names, parts)})
def __getattr__(self, name, default=None):
return self.get(name, default)
def get_stamp(self):
year = int(self['year'])
doy = int(self['doy'])
dt = datetime.strptime('{:d}.{:03d}'.format(int(year), int(doy)), '%Y.%j')
secs += float(self['sec'])
secs -= (secs % 5)
dt += timedelta(seconds=secs)
return dt