Skip to content

Commit

Permalink
Merge pull request #124 from pkuehnel/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
pkuehnel authored Jun 8, 2022
2 parents ad614a6 + 20846e8 commit 331d9fa
Show file tree
Hide file tree
Showing 36 changed files with 331 additions and 178 deletions.
12 changes: 10 additions & 2 deletions Plugins.SmaEnergymeter/Controllers/CurrentPowerController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,18 @@ public CurrentPowerController(CurrentPowerService currentPowerService)
_currentPowerService = currentPowerService;
}

[Obsolete]
[HttpGet]
public int GetCurrentPower(int lastXSeconds)
public int GetCurrentPower(int lastXSeconds = 0)
{
return _currentPowerService.GetCurrentPower(lastXSeconds);
return _currentPowerService.GetCurrentPower();
}

[Route("[action]")]
[HttpGet]
public int GetPower()
{
return _currentPowerService.GetCurrentPower();
}
}
}
23 changes: 3 additions & 20 deletions Plugins.SmaEnergymeter/Services/CurrentPowerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,9 @@ public CurrentPowerService(ILogger<CurrentPowerService> logger, SharedValues sha
_sharedValues = sharedValues;
}

public int GetCurrentPower(int lastXSeconds)
public int GetCurrentPower()
{
_logger.LogTrace("{method}({param1})", nameof(GetCurrentPower), lastXSeconds);
var orderedValues = _sharedValues.LastValues
.Where(v => v.Timestamp >= DateTime.UtcNow.AddSeconds(-lastXSeconds))
.OrderBy(v => v.Timestamp)
.ToList();

long weightedSum = 0;
for (var i = 0; i < orderedValues.Count; i++)
{
_logger.LogTrace("Power Value: {value}", orderedValues[i].Power);
weightedSum += orderedValues[i].Power * (i + 1);
_logger.LogTrace("weightedSum: {value}", weightedSum);
}
var weightedCount = orderedValues.Count * (orderedValues.Count + 1) / 2;
if (weightedCount == 0)
{
throw new InvalidOperationException("There are no power values available");
}
return (int) (weightedSum / weightedCount);
_logger.LogTrace("{method}()", nameof(GetCurrentPower));
return _sharedValues.Overage;
}
}
19 changes: 3 additions & 16 deletions Plugins.SmaEnergymeter/Services/EnergyMeterService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,27 +62,14 @@ public void StartLogging()

_logger.LogTrace("current supply: {currentSupply}", currentSupply);
_logger.LogTrace("current overage: {currentOverage}", currentOverage);

if (currentSupply > 0)
{
_sharedValues.LastValues.Add(new()
{
Timestamp = DateTime.UtcNow,
Power = (int)-currentSupply,
});
_sharedValues.Overage = (int)-currentSupply;
}
else
{
_sharedValues.LastValues.Add(new()
{
Timestamp = DateTime.UtcNow,
Power = (int)currentOverage,
});
}

var maxValuesInList = _configuration.GetValue<int>("MaxValuesInLastValuesList");
if (_sharedValues.LastValues.Count > maxValuesInList)
{
_sharedValues.LastValues.RemoveRange(0, _sharedValues.LastValues.Count - maxValuesInList);
_sharedValues.Overage = (int)currentOverage;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Plugins.SmaEnergymeter/SharedValues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ namespace Plugins.SmaEnergymeter;

public class SharedValues
{
public List<PowerValue> LastValues = new ();
public int Overage { get; set; }
}
3 changes: 1 addition & 2 deletions Plugins.SmaEnergymeter/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,5 @@
},
"AllowedHosts": "*",
"EnergyMeterPort": 9522,
"EnergyMeterMulticastAddress": "239.12.255.254",
"MaxValuesInLastValuesList": 30
"EnergyMeterMulticastAddress": "239.12.255.254"
}
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ You can either use it in a Docker container or go download the code and deploy i

### Docker-compose

If you run the simple Docker deployment of TeslaMate, then adding this will do the trick. You'll have the frontend available on port 7190 then.
If you run the simple Docker deployment of TeslaMate, then adding this will do the trick. You'll have the frontend available on port 7190 then. Note: you have to change the CurrentPowerToGridUrl based on your environment. If you use the SMA Plugin you only have to update the IP address.

