From 5b7e5eee6c8da0a14bbde971737d809daf387975 Mon Sep 17 00:00:00 2001 From: SoulStar Date: Wed, 29 Oct 2025 18:40:26 +0800 Subject: [PATCH] =?UTF-8?q?feat=20-=20PLC=E4=B8=9A=E5=8A=A1=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sln.Iot.Business/RFID01Business.cs | 10 +- Sln.Iot.Business/RFID02Business.cs | 43 +++++-- Sln.Iot.Business/RFID03Business.cs | 73 ++++++++++++ Sln.Iot.Business/RFID04Business.cs | 111 ++++++++++++++++++ Sln.Iot.Business/RFID05Business.cs | 73 ++++++++++++ Sln.Iot.Business/RFID06Business.cs | 77 ++++++++++++ Sln.Iot.PLC/PLCConnect.cs | 2 + Sln.Iot.Repository/SqliteHelper.cs | 14 ++- Sln.Iot.Repository/dao/ProdDataBinding.cs | 41 +++++++ Sln.Iot.Repository/dao/TrayRfidBinding.cs | 22 +++- .../service/TrayBindingService.cs | 75 +++++++++++- Sln.Iot.Test/UnitTest1.cs | 4 +- Sln.Iot/Program.cs | 2 +- 13 files changed, 526 insertions(+), 21 deletions(-) create mode 100644 Sln.Iot.Business/RFID03Business.cs create mode 100644 Sln.Iot.Business/RFID04Business.cs create mode 100644 Sln.Iot.Business/RFID05Business.cs create mode 100644 Sln.Iot.Business/RFID06Business.cs create mode 100644 Sln.Iot.Repository/dao/ProdDataBinding.cs diff --git a/Sln.Iot.Business/RFID01Business.cs b/Sln.Iot.Business/RFID01Business.cs index 83aebec..8ccef69 100644 --- a/Sln.Iot.Business/RFID01Business.cs +++ b/Sln.Iot.Business/RFID01Business.cs @@ -47,13 +47,13 @@ namespace Sln.Iot.Business //成功验证 if (trayBytesResult.IsSuccess && pordBytesResult.IsSuccess) { - //转换托盘吗 + //转换托盘码 string traycode = Encoding.ASCII.GetString(trayBytesResult.Content); byte[] prodBytes = trayBytesResult.Content; string[] prodcode = new string[6]; //分割转换产品码 - for (int i = 0; i < 5; i++) + for (int i = 0; i < 6; i++) { prodcode[i] = Encoding.ASCII.GetString(prodBytes[(i * 20)..(i * 20 + 20)]); } @@ -61,13 +61,13 @@ namespace Sln.Iot.Business bool res = TrayBindingService.Instance.TrayBindingRefresh(traycode, prodcode); if (!res) { - _log.Error("上料提升机数据处理流程异常"); + _log.Error("上料提升机数据库写入异常"); } //写入完成信号 res = _plc.PlcWrite(_plc.DeltaInstance3, "D500", 1002, DataTypeEnum.UInt16).IsSuccess; if (!res) { - _log.Error("上料提升机写入完成信号异常"); + _log.Error("上料提升机PLC写入完成信号异常"); } } //流程完成 @@ -75,7 +75,7 @@ namespace Sln.Iot.Business } else { - _log.Error("上料提升机读取信号异常"); + _log.Error("上料提升机PLC读取信号异常"); } } } diff --git a/Sln.Iot.Business/RFID02Business.cs b/Sln.Iot.Business/RFID02Business.cs index 20f5c84..53462bc 100644 --- a/Sln.Iot.Business/RFID02Business.cs +++ b/Sln.Iot.Business/RFID02Business.cs @@ -1,5 +1,6 @@ using HslCommunication; using Sln.Iot.PLC; +using Sln.Iot.Repository.service; using Sln.Iot.Serilog; using System; using System.Collections.Generic; @@ -23,27 +24,53 @@ namespace Sln.Iot.Business } /// - /// RFID02上料提升机数据处理流程业务刷新 + /// RFID02胶机1真空箱内数据处理流程 /// /// public void TimerCallback(object? state) { // 定时任务逻辑 - OperateResult signalRes = _plc.ReadInt16(_plc.DeltaInstance1, "D500"); + //读取信号 + OperateResult signalRes = _plc.ReadInt16(_plc.DeltaInstance1, "D800"); + //成功验证 if (signalRes.IsSuccess) { short signalValue = signalRes.Content; - if(signalValue == 1001) + //如果有读取信号 + if (signalValue == 2001) { - OperateResult trayBytesResult = _plc.ReadBytes(_plc.DeltaInstance1, "D5000", 10); - OperateResult pordBytesResult = _plc.ReadBytes(_plc.DeltaInstance1, "D8000", 60); - if(trayBytesResult.IsSuccess && pordBytesResult.IsSuccess) + //读取托盘码 + OperateResult trayBytesResult = _plc.ReadBytes(_plc.DeltaInstance1, "D5000", 20); + //成功验证 + if (trayBytesResult.IsSuccess) { - string traycode = "abcdefg"; - string prodcode = "1234567890"; + //转换托盘码 + string traycode = Encoding.ASCII.GetString(trayBytesResult.Content); + + //sql更新 + + //待开发 记录数据 + + bool res = false; + if (!res) + { + _log.Error("胶机1真空箱内数据库写入异常"); + } + + //写入完成信号 + res = _plc.PlcWrite(_plc.DeltaInstance1, "D800", 2002, DataTypeEnum.UInt16).IsSuccess; + if (!res) + { + _log.Error("胶机1真空箱内写入完成信号异常"); + } } + //流程完成 } } + else + { + _log.Error("胶机1真空箱内PLC读取信号异常"); + } } } } diff --git a/Sln.Iot.Business/RFID03Business.cs b/Sln.Iot.Business/RFID03Business.cs new file mode 100644 index 0000000..2f446b2 --- /dev/null +++ b/Sln.Iot.Business/RFID03Business.cs @@ -0,0 +1,73 @@ +using HslCommunication; +using Sln.Iot.PLC; +using Sln.Iot.Repository.service; +using Sln.Iot.Serilog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Sln.Iot.Business +{ + public class RFID03Business + { + private Timer _timer; + + private readonly PLCConnect _plc; + + private readonly SerilogHelper _log; + + public RFID03Business() + { + _timer = new Timer(TimerCallback, null, 0, 5000); + } + + /// + /// RFID03胶机1真空箱外数据处理流程 + /// + /// + public void TimerCallback(object? state) + { + // 定时任务逻辑 + //读取信号 + OperateResult signalRes = _plc.ReadInt16(_plc.DeltaInstance1, "D802"); + //成功验证 + if (signalRes.IsSuccess) + { + short signalValue = signalRes.Content; + //如果有读取信号 + if (signalValue == 3001) + { + //读取托盘码 + OperateResult trayBytesResult = _plc.ReadBytes(_plc.DeltaInstance1, "D5020", 20); + //成功验证 + if (trayBytesResult.IsSuccess) + { + //转换托盘码 + string traycode = Encoding.ASCII.GetString(trayBytesResult.Content); + + //sql更新 + bool res = TrayBindingService.Instance.UpDateTime(DateTime.Now.ToString(), traycode, "1"); + if (!res) + { + _log.Error("胶机1真空箱外数据库写入异常"); + } + + //写入完成信号 + res = _plc.PlcWrite(_plc.DeltaInstance1, "D802", 3002, DataTypeEnum.UInt16).IsSuccess; + if (!res) + { + _log.Error("胶机1真空箱外写入完成信号异常"); + } + } + //流程完成 + } + } + else + { + _log.Error("胶机1真空箱外PLC读取信号异常"); + } + } + } +} diff --git a/Sln.Iot.Business/RFID04Business.cs b/Sln.Iot.Business/RFID04Business.cs new file mode 100644 index 0000000..5de6879 --- /dev/null +++ b/Sln.Iot.Business/RFID04Business.cs @@ -0,0 +1,111 @@ +using HslCommunication; +using Sln.Iot.PLC; +using Sln.Iot.Repository.service; +using Sln.Iot.Serilog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static System.Runtime.CompilerServices.RuntimeHelpers; + +namespace Sln.Iot.Business +{ + public class RFID04Business + { + private Timer _timer; + + private readonly PLCConnect _plc; + + private readonly SerilogHelper _log; + + public RFID04Business() + { + _timer = new Timer(TimerCallback, null, 0, 5000); + } + + /// + /// RFID02胶机1真空箱数据处理流程 + /// + /// + public void TimerCallback(object? state) + { + // 定时任务逻辑 + //读取信号 + OperateResult signalRes = _plc.ReadInt16(_plc.DeltaInstance2, "D800"); + //成功验证 + if (signalRes.IsSuccess) + { + short signalValue = signalRes.Content; + //如果有读取信号 + if (signalValue == 4001) + { + //读取托盘码和产品码 + OperateResult trayBytesResult = _plc.ReadBytes(_plc.DeltaInstance2, "D5000", 20); + //成功验证 + if (trayBytesResult.IsSuccess) + { + //转换托盘吗 + string traycode = Encoding.ASCII.GetString(trayBytesResult.Content); + + //sql更新 + bool res = TrayBindingService.Instance.UpDateTime(DateTime.Now.ToString(), traycode, "2"); + if (!res) + { + _log.Error("胶机2真空箱前开始时间数据库写入异常"); + } + + //写入完成信号 + res = _plc.PlcWrite(_plc.DeltaInstance2, "D800", 4002, DataTypeEnum.UInt16).IsSuccess; + if (!res) + { + _log.Error("胶机2真空箱前开始时间PLC写入完成信号异常"); + } + } + //流程完成 + } + + if(signalValue == 4003) + { + //读取托盘码 + OperateResult trayBytesResult = _plc.ReadBytes(_plc.DeltaInstance2, "D5000", 20); + //成功验证 + if (trayBytesResult.IsSuccess) + { + //转换托盘吗 + string traycode = Encoding.ASCII.GetString(trayBytesResult.Content); + + //sql更新 + string nowTime = DateTime.Now.ToString(); + bool res = TrayBindingService.Instance.UpDateTime(nowTime, traycode, "3"); + if (!res) + { + _log.Error("胶机2真空箱前时间计算数据库写入异常"); + } + //取之前存的时间 + string time2 = TrayBindingService.Instance.GetTime2ByTrayCode(traycode); + //计算时间差 + TimeSpan span = Convert.ToDateTime(time2) - Convert.ToDateTime(nowTime); + ushort spanSecond = (ushort)span.TotalSeconds; + res = _plc.PlcWrite(_plc.DeltaInstance2, "D810", spanSecond, DataTypeEnum.UInt16).IsSuccess; + if (!res) + { + _log.Error("胶机2真空箱前时间计算结果PLC写入异常"); + } + //写入完成信号 + res = _plc.PlcWrite(_plc.DeltaInstance2, "D800", 4004, DataTypeEnum.UInt16).IsSuccess; + if (!res) + { + _log.Error("胶机2真空箱前时间计算PLC写入完成信号异常"); + } + } + //流程完成 + } + } + else + { + _log.Error("胶机2真空箱前开始时间读PLC取信号异常"); + } + } + } +} diff --git a/Sln.Iot.Business/RFID05Business.cs b/Sln.Iot.Business/RFID05Business.cs new file mode 100644 index 0000000..7235227 --- /dev/null +++ b/Sln.Iot.Business/RFID05Business.cs @@ -0,0 +1,73 @@ +using HslCommunication; +using Sln.Iot.PLC; +using Sln.Iot.Repository.service; +using Sln.Iot.Serilog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Sln.Iot.Business +{ + public class RFID05Business + { + private Timer _timer; + + private readonly PLCConnect _plc; + + private readonly SerilogHelper _log; + + public RFID05Business() + { + _timer = new Timer(TimerCallback, null, 0, 5000); + } + + /// + /// RFID02胶机1真空箱数据处理流程 + /// + /// + public void TimerCallback(object? state) + { + // 定时任务逻辑 + //读取信号 + OperateResult signalRes = _plc.ReadInt16(_plc.DeltaInstance2, "D802"); + //成功验证 + if (signalRes.IsSuccess) + { + short signalValue = signalRes.Content; + //如果有读取信号 + if (signalValue == 5001) + { + //读取托盘码 + OperateResult trayBytesResult = _plc.ReadBytes(_plc.DeltaInstance2, "D5020", 20); + //成功验证 + if (trayBytesResult.IsSuccess) + { + //转换托盘吗 + string traycode = Encoding.ASCII.GetString(trayBytesResult.Content); + + //sql更新 + bool res = TrayBindingService.Instance.UpDateTime(DateTime.Now.ToString(), traycode, "4"); + if (!res) + { + _log.Error("胶机2真空箱后数据库写入异常"); + } + + //写入完成信号 + res = _plc.PlcWrite(_plc.DeltaInstance2, "D802", 5002, DataTypeEnum.UInt16).IsSuccess; + if (!res) + { + _log.Error("胶机2真空箱后PLC写入完成信号异常"); + } + } + //流程完成 + } + } + else + { + _log.Error("胶机2真空箱后PLC读取信号异常"); + } + } + } +} diff --git a/Sln.Iot.Business/RFID06Business.cs b/Sln.Iot.Business/RFID06Business.cs new file mode 100644 index 0000000..d746958 --- /dev/null +++ b/Sln.Iot.Business/RFID06Business.cs @@ -0,0 +1,77 @@ +using HslCommunication; +using Sln.Iot.PLC; +using Sln.Iot.Repository.service; +using Sln.Iot.Serilog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Sln.Iot.Business +{ + public class RFID06Business + { + private Timer _timer; + + private readonly PLCConnect _plc; + + private readonly SerilogHelper _log; + + public RFID06Business() + { + _timer = new Timer(TimerCallback, null, 0, 5000); + } + + /// + /// RFID02胶机1真空箱数据处理流程 + /// + /// + public void TimerCallback(object? state) + { + // 定时任务逻辑 + //读取信号 + OperateResult signalRes = _plc.ReadInt16(_plc.DeltaInstance3, "D500"); + //成功验证 + if (signalRes.IsSuccess) + { + short signalValue = signalRes.Content; + //如果有读取信号 + if (signalValue == 6001) + { + //读取托盘码和产品码 + OperateResult trayBytesResult = _plc.ReadBytes(_plc.DeltaInstance3, "D5000", 20); + //成功验证 + if (trayBytesResult.IsSuccess) + { + //转换托盘吗 + string traycode = Encoding.ASCII.GetString(trayBytesResult.Content); + + //sql更新 + + //待开发 + + bool res = TrayBindingService.Instance.TrayCodeDelete(traycode); + + if (!res) + { + _log.Error("下料提升机绑定数据删除异常或删除条数为0"); + } + + //写入完成信号 + res = _plc.PlcWrite(_plc.DeltaInstance3, "D500", 6002, DataTypeEnum.UInt16).IsSuccess; + if (!res) + { + _log.Error("下料提升机PLC写入完成信号异常"); + } + } + //流程完成 + } + } + else + { + _log.Error("下料提升机PLC读取信号异常"); + } + } + } +} diff --git a/Sln.Iot.PLC/PLCConnect.cs b/Sln.Iot.PLC/PLCConnect.cs index 25f2829..5b2aec9 100644 --- a/Sln.Iot.PLC/PLCConnect.cs +++ b/Sln.Iot.PLC/PLCConnect.cs @@ -54,6 +54,8 @@ namespace Sln.Iot.PLC CreateDeltaConnect("192.168.1.23", 502, 1), CreateDeltaConnect("192.168.1.24", 502, 1) }; + + await Task.WhenAll(tasks); DeltaInstance1 = tasks[0].GetAwaiter().GetResult(); DeltaInstance2 = tasks[1].GetAwaiter().GetResult(); diff --git a/Sln.Iot.Repository/SqliteHelper.cs b/Sln.Iot.Repository/SqliteHelper.cs index 807eb16..685b14b 100644 --- a/Sln.Iot.Repository/SqliteHelper.cs +++ b/Sln.Iot.Repository/SqliteHelper.cs @@ -73,9 +73,19 @@ namespace Sln.Iot.Repository /// /// /// - public List DeleteRange(string trayCode) + public int DeleteRange(string trayCode) { - return _connection.Query($"DELETE FROM {typeof(T).Name} WHERE TrayCode = '{trayCode}'"); + return _connection.Execute($"DELETE FROM {typeof(T).Name} WHERE TrayCode = '{trayCode}'"); + } + + /// + /// sql直接执行 + /// + /// + /// + public int SqlExcute(string sql) + { + return _connection.Execute(sql); } /// diff --git a/Sln.Iot.Repository/dao/ProdDataBinding.cs b/Sln.Iot.Repository/dao/ProdDataBinding.cs new file mode 100644 index 0000000..5892d29 --- /dev/null +++ b/Sln.Iot.Repository/dao/ProdDataBinding.cs @@ -0,0 +1,41 @@ +using SQLite; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Sln.Iot.Repository.dao +{ + /// + /// 产品参数存储 + /// + public class ProdDataBinding + { + /// + /// 主键 + /// + [PrimaryKey] + public string GUID { get; set; } + + /// + /// 托盘码 + /// + public string TrayCode { get; set; } + + /// + /// 参数名称 + /// + public string DataName { get; set; } + + /// + /// 参数内容 + /// + public string DataContent { get; set; } + + /// + /// 参数类型(bool, float, uint16, uint32, byte.......) + /// + public string DataType { get; set; } + } +} diff --git a/Sln.Iot.Repository/dao/TrayRfidBinding.cs b/Sln.Iot.Repository/dao/TrayRfidBinding.cs index 230a174..5cb54db 100644 --- a/Sln.Iot.Repository/dao/TrayRfidBinding.cs +++ b/Sln.Iot.Repository/dao/TrayRfidBinding.cs @@ -27,5 +27,25 @@ namespace Sln.Iot.Repository.dao /// 产品编码 /// public string ProductionCode { get; set; } - } + + /// + /// RFID03流程时间 + /// + public string? Time1 { get; set; } + + /// + /// RFID04流程时间1 + /// + public string? Time2 { get; set; } + + /// + /// RFID04流程时间2 + /// + public string? Time3 { get; set; } + + /// + /// RFID05流程时间 + /// + public string? Time4 { get; set; } + } } diff --git a/Sln.Iot.Repository/service/TrayBindingService.cs b/Sln.Iot.Repository/service/TrayBindingService.cs index e0b5e28..1a4f083 100644 --- a/Sln.Iot.Repository/service/TrayBindingService.cs +++ b/Sln.Iot.Repository/service/TrayBindingService.cs @@ -28,11 +28,29 @@ namespace Sln.Iot.Repository.service private SerilogHelper _log = SerilogHelper.Instance; + /// + /// 绑定信息根据托盘号删除 + /// + /// + public bool TrayCodeDelete(string trayCode) + { + try + { + int res = _helper.DeleteRange(trayCode); + return res != 0; + } + catch(Exception ex) + { + _log.Error("托盘码删除错误", ex); + return false; + } + } + /// /// 托盘二维码重新绑定 /// - /// - /// + /// 托盘码 + /// 产品码 /// public bool TrayBindingRefresh(string trayCode, string[] prodCode) { @@ -44,6 +62,10 @@ namespace Sln.Iot.Repository.service var entities = new List(); foreach (string code in prodCode) { + if (string.IsNullOrWhiteSpace(code)) + { + continue; + } TrayRfidBinding entity = new TrayRfidBinding() { GUID = Guid.NewGuid().ToString("N"), @@ -61,5 +83,54 @@ namespace Sln.Iot.Repository.service return false; } } + + /// + /// 存储对应托盘码的时间节点 + /// + /// 时间字符串 + /// 托盘码 + /// 时间参数编号 + /// + public bool UpDateTime(string timeString, string trayCode, string timeCount) + { + try + { + int res = _helper.SqlExcute($"update TrayRfidBinding set time{timeCount} = '{timeString}' where TrayCode = '{trayCode}'"); + if(res <= 0 || res > 6) + { + return false; + } + return true; + } + catch (Exception ex) + { + _log.Error("时间更新错误", ex); + return false; + } + } + + /// + /// 获取一个时间 + /// + /// + /// + public string GetTime2ByTrayCode(string trayCode) + { + string time2 = string.Empty; + try + { + var res = _helper.Query(t => t.TrayCode == trayCode).FirstOrDefault(); + if (res != null) + { + time2 = res.Time2; + } + return time2; + } + catch (Exception ex) + { + _log.Error("根据托盘码获取time2错误", ex); + return time2; + } + } } } diff --git a/Sln.Iot.Test/UnitTest1.cs b/Sln.Iot.Test/UnitTest1.cs index bd1bad3..b262be2 100644 --- a/Sln.Iot.Test/UnitTest1.cs +++ b/Sln.Iot.Test/UnitTest1.cs @@ -51,8 +51,8 @@ namespace Sln.Iot.Test }; var ress = SQLiteHelper.Instance.InsertRange(testDatas); - var res = SQLiteHelper.Instance.DeleteRange("Tray001"); - Assert.Equal(5, res.Count); + var res = SQLiteHelper.Instance.DeleteRange("Tray002"); + Assert.Equal(5, res); } diff --git a/Sln.Iot/Program.cs b/Sln.Iot/Program.cs index f3219d0..c5ce513 100644 --- a/Sln.Iot/Program.cs +++ b/Sln.Iot/Program.cs @@ -22,7 +22,7 @@ namespace Sln.Iot var log = SerilogHelper.Instance; //配置文件加载 var appConfig = AppConfigSetting.Load(); - + //PLC连接初始化 PLCConnect.Instance.InitConnect(); log.Info($"系统启动成功,日志存放位置:{appConfig.logPath}");