master
CaesarBao 3 months ago
parent 3f7054e31f
commit 1b3d2657fd

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>

@ -0,0 +1,541 @@
using HslCommunication.Core;
using Mesnac.Compressor.Entity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json.Linq;
using SlnMesnac.Common;
using SlnMesnac.Config;
using SlnMesnac.Model.domain;
using SlnMesnac.Plc;
using SlnMesnac.Serilog;
using SqlSugar;
using System.Collections;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
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;
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系统启动成功!");
}
private void init()
{
try
{
switch (StationCode)
{
case "S130-1":
_plcHeartBeatAddress = "D7777";
_completeAskAddress = "D7703";
break;
case "S130-2":
_plcHeartBeatAddress = "D7777";
_workAskAddress = "";
_completeAskAddress = "";
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)
{
Plc.writeInt16ByAddress(_completeAskAddress, 0);
SaveStationDataTask(Plc);
}
break;
case "S130-2":
//读取PLC工作请求
if (Plc.readInt16ByAddress(_workAskAddress) == 1)
{
Plc.writeInt16ByAddress(_workAskAddress, 0);
//根据转子码查询上工位是否合格
SelectStationQuality(Plc);
}
//读取PLC放行请求
if (Plc.readInt16ByAddress(_completeAskAddress) == 1)
{
Plc.writeInt16ByAddress(_completeAskAddress, 0);
//存盘
}
break;
}
}
catch (Exception ex)
{
_logger.Error($"ListeningPlcValue方法异常:" + ex.StackTrace);
}
finally
{
Thread.Sleep(1000);
}
}
});
}
/// <summary>
/// 判断数据库表是否已存在条码数据,存在则更新,不存在则插入
/// </summary>
/// <param name="ProductBarCode"></param>
/// <returns></returns>
private Datastation IsExistData(string ProductBarCode)
{
Datastation datastation = null;
try
{
SqlSugarClient.Queryable<Datastation>().Any(x => x.Partsns.Contains(ProductBarCode));
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("D7701", 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()),
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()),
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()),
v = Plc.readFloatByAddress("D7713").ToString(),
min = Plc.readFloatByAddress("D7714").ToString(),
max = Plc.readFloatByAddress("D7715").ToString(),
};
D data4 = new D()
{
n = "转子压装位置4位移值",
t = 0,
ng = 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()),
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 LockFlag = SqlSugarClient.Updateable(datastation).ExecuteCommand();
Console.WriteLine(StringChange.ModeToJson(datastation));
_logger.Info(StringChange.ModeToJson(datastation));
}
else
{
datastation = new Datastation()
{
Stime = DateTime.Now,
Stationid = StationCode,
Productid = "",
Partid = "",
Modelid = "",
Ng = Plc.readFloatByAddress("D7708").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));
}
}
catch (Exception ex)
{
_logger.Error($"存盘异常{ex.Message}");
}
}
/// <summary>
/// 查询上工位是否有数据无数据或NG则下发PLC报警提示
/// </summary>
/// <param name="Plc"></param>
private async void SelectStationQuality(PlcAbsractFactory Plc)
{
try
{
byte[] SemBarCode = Plc.readValueByAddress("D7701", 20);
string ZZBarCode = ByteTransform.TransString(SemBarCode, 0, 20, Encoding.ASCII);
Datastation datastation = IsExistData(ZZBarCode);
if (datastation != null)
{
if (datastation.Ng != 0)
{
//下发PLC上工位不合格
Plc.writeInt16ByAddress("", 1);
}
}
//上工位无数据
else
{
//下发PLC上工位不合格
Plc.writeInt16ByAddress("", 1);
}
}
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
}
}

