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.

262 lines
9.2 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 HybirdFrameworkCore.Autofac.Attribute;
using HybirdFrameworkCore.Utils;
using HybirdFrameworkDriver.Session;
using HybirdFrameworkDriver.TcpClient;
using Newtonsoft.Json;
using Service.Charger.Codec;
using Service.Charger.Common;
using Service.Charger.Handler;
using Service.Charger.Msg.Charger.Req;
using Service.Charger.Msg.Charger.Resp;
using Service.Charger.Msg.Host.Req;
namespace Service.Charger.Client;
/// <summary>
/// 示例程序
/// </summary>
[Scope("InstancePerDependency")]
public class ChargerClient : TcpClient<IBaseHandler, Decoder, Encoder>
{
public ushort AuthTimes { get; set; } = 0;
public bool IsAuthed { get; set; } = false;
/// <summary>
/// 参考 ChargingStatus
/// </summary>
public UInt16 ChargingStatus { get; set; }
/// <summary>
/// 是否已经开始充电
/// </summary>
public bool IsCharged { get; set; } = false;
public bool IsStopped { get; set; } = false;
public bool IsCanSendStopCmd { get; set; } = true;
public DateTime? ChargingStartTime { get; set; }
public DateTime? ChargingStopTime { get; set; }
/// <summary>
/// 电池包实时数据
/// </summary>
public BatteryPackData? BatteryPackData { get; set; }
/// <summary>
/// 电池包实时单体温度&单体电压数据
/// </summary>
public BatteryPackDataVoltage? BatteryPackDataVoltage { get; set; }
/// <summary>
/// 电池包上报累计充放电电量
/// </summary>
public BatteryPackTotalElectricity? BatteryPackTotalElectricity { get; set; }
/// <summary>
/// 电池包上报充放电口温度
/// </summary>
public BatteryPackPortTemperature? BatteryPackPortTemperature { get; set; }
/// <summary>
/// 电池包内部接触器状态和故障上报
/// </summary>
public BatteryPackStateAndFault? BatteryPackStateAndFault { get; set; }
/// <summary>
/// 充放电设备应答站功率调节指令
/// </summary>
public PowerRegulationRes PowerRegulationRes { get; set; }
/// <summary>
/// 电池包实时遥信上报(站内充电模式有电池包时周期性上传)
/// </summary>
public RemoteSignaling RemoteSignaling { get; set; }
/// <summary>
/// 充电机上报车辆 VIN
/// </summary>
public VehicleVIN VehicleVIN { get; set; }
/// <summary>
/// 充放电机应答辅助控制
/// </summary>
public AuxiliaryPowerRes AuxiliaryPowerRes { get; set; }
/// <summary>
/// 充放电上报交流电表数据(交流电表接到充电机上的情况)
/// </summary>
public AcMeter AcMeter { get; set; }
/// <summary>
///充电机遥信数据
/// </summary>
public UploadRemoteSignalData UploadRemoteSignalData = new UploadRemoteSignalData();
/// <summary>
/// 充电机工作状态-从遥信数据包中得到。00H待机 01H工作 02H工作完成 03H充/放电暂停
/// </summary>
public byte Workstate { get; set; }
/// <summary>
/// 充电机故障-遥信数据包总故障 00H正常、01H故障
/// </summary>
public bool TotalError { get; set; }
/// <summary>
/// 充电机告警-遥信数据包总告警 00H正常、01H告警
/// </summary>
public bool TotalWarning { get; set; }
/// <summary>
/// 充电机遥测数据
/// </summary>
public UploadTelemetryData UploadTelemetryData = new UploadTelemetryData();
/// <summary>
///充电机实时充电功率
/// </summary>
public float RealTimeChargePower { get; set; } = 0;
/// <summary>
/// 心跳-桩状态
/// </summary>
public byte PileState { get; set; }
/// <summary>
/// 电池编码
/// </summary>
public string BatterSn { get; set; }
/// <summary>
/// 远程升级-监控网关上送升级完成确认帧
/// </summary>
public UplinkUpgrade UplinkUpgrade { get; set; }
public string? CurrentCmd { get; set; }
#region 发送指令
private ushort IncreAuthTimes()
{
if (AuthTimes < 65535)
{
AuthTimes += 1;
}
else
{
AuthTimes = 1;
}
return AuthTimes;
}
/// <summary>
/// 发送鉴权
/// </summary>
public void SendAuth()
{
byte authCodeKey = ChargerUtils.GetByteRandomNum(); //鉴码KEY[随机数]
byte[] authCodes = ChargerUtils.GetAuthCodesResult(ChargerConst.AuthCode, authCodeKey); //鉴权码
Auth auth = new Auth(IncreAuthTimes(), authCodes, authCodeKey);
CurrentCmd = JsonConvert.SerializeObject(auth)+ "\r\n" + BitUtls.BytesToHexStr(auth.ToBytes());
this.Channel.WriteAndFlushAsync(auth);
}
/// <summary>
/// 监控平台发送远程开始充电指令
/// </summary>
/// <param name="socLimit">SOC限制.百分比</param>
/// <param name="changePowerCmdType">功率调节指令类型.默认1 绝对功率值</param>
/// <param name="changePower">0.1kw/位,默认3600</param>
/// <param name="chargeOrderNo">充电流水号</param>
public void SendRemoteStartCharging(byte socLimit, float changePower, byte changePowerCmdType=1,
string? chargeOrderNo = null)
{
if (string.IsNullOrWhiteSpace(chargeOrderNo))
{
chargeOrderNo = ChargerUtils.GenChargeOrderSn();
}
var remoteStartCharging = new RemoteStartCharging(socLimit, changePowerCmdType, changePower, chargeOrderNo);
CurrentCmd = JsonConvert.SerializeObject(remoteStartCharging)+ "\r\n" + BitUtls.BytesToHexStr(remoteStartCharging.ToBytes());
this.Channel.WriteAndFlushAsync(remoteStartCharging);
}
/// <summary>
/// 监控平台发送远程停止充电指令
/// </summary>
/// <param name="reason">0 正常停机 1 服务器发现桩异常,强制停机</param>
public void SendRemoteStopCharging(byte reason)
{
RemoteStopCharging remoteStopCharging = new RemoteStopCharging(reason);
CurrentCmd = JsonConvert.SerializeObject(remoteStopCharging) + "\r\n" + BitUtls.BytesToHexStr(remoteStopCharging.ToBytes());
this.Channel.WriteAndFlushAsync(remoteStopCharging);
}
public bool Connect()
{
base.BaseConnect();
if (Connected)
{
SendAuth();
}
return Connected;
}
/// <summary>
/// 监控平台发送功率调节指令
/// </summary>
/// <param name="expectedOperatingPower">期望运行功率</param>
public void SendPowerRegulation(ushort expectedOperatingPower)
{
PowerRegulation powerRegulation = new PowerRegulation(expectedOperatingPower);
this.Channel.WriteAndFlushAsync(powerRegulation);
}
/// <summary>
/// 监控平台下发辅源控制指令
/// </summary>
/// <param name="openFlag">打开辅助电源标志 1电池包辅助电源导通 0电池包辅助电源断开</param>
public void SendAuxiliaryPower(byte openFlag)
{
AuxiliaryPower auxiliaryPower = new AuxiliaryPower(openFlag);
this.Channel.WriteAndFlushAsync(auxiliaryPower);
}
/// <summary>
/// 监控平台下发电池仓的状态
/// </summary>
/// <param name="battery">是否有电池 0:无电池 1有电池</param>
/// <param name="connectionState">电接头连接状态 0:未连接 1: 已连接</param>
/// <param name="waterCondition">水接头状态 0:未连接 1: 已连接</param>
public void SendBatteryHolderStatus(byte battery, byte connectionState, byte waterCondition)
{
BatteryHolderStatus batteryHolderStatus = new BatteryHolderStatus(battery, connectionState, waterCondition);
this.Channel.WriteAndFlushAsync(batteryHolderStatus);
}
/// <summary>
/// 站控下发 VIN 鉴权的结果
/// </summary>
/// <param name="vinresult">VIN 鉴权结果 1:通过 2 不通过</param>
public void SendAuthenticationVIN(byte vinresult)
{
AuthenticationVIN authenticationVIN = new AuthenticationVIN(vinresult);
this.Channel.WriteAndFlushAsync(authenticationVIN);
}
/// <summary>
/// 远程升级-站级监控升级请求下发
/// </summary>
/// <param name="executionControl">执行控制 0x01立即执行 0x02空闲执行</param>
/// <param name="downloadTimeout">下载超时时间</param>
/// <param name="versionNumber">版本号</param>
/// <param name="fileName">文件名称</param>
/// <param name="fileSize">文件大小</param>
/// <param name="mD5Verification">MD5校验值</param>
/// <param name="url">URL文件路径</param>
public void SendUpgradeRequest(byte executionControl, byte downloadTimeout, string versionNumber,
string fileName, uint fileSize, string mD5Verification, string url)
{
UpgradeRequest upgradeRequest=new UpgradeRequest(executionControl, downloadTimeout, versionNumber, fileName, fileSize, mD5Verification, url);
this.Channel.WriteAndFlushAsync(upgradeRequest);
}
#endregion
public void SessionAttr(string sn, string destAddr)
{
ChannelUtils.AddAttr(Channel, ChargerConst.ChargerSn, sn);
ChannelUtils.AddAttr(Channel, ChargerConst.EqmTypeNo, sn);
ChannelUtils.AddAttr(Channel, ChargerConst.EqmCode, sn);
ChannelUtils.AddAttr(Channel, ChargerConst.DestAddr, destAddr);
}
}