liudl
2025-02-16 ddd9612ed7cefe12c8ea33ced0711a0b9a3feb99
Admin.NET/WCS.Application/PLC/PLCUtil.cs
@@ -1,4 +1,5 @@
using DocumentFormat.OpenXml.Bibliography;
using DocumentFormat.OpenXml.Drawing;
using Elastic.Clients.Elasticsearch;
using IoTClient;
using IoTClient.Clients.Modbus;
@@ -6,24 +7,30 @@
using IoTClient.Common.Enums;
using IoTClient.Enums;
using IoTClient.Interfaces;
using System.Text;
using System.Text.RegularExpressions;
namespace WCS.Application;
public class PLCUtil
{
    public readonly long PlcId;
    public readonly string PlcIP;
    private SiemensClient _client;
    private WcsPlc _modPlc;
    private Task<WcsPlc> modPlc;
    private readonly object OLock = new object();
    public PLCUtil(WcsPlc modPlc)
    {
        PlcId = modPlc.Id;
        PlcIP = modPlc.IP;
        _modPlc = modPlc;
        _client = new SiemensClient((SiemensVersion)modPlc.PLCType, modPlc.IP, modPlc.Port);
        _client.Open();
    }
    public bool Connected()
    public bool Connected
    {
        return _client.Connected;
        get { return _client.Connected; }
    }
    public IoTClient.Result Open()
    {
@@ -39,55 +46,121 @@
    /// <param name="DbNumber">DB区指定值</param>
    /// <param name="PosType">字符类型</param>
    /// <param name="Pos">偏移量/地址</param>
    /// <param name="Length">长度(字符串)</param>
    /// <returns></returns>
    public (IoTClient.Result, dynamic value) GetPlcDBValue(PLCDataTypeEnum PosType, string DbNumber, string Pos)
    public (IoTClient.Result, dynamic value) GetPlcDBValue(PLCDataTypeEnum PosType, string DbNumber, string Pos, int? Length = 0)
    {
        string address;
        if (DbNumber.StartsWith("DB"))
            address = DbNumber + "." + Pos;
        else
            address = DbNumber + Pos;
        dynamic result = null;
        switch (PosType)
        lock (OLock)
        {
            case PLCDataTypeEnum.Bit:
                result = _client.ReadBoolean(address);
                break;
            case PLCDataTypeEnum.Byte:
                result = _client.ReadByte(address);
                break;
            case PLCDataTypeEnum.Short:
                result = _client.ReadInt16(address);
                break;
            case PLCDataTypeEnum.UShort:
                result = _client.ReadUInt16(address);
                break;
            case PLCDataTypeEnum.Int:
                result = _client.ReadInt32(address);
                break;
            case PLCDataTypeEnum.UInt:
                result = _client.ReadUInt32(address);
                break;
            case PLCDataTypeEnum.Long:
                result = _client.ReadInt64(address);
                break;
            case PLCDataTypeEnum.ULong:
                result = _client.ReadUInt64(address);
                break;
            case PLCDataTypeEnum.Float:
                result = _client.ReadFloat(address);
                break;
            case PLCDataTypeEnum.Double:
                result = _client.ReadDouble(address);
                break;
            case PLCDataTypeEnum.String:
                result = _client.ReadString(address);
                break;
            default:
                result = new IoTClient.Result<object>();
                break;
            string address;
            if (DbNumber.StartsWith("DB"))
                address = DbNumber + "." + Pos;
            else
                address = DbNumber + Pos;
            return this.GetPlcDBValue(PosType, address, Length);
        }
        return (result, result.Value);
    }
    /// <summary>
    /// 读取PLC值
    /// </summary>
    /// <param name="PosType">字符类型</param>
    /// <param name="Pos">偏移量/地址</param>
    /// <param name="Length">长度(字符串)</param>
    /// <returns></returns>
    public (IoTClient.Result, dynamic value) GetPlcDBValue(PLCDataTypeEnum PosType, string Pos, int? Length = 0)
    {
        lock (OLock)
        {
            dynamic result = null;
            switch (PosType)
            {
                case PLCDataTypeEnum.Bit:
                    result = _client.ReadBoolean(Pos);
                    break;
                case PLCDataTypeEnum.Byte:
                    result = _client.ReadByte(Pos);
                    break;
                case PLCDataTypeEnum.Short:
                    result = _client.ReadInt16(Pos);
                    break;
                case PLCDataTypeEnum.UShort:
                    result = _client.ReadUInt16(Pos);
                    break;
                case PLCDataTypeEnum.Int:
                    result = _client.ReadInt32(Pos);
                    break;
                case PLCDataTypeEnum.UInt:
                    result = _client.ReadUInt32(Pos);
                    break;
                case PLCDataTypeEnum.Long:
                    result = _client.ReadInt64(Pos);
                    break;
                case PLCDataTypeEnum.ULong:
                    result = _client.ReadUInt64(Pos);
                    break;
                case PLCDataTypeEnum.Float:
                    result = _client.ReadFloat(Pos);
                    break;
                case PLCDataTypeEnum.Double:
                    result = _client.ReadDouble(Pos);
                    break;
                case PLCDataTypeEnum.String:
                    {
                        string dpos = IncrementCode(Pos);
                        Result<byte[]> result1 = _client.ReadString(Pos, 1);
                        if (result1.IsSucceed)
                        {
                            Result<byte[]> result2 = _client.ReadString(dpos, (ushort)(result1.Value[0]));
                            Result<string> result3 = new Result<string>(result2);
                            if (result3.IsSucceed)
                            {
                                result3.Value = Encoding.ASCII.GetString(result2.Value, 0, result1.Value[0]).Replace("\0", "");
                                result = result3;
                            }
                        }
                        else
                        {
                            result = result1;
                        }
                    }
                    break;
                default:
                    result = new IoTClient.Result<object>();
                    break;
            }
            return (result, result.Value);
        }
    }
    public static string IncrementCode(string code, int index = 2)
    {
        // 使用正则表达式解析字符串
        var match = Regex.Match(code, @"([A-Za-z]+)(\d+)(?:\.(\d+))?");
        if (match.Success)
        {
            // 提取字母部分
            string prefix = match.Groups[1].Value;
            // 提取数字部分
            int number1 = int.Parse(match.Groups[2].Value);
            int number2 = match.Groups[3].Success ? int.Parse(match.Groups[3].Value) : 0;
            // 处理规则
            if (match.Groups[3].Success)
            {
                // 如果有小数点分隔部分,增加2
                number2 += index;
                return $"{prefix}{number1}.{number2:D3}";
            }
            else
            {
                // 没有小数点分隔部分的,增加2
                number1 += index;
                return $"{prefix}{number1}";
            }
        }
        // 如果不匹配,返回原字符串
        return code;
    }
    /// <summary>
    /// 批量读取PLC值
@@ -95,49 +168,52 @@
    /// <returns></returns>
    public Result<Dictionary<string, object>> GetPlcBatchDBValue(Dictionary<string, PLCDataTypeEnum> listaddress)
    {
        Dictionary<string, DataTypeEnum> addresses = new Dictionary<string, DataTypeEnum>();
        foreach (var address in listaddress)
        lock (OLock)
        {
            switch (address.Value)
            Dictionary<string, DataTypeEnum> addresses = new Dictionary<string, DataTypeEnum>();
            foreach (var address in listaddress)
            {
                case PLCDataTypeEnum.Bit:
                    addresses.Add(address.Key, DataTypeEnum.Bool);
                    break;
                case PLCDataTypeEnum.Byte:
                    addresses.Add(address.Key, DataTypeEnum.Byte);
                    break;
                case PLCDataTypeEnum.Short:
                    addresses.Add(address.Key, DataTypeEnum.Int16);
                    break;
                case PLCDataTypeEnum.UShort:
                    addresses.Add(address.Key, DataTypeEnum.UInt16);
                    break;
                case PLCDataTypeEnum.Int:
                    addresses.Add(address.Key, DataTypeEnum.Int32);
                    break;
                case PLCDataTypeEnum.UInt:
                    addresses.Add(address.Key, DataTypeEnum.UInt32);
                    break;
                case PLCDataTypeEnum.Long:
                    addresses.Add(address.Key, DataTypeEnum.Int64);
                    break;
                case PLCDataTypeEnum.ULong:
                    addresses.Add(address.Key, DataTypeEnum.UInt64);
                    break;
                case PLCDataTypeEnum.Float:
                    addresses.Add(address.Key, DataTypeEnum.Float);
                    break;
                case PLCDataTypeEnum.Double:
                    addresses.Add(address.Key, DataTypeEnum.Double);
                    break;
                case PLCDataTypeEnum.String:
                    addresses.Add(address.Key, DataTypeEnum.String);
                    break;
                default:
                    break;
                switch (address.Value)
                {
                    case PLCDataTypeEnum.Bit:
                        addresses.Add(address.Key, DataTypeEnum.Bool);
                        break;
                    case PLCDataTypeEnum.Byte:
                        addresses.Add(address.Key, DataTypeEnum.Byte);
                        break;
                    case PLCDataTypeEnum.Short:
                        addresses.Add(address.Key, DataTypeEnum.Int16);
                        break;
                    case PLCDataTypeEnum.UShort:
                        addresses.Add(address.Key, DataTypeEnum.UInt16);
                        break;
                    case PLCDataTypeEnum.Int:
                        addresses.Add(address.Key, DataTypeEnum.Int32);
                        break;
                    case PLCDataTypeEnum.UInt:
                        addresses.Add(address.Key, DataTypeEnum.UInt32);
                        break;
                    case PLCDataTypeEnum.Long:
                        addresses.Add(address.Key, DataTypeEnum.Int64);
                        break;
                    case PLCDataTypeEnum.ULong:
                        addresses.Add(address.Key, DataTypeEnum.UInt64);
                        break;
                    case PLCDataTypeEnum.Float:
                        addresses.Add(address.Key, DataTypeEnum.Float);
                        break;
                    case PLCDataTypeEnum.Double:
                        addresses.Add(address.Key, DataTypeEnum.Double);
                        break;
                    case PLCDataTypeEnum.String:
                        addresses.Add(address.Key, DataTypeEnum.String);
                        break;
                    default:
                        break;
                }
            }
            return _client.BatchRead(addresses);
        }
        return _client.BatchRead(addresses);
    }
    /// <summary>
    /// 写入PLC值
@@ -149,6 +225,26 @@
            address = DbNumber + "." + Pos;
        else
            address = DbNumber + Pos;
        return this.SetPlcDBValue(PosType, address, Value);
    }
    /// <summary>
    /// 写入PLC值
    /// </summary>
    //public IoTClient.Result SetPlcDBValue(PLCDataTypeEnum PosType, string DbNumber, string Pos, byte Value)
    //{
    //    string address;
    //    if (DbNumber.StartsWith("DB"))
    //        address = DbNumber + "." + Pos;
    //    else
    //        address = DbNumber + Pos;
    //    return this.SetPlcDBValue(PosType, address, Value);
    //}
    /// <summary>
    /// 写入PLC值
    /// </summary>
    public IoTClient.Result SetPlcDBValue(PLCDataTypeEnum PosType, string Pos, string Value)
    {
        switch (PosType)
        {
            case PLCDataTypeEnum.Bit:
@@ -163,25 +259,30 @@
                        throw new Exception("写入值错误");
                    }
                }
                return _client.Write(address, bit);
                return _client.Write(Pos, bit);
            case PLCDataTypeEnum.Byte:
                return _client.Write(address, byte.Parse(Value));
                return _client.Write(Pos, byte.Parse(Value));
            case PLCDataTypeEnum.Short:
                return _client.Write(address, short.Parse(Value));
                return _client.Write(Pos, short.Parse(Value));
            case PLCDataTypeEnum.UShort:
                return _client.Write(address, ushort.Parse(Value));
                return _client.Write(Pos, ushort.Parse(Value));
            case PLCDataTypeEnum.Int:
                return _client.Write(address, int.Parse(Value));
                return _client.Write(Pos, int.Parse(Value));
            case PLCDataTypeEnum.UInt:
                return _client.Write(address, uint.Parse(Value));
                return _client.Write(Pos, uint.Parse(Value));
            case PLCDataTypeEnum.Long:
                return _client.Write(address, long.Parse(Value));
                return _client.Write(Pos, long.Parse(Value));
            case PLCDataTypeEnum.ULong:
                return _client.Write(address, ulong.Parse(Value));
                return _client.Write(Pos, ulong.Parse(Value));
            case PLCDataTypeEnum.Float:
                return _client.Write(address, float.Parse(Value));
                return _client.Write(Pos, float.Parse(Value));
            case PLCDataTypeEnum.Double:
                return _client.Write(address, float.Parse(Value));
                return _client.Write(Pos, float.Parse(Value));
            case PLCDataTypeEnum.String:
                {
                    string dpos = IncrementCode(Pos, 1);
                    return _client.Write(dpos, Value);
                }
            default:
                return new IoTClient.Result();
        }