hwh
2024-10-12 1dff5c1f690299efcd0fc456eb7d7d20c503775b
Modbus读写
1个文件已添加
273 ■■■■■ 已修改文件
Admin.NET/WCS.Application/PLC/ModbusUtil.cs 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/PLC/ModbusUtil.cs
New file
@@ -0,0 +1,273 @@
using IoTClient;
using IoTClient.Clients.Modbus;
using IoTClient.Common.Enums;
using IoTClient.Enums;
using IoTClient.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WCS.Application;
/// <summary>
/// Modbus
/// </summary>
public class ModbusUtil
{
    public readonly long PlcId;
    public readonly string PlcIP;
    private ModbusTcpClient _client;
    private WcsPlc _modPlc;
    private readonly object OLock = new object();
    public ModbusUtil(WcsPlc modPlc)
    {
        //测试代码
        //WCS.Application.ModbusUtil modUtil = new WCS.Application.ModbusUtil(new WCS.Application.WcsPlc() { IP = "127.0.0.1", Port = 502 });
        //var result = modUtil.GetDBValue(WCS.Application.PLCDataTypeEnum.Int, "4");
        //Console.WriteLine(result.value);
        //var result2 = modUtil.SetDBValue(WCS.Application.PLCDataTypeEnum.Int, "4", "44");
        //Console.WriteLine(result2.IsSucceed);
        PlcId = modPlc.Id;
        PlcIP = modPlc.IP;
        _modPlc = modPlc;
        _client = new ModbusTcpClient(modPlc.IP, modPlc.Port);
        _client.Open();
    }
    public bool Connected
    {
        get { return _client.Connected; }
    }
    public IoTClient.Result Open()
    {
        return _client.Open();
    }
    public IoTClient.Result Close()
    {
        return _client.Close();
    }
    /// <summary>
    /// 读取PLC值
    /// </summary>
    /// <param name="PosType">字符类型</param>
    /// <param name="Pos">偏移量/地址</param>
    /// <param name="StationNumber">站号</param>
    /// <returns></returns>
    public (IoTClient.Result, dynamic value) GetDBValue(PLCDataTypeEnum PosType, string Pos, byte StationNumber = 1)
    {
        lock (OLock)
        {
            dynamic result = null;
            switch (PosType)
            {
                case PLCDataTypeEnum.Bit:
                    result = _client.ReadCoil(Pos, StationNumber);
                    break;
                case PLCDataTypeEnum.Byte:
                    result = _client.ReadDiscrete(Pos, StationNumber);
                    break;
                case PLCDataTypeEnum.Short:
                    result = _client.ReadInt16(Pos, StationNumber);
                    break;
                case PLCDataTypeEnum.UShort:
                    result = _client.ReadUInt16(Pos, StationNumber);
                    break;
                case PLCDataTypeEnum.Int:
                    result = _client.ReadInt32(Pos, StationNumber);
                    break;
                case PLCDataTypeEnum.UInt:
                    result = _client.ReadUInt32(Pos, StationNumber);
                    break;
                case PLCDataTypeEnum.Long:
                    result = _client.ReadInt64(Pos, StationNumber);
                    break;
                case PLCDataTypeEnum.ULong:
                    result = _client.ReadUInt64(Pos, StationNumber);
                    break;
                case PLCDataTypeEnum.Float:
                    result = _client.ReadFloat(Pos, StationNumber);
                    break;
                case PLCDataTypeEnum.Double:
                    result = _client.ReadDouble(Pos, StationNumber);
                    break;
                case PLCDataTypeEnum.String:
                    result = _client.ReadString(Pos, StationNumber);
                    break;
                default:
                    result = new IoTClient.Result<object>();
                    break;
            }
            return (result, result.Value);
        }
    }
    /// <summary>
    /// 批量读取PLC值
    /// </summary>
    /// <returns></returns>
    public Result<List<ModbusOutput>> GetBatchDBValue(Dictionary<string, PLCDataTypeEnum> listaddress)
    {
        lock (OLock)
        {
            var list = new List<ModbusInput>();
            foreach (var address in listaddress)
            {
                switch (address.Value)
                {
                    case PLCDataTypeEnum.Bit:
                        list.Add(new ModbusInput()
                        {
                            Address = address.Key,
                            DataType = DataTypeEnum.Bool,
                            FunctionCode = 3,
                            StationNumber = 1
                        });
                        break;
                    case PLCDataTypeEnum.Byte:
                        list.Add(new ModbusInput()
                        {
                            Address = address.Key,
                            DataType = DataTypeEnum.Byte,
                            FunctionCode = 3,
                            StationNumber = 1
                        });
                        break;
                    case PLCDataTypeEnum.Short:
                        list.Add(new ModbusInput()
                        {
                            Address = address.Key,
                            DataType = DataTypeEnum.Int16,
                            FunctionCode = 3,
                            StationNumber = 1
                        });
                        break;
                    case PLCDataTypeEnum.UShort:
                        list.Add(new ModbusInput()
                        {
                            Address = address.Key,
                            DataType = DataTypeEnum.UInt16,
                            FunctionCode = 3,
                            StationNumber = 1
                        });
                        break;
                    case PLCDataTypeEnum.Int:
                        list.Add(new ModbusInput()
                        {
                            Address = address.Key,
                            DataType = DataTypeEnum.Int32,
                            FunctionCode = 3,
                            StationNumber = 1
                        });
                        break;
                    case PLCDataTypeEnum.UInt:
                        list.Add(new ModbusInput()
                        {
                            Address = address.Key,
                            DataType = DataTypeEnum.UInt32,
                            FunctionCode = 3,
                            StationNumber = 1
                        });
                        break;
                    case PLCDataTypeEnum.Long:
                        list.Add(new ModbusInput()
                        {
                            Address = address.Key,
                            DataType = DataTypeEnum.Int64,
                            FunctionCode = 3,
                            StationNumber = 1
                        });
                        break;
                    case PLCDataTypeEnum.ULong:
                        list.Add(new ModbusInput()
                        {
                            Address = address.Key,
                            DataType = DataTypeEnum.UInt64,
                            FunctionCode = 3,
                            StationNumber = 1
                        });
                        break;
                    case PLCDataTypeEnum.Float:
                        list.Add(new ModbusInput()
                        {
                            Address = address.Key,
                            DataType = DataTypeEnum.Float,
                            FunctionCode = 3,
                            StationNumber = 1
                        });
                        break;
                    case PLCDataTypeEnum.Double:
                        list.Add(new ModbusInput()
                        {
                            Address = address.Key,
                            DataType = DataTypeEnum.Double,
                            FunctionCode = 3,
                            StationNumber = 1
                        });
                        break;
                    case PLCDataTypeEnum.String:
                        list.Add(new ModbusInput()
                        {
                            Address = address.Key,
                            DataType = DataTypeEnum.String,
                            FunctionCode = 3,
                            StationNumber = 1
                        });
                        break;
                    default:
                        break;
                }
            }
            return _client.BatchRead(list);
        }
    }
    /// <summary>
    /// 写入PLC值
    /// </summary>
    /// <param name="PosType">字符类型</param>
    /// <param name="Pos">偏移量/地址</param>
    /// <param name="Value">写入值</param>
    /// <param name="StationNumber">站号</param>
    /// <returns></returns>
    public IoTClient.Result SetDBValue(PLCDataTypeEnum PosType, string Pos, string Value, byte StationNumber = 1)
    {
        switch (PosType)
        {
            case PLCDataTypeEnum.Bit:
                if (!bool.TryParse(Value, out bool bit))
                {
                    if (Value == "0")
                        bit = false;
                    else if (Value == "1")
                        bit = true;
                    else
                    {
                        throw new Exception("写入值错误");
                    }
                }
                return _client.Write(Pos, bit, StationNumber);
            case PLCDataTypeEnum.Byte:
                return _client.Write(Pos, byte.Parse(Value), StationNumber);
            case PLCDataTypeEnum.Short:
                return _client.Write(Pos, short.Parse(Value), StationNumber);
            case PLCDataTypeEnum.UShort:
                return _client.Write(Pos, ushort.Parse(Value), StationNumber);
            case PLCDataTypeEnum.Int:
                return _client.Write(Pos, int.Parse(Value), StationNumber);
            case PLCDataTypeEnum.UInt:
                return _client.Write(Pos, uint.Parse(Value), StationNumber);
            case PLCDataTypeEnum.Long:
                return _client.Write(Pos, long.Parse(Value), StationNumber);
            case PLCDataTypeEnum.ULong:
                return _client.Write(Pos, ulong.Parse(Value), StationNumber);
            case PLCDataTypeEnum.Float:
                return _client.Write(Pos, float.Parse(Value), StationNumber);
            case PLCDataTypeEnum.Double:
                return _client.Write(Pos, float.Parse(Value), StationNumber);
            case PLCDataTypeEnum.String:
                return _client.Write(Pos, Value, StationNumber);
            default:
                return new IoTClient.Result();
        }
    }
}