Files
WCS/Plugins/Wcs/Plugin.Cowain.Wcs/Actions/6180/Station6180Action.cs

176 lines
7.0 KiB
C#
Raw Normal View History

2026-03-02 09:13:29 +08:00
using Cowain.Base.Models;
using HslCommunication;
using HslCommunication.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Plugin.Cowain.Driver;
using Plugin.Cowain.Driver.Abstractions;
using Plugin.Cowain.Driver.Attributes;
using Plugin.Cowain.Driver.Models;
using Plugin.Cowain.Wcs.IServices;
using Plugin.Cowain.Wcs.Models.Enum;
using Plugin.Cowain.Wcs.Services;
using System.Text.Json;
namespace Plugin.Cowain.Wcs.Actions;
/// <summary>
/// 20250812简化批量写
/// </summary>
[Action("Station6180", "上下料请求6180")]
public class Station6180Action : IVariableAction
{
private class ParamData
{
/// <summary>
/// PLC名称
/// </summary>
public string StationCode { get; set; } = string.Empty;
/// <summary>
/// PLC名称
/// </summary>
public string PlcName { get; set; } = string.Empty;
/// <summary>
/// 命令地址
/// </summary>
public string CmdAddress { get; set; } = string.Empty;
/// <summary>
/// 反馈命令地址
/// </summary>
public string RetCmdAddress { get; set; } = string.Empty;
}
private readonly IDeviceMonitor _deviceMonitor;
private IServiceScopeFactory _scopeFactory;
private readonly ILogger<Station6180Action> _logger;
public Station6180Action(IDeviceMonitor deviceMonitor, IServiceScopeFactory scopeFactory, ILogger<Station6180Action> logger)
{
_deviceMonitor = deviceMonitor;
_scopeFactory = scopeFactory;
_logger = logger;
}
public async Task<ResultModel> ExecuteAsync(VariableAction variableAction, CancellationToken cancellationToken)
{
_logger.LogInformation($"执行测试事件:{variableAction.Variable.Name}-{variableAction.Variable.Address},参数:{variableAction.Param},旧值:{variableAction.Variable.OldValue},新值:{variableAction.Variable.Value}");
var _param = JsonSerializer.Deserialize<ParamData>(variableAction.Param);
if (_param == null)
{
return ResultModel.Error("参数解析失败");
}
var driver = _deviceMonitor.GetDriver(_param.PlcName);
if (!driver.IsSuccess)
{
return ResultModel.Error($"未找到名称为 {_param.PlcName} 的Driver");
}
var plc = driver.Data.GetReadWrite();
if (plc == null)
{
return ResultModel.Error($"GetReadWrite为空PLC={_param.PlcName}");
}
var read = await ReadAsync(plc, _param.CmdAddress);
if (!read.IsSuccess)
{
_logger.LogError($"从PLC读取工站数据失败{_param.PlcName}->{_param.CmdAddress}{read.ErrorMessage}");
return ResultModel.Error($"读命令失败:{_param.PlcName}->{_param.CmdAddress}{read.ErrorMessage}");
}
using var scope = _scopeFactory.CreateScope();
var stationService = scope.ServiceProvider.GetRequiredService<IStationService>();
var stations = await stationService.GetAllAsync();
var station = stations.FirstOrDefault(x => x.StationCode == _param.StationCode);
if (station == null)
{
_logger.LogError($"工站不存在,请检查:{_param.StationCode}");
return ResultModel.Error($"工站不存在,请检查:{_param.StationCode}");
}
station.UpdateSource = StationUpdateSourceEnum.PLC;
if (read.Data.Command == (short)StationStateEnum.RequestPick)
{
station.Status = StationStateEnum.RequestPick.ToString();
station.QrCode = read.Data.QrCode;
}
else if (read.Data.Command == (short)StationStateEnum.RequestPlace)
{
station.Status = StationStateEnum.RequestPlace.ToString();
}
else if (read.Data.Command == (short)StationStateEnum.NgPick)
{
station.Status = StationStateEnum.NgPick.ToString();
station.QrCode = read.Data.QrCode;
}
else if (read.Data.Command == 1)
{
//清除工站信息
station.QrCode = "";
station.ProcessName = "";
station.Status = StationStateEnum.UnKnown.ToString();
}
else
{
_logger.LogError($"命令不正确,请检查:{_param.StationCode}{read.Data.Command}");
return ResultModel.Error($"命令不正确,请检查:{_param.StationCode}{read.Data.Command}");
}
station.ProcessName = read.Data.ProcessName;
//这里没有判断产品名称是否正确如果不正确需要返回PLC NG,待完善
_logger.LogInformation($"工站更新开始:{_param.StationCode}{read.Data.Command}");
var stationTaskHandler = scope.ServiceProvider.GetRequiredService<IEnumerable<IHostedService>>();
var stationQueueHostedService = stationTaskHandler.OfType<StationQueueHostedService>().FirstOrDefault();
var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
station.UpdatedAction = result => tcs.TrySetResult(result);
stationQueueHostedService?.Enqueue(station);
var ret = await tcs.Task;
_logger.LogInformation($"工站更新结束:{_param.StationCode}{read.Data.Command}");
//使用批量写入保证PLC数据一致性避免出现部分数据未写成功的情况要么都没写成功
if (ret)
{
//工站更新OK
var writeResult = await plc.WriteValuesAysnc(_param.RetCmdAddress, new short[] { read.Data.Command, (short)1, read.Data.Count });
}
else
{
//工站更新NG
var writeResult = await plc.WriteValuesAysnc(_param.RetCmdAddress, new short[] { read.Data.Command, (short)2, read.Data.Count });
}
return ResultModel.Success();
}
private async Task<ResultModel<StationRequestData>> ReadAsync(IReadWriteDevice driver, string address)
{
var readResult = await driver.ReadAsync(address, 70);
if (!readResult.IsSuccess)
{
ResultModel<StationRequestData>.Error(readResult.Message);
}
StationRequestData requestData = new StationRequestData
{
Command = driver.ByteTransform.TransInt16(readResult.Content, 0),
Count = driver.ByteTransform.TransInt16(readResult.Content, 2),
ProcessName = readResult.Content.RemoveBegin(4).GetS7String(),
NgStationName = readResult.Content.RemoveBegin(26).GetS7String(),
QrCode = readResult.Content.RemoveBegin(48).GetS7String()
};
return ResultModel<StationRequestData>.Success(requestData);
}
}
public class StationRequestData
{
public string QrCode { get; set; } = string.Empty;
public string ProcessName { get; set; } = string.Empty;
public string NgStationName { get; set; } = string.Empty;
public short Command { get; set; }
public short Count { get; set; }
}