Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #991

Merged
merged 4 commits into from
Nov 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@
<h3>Issues:</h3>
@foreach (var issue in _issues)
{
<div style="background-color: @(issue.IssueType == IssueType.Error ? "red" : "yellow")">
<div style="background-color: @(issue.IssueType switch
{
IssueType.Error => "red",
IssueType.Warning => "yellow",
_ => "white",
})">
<div>@issue.IssueMessage</div>
@if (issue.PossibleSolutions.Length > 0)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using TeslaSolarCharger.Shared.Dtos.BaseConfiguration;
using Microsoft.AspNetCore.Mvc;
using TeslaSolarCharger.Shared.Dtos.BaseConfiguration;

namespace TeslaSolarCharger.Server.Contracts;

Expand All @@ -7,4 +8,5 @@ public interface IBaseConfigurationService
Task UpdateBaseConfigurationAsync(DtoBaseConfiguration baseConfiguration);
Task UpdateMaxCombinedCurrent(int? maxCombinedCurrent);
void UpdatePowerBuffer(int powerBuffer);
Task<byte[]> DownloadBackup();
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,12 @@ public void UpdateMaxCombinedCurrent(int? maxCombinedCurrent) =>
[HttpGet]
public void UpdatePowerBuffer(int powerBuffer) =>
_service.UpdatePowerBuffer(powerBuffer);

[HttpGet]
public async Task<FileContentResult> DownloadBackup()
{
var bytes = await _service.DownloadBackup().ConfigureAwait(false);
return File(bytes, "application/zip", "TSCBackup.zip");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ public class IssueKeys
public string VersionNotUpToDate = "VersionNotUpToDate";
public string CorrectionFactorZero = "CorrectionFactorZero";
public string ServerTimeZoneDifferentFromClient = "ServerTimeZoneDifferentFromClient";
public string NewTeslaApi = "NewTeslaApi";
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ public PossibleIssues(IssueKeys issueKeys)
"Update the TimeZone of the TeslaSolarChargerContainer in your docker-compose.yml."
)
},
{
issueKeys.NewTeslaApi, CreateIssue("New cars are currently not supported",
IssueType.Information,
"If there are any updates on this topic, I will post them <a href=\"https://github.com/pkuehnel/TeslaSolarCharger/issues/988\" target=\"_blank\">here</a>.",
"Sorry for this information beeing not removable - it will be possible in a future update."
)
},
};
}

Expand Down
68 changes: 66 additions & 2 deletions TeslaSolarCharger/Server/Services/BaseConfigurationService.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
using TeslaSolarCharger.Server.Contracts;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.Sqlite;
using Microsoft.Net.Http.Headers;
using System.IO.Compression;
using System.Net;
using TeslaSolarCharger.Model.Contracts;
using TeslaSolarCharger.Server.Contracts;
using TeslaSolarCharger.Server.Scheduling;
using TeslaSolarCharger.Shared.Contracts;
using TeslaSolarCharger.Shared.Dtos.BaseConfiguration;
using TeslaSolarCharger.Shared.Dtos.Contracts;
using TeslaSolarCharger.Shared.Enums;
using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue;

namespace TeslaSolarCharger.Server.Services;

Expand All @@ -16,10 +23,11 @@ public class BaseConfigurationService : IBaseConfigurationService
private readonly ISolarMqttService _solarMqttService;
private readonly ISettings _settings;
private readonly IPvValueService _pvValueService;
private readonly IDbConnectionStringHelper _dbConnectionStringHelper;

