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#

2 months ago
using HslCommunication.Core;
using Mesnac.Compressor.Entity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
2 months ago
using Models;
2 months ago
using Newtonsoft.Json.Linq;
using SlnMesnac.Common;
using SlnMesnac.Config;
using SlnMesnac.Model.domain;
using SlnMesnac.Plc;
2 months ago
using SlnMesnac.Repository;
2 months ago
using SlnMesnac.Serilog;
using SqlSugar;
using System.Collections;
2 months ago
using System.Diagnostics;
2 months ago
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
2 months ago
using System.Xml.Linq;
2 months ago
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;
2 months ago
//PLC产品码地址
private string _productBarcode;
//PLC支线码1地址
private string _semiBarcode1;
//PLC支线码2地址
private string _semiBarcode2;
2 months ago
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系统启动成功!");
}
2 months ago
/// <summary>
/// 初始化加载PLC地址不同工位PLC提供的地址不同
/// </summary>
2 months ago
private async void init()
2 months ago
{
try
{
switch (StationCode)
{
case "S130-1":
_plcHeartBeatAddress = "D7777";
_completeAskAddress = "D7703";
2 months ago
_semiBarcode1 = "D7701";
2 months ago
break;
case "S130-2":
_plcHeartBeatAddress = "D7777";
2 months ago
_workAskAddress = "D7803";
_completeAskAddress = "D7804";
_productBarcode = "";
_semiBarcode1 = "D7801";
_semiBarcode2 = "D7802";
2 months ago
break;
2 months ago
case "A20":
_plcHeartBeatAddress = "D7777";
_completeAskAddress = "D7703";
_productBarcode = "D7700";
_semiBarcode1 = "D7701";
break;
2 months ago
}
}
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)
{
2 months ago
_logger.Info(StationCode+"放行请求");
2 months ago
Plc.writeInt16ByAddress(_completeAskAddress, 0);
SaveStationDataTask(Plc);
}
break;
case "S130-2":
//读取PLC工作请求
if (Plc.readInt16ByAddress(_workAskAddress) == 1)
{
2 months ago
_logger.Info(StationCode + "工作请求");
2 months ago
Plc.writeInt16ByAddress(_workAskAddress, 0);
//根据转子码查询上工位是否合格
SelectStationQuality(Plc);
}
break;
2 months ago
case "A20":
//读取PLC工作请求
if (Plc.readInt16ByAddress(_completeAskAddress) == 1)
{
_logger.Info(StationCode + "放行请求");
Plc.writeInt16ByAddress(_completeAskAddress, 0);
//根据转子码查询上工位是否合格
BarCodeRelationShipBinding(Plc);
}
break;
2 months ago
}
}
catch (Exception ex)
{
_logger.Error($"ListeningPlcValue方法异常:" + ex.StackTrace);
}
finally
{
Thread.Sleep(1000);
}
}
});
}
2 months ago
private void BarCodeRelationShipBinding(PlcAbsractFactory Plc)
{
try
{
2 months ago
//壳体码
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);
2 months ago
2 months ago
var Dipsn = SqlSugarClient.Queryable<Dataproduce>().First(it => it.Mainsn == KTBarCode);
if (Dipsn != null)
{
Dipsn.Snlist = Dipsn.Snlist + "," + DZBarCode;
int updateflag = SqlSugarClient.Updateable(Dipsn).ExecuteCommand();
}
2 months ago
}
catch (Exception ex)
{
_logger.Error($"BarCodeRelationShipBinding方法异常:" + ex.StackTrace);
}
}
2 months ago
/// <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
2 months ago
{ //转子码
2 months ago
byte[] SemBarCode = Plc.readValueByAddress(_semiBarcode1, 20);
2 months ago
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,
2 months ago
ng = int.Parse(Plc.readFloatByAddress("D7708").ToString()) == 1? 0 : 1,
2 months ago
v = Plc.readFloatByAddress("D7705").ToString(),
min = Plc.readFloatByAddress("D7706").ToString(),
max = Plc.readFloatByAddress("D7707").ToString(),
};
D data2 = new D()
{
n = "转子压装位置2压力值",
t = 0,
2 months ago
ng = int.Parse(Plc.readFloatByAddress("D7712").ToString()) == 1 ? 0 : 1,
2 months ago
v = Plc.readFloatByAddress("D7709").ToString(),
min = Plc.readFloatByAddress("D7710").ToString(),
max = Plc.readFloatByAddress("D7711").ToString(),
};
D data3 = new D()
{
n = "转子压装位置3压力值",
t = 0,
2 months ago
ng = int.Parse(Plc.readFloatByAddress("D7716").ToString()) == 1 ? 0 : 1,
2 months ago
v = Plc.readFloatByAddress("D7713").ToString(),
min = Plc.readFloatByAddress("D7714").ToString(),
max = Plc.readFloatByAddress("D7715").ToString(),
};
D data4 = new D()
{
n = "转子压装位置4位移值",
t = 0,
2 months ago
ng = int.Parse(Plc.readFloatByAddress("D7720").ToString()) == 1 ? 0 : 1,
2 months ago
v = Plc.readFloatByAddress("D7717").ToString(),
min = Plc.readFloatByAddress("D7718").ToString(),
max = Plc.readFloatByAddress("D7719").ToString(),
};
D data5 = new D()
{
n = "转子压装位置4压力值",
t = 0,
2 months ago
ng = int.Parse(Plc.readFloatByAddress("D7724").ToString()) == 1 ? 0 : 1,
2 months ago
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;
2 months ago
int InsertFlag = SqlSugarClient.Updateable(datastation).ExecuteCommand();
//Console.WriteLine(StringChange.ModeToJson(datastation));
2 months ago
_logger.Info(StringChange.ModeToJson(datastation));
}
else
{
2 months ago
SqlSugarClient.AsTenant().BeginTran();
2 months ago
datastation = new Datastation()
{
Stime = DateTime.Now,
Stationid = StationCode,
Productid = "",
Partid = "",
Modelid = "",
2 months ago
Ng = Plc.readInt16ByAddress("D7725").ToString() == "1" ? 0 : 1,
2 months ago
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);
2 months ago
//Console.WriteLine(StringChange.ModeToJson(datastation));
2 months ago
_logger.Info(StringChange.ModeToJson(datastation));
2 months ago
var datastationid = SqlSugarClient.Queryable<Datastation>().First(it => it.Partsns.Contains(barcode));
//datastationparam数据存表
Datastationparam datastationparam1 = new Datastationparam()
{
Dsid = datastationid.Id,
2 months ago
Productid = StationCode,
2 months ago
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,
2 months ago
Productid = StationCode,
2 months ago
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,
2 months ago
Productid = StationCode,
2 months ago
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,
2 months ago
Productid = StationCode,
2 months ago
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,
2 months ago
Productid = StationCode,
2 months ago
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();
2 months ago
}
2 months ago
2 months ago
}
catch (Exception ex)
{
2 months ago
SqlSugarClient.AsTenant().RollbackTran();
2 months ago
_logger.Error($"存盘异常{ex.Message}");
}
}
/// <summary>
/// 查询上工位是否有数据无数据或NG则下发PLC报警提示
/// </summary>
/// <param name="Plc"></param>
private async void SelectStationQuality(PlcAbsractFactory Plc)
{
try
{
2 months ago
byte[] SemBarCode = Plc.readValueByAddress(_semiBarcode1, 20);
2 months ago
string ZZBarCode = ByteTransform.TransString(SemBarCode, 0, 20, Encoding.ASCII);
2 months ago
_logger.Info("转子码:" + ZZBarCode);
2 months ago
Datastation datastation = IsExistData(ZZBarCode);
if (datastation != null)
{
if (datastation.Ng != 0)
{
2 months ago
_logger.Info("上工位不合格");
2 months ago
//下发PLC上工位不合格
2 months ago
Plc.writeInt16ByAddress(_completeAskAddress, 2);
}
else
{
//存盘
//前盖码
byte[] _QGBarcode = Plc.readValueByAddress(_semiBarcode2, 20);
string QGBarCode = ByteTransform.TransString(_QGBarcode, 0, 20, Encoding.ASCII);
_logger.Info("前盖码:" + QGBarCode);
2 months ago
#region 根据前盖码查询Productid
2 months ago
//根据前盖码查询Productid
2 months ago
var Dipsn = SqlSugarClient.Queryable<Dataproduce>().First(it => it.Mainsn == QGBarCode);
2 months ago
if (Dipsn != null)
{
2 months ago
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();
2 months ago
}
2 months ago
#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字段
2 months ago
2 months ago
List<Datastationparam> AllDatastationparamList = await SqlSugarClient.Queryable<Datastationparam>().Where(x => x.Dsid == zzdata.Id).ToListAsync();
if (AllDatastationparamList != null)
{
2 months ago
AllDatastationparamList.ForEach(x => {
string sql = "UPDATE datastationparam SET productid = '" + zzdata.Productid + " ' WHERE id = " + x.Id;
int updateflag = SqlSugarClient.Ado.ExecuteCommand(sql);
});
2 months ago
}
}
#endregion
2 months ago
//下发PLC上工位合格
Plc.writeInt16ByAddress(_completeAskAddress, 1);
//BarCodeRelationShipBinding(Plc);
2 months ago
}
}
//上工位无数据
else
{
2 months ago
_logger.Info("上工位不合格");
2 months ago
//下发PLC上工位不合格
2 months ago
Plc.writeInt16ByAddress(_completeAskAddress, 2);
2 months ago
}
}
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
}
}