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

📄 devbas.cpp

📁 国家环保总局污染源在线通讯协议的简化版
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// DevBas.cpp: implementation of the CDevBas class.
///	无属性页设备驱动模版
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DevDef.h"
#include "DevBas.h"
#include "mcgsrun.h"
#include "mcgsset.h"
#include "DevServer.h"
#include "math.h"

extern IMcgsset g_mcgsset;
extern IDataCentre g_datacentre;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDevBas::CDevBas()
{

}

CDevBas::~CDevBas()
{

}

///	函数功能:	初始化DEV_DATA结构
///	函数返回:	无
///	参数意义:	data MCGS传过来的MCGS_DATA结构的指针
///	备	  注:	
void CDevBas::mfCheckDevDataInit(MCGS_DATA& data)
{
	if (NULL != data.m_pDevData)
	{
	}
	else
	{
		data.m_pDevData = new DEV_DATA;	
		((DEV_DATA*)data.m_pDevData)->nArProperty.SetSize(DEV_DWORD_PROPERTYNUM);
		if (data.m_pArchive->SvrGetRealBufferSize() > 0)
		{
			data.m_pArchive->SvrSeekToBegin();
			for (int i = 0; i < DEV_DWORD_PROPERTYNUM; i ++)
			{
				*data.m_pArchive>>((DEV_DATA*)data.m_pDevData)->nArProperty[i];				
			}
		}
		else
		{			
			for (int i = 0; i < DEV_DWORD_PROPERTYNUM; i ++)
			{
				((DEV_DATA*)data.m_pDevData)->nArProperty[i] = DEV_DWORD_PROPERTYINITVALUE[i];
			}
			data.m_pArchive->SvrSeekToBegin();
			for (i = 0; i < DEV_DWORD_PROPERTYNUM; i ++)
			{
				*data.m_pArchive<<((DEV_DATA*)data.m_pDevData)->nArProperty[i];				
			}
		}

		((DEV_DATA*)data.m_pDevData)->strPW = DEV_STR_PW;
		((DEV_DATA*)data.m_pDevData)->nRtdInterval = DEV_LONG_RTDINTERVAL;
		((DEV_DATA*)data.m_pDevData)->strPW = DEV_STR_PW;
		((DEV_DATA*)data.m_pDevData)->strMN = _T("MN=20112630451001");
		((DEV_DATA*)data.m_pDevData)->bLog = false;
		((DEV_DATA*)data.m_pDevData)->dwLogN = 0;
		((DEV_DATA*)data.m_pDevData)->dwTime = 0;
		((DEV_DATA*)data.m_pDevData)->strError = _T("");
		((DEV_DATA*)data.m_pDevData)->bError = false;
		((DEV_DATA*)data.m_pDevData)->dwErrorTime = 0;

	}
}

///	函数功能:	保存DEV_DATA结构的数据
///	函数返回:	无
///	参数意义:	data MCGS传过来的MCGS_DATA结构的指针
///	备	  注:	
void CDevBas::mfSaveDevData(MCGS_DATA& data)
{
	data.m_pArchive->SvrSeekToBegin();
	for (int i = 0; i < DEV_DWORD_PROPERTYNUM; i ++)
	{
		*data.m_pArchive<<((DEV_DATA*)data.m_pDevData)->nArProperty[i];				
	}
}

