Skip to content

Commit f87a98a

Browse files
committed
refactor: simplify consumer function mapping
# Conflicts: # src/libecalc/presentation/yaml/mappers/facility_input.py
1 parent f0f5115 commit f87a98a

4 files changed

Lines changed: 53 additions & 92 deletions

File tree

src/libecalc/domain/resource.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,31 @@
1-
from typing import Protocol
1+
import abc
2+
import logging
23

4+
from libecalc.common.errors.exceptions import InvalidColumnException
35

4-
class Resource(Protocol):
6+
logger = logging.getLogger(__name__)
7+
8+
9+
class Resource(abc.ABC):
510
"""
611
A resource containing tabular data
712
"""
813

14+
@abc.abstractmethod
915
def get_headers(self) -> list[str]: ...
1016

17+
@abc.abstractmethod
1118
def get_column(self, header: str) -> list[float | int | str]: ...
1219

20+
def get_float_column(self, header: str) -> list[float]:
21+
try:
22+
column = self.get_column(header)
23+
column = [float(value) for value in column]
24+
except ValueError as e:
25+
msg = f"Resource contains non-numeric value: {e}"
26+
logger.error(msg)
27+
raise InvalidColumnException(header=header, message=msg) from e
28+
return column
29+
1330

1431
Resources = dict[str, Resource]

src/libecalc/presentation/yaml/mappers/energy_model_factory.py

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/libecalc/presentation/yaml/mappers/facility_input.py

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from collections.abc import Callable
12
from typing import Union
23

