Add an reflection method in machine
This commit is contained in:
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.Modbus.SelfDefinedSample
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.Modbus.SelfDefinedSample
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Modbus.Net.Modbus
|
||||
/// 读输入寄存器
|
||||
/// </summary>
|
||||
ReadInputRegister = 4,
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 写单个线圈
|
||||
/// </summary>
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Modbus.Net
|
||||
/// 设备的抽象
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
public interface IMachine<TKey> : IMachineProperty<TKey>, IMachineMethodData where TKey : IEquatable<TKey>
|
||||
public interface IMachine<TKey> : IMachineProperty<TKey>, IMachineMethodData, IMachineReflectionCall where TKey : IEquatable<TKey>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
29
Modbus.Net/Modbus.Net/Interface/IMachineReflectionCall.cs
Normal file
29
Modbus.Net/Modbus.Net/Interface/IMachineReflectionCall.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备的反射调用接口
|
||||
/// </summary>
|
||||
public interface IMachineReflectionCall
|
||||
{
|
||||
/// <summary>
|
||||
/// 反射方式调用获取方法
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要返回的数据类型</typeparam>
|
||||
/// <param name="functionName">方法名</param>
|
||||
/// <param name="parameters">参数</param>
|
||||
/// <returns>返回的数据</returns>
|
||||
Task<ReturnStruct<T>> InvokeGet<T>(string functionName, object[] parameters);
|
||||
|
||||
/// <summary>
|
||||
/// 反射方式调用设置方法
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要设置的数据类型</typeparam>
|
||||
/// <param name="functionName">方法名</param>
|
||||
/// <param name="parameters">参数</param>
|
||||
/// <param name="datas">要设置的数据</param>
|
||||
/// <returns>设置是否成功</returns>
|
||||
Task<ReturnStruct<bool>> InvokeSet<T>(string functionName, object[] parameters, T datas);
|
||||
}
|
||||
}
|
||||
@@ -145,9 +145,10 @@ namespace Modbus.Net
|
||||
/// <param name="queryId">任务ID,每个触发器唯一</param>
|
||||
/// <param name="machine">要获取数据的设备实例</param>
|
||||
/// <param name="machineDataType">获取数据的方式</param>
|
||||
/// <param name="callFunction">调用函数的名称</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NullReferenceException"></exception>
|
||||
public async Task<MachineQueryJobScheduler> From(string queryId, IMachineMethodData machine, MachineDataType machineDataType)
|
||||
public async Task<MachineQueryJobScheduler> From(string queryId, IMachineReflectionCall machine, MachineDataType machineDataType, string callFunction = "Datas")
|
||||
{
|
||||
JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name);
|
||||
|
||||
@@ -158,6 +159,7 @@ namespace Modbus.Net
|
||||
|
||||
job.JobDataMap.Put("DataType", machineDataType);
|
||||
job.JobDataMap.Put("Machine", machine);
|
||||
job.JobDataMap.Put("Function", callFunction);
|
||||
|
||||
if (_parentJobKey != null)
|
||||
{
|
||||
@@ -351,9 +353,10 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <param name="queryId">任务ID,每个触发器唯一</param>
|
||||
/// <param name="machine">写入数据的设备实例</param>
|
||||
/// <param name="callFunction">调用函数的名称</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NullReferenceException"></exception>
|
||||
public async Task<MachineDealJobScheduler> To(string queryId, IMachineMethodData machine)
|
||||
public async Task<MachineDealJobScheduler> To(string queryId, IMachineReflectionCall machine, string callFunction = "Datas")
|
||||
{
|
||||
JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name);
|
||||
|
||||
@@ -363,6 +366,7 @@ namespace Modbus.Net
|
||||
.Build();
|
||||
|
||||
job.JobDataMap.Put("Machine", machine);
|
||||
job.JobDataMap.Put("Function", callFunction);
|
||||
|
||||
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");
|
||||
@@ -379,10 +383,11 @@ namespace Modbus.Net
|
||||
/// <param name="queryId">任务ID,每个触发器唯一</param>
|
||||
/// <param name="machine">要获取数据的设备实例</param>
|
||||
/// <param name="machineDataType">获取数据的方式</param>
|
||||
/// <param name="callFunction">调用函数的名称</param>
|
||||
/// <returns></returns>
|
||||
public async Task<MachineQueryJobScheduler> From(string queryId, IMachineMethodData machine, MachineDataType machineDataType)
|
||||
public async Task<MachineQueryJobScheduler> From(string queryId, IMachineReflectionCall machine, MachineDataType machineDataType, string callFunction = "Datas")
|
||||
{
|
||||
return await new MachineGetJobScheduler(_scheduler, _trigger, _parentJobKey).From(queryId, machine, machineDataType);
|
||||
return await new MachineGetJobScheduler(_scheduler, _trigger, _parentJobKey).From(queryId, machine, machineDataType, callFunction);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -476,9 +481,11 @@ namespace Modbus.Net
|
||||
{
|
||||
object machine;
|
||||
object machineDataType;
|
||||
object callFunction;
|
||||
context.JobDetail.JobDataMap.TryGetValue("Machine", out machine);
|
||||
context.JobDetail.JobDataMap.TryGetValue("DataType", out machineDataType);
|
||||
var values = await (machine as IMachineMethodData)!.GetDatasAsync((MachineDataType)machineDataType);
|
||||
context.JobDetail.JobDataMap.TryGetValue("Function", out callFunction);
|
||||
var values = await (machine as IMachineReflectionCall)!.InvokeGet<Dictionary<string, ReturnUnit>>((string)callFunction, new object[] { (MachineDataType)machineDataType });
|
||||
|
||||
context.JobDetail.JobDataMap.Put("Value", values);
|
||||
await context.Scheduler.AddJob(context.JobDetail, true, false);
|
||||
@@ -522,10 +529,12 @@ namespace Modbus.Net
|
||||
object machineDataType;
|
||||
object values;
|
||||
object valuesSet;
|
||||
object callFunction;
|
||||
context.JobDetail.JobDataMap.TryGetValue("Machine", out machine);
|
||||
context.JobDetail.JobDataMap.TryGetValue("DataType", out machineDataType);
|
||||
context.JobDetail.JobDataMap.TryGetValue("Value", out values);
|
||||
context.JobDetail.JobDataMap.TryGetValue("SetValue", out valuesSet);
|
||||
context.JobDetail.JobDataMap.TryGetValue("Function", out callFunction);
|
||||
if (valuesSet == null && values != null)
|
||||
valuesSet = ((ReturnStruct<Dictionary<string, ReturnUnit>>)values).Datas.MapGetValuesToSetValues();
|
||||
|
||||
@@ -534,7 +543,7 @@ namespace Modbus.Net
|
||||
context.JobDetail.JobDataMap.Put("Success", false);
|
||||
return;
|
||||
}
|
||||
var success = await (machine as IMachineMethodData)!.SetDatasAsync((MachineDataType)machineDataType, (Dictionary<string, double>)valuesSet);
|
||||
var success = await (machine as IMachineReflectionCall)!.InvokeSet((string)callFunction, new object[] { (MachineDataType)machineDataType }, (Dictionary<string, double>)valuesSet);
|
||||
|
||||
context.JobDetail.JobDataMap.Put("Success", success);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">设备的Id类型</typeparam>
|
||||
/// <typeparam name="TUnitKey">设备中使用的AddressUnit的Id类型</typeparam>
|
||||
public abstract class BaseMachine<TKey, TUnitKey> : IMachine<TKey>
|
||||
public abstract class BaseMachine<TKey, TUnitKey> : IMachine<TKey>, IMachineReflectionCall
|
||||
where TKey : IEquatable<TKey>
|
||||
where TUnitKey : IEquatable<TUnitKey>
|
||||
{
|
||||
@@ -665,6 +665,39 @@ namespace Modbus.Net
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取Utility的执行方法
|
||||
/// </summary>
|
||||
/// <typeparam name="TUtilityMethod">Utility实现的接口名称</typeparam>
|
||||
/// <returns></returns>
|
||||
public TUtilityMethod GetUtilityMethods<TUtilityMethod>() where TUtilityMethod : class, IUtilityMethod
|
||||
{
|
||||
return BaseUtility as TUtilityMethod;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<ReturnStruct<T>> InvokeGet<T>(string functionName, object[] parameters)
|
||||
{
|
||||
var machineMethodType = GetType();
|
||||
var machineMethod = this as IMachineMethod;
|
||||
var machineSetMethod = machineMethodType.GetMethod("Get" + functionName + "Async");
|
||||
var ans = machineSetMethod.Invoke(machineMethod, parameters);
|
||||
return await (Task<ReturnStruct<T>>)ans;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<ReturnStruct<bool>> InvokeSet<T>(string functionName, object[] parameters, T datas)
|
||||
{
|
||||
var machineMethodType = GetType();
|
||||
var machineMethod = this as IMachineMethod;
|
||||
var machineSetMethod = machineMethodType.GetMethod("Set" + functionName + "Async");
|
||||
object[] allParams = new object[parameters.Length + 1];
|
||||
Array.Copy(parameters, allParams, parameters.Length);
|
||||
allParams[parameters.Length] = datas;
|
||||
var ans = machineSetMethod.Invoke(machineMethod, allParams);
|
||||
return await (Task<ReturnStruct<bool>>)ans;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接设备
|
||||
/// </summary>
|
||||
@@ -709,16 +742,6 @@ namespace Modbus.Net
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取Utility
|
||||
/// </summary>
|
||||
/// <typeparam name="TUtilityMethod">Utility实现的接口名称</typeparam>
|
||||
/// <returns></returns>
|
||||
public TUtilityMethod GetUtility<TUtilityMethod>() where TUtilityMethod : class, IUtilityMethod
|
||||
{
|
||||
return BaseUtility as TUtilityMethod;
|
||||
}
|
||||
}
|
||||
|
||||
internal class BaseMachineEqualityComparer<TKey> : IEqualityComparer<IMachineProperty<TKey>>
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Modbus.Net.Tests
|
||||
public void GetUtility()
|
||||
{
|
||||
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(1, ModbusType.Tcp, "192.168.3.12", null, true, 2, 0);
|
||||
var utility = baseMachine.GetUtility<IUtilityMethodData>();
|
||||
var utility = baseMachine.GetUtilityMethods<IUtilityMethodData>();
|
||||
var methods = utility.GetType().GetRuntimeMethods();
|
||||
Assert.AreEqual(methods.FirstOrDefault(method => method.Name == "GetDataAsync") != null, true);
|
||||
Assert.AreEqual(methods.FirstOrDefault(method => method.Name == "SetDataAsync") != null, true);
|
||||
@@ -22,7 +22,7 @@ namespace Modbus.Net.Tests
|
||||
public async Task InvokeUtility()
|
||||
{
|
||||
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(1, ModbusType.Tcp, "192.168.3.12", null, true, 2, 0);
|
||||
var success = await baseMachine.BaseUtility.GetUtilityMethods<IUtilityMethodData>().SetDatasAsync("4X 1", new object[] {(byte)11});
|
||||
var success = await baseMachine.BaseUtility.GetUtilityMethods<IUtilityMethodData>().SetDatasAsync("4X 1", new object[] { (byte)11 });
|
||||
Assert.AreEqual(success, true);
|
||||
var datas = await baseMachine.BaseUtility.GetUtilityMethods<IUtilityMethodData>().GetDatasAsync("4X 1", 1);
|
||||
Assert.AreEqual(datas.Datas[0], 11);
|
||||
|
||||
Reference in New Issue
Block a user