forked from gary/ems
2
0
Fork 0
sun_ems/ems_c/logic/logic_dido.c

920 lines
30 KiB
C
Raw 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_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闪烁 线程 创建成功");
}
}