Source code for energydatamodel.containers

"""Collection marker and container subclasses.

:class:`Collection` is an :class:`Element` whose primary purpose is grouping
other elements. It is **not** a :class:`Node` β€” collections aren't graph
vertices; they're organizational/logical groupings. Collection shares the
``members`` and ``tz`` field shape with Node, but the semantics differ β€”
``isinstance(x, Node)`` on a Portfolio should return False.

Concrete subclasses carry no additional fields; they distinguish a Portfolio
from a Site at the type level for serialization / introspection / UI.

Conventions:

* ``Portfolio`` β€” trading/asset aggregate. Typically no geometry.
* ``Site`` β€” a geographic site containing assets. Typically a ``Point`` geometry.
* ``MultiSite`` β€” group of sites.
* ``Region`` β€” a named geographic region with a ``Polygon`` / ``MultiPolygon``
  geometry. (Distinct from :class:`Area`: regions are not bound to a market /
  administrative scope.)
* ``EnergyCommunity`` β€” members share resources/balance.
* ``VirtualPowerPlant`` β€” traded flexibility aggregate.
"""

import datetime
from dataclasses import dataclass

from energydatamodel.element import Element, infra


[docs] @dataclass(repr=False, kw_only=True) class Collection(Element): """An Element whose primary purpose is grouping other Elements. Not a :class:`Node` β€” collections are organizational groupings, not graph vertices. Carries ``members`` and ``tz`` (same shape as Node, different semantics). """ members: list[Element] = infra(default_factory=list, children=True) tz: datetime.tzinfo | None = infra(default=None)
[docs] def children(self) -> list: return list(self.members)
[docs] def add_child(self, obj: Element) -> None: if not isinstance(obj, Element): raise TypeError(f"{type(self).__name__} only accepts Element children, got {type(obj).__name__}") self.members.append(obj)
[docs] @dataclass(repr=False, kw_only=True) class Portfolio(Collection): """A trading/asset portfolio aggregate."""
[docs] @dataclass(repr=False, kw_only=True) class Site(Collection): """A geographic site containing one or more assets."""
@dataclass(repr=False, kw_only=True) class MultiSite(Collection): """An aggregate of multiple sites.""" @dataclass(repr=False, kw_only=True) class Region(Collection): """A named geographic region β€” typically backed by a Polygon geometry. Distinct from :class:`Area`: a Region is not labeled by market or administrative scope; it's a freeform geographic grouping. """
[docs] @dataclass(repr=False, kw_only=True) class EnergyCommunity(Collection): """An energy community β€” members share resources/balance."""
@dataclass(repr=False, kw_only=True) class VirtualPowerPlant(Collection): """A virtual power plant β€” traded flexibility aggregate."""