林豪 左 1 year ago
parent
commit
a66774ae50

+ 28 - 21
WCS.Core/DataBlock.cs

@@ -1,5 +1,7 @@
 using System.Collections;
+using System.Net.NetworkInformation;
 using System.Reflection;
+using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 namespace WCS.Core
@@ -14,7 +16,8 @@ namespace WCS.Core
 
         public ushort Start { get; private set; }
         public ushort Length { get; private set; }
-        private bool failed = false;
+        public World World { get; private set; }
+        public bool Failed { get; private set; }
         private byte[] Data = new byte[0];
         private int id = 0;
 
@@ -23,48 +26,51 @@ namespace WCS.Core
             return id.ToString();
         }
 
-        public DataBlock(DBInfo ent) : base(ent)
+        public DataBlock(DBInfo ent,World world) : base(ent)
         {
+            this.World= world;
             DBList.Add(this);
             id = DBList.Count;
         }
 
-        private DateTime faildTime = DateTime.MinValue;
+        DateTime faildTime = DateTime.MinValue;
 
         public void RefreshData()
         {
             var isPing = false;
             try
             {
-                if (failed && !Entity.PLCInfo.Ex().Ping)
+                var plc = Entity.PLCInfo.Ex(World);
+                if (Failed)
                 {
-                    isPing = true;
-                    throw new Exception($"网络异常IP为{Entity.PLCInfo.IP}的设备PLC无法访问");
-                }
-
+                    if (!plc.Ping)
+                    {
+                        isPing = true;
+                        throw new Exception($"网络异常IP为{Entity.PLCInfo.IP}的设备PLC无法访问");
+                    }
+                } 
                 Start = (ushort)ProxyList.Min(v => v.Info.Position);
                 var last = ProxyList.OrderBy(v => v.Info.Position).Last();
                 Length = (ushort)(last.Info.Position + last.BytesCount);
-
                 var data = new byte[0];
-                lock (Entity.PLCInfo.Ex())
+                lock (plc)
                 {
-                    data = Entity.PLCInfo.Ex().Accessor.ReadBytes(Entity.No, Start, (ushort)(Length - Start));
+                    data = plc.Accessor.ReadBytes(Entity.No, Start, (ushort)(Length - Start));
                 }
                 if (!Data.SequenceEqual(data))
                 {
                     Data = data;
                     DbChanged?.Invoke(Data);
                 }
-                failed = false;
+                Failed = false;
             }
             catch (Exception ex)
             {
-                failed = true;
+                Failed = true;
                 if (isPing) throw new Exception($"{ex.Message}");
                 throw new Exception($"{ex.Message}:\r{ex.StackTrace}");
             }
