Remove all unnesessary classes and interfaces and complete job implementation

This commit is contained in:
luosheng
2023-03-29 12:25:14 +08:00
parent d2a8f1e22f
commit 7ba7904282
35 changed files with 170 additions and 471 deletions

View File

@@ -1,4 +1,5 @@
using System; using System;
using ProtocolUnit = Modbus.Net.ProtocolUnit<byte[], byte[]>;
namespace Modbus.Net.Modbus.SelfDefinedSample namespace Modbus.Net.Modbus.SelfDefinedSample
{ {

View File

@@ -48,49 +48,5 @@ namespace Modbus.Net.Modbus
{ {
} }
} }
/// <summary>
/// Modbus设备
/// </summary>
public class ModbusMachine : BaseMachine
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="id">设备的ID号</param>
/// <param name="connectionType">连接类型</param>
/// <param name="connectionString">连接地址</param>
/// <param name="getAddresses">读写的地址</param>
/// <param name="keepConnect">是否保持连接</param>
/// <param name="slaveAddress">从站号</param>
/// <param name="masterAddress">主站号</param>
/// <param name="endian">端格式</param>
public ModbusMachine(string id, ModbusType connectionType, string connectionString,
IEnumerable<AddressUnit> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress,
Endian endian = Endian.BigEndianLsb)
: base(id, getAddresses, keepConnect, slaveAddress, masterAddress)
{
BaseUtility = new ModbusUtility(connectionType, connectionString, slaveAddress, masterAddress, endian);
AddressFormater = new AddressFormaterModbus();
AddressCombiner = new AddressCombinerContinus(AddressTranslator, 100);
AddressCombinerSet = new AddressCombinerContinus(AddressTranslator, 100);
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="id">设备的ID号</param>
/// <param name="connectionType">连接类型</param>
/// <param name="connectionString">连接地址</param>
/// <param name="getAddresses">读写的地址</param>
/// <param name="slaveAddress">从站号</param>
/// <param name="masterAddress">主站号</param>
/// <param name="endian">端格式</param>
public ModbusMachine(string id, ModbusType connectionType, string connectionString,
IEnumerable<AddressUnit> getAddresses, byte slaveAddress, byte masterAddress,
Endian endian = Endian.BigEndianLsb)
: this(id, connectionType, connectionString, getAddresses, true, slaveAddress, masterAddress, endian)
{
}
}
} }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using ProtocolUnit = Modbus.Net.ProtocolUnit<byte[], byte[]>;
namespace Modbus.Net.Modbus namespace Modbus.Net.Modbus
{ {

View File

@@ -48,7 +48,7 @@ namespace Modbus.Net.Modbus
/// <summary> /// <summary>
/// Tcp协议字节伸缩 /// Tcp协议字节伸缩
/// </summary> /// </summary>
public class ModbusTcpProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend public class ModbusTcpProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend<byte[], byte[]>
{ {
private static ushort _sendCount = 0; private static ushort _sendCount = 0;
private static readonly object _counterLock = new object(); private static readonly object _counterLock = new object();
@@ -93,7 +93,7 @@ namespace Modbus.Net.Modbus
/// <summary> /// <summary>
/// Rtu协议字节伸缩 /// Rtu协议字节伸缩
/// </summary> /// </summary>
public class ModbusRtuProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend public class ModbusRtuProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend<byte[], byte[]>
{ {
/// <summary> /// <summary>
/// 协议扩展,协议内容发送前调用 /// 协议扩展,协议内容发送前调用
@@ -128,7 +128,7 @@ namespace Modbus.Net.Modbus
/// <summary> /// <summary>
/// Ascii协议字节伸缩 /// Ascii协议字节伸缩
/// </summary> /// </summary>
public class ModbusAsciiProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend public class ModbusAsciiProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend<byte[], byte[]>
{ {
/// <summary> /// <summary>
/// 协议扩展,协议内容发送前调用 /// 协议扩展,协议内容发送前调用

View File

@@ -67,7 +67,7 @@ namespace Modbus.Net.Modbus
/// <summary> /// <summary>
/// Modbus基础Api入口 /// Modbus基础Api入口
/// </summary> /// </summary>
public class ModbusUtility : BaseUtility, IUtilityMethodWriteSingleCoil public class ModbusUtility : BaseUtility<byte[], byte[], ProtocolUnit<byte[], byte[]>, PipeUnit>, IUtilityMethodWriteSingleCoil
{ {
private static readonly ILogger<ModbusUtility> logger = LogProvider.CreateLogger<ModbusUtility>(); private static readonly ILogger<ModbusUtility> logger = LogProvider.CreateLogger<ModbusUtility>();

View File

@@ -26,7 +26,7 @@ namespace Modbus.Net.OPC
/// <summary> /// <summary>
/// Opc Da设备 /// Opc Da设备
/// </summary> /// </summary>
public abstract class OpcMachine : BaseMachine public abstract class OpcMachine : BaseMachine<string, string>
{ {
/// <summary> /// <summary>
/// 构造函数 /// 构造函数
@@ -37,8 +37,8 @@ namespace Modbus.Net.OPC
protected OpcMachine(string id, IEnumerable<AddressUnit> getAddresses, bool keepConnect) protected OpcMachine(string id, IEnumerable<AddressUnit> getAddresses, bool keepConnect)
: base(id, getAddresses, keepConnect) : base(id, getAddresses, keepConnect)
{ {
AddressCombiner = new AddressCombinerSingle(); AddressCombiner = new AddressCombinerSingle<string>();
AddressCombinerSet = new AddressCombinerSingle(); AddressCombinerSet = new AddressCombinerSingle<string>();
} }
} }
} }

View File

@@ -50,51 +50,4 @@ namespace Modbus.Net.Siemens
{ {
} }
} }
/// <summary>
/// 西门子设备
/// </summary>
public class SiemensMachine : BaseMachine
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="id">设备id号</param>
/// <param name="connectionType">连接类型</param>
/// <param name="connectionString">连接地址</param>
/// <param name="model">设备类型</param>
/// <param name="getAddresses">读写的地址</param>
/// <param name="keepConnect">是否保持连接</param>
/// <param name="slaveAddress">从站号</param>
/// <param name="masterAddress">主站号</param>
/// <param name="src">本机模块位0到7仅200使用其它型号不要填写</param>
/// <param name="dst">PLC模块位0到7仅200使用其它型号不要填写</param>
public SiemensMachine(string id, SiemensType connectionType, string connectionString, SiemensMachineModel model,
IEnumerable<AddressUnit> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress, byte src = 1, byte dst = 0)
: base(id, getAddresses, keepConnect, slaveAddress, masterAddress)
{
BaseUtility = new SiemensUtility(connectionType, connectionString, model, slaveAddress, masterAddress, src, dst);
AddressFormater = new AddressFormaterSiemens();
AddressCombiner = new AddressCombinerContinus(AddressTranslator, 100);
AddressCombinerSet = new AddressCombinerContinus(AddressTranslator, 100);
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="id">设备id号</param>
/// <param name="connectionType">连接类型</param>
/// <param name="connectionString">连接地址</param>
/// <param name="model">设备类型</param>
/// <param name="getAddresses">读写的地址</param>
/// <param name="slaveAddress">从站号</param>
/// <param name="masterAddress">主站号</param>
/// <param name="src">本机模块位0到7仅200使用其它型号不要填写</param>
/// <param name="dst">PLC模块位0到7仅200使用其它型号不要填写</param>
public SiemensMachine(string id, SiemensType connectionType, string connectionString, SiemensMachineModel model,
IEnumerable<AddressUnit> getAddresses, byte slaveAddress, byte masterAddress, byte src = 1, byte dst = 0)
: this(id, connectionType, connectionString, model, getAddresses, true, slaveAddress, masterAddress, src, dst)
{
}
}
} }

View File

@@ -62,7 +62,7 @@ namespace Modbus.Net.Siemens
/// <param name="unit">协议核心</param> /// <param name="unit">协议核心</param>
/// <param name="content">协议的参数</param> /// <param name="content">协议的参数</param>
/// <returns>设备返回的信息</returns> /// <returns>设备返回的信息</returns>
private async Task<PipeUnit> ForceSendReceiveAsync(ProtocolUnit unit, IInputStruct content) private async Task<PipeUnit> ForceSendReceiveAsync(ProtocolUnit<byte[], byte[]> unit, IInputStruct content)
{ {
return await base.SendReceiveAsync(unit, content); return await base.SendReceiveAsync(unit, content);
} }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ProtocolUnit = Modbus.Net.ProtocolUnit<byte[], byte[]>;
namespace Modbus.Net.Siemens namespace Modbus.Net.Siemens
{ {

View File

@@ -5,7 +5,7 @@ namespace Modbus.Net.Siemens
/// <summary> /// <summary>
/// 西门子Tcp协议扩展 /// 西门子Tcp协议扩展
/// </summary> /// </summary>
public class SiemensTcpProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend public class SiemensTcpProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend<byte[], byte[]>
{ {
/// <summary> /// <summary>
/// 协议扩展,协议内容发送前调用 /// 协议扩展,协议内容发送前调用
@@ -35,7 +35,7 @@ namespace Modbus.Net.Siemens
/// <summary> /// <summary>
/// 西门子Ppi协议扩展 /// 西门子Ppi协议扩展
/// </summary> /// </summary>
public class SiemensPpiProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend public class SiemensPpiProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend<byte[], byte[]>
{ {
/// <summary> /// <summary>
/// 协议扩展,协议内容发送前调用 /// 协议扩展,协议内容发送前调用

View File

@@ -106,7 +106,7 @@ namespace Modbus.Net.Siemens
/// <param name="unit">协议的核心</param> /// <param name="unit">协议的核心</param>
/// <param name="content">协议的参数</param> /// <param name="content">协议的参数</param>
/// <returns>返回的数据</returns> /// <returns>返回的数据</returns>
public override PipeUnit SendReceive(ProtocolUnit unit, IInputStruct content) public override PipeUnit SendReceive(ProtocolUnit<byte[], byte[]> unit, IInputStruct content)
{ {
return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content)); return AsyncHelper.RunSync(() => SendReceiveAsync(unit, content));
} }
@@ -117,7 +117,7 @@ namespace Modbus.Net.Siemens
/// <param name="unit">发送的数据</param> /// <param name="unit">发送的数据</param>
/// <param name="content">协议的参数</param> /// <param name="content">协议的参数</param>
/// <returns>返回的数据</returns> /// <returns>返回的数据</returns>
public override async Task<PipeUnit> SendReceiveAsync(ProtocolUnit unit, IInputStruct content) public override async Task<PipeUnit> SendReceiveAsync(ProtocolUnit<byte[], byte[]> unit, IInputStruct content)
{ {
if (ProtocolLinker != null && ProtocolLinker.IsConnected) return await base.SendReceiveAsync(unit, content); if (ProtocolLinker != null && ProtocolLinker.IsConnected) return await base.SendReceiveAsync(unit, content);
if (_connectTryCount > 10) return null; if (_connectTryCount > 10) return null;
@@ -133,7 +133,7 @@ namespace Modbus.Net.Siemens
/// <param name="unit">发送的数据</param> /// <param name="unit">发送的数据</param>
/// <param name="content">协议的参数</param> /// <param name="content">协议的参数</param>
/// <returns>返回的数据</returns> /// <returns>返回的数据</returns>
private async Task<PipeUnit> ForceSendReceiveAsync(ProtocolUnit unit, IInputStruct content) private async Task<PipeUnit> ForceSendReceiveAsync(ProtocolUnit<byte[], byte[]> unit, IInputStruct content)
{ {
return await base.SendReceiveAsync(unit, content); return await base.SendReceiveAsync(unit, content);
} }

View File

@@ -59,7 +59,7 @@ namespace Modbus.Net.Siemens
/// <summary> /// <summary>
/// 西门子通讯Api入口 /// 西门子通讯Api入口
/// </summary> /// </summary>
public class SiemensUtility : BaseUtility public class SiemensUtility : BaseUtility<byte[], byte[], ProtocolUnit<byte[], byte[]>, PipeUnit>
{ {
private static readonly ILogger<SiemensUtility> logger = LogProvider.CreateLogger<SiemensUtility>(); private static readonly ILogger<SiemensUtility> logger = LogProvider.CreateLogger<SiemensUtility>();

View File

@@ -6,7 +6,7 @@ namespace Modbus.Net
/// 设备的抽象 /// 设备的抽象
/// </summary> /// </summary>
/// <typeparam name="TKey"></typeparam> /// <typeparam name="TKey"></typeparam>
public interface IMachine<TKey> : IMachineProperty<TKey>, IMachineMethodData, IMachineReflectionCall where TKey : IEquatable<TKey> public interface IMachine<TKey> : IMachineProperty<TKey>, IMachineMethodDatas, IMachineReflectionCall where TKey : IEquatable<TKey>
{ {
} }
} }

View File

@@ -13,19 +13,19 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// Machine的数据读写接口 /// Machine的数据读写接口
/// </summary> /// </summary>
public interface IMachineMethodData : IMachineMethod public interface IMachineMethodDatas : IMachineMethod
{ {
/// <summary> /// <summary>
/// 读取数据 /// 读取数据
/// </summary> /// </summary>
/// <returns>从设备读取的数据</returns> /// <returns>从设备读取的数据</returns>
ReturnStruct<Dictionary<string, ReturnUnit>> GetDatas(MachineDataType getDataType); ReturnStruct<Dictionary<string, ReturnUnit<double>>> GetDatas(MachineDataType getDataType);
/// <summary> /// <summary>
/// 读取数据 /// 读取数据
/// </summary> /// </summary>
/// <returns>从设备读取的数据</returns> /// <returns>从设备读取的数据</returns>
Task<ReturnStruct<Dictionary<string, ReturnUnit>>> GetDatasAsync(MachineDataType getDataType); Task<ReturnStruct<Dictionary<string, ReturnUnit<double>>>> GetDatasAsync(MachineDataType getDataType);
/// <summary> /// <summary>
/// 写入数据 /// 写入数据

View File

@@ -56,12 +56,6 @@ namespace Modbus.Net
/// </summary> /// </summary>
/// <returns>是否断开成功</returns> /// <returns>是否断开成功</returns>
bool Disconnect(); bool Disconnect();
/// <summary>
/// 获取设备的Id的字符串
/// </summary>
/// <returns></returns>
string GetMachineIdString();
} }
/// <summary> /// <summary>

View File

@@ -1,12 +1,5 @@
namespace Modbus.Net namespace Modbus.Net
{ {
/// <summary>
/// 协议字节伸缩
/// </summary>
public interface IProtocolLinkerBytesExtend : IProtocolLinkerBytesExtend<byte[], byte[]>
{
}
/// <summary> /// <summary>
/// 协议字节伸缩 /// 协议字节伸缩
/// </summary> /// </summary>

View File

@@ -3,6 +3,7 @@ using Quartz.Impl;
using Quartz.Impl.Matchers; using Quartz.Impl.Matchers;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Modbus.Net namespace Modbus.Net
@@ -10,14 +11,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 返回结果的定义类 /// 返回结果的定义类
/// </summary> /// </summary>
public class DataReturnDef : DataReturnDef<string> public class DataReturnDef<TMachineKey, TReturnUnit> where TMachineKey : IEquatable<TMachineKey> where TReturnUnit : struct
{
}
/// <summary>
/// 返回结果的定义类
/// </summary>
public class DataReturnDef<TMachineKey> where TMachineKey : IEquatable<TMachineKey>
{ {
/// <summary> /// <summary>
/// 设备的Id /// 设备的Id
@@ -27,13 +21,13 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 返回的数据值 /// 返回的数据值
/// </summary> /// </summary>
public ReturnStruct<Dictionary<string, ReturnUnit>> ReturnValues { get; set; } public ReturnStruct<Dictionary<string, ReturnUnit<TReturnUnit>>> ReturnValues { get; set; }
} }
/// <summary> /// <summary>
/// 设备调度器创建类 /// 设备调度器创建类
/// </summary> /// </summary>
public sealed class MachineJobSchedulerCreator public sealed class MachineJobSchedulerCreator<TMachineMethod, TMachineKey, TReturnUnit> where TMachineKey : IEquatable<TMachineKey> where TReturnUnit : struct where TMachineMethod : IMachineMethod
{ {
/// <summary> /// <summary>
/// 创建设备调度器 /// 创建设备调度器
@@ -42,7 +36,7 @@ namespace Modbus.Net
/// <param name="count">重复次数负数为无限循环0为执行一次</param> /// <param name="count">重复次数负数为无限循环0为执行一次</param>
/// <param name="intervalSecond">间隔秒数</param> /// <param name="intervalSecond">间隔秒数</param>
/// <returns></returns> /// <returns></returns>
public static async Task<MachineGetJobScheduler> CreateScheduler(string triggerKey, int count = 0, int intervalSecond = 1) public static async Task<MachineGetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> CreateScheduler(string triggerKey, int count = 0, int intervalSecond = 1)
{ {
return await CreateScheduler(triggerKey, count, (double)intervalSecond); return await CreateScheduler(triggerKey, count, (double)intervalSecond);
} }
@@ -54,12 +48,12 @@ namespace Modbus.Net
/// <param name="count">重复次数负数为无限循环0为执行一次</param> /// <param name="count">重复次数负数为无限循环0为执行一次</param>
/// <param name="intervalMilliSecond">间隔毫秒数</param> /// <param name="intervalMilliSecond">间隔毫秒数</param>
/// <returns></returns> /// <returns></returns>
public static async Task<MachineGetJobScheduler> CreateSchedulerMillisecond(string triggerKey, int count = 0, int intervalMilliSecond = 1000) public static async Task<MachineGetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> CreateSchedulerMillisecond(string triggerKey, int count = 0, int intervalMilliSecond = 1000)
{ {
return await CreateScheduler(triggerKey, count, (double)intervalMilliSecond / 1000.0); return await CreateScheduler(triggerKey, count, intervalMilliSecond / 1000.0);
} }
private static async Task<MachineGetJobScheduler> CreateScheduler(string triggerKey, int count = 0, double interval = 1) private static async Task<MachineGetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> CreateScheduler(string triggerKey, int count = 0, double interval = 1)
{ {
IScheduler scheduler = await StdSchedulerFactory.GetDefaultScheduler(); IScheduler scheduler = await StdSchedulerFactory.GetDefaultScheduler();
@@ -87,7 +81,7 @@ namespace Modbus.Net
var jobKeys = await scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals("Modbus.Net.DataQuery.Group." + triggerKey)); var jobKeys = await scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals("Modbus.Net.DataQuery.Group." + triggerKey));
await scheduler.DeleteJobs(jobKeys); await scheduler.DeleteJobs(jobKeys);
return new MachineGetJobScheduler(scheduler, trigger); return new MachineGetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>(scheduler, trigger);
} }
/// <summary> /// <summary>
@@ -107,7 +101,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 获取数据任务 /// 获取数据任务
/// </summary> /// </summary>
public sealed class MachineGetJobScheduler public sealed class MachineGetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit> where TMachineKey: IEquatable<TMachineKey> where TReturnUnit : struct where TMachineMethod : IMachineMethod
{ {
private IScheduler _scheduler; private IScheduler _scheduler;
@@ -147,18 +141,23 @@ namespace Modbus.Net
/// <param name="machineDataType">获取数据的方式</param> /// <param name="machineDataType">获取数据的方式</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="NullReferenceException"></exception> /// <exception cref="NullReferenceException"></exception>
public async Task<MachineQueryJobScheduler> From(string queryId, IMachineReflectionCall machine, MachineDataType machineDataType) public async Task<MachineQueryJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> From(string queryId, IMachineReflectionCall machine, MachineDataType machineDataType)
{ {
JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name); JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name);
IJobDetail job = JobBuilder.Create<MachineGetDataJob>() IJobDetail job = JobBuilder.Create<MachineGetDataJob<TReturnUnit>>()
.WithIdentity(jobKey) .WithIdentity(jobKey)
.StoreDurably(true) .StoreDurably(true)
.Build(); .Build();
string methodName = typeof(TMachineMethod).Name;
if (methodName.Substring(0,14) != "IMachineMethod")
{
throw new FormatException("IMachineMethod Name not match format exception");
}
job.JobDataMap.Put("DataType", machineDataType); job.JobDataMap.Put("DataType", machineDataType);
job.JobDataMap.Put("Machine", machine); job.JobDataMap.Put("Machine", machine);
job.JobDataMap.Put("Function", "Datas"); job.JobDataMap.Put("Function", methodName.Remove(0,14));
if (_parentJobKey != null) if (_parentJobKey != null)
{ {
@@ -173,7 +172,7 @@ namespace Modbus.Net
await _scheduler.ScheduleJob(job, _trigger); await _scheduler.ScheduleJob(job, _trigger);
} }
return new MachineQueryJobScheduler(_scheduler, _trigger, jobKey); return new MachineQueryJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>(_scheduler, _trigger, jobKey);
} }
/// <summary> /// <summary>
@@ -183,25 +182,12 @@ namespace Modbus.Net
/// <param name="values">要写入的数据模板</param> /// <param name="values">要写入的数据模板</param>
/// <param name="machineDataType">获取数据的方式</param> /// <param name="machineDataType">获取数据的方式</param>
/// <returns></returns> /// <returns></returns>
public Task<MachineQueryJobScheduler> Apply(string queryId, Dictionary<string, double> values, MachineDataType machineDataType)
{
return Apply<string>(queryId, values, machineDataType);
}
/// <summary>
/// 直接向任务队列中写一个数据模板
/// </summary>
/// <typeparam name="TMachineKey">设备的ID类型</typeparam>
/// <param name="queryId">任务ID每个触发器唯一</param>
/// <param name="values">要写入的数据模板</param>
/// <param name="machineDataType">获取数据的方式</param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception> /// <exception cref="NullReferenceException"></exception>
public async Task<MachineQueryJobScheduler> Apply<TMachineKey>(string queryId, Dictionary<string, double> values, MachineDataType machineDataType) where TMachineKey : IEquatable<TMachineKey> public async Task<MachineQueryJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> Apply(string queryId, Dictionary<string, double> values, MachineDataType machineDataType)
{ {
JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name); JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name);
IJobDetail job = JobBuilder.Create<MachineQueryDataJob<TMachineKey>>() IJobDetail job = JobBuilder.Create<MachineQueryDataJob<TMachineKey, TReturnUnit>>()
.WithIdentity(jobKey) .WithIdentity(jobKey)
.StoreDurably(true) .StoreDurably(true)
.Build(); .Build();
@@ -223,7 +209,7 @@ namespace Modbus.Net
await _scheduler.ScheduleJob(job, _trigger); await _scheduler.ScheduleJob(job, _trigger);
} }
return new MachineQueryJobScheduler(_scheduler, _trigger, jobKey); return new MachineQueryJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>(_scheduler, _trigger, jobKey);
} }
/// <summary> /// <summary>
@@ -233,23 +219,10 @@ namespace Modbus.Net
/// <param name="values">要写入的数据模板</param> /// <param name="values">要写入的数据模板</param>
/// <param name="machineDataType">获取数据的方式</param> /// <param name="machineDataType">获取数据的方式</param>
/// <returns></returns> /// <returns></returns>
public Task<MachineSetJobScheduler> ApplyTo(string queryId, Dictionary<string, double> values, MachineDataType machineDataType)
{
return ApplyTo<string>(queryId, values, machineDataType);
}
/// <summary>
/// 直接向任务队列中写一个数据模板,并跳过处理数据流程
/// </summary>
/// <typeparam name="TMachineKey">设备的ID类型</typeparam>
/// <param name="queryId">任务ID每个触发器唯一</param>
/// <param name="values">要写入的数据模板</param>
/// <param name="machineDataType">获取数据的方式</param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception> /// <exception cref="NullReferenceException"></exception>
public async Task<MachineSetJobScheduler> ApplyTo<TMachineKey>(string queryId, Dictionary<string, double> values, MachineDataType machineDataType) where TMachineKey : IEquatable<TMachineKey> public async Task<MachineSetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> ApplyTo(string queryId, Dictionary<string, double> values, MachineDataType machineDataType)
{ {
var applyJobScheduler = await Apply<TMachineKey>(queryId, values, machineDataType); var applyJobScheduler = await Apply(queryId, values, machineDataType);
return await applyJobScheduler.Query(); return await applyJobScheduler.Query();
} }
} }
@@ -257,7 +230,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 处理数据任务 /// 处理数据任务
/// </summary> /// </summary>
public sealed class MachineQueryJobScheduler public sealed class MachineQueryJobScheduler<TMachineMethod, TMachineKey, TReturnUnit> where TMachineKey: IEquatable<TMachineKey> where TReturnUnit : struct where TMachineMethod : IMachineMethod
{ {
private IScheduler _scheduler; private IScheduler _scheduler;
@@ -284,26 +257,14 @@ namespace Modbus.Net
/// <param name="queryId">任务ID每个触发器唯一</param> /// <param name="queryId">任务ID每个触发器唯一</param>
/// <param name="QueryDataFunc">处理数据的函数,输入返回读数据的定义和值,输出写数据字典</param> /// <param name="QueryDataFunc">处理数据的函数,输入返回读数据的定义和值,输出写数据字典</param>
/// <returns></returns> /// <returns></returns>
public Task<MachineSetJobScheduler> Query(string queryId = null, Func<DataReturnDef, Dictionary<string, double>> QueryDataFunc = null)
{
return Query<string>(queryId, QueryDataFunc);
}
/// <summary>
/// 处理数据
/// </summary>
/// <typeparam name="TMachineKey">设备的ID类型</typeparam>
/// <param name="queryId">任务ID每个触发器唯一</param>
/// <param name="QueryDataFunc">处理数据的函数,输入返回读数据的定义和值,输出写数据字典</param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception> /// <exception cref="NullReferenceException"></exception>
public async Task<MachineSetJobScheduler> Query<TMachineKey>(string queryId = null, Func<DataReturnDef, Dictionary<string, double>> QueryDataFunc = null) where TMachineKey : IEquatable<TMachineKey> public async Task<MachineSetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> Query(string queryId = null, Func<DataReturnDef<TMachineKey, TReturnUnit>, Dictionary<string, TReturnUnit>> QueryDataFunc = null)
{ {
if (queryId == null) return new MachineSetJobScheduler(_scheduler, _trigger, _parentJobKey); if (queryId == null) return new MachineSetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>(_scheduler, _trigger, _parentJobKey);
JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name); JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name);
IJobDetail job = JobBuilder.Create<MachineQueryDataJob<TMachineKey>>() IJobDetail job = JobBuilder.Create<MachineQueryDataJob<TMachineKey, TReturnUnit>>()
.WithIdentity(jobKey) .WithIdentity(jobKey)
.StoreDurably(true) .StoreDurably(true)
.Build(); .Build();
@@ -317,14 +278,14 @@ namespace Modbus.Net
await _scheduler.AddJob(job, true); await _scheduler.AddJob(job, true);
return new MachineSetJobScheduler(_scheduler, _trigger, jobKey); return new MachineSetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>(_scheduler, _trigger, jobKey);
} }
} }
/// <summary> /// <summary>
/// 写入数据任务 /// 写入数据任务
/// </summary> /// </summary>
public sealed class MachineSetJobScheduler public sealed class MachineSetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit> where TMachineKey: IEquatable<TMachineKey> where TReturnUnit : struct where TMachineMethod : IMachineMethod
{ {
private IScheduler _scheduler; private IScheduler _scheduler;
@@ -354,17 +315,22 @@ namespace Modbus.Net
/// <param name="machine">写入数据的设备实例</param> /// <param name="machine">写入数据的设备实例</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="NullReferenceException"></exception> /// <exception cref="NullReferenceException"></exception>
public async Task<MachineDealJobScheduler> To(string queryId, IMachineReflectionCall machine) public async Task<MachineDealJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> To(string queryId, IMachineReflectionCall machine)
{ {
JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name); JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name);
IJobDetail job = JobBuilder.Create<MachineSetDataJob>() IJobDetail job = JobBuilder.Create<MachineSetDataJob<TReturnUnit>>()
.WithIdentity(jobKey) .WithIdentity(jobKey)
.StoreDurably(true) .StoreDurably(true)
.Build(); .Build();
string methodName = typeof(TMachineMethod).Name;
if (methodName.Substring(0, 14) != "IMachineMethod")
{
throw new FormatException("IMachineMethod Name not match format exception");
}
job.JobDataMap.Put("Machine", machine); job.JobDataMap.Put("Machine", machine);
job.JobDataMap.Put("Function", "Datas"); job.JobDataMap.Put("Function", methodName.Remove(0,14));
var listener = _scheduler.ListenerManager.GetJobListener("Modbus.Net.DataQuery.Chain." + _trigger.Key.Name) as JobChainingJobListenerWithDataMap; var listener = _scheduler.ListenerManager.GetJobListener("Modbus.Net.DataQuery.Chain." + _trigger.Key.Name) as JobChainingJobListenerWithDataMap;
if (listener == null) throw new NullReferenceException("Listener " + "Modbus.Net.DataQuery.Chain." + _trigger.Key.Name + " is null"); if (listener == null) throw new NullReferenceException("Listener " + "Modbus.Net.DataQuery.Chain." + _trigger.Key.Name + " is null");
@@ -372,7 +338,7 @@ namespace Modbus.Net
await _scheduler.AddJob(job, true); await _scheduler.AddJob(job, true);
return new MachineDealJobScheduler(_scheduler, _trigger, jobKey); return new MachineDealJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>(_scheduler, _trigger, jobKey);
} }
/// <summary> /// <summary>
@@ -382,9 +348,9 @@ namespace Modbus.Net
/// <param name="machine">要获取数据的设备实例</param> /// <param name="machine">要获取数据的设备实例</param>
/// <param name="machineDataType">获取数据的方式</param> /// <param name="machineDataType">获取数据的方式</param>
/// <returns></returns> /// <returns></returns>
public async Task<MachineQueryJobScheduler> From(string queryId, IMachineReflectionCall machine, MachineDataType machineDataType) public async Task<MachineQueryJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> From(string queryId, IMachineReflectionCall machine, MachineDataType machineDataType)
{ {
return await new MachineGetJobScheduler(_scheduler, _trigger, _parentJobKey).From(queryId, machine, machineDataType); return await new MachineGetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>(_scheduler, _trigger, _parentJobKey).From(queryId, machine, machineDataType);
} }
/// <summary> /// <summary>
@@ -400,7 +366,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 处理写返回任务 /// 处理写返回任务
/// </summary> /// </summary>
public sealed class MachineDealJobScheduler public sealed class MachineDealJobScheduler<TMachineMethod, TMachineKey, TReturnUnit> where TMachineKey : IEquatable<TMachineKey> where TReturnUnit : struct where TMachineMethod : IMachineMethod
{ {
private IScheduler _scheduler; private IScheduler _scheduler;
@@ -423,7 +389,6 @@ namespace Modbus.Net
_parentJobKey = parentJobKey; _parentJobKey = parentJobKey;
} }
/// <summary> /// <summary>
/// 处理写返回 /// 处理写返回
/// </summary> /// </summary>
@@ -432,22 +397,9 @@ namespace Modbus.Net
/// <param name="onFailure">失败回调方法参数为设备ID</param> /// <param name="onFailure">失败回调方法参数为设备ID</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="NullReferenceException"></exception> /// <exception cref="NullReferenceException"></exception>
public async Task<MachineSetJobScheduler> Deal(string queryId = null, Func<string, Task> onSuccess = null, Func<string, int, string, Task> onFailure = null) public async Task<MachineSetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> Deal(string queryId = null, Func<string, Task> onSuccess = null, Func<string, int, string, Task> onFailure = null)
{ {
return await Deal<string>(queryId, onSuccess, onFailure); if (queryId == null) return new MachineSetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>(_scheduler, _trigger, _parentJobKey);
}
/// <summary>
/// 处理写返回
/// </summary>
/// <param name="queryId">任务ID每个触发器唯一</param>
/// <param name="onSuccess">成功回调方法参数为设备ID</param>
/// <param name="onFailure">失败回调方法参数为设备ID</param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception>
public async Task<MachineSetJobScheduler> Deal<TMachineKey>(string queryId = null, Func<string, Task> onSuccess = null, Func<string, int, string, Task> onFailure = null) where TMachineKey : IEquatable<TMachineKey>
{
if (queryId == null) return new MachineSetJobScheduler(_scheduler, _trigger, _parentJobKey);
JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name); JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name);
IJobDetail job = JobBuilder.Create<MachineDealDataJob<TMachineKey>>() IJobDetail job = JobBuilder.Create<MachineDealDataJob<TMachineKey>>()
@@ -464,14 +416,14 @@ namespace Modbus.Net
await _scheduler.AddJob(job, true); await _scheduler.AddJob(job, true);
return new MachineSetJobScheduler(_scheduler, _trigger, jobKey); return new MachineSetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>(_scheduler, _trigger, jobKey);
} }
} }
/// <summary> /// <summary>
/// 获取数据任务 /// 获取数据任务
/// </summary> /// </summary>
public class MachineGetDataJob : IJob public class MachineGetDataJob<TReturnUnit> : IJob where TReturnUnit : struct
{ {
/// <inheritdoc /> /// <inheritdoc />
public async Task Execute(IJobExecutionContext context) public async Task Execute(IJobExecutionContext context)
@@ -482,7 +434,7 @@ namespace Modbus.Net
context.JobDetail.JobDataMap.TryGetValue("Machine", out machine); context.JobDetail.JobDataMap.TryGetValue("Machine", out machine);
context.JobDetail.JobDataMap.TryGetValue("DataType", out machineDataType); context.JobDetail.JobDataMap.TryGetValue("DataType", out machineDataType);
context.JobDetail.JobDataMap.TryGetValue("Function", out callFunction); context.JobDetail.JobDataMap.TryGetValue("Function", out callFunction);
var values = await (machine as IMachineReflectionCall)!.InvokeGet<Dictionary<string, ReturnUnit>>((string)callFunction, new object[] { (MachineDataType)machineDataType }); var values = await (machine as IMachineReflectionCall)!.InvokeGet<Dictionary<string, ReturnUnit<TReturnUnit>>>((string)callFunction, new object[] { (MachineDataType)machineDataType });
context.JobDetail.JobDataMap.Put("Value", values); context.JobDetail.JobDataMap.Put("Value", values);
await context.Scheduler.AddJob(context.JobDetail, true, false); await context.Scheduler.AddJob(context.JobDetail, true, false);
@@ -492,8 +444,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 处理数据任务 /// 处理数据任务
/// </summary> /// </summary>
/// <typeparam name="TMachineKey"></typeparam> public class MachineQueryDataJob<TMachineKey, TReturnUnit> : IJob where TMachineKey : IEquatable<TMachineKey> where TReturnUnit : struct
public class MachineQueryDataJob<TMachineKey> : IJob where TMachineKey : IEquatable<TMachineKey>
{ {
/// <inheritdoc /> /// <inheritdoc />
public async Task Execute(IJobExecutionContext context) public async Task Execute(IJobExecutionContext context)
@@ -504,11 +455,11 @@ namespace Modbus.Net
context.JobDetail.JobDataMap.TryGetValue("Machine", out machine); context.JobDetail.JobDataMap.TryGetValue("Machine", out machine);
context.JobDetail.JobDataMap.TryGetValue("Value", out values); context.JobDetail.JobDataMap.TryGetValue("Value", out values);
context.JobDetail.JobDataMap.TryGetValue("QueryMethod", out QueryMethod); context.JobDetail.JobDataMap.TryGetValue("QueryMethod", out QueryMethod);
Func<DataReturnDef, Dictionary<string, double>> QueryMethodDispatch = (Func<DataReturnDef, Dictionary<string, double>>)QueryMethod; Func<DataReturnDef<TMachineKey, TReturnUnit>, Dictionary<string, TReturnUnit>> QueryMethodDispatch = (Func<DataReturnDef<TMachineKey, TReturnUnit>, Dictionary<string, TReturnUnit>>)QueryMethod;
if (QueryMethod != null && values != null) if (QueryMethod != null && values != null)
{ {
context.JobDetail.JobDataMap.Put("SetValue", QueryMethodDispatch(new DataReturnDef() { MachineId = machine == null ? null : ((IMachineProperty<TMachineKey>)machine).GetMachineIdString(), ReturnValues = (ReturnStruct<Dictionary<string, ReturnUnit>>)values })); context.JobDetail.JobDataMap.Put("SetValue", QueryMethodDispatch(new DataReturnDef<TMachineKey, TReturnUnit>() { MachineId = machine == null ? default : ((IMachineProperty<TMachineKey>)machine).Id, ReturnValues = (ReturnStruct<Dictionary<string, ReturnUnit<TReturnUnit>>>)values }));
await context.Scheduler.AddJob(context.JobDetail, true, false); await context.Scheduler.AddJob(context.JobDetail, true, false);
} }
} }
@@ -517,7 +468,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 写数据任务 /// 写数据任务
/// </summary> /// </summary>
public class MachineSetDataJob : IJob public class MachineSetDataJob<TReturnUnit> : IJob where TReturnUnit : struct
{ {
/// <inheritdoc /> /// <inheritdoc />
public async Task Execute(IJobExecutionContext context) public async Task Execute(IJobExecutionContext context)
@@ -533,7 +484,9 @@ namespace Modbus.Net
context.JobDetail.JobDataMap.TryGetValue("SetValue", out valuesSet); context.JobDetail.JobDataMap.TryGetValue("SetValue", out valuesSet);
context.JobDetail.JobDataMap.TryGetValue("Function", out callFunction); context.JobDetail.JobDataMap.TryGetValue("Function", out callFunction);
if (valuesSet == null && values != null) if (valuesSet == null && values != null)
valuesSet = ((ReturnStruct<Dictionary<string, ReturnUnit>>)values).Datas.MapGetValuesToSetValues(); {
valuesSet = ((ReturnStruct<Dictionary<string, ReturnUnit<TReturnUnit>>>)values).Datas.MapGetValuesToSetValues();
}
if (valuesSet == null) if (valuesSet == null)
{ {
@@ -565,11 +518,11 @@ namespace Modbus.Net
ReturnStruct<bool> successValue = (ReturnStruct<bool>)success; ReturnStruct<bool> successValue = (ReturnStruct<bool>)success;
if (successValue.IsSuccess == true && onSuccess != null) if (successValue.IsSuccess == true && onSuccess != null)
{ {
await ((Func<string, Task>)onSuccess)(((IMachineProperty<TMachineKey>)machine).GetMachineIdString()); await ((Func<TMachineKey, Task>)onSuccess)(((IMachineProperty<TMachineKey>)machine).Id);
} }
if (successValue.IsSuccess == false && onFailure != null) if (successValue.IsSuccess == false && onFailure != null)
{ {
await ((Func<string, int, string, Task>)onFailure)(((IMachineProperty<TMachineKey>)machine).GetMachineIdString(), successValue.ErrorCode, successValue.ErrorMsg); await ((Func<TMachineKey, int, string, Task>)onFailure)(((IMachineProperty<TMachineKey>)machine).Id, successValue.ErrorCode, successValue.ErrorMsg);
} }
context.JobDetail.JobDataMap.Remove("Success"); context.JobDetail.JobDataMap.Remove("Success");

View File

@@ -9,7 +9,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 多设备任务调度器 /// 多设备任务调度器
/// </summary> /// </summary>
public sealed class MultipleMachinesJobScheduler public sealed class MultipleMachinesJobScheduler<TMachineMethod, TMachineKey, TReturnUnit> where TMachineKey: IEquatable<TMachineKey> where TReturnUnit : struct where TMachineMethod : IMachineMethod
{ {
private static int _machineCount = 0; private static int _machineCount = 0;
@@ -21,7 +21,7 @@ namespace Modbus.Net
/// <param name="count">重复次数负数为无限循环0为执行一次</param> /// <param name="count">重复次数负数为无限循环0为执行一次</param>
/// <param name="intervalSecond">间隔秒数</param> /// <param name="intervalSecond">间隔秒数</param>
/// <returns></returns> /// <returns></returns>
public static ParallelLoopResult RunScheduler<TKey>(IEnumerable<IMachine<TKey>> machines, Func<IMachine<TKey>, MachineGetJobScheduler, Task> machineJobTemplate, int count = 0, int intervalSecond = 1) where TKey : IEquatable<TKey> public static ParallelLoopResult RunScheduler(IEnumerable<IMachine<TMachineKey>> machines, Func<IMachine<TMachineKey>, MachineGetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>, Task> machineJobTemplate, int count = 0, int intervalSecond = 1)
{ {
_machineCount = machines.Count(); _machineCount = machines.Count();
return Parallel.ForEach(machines, (machine, state, index) => return Parallel.ForEach(machines, (machine, state, index) =>
@@ -29,25 +29,12 @@ namespace Modbus.Net
Task.Factory.StartNew(async () => Task.Factory.StartNew(async () =>
{ {
Thread.Sleep((int)(intervalSecond * 1000.0 / _machineCount * index)); Thread.Sleep((int)(intervalSecond * 1000.0 / _machineCount * index));
var getJobScheduler = await MachineJobSchedulerCreator.CreateScheduler("Trigger" + index, count, intervalSecond); var getJobScheduler = await MachineJobSchedulerCreator<TMachineMethod, TMachineKey, TReturnUnit>.CreateScheduler("Trigger" + index, count, intervalSecond);
await machineJobTemplate(machine, getJobScheduler); await machineJobTemplate(machine, getJobScheduler);
}); });
}); });
} }
/// <summary>
/// 创建设备调度器
/// </summary>
/// <param name="machines">设备的集合</param>
/// <param name="machineJobTemplate">设备的运行模板</param>
/// <param name="count">重复次数负数为无限循环0为执行一次</param>
/// <param name="intervalSecond">间隔秒数</param>
/// <returns></returns>
public static ParallelLoopResult RunScheduler(IEnumerable<IMachine<string>> machines, Func<IMachine<string>, MachineGetJobScheduler, Task> machineJobTemplate, int count = 0, int intervalSecond = 1)
{
return RunScheduler<string>(machines, machineJobTemplate, count, intervalSecond);
}
/// <summary> /// <summary>
/// 取消任务 /// 取消任务
/// </summary> /// </summary>
@@ -56,7 +43,7 @@ namespace Modbus.Net
{ {
return Parallel.For(0, _machineCount, async index => return Parallel.For(0, _machineCount, async index =>
{ {
await MachineJobSchedulerCreator.CancelJob("Trigger" + index); await MachineJobSchedulerCreator<TMachineMethod, TMachineKey, TReturnUnit>.CancelJob("Trigger" + index);
}); });
} }
} }

View File

@@ -47,7 +47,7 @@ namespace Modbus.Net
var bytesExtend = var bytesExtend =
Activator.CreateInstance(GetType().GetTypeInfo().Assembly.GetType(GetType().FullName + "BytesExtend")) Activator.CreateInstance(GetType().GetTypeInfo().Assembly.GetType(GetType().FullName + "BytesExtend"))
as as
IProtocolLinkerBytesExtend; IProtocolLinkerBytesExtend<byte[], byte[]>;
return bytesExtend?.BytesExtend(content); return bytesExtend?.BytesExtend(content);
} }
@@ -62,7 +62,7 @@ namespace Modbus.Net
var bytesExtend = var bytesExtend =
Activator.CreateInstance(GetType().GetTypeInfo().Assembly.GetType(GetType().FullName + "BytesExtend")) Activator.CreateInstance(GetType().GetTypeInfo().Assembly.GetType(GetType().FullName + "BytesExtend"))
as as
IProtocolLinkerBytesExtend; IProtocolLinkerBytesExtend<byte[], byte[]>;
return bytesExtend?.BytesDecact(content); return bytesExtend?.BytesDecact(content);
} }

