“Internet of Things Framework Serversuperio Tutorial” -4. As developed a set of equipment drivers while support serial port and network communication. Attachment: Wanted Windows 10 IOT

1.C# Cross-platform Internet of Things Communication Framework ServerSuperIO (SSIO) Introduction

“Serial | Internet of Things Framework ServerSuperIO Tutorial” 1.4 communication mode mechanisms.

“Serial | Internet of Things Framework ServerSuperIO Tutorial” 2. Description of the configuration parameters of the service instance

“Serial | Internet of Things Framework ServerSuperIO Tutorial”-3. Device Driver Introduction

Note: ServerSuperIO may be ported to Windows 10 On IOT, it is possible to develop a set of device drivers in the future, which can be used in server and embedded devices to form a complete solution.

Now that part of the code has been debugged and passed, it will take some time, generally It is done at night, and time is limited. As shown below:

List of items

4. If you develop a device driver that supports both serial and network communication… 2

4.1 Overview… 2

4.2 Communication protocol regulations… 2

4.2.1 Send and read real-time data command protocol… 2

4.2.2 Analyze real-time data protocol… 3

4.2.3 Send and Examples of receiving data… 3

4.3 Develop device drivers… 3

4.3.1 Construct real-time data persistent objects (not required)… 3

< p>4.3.2 Constructing parameter data persistent objects… 5

4.3.3 Constructing sending and parsing protocol command objects… 5

4.3.4 Constructing protocol-driven objects. .. 6

4.3.5 Constructing the device driver object… 8

4.4 Constructing the host program… 12

4.5 Operation effect… 15

4. For example, to develop a set of device drivers that supports serial port and network communication at the same time

4.1 Overview

< p> As a communication framework for the Internet of Things, it must support multiple communication links, and complete the interaction of multiple communication protocols on the basis of multiple communication links, such as Modbus, custom protocols, and so on. However, there is a question: For the same hardware device or sensor, to complete the data collection and control of the serial port and network communication methods, do I need to write code separately? If you analyze from a realistic perspective, the same hardware must have the same business logic. Therefore, the ServerSuperIO IoT framework allows the development of a set of device drivers and supports the interaction of serial and network communication methods.

The communication is very simple, the interaction is very simple, the business is very simple… If many simple questions are put together, then it becomes not simple, so there must be a framework. Re-make many problems simple.

4.2 Communication protocol regulations

Before completing the development of a device driver, you must first know its communication protocol, which is like the language that two people communicate. For the communication protocol, we customize a simple interaction method, just send commands to extract data information.

4.2.1 Sending read real-time data command protocol

The computer sends 0x61 command as a read real-time data command, a total of 6 bytes are sent, and the checksum is the slave “Slave address” The starting cumulative sum does not include “data header”, “checksum” and “end of protocol”.

The sending command data frame is as follows:

Frame structure

Data header

Slave address

Command code

Checksum

End of agreement

0x55

0xAA

0x61

0x0D

bytes

1

< /td>

1

1

< /td>

1

1

< /td>

1

4.2.2 Analyze the real-time data protocol

After receiving the read real-time data command and verifying it successfully, the lower-level computer returns the real-time data. The checksum is the cumulative sum from the “Slave Address”, excluding “Data Header”, “Checksum” and “End of Protocol”.

The received data frame is as follows:

Frame structure

Data header< /strong>

Slave address

Command code

Traffic

strong>

Signal

Checksum

End of agreement

0x55

0xAA

0x61

Floating point

Floating point

0x0D

Bytes

1

1

1

1

4

4

1

1

4.2.3 Examples of sending and receiving data

Sending (hexadecimal): 0x55 0xaa 0x00 0x61 0x61 0x0d

Receiving (hexadecimal) ): 0x55 0xaa 0x00 0x61 0x43 0x7a 0x00 0x00 0x43 0xb4 0x15 0x0d

The flow data is: 250.00

The signal data is: 360.00

4.3 Development device driver< /h2>

4.3.1 Constructing real-time data persistent objects (not necessary)

1. Through the communication protocol of returning data, there are two dynamic variables of flow and signal, we need to create a dynamic object entity The class is mainly used for data interaction between the protocol driver and the device driver. The code is as follows:

1
2

< div class="line number3 index2 alt2"> 3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 < /div>

21
public class Dyn
{
private float _Flow = 0.0f;
/code> ///

/// Traffic
///

public float code> Flow
{
get { return _Flow; }
set { _Flow = value; }
}
private float _Signal = 0.0f;
/ //

/// Signal
///

code>

public float Signal
{
get { return _Signal; }
set { _Signal = value; }< /code>
}
}

< /div>

2. Our main job is to create a real-time data persistent object class to cache data information in real time, or save the real-time data information to a database or other storage media. The code of the real-time data persistent object class is as follows:

1
2
3
4
5 < /div>

6
7
8
9
10
11
12
13
14
15
16
public class DeviceDyn:DeviceDynamic
{

< div class="line number3 index2 alt2"> public DeviceDyn(): base ()

{
Dyn= new Dyn();
}
public override string GetAlertState()
{
throw new NotImplementedException( "No alarm information" );
);
code> }
public override object Repair()
{
return new DeviceDyn();
}
public Dyn Dyn { get ; set ; }
}

The DeviceDyn class inherits from DeviceDynamic, because the alarm information of each hardware device may be different, so the GetAlertState function can do it Function, but the SSIO framework does not directly reference; this class is essentially a serializable, which may cause file damage without mutual exclusion, so Repair can complete the repair function, which is implemented in the DeviceDynamic base class; In addition, the realization of the DeviceDynamic base class comes with two functions, the Save function is used to persist (serialize) this type of information, and Load is used to obtain (deserialize) this type of information, which can be used in the device driver.

4.3.2 Constructing parameter data persistent objects

Generally, hardware devices have commands to read parameters, so the returned parameters also need to be persistently stored, and each device The parameters may be different, an extensible interface is provided here. In this communication protocol, there is no protocol description related to device parameters, but we also need to create a parameter data persistent object class, which does not need to write any extended parameter attributes. The parameter interface is referenced in the SSIO framework. This is Work must be done. The code is as follows:

1
2

< div class="line number3 index2 alt2"> 3

4
5
6
7
< div class="line number1 index0 alt2"> public class DevicePara:ServerSuperIO.Device.DeviceParameter
{
public override object Repair()
{
return new DevicePara();
}
}

DevicePara Inherited from the DeviceParameter class, the situation is similar to the real-time data persistent object, which can be parameterized.

4.3.3 Constructing the sending and parsing protocol command object

Interacting with the device will involve many interactive commands or command codes, and these commands are based on protocols in the SSIO framework. The form of the command object generally includes three parts: execute command interface, package and send data interface, analyze and receive data interface and so on.

For the above communication protocol, there is a 61 command, then we can build a protocol command object for the naming according to the 61 command, including sending data and parsing data. If there are other command codes, draw inferences about them. The code is as follows:

1
2

< div class="line number3 index2 alt2"> 3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33

34
35
36
37
internal class DeviceCommand:ProtocolCommand
{
public override string Name
{
get { return "61" ; }
}
public override void ExcuteCommand(T t)
{
throw new NotImplementedException();
}
public override < code class="csharp keyword">byte [] Package ( string code, T1 t1,T2 t2)
{
//Send: 0x55 0xaa 0x00 0x61 0x61 0x0d
byte [] data = new byte [6];
data[0 ] = 0x55;
             data[1] = 0xaa;
             data[2] = byte .Parse(code);
             data[3] = 0x61;
             data[4] = this .ProtocolDriver.GetCheckData(data)[0];
             data[5] = 0x0d;
             return data;
         }
 
         public override dynamic Analysis( byte [] data, T t)

         {
             Dyn dyn = new Dyn()
             //一般下位机是单片的话,接收到数据的高低位需要互换,才能正常解析。
             byte [] flow = BinaryUtil.SubBytes(data, 4, 4, true );
             dyn.Flow = BitConverter.ToSingle(flow, 0);
             byte [] signal = BinaryUtil.SubBytes(data, 8, 4, true );
             dyn.Signal = BitConverter.ToSingle(signal, 0);
             return dyn;
         }
 
}

     构建协议命令需要全部继承自ProtocolCommand,根据通讯协议规定,Name属性返回61,作为关键字;Package是打包要送的数据信息;Analysis对应着接收数据之后进行解析操作。就这样一个简单的协议命令驱动就构建完成了。

4.3.4    构建协议驱动对象

    有了协议命令之后,我们需要构建协议驱动对象,SSIO框架支持自定义协议也在于此,并且与设备驱动的接口相关联,在SSIO框架的高级应用中也进行了引用,构建这引对象很关键。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
internal class DeviceProtocol:ProtocolDriver
{
         public override bool CheckData( byte [] data)
         {
             if (data[0] == 0x55 && data[1] == 0xaa && data[data.Length - 1] == 0x0d)
             {
                 return true ;
             }
             else
             {
                 return false ;
             }
         }
 
         public override byte [] GetCommand( byte [] data)
         {
             return new byte [] { data[3] };
         }
 
         public override int GetAddress( byte [] data)
         {
             return data[2];
         }
 
         public override byte [] GetHead( byte [] data)
         {
             return new byte [] { data[0], data[1] };
         }
 
         public override byte < code class="csharp plain">[] GetEnd( byte [] data)
         {
             return new byte [] { data[data.Length - 1] };
         }
 
         public override byte [] GetCheckData( byte [] data)
         {
             byte checkSum = 0;
             for ( int i = 2; i < data.Length - 2; i++)
             {
                 checkSum += data[i];
             }
             return new byte [] { checkSum };

         }

 
         public override string GetCode( byte [] data)
         {
             throw new NotImplementedException();
         }
 
         public override int GetPackageLength( byte [] data, IChannel channel, ref int readTimeout)
         {
            throw new NotImplementedException();
         }
}

     DeviceProtocol 协议驱动继承自ProtocolDriver ,一个设备驱动只存在一个协议驱动,一个协议驱动可以存在多个协议命令(如61命令)。该类中的CheckData函数很关键,SSIO框架中的设备驱动基类引用了,主要是完成校验接收数据的完事性,是否符合协议,从而决定了通讯状态:通讯正常、通讯中断、通讯干扰、以及通讯未知,不同的通讯状态也决定了调用设备驱动中的哪个函数接口:Communicate、CommunicateInterrupt、CommunicateError和CommunicateNone。

4.3.5    构建设备驱动对象

     上边的基础工作都做完之后,现在就构建设备驱动的核心部分,也就是SSIO框架与设备驱动对接、协调、调度的唯一接口,写完这个接口,设备驱动就可以在SSIO上直接运行了,并且与硬件设备进行交互。直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
public class DeviceDriver:RunDevice
{
         private DeviceDyn _deviceDyn;
         private DevicePara _devicePara;
         private DeviceProtocol _protocol;
         public DeviceDriver() : base ()
         {
             _devicePara = new DevicePara();
             _deviceDyn = new DeviceDyn();

             _protocol = new DeviceProtocol();

         }
 
