Files
WCS/Plugins/Wcs/Plugin.Cowain.Wcs/Actions/6180/Station6180Action.cs
2026-03-02 09:13:29 +08:00

176 lines
7.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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; }
}