AcqDataInterface学习.docx
《AcqDataInterface学习.docx》由会员分享,可在线阅读,更多相关《AcqDataInterface学习.docx(18页珍藏版)》请在冰豆网上搜索。
![AcqDataInterface学习.docx](https://file1.bdocx.com/fileroot1/2023-2/7/cda138fb-7239-4665-ae41-6d34294b0975/cda138fb-7239-4665-ae41-6d34294b09751.gif)
AcqDataInterface学习
AcqDataInterface:
输出类型为:
类库(输出类型分为:
Windows应用程序,控制台应用程序,类库)。
包含内容:
IMessageStreamEvent
IIODataAcquirable
IDataAcquirable
ICommunicateInfo、类:
CommunicatePower
协议定义:
包括ENUM_TREATY_DEFINE、ENUM_PACKET_TYPE、DevStateType、DebugFlag、BatteryAgedTestFlag、DAAdjuestType、结构体:
PackStruct、类:
TreatyDefine。
IMessageStreamEvent
主界面HCMasterFormEx_Load函数实例了AcquireData
m_AcquireData=newAcquireData();
并调用了init()方法:
intresult=m_AcquireData.Init();
init()方法实例了m_ProcessPackage=newProcessPackage();
ProcessPackage构造函数启动了线程:
packThread=newThread(newThreadStart(DoProcessPackWork));//数据包队列处理线
从队列里面取出一包并解包:
lock(m_RecivePackQue.SyncRoot)
{
ps=(PackStruct)(m_RecivePackQue.Dequeue());
}
_ProcessPackage(ps);
分为解单包和组合包:
组合包拆成单包由单包来解。
单包是按控制码分了30多种
每种安排一个事件去处理。
Acq开了3个线程
_connectCheckThread
_heartbeatThread
_cmdHeartbeatThread
m_RealTimeDataList.Add(dtData);
List
RealTimeData实时数据到底保存了什么?
BatteryDataBlock
publicushortBatteryTemperature{get;set;}
publicintCapacitance{get;set;}
publicshort[]CircleNoArray{get;set;}
publicintCurrent{get;set;}
publicbyteDevCommState{get;set;}
publicintEnergy{get;set;}
publicbyteErrorState1{get;set;}
publicbyteErrorState2{get;set;}
publicintHasExecutedTime{get;set;}
publicintInitFlag{get;set;}
publicintLoadResistance{get;set;}
publicintPower{get;set;}
publicshortTotalCircleLayer{get;set;}
publicDateTimeUpdateTime{get;set;}
publicintVolt{get;set;}
publicbyteWorkState{get;set;}
publicstringWorkStateDesc{get;}
publicushortWorkStepNo{get;set;}
publicstaticRealTimeDataExplainSample(intcabinetNo,byte[]Rxbuffer,DateTimedtime)
{
RealTimeDatarealTimeData=newRealTimeData();
intiOffset=6;
byte[]twobyte=newbyte[2];
byte[]fourbyte=newbyte[4];
realTimeData.CabinetNo=cabinetNo;
realTimeData.SideNo=Rxbuffer[4];
realTimeData.UnitNo=Rxbuffer[5];
realTimeData.BatteryDataBlock.UpdateTime=dtime;
//recomstruct.Channel=boxNo.ToString("D2")+"-"+m.ToString("D2")+"-"+recomstruct.addr.ToString("D2");
//recomstruct.redata.flowNum=Rxbuffer[iOffset];//工步号
realTimeData.BatteryDataBlock.WorkStepNo=Rxbuffer[iOffset];//工步号
Array.Copy(Rxbuffer,iOffset+1,twobyte,0,2);
//recomstruct.redata.circleNo=DbOperation.baseFunction.HexToInt(twobyte);//循环序号
realTimeData.BatteryDataBlock.TotalCircleLayer=1;//写死
realTimeData.BatteryDataBlock.CircleNoArray=newshort[1];
realTimeData.BatteryDataBlock.CircleNoArray[0]=(short)HexToInt(twobyte);
//recomstruct.redata.flowName=GetflowName(Rxbuffer[iOffset+3]);//工作状态
//recomstruct.redata.runState=recomstruct.redata.flowName;
realTimeData.BatteryDataBlock.WorkState=Rxbuffer[iOffset+3];
Array.Copy(Rxbuffer,iOffset+4,twobyte,0,2);
//recomstruct.redata.volt=Convert.ToDecimal(DbOperation.baseFunction.HexToInt(twobyte));
realTimeData.BatteryDataBlock.Volt=Convert.ToInt32(HexToInt(twobyte));
//if(realTimeData.CabinetNo==3&&realTimeData.SideNo==1&&realTimeData.UnitNo==1&&realTimeData.BatteryDataBlock.WorkStepNo>0)
//{
//inta=0;
//}
Array.Copy(Rxbuffer,iOffset+6,fourbyte,0,4);
//recomstruct.redata.current=Convert.ToDecimal(DbOperation.baseFunction.HexToInt(fourbyte));
realTimeData.BatteryDataBlock.Current=Convert.ToInt32(HexToInt(fourbyte));
Array.Copy(Rxbuffer,iOffset+10,fourbyte,0,4);
//recomstruct.redata.capacitanceCharge=Convert.ToDecimal(DbOperation.baseFunction.HexToInt(fourbyte));
if(realTimeData.BatteryDataBlock.WorkState==0X01||realTimeData.BatteryDataBlock.WorkState==0X02||
realTimeData.BatteryDataBlock.WorkState==0X08||realTimeData.BatteryDataBlock.WorkState==0X05)
{
realTimeData.BatteryDataBlock.Capacitance=Convert.ToInt32(HexToInt(fourbyte));
}
Array.Copy(Rxbuffer,iOffset+14,fourbyte,0,4);
if(realTimeData.BatteryDataBlock.WorkState==0X03)
{
//recomstruct.redata.capacitanceDischarge=Convert.ToDecimal(DbOperation.baseFunction.HexToInt(fourbyte));
realTimeData.BatteryDataBlock.Capacitance=Convert.ToInt32(HexToInt(fourbyte));
}
Array.Copy(Rxbuffer,iOffset+18,fourbyte,0,4);
//recomstruct.redata.energyCharge=Convert.ToDecimal(DbOperation.baseFunction.HexToInt(fourbyte));
if(realTimeData.BatteryDataBlock.WorkState==0X01||realTimeData.BatteryDataBlock.WorkState==0X02||
realTimeData.BatteryDataBlock.WorkState==0X08||realTimeData.BatteryDataBlock.WorkState==0X05)
{
realTimeData.BatteryDataBlock.Energy=Convert.ToInt32(HexToInt(fourbyte));
}
Array.Copy(Rxbuffer,iOffset+22,fourbyte,0,4);
//recomstruct.redata.energyDischarge=Convert.ToDecimal(DbOperation.baseFunction.HexToInt(fourbyte));
if(realTimeData.BatteryDataBlock.WorkState==0X03)
{
//recomstruct.redata.capacitanceDischarge=Convert.ToDecimal(DbOperation.baseFunction.HexToInt(fourbyte));
realTimeData.BatteryDataBlock.Energy=Convert.ToInt32(HexToInt(fourbyte));
}
realTimeData.BatteryDataBlock.ErrorState1=Rxbuffer[iOffset+26];
realTimeData.BatteryDataBlock.ErrorState2=Rxbuffer[iOffset+27];
Array.Copy(Rxbuffer,iOffset+28,twobyte,0,2);
realTimeData.BatteryDataBlock.HasExecutedTime=HexToInt(twobyte);
//recomstruct.redata.runMinute=DbOperation.baseFunction.HexToInt(twobyte);//当前工步运行时间
//Stat=Rxbuffer[iOffset+30];//通讯标志0x000xff:
中断,增加0xfe,校准状态
realTimeData.BatteryDataBlock.DevCommState=Rxbuffer[iOffset+30];
//if(Stat==0xff)
//{
//recomstruct.redata.errorState+="通讯中断&";
//recomstruct.err=true;
//}
//if(Stat==0xfe)
//{
//recomstruct.redata.errorState+="设备校准&";
//}
returnrealTimeData;
}
柜子信息(CabinetInfo)和通讯电源(CommunicatePower)的区别:
publicclassCabinetInfo
{
publicCabinetInfo();
publicstringcabinet_name{get;set;}
publicintcabinet_no{get;set;}
publicshortchannel_count_ingroup{get;set;}
publicENUM_COMMUNICATION_TYPEcommunication_type{get;set;}
publicshortgroup_count{get;set;}
publicstringip_address{get;set;}
publicintip_port1{get;set;}
publicintip_port2{get;set;}
publicstringRemark{get;set;}
}
publicclassCommunicatePower
{
///
///柜号
///
Int32m_CabinetNo;
///
///IP地址
///
Stringm_IpAddress;
///
///端口1
///
Int32m_Port1;
///
///端口2
///
Int32m_Port2;
///
///构造
///
///柜编号
///IP地址
///端口1
///端口2
publicCommunicatePower(Int32cabinetNo,StringipAddress,intport1,intport2)
{
m_CabinetNo=cabinetNo;
m_IpAddress=ipAddress;
m_Port1=port1;
m_Port2=port2;
}
///
///客户端连接ID。
当ID=0的时候,断线状态
///
intm_ClientId1;
publicInt32ClientId1
{
get{returnm_ClientId1;}
set{m_ClientId1=value;}
}
///
///客户端连接ID。
当ID=0的时候,未断线状态
///
intm_ClientId2;
publicInt32ClientId2
{
get{returnm_ClientId2;}
set{m_ClientId2=value;}
}
///
///柜编号
///
publicInt32CabinetNo
{
get
{
returnm_CabinetNo;
}
}
///
///IP地址
///
publicStringIPAdress
{
get
{
returnm_IpAddress;
}
}
///
///端口1
///
publicInt32Port1
{
get
{
returnm_Port1;
}
}
///
///端口1
///
publicInt32Port2
{
get
{
returnm_Port2;
}
}
///
///访问锁,调用对象不可以修改
///
publicobjectSendDataLock1=newobject();
///
///访问锁,调用对象不可以修改
///
publicobjectSendDataLock2=newobject();
}
目的是区分开已连接设备和一共设备,我们只对连上设备进行数据交互。
CommunicatePower包括了属性:
编号、IP、端口1、端口2、ClientID1、ClientID2。
通讯上的设备。
CabinetInfo包括属性:
名称、编号、组数、没组个数、通讯类型、端口1、端口2、IP、说明(其实就是我们柜子配置要填入的信息,这些信息保存到SGGDeviceData.mdb文件的T_cabinet_info表里面)。
放在数据库里面的设备。
数据交流:
CommunicatePowercommPower=newCommunicatePower(cabinetNo,cabinetInfo.ip_address,cabinetInfo.ip_port1,cabinetInfo.ip_port2);
根据ClientID找出通讯设备。
可以通过设置ClientID来端口通讯设备连接。
privateCommunicatePowerFindCommunicatePower(intiClientID,outintport)
{
port=0;
if(iClientID<=0||m_CommunicatePowerList==null||m_CommunicatePowerList.Count<=0)
returnnull;
lock(m_CommunicatePowerListLock)
{
foreach(CommunicatePoweriteminm_CommunicatePowerList)
{
//if(item.ClientId1==iClientID||item.ClientId2==iClientID)
if(item.ClientId1==iClientID)
{
port=item.Port1;
returnitem;
}
if(item.ClientId2==iClientID)
{
port=item.Port2;
returnitem;
}
}
returnnull;
}
}
ClientID怎么赋值的:
[DllImport(@"IOCPEncapClient.dll")]
publicstaticexternintIConnect(StringipAddress,intport);
返回值就是一个ClientID。
if(commCabinet.ClientId1<=0&&_connectCheckThreadFlag==0X01)
{
if(!
TTCommonShare.TTCommonTools.PingIpOrDomainName(commCabinet.IPAdress))
continue;
}
的作用:
物理连接有没有连接上。
心跳包线程做了什么事
一个往端口1发0xEB,0x00,0x00,0xFF,0x01,0x01,0x14,0x55,一个往端口2发0xEB,0x00,0x00,0xFF,0x01,0x01,0x14,0x55。
为什么要发心跳包:
如果一段时间没有收到心跳包数据则认为与上位机断开连接。
保持长连接的常用做法。
privatevoidDoHeartBeatWork()
{
if(this.m_CommunicatePowerList==null||m_CommunicatePowerList.Count<=0)
return;
//如果没有建立连接,先进行连接
intsleepTime=2000/m_CommunicatePowerList.Count;
byte[]samplePacket=newByte[8]{0xEB,0x00,0x00,0xFF,0x01,0x01,0x14,0x55};
while(_heartbeatThreadFlag==0X01)
{
#region心跳包
//if(m_KAIO.isRun)
//{
foreach(CommunicatePowercommPowerinm_CommunicatePowerList)
{
Debug.Assert(commPower!
=null);
SendData(commPowe