///	函数功能:	校验收发协议是否正确。
///	函数返回:	TRUE,正确。FALSE,错误。
///	参数意义:	iCheckDir 校验方向:0,发送校验。1:接收校验。
///				strProtocol 要校验的字符串。
///	备	  注:	
///	
BOOL CDevBas::mfAddSum( CString& strProtocol, int nCheckDir)
{

	unsigned char ucSum = 0, ucTemp = 0;
	CByteArray bytArProtocol;
	CDevServer::SvrStr2Byte(strProtocol, bytArProtocol);
	int nCheckLen = bytArProtocol.GetSize();
	if (nCheckDir == 1)
	{		
		nCheckLen -= 6;
	}
	
	WORD wCrcData = 0;
	
	for(int i = 6; i < nCheckLen; i ++)
	{
		ucSum = (wCrcData >> 12)&0XFF;
		wCrcData <<= 4;
		ucTemp = bytArProtocol.GetAt(i);
		wCrcData ^= DEV_DWORD_CRCHALFTABLE[ucSum^(ucTemp>>4)];
		ucSum = (wCrcData >> 12)&0XFF;
		wCrcData <<= 4;
		wCrcData ^= DEV_DWORD_CRCHALFTABLE[ucSum^(ucTemp&0X0F)];
	}
	
	CString str = _T("");
	str.Format(_T("%.2X%.2X"), wCrcData>>8&0xFF, wCrcData&0xFF);
	str += CString(TCHAR(0X0D)) + CString(TCHAR(0X0A));

	switch (nCheckDir)
	{
	case 0:
		// 发数据时校验
		{			
			strProtocol += str;
		}
		break;
	case 1:
		// 收数据时校验
		{
			if(str.CompareNoCase(strProtocol.Right(6)) != 0)	
			{
				strProtocol = _T("");
				return FALSE;
			}
		}
		break;
	default:
		{
			ASSERT(FALSE);
		}break;
	}
	return TRUE;
}

///	函数功能:	获取各个通道的名字和类型
///	函数返回:	TRUE,固定
///	参数意义:	data MCGS传过来的MCGS_DATA结构的指针
///				strChannelName 设备通道的名称的数组		
///				strPropertyValue 设备通道的数据类型的数组
///	备	  注:
BOOL CDevBas::mfCreateChanel(MCGS_DATA& data, CStringArray& strChannelName, INTARRAY& tyChannelType)
{
	DWORD dwModuleNum = ((DEV_DATA*)data.m_pDevData)->nArProperty[DEV_PRO_NUM];
	int nChlNum = DEV_DWORD_FIXCHLNUM + dwModuleNum*2;
	strChannelName.SetSize(nChlNum + 1);
	tyChannelType.SetSize(nChlNum + 1);

	
	for (DWORD i = 0; i < DEV_DWORD_FIXCHLNUM; i ++)
	{
		strChannelName[i+1] = DEV_STR_FIXCHLNAME[i];
		tyChannelType[i+1] = DEV_LONG_FIXCHLTYPE[i];
	}

	nChlNum = DEV_DWORD_FIXCHLNUM;
	for (i = 0; i < dwModuleNum; i ++ ) {
		strChannelName[i*2+nChlNum+1].Format(DEV_STR_TESTCHLNAMEFORMAT[0], i);
		tyChannelType[i*2+nChlNum+1] = DEV_LONG_TESTCHLTYPE[0];
		strChannelName[i*2+nChlNum+2].Format(DEV_STR_TESTCHLNAMEFORMAT[1], i);
		tyChannelType[i*2+nChlNum+2] = DEV_LONG_TESTCHLTYPE[1];
	}

	return TRUE;
}