```yaml
services:
Expand All @@ -45,9 +45,9 @@ services:
depends_on:
- teslamateapi
environment:
- CurrentPowerToGridUrl=http://192.168.1.50/api/CurrentPower
- CurrentPowerToGridUrl=http://192.168.1.50/api/CurrentPower/GetPower
- TeslaMateApiBaseUrl=http://teslamateapi:8080
- UpdateIntervalSeconds=30
- UpdateIntervalSeconds=20
- CarPriorities=1
- GeoFence=Home
- MinutesUntilSwitchOn=5
Expand Down Expand Up @@ -154,5 +154,4 @@ services:
network_mode: host
environment:
- ASPNETCORE_URLS=http://+:8453
- MaxValuesInLastValuesList=120
```
1 change: 1 addition & 0 deletions SmartTeslaAmpSetter.Tests/Services/ChargingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Autofac;
using SmartTeslaAmpSetter.Shared.Dtos.Contracts;
using SmartTeslaAmpSetter.Shared.Dtos.Settings;
using SmartTeslaAmpSetter.Shared.Enums;
using SmartTeslaAmpSetter.Shared.TimeProviding;
Expand Down
1 change: 1 addition & 0 deletions SmartTeslaAmpSetter.Tests/Services/MqttService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using SmartTeslaAmpSetter.Server.Services;
using SmartTeslaAmpSetter.Shared.Dtos.Contracts;
using SmartTeslaAmpSetter.Shared.Dtos.Settings;
using Xunit;
using Xunit.Abstractions;
Expand Down
39 changes: 21 additions & 18 deletions SmartTeslaAmpSetter/Client/Pages/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
@using SmartTeslaAmpSetter.Shared
@using SmartTeslaAmpSetter.Shared.Dtos.Settings
@using SmartTeslaAmpSetter.Shared.Enums
@inject HttpClient _httpClient
@inject IToastService _toastService
@inject IConfiguration _configuration
@inject HttpClient HttpClient
@inject IToastService ToastService

<PageTitle>Index</PageTitle>

