From 40ba5c7bba99561845bd1b7ee9d22be06a4b58cd Mon Sep 17 00:00:00 2001 From: Yinyin Liu Date: Thu, 11 Jul 2024 13:56:13 +0200 Subject: [PATCH] backend for download battery log button --- csharp/App/Backend/Controller.cs | 158 ++++++++++++++++++ .../App/Backend/DataTypes/Methods/Session.cs | 27 +++ 2 files changed, 185 insertions(+) diff --git a/csharp/App/Backend/Controller.cs b/csharp/App/Backend/Controller.cs index fa8113e7b..12887d12e 100644 --- a/csharp/App/Backend/Controller.cs +++ b/csharp/App/Backend/Controller.cs @@ -11,6 +11,14 @@ namespace InnovEnergy.App.Backend; using Token = String; +// create JobStatus class to track download battery log job +public class JobStatus +{ + public string JobId { get; set; } + public string Status { get; set; } + public string FileName { get; set; } + public DateTime StartTime { get; set; } +} [Controller] [Route("api/")] @@ -631,6 +639,156 @@ public class Controller : ControllerBase return Ok(); } + private static Dictionary JobStatuses = new Dictionary(); + + [HttpPost("StartDownloadBatteryLog")] + public async Task> StartDownloadBatteryLog(long batteryNode, long installationId, Token authToken) + { + var session = Db.GetSession(authToken); + var installationToDownload = Db.GetInstallationById(installationId); + + if (installationToDownload != null) + { + string jobId = Guid.NewGuid().ToString(); + _ = Task.Run(async () => + { + await session.RunDownloadLogScript(installationToDownload.VpnIp, batteryNode, installationToDownload.Product); + string fileName = $"{installationToDownload.VpnIp}-node{batteryNode}-{DateTime.Now:dd-MM-yyyy}.bin"; + string filePath = $"/home/ubuntu/backend/downloadBatteryLog/{fileName}"; + + if (System.IO.File.Exists(filePath)) + { + SaveJobStatus(jobId, "Completed", fileName:fileName); + } + else + { + SaveJobStatus(jobId, "Failed"); + } + }); + + // Store initial job status in in-memory storage + SaveJobStatus(jobId, "Processing"); + + return Ok(jobId); + } + + return NotFound(); + } + + [HttpGet("DownloadBatteryLog")] + public async Task DownloadBatteryLog(string jobId) + + { + Console.WriteLine("-----------------------------------Start uploading battery log-----------------------------------"); + var jobStatus = JobStatuses.TryGetValue(jobId, out var status) ? status : null; + if (jobStatus == null || jobStatus.Status != "Completed" || string.IsNullOrEmpty(jobStatus.FileName)) + { + return NotFound(); + } + + string fileName = jobStatus.FileName; + string filePath = $"/home/ubuntu/backend/downloadBatteryLog/{fileName}"; + + if (!System.IO.File.Exists(filePath)) + { + return NotFound(); + } + + string contentType = "application/octet-stream"; + var memory = new MemoryStream(); + await using (var stream = new FileStream(filePath, FileMode.Open)) + { + await stream.CopyToAsync(memory); + } + memory.Position = 0; + + var fileContentResult = new FileContentResult(memory.ToArray(), contentType) + { + //FileDownloadName = Path.GetFileName(filePath) + FileDownloadName = fileName + }; + + Console.WriteLine("-----------------------------------Stop uploading battery log-----------------------------------"); + + return fileContentResult; + } + + [HttpDelete("DeleteBatteryLog")] + public IActionResult DeleteBatteryLog(string fileName) + { + Console.WriteLine("-----------------------------------Start deleting downloaded battery log-----------------------------------"); + string filePath = $"/home/ubuntu/backend/downloadBatteryLog/{fileName}"; + try + { + if (System.IO.File.Exists(filePath)) + { + System.IO.File.Delete(filePath); + Console.WriteLine("-----------------------------------Stop deleting downloaded battery log-----------------------------------"); + return Ok(); + } + else + { + return NotFound("File not found."); + } + } + catch (Exception ex) + { + return StatusCode(500, $"Internal server error: {ex.Message}"); + } + } + + private void SaveJobStatus(string jobId, string status, string fileName = null) + { + JobStatuses[jobId] = new JobStatus + { + JobId = jobId, + Status = status, + FileName = fileName, + StartTime = DateTime.UtcNow // Initialize StartTime when saving + }; + } + + [HttpGet("GetJobResult")] + public ActionResult GetJobResult(string jobId) + { + if (string.IsNullOrEmpty(jobId)) + { + return BadRequest(new { status = "Error", message = "Job ID is required." }); + } + + if (!JobStatuses.TryGetValue(jobId, out var jobStatus)) + { + return NotFound(); + } + + if (jobStatus.Status == "Completed") + { + return Ok(new { status = "Completed", fileName = jobStatus.FileName }); + } + else if (jobStatus.Status == "Failed") + { + return StatusCode(500, new { status = "Failed", message = "Job processing failed." }); + } + else if (jobStatus.Status == "Processing") + { + // Check for timeout + var startTime = jobStatus.StartTime; + var currentTime = DateTime.UtcNow; + + if ((currentTime - startTime).TotalMinutes > 60)//60 minutes as timeout => Running multiple tasks in parallel on a crowded backend server will increase the time each task takes to complete + { + return StatusCode(500, new { status = "Failed", message = "Job in back end timeout exceeded." }); + } + + return Ok(new { status = "Processing" }); + } + else + { + return BadRequest(new { status = "Unknown", message = "Unknown job status." }); + } + } + + [HttpPost(nameof(InsertNewAction))] public async Task>> InsertNewAction([FromBody] UserAction action, Token authToken) { diff --git a/csharp/App/Backend/DataTypes/Methods/Session.cs b/csharp/App/Backend/DataTypes/Methods/Session.cs index cba4852cc..930547eda 100644 --- a/csharp/App/Backend/DataTypes/Methods/Session.cs +++ b/csharp/App/Backend/DataTypes/Methods/Session.cs @@ -91,6 +91,33 @@ public static class SessionMethods Console.WriteLine("-----------------------------------Stop updating firmware-----------------------------------"); } + public static async Task RunDownloadLogScript(this Session? session, String vpnIp, Int64 batteryNode,Int64 product) + { + Console.WriteLine("-----------------------------------Start downloading battery log-----------------------------------"); + string scriptPath = (product == 0) + ? "/home/ubuntu/backend/downloadBatteryLog/download_bms_log_Salimax.sh" + : "/home/ubuntu/backend/downloadBatteryLog/download_bms_log_Salidomo.sh"; + + await Task.Run(() => + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "/bin/bash", + Arguments = $"{scriptPath} {vpnIp} {batteryNode}", + UseShellExecute = false, + RedirectStandardOutput = true + } + }; + + process.Start(); + var output = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + Console.WriteLine(output); + }); + Console.WriteLine("-----------------------------------Stop downloading battery log-----------------------------------"); + } public static async Task SendInstallationConfig(this Session? session, Int64 installationId, Configuration configuration) {