@ -8,22 +8,71 @@ using SlnMesnac.Extensions;
using Microsoft.AspNetCore.Hosting;
using Serilog;
using Autofac.Extensions.DependencyInjection;
using SlnMesnac.Serilog;
namespace ConsoleApp
{
internal class Program
{
private static SerilogHelper? serilogHelper;
static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();//生成宿主。
try
{
Thread.CurrentThread.Name = "Main";
Console.ForegroundColor = ConsoleColor.Yellow;
AppDomain.CurrentDomain.UnhandledException += GlobalExceptionHandler; //全局异常捕获
var host = CreateHostBuilder(args).Build();
host.StartAsync();
var appConfig = host.Services.GetService<AppConfig>();
var logPath = $"{appConfig.logPath}/Logs/{DateTime.UtcNow:yyyy-MM-dd}/";
Log.Information($"系统初始化完成,日志存放路径:{appConfig.logPath}");
Console.ReadLine();
var hostTask = host.RunAsync();
var appConfig = host.Services.GetService<AppConfig>();
//var logPath = $"{appConfig.logPath}/Logs/{DateTime.UtcNow:yyyy-MM-dd}/";
//Log.Information($"系统初始化完成,日志存放路径:{appConfig.logPath}");
serilogHelper = host.Services.GetRequiredService<SerilogHelper>();
MainCentralControl mainCentralControl = new MainCentralControl(host);
mainCentralControl.Start();
serilogHelper.Info("iMES系统启动成功");
while (true)
{
Console.ReadLine();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
if (serilogHelper != null)
{
serilogHelper.Error("系统启动失败,异常:" + ex.Message);
}
}
}
private static void GlobalExceptionHandler(object sender, UnhandledExceptionEventArgs e)
{
//当前线程名称
Thread.CurrentThread.Name = "Error";
if (e.ExceptionObject is Exception exception)
{
Console.WriteLine("全局异常捕获:");
Console.WriteLine(exception.Message);
Console.WriteLine(exception.StackTrace);
if (serilogHelper != null)
{
serilogHelper.Error("全局异常捕获:" + exception.Message + "\n" + exception.StackTrace);
}
}
else
{
Console.WriteLine("未知异常捕获:");
Console.WriteLine(e.ExceptionObject);
if (serilogHelper != null)
{
serilogHelper.Error("未知异常捕获:" + e.ExceptionObject);
}
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()

@ -43,6 +43,8 @@ namespace ConsoleApp
[Obsolete]
public void ConfigureServices(IServiceCollection services)
{
// 注册 SerilogHelper 服务
services.AddSingleton<SerilogHelper>();
services.AddControllers();
//注册AppConfig
@ -57,7 +59,7 @@ namespace ConsoleApp
services.AddSqlSugarSetup();
//注册PLC工厂
//services.AddPlcFactorySetup();
services.AddPlcFactorySetup();
//注册httpClient
//services.AddHostedService<AirPorthttpClient>();
@ -69,7 +71,7 @@ namespace ConsoleApp
//services.AddRfidFactorySetup();
//注册任务调度
services.AddQuartzSetUp();
//services.AddQuartzSetUp();
}

@ -8,41 +8,36 @@
},
"AllowedHosts": "*",
"AppConfig": {
"logPath": "F:\\Mesnac\\2023部门项目\\奥特佳-滁州3期\\源码\\HightWay_Middle_Ware\\ConsoleApp\\bin\\Debug\\net6.0\\log",
"logPath": "F:\\Mesnac\\2025\\奥特佳项目\\奥特佳中继产线MES\\物料绑定\\ConsoleApp\\bin\\Debug\\net6.0-windows\\log",
"SqlConfig": [
{
"configId": "mes",
"dbType": 1,
"connStr": "server=192.168.1.120;uid=sa;pwd=123456;database=ATJ_581_DB"
},
"dbType": 0,
//"connStr": "Data Source=119.45.202.115;Port=3306;Initial Catalog=db_iems;uid=root;pwd=haiwei@123;Charset=utf8mb4;SslMode=none;Connect Timeout=100"
"connStr": "Data Source=127.0.0.1;Port=3306;Initial Catalog=test;uid=root;pwd=123456;Charset=utf8mb4;SslMode=none;Connect Timeout=100"
}
//{
// "configId": "mcs",
// "dbType": 3,
// "connStr": "Data Source=175.27.215.92/helowin;User ID=aucma_scada;Password=aucma"
//},
{
"configId": "Local",
"dbType": 2,
"connStr": "Data Source=F:\\Mesnac\\2023部门项目\\奥特佳-滁州3期\\源码\\HightWay_Middle_Ware\\SlnMesnac.WPF\\bin\\Debug\\net6.0-windows\\data\\LSHData.db3"
}
//{
// "configId": "Local",
// "dbType": 2,
// "connStr": "Data Source=F:\\Mesnac\\2023部门项目\\奥特佳-滁州3期\\源码\\HightWay_Middle_Ware\\SlnMesnac.WPF\\bin\\Debug\\net6.0-windows\\data\\LSHData.db3"
//}
],
"PlcConfig": [
{
"configId": 1,
"plcType": "MelsecBinaryPlc",
"plcIp": "127.0.0.1",
"plcType": "OmronNJPlc",
"plcIp": "192.168.0.120",
//"plcIp": "127.0.0.1",
"plcPort": 6000,
"plcKey": "mcs",
"isFlage": true
},
{
"configId": 2,
"plcType": "MelsecBinaryPlc",
"plcIp": "127.0.0.1",
"plcPort": 6001,
"plcKey": "cwss",
"plcKey": "plc",
"isFlage": true
}
],
"RfidConfig": [
{
@ -60,30 +55,8 @@
"isFlage": true
}
],
"visionConfig": [
{
"VisionId": 1,
"VisionIp": "127.0.0.1",
"VisionPort": 7001,
"AGVID": "1",
"VisionState": "1",
"IsFlag": true
},
{
"VisionId": 2,
"VisionIp": "127.0.0.1",
"VisionPort": 7002,
"AGVID": "2",
"VisionState": "1",
"IsFlag": true
}
],
"AMRIP": "127.0.0.1",
"redisConfig": "175.27.215.92:6379,password=redis@2023",
"AGVIpConfig": "http://192.168.40.81:5102",
"TCPVisionConfig": "127.0.0.1:6000"
"StationCode": "S130-1"
}
}

@ -0,0 +1,319 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SqlSugar;
namespace Models
{
/// <summary>
/// 工位表
///</summary>
[SugarTable("cfgstationattr")]
public class Cfgstationattr
{
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="id" ,IsPrimaryKey = true,IsIdentity = true) ]
public int Id { get; set; }
/// <summary>
/// 备 注:工位配置顺序号
/// 默认值:
///</summary>
[SugarColumn(ColumnName="operid" ) ]
public int? Operid { get; set; }
/// <summary>
/// 备 注:工位代码
/// 默认值:
///</summary>
[SugarColumn(ColumnName="opercode" ) ]
public string? Opercode { get; set; }
/// <summary>
/// 备 注:工位名称
/// 默认值:
///</summary>
[SugarColumn(ColumnName="opername" ) ]
public string? Opername { get; set; }
/// <summary>
/// 备 注:工位类别:起始工位、普通工位、换线工位、停止工位、半成品停止工位
/// 默认值:
///</summary>
[SugarColumn(ColumnName="opertype" ) ]
public string? Opertype { get; set; }
/// <summary>
/// 备 注:线路id
/// 默认值:
///</summary>
[SugarColumn(ColumnName="lineid" ) ]
public int? Lineid { get; set; }
/// <summary>
/// 备 注:参数模板id
/// 默认值:
///</summary>
[SugarColumn(ColumnName="tempid" ) ]
public int? Tempid { get; set; }
/// <summary>
/// 备 注:工位流水线顺序号(缺省)
/// 默认值:
///</summary>
[SugarColumn(ColumnName="no" ) ]
public int? No { get; set; }
/// <summary>
/// 备 注:是否排出工位 0 -不是 1- 是
/// 默认值:
///</summary>
[SugarColumn(ColumnName="outng" ) ]
public SByte? Outng { get; set; }
/// <summary>
/// 备 注:是否是半成品投入位 0 -不是 1- 是
/// 默认值:
///</summary>
[SugarColumn(ColumnName="semistart" ) ]
public SByte? Semistart { get; set; }
/// <summary>
/// 备 注:半成品结束工位
/// 默认值:
///</summary>
[SugarColumn(ColumnName="semifinish" ) ]
public SByte? Semifinish { get; set; }
/// <summary>
/// 备 注:离线工位
/// 默认值:
///</summary>
[SugarColumn(ColumnName="bloffline" ) ]
public SByte? Bloffline { get; set; }
/// <summary>
/// 备 注:所属机种idmodelid
/// 默认值:
///</summary>
[SugarColumn(ColumnName="productid" ) ]
public int? Productid { get; set; }
/// <summary>
/// 备 注:当前状态:0 - 未启用,1-空闲
/// 默认值:
///</summary>
[SugarColumn(ColumnName="status" ) ]
public int? Status { get; set; }
/// <summary>
/// 备 注:PLC连接类型:0-三菱mc/slmp UDP协议; 1-欧姆龙 UDP协议3-西门子
/// 默认值:
///</summary>
[SugarColumn(ColumnName="plctype" ) ]
public int? Plctype { get; set; }
/// <summary>
/// 备 注:PLC数据区起始地址
/// 默认值:
///</summary>
[SugarColumn(ColumnName="addrstart" ) ]
public int? Addrstart { get; set; }
/// <summary>
/// 备 注:PLC ip地址
/// 默认值:
///</summary>
[SugarColumn(ColumnName="ip" ) ]
public string? Ip { get; set; }
/// <summary>
/// 备 注:tcp/udp 端口
/// 默认值:
///</summary>
[SugarColumn(ColumnName="port" ) ]
public int? Port { get; set; }
/// <summary>
/// 备 注:串口设备名
/// 默认值:
///</summary>
[SugarColumn(ColumnName="com" ) ]
public string? Com { get; set; }
/// <summary>
/// 备 注:波特率
/// 默认值:
///</summary>
[SugarColumn(ColumnName="baudrate" ) ]
public int? Baudrate { get; set; }
/// <summary>
/// 备 注:数据位
/// 默认值:
///</summary>
[SugarColumn(ColumnName="databits" ) ]
public int? Databits { get; set; }
/// <summary>
/// 备 注:校验位
/// 默认值:
///</summary>
[SugarColumn(ColumnName="parity" ) ]
public int? Parity { get; set; }
/// <summary>
/// 备 注:组态图用。当前操作状态: 正常生产,NG品排出NG品非排出等 -- 外键cfgoperstatus
/// 默认值:
///</summary>
[SugarColumn(ColumnName="curOperStatus" ) ]
public int? CurOperStatus { get; set; }
/// <summary>
/// 备 注:生产合格品数量
/// 默认值:
///</summary>
[SugarColumn(ColumnName="statNormalNum" ) ]
public int? StatNormalNum { get; set; }
/// <summary>
/// 备 注:生产非合格品数量
/// 默认值:
///</summary>
[SugarColumn(ColumnName="statNGNum" ) ]
public int? StatNGNum { get; set; }
/// <summary>
/// 备 注:当前操作生产人员ID
/// 默认值:
///</summary>
[SugarColumn(ColumnName="curoperid" ) ]
public string? Curoperid { get; set; }
/// <summary>
/// 备 注:连接方式 : 0 -网络;1-excel通过excel传递数据
/// 默认值:
///</summary>
[SugarColumn(ColumnName="auto" ) ]
public int? Auto { get; set; }
/// <summary>
/// 备 注:最后状态改变时间
/// 默认值:
///</summary>
[SugarColumn(ColumnName="ltime" ) ]
public DateTime? Ltime { get; set; }
/// <summary>
/// 备 注:最后读取的PLC数据区号
/// 默认值:
///</summary>
[SugarColumn(ColumnName="lastRegIndex" ) ]
public int? LastRegIndex { get; set; }
/// <summary>
/// 备 注:当前是否未连接;0-否,1-是
/// 默认值:
///</summary>
[SugarColumn(ColumnName="bcon" ) ]
public SByte? Bcon { get; set; }
/// <summary>
/// 备 注:当前是否自动:0-否,1-是
/// 默认值:
///</summary>
[SugarColumn(ColumnName="bauto" ) ]
public SByte? Bauto { get; set; }
/// <summary>
/// 备 注:当前产品是否重投:0-否,1-是
/// 默认值:
///</summary>
[SugarColumn(ColumnName="bret" ) ]
public SByte? Bret { get; set; }
/// <summary>
/// 备 注:适用机种用逗号分割例如机种1,机种2,机种3
/// 默认值:
///</summary>
[SugarColumn(ColumnName="appmode" ) ]
public string? Appmode { get; set; }
/// <summary>
/// 备 注:节拍指标(单位秒)
/// 默认值:
///</summary>
[SugarColumn(ColumnName="rhythm" ) ]
public int? Rhythm { get; set; }
/// <summary>
/// 备 注:PLC数据块编号
/// 默认值:
///</summary>
[SugarColumn(ColumnName="dbcode" ) ]
public int? Dbcode { get; set; }
/// <summary>
/// 备 注:PLC上报物料区起始地址
/// 默认值:
///</summary>
[SugarColumn(ColumnName="matstartaddr" ) ]
public int? Matstartaddr { get; set; }
/// <summary>
/// 备 注:该工位PLC挂接扫描枪只为本工位投料还是为全产线投料共用。0该工位独用1产线共用。
/// 默认值:
///</summary>
[SugarColumn(ColumnName="fulllinescan" ) ]
public UInt32? Fulllinescan { get; set; }
/// <summary>
/// 备 注:上位机与PLC通信连接正常与否0连接断开1建立连接
/// 默认值:
///</summary>
[SugarColumn(ColumnName="commstatus" ) ]
public int? Commstatus { get; set; }
/// <summary>
/// 备 注:建立连接的时间
/// 默认值:
///</summary>
[SugarColumn(ColumnName="connecttime" ) ]
public DateTime? Connecttime { get; set; }
/// <summary>
/// 备 注:连接断开的时间
/// 默认值:
///</summary>
[SugarColumn(ColumnName="disconnecttime" ) ]
public DateTime? Disconnecttime { get; set; }
/// <summary>
/// 备 注:超时未连接的次数累计默认大于2秒为超时界面可清零
/// 默认值:
///</summary>
[SugarColumn(ColumnName="timeoutnum" ) ]
public int? Timeoutnum { get; set; }
/// <summary>
/// 备 注:连接断开的次数累计,界面可清零
/// 默认值:
///</summary>
[SugarColumn(ColumnName="disconectnum" ) ]
public int? Disconectnum { get; set; }
/// <summary>
/// 备 注:暂不用预留。该工位产品类别针对机种下的首工位是主产品还是部件1主产品2一级部件3二级部件4其他。
/// 默认值:
///</summary>
[SugarColumn(ColumnName="statpdtype" ) ]
public int? Statpdtype { get; set; }
}
}

