using EVCB_OCPP.Domain; using EVCB_OCPP.Packet.Features; using EVCB_OCPP.Packet.Messages; using EVCB_OCPP.Packet.Messages.FirmwareManagement; using Newtonsoft.Json; using System; using System.Linq; using Microsoft.Extensions.Logging; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using EVCB_OCPP.Domain.Models.MainDb; using EVCB_OCPP.WSServer.Service.WsService; namespace EVCB_OCPP.WSServer.Message { public partial class ProfileHandler { internal async Task ExecuteFirmwareManagementRequest(Actions action, WsClientData session, IRequest request) { MessageResult result = new MessageResult() { Success = false }; try { switch (action) { case Actions.FirmwareStatusNotification: { FirmwareStatusNotificationRequest _request = request as FirmwareStatusNotificationRequest; if (_request.status == Packet.Messages.SubTypes.FirmwareStatus.Idle) { string requestId = Guid.NewGuid().ToString(); using (var db = await maindbContextFactory.CreateDbContextAsync()) { var machine = await db.Machines.Where(x => x.FwAssignedVersion.HasValue == true && x.FwAssignedVersion.HasValue && x.FwAssignedVersion != x.FwVersionReport && x.ChargeBoxId == session.ChargeBoxId) .Select(x => new { x.Id, x.FwAssignedVersion }).AsNoTracking().FirstOrDefaultAsync(); if (machine != null) { var mv = db.MachineVersionFiles.Include(c => c.UploadFile) .Where(c => c.Id == machine.FwAssignedVersion.Value).First(); string downloadUrl = mv.UploadFile.FileUrl; var _updateFWrequest = new UpdateFirmwareRequest() { location = new Uri(downloadUrl), retries = 3, retrieveDate = DateTime.UtcNow, retryInterval = 10 }; await db.MachineOperateRecords.AddAsync(new MachineOperateRecord() { CreatedOn = DateTime.UtcNow, ChargeBoxId = session.ChargeBoxId, SerialNo = requestId, RequestContent = JsonConvert.SerializeObject(_updateFWrequest, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }), EvseStatus = 0, EvseValue = "Fw Version:" + machine.FwAssignedVersion, Status = 0, RequestType = 0, Action = _updateFWrequest.Action.ToString() }); await db.SaveChangesAsync(); await mainDbService.AddServerMessage( ChargeBoxId: session.ChargeBoxId, OutAction: _updateFWrequest.Action.ToString(), OutRequest: _updateFWrequest, SerialNo: requestId); var clearMachine = await db.Machines.Where(x => x.Id == machine.Id).FirstOrDefaultAsync(); clearMachine.FwAssignedVersion = null; await db.SaveChangesAsync(); } } } else { using (var db = await maindbContextFactory.CreateDbContextAsync()) { var item = await db.MachineOperateRecords.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.RequestType == 0) .OrderByDescending(x => x.CreatedOn).FirstOrDefaultAsync(); if (item != null) { item.EvseStatus = (int)_request.status; item.FinishedOn = DateTime.UtcNow; //if (!string.IsNullOrEmpty(item.EvseValue) && _request.status == Packet.Messages.SubTypes.FirmwareStatus.Installed) //{ // int version = 0; // int.TryParse(item.EvseValue.Split(':').Last(), out version); // var machine = await db.Machine.Where(x => x.ChargeBoxId == session.ChargeBoxId).FirstOrDefaultAsync(); // machine.FW_VersionReport = version; //} } await db.SaveChangesAsync(); } } var confirm = new FirmwareStatusNotificationConfirmation() { }; result.Message = confirm; result.Success = true; } break; case Actions.DiagnosticsStatusNotification: { DiagnosticsStatusNotificationRequest _request = request as DiagnosticsStatusNotificationRequest; if (_request.status != Packet.Messages.SubTypes.DiagnosticsStatus.Idle) { using (var db = new MainDBContext()) { var item = await db.MachineOperateRecords.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.Action == "GetDiagnostics" && x.RequestType == 1) .OrderByDescending(x => x.CreatedOn).FirstOrDefaultAsync(); if (item != null) { item.EvseStatus = (int)_request.status; item.FinishedOn = DateTime.UtcNow; } await db.SaveChangesAsync(); } } var confirm = new DiagnosticsStatusNotificationConfirmation() { }; result.Message = confirm; result.Success = true; } break; default: { logger.LogWarning(string.Format("Not Implement {0} Logic", request.GetType().ToString().Replace("OCPPPackage.Messages.FirmwareManagement.", ""))); } break; } } catch (Exception ex) { logger.LogCritical("chargeBoxId:{0} {1}", session.ChargeBoxId, action); logger.LogCritical("Data {0}", request.ToString()); logger.LogCritical("Error {0}", ex.ToString()); result.Exception = ex; } return result; } internal async Task ExecuteFirmwareManagementConfirm(Actions action, WsClientData session, IConfirmation confirm, string requestId) { MessageResult result = new MessageResult() { Success = true }; switch (action) { case Actions.UpdateFirmware: case Actions.GetDiagnostics: { string evse_rep = string.Empty; if (confirm is GetDiagnosticsConfirmation) { var confirmation = confirm as GetDiagnosticsConfirmation; evse_rep = confirmation.fileName; } using (var db = await maindbContextFactory.CreateDbContextAsync()) { var operation = await db.MachineOperateRecords .Where(x => x.SerialNo == requestId && x.ChargeBoxId == session.ChargeBoxId && x.Status == 0) .FirstOrDefaultAsync(); if (operation != null) { operation.FinishedOn = DateTime.UtcNow; operation.Status = 1;//電樁有回覆 operation.EvseStatus = (int)1;//OK operation.EvseValue = string.IsNullOrEmpty(evse_rep) ? operation.EvseValue : evse_rep; await db.SaveChangesAsync(); } } } break; default: { logger.LogWarning(string.Format("Not Implement {0} Logic", confirm.GetType().ToString().Replace("OCPPPackage.Messages.FirmwareManagement.", ""))); } break; } return result; } internal async Task ReceivedFirmwareManagementError(Actions action, string errorMsg, WsClientData session, string requestId) { MessageResult result = new MessageResult() { Success = true }; switch (action) { case Actions.FirmwareStatusNotification: case Actions.UpdateFirmware: case Actions.GetDiagnostics: case Actions.DiagnosticsStatusNotification: { using (var db = await maindbContextFactory.CreateDbContextAsync()) { var operation = await db.MachineOperateRecords .Where(x => x.SerialNo == requestId && x.ChargeBoxId == session.ChargeBoxId && x.Status == 0) .FirstOrDefaultAsync(); if (operation != null) { operation.FinishedOn = DateTime.UtcNow; operation.Status = 1;//電樁有回覆 operation.EvseStatus = (int)255;//錯誤 operation.EvseValue = errorMsg; await db.SaveChangesAsync(); } } } break; default: { logger.LogWarning(string.Format("Not Implement {0} Logic", action)); } break; } return result; } } }