MIT -> ISC
[infoex-autowx.git] / infoex-autowx.py
index f951c0d426355a4620b8eb6673fc5a31c8f4a30f..a4e50a931f2fc9324174a3d9875441b6889833d4 100755 (executable)
@@ -1,37 +1,42 @@
-#!/usr/bin/python3
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
 
 
-#
-# InfoEx <-> NRCS Auto Wx implementation
-# Alexander Vasarab
-# Wylark Mountaineering LLC
-# 2020-04-22
-#
-# Version 0.8
-#
-# This program fetches data from an NRCS SNOTEL site and pushes it to
-# InfoEx using the new automated weather system implementation.
-#
-# It is designed to be run hourly, and it asks for the last three hours
-# of data of each desired type, and selects the most recent one. This
-# lends some resiliency to the process and helps ensure that we have a
-# value to send, but it can lead to somewhat inconsistent/untruthful
-# data if e.g. the HS is from the last hour but the tempPres is from two
-# hours ago because the instrumentation had a hiccup. It's worth
-# considering if this is a bug or a feature.
-#
+"""
+InfoEx <-> NRCS Auto Wx implementation
+Alexander Vasarab
+Wylark Mountaineering LLC
+
+Version 1.0.0
+
+This program fetches data from an NRCS SNOTEL site and pushes it to
+InfoEx using the new automated weather system implementation.
+
+It is designed to be run hourly, and it asks for the last three hours
+of data of each desired type, and selects the most recent one. This
+lends some resiliency to the process and helps ensure that we have a
+value to send, but it can lead to somewhat inconsistent/untruthful
+data if e.g. the HS is from the last hour but the tempPres is from two
+hours ago because the instrumentation had a hiccup. It's worth
+considering if this is a bug or a feature.
+
+For more information, see file: README
+For licensing, see file: LICENSE
+"""
 
 import configparser
 import csv
 import datetime
 import logging
 import time
 
 import configparser
 import csv
 import datetime
 import logging
 import time
-import zeep
-import zeep.cache
-import zeep.transports
+
 from collections import OrderedDict
 from ftplib import FTP
 from optparse import OptionParser
 
 from collections import OrderedDict
 from ftplib import FTP
 from optparse import OptionParser
 
+import zeep
+import zeep.cache
+import zeep.transports
+
 log = logging.getLogger(__name__)
 log.setLevel(logging.DEBUG)
 
 log = logging.getLogger(__name__)
 log.setLevel(logging.DEBUG)
 
@@ -61,7 +66,7 @@ try:
         'uuid': config['ftp']['uuid'],
         'api_key': config['ftp']['api_key'],
         'location_uuid': config['wxsite']['location_uuid'],
         'uuid': config['ftp']['uuid'],
         'api_key': config['ftp']['api_key'],
         'location_uuid': config['wxsite']['location_uuid'],
-        'wx_data': {},
+        'wx_data': {}, # placeholder key, values to come later
         'csv_filename': config['wxsite']['csv_filename']
     }
 
         'csv_filename': config['wxsite']['csv_filename']
     }
 
@@ -172,6 +177,10 @@ for elementCd in desired_data:
     values = tmp[0]['values']
 
     # sort and isolate the most recent
     values = tmp[0]['values']
 
     # sort and isolate the most recent
+    #
+    # NOTE: we do this because sometimes there are gaps in hourly data
+    #       in NRCS; yes, we may end up with slightly inaccurate data,
+    #       so perhaps this decision will be re-evaluated in the future
     if values:
         ordered = sorted(values, key=lambda t: t['dateTime'], reverse=True)
         infoex['wx_data'][elementCd] = ordered[0]['value']
     if values:
         ordered = sorted(values, key=lambda t: t['dateTime'], reverse=True)
         infoex['wx_data'][elementCd] = ordered[0]['value']
@@ -183,16 +192,12 @@ log.info("Time to get all elementCds : %.3f sec" % (time.time() -
 
 log.debug("infoex[wx_data]: %s", str(infoex['wx_data']))
 
 
 log.debug("infoex[wx_data]: %s", str(infoex['wx_data']))
 
-# Only need to add in what we want to change thanks to that abomination
-# of a variable declaration earlier
+# Now we only need to add in what we want to change thanks to that
+# abomination of a variable declaration earlier
 final_data[fmap['Location UUID']] = infoex['location_uuid']
 final_data[fmap['obDate']] = end_date.strftime('%m/%d/%Y')
 final_data[fmap['obTime']] = end_date.strftime('%H:%M')
 
 final_data[fmap['Location UUID']] = infoex['location_uuid']
 final_data[fmap['obDate']] = end_date.strftime('%m/%d/%Y')
 final_data[fmap['obTime']] = end_date.strftime('%H:%M')
 
-#final_data[fmap['tempPres']] = float(infoex['wx_data']['TOBS'])
-#final_data[fmap['precipitationGauge']] = float(infoex['wx_data']['PREC'])
-#final_data[fmap['hS']] = float(infoex['wx_data']['SNWD'])
-
 for elementCd in infoex['wx_data']:
     if elementCd not in iemap:
         log.warning("BAD KEY wx_data['%s']" % (elementCd))
 for elementCd in infoex['wx_data']:
     if elementCd not in iemap:
         log.warning("BAD KEY wx_data['%s']" % (elementCd))