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

📄 netelectronsrvdlg.cpp

📁 网络家电
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	m_nWaterHeaterOpenOrClose = pJiadianState->nWaterHeaterOpenOrClose;
	SetDlgItemText ( IDC_STATIC_WATER_HEATER_OPEN_OR_CLOSE,
		m_nWaterHeaterOpenOrClose?"开":"关" );
	m_nWaterHeaterTemperature = pJiadianState->nWaterHeaterTemperature;

	m_nMicroWaveOvenOpenOrClose = pJiadianState->nMicroWaveOvenOpenOrClose;
	SetDlgItemText ( IDC_STATIC_MicroWaveOven_OPEN_OR_CLOSE,
		m_nMicroWaveOvenOpenOrClose?"开":"关" );
	m_nMicroWaveOvenTiming = pJiadianState->nMicroWaveOvenTiming;

	m_nCurtainOpenOrClose = pJiadianState->nCurtainOpenOrClose;
	SetDlgItemText ( IDC_STATIC_Curtain_OPEN_OR_CLOSE,
		m_nCurtainOpenOrClose?"开":"关" );
	m_nCurtainTiming = pJiadianState->nCurtainTiming;

	UpdateData ( FALSE );
}

void CNetElectronSrvDlg::OnAccept()
{
	if ( !m_sockListen.Accept ( m_sockSend ) )
	{
		Log ( "接受客户连接失败" );
		return;
	}

	m_bSockConnected = TRUE;
	Log ( "连接成功,正在身份验证 ..." );
	// 身份验证
	char str[] = "Password:";
	// 发送验证字符串
	SendSockData ( str,strlen (str ) + 1 );
	m_sockSend.m_CommState = CSTATE_WAIT_PASS;
}

// 处理收到的数据
void CNetElectronSrvDlg::HandleWhenReceivedData(char *pData, int nLen)
{
	Log ( "收到数据:%s", Data2String(pData,nLen) );
	
	switch ( m_sockSend.m_CommState )
	{
	case CSTATE_START:
		break;
	case CSTATE_WAIT_PASS:
		if ( strcmp ( pData, "xhw" ) == 0 )		// 身份验证已经通过
		{
			Log ( "身份验证已经通过!" );
			m_sockSend.m_CommState = CSTATE_LOGINOK;
			SendSockData ( (char*)&m_JiaDianState, sizeof(t_JiaDianState) );
		}
		else
		{
			char str[] = "Password:";
			SendSockData ( str, strlen (str ) + 1 );
		}
		break;
	case CSTATE_LOGINOK:
		if ( sizeof(t_JiaDianState) == nLen )
		{
			if ( memcmp ( &m_JiaDianState, pData, nLen ) != 0 )
			{
				memcpy ( &m_JiaDianState, pData, nLen );
				SetNewStatus ( &m_JiaDianState );
				// 将新状态发送给串口
				SendNewStatusToCOM ( &m_JiaDianState );
			}
		}
		break;
	}
}

void CNetElectronSrvDlg::OnClose()
{
	// 关闭所有端口
	m_COM.Close();
	m_sockSend.Close();
	m_sockListen.Close();
	m_SrvStart = FALSE;
	EnableCtrlWindow ( m_SrvStart );

	// 重新启动
	OnButtonStartSrv();

}

// 参数:bStart - 服务是否已经启动
void CNetElectronSrvDlg::EnableCtrlWindow( BOOL bStart)
{
	m_btnStartSrv.EnableWindow ( !bStart );
	GetDlgItem(IDC_EDIT_COM)->EnableWindow ( !bStart );
	GetDlgItem(IDC_EDIT_PORT)->EnableWindow ( !bStart );
	GetDlgItem(IDC_BUTTON_TEST_COM)->EnableWindow ( bStart );
}

CString CNetElectronSrvDlg::Data2String(char *pData, int nSize)
{
	CString csData, csTemp;
	for ( int i=0; i<nSize; i++ )
	{
		csTemp.Format ( "%02x ", (UCHAR)pData[i] );
		csData += csTemp;
	}

	csTemp.Format ("\t-\t%s", pData );
	csData += csTemp;
	return csData;
}

