Skip to content

Commit

Permalink
Merge pull request #105 from pkuehnel/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
pkuehnel authored May 21, 2022
2 parents f766757 + 3d53d26 commit e9757d9
Show file tree
Hide file tree
Showing 17 changed files with 379 additions and 60 deletions.
4 changes: 0 additions & 4 deletions SmartTeslaAmpSetter.Tests/SmartTeslaAmpSetter.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@
</PackageReference>
</ItemGroup>

<ItemGroup>
<Folder Include="Services\" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\SmartTeslaAmpSetter\Server\SmartTeslaAmpSetter.Server.csproj" />
<ProjectReference Include="..\SmartTeslaAmpSetter\Shared\SmartTeslaAmpSetter.Shared.csproj" />
Expand Down
3 changes: 3 additions & 0 deletions SmartTeslaAmpSetter.Tests/TestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ protected TestBase(
var configDictionary = new Dictionary<string, string>
{
{"TeslaMateApiBaseUrl", "http://192.168.1.50:8097"},
{"ten", "10"},
{"one", "1"},
{"zero", "0"},
};
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(configDictionary)
Expand Down
107 changes: 107 additions & 0 deletions SmartTeslaAmpSetter.Tests/Wrappers/ConfigurationWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using System;
using Xunit;
using Xunit.Abstractions;

namespace SmartTeslaAmpSetter.Tests.Wrappers;

public class ConfigurationWrapper : TestBase
{
public ConfigurationWrapper(ITestOutputHelper outputHelper)
: base(outputHelper)
{
}

[Fact]
public void Get_Not_Nullable_String()
{
var configurationService = Mock.Create<Server.Wrappers.ConfigurationWrapper>();

var existingConfigValue = "TeslaMateApiBaseUrl";
var teslaMateApiBaseUrl =
configurationService.GetNotNullableConfigurationValue(existingConfigValue);

Assert.Equal("http://192.168.1.50:8097", teslaMateApiBaseUrl);
}

[Theory]
[InlineData("")]
[InlineData("notExisiting")]
public void Throw_Exception_On_Null_String(string notExisitingConfigValue)
{
var configurationService = Mock.Create<Server.Wrappers.ConfigurationWrapper>();
Assert.Throws<NullReferenceException>(
() => configurationService.GetNotNullableConfigurationValue(notExisitingConfigValue));
}

[Theory]
[InlineData("")]
[InlineData("notExisiting")]
public void Returns_Null_On_Non_Exisiting_Values(string notExisitingConfigValue)
{
var configurationService = Mock.Create<Server.Wrappers.ConfigurationWrapper>();
var value = configurationService.GetNullableConfigurationValue(notExisitingConfigValue);

Assert.Null(value);
}

[Theory]
[InlineData("ten")]
[InlineData("one")]
[InlineData("zero")]
[InlineData("notExisiting")]
public void Get_TimeSpan_From_Minutes(string configName)
{
var configurationService = Mock.Create<Server.Wrappers.ConfigurationWrapper>();
var timespan =
configurationService.GetMinutesConfigurationValueIfGreaterThanMinumum(configName, TimeSpan.FromMinutes(1));

switch (configName)
{
case "ten":
Assert.Equal(TimeSpan.FromMinutes(10), timespan);
break;
case "one":
Assert.Equal(TimeSpan.FromMinutes(1), timespan);
break;
case "zero":
Assert.Equal(TimeSpan.FromMinutes(1), timespan);
break;
case "notExisiting":
Assert.Equal(TimeSpan.FromMinutes(1), timespan);
break;
default:
throw new NotImplementedException("Config name not converd in this test");
}
}

[Theory]
[InlineData("ten")]
[InlineData("one")]
[InlineData("zero")]
[InlineData("notExisiting")]
public void Get_TimeSpan_From_Seconds(string configName)
{
var configurationService = Mock.Create<Server.Wrappers.ConfigurationWrapper>();
var minimum = TimeSpan.FromSeconds(1);
var timespan =
configurationService.GetSecondsConfigurationValueIfGreaterThanMinumum(configName, minimum);

switch (configName)
{
case "ten":
Assert.Equal(TimeSpan.FromSeconds(10), timespan);
break;
case "one":
Assert.Equal(TimeSpan.FromSeconds(1), timespan);
break;
case "zero":
Assert.Equal(TimeSpan.FromSeconds(1), timespan);
break;
case "notExisiting":
Assert.Equal(TimeSpan.FromSeconds(1), timespan);
break;
default:
throw new NotImplementedException("Config name not converd in this test");
}
}
}
2 changes: 1 addition & 1 deletion SmartTeslaAmpSetter/Client/Pages/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ else
}

