#include "stdafx.h" #include "Daikin.h" CDaiKin::CDaiKin(char *szPath,char *szIniName,int nCommPort,int nAddr,int nRate,int nDataBit,int nStopBit,int nParity,int nInterval) { #if IS_USE_READMSG_CS InitializeCriticalSection( &m_csReadMsg ); //初始化一个临界资源对象 #endif MTVERIFY( m_hSemComm = CreateEvent( NULL, TRUE, TRUE, 0 ) ); //CreateEvent()创建或打开一个命名的或无名的事件对象 for( int i = 0; i < 9; i++ ) { memset(m_szDaKin_400Msg[i], 0, sizeof(m_szDaKin_400Msg[i])); m_devOnline[i] = TRUE; m_dwOnlineTick[i] = 0; } } CDaiKin::~CDaiKin() { #if IS_USE_READMSG_CS DeleteCriticalSection( &m_csReadMsg ); #endif MTVERIFY( CloseHandle( m_hSemComm ) ); CloseComm(); } BOOL CDaiKin::DaiKinOpenComm(int nCommPort, int nAddr, int nRate, int nDataBit, int nStopBit, int nParity, int nInterval) { BOOL bResult = FALSE; bResult = OpenComm( nCommPort, nAddr, nRate, nDataBit, nStopBit, nParity, nInterval ); return bResult; } int CDaiKin::GetIniInfo(char *szPath,char *szIniName,char *szCmd,char *IniSendCMD,int &IniSendlen,char *szDataType,int &nIndex,int &nLen, int &iSBit, int &iEBit) { CHAR szFile[MAX_PATH + 1] = ""; wsprintf(szFile, "%s\\config\\%s", szPath, szIniName); IniSendlen = GetPrivateProfileString(szCmd, "SendCmd", "", IniSendCMD, 10, szFile); // 返回的字符串是以\0结束的; GetPrivateProfileString(szCmd, "type", "", szDataType, 10, szFile); szDataType[strlen(szDataType)] = '\0'; nIndex = GetPrivateProfileInt(szCmd, "Index", 0, szFile); nLen = GetPrivateProfileInt(szCmd, "Len", 0, szFile); iSBit = GetPrivateProfileInt(szCmd, "StaBit", 0, szFile);//从配置文件中取值 iEBit = GetPrivateProfileInt(szCmd, "EndBit", 0, szFile); return 0; } // 发送读取设备参数请求 int CDaiKin::SendReadRequest( char *szPath, char *szIniName, int nCommPort, int nAddr, char *szCmd, char *szMsg, int nReversed1, int nReversed2, int nReversed3, int nReversed4, int nReversed5, float fReversed1, float fReversed2, float fReversed3, char *szReversed1, char *szReversed2, char *szReversed3, char *szReversed4, char *szReversed5 ) { CCommProcess *pComm = FindComm(nCommPort); if( pComm == NULL ) return -1; int nRet = -1; int nIndex(0), nLen(0), IniSendlen(0),iSBit(0), iEBit(0); char IniSendCMD[MAX_CMD] = {0}, szDataType[CMD_TYPE] = {0}; GetIniInfo(szPath,szIniName,szCmd,IniSendCMD,IniSendlen,szDataType,nIndex,nLen,iSBit,iEBit); int iCmd = atoi(szCmd + 4); if( (strlen(m_szDaKin_400Msg[nAddr -1]) == 0 && (iCmd >= 5 && iCmd <= 15)) || iCmd == 5) { nRet = GetDeviceParam(nAddr, pComm,szCmd, IniSendCMD, IniSendlen); if( nRet != 0 ) return nRet; } if( GetTickCount() - m_dwOnlineTick[nAddr - 1] > 60 *1000 && m_dwOnlineTick[nAddr - 1] > 0 ) m_devOnline[nAddr - 1] = FALSE; else if( GetTickCount() - m_dwOnlineTick[nAddr - 1] < 60 *1000 && m_dwOnlineTick[nAddr - 1] > 0 ) m_devOnline[nAddr - 1] = TRUE; if( m_devOnline[nAddr - 1] == FALSE ) return -1; nRet = GetDaiKin_400VarMsg(nAddr, szCmd, szMsg, nIndex, nLen, szDataType, iSBit, iEBit); //LOG4C((LOG_NOTICE, "CDaiKin::SendSetReuest szCmd= %s, szMsg = %s", szCmd, szMsg)); return nRet; } void CDaiKin::BitDataProcess(const BYTE &bySour, char *szRecv,int &StaBit,int &EndBit) { int ByteBit = 0; int sum = bySour - 48; switch(StaBit) { case 0: ByteBit = sum & 0x01; break; case 1: ByteBit = (sum & 0x02) / 0x02 ; break; case 2: ByteBit = (sum & 0x04) / 0x04 ; break; case 3: ByteBit = (sum & 0x08) / 0x08 ; break; case 4: ByteBit = (sum & 0x10) / 0x10 ; break; case 5: ByteBit = (sum & 0x20) / 0x20 ; break; case 6: ByteBit = (sum & 0x40) / 0x40 ; break; case 7: ByteBit = (sum & 0x80) / 0x80; break; } sprintf(szRecv,"%d",ByteBit); } int CDaiKin::GetDaiKin_400VarMsg( int nAddr,char *szCmd,char *szMsg,int &nIndex,int &nLen,char *szType,int startBit,int endBit ) { #if IS_USE_READMSG_CS EnterCriticalSection( &m_csReadMsg ); #endif int i = 0; if ( strcmp(szType, "BIT") == 0 ) { char szConvMsg[2] = {0}; memcpy(szMsg, m_szDaKin_400Msg[nAddr -1] + nIndex,nLen); BitDataProcess((BYTE)szMsg[0],szConvMsg,startBit,endBit); memset(szMsg,0,strlen(szMsg)); memcpy(szMsg,szConvMsg,2); }else DataConversion(szType, m_szDaKin_400Msg[nAddr - 1] + nIndex, szMsg, nLen, startBit, endBit); #if IS_USE_READMSG_CS LeaveCriticalSection(&m_csReadMsg); #endif return 0; } int CDaiKin::GetDeviceParam(int nAddr,CCommProcess *pComm,char *szCmd,char *IniSendCMD, const int &IniSendlen) { int nRet = -1; nRet = Send_ReadDeviceData(nAddr,pComm,szCmd,IniSendCMD,IniSendlen); if( nRet != 0 ) { LOG4C((LOG_NOTICE,"DAKIN Write Error")); return nRet; // 串口忙 } nRet = Recv_ReadDeviceData(nAddr, pComm, szCmd); return nRet; } int CDaiKin::SetDeviceParam(int nAddr,CCommProcess *pComm,char *szCmd,char *szSetMsg,char *szRecvMsg,char *IniSendCMD, const int &IniSendlen) { int nRet = -1; nRet = Send_WriteDeviceData(nAddr, pComm, szCmd, szSetMsg,IniSendCMD, IniSendlen ); if( nRet != 0 ) { LOG4C((LOG_NOTICE,"DAKIN Write Error")); return nRet; // 串口忙 } nRet = Recv_WriteDeviceData(nAddr, pComm, szCmd, szRecvMsg); return nRet; } // 发送设置设备参数请求 int CDaiKin::SendSetReuest( char *szPath, char *szIniName, int nCommPort, int nAddr, char *szCmd, char *szSetMsg, int nReversed1, int nReversed2, int nReversed3, int nReversed4, int nReversed5, float fReversed1, float fReversed2, float fReversed3, char *szReversed1, char *szReversed2, char *szReversed3, char *szReversed4, char *szReversed5 ) { CCommProcess *pComm = FindComm(nCommPort); if( pComm == NULL ) return -1; int nRet = -1; int nIndex(0), nLen(0), IniSendlen(0),iSBit(0), iEBit(0); char IniSendCMD[MAX_CMD] = {0}, szDataType[CMD_TYPE] = {0}; GetIniInfo(szPath,szIniName,szCmd,IniSendCMD,IniSendlen,szDataType,nIndex,nLen,iSBit,iEBit); char szRecvMsg[10] = {0}; SetDeviceParam(nAddr, pComm, szCmd, szSetMsg,szRecvMsg,IniSendCMD,IniSendlen); return 0; } int CDaiKin::Send_ReadDeviceData(int nAddr,CCommProcess *pComm,char *szCmd,const char *IniSendCMD,const int &IniSendlen) { int nRet = -1; #if DEBUG_DAIKIN int iSendLen = 0; BYTE byArySend[60] = {0}; byArySend[0] = 0x7E; byArySend[1] = 0x32; byArySend[2] = 0x30; byArySend[3] = ByteToAscii((nAddr>>4) & 0x0f); byArySend[4] = ByteToAscii(nAddr & 0x0f); //Cid1 byArySend[5] = 0x36; byArySend[6] = 0x30; //Cid2 byArySend[7] = 0x45; byArySend[8] = 0x30; // length; byArySend[9] = 0x41; byArySend[10] = 0x30; byArySend[11] = 0x30; byArySend[12] = 0x36; // STX; byArySend[13] = 0x34; byArySend[14] = 0x30; byArySend[15] = 0x30; // Line id; byArySend[16] = nAddr + 47; // Unit No; #if 0 int UnitNo = nAddr - 1; byArySend[17] = ByteToAscii((UnitNo>>4) & 0x0f); byArySend[18] = ByteToAscii(UnitNo & 0x0f); #else byArySend[17] = 0x30; byArySend[18] = 0x30; #endif // CHECK; char chChkSum[5] = {0}; GetCheckSum((char *)byArySend + 1, chChkSum, 18 ); memcpy(byArySend + 19, chChkSum, 4); // EOI; byArySend[23] = 0x0D; iSendLen = 24; if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口 { ResetEvent( m_hSemComm ); int nResult = pComm->Write(byArySend, iSendLen); if( nResult != iSendLen ) { SetEvent( m_hSemComm ); LOG4C((LOG_NOTICE,"DAKIN Write长度错误")); return EER_CODE_COM_WRITE_DATA; } } else { LOG4C((LOG_NOTICE,"DAKIN 无法获取信号控制")); return ERR_CODE_COM_BUSY; } #endif return 0; } int CDaiKin::Recv_ReadDeviceData(int nAddr,CCommProcess *pComm,char *szCmd) { #if DEBUG_DAIKIN BYTE *byAryRecv = new BYTE[90]; ZeroMemory(byAryRecv, 90); int iRecvLen = pComm->Read(byAryRecv,90); if( iRecvLen <= 0) { SetEvent( m_hSemComm ); if( byAryRecv != NULL) { delete[] byAryRecv; byAryRecv = NULL; } LOG4C((LOG_NOTICE, "DAKIN 串口没有读到数据")); return ERR_CODE_COM_READ_NO_DATA; } if (!ChkSumCheck( (char*)byAryRecv, iRecvLen)) { SetEvent(m_hSemComm); if (byAryRecv != NULL) { delete [] byAryRecv; byAryRecv = NULL; } LOG4C((LOG_NOTICE, "DAKIN 校验码校验出错")); return ERR_CODE_RTN_CHKSUM_ERROR; } if (RtnCheck( (char*)byAryRecv) != 0) { SetEvent(m_hSemComm); if (byAryRecv != NULL) { delete [] byAryRecv; byAryRecv = NULL; } LOG4C((LOG_NOTICE, "DAKIN RTN校验出错")); return ERR_CODE_RTN_CHKSUM; } // copy ; memcpy(m_szDaKin_400Msg[nAddr -1], byAryRecv, iRecvLen); m_dwOnlineTick[nAddr - 1] = GetTickCount(); SetEvent( m_hSemComm ); if( byAryRecv != NULL) { delete[] byAryRecv; byAryRecv = NULL; } #else SimulationCommData(nAddr); #endif return 0; } int CDaiKin::Send_WriteDeviceData( int nAddr,CCommProcess *pComm, char *szCmd, char *szSetMsg,char *IniSendCMD, const int &IniSendlen) { #if DEBUG_DAIKIN /************************************************************************/ int iSendLen = 0; char chLength[4] = {0}; char chChkSum[5] = {0}; BYTE byArySend[120] = {0}; // SOI; byArySend[0] = 0x7E; // Ver; byArySend[1] = 0x32; byArySend[2] = 0x30; // Addr; byArySend[3] = ByteToAscii((nAddr>>4) & 0x0f); byArySend[4] = ByteToAscii(nAddr & 0x0f); // Cid1; byArySend[5] = 0x36; byArySend[6] = 0x30; // Cid2; memcpy(byArySend + 7, IniSendCMD, IniSendlen); if ( (strcmp(szCmd, "cmd-1") == 0)) // 开关机; { // Length; byArySend[9] = 0x45; byArySend[10] = 0x30; byArySend[11] = 0x30; byArySend[12] = 0x32; int iCtrl = atoi(szSetMsg); memset(szSetMsg,0,strlen(szSetMsg)); itoa(iCtrl,szSetMsg,16); for (int i(0); i < 2 ; i++) lowcase2uppcase((BYTE &)szSetMsg[i]); memcpy(byArySend + 13, szSetMsg, 2); GetCheckSum((char *)byArySend + 1, chChkSum, 14 ); memcpy(byArySend + 15, chChkSum, 4); byArySend[19] = 0x0D; iSendLen = 20; LOG4C((LOG_NOTICE,"DAKIN cmd-1=空调开关控制:%s",szSetMsg)); } else if ( (strcmp(szCmd, "cmd-2") == 0)) // 设置风量; { char szTemp[10] = {0}; int iRealLen = strlen(szSetMsg); memcpy(szTemp,szSetMsg,iRealLen); if (iRealLen > 4) { LOG4C((LOG_NOTICE,"DAKIN 非法指令长度:%s",szSetMsg)); return -1; } // 制热模式下,制冷为00; if (iRealLen == 2) { memcpy(szSetMsg + 2, szTemp,iRealLen); szSetMsg[0] = 48; szSetMsg[1] = 48; }else if (iRealLen == 1) { memcpy(szSetMsg + 3, szTemp,iRealLen); szSetMsg[0] = 48; szSetMsg[1] = 48; szSetMsg[2] = 48; } // Length; byArySend[9] = 0x38; byArySend[10] = 0x30; byArySend[11] = 0x30; byArySend[12] = 0x38; // STX; byArySend[13] = 0x36; byArySend[14] = 0x34; byArySend[15] = 0x30; // 接口卡LINEID; byArySend[16] = nAddr -1 + 48; // 设置值; memcpy(byArySend + 17, szSetMsg, 4); GetCheckSum((char *)byArySend + 1, chChkSum, 20 ); memcpy(byArySend + 21, chChkSum, 4); // EOL; byArySend[25] = 0x0D; iSendLen = 26; LOG4C((LOG_NOTICE,"DAKIN cmd-2=空调风量设置:%s",szSetMsg)); } else if ( (strcmp(szCmd, "cmd-3") == 0)) // 设置温度; { // Length; byArySend[9] = 0x36; byArySend[10] = 0x30; byArySend[11] = 0x30; byArySend[12] = 0x41; // STX; byArySend[13] = 0x36; byArySend[14] = 0x33; byArySend[15] = 0x30; // Line No; byArySend[16] = nAddr -1 + 48; // 设置的值; char szTemp[10] = {0}; int iRealLen = strlen(szSetMsg); memcpy(szTemp,szSetMsg,iRealLen); if (iRealLen > 6) { LOG4C((LOG_NOTICE,"DAKIN 非法指令长度:%s",szSetMsg)); return -1; } if (iRealLen == 5) { memcpy(szSetMsg + 1, szTemp,iRealLen); szSetMsg[0] = 48; }else if (iRealLen == 4) { memcpy(szSetMsg + 2, szTemp,iRealLen); szSetMsg[0] = 48; szSetMsg[1] = 48; } else if ( iRealLen == 3) { memcpy(szSetMsg + 3, szTemp,iRealLen); szSetMsg[0] = 48; szSetMsg[1] = 48; szSetMsg[2] = 48; } else if ( iRealLen == 2) { memcpy(szSetMsg + 4, szTemp,iRealLen); szSetMsg[0] = 48; szSetMsg[1] = 48; szSetMsg[2] = 48; szSetMsg[3] = 48; } else if ( iRealLen == 1) { memcpy(szSetMsg + 5, szTemp,iRealLen); szSetMsg[0] = 48; szSetMsg[1] = 48; szSetMsg[2] = 48; szSetMsg[3] = 48; szSetMsg[4] = 48; } else if ( iRealLen == 0) memcpy(szSetMsg , "000000", 6); memcpy(byArySend + 17, szSetMsg, 6); GetCheckSum((char *)byArySend + 1, chChkSum, 22 ); memcpy(byArySend + 23, chChkSum, 4); byArySend[27] = 0x0D; iSendLen = 28; LOG4C((LOG_NOTICE,"DAKIN cmd-3=空调温度设置:%s",szSetMsg)); }else if ( strcmp(szCmd, "cmd-4") == 0) // 设置运转模式; { // Length; byArySend[9] = 0x42; byArySend[10] = 0x30; byArySend[11] = 0x30; byArySend[12] = 0x35; // STX; byArySend[13] = 0x36; byArySend[14] = 0x32; byArySend[15] = 0x30; // 接口卡LINEID; 范围:0~2 byArySend[16] = nAddr -1 + 48; // 设置值; 范围:0~7 memcpy(byArySend + 17, szSetMsg, 1); GetCheckSum((char *)byArySend + 1, chChkSum, 17 ); memcpy(byArySend + 18, chChkSum, 4); // EOI; byArySend[22] = 0x0D; iSendLen = 23; LOG4C((LOG_NOTICE,"DAKIN cmd-4=空调运转模式设置:%s",szSetMsg)); } /************************************************************************/ ResetEvent( m_hSemComm ); // 读取上次未读的数据,确保空调缓存已无数据; BYTE byRecv[250] = {0}; pComm->Read(byRecv, 250); Sleep(500); int nResult = pComm->Write(byArySend, iSendLen); if( nResult != iSendLen ) { SetEvent( m_hSemComm ); return EER_CODE_COM_WRITE_DATA; } Sleep(300); #endif return 0; } int CDaiKin::Recv_WriteDeviceData(int nAddr, CCommProcess *pComm, char *szCmd, char *szRecvMsg) { #if DEBUG_DAIKIN int nReceiveLen = 250; int nProcessLen = 0; int nReadLen = 0; char *pBuffer = new char[ nReceiveLen ]; memset(pBuffer, 0, nReceiveLen); Sleep(200); nReadLen = pComm->Read((BYTE *)pBuffer, nReceiveLen); if( nReadLen <= 0) { SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } LOG4C((LOG_NOTICE,"DAKIN 写 串口没有读到数据")); return ERR_CODE_COM_READ_NO_DATA; } #if 0 if (!ChkSumCheck(pBuffer, strlen(pBuffer))) { SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } LOG4C((LOG_NOTICE,"DAKIN 写 校检错误")); return ERR_CODE_DAIKIN_COM_CHKSUM_LOST; } if (!CheckLength(pBuffer)) { SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } LOG4C((LOG_NOTICE,"DAKIN 写 数据长度校检错误")); return ERR_CODE_DAIKIN_COM_VARLEN; } int nRet = RtnCheck(pBuffer); if(0 != nRet) { SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } LOG4C((LOG_NOTICE,"DAKIN 写 返回码出错")); return nRet; } #endif // 设置串口等待事件为有信号; SetEvent( m_hSemComm ); if( pBuffer != NULL) { delete[] pBuffer; pBuffer = NULL; } #else SimulationCommData(nAddr); #endif return 0; } void CDaiKin::SimulationCommData(int nAddr) { } WORD CDaiKin::RtnCheck(char Msg[VAR_MSG]) { int len ,index; len = 2; index = 7; char ch[2]; ch[0] = Msg[index]; ch[1] = Msg[index+1]; int RTN = atoi(ch); if ( RTN == 0) return 0; if (RTN==ERR_CODE_RTN_VER_ERROR) { return ERR_CODE_RTN_VER_ERROR; } else if (RTN==ERR_CODE_RTN_CHKSUM_ERROR) { return ERR_CODE_RTN_CHKSUM_ERROR; } else if (RTN==ERR_CODE_RTN_LCHKSUM_ERROR) { return ERR_CODE_RTN_LCHKSUM_ERROR; } else if (RTN==ERR_CODE_RTN_CID_ERROR) { return ERR_CODE_RTN_CID_ERROR; } else if (RTN==ERR_CODE_RTN_COMMAND_FORMAT) { return ERR_CODE_RTN_COMMAND_FORMAT; } else if (RTN==ERR_CODE_RTN_INVALID_DATA) { return ERR_CODE_RTN_INVALID_DATA; } else /*if (atoi(ch)==ERR_CID_RTN_NORMAL)*/ { return ERR_CODE_RTN_OPERATE_FAIL; } } void CDaiKin::lowcase2uppcase(BYTE &btSrc) { if( btSrc >= 'a' && btSrc <= 'z' ) btSrc = btSrc - 'a' + 'A'; } void CDaiKin::GetCheckSum(char *szData, char *szCheck ,int nlen) { DWORD dwSum(0); for (int i = 0; i < nlen; i++) dwSum += szData[i]; WORD iCompliment = dwSum; iCompliment = ~iCompliment;//取反 iCompliment++; itoa(iCompliment, szCheck, 16); for (int i(0); i < 5 ; i++) lowcase2uppcase((BYTE &)szCheck[i]); }