Browse Source

Merge branch 'debug' of zuolinhao/WCS-Pedestal into master

zuolinhao 3 years ago
parent
commit
c7abdff273
40 changed files with 642 additions and 199 deletions
  1. 6 6
      DBHelper-SqlSugar/DB.cs
  2. BIN
      DLL/PLC.Siemens.dll
  3. 28 5
      Projects/永冠OPP/WCS.Entity.Protocol/RGV/WCS_RGV521.cs
  4. 10 2
      Projects/永冠OPP/WCS.Entity.Protocol/RGV/WCS_RGV523.cs
  5. 1 1
      Projects/永冠OPP/WCS.Entity.Protocol/SRM/ISRM521.cs
  6. 40 2
      Projects/永冠OPP/WCS.Entity.Protocol/SRM/WCS_SRM520.cs
  7. 68 3
      Projects/永冠OPP/WCS.Entity.Protocol/SRM/WCS_SRM521.cs
  8. 5 2
      Projects/永冠OPP/WCS.Entity.Protocol/SRM/WCS_SRM537.cs
  9. 34 14
      Projects/永冠OPP/WCS.Entity.Protocol/Station/WCS_Station520.cs
  10. 13 2
      Projects/永冠OPP/WCS.Entity.Protocol/Station/WCS_Station521.cs
  11. 8 2
      Projects/永冠OPP/WCS.Entity.Protocol/Station/WCS_Station523.cs
  12. 57 1
      Projects/永冠OPP/WCS.Service/Extensions/TypeExtension.cs
  13. 13 12
      Projects/永冠OPP/WCS.Service/Handlers/DataClearHandler.cs
  14. 1 1
      Projects/永冠OPP/WCS.Service/Handlers/WorkHandler.cs
  15. 21 8
      Projects/永冠OPP/WCS.Service/PLCAccessors/SiemensS7PLC.cs
  16. 2 0
      Projects/永冠OPP/WCS.Service/Program.cs
  17. 15 31
      Projects/永冠OPP/WCS.Service/ProtocolProxy.cs
  18. 4 1
      Projects/永冠OPP/WCS.Service/WCS.Service.csproj
  19. 1 0
      Projects/永冠OPP/WCS.Service/WebApi/WMS/WMS.cs
  20. 43 13
      Projects/永冠OPP/WCS.Service/Worker.cs
  21. 6 6
      Projects/永冠OPP/WCS.Service/Works/RGV/RGVWorks.cs
  22. 2 2
      Projects/永冠OPP/WCS.Service/Works/SRM/SRMWork.cs
  23. 6 7
      Projects/永冠OPP/WCS.Service/Works/Station/BOPP入库.cs
  24. 11 8
      Projects/永冠OPP/WCS.Service/Works/Station/一楼入库.cs
  25. 6 6
      Projects/永冠OPP/WCS.Service/Works/Station/一楼出库.cs
  26. 11 22
      Projects/永冠OPP/WCS.Service/Works/Station/涂布入库.cs
  27. 10 10
      Projects/永冠OPP/WCS.Service/Works/Station/涂布出库.cs
  28. 5 3
      Projects/永冠OPP/WCS.Service/appsettings.json
  29. 142 0
      Virtual_PLC/PlcData.cs
  30. 12 0
      Virtual_PLC/Virtual_PLC.csproj
  31. 7 0
      WCS Pedestal.sln
  32. 27 2
      WCS.Core/Configs.cs
  33. 6 3
      WCS.Core/DataTrans/DataBlock.cs
  34. 1 1
      WCS.Core/DataTrans/IPLCAccessor.cs
  35. 2 2
      WCS.Core/DataTrans/ProtocolProxyBase.cs
  36. 6 7
      WCS.Core/LogicHandler.cs
  37. 1 1
      WCS.Core/WCS.Core.csproj
  38. 1 3
      WCS.Entity/OBJ.cs
  39. 5 5
      WCS.Entity/WCS_DEVICE.cs
  40. 5 5
      WCS.Entity/WCS_PLC.cs

+ 6 - 6
DBHelper-SqlSugar/DB.cs

@@ -63,7 +63,7 @@ namespace DBHelper_SqlSugar
         /// <summary>
         /// 默认链接
         /// </summary>
-        public SqlSugarClient Default
+        public SqlSugarScope Default
         {
             get
             {
@@ -78,11 +78,11 @@ namespace DBHelper_SqlSugar
         /// </summary>
         /// <param name="type"></param>
         /// <returns></returns>
-        public static SqlSugarClient CreateContext(ConnectionConfig config, string key)
+        public static SqlSugarScope CreateContext(ConnectionConfig config, string key)
         {
             var ctx = _contexts.FirstOrDefault(v => v.Key == key);
             if (ctx != null) return ctx.Client;
-            ctx = new ContextList(key, new SqlSugarClient(new ConnectionConfig()
+            ctx = new ContextList(key, new SqlSugarScope(new ConnectionConfig()
             {
                 ConnectionString = config.ConnectionString,
                 DbType = config.DbType,
@@ -93,7 +93,7 @@ namespace DBHelper_SqlSugar
             return ctx.Client;
         }
 
-        public SqlSugarClient Context(string key)
+        public SqlSugarScope Context(string key)
         {
             var ctx = _contexts.FirstOrDefault(v => v.Key == key);
             if (ctx == null) throw new Exception("没有对应的链接,请先调用创建");
@@ -107,7 +107,7 @@ namespace DBHelper_SqlSugar
     public class ContextList
 
     {
-        public ContextList(string key, SqlSugarClient client, ConnectionConfig connectionConfig)
+        public ContextList(string key, SqlSugarScope client, ConnectionConfig connectionConfig)
         {
             this.Key = key;
             Client = client;
@@ -116,7 +116,7 @@ namespace DBHelper_SqlSugar
 
         public string Key { get; set; }
 
-        public SqlSugarClient Client { get; set; }
+        public SqlSugarScope Client { get; set; }
 
         public ConnectionConfig ConnectionConfig { get; set; }
     }

BIN
DLL/PLC.Siemens.dll


+ 28 - 5
Projects/永冠OPP/WCS.Entity.Protocol/RGV/WCS_RGV521.cs

@@ -1,4 +1,5 @@
-using System.Runtime.Serialization;
+using SqlSugar;
+using System.Runtime.Serialization;
 using WCS.Entity.Protocol.RGV;
 
 namespace WCS.Entity.Protocol
@@ -6,82 +7,104 @@ namespace WCS.Entity.Protocol
     /// <summary>
     /// RGV 读取协议 后缀 _1=1工位 _2=2工位 无=共用
     /// </summary>
+    [SugarTable(nameof(WCS_RGV521), "RGV 读取协议 后缀 _1=1工位 _2=2工位 无=共用")]
     [DataContract]
     public class WCS_RGV521 : WCS_PROTOCOLDATA, IRGV521
     {
+        [SugarColumn(ColumnDescription = "任务号")]
         [DataMember(Order = 0)]
         public int TaskID_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "任务类型")]
         [DataMember(Order = 1)]
         public RGVTaskType TaskType_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始站台")]
         [DataMember(Order = 2)]
         public short StartPosition_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标站台")]
         [DataMember(Order = 3)]
         public short DestPosition_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "优先级")]
         [DataMember(Order = 4)]
         public short PRIORITY_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用1")]
         [DataMember(Order = 5)]
         public short RES1_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用2")]
         [DataMember(Order = 6)]
         public short RES2_1 { get; set; }
 
-        /// <summary>
-        ///
-        /// </summary>
+        [SugarColumn(ColumnDescription = "状态")]
         [DataMember(Order = 7)]
         public RGVStatus Status_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "凭证号")]
         [DataMember(Order = 8)]
         public int Trigger_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "任务号")]
         [DataMember(Order = 9)]
         public int TaskID_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "任务类型")]
         [DataMember(Order = 10)]
         public RGVTaskType TaskType_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始站点")]
         [DataMember(Order = 11)]
         public short StartPosition_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标站点")]
         [DataMember(Order = 12)]
         public short DestPosition_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "优先级")]
         [DataMember(Order = 13)]
         public short PRIORITY_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用1")]
         [DataMember(Order = 14)]
         public short RES1_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用2")]
         [DataMember(Order = 15)]
         public short RES2_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "状态")]
         [DataMember(Order = 16)]
         public RGVStatus Status_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "凭证号")]
         [DataMember(Order = 17)]
         public int Trigger_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "运行状态")]
         [DataMember(Order = 18)]
         public RGVRunStatus SystemStatus { get; set; }
 
+        [SugarColumn(ColumnDescription = "运行模式")]
         [DataMember(Order = 19)]
         public RGVMode WorkMode { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用6")]
         [DataMember(Order = 20)]
         public short RES6 { get; set; }
 
+        [SugarColumn(ColumnDescription = "位置")]
         [DataMember(Order = 21)]
         public float Position { get; set; }
 
+        [SugarColumn(ColumnDescription = "里程")]
         [DataMember(Order = 22)]
         public float Mileage { get; set; }
 
+        [SugarColumn(ColumnDescription = "运行时长")]
         [DataMember(Order = 23)]
         public float Runtime { get; set; }
     }
-}
+}

+ 10 - 2
Projects/永冠OPP/WCS.Entity.Protocol/RGV/WCS_RGV523.cs

@@ -1,4 +1,5 @@
-using System.Runtime.Serialization;
+using SqlSugar;
+using System.Runtime.Serialization;
 using WCS.Entity.Protocol.RGV;
 
 namespace WCS.Entity.Protocol
@@ -6,25 +7,32 @@ namespace WCS.Entity.Protocol
     /// <summary>
     /// RGV状态记录
     /// </summary>
