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; /// /// Modbus /// 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(); } /// /// 读取PLC值 /// /// 字符类型 /// 偏移量/地址 /// 站号 /// 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(); break; } return (result, result.Value); } } /// /// 批量读取PLC值 /// /// public Result> GetBatchDBValue(Dictionary listaddress) { lock (OLock) { var list = new List(); 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); } } /// /// 写入PLC值 /// /// 字符类型 /// 偏移量/地址 /// 写入值 /// 站号 /// 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(); } } }