-        }
+        } 
 
         public PlcItem<T> Regist<T>(ProtocolProxyBase proxy, string objid, string name, int start, byte arrLen = 1, byte strLen = 0)
         {
@@ -104,9 +110,10 @@ namespace WCS.Core
 
         private object Read(Type type, ref int bitStart, int strLength, int arrLength)
         {
-            if (failed)
+            if (Failed)
+            {
                 throw new Exception(this.Entity.No + "连接失败");
-
+            }
             if (type.IsArray)
             {
                 var t = type.GetElementType();
@@ -114,7 +121,7 @@ namespace WCS.Core
                 {
                     throw new Exception("只支持一维数组");
                 }
-                var arr = Array.CreateInstance(t, arrLength);
+                var arr = Array.CreateInstance(t, arrLength);   
 
                 for (int i = 0; i < arr.Length; i++)
                 {
@@ -444,11 +451,11 @@ namespace WCS.Core
 
         private void WriteBytes(ref int bitStart, byte[] data)
         {
-            lock (Entity.PLCInfo.Ex())
+            lock (Entity.PLCInfo.Ex(World))
             {
                 var start = GetByteStart(bitStart);
 
-                Entity.PLCInfo.Ex().Accessor.WriteBytes(Entity.No, start, data);
+                Entity.PLCInfo.Ex(World).Accessor.WriteBytes(Entity.No, start, data);
                 data.CopyTo(Data, start - Start);
                 bitStart += data.Length * 8;
             }
@@ -456,7 +463,7 @@ namespace WCS.Core
 
         private void WriteBit(ref int bitStart, bool flag)
         {
-            lock (Entity.PLCInfo.Ex())
+            lock (Entity.PLCInfo.Ex(World))
             {
                 var start = GetByteStart(bitStart);
                 var bitIndex = GetBitIndex(bitStart);
@@ -465,7 +472,7 @@ namespace WCS.Core
                 b = b.SetBit(bitIndex, flag);
                 var data = new byte[] { b };
 
-                Entity.PLCInfo.Ex().Accessor.WriteBytes(Entity.No, (ushort)start, data);
+                Entity.PLCInfo.Ex(World).Accessor.WriteBytes(Entity.No, (ushort)start, data);
                 data.CopyTo(Data, start - Start);
 
                 bitStart += 1;

+ 5 - 26
WCS.Core/Device.cs

@@ -45,7 +45,7 @@ namespace WCS.Core
             all[code] = this;
         }
 
-        private ConcurrentDictionary<Type, object> ProtocolObjs(World world)
+        public ConcurrentDictionary<Type, object> ProtocolObjs(World world)
         {
             if (!ProtocolObjsOfWorld.TryGetValue(world, out var pobjs))
             {
@@ -101,20 +101,6 @@ namespace WCS.Core
             return ProtocolObjs(world)[protocolType];
         }
 
-        //object Copy(object obj, Type type)
-        //{
-        //    var res = Activator.CreateInstance(type);
-        //    foreach (var p in type.GetProperties())
-        //    {
-        //        var p2 = obj.GetType().GetProperty(p.Name);
-        //        if (p2 != null && p2.PropertyType == p.PropertyType)
-        //        {
-        //            p.SetValue(res, p2.GetValue(obj));
-        //        }
-        //    }
-        //    return res;
-        //}
-
         public override string ToString()
         {
             return Code;
@@ -224,18 +210,9 @@ namespace WCS.Core
             if (!Flags.ContainsKey(key))
                 return false;
             return Flags[key].Contains(flag);
-        }
-
-        public void AddFlag(string flag)
-        {
-            SetFlag("Globals", flag);
-        }
-
-        public bool HasFlag(string flag)
-        {
-            return HasFlag("Globals", flag);
-        }
+        } 
 
+      
         public void AddFlag<T>(T flag) where T : struct, Enum
         {
             var key = typeof(T).AssemblyQualifiedName;
@@ -264,10 +241,12 @@ namespace WCS.Core
 
     public class Device<T> : EntityEx<Device>
     {
+        public World World { get; private set; }
         public T Data { get; set; }
 
         public Device(Device device, World world) : base(device)
         {
+            this.World = world;
             Data = Entity.Protocol<T>(world);
         }
 

+ 22 - 5
WCS.Core/Extentions.cs

@@ -16,7 +16,7 @@ namespace WCS.Core
         static ConcurrentDictionary<object, object> ExObjs = new ConcurrentDictionary<object, object>();
 
         public static T GetEx<T>(object entity)
-        {
+        { 
             lock (ExObjs)
             {
                 if (!ExObjs.ContainsKey(entity))
@@ -25,12 +25,12 @@ namespace WCS.Core
                     ExObjs[entity] = obj;
                 }
                 return (T)ExObjs[entity];
-            }
+            } 
         }
 
-        public static PLC Ex(this PLCInfo source)
+        public static PLC Ex(this PLCInfo source,World world)
         {
-            return GetEx<PLC>(source);
+            return GetExOfWorld<PLC>(source,world);
         }
 
         static ConcurrentDictionary<World, ConcurrentDictionary<object, object>> ExObjsOfWorld = new ConcurrentDictionary<World, ConcurrentDictionary<object, object>>(); 
@@ -44,7 +44,7 @@ namespace WCS.Core
             }
             if (!objs.TryGetValue(source, out var obj))
             {
-                obj = Activator.CreateInstance(typeof(T), source);
+                obj = Activator.CreateInstance(typeof(T), source, world);
                 objs[source] = obj;
             }
             return (T)obj;
@@ -97,6 +97,23 @@ namespace WCS.Core
                 return attr.Description;
         }
 
+        public static object Copy(this object source, Type t)
+        { 
+            var obj=Activator.CreateInstance(t);
+            foreach (var p in t.GetProperties())
+            {
+                var p2 = source.GetType().GetProperty(p.Name);
+                var value = p2.GetValue(source);
+                p.SetValue(obj, value);
+            }
+            return obj;
+        }
+
+        public static T Copy<T>(this object source)
+        {
+            return (T)source.Copy(typeof(T));
+        }
+
     }
 
 

+ 3 - 2
WCS.Core/Ltc.cs

@@ -8,7 +8,7 @@ using System.Threading.Channels;
 
 namespace WCS.Core
 {
-    internal static class Ltc
+    public static class Ltc
     {  
         private static ConcurrentDictionary<Thread, Channel> Channels = new ConcurrentDictionary<Thread, Channel>(); 
 
@@ -20,7 +20,8 @@ namespace WCS.Core
 
         public static Channel GetChannel()
         {
-            return Channels[Thread.CurrentThread];
+            if (Channels.ContainsKey(Thread.CurrentThread))return Channels[Thread.CurrentThread];
+            else return null;
         }
 
         //static ConcurrentDictionary<Channel, List<LogInfo>> Msgs = new ConcurrentDictionary<Channel, List<LogInfo>>();

+ 14 - 33
WCS.Core/PLC.cs

@@ -1,13 +1,16 @@
-using System.Net.NetworkInformation;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.NetworkInformation;
 using System.Text;
+using System.Threading.Tasks; 
 
 namespace WCS.Core
 {
     public class PLC : EntityEx<PLCInfo>
     {
         public bool Ping { get; private set; }
-
-        public PLC(PLCInfo ent) : base(ent)
+        public PLC(PLCInfo ent,World world) : base(ent)
         {
             if (Configs.PLCAccessorCreater != null)
             {
@@ -20,51 +23,29 @@ namespace WCS.Core
             {
                 while (true)
                 {
-                    Ping = ping();
+                    Ping=ping();
                     Task.Delay(1000);
                 }
             });
-        }
-
+        }      
         public IPLCAccessor Accessor { get; private set; }
 
-        private bool ping(int timeout = 100)
-        {
-            if (Entity.IP == "1") return false;
-            try
-            {
-                var objPingSender = new Ping();
-                var objPinOptions = new PingOptions
-                {
-                    DontFragment = true
-                };
-                const string data = "";
-                var buffer = Encoding.UTF8.GetBytes(data);
-                var objPinReply = objPingSender.Send(Entity.IP, timeout, buffer, objPinOptions);
-                var strInfo = objPinReply.Status.ToString();
-                return strInfo == "Success";
-            }
-            catch (Exception)
-            {
-                return false;
-            }
-
-            //var p = new Ping();
-            //var res = p.Send(Entity.IP, timeout);
-            //return res.Status == IPStatus.Success;
-            ////return true;
+        bool ping(int timeout = 100)
+        { 
+            var p = new Ping();
+            var res = p.Send(Entity.IP, timeout);
+            return res.Status == IPStatus.Success;
         }
+      
     }
 
     public interface IPLCAccessorCreater
     {
         IPLCAccessor Create(PLCInfo data);
     }
-
     public interface IPLCAccessor
     {
         void WriteBytes(ushort db, ushort address, byte[] data);
-
         byte[] ReadBytes(ushort db, ushort address, ushort length);
     }
 }

+ 3 - 3
WCS.Core/PlcItem.cs

@@ -23,7 +23,7 @@ namespace WCS.Core
         /// <summary>
         /// 数据类型所占的字节数
         /// </summary>
-        public byte DataSize { get; private set; }
+        public int DataSize { get; private set; }
 
         public int DataSizeOfBits { get; private set; }
 
@@ -38,7 +38,7 @@ namespace WCS.Core
             this.ArrayLength = arrLen;
             this.StringLength = strLength;
 
-            DataSize = (byte)GetTypeLen(DataType);
+            DataSize = GetTypeLen(DataType);
 
             DataSizeOfBits = _getBitLen(DataType);
         }
@@ -117,7 +117,7 @@ namespace WCS.Core
                 }
                 catch (Exception ex)
                 {
-                    if (i >= 3) throw new Exception($"写入出错{ex.Message}--{Start}--{(T)value}--{StringLength}--{ArrayLength}--{Db.Entity.No}");
+                    if (i >= 3) throw new Exception($"写入出错{ex.Message}--{Start}--{(T)value}--{StringLength}--{ArrayLength}--{Db.Entity.No}"); ;
                     i++;
                     Thread.Sleep(100);
                 }

+ 14 - 7
WCS.Core/ProtocolProxyBase.cs

@@ -8,16 +8,18 @@ namespace WCS.Core
     {
         private string Id = Guid.NewGuid().ToString();
         public ProtocolInfo Info { get; private set; }
-        public ushort BytesCount { get; private set; }
+        public int BytesCount { get; private set; }
         public Dictionary<string, PlcItem> Items = new Dictionary<string, PlcItem>();
         public Type ProtocolType, ProtocolDataType;
         public Device Device { get; private set; }
         public World World { get; private set; }
-        private DataBlock Db;
+        public DataBlock Db { get; private set; }
+        public DateTime Frame;
 
         public ProtocolProxyBase(Device dev, ProtocolInfo info, Type protocolType, World world)
         {
-            this.World = world;
+            this.World= world;
+            this.Frame = world.Frame;
             this.Device = dev;
             this.Info = info;
             Db = info.DBInfo.Ex(world);
@@ -82,7 +84,6 @@ namespace WCS.Core
                 bitStart += item.DataSizeOfBits;
                 BytesCount += item.DataSize;
             }
-
             ProtocolDataType = ProtocolType.Assembly.GetTypes().Where(v => v.IsClass).First(v => v.GetInterface(ProtocolType.Name) != null && v != this.GetType());
         }
 
@@ -92,7 +93,9 @@ namespace WCS.Core
         {
             var pos = Info.Position - Db.Start;
             var bytes = data.Skip(pos).Take(BytesCount).ToArray();
-            if (Data.SequenceEqual(bytes)) return;
+            if (Data.SequenceEqual(bytes)) 
+                return;
+            this.Frame = World.Frame;
             Data = bytes;
             DataChanged();
         }
@@ -126,7 +129,8 @@ namespace WCS.Core
             var item = Items[propertyName] as PlcItem<T>;
             var res = item.Value;
             var channel = Ltc.GetChannel();
-            //if (channel != null && !ProtocolType.Name.Contains("525") && !ProtocolType.Name.Contains("83")) this.World.OnInternalLog(channel, $"获取值:{Device.Code}.{ProtocolType.Name}.{propertyName}:{res}");
+            //if (channel != null)
+            //    this.World.OnInternalLog(channel, $"获取{Device.Code}.{ProtocolType.Name}.{propertyName} 值:{res}");
             return res;
         }
 
@@ -135,7 +139,10 @@ namespace WCS.Core
             var item = Items[propertyName] as PlcItem<T>;
             item.Value = value;
             var channel = Ltc.GetChannel();
-            if (channel != null) this.World.OnInternalLog(channel, $"设置值:{Device.Code}.{ProtocolType.Name}.{propertyName} :{value}");
+            if (channel != null)
+                this.World.OnInternalLog(channel, $"设置{Device.Code}.{ProtocolType.Name}.{propertyName} 值:{value}");
+            this.Frame = World.Frame;
+            //DataChanged(); 
         }
 
         #endregion

+ 18 - 13
WCS.Core/System.cs

@@ -28,12 +28,7 @@ namespace WCS.Core
         /// <summary>
         /// 对所有Objects并行循环执行Do
         /// </summary>
-        protected abstract bool ParallelDo { get; }
-
-        /// <summary>
-        /// 保存日志到文件
-        /// </summary>
-        protected abstract bool SaveLogsToFile { get; }
+        protected abstract bool ParallelDo { get; } 
 
         public SystemBase()
         {
@@ -116,15 +111,25 @@ namespace WCS.Core
                 if (t.IsGenericType) break;
                 t = t.BaseType;
             }
-
-            var types = t.GetGenericArguments();
-            var list = Device.All.Where(v => types.All(v.HasProtocol)).Where(Select).Select(v => Activator.CreateInstance(typeof(T), v, World)).OfType<T>().ToList();//此时才实例化Protocol
-
-            if (list.Count == 0)
+            if (t == typeof(EntityEx<Device>))
             {
-                //throw new Exception($"{this.GetType().Name}未匹配到任何Device");
+                var list = Device.All
+                   .Where(Select)
+                   .Select(v => Activator.CreateInstance(typeof(T), v)).OfType<T>().ToList();//此时才实例化Protocol 
+                return list;
+            }
+            else
+            {
+                var types = t.GetGenericArguments();
+                var list = Device.All.Where(v => types.All(v.HasProtocol))
+                    .Where(Select)
+                    .Select(v => Activator.CreateInstance(typeof(T), v, World)).OfType<T>().ToList();//此时才实例化Protocol
+                if (list.Count == 0)
+                {
+                    //throw new Exception($"{this.GetType().Name}未匹配到任何Device");
+                }
+                return list;
             }
-            return list;
         }
 
         /// <summary>

+ 22 - 18
WCS.Core/World.cs

@@ -109,6 +109,8 @@ namespace WCS.Core
             get;
         }
 