@ -0,0 +1,151 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SqlSugar;
namespace SlnMesnac.Model.domain
{
/// <summary>
/// 产品生产工位全过程数据(对于同一工位下同一产品码,可能有多条不同记录),表结构完全同datastationcur
///</summary>
[SugarTable("datastation")]
public class Datastation
{
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="id" ,IsPrimaryKey = true,IsIdentity = true) ]
public int Id { get; set; }
/// <summary>
/// 备 注:工位码
/// 默认值:
///</summary>
[SugarColumn(ColumnName="stationid" ) ]
public string? Stationid { get; set; }
/// <summary>
/// 备 注:产品码
/// 默认值:
///</summary>
[SugarColumn(ColumnName="productid" ) ]
public string? Productid { get; set; }
/// <summary>
/// 备 注:部件码
/// 默认值:
///</summary>
[SugarColumn(ColumnName="partid" ) ]
public string? Partid { get; set; }
/// <summary>
/// 备 注:机种码
/// 默认值:
///</summary>
[SugarColumn(ColumnName="modelid" ) ]
public string? Modelid { get; set; }
/// <summary>
/// 备 注:记录时间
/// 默认值:
///</summary>
[SugarColumn(ColumnName="stime" ) ]
public DateTime? Stime { get; set; }
/// <summary>
/// 备 注:是否NG0 非NG1 NG品
/// 默认值:
///</summary>
[SugarColumn(ColumnName="ng" ) ]
public int Ng { get; set; }
/// <summary>
/// 备 注:过程描述 0 正常1 NG品未加工2 - NG品排出
/// 默认值:
///</summary>
[SugarColumn(ColumnName="proc" ) ]
public int Proc { get; set; }
/// <summary>
/// 备 注:支线数
/// 默认值:
///</summary>
[SugarColumn(ColumnName="sublinenum" ) ]
public int? Sublinenum { get; set; }
/// <summary>
/// 备 注:支线条码数
/// 默认值:
///</summary>
[SugarColumn(ColumnName="sublinesnnum" ) ]
public int? Sublinesnnum { get; set; }
/// <summary>
/// 备 注:部件条码数
/// 默认值:
///</summary>
[SugarColumn(ColumnName="partsnnum" ) ]
public int? Partsnnum { get; set; }
/// <summary>
/// 备 注:操作员ID
/// 默认值:
///</summary>
[SugarColumn(ColumnName="operid" ) ]
public string? Operid { get; set; }
/// <summary>
/// 备 注:支线id,json格式:{ids:[1,2,3]}
/// 默认值:
///</summary>
[SugarColumn(ColumnName="sublineids" ) ]
public string? Sublineids { get; set; }
/// <summary>
/// 备 注:部件条码json格式{'sn':['10001','10002','20008']}
/// 默认值:
///</summary>
[SugarColumn(ColumnName="partsns" ) ]
public string? Partsns { get; set; }
/// <summary>
/// 备 注:支线条码json格式{'sn':['10001','10002','20008']}
/// 默认值:
///</summary>
[SugarColumn(ColumnName="sublinesns" ) ]
public string? Sublinesns { get; set; }
/// <summary>
/// 备 注:参数数据,json格式。 {"d":[{"v":1.2,"max":2.0,"min":1.0,"ng":1},{}]}
/// 默认值:
///</summary>
[SugarColumn(ColumnName="paratemp" ) ]
public string? Paratemp { get; set; }
/// <summary>
/// 备 注:字符串参数。json:{"str":["1111","2222"]}
/// 默认值:
///</summary>
[SugarColumn(ColumnName="stringtemp" ) ]
public string? Stringtemp { get; set; }
/// <summary>
/// 备 注:工位组,同一线路,相同工序号的工位放在一个工位组里,以 ","号分隔
/// 默认值:
///</summary>
[SugarColumn(ColumnName="groupStationId" ) ]
public string? GroupStationId { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="renum" ) ]
public string? Renum { get; set; }
}
}

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SqlSugar;
namespace SlnMesnac.Model.domain
{
/// <summary>
/// 工位数据参数值
///</summary>
[SugarTable("datastationparam")]
public class Datastationparam
{
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="id" ,IsPrimaryKey = true,IsIdentity = true) ]
public int Id { get; set; }
/// <summary>
/// 备 注:datastation表索引id
/// 默认值:
///</summary>
[SugarColumn(ColumnName="dsid" ) ]
public int Dsid { get; set; }
/// <summary>
/// 备 注:工位号
/// 默认值:
///</summary>
[SugarColumn(ColumnName="stationid" ,IsPrimaryKey = true) ]
public string Stationid { get; set; } = null!;
/// <summary>
/// 备 注:产品系统号
/// 默认值:
///</summary>
[SugarColumn(ColumnName="productid" ,IsPrimaryKey = true) ]
public string Productid { get; set; } = null!;
/// <summary>
/// 备 注:参数名
/// 默认值:
///</summary>
[SugarColumn(ColumnName="n" ) ]
public string? N { get; set; }
/// <summary>
/// 备 注:数据类别0 数值浮点数1 整数
/// 默认值:
///</summary>
[SugarColumn(ColumnName="t" ) ]
public bool T { get; set; }
/// <summary>
/// 备 注:数据
/// 默认值:
///</summary>
[SugarColumn(ColumnName="v" ) ]
public string? V { get; set; }
/// <summary>
/// 备 注:最大值
/// 默认值:
///</summary>
[SugarColumn(ColumnName="max" ) ]
public string Max { get; set; } = null!;
/// <summary>
/// 备 注:最小值
/// 默认值:
///</summary>
[SugarColumn(ColumnName="min" ) ]
public string? Min { get; set; }
/// <summary>
/// 备 注:是否NG品1:OK品2:NG品
/// 默认值:
///</summary>
[SugarColumn(ColumnName="ng" ) ]
public bool? Ng { get; set; }
/// <summary>
/// 备 注:记录时间
/// 默认值:
///</summary>
[SugarColumn(ColumnName="stime" ) ]
public DateTime Stime { get; set; }
/// <summary>
/// 备 注:缺省null在v比较上下限后超限则拼接"工位号"“参数名”"NG+或NG-或NG其他”
/// 默认值:
///</summary>
[SugarColumn(ColumnName="ngcode" ) ]
public string? Ngcode { get; set; }
}
}

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SqlSugar;
namespace SlnMesnac.Model.domain
{
/// <summary>
/// 使用过的条码记录一旦成品或半成品就从tmpsnpid导入dipsn
///</summary>
[SugarTable("dipsn")]
public class Dipsn
{
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="id" ,IsPrimaryKey = true,IsIdentity = true) ]
public int Id { get; set; }
/// <summary>
/// 备 注:条码
/// 默认值:
///</summary>
[SugarColumn(ColumnName="sn" ) ]
public string? Sn { get; set; }
/// <summary>
/// 备 注:产品码
/// 默认值:
///</summary>
[SugarColumn(ColumnName="productid" ) ]
public string? Productid { get; set; }
/// <summary>
/// 备 注:产品类别0-暂空1-从主线下来的完成品2-半成品5-已被装配到主线上的半成品
/// 默认值:
///</summary>
[SugarColumn(ColumnName="type" ) ]
public int Type { get; set; }
/// <summary>
/// 备 注:SN使用时间。产品完成时间
/// 默认值:
///</summary>
[SugarColumn(ColumnName="stime" ) ]
public DateTime? Stime { get; set; }
}
}

