You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

532 lines
15 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Text.Json.Nodes;
using Autofac;
using AutoMapper;
using Entity.Api.Resp;
using Entity.Constant;
using Entity.DbModel.Station;
using HybirdFrameworkCore.Autofac;
using HybirdFrameworkCore.Autofac.Attribute;
using HybirdFrameworkCore.Entity;
using HybirdFrameworkDriver.Session;
using HybirdFrameworkDriver.TcpClient;
using log4net;
using Newtonsoft.Json;
using Repository.Station;
using Service.Charger.Client;
using Service.Charger.Codec;
using Service.Charger.Handler;
using Service.Charger.Msg.Host.Req;
using Service.Execute;
using Service.Plc.Msg.Host.Req;
namespace Service.Charger.Server;
[Scope]
public class PlcClient : TcpClient<IBaseHandler, Decoder, Encoder>
{
//0 待机 1换电任务 2:移仓任务 3:消防任务
#region 属性
private long TaskNo = 0;
/// <summary>
/// Plc编号
/// </summary>
public string Sn { get; set; }
/// <summary>
///
/// </summary>
public bool SwapDone { get; set; }
/// <summary>
/// 换电开始标记
/// </summary>
public bool SwapStart { get; set; }
/// <summary>
/// 电池搬运结束
/// </summary>
public bool BatteryMoveDone { get; set; }
public bool DisassembleDone { get; set; }
//自动模式
public bool Auto { get; set; }
//远程模式
public bool Remote { get; set; }
//初始化完成
public bool Init { get; set; }
//9号仓是否有电池
public bool Is9Exist { get; set; }
private readonly BinInfoRepository _binInfoRepository;
public PlcClient(BinInfoRepository binInfoRepository)
{
_binInfoRepository = binInfoRepository;
}
#endregion
//修改当前任务
public void ExChangeTaskNo(long taskNo)
{
Interlocked.Exchange(ref TaskNo, taskNo);
}
//重置当前任务
public void ResetTaskNo()
{
Interlocked.Exchange(ref TaskNo, 0);
}
public bool IsTaskFree()
{
return ReadTaskNo() == 0l;
}
//读取当前任务
public long ReadTaskNo()
{
return Interlocked.Read(ref TaskNo);
}
#region send
/// <summary>
/// 发送初始化命令
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
public Result<bool> SendInitializeCommandReq()
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
InitializeCommandReq req = new InitializeCommandReq();
this.Channel.WriteAndFlushAsync(req);
StationSoftMgr.PutDeviceLog((int)StationConstant.DeviceCode.Plc,SwapConstant.PlcProtocol.Init,
JsonConvert.SerializeObject(req),(int)SwapConstant.CommunicationType.Send);
return Result<bool>.Success();
}
/// <summary>
/// 发送出库命令
/// </summary>
/// <param name="outboundMode">出库方式</param>
/// <param name="takePositionNumber">取仓位号</param>
public Result<bool> SendOutboundCommandReq(byte outboundMode,byte takePositionNumber)
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
OutboundCommandReq req = new OutboundCommandReq(outboundMode, takePositionNumber)
{
OutboundMode = outboundMode,
TakePositionNumber = takePositionNumber,
};
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
/// <summary>
/// 发送红绿灯
/// </summary>
/// <param name="trafficLight">出库方式</param>
public Result<bool> SendTrafficLightReq(byte trafficLight)
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
TrafficLightReq req = new TrafficLightReq(trafficLight)
{
TrafficLight = trafficLight,
};
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
/// <summary>
/// 发送开始换电命令
/// </summary>
/// <param name="takePositionNumber">取仓位号</param>
/// <param name="positionNumber">存仓位号</param>
/// <returns></returns>
public Result<bool> SendStartBatterySwapReq(byte takePositionNumber,byte positionNumber)
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
StartBatterySwapReq req = new StartBatterySwapReq(takePositionNumber, positionNumber)
{
TakePositionNumber = takePositionNumber,
PositionNumber = positionNumber,
};
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
/// <summary>
/// 发送开始搬电命令
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
public Result<bool> SendStartMovElectricityReq(byte takeBatteryShelfNumber,byte saveBatteryShelfNumber)
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
StartMovElectricityReq req = new StartMovElectricityReq(takeBatteryShelfNumber, saveBatteryShelfNumber)
{
TakeBatteryShelfNumber = takeBatteryShelfNumber,
SaveBatteryShelfNumber = saveBatteryShelfNumber,
};
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
/// <summary>
/// 发送车辆型号
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
public Result<bool> SendVehicleModelReq(byte cartNo)
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
VehicleModelReq req = new VehicleModelReq(cartNo)
{
CartNo = cartNo,
};
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
/// <summary>
/// 发送移库命令
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
public Result<bool> SendMoveCommandReq(byte takePositionNumber,byte positionNumber)
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
MoveCommandReq req = new MoveCommandReq(takePositionNumber, positionNumber)
{
TakePositionNumber = takePositionNumber,
PositionNumber = positionNumber,
};
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
/// <summary>
/// 发送继续命令
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
public Result<bool> SendContinueCommandReq( )
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
ContinueCommandReq req = new ContinueCommandReq();
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
/// <summary>
/// 发送暂停命令
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
public Result<bool> SendPauseCommandReq()
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
PauseCommandReq req = new PauseCommandReq();
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
/// <summary>
/// 发送入库命令
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
public Result<bool> SendInboundCommandsReq(byte positionNumber)
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
InboundCommandsReq req = new InboundCommandsReq(positionNumber)
{
PositionNumber = positionNumber,
};
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
/// <summary>
/// 发送入库命令修改为红绿灯
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
// public Result<bool> SendInboundCommandsReq(byte positionNumber)
// {
// if (!Connected)
// {
// return Result<bool>.Fail($"Plc{Sn}未连接");
// }
// InboundCommandsReq req = new InboundCommandsReq(positionNumber)
// {
// PositionNumber = positionNumber,
// };
// this.Channel.WriteAndFlushAsync(req);
// return Result<bool>.Success();
// }
/// <summary>
/// 发送终止命令
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
public Result<bool> SendTerminationOrderReq( )
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
TerminationOrderReq req = new TerminationOrderReq();
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
/// <summary>
/// 发送故障复位命令
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
public Result<bool> SendFaultResetReq()
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
FaultResetReq req = new FaultResetReq();
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
/// <summary>
/// 发送电池充电状态
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
public Result<bool> SendWhetherChargedReq()
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
List<BinInfo> binInfos = _binInfoRepository.Query();
var configuration = new MapperConfiguration(cfg => cfg.CreateMap<BinInfo, BinInfoResp>());
var mapper = configuration.CreateMapper();
List<BinInfoResp> binInfoList = mapper.Map<List<BinInfoResp>>(binInfos);
byte[] granaries = new byte[8];
for (int i = 0; i < binInfoList.Count && i < granaries.Length; i++)
{
granaries[i] = (binInfoList[i].ChargeStatus == 0 || binInfoList[i].ChargeStatus.Value == 2 || binInfoList[i].ChargeStatus.Value == 4) ? (byte)0 : (byte)1;
}
WhetherChargedReq req=new WhetherChargedReq(granaries[0], granaries[1], granaries[2], granaries[3], granaries[4], granaries[5], granaries[6], granaries[7]);
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
///// <summary>
///// 发送电池充电状态
///// </summary>
///// <param name="sn">Plc编号</param>
///// <param name="msg">消息</param>
//public Result<bool> SendWhetherChargedResq()
//{
// if (!Connected)
// {
// return Result<bool>.Fail($"Plc{Sn}未连接");
// }
// List<BinInfo> binInfos = _binInfoRepository.Query();
// var configuration = new MapperConfiguration(cfg => cfg.CreateMap<BinInfo, BinInfoResp>());
// var mapper = configuration.CreateMapper();
// List<BinInfoResp> binInfoList = mapper.Map<List<BinInfoResp>>(binInfos);
// byte[] granaries = new byte[8];
// for (int i = 0; i < binInfoList.Count && i < granaries.Length; i++)
// {
// granaries[i] = (binInfoList[i].ChargeStatus == 0 || binInfoList[i].ChargeStatus.Value == 2 || binInfoList[i].ChargeStatus.Value == 4) ? (byte)0 : (byte)1;
// }
// WhetherChargedResq req = new WhetherChargedResq(granaries[0], granaries[1], granaries[2], granaries[3], granaries[4], granaries[5], granaries[6], granaries[7]);
// this.Channel.WriteAndFlushAsync(req);
// return Result<bool>.Success();
//}
///// <summary>
///// 发送参数设置
///// </summary>
///// <param name="sn">Plc编号</param>
///// <param name="msg">消息</param>
//public Result<bool> SendParameterSettingsReq(byte[] messageBodyAddress,byte parameterType,byte parameter)
//{
// if (!Connected)
// {
// return Result<bool>.Fail($"Plc{Sn}未连接");
// }
// ParameterSettingsReq req = new ParameterSettingsReq( parameterType, parameter)
// {
// MessageBodyAddress = messageBodyAddress,
// ParameterType = parameterType,
// Parameter = parameter,
// };
// this.Channel.WriteAndFlushAsync(req);
// return Result<bool>.Success();
//}
/// <summary>
/// 发送参数设置
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
public Result<bool> SendParameterSettingsReq( byte parameterType, byte parameter)
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
ParameterSettingsReq req = new ParameterSettingsReq(parameterType, parameter)
{
ParameterType = parameterType,
Parameter = parameter,
};
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
public EquipAlarmDefineRepository _equipAlarmDefineRepository = AppInfo.Container.Resolve<EquipAlarmDefineRepository>();
public List<EquipAlarmDefine> GetAlarmDeinneList()
{
return _equipAlarmDefineRepository.QueryByClauseToList(i => i.EquipCode == "plc");
}
/// <summary>
/// 发送准备电池开启
/// </summary>
/// <param name="sn">Plc编号</param>
/// <param name="msg">消息</param>
public Result<bool> SendPrepareBatteryOnReq(byte readyBatterySign,byte takePositionNumber)
{
if (!Connected)
{
return Result<bool>.Fail($"Plc{Sn}未连接");
}
PrepareBatteryOnReq req = new PrepareBatteryOnReq(readyBatterySign, takePositionNumber)
{
ReadyBatterySign = readyBatterySign,
TakePositionNumber = takePositionNumber,
};
this.Channel.WriteAndFlushAsync(req);
return Result<bool>.Success();
}
#endregion
public void Reset()
{
SwapDone = false;
DisassembleDone = false;
SwapStart = false;
ResetTaskNo();
}
public override ILog Logger()
{
return Log();
}
private ILog Log()
{
var name = "Plc" + this.Sn;
ILog logger = LogManager.GetLogger(name);
Console.WriteLine(name + "-" + logger.GetHashCode());
return logger;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool Connect()
{
base.BaseConnect();
Log().Info($"charger {Sn} connect succeed");
return Connected;
}
/// <summary>
///
/// </summary>
/// <param name="sn"></param>
/// <param name="destAddr"></param>
public void SessionAttr(string sn, string destAddr)
{
ChannelUtils.AddAttr(Channel, PlcConst.ChargerSn, sn);
ChannelUtils.AddAttr(Channel, PlcConst.EqmTypeNo, sn);
ChannelUtils.AddAttr(Channel, PlcConst.EqmCode, sn);
ChannelUtils.AddAttr(Channel, PlcConst.DestAddr, destAddr);
}
}