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;
}
}
}
}