Skip to content

Commit 5e6848a

Browse files
committed
refactor: move generator set model mapping
1 parent 504b923 commit 5e6848a

5 files changed

Lines changed: 126 additions & 49 deletions

File tree

src/libecalc/presentation/yaml/domain/reference_service.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
from collections.abc import Iterable
33
from typing import Protocol
44

5-
from libecalc.domain.infrastructure.energy_components.generator_set import GeneratorSetModel
65
from libecalc.domain.infrastructure.energy_components.legacy_consumer.tabulated import TabularEnergyFunction
76
from libecalc.domain.process.pump.pump import PumpModel
87
from libecalc.dto import FuelType
98
from libecalc.presentation.yaml.mappers.yaml_path import YamlPath
10-
from libecalc.presentation.yaml.yaml_types.facility_model.yaml_facility_model import YamlCompressorTabularModel
9+
from libecalc.presentation.yaml.yaml_types.facility_model.yaml_facility_model import (
10+
YamlCompressorTabularModel,
11+
YamlGeneratorSetModel,
12+
)
1113
from libecalc.presentation.yaml.yaml_types.models import (
1214
YamlCompressorChart,
1315
YamlCompressorWithTurbine,
@@ -58,7 +60,7 @@ def get_compressor_chart(self, reference: str) -> YamlCompressorChart: ...
5860
def get_fuel_reference(self, reference: str) -> FuelType: ...
5961

6062
@abc.abstractmethod
61-
def get_generator_set_model(self, reference: str) -> GeneratorSetModel: ...
63+
def get_generator_set_model(self, reference: str) -> YamlGeneratorSetModel: ...
6264

6365
@abc.abstractmethod
6466
def get_compressor_model(self, reference: str) -> YamlCompressorModel: ...

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

Lines changed: 110 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@
2525
ElectricityConsumer,
2626
)
2727
from libecalc.domain.infrastructure.energy_components.fuel_consumer.fuel_consumer import FuelConsumerComponent
28+
from libecalc.domain.infrastructure.energy_components.generator_set import GeneratorSetModel
2829
from libecalc.domain.infrastructure.energy_components.generator_set.generator_set_component import (
2930
GeneratorSetEnergyComponent,
3031
)
3132
from libecalc.domain.infrastructure.energy_components.installation.installation import InstallationComponent
3233
from libecalc.domain.infrastructure.path_id import PathID
3334
from libecalc.domain.regularity import Regularity
34-
from libecalc.domain.resource import Resources
35+
from libecalc.domain.resource import Resource, Resources
3536
from libecalc.dto import FuelType
3637
from libecalc.expression.expression import InvalidExpressionError
3738
from libecalc.presentation.yaml.domain.expression_time_series_cable_loss import ExpressionTimeSeriesCableLoss
@@ -45,6 +46,7 @@
4546
ConsumerFunctionMapper,
4647
InvalidEnergyUsageModelException,
4748
)
49+
from libecalc.presentation.yaml.mappers.facility_input import _get_adjustment_constant, _get_adjustment_factor
4850
from libecalc.presentation.yaml.mappers.yaml_mapping_context import MappingContext
4951
from libecalc.presentation.yaml.mappers.yaml_path import YamlPath
5052
from libecalc.presentation.yaml.model_validation_exception import ModelValidationException
@@ -149,8 +151,8 @@ def __init__(self):
149151

150152

