电力DL476规约的实现 电力104规约

电力系统DL476规约本标准适用于电力系统调度(控制)中心之间以及调度(控制)中心与厂站之间的实时数据通讯,在网上关于规约的说明很多,但具体实现的资料很少。根据自己使用此规约的摸索,共享一点实现的资料给大家。
协议是以网络基础,网络层采用Tcp/IP协议,具体协议说明很长,可以看规范。实现主要是实现网络连接,发送数据和断开连接。
申请连接:控制域+运行模式+状态标识+原因码+参数域长度(低位)+参数域长度(高位)
每个都是一个字节长度8位,控制域0000001表示联系,0000100,表示释放,状态标识,本机在线与不在线,原因吗一般写0,如果不带参数全部写0.
传输数据使用基本数据apdu,报头+基本数据,其中报头是6个字节,报头为:控制域+接收序号(NR)+发送序号(NS)+优先级+数据长度(低)+数据长度(高)。控制域最高位为0表示是最后一个apdu,为1表示后续还有apdu。10表示数据,11表示数据确认,12表示数据否认。接收序号一般写0。发送序号是0开始,到255结束,循环执行。优先级一般写0,如果重要数据,双方约定优先级,数字越大,越优先。数据长度是后面整个数据库的长度,低位在前,高位在后面。这里用2个字节表示长度,所以注意转换。
数据块为:数据块类型+数据表索引号+数据块长度(低)+数据块长度(高)+数据项。数据库类型看规范。例如2表示传输是全部数据,数据是实数,数据表索引号是厂站的编号,数据长度是数据项的长度。这里报头的数据长度=数据块的长度+4.
对于具体规约,本文用c#代码实现了连接、释放、全数据传输和变化数据传输。
连接实现:
///
/// 确定连接,发送连接
///
///
public void SendConnect()
{
if (connected) return;//connedted为布尔变量,1 表示已经连接,0表示没有连接
byte[] data = new byte[6];
data[0]=1;//控制域,建立联系,不带参数
data[1]=42;//运行模式,01000101,1型规程,始发站为从站,变化遥测和变化要单信号单个传输
data[2] = 80;//本机在线
data[3] = 0;//原因码
//参数域长度为0
data[4] = 0;
data[5] = 0;
streamToClient.Write(data, 0,data.Length);
streamToClient.Flush();
streamToClient.Read(data, 0, data.Length);
if (Convert.ToInt16(data[0]) == 2)
{
connected = true;
SystemManagerment.Log("连接成功");

}
streamToClient.Flush();
}
传输全部数据实现:
///
/// 自动上传全部数据
///
public void AutoSendAllTag()
{

try
{
if (timeCount * heartTime < 300) return;//是否与上次全部传输相差5分钟
timeCount = 0;
//tagList是全局变量,由于涉及到多线程,所以在此处复制一份最新
ArrayList tempTagList = new ArrayList(tagList);
int tagCount = tempTagList.Count;
ushort dataLength = (ushort)(4+2 +tagCount * 5);
float tempVal = 0;
byte[] byteushorts=new byte[2];

int i = 0;
byte[] data = new byte[6 + 4+2 + tagCount * 5];
data[0] = 10;//基本数据
//SystemManagerment.Log("进入发送全数据: ");
//data[1] = receiveCount;//接收序号
data[1] = 0;
data[2] =changeReceiveCount;//发送序号
//data[2] = receiveCount;
//SystemManagerment.Log("全数据发送序号:"+changeReceiveCount.ToString());
changeReceiveCount++;
//SystemManagerment.Log("发送序号: "+receiveCount.ToString());
//if (receiveCount == 127) receiveCount = 0;
data[3] = 0;//优先级
//整个数据长度
data[4] = 0;
data[5] = 0;
byteushorts = BitConverter.GetBytes(dataLength);
//Array.Reverse(byteushorts);
Array.Copy(byteushorts, 0, data, 4, 2);

data[6] = 2;//全测量实型块
data[7] = 1;//厂站编号
//全遥测数据长度
data[8] = 0;
data[9] = 0;
dataLength = (ushort)(tagCount * 5+2);
byteushorts = BitConverter.GetBytes(dataLength);
//Array.Reverse(byteushorts);对数据进行高位与低位互换
Array.Copy(byteushorts, 0, data, 8, 2);
//遥测开始序号
data[10] = 1;
data[11] = 0;
foreach (TagInfor tagInfor in tempTagList)
{
tempVal =(float)tagInfor.tagVal;
Array.Copy(BitConverter.GetBytes(tempVal), 0, data, 12 + i * 5,4);
data[12 + i * 5+1] = 0;
}
streamToClient.Write(data, 0, data.Length);

SystemManagerment.Log("发送全部数据");
streamToClient.Flush();
}
catch (Exception ex)
{
connected = false;
SystemManagerment.Log("auto send all tag error:"+ex.Message);
}

}
传输变化数据
///
/// 上传变化数据
///
public void SendChangeData()
{
电力DL476规约的实现 电力104规约
try
{
int i =0;
ArrayList tempTagList = new ArrayList(tagList);
ArrayList changeTagList = new ArrayList();
TagInfor tempTagInfor = newTagInfor();
for (i = 0; i < tempTagList.Count; i++)
{
tempTagInfor = (TagInfor)tempTagList[i];
if (tempTagInfor.tagState == TagState.Good)
{
changeTagList.Add(tempTagInfor);
//SystemManagerment.Log("status :"+i.ToString()+""+tempTagInfor.tagState.ToString());
}
//SystemManagerment.Log("status :" + i.ToString() + " " +tempTagInfor.tagState.ToString()+"##:"+tempTagList.Count.ToString());
}
int tagCount = changeTagList.Count;
if (changeTagList.Count == 0) return;
ushort dataLength = (ushort)(4 + tagCount * 7);
float tempVal = 0;
byte[] byteushorts = new byte[2];
byte[] tagValue = new byte[4];

i=0;
byte[] data = new byte[6 + 4 + tagCount * 7];
data[0] = 10;//基本数据
//if(changeReceiveCount==0) data[1] = changeReceiveCount;
//else data[1]=(byte)(changeReceiveCount-1);//接收序号
//data[2] = (byte)(changeReceiveCount + 1);//发送序号
data[1] = 0;
data[2] = changeReceiveCount;
changeReceiveCount++;
//SystemManagerment.Log("发送序号: " + receiveCount.ToString());
//if (receiveCount == 127) receiveCount = 0;
data[3] = 0;//优先级
//整个数据长度
data[4] = 0;
data[5] = 0;
byteushorts = BitConverter.GetBytes(dataLength);
//Array.Reverse(byteushorts);
Array.Copy(byteushorts, 0, data, 4, 2);

data[6] = 8;//变化实型量
data[7] = 1;//厂站编号
//全遥测数据长度
data[8] = 0;
data[9] = 0;
dataLength = (ushort)(tagCount * 7 );
byteushorts = BitConverter.GetBytes(dataLength);
//Array.Reverse(byteushorts);
Array.Copy(byteushorts, 0, data, 8, 2);

//遥测开始序号
short tagid = 1;
foreach (TagInfor tagInfor in changeTagList)
{
tagid =(short) tagInfor.sequence;

byteushorts = BitConverter.GetBytes(tagid);
//Array.Reverse(byteushorts);
Array.Copy(byteushorts, 0, data, 10 + i * 7, 2);
tempVal = (float)tagInfor.tagVal;
//Random ra = new Random();
//tempVal =(float) ra.NextDouble()*100;
//SystemManagerment.Log("value:"+tempVal.ToString());
//data[12 + i * 7] = 0;
tagValue = BitConverter.GetBytes(tempVal);
//Array.Reverse(tagValue);
Array.Copy(tagValue, 0, data, 12 + i * 7, 4);
data[16 + i * 7] = 0;
i++;
}
streamToClient.Write(data, 0, data.Length);

//streamToClient.Flush();
}
catch (Exception ex)
{
connected = false;
SystemManagerment.Log("change send all tag error: " +ex.Message);
}
}
注意说明:
1对于tag的定义,程序中只取它的值,可以根据情况自己定义tag类。
2对于数据长度高低位,数据转换后,默认的是高位+低位,规范要求是低位+高位,具体看厂站程序的设定

  