@ -0,0 +1,220 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Mesnac.Compressor.Entity
{
/// <summary>
/// 单工位保存数据
/// </summary>
public class stationPara
{
#region 显示数据
private string _state = "";
public string state
{
get
{
return _state;
}
set
{
_state = value;
}
}
/// <summary>
/// 检测值
/// </summary>
private string _data = "";
public string data
{
get
{
return _data;
}
set
{
_data = value;
}
}
#endregion
#region 保存数据
//工作完成信号
public bool NewFlag = false;
//工作请求信号
public bool AskWork= false;
public bool QGCT = false;
public bool subLine1 = false;
public bool subLine2 = false;
public bool subLine3 = false;
/// <summary>
/// 动盘扫码枪开关信号
/// </summary>
public bool DP_OpenFlag = false;
/// <summary>
/// 当前工位是否重做
/// </summary>
public bool ReWork = false;
/// <summary>
/// 是否重投
/// </summary>
public bool Restart = false;
/// <summary>
///
/// </summary>
public bool BarcodeUpdate = false;
/// <summary>
/// 物料条码是否上传
/// </summary>
public bool MaterialBarcodeUpdate = false;
/// <summary>
/// 支线条码上传
/// </summary>
public bool ZhiXianBarUp = false;
/// <summary>
/// 物料条码
/// </summary>
public string MaterialBarcode = "";
/// <summary>
/// 产品状态
/// </summary>
public int ProductOkNg = 0;
/// <summary>
/// 机种ID
/// </summary>
public int machineID = 0;
/// <summary>
/// 任务号
/// </summary>
public int MaskID = 0;
public string RFIDNo
{
get;
set;
}
public string productDate
{
get;
set;
}
public string semibacode = "";
public string MainBarcode = "";
public string ProductBarcode = "";
private List<dataUnite> _savedatalist = new List<dataUnite>();
public List<dataUnite> SavedataList
{
get
{
return _savedatalist;
}
set
{
_savedatalist = value;
}
}
#endregion
public List<subLine> subLineList = new List<subLine>();
}
public class subLine
{
public string lineID = "";
public string barcode = "";
}
public class dataUnite
{
public string actValue { get; set; }
public string MaxValue { get; set; }
public string MinValue { get; set; }
public int result { get; set; }
public string Remark { get; set; }
}
public class StationInfo
{
public string stationID = "";
public string StationCode = "";
public string StationName = "";
public string TableName = "";
public string PreTableName = "";
public int ParaCount = 0;
public string StationType = "";
//add by yinzf 2023-3-2
//设备对应PLC的名称A1
public string PLCName = "";
/// <summary>
/// PLC地址块号
/// </summary>
public int PLCBlock = 0;
public bool NGTakeStation = true;
//end add
public string lineID = "";
public string barcodeHead = "";
public bool IfMainline
{ get; set; }//是否是主线
/// <summary>
/// 数据处理是否处理
/// </summary>
public bool handle = true;
public stationPara Data = new stationPara();
}
public class MachineInfo
{
public string MachineName = "";
public string MachineID = "";
public int stationCount = 0;
public StationInfo StationOne = new StationInfo();
public StationInfo StationTwo = new StationInfo();
}
}

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SlnMesnac.Model.domain
{
public class partsns
{
/// <summary>
///
/// </summary>
public List<string> sn = new List<string>();
}
public class D
{
/// <summary>
/// 销钉1压装终点位移
/// </summary>
public string n { get; set; }
/// <summary>
///
/// </summary>
public int t { get; set; }
/// <summary>
///
/// </summary>
public string v { get; set; }
/// <summary>
///
/// </summary>
public string max { get; set; }
/// <summary>
///
/// </summary>
public string min { get; set; }
/// <summary>
///
/// </summary>
public int ng { get; set; }
}
public class Root
{
/// <summary>
///
/// </summary>
public List<D> d = new List<D>();
}
}

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using HslCommunication;
using HslCommunication.Profinet.Inovance;
using SlnMesnac.Common;
@ -342,5 +343,25 @@ namespace SlnMesnac.Plc.Factory
throw new InvalidOperationException($"根据地址:{address};写入double数据异常{ex.Message}");
}
}
public override Task<bool> ConnectAsync(string ip, int port)
{
throw new NotImplementedException();
}
public override object[] readObjectValueByAddress(string address, int len)
{
throw new NotImplementedException();
}
public override float readFloatByAddress(string address)
{
throw new NotImplementedException();
}
public override bool readHeartByAddress(string address)
{
throw new NotImplementedException();
}
}
}

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using HslCommunication;
using HslCommunication.Profinet.Melsec;
using SlnMesnac.Common;
@ -283,5 +284,25 @@ namespace SlnMesnac.Plc.Factory
throw new InvalidOperationException($"根据地址:{address};写入double数据异常{ex.Message}");
}
}
public override Task<bool> ConnectAsync(string ip, int port)
{
throw new NotImplementedException();
}
public override object[] readObjectValueByAddress(string address, int len)
{
throw new NotImplementedException();
}
public override float readFloatByAddress(string address)
{
throw new NotImplementedException();
}
public override bool readHeartByAddress(string address)
{
throw new NotImplementedException();
}
}
}

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using HslCommunication;
using HslCommunication.Profinet.Omron;
using SlnMesnac.Common;
@ -31,13 +32,14 @@ namespace SlnMesnac.Plc.Factory
{
private StringChange _stringChange;
private OmronFinsNet omronFinsNet = null;
private OmronCipNet omronFinsNet = null;
public OmronNJFactory(StringChange stringChange)
{
_stringChange = stringChange;
this.omronFinsNet = new OmronFinsNet();
this.omronFinsNet = new OmronCipNet();
this.omronFinsNet.ConnectTimeOut = 2000;
}
@ -55,10 +57,10 @@ namespace SlnMesnac.Plc.Factory
try
{
omronFinsNet.IpAddress = iP;
omronFinsNet.Port = 9600;
omronFinsNet.SA1 = (byte)192;
omronFinsNet.DA1 = (byte)239;
omronFinsNet.DA2 = (byte)0;
omronFinsNet.Port = 44818;
//omronFinsNet.SA1 = (byte)192;
//omronFinsNet.DA1 = (byte)239;
//omronFinsNet.DA2 = (byte)0;
OperateResult connect = omronFinsNet.ConnectServer();
this.IsConnected = connect.IsSuccess;
if (!connect.IsSuccess)
@ -104,16 +106,22 @@ namespace SlnMesnac.Plc.Factory
/// <param name="len"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public override byte[] readValueByAddress(string address, int len)
public override object[] readObjectValueByAddress(string address, int len)
{
try
{
object[] buff = null;
OperateResult<byte[]> read = omronFinsNet.Read(address, (ushort)(len));
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取指定长度数据失败:{read.Message}");
}
return _stringChange.ConvertFloatToINt(read.Content);
buff = new object[read.Content.Length];
for (int i = 0; i < read.Content.Length; i++)
{
buff[i] = read.Content[i];
}
return buff;
}
catch (Exception ex)
{
@ -134,7 +142,7 @@ namespace SlnMesnac.Plc.Factory
OperateResult<short> read = omronFinsNet.ReadInt16(address);
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取int16数据失败{read.Content}");
throw new InvalidOperationException($"根据地址:{address};读取int16数据失败{read.Message}");
}
return read.Content;
}
@ -182,7 +190,7 @@ namespace SlnMesnac.Plc.Factory
OperateResult<String> read = omronFinsNet.ReadString(address, length);
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取string数据失败{read.Content}");
throw new InvalidOperationException($"根据地址:{address};读取string数据失败{read.Message}");
}
return read.Content;
}
@ -229,7 +237,7 @@ namespace SlnMesnac.Plc.Factory
OperateResult<bool> read = omronFinsNet.ReadBool(address);
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取bool数据失败{read.Content}");
throw new InvalidOperationException($"根据地址:{address};读取bool数据失败{read.Message}");
}
return read.Content;
}
@ -286,5 +294,81 @@ namespace SlnMesnac.Plc.Factory
throw new InvalidOperationException($"根据地址:{address};写入double数据异常{ex.Message}");
}
}
public override async Task<bool> ConnectAsync(string ip, int port)
{
try
{
omronFinsNet.IpAddress = ip;
omronFinsNet.Port = 44818;
//omronFinsNet.SA1 = (byte)192;
//omronFinsNet.DA1 = (byte)239;
//omronFinsNet.DA2 = (byte)0;
OperateResult connect = await omronFinsNet.ConnectServerAsync();
this.IsConnected = connect.IsSuccess;
if (!connect.IsSuccess)
{
throw new InvalidOperationException($"欧姆龙PLC连接失败:{connect.Message}");
}
return connect.IsSuccess;
}
catch (Exception ex)
{
Console.WriteLine($"欧姆龙PLC连接异常{ex.Message}");
return false;
}
}
public override byte[] readValueByAddress(string address, int len)
{
try
{
OperateResult<byte[]> read = omronFinsNet.Read(address, (ushort)(len));
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取指定长度数据失败:{read.Message}");
}
return read.Content;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};读取指定长度数据异常:{ex.Message}");
}
}
public override float readFloatByAddress(string address)
{
try
{
OperateResult<float> read = omronFinsNet.ReadFloat(address);
if (!read.IsSuccess)
{
throw new InvalidOperationException($"根据地址:{address};读取float数据失败{read.Message}");
}
return read.Content;
}
catch (Exception ex)
{
throw new InvalidOperationException($"根据地址:{address};读取float数据异常{ex.Message}");
}
}
public override bool readHeartByAddress(string address)
{
try
{
OperateResult<bool> read = omronFinsNet.ReadBool(address);
if (!read.IsSuccess)
{
return false;
}
return true;
}
catch (Exception ex)
{
return false;
}
}
}
}

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using HslCommunication;
using HslCommunication.Profinet.Siemens;
using SlnMesnac.Common;
@ -283,5 +284,25 @@ namespace SlnMesnac.Plc.Factory
throw new InvalidOperationException($"根据地址:{address};写入double数据异常{ex.Message}");
}
}
public override Task<bool> ConnectAsync(string ip, int port)
{
throw new NotImplementedException();
}
public override object[] readObjectValueByAddress(string address, int len)
{
throw new NotImplementedException();
}
public override float readFloatByAddress(string address)
{
throw new NotImplementedException();
}
public override bool readHeartByAddress(string address)
{
throw new NotImplementedException();
}
}
}