34
from pydantic import ValidationError
@@ -16,7 +17,6 @@
1617
from libecalc.domain.process.value_objects.chart import SingleSpeedChart, VariableSpeedChart
1718
from libecalc.domain.resource import Resource, Resources
1819
from libecalc.presentation.yaml.file_context import FileContext, FileMark
19-
from libecalc.presentation.yaml.mappers.energy_model_factory import EnergyModelFactory
2020
from libecalc.presentation.yaml.mappers.utils import (
2121
YAML_UNIT_MAPPING,
2222
chart_curves_as_resource_to_dto_format,
@@ -46,7 +46,7 @@
4646
# Used here to make pydantic understand which object to instantiate.
4747
EnergyModelUnionType = Union[GeneratorSetModel, TabularEnergyFunction, CompressorTrainSampledDTO]
4848

49-
energy_model_type_map = {
49+
energy_model_type_map: dict[str, EnergyModelType | ChartType] = {
5050
EcalcYamlKeywords.facility_type_electricity2fuel: EnergyModelType.GENERATOR_SET_SAMPLED,
5151
EcalcYamlKeywords.facility_type_pump_chart_single_speed: ChartType.SINGLE_SPEED,
5252
EcalcYamlKeywords.facility_type_pump_chart_variable_speed: ChartType.VARIABLE_SPEED,
@@ -77,7 +77,8 @@ def _get_column_or_none(resource: Resource, header: str) -> list[float | int | s
7777

7878

7979
def _create_compressor_train_sampled_dto_model_data(
80-
resource: Resource, facility_data: YamlCompressorTabularModel, **kwargs
80+
resource: Resource,
81+
facility_data: YamlCompressorTabularModel,
8182
) -> CompressorTrainSampledDTO:
8283
# kwargs just to allow this to be used with _default_facility_to_dto_model_data which needs type until we have
8384
# replaced _default_facility_to_dto_model_data and have separate functions for all types
@@ -116,7 +117,7 @@ def _create_compressor_train_sampled_dto_model_data(
116117

117118

118119
def _create_pump_model_single_speed_dto_model_data(
119-
resource: Resource, facility_data: YamlPumpChartSingleSpeed, **kwargs
120+
resource: Resource, facility_data: YamlPumpChartSingleSpeed,
120121
) -> PumpSingleSpeed:
121122
chart_data = get_single_speed_chart_data(resource=resource)
122123
pump_chart = SingleSpeedChart(
@@ -143,7 +144,7 @@ def _create_pump_model_single_speed_dto_model_data(
143144

144145

145146
def _create_pump_chart_variable_speed_dto_model_data(
146-
resource: Resource, facility_data: YamlPumpChartVariableSpeed, **kwargs
147+
resource: Resource, facility_data: YamlPumpChartVariableSpeed,
147148
) -> PumpVariableSpeed:
148149
curves_data = chart_curves_as_resource_to_dto_format(resource=resource)
149150
pump_chart = VariableSpeedChart(
@@ -176,47 +177,41 @@ def _create_pump_chart_variable_speed_dto_model_data(
176177
)
177178

178179

179-
def _create_generator_set_dto_model_data(
180-
resource: Resource, facility_data: YamlGeneratorSetModel, **kwargs
180+
def _create_generator_set_model(
181+
resource: Resource,
182+
facility_data: YamlGeneratorSetModel,
181183
) -> GeneratorSetModel:
182184
# Extract adjustment constants from facility data
183185
adjustment_constant = _get_adjustment_constant(facility_data)
184186
adjustment_factor = _get_adjustment_factor(facility_data)
185187

186-
# Ensure the 'name' field is present in facility data
187-
name = getattr(facility_data, "name", "default_generator_set_name")
188-
189188
# Create and return the GeneratorSetProcessUnit instance
190189
return GeneratorSetModel(
191-
name=name,
190+
name=facility_data.name,
192191
resource=resource,
193192
energy_usage_adjustment_constant=adjustment_constant,
194193
energy_usage_adjustment_factor=adjustment_factor,
195194
)
196195

197196

198-
def _default_facility_to_dto_model_data(
199-
resource: Resource, typ: EnergyModelType, facility_data: YamlFacilityModelBase
200-
) -> EnergyModelUnionType:
197+
def _create_tabulated_model(resource: Resource, facility_data: YamlFacilityModelBase) -> EnergyModelUnionType:
201198
resource_headers = resource.get_headers()
202-
resource_data = [resource.get_column(header) for header in resource_headers]
203-
204-
model_data = {
205-
"typ": typ,
206-
"headers": resource_headers,
207-
"data": resource_data,
208-
"energy_usage_adjustment_constant": _get_adjustment_constant(data=facility_data),
209-
"energy_usage_adjustment_factor": _get_adjustment_factor(data=facility_data),
210-
}
199+
resource_data = [resource.get_float_column(header) for header in resource_headers]
211200

212-
return EnergyModelFactory.create(typ, model_data)
201+
return TabularEnergyFunction(
202+
headers=resource_headers,
203+
data=resource_data,
204+
energy_usage_adjustment_factor=_get_adjustment_factor(data=facility_data),
205+
energy_usage_adjustment_constant=_get_adjustment_constant(data=facility_data),
206+
)
213207

214208

215-
facility_input_to_dto_map = {
209+
facility_input_to_dto_map: dict[EnergyModelType | ChartType, Callable] = {
216210
EnergyModelType.COMPRESSOR_SAMPLED: _create_compressor_train_sampled_dto_model_data,
217-
EnergyModelType.GENERATOR_SET_SAMPLED: _create_generator_set_dto_model_data,
211+
EnergyModelType.GENERATOR_SET_SAMPLED: _create_generator_set_model,
218212
ChartType.SINGLE_SPEED: _create_pump_model_single_speed_dto_model_data,
219213
ChartType.VARIABLE_SPEED: _create_pump_chart_variable_speed_dto_model_data,
214+
EnergyModelType.TABULATED: _create_tabulated_model,
220215
}
221216

222217

@@ -237,13 +232,17 @@ def from_yaml_to_dto(self, data: YamlFacilityModel) -> EnergyModel:
237232

238233
typ = energy_model_type_map.get(data.type)
239234

235+
if typ is None:
236+
raise DataValidationError(
237+
data=data.model_dump(),
238+
message=f"Unsupported facility input type '{data.type}'",
239+
dump_flow_style=DumpFlowStyle.BLOCK,
240+
)
241+
240242
try:
241-
return facility_input_to_dto_map.get(
242-
typ, # type: ignore[operator, arg-type]
243-
_default_facility_to_dto_model_data,
244-
)(
243+
assert typ in facility_input_to_dto_map
244+
return facility_input_to_dto_map[typ](
245245
resource=resource,
246-
typ=typ,
247246
facility_data=data,
248247
)
249248
except ValidationError as ve:

src/libecalc/presentation/yaml/mappers/utils.py

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def get_units_from_chart_config(
255255

256256
def get_single_speed_chart_data(resource: Resource) -> ChartData:
257257
try:
258-
speed_values = _get_float_column(resource=resource, header=EcalcYamlKeywords.consumer_chart_speed)
258+
speed_values = resource.get_float_column(EcalcYamlKeywords.consumer_chart_speed)
259259

260260
if not _all_numbers_equal(speed_values):
261261
raise InvalidColumnException(
@@ -268,31 +268,11 @@ def get_single_speed_chart_data(resource: Resource) -> ChartData:
268268
logger.debug("Speed not specified for single speed chart, setting speed to 1.")
269269
speed = 1
270270

271-
efficiency_values = _get_float_column(
272-
resource=resource,
273-
header=EcalcYamlKeywords.consumer_chart_efficiency,
274-
)
275-
rate_values = _get_float_column(
276-
resource=resource,
277-
header=EcalcYamlKeywords.consumer_chart_rate,
278-
)
279-
head_values = _get_float_column(
280-
resource=resource,
281-
header=EcalcYamlKeywords.consumer_chart_head,
282-
)
271+
efficiency_values = resource.get_float_column(EcalcYamlKeywords.consumer_chart_efficiency)
272+
rate_values = resource.get_float_column(EcalcYamlKeywords.consumer_chart_rate)
273+
head_values = resource.get_float_column(EcalcYamlKeywords.consumer_chart_head)
283274
return ChartData(speed, rate_values, head_values, efficiency_values)
284275

285276

286-
def _get_float_column(resource: Resource, header: str) -> list[float]:
287-
try:
288-
column = resource.get_column(header)
289-
column = [float(value) for value in column]
290-
except ValueError as e:
291-
msg = f"Resource contains non-numeric value: {e}"
292-
logger.error(msg)
293-
raise InvalidColumnException(header=header, message=msg) from e
294-
return column
295-
296-
297277
def _all_numbers_equal(values: list[int | float]) -> bool:
298278
return len(set(values)) == 1

0 commit comments

Comments
 (0)