ems/ems_c/logic/logic_protected.c

293 lines
12 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_protected.c
* @brief xxxx
* @author Gary
* @date 2024/09/21
* @remark 初修订
*****************************************************************************/
#include "logic_comm.h"
/*****************************************************************************
* @brief 获取保护参数
* @return 0 成功 -1 失败
*****************************************************************************/
int logic_getProtectParam()
{
static protect_algorithm_t getProtectBuff = {0.0f, 0.0f, 0.0f, 0.0f, 0, 0.0f, 0.0f, 0.0f, 0, 0.0f, 0.0f};
static protect_params_t *tmpProtectBuff = &stlogic.para_delivery.task_params.protect;
if (0 != kit_get_protect_algorithm(&getProtectBuff))
{
// INLOG(Log_LOGIC_EN, ERROR_EN, "获取保护配置失败\n");
return 1;
}
// 防过载和功率限制
tmpProtectBuff->maxActivePower = getProtectBuff.transCapacity;
tmpProtectBuff->overFlowLowLimt = getProtectBuff.olWarnLimitVal;
tmpProtectBuff->overFlowCloseLimt = getProtectBuff.olShutdownVal;
tmpProtectBuff->maxPower = getProtectBuff.maxPower;
// 防需和防逆流
tmpProtectBuff->demandCtl = getProtectBuff.demandSwitch;
tmpProtectBuff->aimActiveDemand = getProtectBuff.targetDemand;
tmpProtectBuff->demandCtrlLowLimt = getProtectBuff.deWarnLimitVal;
tmpProtectBuff->demandCtrlCloseLimt = getProtectBuff.deShutdownVal;
tmpProtectBuff->backFlow = getProtectBuff.backflowSwitch;
tmpProtectBuff->backFlowLowLimt = getProtectBuff.bfWarnLimitVal;
tmpProtectBuff->backFlowCloseLimt = getProtectBuff.bfShutdownVal;
// soc 保护
tmpProtectBuff->socForbidCharge = getProtectBuff.socForbidChg;
tmpProtectBuff->socForbidDischarge = getProtectBuff.socForbidDischg;
return 0;
}
/*****************************************************************************
* @brief 过载保护判断及处理
* @param[inout] protect_params_t *charge_params 运行参数
* @return 参数指针返回
*****************************************************************************/
void logic_protect_overload(protect_params_t *charge_params)
{
float_t tmp_max_power = charge_params->maxActivePower - charge_params->overFlowCloseLimt; // 计算关机功率点
if (tmp_max_power >= charge_params->totalActivePower) // 关机判断
{
float_t load_active_power = charge_params->totalActivePower - charge_params->emsActivePower; // 算出负载功率
tmp_max_power = charge_params->maxActivePower - charge_params->overFlowLowLimt;
if (tmp_max_power >= charge_params->totalActivePower) // 限流判断
{
float_t tmp_power = tmp_max_power - load_active_power - charge_params->overFlowLowLimt / 10;
if (tmp_power > 0)
{
charge_params->power = -float_min(abs(charge_params->power), tmp_power);
}
else
{
charge_params->power = 0;
}
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "触发过载保护!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
KITPTF(LOG_MODBUS_EN, INFO_EN, "触发过载保护!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
}
}
else
{
float_t tmp_power = tmp_max_power - load_active_power - charge_params->overFlowLowLimt / 2;
if (tmp_power > 0)
{
charge_params->power = -float_min(abs(charge_params->power), tmp_power);
}
else
{
charge_params->power = 0;
}
}
}
else
{
charge_params->power = 0;
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "触发过载保护!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
KITPTF(LOG_MODBUS_EN, INFO_EN, "触发过载保护!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
}
}
}
/*****************************************************************************
* @brief 逆流防护判断及处理
* @param[in] protect_backflow_t backflowParams 运行参数
* @return 参数指针返回
*****************************************************************************/
void logic_protect_backflow(protect_params_t *charge_params)
{
float_t load_active_power = charge_params->totalActivePower - charge_params->emsActivePower; // 算出负载功率
if (charge_params->totalActivePower > charge_params->backFlowCloseLimt) // 关机判断
{
if (load_active_power > charge_params->backFlowLowLimt) // 限流判断
{
float_t tmp_power = load_active_power - charge_params->backFlowLowLimt * 1.10;
if (tmp_power > 0)
{
charge_params->power = float_min(charge_params->power, tmp_power);
}
else
{
charge_params->power = 0;
}
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "触发逆流保护!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
KITPTF(LOG_MODBUS_EN, INFO_EN, "触发逆流保护!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
}
}
else
{
float_t tmp_power = load_active_power - charge_params->backFlowLowLimt * 1.50;
if (tmp_power > 0)
{
charge_params->power = float_min(charge_params->power, tmp_power);
}
else
{
charge_params->power = 0;
}
}
}
else
{
charge_params->power = 0;
if ((uint8_t)getRtdbPointValue(rtdbType, kDev_Type_EMS, 0, kEms_LogicLog_Enable) == 1)
{
KITLOG(LOG_MODBUS_EN, INFO_EN, "触发逆流关机!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
KITPTF(LOG_MODBUS_EN, INFO_EN, "触发逆流关机!!! 并网点功率:%.2f kw 新的目标功率:%.2f kw", charge_params->totalActivePower, charge_params->power);
}
}
}
/*****************************************************************************
* @brief 最大充放电功率防护判断及处理
* @param[in] protect_backflow_t backflowParams 运行参数
* @return 参数指针返回
*****************************************************************************/
void logic_protect_maxPower(protect_params_t *charge_params)
{
if (charge_params->power < 0) // 充电
{
charge_params->power = -float_min(abs(charge_params->power), abs(charge_params->maxPower));
}
else if (charge_params->power > 0) // 放电
{
charge_params->power = float_min(charge_params->power, abs(charge_params->maxPower));
}
}
/*****************************************************************************
* @brief 策略数据计算及保护接口
* @return -1数据处理失败 0数据处理成功
*****************************************************************************/
int logicFun_protect()
{
protect_params_t *charge_params = &stlogic.para_delivery.task_params.protect;
if (charge_params->scramButton)
{
charge_params->power = 0;
return 0;
}
switch (stlogic.para_delivery.mode)
{
case E_TACTIC_MODE_DEBUG: // 调试模式
charge_params->power = stlogic.para_delivery.task_params.debug.activePower;
charge_params->rePower = stlogic.para_delivery.task_params.debug.reactivePower;
break;
case E_TACTIC_MODE_PEAKVALLY: // 削峰填谷模式
charge_params->power = stlogic.para_delivery.task_params.pkvly.power;
break;
case E_TACTIC_MODE_DEMANDRES: // 需求响应模式
/* 暂未实现 */
charge_params->power = stlogic.para_delivery.task_params.demand.power;
break;
case E_TACTIC_MODE_LOADTRACK: // 负载跟踪模式
/* 暂未实现 */
charge_params->power = stlogic.para_delivery.task_params.loadTrack.power;
break;
default:
/*未知模式*/
stlogic.para_delivery.task_params.distr.power = 0;
stlogic.para_delivery.task_params.protect.power = 0;
break;
}
// 统计总SOC
int bmsOlineNum = 0;
stlogic.para_delivery.task_params.distr.sumSoc = 0; // 参数清零
if (charge_params->power < 0) // 充电
{
stlogic.para_delivery.task_params.distr.stationBmsSoc = 0;
for (int loop = 0; loop < stlogic.para_delivery.task_params.distr.cabintCont; loop++)
{
if (!float_equal(stlogic.para_delivery.task_params.distr.pcsMaxChaPower[loop], 0) &&
stlogic.para_delivery.task_params.distr.pcsState[loop] != 0 && stlogic.para_delivery.task_params.distr.bmsState[loop] != 0)
{
stlogic.para_delivery.task_params.distr.sumSoc += (SOCMAX - stlogic.para_delivery.task_params.distr.bmsSoc[loop]);
bmsOlineNum++;
}
}
if (bmsOlineNum)
{
stlogic.para_delivery.task_params.distr.stationBmsSoc = (((SOCMAX * bmsOlineNum) - stlogic.para_delivery.task_params.distr.sumSoc) / (SOCMAX * bmsOlineNum)) * 100.0;
}
else
{
stlogic.para_delivery.task_params.distr.stationBmsSoc = 0.0;
}
}
else if (charge_params->power > 0) // 放电
{
stlogic.para_delivery.task_params.distr.stationBmsSoc = 0;
for (int loop = 0; loop < stlogic.para_delivery.task_params.distr.cabintCont; loop++)
{
if (!float_equal(stlogic.para_delivery.task_params.distr.pcsMaxDiscPower[loop], 0) &&
stlogic.para_delivery.task_params.distr.pcsState[loop] != 0 && stlogic.para_delivery.task_params.distr.bmsState[loop] != 0)
{
stlogic.para_delivery.task_params.distr.sumSoc += stlogic.para_delivery.task_params.distr.bmsSoc[loop];
bmsOlineNum++;
}
}
if (bmsOlineNum)
{
stlogic.para_delivery.task_params.distr.stationBmsSoc = (stlogic.para_delivery.task_params.distr.sumSoc / (SOCMAX * bmsOlineNum)) * 100.0;
}
else
{
stlogic.para_delivery.task_params.distr.stationBmsSoc = 0.0;
}
}
if (E_TACTIC_MODE_DEBUG == stlogic.para_delivery.mode && stlogic.para_delivery.task_params.debug.protectSwitch)
{
charge_params = NULL;
return 0; // 调试模式保护跳过
}
if (charge_params->power < 0) // 充电
{
if (stlogic.para_delivery.task_params.distr.stationBmsSoc >= charge_params->socForbidCharge)
{
// 到达禁充SOC
charge_params->power = 0;
return 0;
}
logic_protect_overload(charge_params); // 防过载
if (charge_params->demandCtl)
{
logic_protect_demandCtrl(charge_params); // 需量控制
}
}
else if (charge_params->power > 0) // 放电
{
if (stlogic.para_delivery.task_params.distr.stationBmsSoc <= charge_params->socForbidDischarge)
{
// 到达禁放SOC
charge_params->power = 0;
return 0;
}
if (charge_params->backFlow)
{
logic_protect_backflow(charge_params); // 防逆流
}
}
else // 待机
{
// 待机目前考虑不用保护
}
logic_protect_maxPower(charge_params); // 限制功率
charge_params = NULL;
return 0; // 处理结束
}