@ -20,6 +20,8 @@
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
using System.Threading.Tasks;
namespace SlnMesnac.Plc
{
public abstract class PlcAbsractFactory
@ -39,7 +41,13 @@ namespace SlnMesnac.Plc
/// <param name="port"></param>
/// <returns></returns>
public abstract bool Connect(string ip, int port);
/// <summary>
/// 异步建立连接
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
public abstract Task<bool> ConnectAsync(string ip, int port);
/// <summary>
/// 断开连接
/// </summary>
@ -105,5 +113,11 @@ namespace SlnMesnac.Plc
/// <param name="value"></param>
/// <returns></returns>
public abstract bool writeDoubleByAddress(string address, int value);
public abstract object[] readObjectValueByAddress(string address, int len);
public abstract float readFloatByAddress(string address);
public abstract bool readHeartByAddress(string address);
}
}

@ -0,0 +1,15 @@
using Models;
using SlnMesnac.Repository.service.@base;
using SlnMesnac.Repository.service.Impl;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace SlnMesnac.Repository.service
{
public interface ICfgstationattrService : IBaseService<Cfgstationattr>
{
Task<List<Cfgstationattr>> GetTableListAsync();
}
}

@ -0,0 +1,38 @@
using Models;
using SlnMesnac.Common;
using SlnMesnac.Repository.service.@base;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace SlnMesnac.Repository.service.Impl
{
public class CfgstationattrServiceImpl : BaseServiceImpl<Cfgstationattr>, ICfgstationattrService
{
private Repository<Cfgstationattr> _repository;
public CfgstationattrServiceImpl(Repository<Cfgstationattr> rep) : base(rep)
{
_repository = rep;
}
public async Task<List<Cfgstationattr>> GetTableListAsync()
{
List<Cfgstationattr> list = null;
try
{
Expression<Func<Cfgstationattr, bool>> exp = x => true;
exp = exp.And(x =>
(x.Opername != "")
);
list = _repository.GetList(exp);
}
catch (Exception ex)
{
}
return list;
}
}
}