         public override void Initialize( string devid)
         {
             this .Protocol.InitDriver( this .GetType(), null );
             //初始化设备参数信息
             _devicePara.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的参数文件。
             if (System.IO.File.Exists(_devicePara.SavePath))
             {
                 //如果参数文件存在,则获得参数实例
                 _devicePara = _devicePara.Load();
             }
             else
             {
                 //如果参数文件不存在,则序列化一个文件
                 _devicePara.Save(_devicePara);
             }
 
             //初始化设备实时数据信息
             _deviceDyn.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的实时数据文件。
             if (System.IO.File.Exists(_deviceDyn.SavePath))
             {
                 //参数文件存在,则获得参数实例
                 _deviceDyn = _deviceDyn.Load();
             }
             else
             {
                 //如果参数文件不存在,则序列化一个文件
                 _deviceDyn.Save(_deviceDyn);
             }
         }
  
         public override byte [] GetConstantCommand()
         {
             return this .P rotocol.DriverPackage( "0" , "61" , null );
         }
  
         public override void Communicate(ServerSuperIO.Communicate.IRequestInfo info)

         {
             Dyn dyn = this .Protocol.DriverAnalysis( "61" , info.Data, null );
             if (dyn != null )
             {
                 _deviceDyn.Dyn = dyn;
             }
             OnDeviceRuningLog( "通讯正常" );
         }
 
         public override void CommunicateInterrupt(ServerSuperIO.Communicate.IRequestInfo info)
         {
             OnDeviceRuningLog( "通讯中断" );
         }
  
         public override void CommunicateError(ServerSuperIO.Communicate.IRequestInfo info)
         {
             OnDeviceRuningLog( "通讯干扰" );
         }
  
         public override void CommunicateNone()
         {
             OnDeviceRuningLog( "通讯未知" );
         }
 
         public override void Alert()
         {
             return ;
         }
 
         public override void Save()
         {
             try
             {
                 _deviceDyn.Save(_deviceDyn);
             }
             catch (Exception ex)
             {
                 OnDeviceRuningLog(ex.Message);
             }
         }
 
         public override void Show()
         < code class="csharp plain">{
             List< string > list= new List< string >();
             list.Add(_devicePara.DeviceName);
             list.Add(_deviceDyn.Dyn.Flow.ToString());
             list.Add(_deviceDyn.Dyn.Signal.ToString());
             OnDeviceObjectChanged(list.ToArray());
         }
  
         public override void UnknownIO()
         {
             OnDeviceRuningLog( "未知通讯接口" );
         }
 
         public override void CommunicateStat eChanged(ServerSuperIO.Communicate.CommunicateState comState)
         {
             OnDeviceRuningLog( "通讯状态改变" );
         }
 
         public override void ChannelStateChanged(ServerSuperIO.Communicate.ChannelState channelState)
         {
             OnDeviceRuningLog( "通道状态改变" );
         }
 
         public override void Exit()
         {
             OnDeviceRuningLog( "退出设备" );
         }
 
         public override void Delete()
         {
             OnDeviceRuningLog( "删除设备" );
         }
  

         public override object GetObject()
         {
             throw new NotImplementedException();
         }
 
         public override void ShowContextMenu()
         {
             throw new NotImplementedException();
         }
 
         public override IDeviceDynamic DeviceDynamic
         {
             get { return _deviceDyn; }
         }
 
         public override IDeviceParameter DeviceParameter
         {
             get { return _devicePara; }
         }
 
         public override IProtocolDriver Protocol
        {
             get { return _proto col;}
         }
 
         public override DeviceType DeviceType
         {
             get { return DeviceType.Common; }
         }
 
         public override string ModelNumber
         {
             get { return "serversuperio" ; }
         }
 
         public override System.Windows.Forms.Control DeviceGraphics
         {
             get { throw new NotImplementedException(); }
         }
}

    实时动态数据对象_deviceDyn、参数数据对象_devicePara、协议驱动对象_protocol分别提供给接口:DeviceDynamic、DeviceParameter和Protocol,为SSIO提供可引用的基础属性参数。

     Initialize是设备驱动初始化的函数接口,在这个接口完成两个主要工作:初始化协议驱动和参数性的信息。通过this.Protocol.InitDriver(this.GetType(),null);代码可以加载所有协议命令到协议驱动的缓存中,以便实时调用。当然这里边也可以进行其他方面的工作,但是注意对异常的处理。

     DeviceType这个是设备的类型,一般指定为Common就好了。其他函数接口功能已经在《物联网框架ServerSuperIO教程-3.设备驱动介绍》中详细介绍了,请参考。

4.4    构建宿主程序

     一个简单的设备驱动就已经开发好了,光有驱动还不行,那么我们基于SSIO框架再写几行代码,完成一个宿主程序,把设备驱动实例化,放SSIO的服务实例中运行,完成串口和网络两种方式的通讯交互,代码也非常简单。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class Program
{
         static void Main( string [] args)
         {
             DeviceDriver dev1 = new DeviceDriver();
             dev1.DeviceParameter.DeviceName = "串口设备1" ;
             dev1.DeviceParameter.DeviceAddr = 0;
             dev1.DeviceParameter.DeviceID = "0" ;
             dev1.DeviceDynamic.DeviceID = "0" ;
             dev1.DeviceParameter.COM.Port = 1;
             dev1.DeviceParameter.COM.Baud = 9600;
             dev1.CommunicateType = CommunicateType.COM;
             dev1.Initialize( "0" );
 
             DeviceDriver dev4 = new DeviceDriver();
             dev4.DeviceParameter.DeviceName = "网络设备2" ;
             dev4.DeviceParameter.DeviceAddr = 0;
             dev4.DeviceParameter.DeviceID = "3" ;
             dev4.DeviceDynamic.DeviceID = "3" ;
             dev4.DeviceParameter.NET.RemoteIP = "127.0.0.1" ;
             dev4.DeviceParameter.NET.RemotePort = 9600;
             dev4.CommunicateType = CommunicateType.NET;
             dev4.Initialize( "3" );
 
             IServer server = new ServerFactory().CreateServer( new ServerConfig()
             {
                 ServerName = "服务实例1" ,
                 SocketMode = SocketMode.Tcp,
                 ControlMode = ControlMode.Loop,
                 CheckSameSocketSession = false ,
                 StartCheckPa ckageLength = false ,
             });
 
             server.AddDeviceCompleted += server_AddDeviceCompleted;
             server.DeleteDeviceCompleted += server_DeleteDeviceCompleted;
             server.SocketCo nnected+=server_SocketConnected;
             server.SocketClosed+=server_SocketClosed;
             server.Start();
 
             server.AddDevice(dev1);
             server.AddDevice(dev4);
 

< div class="line number43 index42 alt2">              while ( "exit" ==Console.ReadLine())

             {
                  server.Stop();
             }
         }
 
         private static void server_SocketClosed( string ip, int port)
         {
             Console.WriteLine(String.Format( "断开:{0}-{1} 成功" , ip, port));
         }
 
         private static void server_SocketConnected( string ip, int port)
         {
             Console.WriteLine(String.Format( "连接:{0}-{1} 成功" ,ip, port));
         }
 
         private static void server_AddDeviceCompleted( < code class="csharp keyword">string devid, string devName, bool isSuccess)
 
         {
             Console.WriteLine(devName+ ",增加:" +isSuccess.ToString());
         }
 
         private static void server_DeleteDeviceCompleted( string devid, string devName, bool isSuccess)
         {
             Console.WriteLine(devName + ",删除:" + isSuccess.ToString());
         }
     }
}

     这个代码大家都能看明白,具体的控制模式我们接下来会一一介绍。在构建宿主程序的时候,切忌对服务实例这样引用:server.ChannelManager、server.ControllerManager、server.DeviceManager。尽管提供了这样的接口,主要是为了SSIO框架内部使用的,不需要我们单独去操作这些接口。有的网友是这样的写的,那么就变成了一个纯的通信IO框架,那么就失去了SSIO框架本身的价值。作为二次开发者,只需要设置设备驱动的参数,以及向服务实例中增加或删除设备就行了,其他所有的运行全部交给SSIO框架来完成。

4.5    运行效果

 

 

1.[连载]《C#通讯(串口和网络)框架的设计与实现》

2.[开源]C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍

2.应用SuperIO(SIO)和开源跨平台物联网框架ServerSuperIO(SSIO)构建系统的整体方案

3.C#工业物联网和集成系统解决方案的技术路线(数据源、数据采集、数据上传与接收、ActiveMQ、Mongodb、WebApi、手机App)

5.ServerSuperIO开源地址:https://github.com/wxzz/ServerSuperIO

物联网&集成技术(.NET) QQ群54256083

1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍

《连载 | 物联网框架ServerSuperIO教程》1.4种通讯模式机制。

《连载 | 物联网框架ServerSuperIO教程》2.服务实例的配置参数说明

《连载 | 物联网框架ServerSuperIO教程》- 3.设备驱动介绍

 

注:ServerSuperIO有可能被移植到Windows 10 IOT上,那么将来有可能开发一套设备驱动,可以支行在服务端、嵌入式设备中,将形成完整的解决方案。

      现在已经调试通过部分代码,还得需要一段时间,一般都是晚上干,时间也有限。如下图:

 

目       录

4.如开发一套设备驱动,同时支持串口和网络通讯... 2

4.1           概述... 2

4.2           通讯协议规定... 2

4.2.1    发送读实时数据命令协议... 2

4.2.2    解析实时数据协议... 3

4.2.3    发送和接收数据事例... 3

4.3           开发设备驱动... 3

4.3.1    构建实时数据持久对象(不是必须)... 3

4.3.2    构建参数数据持久对象... 5

4.3.3    构建发送和解析协议命令对象... 5

4.3.4    构建协议驱动对象... 6

4.3.5    构建设备驱动对象... 8

4.4           构建宿主程序... 12

4.5           运行效果... 15

 

 

4.如开发一套设备驱动,同时支持串口和网络通讯

4.1    概述

     作为物联网通讯框架,肯定要支持多种通讯链路,在多种通讯链路的基础上完成多种通讯协议的交互,例如:Modbus、自定义协议等等。但是,有一个问题:针对同一台硬件设备或传感器,完成串口和网络两种通讯方式的数据采集和控制,是否要分别写代码? 如果从现实角度分析,同一硬件,它要完成的业务逻辑肯定是相同的,所以ServerSuperIO物联网框架,允许开发一套设备驱动,同时支持串口和网络两种通讯方式的交互。

     通讯很简单、交互很简单、业务很简单……如果把很多简单的问题合在一起,那么就变得不简单了,所以要有一个框架性的东西,重新把众多问题变得简单。

4.2    通讯协议规定

    在完成一个设备驱动的开发之前,首先要知道它的通讯协议,好比两个人交流的语言一样。针对通讯协议,我们自定义一个简单交互方式,只是发送命令,提取数据信息。

4.2.1    发送读实时数据命令协议

     计算机发送0x61指令为读实时数据命令,共发送6个字节,校验和为从“从机地址”开始的累加和,不包括“数据报头”、“校验和”和“协议结束”。

     发送指令数据帧如下:

帧结构

数据报头

从机地址

指令代码

校验和

协议结束

0x55

0xAA

 

0x61

 

0x0D

字节数

1

1

1

1

1

1

  

