306 lines
11 KiB
C#
306 lines
11 KiB
C#
|
|
using WcsMain.Common;
|
|||
|
|
using WcsMain.DataBase.TableEntity;
|
|||
|
|
using WcsMain.Enum.Stacker;
|
|||
|
|
using WcsMain.PlcOperation.Entity;
|
|||
|
|
using WcsMain.PlcOperation.Entity.Stacker;
|
|||
|
|
using WcsMain.WcsAttribute.AutoFacAttribute;
|
|||
|
|
|
|||
|
|
namespace WcsMain.PlcOperation.Stacker;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 堆垛机操作
|
|||
|
|
/// </summary>
|
|||
|
|
[Component]
|
|||
|
|
public class StackerOperation
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
|
|||
|
|
/********************************** 总结方法 *******************************************/
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 判断堆垛机状态,若是等待(二次申请)状态则带出当前的PlcId
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="stackerId"></param>
|
|||
|
|
/// <param name="plcId"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public StackerUseStatusEnum StackerCanUse(int? stackerId, out int plcId)
|
|||
|
|
{
|
|||
|
|
plcId = 0;
|
|||
|
|
if (stackerId == default) return StackerUseStatusEnum.BusyOrErr;
|
|||
|
|
/* 获取堆垛机状态 */
|
|||
|
|
var (errMsg, stackerInfo) = GetStackerInfo((int)stackerId!);
|
|||
|
|
if(!string.IsNullOrEmpty(errMsg) || stackerInfo == default) return StackerUseStatusEnum.BusyOrErr;
|
|||
|
|
/* 堆垛机空闲条件 */
|
|||
|
|
var canUse = stackerInfo.PlcId == 0 && stackerInfo.ControlModel == StackerControlModeEnum.online
|
|||
|
|
&& stackerInfo.StackerStatus == StackerStatusEnum.free && stackerInfo.ErrCode == 0;
|
|||
|
|
if (canUse) return StackerUseStatusEnum.Free;
|
|||
|
|
/* 堆垛机等待任务条件(二次申请) */
|
|||
|
|
var waitTask = stackerInfo.ControlModel == StackerControlModeEnum.online && stackerInfo.StackerStatus == StackerStatusEnum.applyTask
|
|||
|
|
&& stackerInfo.ErrCode == 0;
|
|||
|
|
if(waitTask)
|
|||
|
|
{
|
|||
|
|
plcId = stackerInfo.PlcId;
|
|||
|
|
return StackerUseStatusEnum.waitTask;
|
|||
|
|
}
|
|||
|
|
return StackerUseStatusEnum.BusyOrErr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/********************************** 子方法 *******************************************/
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 读取堆垛机反馈信息
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="stackerId"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public (string? errText, StackerInfo? stackerInfo) GetStackerInfo(int stackerId)
|
|||
|
|
{
|
|||
|
|
if (!CommonData.IsConnectPlc || CommonTool.Siemens == default)
|
|||
|
|
{
|
|||
|
|
return ("设备尚未连接", default); // 未连接PLC
|
|||
|
|
}
|
|||
|
|
var readResult = CommonTool.Siemens.ReadByteWithName($"堆垛机状态反馈{stackerId}", 24);
|
|||
|
|
if (!readResult.Success || readResult.Value == default)
|
|||
|
|
{
|
|||
|
|
return (readResult.Message, default); // 读取失败
|
|||
|
|
}
|
|||
|
|
var data = readResult.Value;
|
|||
|
|
StackerInfo stackerInfo = new()
|
|||
|
|
{
|
|||
|
|
PlcId = Convert.ToInt32(CommonTool.Siemens.Trans<int>(data, 0)), // 当前运行任务号
|
|||
|
|
ControlModel = (StackerControlModeEnum)Convert.ToInt16(CommonTool.Siemens.Trans<short>(data, 4)), // 控制方式
|
|||
|
|
StackerStatus = (StackerStatusEnum)Convert.ToInt16(CommonTool.Siemens.Trans<short>(data, 6)), // 堆垛机状态
|
|||
|
|
TunnelId = Convert.ToInt16(CommonTool.Siemens.Trans<short>(data, 8)), // 当前巷道
|
|||
|
|
Row = Convert.ToInt16(CommonTool.Siemens.Trans<short>(data, 10)), // 当前排
|
|||
|
|
Line = Convert.ToInt16(CommonTool.Siemens.Trans<short>(data, 12)), // 当前列
|
|||
|
|
Layer = Convert.ToInt16(CommonTool.Siemens.Trans<short>(data, 14)), // 当前层
|
|||
|
|
Depth = Convert.ToInt16(CommonTool.Siemens.Trans<short>(data, 16)), // 当前深度
|
|||
|
|
Code = Convert.ToInt32(CommonTool.Siemens.Trans<int>(data, 18)), // 料箱码
|
|||
|
|
ErrCode = Convert.ToInt16(CommonTool.Siemens.Trans<short>(data, 22)), // 错误码
|
|||
|
|
// WorkLength = Convert.ToSingle(CommonTool.Siemens.Trans<float>(data, 24)), // 行走距离
|
|||
|
|
// UpLength = Convert.ToSingle(CommonTool.Siemens.Trans<float>(data, 28)), // 提升距离
|
|||
|
|
// ForkCount = Convert.ToInt32(CommonTool.Siemens.Trans<int>(data, 32)), // 货叉动作次数
|
|||
|
|
// SubmitPlcId = Convert.ToInt32(CommonTool.Siemens.Trans<int>(data, 36)), // 提交的任务
|
|||
|
|
// DeletePlcId = Convert.ToInt32(CommonTool.Siemens.Trans<int>(data, 40)), // 删除的任务
|
|||
|
|
// Spare1 = Convert.ToInt32(CommonTool.Siemens.Trans<int>(data, 44)), // 备用1
|
|||
|
|
// Spare2 = Convert.ToInt16(CommonTool.Siemens.Trans<short>(data, 48)), // 备用2
|
|||
|
|
};
|
|||
|
|
return (string.Empty, stackerInfo);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 读取所有故障
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="stackerId"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public bool[]? GetStackerErrInfo(int stackerId)
|
|||
|
|
{
|
|||
|
|
if (!CommonData.IsConnectPlc || CommonTool.Siemens == default)
|
|||
|
|
{
|
|||
|
|
return default; // 未连接PLC
|
|||
|
|
}
|
|||
|
|
var readResult = CommonTool.Siemens.ReadBoolWithName($"堆垛机当前报警{stackerId}", 96);
|
|||
|
|
if (!readResult.Success || readResult.Value == default)
|
|||
|
|
{
|
|||
|
|
return default;
|
|||
|
|
}
|
|||
|
|
var data = readResult.Value;
|
|||
|
|
return [.. data];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 复位堆垛机
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="stackerId"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public string ResetStacker(string? stackerId)
|
|||
|
|
{
|
|||
|
|
if (!CommonData.IsConnectPlc || CommonTool.Siemens == default)
|
|||
|
|
{
|
|||
|
|
// 未连接PLC
|
|||
|
|
return "PLC尚未连接";
|
|||
|
|
}
|
|||
|
|
var (readResult, _) = CommonTool.Siemens.WritePlcWhithName($"堆垛机复位{stackerId}", (short)1);
|
|||
|
|
if (readResult.Success)
|
|||
|
|
{
|
|||
|
|
return string.Empty;
|
|||
|
|
}
|
|||
|
|
return readResult.Message ?? "请求失败,请检查网络";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 堆垛机继续运行
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="stackerId"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public string StackerContinue(string? stackerId)
|
|||
|
|
{
|
|||
|
|
if (!CommonData.IsConnectPlc || CommonTool.Siemens == default)
|
|||
|
|
{
|
|||
|
|
// 未连接PLC
|
|||
|
|
return "PLC尚未连接";
|
|||
|
|
}
|
|||
|
|
var (readResult, _) = CommonTool.Siemens.WritePlcWhithName($"堆垛机继续运行{stackerId}", (short)1);
|
|||
|
|
if (readResult.Success)
|
|||
|
|
{
|
|||
|
|
return string.Empty;
|
|||
|
|
}
|
|||
|
|
return readResult.Message ?? "请求失败,请检查网络";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取报警编号
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="stackerNo"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public int GetErrCode(int? stackerNo)
|
|||
|
|
{
|
|||
|
|
if (!CommonData.IsConnectPlc || CommonTool.Siemens == default)
|
|||
|
|
{
|
|||
|
|
return -1; // 未连接PLC
|
|||
|
|
}
|
|||
|
|
var readResult = CommonTool.Siemens.ReadInt16WithName($"报警编号{stackerNo}");
|
|||
|
|
return readResult.Success ? readResult.Value : -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 堆垛机任务写入确认
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="stackerId"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public string WriteTaskConfirm(int stackerId)
|
|||
|
|
{
|
|||
|
|
if (!CommonData.IsConnectPlc || CommonTool.Siemens == default)
|
|||
|
|
{
|
|||
|
|
// 未连接PLC
|
|||
|
|
return "PLC尚未连接。";
|
|||
|
|
}
|
|||
|
|
var (writeResult, _) = CommonTool.Siemens.WritePlcWhithName($"堆垛机写任务确认{stackerId}", (short)1);
|
|||
|
|
if (writeResult.Success)
|
|||
|
|
{
|
|||
|
|
return string.Empty;
|
|||
|
|
}
|
|||
|
|
return writeResult.Message ?? "写入失败";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 写入堆垛机任务,返回错误信息
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="task"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public string WriteTask(StackerPlcTask task)
|
|||
|
|
{
|
|||
|
|
if (!CommonData.IsConnectPlc || CommonTool.Siemens == default) return "PLC尚未连接。"; // 未连接PLC
|
|||
|
|
var (writeResult, _) = CommonTool.Siemens.WritePlcWhithName($"堆垛机写任务{task.StackerId}",
|
|||
|
|
task.PlcId!,
|
|||
|
|
task.TaskType!,
|
|||
|
|
task.GetStand!,
|
|||
|
|
task.InTunnelId!,
|
|||
|
|
task.OutTunnelId!,
|
|||
|
|
task.SetStand!,
|
|||
|
|
task.GetQueue!,
|
|||
|
|
task.GetLine!,
|
|||
|
|
task.GetLayer!,
|
|||
|
|
task.SetQueue!,
|
|||
|
|
task.SetLine!,
|
|||
|
|
task.SetLayer!,
|
|||
|
|
task.GetDeep!,
|
|||
|
|
task.SetDeep!,
|
|||
|
|
task.Size!,
|
|||
|
|
task.Weight!,
|
|||
|
|
task.Code
|
|||
|
|
);
|
|||
|
|
return writeResult.Success ? string.Empty : writeResult.Message ?? "写入失败";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取过账数据
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="dataNum"></param>
|
|||
|
|
/// <param name="stackerList"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public List<TaskFeedBackEntity>? GetTaskFeedBackData(int dataNum, List<AppStacker> stackerList)
|
|||
|
|
{
|
|||
|
|
if (!CommonData.IsConnectPlc || CommonTool.Siemens == default)
|
|||
|
|
{
|
|||
|
|
return default; // 未连接PLC
|
|||
|
|
}
|
|||
|
|
List<TaskFeedBackEntity> taskFeedBackEntities = [];
|
|||
|
|
foreach (var stacker in stackerList)
|
|||
|
|
{
|
|||
|
|
var readResult = CommonTool.Siemens.ReadByteWithName($"过账区{stacker.StackerId}", (ushort)(6 * dataNum));
|
|||
|
|
if (!readResult.Success) { continue; }
|
|||
|
|
var readData = readResult.Value;
|
|||
|
|
if (readData == default) { continue; }
|
|||
|
|
for (var i = 0; i < dataNum; i++)
|
|||
|
|
{
|
|||
|
|
TaskFeedBackEntity taskFeedBackEntity = new()
|
|||
|
|
{
|
|||
|
|
StackerId = stacker.StackerId ?? 0,
|
|||
|
|
PlcId = Convert.ToInt32(CommonTool.Siemens.Trans<int>(readData, 0 + i * 6)),
|
|||
|
|
FeedBackType = Convert.ToInt16(CommonTool.Siemens.Trans<short>(readData, 4 + i * 6)),
|
|||
|
|
CountNo = i
|
|||
|
|
};
|
|||
|
|
taskFeedBackEntities.Add(taskFeedBackEntity);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return taskFeedBackEntities;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 重置过账缓冲区 --- 写反馈区间接清除
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="taskFeedBackData"></param>
|
|||
|
|
public string? ResetFeedBackData(TaskFeedBackEntity taskFeedBackData)
|
|||
|
|
{
|
|||
|
|
if (!CommonData.IsConnectPlc || CommonTool.Siemens == default)
|
|||
|
|
{
|
|||
|
|
return "PLC 未连接"; // 未连接PLC
|
|||
|
|
}
|
|||
|
|
var dbAddress = CommonTool.Siemens.GetAddressWithNameAndBit($"过账区反馈区{taskFeedBackData.StackerId}", 4 * taskFeedBackData.CountNo);
|
|||
|
|
if (string.IsNullOrEmpty(dbAddress))
|
|||
|
|
{
|
|||
|
|
return "无法计算偏移量";
|
|||
|
|
}
|
|||
|
|
var plcNo = taskFeedBackData.StackerId;
|
|||
|
|
var writeResult = CommonTool.Siemens.WritePlcWhithAddress(plcNo, dbAddress, taskFeedBackData.PlcId);
|
|||
|
|
return writeResult.Success ? default : $"清除过账失败,异常信息:{writeResult.Message}";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 重置过账缓冲区 --- 直接清除
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="taskFeedBackData"></param>
|
|||
|
|
public string? ClearFeedBackData(TaskFeedBackEntity taskFeedBackData)
|
|||
|
|
{
|
|||
|
|
if (!CommonData.IsConnectPlc || CommonTool.Siemens == default)
|
|||
|
|
{
|
|||
|
|
return "PLC 未连接"; // 未连接PLC
|
|||
|
|
}
|
|||
|
|
var dbAddress = CommonTool.Siemens.GetAddressWithNameAndBit($"过账区{taskFeedBackData.StackerId}", 6 * taskFeedBackData.CountNo);
|
|||
|
|
if (string.IsNullOrEmpty(dbAddress))
|
|||
|
|
{
|
|||
|
|
return "无法计算偏移量";
|
|||
|
|
}
|
|||
|
|
var writeResult = CommonTool.Siemens.WritePlcWhithAddress(1, dbAddress, 0);
|
|||
|
|
return !writeResult.Success ? $"清除过账失败,异常信息:{writeResult.Message}" : default;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|