151153
def _resolve_fuel(
152-
consumer_fuel: str | None | dict,
153-
default_fuel: str | None,
154+
consumer_fuel: YamlTemporalModel[str],
155+
default_fuel: YamlTemporalModel[str] | None,
154156
references: ReferenceService,
155157
target_period: Period,
156158
mapping_context: MappingContext,
@@ -182,10 +184,13 @@ def _resolve_fuel(
182184

183185

184186
class ConsumerMapper:
185-
def __init__(self, resources: Resources, references: ReferenceService, target_period: Period):
187+
def __init__(
188+
self, resources: Resources, references: ReferenceService, target_period: Period, configuration: YamlValidator
189+
):
186190
self.__references = references
187191
self._target_period = target_period
188192
self._resources = resources
193+
self._configuration = configuration
189194

190195
def from_yaml_to_domain(
191196
self,
@@ -195,13 +200,12 @@ def from_yaml_to_domain(
195200
regularity: Regularity,
196201
consumes: ConsumptionType,
197202
expression_evaluator: ExpressionEvaluator,
198-
configuration: YamlValidator,
199203
yaml_path: YamlPath,
200204
mapping_context: MappingContext,
201-
default_fuel: str | None = None,
205+
default_fuel: YamlTemporalModel[str] | None,
202206
) -> Consumer | None:
203207
energy_usage_model_mapper = ConsumerFunctionMapper(
204-
configuration=configuration,
208+
configuration=self._configuration,
205209
resources=self._resources,
206210
references=self.__references,
207211
target_period=self._target_period,
@@ -215,7 +219,7 @@ def create_error_from_key(
215219
key: str,
216220
) -> ModelValidationError:
217221
key_path: YamlPath = yaml_path.append(key)
218-
file_context = configuration.get_file_context(key_path.keys) or configuration.get_file_context(
222+
file_context = self._configuration.get_file_context(key_path.keys) or self._configuration.get_file_context(
219223
yaml_path.keys
220224
)
221225
return ModelValidationError(
@@ -230,7 +234,7 @@ def create_error(
230234
specific_path: YamlPath = None,
231235
):
232236
yaml_path_to_use = specific_path if specific_path is not None else yaml_path
233-
file_context = configuration.get_file_context(yaml_path_to_use.keys)
237+
file_context = self._configuration.get_file_context(yaml_path_to_use.keys)
234238

235239
return ModelValidationError(
236240
message=message,
@@ -282,7 +286,7 @@ def create_error(
282286
MissingFuelReference,
283287
InvalidTemporalModel,
284288
DomainValidationException,
285-
) as e: # TODO: Should all these also be DomainValidationException? Do we need 'domain' or can we just have SingleValidationError (or ValidationValueError which already exists), i.e. two validation errors, one for a single error and one for Model where we expect several errors and some context.
289+
) as e: # TODO: Should all these also be DomainValidationException? Do we need 'domain' or can we just have SingleValidationError, i.e. two validation errors, one for a single error and one for Model where we expect several errors and some context.
286290
raise ModelValidationException(
287291
errors=[create_error(message=str(e), specific_path=fuel_yaml_path)]
288292
) from e
@@ -315,10 +319,71 @@ def create_error(
315319

316320

317321
class GeneratorSetMapper:
318-
def __init__(self, resources: Resources, references: ReferenceService, target_period: Period):
322+
def __init__(
323+
self,
324+
resources: Resources,
325+
references: ReferenceService,
326+
target_period: Period,
327+
configuration: YamlValidator,
328+
):
319329
self.__references = references
320330
self._target_period = target_period
321-
self.__consumer_mapper = ConsumerMapper(resources=resources, references=references, target_period=target_period)
331+
self.__consumer_mapper = ConsumerMapper(
332+
resources=resources, references=references, target_period=target_period, configuration=configuration
333+
)
334+
self._configuration = configuration
335+
self._resources = resources
336+
337+
def _create_reference_error(self, message: str, reference: str, key: str | None = None):
338+
yaml_path = self.__references.get_yaml_path(reference)
339+
340+
location_keys = [*yaml_path.keys[:-1], reference] # Replace index with name
341+
342+
if key is not None:
343+
key_path = yaml_path.append(key)
344+
location_keys.append(key)
345+
else:
346+
key_path = yaml_path
347+
348+
file_context = self._configuration.get_file_context(key_path.keys)
349+
return ModelValidationError(
350+
message=message,
351+
location=Location(keys=location_keys),
352+
name=reference,
353+
file_context=file_context,
354+
)
355+
356+
def _get_resource(self, resource_name: str, reference: str) -> Resource:
357+
resource = self._resources.get(resource_name)
358+
if resource is None:
359+
raise ModelValidationException(
360+
errors=[
361+
self._create_reference_error(
362+
message=f"Unable to find resource '{resource_name}'", reference=reference, key="FILE"
363+
)
364+
]
365+
)
366+
return resource
367+
368+
def _create_generator_set_model(self, reference: str) -> GeneratorSetModel:
369+
model = self.__references.get_generator_set_model(reference)
370+
resource = self._get_resource(model.file, reference)
371+
# Extract adjustment constants from facility data
372+
adjustment_constant = _get_adjustment_constant(model)
373+
adjustment_factor = _get_adjustment_factor(model)
374+
375+
# Create and return the GeneratorSetProcessUnit instance
376+
try:
377+
return GeneratorSetModel(
378+
name=model.name,
379+
resource=resource,
380+
energy_usage_adjustment_constant=adjustment_constant,
381+
energy_usage_adjustment_factor=adjustment_factor,
382+
)
383+
except DomainValidationException as e:
384+
raise ModelValidationException(
385+
errors=[self._create_reference_error(message=str(e), reference=reference)]
386+
) from e
322387

323388
def from_yaml_to_domain(
324389
self,
@@ -327,17 +392,16 @@ def from_yaml_to_domain(
327392
path_id: PathID,
328393
regularity: Regularity,
329394
expression_evaluator: ExpressionEvaluator,
330-
configuration: YamlValidator,
331395
yaml_path: YamlPath,
332396
mapping_context: MappingContext,
333-
default_fuel: str | None = None,
397+
default_fuel: YamlTemporalModel[str] | None,
334398
) -> GeneratorSetEnergyComponent | None:
335399
def create_error(message: str, key: str | None = None) -> ModelValidationError:
336400
if key is None:
337401
yaml_path_to_use = yaml_path
338402
else:
339403
yaml_path_to_use = yaml_path.append(key)
340-
file_context = configuration.get_file_context(yaml_path_to_use.keys)
404+
file_context = self._configuration.get_file_context(yaml_path_to_use.keys)
341405
return ModelValidationError(
342406
message=message,
343407
location=get_location_from_yaml_path(yaml_path_to_use, mapping_context=mapping_context),
@@ -367,7 +431,7 @@ def create_error(message: str, key: str | None = None) -> ModelValidationError:
367431
try:
368432
generator_set_model = TemporalModel(
369433
{
370-
start_time: self.__references.get_generator_set_model(model_reference)
434+
start_time: self._create_generator_set_model(model_reference)
371435
for start_time, model_reference in generator_set_model_data.items()
372436
}
373437
)
@@ -396,9 +460,9 @@ def create_error(message: str, key: str | None = None) -> ModelValidationError:
396460
regularity=regularity,
397461
consumes=ConsumptionType.ELECTRICITY,
398462
expression_evaluator=expression_evaluator,
399-
configuration=configuration,
400463
yaml_path=consumer_yaml_path,
401464
mapping_context=mapping_context,
465+
default_fuel=default_fuel,
402466
)
403467

404468
if parsed_consumer is None:
@@ -454,13 +518,25 @@ def create_error(message: str, key: str | None = None) -> ModelValidationError:
454518

455519

456520
class InstallationMapper:
457-
def __init__(self, resources: Resources, references: ReferenceService, target_period: Period):
521+
def __init__(
522+
self,
523+
resources: Resources,
524+
references: ReferenceService,
525+
target_period: Period,
526+
configuration: YamlValidator,
527+
):
458528
self.__references = references
459529
self._target_period = target_period
460530
self.__generator_set_mapper = GeneratorSetMapper(
461-
resources=resources, references=references, target_period=target_period
531+
resources=resources,
532+
references=references,
533+
target_period=target_period,
534+
configuration=configuration,
462535
)
463-
self.__consumer_mapper = ConsumerMapper(resources=resources, references=references, target_period=target_period)
536+
self.__consumer_mapper = ConsumerMapper(
537+
resources=resources, references=references, target_period=target_period, configuration=configuration
538+
)
539+
self._configuration = configuration
464540

465541
def from_yaml_venting_emitter_to_domain(
466542
self,
@@ -469,14 +545,13 @@ def from_yaml_venting_emitter_to_domain(
469545
path_id: PathID,
470546
expression_evaluator: ExpressionEvaluator,
471547
regularity: Regularity,
472-
configuration: YamlValidator,
473548
yaml_path: YamlPath,
474549
mapping_context: MappingContext,
475550
) -> DirectVentingEmitter | OilVentingEmitter:
476551
venting_emitter_location = get_location_from_yaml_path(yaml_path, mapping_context=mapping_context)
477552

478553
def create_error(message: str) -> ModelValidationError:
479-
file_context = configuration.get_file_context(yaml_path.keys)
554+
file_context = self._configuration.get_file_context(yaml_path.keys)
480555
return ModelValidationError(
481556
message=message,
482557
location=venting_emitter_location,
@@ -538,7 +613,6 @@ def from_yaml_to_domain(
538613
id: UUID,
539614
path_id: PathID,
540615
expression_evaluator: ExpressionEvaluator,
541-
configuration: YamlValidator,
542616
yaml_path: YamlPath,
543617
mapping_context: MappingContext,
544618
) -> InstallationComponent:
@@ -547,7 +621,7 @@ def create_error(message: str, key: str | None = None) -> ModelValidationError:
547621
yaml_path_to_use = yaml_path
548622
else:
549623
yaml_path_to_use = yaml_path.append(key)
550-
file_context = configuration.get_file_context(yaml_path_to_use.keys)
624+
file_context = self._configuration.get_file_context(yaml_path_to_use.keys)
551625
return ModelValidationError(
552626
message=message,
553627
location=get_location_from_yaml_path(yaml_path_to_use, mapping_context=mapping_context),
@@ -596,9 +670,8 @@ def create_error(message: str, key: str | None = None) -> ModelValidationError:
596670
id=generator_set_id,
597671
path_id=generator_set_path_id,
598672
regularity=regularity,
599-
default_fuel=fuel_data, # type: ignore[arg-type]
673+
default_fuel=fuel_data,
600674
expression_evaluator=expression_evaluator,
601-
configuration=configuration,
602675
yaml_path=generator_set_yaml_path,
603676
mapping_context=mapping_context,
604677
)
@@ -626,9 +699,8 @@ def create_error(message: str, key: str | None = None) -> ModelValidationError:
626699
path_id=fuel_consumer_path_id,
627700
regularity=regularity,
628701
consumes=ConsumptionType.FUEL,
629-
default_fuel=fuel_data, # type: ignore[arg-type]
702+
default_fuel=fuel_data,
630703
expression_evaluator=expression_evaluator,
631-
configuration=configuration,
632704
yaml_path=fuel_consumer_yaml_path,
633705
mapping_context=mapping_context,
634706
)
@@ -658,7 +730,6 @@ def create_error(message: str, key: str | None = None) -> ModelValidationError:
658730
path_id=venting_emitter_path_id,
659731
expression_evaluator=expression_evaluator,
660732
regularity=regularity,
661-
configuration=configuration,
662733
yaml_path=venting_emitter_yaml_path,
663734
mapping_context=mapping_context,
664735
)
@@ -686,19 +757,24 @@ def __init__(
686757
target_period: Period,
687758
expression_evaluator: ExpressionEvaluator,
688759
mapping_context: MappingContext,
760+
configuration: YamlValidator,
689761
):
690762
self.__references = references
691763
self.__installation_mapper = InstallationMapper(
692-
resources=resources, references=references, target_period=target_period
764+
resources=resources,
765+
references=references,
766+
target_period=target_period,
767+
configuration=configuration,
693768
)
694769
self.__expression_evaluator = expression_evaluator
695770
self.__mapping_context = mapping_context
771+
self._configuration = configuration
696772

697-
def from_yaml_to_domain(self, configuration: YamlValidator) -> Asset:
773+
def from_yaml_to_domain(self) -> Asset:
698774
installations_path = YamlPath(("installations",))
699775
try:
700776
installations = []
701-
for installation_index, installation in enumerate(configuration.installations):
777+
for installation_index, installation in enumerate(self._configuration.installations):
702778
installation_yaml_path = installations_path.append(installation_index)
703779
installation_path_id = PathID(installation.name)
704780
installation_id = uuid4()
@@ -716,15 +792,14 @@ def from_yaml_to_domain(self, configuration: YamlValidator) -> Asset:
716792
id=installation_id,
717793
path_id=installation_path_id,
718794
expression_evaluator=self.__expression_evaluator,
719-
configuration=configuration,
720795
yaml_path=installation_yaml_path,
721796
mapping_context=self.__mapping_context,
722797
)
723798

724799
installations.append(parsed_installation)
725800
ecalc_model = Asset(
726801
id=uuid4(),
727-
path_id=PathID(configuration.name),
802+
path_id=PathID(self._configuration.name),
728803
installations=installations,
729804
)
730805
return ecalc_model
@@ -734,7 +809,7 @@ def from_yaml_to_domain(self, configuration: YamlValidator) -> Asset:
734809
ModelValidationError(
735810
message=str(e),
736811
location=Location(keys=""),
737-
file_context=configuration.get_file_context(()),
812+
file_context=self._configuration.get_file_context(()),
738813
)
739814
]
740815
) from e

0 commit comments

Comments
 (0)