4.2.2    解析实时数据协议

    下位机接收到读实时数据命令后,并校验成功,返回实时数据,校验和为从“从机地址”开始的累加和,不包括“数据报头”、“校验和”和“协议结束”。

    接收数据帧如下:

帧结构

数据报头

从机地址

指令代码

流量

信号

校验和

协议结束

0x55

0xAA

 

0x61

浮点型

浮点型

 

0x0D

字节数

1

1

1

1

4

 

4

1

1

4.2.3    发送和接收数据事例

发送(十六进制):0x55 0xaa 0x00 0x61 0x61 0x0d

接收(十六进制):0x55 0xaa 0x00 0x61 0x43 0x7a 0x00 0x00 0x43 0xb4 0x15 0x0d

流量数据为:250.00

信号数据为:360.00

4.3    开发设备驱动

4.3.1    构建实时数据持久对象(不是必须)

1.通过返回数据的通讯协议,有流量和信号两个动态变量,我们需要创建一个动态对象实体类,主要用于协议驱动与设备驱动之间的数据交互。代码如下:

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
public class Dyn
{
         private float _Flow = 0.0f;
         ///

         /// 流量
         ///

         public float Flow
         {
             get { return _Flow; }
             set { _Flow = value; }
         }
         private float _Signal = 0.0f;
         ///

         /// 信号
         ///

         public float Signal
         {
             get { return _Signal; }
             set { _Signal = value; }
         }

< div class="line number21 index20 alt2"> }

  2.我们主要的工作是要创建一个实时数据持久对象类,实时缓存数据信息,也可以把该实时数据信息保存到数据库中或其他存储媒质。实时数据持久对象类的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class DeviceDyn:DeviceDynamic
{
         public DeviceDyn() : < code class="csharp keyword">base ()
         {
             Dyn= new Dyn();
         }
         public override string GetAlertState()
         {
             throw new NotImplementedException( "无报警信息" );
         }
         public override object Repair()
         {
             return new DeviceDyn();
         }
         public Dyn Dyn { get ; set ; }
}

     DeviceDyn 类继承自DeviceDynamic,因为每个硬件设备的报警信息有可能不一样,所以GetAlertState函数可以实该功能,但是SSIO框架并没有直接引用;这个类本质上是一个可以序列化,在不加互斥的情况下可能造成文件损坏,所以Repair可以完成修复功能,在DeviceDynamic基类里实现了该功能;另外,实现DeviceDynamic基类自带两个函数,Save函数用于持久化(序列化)此类的信息,Load用于获得(反序列化)此类的信息,在设备驱动中可以使用。

4.3.2    构建参数数据持久对象

    一般来说硬件设备会有读参数的命令,那么返回来的参数也需要进行持久化存储,并且每台设备的参数都可能不一样,在此提供一个可扩展的接口。在这个通讯协议中并没有涉及到设备参数相关的协议说明,但是我们也需要创建一个参数数据持久对象类,可以不写任何扩展的参数属性,在SSIO框架对参数的接口进行了引用,这是必须进行了工作。代码如下:

1
2
3
4
5
6
7
public class DevicePara:ServerSuperIO.Device.D eviceParameter
{
         public override object Repair()
         {
             return new DevicePara();
         }
}

     DevicePara继承自DeviceParameter类,情况与实时数据持久对象类似,可以参数。

4.3.3    构建发送和解析协议命令对象

    与设备进行交互会涉及到很多交互式的命令或指令代码,而这些命令在SSIO框架内是以协议命令对象的形式存在,大体包括三个部:执行命令接口、打包发送数据接口、解析接收数据接口等。

    针对上面的通讯协议,有一个61指令,那么我们就可以根据61指令为命名构建一个协议命令对象,包括发送数据和解析数据部分。如果有其他命令代码,举一反三。代码如下:

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
internal class DeviceCommand:ProtocolCommand
{
         public override string Name
         {
             get { < code class="csharp keyword">return "61" ; }
         }
 
         public override void ExcuteCommand(T t)
         {
             throw new NotImplementedException();
         }
 
         public override byte [] Package ( string code, T1 t1,T2 t2)
         {
             //发送:0x55 0xaa 0x00 0x61 0x61 0x0d
             byte [] data = new byte [6];
             data[0] = 0x55;
             data[1] = 0xaa;
             data[2] = byte .Parse(code);
             data[3] = 0x61;
             data[4] = this .ProtocolDriver.GetCheckData(data)[0];
             data[5] = 0x0d;
            < /code> return data;
         }
 
         public override dynamic Analysis( byte [] data, T t)
         {
             Dyn dyn = new Dyn()
             //一般下位机是单片的话,接收到数据的高低位需要互换,才能正常解析。
             byte [] flow = BinaryUtil.SubBytes(data, 4, 4, true );
             dyn.Flow = BitConverter.ToSingle(flow, 0);
             byte [] signal = BinaryUtil.SubBytes(data, 8, 4, true );
             dyn.Signal = BitConverter.ToSingle(signal, 0);
             return dyn;
         }
 
}

     构建协议命令需要全部继承自ProtocolCommand,根据通讯协议规定,Name属性返回61,作为关键字;Package是打包要送的数据信息;Analysis对应着接收数据之后进行解析操作。就这样一个简单的协议命令驱动就构建完成了。

4.3.4    构建协议驱动对象

    有了协议命令之后,我们需要构建协议驱动对象,SSIO框架支持自定义协议也在于此,并且与设备驱动的接口相关联,在SSIO框架的高级应用中也进行了引用,构建这引对象很关键。代码如下:

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
internal class DeviceProtocol:ProtocolDriver
{
         public override bool CheckData( byte [] data)
         {
             if (data[0] == 0x55 && data[1] == 0xaa && data[data.Length - 1] == 0x0d)
             {
                 return true ;
             }
             else
             {
                 return false ;
             }
         }
 
         public override byte [] GetCommand( byte [] data)
         {
             return new byte [] { data[3] };
         }
 
         public override int GetAddress( byte [] data)
         {
             return data[2];

         }
 
         public override byte [] GetHead( byte [] data)
         {
             return new byte [] { data[0], data[1] };
         }
 
         public override byte [] GetEnd( byte [] data)
         {
             return new byte [] { data[data.Length - 1] };
         }
 
         public override byte [] GetCheckData( byte [] data)
         {
             byte checkSum = 0;
             for ( int i = 2; i < data.Length - 2; i++)
             {
                 checkSum += data[i];
             }
             return new byte [] { checkSum };
         }
 
         public override string GetCode( byte [] data)
         {
             throw new NotImplementedException();
         }
 
         public override int GetPackageLength( byte [] data, IChannel channel, ref int readTimeout)
         {
            throw new NotImplementedException();
         }
}

     DeviceProtocol 协议驱动继承自ProtocolDriver ,一个设备驱动只存在一个协议驱动,一个协议驱动可以存在多个协议命令(如61命令)。该类中的CheckData函数很关键,SSIO框架中的设备驱动基类引用了,主要是完成校验接收数据的完事性,是否符合协议,从而决定了通讯状态:通讯正常、通讯中断、通讯干扰、以及通讯未知,不同的通讯状态也决定了调用设备驱动中的哪个函数接口:Communicate、CommunicateInterrupt、CommunicateError和CommunicateNone。

4.3.5    构建设备驱动对象

     上边的基础工作都做完之后,现在就构建设备驱动的核心部分,也就是SSIO框架与设备驱动对接、协调、调度的唯一接口,写完这个接口,设备驱动就可以在SSIO上直接运行了,并且与硬件设备进行交互。直接上代码:

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

94

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
public class DeviceDriver:RunDevice
{
         private DeviceDyn _deviceDyn;
         private DevicePara _devicePara;
         private DeviceProtocol _protocol;
         public DeviceDriver() : base ()
         {
             _devicePara = new DevicePara();
             _deviceDyn = new DeviceDyn();
             _protocol = new DeviceProtocol();
         }
 
         public override void Initialize( string devid)
         {
             this .Protocol.InitDriver( this .GetType(), null );
             //初始化设备参数信息
             _devicePara.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的参数文件。
             if (System.IO.File.Exists(_devicePara.SavePath))
             {
                 //如果参数文件存在,则获得参数实例
                 _devicePara = _devicePara.Load();
             }
             else
             {
                 //如果参数文件不存在,则序列化一个文件
                 _devicePara.Save(_devicePara);
             }
 
             //初始化设备实时数据信息
             _deviceDyn.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的实时数据文件。
             if (System.IO.File.Exists(_deviceDyn.SavePath))
             {
                 //参数文件存在,则获得参数实例
                 _deviceDyn = _deviceDyn.Load();
             }
             else
             {
                 //如果参数文件不存在,则序列化一个文件
                 _deviceDyn.Save(_deviceDyn);
             }
         }
  
         public override byte [] GetConstantCommand()
         {
             return this .Protocol.DriverPackage( "0" , "61" , null );
         }
  
         public override void Communicate(ServerSuperIO.Communicate.IRequestInfo info)
         {
             Dyn dyn = this .Protocol.DriverAnalysis( "61" , info.Data, null );
             if (dyn != null )
            < /code> {
                 _deviceDyn.Dyn = dyn;
             }
             OnDeviceRuningLog( "通讯正常" );
         }
 
         public override void CommunicateInterrupt(ServerSuperIO.Communicate.IRequestInfo info)
         {
             OnDeviceRuningLog( "通讯中断" );
         }
  
         public override void CommunicateError(ServerSuperIO.Communicate.IRequestInfo info)
         {
             OnDeviceRuningLog( "通讯干扰" );
         }
  
         public override void CommunicateNone()
         {
             OnDeviceRuningLog( "通讯未知" );
         }
 
         public override void Alert()
         {
             return ;
         }
 
         public override void Save()
         {
             try
             {
                 _deviceDyn.Save(_deviceDyn);
             }
             catch (Exception ex)
             {
                 OnDeviceRuningLog(ex.Message);
             }
         }
 
         public override void Show()
         {
             List< string > list= new List< string >();
             list.Add(_devicePara.DeviceName);
             list.Add(_deviceDyn.Dyn.Flow.ToString());
             list.Add(_deviceDyn.Dyn.Signal.ToString());
             OnDeviceObjec tChanged(list.ToArray());
         }
  
         public override void UnknownIO()
         {
             OnDeviceRuningLog( "未知通讯接口" );
         }
 
         public override void CommunicateStateChanged(ServerSuperIO.Communicate.CommunicateState comState)
         {
             OnDeviceRuningLog( "通讯状态改变" );
         }
 
         public override void ChannelStateChanged(ServerSuperIO.Communicate.ChannelState channelState)
         {
             OnDeviceRuningLog( "通道状态改变" );
         }
 
         public override void Exit()
         {

             OnDeviceRuningLog( "退出设备" );

         }
 
         public override void Delete()
         {

             OnDeviceRuningLog( "删除设备" );
         }
  
         public override object GetObject()
         {
             throw new NotImplementedException();
         }
 
         public override void ShowContextMenu()
         {
             throw new NotImplementedException();
         }
 
         public override IDeviceDynamic DeviceDynamic
         {
             get { return _deviceDyn; }
         }
 
         public override IDeviceParameter DeviceParameter
         {
             get { return _devicePara; }
         }
 
         public override IProtocolDriver Protocol
        {
             get { return _protocol;}
         }
 
