using Modbus.Data; using Modbus.Device; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using TeamAAS_VP; using TeamAAS_VP.Models; using TeamAAS_VP.Resources.Languages; namespace TeamAAS_VP.Core { /// /// 后台Modbus TCP 通讯 /// public class BgModbusTcpCommunicate { public TcpListener TcpListener { get;private set; } public ModbusSlave Slave { get; private set; } BgModbusTcp Config; public string IP { get => Config.IP; } public int Port { get => Config.Port; } public byte SlaveID { get => Config.SlaveID; } public bool IsEnabled { get => Config.IsEnabled; } public BgModbusTcpCommunicate(BgModbusTcp _Config) { Config = _Config; if (!Config.IsEnabled) { return; } if (TcpListener == null) { TcpListener = new TcpListener(IPAddress.Parse(Config.IP), Config.Port); TcpListener.Start(); } Slave = ModbusTcpSlave.CreateTcp(Config.SlaveID, TcpListener); Slave.DataStore = Modbus.Data.DataStoreFactory.CreateDefaultDataStore(); Slave.ModbusSlaveRequestReceived += Slave_ModbusSlaveRequestReceived; Slave.DataStore.DataStoreWrittenTo += DataStore_DataStoreWrittenTo; Slave.DataStore.DataStoreReadFrom += DataStore_DataStoreReadFrom; } public void Listen() { Slave.Listen(); } private void Slave_ModbusSlaveRequestReceived(object sender, ModbusSlaveRequestEventArgs e) { try { switch (e.Message.FunctionCode) { case 2: break; case 4: break; default: break; } } catch (Exception ex) { LogHelper.WriteLogError(string.Format(Lang.后台Modbustcp读取0, e.Message.FunctionCode), ex); } } /// /// 当通过Modbus命令读取数据存储时发生 /// /// /// private void DataStore_DataStoreReadFrom(object sender, Modbus.Data.DataStoreEventArgs e) { try { switch (e.ModbusDataType) { case ModbusDataType.HoldingRegister: break; case ModbusDataType.InputRegister: break; case ModbusDataType.Coil: break; case ModbusDataType.Input: break; default: break; } } catch (Exception ex) { LogHelper.WriteLogError(string.Format(Lang.后台Modbustcp读取0, e.ModbusDataType.ToString()), ex); } } /// /// 当slave 收到 master 的命令 写入 DO 值或 AO 值到 DataStore 时触发事件。 /// /// /// private void DataStore_DataStoreWrittenTo(object sender, Modbus.Data.DataStoreEventArgs e) { switch (e.ModbusDataType) { case ModbusDataType.Coil: //code 5 //写入单个线圈 //ModbusDataCollection discretes = slave.DataStore.CoilDiscretes; //获取线圈离散 break; case ModbusDataType.HoldingRegister: //code 15 //ModbusDataCollection holdingRegisters = slave.DataStore.HoldingRegisters; //获取保存寄存器。 break; } } /// /// 将接收到的ushort[]转换为float类型 /// /// /// public float GetFloatFormUshortArray(ushort[] val) { if (val != null && val.Length == 2) { List result = new List(); result.AddRange(BitConverter.GetBytes(val[0])); result.AddRange(BitConverter.GetBytes(val[1])); return BitConverter.ToSingle(result.ToArray(), 0); } else { return 0.0f; } } /// /// 将float类型分解成两个ushort类型 /// /// /// public ushort[] GetUshortArrayFormFloat(float value) { ushort lowOrderValue = BitConverter.ToUInt16(BitConverter.GetBytes(value), 2); ushort highOrderValue = BitConverter.ToUInt16(BitConverter.GetBytes(value), 0); return new ushort[2] { lowOrderValue, highOrderValue }; } /// /// 获取输入位状态 /// /// /// public bool SW(int index) { try { return Slave.DataStore.CoilDiscretes[index]; } catch (Exception ex) { LogHelper.WriteLogError(Lang.获取输入位状态时出错, ex); return false; } } /// /// 获取输出位状态 /// /// /// public bool Oport(int index) { try { return Slave.DataStore.InputDiscretes[index]; } catch (Exception ex) { LogHelper.WriteLogError(Lang.获取输出位状态时出错, ex); return false; } } /// /// 输出位操作 /// /// 地址 /// 状态 /// 脉冲时间 /// 是否异步执行 public void BitOperate(int index, bool state) { try { Slave.DataStore.InputDiscretes[index] = state; } catch (Exception ex) { LogHelper.WriteLogError(Lang.输出位操作时出错, ex); } } /// /// 输出字操作 /// /// 字编号 /// 输出值 /// 脉冲时长 /// 是否异步 public void OutW(int index, ushort value) { try { Slave.DataStore.InputRegisters[index] = value; } catch (Exception ex) { LogHelper.WriteLogError(Lang.输出字操作时出错, ex); } } /// /// 获取输出字值 /// /// /// public ushort ReadOutW(int index) { try { return Slave.DataStore.InputRegisters[index]; } catch (Exception ex) { LogHelper.WriteLogError(Lang.获取输出字值时出错, ex); return 0; } } /// /// 获取输入字值 /// /// /// public ushort InW(int index) { try { return Slave.DataStore.HoldingRegisters[index]; } catch (Exception ex) { LogHelper.WriteLogError(Lang.获取输入字值时出错, ex); return 0; } } /// /// 输出浮点数 /// /// 字编号 /// 值 /// 脉冲时长 /// 是否异步 public void OutReal(int index, float value) { try { ushort[] data = GetUshortArrayFormFloat(value); Slave.DataStore.InputRegisters[index] = data[0]; Slave.DataStore.InputRegisters[index + 1] = data[1]; } catch (Exception ex) { LogHelper.WriteLogError(Lang.输出浮点数时出错, ex); } } /// /// 获取输出浮点数 /// /// /// public float ReadOutReal(int index) { try { return GetFloatFormUshortArray(new ushort[] { Slave.DataStore.InputRegisters[index], Slave.DataStore.InputRegisters[index + 1] }); } catch (Exception ex) { LogHelper.WriteLogError(Lang.获取输出浮点数时出错, ex); return 0.0f; } } /// /// 获取输入浮点数 /// /// /// public float InReal(int index) { try { return GetFloatFormUshortArray(new ushort[] { Slave.DataStore.HoldingRegisters[index + 1], Slave.DataStore.HoldingRegisters[index + 0] }); } catch (Exception ex) { LogHelper.WriteLogError(Lang.获取输入浮点数时出错, ex); return 0.0f; } } } }