+    [SugarTable(nameof(WCS_RGV523), "RGV状态记录")]
     [DataContract]
     public class WCS_RGV523 : WCS_PROTOCOLDATA, IRGV523
     {
+        [SugarColumn(ColumnDescription = "环形穿梭车故障")]
         [DataMember(Order = 0)]
         public RGVFault Fault { get; set; }
 
+        [SugarColumn(ColumnDescription = "工位1故障")]
         [DataMember(Order = 1)]
         public RGVPlatformFault Fault1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "工位2故障")]
         [DataMember(Order = 2)]
         public RGVPlatformFault Fault2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "环穿状态")]
         [DataMember(Order = 3)]
         public RGVStatus Status { get; set; }
 
+        [SugarColumn(ColumnDescription = "工位1状态")]
         [DataMember(Order = 4)]
         public RGVPlatformStatus Status1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "工位2状态")]
         [DataMember(Order = 5)]
         public RGVPlatformStatus Status2 { get; set; }
     }
-}
+}

+ 1 - 1
Projects/永冠OPP/WCS.Entity.Protocol/SRM/ISRM521.cs

@@ -317,7 +317,7 @@ namespace WCS.Entity.Protocol
         SCMode SRMMode { get; set; }
 
         /// <summary>
-        /// 堆垛机模式
+        /// 堆垛机状态
         /// </summary>
         SCRunStatus SRMStatus { get; set; }
 

+ 40 - 2
Projects/永冠OPP/WCS.Entity.Protocol/SRM/WCS_SRM520.cs

@@ -1,4 +1,5 @@
-using System.Runtime.Serialization;
+using SqlSugar;
+using System.Runtime.Serialization;
 using WCS.Entity.Protocol.SRM;
 
 namespace WCS.Entity.Protocol
@@ -6,115 +7,152 @@ namespace WCS.Entity.Protocol
     /// <summary>
     /// 堆垛机协议,WCS写入
     /// </summary>
+    [SugarTable(nameof(WCS_SRM520), "堆垛机协议,WCS写入")]
     [DataContract]
     public class WCS_SRM520 : WCS_PROTOCOLDATA, ISRM520
     {
+        [SugarColumn(ColumnDescription = "WCS心跳信号")]
         [DataMember(Order = 0)]
         public short Handshake_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "货物数量")]
         [DataMember(Order = 1)]
         public short RES1_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用")]
         [DataMember(Order = 2)]
         public short RES2_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "货物类型")]
         [DataMember(Order = 3)]
         public short GoodsType_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "速度")]
         [DataMember(Order = 4)]
         public SCSpeedMode SpeedMode_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始行")]
         [DataMember(Order = 5)]
         public short SLine_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始列")]
         [DataMember(Order = 6)]
         public short SCol_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始层")]
         [DataMember(Order = 7)]
         public short SLayer_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始深度")]
         [DataMember(Order = 8)]
         public short SDepth_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标行")]
         [DataMember(Order = 9)]
         public short ELine_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标列")]
         [DataMember(Order = 10)]
         public short ECol_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标层")]
         [DataMember(Order = 11)]
         public short ELayer_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标深度")]
         [DataMember(Order = 12)]
         public short EDepth_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "任务号")]
         [DataMember(Order = 13)]
         public int TaskID_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "触发")]
         [DataMember(Order = 14)]
         public short VoucherNo_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "完成任务触发")]
         [DataMember(Order = 15)]
         public short FinishedACK_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用3")]
         [DataMember(Order = 16)]
         public short RES3_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用4")]
         [DataMember(Order = 17)]
         public short RES4_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "WCS心跳信号")]
         [DataMember(Order = 18)]
         public short Handshake_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "货物数量")]
         [DataMember(Order = 19)]
         public short RES1_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用2")]
         [DataMember(Order = 20)]
         public short RES2_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "货物类型")]
         [DataMember(Order = 21)]
         public short GoodsType_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "行驶速度")]
         [DataMember(Order = 22)]
         public SCSpeedMode SCSpeedMode_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始行")]
         [DataMember(Order = 23)]
         public short SLine_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始列")]
         [DataMember(Order = 24)]
         public short SCol_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始层")]
         [DataMember(Order = 25)]
         public short SLayer_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始深度")]
         [DataMember(Order = 26)]
         public short SDepth_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标行")]
         [DataMember(Order = 27)]
         public short ELine_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标列")]
         [DataMember(Order = 28)]
         public short ECol_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标层")]
         [DataMember(Order = 29)]
         public short ELayer_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标深度")]
         [DataMember(Order = 30)]
         public short EDepth_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "任务号")]
         [DataMember(Order = 31)]
         public int TaskID_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "触发")]
         [DataMember(Order = 32)]
         public short VoucherNo_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "完成任务触发")]
         [DataMember(Order = 33)]
         public short FinishedACK_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用3")]
         [DataMember(Order = 34)]
         public short RES3_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用4")]
         [DataMember(Order = 35)]
         public short RES4_2 { get; set; }
     }
-}
+}

+ 68 - 3
Projects/永冠OPP/WCS.Entity.Protocol/SRM/WCS_SRM521.cs

@@ -1,4 +1,5 @@
-using System.Runtime.Serialization;
+using SqlSugar;
+using System.Runtime.Serialization;
 using WCS.Entity.Protocol.SRM;
 
 namespace WCS.Entity.Protocol
@@ -6,196 +7,260 @@ namespace WCS.Entity.Protocol
     /// <summary>
     /// 堆垛机协议,WCS只读
     /// </summary>
+    [SugarTable(nameof(WCS_SRM521), "堆垛机协议,WCS只读")]
     [DataContract]
     public class WCS_SRM521 : WCS_PROTOCOLDATA, ISRM521
     {
+        [SugarColumn(ColumnDescription = "货叉状态")]
         [DataMember(Order = 0)]
         public SRMForkStatus ForkStatus_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "模式")]
         [DataMember(Order = 1)]
         public SCMode Mode_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "运行状态")]
         [DataMember(Order = 2)]
         public SCRunStatus Status_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始行")]
         [DataMember(Order = 3)]
         public short SLine_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始列")]
         [DataMember(Order = 4)]
         public short SCol_1 { get; set; }
 
-        [DataMember(Order = 5)]   
+        [SugarColumn(ColumnDescription = "起始层")]
+        [DataMember(Order = 5)]
         public short SLayer_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始深度")]
         [DataMember(Order = 6)]
         public short SDepth_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标行")]
         [DataMember(Order = 7)]
         public short ELine_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标列")]
         [DataMember(Order = 8)]
         public short ECol_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标层")]
         [DataMember(Order = 9)]
         public short ELayer_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标深度")]
         [DataMember(Order = 10)]
         public short EDepth_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "任务号")]
         [DataMember(Order = 11)]
         public int TaskID_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "触发信号")]
         [DataMember(Order = 12)]
         public short VoucherNo_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "当前行")]
         [DataMember(Order = 13)]
         public short Line_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "当前列")]
         [DataMember(Order = 14)]
         public short Col_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "当前层")]
         [DataMember(Order = 15)]
         public short Layer_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "已完成任务号")]
         [DataMember(Order = 16)]
         public int FinishedTask_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "X轴位置(0.1毫米) 行走")]
         [DataMember(Order = 17)]
         public int TravelPos_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "Y轴位置 提升")]
         [DataMember(Order = 18)]
         public int LiftPos_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "Z轴位置 货叉")]
         [DataMember(Order = 19)]
         public int ForkPos_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用 PLCname=Start_number1")]
         [DataMember(Order = 20)]
         public short RES9_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用 PLCname=End_number2")]
         [DataMember(Order = 21)]
         public short RES10_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "总里程")]
         [DataMember(Order = 22)]
         public float TotalKM_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "货物类型")]
         [DataMember(Order = 23)]
         public short GoodsType_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "运行时长")]
         [DataMember(Order = 24)]
         public float Runtime_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用 PLCname=ForkPos2")]
         [DataMember(Order = 25)]
         public int RES11_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用 PLCname=Dest_Xmm")]
         [DataMember(Order = 26)]
         public int RES12_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用 PLCname=Dest_Ymm")]
         [DataMember(Order = 27)]
         public int RES13_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用 PLCname=Dest_Zmm")]
         [DataMember(Order = 28)]
         public int RES14_1 { get; set; }
 
+        [SugarColumn(ColumnDescription = "货叉状态")]
         [DataMember(Order = 29)]
         public SRMForkStatus ForkStatus_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "模式")]
         [DataMember(Order = 30)]
         public SCMode Mode_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "运行状态")]
         [DataMember(Order = 31)]
         public SCRunStatus Status_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始行")]
         [DataMember(Order = 32)]
         public short SLine_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始列")]
         [DataMember(Order = 33)]
         public short SCol_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始层")]
         [DataMember(Order = 34)]
         public short SLayer_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始深度")]
         [DataMember(Order = 35)]
         public short SDepth_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标行")]
         [DataMember(Order = 36)]
         public short ELine_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标列")]
         [DataMember(Order = 37)]
         public short ECol_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标层")]
         [DataMember(Order = 38)]
         public short ELayer_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标深度")]
         [DataMember(Order = 39)]
         public short EDepth_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "任务号")]
         [DataMember(Order = 40)]
         public int TaskID_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "触发信号")]
         [DataMember(Order = 41)]
         public short VoucherNo_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "当前行")]
         [DataMember(Order = 42)]
         public short Line_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "当前列")]
         [DataMember(Order = 43)]
         public short Col_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "当前层")]
         [DataMember(Order = 44)]
         public short Layer_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "已完成任务号")]
         [DataMember(Order = 45)]
         public int FinishedTask_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "X轴位置(0.1毫米) 行走")]
         [DataMember(Order = 46)]
         public int TravelPos_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "Y轴位置 提升")]
         [DataMember(Order = 47)]
         public int LiftPos_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "Z轴位置 货叉")]
         [DataMember(Order = 48)]
         public int ForkPos_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用 PLCname=Start_number1")]
         [DataMember(Order = 49)]
         public short RES9_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用 PLCname=End_number2")]
         [DataMember(Order = 50)]
         public short RES10_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "总里程")]
         [DataMember(Order = 51)]
         public float TotalKM_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "货物类型")]
         [DataMember(Order = 52)]
         public short GoodsType_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "运行时长")]
         [DataMember(Order = 53)]
         public float Runtime_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用 PLCname=ForkPos2")]
         [DataMember(Order = 54)]
         public int RES11_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用 PLCname=Dest_Xmm")]
         [DataMember(Order = 55)]
         public int RES12_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用 PLCname=Dest_Ymm")]
         [DataMember(Order = 56)]
         public int RES13_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用 PLCname=Dest_Zmm")]
         [DataMember(Order = 57)]
         public int RES14_2 { get; set; }
 
