📄 monitor.cpp
字号:
// 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 + -