PLC报警信息
This commit is contained in:
parent
f2e4626616
commit
9a4d807700
101
RIZO.Admin.WebApi/Controllers/MES/alarm/AlarmInfoController.cs
Normal file
101
RIZO.Admin.WebApi/Controllers/MES/alarm/AlarmInfoController.cs
Normal file
@ -0,0 +1,101 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RIZO.Model.MES.alarm;
|
||||
using RIZO.Model.MES.alarm.Dto;
|
||||
using RIZO.Service.MES.alarm.IService;
|
||||
|
||||
//创建时间:2026-01-19
|
||||
namespace RIZO.Admin.WebApi.Controllers.Mes.alerm
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC报警信息
|
||||
/// </summary>
|
||||
[Route("mes/AlarmInfo")]
|
||||
[AllowAnonymous]
|
||||
public class AlarmInfoController : BaseController
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC报警信息接口
|
||||
/// </summary>
|
||||
private readonly IAlarmInfoService _AlarmInfoService;
|
||||
|
||||
public AlarmInfoController(IAlarmInfoService AlarmInfoService)
|
||||
{
|
||||
_AlarmInfoService = AlarmInfoService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询PLC报警信息列表
|
||||
/// </summary>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("list")]
|
||||
[ActionPermissionFilter(Permission = "alarminfo:list")]
|
||||
public IActionResult QueryAlarmInfo([FromQuery] AlarmInfoQueryDto parm)
|
||||
{
|
||||
var response = _AlarmInfoService.GetList(parm);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 查询PLC报警信息详情
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{Id}")]
|
||||
[ActionPermissionFilter(Permission = "alarminfo:query")]
|
||||
public IActionResult GetAlarmInfo(int Id)
|
||||
{
|
||||
var response = _AlarmInfoService.GetInfo(Id);
|
||||
|
||||
var info = response.Adapt<AlarmInfoDto>();
|
||||
return SUCCESS(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加PLC报警信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ActionPermissionFilter(Permission = "alarminfo:add")]
|
||||
[Log(Title = "PLC报警信息", BusinessType = BusinessType.INSERT)]
|
||||
public IActionResult AddAlarmInfo([FromBody] AlarmInfoDto parm)
|
||||
{
|
||||
var modal = parm.Adapt<AlarmInfo>().ToCreate(HttpContext);
|
||||
|
||||
var response = _AlarmInfoService.AddAlarmInfo(modal);
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新PLC报警信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPut]
|
||||
[ActionPermissionFilter(Permission = "alarminfo:edit")]
|
||||
[Log(Title = "PLC报警信息", BusinessType = BusinessType.UPDATE)]
|
||||
public IActionResult UpdateAlarmInfo([FromBody] AlarmInfoDto parm)
|
||||
{
|
||||
var modal = parm.Adapt<AlarmInfo>().ToUpdate(HttpContext);
|
||||
var response = _AlarmInfoService.UpdateAlarmInfo(modal);
|
||||
|
||||
return ToResponse(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除PLC报警信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("delete/{ids}")]
|
||||
[ActionPermissionFilter(Permission = "alarminfo:delete")]
|
||||
[Log(Title = "PLC报警信息", BusinessType = BusinessType.DELETE)]
|
||||
public IActionResult DeleteAlarmInfo([FromRoute]string ids)
|
||||
{
|
||||
var idArr = Tools.SplitAndConvert<int>(ids);
|
||||
|
||||
return ToResponse(_AlarmInfoService.Delete(idArr));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,101 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RIZO.Model.MES.alarm;
|
||||
using RIZO.Model.MES.alarm.Dto;
|
||||
using RIZO.Service.MES.alarm.IService;
|
||||
|
||||
//创建时间:2026-01-19
|
||||
namespace RIZO.Admin.WebApi.Controllers.Mes.alarm
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC报警信息字典
|
||||
/// </summary>
|
||||
[Route("mes/AlarmProblemDictionary")]
|
||||
[AllowAnonymous]
|
||||
public class AlarmProblemDictionaryController : BaseController
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC报警信息字典接口
|
||||
/// </summary>
|
||||
private readonly IAlarmProblemDictionaryService _AlarmProblemDictionaryService;
|
||||
|
||||
public AlarmProblemDictionaryController(IAlarmProblemDictionaryService AlarmProblemDictionaryService)
|
||||
{
|
||||
_AlarmProblemDictionaryService = AlarmProblemDictionaryService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询PLC报警信息字典列表
|
||||
/// </summary>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("list")]
|
||||
[ActionPermissionFilter(Permission = "alarmproblemdictionary:list")]
|
||||
public IActionResult QueryAlarmProblemDictionary([FromQuery] AlarmProblemDictionaryQueryDto parm)
|
||||
{
|
||||
var response = _AlarmProblemDictionaryService.GetList(parm);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 查询PLC报警信息字典详情
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{Id}")]
|
||||
[ActionPermissionFilter(Permission = "alarmproblemdictionary:query")]
|
||||
public IActionResult GetAlarmProblemDictionary(int Id)
|
||||
{
|
||||
var response = _AlarmProblemDictionaryService.GetInfo(Id);
|
||||
|
||||
var info = response.Adapt<AlarmProblemDictionaryDto>();
|
||||
return SUCCESS(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加PLC报警信息字典
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ActionPermissionFilter(Permission = "alarmproblemdictionary:add")]
|
||||
[Log(Title = "PLC报警信息字典", BusinessType = BusinessType.INSERT)]
|
||||
public IActionResult AddAlarmProblemDictionary([FromBody] AlarmProblemDictionaryDto parm)
|
||||
{
|
||||
var modal = parm.Adapt<AlarmProblemDictionary>().ToCreate(HttpContext);
|
||||
|
||||
var response = _AlarmProblemDictionaryService.AddAlarmProblemDictionary(modal);
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新PLC报警信息字典
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPut]
|
||||
[ActionPermissionFilter(Permission = "alarmproblemdictionary:edit")]
|
||||
[Log(Title = "PLC报警信息字典", BusinessType = BusinessType.UPDATE)]
|
||||
public IActionResult UpdateAlarmProblemDictionary([FromBody] AlarmProblemDictionaryDto parm)
|
||||
{
|
||||
var modal = parm.Adapt<AlarmProblemDictionary>().ToUpdate(HttpContext);
|
||||
var response = _AlarmProblemDictionaryService.UpdateAlarmProblemDictionary(modal);
|
||||
|
||||
return ToResponse(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除PLC报警信息字典
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("delete/{ids}")]
|
||||
[ActionPermissionFilter(Permission = "alarmproblemdictionary:delete")]
|
||||
[Log(Title = "PLC报警信息字典", BusinessType = BusinessType.DELETE)]
|
||||
public IActionResult DeleteAlarmProblemDictionary([FromRoute]string ids)
|
||||
{
|
||||
var idArr = Tools.SplitAndConvert<int>(ids);
|
||||
|
||||
return ToResponse(_AlarmProblemDictionaryService.Delete(idArr));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -234,7 +234,6 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
});
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
_logger.LogInformation($"批量连接完成 | 已测试设备数:{validConfigs.Count}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -242,7 +241,6 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
/// </summary>
|
||||
private async Task PollPlcDataAsync()
|
||||
{
|
||||
_logger.LogInformation("开始轮询PLC生产数据...");
|
||||
|
||||
// 过滤有效配置(非空IP)
|
||||
var validConfigs = _plcConfigs.Where(c => !string.IsNullOrWhiteSpace(c.Ip)).ToList();
|
||||
@ -321,9 +319,6 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
|
||||
if (success)
|
||||
{
|
||||
// 日志输出关键业务数据(而非抽象的value)
|
||||
_logger.LogInformation(
|
||||
$"[{config.PlcName}] 生产数据读取成功 | IP:{config.Ip} | 产线:{prodData.LineCode} | 产品:{prodData.ProductCode} | 合格标志:{prodData.QualificationFlag} | 生产节拍:{prodData.ProductionCycle}s");
|
||||
|
||||
// 数据处理逻辑(示例:可替换为入库/推MQ/存Redis等)
|
||||
await ProcessPlcProductionDataAsync(config, prodData);
|
||||
@ -364,10 +359,6 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
|
||||
// 等待所有轮询任务完成
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
// 输出本轮轮询汇总日志
|
||||
_logger.LogInformation(
|
||||
$"PLC生产数据轮询完成 | 总设备数:{validConfigs.Count} | 成功:{successCount} | 失败:{failCount} | 跳过:{skipCount}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -5,6 +5,7 @@ using RIZO.Admin.WebApi.PLC.Model;
|
||||
using RIZO.Common;
|
||||
using S7.Net;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -26,8 +27,12 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
private readonly List<PlcConfig> _plcConfigs;
|
||||
private readonly GlobalPlcConfig _globalConfig;
|
||||
|
||||
private PlcProductionDataService plcProductionDataService = new PlcProductionDataService();
|
||||
private PlantWorkstationService plantWorkstationService = new PlantWorkstationService();
|
||||
private PlcProductionDataService _plcProductionDataService = new PlcProductionDataService();
|
||||
private PlantWorkstationService _plantWorkstationService = new PlantWorkstationService();
|
||||
|
||||
// 先在类中添加2个核心优化字段(支撑高频访问)
|
||||
private readonly SemaphoreSlim _concurrencySemaphore = new SemaphoreSlim(15, 50); // 限制20并发(适配50台PLC)
|
||||
private readonly ConcurrentDictionary<string, (Plc Client, DateTime LastUsedTime)> _plcConnPool = new(); // 连接池
|
||||
|
||||
// PLC地址映射(严格匹配业务地址清单)
|
||||
private readonly Dictionary<string, (string Addr, int Len)> _plcStringMap = new()
|
||||
@ -67,8 +72,86 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
#endregion
|
||||
|
||||
#region 核心业务方法
|
||||
///// <summary>
|
||||
///// 读取PLC生产数据(严格匹配业务地址和解析规则)
|
||||
///// </summary>
|
||||
///// <param name="ip">PLC IP地址</param>
|
||||
///// <param name="rack">机架号</param>
|
||||
///// <param name="slot">槽位号</param>
|
||||
///// <param name="cpuType">PLC型号(默认S7-1500)</param>
|
||||
///// <returns>读取结果(状态+数据+消息)</returns>
|
||||
//public async Task<(bool Success, PlcProductionData Data, string Message)> ReadProductionDataAsync(
|
||||
// string ip,
|
||||
// short rack,
|
||||
// short slot,
|
||||
// CpuType cpuType = CpuType.S71500)
|
||||
//{
|
||||
// // 参数校验
|
||||
// if (string.IsNullOrWhiteSpace(ip))
|
||||
// return (false, null, "PLC IP地址不能为空");
|
||||
|
||||
// Plc plc = null;
|
||||
// try
|
||||
// {
|
||||
// // 初始化PLC连接
|
||||
// plc = CreatePlcClient(cpuType, ip, rack, slot);
|
||||
// await OpenPlcConnectionAsync(plc);
|
||||
|
||||
// if (!plc.IsConnected)
|
||||
// return (false, null, "PLC连接失败");
|
||||
|
||||
// // 构建生产数据实体
|
||||
// var prodData = new PlcProductionData
|
||||
// {
|
||||
// PlcIp = ip.Trim(),
|
||||
// OccurTime = DateTime.Now, // MES自配时间
|
||||
|
||||
// // 字符串字段(按规则解析)
|
||||
// LineCode = await ReadPlcStringAsync(plc, _plcStringMap["LineCode"].Addr, _plcStringMap["LineCode"].Len),
|
||||
// ProductCode = await ReadPlcStringAsync(plc, _plcStringMap["ProductCode"].Addr, _plcStringMap["ProductCode"].Len),
|
||||
// ProductName = await ReadPlcStringAsync(plc, _plcStringMap["ProductName"].Addr, _plcStringMap["ProductName"].Len),
|
||||
// PartCode = await ReadPlcStringAsync(plc, _plcStringMap["PartCode"].Addr, _plcStringMap["PartCode"].Len),
|
||||
// PartName = await ReadPlcStringAsync(plc, _plcStringMap["PartName"].Addr, _plcStringMap["PartName"].Len),
|
||||
// ProcessName = await ReadPlcStringAsync(plc, _plcStringMap["ProcessName"].Addr, _plcStringMap["ProcessName"].Len),
|
||||
// ParamName = await ReadPlcStringAsync(plc, _plcStringMap["ParamName"].Addr, _plcStringMap["ParamName"].Len),
|
||||
// ParamValue = await ReadPlcStringAsync(plc, _plcStringMap["ParamValue"].Addr, _plcStringMap["ParamValue"].Len),
|
||||
|
||||
// // 修复:改为异步读取整数,确保类型兼容
|
||||
// //合格标志(0默认,1合格,2不合格)
|
||||
// QualificationFlag = (await ReadPlcIntAsync(plc, _plcIntMap["QualificationFlag"])).ToString(),
|
||||
// //返工标志(0正常,1返工)
|
||||
// ReworkFlag = (await ReadPlcIntAsync(plc, _plcIntMap["ReworkFlag"])).ToString(),
|
||||
// //设备自动手动:0-自动,1-手动
|
||||
// AutoManual = (await ReadPlcIntAsync(plc, _plcIntMap["AutoManual"])),
|
||||
// //运行状态:1正常,2异常
|
||||
// RunStatus = (await ReadPlcIntAsync(plc, _plcIntMap["RunStatus"])),
|
||||
// //生产节拍秒
|
||||
// ProductionCycle = await ReadPlcIntAsync(plc, _plcIntMap["ProductionCycle"])
|
||||
// };
|
||||
|
||||
// // 空值兜底(避免入库报错)
|
||||
// prodData.QualificationFlag ??= "0";
|
||||
// prodData.ReworkFlag ??= "0";
|
||||
// prodData.ProductionCycle ??= 0;
|
||||
|
||||
// // 保存生产数据到MES数据库
|
||||
// _plcProductionDataService.AddPlcProductionData(prodData);
|
||||
// return (true, prodData, "生产数据读取成功");
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// return (false, null, $"生产数据读取失败:{ex.Message}");
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// ReleasePlcConnection(plc);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 读取PLC生产数据(严格匹配业务地址和解析规则)
|
||||
/// 读取PLC生产数据(优化版:连接池+并发控制+批量读取+异常防护)
|
||||
/// </summary>
|
||||
/// <param name="ip">PLC IP地址</param>
|
||||
/// <param name="rack">机架号</param>
|
||||
@ -81,68 +164,189 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
short slot,
|
||||
CpuType cpuType = CpuType.S71500)
|
||||
{
|
||||
// 参数校验
|
||||
// 1. 强化参数校验(源头避免无效请求)
|
||||
if (string.IsNullOrWhiteSpace(ip))
|
||||
return (false, null, "PLC IP地址不能为空");
|
||||
if (rack < 0 || rack > 10) // 工业场景机架号常规范围
|
||||
return (false, null, $"PLC机架号{rack}无效(有效值0-10)");
|
||||
if (slot < 0 || slot > 4) // 工业场景槽位号常规范围
|
||||
return (false, null, $"PLC槽位号{slot}无效(有效值0-4)");
|
||||
|
||||
Plc plc = null;
|
||||
bool isConnReused = false; // 标记是否复用连接
|
||||
var poolKey = $"{ip}_{rack}_{slot}_{cpuType}"; // 连接池唯一标识
|
||||
|
||||
// 2. 并发控制(防止50台PLC同时访问导致端口/线程耗尽)
|
||||
await _concurrencySemaphore.WaitAsync();
|
||||
|
||||
try
|
||||
{
|
||||
// 初始化PLC连接
|
||||
plc = CreatePlcClient(cpuType, ip, rack, slot);
|
||||
await OpenPlcConnectionAsync(plc);
|
||||
// 3. 连接池复用(核心优化:避免高频创建/销毁连接)
|
||||
if (_plcConnPool.TryGetValue(poolKey, out var poolItem) && poolItem.Client.IsConnected)
|
||||
{
|
||||
plc = poolItem.Client;
|
||||
_plcConnPool.TryUpdate(poolKey, (plc, DateTime.Now), poolItem); // 更新最后使用时间
|
||||
isConnReused = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 初始化新连接(保留你的原始逻辑,增加重试)
|
||||
plc = CreatePlcClient(cpuType, ip, rack, slot);
|
||||
// 连接重试(应对临时网络波动)
|
||||
int retryCount = 2;
|
||||
bool isConnected = false;
|
||||
while (retryCount-- > 0 && !isConnected)
|
||||
{
|
||||
try
|
||||
{
|
||||
await OpenPlcConnectionAsync(plc);
|
||||
isConnected = plc.IsConnected;
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (retryCount > 0) await Task.Delay(100); // 重试间隔
|
||||
}
|
||||
}
|
||||
|
||||
if (!plc.IsConnected)
|
||||
return (false, null, "PLC连接失败");
|
||||
if (!isConnected)
|
||||
return (false, null, "PLC连接失败(含2次重试)");
|
||||
|
||||
// 构建生产数据实体
|
||||
// 新连接加入池
|
||||
_plcConnPool.TryAdd(poolKey, (plc, DateTime.Now));
|
||||
}
|
||||
|
||||
// 4. 批量并行读取(核心优化:替代串行await,提升效率30%+)
|
||||
// 4.1 字符串字段批量读取
|
||||
var stringTasks = new Dictionary<string, Task<string>>
|
||||
{
|
||||
{ "LineCode", ReadPlcStringAsync(plc, _plcStringMap["LineCode"].Addr, _plcStringMap["LineCode"].Len) },
|
||||
{ "ProductCode", ReadPlcStringAsync(plc, _plcStringMap["ProductCode"].Addr, _plcStringMap["ProductCode"].Len) },
|
||||
{ "ProductName", ReadPlcStringAsync(plc, _plcStringMap["ProductName"].Addr, _plcStringMap["ProductName"].Len) },
|
||||
{ "PartCode", ReadPlcStringAsync(plc, _plcStringMap["PartCode"].Addr, _plcStringMap["PartCode"].Len) },
|
||||
{ "PartName", ReadPlcStringAsync(plc, _plcStringMap["PartName"].Addr, _plcStringMap["PartName"].Len) },
|
||||
{ "ProcessName", ReadPlcStringAsync(plc, _plcStringMap["ProcessName"].Addr, _plcStringMap["ProcessName"].Len) },
|
||||
{ "ParamName", ReadPlcStringAsync(plc, _plcStringMap["ParamName"].Addr, _plcStringMap["ParamName"].Len) },
|
||||
{ "ParamValue", ReadPlcStringAsync(plc, _plcStringMap["ParamValue"].Addr, _plcStringMap["ParamValue"].Len) }
|
||||
};
|
||||
|
||||
// 4.2 整数字段批量读取
|
||||
var intTasks = new Dictionary<string, Task<int>>
|
||||
{
|
||||
{ "QualificationFlag", ReadPlcIntAsync(plc, _plcIntMap["QualificationFlag"]) },
|
||||
{ "ReworkFlag", ReadPlcIntAsync(plc, _plcIntMap["ReworkFlag"]) },
|
||||
{ "AutoManual", ReadPlcIntAsync(plc, _plcIntMap["AutoManual"]) },
|
||||
{ "RunStatus", ReadPlcIntAsync(plc, _plcIntMap["RunStatus"]) },
|
||||
{ "ProductionCycle", ReadPlcIntAsync(plc, _plcIntMap["ProductionCycle"]) }
|
||||
};
|
||||
|
||||
// 等待所有读取完成(并行执行,减少等待时间)
|
||||
IEnumerable<Task> allTasks = stringTasks.Values.Cast<Task>()
|
||||
.Concat(intTasks.Values.Cast<Task>());
|
||||
await Task.WhenAll(allTasks);
|
||||
|
||||
// 5. 构建数据实体(空值安全处理,单个字段失败不影响整体)
|
||||
var prodData = new PlcProductionData
|
||||
{
|
||||
PlcIp = ip.Trim(),
|
||||
OccurTime = DateTime.Now, // MES自配时间
|
||||
OccurTime = DateTime.Now,
|
||||
|
||||
// 字符串字段(按规则解析)
|
||||
LineCode = await ReadPlcStringAsync(plc, _plcStringMap["LineCode"].Addr, _plcStringMap["LineCode"].Len),
|
||||
ProductCode = await ReadPlcStringAsync(plc, _plcStringMap["ProductCode"].Addr, _plcStringMap["ProductCode"].Len),
|
||||
ProductName = await ReadPlcStringAsync(plc, _plcStringMap["ProductName"].Addr, _plcStringMap["ProductName"].Len),
|
||||
PartCode = await ReadPlcStringAsync(plc, _plcStringMap["PartCode"].Addr, _plcStringMap["PartCode"].Len),
|
||||
PartName = await ReadPlcStringAsync(plc, _plcStringMap["PartName"].Addr, _plcStringMap["PartName"].Len),
|
||||
ProcessName = await ReadPlcStringAsync(plc, _plcStringMap["ProcessName"].Addr, _plcStringMap["ProcessName"].Len),
|
||||
ParamName = await ReadPlcStringAsync(plc, _plcStringMap["ParamName"].Addr, _plcStringMap["ParamName"].Len),
|
||||
ParamValue = await ReadPlcStringAsync(plc, _plcStringMap["ParamValue"].Addr, _plcStringMap["ParamValue"].Len),
|
||||
// 字符串字段(空值兜底)
|
||||
LineCode = await stringTasks["LineCode"] ?? string.Empty,
|
||||
ProductCode = await stringTasks["ProductCode"] ?? string.Empty,
|
||||
ProductName = await stringTasks["ProductName"] ?? string.Empty,
|
||||
PartCode = await stringTasks["PartCode"] ?? string.Empty,
|
||||
PartName = await stringTasks["PartName"] ?? string.Empty,
|
||||
ProcessName = await stringTasks["ProcessName"] ?? string.Empty,
|
||||
ParamName = await stringTasks["ParamName"] ?? string.Empty,
|
||||
ParamValue = await stringTasks["ParamValue"] ?? string.Empty,
|
||||
|
||||
// 修复:改为异步读取整数,确保类型兼容
|
||||
//合格标志(0默认,1合格,2不合格)
|
||||
QualificationFlag = (await ReadPlcIntAsync(plc, _plcIntMap["QualificationFlag"])).ToString(),
|
||||
//返工标志(0正常,1返工)
|
||||
ReworkFlag = (await ReadPlcIntAsync(plc, _plcIntMap["ReworkFlag"])).ToString(),
|
||||
//设备自动手动:0-自动,1-手动
|
||||
AutoManual = (await ReadPlcIntAsync(plc, _plcIntMap["AutoManual"])),
|
||||
//运行状态:1正常,2异常
|
||||
RunStatus = (await ReadPlcIntAsync(plc, _plcIntMap["AutoManual"])),
|
||||
//生产节拍秒
|
||||
ProductionCycle = await ReadPlcIntAsync(plc, _plcIntMap["ProductionCycle"])
|
||||
// 整数字段(读取失败返回0,不中断流程)
|
||||
QualificationFlag = (await intTasks["QualificationFlag"]).ToString(),
|
||||
ReworkFlag = (await intTasks["ReworkFlag"]).ToString(),
|
||||
AutoManual = await intTasks["AutoManual"],
|
||||
RunStatus = await intTasks["RunStatus"],
|
||||
ProductionCycle = await intTasks["ProductionCycle"]
|
||||
};
|
||||
|
||||
// 空值兜底(避免入库报错)
|
||||
// 空值兜底(保留你的原始逻辑)
|
||||
prodData.QualificationFlag ??= "0";
|
||||
prodData.ReworkFlag ??= "0";
|
||||
prodData.ProductionCycle ??= 0;
|
||||
|
||||
// 保存生产数据到MES数据库
|
||||
plcProductionDataService.AddPlcProductionData(prodData);
|
||||
return (true, prodData, "生产数据读取成功");
|
||||
// 6. 异步保存数据(非阻塞,提升响应速度)
|
||||
_ = Task.Run(() => _plcProductionDataService.AddPlcProductionData(prodData))
|
||||
.ContinueWith(t =>
|
||||
{
|
||||
if (t.IsFaulted)
|
||||
{
|
||||
// 记录保存失败日志(建议替换为ILogger)
|
||||
Console.WriteLine($"PLC({ip})数据保存失败:{t.Exception?.InnerException?.Message}");
|
||||
}
|
||||
});
|
||||
|
||||
var successMsg = isConnReused ? "生产数据读取成功(复用连接)" : "生产数据读取成功(新建连接)";
|
||||
return (true, prodData, successMsg);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 精细化异常日志(便于定位具体PLC故障)
|
||||
Console.WriteLine($"PLC({ip})生产数据读取异常:{ex.Message}\n{ex.StackTrace}");
|
||||
return (false, null, $"生产数据读取失败:{ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleasePlcConnection(plc);
|
||||
// 7. 资源安全释放(核心:复用连接不释放,仅新建连接释放;必须释放并发信号量)
|
||||
if (!isConnReused)
|
||||
{
|
||||
ReleasePlcConnection(plc);
|
||||
}
|
||||
_concurrencySemaphore.Release(); // 防止死锁的关键
|
||||
}
|
||||
}
|
||||
|
||||
// 可选:添加连接池清理方法(防止长期运行导致连接泄露)
|
||||
private void CleanupExpiredConnections()
|
||||
{
|
||||
var expiredTime = DateTime.Now.AddMinutes(-5); // 5分钟未使用的连接清理
|
||||
// 先复制所有Key到列表,避免遍历中修改原集合
|
||||
var allKeys = _plcConnPool.Keys.ToList();
|
||||
|
||||
foreach (var key in allKeys)
|
||||
{
|
||||
if (!_plcConnPool.TryGetValue(key, out var poolItem))
|
||||
continue;
|
||||
|
||||
if (poolItem.LastUsedTime < expiredTime)
|
||||
{
|
||||
if (_plcConnPool.TryRemove(key, out var removedItem))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (removedItem.Client != null && removedItem.Client.IsConnected)
|
||||
removedItem.Client.Close();
|
||||
if (removedItem.Client is IDisposable disposable)
|
||||
disposable.Dispose();
|
||||
// 可选:置空引用,帮助GC回收
|
||||
removedItem.Client = null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 静默释放,避免清理失败影响主流程
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 在类的构造函数中启动定时清理(可选)
|
||||
// public PlcService(IOptions<GlobalPlcConfig> globalConfig)
|
||||
// {
|
||||
// _globalConfig = globalConfig?.Value ?? throw new ArgumentNullException(nameof(globalConfig));
|
||||
// _plcConfigs = initPlcConfigs(_plcConfigs);
|
||||
// // 每30秒清理一次过期连接
|
||||
// new Timer(_ => CleanupExpiredConnections(), null, TimeSpan.Zero, TimeSpan.FromSeconds(30));
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 测试单个PLC的连接、读、写功能
|
||||
/// </summary>
|
||||
@ -391,16 +595,15 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
{
|
||||
if (plc.IsConnected)
|
||||
plc.Close();
|
||||
// 正确释放PLC实例(适配S7.Net显式实现IDisposable)
|
||||
if (plc is IDisposable disposable)
|
||||
disposable.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 记录日志(此处简化为控制台输出,实际项目替换为日志框架)
|
||||
Console.WriteLine($"PLC连接关闭失败:{ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
// 移除finally中的Dispose(),避免误释放服务
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -621,7 +824,7 @@ namespace RIZO.Admin.WebApi.PLC.Service
|
||||
var defaultResult = result ?? new List<PlcConfig>();
|
||||
try
|
||||
{
|
||||
List<PlcConfig> query = plantWorkstationService.Queryable()
|
||||
List<PlcConfig> query = _plantWorkstationService.Queryable()
|
||||
.Where(it => it.Status == 1)
|
||||
.Select(it => new PlcConfig
|
||||
{
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Controllers\MES\alarm\" />
|
||||
<Folder Include="Properties\PublishProfiles\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@ -4,7 +4,8 @@
|
||||
//"Conn": "Data Source=139.224.232.211;User ID=root;Password=RIZOtech123;Initial Catalog=ay2509055-guiyang-fluorescence-lmes;Port=3308;",
|
||||
//"Conn": "Data Source=43.142.238.124;User ID=root;Password=mysql_3AMPxs;Initial Catalog=valeo_lmes;Port=3308;",
|
||||
// "Conn": "Server=43.142.238.124,1433;Database=valeo_lmes_2;User Id=sa;Password=MSSQLP0ss_MBTc7D;Encrypt=True;TrustServerCertificate=True;",
|
||||
"Conn": "Server=127.0.0.1,1433;Database=valeo_lmes;User Id=root;Password=123456;Encrypt=True;TrustServerCertificate=True;",
|
||||
//"Conn": "Server=127.0.0.1,1433;Database=valeo_lmes;User Id=root;Password=123456;Encrypt=True;TrustServerCertificate=True;",
|
||||
"Conn": "Server=192.168.1.48,1433;Database=valeo_lmes;User Id=root;Password=123456;Encrypt=True;TrustServerCertificate=True;",
|
||||
//"Conn": "Data Source=127.0.0.1;User ID=root;Password=123456;Initial Catalog=valeo_lmes;Port=3306;",
|
||||
"DbType": 1, //数据库类型 MySql = 0, SqlServer = 1, Oracle = 3,PgSql = 4
|
||||
"ConfigId": "0", //多租户唯一标识
|
||||
@ -18,7 +19,8 @@
|
||||
//"Conn": "Data Source=139.224.232.211;User ID=root;Password=RIZOtech123;Initial Catalog={dbName};Port=3308;",
|
||||
//"Conn": "Data Source=192.168.1.48;User ID=root;Password=123456;Initial Catalog={dbName};Port=3306;",
|
||||
//"Conn": "Data Source=127.0.0.1;User ID=root;Password=123456;Initial Catalog={dbName};Port=3306;",
|
||||
"Conn": "Server=127.0.0.1,1433;Database={dbName};User Id=root;Password=123456;Encrypt=True;TrustServerCertificate=True;",
|
||||
//"Conn": "Server=127.0.0.1,1433;Database={dbName};User Id=root;Password=123456;Encrypt=True;TrustServerCertificate=True;",
|
||||
"Conn": "Server=192.168.1.48,1433;Database={dbName};User Id=root;Password=123456;Encrypt=True;TrustServerCertificate=True;",
|
||||
"IsAutoCloseConnection": true,
|
||||
"DbName": "valeo_lmes", //代码生成默认连接数据库,Oracle库是实例的名称
|
||||
"DbType": 1
|
||||
|
||||
64
RIZO.Model/MES/alarm/AlarmInfo.cs
Normal file
64
RIZO.Model/MES/alarm/AlarmInfo.cs
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
namespace RIZO.Model.MES.alarm
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC报警信息
|
||||
/// </summary>
|
||||
[SugarTable("alarm_info")]
|
||||
public class AlarmInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// ID
|
||||
/// </summary>
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工站编码
|
||||
/// </summary>
|
||||
public string WorkstationCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 报警问题类型
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "err_type")]
|
||||
public string ErrType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 问题编码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "err_code")]
|
||||
public string ErrCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建人
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "created_by")]
|
||||
public string CreatedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "created_time")]
|
||||
public DateTime? CreatedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新人
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "updated_by")]
|
||||
public string UpdatedBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "updated_time")]
|
||||
public DateTime? UpdatedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PLCIP
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "plc_ip")]
|
||||
public string PlcIp { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
47
RIZO.Model/MES/alarm/AlarmProblemDictionary.cs
Normal file
47
RIZO.Model/MES/alarm/AlarmProblemDictionary.cs
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
namespace RIZO.Model.MES.alarm
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC报警信息字典
|
||||
/// </summary>
|
||||
[SugarTable("AlarmProblemDictionary")]
|
||||
public class AlarmProblemDictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// WorkstationCode
|
||||
/// </summary>
|
||||
public string WorkstationCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// DataType
|
||||
/// </summary>
|
||||
public string DataType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// LogicalAddress
|
||||
/// </summary>
|
||||
public string LogicalAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Comment
|
||||
/// </summary>
|
||||
public string Comment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// CreatedTime
|
||||
/// </summary>
|
||||
public DateTime? CreatedTime { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
40
RIZO.Model/MES/alarm/Dto/AlarmInfoDto.cs
Normal file
40
RIZO.Model/MES/alarm/Dto/AlarmInfoDto.cs
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
namespace RIZO.Model.MES.alarm.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC报警信息查询对象
|
||||
/// </summary>
|
||||
public class AlarmInfoQueryDto : PagerInfo
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PLC报警信息输入输出对象
|
||||
/// </summary>
|
||||
public class AlarmInfoDto
|
||||
{
|
||||
[Required(ErrorMessage = "ID不能为空")]
|
||||
public int Id { get; set; }
|
||||
|
||||
public string WorkstationCode { get; set; }
|
||||
|
||||
public string ErrType { get; set; }
|
||||
|
||||
public string ErrCode { get; set; }
|
||||
|
||||
public string CreatedBy { get; set; }
|
||||
|
||||
public DateTime? CreatedTime { get; set; }
|
||||
|
||||
public string UpdatedBy { get; set; }
|
||||
|
||||
public DateTime? UpdatedTime { get; set; }
|
||||
|
||||
public string PlcIp { get; set; }
|
||||
|
||||
|
||||
|
||||
[ExcelColumn(Name = "报警问题类型")]
|
||||
public string ErrTypeLabel { get; set; }
|
||||
}
|
||||
}
|
||||
36
RIZO.Model/MES/alarm/Dto/AlarmProblemDictionaryDto.cs
Normal file
36
RIZO.Model/MES/alarm/Dto/AlarmProblemDictionaryDto.cs
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
namespace RIZO.Model.MES.alarm.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC报警信息字典查询对象
|
||||
/// </summary>
|
||||
public class AlarmProblemDictionaryQueryDto : PagerInfo
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PLC报警信息字典输入输出对象
|
||||
/// </summary>
|
||||
public class AlarmProblemDictionaryDto
|
||||
{
|
||||
[Required(ErrorMessage = "Id不能为空")]
|
||||
public int Id { get; set; }
|
||||
|
||||
public string WorkstationCode { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string DataType { get; set; }
|
||||
|
||||
public string LogicalAddress { get; set; }
|
||||
|
||||
public string Comment { get; set; }
|
||||
|
||||
public DateTime? CreatedTime { get; set; }
|
||||
|
||||
|
||||
|
||||
[ExcelColumn(Name = "DataType")]
|
||||
public string DataTypeLabel { get; set; }
|
||||
}
|
||||
}
|
||||
@ -13,4 +13,8 @@
|
||||
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.207" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="MES\alarm\Dto\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
79
RIZO.Service/MES/alarm/AlarmInfoService.cs
Normal file
79
RIZO.Service/MES/alarm/AlarmInfoService.cs
Normal file
@ -0,0 +1,79 @@
|
||||
using Infrastructure.Attribute;
|
||||
using Infrastructure.Extensions;
|
||||
using RIZO.Model.MES.alarm;
|
||||
using RIZO.Model.MES.alarm.Dto;
|
||||
using RIZO.Repository;
|
||||
using RIZO.Service.MES.alarm.IService;
|
||||
|
||||
namespace RIZO.Service.MES.alarm
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC报警信息Service业务层处理
|
||||
/// </summary>
|
||||
[AppService(ServiceType = typeof(IAlarmInfoService), ServiceLifetime = LifeTime.Transient)]
|
||||
public class AlarmInfoService : BaseService<AlarmInfo>, IAlarmInfoService
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询PLC报警信息列表
|
||||
/// </summary>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
public PagedInfo<AlarmInfoDto> GetList(AlarmInfoQueryDto parm)
|
||||
{
|
||||
var predicate = QueryExp(parm);
|
||||
|
||||
var response = Queryable()
|
||||
.Where(predicate.ToExpression())
|
||||
.ToPage<AlarmInfo, AlarmInfoDto>(parm);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取详情
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
/// <returns></returns>
|
||||
public AlarmInfo GetInfo(int Id)
|
||||
{
|
||||
var response = Queryable()
|
||||
.Where(x => x.Id == Id)
|
||||
.First();
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加PLC报警信息
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public AlarmInfo AddAlarmInfo(AlarmInfo model)
|
||||
{
|
||||
return Insertable(model).ExecuteReturnEntity();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改PLC报警信息
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public int UpdateAlarmInfo(AlarmInfo model)
|
||||
{
|
||||
return Update(model, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询导出表达式
|
||||
/// </summary>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
private static Expressionable<AlarmInfo> QueryExp(AlarmInfoQueryDto parm)
|
||||
{
|
||||
var predicate = Expressionable.Create<AlarmInfo>();
|
||||
|
||||
return predicate;
|
||||
}
|
||||
}
|
||||
}
|
||||
80
RIZO.Service/MES/alarm/AlarmProblemDictionaryService.cs
Normal file
80
RIZO.Service/MES/alarm/AlarmProblemDictionaryService.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using Infrastructure.Attribute;
|
||||
using Infrastructure.Extensions;
|
||||
using RIZO.Model.MES.alarm;
|
||||
using RIZO.Model.MES.alarm.Dto;
|
||||
using RIZO.Repository;
|
||||
using RIZO.Service.Mes.IMesService;
|
||||
using RIZO.Service.MES.alarm.IService;
|
||||
|
||||
namespace RIZO.Service.MES.alarm
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC报警信息字典Service业务层处理
|
||||
/// </summary>
|
||||
[AppService(ServiceType = typeof(IAlarmProblemDictionaryService), ServiceLifetime = LifeTime.Transient)]
|
||||
public class AlarmProblemDictionaryService : BaseService<AlarmProblemDictionary>, IAlarmProblemDictionaryService
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询PLC报警信息字典列表
|
||||
/// </summary>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
public PagedInfo<AlarmProblemDictionaryDto> GetList(AlarmProblemDictionaryQueryDto parm)
|
||||
{
|
||||
var predicate = QueryExp(parm);
|
||||
|
||||
var response = Queryable()
|
||||
.Where(predicate.ToExpression())
|
||||
.ToPage<AlarmProblemDictionary, AlarmProblemDictionaryDto>(parm);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取详情
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
/// <returns></returns>
|
||||
public AlarmProblemDictionary GetInfo(int Id)
|
||||
{
|
||||
var response = Queryable()
|
||||
.Where(x => x.Id == Id)
|
||||
.First();
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加PLC报警信息字典
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public AlarmProblemDictionary AddAlarmProblemDictionary(AlarmProblemDictionary model)
|
||||
{
|
||||
return Insertable(model).ExecuteReturnEntity();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改PLC报警信息字典
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public int UpdateAlarmProblemDictionary(AlarmProblemDictionary model)
|
||||
{
|
||||
return Update(model, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询导出表达式
|
||||
/// </summary>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
private static Expressionable<AlarmProblemDictionary> QueryExp(AlarmProblemDictionaryQueryDto parm)
|
||||
{
|
||||
var predicate = Expressionable.Create<AlarmProblemDictionary>();
|
||||
|
||||
return predicate;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
RIZO.Service/MES/alarm/IService/IAlarmInfoService.cs
Normal file
21
RIZO.Service/MES/alarm/IService/IAlarmInfoService.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using RIZO.Model.MES.alarm;
|
||||
using RIZO.Model.MES.alarm.Dto;
|
||||
|
||||
namespace RIZO.Service.MES.alarm.IService
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC报警信息service接口
|
||||
/// </summary>
|
||||
public interface IAlarmInfoService : IBaseService<AlarmInfo>
|
||||
{
|
||||
PagedInfo<AlarmInfoDto> GetList(AlarmInfoQueryDto parm);
|
||||
|
||||
AlarmInfo GetInfo(int Id);
|
||||
|
||||
|
||||
AlarmInfo AddAlarmInfo(AlarmInfo parm);
|
||||
int UpdateAlarmInfo(AlarmInfo parm);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
|
||||
|
||||
using RIZO.Model.MES.alarm;
|
||||
using RIZO.Model.MES.alarm.Dto;
|
||||
|
||||
namespace RIZO.Service.MES.alarm.IService
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC报警信息字典service接口
|
||||
/// </summary>
|
||||
public interface IAlarmProblemDictionaryService : IBaseService<AlarmProblemDictionary>
|
||||
{
|
||||
PagedInfo<AlarmProblemDictionaryDto> GetList(AlarmProblemDictionaryQueryDto parm);
|
||||
|
||||
AlarmProblemDictionary GetInfo(int Id);
|
||||
|
||||
|
||||
AlarmProblemDictionary AddAlarmProblemDictionary(AlarmProblemDictionary parm);
|
||||
int UpdateAlarmProblemDictionary(AlarmProblemDictionary parm);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user