/**
******************************************************************************
* @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 = to_float(protect->Umin, 100)/**to_float(nominal->U, 10)*/;
  float lUmax = to_float(protect->Umax, 100)/**to_float(nominal->U, 10)*/;
  float lPhaseSequence = to_float(nominal->PhaseSequence, 100);
  
  /* Общее напряжение */
  if(measure->final.Uamp > lUmax)
  {
    errors.prvt.f.err.uamp_max = 1;
  }
  else if (measure->final.Uamp < lUmin)
  {
    errors.prvt.f.err.uamp_min = 1;
  }
  else
  {
    errors.prvt.f.err.uamp_max = 0;
    errors.prvt.f.err.uamp_min = 0;
  }
  
  /* Последовательность фаз */
  int realPhaseSequence = 0;
  if(realPhaseSequence != lPhaseSequence)
  {
    errors.prvt.f.err.interlance = 1;
  }
  else
  {
    errors.prvt.f.err.interlance = 0;
  }  
  
  return (errors.prvt.f.err.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 = to_float(protect->Iref, 100)/**to_float(nominal->I, 10)*/;
  float lImax = to_float(protect->Imax, 100)/**to_float(nominal->I, 10)*/;
  float lImin = to_float(protect->Imin, 100)/**to_float(nominal->I, 10)*/;

  /* Общий ток */
  if(measure->final.Iamp > lImax)
  {
    errors.prvt.f.err.iamp_max = 1;
  }
  else if (measure->final.Iamp < lImin)
  {
    errors.prvt.f.err.iamp_min = 1;
  }
  else
  {
    errors.prvt.f.err.iamp_max = 0;
    errors.prvt.f.err.iamp_min = 0;
  }
  
  /* Ток по фазам */
  if(measure->final.I[I_A] > lImax)
  {
    errors.prvt.f.err.ia_max = 1;
  }
  else if (measure->final.I[I_A] < lImin)
  {
    errors.prvt.f.err.ia_min = 1;
  }
  else
  {
    errors.prvt.f.err.ia_max = 0;
    errors.prvt.f.err.ia_min = 0;
  }
  
  if(measure->final.I[I_B] > lImax)
  {
    errors.prvt.f.err.ib_max = 1;
  }
  else if (measure->final.I[I_B] < lImin)
  {
    errors.prvt.f.err.ib_min = 1;
  }
  else
  {
    errors.prvt.f.err.ib_max = 0;
    errors.prvt.f.err.ib_min = 0;
  }
  
  if(measure->final.I[I_C] > lImax)
  {
    errors.prvt.f.err.ic_max = 1;
  }
  else if (measure->final.I[I_C] < lImin)
  {
    errors.prvt.f.err.ic_min = 1;
  }
  else
  {
    errors.prvt.f.err.ic_max = 0;
    errors.prvt.f.err.ic_min = 0;
  }
  
  return (errors.prvt.f.err.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 = to_float(PARAM_INTERNAL.nominal.F, 100);
  float lFmin = lFnom - lFnom*to_float(PARAM_INTERNAL.nominal.F_deviation_minus, 100);
  float lFmax = lFnom + lFnom*to_float(PARAM_INTERNAL.nominal.F_deviation_plus, 100);
  
  float lTwarn = to_float(PARAM_INTERNAL.setpoints.TemperatureWarn, 100);
  float lTerr = to_float(PARAM_INTERNAL.setpoints.TemperatureWarn, 100);


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