⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monitor.cpp

📁 电信机房MDF、电源柜监控源码,主要用在通信机房配线设备监控、电源柜监控
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Monitor.cpp : 实现文件
//

#include "stdafx.h"
#include <afxmt.h>
#include <afx.h>
#include "MDF.h"
#include ".\monitor.h"
#include "ptcweb.h"
#include "media.h"
#include "ptccable.h"
#include "ptcpowerdc.h"

//#include "..\Global\tcpbase.h"
// CMonitor 对话框

IMPLEMENT_DYNAMIC(CMonitor, CWnd)
extern CMDFApp theApp ;

//static UINT indicators[] =
//{
//	ID_SEPARATOR,           // 状态行指示器
//	ID_INDICATOR_CAPS,
//	ID_INDICATOR_NUM,
//	ID_INDICATOR_SCRL,
//};



CMonitor::CMonitor()
{
	/******************************************************************/
	//初始化通讯组件
	
	CreateEx(NULL,"#32770",NULL,WS_CAPTION | WS_TILEDWINDOW,0,0,1,1,NULL,NULL);
	strReceive.Empty();
	p_adodb = theApp.m_pAdoDB;
	memset(buff,0,MAX_SIZE);
	iRev = 0;
	m_protocol = new CProtocol();		//协议处理包
	m_pEQPool = new CEQPool();			//设备管理包
	m_pEQPool->InitUnitList();			//初始化设备列表
	IniEquipPort();						//初始化各监测端口状态
	m_pAnalyse = new CDataAnalyse();	//数据分析包	
	m_pAnalyse->SetParent(this);
	
	m_AskingStatus	= FALSE;			//轮巡监测线程状态


	m_hEventArray[0] = CreateEvent(NULL, TRUE, FALSE, "Close");
	m_hEventArray[1] = CreateEvent(NULL, TRUE, FALSE, "Reset");
	m_hEventArray[2] = CreateEvent(NULL, TRUE, FALSE, "Send");
	SetEvent(m_hEventArray[2]);

}

CMonitor::~CMonitor()
{
	//删除

	delete m_protocol;			//协议处理包
	delete m_pEQPool;			//设备管理包
	delete m_pAnalyse;			//数据分析包	

}



BEGIN_MESSAGE_MAP(CMonitor, CWnd)
//{{AFX_MSG_MAP(CMDFDlg)
	ON_MESSAGE(WM_SOCK_RXSTRING,onSockReadString)		//SOCKET 读数据
	ON_MESSAGE(WM_COMM_RXCHAR,onCom_RXChar)				//串口 读数据
	ON_MESSAGE(WM_STATUS_CHANGE,onStatusChange)			//设备状态改变
	ON_MESSAGE(WM_DEVICE_ALARM,onAlarming)				//设备发生告警
	ON_MESSAGE(WM_DEVICE_DATA,onReadData)				//设备发生告警
	
	ON_MESSAGE(WM_GSMMSG,onSendSMSInfo)					//发送收机短信

	ON_MESSAGE(MM_WOM_OPEN,onSoundOpen)					//开始播放声音
	ON_MESSAGE(MM_WOM_DONE,onSoundDone)					//播放声音中
	ON_MESSAGE(MM_WOM_CLOSE,onSoundClose)				//播放声音结束
	ON_MESSAGE(WM_VOICE, GsmVoice)						//GSM播放声音
	ON_MESSAGE(WM_VOICE_CLOSE, GsmVoiceClose)			//GSM声音关闭

	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_COMMAND(ID_CM_START, OnCmStart)
	ON_COMMAND(ID_CM_STOP, OnCmStop)
	ON_COMMAND(ID_APP_EXIT, OnAppExit)

//}}AFX_MSG_MAP

//ON_BN_CLICKED(IDOK, OnBnClickedOk)
//ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
//ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel)
ON_COMMAND(ID_CM_SOUND, OnCmSound)
END_MESSAGE_MAP()


// CMonitor 消息处理程序



// 起动系统监测功能