// 构造一个数据包,返回包长度
int CNetElectronSrvDlg::BuildPkt(t_JiaDianState *pJiaDianState,char *pBuf,int nBufSize)
{
	int nCount = 0;
	// 空调开关
	pBuf[nCount] = pJiaDianState->nKongTiaoOpenOrClose?0x01:0x00;
	nCount ++;
	ASSERT ( nCount < nBufSize );
	// 空调温度
	pBuf[nCount] = pJiaDianState->nKongTiaoTemperature;
	nCount ++;
	ASSERT ( nCount < nBufSize );

	// 热水器开关
	pBuf[nCount] = pJiaDianState->nWaterHeaterOpenOrClose?0x01:0x00;
	nCount ++;
	ASSERT ( nCount < nBufSize );
	// 热水器温度
	pBuf[nCount] = pJiaDianState->nWaterHeaterTemperature;
	nCount ++;
	ASSERT ( nCount < nBufSize );

	// 微波炉开关
	pBuf[nCount] = pJiaDianState->nMicroWaveOvenOpenOrClose?0x01:0x00;
	nCount ++;
	ASSERT ( nCount < nBufSize );
	// 微波炉定时
	pBuf[nCount] = pJiaDianState->nMicroWaveOvenTiming;
	nCount ++;
	ASSERT ( nCount < nBufSize );

	// 窗帘开关
	pBuf[nCount] = pJiaDianState->nCurtainOpenOrClose?0x01:0x00;
	nCount ++;
	ASSERT ( nCount < nBufSize );
	// 窗帘定时
	pBuf[nCount] = pJiaDianState->nCurtainTiming;
	nCount ++;
	ASSERT ( nCount < nBufSize );

	return nCount;
}

// 给串口发送AT命令,来测试串口通信是否完好。
void CNetElectronSrvDlg::OnButtonTestCom() 
{
	UpdateData ( TRUE );
	CString csTemp;
	csTemp.Format ( "先在串口〖COM%d〗上接好一个modem并打开modem开关,然后就可以开始测试了,测试程序将拨号到〖%s〗,如果modem提机并拨号,说明对串口的操作是正确的,准备好了吗?",
		m_nComNo, m_csPhoneNo );
	if ( MessageBox ( csTemp, "Question", MB_ICONQUESTION | MB_YESNO ) == IDNO )
		return;
	char buf[256] = {0};
	int nLen = _snprintf((char*)buf,sizeof(buf) - 1,"ATDT%s\r\n",m_csPhoneNo);
	Log ( "发送%d字节的串口数据:%s", nLen, Data2String(buf,nLen) );
	if ( m_COM.Write ( buf, nLen ) != nLen )
	{
		csTemp.Format ( "发送数据到串口失败 - %s", m_COM.GetLastErrorString() );
		MessageBox ( csTemp, "错误", MB_ICONERROR );
	}
	else
	{
		Log ( "发送串口数据成功" );
	}
}

