You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

728 lines
29 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using HslCommunication.Core;
using Mesnac.Compressor.Entity;
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.Serilog;
using SqlSugar;
using System.Collections;
using System.Diagnostics;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Xml.Linq;
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<PlcAbsractFactory> 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;
public MainCentralControl(IHost host)
{
this.host = host;
_appConfig = host.Services.GetService<AppConfig>();
StationCode = _appConfig.StationCode;
SqlSugarClient = host.Services.GetRequiredService<ISqlSugarClient>();
_logger = host.Services.GetRequiredService<SerilogHelper>();
plcList = host.Services.GetRequiredService<List<PlcAbsractFactory>>();
}
public void Start()
{
init();
StartCheckStatus();
ListeningPlcValue();
_logger.Info("iMES系统启动成功!");
}
/// <summary>
/// 初始化加载PLC地址不同工位PLC提供的地址不同
/// </summary>
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 = "D7777";
_completeAskAddress = "D7703";
_productBarcode = "D7700";
_semiBarcode1 = "D7701";
break;
}
}
catch (Exception ex)
{
}
}
/// <summary>
/// 监听PLC地址值
/// </summary>
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<Dataproduce>().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);
}
}
/// <summary>
/// 判断数据库表是否已存在条码数据,存在则更新,不存在则插入
/// </summary>
/// <param name="ProductBarCode"></param>
/// <returns></returns>
private Datastation IsExistData(string ProductBarCode)
{
Datastation datastation = null;
try
{
datastation = SqlSugarClient.Queryable<Datastation>().First(it => it.Partsns.Contains(ProductBarCode));
if (datastation != null)
{
return datastation;
}
return datastation;
}
catch (Exception ex)
{
return datastation;
}
}
/// <summary>
/// S130-1工位存盘
/// </summary>
/// <param name="Plc"></param>
private async void SaveStationDataTask(PlcAbsractFactory Plc)
{
try
{ //转子码
byte[] SemBarCode = Plc.readValueByAddress(_semiBarcode1, 20);
string barcode = ByteTransform.TransString(SemBarCode, 0, 20, Encoding.ASCII);
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 = IsExistData(barcode);
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 = "",
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",
};
//存盘
int id = SqlSugarClient.Insertable(datastation).ExecuteReturnIdentity();
Plc.writeInt16ByAddress("D7704", 1);
//Console.WriteLine(StringChange.ModeToJson(datastation));
_logger.Info(StringChange.ModeToJson(datastation));
var datastationid = SqlSugarClient.Queryable<Datastation>().First(it => it.Partsns.Contains(barcode));
//datastationparam数据存表
Datastationparam datastationparam1 = new Datastationparam()
{
Dsid = datastationid.Id,
Productid = StationCode,
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 = datastationid.Id,
Productid = StationCode,
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 = datastationid.Id,
Productid = StationCode,
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 = datastationid.Id,
Productid = StationCode,
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 = datastationid.Id,
Productid = StationCode,
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}");
}
}
/// <summary>
/// 查询上工位是否有数据无数据或NG则下发PLC报警提示
/// </summary>
/// <param name="Plc"></param>
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);
Datastation 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
var Dipsn = SqlSugarClient.Queryable<Dataproduce>().First(it => it.Mainsn == QGBarCode);
if (Dipsn != null)
{
Dipsn.Snlist = QGBarCode+","+ZZBarCode;
Dipsn.Operseq = Dipsn.Operseq+","+StationCode;
int updateflag = SqlSugarClient.Updateable(Dipsn).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<Datastation>().First(it => it.Partsns.Contains(ZZBarCode));
if (zzdata != null)
{
zzdata.Productid = Dipsn.Productid;
int UpdateDatastationFlag = SqlSugarClient.Updateable(zzdata).ExecuteCommand();
//更新datastationparam表Productid字段
List<Datastationparam> AllDatastationparamList = await SqlSugarClient.Queryable<Datastationparam>().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
//下发PLC上工位合格
Plc.writeInt16ByAddress(_completeAskAddress, 1);
//BarCodeRelationShipBinding(Plc);
}
}
//上工位无数据
else
{
_logger.Info("上工位不合格");
//下发PLC上工位不合格
Plc.writeInt16ByAddress(_completeAskAddress, 2);
}
}
catch (Exception ex)
{
_logger.Error($"上工位查询异常{ex.Message}");
}
}
/// <summary>
/// PLC心跳检测重连机制
/// </summary>
private void StartCheckStatus()
{
Task.Run(async () =>
{
while (true)
{
try
{
foreach (var plc in plcList)
{
PlcConfig? plcConfig = host.Services.GetService<AppConfig>().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
}
}