BOOL CMonitor::StartMonitoring(void)
{
	CString strCom;
	BOOL blRet;

	HANDLE hThreadID = 0;

	DWORD dwCommEvents =0;
	dwCommEvents  |= EV_BREAK;
	dwCommEvents  |= EV_CTS;
	dwCommEvents  |= EV_DSR;
	dwCommEvents  |= EV_ERR;
	dwCommEvents  |= EV_RING;
	dwCommEvents  |= EV_RLSD;
	dwCommEvents  |= EV_RXCHAR;
	dwCommEvents  |= EV_RXFLAG;
	dwCommEvents  |= EV_TXEMPTY;

	//起动WEB端口监测服务
	m_udpServer[0] = new CSocketComm();
	m_udpServer[0]->SetMessageWindow(this);
	m_udpServer[0]->StartMonitoring(theApp.m_Baseinfo.ServerPort);
	
	//起动监测设备端口监测服务
	m_udpServer[1] = new CSocketComm();
	m_udpServer[1]->SetMessageWindow(this);
	m_udpServer[1]->StartMonitoring(theApp.m_Baseinfo.DevicePort);
	
	CSerialPort *sport;
	GetComPort();				//取得现有设备的通信端口
	for(int i=0;i<m_comArray.GetCount();i++)
	{
		strCom = m_comArray.GetAt(i);
		strCom.Replace("COM","");
		sport = new CSerialPort;
		blRet = sport->InitPort(this,atoi(strCom.GetBuffer()),9600,'N',8,1,dwCommEvents,512);		
		if (blRet == TRUE)
		{
			blRet = sport->StartMonitoring();
			m_comPort.Add(sport);
			TRACE("串口监测开始...");
		}else
		{
			TRACE("串口起动监测失败...");
			delete sport;
			blRet = FALSE;
		}
	}
	return blRet;
}

// 停止系统监测功能
BOOL CMonitor::StopMonitoring(void)
{
	BOOL bResul = FALSE;
	//停止UDP通信

	//停止轮循线程
	SetEvent(m_hEventArray[0]);
	Sleep(500);
	DWORD dwStart,dwEnd;
	dwEnd = dwStart = GetTickCount();
	while (m_AskingStatus && (dwEnd - dwStart < 10000))
	{
		dwEnd = GetTickCount();
		Sleep(100);
	}


	bResul = this->m_udpServer[0]->StopMonitoring();
	//bResul = this->m_udpServer[0]->ClosePort();
	//if (bResul)
	//	TRACE0("停止WEB端监测服务成功...");

	bResul = this->m_udpServer[1]->StopMonitoring();
	//bResul = this->m_udpServer[1]->ClosePort();
	//if (bResul)
	//	TRACE0("停止设备端UDP监测服务成功...");
	

	//停止串口通信线程
	if (!m_AskingStatus)
	{
		CSerialPort *m_port;
		for(int i=0;i<m_comPort.GetCount();i++)
		{
			m_port = (CSerialPort *) m_comPort.GetAt(i);
			bResul = m_port->CloseMonitoring();
			bResul = m_port->ClosePort();
			if (bResul)
			{
				delete m_port;
				bResul = TRUE;
			}
			else
			{
				bResul = FALSE;
			}
		}
		m_comPort.RemoveAll();

	}else
		bResul = FALSE;

	//m_udpServer[1]->ClosePort();
	//m_udpServer[0]->ClosePort();
	

	return bResul;
}

// 重新起动监测功能
int CMonitor::Restart(void)
{
	return 0;
}

// 关闭监测功能
BOOL CMonitor::Close(void)
{
	//m_udpServer[0]->StopMonitoring();
	//m_udpServer[1]->StopMonitoring();
	StopMonitoring();

	PostQuitMessage(0);
	return TRUE;

}


// Socket接收消息
LRESULT CMonitor::onSockReadString(WPARAM wParam, LPARAM lParam)
{
	CString sBuf;
	//CInfoFrame frame;
	sMsgBody  *msgBody;
	CInfoFrame *frame;
	frame = new CInfoFrame;
	
	//填充包结构
	msgBody = (sMsgBody *)wParam;
	sBuf = CString(msgBody->lpBuf,msgBody->iLen);
	memcpy(frame->ucBuf,msgBody->lpBuf,msgBody->iLen);
	frame->ucBuf[msgBody->iLen] = '\0';
	frame->address = msgBody->sIP;
	frame->addrType = COMM_UDP;
	frame->iPort = msgBody->iPort;
	frame->nRLen = msgBody->iLen;
	frame->time = CTime::GetCurrentTime();
	frame->unState = 0;

	if ((int)lParam == theApp.m_Baseinfo.DevicePort)
	{
		DataAnalyse(*frame);
	}else 	//WEB数据分析
	{
		WebDataAnalyse(*frame);									//处理方法
	}
	
	delete frame;
	return LRESULT();
}