///	函数功能:	DevBas中的主采集函数,用于采集数据,对设备的通道进行分块,并调用块读函数。
///	函数返回:	TRUE,正确。FALSE,错误。
///	参数意义:	data MCGS传过来的MCGS_DATA结构的指针。
///				collectFlag 用于标志设备通道是否需要操作的数组。		
///				valueArray 用于返回设备通道的数值型数据的数组。			
///				strValueArray 用于返回设备通道的字符串型数据的数组。
///	备	  注:	一般来说此函数可以不用修改,可用于任何设备。
///				
BOOL CDevBas::mfCollectDevData(MCGS_DATA& data, CArray<int,int>& collectFlag, 
							   CArray<double,double>& valueArray, CStringArray& strValueArray)
{	
 	DEV_DATA* pDevData = (DEV_DATA*)data.m_pDevData;
	if (pDevData->strMN.GetLength() < DEV_LONG_MNLENGTH) {
		valueArray[0] = -1;
		return TRUE;
	}

	int nReturn = 0;
	CString	strProtocol, strTemp, strQN, strTime;

	if ((pDevData->bError) && (pDevData->nTimes < 10)) {//上次发送失败
		strProtocol = pDevData->strError;
		int nReturn = mfWriteAndRead(data, strProtocol, strQN, 3);
		if (nReturn < 0) {
			pDevData->nTimes += 1;
			return nReturn;
		}
		
		pDevData->bError = false;
		pDevData->dwTime = pDevData->dwErrorTime;
		pDevData->dwErrorTime = 0;
		pDevData->strError = _T("");
		pDevData->nTimes = 0;
	}
	else if(pDevData->bError){
		pDevData->bError = false;
		pDevData->dwTime = pDevData->dwErrorTime;
		pDevData->dwErrorTime = 0;
		pDevData->strError = _T("");
		pDevData->nTimes = 0;
	}

///	((DEV_DATA*)data.m_pDevData)->strData = _T("##0122QN=20080709110935001;ST=32;CN=3014;PW=123456;MN=20040885713203;Flag=1;CP=&&PolID=011,CTime=04,CTime=10,CTime=14,CTime=16&&ab4f");
///	((DEV_DATA*)data.m_pDevData)->strData += CString(TCHAR(0X0D)) + CString(TCHAR(0X0A));

	///是否上传实时数据
//	if (GetTickCount() - pDevData->dwTime >= pDevData->nRtdInterval*1000) {
	if (CDevServer::mfTimeOut(pDevData->dwTime, pDevData->nRtdInterval*1000)) {
		mfGetSysTime(strTime, strValueArray);
		///QN
		strQN = _T("QN=") + strTime;
		strProtocol = strQN + _T(";") + pDevData->strST + _T(";CN=2011;") 
			+ pDevData->strPW + _T(";") + pDevData->strMN
			 + _T(";CP=&&DataTime=");
		///时间
		strProtocol += strTime.Left(strTime.GetLength()-3);
		///测量数据代码、Rtd、Flag;
		int nModuleNum = pDevData->nArProperty[DEV_PRO_NUM];
		for (int i = 0; i < nModuleNum; i ++) {
			///测量因子
			strProtocol += _T(";") + strValueArray[i*2+DEV_DWORD_FIXCHLNUM+1] + _T("-Rtd=");
			///测量值
			strTemp.Format(_T("%.2f"), valueArray[i*2+DEV_DWORD_FIXCHLNUM+2]);
			strProtocol += strTemp;			
		}

		strProtocol += _T("&&");
		///加包头
		mfAddHead(strProtocol);
		pDevData->dwErrorTime = GetTickCount();
		pDevData->strError = strProtocol;

		int nReturn = mfWriteAndRead(data, strProtocol, strQN, 3);

		if (nReturn < 0) {
			pDevData->bError = true;
			pDevData->nTimes = 0;
			return nReturn;
		}

		pDevData->dwTime = GetTickCount();
	}

	return TRUE;
}

///	函数功能:	形成读命令。
///	函数返回:	欲读取的长度。
///	参数意义:	data MCGS传过来的MCGS_DATA结构的指针。
///				strProtocol 用于保存命令的字符串。
///	备	  注:	
///	
DWORD CDevBas::mfFormReadOrder(MCGS_DATA& data, CString& strProtocol, int nStart, int nChanelNum)
{
	
	return 100;
}

///	函数功能:	对从串口中读回来的数据进行解码,最后的值存入asngValue中返回。
///	函数返回:	TRUE,正确。FALSE,错误。
///	参数意义:	collectFlag 用于标志设备通道是否需要操作的数组。		
///				valueArray 用于返回设备通道的数值型数据的数组。	
///				data MCGS传过来的MCGS_DATA结构的指针。
///				strProtocol 用于保存命令的字符串。
///	备	  注:	
///	
void CDevBas::mfExplainCommBtyeData(CArray<int,int>& collectFlag, CArray<double,double>& valueArray, 
						   MCGS_DATA& data, const CString& strProtocol, int nStart, int nChanelNum)
{
	
}

