Update dbus-fzsonic skripts

This commit is contained in:
Noe 2024-12-16 15:03:27 +01:00
parent 98fb313a6f
commit 074511f6a7
35 changed files with 1097 additions and 948 deletions

View File

@ -4,10 +4,13 @@ namespace InnovEnergy.App.Backend.DataTypes;
public class Installation : TreeNode public class Installation : TreeNode
{ {
public String Location { get; set; } = ""; //Each installation has 2 roles, a read role and a write role.
public String Region { get; set; } = ""; //There are 2 keys per role a public key and a secret
public String Country { get; set; } = ""; //Product can be 0 or 1, 0 for Salimax, 1 for Salidomo
public String VpnIp { get; set; } = ""; public String Location { get; set; } = "";
public String Region { get; set; } = "";
public String Country { get; set; } = "";
public String VpnIp { get; set; } = "";
public String InstallationName { get; set; } = ""; public String InstallationName { get; set; } = "";
public String S3Region { get; set; } = "sos-ch-dk-2"; public String S3Region { get; set; } = "sos-ch-dk-2";
@ -16,14 +19,15 @@ public class Installation : TreeNode
public String S3Key { get; set; } = ""; public String S3Key { get; set; } = "";
public String S3WriteSecret { get; set; } = ""; public String S3WriteSecret { get; set; } = "";
public String S3Secret { get; set; } = ""; public String S3Secret { get; set; } = "";
public int S3BucketId { get; set; } = 0; public int S3BucketId { get; set; } = 0;
public String ReadRoleId { get; set; } = ""; public String ReadRoleId { get; set; } = "";
public String WriteRoleId { get; set; } = ""; public String WriteRoleId { get; set; } = "";
public Boolean TestingMode { get; set; } = false; public Boolean TestingMode { get; set; } = false;
public int Status { get; set; } = -1;
public int Product { get; set; } = 0;
public int Device { get; set; } = 0;
public int Product { get; set; } = 0;
public int Device { get; set; } = 0;
[Ignore] [Ignore]
public String OrderNumbers { get; set; } public String OrderNumbers { get; set; }
public String VrmLink { get; set; } = ""; public String VrmLink { get; set; } = "";
} }

View File

@ -282,9 +282,9 @@ public static class SessionMethods
&& Db.Delete(installation) && Db.Delete(installation)
&& await installation.RevokeReadKey() && await installation.RevokeReadKey()
&& await installation.RevokeWriteKey() && await installation.RevokeWriteKey()
&& await installation.DeleteBucket()
&& await installation.RemoveReadRole() && await installation.RemoveReadRole()
&& await installation.RemoveWriteRole(); && await installation.RemoveWriteRole()
&& await installation.DeleteBucket();
} }

View File

@ -3,7 +3,7 @@ namespace InnovEnergy.App.Backend.DataTypes;
public abstract partial class TreeNode public abstract partial class TreeNode
{ {
//This is the parent class of each relation. It has an autoincrement Id, name, information, parent Id and Type. //This is the parent class of each relation. It has an autoincrement Id, name, information, parent Id and Type.
//Ignore means: "Do not map this property to a database column." //Ignore means: "Do not map this property to a database column."
[PrimaryKey, AutoIncrement] [PrimaryKey, AutoIncrement]
public Int64 Id { get; set; } public Int64 Id { get; set; }

View File

@ -7,28 +7,19 @@ namespace InnovEnergy.App.Backend.Database;
public static partial class Db public static partial class Db
{ {
private static int _backupCounter = 0;
private static Boolean Insert(Object obj) private static Boolean Insert(Object obj)
{ {
var success = Connection.Insert(obj) > 0; var success = Connection.Insert(obj) > 0;
if (success) if (success) Backup();
{
_backupCounter++;
if (_backupCounter > 100)
{
_backupCounter = 0;
BackupDatabase();
}
}
return success; return success;
} }
public static Boolean Create(Installation installation) public static Boolean Create(Installation installation)
{ {
installation.S3BucketId = Installations.Where(inst => inst.Product == installation.Product).Max(inst => (int?)inst.S3BucketId)+1 ?? 0; // The bucket Id it calculated as follows: It is 1 + the maximum bucket id of all the existing installations of the same product
// SQLite wrapper is smart and *modifies* t's Id to the one generated (autoincrement) by the insertion // SQLite wrapper is smart and *modifies* t's Id to the one generated (autoincrement) by the insertion
installation.S3BucketId = Installations.Where(inst => inst.Product == installation.Product).Max(inst => (int?)inst.S3BucketId)+1 ?? 0;
return Insert(installation); return Insert(installation);
} }
@ -103,21 +94,8 @@ public static partial class Db
} }
} }
public static void UpdateAction(UserAction updatedAction) //This function is called from the RabbitMQ manager when a new error arrives to the database.
{ //We keep only the last 100 errors for each installation. If we already have stored 100 errors, we delete the older one and we insert the new one.
var existingAction = UserActions.FirstOrDefault(action => action.Id == updatedAction.Id);
if (existingAction != null)
{
//existingAction.Description = updatedAction.Description;
//existingAction.Timestamp = updatedAction.Timestamp;
//existingAction.TestingMode = updatedAction.TestingMode;
Update(updatedAction);
Console.WriteLine("---------------Updated the Action in the database-----------------");
}
}
public static void HandleError(Error newError,int installationId) public static void HandleError(Error newError,int installationId)
{ {
@ -140,7 +118,7 @@ public static partial class Db
} }
else else
{ {
Console.WriteLine("---------------Added the new Error to the database-----------------"); Console.WriteLine("---------------Added the new Alarm to the database-----------------");
Create(newError); Create(newError);
} }
} }
@ -158,10 +136,10 @@ public static partial class Db
.OrderBy(warning => warning.Date) .OrderBy(warning => warning.Date)
.FirstOrDefault(); .FirstOrDefault();
//Remove the old error //Remove the old warning
Delete(oldestWarning); Delete(oldestWarning);
//Add the new error //Add the new warning
Create(newWarning); Create(newWarning);
} }
else else

View File

@ -9,6 +9,9 @@ using SQLiteConnection = SQLite.SQLiteConnection;
namespace InnovEnergy.App.Backend.Database; namespace InnovEnergy.App.Backend.Database;
//The methods of the Db class are located in multiple files (Create.cs, Read,cs, Delete.cs, Update.cs)
//That's why the class definition is partial
public static partial class Db public static partial class Db
{ {
private static SQLiteConnection Connection { get; } = InitConnection(); private static SQLiteConnection Connection { get; } = InitConnection();
@ -30,7 +33,7 @@ public static partial class Db
//Since this class is static, we call Init method from the Program.cs to initialize all the fields of the class //Since this class is static, we call Init method from the Program.cs to initialize all the fields of the class
//When a class is loaded, the fields are initialized before the constructor's code is executed. //When a class is loaded, the fields are initialized before the constructor's code is executed.
//The TableQuery fields are lazy meaning that they will be initialized when they get accessed //The TableQuery fields are lazy meaning that they will be initialized when they get accessed
//The connection searches for the latest backup and it binds all the tables to it. //The connection searches for the latest backup and binds all the tables to it.
} }
//This is the constructor of the class //This is the constructor of the class
@ -90,7 +93,7 @@ public static partial class Db
Connection.Backup("DbBackups/" + filename); Connection.Backup("DbBackups/" + filename);
} }
//Delete all by 10 snapshots every 24 hours. //Delete all except 10 snapshots every 24 hours.
private static async Task DeleteSnapshots() private static async Task DeleteSnapshots()
{ {
while (true) while (true)

View File

@ -1,16 +1,12 @@
using InnovEnergy.App.Backend.DataTypes; using InnovEnergy.App.Backend.DataTypes;
using InnovEnergy.App.Backend.DataTypes.Methods; using InnovEnergy.App.Backend.DataTypes.Methods;
using InnovEnergy.App.Backend.Relations; using InnovEnergy.App.Backend.Relations;
using Microsoft.AspNetCore.Authentication.OAuth.Claims;
namespace InnovEnergy.App.Backend.Database; namespace InnovEnergy.App.Backend.Database;
public static partial class Db public static partial class Db
{ {
//Since we do not want to stress the memory in the VM a lot, we make a snapshot of the database every 100 transactions.
private static int _backupCounter = 0;
private static void Backup() private static void Backup()
{ {
_backupCounter++; _backupCounter++;
@ -65,6 +61,8 @@ public static partial class Db
public static Boolean Delete(UserAction actionToDelete) public static Boolean Delete(UserAction actionToDelete)
{ {
var deleteSuccess = RunTransaction(DeleteAction); var deleteSuccess = RunTransaction(DeleteAction);
if (deleteSuccess) if (deleteSuccess)
Backup(); Backup();
return deleteSuccess; return deleteSuccess;
@ -73,6 +71,7 @@ public static partial class Db
Boolean DeleteAction() Boolean DeleteAction()
{ {
return UserActions.Delete(action => action.Id == actionToDelete.Id) >0; return UserActions.Delete(action => action.Id == actionToDelete.Id) >0;
} }
} }
@ -86,7 +85,7 @@ public static partial class Db
Boolean DeleteWarning() Boolean DeleteWarning()
{ {
return Warnings.Delete(error => error.Id == warningToDelete.Id) >0; return Warnings.Delete(warning => warning.Id == warningToDelete.Id) >0;
} }
} }
@ -100,15 +99,14 @@ public static partial class Db
Boolean DeleteInstallationAndItsDependencies() Boolean DeleteInstallationAndItsDependencies()
{ {
InstallationAccess.Delete(i => i.InstallationId == installation.Id);
if (installation.Product == 0) if (installation.Product == 0)
{ {
InstallationAccess.Delete(i => i.InstallationId == installation.Id); //For Salimax, delete the OrderNumber2Installation entries associated with this installation id.
OrderNumber2Installation.Delete(i => i.InstallationId == installation.Id); OrderNumber2Installation.Delete(i => i.InstallationId == installation.Id);
} }
return Installations.Delete(i => i.Id == installation.Id) > 0; return Installations.Delete(i => i.Id == installation.Id) > 0;
} }
} }
@ -123,7 +121,6 @@ public static partial class Db
{ {
FolderAccess .Delete(u => u.UserId == user.Id); FolderAccess .Delete(u => u.UserId == user.Id);
InstallationAccess.Delete(u => u.UserId == user.Id); InstallationAccess.Delete(u => u.UserId == user.Id);
return Users.Delete(u => u.Id == user.Id) > 0; return Users.Delete(u => u.Id == user.Id) > 0;
} }
} }

View File

@ -1,10 +1,13 @@
using InnovEnergy.App.Backend.DataTypes; using InnovEnergy.App.Backend.DataTypes;
namespace InnovEnergy.App.Backend.Database; namespace InnovEnergy.App.Backend.Database;
public static partial class Db public static partial class Db
{ {
//We can execute the updates manually for each table, but we prefer the abstract way using Connection.Update method
//We pass an object as an argument and the Connection will connect this object with the corresponding table.
//The update is being done based on the primary id of the object.
private static Boolean Update(Object obj) private static Boolean Update(Object obj)
{ {
var success = Connection.Update(obj) > 0; var success = Connection.Update(obj) > 0;
@ -22,7 +25,6 @@ public static partial class Db
return Update(obj: error); return Update(obj: error);
} }
public static Boolean Update(Warning warning) public static Boolean Update(Warning warning)
{ {
return Update(obj: warning); return Update(obj: warning);
@ -44,4 +46,15 @@ public static partial class Db
return Update(obj: user); return Update(obj: user);
} }
public static void UpdateAction(UserAction updatedAction)
{
var existingAction = UserActions.FirstOrDefault(action => action.Id == updatedAction.Id);
if (existingAction != null)
{
Update(updatedAction);
}
}
} }

View File

@ -26,9 +26,9 @@ public static class Program
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
RabbitMqManager.InitializeEnvironment(); RabbitMqManager.InitializeEnvironment();
RabbitMqManager.StartRabbitMqConsumer(); RabbitMqManager.StartRabbitMqConsumer().SupressAwaitWarning();
WebsocketManager.MonitorSalimaxInstallationTable(); WebsocketManager.MonitorSalimaxInstallationTable().SupressAwaitWarning();
WebsocketManager.MonitorSalidomoInstallationTable(); WebsocketManager.MonitorSalidomoInstallationTable().SupressAwaitWarning();
builder.Services.AddControllers(); builder.Services.AddControllers();

View File

@ -1,12 +1,10 @@
using System.Net;
using System.Net.Sockets;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using InnovEnergy.App.Backend.Database; using InnovEnergy.App.Backend.Database;
using InnovEnergy.App.Backend.DataTypes; using InnovEnergy.App.Backend.DataTypes;
using InnovEnergy.Lib.Utils;
using RabbitMQ.Client; using RabbitMQ.Client;
using RabbitMQ.Client.Events; using RabbitMQ.Client.Events;
using InnovEnergy.Lib.Mailer;
namespace InnovEnergy.App.Backend.Websockets; namespace InnovEnergy.App.Backend.Websockets;
@ -59,23 +57,17 @@ public static class RabbitMqManager
{ {
Installation installation = Db.Installations.FirstOrDefault(f => f.Product == receivedStatusMessage.Product && f.S3BucketId == receivedStatusMessage.InstallationId); Installation installation = Db.Installations.FirstOrDefault(f => f.Product == receivedStatusMessage.Product && f.S3BucketId == receivedStatusMessage.InstallationId);
int installationId = (int)installation.Id; int installationId = (int)installation.Id;
//Console.WriteLine("received a message from rabbitmq\n");
//if (installationId == 138)
//{
// Console.WriteLine("Received a message from installation: " + installationId + " , product is: " + receivedStatusMessage.Product + " and status is: " + receivedStatusMessage.Status);
//}
//This is a heartbit message, just update the timestamp for this installation. //This is a heartbit message, just update the timestamp for this installation.
//There is no need to notify the corresponding front-ends. //There is no need to notify the corresponding front-ends.
//Every 15 iterations(30 seconds), the installation sends a heartbit message to the queue //Every 15 iterations(30 seconds), the installation sends a heartbit message to the queue
if (receivedStatusMessage.Type == MessageType.Heartbit) if (receivedStatusMessage.Type == MessageType.Heartbit)
{ {
if (installation.Product == 1 && installation.Device == 2) // if (installation.Product == 1 && installation.Device == 2)
{ // {
Console.WriteLine("This is a heartbit message from installation: " + installationId + " Name of the file is " + receivedStatusMessage.Timestamp); // Console.WriteLine("This is a heartbit message from installation: " + installationId + " Name of the file is " + receivedStatusMessage.Timestamp);
} // }
} }
else else
{ {
@ -95,7 +87,7 @@ public static class RabbitMqManager
Seen = false Seen = false
}; };
//Create a new warning and add it to the database //Create a new warning and add it to the database
Console.WriteLine("Add a warning for installation "+installationId); //Console.WriteLine("Add a warning for installation "+installationId);
Db.HandleWarning(newWarning, installationId); Db.HandleWarning(newWarning, installationId);
} }
} }
@ -176,8 +168,16 @@ public static class RabbitMqManager
prevStatus = WebsocketManager.InstallationConnections[installationId].Status; prevStatus = WebsocketManager.InstallationConnections[installationId].Status;
WebsocketManager.InstallationConnections[installationId].Status = receivedStatusMessage.Status; WebsocketManager.InstallationConnections[installationId].Status = receivedStatusMessage.Status;
WebsocketManager.InstallationConnections[installationId].Timestamp = DateTime.Now; WebsocketManager.InstallationConnections[installationId].Timestamp = DateTime.Now;
// if (installationId == 130)
// {
// Console.WriteLine("prevStatus " + prevStatus + " , new status is: " + receivedStatusMessage.Status + " and status is: " + receivedStatusMessage.Status);
// }
} }
installation.Status = receivedStatusMessage.Status;
installation.Apply(Db.Update);
//Console.WriteLine("----------------------------------------------"); //Console.WriteLine("----------------------------------------------");
//If the status has changed, update all the connected front-ends regarding this installation //If the status has changed, update all the connected front-ends regarding this installation
if(prevStatus != receivedStatusMessage.Status && WebsocketManager.InstallationConnections[installationId].Connections.Count > 0) if(prevStatus != receivedStatusMessage.Status && WebsocketManager.InstallationConnections[installationId].Connections.Count > 0)

View File

@ -19,32 +19,53 @@ public static class WebsocketManager
{ {
while (true){ while (true){
lock (InstallationConnections){ lock (InstallationConnections){
Console.WriteLine("MONITOR SALIMAX INSTALLATIONS\n");
foreach (var installationConnection in InstallationConnections){ foreach (var installationConnection in InstallationConnections){
if (installationConnection.Value.Product==0 && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(1)){
if (installationConnection.Value.Product==0 && (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("diff is "+(DateTime.Now-installationConnection.Value.Timestamp));
installationConnection.Value.Status = -1; installationConnection.Value.Status = -1;
Installation installation = Db.Installations.FirstOrDefault(f => f.Product == 0 && f.S3BucketId == installationConnection.Key); Installation installation = Db.Installations.FirstOrDefault(f => f.Product == 0 && f.Id == installationConnection.Key);
installation.Status = -1; installation.Status = -1;
installation.Apply(Db.Update); installation.Apply(Db.Update);
if (installationConnection.Value.Connections.Count > 0){InformWebsocketsForInstallation(installationConnection.Key);} if (installationConnection.Value.Connections.Count > 0){InformWebsocketsForInstallation(installationConnection.Key);}
} }
} }
Console.WriteLine("FINISHED MONITORING SALIMAX INSTALLATIONS\n");
} }
await Task.Delay(TimeSpan.FromMinutes(2));
await Task.Delay(TimeSpan.FromMinutes(1));
} }
} }
public static async Task MonitorSalidomoInstallationTable() public static async Task MonitorSalidomoInstallationTable()
{ {
while (true){ while (true){
Console.WriteLine("TRY TO LOCK FOR MONITOR SALIDOMO INSTALLATIONS\n");
lock (InstallationConnections){ lock (InstallationConnections){
Console.WriteLine("MONITOR SALIDOMO INSTALLATIONS\n");
foreach (var installationConnection in InstallationConnections){ foreach (var installationConnection in InstallationConnections){
Console.WriteLine("Installation ID is "+installationConnection.Key);
// if (installationConnection.Key == 104)
// {
// Console.WriteLine("installationConnection.Value.Timestamp is "+installationConnection.Value.Timestamp);
// Console.WriteLine("diff is "+(DateTime.Now-installationConnection.Value.Timestamp));
//
//
// }
if (installationConnection.Value.Product==1 && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(30)) if (installationConnection.Value.Product==1 && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(30))
{ {
// Console.WriteLine("Installation ID is "+installationConnection.Key); // Console.WriteLine("Installation ID is "+installationConnection.Key);
// Console.WriteLine("installationConnection.Value.Timestamp is "+installationConnection.Value.Timestamp); // Console.WriteLine("installationConnection.Value.Timestamp is "+installationConnection.Value.Timestamp);
// Console.WriteLine("diff is "+(DateTime.Now-installationConnection.Value.Timestamp)); // Console.WriteLine("diff is "+(DateTime.Now-installationConnection.Value.Timestamp));
Installation installation = Db.Installations.FirstOrDefault(f => f.Product == 1 && f.S3BucketId == installationConnection.Key); Installation installation = Db.Installations.FirstOrDefault(f => f.Product == 1 && f.Id == installationConnection.Key);
installation.Status = -1; installation.Status = -1;
installation.Apply(Db.Update); installation.Apply(Db.Update);
@ -52,8 +73,9 @@ public static class WebsocketManager
if (installationConnection.Value.Connections.Count > 0){InformWebsocketsForInstallation(installationConnection.Key);} if (installationConnection.Value.Connections.Count > 0){InformWebsocketsForInstallation(installationConnection.Key);}
} }
} }
Console.WriteLine("FINISHED WITH UPDATING\n");
} }
await Task.Delay(TimeSpan.FromMinutes(10)); await Task.Delay(TimeSpan.FromMinutes(1));
} }
} }
@ -124,7 +146,6 @@ public static class WebsocketManager
//Console.WriteLine("Received a new message from websocket"); //Console.WriteLine("Received a new message from websocket");
lock (InstallationConnections) lock (InstallationConnections)
{ {
List<WebsocketMessage> dataToSend = new List<WebsocketMessage>(); List<WebsocketMessage> dataToSend = new List<WebsocketMessage>();
//Each front-end will send the list of the installations it wants to access //Each front-end will send the list of the installations it wants to access
@ -139,7 +160,7 @@ public static class WebsocketManager
//Console.WriteLine("Create new empty list for installation id " + installationId); //Console.WriteLine("Create new empty list for installation id " + installationId);
InstallationConnections[installationId] = new InstallationInfo InstallationConnections[installationId] = new InstallationInfo
{ {
Status = -1, Status = installation.Status,
Product = installation.Product Product = installation.Product
}; };
} }
@ -155,15 +176,6 @@ public static class WebsocketManager
dataToSend.Add(jsonObject); dataToSend.Add(jsonObject);
//var jsonString = JsonSerializer.Serialize(jsonObject);
//var dataToSend = Encoding.UTF8.GetBytes(jsonString);
// currentWebSocket.SendAsync(dataToSend,
// WebSocketMessageType.Text,
// true, // Indicates that this is the end of the message
// CancellationToken.None
// );
} }
var jsonString = JsonSerializer.Serialize(dataToSend); var jsonString = JsonSerializer.Serialize(dataToSend);
var encodedDataToSend = Encoding.UTF8.GetBytes(jsonString); var encodedDataToSend = Encoding.UTF8.GetBytes(jsonString);

Binary file not shown.

View File

@ -13,9 +13,9 @@ DEVICE_INSTANCE = 1
SERVICE_NAME_PREFIX = 'com.victronenergy.battery.' SERVICE_NAME_PREFIX = 'com.victronenergy.battery.'
#s3 configuration #s3 configuration
S3BUCKET = "673-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e" S3BUCKET = "489-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e"
S3KEY = "EXO270612dc3f57a61870220eea" S3KEY = "EXOd55ec2d5702c3b94f1e275a4"
S3SECRET = "4fPVVN8JGnD9IY1k5RrrNUzo2L1IpR6gdSuGRB9pMWg" S3SECRET = "0bOJW6COdJ1_vQ_SDbaYKtLs9E7bxANZb5d1X4zf97g"
# driver configuration # driver configuration

View File

@ -643,6 +643,10 @@ def read_battery_status(modbus, battery):
modbus.connect() modbus.connect()
data = read_modbus_registers(modbus, battery.slave_address) data = read_modbus_registers(modbus, battery.slave_address)
return BatteryStatus(battery, data.registers) return BatteryStatus(battery, data.registers)
except Exception as e:
logging.error(f"An error occurred: {e}")
create_batch_of_csv_files() # Call this only if there's an error
raise
finally: finally:
modbus.close() # close in any case modbus.close() # close in any case
@ -655,6 +659,7 @@ def publish_values(dbus, signals, statuses):
previous_warnings = {} previous_warnings = {}
previous_alarms = {} previous_alarms = {}
num_of_csv_files_saved=0
class MessageType: class MessageType:
ALARM_OR_WARNING = "AlarmOrWarning" ALARM_OR_WARNING = "AlarmOrWarning"
@ -680,6 +685,7 @@ def SubscribeToQueue():
connection = pika.BlockingConnection(pika.ConnectionParameters(host="10.2.0.11", connection = pika.BlockingConnection(pika.ConnectionParameters(host="10.2.0.11",
port=5672, port=5672,
virtual_host="/", virtual_host="/",
heartbeat=30,
credentials=pika.PlainCredentials("producer", "b187ceaddb54d5485063ddc1d41af66f"))) credentials=pika.PlainCredentials("producer", "b187ceaddb54d5485063ddc1d41af66f")))
channel = connection.channel() channel = connection.channel()
channel.queue_declare(queue="statusQueue", durable=True) channel.queue_declare(queue="statusQueue", durable=True)
@ -903,7 +909,7 @@ def count_files_in_folder(folder_path):
def create_batch_of_csv_files(): def create_batch_of_csv_files():
global prev_status,INSTALLATION_ID, PRODUCT_ID global prev_status,INSTALLATION_ID, PRODUCT_ID, num_of_csv_files_saved
# list all files in the directory # list all files in the directory
files = os.listdir(CSV_DIR) files = os.listdir(CSV_DIR)
@ -914,7 +920,8 @@ def create_batch_of_csv_files():
csv_files.sort(key=lambda x: os.path.getctime(os.path.join(CSV_DIR, x))) csv_files.sort(key=lambda x: os.path.getctime(os.path.join(CSV_DIR, x)))
# keep the 600 MOST RECENT FILES # keep the 600 MOST RECENT FILES
recent_csv_files = csv_files[-600:] if len(csv_files) > 600 else csv_files recent_csv_files = csv_files[-num_of_csv_files_saved:]
print("num_of_csv_files_saved is " + str(num_of_csv_files_saved))
# get the name of the first csv file # get the name of the first csv file
if not csv_files: if not csv_files:
@ -949,6 +956,7 @@ def create_batch_of_csv_files():
# replace the original first csv file with the temporary file # replace the original first csv file with the temporary file
os.remove(first_csv_file) os.remove(first_csv_file)
os.rename(temp_file_path, first_csv_file) os.rename(temp_file_path, first_csv_file)
num_of_csv_files_saved = 0
# create a loggin directory that contains at max 20 batch files for logging info # create a loggin directory that contains at max 20 batch files for logging info
# logging_dir = os.path.join(CSV_DIR, 'logging_batch_files') # logging_dir = os.path.join(CSV_DIR, 'logging_batch_files')
@ -1023,10 +1031,12 @@ def create_update_task(modbus, dbus, batteries, signals, csv_signals, main_loop)
ALLOW = True ALLOW = True
alive = update(modbus, batteries, dbus, signals, csv_signals) alive = update(modbus, batteries, dbus, signals, csv_signals)
elapsed_time = time.time() - start_time elapsed_time = time.time() - start_time
print("11111111111111111111111111111111111111111111 elapsed time is ", elapsed_time)
# keep at most 1900 files at CSV_DIR for logging and aggregation # keep at most 1900 files at CSV_DIR for logging and aggregation
manage_csv_files(CSV_DIR, 1900) manage_csv_files(CSV_DIR, 1900)
if elapsed_time >= 1200: if elapsed_time >= 1200:
print("CREATE BATCH ======================================>")
create_batch_of_csv_files() create_batch_of_csv_files()
start_time = time.time() start_time = time.time()
#alive = update_for_testing(modbus, batteries, dbus, signals, csv_signals) #alive = update_for_testing(modbus, batteries, dbus, signals, csv_signals)
@ -1075,7 +1085,7 @@ def insert_id(path, id_number):
return "/".join(parts) return "/".join(parts)
def create_csv_files(signals, statuses, node_numbers, alarms_number_list, warnings_number_list): def create_csv_files(signals, statuses, node_numbers, alarms_number_list, warnings_number_list):
global s3_config global s3_config, num_of_csv_files_saved
timestamp = int(time.time()) timestamp = int(time.time())
if timestamp % 2 != 0: if timestamp % 2 != 0:
timestamp -= 1 timestamp -= 1
@ -1084,6 +1094,8 @@ def create_csv_files(signals, statuses, node_numbers, alarms_number_list, warnin
os.makedirs(CSV_DIR) os.makedirs(CSV_DIR)
csv_filename = f"{timestamp}.csv" csv_filename = f"{timestamp}.csv"
csv_path = os.path.join(CSV_DIR, csv_filename) csv_path = os.path.join(CSV_DIR, csv_filename)
num_of_csv_files_saved+=1
# Append values to the CSV file # Append values to the CSV file
if not os.path.exists(csv_path): if not os.path.exists(csv_path):
with open(csv_path, 'a', newline='') as csvfile: with open(csv_path, 'a', newline='') as csvfile:

View File

@ -54,6 +54,6 @@ INNOVENERGY_PROTOCOL_VERSION = '48TL200V3'
# S3 Credentials # S3 Credentials
S3BUCKET = "140-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e" S3BUCKET = "627-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e"
S3KEY = "EXOa947c7fc5990a7a6f6c40860" S3KEY = "EXOb7bcf7d1e53f2d46923144de"
S3SECRET = "J1yOTLbYEO6cMxQ2wgIwe__ru9-_RH5BBtKzx_2JJHk" S3SECRET = "-uUmMuAfx40LpTKTZgdbXswTw09o_qmE4gzkmQS8PTk"

View File

@ -141,39 +141,39 @@ async def main(remote_host):
##### 2. check whether it's Venus ###### ##### 2. check whether it's Venus ######
gx_type = await check_GX_type(remote_host) gx_type = await check_GX_type(remote_host)
if gx_type == "beaglebone\n": # if gx_type == "beaglebone\n":
##### 3. upload VPN and battery files ###### ##### 3. upload VPN and battery files ######
print("Upload pika and battery files!") print("Upload pika and battery files!")
if(await upload_files(remote_host)!="All files uploaded successfully."): if(await upload_files(remote_host)!="All files uploaded successfully."):
sys.exit("Failed to upload files!") sys.exit("Failed to upload files!")
else:
print(await upload_files(remote_host))
#### 4. import pika ####
print("Import pika!")
print(await import_pika(remote_host))
#### 5. resize /dev/root #####
print("Resize /dev/root now!")
print(await resize(remote_host))
#### 6. stop battery service ######
print("Stop battery service!")
print(await stop_battery_service(remote_host))
#### 7. stop controller service ######
print("Stop controller service!")
print(await stop_controller(remote_host))
##### 8. run rc.local ######
print("Run rc.local!")
print(await run_rclocal(remote_host))
##### 9. start battery service ######
print("Start battery service!")
print(await start_battery_service(remote_host))
##### 10. start controller service ######
print("Start controller service!")
print(await start_controller(remote_host))
##### 11. restart gui ######
print("Restart gui!")
print(await restart_gui(remote_host))
else: else:
sys.exit("It's not Venus GX!") print(await upload_files(remote_host))
#### 4. import pika ####
print("Import pika!")
print(await import_pika(remote_host))
#### 5. resize /dev/root #####
print("Resize /dev/root now!")
print(await resize(remote_host))
#### 6. stop battery service ######
print("Stop battery service!")
print(await stop_battery_service(remote_host))
#### 7. stop controller service ######
print("Stop controller service!")
print(await stop_controller(remote_host))
##### 8. run rc.local ######
print("Run rc.local!")
print(await run_rclocal(remote_host))
##### 9. start battery service ######
print("Start battery service!")
print(await start_battery_service(remote_host))
##### 10. start controller service ######
print("Start controller service!")
print(await start_controller(remote_host))
##### 11. restart gui ######
print("Restart gui!")
print(await restart_gui(remote_host))
# else:
# sys.exit("It's not Venus GX!")
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -1,11 +1,11 @@
{ {
"name": "Inesco Energy", "name": "InnovEnergy",
"version": "2.0.0", "version": "2.0.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "Inesco Energy", "name": "InnovEnergy",
"version": "2.0.0", "version": "2.0.0",
"dependencies": { "dependencies": {
"@emotion/react": "11.9.0", "@emotion/react": "11.9.0",

View File

@ -1,7 +1,7 @@
{ {
"name": "c", "name": "InnovEnergy",
"version": "2.0.0", "version": "2.0.0",
"title": "Inesco Energy", "title": "InnovEnergy",
"private": false, "private": false,
"dependencies": { "dependencies": {
"@emotion/react": "11.9.0", "@emotion/react": "11.9.0",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

View File

@ -13,7 +13,7 @@
href="https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400&display=swap" href="https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400&display=swap"
rel="stylesheet" rel="stylesheet"
/> />
<title>Inesco Energy</title> <title>InnovEnergy</title>
</head> </head>
<body> <body>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 28.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 841.89 595.28" style="enable-background:new 0 0 841.89 595.28;" xml:space="preserve">
<style type="text/css">
.st0{fill:#646363;}
.st1{fill:#F39200;}
</style>
<g>
<path class="st0" d="M114.05,430.69c2.55,1.07,6.32,1.94,10.5,1.94c6.47,0,12.13-2.7,12.13-9.69c0-7.03-4.99-9.02-11.06-11.01
c-4.79-1.53-7.55-2.91-7.55-7.04c0-3.82,2.55-5.91,7.9-5.91c2.45,0,5.15,0.61,7.54,1.38l0.76-3.11c-2.24-0.87-5.71-1.53-8.56-1.53
c-6.98,0-11.42,3.21-11.42,9.23c0,5.71,3.52,8.21,9.53,10.14c5.45,1.68,9.07,3.11,9.07,7.85c0,4.38-3.26,6.42-8.46,6.42
c-3.98,0-7.29-1.07-9.68-1.94L114.05,430.69L114.05,430.69z M165.59,418.56c0-7.54-3.98-12.85-11.98-12.85
c-2.86,0-6.42,0.71-9.64,2.39v33.34h3.57v-10.14c1.38,0.66,3.26,1.27,5.86,1.27C161.76,432.58,165.59,426.72,165.59,418.56
L165.59,418.56z M147.54,428.09V410.3c1.53-0.87,3.57-1.48,5.91-1.48c5.91,0,8.41,4.38,8.41,9.79c0,6.98-2.96,10.91-8.82,10.91
C150.6,429.52,148.92,428.81,147.54,428.09L147.54,428.09z M192.96,427.84c-2.4,1.02-5.1,1.68-7.7,1.68
c-5.81,0-9.48-3.11-9.79-9.63h18.35c0.1-0.92,0.15-1.89,0.15-3.01c0-6.22-3.62-11.16-10.4-11.16c-7.34,0-11.77,5.61-11.77,13.41
c0,8.77,5.2,13.51,13.2,13.51c3.21,0,6.12-0.61,8.61-1.78L192.96,427.84L192.96,427.84z M183.58,408.77c4.89,0,6.88,3.72,6.88,7.6
c0,0.41,0,0.61-0.05,0.97h-14.88C175.99,412.24,178.79,408.77,183.58,408.77L183.58,408.77z M205.55,406.33h-3.57v25.69h3.57
V406.33L205.55,406.33z M203.77,400.98c1.53,0,2.4-1.07,2.4-2.45c0-1.33-0.87-2.35-2.4-2.35c-1.53,0-2.4,1.02-2.4,2.35
C201.37,399.9,202.24,400.98,203.77,400.98L203.77,400.98z M225.89,405.72c-7.85,0-12.29,5.51-12.29,13.66
c0,8.41,4.64,13.25,12.9,13.25c2.55,0,5.15-0.66,6.98-1.63l-0.71-2.96c-1.89,0.92-4.03,1.48-6.12,1.48
c-6.17,0-9.38-3.57-9.38-10.19c0-6.37,3.01-10.5,8.82-10.5c2.14,0,4.43,0.56,6.37,1.32l0.76-2.9
C231.4,406.38,228.8,405.72,225.89,405.72L225.89,405.72z M244.24,432.02v-21.26c2.04-1.22,4.38-1.94,7.14-1.94
c4.54,0,6.73,2.5,6.73,6.52v16.67h3.57V415.1c0-5.81-3.57-9.38-9.94-9.38c-3.21,0-5.45,0.82-7.49,1.89v-12.49l-3.57,0.25v36.65
H244.24L244.24,432.02z M290.42,427.84c-2.4,1.02-5.1,1.68-7.7,1.68c-5.81,0-9.48-3.11-9.79-9.63h18.35
c0.1-0.92,0.15-1.89,0.15-3.01c0-6.22-3.62-11.16-10.4-11.16c-7.34,0-11.78,5.61-11.78,13.41c0,8.77,5.2,13.51,13.2,13.51
c3.21,0,6.12-0.61,8.61-1.78L290.42,427.84L290.42,427.84z M281.05,408.77c4.89,0,6.88,3.72,6.88,7.6c0,0.41,0,0.61-0.05,0.97
h-14.88C273.45,412.24,276.25,408.77,281.05,408.77L281.05,408.77z M299.45,408.32v23.7h3.57v-21.46c1.78-1.02,4.23-1.73,7.34-1.73
c0.61,0,1.48,0.05,2.14,0.25l0.51-3.11c-0.87-0.15-1.73-0.25-2.85-0.25C306.02,405.72,302.15,406.79,299.45,408.32L299.45,408.32z
M322.44,432.02v-21.46c2.19-1.17,4.69-1.73,7.24-1.73c4.59,0,6.63,2.55,6.63,6.47v16.72h3.57V415.1c0-5.81-3.31-9.38-10.2-9.38
c-3.98,0-7.7,1.02-10.81,2.6v23.7H322.44L322.44,432.02z M402.21,432.02V415.1c0-5.56-3.11-9.38-9.89-9.38
c-3.62,0-6.63,1.17-9.12,2.65c-1.63-1.68-4.03-2.65-7.29-2.65c-3.82,0-7.39,1.02-10.45,2.6v23.7h3.57v-21.46
c2.09-1.17,4.43-1.73,6.78-1.73c4.64,0,6.27,2.75,6.27,6.47v16.72h3.52v-16.46c0-1.68-0.26-3.16-0.71-4.49
c1.89-1.27,4.64-2.24,7.34-2.24c4.59,0,6.42,2.75,6.42,6.47v16.72H402.21L402.21,432.02z M415.21,406.33h-3.57v25.69h3.57V406.33
L415.21,406.33z M413.42,400.98c1.53,0,2.4-1.07,2.4-2.45c0-1.33-0.87-2.35-2.4-2.35c-1.53,0-2.4,1.02-2.4,2.35
C411.03,399.9,411.89,400.98,413.42,400.98L413.42,400.98z M436.67,432.12l-0.26-3.01c-0.87,0.25-2.09,0.41-3.11,0.41
c-2.75,0-4.38-1.27-4.38-5.05v-15.14h6.93v-3.01h-6.93v-6.32l-3.57,0.26v6.07h-3.87v3.01h3.87v15.14c0,5.96,3.01,8.16,7.49,8.16
C434.32,432.63,435.49,432.43,436.67,432.12L436.67,432.12z M457.31,430.69c2.55,1.07,6.32,1.94,10.5,1.94
c6.47,0,12.13-2.7,12.13-9.69c0-7.03-5-9.02-11.06-11.01c-4.79-1.53-7.54-2.91-7.54-7.04c0-3.82,2.55-5.91,7.9-5.91
c2.45,0,5.15,0.61,7.54,1.38l0.76-3.11c-2.24-0.87-5.71-1.53-8.56-1.53c-6.98,0-11.42,3.21-11.42,9.23c0,5.71,3.52,8.21,9.53,10.14
c5.45,1.68,9.07,3.11,9.07,7.85c0,4.38-3.26,6.42-8.46,6.42c-3.98,0-7.29-1.07-9.69-1.94L457.31,430.69L457.31,430.69z
M495.28,429.78c-3.98,0-6.37-1.58-6.37-4.79c0-3.82,2.85-5.1,6.68-5.1c2.29,0,4.13,0.36,5.81,0.71v7.75
C500.28,429.06,498.34,429.78,495.28,429.78L495.28,429.78z M504.92,430.24V415.2c0-6.12-3.31-9.48-9.94-9.48
c-2.9,0-5.96,0.61-7.95,1.48l0.82,2.96c1.89-0.81,4.38-1.32,6.88-1.32c4.64,0,6.68,2.29,6.68,6.22V418
c-1.84-0.41-4.08-0.71-6.17-0.71c-5.45,0.05-9.89,2.29-9.89,7.8c0,4.43,3.31,7.55,9.63,7.55
C499.51,432.63,502.67,431.56,504.92,430.24L504.92,430.24z M517.66,395.11l-3.57,0.25v29.41c0,5.15,2.09,7.85,6.47,7.85
c0.71,0,1.63-0.15,2.29-0.31l-0.31-2.91c-0.36,0.05-0.87,0.15-1.48,0.15c-2.6,0-3.41-1.63-3.41-4.84V395.11L517.66,395.11z
M527.4,406.33v3.01h14.53c-3.62,6.47-9.18,13.41-15.39,20.14v2.55h20.14v-3.01h-15.65c6.07-6.63,11.01-13.15,14.89-20.14v-2.55
H527.4L527.4,406.33z M558.08,396.34h-4.03v12.13c0,3.31,0.2,7.39,0.61,11.98h2.8c0.41-4.64,0.61-8.61,0.61-11.93V396.34
L558.08,396.34z M558.44,430.03c0-1.33-0.87-2.29-2.29-2.29c-1.53,0-2.4,0.97-2.4,2.29s0.87,2.35,2.4,2.35
C557.57,432.38,558.44,431.36,558.44,430.03L558.44,430.03z"/>
<path class="st0" d="M305.72,269.82v-65.28c5.44-2.72,12-4.16,18.72-4.16c12.16,0,18.08,6.72,18.08,18.4v51.04h16.16v-52.16
c0-19.52-11.84-30.88-34.24-30.88c-12.32,0-24.96,2.88-34.88,7.52v75.52H305.72L305.72,269.82z M399,269.82v-65.28
c5.44-2.72,12-4.16,18.72-4.16c12.16,0,18.08,6.72,18.08,18.4v51.04h16.16v-52.16c0-19.52-11.84-30.88-34.24-30.88
c-12.32,0-24.96,2.88-34.88,7.52v75.52H399L399,269.82z M547.32,229.18c0-25.28-14.08-42.4-38.08-42.4
c-23.68,0-37.92,17.12-37.92,42.4c0,25.44,14.24,42.56,37.92,42.56C533.24,271.74,547.32,254.62,547.32,229.18L547.32,229.18z
M487.8,229.18c0-17.44,7.36-28.8,21.44-28.8c14.56,0,21.44,11.36,21.44,28.8c0,17.6-6.88,28.96-21.44,28.96
C495.16,258.14,487.8,246.78,487.8,229.18L487.8,229.18z M575.8,188.7h-16.32c3.2,31.2,11.84,53.12,28.16,81.12h17.92
c16-28,24.32-49.92,28.16-81.12h-16.16c-2.56,27.36-9.92,47.2-20.96,67.68C585.88,235.9,578.68,216.06,575.8,188.7L575.8,188.7z"/>
<path class="st1" d="M307.68,360.51c-7.2,3.04-15.36,4.96-23.36,4.96c-15.68,0-25.44-7.84-27.04-24.96h54.56
c0.32-3.04,0.64-6.56,0.64-10.72c0-20.32-12.48-35.52-33.6-35.52c-23.36,0-38.24,17.44-38.24,42.4c0,27.04,16.8,42.56,42.24,42.56
c10.4,0,20-2.08,27.52-5.6L307.68,360.51L307.68,360.51z M278.88,307.55c12.32,0,17.92,9.28,17.92,20c0,0.96,0,1.6-0.16,2.56h-39.2
C258.88,316.35,266.4,307.55,278.88,307.55L278.88,307.55z M348.07,377.31v-65.28c5.44-2.72,12-4.16,18.72-4.16
c12.16,0,18.08,6.72,18.08,18.4v51.04h16.16v-52.16c0-19.52-11.84-30.88-34.24-30.88c-12.32,0-24.96,2.88-34.88,7.52v75.52H348.07
L348.07,377.31z M487.43,360.51c-7.2,3.04-15.36,4.96-23.36,4.96c-15.68,0-25.44-7.84-27.04-24.96h54.56
c0.32-3.04,0.64-6.56,0.64-10.72c0-20.32-12.48-35.52-33.6-35.52c-23.36,0-38.24,17.44-38.24,42.4c0,27.04,16.8,42.56,42.24,42.56
c10.4,0,20-2.08,27.52-5.6L487.43,360.51L487.43,360.51z M458.63,307.55c12.32,0,17.92,9.28,17.92,20c0,0.96,0,1.6-0.16,2.56h-39.2
C438.63,316.35,446.15,307.55,458.63,307.55L458.63,307.55z M512.71,301.95v75.36h16.16v-65.28c4.48-2.4,10.56-4.16,18.56-4.16
c2.56,0,5.6,0.32,8,1.12l2.24-13.6c-2.88-0.64-6.88-1.12-11.36-1.12C533.99,294.27,521.03,297.31,512.71,301.95L512.71,301.95z
M636.05,375.07v-74.4c-7.04-3.36-17.92-6.4-29.92-6.4c-24.8,0-41.12,15.84-41.12,41.44c0,24.32,14.4,38.24,37.28,38.24
c6.72,0,12.64-1.6,17.6-4.16v6.72c0,11.04-7.52,17.6-21.76,17.6c-8.48,0-15.36-1.28-22.4-4l-3.36,13.12
c8.16,3.2,15.2,4.64,26.72,4.64C621.81,407.87,636.05,396.35,636.05,375.07L636.05,375.07z M581.49,334.43
c0-16.48,9.44-26.56,24.64-26.56c5.12,0,10.24,1.28,13.76,2.56v45.6c-4,2.56-8.96,4.16-15.36,4.16
C589.97,360.19,581.49,350.43,581.49,334.43L581.49,334.43z M700.69,372.83c12.8-22.88,22.56-47.68,25.76-76.64h-16.16
c-2.4,27.36-8.48,45.12-18.56,65.28c-11.04-18.56-19.36-37.92-21.92-65.28h-16.32c3.36,30.72,12.64,53.44,29.76,77.76
c-6.24,10.4-16.96,16.96-27.36,19.04l2.72,13.92C674.45,403.71,688.53,394.11,700.69,372.83L700.69,372.83z"/>
<polygon class="st0" points="263.6,188.59 247.44,188.59 247.44,269.71 263.6,269.71 263.6,188.59 "/>
<path class="st1" d="M255.44,174.51c6.24,0,9.92-4,9.92-9.92c0-5.6-3.68-9.6-9.92-9.6c-6.4,0-10.08,4-10.08,9.6
C245.36,170.51,249.04,174.51,255.44,174.51L255.44,174.51z"/>
<path class="st0" d="M666.38,255.96c0,8.32-4.87,12.94-12.92,12.94c-8.12,0-12.85-4.62-12.85-12.94c0-8.25,4.73-12.94,12.85-12.94
C661.51,243.03,666.38,247.71,666.38,255.96L666.38,255.96z M637.36,255.96c0,9.51,6.29,15.78,16.1,15.78
c9.61,0,16.17-6.27,16.17-15.78s-6.49-15.78-16.17-15.78C643.72,240.19,637.36,246.46,637.36,255.96L637.36,255.96z M647.78,263.69
h3.11v-5.81h2.37c1.02,1.98,2.23,3.96,3.79,5.81h3.79c-1.83-2.18-3.31-4.23-4.4-6.27c2.23-0.73,3.25-2.38,3.25-4.62
c0-3.1-2.03-5.15-6.49-5.15h-5.41V263.69L647.78,263.69z M653.19,250.15c2.3,0,3.52,0.79,3.52,2.64c0,1.85-1.22,2.64-3.52,2.64
h-2.3v-5.28H653.19L653.19,250.15z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -18,7 +18,7 @@ function Footer() {
> >
<Box> <Box>
<Typography variant="subtitle1"> <Typography variant="subtitle1">
&copy; 2024 - Inesco Energy Solutions AG &copy; 2024 - InnovEnergy AG
</Typography> </Typography>
</Box> </Box>
<Typography <Typography
@ -33,7 +33,7 @@ function Footer() {
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
Inesco Energy Solutions AG InnovEnergy AG
</Link> </Link>
</Typography> </Typography>
</Box> </Box>

View File

@ -3,11 +3,14 @@ import {
Box, Box,
Button, Button,
CircularProgress, CircularProgress,
Container,
Grid,
Modal, Modal,
TextField, TextField,
Typography, Typography,
useTheme useTheme
} from '@mui/material'; } from '@mui/material';
import innovenergyLogo from 'src/Resources/innoveng_logo_on_orange.png';
import { UserContext } from 'src/contexts/userContext'; import { UserContext } from 'src/contexts/userContext';
import { TokenContext } from 'src/contexts/tokenContext'; import { TokenContext } from 'src/contexts/tokenContext';
import Avatar from '@mui/material/Avatar'; import Avatar from '@mui/material/Avatar';
@ -15,7 +18,6 @@ import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
import axiosConfig from 'src/Resources/axiosConfig'; import axiosConfig from 'src/Resources/axiosConfig';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import routes from 'src/Resources/routes.json'; import routes from 'src/Resources/routes.json';
import inescologo from '../Resources/images/Logo.svg';
interface ForgotPasswordPromps { interface ForgotPasswordPromps {
resetPassword: () => void; resetPassword: () => void;
@ -71,6 +73,16 @@ function ForgotPassword() {
return ( return (
<> <>
<Container maxWidth="xl" sx={{ pt: 2 }}>
<Grid container>
<Grid item xs={3} container justifyContent="flex-start" mb={2}>
<a href="https://monitor.innov.energy/">
<img src={innovenergyLogo} alt="innovenergy logo" height="100" />
</a>
</Grid>
</Grid>
</Container>
<Box <Box
sx={{ sx={{
marginTop: 8, marginTop: 8,
@ -88,12 +100,7 @@ function ForgotPassword() {
transform: 'translate(-50%, -50%)' transform: 'translate(-50%, -50%)'
}} }}
> >
<Box sx={{ display: 'flex', justifyContent: 'center', mb: 2 }}> <Avatar sx={{ m: 1, bgcolor: '#ffc04d' }}>
<a href="https://monitor.innov.energy/">
<img src={inescologo} alt="inescologo" height="100" />
</a>
</Box>
<Avatar sx={{ m: 1, bgcolor: '#00b33c' }}>
<LockOutlinedIcon /> <LockOutlinedIcon />
</Avatar> </Avatar>
<Typography component="h1" variant="h5"> <Typography component="h1" variant="h5">
@ -127,15 +134,15 @@ function ForgotPassword() {
}} }}
/> />
{loading && <CircularProgress sx={{ color: '#00b33c' }} />} {loading && <CircularProgress sx={{ color: '#ffc04d' }} />}
<Button <Button
sx={{ sx={{
mt: 3, mt: 3,
mb: 2, mb: 2,
textTransform: 'none', textTransform: 'none',
bgcolor: '#00b33c', bgcolor: '#ffc04d',
'&:hover': { bgcolor: '#009933' } '&:hover': { bgcolor: '#f7b34d' }
}} }}
variant="contained" variant="contained"
fullWidth={true} fullWidth={true}
@ -174,9 +181,9 @@ function ForgotPassword() {
sx={{ sx={{
marginTop: 2, marginTop: 2,
textTransform: 'none', textTransform: 'none',
bgcolor: '#00b33c', bgcolor: '#ffc04d',
color: '#111111', color: '#111111',
'&:hover': { bgcolor: '#009933' } '&:hover': { bgcolor: '#f7b34d' }
}} }}
onClick={() => setErrorModalOpen(false)} onClick={() => setErrorModalOpen(false)}
> >
@ -214,9 +221,9 @@ function ForgotPassword() {
sx={{ sx={{
marginTop: 2, marginTop: 2,
textTransform: 'none', textTransform: 'none',
bgcolor: '#00b33c', bgcolor: '#ffc04d',
color: '#111111', color: '#111111',
'&:hover': { bgcolor: '#009933' } '&:hover': { bgcolor: '#f7b34d' }
}} }}
onClick={handleReturn} onClick={handleReturn}
> >

View File

@ -3,18 +3,20 @@ import {
Box, Box,
Button, Button,
CircularProgress, CircularProgress,
Container,
Grid,
Modal, Modal,
TextField, TextField,
Typography, Typography,
useTheme useTheme
} from '@mui/material'; } from '@mui/material';
import innovenergyLogo from 'src/Resources/innoveng_logo_on_orange.png';
import axiosConfig from 'src/Resources/axiosConfig'; import axiosConfig from 'src/Resources/axiosConfig';
import { UserContext } from 'src/contexts/userContext'; import { UserContext } from 'src/contexts/userContext';
import { TokenContext } from 'src/contexts/tokenContext'; import { TokenContext } from 'src/contexts/tokenContext';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import Avatar from '@mui/material/Avatar'; import Avatar from '@mui/material/Avatar';
import LockOutlinedIcon from '@mui/icons-material/LockOutlined'; import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
import inescologo from '../Resources/images/Logo.svg';
function ResetPassword() { function ResetPassword() {
const [username, setUsername] = useState(''); const [username, setUsername] = useState('');
@ -68,6 +70,16 @@ function ResetPassword() {
return ( return (
<> <>
<Container maxWidth="xl" sx={{ pt: 2 }}>
<Grid container>
<Grid item xs={3} container justifyContent="flex-start" mb={2}>
<a href="https://monitor.innov.energy/">
<img src={innovenergyLogo} alt="innovenergy logo" height="100" />
</a>
</Grid>
</Grid>
</Container>
<Box <Box
sx={{ sx={{
marginTop: 8, marginTop: 8,
@ -85,12 +97,7 @@ function ResetPassword() {
transform: 'translate(-50%, -50%)' transform: 'translate(-50%, -50%)'
}} }}
> >
<Box sx={{ display: 'flex', justifyContent: 'center', mb: 2 }}> <Avatar sx={{ m: 1, bgcolor: '#ffc04d' }}>
<a href="https://monitor.innov.energy/">
<img src={inescologo} alt="inescologo" height="100" />
</a>
</Box>
<Avatar sx={{ m: 1, bgcolor: '#00b33c' }}>
<LockOutlinedIcon /> <LockOutlinedIcon />
</Avatar> </Avatar>
<Typography component="h1" variant="h5"> <Typography component="h1" variant="h5">
@ -130,7 +137,7 @@ function ResetPassword() {
/> />
{loading && ( {loading && (
<CircularProgress sx={{ color: '#00b33c', marginLeft: '170px' }} /> <CircularProgress sx={{ color: '#ffc04d', marginLeft: '170px' }} />
)} )}
{password != verifypassword && ( {password != verifypassword && (
@ -148,8 +155,8 @@ function ResetPassword() {
mt: 3, mt: 3,
mb: 2, mb: 2,
textTransform: 'none', textTransform: 'none',
bgcolor: '#00b33c', bgcolor: '#ffc04d',
'&:hover': { bgcolor: '#009933' } '&:hover': { bgcolor: '#f7b34d' }
}} }}
variant="contained" variant="contained"
fullWidth={true} fullWidth={true}
@ -188,9 +195,9 @@ function ResetPassword() {
sx={{ sx={{
marginTop: 2, marginTop: 2,
textTransform: 'none', textTransform: 'none',
bgcolor: '#00b33c', bgcolor: '#ffc04d',
color: '#111111', color: '#111111',
'&:hover': { bgcolor: '#009933' } '&:hover': { bgcolor: '#f7b34d' }
}} }}
onClick={() => setOpen(false)} onClick={() => setOpen(false)}
> >

View File

@ -3,18 +3,20 @@ import {
Box, Box,
Button, Button,
CircularProgress, CircularProgress,
Container,
Grid,
Modal, Modal,
TextField, TextField,
Typography, Typography,
useTheme useTheme
} from '@mui/material'; } from '@mui/material';
import innovenergyLogo from 'src/Resources/innoveng_logo_on_orange.png';
import axiosConfig from 'src/Resources/axiosConfig'; import axiosConfig from 'src/Resources/axiosConfig';
import { UserContext } from 'src/contexts/userContext'; import { UserContext } from 'src/contexts/userContext';
import { TokenContext } from 'src/contexts/tokenContext'; import { TokenContext } from 'src/contexts/tokenContext';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import Avatar from '@mui/material/Avatar'; import Avatar from '@mui/material/Avatar';
import LockOutlinedIcon from '@mui/icons-material/LockOutlined'; import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
import inescologo from '../Resources/images/Logo.svg';
function SetNewPassword() { function SetNewPassword() {
const [username, setUsername] = useState(''); const [username, setUsername] = useState('');
@ -69,6 +71,16 @@ function SetNewPassword() {
return ( return (
<> <>
<Container maxWidth="xl" sx={{ pt: 2 }}>
<Grid container>
<Grid item xs={3} container justifyContent="flex-start" mb={2}>
<a href="https://monitor.innov.energy/">
<img src={innovenergyLogo} alt="innovenergy logo" height="100" />
</a>
</Grid>
</Grid>
</Container>
<Box <Box
sx={{ sx={{
marginTop: 8, marginTop: 8,
@ -86,12 +98,7 @@ function SetNewPassword() {
transform: 'translate(-50%, -50%)' transform: 'translate(-50%, -50%)'
}} }}
> >
<Box sx={{ display: 'flex', justifyContent: 'center', mb: 2 }}> <Avatar sx={{ m: 1, bgcolor: '#ffc04d' }}>
<a href="https://monitor.innov.energy/">
<img src={inescologo} alt="inescologo" height="100" />
</a>
</Box>
<Avatar sx={{ m: 1, bgcolor: '#00b33c' }}>
<LockOutlinedIcon /> <LockOutlinedIcon />
</Avatar> </Avatar>
<Typography component="h1" variant="h5"> <Typography component="h1" variant="h5">
@ -131,7 +138,7 @@ function SetNewPassword() {
/> />
{loading && ( {loading && (
<CircularProgress sx={{ color: '#00b33c', marginLeft: '0px' }} /> <CircularProgress sx={{ color: '#ffc04d', marginLeft: '0px' }} />
)} )}
{password != verifypassword && ( {password != verifypassword && (
@ -149,8 +156,8 @@ function SetNewPassword() {
mt: 3, mt: 3,
mb: 2, mb: 2,
textTransform: 'none', textTransform: 'none',
bgcolor: '#00b33c', bgcolor: '#ffc04d',
'&:hover': { bgcolor: '#009933' } '&:hover': { bgcolor: '#f7b34d' }
}} }}
variant="contained" variant="contained"
fullWidth={true} fullWidth={true}
@ -189,9 +196,9 @@ function SetNewPassword() {
sx={{ sx={{
marginTop: 2, marginTop: 2,
textTransform: 'none', textTransform: 'none',
bgcolor: '#00b33c', bgcolor: '#ffc04d',
color: '#111111', color: '#111111',
'&:hover': { bgcolor: '#009933' } '&:hover': { bgcolor: '#f7b34d' }
}} }}
onClick={() => setOpen(false)} onClick={() => setOpen(false)}
> >

View File

@ -4,6 +4,7 @@ import {
Button, Button,
Checkbox, Checkbox,
CircularProgress, CircularProgress,
Container,
FormControlLabel, FormControlLabel,
Grid, Grid,
Modal, Modal,
@ -14,7 +15,7 @@ import {
import Avatar from '@mui/material/Avatar'; import Avatar from '@mui/material/Avatar';
import LockOutlinedIcon from '@mui/icons-material/LockOutlined'; import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
import Link from '@mui/material/Link'; import Link from '@mui/material/Link';
import inescologo from 'src/Resources/images/Logo.svg'; import innovenergyLogo from 'src/Resources/innoveng_logo_on_orange.png';
import { axiosConfigWithoutToken } from 'src/Resources/axiosConfig'; import { axiosConfigWithoutToken } from 'src/Resources/axiosConfig';
import Cookies from 'universal-cookie'; import Cookies from 'universal-cookie';
import { UserContext } from 'src/contexts/userContext'; import { UserContext } from 'src/contexts/userContext';
@ -101,6 +102,16 @@ function Login() {
return ( return (
<div style={{ userSelect: 'none' }}> <div style={{ userSelect: 'none' }}>
<Container maxWidth="xl" sx={{ pt: 2 }} className="login">
<Grid container>
<Grid item xs={3} container justifyContent="flex-start" mb={2}>
<a href="https://monitor.innov.energy/">
<img src={innovenergyLogo} alt="innovenergy logo" height="100" />
</a>
</Grid>
</Grid>
</Container>
<Box <Box
sx={{ sx={{
marginTop: 8, marginTop: 8,
@ -118,12 +129,7 @@ function Login() {
transform: 'translate(-50%, -50%)' transform: 'translate(-50%, -50%)'
}} }}
> >
<Box sx={{ display: 'flex', justifyContent: 'center', mb: 2 }}> <Avatar sx={{ m: 1, bgcolor: '#ffc04d' }}>
<a href="https://monitor.innov.energy/">
<img src={inescologo} alt="inescologo" height="100" />
</a>
</Box>
<Avatar sx={{ m: 1, bgcolor: '#00b33c' }}>
<LockOutlinedIcon /> <LockOutlinedIcon />
</Avatar> </Avatar>
<Typography component="h1" variant="h5"> <Typography component="h1" variant="h5">
@ -179,7 +185,7 @@ function Login() {
checked={rememberMe} checked={rememberMe}
onChange={handleRememberMeChange} onChange={handleRememberMeChange}
icon={<CheckBoxOutlineBlankIcon style={{ color: 'grey' }} />} icon={<CheckBoxOutlineBlankIcon style={{ color: 'grey' }} />}
checkedIcon={<CheckBoxIcon style={{ color: '#00b33c' }} />} checkedIcon={<CheckBoxIcon style={{ color: '#ffc04d' }} />}
style={{ marginLeft: -175 }} style={{ marginLeft: -175 }}
/> />
} }
@ -190,8 +196,8 @@ function Login() {
sx={{ sx={{
mb: 2, mb: 2,
textTransform: 'none', textTransform: 'none',
bgcolor: '#00b33c', bgcolor: '#ffc04d',
'&:hover': { bgcolor: '#009933' } '&:hover': { bgcolor: '#f7b34d' }
}} }}
variant="contained" variant="contained"
fullWidth={true} fullWidth={true}
@ -204,7 +210,7 @@ function Login() {
{loading && ( {loading && (
<CircularProgress <CircularProgress
sx={{ sx={{
color: '#009933', color: '#ffc04d',
marginLeft: '20px' marginLeft: '20px'
}} }}
/> />
@ -239,9 +245,9 @@ function Login() {
sx={{ sx={{
marginTop: 2, marginTop: 2,
textTransform: 'none', textTransform: 'none',
bgcolor: '#00b33c', bgcolor: '#ffc04d',
color: '#111111', color: '#111111',
'&:hover': { bgcolor: '#009933' } '&:hover': { bgcolor: '#f7b34d' }
}} }}
onClick={() => setOpen(false)} onClick={() => setOpen(false)}
> >

View File

@ -390,11 +390,7 @@ function InstallationTabs() {
return salimaxInstallations.length > 1 ? ( return salimaxInstallations.length > 1 ? (
<> <>
<Container <Container maxWidth="xl" sx={{ marginTop: '20px' }} className="mainframe">
maxWidth="xl"
sx={{ marginLeft: '40px', marginTop: '20px' }}
className="mainframe"
>
<TabsContainerWrapper> <TabsContainerWrapper>
<Tabs <Tabs
onChange={handleTabsChange} onChange={handleTabsChange}
@ -456,11 +452,7 @@ function InstallationTabs() {
</> </>
) : salimaxInstallations.length === 1 ? ( ) : salimaxInstallations.length === 1 ? (
<> <>
<Container <Container maxWidth="xl" sx={{ marginTop: '20px' }} className="mainframe">
maxWidth="xl"
sx={{ marginLeft: '40px', marginTop: '20px' }}
className="mainframe"
>
<TabsContainerWrapper> <TabsContainerWrapper>
<Tabs <Tabs
onChange={handleTabsChange} onChange={handleTabsChange}

View File

@ -129,210 +129,215 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
{sortedInstallations.map((installation) => { {sortedInstallations
const isInstallationSelected = .filter(
installation.s3BucketId === selectedInstallation; (installation) =>
installation.status === -1 && installation.device === 1
)
.map((installation) => {
const isInstallationSelected =
installation.s3BucketId === selectedInstallation;
const status = installation.status; const status = installation.status;
return ( return (
<HoverableTableRow <HoverableTableRow
key={installation.s3BucketId} key={installation.s3BucketId}
onClick={() => onClick={() =>
handleSelectOneInstallation(installation.s3BucketId) handleSelectOneInstallation(installation.s3BucketId)
} }
> >
<TableCell> <TableCell>
<Typography <Typography
variant="body2" variant="body2"
fontWeight="bold" fontWeight="bold"
color="text.primary" color="text.primary"
gutterBottom gutterBottom
noWrap noWrap
sx={{ marginTop: '10px', fontSize: 'small' }} sx={{ marginTop: '10px', fontSize: 'small' }}
>
{installation.name}
</Typography>
</TableCell>
<TableCell>
<Typography
variant="body2"
fontWeight="bold"
color="text.primary"
gutterBottom
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
{installation.location}
</Typography>
</TableCell>
<TableCell>
<Typography
variant="body2"
fontWeight="bold"
color="text.primary"
gutterBottom
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
{installation.region}
</Typography>
</TableCell>
<TableCell>
<Typography
variant="body2"
fontWeight="bold"
color="text.primary"
gutterBottom
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
{installation.country}
</Typography>
</TableCell>
<TableCell>
<Typography
variant="body2"
fontWeight="bold"
color="text.primary"
gutterBottom
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
<a
href={
'https://vrm.victronenergy.com/installation/' +
installation.vrmLink +
'/dashboard'
}
target="_blank"
rel="noopener noreferrer"
style={{
display: 'inline-block',
padding: '0'
}} // Style the link
onClick={(e) => e.stopPropagation()} // Prevent the click event from bubbling up to the table row
> >
VRM link {installation.name}
</a> </Typography>
</Typography> </TableCell>
</TableCell>
<TableCell> <TableCell>
<div <Typography
style={{ variant="body2"
display: 'flex', fontWeight="bold"
alignItems: 'center', color="text.primary"
marginLeft: '5px' gutterBottom
}} noWrap
> sx={{ marginTop: '10px', fontSize: 'small' }}
{installation.device === 1 ? ( >
<Typography {installation.location}
variant="body2" </Typography>
fontWeight="bold" </TableCell>
color="text.primary"
gutterBottom
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
Cerbo
</Typography>
) : installation.device === 2 ? (
<Typography
variant="body2"
fontWeight="bold"
color="text.primary"
gutterBottom
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
Venus
</Typography>
) : (
<Typography
variant="body2"
fontWeight="bold"
color="text.primary"
gutterBottom
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
Device not specified
</Typography>
)}
</div>
</TableCell>
<TableCell> <TableCell>
<div <Typography
style={{ variant="body2"
display: 'flex', fontWeight="bold"
alignItems: 'center', color="text.primary"
marginLeft: '15px' gutterBottom
}} noWrap
> sx={{ marginTop: '10px', fontSize: 'small' }}
{status === -1 ? ( >
<CancelIcon {installation.region}
</Typography>
</TableCell>
<TableCell>
<Typography
variant="body2"
fontWeight="bold"
color="text.primary"
gutterBottom
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
{installation.country}
</Typography>
</TableCell>
<TableCell>
<Typography
variant="body2"
fontWeight="bold"
color="text.primary"
gutterBottom
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
<a
href={
'https://vrm.victronenergy.com/installation/' +
installation.vrmLink +
'/dashboard'
}
target="_blank"
rel="noopener noreferrer"
style={{ style={{
width: '23px', display: 'inline-block',
height: '23px', padding: '0'
color: 'red', }} // Style the link
borderRadius: '50%' onClick={(e) => e.stopPropagation()} // Prevent the click event from bubbling up to the table row
}} >
/> VRM link
) : ( </a>
'' </Typography>
)} </TableCell>
{status === -2 ? (
<CircularProgress
size={20}
sx={{
color: '#f7b34d'
}}
/>
) : (
''
)}
<TableCell>
<div <div
style={{ style={{
width: '20px', display: 'flex',
height: '20px', alignItems: 'center',
marginLeft: '2px', marginLeft: '5px'
borderRadius: '50%',
backgroundColor:
status === 2
? 'red'
: status === 1
? 'orange'
: status === -1 || status === -2
? 'transparent'
: 'green'
}} }}
/> >
{installation.testingMode && ( {installation.device === 1 ? (
<BuildIcon <Typography
variant="body2"
fontWeight="bold"
color="text.primary"
gutterBottom
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
Cerbo
</Typography>
) : installation.device === 2 ? (
<Typography
variant="body2"
fontWeight="bold"
color="text.primary"
gutterBottom
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
Venus
</Typography>
) : (
<Typography
variant="body2"
fontWeight="bold"
color="text.primary"
gutterBottom
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
Device not specified
</Typography>
)}
</div>
</TableCell>
<TableCell>
<div
style={{
display: 'flex',
alignItems: 'center',
marginLeft: '15px'
}}
>
{status === -1 ? (
<CancelIcon
style={{
width: '23px',
height: '23px',
color: 'red',
borderRadius: '50%'
}}
/>
) : (
''
)}
{status === -2 ? (
<CircularProgress
size={20}
sx={{
color: '#f7b34d'
}}
/>
) : (
''
)}
<div
style={{ style={{
width: '23px', width: '20px',
height: '23px', height: '20px',
color: 'purple', marginLeft: '2px',
borderRadius: '50%', borderRadius: '50%',
position: 'relative', backgroundColor:
zIndex: 1, status === 2
marginLeft: status != -1 ? '25px' : '0px' ? 'red'
: status === 1
? 'orange'
: status === -1 || status === -2
? 'transparent'
: 'green'
}} }}
/> />
)} {installation.testingMode && (
</div> <BuildIcon
</TableCell> style={{
</HoverableTableRow> width: '23px',
); height: '23px',
})} color: 'purple',
borderRadius: '50%',
position: 'relative',
zIndex: 1,
marginLeft: status != -1 ? '25px' : '0px'
}}
/>
)}
</div>
</TableCell>
</HoverableTableRow>
);
})}
</TableBody> </TableBody>
</Table> </Table>
</TableContainer> </TableContainer>

View File

@ -276,11 +276,7 @@ function SalidomoInstallationTabs() {
return salidomoInstallations.length > 1 ? ( return salidomoInstallations.length > 1 ? (
<> <>
<Container <Container maxWidth="xl" sx={{ marginTop: '20px' }} className="mainframe">
maxWidth="xl"
sx={{ marginLeft: '40px', marginTop: '20px' }}
className="mainframe"
>
<TabsContainerWrapper> <TabsContainerWrapper>
<Tabs <Tabs
onChange={handleTabsChange} onChange={handleTabsChange}
@ -346,11 +342,7 @@ function SalidomoInstallationTabs() {
) : salidomoInstallations.length === 1 ? ( ) : salidomoInstallations.length === 1 ? (
<> <>
{' '} {' '}
<Container <Container maxWidth="xl" sx={{ marginTop: '20px' }} className="mainframe">
maxWidth="xl"
sx={{ marginLeft: '40px', marginTop: '20px' }}
className="mainframe"
>
<TabsContainerWrapper> <TabsContainerWrapper>
<Tabs <Tabs
onChange={handleTabsChange} onChange={handleTabsChange}

View File

@ -1,6 +1,7 @@
import { useContext } from 'react'; import { useContext } from 'react';
import Scrollbar from 'src/components/Scrollbar'; import Scrollbar from 'src/components/Scrollbar';
import { SidebarContext } from 'src/contexts/SidebarContext'; import { SidebarContext } from 'src/contexts/SidebarContext';
import innovenergyLogo from 'src/Resources/images/innovenergy-Logo_Speichern-mit-Salz_R_color.svg';
import { import {
alpha, alpha,
Box, Box,
@ -13,11 +14,10 @@ import {
} from '@mui/material'; } from '@mui/material';
import SidebarMenu from './SidebarMenu'; import SidebarMenu from './SidebarMenu';
import Logo from 'src/Resources/images/Logo_for_dark_bg.svg';
const SidebarWrapper = styled(Box)( const SidebarWrapper = styled(Box)(
({ theme }) => ` ({ theme }) => `
width : 250px; width: ${theme.sidebar.width};
min-width: ${theme.sidebar.width}; min-width: ${theme.sidebar.width};
color: ${theme.colors.alpha.trueWhite[70]}; color: ${theme.colors.alpha.trueWhite[70]};
position: relative; position: relative;
@ -60,11 +60,10 @@ function Sidebar() {
}} }}
> >
<img <img
src={Logo} src={innovenergyLogo}
alt="inesco logo" alt="innovenergy logo"
style={{ style={{
marginLeft: '30px', width: '150px' // Width of the image
width: '150px'
}} }}
/> />
</Box> </Box>
@ -106,8 +105,8 @@ function Sidebar() {
}} }}
> >
<img <img
src={Logo} src={innovenergyLogo}
alt="innesco logo" alt="innovenergy logo"
style={{ style={{
width: '150px' // Width of the image width: '150px' // Width of the image
}} }}