From 26bb445bcf1d2d1f2889e290e6a87b013fec60f6 Mon Sep 17 00:00:00 2001 From: Alexander Vasarab Date: Mon, 15 Nov 2021 20:12:48 -0800 Subject: [PATCH] Finish HN24/wind averaging implementation --- infoex-autowx.py | 91 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 6 deletions(-) diff --git a/infoex-autowx.py b/infoex-autowx.py index 2b7880e..e584933 100755 --- a/infoex-autowx.py +++ b/infoex-autowx.py @@ -328,7 +328,8 @@ def main(): # Avoid transforming None values if element_cd in ['wind_speed', 'WSPD', 'wind_direction', 'RHUM', 'relative_humidity', 'WDIR', - 'wind_gust', 'SNWD', 'snow_depth']: + 'wind_gust', 'SNWD', 'snow_depth', + 'hn24']: infoex['wx_data'][element_cd] = round(infoex['wx_data'][element_cd]) elif element_cd in ['TOBS', 'air_temp', 'PRES', 'pressure']: infoex['wx_data'][element_cd] = round(infoex['wx_data'][element_cd], 1) @@ -440,6 +441,10 @@ def setup_infoex_counterparts_mapping(provider): iemap['wind_speed'] = 'windSpeedNum' iemap['wind_direction'] = 'windDirectionNum' iemap['wind_gust'] = 'windGustSpeedNum' + + # NOTE: this doesn't exist in MesoWest, we create it in this + # program, so add it to the map here + iemap['hn24'] = 'hn24Auto' elif provider == 'python': # we expect Python programs to use the InfoEx data type names iemap['precipitationGauge'] = 'precipitationGauge' @@ -536,8 +541,21 @@ def get_mesowest_data(begin, end, station): LOG.error("Bad JSON in MesoWest response: '%s'", exc) sys.exit(1) + # pos represents the last item in the array, aka the most recent pos = len(observations['date_time']) - 1 + # while these values only apply in certain cases, init them here + wind_speed_values = [] + wind_gust_speed_values = [] + wind_direction_values = [] + hn24_values = [] + + # results + wind_speed_avg = None + wind_gust_speed_avg = None + wind_direction_avg = None + hn24 = None + for element_cd in station['desired_data'].split(','): # sort and isolate the most recent, see note above in NRCS for how and # why this is done @@ -556,23 +574,84 @@ def get_mesowest_data(begin, end, station): key_name = element_cd + '_set_1' if key_name in observations: - if observations[key_name][pos]: - remote_data[element_cd] = observations[key_name][pos] + # val is what will make it into the dataset, after + # conversions... it gets defined here because in certain + # cases we need to look at all of the data to calculate HN24 + # or wind averages, but for the rest of the data, we only + # take the most recent + val = None + + # loop through all observations for this key_name + # record relevant values for wind averaging or hn24, but + # otherwise only persist the data if it's the last datum in + # the set + for idx, _ in enumerate(observations[key_name]): + val = observations[key_name][idx] + + # skip bunk vals + if val is None: + continue # mesowest by default provides wind_speed in m/s, but # we specify 'english' units in the request; either way, # we want mph if element_cd in ('wind_speed', 'wind_gust'): - remote_data[element_cd] = kn_to_mph(remote_data[element_cd]) + val = kn_to_mph(val) # mesowest provides HS in mm, not cm; we want cm if element_cd == 'snow_depth' and station['units'] == 'metric': - remote_data[element_cd] = mm_to_cm(remote_data[element_cd]) - else: + val = mm_to_cm(val) + + # HN24 / wind_mode transformations, once the data has + # completed unit conversions + if station['wind_mode'] == "average": + if element_cd == 'wind_speed' and val is not None: + wind_speed_values.append(val) + elif element_cd == 'wind_gust' and val is not None: + wind_gust_speed_values.append(val) + elif element_cd == 'wind_direction' and val is not None: + wind_direction_values.append(val) + + if element_cd == 'snow_depth': + hn24_values.append(val) + + # again, only persist this datum to the final data if + # it's from the most recent date + if idx == pos: + remote_data[element_cd] = val + + # ensure that the data is filled out + if not observations[key_name][pos]: remote_data[element_cd] = None else: remote_data[element_cd] = None + if len(hn24_values) > 0: + hn24 = max(hn24_values) - min(hn24_values) + + if len(wind_speed_values) > 0: + wind_speed_avg = sum(wind_speed_values) / len(wind_speed_values) + + if len(wind_gust_speed_values) > 0: + wind_gust_speed_avg = sum(wind_gust_speed_values) / len(wind_gust_speed_values) + + if len(wind_direction_values) > 0: + wind_direction_avg = sum(wind_direction_values) / len(wind_direction_values) + + if hn24 is not None: + remote_data['hn24'] = hn24 + + # overwrite the following with the respective averages, if + # applicable + if wind_speed_avg is not None: + remote_data['wind_speed'] = wind_speed_avg + + if wind_gust_speed_avg is not None: + remote_data['wind_gust'] = wind_gust_speed_avg + + if wind_direction_avg is not None: + remote_data['wind_direction'] = wind_direction_avg + return remote_data def switch_units_to_metric(data_map, mapping): -- 2.30.2