@ -0,0 +1,50 @@
using Serilog.Core;
using Serilog.Events;
namespace SlnMesnac.Serilog
{
// 自定义日志级别缩写增强器
public class CustomLogLevelAbbreviationEnricher : ILogEventEnricher
{
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
string abbreviation;
switch (logEvent.Level)
{
case LogEventLevel.Verbose:
abbreviation = "VRB";
break;
case LogEventLevel.Debug:
abbreviation = "DBG";
break;
case LogEventLevel.Information:
abbreviation = "INF";
break;
case LogEventLevel.Warning:
abbreviation = "WRN";
break;
case LogEventLevel.Error:
abbreviation = "ERR";
break;
case LogEventLevel.Fatal:
abbreviation = "FTL";
break;
//case (LogEventLevel)35: // 自定义的 AgvLevel
// abbreviation = "AGV";
// break;
default:
abbreviation = logEvent.Level.ToString();
break;
}
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("LevelAbbreviation", abbreviation));
}
}
}

@ -1,5 +1,4 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Serilog.Events;
using SlnMesnac.Config;
@ -7,6 +6,7 @@ using System;
using System.IO;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
@ -27,7 +27,9 @@ using System.IO;
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.Serilog
{
/// <summary>
@ -35,27 +37,77 @@ namespace SlnMesnac.Serilog
/// </summary>
public static class SerilogExtensions
{
// 定义自定义日志级别
public static readonly LogEventLevel AgvLevel = (LogEventLevel)35;
//public static IApplicationBuilder UseSerilogExtensions(this IApplicationBuilder app)
//{
// // 获取当前程序所在的目录
// string currentDirectory = Directory.GetCurrentDirectory();
// Log.Logger = new LoggerConfiguration()
// .MinimumLevel.Verbose() // 确保能捕获所有级别日志
// .Enrich.With(new CustomLogLevelAbbreviationEnricher()) // 添加自定义日志级别缩写增强器
// .WriteTo.Console(
// outputTemplate: "{Timestamp:MM-dd HH:mm:ss} [{LevelAbbreviation}] [{ClassName}] [{LineNumber}] {Message:lj}{NewLine}{Exception}",
// restrictedToMinimumLevel: LogEventLevel.Error
// )
// // retainedFileCountLimit: 3, // 保留最近3天日志
// .WriteTo.File(path: GetDynamicLogPath("Info"), retainedFileCountLimit: 3, restrictedToMinimumLevel: LogEventLevel.Information, rollingInterval: RollingInterval.Day, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{ClassName}] [{LineNumber}] {Message:lj}{NewLine}{Exception}")
// .WriteTo.File(path: GetDynamicLogPath("Error"), retainedFileCountLimit: 3, restrictedToMinimumLevel: LogEventLevel.Error, rollingInterval: RollingInterval.Day, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{ClassName}] [{LineNumber}] {Message:lj}{NewLine}{Exception}")
// .WriteTo.File(path: GetDynamicLogPath("Agv"), retainedFileCountLimit: 3, restrictedToMinimumLevel: AgvLevel, rollingInterval: RollingInterval.Day, outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{ClassName}] [{LineNumber}] {Message:lj}{NewLine}{Exception}") // 新增 Agv 日志文件
// .CreateLogger();
// // 启用 Serilog 中间件
// app.UseSerilogRequestLogging();
// return app;
//}
public static IApplicationBuilder UseSerilogExtensions(this IApplicationBuilder app)
{
//启用Serilog中间件
app.UseSerilogRequestLogging();
// 获取当前程序所在的目录
string currentDirectory = Directory.GetCurrentDirectory();
var logPath = Path.Combine(currentDirectory, "Logs");
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Verbose() // 确保能捕获所有级别日志
.Enrich.With(new CustomLogLevelAbbreviationEnricher()) // 添加自定义日志级别缩写增强器
.WriteTo.Console(
outputTemplate: "{Timestamp:MM-dd HH:mm:ss} [{LevelAbbreviation}] [{ClassName}] [{LineNumber}] {Message:lj}{NewLine}{Exception}",
restrictedToMinimumLevel: LogEventLevel.Error
#region 通过配置文件读取日志存放位置
var appConfig = app.ApplicationServices.GetService<AppConfig>();
var logPath = $"{appConfig.logPath}/Logs/";
#endregion
)
// retainedFileCountLimit: 3, // 保留最近3天日志
.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(logEvent => logEvent.Properties.ContainsKey("Module") && logEvent.Properties["Module"].ToString().Contains("Info"))
.WriteTo.File(Path.Combine($"{logPath}/Info/", "Info.log"), rollingInterval: RollingInterval.Day, retainedFileCountLimit: 3))
.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(logEvent => logEvent.Properties.ContainsKey("Module") && logEvent.Properties["Module"].ToString().Contains("Plc"))
.WriteTo.File(Path.Combine($"{logPath}/Plc/", "Plc.log"), rollingInterval: RollingInterval.Day, retainedFileCountLimit: 3))
.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(logEvent => logEvent.Properties.ContainsKey("Module") && logEvent.Properties["Module"].ToString().Contains("Agv"))
.WriteTo.File(Path.Combine($"{logPath}/Agv/", "Agv.log"), rollingInterval: RollingInterval.Day, retainedFileCountLimit: 3))
.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(logEvent => logEvent.Properties.ContainsKey("Module") && logEvent.Properties["Module"].ToString().Contains("Error"))
.WriteTo.File(Path.Combine($"{logPath}/Error/", "Error.log"), rollingInterval: RollingInterval.Day, retainedFileCountLimit: 3))
.CreateLogger();
Log.Logger = new LoggerConfiguration().MinimumLevel.Information().WriteTo.Console()
.WriteTo.File(Path.Combine(logPath, "Info.log"), LogEventLevel.Information,rollingInterval:RollingInterval.Day)
.WriteTo.File(Path.Combine(logPath, "Error.log"), LogEventLevel.Error, rollingInterval: RollingInterval.Day)
.WriteTo.File(Path.Combine(logPath, "data.log"), LogEventLevel.Warning, rollingInterval: RollingInterval.Day)
//.WriteTo.File(Path.Combine(logPath, "data.log"), LogEventLevel.Debug)
//.WriteTo.File(Path.Combine(logPath, "Debug.log"), LogEventLevel.Debug, fileSizeLimitBytes: 5 * 1024)
.CreateLogger();
// 启用 Serilog 中间件
app.UseSerilogRequestLogging();
return app;
}
// 新的动态路径生成方法
private static string GetDynamicLogPath(string logType)
{
return Path.Combine(
Directory.GetCurrentDirectory(),
"Logs",
$"{DateTime.UtcNow:yyyy-MM-dd}",
$"{logType}-.log"
);
}
}
}
}

