From 878b1c5893eb96d366a003b5a36ca9407bf440c2 Mon Sep 17 00:00:00 2001
From: fengjiayi <12821976+ning_xi@user.noreply.gitee.com>
Date: Mon, 7 Oct 2024 15:15:18 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E4=BA=86=E5=AE=9E=E4=BE=8B?=
=?UTF-8?q?=E5=B7=A5=E7=A8=8B=E7=9A=84=E6=8A=BD=E8=B1=A1=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Library/Api/ISereinIoc.cs | 1 +
Library/Entity/MethodDetails.cs | 2 +-
Library/Ex/FlipflopException.cs | 12 +-
Library/{Web => Network/Http}/Attribute.cs | 0
.../{Web => Network/Http}/ControllerBase.cs | 0
.../Http}/QueryStringParser.cs | 0
Library/{Web => Network/Http}/Router.cs | 10 +-
Library/{Web => Network/Http}/WebServer.cs | 0
Library/Network/WebSocket/WebSocketRouter.cs | 10 +
Library/Network/WebSocket/WebSocketServer.cs | 57 +++
Library/NodeAttribute.cs | 6 +-
Library/Utils/ChannelFlowTrigger.cs | 24 +-
Library/Utils/EnumHelper.cs | 10 +
Net462DllTest/Device/SiemensPlcDevice.cs | 293 -----------
Net462DllTest/Enums/FromValue.cs | 1 -
.../Enums/{PlcVarEnum.cs => PlcVarName.cs} | 58 ++-
.../LogicControl/ParkingLogicControl.cs | 13 +-
Net462DllTest/LogicControl/PlcLogicControl.cs | 113 ++---
.../LogicControl/ViewLogicControl.cs | 44 +-
Net462DllTest/Model/PlcVarModel.cs | 144 ++++++
Net462DllTest/Net462DllTest.csproj | 12 +-
Net462DllTest/Signal/PLCVarSignal.cs | 112 +++--
.../{Device => Trigger}/PrakingDevice.cs | 2 +-
Net462DllTest/Trigger/SiemensPlcDevice.cs | 465 ++++++++++++++++++
Net462DllTest/Utils/GSModel.cs | 143 ++++++
Net462DllTest/Utils/RelayCommand.cs | 38 ++
Net462DllTest/Utils/ToValue.cs | 231 ---------
.../View/FromWorkBenchView.Designer.cs | 23 +-
Net462DllTest/View/FromWorkBenchView.cs | 54 +-
.../ViewModel/FromWorkBenchViewModel.cs | 109 +++-
Net462DllTest/Web/CommandController.cs | 33 +-
Net462DllTest/Web/CommandController_1.cs | 42 --
NodeFlow/Base/NodeModelBaseFunc.cs | 2 +-
NodeFlow/FlowEnvironment.cs | 15 +-
NodeFlow/FlowStarter.cs | 11 +-
NodeFlow/Model/SingleFlipflopNode.cs | 33 +-
NodeFlow/Tool/MethodDetailsHelper.cs | 59 ++-
WorkBench/App.xaml.cs | 3 -
WorkBench/MainWindow.xaml.cs | 2 +-
39 files changed, 1361 insertions(+), 826 deletions(-)
rename Library/{Web => Network/Http}/Attribute.cs (100%)
rename Library/{Web => Network/Http}/ControllerBase.cs (100%)
rename Library/{Web => Network/Http}/QueryStringParser.cs (100%)
rename Library/{Web => Network/Http}/Router.cs (98%)
rename Library/{Web => Network/Http}/WebServer.cs (100%)
create mode 100644 Library/Network/WebSocket/WebSocketRouter.cs
create mode 100644 Library/Network/WebSocket/WebSocketServer.cs
delete mode 100644 Net462DllTest/Device/SiemensPlcDevice.cs
rename Net462DllTest/Enums/{PlcVarEnum.cs => PlcVarName.cs} (53%)
create mode 100644 Net462DllTest/Model/PlcVarModel.cs
rename Net462DllTest/{Device => Trigger}/PrakingDevice.cs (91%)
create mode 100644 Net462DllTest/Trigger/SiemensPlcDevice.cs
create mode 100644 Net462DllTest/Utils/GSModel.cs
create mode 100644 Net462DllTest/Utils/RelayCommand.cs
delete mode 100644 Net462DllTest/Utils/ToValue.cs
delete mode 100644 Net462DllTest/Web/CommandController_1.cs
diff --git a/Library/Api/ISereinIoc.cs b/Library/Api/ISereinIoc.cs
index c1aaf32..7f22dcc 100644
--- a/Library/Api/ISereinIoc.cs
+++ b/Library/Api/ISereinIoc.cs
@@ -30,6 +30,7 @@ namespace Serein.Library.Api
///
///
ISereinIOC Register(params object[] parameters) where TImplementation : TService;
+
/////
///// 获取或创建并注入目标类型,会记录到IOC容器中。
/////
diff --git a/Library/Entity/MethodDetails.cs b/Library/Entity/MethodDetails.cs
index a666065..0fa74f9 100644
--- a/Library/Entity/MethodDetails.cs
+++ b/Library/Entity/MethodDetails.cs
@@ -38,7 +38,7 @@ namespace Serein.Library.Entity
///
/// 是否保护参数
///
- public bool IsProtectionParameter { get; set; } = true;
+ public bool IsProtectionParameter { get; set; } = false;
///
/// 作用实例的类型
diff --git a/Library/Ex/FlipflopException.cs b/Library/Ex/FlipflopException.cs
index 6742039..503021c 100644
--- a/Library/Ex/FlipflopException.cs
+++ b/Library/Ex/FlipflopException.cs
@@ -8,11 +8,19 @@ namespace Serein.Library.Ex
///
public class FlipflopException: Exception
{
-
+ public enum CancelClass
+ {
+ // 取消当前分支的继续执行
+ Branch,
+ // 取消整个触发器流程的再次执行
+ Flow,
+ }
public bool IsCancel { get; }
- public FlipflopException(string message, bool isCancel = true) :base(message)
+ public CancelClass Clsss { get; }
+ public FlipflopException(string message, bool isCancel = true,CancelClass clsss = CancelClass.Branch) :base(message)
{
IsCancel = isCancel;
+ Clsss = clsss;
}
}
}
diff --git a/Library/Web/Attribute.cs b/Library/Network/Http/Attribute.cs
similarity index 100%
rename from Library/Web/Attribute.cs
rename to Library/Network/Http/Attribute.cs
diff --git a/Library/Web/ControllerBase.cs b/Library/Network/Http/ControllerBase.cs
similarity index 100%
rename from Library/Web/ControllerBase.cs
rename to Library/Network/Http/ControllerBase.cs
diff --git a/Library/Web/QueryStringParser.cs b/Library/Network/Http/QueryStringParser.cs
similarity index 100%
rename from Library/Web/QueryStringParser.cs
rename to Library/Network/Http/QueryStringParser.cs
diff --git a/Library/Web/Router.cs b/Library/Network/Http/Router.cs
similarity index 98%
rename from Library/Web/Router.cs
rename to Library/Network/Http/Router.cs
index 15c1cfb..d794328 100644
--- a/Library/Web/Router.cs
+++ b/Library/Network/Http/Router.cs
@@ -341,7 +341,15 @@ namespace Serein.Library.Web
{
try
{
- return JsonConvert.DeserializeObject(value.ToString(), targetType);
+ if (targetType == typeof(string))
+ {
+ return value;
+ }
+ else
+ {
+ return JsonConvert.DeserializeObject(value.ToString(), targetType);
+ }
+
}
catch (JsonReaderException ex)
{
diff --git a/Library/Web/WebServer.cs b/Library/Network/Http/WebServer.cs
similarity index 100%
rename from Library/Web/WebServer.cs
rename to Library/Network/Http/WebServer.cs
diff --git a/Library/Network/WebSocket/WebSocketRouter.cs b/Library/Network/WebSocket/WebSocketRouter.cs
new file mode 100644
index 0000000..7b56edd
--- /dev/null
+++ b/Library/Network/WebSocket/WebSocketRouter.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Serein.Library.Network.WebSocketCommunication
+{
+ public class WebSocketRouter
+ {
+ }
+}
diff --git a/Library/Network/WebSocket/WebSocketServer.cs b/Library/Network/WebSocket/WebSocketServer.cs
new file mode 100644
index 0000000..f1e25cf
--- /dev/null
+++ b/Library/Network/WebSocket/WebSocketServer.cs
@@ -0,0 +1,57 @@
+using Newtonsoft.Json;
+using System;
+using System.Net;
+using System.Net.WebSockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Serein.Library.Network.WebSocketCommunication
+{
+ public class WebSocketServer
+ {
+ public Func OnReceiveMsg;
+
+ public async Task StartAsync(string url)
+ {
+ HttpListener listener = new HttpListener();
+ listener.Prefixes.Add(url);
+ listener.Start();
+
+ while (true)
+ {
+ var context = await listener.GetContextAsync();
+ if (context.Request.IsWebSocketRequest)
+ {
+ var webSocketContext = await context.AcceptWebSocketAsync(null); //新连接
+ _ = HandleWebSocketAsync(webSocketContext.WebSocket); // 处理消息
+ }
+ }
+ }
+
+ private async Task HandleWebSocketAsync(WebSocket webSocket)
+ {
+ var buffer = new byte[1024];
+ while (webSocket.State == WebSocketState.Open)
+ {
+ var result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None);
+ if (result.MessageType == WebSocketMessageType.Close)
+ {
+ await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
+ }
+ else
+ {
+ var message = Encoding.UTF8.GetString(buffer, 0, result.Count);
+ Console.WriteLine($"Received: {message}");
+ var action = OnReceiveMsg.Invoke(message);
+ action?.Invoke();
+
+ // 回显消息(可选)
+ //ar echoMessage = Encoding.UTF8.GetBytes(message);
+ //await webSocket.SendAsync(new ArraySegment(echoMessage, 0, echoMessage.Length), result.MessageType, result.EndOfMessage, CancellationToken.None);
+
+ }
+ }
+ }
+ }
+}
diff --git a/Library/NodeAttribute.cs b/Library/NodeAttribute.cs
index b8e9f9c..91c5647 100644
--- a/Library/NodeAttribute.cs
+++ b/Library/NodeAttribute.cs
@@ -25,10 +25,12 @@ namespace Serein.Library.Attributes
[AttributeUsage(AttributeTargets.Class)]
public class DynamicFlowAttribute : Attribute
{
- public DynamicFlowAttribute(bool scan = true)
+ public DynamicFlowAttribute(string name = "",bool scan = true)
{
+ Name = name;
Scan = scan;
}
+ public string Name { get; set; }
public bool Scan { get; set; } = true;
}
@@ -70,7 +72,7 @@ namespace Serein.Library.Attributes
// }
//}
- [AttributeUsage(AttributeTargets.Field)]
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class BindValueAttribute : Attribute
{
public object Value { get; }
diff --git a/Library/Utils/ChannelFlowTrigger.cs b/Library/Utils/ChannelFlowTrigger.cs
index 9c9f0e4..917abce 100644
--- a/Library/Utils/ChannelFlowTrigger.cs
+++ b/Library/Utils/ChannelFlowTrigger.cs
@@ -33,10 +33,15 @@ namespace Serein.Library.NodeFlow.Tool
{
// 使用并发字典管理每个枚举信号对应的 Channel
private readonly ConcurrentDictionary> _channels = new ConcurrentDictionary>();
-
-
- // 到期后自动触发。短时间内触发频率过高的情况下,请将 outTime 设置位短一些的时间,因为如果超时等待时间过长,会导致非预期的“托管内存泄露”。
-
+ ///
+ /// 获取或创建指定信号的 Channel
+ ///
+ /// 枚举信号标识符
+ /// 对应的 Channel
+ private Channel GetOrCreateChannel(TSignal signal)
+ {
+ return _channels.GetOrAdd(signal, _ => Channel.CreateUnbounded());
+ }
///
/// 创建信号并指定超时时间的Channel.
///
@@ -96,6 +101,7 @@ namespace Serein.Library.NodeFlow.Tool
Type = TriggerType.External,
};
// 手动触发信号
+
channel.Writer.TryWrite(triggerData);
return true;
}
@@ -114,14 +120,6 @@ namespace Serein.Library.NodeFlow.Tool
_channels.Clear();
}
- ///
- /// 获取或创建指定信号的 Channel
- ///
- /// 枚举信号标识符
- /// 对应的 Channel
- private Channel GetOrCreateChannel(TSignal signal)
- {
- return _channels.GetOrAdd(signal, _ => Channel.CreateUnbounded());
- }
+
}
}
diff --git a/Library/Utils/EnumHelper.cs b/Library/Utils/EnumHelper.cs
index 3056f9c..c8cae80 100644
--- a/Library/Utils/EnumHelper.cs
+++ b/Library/Utils/EnumHelper.cs
@@ -8,6 +8,16 @@ namespace Serein.Library.Utils
{
public static class EnumHelper
{
+ public static bool TryConvertEnum(this string value, out T result) where T : struct, Enum
+ {
+ if (!string.IsNullOrEmpty(value) && Enum.TryParse(value, true, out T tempResult) && Enum.IsDefined(typeof(T), tempResult))
+ {
+ result = tempResult;
+ return true;
+ }
+ result = default;
+ return false;
+ }
public static TResult GetBoundValue(TEnum enumValue, Func valueSelector)
where TEnum : Enum
{
diff --git a/Net462DllTest/Device/SiemensPlcDevice.cs b/Net462DllTest/Device/SiemensPlcDevice.cs
deleted file mode 100644
index 2418fb9..0000000
--- a/Net462DllTest/Device/SiemensPlcDevice.cs
+++ /dev/null
@@ -1,293 +0,0 @@
-using IoTClient;
-using IoTClient.Clients.PLC;
-using IoTClient.Enums;
-using Net462DllTest.Enums;
-using Net462DllTest.Signal;
-using Serein.Library.Attributes;
-using Serein.Library.NodeFlow.Tool;
-using System;
-
-namespace Net462DllTest.Device
-{
-
- ///
- /// 官方文档:如果没有主动Open,则会每次读写操作的时候自动打开自动和关闭连接,这样会使读写效率大大减低。所以建议手动Open和Close。
- ///
- [AutoRegister]
- public class SiemensPlcDevice : ChannelFlowTrigger
- {
- public SiemensClient Client { get; set; }
-
- public IoTClient.Common.Enums.SiemensVersion Version { get; set; }
- public string IP { get; set; }
- public int Port { get; set; }
- public PlcState State { get; set; } = PlcState.PowerOff;
-
-
- public void Init(IoTClient.Common.Enums.SiemensVersion version,string ip, int port)
- {
- Client = new SiemensClient(version, ip, port);
- Version = version;
- IP = ip;
- Port = port;
- }
-
- public void ResetDevice()
- {
- Client?.Close();
- Client = null;
- }
-
- public void Write(PlcVarInfo plcValue, object value)
- {
- try
- {
- Client.WriteToPlcValue(plcValue, value);
- }
- catch (Exception ex)
- {
- Console.WriteLine($"写入出错:{this}{plcValue}。{ex.Message}");
- throw;
- }
- }
- public object Read(PlcVarInfo plcValue)
- {
- try
- {
- return Client.ReadToPlcValue(plcValue);
- }
- catch (Exception ex)
- {
- Console.WriteLine($"读取出错:{this}{plcValue}。{ex.Message}");
- throw;
- }
-
- }
-
- public override string ToString()
- {
- return $"西门子Plc[{this.Version}-{this.IP}:{this.Port}]";
- }
- }
-
- ///
- /// 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/Net462DllTest/Enums/FromValue.cs b/Net462DllTest/Enums/FromValue.cs
index 4bd6eda..9cefffb 100644
--- a/Net462DllTest/Enums/FromValue.cs
+++ b/Net462DllTest/Enums/FromValue.cs
@@ -10,7 +10,6 @@ namespace Net462DllTest.Signal
{
public enum FromValue
{
- None,
[BindValue(typeof(FromWorkBenchView))]
FromWorkBenchView,
[BindValue(typeof(TestFormView))]
diff --git a/Net462DllTest/Enums/PlcVarEnum.cs b/Net462DllTest/Enums/PlcVarName.cs
similarity index 53%
rename from Net462DllTest/Enums/PlcVarEnum.cs
rename to Net462DllTest/Enums/PlcVarName.cs
index 9c85f3f..3d4408d 100644
--- a/Net462DllTest/Enums/PlcVarEnum.cs
+++ b/Net462DllTest/Enums/PlcVarName.cs
@@ -1,10 +1,18 @@
-using Net462DllTest.Signal;
+using IoTClient.Clients.PLC;
+using IoTClient.Enums;
+using Net462DllTest.Trigger;
+using Net462DllTest.Signal;
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
+using System.Reflection.Emit;
+using System.Reflection;
using System.Text;
using System.Threading.Tasks;
-using static Net462DllTest.Signal.PlcValueAttribute;
+using static Net462DllTest.Signal.PlcVarInfoAttribute;
+using Serein.Library.Attributes;
+using static Net462DllTest.Signal.PlcVarInfo;
namespace Net462DllTest.Enums
{
@@ -12,118 +20,122 @@ namespace Net462DllTest.Enums
///
- /// PLC变量
+ /// PLC变量信息
///
- public enum PlcVarEnum
+ public enum PlcVarName
{
- None,
///
/// 车位号
///
- [PlcValue(typeof(short), "V100", VarType.Writable)]
+ [PlcVarInfo(DataTypeEnum.Int16, "V100", OnNotificationType.OnChanged)]
SpaceNum,
///
/// 上位机指令
///
- [PlcValue(typeof(short), "V102", VarType.Writable)]
+ [PlcVarInfo(DataTypeEnum.Int16, "V102", OnNotificationType.OnChanged)]
CmdForPLC,
///
/// PLC当前存取车位号
///
- [PlcValue(typeof(short), "V110", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Int16, "V110", OnNotificationType.OnChanged)]
DoingSpaceNum,
///
/// 下位机状态
///
- [PlcValue(typeof(short), "V112", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Int16, "V112", OnNotificationType.OnChanged)]
PLCState,
///
/// 门1正常待机车位号,存车完成地面车位0
///
- [PlcValue(typeof(short), "V114", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Int16, "V114", OnNotificationType.OnChanged)]
Door1CurSpaceNum,
///
/// 门2正常待机车位号,存车完成地面车位0
///
- [PlcValue(typeof(short), "V124", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Int16, "V124", OnNotificationType.OnChanged)]
Door2CurSpaceNum,
///
/// 下位机运行模式
///
- [PlcValue(typeof(short), "V116", VarType.Writable)]
+ [PlcVarInfo(DataTypeEnum.Int16, "V116", OnNotificationType.OnChanged)]
PLCRunMode,
///
/// 执行的门号
///
- [PlcValue(typeof(short), "V104", VarType.Writable)]
+ [PlcVarInfo(DataTypeEnum.Int16, "V104", OnNotificationType.OnChanged)]
DoorVar,
///
/// 门1是否开到位
///
- [PlcValue(typeof(bool), "V207.0", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Bool, "V207.0", OnNotificationType.OnChanged)]
IsDoor1OpenDone,
///
/// 门1是否关到位
///
- [PlcValue(typeof(bool), "V207.1", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Bool, "V207.1", OnNotificationType.OnChanged)]
IsDoor1ClosedDone,
///
/// 门2是否开到位
///
- [PlcValue(typeof(bool), "V207.3", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Bool, "V207.3", OnNotificationType.OnChanged)]
IsDoor2OpenDone,
///
/// 门2是否关到位
///
- [PlcValue(typeof(bool), "V207.4", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Bool, "V207.4", OnNotificationType.OnChanged)]
IsDoor2ClosedDone,
///
/// 通道1是否有车
///
- [PlcValue(typeof(bool), "V284.7", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Bool, "V284.7", OnNotificationType.OnChanged)]
HasCarInTone1,
///
/// 通道2是否有车
///
- [PlcValue(typeof(bool), "V286.7", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Bool, "V286.7", OnNotificationType.OnChanged)]
HasCarInTone2,
///
/// 下位机异常代码
///
- [PlcValue(typeof(short), "V2", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Int16, "V2", OnNotificationType.OnChanged)]
ErrorCode,
///
/// 2层以上的空板是否在待机
///
- [PlcValue(typeof(bool), "V200.7", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Bool, "V200.7", OnNotificationType.OnChanged)]
IsOver2FlowStanded,
///
/// 1号门指示灯
///
- [PlcValue(typeof(bool), "Q17.0", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Bool, "Q17.0", OnNotificationType.OnChanged)]
Gate1Light,
///
/// 2号门指示灯
///
- [PlcValue(typeof(bool), "Q17.3", VarType.ReadOnly)]
+ [PlcVarInfo(DataTypeEnum.Bool, "Q17.3", OnNotificationType.OnChanged)]
Gate2Light,
}
+
+
+
+
+
}
diff --git a/Net462DllTest/LogicControl/ParkingLogicControl.cs b/Net462DllTest/LogicControl/ParkingLogicControl.cs
index 200309d..37aabaa 100644
--- a/Net462DllTest/LogicControl/ParkingLogicControl.cs
+++ b/Net462DllTest/LogicControl/ParkingLogicControl.cs
@@ -1,5 +1,6 @@
-using Net462DllTest.Device;
+
using Net462DllTest.Signal;
+using Net462DllTest.Trigger;
using Net462DllTest.ViewModel;
using Serein.Library.Api;
using Serein.Library.Attributes;
@@ -22,7 +23,7 @@ namespace Net462DllTest.LogicControl
}
[AutoRegister]
- [DynamicFlow]
+ [DynamicFlow("[Parking]")]
public class ParkingLogicControl
{
private readonly PrakingDevice PrakingDevice;
@@ -38,7 +39,7 @@ namespace Net462DllTest.LogicControl
{
try
{
- TriggerData triggerData = await PrakingDevice.CreateChannelWithTimeoutAsync(parkingCommand, TimeSpan.FromMinutes(5), 0);
+ TriggerData triggerData = await PrakingDevice.CreateChannelWithTimeoutAsync(parkingCommand, TimeSpan.FromMinutes(120), 0);
if (triggerData.Type == TriggerType.Overtime)
{
throw new FlipflopException("超时取消");
@@ -65,7 +66,7 @@ namespace Net462DllTest.LogicControl
}
- [NodeAction(NodeType.Action, "手动触发模拟调取车位")]
+ [NodeAction(NodeType.Action, "调取指定车位")]
public void Storage(string spaceNum = "101")
{
if (PrakingDevice.TriggerSignal(ParkingCommand.GetPparkingSpace, spaceNum))
@@ -76,11 +77,7 @@ namespace Net462DllTest.LogicControl
else
{
Console.WriteLine("发送命令失败:调取车位" + spaceNum);
-
}
}
-
-
-
}
}
diff --git a/Net462DllTest/LogicControl/PlcLogicControl.cs b/Net462DllTest/LogicControl/PlcLogicControl.cs
index 6624f20..52c8b36 100644
--- a/Net462DllTest/LogicControl/PlcLogicControl.cs
+++ b/Net462DllTest/LogicControl/PlcLogicControl.cs
@@ -1,8 +1,8 @@
using IoTClient.Clients.PLC;
using IoTClient.Common.Enums;
-using Net462DllTest.Device;
using Net462DllTest.Enums;
using Net462DllTest.Signal;
+using Net462DllTest.Trigger;
using Net462DllTest.Web;
using Serein.Library.Api;
using Serein.Library.Attributes;
@@ -20,8 +20,17 @@ using System.Threading.Tasks;
namespace Net462DllTest.LogicControl
{
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class AutoSocketAttribute : Attribute
+ {
+ public string BusinessField;
+ }
+
+
+
+
[AutoRegister]
- [DynamicFlow]
+ [DynamicFlow("[SiemensPlc]")]
public class PlcLogicControl
{
private readonly SiemensPlcDevice MyPlc;
@@ -29,8 +38,6 @@ namespace Net462DllTest.LogicControl
public PlcLogicControl(SiemensPlcDevice MyPlc)
{
this.MyPlc = MyPlc;
-
-
}
#region 初始化、初始化完成以及退出的事件
@@ -39,7 +46,9 @@ namespace Net462DllTest.LogicControl
{
context.Env.IOC.Register();
context.Env.IOC.Register();
-
+
+ //context.Env.IOC.Register();
+ //context.Env.IOC.Register();
}
[NodeAction(NodeType.Loading)] // Loading 初始化完成已注入依赖项,可以开始逻辑上的操作
@@ -47,16 +56,13 @@ namespace Net462DllTest.LogicControl
{
// 注册控制器
context.Env.IOC.Run((router, web) => {
- try
- {
- router.RegisterController(typeof(CommandController));
- web.Start("http://*:8089/"); // 开启 Web 服务
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex);
- }
+ router.RegisterController(typeof(CommandController));
+ web.Start("http://*:8089/"); // 开启 Web 服务
});
+
+ //context.Env.IOC.Run(server => {
+ // server.Start(5000); // 开启 Socket 监听
+ //});
}
[NodeAction(NodeType.Exit)] // 流程结束时自动执行
@@ -66,7 +72,7 @@ namespace Net462DllTest.LogicControl
{
web?.Stop(); // 关闭 Web 服务
});
- MyPlc.ResetDevice();
+ MyPlc.Close();
MyPlc.CancelAllTasks();
}
@@ -74,17 +80,17 @@ namespace Net462DllTest.LogicControl
#region 触发器节点
- [NodeAction(NodeType.Flipflop, "等待信号触发", ReturnType = typeof(int))]
- public async Task WaitTask(CommandSignal order = CommandSignal.Command_1)
+ [NodeAction(NodeType.Flipflop, "等待变量更新", ReturnType = typeof(int))]
+ public async Task WaitTask(PlcVarName varName = PlcVarName.ErrorCode)
{
try
{
- TriggerData triggerData = await MyPlc.CreateChannelWithTimeoutAsync(order, TimeSpan.FromMinutes(5), 0);
+ TriggerData triggerData = await MyPlc.CreateChannelWithTimeoutAsync(varName, TimeSpan.FromMinutes(120), 0);
if (triggerData.Type == TriggerType.Overtime)
{
throw new FlipflopException("超时取消");
}
- //int.TryParse(triggerData.Value.ToString(),out int result);
+ await Console.Out.WriteLineAsync($"PLC变量触发器[{varName}]传递数据:{triggerData.Value}");
return new FlipflopContext(FlipflopStateType.Succeed, triggerData.Value);
}
catch (FlipflopException)
@@ -102,11 +108,13 @@ namespace Net462DllTest.LogicControl
#region 动作节点
- [NodeAction(NodeType.Action, "初始化")]
+ [NodeAction(NodeType.Action, "PLC初始化")]
public SiemensPlcDevice PlcInit(SiemensVersion version = SiemensVersion.None,
string ip = "192.168.10.100",
int port = 102)
{
+ //MyPlc.Model.Set(PlcVarName.DoorVar,1);
+ //MyPlc.Model.Value.SpaceNum = 1;
if (MyPlc.Client is null)
{
try
@@ -129,41 +137,34 @@ namespace Net462DllTest.LogicControl
[NodeAction(NodeType.Action, "设置PLC状态")]
public SiemensPlcDevice SetState(PlcState state = PlcState.PowerOff)
{
- if(MyPlc.Client != null)
- {
- var oldState = MyPlc.State;
- MyPlc.State = state;
- Console.WriteLine($"PLC状态从[{oldState}]转为[{state}]");
- return MyPlc;
- }
- else
- {
- Console.WriteLine($"PLC尚未初始化");
- return MyPlc;
- }
+ var oldState = MyPlc.State;
+ MyPlc.State = state;
+ Console.WriteLine($"PLC状态从[{oldState}]转为[{state}]");
+ return MyPlc;
}
[NodeAction(NodeType.Action, "PLC获取变量")]
- public object ReadVar(PlcVarEnum plcVarEnum)
+ public object ReadVar(PlcVarName plcVarEnum)
{
- var varInfo = ToVarInfo(plcVarEnum);
+ var varInfo = plcVarEnum.ToVarInfo();
var result = MyPlc.Read(varInfo);
Console.WriteLine($"获取变量成功:({varInfo})\t result = {result}");
return result;
}
[NodeAction(NodeType.Action, "PLC写入变量")]
- public SiemensPlcDevice WriteVar2(object value, PlcVarEnum plcVarEnum)
+ public SiemensPlcDevice WriteVar2(object value, PlcVarName varName)
{
- var varInfo = ToVarInfo(plcVarEnum);
+ var varInfo = varName.ToVarInfo();
if (MyPlc.State == PlcState.Runing)
{
- if (varInfo.IsProtected)
+ if (varInfo.IsReadOnly)
{
Console.WriteLine($"PLC变量{varInfo}当前禁止写入");
}
else
{
+
MyPlc.Write(varInfo, value);
Console.WriteLine($"PLC变量{varInfo}写入数据:{value}");
}
@@ -175,30 +176,24 @@ namespace Net462DllTest.LogicControl
return MyPlc;
}
- ///
- /// 缓存变量信息
- ///
- private readonly Dictionary VarInfoDict = new Dictionary();
-
- private PlcVarInfo ToVarInfo(PlcVarEnum plcVarEnum)
+
+ [NodeAction(NodeType.Action, "批量读取")]
+ public void BatchReadVar()
{
- if (VarInfoDict.ContainsKey(plcVarEnum))
- {
- return VarInfoDict[plcVarEnum];
- }
- if (plcVarEnum == PlcVarEnum.None)
- {
- throw new Exception("非预期枚举值");
- }
- var plcValue = EnumHelper.GetBoundValue(plcVarEnum, attr => attr.PlcInfo)
- ?? throw new Exception($"获取变量异常:{plcVarEnum},没有标记PlcValueAttribute");
- if (string.IsNullOrEmpty(plcValue.VarAddress))
- {
- throw new Exception($"获取变量异常:{plcVarEnum},变量地址为空");
- }
- VarInfoDict.Add(plcVarEnum, plcValue);
- return plcValue;
+ MyPlc.BatchRefresh();
}
+ [NodeAction(NodeType.Action, "开启定时刷新")]
+ public void OpenTimedRefresh()
+ {
+ Task.Run(async () => await MyPlc.OpenTimedRefreshAsync());
+ }
+
+ [NodeAction(NodeType.Action, "关闭定时刷新")]
+ public void CloseTimedRefresh()
+ {
+ MyPlc.CloseTimedRefresh();
+ }
+
#endregion
}
diff --git a/Net462DllTest/LogicControl/ViewLogicControl.cs b/Net462DllTest/LogicControl/ViewLogicControl.cs
index 6a47e59..bb09dc8 100644
--- a/Net462DllTest/LogicControl/ViewLogicControl.cs
+++ b/Net462DllTest/LogicControl/ViewLogicControl.cs
@@ -1,25 +1,29 @@
-using Net462DllTest.Device;
+
using Net462DllTest.Signal;
using Net462DllTest.ViewModel;
using Serein.Library.Api;
using Serein.Library.Attributes;
using Serein.Library.Enums;
+using Serein.Library.Ex;
+using Serein.Library.Framework.NodeFlow;
+using Serein.Library.NodeFlow.Tool;
using Serein.Library.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
using System.Windows.Forms;
-namespace Net462DllTest.LogicControl
+namespace Net462DllTest.LogicControl
{
///
/// 视图管理
///
[AutoRegister]
- public class ViewManagement
+ public class ViewManagement:ChannelFlowTrigger
{
- private List