{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Multi-period Dispatch Simulation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Multi-period dispatch economic dispatch (ED) and unit commitment (UC) is also available.\n",
    "\n",
    "In this case, we will show a 24-hour ED simulation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import ams\n",
    "\n",
    "import datetime"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Last run time: 2024-02-24 17:29:42\n",
      "ams:0.8.5.post62.dev0+gf6ed683\n"
     ]
    }
   ],
   "source": [
    "print(\"Last run time:\", datetime.datetime.now().strftime(\"%Y-%m-%d %H:%M:%S\"))\n",
    "\n",
    "print(f'ams:{ams.__version__}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "ams.config_logger(stream_level=20)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load Case"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Parsing input file \"/Users/jinningwang/Documents/work/ams/ams/cases/5bus/pjm5bus_demo.xlsx\"...\n",
      "Input file parsed in 0.1202 seconds.\n",
      "Zero line rates detacted in rate_a, rate_b, rate_c, adjusted to 999.\n",
      "If expect a line outage, please set 'u' to 0.\n",
      "System set up in 0.0022 seconds.\n"
     ]
    }
   ],
   "source": [
    "sp = ams.load(ams.get_case('5bus/pjm5bus_demo.xlsx'),\n",
    "              setup=True,\n",
    "              no_output=True,)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Reginonal Design"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The disaptch models in AMS has develoepd with regional structure, and it can be inspected in device ``Region``."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>idx</th>\n",
       "      <th>u</th>\n",
       "      <th>name</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>uid</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>ZONE_1</td>\n",
       "      <td>1.0</td>\n",
       "      <td>ZONE 1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>ZONE_2</td>\n",
       "      <td>1.0</td>\n",
       "      <td>ZONE 2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        idx    u    name\n",
       "uid                     \n",
       "0    ZONE_1  1.0  ZONE 1\n",
       "1    ZONE_2  1.0  ZONE 2"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.Region.as_df()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In device ``Bus``, the Param ``zone`` indicates the zone of the bus.\n",
    "Correspondingly, the region of generator and load are determined by the bus they connected."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>idx</th>\n",
       "      <th>u</th>\n",
       "      <th>name</th>\n",
       "      <th>Vn</th>\n",
       "      <th>vmax</th>\n",
       "      <th>vmin</th>\n",
       "      <th>v0</th>\n",
       "      <th>a0</th>\n",
       "      <th>xcoord</th>\n",
       "      <th>ycoord</th>\n",
       "      <th>area</th>\n",
       "      <th>zone</th>\n",
       "      <th>owner</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>uid</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Bus_1</td>\n",
       "      <td>1.0</td>\n",
       "      <td>A</td>\n",
       "      <td>230.0</td>\n",
       "      <td>1.1</td>\n",
       "      <td>0.9</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>ZONE_1</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Bus_2</td>\n",
       "      <td>1.0</td>\n",
       "      <td>B</td>\n",
       "      <td>230.0</td>\n",
       "      <td>1.1</td>\n",
       "      <td>0.9</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>ZONE_1</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Bus_3</td>\n",
       "      <td>1.0</td>\n",
       "      <td>C</td>\n",
       "      <td>230.0</td>\n",
       "      <td>1.1</td>\n",
       "      <td>0.9</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>ZONE_1</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Bus_4</td>\n",
       "      <td>1.0</td>\n",
       "      <td>D</td>\n",
       "      <td>230.0</td>\n",
       "      <td>1.1</td>\n",
       "      <td>0.9</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>ZONE_1</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Bus_5</td>\n",
       "      <td>1.0</td>\n",
       "      <td>E</td>\n",
       "      <td>230.0</td>\n",
       "      <td>1.1</td>\n",
       "      <td>0.9</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>ZONE_1</td>\n",
       "      <td>None</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       idx    u name     Vn  vmax  vmin   v0   a0  xcoord  ycoord  area  \\\n",
       "uid                                                                       \n",
       "0    Bus_1  1.0    A  230.0   1.1   0.9  1.0  0.0       0       0     1   \n",
       "1    Bus_2  1.0    B  230.0   1.1   0.9  1.0  0.0       0       0     1   \n",
       "2    Bus_3  1.0    C  230.0   1.1   0.9  1.0  0.0       0       0     2   \n",
       "3    Bus_4  1.0    D  230.0   1.1   0.9  1.0  0.0       0       0     2   \n",
       "4    Bus_5  1.0    E  230.0   1.1   0.9  1.0  0.0       0       0     3   \n",
       "\n",
       "       zone owner  \n",
       "uid                \n",
       "0    ZONE_1  None  \n",
       "1    ZONE_1  None  \n",
       "2    ZONE_1  None  \n",
       "3    ZONE_1  None  \n",
       "4    ZONE_1  None  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.Bus.as_df()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Multi-period Dispatch Base"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In AMS, multi-period dispatch involves devices in group ``Horizon``.\n",
    "This group is developed to provide time-series data for multi-period dispatch."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "OrderedDict([('TimeSlot', TimeSlot (0 devices) at 0x15b19ee20),\n",
       "             ('EDTSlot', EDTSlot (6 devices) at 0x15b1a58e0),\n",
       "             ('UCTSlot', UCTSlot (6 devices) at 0x15b1a5d00)])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.Horizon.models"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can get the idx of StaticGens."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['PV_1', 'PV_3', 'PV_5', 'Slack_4']"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.StaticGen.get_idx()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In ``EDTSlot``, Param ``sd`` refers the load factors of each region in each time slot, and Param ``ug`` represents the generator commitment status in each time slot.\n",
    "\n",
    "To be more specific, EDT1 has ``sd=0.0793,0.0``, which means the load factor of region 1 is 0.0793 in the first time slot, and 0.0 in the second time slot.\n",
    "\n",
    "Next, EDT1 has ``ug=1,1,1,1``, and it means the commitment status of generator PV_1, PV_3, PV_5, and Slack_4 are all online."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>idx</th>\n",
       "      <th>u</th>\n",
       "      <th>name</th>\n",
       "      <th>sd</th>\n",
       "      <th>ug</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>uid</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>EDT1</td>\n",
       "      <td>1.0</td>\n",
       "      <td>EDT1</td>\n",
       "      <td>0.793,0.0</td>\n",
       "      <td>1,1,1,1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>EDT2</td>\n",
       "      <td>1.0</td>\n",
       "      <td>EDT2</td>\n",
       "      <td>0.756,0.0</td>\n",
       "      <td>1,1,1,1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>EDT3</td>\n",
       "      <td>1.0</td>\n",
       "      <td>EDT3</td>\n",
       "      <td>0.723,0.0</td>\n",
       "      <td>1,1,1,1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>EDT4</td>\n",
       "      <td>1.0</td>\n",
       "      <td>EDT4</td>\n",
       "      <td>0.708,0.0</td>\n",
       "      <td>1,1,1,1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>EDT5</td>\n",
       "      <td>1.0</td>\n",
       "      <td>EDT5</td>\n",
       "      <td>0.7,0.0</td>\n",
       "      <td>1,1,1,1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>EDT6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>EDT6</td>\n",
       "      <td>0.706,0.0</td>\n",
       "      <td>1,1,1,1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      idx    u  name         sd       ug\n",
       "uid                                     \n",
       "0    EDT1  1.0  EDT1  0.793,0.0  1,1,1,1\n",
       "1    EDT2  1.0  EDT2  0.756,0.0  1,1,1,1\n",
       "2    EDT3  1.0  EDT3  0.723,0.0  1,1,1,1\n",
       "3    EDT4  1.0  EDT4  0.708,0.0  1,1,1,1\n",
       "4    EDT5  1.0  EDT5    0.7,0.0  1,1,1,1\n",
       "5    EDT6  1.0  EDT6  0.706,0.0  1,1,1,1"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.EDTSlot.as_df()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Solve and Result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Routine <ED> initialized in 0.0288 seconds.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.ED.init()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "ED solved as optimal in 0.0305 seconds, converged after 9 iterations using solver ECOS.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.ED.run(solver='ECOS')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "All decision variables are collected in the dict ``vars``."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "OrderedDict([('pg', Var: StaticGen.pg),\n",
       "             ('aBus', Var: Bus.aBus),\n",
       "             ('plf', Var: Line.plf),\n",
       "             ('pru', Var: StaticGen.pru),\n",
       "             ('prd', Var: StaticGen.prd),\n",
       "             ('prs', Var: StaticGen.prs)])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.ED.vars"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we can see, the generator output ``pg`` is a 2D array, and the first dimension is the generator index, and the second dimension is the time slot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[2.1 , 2.1 , 2.1 , 2.1 , 2.1 , 2.1 ],\n",
       "       [3.23, 2.86, 2.53, 2.38, 2.3 , 2.36],\n",
       "       [0.6 , 0.6 , 0.6 , 0.6 , 0.6 , 0.6 ],\n",
       "       [2.  , 2.  , 2.  , 2.  , 2.  , 2.  ]])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.ED.pg.v"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Partial results can be accessed with desired time slot.\n",
    "In the retrieved result, the first dimension is the generator index, and the second dimension is the time slot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2.1])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.ED.get(src='pg', attr='v', idx='PV_1', horizon=['EDT1'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or, get multiple variables in mutliple time slots."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[2.1 , 2.1 , 2.1 ],\n",
       "       [3.23, 2.86, 2.53]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sp.ED.get(src='pg', attr='v', idx=['PV_1', 'PV_3'], horizon=['EDT1', 'EDT2', 'EDT3'])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "ams",
   "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.18"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "d2b3bf80176349caa68dc4a3c77bd06eaade8abc678330f7d1c813c53380e5d2"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}