AcqDataInterface学习Word文件下载.docx
《AcqDataInterface学习Word文件下载.docx》由会员分享,可在线阅读,更多相关《AcqDataInterface学习Word文件下载.docx(18页珍藏版)》请在冰点文库上搜索。
ps=(PackStruct)(m_RecivePackQue.Dequeue());
}
_ProcessPackage(ps);
分为解单包和组合包:
组合包拆成单包由单包来解。
单包是按控制码分了30多种
每种安排一个事件去处理。
Acq开了3个线程
_connectCheckThread
_heartbeatThread
_cmdHeartbeatThread
m_RealTimeDataList.Add(dtData);
List<
RealTimeData>
RealTimeData实时数据到底保存了什么?
BatteryDataBlock
publicushortBatteryTemperature{get;
set;
publicintCapacitance{get;
publicshort[]CircleNoArray{get;
publicintCurrent{get;
publicbyteDevCommState{get;
publicintEnergy{get;
publicbyteErrorState1{get;
publicbyteErrorState2{get;
publicintHasExecutedTime{get;
publicintInitFlag{get;
publicintLoadResistance{get;
publicintPower{get;
publicshortTotalCircleLayer{get;
publicDateTimeUpdateTime{get;
publicintVolt{get;
publicbyteWorkState{get;
publicstringWorkStateDesc{get;
publicushortWorkStepNo{get;
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("
+recomstruct.addr.ToString("
);
//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));
Array.Copy(Rxbuffer,iOffset+18,fourbyte,0,4);
//recomstruct.redata.energyCharge=Convert.ToDecimal(DbOperation.baseFunction.HexToInt(fourbyte));
realTimeData.BatteryDataBlock.Energy=Convert.ToInt32(HexToInt(fourbyte));
Array.Copy(Rxbuffer,iOffset+22,fourbyte,0,4);
//recomstruct.redata.energyDischarge=Convert.ToDecimal(DbOperation.baseFunction.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)
设备校准&
returnrealTimeData;
柜子信息(CabinetInfo)和通讯电源(CommunicatePower)的区别:
publicclassCabinetInfo
publicCabinetInfo();
publicstringcabinet_name{get;
publicintcabinet_no{get;
publicshortchannel_count_ingroup{get;
publicENUM_COMMUNICATION_TYPEcommunication_type{get;
publicshortgroup_count{get;
publicstringip_address{get;
publicintip_port1{get;
publicintip_port2{get;
publicstringRemark{get;
publicclassCommunicatePower
///<
summary>
///柜号
/summary>
Int32m_CabinetNo;
///IP地址
Stringm_IpAddress;
///端口1
Int32m_Port1;
///端口2
Int32m_Port2;
///构造
paramname="
cabinetNo"
>
柜编号<
/param>
ipAddress"
IP地址<
port1"
端口1<
port2"
端口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=0的时候,未断线状态
intm_ClientId2;
publicInt32ClientId2
get{returnm_ClientId2;
set{m_ClientId2=value;
///柜编号
publicInt32CabinetNo
get
returnm_CabinetNo;
publicStringIPAdress
returnm_IpAddress;
publicInt32Port1
returnm_Port1;
publicInt32Port2
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;
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<
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