+        [SugarColumn(ColumnDescription = "堆垛机模式")]
         [DataMember(Order = 58)]
         public SCMode SRMMode { get; set; }
 
+        [SugarColumn(ColumnDescription = "堆垛机状态")]
         [DataMember(Order = 59)]
         public SCRunStatus SRMStatus { get; set; }
 
+        [SugarColumn(ColumnDescription = "总里程")]
         [DataMember(Order = 60)]
         public float TotalKM { get; set; }
 
+        [SugarColumn(ColumnDescription = "运行时长")]
         [DataMember(Order = 61)]
         public float Runtime { get; set; }
 
+        [SugarColumn(ColumnDescription = "堆垛机是否异常 1:异常 0:正常")]
         [DataMember(Order = 62)]
         public short Alarm { get; set; }
     }
-}
+}

+ 5 - 2
Projects/永冠OPP/WCS.Entity.Protocol/SRM/WCS_SRM537.cs

@@ -1,4 +1,5 @@
-using System.Runtime.Serialization;
+using SqlSugar;
+using System.Runtime.Serialization;
 using WCS.Entity.Protocol.SRM;
 
 namespace WCS.Entity.Protocol
@@ -6,10 +7,12 @@ namespace WCS.Entity.Protocol
     /// <summary>
     /// 堆垛机异常读取
     /// </summary>
+    [SugarTable(nameof(WCS_SRM537), "堆垛机异常读取")]
     [DataContract]
     public class WCS_SRM537 : WCS_PROTOCOLDATA, ISRM537
     {
+        [SugarColumn(ColumnDescription = "堆垛机报警")]
         [DataMember(Order = 0)]
         public SCAlarm SCAlarm { get; set; }
     }
-}
+}

+ 34 - 14
Projects/永冠OPP/WCS.Entity.Protocol/Station/WCS_Station520.cs

@@ -1,33 +1,53 @@
-using System.Runtime.Serialization;
+using SqlSugar;
+using System.Runtime.Serialization;
 
 namespace WCS.Entity.Protocol.Station
 {
     /// <summary>
-    /// 站台交互信号 写记录表 
+    /// 站台交互信号 写记录表
     /// </summary>
+    [SugarTable(nameof(WCS_Station520), "站台交互信号 写记录表")]
     [DataContract]
     public class WCS_Station520 : WCS_PROTOCOLDATA, IStation520
     {
+        [SugarColumn(ColumnDescription = "任务号")]
         [DataMember(Order = 0)]
-        public int Tasknum { get  ; set  ; }
+        public int Tasknum { get; set; }
+
+        [SugarColumn(ColumnDescription = "货物数条码 涂布入库口代表AGV任务")]
         [DataMember(Order = 1)]
-        public int Goodscode { get  ; set  ; }
+        public int Goodscode { get; set; }
+
+        [SugarColumn(ColumnDescription = "货物数量(1.两个位置放1个货物,2.两个位置放2个货物)")]
         [DataMember(Order = 2)]
-        public short Goodsnum { get  ; set  ; }
+        public short Goodsnum { get; set; }
+
+        [SugarColumn(ColumnDescription = "货物高度")]
         [DataMember(Order = 3)]
-        public short GoodsSize { get  ; set  ; }
+        public short GoodsSize { get; set; }
+
+        [SugarColumn(ColumnDescription = "起始地址")]
         [DataMember(Order = 4)]
-        public short Goodsstart { get  ; set  ; }
+        public short Goodsstart { get; set; }
+
+        [SugarColumn(ColumnDescription = "目标地址")]
         [DataMember(Order = 5)]
-        public short Goodsend { get  ; set  ; }
+        public short Goodsend { get; set; }
+
+        [SugarColumn(ColumnDescription = "请求")]
         [DataMember(Order = 6)]
-        public IstationRequest Request { get  ; set  ; }
+        public IstationRequest Request { get; set; }
+
+        [SugarColumn(ColumnDescription = "命令类型")]
         [DataMember(Order = 7)]
-        public IstationCmdType CmdType { get  ; set  ; }
+        public IstationCmdType CmdType { get; set; }
+
+        [SugarColumn(ColumnDescription = "凭证号 每次累加")]
         [DataMember(Order = 8)]
-        public short VoucherNo { get  ; set  ; }
+        public short VoucherNo { get; set; }
+
+        [SugarColumn(ColumnDescription = "输送机状态")]
         [DataMember(Order = 9)]
-        public IstationStatus Istation521Status { get  ; set  ; }
-       
+        public IstationStatus Istation521Status { get; set; }
     }
-}
+}

+ 13 - 2
Projects/永冠OPP/WCS.Entity.Protocol/Station/WCS_Station521.cs

@@ -1,39 +1,50 @@
-using System.ComponentModel;
+using SqlSugar;
 using System.Runtime.Serialization;
 
 namespace WCS.Entity.Protocol.Station
 {
+    [SugarTable(nameof(WCS_Station521), "输送机交互信号 读记录表")]
     [DataContract]
     public class WCS_Station521 : WCS_PROTOCOLDATA, IStation521
     {
+        [SugarColumn(ColumnDescription = "任务号")]
         [DataMember(Order = 0)]
         public int Tasknum { get; set; }
 
+        [SugarColumn(ColumnDescription = "货物数条码 涂布入库扫码位是AGV任务号")]
         [DataMember(Order = 1)]
         public int Goodscode { get; set; }
 
+        [SugarColumn(ColumnDescription = "货物数量(1.两个位置放1个货物,2.两个位置放2个货物)")]
         [DataMember(Order = 2)]
         public short Goodsnum { get; set; }
 
+        [SugarColumn(ColumnDescription = "货物高度")]
         [DataMember(Order = 3)]
         public short GoodsSize { get; set; }
 
+        [SugarColumn(ColumnDescription = "起始地址")]
         [DataMember(Order = 4)]
         public short Goodsstart { get; set; }
 
+        [SugarColumn(ColumnDescription = "目标地址")]
         [DataMember(Order = 5)]
         public short Goodsend { get; set; }
 
+        [SugarColumn(ColumnDescription = "请求")]
         [DataMember(Order = 6)]
         public IstationRequest Request { get; set; }
 
+        [SugarColumn(ColumnDescription = "命令类型")]
         [DataMember(Order = 7)]
         public IstationCmdType CmdType { get; set; }
 
+        [SugarColumn(ColumnDescription = "凭证号 每次累加")]
         [DataMember(Order = 8)]
         public short VoucherNo { get; set; }
 
+        [SugarColumn(ColumnDescription = "输送机状态")]
         [DataMember(Order = 9)]
         public IstationStatus Status { get; set; }
     }
-}
+}

+ 8 - 2
Projects/永冠OPP/WCS.Entity.Protocol/Station/WCS_Station523.cs

@@ -1,23 +1,29 @@
-using System.Runtime.Serialization;
+using SqlSugar;
+using System.Runtime.Serialization;
 
 namespace WCS.Entity.Protocol.Station
 {
     /// <summary>
     /// 站台状态读取记录表
     /// </summary>
+    [SugarTable(nameof(WCS_Station523), "站台状态读取记录表")]
     [DataContract]
     public class WCS_Station523 : WCS_PROTOCOLDATA, IStation523
     {
+        [SugarColumn(ColumnDescription = "警报")]
         [DataMember(Order = 0)]
         public StationFault Alarm { get; set; }
 
+        [SugarColumn(ColumnDescription = "备用")]
         [DataMember(Order = 1)]
         public short RES { get; set; }
 
+        [SugarColumn(ColumnDescription = "允许状态 值为零时是手动")]
         [DataMember(Order = 2)]
         public StationStatus Status { get; set; }
 
+        [SugarColumn(ColumnDescription = "运行时间")]
         [DataMember(Order = 3)]
         public float RunTime { get; set; }
     }
-}
+}

+ 57 - 1
Projects/永冠OPP/WCS.Service/Extensions/TypeExtension.cs

@@ -1,4 +1,8 @@
-using System;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
 
 namespace WCS.Service.Extensions
 {
@@ -63,5 +67,57 @@ namespace WCS.Service.Extensions
         {
             return value.Replace("G", "").ToShort();
         }
+
+        /// <summary>
+        /// 数据映射
+        /// </summary>
+        /// <typeparam name="D"></typeparam>
+        /// <typeparam name="S"></typeparam>
+        /// <param name="s"></param>
+        /// <returns></returns>
+        public static D Mapper<D, S>(S s)
+        {
+            D d = Activator.CreateInstance<D>();
+
+            var sType = s.GetType();
+            var dType = typeof(D);
+            foreach (PropertyInfo sP in sType.GetProperties())
+            {
+                foreach (PropertyInfo dP in dType.GetProperties())
+                {
+                    if (dP.Name == sP.Name)
+                    {
+                        dP.SetValue(d, sP.GetValue(s));
+                        break;
+                    }
+                }
+            }
+            return d;
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <typeparam name="T1"></typeparam>
+        /// <typeparam name="T2"></typeparam>
+        /// <typeparam name="T3"></typeparam>
+        /// <param name="t3"></param>
+        /// <returns></returns>
+        public static Dictionary<string, object> EntityClassToDictionary<T>(T t)
+        {
+            Type type = typeof(SugarColumn);
+            Dictionary<string, object> d = new Dictionary<string, object>();
+
+            var sType = t.GetType();
+            foreach (PropertyInfo sP in sType.GetProperties())
+            {
+                if (sP.CustomAttributes.Any(v => v.AttributeType == type) && sP.Name != "VER" && sP.Name != "ID")
+                {
+                    d.Add(sP.Name, sP.GetValue(t));
+                }
+            }
+
+            return d;
+        }
     }
 }

