|
@@ -3,94 +3,189 @@ using S7.Net.Types;
|
|
using System;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq;
|
|
|
|
+using System.Reflection;
|
|
|
|
+using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Text;
|
|
|
|
+using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Threading.Tasks;
|
|
using System.Timers;
|
|
using System.Timers;
|
|
|
|
|
|
namespace PLCLinker
|
|
namespace PLCLinker
|
|
{
|
|
{
|
|
- public class AbstractMessage
|
|
|
|
|
|
+ interface PLCS7
|
|
{
|
|
{
|
|
-
|
|
|
|
|
|
+ void PLCConnect(CpuType cpu, string ip, short rack, short slot);
|
|
|
|
+ void PLCDisconnect();
|
|
|
|
+ bool WriteToPLC(object abstractPLCMsg, PLCDataType whoami);
|
|
|
|
+ List<object> ReadFromPLC(PLCDataType whichToRead, int index);
|
|
}
|
|
}
|
|
- interface IEquipments
|
|
|
|
|
|
+ public enum PLCDataType
|
|
{
|
|
{
|
|
- void Start();
|
|
|
|
- void Stop();
|
|
|
|
- void SetMessage(AbstractMessage abstractMsg);
|
|
|
|
- AbstractMessage GetMessage();
|
|
|
|
|
|
+ terminal,
|
|
|
|
+ central,
|
|
|
|
+ parkingSpace
|
|
}
|
|
}
|
|
-
|
|
|
|
- class PLCLinker : IEquipments
|
|
|
|
|
|
+ public abstract class AbstractPLCLinker : PLCS7
|
|
{
|
|
{
|
|
|
|
+ protected const int mainBlockOffset = 18;
|
|
|
|
+ protected const int parkingSpaceOffset = 18;
|
|
/// <summary>
|
|
/// <summary>
|
|
/// PLC 连接状态flag
|
|
/// PLC 连接状态flag
|
|
/// </summary>
|
|
/// </summary>
|
|
- private bool isConnected = false;
|
|
|
|
|
|
+ protected bool isConnected = false;
|
|
/// <summary>
|
|
/// <summary>
|
|
/// 系统关闭flag
|
|
/// 系统关闭flag
|
|
/// </summary>
|
|
/// </summary>
|
|
- private bool isClosing = false;
|
|
|
|
- ///// <summary>
|
|
|
|
- ///// 从plc获得结构化数据
|
|
|
|
- ///// </summary>
|
|
|
|
- //private PLCMessage plcMsg;
|
|
|
|
|
|
+ protected bool isClosing = false;
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// 定时器
|
|
|
|
|
|
+ /// plc中cpu类型
|
|
/// </summary>
|
|
/// </summary>
|
|
- System.Timers.Timer timer;
|
|
|
|
- ///// <summary>
|
|
|
|
- ///// 读PLC初始地址
|
|
|
|
- ///// </summary>
|
|
|
|
- //private int startAddr = 0;
|
|
|
|
- ///// <summary>
|
|
|
|
- ///// 读PLC地址长度
|
|
|
|
- ///// </summary>
|
|
|
|
- //private int addrLength = 110;
|
|
|
|
|
|
+ protected CpuType cpu;
|
|
/// <summary>
|
|
/// <summary>
|
|
/// PLC的IP地址
|
|
/// PLC的IP地址
|
|
/// </summary>
|
|
/// </summary>
|
|
- private string ipString;
|
|
|
|
|
|
+ protected string ip;
|
|
/// <summary>
|
|
/// <summary>
|
|
/// PLC的端口号
|
|
/// PLC的端口号
|
|
/// </summary>
|
|
/// </summary>
|
|
- private Int16 rack;
|
|
|
|
|
|
+ protected Int16 rack;
|
|
/// <summary>
|
|
/// <summary>
|
|
/// 工作站号
|
|
/// 工作站号
|
|
/// </summary>
|
|
/// </summary>
|
|
- private Int16 slot;
|
|
|
|
|
|
+ protected Int16 slot;
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// PLC刷新频率,来自于配置文件
|
|
|
|
|
|
+ /// 终端DB块iD
|
|
/// </summary>
|
|
/// </summary>
|
|
- private int PLC_refresh_interval;
|
|
|
|
|
|
+ protected int terminalDB;
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// 无法获取配置文件时使用的PLC刷新频率
|
|
|
|
|
|
+ /// 中心DB块iD
|
|
/// </summary>
|
|
/// </summary>
|
|
- private const short PLC_TIME_SCALE = 200;
|
|
|
|
|
|
+ protected int centralDB;
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// PLC S7连接对象
|
|
|
|
|
|
+ /// 车位DB块ID
|
|
|
|
+ /// </summary>
|
|
|
|
+ protected int parkingSpaceDB;
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 终端个数
|
|
/// </summary>
|
|
/// </summary>
|
|
- Plc plc = null;
|
|
|
|
|
|
+ protected int terminalCount;
|
|
/// <summary>
|
|
/// <summary>
|
|
- /// 停车终端结构体
|
|
|
|
|
|
+ /// 停车位个数
|
|
/// </summary>
|
|
/// </summary>
|
|
- public ParkEndPoint pe;
|
|
|
|
- public TestStru ts;
|
|
|
|
- public List<byte> resultBytes;
|
|
|
|
|
|
+ protected int parkingSpaceCount;
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// PLC S7连接对象
|
|
|
|
+ /// </summary>
|
|
|
|
+ protected static Plc plc = null;
|
|
|
|
|
|
- public PLCLinker()
|
|
|
|
|
|
+ public void PLCConnect(CpuType cpu, string ip, short rack, short slot)
|
|
{
|
|
{
|
|
plc = new Plc(CpuType.S71500, "192.168.0.1", 0, 1);
|
|
plc = new Plc(CpuType.S71500, "192.168.0.1", 0, 1);
|
|
//plc = new Plc(CpuType.S71500, "127.0.0.1", 0, 1);
|
|
//plc = new Plc(CpuType.S71500, "127.0.0.1", 0, 1);
|
|
ErrorCode err = plc.Open();
|
|
ErrorCode err = plc.Open();
|
|
if (err == ErrorCode.ConnectionError) { Console.WriteLine("connection error"); }
|
|
if (err == ErrorCode.ConnectionError) { Console.WriteLine("connection error"); }
|
|
else { Console.WriteLine("connected"); }
|
|
else { Console.WriteLine("connected"); }
|
|
- pe = new ParkEndPoint();
|
|
|
|
- ts = new TestStru();
|
|
|
|
- resultBytes = new List<byte>();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- public List<byte> ReadMultipleBytes(int db, int length, int startAddr = 0)
|
|
|
|
|
|
+ public void PLCDisconnect()
|
|
|
|
+ {
|
|
|
|
+ if (plc != null)
|
|
|
|
+ {
|
|
|
|
+ plc.Close();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public abstract List<object> ReadFromPLC(PLCDataType whichToRead, int index);
|
|
|
|
+
|
|
|
|
+ public abstract bool WriteToPLC(object abstractPLCMsg, PLCDataType whoami);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public class PLCLinker : AbstractPLCLinker
|
|
|
|
+ {
|
|
|
|
+ ///// <summary>
|
|
|
|
+ ///// 从plc获得结构化数据
|
|
|
|
+ ///// </summary>
|
|
|
|
+ //private PLCMessage plcMsg;
|
|
|
|
+
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// PLC刷新频率,来自于配置文件
|
|
|
|
+ /// </summary>
|
|
|
|
+ private int PLC_refresh_interval;
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 无法获取配置文件时使用的PLC刷新频率
|
|
|
|
+ /// </summary>
|
|
|
|
+ private const short PLC_TIME_SCALE = 200;
|
|
|
|
+ //************************************** 方法区 *************************************
|
|
|
|
+ public void test()
|
|
|
|
+ {
|
|
|
|
+ Random rnd = new Random();
|
|
|
|
+ Task t = Task.Factory.StartNew(() =>
|
|
|
|
+ {
|
|
|
|
+ while (true)
|
|
|
|
+ {
|
|
|
|
+ TerminalStru terminal1 = new TerminalStru();
|
|
|
|
+ terminal1 = (TerminalStru)ReadStruFromPLC(terminal1, 27, 0);
|
|
|
|
+ Console.WriteLine(terminal1.ToString());
|
|
|
|
+ Thread.Sleep(200);
|
|
|
|
+ terminal1.terminalStatus = (short)rnd.Next(1, 6);
|
|
|
|
+ terminal1.licenseCodeA = rnd.Next(3000, 9999);
|
|
|
|
+ terminal1.receiptNum = rnd.Next(3000, 9999);
|
|
|
|
+ terminal1.licVerification = (short)rnd.Next(1, 555);
|
|
|
|
+ WriteStruToPLC(terminal1, 27, 0);
|
|
|
|
+ //List<byte> bList = Struct.ToBytes(terminal1).ToList();
|
|
|
|
+ //WriteMultipleBytes(27, bList, 0);
|
|
|
|
+
|
|
|
|
+ ////203 chars
|
|
|
|
+ //string str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccc";
|
|
|
|
+ ////pl.WriteMultipleBytes(1, (Encoding.ASCII.GetBytes(str)).ToList());
|
|
|
|
+ //byte[] bytes = pl.ReadMultipleBytes(27, 50).ToArray();
|
|
|
|
+ //string str2 = Encoding.ASCII.GetString(bytes);
|
|
|
|
+ //Console.WriteLine(str2);
|
|
|
|
+ //if (str == str2)
|
|
|
|
+ //{
|
|
|
|
+ // Console.WriteLine("equals");
|
|
|
|
+ //}
|
|
|
|
+ //else
|
|
|
|
+ //{
|
|
|
|
+ // Console.WriteLine("error, unequal");
|
|
|
|
+ //}
|
|
|
|
+
|
|
|
|
+ Thread.Sleep(2000);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ t.Wait();
|
|
|
|
+ }
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// PLCLinker构造函数
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="cpu"></param>
|
|
|
|
+ /// <param name="ip"></param>
|
|
|
|
+ /// <param name="rack"></param>
|
|
|
|
+ /// <param name="slot"></param>
|
|
|
|
+ /// <param name="terminalDB"></param>
|
|
|
|
+ /// <param name="centralDB"></param>
|
|
|
|
+ /// <param name="parkingSpaceDB"></param>
|
|
|
|
+ public PLCLinker(CpuType cpu, string ip, short rack, short slot, int terminalDB, int centralDB, int parkingSpaceDB, int terminalCount, int parkingSpaceCount)
|
|
|
|
+ {
|
|
|
|
+ this.cpu = cpu;
|
|
|
|
+ this.ip = ip;
|
|
|
|
+ this.rack = rack;
|
|
|
|
+ this.slot = slot;
|
|
|
|
+ this.terminalDB = terminalDB;
|
|
|
|
+ this.centralDB = centralDB;
|
|
|
|
+ this.parkingSpaceDB = parkingSpaceDB;
|
|
|
|
+ this.terminalCount = terminalCount;
|
|
|
|
+ this.parkingSpaceCount = parkingSpaceCount;
|
|
|
|
+ PLCConnect(cpu, ip, rack, slot);
|
|
|
|
+ }
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 读取指定数据块中多个字节
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="db"></param>
|
|
|
|
+ /// <param name="length"></param>
|
|
|
|
+ /// <param name="startAddr"></param>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ private List<byte> ReadMultipleBytes(int db, int length, int startAddr = 0)
|
|
{
|
|
{
|
|
List<byte> resultBytes = new List<byte>();
|
|
List<byte> resultBytes = new List<byte>();
|
|
int index = startAddr;
|
|
int index = startAddr;
|
|
@@ -98,161 +193,289 @@ namespace PLCLinker
|
|
while (remains > 0)
|
|
while (remains > 0)
|
|
{
|
|
{
|
|
int maxToRead = Math.Min(remains, 200);
|
|
int maxToRead = Math.Min(remains, 200);
|
|
- byte[] temp = plc.ReadBytes(DataType.DataBlock, db, index, maxToRead);
|
|
|
|
- if (temp == null)
|
|
|
|
- return new List<byte>();
|
|
|
|
- resultBytes.AddRange(temp);
|
|
|
|
- remains -= maxToRead;
|
|
|
|
- index += maxToRead;
|
|
|
|
|
|
+ try
|
|
|
|
+ {
|
|
|
|
+ byte[] temp = plc.ReadBytes(DataType.DataBlock, db, index, maxToRead);
|
|
|
|
+ if (temp == null)
|
|
|
|
+ return new List<byte>();
|
|
|
|
+ resultBytes.AddRange(temp);
|
|
|
|
+ remains -= maxToRead;
|
|
|
|
+ index += maxToRead;
|
|
|
|
+ }
|
|
|
|
+ catch { }
|
|
}
|
|
}
|
|
return resultBytes;
|
|
return resultBytes;
|
|
}
|
|
}
|
|
- public void WriteMultipleBytes(int db, List<byte> bytesToWrite, int startAddr = 0)
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 写入指定数据块中多个字节
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="db"></param>
|
|
|
|
+ /// <param name="bytesToWrite"></param>
|
|
|
|
+ /// <param name="startAddr"></param>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ private ErrorCode WriteMultipleBytes(int db, List<byte> bytesToWrite, int startAddr = 0)
|
|
{
|
|
{
|
|
int index = startAddr;
|
|
int index = startAddr;
|
|
int remains = bytesToWrite.Count();
|
|
int remains = bytesToWrite.Count();
|
|
- while (remains > 0)
|
|
|
|
- {
|
|
|
|
- int maxToWrite = Math.Min(remains, 200);
|
|
|
|
- plc.WriteBytes(DataType.DataBlock, db, index, bytesToWrite.GetRange(index, maxToWrite).ToArray());
|
|
|
|
- index += maxToWrite;
|
|
|
|
- remains -= maxToWrite;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void ReadFromPLC()
|
|
|
|
- {
|
|
|
|
- if (plc != null)
|
|
|
|
|
|
+ try
|
|
{
|
|
{
|
|
- int index = 0;
|
|
|
|
- byte[] receive = new byte[256];
|
|
|
|
- receive = plc.ReadBytes(DataType.DataBlock, 1, index, ParkEndPoint.bytesCount);
|
|
|
|
- byte[][] subStru = new byte[pe.indices.Count][];
|
|
|
|
- if (receive.Count() != 0)
|
|
|
|
|
|
+ while (remains > 0)
|
|
{
|
|
{
|
|
- for (int i = 0; i < pe.indices.Count; i++)
|
|
|
|
- {
|
|
|
|
- subStru[i] = new byte[20];
|
|
|
|
- for (int j = 0; j < pe.indices[i]; j++)
|
|
|
|
- {
|
|
|
|
- subStru[i][j] = receive[index + j];
|
|
|
|
- //if(j == pe.indices[i] - 1)
|
|
|
|
- //{
|
|
|
|
- // subStru[i][j + 1] = BitConverter.GetBytes('\0')[0];
|
|
|
|
- // subStru[i][j + 2] = BitConverter.GetBytes('\0')[1];
|
|
|
|
- //}
|
|
|
|
- }
|
|
|
|
- index += pe.indices[i];
|
|
|
|
- }
|
|
|
|
- pe.endPointNo = BitConverter.ToInt32(subStru[0], 0);
|
|
|
|
- pe.licCode = Encoding.ASCII.GetString(subStru[1]).TrimEnd('\0');
|
|
|
|
- pe.unregistered = BitConverter.ToBoolean(subStru[2], 0);
|
|
|
|
- pe.completed = BitConverter.ToBoolean(subStru[3], 0);
|
|
|
|
- pe.serialNo = Encoding.ASCII.GetString(subStru[4]).TrimEnd('\0');
|
|
|
|
- Console.WriteLine(pe.ToString());
|
|
|
|
|
|
+ int maxToWrite = Math.Min(remains, 200);
|
|
|
|
+ ErrorCode ec = plc.WriteBytes(DataType.DataBlock, db, index, bytesToWrite.GetRange(index, maxToWrite).ToArray());
|
|
|
|
+ index += maxToWrite;
|
|
|
|
+ remains -= maxToWrite;
|
|
|
|
+ if (!ec.Equals(ErrorCode.NoError)) { return ec; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ catch (Exception e) { Console.WriteLine(e.Message); }
|
|
|
|
+ return ErrorCode.NoError;
|
|
}
|
|
}
|
|
- public void WriteToPLC(ParkEndPoint pe)
|
|
|
|
- {
|
|
|
|
- if (plc != null)
|
|
|
|
- {
|
|
|
|
- Console.WriteLine("write to PLC");
|
|
|
|
- //plc.WriteClass(pe, 1);
|
|
|
|
- byte[] sendBytes = new byte[200];
|
|
|
|
- int index = 0;
|
|
|
|
- byte[] temp;
|
|
|
|
-
|
|
|
|
- temp = BitConverter.GetBytes(pe.endPointNo);
|
|
|
|
- temp.CopyTo(sendBytes, index);
|
|
|
|
- index += temp.Length;
|
|
|
|
-
|
|
|
|
- temp = Encoding.ASCII.GetBytes(pe.licCode);
|
|
|
|
- temp.CopyTo(sendBytes, index);
|
|
|
|
- index += temp.Length;
|
|
|
|
-
|
|
|
|
- temp = BitConverter.GetBytes(pe.unregistered);
|
|
|
|
- temp.CopyTo(sendBytes, index);
|
|
|
|
- index += temp.Length;
|
|
|
|
-
|
|
|
|
- temp = BitConverter.GetBytes(pe.completed);
|
|
|
|
- temp.CopyTo(sendBytes, index);
|
|
|
|
- index += temp.Length;
|
|
|
|
-
|
|
|
|
- temp = Encoding.ASCII.GetBytes(pe.serialNo);
|
|
|
|
- temp.CopyTo(sendBytes, index);
|
|
|
|
- index += temp.Length;
|
|
|
|
-
|
|
|
|
- plc.WriteBytes(DataType.DataBlock, 1, 0, sendBytes);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void ReadClassFromPLC()
|
|
|
|
- {
|
|
|
|
- object obj = plc.ReadClass<ParkEndPoint>(1, 0);
|
|
|
|
- if (obj != null) { pe = (ParkEndPoint)obj; }
|
|
|
|
- Console.WriteLine(pe.ToString());
|
|
|
|
- }
|
|
|
|
- public void WriteClassToPLC()
|
|
|
|
- {
|
|
|
|
- Console.WriteLine("write to PLC");
|
|
|
|
- plc.WriteClass(pe, 1, 0);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public object ReadStruFromPLC(object obj, int db, int startAddr = 0)
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 从PLC中读取结构体
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="obj"></param>
|
|
|
|
+ /// <param name="db"></param>
|
|
|
|
+ /// <param name="startAddr"></param>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ private object ReadStruFromPLC(object obj, int db, int startAddr = 0)
|
|
{
|
|
{
|
|
Type structType = obj.GetType();
|
|
Type structType = obj.GetType();
|
|
object returnedObj;
|
|
object returnedObj;
|
|
try
|
|
try
|
|
{
|
|
{
|
|
- returnedObj = plc.ReadStruct(structType, db, startAddr);
|
|
|
|
- //int numBytes = Struct.GetStructSize(structType);
|
|
|
|
- //// now read the package
|
|
|
|
- //var resultBytes = plc.ReadBytes(DataType.DataBlock, db, startAddr, numBytes);
|
|
|
|
-
|
|
|
|
- //// and decode it
|
|
|
|
- //returnedObj = Struct.FromBytes(structType, resultBytes);
|
|
|
|
|
|
+ //returnedObj = plc.ReadStruct(structType, db, startAddr);
|
|
|
|
+ int numBytes = Struct.GetStructSize(structType);
|
|
|
|
+ var resultBytes = plc.ReadBytes(DataType.DataBlock, db, startAddr, numBytes);
|
|
|
|
+ returnedObj = Struct.FromBytes(structType, resultBytes);
|
|
if (returnedObj != null) { return returnedObj; }
|
|
if (returnedObj != null) { return returnedObj; }
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
catch (Exception e)
|
|
{
|
|
{
|
|
Console.WriteLine(e.Message);
|
|
Console.WriteLine(e.Message);
|
|
}
|
|
}
|
|
- return Activator.CreateInstance(structType);
|
|
|
|
|
|
+ return null;
|
|
//Console.WriteLine(ts.ToString());
|
|
//Console.WriteLine(ts.ToString());
|
|
}
|
|
}
|
|
- public void WriteStruToPLC(object obj, int db, int startAddr = 0)
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 向PLC中写入结构体
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="obj"></param>
|
|
|
|
+ /// <param name="db"></param>
|
|
|
|
+ /// <param name="startAddr"></param>
|
|
|
|
+ private ErrorCode WriteStruToPLC(object obj, int db, int startAddr = 0)
|
|
{
|
|
{
|
|
Console.WriteLine("write to PLC");
|
|
Console.WriteLine("write to PLC");
|
|
ErrorCode ec = ErrorCode.NoError;
|
|
ErrorCode ec = ErrorCode.NoError;
|
|
try
|
|
try
|
|
{
|
|
{
|
|
- ec = plc.WriteStruct(obj, 22, startAddr);
|
|
|
|
|
|
+ //ec = plc.WriteStruct(obj, 22, startAddr);
|
|
|
|
+ List<byte> bList = Struct.ToBytes(obj).ToList();
|
|
|
|
+ ec = WriteMultipleBytes(db, bList, startAddr);
|
|
}
|
|
}
|
|
catch (Exception e) { Console.WriteLine(ec.ToString() + "," + e.Message); }
|
|
catch (Exception e) { Console.WriteLine(ec.ToString() + "," + e.Message); }
|
|
|
|
+ return ec;
|
|
}
|
|
}
|
|
-
|
|
|
|
- public AbstractMessage GetMessage()
|
|
|
|
|
|
+ private short BytesRevert(short num)
|
|
{
|
|
{
|
|
- throw new NotImplementedException();
|
|
|
|
|
|
+ byte[] temp = BitConverter.GetBytes(num);
|
|
|
|
+ Array.Reverse(temp);
|
|
|
|
+ return BitConverter.ToInt16(temp, 0);
|
|
}
|
|
}
|
|
-
|
|
|
|
- public void SetMessage(AbstractMessage abstractMsg)
|
|
|
|
|
|
+ private int BytesRevert(int num)
|
|
{
|
|
{
|
|
- throw new NotImplementedException();
|
|
|
|
|
|
+ byte[] temp = BitConverter.GetBytes(num);
|
|
|
|
+ Array.Reverse(temp);
|
|
|
|
+ return BitConverter.ToInt32(temp, 0);
|
|
}
|
|
}
|
|
|
|
|
|
- public void Start()
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 读取PLC数据块
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="whichToRead"></param>
|
|
|
|
+ /// <param name="index"></param>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ public override List<object> ReadFromPLC(PLCDataType whichToRead, int index)
|
|
{
|
|
{
|
|
- throw new NotImplementedException();
|
|
|
|
|
|
+ //更新设备状态
|
|
|
|
+ isConnected = plc.IsConnected;
|
|
|
|
+ List<object> result = new List<object>();
|
|
|
|
+ if (isConnected)
|
|
|
|
+ {
|
|
|
|
+ switch (whichToRead)
|
|
|
|
+ {
|
|
|
|
+ case PLCDataType.central:
|
|
|
|
+ object obj = ReadStruFromPLC(new MainBlockStru(), centralDB);
|
|
|
|
+ if (obj != null) { result.Add(obj); }
|
|
|
|
+ break;
|
|
|
|
+ case PLCDataType.terminal:
|
|
|
|
+ TerminalStru ts = new TerminalStru();
|
|
|
|
+ //index 在合理范围读取单一元素,否则全部读取
|
|
|
|
+ if (index > 0 && index < terminalCount)
|
|
|
|
+ {
|
|
|
|
+ obj = ReadStruFromPLC(ts, terminalDB, Struct.GetStructSize(ts.GetType()) * (index - 1));
|
|
|
|
+ if (obj != null) { result.Add(obj); }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ for (int i = 0; i < terminalCount; i++)
|
|
|
|
+ {
|
|
|
|
+ obj = ReadStruFromPLC(ts, terminalDB, Struct.GetStructSize(ts.GetType()) * i);
|
|
|
|
+ if (obj != null) { result.Add(obj); }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case PLCDataType.parkingSpace:
|
|
|
|
+ ParkingSpaceStru pss = new ParkingSpaceStru();
|
|
|
|
+ //index 在合理范围读取单一元素,否则全部读取
|
|
|
|
+ if (index > 0 && index < parkingSpaceCount)
|
|
|
|
+ {
|
|
|
|
+ obj = ReadStruFromPLC(pss, parkingSpaceDB, Struct.GetStructSize(pss.GetType()) * (index - 1));
|
|
|
|
+ if (obj != null) { result.Add(obj); }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ for (int i = 0; i < parkingSpaceCount; i++)
|
|
|
|
+ {
|
|
|
|
+ obj = ReadStruFromPLC(pss, parkingSpaceDB, Struct.GetStructSize(pss.GetType()) * i);
|
|
|
|
+ if (obj != null) { result.Add(obj); }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ Console.WriteLine("wrong type");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
}
|
|
}
|
|
-
|
|
|
|
- public void Stop()
|
|
|
|
|
|
+ /// <summary>
|
|
|
|
+ /// 写入PLC,其中可写入但不需写入字段请赋值为-1
|
|
|
|
+ /// </summary>
|
|
|
|
+ /// <param name="abstractPLCMsg"></param>
|
|
|
|
+ /// <param name="whoami"></param>
|
|
|
|
+ /// <returns></returns>
|
|
|
|
+ public override bool WriteToPLC(object abstractPLCMsg, PLCDataType whoami)
|
|
{
|
|
{
|
|
- if (plc != null)
|
|
|
|
|
|
+ //更新设备状态
|
|
|
|
+ isConnected = plc.IsConnected;
|
|
|
|
+ if (abstractPLCMsg == null)
|
|
|
|
+ return false;
|
|
|
|
+ if (isConnected)
|
|
{
|
|
{
|
|
- plc.Close();
|
|
|
|
|
|
+ if (abstractPLCMsg.GetType().Equals(typeof(TerminalStru)))
|
|
|
|
+ {
|
|
|
|
+ TerminalStru ts = (TerminalStru)abstractPLCMsg;
|
|
|
|
+ if (ts.terminalID < 0 || ts.terminalID >= terminalCount) { return false; }
|
|
|
|
+ int offset = 36 * (ts.terminalID - 1);
|
|
|
|
+ if (whoami.Equals(PLCDataType.central))
|
|
|
|
+ {
|
|
|
|
+ if (ts.paymentStatus != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 22 + offset, BitConverter.GetBytes(BytesRevert(ts.paymentStatus))); }
|
|
|
|
+ if (ts.licVerification != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 24 + offset, BitConverter.GetBytes(BytesRevert(ts.licVerification))); }
|
|
|
|
+ if (ts.parkingFee != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 26 + offset, BitConverter.GetBytes(BytesRevert(ts.parkingFee))); }
|
|
|
|
+ if (ts.userType != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 28 + offset, BitConverter.GetBytes(BytesRevert(ts.userType))); }
|
|
|
|
+ }
|
|
|
|
+ else if (whoami.Equals(PLCDataType.terminal))
|
|
|
|
+ {
|
|
|
|
+ if (ts.btnStatus != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 4 + offset, BitConverter.GetBytes(BytesRevert(ts.btnStatus))); }
|
|
|
|
+ if (ts.terminalStatus != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 4 + offset, BitConverter.GetBytes(BytesRevert(ts.terminalStatus))); }
|
|
|
|
+ if (ts.licenseCodeA != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 6 + offset, BitConverter.GetBytes(BytesRevert(ts.licenseCodeA))); }
|
|
|
|
+ if (ts.licenseCodeB != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 10 + offset, BitConverter.GetBytes(BytesRevert(ts.licenseCodeB))); }
|
|
|
|
+ if (ts.licenseCodeC != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 14 + offset, BitConverter.GetBytes(BytesRevert(ts.licenseCodeC))); }
|
|
|
|
+ if (ts.receiptNum != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 18 + offset, BitConverter.GetBytes(BytesRevert(ts.receiptNum))); }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if (abstractPLCMsg.GetType().Equals(typeof(MainBlockStru)) && whoami.Equals(PLCDataType.central))
|
|
|
|
+ {
|
|
|
|
+ //只允许中控写入,且中控只允许写入号牌获取状态
|
|
|
|
+ MainBlockStru mbs = (MainBlockStru)abstractPLCMsg;
|
|
|
|
+ byte[] temp = BitConverter.GetBytes(BytesRevert(mbs.licenseReceived));
|
|
|
|
+ ErrorCode ec = plc.WriteBytes(DataType.DataBlock, centralDB, mainBlockOffset, temp);
|
|
|
|
+ if (!ec.Equals(ErrorCode.NoError)) { return false; }
|
|
|
|
+ }
|
|
|
|
+ else if (abstractPLCMsg.GetType().Equals(typeof(ParkingSpaceStru)) && whoami.Equals(PLCDataType.central))
|
|
|
|
+ {
|
|
|
|
+ //只允许中控写入,中控只允许写车位状态
|
|
|
|
+ ParkingSpaceStru pss = (ParkingSpaceStru)abstractPLCMsg;
|
|
|
|
+ int offset = 24 * (pss.parkingSpace - 1) + parkingSpaceOffset;
|
|
|
|
+ byte[] temp = BitConverter.GetBytes(BytesRevert(pss.spaceStatus));
|
|
|
|
+ ErrorCode ec = plc.WriteBytes(DataType.DataBlock, parkingSpaceDB, offset, temp);
|
|
|
|
+ if (!ec.Equals(ErrorCode.NoError)) { return false; }
|
|
|
|
+ }
|
|
|
|
+ else { return false; }
|
|
}
|
|
}
|
|
|
|
+ else { return false; }
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ //public void ReadFromPLC()
|
|
|
|
+ //{
|
|
|
|
+ // if (plc != null)
|
|
|
|
+ // {
|
|
|
|
+ // int index = 0;
|
|
|
|
+ // byte[] receive = new byte[256];
|
|
|
|
+ // receive = plc.ReadBytes(DataType.DataBlock, 1, index, ParkEndPoint.bytesCount);
|
|
|
|
+ // byte[][] subStru = new byte[pe.indices.Count][];
|
|
|
|
+ // if (receive.Count() != 0)
|
|
|
|
+ // {
|
|
|
|
+ // for (int i = 0; i < pe.indices.Count; i++)
|
|
|
|
+ // {
|
|
|
|
+ // subStru[i] = new byte[20];
|
|
|
|
+ // for (int j = 0; j < pe.indices[i]; j++)
|
|
|
|
+ // {
|
|
|
|
+ // subStru[i][j] = receive[index + j];
|
|
|
|
+ // //if(j == pe.indices[i] - 1)
|
|
|
|
+ // //{
|
|
|
|
+ // // subStru[i][j + 1] = BitConverter.GetBytes('\0')[0];
|
|
|
|
+ // // subStru[i][j + 2] = BitConverter.GetBytes('\0')[1];
|
|
|
|
+ // //}
|
|
|
|
+ // }
|
|
|
|
+ // index += pe.indices[i];
|
|
|
|
+ // }
|
|
|
|
+ // pe.endPointNo = BitConverter.ToInt32(subStru[0], 0);
|
|
|
|
+ // pe.licCode = Encoding.ASCII.GetString(subStru[1]).TrimEnd('\0');
|
|
|
|
+ // pe.unregistered = BitConverter.ToBoolean(subStru[2], 0);
|
|
|
|
+ // pe.completed = BitConverter.ToBoolean(subStru[3], 0);
|
|
|
|
+ // pe.serialNo = Encoding.ASCII.GetString(subStru[4]).TrimEnd('\0');
|
|
|
|
+ // Console.WriteLine(pe.ToString());
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+ //}
|
|
|
|
+ //public void WriteToPLC(ParkEndPoint pe)
|
|
|
|
+ //{
|
|
|
|
+ // if (plc != null)
|
|
|
|
+ // {
|
|
|
|
+ // Console.WriteLine("write to PLC");
|
|
|
|
+ // //plc.WriteClass(pe, 1);
|
|
|
|
+ // byte[] sendBytes = new byte[200];
|
|
|
|
+ // int index = 0;
|
|
|
|
+ // byte[] temp;
|
|
|
|
+
|
|
|
|
+ // temp = BitConverter.GetBytes(pe.endPointNo);
|
|
|
|
+ // temp.CopyTo(sendBytes, index);
|
|
|
|
+ // index += temp.Length;
|
|
|
|
+
|
|
|
|
+ // temp = Encoding.ASCII.GetBytes(pe.licCode);
|
|
|
|
+ // temp.CopyTo(sendBytes, index);
|
|
|
|
+ // index += temp.Length;
|
|
|
|
+
|
|
|
|
+ // temp = BitConverter.GetBytes(pe.unregistered);
|
|
|
|
+ // temp.CopyTo(sendBytes, index);
|
|
|
|
+ // index += temp.Length;
|
|
|
|
+
|
|
|
|
+ // temp = BitConverter.GetBytes(pe.completed);
|
|
|
|
+ // temp.CopyTo(sendBytes, index);
|
|
|
|
+ // index += temp.Length;
|
|
|
|
+
|
|
|
|
+ // temp = Encoding.ASCII.GetBytes(pe.serialNo);
|
|
|
|
+ // temp.CopyTo(sendBytes, index);
|
|
|
|
+ // index += temp.Length;
|
|
|
|
+
|
|
|
|
+ // plc.WriteBytes(DataType.DataBlock, 1, 0, sendBytes);
|
|
|
|
+ // }
|
|
|
|
+ //}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|