/**
******************************************************************************
* @file power_protect.c
* @brief Модуль реализующий защиты по Напряжению/Токам/Температуре
******************************************************************************
* @details
******************************************************************************/
#include "power_protect.h"


/** 
  * @brief    Проверяет защиты по напряжению.
  * @note     Заполняет флаги prvt ошибок (приватные). 
  * Потом в @ref UPP_ErrorsHandle исходя из них заполняются ошибки для ПУИ
  * @return   1 - напряжение есть, 0 - напряжения нет
  */
int Protect_Voltages(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *protect, UPP_ParamsNominal_t *nominal)
{
  /* Переводим уставки ПУИ в удобный вид */   
  float lUmin = u2f(protect->Umin, 100)/**u2f(nominal->U, 10)*/;
  float lUmax = u2f(protect->Umax, 100)/**u2f(nominal->U, 10)*/;
  float lPhaseSequence = u2f(nominal->PhaseSequence, 100);
  
  /* Общее напряжение */
  if(measure->final.Uamp > lUmax)
  {
    ERR_PRIVATE.uamp_max = 1;
  }
  else if (measure->final.Uamp < lUmin)
  {
    ERR_PRIVATE.uamp_min = 1;
  }
  else
  {
    ERR_PRIVATE.uamp_max = 0;
    ERR_PRIVATE.uamp_min = 0;
  }
  
  /* Последовательность фаз */
  int realPhaseSequence = 0;
  if(realPhaseSequence != lPhaseSequence)
  {
    ERR_PRIVATE.interlance = 1;
  }
  else
  {
    ERR_PRIVATE.interlance = 0;
  }  
  
  return (ERR_PRIVATE.uamp_min == 0);
}

/** 
  * @brief    Проверяет защиты по току.
  * @note     Заполняет флаги prvt ошибок (приватные). 
  * Потом в @ref UPP_ErrorsHandle исходя из них заполняются ошибки для ПУИ
  */
int Protect_Currents(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *protect, UPP_ParamsNominal_t *nominal)
{
  /* Переводим уставки ПУИ в удобный вид */   
  float lIref = u2f(protect->Iref, 100)/**u2f(nominal->I, 10)*/;
  float lImin = u2f(protect->Imin, 100)/**u2f(nominal->I, 10)*/;
  float lImax = u2f(protect->Imax, 100) * 50 / u2f(nominal->I, 10); // Imax процентов от 50 А, в о.е. от номинального

  /* Общий ток */
  if(measure->final.Iamp > lImax)
  {
    ERR_PRIVATE.iamp_max = 1;
  }
  else if (measure->final.Iamp < lImin)
  {
    ERR_PRIVATE.iamp_min = 1;
  }
  else
  {
    ERR_PRIVATE.iamp_max = 0;
    ERR_PRIVATE.iamp_min = 0;
  }
  
  /* Ток по фазам */
  if(measure->final.I[I_A] > lImax)
  {
    ERR_PRIVATE.ia_max = 1;
  }
  else if (measure->final.I[I_A] < lImin)
  {
    ERR_PRIVATE.ia_min = 1;
  }
  else
  {
    ERR_PRIVATE.ia_max = 0;
    ERR_PRIVATE.ia_min = 0;
  }
  
  if(measure->final.I[I_B] > lImax)
  {
    ERR_PRIVATE.ib_max = 1;
  }
  else if (measure->final.I[I_B] < lImin)
  {
    ERR_PRIVATE.ib_min = 1;
  }
  else
  {
    ERR_PRIVATE.ib_max = 0;
    ERR_PRIVATE.ib_min = 0;
  }
  
  if(measure->final.I[I_C] > lImax)
  {
    ERR_PRIVATE.ic_max = 1;
  }
  else if (measure->final.I[I_C] < lImin)
  {
    ERR_PRIVATE.ic_min = 1;
  }
  else
  {
    ERR_PRIVATE.ic_max = 0;
    ERR_PRIVATE.ic_min = 0;
  }
  
  return (ERR_PRIVATE.iamp_min == 0);
}



/** 
  * @brief    Проверяет всякие другие защиты (частота, температура).
  * @note     Заполняет флаги prvt ошибок (приватные). 
  * Потом в @ref UPP_ErrorsHandle исходя из них заполняются ошибки для ПУИ
  */
void Protect_Misc(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *protect, UPP_ParamsNominal_t *nominal)
{  
  /* Переводим внутренние уставки в удобный вид */    
  float lFnom = u2f(PARAM_INTERNAL.nominal.F, 100);
  float lFmin = lFnom - lFnom*u2f(PARAM_INTERNAL.nominal.F_deviation_minus, 10000);
  float lFmax = lFnom + lFnom*u2f(PARAM_INTERNAL.nominal.F_deviation_plus, 10000);
  
  float lTwarn = u2f(PARAM_INTERNAL.setpoints.TemperatureWarn, 100);
  float lTerr = u2f(PARAM_INTERNAL.setpoints.TemperatureWarn, 100);


  /*=============== ЗАЩИТЫ ПО ЧАСТОТЕ ==================*/
  if(measure->final.F[U_CA] > lFmax)
  {
    ERR_PRIVATE.fac_max = 1; 
  }
  else if (measure->final.F[U_CA] < lFmin)
  {
    ERR_PRIVATE.fac_min = 1; 
  }
  else
  {
    ERR_PRIVATE.fac_max = 0; 
    ERR_PRIVATE.fac_min = 0; 
  }
  
  if(measure->final.F[U_AB] > lFmax)
  {
    ERR_PRIVATE.fba_max = 1; 
  }
  else if (measure->final.F[U_AB] < lFmin)
  {
    ERR_PRIVATE.fba_min = 1; 
  }
  else
  {
    ERR_PRIVATE.fba_max = 0; 
    ERR_PRIVATE.fba_min = 0; 
  }
  
  if(measure->final.F[U_BC] > lFmax)
  {
    ERR_PRIVATE.fbc_max = 1; 
  }
  else if (measure->final.F[U_BC] < lFmin)
  {
    ERR_PRIVATE.fbc_min = 1; 
  }
  else
  {
    ERR_PRIVATE.fbc_max = 0; 
    ERR_PRIVATE.fbc_min = 0; 
  }
  
  
  
  /*=============== ЗАЩИТЫ ПО ТЕМПЕРАТУРЕ ==================*/
  if(measure->final.T[TEMP_1] > lTerr)
  {
    ERR_PRIVATE.temp_err = 1;
  }
  else if (measure->final.T[TEMP_1] > lTwarn)
  {
    ERR_PRIVATE.temp_warn = 1;
  }
  else
  {
    ERR_PRIVATE.temp_err = 0;
    ERR_PRIVATE.temp_warn = 0;
  }
}
