Update SodistoreMax code.
Fixed the product to value 3 when sending heartbits. Deleted prints during aggregation Updated backend code to support SodistoreMax
This commit is contained in:
parent
31c06e2815
commit
cf9c96377f
|
|
@ -193,7 +193,8 @@ public class Controller : ControllerBase
|
|||
|
||||
while (startTimestamp <= endTimestamp)
|
||||
{
|
||||
string bucketPath = installation.Product==(int)ProductType.Salimax? "s3://"+installation.S3BucketId + "-3e5b3069-214a-43ee-8d85-57d72000c19d/"+startTimestamp :
|
||||
string bucketPath = installation.Product==(int)ProductType.Salimax || installation.Product==(int)ProductType.SodiStoreMax?
|
||||
"s3://"+installation.S3BucketId + "-3e5b3069-214a-43ee-8d85-57d72000c19d/"+startTimestamp :
|
||||
"s3://"+installation.S3BucketId + "-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e/"+startTimestamp;
|
||||
Console.WriteLine("Fetching data for "+startTimestamp);
|
||||
|
||||
|
|
@ -442,28 +443,41 @@ public class Controller : ControllerBase
|
|||
}
|
||||
|
||||
|
||||
[HttpGet(nameof(GetAllInstallationsFromProduct))]
|
||||
public ActionResult<IEnumerable<Installation>> GetAllInstallationsFromProduct(int product,Token authToken)
|
||||
{
|
||||
var user = Db.GetSession(authToken)?.User;
|
||||
|
||||
if (user is null)
|
||||
return Unauthorized();
|
||||
|
||||
return user
|
||||
.AccessibleInstallations(product)
|
||||
.Select(i => i.FillOrderNumbers().HideParentIfUserHasNoAccessToParent(user).HideWriteKeyIfUserIsNotAdmin(user.UserType))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
[HttpGet(nameof(GetAllInstallations))]
|
||||
public ActionResult<IEnumerable<Installation>> GetAllInstallations(Token authToken)
|
||||
{
|
||||
var user = Db.GetSession(authToken)?.User;
|
||||
|
||||
|
||||
if (user is null)
|
||||
return Unauthorized();
|
||||
|
||||
|
||||
return user
|
||||
.AccessibleInstallations(product:(int)ProductType.Salimax)
|
||||
.Select(i => i.FillOrderNumbers().HideParentIfUserHasNoAccessToParent(user).HideWriteKeyIfUserIsNotAdmin(user.UserType))
|
||||
.ToList();
|
||||
.AccessibleInstallations(product:(int)ProductType.Salimax)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
[HttpGet(nameof(GetAllSalidomoInstallations))]
|
||||
public ActionResult<IEnumerable<Installation>> GetAllSalidomoInstallations(Token authToken)
|
||||
{
|
||||
var user = Db.GetSession(authToken)?.User;
|
||||
|
||||
|
||||
if (user is null)
|
||||
return Unauthorized();
|
||||
|
||||
|
||||
return user
|
||||
.AccessibleInstallations(product:(int)ProductType.Salidomo)
|
||||
.ToList();
|
||||
|
|
@ -473,10 +487,10 @@ public class Controller : ControllerBase
|
|||
public ActionResult<IEnumerable<Installation>> GetAllSodioHomeInstallations(Token authToken)
|
||||
{
|
||||
var user = Db.GetSession(authToken)?.User;
|
||||
|
||||
|
||||
if (user is null)
|
||||
return Unauthorized();
|
||||
|
||||
|
||||
return user
|
||||
.AccessibleInstallations(product:(int)ProductType.SodioHome)
|
||||
.ToList();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ public enum ProductType
|
|||
{
|
||||
Salimax = 0,
|
||||
Salidomo = 1,
|
||||
SodioHome =2
|
||||
SodioHome =2,
|
||||
SodiStoreMax=3
|
||||
}
|
||||
|
||||
public enum StatusType
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ public static class Program
|
|||
RabbitMqManager.StartRabbitMqConsumer().SupressAwaitWarning();
|
||||
WebsocketManager.MonitorSalimaxInstallationTable().SupressAwaitWarning();
|
||||
WebsocketManager.MonitorSalidomoInstallationTable().SupressAwaitWarning();
|
||||
WebsocketManager.MonitorSodistoreInstallationTable().SupressAwaitWarning();
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddProblemDetails(setup =>
|
||||
|
|
|
|||
|
|
@ -78,6 +78,39 @@ public static class WebsocketManager
|
|||
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));
|
||||
}
|
||||
}
|
||||
|
||||
//Inform all the connected websockets regarding installation "installationId"
|
||||
public static void InformWebsocketsForInstallation(Int64 installationId)
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public static class Aggregator
|
|||
dailyAggregatedData.Save("DailyData");
|
||||
if (await dailyAggregatedData.PushToS3())
|
||||
{
|
||||
//DeleteHourlyData("HourlyData",currentTime.ToUnixTime());
|
||||
DeleteHourlyData("HourlyData",currentTime.ToUnixTime());
|
||||
//AggregatedData.DeleteDailyData("DailyData");
|
||||
}
|
||||
|
||||
|
|
@ -86,13 +86,13 @@ public static class Aggregator
|
|||
private static void DeleteHourlyData(String myDirectory, Int64 beforeTimestamp)
|
||||
{
|
||||
var jsonFiles = Directory.GetFiles(myDirectory, "*.json");
|
||||
Console.WriteLine("Delete data before"+beforeTimestamp);
|
||||
//Console.WriteLine("Delete data before"+beforeTimestamp);
|
||||
foreach (var jsonFile in jsonFiles)
|
||||
{
|
||||
if (IsFileWithinTimeRange(jsonFile, 0, beforeTimestamp))
|
||||
{
|
||||
File.Delete(jsonFile);
|
||||
Console.WriteLine($"Deleted hourly data file: {jsonFile}");
|
||||
//Console.WriteLine($"Deleted hourly data file: {jsonFile}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -103,14 +103,10 @@ public static class Aggregator
|
|||
var jsonFiles = Directory.GetFiles(myDirectory, "*.json");
|
||||
var batterySoc = new List<Double>();
|
||||
var pvPowerSum = new List<Double>();
|
||||
var heatingPower = new List<Double>();
|
||||
var gridPowerImport = new List<Double>();
|
||||
var gridPowerExport = new List<Double>();
|
||||
var batteryDischargePower = new List<Double>();
|
||||
var batteryChargePower = new List<Double>();
|
||||
|
||||
|
||||
Console.WriteLine("File timestamp should start after "+ afterTimestamp);
|
||||
|
||||
foreach (var jsonFile in jsonFiles)
|
||||
{
|
||||
|
|
@ -136,7 +132,6 @@ public static class Aggregator
|
|||
|
||||
var jsonObject = JObject.Parse(jsonData);
|
||||
|
||||
//Console.WriteLine(jsonObject);
|
||||
if (jsonObject["Battery"] != null && jsonObject["Battery"]["Soc"] != null)
|
||||
{
|
||||
batterySoc.Add((double)jsonObject["Battery"]["Soc"]);
|
||||
|
|
@ -155,12 +150,10 @@ public static class Aggregator
|
|||
}
|
||||
if (jsonObject["GridMeter"] != null && jsonObject["GridMeter"]["ActivePowerExportT3"] != null)
|
||||
{
|
||||
Console.WriteLine("power export is "+jsonObject["GridMeter"]["ActivePowerExportT3"]);
|
||||
gridPowerExport.Add((double)jsonObject["GridMeter"]["ActivePowerExportT3"]);
|
||||
}
|
||||
if (jsonObject["GridMeter"] != null && jsonObject["GridMeter"]["ActivePowerImportT3"] != null)
|
||||
{
|
||||
Console.WriteLine("power import is "+jsonObject["GridMeter"]["ActivePowerImportT3"]);
|
||||
gridPowerImport.Add((double)jsonObject["GridMeter"]["ActivePowerImportT3"]);
|
||||
}
|
||||
}
|
||||
|
|
@ -234,10 +227,6 @@ public static class Aggregator
|
|||
var batteryDischargePower = new List<Double>();
|
||||
var batteryChargePower = new List<Double>();
|
||||
var heatingPowerAvg = new List<Double>();
|
||||
|
||||
|
||||
|
||||
Console.WriteLine("File timestamp should start after "+ afterTimestamp);
|
||||
|
||||
foreach (var jsonFile in jsonFiles)
|
||||
{
|
||||
|
|
@ -252,7 +241,6 @@ public static class Aggregator
|
|||
try
|
||||
{
|
||||
var jsonData = File.ReadAllText(jsonFile);
|
||||
//Console.WriteLine("Parse file "+jsonFile);
|
||||
|
||||
// Parse JSON into a Dictionary
|
||||
var jsonDict = JsonConvert.DeserializeObject<Dictionary<string, Double>>(jsonData);
|
||||
|
|
@ -286,14 +274,7 @@ public static class Aggregator
|
|||
case "GridImportPower":
|
||||
gridPowerImport.Add(value);
|
||||
break;
|
||||
|
||||
case "HeatingPower":
|
||||
heatingPowerAvg.Add(value);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Ignore unknown variables
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -302,70 +283,6 @@ public static class Aggregator
|
|||
{
|
||||
Console.WriteLine($"Failed to parse JSON file {jsonFile}: {e.Message}");
|
||||
}
|
||||
// using var reader = new StreamReader(csvFile);
|
||||
//
|
||||
// while (!reader.EndOfStream)
|
||||
// {
|
||||
//
|
||||
// var line = reader.ReadLine();
|
||||
// var lines = line?.Split(';');
|
||||
//
|
||||
// // Assuming there are always three columns (variable name and its value)
|
||||
// if (lines is { Length: 3 })
|
||||
// {
|
||||
// var variableName = lines[0].Trim();
|
||||
//
|
||||
// if (TryParse(lines[1].Trim(), out var value))
|
||||
// {
|
||||
// switch (variableName)
|
||||
// {
|
||||
// case "/MinSoc" or "/MaxSoc":
|
||||
// batterySoc.Add(value);
|
||||
// break;
|
||||
//
|
||||
// case "/PvPower":
|
||||
// pvPower.Add(value);
|
||||
// break;
|
||||
//
|
||||
// case "/DischargingBatteryPower" :
|
||||
// batteryDischargePower.Add(value);
|
||||
// break;
|
||||
//
|
||||
// case "/ChargingBatteryPower" :
|
||||
// batteryChargePower.Add(value);
|
||||
// break;
|
||||
//
|
||||
// case "/GridExportPower":
|
||||
// gridPowerExport.Add(value);
|
||||
// break;
|
||||
//
|
||||
// case "/GridImportPower":
|
||||
// gridPowerImport.Add(value);
|
||||
// break;
|
||||
//
|
||||
// case "/HeatingPower":
|
||||
// heatingPowerAvg.Add(value);
|
||||
// break;
|
||||
// // Add more cases as needed
|
||||
// default:
|
||||
// // Code to execute when variableName doesn't match any condition
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //Handle cases where variableValue is not a valid number
|
||||
// // Console.WriteLine(
|
||||
// // $"Invalid numeric value for variable {variableName}:{lines[1].Trim()}");
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // Handle invalid column format
|
||||
// //Console.WriteLine("Invalid format in column");
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -277,10 +277,7 @@ internal static class Program
|
|||
{
|
||||
var s3Bucket = Config.Load().S3?.Bucket;
|
||||
var subscribedNow = false;
|
||||
|
||||
//Every 15 iterations(30 seconds), the installation sends a heartbit message to the queue
|
||||
//_heartBitInterval++;
|
||||
|
||||
|
||||
//When the controller boots, it tries to subscribe to the queue
|
||||
if (_subscribeToQueueForTheFirstTime == false)
|
||||
{
|
||||
|
|
@ -297,16 +294,6 @@ internal static class Program
|
|||
if (s3Bucket != null)
|
||||
RabbitMqManager.InformMiddleware(currentSalimaxState);
|
||||
}
|
||||
// else if (_subscribedToQueue && _heartBitInterval >= 30)
|
||||
// {
|
||||
// //Send a heartbit to the backend
|
||||
// Console.WriteLine("----------------------------------------Sending Heartbit----------------------------------------");
|
||||
// _heartBitInterval = 0;
|
||||
// currentSalimaxState.Type = MessageType.Heartbit;
|
||||
//
|
||||
// if (s3Bucket != null)
|
||||
// RabbitMqManager.InformMiddleware(currentSalimaxState);
|
||||
// }
|
||||
|
||||
//If there is an available message from the RabbitMQ Broker, apply the configuration file
|
||||
Configuration? config = SetConfigurationFile();
|
||||
|
|
@ -498,7 +485,7 @@ internal static class Program
|
|||
var returnedStatus = new StatusMessage
|
||||
{
|
||||
InstallationId = installationId,
|
||||
Product = 0,
|
||||
Product = 3,
|
||||
Status = _salimaxAlarmState,
|
||||
Type = MessageType.AlarmOrWarning,
|
||||
Alarms = alarmList,
|
||||
|
|
@ -845,6 +832,16 @@ internal static class Program
|
|||
}
|
||||
else
|
||||
{
|
||||
// var values = value.Split(','); //in case it is a list
|
||||
// Console.WriteLine("len is ",values.Length);
|
||||
// if (values.Length > 4)
|
||||
// {
|
||||
// foreach (var val in values)
|
||||
// {
|
||||
// Console.WriteLine("value from list is ", val);
|
||||
// }
|
||||
// }
|
||||
|
||||
currentDict[key] = value; // Store as string if not a number
|
||||
}
|
||||
}
|
||||
|
|
@ -944,7 +941,7 @@ internal static class Program
|
|||
var returnedStatus = new StatusMessage
|
||||
{
|
||||
InstallationId = installationId,
|
||||
Product = 0, // Salimax is always 0
|
||||
Product = 3, // Salimax is always 0
|
||||
Status = _salimaxAlarmState,
|
||||
Type = MessageType.Heartbit,
|
||||
Timestamp = nameOfJsonFile
|
||||
|
|
|
|||
Loading…
Reference in New Issue