Expand All @@ -19,12 +18,16 @@ else
<div class="shadow p-3 mb-5 bg-white rounded">
@if (_settings.InverterPower != null)
{
<div><i class="fa-solid fa-solar-panel"></i> @_settings.InverterPower W</div>
<div><i class="fa-solid fa-house"></i> @(_settings.InverterPower - _settings.Overage - _settings.Cars.Sum(c => c.CarState.ChargingPowerAtHome)) W</div>
<div><i class="fa-solid fa-solar-panel" style="width: 25px;"></i>@_settings.InverterPower W</div>
<div><i class="fa-solid fa-house" style="width: 25px;"></i>@(_settings.InverterPower - _settings.Overage - _settings.Cars.Sum(c => c.CarState.ChargingPowerAtHome)) W</div>
}
<div class="@(_settings.Overage > 0 ? "text-success" : "text-danger")"><i class="fa-solid fa-bolt"></i> @(Math.Abs(_settings.Overage)) W</div>
<div><i class="fa-solid fa-car"></i> @_settings.Cars.Sum(c => c.CarState.ChargingPowerAtHome) W</div>
<button class="btn btn-primary col-6 col-sm-6 col-md-3" @onclick="() => RefreshSettings()">@_refreshButtonText</button>
<div class="@(_settings.Overage > 0 ? "text-success" : "text-danger")"><i class="fa-solid fa-bolt" style="width: 25px;"></i>
@if (_settings.Overage != null)
{
@Math.Abs((int)_settings.Overage)
}
W</div>
<div><i class="fa-solid fa-car" style="width: 25px;"></i>@_settings.Cars.Sum(c => c.CarState.ChargingPowerAtHome) W</div>
</div>
@foreach (var car in _settings.Cars)
{
Expand Down Expand Up @@ -219,7 +222,7 @@ else

protected override async Task OnInitializedAsync()
{
var handler = _httpClient.GetFromJsonAsync<Settings>("api/Config/GetSettings");
var handler = HttpClient.GetFromJsonAsync<Settings>("api/Config/GetSettings");
_settings = await handler;
foreach (var car in _settings!.Cars)
{
Expand All @@ -236,39 +239,39 @@ else
private async Task ChangeChargeMode(int carId)
{
_chargemodeChangeButtonTexts[carId] = _buttonLoadingText;
var updateBackend = _httpClient.PostAsync($"api/Config/ChangeChargeMode?carId={carId}", new StringContent(string.Empty));
var updateBackend = HttpClient.PostAsync($"api/Config/ChangeChargeMode?carId={carId}", new StringContent(string.Empty));
var car = _settings?.Cars.First(c => c.Id == carId);
var result = await updateBackend;
if (result.IsSuccessStatusCode)
{
_toastService.ShowSuccess("ChargeMode Changed");
ToastService.ShowSuccess("ChargeMode Changed");
car!.CarConfiguration.ChargeMode = car.CarConfiguration.ChargeMode.Next();
}
else
{
_toastService.ShowError("Error changing ChargeMode");
ToastService.ShowError("Error changing ChargeMode");
}
_chargemodeChangeButtonTexts[carId] = _chargeModeChangeButtonDefaultText;
}

private async Task UpdateCarConfiguration(int carId, CarConfiguration carConfiguration)
{
_saveButtonTexts[carId] = _buttonLoadingText;
var result = await _httpClient.PutAsJsonAsync($"api/Config/UpdateCarConfiguration?carId={carId}", carConfiguration);
var result = await HttpClient.PutAsJsonAsync($"api/Config/UpdateCarConfiguration?carId={carId}", carConfiguration);
if (result.IsSuccessStatusCode)
{
_toastService.ShowSuccess("Car Configuration updated");
ToastService.ShowSuccess("Car Configuration updated");
}
else
{
_toastService.ShowError("Error updating car configuration");
ToastService.ShowError("Error updating car configuration");
}
_saveButtonTexts[carId] = _saveButtonDefaultText;
}

private async void RefreshStates(object? sender, ElapsedEventArgs elapsedEventArgs)
{
var tmpSettings = await _httpClient.GetFromJsonAsync<Settings>("api/Config/GetSettings");
var tmpSettings = await HttpClient.GetFromJsonAsync<Settings>("api/Config/GetSettings");
_settings!.InverterPower = tmpSettings!.InverterPower;
_settings.Overage = tmpSettings.Overage;
foreach (var tmpCar in tmpSettings.Cars)
Expand All @@ -282,9 +285,9 @@ else
private async void RefreshSettings()
{
_refreshButtonText = _buttonLoadingText;
_settings = await _httpClient.GetFromJsonAsync<Settings>("api/Config/GetSettings");
_settings = await HttpClient.GetFromJsonAsync<Settings>("api/Config/GetSettings");
this.StateHasChanged();
_toastService.ShowSuccess("Refreshed");
ToastService.ShowSuccess("Refreshed");
_refreshButtonText = _refreshButtonDefaultText;
this.StateHasChanged();
}
Expand Down
2 changes: 1 addition & 1 deletion SmartTeslaAmpSetter/Server/Contracts/IChargingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

public interface IChargingService
{
Task SetNewChargingValues(bool onlyUpdateValues = false);
Task SetNewChargingValues();
}
3 changes: 2 additions & 1 deletion SmartTeslaAmpSetter/Server/Contracts/IConfigService.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using SmartTeslaAmpSetter.Shared.Dtos;
using SmartTeslaAmpSetter.Shared.Dtos.Contracts;
using SmartTeslaAmpSetter.Shared.Dtos.Settings;
using SmartTeslaAmpSetter.Shared.Enums;

namespace SmartTeslaAmpSetter.Server.Contracts;

public interface IConfigService
{
Task<ISettings> GetSettings();
ISettings GetSettings();
ChargeMode ChangeChargeMode(int carId);
void UpdateCarConfiguration(int carId, CarConfiguration carConfiguration);
List<CarBasicConfiguration> GetCarBasicConfigurations();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
public interface IConfigurationWrapper
{
string ConfigFileLocation();
TimeSpan UpdateIntervall();
TimeSpan ChargingValueJobUpdateIntervall();
TimeSpan PvValueJobUpdateIntervall();
string MqqtClientId();
string MosquitoServer();
string CurrentPowerToGridUrl();
Expand Down
2 changes: 1 addition & 1 deletion SmartTeslaAmpSetter/Server/Contracts/IGridService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

public interface IGridService
{
Task<int> GetCurrentOverage();
Task<int?> GetCurrentOverage();
Task<int?> GetCurrentInverterPower();
}
7 changes: 7 additions & 0 deletions SmartTeslaAmpSetter/Server/Contracts/IPvValueService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace SmartTeslaAmpSetter.Server.Contracts;

public interface IPvValueService
{
Task UpdatePvValues();
int GetAveragedOverage();
}
3 changes: 2 additions & 1 deletion SmartTeslaAmpSetter/Server/Controllers/ConfigController.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using SmartTeslaAmpSetter.Server.Contracts;
using SmartTeslaAmpSetter.Shared.Dtos;
using SmartTeslaAmpSetter.Shared.Dtos.Contracts;
using SmartTeslaAmpSetter.Shared.Dtos.Settings;
using SmartTeslaAmpSetter.Shared.Enums;

Expand All @@ -21,7 +22,7 @@ public ConfigController(IConfigService service)
/// Get all settings and status of all cars
/// </summary>
[HttpGet]
public Task<ISettings> GetSettings() => _service.GetSettings();
public ISettings GetSettings() => _service.GetSettings();

/// <summary>
/// Change Chargemode of car
Expand Down
12 changes: 7 additions & 5 deletions SmartTeslaAmpSetter/Server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using SmartTeslaAmpSetter.Server.Scheduling;
using SmartTeslaAmpSetter.Server.Services;
using SmartTeslaAmpSetter.Server.Wrappers;
using SmartTeslaAmpSetter.Shared.Dtos;
using SmartTeslaAmpSetter.Shared.Dtos.Contracts;
using SmartTeslaAmpSetter.Shared.Dtos.Settings;
using SmartTeslaAmpSetter.Shared.TimeProviding;

Expand All @@ -27,9 +29,10 @@

builder.Services
.AddTransient<JobManager>()
.AddTransient<Job>()
.AddTransient<ChargingValueJob>()
.AddTransient<ConfigJsonUpdateJob>()
.AddTransient<ChargeTimeUpdateJob>()
.AddTransient<PvValueJob>()
.AddTransient<JobFactory>()
.AddTransient<IJobFactory, JobFactory>()
.AddTransient<ISchedulerFactory, StdSchedulerFactory>()
Expand All @@ -42,10 +45,12 @@
.AddTransient<ITelegramService, TelegramService>()
.AddTransient<ITeslaService, TeslamateApiService>()
.AddSingleton<ISettings, Settings>()
.AddSingleton<IInMemoryValues, InMemoryValues>()
.AddSingleton<IConfigurationWrapper, ConfigurationWrapper>()
.AddSingleton(mqttClient)
.AddTransient<MqttFactory>()
.AddTransient<IMqttService, MqttService>()
.AddTransient<IPvValueService, PvValueService>()
;

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

var configurationWrapper = app.Services.GetRequiredService<IConfigurationWrapper>();
var jobIntervall = configurationWrapper.UpdateIntervall();

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

await configJsonService.AddCarIdsToSettings().ConfigureAwait(false);
Expand All @@ -80,7 +82,7 @@
await mqttHelper.ConfigureMqttClient().ConfigureAwait(false);

var jobManager = app.Services.GetRequiredService<JobManager>();
jobManager.StartJobs(jobIntervall);
jobManager.StartJobs();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
namespace SmartTeslaAmpSetter.Server.Scheduling;

[DisallowConcurrentExecution]
public class Job : IJob
public class ChargingValueJob : IJob
{
private readonly ILogger<Job> _logger;
private readonly ILogger<ChargingValueJob> _logger;
private readonly IChargingService _chargingService;

public Job(ILogger<Job> logger, IChargingService chargingService)
public ChargingValueJob(ILogger<ChargingValueJob> logger, IChargingService chargingService)
{
_logger = logger;
_chargingService = chargingService;
Expand Down
Loading

0 comments on commit 331d9fa

Please sign in to comment.