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