         public override DeviceType DeviceType

         {
             get { return DeviceType.Common; }
         }
 
         public override string< /code> ModelNumber
         {
             get { return "serversuperio" ; }
         }
 
         public override System.Windows.Forms.Control DeviceGraphics
         {
             get { throw new NotImplementedException(); }
         }
}

    实时动态数据对象_deviceDyn、参数数据对象_devicePara、协议驱动对象_protocol分别提供给接口:DeviceDynamic、DeviceParameter和Protocol,为SSIO提供可引用的基础属性参数。

     Initialize是设备驱动初始化的函数接口,在这个接口完成两个主要工作:初始化协议驱动和参数性的信息。通过this.Protocol.InitDriver(this.GetType(),null);代码可以加载所有协议命令到协议驱动的缓存中,以便实时调用。当然这里边也可以进行其他方面的工作,但是注意对异常的处理。

     DeviceType这个是设备的类型,一般指定为Common就好了。其他函数接口功能已经在《物联网框架ServerSuperIO教程-3.设备驱动介绍》中详细介绍了,请参考。

4.4    构建宿主程序

     一个简单的设备驱动就已经开发好了,光有驱动还不行,那么我们基于SSIO框架再写几行代码,完成一个宿主程序,把设备驱动实例化,放SSIO的服务实例中运行,完成串口和网络两种方式的通讯交互,代码也非常简单。代码如下:

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class Program
{
         static void Main( string [] args)
         {
             DeviceDriver dev1 = new DeviceDriver();
             dev1.DeviceParameter.DeviceName = "串口设备1" ;
             dev1.DeviceParameter.DeviceAddr = 0;
             dev1.DeviceParameter.DeviceID = "0" ;
             dev1.DeviceDynamic.DeviceID = "0" ;
             dev1.DeviceParameter.COM.Port = 1;
             dev1.DeviceParameter.COM.Baud = 9600;
             dev1.CommunicateType = CommunicateType.COM;
             dev1.Initialize( "0" );
 
             DeviceDriver dev4 = new DeviceDriver();
             dev4.DeviceParameter.DeviceName = "网络设备2" ;
             dev4.DeviceParameter.DeviceAddr = 0;
             dev4.DeviceParameter.DeviceID = "3" ;
             dev4.DeviceDynamic.DeviceID = "3" ;
             dev4.DeviceParameter.NET.RemoteIP = "127.0.0.1" ;
             dev4.DeviceParameter.NET.RemotePort = 9600;
             dev4.CommunicateType = CommunicateType.NET;
             dev4.Initialize( "3" );
 
             IServer server = new ServerFactory().CreateServer( new ServerConfig()
             {
                 ServerName = "服务实例1" ,
                 SocketMode = SocketMode.Tcp,
                 ControlMode = ControlMode.Loop,
                 CheckSameSocketSession = false ,
                 StartCheckPackageLength = false ,
             });
 

             server.AddDeviceCompleted += server_AddDeviceCompleted;
             server.DeleteDeviceCompleted += server_DeleteDeviceCompleted;
             server.SocketConnected+=server_SocketConnected;
             server.SocketClosed+=server_SocketClosed;
             server.Start();
 
             server.AddDevice(dev1);
             server.AddDevice(dev4);
 
             while ( "exit" ==Console.ReadLine())
             {
                  server.Stop();
             }
         }
 
         private static void server_SocketClosed( string ip, int port)
         {
             Console.WriteLine(String.Format( "断开:{0}-{1} 成功" , ip, port));
         }
 
         private static void server_SocketConnected( string ip, int port)
         {
             Console.WriteLine(String.Format( "连接:{0}-{1} 成功" ,ip, port));
         }
 
         private static void server_AddDeviceCompleted( string devid, string devName, bool isSuccess)
 
         {
             Console.WriteLine(devName+ ",增加:" +isSuccess.ToString());
         }
 
         private static void server_DeleteDeviceCompleted( string devid, string devName, bool isSuccess)
         {
             Console.WriteLine(devName + ",删除:" + isSuccess.ToString());
         }
     }
}

     这个代码大家都能看明白,具体的控制模式我们接下来会一一介绍。在构建宿主程序的时候,切忌对服务实例这样引用:server.ChannelManager、server.ControllerManager、server.DeviceManager。尽管提供了这样的接口,主要是为了SSIO框架内部使用的,不需要我们单独去操作这些接口。有的网友是这样的写的,那么就变成了一个纯的通信IO框架,那么就失去了SSIO框架本身的价值。作为二次开发者,只需要设置设备驱动的参数,以及向服务实例中增加或删除设备就行了,其他所有的运行全部交给SSIO框架来完成。

4.5    运行效果

 

 

1.[连载]《C#通讯(串口和网络)框架的设计与实现》

2.[开源]C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍

2.应用SuperIO(SIO)和开源跨平台物联网框架ServerSuperIO(SSIO)构建系统的整体方案

3.C#工业物联网和集成系统解决方案的技术路线(数据源、数据采集、数据上传与接收、ActiveMQ、Mongodb、WebApi、手机App)

5.ServerSuperIO开源地址:https://github.com/wxzz/ServerSuperIO