View File

@@ -4,13 +4,6 @@ using System.Linq;
namespace Modbus.Net namespace Modbus.Net
{ {
/// <summary>
/// 地址组合器,组合后的每一组地址将只需一次向设备进行通讯
/// </summary>
public abstract class AddressCombiner : AddressCombiner<string>
{
}
/// <summary> /// <summary>
/// 地址组合器,组合后的每一组地址将只需一次向设备进行通讯 /// 地址组合器,组合后的每一组地址将只需一次向设备进行通讯
/// </summary> /// </summary>
@@ -24,22 +17,6 @@ namespace Modbus.Net
public abstract IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses); public abstract IEnumerable<CommunicationUnit<TKey>> Combine(IEnumerable<AddressUnit<TKey>> addresses);
} }
/// <summary>
/// 连续的地址将组合成一组,向设备进行通讯
/// </summary>
public class AddressCombinerContinus : AddressCombinerContinus<string>
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="addressTranslator">地址转换器</param>
/// <param name="maxLength">单个发送协议允许的数据最长长度(字节)</param>
public AddressCombinerContinus(AddressTranslator addressTranslator, int maxLength)
: base(addressTranslator, maxLength)
{
}
}
/// <summary> /// <summary>
/// 连续的地址将组合成一组,向设备进行通讯 /// 连续的地址将组合成一组,向设备进行通讯
/// </summary> /// </summary>
@@ -226,13 +203,6 @@ namespace Modbus.Net
} }
} }
/// <summary>
/// 单个地址变为一组,每一个地址都进行一次查询
/// </summary>
public class AddressCombinerSingle : AddressCombinerSingle<string>
{
}
/// <summary> /// <summary>
/// 单个地址变为一组,每一个地址都进行一次查询 /// 单个地址变为一组,每一个地址都进行一次查询
/// </summary> /// </summary>
@@ -269,23 +239,6 @@ namespace Modbus.Net
public int GapNumber { get; set; } public int GapNumber { get; set; }
} }
/// <summary>
/// 可以调过多少数量的地址,把两个地址段变为一组通讯
/// </summary>
public class AddressCombinerNumericJump : AddressCombinerNumericJump<string>
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="jumpByteCount">需要跳过的字节个数</param>
/// <param name="maxLength">单个协议允许的数据最长长度(字节)</param>
/// <param name="addressTranslator">地址转换器</param>
public AddressCombinerNumericJump(int jumpByteCount, int maxLength, AddressTranslator addressTranslator)
: base(jumpByteCount, maxLength, addressTranslator)
{
}
}
/// <summary> /// <summary>
/// 可以调过多少数量的地址,把两个地址段变为一组通讯 /// 可以调过多少数量的地址,把两个地址段变为一组通讯
/// </summary> /// </summary>
@@ -382,23 +335,6 @@ namespace Modbus.Net
} }
} }
/// <summary>
/// 可以调过多少百分比的地址,把两个地址段变为一个
/// </summary>
public class AddressCombinerPercentageJump : AddressCombinerPercentageJump<string>
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="percentage">允许跳过的字节数除以待组合的地址的字节数的百分比</param>
/// <param name="maxLength">单个协议允许的数据最大长度</param>
/// <param name="addressTranslator">地址转换器</param>
public AddressCombinerPercentageJump(double percentage, int maxLength, AddressTranslator addressTranslator)
: base(percentage, maxLength, addressTranslator)
{
}
}
/// <summary> /// <summary>
/// 可以调过多少百分比的地址,把两个地址段变为一个 /// 可以调过多少百分比的地址,把两个地址段变为一个
/// </summary> /// </summary>