+ 13 - 12
Projects/永冠OPP/WCS.Service/Handlers/DataClearHandler.cs

@@ -1,8 +1,10 @@
 using DBHelper_SqlSugar;
+using SqlSugar;
 using System;
 using System.ComponentModel;
 using WCS.Core;
 using WCS.Entity;
+using WCS.Service.Extensions;
 
 namespace WCS.Service
 {
@@ -22,7 +24,8 @@ namespace WCS.Service
             last = DateTime.Now;
             Db.Do(db =>
             {
-                db.Default.Ado.UseStoredProcedure().ExecuteCommand("delete WCS_EXCEPTION where datediff(dd, UPDATETIME, getdate()) > 7");
+                db.Default.Deleteable<WCS_EXCEPTION>().Where(v => SqlFunc.DateDiff(DateType.Day, v.UPDATETIME, SqlFunc.GetDate()) > 7).AddQueue();
+                //db.Default.Ado.UseStoredProcedure().ExecuteCommand("DELETE FROM wcs_exception WHERE TIMESTAMPDIFF(DAY,UPDATETIME,NOW()) > 7");
 
                 var ps = db.Default.GetType().GetProperties();
                 foreach (var p in ps)
@@ -32,21 +35,19 @@ namespace WCS.Service
                     var tType = p.PropertyType.GenericTypeArguments[0];
                     if (!tType.IsSubclassOf(typeof(WCS_PROTOCOLDATA)))
                         continue;
-                    var sSql = $"Delete {tType.Name} where datediff(dd,Frame,getdate())>7";
+                    var sSql = $"Delete FROM {tType.Name} where TIMESTAMPDIFF(DAY,Frame,NOW())>7";
                     db.Default.Ado.UseStoredProcedure().ExecuteCommand(sSql);
                     DBHelper.DbLog.DB_CLEAN(sSql);
                 }
+                var taskList = db.Default.Queryable<WCS_TASK>().Where(v => SqlFunc.DateDiff(DateType.Day, v.UPDATETIME, SqlFunc.GetDate()) > 3 && v.STATUS >= TaskStatus.已完成).ToList();
 
-                var copySql = @"INSERT INTO WCS_TASK_OLD (ID,BARCODE,TYPE,STATUS,ADDRFROM,ADDRTO,ADDRNEXT,TUNNEL,FLOOR,
-                                DEVICE,SRMSTATION,CREATETIME,STARTTIME,ENDTIME,DOCID,PALLETTYPE,PRODLINE,FULLQTY,HEIGHT,
-                                WMSTASK,TaskGroupKey,UPLOADED,AgvTask,Priority,ManualRemarks,ENABLED,UPDATEUSER,UPDATETIME,
-                                Length,MaterialCode) SELECT
-                                ID,BARCODE,TYPE,STATUS,ADDRFROM,ADDRTO,ADDRNEXT,TUNNEL,FLOOR,DEVICE,SRMSTATION,CREATETIME,
-                                STARTTIME,ENDTIME,DOCID,PALLETTYPE,PRODLINE,FULLQTY,HEIGHT,WMSTASK,TaskGroupKey,UPLOADED,AgvTask,
-                                Priority,ManualRemarks,ENABLED,UPDATEUSER,UPDATETIME,Length,MaterialCode FROM WCS_TASK WHERE STATUS >=99 AND UPDATETIME < DATEADD(DAY, -3, GETDATE())";
-                db.Default.Ado.UseStoredProcedure().ExecuteCommand(copySql);
-                var clearSql = "DELETE FROM WCS_TASK WHERE STATUS >=99 AND UPDATETIME < DATEADD(DAY, -3, GETDATE())";
-                db.Default.Ado.UseStoredProcedure().ExecuteCommand(clearSql);
+                foreach (var task in taskList)
+                {
+                    var taskOld = TypeExtension.Mapper<WCS_TASK_OLD, WCS_TASK>(task);
+                    db.Default.Insertable(taskOld).AddQueue();
+                    db.Default.Deleteable(task).AddQueue();
+                }
+                db.Default.SaveQueues();
             });
         }
     }

+ 1 - 1
Projects/永冠OPP/WCS.Service/Handlers/WorkHandler.cs

@@ -30,6 +30,7 @@ namespace WCS.Service.Handlers
                         return false;
                     return attr.Handler == this.GetType();
                 });
