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; using Service.Charger.Msg.Charger.Req; using Service.Charger.Msg.Charger.Resp; using Service.Charger.Msg.Host.Req; using Service.Charger.Msg.Host.Req.Bms; namespace Service.Charger.Client; /// /// 示例程序 /// [Scope("InstancePerDependency")] public class ChargerClient : TcpClient { #region 属性 public ushort AuthTimes { get; set; } = 0; public bool IsAuthed { get; set; } = false; /// /// 参考 ChargingStatus /// public UInt16 ChargingStatus { get; set; } /// /// 是否已经开始充电 /// 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; } /// /// 电池包实时数据 /// public BatteryPackData? BatteryPackData { get; set; } /// /// 电池包实时单体温度&单体电压数据 /// public BatteryPackDataVoltage? BatteryPackDataVoltage { get; set; } /// /// 电池包上报累计充放电电量 /// public BatteryPackTotalElectricity? BatteryPackTotalElectricity { get; set; } /// /// 电池包上报充放电口温度 /// public BatteryPackPortTemperature? BatteryPackPortTemperature { get; set; } /// /// 电池包内部接触器状态和故障上报 /// public BatteryPackStateAndFault? BatteryPackStateAndFault { get; set; } /// /// 充放电设备应答站功率调节指令 /// public PowerRegulationRes PowerRegulationRes { get; set; } /// /// 电池包实时遥信上报(站内充电模式有电池包时周期性上传) /// public RemoteSignaling RemoteSignaling { get; set; } /// /// 充电机上报车辆 VIN /// public VehicleVIN VehicleVIN { get; set; } /// /// 充放电机应答辅助控制 /// public AuxiliaryPowerRes AuxiliaryPowerRes { get; set; } /// /// 充放电上报交流电表数据(交流电表接到充电机上的情况) /// public AcMeter AcMeter { get; set; } /// ///充电机遥信数据 /// public UploadRemoteSignalData UploadRemoteSignalData = new UploadRemoteSignalData(); /// /// 充电机工作状态-从遥信数据包中得到。00H:待机 01H:工作 02H:工作完成 03H:充/放电暂停 /// public byte Workstate { get; set; } /// /// 充电机故障-遥信数据包总故障 00H正常、01H故障 /// public bool TotalError { get; set; } /// /// 充电机告警-遥信数据包总告警 00H正常、01H告警 /// public bool TotalWarning { get; set; } /// /// 充电机遥测数据 /// public UploadTelemetryData UploadTelemetryData = new UploadTelemetryData(); /// ///充电机实时充电功率 /// public float RealTimeChargePower { get; set; } = 0; /// /// 心跳-桩状态 /// public byte PileState { get; set; } /// /// 电池编码 /// public string? BatterSn { get; set; } /// /// 远程升级-监控网关上送升级完成确认帧 /// public UplinkUpgrade UplinkUpgrade { get; set; } /// /// 充电订单号 /// public string? ChargeOrderNo { get; set; } /// /// 当前指令 /// public string? CurrentCmd { get; set; } /// /// 当前接收报文 /// public string? CurrentMsg { get; set; } #endregion /// /// /// /// public void ReceiveMsgHandle(ASDU asdu) { this.CurrentMsg = CurrentCmd = JsonConvert.SerializeObject(asdu, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(asdu.ToBytes()); } #region 发送指令 private ushort IncreAuthTimes() { if (AuthTimes < 65535) { AuthTimes += 1; } else { AuthTimes = 1; } return AuthTimes; } /// /// 发送鉴权 /// 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, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(auth.ToBytes()); this.Channel.WriteAndFlushAsync(auth); } /// /// 监控平台发送远程开始充电指令 /// /// SOC限制.百分比 /// 功率调节指令类型.默认1 绝对功率值 /// 0.1kw/位,默认3600 /// 充电流水号 public string SendRemoteStartCharging(byte socLimit, float changePower=3600, 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, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(remoteStartCharging.ToBytes()); this.Channel.WriteAndFlushAsync(remoteStartCharging); return chargeOrderNo; } /// /// 监控平台发送远程停止充电指令 /// /// 0 正常停机 1 服务器发现桩异常,强制停机 public void SendRemoteStopCharging(byte reason) { RemoteStopCharging remoteStopCharging = new RemoteStopCharging(reason); CurrentCmd = JsonConvert.SerializeObject(remoteStopCharging, Formatting.Indented) + "\r\n" + BitUtls.BytesToHexStr(remoteStopCharging.ToBytes()); this.Channel.WriteAndFlushAsync(remoteStopCharging); } /// /// 监控平台发送功率调节指令 /// /// 期望运行功率 public void SendPowerRegulation(float expectedOperatingPower) { PowerRegulation powerRegulation = new PowerRegulation(expectedOperatingPower); this.Channel.WriteAndFlushAsync(powerRegulation); } /// /// 倍率 例如,0.单5C位该0值.1C为 5 ,1C 时该值为 10 /// /// public void SendAdjustChargeRate(float rate) { AdjustChargeRate adjustChargeRate = new AdjustChargeRate(rate); this.Channel.WriteAndFlushAsync(adjustChargeRate); } /// /// 监控平台下发辅源控制指令 /// /// 打开辅助电源标志 1:电池包辅助电源导通 0:电池包辅助电源断开 public void SendAuxiliaryPower(byte openFlag) { AuxiliaryPower auxiliaryPower = new AuxiliaryPower(openFlag); CurrentCmd = JsonConvert.SerializeObject(auxiliaryPower, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(auxiliaryPower.ToBytes()); this.Channel.WriteAndFlushAsync(auxiliaryPower); } /// /// 监控平台下发电池仓的状态 /// /// 是否有电池 0:无电池 1:有电池 /// 电接头连接状态 0:未连接 1: 已连接 /// 水接头状态 0:未连接 1: 已连接 public void SendBatteryHolderStatus(byte battery, byte connectionState, byte waterCondition) { BatteryHolderStatus batteryHolderStatus = new BatteryHolderStatus(battery, connectionState, waterCondition); CurrentCmd = JsonConvert.SerializeObject(batteryHolderStatus, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(batteryHolderStatus.ToBytes()); this.Channel.WriteAndFlushAsync(batteryHolderStatus); } /// /// 站控下发 VIN 鉴权的结果 /// /// VIN 鉴权结果 1:通过 2 不通过 public void SendAuthenticationVIN(byte vinresult) { AuthenticationVIN authenticationVIN = new AuthenticationVIN(vinresult); this.Channel.WriteAndFlushAsync(authenticationVIN); } /// /// 远程升级-站级监控升级请求下发 /// /// 执行控制 0x01:立即执行 0x02:空闲执行 /// 下载超时时间 /// 版本号 /// 文件名称 /// 文件大小 /// MD5校验值 /// URL(文件路径) 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); } /// /// 设置尖峰平谷时间段 /// /// public void SendSetPeakValleyTime(SetPeakValleyTime setPeakValleyTime) { CurrentCmd = JsonConvert.SerializeObject(setPeakValleyTime, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(setPeakValleyTime.ToBytes()); this.Channel.WriteAndFlushAsync(setPeakValleyTime); } /// /// 3.4.7 监控平台下发掉线停止充电 /// /// 0:不使能 1:使能 public void SendOfflineStopCharging(byte enabled) { OfflineStopCharging offlineStopCharging = new OfflineStopCharging(enabled); CurrentCmd = JsonConvert.SerializeObject(offlineStopCharging, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(offlineStopCharging.ToBytes()); this.Channel.WriteAndFlushAsync(offlineStopCharging); } /// /// 3.4.12 站控设备切换站内/站外充电切换 /// /// 00:无效 01:站内 02:站外 public void SendChangeChargeMode(byte chargeMode) { ChangeChargeMode req = new ChangeChargeMode(chargeMode); this.Channel.WriteAndFlushAsync(req); } /// /// /// public void SendQueryBattery() { QueryBattery queryBattery = new QueryBattery(ChargerConst.BatteryNo); CurrentCmd = JsonConvert.SerializeObject(queryBattery, Formatting.Indented)+ "\r\n" + BitUtls.BytesToHexStr(queryBattery.ToBytes()); this.Channel.WriteAndFlushAsync(queryBattery); } #endregion /// /// /// /// public bool Connect() { base.BaseConnect(); if (Connected) { SendAuth(); } return Connected; } /// /// /// /// /// 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); } }