Update backend to support SodioHome installations, update backend controller to support new user access management features
This commit is contained in:
parent
0d8978c6b0
commit
076dcda4a2
|
|
@ -345,6 +345,18 @@ public class Controller : ControllerBase
|
|||
.ToList();
|
||||
}
|
||||
|
||||
[HttpGet(nameof(GetInstallationsTheUserHasAccess))]
|
||||
public ActionResult<IEnumerable<Object>> GetInstallationsTheUserHasAccess(Int64 userId, Token authToken)
|
||||
{
|
||||
var user = Db.GetUserById(userId);
|
||||
if (user == null)
|
||||
return Unauthorized();
|
||||
|
||||
|
||||
|
||||
return user.AccessibleInstallations().ToList();
|
||||
}
|
||||
|
||||
[HttpGet(nameof(GetUsersWithInheritedAccessToInstallation))]
|
||||
public ActionResult<IEnumerable<Object>> GetUsersWithInheritedAccessToInstallation(Int64 id, Token authToken)
|
||||
{
|
||||
|
|
@ -927,6 +939,8 @@ public class Controller : ControllerBase
|
|||
{
|
||||
var session = Db.GetSession(authToken);
|
||||
|
||||
Console.WriteLine("CONFIG IS " + config.GetConfigurationString());
|
||||
|
||||
// Send configuration changes
|
||||
var success = await session.SendInstallationConfig(installationId, config);
|
||||
|
||||
|
|
@ -940,6 +954,7 @@ public class Controller : ControllerBase
|
|||
Timestamp = DateTime.Now,
|
||||
Description = config.GetConfigurationString()
|
||||
};
|
||||
Console.WriteLine(action.Description);
|
||||
|
||||
var actionSuccess = await session.InsertUserAction(action);
|
||||
return actionSuccess?Ok():Unauthorized();
|
||||
|
|
@ -1020,7 +1035,7 @@ public class Controller : ControllerBase
|
|||
|
||||
Db.DeleteUserPassword(user);
|
||||
|
||||
return Redirect($"https://monitor.innov.energy/?username={user.Email}&reset=true"); // TODO: move to settings file
|
||||
return Redirect($"https://monitor.inesco.energy/?username={user.Email}&reset=true"); // TODO: move to settings file
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -413,6 +413,8 @@ public static class ExoCmd
|
|||
byte[] data = Encoding.UTF8.GetBytes(JsonSerializer.Serialize<Configuration>(config));
|
||||
udpClient.Send(data, data.Length, installation.VpnIp, port);
|
||||
|
||||
Console.WriteLine(config.GetConfigurationString());
|
||||
|
||||
//Console.WriteLine($"Sent UDP message to {installation.VpnIp}:{port}: {config}");
|
||||
Console.WriteLine($"Sent UDP message to {installation.VpnIp}:{port}"+" GridSetPoint is "+config.GridSetPoint +" and MinimumSoC is "+config.MinimumSoC);
|
||||
|
||||
|
|
@ -435,15 +437,6 @@ public static class ExoCmd
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
//var s3Region = new S3Region($"https://{installation.S3Region}.{installation.S3Provider}", S3Credentials!);
|
||||
//var url = s3Region.Bucket(installation.BucketName()).Path("config.json");
|
||||
//return await url.PutObject(config);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,12 +7,9 @@ namespace InnovEnergy.App.Backend.DataTypes.Methods;
|
|||
|
||||
public static class InstallationMethods
|
||||
{
|
||||
private static readonly String BucketNameSalt =
|
||||
// Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == ""
|
||||
// ? "stage" :"3e5b3069-214a-43ee-8d85-57d72000c19d";
|
||||
"3e5b3069-214a-43ee-8d85-57d72000c19d";
|
||||
|
||||
private static readonly String BucketNameSalt = "3e5b3069-214a-43ee-8d85-57d72000c19d";
|
||||
private static readonly String SalidomoBucketNameSalt = "c0436b6a-d276-4cd8-9c44-1eae86cf5d0e";
|
||||
private static readonly String SodioHomeBucketNameSalt = "e7b9a240-3c5d-4d2e-a019-6d8b1f7b73fa";
|
||||
|
||||
public static String BucketName(this Installation installation)
|
||||
{
|
||||
|
|
@ -21,6 +18,11 @@ public static class InstallationMethods
|
|||
return $"{installation.S3BucketId}-{BucketNameSalt}";
|
||||
}
|
||||
|
||||
if (installation.Product == (int)ProductType.SodioHome)
|
||||
{
|
||||
return $"{installation.S3BucketId}-{SodioHomeBucketNameSalt}";
|
||||
}
|
||||
|
||||
return $"{installation.S3BucketId}-{SalidomoBucketNameSalt}";
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ public static class SessionMethods
|
|||
|
||||
}
|
||||
|
||||
if (installation.Product == (int)ProductType.SodiStoreMax)
|
||||
if (installation.Product == (int)ProductType.SodiStoreMax || installation.Product == (int)ProductType.SodioHome)
|
||||
{
|
||||
return user is not null
|
||||
&& user.UserType != 0
|
||||
|
|
@ -244,15 +244,15 @@ public static class SessionMethods
|
|||
&& await installation.CreateBucket()
|
||||
&& await installation.RenewS3Credentials();
|
||||
}
|
||||
|
||||
if (installation.Product == (int)ProductType.SodioHome)
|
||||
{
|
||||
return user is not null
|
||||
&& user.UserType != 0
|
||||
&& user.HasAccessToParentOf(installation)
|
||||
&& Db.Create(installation);
|
||||
}
|
||||
|
||||
//
|
||||
// if (installation.Product == (int)ProductType.SodioHome)
|
||||
// {
|
||||
// return user is not null
|
||||
// && user.UserType != 0
|
||||
// && user.HasAccessToParentOf(installation)
|
||||
// && Db.Create(installation);
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -229,6 +229,9 @@ public static class UserMethods
|
|||
|
||||
public static Task SendEmail(this User user, String subject, String body)
|
||||
{
|
||||
|
||||
Console.WriteLine(user.Name);
|
||||
Console.WriteLine(subject);
|
||||
return Mailer.Send(user.Name, user.Email, subject, body);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -284,6 +284,7 @@ public static partial class Db
|
|||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("return false");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"SmtpServerUrl" : "mail.agenturserver.de",
|
||||
"SmtpUsername" : "p518526p69",
|
||||
"SmtpPassword" : "i;b*xqm4iB5uhl",
|
||||
"SmtpServerUrl" : "smtp.gmail.com",
|
||||
"SmtpUsername" : "angelis@inesco.energy",
|
||||
"SmtpPassword" : "huvu pkqd kakz hqtm ",
|
||||
"SmtpPort" : 587,
|
||||
"SenderName" : "InnovEnergy",
|
||||
"SenderAddress" : "noreply@innov.energy"
|
||||
"SenderName" : "Inesco Energy",
|
||||
"SenderAddress" : "noreply@inesco.energy"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,8 @@ public static class Program
|
|||
|
||||
RabbitMqManager.InitializeEnvironment();
|
||||
RabbitMqManager.StartRabbitMqConsumer().SupressAwaitWarning();
|
||||
WebsocketManager.MonitorSalimaxInstallationTable().SupressAwaitWarning();
|
||||
WebsocketManager.MonitorSalidomoInstallationTable().SupressAwaitWarning();
|
||||
WebsocketManager.MonitorSodistoreInstallationTable().SupressAwaitWarning();
|
||||
|
||||
WebsocketManager.MonitorInstallationTable().SupressAwaitWarning();
|
||||
|
||||
|
||||
// Task.Run(() => DeleteOldDataFromS3.DeleteOldData());
|
||||
|
|
|
|||
|
|
@ -49,6 +49,10 @@ public class Session : Relation<String, Int64>
|
|||
AccessToSalidomo = user.AccessibleInstallations(product: (int)ProductType.Salidomo).ToList().Count > 0;
|
||||
AccessToSodistoreMax = user.AccessibleInstallations(product: (int)ProductType.SodiStoreMax).ToList().Count > 0;
|
||||
AccessToSodioHome = user.AccessibleInstallations(product: (int)ProductType.SodioHome).ToList().Count > 0;
|
||||
|
||||
Console.WriteLine("salimax" +user.AccessibleInstallations(product: (int)ProductType.Salimax).ToList().Count);
|
||||
Console.WriteLine("AccessToSodistoreMax" +user.AccessibleInstallations(product: (int)ProductType.SodiStoreMax).ToList().Count);
|
||||
Console.WriteLine("sodio" + user.AccessibleInstallations(product: (int)ProductType.SodioHome).ToList().Count);
|
||||
}
|
||||
|
||||
private static String CreateToken()
|
||||
|
|
|
|||
|
|
@ -13,101 +13,41 @@ public static class WebsocketManager
|
|||
{
|
||||
public static Dictionary<Int64, InstallationInfo> InstallationConnections = new Dictionary<Int64, InstallationInfo>();
|
||||
|
||||
//Every 1 minute, check the timestamp of the latest received message for every installation.
|
||||
//If the difference between the two timestamps is more than two minutes, we consider this Salimax installation unavailable.
|
||||
public static async Task MonitorSalimaxInstallationTable()
|
||||
public static async Task MonitorInstallationTable()
|
||||
{
|
||||
while (true){
|
||||
lock (InstallationConnections){
|
||||
// Console.WriteLine("MONITOR SALIMAX INSTALLATIONS\n");
|
||||
foreach (var installationConnection in InstallationConnections){
|
||||
while (true)
|
||||
{
|
||||
lock (InstallationConnections)
|
||||
{
|
||||
Console.WriteLine("Monitoring installation table...");
|
||||
foreach (var installationConnection in InstallationConnections)
|
||||
{
|
||||
Console.WriteLine("installationConnection ID is " + installationConnection.Key + "latest timestamp is" +installationConnection.Value.Timestamp + "product is "+ installationConnection.Value.Product
|
||||
+ "and time diff is "+ (DateTime.Now - installationConnection.Value.Timestamp));
|
||||
|
||||
if (installationConnection.Value.Product==(int)ProductType.Salimax && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(2)){
|
||||
if ((installationConnection.Value.Product == (int)ProductType.Salimax && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(2)) ||
|
||||
(installationConnection.Value.Product == (int)ProductType.Salidomo && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(60)) ||
|
||||
(installationConnection.Value.Product == (int)ProductType.SodioHome && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(2)) ||
|
||||
(installationConnection.Value.Product == (int)ProductType.SodiStoreMax && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(2))
|
||||
)
|
||||
{
|
||||
|
||||
// Console.WriteLine("Installation ID is "+installationConnection.Key);
|
||||
// Console.WriteLine("installationConnection.Value.Timestamp is "+installationConnection.Value.Timestamp);
|
||||
Console.WriteLine("Installation ID is " + installationConnection.Key);
|
||||
Console.WriteLine("installationConnection.Value.Timestamp is " + installationConnection.Value.Timestamp);
|
||||
// Console.WriteLine("diff is "+(DateTime.Now-installationConnection.Value.Timestamp));
|
||||
|
||||
installationConnection.Value.Status = (int)StatusType.Offline;
|
||||
Installation installation = Db.Installations.FirstOrDefault(f => f.Product == (int)ProductType.Salimax && f.Id == installationConnection.Key);
|
||||
Installation installation = Db.Installations.FirstOrDefault(f => f.Product == installationConnection.Value.Product && f.Id == installationConnection.Key);
|
||||
installation.Status = (int)StatusType.Offline;
|
||||
installation.Apply(Db.Update);
|
||||
if (installationConnection.Value.Connections.Count > 0){InformWebsocketsForInstallation(installationConnection.Key);}
|
||||
}
|
||||
}
|
||||
// Console.WriteLine("FINISHED MONITORING SALIMAX INSTALLATIONS\n");
|
||||
}
|
||||
|
||||
await Task.Delay(TimeSpan.FromMinutes(1));
|
||||
}
|
||||
}
|
||||
|
||||
//Every 1 minute, check the timestamp of the latest received message for every installation.
|
||||
//If the difference between the two timestamps is more than 1 hour, we consider this Salidomo installation unavailable.
|
||||
public static async Task MonitorSalidomoInstallationTable()
|
||||
if (installationConnection.Value.Connections.Count > 0)
|
||||
{
|
||||
while (true){
|
||||
//Console.WriteLine("TRY TO LOCK FOR MONITOR SALIDOMO INSTALLATIONS\n");
|
||||
lock (InstallationConnections){
|
||||
//Console.WriteLine("MONITOR SALIDOMO INSTALLATIONS\n");
|
||||
foreach (var installationConnection in InstallationConnections)
|
||||
{
|
||||
//Console.WriteLine("Installation ID is "+installationConnection.Key);
|
||||
// if (installationConnection.Value.Product == (int)ProductType.Salidomo && (DateTime.Now - installationConnection.Value.Timestamp) < TimeSpan.FromMinutes(60)){
|
||||
// Console.WriteLine("Installation ID is "+installationConnection.Key + " diff is "+(DateTime.Now-installationConnection.Value.Timestamp));
|
||||
// }
|
||||
|
||||
if (installationConnection.Value.Product==(int)ProductType.Salidomo && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(60))
|
||||
{
|
||||
|
||||
//Console.WriteLine("installationConnection.Value.Timestamp is "+installationConnection.Value.Timestamp);
|
||||
//Console.WriteLine("timestamp now is is "+(DateTime.Now));
|
||||
|
||||
Installation installation = Db.Installations.FirstOrDefault(f => f.Product == (int)ProductType.Salidomo && f.Id == installationConnection.Key);
|
||||
//Console.WriteLine("Installation ID is "+installation.Name + " diff is "+(DateTime.Now-installationConnection.Value.Timestamp));
|
||||
installation.Status = (int)StatusType.Offline;
|
||||
installation.Apply(Db.Update);
|
||||
|
||||
installationConnection.Value.Status = (int)StatusType.Offline;
|
||||
if (installationConnection.Value.Connections.Count > 0){InformWebsocketsForInstallation(installationConnection.Key);}
|
||||
//else{Console.WriteLine("NONE IS CONNECTED TO THAT INSTALLATION-------------------------------------------------------------");}
|
||||
InformWebsocketsForInstallation(installationConnection.Key);
|
||||
}
|
||||
}
|
||||
//Console.WriteLine("FINISHED WITH UPDATING\n");
|
||||
}
|
||||
await Task.Delay(TimeSpan.FromMinutes(1));
|
||||
}
|
||||
}
|
||||
|
||||
//Every 1 minute, check the timestamp of the latest received message for every installation.
|
||||
//If the difference between the two timestamps is more than two minutes, we consider this Sodistore installation unavailable.
|
||||
public static async Task MonitorSodistoreInstallationTable()
|
||||
{
|
||||
while (true){
|
||||
//Console.WriteLine("TRY TO LOCK FOR MONITOR SODISTORE INSTALLATIONS\n");
|
||||
lock (InstallationConnections){
|
||||
//Console.WriteLine("MONITOR SODISTORE INSTALLATIONS\n");
|
||||
foreach (var installationConnection in InstallationConnections)
|
||||
{
|
||||
|
||||
if (installationConnection.Value.Product==(int)ProductType.SodiStoreMax && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(2))
|
||||
{
|
||||
|
||||
//Console.WriteLine("installationConnection.Value.Timestamp is "+installationConnection.Value.Timestamp);
|
||||
//Console.WriteLine("timestamp now is is "+(DateTime.Now));
|
||||
|
||||
Installation installation = Db.Installations.FirstOrDefault(f => f.Product == (int)ProductType.SodiStoreMax && f.Id == installationConnection.Key);
|
||||
//Console.WriteLine("Installation ID is "+installation.Name + " diff is "+(DateTime.Now-installationConnection.Value.Timestamp));
|
||||
installation.Status = (int)StatusType.Offline;
|
||||
installation.Apply(Db.Update);
|
||||
|
||||
installationConnection.Value.Status = (int)StatusType.Offline;
|
||||
if (installationConnection.Value.Connections.Count > 0){InformWebsocketsForInstallation(installationConnection.Key);}
|
||||
//else{Console.WriteLine("NONE IS CONNECTED TO THAT INSTALLATION-------------------------------------------------------------");}
|
||||
}
|
||||
}
|
||||
//Console.WriteLine("FINISHED WITH UPDATING\n");
|
||||
}
|
||||
await Task.Delay(TimeSpan.FromMinutes(1));
|
||||
}
|
||||
}
|
||||
|
|
@ -140,6 +80,7 @@ public static class WebsocketManager
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public static async Task HandleWebSocketConnection(WebSocket currentWebSocket)
|
||||
{
|
||||
var buffer = new byte[4096];
|
||||
|
|
@ -155,6 +96,7 @@ public static class WebsocketManager
|
|||
|
||||
var message = Encoding.UTF8.GetString(buffer, 0, result.Count);
|
||||
var installationIds = JsonSerializer.Deserialize<int[]>(message);
|
||||
Console.WriteLine("Received Websocket message: " + message);
|
||||
|
||||
//This is a ping message to keep the connection alive, reply with a pong
|
||||
if (installationIds[0] == -1)
|
||||
|
|
|
|||
|
|
@ -5191,7 +5191,7 @@
|
|||
"order": 5,
|
||||
"width": 0,
|
||||
"height": 0,
|
||||
"format": "<a href=\"https://monitor.innov.energy/salidomo_installations/list/\" target=\"_blank\" class=\"button\"> Battery Monitor </a>\n",
|
||||
"format": "<a href=\"https://monitor.inesco.energy/salidomo_installations/list/\" target=\"_blank\" class=\"button\"> Battery Monitor </a>\n",
|
||||
"storeOutMessages": true,
|
||||
"fwdInMessages": true,
|
||||
"resendOnRefresh": true,
|
||||
|
|
|
|||
|
|
@ -55,112 +55,6 @@ const WebSocketContextProvider = ({ children }: { children: ReactNode }) => {
|
|||
[]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// if (sortedInstallations) {
|
||||
// const tokenString = localStorage.getItem('token');
|
||||
// const token = tokenString !== null ? tokenString : '';
|
||||
// const urlWithToken = `wss://monitor.innov.energy/api/CreateWebSocket?authToken=${token}`;
|
||||
//
|
||||
// const socket = new WebSocket(urlWithToken);
|
||||
// // Connection opened
|
||||
// socket.addEventListener('open', (event) => {
|
||||
// socket.send(
|
||||
// JSON.stringify(
|
||||
// sortedInstallations.map((installation) => installation.id)
|
||||
// )
|
||||
// );
|
||||
// });
|
||||
//
|
||||
// // Periodically send ping messages to keep the connection alive
|
||||
// const pingInterval = setInterval(() => {
|
||||
// if (socket.readyState === WebSocket.OPEN) {
|
||||
// socket.send(JSON.stringify([-1]));
|
||||
// }
|
||||
// }, 10000); // Send a ping every 10 seconds
|
||||
//
|
||||
// let messageBuffer = [];
|
||||
// let isProcessing = false;
|
||||
//
|
||||
// socket.addEventListener('message', (event) => {
|
||||
// const message = JSON.parse(event.data); // Parse the JSON data
|
||||
//
|
||||
// if (Array.isArray(message)) {
|
||||
// message.forEach((item) => {
|
||||
// console.log('status is ' + item.status);
|
||||
// // Update status and testingMode for each installation received
|
||||
// // updateInstallationStatus(item.id, item.status, item.testingMode);
|
||||
// });
|
||||
// }
|
||||
// // } else if (message.id !== -1) {
|
||||
// // // Handle individual messages for installations
|
||||
// // updateInstallationStatus(
|
||||
// // message.id,
|
||||
// // message.status,
|
||||
// // message.testingMode
|
||||
// // );
|
||||
// // }
|
||||
//
|
||||
// // if (Array.isArray(message)) {
|
||||
// // // Existing code for handling arrays, if necessary
|
||||
// // setInstallationMode((prevMode) => {
|
||||
// // const newMode = new Map(prevMode);
|
||||
// // message.forEach((item) => {
|
||||
// // newMode.set(item.id, item.testingMode);
|
||||
// // });
|
||||
// // return newMode;
|
||||
// // });
|
||||
// //
|
||||
// // setInstallationStatus((prevStatus) => {
|
||||
// // const newStatus = new Map(prevStatus);
|
||||
// // message.forEach((item) => {
|
||||
// // newStatus.set(item.id, item.status);
|
||||
// // });
|
||||
// // return newStatus;
|
||||
// // });
|
||||
// // } else if (message.id != -1) {
|
||||
// // // Accumulate messages in the buffer
|
||||
// // messageBuffer.push(message);
|
||||
// //
|
||||
// // // Process the buffer if not already processing
|
||||
// // if (!isProcessing) {
|
||||
// // isProcessing = true;
|
||||
// //
|
||||
// // // Use setTimeout to process the buffer periodically
|
||||
// // setTimeout(() => {
|
||||
// // const newInstallationMode = new Map();
|
||||
// // const newInstallationStatus = new Map();
|
||||
// //
|
||||
// // // Process all accumulated messages
|
||||
// // messageBuffer.forEach((msg) => {
|
||||
// // newInstallationMode.set(msg.id, msg.testingMode);
|
||||
// // newInstallationStatus.set(msg.id, msg.status);
|
||||
// // });
|
||||
// //
|
||||
// // // Update the state with the accumulated messages
|
||||
// // setInstallationMode(
|
||||
// // (prevMode) => new Map([...prevMode, ...newInstallationMode])
|
||||
// // );
|
||||
// // setInstallationStatus(
|
||||
// // (prevStatus) =>
|
||||
// // new Map([...prevStatus, ...newInstallationStatus])
|
||||
// // );
|
||||
// //
|
||||
// // // Clear the buffer after processing
|
||||
// // messageBuffer = [];
|
||||
// // isProcessing = false; // Reset processing flag
|
||||
// // }, 100); // Adjust the delay as needed to control processing frequency
|
||||
// // }
|
||||
// // }
|
||||
// });
|
||||
//
|
||||
// setSocket(socket);
|
||||
// }
|
||||
}, [sortedInstallations]);
|
||||
|
||||
// const openSocket = (installations: I_Installation[]) => {
|
||||
// setInstallations(installations);
|
||||
// };
|
||||
|
||||
const openSocket = (installations) => {
|
||||
// setSortedInstallations(installations.sort((a, b) => b.status - a.status)); // Sort installations by status
|
||||
};
|
||||
|
|
@ -169,18 +63,6 @@ const WebSocketContextProvider = ({ children }: { children: ReactNode }) => {
|
|||
// socket.close();
|
||||
};
|
||||
|
||||
// const getStatus = (installationId: number) => {
|
||||
// return installationStatus.get(installationId);
|
||||
// // if (installationStatus.has(installationId)) {
|
||||
// // installationStatus.get(installationId);
|
||||
// // } else {
|
||||
// // return -2;
|
||||
// // }
|
||||
// };
|
||||
|
||||
// const getTestingMode = (installationId: number) => {
|
||||
// return installationMode.get(installationId);
|
||||
// };
|
||||
|
||||
return (
|
||||
<WebSocketContext.Provider
|
||||
|
|
|
|||
Loading…
Reference in New Issue