Managing Time-Series Data#
Infrasys
systems are designed to assist with the management of systems and their associated datasets. The infrasys package utilizes Chronofy
, which supports the ingestion of the most commonly used time series data structures in power systems. Infrasys supports both continuous and discontinuous time series datasets.
SingleTimeSeries: Used for representing continuous time series datasets. Defined by start time and time step resolution. Data length determines end time.
NonSequentialTimeSeries: Used for representing discontinuous time-series data. Each data point is time-stamped in this representation.
In the example below, we attach a time series profile to a load in a distribution system. We create an example load model and add it to a system.
from gdm.distribution.components import DistributionLoad
from gdm.distribution import DistributionSystem
system =DistributionSystem(auto_add_composed_components=True)
load1 = DistributionLoad.example()
system.add_component(load1)
/opt/hostedtoolcache/Python/3.12.10/x64/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py:502: UserWarning: Ellipsis is not a Python type (it may be an instance of an object), Pydantic will allow any object with no validation since we cannot even enforce that the input is an instance of the given type. To get rid of this error wrap the type with `pydantic.SkipValidation`.
warn(
Next, we create a time series object and attach it to the load component. The time series interface also supports unit conversion. A profile is mapped to the parameter of the component to which it is attached. In the example below, the profile is attached to the active_power
parameter of the DistributionLoad
component.
Note
Time-series profiles can only be added to components already in the system.
A profile can be mapped to multiple components.
Multiple profiles can be mapped to an infrasys/gdm component.
from datetime import datetime, timedelta
from gdm.quantities import ActivePower
from infrasys import SingleTimeSeries
load_profile_kw = SingleTimeSeries.from_array(
data=ActivePower([1, 2, 3, 4, 5], "kilowatt"),
variable_name="active_power",
initial_time=datetime(2020, 1, 1),
resolution=timedelta(minutes=30),
)
system.add_time_series(
load_profile_kw,
*[load1],
profile_type="PMult",
profile_name="load_profile_kw",
use_actual=True,
)
SingleTimeSeriesKey(variable_name='active_power', time_series_type=<class 'infrasys.time_series_models.SingleTimeSeries'>, user_attributes={'profile_type': 'PMult', 'profile_name': 'load_profile_kw', 'use_actual': True}, length=5, initial_time=datetime.datetime(2020, 1, 1, 0, 0), resolution=datetime.timedelta(seconds=1800))
Once added, system info should show number of timeseries profiles added to the system.
system.info()
System ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓ ┃ Property ┃ Value ┃ ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩ │ System name │ │ │ Data format version │ 2.0.1 │ │ Components attached │ 10 │ │ Time Series attached │ 1 │ │ Description │ │ └──────────────────────┴───────┘
Component Information ┏━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓ ┃ Type ┃ Count ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩ │ DistributionBus │ 1 │ │ DistributionFeeder │ 4 │ │ DistributionLoad │ 1 │ │ DistributionSubstation │ 2 │ │ LoadEquipment │ 1 │ │ PhaseLoadEquipment │ 1 │ └────────────────────────┴───────┘
Time Series Summary ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━ ┃ ┃ ┃ ┃ ┃ ┃ No. Components ┃ Component Type ┃ Time Series Type ┃ Initial time ┃ Resolution ┃ No. Components ┃ with Time Series ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━ │ DistributionLoad │ SingleTimeSeries │ 2020-01-01 00:00:00 │ 0:30:00 │ 1 │ 1 └──────────────────────┴──────────────────┴─────────────────────┴────────────┴────────────────┴────────────────────
List of timeseries profiles mapped to a given component can be listed using the list_time_series
method.
print(system.list_time_series(load1))
[SingleTimeSeries(variable_name='active_power', normalization=None, data=<Quantity([1 2 3 4 5], 'kilowatt')>, resolution=datetime.timedelta(seconds=1800), initial_time=datetime.datetime(2020, 1, 1, 0, 0), length=5)]
When a system is serialized, time series data is exported to the <system name>_timeseries
folder.