// 从串口中读取数据,得到设备当前状态
BOOL CNetElectronSrvDlg::GetDevStatusFromCOM(t_JiaDianState *pJiaDianState)
{
	char cComData [ 128*COM_DATA_SIZE ] = {0};
	int nReadyDataLen = m_COM.GetCommInputBuffLen();
	if ( nReadyDataLen < 1 )
	{
//		Log ( "串口〖COM%d〗中没有足够的数据可以读取", m_nComNo );
		return FALSE;
	}
	int nComDataLen = m_COM.Read ( cComData, nReadyDataLen );
	if ( nComDataLen <= 0 )
	{
		Log ( "从串口中读数据出错!" );
		return FALSE;
	}
	Log ( "从串口〖COM%d〗读到%d字节数据:%s", m_nComNo, nComDataLen, Data2String(cComData,nComDataLen) );

	if ( nComDataLen < COM_DATA_SIZE )
	{
		Log ( "读到 %d 字节数据,不够一个包长度(%d字节)", nComDataLen, COM_DATA_SIZE );
		return FALSE;
	}

	int nCount = 0;
	// 空调开关
	pJiaDianState->nKongTiaoOpenOrClose = cComData[nCount];
	nCount ++;
	// 空调温度
	pJiaDianState->nKongTiaoTemperature = cComData[nCount];
	nCount ++;
	// 热水器开关
	pJiaDianState->nWaterHeaterOpenOrClose = cComData[nCount];
	nCount ++;
	// 热水器温度
	pJiaDianState->nWaterHeaterTemperature = cComData[nCount];
	nCount ++;
	// 微波炉开关
	pJiaDianState->nMicroWaveOvenOpenOrClose = cComData[nCount];
	nCount ++;
	// 微波炉定时
	pJiaDianState->nMicroWaveOvenTiming = cComData[nCount];
	nCount ++;
	// 窗帘开关
	pJiaDianState->nCurtainOpenOrClose = cComData[nCount];
	nCount ++;
	// 窗帘定时
	pJiaDianState->nCurtainTiming = cComData[nCount];
	nCount ++;

	return TRUE;
}

// 从串口中取最新的家电状态,并处理这些最新的状态
void CNetElectronSrvDlg::GetAndHandleNewSTFromCOM() 
{
	t_JiaDianState JiaDianState;
	if ( !GetDevStatusFromCOM ( &JiaDianState ) )
		return;
	if ( memcmp ( &JiaDianState, &m_JiaDianState, sizeof(t_JiaDianState) ) == 0 )
		return;
	memcpy ( &m_JiaDianState, &JiaDianState, sizeof(t_JiaDianState) );
	SetNewStatus ( &m_JiaDianState );
	SendSockData ( (char*)&m_JiaDianState, sizeof(t_JiaDianState) );
	
}
// 将新的电器状态发送给串口
BOOL CNetElectronSrvDlg::SendNewStatusToCOM(t_JiaDianState *pJiadianState)
{
	char cComData [ COM_DATA_SIZE+1 ] = {0};
	int nComDataLen = BuildPkt ( pJiadianState, cComData, sizeof(cComData) );
	ASSERT ( nComDataLen == COM_DATA_SIZE );
	Log ( "发送%d字节的串口数据:%s", nComDataLen, Data2String(cComData,nComDataLen) );
	if ( m_COM.Write ( cComData, nComDataLen ) != nComDataLen )
	{
		CString csTemp;
		csTemp.Format ( "发送数据到串口失败 - %s", m_COM.GetLastErrorString() );
		MessageBox ( csTemp, "错误", MB_ICONERROR );
		Log ( "发送串口数据失败" );
		return FALSE;
	}
	else
	{
		Log ( "发送串口数据成功" );
	}
	return TRUE;
}

void CNetElectronSrvDlg::OnDblclkListLogInfo() 
{
	int nCurSel = m_ListLogInfo.GetCurSel();
	if ( nCurSel < 0 ) return;
	CString csText;
	m_ListLogInfo.GetText ( nCurSel, csText );
	MessageBox ( csText, "日志信息", MB_ICONINFORMATION );
}

// 将新的状态数据通过socket发送给客户端
BOOL CNetElectronSrvDlg::SendSockData(char *pData, int nSize)
{
	if ( !m_bSockConnected ) return FALSE;
	Log ( "发送%d字节到客户端:%s", nSize, Data2String(pData,nSize) );
	int nReturned = m_sockSend.Send ( (const void*)pData, nSize );
	if ( nReturned != nSize )
	{
		Log ( "发送 %d 字节数据到客户端失败!", nSize );
		return FALSE;
	}
	return TRUE;
}

void CNetElectronSrvDlg::OnTimer(UINT nIDEvent) 
{
	GetAndHandleNewSTFromCOM ();
	CDialog::OnTimer(nIDEvent);
}

⌨️ 快捷键说明

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