+            //TODO:加一层关于仓库的管控,通过
             var works = arr.Select(v => Activator.CreateInstance(v) as Work).Select(v =>
             {
                 var attr = v.GetType().GetCustomAttribute<WorkTitleAttribute>();
@@ -119,7 +120,6 @@ namespace WCS.Service.Handlers
                 {
                     Ltc.Log(ex.GetBaseException().Message);
                 }
-
                 if (ex.REPORTWMS)
                 {
                     Configs.UploadException?.Invoke(p.ToString(), ex.GetBaseException().Message);

+ 21 - 8
Projects/永冠OPP/WCS.Service/PLCAccessors/SiemensS7PLC.cs

@@ -1,9 +1,11 @@
 using HslCommunication.Profinet.Siemens;
-using System;
+using Virtual_PLC;
+using WCS.Core;
+using WCS.Core.DataTrans;
 
 namespace WCS.Service.PLCAccessors
 {
-    public class SiemensS7PLC : SiemensS7Net
+    public class SiemensS7PLC : SiemensS7Net, IPlcAccessor
     {
         private SiemensS7Net plc;
 
@@ -21,21 +23,32 @@ namespace WCS.Service.PLCAccessors
             plc = new SiemensS7Net((SiemensPLCS)type, ip);
         }
 
-        public byte[] ReadBytes(ushort db, ushort address, ushort length)
+        public byte[] ReadBytes(ushort db, ushort address, ushort length, ushort dataLength)
         {
+            if (Configs.Any(SystemMode.虚拟PLC))
+            {
+                return PlcData.Read(new PLCData { IP = plc.IpAddress, DB = db, Length = length, DataLength = dataLength });
+            }
+
             var addr = "DB" + db + "." + address;
             var res = plc.Read(addr, length);
             if (res.IsSuccess)
                 return res.Content;
-            throw new Exception("读取PLC数据失败:" + res.Message);
+            throw new WarnException("读取PLC数据失败:" + res.Message);
         }
 
         public void WriteBytes(ushort db, ushort address, byte[] data)
         {
-            var start = db + address / 2;
-            var res = plc.Write("D" + start, data);
-            if (!res.IsSuccess)
-                throw new Exception("写入PLC数据失败:" + res.Message);
+            if (Configs.Any(SystemMode.虚拟PLC))
+            {
+                PlcData.Write(new PLCData { IP = plc.IpAddress, DB = db }, address, data);
+            }
+            else
+            {
+                var res = plc.Write("D" + address, data);
+                if (!res.IsSuccess)
+                    throw new WarnException("写入PLC数据失败:" + res.Message);
+            }
         }
     }
 }

+ 2 - 0
Projects/永冠OPP/WCS.Service/Program.cs

@@ -5,6 +5,7 @@ using System;
 using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading.Tasks;
+using WCS.Core;
 
 namespace WCS.Service
 {
@@ -19,6 +20,7 @@ namespace WCS.Service
             using var mt = new Mutex(true, "WCS");
             if (mt.WaitOne())
             {
+                Configs.AddSystemMode(SystemMode.ÐéÄâPLC);
                 CreateHostBuilder(args).Build().Run(); mt.ReleaseMutex();
             }
             else

+ 15 - 31
Projects/永冠OPP/WCS.Service/ProtocolProxy.cs

@@ -2,6 +2,7 @@
 using FreeRedis;
 using MessagePack;
 using MessagePack.Resolvers;
+using SqlSugar;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
@@ -13,7 +14,7 @@ using WCS.Core;
 using WCS.Core.DataTrans;
 using WCS.Entity;
 using WCS.Entity.Protocol;
-using DbContext = Microsoft.EntityFrameworkCore.DbContext;
+using WCS.Service.Extensions;
 
 namespace WCS.Service
 {
@@ -23,7 +24,7 @@ namespace WCS.Service
 
         public ProtocolProxy(string id, WCS_DATABLOCK db, ushort start, WCS_DEVICEPROTOCOL protocol) : base(id, db, start, protocol)
         {
-            _setMethod = typeof(DbContext).GetMethod("Set", new Type[] { })?.MakeGenericMethod(this.ProtocolDataType);
+            _setMethod = typeof(SqlSugarScope).GetMethod("Queryable", new Type[] { })?.MakeGenericMethod(this.ProtocolDataType);
         }
 
         private static readonly ConcurrentDictionary<Type, object[]> LastDatas = new();
@@ -32,19 +33,14 @@ namespace WCS.Service
         {
             if (!LastDatas.ContainsKey(this.ProtocolDataType))
             {
-                dynamic q = _setMethod.Invoke(db.Default, null);
-                q = DynamicQueryableExtensions.Where(q, "ISLAST==@0", true);
-                q = DynamicQueryableExtensions.OrderBy(q, "ID");
-                q = DynamicQueryableExtensions.Select(q, "new(it.DEVICE.CODE as Code,it as Data)");
-                var arr = Enumerable.ToArray(q);
-                LastDatas[this.ProtocolDataType] = arr;
+                LastDatas[this.ProtocolDataType] = db.Default.Queryable<dynamic>().AS($"{this.ProtocolDataType.Name}", "it").Where("ISLAST=0").OrderBy("ID").ToArray();
             }
             dynamic datas = LastDatas[this.ProtocolDataType];
             var list = new List<WCS_PROTOCOLDATA>();
             foreach (var data in datas)
             {
-                if (data.Code == Protocol.DEVICE.CODE)
-                    list.Add(data.Data);
+                if (data.DEVICECOD == Protocol.DEVICE.CODE)
+                    list.Add(data);
             }
 
             if (list.Count > 1)
@@ -68,18 +64,21 @@ namespace WCS.Service
 
             if (last != null)
             {
-                db.Default.Insertable((object)last).ExecuteCommand();
+                var dc = TypeExtension.EntityClassToDictionary((object)last);
+                db.Default.Insertable(dc).AS($"{last.GetType().Name}").ExecuteCommand();
                 last.ISLAST = false;
             }
 
-            db.Default.Storageable(Protocol.DEVICE).ExecuteCommand();
-
-            newobj.DEVICE = Protocol.DEVICE;
+            var a = db.Default.Storageable(Protocol.DEVICE).ExecuteCommand();
+            newobj.DEVICECOD = Protocol.DEVICE.CODE;
             newobj.ISLAST = true;
             newobj.UPDATETIME = DateTime.Now;
             newobj.UPDATEUSER = user;
             newobj.FRAME = LogicHandler.Frame;
-            db.Default.Insertable((object)newobj).ExecuteCommand();
+            var typeName = newobj.GetType().Name;
+
+            var dc1 = TypeExtension.EntityClassToDictionary((object)newobj);
+            db.Default.Insertable(dc1).AS($"{typeName}").ExecuteCommand();
             return newobj;
         }
 
@@ -91,7 +90,7 @@ namespace WCS.Service
         static ProtocolProxy()
         {
             MessagePackSerializer.DefaultOptions = StandardResolver.Options.WithCompression(MessagePackCompression.Lz4Block);
-            Redis = new RedisClient("212.64.66.35,database=10");
+            Redis = new RedisClient("127.0.0.1,database=10");
             Redis.Serialize = obj =>
             {
                 var bytes = MessagePackSerializer.Serialize(obj);
@@ -102,23 +101,8 @@ namespace WCS.Service
                 var obj = MessagePackSerializer.Deserialize(type, bytes);
                 return obj;
             };
-
-            Yg150Redis = new RedisClient("192.168.249.150,password=123456,database=1");
-            Ygwms150Redis = new RedisClient("192.168.249.150,password=123456,database=0");
-            Ygwcs150Redis = new RedisClient("192.168.249.150,password=123456,database=10");
-            Ygwcs150Redis.Serialize = obj =>
-            {
-                var bytes = MessagePackSerializer.Serialize(obj);
-                return bytes;
-            };
-            Ygwcs150Redis.DeserializeRaw = (bytes, type) =>
-            {
-                var obj = MessagePackSerializer.Deserialize(type, bytes);
-                return obj;
-            };
         }
 
-        //static ConcurrentDictionary<string, DeviceData> Datas = new ConcurrentDictionary<string, DeviceData>();
         public override void Publish(string code, WCS_PROTOCOLDATA obj)
         {
             try

+ 4 - 1
Projects/永冠OPP/WCS.Service/WCS.Service.csproj

@@ -38,13 +38,16 @@
     <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
     <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.6" />
     <PackageReference Include="Swashbuckle.AspNetCore" Version="6.3.1" />
-    <PackageReference Include="WCS.Core" Version="1.0.0.3" />
   </ItemGroup>
 
   <ItemGroup>
     <ProjectReference Include="..\..\..\DBHelper-SqlSugar\DBHelper-SqlSugar.csproj" />
     <ProjectReference Include="..\..\..\Logs\Logs.csproj" />
+    <ProjectReference Include="..\..\..\Virtual_PLC\Virtual_PLC.csproj" />
+    <ProjectReference Include="..\..\..\WCS.Core\WCS.Core.csproj" />
     <ProjectReference Include="..\..\..\WCS.Entity\WCS.Entity.csproj" />
     <ProjectReference Include="..\WCS.Entity.Protocol\WCS.Entity.Protocol.csproj" />
   </ItemGroup>
+
+  <ProjectExtensions><VisualStudio><UserProperties appsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
 </Project>

+ 1 - 0
Projects/永冠OPP/WCS.Service/WebApi/WMS/WMS.cs

@@ -241,6 +241,7 @@ namespace WCS.Service
 
         public static void UploadDevInfo()
         {
+            return;
             try
             {
                 var res = APICaller.CallApi<I_WCS_PutDevInfoResponse>(Url + "/api/Task/I_WCS_PutDevInfo", DevInfoList);

+ 43 - 13
Projects/永冠OPP/WCS.Service/Worker.cs

@@ -6,17 +6,20 @@ using Microsoft.Extensions.Logging;
 using Newtonsoft.Json;
 using SqlSugar;
 using System;
+using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Reflection;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
+using Virtual_PLC;
 using WCS.Core;
 using WCS.Core.DataTrans;
 using WCS.Entity;
 using WCS.Entity.Protocol;
 using WCS.Entity.Protocol.BCR;
+using WCS.Entity.Protocol.Station;
 
 namespace WCS.Service
 {
@@ -49,10 +52,11 @@ namespace WCS.Service
             Configs.ProtocolProxyBaseType = typeof(ProtocolProxy);
             Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
             Configs.StringEncoding = Encoding.UTF8;
+
             Db.CreateContext(new ConnectionConfig()
             {
                 ConnectionString = AppSettings.Config.GetConnectionString("WCSDB"),
-                DbType = DbType.MySql
+                DbType = DbType.SqlServer
             }, "WCSDB");
             Db.SetDefaultDbContextType("WCSDB");
             Db.Do(db =>
@@ -78,14 +82,34 @@ namespace WCS.Service
                 db.Default.CodeFirst.InitTables(typeof(WCS_StatusLog));
                 db.Default.CodeFirst.InitTables(typeof(WCS_BCR80));
                 db.Default.CodeFirst.InitTables(typeof(WCS_RGV520));
-                //db.Default.CodeFirst.InitTables(typeof(WCS_DATABLOCK));
-                //db.Default.CodeFirst.InitTables(typeof(WCS_DATABLOCK));
-                //db.Default.CodeFirst.InitTables(typeof(WCS_DATABLOCK));
-                //db.Default.CodeFirst.InitTables(typeof(WCS_DATABLOCK));
-                //db.Default.CodeFirst.InitTables(typeof(WCS_DATABLOCK));
-                //db.Default.CodeFirst.InitTables(typeof(WCS_DATABLOCK));
+                db.Default.CodeFirst.InitTables(typeof(WCS_RGV521));
+                db.Default.CodeFirst.InitTables(typeof(WCS_RGV523));
+                db.Default.CodeFirst.InitTables(typeof(WCS_SRM520));
+                db.Default.CodeFirst.InitTables(typeof(WCS_SRM521));
+                db.Default.CodeFirst.InitTables(typeof(WCS_SRM537));
+                db.Default.CodeFirst.InitTables(typeof(WCS_Station520));
+                db.Default.CodeFirst.InitTables(typeof(WCS_Station521));
+                db.Default.CodeFirst.InitTables(typeof(WCS_Station523));
+            });
+
+            //从现有结构解析出需要的结构
+            List<PLCData> list = new List<PLCData>();
+            Db.Do(db =>
+            {
+                var dataBlocks = db.Default.Queryable<WCS_DATABLOCK>().Includes(v => v.PLC).ToList();
+                foreach (var dataBlock in dataBlocks)
+                {
+                    list.Add(new PLCData()
+                    {
+                        IP = dataBlock.PLC.IP,
+                        DB = dataBlock.NO,
+                        Length = dataBlock.LENGTH,
+                        DataLength = dataBlock.DATALENGTH,
+                    });
+                }
             });
 
+            PlcData.Init("127.0.0.1,database=0").InitPlcData(list);
             //日志发布事件s
             Configs.PublishEvent += () =>
             {
@@ -95,8 +119,7 @@ namespace WCS.Service
             //异常上抛
             Configs.UploadException = (d, s) =>
             {
-                if (s == "接口调用中")
-                    return;
+                if (s == "接口调用中") return;
                 if (ProtocolProxy.AllDatas.ContainsKey(d))
                 {
                     ProtocolProxy.AllDatas[d].Info = s;
@@ -113,18 +136,25 @@ namespace WCS.Service
                 Db.Do(db =>
                 {
                     var items = db.Default.Queryable<WCS_DEVICEPROTOCOL>()
-                   .Includes(v => v.DEVICE.ROUTES)
-                   .Includes(v => v.DEVICE.PATHS)
-                   .Includes(v => v.DB.PLC).ToArray();
+                    .Includes(d => d.DEVICE, r => r.ROUTES)
+                    .Includes(d => d.DEVICE, p => p.PATHS)
+                    .Includes(d => d.DB, p => p.PLC).ToArray();
                     items.Select(v => v.Data()).ToArray();
                     LogicHandler.AllObjects.AddRange(items);
 
-                    var devices = db.Default.Queryable<WCS_DEVICE>().Includes(v => v.ROUTES).Includes(v => v.PATHS).Includes(v => v.DEVICEGROUP).ToArray();
+                    var devices = db.Default.Queryable<WCS_DEVICE>()
+                                            .Includes(v => v.ROUTES)
+                                            .Includes(v => v.PATHS)
+                                            .Includes(v => v.DEVICEGROUP)
+                                            .Includes(v => v.DEVICEPROTOCOLS, p => p.DB, c => c.PLC)
+                                            .Includes(v => v.DEVICEPROTOCOLS, p => p.DEVICE)
+                                            .ToList();
                     LogicHandler.AllObjects.AddRange(devices);
                 });
 
                 #region 设备扩展数据配置
 
+                //TODO:通过配置使用switch
                 Device.AddFlag(DF.一楼RGV放货, "G1035", "G1044", "G1053", "G1062");
                 Device.AddFlag(DF.SRM, "SRM1", "SRM2", "SRM3", "SRM4", "SRM5", "SRM6", "SRM7", "SRM8");
                 Device.AddFlag(DF.月台, "G1469", "G1561", "G1538", "G1574", "G1509");

+ 6 - 6
Projects/永冠OPP/WCS.Service/Works/RGV/RGVWorks.cs

@@ -6,11 +6,11 @@ using WCS.Service.Handlers;
 namespace WCS.Service.Works.RGV
 {
     [WorkTitle(typeof(RGVHandler), "直穿RGV")]
-    public class 直穿RGV : Work<IRGV520>
+    public class 直穿RGV : DeviceWork<Device<IRGV520, IRGV521, IRGV523>>
     {
         private const string Rgv8 = "RGV8";
 
-        protected override void Do(IRGV520 rgv)
+        protected override void Do(Device<IRGV520, IRGV521, IRGV523> rgv)
         {
         }
 
@@ -21,9 +21,9 @@ namespace WCS.Service.Works.RGV
     }
 
     [WorkTitle(typeof(RGVHandler), "涂布环穿")]
-    public class 涂布环穿 : Work<IRGV520>
+    public class 涂布环穿 : DeviceWork<Device<IRGV520, IRGV521, IRGV523>>
     {
-        protected override void Do(IRGV520 obj)
+        protected override void Do(Device<IRGV520, IRGV521, IRGV523> obj)
         {
         }
 
@@ -34,9 +34,9 @@ namespace WCS.Service.Works.RGV
     }
 
     [WorkTitle(typeof(RGVHandler), "BOPP环穿")]
-    public class BOPP环穿 : Work<IRGV520>
+    public class BOPP环穿 : DeviceWork<Device<IRGV520, IRGV521, IRGV523>>
     {
-        protected override void Do(IRGV520 obj)
+        protected override void Do(Device<IRGV520, IRGV521, IRGV523> obj)
         {
         }
 

+ 2 - 2
Projects/永冠OPP/WCS.Service/Works/SRM/SRMWork.cs

@@ -7,7 +7,7 @@ using WCS.Service.Handlers;
 namespace WCS.Service.Works.SRM
 {
     [WorkTitle(typeof(SRMHandler), "堆垛机")]
-    internal class SRMWork : Work<ISRM520>
+    internal class SRMWork : DeviceWork<Device<ISRM520, ISRM521, ISRM537>>
     {
         //月台发货需要的设备
         private ISRM520[] DockDevs;
@@ -20,7 +20,7 @@ namespace WCS.Service.Works.SRM
             }.Select(v => Device.Find(v)).SelectMany(v => v.DEVICEGROUP).Select(v => v.MEMBER.Create<ISRM520>()).ToArray();
         }
 
-        protected override void Do(ISRM520 obj)
+        protected override void Do(Device<ISRM520, ISRM521, ISRM537> obj)
         {
         }
 

+ 6 - 7
Projects/永冠OPP/WCS.Service/Works/Station/BOPP入库.cs

@@ -2,7 +2,6 @@
 using WCS.Core;
 using WCS.Entity;
 using WCS.Entity.Protocol;
-using WCS.Service.Extensions;
 using WCS.Service.Handlers;
 
 namespace WCS.Service.Works.Station
@@ -11,9 +10,9 @@ namespace WCS.Service.Works.Station
     ///BOPP扫码入库
     /// </summary>
     [WorkTitle(typeof(BOPPHandler), "BOPP扫码入库")]
-    public class BOPP扫码入库 : Work<IStation520>
+    public class BOPP扫码入库 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 
@@ -27,9 +26,9 @@ namespace WCS.Service.Works.Station
     /// BOPP巷道分配
     /// </summary>
     [WorkTitle(typeof(BOPPHandler), "BOPP巷道分配")]
-    public class BOPP巷道分配 : Work<IStation520>
+    public class BOPP巷道分配 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 
@@ -43,9 +42,9 @@ namespace WCS.Service.Works.Station
     /// 涂布入库旋转台二次分配巷道
     /// </summary>
     [WorkTitle(typeof(BOPPHandler), "BOPP入库旋转台二次分配巷道")]
-    public class BOPP入库旋转台二次分配巷道 : Work<IStation520>
+    public class BOPP入库旋转台二次分配巷道 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 

+ 11 - 8
Projects/永冠OPP/WCS.Service/Works/Station/一楼入库.cs

@@ -6,36 +6,39 @@ using WCS.Service.Handlers;
 
 namespace WCS.Service.Works.Station
 {
+    /// <summary>
+    /// 
+    /// </summary>
     [WorkTitle(typeof(ProductHandler), "扫码入库")]
-    internal class 扫码入库 : Work<IStation520>
+    internal class 扫码入库 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
         protected override bool SelectDevice(WCS_DEVICE dev)
         {
             return dev.CODE == "G1028";
         }
 
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
     }
 
     [WorkTitle(typeof(ProductHandler), "一楼分配巷道")]
-    internal class 巷道分配 : Work<IStation520>
+    internal class 巷道分配 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
         protected override bool SelectDevice(WCS_DEVICE dev)
         {
             return dev.CODE == "G1030";
         }
 
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
     }
 
     //[WorkTitle(typeof(ProductHandler), "一楼入库旋转台二次分配巷道")]
-    internal class 一楼入库旋转台二次分配巷道 : Work<IStation520>
+    internal class 一楼入库旋转台二次分配巷道 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 
@@ -48,9 +51,9 @@ namespace WCS.Service.Works.Station
     }
 
     [WorkTitle(typeof(ProductHandler), "一楼RGV放货结束分配目标地址")]
-    internal class 一楼RGV放货结束分配目标地址 : Work<IStation520>
+    internal class 一楼RGV放货结束分配目标地址 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 

+ 6 - 6
Projects/永冠OPP/WCS.Service/Works/Station/一楼出库.cs

@@ -7,9 +7,9 @@ using WCS.Service.Handlers;
 namespace WCS.Service.Works.Station
 {
     [WorkTitle(typeof(ProductHandler), "一楼出库堆垛机放货完成后分配下一个地址")]
-    public class 一楼出库 : Work<IStation520>
+    public class 一楼出库 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 
@@ -23,9 +23,9 @@ namespace WCS.Service.Works.Station
     }
 
     [WorkTitle(typeof(ProductHandler), "月台出货口完成任务")]
-    public class 月台完成任务 : Work<IStation520>
+    public class 月台完成任务 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 
@@ -38,9 +38,9 @@ namespace WCS.Service.Works.Station
     }
 
     [WorkTitle(typeof(ProductHandler), "转圈交互点分配目标地址")]
-    public class 转圈交互点分配目标地址 : Work<IStation520>
+    public class 转圈交互点分配目标地址 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 

+ 11 - 22
Projects/永冠OPP/WCS.Service/Works/Station/涂布入库.cs

@@ -1,16 +1,8 @@
-using DBHelper;
-using Microsoft.EntityFrameworkCore;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
+using System.Collections.Generic;
 using WCS.Core;
 using WCS.Entity;
 using WCS.Entity.Protocol;
-using WCS.Entity.Protocol.SRM;
-using WCS.Service.Extensions;
 using WCS.Service.Handlers;
-using WCS.Service.Helpers;
 
 namespace WCS.Service.Works.Station
 {
@@ -18,16 +10,15 @@ namespace WCS.Service.Works.Station
     /// 涂布入库AGV交互
     /// </summary>
     [WorkTitle(typeof(CoatingHandler), "涂布入库AGV交互")]
-    public class 涂布入库AGV交互 : Work<IStation520>
+    public class 涂布入库AGV交互 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
-          
         }
 
         protected override bool SelectDevice(WCS_DEVICE dev)
         {
-            return dev.CODE == "G1394" || dev.CODE == "G1386";
+            return dev.CODE == "1394" || dev.CODE == "1386";
         }
     }
 
@@ -35,11 +26,10 @@ namespace WCS.Service.Works.Station
     /// 涂布扫码入库
     /// </summary>
     [WorkTitle(typeof(CoatingHandler), "涂布入库")]
-    public class 涂布扫码入库 : Work<IStation520>
+    public class 涂布扫码入库 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
-          
         }
 
         protected override bool SelectDevice(WCS_DEVICE dev)
@@ -52,11 +42,10 @@ namespace WCS.Service.Works.Station
     /// 涂布入库分配巷道
     /// </summary>
     [WorkTitle(typeof(CoatingHandler), "涂布入库分配巷道")]
-    public class 涂布入库分配巷道 : Work<IStation520>
+    public class 涂布入库分配巷道 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
-           
         }
 
         protected override bool SelectDevice(WCS_DEVICE dev)
@@ -69,11 +58,11 @@ namespace WCS.Service.Works.Station
     /// 涂布入库旋转台二次分配巷道
     /// </summary>
     [WorkTitle(typeof(CoatingHandler), "涂布入库旋转台二次分配巷道")]
-    public class 涂布入库旋转台二次分配巷道 : Work<IStation520>
+    public class 涂布入库旋转台二次分配巷道 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
-            
+
         }
 
         protected override bool SelectDevice(WCS_DEVICE dev)

+ 10 - 10
Projects/永冠OPP/WCS.Service/Works/Station/涂布出库.cs

@@ -11,9 +11,9 @@ namespace WCS.Service.Works.Station
     /// 涂布堆垛机放货分配目标地址
     /// </summary>
     [WorkTitle(typeof(CoatingHandler), "涂布堆垛机放货分配目标地址")]
-    public class 涂布堆垛机放货分配目标地址 : Work<IStation520>
+    public class 涂布堆垛机放货分配目标地址 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 
@@ -29,9 +29,9 @@ namespace WCS.Service.Works.Station
     /// 涂布出库分配出库口
     /// </summary>
     [WorkTitle(typeof(CoatingHandler), "涂布出库分配出库口")]
-    public class 涂布出库分配出库口 : Work<IStation520>
+    public class 涂布出库分配出库口 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 
@@ -47,9 +47,9 @@ namespace WCS.Service.Works.Station
     /// 涂布出库分配AGV取货点
     /// </summary>
     [WorkTitle(typeof(CoatingHandler), "涂布出库分配AGV取货点")]
-    public class 涂布出库分配AGV取货点 : Work<IStation520>
+    public class 涂布出库分配AGV取货点 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 
@@ -63,9 +63,9 @@ namespace WCS.Service.Works.Station
     /// 涂布出库返回任务长度
     /// </summary>
     [WorkTitle(typeof(CoatingHandler), "涂布出库返回任务长度")]
-    public class 涂布出库返回任务长度 : Work<IStation520>
+    public class 涂布出库返回任务长度 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 
@@ -79,9 +79,9 @@ namespace WCS.Service.Works.Station
     /// 涂布叫料
     /// </summary>
     [WorkTitle(typeof(CoatingHandler), "涂布叫料")]
-    public class 涂布叫料 : Work<IStation520>
+    public class 涂布叫料 : DeviceWork<Device<IStation520, IStation521, IStation523>>
     {
-        protected override void Do(IStation520 obj)
+        protected override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
         }
 

+ 5 - 3
Projects/永冠OPP/WCS.Service/appsettings.json

@@ -9,7 +9,9 @@
   "ConnectionStrings": {
     //"WCSDB": "Data Source=192.168.251.12;User ID=sa;Password=abc.123;Initial Catalog=WCS_MW;Integrated Security=False"
     //"WCSDB": "Data Source=192.168.249.120;User ID=sa;Password=password@123$%^;Initial Catalog=WCS_MW;Integrated Security=False;"
-    "WCSDB": "server=localhost;Database=wcs;Uid=root;Pwd=123456;AllowLoadLocalInfile=true"
-    //"WMSDB": "Data Source=192.168.249.151;User ID=sa;Password=Password@123;Initial Catalog=yongguanwms_opp;Integrated Security=False;"
+    //本地数据库
+    "WCSDB": "Data Source=LAPTOP-D9OEIS1K\\SQLEXPRESS;User ID=sa;Password=7166766;Initial Catalog=wcs;Integrated Security=False;"
+    //MySql
+    //"WCSDB": "server=localhost;Database=wcs;Uid=root;Pwd=123456;AllowLoadLocalInfile=true"
   }
-}
+}

+ 142 - 0
Virtual_PLC/PlcData.cs

@@ -0,0 +1,142 @@
+using FreeRedis;
+using System.Collections.Generic;
+
+namespace Virtual_PLC
+{
+    /// <summary>
+    /// plc数据
+    /// </summary>
+    public class PlcData
+    {
+        private static RedisClient Redis { get; set; }
+
+        /// <summary>
+        /// 数据结构缓存
+        /// </summary>
+        private static List<PLCData> PLCDatas { get; set; } = new List<PLCData>();
+
+        /// <summary>
+        /// redis 链接字符串
+        /// </summary>
+        /// <param name="redisClient">Redis链接字符串</param>
+        public PlcData(string redisClient)
+        {
+            Redis = new RedisClient(redisClient);
+        }
+
+        /// <summary>
+        /// redis 链接字符串
+        /// </summary>
+        /// <param name="redisClient"></param>
+        /// <returns></returns>
+        public static PlcData Init(string redisClient)
+        {
+            return new PlcData(redisClient);
+        }
+
+        /// <summary>
+        /// 初始化PLC数据
+        /// </summary>
+        /// <param name="pLCData">一个PLC</param>
+        public void InitPlcData(PLCData pLCData)
+        {
+            if (!PLCDatas.Contains(pLCData))
+            {
+                PLCDatas.Add(pLCData);
+            }
+            //用总长度除以数据长度,再以每断数据的起始位置、IP、DB组成Key
+            var mun = pLCData.Length / pLCData.DataLength;
+            int addstart = 0;
+
+            for (int i = 0; i < mun; i++)
+            {
+                var key = $"{pLCData.IP}:{pLCData.DB}:{addstart}";
+                if (Redis.Exists(key)) continue;
+                Redis.Set(key, new byte[pLCData.DataLength]);
+                addstart = addstart + pLCData.DataLength;
+            }
+        }
+
+        /// <summary>
+        /// 初始化PLC数据
+        /// </summary>
+        /// <param name="pLCDatas">多个PLC</param>
+        public void InitPlcData(List<PLCData> pLCDatas)
+        {
+            pLCDatas.ForEach(v =>
+            {
+                InitPlcData(v);
+            });
+        }
+
+        /// <summary>
+        /// 按照DB读取
+        /// </summary>
+        /// <param name="pLCData"></param>
+        /// <returns></returns>
+        public static byte[] Read(PLCData pLCData)
+        {
+            byte[] data = new byte[pLCData.Length];
+            //用总长度除以数据长度,再以每断数据的起始位置、IP、DB组成Key
+            var mun = pLCData.Length / pLCData.DataLength;
+            int addstart = 0;
+
+            for (int i = 0; i < mun; i++)
+            {
+                var a = Redis.Get<byte[]>($"{pLCData.IP}:{pLCData.DB}:{addstart}");
+                a.CopyTo(data, addstart);
+                addstart = addstart + pLCData.DataLength;
+            }
+            return data;
+        }
+
+        /// <summary>
+        /// 按照长度读取
+        /// </summary>
+        /// <param name="pLCData"></param>
+        /// <param name="startLength">起始长度</param>
+        /// <returns></returns>
+        public static byte[] Read(PLCData pLCData, int startLength)
+        {
+            return System.Text.Encoding.Default.GetBytes(Redis.Get($"{pLCData.IP}:{pLCData.DB}:{startLength}"));
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        public static void Write(PLCData pLCData, int startLength, byte[] value)
+        {
+            var data = PLCDatas.Find(v => v.IP == pLCData.IP && v.DB == pLCData.DB);
+            var start = startLength < data.DataLength ? 0 : (data.DataLength - startLength) + startLength;
+            var bytes = System.Text.Encoding.Default.GetBytes(Redis.Get($"{pLCData.IP}:{pLCData.DB}:{start}")); //获取原有数据
+            value.CopyTo(bytes, startLength); //将变更的数据,更新到redis字节组中
+            Redis.Set($"{pLCData.IP}:{pLCData.DB}:{start}", bytes);
+        }
+    }
+
+    /// <summary>
+    /// PLC数据结构
+    /// </summary>
+    public class PLCData
+    {
+        /// <summary>
+        /// IP
+        /// </summary>
+        public string IP { get; set; }
+
+        /// <summary>
+        /// DB
+        /// </summary>
+        public int DB { get; set; }
+
+        /// <summary>
+        /// 总长度
+        /// </summary>
+        public int Length { get; set; }
+
+        /// <summary>
+        /// 数据长度
+        /// </summary>
+        public int DataLength { get; set; }
+    }
+}

+ 12 - 0
Virtual_PLC/Virtual_PLC.csproj

@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netstandard2.1</TargetFramework>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="FreeRedis" Version="0.5.9" />
+  </ItemGroup>
+
+</Project>

+ 7 - 0
WCS Pedestal.sln

@@ -34,6 +34,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DBHelper-SqlSugar", "DBHelp
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SqlSugar", "..\..\..\..\开源\Src\Asp.NetCore2\SqlSugar\SqlSugar.csproj", "{9993C299-72BF-4F5A-AEAB-F1B41DF01FBC}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Virtual_PLC", "Virtual_PLC\Virtual_PLC.csproj", "{FFE12700-0A7F-474B-8B0B-ABC209C79383}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -80,6 +82,10 @@ Global
 		{9993C299-72BF-4F5A-AEAB-F1B41DF01FBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{9993C299-72BF-4F5A-AEAB-F1B41DF01FBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{9993C299-72BF-4F5A-AEAB-F1B41DF01FBC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{FFE12700-0A7F-474B-8B0B-ABC209C79383}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{FFE12700-0A7F-474B-8B0B-ABC209C79383}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{FFE12700-0A7F-474B-8B0B-ABC209C79383}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{FFE12700-0A7F-474B-8B0B-ABC209C79383}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -96,6 +102,7 @@ Global
 		{8F6C4A79-98EA-4019-B72A-29290328185A} = {2C6BCFE4-581D-4BC8-91EC-BD9FA91B9605}
 		{A3E602C7-597C-469F-A065-BBA5901FFE2C} = {2C6BCFE4-581D-4BC8-91EC-BD9FA91B9605}
 		{9993C299-72BF-4F5A-AEAB-F1B41DF01FBC} = {2C6BCFE4-581D-4BC8-91EC-BD9FA91B9605}
+		{FFE12700-0A7F-474B-8B0B-ABC209C79383} = {2C6BCFE4-581D-4BC8-91EC-BD9FA91B9605}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {75D30B04-ADD6-4FC6-8D7E-FAD45B731BB4}

+ 27 - 2
WCS.Core/Configs.cs

@@ -7,11 +7,29 @@ namespace WCS.Core
 {
     public static class Configs
     {
+        public static Type ProtocolProxyBaseType { get; set; }
+
+        private static List<SystemMode> SystemModes { get; set; } = new List<SystemMode>();
+
         /// <summary>
-        /// 设置协议通讯代理类的基类,继承至DataObject,IBaseType
+        /// 添加一种模式
         /// </summary>
-        public static Type ProtocolProxyBaseType { get; set; }
+        /// <param name="mode"></param>
+        public static void AddSystemMode(SystemMode mode)
+        {
+            if (SystemModes.Contains(mode)) return;
+            SystemModes.Add(mode);
+        }
 
+        /// <summary>
+        /// 是否有
+        /// </summary>
+        /// <param name="mode"></param>
+        /// <returns></returns>
+        public static bool Any(SystemMode mode)
+        {
+            return SystemModes.Contains(mode);
+        }
 
         public static Encoding StringEncoding { get; set; }
 
@@ -27,6 +45,13 @@ namespace WCS.Core
         }
 
         public static Action<string, string> UploadException { get; set; }
+    }
 
+    /// <summary>
+    /// 系统模式
+    /// </summary>
+    public enum SystemMode
+    {
+        虚拟PLC = 1,
     }
 }

+ 6 - 3
WCS.Core/DataTrans/DataBlock.cs

@@ -48,7 +48,7 @@ namespace WCS.Core
                 lock (Entity.PLC)
                 {
                     sw.Start();
-                    data = Entity.PLC.Ex().Accessor.ReadBytes((ushort)Entity.NO, 0, (ushort)Entity.LENGTH);
+                    data = Entity.PLC.Ex().Accessor.ReadBytes((ushort)Entity.NO, 0, (ushort)Entity.LENGTH, (ushort)Entity.DATALENGTH);
                     sw.Stop();
                 }
 
@@ -80,7 +80,6 @@ namespace WCS.Core
 
         public PlcItem<T> Regist<T>(string objid, string name, int start, byte arrLen = 1, byte strLen = 0)
         {
-            var t = typeof(T);
             var pv = new PlcItem<T>(objid, name, this, start, arrLen, strLen);
             Values.Add(pv);
             return pv;
@@ -151,7 +150,7 @@ namespace WCS.Core
             else if (type.IsPrimitive)
             {
                 var revers = Entity.PLC.TYPE == PLCType.西门子;
-
+               
                 return ReadPrimitive(type, ref bitStart, revers);
 
                 //var revers = Entity.PLC.TYPE == PLCType.西门子;
@@ -238,6 +237,10 @@ namespace WCS.Core
             var data = ReadBytes(ref bitStart, size);
             if (reverse)
                 data = data.Reverse().ToArray();
+            if (Entity.CODE == "SRM2_521" && type == typeof(short))
+            {
+                var c = 1;
+            }
             if (type == typeof(byte))
             {
                 return data.First();

+ 1 - 1
WCS.Core/DataTrans/IPLCAccessor.cs

@@ -12,7 +12,7 @@ namespace WCS.Core.DataTrans
     {
         void WriteBytes(ushort db, ushort address, byte[] data);
 
-        byte[] ReadBytes(ushort db, ushort address, ushort length);
+        byte[] ReadBytes(ushort db, ushort address, ushort length, ushort dataLength);
     }
 
     public class PlcAccessor : EntityEx<WCS_PLC>

+ 2 - 2
WCS.Core/DataTrans/ProtocolProxyBase.cs

@@ -27,12 +27,12 @@ namespace WCS.Core.DataTrans
         /// <summary>
         /// 起始便宜量,按字节算
         /// </summary>
-        private readonly ushort _start;
+        public readonly ushort _start;
 
         /// <summary>
         /// 长度,按字节算
         /// </summary>
-        private readonly ushort _length;
+        public readonly ushort _length;
 
         public WCS_DATABLOCK Db;
 

+ 6 - 7
WCS.Core/LogicHandler.cs

@@ -2,6 +2,7 @@
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
+using System.Diagnostics;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
@@ -124,8 +125,10 @@ namespace WCS.Core
 
             while (true)
             {
-                var dd = DateTime.Now;
+                var time = new Stopwatch();
+                time.Start();
                 Frame = DateTime.Now;
+
                 Parallel.ForEach(arr, db =>
                 {
                     try
@@ -138,7 +141,7 @@ namespace WCS.Core
                         Console.WriteLine("更新" + db.NAME + "数据失败:" + ex.Message);
                     }
                 });
-                var dbTimes = (DateTime.Now - dd).TotalMilliseconds;
+                time.Stop();
 
                 var total = (DateTime.Now - _last).TotalMilliseconds;
                 var s = (int)(600 - total);
@@ -147,7 +150,7 @@ namespace WCS.Core
                 total = (DateTime.Now - _last).TotalMilliseconds;
                 Console.ForegroundColor = ConsoleColor.Blue;
                 //此处打印的logicTimes实际是上一个周期的业务处理时长
-                Console.WriteLine("------刷新DB块数据耗时:" + ((int)dbTimes).ToString().PadRight(4, ' ') + ";业务逻辑耗时:" + ((int)_logicTimes).ToString().PadRight(4, ' ') + ";周期总耗时" + ((int)total).ToString().PadRight(4, ' ') + "");
+                Console.WriteLine("------刷新DB块数据耗时:" + time.ElapsedMilliseconds + ";业务逻辑耗时:" + _logicTimes.ToString().PadRight(4, ' ') + ";周期总耗时" + ((int)total).ToString().PadRight(4, ' ') + "");
                 Console.ResetColor();
                 _last = DateTime.Now;
 
@@ -365,8 +368,4 @@ namespace WCS.Core
 
         public abstract void Execute(object obj);
     }
-
-   
-
-   
 }

+ 1 - 1
WCS.Core/WCS.Core.csproj

@@ -16,13 +16,13 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="DBHelper-SqlSugar" Version="1.0.0.1" />
     <PackageReference Include="FreeRedis" Version="0.3.5" />
     <PackageReference Include="HslCommunication" Version="6.2.2" />
     <PackageReference Include="Logs" Version="1.0.0.1" />
   </ItemGroup>
 
   <ItemGroup>
+    <ProjectReference Include="..\DBHelper-SqlSugar\DBHelper-SqlSugar.csproj" />
     <ProjectReference Include="..\WCS.Entity\WCS.Entity.csproj" />
   </ItemGroup>
 

+ 1 - 3
WCS.Entity/OBJ.cs

@@ -1,6 +1,5 @@
 using SqlSugar;
 using System;
-using System.ComponentModel.DataAnnotations;
 using System.ComponentModel.DataAnnotations.Schema;
 
 namespace WCS.Entity
@@ -45,8 +44,7 @@ namespace WCS.Entity
         /// <summary>
         /// 版本号
         /// </summary>
-        [SugarColumn(ColumnDescription = "版本号")]
-        [Timestamp]
+        [SugarColumn(ColumnDescription = "版本号", ColumnDataType = "timestamp", IsNullable = true, IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
         public byte[] VER { get; set; }
 
         /// <summary>

+ 5 - 5
WCS.Entity/WCS_DEVICE.cs

@@ -29,26 +29,26 @@ namespace WCS.Entity
         /// <summary>
         /// 设备可用协议集合
         /// </summary>
-        [Navigate(NavigateType.OneToMany, nameof(WCS_DEVICEPROTOCOL.DATABLOCKCODE))]
-        public List<WCS_DEVICEPROTOCOL> DEVICEPROTOCOLS { get; set; } = new List<WCS_DEVICEPROTOCOL>();
+        [Navigate(NavigateType.OneToMany, nameof(WCS_DEVICEPROTOCOL.DEVICECODE))]
+        public List<WCS_DEVICEPROTOCOL> DEVICEPROTOCOLS { get; set; }
 
         /// <summary>
         /// 设备可用路由集合
         /// </summary>
         [Navigate(NavigateType.OneToMany, nameof(WCS_ROUTE.DEVICECODE))]
-        public List<WCS_ROUTE> ROUTES { get; set; } = new List<WCS_ROUTE>();
+        public List<WCS_ROUTE> ROUTES { get; set; }
 
         /// <summary>
         /// 设备可用路径集合
         /// </summary>
         [Navigate(NavigateType.OneToMany, nameof(WCS_PATH.STARTCODE))]
-        public List<WCS_PATH> PATHS { get; set; } = new List<WCS_PATH>();
+        public List<WCS_PATH> PATHS { get; set; }
 
         /// <summary>
         /// 设备对应设备组信息
         /// </summary>
         [Navigate(NavigateType.OneToMany, nameof(WCS_GROUPMEMBER.GROUPCODE))]
-        public List<WCS_GROUPMEMBER> DEVICEGROUP { get; set; } = new List<WCS_GROUPMEMBER>();
+        public List<WCS_GROUPMEMBER> DEVICEGROUP { get; set; }
 
         public override string ToString()
         {

+ 5 - 5
WCS.Entity/WCS_PLC.cs

@@ -34,31 +34,31 @@ namespace WCS.Entity
         /// <summary>
         /// 端口
         /// </summary>
-        [SugarColumn(ColumnDescription = "端口", Length = 20)]
+        [SugarColumn(ColumnDescription = "端口")]
         public int PORT { get; set; } = 102;
 
         /// <summary>
         /// 插槽号
         /// </summary>
-        [SugarColumn(ColumnDescription = "插槽号", Length = 20)]
+        [SugarColumn(ColumnDescription = "插槽号")]
         public int SLOT { get; set; }
 
         /// <summary>
         /// 机架号
         /// </summary>
-        [SugarColumn(ColumnDescription = "机架号", Length = 20)]
+        [SugarColumn(ColumnDescription = "机架号")]
         public int RACK { get; set; }
 
         /// <summary>
         /// 厂商
         /// </summary>
-        [SugarColumn(ColumnDescription = "厂商", Length = 20)]
+        [SugarColumn(ColumnDescription = "厂商")]
         public PLCType TYPE { get; set; }
 
         /// <summary>
         /// 型号
         /// </summary>
-        [SugarColumn(ColumnDescription = "型号", Length = 10)]
+        [SugarColumn(ColumnDescription = "型号")]
         public PLCMODEL MODEL { get; set; }
     }