public BaseConfigurationService(ILogger<BaseConfigurationService> logger, IConfigurationWrapper configurationWrapper,
JobManager jobManager, ITeslaMateMqttService teslaMateMqttService, ISolarMqttService solarMqttService,
ISettings settings, IPvValueService pvValueService)
ISettings settings, IPvValueService pvValueService, IDbConnectionStringHelper dbConnectionStringHelper)
{
_logger = logger;
_configurationWrapper = configurationWrapper;
Expand All @@ -28,6 +36,7 @@ public BaseConfigurationService(ILogger<BaseConfigurationService> logger, IConfi
_solarMqttService = solarMqttService;
_settings = settings;
_pvValueService = pvValueService;
_dbConnectionStringHelper = dbConnectionStringHelper;
}

public async Task UpdateBaseConfigurationAsync(DtoBaseConfiguration baseConfiguration)
Expand Down Expand Up @@ -69,4 +78,59 @@ public void UpdatePowerBuffer(int powerBuffer)
{
_settings.PowerBuffer = powerBuffer;
}

public async Task<byte[]> DownloadBackup()
{
try
{
await _jobManager.StopJobs().ConfigureAwait(false);

var backupCopyDestinationDirectory = _configurationWrapper.BackupCopyDestinationDirectory();
if (Directory.Exists(backupCopyDestinationDirectory))
{
Directory.Delete(backupCopyDestinationDirectory, true);
}
Directory.CreateDirectory(backupCopyDestinationDirectory);

//Backup Sqlite database
using (var source = new SqliteConnection(_dbConnectionStringHelper.GetTeslaSolarChargerDbPath()))
using (var destination = new SqliteConnection(string.Format($"Data Source={Path.Combine(backupCopyDestinationDirectory, _configurationWrapper.GetSqliteFileNameWithoutPath())};Pooling=False")))
{
source.Open();
destination.Open();
source.BackupDatabase(destination, "main", "main");
}

//Backup config files
var baseConfigFileFullName = _configurationWrapper.BaseConfigFileFullName();
var carConfigFileFullName = _configurationWrapper.CarConfigFileFullName();
File.Copy(baseConfigFileFullName, Path.Combine(backupCopyDestinationDirectory, Path.GetFileName(baseConfigFileFullName)), true);
File.Copy(carConfigFileFullName, Path.Combine(backupCopyDestinationDirectory, Path.GetFileName(carConfigFileFullName)), true);


var backupFileName = "TSC-Backup.zip";
var backupZipDirectory = _configurationWrapper.BackupZipDirectory();
if(Directory.Exists(backupZipDirectory))
{
Directory.Delete(backupZipDirectory, true);
}
Directory.CreateDirectory(backupZipDirectory);
var destinationArchiveFileName = Path.Combine(backupZipDirectory, backupFileName);
ZipFile.CreateFromDirectory(backupCopyDestinationDirectory, destinationArchiveFileName);
var bytes = await File.ReadAllBytesAsync(destinationArchiveFileName).ConfigureAwait(false);
return bytes;
}
catch (Exception ex)
{
_logger.LogError(ex, "Couldn't download backup");
throw;
}
finally
{
await _jobManager.StartJobs().ConfigureAwait(false);
}



}
}
5 changes: 4 additions & 1 deletion TeslaSolarCharger/Server/Services/IssueValidationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ public IssueValidationService(ILogger<IssueValidationService> logger, ISettings
public async Task<List<Issue>> RefreshIssues(TimeSpan clientTimeZoneId)
{
_logger.LogTrace("{method}()", nameof(RefreshIssues));
var issueList = new List<Issue>();
var issueList = new List<Issue>
{
_possibleIssues.GetIssueByKey(_issueKeys.NewTeslaApi),
};
issueList.AddRange(GetServerConfigurationIssues(clientTimeZoneId));
if (Debugger.IsAttached)
{
Expand Down
2 changes: 2 additions & 0 deletions TeslaSolarCharger/Server/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
},
"AllowedHosts": "*",
"ConfigFileLocation": "configs",
"BackupCopyDestinationDirectory": "backups",
"BackupZipDirectory": "backupZips",
"CarConfigFilename": "carConfig.json",
"BaseConfigFileName": "baseConfig.json",
"SqliteFileName": "TeslaSolarCharger.db",
Expand Down
3 changes: 3 additions & 0 deletions TeslaSolarCharger/Shared/Contracts/IConfigurationWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,7 @@ public interface IConfigurationWrapper
bool AllowCors();
bool ShouldDisplayApiRequestCounter();
bool ShouldIgnoreSslErrors();
string BackupCopyDestinationDirectory();
string GetSqliteFileNameWithoutPath();
string BackupZipDirectory();
}
26 changes: 25 additions & 1 deletion TeslaSolarCharger/Shared/Wrappers/ConfigurationWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,37 @@ public string CarConfigFileFullName()
return Path.Combine(configFileDirectory, value);
}

public string BackupCopyDestinationDirectory()
{
var configFileDirectory = ConfigFileDirectory();
var environmentVariableName = "BackupCopyDestinationDirectory";
var value = GetNotNullableConfigurationValue<string>(environmentVariableName);
_logger.LogTrace("Config value extracted: [{key}]: {value}", environmentVariableName, value);
return Path.Combine(configFileDirectory, value);
}

public string BackupZipDirectory()
{
var configFileDirectory = ConfigFileDirectory();
var environmentVariableName = "BackupZipDirectory";
var value = GetNotNullableConfigurationValue<string>(environmentVariableName);
_logger.LogTrace("Config value extracted: [{key}]: {value}", environmentVariableName, value);
return Path.Combine(configFileDirectory, value);
}

public string SqliteFileFullName()
{
var configFileDirectory = ConfigFileDirectory();
var value = GetSqliteFileNameWithoutPath();
return Path.Combine(configFileDirectory, value);
}

public string GetSqliteFileNameWithoutPath()
{
var environmentVariableName = "SqliteFileName";
var value = GetNotNullableConfigurationValue<string>(environmentVariableName);
_logger.LogTrace("Config value extracted: [{key}]: {value}", environmentVariableName, value);
return Path.Combine(configFileDirectory, value);
return value;
}

public string BaseConfigFileFullName()
Expand Down
Loading