Source code for oemof.network.network.edge

# -*- coding: utf-8 -*-

"""This package contains the class Edge used to model
energy systems.

SPDX-FileCopyrightText: Stephan Günther <>
SPDX-FileCopyrightText: Uwe Krien <krien@uni-bremen.de>
SPDX-FileCopyrightText: Simon Hilpert <>
SPDX-FileCopyrightText: Cord Kaldemeyer <>
SPDX-FileCopyrightText: Patrik Schönfeldt <patrik.schoenfeldt@dlr.de>

SPDX-License-Identifier: MIT
"""

from collections import namedtuple
from collections.abc import Mapping

from .entity import Entity


[docs]class Edge(Entity): """ :class:`Bus`es/:class:`Component`s are always connected by an :class:`Edge`. :class:`Edge`s connect a single :class:`Node` with another. They are directed and have a (sequence of) value(s) attached to them, so they can be used to represent a flow from a source/an input to a target/an output. Parameters ---------- input, output: :class:`Bus` or :class:`Component`, optional flow, values: object, optional The (list of) object(s) representing the values flowing from this edge's input into its output. Note that these two names are aliases of each other, so `flow` and `values` are mutually exclusive. Note that all of these parameters are also set as attributes with the same name. """ Label = namedtuple("EdgeLabel", ["input", "output"]) def __init__( self, input_node=None, output_node=None, flow=None, values=None, *, custom_properties=None, ): if flow is not None and values is not None: raise ValueError( "\n\n`Edge`'s `flow` and `values` keyword arguments are " "aliases of each other,\nso they're mutually exclusive.\n" "You supplied:\n" f" `flow` : {flow}\n" f" `values`: {values}\n" "Choose one." ) super().__init__( label=Edge.Label(input_node, output_node), custom_properties=custom_properties, ) self.values = values if values is not None else flow if input_node is not None and output_node is not None: input_node.outputs[output_node] = self
[docs] @classmethod def from_object(cls, o): """Creates an `Edge` instance from a single object. This method inspects its argument and does something different depending on various cases: * If `o` is an instance of `Edge`, `o` is returned unchanged. * If `o` is a `Mapping`, the instance is created by calling `cls(**o)`, * In all other cases, `o` will be used as the `values` keyword argument to `Edge`'s constructor. """ if isinstance(o, Edge): return o elif isinstance(o, Mapping): return cls(**o) else: return Edge(values=o)
@property def flow(self): return self.values @flow.setter def flow(self, values): self.values = values @property def input(self): return self.label.input @input.setter def input(self, i): old_input = self.input self._label = Edge.Label(i, self.label.output) if old_input is None and i is not None and self.output is not None: i.outputs[self.output] = self @property def output(self): return self.label.output @output.setter def output(self, o): old_output = self.output self._label = Edge.Label(self.label.input, o) if old_output is None and o is not None and self.input is not None: o.inputs[self.input] = self