From 6b7f83123d1b8626240f89c6ed84df58473c901c Mon Sep 17 00:00:00 2001 From: Jan Pecinovsky Date: Tue, 16 Jul 2024 16:26:54 +0000 Subject: [PATCH] more annotations --- demo_energiedelen.ipynb | 158 +++++++++--------- openenergyid/__init__.py | 2 +- openenergyid/energysharing/__init__.py | 10 +- openenergyid/energysharing/data_formatting.py | 3 - openenergyid/energysharing/models.py | 40 ++++- 5 files changed, 120 insertions(+), 93 deletions(-) diff --git a/demo_energiedelen.ipynb b/demo_energiedelen.ipynb index 56fda2c..9c7453f 100644 --- a/demo_energiedelen.ipynb +++ b/demo_energiedelen.ipynb @@ -27,7 +27,7 @@ "outputs": [], "source": [ "from openenergyid import TimeDataFrame\n", - "from openenergyid.energysharing import EnergySharingInput, EnergySharingOutput, calculate, CalculationMethod" + "from openenergyid.energysharing import EnergySharingInput, EnergySharingOutput, calculate, CalculationMethod, KeyInput" ] }, { @@ -388,10 +388,10 @@ "input = EnergySharingInput.model_construct(\n", " gross_injection=TimeDataFrame.from_pandas(gross_injection),\n", " gross_offtake=TimeDataFrame.from_pandas(gross_offtake),\n", - " key=TimeDataFrame.from_pandas(key),\n", + " key=KeyInput.from_pandas(key)\n", ")\n", "\n", - "df = input.data_frame()" + "df = input.to_pandas()" ] }, { @@ -448,7 +448,7 @@ " \n", " \n", " \n", - " 2024-01-01 12:00:00+01:00\n", + " 2024-01-01 11:00:00+00:00\n", " 70\n", " 10\n", " 20\n", @@ -469,7 +469,7 @@ " 0.225\n", " \n", " \n", - " 2024-01-01 12:15:00+01:00\n", + " 2024-01-01 11:15:00+00:00\n", " 20\n", " 10\n", " 30\n", @@ -490,7 +490,7 @@ " 0.225\n", " \n", " \n", - " 2024-01-01 12:30:00+01:00\n", + " 2024-01-01 11:30:00+00:00\n", " 100\n", " 10\n", " 40\n", @@ -511,7 +511,7 @@ " 0.225\n", " \n", " \n", - " 2024-01-01 12:45:00+01:00\n", + " 2024-01-01 11:45:00+00:00\n", " 0\n", " 10\n", " 50\n", @@ -538,24 +538,24 @@ "text/plain": [ " Gross Injection Gross Offtake \\\n", " P1 P2 P3 P4 P5 P6 P1 P2 \n", - "2024-01-01 12:00:00+01:00 70 10 20 0 0 0 0 30 \n", - "2024-01-01 12:15:00+01:00 20 10 30 0 0 0 0 20 \n", - "2024-01-01 12:30:00+01:00 100 10 40 0 0 0 0 10 \n", - "2024-01-01 12:45:00+01:00 0 10 50 0 0 0 0 0 \n", + "2024-01-01 11:00:00+00:00 70 10 20 0 0 0 0 30 \n", + "2024-01-01 11:15:00+00:00 20 10 30 0 0 0 0 20 \n", + "2024-01-01 11:30:00+00:00 100 10 40 0 0 0 0 10 \n", + "2024-01-01 11:45:00+00:00 0 10 50 0 0 0 0 0 \n", "\n", " Key \\\n", " P3 P4 P5 P6 P1 P2 P3 P4 P5 \n", - "2024-01-01 12:00:00+01:00 22 30 18 20 0.0 0.1 0.225 0.225 0.225 \n", - "2024-01-01 12:15:00+01:00 20 25 17 22 0.0 0.1 0.225 0.225 0.225 \n", - "2024-01-01 12:30:00+01:00 30 35 19 24 0.0 0.1 0.225 0.225 0.225 \n", - "2024-01-01 12:45:00+01:00 40 10 25 26 0.0 0.1 0.225 0.225 0.225 \n", + "2024-01-01 11:00:00+00:00 22 30 18 20 0.0 0.1 0.225 0.225 0.225 \n", + "2024-01-01 11:15:00+00:00 20 25 17 22 0.0 0.1 0.225 0.225 0.225 \n", + "2024-01-01 11:30:00+00:00 30 35 19 24 0.0 0.1 0.225 0.225 0.225 \n", + "2024-01-01 11:45:00+00:00 40 10 25 26 0.0 0.1 0.225 0.225 0.225 \n", "\n", " \n", " P6 \n", - "2024-01-01 12:00:00+01:00 0.225 \n", - "2024-01-01 12:15:00+01:00 0.225 \n", - "2024-01-01 12:30:00+01:00 0.225 \n", - "2024-01-01 12:45:00+01:00 0.225 " + "2024-01-01 11:00:00+00:00 0.225 \n", + "2024-01-01 11:15:00+00:00 0.225 \n", + "2024-01-01 11:30:00+00:00 0.225 \n", + "2024-01-01 11:45:00+00:00 0.225 " ] }, "execution_count": 9, @@ -630,7 +630,7 @@ " \n", " \n", " \n", - " 2024-01-01 12:00:00+01:00\n", + " 2024-01-01 11:00:00+00:00\n", " 4.9\n", " 1.70\n", " 5.90\n", @@ -651,7 +651,7 @@ " 20.0\n", " \n", " \n", - " 2024-01-01 12:15:00+01:00\n", + " 2024-01-01 11:15:00+00:00\n", " 0.0\n", " 1.00\n", " 6.75\n", @@ -672,7 +672,7 @@ " 13.5\n", " \n", " \n", - " 2024-01-01 12:30:00+01:00\n", + " 2024-01-01 11:30:00+00:00\n", " 19.0\n", " 2.90\n", " 16.60\n", @@ -693,7 +693,7 @@ " 24.0\n", " \n", " \n", - " 2024-01-01 12:45:00+01:00\n", + " 2024-01-01 11:45:00+00:00\n", " 0.0\n", " 2.42\n", " 18.33\n", @@ -720,24 +720,24 @@ "text/plain": [ " Net Injection \\\n", " P1 P2 P3 P4 P5 P6 \n", - "2024-01-01 12:00:00+01:00 4.9 1.70 5.90 0.0 0.0 0.0 \n", - "2024-01-01 12:15:00+01:00 0.0 1.00 6.75 0.0 0.0 0.0 \n", - "2024-01-01 12:30:00+01:00 19.0 2.90 16.60 0.0 0.0 0.0 \n", - "2024-01-01 12:45:00+01:00 0.0 2.42 18.33 0.0 0.0 0.0 \n", + "2024-01-01 11:00:00+00:00 4.9 1.70 5.90 0.0 0.0 0.0 \n", + "2024-01-01 11:15:00+00:00 0.0 1.00 6.75 0.0 0.0 0.0 \n", + "2024-01-01 11:30:00+00:00 19.0 2.90 16.60 0.0 0.0 0.0 \n", + "2024-01-01 11:45:00+00:00 0.0 2.42 18.33 0.0 0.0 0.0 \n", "\n", " Net Offtake \\\n", " P1 P2 P3 P4 P5 P6 \n", - "2024-01-01 12:00:00+01:00 0.0 21.0 4.00 7.50 0.0 0.0 \n", - "2024-01-01 12:15:00+01:00 0.0 15.0 13.25 11.50 3.5 8.5 \n", - "2024-01-01 12:30:00+01:00 0.0 0.0 5.25 1.25 0.0 0.0 \n", - "2024-01-01 12:45:00+01:00 0.0 0.0 37.75 0.00 11.5 12.5 \n", + "2024-01-01 11:00:00+00:00 0.0 21.0 4.00 7.50 0.0 0.0 \n", + "2024-01-01 11:15:00+00:00 0.0 15.0 13.25 11.50 3.5 8.5 \n", + "2024-01-01 11:30:00+00:00 0.0 0.0 5.25 1.25 0.0 0.0 \n", + "2024-01-01 11:45:00+00:00 0.0 0.0 37.75 0.00 11.5 12.5 \n", "\n", " Shared Energy \n", " P1 P2 P3 P4 P5 P6 \n", - "2024-01-01 12:00:00+01:00 0.0 9.0 18.00 22.50 18.0 20.0 \n", - "2024-01-01 12:15:00+01:00 0.0 5.0 6.75 13.50 13.5 13.5 \n", - "2024-01-01 12:30:00+01:00 0.0 10.0 24.75 33.75 19.0 24.0 \n", - "2024-01-01 12:45:00+01:00 0.0 0.0 2.25 10.00 13.5 13.5 " + "2024-01-01 11:00:00+00:00 0.0 9.0 18.00 22.50 18.0 20.0 \n", + "2024-01-01 11:15:00+00:00 0.0 5.0 6.75 13.50 13.5 13.5 \n", + "2024-01-01 11:30:00+00:00 0.0 10.0 24.75 33.75 19.0 24.0 \n", + "2024-01-01 11:45:00+00:00 0.0 0.0 2.25 10.00 13.5 13.5 " ] }, "execution_count": 10, @@ -812,7 +812,7 @@ " \n", " \n", " \n", - " 2024-01-01 12:00:00+01:00\n", + " 2024-01-01 11:00:00+00:00\n", " 7.08\n", " 1.01\n", " 2.02\n", @@ -833,7 +833,7 @@ " 20.00\n", " \n", " \n", - " 2024-01-01 12:15:00+01:00\n", + " 2024-01-01 11:15:00+00:00\n", " 0.00\n", " 0.00\n", " -0.00\n", @@ -854,7 +854,7 @@ " 15.71\n", " \n", " \n", - " 2024-01-01 12:30:00+01:00\n", + " 2024-01-01 11:30:00+00:00\n", " 24.67\n", " 2.47\n", " 9.87\n", @@ -875,7 +875,7 @@ " 24.00\n", " \n", " \n", - " 2024-01-01 12:45:00+01:00\n", + " 2024-01-01 11:45:00+00:00\n", " 0.00\n", " 2.24\n", " 11.22\n", @@ -902,24 +902,24 @@ "text/plain": [ " Net Injection \\\n", " P1 P2 P3 P4 P5 P6 \n", - "2024-01-01 12:00:00+01:00 7.08 1.01 2.02 0.0 0.0 0.0 \n", - "2024-01-01 12:15:00+01:00 0.00 0.00 -0.00 0.0 0.0 0.0 \n", - "2024-01-01 12:30:00+01:00 24.67 2.47 9.87 0.0 0.0 0.0 \n", - "2024-01-01 12:45:00+01:00 0.00 2.24 11.22 0.0 0.0 0.0 \n", + "2024-01-01 11:00:00+00:00 7.08 1.01 2.02 0.0 0.0 0.0 \n", + "2024-01-01 11:15:00+00:00 0.00 0.00 -0.00 0.0 0.0 0.0 \n", + "2024-01-01 11:30:00+00:00 24.67 2.47 9.87 0.0 0.0 0.0 \n", + "2024-01-01 11:45:00+00:00 0.00 2.24 11.22 0.0 0.0 0.0 \n", "\n", " Net Offtake \\\n", " P1 P2 P3 P4 P5 P6 \n", - "2024-01-01 12:00:00+01:00 0.0 20.42 3.75 5.94 0.00 0.00 \n", - "2024-01-01 12:15:00+01:00 0.0 14.13 13.00 9.29 1.29 6.29 \n", - "2024-01-01 12:30:00+01:00 0.0 0.00 5.00 0.00 0.00 0.00 \n", - "2024-01-01 12:45:00+01:00 0.0 0.00 37.50 0.00 7.98 8.98 \n", + "2024-01-01 11:00:00+00:00 0.0 20.42 3.75 5.94 0.00 0.00 \n", + "2024-01-01 11:15:00+00:00 0.0 14.13 13.00 9.29 1.29 6.29 \n", + "2024-01-01 11:30:00+00:00 0.0 0.00 5.00 0.00 0.00 0.00 \n", + "2024-01-01 11:45:00+00:00 0.0 0.00 37.50 0.00 7.98 8.98 \n", "\n", " Shared Energy \n", " P1 P2 P3 P4 P5 P6 \n", - "2024-01-01 12:00:00+01:00 0.0 9.58 18.25 24.06 18.00 20.00 \n", - "2024-01-01 12:15:00+01:00 0.0 5.87 7.00 15.71 15.71 15.71 \n", - "2024-01-01 12:30:00+01:00 0.0 10.00 25.00 35.00 19.00 24.00 \n", - "2024-01-01 12:45:00+01:00 0.0 0.00 2.50 10.00 17.02 17.02 " + "2024-01-01 11:00:00+00:00 0.0 9.58 18.25 24.06 18.00 20.00 \n", + "2024-01-01 11:15:00+00:00 0.0 5.87 7.00 15.71 15.71 15.71 \n", + "2024-01-01 11:30:00+00:00 0.0 10.00 25.00 35.00 19.00 24.00 \n", + "2024-01-01 11:45:00+00:00 0.0 0.00 2.50 10.00 17.02 17.02 " ] }, "execution_count": 11, @@ -1000,7 +1000,7 @@ " \n", " \n", " \n", - " 2024-01-01 12:00:00+01:00\n", + " 2024-01-01 11:00:00+00:00\n", " 0.00\n", " 0.00\n", " 0.00\n", @@ -1021,7 +1021,7 @@ " 20.00\n", " \n", " \n", - " 2024-01-01 12:15:00+01:00\n", + " 2024-01-01 11:15:00+00:00\n", " 0.00\n", " 0.00\n", " 0.00\n", @@ -1042,7 +1042,7 @@ " 15.71\n", " \n", " \n", - " 2024-01-01 12:30:00+01:00\n", + " 2024-01-01 11:30:00+00:00\n", " 14.76\n", " 1.48\n", " 15.77\n", @@ -1063,7 +1063,7 @@ " 24.00\n", " \n", " \n", - " 2024-01-01 12:45:00+01:00\n", + " 2024-01-01 11:45:00+00:00\n", " 0.00\n", " 0.00\n", " 0.00\n", @@ -1090,24 +1090,24 @@ "text/plain": [ " Net Injection \\\n", " P1 P2 P3 P4 P5 P6 \n", - "2024-01-01 12:00:00+01:00 0.00 0.00 0.00 0.0 0.0 0.0 \n", - "2024-01-01 12:15:00+01:00 0.00 0.00 0.00 0.0 0.0 0.0 \n", - "2024-01-01 12:30:00+01:00 14.76 1.48 15.77 0.0 0.0 0.0 \n", - "2024-01-01 12:45:00+01:00 0.00 0.00 0.00 0.0 0.0 0.0 \n", + "2024-01-01 11:00:00+00:00 0.00 0.00 0.00 0.0 0.0 0.0 \n", + "2024-01-01 11:15:00+00:00 0.00 0.00 0.00 0.0 0.0 0.0 \n", + "2024-01-01 11:30:00+00:00 14.76 1.48 15.77 0.0 0.0 0.0 \n", + "2024-01-01 11:45:00+00:00 0.00 0.00 0.00 0.0 0.0 0.0 \n", "\n", " Net Offtake \\\n", " P1 P2 P3 P4 P5 P6 \n", - "2024-01-01 12:00:00+01:00 0.0 18.51 0.35 1.14 0.00 0.00 \n", - "2024-01-01 12:15:00+01:00 0.0 14.13 13.00 9.29 1.29 6.29 \n", - "2024-01-01 12:30:00+01:00 0.0 0.00 0.00 0.00 0.00 0.00 \n", - "2024-01-01 12:45:00+01:00 0.0 0.00 36.75 0.00 1.62 2.62 \n", + "2024-01-01 11:00:00+00:00 0.0 18.51 0.35 1.14 0.00 0.00 \n", + "2024-01-01 11:15:00+00:00 0.0 14.13 13.00 9.29 1.29 6.29 \n", + "2024-01-01 11:30:00+00:00 0.0 0.00 0.00 0.00 0.00 0.00 \n", + "2024-01-01 11:45:00+00:00 0.0 0.00 36.75 0.00 1.62 2.62 \n", "\n", " Shared Energy \n", " P1 P2 P3 P4 P5 P6 \n", - "2024-01-01 12:00:00+01:00 0.0 11.49 21.65 28.86 18.00 20.00 \n", - "2024-01-01 12:15:00+01:00 0.0 5.87 7.00 15.71 15.71 15.71 \n", - "2024-01-01 12:30:00+01:00 0.0 10.00 30.00 35.00 19.00 24.00 \n", - "2024-01-01 12:45:00+01:00 0.0 0.00 3.25 10.00 23.38 23.38 " + "2024-01-01 11:00:00+00:00 0.0 11.49 21.65 28.86 18.00 20.00 \n", + "2024-01-01 11:15:00+00:00 0.0 5.87 7.00 15.71 15.71 15.71 \n", + "2024-01-01 11:30:00+00:00 0.0 10.00 30.00 35.00 19.00 24.00 \n", + "2024-01-01 11:45:00+00:00 0.0 0.00 3.25 10.00 23.38 23.38 " ] }, "execution_count": 12, @@ -1156,10 +1156,10 @@ "{\n", " \"netInjection\": {\n", " \"index\": [\n", - " \"2024-01-01T12:00:00+01:00\",\n", - " \"2024-01-01T12:15:00+01:00\",\n", - " \"2024-01-01T12:30:00+01:00\",\n", - " \"2024-01-01T12:45:00+01:00\"\n", + " \"2024-01-01T11:00:00Z\",\n", + " \"2024-01-01T11:15:00Z\",\n", + " \"2024-01-01T11:30:00Z\",\n", + " \"2024-01-01T11:45:00Z\"\n", " ],\n", " \"columns\": [\n", " \"P1\",\n", @@ -1206,10 +1206,10 @@ " },\n", " \"netOfftake\": {\n", " \"index\": [\n", - " \"2024-01-01T12:00:00+01:00\",\n", - " \"2024-01-01T12:15:00+01:00\",\n", - " \"2024-01-01T12:30:00+01:00\",\n", - " \"2024-01-01T12:45:00+01:00\"\n", + " \"2024-01-01T11:00:00Z\",\n", + " \"2024-01-01T11:15:00Z\",\n", + " \"2024-01-01T11:30:00Z\",\n", + " \"2024-01-01T11:45:00Z\"\n", " ],\n", " \"columns\": [\n", " \"P1\",\n", @@ -1256,10 +1256,10 @@ " },\n", " \"sharedEnergy\": {\n", " \"index\": [\n", - " \"2024-01-01T12:00:00+01:00\",\n", - " \"2024-01-01T12:15:00+01:00\",\n", - " \"2024-01-01T12:30:00+01:00\",\n", - " \"2024-01-01T12:45:00+01:00\"\n", + " \"2024-01-01T11:00:00Z\",\n", + " \"2024-01-01T11:15:00Z\",\n", + " \"2024-01-01T11:30:00Z\",\n", + " \"2024-01-01T11:45:00Z\"\n", " ],\n", " \"columns\": [\n", " \"P1\",\n", diff --git a/openenergyid/__init__.py b/openenergyid/__init__.py index a6d8967..7be25ed 100644 --- a/openenergyid/__init__.py +++ b/openenergyid/__init__.py @@ -1,6 +1,6 @@ """Open Energy ID Python SDK.""" -__version__ = "0.1.12" +__version__ = "0.1.13" from .enums import Granularity from .models import TimeDataFrame, TimeSeries diff --git a/openenergyid/energysharing/__init__.py b/openenergyid/energysharing/__init__.py index a88e1cd..1362c79 100644 --- a/openenergyid/energysharing/__init__.py +++ b/openenergyid/energysharing/__init__.py @@ -1,6 +1,12 @@ """Energy Sharing package.""" from .main import calculate -from .models import CalculationMethod, EnergySharingInput, EnergySharingOutput +from .models import CalculationMethod, EnergySharingInput, EnergySharingOutput, KeyInput -__all__ = ["calculate", "CalculationMethod", "EnergySharingInput", "EnergySharingOutput"] +__all__ = [ + "calculate", + "CalculationMethod", + "EnergySharingInput", + "EnergySharingOutput", + "KeyInput", +] diff --git a/openenergyid/energysharing/data_formatting.py b/openenergyid/energysharing/data_formatting.py index 7cbd770..c294c8d 100644 --- a/openenergyid/energysharing/data_formatting.py +++ b/openenergyid/energysharing/data_formatting.py @@ -22,9 +22,6 @@ def create_multi_index_input_frame( df = pd.concat([gross_injection, gross_offtake, key], axis=1) - # Do a check that the sum of the keys per timestamp is 1 - assert df[KEY].dropna(how="all").sum(axis=1).round(2).eq(1).all() - return df diff --git a/openenergyid/energysharing/models.py b/openenergyid/energysharing/models.py index 084a2fa..d869d13 100644 --- a/openenergyid/energysharing/models.py +++ b/openenergyid/energysharing/models.py @@ -1,9 +1,9 @@ """Data models for energy sharing.""" from enum import Enum -from typing import Annotated +from typing import Annotated, Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, confloat import pandas as pd from openenergyid import TimeDataFrame @@ -19,22 +19,46 @@ class CalculationMethod(Enum): OPTIMAL = "Optimal" +class KeyInput(TimeDataFrame): + """Energy Sharing Keys.""" + + data: Annotated[ + list[list[confloat(ge=0.0, le=1.0)]], # type: ignore + Field( + description="Key data, column per participant. " + "Must be between 0 and 1. " + "Each row must sum to 1." + ), + ] + + def model_post_init(self, __context: Any) -> None: + """Post-initialization validation.""" + for row in self.data: + if round(sum(row), 6) != 1: + raise ValueError("Each row must sum to 1.") + return super().model_post_init(__context) + + class EnergySharingInput(BaseModel): """Input data for energy sharing.""" - gross_injection: Annotated[TimeDataFrame, Field(alias="grossInjection")] - gross_offtake: Annotated[TimeDataFrame, Field(alias="grossOfftake")] - key: Annotated[TimeDataFrame, Field(alias="key")] - timezone: str = Field(alias="timeZone", default="Europe/Brussels") + gross_injection: Annotated[ + TimeDataFrame, + Field(alias="grossInjection", description="Gross injection data, column per participant"), + ] + gross_offtake: Annotated[ + TimeDataFrame, + Field(alias="grossOfftake", description="Gross offtake data, column per participant"), + ] + key: KeyInput - def data_frame(self) -> pd.DataFrame: + def to_pandas(self) -> pd.DataFrame: """Return the data as a combined DataFrame""" df = create_multi_index_input_frame( gross_injection=self.gross_injection.to_pandas(), gross_offtake=self.gross_offtake.to_pandas(), key=self.key.to_pandas(), ) - df = df.tz_convert(self.timezone) return df