{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Complex Control Example" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.display import display, HTML\n", "display(HTML('\"Open'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[EPyT-Flow](https://github.com/WaterFutures/EPyT-Flow) is available on [PyPI](https://pypi.org/project/epyt-flow/) and can be installed via `pip install epyt-flow`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%pip install epyt-flow --quiet" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from epyt_flow.data.networks import load_net1\n", "from epyt_flow.simulation import ScenarioSimulator, EpanetConstants\n", "from epyt_flow.simulation.scada import ComplexControlModule, RuleAction, RuleCondition, \\\n", " EN_R_LEVEL, EN_R_LEQ, EN_R_GEQ, EN_R_ACTION_STATUS_CLOSED, EN_R_ACTION_STATUS_OPEN\n", "from epyt_flow.utils import to_seconds" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create two complex control modules (i.e. entries in the \"RULES\" section of an .inp file) for controlling pump \"9\" based on the water leven in tank \"2\":\n", "\n", "- IF TANK 2 LEVEL <= 110 THEN PUMP 9 SETTING IS OPEN\n", "- IF TANK 2 LEVEL >= 140 THEN PUMP 9 SETTING IS CLOSED" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first control rule:\n", "IF TANK 2 LEVEL <= 110 THEN PUMP 9 SETTING IS OPEN\n", "\n", "1. Create the condition (instance of [RuleCondition](https://epyt-flow.readthedocs.io/en/stable/epyt_flow.simulation.scada.html#epyt_flow.simulation.scada.complex_control.RuleCondition)) TANK 2 LEVEL <= 110\n", "2. Create the action (instance of [RuleAction](https://epyt-flow.readthedocs.io/en/stable/epyt_flow.simulation.scada.html#epyt_flow.simulation.scada.complex_control.RuleAction)): PUMP 9 SETTING IS OPEN\n", "3. Combine condition and action into the final control rule (instance of [ComplexControlModule](https://epyt-flow.readthedocs.io/en/stable/epyt_flow.simulation.scada.html#epyt_flow.simulation.scada.complex_control.ComplexControlModule))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# IF TANK 2 LEVEL <= 110 THEN PUMP 9 SETTING IS OPEN\n", "# Create the condition: TANK 2 LEVEL <= 110\n", "condition_1 = RuleCondition(object_type_id=EpanetConstants.EN_R_NODE,\n", " object_id=\"2\",\n", " attribute_id=EN_R_LEVEL,\n", " relation_type_id=EN_R_LEQ,\n", " value=110)\n", "\n", "# Create the action: PUMP 9 SETTING IS OPEN\n", "action_1 = RuleAction(link_type_id=EpanetConstants.EN_PUMP,\n", " link_id=\"9\",\n", " action_type_id=EN_R_ACTION_STATUS_OPEN,\n", " action_value=None)\n", "\n", "# Combine condition and action into the final control rule\n", "my_control_1 = ComplexControlModule(rule_id=\"PUMP-9_1\",\n", " condition_1=condition_1,\n", " additional_conditions=[],\n", " actions=[action_1],\n", " else_actions=[],\n", " priority=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The second control rule:\n", "IF TANK 2 LEVEL >= 140 THEN PUMP 9 SETTING IS CLOSED\n", "\n", "1. Create the condition (instance of [RuleCondition](https://epyt-flow.readthedocs.io/en/stable/epyt_flow.simulation.scada.html#epyt_flow.simulation.scada.complex_control.RuleCondition)) TANK 2 LEVEL >= 140\n", "2. Create the action (instance of [RuleAction](https://epyt-flow.readthedocs.io/en/stable/epyt_flow.simulation.scada.html#epyt_flow.simulation.scada.complex_control.RuleAction)): PUMP 9 SETTING IS CLOSED\n", "3. Combine condition and action into the final control rule (instance of [ComplexControlModule](https://epyt-flow.readthedocs.io/en/stable/epyt_flow.simulation.scada.html#epyt_flow.simulation.scada.complex_control.ComplexControlModule))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# IF TANK 2 LEVEL >= 140 THEN PUMP 9 SETTING IS CLOSED\n", "# Create condition: TANK 2 LEVEL >= 140\n", "condition_1 = RuleCondition(object_type_id=EpanetConstants.EN_R_NODE,\n", " object_id=\"2\",\n", " attribute_id=EN_R_LEVEL,\n", " relation_type_id=EN_R_GEQ,\n", " value=140)\n", "\n", "# Create action: TANK 2 LEVEL >= 140\n", "action_1 = RuleAction(link_type_id=EpanetConstants.EN_PUMP,\n", " link_id=\"9\",\n", " action_type_id=EN_R_ACTION_STATUS_CLOSED,\n", " action_value=None)\n", "\n", "# Combine condition and action into the final control rule\n", "my_control_2 = ComplexControlModule(rule_id=\"PUMP-9_2\",\n", " condition_1=condition_1,\n", " additional_conditions=[],\n", " actions=[action_1],\n", " else_actions=[],\n", " priority=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create new simulation based on Net1:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sim = ScenarioSimulator(scenario_config=load_net1(verbose=False))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Set simulation duration to two days:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sim.set_general_parameters(simulation_duration=to_seconds(days=2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Monitor states of tank \"2\" and pump \"9\":" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sim.set_tank_sensors(sensor_locations=[\"2\"])\n", "sim.set_pump_state_sensors(sensor_locations=[\"9\"])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that Net1.inp contains some simple controls. Remove all of them by calling [remove_all_simple_controls()](https://epyt-flow.readthedocs.io/en/stable/epyt_flow.simulation.html#epyt_flow.simulation.scenario_simulator.ScenarioSimulator.remove_all_simple_controls):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sim.remove_all_simple_controls()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add our complex control modules by calling [add_complex_control()](https://epyt-flow.readthedocs.io/en/stable/epyt_flow.simulation.html#epyt_flow.simulation.scenario_simulator.ScenarioSimulator.add_complex_control):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sim.add_complex_control(my_control_1)\n", "sim.add_complex_control(my_control_2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Run the simulation and show sensor readings over time:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "scada_data = sim.run_simulation()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "scada_data.plot_pumps_state()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "scada_data.plot_tanks_water_volume()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Do not forget to close the simulation!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sim.close()" ] } ], "metadata": { "kernelspec": { "display_name": "epytflow2", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.20" } }, "nbformat": 4, "nbformat_minor": 2 }