Custom System¶
This tutorial describes how to create and use a custom system in a parent package.
Define the system. This example defines some custom attributes to illustrate serialization and de-serialization behaviors.
from typing import Any
from infrasys import System
class CustomSystem(System):
"""Custom System"""
def __init__(self, my_attribute=5, *args, **kwargs):
super().__init__(*args, **kwargs)
self.data_format_version = "1.1.0"
self.my_attribute = my_attribute
def serialize_system_attributes(self) -> dict[str, Any]:
return {"my_attribute": self.my_attribute}
def deserialize_system_attributes(self, data: dict[str, Any]) -> None:
self.my_attribute = data["my_attribute"]
def handle_data_format_upgrade(self, data: dict[str, Any], from_version, to_version)) -> None:
...
Notes:
The system’s custom attribute
my_attribute
will be serialized and de-serialized automatically.infrasys
will call handle_data_format_upgrade during de-serialization so that this package can handle format changes that might occur in the future.
Define some component classes.
from uuid import UUID
from infrasys.component import Component
from infrasys.location import Location
class Bus(Component):
"""Represents a bus."""
voltage: float
coordinates: Location | None = None
@classmethod
def example(cls) -> "Bus":
return Bus(
name="my-bus",
voltage=1.1,
coordinates=Location(x=0.0, y=0.0),
)
class Generator(Component):
"""Represents a generator."""
available: bool
bus: Bus
active_power: float
rating: float
@classmethod
def example(cls) -> "Generator":
return Generator(
name="simple-gen",
available=True,
bus=Bus.example(),
active_power=1.0,
rating=0.0,
)
Notes:
Each component defines the
example
method. This is highly recommended so that users can see what a component might look like in the REPL.The
Bus
class implements a custom check when it is added to the system. It raises an exception if itsLocation
object is not already attached to the system. The same could be done for generators and buses.
Build a system.
import random
from datetime import datetime, timedelta
from infrasys.location import Location
from infrasys.time_series_models import SingleTimeSeries
system = CustomSystem(name="my_system", my_attribute=10)
location = Location(x=0.0, y=0.0)
bus = Bus(name="bus1", voltage=1.1, coordinates=location)
gen = Generator(name="gen1", available=True, bus=bus, active_power=1.2, rating=1.1)
system.add_components(location, bus, gen)
time_series = SingleTimeSeries.from_array(
data=[random.random() for x in range(24)],
variable_name="active_power",
initial_time=datetime(year=2030, month=1, day=1),
resolution=timedelta(hours=1),
)
system.add_time_series(time_series, gen)
Serialize and de-serialize the system.
system.to_json("system.json")
system2 = CustomSystem.from_json("system.json")
assert system.get_component(Generator, "gen1").active_power == \
system2.get_component(Generator, "gen1").active_power