_timer = new Timer();
_timer.Interval = (_configuration.GetValue<int>("FrontendUpdateintervallSeconds") < 5 ? 5 : _configuration.GetValue<int>("FrontendUpdateintervallSeconds")) * 1000;
_timer.Interval = 5000;
_timer.Elapsed += RefreshStates;
_timer.Start();
}
Expand Down
21 changes: 21 additions & 0 deletions SmartTeslaAmpSetter/Server/Contracts/IConfigurationWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace SmartTeslaAmpSetter.Server.Contracts;

public interface IConfigurationWrapper
{
string ConfigFileLocation();
TimeSpan UpdateIntervall();
string MqqtClientId();
string MosquitoServer();
string CurrentPowerToGridUrl();
string? CurrentInverterPowerUrl();
string? CurrentPowerToGridJsonPattern();
bool CurrentPowerToGridInvertValue();
string TeslaMateApiBaseUrl();
List<int> CarPriorities();
string GeoFence();
TimeSpan TimeUntilSwitchOn();
TimeSpan TimespanUntilSwitchOff();
int PowerBuffer();
string? TelegramBotKey();
string? TelegramChannelId();
}
6 changes: 6 additions & 0 deletions SmartTeslaAmpSetter/Server/Contracts/IMqttService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace SmartTeslaAmpSetter.Server.Contracts;

public interface IMqttService
{
Task ConfigureMqttClient();
}
11 changes: 6 additions & 5 deletions SmartTeslaAmpSetter/Server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
using Quartz.Impl;
using Quartz.Spi;
using Serilog;
using SmartTeslaAmpSetter.Server;
using SmartTeslaAmpSetter.Server.Contracts;
using SmartTeslaAmpSetter.Server.Scheduling;
using SmartTeslaAmpSetter.Server.Services;
using SmartTeslaAmpSetter.Server.Wrappers;
using SmartTeslaAmpSetter.Shared.Dtos.Settings;
using SmartTeslaAmpSetter.Shared.TimeProviding;

Expand Down Expand Up @@ -42,9 +42,10 @@
.AddTransient<ITelegramService, TelegramService>()
.AddTransient<ITeslaService, TeslamateApiService>()
.AddSingleton<ISettings, Settings>()
.AddSingleton<IConfigurationWrapper, ConfigurationWrapper>()
.AddSingleton(mqttClient)
.AddTransient<MqttFactory>()
.AddTransient<MqttHelper>()
.AddTransient<IMqttService, MqttService>()
;

