123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556 |
- using Evcb.Domain.Model;
- using Evcb.Domain.mongo;
- using Evcb.Repository;
- using Evcb.Service;
- using Evcb.Utility;
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- using NLog;
- using OCPP_Packet.Packet.DataTransfer;
- using OCPPPacket.Packet.DataTransfer;
- using OCPPPacket.Packet.Feature;
- using OCPPPacket.Packet.Feature.Core;
- using OCPPPacket.Packet.Feature.FirmwareManagement;
- using OCPPPacket.Packet.Feature.LocalAuthListManagement;
- using OCPPPacket.Packet.Feature.RemoteTrigger;
- using OCPPPacket.Packet.Feature.Reservation;
- using OCPPPacket.Packet.Feature.SmartCharging;
- using OCPPPacket.Packet.Messages;
- using OCPPPacket.Packet.Messages.Basic;
- 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 OCPPServer.Protocol;
- using Packet.Cmd;
- using System;
- using System.Collections.Generic;
- using System.Configuration;
- using System.Data.Entity;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Net.Http;
- using System.Threading.Tasks;
- namespace OCPPServer.Handler
- {
- public class OCPPMessageHandler
- {
- private ILogger logger = NLog.LogManager.GetCurrentClassLogger();
- private FeatureHandler featureHandler;
- //private CmdHelper CmdHelper;
- private List<string> _cmd202lst = new List<string>();
- private static readonly Object _clientQueue = new object();
- static private MakeConfirmationHandler makeConfirmation = new MakeConfirmationHandler();
- static private MakeRequestHandler makeRequest = new MakeRequestHandler();
- private string ApiUrl { get; set; }
- //設定OCPP Message Constant
- private const int INDEX_MESSAGEID = 0;
- private const int TYPENUMBER_CALL = 2;
- private const int TYPENUMBER_CALLRESULT = 3;
- private const int TYPENUMBER_CALLERROR = 4;
- private const int INDEX_CALL_ACTION = 2;
- private const int INDEX_CALL_PAYLOAD = 3;
- private const int INDEX_CALLRESULT_PAYLOAD = 2;
- private const int INDEX_CALLERROR_ERRORCODE = 2;
- private const int INDEX_CALLERROR_DESCRIPTION = 3;
- private const int INDEX_CALLERROR_PAYLOAD = 4;
- private const int INDEX_UNIQUEID = 1;
- /// <summary>
- /// 初始化 OCPPMessageHandler Class
- /// </summary>
- public OCPPMessageHandler()
- {
- this.featureHandler = new FeatureHandler();
- ApiUrl = ConfigurationManager.AppSettings.Get("ApiUrl");
- #region Core
- //加入core feature
- featureHandler.AddFeatureProfile(new AuthorizeFeature());
- featureHandler.AddFeatureProfile(new BootNotificationFeature());
- featureHandler.AddFeatureProfile(new ChangeAvailabilityFeature());
- featureHandler.AddFeatureProfile(new ChangeConfigurationFeature());
- featureHandler.AddFeatureProfile(new ClearCacheFeature());
- featureHandler.AddFeatureProfile(new DataTransferFeature());
- featureHandler.AddFeatureProfile(new GetConfigurationFeature());
- featureHandler.AddFeatureProfile(new HeartbeatFeature());
- featureHandler.AddFeatureProfile(new StartTransactionFeature());
- featureHandler.AddFeatureProfile(new StatusNotificationFeature());
- featureHandler.AddFeatureProfile(new MeterValuesFeature());
- featureHandler.AddFeatureProfile(new RemoteStartTransactionFeature());
- featureHandler.AddFeatureProfile(new RemoteStopTransactionFeature());
- featureHandler.AddFeatureProfile(new ResetFeature());
- featureHandler.AddFeatureProfile(new StopTransactionFeature());
- featureHandler.AddFeatureProfile(new UnlockConnectorFeature());
- #endregion Core
- #region FirmwareManagement
- //加入FirmwareManagement feature
- featureHandler.AddFeatureProfile(new GetDiagnosticsFeature());
- featureHandler.AddFeatureProfile(new DiagnosticsStatusNotificationFeature());
- featureHandler.AddFeatureProfile(new FirmwareStatusNotificationFeature());
- featureHandler.AddFeatureProfile(new UpdateFirmwareFeature());
- #endregion FirmwareManagement
- #region LocalAuthListManagement
- //加入LocalAuthListManagement feature
- featureHandler.AddFeatureProfile(new GetLocalListVersionFeature());
- featureHandler.AddFeatureProfile(new SendLocalListFeature());
- #endregion LocalAuthListManagement
- #region RemoteTrigger
- //加入RemoteTrigger feature
- featureHandler.AddFeatureProfile(new TriggerMessageFeature());
- #endregion RemoteTrigger
- #region Reservation
- //加入Reservation feature
- featureHandler.AddFeatureProfile(new CancelReservationFeature());
- featureHandler.AddFeatureProfile(new ReserveNowFeature());
- #endregion Reservation
- #region SmartCharging
- //加入SmartCharging feature
- featureHandler.AddFeatureProfile(new ClearChargingProfileFeature());
- featureHandler.AddFeatureProfile(new GetCompositeScheduleFeature());
- featureHandler.AddFeatureProfile(new SetChargingProfileFeature());
- #endregion SmartCharging
- }
- /// <summary>
- /// 解析message type,歸類為Call Message 或 CALLRESULT Message或 CALLERROR Message
- /// </summary>
- /// <param name="message">OCPP Message</param>
- /// <returns></returns>
- public BaseMessage Parse(string message)
- {
- const int INDEX_MESSAGEID = 0;
- const int TYPENUMBER_CALL = 2;
- const int TYPENUMBER_CALLRESULT = 3;
- const int TYPENUMBER_CALLERROR = 4;
- const int INDEX_CALL_ACTION = 2;
- const int INDEX_CALL_PAYLOAD = 3;
- const int INDEX_CALLRESULT_PAYLOAD = 2;
- const int INDEX_CALLERROR_ERRORCODE = 2;
- const int INDEX_CALLERROR_DESCRIPTION = 3;
- const int INDEX_CALLERROR_PAYLOAD = 4;
- const int INDEX_UNIQUEID = 1;
- try
- {
- var array = JsonConvert.DeserializeObject<JArray>(message);
- BaseMessage msg = null;
- switch ((int)array[INDEX_MESSAGEID])
- {
- case TYPENUMBER_CALL:
- {
- CallMessage call = new CallMessage();
- call.action = array[INDEX_CALL_ACTION].ToString();
- call.payload = array[INDEX_CALL_PAYLOAD].ToString().Replace("\r\n", "");
- msg = call;
- }
- break;
- case TYPENUMBER_CALLRESULT:
- {
- CallResultMessage callResult = new CallResultMessage();
- callResult.payload = array[INDEX_CALLRESULT_PAYLOAD].ToString().Replace("\r\n", "");
- msg = callResult;
- }
- break;
- case TYPENUMBER_CALLERROR:
- {
- CallErrorMessage callError = new CallErrorMessage();
- callError.ErrorCode = array[INDEX_CALLERROR_ERRORCODE].ToString();
- callError.ErrorDescription = array[INDEX_CALLERROR_DESCRIPTION].ToString();
- //假如沒有error details ,判斷CallError Message的payload 是 an empty object \{}.
- if (array.Count > INDEX_CALLERROR_PAYLOAD)
- {
- callError.payload = array[INDEX_CALLERROR_PAYLOAD].ToString().Replace("\r\n", "");
- }
- msg = callError;
- }
- break;
- default:
- throw new Exception("Message Type notSupported");
- }
- msg.id = array[INDEX_UNIQUEID].ToString();
- return msg;
- }
- catch (Exception ex)
- {
- throw new Exception(string.Format("Error=>Communicator.Parse: {0}", ex.ToString()));
- }
- }
- /// <summary>
- /// 解壓縮Payload為OCPP Message
- /// </summary>
- /// <param name="payload">OCPP Message Payload</param>
- /// <param name="type">OCPP Message Type</param>
- /// <returns></returns>
- private object UnpackPayload(object payload, Type type)
- {
- var ocppMessage = JsonConvert.DeserializeObject(payload.ToString(), type);
- return ocppMessage;
- }
- /// <summary>
- /// 壓縮OCPP Message為Payload
- /// </summary>
- /// <param name="ocppMessage"></param>
- /// <returns></returns>
- private object PackPayload(object ocppMessage)
- {
- return JsonConvert.SerializeObject(ocppMessage);
- }
- /// <summary>
- /// 透過OCPP Message 的UniqueId,從client queue 取出之前後台送出的request, 透過取出的request找出相對應的confirmation type
- /// </summary>
- /// <param name="queue">Messgae queue</param>
- /// <param name="uniqueId">OCPP Message UniqueId</param>
- /// <param name="requestObj">OCPP Request Message</param>
- /// <returns></returns>
- private Type GetConfirmationType(ref Queue queue, string uniqueId, out IRequest requestObj)
- {
- IRequest request = queue.RestoreRequest(uniqueId);
- if (request == null)
- {
- requestObj = null;
- return null;
- }
- Feature feature = this.featureHandler.FindFeatureByRequest(request.GetType());
- requestObj = request;
- return feature.GetConfirmationType();
- }
- //處理OCPP errorCode, 相對應到資料庫ChargingRecordStatus的Warning欄位
- //DC:
- //ConnectorLockFailure: 90000,EVCommunicationError: 90001,GroundFailure: 90002,HighTemperature: 90003,
- //InternalError: 90004,LocalListConflict: 90005,NoError: 90006,OtherError: 90007,OverCurrentFailure: 90008,
- //OverVoltage: 90009, PowerMeterFailure: 90010,PowerSwitchFailure: 90011,ReaderFailure: 90012,ResetFailure: 90013,
- //UnderVoltage: 90014, WeakSignal: 90015
- //AC:
- //ConnectorLockFailure: 110000,EVCommunicationError: 110001,GroundFailure: 110002,HighTemperature: 110003,
- //InternalError: 110004,LocalListConflict: 110005,NoError: 110006,OtherError: 110007,OverCurrentFailure: 110008,
- //OverVoltage: 110009, PowerMeterFailure: 110010,PowerSwitchFailure: 110011,ReaderFailure: 110012,ResetFailure: 110013,
- //UnderVoltage: 110014, WeakSignal: 110015
- /// <summary>
- /// 處理 Error Code
- /// </summary>
- /// <param name="typeAC"></param>
- /// <param name="errorCode"></param>
- /// <returns></returns>
- private int ProcessErrorCode(bool typeAC, ChargePointErrorCode errorCode)
- {
- int warning = 0;
- switch (errorCode)
- {
- case ChargePointErrorCode.ConnectorLockFailure:
- if (typeAC == true)
- warning = 110000; // AC
- else
- warning = 90000; // DC
- break;
- case ChargePointErrorCode.EVCommunicationError:
- if (typeAC == true)
- warning = 110001; // AC
- else
- warning = 90001; // DC
- break;
- case ChargePointErrorCode.GroundFailure:
- if (typeAC == true)
- warning = 110002; // AC
- else
- warning = 90002; // DC
- break;
- case ChargePointErrorCode.HighTemperature:
- if (typeAC == true)
- warning = 110003; // AC
- else
- warning = 90003; // DC
- break;
- case ChargePointErrorCode.InternalError:
- if (typeAC == true)
- warning = 110004; // AC
- else
- warning = 90004; // DC
- break;
- case ChargePointErrorCode.LocalListConflict:
- if (typeAC == true)
- warning = 110005; // AC
- else
- warning = 90005; // DC
- break;
- case ChargePointErrorCode.NoError:
- if (typeAC == true)
- warning = 110006; // AC
- else
- warning = 90006; // DC
- break;
- case ChargePointErrorCode.OtherError:
- if (typeAC == true)
- warning = 110007; // AC
- else
- warning = 90007; // DC
- break;
- case ChargePointErrorCode.OverCurrentFailure:
- if (typeAC == true)
- warning = 110008; // AC
- else
- warning = 90008; // DC
- break;
- case ChargePointErrorCode.OverVoltage:
- if (typeAC == true)
- warning = 110009; // AC
- else
- warning = 90009; // DC
- break;
- case ChargePointErrorCode.PowerMeterFailure:
- if (typeAC == true)
- warning = 110010; // AC
- else
- warning = 90010; // DC
- break;
- case ChargePointErrorCode.PowerSwitchFailure:
- if (typeAC == true)
- warning = 110011; // AC
- else
- warning = 90011; // DC
- break;
- case ChargePointErrorCode.ReaderFailure:
- if (typeAC == true)
- warning = 110012; // AC
- else
- warning = 90012; // DC
- break;
- case ChargePointErrorCode.ResetFailure:
- if (typeAC == true)
- warning = 110013; // AC
- else
- warning = 90013; // DC
- break;
- case ChargePointErrorCode.UnderVoltage:
- if (typeAC == true)
- warning = 110014; // AC
- else
- warning = 90014; // DC
- break;
- case ChargePointErrorCode.WeakSignal:
- if (typeAC == true)
- warning = 110015; // AC
- else
- warning = 90015; // DC
- break;
- default:
- break;
- }
- return warning;
- }
- /// <summary>
- /// 產生 random 20 character alphanumeric strings
- /// </summary>
- /// <returns></returns>
- private string GenerateRandomString()
- {
- var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
- var random = new Random();
- var list = Enumerable.Repeat(0, 20).Select(x => chars[random.Next(chars.Length)]);
- string finalString = string.Join("", list);
- return finalString;
- }
- /// <summary>
- /// 處理 Server Command
- /// </summary>
- /// <param name="cmd">server command</param>
- /// <param name="machineCustomId">電樁樁號</param>
- /// <param name="queue">Messgae queue</param>
- /// <param name="configurationKey">Configuration Key</param>
- /// <param name="reservationId">預約卡號</param>
- /// <param name="chargingProfileId">充電檔案</param>
- /// <param name="messageType">Message Type</param>
- /// <param name="db">Data Base Entity</param>
- /// <returns></returns>
- public string HandleServerCommand(BaseCmd cmd, string machineCustomId, ref Queue queue, ref List<KeyValueType> configurationKey, int reservationId, int chargingProfileId, out string messageType, PhihongDbContext db)
- {
- string result = string.Empty;
- messageType = string.Empty;
- //設定心跳時間和心跳的timeout次數
- if (cmd is Cmd1001)
- {
- var c = cmd as Cmd1001;
- if (c.ParamIndex == 21)
- {
- var machine = db.Machine.Where(x => x.CustomId == machineCustomId).AsNoTracking().FirstOrDefault();
- if (machine != null)
- {
- IRequest req = MakeRequestHandler.MakeChangeConfigurationRequest("HeartbeatInterval", machine.HeartbeatInterval.ToString());
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "ChangeConfiguration Request(HeartbeatInterval)";
- result = GenerateCall(uuid, Actions.ChangeConfiguration.ToString(), req);
- }
- }
- }
- //校時
- if (cmd is Cmd1003)
- {
- var c = cmd as Cmd1003;
- var machine = db.Machine.Where(x => x.CustomId == machineCustomId).AsNoTracking().FirstOrDefault();
- if (machine != null)
- {
- //確認發送是校時參數,就修改校時時間為封包送出時間
- if (c.ParamIndex == 2)
- {
- IRequest req = MakeRequestHandler.MakeChangeConfigurationRequest("HeartbeatInterval", "1");
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "ChangeConfiguration Request(HeartbeatInterval)";
- result = GenerateCall(uuid, Actions.ChangeConfiguration.ToString(), req);
- }
- //確認發送設定Server Domain Name
- if (c.ParamIndex == 11)
- {
- //OCPP 不支援Server Domain Name
- messageType = "Server Domain Name Request";
- result = String.Empty;
- }
- //確認發送設定樁的夥伴代碼
- if (c.ParamIndex == 12)
- {
- IRequest req = makeRequest.MakeSendPartnerPoleIdRequest(machine.PartnerPoleId);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "DataTransfer Request(SendPartnerPoleId)";
- result = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- }
- }
- //Remote結束充電
- if (cmd is Cmd1005)
- {
- var c = cmd as Cmd1005;
- //int transactionId = 0;
- var machine = db.Machine.Where(x => x.CustomId == machineCustomId).AsNoTracking().FirstOrDefault();
- //確認發送停止充電
- if (c.ParamIndex == 2)
- {
- if (machine != null)
- {
- var gunStatusNow = db.MachineGun.Where(x => x.GunSerNo == c.GunSerNo
- && x.MachineId == machine.Id).AsNoTracking().FirstOrDefault();
- //如果是 DC且狀態等於 2(充電中) 或是 AC或 HMI 且在充電中
- if ((machine.MachineModelId == 2 && gunStatusNow.Status == 2) || (machine.MachineModelId != 2 && (gunStatusNow.Status == 2 || gunStatusNow.Status == 3)))
- {
- var record = db.ChargingRecord.Where(x => x.GunSerNo == c.GunSerNo
- && x.MachineId == machine.Id
- && x.ClientStartChargingDateTime == null
- && x.ClientEndChargingDateTime == null
- && x.EndChargingDateTime == null
- && x.StartChargingDateTime != null
- && x.ChargingSerNo == gunStatusNow.ChargingSerNo).AsNoTracking().FirstOrDefault();
- var chargingTransaction = db.ChargingTransaction.Where(x => x.ChargingRecordId == record.Id).AsNoTracking().FirstOrDefault();
- IRequest req = makeRequest.MakeRemoteStopTransactionRequest(chargingTransaction.TransactionId);
- //client.RemoteCharging = true; /// Remote充電
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "RemoteStopTransaction Request";
- result = GenerateCall(uuid, Actions.RemoteStopTransaction.ToString(), req);
- }
- }
- }
- //確認發送停止預約
- if (c.ParamIndex == 10)
- {
- if (machine != null)
- {
- IRequest req = makeRequest.MakeCancelReservationRequest(reservationId);
- //client.RemoteCharging = true; /// Remote充電
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "CancelReservation Request";
- result = GenerateCall(uuid, Actions.CancelReservation.ToString(), req);
- }
- }
- //確認發送Psu Log To Ftp (發送 GetDiagnostics 訊息)
- if (c.ParamIndex == 17)
- {
- if (machine != null)
- {
- IRequest req = MakeRequestHandler.MakeGetDiagnosticsRequest(machine.AC);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "GetDiagnostics Request";
- result = GenerateCall(uuid, Actions.GetDiagnostics.ToString(), req);
- }
- }
- /// 18: QRCode Flash 效果 , 19: 禁用充电桩, 20: 启用充电桩
- if (c.ParamIndex == 18 || c.ParamIndex == 19 || c.ParamIndex == 20)
- {
- if (machine != null)
- {
- var type = Convert.ToInt32(c.ParamIndex);
- int gunNo = 0;
- switch (type)
- {
- //QRCode Flash 效果
- case 18:
- gunNo = c.GunSerNo + 1;
- break;
- // 19: 禁用充电桩
- case 19:
- gunNo = 0;
- break;
- //20: 启用充电桩
- case 20:
- gunNo = 0;
- break;
- }
- IRequest req = makeRequest.MakeCustomCommandRequest(gunNo, type);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "DataTransfer Request(CustomCommand)";
- result = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- }
- }
- //Remote啟動充電 / 預約充電
- if (cmd is Cmd1007)
- {
- var c = cmd as Cmd1007;
- if (c.StartChargingType == 0) // 0:实时充电
- {
- var machine = db.Machine.Where(x => x.CustomId == machineCustomId).AsNoTracking().FirstOrDefault();
- var memberQuery = db.MemberCharging.Where(x => x.MemberId == c.ReservationCardNum).AsNoTracking().FirstOrDefault();
- string randomString = string.Empty;
- if (memberQuery == null) // member id不存在,才產生新的SelfDefinedId
- {
- randomString = GenerateRandomString();
- var selfDefinedIdQuery = db.MemberCharging.Where(x => x.SelfDefinedId == randomString).AsNoTracking().FirstOrDefault();
- while (selfDefinedIdQuery != null)
- {
- randomString = GenerateRandomString();
- selfDefinedIdQuery = db.MemberCharging.Where(x => x.SelfDefinedId == randomString).AsNoTracking().FirstOrDefault();
- }
- //將 random 20 character alphanumeric strings 與 MemberId 儲存到 Member 表格,之後處理Remote充電會透過Member表格取得 MemberId
- MemberMapping remotemember = new MemberMapping();
- remotemember.MemberId = c.ReservationCardNum;
- remotemember.SelfDefinedId = randomString;
- remotemember.CustomerId = machine.CustomerId;
- remotemember.CreatedOn = DateTime.Now;
- db.MemberCharging.Add(remotemember);
- db.SaveChanges();
- }
- else
- {
- randomString = memberQuery.SelfDefinedId;
- }
- //處理Remote充電命令,並且發送給電樁
- IRequest req = makeRequest.MakeRemoteStartTransactionRequest((int)c.GunSerNo + 1, randomString);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "RemoteStartTransaction Request";
- result = GenerateCall(uuid, Actions.RemoteStartTransaction.ToString(), req);
- }
- if (c.StartChargingType == 1) // 1: 定時啟動充電
- {
- var machine = db.Machine.Where(x => x.CustomId == machineCustomId).AsNoTracking().FirstOrDefault();
- var memberQuery = db.MemberCharging.Where(x => x.MemberId == c.ReservationCardNum).AsNoTracking().FirstOrDefault();
- string randomString = string.Empty;
- if (memberQuery == null) // member id不存在,才產生新的SelfDefinedId
- {
- randomString = GenerateRandomString();
- var selfDefinedIdQuery = db.MemberCharging.Where(x => x.SelfDefinedId == randomString).AsNoTracking().FirstOrDefault();
- while (selfDefinedIdQuery != null)
- {
- randomString = GenerateRandomString();
- selfDefinedIdQuery = db.MemberCharging.Where(x => x.SelfDefinedId == randomString).AsNoTracking().FirstOrDefault();
- }
- //將 random 20 character alphanumeric strings 與 MemberId 儲存到 Member 表格,之後處理Remote充電會透過Member表格取得 MemberId
- MemberMapping remotemember = new MemberMapping();
- remotemember.MemberId = c.ReservationCardNum;
- remotemember.SelfDefinedId = randomString;
- remotemember.CustomerId = machine.CustomerId;
- remotemember.CreatedOn = DateTime.Now;
- db.MemberCharging.Add(remotemember);
- db.SaveChanges();
- }
- else
- {
- randomString = memberQuery.SelfDefinedId;
- }
- AutoChargeReservation autoChargeReservation = new AutoChargeReservation();
- autoChargeReservation.connectorId = (int)c.GunSerNo + 1;
- autoChargeReservation.chargingStrategy = (ChargingStrategy)c.ChargingStrategy;
- autoChargeReservation.chargingStrategyParam = (double)c.ChargingStrategyParam;
- autoChargeReservation.startChargingDateTime = (DateTime)c.StartChargingDateTime;
- autoChargeReservation.idTag = randomString;
- autoChargeReservation.accountBalance = (double)c.AccountBalance.RealValue;
- autoChargeReservation.memberName = c.MemberName;
- autoChargeReservation.vehicleType = (int)c.VehicleType;
- autoChargeReservation.reservationId = reservationId;
- //處理定時啟動充電,並且發送給電樁
- IRequest req = makeRequest.MakeAutoChargeReservationRequest(autoChargeReservation);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "DataTransfer Request(AutoChargeReservation)";
- result = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- if (c.StartChargingType == 2) // 2:预约充电
- {
- var machine = db.Machine.Where(x => x.CustomId == machineCustomId).AsNoTracking().FirstOrDefault();
- var memberQuery = db.MemberCharging.Where(x => x.MemberId == c.ReservationCardNum).AsNoTracking().FirstOrDefault();
- string randomString = string.Empty;
- if (memberQuery == null) // member id不存在,才產生新的SelfDefinedId
- {
- randomString = GenerateRandomString();
- var selfDefinedIdQuery = db.MemberCharging.Where(x => x.SelfDefinedId == randomString).AsNoTracking().FirstOrDefault();
- while (selfDefinedIdQuery != null)
- {
- randomString = GenerateRandomString();
- selfDefinedIdQuery = db.MemberCharging.Where(x => x.SelfDefinedId == randomString).AsNoTracking().FirstOrDefault();
- }
- //將 random 20 character alphanumeric strings 與 MemberId 儲存到 Member 表格,之後處理Remote充電會透過Member表格取得 MemberId
- MemberMapping remotemember = new MemberMapping();
- remotemember.MemberId = c.ReservationCardNum;
- remotemember.SelfDefinedId = randomString;
- remotemember.CustomerId = machine.CustomerId;
- remotemember.CreatedOn = DateTime.Now;
- db.MemberCharging.Add(remotemember);
- db.SaveChanges();
- }
- else
- {
- randomString = memberQuery.SelfDefinedId;
- }
- var item = configurationKey.Where(a => a.key == "ReserveConnectorZeroSupported").FirstOrDefault();
- IRequest req = makeRequest.MakeReserveNowRequest((int)c.GunSerNo + 1, randomString, Convert.ToBoolean(item.value), reservationId);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "ReserveNow Request";
- result = GenerateCall(uuid, Actions.ReserveNow.ToString(), req);
- }
- }
- //后台服务器下发充电桩本地验证卡号名单命令
- if (cmd is Cmd1009)
- {
- var c = cmd as Cmd1009;
- string sLine = "";
- if (!Directory.Exists(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UploadFiles")))
- {
- Directory.CreateDirectory(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UploadFiles"));
- }
- string fileName = System.IO.Path.GetFileName(c.Url);
- string destFilePath = System.IO.Path.Combine(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UploadFiles/"), fileName);
- if (!Directory.Exists(destFilePath))
- {
- List<Task> tList = new List<Task>();
- //downloading
- using (WebClient webClient = new WebClient())
- {
- webClient.Credentials = CredentialCache.DefaultNetworkCredentials;
- if (c.Url.Contains("http") == false)
- {
- c.Url = "http://" + c.Url;
- }
- tList.Add(Task.Run(() => webClient.DownloadFileTaskAsync(new Uri(c.Url), destFilePath)));
- }
- Task.WaitAll(tList.ToArray());
- }
- if (File.Exists(destFilePath))
- {
- using (FileStream file = new FileStream(destFilePath, FileMode.Open, FileAccess.Read))
- {
- using (StreamReader srReader = new StreamReader(file))
- {
- sLine = srReader.ReadToEnd();
- }
- }
- }
- List<OCPPServer.Common.LocalAuthorization> localAuthorizationList = JsonConvert.DeserializeObject<List<OCPPServer.Common.LocalAuthorization>>(sLine);
- IRequest req = MakeRequestHandler.MakeSendLocalListRequest(localAuthorizationList, c.VersionNo, c.Type);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "SendLocalListRequest Request";
- result = GenerateCall(uuid, Actions.SendLocalList.ToString(), req);
- }
- if (cmd is Cmd1011)
- {
- IRequest req = MakeRequestHandler.MakeGetLocalListVersionRequest();
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "GetLocalListVersion Request";
- result = GenerateCall(uuid, Actions.GetLocalListVersion.ToString(), req);
- }
- if (cmd is Cmd1013)
- {
- var c = cmd as Cmd1013;
- int TransactionId = 0;
- var machine = db.Machine.Where(x => x.CustomId == machineCustomId).AsNoTracking().FirstOrDefault();
- var gunStatusNow = db.MachineGun.Where(y => y.GunSerNo == c.GunSerNo
- && y.MachineId == machine.Id).AsNoTracking().FirstOrDefault();
- //充電目的檔為 TxProfile
- if (gunStatusNow != null && c.ChargingProfilePurpose == 2)
- {
- //確認電樁在充電中
- if (gunStatusNow.Status == 2 || gunStatusNow.Status == 3)
- {
- var chargingRecord = db.ChargingRecord.Where(x => x.ChargingSerNo == gunStatusNow.ChargingSerNo).AsNoTracking().FirstOrDefault();
- if (chargingRecord != null)
- {
- var chargingTransaction = db.ChargingTransaction.Where(x => x.MachineId == machine.Id
- && x.GunSerNo == c.GunSerNo
- && x.ChargingRecordId == chargingRecord.Id).AsNoTracking().FirstOrDefault();
- if (chargingTransaction != null)
- {
- TransactionId = chargingTransaction.TransactionId;
- }
- }
- }
- }
- IRequest req = MakeRequestHandler.MakeSetChargingProfileRequest(cmd, TransactionId);
- lock (_clientQueue)
- {
- queue.store(req, c.UUID);
- }
- messageType = "SetChargingProfile Request";
- result = GenerateCall(c.UUID, Actions.SetChargingProfile.ToString(), req);
- }
- if (cmd is Cmd1015)
- {
- var c = cmd as Cmd1015;
- IRequest req = makeRequest.MakeClearChargingProfileRequest(cmd);
- lock (_clientQueue)
- {
- queue.store(req, c.UUID);
- }
- messageType = "ClearChargingProfile Request";
- result = GenerateCall(c.UUID, Actions.ClearChargingProfile.ToString(), req);
- }
- if (cmd is Cmd1017)
- {
- var c = cmd as Cmd1017;
- IRequest req = MakeRequestHandler.MakeSendChargingConfigRequest(cmd);
- lock (_clientQueue)
- {
- queue.store(req, c.UUID);
- }
- messageType = "SetChargingConfig Request";
- result = GenerateCall(c.UUID, Actions.DataTransfer.ToString(), req);
- }
- if (cmd is Cmd1019)
- {
- var c = cmd as Cmd1019;
- IRequest req = MakeRequestHandler.MakeSendGetChargingConfigRequest(cmd);
- lock (_clientQueue)
- {
- queue.store(req, c.UUID);
- }
- messageType = "GetChargingConfig Request";
- result = GenerateCall(c.UUID, Actions.DataTransfer.ToString(), req);
- }
- //設定每度費用
- if (cmd is Cmd2301)
- {
- var c = cmd as Cmd2301;
- IRequest req = makeRequest.MakeAllDayUniformElectricBillRequest(c.PricePerKWH.RealValue);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "DataTransfer Request(AllDayUniformElectricBill)";
- result = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- //設定區段費用
- if (cmd is Cmd2303)
- {
- var c = cmd as Cmd2303;
- List<double> sectionElectricBill = new List<double>();
- sectionElectricBill.Add((double)c.Section0000_0030.RealValue);
- sectionElectricBill.Add((double)c.Section0030_0100.RealValue);
- sectionElectricBill.Add((double)c.Section0100_0130.RealValue);
- sectionElectricBill.Add((double)c.Section0130_0200.RealValue);
- sectionElectricBill.Add((double)c.Section0200_0230.RealValue);
- sectionElectricBill.Add((double)c.Section0230_0300.RealValue);
- sectionElectricBill.Add((double)c.Section0300_0330.RealValue);
- sectionElectricBill.Add((double)c.Section0330_0400.RealValue);
- sectionElectricBill.Add((double)c.Section0400_0430.RealValue);
- sectionElectricBill.Add((double)c.Section0430_0500.RealValue);
- sectionElectricBill.Add((double)c.Section0500_0530.RealValue);
- sectionElectricBill.Add((double)c.Section0530_0600.RealValue);
- sectionElectricBill.Add((double)c.Section0600_0630.RealValue);
- sectionElectricBill.Add((double)c.Section0630_0700.RealValue);
- sectionElectricBill.Add((double)c.Section0700_0730.RealValue);
- sectionElectricBill.Add((double)c.Section0730_0800.RealValue);
- sectionElectricBill.Add((double)c.Section0800_0830.RealValue);
- sectionElectricBill.Add((double)c.Section0830_0900.RealValue);
- sectionElectricBill.Add((double)c.Section0900_0930.RealValue);
- sectionElectricBill.Add((double)c.Section0930_1000.RealValue);
- sectionElectricBill.Add((double)c.Section1000_1030.RealValue);
- sectionElectricBill.Add((double)c.Section1030_1100.RealValue);
- sectionElectricBill.Add((double)c.Section1100_1130.RealValue);
- sectionElectricBill.Add((double)c.Section1130_1200.RealValue);
- sectionElectricBill.Add((double)c.Section1200_1230.RealValue);
- sectionElectricBill.Add((double)c.Section1230_1300.RealValue);
- sectionElectricBill.Add((double)c.Section1300_1330.RealValue);
- sectionElectricBill.Add((double)c.Section1330_1400.RealValue);
- sectionElectricBill.Add((double)c.Section1400_1430.RealValue);
- sectionElectricBill.Add((double)c.Section1430_1500.RealValue);
- sectionElectricBill.Add((double)c.Section1500_1530.RealValue);
- sectionElectricBill.Add((double)c.Section1530_1600.RealValue);
- sectionElectricBill.Add((double)c.Section1600_1630.RealValue);
- sectionElectricBill.Add((double)c.Section1630_1700.RealValue);
- sectionElectricBill.Add((double)c.Section1700_1730.RealValue);
- sectionElectricBill.Add((double)c.Section1730_1800.RealValue);
- sectionElectricBill.Add((double)c.Section1800_1830.RealValue);
- sectionElectricBill.Add((double)c.Section1830_1900.RealValue);
- sectionElectricBill.Add((double)c.Section1900_1930.RealValue);
- sectionElectricBill.Add((double)c.Section1930_2000.RealValue);
- sectionElectricBill.Add((double)c.Section2000_2030.RealValue);
- sectionElectricBill.Add((double)c.Section2030_2100.RealValue);
- sectionElectricBill.Add((double)c.Section2100_2130.RealValue);
- sectionElectricBill.Add((double)c.Section2130_2200.RealValue);
- sectionElectricBill.Add((double)c.Section2200_2230.RealValue);
- sectionElectricBill.Add((double)c.Section2230_2300.RealValue);
- sectionElectricBill.Add((double)c.Section2300_2330.RealValue);
- sectionElectricBill.Add((double)c.Section2330_2400.RealValue);
- IRequest req = makeRequest.MakeAllDaySectionElectricBillRequest(sectionElectricBill);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "DataTransfer Request(AllDaySectionElectricBill)";
- result = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- //設定每度服務費
- if (cmd is Cmd2305)
- {
- var c = cmd as Cmd2305;
- IRequest req = makeRequest.MakeFeePerKWHRequest(c.FeePerKWH.RealValue);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "DataTransfer Request(FeePerKWH)";
- result = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- //ocpp cmd: MessageTrigger BootNotification
- if (cmd is Cmd9001)
- {
- IRequest req = makeRequest.MakeTriggerMessageRequest(MessageTrigger.BootNotification, 1);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "TriggerMessage Request(BootNotification)";
- result = GenerateCall(uuid, Actions.TriggerMessage.ToString(), req);
- }
- //ocpp cmd: MessageTrigger DiagnosticsStatusNotification
- if (cmd is Cmd9003)
- {
- IRequest req = makeRequest.MakeTriggerMessageRequest(MessageTrigger.DiagnosticsStatusNotification, 1);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "TriggerMessage Request(DiagnosticsStatusNotification)";
- result = GenerateCall(uuid, Actions.TriggerMessage.ToString(), req);
- }
- //ocpp cmd: MessageTrigger FirmwareStatusNotification
- if (cmd is Cmd9005)
- {
- IRequest req = makeRequest.MakeTriggerMessageRequest(MessageTrigger.FirmwareStatusNotification, 1);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "TriggerMessage Request(FirmwareStatusNotification)";
- result = GenerateCall(uuid, Actions.TriggerMessage.ToString(), req);
- }
- //ocpp cmd: MessageTrigger Heartbeat
- if (cmd is Cmd9007)
- {
- IRequest req = makeRequest.MakeTriggerMessageRequest(MessageTrigger.Heartbeat, 1);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "TriggerMessage Request(Heartbeat)";
- result = GenerateCall(uuid, Actions.TriggerMessage.ToString(), req);
- }
- //ocpp cmd: MessageTrigger MeterValues
- if (cmd is Cmd9009)
- {
- IRequest req = makeRequest.MakeTriggerMessageRequest(MessageTrigger.MeterValues, 1);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "TriggerMessage Request(MeterValues)";
- result = GenerateCall(uuid, Actions.TriggerMessage.ToString(), req);
- }
- //ocpp cmd: MessageTrigger StatusNotification
- if (cmd is Cmd9011)
- {
- IRequest req = makeRequest.MakeTriggerMessageRequest(MessageTrigger.StatusNotification, 1);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "TriggerMessage Request(StatusNotification)";
- result = GenerateCall(uuid, Actions.TriggerMessage.ToString(), req);
- }
- //ocpp cmd : SendLocalListRequest , GetLocalListVersion , OCPPUpdateFirmware
- if (cmd is Cmd9013)
- {
- var c = cmd as Cmd9013;
- //OCPP UpdateFirmware
- if (c.ParamIndex == 4)
- {
- var machine = db.Machine.Where(x => x.CustomId == machineCustomId).AsNoTracking().FirstOrDefault();
- IRequest req = MakeRequestHandler.MakeOCPPUpdateFirmwareRequest(@"http://");
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "OCPPUpdateFirmware Request";
- result = GenerateCall(uuid, Actions.UpdateFirmware.ToString(), req);
- }
- }
- //ocpp cmd : SetChargingProfile
- if (cmd is Cmd9015)
- {
- var c = cmd as Cmd9015;
- string purpose = System.Text.Encoding.ASCII.GetString(c.ParamByteList.ToArray()).Trim('\0');
- var machine = db.Machine.Where(x => x.CustomId == machineCustomId).AsNoTracking().FirstOrDefault();
- IRequest req = MakeRequestHandler.MakeSetChargingProfileRequest(0, 0, chargingProfileId, purpose);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "SetChargingProfile Request";
- result = GenerateCall(uuid, Actions.SetChargingProfile.ToString(), req);
- if (result.Contains("TxProfile") == false)
- {
- int location = result.IndexOf("transactionId");
- int len = "\"transactionId\":0,".Length;
- result = result.Remove(location - 1, len);
- }
- }
- //ocpp cmd : ClearChargingProfile
- if (cmd is Cmd9017)
- {
- IRequest req = makeRequest.MakeClearChargingProfileRequest(0);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "ClearChargingProfile Request";
- result = GenerateCall(uuid, Actions.ClearChargingProfile.ToString(), req);
- }
- //ocpp cmd : GetCompositeSchedule
- if (cmd is Cmd9019)
- {
- IRequest req = makeRequest.MakeGetCompositeScheduleRequest(0);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "GetCompositeSchedule Request";
- result = GenerateCall(uuid, Actions.GetCompositeSchedule.ToString(), req);
- }
- //ocpp cmd : HardReset
- if (cmd is Cmd9021)
- {
- IRequest req = makeRequest.MakeHardResetRequest();
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "Reset Request(Hard)";
- result = GenerateCall(uuid, Actions.Reset.ToString(), req);
- }
- //ocpp cmd : SoftReset
- if (cmd is Cmd9023)
- {
- IRequest req = makeRequest.MakeSoftResetRequest();
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "Reset Request(Soft)";
- result = GenerateCall(uuid, Actions.Reset.ToString(), req);
- }
- //ocpp cmd : ClearCache
- if (cmd is Cmd9025)
- {
- IRequest req = makeRequest.MakeClearCacheRequest();
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "ClearCache Request";
- result = GenerateCall(uuid, Actions.ClearCache.ToString(), req);
- }
- //ocpp cmd : ChangeAvailability
- if (cmd is Cmd9027)
- {
- IRequest req = makeRequest.MakeChangeAvailabilityRequest(1);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "ChangeAvailability Request";
- result = GenerateCall(uuid, Actions.ChangeAvailability.ToString(), req);
- }
- //ocpp cmd : GetConfiguration
- if (cmd is Cmd9029)
- {
- IRequest req = makeRequest.MakeGetConfigurationRequest("");
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "GetConfiguration Request";
- result = GenerateCall(uuid, Actions.GetConfiguration.ToString(), req);
- }
- //ocpp cmd : UnlockConnector
- if (cmd is Cmd9031)
- {
- IRequest req = makeRequest.MakeUnlockConnectorRequest(1);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- messageType = "UnlockConnector Request";
- result = GenerateCall(uuid, Actions.UnlockConnector.ToString(), req);
- }
- return result;
- }
- /// <summary>
- /// 處理OCPP Request Message
- /// </summary>
- /// <param name="request">OCPP Request Message</param>
- /// <param name="callid">OCPP Request Message Call Id</param>
- /// <param name="db">Data Base Entity</param>
- /// <param name="client">Connected Client Data</param>
- /// <returns></returns>
- public OCPPResult HandleRequest(IRequest request, string callid, PhihongDbContext db, ref ClientData client)
- {
- OCPPResult result = new OCPPResult();
- IUnitOfWork uowtemp = new UnitOfWork(db);
- IMachineService machineSrvTemp = new MachineService(uowtemp);
- ISocketCommandService socketCommandSrvTemp = new SocketCommandService(uowtemp);
- ICustomerService _customerServiceTemp = new CustomerService();
- try
- {
- //簽到
- if (request is BootNotificationRequest)
- {
- var cmd = request as BootNotificationRequest;
- result.Success = true;
- result.Payload = makeConfirmation.MakeBootNotificationConfirmation(cmd);
- }
- //刷卡認證
- if (request is AuthorizeRequest)
- {
- #region AuthorizeRequest
- var cmd = request as AuthorizeRequest;
- var c = new HttpClient();
- string receivedCard = string.Empty;
- string cardpwd = string.Empty;
- //判斷此Authorize Reauest是Remote啟動充電 或 刷卡/後台啟動
- MemberMapping memberObj = db.MemberCharging.Where(x => x.SelfDefinedId == cmd.idTag).AsNoTracking().FirstOrDefault();
- if (memberObj != null)//為Remote啟動充電
- {
- receivedCard = memberObj.MemberId;
- }
- else //為刷卡或後台啟動
- {
- receivedCard = cmd.idTag;
- cardpwd = "nocheck";
- }
- var param = new { CustomerName = client.CustomerName, CardNum = receivedCard, PoleId = client.MachineCustomId, CardPwd = cardpwd };
- //將卡片資訊送到營運平台驗證
- var response = c.PostAsJsonAsync(ApiUrl + @"AuthenticateCard", param).Result;
- string responseBody = response.Content.ReadAsStringAsync().Result;
- if (response.IsSuccessStatusCode)
- {
- //伺服器回應正常
- var machine = machineSrvTemp.GetByCustomId(client.MachineCustomId);
- var authresult = JsonConvert.DeserializeObject<Cmd1203>(responseBody);
- if (authresult.UserMessageCode == 1) //卡片餘額充足
- {
- //卡片認證成功
- result.Payload = makeConfirmation.MakeAuthorizeConfirmation(cmd, AuthorizationStatus.Accepted);
- #region 下發卡片餘額
- IRequest req = makeRequest.MakeAccountBalanceRequest(callid, authresult.AccountBalance.RealValue, client.CarType);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = client.queue.store(req);
- }
- result.Message = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- #endregion 下發卡片餘額
- }
- else
- {
- if (authresult.UserMessageCode == 6) //卡片被凍結
- {
- //卡片認證失敗,檢查卡片是否在充電中
- //取得充電樁目前的Status
- string rqueryCard = string.Empty;
- if (memberObj != null) //為Remote啟動充電
- {
- rqueryCard = memberObj.MemberId;
- }
- else
- {
- rqueryCard = cmd.idTag;
- }
- //若電樁狀態不是"充電中"/"充電結束" ,MachineGun的ReservationCardNum欄位為空白,此時取出的 gunStatusNow 為null
- var gunStatusNow = db.MachineGun.Where(x => x.ReservationCardNum == rqueryCard
- && x.MachineId == machine.Id).AsNoTracking().FirstOrDefault();
- if (gunStatusNow != null && (gunStatusNow.Status == 2 || gunStatusNow.Status == 3))
- {
- //取得充電樁在充電中或充電結束的狀態,回應有效
- result.Payload = makeConfirmation.MakeAuthorizeConfirmation(cmd, AuthorizationStatus.Accepted);
- }
- else
- {
- //取得充電樁不在充電中或充電結束的狀態,回應無效
- result.Payload = makeConfirmation.MakeAuthorizeConfirmation(cmd, AuthorizationStatus.Blocked);
- #region 下發卡片餘額
- {
- IRequest req = makeRequest.MakeAccountBalanceRequest(callid, authresult.AccountBalance.RealValue, client.CarType);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = client.queue.store(req);
- }
- result.Message = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- #endregion 下發卡片餘額
- }
- }
- else
- {
- //卡片為非餘額充足.非凍結的其他狀態
- result.Payload = makeConfirmation.MakeAuthorizeConfirmation(cmd, AuthorizationStatus.Invalid);
- #region 下發卡片餘額
- {
- IRequest req = makeRequest.MakeAccountBalanceRequest(callid, authresult.AccountBalance.RealValue, client.CarType);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = client.queue.store(req);
- }
- result.Message = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- #endregion 下發卡片餘額
- }
- }
- }
- else
- {
- //伺服器異常
- result.Payload = makeConfirmation.MakeAuthorizeConfirmation((AuthorizeRequest)request, AuthorizationStatus.Invalid);
- }
- result.Success = true;
- #endregion AuthorizeRequest
- }
- //狀態包
- if (request is StatusNotificationRequest)
- {
- #region StatusNotificationRequest
- //目前以DataTransfer的GunStatus封包取代
- var cmd = request as StatusNotificationRequest;
- logger.Trace("Receive Command Status{0}", client.MachineCustomId);
- result.Success = true;
- result.Payload = makeConfirmation.MakeStatusNotificationConfirmation(cmd);
- #endregion StatusNotificationRequest
- }
- //心跳包
- if (request is HeartbeatRequest)
- {
- result.Success = true;
- result.Payload = makeConfirmation.MakeHeartbeatConfirmation((HeartbeatRequest)request);
- client.heartbeatDate = DateTime.Now;
- }
- //充電狀態包
- if (request is MeterValuesRequest)
- {
- #region MeterValuesRequest
- var cmd = request as MeterValuesRequest;
- logger.Trace("Receive Command Status{0}", client.MachineCustomId);
- WebSocketCommandService wsCommandSrv = new WebSocketCommandService(uowtemp);
- //處理104狀態包
- //不存在機器,要紀錄起來
- var machine = machineSrvTemp.GetByCustomId(client.MachineCustomId);
- if (machine != null)
- {
- //取得充電樁目前Status的充電序號
- var gunStatusNow = db.MachineGun.Where(c => c.GunSerNo == (cmd.connectorId - 1)
- && c.MachineId == machine.Id).AsNoTracking().FirstOrDefault();
- if (gunStatusNow.Status != (byte)ChargePointStatus.Charging)
- {
- result.Success = true;
- result.Payload = makeConfirmation.MakeMeterValuesConfirmation(cmd);
- return result;
- }
- result.Success = true;
- result.Payload = makeConfirmation.MakeMeterValuesConfirmation(cmd);
- }
- #endregion MeterValuesRequest
- }
- //啟動充電狀態包
- if (request is StartTransactionRequest)
- {
- #region StartTransactionRequest
- var cmd = request as StartTransactionRequest;
- logger.Trace("Receive Command Status{0}", client.MachineCustomId);
- WebSocketCommandService wsCommandSrv = new WebSocketCommandService(uowtemp);
- //處理104狀態包
- //不存在機器,要紀錄起來
- var machine = machineSrvTemp.GetByCustomId(client.MachineCustomId);
- if (machine != null)
- {
- //取得充電樁目前Status的充電序號
- var gunStatusNow = db.MachineGun.Where(c => c.GunSerNo == (cmd.connectorId - 1)
- && c.MachineId == machine.Id).AsNoTracking().FirstOrDefault();
- int transactionId = 0;
- result.Success = true;
- #region 確認是否有重覆的StartTransaction
- var repeatStartTransaction = db.ChargingTransaction.Where(c => c.GunSerNo == (cmd.connectorId - 1)
- && c.MachineId == machine.Id
- && c.StartChargingDateTime == cmd.timestamp
- ).AsNoTracking().FirstOrDefault();
- if (repeatStartTransaction != null) //重複的StartTransaction
- result.Payload = makeConfirmation.MakeRePeatStartTransactionConfirmation(cmd, repeatStartTransaction.TransactionId);
- else
- result.Payload = makeConfirmation.MakeStartTransactionConfirmation(cmd, out transactionId);
- #endregion 確認是否有重覆的StartTransaction
- //取得OCPP transactionId之後,寫入mapping table(OCPP transactionId, 充電紀錄ID),取得充電樁目前Status的充電序號
- if (gunStatusNow.Status != (byte)ChargePointStatus.Charging)
- {
- gunStatusNow = db.MachineGun.Where(c => c.GunSerNo == (cmd.connectorId - 1)
- && c.MachineId == machine.Id).AsNoTracking().FirstOrDefault();
- }
- var record = db.ChargingRecord.Where(c => c.GunSerNo == (cmd.connectorId - 1)
- && c.MachineId == machine.Id
- && c.ClientStartChargingDateTime == null
- && c.ClientEndChargingDateTime == null
- && c.EndChargingDateTime == null
- && c.StartChargingDateTime != null
- && c.ChargingSerNo == gunStatusNow.ChargingSerNo).AsNoTracking().FirstOrDefault();
- //處理沒有重複送的StartTransaction封包
- if (record != null)
- {
- //避免在物件 'dbo.ChargingTransaction' 中插入重複的索引鍵資料列
- var chargingTransactiontemp = db.ChargingTransaction.Where(c => c.GunSerNo == (cmd.connectorId - 1)
- && c.MachineId == machine.Id
- && c.StartChargingDateTime == record.StartChargingDateTime
- ).AsNoTracking().FirstOrDefault();
- if (chargingTransactiontemp == null)
- {
- ChargingTransaction chargingTransaction = new ChargingTransaction();
- chargingTransaction.MachineId = machine.Id;
- chargingTransaction.TransactionId = transactionId;
- chargingTransaction.GunSerNo = (byte)(cmd.connectorId - 1);
- chargingTransaction.StartChargingDateTime = record.StartChargingDateTime;
- chargingTransaction.ChargingRecordId = record.Id;
- chargingTransaction.CreatedOn = DateTime.Now;
- db.ChargingTransaction.Add(chargingTransaction);
- db.SaveChanges();
- }
- }
- }
- #endregion StartTransactionRequest
- }
- //停止充電,接收充电桩上報最新一次充电信息
- if (request is StopTransactionRequest)
- {
- #region StopTransactionRequest
- //目前採用DataTransfer的ChargeComplete封包來取代 StopTransactionRequest
- var cmd = request as StopTransactionRequest;
- result.Success = true;
- result.Payload = makeConfirmation.MakeStopTransactionConfirmation(cmd, AuthorizationStatus.Accepted);
- logger.Trace("reply StopTransactionRequest");
- #endregion StopTransactionRequest
- }
- //接收電樁DiagnosticsStatus狀態
- if (request is DiagnosticsStatusNotificationRequest)
- {
- var cmd = request as DiagnosticsStatusNotificationRequest;
- logger.Trace("Receive 電樁 {0} Staus {1}", client.MachineCustomId, cmd.status.ToString());
- result.Success = true;
- result.Payload = makeConfirmation.MakeDiagnosticsStatusNotificationConfirmation();
- }
- //接收電樁update firmware 進度狀態
- if (request is FirmwareStatusNotificationRequest)
- {
- var cmd = request as FirmwareStatusNotificationRequest;
- if ((cmd.status == FirmwareStatus.DownloadFailed) || (cmd.status == FirmwareStatus.InstallationFailed))
- {
- //更新主程序 或 FW 部分
- }
- logger.Trace("Receive 電樁 {0} Staus {1}", client.MachineCustomId, cmd.status.ToString());
- result.Success = true;
- result.Payload = makeConfirmation.MakeFirmwareStatusNotificationConfirmation();
- }
- //處理自訂的訊息
- if (request is DataTransferRequest)
- {
- var cmd = request as DataTransferRequest;
- //刷卡認證
- if (cmd.messageId == "AuthorizeData")
- {
- #region AuthorizeData
- logger.Trace("Receive Command Status{0}", client.MachineCustomId);
- var cmd1204 = JsonConvert.DeserializeObject<AuthorizeData>(cmd.data);
- var c = new HttpClient();
- string receivedCard = string.Empty;
- //判斷此Authorize Reauest是Remote啟動充電 或 刷卡/後台啟動
- MemberMapping memberObj = db.MemberCharging.Where(x => x.SelfDefinedId == cmd1204.idTag).AsNoTracking().FirstOrDefault();
- if (memberObj != null)//為Remote啟動充電
- {
- receivedCard = memberObj.MemberId;
- }
- else //為刷卡或後台啟動
- {
- receivedCard = cmd1204.idTag;
- }
- var param = new { CustomerName = client.CustomerName, CardNum = receivedCard, PoleId = client.MachineCustomId, CardPwd = cmd1204.password };
- //將卡片資訊送到營運平台驗證
- var response = c.PostAsJsonAsync(ApiUrl + @"AuthenticateCard", param).Result;
- string responseBody = response.Content.ReadAsStringAsync().Result;
- if (response.IsSuccessStatusCode)
- {
- //伺服器回應正常
- var machine = machineSrvTemp.GetByCustomId(client.MachineCustomId);
- var authresult = JsonConvert.DeserializeObject<Cmd1203>(responseBody);
- if (authresult.UserMessageCode == 1) //卡片餘額充足
- {
- //卡片認證成功
- result.Payload = makeConfirmation.MakeAuthorizeDataConfConfirmation(cmd1204, AuthorizeStatus.Accepted);
- #region 下發卡片餘額
- IRequest req = makeRequest.MakeAccountBalanceRequest(callid, authresult.AccountBalance.RealValue, client.CarType);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = client.queue.store(req);
- }
- result.Message = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- #endregion 下發卡片餘額
- }
- else
- {
- if (authresult.UserMessageCode == 6) //卡片被凍結
- {
- //卡片認證失敗,檢查卡片是否在充電中
- //取得充電樁目前的Status
- string rqueryCard = string.Empty;
- if (memberObj != null) //為Remote啟動充電
- {
- rqueryCard = memberObj.MemberId;
- }
- else
- {
- rqueryCard = cmd1204.idTag;
- }
- //若電樁狀態不是"充電中"/"充電結束" ,MachineGun的ReservationCardNum欄位為空白,此時取出的 gunStatusNow 為null
- var gunStatusNow = db.MachineGun.Where(x => x.ReservationCardNum == rqueryCard
- && x.MachineId == machine.Id).AsNoTracking().FirstOrDefault();
- if (gunStatusNow != null && (gunStatusNow.Status == 2 || gunStatusNow.Status == 3))
- {
- //取得充電樁在充電中或充電結束的狀態,回應有效
- result.Payload = makeConfirmation.MakeAuthorizeDataConfConfirmation(cmd1204, AuthorizeStatus.Accepted);
- }
- else
- {
- //取得充電樁不在充電中或充電結束的狀態,回應無效
- result.Payload = makeConfirmation.MakeAuthorizeDataConfConfirmation(cmd1204, AuthorizeStatus.Blocked);
- #region 下發卡片餘額
- {
- IRequest req = makeRequest.MakeAccountBalanceRequest(callid, authresult.AccountBalance.RealValue, client.CarType);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = client.queue.store(req);
- }
- result.Message = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- #endregion 下發卡片餘額
- }
- }
- else if (authresult.UserMessageCode == 13) //密碼錯誤
- {
- result.Payload = makeConfirmation.MakeAuthorizeDataConfConfirmation(cmd1204, AuthorizeStatus.PasswordError);
- }
- else
- {
- //卡片為非餘額充足.非凍結的其他狀態
- result.Payload = makeConfirmation.MakeAuthorizeDataConfConfirmation(cmd1204, AuthorizeStatus.Invalid);
- #region 下發卡片餘額
- {
- IRequest req = makeRequest.MakeAccountBalanceRequest(callid, authresult.AccountBalance.RealValue, client.CarType);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = client.queue.store(req);
- }
- result.Message = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- #endregion 下發卡片餘額
- }
- }
- }
- else
- {
- //伺服器異常
- result.Payload = makeConfirmation.MakeAuthorizeConfirmation((AuthorizeRequest)request, AuthorizationStatus.Invalid);
- }
- result.Success = true;
- #endregion
- }
- if (cmd.messageId == "GunStatus")
- {
- #region GunStatus
- logger.Trace("Receive Command Status{0}", client.MachineCustomId);
- var cmd104 = JsonConvert.DeserializeObject<GunStatus>(cmd.data);
- WebSocketCommandService wsCommandSrv = new WebSocketCommandService(uowtemp);
- //處理104狀態包
- //不存在機器,要紀錄起來
- var machine = machineSrvTemp.GetByCustomId(client.MachineCustomId);
- #region mapper
- ChargingRecordStatus dObj = new ChargingRecordStatus();
- dObj.MachineId = machine.Id;
- dObj.MachineCustomId = machine.CustomId;
- dObj.Warning = ProcessErrorCode(machine.AC, cmd104.errorCode);
- dObj.DcV = (decimal)cmd104.dcVoltage;
- dObj.DcA = (decimal)cmd104.dcCurrent;
- dObj.BmsV = (decimal)cmd104.bmsVoltage;
- dObj.BmsA = (decimal)cmd104.bmsCurrent;
- dObj.AcV_A = (decimal)cmd104.acVoltage_A;
- dObj.AcV_B = (decimal)cmd104.acVoltage_B;
- dObj.AcV_C = (decimal)cmd104.acVoltage_C;
- dObj.AcA_A = (decimal)cmd104.acCurrent_A;
- dObj.AcA_B = (decimal)cmd104.acCurrent_B;
- dObj.AcA_C = (decimal)cmd104.acCurrent_C;
- dObj.BmsWorkingMode = (byte)cmd104.bmsWorkingMode;
- dObj.CumulativeKwh = (decimal)(cmd104.currentKwh - cmd104.beforeChargingKwh);//(decimal)cmd104.cumulativeKwh;
- dObj.CumulativeTime = cmd104.cumulativeTime;
- dObj.CurrentKwh = (decimal)cmd104.currentKwh;
- dObj.CardBalanceBeforeCharging = (decimal)cmd104.cardBalanceBeforeCharging;
- dObj.ChargingStrategy = (byte)cmd104.chargingStrategy;
- dObj.ChargingStrategyParam = (decimal)cmd104.chargingStrategyParameter;
- dObj.CurrentSoc = (byte)cmd104.currentSOC;
- dObj.CarConnection = (byte)cmd104.carConnectionStatus;
- dObj.KwhBeforeCharging = (decimal)cmd104.beforeChargingKwh;
- dObj.CumulativeChargeFee = (decimal)cmd104.cumulativeChargeFee;
- dObj.GunAmt = (byte)machine.GunAmt;
- dObj.GunSerNo = (byte)(cmd104.connectorId - 1);
- dObj.GunType = (byte)(machine.AC ? 2 : 1);
- dObj.RemainingTime = cmd104.remainingTime;
- dObj.Reservation = (byte)(cmd104.isReserved ? 1 : 0);
- dObj.ReservationOverTime = 0;
- dObj.StartWith = (byte)cmd104.startWith;
- dObj.CumulativeOutputKwh = Convert.ToDecimal(cmd104.CumulativeOutputKwh);
- dObj.GunTemperature = cmd104.GunTemperature;
- if (cmd104.status == ChargePointStatus.Charging || cmd104.status == ChargePointStatus.Finishing)
- {
- dObj.StartChargingDateTime = cmd104.startChargingDateTime;
- }
- else
- {
- dObj.StartChargingDateTime = null;
- }
- dObj.StartChargingType = (byte)cmd104.startChargingType;
- dObj.Status = (byte)cmd104.status;
- if (cmd104.startWith == StartWith.Member)
- {
- var membertb = db.MemberCharging.Where(c => c.SelfDefinedId == cmd104.idTag).AsNoTracking().FirstOrDefault();
- if (membertb != null)
- {
- //會員
- dObj.MemberId = membertb.MemberId.ToString();//client.ReservationCardNum;
- dObj.ReservationCardNum = membertb.MemberId.ToString();/*client.ReservationCardNum;*/
- }
- }
- else if ((cmd104.startWith == StartWith.CardNumber) || (cmd104.startWith == StartWith.Unknown))
- {
- dObj.ReservationCardNum = cmd104.idTag;
- }
- MChargingRecordStatus mdObj = new MChargingRecordStatus();
- mdObj.MachineId = machine.Id;
- mdObj.MachineCustomId = machine.CustomId;
- mdObj.Warning = ProcessErrorCode(machine.AC, cmd104.errorCode);
- mdObj.DcV = (decimal)cmd104.dcVoltage;
- mdObj.DcA = (decimal)cmd104.dcCurrent;
- mdObj.BmsV = (decimal)cmd104.bmsVoltage;
- mdObj.BmsA = (decimal)cmd104.bmsCurrent;
- mdObj.AcV_A = (decimal)cmd104.acVoltage_A;
- mdObj.AcV_B = (decimal)cmd104.acVoltage_B;
- mdObj.AcV_C = (decimal)cmd104.acVoltage_C;
- mdObj.AcA_A = (decimal)cmd104.acCurrent_A;
- mdObj.AcA_B = (decimal)cmd104.acCurrent_B;
- mdObj.AcA_C = (decimal)cmd104.acCurrent_C;
- mdObj.BmsWorkingMode = (byte)cmd104.bmsWorkingMode;
- mdObj.CumulativeKwh = (decimal)(cmd104.currentKwh - cmd104.beforeChargingKwh);//(decimal)cmd104.cumulativeKwh;
- mdObj.CumulativeTime = cmd104.cumulativeTime;
- mdObj.CurrentKwh = (decimal)cmd104.currentKwh;
- mdObj.CardBalanceBeforeCharging = (decimal)cmd104.cardBalanceBeforeCharging;
- mdObj.ChargingStrategy = (byte)cmd104.chargingStrategy;
- mdObj.ChargingStrategyParam = (decimal)cmd104.chargingStrategyParameter;
- mdObj.CurrentSoc = (byte)cmd104.currentSOC;
- mdObj.CarConnection = (byte)cmd104.carConnectionStatus;
- mdObj.KwhBeforeCharging = (decimal)cmd104.beforeChargingKwh;
- mdObj.CumulativeChargeFee = (decimal)cmd104.cumulativeChargeFee;
- mdObj.GunAmt = (byte)machine.GunAmt;
- mdObj.GunSerNo = (byte)(cmd104.connectorId - 1);
- mdObj.GunType = (byte)(machine.AC ? 2 : 1);
- mdObj.RemainingTime = cmd104.remainingTime;
- mdObj.Reservation = (byte)(cmd104.isReserved ? 1 : 0);
- mdObj.ReservationOverTime = 0;
- mdObj.StartWith = (byte)cmd104.startWith;
- mdObj.CumulativeOutputKwh = Convert.ToDecimal(cmd104.CumulativeOutputKwh);
- mdObj.GunTemperature = cmd104.GunTemperature;
- if (cmd104.status == ChargePointStatus.Charging || cmd104.status == ChargePointStatus.Finishing)
- {
- mdObj.StartChargingDateTime = cmd104.startChargingDateTime;
- }
- else
- {
- mdObj.StartChargingDateTime = null;
- }
- mdObj.StartChargingType = (byte)cmd104.startChargingType;
- mdObj.Status = (byte)cmd104.status;
- if (cmd104.startWith == StartWith.Member)
- {
- var membertb = db.MemberCharging.Where(c => c.SelfDefinedId == cmd104.idTag).AsNoTracking().FirstOrDefault();
- if (membertb != null)
- {
- //會員
- mdObj.MemberId = membertb.MemberId.ToString();//client.ReservationCardNum;
- mdObj.ReservationCardNum = membertb.MemberId.ToString();/*client.ReservationCardNum;*/
- }
- }
- else if ((cmd104.startWith == StartWith.CardNumber) || (cmd104.startWith == StartWith.Unknown))
- {
- mdObj.ReservationCardNum = cmd104.idTag;
- }
- #endregion mapper
- GunMessage socketCommand1104 = new GunMessage();
- socketCommand1104.chargingRecordStatus = dObj;
- socketCommand1104.mchargingRecordStatus = mdObj;
- var process1104Result = wsCommandSrv.Process1104(socketCommand1104);
- result.Success = true;
- result.Payload = makeConfirmation.MakeGunStatusConfirmation();
- #endregion GunStatus
- }
- if (cmd.messageId == "ChargeComplete")
- {
- #region ChargeComplete
- var chargeComplete = JsonConvert.DeserializeObject<ChargeComplete>(cmd.data);
- WebSocketCommandService wsCommandSrv = new WebSocketCommandService(uowtemp);
- //避免同時處理同一個樁號的ChargeComplete
- lock (_cmd202lst)
- {
- if (_cmd202lst.Contains(client.MachineCustomId))
- {
- result.Success = false;
- return result;
- }
- if (!_cmd202lst.Contains(client.MachineCustomId))
- {
- _cmd202lst.Add(client.MachineCustomId);
- }
- }
- logger.Trace("receive ChargeComplete{0}", client.MachineCustomId);
- var processChargeCompleteResult = wsCommandSrv.ProcessChargeComplete(chargeComplete, client.MachineCustomId);
- if (processChargeCompleteResult.Success)
- {
- result.Success = true;
- result.Payload = makeConfirmation.MakeChargeCompleteConfirmation();
- logger.Trace("reply ChargeComplete");
- }
- else
- {
- result.Success = false;
- result.Exception = processChargeCompleteResult.Exception;
- result.Message = processChargeCompleteResult.Message;
- logger.Error(processChargeCompleteResult.Exception, "ChargeComplete error");
- }
- lock (_cmd202lst)
- {
- _cmd202lst.Remove(client.MachineCustomId);
- }
- #endregion ChargeComplete
- }
- if (cmd.messageId == "Location")
- {
- #region Location
- var data = JsonConvert.DeserializeObject<OCPPPacket.Packet.DataTransfer.Location>(cmd.data);
- WebSocketCommandService wsCommandSrv = new WebSocketCommandService(uowtemp);
- logger.Trace("receive 1120 {0}", client.MachineCustomId);
- logger.Trace("receive 1120 {0} {1} {2}", client.MachineCustomId, data.longitude, data.latitude);
- var processLocationResult = wsCommandSrv.ProcessLocation(client.MachineCustomId, data);
- if (processLocationResult.Success)
- {
- result.Success = true;
- result.Payload = makeConfirmation.MakeLocationConfirmation();
- logger.Trace("reply Location");
- }
- else
- {
- result.Success = false;
- result.Exception = processLocationResult.Exception;
- logger.Error(processLocationResult.Exception, "Location.conf error");
- }
- #endregion Location
- }
- if (cmd.messageId == "ChargingGunBMS")
- {
- #region ChargingGunBMS
- var data = JsonConvert.DeserializeObject<ChargingGunBMS>(cmd.data);
- WebSocketCommandService wsCommandSrv = new WebSocketCommandService(uowtemp);
- var processChargingGunBMSResult = wsCommandSrv.ProcessChargingGunBMS(client.MachineId, data);
- if (processChargingGunBMSResult.Success)
- {
- result.Success = true;
- result.Payload = makeConfirmation.MakeChargingGunBMSConfirmation();
- logger.Trace("reply ChargingGunBMS");
- }
- #endregion ChargingGunBMS
- }
- //電樁上報升級文件的版
- if (cmd.messageId == "UpgradeVersion")
- {
- #region UpgradeVersion
- UploadFile uploadFile = null;
- WebSocketCommandService wsCommandSrv = new WebSocketCommandService(uowtemp);
- var data = JsonConvert.DeserializeObject<UpgradeVersion>(cmd.data);
- var processUpgradeVersionResult = wsCommandSrv.CheckCmd2104(client.MachineId, data, out uploadFile);
- result.Success = true;
- result.Payload = makeConfirmation.MakeUpgradeVersionConfConfirmation(processUpgradeVersionResult, data.param);
- logger.Trace("reply DataTransfer.conf");
- //DC 桩
- if (uploadFile != null)
- {
- //製作 UpdateFirmware Request
- if (((int)data.param == 1 || CmdHelper.GetCmd2101Type((byte)data.param) == 2) && processUpgradeVersionResult == false)
- {
- int type = CmdHelper.GetCmd2101Type((byte)data.param);
- IRequest req = makeRequest.MakeUpdateFirmware(type, data.param, uploadFile);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = client.queue.store(req);
- }
- result.Message = GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- }
- #endregion UpgradeVersion
- }
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- result.Exception = ex;
- result.Success = false;
- }
- return result;
- }
- /// <summary>
- /// 判斷是否由會員帳號充電
- /// </summary>
- /// <param name="request">OCPP Request</param>
- /// <param name="db">Data Base Entity</param>
- /// <returns></returns>
- public bool IsMemberCharging(IRequest request, PhihongDbContext db)
- {
- bool result = new Boolean();
- IUnitOfWork uowtemp = new UnitOfWork(db);
- IMachineService machineSrvTemp = new MachineService(uowtemp);
- ISocketCommandService socketCommandSrvTemp = new SocketCommandService(uowtemp);
- ICustomerService _customerServiceTemp = new CustomerService();
- try
- {
- //刷卡認證
- if (request is AuthorizeRequest)
- {
- var cmd = request as AuthorizeRequest;
- //判斷此Authorize Reauest是Remote啟動充電 或 刷卡/後台啟動
- MemberMapping memberObj = db.MemberCharging.Where(x => x.SelfDefinedId == cmd.idTag).AsNoTracking().FirstOrDefault();
- if (memberObj != null)//為Remote啟動充電
- {
- result = true;
- }
- else //為刷卡或後台啟動
- {
- result = false;
- }
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- result = false;
- }
- return result;
- }
- /// <summary>
- /// 處理電樁所送的comfirm message
- /// </summary>
- /// <param name="uniqueId">OCPP Message uniqueId</param>
- /// <param name="confirmation">OCPP Confirm Message</param>
- /// <param name="db">Data Base Entity</param>
- /// <param name="client">Connected Client Data</param>
- /// <returns></returns>
- public OCPPResult HandleConfirmation(string uniqueId, IConfirmation confirmation, string callResultAction, PhihongDbContext db, ref ClientData client)
- {
- OCPPResult result = new OCPPResult();
- IUnitOfWork uowconf = new UnitOfWork(db);
- IRepository<MachineVersionFile> _mvfRepo = uowconf.Repository<MachineVersionFile>();
- try
- {
- #region Core
- //接收電樁對Remote啟動充電回應
- if (confirmation is RemoteStartTransactionConfirmation)
- {
- IConfirmation cmd = confirmation as RemoteStartTransactionConfirmation;
- }
- //接收電樁對Remote停止充電回應
- if (confirmation is RemoteStopTransactionConfirmation)
- {
- IConfirmation cmd = confirmation as RemoteStopTransactionConfirmation;
- }
- //接收電樁對Unlock Connector回應
- if (confirmation is UnlockConnectorConfirmation)
- {
- IConfirmation cmd = confirmation as UnlockConnectorConfirmation;
- }
- //接收電樁對configuration 回應
- if (confirmation is GetConfigurationConfirmation)
- {
- GetConfigurationConfirmation cmd = confirmation as GetConfigurationConfirmation;
- foreach (var config in cmd.configurationKey)
- {
- var item = client.configurationKey.Where(c => c.key == config.key).FirstOrDefault();
- item.value = config.value;
- }
- }
- //接收電樁對電樁槍號 availability 改變 回應
- if (confirmation is ChangeAvailabilityConfirmation)
- {
- ChangeAvailabilityConfirmation cmd = confirmation as ChangeAvailabilityConfirmation;
- }
- #endregion Core
- #region FirmwareManagement
- //接收電樁對取得 GetDiagnostics資訊回應
- if (confirmation is GetDiagnosticsConfirmation)
- {
- GetDiagnosticsConfirmation cmd = confirmation as GetDiagnosticsConfirmation;
- logger.Trace("Receive 電樁 {0} 上傳檔案 {1}", client.MachineCustomId, cmd.fileName);
- }
- //接收電樁對UpdateFirmware回應
- if (confirmation is UpdateFirmwareConfirmation)
- {
- UpdateFirmwareConfirmation cmd = confirmation as UpdateFirmwareConfirmation;
- }
- #endregion FirmwareManagement
- #region LocalAuthListManagement
- //接收電樁對 Get Local List Version 回應
- if (confirmation is GetLocalListVersionConfirmation)
- {
- GetLocalListVersionConfirmation cmd = confirmation as GetLocalListVersionConfirmation;
- string customId = client.MachineCustomId;
- var localauthTable = db.LocalAuthorization.Where(c => c.CustomId == customId).FirstOrDefault();
- if (localauthTable != null)
- {
- localauthTable.CurrentVersion = cmd.listVersion;
- localauthTable.UpdatedOn = DateTime.Now;
- db.SaveChanges();
- }
- }
- //接收電樁對 Send Local List 回應
- if (confirmation is SendLocalListConfirmation)
- {
- SendLocalListConfirmation cmd = confirmation as SendLocalListConfirmation;
- if (cmd.updateStatus == UpdateStatus.Accepted)
- {
- //下發GetLocalListVersion.req
- Cmd1011 cmd1011 = client.CmdHelper.Create(1011) as Cmd1011;
- cmd1011.CmdSerNum = client.GetCmdSerNum();
- cmd1011.SerNum = client.GetSerNum();
- cmd1011.Pack();
- ServerCommand sc = new ServerCommand();
- sc.OutCmdNum = cmd1011.Cmd;
- sc.CreatedOn = DateTime.Now;
- sc.MachineId = client.MachineId;
- sc.MachineCustomId = client.MachineCustomId;
- sc.OutTransData = cmd1011.byteList.ToArray();
- db.ServerCommand.Add(sc);
- db.SaveChanges();
- }
- }
- #endregion LocalAuthListManagement
- #region Reservation
- //接收電樁對 預約 回應
- if (confirmation is ReserveNowConfirmation)
- {
- ReserveNowConfirmation cmd = confirmation as ReserveNowConfirmation;
- }
- //接收電樁對 取消預約 回應
- if (confirmation is CancelReservationConfirmation)
- {
- CancelReservationConfirmation cmd = confirmation as CancelReservationConfirmation;
- }
- #endregion Reservation
- #region SmartCharging
- //接收電樁對 Charging Profile回應
- if (confirmation is SetChargingProfileConfirmation)
- {
- SetChargingProfileConfirmation cmd = confirmation as SetChargingProfileConfirmation;
- var uuid = Guid.Parse(uniqueId);
- var chargingProfile = db.ChargingProfile.Where(x => x.Id == uuid).FirstOrDefault();
- if (chargingProfile != null)
- {
- chargingProfile.UpdatedOn = DateTime.Now;
- chargingProfile.ResponseStatus = (int)cmd.status;
- db.SaveChanges();
- }
- logger.Trace("Receive 電樁 {0} Charging Profile回應 Status:{1} \n", client.MachineCustomId, cmd.status);
- }
- //接收電樁對清除Charging Profile回應
- if (confirmation is ClearChargingProfileConfirmation)
- {
- ClearChargingProfileConfirmation cmd = confirmation as ClearChargingProfileConfirmation;
- var uuid = Guid.Parse(uniqueId);
- var chargingProfile = db.ChargingProfile.Where(x => x.Id == uuid).FirstOrDefault();
- if (chargingProfile != null)
- {
- chargingProfile.UpdatedOn = DateTime.Now;
- chargingProfile.ResponseStatus = (int)cmd.status;
- db.SaveChanges();
- }
- logger.Trace("Receive 電樁 {0} 清除Charging Profile Status:{1} \n", client.MachineCustomId, cmd.status);
- }
- //接收電樁對Composite Charging Schedule 回應
- if (confirmation is GetCompositeScheduleConfirmation)
- {
- GetCompositeScheduleConfirmation cmd = confirmation as GetCompositeScheduleConfirmation;
- if (cmd.chargingSchedule != null)
- {
- logger.Trace("Receive 電樁 {0} Composite Charging Schedule connectorId:{1} Status:{2} ScheduleStart:{3} duration:{4} chargingRateUnit:{5} minChargingRate:{6}\n", client.MachineCustomId, cmd.connectorId, cmd.status, cmd.scheduleStart.ToLocalTime(), cmd.chargingSchedule.duration, cmd.chargingSchedule.chargingRateUnit, cmd.chargingSchedule.minChargingRate);
- foreach (var period in cmd.chargingSchedule.chargingSchedulePeriod)
- {
- logger.Trace("startPeriod:{0} limit:{1} numberPhases:{2}\n", period.startPeriod, period.limit, period.numberPhases);
- }
- }
- else
- logger.Trace("Receive 電樁 {0} Composite Charging Schedule connectorId:{1} Status:{2} ScheduleStart:{3} \n", client.MachineCustomId, cmd.connectorId, cmd.status, cmd.scheduleStart.ToLocalTime());
- }
- #endregion SmartCharging
- #region DataTransfer
- //處理自訂的訊息
- if (confirmation is DataTransferConfirmation)
- {
- DataTransferConfirmation cmd = confirmation as DataTransferConfirmation;
-
- if (cmd.data != null)
- {
-
- if (callResultAction.Contains("SetChargingConfig"))
- {
-
- var uuid = Guid.Parse(uniqueId);
- var chargingProfile = db.ChargingProfile.Where(x => x.Id == uuid).FirstOrDefault();
- if (chargingProfile != null)
- {
- chargingProfile.UpdatedOn = DateTime.Now;
- chargingProfile.ResponseStatus = (int)cmd.status;
- db.SaveChanges();
- }
-
- }
- else if (callResultAction.Contains("GetChargingConfig"))
- {
-
- var uuid = Guid.Parse(uniqueId);
- var chargingProfile = db.ChargingProfile.Where(x => x.Id == uuid).FirstOrDefault();
- if (chargingProfile != null)
- {
- var charingRate = JsonConvert.DeserializeObject<ChargingRate>(cmd.data);
- chargingProfile.UpdatedOn = DateTime.Now;
- chargingProfile.ResponseStatus = (int)cmd.status;
- chargingProfile.EasyConfig = String.Format("{0}:{1}", charingRate.chargingRateUnit, charingRate.limit);
- db.SaveChanges();
- }
-
- }
- else if (cmd.data[0] == '{')
- {
-
- JObject restoredObject = JObject.Parse(cmd.data);
- FirmwareMD5 fwmd5 = new FirmwareMD5();
-
- if (cmd.data.Contains("md5") == true)
- {
- // Copy to a static fwmd5 instance
- fwmd5 = restoredObject.ToObject<FirmwareMD5>();
- //充電樁對服務器下發升級指令的應答
- //處理 UpdateFirmware conf
- fwmd5.md5 = fwmd5.md5.ToUpper();
- string machineId = client.MachineId;
- var mvFile = _mvfRepo.Query(c => c.MachineVersion.MachineId.Equals(machineId) && c.UploadFile.FileMD5.ToUpper().Equals(fwmd5.md5)).Select(c => c).OrderByDescending(c => c.CreatedOn).FirstOrDefault();
- if (mvFile != null)
- {
- mvFile.DownloadedOn = DateTime.Now;
- uowconf.SaveChanges();
- result.Success = true;
- }
- else
- {
- throw new ApplicationException("找不到相關檔案");
- }
- }
- }
- else
- {
- if (cmd.data == "true") //成功
- {
- logger.Trace("Receive 電樁 {0} 處理電費/服務費 結果 {1}", client.MachineCustomId, cmd.data);
- }
- else if (cmd.data == "false") //失敗
- {
- logger.Trace("Receive 電樁 {0} 處理電費/服務費 結果 {1}", client.MachineCustomId, cmd.data);
- }
- }
- }
- }
- #endregion DataTransfer
- result.Success = true;
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- result.Exception = ex;
- result.Success = false;
- }
- return result;
- }
- //處理電樁所送的Error Message
- public OCPPResult HandleError(string uniqueId, string errorCode, string errorDescription, object payload)
- {
- OCPPResult result = new OCPPResult();
- return result;
- }
- /// <summary>
- /// 處理WSServer 產生DataTransfer的ServerDomainName命令
- /// </summary>
- /// <param name="queue">Message Queue</param>
- /// <param name="ServerDomainName">ServerDomainName</param>
- /// <returns></returns>
- public string HandleServerDomainName(ref Queue queue, string ServerDomainName)
- {
- IRequest req = makeRequest.MakeServerDomainNameRequest(ServerDomainName);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- return GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- /// <summary>
- /// 處理WSServer 產生DataTransfer的UpdateFirmware命令
- /// </summary>
- /// <param name="queue">Message Queue</param>
- /// <param name="type">Messgae Type</param>
- /// <param name="param">ProgramParam Type</param>
- /// <param name="uploadFile">UploadFile</param>
- /// <returns></returns>
- public string HandleUpdateFirmware(ref Queue queue, int type, ProgramParam param, UploadFile uploadFile)
- {
- IRequest req = makeRequest.MakeUpdateFirmware(type, param, uploadFile);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- return GenerateCall(uuid, Actions.DataTransfer.ToString(), req);
- }
- /// <summary>
- /// 處理WSServer 產生OCPP協議的UpdateFirmware命令
- /// </summary>
- /// <param name="queue">Message Queue</param>
- /// <param name="fileurl">FileURL</param>
- /// <returns></returns>
- public string HandleOCPPUpdateFirmware(ref Queue queue, string fileurl)
- {
- IRequest req = MakeRequestHandler.MakeOCPPUpdateFirmwareRequest(fileurl);
- string uuid = String.Empty;
- lock (_clientQueue)
- {
- uuid = queue.store(req);
- }
- return GenerateCall(uuid, Actions.UpdateFirmware.ToString(), req);
- }
- /// <summary>
- /// 將後台要傳給電樁的request轉換成Call Message
- /// </summary>
- /// <param name="uniqueId">OCPP Call Message uniqueId</param>
- /// <param name="action">OCPP Call Message action</param>
- /// <param name="request">Request Message</param>
- /// <returns></returns>
- public string GenerateCall(string uniqueId, string action, object request)
- {
- try
- {
- return MakeCall(uniqueId, action, PackPayload(request));
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- throw new ApplicationException(ex.ToString());
- }
- }
- /// <summary>
- /// 將後台要傳給電樁的comfirm轉換成CallResult Message
- /// </summary>
- /// <param name="uniqueId">OCPP Call Message uniqueId</param>
- /// <param name="confirmation">Confirmation Message</param>
- /// <returns></returns>
- public string GenerateCallResult(string uniqueId, object confirmation)
- {
- try
- {
- return MakeCallResult(uniqueId, PackPayload(confirmation));
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- throw new ApplicationException(ex.ToString());
- }
- }
- /// <summary>
- /// 將後台要傳給電樁的錯誤訊息轉換成CallError Message
- /// </summary>
- /// <param name="uniqueId">OCPP CallError Message uniqueId</param>
- /// <param name="errorCode">OCPP CallError Message errorCode</param>
- /// <param name="errorDescription">OCPP CallError Message errorDescription</param>
- /// <returns></returns>
- public string GenerateCallError(string uniqueId, string errorCode, string errorDescription)
- {
- try
- {
- return MakeCallError(uniqueId, errorCode, errorDescription);
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- throw new ApplicationException(ex.ToString());
- }
- }
- /// <summary>
- /// 產生CallResult Message
- /// </summary>
- /// <param name="uniqueId">OCPP CallResult Message uniqueId</param>
- /// <param name="payload">OCPP CallResult Message payload</param>
- /// <returns></returns>
- private string MakeCallResult(string uniqueId, object payload)
- {
- const string CALLRESULT_FORMAT = "[3,\"{0}\",{1}]";
- return string.Format(CALLRESULT_FORMAT, uniqueId, payload.ToString());
- }
- /// <summary>
- /// 產生Call Message
- /// </summary>
- /// <param name="uniqueId">OCPP CallResult Message uniqueId</param>
- /// <param name="action">OCPP CallResult Message action</param>
- /// <param name="payload">OCPP CallResult Message payload</param>
- /// <returns></returns>
- private string MakeCall(string uniqueId, string action, object payload)
- {
- const string CALL_FORMAT = "[2,\"{0}\",\"{1}\",{2}]";
- return string.Format(CALL_FORMAT, uniqueId, action, payload.ToString());
- }
- /// <summary>
- /// 產生CallError Message
- /// </summary>
- /// <param name="uniqueId">OCPP CallError Message uniqueId</param>
- /// <param name="errorCode">OCPP CallError Message errorCode</param>
- /// <param name="errorDescription">OCPP CallError Message errorDescription</param>
- /// <returns></returns>
- private string MakeCallError(string uniqueId, string errorCode, string errorDescription)
- {
- const string CALLERROR_FORMAT = "[4,\"{0}\",\"{1}\",\"{2}\",{3}]";
- return string.Format(CALLERROR_FORMAT, uniqueId, errorCode, errorDescription, "{}");
- }
- /// <summary>
- /// 處理OCPP CallResult Message
- /// </summary>
- /// <param name="id">OCPP CallResult Message uniqueId</param>
- /// <param name="payload">OCPP CallResult Message payload</param>
- /// <param name="queue">OCPP CallResult Message queue</param>
- /// <param name="messageType">OCPP CallResult Message messageType</param>
- /// <returns></returns>
- public OCPPResult OnCallResult(string id, object payload, ref Queue queue, out string messageType)
- {
- OCPPResult result = new OCPPResult();
- try
- {
- IRequest request;
- Type actionType = GetConfirmationType(ref queue, id, out request);
- if (request == null)
- {
- messageType = "There are two conditions. Maybe it was sent repeatedly or there is no related Request. ";
- result.Message = "none";
- result.Success = false;
- }
- else
- {
- IConfirmation confirmation = (IConfirmation)UnpackPayload(payload, actionType);
- if (actionType.Name.Contains("DataTransferConfirmation"))
- {
- messageType = "DataTransfer Confirmation(" + ((DataTransferRequest)request).messageId + ")";
- }
- else if (actionType.Name.Contains("TriggerMessageConfirmation"))
- {
- messageType = "TriggerMessage Confirmation(" + ((TriggerMessageRequest)request).requestedMessage.ToString() + ")";
- }
- else
- {
- messageType = actionType.Name.Remove(actionType.Name.IndexOf("Confirmation")) + " Confirmation";
- }
- if (confirmation.Validate())
- {
- result.Payload = confirmation;
- result.Success = true;
- }
- else
- {
- result.Message = GenerateCallError(id, "OccurenceConstraintViolation", "Payload for Action is syntactically correct but at least one of the fields violates occurence constraints");
- result.Success = false;
- }
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- result.Exception = ex;
- messageType = string.Empty;
- result.Success = false;
- }
- return result;
- }
- /// <summary>
- /// 處理OCPP CALL Message
- /// </summary>
- /// <param name="id">OCPP CALL Message uniqueId</param>
- /// <param name="action">OCPP CALL Message action</param>
- /// <param name="payload">OCPP CALL Message payload</param>
- /// <returns></returns>
- public OCPPResult OnCall(string id, string action, object payload)
- {
- OCPPResult result = new OCPPResult();
- Feature feature = featureHandler.FindFeatureByAction(action);
- if (feature == null)
- {
- result.Message = GenerateCallError(id, "NotImplemented", "Requested Action is not known by receiver");
- result.Success = false;
- }
- else
- {
- try
- {
- IRequest request = (IRequest)UnpackPayload(payload, feature.GetRequestType());
- if (request.Validate())
- {
- result.Payload = request;
- result.Success = true;
- }
- else
- {
- result.Message = GenerateCallError(id, "OccurenceConstraintViolation", "Payload for Action is syntactically correct but at least one of the fields violates occurence constraints");
- result.Success = false;
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- result.Exception = ex;
- result.Success = false;
- }
- }
- return result;
- }
- /// <summary>
- /// 處理OCPP Error Message
- /// </summary>
- /// <param name="id">OCPP Error Message uniqueId</param>
- /// <param name="errorCode">OCPP Error Message errorCode</param>
- /// <param name="errorDescription">OCPP Error Message errorDescription</param>
- /// <param name="payload">OCPP Error Message payload</param>
- /// <returns></returns>
- public OCPPResult OnError(string id, string errorCode, string errorDescription, object payload)
- {
- OCPPResult result = new OCPPResult();
- result.Success = true;
- return result;
- }
- }
- }
|