using HslCommunication.Core; using Mesnac.Compressor.Entity; using Microsoft.AspNetCore.Http; using Microsoft.Data.SqlClient; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Models; using Newtonsoft.Json.Linq; using SlnMesnac.Common; using SlnMesnac.Config; using SlnMesnac.Model.domain; using SlnMesnac.Plc; using SlnMesnac.Repository; using SlnMesnac.Repository.service; using SlnMesnac.Serilog; using SqlSugar; using System.Collections; using System.Diagnostics; using System.Text; using System.Text.Json; using System.Threading.Tasks; using System.Xml.Linq; using static System.Net.Mime.MediaTypeNames; namespace ConsoleApp { internal class MainCentralControl { private IHost host; // 新增一个标志位,用于表示方法是否正在执行 private static String StationCode; private bool isExecuting = false; private AppConfig _appConfig; private readonly SerilogHelper _logger; private IServiceProvider serviceProvider; private ISqlSugarClient SqlSugarClient; public List plcList; IByteTransform ByteTransform = new ReverseBytesTransform(); public bool isConnect; public string State; private StationInfo _stationInfo; private object _mcValue; //PLC心跳地址 private string _plcHeartBeatAddress; //PLC工作请求地址 private string _workAskAddress; //PLC工作完成放行请求地址 private string _completeAskAddress; //PLC产品码地址 private string _productBarcode; //PLC支线码1地址 private string _semiBarcode1; //PLC支线码2地址 private string _semiBarcode2; private IDatastationLocalService _datastationLocalService; public MainCentralControl(IHost host) { try { this.host = host; _appConfig = host.Services.GetService(); StationCode = _appConfig.StationCode; SqlSugarClient = host.Services.GetRequiredService(); _logger = host.Services.GetRequiredService(); plcList = host.Services.GetRequiredService>(); _datastationLocalService = host.Services.GetService(); } catch (Exception ex) { _logger.Info($"MainCentralControl出错: {ex.Message}"); } } private void test() { Datastation datastation = new Datastation() { Stime = DateTime.Now, Stationid = StationCode, Productid = "S123456", Partid = "", Modelid = "", Ng = 1, Proc = 0, Sublinenum = 0, Sublinesnnum = 0, Partsnnum = 1, Sublineids = "", Partsns = "123456", Sublinesns = StringChange.ModeToJson(new partsns()), Paratemp = "", Stringtemp = "", GroupStationId = "", Renum = "0", }; int id = SqlSugarClient.Insertable(datastation).ExecuteReturnIdentity(); } public void Start() { init(); StartCheckStatus(); ListeningPlcValue(); _logger.Info("iMES系统启动成功!"+StationCode); } /// /// 初始化加载PLC地址,不同工位PLC提供的地址不同 /// private async void init() { try { switch (StationCode) { case "S130-1": _plcHeartBeatAddress = "D7777"; _completeAskAddress = "D7703"; _semiBarcode1 = "D7701"; break; case "S130-2": _plcHeartBeatAddress = "D7777"; _workAskAddress = "D7803"; _completeAskAddress = "D7804"; _productBarcode = ""; _semiBarcode1 = "D7801"; _semiBarcode2 = "D7802"; break; case "A20": _plcHeartBeatAddress = "D7778"; _completeAskAddress = "D7703"; _productBarcode = "D7700"; _semiBarcode1 = "D7701"; break; } } catch (Exception ex) { } } /// /// 监听PLC地址值 /// private void ListeningPlcValue() { Task.Run(async () => { while (true) { try { PlcAbsractFactory? Plc = plcList.FirstOrDefault(x => x.ConfigKey == "plc"); if (Plc == null || !Plc.IsConnected) { _logger.Plc(DateTime.Now + "PLC未连接,请检查网络!"); continue; } //读取PLC工作请求,放行请求 switch (StationCode) { case "S130-1": if (Plc.readInt16ByAddress(_completeAskAddress) == 1) { _logger.Info(StationCode+"放行请求"); Plc.writeInt16ByAddress(_completeAskAddress, 0); SaveStationDataTask(Plc); } break; case "S130-2": //读取PLC工作请求 if (Plc.readInt16ByAddress(_workAskAddress) == 1) { _logger.Info(StationCode + "工作请求"); Plc.writeInt16ByAddress(_workAskAddress, 0); //根据转子码查询上工位是否合格 SelectStationQuality(Plc); } break; case "A20": //读取PLC工作请求 if (Plc.readInt16ByAddress(_completeAskAddress) == 1) { _logger.Info(StationCode + "放行请求"); Plc.writeInt16ByAddress(_completeAskAddress, 0); //根据转子码查询上工位是否合格 BarCodeRelationShipBinding(Plc); } break; } } catch (Exception ex) { _logger.Error($"ListeningPlcValue方法异常:" + ex.StackTrace); } finally { Thread.Sleep(1000); } } }); } private void BarCodeRelationShipBinding(PlcAbsractFactory Plc) { try { //壳体码 byte[] _KTBarcode = Plc.readValueByAddress(_productBarcode, 20); string KTBarCode = ByteTransform.TransString(_KTBarcode, 0, 20, Encoding.ASCII); _logger.Info("壳体码:"+ KTBarCode); //定子码 byte[] _DZBarcode = Plc.readValueByAddress(_semiBarcode1, 20); string DZBarCode = ByteTransform.TransString(_DZBarcode, 0, 20, Encoding.ASCII); _logger.Info("定子码:" + DZBarCode); var Dipsn = SqlSugarClient.Queryable().First(it => it.Mainsn == KTBarCode); if (Dipsn != null) { Dipsn.Snlist = Dipsn.Snlist + "," + DZBarCode; int updateflag = SqlSugarClient.Updateable(Dipsn).ExecuteCommand(); } } catch (Exception ex) { _logger.Error($"BarCodeRelationShipBinding方法异常:" + ex.StackTrace); } } /// /// 判断数据库表是否已存在条码数据,存在则更新,不存在则插入 /// /// /// private DatastationLocal IsExistData(string ProductBarCode) { DatastationLocal datastationLocal = null; try { partsns partsns = new partsns(); partsns.sn.Add(ProductBarCode); string jsonString = StringChange.ModeToJson(partsns); //查询本地库是否存在该数据 datastationLocal = _datastationLocalService.GetDatastationLocal(jsonString); //datastationLocal = SqlSugarClient.Queryable().First(it => it.Partsns == jsonString); //datastation = SqlSugarClient.Queryable().First(it => it.Partsns == jsonString); if (datastationLocal != null) { return datastationLocal; } return datastationLocal; } catch (Exception ex) { return datastationLocal; } } /// /// S130-1工位存盘 /// /// private async void SaveStationDataTask(PlcAbsractFactory Plc) { try { //转子码 byte[] SemBarCode = Plc.readValueByAddress(_semiBarcode1, 20); string barcode = ByteTransform.TransString(SemBarCode, 0, 20, Encoding.ASCII); Glbcaldata no = SqlSugarClient.Queryable().First(it => it.Id == 18); Dataproduce dataproduce = null; if (no != null) { dataproduce = new Dataproduce() { Productid = no.ProducePreSn + no.LastProduceId, Stime = DateTime.Now, Etime = DateTime.Now, Currreinstation = StationCode, Operseq = StationCode, Snlist = barcode, Mainsn = barcode, Pdtype = 2, Status = 2, }; int id = SqlSugarClient.Insertable(dataproduce).ExecuteReturnIdentity(); no.LastProduceId = no.LastProduceId + 1; SqlSugarClient.Updateable(no).ExecuteCommand(); } partsns partsns = new partsns(); partsns.sn.Add(barcode); //数据 string jsonString = StringChange.ModeToJson(partsns); D data1 = new D() { n = "转子压装位置1压力值", t = 0, ng = int.Parse(Plc.readFloatByAddress("D7708").ToString()) == 1? 0 : 1, v = Plc.readFloatByAddress("D7705").ToString(), min = Plc.readFloatByAddress("D7706").ToString(), max = Plc.readFloatByAddress("D7707").ToString(), }; D data2 = new D() { n = "转子压装位置2压力值", t = 0, ng = int.Parse(Plc.readFloatByAddress("D7712").ToString()) == 1 ? 0 : 1, v = Plc.readFloatByAddress("D7709").ToString(), min = Plc.readFloatByAddress("D7710").ToString(), max = Plc.readFloatByAddress("D7711").ToString(), }; D data3 = new D() { n = "转子压装位置3压力值", t = 0, ng = int.Parse(Plc.readFloatByAddress("D7716").ToString()) == 1 ? 0 : 1, v = Plc.readFloatByAddress("D7713").ToString(), min = Plc.readFloatByAddress("D7714").ToString(), max = Plc.readFloatByAddress("D7715").ToString(), }; D data4 = new D() { n = "转子压装位置4位移值", t = 0, ng = int.Parse(Plc.readFloatByAddress("D7720").ToString()) == 1 ? 0 : 1, v = Plc.readFloatByAddress("D7717").ToString(), min = Plc.readFloatByAddress("D7718").ToString(), max = Plc.readFloatByAddress("D7719").ToString(), }; D data5 = new D() { n = "转子压装位置4压力值", t = 0, ng = int.Parse(Plc.readFloatByAddress("D7724").ToString()) == 1 ? 0 : 1, v = Plc.readFloatByAddress("D7721").ToString(), min = Plc.readFloatByAddress("D7722").ToString(), max = Plc.readFloatByAddress("D7723").ToString(), }; Root root = new Root(); root.d.Add(data1); root.d.Add(data2); root.d.Add(data3); root.d.Add(data4); root.d.Add(data5); string datastring = StringChange.ModeToJson(root); //查询是否已经存在数据,存在则更新不存在则保存 Datastation datastation = null; if (datastation != null) { //更新 datastation.Stime = DateTime.Now; datastation.Stationid = StationCode; datastation.Ng = Plc.readFloatByAddress("D7708").ToString() == "1" ? 0 : 1; datastation.Partsns = jsonString; datastation.Paratemp = datastring; int InsertFlag = SqlSugarClient.Updateable(datastation).ExecuteCommand(); //Console.WriteLine(StringChange.ModeToJson(datastation)); _logger.Info(StringChange.ModeToJson(datastation)); } else { SqlSugarClient.AsTenant().BeginTran(); //存库 datastation = new Datastation() { Stime = DateTime.Now, Stationid = StationCode, Productid = dataproduce.Productid, Partid = "", Modelid = "", Ng = Plc.readInt16ByAddress("D7725").ToString() == "1" ? 0 : 1, Proc = 0, Sublinenum = 0, Sublinesnnum = 0, Partsnnum = 1, Sublineids = "", Partsns = jsonString, Sublinesns = StringChange.ModeToJson(new partsns()), Paratemp = datastring, Stringtemp = "", GroupStationId = "", Renum = "0", }; DatastationLocal datastationLocal = new DatastationLocal() { Stime = DateTime.Now, Stationid = StationCode, Productid = dataproduce.Productid, Partid = "", Modelid = "", Ng = Plc.readInt16ByAddress("D7725").ToString() == "1" ? 0 : 1, Proc = 0, Sublinenum = 0, Sublinesnnum = 0, Partsnnum = 1, Sublineids = "", Partsns = jsonString, Sublinesns = StringChange.ModeToJson(new partsns()), Paratemp = datastring, Stringtemp = "", GroupStationId = "", Renum = "0", }; //存盘先报存到本地数据库 bool insertflag = await _datastationLocalService.AddDatastationLocalAsync(datastationLocal); int id = SqlSugarClient.Insertable(datastation).ExecuteReturnIdentity(); _logger.Info("datastationID"+id); Plc.writeInt16ByAddress("D7704", 1); _logger.Info(StringChange.ModeToJson(datastation)); //var datastationid = SqlSugarClient.Queryable().First(it => it.Partsns.Contains(barcode)); //datastationparam数据存表 Datastationparam datastationparam1 = new Datastationparam() { Dsid = id, Productid = dataproduce.Productid, Stationid = StationCode, N = data1.n, T = false, V = data1.v, Ng = data1.ng == 0?1:0, Max = data1.max, Min = data1.min, Stime = datastation.Stime, Ngcode = "OK" }; Datastationparam datastationparam2 = new Datastationparam() { Dsid = id, Productid = dataproduce.Productid, Stationid = StationCode, N = data2.n, T = false, V = data2.v, Ng = data2.ng == 0 ? 1 : 0, Max = data2.max, Min = data2.min, Stime = datastation.Stime, Ngcode = "OK" }; Datastationparam datastationparam3 = new Datastationparam() { Dsid = id, Productid = dataproduce.Productid, Stationid = StationCode, N = data3.n, T = false, V = data3.v, Ng = data3.ng == 0 ? 1 : 0, Max = data3.max, Min = data3.min, Stime = datastation.Stime, Ngcode = "OK" }; Datastationparam datastationparam4 = new Datastationparam() { Dsid = id, Productid = dataproduce.Productid, Stationid = StationCode, N = data4.n, T = false, V = data4.v, Ng = data4.ng == 0 ? 1 : 0, Max = data4.max, Min = data4.min, Stime = datastation.Stime, Ngcode = "OK" }; Datastationparam datastationparam5 = new Datastationparam() { Dsid = id, Productid = dataproduce.Productid, Stationid = StationCode, N = data5.n, T = false, V = data5.v, Ng = data5.ng == 0 ? 1 : 0, Max = data5.max, Min = data5.min, Stime = datastation.Stime, Ngcode = "OK" }; int flag1 = SqlSugarClient.Insertable(datastationparam1).ExecuteReturnIdentity(); int flag2 = SqlSugarClient.Insertable(datastationparam2).ExecuteReturnIdentity(); int flag3 = SqlSugarClient.Insertable(datastationparam3).ExecuteReturnIdentity(); int flag4 = SqlSugarClient.Insertable(datastationparam4).ExecuteReturnIdentity(); int flag5 = SqlSugarClient.Insertable(datastationparam5).ExecuteReturnIdentity(); SqlSugarClient.AsTenant().CommitTran(); } } catch (Exception ex) { SqlSugarClient.AsTenant().RollbackTran(); _logger.Error($"存盘异常{ex.Message}"); } } /// /// 查询上工位是否有数据,无数据或NG则下发PLC报警提示 /// /// private async void SelectStationQuality(PlcAbsractFactory Plc) { try { byte[] SemBarCode = Plc.readValueByAddress(_semiBarcode1, 20); string ZZBarCode = ByteTransform.TransString(SemBarCode, 0, 20, Encoding.ASCII); _logger.Info("转子码:" + ZZBarCode); DatastationLocal datastation = IsExistData(ZZBarCode); if (datastation != null) { if (datastation.Ng != 0) { _logger.Info("上工位不合格"); //下发PLC上工位不合格 Plc.writeInt16ByAddress(_completeAskAddress, 2); } else { //存盘 //前盖码 byte[] _QGBarcode = Plc.readValueByAddress(_semiBarcode2, 20); string QGBarCode = ByteTransform.TransString(_QGBarcode, 0, 20, Encoding.ASCII); _logger.Info("前盖码:" + QGBarCode); #region 根据前盖码查询Productid //根据前盖码查询Productid //下发PLC上工位合格 Plc.writeInt16ByAddress(_completeAskAddress, 1); _logger.Info(StationCode + "工作允许"); var Dipsn = SqlSugarClient.Queryable().First(it => it.Mainsn == QGBarCode); if (Dipsn != null) { var ZZBarcide = SqlSugarClient.Queryable().First(it => it.Mainsn == ZZBarCode); if (ZZBarcide != null) { ZZBarcide.Sysid = Dipsn.Productid; //ZZBarcide.Snlist = QGBarCode + "," + ZZBarCode; //ZZBarcide.Operseq = Dipsn.Operseq + "," + StationCode; int updateflag = SqlSugarClient.Updateable(ZZBarcide).ExecuteCommand(); } //Dipsn dipsn = new Dipsn() //{ // Type = Dipsn.Type, // Stime = DateTime.Now, // Sn = ZZBarCode, // Productid = Dipsn.Productid, //}; //int id = SqlSugarClient.Insertable(dipsn).ExecuteReturnIdentity(); } #endregion #region 查询datastation表,更新Productid /* var zzdata = SqlSugarClient.Queryable().First(it => it.Partsns.Contains(ZZBarCode)); if (zzdata != null) { zzdata.Productid = Dipsn.Productid; int UpdateDatastationFlag = SqlSugarClient.Updateable(zzdata).ExecuteCommand(); //更新datastationparam表Productid字段 List AllDatastationparamList = await SqlSugarClient.Queryable().Where(x => x.Dsid == zzdata.Id).ToListAsync(); if (AllDatastationparamList != null) { AllDatastationparamList.ForEach(x => { string sql = "UPDATE datastationparam SET productid = '" + zzdata.Productid + " ' WHERE id = " + x.Id; int updateflag = SqlSugarClient.Ado.ExecuteCommand(sql); }); } }*/ #endregion //BarCodeRelationShipBinding(Plc); } } //上工位无数据 else { _logger.Info("上工位不合格"); //下发PLC上工位不合格 Plc.writeInt16ByAddress(_completeAskAddress, 2); } } catch (Exception ex) { _logger.Error($"上工位查询异常{ex.Message}"); } } /// /// PLC心跳检测,重连机制 /// private void StartCheckStatus() { Task.Run(async () => { while (true) { try { foreach (var plc in plcList) { PlcConfig? plcConfig = host.Services.GetService().plcConfig.FirstOrDefault(x => x.plcKey == plc.ConfigKey); if (plc != null && plc.IsConnected) { plc.IsConnected = plc.readHeartByAddress(_plcHeartBeatAddress); //DB100.DBX0.0 if (!plc.IsConnected) { plc.IsConnected = await plc.ConnectAsync(plcConfig.plcIp, plcConfig.plcPort); } } else { if (plcConfig != null) { bool result = await plc.ConnectAsync(plcConfig.plcIp, plcConfig.plcPort); plc.IsConnected = result; } } } } catch (Exception ex) { _logger.Error($"监听PLC设备状态异常:{ex.Message}"); } await Task.Delay(1000 * 10); } }); } #region 中际产线弃用逻辑 private bool TryObject(object value, out object[] arry) { arry = null; try { arry = (object[])value; return true; } catch (Exception ex) { return false; } } public stationPara ParaFormart(object[] obj, int paraCount) { byte[] bytes = obj.Select(o => Convert.ToByte(o)).ToArray(); string str = Convert.ToString(Convert.ToInt32(bytes[2]), 2).PadLeft(8, '0'); string[] items = new string[8]; for (int i = 0; i < items.Length; i++) { items[i] = str[i].ToString(); } Array.Reverse(items); //byte[] bools = ByteTransform.TransByte(bytes, 2,1); isConnect = Convert.ToInt32(items[0]) == 1; State = Convert.ToInt32(items[1]).ToString(); stationPara sinfo = new stationPara(); int index = 0; //是否重投 if (sinfo.Restart) { //ICSharpCode.Core.LoggingService.Info(StationInfo.StationCode + ",开始重投"); } //是否有主线二维码 sinfo.BarcodeUpdate = Convert.ToInt32(items[3]) == 1; //是否有支线二维码 sinfo.MaterialBarcodeUpdate = Convert.ToInt32(items[4]) == 1; index++; //自动模式 //重构,收到作业或放行请求才进行解析 //PLC工作请求信号 sinfo.AskWork = ByteTransform.TransInt16(bytes, 5) > 0; index++; //放行请求 sinfo.MaskID = ByteTransform.TransInt16(bytes, 7); sinfo.NewFlag = sinfo.MaskID > 0 ? true : false; index += 3; //当前机种号 sinfo.machineID = ByteTransform.TransByte(bytes, 13); string NewMachineID = sinfo.machineID.ToString(); index++; //托盘号 int intNum = ByteTransform.TransByte(bytes, 15); //支线条码状态 index++; bool[] bools2 = ByteTransform.TransBool(bytes, 16, 1); //ArrayList array2 = ConvertToList(bools2); //数据保存区 index++; sinfo.ProductOkNg = ByteTransform.TransByte(bytes, 19); index++; //线体代号ABC' int gongxu = ByteTransform.TransByte(bytes, 21); sinfo.RFIDNo = string.Format("{0:X}", gongxu) + intNum.ToString().PadLeft(2, '0'); index += 1; //sinfo.productDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");//这里不用日期了 if (sinfo.BarcodeUpdate || sinfo.MaterialBarcodeUpdate) { GetBarcodeList(bytes, index, ref sinfo); } index = 180; for (int i = 0; i < paraCount; i++) { dataUnite du = new dataUnite(); du.actValue = ByteTransform.TransSingle(bytes, index).ToString(); du.MaxValue = ByteTransform.TransSingle(bytes, index + 4).ToString(); du.MinValue = ByteTransform.TransSingle(bytes, index + 8).ToString(); du.result = ByteTransform.TransInt32(bytes, index + 12); du.Remark = ByteTransform.TransInt32(bytes, index + 16).ToString(); index += 20; sinfo.SavedataList.Add(du); } if (sinfo.MaskID == 1) { foreach (var row in sinfo.SavedataList) { Console.WriteLine("------------------------"); Console.WriteLine("|生产值:" + row.actValue + "|"); Console.WriteLine("------------------------"); } } return sinfo; } private void GetBarcodeList(byte[] buffer, int index, ref stationPara sinfo) { try { //获取条码支线信息 //for (int i = 1; i <= 5; i++) //{ // subLine sl = new subLine(); // sl.lineID = buffer[index + i].ToString(); // sl.barcode = ""; // sinfo.subLineList.Add(sl); //} //int barcodeLegth = 10;//设置单个条码长度 //获取主条码 byte[] bytes = new byte[20]; Array.Copy(buffer, 22, bytes, 0, 20); //ByteTransform.DataFormat = HslCommunication.Core.DataFormat.DCBA; //ByteTransform.IsStringReverseByteWord = true; //if (BitConverter.IsLittleEndian) //{ // Array.Reverse(bytes, 0, 4); // Array.Reverse(bytes, 4, 4); // Array.Reverse(bytes, 8, 4); // Array.Reverse(bytes, 12, 4); // Array.Reverse(bytes, 16, 4); //} sinfo.ProductBarcode = ByteTransform.TransString(bytes, 0, 20, Encoding.ASCII); } catch (Exception ex) { _logger.Error("条码信息获取失败:" + ex.ToString()); } } public object MCValue { get { return _mcValue; } set { if (value == null) { return; } //数据没有变化,直接返回 object[] objectarray; if (!TryObject(value, out objectarray)) { return; } if (value == _mcValue) { return; } _mcValue = value; _stationInfo.Data = ParaFormart(objectarray, 0); if (_stationInfo.Data.AskWork) { //这里需要判断上工位结果是否OK _logger.Info("工位:" + _stationInfo.StationCode + " 收到作业请求信号"); //PreWorkThread(); } ////有新数据 if (isConnect && _stationInfo.Data.NewFlag) { _logger.Info("工位:" + _stationInfo.StationCode + " 收到作业完成信号,开始上传数据。托盘号:" + _stationInfo.Data.RFIDNo); //OnRerefreshData(); } } } #endregion } }