multiple fixes

This commit is contained in:
Kim 2023-08-23 11:31:30 +02:00
parent b4174d09bf
commit 5e320941bd
12 changed files with 78 additions and 38 deletions

View File

@ -254,7 +254,7 @@ public class Controller : ControllerBase
[HttpPost(nameof(CreateUser))] [HttpPost(nameof(CreateUser))]
public ActionResult<User> CreateUser(User newUser, Token authToken) public ActionResult<User> CreateUser(User newUser, Token authToken)
{ {
return Db.GetSession(authToken).Create(newUser) return Db.GetSession(authToken).Create(newUser)
? newUser.HidePassword() ? newUser.HidePassword()
: Unauthorized() ; : Unauthorized() ;
} }

View File

@ -58,6 +58,7 @@ public static class ExoCmd
{ {
await Exo await Exo
.WithArguments("iam access-key revoke " + installation.S3Key + " -f " + " -C " + ConfigFile) .WithArguments("iam access-key revoke " + installation.S3Key + " -f " + " -C " + ConfigFile)
.WithValidation(CommandResultValidation.None)
.ExecuteAsync(); .ExecuteAsync();
} }
catch catch

View File

@ -7,7 +7,7 @@ namespace InnovEnergy.App.Backend.DataTypes.Methods;
public static class InstallationMethods public static class InstallationMethods
{ {
private const String BucketNameSalt = "3e5b3069-214a-43ee-8d85-57d72000c10d"; private const String BucketNameSalt = "3e5b3069-214a-43ee-8d85-57d72000c19d";
public static String BucketName(this Installation installation) public static String BucketName(this Installation installation)
{ {

View File

@ -86,12 +86,14 @@ public static class SessionMethods
return user is not null return user is not null
&& installation is not null && installation is not null
&& user.HasWriteAccess && user.HasWriteAccess
&& user.HasAccessTo(installation.Parent()) && user.HasAccessToParentOf(installation)
&& Db.Create(installation) // TODO: these two in a transaction && Db.Create(installation) // TODO: these two in a transaction
&& Db.Create(new InstallationAccess { UserId = user.Id, InstallationId = installation.Id }) && Db.Create(new InstallationAccess { UserId = user.Id, InstallationId = installation.Id })
&& await installation.CreateBucket() && await installation.CreateBucket()
&& await installation.RenewS3Credentials(); // generation of access _after_ generation of && await installation.RenewS3Credentials(); // generation of access _after_ generation of
// bucket to prevent "zombie" access-rights. // bucket to prevent "zombie" access-rights.
// This might fuck us over if the creation of access rights fails,
// as bucket-names are unique and bound to the installation id... -K
} }
public static Boolean Update(this Session? session, Installation? installation) public static Boolean Update(this Session? session, Installation? installation)
@ -155,10 +157,12 @@ public static class SessionMethods
&& sessionUser.HasWriteAccess && sessionUser.HasWriteAccess
&& newUser && newUser
.WithParent(sessionUser) .WithParent(sessionUser)
.Do(() => newUser.Password = newUser.SaltAndHashPassword(newUser.Password))
.Do(() => newUser.MustResetPassword = true) .Do(() => newUser.MustResetPassword = true)
.Apply(Db.Create) .Do(() => newUser.Password = newUser.SaltAndHashPassword(newUser.Password))
&& Mailer.Mailer.SendVerificationMessage(newUser); .Apply(Db.Create);
// && Mailer.Mailer.SendVerificationMessage(newUser);
// .Do(() => newUser.Password = newUser.SaltAndHashPassword(newUser.Password))
//Send Email to new user to verify email and set password //Send Email to new user to verify email and set password

View File

@ -0,0 +1,10 @@
defaultaccount = "Kim"
[[accounts]]
account = "innovenergy-ag"
defaultZone = "ch-dk-2"
endpoint = "https://api.exoscale.com/v1"
environment = ""
key = "EXOf67c5b528282988503ddab12"
name = "Kim"
secret = "KBFh5HvoSQcTtGYcWSm4Qn4m-WFutKe89UqsOdOL-ts"

View File

@ -24,7 +24,7 @@ public static partial class Db
{ {
var latestDb = new DirectoryInfo(@"DbBackups").GetFiles() var latestDb = new DirectoryInfo(@"DbBackups").GetFiles()
.OrderBy(f => f.LastWriteTime) .OrderBy(f => f.LastWriteTime)
.First().Name; .Last().Name;
var fileConnection = new SQLiteConnection("DbBackups/"+latestDb); var fileConnection = new SQLiteConnection("DbBackups/"+latestDb);
@ -129,7 +129,7 @@ public static partial class Db
Connection.CreateTable<OrderNumber2Installation>(); Connection.CreateTable<OrderNumber2Installation>();
}); });
Observable.Interval(TimeSpan.FromDays(0.5)) Observable.Interval(TimeSpan.FromHours(0.5))
.StartWith(0) // Do it right away (on startup) .StartWith(0) // Do it right away (on startup)
.ObserveOn(TaskPoolScheduler.Default) .ObserveOn(TaskPoolScheduler.Default)
.SubscribeOn(TaskPoolScheduler.Default) .SubscribeOn(TaskPoolScheduler.Default)
@ -182,8 +182,7 @@ public static partial class Db
var installationsToUpdate = Installations var installationsToUpdate = Installations
.Select(i => i) .Select(i => i)
.Where(i => bucketList.StandardOutput.Contains("\"" + i.BucketName())).ToList() .Where(i => bucketList.StandardOutput.Contains("\"" + i.BucketName() + "\"")).ToList();
;
foreach (var installation in installationsToUpdate) foreach (var installation in installationsToUpdate)
{ {

View File

@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using CliWrap; using CliWrap;
using CliWrap.Buffered; using CliWrap.Buffered;
using InnovEnergy.Lib.Utils; using InnovEnergy.Lib.Utils;
@ -14,7 +15,8 @@ public class S3Cmd
private const String S3Prefix = "s3://"; private const String S3Prefix = "s3://";
public String Key { get; init;} public String Key { get; init;}
public String Secret { get; init;} public String Secret { get; init;}
public String Region { get; init; } = "sos-ch-dk-2.exo.io";
// private String?[] DefaultArgs { get; } // private String?[] DefaultArgs { get; }
@ -79,6 +81,7 @@ public class S3Cmd
S3CmdPath, S3CmdPath,
"--access_key", Key, "--access_key", Key,
"--secret_key", Secret, "--secret_key", Secret,
"--host", Region
}; };
var args = credentials var args = credentials

View File

@ -21,9 +21,10 @@ public record InstallationToHtmlInterface(
String LastSeen, String LastSeen,
String NumBatteries, String NumBatteries,
String BatteryVersion, String BatteryVersion,
String BatteryUpdateStatus,
String ServerIp = "10.2.0.1", //TODO MAKE ME DYNAMIC String ServerIp = "10.2.0.1", //TODO MAKE ME DYNAMIC
String FirmwareVersion = "AF09" //Todo automatically grab newest version? String FirmwareVersion = "AF09" //Todo automatically grab newest version?
); );
[Controller] [Controller]
public class Controller : ControllerBase public class Controller : ControllerBase
@ -95,7 +96,7 @@ th { /* header cell */
<table> <table>
<tbody> <tbody>
<tr> <tr>
<th>Name</th> <th>Name This site is updated once per day!</th>
<th>Gui</th> <th>Gui</th>
<th>VRM</th> <th>VRM</th>
<th>Grafana</th> <th>Grafana</th>
@ -105,6 +106,7 @@ th { /* header cell */
<th>#Batteries</th> <th>#Batteries</th>
<th>Firmware-Version</th> <th>Firmware-Version</th>
<th>Update</th> <th>Update</th>
<th>Last Update Status</th>
</tr> </tr>
{{#inst}} {{#inst}}
{{> installations}} {{> installations}}
@ -124,7 +126,8 @@ th { /* header cell */
<td>{{Serial}}</td> <td>{{Serial}}</td>
<td>{{NumBatteries}}</td> <td>{{NumBatteries}}</td>
<td>{{BatteryVersion}}</td> <td>{{BatteryVersion}}</td>
<td><a target='_blank' href=https://{{ServerIp}}/UpdateBatteryFirmware/{{Ip}}/{{NumBatteries}}>⬆️{{FirmwareVersion}}</a></td> <td><a target='_blank' href=http://{{ServerIp}}/UpdateBatteryFirmware/{{Ip}}/{{NumBatteries}}>⬆️{{FirmwareVersion}}</a></td>
<td>{{BatteryUpdateStatus}}</td>
</tr>"; </tr>";
var installationsInDb = Db.Installations.OrderBy(i => i.Name, StringComparer.OrdinalIgnoreCase).ToList(); var installationsInDb = Db.Installations.OrderBy(i => i.Name, StringComparer.OrdinalIgnoreCase).ToList();
@ -146,7 +149,8 @@ th { /* header cell */
i.Online, i.Online,
DateTimeOffset.FromUnixTimeSeconds(Convert.ToInt64(i.LastSeen)).ToString(), DateTimeOffset.FromUnixTimeSeconds(Convert.ToInt64(i.LastSeen)).ToString(),
i.NumberOfBatteries, i.NumberOfBatteries,
i.BatteryFirmwareVersion)); i.BatteryFirmwareVersion,
i.BatteryUpdateStatus));
var data = new var data = new
{ {
@ -179,21 +183,36 @@ th { /* header cell */
} }
if (split[1] == "Failed" || split2[0] == "Error") return "Update failed"; if (split[1] == "Failed" || split2[0] == "Error") return "Update failed";
await UpdateVrmTagsToNewFirmware(installationIp);
SendNewBatteryFirmware(installationIp); await SendNewBatteryFirmware(installationIp);
var batteryTtyName = split[1].Split(".").Last();
for (var batteryId = 2; batteryId <= Int64.Parse(numberOfBatteries) + 1; batteryId++) var localCommand = $"/opt/innovenergy/scripts/upload-bms-firmware {batteryTtyName} 2 /opt/innovenergy/{FirmwareVersion}.bin";
var installation = Db.Installations.First(installation => installation.Ip == installationIp);
installation.BatteryUpdateStatus = "Running";
Db.Update(installation: installation);
for (var batteryId = 3; batteryId < Int64.Parse(numberOfBatteries) + 2; batteryId++)
{ {
var batteryTtyName = split[1].Split(".").Last(); localCommand = localCommand.Append(
var localCommand = $"/opt/innovenergy/scripts/upload-bms-firmware {batteryTtyName} {batteryId} /opt/innovenergy/bms-firmware/{FirmwareVersion}.bin"; $" && /opt/innovenergy/scripts/upload-bms-firmware {batteryTtyName} {batteryId} /opt/innovenergy/{FirmwareVersion}.bin");
#pragma warning disable CS4014
Db.ExecuteBufferedAsyncCommandOnIp(installationIp, localCommand);
#pragma warning restore CS4014
// Console.WriteLine(remoteUpdateCommandResult);
} }
#pragma warning disable CS4014
Db.ExecuteBufferedAsyncCommandOnIp(installationIp, localCommand)
.ContinueWith(t =>
{
if (t.Status == TaskStatus.RanToCompletion)
{
installation.BatteryUpdateStatus = "Complete";
Db.Update(installation: installation);
UpdateVrmTagsToNewFirmware(installationIp);
}
else
{
installation.BatteryUpdateStatus = "Failed";
Db.Update(installation: installation);
}
});
#pragma warning restore CS4014
return "Battery update is successfully initiated, it will take around 15 minutes to complete! You can close this page now."; return "Battery update is successfully initiated, it will take around 15 minutes to complete! You can close this page now.";
} }
@ -217,12 +236,12 @@ th { /* header cell */
return await vrmAccount.GetInstallation(installationId!); return await vrmAccount.GetInstallation(installationId!);
} }
private static void SendNewBatteryFirmware(String installationIp) private static async Task SendNewBatteryFirmware(String installationIp)
{ {
Cli.Wrap("scp") await Cli.Wrap("scp")
.WithArguments($@"{FirmwareVersion}.bin") .WithArguments($@"{FirmwareVersion}.bin")
.AppendArgument($@"root@{installationIp}:/opt/innovenergy/bms-firmware/{FirmwareVersion}.bin") .AppendArgument($@"root@{installationIp}:/opt/innovenergy/{FirmwareVersion}.bin")
.WithValidation(CommandResultValidation.None).ExecuteBufferedAsync(); .ExecuteAsync();
} }
// [HttpGet(nameof(GetInstallation))] // [HttpGet(nameof(GetInstallation))]
// [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")] // [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]

View File

@ -6,7 +6,7 @@ namespace InnovEnergy.App.VrmGrabber.DataTypes;
public class Installation public class Installation
{ {
public Installation(String? argName, String? argIp, Int64 argVrm, String? argIdentifier, String? serial, String? urlEncode, String? online, String? lastSeen, String details, String numberOfBatteries, String batteryFirmwareVersion) public Installation(String? argName, String? argIp, Int64 argVrm, String? argIdentifier, String? serial, String? urlEncode, String? online, String? lastSeen, String details, String numberOfBatteries, String batteryFirmwareVersion, String? batteryUpdateStatus)
{ {
Name = argName; Name = argName;
Ip = argIp; Ip = argIp;
@ -19,6 +19,7 @@ public class Installation
Details = details; Details = details;
NumberOfBatteries = numberOfBatteries; NumberOfBatteries = numberOfBatteries;
BatteryFirmwareVersion = batteryFirmwareVersion; BatteryFirmwareVersion = batteryFirmwareVersion;
BatteryUpdateStatus = batteryUpdateStatus;
} }
public Installation() public Installation()
@ -37,6 +38,7 @@ public class Installation
public String? LastSeen { get; set;} public String? LastSeen { get; set;}
public String? NumberOfBatteries { get; set;} public String? NumberOfBatteries { get; set;}
public String? BatteryFirmwareVersion { get; set;} public String? BatteryFirmwareVersion { get; set;}
public String? BatteryUpdateStatus { get; set;}
public String? Details { get; set; } //JSON public String? Details { get; set; } //JSON
} }