builder.Host.UseSerilog((context, configuration) => configuration
Expand All @@ -67,14 +68,14 @@
var telegramService = app.Services.GetRequiredService<ITelegramService>();
await telegramService.SendMessage("Application starting up");

var secondsFromConfig = app.Configuration.GetValue<double>("UpdateIntervalSeconds");
var jobIntervall = TimeSpan.FromSeconds(secondsFromConfig);
var configurationWrapper = app.Services.GetRequiredService<IConfigurationWrapper>();
var jobIntervall = configurationWrapper.UpdateIntervall();

var configJsonService = app.Services.GetRequiredService<IConfigJsonService>();

await configJsonService.AddCarIdsToSettings().ConfigureAwait(false);

var mqttHelper = app.Services.GetRequiredService<MqttHelper>();
var mqttHelper = app.Services.GetRequiredService<IMqttService>();

await mqttHelper.ConfigureMqttClient().ConfigureAwait(false);

Expand Down
8 changes: 0 additions & 8 deletions SmartTeslaAmpSetter/Server/Scheduling/JobManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,6 @@ public async void StartJobs(TimeSpan jobIntervall)
_scheduler = _schedulerFactory.GetScheduler().GetAwaiter().GetResult();
_scheduler.JobFactory = _jobFactory;

var minimumJobIntervall = TimeSpan.FromSeconds(30);

if (jobIntervall < minimumJobIntervall)
{
_logger.LogWarning("Jobintervall below {minimumJobIntervall}. Due to delays in TeslaMate and TeslaMate API use {minimum} as job interval", minimumJobIntervall, minimumJobIntervall);
jobIntervall = minimumJobIntervall;
}

var chargeLogJob = JobBuilder.Create<Job>().Build();
var configJsonUpdateJob = JobBuilder.Create<ConfigJsonUpdateJob>().Build();
var chargeTimeUpdateJob = JobBuilder.Create<ChargeTimeUpdateJob>().Build();
Expand Down
20 changes: 10 additions & 10 deletions SmartTeslaAmpSetter/Server/Services/ChargingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,23 @@ public class ChargingService : IChargingService
{
private readonly ILogger<ChargingService> _logger;
private readonly IGridService _gridService;
private readonly IConfiguration _configuration;
private readonly ISettings _settings;
private readonly IDateTimeProvider _dateTimeProvider;
private readonly ITelegramService _telegramService;
private readonly ITeslaService _teslaService;
private readonly IConfigurationWrapper _configurationWrapper;

public ChargingService(ILogger<ChargingService> logger, IGridService gridService, IConfiguration configuration,
public ChargingService(ILogger<ChargingService> logger, IGridService gridService,
ISettings settings, IDateTimeProvider dateTimeProvider, ITelegramService telegramService,
ITeslaService teslaService)
ITeslaService teslaService, IConfigurationWrapper configurationWrapper)
{
_logger = logger;
_gridService = gridService;
_configuration = configuration;
_settings = settings;
_dateTimeProvider = dateTimeProvider;
_telegramService = telegramService;
_teslaService = teslaService;
_configurationWrapper = configurationWrapper;
}

public async Task SetNewChargingValues(bool onlyUpdateValues = false)
Expand All @@ -47,12 +47,12 @@ public async Task SetNewChargingValues(bool onlyUpdateValues = false)

_logger.LogDebug($"Current overage is {overage} Watt.");

var buffer = _configuration.GetValue<int>("PowerBuffer");
var buffer = _configurationWrapper.PowerBuffer();
_logger.LogDebug("Adding powerbuffer {powerbuffer}", buffer);

overage -= buffer;

var geofence = _configuration.GetValue<string>("GeoFence");
var geofence = _configurationWrapper.GeoFence();
_logger.LogDebug("Relevant Geofence: {geofence}", geofence);

await WakeupCarsWithUnknownSocLimit(_settings.Cars);
Expand Down Expand Up @@ -306,11 +306,11 @@ private void UpdateEarliestTimesAfterSwitch(int carId)
private DateTime EarliestSwitchOff(int carId)
{
_logger.LogTrace("{method}({param1})", nameof(EarliestSwitchOff), carId);
var minutesUntilSwitchOff = _configuration.GetValue<int>("MinutesUntilSwitchOff");
var timeSpanUntilSwitchOff = _configurationWrapper.TimespanUntilSwitchOff();
var car = _settings.Cars.First(c => c.Id == carId);
if (car.CarState.ShouldStopChargingSince == DateTime.MaxValue)
{
car.CarState.ShouldStopChargingSince = DateTime.Now.AddMinutes(minutesUntilSwitchOff);
car.CarState.ShouldStopChargingSince = DateTime.Now + timeSpanUntilSwitchOff;
}

var earliestSwitchOff = car.CarState.ShouldStopChargingSince;
Expand All @@ -320,11 +320,11 @@ private DateTime EarliestSwitchOff(int carId)
private DateTime EarliestSwitchOn(int carId)
{
_logger.LogTrace("{method}({param1})", nameof(EarliestSwitchOn), carId);
var minutesUntilSwitchOn = _configuration.GetValue<int>("MinutesUntilSwitchOn");
var timeSpanUntilSwitchOn = _configurationWrapper.TimeUntilSwitchOn();
var car = _settings.Cars.First(c => c.Id == carId);
if (car.CarState.ShouldStartChargingSince == DateTime.MaxValue)
{
car.CarState.ShouldStartChargingSince = DateTime.Now.AddMinutes(minutesUntilSwitchOn);
car.CarState.ShouldStartChargingSince = DateTime.Now + timeSpanUntilSwitchOn;
}

var earliestSwitchOn = car.CarState.ShouldStartChargingSince;
Expand Down
11 changes: 6 additions & 5 deletions SmartTeslaAmpSetter/Server/Services/ConfigJsonService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ namespace SmartTeslaAmpSetter.Server.Services;
public class ConfigJsonService : IConfigJsonService
{
private readonly ILogger<ConfigJsonService> _logger;
private readonly IConfiguration _configuration;
private readonly ISettings _settings;
private readonly IConfigurationWrapper _congConfigurationWrapper;

public ConfigJsonService(ILogger<ConfigJsonService> logger, IConfiguration configuration, ISettings settings)
public ConfigJsonService(ILogger<ConfigJsonService> logger, ISettings settings,
IConfigurationWrapper congConfigurationWrapper)
{
_logger = logger;
_configuration = configuration;
_settings = settings;
_congConfigurationWrapper = congConfigurationWrapper;
}

private bool CarConfigurationFileExists()
Expand All @@ -30,7 +31,7 @@ private bool CarConfigurationFileExists()

private string GetConfigurationFileFullPath()
{
var configFileLocation = _configuration.GetValue<string>("ConfigFileLocation");
var configFileLocation = _congConfigurationWrapper.ConfigFileLocation();
var path = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory?.FullName;
path = Path.Combine(path ?? throw new InvalidOperationException("Could not get Assembly directory"), configFileLocation);
return path;
Expand All @@ -52,7 +53,7 @@ public async Task<List<Car>> GetCarsFromConfiguration()
}
}

var carIds = _configuration.GetValue<string>("CarPriorities").Split("|").Select(id => Convert.ToInt32(id)).ToList();
var carIds = _congConfigurationWrapper.CarPriorities();
RemoveOldCars(cars, carIds);

var newCarIds = carIds.Where(i => !cars.Any(c => c.Id == i)).ToList();
Expand Down
14 changes: 7 additions & 7 deletions SmartTeslaAmpSetter/Server/Services/GridService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@ namespace SmartTeslaAmpSetter.Server.Services;
public class GridService : IGridService
{
private readonly ILogger<GridService> _logger;
private readonly IConfiguration _configuration;
private readonly ITelegramService _telegramService;
private readonly IConfigurationWrapper _configurationWrapper;

public GridService(ILogger<GridService> logger, IConfiguration configuration, ITelegramService telegramService)
public GridService(ILogger<GridService> logger, ITelegramService telegramService, IConfigurationWrapper configurationWrapper)
{
_logger = logger;
_configuration = configuration;
_telegramService = telegramService;
_configurationWrapper = configurationWrapper;
}

public async Task<int> GetCurrentOverage()
{
_logger.LogTrace("{method}()", nameof(GetCurrentOverage));
using var httpClient = new HttpClient();
var requestUri = _configuration.GetValue<string>("CurrentPowerToGridUrl");
var requestUri = _configurationWrapper.CurrentPowerToGridUrl();
_logger.LogDebug("Using {uri} to get current overage.", requestUri);
var response = await httpClient.GetAsync(
requestUri)
Expand All @@ -35,7 +35,7 @@ public async Task<int> GetCurrentOverage()

var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

var jsonPattern = _configuration.GetValue<string>("CurrentPowerToGridJsonPattern");
var jsonPattern = _configurationWrapper.CurrentPowerToGridJsonPattern();

if (jsonPattern != null)
{
Expand All @@ -47,7 +47,7 @@ public async Task<int> GetCurrentOverage()
try
{
var overage = GetIntegerFromString(result);
if (_configuration.GetValue<bool>("CurrentPowerToGridInvertValue"))
if (_configurationWrapper.CurrentPowerToGridInvertValue())
{
overage = -overage;
}
Expand All @@ -70,7 +70,7 @@ internal int GetIntegerFromString(string? inputString)
{
_logger.LogTrace("{method}()", nameof(GetCurrentInverterPower));
using var httpClient = new HttpClient();
var requestUri = _configuration.GetValue<string>("CurrentInverterPowerUrl");
var requestUri = _configurationWrapper.CurrentInverterPowerUrl();
if (requestUri == null)
{
return null;
Expand Down
Loading

0 comments on commit e9757d9

Please sign in to comment.