From 255b22ffc06b6da0e0f96851fea2947ea8bd82ee Mon Sep 17 00:00:00 2001 From: Mikkel Pedersen Date: Thu, 18 Jun 2026 14:40:49 +0200 Subject: [PATCH 1/2] fix(wea): Add EPW/Wea handler that returns the original object as a path The difference between this the existing handler is that if the input is an EPW file it will return the EPW file while still making the checks for timestep and is_annual. --- pollination_handlers/inputs/wea.py | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/pollination_handlers/inputs/wea.py b/pollination_handlers/inputs/wea.py index f23874b..be26936 100644 --- a/pollination_handlers/inputs/wea.py +++ b/pollination_handlers/inputs/wea.py @@ -91,3 +91,47 @@ def _wea_file_name(wea_obj): dts = (DateTime(1, 1, 0), DateTime(12, 11, 23)) wea_obj.location.city = ''.join(i for i in wea_obj.location.city if ord(i) < 128) return '{}_{}_{}'.format(wea_obj.location.city, dts[0].int_hoy, dts[-1].int_hoy) + + +def epw_or_wea_handler_timestep_annual_check(wea_obj): + """Translate an EPW or Wea object to check annual/timestep criteria, + but return the original input object/path, e.g., if the input is a path to + an epw file, return that path after checking the criteria. + + Args: + wea_obj: Either a Wea python object, an EPW object, or the path to a + wea or an epw file. + + Returns: + Either a EPW or Wea file. + """ + if isinstance(wea_obj, str): + if not os.path.isfile(wea_obj): + raise ValueError('Invalid file path: %s' % wea_obj) + if wea_obj.lower().endswith('.wea'): + check_wea = Wea.from_file(wea_obj) + result = wea_obj + elif wea_obj.lower().endswith('.epw'): + check_wea = Wea.from_epw_file(wea_obj) + result = wea_obj + else: + raise ValueError( + 'File path should end with wea or epw not %s' % wea_obj.split('.')[-1] + ) + elif isinstance(wea_obj, EPW): + check_wea = wea_obj.to_wea() + result = wea_obj + elif isinstance(wea_obj, Wea): + check_wea = wea_obj + file_path = get_tempfile('wea', _wea_file_name(wea_obj)) + result = wea_obj.write(file_path) + else: + raise ValueError( + 'Wea input should be a string, a Wea object, or an EPW object. ' + 'Not {}.'.format(type(wea_obj)) + ) + + assert check_wea.timestep == 1, 'Wea timestep must be 1 for this recipe.' + assert check_wea.is_annual, 'Wea must be annual for this recipe.' + + return result From b97098c615588b388e02cc11270e88b0ab321551 Mon Sep 17 00:00:00 2001 From: Mikkel Pedersen Date: Thu, 18 Jun 2026 17:42:05 +0200 Subject: [PATCH 2/2] fix(daylight): Add handler to read a CSV file into a list of dicts --- pollination_handlers/outputs/daylight.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pollination_handlers/outputs/daylight.py b/pollination_handlers/outputs/daylight.py index 044c3bf..982cabc 100644 --- a/pollination_handlers/outputs/daylight.py +++ b/pollination_handlers/outputs/daylight.py @@ -216,3 +216,19 @@ def read_hourly_continuous_collection_from_json(json_path): data = json.load(json_file) datacollection = HourlyContinuousCollection.from_dict(data) return datacollection + + +def read_csv_summary_formatted(summary_csv): + """Read a CSV file and return a list of formatted summary lists.""" + if not os.path.isfile(summary_csv): + raise ValueError('Invalid file path: %s' % summary_csv) + + results = [] + with open(summary_csv) as csv_file: + reader = csv.DictReader(csv_file) + for row in reader: + row_results = [] + for key, value in row.items(): + row_results.append('{}: {}'.format(key, value)) + results.append(row_results) + return results