View File

@ -74,7 +74,7 @@ public static partial class Db
var readOnlyInstallations = await user.GetInstallations(); var readOnlyInstallations = await user.GetInstallations();
var installations = readOnlyInstallations.ToList(); var installations = readOnlyInstallations.ToList();
installations.Shuffle(); installations.Shuffle(); // This
foreach (var installation in installations) foreach (var installation in installations)
{ {
@ -88,12 +88,14 @@ public static partial class Db
(Int64)installation.IdSite, (Int64)installation.IdSite,
installation.Identifier, installation.Identifier,
details.Details.MachineSerial() ?? "Unknown", details.Details.MachineSerial() ?? "Unknown",
HttpUtility.UrlEncode(installation.Name), HttpUtility.UrlEncode(installation.Name),
ip[1], ip[1],
details.Details.Last().Json["timestamp"].ToString(), details.Details.Last().Json["timestamp"].ToString(),
Serialize(details.Details), Serialize(details.Details),
await NumberOfBatteries(ip[0], ip[1]), await NumberOfBatteries(ip[0], ip[1]),
await BatteryFirmwareVersion(ip[0], ip[1])); await BatteryFirmwareVersion(ip[0], ip[1]),
"No updates"
);
if (ip[0] != "Unknown") if (ip[0] != "Unknown")
await UpdateInstallationName(installation, ip[0]); await UpdateInstallationName(installation, ip[0]);

Binary file not shown.

View File

@ -1,11 +1,11 @@
import axios from "axios"; import axios from "axios";
export const axiosConfigWithoutToken = axios.create({ export const axiosConfigWithoutToken = axios.create({
baseURL: "https://monitor.innov.energy/api", baseURL: "http://localhost:5000/api",
}); });
const axiosConfig = axios.create({ const axiosConfig = axios.create({
baseURL: "https://monitor.innov.energy/api", baseURL: "http://localhost:5000/api",
}); });
axiosConfig.defaults.params = {}; axiosConfig.defaults.params = {};