import zeep.cache
import zeep.transports
+__version__ = '2.0.0'
+
log = logging.getLogger(__name__)
-log.setLevel(logging.DEBUG)
+log.setLevel(logging.NOTSET)
try:
from systemd.journal import JournalHandler
handler = logging.StreamHandler(sys.stdout)
log.addHandler(handler)
-parser = OptionParser()
+parser = OptionParser(version=__version__)
parser.add_option("--config",
dest="config",
metavar="FILE",
help="location of config file")
+parser.add_option("--log-level",
+ dest="log_level",
+ default=None,
+ help="set the log level (debug, info, warning)")
+
parser.add_option("--dry-run",
action="store_true",
dest="dry_run",
config = configparser.ConfigParser(allow_no_value=False)
if not options.config:
- print("Please specify a configuration file via --config.")
+ parser.print_help()
+ print("\nPlease specify a configuration file via --config.")
sys.exit(1)
config.read(options.config)
+# ugly, but passable
+if options.log_level in [None, 'debug', 'info', 'warning']:
+ if options.log_level == 'debug':
+ log.setLevel(logging.DEBUG)
+ elif options.log_level == 'info':
+ log.setLevel(logging.INFO)
+ elif options.log_level == 'warning':
+ log.setLevel(logging.WARNING)
+ else:
+ log.setLevel(logging.NOTSET)
+else:
+ parser.print_help()
+ print("\nPlease select an appropriate log level or remove the switch (--log-level).")
+ sys.exit(1)
+
log.debug('STARTING UP')
try:
'PREC' # PRECIPITATION ACCUMULATION (in)
]
+ # XXX: For NRCS, we're manually overriding units for now! Once
+ # unit conversion is supported for NRCS, REMOVE THIS!
+ if 'units' not in data:
+ data['units'] = 'imperial'
+
if data['provider'] == 'mesowest':
data['source'] = 'https://api.synopticdata.com/v2/stations/timeseries'
data['station_id'] = config['station']['station_id']
#
# Also note that the current Auto Wx InfoEx documentation shows these
# keys in a graphical table with the "index" beginning at 1, but here we
-# are sanely indexing beginning at 0.
+# sanely index beginning at 0.
fmap = {} ; final_data = [None] * 29
fmap['Location UUID'] = 0 ; final_data[0] = infoex['location_uuid']
fmap['obDate'] = 1 ; final_data[1] = None
iemap['PREC'] = 'precipitationGauge'
iemap['TOBS'] = 'tempPres'
iemap['SNWD'] = 'hS'
+ iemap['PRES'] = 'baro'
+ iemap['RHUM'] = 'rH'
+ iemap['WSPD'] = 'windSpeedNum'
+ iemap['WDIR'] = 'windDirectionNum'
+ # unsupported by NRCS:
+ # windGustSpeedNum
elif data['provider'] == 'mesowest':
iemap['precip_accum'] = 'precipitationGauge'
iemap['air_temp'] = 'tempPres'
iemap['snow_depth'] = 'hS'
+ iemap['pressure'] = 'baro'
+ iemap['relative_humidity'] = 'rH'
+ iemap['wind_speed'] = 'windSpeedNum'
+ iemap['wind_direction'] = 'windDirectionNum'
+ iemap['wind_gust'] = 'windGustSpeedNum'
+
+# override units if user selected metric
+#
+# NOTE: to update this, use the fmap<->final_data mapping laid out above
+#
+# NOTE: this only 'works' with MesoWest for now, as the MesoWest API
+# itself handles the unit conversion; in the future, we will also
+# support NRCS unit conversion, but this must be done by this
+# program.
+if data['units'] == 'metric':
+ final_data[fmap['tempPresUnit']] = 'C'
+ final_data[fmap['hsUnit']] = 'm'
+ final_data[fmap['windSpeedUnit']] = 'm/s'
+ final_data[fmap['windGustSpeedNumUnit']] = 'm/s'
# floor time to nearest hour
dt = datetime.datetime.now()
# sort and isolate the most recent, see note above in NRCS for how and
# why this is done
#
- # NOTE: Unlike in the NRCS case, the MesoWest API respones contains all
+ # NOTE: Unlike in the NRCS case, the MesoWest API response contains all
# data (whereas with NRCS, we have to make a separate request for
- # each element we want. This is nice for network efficiency but
+ # each element we want). This is nice for network efficiency but
# it means we have to handle this part differently for each.
#
# NOTE: Also unlike NRCS, MesoWest provides more granular data; NRCS
# any possible elementCds we may want are any other data
# type than float.
#
- # Another possibility is to query the API with
+ # Another possibility is to query the API with
# getStationElements and temporarily store the
# storedUnitCd. But that's pretty network-intensive and
# may not even be worth it if there's only e.g. one or two
f.close()
if not options.dry_run:
- # not a dry run
with open(infoex['csv_filename'], 'rb') as f:
log.debug("uploading FTP file '%s'" % (infoex['host']))
ftp = FTP(infoex['host'], infoex['uuid'], infoex['api_key'])