Skip to content

Commit

Permalink
GSYE-681: Added support for SCMStorage strategy in the CDS. Modified …
Browse files Browse the repository at this point in the history
…schema in order to support the SCMStorage strategy.
  • Loading branch information
spyrostz committed Feb 8, 2024
1 parent 7ef26b5 commit 4ec0f79
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
PROFILE_KEYS_BY_TYPE = {
"Load": "daily_load_profile",
"PV": "power_profile",
"SmartMeter": "smart_meter_profile"
"SmartMeter": "smart_meter_profile",
"ScmStorage": "prosumption_kWh_profile"
}


Expand Down
23 changes: 6 additions & 17 deletions gsy_framework/community_datasheet/row_converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def convert(cls, row: Dict) -> Dict:
row[PVSheetHeader.CAPACITY_KW], ConstSettings.PVSettings.DEFAULT_CAPACITY_KW),
"tilt": row[PVSheetHeader.TILT],
"azimuth": row[PVSheetHeader.AZIMUTH],
"forecast_stream_id": row.get(LoadSheetHeader.DATASTREAM_ID)
"forecast_stream_id": row.get(PVSheetHeader.DATASTREAM_ID)
}

@classmethod
Expand All @@ -218,6 +218,7 @@ def _validate_row(cls, row: Dict):

class StorageRowConverter:
"""Convert from the excel row to a grid representation of a Storage asset."""
OPTIONAL_FIELDS = (StorageSheetHeader.DATASTREAM_ID, )

