{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to the pandapower control module" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This tutorial introduces the pandapower controle module with the example of tap changer control. For this, we first load the MV oberrhein network that contains two 110/20 kV transformers:" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namestd_typehv_buslv_bussn_mvavn_hv_kvvn_lv_kvvk_percentvkr_percentpfe_kw...tap_neutraltap_mintap_maxtap_step_percenttap_step_degreetap_postap_phase_shifterparalleldfin_service
114HV/MV Transformer 025 MVA 110/20 kV583925.0110.020.011.20.28229.0...0-991.5NaN-2False11.0True
142HV/MV Transformer 125 MVA 110/20 kV31831925.0110.020.011.20.28229.0...0-991.5NaN-3False11.0True
\n", "

2 rows × 23 columns

\n", "
" ], "text/plain": [ " name std_type hv_bus lv_bus sn_mva vn_hv_kv \\\n", "114 HV/MV Transformer 0 25 MVA 110/20 kV 58 39 25.0 110.0 \n", "142 HV/MV Transformer 1 25 MVA 110/20 kV 318 319 25.0 110.0 \n", "\n", " vn_lv_kv vk_percent vkr_percent pfe_kw ... tap_neutral tap_min \\\n", "114 20.0 11.2 0.282 29.0 ... 0 -9 \n", "142 20.0 11.2 0.282 29.0 ... 0 -9 \n", "\n", " tap_max tap_step_percent tap_step_degree tap_pos tap_phase_shifter \\\n", "114 9 1.5 NaN -2 False \n", "142 9 1.5 NaN -3 False \n", "\n", " parallel df in_service \n", "114 1 1.0 True \n", "142 1 1.0 True \n", "\n", "[2 rows x 23 columns]" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Importing necessary packages\n", "import pandapower as pp\n", "from pandapower.networks import mv_oberrhein\n", "\n", "net = mv_oberrhein()\n", "net.trafo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we run a power flow, we can see the voltage at the low voltage side of the transformers:" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "114 1.014598\n", "142 1.028804\n", "Name: vm_lv_pu, dtype: float64" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pp.runpp(net)\n", "net.res_trafo.vm_lv_pu" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Both transformers include a tap changer with a range of -9 to +9, which are set to positions -2 and -3 respectively:" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "114 -2\n", "142 -3\n", "Name: tap_pos, dtype: int32" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.trafo[\"tap_pos\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The tap position is constant within a power flow calculation. A controller can now be used to control the tap changer position depending on the bus voltage." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Discrete Tap Control" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The DiscreteTapControl from the pandapower control package receives a deadband of permissable voltage and uses the tap changer to keep the voltage within this voltage band. We define such a controller for the first transformer in the oberrhein network with a deadband of 0.99 to 1.01pu:" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [], "source": [ "import pandapower.control as control\n", "trafo_controller = control.DiscreteTapControl(net=net, tid=114, vm_lower_pu=0.99, vm_uppe_pur=1.01)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The initiated controller automatically registers in the net. It can be found in the controller table:" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
controllerin_serviceorderlevelrecycle
0DiscreteTapControl of trafo 114True0.00False
\n", "
" ], "text/plain": [ " controller in_service order level recycle\n", "0 DiscreteTapControl of trafo 114 True 0.0 0 False" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.controller" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We now run a controlled power flow by setting **run_control=True** within the runpp arguments and check the transformer voltage:" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "114 0.998267\n", "142 1.028804\n", "Name: vm_lv_pu, dtype: float64" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# running a control-loop\n", "pp.runpp(net, run_control=True)\n", "net.res_trafo.vm_lv_pu" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The voltage at transformer 114 is now within the given range. If we checke the transformer table, we can see that the tap position of the first transformer as been changed from -2 to -1:" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "114 -1\n", "142 -3\n", "Name: tap_pos, dtype: int32" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.trafo[\"tap_pos\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Continous Tap Control\n", "\n", "It is also possible to control transformer with a **ContiniousTapControl** strategy. Instead of a range, this type of controller is able to achieve an exact output voltage. For this it assumes tap positions as floating numbers. We define such a controller for the second transformer in the network:" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [], "source": [ "trafo_controller = control.ContinuousTapControl(net=net, tid=142, vm_set_pu=0.98, tol=1e-6)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we now run the result, the low voltage side of the second transformer is controlled to exactly 0.98 pu:" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "114 0.998267\n", "142 0.980000\n", "Name: vm_lv_pu, dtype: float64" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pp.runpp(net, run_control=True)\n", "net.res_trafo.vm_lv_pu" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The tap position is set to -0.07:" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "114 -1.000000\n", "142 -0.067373\n", "Name: tap_pos, dtype: float64" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "net.trafo[\"tap_pos\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "While this obviously would not possible in real transformers, it can be useful to assume continous taps in large scale studies to avoid big steps in the results." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }