Compare commits

..

2 Commits

2 changed files with 185 additions and 0 deletions

View File

@ -11,6 +11,14 @@ namespace InnovEnergy.App.Backend;
using Token = String; 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] [Controller]
[Route("api/")] [Route("api/")]
@ -631,6 +639,156 @@ public class Controller : ControllerBase
return Ok(); return Ok();
} }
private static Dictionary<string, JobStatus> JobStatuses = new Dictionary<string, JobStatus>();
[HttpPost("StartDownloadBatteryLog")]
public async Task<ActionResult<string>> 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<ActionResult> 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))] [HttpPost(nameof(InsertNewAction))]
public async Task<ActionResult<IEnumerable<Object>>> InsertNewAction([FromBody] UserAction action, Token authToken) public async Task<ActionResult<IEnumerable<Object>>> InsertNewAction([FromBody] UserAction action, Token authToken)
{ {

View File

@ -91,6 +91,33 @@ public static class SessionMethods
Console.WriteLine("-----------------------------------Stop updating firmware-----------------------------------"); 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<Boolean> SendInstallationConfig(this Session? session, Int64 installationId, Configuration configuration) public static async Task<Boolean> SendInstallationConfig(this Session? session, Int64 installationId, Configuration configuration)
{ {