@classmethod
def convert(cls, row: Dict) -> Dict:
Expand All @@ -226,29 +227,17 @@ def convert(cls, row: Dict) -> Dict:
"""
cls._validate_row(row)

min_allowed_soc = use_default_if_null(row[StorageSheetHeader.MINIMUM_ALLOWED_SOC],
ConstSettings.StorageSettings.MIN_ALLOWED_SOC)
# The community datasheet doesn't allow setting the initial SOC, so we intentionally set it
# to be equal to the min_allowed_soc specified by the user.
initial_soc = min_allowed_soc

return {
"name": row[StorageSheetHeader.BATTERY_NAME],
"type": "Storage",
"type": "ScmStorage",
"uuid": str(uuid.uuid4()),
"battery_capacity_kWh": use_default_if_null(
row[StorageSheetHeader.CAPACITY_KWH],
ConstSettings.StorageSettings.CAPACITY),
"min_allowed_soc": min_allowed_soc,
"initial_soc": initial_soc,
"max_abs_battery_power_kW": use_default_if_null(
row[StorageSheetHeader.MAXIMUM_POWER_KW],
ConstSettings.StorageSettings.MAX_ABS_POWER)
"forecast_stream_id": row.get(StorageSheetHeader.DATASTREAM_ID)
}

@classmethod
def _validate_row(cls, row: Dict):
missing_fields = [field for field, value in row.items() if value in NULL_VALUES]
missing_fields = [field for field, value in row.items()
if field not in cls.OPTIONAL_FIELDS and value in NULL_VALUES]

if missing_fields:
raise CommunityDatasheetException((
Expand Down
4 changes: 1 addition & 3 deletions gsy_framework/community_datasheet/sheet_headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ class StorageSheetHeader(str, Enum):

MEMBER_NAME = "Member_name"
BATTERY_NAME = "Battery_name"
CAPACITY_KWH = "Capacity [kWh]"
MINIMUM_ALLOWED_SOC = "Minimum allowed SoC [-]"
MAXIMUM_POWER_KW = "Maximum power [kW]"
DATASTREAM_ID = "Datastream_ID"

@classmethod
def values(cls):
Expand Down
3 changes: 2 additions & 1 deletion gsy_framework/community_datasheet/sheet_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,15 @@ class PVSheetParser(MembersSheetParser):

EXPECTED_HEADER = PVSheetHeader.values()
ROW_CONVERTER_CLASS = PVRowConverter
OPTIONAL_COLUMN_NAMES = [LoadSheetHeader.DATASTREAM_ID]
OPTIONAL_COLUMN_NAMES = [PVSheetHeader.DATASTREAM_ID]


class StorageSheetParser(MembersSheetParser):
"""Parser for the "Storage" sheet of the Community Datasheet."""

EXPECTED_HEADER = StorageSheetHeader.values()
ROW_CONVERTER_CLASS = StorageRowConverter
OPTIONAL_COLUMN_NAMES = [StorageSheetHeader.DATASTREAM_ID]


class ProfileSheetParser(MembersSheetParser):
Expand Down
44 changes: 40 additions & 4 deletions gsy_framework/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class ScenarioSchemas:
{"$ref": "#/definitions/infinite_power_plant"},
{"$ref": "#/definitions/finite_power_plant"},
{"$ref": "#/definitions/storage"},
{"$ref": "#/definitions/scm_storage"},
{"$ref": "#/definitions/wind_turbine"},
{"$ref": "#/definitions/heat_pump"},
]}, "default": []
Expand Down Expand Up @@ -90,6 +91,7 @@ class ScenarioSchemas:
{"type": "null"}]},
"capacity_kW": {"type": "number"},
"cloud_coverage": {"anyOf": [{"type": "number"}, {"type": "null"}]},
"forecast_stream_id": {"anyOf": [{"type": "number"}, {"type": "null"}]},
"power_profile": {
"anyOf": [
{"type": "object"},
Expand Down Expand Up @@ -169,15 +171,16 @@ class ScenarioSchemas:
"avg_power_W": {"anyOf": [{"type": "number"}, {"type": "null"}]},
"hrs_per_day": {"anyOf": [{"type": "number"}, {"type": "null"}]},
"hrs_of_day": {"anyOf": [{"type": "array"}, {"type": "null"}]},
"initial_buying_rate": {"type": "number"},
"initial_buying_rate": {"anyOf": [{"type": "number"}, {"type": "null"}]},
"final_buying_rate": {"anyOf": [{"type": "number"}, {"type": "null"}]},
"fit_to_limit": {"type": "boolean"},
"fit_to_limit": {"type": ["boolean", "null"]},
"update_interval": {"anyOf": [{"type": "number"}, {"type": "null"}]},
"grid_connected": {"type": "boolean"},
"grid_connected": {"type": ["boolean", "null"]},
"energy_rate_increase_per_update": {"anyOf": [{"type": "number"},
{"type": "null"}]},
"forecast_stream_id": {"anyOf": [{"type": "number"}, {"type": "null"}]},
"daily_load_profile_uuid": {"anyOf": [{"type": "string"}, {"type": "null"}]},
"use_market_maker_rate": {"type": "boolean"},
"use_market_maker_rate": {"type": ["boolean", "null"]},
"daily_load_profile": {
"anyOf": [
{"type": "object"},
Expand Down Expand Up @@ -221,6 +224,8 @@ class ScenarioSchemas:
"address": {"type": ["string", "null"]},
"allow_external_connection": {"type": ["null", "boolean"]},
"geo_tag_location": {},
"energy_rate": {"anyOf": [{"type": "number"}, {"type": "null"}]},
"energy_buy_rate": {"anyOf": [{"type": "number"}, {"type": "null"}]},
}
},
"finite_power_plant": {
Expand Down Expand Up @@ -265,6 +270,36 @@ class ScenarioSchemas:
"update_interval": {"anyOf": [{"type": "number"}, {"type": "null"}]},
}
},
"scm_storage": {
"type": "object",
"properties": {
"name": {"type": "string"},
"type": {"enum": ["ScmStorage"]},
"uuid": {"type": "string"},
"libraryUUID": {"anyOf": [{"type": "string"}, {"type": "null"}]},
"address": {"type": ["string", "null"]},
"allow_external_connection": {"type": ["null", "boolean"]},
"geo_tag_location": {},
"initial_buying_rate": {"type": "number"},
"final_buying_rate": {"anyOf": [{"type": "number"}, {"type": "null"}]},
"fit_to_limit": {"type": "boolean"},
"update_interval": {"anyOf": [{"type": "number"}, {"type": "null"}]},
"energy_rate_increase_per_update": {"anyOf": [{"type": "number"},
{"type": "null"}]},
"use_market_maker_rate": {"type": "boolean"},
"forecast_stream_id": {"anyOf": [{"type": "number"}, {"type": "null"}]},
"prosumption_kWh_profile_uuid": {
"anyOf": [{"type": "string"}, {"type": "null"}]},
"prosumption_kWh_profile": {
"anyOf": [
{"type": "object"},
{"type": "array"},
{"type": "null"},
{"type": "string"}
]
}
}
},
},
"anyOf": [
{"$ref": "#/definitions/area"},
Expand All @@ -274,6 +309,7 @@ class ScenarioSchemas:
{"$ref": "#/definitions/infinite_power_plant"},
{"$ref": "#/definitions/finite_power_plant"},
{"$ref": "#/definitions/storage"},
{"$ref": "#/definitions/scm_storage"},
{"$ref": "#/definitions/wind_turbine"},
{"$ref": "#/definitions/heat_pump"},
],
Expand Down
Binary file modified tests/fixtures/community_datasheet.xlsx
Binary file not shown.
Binary file modified tests/fixtures/community_datasheet_alt.xlsx
Binary file not shown.

0 comments on commit 4ec0f79

Please sign in to comment.