Source code for twin4build.systems.controller.sequence_controller.sequence_controller_system

# Standard library imports
import datetime
from typing import Optional

# Local application imports
import twin4build.core as core
import twin4build.systems as systems
import twin4build.utils.types as tps
from twin4build.translator.translator import Exact, MultiPath, Node, SignaturePattern
from twin4build.utils.get_object_properties import get_object_properties
from twin4build.utils.rgetattr import rgetattr
from twin4build.utils.rsetattr import rsetattr


[docs] def get_signature_pattern(): node0 = Node(cls=core.namespace.S4BLDG.SetpointController) node1 = Node(cls=core.namespace.S4BLDG.RulebasedController) node2 = Node(cls=core.namespace.SAREF.Property) node3 = Node(cls=core.namespace.SAREF.Property) node4 = Node(cls=core.namespace.SAREF.Property) node5 = Node(cls=core.namespace.S4BLDG.Schedule) node6 = Node(cls=core.namespace.S4BLDG.Schedule) node7 = Node(cls=core.namespace.SAREF.Sensor) node8 = Node(cls=core.namespace.SAREF.Sensor) node9 = Node(cls=core.namespace.SAREF.Property) sp = SignaturePattern( semantic_model_=core.ontologies, id="sequence_controller_signature_pattern" ) sp.add_triple( Exact(subject=node0, object=node2, predicate=core.namespace.SAREF.observes) ) sp.add_triple( Exact(subject=node1, object=node4, predicate=core.namespace.SAREF.observes) ) sp.add_triple( Exact(subject=node0, object=node3, predicate=core.namespace.SAREF.controls) ) sp.add_triple( Exact(subject=node1, object=node3, predicate=core.namespace.SAREF.controls) ) sp.add_triple( Exact(subject=node0, object=node5, predicate=core.namespace.SAREF.hasProfile) ) sp.add_triple( Exact(subject=node1, object=node6, predicate=core.namespace.SAREF.hasProfile) ) sp.add_triple( Exact(subject=node7, object=node2, predicate=core.namespace.SAREF.observes) ) sp.add_triple( Exact(subject=node8, object=node4, predicate=core.namespace.SAREF.observes) ) sp.add_triple( Exact(subject=node0, object=node9, predicate=core.namespace.SAREF.controls) ) sp.add_triple( Exact(subject=node1, object=node9, predicate=core.namespace.SAREF.controls) ) sp.add_input("actualValueSetpointController", node7, "measuredValue") sp.add_input("actualValueRulebasedController", node8, "measuredValue") sp.add_input("setpointValueSetpointController", node5, "scheduleValue") sp.add_input("setpointValueRulebasedController", node6, "scheduleValue") sp.add_modeled_node(node0) sp.add_modeled_node(node1) return sp
[docs] class SequenceControllerSystem: sp = [get_signature_pattern()] def __init__(self, **kwargs): self.base_components = kwargs["base_components"] base_setpoint_controller = [ component for component in self.base_components if isinstance(component, core.SetpointController) ][0] base_rulebased_controller = [ component for component in self.base_components if isinstance(component, core.RulebasedController) ][0] self.setpoint_controller = systems.PIControllerFMUSystem( **get_object_properties(base_setpoint_controller) ) self.rulebased_controller = systems.OnOffControllerSystem( **get_object_properties(base_rulebased_controller) ) # id=f"setpoint_controller - {self.id}", # id=f"rulebased_controller - {self.id}", self.input = { "actualValueSetpointController": tps.Scalar(), "actualValueRulebasedController": tps.Scalar(), "setpointValueSetpointController": tps.Scalar(), "setpointValueRulebasedController": tps.Scalar(), } self.output = {"inputSignal": tps.Scalar()} self._config = {"parameters": []} for attr in self.setpoint_controller.config["parameters"]: new_attr = f"{attr}__{self.setpoint_controller.id}" rsetattr(self, new_attr, rgetattr(self.setpoint_controller, attr)) self._config["parameters"].append(new_attr) for attr in self.rulebased_controller.config["parameters"]: new_attr = f"{attr}__{self.rulebased_controller.id}" rsetattr(self, new_attr, rgetattr(self.rulebased_controller, attr)) self._config["parameters"].append(new_attr) @property def config(self): return self._config
[docs] def initialize( self, start_time: datetime.datetime, end_time: datetime.datetime, step_size: int, simulator: core.Simulator, ) -> None: """ This function initializes the FMU component by setting the start_time and fmu_filename attributes, and then sets the parameters for the FMU model. """ for attr in self.setpoint_controller.config["parameters"]: new_attr = f"{attr}__{self.setpoint_controller.id}" rsetattr(self.setpoint_controller, attr, rgetattr(self, new_attr)) for attr in self.rulebased_controller.config["parameters"]: new_attr = f"{attr}__{self.rulebased_controller.id}" rsetattr(self.rulebased_controller, attr, rgetattr(self, new_attr)) self.setpoint_controller.input["actualValue"] = self.input[ "actualValueSetpointController" ] self.setpoint_controller.input["setpointValue"] = self.input[ "setpointValueSetpointController" ] self.rulebased_controller.input["actualValue"] = self.input[ "actualValueRulebasedController" ] self.rulebased_controller.input["setpointValue"] = self.input[ "setpointValueRulebasedController" ] self.setpoint_controller.output = self.output.copy() self.setpoint_controller.initialize(start_time, end_time, step_size, simulator) self.rulebased_controller.output = self.output.copy() self.rulebased_controller.initialize(start_time, end_time, step_size, simulator)
[docs] def do_step( self, secondTime: float, dateTime: datetime.datetime, step_size: int, stepIndex: int, ) -> None: self.setpoint_controller.input["actualValue"].set( self.input["actualValueSetpointController"], stepIndex ) self.setpoint_controller.input["setpointValue"].set( self.input["setpointValueSetpointController"], stepIndex ) self.setpoint_controller.do_step( secondTime=secondTime, dateTime=dateTime, step_size=step_size, stepIndex=stepIndex, ) self.rulebased_controller.input["actualValue"].set( self.input["actualValueRulebasedController"], stepIndex ) self.rulebased_controller.input["setpointValue"].set( self.input["setpointValueRulebasedController"], stepIndex ) self.rulebased_controller.do_step( secondTime=secondTime, dateTime=dateTime, step_size=step_size, stepIndex=stepIndex, ) self.output["inputSignal"].set( max( next(iter(self.setpoint_controller.output.values())), next(iter(self.rulebased_controller.output.values())), ), stepIndex, )