@ -0,0 +1,114 @@
using Serilog;
using System;
using System.IO;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* T14-GEN3-7895
* SlnMesnac.Serilog
* fae9d68d-1992-4a03-b299-19edd9fc786d
*
* WenJY
*
* 2024-12-26 8:46:21
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.Serilog
{
/// <summary>
/// Serilog日志类
/// </summary>
public class SerilogHelper
{
private readonly ILogger Info_logger = Log.ForContext("Module", "Info");
private readonly ILogger Plc_logger = Log.ForContext("Module", "Plc");
private readonly ILogger Error_logger = Log.ForContext("Module", "Error");
//private readonly ILogger Agv_logger = Log.ForContext("Module", "Agv"); // 新增 Agv 日志记录器
/// <summary>
/// Info日志
/// </summary>
/// <param name="msg"></param>
/// <param name="callerFilePath"></param>
/// <param name="callerLineNumber"></param>
public void Info(string msg, [System.Runtime.CompilerServices.CallerFilePath] string callerFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int callerLineNumber = 0)
{
var className = Path.GetFileNameWithoutExtension(callerFilePath);
Info_logger.ForContext("ClassName", className).ForContext("LineNumber", callerLineNumber).Information(msg);
}
/// <summary>
/// Plc日志
/// </summary>
/// <param name="msg"></param>
/// <param name="callerFilePath"></param>
/// <param name="callerLineNumber"></param>
public void Plc(string msg, [System.Runtime.CompilerServices.CallerFilePath] string callerFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int callerLineNumber = 0)
{
var className = Path.GetFileNameWithoutExtension(callerFilePath);
Plc_logger.ForContext("ClassName", className).ForContext("LineNumber", callerLineNumber).Information(msg);
}
/// <summary>
/// Error日志
/// </summary>
/// <param name="msg"></param>
/// <param name="ex"></param>
/// <param name="callerFilePath"></param>
/// <param name="callerLineNumber"></param>
public void Error(string msg, Exception ex = null, [System.Runtime.CompilerServices.CallerFilePath] string callerFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int callerLineNumber = 0)
{
var className = Path.GetFileNameWithoutExtension(callerFilePath);
var logger = Error_logger.ForContext("ClassName", className).ForContext("LineNumber", callerLineNumber);
if (!string.IsNullOrEmpty(msg) && ex == null)
{
logger.Error("【附加信息】 : {0}<br>", msg);
}
else if (!string.IsNullOrEmpty(msg) && ex != null)
{
string errorMsg = BeautyErrorMsg(ex);
logger.Error("【附加信息】 : {0}<br>{1}", msg, errorMsg);
}
else if (string.IsNullOrEmpty(msg) && ex != null)
{
string errorMsg = BeautyErrorMsg(ex);
logger.Error(errorMsg);
}
}
/// <summary>
/// Agv日志
/// </summary>
/// <param name="msg"></param>
/// <param name="callerFilePath"></param>
/// <param name="callerLineNumber"></param>
//public void Agv(string msg, [System.Runtime.CompilerServices.CallerFilePath] string callerFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int callerLineNumber = 0)
//{
// var className = Path.GetFileNameWithoutExtension(callerFilePath);
// Agv_logger.ForContext("ClassName", className).ForContext("LineNumber", callerLineNumber).Write(SerilogExtensions.AgvLevel, msg);
//}
private string BeautyErrorMsg(Exception ex)
{
string errorMsg = string.Format("【异常类型】:{0} <br>【异常信息】:{1} <br>【堆栈调用】:{2}", ex.GetType().Name, ex.Message, ex.StackTrace);
errorMsg = errorMsg.Replace("\r\n", "<br>");
errorMsg = errorMsg.Replace("位置", "<strong style=\"color:red\">位置</strong>");
return errorMsg;
}
}
}

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>

