ems/ems_c/logic/logic_task_data.c

399 lines
15 KiB
C
Raw Normal View History

2025-05-13 17:49:49 +08:00
/*****************************************************************************
* @copyright 2024-202, . POWER SUPPLY CO., LTD.
* @file logic_task_schedu.c
* @brief xxxx
* @author Gary
* @date 2024/09/28
* @remark
*****************************************************************************/
#include <pthread.h>
#include "logic_comm.h"
// 各模块任务函数注册
// static task_funcPoint_t g_taskUnitSet;
// 设置任务的固定参数和初始参数
// static task_params_t g_defaultParams;
// 序号设备号点位ID
ParamFromRTDB RTDBtable[e_Logic_RTDB_end] =
{
{e_Logic_totalAcPower, kDev_Type_Pccmeter, kPCC_TotalActivePwr },
{e_Logic_emsActivePower, kDev_Type_Bsmeter, kBs_TotalActivePwr },
{e_Logic_bmsSoc, kDev_Type_BCU, kBcu_SOC },
{e_Logic_pcsMaxChaPower, kDev_Type_PCS, kPcs_MaxAllowedChgPwr },
{e_Logic_pcsMaxDiscPower, kDev_Type_PCS, kPcs_MaxAllowedDisChgPwr },
{e_Logic_nowBmsPower, kDev_Type_PCS, kPcs_TotalActivePwr },
{e_Logic_nowActiveDemand, kDev_Type_Pccmeter, kPCC_MaxDemandActiveFwd },
{e_Logic_distrPower, kDev_Type_PCS, kPcs_ConstantActivePwrSet },
{e_Logic_pcsSwitch, kDev_Type_PCS, kPcs_DeviceSwitchCommand },
{e_Logic_pcsState, kDev_Type_PCS, kPcs_IsOnline },
{e_Logic_bmsState, kDev_Type_BCU, kBcu_IsOnline },
{e_Logic_emsMode, kDev_Type_EMS, kEms_LogicMode },
{e_Logic_bsuMaxCellTemp, kDev_Type_BSU, kBsu_MaxCellTemp },
{e_Logic_bsuMinCellTemp, kDev_Type_BSU, kBsu_MinCellTemp }
// {e_Logic_AcLiquidSwitch, kDev_Type_AirCond_LiquidCool, kAcLiquidMac_SetOnOff },
// {e_Logic_AcLiquidHeatTemp, kDev_Type_AirCond_LiquidCool, kAcLiquidMac_SetHeatTemp },
// {e_Logic_AcLiquidColdTemp, kDev_Type_AirCond_LiquidCool, kAcLiquidMac_SetCoolDiff }
};
/*****************************************************************************
* @brief RTDB参数
* @param[in]
* @return
*****************************************************************************/
void logic_getValue(int No, void *value, data_type_e dataType)
{
if (No < 0 || No >= e_Logic_RTDB_end)
{
// 输入的 No 无效
return;
}
// 从表格中获取对应的条目
ParamFromRTDB entry = RTDBtable[No];
switch (dataType)
{
case Uint8:
{
// 对于 uint8_t 类型
uint8_t *uint8Value = (uint8_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
uint8Value[i] = (uint8_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Int8:
{
// 对于 int8_t 类型
int8_t *int8Value = (int8_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
int8Value[i] = (int8_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Uint16:
{
// 对于 uint16_t 类型
uint16_t *uint16Value = (uint16_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
uint16Value[i] = (uint16_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Int16:
{
// 对于 int16_t 类型
int16_t *int16Value = (int16_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
int16Value[i] = (int16_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Uint32:
{
// 对于 uint32_t 类型
uint32_t *uint32Value = (uint32_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
uint32Value[i] = (uint32_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Int32:
{
// 对于 int32_t 类型
int32_t *int32Value = (int32_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
int32Value[i] = (int32_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Uint64:
{
// 对于 uint64_t 类型
uint64_t *uint64Value = (uint64_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
uint64Value[i] = (uint64_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Int64:
{
// 对于 int64_t 类型
int64_t *int64Value = (int64_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
int64Value[i] = (int64_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Float32:
{
// 对于 float_t (Float32) 类型
float_t *floatValue = (float_t *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
floatValue[i] = (float_t)getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
case Float64:
{
// 对于 double (Float64) 类型
double *doubleValue = (double *)value;
for (uint16_t i = 0; i < gStDevTypeNum[entry.devType]; i++)
{
doubleValue[i] = getRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId);
}
break;
}
default:
// 不支持的类型
return;
}
return;
}
/*****************************************************************************
* @brief
* @param[in] No RTDBtable
* @param[in] value
* @param[in] num
* @return
*****************************************************************************/
void logic_skip_judge(bool *skip, uint16_t num, int No, void *value, data_type_e dataType)
{
ParamFromRTDB entry = RTDBtable[No];
for (uint16_t i = 0; i < num; i++)
{
// skip[i] = false; // 默认不跳过
if(stlogic.para_delivery.task_params.distr.allocateMode)
{
float_t *floatValue = (float_t *)value;
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_APhaseAPSet, (float_t)floatValue[i]/3);
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_BPhaseAPSet, (float_t)floatValue[i]/3);
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_CPhaseAPSet, (float_t)floatValue[i]/3);
skip[i] = true; // 标记跳过
continue;
}
// 根据 No 值进行不同的处理
switch (No)
{
case e_Logic_pcsSwitch: // PCS开关
// 判断 pcsState 和 bmsState
if (stlogic.para_delivery.task_params.distr.pcsState[i] == 0 ||
stlogic.para_delivery.task_params.distr.bmsState[i] == 0)
{
skip[i] = true; // 标记跳过
}
else
{
// _PCS 特殊处理
#ifdef _PCS
// if (dataType == Uint16 && value != NULL)
// {
uint16_t *uint16Value = (uint16_t *)value;
if (uint16Value[i])
{
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_DeviceStartup, 1.0);
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_DeviceShutdown, 0.0);
}
else
{
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_DeviceStartup, 0.0);
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, kPcs_DeviceShutdown, 1.0);
}
// }
skip[i] = true; // 标记跳过
#endif
}
break;
case e_Logic_distrPower: // distrPower 为 No 的处理逻辑
// 判断 pcsState 和 bmsState
if (stlogic.para_delivery.task_params.distr.pcsState[i] == 0 ||
stlogic.para_delivery.task_params.distr.bmsState[i] == 0)
{
// 分配电力为 No 且满足保护条件时跳过
if (E_TACTIC_MODE_DEBUG != stlogic.para_delivery.mode ||
!stlogic.para_delivery.task_params.debug.protectSwitch)
{
skip[i] = true; // 标记跳过
}
}
break;
default:
// 如果 No 不符合任何已定义的条件,默认不跳过
break;
}
}
}
/*****************************************************************************
* @brief RTDB参数
* @param[in] No RTDBtable
* @param[in] value
* @param[in] num
* @param[in] dataType Uint8Int16
* @return
*****************************************************************************/
void logic_setValue(int No, void *value, uint16_t num, data_type_e dataType)
{
if (No < 0 || No >= e_Logic_RTDB_end)
{
// 输入的 No 无效
return;
}
// 从表格中获取对应的条目
ParamFromRTDB entry = RTDBtable[No];
bool skip[MAX_NUM_CABINT] = {false};
// 调用跳过判断逻辑
logic_skip_judge(skip, num, No, value, dataType);
for (uint16_t i = 0; i < num; i++)
{
if (skip[i])
continue;
switch (dataType)
{
case Uint8:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((uint8_t*)value)[i]);
break;
case Int8:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((int8_t*)value)[i]);
break;
case Uint16:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((uint16_t*)value)[i]);
break;
case Int16:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((int16_t*)value)[i]);
break;
case Uint32:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((uint32_t*)value)[i]);
break;
case Int32:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((int32_t*)value)[i]);
break;
case Uint64:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((uint64_t*)value)[i]);
break;
case Int64:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((int64_t*)value)[i]);
break;
case Float32:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, (double)((float*)value)[i]);
break;
case Float64:
setRtdbPointValue(Rtdb_ShMem, entry.devType, i, entry.pointId, ((double*)value)[i]);
break;
default:
// 不支持的类型,返回
return;
}
}
return;
}
/*****************************************************************************
* @brief
*
* @return 0 -1 1
*****************************************************************************/
void logic_getRTDBParams()
{
/*获取电表的数据*/
logic_getValue(e_Logic_totalAcPower, &stlogic.para_delivery.task_params.protect.totalActivePower, Float32);
logic_getValue(e_Logic_emsActivePower, &stlogic.para_delivery.task_params.protect.emsActivePower, Float32);
logic_getValue(e_Logic_nowActiveDemand, &stlogic.para_delivery.task_params.protect.nowActiveDemand, Float32);
/*获取pcs的数据*/
logic_getValue(e_Logic_bmsSoc, &stlogic.para_delivery.task_params.distr.bmsSoc, Float32);
logic_getValue(e_Logic_pcsMaxChaPower, &stlogic.para_delivery.task_params.distr.pcsMaxChaPower, Float32);
logic_getValue(e_Logic_pcsMaxDiscPower, &stlogic.para_delivery.task_params.distr.pcsMaxDiscPower, Float32);
logic_getValue(e_Logic_nowBmsPower, &stlogic.para_delivery.task_params.distr.nowBmsPower, Float32);
logic_getValue(e_Logic_pcsState, &stlogic.para_delivery.task_params.distr.pcsState, Uint8);
logic_getValue(e_Logic_bmsState, &stlogic.para_delivery.task_params.distr.bmsState, Uint8);
}
/*********************************************************************
* @brief
* @param[in]
* @return
*********************************************************************/
int logic_paramUpload()
{
if (LOGIC_SIGN_UPLOAD == stlogic.para_delivery.task_params.protect.protectSign)
{
stlogic.para_delivery.task_params.protect.protectSign = LOGIC_SIGN_NONE;
writeWebSign(kSign_ShMem, kSign_Protect, LOGIC_SIGN_UPLOAD);
}
if (LOGIC_SIGN_UPLOAD == stlogic.para_delivery.task_params.distr.powerSign)
{
stlogic.para_delivery.task_params.distr.powerSign = LOGIC_SIGN_NONE;
writeWebSign(kSign_ShMem, kSign_ActivePower, LOGIC_SIGN_UPLOAD);
}
switch (stlogic.para_delivery.mode)
{
case E_TACTIC_MODE_DEBUG: // 调试模式
writeWebSign(kSign_ShMem, kSign_LogicDebug, LOGIC_SIGN_UPLOAD);
// PCS开关机下发
logic_setValue(e_Logic_pcsSwitch, &stlogic.para_delivery.task_params.distr.pcsSwitch, stlogic.para_delivery.task_params.distr.cabintCont, Uint16);
// 功率下发
logic_setValue(e_Logic_distrPower, &stlogic.para_delivery.task_params.distr.nowDistPower, stlogic.para_delivery.task_params.distr.cabintCont, Float32);
break;
case E_TACTIC_MODE_PEAKVALLY: // 削峰填谷模式
writeWebSign(kSign_ShMem, kSign_LogicPeakValley, LOGIC_SIGN_UPLOAD);
// PCS开关机下发
logic_setValue(e_Logic_pcsSwitch, &stlogic.para_delivery.task_params.distr.pcsSwitch, stlogic.para_delivery.task_params.distr.cabintCont, Uint16);
// 功率下发
logic_setValue(e_Logic_distrPower, &stlogic.para_delivery.task_params.distr.nowDistPower, stlogic.para_delivery.task_params.distr.cabintCont, Float32);
break;
case E_TACTIC_MODE_DEMANDRES: // 需求响应模式
/* 暂未实现 */
// 系统状态更新为停机
updateState(kState_Shutdown, true);
break;
case E_TACTIC_MODE_LOADTRACK: // 负载跟踪模式
/* 暂未实现 */
// 系统状态更新为停机
updateState(kState_Shutdown, true);
break;
case E_TACTIC_MODE_DMDCTRL: // 需量控制
/* 暂未实现 */
// 系统状态更新为停机
updateState(kState_Shutdown, true);
break;
case E_TACTIC_MODE_PFCTRL: // 功率因数
/* 暂未实现 */
// 系统状态更新为停机
updateState(kState_Shutdown, true);
break;
default:
// 系统状态更新为停机
updateState(kState_Shutdown, true);
break;
}
// 运行模式入RTDB
logic_setValue(e_Logic_emsMode, &stlogic.para_delivery.mode, 1, Uint16);
return 0;
}