LRESULT CMonitor::onCom_RXChar(WPARAM wParam, LPARAM lParam)
{
	CString sBuf,strTemp,strPort;
	char *cRet;
	sMsgBody *msgBody;
	CInfoFrame *frame;
	int iPort,iLen;
	msgBody = (sMsgBody *)wParam;

	cRet = new char[msgBody->iLen + 1];
	iLen = msgBody->iLen;
	memcpy(cRet,msgBody->lpBuf ,iLen);
	cRet[iLen] = '\0';
	iPort = (int)lParam;
	int  pStart,pEnd;
	pStart = pEnd = 0;

	sBuf = strReceive;
	
	//TRACE0(cRet);
	//CMutex mutex;
	sBuf += cRet;
	pStart = sBuf.Find(0x7e);
	sBuf = sBuf.Mid(pStart);
	strTemp = sBuf;
	pEnd = strTemp.Find(0xd) ;
	strReceive = sBuf.Mid(pEnd + 1);
	
	if (pEnd > 1 )
	{
		strTemp = strTemp.Left(pEnd);

		TRACE0(strTemp +'\n');
		
		//记录日志文件
		/****************************************************************/
		//theApp.WriteTxtLog(strTemp);
		/****************************************************************/

		//填充包结构
		frame = new CInfoFrame;
		frame->address.Format("COM%d",iPort);				//记录通信的原地址
		frame->addrType = COMM_COM;							//通信方式
		frame->iPort = iPort;
		frame->nRLen = strTemp.GetLength();
		memcpy(frame->ucBuf,strTemp.GetBuffer(),frame->nRLen );
		frame->time = CTime::GetCurrentTime();
		frame->unState = 0;
		frame->ucBuf[strTemp.GetLength()] = '\0';

		//取得最后一次送出的命令字
		DataAnalyse(*frame);
		delete frame;
	}
	return LRESULT();
}


// 取得监测串口号
int CMonitor::GetComPort(void)
{
	CString sSql,sTip,strField ;
	_RecordsetPtr pRst;
	_variant_t vt,vtTmp;
	m_comArray.RemoveAll();
	//选择通讯方式为RS232的设备都用了那些串口
	sSql = "SELECT DISTINCT SVMAddrSource FROM dbo.CMTSVModule  where (SVMAddrSource Like 'COM%') AND (SVMComModel = 1) ";
	pRst.CreateInstance(__uuidof(Recordset));
	p_adodb->ReadDB(sSql,pRst,sTip);
	while(!pRst->adoEOF)
	{
		vtTmp = pRst->GetCollect(_bstr_t("SVMAddrSource"));
		if (vtTmp.vt != VT_NULL)
		{
			strField = (LPCTSTR)_bstr_t(vtTmp);
			m_comArray.Add(strField);
		}
		pRst->MoveNext();
	}
	pRst->Close();
	pRst.Release();

	return 0;
}


// 数据分析处理
int CMonitor::DataAnalyse(CInfoFrame frame)
{
	CString strError, strEQName, strTip, strTemp;
	CString strTime, strType, strNote, strData ,strMemo ; //数据库各字段
	CString strAddr ;

	sUnit m_unit;
	UCHAR ucRecvBuf[MAX_SIZE] ;
	//int nRecvLen ;
	frame.ucBuf[frame.nRLen] = '\0';
	try
	{
		//存储原始数据包
		if (theApp.m_Baseinfo.SaveLog == 1)
			p_adodb->WriteCommRd(frame);

		//数据包展开
		if (m_protocol->Explain(frame) == 0)		//分析数据告警内容
		{
			

			for(int i=0;i<m_UnitArray.GetCount();i++)
			{
				m_unit = m_UnitArray.GetAt(i);
				//取得最近一次发送命令及发送数量,检查是否已经多次发送而没有回复。以此来确定是否在线
				if (atoi(m_unit.strIDAddr.GetBuffer()) == frame.InPack.ADR && m_unit.sIP == frame.address)
				{
					frame.iCmd = m_unit.iCmd;
					m_unit.iSendCount = 0;
					m_unit.iReceive++ ;
					m_unit.tmReceive = CTime::GetCurrentTime();
					break;
				}
			}
			
			//告警分析
			
			switch(frame.InPack.CID1 )
			{
			case 0x81:	//MDF智能告警器
					CEquipmentPort *m_PortState;
					m_PortState = new CEquipmentPort;
					m_PortState->AlarmState = PORT_NORMAL;
					m_pAnalyse->AnalyseAlarm(frame,*m_PortState);
					//delete m_PortState; 
				break;	
			case 0x82:	//电缆检测单元
				//frame
				CPtcCable *m_pCable;
				m_pCable = new CPtcCable();
				m_pCable->DataAnalyse(frame);   
				
				break;
			case 0x83:	//强电入侵监测模块
				break;
			case 0x2C:	//交流电源分配柜
				break;	
			case 0x25:	//直流电源分配柜
				CPtcPowerDC *m_pPowerDC;
				m_pPowerDC = new CPtcPowerDC();
				m_pPowerDC->DataAnalyse(frame);   
				break;
			case 0x2d:	//交流电源分配箱
				break;	
			case 0x2e:	//直流电源分配箱
				break;
			case 0x8a:	//环境检测模块
				break;
			
			}


			return 0;
			
		}else		//数据包错误,写日志
		{
			strError.Format("数据包错误,详细内容:%s",frame.ucBuf);
			theApp.WriteTxtLog(strError);
			return -1;
		}
		
	}catch(_com_error e)
	{
		//数据分析错误,丢弃数据包
		strTip.Format("%s",frame.ucBuf);
		theApp.WriteTxtLog("数据包分析错误,丢弃数据包:" + strTip);
		return -1;
	}
	
	
}

