using Evcb.Domain.Model;
using Newtonsoft.Json;
using OCPP_Packet.Packet.DataTransfer;
using OCPPPacket.Packet.DataTransfer;
using OCPPPacket.Packet.Messages;
using OCPPPacket.Packet.Messages.Core;
using OCPPPacket.Packet.Messages.FirmwareManagement;
using OCPPPacket.Packet.Messages.LocalAuthListManagement;
using OCPPPacket.Packet.Messages.RemoteTrigger;
using OCPPPacket.Packet.Messages.Reservation;
using OCPPPacket.Packet.Messages.SmartCharging;
using OCPPPacket.Packet.Status;
using OCPPServer.Common;
using Packet.Cmd;
using System;
using System.Collections.Generic;
namespace OCPPServer.Handler
{
public class MakeRequestHandler
{
#region Core
///
/// 取得電樁 configuration settings
///
static public IRequest MakeGetConfigurationRequest()
{
GetConfigurationRequest req = new GetConfigurationRequest();
req.key = new List();
//req.key.Add("AllowOfflineTxForUnknownIdAvailable");
//req.key.Add("AllowOfflineTxForUnknownIdEnabled");
//req.key.Add("AuthorizationCacheAvailable");
//req.key.Add("AuthorizationCacheEnabled");
//req.key.Add("BlinkRepeat");
//req.key.Add("ClockAlignedDataInterval");
//req.key.Add("ConnectionTimeOut");
//req.key.Add("HeartBeatInterval");
//req.key.Add("LightIntensity");
//req.key.Add("LocalAuthorizeOffline");
//req.key.Add("LocalPreAuthorize");
//req.key.Add("MeterValuesAlignedData");
//req.key.Add("MeterValuesSampledData");
//req.key.Add("MeterValueSampleInterval");
//req.key.Add("MinimumStatusDuration");
//req.key.Add("ResetRetries");
//req.key.Add("ConnectorPhaseRotation");
//req.key.Add("StopTransactionOnEVSideDisconnect");
//req.key.Add("LocalAuthorizationListEnabled");
//req.key.Add("StopTransactionOnInvalidId");
//req.key.Add("StopTxnAlignedData");
//req.key.Add("StopTxnSampledData");
//req.key.Add("SupportedCompliancyProfiles");
//req.key.Add("TransactionMessageAttempts");
//req.key.Add("TransactionMessageRetryInterval");
//req.key.Add("UnlockConnectorOnEVSideDisconnect");
//req.key.Add("ChargeProfileMaxStackLevel");
//req.key.Add("ChargingScheduleAllowedSchedulingUnit");
//req.key.Add("ChargingScheduleMaxPeriods");
//req.key.Add("MaxChargingProfilesInstalled");
//req.key.Add("ProximityLockRetries");
//req.key.Add("ProximityContactRetries");
//req.key.Add("ChargePointId");
//req.key.Add("GetConfigurationMaxKeys");
//req.key.Add("LocalAuthListSize");
//req.key.Add("LocalAuthMaxElementsOnce");
//req.key.Add("MaxEnergyOnInvalidId");
//req.key.Add("MeterValuesTriggeredData");
//req.key.Add("ReserveConnectorZeroSupported");
//req.key.Add("WebSocketPingInterval");
//req.key.Add("Testing");
return req;
}
///
/// 要求電樁改變configuration parameters
///
static public IRequest MakeChangeConfigurationRequest(string key, string keyvalue)
{
ChangeConfigurationRequest req = new ChangeConfigurationRequest();
if (key == "HeartbeatInterval")
{
req.key = "HeartbeatInterval";
req.value = keyvalue;
}
return req;
}
///
/// APP啟動充電
///
public IRequest MakeRemoteStartTransactionRequest(int gunSerNo, string memberId)
{
RemoteStartTransactionRequest req = new RemoteStartTransactionRequest();
req.connectorId = gunSerNo;//0;
req.idTag = memberId;//"990f57dd-b660-4734-8e96-4cd346d0qwez";
req.chargingProfile = null;
return req;
}
///
/// APP結束充電
///
public IRequest MakeRemoteStopTransactionRequest(int transactionId)
{
RemoteStopTransactionRequest req = new RemoteStopTransactionRequest();
req.transactionId = transactionId;
return req;
}
///
/// 要求電樁清除 Authorization Cache
///
public IRequest MakeClearCacheRequest()
{
ClearCacheRequest req = new ClearCacheRequest();
return req;
}
///
/// 要求電樁 Hard Reset
///
public IRequest MakeHardResetRequest()
{
ResetRequest req = new ResetRequest();
req.type = ResetType.Hard;
return req;
}
///
/// 要求電樁 Soft Reset
///
public IRequest MakeSoftResetRequest()
{
ResetRequest req = new ResetRequest();
req.type = ResetType.Soft;
return req;
}
///
/// unlock 電樁 connector
///
public IRequest MakeUnlockConnectorRequest(int connectorId)
{
UnlockConnectorRequest req = new UnlockConnectorRequest();
req.connectorId = connectorId;
return req;
}
///
/// 取得 電樁 configuration
///
public IRequest MakeGetConfigurationRequest(string key)
{
GetConfigurationRequest req = new GetConfigurationRequest();
//req.key = new List {"LocalAuthListEnabled","SendLocalListMaxLength"};
//req.key = new List { "AllowOfflineTxForUnknownId", "AuthorizationCacheEnabled", "AuthorizeRemoteTxRequests", "BlinkRepeat", "ClockAlignedDataInterval", "ConnectionTimeOut", "GetConfigurationMaxKeys", "HeartbeatInterval", "LightIntensity", "LocalAuthorizeOffline", "LocalPreAuthorize", "MaxEnergyOnInvalidId" , "MeterValuesAlignedData", "MeterValuesAlignedDataMaxLength", "MeterValuesSampledData", "MeterValuesSampledDataMaxLength", "MeterValueSampleInterval", "MinimumStatusDuration", "NumberOfConnectors", "ResetRetries", "ConnectorPhaseRotation", "ConnectorPhaseRotationMaxLength", "StopTransactionOnEVSideDisconnect", "StopTransactionOnInvalidId", "StopTxnAlignedData", "StopTxnAlignedDataMaxLength", "StopTxnSampledData", "StopTxnSampledDataMaxLength", "SupportedFeatureProfiles", "SupportedFeatureProfilesMaxLength", "TransactionMessageAttempts", "TransactionMessageRetryInterval", "UnlockConnectorOnEVSideDisconnect", "WebSocketPingInterval", "LocalAuthListEnabled", "LocalAuthListMaxLength", "SendLocalListMaxLength", "ReserveConnectorZeroSupported", "ChargeProfileMaxStackLevel", "ChargingScheduleAllowedChargingRateUnit", "ChargingScheduleMaxPeriods", "ConnectorSwitch3to1PhaseSupported", "MaxChargingProfilesInstalled" };
//req.key = new List ();
req.key = new List { "AllowOfflineTxForUnknownId", "AuthorizationCacheEnabled", "LocalAuthListEnabled", "SendLocalListMaxLength", "ConnectionTimeOut", "HeartbeatInterval", "test1", "test2" };
return req;
}
///
/// 設定 電樁槍號 availability 改變
///
public IRequest MakeChangeAvailabilityRequest(int connectorId)
{
ChangeAvailabilityRequest req = new ChangeAvailabilityRequest();
req.connectorId = connectorId;
req.type = AvailabilityType.Operative;
return req;
}
#endregion Core
#region RemoteTrigger
///
/// Trigger 電樁 送相關的message
///
public IRequest MakeTriggerMessageRequest(MessageTrigger messageType, int connectorId)
{
TriggerMessageRequest req = new TriggerMessageRequest();
req.requestedMessage = messageType;
req.connectorId = connectorId;
return req;
}
#endregion RemoteTrigger
#region FirmwareManagement
///
/// 請電樁送diagnostic information
///
static public IRequest MakeGetDiagnosticsRequest(bool ac)
{
GetDiagnosticsRequest req = new GetDiagnosticsRequest();
if (ac == true)
req.location = new Uri("ftp://ipc_ui:pht2016@ftp.phihong.com.tw/AC/log/");
else
req.location = new Uri("ftp://ipc_ui:pht2016@ftp.phihong.com.tw/DC/log/");
return req;
}
///
/// 請電樁 update firmware
///
static public IRequest MakeOCPPUpdateFirmwareRequest(string fileurl)
{
UpdateFirmwareRequest req = new UpdateFirmwareRequest();
req.location = new Uri(fileurl);
req.retrieveDate = DateTime.Now;
return req;
}
#endregion FirmwareManagement
#region LocalAuthListManagement
///
/// 請電樁送 the Local Authorization Lis 版本號
///
static public IRequest MakeGetLocalListVersionRequest()
{
GetLocalListVersionRequest req = new GetLocalListVersionRequest();
return req;
}
///
/// 送給電樁 Local Authorization Lis 版本號 跟 idTags
///
static public IRequest MakeSendLocalListRequest(List localauth, uint version, byte type)
{
SendLocalListRequest req = new SendLocalListRequest();
req.localAuthorizationList = new List();
foreach (var localAuthorization in localauth)
{
AuthorizationData athData = new AuthorizationData();
athData.IdToken = localAuthorization.CardNumber;
IdTagInfo idTagInfo = new IdTagInfo();
idTagInfo.expiryDate = DateTime.Parse(localAuthorization.ExpiryDate);
idTagInfo.parentIdTag = localAuthorization.CardNumber;
idTagInfo.status = (AuthorizationStatus)localAuthorization.Status;
athData.idTagInfo = idTagInfo;
req.localAuthorizationList.Add(athData);
}
req.listVersion = Convert.ToInt32(version);
//0:全部更新 ,1:差异更新
if (type == 0)
{
req.updateType = UpdateType.Full;
}
else
{
req.updateType = UpdateType.Differential;
}
return req;
}
#endregion LocalAuthListManagement
#region Reservation
///
/// 預約電樁槍號
///
public IRequest MakeReserveNowRequest(int connectorId, string memberId, bool reserveConnectorZeroSupported, int reservationId)
{
int RetainMinute = 5;
ReserveNowRequest req = new ReserveNowRequest();
if (reserveConnectorZeroSupported == true)
req.connectorId = 0;
else
req.connectorId = connectorId;
req.expiryDate = DateTime.Now.AddMinutes(RetainMinute);
req.parentIdTag = memberId;
req.idTag = memberId;
req.reservationId = reservationId;
return req;
}
///
/// 取消預約電樁槍號
///
public IRequest MakeCancelReservationRequest(int reservationId)
{
CancelReservationRequest req = new CancelReservationRequest();
req.reservationId = reservationId;
return req;
}
#endregion Reservation
#region SmartCharging
///
/// 設定 Charging Profile
///
static public IRequest MakeSetChargingProfileRequest(int connectorId, int transactionId, int chargingProfileId, string purpose)
{
SetChargingProfileRequest req = new SetChargingProfileRequest();
req.connectorId = connectorId;
req.csChargingProfiles = new csChargingProfiles();
req.csChargingProfiles.chargingProfileId = chargingProfileId;
req.csChargingProfiles.transactionId = transactionId;
if (purpose.Contains("ChargePointMaxProfile"))
{
req.csChargingProfiles.stackLevel = 2;
req.csChargingProfiles.chargingProfilePurpose = ChargingProfilePurposeType.ChargePointMaxProfile;
req.csChargingProfiles.chargingProfileKind = ChargingProfileKindType.Recurring;
req.csChargingProfiles.recurrencyKind = RecurrencyKindType.Daily;
}
else if (purpose.Contains("TxDefaultProfile"))
{
req.csChargingProfiles.stackLevel = 1;
req.csChargingProfiles.chargingProfilePurpose = ChargingProfilePurposeType.TxDefaultProfile;
req.csChargingProfiles.chargingProfileKind = ChargingProfileKindType.Absolute;
req.csChargingProfiles.recurrencyKind = RecurrencyKindType.Weekly;
}
else if (purpose.Contains("TxProfile"))
{
req.csChargingProfiles.stackLevel = 0;
req.csChargingProfiles.chargingProfilePurpose = ChargingProfilePurposeType.TxProfile;
req.csChargingProfiles.chargingProfileKind = ChargingProfileKindType.Relative;
req.csChargingProfiles.recurrencyKind = RecurrencyKindType.Daily;
}
req.csChargingProfiles.validFrom = DateTime.Now;
req.csChargingProfiles.validTo = DateTime.Now.AddHours(2);
req.csChargingProfiles.chargingSchedule = new ChargingSchedule();
req.csChargingProfiles.chargingSchedule.chargingRateUnit = ChargingRateUnitType.A;
req.csChargingProfiles.chargingSchedule.chargingSchedulePeriod = new List();
req.csChargingProfiles.chargingSchedule.duration = 120;
req.csChargingProfiles.chargingSchedule.minChargingRate = 0.0m;
req.csChargingProfiles.chargingSchedule.startSchedule = DateTime.Now;
req.csChargingProfiles.chargingSchedule.chargingSchedulePeriod = new List();
req.csChargingProfiles.chargingSchedule.chargingSchedulePeriod.Add(new ChargingSchedulePeriod() { startPeriod = 0, limit = 11000.0m, numberPhases = 3 });
req.csChargingProfiles.chargingSchedule.chargingSchedulePeriod.Add(new ChargingSchedulePeriod() { startPeriod = 28800, limit = 6000.0m, numberPhases = 3 });
req.csChargingProfiles.chargingSchedule.chargingSchedulePeriod.Add(new ChargingSchedulePeriod() { startPeriod = 72000, limit = 6000.0m, numberPhases = 3 });
// Add parts to the list.
//req.csChargingProfiles.chargingSchedule.chargingSchedulePeriod.Add(new ChargingSchedulePeriod() { startPeriod = 5, limit = 8.1m, numberPhases = 3 });
return req;
}
///
/// 設定 Charging Profile
///
static public IRequest MakeSetChargingProfileRequest(BaseCmd cmd, int transactionId)
{
SetChargingProfileRequest req = new SetChargingProfileRequest();
var c = cmd as Cmd1013;
if(c.GunSerNo == 255)
req.connectorId = 0;
else
req.connectorId = c.GunSerNo + 1;
req.csChargingProfiles = new csChargingProfiles();
req.csChargingProfiles.chargingProfileId = c.ChargingProfileId;
req.csChargingProfiles.transactionId = transactionId;
req.csChargingProfiles.stackLevel = c.stackLevel;
req.csChargingProfiles.chargingProfilePurpose = (c.ChargingProfilePurpose == 0) ? ChargingProfilePurposeType.ChargePointMaxProfile : ((c.ChargingProfilePurpose == 1) ? ChargingProfilePurposeType.TxDefaultProfile : ChargingProfilePurposeType.TxProfile);
req.csChargingProfiles.chargingProfileKind = (c.ChargingProfileKind == 0) ? ChargingProfileKindType.Absolute : ((c.ChargingProfileKind == 1) ? ChargingProfileKindType.Recurring : ChargingProfileKindType.Relative);
req.csChargingProfiles.recurrencyKind = (c.RecurrencyKind == 0) ? RecurrencyKindType.Daily : RecurrencyKindType.Weekly;
req.csChargingProfiles.validFrom = c.ValidFrom.Value;
req.csChargingProfiles.validTo = c.ValidTo.Value;
req.csChargingProfiles.chargingSchedule = new ChargingSchedule();
req.csChargingProfiles.chargingSchedule.chargingRateUnit = (c.ChargingRateUnit == 0) ? ChargingRateUnitType.W: ChargingRateUnitType.A;
req.csChargingProfiles.chargingSchedule.duration = Convert.ToInt32(c.Duration);
req.csChargingProfiles.chargingSchedule.minChargingRate = c.MinChargingRate.RealValue;
req.csChargingProfiles.chargingSchedule.startSchedule = c.StartSchedule.Value;
req.csChargingProfiles.chargingSchedule.chargingSchedulePeriod = new List();
var chargingPeriod = c.ChargingSchedulePeriod as List;
foreach (var csp in chargingPeriod)
{
req.csChargingProfiles.chargingSchedule.chargingSchedulePeriod.Add(new ChargingSchedulePeriod() { startPeriod = Convert.ToInt32(csp.StartPeriod), limit = csp.Limit.RealValue, numberPhases = 3 });
}
return req;
}
///
/// 設定Clear Charging Profile
///
public IRequest MakeClearChargingProfileRequest(int connectorId)
{
ClearChargingProfileRequest req = new ClearChargingProfileRequest();
req.connectorId = 0;
req.id = 1;
req.stackLevel = 1;
req.chargingProfilePurpose = ChargingProfilePurposeType.TxDefaultProfile;
return req;
}
///
/// 設定Clear Charging Profile
///
public IRequest MakeClearChargingProfileRequest(BaseCmd cmd)
{
ClearChargingProfileRequest req = new ClearChargingProfileRequest();
var c = cmd as Cmd1015;
if (c.GunSerNo == 255)
req.connectorId = 0;
else
req.connectorId = c.GunSerNo + 1;
req.id = c.ChargingProfileId;
req.stackLevel = c.stackLevel;
req.chargingProfilePurpose = (c.ChargingProfilePurpose == 0) ? ChargingProfilePurposeType.ChargePointMaxProfile : ((c.ChargingProfilePurpose == 1) ? ChargingProfilePurposeType.TxDefaultProfile : ChargingProfilePurposeType.TxProfile);
return req;
}
///
/// 取得電樁 Composite Charging Schedule
///
public IRequest MakeGetCompositeScheduleRequest(int connectorId)
{
GetCompositeScheduleRequest req = new GetCompositeScheduleRequest();
req.connectorId = connectorId;
req.duration = 120;
req.chargingRateUnit = ChargingRateUnitType.A;
return req;
}
#endregion SmartCharging
#region DataTransfer
///
/// 向充電樁下發升級指令
///
public IRequest MakeUpdateFirmware(int type, ProgramParam param, UploadFile uploadFile)
{
UpdateFirmware updatefirm = new UpdateFirmware();
updatefirm.type = (ProgramType)type;
updatefirm.param = param;
updatefirm.url = @"http://" + uploadFile.FileUrl;
updatefirm.md5 = uploadFile.FileMD5.ToUpper();
DataTransferRequest req = new DataTransferRequest();
req.vendorId = "Phihong";
req.messageId = "UpdateFirmware";
req.data = JsonConvert.SerializeObject(updatefirm);
return req;
}
///
/// 設定簡易版充電電量
///
static public IRequest MakeSendChargingConfigRequest(BaseCmd cmd)
{
var c = cmd as Cmd1017;
DataTransferRequest req = new DataTransferRequest();
req.vendorId = c.vendorId;
req.messageId = "SetChargingConfig";
req.data = JsonConvert.SerializeObject( new ChargingRate() { chargingRateUnit="A", limit=c.limit});
return req;
}
///
/// 取得簡易版充電電量
///
static public IRequest MakeSendGetChargingConfigRequest(BaseCmd cmd)
{
var c = cmd as Cmd1019;
DataTransferRequest req = new DataTransferRequest();
req.vendorId = c.vendorId;
req.messageId = "GetChargingConfig";
return req;
}
///
/// 設定樁的夥伴代碼
///
public IRequest MakeSendPartnerPoleIdRequest(string partnerPoleId)
{
DataTransferRequest req = new DataTransferRequest();
req.vendorId = "Phihong";
req.messageId = "SendPartnerPoleId";
req.data = partnerPoleId;
return req;
}
///
/// 將電樁轉伺服器
///
public IRequest MakeServerDomainNameRequest(string ServerDomainName)
{
DataTransferRequest req = new DataTransferRequest();
req.vendorId = "Phihong";
req.messageId = "ServerDomainName";
req.data = ServerDomainName;
return req;
}
///
/// 下發全天電費
///
public IRequest MakeAllDayUniformElectricBillRequest(decimal pricePerKWH)
{
DataTransferRequest req = new DataTransferRequest();
req.vendorId = "Phihong";
req.messageId = "AllDayUniformElectricBill";
req.data = System.Convert.ToString((double)pricePerKWH);
return req;
}
///
/// 下發全天 48 時段電費
///
public IRequest MakeAllDaySectionElectricBillRequest(List sectionElectricBill)
{
DataTransferRequest req = new DataTransferRequest();
req.vendorId = "Phihong";
req.messageId = "AllDaySectionElectricBill";
req.data = JsonConvert.SerializeObject(sectionElectricBill);
return req;
}
///
/// 下發充電服務費
///
public IRequest MakeFeePerKWHRequest(decimal pricePerKWH)
{
DataTransferRequest req = new DataTransferRequest();
req.vendorId = "Phihong";
req.messageId = "FeePerKWH";
req.data = System.Convert.ToString((double)pricePerKWH);
return req;
}
///
/// 下發帳戶餘額
///
public IRequest MakeAccountBalanceRequest(string uniqueId, decimal balance, int VehicleType)
{
DataTransferRequest req = new DataTransferRequest();
req.vendorId = "Phihong";
req.messageId = "AccountBalance";
AccountBalance account = new AccountBalance();
account.uniqueId = uniqueId;
account.balance = (double)balance;
account.VehicleType = VehicleType;
req.data = JsonConvert.SerializeObject(account);
return req;
}
///
/// 下發定時充電資訊
///
public IRequest MakeAutoChargeReservationRequest(AutoChargeReservation autoChargeReservationParam)
{
DataTransferRequest req = new DataTransferRequest();
req.vendorId = "Phihong";
req.messageId = "AutoChargeReservation";
req.data = JsonConvert.SerializeObject(autoChargeReservationParam);
return req;
}
///
///
///
///
///
///
public IRequest MakeCustomCommandRequest(int gunNo, int Type)
{
DataTransferRequest req = new DataTransferRequest();
req.vendorId = "Phihong";
req.messageId = "SetCustomCMD";
CustomCommand customCommandParam = new CustomCommand();
customCommandParam.connectorId = gunNo;
customCommandParam.CommandType = (Type == 18) ? OCPP_Packet.Packet.Status.CustomCommandType.QRCodeFlash : ((Type == 19) ? OCPP_Packet.Packet.Status.CustomCommandType.DisableCharger : OCPP_Packet.Packet.Status.CustomCommandType.EnableCharger);
req.data = JsonConvert.SerializeObject(customCommandParam);
return req;
}
#endregion DataTransfer
}
}