/***************************************************************************** * @copyright 2024-202, . POWER SUPPLY CO., LTD. * @file logic_task_schedu.c * @brief xxxx * @author Gary * @date 2024/09/28 * @remark 初修订 *****************************************************************************/ #include #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; }