#include "stdafx.h" #include "rtuprocess.h" #include "Global.h" #include "struct.h" #include "NoticeQueue.h" DWORD g_dwIcpdasVariantTick = 0; HANDLE g_ICPDASRequestThread = NULL; HANDLE g_ICPDASResponseThread = NULL; DWORD g_dwICPDASVariantTick = 0; CRITICAL_SECTION g_csIcpdasReadOneData; //icpdas动态库输出函数 HINSTANCE g_hICPDASLibModule = NULL; ICPDAS_DLLInitCom pICPDAS_DLLInitCom = NULL; ICPDAS_DLLInit pICPDAS_DLLInit = NULL; ICPDAS_DLLUnInit pICPDAS_DLLUnInit = NULL; ICPDAS_DLLRequestStatusData pICPDAS_DLLRequestStatusData = NULL; ICPDAS_DLLWrCom pICPDAS_DLLWrCom = NULL; int IcpdasResponseValue(); int IcpdasCommandSend(); void UnInitIcpdasDll(); int IcpdasSingleResponseData(char chDevUid[20], int iVarID, char chMsg[80]); int GetIcpdasFromIni(char chCmd[32], BYTE *Start, BYTE* byWithAddrFlag, BYTE *pFuncCode); BOOL LoadIcpdasDll(CString strpath) { char strFile[256] = {0}; g_hICPDASLibModule = NULL; sprintf(strFile, "%s\\dll\\icpdas.dll", strpath); g_hICPDASLibModule = AfxLoadLibrary(strFile); InitializeCriticalSection( &g_csIcpdasReadOneData ); //RTU 动态库初始化 if (NULL != g_hICPDASLibModule) { pICPDAS_DLLInitCom =( ICPDAS_DLLInitCom)::GetProcAddress(g_hICPDASLibModule, "ICPDAS_DLLInitCom"); pICPDAS_DLLInit = (ICPDAS_DLLInit)::GetProcAddress(g_hICPDASLibModule, "ICPDAS_DLLInit"); pICPDAS_DLLUnInit = (ICPDAS_DLLUnInit)::GetProcAddress(g_hICPDASLibModule, "ICPDAS_DLLUnInit"); pICPDAS_DLLRequestStatusData = (ICPDAS_DLLRequestStatusData)::GetProcAddress(g_hICPDASLibModule, "ICPDAS_DLLRequestStatusData"); pICPDAS_DLLWrCom = (ICPDAS_DLLWrCom)::GetProcAddress(g_hICPDASLibModule, "ICPDAS_DLLWrCom"); return TRUE; } else { return FALSE; } } BOOL InitIcpdasComm(int iAddr, int iPort, int iBaudrate, int iDataBit, int iStopBit, int iParity, int iIntervals) { if (pICPDAS_DLLInitCom(iAddr,iPort, iBaudrate, iDataBit, iStopBit, iParity, iIntervals))//初始化串口 { return TRUE; } else { return FALSE; } } int IcpdasRequestData( int nIndex, SETBASEPARAM SetBasePara, int nDataLen, int nPort, int nDevAddr, char chDevUid[20], int iVarID, char chRs232cmd[32]) { char chMsg[80] = {0}; BYTE Start= 0x0;//起始位 BYTE StartAddr[MAX_ID] = {0}; BYTE FuncCode[MAX_ID] = {0}; BYTE byWithAddrFlag; int nDeviceIndex = -1, nVarIndex = -1; BOOL bFind = FindVar(chDevUid, iVarID, nDeviceIndex, nVarIndex); if( bFind == FALSE ) return -1; CDevice *pDev = g_pDevicesManager->m_Devices[nDeviceIndex]; CBaseVar *pBaseVar = pDev->m_Vars[nVarIndex]; char szMsg[80] = {0}; sprintf((char*)StartAddr, "%02d", SetBasePara.nStartAddr); GetIcpdasFromIni(chRs232cmd, &Start, &byWithAddrFlag,FuncCode); CString strIndex; if( 0 == stricmp((char *)FuncCode, "#AAN") ) { strIndex.Format("%d", atoi(pBaseVar->m_strRs232Index)); strcpy((char *)FuncCode, (char *)(LPCTSTR)strIndex); //LOG4C((LOG_NOTICE, "strIndex=%s, FuncCode=%s", strIndex, FuncCode)); } if( nIndex == 0 ) { if( pICPDAS_DLLInit(nPort, nDevAddr, Start, StartAddr, SetBasePara.nRegNum, FuncCode, nDataLen, byWithAddrFlag, szMsg)!=0) { return -1; } } else if( strlen(szMsg) == 0 ) { if( pICPDAS_DLLInit(nPort, nDevAddr, Start, StartAddr, SetBasePara.nRegNum, FuncCode, nDataLen, byWithAddrFlag, szMsg)!=0) { return -1; } } return IcpdasSingleResponseData(chDevUid, iVarID, szMsg); } int IcpdasSingleResponseData(char chDevUid[20], int iVarID, char chMsg[80]) { int nDeviceIndex = -1, nVarIndex = -1; BOOL bFind = FindVar(chDevUid, iVarID, nDeviceIndex, nVarIndex); if( bFind == FALSE ) return -1; CDevice *pDev = g_pDevicesManager->m_Devices[nDeviceIndex]; CBaseVar *pBaseVar = pDev->m_Vars[nVarIndex]; EnterCriticalSection(&g_csIcpdasReadOneData); pDev->m_dwOnlineTick = GetTickCount(); LeaveCriticalSection(&g_csIcpdasReadOneData); DWORD nValue = 0; WORD wdValue = 0; double fCoef = pBaseVar->m_dbCoefficient; int nDataLen = pBaseVar->m_iDataLen/2; int nVarItemID = pBaseVar->m_nVarItemID; if( nVarItemID > 0 )//BIT位变量 { int nStartBit = pBaseVar->m_nStartBit; int nEndBit = pBaseVar->m_nEndBit; int nStartReg, nEndReg; if( nEndBit - nStartBit < 7 ) // 一般告警状态会这样子定义,Modbus Ascii码暂时没有碰到,没有经过调试,待测试 { if( nDataLen == 1 ) { char chBuffer[8] = {0}; memset(chBuffer, 0, sizeof(chBuffer)); BYTE byValue = (AsciiToBYTE(chMsg[0]) << 4) | ( AsciiToBYTE(chMsg[0 + 1]) & 0x00FF ); DigitToBinary(byValue, chBuffer, 8) ; CString strTemp; switch( nEndBit - nStartBit ) { case 0: strTemp.Format("%c", chBuffer[nStartBit]); break; case 1: strTemp.Format("%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1]); break; case 2: strTemp.Format("%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2]); break; case 3: strTemp.Format("%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit +3]); break; case 4: strTemp.Format("%c%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit + 3], chBuffer[nStartBit + 4]); break; case 5: strTemp.Format("%c%c%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit + 3], chBuffer[nStartBit + 4], chBuffer[nStartBit + 5]); break; case 6: strTemp.Format("%c%c%c%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit + 3], chBuffer[nStartBit + 4], chBuffer[nStartBit + 5], chBuffer[nStartBit + 6]); break; } nValue = atoi(strTemp); //strTemp.Format("%d", } else if( nDataLen == 2 ) { char chBuffer[16] = {0}; //chMsg[0] = 0x00; //chMsg[2] = 0x00; //chMsg[2] = 0x0E; //chMsg[3] = 0x0F; WORD wValue = ( ( (AsciiToBYTE(chMsg[0]) << 4) | ( AsciiToBYTE(chMsg[1]) & 0x00FF ) ) << 8 ) | ( ( (AsciiToBYTE(chMsg[2]) << 4) | ( AsciiToBYTE(chMsg[3]) & 0x00FF ) ) & 0x0000FFFF ); DigitToBinary(wValue, chBuffer, 16) ; CString strTemp; switch( nEndBit - nStartBit ) { case 0: strTemp.Format("%c", chBuffer[nStartBit]); break; case 1: strTemp.Format("%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1]); break; case 2: strTemp.Format("%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2]); break; case 3: strTemp.Format("%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit +3]); break; case 4: strTemp.Format("%c%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit + 3], chBuffer[nStartBit + 4]); break; case 5: strTemp.Format("%c%c%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit + 3], chBuffer[nStartBit + 4], chBuffer[nStartBit + 5]); break; case 6: strTemp.Format("%c%c%c%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit + 3], chBuffer[nStartBit + 4], chBuffer[nStartBit + 5], chBuffer[nStartBit + 6]); break; } nValue = atoi(strTemp); } } // 特殊变量处理(例如,一个命令返回两个变量的情况) else if( nEndBit - nStartBit == 7 ) // 1个字节的情况 { nStartReg = (int)nStartBit / 8; nEndReg = (int)(nEndBit + 1) / 8; nValue = (AsciiToBYTE(chMsg[nStartReg]) << 4) | ( AsciiToBYTE(chMsg[nStartReg + 1]) & 0x00FF ); } else if( nEndBit - nStartBit == 15 ) // 2个字节的情况 { nStartReg = (int)nStartBit / 8; nEndReg = (int)(nEndBit + 1) / 8; nValue = ( ( (AsciiToBYTE(chMsg[nStartReg]) << 4) | ( AsciiToBYTE(chMsg[nStartReg + 1]) & 0x00FF ) ) << 8 ) | ( ( (AsciiToBYTE(chMsg[nStartReg + 2]) << 4) | ( AsciiToBYTE(chMsg[nStartReg + 3]) & 0x00FF ) ) & 0x0000FFFF ); } EnterCriticalSection( &g_csIcpdasReadOneData ); pBaseVar->m_dbData = (double)(nValue * fCoef); if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csIcpdasReadOneData ); //LOG4C((LOG_NOTICE, "变量:%s, 值=%d", pBaseVar->m_strDesc, (int)pBaseVar->m_dbData)); } else { // 联合类型变量做特殊处理 if( pBaseVar->m_nVarTypeID >= UNION_TYPE_MIN_ID && pBaseVar->m_nVarTypeID <= UNION_TYPE_MAX_ID ) { if( nDataLen == 2 ) { //int类型 union __UNION_VAR_INT{ char ch[2]; int value; }unionVarInt; unionVarInt.ch[0] = chMsg[1]; unionVarInt.ch[1] = chMsg[0]; EnterCriticalSection( &g_csIcpdasReadOneData ); pBaseVar->m_dbData = (double)(unionVarInt.value * fCoef); if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csIcpdasReadOneData ); //TRACE2("联合类型变量ID%d, 值=%d\r\n", iVarID, unionVarInt.value); } else if( nDataLen == 4 ) { //float类型 union __UNION_VAR_FLOAT{ char ch[4]; float value; }unionVarFloat; unionVarFloat.ch[0] = chMsg[3]; unionVarFloat.ch[1] = chMsg[2]; unionVarFloat.ch[2] = chMsg[1]; unionVarFloat.ch[3] = chMsg[0]; EnterCriticalSection( &g_csIcpdasReadOneData ); pBaseVar->m_dbData = (double)(unionVarFloat.value * fCoef); if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csIcpdasReadOneData ); //TRACE2("联合类型变量ID%d, 值=%.1f\r\n", iVarID, unionVarFloat.value); } else if( nDataLen == 8 ) { //double类型 union __UNION_VAR_DOUBLE{ char ch[8]; double value; }unionVarDouble; unionVarDouble.ch[0] = chMsg[7]; unionVarDouble.ch[1] = chMsg[6]; unionVarDouble.ch[2] = chMsg[5]; unionVarDouble.ch[3] = chMsg[4]; unionVarDouble.ch[4] = chMsg[3]; unionVarDouble.ch[5] = chMsg[2]; unionVarDouble.ch[6] = chMsg[1]; unionVarDouble.ch[7] = chMsg[0]; EnterCriticalSection( &g_csIcpdasReadOneData ); pBaseVar->m_dbData = (double)(unionVarDouble.value * fCoef); if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csIcpdasReadOneData ); //TRACE2("联合类型变量ID%d, 值=%.1f\r\n", iVarID, unionVarDouble.value); } } else { CString str; WORD wdValue; switch( nDataLen ) { case 1: nValue = atoi(chMsg); break; case 2: memcpy(&wdValue, chMsg, sizeof(WORD)); nValue = ntohs(wdValue); break; case 3: // 一般为字符串类型,不作处理 break; case 4: // 保留,暂时不知道什么处理 break; case 5: // 一般为字符串类型,不作处理 break; case 6: // 一般为字符串类型,不作处理 break; case 7: // 7017 //str.Format("%s", chMsg); break; case 8: // 保留,暂时没有用到 break; } //LOG4C((LOG_NOTICE, "pBaseVar->m_iDataLen = %d", pBaseVar->m_iDataLen)); if( pBaseVar->m_iDataLen == 7 ) { str.Format("%s", chMsg); EnterCriticalSection( &g_csIcpdasReadOneData ); if( pBaseVar->m_nMaxValues != 0 || pBaseVar->m_nMinValues != 0 || pBaseVar->m_nMaxConvtRate != 0 || pBaseVar->m_nMinConvtRate != 0 ) { double fScale = (double)(pBaseVar->m_nMaxConvtRate - pBaseVar->m_nMinConvtRate) / (double)(pBaseVar->m_nMaxValues - pBaseVar->m_nMinValues); pBaseVar->m_dbData = atof(str) * fCoef * fScale; } else { pBaseVar->m_dbData = (double)(atof(str) * fCoef); } if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } pDev->m_dwOnlineTick = GetTickCount(); LeaveCriticalSection( &g_csIcpdasReadOneData ); //LOG4C((LOG_NOTICE, "desc = %s, data = %d", pBaseVar->m_strDesc, (int)pBaseVar->m_dbData)); return 0; } EnterCriticalSection( &g_csIcpdasReadOneData ); if( pBaseVar->m_nMaxValues != 0 || pBaseVar->m_nMinValues != 0 || pBaseVar->m_nMaxConvtRate != 0 || pBaseVar->m_nMinConvtRate != 0 ) { double fScale = (double)(pBaseVar->m_nMaxConvtRate - pBaseVar->m_nMinConvtRate) / (double)(pBaseVar->m_nMaxValues - pBaseVar->m_nMinValues); pBaseVar->m_dbData = nValue * fCoef * fScale; } else { pBaseVar->m_dbData = (double)(nValue * fCoef); } if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csIcpdasReadOneData ); //g_IcpdasReadOneData.dbData = (double)(nValue * fCoef); //TRACE2("普通变量ID%d, 值=%d\r\n", iVarID, g_IcpdasReadOneData.dbData); } } EnterCriticalSection(&g_csIcpdasReadOneData); pDev->m_dwOnlineTick = GetTickCount(); LeaveCriticalSection(&g_csIcpdasReadOneData); return 0; } void UnInitIcpdasDll() { if (g_hICPDASLibModule != NULL && ( NULL != pICPDAS_DLLUnInit )) { pICPDAS_DLLUnInit(); } DeleteCriticalSection( &g_csIcpdasReadOneData ); if (g_hICPDASLibModule!= NULL) { AfxFreeLibrary(g_hICPDASLibModule); g_hICPDASLibModule = NULL; } } int GetIcpdasFromIni(char chCmd[32], BYTE *Start, BYTE* byWithAddrFlag, BYTE *pFuncCode) { CHAR strFile[MAX_FILE_LENGTH + 1] = ""; CHAR strValue[MAX_VALUE_LENGTH + 1] = ""; CHAR strValueAddrFlag[4] =""; wsprintf(strFile, "%s\\config\\icpdas.ini", g_strDirectory); //Database GetPrivateProfileString("CMD", chCmd, "", strValue, sizeof(strValue), strFile); GetPrivateProfileString("RESWITHADDR", chCmd, "", strValueAddrFlag, sizeof(strValueAddrFlag), strFile); Start[0] = strValue[0]; byWithAddrFlag[0] = strValueAddrFlag[0]; if (strcmp( strValue, "@AA") == 0) sprintf((char*)pFuncCode, "%02d", -1); else if (strcmp( strValue, "$AALS") == 0) memcpy(pFuncCode, strValue + 3, 2); else if (strcmp( strValue, "@AA(Data)") == 0) sprintf((char*)pFuncCode, "%02d", -1); else if( strcmp( strValue, "#AA1cDD") == 0 ) memcpy(pFuncCode, strValue + 3, 4); else if( strcmp( strValue, "#AAN" ) == 0 ) memcpy(pFuncCode, "#AAN", strlen("#AAN")); else sprintf((char*)pFuncCode, "%02C", strValue[3]); return 0; } int RequestWrIcpdasData(char chDevUid[20], int iVarID, double data)//用于请求写命令操作 { int nDeviceIndex = -1, nVarIndex = -1; BOOL bFind = FindVar(chDevUid, iVarID, nDeviceIndex, nVarIndex); if( bFind == FALSE ) return -1; CDevice *pDev = g_pDevicesManager->m_Devices[nDeviceIndex]; CBaseVar *pBaseVar = pDev->m_Vars[nVarIndex]; char chMsg[80] = {0}; BYTE Start= 0x0;//起始位 BYTE StartAddr[MAX_ID] = {0}; BYTE FuncCode[MAX_ID] = {0}; BYTE byWithAddrFlag = 0; int nLen = 0; sprintf((char*)StartAddr, "%02d", pDev->m_iDevideaddr); GetIcpdasFromIni((char *)(LPCTSTR)pBaseVar->m_strRs232cmd, &Start, &byWithAddrFlag,FuncCode); memcpy(chMsg, &Start, sizeof(Start)); nLen += sizeof(Start); memcpy(chMsg + nLen, StartAddr, strlen((char *)StartAddr)); nLen += strlen((char *)StartAddr); // 固定信息 memcpy(chMsg + nLen, "1", 1); nLen += 1; double fCoef = pBaseVar->m_dbCoefficient; int nDataLen = pBaseVar->m_iDataLen; int nVarItemID = pBaseVar->m_nVarItemID; // 泓格I-7000系列为特殊协议只有BIT变量,这里只处理BIT位变量 if( nVarItemID > 0 )//BIT位变量 { int nStartBit = pBaseVar->m_nStartBit; int nEndBit = pBaseVar->m_nEndBit; if( nEndBit - nStartBit < 7 ) { CString strTemp; CString strIndex; if( nDataLen == 1 ) { switch( nEndBit - nStartBit ) { case 0: strTemp.Format("%02d", (int)data); break; } strIndex.Format("%d", atoi(pBaseVar->m_strRs232Index)); memcpy(chMsg + nLen, (char *)(LPCTSTR)strIndex, strIndex.GetLength()); nLen += strIndex.GetLength(); memcpy(chMsg + nLen, (char *)(LPCTSTR)strTemp, strTemp.GetLength()); nLen += strTemp.GetLength(); } } } chMsg[nLen] = 0x0D; nLen++; if( pICPDAS_DLLWrCom(pDev->m_iPort, pDev->m_iDevideaddr, chMsg, nLen) == 0) { LOG4C((LOG_NOTICE, "pICPDAS_DLLWrCom success!")); return 0; } else { LOG4C((LOG_NOTICE, "pICPDAS_DLLWrCom lost!")); return -1; } }