///	函数功能:	形成写命令。
///	函数返回:	TRUE,固定。
///	参数意义:	strProtocol 用于保存命令的字符串。
///				data MCGS传过来的MCGS_DATA结构的指针。
///				nIndex 通道序号。
///				nStart 通道值。
///	备	  注:	
///	
BOOL CDevBas::mfFormWriteOrder(CString& strProtocol, MCGS_DATA& data, int nIndex, double dData)
{
	
	return TRUE;	
}

///	函数功能:	DevBas中的命令功能函数实现,所有的命令操作都在这里进行
///	函数返回:	0,正确。2,设备命令无效。
///	参数意义:	data			MCGS传过来的MCGS_DATA结构的指针
///				strCmd			MCGS传过来的命令字符串
///				valueArray		用于返回设备通道的数值型数据的数组			
///				strValueArray	用于返回设备通道的字符串型数据的数组
///	备	  注:	
BOOL CDevBas::mfDevIOCtrl(MCGS_DATA& data, CString& strCmd, 
					  CArray<double,double>& valueArray, CStringArray& strValueArray)
{
	///	解释命令
	int nPos1 = strCmd.Find(_T("("));
	int nPos2 = strCmd.Find(_T(")"));
    if (nPos1 < 0 || nPos2 < 0)
	{
		return FALSE;
	}

	///	把设备命令字符串分解成所需的三个部分
	CString strOrder = strCmd.Left(nPos1);
	CString strMyCmd = strCmd.Mid(nPos1 + 1, nPos2 - nPos1 - 1);
	strOrder.TrimLeft();
	strOrder.TrimRight();
	strOrder.MakeUpper();

	///	写DEV通道	
	if (strOrder.CompareNoCase(DEV_STR_MCGSWRITE) == 0)
	{				
		return mfDevIOWriteChannel(data, strMyCmd);			
	}

	///	READ 命令
	if (strOrder.CompareNoCase(DEV_STR_READ) == 0)
	{
		return mfDevIOReadOrder(data, strMyCmd);				
	}

	///执行SETINI命令
	if (strOrder.CompareNoCase(DEV_STR_SETINI) == 0)
	{		
		return mfDevIOSetiniOrder(data, strMyCmd);
	}

	///隐含命令,开启和关闭日志功能
	if(strOrder.CompareNoCase(DEV_STR_GETHIDDENPRO) == 0)
	{
		mfGetHidePro(data, strMyCmd);
	}
	if(strOrder.CompareNoCase(DEV_STR_SETHIDDENPRO) == 0)
	{
		mfSetHidePro(data, strMyCmd);
	}

	return FALSE;
}

///	函数功能:	此函数写通道功能。
///	函数返回:	TRUE,正确。FALSE,错误。
///	参数意义:	data			MCGS传过来的MCGS_DATA结构的指针。
///				strCmd			设备命令字符串中去掉命令符后剩下的字符串。
///	备	  注:	一般来说,如果有通讯状态标志位,此函数可以不用修改,可用于任何设备。
///				
BOOL CDevBas::mfDevIOWriteChannel(MCGS_DATA& data, CString& strCmd)
{
	/*
	CString strChannel = _T(""), strData = _T(""), strDivision = _T("=");	
	if (!CDevServer::SvrGetCmdStr(strCmd, strDivision, strChannel, strData))
	{
		return FALSE;
	}	
	int nIndex = (int)CDevServer::SvrStr2Double(strChannel, 0, 0, 0);
	double dData = CDevServer::SvrStr2Double(strData, 4, 0, 0);	

	int nIsCheckout = ((DEV_DATA*)data.m_pDevData)->nArProperty[0];
	
	// 形成块读命令的字符串,在字节数组 strProtocol()中返回
	CString strProtocol = _T("");
	mfFormWriteOrder(strProtocol, data, nIndex, dData);

	// 组成协议并校验
	mfAddSum(strProtocol, 0, nIsCheckout); 
	
	if (CDevServer::SvrWriteAndReadComm(data, 0, strProtocol, 300, 0, 255, char(13)) == 0)
	{
		return FALSE;
	}
	// 校验
	if (!mfAddSum(strProtocol, 1, nIsCheckout))

⌨️ 快捷键说明

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