From 4b612be47eb1e41fae645a7be742d8b6d14e5aa8 Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Mon, 14 Aug 2023 10:05:07 +0200 Subject: [PATCH 01/42] :construction: initialized bo bilanzierungs class --- src/bo4e/bo/bilanzierung.py | 76 +++++++++++++++++++++++++++++++++++++ src/bo4e/enum/botyp.py | 2 + 2 files changed, 78 insertions(+) create mode 100644 src/bo4e/bo/bilanzierung.py diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py new file mode 100644 index 000000000..d656db810 --- /dev/null +++ b/src/bo4e/bo/bilanzierung.py @@ -0,0 +1,76 @@ +""" +Bilanzierungsklasse +""" +from datetime import datetime +from typing import Optional + +from bo4e.bo.geschaeftsobjekt import Geschaeftsobjekt +from bo4e.com.menge import Menge +from bo4e.enum.botyp import BoTyp + + +class Bilanzierung(Geschaeftsobjekt): + """ + Object containing information about Bilanzierung i.e. accounting + """ + + +bo_typ: BoTyp = BoTyp.BILANZIERUNG # added to botyp.py + +# required attributes + +# optional attributes +# Welche Marktlokation +marktlokations_id: Optional[str] = None +### +# todo: add marktlokations_id check? +# _marktlokations_id_check = field_validator("marktlokations_id")(validate_marktlokations_id) +### +# Eine Liste der verwendeten Lastprofile (SLP, SLP/TLP, ALP etc.) +lastprofil: list[Optional[Lastprofil]] = [] # messgroesse? +# Inklusiver Start der Bilanzierung +bilanzierungsbeginn: Optional[datetime] = None +# Exklusives Ende der Bilanzierung +bilanzierungsende: Optional[datetime] = None +# todo: add tests? + +# Bilanzkreis +bilanzkreis: Optional[str] = None +# Jahresverbrauchsprognose +jahresverbrauchsprognose: Optional[Menge] = None +# Temperatur Arbeit +temperatur_arbeit: Optional[Menge] = None +# Kundenwert +kundenwert: Optional[Menge] = None +""" + + Verbrauchsaufteilung in % zwischen SLP und TLP-Profil + 1. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] * [Verbrauchsaufteilung in % / 100%] + = [zu verlagernde Energiemenge] + 2. [Gemessene Energiemenge der OBIS "Schwachlast"] - [zu verlagernde Energiemenge] + = [Ermittelte Energiemenge für Schwachlast] + 3. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] + [zu verlagernde Energiemenge] + = [Ermittelte Energiemenge für nicht Schwachlast] + +""" +verbrauchsaufteilung: Optional[float] = None # double precision in python +# Zeitreihentyp (SLS, TLS, etc.) +zeitreihentyp: Optional[Zeitreihentyp] = None # enum +# Aggregationsverantwortung +aggregationsverantwortung: Optional[Aggregationsverantwortung] = None # enum +# Prognosegrundlage +prognosegrundlage: Optional[Prognosegrundlage] = None # enum +""" + Prognosegrundlage + Besteht der Bedarf ein tagesparameteräbhängiges Lastprofil mit gemeinsamer Messung anzugeben, + so ist dies über die 2 -malige Wiederholung des CAV Segments mit der Angabe der Codes E02 und E14 möglich. +""" +details_prognosegrundlage: list[Optional[Profiltyp]] = [] # enum +# Wahlrecht der Prognosegrundlage (true = Wahlrecht beim Lieferanten vorhanden) +wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None # enum +# Fallgruppenzuordnung (für gas RLM) +fallgruppenzuordnung: Optional[Fallgruppenzuordnung] = None # enum +# Priorität des Bilanzkreises (für Gas) +prioritaet: Optional[int] = None +# Grund Wahlrecht der Prognosegrundlage(true=Wahlrecht beim Lieferanten vorhanden) +grund_wahlrechts_prognosegrundlage: Optional[WahlrechtsPrognosegrundlage] = None # enum diff --git a/src/bo4e/enum/botyp.py b/src/bo4e/enum/botyp.py index 4b83d4de8..8d57e088e 100644 --- a/src/bo4e/enum/botyp.py +++ b/src/bo4e/enum/botyp.py @@ -10,6 +10,8 @@ class BoTyp(StrEnum): ANGEBOT = "ANGEBOT" ANSPRECHPARTNER = "ANSPRECHPARTNER" AUSSCHREIBUNG = "AUSSCHREIUNG" + # work in progress + BILANZIERUNG = "BILANZIERUNG" BUENDELVERTRAG = "BUENDELVERTRAG" ENERGIEMENGE = "ENERGIEMENGE" FREMDKOSTEN = "FREMDKOSTEN" From 047546b53479299956848b744252da096345294e Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Mon, 21 Aug 2023 09:47:38 +0200 Subject: [PATCH 02/42] :construction: added Lastprofil-Klasse and testing functions. --- src/bo4e/bo/bilanzierung.py | 111 +++++++------- src/bo4e/com/lastprofil.py | 38 +++++ src/bo4e/com/tagesparameter.py | 24 +++ src/bo4e/enum/aggregationsverantwortung.py | 14 ++ src/bo4e/enum/botyp.py | 2 +- src/bo4e/enum/fallgruppenzuordnung.py | 14 ++ src/bo4e/enum/profilart.py | 16 ++ src/bo4e/enum/profiltyp.py | 14 ++ src/bo4e/enum/profilverfahren.py | 13 ++ src/bo4e/enum/prognosegrundlage.py | 13 ++ src/bo4e/enum/wahlrechtprognosegrundlage.py | 16 ++ src/bo4e/enum/zeitreihentyp.py | 24 +++ src/bo4e/validators.py | 14 ++ tests/test_bilanzierung.py | 154 ++++++++++++++++++++ tests/test_lastprofil.py | 87 +++++++++++ tests/test_tagesparameter.py | 48 ++++++ 16 files changed, 549 insertions(+), 53 deletions(-) create mode 100644 src/bo4e/com/lastprofil.py create mode 100644 src/bo4e/com/tagesparameter.py create mode 100644 src/bo4e/enum/aggregationsverantwortung.py create mode 100644 src/bo4e/enum/fallgruppenzuordnung.py create mode 100644 src/bo4e/enum/profilart.py create mode 100644 src/bo4e/enum/profiltyp.py create mode 100644 src/bo4e/enum/profilverfahren.py create mode 100644 src/bo4e/enum/prognosegrundlage.py create mode 100644 src/bo4e/enum/wahlrechtprognosegrundlage.py create mode 100644 src/bo4e/enum/zeitreihentyp.py create mode 100644 tests/test_bilanzierung.py create mode 100644 tests/test_lastprofil.py create mode 100644 tests/test_tagesparameter.py diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index d656db810..46820c6ea 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -1,76 +1,83 @@ """ -Bilanzierungsklasse +Contains class Bilanzierung """ from datetime import datetime from typing import Optional from bo4e.bo.geschaeftsobjekt import Geschaeftsobjekt +from bo4e.com.lastprofil import Lastprofil from bo4e.com.menge import Menge +from bo4e.enum.aggregationsverantwortung import Aggregationsverantwortung from bo4e.enum.botyp import BoTyp +from bo4e.enum.fallgruppenzuordnung import Fallgruppenzuordnung +from bo4e.enum.profiltyp import Profiltyp +from bo4e.enum.prognosegrundlage import Prognosegrundlage +from bo4e.enum.wahlrechtprognosegrundlage import WahlrechtPrognosegrundlage +from bo4e.enum.zeitreihentyp import Zeitreihentyp class Bilanzierung(Geschaeftsobjekt): """ - Object containing information about Bilanzierung i.e. accounting + Bilanzierungs BO """ + bo_typ: BoTyp = BoTyp.BILANZIERUNG # added to botyp.py + # optional attributes + #: Welche Marktlokation + marktlokations_id: Optional[str] = None -bo_typ: BoTyp = BoTyp.BILANZIERUNG # added to botyp.py + ### + # todo: optional/add marktlokations_id check? -# required attributes + # _marktlokations_id_check = field_validator("marktlokations_id")(validate_marktlokations_id) + ### -# optional attributes -# Welche Marktlokation -marktlokations_id: Optional[str] = None -### -# todo: add marktlokations_id check? -# _marktlokations_id_check = field_validator("marktlokations_id")(validate_marktlokations_id) -### -# Eine Liste der verwendeten Lastprofile (SLP, SLP/TLP, ALP etc.) -lastprofil: list[Optional[Lastprofil]] = [] # messgroesse? -# Inklusiver Start der Bilanzierung -bilanzierungsbeginn: Optional[datetime] = None -# Exklusives Ende der Bilanzierung -bilanzierungsende: Optional[datetime] = None -# todo: add tests? + #: Eine Liste der verwendeten Lastprofile (SLP, SLP/TLP, ALP etc.) + lastprofil: list[Optional[Lastprofil]] = [] + #: Inklusiver Start der Bilanzierung + bilanzierungsbeginn: Optional[datetime] = None + #: Exklusives Ende der Bilanzierung + bilanzierungsende: Optional[datetime] = None + # todo: add tests? -# Bilanzkreis -bilanzkreis: Optional[str] = None -# Jahresverbrauchsprognose -jahresverbrauchsprognose: Optional[Menge] = None -# Temperatur Arbeit -temperatur_arbeit: Optional[Menge] = None -# Kundenwert -kundenwert: Optional[Menge] = None -""" - - Verbrauchsaufteilung in % zwischen SLP und TLP-Profil + #: Bilanzkreis + bilanzkreis: Optional[str] = None + #: Jahresverbrauchsprognose + jahresverbrauchsprognose: Optional[Menge] = None + #: Temperatur Arbeit + temperatur_arbeit: Optional[Menge] = None + #: Kundenwert + kundenwert: Optional[Menge] = None + """ + Verbrauchsaufteilung in % zwischen SLP und TLP-Profil. + 1. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] * [Verbrauchsaufteilung in % / 100%] = [zu verlagernde Energiemenge] 2. [Gemessene Energiemenge der OBIS "Schwachlast"] - [zu verlagernde Energiemenge] = [Ermittelte Energiemenge für Schwachlast] 3. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] + [zu verlagernde Energiemenge] = [Ermittelte Energiemenge für nicht Schwachlast] - -""" -verbrauchsaufteilung: Optional[float] = None # double precision in python -# Zeitreihentyp (SLS, TLS, etc.) -zeitreihentyp: Optional[Zeitreihentyp] = None # enum -# Aggregationsverantwortung -aggregationsverantwortung: Optional[Aggregationsverantwortung] = None # enum -# Prognosegrundlage -prognosegrundlage: Optional[Prognosegrundlage] = None # enum -""" - Prognosegrundlage - Besteht der Bedarf ein tagesparameteräbhängiges Lastprofil mit gemeinsamer Messung anzugeben, - so ist dies über die 2 -malige Wiederholung des CAV Segments mit der Angabe der Codes E02 und E14 möglich. -""" -details_prognosegrundlage: list[Optional[Profiltyp]] = [] # enum -# Wahlrecht der Prognosegrundlage (true = Wahlrecht beim Lieferanten vorhanden) -wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None # enum -# Fallgruppenzuordnung (für gas RLM) -fallgruppenzuordnung: Optional[Fallgruppenzuordnung] = None # enum -# Priorität des Bilanzkreises (für Gas) -prioritaet: Optional[int] = None -# Grund Wahlrecht der Prognosegrundlage(true=Wahlrecht beim Lieferanten vorhanden) -grund_wahlrechts_prognosegrundlage: Optional[WahlrechtsPrognosegrundlage] = None # enum + + """ + verbrauchsaufteilung: Optional[float] = None + #: Zeitreihentyp (SLS, TLS, etc.) + zeitreihentyp: Optional[Zeitreihentyp] = None + #: Aggregationsverantwortung + aggregationsverantwortung: Optional[Aggregationsverantwortung] = None + #: Prognosegrundlage + prognosegrundlage: Optional[Prognosegrundlage] = None + """ + Prognosegrundlage. + + Besteht der Bedarf ein tagesparameteräbhängiges Lastprofil mit gemeinsamer Messung anzugeben, + so ist dies über die 2 -malige Wiederholung des CAV Segments mit der Angabe der Codes E02 und E14 möglich. + """ + details_prognosegrundlage: list[Optional[Profiltyp]] = [] + #: Wahlrecht der Prognosegrundlage (true = Wahlrecht beim Lieferanten vorhanden) + wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None + #: Fallgruppenzuordnung (für gas RLM) + fallgruppenzuordnung: Optional[Fallgruppenzuordnung] = None + #: Priorität des Bilanzkreises (für Gas) + prioritaet: Optional[int] = None + #: Grund Wahlrecht der Prognosegrundlage(true=Wahlrecht beim Lieferanten vorhanden) + grund_wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None diff --git a/src/bo4e/com/lastprofil.py b/src/bo4e/com/lastprofil.py new file mode 100644 index 000000000..3025077a2 --- /dev/null +++ b/src/bo4e/com/lastprofil.py @@ -0,0 +1,38 @@ +""" +Contains class Lastprofil +""" +from typing import Optional + +from pydantic import field_validator + +from bo4e.com.com import COM +from bo4e.com.tagesparameter import Tagesparameter +from bo4e.enum.profilart import Profilart +from bo4e.enum.profilverfahren import Profilverfahren +from bo4e.validators import tagesparameter_given_for_tagesparam_lastprofil + + +class Lastprofil(COM): + """ + Lastprofil + """ + # optional attributes + #: Bezeichnung des Profils, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) + bezeichnung: Optional[str] = None + #: Optionale Bezeichnung der Profilschar, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) + profilschar: Optional[str] = None + #: Verfahren des Profils (analytisch oder synthetisch) + verfahren: Optional[Profilverfahren] = None + #: Einspeiseprofil: True/False + einspeisung: Optional[bool] = None + #: Klimazone / Temperaturmessstelle + tagesparameter: Optional[Tagesparameter] = None + #: Profilart des Lastprofils, e.g. ART_STANDARDLASTPROFIL + profilart: Optional[Profilart] = None + _tagesparameter_check = field_validator("profilart")(tagesparameter_given_for_tagesparam_lastprofil) + """ + Field validator für Profilart. + Wenn die Profilart tagesparameterabh. ist, muss ein Tagesparameter gegeben sein. + """ + #: Herausgeber des Lastprofil-Codes, e.g. BDEW + herausgeber: Optional[str] = None diff --git a/src/bo4e/com/tagesparameter.py b/src/bo4e/com/tagesparameter.py new file mode 100644 index 000000000..dbeffc86a --- /dev/null +++ b/src/bo4e/com/tagesparameter.py @@ -0,0 +1,24 @@ +""" +contains tagesparameter class +""" + + +from typing import Optional + +from bo4e.com.com import COM + + +class Tagesparameter(COM): + """ + Speichert Informationen zu einer tagesparameter abhängigen Messstelle. z.B. den Namen einer Klimazone oder die ID + der Wetterstation für die Temperaturmessstelle + """ + # optional attributes + #: Qualifier der Klimazone, e.g. 7624q + klimazone: Optional[str] = None + #: Qualifier der Temperaturmessstelle, e.g. 1234x + temperaturmessstelle: Optional[str] = None + #: Dienstanbieter (bei Temperaturmessstellen), e.g. ZT1 + dienstanbieter: Optional[str] = None + #: Herausgeber des Lastprofil-Codes, e.g. BDEW + herausgeber: Optional[str] = None diff --git a/src/bo4e/enum/aggregationsverantwortung.py b/src/bo4e/enum/aggregationsverantwortung.py new file mode 100644 index 000000000..8f60f58a0 --- /dev/null +++ b/src/bo4e/enum/aggregationsverantwortung.py @@ -0,0 +1,14 @@ +""" +Contains class Aggregationsverantwortungs +""" + +from bo4e.enum.strenum import StrEnum + + +class Aggregationsverantwortung(StrEnum): + """ + Mögliche Qualifier für die Aggregationsverantwortung + """ + + UENB = "UENB" #: Übertragungsnetzbetreiber + VNB = "VNB" #: Verteilnetzbetreiber diff --git a/src/bo4e/enum/botyp.py b/src/bo4e/enum/botyp.py index 8d57e088e..dd5473952 100644 --- a/src/bo4e/enum/botyp.py +++ b/src/bo4e/enum/botyp.py @@ -9,7 +9,7 @@ class BoTyp(StrEnum): ANGEBOT = "ANGEBOT" ANSPRECHPARTNER = "ANSPRECHPARTNER" - AUSSCHREIBUNG = "AUSSCHREIUNG" + AUSSCHREIBUNG = "AUSSCHREIBUNG" # work in progress BILANZIERUNG = "BILANZIERUNG" BUENDELVERTRAG = "BUENDELVERTRAG" diff --git a/src/bo4e/enum/fallgruppenzuordnung.py b/src/bo4e/enum/fallgruppenzuordnung.py new file mode 100644 index 000000000..7464e6d4d --- /dev/null +++ b/src/bo4e/enum/fallgruppenzuordnung.py @@ -0,0 +1,14 @@ +""" +Contains class Fallgruppenzuordnung +""" + +from bo4e.enum.strenum import StrEnum + +class Fallgruppenzuordnung(StrEnum): + """ + Fallgruppenzuordnung nach edi@energy + """ + + GABI_RLMmT = "GABI_RLMmT" #: RLM mit Tagesband, + GABI_RLMoT = "GABI_RLMoT" #: RLM ohne Tagesband, + GABI_RLMNEV = "GABI_RLMNEV" #: RLM im Nominierungsersatzverfahren diff --git a/src/bo4e/enum/profilart.py b/src/bo4e/enum/profilart.py new file mode 100644 index 000000000..22840e15b --- /dev/null +++ b/src/bo4e/enum/profilart.py @@ -0,0 +1,16 @@ +""" +Contains class Profilart +""" + +from bo4e.enum.strenum import StrEnum + + +class Profilart(StrEnum): + """ + Profilart: temperaturabh./Standardlastprofil + """ + + ART_STANDARDLASTPROFIL = "ART_STANDARDLASTPROFIL" #: ART_STANDARDLASTPROFIL, Z02 + ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL = "ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL" + #: ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL, Z03 + ART_LASTPROFIL = "ART_LASTPROFIL" #: ART_LASTPROFIL, Z12 diff --git a/src/bo4e/enum/profiltyp.py b/src/bo4e/enum/profiltyp.py new file mode 100644 index 000000000..82cf546de --- /dev/null +++ b/src/bo4e/enum/profiltyp.py @@ -0,0 +1,14 @@ +""" +Contains class Profiltyp +""" + +from bo4e.enum.strenum import StrEnum + + +class Profiltyp(StrEnum): + """ + Profiltyp (temperaturabhängig / Standardlastprofil) + """ + + SLP_SEP = "SLP_SEP" #: SLP/SEP + TLP_TEP = "TLP_TEP" #: TLP/TEP diff --git a/src/bo4e/enum/profilverfahren.py b/src/bo4e/enum/profilverfahren.py new file mode 100644 index 000000000..3b88942ca --- /dev/null +++ b/src/bo4e/enum/profilverfahren.py @@ -0,0 +1,13 @@ +""" +Contains class Profilverfahren +""" +from bo4e.enum.strenum import StrEnum + + +class Profilverfahren(StrEnum): + """ + Profilverfahren: synthetisch/ analytisch + """ + + SYNTHETISCH = "SYNTHETISCH" #: SLP + ANALYTISCH = "ANALYTISCH" #: ALP diff --git a/src/bo4e/enum/prognosegrundlage.py b/src/bo4e/enum/prognosegrundlage.py new file mode 100644 index 000000000..b064346d7 --- /dev/null +++ b/src/bo4e/enum/prognosegrundlage.py @@ -0,0 +1,13 @@ +""" +Contains class Prognosegrundlage +""" +from bo4e.enum.strenum import StrEnum + + +class Prognosegrundlage(StrEnum): + """ + Prognosegrundlage (WERTE, PROFILE) + """ + + WERTE = "WERTE" #: Prognose auf Basis von Werten + PROFILE = "PROFILE" #: Prognose auf Basis von Profilen diff --git a/src/bo4e/enum/wahlrechtprognosegrundlage.py b/src/bo4e/enum/wahlrechtprognosegrundlage.py new file mode 100644 index 000000000..50f02bca3 --- /dev/null +++ b/src/bo4e/enum/wahlrechtprognosegrundlage.py @@ -0,0 +1,16 @@ +""" +Contains class Wahlrechtsprognosgrundlage +""" +from bo4e.enum.strenum import StrEnum + + +class WahlrechtPrognosegrundlage(StrEnum): + """ + Wahlrecht der Prognosegrundlage der Marktlokation + """ + DURCH_LF = "DURCH_LF" #: Wahlrecht durch LF gegeben, remark: SG10 CAV + DURCH_LF_NICHT_GEGEBEN = "DURCH_LF_NICHT_GEGEBEN" #: Wahlrecht durch LF nicht gegeben, remark: CAV + ZE2 + NICHT_WEGEN_GROSSEN_VERBRAUCHS = "NICHT_WEGEN_GROSSEN_VERBRAUCHS" # : kein WR, Verbrauch>10k, CAV+ Z55 + NICHT_WEGEN_EIGENVERBRAUCH = "NICHT_WEGEN_EIGENVERBRAUCH" #: kein WR, Eigenverbrauch, CAV + ZC1 + NICHT_WEGEN_TAGES_VERBRAUCH = "NICHT_WEGEN_TAGES_VERBRAUCH" # : kein WR, tagesparam.abh. Verbrauch, CAV + ZD2 + NICHT_WEGEN_ENWG = "NICHT_WEGEN_ENWG" #: WR nicht wegen $14a EnWG, CAV + ZE3 diff --git a/src/bo4e/enum/zeitreihentyp.py b/src/bo4e/enum/zeitreihentyp.py new file mode 100644 index 000000000..e1c1bd770 --- /dev/null +++ b/src/bo4e/enum/zeitreihentyp.py @@ -0,0 +1,24 @@ +""" +Contains class Zeitreihentyp +""" +from bo4e.enum.strenum import StrEnum + + +class Zeitreihentyp(StrEnum): + """ + Codes der Summenzeitreihentypen. + + Die nachfolgenden Codes sind in DE7111 zu nutzen: + https://www.edi-energy.de/index.php?id=38&tx_bdew_bdew%5Buid%5D=695&tx_bdew_bdew%5Baction%5D=download + &tx_bdew_bdew%5Bcontroller%5D=Dokument&cHash=67782e05d8b0f75fbe3a0e1801d07ed0 + """ + + EGS = "EGS" #: Einspeisegangsumme + LGS = "LGS" #: Lastgangsumme + NZR = "NZR" #: Netzzeitreihe + SES = "SES" #: Standardeinspeiseprofilsumme + SLS = "SLS" #: Standardlastsumme + TES = "TES" #: tagesparameterabhängige Einspeiseprofilsumme + TLS = "TLS" #: tagesparameterabhängige Lastprofilsumme + SLS_TLS = "SLS_TLS" #: gemeinsame Messung aus SLS und TLS + SES_TES = "SES_TES" #: gemeinsame Messung aus SES und TES diff --git a/src/bo4e/validators.py b/src/bo4e/validators.py index 14fe3e9b2..ac7e9bec9 100644 --- a/src/bo4e/validators.py +++ b/src/bo4e/validators.py @@ -10,6 +10,7 @@ from pydantic_core.core_schema import ValidationInfo from bo4e.enum.aufabschlagstyp import AufAbschlagstyp +from bo4e.enum.profilart import Profilart from bo4e.enum.waehrungseinheit import Waehrungseinheit ModelT = TypeVar("ModelT", bound=BaseModel) @@ -69,6 +70,19 @@ def einheit_only_for_abschlagstyp_absolut( # type: ignore[no-untyped-def] raise ValueError("Only state einheit if auf_abschlagstyp is absolute.") return value +# pylint:disable=unused-argument +def tagesparameter_given_for_tagesparam_lastprofil( # type: ignore[no-untyped-def] + cls, value: Profilart, validation_info: ValidationInfo +) -> Profilart: + """ + Check that tagesdparameter is given for tagesparam.abh. Profil + Currently, (2023-08-21) only used in COM Lastprofil. + """ + values = validation_info.data # type:ignore[attr-defined] + if (value==Profilart.ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL) and not values["tagesparameter"]: + raise ValueError("Lastprofil depends on Tagesparameter. Tagesparameter not given.") + return value + # pylint:disable=too-few-public-methods class _VonBisType(Protocol): diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py new file mode 100644 index 000000000..2f617a556 --- /dev/null +++ b/tests/test_bilanzierung.py @@ -0,0 +1,154 @@ +from datetime import datetime, timezone +from typing import Dict, Any + +import pytest +from _decimal import Decimal + +from bo4e.bo.bilanzierung import Bilanzierung +from bo4e.com.lastprofil import Lastprofil +from bo4e.com.menge import Menge +from bo4e.com.tagesparameter import Tagesparameter +from bo4e.enum.aggregationsverantwortung import Aggregationsverantwortung +from bo4e.enum.botyp import BoTyp +from bo4e.enum.fallgruppenzuordnung import Fallgruppenzuordnung +from bo4e.enum.mengeneinheit import Mengeneinheit +from bo4e.enum.profilart import Profilart +from bo4e.enum.profiltyp import Profiltyp +from bo4e.enum.profilverfahren import Profilverfahren +from bo4e.enum.prognosegrundlage import Prognosegrundlage +from bo4e.enum.wahlrechtprognosegrundlage import WahlrechtPrognosegrundlage +from bo4e.enum.zeitreihentyp import Zeitreihentyp +from tests.serialization_helper import assert_serialization_roundtrip + +#: full example +example_bilanzierung = Bilanzierung( + marktlokations_id="51238696781", + lastprofil=[Lastprofil( + bezeichnung="foo", + profilschar="foo2", + verfahren=Profilverfahren.SYNTHETISCH, + einspeisung=True, + tagesparameter=Tagesparameter( + klimazone="7624q", + temperaturmessstelle="1234x", + dienstanbieter="ZT1", + herausgeber="BDEW", + ), + profilart=Profilart.ART_LASTPROFIL, + herausgeber="BDEW", + )], + bilanzierungsbeginn=datetime(2022, 1, 1, 0, 0, 0, tzinfo=timezone.utc), + bilanzierungsende=datetime(2023, 1, 1, 0, 0, 0, tzinfo=timezone.utc), + bilanzkreis="foo", + jahresverbrauchsprognose=Menge( + wert=Decimal(3.41), + einheit=Mengeneinheit.MWH + ), + temperatur_arbeit=Menge( + wert=Decimal(3.41), + einheit=Mengeneinheit.MWH + ), + # todo: check einheiten + kundenwert=Menge( + wert=Decimal(3.41), + einheit=Mengeneinheit.MWH + ), + verbrauchsaufteilung=1.5, + zeitreihentyp=Zeitreihentyp.EGS, + aggregationsverantwortung=Aggregationsverantwortung.VNB, + prognosegrundlage=Prognosegrundlage.WERTE, + details_prognosegrundlage=[Profiltyp.SLP_SEP], + wahlrecht_prognosegrundlage=WahlrechtPrognosegrundlage.DURCH_LF, + fallgruppenzuordnung=Fallgruppenzuordnung.GABI_RLMmT, + prioritaet=1, + grund_wahlrecht_prognosegrundlage=WahlrechtPrognosegrundlage.DURCH_LF_NICHT_GEGEBEN, +) + + +class TestBilanzierung: + @pytest.mark.parametrize( + "bilanzierung, expected_json_dict", + [ + pytest.param( + example_bilanzierung, + { + # todo: cf. alias_generator=camelize in geschaeftsobjekte.py + "versionstruktur": "2", + "boTyp": BoTyp.BILANZIERUNG, + "externeReferenzen": [], + "marktlokationsId": "51238696781", + "lastprofil": [{ + "bezeichnung": "foo", + "profilschar": "foo2", + "verfahren": Profilverfahren.SYNTHETISCH, + "einspeisung": True, + "tagesparameter": { + "klimazone": "7624q", + "temperaturmessstelle": "1234x", + "dienstanbieter": "ZT1", + "herausgeber": "BDEW", + }, + "profilart": Profilart.ART_LASTPROFIL, + "herausgeber": "BDEW", + }], + "bilanzierungsbeginn": datetime(2022, 1, 1, 0, 0, 0, tzinfo=timezone.utc), + "bilanzierungsende": datetime(2023, 1, 1, 0, 0, 0, tzinfo=timezone.utc), + "bilanzkreis": "foo", + "jahresverbrauchsprognose": { + "wert": 3.41, + "einheit": Mengeneinheit.MWH, + }, + "temperaturArbeit": { + "wert": 3.41, + "einheit": Mengeneinheit.MWH, + }, + "kundenwert": { + "wert": 3.41, + "einheit": Mengeneinheit.MWH, + }, + "verbrauchsaufteilung": 1.5, + "zeitreihentyp": Zeitreihentyp.EGS, + "aggregationsverantwortung": Aggregationsverantwortung.VNB, + "prognosegrundlage": Prognosegrundlage.WERTE, + "detailsPrognosegrundlage": [Profiltyp.SLP_SEP], + "wahlrechtPrognosegrundlage": WahlrechtPrognosegrundlage.DURCH_LF, + "fallgruppenzuordnung": Fallgruppenzuordnung.GABI_RLMmT, + "prioritaet": 1, + "grundWahlrechtPrognosegrundlage": WahlrechtPrognosegrundlage.DURCH_LF_NICHT_GEGEBEN, + }, + id="full example" + ), + pytest.param( + Bilanzierung(), + { + # todo: cf. alias_generator=camelize in geschaeftsobjekte.py + "versionstruktur": "2", + "boTyp": BoTyp.BILANZIERUNG, + "externeReferenzen": [], + "marktlokationsId": None, + "lastprofil": [], + "bilanzierungsbeginn": None, + "bilanzierungsende": None, + "bilanzkreis": None, + "jahresverbrauchsprognose": None, + "temperaturArbeit": None, + "kundenwert": None, + "verbrauchsaufteilung": None, + "zeitreihentyp": None, + "aggregationsverantwortung": None, + "prognosegrundlage": None, + "detailsPrognosegrundlage": [], + "wahlrechtPrognosegrundlage": None, + "fallgruppenzuordnung": None, + "prioritaet": None, + "grundWahlrechtPrognosegrundlage": None, + }, + id="min example" + ), + ], + ) + def test_serialization_roundtrip(self, bilanzierung: Bilanzierung, expected_json_dict: Dict[str, Any]) -> None: + """ + Test de-/serialisation of Bilanzierung with minimal attributes. + """ + assert_serialization_roundtrip(bilanzierung, expected_json_dict) diff --git a/tests/test_lastprofil.py b/tests/test_lastprofil.py new file mode 100644 index 000000000..a627e89b8 --- /dev/null +++ b/tests/test_lastprofil.py @@ -0,0 +1,87 @@ +from typing import Dict, Any + +import pytest +from pydantic import ValidationError + +from bo4e.com.lastprofil import Lastprofil +from bo4e.com.tagesparameter import Tagesparameter +from bo4e.enum.profilart import Profilart +from bo4e.enum.profilverfahren import Profilverfahren +from tests.serialization_helper import assert_serialization_roundtrip + +#: maximal example +example_lastprofil = Lastprofil( + bezeichnung="foo", + profilschar="foo2", + verfahren=Profilverfahren.SYNTHETISCH, + einspeisung=True, + tagesparameter=Tagesparameter( + klimazone="7624q", + temperaturmessstelle="1234x", + dienstanbieter="ZT1", + herausgeber="BDEW", + ), + profilart=Profilart.ART_LASTPROFIL, + herausgeber="BDEW", +) + + +class TestLastprofil: + @pytest.mark.parametrize( + "lastprofil, expected_json_dict", + [ + pytest.param( + example_lastprofil, + { + "bezeichnung": "foo", + "profilschar": "foo2", + "verfahren": Profilverfahren.SYNTHETISCH, + "einspeisung": True, + "tagesparameter": { + "klimazone": "7624q", + "temperaturmessstelle": "1234x", + "dienstanbieter": "ZT1", + "herausgeber": "BDEW", + }, + "profilart": Profilart.ART_LASTPROFIL, + "herausgeber": "BDEW", + }, + id="max param test" + ), + pytest.param( + Lastprofil(), + { + "bezeichnung": None, + "profilschar": None, + "verfahren": None, + "einspeisung": None, + "tagesparameter": None, + "profilart": None, + "herausgeber": None, + }, + id="min param test" + ), + ], + ) + def test_serialization_roundtrip(self, lastprofil: Lastprofil, expected_json_dict: Dict[str, Any]) -> None: + """ + Test de-/serialisation of Lastprofil with minimal attributes. + """ + assert_serialization_roundtrip(lastprofil, expected_json_dict) + + @pytest.mark.parametrize( + "profil_art", + [ + pytest.param( + Profilart.ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL, + id="profilart tagesparm.abh.", + ), + ], + ) + def test_failing_validation_tagesparameter_given_for_tagesparam_lastprofil(self, profil_art: Profilart) -> None: + with pytest.raises(ValidationError) as excinfo: + _ = Lastprofil( + profilart=profil_art, + ) + + assert "Lastprofil depends on Tagesparameter. Tagesparameter not given." in str(excinfo.value) diff --git a/tests/test_tagesparameter.py b/tests/test_tagesparameter.py new file mode 100644 index 000000000..ccc87e79c --- /dev/null +++ b/tests/test_tagesparameter.py @@ -0,0 +1,48 @@ +from typing import Dict, Any + +import pytest + +from bo4e.com.tagesparameter import Tagesparameter +from tests.serialization_helper import assert_serialization_roundtrip + +#: full example +example_tagesparameter = Tagesparameter( + klimazone="7624q", + temperaturmessstelle="1234x", + dienstanbieter="ZT1", + herausgeber="BDEW", +) + + +class TestTagesparameter: + # + @pytest.mark.parametrize( + "tagesparameter, expected_json_dict", + [ + pytest.param( + example_tagesparameter, + { + "klimazone": "7624q", + "temperaturmessstelle": "1234x", + "dienstanbieter": "ZT1", + "herausgeber": "BDEW", + }, + id="full example" + ), + pytest.param( + Tagesparameter(), + { + "klimazone": None, + "temperaturmessstelle": None, + "dienstanbieter": None, + "herausgeber": None, + }, + id="min example" + ), + ], + ) + def test_serialization_roundtrip(self, tagesparameter: Tagesparameter, expected_json_dict: Dict[str, Any]) -> None: + """ + Test de-/serialisation of Tagesparameter with minimal attributes. + """ + assert_serialization_roundtrip(tagesparameter, expected_json_dict) From 330f6f5b995b8e4da15fccdb9dde1ef669c5630a Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Mon, 21 Aug 2023 10:10:27 +0200 Subject: [PATCH 03/42] :construction: Update Formatierung --- src/bo4e/bo/bilanzierung.py | 1 + src/bo4e/com/lastprofil.py | 1 + src/bo4e/com/tagesparameter.py | 1 + src/bo4e/enum/fallgruppenzuordnung.py | 11 ++- src/bo4e/enum/wahlrechtprognosegrundlage.py | 1 + src/bo4e/validators.py | 3 +- tests/test_bilanzierung.py | 75 ++++++++++----------- tests/test_lastprofil.py | 4 +- tests/test_tagesparameter.py | 4 +- 9 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index 46820c6ea..698b4bd77 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -20,6 +20,7 @@ class Bilanzierung(Geschaeftsobjekt): """ Bilanzierungs BO """ + bo_typ: BoTyp = BoTyp.BILANZIERUNG # added to botyp.py # optional attributes diff --git a/src/bo4e/com/lastprofil.py b/src/bo4e/com/lastprofil.py index 3025077a2..487d01933 100644 --- a/src/bo4e/com/lastprofil.py +++ b/src/bo4e/com/lastprofil.py @@ -16,6 +16,7 @@ class Lastprofil(COM): """ Lastprofil """ + # optional attributes #: Bezeichnung des Profils, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) bezeichnung: Optional[str] = None diff --git a/src/bo4e/com/tagesparameter.py b/src/bo4e/com/tagesparameter.py index dbeffc86a..e015682f9 100644 --- a/src/bo4e/com/tagesparameter.py +++ b/src/bo4e/com/tagesparameter.py @@ -13,6 +13,7 @@ class Tagesparameter(COM): Speichert Informationen zu einer tagesparameter abhängigen Messstelle. z.B. den Namen einer Klimazone oder die ID der Wetterstation für die Temperaturmessstelle """ + # optional attributes #: Qualifier der Klimazone, e.g. 7624q klimazone: Optional[str] = None diff --git a/src/bo4e/enum/fallgruppenzuordnung.py b/src/bo4e/enum/fallgruppenzuordnung.py index 7464e6d4d..3862a3272 100644 --- a/src/bo4e/enum/fallgruppenzuordnung.py +++ b/src/bo4e/enum/fallgruppenzuordnung.py @@ -4,11 +4,16 @@ from bo4e.enum.strenum import StrEnum + class Fallgruppenzuordnung(StrEnum): """ Fallgruppenzuordnung nach edi@energy """ - GABI_RLMmT = "GABI_RLMmT" #: RLM mit Tagesband, - GABI_RLMoT = "GABI_RLMoT" #: RLM ohne Tagesband, - GABI_RLMNEV = "GABI_RLMNEV" #: RLM im Nominierungsersatzverfahren + # todo: Uppercase-Problematik klären. -> pylint + GABI_RLMmT = "GABI_RLMmT" # pylint:disable=invalid-name + # #: RLM mit Tagesband, + GABI_RLMoT = "GABI_RLMoT" # pylint:disable=invalid-name + # #: RLM ohne Tagesband, + GABI_RLMNEV = "GABI_RLMNEV" + #: RLM im Nominierungsersatzverfahren diff --git a/src/bo4e/enum/wahlrechtprognosegrundlage.py b/src/bo4e/enum/wahlrechtprognosegrundlage.py index 50f02bca3..4955ea303 100644 --- a/src/bo4e/enum/wahlrechtprognosegrundlage.py +++ b/src/bo4e/enum/wahlrechtprognosegrundlage.py @@ -8,6 +8,7 @@ class WahlrechtPrognosegrundlage(StrEnum): """ Wahlrecht der Prognosegrundlage der Marktlokation """ + DURCH_LF = "DURCH_LF" #: Wahlrecht durch LF gegeben, remark: SG10 CAV DURCH_LF_NICHT_GEGEBEN = "DURCH_LF_NICHT_GEGEBEN" #: Wahlrecht durch LF nicht gegeben, remark: CAV + ZE2 NICHT_WEGEN_GROSSEN_VERBRAUCHS = "NICHT_WEGEN_GROSSEN_VERBRAUCHS" # : kein WR, Verbrauch>10k, CAV+ Z55 diff --git a/src/bo4e/validators.py b/src/bo4e/validators.py index ac7e9bec9..3ac5e5053 100644 --- a/src/bo4e/validators.py +++ b/src/bo4e/validators.py @@ -70,6 +70,7 @@ def einheit_only_for_abschlagstyp_absolut( # type: ignore[no-untyped-def] raise ValueError("Only state einheit if auf_abschlagstyp is absolute.") return value + # pylint:disable=unused-argument def tagesparameter_given_for_tagesparam_lastprofil( # type: ignore[no-untyped-def] cls, value: Profilart, validation_info: ValidationInfo @@ -79,7 +80,7 @@ def tagesparameter_given_for_tagesparam_lastprofil( # type: ignore[no-untyped-d Currently, (2023-08-21) only used in COM Lastprofil. """ values = validation_info.data # type:ignore[attr-defined] - if (value==Profilart.ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL) and not values["tagesparameter"]: + if (value == Profilart.ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL) and not values["tagesparameter"]: raise ValueError("Lastprofil depends on Tagesparameter. Tagesparameter not given.") return value diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index 2f617a556..bbcf784dd 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -23,36 +23,29 @@ #: full example example_bilanzierung = Bilanzierung( marktlokations_id="51238696781", - lastprofil=[Lastprofil( - bezeichnung="foo", - profilschar="foo2", - verfahren=Profilverfahren.SYNTHETISCH, - einspeisung=True, - tagesparameter=Tagesparameter( - klimazone="7624q", - temperaturmessstelle="1234x", - dienstanbieter="ZT1", + lastprofil=[ + Lastprofil( + bezeichnung="foo", + profilschar="foo2", + verfahren=Profilverfahren.SYNTHETISCH, + einspeisung=True, + tagesparameter=Tagesparameter( + klimazone="7624q", + temperaturmessstelle="1234x", + dienstanbieter="ZT1", + herausgeber="BDEW", + ), + profilart=Profilart.ART_LASTPROFIL, herausgeber="BDEW", - ), - profilart=Profilart.ART_LASTPROFIL, - herausgeber="BDEW", - )], + ) + ], bilanzierungsbeginn=datetime(2022, 1, 1, 0, 0, 0, tzinfo=timezone.utc), bilanzierungsende=datetime(2023, 1, 1, 0, 0, 0, tzinfo=timezone.utc), bilanzkreis="foo", - jahresverbrauchsprognose=Menge( - wert=Decimal(3.41), - einheit=Mengeneinheit.MWH - ), - temperatur_arbeit=Menge( - wert=Decimal(3.41), - einheit=Mengeneinheit.MWH - ), + jahresverbrauchsprognose=Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH), + temperatur_arbeit=Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH), # todo: check einheiten - kundenwert=Menge( - wert=Decimal(3.41), - einheit=Mengeneinheit.MWH - ), + kundenwert=Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH), verbrauchsaufteilung=1.5, zeitreihentyp=Zeitreihentyp.EGS, aggregationsverantwortung=Aggregationsverantwortung.VNB, @@ -77,20 +70,22 @@ class TestBilanzierung: "boTyp": BoTyp.BILANZIERUNG, "externeReferenzen": [], "marktlokationsId": "51238696781", - "lastprofil": [{ - "bezeichnung": "foo", - "profilschar": "foo2", - "verfahren": Profilverfahren.SYNTHETISCH, - "einspeisung": True, - "tagesparameter": { - "klimazone": "7624q", - "temperaturmessstelle": "1234x", - "dienstanbieter": "ZT1", + "lastprofil": [ + { + "bezeichnung": "foo", + "profilschar": "foo2", + "verfahren": Profilverfahren.SYNTHETISCH, + "einspeisung": True, + "tagesparameter": { + "klimazone": "7624q", + "temperaturmessstelle": "1234x", + "dienstanbieter": "ZT1", + "herausgeber": "BDEW", + }, + "profilart": Profilart.ART_LASTPROFIL, "herausgeber": "BDEW", - }, - "profilart": Profilart.ART_LASTPROFIL, - "herausgeber": "BDEW", - }], + } + ], "bilanzierungsbeginn": datetime(2022, 1, 1, 0, 0, 0, tzinfo=timezone.utc), "bilanzierungsende": datetime(2023, 1, 1, 0, 0, 0, tzinfo=timezone.utc), "bilanzkreis": "foo", @@ -116,7 +111,7 @@ class TestBilanzierung: "prioritaet": 1, "grundWahlrechtPrognosegrundlage": WahlrechtPrognosegrundlage.DURCH_LF_NICHT_GEGEBEN, }, - id="full example" + id="full example", ), pytest.param( Bilanzierung(), @@ -143,7 +138,7 @@ class TestBilanzierung: "prioritaet": None, "grundWahlrechtPrognosegrundlage": None, }, - id="min example" + id="min example", ), ], ) diff --git a/tests/test_lastprofil.py b/tests/test_lastprofil.py index a627e89b8..39e60574b 100644 --- a/tests/test_lastprofil.py +++ b/tests/test_lastprofil.py @@ -46,7 +46,7 @@ class TestLastprofil: "profilart": Profilart.ART_LASTPROFIL, "herausgeber": "BDEW", }, - id="max param test" + id="max param test", ), pytest.param( Lastprofil(), @@ -59,7 +59,7 @@ class TestLastprofil: "profilart": None, "herausgeber": None, }, - id="min param test" + id="min param test", ), ], ) diff --git a/tests/test_tagesparameter.py b/tests/test_tagesparameter.py index ccc87e79c..9949f5211 100644 --- a/tests/test_tagesparameter.py +++ b/tests/test_tagesparameter.py @@ -27,7 +27,7 @@ class TestTagesparameter: "dienstanbieter": "ZT1", "herausgeber": "BDEW", }, - id="full example" + id="full example", ), pytest.param( Tagesparameter(), @@ -37,7 +37,7 @@ class TestTagesparameter: "dienstanbieter": None, "herausgeber": None, }, - id="min example" + id="min example", ), ], ) From 5cd5503665bcb89cbea25e9ad4d0046d9e90d679 Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Mon, 21 Aug 2023 10:15:25 +0200 Subject: [PATCH 04/42] :construction: fixed isort --- tests/test_bilanzierung.py | 2 +- tests/test_lastprofil.py | 2 +- tests/test_tagesparameter.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index bbcf784dd..586392d8c 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -1,5 +1,5 @@ from datetime import datetime, timezone -from typing import Dict, Any +from typing import Any, Dict import pytest from _decimal import Decimal diff --git a/tests/test_lastprofil.py b/tests/test_lastprofil.py index 39e60574b..8f27f2c20 100644 --- a/tests/test_lastprofil.py +++ b/tests/test_lastprofil.py @@ -1,4 +1,4 @@ -from typing import Dict, Any +from typing import Any, Dict import pytest from pydantic import ValidationError diff --git a/tests/test_tagesparameter.py b/tests/test_tagesparameter.py index 9949f5211..72e060fd6 100644 --- a/tests/test_tagesparameter.py +++ b/tests/test_tagesparameter.py @@ -1,4 +1,4 @@ -from typing import Dict, Any +from typing import Any, Dict import pytest From 61d696cc3c05b2c1c934f2a05cfa643239e96ed2 Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Mon, 21 Aug 2023 12:05:31 +0200 Subject: [PATCH 05/42] :construction: added MaLo validator --- src/bo4e/bo/bilanzierung.py | 13 ++++++++++--- src/bo4e/validators.py | 6 ++---- tests/test_bilanzierung.py | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index 698b4bd77..2c48bdfdb 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -4,6 +4,8 @@ from datetime import datetime from typing import Optional +from pydantic import field_validator + from bo4e.bo.geschaeftsobjekt import Geschaeftsobjekt from bo4e.com.lastprofil import Lastprofil from bo4e.com.menge import Menge @@ -14,6 +16,7 @@ from bo4e.enum.prognosegrundlage import Prognosegrundlage from bo4e.enum.wahlrechtprognosegrundlage import WahlrechtPrognosegrundlage from bo4e.enum.zeitreihentyp import Zeitreihentyp +from bo4e.validators import validate_marktlokations_id class Bilanzierung(Geschaeftsobjekt): @@ -27,11 +30,8 @@ class Bilanzierung(Geschaeftsobjekt): #: Welche Marktlokation marktlokations_id: Optional[str] = None - ### # todo: optional/add marktlokations_id check? - # _marktlokations_id_check = field_validator("marktlokations_id")(validate_marktlokations_id) - ### #: Eine Liste der verwendeten Lastprofile (SLP, SLP/TLP, ALP etc.) lastprofil: list[Optional[Lastprofil]] = [] @@ -82,3 +82,10 @@ class Bilanzierung(Geschaeftsobjekt): prioritaet: Optional[int] = None #: Grund Wahlrecht der Prognosegrundlage(true=Wahlrecht beim Lieferanten vorhanden) grund_wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None + + @field_validator("marktlokations_id") + @classmethod + def _validate_malo_if_given(cls, marktlokations_id: Optional[str]) -> str: + if marktlokations_id is None: + return marktlokations_id + return validate_marktlokations_id(cls, marktlokations_id) diff --git a/src/bo4e/validators.py b/src/bo4e/validators.py index 3ac5e5053..c330a473a 100644 --- a/src/bo4e/validators.py +++ b/src/bo4e/validators.py @@ -80,7 +80,7 @@ def tagesparameter_given_for_tagesparam_lastprofil( # type: ignore[no-untyped-d Currently, (2023-08-21) only used in COM Lastprofil. """ values = validation_info.data # type:ignore[attr-defined] - if (value == Profilart.ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL) and not values["tagesparameter"]: + if (value is Profilart.ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL) and not values["tagesparameter"]: raise ValueError("Lastprofil depends on Tagesparameter. Tagesparameter not given.") return value @@ -124,9 +124,7 @@ def check_bis_is_later_than_von(cls, value: datetime, values: ValidationInfo): # pylint: disable=unused-argument -def validate_marktlokations_id( # type: ignore[no-untyped-def] - cls, marktlokations_id: str, values: ValidationInfo -) -> str: +def validate_marktlokations_id(cls, marktlokations_id: str) -> str: # type: ignore[no-untyped-def] """ A validator for marktlokations IDs """ diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index 586392d8c..39bf094c4 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -1,8 +1,9 @@ from datetime import datetime, timezone -from typing import Any, Dict +from typing import Any, Dict, Tuple import pytest from _decimal import Decimal +from pydantic import ValidationError from bo4e.bo.bilanzierung import Bilanzierung from bo4e.com.lastprofil import Lastprofil @@ -147,3 +148,36 @@ def test_serialization_roundtrip(self, bilanzierung: Bilanzierung, expected_json Test de-/serialisation of Bilanzierung with minimal attributes. """ assert_serialization_roundtrip(bilanzierung, expected_json_dict) + + @pytest.mark.parametrize( + "malo_id_valid", + [ + ("51238696781", True), + ("41373559241", True), + ("56789012345", True), + ("52935155442", True), + ("12345678910", False), + ("asdasd", False), + (" ", False), + (" asdasdasd ", False), + ("keine malo id", False), + (None, True), + ("", False), + ], + ) + def test_id_validation(self, malo_id_valid: Tuple[str, bool]) -> None: + """ + Test different MaLos. + Field optional -> None values are allowed + """ + + def _instantiate_malo(malo_id: str) -> None: + _ = Bilanzierung( + marktlokations_id=malo_id, + ) + + if not malo_id_valid[1]: + with pytest.raises(ValidationError): + _instantiate_malo(malo_id_valid[0]) + else: + _instantiate_malo(malo_id_valid[0]) From 004e9bd1c968d28f84bef0162a2932bdabc477f7 Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Mon, 21 Aug 2023 12:14:39 +0200 Subject: [PATCH 06/42] :construction: fixed minor issue in field validator in bilanzierung.py --- src/bo4e/bo/bilanzierung.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index 2c48bdfdb..286735f87 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -85,7 +85,7 @@ class Bilanzierung(Geschaeftsobjekt): @field_validator("marktlokations_id") @classmethod - def _validate_malo_if_given(cls, marktlokations_id: Optional[str]) -> str: + def _validate_malo_if_given(cls, marktlokations_id: Optional[str]) -> Optional[str]: if marktlokations_id is None: return marktlokations_id return validate_marktlokations_id(cls, marktlokations_id) From 98d36927a9bd78d6028e55200dd864f0488be29a Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Wed, 23 Aug 2023 12:25:30 +0200 Subject: [PATCH 07/42] :wastebasket: removed unused comment --- src/bo4e/bo/bilanzierung.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index 286735f87..c3192a0e8 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -30,9 +30,6 @@ class Bilanzierung(Geschaeftsobjekt): #: Welche Marktlokation marktlokations_id: Optional[str] = None - # todo: optional/add marktlokations_id check? - # _marktlokations_id_check = field_validator("marktlokations_id")(validate_marktlokations_id) - #: Eine Liste der verwendeten Lastprofile (SLP, SLP/TLP, ALP etc.) lastprofil: list[Optional[Lastprofil]] = [] #: Inklusiver Start der Bilanzierung From 1ccf38184b1ab1a24d96354368fcfa3b1e7638a5 Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Wed, 23 Aug 2023 13:51:56 +0200 Subject: [PATCH 08/42] :wastebasket: removed unused comments -> required/optional attributes --- src/bo4e/bo/bilanzierung.py | 4 ---- src/bo4e/com/lastprofil.py | 1 - src/bo4e/com/tagesparameter.py | 1 - 3 files changed, 6 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index c3192a0e8..db4b1f501 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -26,18 +26,14 @@ class Bilanzierung(Geschaeftsobjekt): bo_typ: BoTyp = BoTyp.BILANZIERUNG # added to botyp.py - # optional attributes #: Welche Marktlokation marktlokations_id: Optional[str] = None - #: Eine Liste der verwendeten Lastprofile (SLP, SLP/TLP, ALP etc.) lastprofil: list[Optional[Lastprofil]] = [] #: Inklusiver Start der Bilanzierung bilanzierungsbeginn: Optional[datetime] = None #: Exklusives Ende der Bilanzierung bilanzierungsende: Optional[datetime] = None - # todo: add tests? - #: Bilanzkreis bilanzkreis: Optional[str] = None #: Jahresverbrauchsprognose diff --git a/src/bo4e/com/lastprofil.py b/src/bo4e/com/lastprofil.py index 487d01933..17a2694b6 100644 --- a/src/bo4e/com/lastprofil.py +++ b/src/bo4e/com/lastprofil.py @@ -17,7 +17,6 @@ class Lastprofil(COM): Lastprofil """ - # optional attributes #: Bezeichnung des Profils, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) bezeichnung: Optional[str] = None #: Optionale Bezeichnung der Profilschar, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) diff --git a/src/bo4e/com/tagesparameter.py b/src/bo4e/com/tagesparameter.py index e015682f9..1bdcef017 100644 --- a/src/bo4e/com/tagesparameter.py +++ b/src/bo4e/com/tagesparameter.py @@ -14,7 +14,6 @@ class Tagesparameter(COM): der Wetterstation für die Temperaturmessstelle """ - # optional attributes #: Qualifier der Klimazone, e.g. 7624q klimazone: Optional[str] = None #: Qualifier der Temperaturmessstelle, e.g. 1234x From 56cb779c6f4e28e79cd7458de1c48fc8c2fc5636 Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Wed, 23 Aug 2023 13:56:03 +0200 Subject: [PATCH 09/42] :bulb: updated comments for field validators --- src/bo4e/bo/bilanzierung.py | 5 ++++- src/bo4e/com/lastprofil.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index db4b1f501..c509e07dd 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -75,7 +75,10 @@ class Bilanzierung(Geschaeftsobjekt): prioritaet: Optional[int] = None #: Grund Wahlrecht der Prognosegrundlage(true=Wahlrecht beim Lieferanten vorhanden) grund_wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None - + """ + Validator für marktlokations_id. + Prüft, ob marktlokations_id, wenn gegeben, formal richtig ist. + """ @field_validator("marktlokations_id") @classmethod def _validate_malo_if_given(cls, marktlokations_id: Optional[str]) -> Optional[str]: diff --git a/src/bo4e/com/lastprofil.py b/src/bo4e/com/lastprofil.py index 17a2694b6..af5730127 100644 --- a/src/bo4e/com/lastprofil.py +++ b/src/bo4e/com/lastprofil.py @@ -29,10 +29,10 @@ class Lastprofil(COM): tagesparameter: Optional[Tagesparameter] = None #: Profilart des Lastprofils, e.g. ART_STANDARDLASTPROFIL profilart: Optional[Profilart] = None - _tagesparameter_check = field_validator("profilart")(tagesparameter_given_for_tagesparam_lastprofil) """ Field validator für Profilart. Wenn die Profilart tagesparameterabh. ist, muss ein Tagesparameter gegeben sein. """ + _tagesparameter_check = field_validator("profilart")(tagesparameter_given_for_tagesparam_lastprofil) #: Herausgeber des Lastprofil-Codes, e.g. BDEW herausgeber: Optional[str] = None From 2d7432df71c0a93f0e58683ba4693c2ef2af54cd Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Wed, 23 Aug 2023 13:57:50 +0200 Subject: [PATCH 10/42] :wastebasket: removed depracted comment in enum botyp --- src/bo4e/enum/botyp.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bo4e/enum/botyp.py b/src/bo4e/enum/botyp.py index dd5473952..f65d16be7 100644 --- a/src/bo4e/enum/botyp.py +++ b/src/bo4e/enum/botyp.py @@ -10,7 +10,6 @@ class BoTyp(StrEnum): ANGEBOT = "ANGEBOT" ANSPRECHPARTNER = "ANSPRECHPARTNER" AUSSCHREIBUNG = "AUSSCHREIBUNG" - # work in progress BILANZIERUNG = "BILANZIERUNG" BUENDELVERTRAG = "BUENDELVERTRAG" ENERGIEMENGE = "ENERGIEMENGE" From 1bd5c00699b36bcc3492a0a26a5eb0bd49a92070 Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Wed, 23 Aug 2023 14:01:37 +0200 Subject: [PATCH 11/42] :bulb: Updated description for enums. --- src/bo4e/enum/fallgruppenzuordnung.py | 2 +- src/bo4e/enum/profilart.py | 4 ++-- src/bo4e/enum/profiltyp.py | 4 ++-- src/bo4e/enum/profilverfahren.py | 4 ++-- src/bo4e/enum/prognosegrundlage.py | 4 ++-- src/bo4e/enum/wahlrechtprognosegrundlage.py | 4 ++-- src/bo4e/enum/zeitreihentyp.py | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/bo4e/enum/fallgruppenzuordnung.py b/src/bo4e/enum/fallgruppenzuordnung.py index 3862a3272..e31cde7fe 100644 --- a/src/bo4e/enum/fallgruppenzuordnung.py +++ b/src/bo4e/enum/fallgruppenzuordnung.py @@ -1,5 +1,5 @@ """ -Contains class Fallgruppenzuordnung +Contains Enums for Fallgruppenzuordnung """ from bo4e.enum.strenum import StrEnum diff --git a/src/bo4e/enum/profilart.py b/src/bo4e/enum/profilart.py index 22840e15b..6f8015253 100644 --- a/src/bo4e/enum/profilart.py +++ b/src/bo4e/enum/profilart.py @@ -1,5 +1,5 @@ """ -Contains class Profilart +Contains Enums for Profilart. """ from bo4e.enum.strenum import StrEnum @@ -7,7 +7,7 @@ class Profilart(StrEnum): """ - Profilart: temperaturabh./Standardlastprofil + Profilart: temperaturabh./Standardlastprofil. """ ART_STANDARDLASTPROFIL = "ART_STANDARDLASTPROFIL" #: ART_STANDARDLASTPROFIL, Z02 diff --git a/src/bo4e/enum/profiltyp.py b/src/bo4e/enum/profiltyp.py index 82cf546de..d2067b21c 100644 --- a/src/bo4e/enum/profiltyp.py +++ b/src/bo4e/enum/profiltyp.py @@ -1,5 +1,5 @@ """ -Contains class Profiltyp +Contains Enums for Profiltyp. """ from bo4e.enum.strenum import StrEnum @@ -7,7 +7,7 @@ class Profiltyp(StrEnum): """ - Profiltyp (temperaturabhängig / Standardlastprofil) + Profiltyp (temperaturabhängig / Standardlastprofil). """ SLP_SEP = "SLP_SEP" #: SLP/SEP diff --git a/src/bo4e/enum/profilverfahren.py b/src/bo4e/enum/profilverfahren.py index 3b88942ca..fa44c94fe 100644 --- a/src/bo4e/enum/profilverfahren.py +++ b/src/bo4e/enum/profilverfahren.py @@ -1,12 +1,12 @@ """ -Contains class Profilverfahren +Contains Enums for Profilverfahren. """ from bo4e.enum.strenum import StrEnum class Profilverfahren(StrEnum): """ - Profilverfahren: synthetisch/ analytisch + Profilverfahren: synthetisch/ analytisch. """ SYNTHETISCH = "SYNTHETISCH" #: SLP diff --git a/src/bo4e/enum/prognosegrundlage.py b/src/bo4e/enum/prognosegrundlage.py index b064346d7..db9353058 100644 --- a/src/bo4e/enum/prognosegrundlage.py +++ b/src/bo4e/enum/prognosegrundlage.py @@ -1,12 +1,12 @@ """ -Contains class Prognosegrundlage +Contains Enums for Prognosegrundlage. """ from bo4e.enum.strenum import StrEnum class Prognosegrundlage(StrEnum): """ - Prognosegrundlage (WERTE, PROFILE) + Prognosegrundlage (WERTE, PROFILE). """ WERTE = "WERTE" #: Prognose auf Basis von Werten diff --git a/src/bo4e/enum/wahlrechtprognosegrundlage.py b/src/bo4e/enum/wahlrechtprognosegrundlage.py index 4955ea303..a10d04de4 100644 --- a/src/bo4e/enum/wahlrechtprognosegrundlage.py +++ b/src/bo4e/enum/wahlrechtprognosegrundlage.py @@ -1,12 +1,12 @@ """ -Contains class Wahlrechtsprognosgrundlage +Contains Enums for Wahlrechtsprognosgrundlage. """ from bo4e.enum.strenum import StrEnum class WahlrechtPrognosegrundlage(StrEnum): """ - Wahlrecht der Prognosegrundlage der Marktlokation + Wahlrecht der Prognosegrundlage der Marktlokation. """ DURCH_LF = "DURCH_LF" #: Wahlrecht durch LF gegeben, remark: SG10 CAV diff --git a/src/bo4e/enum/zeitreihentyp.py b/src/bo4e/enum/zeitreihentyp.py index e1c1bd770..14451cd5b 100644 --- a/src/bo4e/enum/zeitreihentyp.py +++ b/src/bo4e/enum/zeitreihentyp.py @@ -1,5 +1,5 @@ """ -Contains class Zeitreihentyp +Contains Enums for Zeitreihentyp. """ from bo4e.enum.strenum import StrEnum From 4c3a73ebd1c69da31315a5d0a0352c298cd9387a Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Wed, 23 Aug 2023 14:05:11 +0200 Subject: [PATCH 12/42] :bulb: updated formatting of comments --- src/bo4e/bo/bilanzierung.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index c509e07dd..c23035b32 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -79,6 +79,7 @@ class Bilanzierung(Geschaeftsobjekt): Validator für marktlokations_id. Prüft, ob marktlokations_id, wenn gegeben, formal richtig ist. """ + @field_validator("marktlokations_id") @classmethod def _validate_malo_if_given(cls, marktlokations_id: Optional[str]) -> Optional[str]: From df48f3fbd05b4e21ed592f57444227cf2ccc960c Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Wed, 23 Aug 2023 15:07:39 +0200 Subject: [PATCH 13/42] :white_check_mark: added testsvariables to bo bilanzierung --- tests/test_bilanzierung.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index 39bf094c4..a5ba32985 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -156,12 +156,14 @@ def test_serialization_roundtrip(self, bilanzierung: Bilanzierung, expected_json ("41373559241", True), ("56789012345", True), ("52935155442", True), - ("12345678910", False), + ("12345678910", False), # Prüfsumme falsch + ("529351554422", False), # zu lang + ("5293515544", False), # zu kurz + ("5293v15a442", False), # Mix aus Zahlen und Buchstaben ("asdasd", False), (" ", False), (" asdasdasd ", False), - ("keine malo id", False), - (None, True), + (None, True), # malo_id not required ("", False), ], ) From a3b63def62d4648837179cf9aefa5fe7b9bfee54 Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Wed, 23 Aug 2023 15:16:55 +0200 Subject: [PATCH 14/42] Minor corrections --- src/bo4e/bo/bilanzierung.py | 4 ++-- tests/test_bilanzierung.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index c23035b32..7169182ad 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -29,7 +29,7 @@ class Bilanzierung(Geschaeftsobjekt): #: Welche Marktlokation marktlokations_id: Optional[str] = None #: Eine Liste der verwendeten Lastprofile (SLP, SLP/TLP, ALP etc.) - lastprofil: list[Optional[Lastprofil]] = [] + lastprofil: Optional[list[Lastprofil]] = None #: Inklusiver Start der Bilanzierung bilanzierungsbeginn: Optional[datetime] = None #: Exklusives Ende der Bilanzierung @@ -66,7 +66,7 @@ class Bilanzierung(Geschaeftsobjekt): Besteht der Bedarf ein tagesparameteräbhängiges Lastprofil mit gemeinsamer Messung anzugeben, so ist dies über die 2 -malige Wiederholung des CAV Segments mit der Angabe der Codes E02 und E14 möglich. """ - details_prognosegrundlage: list[Optional[Profiltyp]] = [] + details_prognosegrundlage: Optional[list[Profiltyp]] = None #: Wahlrecht der Prognosegrundlage (true = Wahlrecht beim Lieferanten vorhanden) wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None #: Fallgruppenzuordnung (für gas RLM) diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index a5ba32985..c898723e6 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -163,7 +163,7 @@ def test_serialization_roundtrip(self, bilanzierung: Bilanzierung, expected_json ("asdasd", False), (" ", False), (" asdasdasd ", False), - (None, True), # malo_id not required + (None, True), # malo_id not required ("", False), ], ) From ce483ae5de0c7c0f5f49bfcbbca39b164a549799 Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Wed, 23 Aug 2023 15:22:17 +0200 Subject: [PATCH 15/42] :white_check_mark: Fixed tests in bo --- tests/test_bilanzierung.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index c898723e6..1db630392 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -122,7 +122,7 @@ class TestBilanzierung: "boTyp": BoTyp.BILANZIERUNG, "externeReferenzen": [], "marktlokationsId": None, - "lastprofil": [], + "lastprofil": None, "bilanzierungsbeginn": None, "bilanzierungsende": None, "bilanzkreis": None, @@ -133,7 +133,7 @@ class TestBilanzierung: "zeitreihentyp": None, "aggregationsverantwortung": None, "prognosegrundlage": None, - "detailsPrognosegrundlage": [], + "detailsPrognosegrundlage": None, "wahlrechtPrognosegrundlage": None, "fallgruppenzuordnung": None, "prioritaet": None, From 636958bce49b11f787c670c5d5c7f639fe4f5c7f Mon Sep 17 00:00:00 2001 From: Daniel <139119540+hf-ddernbach@users.noreply.github.com> Date: Mon, 28 Aug 2023 09:40:58 +0200 Subject: [PATCH 16/42] Update src/bo4e/bo/bilanzierung.py Co-authored-by: Leon Haffmans <49658102+lord-haffi@users.noreply.github.com> --- src/bo4e/bo/bilanzierung.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index 7169182ad..ab59e7f17 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -75,14 +75,14 @@ class Bilanzierung(Geschaeftsobjekt): prioritaet: Optional[int] = None #: Grund Wahlrecht der Prognosegrundlage(true=Wahlrecht beim Lieferanten vorhanden) grund_wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None - """ - Validator für marktlokations_id. - Prüft, ob marktlokations_id, wenn gegeben, formal richtig ist. - """ @field_validator("marktlokations_id") @classmethod def _validate_malo_if_given(cls, marktlokations_id: Optional[str]) -> Optional[str]: + """ + Validator für marktlokations_id. + Prüft, ob marktlokations_id, wenn gegeben, formal richtig ist. + """ if marktlokations_id is None: return marktlokations_id return validate_marktlokations_id(cls, marktlokations_id) From d9173a0de85c58b9d33b469de5a85e2a61a64f63 Mon Sep 17 00:00:00 2001 From: Daniel <139119540+hf-ddernbach@users.noreply.github.com> Date: Mon, 28 Aug 2023 09:42:46 +0200 Subject: [PATCH 17/42] Update tests/test_bilanzierung.py Co-authored-by: Leon Haffmans <49658102+lord-haffi@users.noreply.github.com> --- tests/test_bilanzierung.py | 41 +++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index 1db630392..e0f4fd69a 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -150,36 +150,31 @@ def test_serialization_roundtrip(self, bilanzierung: Bilanzierung, expected_json assert_serialization_roundtrip(bilanzierung, expected_json_dict) @pytest.mark.parametrize( - "malo_id_valid", + "malo_id,is_valid", [ - ("51238696781", True), - ("41373559241", True), - ("56789012345", True), - ("52935155442", True), - ("12345678910", False), # Prüfsumme falsch - ("529351554422", False), # zu lang - ("5293515544", False), # zu kurz - ("5293v15a442", False), # Mix aus Zahlen und Buchstaben - ("asdasd", False), - (" ", False), - (" asdasdasd ", False), - (None, True), # malo_id not required - ("", False), + pytest.param("51238696781", True), + pytest.param("41373559241", True), + pytest.param("56789012345", True), + pytest.param("52935155442", True), + pytest.param("12345678910", False, id="wrong checksum"), + pytest.param("529351554422", False, id="too long"), + pytest.param("5293515544", False, id=""too short"), + pytest.param("5293v15a442", False, id="alphanumeric"), + pytest.param("asdasd", False), + pytest.param(" ", False), + pytest.param(" asdasdasd ", False), + pytest.param(None, True, id="malo_id not required"), + pytest.param("", False), ], ) - def test_id_validation(self, malo_id_valid: Tuple[str, bool]) -> None: + def test_id_validation(self, malo_id: str, is_valid: bool) -> None: """ Test different MaLos. Field optional -> None values are allowed """ - def _instantiate_malo(malo_id: str) -> None: - _ = Bilanzierung( - marktlokations_id=malo_id, - ) - - if not malo_id_valid[1]: + if not is_valid: with pytest.raises(ValidationError): - _instantiate_malo(malo_id_valid[0]) + _ = Bilanzierung(marktlokations_id=malo_id) else: - _instantiate_malo(malo_id_valid[0]) + _ = Bilanzierung(marktlokations_id=malo_id) From 77bc4008d6044d471ed2b589747d578406c0bb0a Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Mon, 28 Aug 2023 13:51:09 +0200 Subject: [PATCH 18/42] typo/black/iso --- src/bo4e/bo/bilanzierung.py | 2 +- tests/test_bilanzierung.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index ab59e7f17..a627a5322 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -81,7 +81,7 @@ class Bilanzierung(Geschaeftsobjekt): def _validate_malo_if_given(cls, marktlokations_id: Optional[str]) -> Optional[str]: """ Validator für marktlokations_id. - Prüft, ob marktlokations_id, wenn gegeben, formal richtig ist. + Prüft, ob marktlokations_id, wenn gegeben, formal richtig ist. """ if marktlokations_id is None: return marktlokations_id diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index e0f4fd69a..650be4a8e 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -158,7 +158,7 @@ def test_serialization_roundtrip(self, bilanzierung: Bilanzierung, expected_json pytest.param("52935155442", True), pytest.param("12345678910", False, id="wrong checksum"), pytest.param("529351554422", False, id="too long"), - pytest.param("5293515544", False, id=""too short"), + pytest.param("5293515544", False, id="too short"), pytest.param("5293v15a442", False, id="alphanumeric"), pytest.param("asdasd", False), pytest.param(" ", False), From e41bd3e74a8419edb5e385976f8bf173e71c7344 Mon Sep 17 00:00:00 2001 From: hf-ddernbach Date: Mon, 28 Aug 2023 15:03:01 +0200 Subject: [PATCH 19/42] :memo: updated documentation --- src/bo4e/bo/bilanzierung.py | 67 +++++++++++++-------------- src/bo4e/com/lastprofil.py | 33 ++++++------- src/bo4e/com/tagesparameter.py | 12 ++--- src/bo4e/enum/fallgruppenzuordnung.py | 6 +-- src/bo4e/enum/profilart.py | 2 +- tests/test_bilanzierung.py | 4 +- tests/test_lastprofil.py | 4 +- tests/test_tagesparameter.py | 4 +- 8 files changed, 62 insertions(+), 70 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index a627a5322..356f21aa8 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -24,64 +24,59 @@ class Bilanzierung(Geschaeftsobjekt): Bilanzierungs BO """ - bo_typ: BoTyp = BoTyp.BILANZIERUNG # added to botyp.py + bo_typ: BoTyp = BoTyp.BILANZIERUNG - #: Welche Marktlokation - marktlokations_id: Optional[str] = None - #: Eine Liste der verwendeten Lastprofile (SLP, SLP/TLP, ALP etc.) - lastprofil: Optional[list[Lastprofil]] = None - #: Inklusiver Start der Bilanzierung - bilanzierungsbeginn: Optional[datetime] = None - #: Exklusives Ende der Bilanzierung - bilanzierungsende: Optional[datetime] = None - #: Bilanzkreis - bilanzkreis: Optional[str] = None - #: Jahresverbrauchsprognose - jahresverbrauchsprognose: Optional[Menge] = None - #: Temperatur Arbeit - temperatur_arbeit: Optional[Menge] = None - #: Kundenwert - kundenwert: Optional[Menge] = None + marktlokations_id: Optional[str] = None #: ID der Marktlokation + lastprofil: Optional[list[Lastprofil]] = None #: Eine Liste der verwendeten Lastprofile (SLP, SLP/TLP, ALP etc.) + bilanzierungsbeginn: Optional[datetime] = None #: Inklusiver Start der Bilanzierung + bilanzierungsende: Optional[datetime] = None #: Exklusives Ende der Bilanzierung + bilanzkreis: Optional[str] = None #: Bilanzkreis + jahresverbrauchsprognose: Optional[Menge] = None #: Jahresverbrauchsprognose + temperatur_arbeit: Optional[Menge] = None #: Temperatur Arbeit + kundenwert: Optional[Menge] = None #: Kundenwert + verbrauchsaufteilung: Optional[float] = None """ Verbrauchsaufteilung in % zwischen SLP und TLP-Profil. - + 1. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] * [Verbrauchsaufteilung in % / 100%] = [zu verlagernde Energiemenge] 2. [Gemessene Energiemenge der OBIS "Schwachlast"] - [zu verlagernde Energiemenge] = [Ermittelte Energiemenge für Schwachlast] 3. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] + [zu verlagernde Energiemenge] = [Ermittelte Energiemenge für nicht Schwachlast] - + """ - verbrauchsaufteilung: Optional[float] = None - #: Zeitreihentyp (SLS, TLS, etc.) - zeitreihentyp: Optional[Zeitreihentyp] = None - #: Aggregationsverantwortung - aggregationsverantwortung: Optional[Aggregationsverantwortung] = None - #: Prognosegrundlage - prognosegrundlage: Optional[Prognosegrundlage] = None + zeitreihentyp: Optional[Zeitreihentyp] = None #: Zeitreihentyp (SLS, TLS, etc.) + aggregationsverantwortung: Optional[Aggregationsverantwortung] = None #: Aggregationsverantwortung + prognosegrundlage: Optional[Prognosegrundlage] = None #: Prognosegrundlage + details_prognosegrundlage: Optional[list[Profiltyp]] = None """ Prognosegrundlage. - + Besteht der Bedarf ein tagesparameteräbhängiges Lastprofil mit gemeinsamer Messung anzugeben, so ist dies über die 2 -malige Wiederholung des CAV Segments mit der Angabe der Codes E02 und E14 möglich. """ - details_prognosegrundlage: Optional[list[Profiltyp]] = None - #: Wahlrecht der Prognosegrundlage (true = Wahlrecht beim Lieferanten vorhanden) wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None - #: Fallgruppenzuordnung (für gas RLM) - fallgruppenzuordnung: Optional[Fallgruppenzuordnung] = None - #: Priorität des Bilanzkreises (für Gas) - prioritaet: Optional[int] = None - #: Grund Wahlrecht der Prognosegrundlage(true=Wahlrecht beim Lieferanten vorhanden) + """ + Wahlrecht der Prognosegrundlage. + + true = Wahlrecht beim Lieferanten vorhanden + """ + fallgruppenzuordnung: Optional[Fallgruppenzuordnung] = None #: Fallgruppenzuordnung (für gas RLM) + prioritaet: Optional[int] = None #: Priorität des Bilanzkreises (für Gas) grund_wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None + """ + Grund Wahlrecht der Prognosegrundlage. + + true=Wahlrecht beim Lieferanten vorhanden + """ @field_validator("marktlokations_id") @classmethod def _validate_malo_if_given(cls, marktlokations_id: Optional[str]) -> Optional[str]: """ - Validator für marktlokations_id. - Prüft, ob marktlokations_id, wenn gegeben, formal richtig ist. + Validator for field marktlokations_id. + Validates formal correctness of marktlokations_id if given. """ if marktlokations_id is None: return marktlokations_id diff --git a/src/bo4e/com/lastprofil.py b/src/bo4e/com/lastprofil.py index af5730127..ab20377ba 100644 --- a/src/bo4e/com/lastprofil.py +++ b/src/bo4e/com/lastprofil.py @@ -17,22 +17,23 @@ class Lastprofil(COM): Lastprofil """ - #: Bezeichnung des Profils, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) - bezeichnung: Optional[str] = None - #: Optionale Bezeichnung der Profilschar, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) - profilschar: Optional[str] = None - #: Verfahren des Profils (analytisch oder synthetisch) - verfahren: Optional[Profilverfahren] = None - #: Einspeiseprofil: True/False + bezeichnung: Optional[str] = None #: Bezeichnung des Profils, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) + profilschar: Optional[ + str + ] = None #: Bezeichnung der Profilschar, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) + verfahren: Optional[Profilverfahren] = None #: Verfahren des Profils (analytisch oder synthetisch) einspeisung: Optional[bool] = None - #: Klimazone / Temperaturmessstelle - tagesparameter: Optional[Tagesparameter] = None - #: Profilart des Lastprofils, e.g. ART_STANDARDLASTPROFIL - profilart: Optional[Profilart] = None - """ - Field validator für Profilart. - Wenn die Profilart tagesparameterabh. ist, muss ein Tagesparameter gegeben sein. """ + Einspeiseprofil: + + True/False + """ + tagesparameter: Optional[Tagesparameter] = None #: Klimazone / Temperaturmessstelle + profilart: Optional[Profilart] = None #: Profilart des Lastprofils, e.g. ART_STANDARDLASTPROFIL + herausgeber: Optional[str] = None #: Herausgeber des Lastprofil-Codes, e.g. BDEW + _tagesparameter_check = field_validator("profilart")(tagesparameter_given_for_tagesparam_lastprofil) - #: Herausgeber des Lastprofil-Codes, e.g. BDEW - herausgeber: Optional[str] = None + """ + Field validator for profilart. + Tagesparameter needs to be set if profilart is depended on daily parameters. + """ diff --git a/src/bo4e/com/tagesparameter.py b/src/bo4e/com/tagesparameter.py index 1bdcef017..6c3381002 100644 --- a/src/bo4e/com/tagesparameter.py +++ b/src/bo4e/com/tagesparameter.py @@ -14,11 +14,7 @@ class Tagesparameter(COM): der Wetterstation für die Temperaturmessstelle """ - #: Qualifier der Klimazone, e.g. 7624q - klimazone: Optional[str] = None - #: Qualifier der Temperaturmessstelle, e.g. 1234x - temperaturmessstelle: Optional[str] = None - #: Dienstanbieter (bei Temperaturmessstellen), e.g. ZT1 - dienstanbieter: Optional[str] = None - #: Herausgeber des Lastprofil-Codes, e.g. BDEW - herausgeber: Optional[str] = None + klimazone: Optional[str] = None #: Qualifier der Klimazone, e.g. 7624q + temperaturmessstelle: Optional[str] = None #: Qualifier der Temperaturmessstelle, e.g. 1234x + dienstanbieter: Optional[str] = None #: Dienstanbieter (bei Temperaturmessstellen), e.g. ZT1 + herausgeber: Optional[str] = None #: Herausgeber des Lastprofil-Codes, e.g. BDEW diff --git a/src/bo4e/enum/fallgruppenzuordnung.py b/src/bo4e/enum/fallgruppenzuordnung.py index e31cde7fe..d34e7ba58 100644 --- a/src/bo4e/enum/fallgruppenzuordnung.py +++ b/src/bo4e/enum/fallgruppenzuordnung.py @@ -12,8 +12,8 @@ class Fallgruppenzuordnung(StrEnum): # todo: Uppercase-Problematik klären. -> pylint GABI_RLMmT = "GABI_RLMmT" # pylint:disable=invalid-name - # #: RLM mit Tagesband, + """RLM mit Tagesband""" GABI_RLMoT = "GABI_RLMoT" # pylint:disable=invalid-name - # #: RLM ohne Tagesband, + """RLM ohne Tagesband""" GABI_RLMNEV = "GABI_RLMNEV" - #: RLM im Nominierungsersatzverfahren + """RLM im Nominierungsersatzverfahren""" diff --git a/src/bo4e/enum/profilart.py b/src/bo4e/enum/profilart.py index 6f8015253..10510e4dd 100644 --- a/src/bo4e/enum/profilart.py +++ b/src/bo4e/enum/profilart.py @@ -12,5 +12,5 @@ class Profilart(StrEnum): ART_STANDARDLASTPROFIL = "ART_STANDARDLASTPROFIL" #: ART_STANDARDLASTPROFIL, Z02 ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL = "ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL" - #: ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL, Z03 + """ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL, Z03""" ART_LASTPROFIL = "ART_LASTPROFIL" #: ART_LASTPROFIL, Z12 diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index 650be4a8e..5f3a9108a 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -21,7 +21,7 @@ from bo4e.enum.zeitreihentyp import Zeitreihentyp from tests.serialization_helper import assert_serialization_roundtrip -#: full example +# full example example_bilanzierung = Bilanzierung( marktlokations_id="51238696781", lastprofil=[ @@ -145,7 +145,7 @@ class TestBilanzierung: ) def test_serialization_roundtrip(self, bilanzierung: Bilanzierung, expected_json_dict: Dict[str, Any]) -> None: """ - Test de-/serialisation of Bilanzierung with minimal attributes. + Test de-/serialisation of Bilanzierung with maximal/minimal attributes. """ assert_serialization_roundtrip(bilanzierung, expected_json_dict) diff --git a/tests/test_lastprofil.py b/tests/test_lastprofil.py index 8f27f2c20..8b555bed8 100644 --- a/tests/test_lastprofil.py +++ b/tests/test_lastprofil.py @@ -9,7 +9,7 @@ from bo4e.enum.profilverfahren import Profilverfahren from tests.serialization_helper import assert_serialization_roundtrip -#: maximal example +# maximal example example_lastprofil = Lastprofil( bezeichnung="foo", profilschar="foo2", @@ -65,7 +65,7 @@ class TestLastprofil: ) def test_serialization_roundtrip(self, lastprofil: Lastprofil, expected_json_dict: Dict[str, Any]) -> None: """ - Test de-/serialisation of Lastprofil with minimal attributes. + Test de-/serialisation of Lastprofil with maximal/minimal attributes. """ assert_serialization_roundtrip(lastprofil, expected_json_dict) diff --git a/tests/test_tagesparameter.py b/tests/test_tagesparameter.py index 72e060fd6..a69aaeabc 100644 --- a/tests/test_tagesparameter.py +++ b/tests/test_tagesparameter.py @@ -5,7 +5,7 @@ from bo4e.com.tagesparameter import Tagesparameter from tests.serialization_helper import assert_serialization_roundtrip -#: full example +# full example example_tagesparameter = Tagesparameter( klimazone="7624q", temperaturmessstelle="1234x", @@ -43,6 +43,6 @@ class TestTagesparameter: ) def test_serialization_roundtrip(self, tagesparameter: Tagesparameter, expected_json_dict: Dict[str, Any]) -> None: """ - Test de-/serialisation of Tagesparameter with minimal attributes. + Test de-/serialisation of Tagesparameter with maximal/minimal attributes. """ assert_serialization_roundtrip(tagesparameter, expected_json_dict) From fd4d6f47f541582f4b3c7737dcbfd9383b19eb7a Mon Sep 17 00:00:00 2001 From: Franziska Date: Fri, 24 Nov 2023 20:50:05 +0100 Subject: [PATCH 20/42] Add new BO, COMs and ENUMs to init.py --- src/bo4e/__init__.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/bo4e/__init__.py b/src/bo4e/__init__.py index 3d132ae4a..0d9becdd8 100644 --- a/src/bo4e/__init__.py +++ b/src/bo4e/__init__.py @@ -11,6 +11,7 @@ "Angebot", "Ansprechpartner", "Ausschreibung", + "Bilanzierung", "Buendelvertrag", "Energiemenge", "Fremdkosten", @@ -63,6 +64,7 @@ "Kostenblock", "Kostenposition", "KriteriumWert", + "Lastprofil", "MarktgebietInfo", "Menge", "Messlokationszuordnung", @@ -83,6 +85,7 @@ "StandorteigenschaftenGas", "StandorteigenschaftenStrom", "Steuerbetrag", + "Tagesparameter", "Tarifberechnungsparameter", "Tarifeinschraenkung", "Tarifpreis", @@ -101,6 +104,7 @@ "Zeitspanne", "Zustaendigkeit", "AbgabeArt", + "Aggregationsverantwortung", "Angebotsstatus", "Anrede", "ArithmetischeOperation", @@ -117,6 +121,7 @@ "Dienstleistungstyp", "Energierichtung", "Erzeugungsart", + "Fallgruppenzuordnung", "Gasqualitaet", "Gebiettyp", "Geraeteklasse", @@ -150,6 +155,10 @@ "Preismodell", "Preisstatus", "Preistyp", + "Profilart", + "Profiltyp", + "Profilverfahren", + "Prognosegrundlage", "Rechnungslegung", "Rechnungsstatus", "Rechnungstyp", @@ -174,6 +183,7 @@ "Vertragsstatus", "Verwendungszweck", "Voraussetzungen", + "WahlrechtPrognosegrundlage", "Waehrungscode", "Waehrungseinheit", "Waermenutzung", @@ -182,6 +192,7 @@ "Zaehlergroesse", "Zaehlertyp", "ZaehlertypSpezifikation", + "Zeitreihentyp", "__version__", ] @@ -189,6 +200,7 @@ from .bo.angebot import Angebot from .bo.ansprechpartner import Ansprechpartner from .bo.ausschreibung import Ausschreibung +from .bo.bilanzierung import Bilanzierung from .bo.buendelvertrag import Buendelvertrag from .bo.energiemenge import Energiemenge from .bo.fremdkosten import Fremdkosten @@ -243,6 +255,7 @@ from .com.kostenblock import Kostenblock from .com.kostenposition import Kostenposition from .com.kriteriumwert import KriteriumWert +from .com.lastprofil import Lastprofil from .com.marktgebietinfo import MarktgebietInfo from .com.menge import Menge from .com.messlokationszuordnung import Messlokationszuordnung @@ -263,6 +276,7 @@ from .com.standorteigenschaftengas import StandorteigenschaftenGas from .com.standorteigenschaftenstrom import StandorteigenschaftenStrom from .com.steuerbetrag import Steuerbetrag +from .com.tagesparameter import Tagesparameter from .com.tarifberechnungsparameter import Tarifberechnungsparameter from .com.tarifeinschraenkung import Tarifeinschraenkung from .com.tarifpreis import Tarifpreis @@ -283,6 +297,7 @@ # Import Enums from .enum.abgabeart import AbgabeArt +from .enum.aggregationsverantwortung import Aggregationsverantwortung from .enum.angebotsstatus import Angebotsstatus from .enum.anrede import Anrede from .enum.arithmetische_operation import ArithmetischeOperation @@ -299,6 +314,7 @@ from .enum.dienstleistungstyp import Dienstleistungstyp from .enum.energierichtung import Energierichtung from .enum.erzeugungsart import Erzeugungsart +from .enum.fallgruppenzuordnung import Fallgruppenzuordnung from .enum.gasqualitaet import Gasqualitaet from .enum.gebiettyp import Gebiettyp from .enum.geraeteklasse import Geraeteklasse @@ -332,6 +348,10 @@ from .enum.preismodell import Preismodell from .enum.preisstatus import Preisstatus from .enum.preistyp import Preistyp +from .enum.profilart import Profilart +from .enum.profiltyp import Profiltyp +from .enum.profilverfahren import Profilverfahren +from .enum.prognosegrundlage import Prognosegrundlage from .enum.rechnungslegung import Rechnungslegung from .enum.rechnungsstatus import Rechnungsstatus from .enum.rechnungstyp import Rechnungstyp @@ -359,9 +379,11 @@ from .enum.waehrungscode import Waehrungscode from .enum.waehrungseinheit import Waehrungseinheit from .enum.waermenutzung import Waermenutzung +from .enum.wahlrechtprognosegrundlage import WahlrechtPrognosegrundlage from .enum.wertermittlungsverfahren import Wertermittlungsverfahren from .enum.zaehlerauspraegung import Zaehlerauspraegung from .enum.zaehlergroesse import Zaehlergroesse from .enum.zaehlertyp import Zaehlertyp from .enum.zaehlertypspezifikation import ZaehlertypSpezifikation +from .enum.zeitreihentyp import Zeitreihentyp from .version import __version__ From 1b12ba87f944bad6443a6a9ab1fd28b9a3aec0fe Mon Sep 17 00:00:00 2001 From: Franziska Date: Fri, 24 Nov 2023 21:07:16 +0100 Subject: [PATCH 21/42] Remove validation and adapt test --- src/bo4e/bo/bilanzierung.py | 31 ++---- src/bo4e/bo/energiemenge.py | 2 - src/bo4e/com/lastprofil.py | 11 +-- tests/test_bilanzierung.py | 188 +++++++----------------------------- 4 files changed, 48 insertions(+), 184 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index 356f21aa8..6821a41b7 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -2,21 +2,21 @@ Contains class Bilanzierung """ from datetime import datetime -from typing import Optional +from typing import Annotated, Optional -from pydantic import field_validator +from pydantic import Field from bo4e.bo.geschaeftsobjekt import Geschaeftsobjekt from bo4e.com.lastprofil import Lastprofil from bo4e.com.menge import Menge from bo4e.enum.aggregationsverantwortung import Aggregationsverantwortung -from bo4e.enum.botyp import BoTyp from bo4e.enum.fallgruppenzuordnung import Fallgruppenzuordnung from bo4e.enum.profiltyp import Profiltyp from bo4e.enum.prognosegrundlage import Prognosegrundlage from bo4e.enum.wahlrechtprognosegrundlage import WahlrechtPrognosegrundlage from bo4e.enum.zeitreihentyp import Zeitreihentyp -from bo4e.validators import validate_marktlokations_id + +from ..enum.typ import Typ class Bilanzierung(Geschaeftsobjekt): @@ -24,7 +24,7 @@ class Bilanzierung(Geschaeftsobjekt): Bilanzierungs BO """ - bo_typ: BoTyp = BoTyp.BILANZIERUNG + typ: Annotated[Optional[Typ], Field(alias="_typ")] = Typ.BILANZIERUNG marktlokations_id: Optional[str] = None #: ID der Marktlokation lastprofil: Optional[list[Lastprofil]] = None #: Eine Liste der verwendeten Lastprofile (SLP, SLP/TLP, ALP etc.) @@ -38,11 +38,11 @@ class Bilanzierung(Geschaeftsobjekt): """ Verbrauchsaufteilung in % zwischen SLP und TLP-Profil. - 1. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] * [Verbrauchsaufteilung in % / 100%] + 1. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] * [Verbrauchsaufteilung in % / 100%] = [zu verlagernde Energiemenge] - 2. [Gemessene Energiemenge der OBIS "Schwachlast"] - [zu verlagernde Energiemenge] + 2. [Gemessene Energiemenge der OBIS "Schwachlast"] - [zu verlagernde Energiemenge] = [Ermittelte Energiemenge für Schwachlast] - 3. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] + [zu verlagernde Energiemenge] + 3. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] + [zu verlagernde Energiemenge] = [Ermittelte Energiemenge für nicht Schwachlast] """ @@ -59,7 +59,7 @@ class Bilanzierung(Geschaeftsobjekt): wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None """ Wahlrecht der Prognosegrundlage. - + true = Wahlrecht beim Lieferanten vorhanden """ fallgruppenzuordnung: Optional[Fallgruppenzuordnung] = None #: Fallgruppenzuordnung (für gas RLM) @@ -67,17 +67,6 @@ class Bilanzierung(Geschaeftsobjekt): grund_wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None """ Grund Wahlrecht der Prognosegrundlage. - + true=Wahlrecht beim Lieferanten vorhanden """ - - @field_validator("marktlokations_id") - @classmethod - def _validate_malo_if_given(cls, marktlokations_id: Optional[str]) -> Optional[str]: - """ - Validator for field marktlokations_id. - Validates formal correctness of marktlokations_id if given. - """ - if marktlokations_id is None: - return marktlokations_id - return validate_marktlokations_id(cls, marktlokations_id) diff --git a/src/bo4e/bo/energiemenge.py b/src/bo4e/bo/energiemenge.py index 62762e1da..6f81d807e 100644 --- a/src/bo4e/bo/energiemenge.py +++ b/src/bo4e/bo/energiemenge.py @@ -31,10 +31,8 @@ class Energiemenge(Geschaeftsobjekt): typ: Annotated[Optional[Typ], Field(alias="_typ")] = Typ.ENERGIEMENGE #: Eindeutige Nummer der Marktlokation bzw. der Messlokation, zu der die Energiemenge gehört lokations_id: Optional[str] = None - # todo: add validator such that only mess- or marktlokations IDs are accepted + cross check with lokationstyp #: Gibt an, ob es sich um eine Markt- oder Messlokation handelt lokationstyp: Optional[Lokationstyp] = None - #: Gibt den Verbrauch in einer Zeiteinheit an energieverbrauch: Optional[list[Verbrauch]] = None # there are no optional attributes diff --git a/src/bo4e/com/lastprofil.py b/src/bo4e/com/lastprofil.py index ab20377ba..925bd3835 100644 --- a/src/bo4e/com/lastprofil.py +++ b/src/bo4e/com/lastprofil.py @@ -3,13 +3,10 @@ """ from typing import Optional -from pydantic import field_validator - from bo4e.com.com import COM from bo4e.com.tagesparameter import Tagesparameter from bo4e.enum.profilart import Profilart from bo4e.enum.profilverfahren import Profilverfahren -from bo4e.validators import tagesparameter_given_for_tagesparam_lastprofil class Lastprofil(COM): @@ -25,15 +22,9 @@ class Lastprofil(COM): einspeisung: Optional[bool] = None """ Einspeiseprofil: - + True/False """ tagesparameter: Optional[Tagesparameter] = None #: Klimazone / Temperaturmessstelle profilart: Optional[Profilart] = None #: Profilart des Lastprofils, e.g. ART_STANDARDLASTPROFIL herausgeber: Optional[str] = None #: Herausgeber des Lastprofil-Codes, e.g. BDEW - - _tagesparameter_check = field_validator("profilart")(tagesparameter_given_for_tagesparam_lastprofil) - """ - Field validator for profilart. - Tagesparameter needs to be set if profilart is depended on daily parameters. - """ diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index 5f3a9108a..aca1becbe 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -1,16 +1,13 @@ from datetime import datetime, timezone -from typing import Any, Dict, Tuple import pytest from _decimal import Decimal -from pydantic import ValidationError from bo4e.bo.bilanzierung import Bilanzierung from bo4e.com.lastprofil import Lastprofil from bo4e.com.menge import Menge from bo4e.com.tagesparameter import Tagesparameter from bo4e.enum.aggregationsverantwortung import Aggregationsverantwortung -from bo4e.enum.botyp import BoTyp from bo4e.enum.fallgruppenzuordnung import Fallgruppenzuordnung from bo4e.enum.mengeneinheit import Mengeneinheit from bo4e.enum.profilart import Profilart @@ -21,160 +18,49 @@ from bo4e.enum.zeitreihentyp import Zeitreihentyp from tests.serialization_helper import assert_serialization_roundtrip -# full example -example_bilanzierung = Bilanzierung( - marktlokations_id="51238696781", - lastprofil=[ - Lastprofil( - bezeichnung="foo", - profilschar="foo2", - verfahren=Profilverfahren.SYNTHETISCH, - einspeisung=True, - tagesparameter=Tagesparameter( - klimazone="7624q", - temperaturmessstelle="1234x", - dienstanbieter="ZT1", - herausgeber="BDEW", - ), - profilart=Profilart.ART_LASTPROFIL, - herausgeber="BDEW", - ) - ], - bilanzierungsbeginn=datetime(2022, 1, 1, 0, 0, 0, tzinfo=timezone.utc), - bilanzierungsende=datetime(2023, 1, 1, 0, 0, 0, tzinfo=timezone.utc), - bilanzkreis="foo", - jahresverbrauchsprognose=Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH), - temperatur_arbeit=Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH), - # todo: check einheiten - kundenwert=Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH), - verbrauchsaufteilung=1.5, - zeitreihentyp=Zeitreihentyp.EGS, - aggregationsverantwortung=Aggregationsverantwortung.VNB, - prognosegrundlage=Prognosegrundlage.WERTE, - details_prognosegrundlage=[Profiltyp.SLP_SEP], - wahlrecht_prognosegrundlage=WahlrechtPrognosegrundlage.DURCH_LF, - fallgruppenzuordnung=Fallgruppenzuordnung.GABI_RLMmT, - prioritaet=1, - grund_wahlrecht_prognosegrundlage=WahlrechtPrognosegrundlage.DURCH_LF_NICHT_GEGEBEN, -) - class TestBilanzierung: @pytest.mark.parametrize( - "bilanzierung, expected_json_dict", + "bilanzierung", [ pytest.param( - example_bilanzierung, - { - # todo: cf. alias_generator=camelize in geschaeftsobjekte.py - "versionstruktur": "2", - "boTyp": BoTyp.BILANZIERUNG, - "externeReferenzen": [], - "marktlokationsId": "51238696781", - "lastprofil": [ - { - "bezeichnung": "foo", - "profilschar": "foo2", - "verfahren": Profilverfahren.SYNTHETISCH, - "einspeisung": True, - "tagesparameter": { - "klimazone": "7624q", - "temperaturmessstelle": "1234x", - "dienstanbieter": "ZT1", - "herausgeber": "BDEW", - }, - "profilart": Profilart.ART_LASTPROFIL, - "herausgeber": "BDEW", - } + Bilanzierung( + marktlokations_id="51238696781", + lastprofil=[ + Lastprofil( + bezeichnung="foo", + profilschar="foo2", + verfahren=Profilverfahren.SYNTHETISCH, + einspeisung=True, + tagesparameter=Tagesparameter( + klimazone="7624q", + temperaturmessstelle="1234x", + dienstanbieter="ZT1", + herausgeber="BDEW", + ), + profilart=Profilart.ART_LASTPROFIL, + herausgeber="BDEW", + ) ], - "bilanzierungsbeginn": datetime(2022, 1, 1, 0, 0, 0, tzinfo=timezone.utc), - "bilanzierungsende": datetime(2023, 1, 1, 0, 0, 0, tzinfo=timezone.utc), - "bilanzkreis": "foo", - "jahresverbrauchsprognose": { - "wert": 3.41, - "einheit": Mengeneinheit.MWH, - }, - "temperaturArbeit": { - "wert": 3.41, - "einheit": Mengeneinheit.MWH, - }, - "kundenwert": { - "wert": 3.41, - "einheit": Mengeneinheit.MWH, - }, - "verbrauchsaufteilung": 1.5, - "zeitreihentyp": Zeitreihentyp.EGS, - "aggregationsverantwortung": Aggregationsverantwortung.VNB, - "prognosegrundlage": Prognosegrundlage.WERTE, - "detailsPrognosegrundlage": [Profiltyp.SLP_SEP], - "wahlrechtPrognosegrundlage": WahlrechtPrognosegrundlage.DURCH_LF, - "fallgruppenzuordnung": Fallgruppenzuordnung.GABI_RLMmT, - "prioritaet": 1, - "grundWahlrechtPrognosegrundlage": WahlrechtPrognosegrundlage.DURCH_LF_NICHT_GEGEBEN, - }, - id="full example", + bilanzierungsbeginn=datetime(2022, 1, 1, 0, 0, 0, tzinfo=timezone.utc), + bilanzierungsende=datetime(2023, 1, 1, 0, 0, 0, tzinfo=timezone.utc), + bilanzkreis="foo", + jahresverbrauchsprognose=Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH), + temperatur_arbeit=Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH), + # todo: check einheiten + kundenwert=Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH), + verbrauchsaufteilung=1.5, + zeitreihentyp=Zeitreihentyp.EGS, + aggregationsverantwortung=Aggregationsverantwortung.VNB, + prognosegrundlage=Prognosegrundlage.WERTE, + details_prognosegrundlage=[Profiltyp.SLP_SEP], + wahlrecht_prognosegrundlage=WahlrechtPrognosegrundlage.DURCH_LF, + fallgruppenzuordnung=Fallgruppenzuordnung.GABI_RLMmT, + prioritaet=1, + grund_wahlrecht_prognosegrundlage=WahlrechtPrognosegrundlage.DURCH_LF_NICHT_GEGEBEN, + ) ), - pytest.param( - Bilanzierung(), - { - # todo: cf. alias_generator=camelize in geschaeftsobjekte.py - "versionstruktur": "2", - "boTyp": BoTyp.BILANZIERUNG, - "externeReferenzen": [], - "marktlokationsId": None, - "lastprofil": None, - "bilanzierungsbeginn": None, - "bilanzierungsende": None, - "bilanzkreis": None, - "jahresverbrauchsprognose": None, - "temperaturArbeit": None, - "kundenwert": None, - "verbrauchsaufteilung": None, - "zeitreihentyp": None, - "aggregationsverantwortung": None, - "prognosegrundlage": None, - "detailsPrognosegrundlage": None, - "wahlrechtPrognosegrundlage": None, - "fallgruppenzuordnung": None, - "prioritaet": None, - "grundWahlrechtPrognosegrundlage": None, - }, - id="min example", - ), - ], - ) - def test_serialization_roundtrip(self, bilanzierung: Bilanzierung, expected_json_dict: Dict[str, Any]) -> None: - """ - Test de-/serialisation of Bilanzierung with maximal/minimal attributes. - """ - assert_serialization_roundtrip(bilanzierung, expected_json_dict) - - @pytest.mark.parametrize( - "malo_id,is_valid", - [ - pytest.param("51238696781", True), - pytest.param("41373559241", True), - pytest.param("56789012345", True), - pytest.param("52935155442", True), - pytest.param("12345678910", False, id="wrong checksum"), - pytest.param("529351554422", False, id="too long"), - pytest.param("5293515544", False, id="too short"), - pytest.param("5293v15a442", False, id="alphanumeric"), - pytest.param("asdasd", False), - pytest.param(" ", False), - pytest.param(" asdasdasd ", False), - pytest.param(None, True, id="malo_id not required"), - pytest.param("", False), ], ) - def test_id_validation(self, malo_id: str, is_valid: bool) -> None: - """ - Test different MaLos. - Field optional -> None values are allowed - """ - - if not is_valid: - with pytest.raises(ValidationError): - _ = Bilanzierung(marktlokations_id=malo_id) - else: - _ = Bilanzierung(marktlokations_id=malo_id) + def test_serialization_roundtrip(self, bilanzierung: Bilanzierung) -> None: + assert_serialization_roundtrip(bilanzierung) From 09fc56ff3198c06451faff0d34eed1ff70f08e45 Mon Sep 17 00:00:00 2001 From: Franziska Date: Fri, 24 Nov 2023 21:14:16 +0100 Subject: [PATCH 22/42] Also adapt Lastprofil Test --- tests/test_lastprofil.py | 87 +++++++++------------------------------- 1 file changed, 18 insertions(+), 69 deletions(-) diff --git a/tests/test_lastprofil.py b/tests/test_lastprofil.py index 8b555bed8..c460c0e60 100644 --- a/tests/test_lastprofil.py +++ b/tests/test_lastprofil.py @@ -1,7 +1,4 @@ -from typing import Any, Dict - import pytest -from pydantic import ValidationError from bo4e.com.lastprofil import Lastprofil from bo4e.com.tagesparameter import Tagesparameter @@ -9,79 +6,31 @@ from bo4e.enum.profilverfahren import Profilverfahren from tests.serialization_helper import assert_serialization_roundtrip -# maximal example -example_lastprofil = Lastprofil( - bezeichnung="foo", - profilschar="foo2", - verfahren=Profilverfahren.SYNTHETISCH, - einspeisung=True, - tagesparameter=Tagesparameter( - klimazone="7624q", - temperaturmessstelle="1234x", - dienstanbieter="ZT1", - herausgeber="BDEW", - ), - profilart=Profilart.ART_LASTPROFIL, - herausgeber="BDEW", -) - class TestLastprofil: @pytest.mark.parametrize( - "lastprofil, expected_json_dict", + "lastprofil", [ pytest.param( - example_lastprofil, - { - "bezeichnung": "foo", - "profilschar": "foo2", - "verfahren": Profilverfahren.SYNTHETISCH, - "einspeisung": True, - "tagesparameter": { - "klimazone": "7624q", - "temperaturmessstelle": "1234x", - "dienstanbieter": "ZT1", - "herausgeber": "BDEW", - }, - "profilart": Profilart.ART_LASTPROFIL, - "herausgeber": "BDEW", - }, - id="max param test", - ), - pytest.param( - Lastprofil(), - { - "bezeichnung": None, - "profilschar": None, - "verfahren": None, - "einspeisung": None, - "tagesparameter": None, - "profilart": None, - "herausgeber": None, - }, - id="min param test", + Lastprofil( + bezeichnung="foo", + profilschar="foo2", + verfahren=Profilverfahren.SYNTHETISCH, + einspeisung=True, + tagesparameter=Tagesparameter( + klimazone="7624q", + temperaturmessstelle="1234x", + dienstanbieter="ZT1", + herausgeber="BDEW", + ), + profilart=Profilart.ART_LASTPROFIL, + herausgeber="BDEW", + ) ), ], ) - def test_serialization_roundtrip(self, lastprofil: Lastprofil, expected_json_dict: Dict[str, Any]) -> None: + def test_serialization_roundtrip(self, lastprofil: Lastprofil) -> None: """ - Test de-/serialisation of Lastprofil with maximal/minimal attributes. + Test de-/serialisation """ - assert_serialization_roundtrip(lastprofil, expected_json_dict) - - @pytest.mark.parametrize( - "profil_art", - [ - pytest.param( - Profilart.ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL, - id="profilart tagesparm.abh.", - ), - ], - ) - def test_failing_validation_tagesparameter_given_for_tagesparam_lastprofil(self, profil_art: Profilart) -> None: - with pytest.raises(ValidationError) as excinfo: - _ = Lastprofil( - profilart=profil_art, - ) - - assert "Lastprofil depends on Tagesparameter. Tagesparameter not given." in str(excinfo.value) + assert_serialization_roundtrip(lastprofil) From e20961e529e8e105196571c339d85c10388ab1ca Mon Sep 17 00:00:00 2001 From: Franziska Date: Fri, 24 Nov 2023 21:17:18 +0100 Subject: [PATCH 23/42] And also Tagesparameter test --- tests/test_tagesparameter.py | 43 +++++++++--------------------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/tests/test_tagesparameter.py b/tests/test_tagesparameter.py index a69aaeabc..a52d3851b 100644 --- a/tests/test_tagesparameter.py +++ b/tests/test_tagesparameter.py @@ -1,48 +1,25 @@ -from typing import Any, Dict - import pytest from bo4e.com.tagesparameter import Tagesparameter from tests.serialization_helper import assert_serialization_roundtrip -# full example -example_tagesparameter = Tagesparameter( - klimazone="7624q", - temperaturmessstelle="1234x", - dienstanbieter="ZT1", - herausgeber="BDEW", -) - class TestTagesparameter: - # @pytest.mark.parametrize( - "tagesparameter, expected_json_dict", + "tagesparameter", [ pytest.param( - example_tagesparameter, - { - "klimazone": "7624q", - "temperaturmessstelle": "1234x", - "dienstanbieter": "ZT1", - "herausgeber": "BDEW", - }, - id="full example", - ), - pytest.param( - Tagesparameter(), - { - "klimazone": None, - "temperaturmessstelle": None, - "dienstanbieter": None, - "herausgeber": None, - }, - id="min example", + Tagesparameter( + klimazone="7624q", + temperaturmessstelle="1234x", + dienstanbieter="ZT1", + herausgeber="BDEW", + ) ), ], ) - def test_serialization_roundtrip(self, tagesparameter: Tagesparameter, expected_json_dict: Dict[str, Any]) -> None: + def test_serialization_roundtrip(self, tagesparameter: Tagesparameter) -> None: """ - Test de-/serialisation of Tagesparameter with maximal/minimal attributes. + Test de-/serialisation of Tagesparameter. """ - assert_serialization_roundtrip(tagesparameter, expected_json_dict) + assert_serialization_roundtrip(tagesparameter) From d77e02989fbfd0effcf6f471d6c9709f28fd1db5 Mon Sep 17 00:00:00 2001 From: DeltaDaniel Date: Mon, 15 Jan 2024 11:15:32 +0100 Subject: [PATCH 24/42] changed type of "verbrauchsaufteilung": float -> decimal --- src/bo4e/bo/bilanzierung.py | 3 ++- tests/test_bilanzierung.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index 6821a41b7..5fe1e5ac6 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -2,6 +2,7 @@ Contains class Bilanzierung """ from datetime import datetime +from decimal import Decimal from typing import Annotated, Optional from pydantic import Field @@ -34,7 +35,7 @@ class Bilanzierung(Geschaeftsobjekt): jahresverbrauchsprognose: Optional[Menge] = None #: Jahresverbrauchsprognose temperatur_arbeit: Optional[Menge] = None #: Temperatur Arbeit kundenwert: Optional[Menge] = None #: Kundenwert - verbrauchsaufteilung: Optional[float] = None + verbrauchsaufteilung: Optional[Decimal] = None """ Verbrauchsaufteilung in % zwischen SLP und TLP-Profil. diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index aca1becbe..12b4bb3c1 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -49,7 +49,7 @@ class TestBilanzierung: temperatur_arbeit=Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH), # todo: check einheiten kundenwert=Menge(wert=Decimal(3.41), einheit=Mengeneinheit.MWH), - verbrauchsaufteilung=1.5, + verbrauchsaufteilung=Decimal(1.5), zeitreihentyp=Zeitreihentyp.EGS, aggregationsverantwortung=Aggregationsverantwortung.VNB, prognosegrundlage=Prognosegrundlage.WERTE, From a727ad7229f880c9776fccd17e31b3992332c366 Mon Sep 17 00:00:00 2001 From: DeltaDaniel Date: Mon, 15 Jan 2024 11:19:25 +0100 Subject: [PATCH 25/42] added missing import to __init__.py --- src/bo4e/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bo4e/__init__.py b/src/bo4e/__init__.py index 7cfe3aaf0..5309802b7 100644 --- a/src/bo4e/__init__.py +++ b/src/bo4e/__init__.py @@ -385,5 +385,6 @@ from .enum.zaehlergroesse import Zaehlergroesse from .enum.zaehlertyp import Zaehlertyp from .enum.zaehlertypspezifikation import ZaehlertypSpezifikation +from .enum.zeitreihentyp import Zeitreihentyp from .version import __gh_version__, __version__ from .zusatzattribut import ZusatzAttribut From 0df752bf3dca9f3ba9b91ad720f825371376b6d2 Mon Sep 17 00:00:00 2001 From: Daniel <139119540+DeltaDaniel@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:56:13 +0200 Subject: [PATCH 26/42] Update src/bo4e/bo/bilanzierung.py Co-authored-by: Leon Haffmans <49658102+lord-haffi@users.noreply.github.com> --- src/bo4e/bo/bilanzierung.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index 5fe1e5ac6..d4f873c19 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -37,15 +37,14 @@ class Bilanzierung(Geschaeftsobjekt): kundenwert: Optional[Menge] = None #: Kundenwert verbrauchsaufteilung: Optional[Decimal] = None """ - Verbrauchsaufteilung in % zwischen SLP und TLP-Profil. - - 1. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] * [Verbrauchsaufteilung in % / 100%] - = [zu verlagernde Energiemenge] - 2. [Gemessene Energiemenge der OBIS "Schwachlast"] - [zu verlagernde Energiemenge] - = [Ermittelte Energiemenge für Schwachlast] - 3. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] + [zu verlagernde Energiemenge] - = [Ermittelte Energiemenge für nicht Schwachlast] + Verbrauchsaufteilung in % zwischen SLP und TLP-Profil. + 1. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] * [Verbrauchsaufteilung in % / 100%] + = [zu verlagernde Energiemenge] + 2. [Gemessene Energiemenge der OBIS "Schwachlast"] - [zu verlagernde Energiemenge] + = [Ermittelte Energiemenge für Schwachlast] + 3. [Gemessene Energiemenge der OBIS "nicht Schwachlast"] + [zu verlagernde Energiemenge] + = [Ermittelte Energiemenge für nicht Schwachlast] """ zeitreihentyp: Optional[Zeitreihentyp] = None #: Zeitreihentyp (SLS, TLS, etc.) aggregationsverantwortung: Optional[Aggregationsverantwortung] = None #: Aggregationsverantwortung From ebac708bfe16517378e54a1da63eb730d7af7a80 Mon Sep 17 00:00:00 2001 From: Daniel <139119540+DeltaDaniel@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:56:28 +0200 Subject: [PATCH 27/42] Update src/bo4e/bo/bilanzierung.py Co-authored-by: Leon Haffmans <49658102+lord-haffi@users.noreply.github.com> --- src/bo4e/bo/bilanzierung.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index d4f873c19..3fff8ff4b 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -51,10 +51,10 @@ class Bilanzierung(Geschaeftsobjekt): prognosegrundlage: Optional[Prognosegrundlage] = None #: Prognosegrundlage details_prognosegrundlage: Optional[list[Profiltyp]] = None """ - Prognosegrundlage. + Prognosegrundlage. - Besteht der Bedarf ein tagesparameteräbhängiges Lastprofil mit gemeinsamer Messung anzugeben, - so ist dies über die 2 -malige Wiederholung des CAV Segments mit der Angabe der Codes E02 und E14 möglich. + Besteht der Bedarf ein tagesparameteräbhängiges Lastprofil mit gemeinsamer Messung anzugeben, + so ist dies über die 2 -malige Wiederholung des CAV Segments mit der Angabe der Codes E02 und E14 möglich. """ wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None """ From 33e8d5a26c6c6bee0dd2494445515d4eba78968e Mon Sep 17 00:00:00 2001 From: Daniel <139119540+DeltaDaniel@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:56:45 +0200 Subject: [PATCH 28/42] Update src/bo4e/bo/bilanzierung.py Co-authored-by: Leon Haffmans <49658102+lord-haffi@users.noreply.github.com> --- src/bo4e/bo/bilanzierung.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index 3fff8ff4b..f14e40e1e 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -58,9 +58,9 @@ class Bilanzierung(Geschaeftsobjekt): """ wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None """ - Wahlrecht der Prognosegrundlage. + Wahlrecht der Prognosegrundlage. - true = Wahlrecht beim Lieferanten vorhanden + true = Wahlrecht beim Lieferanten vorhanden """ fallgruppenzuordnung: Optional[Fallgruppenzuordnung] = None #: Fallgruppenzuordnung (für gas RLM) prioritaet: Optional[int] = None #: Priorität des Bilanzkreises (für Gas) From af0c214427be7e8c1c1047e04ef0ac9c84667443 Mon Sep 17 00:00:00 2001 From: Daniel <139119540+DeltaDaniel@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:56:59 +0200 Subject: [PATCH 29/42] Update src/bo4e/bo/bilanzierung.py Co-authored-by: Leon Haffmans <49658102+lord-haffi@users.noreply.github.com> --- src/bo4e/bo/bilanzierung.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index f14e40e1e..228deebf2 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -66,7 +66,7 @@ class Bilanzierung(Geschaeftsobjekt): prioritaet: Optional[int] = None #: Priorität des Bilanzkreises (für Gas) grund_wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None """ - Grund Wahlrecht der Prognosegrundlage. + Grund Wahlrecht der Prognosegrundlage. - true=Wahlrecht beim Lieferanten vorhanden + true=Wahlrecht beim Lieferanten vorhanden """ From 6ba7dba24c044772558934aa98d26643050eab0c Mon Sep 17 00:00:00 2001 From: Daniel <139119540+DeltaDaniel@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:57:22 +0200 Subject: [PATCH 30/42] Update src/bo4e/com/lastprofil.py Co-authored-by: Leon Haffmans <49658102+lord-haffi@users.noreply.github.com> --- src/bo4e/com/lastprofil.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/bo4e/com/lastprofil.py b/src/bo4e/com/lastprofil.py index 925bd3835..e66f337e5 100644 --- a/src/bo4e/com/lastprofil.py +++ b/src/bo4e/com/lastprofil.py @@ -19,12 +19,7 @@ class Lastprofil(COM): str ] = None #: Bezeichnung der Profilschar, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) verfahren: Optional[Profilverfahren] = None #: Verfahren des Profils (analytisch oder synthetisch) - einspeisung: Optional[bool] = None - """ - Einspeiseprofil: - - True/False - """ + einspeisung: Optional[bool] = None #: Einspeiseprofil: True/False tagesparameter: Optional[Tagesparameter] = None #: Klimazone / Temperaturmessstelle profilart: Optional[Profilart] = None #: Profilart des Lastprofils, e.g. ART_STANDARDLASTPROFIL herausgeber: Optional[str] = None #: Herausgeber des Lastprofil-Codes, e.g. BDEW From b9a380c57d0c3346a666067706a09d42df0f698f Mon Sep 17 00:00:00 2001 From: Daniel <139119540+DeltaDaniel@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:57:36 +0200 Subject: [PATCH 31/42] Update src/bo4e/com/tagesparameter.py Co-authored-by: Leon Haffmans <49658102+lord-haffi@users.noreply.github.com> --- src/bo4e/com/tagesparameter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bo4e/com/tagesparameter.py b/src/bo4e/com/tagesparameter.py index 6c3381002..3a3b59ae0 100644 --- a/src/bo4e/com/tagesparameter.py +++ b/src/bo4e/com/tagesparameter.py @@ -1,5 +1,5 @@ """ -contains tagesparameter class +Contains tagesparameter class """ From a41916b3b3454ae513c70a1017f481711547856f Mon Sep 17 00:00:00 2001 From: DeltaDaniel Date: Tue, 30 Apr 2024 15:09:10 +0200 Subject: [PATCH 32/42] changed docstrings --- src/bo4e/bo/bilanzierung.py | 10 +++++++++- src/bo4e/com/lastprofil.py | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index 228deebf2..e27c29f5c 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -22,7 +22,15 @@ class Bilanzierung(Geschaeftsobjekt): """ - Bilanzierungs BO + Das BO Bilanzierung erfasst alle relevanten Informationen zur Bilanzierung. + + .. raw:: html + + + + .. HINT:: + `Lastprofil JSON Schema `_ + """ typ: Annotated[Optional[Typ], Field(alias="_typ")] = Typ.BILANZIERUNG diff --git a/src/bo4e/com/lastprofil.py b/src/bo4e/com/lastprofil.py index e66f337e5..3ee034366 100644 --- a/src/bo4e/com/lastprofil.py +++ b/src/bo4e/com/lastprofil.py @@ -11,7 +11,15 @@ class Lastprofil(COM): """ - Lastprofil + Informationen zum Lastprofil. + + .. raw:: html + + + + .. HINT:: + `Lastprofil JSON Schema `_ + """ bezeichnung: Optional[str] = None #: Bezeichnung des Profils, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) From 0168a4e2364f733241c09115918bc8d21a2984aa Mon Sep 17 00:00:00 2001 From: Fstei Date: Wed, 11 Sep 2024 14:42:12 +0200 Subject: [PATCH 33/42] Add Abwicklungsmodell ENums to Bilanzierung --- src/bo4e/__init__.py | 2 ++ src/bo4e/bo/bilanzierung.py | 3 +++ src/bo4e/enum/abwicklungsmodell.py | 11 +++++++++++ 3 files changed, 16 insertions(+) create mode 100644 src/bo4e/enum/abwicklungsmodell.py diff --git a/src/bo4e/__init__.py b/src/bo4e/__init__.py index 668dd7eca..bc06a6a0e 100644 --- a/src/bo4e/__init__.py +++ b/src/bo4e/__init__.py @@ -9,6 +9,7 @@ """ __all__ = [ + "Abwicklungsmodell", "Angebot", "Ausschreibung", "Bilanzierung", @@ -314,6 +315,7 @@ # Import Enums from .enum.abgabeart import AbgabeArt +from .enum.abwicklungsmodell import Abwicklungsmodell from .enum.aggregationsverantwortung import Aggregationsverantwortung from .enum.angebotsstatus import Angebotsstatus from .enum.anrede import Anrede diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index e27c29f5c..3f3025333 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -1,6 +1,7 @@ """ Contains class Bilanzierung """ + from datetime import datetime from decimal import Decimal from typing import Annotated, Optional @@ -17,6 +18,7 @@ from bo4e.enum.wahlrechtprognosegrundlage import WahlrechtPrognosegrundlage from bo4e.enum.zeitreihentyp import Zeitreihentyp +from ..enum.abwicklungsmodell import Abwicklungsmodell from ..enum.typ import Typ @@ -78,3 +80,4 @@ class Bilanzierung(Geschaeftsobjekt): true=Wahlrecht beim Lieferanten vorhanden """ + abwicklungsmodell: Optional[Abwicklungsmodell] = None #: Abwicklungsmodell diff --git a/src/bo4e/enum/abwicklungsmodell.py b/src/bo4e/enum/abwicklungsmodell.py new file mode 100644 index 000000000..0e31649c8 --- /dev/null +++ b/src/bo4e/enum/abwicklungsmodell.py @@ -0,0 +1,11 @@ +# pylint: disable=missing-module-docstring +from bo4e.enum.strenum import StrEnum + + +class Abwicklungsmodell(StrEnum): + """ + Art der Abwicklungsmodell (E-Mob) + """ + + MODEL_1 = "MODEL_1" #: MODEL_1 + MODEL_2 = "MODEL_2" #: MODEL_2 From 8bd851b6243a49b785dce2d8ac50d57d12a4b9a2 Mon Sep 17 00:00:00 2001 From: Fstei Date: Wed, 11 Sep 2024 14:53:45 +0200 Subject: [PATCH 34/42] Update Profielart --- src/bo4e/enum/profilart.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bo4e/enum/profilart.py b/src/bo4e/enum/profilart.py index 10510e4dd..70337ea95 100644 --- a/src/bo4e/enum/profilart.py +++ b/src/bo4e/enum/profilart.py @@ -14,3 +14,6 @@ class Profilart(StrEnum): ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL = "ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL" """ART_TAGESPARAMETERABHAENGIGES_LASTPROFIL, Z03""" ART_LASTPROFIL = "ART_LASTPROFIL" #: ART_LASTPROFIL, Z12 + ART_STANDARDEINSPEISEPROFIL = "ART_STANDARDEINSPEISEPROFIL" #: ART_STANDARDEINSPEISEPROFIL, Z04 + ART_TAGESPARAMETERABHAENGIGES_EINSPEISEPROFIL = "ART_TAGESPARAMETERABHAENGIGES_EINSPEISEPROFIL" + #: ART_TAGESPARAMETERABHAENGIGES_EINSPEISEPROFIL, Z05 From bdb5e7bc2cc0274c683faab91da4f901eebcd2d4 Mon Sep 17 00:00:00 2001 From: Fstei Date: Wed, 11 Sep 2024 14:58:51 +0200 Subject: [PATCH 35/42] black . --- src/bo4e/com/lastprofil.py | 7 ++++--- src/bo4e/com/tagesparameter.py | 1 - src/bo4e/enum/profilverfahren.py | 1 + src/bo4e/enum/prognosegrundlage.py | 1 + src/bo4e/enum/wahlrechtprognosegrundlage.py | 1 + src/bo4e/enum/zeitreihentyp.py | 1 + 6 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/bo4e/com/lastprofil.py b/src/bo4e/com/lastprofil.py index 3ee034366..623acf0c3 100644 --- a/src/bo4e/com/lastprofil.py +++ b/src/bo4e/com/lastprofil.py @@ -1,6 +1,7 @@ """ Contains class Lastprofil """ + from typing import Optional from bo4e.com.com import COM @@ -23,9 +24,9 @@ class Lastprofil(COM): """ bezeichnung: Optional[str] = None #: Bezeichnung des Profils, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) - profilschar: Optional[ - str - ] = None #: Bezeichnung der Profilschar, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) + profilschar: Optional[str] = ( + None #: Bezeichnung der Profilschar, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) + ) verfahren: Optional[Profilverfahren] = None #: Verfahren des Profils (analytisch oder synthetisch) einspeisung: Optional[bool] = None #: Einspeiseprofil: True/False tagesparameter: Optional[Tagesparameter] = None #: Klimazone / Temperaturmessstelle diff --git a/src/bo4e/com/tagesparameter.py b/src/bo4e/com/tagesparameter.py index 3a3b59ae0..f76793d30 100644 --- a/src/bo4e/com/tagesparameter.py +++ b/src/bo4e/com/tagesparameter.py @@ -2,7 +2,6 @@ Contains tagesparameter class """ - from typing import Optional from bo4e.com.com import COM diff --git a/src/bo4e/enum/profilverfahren.py b/src/bo4e/enum/profilverfahren.py index fa44c94fe..6c726911d 100644 --- a/src/bo4e/enum/profilverfahren.py +++ b/src/bo4e/enum/profilverfahren.py @@ -1,6 +1,7 @@ """ Contains Enums for Profilverfahren. """ + from bo4e.enum.strenum import StrEnum diff --git a/src/bo4e/enum/prognosegrundlage.py b/src/bo4e/enum/prognosegrundlage.py index db9353058..d244325dc 100644 --- a/src/bo4e/enum/prognosegrundlage.py +++ b/src/bo4e/enum/prognosegrundlage.py @@ -1,6 +1,7 @@ """ Contains Enums for Prognosegrundlage. """ + from bo4e.enum.strenum import StrEnum diff --git a/src/bo4e/enum/wahlrechtprognosegrundlage.py b/src/bo4e/enum/wahlrechtprognosegrundlage.py index a10d04de4..436a752df 100644 --- a/src/bo4e/enum/wahlrechtprognosegrundlage.py +++ b/src/bo4e/enum/wahlrechtprognosegrundlage.py @@ -1,6 +1,7 @@ """ Contains Enums for Wahlrechtsprognosgrundlage. """ + from bo4e.enum.strenum import StrEnum diff --git a/src/bo4e/enum/zeitreihentyp.py b/src/bo4e/enum/zeitreihentyp.py index 14451cd5b..fc7843a6e 100644 --- a/src/bo4e/enum/zeitreihentyp.py +++ b/src/bo4e/enum/zeitreihentyp.py @@ -1,6 +1,7 @@ """ Contains Enums for Zeitreihentyp. """ + from bo4e.enum.strenum import StrEnum From b7d336dcc812e9fedc3b70f8985298cdd236a3f8 Mon Sep 17 00:00:00 2001 From: Annika Schloegl Date: Thu, 20 Mar 2025 12:02:21 +0100 Subject: [PATCH 36/42] Spell out Enums in Fallgruppenzuordnung --- src/bo4e/enum/fallgruppenzuordnung.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/bo4e/enum/fallgruppenzuordnung.py b/src/bo4e/enum/fallgruppenzuordnung.py index d34e7ba58..42307c2d7 100644 --- a/src/bo4e/enum/fallgruppenzuordnung.py +++ b/src/bo4e/enum/fallgruppenzuordnung.py @@ -10,10 +10,9 @@ class Fallgruppenzuordnung(StrEnum): Fallgruppenzuordnung nach edi@energy """ - # todo: Uppercase-Problematik klären. -> pylint - GABI_RLMmT = "GABI_RLMmT" # pylint:disable=invalid-name + GABI_RLM_MIT_TAGESBAND = "GABI_RLM_MIT_TAGESBAND" """RLM mit Tagesband""" - GABI_RLMoT = "GABI_RLMoT" # pylint:disable=invalid-name + GABI_RLM_OHNE_TAGESBAND = "GABI_RLM_OHNE_TAGESBAND" """RLM ohne Tagesband""" - GABI_RLMNEV = "GABI_RLMNEV" + GABI_RLM_IM_NOMINIERUNGSERSATZVERFAHREN = "GABI_RLM_IM_NOMINIERUNGSERSATZVERFAHREN" """RLM im Nominierungsersatzverfahren""" From d448c8cfb30ced71d6f81a72c6199b233049ca57 Mon Sep 17 00:00:00 2001 From: Annika Schloegl Date: Thu, 20 Mar 2025 12:06:12 +0100 Subject: [PATCH 37/42] Adapt test data --- tests/test_bilanzierung.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index 12b4bb3c1..6c2b45835 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -55,7 +55,7 @@ class TestBilanzierung: prognosegrundlage=Prognosegrundlage.WERTE, details_prognosegrundlage=[Profiltyp.SLP_SEP], wahlrecht_prognosegrundlage=WahlrechtPrognosegrundlage.DURCH_LF, - fallgruppenzuordnung=Fallgruppenzuordnung.GABI_RLMmT, + fallgruppenzuordnung=Fallgruppenzuordnung.GABI_RLM_MIT_TAGESBAND, prioritaet=1, grund_wahlrecht_prognosegrundlage=WahlrechtPrognosegrundlage.DURCH_LF_NICHT_GEGEBEN, ) From 1aea56da00c631fe1acc3ffed7e6f1e8a2791d88 Mon Sep 17 00:00:00 2001 From: Annika <73470827+hf-aschloegl@users.noreply.github.com> Date: Thu, 20 Mar 2025 12:12:05 +0100 Subject: [PATCH 38/42] Adapt boolean name --- src/bo4e/com/lastprofil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bo4e/com/lastprofil.py b/src/bo4e/com/lastprofil.py index 623acf0c3..0fd80c1f0 100644 --- a/src/bo4e/com/lastprofil.py +++ b/src/bo4e/com/lastprofil.py @@ -28,7 +28,7 @@ class Lastprofil(COM): None #: Bezeichnung der Profilschar, durch DVGW bzw. den Netzbetreiber vergeben (z.B. H0) ) verfahren: Optional[Profilverfahren] = None #: Verfahren des Profils (analytisch oder synthetisch) - einspeisung: Optional[bool] = None #: Einspeiseprofil: True/False + ist_einspeisung: Optional[bool] = None #: Einspeiseprofil: True/False tagesparameter: Optional[Tagesparameter] = None #: Klimazone / Temperaturmessstelle profilart: Optional[Profilart] = None #: Profilart des Lastprofils, e.g. ART_STANDARDLASTPROFIL herausgeber: Optional[str] = None #: Herausgeber des Lastprofil-Codes, e.g. BDEW From 11ade49ab1ff7be622f871e109c851f1b5aaf83f Mon Sep 17 00:00:00 2001 From: Annika Schloegl Date: Thu, 20 Mar 2025 12:20:01 +0100 Subject: [PATCH 39/42] Adapt tests for new boolean name --- tests/test_bilanzierung.py | 2 +- tests/test_lastprofil.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_bilanzierung.py b/tests/test_bilanzierung.py index 6c2b45835..9a70acff1 100644 --- a/tests/test_bilanzierung.py +++ b/tests/test_bilanzierung.py @@ -31,7 +31,7 @@ class TestBilanzierung: bezeichnung="foo", profilschar="foo2", verfahren=Profilverfahren.SYNTHETISCH, - einspeisung=True, + ist_einspeisung=True, tagesparameter=Tagesparameter( klimazone="7624q", temperaturmessstelle="1234x", diff --git a/tests/test_lastprofil.py b/tests/test_lastprofil.py index c460c0e60..354e94d57 100644 --- a/tests/test_lastprofil.py +++ b/tests/test_lastprofil.py @@ -16,7 +16,7 @@ class TestLastprofil: bezeichnung="foo", profilschar="foo2", verfahren=Profilverfahren.SYNTHETISCH, - einspeisung=True, + ist_einspeisung=True, tagesparameter=Tagesparameter( klimazone="7624q", temperaturmessstelle="1234x", From 83a567e304fe0d3d62be7af00d080bf6feeaf733 Mon Sep 17 00:00:00 2001 From: Annika Schloegl Date: Thu, 20 Mar 2025 12:23:01 +0100 Subject: [PATCH 40/42] Remove wrong info in docstring --- src/bo4e/bo/bilanzierung.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/bo4e/bo/bilanzierung.py b/src/bo4e/bo/bilanzierung.py index 3f3025333..ad9586651 100644 --- a/src/bo4e/bo/bilanzierung.py +++ b/src/bo4e/bo/bilanzierung.py @@ -69,8 +69,6 @@ class Bilanzierung(Geschaeftsobjekt): wahlrecht_prognosegrundlage: Optional[WahlrechtPrognosegrundlage] = None """ Wahlrecht der Prognosegrundlage. - - true = Wahlrecht beim Lieferanten vorhanden """ fallgruppenzuordnung: Optional[Fallgruppenzuordnung] = None #: Fallgruppenzuordnung (für gas RLM) prioritaet: Optional[int] = None #: Priorität des Bilanzkreises (für Gas) From 519db12f0a834d2abf6c50ab8e8fa1abf336404f Mon Sep 17 00:00:00 2001 From: Annika Schloegl Date: Thu, 20 Mar 2025 12:24:14 +0100 Subject: [PATCH 41/42] Fix grammar --- src/bo4e/enum/abwicklungsmodell.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bo4e/enum/abwicklungsmodell.py b/src/bo4e/enum/abwicklungsmodell.py index 0e31649c8..8501253d2 100644 --- a/src/bo4e/enum/abwicklungsmodell.py +++ b/src/bo4e/enum/abwicklungsmodell.py @@ -4,7 +4,7 @@ class Abwicklungsmodell(StrEnum): """ - Art der Abwicklungsmodell (E-Mob) + Art des Abwicklungsmodell (E-Mob) """ MODEL_1 = "MODEL_1" #: MODEL_1 From c301307a96507768bbe9f1da617dcaee661788f0 Mon Sep 17 00:00:00 2001 From: Annika Schloegl Date: Thu, 20 Mar 2025 12:26:29 +0100 Subject: [PATCH 42/42] Adapt ENUM Abwicklungsmodell --- src/bo4e/enum/abwicklungsmodell.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bo4e/enum/abwicklungsmodell.py b/src/bo4e/enum/abwicklungsmodell.py index 8501253d2..467a0b144 100644 --- a/src/bo4e/enum/abwicklungsmodell.py +++ b/src/bo4e/enum/abwicklungsmodell.py @@ -7,5 +7,5 @@ class Abwicklungsmodell(StrEnum): Art des Abwicklungsmodell (E-Mob) """ - MODEL_1 = "MODEL_1" #: MODEL_1 - MODEL_2 = "MODEL_2" #: MODEL_2 + MODELL_1 = "MODELL_1" #: Modell 1 "Bilanzierung an der Marktlokation" + MODELL_2 = "MODELL_2" #: Modell 2 "Bilanzierung im Bilanzierungsgebiet (BG) des LPB