View File

@@ -32,45 +32,6 @@ namespace Modbus.Net
Id Id
} }
/// <summary>
/// 设备
/// </summary>
public abstract class BaseMachine : BaseMachine<string, string>
{
/// <summary>
/// 构造器
/// </summary>
/// <param name="id">设备的ID号</param>
/// <param name="getAddresses">需要与设备通讯的地址</param>
protected BaseMachine(string id, IEnumerable<AddressUnit> getAddresses) : base(id, getAddresses)
{
}
/// <summary>
/// 构造器
/// </summary>
/// <param name="id">设备的ID号</param>
/// <param name="getAddresses">需要与设备通讯的地址</param>
/// <param name="keepConnect">是否保持连接</param>
protected BaseMachine(string id, IEnumerable<AddressUnit> getAddresses, bool keepConnect)
: base(id, getAddresses, keepConnect)
{
}
/// <summary>
/// 构造器
/// </summary>
/// <param name="id">设备的ID号</param>
/// <param name="getAddresses">需要与设备通讯的地址</param>
/// <param name="keepConnect">是否保持连接</param>
/// <param name="slaveAddress">从站地址</param>
/// <param name="masterAddress">主站地址</param>
protected BaseMachine(string id, IEnumerable<AddressUnit> getAddresses, bool keepConnect, byte slaveAddress,
byte masterAddress) : base(id, getAddresses, keepConnect, slaveAddress, masterAddress)
{
}
}
/// <summary> /// <summary>
/// 设备 /// 设备
/// </summary> /// </summary>
@@ -193,7 +154,7 @@ namespace Modbus.Net
/// 读取数据 /// 读取数据
/// </summary> /// </summary>
/// <returns>从设备读取的数据</returns> /// <returns>从设备读取的数据</returns>
public ReturnStruct<Dictionary<string, ReturnUnit>> GetDatas(MachineDataType getDataType) public ReturnStruct<Dictionary<string, ReturnUnit<double>>> GetDatas(MachineDataType getDataType)
{ {
return AsyncHelper.RunSync(() => GetDatasAsync(getDataType)); return AsyncHelper.RunSync(() => GetDatasAsync(getDataType));
} }
@@ -203,17 +164,17 @@ namespace Modbus.Net
/// 读取数据 /// 读取数据
/// </summary> /// </summary>
/// <returns>从设备读取的数据</returns> /// <returns>从设备读取的数据</returns>
public async Task<ReturnStruct<Dictionary<string, ReturnUnit>>> GetDatasAsync(MachineDataType getDataType) public async Task<ReturnStruct<Dictionary<string, ReturnUnit<double>>>> GetDatasAsync(MachineDataType getDataType)
{ {
try try
{ {
var ans = new Dictionary<string, ReturnUnit>(); var ans = new Dictionary<string, ReturnUnit<double>>();
//检测并连接设备 //检测并连接设备
if (!BaseUtility.IsConnected) if (!BaseUtility.IsConnected)
await BaseUtility.ConnectAsync(); await BaseUtility.ConnectAsync();
//如果无法连接,终止 //如果无法连接,终止
if (!BaseUtility.IsConnected) return if (!BaseUtility.IsConnected) return
new ReturnStruct<Dictionary<string, ReturnUnit>>() new ReturnStruct<Dictionary<string, ReturnUnit<double>>>()
{ {
Datas = null, Datas = null,
IsSuccess = false, IsSuccess = false,
@@ -238,7 +199,7 @@ namespace Modbus.Net
//如果没有数据,终止 //如果没有数据,终止
if (datas.IsSuccess == false || datas.Datas == null) if (datas.IsSuccess == false || datas.Datas == null)
{ {
return new ReturnStruct<Dictionary<string, ReturnUnit>>() return new ReturnStruct<Dictionary<string, ReturnUnit<double>>>()
{ {
Datas = null, Datas = null,
IsSuccess = false, IsSuccess = false,
@@ -252,7 +213,7 @@ namespace Modbus.Net
BigEndianValueHelper.Instance.ByteLength[ BigEndianValueHelper.Instance.ByteLength[
communicateAddress.DataType.FullName])) communicateAddress.DataType.FullName]))
{ {
return new ReturnStruct<Dictionary<string, ReturnUnit>>() return new ReturnStruct<Dictionary<string, ReturnUnit<double>>>()
{ {
Datas = null, Datas = null,
IsSuccess = false, IsSuccess = false,
@@ -310,14 +271,14 @@ namespace Modbus.Net
{ {
//如果没有数据返回空 //如果没有数据返回空
if (datas.Datas.Length == 0) if (datas.Datas.Length == 0)
ans.Add(key, new ReturnUnit ans.Add(key, new ReturnUnit<double>
{ {
DeviceValue = null, DeviceValue = null,
AddressUnit = address.MapAddressUnitTUnitKeyToAddressUnit(), AddressUnit = address.MapAddressUnitTUnitKeyToAddressUnit(),
}); });
else else
ans.Add(key, ans.Add(key,
new ReturnUnit new ReturnUnit<double>
{ {
DeviceValue = DeviceValue =
Convert.ToDouble( Convert.ToDouble(
@@ -334,7 +295,7 @@ namespace Modbus.Net
if (ErrorCount >= _maxErrorCount) if (ErrorCount >= _maxErrorCount)
Disconnect(); Disconnect();
return new ReturnStruct<Dictionary<string, ReturnUnit>>() return new ReturnStruct<Dictionary<string, ReturnUnit<double>>>()
{ {
Datas = null, Datas = null,
IsSuccess = false, IsSuccess = false,
@@ -350,7 +311,7 @@ namespace Modbus.Net
//返回数据 //返回数据
if (ans.All(p => p.Value.DeviceValue == null)) ans = null; if (ans.All(p => p.Value.DeviceValue == null)) ans = null;
ErrorCount = 0; ErrorCount = 0;
return new ReturnStruct<Dictionary<string, ReturnUnit>> return new ReturnStruct<Dictionary<string, ReturnUnit<double>>>
{ {
Datas = ans, Datas = ans,
IsSuccess = true, IsSuccess = true,
@@ -365,7 +326,7 @@ namespace Modbus.Net
if (ErrorCount >= _maxErrorCount) if (ErrorCount >= _maxErrorCount)
Disconnect(); Disconnect();
return new ReturnStruct<Dictionary<string, ReturnUnit>>() return new ReturnStruct<Dictionary<string, ReturnUnit<double>>>()
{ {
Datas = null, Datas = null,
IsSuccess = false, IsSuccess = false,
@@ -676,17 +637,17 @@ namespace Modbus.Net
} }
/// <inheritdoc /> /// <inheritdoc />
public async Task<ReturnStruct<T>> InvokeGet<T>(string functionName, object[] parameters) public Task<ReturnStruct<T>> InvokeGet<T>(string functionName, object[] parameters)
{ {
var machineMethodType = GetType(); var machineMethodType = GetType();
var machineMethod = this as IMachineMethod; var machineMethod = this as IMachineMethod;
var machineSetMethod = machineMethodType.GetMethod("Get" + functionName + "Async"); var machineSetMethod = machineMethodType.GetMethod("Get" + functionName + "Async");
var ans = machineSetMethod.Invoke(machineMethod, parameters); var ans = machineSetMethod.Invoke(machineMethod, parameters);
return await (Task<ReturnStruct<T>>)ans; return (Task<ReturnStruct<T>>)ans;
} }
/// <inheritdoc /> /// <inheritdoc />
public async Task<ReturnStruct<bool>> InvokeSet<T>(string functionName, object[] parameters, T datas) public Task<ReturnStruct<bool>> InvokeSet<T>(string functionName, object[] parameters, T datas)
{ {
var machineMethodType = GetType(); var machineMethodType = GetType();
var machineMethod = this as IMachineMethod; var machineMethod = this as IMachineMethod;
@@ -695,7 +656,7 @@ namespace Modbus.Net
Array.Copy(parameters, allParams, parameters.Length); Array.Copy(parameters, allParams, parameters.Length);
allParams[parameters.Length] = datas; allParams[parameters.Length] = datas;
var ans = machineSetMethod.Invoke(machineMethod, allParams); var ans = machineSetMethod.Invoke(machineMethod, allParams);
return await (Task<ReturnStruct<bool>>)ans; return (Task<ReturnStruct<bool>>)ans;
} }
/// <summary> /// <summary>
@@ -716,15 +677,6 @@ namespace Modbus.Net
return BaseUtility.Disconnect(); return BaseUtility.Disconnect();
} }
/// <summary>
/// 获取设备的Id字符串格式
/// </summary>
/// <returns></returns>
public string GetMachineIdString()
{
return Id.ToString();
}
/// <summary> /// <summary>
/// 通过Id获取数据字段定义 /// 通过Id获取数据字段定义
/// </summary> /// </summary>
@@ -758,13 +710,6 @@ namespace Modbus.Net
} }
} }
/// <summary>
/// 通讯单元
/// </summary>
public class CommunicationUnit : CommunicationUnit<string>
{
}
/// <summary> /// <summary>
/// 通讯单元 /// 通讯单元
/// </summary> /// </summary>
@@ -811,12 +756,12 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 返回的数据单元 /// 返回的数据单元
/// </summary> /// </summary>
public class ReturnUnit public class ReturnUnit<TReturn> where TReturn : struct
{ {
/// <summary> /// <summary>
/// 返回的数据 /// 返回的数据
/// </summary> /// </summary>
public double? DeviceValue { get; set; } public TReturn? DeviceValue { get; set; }
/// <summary> /// <summary>
/// 数据定义 /// 数据定义
@@ -906,34 +851,4 @@ namespace Modbus.Net
return Area.ToUpper() == other.Area.ToUpper() && Address == other.Address || Id.Equals(other.Id); return Area.ToUpper() == other.Area.ToUpper() && Address == other.Address || Id.Equals(other.Id);
} }
} }
/// <summary>
/// AddressUnit扩展
/// </summary>
public static class AddressUnitExtend
{
/// <summary>
/// 映射泛型AddressUnit到字符串型AddressUnit
/// </summary>
/// <param name="addressUnit"></param>
/// <returns></returns>
public static AddressUnit MapAddressUnitTUnitKeyToAddressUnit<TUnitKey>(this AddressUnit<TUnitKey> addressUnit) where TUnitKey : IEquatable<TUnitKey>
{
return new AddressUnit()
{
Id = addressUnit.ToString(),
Area = addressUnit.Area,
Address = addressUnit.Address,
SubAddress = addressUnit.SubAddress,
DataType = addressUnit.DataType,
Zoom = addressUnit.Zoom,
DecimalPos = addressUnit.DecimalPos,
CommunicationTag = addressUnit.CommunicationTag,
Name = addressUnit.Name,
Unit = addressUnit.Unit,
CanWrite = addressUnit.CanWrite,
UnitExtend = addressUnit.UnitExtend
};
}
}
} }

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Modbus.Net namespace Modbus.Net
@@ -14,13 +15,43 @@ namespace Modbus.Net
/// </summary> /// </summary>
/// <param name="getValues">获取的数据</param> /// <param name="getValues">获取的数据</param>
/// <returns>应该写入的数据</returns> /// <returns>应该写入的数据</returns>
public static Dictionary<string, double> MapGetValuesToSetValues(this Dictionary<string, ReturnUnit> getValues) public static Dictionary<string, TSend> MapGetValuesToSetValues<TSend>(this Dictionary<string, ReturnUnit<TSend>> getValues) where TSend : struct
{ {
if (getValues == null) return null; if (getValues == null) return null;
return (from getValue in getValues return (from getValue in getValues
where getValue.Value.DeviceValue != null where getValue.Value.DeviceValue != null
select new KeyValuePair<string, double>(getValue.Key, getValue.Value.DeviceValue.Value)).ToDictionary( select new KeyValuePair<string, TSend>(getValue.Key, getValue.Value.DeviceValue.Value)).ToDictionary(
p => p.Key, p => p.Value); p => p.Key, p => p.Value);
} }
} }
/// <summary>
/// AddressUnit扩展
/// </summary>
public static class AddressUnitExtend
{
/// <summary>
/// 映射泛型AddressUnit到字符串型AddressUnit
/// </summary>
/// <param name="addressUnit"></param>
/// <returns></returns>
public static AddressUnit MapAddressUnitTUnitKeyToAddressUnit<TUnitKey>(this AddressUnit<TUnitKey> addressUnit) where TUnitKey : IEquatable<TUnitKey>
{
return new AddressUnit()
{
Id = addressUnit.ToString(),
Area = addressUnit.Area,
Address = addressUnit.Address,
SubAddress = addressUnit.SubAddress,
DataType = addressUnit.DataType,
Zoom = addressUnit.Zoom,
DecimalPos = addressUnit.DecimalPos,
CommunicationTag = addressUnit.CommunicationTag,
Name = addressUnit.Name,
Unit = addressUnit.Unit,
CanWrite = addressUnit.CanWrite,
UnitExtend = addressUnit.UnitExtend
};
}
}
} }

View File

@@ -8,7 +8,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 基本协议 /// 基本协议
/// </summary> /// </summary>
public abstract class BaseProtocol : BaseProtocol<byte[], byte[], ProtocolUnit, PipeUnit> public abstract class BaseProtocol : BaseProtocol<byte[], byte[], ProtocolUnit<byte[], byte[]>, PipeUnit>
{ {
/// <summary> /// <summary>
/// 构造器 /// 构造器
@@ -42,7 +42,7 @@ namespace Modbus.Net
/// <param name="content">输入信息的结构化描述</param> /// <param name="content">输入信息的结构化描述</param>
/// <returns>输出信息的结构化描述</returns> /// <returns>输出信息的结构化描述</returns>
public override async Task<PipeUnit> public override async Task<PipeUnit>
SendReceiveAsync(ProtocolUnit unit, IInputStruct content) SendReceiveAsync(ProtocolUnit<byte[], byte[]> unit, IInputStruct content)
{ {
if (content != null) if (content != null)
{ {

View File

@@ -8,7 +8,7 @@ namespace Modbus.Net
/// <summary> /// <summary>
/// 管道单元 /// 管道单元
/// </summary> /// </summary>
public class PipeUnit : PipeUnit<byte[], byte[], IProtocolLinker<byte[], byte[]>, ProtocolUnit> public class PipeUnit : PipeUnit<byte[], byte[], IProtocolLinker<byte[], byte[]>, ProtocolUnit<byte[], byte[]>>
{ {
/// <summary> /// <summary>
/// 构造函数 /// 构造函数
@@ -26,7 +26,7 @@ namespace Modbus.Net
/// <param name="protocolUnit">协议单元</param> /// <param name="protocolUnit">协议单元</param>
/// <param name="parameters">传递给输入结构的参数</param> /// <param name="parameters">传递给输入结构的参数</param>
/// <param name="success">上次的管道是否成功执行</param> /// <param name="success">上次的管道是否成功执行</param>
protected PipeUnit(IProtocolLinker<byte[], byte[]> protocolLinker, ProtocolUnit protocolUnit, byte[] parameters, protected PipeUnit(IProtocolLinker<byte[], byte[]> protocolLinker, ProtocolUnit<byte[], byte[]> protocolUnit, byte[] parameters,
bool success) : base(protocolLinker, protocolUnit, parameters, success) bool success) : base(protocolLinker, protocolUnit, parameters, success)
{ {
} }
@@ -44,7 +44,7 @@ namespace Modbus.Net
var content = inputStructCreator.Invoke(ReturnParams); var content = inputStructCreator.Invoke(ReturnParams);
if (ProtocolLinker != null) if (ProtocolLinker != null)
return new PipeUnit(ProtocolLinker, null, return new PipeUnit(ProtocolLinker, null,
await ProtocolLinker.SendReceiveAsync(ProtocolUnit.TranslateContent(endian, content)), await ProtocolLinker.SendReceiveAsync(ProtocolUnit<byte[], byte[]>.TranslateContent(endian, content)),
true); true);
} }
return new PipeUnit(ProtocolLinker, null, ReturnParams, false); return new PipeUnit(ProtocolLinker, null, ReturnParams, false);
@@ -57,7 +57,7 @@ namespace Modbus.Net
/// <param name="inputStructCreator">构造输入结构的函数</param> /// <param name="inputStructCreator">构造输入结构的函数</param>
/// <returns>发送完成之后新的管道实例</returns> /// <returns>发送完成之后新的管道实例</returns>
public new async Task<PipeUnit> SendReceiveAsync( public new async Task<PipeUnit> SendReceiveAsync(
ProtocolUnit unit, ProtocolUnit<byte[], byte[]> unit,
Func<byte[], IInputStruct> inputStructCreator) Func<byte[], IInputStruct> inputStructCreator)
{ {
var receiveContent = await SendReceiveAsyncParamOut(unit, inputStructCreator); var receiveContent = await SendReceiveAsyncParamOut(unit, inputStructCreator);

View File

@@ -2,13 +2,6 @@
namespace Modbus.Net namespace Modbus.Net
{ {
/// <summary>
/// 协议单元
/// </summary>
public abstract class ProtocolUnit : ProtocolUnit<byte[], byte[]>
{
}
/// <summary> /// <summary>
/// 协议单元 /// 协议单元
/// </summary> /// </summary>

View File

@@ -27,19 +27,6 @@ public enum Endian
namespace Modbus.Net namespace Modbus.Net
{ {
/// <summary>
/// 基础Api入口
/// </summary>
public abstract class BaseUtility : BaseUtility<byte[], byte[], ProtocolUnit, PipeUnit>
{
/// <summary>
/// 构造器
/// </summary>
protected BaseUtility(byte slaveAddress, byte masterAddress) : base(slaveAddress, masterAddress)
{
}
}
/// <summary> /// <summary>
/// 基础Api入口 /// 基础Api入口
/// </summary> /// </summary>

View File

@@ -11,8 +11,4 @@
<ProjectReference Include="..\..\Modbus.Net\Modbus.Net\Modbus.Net.csproj" /> <ProjectReference Include="..\..\Modbus.Net\Modbus.Net\Modbus.Net.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Scripts\" />
</ItemGroup>
</Project> </Project>

View File

@@ -3,6 +3,8 @@ using Microsoft.AspNetCore.Mvc;
using Modbus.Net; using Modbus.Net;
using Modbus.Net.Modbus; using Modbus.Net.Modbus;
using System.Diagnostics; using System.Diagnostics;
using MachineJobSchedulerCreator = Modbus.Net.MachineJobSchedulerCreator<Modbus.Net.IMachineMethodDatas, string, double>;
using ModbusMachine = Modbus.Net.Modbus.ModbusMachine<string, string>;
namespace AnyType.Controllers namespace AnyType.Controllers
{ {

View File

@@ -16,7 +16,7 @@ namespace CrossLamp.Controllers
_logger = logger; _logger = logger;
} }
private static BaseUtility? _utility = null; private static IUtility? _utility = null;
public ActionResult Index() public ActionResult Index()
{ {

View File

@@ -15,8 +15,8 @@ namespace TripleAdd.Controllers
_logger = logger; _logger = logger;
} }
private static BaseUtility? utility; private static IUtility? utility;
private static BaseMachine? machine; private static IMachine<string>? machine;
public ActionResult Index() public ActionResult Index()
{ {
@@ -54,15 +54,15 @@ namespace TripleAdd.Controllers
{ {
if (machine == null) if (machine == null)
{ {
machine = new ModbusMachine("1", ModbusType.Tcp, "192.168.0.161", new List<AddressUnit>() machine = new ModbusMachine<string, string>("1", ModbusType.Tcp, "192.168.0.161", new List<AddressUnit>()
{ {
new AddressUnit() {Id = "1", Area = "4X", Address = 1, CommunicationTag = "Add1", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0}, new AddressUnit() {Id = "1", Area = "4X", Address = 1, CommunicationTag = "Add1", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
new AddressUnit() {Id = "2", Area = "4X", Address = 2, CommunicationTag = "Add2", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0}, new AddressUnit() {Id = "2", Area = "4X", Address = 2, CommunicationTag = "Add2", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
new AddressUnit() {Id = "3", Area = "4X", Address = 3, CommunicationTag = "Add3", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0}, new AddressUnit() {Id = "3", Area = "4X", Address = 3, CommunicationTag = "Add3", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
new AddressUnit() {Id = "4", Area = "4X", Address = 4, CommunicationTag = "Ans", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0}, new AddressUnit() {Id = "4", Area = "4X", Address = 4, CommunicationTag = "Ans", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
}, 2, 0); }, 2, 0);
machine.AddressCombiner = new AddressCombinerContinus(machine.AddressTranslator, 100000); machine.AddressCombiner = new AddressCombinerContinus<string>(machine.AddressTranslator, 100000);
machine.AddressCombinerSet = new AddressCombinerContinus(machine.AddressTranslator, 100000); machine.AddressCombinerSet = new AddressCombinerContinus<string>(machine.AddressTranslator, 100000);
} }
var resultFormat = (await machine.GetDatasAsync(MachineDataType.CommunicationTag)).Datas.MapGetValuesToSetValues(); var resultFormat = (await machine.GetDatasAsync(MachineDataType.CommunicationTag)).Datas.MapGetValuesToSetValues();
return SetValue(new ushort[4] { (ushort)resultFormat["Add1"], (ushort)resultFormat["Add2"], (ushort)resultFormat["Add3"], (ushort)resultFormat["Ans"] }); return SetValue(new ushort[4] { (ushort)resultFormat["Add1"], (ushort)resultFormat["Add2"], (ushort)resultFormat["Add3"], (ushort)resultFormat["Ans"] });

View File

@@ -6,16 +6,16 @@ namespace Modbus.Net.Tests
[TestClass] [TestClass]
public class EndianTest public class EndianTest
{ {
private BaseMachine? _modbusTcpMachine; private BaseMachine<string, string>? _modbusTcpMachine;
private BaseMachine? _modbusTcpMachine2; private BaseMachine<string, string>? _modbusTcpMachine2;
[TestInitialize] [TestInitialize]
public void Init() public void Init()
{ {
_modbusTcpMachine = new ModbusMachine("1", ModbusType.Tcp, "127.0.0.1", null, true, 1, 0); _modbusTcpMachine = new ModbusMachine<string, string>("1", ModbusType.Tcp, "127.0.0.1", null, true, 1, 0);
_modbusTcpMachine2 = new ModbusMachine("2", ModbusType.Tcp, "127.0.0.1", null, true, 1, 0, Endian.LittleEndianLsb); _modbusTcpMachine2 = new ModbusMachine<string, string>("2", ModbusType.Tcp, "127.0.0.1", null, true, 1, 0, Endian.LittleEndianLsb);
} }
[TestMethod] [TestMethod]

View File

@@ -44,7 +44,7 @@ namespace Modbus.Net.Tests
DataType = typeof(bool) DataType = typeof(bool)
} }
}, true, 2, 0); }, true, 2, 0);
var success = await baseMachine.GetMachineMethods<IMachineMethodData>().SetDatasAsync( var success = await baseMachine.GetMachineMethods<IMachineMethodDatas>().SetDatasAsync(
MachineDataType.Address, MachineDataType.Address,
new Dictionary<string, double> new Dictionary<string, double>
{ {
@@ -53,9 +53,9 @@ namespace Modbus.Net.Tests
} }
}); });
Assert.AreEqual(success, true); Assert.AreEqual(success, true);
var datas = await baseMachine.GetMachineMethods<IMachineMethodData>().GetDatasAsync(MachineDataType.Address); var datas = await baseMachine.GetMachineMethods<IMachineMethodDatas>().GetDatasAsync(MachineDataType.Address);
Assert.AreEqual(datas.Datas["0X 1.0"].DeviceValue, 1); Assert.AreEqual(datas.Datas["0X 1.0"].DeviceValue, 1);
success = await baseMachine.GetMachineMethods<IMachineMethodData>().SetDatasAsync( success = await baseMachine.GetMachineMethods<IMachineMethodDatas>().SetDatasAsync(
MachineDataType.Address, MachineDataType.Address,
new Dictionary<string, double> new Dictionary<string, double>
{ {

View File

@@ -6,15 +6,15 @@ namespace Modbus.Net.Tests
[TestClass] [TestClass]
public class ModbusMultiStationTest public class ModbusMultiStationTest
{ {
private BaseMachine? _modbusRtuMachine1; private BaseMachine<string, string>? _modbusRtuMachine1;
private BaseMachine? _modbusRtuMachine2; private BaseMachine<string, string>? _modbusRtuMachine2;
[TestInitialize] [TestInitialize]
public void Init() public void Init()
{ {
_modbusRtuMachine1 = new ModbusMachine("1", ModbusType.Rtu, "COM1", null, true, 1, 0); _modbusRtuMachine1 = new ModbusMachine<string, string>("1", ModbusType.Rtu, "COM1", null, true, 1, 0);
_modbusRtuMachine2 = new ModbusMachine("2", ModbusType.Rtu, "COM1", null, true, 2, 0); _modbusRtuMachine2 = new ModbusMachine<string, string>("2", ModbusType.Rtu, "COM1", null, true, 2, 0);
} }
[TestMethod] [TestMethod]

View File

@@ -6,20 +6,20 @@ namespace Modbus.Net.Tests
[TestClass] [TestClass]
public class ModbusTest public class ModbusTest
{ {
private BaseMachine? _modbusTcpMachine; private BaseMachine<string, string>? _modbusTcpMachine;
private BaseMachine? _modbusRtuMachine; private BaseMachine<string, string>? _modbusRtuMachine;
private BaseMachine? _modbusAsciiMachine; private BaseMachine<string, string>? _modbusAsciiMachine;
[TestInitialize] [TestInitialize]
public void Init() public void Init()
{ {
_modbusTcpMachine = new ModbusMachine("1", ModbusType.Tcp, "192.168.3.10", null, true, 2, 0); _modbusTcpMachine = new ModbusMachine<string, string>("1", ModbusType.Tcp, "192.168.3.10", null, true, 2, 0);
_modbusRtuMachine = new ModbusMachine("2", ModbusType.Rtu, "COM5", null, true, 2, 0); _modbusRtuMachine = new ModbusMachine<string, string>("2", ModbusType.Rtu, "COM5", null, true, 2, 0);
_modbusAsciiMachine = new ModbusMachine("3", ModbusType.Ascii, "COM5", null, true, 2, 0); _modbusAsciiMachine = new ModbusMachine<string, string>("3", ModbusType.Ascii, "COM5", null, true, 2, 0);
} }
[TestMethod] [TestMethod]

View File

@@ -6,12 +6,12 @@ namespace Modbus.Net.Tests
[TestClass] [TestClass]
public class SiemensTest public class SiemensTest
{ {
private BaseMachine? _siemensTcpMachine; private BaseMachine<string, string>? _siemensTcpMachine;
[TestInitialize] [TestInitialize]
public void Init() public void Init()
{ {
_siemensTcpMachine = new SiemensMachine("1", SiemensType.Tcp, "192.168.3.10", SiemensMachineModel.S7_1200, null, true, 2, 0); _siemensTcpMachine = new SiemensMachine<string, string>("1", SiemensType.Tcp, "192.168.3.10", SiemensMachineModel.S7_1200, null, true, 2, 0);
} }
[TestMethod] [TestMethod]