diff --git a/SmartTeslaAmpSetter.Tests/Services/ChargingService.cs b/SmartTeslaAmpSetter.Tests/Services/ChargingService.cs
index 7aa226518..a0fc7d6fd 100644
--- a/SmartTeslaAmpSetter.Tests/Services/ChargingService.cs
+++ b/SmartTeslaAmpSetter.Tests/Services/ChargingService.cs
@@ -140,6 +140,10 @@ public void Gets_relevant_car_IDs()
SoC = 30,
SocLimit = 60,
},
+ CarConfiguration = new CarConfiguration()
+ {
+ ShouldBeManaged = true,
+ },
},
new Car()
{
@@ -153,6 +157,27 @@ public void Gets_relevant_car_IDs()
SoC = 30,
SocLimit = 60,
},
+ CarConfiguration = new CarConfiguration()
+ {
+ ShouldBeManaged = true,
+ },
+ },
+ new Car()
+ {
+ Id = 3,
+ CarState = new CarState()
+ {
+ Geofence = geofence,
+ PluggedIn = true,
+ ClimateOn = false,
+ ChargerActualCurrent = 3,
+ SoC = 30,
+ SocLimit = 60,
+ },
+ CarConfiguration = new CarConfiguration()
+ {
+ ShouldBeManaged = false,
+ },
},
};
Mock.Mock().Setup(s => s.Cars).Returns(cars);
@@ -182,6 +207,10 @@ public void Gets_irrelevant_cars()
SoC = 30,
SocLimit = 60,
},
+ CarConfiguration = new CarConfiguration()
+ {
+ ShouldBeManaged = true,
+ },
},
new Car()
{
@@ -195,15 +224,37 @@ public void Gets_irrelevant_cars()
SoC = 30,
SocLimit = 60,
},
+ CarConfiguration = new CarConfiguration()
+ {
+ ShouldBeManaged = true,
+ },
+ },
+ new Car()
+ {
+ Id = 3,
+ CarState = new CarState()
+ {
+ Geofence = geofence,
+ PluggedIn = true,
+ ClimateOn = false,
+ ChargerActualCurrent = 3,
+ SoC = 30,
+ SocLimit = 60,
+ },
+ CarConfiguration = new CarConfiguration()
+ {
+ ShouldBeManaged = false,
+ },
},
};
Mock.Mock().Setup(s => s.Cars).Returns(cars);
var chargingService = Mock.Create();
- var irrelevantCars = chargingService.GetIrrelevantCars(new List(){1});
-
- Assert.Single(irrelevantCars);
+ var irrelevantCars = chargingService.GetIrrelevantCars(chargingService.GetRelevantCarIds(geofence));
+
+ Assert.Equal(2, irrelevantCars.Count);
Assert.Contains(2, irrelevantCars.Select(c => c.Id));
+ Assert.Contains(3, irrelevantCars.Select(c => c.Id));
}
private Car CreateDemoCar(ChargeMode chargeMode, DateTime latestTimeToReachSoC, int soC, int minimumSoC, bool autoFullSpeedCharge)
diff --git a/SmartTeslaAmpSetter.Tests/Services/MqttService.cs b/SmartTeslaAmpSetter.Tests/Services/MqttService.cs
new file mode 100644
index 000000000..c588f52ce
--- /dev/null
+++ b/SmartTeslaAmpSetter.Tests/Services/MqttService.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using SmartTeslaAmpSetter.Server.Services;
+using SmartTeslaAmpSetter.Shared.Dtos.Settings;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace SmartTeslaAmpSetter.Tests.Services;
+
+public class MqttService : TestBase
+{
+ public MqttService(ITestOutputHelper outputHelper)
+ : base(outputHelper)
+ {
+ }
+
+ [Theory]
+ [InlineData("1")]
+ [InlineData("3")]
+ [InlineData("4")]
+ [InlineData("5")]
+ [InlineData("8")]
+ public void ReducesActualCurrentToLastSetAmpIfDifferenceIsOneAndBelow5A(string value)
+ {
+ var cars = new List()
+ {
+ new Car()
+ {
+ Id = 1,
+ CarState = new CarState()
+ {
+ LastSetAmp = 3,
+ },
+ },
+ };
+ Mock.Mock().Setup(s => s.Cars).Returns(cars);
+
+ var mqttService = Mock.Create();
+
+ var teslamateValue = new TeslaMateValue()
+ {
+ CarId = 1,
+ Topic = "charger_actual_current",
+ Value = value,
+ };
+ mqttService.UpdateCar(teslamateValue);
+
+ switch (value)
+ {
+ case "1":
+ Assert.Equal(1, cars.First().CarState.ChargerActualCurrent);
+ break;
+ case "3":
+ case "4":
+ Assert.Equal(3, cars.First().CarState.ChargerActualCurrent);
+ break;
+ case "5":
+ Assert.Equal(5, cars.First().CarState.ChargerActualCurrent);
+ break;
+ case "8":
+ Assert.Equal(8, cars.First().CarState.ChargerActualCurrent);
+ break;
+ default:
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/SmartTeslaAmpSetter/Client/Pages/CarSettings.razor b/SmartTeslaAmpSetter/Client/Pages/CarSettings.razor
index 0f2cb3a93..dadb8e60b 100644
--- a/SmartTeslaAmpSetter/Client/Pages/CarSettings.razor
+++ b/SmartTeslaAmpSetter/Client/Pages/CarSettings.razor
@@ -31,6 +31,11 @@ else
carBasicConfiguration.UsableEnergy = Int32.Parse(e.Value?.ToString() ?? "1"))">
+
+
+ carBasicConfiguration.ShouldBeManaged = Boolean.Parse(e.Value?.ToString() ?? "true"))">
+
}
diff --git a/SmartTeslaAmpSetter/Server/Services/ChargingService.cs b/SmartTeslaAmpSetter/Server/Services/ChargingService.cs
index 2e6919764..e137aa051 100644
--- a/SmartTeslaAmpSetter/Server/Services/ChargingService.cs
+++ b/SmartTeslaAmpSetter/Server/Services/ChargingService.cs
@@ -68,24 +68,7 @@ public async Task SetNewChargingValues(bool onlyUpdateValues = false)
_logger.LogTrace("Relevant cars: {@relevantCars}", relevantCars);
_logger.LogTrace("Irrelevant cars: {@irrlevantCars}", irrelevantCars);
- foreach (var relevantCar in relevantCars)
- {
- relevantCar.CarState.ChargingPowerAtHome = relevantCar.CarState.ChargingPower;
- }
-
- //Do not combine with irrelevant cars because then charging would never start
- foreach (var pluggedOutCar in _settings.Cars
- .Where(c => c.CarState.PluggedIn != true).ToList())
- {
- _logger.LogDebug("Resetting ChargeStart and ChargeStop for car {carId}", pluggedOutCar.Id);
- UpdateEarliestTimesAfterSwitch(pluggedOutCar.Id);
- pluggedOutCar.CarState.ChargingPowerAtHome = 0;
- }
-
- foreach (var car in irrelevantCars)
- {
- car.CarState.ChargingPowerAtHome = 0;
- }
+ UpdateChargingPowerAtHome(geofence);
if (onlyUpdateValues)
{
@@ -120,6 +103,30 @@ public async Task SetNewChargingValues(bool onlyUpdateValues = false)
}
}
+ private void UpdateChargingPowerAtHome(string geofence)
+ {
+ var carsAtHome = _settings.Cars.Where(c => c.CarState.Geofence == geofence).ToList();
+ foreach (var car in carsAtHome)
+ {
+ car.CarState.ChargingPowerAtHome = car.CarState.ChargingPower;
+ }
+ var carsNotAtHome = _settings.Cars.Where(car => !carsAtHome.Select(c => c.Id).Any(i => i == car.Id)).ToList();
+
+ foreach (var car in carsNotAtHome)
+ {
+ car.CarState.ChargingPowerAtHome = 0;
+ }
+
+ //Do not combine with irrelevant cars because then charging would never start
+ foreach (var pluggedOutCar in _settings.Cars
+ .Where(c => c.CarState.PluggedIn != true).ToList())
+ {
+ _logger.LogDebug("Resetting ChargeStart and ChargeStop for car {carId}", pluggedOutCar.Id);
+ UpdateEarliestTimesAfterSwitch(pluggedOutCar.Id);
+ pluggedOutCar.CarState.ChargingPowerAtHome = 0;
+ }
+ }
+
internal List GetIrrelevantCars(List relevantCarIds)
{
return _settings.Cars.Where(car => !relevantCarIds.Any(i => i == car.Id)).ToList();
@@ -150,6 +157,7 @@ internal List GetRelevantCarIds(string geofence)
var relevantIds = _settings.Cars
.Where(c =>
c.CarState.Geofence == geofence
+ && c.CarConfiguration.ShouldBeManaged == true
&& c.CarState.PluggedIn == true
&& (c.CarState.ClimateOn == true ||
c.CarState.ChargerActualCurrent > 0 ||
diff --git a/SmartTeslaAmpSetter/Server/Services/ConfigJsonService.cs b/SmartTeslaAmpSetter/Server/Services/ConfigJsonService.cs
index fd80c346b..e69404f49 100644
--- a/SmartTeslaAmpSetter/Server/Services/ConfigJsonService.cs
+++ b/SmartTeslaAmpSetter/Server/Services/ConfigJsonService.cs
@@ -174,6 +174,13 @@ public async Task AddCarIdsToSettings()
{
car.CarConfiguration.MinimumAmpere = 1;
}
+
+ if (car.CarConfiguration.ShouldBeManaged == null)
+ {
+ var defaultValue = true;
+ _logger.LogInformation("Car {carId}: {variable} is not set, use default value {defaultValue}", car.Id, nameof(car.CarConfiguration.ShouldBeManaged), defaultValue);
+ car.CarConfiguration.ShouldBeManaged = defaultValue;
+ }
}
_logger.LogDebug("All unset car configurations set.");
}
diff --git a/SmartTeslaAmpSetter/Server/Services/ConfigService.cs b/SmartTeslaAmpSetter/Server/Services/ConfigService.cs
index debfca457..75e85877c 100644
--- a/SmartTeslaAmpSetter/Server/Services/ConfigService.cs
+++ b/SmartTeslaAmpSetter/Server/Services/ConfigService.cs
@@ -54,6 +54,7 @@ public List GetCarBasicConfigurations()
MaximumAmpere = car.CarConfiguration.MaximumAmpere,
MinimumAmpere = car.CarConfiguration.MinimumAmpere,
UsableEnergy = car.CarConfiguration.UsableEnergy,
+ ShouldBeManaged = car.CarConfiguration.ShouldBeManaged,
});
}
@@ -67,5 +68,6 @@ public void UpdateCarBasicConfiguration(int carId, CarBasicConfiguration carBasi
car.CarConfiguration.MinimumAmpere = carBasicConfiguration.MinimumAmpere;
car.CarConfiguration.MaximumAmpere = carBasicConfiguration.MaximumAmpere;
car.CarConfiguration.UsableEnergy = carBasicConfiguration.UsableEnergy;
+ car.CarConfiguration.ShouldBeManaged = carBasicConfiguration.ShouldBeManaged;
}
}
\ No newline at end of file
diff --git a/SmartTeslaAmpSetter/Server/Services/MqttService.cs b/SmartTeslaAmpSetter/Server/Services/MqttService.cs
index 2e7b64785..d57915512 100644
--- a/SmartTeslaAmpSetter/Server/Services/MqttService.cs
+++ b/SmartTeslaAmpSetter/Server/Services/MqttService.cs
@@ -137,7 +137,7 @@ public async Task ConfigureMqttClient()
await _mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
}
- private void UpdateCar(TeslaMateValue value)
+ internal void UpdateCar(TeslaMateValue value)
{
var car = _settings.Cars.First(c => c.Id == value.CarId);
@@ -188,6 +188,13 @@ private void UpdateCar(TeslaMateValue value)
if (!string.IsNullOrWhiteSpace(value.Value))
{
car.CarState.ChargerActualCurrent = Convert.ToInt32(value.Value);
+ if (car.CarState.ChargerActualCurrent < 5 &&
+ car.CarState.LastSetAmp == car.CarState.ChargerActualCurrent - 1 &&
+ car.CarState.LastSetAmp > 0)
+ {
+ _logger.LogWarning("CarId {carId}: Reducing {actualCurrent} from {originalValue} to {newValue} due to error in TeslaApi", car.Id, nameof(car.CarState.ChargerActualCurrent), car.CarState.ChargerActualCurrent, car.CarState.LastSetAmp);
+ car.CarState.ChargerActualCurrent = car.CarState.LastSetAmp;
+ }
}
else
{
diff --git a/SmartTeslaAmpSetter/Shared/ConfigPropertyResolver.cs b/SmartTeslaAmpSetter/Shared/ConfigPropertyResolver.cs
index d0e2624a4..cfbf7c1d4 100644
--- a/SmartTeslaAmpSetter/Shared/ConfigPropertyResolver.cs
+++ b/SmartTeslaAmpSetter/Shared/ConfigPropertyResolver.cs
@@ -17,6 +17,7 @@ public class ConfigPropertyResolver : DefaultContractResolver
nameof(Car.CarConfiguration.MinimumAmpere),
nameof(Car.CarConfiguration.MaximumAmpere),
nameof(Car.CarConfiguration.UsableEnergy),
+ nameof(Car.CarConfiguration.ShouldBeManaged),
nameof(Car.Id),
};
diff --git a/SmartTeslaAmpSetter/Shared/Dtos/CarBasicConfiguration.cs b/SmartTeslaAmpSetter/Shared/Dtos/CarBasicConfiguration.cs
index 06c33e38c..2a7163a2f 100644
--- a/SmartTeslaAmpSetter/Shared/Dtos/CarBasicConfiguration.cs
+++ b/SmartTeslaAmpSetter/Shared/Dtos/CarBasicConfiguration.cs
@@ -12,4 +12,5 @@ public CarBasicConfiguration(int carId, string? carName)
public int MaximumAmpere { get; set; }
public int MinimumAmpere { get; set; }
public int UsableEnergy { get; set; }
+ public bool? ShouldBeManaged { get; set; }
}
\ No newline at end of file
diff --git a/SmartTeslaAmpSetter/Shared/Dtos/Settings/CarConfiguration.cs b/SmartTeslaAmpSetter/Shared/Dtos/Settings/CarConfiguration.cs
index b281a7b7c..3d51c13e2 100644
--- a/SmartTeslaAmpSetter/Shared/Dtos/Settings/CarConfiguration.cs
+++ b/SmartTeslaAmpSetter/Shared/Dtos/Settings/CarConfiguration.cs
@@ -11,10 +11,12 @@ public class CarConfiguration
private int _maximumAmpere;
private int _minimumAmpere;
private int _usableEnergy;
+ private bool? _shouldBeManaged;
public CarConfiguration()
{
UpdatedSincLastWrite = true;
+ _shouldBeManaged = true;
}
[JsonIgnore]
@@ -79,4 +81,14 @@ public int UsableEnergy
UpdatedSincLastWrite = true;
}
}
+
+ public bool? ShouldBeManaged
+ {
+ get => _shouldBeManaged;
+ set
+ {
+ _shouldBeManaged = value;
+ UpdatedSincLastWrite = true;
+ }
+ }
}
\ No newline at end of file