From e8665019a382317280812d6ee0e50d434e4189b0 Mon Sep 17 00:00:00 2001 From: Hannah Eslinger Date: Fri, 21 Apr 2023 16:00:36 -0600 Subject: [PATCH] Use converter in formatters --- buildingsync_asset_extractor/converter.py | 17 ++++- buildingsync_asset_extractor/formatters.py | 22 +++--- tests/test_formatters.py | 85 ++++++++++++++++++++++ 3 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 tests/test_formatters.py diff --git a/buildingsync_asset_extractor/converter.py b/buildingsync_asset_extractor/converter.py index c94c98c..0ed4626 100644 --- a/buildingsync_asset_extractor/converter.py +++ b/buildingsync_asset_extractor/converter.py @@ -1,6 +1,7 @@ -from typing import Literal, get_args +from typing import Literal, Optional, get_args from buildingsync_asset_extractor.errors import BSyncProcessorError +from buildingsync_asset_extractor.types import SystemData PowerUnits = Literal[ "W", @@ -19,6 +20,20 @@ POWERUNITSLIST: list[PowerUnits] = list(get_args(PowerUnits)) +def unify_units(system_datas: list[SystemData], to_units: Optional[str] = None) -> list[SystemData]: + if to_units is None: + to_units = system_datas[0].cap_units + for sd in system_datas: + if sd.cap is not None: + try: + sd.cap = convert(float(sd.cap), sd.cap_units, to_units) # type: ignore + sd.cap_units = to_units + except BSyncProcessorError: + pass + + return system_datas + + def convert(value: float, original_type: PowerUnits, to: PowerUnits) -> float: if original_type not in POWERUNITSLIST: raise BSyncProcessorError(f"`{original_type}` not a valid power unit") diff --git a/buildingsync_asset_extractor/formatters.py b/buildingsync_asset_extractor/formatters.py index 749a7ed..91f0747 100644 --- a/buildingsync_asset_extractor/formatters.py +++ b/buildingsync_asset_extractor/formatters.py @@ -1,9 +1,8 @@ import logging from typing import Any, Callable, Optional, Tuple, Union -from buildingsync_asset_extractor.converter import convert +from buildingsync_asset_extractor.converter import unify_units from buildingsync_asset_extractor.eletric_fuel_types import electric_fuel_types -from buildingsync_asset_extractor.errors import BSyncProcessorError from buildingsync_asset_extractor.lighting_processing.lighting_processing import ( LightingData, LightingDataLPD, @@ -61,14 +60,15 @@ def format_80_percent_results(self, name: str, results: list[SystemData], units: self.export_asset_units(name, units) return - values, capacities, cap_units, sqfts = self.remap_results(results) - # if only 1 asset, we'll call it primary! - if len(values) == 1: - self.export_asset(name, values[0]) + if len(results) == 1: + self.export_asset(name, results[0].value) self.export_asset_units(name, units) return + results = unify_units(results) + + values, capacities, cap_units, sqfts = self.remap_results(results) if None not in capacities and len(set(cap_units)) <= 1: # capacity method # add all capacities @@ -213,6 +213,8 @@ def format_custom_avg_results(self, name: str, results: list[SystemData], units: self.export_asset_units(name, units) return + results = unify_units(results) + values, capacities, cap_units, sqfts = self.remap_results(results) # logger.debug(f"values: {values}") @@ -326,13 +328,7 @@ def format_electrification_pontential(self, name: str, results: list[SystemData] # try to convert cap to same power unit if not units: units = non_electric[0].cap_units - for sd in non_electric: - if sd.cap is not None: - try: - sd.cap = convert(float(sd.cap), sd.cap_units, units) # type: ignore - sd.cap_units = units - except BSyncProcessorError: - pass + non_electric = unify_units(non_electric, to_units=units) # if all non electric SystemData have same cap unit, sum _, capacities, cap_units, _ = self.remap_results(non_electric) diff --git a/tests/test_formatters.py b/tests/test_formatters.py new file mode 100644 index 0000000..b22ef99 --- /dev/null +++ b/tests/test_formatters.py @@ -0,0 +1,85 @@ +import unittest +from unittest.mock import MagicMock + +import pytest + +from buildingsync_asset_extractor.formatters import Formatter +from buildingsync_asset_extractor.types import SystemData + + +class TestFormatters(unittest.TestCase): + def setUp(self) -> None: + self.export_asset = MagicMock() + self.export_asset_units = MagicMock() + self.formatter = Formatter(self.export_asset, self.export_asset_units) + + def test_format_80_percent_results(self) -> None: + # SET UP + system_datas = \ + [SystemData(value='Fuel oil no 1', cap='20.0', cap_units='kBtu/hr')] + \ + [SystemData(value='Natural gas', cap='10.0', cap_units='kBtu/hr')] * 8 + + # ACTION + self.formatter.format_80_percent_results("Heating Fuel Type", system_datas, None) + + # ASSERT + self.export_asset.assert_called_with("Heating Fuel Type", "Natural gas") + self.export_asset_units.assert_called_with("Heating Fuel Type", None) + + def test_format_80_percent_results_different_units(self) -> None: + # SET UP + system_datas = \ + [SystemData(value='Fuel oil no 1', cap='100.0', cap_units='kBtu/hr')] + \ + [SystemData(value='Natural gas', cap='1', cap_units='kW')] + + # ACTION + self.formatter.format_80_percent_results("Heating Fuel Type", system_datas, None) + + # ASSERT + self.export_asset.assert_called_with("Heating Fuel Type", "Natural gas") + self.export_asset_units.assert_called_with("Heating Fuel Type", None) + + def test_format_80_percent_results_use_sqft(self) -> None: + # SET UP + system_datas = \ + [SystemData(value='Fuel oil no 1', sqft=20)] + \ + [SystemData(value='Natural gas', sqft=80)] + + # ACTION + self.formatter.format_80_percent_results("Heating Fuel Type", system_datas, None) + + # ASSERT + self.export_asset.assert_called_with("Heating Fuel Type", "Natural gas") + self.export_asset_units.assert_called_with("Heating Fuel Type", None) + + def test_format_custom_avg_results(self) -> None: + # SET UP + system_datas = [ + SystemData(value='1.0', cap='3.0', cap_units='kBtu/hr'), + SystemData(value='1.0', cap='2.0', cap_units='kBtu/hr'), + SystemData(value='3.0', cap='5.0', cap_units='kBtu/hr') + ] + + # ACTION + self.formatter.format_custom_avg_results("Heating System Efficiency", system_datas, "Thermal Efficiency") + + # ASSERT + self.export_asset.assert_called_with("Heating System Efficiency", 2.0) + self.export_asset_units.assert_called_with("Heating System Efficiency", "Thermal Efficiency") + + def test_format_custom_avg_different_units(self) -> None: + # SET UP + system_datas = [ + SystemData(value='1.0', cap='3.0', cap_units='kBtu/hr'), + SystemData(value='1.0', cap='2.0', cap_units='kBtu/hr'), + SystemData(value='3.0', cap='5.0', cap_units='W') + ] + + # ACTION + self.formatter.format_custom_avg_results("Heating System Efficiency", system_datas, "Thermal Efficiency") + + # ASSERT + (name, value) = self.export_asset.call_args.args + assert name == "Heating System Efficiency" + assert value == pytest.approx(2.546705) + self.export_asset_units.assert_called_with("Heating System Efficiency", "Thermal Efficiency")