爱华网本文地址 » http://www.aihuau.com/a/25101011/60352.html

更多阅读

MFC实习的QQ游戏“大家来找茬”游戏辅助工具的实现

转载请注明出处:这段时间GF一直在玩QQ找茬,看了一下,原理很简单,就是找到2附图片的不同之处,那么程序的思路也就很明了了,就是抓图,存入buffer,比较,显示,这么一个过程。闲话不多说了,下面我用MFC来实现它。首先先要拿到QQ找茬从窗口的句柄,拿到

Jsp中分页功能的实现 jsp 实现分页查询

分页查询功能一直是web编程中常用的技术,如何实现可重复使用而又简单的分页技术呢,下面的代码可以提供一些参考,实现用户列表的分页显示,当其它数据需分页显示时,可以复用其中的分页对象(SplitPage.java),然后提供实现dao接口的类.

二叉排序树的实现 二叉排序树的查找

二叉排序树的实现 分类: 数据结构 2012-08-12 20:42 265人阅读 评论(0) 收藏 举报nullinsertdeletetreeclass算法二叉排序树(Binary Sort Tree)又称二叉查找树。 它是一棵空树,或者是具有下列性质的二叉树:(1)若左子树不空,则左子树上所有结

声明:《电力DL476规约的实现 电力104规约》为网友如果忘了爱分享!如侵犯到您的合法权益请联系我们删除