diff --git a/csharp/App/Backend/Backend.csproj b/csharp/App/Backend/Backend.csproj
index 71cefbddc..fc491daee 100644
--- a/csharp/App/Backend/Backend.csproj
+++ b/csharp/App/Backend/Backend.csproj
@@ -34,6 +34,7 @@
+
diff --git a/csharp/App/Backend/DataTypes/Installation.cs b/csharp/App/Backend/DataTypes/Installation.cs
index 067da8cba..b0c2c0b33 100644
--- a/csharp/App/Backend/DataTypes/Installation.cs
+++ b/csharp/App/Backend/DataTypes/Installation.cs
@@ -10,7 +10,7 @@ public class Installation : TreeNode
// TODO: make relation
//public IReadOnlyList OrderNumbers { get; set; } = Array.Empty();
- public String OrderNumbers { get; set; } = "";
+ public String? OrderNumbers { get; set; } = "";
public Double Lat { get; set; }
public Double Long { get; set; }
diff --git a/csharp/App/Backend/DataTypes/Methods/ExoCmd.cs b/csharp/App/Backend/DataTypes/Methods/ExoCmd.cs
index 4f935e17b..129f500da 100644
--- a/csharp/App/Backend/DataTypes/Methods/ExoCmd.cs
+++ b/csharp/App/Backend/DataTypes/Methods/ExoCmd.cs
@@ -1,71 +1,63 @@
-using CliWrap;
-using CliWrap.Buffered;
-using InnovEnergy.Lib.Utils;
+using System.Text.Json;
+using InnovEnergy.Lib.S3Utils;
+using InnovEnergy.Lib.S3Utils.DataTypes;
+using System.Diagnostics.CodeAnalysis;
namespace InnovEnergy.App.Backend.DataTypes.Methods;
public static class ExoCmd
{
- private static readonly Command Exo = Cli.Wrap("exo");
- private const String ConfigFile = "./exoscale.toml";
-
+ [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "")]
+ private static readonly S3Credentials? S3Creds = JsonSerializer.Deserialize("./exoscaleS3.json");
+
public static async Task<(String key, String secret)> CreateReadKey(this Installation installation)
{
- //if (installation.Id != 1) return "help"; //Todo remove me I am for debugging
+ var iamService = new S3Region(installation.Region, S3Creds!).GetIamClient();
+ if (!await Iam.UserExists(iamService, $"READ{installation.BucketName()}"))
+ {
+
+ var readOnlyPolicy = $"{installation.BucketName()}"; // TODO make me
+ await Iam.CreateUserAsync(iamService, $"READ{installation.BucketName()}");
+ await Iam.PutUserPolicyAsync(iamService, $"READ{installation.BucketName()}", $"READ{installation.BucketName()}",readOnlyPolicy);
+ }
+
+ var keySecret = await Iam.CreateAccessKeyAsync(iamService, $"READ{installation.BucketName()}");
-
- var preParse = await Exo
- .WithArguments("iam access-key create " + installation.BucketName()
- + " --operation get-sos-object"
- + " --resource sos/bucket:" + installation.BucketName()
- + " -C " + ConfigFile
- + " -O text")
- .ExecuteBufferedAsync();
+ return (keySecret.AccessKeyId, keySecret.SecretAccessKey);
+ }
+
+ public static async Task RevokeReadKey(this Installation installation)
+ {
+ var iamService = new S3Region(installation.Region, S3Creds!).GetIamClient();
+ if (!await Iam.UserExists(iamService, $"READ{installation.BucketName()}"))
+ {
+ return true;
+ }
- var key = preParse.StandardOutput.Split("\t")[2];
- var secret = preParse.StandardOutput.Split("\t")[3];
-
- return (key, secret);
-
- //return $"{key};{secret}";
+ return await Iam.RevokeAccessKey(iamService, $"READ{installation.BucketName()}");
}
public static async Task<(String key, String secret)> CreateWriteKey(this Installation installation)
{
- //if (installation.Id != 1) return "help"; //Todo remove me I am for debugging
+ var iamService = new S3Region(installation.Region, S3Creds!).GetIamClient();
+ if (!await Iam.UserExists(iamService, $"READWRITE{installation.BucketName()}"))
+ {
+ var readWritePolicy = $"{installation.BucketName()}"; // TODO make me
+ await Iam.CreateUserAsync(iamService, $"READWRITE{installation.BucketName()}");
+ await Iam.PutUserPolicyAsync(iamService, $"READWRITE{installation.BucketName()}", $"READWRITE{installation.BucketName()}",readWritePolicy);
+ }
+
+ var keySecret = await Iam.CreateAccessKeyAsync(iamService, $"READWRITE{installation.BucketName()}");
-
- var preParse = await Exo
- .WithArguments("iam access-key create " + installation.BucketName()
- + " --resource sos/bucket:" + installation.BucketName()
- + " -C " + ConfigFile
- + " -O text")
- .ExecuteBufferedAsync();
-
- var key = preParse.StandardOutput.Split("\t")[2];
- var secret = preParse.StandardOutput.Split("\t")[3];
-
- return (key, secret);
-
- //return $"{key};{secret}";
+ return (keySecret.AccessKeyId, keySecret.SecretAccessKey);
}
-
- public static async Task RevokeReadKey(this Installation installation)
+
+
+ public static async Task CreateBucket(this Installation installation)
{
- try
- {
- await Exo
- .WithArguments("iam access-key revoke " + installation.S3Key + " -f " + " -C " + ConfigFile)
- .WithValidation(CommandResultValidation.None)
- .ExecuteAsync();
- }
- catch
- {
- // TODO
- ("Failed to revoke key for installation " + installation.Name).WriteLine();
- }
+ var s3Region = new S3Region(installation.Region, S3Creds!);
+ return await s3Region.PutBucket(installation.BucketName()) != null;
}
-
}
\ No newline at end of file
diff --git a/csharp/App/Backend/DataTypes/Methods/Installation.cs b/csharp/App/Backend/DataTypes/Methods/Installation.cs
index 7f3ffd55e..420b905b4 100644
--- a/csharp/App/Backend/DataTypes/Methods/Installation.cs
+++ b/csharp/App/Backend/DataTypes/Methods/Installation.cs
@@ -1,4 +1,5 @@
using InnovEnergy.App.Backend.Database;
+using InnovEnergy.Lib.S3Utils;
using InnovEnergy.Lib.Utils;
namespace InnovEnergy.App.Backend.DataTypes.Methods;
@@ -31,27 +32,12 @@ public static class InstallationMethods
return Db.Update(installation);
}
-
- public static Task CreateBucket(this Installation installation)
- {
- // TODO
- throw new NotImplementedException();
-
- // return S3Access
- // .Admin
- // .CreateBucket(installation.BucketName());
- }
- public static Task DeleteBucket(this Installation installation)
+ public static async Task DeleteBucket(this Installation installation)
{
- // TODO
-
- throw new NotImplementedException();
-
- // return S3Access
- // .ReadWrite
- // .DeleteBucket(installation.BucketName());
+ // TODO We dont do this here
+ return true;
}
public static IEnumerable UsersWithAccess(this Installation installation)
@@ -138,7 +124,7 @@ public static class InstallationMethods
public static Installation FillOrderNumbers(this Installation installation)
{
- installation.OrderNumbers = installation.GetOrderNumbers();
+ installation.OrderNumbers = installation.GetOrderNumbers().ToString();
return installation;
}
diff --git a/csharp/App/Backend/DataTypes/Methods/Session.cs b/csharp/App/Backend/DataTypes/Methods/Session.cs
index 488465263..1376342ac 100644
--- a/csharp/App/Backend/DataTypes/Methods/Session.cs
+++ b/csharp/App/Backend/DataTypes/Methods/Session.cs
@@ -87,7 +87,7 @@ public static class SessionMethods
&& user.HasWriteAccess
&& user.HasAccessToParentOf(installation)
&& Db.Create(installation) // TODO: these two in a transaction
- && installation.SetOrderNumbers()
+ // && installation.SetOrderNumbers()
&& Db.Create(new InstallationAccess { UserId = user.Id, InstallationId = installation.Id })
&& await installation.CreateBucket()
&& await installation.RenewS3Credentials(); // generation of access _after_ generation of
@@ -101,7 +101,7 @@ public static class SessionMethods
var user = session?.User;
var original = Db.GetInstallationById(installation?.Id);
- var originalOrderNumbers = original!.GetOrderNumbers();
+ var originalOrderNumbers = original.OrderNumbers;
if (!Equals(originalOrderNumbers, installation?.OrderNumbers))
{
diff --git a/csharp/App/Backend/DataTypes/Methods/exoscale.toml b/csharp/App/Backend/DataTypes/Methods/exoscale.toml
deleted file mode 100644
index 58336b073..000000000
--- a/csharp/App/Backend/DataTypes/Methods/exoscale.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-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"
diff --git a/csharp/App/Backend/DataTypes/Methods/exoscaleS3.json b/csharp/App/Backend/DataTypes/Methods/exoscaleS3.json
new file mode 100644
index 000000000..15df82368
--- /dev/null
+++ b/csharp/App/Backend/DataTypes/Methods/exoscaleS3.json
@@ -0,0 +1,4 @@
+{
+ "Key": "EXOf67c5b528282988503ddab12",
+ "Secret": "KBFh5HvoSQcTtGYcWSm4Qn4m-WFutKe89UqsOdOL-ts"
+}
\ No newline at end of file
diff --git a/csharp/App/Backend/Properties/launchSettings.json b/csharp/App/Backend/Properties/launchSettings.json
index c1c45c271..3bef649bb 100644
--- a/csharp/App/Backend/Properties/launchSettings.json
+++ b/csharp/App/Backend/Properties/launchSettings.json
@@ -9,7 +9,8 @@
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7087",
"environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "HOME":"~/backend"
}
}
}
diff --git a/csharp/App/Backend/S3/S3Access.cs b/csharp/App/Backend/S3/S3Access.cs
deleted file mode 100644
index c71a3d317..000000000
--- a/csharp/App/Backend/S3/S3Access.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-// using System.Diagnostics.CodeAnalysis;
-// using static System.IO.File;
-// using static System.Text.Json.JsonSerializer;
-//
-// namespace InnovEnergy.App.Backend.S3;
-//
-// [SuppressMessage("Trimming", "IL2026:Members annotated with \'RequiresUnreferencedCodeAttribute\' require dynamic access otherwise can break functionality when trimming application code")]
-// public static class S3Access
-// {
-// public static S3Cmd ReadOnly => ParseJsonFile("./Resources/s3ReadOnlyKey.json")!;
-//
-// private static T? ParseJsonFile(String file)
-// {
-// var fileStream = OpenRead(file);
-// return Deserialize(fileStream);
-// }
-//
-// public static S3Cmd ReadWrite => Deserialize(OpenRead("./Resources/s3ReadWriteKey.json"))!;
-// public static S3Cmd Admin => Deserialize(OpenRead("./Resources/s3AdminKey.json"))!;
-// }
\ No newline at end of file
diff --git a/csharp/App/Backend/S3/S3Cmd.cs b/csharp/App/Backend/S3/S3Cmd.cs
deleted file mode 100644
index 5869d4232..000000000
--- a/csharp/App/Backend/S3/S3Cmd.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-// using System.Diagnostics.CodeAnalysis;
-// using CliWrap;
-// using CliWrap.Buffered;
-// using InnovEnergy.Lib.Utils;
-//
-// #pragma warning disable CS8618
-//
-// namespace InnovEnergy.App.Backend.S3;
-//
-// [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")]
-// public class S3Cmd
-// {
-// private static readonly Command Python = Cli.Wrap("python3");
-//
-// private const String S3CmdPath = "Resources/s3cmd.py";
-// private const String S3Prefix = "s3://";
-//
-// public String Key { get; init; }
-// public String Secret { get; init; }
-// public String Region { get; init; } = "sos-ch-dk-2.exo.io";
-//
-// [Obsolete("Only to be used by Json-Deserializer")] public S3Cmd()
-// {}
-//
-// public async Task CreateBucket(String bucketName)
-// {
-// const String cors = "./Resources/CORS";
-//
-// var makeBucket = await Run(bucketName, "mb");
-//
-// if (makeBucket.ExitCode != 0)
-// return false;
-//
-// var setCors = await Run(bucketName, "setcors", cors);
-//
-// return setCors.ExitCode == 0;
-// }
-//
-// public async Task ListFilesInBucket(String bucketName)
-// {
-// var result = await Run(bucketName, "ls");
-// return result.StandardOutput;
-// }
-//
-// public async Task?> GetFileLines(String bucketName, String filename)
-// {
-// try
-// {
-// await Run(bucketName + "/" + filename, "get", "--force");
-// }
-// catch
-// {
-// return null;
-// }
-//
-// var lines = File.ReadAllLines($"./{filename}");
-// File.Delete(filename);
-// return lines;
-// }
-//
-// public async Task DeleteBucket(String bucketName)
-// {
-// var result = await Run(bucketName, "rb");
-// return result.ExitCode == 0;
-// }
-//
-// private Task Run(String s3Path, String operation, params String[] optionalArgs)
-// {
-// var credentials = new[]
-// {
-// S3CmdPath,
-// "--access_key", Key,
-// "--secret_key", Secret,
-// "--host" , Region
-// };
-//
-// var args = credentials
-// .Append(operation)
-// .Concat(optionalArgs)
-// .Append(s3Path.EnsureStartsWith(S3Prefix));
-//
-// var withArguments = Python
-// .WithArguments(args);
-//
-// return withArguments
-// .WithValidation(CommandResultValidation.None)
-// .ExecuteBufferedAsync();
-// }
-//
-// }
\ No newline at end of file
diff --git a/csharp/App/Backend/S3/exoscale.toml b/csharp/App/Backend/S3/exoscale.toml
deleted file mode 100644
index 58336b073..000000000
--- a/csharp/App/Backend/S3/exoscale.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-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"
diff --git a/csharp/App/S3Explorer/Program.cs b/csharp/App/S3Explorer/Program.cs
index 95413a4d7..e00a2df02 100644
--- a/csharp/App/S3Explorer/Program.cs
+++ b/csharp/App/S3Explorer/Program.cs
@@ -4,6 +4,7 @@ using Amazon.S3.Model;
using InnovEnergy.Lib.S3Utils;
using InnovEnergy.Lib.S3Utils.DataTypes;
using InnovEnergy.Lib.Utils;
+using S3Cfg = InnovEnergy.Lib.S3Utils.S3Cfg;
namespace InnovEnergy.App.S3Explorer;
diff --git a/csharp/App/VrmGrabber/Controller.cs b/csharp/App/VrmGrabber/Controller.cs
index 461f9a1d6..d2012c8a9 100644
--- a/csharp/App/VrmGrabber/Controller.cs
+++ b/csharp/App/VrmGrabber/Controller.cs
@@ -191,17 +191,19 @@ th { /* header cell */
for (var batteryId = 3; batteryId < Int64.Parse(numberOfBatteries) + 2; batteryId++)
{
localCommand = localCommand.Append(
- $" && sleep 3m && /opt/innovenergy/scripts/upload-bms-firmware {batteryTtyName} {batteryId} /opt/innovenergy/{FirmwareVersion}.bin");
+ $" && sleep 3m && /opt/innovenergy/scripts/upload-bms-firmware {batteryTtyName} {batteryId} /opt/innovenergy/bms-firmware/{FirmwareVersion}.bin");
}
#pragma warning disable CS4014
Db.ExecuteBufferedAsyncCommandOnIp(installationIp, localCommand)
- .ContinueWith(t =>
+ .ContinueWith(async t =>
{
if (t.Status == TaskStatus.RanToCompletion)
{
installation.BatteryUpdateStatus = "Complete";
Db.Update(installation: installation);
- UpdateVrmTagsToNewFirmware(installationIp);
+ var vrmInst = await FindVrmInstallationByIp(installation.Ip!);
+ await UpdateVrmTagsToNewFirmware(installationIp);
+ await Db.UpdateAlarms(vrmInst);
}
else
{
@@ -236,8 +238,8 @@ th { /* header cell */
private static async Task SendNewBatteryFirmware(String installationIp)
{
await Cli.Wrap("rsync")
- .WithArguments($@"-r {FirmwareVersion}.bin")
- .AppendArgument($@"root@{installationIp}:/opt/innovenergy/bms-firmware/{FirmwareVersion}.bin")
+ .WithArguments($@"-r --relative bms-firmware/{FirmwareVersion}.bin")
+ .AppendArgument($@"root@{installationIp}:/opt/innovenergy")
.ExecuteAsync();
}
// [HttpGet(nameof(GetInstallation))]
diff --git a/csharp/App/VrmGrabber/Database/Db.cs b/csharp/App/VrmGrabber/Database/Db.cs
index 79599c9dc..f0adf3cda 100644
--- a/csharp/App/VrmGrabber/Database/Db.cs
+++ b/csharp/App/VrmGrabber/Database/Db.cs
@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
+using System.IO.Enumeration;
using System.Runtime.InteropServices;
using System.Text.Json.Nodes;
using System.Web;
@@ -80,9 +81,10 @@ public static partial class Db
foreach (var installation in installations)
{
Console.WriteLine(installation.Name);
- sd_notify(0, "WATCHDOG=1");
+ sd_notify(0, "WATCHDOG=1");
var details = await GetInstallationDetails(installation);
- await updateAlarms(installation);
+ // Thread.Sleep(1000);
+ await UpdateAlarms(installation);
var ip = Ip(details);
var updatedInstallation = new Installation(
installation.Name,
@@ -113,23 +115,21 @@ public static partial class Db
}
}
- [RequiresUnreferencedCode("Calls System.Text.Json.JsonSerializer.SerializeToElement(TValue, JsonSerializerOptions)")]
- private static async Task updateAlarms(VrmInstallation installation)
+ [RequiresUnreferencedCode(
+ "Calls System.Text.Json.JsonSerializer.SerializeToElement(TValue, JsonSerializerOptions)")]
+ public static async Task UpdateAlarms(VrmInstallation installation)
{
// installation.GetDevices().batteryMonitor.setTemperatureAlarms(245,250,315,313);
- var alarmJson = Deserialize("""
- {
- "AlarmEnabled": 1,
- "NotifyAfterSeconds": 60,
- "highAlarm": 315,
- "highAlarmHysteresis": 313,
- "lowAlarm": 245,
- "lowAlarmHysteresis": 250
- }
- """)!;
+ var alarmJson = JsonNode.Parse(File.ReadAllText("./alarm.json"))!.AsObject();
var tags = await installation.GetTags();
if (tags.Contains("FM-AF09"))
+ {
+ // Console.WriteLine(installation.IdSite.ToString());
+ // await installation.GetAlarms();
return await installation.SetAlarms(alarmJson);
+
+ }
+
return true;
}
diff --git a/csharp/App/VrmGrabber/alarm.json b/csharp/App/VrmGrabber/alarm.json
new file mode 100644
index 000000000..a99f75c16
--- /dev/null
+++ b/csharp/App/VrmGrabber/alarm.json
@@ -0,0 +1,10 @@
+{
+ "idDataAttribute":115,
+ "instance":1,
+ "lowAlarm":245,
+ "lowAlarmHysteresis":250,
+ "highAlarm":315,
+ "highAlarmHysteresis":313,
+ "AlarmEnabled":1,
+ "NotifyAfterSeconds":60,
+ "meta_info": {"icon":"device-battery-monitor","name":"Battery Monitor [1]","idDeviceType":2,"dataAttribute":"Battery temperature"}}
diff --git a/csharp/App/VrmGrabber/db.sqlite b/csharp/App/VrmGrabber/db.sqlite
index 81843140c..4847f0a8b 100644
Binary files a/csharp/App/VrmGrabber/db.sqlite and b/csharp/App/VrmGrabber/db.sqlite differ
diff --git a/csharp/Lib/S3Utils/DataTypes/S3Cfg.cs b/csharp/Lib/S3Utils/DataTypes/S3Cfg.cs
index 4f5ce85ab..cb362c413 100644
--- a/csharp/Lib/S3Utils/DataTypes/S3Cfg.cs
+++ b/csharp/Lib/S3Utils/DataTypes/S3Cfg.cs
@@ -57,7 +57,7 @@ public static class S3Cfg
Secret: cfg["secret_key"]
);
- return new S3Region(Name: cfg["host_base"], Credentials: credentials);
+ return new S3Region(cfg["host_base"], credentials);
}
catch
{
diff --git a/csharp/Lib/S3Utils/DataTypes/S3Region.cs b/csharp/Lib/S3Utils/DataTypes/S3Region.cs
index 2e507dfaf..034b0b87a 100644
--- a/csharp/Lib/S3Utils/DataTypes/S3Region.cs
+++ b/csharp/Lib/S3Utils/DataTypes/S3Region.cs
@@ -1,7 +1,13 @@
namespace InnovEnergy.Lib.S3Utils.DataTypes;
public record S3Region
-(
- String Name,
- S3Credentials Credentials
-);
+{
+ public S3Region(String name, S3Credentials creds)
+ {
+ Name = name;
+ Credentials = creds;
+ }
+ public String Name { get; init; }
+ public S3Credentials Credentials { get; init; }
+
+}
diff --git a/csharp/Lib/S3Utils/Iam.cs b/csharp/Lib/S3Utils/Iam.cs
index 7a55c3158..d43c0979f 100644
--- a/csharp/Lib/S3Utils/Iam.cs
+++ b/csharp/Lib/S3Utils/Iam.cs
@@ -1,5 +1,7 @@
using System.Collections.Concurrent;
+using System.Net;
using Amazon.IdentityManagement;
+using Amazon.IdentityManagement.Model;
using Amazon.Runtime;
using InnovEnergy.Lib.S3Utils.DataTypes;
using InnovEnergy.Lib.Utils;
@@ -10,7 +12,9 @@ public static class Iam
{
// TODO
+
+
private static readonly ConcurrentDictionary AimClientCache = new();
public static AmazonIdentityManagementServiceClient GetIamClient(this S3Url url ) => url.Bucket.GetIamClient();
@@ -23,10 +27,48 @@ public static class Iam
private static AmazonIdentityManagementServiceClient CreateIamClient(S3Region region) => new
(
credentials: new BasicAWSCredentials(region.Credentials.Key, region.Credentials.Secret),
- clientConfig: new() { ServiceURL = StringUtils.EnsureStartsWith(region.Name, "https://") }
+ clientConfig: new() { ServiceURL = region.Name.EnsureStartsWith("https://") }
);
+ public static async Task CreateUserAsync(AmazonIdentityManagementServiceClient iamService,String userName)
+ {
+ var response = await iamService.CreateUserAsync(new CreateUserRequest { UserName = userName });
+ return response.User;
+ }
-
+ public static async Task PutUserPolicyAsync(AmazonIdentityManagementServiceClient iamService, String userName, String policyName, String policyDocument)
+ {
+ var request = new PutUserPolicyRequest()
+ {
+ UserName = userName,
+ PolicyName = policyName,
+ PolicyDocument = policyDocument
+ };
+
+ var response = await iamService.PutUserPolicyAsync(request);
+ return response.HttpStatusCode == System.Net.HttpStatusCode.OK;
+ }
+ public static async Task CreateAccessKeyAsync(AmazonIdentityManagementServiceClient iamService, String userName)
+ {
+ var response = await iamService.CreateAccessKeyAsync(new CreateAccessKeyRequest
+ {
+ UserName = userName,
+ });
+
+ return response.AccessKey;
+
+ }
+
+ public static async Task UserExists(AmazonIdentityManagementServiceClient iamService, String userName)
+ {
+ var response = await iamService.GetUserAsync(new GetUserRequest { UserName = userName });
+ return response.HttpStatusCode == HttpStatusCode.OK;
+ }
+
+ public static async Task RevokeAccessKey(AmazonIdentityManagementServiceClient iamService, String userName)
+ {
+ var response = await iamService.DeleteAccessKeyAsync(new DeleteAccessKeyRequest{ AccessKeyId = userName });
+ return response.HttpStatusCode == HttpStatusCode.OK;
+ }
}
\ No newline at end of file
diff --git a/csharp/Lib/S3Utils/S3.cs b/csharp/Lib/S3Utils/S3.cs
index 345d41ce5..b80458e82 100644
--- a/csharp/Lib/S3Utils/S3.cs
+++ b/csharp/Lib/S3Utils/S3.cs
@@ -15,13 +15,6 @@ public static class S3
{
private static readonly ConcurrentDictionary S3ClientCache = new();
- // QOL method
- public static S3Region Region(this S3Credentials credentials, String name) => new
- (
- Name: name,
- Credentials: credentials
- );
-
// QOL method
public static S3Bucket Bucket(this S3Region region, String name) => new
(
@@ -179,7 +172,7 @@ public static class S3
credentials: new BasicAWSCredentials(region.Credentials.Key, region.Credentials.Secret),
clientConfig: new()
{
- ServiceURL = StringUtils.EnsureStartsWith(region.Name, "https://"),
+ ServiceURL = region.Name.EnsureStartsWith("https://"),
ForcePathStyle = true,
}
);
diff --git a/csharp/Lib/S3Utils/S3Cfg.cs b/csharp/Lib/S3Utils/S3Cfg.cs
index 2f9f9a328..a55209247 100644
--- a/csharp/Lib/S3Utils/S3Cfg.cs
+++ b/csharp/Lib/S3Utils/S3Cfg.cs
@@ -58,7 +58,7 @@ public static class S3Cfg
Secret: cfg["secret_key"]
);
- return new S3Region(Name: cfg["host_base"], Credentials: credentials);
+ return new S3Region(cfg["host_base"], credentials);
}
catch
{
diff --git a/csharp/Lib/S3Utils/S3Utils.csproj b/csharp/Lib/S3Utils/S3Utils.csproj
index e672ba589..a161ec092 100644
--- a/csharp/Lib/S3Utils/S3Utils.csproj
+++ b/csharp/Lib/S3Utils/S3Utils.csproj
@@ -16,18 +16,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/csharp/Lib/Victron/VictronVRM/FlurlExtensions.cs b/csharp/Lib/Victron/VictronVRM/FlurlExtensions.cs
index dbd443571..47be48176 100644
--- a/csharp/Lib/Victron/VictronVRM/FlurlExtensions.cs
+++ b/csharp/Lib/Victron/VictronVRM/FlurlExtensions.cs
@@ -2,6 +2,7 @@ using System.Net;
using System.Text.Json.Nodes;
using Flurl.Http;
using Flurl.Http.Content;
+using InnovEnergy.Lib.Utils;
using static System.Net.Http.HttpMethod;
namespace InnovEnergy.Lib.Victron.VictronVRM;
@@ -20,6 +21,12 @@ public static class FlurlExtensions
var stream = await TryRequest(request, Post, content).ReceiveStream();
return JsonNode.Parse(stream)!;
}
+
+ public static async Task TryPutJson(this IFlurlRequest request, JsonObject? content = null)
+ {
+ var stream = await TryRequest(request, Put, content).ReceiveStream();
+ return JsonNode.Parse(stream)!;
+ }
private static async Task TryRequest(this IFlurlRequest request, HttpMethod verb, JsonObject? data = null)
{
diff --git a/csharp/Lib/Victron/VictronVRM/Installation.Alarms.cs b/csharp/Lib/Victron/VictronVRM/Installation.Alarms.cs
index 38c54ac20..016da8ff0 100644
--- a/csharp/Lib/Victron/VictronVRM/Installation.Alarms.cs
+++ b/csharp/Lib/Victron/VictronVRM/Installation.Alarms.cs
@@ -1,5 +1,6 @@
using System.Text.Json;
using System.Text.Json.Nodes;
+using Flurl.Http;
namespace InnovEnergy.Lib.Victron.VictronVRM;
@@ -10,21 +11,23 @@ public readonly partial record struct Installation
public async Task> GetAlarms()
{
var reply = await VrmAccount.AlarmsRequest(IdSite).TryGetJson();
+ // Console.WriteLine("Got");
var vrmReply = new Reply(reply);
+ Console.WriteLine(vrmReply.ToString());
if (!vrmReply.Success)
throw new Exception(nameof(GetAlarms) + " failed");
-
+ Console.WriteLine(vrmReply.Alarms);
return vrmReply.Alarms;
}
public async Task SetAlarms(JsonObject tags)
{
- var reply = await VrmAccount.AlarmsRequest(IdSite).TryPostJson(tags);
+ var reply = await VrmAccount.AlarmsRequest(IdSite).TryPutJson(tags);
var vrmReply = new Reply(reply);
+ // Console.WriteLine(vrmReply.Success.ToString());
if (!vrmReply.Success)
throw new Exception(nameof(SetAlarms) + " failed");
-
return vrmReply.Success;
}
}
\ No newline at end of file
diff --git a/csharp/Lib/Victron/VictronVRM/Reply.cs b/csharp/Lib/Victron/VictronVRM/Reply.cs
index af91e9b3d..35b5190ed 100644
--- a/csharp/Lib/Victron/VictronVRM/Reply.cs
+++ b/csharp/Lib/Victron/VictronVRM/Reply.cs
@@ -9,7 +9,7 @@ public readonly record struct Reply(JsonNode Json)
public Boolean Success => Json.TryGetBoolean("success") is not null or true;
public IReadOnlyList Tags => Json.GetArray("tags");
- public IReadOnlyList Alarms => Json.GetArray("alarms");
+ public IReadOnlyList Alarms => Json.GetArray("alarms");
public JsonArray Records => Json.GetArray("records");
public IReadOnlyList Devices => Json["records"]!