+        public DateTime Frame { get; private set; }
+
         public World()
         {
             SystemTypes = GetSystemTypes();
@@ -206,12 +208,13 @@ namespace WCS.Core
             var sw = new Stopwatch();
             while (!Stoped)
             {
+                this.Frame = DateTime.Now;
                 WorkTimes wt = new WorkTimes();
                 wt.Key = $"{this.Description} 周期:{Interval}";
                 sw.Restart();
-                BeforeUpdate();
+                BeforeUpdate(wt.Items);
                 Update(wt.Items);
-                AfterUpdate();
+                AfterUpdate(wt.Items);
                 sw.Stop();
                 var workTimes = (int)sw.ElapsedMilliseconds;
                 var ms = Interval - workTimes;
@@ -254,17 +257,14 @@ namespace WCS.Core
 
         private void LoadPlcData(List<WorkTimes> list)
         {
-            var a = this.GetDataBlocks();
             Parallel.ForEach(this.GetDataBlocks(), db =>
             {
-                var b = GetType();
-                var a = b.GetCustomAttribute(typeof(DescriptionAttribute)) as DescriptionAttribute;
                 var channel = new Channel
                 {
-                    World = a.Description,
+                    World = GetType().Name,
                     Stage = "LoadPlcData",
                     System = "",
-                    Item = $"{db.Entity.PLCInfo.IP}"
+                    Item = $"{db.Entity.PLCInfo.IP}_{db.Entity.No}"
                 };
                 var sw = new Stopwatch();
                 sw.Start();
@@ -275,9 +275,6 @@ namespace WCS.Core
                 catch (Exception ex)
                 {
                     this.Ex().Publish(channel, ex.GetBaseException().Message);
-                    sw.Stop();
-                    list.AddSafe(new WorkTimes { Key = $"{db.Entity.PLCInfo.IP}/{db.Entity.No}", Total = sw.ElapsedMilliseconds });
-                    OnLog(channel, ex.Message);
                 }
                 sw.Stop();
                 list.AddSafe(new WorkTimes { Key = $"{db.Entity.PLCInfo.IP}/{db.Entity.No}", Total = sw.ElapsedMilliseconds });
@@ -318,11 +315,11 @@ namespace WCS.Core
             }
         }
 
-        protected virtual void BeforeUpdate()
+        protected virtual void BeforeUpdate(List<WorkTimes> list)
         {
         }
 
-        protected virtual void AfterUpdate()
+        protected virtual void AfterUpdate(List<WorkTimes> list)
         {
         }
 
@@ -355,7 +352,9 @@ namespace WCS.Core
 
         public void Log<T>(T log) where T : ILog
         {
-            OnLog(Ltc.GetChannel(), log);
+            var channel = Ltc.GetChannel();
+            if (channel != null)
+                OnLog(Ltc.GetChannel(), log);
         }
 
         protected internal abstract void OnError(Channel channel, Exception exception);
@@ -369,9 +368,12 @@ namespace WCS.Core
         internal void Publish()
         {
             var channel = Ltc.GetChannel();
-            var msgs = GetChannelMsg(channel);
-            var msg = string.Join("\n", msgs);
-            this.Ex().Publish(channel, msg);
+            if (channel != null)
+            {
+                var msgs = GetChannelMsg(channel);
+                var msg = string.Join("\n", msgs);
+                this.Ex().Publish(channel, msg);
+            }
         }
     }
 
@@ -403,7 +405,8 @@ namespace WCS.Core
 
         public void Publish(Channel channel, string msg)
         {
-            if ((DateTime.Now - SubTime).TotalSeconds > 20) return;
+            if ((DateTime.Now - SubTime).TotalSeconds > 20)
+                return;
             var flag = false;
 
             flag = ChannelList.Any(v =>
@@ -412,7 +415,8 @@ namespace WCS.Core
                 return b.Success;
             });
 
-            if (flag) Redis.Publish(channel.ToString(), msg);
+            if (flag)
+                Redis.Publish(channel.ToString(), msg);
         }
     }
 

+ 1 - 1
业务工程/分拣库/WCS.WorkEngineering/Systems/桁架码垛/桁架码垛工位任务结束处理.cs

@@ -27,7 +27,7 @@ namespace WCS.WorkEngineering.Systems
 
         public override void Do(Device<IStation520, IStation521, IStation523, ITruss530, ITruss531> obj)
         {
-            if (!obj.Data5.CmdType.HasFlag(TrussCmdType.End) && !obj.Data4.CmdType.HasFlag(TrussCmdType.End1 | TrussCmdType.Two)) obj.Data4.CmdType = 0;
+            if (!obj.Data5.CmdType.HasFlag(TrussCmdType.End) && !obj.Data4.CmdType.HasFlag(TrussCmdType.End1 | TrussCmdType.Two) && obj.Data4.CmdType != 0) obj.Data4.CmdType = 0;
             if (!obj.Data3.Status.HasFlag(StationStatus.PH_Status)) return;
             if (!obj.Data5.CmdType.HasFlag(TrussCmdType.End)) return;
             if (!obj.Data5.CmdType.HasFlag(TrussCmdType.End1))