int CMonitor::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	//if (CWnd::OnCreate(lpCreateStruct) == -1)
	
	return 0;
}

// 命令发送器
UINT CMonitor::SendThd(LPVOID lpWnd)
{
	CMonitor* pMonitor = (CMonitor*)lpWnd;
	sUnit m_unit;
	CString strTemp;
	DWORD event  = 0;	
	int iPort;
	CMutex mutex;
	//取得命令列表
	pMonitor->m_UnitArray.Copy(pMonitor->m_pEQPool->m_UnitArray);
	pMonitor->m_protocol->Build(pMonitor->m_UnitArray,0x44);

	for(;;)			//开始循环发送
	{
		
		event = WaitForMultipleObjects(3, pMonitor->m_hEventArray, FALSE, INFINITE);
		switch (event)
		{
		case 0:
			pMonitor->m_AskingStatus = FALSE;
			AfxEndThread(0);
			break;
		case 1:			//重置
			
			break;
		case 2:			//发送数据取得命令队列中的数据
			//取得设备列表

			//开始循环发送资料
			for(int i =0;i< pMonitor->m_UnitArray.GetCount() ; i++)
			{
				
				m_unit = pMonitor->m_UnitArray.GetAt(i);
				
				/************************************************************************
				//检查设备是否在线
				************************************************************************/
				if ((m_unit.iSendCount >= 3) && (m_unit.iReceive == 0) && (m_unit.tmSend == 1))
				{
					//认为设备不在线,发送状态消息 在线-->不在线
					//::SendMessage(pMonitor->m_hWnd,WM_STATUS_CHANGE,(WPARAM)&m_unit,0);
					
				}else if(m_unit.iReceive > 0 && m_unit.tmSend == 0)
				{
					//设备在线 不在线转-->在线
					//::SendMessage(pMonitor->m_hWnd,WM_STATUS_CHANGE,(WPARAM)&m_unit,1);
				}

				/************************************************************************/

				switch(m_unit.nModel)
				{
				case 2:
				case 0:
					pMonitor->m_udpServer[1]->SendTo(m_unit.strSend,m_unit.sIP ,theApp.m_Baseinfo.DevicePort);
					
					break;
				case 1:
					strTemp = m_unit.sIP;
					strTemp.Replace("COM","");
					iPort = atoi(strTemp.GetBuffer() );
					if (pMonitor->m_comPort.GetCount() >0 )
					{
						pMonitor->SendInfoToCom(iPort,m_unit.strSend);
						mutex.Lock();
						m_unit.tmSend = CTime::GetCurrentTime();
						m_unit.iSendCount++;
						m_unit.iReceive++;
						
						//检查是否在线
						mutex.Unlock();
					}
					break;
				}
				//相同串口间的间隔询问
				
				Sleep(500);
		
			}
			break;
		}

		//设置扫描间隔时间
		Sleep(theApp.m_Baseinfo.Interval);
		//Sleep(1000);
		
	}

	return 0;
}

// 送出信息到串口
int CMonitor::SendInfoToCom(int iPort, CString strBuf)
{
	BYTE *chArray; 
	int iLen;
	CSerialPort *sport;
	iLen = strBuf.GetLength();
	chArray = new BYTE[iLen];
	memset(chArray,0,iLen);
	chArray = (BYTE *)strBuf.GetBuffer();
	for(int i = 0; i< m_comPort.GetCount(); i++)
	{
		sport = (CSerialPort *)m_comPort.GetAt(i);
		if (iPort == sport->m_port)
		{
			sport->WriteToPort(chArray,iLen);
			break;
		}
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -