ems/ems_c/logic/logic_task_data.c

399 lines
15 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_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 数据类型表示写入的数据类型Uint8、Int16 等)
* @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;
}