{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Interactive simulation with Duty Cycle modification\n",
    "\n",
    "This python script example helps to understand how to change the value of a parameter during the simulation interactively (pseudo real time).\n",
    "\n",
    "In this case, the **duty cycle** of a Buck converter will be modified suddenly at any time and the impact of this change will be observed on the output voltage through an oscilloscope. \n",
    "\n",
    "The library called **ipywidgets** is used to create this interactive display in pseudo real-time."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "3e36365f8004429dabf58f41e1478a9f",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "interactive(children=(FloatSlider(value=0.5, description='duty_cycle', max=1.0), Play(value=0, description='co…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Load required module\n",
    "from aesim.simba import DesignExamples\n",
    "import os\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import ipywidgets as widgets\n",
    "\n",
    "# Result tables initilization\n",
    "table_t = []\n",
    "table_Vout = []\n",
    "\n",
    "# Load project\n",
    "Buck = DesignExamples.BuckConverter()\n",
    "R1 = Buck.Circuit.GetDeviceByName('R1')\n",
    "for scope in R1.Scopes:\n",
    "    scope.Enabled=True\n",
    "    \n",
    "# Get the job object and solve the system\n",
    "Buck.TransientAnalysis.NumberOfPointsToSimulate = 1000 # emulate the time by using points\n",
    "Buck.TransientAnalysis.StopAtSteadyState=False\n",
    "Buck.TransientAnalysis.CompressScopes=False\n",
    "job = Buck.TransientAnalysis.NewJob()\n",
    "\n",
    "def run_simulation(duty_cycle, count):\n",
    "    PWM = Buck.Circuit.GetDeviceByName('C1')\n",
    "    PWM.DutyCycle=duty_cycle        # set duty cycle\n",
    "    status = job.Run()              # simulate\n",
    "    if str(status) != \"OK\": \n",
    "        raise Exception(job.Summary())\n",
    "    t = job.TimePoints              # get results\n",
    "    Vout = job.GetSignalByName('R1 - Voltage').DataPoints\n",
    "\n",
    "    if len(table_t) < 25000:\n",
    "        # remove all data as t and Vout contain result from t = 0\n",
    "        del table_t[0:len(t)]\n",
    "        del table_Vout[0:len(t)]\n",
    "        table_t.extend(t)\n",
    "        table_Vout.extend(Vout)\n",
    "    else:\n",
    "        # Fill tables with the length of simulation (1000 points)\n",
    "        table_t.extend(t)\n",
    "        table_Vout.extend(Vout)\n",
    "        del table_t[0:len(t)]\n",
    "        del table_Vout[0:len(Vout)]\n",
    "\n",
    "    \n",
    "    # graph initialization\n",
    "    fig, ax = plt.subplots()\n",
    "    ax.set_title('Buck')\n",
    "    ax.set_ylabel('Vout (V)')\n",
    "    ax.set_xlabel('time (s)')\n",
    "    ax.set_ylim((0, 70))\n",
    "    ax.plot(table_t, table_Vout)\n",
    "\n",
    "    plt.show()\n",
    "\n",
    "if os.environ.get('SIMBA_SCRIPT_TEST') == 'True':\n",
    "    run_simulation(duty_cycle=0.5, count=0)\n",
    "else:\n",
    "    w = widgets.interact(run_simulation, count=widgets.Play(min=0, max=10), duty_cycle=(0.0, 1.0, 0.1))\n",
    "    w"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "myenv",
   "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.13.3"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
