diff --git a/Library/Utils/SereinIoc.cs b/Library/Utils/SereinIoc.cs index 02c64a8..ae83f5e 100644 --- a/Library/Utils/SereinIoc.cs +++ b/Library/Utils/SereinIoc.cs @@ -5,6 +5,7 @@ using Serein.Library.Web; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; using System.Xml; @@ -12,6 +13,7 @@ using System.Xml.Schema; namespace Serein.Library.Utils { + /// /// IOC管理容器 /// @@ -44,20 +46,7 @@ namespace Serein.Library.Utils _unfinishedDependencies = new ConcurrentDictionary>(); } - /// - /// 绑定之前进行的默认绑定 - /// - public void InitRegister() - { - _dependencies[typeof(ISereinIOC).FullName] = this; - Register(); - //foreach (var type in _typeMappings.Values) - //{ - // Register(type); - //} - //Build(); - } #region 类型的注册 @@ -93,51 +82,6 @@ namespace Serein.Library.Utils } #endregion - /// - /// 尝试从容器中获取对象,如果不存在目标类型的对象,则将类型信息登记到容器,并实例化注入依赖项。如果依然无法注册,则返回null。 - /// - //public T GetOrRegisterInstantiate() - //{ - // return (T)GetOrRegisterInstantiate(typeof(T)); - //} - - ///// - ///// 尝试从容器中获取对象,如果不存在目标类型的对象,则将类型信息登记到容器,并实例化注入依赖项。如果依然无法注册,则返回null。 - ///// - //public object GetOrRegisterInstantiate(Type type) - //{ - // // 尝试从容器中获取对象 - // if (!_dependencies.TryGetValue(type.FullName, out object value)) - // { - // // 容器中不存在目标类型的对象 - // if (type.IsInterface) - // { - // if (_typeMappings.TryGetValue(type.FullName, out Type implementationType)) - // { - // // 是接口类型,存在注册信息 - // Register(type);// 注册类型信息 - // value = Instantiate(implementationType); // 创建实例对象,并注入依赖 - // CustomRegisterInstance(type.FullName, value);// 登记到IOC容器中 - // _typeMappings.TryRemove(type.FullName, out _); // 取消类型的注册信息 - // } - // else - // { - // //需要获取接口类型的实例,但不存在类型注册信息 - // Console.WriteLine("当前需要获取接口,但没有注册实现类的类型,无法创建接口实例"); - // return null; - // } - // } - // else - // { - // // 不是接口,直接注册 - // Register(type);// 注册类型信息 - // value = Instantiate(type); // 创建实例对象,并注入依赖 - // CustomRegisterInstance(type.FullName, value);// 登记到IOC容器中 - // } - // } - // return value; - //} - /// /// 用于临时实例的创建,不登记到IOC容器中,依赖项注入失败时也不记录。 /// @@ -229,134 +173,157 @@ namespace Serein.Library.Utils _unfinishedDependencies?.Clear(); _typeMappings?.Clear(); _dependencies?.Clear(); - // _waitingForInstantiation?.Clear(); return true; } - - /// - /// 实例化所有已注册的类型,并尝试绑定 - /// - /// - public bool Build2() + public class TypeKeyValue { - InitRegister(); - // 遍历已注册类型 - foreach (var type in _typeMappings.Values.ToArray()) + public TypeKeyValue(string name, Type type) { - if (!_dependencies.ContainsKey(type.FullName)) - { - var value = CreateInstance(type); // 绑定时注册的类型如果没有创建实例,则创建对应的实例 - CustomRegisterInstance(type.FullName, value);// 登记到IOC容器中 - } - _typeMappings.TryRemove(type.FullName, out _); // 移除类型的注册记录 + this.Type = type; + this.Name = name; } - - - foreach (var instance in _dependencies.Values) - { - InjectDependencies(instance); // 绑定时注入实例的依赖项 - } - - return true; + public string Name { get; set; } + public Type Type { get; set; } } + public Dictionary> BuildDependencyTree() + { + var dependencyMap = new Dictionary>(); + + foreach (var typeMapping in _typeMappings) + { + var constructor = GetConstructorWithMostParameters(typeMapping.Value); // 获取参数最多的构造函数 + if (constructor != null) + { + var parameters = constructor.GetParameters() + .Select(p => p.ParameterType) + .ToList(); + + foreach (var param in parameters) + { + if (!dependencyMap.ContainsKey(param.FullName)) + { + dependencyMap[param.FullName] = new List(); + } + dependencyMap[param.FullName].Add(typeMapping.Key); + } + } + } + + return dependencyMap; + } + // 获取参数最多的构造函数 + private ConstructorInfo GetConstructorWithMostParameters(Type type) + { + return type.GetConstructors() + .OrderByDescending(c => c.GetParameters().Length) + .FirstOrDefault(); + } + // 生成顺序 + public List GetCreationOrder(Dictionary> dependencyMap) + { + var graph = new Dictionary>(); + var indegree = new Dictionary(); + + foreach (var entry in dependencyMap) + { + var key = entry.Key; + if (!graph.ContainsKey(key)) + { + graph[key] = new List(); + } + + foreach (var dependent in entry.Value) + { + if (!graph.ContainsKey(dependent)) + { + graph[dependent] = new List(); + } + graph[key].Add(dependent); + + // 更新入度 + if (!indegree.ContainsKey(dependent)) + { + indegree[dependent] = 0; + } + indegree[dependent]++; + } + + if (!indegree.ContainsKey(key)) + { + indegree[key] = 0; + } + } + + // 拓扑排序 + var creationOrder = new List(); + var queue = new Queue(indegree.Where(x => x.Value == 0).Select(x => x.Key)); + + while (queue.Count > 0) + { + var current = queue.Dequeue(); + creationOrder.Add(current); + + foreach (var neighbor in graph[current]) + { + indegree[neighbor]--; + if (indegree[neighbor] == 0) + { + queue.Enqueue(neighbor); + } + } + } + + return creationOrder; + } + + public object CreateInstance(string typeName) + { + if (_typeMappings.TryGetValue(typeName, out var type)) + { + var constructor = GetConstructorWithMostParameters(type); + var parameters = constructor.GetParameters(); + var args = new object[parameters.Length]; + + + for (int i = 0; i < parameters.Length; i++) + { + var fullName = parameters[i].ParameterType.FullName; + if (!_dependencies.TryGetValue(fullName, out var argObj)) + { + argObj = CreateInstance(parameters[i].ParameterType.FullName); + } + args[i] = argObj; + } + var value = Activator.CreateInstance(type, args); + _dependencies[typeName] = value; + return value; + } + + return null; + } + + public bool Build() { - InitRegister(); - var graph = new Dictionary>(); - //var graph = new Dictionary>(); + var dependencyTree = BuildDependencyTree(); + var creationOrder = GetCreationOrder(dependencyTree); - // 构建依赖关系图 - foreach (var type in _typeMappings.Values) + // 输出创建顺序 + Debug.WriteLine("创建顺序: " + string.Join(" → ", creationOrder)); + + // 创建对象 + foreach (var typeName in creationOrder) { - var constructor = type.GetConstructors() - .OrderByDescending(c => c.GetParameters().Length) - .FirstOrDefault(); - - if (constructor != null) - { - var parameters = constructor.GetParameters(); - foreach (var param in parameters) - { - var paramTypeName = param.ParameterType.FullName; - if (!graph.ContainsKey(paramTypeName)) - { - graph[paramTypeName] = new List(); - } - graph[paramTypeName].Add(type); // 使用 Type 而不是字符串 - } - } + var value = CreateInstance(typeName); + } - - // 执行拓扑排序 - var sortedTypes = TopologicalSort(graph); - - // 创建实例并注册 - foreach (var type in sortedTypes) - { - var typeName = type.FullName; - if (!_dependencies.ContainsKey(typeName)) - { - - var value = CreateInstance(type); - CustomRegisterInstance(typeName, value); - //if (graph.ContainsKey(typeName)) - //{ - - - //} - //else - //{ - // Console.WriteLine("error:"+typeName); - //} - } - else - { - Console.WriteLine("not create:" + type); - } - } - + _typeMappings.Clear(); return true; + } - /// - /// 执行拓扑排序 - /// - /// - /// - private List TopologicalSort(Dictionary> graph) - { - var sorted = new List(); - var visited = new HashSet(); - - void Visit(Type node) - { - var nodeName = node.FullName; - if (visited.Contains(nodeName)) return; - visited.Add(nodeName); - if (graph.TryGetValue(nodeName, out var neighbors)) - { - foreach (var neighbor in neighbors) - { - Visit(neighbor); - } - } - sorted.Add(node); - } - - foreach (var node in graph.Keys) - { - if (!_dependencies.ContainsKey(node)) - { - var type = _typeMappings[node]; // 获取对应的 Type - Visit(type); - } - - } - - sorted.Reverse(); // 反转以得到正确顺序 - return sorted; - } + #endregion #region 私有方法 @@ -380,19 +347,6 @@ namespace Serein.Library.Utils } } - /// - /// 创建实例时,尝试注入到由ioc容器管理、并需要此实例的对象。 - /// - private object CreateInstance(Type type) - { - var constructor = type.GetConstructors().First(); // 获取第一个构造函数 - var parameters = constructor.GetParameters(); // 获取参数列表 - var parameterValues = parameters.Select(param => ResolveDependency(param.ParameterType)).ToArray(); - var instance = Activator.CreateInstance(type, parameterValues); - InjectUnfinishedDependencies(type.FullName, instance); - return instance; - } - private object ResolveDependency(Type parameterType) { var obj = Get(parameterType); @@ -459,55 +413,16 @@ namespace Serein.Library.Utils return isPass; } - - /// - /// 再次尝试注入目标实例的依赖项 - /// - //private void TryInstantiateWaitingDependencies() - //{ - // foreach (var waitingType in _waitingForInstantiation.ToList()) - // { - // if (_typeMappings.TryGetValue(waitingType.FullName, out var implementationType)) - // { - // var instance = Instantiate(implementationType); - // if (instance != null) - // { - - // _dependencies[waitingType.FullName] = instance; - - // _waitingForInstantiation.Remove(waitingType); - // } - // } - // } - //} - #endregion - - #region run() - //public bool Run(string name, Action action) - //{ - // var obj = Get(name); - // if (obj != null) - // { - // if(obj is T service) - // { - // try - // { - // action(service); - // } - // catch (Exception ex) - // { - // Console.WriteLine(ex.Message); - // } - // } - // } - // return this; - //} - - + public void Run(Action action) { var service = Get(); - if (service != null) + if (service == null) + { + throw new Exception("类型没有注册:"+typeof(T).FullName); + + } + else { action(service); } diff --git a/Library/Web/Router.cs b/Library/Web/Router.cs index 12192e9..a7318f3 100644 --- a/Library/Web/Router.cs +++ b/Library/Web/Router.cs @@ -31,10 +31,7 @@ namespace Serein.Library.Web { private readonly ISereinIOC SereinIOC; // 用于存储路由信息 - public Router(ISereinIOC SereinIOC) - { - this.SereinIOC = SereinIOC; - } + /// /// 控制器实例对象的类型,每次调用都会重新实例化,[Url - ControllerType] /// @@ -50,9 +47,9 @@ namespace Serein.Library.Web //private Type PostRequest; - public Router() + public Router(ISereinIOC SereinIOC) { - + this.SereinIOC = SereinIOC; _routes = new ConcurrentDictionary>(); // 初始化路由字典 _controllerTypes = new ConcurrentDictionary(); // 初始化控制器实例对象字典 foreach (API method in Enum.GetValues(typeof(API))) // 遍历 HTTP 枚举类型的所有值 diff --git a/Library/Web/WebServer.cs b/Library/Web/WebServer.cs index e0ff7e0..824d67a 100644 --- a/Library/Web/WebServer.cs +++ b/Library/Web/WebServer.cs @@ -20,6 +20,8 @@ namespace Serein.Library.Web public WebServer(IRouter router) { this.Router = router; + listener = new HttpListener(); + requestLimiter = new RequestLimiter(5, 8); } @@ -29,11 +31,6 @@ namespace Serein.Library.Web private HttpListener listener; // HTTP 监听器 private RequestLimiter requestLimiter; //接口防刷 - public WebServer() - { - listener = new HttpListener(); - requestLimiter = new RequestLimiter(5, 8); - } // 启动服务器 public WebServer Start(string prefixe) diff --git a/Net461DllTest/Device/SiemensPlcDevice.cs b/Net461DllTest/Device/SiemensPlcDevice.cs index a0991f8..4c711c6 100644 --- a/Net461DllTest/Device/SiemensPlcDevice.cs +++ b/Net461DllTest/Device/SiemensPlcDevice.cs @@ -1,7 +1,8 @@ -using IoTClient.Clients.PLC; +using IoTClient; +using IoTClient.Clients.PLC; +using IoTClient.Enums; using Net461DllTest.Enums; using Net461DllTest.Signal; -using Net461DllTest.Utils; using Serein.Library.Attributes; using Serein.Library.NodeFlow.Tool; using System; @@ -13,7 +14,7 @@ namespace Net461DllTest.Device /// 官方文档:如果没有主动Open,则会每次读写操作的时候自动打开自动和关闭连接,这样会使读写效率大大减低。所以建议手动Open和Close。 /// [AutoRegister] - public class SiemensPlcDevice : ChannelFlowTrigger + public class SiemensPlcDevice : ChannelFlowTrigger { public SiemensClient Client { get; set; } @@ -69,4 +70,224 @@ namespace Net461DllTest.Device } } + /// + /// PLC方法 + /// + public static class PlcExtension + { + public static DataTypeEnum ToDataTypeEnum(this PlcVarInfo varInfo) + { + Type dataType = varInfo.DataType; + DataTypeEnum plcDataType; + switch (dataType) + { + case Type _ when dataType == typeof(string): + plcDataType = DataTypeEnum.String; + break; + case Type _ when dataType == typeof(char): + plcDataType = DataTypeEnum.String; + break; + case Type _ when dataType == typeof(bool): + plcDataType = DataTypeEnum.Bool; + break; + case Type _ when dataType == typeof(float): + plcDataType = DataTypeEnum.Float; + break; + case Type _ when dataType == typeof(double): + plcDataType = DataTypeEnum.Double; + break; + case Type _ when dataType == typeof(byte): + plcDataType = DataTypeEnum.Byte; + break; + case Type _ when dataType == typeof(short): + plcDataType = DataTypeEnum.Int16; + break; + case Type _ when dataType == typeof(ushort): + plcDataType = DataTypeEnum.UInt16; + break; + case Type _ when dataType == typeof(int): + plcDataType = DataTypeEnum.Int32; + break; + case Type _ when dataType == typeof(uint): + plcDataType = DataTypeEnum.UInt32; + break; + case Type _ when dataType == typeof(long): + plcDataType = DataTypeEnum.Int64; + break; + case Type _ when dataType == typeof(ulong): + plcDataType = DataTypeEnum.UInt64; + break; + default: + plcDataType = DataTypeEnum.None; + break; + } + + + return plcDataType; + } + + /// + /// 读取设备的值 + /// + /// + /// + /// + /// + public static object ReadToPlcValue(this SiemensClient client, PlcVarInfo varInfo) + { + Type dataType = varInfo.DataType; + object resultvalue; + if (dataType == typeof(string)) + { + var result = client.ReadString(varInfo.VarAddress); + if (!result.IsSucceed) throw new Exception(result.Err); + resultvalue = result.Value; + } + else if (dataType == typeof(char)) + { + var result = client.ReadString(varInfo.VarAddress); + if (!result.IsSucceed) throw new Exception(result.Err); + resultvalue = result.Value; + } + else if (dataType == typeof(bool)) + { + var result = client.ReadBoolean(varInfo.VarAddress); + if (!result.IsSucceed) throw new Exception(result.Err); + resultvalue = result.Value; + } + else if (dataType == typeof(float)) + { + var result = client.ReadFloat(varInfo.VarAddress); + if (!result.IsSucceed) throw new Exception(result.Err); + resultvalue = result.Value; + } + else if (dataType == typeof(double)) + { + var result = client.ReadDouble(varInfo.VarAddress); + if (!result.IsSucceed) throw new Exception(result.Err); + resultvalue = result.Value; + } + else if (dataType == typeof(byte)) + { + var result = client.ReadByte(varInfo.VarAddress); + if (!result.IsSucceed) throw new Exception(result.Err); + resultvalue = result.Value; + } + else if (dataType == typeof(short)) + { + var result = client.ReadInt16(varInfo.VarAddress); + if (!result.IsSucceed) throw new Exception(result.Err); + resultvalue = result.Value; + } + else if (dataType == typeof(ushort)) + { + var result = client.ReadUInt16(varInfo.VarAddress); + if (!result.IsSucceed) throw new Exception(result.Err); + resultvalue = result.Value; + } + else if (dataType == typeof(int)) + { + var result = client.ReadInt32(varInfo.VarAddress); + if (!result.IsSucceed) throw new Exception(result.Err); + resultvalue = result.Value; + } + else if (dataType == typeof(uint)) + { + var result = client.ReadUInt32(varInfo.VarAddress); + if (!result.IsSucceed) throw new Exception(result.Err); + resultvalue = result.Value; + } + else if (dataType == typeof(long)) + { + var result = client.ReadInt64(varInfo.VarAddress); + if (!result.IsSucceed) throw new Exception(result.Err); + resultvalue = result.Value; + } + else if (dataType == typeof(ulong)) + { + var result = client.ReadUInt64(varInfo.VarAddress); + if (!result.IsSucceed) throw new Exception(result.Err); + resultvalue = result.Value; + } + else + { + resultvalue = default; + } + return resultvalue; + } + + public static void WriteToPlcValue(this SiemensClient client, PlcVarInfo varInfo, object value) + { + if (client == null) throw new ArgumentNullException("client"); + Type dataType = varInfo.DataType; + Result result = null; + if (dataType == typeof(string)) + { + result = client.Write(varInfo.VarAddress, value.ToString()); + } + else if (dataType == typeof(char)) + { + result = client.Write(varInfo.VarAddress, value.ToString()); + } + else if (dataType == typeof(bool)) + { + var @bool = bool.Parse(value.ToString()); + result = client.Write(varInfo.VarAddress, @bool); + } + else if (dataType == typeof(float)) + { + var @float = float.Parse(value.ToString()); + result = client.Write(varInfo.VarAddress, @float); + } + else if (dataType == typeof(double)) + { + var @double = double.Parse(value.ToString()); + result = client.Write(varInfo.VarAddress, @double); + } + else if (dataType == typeof(byte)) + { + var @byte = byte.Parse(value.ToString()); + result = client.Write(varInfo.VarAddress, @byte); + } + else if (dataType == typeof(short)) + { + var @short = short.Parse(value.ToString()); + result = client.Write(varInfo.VarAddress, @short); + } + else if (dataType == typeof(ushort)) + { + var @ushort = ushort.Parse(value.ToString()); + result = client.Write(varInfo.VarAddress, @ushort); + } + else if (dataType == typeof(int)) + { + var @int = int.Parse(value.ToString()); + result = client.Write(varInfo.VarAddress, @int); + } + else if (dataType == typeof(uint)) + { + var @uint = uint.Parse(value.ToString()); + result = client.Write(varInfo.VarAddress, @uint); + } + else if (dataType == typeof(long)) + { + var @long = long.Parse(value.ToString()); + result = client.Write(varInfo.VarAddress, @long); + } + else if (dataType == typeof(ulong)) + { + var @ulong = ulong.Parse(value.ToString()); + result = client.Write(varInfo.VarAddress, @ulong); + } + if (result is null) + { + throw new Exception($"未定义的数据类型"); + } + if (!result.IsSucceed) + { + throw new Exception(result.Err); + } + } + + } } diff --git a/Net461DllTest/Enums/PlcVarEnum.cs b/Net461DllTest/Enums/PlcVarEnum.cs index 8fac389..2ccaaf8 100644 --- a/Net461DllTest/Enums/PlcVarEnum.cs +++ b/Net461DllTest/Enums/PlcVarEnum.cs @@ -17,18 +17,35 @@ namespace Net461DllTest.Enums public enum PlcVarEnum { None, + /// + /// 车位号 + /// + [PlcValue(typeof(short), "V100", VarType.Writable)] + SpaceNum, + /// /// 上位机指令 /// [PlcValue(typeof(short), "V102", VarType.Writable)] CmdForPLC, + /// + /// PLC当前存取车位号 + /// + [PlcValue(typeof(short), "V110", VarType.ReadOnly)] + DoingSpaceNum, + /// /// 下位机状态 /// [PlcValue(typeof(short), "V112", VarType.ReadOnly)] PLCState, + /// + /// 门1正常待机车位号,存车完成地面车位0 + /// + [PlcValue(typeof(short), "V114", VarType.ReadOnly)] + Door1CurSpaceNum, /// /// 门2正常待机车位号,存车完成地面车位0 @@ -73,6 +90,17 @@ namespace Net461DllTest.Enums [PlcValue(typeof(bool), "V207.4", VarType.ReadOnly)] IsDoor2ClosedDone, + /// + /// 通道1是否有车 + /// + [PlcValue(typeof(bool), "V284.7", VarType.ReadOnly)] + HasCarInTone1, + + /// + /// 通道2是否有车 + /// + [PlcValue(typeof(bool), "V286.7", VarType.ReadOnly)] + HasCarInTone2, /// /// 下位机异常代码 @@ -80,6 +108,12 @@ namespace Net461DllTest.Enums [PlcValue(typeof(short), "V2", VarType.ReadOnly)] ErrorCode, + /// + /// 2层以上的空板是否在待机 + /// + [PlcValue(typeof(bool), "V200.7", VarType.ReadOnly)] + IsOver2FlowStanded, + /// /// 1号门指示灯 /// diff --git a/Net461DllTest/LogicControl/PlcLogicControl.cs b/Net461DllTest/LogicControl/PlcLogicControl.cs index 9ed600c..07caa0a 100644 --- a/Net461DllTest/LogicControl/PlcLogicControl.cs +++ b/Net461DllTest/LogicControl/PlcLogicControl.cs @@ -29,30 +29,43 @@ namespace Net461DllTest.LogicControl public PlcLogicControl(SiemensPlcDevice MyPlc) { this.MyPlc = MyPlc; + + } #region 初始化、初始化完成以及退出的事件 [NodeAction(NodeType.Init)] // Init : 初始化事件,流程启动时执行 public void Init(IDynamicContext context) { - // // 注册控制器 - context.Env.IOC.Run(router => { - router.RegisterController(typeof(ApiController)); - }); + context.Env.IOC.Register(); + context.Env.IOC.Register(); + } [NodeAction(NodeType.Loading)] // Loading 初始化完成已注入依赖项,可以开始逻辑上的操作 public void Loading(IDynamicContext context) { - context.Env.IOC.Run((web) => - { - web.Start("http://*:8089/"); // 开启 Web 服务 + // 注册控制器 + context.Env.IOC.Run((router, web) => { + try + { + router.RegisterController(typeof(CommandController)); + web.Start("http://*:8089/"); // 开启 Web 服务 + } + catch (Exception ex) + { + Console.WriteLine(ex); + } }); } [NodeAction(NodeType.Exit)] // 流程结束时自动执行 public void Exit(IDynamicContext context) { + context.Env.IOC.Run((web) => + { + web?.Stop(); // 关闭 Web 服务 + }); MyPlc.ResetDevice(); MyPlc.CancelAllTasks(); } @@ -62,7 +75,7 @@ namespace Net461DllTest.LogicControl #region 触发器节点 [NodeAction(NodeType.Flipflop, "等待信号触发", ReturnType = typeof(int))] - public async Task WaitTask(OrderSignal order = OrderSignal.Command_1) + public async Task WaitTask(CommandSignal order = CommandSignal.Command_1) { try { @@ -113,7 +126,6 @@ namespace Net461DllTest.LogicControl return MyPlc; } - [NodeAction(NodeType.Action, "设置PLC状态")] public SiemensPlcDevice SetState(PlcState state = PlcState.PowerOff) { @@ -129,14 +141,12 @@ namespace Net461DllTest.LogicControl Console.WriteLine($"PLC尚未初始化"); return MyPlc; } - } - // [BindConvertor(typeof(PlcVarEnum), typeof(PlcVarConvertor))] [NodeAction(NodeType.Action, "PLC获取变量")] public object ReadVar(PlcVarEnum plcVarEnum) { - var varInfo = Convertor(plcVarEnum); + var varInfo = ToVarInfo(plcVarEnum); var result = MyPlc.Read(varInfo); Console.WriteLine($"获取变量成功:({varInfo})\t result = {result}"); return result; @@ -145,7 +155,7 @@ namespace Net461DllTest.LogicControl [NodeAction(NodeType.Action, "PLC写入变量")] public SiemensPlcDevice WriteVar2(object value, PlcVarEnum plcVarEnum) { - var varInfo = Convertor(plcVarEnum); + var varInfo = ToVarInfo(plcVarEnum); if (MyPlc.State == PlcState.Runing) { if (varInfo.IsProtected) @@ -165,9 +175,12 @@ namespace Net461DllTest.LogicControl return MyPlc; } - - private readonly Dictionary VarInfoDict; - public PlcVarInfo Convertor(PlcVarEnum plcVarEnum) + /// + /// 缓存变量信息 + /// + private readonly Dictionary VarInfoDict = new Dictionary(); + + private PlcVarInfo ToVarInfo(PlcVarEnum plcVarEnum) { if (VarInfoDict.ContainsKey(plcVarEnum)) { @@ -187,28 +200,6 @@ namespace Net461DllTest.LogicControl return plcValue; } - /// - /// 转换器,用于将枚举转为自定义特性中的数据 - /// - //public class PlcVarConvertor: IEnumConvertor - //{ - // public PlcVarInfo Convertor(PlcVarEnum plcVarValue) - // { - // if (plcVarValue == PlcVarEnum.None) - // { - // throw new Exception("非预期枚举值"); - // } - // var plcValue = EnumHelper.GetBoundValue(plcVarValue, attr => attr.PlcInfo) - // ?? throw new Exception($"获取变量异常:{plcVarValue},没有标记PlcValueAttribute"); - // if (string.IsNullOrEmpty(plcValue.VarAddress)) - // { - // throw new Exception($"获取变量异常:{plcVarValue},变量地址为空"); - // } - // return plcValue; - // } - - //} - #endregion } } diff --git a/Net461DllTest/LogicControl/ViewLogicControl.cs b/Net461DllTest/LogicControl/ViewLogicControl.cs index 031495b..15aa626 100644 --- a/Net461DllTest/LogicControl/ViewLogicControl.cs +++ b/Net461DllTest/LogicControl/ViewLogicControl.cs @@ -10,19 +10,23 @@ using System.Collections.Generic; using System.Linq; using System.Windows.Forms; -namespace Net461DllTest.LogicControl -{ +namespace Net461DllTest.LogicControl +{ + + /// + /// 视图管理 + /// [AutoRegister] public class ViewManagement { - private List
forms = new List(); + /// + /// 打开窗口 + /// + /// 要打开的窗口类型 + /// 是否置顶 public void OpenView(Form form, bool isTop) { - form.FormClosing += (s, e) => - { - // 关闭窗体时执行一些关于逻辑层的操作 - }; form.TopMost = isTop; form.Show(); forms.Add(form); @@ -36,8 +40,6 @@ namespace Net461DllTest.LogicControl f.Dispose(); this.forms.Remove(f); } - - } } diff --git a/Net461DllTest/Net461DllTest.csproj b/Net461DllTest/Net461DllTest.csproj index 3676fab..3bb3dea 100644 --- a/Net461DllTest/Net461DllTest.csproj +++ b/Net461DllTest/Net461DllTest.csproj @@ -68,7 +68,7 @@ - + @@ -84,7 +84,7 @@ TestFormView.cs - + diff --git a/Net461DllTest/Signal/OrderSignal.cs b/Net461DllTest/Signal/CommandSignal.cs similarity index 88% rename from Net461DllTest/Signal/OrderSignal.cs rename to Net461DllTest/Signal/CommandSignal.cs index 7eeb8a8..c8dfe50 100644 --- a/Net461DllTest/Signal/OrderSignal.cs +++ b/Net461DllTest/Signal/CommandSignal.cs @@ -1,6 +1,6 @@ namespace Net461DllTest.Signal { - public enum OrderSignal + public enum CommandSignal { Command_1, Command_2, diff --git a/Net461DllTest/Signal/CommandSignal_1.cs b/Net461DllTest/Signal/CommandSignal_1.cs new file mode 100644 index 0000000..c8dfe50 --- /dev/null +++ b/Net461DllTest/Signal/CommandSignal_1.cs @@ -0,0 +1,15 @@ +namespace Net461DllTest.Signal +{ + public enum CommandSignal + { + Command_1, + Command_2, + Command_3, + Command_4, + Command_5, + Command_6, + Command_7, + Command_8, + Command_9, + } +} diff --git a/Net461DllTest/View/FromWorkBenchView.cs b/Net461DllTest/View/FromWorkBenchView.cs index 0eaca8f..ac47216 100644 --- a/Net461DllTest/View/FromWorkBenchView.cs +++ b/Net461DllTest/View/FromWorkBenchView.cs @@ -21,7 +21,7 @@ namespace Net461DllTest public FromWorkBenchView(IFlowEnvironment env) { - ViewModel = env.IOC.Instantiate(); + ViewModel = env.IOC.Instantiate(); // 创建对象并注入依赖项 InitializeComponent(); Init(); } @@ -29,7 +29,7 @@ namespace Net461DllTest public void Init() { listBox1.Items.Clear(); - var enumValues = Enum.GetValues(typeof(OrderSignal)).Cast(); + var enumValues = Enum.GetValues(typeof(CommandSignal)).Cast(); foreach (var value in enumValues) { listBox1.Items.Add(value.ToString()); @@ -49,7 +49,7 @@ namespace Net461DllTest } string type = listBox1.SelectedItem.ToString(); - if (!string.IsNullOrEmpty(type) && Enum.TryParse(type, out OrderSignal signal) && Enum.IsDefined(typeof(OrderSignal), signal)) + if (!string.IsNullOrEmpty(type) && Enum.TryParse(type, out CommandSignal signal) && Enum.IsDefined(typeof(CommandSignal), signal)) { Console.WriteLine($"Trigger : {type}"); ViewModel.Trigger(signal,textBoxSpaceNum.Text); diff --git a/Net461DllTest/ViewModel/FromWorkBenchViewModel.cs b/Net461DllTest/ViewModel/FromWorkBenchViewModel.cs index 8715120..0c0fed2 100644 --- a/Net461DllTest/ViewModel/FromWorkBenchViewModel.cs +++ b/Net461DllTest/ViewModel/FromWorkBenchViewModel.cs @@ -24,7 +24,7 @@ namespace Net461DllTest.ViewModel return Device?.ToString(); } - public void Trigger(OrderSignal signal,string spcaeNumber) + public void Trigger(CommandSignal signal,string spcaeNumber) { _ = Task.Run(() => { diff --git a/Net461DllTest/Web/CommandController.cs b/Net461DllTest/Web/CommandController.cs new file mode 100644 index 0000000..ac37c59 --- /dev/null +++ b/Net461DllTest/Web/CommandController.cs @@ -0,0 +1,47 @@ +using Net461DllTest.Device; +using Net461DllTest.Signal; +using Serein.Library.Attributes; +using Serein.Library.Web; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Net461DllTest.Web +{ + [AutoHosting] + public class CommandController : ControllerBase + { + private SiemensPlcDevice PlcDevice; + + public CommandController(SiemensPlcDevice PlcDevice) + { + this.PlcDevice = PlcDevice; + } + + + /* + * 类型 :POST + * url : http://127.0.0.1:8089/command/trigger?command= + * body :[JSON] + * + * { + * "value":0, + * } + * + */ + [WebApi(API.POST)] + public dynamic Trigger([Url] string command, int value) + { + if (Enum.TryParse(command, out CommandSignal signal) && Enum.IsDefined(typeof(CommandSignal), signal)) + { + Console.WriteLine($"外部触发 {signal} 信号,信号内容 : {value} "); + PlcDevice.TriggerSignal(signal, value);// 通过 Web Api 模拟外部输入信号 + return new { state = "succeed" }; + } + return new { state = "fail" }; + } + } + +} diff --git a/Net461DllTest/Web/ApiController.cs b/Net461DllTest/Web/CommandController_1.cs similarity index 63% rename from Net461DllTest/Web/ApiController.cs rename to Net461DllTest/Web/CommandController_1.cs index 658af8c..d4fc1c8 100644 --- a/Net461DllTest/Web/ApiController.cs +++ b/Net461DllTest/Web/CommandController_1.cs @@ -11,15 +11,25 @@ using System.Threading.Tasks; namespace Net461DllTest.Web { [AutoHosting] - public class ApiController : ControllerBase + public class CommandController : ControllerBase { [AutoInjection] public SiemensPlcDevice PlcDevice { get; set; } + /* + * 类型 :POST + * url : http://127.0.0.1:8089/command/trigger?command= + * body :[JSON] + * + * { + * "value":0, + * } + * + */ [WebApi(API.POST)] - public dynamic Trigger([Url] string type, int value) + public dynamic Trigger([Url] string command, int value) { - if (Enum.TryParse(type, out OrderSignal signal) && Enum.IsDefined(typeof(OrderSignal), signal)) + if (Enum.TryParse(command, out CommandSignal signal) && Enum.IsDefined(typeof(CommandSignal), signal)) { Console.WriteLine($"外部触发 {signal} 信号,信号内容 : {value} "); PlcDevice.TriggerSignal(signal, value);// 通过 Web Api 模拟外部输入信号