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