wanshenmean
10 小时以前 c9a1df9c19a64844d05d120ff171f523d77e7823
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Communicator/Siemens/SiemensS7Communicator.cs
@@ -1,4 +1,5 @@
#region << 版 本 注 释 >>
/*----------------------------------------------------------------
 * 命名空间:WIDESEAWCS_Communicator
 * 创建者:胡童庆
@@ -11,8 +12,9 @@
 * 修改时间:
 * 版本:V1.0.1
 * 修改说明:
 *
 *
 *----------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
using HslCommunication;
@@ -20,19 +22,12 @@
using HslCommunication.LogNet;
using HslCommunication.Profinet.Siemens;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace WIDESEAWCS_Communicator
{
@@ -43,6 +38,7 @@
    public class SiemensS7 : BaseCommunicator
    {
        #region Private Member
        /// <summary>
        /// HSLCommunication的西门子的S7协议的通讯类
        /// </summary>
@@ -59,7 +55,7 @@
        private int _port;
        /// <summary>
        /// 当前通讯器是否已连接到PLC。
        /// 当前通讯器是否已连接到PLC。
        /// </summary>
        private bool _connected;
@@ -71,11 +67,13 @@
        private ILogNet _logNet;
        private bool _isPing = true;
        #endregion Private Member
        #region Public Member
        /// <summary>
        /// 获取当前通讯器是否已连接到PLC。
        /// <summary>
        /// 获取当前通讯器是否已连接到PLC。
        /// </summary>
        public override bool IsConnected => _connected;
@@ -92,10 +90,12 @@
        /// <summary>
        /// 是否在写入数据后读取数据确认。
        /// </summary>
        public override bool IsReadAfterWrite { get; set; } = false;
        public override bool IsReadAfterWrite { get; set; } = true;
        #endregion Public Member
        #region Constructor Function
        /// <summary>
        /// 构造函数
        /// </summary>
@@ -118,9 +118,11 @@
            _port = port;//通过构造函数赋值连接使用的端口号
            _name = name;
        }
        #endregion
        #region Private Method
        /// <summary>
        /// 从OperateResult对象中获取读取的数据。
        /// </summary>
@@ -150,7 +152,7 @@
        }
        /// <summary>
        ///
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="operateResult"></param>
@@ -221,27 +223,36 @@
            try
            {
                Type type = value.GetType();
                switch (Type.GetTypeCode(type))
                {
                    case TypeCode.Int32:
                        return plc.Write(address, Convert.ToInt32(value));
                    case TypeCode.UInt32:
                        return plc.Write(address, Convert.ToUInt32(value));
                    case TypeCode.Int16:
                        return plc.Write(address, Convert.ToInt16(value));
                    case TypeCode.UInt16:
                        return plc.Write(address, Convert.ToUInt16(value));
                    case TypeCode.Single:
                        return plc.Write(address, Convert.ToSingle(value));
                    case TypeCode.Boolean:
                        return plc.Write(address, Convert.ToBoolean(value));
                    case TypeCode.Byte:
                        return plc.Write(address, Convert.ToByte(value));
                    case TypeCode.String:
                        return plc.Write(address, Convert.ToString(value));
                    case TypeCode.Char:
                        return plc.Write(address, Convert.ToChar(value));
                    //case TypeCode.arr:
                    //    return plc.Write(address, Convert.ToChar(value));
                    default:
                        if (value is int[])
                        {
@@ -300,44 +311,53 @@
                            return (int[])GetContent(plc.ReadInt32(address, length), address);
                        else
                            return (int)GetContent(plc.ReadInt32(address), address);
                    case TypeCode.UInt32:
                        if (length > 1)
                            return (uint[])GetContent(plc.ReadUInt32(address, length), address);
                        else
                            return (uint)GetContent(plc.ReadUInt32(address), address);
                    case TypeCode.Int16:
                        if (length > 1)
                            return (short[])GetContent(plc.ReadInt16(address, length), address);
                        else
                            return (short)GetContent(plc.ReadInt16(address), address);
                    case TypeCode.UInt16:
                        if (length > 1)
                            return (ushort[])GetContent(plc.ReadUInt16(address, length), address);
                        else
                            return (ushort)GetContent(plc.ReadUInt16(address), address);
                    case TypeCode.Single:
                        if (length > 1)
                            return (float[])GetContent(plc.ReadFloat(address, length), address);
                        else
                            return (float)GetContent(plc.ReadFloat(address), address);
                    case TypeCode.Boolean:
                        if (length > 1)
                            return (bool[])GetContent(plc.ReadBool(address, length), address);
                        else
                            return (bool)GetContent(plc.ReadBool(address), address);
                    case TypeCode.Byte:
                        if (length > 1)
                            return (byte)GetContent(plc.Read(address, length), address);
                        return (byte)GetContent(plc.ReadByte(address), address);
                    case TypeCode.String:
                        if (length > 1)
                            return (string)GetContent(plc.ReadString(address, length), address);
                        else
                            return (string)GetContent(plc.ReadString(address), address);
                    case TypeCode.Char:
                        if (length > 1)
                            return Encoding.Default.GetString((byte[])GetContent(plc.Read(address, length), address)).ToArray();
                        return (char)GetContent(plc.ReadByte(address), address);
                    default:
                        throw new CommunicationException(string.Format(CommunicationExceptionMessage.DataTypeErrorException, typeCode.ToString(), address), CommunicationErrorType.TypeError);
                }
@@ -374,14 +394,15 @@
                    }
                }
            });
        }
        #endregion
        #region Public Method
        /// <summary>
        /// <summary>
        /// 连接到PLC。
        /// </summary>
        /// </summary>
        /// <returns>如果连接成功则返回true,否则返回false。</returns>
        /// <exception cref="CommunicationException">自定义通讯异常类</exception>
        public override bool Connect()
@@ -414,10 +435,10 @@
            }
        }
        /// <summary>
        /// 断开与工业设备的连接。
        /// </summary>
        /// <returns>如果成功断开连接则返回true,如果已经是断开状态则返回false。</returns>
        /// <summary>
        /// 断开与工业设备的连接。
        /// </summary>
        /// <returns>如果成功断开连接则返回true,如果已经是断开状态则返回false。</returns>
        public override bool Disconnect()
        {
            try
@@ -440,12 +461,13 @@
        }
        #region Read
        /// <summary>
        /// 从PLC读取数据。
        /// </summary>
        /// <param name="address">源地址,具体格式取决于使用的工业协议。</param>
        /// <param name="length">要读取的数据长度。</param>
        /// <returns>读取到的数据,如果读取失败则可能返回null、空数组或抛出自定义通讯异常。</returns>
        /// <summary>
        /// 从PLC读取数据。
        /// </summary>
        /// <param name="address">源地址,具体格式取决于使用的工业协议。</param>
        /// <param name="length">要读取的数据长度。</param>
        /// <returns>读取到的数据,如果读取失败则可能返回null、空数组或抛出自定义通讯异常。</returns>
        /// <exception cref="CommunicationException">自定义通讯异常类</exception>
        public override byte[] Read(string address, int length)
        {
@@ -467,7 +489,7 @@
        }
        /// <summary>
        ///
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="address"></param>
@@ -493,9 +515,11 @@
            else
                return Read(address, SiemensDBDataType.GetTypeCode(dataType));
        }
        #endregion
        #region Write
        /// <summary>
        /// 向PLC写入数据。
        /// </summary>
@@ -526,7 +550,7 @@
        }
        /// <summary>
        ///
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="address"></param>
@@ -537,7 +561,6 @@
        {
            return GetResult(Write(address, value), address, value);
        }
        public override bool Write<T>(string address, T[] values)
        {
@@ -571,6 +594,7 @@
                        obj = GetResult(Write(address, writeVal), address, writeVal);
                    }
                    break;
                case SiemensDBDataType.DataType_DW:
                    {
                        uint writeVal;
@@ -585,6 +609,7 @@
                        obj = GetResult(Write(address, writeVal), address, writeVal);
                    }
                    break;
                case SiemensDBDataType.DataType_Int:
                    {
                        short writeVal;
@@ -599,6 +624,7 @@
                        obj = GetResult(Write(address, writeVal), address, writeVal);
                    }
                    break;
                case SiemensDBDataType.DataType_W:
                    {
                        ushort writeVal;
@@ -613,6 +639,7 @@
                        obj = GetResult(Write(address, writeVal), address, writeVal);
                    }
                    break;
                case SiemensDBDataType.DataType_Float:
                    {
                        float writeVal;
@@ -627,6 +654,7 @@
                        obj = GetResult(Write(address, writeVal), address, writeVal);
                    }
                    break;
                case SiemensDBDataType.DataType_Bool:
                    {
                        bool writeVal;
@@ -641,6 +669,7 @@
                        obj = GetResult(Write(address, writeVal), address, writeVal);
                    }
                    break;
                case SiemensDBDataType.DataType_Byte:
                    {
                        byte writeVal;
@@ -655,6 +684,7 @@
                        obj = GetResult(Write(address, writeVal), address, writeVal);
                    }
                    break;
                case SiemensDBDataType.DataType_String:
                    {
                        string writeVal;
@@ -670,17 +700,36 @@
                    }
                    break;
                case SiemensDBDataType.DataType_Char:
                    break;
                case SiemensDBDataType.DataType_ByteArray:
                    {
                        byte[] writeVal;
                        try
                        {
                            writeVal = Encoding.UTF8.GetBytes(value.ToString());
                        }
                        catch (Exception ex)
                        {
                            throw new CommunicationException(string.Format(CommunicationExceptionMessage.TypeConvertError, dataType, address, value, ex.Message), CommunicationErrorType.TypeError, innerException: ex);
                        }
                        obj = GetResult(Write(address, writeVal), address, writeVal);
                    }
                    break;
                default:
                    throw new CommunicationException(string.Format(CommunicationExceptionMessage.DataTypeErrorException, dataType, address), CommunicationErrorType.TypeError);
            }
            return obj;
        }
        #endregion
        #region ReadCustomer
        /// <summary>
        /// 读取自定义的数据类型,需要继承自IDataTransfer接口,返回一个新的类型的实例对象。
        /// </summary>
@@ -699,9 +748,11 @@
                throw new CommunicationException(ex.Message, CommunicationErrorType.ReadException, innerException: ex);
            }
        }
        #endregion
        #region WriteCustomer
        /// <summary>
        /// 写入自定义类型的数据,该类型必须继承自IDataTransfer接口。
        /// </summary>
@@ -768,6 +819,7 @@
                LogNet.WriteInfo(Name, stringBuilder.ToString());
            }
        }
        #endregion
        /// <summary>
@@ -812,29 +864,36 @@
                case TypeCode.Int16:
                    OperateResult<TimeSpan> operateResultShort = plc.Wait(address, Convert.ToInt16(value), readInterval, waitTimeout);
                    return operateResultShort;
                case TypeCode.Int32:
                    OperateResult<TimeSpan> operateResultInt = plc.Wait(address, Convert.ToInt16(value), readInterval, waitTimeout);
                    return operateResultInt;
                case TypeCode.UInt16:
                    OperateResult<TimeSpan> operateResultUShort = plc.Wait(address, Convert.ToInt16(value), readInterval, waitTimeout);
                    return operateResultUShort;
                case TypeCode.UInt32:
                    OperateResult<TimeSpan> operateResultUInt = plc.Wait(address, Convert.ToInt16(value), readInterval, waitTimeout);
                    return operateResultUInt;
                default:
                    throw new NotSupportedException();
            }
        }
        #endregion
        #region Destruction Function
        /// <summary>
        /// 析构函数,确保在不再需要时关闭连接
        /// 析构函数,确保在不再需要时关闭连接
        /// </summary>
        ~SiemensS7()
        {
            Dispose();
        }
        #endregion
    }
}
}