@ -0,0 +1,57 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Models;
using NVelocity.Runtime.Directive;
using SlnMesnac.Repository.service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SlnMesnac.WPF.ViewModel.IndexPage
{
public partial class FirstContentViewModel : ObservableObject
{
private ILogger<FirstContentViewModel> _logger;
private ICfgstationattrService _cfgstationattrService;
public FirstContentViewModel()
{
_cfgstationattrService = App.ServiceProvider.GetService<ICfgstationattrService>();
Init();
}
private async Task Init()
{
List<Cfgstationattr> cfgstationattrs = await _cfgstationattrService.GetTableListAsync();
}
/// <summary>
/// 监听PLC地址值
/// </summary>
private void ListeningPlcValue()
{
try
{
}
catch (Exception ex)
{
}
}
private bool TryObject(object value, out object[] arry)
{
arry = null;
try
{
arry = (object[])value;
return true;
}
catch
{
return false;
}
}
}
}

@ -34,6 +34,7 @@ using System.Data;
using System.Dynamic;
using System.Drawing;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock;
using Models;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
@ -81,6 +82,7 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
private string WritePLCAddress = "D6000";
private String _lastCode = string.Empty;
private int stationid = 3;
private ICfgstationattrService _cfgstationattrService;
public IndexContentViewModel()
{
taskInfo = new TaskInfo1();
@ -100,10 +102,12 @@ namespace SlnMesnac.WPF.ViewModel.IndexPage
OKCount = _appSettings.ReadAppSettings("ProductConfig:OKCount");
//_appSettings.WriteAppSettings("ProductConfig", "OKCount", "2");
NGCount = _appSettings.ReadAppSettings("ProductConfig:NGCount");
_cfgstationattrService = App.ServiceProvider.GetService<ICfgstationattrService>();
this.Init();
}
private void Init()
private async Task Init()
{
List<Cfgstationattr> cfgstationattrs =await _cfgstationattrService.GetTableListAsync();
_controlOffLineScanHelper.RecAutoDataAction += ShowBarCode;
LoadStationInfo();
#region 测试数据

@ -12,9 +12,11 @@
"SqlConfig": [
{
"configId": "mes",
"dbType": 1,
"dbType": 0,
//"connStr": "server=192.168.1.120;uid=sa;pwd=123456;database=ATJ_581_DB"
"connStr": "server=119.45.202.115;uid=sa;pwd=haiwei@123;database=ATJ_581_DB"
//"connStr": "server=119.45.202.115;uid=sa;pwd=haiwei@123;database=ATJ_581_DB"
//"connStr": "server=119.45.202.115;uid=root;pwd=haiwei@123;database=db_iems",
"connStr": "Data Source=119.45.202.115;Port=3306;Initial Catalog=db_iems;uid=root;pwd=haiwei@123;Charset=utf8mb4;SslMode=none;Connect Timeout=100"
},
{
"configId": "Local",
@ -71,7 +73,7 @@
"ComPort": "COM1",
"StationCode": "150"
"StationCode": "200"
},
"ProductConfig": {
@ -79,7 +81,7 @@
"NGCount": "0"
},
"ChangeTypeConfig": {
"ProductType": "E34F",
"ProductType": "E34FU",
"KTProductType": "E34F",
"OpenFlag": "1"
}

Loading…
Cancel
Save