/***************************************************************************** * @copyright 2024-202, . POWER SUPPLY CO., LTD. * @file logic_dido.C * @brief xxxx * @author Gary * @date 2024/10/18 * @remark 初修订 *****************************************************************************/ #include "logic_comm.h" #include "logic_dido.h" // dido任务数组 static gpio_func_t gpioDiTask[MAX_NUM_CABINT][DI_End - DI_Start] = {NULL}; static gpio_func_t gpioDoTask[MAX_NUM_CABINT][DO_End - DO_Start] = {NULL}; static gpio_rtdb_data_parsing_t gpioRtdbData = {0}; pthread_mutex_t stateMutex = PTHREAD_MUTEX_INITIALIZER; // 开启对应功能的led闪烁 uint8_t ledFucSwitch[kLedFuc_End] = {0}; /***************************************************************************** * @brief 更新系统状态函数 (内部带互斥锁) * @param[in] state_e newState 需要更新的状态 * @param[in] 状态使能 enOrDisable 0 不使能 1 使能 (仅用于故障状态恢复) * @return 无 *****************************************************************************/ void updateState(state_e newState, bool enOrDisable) { static state_e currentState = kState_Start; pthread_mutex_lock(&stateMutex); if (currentState == kState_Fault) { if (newState == kState_Fault) { if (enOrDisable) { // 故障状态再次被调用,保持故障状态 pthread_mutex_unlock(&stateMutex); return; } else { // 故障解除 切为停机 currentState = kState_Shutdown; } } else { // 非故障状态调用,忽略 pthread_mutex_unlock(&stateMutex); return; } } else if (currentState == newState) { // 非故障状态再次被调用,保持故障状态 pthread_mutex_unlock(&stateMutex); return; } else // 所有状态的更新 { if (enOrDisable) { currentState = newState; } else { // 防止多次调用故障解除 pthread_mutex_unlock(&stateMutex); return; } } // 系统状态写入实时库 setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_RunState, (double)currentState); pthread_mutex_unlock(&stateMutex); return; } // RTDB数据获取 void faultDataGet() { uint8_t loop = 0; // DI值获取 for (loop = 0; loop < (DI_End - DI_Start); loop++) { gpioRtdbData.diValue[loop] = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Di_Start + loop)); } // 获取联网状态 ledFucSwitch[kLedFuc_wlan] = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_netStatus); gpioRtdbData.pccmeterStatus = (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_Pccmeter, 0, kPCC_IsOnline)); gpioRtdbData.bsmeterStatus = (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_Bsmeter, 0, kBs_IsOnline)); for (loop = 0; loop < gpioRtdbData.pcsSum; loop++) { gpioRtdbData.pcsStatus[loop] = 0; gpioRtdbData.pcsStatus[loop] += (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_PCS, loop, kPcs_IsOnline)); gpioRtdbData.pcsStatus[loop] += (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_PCS, loop, kPcs_TotalFault); } for (loop = 0; loop < gpioRtdbData.bsuNum; loop++) { gpioRtdbData.bsuStatus[loop] = 0; gpioRtdbData.bsuStatus[loop] += (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_BSU, loop, kBsu_IsOnline)); gpioRtdbData.bsuStatus[loop] += (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_BSU, loop, kBsu_TotalAlarm); gpioRtdbData.bsuStatus[loop] += (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_BSU, loop, kBsu_TotalFault); } for (loop = 0; loop < gpioRtdbData.bcuNum; loop++) { gpioRtdbData.bcuStatus[loop] = 0; gpioRtdbData.bcuStatus[loop] += (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_BCU, loop, kBcu_IsOnline)); gpioRtdbData.bcuStatus[loop] += (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_BCU, loop, kBsu_TotalAlarm); gpioRtdbData.bcuStatus[loop] += (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_BCU, loop, kBsu_TotalFault); } for (loop = 0; loop < gpioRtdbData.thsensorNum; loop++) { gpioRtdbData.thsensorStatus[loop] = (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_Thsensor, loop, kTHSenor_IsOnline)); gpioRtdbData.tmp[loop] = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_Thsensor, loop, kTHSenor_Temp); } for (loop = 0; loop < gpioRtdbData.upsNum; loop++) { gpioRtdbData.upsStatus[loop] = (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_UPS, loop, kUps_IsOnline)); } for (loop = 0; loop < gpioRtdbData.airCondNum; loop++) { gpioRtdbData.airCondStatus[loop] = (uint8_t)(0 == (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_AirCond_LiquidCool, loop, kAcLiquidMac_IsOnline)); } #if 0 printf("******************************************************** tmp %d 度\r\n",(uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_Thsensor, 0, kTHSenor_Temp)); printf("输入:\r\n 水浸传感器低:%d\r\n水浸传感器高:%d\r\n急停:%d\r\n烟感:%d\r\n温感:%d\r\n消防触发反馈:%d\r\n门禁传感器:%d\r\n交流断路器反馈:%d\r\n", (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1), (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+1), (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+2), (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+3), (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+4), (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+5), (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+6), (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Di1+7)); printf("\r\n输入:\r\n运行灯:%d\r\n故障灯:%d\r\n交流断路器分励脱扣:%d\r\n机柜风扇:%d\r\n消防一级准备:%d\r\n消防二级触发:%d\r\n", (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Do1), (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Do1+1), (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Do1+2), (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Do1+3), (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Do1+4), (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_Do1+5)); #endif return; } // RTDB数据写入 void faultDataSet(uint8_t cabt) { return; } // 水浸低(常闭) void diWaterLowGetOn(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.waterLow[cabt] = kGpioSwitch_off; } else { gpioRtdbData.waterLow[cabt] = kGpioSwitch_on; } } // 水浸低(常开) void diWaterLowGetOff(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.waterLow[cabt] = kGpioSwitch_on; } else { gpioRtdbData.waterLow[cabt] = kGpioSwitch_off; } } // 水浸高(常闭) void diWaterHighGetOn(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.waterHigh[cabt] = kGpioSwitch_off; } else { gpioRtdbData.waterHigh[cabt] = kGpioSwitch_on; } } // 水浸高(常开) void diWaterHighGetOff(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.waterHigh[cabt] = kGpioSwitch_on; } else { gpioRtdbData.waterHigh[cabt] = kGpioSwitch_off; } } // 急停(常闭) void diEmergSignalGetOn(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.emergStop[cabt] = kGpioSwitch_off; } else { gpioRtdbData.emergStop[cabt] = kGpioSwitch_on; } } // 急停(常开) void diEmergSignalGetOff(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.emergStop[cabt] = kGpioSwitch_on; } else { gpioRtdbData.emergStop[cabt] = kGpioSwitch_off; } } // 烟感(常闭) void diSmokeSignalGetOn(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.smokeDetec[cabt] = kGpioSwitch_off; } else { gpioRtdbData.smokeDetec[cabt] = kGpioSwitch_on; } } // 烟感(常开) void diSmokeSignalGetOff(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.smokeDetec[cabt] = kGpioSwitch_on; } else { gpioRtdbData.smokeDetec[cabt] = kGpioSwitch_off; } } // 温感(常闭) void diTempSignalGetOn(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.tempSensor[cabt] = kGpioSwitch_off; } else { gpioRtdbData.tempSensor[cabt] = kGpioSwitch_on; } } // 温感(常开) void diTempSignalGetOff(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.tempSensor[cabt] = kGpioSwitch_on; } else { gpioRtdbData.tempSensor[cabt] = kGpioSwitch_off; } } // 消防触发反馈(常闭) void diFireFeedbackSignalGetOn(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.fireFeedback[cabt] = kGpioSwitch_off; // 消防触发 } else { gpioRtdbData.fireFeedback[cabt] = kGpioSwitch_on; // 消防未触发 } } // 消防触发反馈(常开) void diFireFeedbackSignalGetOff(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.fireFeedback[cabt] = kGpioSwitch_on; // 消防触发 } else { gpioRtdbData.fireFeedback[cabt] = kGpioSwitch_off; // 消防未触发 } } // 门禁传感器(常闭) void diAccessSignalGetOn(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.accessSensor[cabt] = kGpioSwitch_off; } else { gpioRtdbData.accessSensor[cabt] = kGpioSwitch_on; } } // 门禁传感器(常开) void diAccessSignalGetOff(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.accessSensor[cabt] = kGpioSwitch_on; } else { gpioRtdbData.accessSensor[cabt] = kGpioSwitch_off; } } // 交流断路器反馈(常闭) void diCircuitFeedGetOn(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.circuitFeed[cabt] = kGpioSwitch_off; } else { gpioRtdbData.circuitFeed[cabt] = kGpioSwitch_on; } } // 交流断路器反馈(常开) void diCircuitFeedGetOff(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.circuitFeed[cabt] = kGpioSwitch_on; } else { gpioRtdbData.circuitFeed[cabt] = kGpioSwitch_off; } } // 气溶胶触发反馈(常闭) void diFireAerosolGetOn(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.fireAerosol[cabt] = kGpioSwitch_off; } else { gpioRtdbData.fireAerosol[cabt] = kGpioSwitch_on; } } // 气溶胶触发反馈(常开) void diFireAerosolGetOff(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.fireAerosol[cabt] = kGpioSwitch_on; } else { gpioRtdbData.fireAerosol[cabt] = kGpioSwitch_off; } } // 浪涌辅助触点(常闭) void diSurgeGetOn(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.surge[cabt] = kGpioSwitch_off; } else { gpioRtdbData.surge[cabt] = kGpioSwitch_on; } } // 浪涌辅助触点(常开) void diSurgeGetOff(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.surge[cabt] = kGpioSwitch_on; } else { gpioRtdbData.surge[cabt] = kGpioSwitch_off; } } // 消防故障(常闭) void diFireFaultGetOn(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.fireFault[cabt] = kGpioSwitch_off; } else { gpioRtdbData.fireFault[cabt] = kGpioSwitch_on; } } // 消防故障(常开) void diFireFaultGetOff(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.diValue[indx]) { gpioRtdbData.fireFault[cabt] = kGpioSwitch_on; } else { gpioRtdbData.fireFault[cabt] = kGpioSwitch_off; } } // LED闪烁模式 void doRunLedBliCtrl(uint8_t cabt, uint16_t indx) { static int rtLedStat[MAX_NUM_CABINT] = {kGpioSwitch_off}; // 本机LED闪烁与DIDO策略无关仅用于开发 ledFucSwitch[kLedFuc_on] = kGpioSwitch_on; if (rtLedStat[cabt]) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on); // drvGpioWrite(DO_Start + indx, kGpioSwitch_on); rtLedStat[cabt] = kGpioSwitch_off; } else { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off); // drvGpioWrite(DO_Start + indx, kGpioSwitch_off); rtLedStat[cabt] = kGpioSwitch_on; } return; } // LED常亮常灭模式 void doRunLedContnCtrl(uint8_t cabt, uint16_t indx) { static gpioSwitch_e rtLedStat[MAX_NUM_CABINT] = {kGpioSwitch_off}; if (kGpioSwitch_on) // 待获取开灯条件 { if (1 != rtLedStat[cabt]) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on); drvGpioWrite(DO_Start + indx, kGpioSwitch_on); // 写DO任务暂时在这里 rtLedStat[cabt] = kGpioSwitch_on; // 本机LED闪烁与DIDO策略无关仅用于开发 ledFucSwitch[kLedFuc_on] = kGpioSwitch_on; } } else if (kGpioSwitch_off) { if (0 != rtLedStat[cabt]) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off); drvGpioWrite(DO_Start + indx, kGpioSwitch_off); // 写DO任务暂时在这里 rtLedStat[cabt] = kGpioSwitch_off; // 本机LED闪烁与DIDO策略无关仅用于开发 ledFucSwitch[kLedFuc_on] = kGpioSwitch_off; } } return; } // 故障LED闪烁模式 void doFaultLedBliCtrl(uint8_t cabt, uint16_t indx) { static int rtLedStat[MAX_NUM_CABINT] = {kGpioSwitch_off}, flag = 0; // 告警 if (gpioRtdbData.thsensorStatus[cabt] || gpioRtdbData.upsStatus[cabt] || gpioRtdbData.airCondStatus[cabt]) { // EMS自带告警灯闪烁 ledFucSwitch[kLedFuc_alarm] = kGpioSwitch_on; } else { ledFucSwitch[kLedFuc_alarm] = kGpioSwitch_off; } // 故障 if (gpioRtdbData.pccmeterStatus || gpioRtdbData.bsmeterStatus || gpioRtdbData.pcsStatus[cabt] || gpioRtdbData.bsuStatus[cabt] || gpioRtdbData.bcuStatus[cabt]) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off); // 关灯 // 控灯 // 故障上报 updateState(kState_Fault, true); flag = 1; // EMS自带故障灯闪烁 ledFucSwitch[kLedFuc_fault] = kGpioSwitch_on; } else if (flag) { // 故障恢复上报 updateState(kState_Fault, false); flag = 0; // 恢复只能调用一次 drvGpioWrite(DO_Start + indx, kGpioSwitch_off); ledFucSwitch[kLedFuc_fault] = kGpioSwitch_off; return; } if (rtLedStat[cabt]) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on); // drvGpioWrite(DO_Start + indx, kGpioSwitch_on); rtLedStat[cabt] = kGpioSwitch_off; } else { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off); // drvGpioWrite(DO_Start + indx, kGpioSwitch_off); rtLedStat[cabt] = kGpioSwitch_on; } return; } // 故障和告警LED常亮常灭模式 void doFaultLedContnCtrl(uint8_t cabt, uint16_t indx) { static gpioSwitch_e rtLedStat[MAX_NUM_CABINT] = {kGpioSwitch_off}; if (gpioRtdbData.pccmeterStatus || gpioRtdbData.bsmeterStatus || gpioRtdbData.pcsStatus[cabt] || gpioRtdbData.bsuStatus[cabt] || gpioRtdbData.bcuStatus[cabt]) { if (kGpioSwitch_on != rtLedStat[cabt]) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on); drvGpioWrite(DO_Start + indx, kGpioSwitch_on); // 写DO任务暂时在这里 rtLedStat[cabt] = kGpioSwitch_on; // 故障上报 updateState(kState_Fault, true); // 本机LED闪烁与DIDO策略无关仅用于开发 ledFucSwitch[kLedFuc_fault] = kGpioSwitch_on; } } else { if (kGpioSwitch_off != rtLedStat[cabt]) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off); drvGpioWrite(DO_Start + indx, kGpioSwitch_off); // 写DO任务暂时在这里 rtLedStat[cabt] = kGpioSwitch_off; // 故障恢复上报 updateState(kState_Fault, false); // 本机LED闪烁与DIDO策略无关仅用于开发 ledFucSwitch[kLedFuc_fault] = kGpioSwitch_on; } } // 告警 if (gpioRtdbData.thsensorStatus[cabt] || gpioRtdbData.upsStatus[cabt] || gpioRtdbData.airCondStatus[cabt]) { // EMS自带告警灯闪烁 ledFucSwitch[kLedFuc_alarm] = kGpioSwitch_on; } else { ledFucSwitch[kLedFuc_alarm] = kGpioSwitch_off; } return; } // 交流断路器分励脱扣 void doCircuitTrippingCtrl(uint8_t cabt, uint16_t indx) { static gpioSwitch_e rtDoStat[MAX_NUM_CABINT] = {kGpioSwitch_off}; if (gpioRtdbData.emergStop[cabt] || (gpioRtdbData.waterHigh[cabt] && gpioRtdbData.waterHigh[cabt]) || gpioRtdbData.tempSensor[cabt] || gpioRtdbData.smokeDetec[cabt] || gpioRtdbData.fireFeedback[cabt]) { if (kGpioSwitch_on != gpioRtdbData.circuitFeed[cabt] && kGpioSwitch_on != rtDoStat[cabt]) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on); drvGpioWrite(DO_Start + indx, kGpioSwitch_on); // 写DO任务暂时在这里 rtDoStat[cabt] = kGpioSwitch_on; } if (1 != stlogic.para_delivery.task_params.protect.scramButton) { stlogic.para_delivery.task_params.protect.scramButton = 1; } // 不仅仅是交流脱扣 还有 PCS 停机 BMS脱扣 } else { if (0 != stlogic.para_delivery.task_params.protect.scramButton) { stlogic.para_delivery.task_params.protect.scramButton = 0; } if (kGpioSwitch_off != rtDoStat[cabt]) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off); drvGpioWrite(DO_Start + indx, kGpioSwitch_off); // 写DO任务暂时在这里 rtDoStat[cabt] = kGpioSwitch_off; } } } // 机柜风扇控制 void doFanCtrl(uint8_t cabt, uint16_t indx) { static gpioSwitch_e rtFanStat[MAX_NUM_CABINT] = {kGpioSwitch_off}; if (gpioRtdbData.tmp[cabt] >= 35) // 判断风扇开启条件 { if (rtFanStat[cabt] != kGpioSwitch_on) // 开启 { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on); drvGpioWrite(DO_Start + indx, kGpioSwitch_on); rtFanStat[cabt] = kGpioSwitch_on; } } else if (gpioRtdbData.tmp[cabt] < 30 && 1 == rtFanStat[cabt]) // 回差判断 { if (rtFanStat[cabt] != kGpioSwitch_off) // 关闭 { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off); drvGpioWrite(DO_Start + indx, kGpioSwitch_off); rtFanStat[cabt] = kGpioSwitch_off; } } return; } // 消防一级准备 暂时不启用 void multiCondTrigFire1(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.smokeDetec[cabt] && gpioRtdbData.tempSensor[cabt]) { if (kGpioSwitch_off == gpioRtdbData.fireFeedback[cabt]) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on); // drvGpioWrite(DO_Start + indx, kGpioSwitch_on); } } else { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off); // drvGpioWrite(DO_Start + indx, kGpioSwitch_off); } return; } // 消防二级触发 暂时不启用 void multiCondTrigFire2(uint8_t cabt, uint16_t indx) { if (gpioRtdbData.smokeDetec[cabt] && gpioRtdbData.tempSensor[cabt]) { if (kGpioSwitch_off == gpioRtdbData.fireFeedback[cabt]) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on); // drvGpioWrite(DO_Start + indx, kGpioSwitch_on); } } else { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off); // drvGpioWrite(DO_Start + indx, kGpioSwitch_off); } return; } // 对应DO口输出高电平 void doPutHigh(uint8_t cabt, uint16_t indx) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_on); drvGpioWrite(DO_Start + indx, kGpioSwitch_on); return; } // 对应DO口输出低电平 void doPutLow(uint8_t cabt, uint16_t indx) { setRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, (kEms_Do_Start + indx), kGpioSwitch_off); drvGpioWrite(DO_Start + indx, kGpioSwitch_off); return; } static gpio_func_t diFuc[kDiFuc_End] = { NULL, diWaterLowGetOn, // 水浸传感器低常闭0 diWaterLowGetOff, // 水浸传感器低常开1 diWaterHighGetOn, // 水浸传感器高常闭2 diWaterHighGetOff, // 水浸传感器高常开3 diEmergSignalGetOn, // 急停常闭4 diEmergSignalGetOff, // 急停常开5 diSmokeSignalGetOn, // 烟感常闭6 diSmokeSignalGetOff, // 烟感常开7 diTempSignalGetOn, // 温感常闭8 diTempSignalGetOff, // 温感常开9 diFireFeedbackSignalGetOn, // 消防触发反馈常闭10 diFireFeedbackSignalGetOff, // 消防触发反馈常开11 diAccessSignalGetOn, // 门禁传感器常闭12 diAccessSignalGetOff, // 门禁传感器常开13 diCircuitFeedGetOn, // 交流断路器反馈常闭14 diCircuitFeedGetOff, // 交流断路器反馈常开15 diFireAerosolGetOn, // 气溶胶触发反馈常闭16 diFireAerosolGetOff, // 气溶胶触发反馈常开17 diSurgeGetOn, // 浪涌辅助触点常闭18 diSurgeGetOff, // 浪涌辅助触点常开19 diFireFaultGetOn, // 消防故障常闭20 diFireFaultGetOff // 消防故障常开21 }; static gpio_func_t doFuc[kDoFuc_End] = { NULL, doRunLedContnCtrl, // 运行灯 常亮 0 doRunLedBliCtrl, // 运行灯 闪烁 1 doFaultLedContnCtrl, // 故障灯 常亮 2 doFaultLedBliCtrl, // 故障灯 闪烁 3 doCircuitTrippingCtrl, // 交流断路器分励脱扣 4 doFanCtrl, // 机柜风扇 5 multiCondTrigFire1, // 消防一级准备 6 multiCondTrigFire2, // 消防二级触发 一级二级同时置高电平才真的喷洒 7 doPutHigh, // 对应DO口输出高电平8 doPutLow // 对应DO口输出低电平9 }; // 从sq获取配置用于初始化DIDO定义 int didoConfigInit() { // 初始化 memset(&gpioRtdbData, 0, sizeof(gpio_rtdb_data_parsing_t)); UT_array *didoInfoArr = NULL; // 测试使用默认配置 #if 0 gpioDiTask[0][0] = diFuc[0]; gpioDiTask[0][1] = diFuc[1]; gpioDiTask[0][2] = diFuc[2]; gpioDiTask[0][3] = diFuc[3]; gpioDiTask[0][4] = diFuc[4]; gpioDiTask[0][5] = diFuc[5]; gpioDiTask[0][6] = diFuc[6]; gpioDiTask[0][7] = diFuc[7]; gpioDoTask[0][0] = doFuc[0]; gpioDoTask[0][1] = doFuc[2]; gpioDoTask[0][2] = doFuc[4]; gpioDoTask[0][3] = doFuc[5]; gpioDoTask[0][4] = doFuc[6]; gpioDoTask[0][5] = doFuc[7]; #endif // 获取数据库ID、设备类型、设备编号、协议类型 if (0 != kit_get_di_do_set_arr(&didoInfoArr)) { return 1; } // 遍历设备 utarray_foreach(didoInfoArr, di_do_logic_set_t *, p_didoInfo) { if (kDi == p_didoInfo->dIDOType) { gpioDiTask[p_didoInfo->cabinetCode][p_didoInfo->dIDOseq] = diFuc[p_didoInfo->strategySeqDi]; } else if (kDo == p_didoInfo->dIDOType) { gpioDoTask[p_didoInfo->cabinetCode][p_didoInfo->dIDOseq] = doFuc[p_didoInfo->strategySeqDo]; } } utarray_free(didoInfoArr); // 释放 UT_array gpioDoTask[0][0] = doFuc[1]; gpioDoTask[0][1] = doFuc[3]; return 0; } // 初始化rtdb 固定的的数据 void gpioRtdbDataInit() { // 设备数量读取 gpioRtdbData.pccmeterNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_PccmeterNum); gpioRtdbData.bsmeterNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_BsmeterNum); gpioRtdbData.pcsSum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_PCSNum); gpioRtdbData.bsuNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_BSUNum); gpioRtdbData.bcuNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_BCUNum); gpioRtdbData.thsensorNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_ThsensorNum); // gpioRtdbData.didoNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_DI_Num); gpioRtdbData.upsNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_UPSNum); gpioRtdbData.airCondNum = (uint8_t)getRtdbPointValue(kSign_ShMem, kDev_Type_EMS, 0, kEms_AirCondNum); return; } // 模块主循环 void *taskGpioProduce(void *itime) { uint16_t cnt = 0; uint16_t time = *(uint16_t *)itime; uint8_t loop = 0, cabt = 0; if (time == 0) { KITPTF(LOG_MODBUS_EN, INFO_EN, "EMS本地DIDO处理 线程 延时参数有误!!"); KITLOG(LOG_MODBUS_EN, INFO_EN, "EMS本地DIDO处理 线程 延时参数有误!!"); } while (1) { if (0 == cnt % time) { faultDataGet(); // 故障数据刷新 for (cabt = 0; cabt < MAX_NUM_CABINT; cabt++) { for (loop = 0; loop < (DI_End - DI_Start); loop++) { if (NULL != gpioDiTask[cabt][loop]) { (*gpioDiTask[cabt][loop])(cabt, loop); } } for (loop = 0; loop < (DO_End - DO_Start); loop++) { if (NULL != gpioDoTask[cabt][loop]) { (*gpioDoTask[cabt][loop])(cabt, loop); } } // 维护RTDB故障 faultDataSet(cabt); } cnt = 0; } cnt++; usleep(50000); } } void *led_blink_thread(void *arg) { uint8_t led_status = kGpioSwitch_on; ledFuc_e step = 0; while (1) { // 运行灯必然会闪烁 if (ledFucSwitch[kLedFuc_on]) { led_status = (led_status == kGpioSwitch_on) ? kGpioSwitch_off : kGpioSwitch_on; for (step = 0; step < kLedFuc_End; step++) { switch (step) { case kLedFuc_on: drvGpioWrite(LED1, (int)(led_status && ledFucSwitch[step])); // 开机控灯 break; case kLedFuc_alarm: drvGpioWrite(LED2, (int)ledFucSwitch[step]); // 告警控灯 break; case kLedFuc_wlan: drvGpioWrite(LED3, (int)(led_status && ledFucSwitch[step])); // 连网控灯 break; case kLedFuc_fault: drvGpioWrite(LED4, (int)ledFucSwitch[step]); // 故障控灯 break; default: break; } } } else { sleep(1); } usleep(50000); } pthread_exit(NULL); } /********************************************************************* * @brief 初始化 GPIO模块 任务入口 * @param[in] time 运行周期 * @return 无 *********************************************************************/ void creatGpioModTaskEntry(uint16_t time) { // GPIO配置只在启动时读一遍 修改需要重启 if (0 != didoConfigInit()) { KITPTF(LOG_MODBUS_EN, ERROR_EN, "EMS获取DIDO配置失败"); KITLOG(LOG_MODBUS_EN, ERROR_EN, "EMS获取DIDO配置失败"); return; } // 一些固定数据获取 gpioRtdbDataInit(); static uint16_t itime = 10; itime = time; pthread_t pfd, led_thread; if (pthread_create(&pfd, NULL, taskGpioProduce, (void *)&itime)) { KITPTF(LOG_MODBUS_EN, INFO_EN, "EMS本地DIDO处理 线程 创建成功"); KITLOG(LOG_MODBUS_EN, INFO_EN, "EMS本地DIDO处理 线程 创建成功"); } // 创建LED闪烁线程 if (pthread_create(&led_thread, NULL, led_blink_thread, NULL) != 0) { KITPTF(LOG_MODBUS_EN, INFO_EN, "LED闪烁 线程 创建成功"); KITLOG(LOG_MODBUS_EN, INFO_EN, "LED闪烁 线程 创建成功"); } }