Skip to content

Commit

Permalink
fix: error message when model/facility input does not exist
Browse files Browse the repository at this point in the history
  • Loading branch information
jsolaas committed Dec 1, 2023
1 parent ba48dcd commit 4437032
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 45 deletions.
7 changes: 7 additions & 0 deletions src/libecalc/common/errors/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,10 @@ class IllegalStateException(EcalcError):

def __init__(self, message: str):
super().__init__("Illegal state", message, error_type=EcalcErrorType.SERVER_ERROR)


class InvalidReferenceException(EcalcError):
"""The data provided is missing a required reference."""

def __init__(self, message: str):
super().__init__("Invalid reference", message, error_type=EcalcErrorType.CLIENT_ERROR)
3 changes: 0 additions & 3 deletions src/libecalc/presentation/yaml/mappers/component_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,7 @@ def _resolve_fuel(
resolved_fuel = resolve_reference(
fuel,
references=references.fuel_types,
none_if_not_found=True,
)
if resolved_fuel is None:
raise ValueError("Fuel not found")

temporal_fuel_model[start_time] = resolved_fuel

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from libecalc.dto.types import EnergyModelType, EnergyUsageType
from libecalc.expression import Expression
from libecalc.presentation.yaml.mappers.utils import (
resolve_and_validate_reference,
resolve_reference,
)
from libecalc.presentation.yaml.validation_errors import DataValidationError
Expand Down Expand Up @@ -84,7 +83,7 @@ def _compressor_system_mapper(
compressors = []
compressor_power_usage_type = set()
for compressor in energy_usage_model.get(EcalcYamlKeywords.compressor_system_compressors, []):
compressor_train = resolve_and_validate_reference(
compressor_train = resolve_reference(
value=compressor.get(EcalcYamlKeywords.compressor_system_compressor_sampled_data),
references=references.models,
)
Expand Down Expand Up @@ -146,7 +145,10 @@ def _pump_system_mapper(energy_usage_model: Dict, references: References = None)
"""
pumps = []
for pump in energy_usage_model.get(EcalcYamlKeywords.pump_system_pumps, []):
pump_model = resolve_reference(pump.get(EcalcYamlKeywords.pump_system_pump_model), references=references.models)
pump_model = resolve_reference(
pump.get(EcalcYamlKeywords.pump_system_pump_model),
references=references.models,
)
pumps.append(dto.PumpSystemPump(name=pump.get(EcalcYamlKeywords.name), pump_model=pump_model))

return dto.PumpSystemConsumerFunction(
Expand Down Expand Up @@ -241,7 +243,7 @@ def _pump_mapper(energy_usage_model: Dict, references: References = None) -> dto
def _variable_speed_compressor_train_multiple_streams_and_pressures_mapper(
energy_usage_model: Dict, references: References = None
) -> dto.CompressorConsumerFunction:
compressor_train_model = resolve_and_validate_reference(
compressor_train_model = resolve_reference(
energy_usage_model.get(EcalcYamlKeywords.models_type_compressor_train_compressor_train_model),
references=references.models,
)
Expand Down Expand Up @@ -296,7 +298,7 @@ def _variable_speed_compressor_train_multiple_streams_and_pressures_mapper(


def _compressor_mapper(energy_usage_model: Dict, references: References = None) -> dto.CompressorConsumerFunction:
energy_model = resolve_and_validate_reference(
energy_model = resolve_reference(
energy_usage_model.get(EcalcYamlKeywords.energy_model),
references=references.models,
)
Expand Down Expand Up @@ -337,7 +339,7 @@ def create_model(model: Dict, references: References = None):
raise ValueError(f"Unknown model type: {model.get(EcalcYamlKeywords.type)}")
return model_creator(model, references)

def from_yaml_to_dto(self, data: Dict) -> Optional[Dict[datetime, dto.ConsumerFunction]]:
def from_yaml_to_dto(self, data: dto.EnergyModel) -> Optional[Dict[datetime, dto.ConsumerFunction]]:
if data is None:
return None

Expand Down
12 changes: 6 additions & 6 deletions src/libecalc/presentation/yaml/mappers/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
convert_temperature_to_kelvin,
get_single_speed_chart_data,
get_units_from_chart_config,
resolve_and_validate_reference,
resolve_reference,
)
from libecalc.presentation.yaml.validation_errors import (
DataValidationError,
Expand Down Expand Up @@ -247,7 +247,7 @@ def _generic_from_design_point_compressor_chart_mapper(


def _resolve_and_validate_chart(compressor_chart_reference, input_models: Dict[str, Any]) -> dto.CompressorChart:
compressor_chart = resolve_and_validate_reference(
compressor_chart = resolve_reference(
value=compressor_chart_reference,
references=input_models,
)
Expand All @@ -273,7 +273,7 @@ def _variable_speed_compressor_train_multiple_streams_and_pressures_stream_mappe
stream_type = stream_config.get(EcalcYamlKeywords.type)
fluid_model_reference = stream_config.get(EcalcYamlKeywords.models_type_fluid_model)
if fluid_model_reference is not None:
fluid_model = resolve_and_validate_reference(value=fluid_model_reference, references=input_models)
fluid_model = resolve_reference(value=fluid_model_reference, references=input_models)
return dto.MultipleStreamsAndPressureStream(
name=reference_name,
fluid_model=fluid_model,
Expand All @@ -292,7 +292,7 @@ def _variable_speed_compressor_train_multiple_streams_and_pressures_stage_mapper
input_models: Dict[str, Any],
) -> dto.MultipleStreamsCompressorStage:
compressor_chart_reference = stage_config.get(EcalcYamlKeywords.models_type_compressor_train_compressor_chart)
compressor_chart = resolve_and_validate_reference(value=compressor_chart_reference, references=input_models)
compressor_chart = resolve_reference(value=compressor_chart_reference, references=input_models)
inlet_temperature_kelvin = convert_temperature_to_kelvin(
[stage_config.get(EcalcYamlKeywords.models_type_compressor_train_inlet_temperature)],
input_unit=Unit.CELSIUS,
Expand Down Expand Up @@ -599,11 +599,11 @@ def _compressor_with_turbine_mapper(
) -> dto.CompressorWithTurbine:
compressor_train_model_reference = model_config.get(EcalcYamlKeywords.models_compressor_model)
turbine_model_reference = model_config.get(EcalcYamlKeywords.models_turbine_model)
compressor_train_model = resolve_and_validate_reference(
compressor_train_model = resolve_reference(
value=compressor_train_model_reference,
references=input_models,
)
turbine_model = resolve_and_validate_reference(
turbine_model = resolve_reference(
value=turbine_model_reference,
references=input_models,
)
Expand Down
42 changes: 18 additions & 24 deletions src/libecalc/presentation/yaml/mappers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import pandas as pd

from libecalc.common.errors.exceptions import InvalidReferenceException
from libecalc.common.logger import logger
from libecalc.common.units import Unit
from libecalc.dto.types import (
Expand Down Expand Up @@ -30,13 +31,18 @@
}


def resolve_reference(
value: Any,
references: Dict[str, Any],
none_if_not_found: bool = False,
) -> Any:
"""Check if value is a reference and return it, if not a reference return the original value
:param none_if_not_found: return None if reference is not found
def is_reference(value: Any) -> bool:
return isinstance(value, str)


ReferenceValue = TypeVar("ReferenceValue")


def resolve_reference(value: Any, references: Dict[str, ReferenceValue]) -> ReferenceValue:
"""Check if value is a reference and return it.
If not a reference return the original value
If reference is invalid, raise InvalidReferenceException
:param value: reference or value
:param references: mapping from reference name to reference data
{
Expand All @@ -45,26 +51,14 @@ def resolve_reference(
}
:return: the actual value either referenced or not.
"""
if isinstance(value, str):
resolved = references.get(value, None)
if resolved is not None:
return resolved
elif none_if_not_found:
return None
else:
return value
else:
if not is_reference(value):
return value

if value not in references:
available_references = ",\n".join(references.keys())
raise InvalidReferenceException(f"'{value}' not found. \n\nAvailable references:\n{available_references}")

ReferenceValue = TypeVar("ReferenceValue")


def resolve_and_validate_reference(value: str, references: Dict[str, ReferenceValue]) -> ReferenceValue:
model = resolve_reference(value, references, none_if_not_found=True)
if model is None:
raise ValueError(f"Reference '{value}' not found. \nAvailable: {', '.join(references.keys())}")
return model
return references[value]


def convert_rate_to_am3_per_hour(rate_values: List[float], input_unit: Unit) -> List[float]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from libecalc.dto.components import CompressorComponent
from libecalc.dto.types import ConsumptionType
from libecalc.expression import Expression
from libecalc.presentation.yaml.mappers.utils import resolve_and_validate_reference
from libecalc.presentation.yaml.mappers.utils import resolve_reference
from libecalc.presentation.yaml.yaml_entities import References
from libecalc.presentation.yaml.yaml_types.components.yaml_base import (
YamlConsumerBase,
Expand Down Expand Up @@ -49,7 +49,7 @@ def to_dto(
user_defined_category=define_time_model_for_period(self.category or category, target_period=target_period),
fuel=fuel,
energy_usage_model={
timestep: resolve_and_validate_reference(
timestep: resolve_reference(
value=reference,
references=references.models,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from libecalc.dto.components import PumpComponent
from libecalc.dto.types import ConsumptionType
from libecalc.expression import Expression
from libecalc.presentation.yaml.mappers.utils import resolve_and_validate_reference
from libecalc.presentation.yaml.mappers.utils import resolve_reference
from libecalc.presentation.yaml.yaml_entities import References
from libecalc.presentation.yaml.yaml_types.components.yaml_base import (
YamlConsumerBase,
Expand Down Expand Up @@ -46,7 +46,7 @@ def to_dto(
user_defined_category=define_time_model_for_period(self.category or category, target_period=target_period),
fuel=fuel,
energy_usage_model={
timestep: resolve_and_validate_reference(
timestep: resolve_reference(
value=reference,
references=references.models,
)
Expand Down
5 changes: 3 additions & 2 deletions src/tests/libecalc/input/mappers/test_resolve_fuel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytest
from libecalc import dto
from libecalc.common.errors.exceptions import InvalidReferenceException
from libecalc.common.time_utils import Period
from libecalc.presentation.yaml.mappers.component_mapper import _resolve_fuel

Expand Down Expand Up @@ -44,11 +45,11 @@ def test_both(self, references, all_the_time):
assert _resolve_fuel("diesel", "fuel_gas", references, target_period=all_the_time).popitem()[1].name == "diesel"

def test_invalid(self, references, all_the_time):
with pytest.raises(ValueError) as exc_info:
with pytest.raises(InvalidReferenceException) as exc_info:
assert (
_resolve_fuel("diessel", "fuel_gass", references, target_period=all_the_time).popitem()[1] == "diessel"
)
assert "Fuel not found" in str(exc_info.value)
assert "Invalid reference: 'diessel' not found." in str(exc_info.value)

def test_resolve_multiple_fuels(self, references, all_the_time):
_resolve_fuel(
Expand Down

0 comments on commit 4437032

Please sign in to comment.