123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- using HslCommunication;
- using Newtonsoft.Json.Linq;
- using ProjectManagementSystem.Common.Config;
- using ProjectManagementSystem.Common.Extenions;
- using ProjectManagementSystem.Common.Logger;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- namespace ProjectManagementSystem.Common.Core
- {
- public class PlcControl
- {
- private static PlcControl m_instance;
- private Dictionary<string, HslCommunication.Core.IReadWriteNet> m_plcDict = new Dictionary<string, HslCommunication.Core.IReadWriteNet>();
- public List<JObject> JDataList { get; set; } = new List<JObject>();
- private string[] columnNameArray = new string[]
- {
- "PLC允许进入" ,
- "PLC放行" ,
- "PLC返修" ,
- "AGV请求进入",
- "AGV正在进入",
- "AGV到位",
- "AGV正在离开"
- };
- public static PlcControl Instance
- {
- get
- {
- if (m_instance == null)
- {
- m_instance = new PlcControl();
- if (!m_instance.Initialize())
- {
- m_instance = null;
- }
- }
- return m_instance;
- }
- }
- private PlcControl()
- {
- }
- private bool Initialize()
- {
- var dataList = ExcelConfig.Instance.RouteConfigList;
- for (int i = 0; i < dataList.Count; i++)
- {
- var data = dataList[i];
- string plcIpAddr = data.PlcIpAddr;
- if (!string.IsNullOrEmpty(plcIpAddr))
- {
- bool selfPlcReadWrite = data.LocationCode.GetLocationMember("独立通讯(PLC)").ToValue<bool>();
- if (selfPlcReadWrite)
- {
- //每个库位独立的PLC通讯对象
- var plc = GetReadWriteNet(data);
- data.PlcReadWrite = plc;
- }
- else
- {
- //库位相同IP共用PLC通讯对象
- if (!m_plcDict.ContainsKey(plcIpAddr))
- {
- var plc = GetReadWriteNet(data);
- m_plcDict.Add(plcIpAddr, plc);
- }
- if (m_plcDict.TryGetValue(plcIpAddr, out var plcObj))
- {
- data.PlcReadWrite = plcObj;
- }
- }
- }
- }
- columnNameArray = Function.AppSetting.TryGetValue<string>("PlcSignalColumnName").ToValueArray<string>();
- var dataList2 = ExcelConfig.Instance.InfoPlcList;
- for (int i = 0; i < dataList2.Count; i++)
- {
- var data = dataList2[i];
- data.routeConfig = ExcelConfig.Instance.GetRouteConfig(data.库位号);
- data.JData = new JObject();
- string defaultAddr = data.routeConfig.PlcHeartbearAddr;
- data.PlcSignalAddrArray = new string[columnNameArray.Length];
- data.PlcSignalAddrLengthArray = new ushort[columnNameArray.Length];
- for (int infoIndex = 0; infoIndex < columnNameArray.Length; infoIndex++)
- {
- string info = columnNameArray[infoIndex];
- string plcRealAddr = data.routeConfig.LocationCode.GetLocationMember(info);
- data.PlcSignalAddrArray[infoIndex] = string.IsNullOrEmpty(plcRealAddr) ? defaultAddr : plcRealAddr;
- //读取长度2,要求PLC有多出来一个byte地址
- data.PlcSignalAddrLengthArray[infoIndex] = 2;
- }
- var jData = new JObject();
- jData["库位号"] = data.routeConfig.LocationCode;
- jData["IP地址"] = data.routeConfig.PlcIpAddr;
- JDataList.Add(jData);
- }
- Task.Factory.StartNew(UserThread, TaskCreationOptions.LongRunning);
- return true;
- }
- /// <summary>
- /// 获取创建的PLC通讯对象
- /// </summary>
- /// <param name="data"></param>
- /// <returns></returns>
- private HslCommunication.Core.IReadWriteNet GetReadWriteNet(RouteConfig data)
- {
- string plcIpAddr = data.PlcIpAddr;
- var plcProtocol = data.LocationCode.GetLocationMember("通讯协议(PLC)");
- switch (plcProtocol)
- {
- case "SiemensS7Net":
- {
- var plc = new HslCommunication.Profinet.Siemens.SiemensS7Net(HslCommunication.Profinet.Siemens.SiemensPLCS.S1500, plcIpAddr);
- plc.ConnectTimeOut = 1000;
- plc.ReceiveTimeOut = 1000;
- plc.SetPersistentConnection();
- return plc;
- }
- case "SiemensS7Net_S200Smart":
- {
- var plc = new HslCommunication.Profinet.Siemens.SiemensS7Net(HslCommunication.Profinet.Siemens.SiemensPLCS.S200Smart, plcIpAddr);
- plc.ConnectTimeOut = 1000;
- plc.ReceiveTimeOut = 1000;
- plc.SetPersistentConnection();
- return plc;
- }
- case "MelsecMcNet":
- {
- var plc = new HslCommunication.Profinet.Melsec.MelsecMcNet(plcIpAddr, 5000);
- plc.ConnectTimeOut = 1000;
- plc.ReceiveTimeOut = 1000;
- plc.SetPersistentConnection();
- return plc;
- }
- case "OmronFinsNet":
- {
- var plc = new HslCommunication.Profinet.Omron.OmronFinsNet(plcIpAddr, 9600);
- plc.ConnectTimeOut = 1000;
- plc.ReceiveTimeOut = 1000;
- plc.ByteTransform.DataFormat = HslCommunication.Core.DataFormat.BADC;
- plc.SetPersistentConnection();
- return plc;
- }
- case "OmronFinsUdp":
- {
- var plc = new HslCommunication.Profinet.Omron.OmronFinsUdp(plcIpAddr, 9600);
- plc.ReceiveTimeout = 1000;
- plc.ByteTransform.DataFormat = HslCommunication.Core.DataFormat.BADC;
- return plc;
- }
- case "AllenBradleyNet":
- {
- var plc = new HslCommunication.Profinet.AllenBradley.AllenBradleyNet(plcIpAddr);
- plc.ConnectTimeOut = 1000;
- plc.ReceiveTimeOut = 1000;
- plc.SetPersistentConnection();
- return plc;
- }
- case "ModbusTcpNet":
- {
- var plc = new HslCommunication.ModBus.ModbusTcpNet(plcIpAddr);
- plc.ConnectTimeOut = 1000;
- plc.ReceiveTimeOut = 1000;
- plc.ByteTransform.DataFormat = HslCommunication.Core.DataFormat.BADC;
- plc.SetPersistentConnection();
- return plc;
- }
- case "IOBoxNet":
- {
- var plc = new Profinet.IOBoxNet(plcIpAddr, 8898);
- return plc;
- }
- default:
- {
- var plc = new HslCommunication.Profinet.AllenBradley.AllenBradleyNet(plcIpAddr);
- plc.ConnectTimeOut = 1000;
- plc.ReceiveTimeOut = 1000;
- plc.SetPersistentConnection();
- return plc;
- }
- }
- }
- private void PlcTaskProc()
- {
- var configList = ExcelConfig.Instance.RouteConfigList;
- var plcGroupList = configList
- .Where(d => d.PlcReadWrite != null)
- .GroupBy(d => d.PlcIpAddr);
- foreach (var item in plcGroupList)
- {
- var first = item.FirstOrDefault(d => !string.IsNullOrEmpty(d.PlcHeartbearAddr));
- if (first == null)
- {
- continue;
- }
- //读取PLC心跳信号
- var tempResult = first.PlcReadWrite.ReadBool(first.PlcHeartbearAddr);
- if (first.PlcConnected != tempResult.IsSuccess)
- {
- CLog.Instance.SystemLog.WriteInfo($"{first.LocationCode} {first.PlcIpAddr} PLC连接:{tempResult.IsSuccess.ToChineseString()} Code:{tempResult.ErrorCode} Message:{tempResult.Message}");
- }
- foreach (var config in item)
- {
- config.PlcConnected = tempResult.IsSuccess;
- }
- }
- //for (int i = 0; i < configList.Count; i++)
- //{
- // var routeConfig = configList[i];
- // if (!string.IsNullOrEmpty(routeConfig.PlcHeartbearAddr)
- // && routeConfig.PlcReadWrite != null)
- // {
- // //读取PLC心跳信号
- // var tempResult = routeConfig.PlcReadWrite.ReadBool(routeConfig.PlcHeartbearAddr);
- // if (routeConfig.PlcConnected != tempResult.IsSuccess)
- // {
- // CLog.Instance.SystemLog.WriteInfo($"{routeConfig.LocationCode} {routeConfig.PlcIpAddr} PLC连接:{tempResult.IsSuccess.ToChineseString()}");
- // }
- // routeConfig.PlcConnected = tempResult.IsSuccess;
- // ////回写PLC心跳信号
- // //if (tempResult.IsSuccess
- // // && !string.IsNullOrEmpty(routeConfig.PlcHeartbearAddr_AGV))
- // //{
- // // routeConfig.PlcReadWrite.Write(routeConfig.PlcHeartbearAddr_AGV, tempResult.Content);
- // //}
- // }
- //}
- }
- public List<JObject> ReadPlcInfo()
- {
- //用于显示
- var infoPlcList = ExcelConfig.Instance.InfoPlcList;
- //var RouteConfigList = ExcelConfig.Instance.RouteConfigList;
- Parallel.ForEach(infoPlcList, delegate (InfoPlc info, ParallelLoopState loopState)
- {
- try
- {
- DateTime start = DateTime.Now;
- ////单个读取信号
- //for (int i = 0; i < columnNameArray.Length; i++)
- //{
- // string colName = columnNameArray[i];
- // string addr = info.routeConfig.LocationCode.GetLocationMember(colName);
- // if (!string.IsNullOrEmpty(addr))
- // {
- // var result = info.routeConfig.PlcReadWrite.ReadBool(addr);
- // if (result.IsSuccess)
- // {
- // info.JData[colName] = result.Content;
- // }
- // else
- // {
- // info.JData[colName] = null;
- // }
- // }
- // else
- // {
- // info.JData[colName] = null;
- // }
- //}
- //info.LastUpdateTime = DateTime.Now;
- //////离散地址批量读取,部分plc支持
- OperateResult<byte[]> result = null;
- switch (info.routeConfig.PlcReadWrite)
- {
- case HslCommunication.Profinet.AllenBradley.AllenBradleyNet plc:
- result = plc.Read(info.PlcSignalAddrArray);
- break;
- case HslCommunication.Profinet.Siemens.SiemensS7Net plc:
- result = plc.Read(info.PlcSignalAddrArray, info.PlcSignalAddrLengthArray);
- break;
- default:
- CLog.Instance.SystemLog.WriteInfo("PlcReadWrite转换失败");
- return;
- }
- //批量读取
- if (result.IsSuccess)
- {
- for (int i = 0; i < columnNameArray.Length; i++)
- {
- string colName = columnNameArray[i];
- string addr = info.routeConfig.LocationCode.GetLocationMember(colName);
- if (string.IsNullOrEmpty(addr))
- {
- info.JData[colName] = null;
- }
- else
- {
- switch (info.routeConfig.PlcReadWrite)
- {
- case HslCommunication.Profinet.AllenBradley.AllenBradleyNet plc:
- info.JData[colName] = plc.ByteTransform.TransBool(result.Content, i) ? "1" : "0";
- break;
- case HslCommunication.Profinet.Siemens.SiemensS7Net plc:
- if (addr.Contains("DBW") || addr.Count(d => d == '.') == 1)
- {
- info.JData[colName] = plc.ByteTransform.TransInt16(result.Content, i * 2);
- }
- else
- {
- int bitIndex = int.Parse(addr.Last().ToString());
- info.JData[colName] = result.Content[i * 2].GetBitVaule(bitIndex) ? "1" : "0";
- }
- break;
- default:
- break;
- }
- }
- }
- info.LastUpdateTime = DateTime.Now;
- }
- info.JData["耗时"] = Math.Round((DateTime.Now - start).TotalMilliseconds);
- info.JData["消息"] = result.Message;
- }
- catch (Exception ex)
- {
- info.JData["消息"] = ex.Message;
- }
- });
- for (int index = 0; index < infoPlcList.Count; index++)
- {
- var info = infoPlcList[index];
- var jData = JDataList[index];
- jData["更新时间"] = info.LastUpdateTime.ToString("G");
- jData["消息"] = info.JData["消息"];
- for (int i = 0; i < columnNameArray.Length; i++)
- {
- string colName = columnNameArray[i];
- jData[colName] = info.JData[colName];
- }
- jData["耗时(ms)"] = info.JData["耗时"];
- //jData["有效"] = info.有效;
- }
- return JDataList.ToList();
- }
- private void UserThread()
- {
- CLog.Instance.SystemLog.WriteDebug($"PlcControl已启动");
- Thread.Sleep(2000);
- while (true)
- {
- try
- {
- PlcTaskProc();
- }
- catch (Exception ex)
- {
- CLog.Instance.SystemLog.WriteException("PlcControl", ex);
- Thread.Sleep(5000);
- }
- Thread.Sleep(1000);
- }
- }
- }
- }
|