物联网&集成技术(.NET) QQ群54256083

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Dyn
{
         private float _Flow = 0.0f;
         ///

         /// 流量
         ///

         public float Flow
         {
             get { return _Flow; }
             set { _Flow = value; }
         }
         private float _Signal = 0.0f;
         ///

         /// 信号
         ///

         public float Signal
         {
             get { return _Signal; }
             set { _Signal = value; }
         }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Dyn
{
         private float _Flow = 0.0f;
         ///

< code class="csharp spaces">         /// 流量
         ///

         public float Flow
         {
             get { return _Flow; }
             set { _Flow = value; }
         }
         private float _Signal = 0.0f;
         ///

         /// 信号
         ///

         public float Signal
         {
             get { return _Signal; }
             set { _Signal = value; }
         }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Dyn
{
         private float _Flow = 0.0f;
         ///

         /// 流量
         ///

         public float Flow
         {
             get { return _Flow; }
             set { _Flow = value; }
         }
         private float _Signal = 0.0f;
         ///

         /// 信号
         ///

         public float Signal
         {
             get { return _Signal; }
             set { _Signal = value; }
         }
}

1

2

3

4

5

6

7

8

9

10

11

12

< p>13

14

15

16

17

18

19

20

21

public class Dyn
{
         private float _Flow = 0.0f;
         ///

         /// 流量
         ///

         public float Flow
         {
             get { return _Flow; }
             set { _Flow = value; }
         }
         private float _Signal = 0.0f;
         ///

         /// 信号
         ///

         public float Signal
         {
             get { return _Signal; }
             set { _Signal = value; }
         }
}

public class Dyn

{

         private float _Flow = 0.0f;

         ///

         /// 流量

         ///

         public float Flow

         {

             get { return _Flow; }

             set { _Flow = value; }

         }

         private float _Signal = 0.0f;

         ///

         /// 信号

         ///

         public float Signal

         {

             get { return _Signal; }

             set { _Signal = value; }

         }

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class DeviceDyn:DeviceDynamic
{
         public DeviceDyn() : base ()
         {
             Dyn= new Dyn();
         }
         public override string GetAlertState()
         {
             throw new NotImplementedException( "无报警信息" );
         }
         public override object Repair()
         {
             return new DeviceDyn();
         }
         public Dyn Dyn { get ; set ; }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class DeviceDyn:DeviceDynamic
{
         public DeviceDyn() : base ()
         {
             Dyn= new Dyn();
         }
         public override string GetAlertState()
         {
             throw new NotImplementedException( "无报警信息" );
         }
         public override object Repair()
         {
             return new DeviceDyn();
         }
         public Dyn Dyn { get ; set ; }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class DeviceDyn:DeviceDynamic
{
         public DeviceDyn() : base ()
         {
             Dyn= new Dyn();
         }
         public override string GetAlertState()
         {
             throw new NotImplementedException( "无报警信息" );
         }
         public override object Repair()
         {
             return new DeviceDyn();
         }
         public Dyn Dyn { get ; set ; }
}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

public class DeviceDyn:DeviceDynamic
{
         public DeviceDyn() : base ()
         {
             Dyn= new Dyn();
         }
         public override string GetAlertState()
         {
             throw new NotImplementedException( "无报警信息" );
         }
         public override object Repair()
         {
             return new DeviceDyn();
         }
         public Dyn Dyn { get ; set ; }
}

public class DeviceDyn:DeviceDynamic

{

         public DeviceDyn() : base ()

         {

             Dyn= new Dyn();

         }

         public override string GetAlertState()

         {

             throw new NotImplementedException( "无报警信息" );

         }

         public override object Repair()

         {

             return new DeviceDyn();

         }

         public Dyn Dyn { get ; set ; }

}

1
2
3
4
5
6
7
public class DevicePara:ServerSuperIO.Device.DeviceParameter
{
         public override object Repair()
         {
             return new DevicePara();
         }
}

1
2
3
4
5
6
7
public class DevicePara:ServerSuperIO.Device.DeviceParameter
{
         public override object Repair()
         {
             return new DevicePara();
         }
}

1
2
3
4
5
6
7
public class DevicePara:ServerSuperIO.Device.DeviceParameter
{
         public override object Repair()
         {
             return new DevicePara();
         }
}

1

2

3

4

5

6

7

public class DevicePara:ServerSuperIO.Device.DeviceParameter
{
         public override object Repair()
         {
             return new DevicePara();
         }
}

public class DevicePara:ServerSuperIO.Device.DeviceParameter

{

         public override object Repair()

         {

             return new DevicePara();

         }

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
internal class DeviceCommand:ProtocolCommand
{
         public override string Name
         {
             get { return "61" ; }
         }
 
         public override void ExcuteCommand(T t)
         {
             throw new NotImplementedException();
         }
 
         public override byte [] Package ( string code, T1 t1,T2 t2)
         {
             //发送:0x55 0xaa 0x00 0x61 0x61 0x0d
             byte [] data = new byte [6];
             data[0] = 0x55;

             data[1] = 0xaa;
             data[2] = byte .Parse(code);
             data[3] = 0x61;
             data[4] = this .ProtocolDriver.GetCheckData(data)[0];
             data[5] = 0x0d;
             return data;
         }
 
         public override dynamic Analysis( byte [] data, T t)
         {
             Dyn dyn = new Dyn()
             //一般下位机是单片的话,接收到数据的高低位需要互换,才能正常解析。
             byte [] flow = BinaryUtil.SubBytes(data, 4, 4, true );
             dyn.Flow = BitConverter.ToSingle(flow, 0);
             byte [] signal = BinaryUtil.SubBytes(data, 8, 4, true );
             dyn.Signal = BitConverter.ToSingle(signal, 0);
             return dyn;
         }
 
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
internal class DeviceCommand:ProtocolCommand
{
         public override string Name
         {
             get { return "61" ; }
         }
 
         public override void ExcuteCommand(T t)
         {
             throw new NotImplementedException();
         }
 
         public override byte [] Package ( string code, T1 t1,T2 t2)
         {
             //发送:0x55 0xaa 0x00 0x61 0x61 0x0d
             byte [] data = new byte [6];
             data[0] = 0x55;
             data[1] = 0xaa;
             data[2] = byte .Parse(code);
             data[3] = 0x61;
             data[4] = this .ProtocolDriver.GetCheckData(data)[0];
             data[5] = 0x0d;
             return data;
         }
 
         public override dynamic Analysis( byte [] data, T t)
         {
             Dyn dyn = new Dyn()
             //一般下位机是单片的话,接收到数据的高低位需要互换,才能正常解析。
             byte [] flow = BinaryUtil.SubBytes(data, 4, 4, true );
             dyn.Flow = BitConverter.ToSingle(flow, 0);
             byte [] signal = BinaryUtil.SubBytes(data, 8, 4, true );
             dyn.Signal = BitConverter.ToSingle(signal, 0);
             return dyn;
         }
 
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

36
37
internal class DeviceCommand:ProtocolCommand
{
         public override string Name
         {
             get { return "61" ; }
         }
 
         public override void ExcuteCommand(T t)
         {
             throw new NotImplementedException();
         }
 
         public override byte [] Package ( string code, T1 t1,T2 t2)
         {
             //发送:0x55 0xaa 0x00 0x61 0x61 0x0d
             byte [] data = new byte [6];
             data[0] = 0x55;
             data[1] = 0xaa;
             data[2] = byte .Parse(code);
             data[3] = 0x61;
             data[4] = this .ProtocolDriver.GetCheckData(data)[0];
             data[5] = 0x0d;
             return data;
         }
 
         public override dynamic Analysis( byte [] data, T t)
         {
             Dyn dyn = new Dyn()
             //一般下位机是单片的话,接收到数据的高低位需要互换,才能正常解析。
             byte [] flow = BinaryUtil.SubBytes(data, 4, 4, true );
             dyn.Flow = BitConverter.ToSingle(flow, 0);
             byte [] signal = BinaryUtil.SubBytes(data, 8, 4, true );
             dyn.Signal = BitConverter.ToSingle(signal, 0);
             return dyn;
         }
 
}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

internal class DeviceCommand:ProtocolCommand
{
         public override string Name
         {
             get { return "61" ; }
         }
 
         public override void ExcuteCommand(T t)
         {
             throw new NotImplementedException();
         }
 
         public override byte [] Package ( string code, T1 t1,T2 t2)
         {
             //发送:0x55 0xaa 0x00 0x61 0x61 0x0d
             byte [] data = new byte [6];
             data[0] = 0x55;
             data[1] = 0xaa;
             data[2] = byte .Parse(code);
             data[3] = 0x61;
             data[4] = this .ProtocolDriver.GetCheckData(data)[0];
             data [5] = 0x0d;
             return data;
         }
 
         public override dynamic Analysis( byte [] data, T t)
         {
             Dyn dyn = new Dyn()
             //一般下位机是单片的话,接收到数据的高低位需要互换,才能正常解析。
             byte [] flow = BinaryUtil.SubBytes(data, 4, 4, true );
             dyn.Flow = BitConverter.ToSingle(flow, 0);
             byte [] signal = BinaryUtil.SubBytes(data, 8, 4, true );
             dyn.Signal = BitConverter.ToSingle(signal, 0);
             return dyn;
         }
 
}

internal class DeviceCommand:ProtocolCommand

{

         public override string Name

         {

             get { return "61" ; }

         }

 

         public override void ExcuteCommand(T t)

         {

             throw new NotImplementedException();

         }

 

         public ov erride byte [] Package ( string code, T1 t1,T2 t2)

         {

             //发送:0x55 0xaa 0x00 0x61 0x61 0x0d

             byte [] data = new byte [6];

             data[0] = 0x55;

             data[1] = 0xaa;

             data[2] = byte .Parse(code);

             data[3] = 0x61;

             data[4] = this .ProtocolDriver.GetCheckData(data)[0];

             data[5] = 0x0d;

             return data;

         }

 

         public override dynamic Analysis( byte [] data, T t)

         {

             Dyn dyn = new Dyn()

             //一般下位机是单片的话,接收到数据的高低位需要互换,才能正常解析。

             byte [] flow = BinaryUtil.SubBytes(data, 4, 4, true );

             dyn.Flow = BitConverter.ToSingle(flow, 0);

             byte [] signal = BinaryUtil.SubBytes(data, 8, 4, true );

             dyn.Signal = BitConverter.ToSingle(signal, 0);

             return dyn;

         }

 

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2 6
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
internal class DeviceProtocol:ProtocolDriver
{
         public override bool CheckData( byte [] data)
         {
             if (data[0] == 0x55 && data[1] == 0xaa && data[data.Length - 1] == 0x0d)
             {
                 return true ;
             }
             else
             {
                 return false ;
             }
         }
 
         public override byte [] GetCommand( byte [] data)
         {
             return new byte [] { data[3] };
         }
 
         public override int GetAddress( byte [] data)
         {
             return data[2];
         }
 
         public override byte [] GetHead( byte [] data)
         {
             return new byte [] { data[0], data[1] };
         }
 
         public override byte [] GetEnd( byte [] data)
         {
             return new byte [] { data[data.Length - 1] };
         }
 
         public override byte [] GetCheckData( byte [] data)
         {
             byte checkSum = 0;
             for ( int i = 2; i < data.Length - 2; i++)
             {
                 checkSum += data[i];
             }
             return new byte [] { checkSum };
         }
 
         public override string GetCode( byte [] data)
         {
             throw new NotImplementedException();
         }
 
         public override int GetPackageLength( byte [] data, IChannel channel, ref int readTimeout)
         {
            throw new NotImplementedException();
         }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

< div class="line number45 index44 alt2"> 45

46
47
48
49
50
51
52
53
54
internal class DeviceProtocol:ProtocolDriver
{
         public override bool CheckData( byte [] data)
         {
             if (data[0] == 0x55 && data[1] == 0xaa && data[data.Length - 1] == 0x0d)
             {
                 return true ;
             }
             else
             {
                 return false ;
             }
         }
 
         public override byte [] GetCommand( byte [] data)
         {
             return new byte [] { data[3] };
         }
 
         public override int GetAddress( byte [] data)
         {
             return data[2];
         }
 
         public override byte [] GetHead( byte [] data)
         {
             return new byte [] { data[0], data[1] };
         }
 
         public override byte [] GetEnd( byte [] data)
         {
             return new byte [] { data[data.Length - 1] };
         }
 
         public override byte< /code> [] GetCheckData( byte [] data)
         {
             byte checkSum = 0;
             for ( int i = 2; i < data.Length - 2; i++)
             {
                 checkSum += data[i];
             }
             return new byte [] { checkSum };
         }
 
         public override string GetCode( byte [] data)
         {
             throw new NotImplementedException();
         }
 
         public override int GetPackageLength( byte [] data, IChannel channel, ref int readTimeout)
         {
            throw new NotImplementedException();
         }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
internal class DeviceProtocol:ProtocolDriver
{
         public override bool CheckData( byte [] data)
         {
             if (data[0] == 0x55 && data[1] == 0xaa && data[data.Length - 1] == 0x 0d)
             {
                 return true ;
             }
             else
             {
                 < code class="csharp keyword">return false ;
             }
         }
 
         public override byte [] GetCommand( byte [] data)
         {
             return new byte [] { data[3] };
         }
 
         public override int GetAddress( byte [] data)
         {
             return data[2];
         }
 
         public override byte [] GetHead( byte [] data)
         {
             return new byte [] { data[0], data[1] };
         }
 
         public override byte [] GetEnd( byte [] data)
         {
             return new byte [] { data[data.Length - 1] };
         }
 
         public override byte [] GetCheckData( byte [] data)
         {
             byte checkSum = 0;
             for ( int i = 2; i < data.Length - 2; i++)
             {
                 checkSum += data[i];
             }
             return new byte [] { checkSum };
         }
 
         public override string GetCode( byte [] data)
         {
             throw new NotImplementedException();
         }
 
         public override int GetPackageLength( byte [] data, IChannel channel, ref int readTimeout)
         {
            throw new NotImplementedException();
         }
}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

internal class DeviceProtocol:ProtocolDriver
{
         public override bool CheckData( byte [] data)
         {
             if (data[0] == 0x55 && data[1] == 0xaa && data[data.Length - 1] == 0x0d)
             {
                 return true ;
             }
             else
             {
                 return false ;
             }
         }
 
         public override byte [] GetCommand( byte [] data)
         {
             return new byte [] { data[3] };
         }
 
         public override int GetAddress( byte [] data)
         {
             return data[2];
         }
 
         public override byte [] GetHead( byte [] data)
         {
             return new byte [] { data[0], data[1] };
         }
 
         public override byte [] GetEnd( byte [] data)
         {
             return new byte [] { data[data.Length - 1] };
         }
 
         public override byte [] GetCheckData( byte [] data)
         {
             byte checkSum = 0;
             for ( int i = 2; i < data.Length - 2; i++)
             {
                 checkSum += data[i];
             }
             return new byte [] { checkSum };
         }
 
         public override string GetCode( byte [] data)
         {
             throw new NotImplementedException();
         }
 
         public override int GetPackageLength( byte [] data, IChannel channel, ref int readTimeout)
         {
            throw new NotImplementedException();
         }
}

internal class DeviceProtocol:ProtocolDriver

{

         public override bool CheckData( byte [] data)

         {

             if (data[0] == 0x55 && data[1] == 0xaa && data[data.Length - 1] == 0x0d)

             {

                 return true ;

             }

             else

             {

                 return false ;

             }

         }

 

         public override byte [] GetCommand( byte [] data)

         {

             return new byte [] { data[3] };

         }

 

         public override int GetAddress( byte [] data)

         {

             return data[2];

         }

 

         public override byte [] GetHead( byte [] data)

         {

             return new byte [] { data[0], data[1] };

         }

 

         public override byte [] GetEnd( byte [] data)

         {

             return new byte [] { data[data.Length - 1] };

         }

 

         public override byte [] GetCheckData( byte [] data)

         {

             byte checkSum = 0;

             for ( int i = 2; i < data.Length - 2; i++)

             {

                 check Sum += data[i];

             }

             return new byte [] { checkSum };

         }

 

         public override string GetCode( byte [] data)

         {

             throw new NotImpl ementedException();

         }

 

         public override int GetPackageLength( byte [] data, IChannel channel, ref int readTimeout)

         {

            throw new NotImplementedException();

         }

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
11 2
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
public class DeviceDriver:RunDevi ce
{
         private DeviceDyn _deviceDyn;
         private DevicePara _devicePara;
         private DeviceProtocol _protocol;
         public DeviceDriver() : base ()
         {
             _devicePara = new DevicePara();
             _deviceDyn = new DeviceDyn();
             _protocol = new DeviceProtocol();
         }
 
         public override void Initialize( string devid)
         {
             this .Protocol.InitDriver( this .GetType(), null );
             //初始化设备参数信息
             _devicePara.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的参数文件。
             if (System.IO.File.Exists(_devicePara.SavePath))
             {
                 //如果参数文件存在,则获得参数实例
                 _devicePara = _devicePara.Load();
             }
             else
             {
                 //如果参数文件不存在,则序列化一个文件
                 _devicePara.Save(_devicePara);
             }
 
             //初始化设备实时数据信息
             _deviceDyn.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的实时数据文件。
             if (System.IO.File.Exists(_deviceDyn.SavePath))
             {
                 //参数文件存在,则获得参数实例
                 _deviceDyn = _deviceDyn.Load();
             }
             else
             {
                 //如果参数文件不存在,则序列化一个文件
                 _deviceDyn.Save(_deviceDyn);
             }
         }
  
         public override byte [] GetConstantCommand()
         {
             return this .Protocol.DriverPackage( "0" , "61" , null );
         }
  
         public override void Communicate(ServerSuperIO.Communicate.IRequestInfo info)
         {

             Dyn dyn = this .Protocol.DriverAnalysis( "61" , info.Data, null );

             if (dyn != null )
             {
                 _deviceDyn.Dyn = dyn;
             }
             OnDeviceRuningLog( "通讯正常" );
         }
 
         public over ride void CommunicateInterrupt(ServerSuperIO.Communicate.IRequestInfo info)
         {
             OnDeviceRuningLog( "通讯中断" );
         }
  
         public override void CommunicateError(ServerSuperIO.Communicate.IRequestInfo info)
         {
             OnDeviceRuningLog( "通讯干扰" );
         }
  
         public override void CommunicateNone()
         {
             OnDeviceRuningLog( "通讯未知" );
         }
 
         public override void Alert()
         {
             return ;
         }
 
         public override void Save()
         {
             try
             {
                 _deviceDyn.Save(_deviceDyn);
             }
             catch (Exception ex)
             {
                 OnDeviceRuningLog(ex.Message);
             }
         }
 
         public override void Show()
         {
             List< string > list= new List< string >();
             list.Add(_devicePara.DeviceName);
             list.Add(_deviceDyn.Dyn.Flow.ToString());
             list.Add(_deviceDyn.Dyn.Signal.ToString());
             OnDeviceObjectChanged(list.ToArray());
         }
  
         public override void UnknownIO()
         {
             OnDeviceRuningLog( "未知通讯接口" );
         }
 

         public override void CommunicateStateChanged(ServerSuperIO.Communicate.CommunicateState comState)

         {
             OnDeviceRuningLog( "通讯状态改变" );
         }
 
         public override void ChannelStateChanged(ServerSuperIO.Communicate.ChannelState channelState)
         {
             OnDeviceRuningLog( "通道状态改变" );
         }
 
         public override void Exit()
         {
             OnDeviceRuningLog( "退出设备" );
         }< /code>
 
         public override void Delete()
         {
             OnDeviceRuningLog( "删除设备" );
         }
  
         public override object GetObject()
         {
             throw new NotImplementedException();
         }
 
         public override void ShowContextMenu()
         {
             throw new NotImplementedException();
         }
 
         public override IDeviceDynamic DeviceDynamic
         {
             get { return _deviceDyn; }
         }
 
         public override IDeviceParameter DeviceParameter
         {
             get { return _devicePara; }
         }
 
         public override IProtocolDriver Protocol
        {
             get { return _protocol;}
         }
 
         public override DeviceType DeviceType
         {
             get { return DeviceType.Common; }
         }
 
         public override string ModelNumber
         {
             get { return "serversuperio" ; }
         }
 
         public override System.Windows.Forms.Control DeviceGraphics
         {
             get { throw new NotImplementedException(); }
         }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

< div class="line number82 index81 alt1"> 82

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
public class DeviceDriver:RunDevice
{
         private DeviceDyn _deviceDyn;
         private DevicePara _devicePara;
         private DeviceProtocol _protocol;
         public DeviceDriver() : base ()
         {
             _devicePara = new DevicePara();
             _deviceDyn = new DeviceDyn();
             _protocol = new DeviceProtocol();
         }
 
         public override void Initialize( string devid)
         {
             this .Protocol.InitDri ver( this .GetType(), null );
             //初始化设备参数信息
             _devicePara.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的参数文件。
             if (System.IO.File.Exists(_devicePara.SavePath))
             {
                 //如果参数文件存在,则获得参数实例
                 _devicePara = _devicePara.Load();
             }
             else
             {
                 //如果参数文件不存在,则序列化一个文件
                 _devicePara.Save(_devicePara);
             }
 
             //初始化设备实时数据信息
             _deviceDyn.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的实时数据文件。
             if (System.IO.File.Exists(_deviceDyn.SavePath))
             {
                 //参数文件存在,则获得参数实例
                 _deviceDyn = _deviceDyn.Load();
             }
             else
             {
                 //如果参数文件不存在,则序列化一个文件
                 _deviceDyn.Save(_deviceDyn);
             }
         }
  
         public override byte [] GetConstantCommand()
         {
             return this .Protocol.DriverPackage( "0" , "61" , null );
         }
  
         public override void Communicate(ServerSuperIO.Communicate.IRequestInfo info)
         {
             Dyn dyn = this .Protocol.DriverAnalysis( "61" , info.Data, null );
             if (dyn != null )
             {
                 _deviceDyn.Dyn = dyn;
             }
             OnDeviceRuningLog( "通讯正常" );
         }
 
         public override void CommunicateInterrupt(ServerSuperIO.Communi cate.IRequestInfo info)
         {
             OnDeviceRuningLog( "通讯中断" );
         }
  
         public override void CommunicateError(ServerSuperIO.Communicate.IRequestInfo info)
         {
             OnDeviceRuningLog( "通讯干扰" );
         }
  
         public override void CommunicateNone()
         {
             OnDeviceRuningLog( "通讯未知" );
         }
 
         public override void Alert()
         {
             return ;
         }
 
         public override void Save()
         {
             try
             {
                 _deviceDyn.Save(_deviceDyn);
             }
             catch (Exception ex)

             {

                 OnDeviceRuningLog(ex.Message);
             }
         }
 
         public override void Show()
         {
             List< string > list= new List< string >();
             list.Add(_devicePara.DeviceName);
             list.Add(_deviceDyn.Dyn.Flow.ToString() );
             list.Add(_deviceDyn.Dyn.Signal.ToString());
             OnDeviceObjectChanged(list.ToArray());
         }
  
         public override void UnknownIO()

         {

             OnDeviceRuningLog( "未知通讯接口" );
         }
 
         public override void CommunicateStateChanged(ServerSuperIO.Communicate.CommunicateState comS tate)
         {
             OnDeviceRuningLog( "通讯状态改变" );
         }
 
         public override void ChannelStateChanged(ServerSuperIO.C ommunicate.ChannelState channelState)
         {
             OnDeviceRuningLog( "通道状态改变" );
         }
 
         public override void Exi t()
         {
             OnDeviceRuningLog( "退出设备" );
         }
 
         public override void Delete()
         {
             OnDeviceRuningLog( "删除设备" );
         }
  
         public override object GetObject()
         {
             throw new NotImplementedException();
         }
 
         public override void ShowContextMenu()
         {
             throw new NotImplementedException();
         }
 
         public override IDeviceDynamic DeviceDynamic
         {
             get { return _deviceDyn; }
         }
 
         public override IDeviceParameter DeviceParameter
         {
             get { return _devicePara; }
         }
 
         public override IProtocolDriver Protocol
        {
             get { return _protocol;}
         }
 
         public override DeviceType DeviceType
         {
             get { return DeviceType.Common; }
         }
 
         public override string ModelNumber
         {
             get { return "serversuperio" ; }
         }
 
         public override System.Windows.Forms.Control DeviceGraphics
         {
             get { throw new NotImplementedException(); }
         }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

< div class="line number97 index96 alt2"> 97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

< div class="line number127 index126 alt2"> 127

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
public class DeviceDriver:RunDevice
{
         private DeviceDyn _deviceDyn;
         private DevicePara _devicePara;
         private DeviceProtocol _protocol;
         public DeviceDriver() : base ()
         {
             _devicePara = new DevicePara();
             _deviceDyn = new DeviceDyn();
             _protocol = new DeviceProtocol();
         }
 
         public override void Initialize( string devid)
         {
             this .Protocol.InitDriver( this .GetType(), null );
             //初始化设备参数信息
             _devicePara.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的参数文件。
             if (System.IO.File.Exists(_devicePara.SavePath))
             {
                 //如果参数文件存在,则获得参数实例
                 _devicePara = _devicePara.Load();
             }
             else
             {
                 //如果参数文件不存在,则序列化一个文件
                 _devicePara.Save(_devicePara);
             }
 
             / /初始化设备实时数据信息
             _deviceDyn.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的实时数据文件。
             if (System.IO.File.Exists(_deviceDyn.SavePath))
             {
                 //参数文件存在,则获得参数实例
                 _deviceDyn = _deviceDyn.Load();
             }
             else
             {
                 //如果参数文件不存在,则序列化一个文件
                 _deviceDyn.Save(_deviceDyn);
             }
         }
  
         public override byte [] GetConstantCommand()
         {
             return this .Protocol.DriverPackage( "0" , "61" , null );
         }
  
         public override void Communicate(ServerSuperIO.Communicate.IRequestInfo info)
         {
             Dyn dyn = thi s .Protocol.DriverAnalysis( "61" , info.Data, null );
             if (dyn != null )
             {
                 _deviceDyn.Dyn = dyn;
             }
             OnDeviceRuningLog( "通讯正常" );
         }
 
         public override void CommunicateInterrupt(ServerSuperIO.Communicate.IRequestInfo info)
         {
             OnDeviceRuningLog( "通讯中断" );
         }
  
         public override void CommunicateError(ServerSuperIO.Communicate.IRequestInfo info)
         {
             OnDeviceRuningLog( "通讯干扰" );
         }
  
         public override void CommunicateNone()
         {
             OnDeviceRuningLog( "通讯未知" );
         }
 
         public override void Alert()
         {
             return ;
         }
 
         public override void Save()
         {
             try
             {
                 _deviceDyn.Save(_deviceDyn);
             }
             catch (Exception ex)
             {
                 OnDeviceRuningLog(ex.Message);
             }
         }
 
         public override void Show()
         {
             List< string > list= new List< string >();
             list.Add(_devicePara.DeviceName);
             list.Add(_deviceDyn.Dyn.Flow.ToString());
             list.Add(_deviceDyn.Dyn.Signal.ToString());
             OnDeviceObjectChanged(list.ToArray());
         }
  
         public override void UnknownIO()
         {
             OnDeviceRuningLog( "未知通讯接口" );
         }
 
         public override void CommunicateStateChanged(ServerSuperIO.Communicate.CommunicateState comState)
         {
             OnDeviceRuningLog( "通讯状态改变" );
         }
 
         public override void ChannelStateChanged(ServerSuperIO.Communicate.ChannelState channelState)
         {
             OnDeviceRuningLog( "通道状态改变" );
         }
 
         public override void Exit()
         {
             OnDeviceRuningLog( "退出设备" );
         }
 
         public override void Delete()
         {
             OnDeviceRuningLog( "删除设备" );
         }
  
         public override object GetObject()
         {
             throw new NotImplementedException();
         }
 
         public override void ShowContextMenu()
         {
             throw new NotImplementedException();
         }
 
         public override IDeviceDynamic DeviceDynamic
         {
             get { return _deviceDyn; }
         < code class="csharp plain">}
 
         public override IDeviceParameter DeviceParameter
         {
             get { return _devicePara; }
         }
 
         public override IProtocolDriver Protocol
        {
             get { return _protocol;}
         }
 
         public override DeviceType DeviceType
         {
             get { return DeviceType.Common; }
         }
 
         public override string ModelNumber
         {
             get { return "serversuperio" ; }
         }
 
         public override System.Windows.Forms.Control DeviceGraphics
         {
             get { throw new NotImplementedException(); }
         }
}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

public class DeviceDriver:RunDevice
{
         private DeviceDyn _deviceDyn;
         private DevicePara _devicePara;
         private DeviceProtocol _protocol;
         public DeviceDriver() : base ()
         {
            < /code> _devicePara = new DevicePara();
             _deviceDyn = new DeviceDyn();
             _protocol = new DeviceProtocol();
         }
 
         public override void Initialize( string devid)
         {
             this .Protocol.InitDriver( this .GetType(), null );
             //初始化设备参数信息
             _devicePara.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的参数文件。
             if (System.IO.File.Exists(_devicePara.SavePath))
             {
                 //如果参数文件存在,则获得参数实例
                 _devicePara = _devicePara.Load();
             }
             else
             {
                 //如果参数文件不存在,则序列化一个文件
                 _devicePara.Save(_devicePara);
             }
 
             //初始化设备实时数据信息
             _deviceDyn.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的实时数据文件。
             if (System.IO.File.Exists(_deviceDyn.SavePath))
             {
                 //参数文件存在,则获得参数实例
                 _deviceDyn = _deviceDyn.Load();
             }
             else
             {
                 //如果参数文件不存在,则序列化一个文件
                 _deviceDyn.Save(_deviceDyn);
             }
         }
  
         public override byte [] GetConstantCommand()
         {
             return this .Protocol.DriverPackage( "0" , "61" , null );
         }
  
         public override void Communicate(ServerSuperIO.Communicate.IRequestInfo info)
         {
             Dyn dyn = this .Protocol.DriverAnalysis( "61" , info.Data, null );
             if (dyn != null )
             {
                 _deviceDyn.Dyn = dyn;
             }
             OnDeviceRuningLog( "通讯正常" );
         }
 
         public override void CommunicateInterrupt(ServerSuperIO.Communicate.IRequestInfo info)
         {
             OnDeviceRuningLog( "通讯中断" );
         }
  
         public override void< /code> CommunicateError(ServerSuperIO.Communicate.IRequestInfo info)
         {
             OnDeviceRuningLog( "通讯干扰" );
         }
  
         public override void CommunicateNone()
         {
             OnDeviceRuningLog( "通讯未知" );
         }
 
         public override void Alert()
         {
             return ;
         }
 
         public override void Save()
         {
             try
             {
                 _deviceDyn.Save(_deviceDyn);
             }
             catch (Exception ex)
             {
                 OnDeviceRuningLog(ex.Message);
             }
         }
 
         public override void Show()
         {
             List< string > list= new List< string >();
             list.Add(_devicePara.DeviceName);
             list.Add(_deviceDyn.Dyn.Flow.ToString());
             list.Add(_deviceDyn.Dyn.Signal.ToString());
             OnDeviceObjectChanged(list.ToArray());
         }
  
         public override void UnknownIO ()
         {
             OnDeviceRuningLog( "未知通讯接口" );
         }
 
         public override void CommunicateStateChanged(ServerSuperIO.Communicate.CommunicateState comState)
         {
             OnDeviceRuningLog( "通讯状态改变" );
         }
 
         public override void ChannelStateChanged(ServerSuperIO.Communicate.ChannelState channelState)
         {
             OnDeviceRuningLog( "通道状态改变" );
         }
 
         public override void Exit()
         {
             OnDeviceRuningLog( "退出设备" );
         }
 
         public override void Delete()
         {
             OnDeviceRuningLog( "删除设备" );
         }
  
         public override object GetObject()
         {
             throw new NotImplementedException();
         }
 
         public override void ShowContextMenu()
         {
             throw new NotImplementedException();
         }
 
         public override IDeviceDynamic DeviceDynamic
         {
             get { return _deviceDyn; }
         }
 
         public override IDeviceParameter DeviceParameter
         {
             get { return _devicePara; }
         }
 
         public override IProtocolDriver Protocol
        {
             get { return _protocol;}
         }
 
         public override DeviceType DeviceType
         {
             get { return DeviceType.Common; }
         }

 
         public override string ModelNumber
         {
             get { return "serversuperio" ; }
         }
 
         public override System.Windows.Forms.Control DeviceGraphics
         {
             get { throw new NotImplementedException(); }
         }
}

public class DeviceDriver:RunDevice

{

         private DeviceDyn _deviceDyn;

         private DevicePara _devicePara;

         private DeviceProtocol _protocol;

         public DeviceDriver() : base ()

         {

             _devicePara = new DevicePara();

             _deviceDyn = new DeviceDyn();

             _protocol = new DeviceProtocol();

         }

 

         public override void Initialize( string devid)

         {

             this .Protocol.InitDriver( this .GetType(), null );

             //初始化设备参数信息

             _devicePara.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的参数文件。

             if (System.IO.File.Exists(_devicePara.SavePath))

             {

                 //如果参数文件存在,则获得参数实例

                 _devicePara = _devicePara.Load();

             }

             else

             {

                 //如果参数文件不存在,则序列化一个文件

                 _ devicePara.Save(_devicePara);

             }

 

             //初始化设备实时数据信息

             _deviceDyn.DeviceID = devid; //设备的ID必须先赋值,因为要查找对应的实时数据文件。

             if (System.IO.File.Exists(_deviceDyn.SavePath))

             {

                 //参数文件存在,则获得参数实例

                 _deviceDyn = _deviceDyn.Load();

             }

             else

             {

                 //如果参数文件不存在,则序列化一个文件

                 _device Dyn.Save(_deviceDyn);

             }

         }

  

         public override byte [] GetConstantCommand()

         {

             return this .Protocol.DriverPackage( "0" , "61" , null );

         }

  

         public override void Communicate(ServerSuperIO.Communicate.IRequestInfo info)

         {

             Dyn dyn = this .Protocol.DriverAnalysis( "61" , info.Data, null );

             if ( dyn != null )

             {

                 _deviceDyn.Dyn = dyn;

             }

             OnDeviceRuningLog( "通讯正常" );

         }

 

         public override void CommunicateInterrupt(ServerSuperIO.Communicate.IRequestInfo info)

         {

             OnDeviceRuningLog( "通讯中断" );

         }

  

         public override void CommunicateError(ServerSuperIO.Communicate.IRequestInfo info)

         {

             OnDeviceRuningLog( "通讯干扰" );

         }

  

         public override void CommunicateNone()

         {

             OnDeviceRuningLog( "通讯未知" );

         }

 

         public override void Alert()

         {

             return ;

         }

 

         public override void Save()

         {

             try

             {

                 _deviceDyn.Save(_deviceDyn);

             }

             catch (Exception ex)

             {

                 OnDeviceRuningLog(ex.Message);

             }

         }

 

         public override void Show()

         {

             List< string > list= new List< string >();

             list.Add(_devicePara.DeviceName);

             list.Add(_deviceDyn.Dyn.Flow.ToString());

             list.Add(_deviceDyn.Dyn.Signal.ToString());

             OnDeviceObjectChanged(list.ToArray());

         }

  

         public override void UnknownIO()

         {

             OnDeviceRuningLog( "未知通讯接口" );

         }

 

         public override void CommunicateStateChanged(ServerSuperIO.Communicate.CommunicateState comState)

         {

             OnDeviceRuningLog( "通讯状态改变" );

         }

 

         public override void ChannelStateChanged(ServerSuperIO.Communicate.ChannelState channelState)

         {

             OnDeviceRuningLog( "通道状态改变" );

         }

 

         public override void Exit()

         {

             OnDeviceRun ingLog( "退出设备" );

         }

 

         public override void Delete()

         {

             OnDeviceRuningLog( "删除设备" );

         }

  

         public override object GetObject()

         {

             throw new NotImplementedException();

         }

 

         public override void ShowContextMenu()

         {

             throw new NotImplementedException();

         }

 

         public override IDeviceDynamic DeviceDynamic

         {

             get { return _deviceDyn; }

         }

 

         public override IDeviceParameter DeviceParameter

         {

             get { return _devicePara; }

         }

 

         public override IProtocolDriver Protocol

        {

             get { return _protocol;}

         }

 

         public override D eviceType DeviceType

         {

             get { return DeviceType.Common; }

         }

 

         public override string ModelNumber

         {

             get { return "serversuperio" ; }

         }

 

         public override System.Windows.Forms.Control DeviceGraphics

         {

             get { throw new NotImplementedException(); }

         }

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

< div class="line number30 index29 alt1"> 30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class Program
{
         static void Main( string [] args)
         {
             DeviceDriver dev1 = new DeviceDriver();

             dev1.DeviceParameter.DeviceName = "串口设备1" ;

             dev1.DeviceParameter.DeviceAddr = 0;
             dev1.DeviceParameter.DeviceID = "0" ;
             dev1.DeviceDynamic.DeviceID = "0" ;
             dev1.DeviceParameter.COM.Port = 1;
             dev1.DeviceParameter.COM.Baud = 9600;
             dev1.CommunicateType = CommunicateType.COM;
             dev1.Initialize( "0" );
 
             DeviceDriver dev4 = new DeviceDriver();
             dev4.DeviceParameter.DeviceName = "网络设备2" ;
             dev4.DeviceParameter.DeviceAddr = 0;
             dev4.DeviceParameter.DeviceID = "3" ;
             dev4.DeviceDynamic.DeviceID = "3" ;
             dev4.DeviceParameter.NET.RemoteIP = "127.0.0.1" ;
             dev4.DeviceParameter.NET.RemotePort = 9600;
             dev4.CommunicateType = CommunicateType.NET;
             dev4.Initialize( "3" );
 
             IServer server = new ServerFactory().CreateServer( new ServerConfig()
             {
                 ServerName = "服务实例1" ,
                 SocketMode = SocketMode.Tcp,
                 ControlMode = ControlMode.Loop,
                 CheckSameSocketSession = false ,
                 StartCheckPackageLength = false ,
             });
 
             server.AddDeviceCompleted += server_AddDeviceCompleted;
             server.DeleteDeviceCompleted += server_DeleteDeviceCompleted;
             server.SocketConnected+=server_Soc ketConnected;
             server.SocketClosed+=server_SocketClosed;
             server.Start();
 
             server.AddDevice(dev1);
             server.AddDevice(dev4);
 
             while ( "exit" ==Console.ReadLine())
             {
                  server.Stop();
             }
         }
 
         private static void server_SocketClosed( string ip, int port)
         {
             Console.WriteLine(String.Format( "断开:{0}-{1} 成功" , ip, port));
         }
 
         private static void server_SocketConnected( string ip, int port)
         {
             Console.WriteLine(String.Format( "连接:{0}-{1} 成功" ,ip, port));
         }
 
         private static void server_AddDeviceCompleted( string devid, string devName, bool isSuccess)
 
         {
             Console.WriteLine(devName+ ",增加:" +isSuccess.ToString());
         }
 
         private static void server_DeleteDeviceCompleted( string devid, string devName, bool isSuccess)
         {
             Console.WriteLine(devName + ",删除:" + isSuccess.ToString());
         }
     }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class Program
{
         static void Main( string [] args)
         {
             DeviceDriver dev1 = new DeviceDriver();
             dev1.DeviceParameter.DeviceName = "串口设备1" ;
             dev1.DeviceParameter.DeviceAddr = 0;
             dev1.DeviceParameter.DeviceID = "0" ;
             dev1.DeviceDynamic.DeviceID = "0" ;
             dev1.DeviceParameter.COM.Port = 1;
             dev1.DeviceParameter.COM.Baud = 9600;
             dev1.CommunicateType = CommunicateType.COM;
             dev1.Initialize( "0" );
 
             DeviceDriver dev4 = new DeviceDriver();
             dev4.DeviceParameter.DeviceName = "网络设备2" ;
             dev4.Devic eParameter.DeviceAddr = 0;
             dev4.DeviceParameter.DeviceID = "3" ;
             dev4.DeviceDynamic.DeviceID = "3" ;
             dev4.DeviceParameter.NET.RemoteIP = "127.0.0.1" ;
             dev4.DeviceParameter.NET.RemotePort = 9600;
             dev4.CommunicateType = CommunicateType.NET;
             dev4.Initialize( "3" );
 
             IServer server = new ServerFactory().CreateServer( new ServerConfig()
             {
                 ServerName = "服务实例1" ,
                 SocketMode = SocketMode.Tcp,
                 ControlMode = ControlMode.Loop,
                 CheckSameSocketSession = false ,
                 StartCheckPackageLength = false ,
             });
 
             server.AddDeviceCompleted += server_AddDeviceCompleted;
             server.DeleteDeviceCompleted += server_Del eteDeviceCompleted;
             server.SocketConnected+=server_SocketConnected;
             server.SocketClosed+=server_SocketClosed;
             server.Start();
 
             server.AddDevice(dev1);
             s erver.AddDevice(dev4);
 
             while ( "exit" ==Console.ReadLine())
             {
                  server.Stop();
             }
         }
 
         private static void server_SocketClosed( string ip, int port)
         {
             Console.WriteLine(String.Format( "断开:{0}-{1} 成功" , ip, port));
         }
 
         private static void server_SocketConnected( string ip, int port)
         {
             Console.WriteLine(String.Format( "连接:{0}-{1} 成功" ,ip, port));
         }
 
         private static void server_AddDeviceCompleted( string devid, string devName, bool isSuccess)
 
         {
             Console.WriteLine(devName+ ",增加:" +isSuccess.ToString());
         }
 
         private static void server_DeleteDeviceCompleted( string devid, string devName, bool isSuccess)
         {
             Console.WriteLine(devName + ",删除:" + isSuccess.ToString());
         }
     }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

class Program
{
         static void Main( string [] args)
         {
             DeviceDriver dev1 = new DeviceDriver();
             dev1.DeviceParameter.DeviceName = "串口设备1" ;
             dev1.DeviceParameter.DeviceAddr = 0;
             dev1.DeviceParameter.DeviceID = "0" ;
             dev1.DeviceDynamic.DeviceID = "0" ;
             dev1.DeviceParameter.COM.Port = 1;
             dev1.DeviceParameter.COM.Baud = 9600;
             dev1.CommunicateType = CommunicateType.COM;
             dev1.Initialize( "0" );
 
             DeviceDriver dev4 = new DeviceDriver();
             dev4.DeviceParameter.DeviceName = "网络设备2" ;
             dev4.DeviceParameter.DeviceAddr = 0;
             dev4.DeviceParameter.DeviceID = "3" ;
             dev4.DeviceDynamic.DeviceID = "3" ;
             dev4.DeviceParameter.NET.RemoteIP = "127.0.0.1" ;
             dev4.DeviceParameter.NET.RemotePort = 9600;
             dev4.CommunicateType = CommunicateType.NET;
             dev4.Initialize( "3" );
 
             IServer server = new ServerFactory().CreateServer( new ServerConfig()
             {
                 ServerName = "服务实例1" ,
                 SocketMode = SocketMode.Tcp,
                 ControlMode = ControlMode.Loop,
                 CheckSameSocketSession = false ,
                 StartCheckPackageLength = false ,
             });
 
             server.AddDeviceCompleted += server_AddDeviceCompleted;
             server.DeleteDeviceCompleted += server_DeleteDeviceCompleted;
             server.SocketConnected+=server_SocketConnected;
             server.SocketClosed+=server_SocketClosed;
             server.Start();
 
             server.AddDevice(dev1);
             server.AddDevice(dev4);
 
             while ( "exit" ==Console.ReadLine())
             {
                  server.Stop();
             }
         }
 
         private static void server_SocketClosed( string ip, int port)
         {
             Console.WriteLine(String.Format( "断开:{0}-{1} 成功" , ip, port));
         }
 
         private static void server_SocketConnected( string ip, int port)
         {
             Console.WriteLine(String.Format( "连接:{0}-{1} 成功" ,ip, port));
         }
 
         private static void server_AddDeviceCompleted( string devid, string devName, bool isSuccess)
 
         {
             Console.WriteLine(devName+ ",增加:" +isSuccess.ToString());
         }
 
         private static void server_DeleteDeviceCompleted( string devid, string devName, bool isSuccess)
         {
             Console.WriteLine(devName + ",删除:" + isSuccess.ToString());
         }
     }
}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19< /p>

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

class Program
{
         static void Main( string [] args)
         {
             DeviceDriver dev1 = new DeviceDriver();
             dev1.DeviceParameter.DeviceName = "串口设备1" ;
             dev1.DeviceParameter.DeviceAddr = 0;
             dev1.DeviceParameter.DeviceID = "0" ;
             dev1.DeviceDynamic.DeviceID = "0" ;
             dev1.DeviceParameter.COM.Port = 1;
             dev1.DeviceParameter.COM.Baud = 9600;
             dev1.CommunicateType = CommunicateType.COM;
             dev1.Initialize( "0" );
 
             DeviceDriver dev4 = new DeviceDriver();
             dev4.DeviceParameter.DeviceName = "网络设备2" ;
             dev4.DeviceParameter.DeviceAddr = 0;
             dev4.DeviceParameter.DeviceID = "3" ;
             dev4.DeviceDynamic.DeviceID = "3" ;
             dev4.DeviceParameter.NET.RemoteIP = "127.0.0.1" ;
             dev4.DeviceParameter.NET.RemotePort = 9600;
             dev4.CommunicateType = CommunicateType.NET;
             dev4.Initialize( "3" ) ;
 
             IServer server = new ServerFactory().CreateServer( new ServerConfig()
             {
                 ServerName = "服务实例1" ,
                 SocketMode = SocketMode.Tcp,
                 ControlMode = ControlMode.Loop,
                 CheckSameSocketSession = false ,
                 StartCheckPackageLength = false ,
             });
 
             server.AddDeviceCompleted += server_AddDeviceCompleted;
             server.DeleteDeviceCompleted += server_DeleteDeviceCompleted;
             server.SocketConnected+=server_SocketConnected;
             server.SocketClosed+=server_SocketClosed;
             server.Start();
 
             server.AddDevice(dev1);
             server. AddDevice(dev4);
 
             while ( "exit" ==Console.ReadLine())
             {
                  server.Stop();
             }
         }
 
         private static void server_SocketClosed( string ip, int port)
         {
             Console.WriteLine(String.Format( "断开:{0}-{1} 成功" , ip, port));
         }
 
         private static void server_SocketConnected( string ip, int port)
         {
             Console.WriteLine(String.Format( "连接:{0}-{1} 成功" ,ip, port));
         }
 
         private static void server_AddDeviceCompleted( string devid, string devName, bool isSuccess)
 
         {
             Console.WriteLine(devName+ ",增加:" +isSuccess.ToString());
         }
 
         private static void server_DeleteDeviceCompleted( string devid, string devName, bool isSuccess)
         {
             Console.WriteLin e(devName + ",删除:" + isSuccess.ToString());
         }
     }
}

class Program

{

         static void Main( string [] args)

         {

             DeviceDriver dev1 = new DeviceDriver();

             dev1.DeviceParameter.DeviceName = "串口设备1" ;

             dev1.DeviceParameter.DeviceAddr = 0;

             dev1.DeviceParameter.DeviceID = "0" ;

             dev1.DeviceDynamic.DeviceID = "0" ;

             dev1.DeviceParameter.COM.Port = 1;

             dev1.DeviceParameter.COM.Baud = 9600;

             dev1.CommunicateType = CommunicateType.COM;

             dev1.Initialize( "0" );

 

             DeviceDriver dev4 = new DeviceDriver();

             dev4.DeviceParameter.DeviceName = "网络设备2" ;

             dev4.DeviceParameter.DeviceAddr = 0;

             dev4.DeviceParameter.DeviceID = "3" ;

             dev4.DeviceDynamic.DeviceID = "3" ;

             dev4.DeviceParameter.NET.RemoteIP = "127.0.0.1" ;

             dev4.DeviceParameter.NET.RemotePort = 9600;

             dev4.CommunicateType = CommunicateType.NET;

             dev4.Initialize( "3" );

 

             IServer server = new ServerFactory().CreateServer( new ServerConfig()

             {

                 ServerName = "服务实例1" ,

                 SocketMode = SocketMode.Tcp,

                 ControlMode = ControlMode.Loop,

                 CheckSameSocketSession = false ,

                 StartCheckPackageLength = false ,

             });

 

             server.AddDeviceCompleted += server_AddDeviceCompleted;

             server.DeleteDeviceCompleted += server_DeleteDeviceCompleted;

             server.SocketConnected+=server_SocketConnected;

             server.SocketClosed+=server_SocketClosed;

             server.Start();

 

             server.AddDevice(dev1);

             server.AddDevice(dev4);

 

             while ( "exit" ==Console.ReadLine())

             {

                  server.Stop();

             }

         }

 

         private static void server_SocketClosed( string ip, int port)

         {

             Console.WriteLine(String.Format( "断开:{0}-{1} 成功" , ip, port));

         }

 

         private static void server_SocketConnected( string ip, int port)

         {

             Console.WriteLine(String.Format( "连接:{0}-{1} 成功" ,ip, port));

         }

 

         private static void server_AddDeviceCompleted( string devid, string devName, bool isSuccess)

 

         {

             Console.WriteLine(devName+ ",增加:" +isSuccess.ToString());

         }

 

         private static void server_DeleteDeviceCompleted( string devid, string devName, bool isSuccess)

         {

             Console.WriteLine(devName + ",删除:" + isSuccess.ToString());

         }

     }

}

WordPress database error: [Table 'yf99682.wp_s6mz6tyggq_comments' doesn't exist]
SELECT SQL_CALC_FOUND_ROWS wp_s6mz6tyggq_comments.comment_ID FROM wp_s6mz6tyggq_comments WHERE ( comment_approved = '1' ) AND comment_post_ID = 1255 ORDER BY wp_s6mz6tyggq_comments.comment_date_gmt ASC, wp_s6mz6tyggq_comments.comment_ID ASC

Leave a Comment

Your email address will not be published.