diff --git a/.github/workflows/versionRelease.yml b/.github/workflows/versionRelease.yml
index 942843485..b735f3392 100644
--- a/.github/workflows/versionRelease.yml
+++ b/.github/workflows/versionRelease.yml
@@ -72,7 +72,7 @@ jobs:
release_name="Plugins.SmaEnergymeter-$tag-${{ matrix.kind }}"
# Build everything
- dotnet publish Plugins.SmaEnergymeter/Plugins.SmaEnergymeter.csproj --runtime "${{ matrix.kind }}" -c Release -o "$release_name"
+ dotnet publish Plugins.SmaEnergymeter/Plugins.SmaEnergymeter.csproj --runtime "${{ matrix.kind }}" -c Release -o "$release_name" --self-contained
# Pack files
tar czvf "${release_name}.tar.gz" "$release_name"
diff --git a/Plugins.Modbus/Plugins.Modbus.csproj b/Plugins.Modbus/Plugins.Modbus.csproj
index cdce2cb23..e3dfc931d 100644
--- a/Plugins.Modbus/Plugins.Modbus.csproj
+++ b/Plugins.Modbus/Plugins.Modbus.csproj
@@ -9,13 +9,13 @@
-
-
+
+
-
-
+
+
diff --git a/Plugins.Modbus/Services/ModbusService.cs b/Plugins.Modbus/Services/ModbusService.cs
index 3efb34833..d1c6c5773 100644
--- a/Plugins.Modbus/Services/ModbusService.cs
+++ b/Plugins.Modbus/Services/ModbusService.cs
@@ -100,9 +100,9 @@ public async Task GetBinaryString(byte unitIdentifier, ushort startingAd
var byteArray = await GetByteArray(unitIdentifier, startingAddress, quantity, ipAddress, port, connectDelaySeconds, timeoutSeconds, modbusRegisterType, registerSwap).ConfigureAwait(false);
byteArray = byteArray.Reverse().ToArray();
var stringbuilder = new StringBuilder();
- foreach (var byteString in byteArray)
+ foreach (var byteValue in byteArray)
{
- stringbuilder.Append(Convert.ToString(byteString, 2).PadLeft(8, '0'));
+ stringbuilder.Append(Convert.ToString(byteValue, 2).PadLeft(8, '0'));
stringbuilder.Append(_byteDelimiter);
}
diff --git a/Plugins.SmaEnergymeter/Plugins.SmaEnergymeter.csproj b/Plugins.SmaEnergymeter/Plugins.SmaEnergymeter.csproj
index 857a0fa27..c50e498ed 100644
--- a/Plugins.SmaEnergymeter/Plugins.SmaEnergymeter.csproj
+++ b/Plugins.SmaEnergymeter/Plugins.SmaEnergymeter.csproj
@@ -9,9 +9,9 @@
-
-
-
+
+
+
diff --git a/Plugins.SolarEdge/Plugins.SolarEdge.csproj b/Plugins.SolarEdge/Plugins.SolarEdge.csproj
index a045cbfa5..8ef308560 100644
--- a/Plugins.SolarEdge/Plugins.SolarEdge.csproj
+++ b/Plugins.SolarEdge/Plugins.SolarEdge.csproj
@@ -9,12 +9,12 @@
-
+
-
+
diff --git a/Plugins.Solax/Plugins.Solax.csproj b/Plugins.Solax/Plugins.Solax.csproj
index ffa71da2c..8e9886f3d 100644
--- a/Plugins.Solax/Plugins.Solax.csproj
+++ b/Plugins.Solax/Plugins.Solax.csproj
@@ -8,12 +8,12 @@
-
-
+
+
-
+
diff --git a/TeslaSolarCharger.GridPriceProvider/Data/Options/FixedPriceOptions.cs b/TeslaSolarCharger.GridPriceProvider/Data/Options/FixedPriceOptions.cs
deleted file mode 100644
index 8fc032f57..000000000
--- a/TeslaSolarCharger.GridPriceProvider/Data/Options/FixedPriceOptions.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-
-namespace TeslaSolarCharger.GridPriceProvider.Data.Options;
-
-public class FixedPriceOptions
-{
- public List Prices { get; set; } = new();
-}
diff --git a/TeslaSolarCharger.GridPriceProvider/ServiceCollectionExtensions.cs b/TeslaSolarCharger.GridPriceProvider/ServiceCollectionExtensions.cs
deleted file mode 100644
index 9fd98b61a..000000000
--- a/TeslaSolarCharger.GridPriceProvider/ServiceCollectionExtensions.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using GraphQL.Client.Abstractions;
-using GraphQL.Client.Serializer.SystemTextJson;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using TeslaSolarCharger.GridPriceProvider.Services;
-using TeslaSolarCharger.GridPriceProvider.Services.Interfaces;
-
-namespace TeslaSolarCharger.GridPriceProvider;
-
-public static class ServiceCollectionExtensions
-{
- public static IServiceCollection AddGridPriceProvider(this IServiceCollection services)
- {
- services.AddHttpClient();
- services.AddTransient();
-
- return services;
- }
-}
diff --git a/TeslaSolarCharger.GridPriceProvider/Services/Interfaces/IFixedPriceService.cs b/TeslaSolarCharger.GridPriceProvider/Services/Interfaces/IFixedPriceService.cs
deleted file mode 100644
index b1279b222..000000000
--- a/TeslaSolarCharger.GridPriceProvider/Services/Interfaces/IFixedPriceService.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using TeslaSolarCharger.Shared.Dtos.ChargingCost.CostConfigurations;
-
-namespace TeslaSolarCharger.GridPriceProvider.Services.Interfaces;
-
-public interface IFixedPriceService : IPriceDataService
-{
- string GenerateConfigString(List prices);
- List ParseConfigString(string configString);
-}
diff --git a/TeslaSolarCharger.GridPriceProvider/TeslaSolarCharger.GridPriceProvider.csproj b/TeslaSolarCharger.GridPriceProvider/TeslaSolarCharger.GridPriceProvider.csproj
deleted file mode 100644
index 3a8200064..000000000
--- a/TeslaSolarCharger.GridPriceProvider/TeslaSolarCharger.GridPriceProvider.csproj
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
- net8.0
- enable
- enable
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/TeslaSolarCharger.Model/BaseClasses/JsonXmlResultConfigurationBase.cs b/TeslaSolarCharger.Model/BaseClasses/JsonXmlResultConfigurationBase.cs
new file mode 100644
index 000000000..1feeb4080
--- /dev/null
+++ b/TeslaSolarCharger.Model/BaseClasses/JsonXmlResultConfigurationBase.cs
@@ -0,0 +1,9 @@
+namespace TeslaSolarCharger.Model.BaseClasses;
+
+public abstract class JsonXmlResultConfigurationBase : ResultConfigurationBase
+{
+ public string? NodePattern { get; set; }
+ public string? XmlAttributeHeaderName { get; set; }
+ public string? XmlAttributeHeaderValue { get; set; }
+ public string? XmlAttributeValueName { get; set; }
+}
diff --git a/TeslaSolarCharger.Model/BaseClasses/ResultConfigurationBase.cs b/TeslaSolarCharger.Model/BaseClasses/ResultConfigurationBase.cs
new file mode 100644
index 000000000..01ceebe30
--- /dev/null
+++ b/TeslaSolarCharger.Model/BaseClasses/ResultConfigurationBase.cs
@@ -0,0 +1,11 @@
+using TeslaSolarCharger.SharedModel.Enums;
+
+namespace TeslaSolarCharger.Model.BaseClasses;
+
+public abstract class ResultConfigurationBase
+{
+ public int Id { get; set; }
+ public decimal CorrectionFactor { get; set; }
+ public ValueUsage UsedFor { get; set; }
+ public ValueOperator Operator { get; set; }
+}
diff --git a/TeslaSolarCharger.Model/Contracts/ITeslaSolarChargerContext.cs b/TeslaSolarCharger.Model/Contracts/ITeslaSolarChargerContext.cs
index 3cca7c22d..b97667725 100644
--- a/TeslaSolarCharger.Model/Contracts/ITeslaSolarChargerContext.cs
+++ b/TeslaSolarCharger.Model/Contracts/ITeslaSolarChargerContext.cs
@@ -18,5 +18,14 @@ public interface ITeslaSolarChargerContext
DbSet TeslaTokens { get; set; }
DbSet TscConfigurations { get; set; }
DbSet Cars { get; set; }
+ DbSet RestValueConfigurations { get; set; }
+ DbSet RestValueConfigurationHeaders { get; set; }
+ DbSet RestValueResultConfigurations { get; set; }
+ DbSet ChargingProcesses { get; set; }
+ DbSet ChargingDetails { get; set; }
+ DbSet ModbusConfigurations { get; set; }
+ DbSet ModbusResultConfigurations { get; set; }
+ DbSet MqttConfigurations { get; set; }
+ DbSet MqttResultConfigurations { get; set; }
void RejectChanges();
}
diff --git a/TeslaSolarCharger.Model/Converters/LocalDateTimeConverter.cs b/TeslaSolarCharger.Model/Converters/LocalDateTimeConverter.cs
new file mode 100644
index 000000000..287844ceb
--- /dev/null
+++ b/TeslaSolarCharger.Model/Converters/LocalDateTimeConverter.cs
@@ -0,0 +1,13 @@
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+namespace TeslaSolarCharger.Model.Converters;
+
+public class LocalDateTimeConverter : ValueConverter
+{
+ public LocalDateTimeConverter()
+ : base(
+ v => v.ToUniversalTime(), // Store as UTC
+ v => DateTime.SpecifyKind(v, DateTimeKind.Utc).ToLocalTime()) // Convert to Local on read
+ {
+ }
+}
diff --git a/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/Car.cs b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/Car.cs
index 00f012c34..02ac603f5 100644
--- a/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/Car.cs
+++ b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/Car.cs
@@ -6,6 +6,41 @@ namespace TeslaSolarCharger.Model.Entities.TeslaSolarCharger;
public class Car
{
public int Id { get; set; }
- public int TeslaMateCarId { get; set; }
+ public int? TeslaMateCarId { get; set; }
+ public string? Name { get; set; }
+ public string? Vin { get; set; }
public TeslaCarFleetApiState TeslaFleetApiState { get; set; } = TeslaCarFleetApiState.NotConfigured;
+ public ChargeMode ChargeMode { get; set; }
+ public int MinimumSoc { get; set; }
+ public DateTime LatestTimeToReachSoC { get; set; }
+
+ public bool IgnoreLatestTimeToReachSocDate { get; set; }
+
+ public int MaximumAmpere { get; set; }
+
+ public int MinimumAmpere { get; set; }
+
+ public int UsableEnergy { get; set; }
+
+ public bool? ShouldBeManaged { get; set; }
+ public bool? ShouldSetChargeStartTimes { get; set; }
+
+ public int ChargingPriority { get; set; }
+
+ public int? SoC { get; set; }
+ public int? SocLimit { get; set; }
+
+ public int? ChargerPhases { get; set; }
+ public int? ChargerVoltage { get; set; }
+ public int? ChargerActualCurrent { get; set; }
+ public int? ChargerPilotCurrent { get; set; }
+ public int? ChargerRequestedCurrent { get; set; }
+ public bool? PluggedIn { get; set; }
+ public bool? ClimateOn { get; set; }
+ public double? Latitude { get; set; }
+ public double? Longitude { get; set; }
+ public CarStateEnum? State { get; set; }
+ public bool VehicleCommandProtocolRequired { get; set; }
+
+ public List ChargingProcesses { get; set; } = new List();
}
diff --git a/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/ChargingDetail.cs b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/ChargingDetail.cs
new file mode 100644
index 000000000..ede04afcd
--- /dev/null
+++ b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/ChargingDetail.cs
@@ -0,0 +1,13 @@
+namespace TeslaSolarCharger.Model.Entities.TeslaSolarCharger;
+
+public class ChargingDetail
+{
+ public int Id { get; set; }
+ public DateTime TimeStamp { get; set; }
+ public int SolarPower { get; set; }
+ public int GridPower { get; set; }
+
+ public int ChargingProcessId { get; set; }
+
+ public ChargingProcess ChargingProcess { get; set; } = null!;
+}
diff --git a/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/ChargingProcess.cs b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/ChargingProcess.cs
new file mode 100644
index 000000000..a353ac2d6
--- /dev/null
+++ b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/ChargingProcess.cs
@@ -0,0 +1,18 @@
+namespace TeslaSolarCharger.Model.Entities.TeslaSolarCharger;
+
+public class ChargingProcess
+{
+ public int Id { get; set; }
+ public DateTime StartDate { get; set; }
+ public DateTime? EndDate { get; set; }
+ public decimal? UsedGridEnergyKwh { get; set; }
+ public decimal? UsedSolarEnergyKwh { get; set; }
+ public decimal? Cost { get; set; }
+ public int? OldHandledChargeId { get; set; }
+
+ public int CarId { get; set; }
+
+ public Car Car { get; set; } = null!;
+
+ public List ChargingDetails { get; set; } = new();
+}
diff --git a/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/ModbusConfiguration.cs b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/ModbusConfiguration.cs
new file mode 100644
index 000000000..f2d629f36
--- /dev/null
+++ b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/ModbusConfiguration.cs
@@ -0,0 +1,17 @@
+using TeslaSolarCharger.Model.BaseClasses;
+using TeslaSolarCharger.Shared.Enums;
+
+namespace TeslaSolarCharger.Model.Entities.TeslaSolarCharger;
+
+public class ModbusConfiguration
+{
+ public int Id { get; set; }
+ public int UnitIdentifier { get; set; }
+ public string Host { get; set; }
+ public int Port { get; set; }
+ public ModbusEndianess Endianess { get; set; }
+ public int ConnectDelayMilliseconds { get; set; }
+ public int ReadTimeoutMilliseconds { get; set; }
+
+ public List ModbusResultConfigurations { get; set; }
+}
diff --git a/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/ModbusResultConfiguration.cs b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/ModbusResultConfiguration.cs
new file mode 100644
index 000000000..fa8cb253b
--- /dev/null
+++ b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/ModbusResultConfiguration.cs
@@ -0,0 +1,20 @@
+using TeslaSolarCharger.Model.BaseClasses;
+using TeslaSolarCharger.Shared.Enums;
+
+namespace TeslaSolarCharger.Model.Entities.TeslaSolarCharger;
+
+public class ModbusResultConfiguration : ResultConfigurationBase
+{
+ public ModbusRegisterType RegisterType { get; set; }
+ public ModbusValueType ValueType { get; set; }
+ public int Address { get; set; }
+ public int Length { get; set; }
+ public int? BitStartIndex { get; set; }
+
+ public int ModbusConfigurationId { get; set; }
+ public int? InvertedByModbusResultConfigurationId { get; set; }
+
+ public ModbusConfiguration ModbusConfiguration { get; set; }
+ public ModbusResultConfiguration? InvertedByModbusResultConfiguration { get; set; }
+
+}
diff --git a/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/MqttConfiguration.cs b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/MqttConfiguration.cs
new file mode 100644
index 000000000..ae7fab97c
--- /dev/null
+++ b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/MqttConfiguration.cs
@@ -0,0 +1,12 @@
+namespace TeslaSolarCharger.Model.Entities.TeslaSolarCharger;
+
+public class MqttConfiguration
+{
+ public int Id { get; set; }
+ public string Host { get; set; }
+ public int Port { get; set; } = 1883;
+ public string? Username { get; set; }
+ public string? Password { get; set; }
+
+ public List? MqttResultConfigurations { get; set; }
+}
diff --git a/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/MqttResultConfiguration.cs b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/MqttResultConfiguration.cs
new file mode 100644
index 000000000..39d2b2376
--- /dev/null
+++ b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/MqttResultConfiguration.cs
@@ -0,0 +1,13 @@
+using TeslaSolarCharger.Model.BaseClasses;
+using TeslaSolarCharger.SharedModel.Enums;
+
+namespace TeslaSolarCharger.Model.Entities.TeslaSolarCharger;
+
+public class MqttResultConfiguration : JsonXmlResultConfigurationBase
+{
+ public NodePatternType NodePatternType { get; set; }
+ public string Topic { get; set; }
+
+ public int MqttConfigurationId { get; set; }
+ public MqttConfiguration MqttConfiguration { get; set; } = null!;
+}
diff --git a/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/RestValueConfiguration.cs b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/RestValueConfiguration.cs
new file mode 100644
index 000000000..f024908ed
--- /dev/null
+++ b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/RestValueConfiguration.cs
@@ -0,0 +1,14 @@
+using TeslaSolarCharger.SharedModel.Enums;
+
+namespace TeslaSolarCharger.Model.Entities.TeslaSolarCharger;
+
+public class RestValueConfiguration
+{
+ public int Id { get; set; }
+ public string Url { get; set; }
+ public NodePatternType NodePatternType { get; set; }
+ public HttpVerb HttpMethod { get; set; }
+
+ public List Headers { get; set; } = new();
+ public List RestValueResultConfigurations { get; set; } = new();
+}
diff --git a/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/RestValueConfigurationHeader.cs b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/RestValueConfigurationHeader.cs
new file mode 100644
index 000000000..571499133
--- /dev/null
+++ b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/RestValueConfigurationHeader.cs
@@ -0,0 +1,11 @@
+namespace TeslaSolarCharger.Model.Entities.TeslaSolarCharger;
+
+public class RestValueConfigurationHeader
+{
+ public int Id { get; set; }
+ public string Key { get; set; }
+ public string Value { get; set; }
+
+ public int RestValueConfigurationId { get; set; }
+ public RestValueConfiguration RestValueConfiguration { get; set; }
+}
diff --git a/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/RestValueResultConfiguration.cs b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/RestValueResultConfiguration.cs
new file mode 100644
index 000000000..b381e4ef7
--- /dev/null
+++ b/TeslaSolarCharger.Model/Entities/TeslaSolarCharger/RestValueResultConfiguration.cs
@@ -0,0 +1,10 @@
+using TeslaSolarCharger.Model.BaseClasses;
+using TeslaSolarCharger.SharedModel.Enums;
+
+namespace TeslaSolarCharger.Model.Entities.TeslaSolarCharger;
+
+public class RestValueResultConfiguration : JsonXmlResultConfigurationBase
+{
+ public int RestValueConfigurationId { get; set; }
+ public RestValueConfiguration RestValueConfiguration { get; set; }
+}
diff --git a/TeslaSolarCharger.Model/EntityFramework/TeslaSolarChargerContext.cs b/TeslaSolarCharger.Model/EntityFramework/TeslaSolarChargerContext.cs
index f13e1e1b1..546ff1052 100644
--- a/TeslaSolarCharger.Model/EntityFramework/TeslaSolarChargerContext.cs
+++ b/TeslaSolarCharger.Model/EntityFramework/TeslaSolarChargerContext.cs
@@ -1,5 +1,7 @@
using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using TeslaSolarCharger.Model.Contracts;
+using TeslaSolarCharger.Model.Converters;
using TeslaSolarCharger.Model.Entities.TeslaSolarCharger;
using TeslaSolarCharger.Shared.Enums;
@@ -15,7 +17,15 @@ public class TeslaSolarChargerContext : DbContext, ITeslaSolarChargerContext
public DbSet TeslaTokens { get; set; } = null!;
public DbSet TscConfigurations { get; set; } = null!;
public DbSet Cars { get; set; } = null!;
-
+ public DbSet RestValueConfigurations { get; set; } = null!;
+ public DbSet RestValueConfigurationHeaders { get; set; } = null!;
+ public DbSet RestValueResultConfigurations { get; set; } = null!;
+ public DbSet ChargingProcesses { get; set; } = null!;
+ public DbSet ChargingDetails { get; set; } = null!;
+ public DbSet ModbusConfigurations { get; set; } = null!;
+ public DbSet ModbusResultConfigurations { get; set; } = null!;
+ public DbSet MqttConfigurations { get; set; } = null!;
+ public DbSet MqttResultConfigurations { get; set; } = null!;
// ReSharper disable once UnassignedGetOnlyAutoProperty
public string DbPath { get; }
@@ -41,6 +51,38 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
+ var dateTimeConverter = new ValueConverter(
+ v => v, v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
+
+ var dateTimeNullableConverter = new ValueConverter(
+ v => v, v => v.HasValue ? DateTime.SpecifyKind(v.Value, DateTimeKind.Utc) : v);
+
+ foreach (var entityType in modelBuilder.Model.GetEntityTypes())
+ {
+ foreach (var property in entityType.GetProperties())
+ {
+
+ if (entityType.ClrType == typeof(Car) && property.Name == nameof(Car.LatestTimeToReachSoC))
+ {
+ continue;
+ }
+ if (property.ClrType == typeof(DateTime))
+ {
+ property.SetValueConverter(dateTimeConverter);
+ }
+ else if (property.ClrType == typeof(DateTime?))
+ {
+ property.SetValueConverter(dateTimeNullableConverter);
+ }
+ }
+ }
+
+ var converter = new LocalDateTimeConverter();
+
+ modelBuilder.Entity()
+ .Property(c => c.LatestTimeToReachSoC)
+ .HasConversion(converter);
+
modelBuilder.Entity()
.Property(c => c.EnergyProvider)
.HasDefaultValue(EnergyProvider.OldTeslaSolarChargerConfig);
@@ -52,6 +94,14 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.Entity()
.HasIndex(c => c.TeslaMateCarId)
.IsUnique();
+
+ modelBuilder.Entity()
+ .HasIndex(c => c.Vin)
+ .IsUnique();
+
+ modelBuilder.Entity()
+ .HasIndex(h => new { h.RestValueConfigurationId, h.Key })
+ .IsUnique();
}
#pragma warning disable CS8618
diff --git a/TeslaSolarCharger.Model/Migrations/20240223001353_AddCarConfigurationValues.Designer.cs b/TeslaSolarCharger.Model/Migrations/20240223001353_AddCarConfigurationValues.Designer.cs
new file mode 100644
index 000000000..42466d9f4
--- /dev/null
+++ b/TeslaSolarCharger.Model/Migrations/20240223001353_AddCarConfigurationValues.Designer.cs
@@ -0,0 +1,288 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using TeslaSolarCharger.Model.EntityFramework;
+
+#nullable disable
+
+namespace TeslaSolarCharger.Model.Migrations
+{
+ [DbContext(typeof(TeslaSolarChargerContext))]
+ [Migration("20240223001353_AddCarConfigurationValues")]
+ partial class AddCarConfigurationValues
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "8.0.0");
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.CachedCarState", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("CarId")
+ .HasColumnType("INTEGER");
+
+ b.Property("CarStateJson")
+ .HasColumnType("TEXT");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("LastUpdated")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("CachedCarStates");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.Car", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargeMode")
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargingPriority")
+ .HasColumnType("INTEGER");
+
+ b.Property("IgnoreLatestTimeToReachSocDate")
+ .HasColumnType("INTEGER");
+
+ b.Property("LatestTimeToReachSoC")
+ .HasColumnType("TEXT");
+
+ b.Property("MaximumAmpere")
+ .HasColumnType("INTEGER");
+
+ b.Property("MinimumAmpere")
+ .HasColumnType("INTEGER");
+
+ b.Property("MinimumSoc")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("ShouldBeManaged")
+ .HasColumnType("INTEGER");
+
+ b.Property("ShouldSetChargeStartTimes")
+ .HasColumnType("INTEGER");
+
+ b.Property("TeslaFleetApiState")
+ .HasColumnType("INTEGER");
+
+ b.Property("TeslaMateCarId")
+ .HasColumnType("INTEGER");
+
+ b.Property("UsableEnergy")
+ .HasColumnType("INTEGER");
+
+ b.Property("Vin")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TeslaMateCarId")
+ .IsUnique();
+
+ b.ToTable("Cars");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.ChargePrice", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AddSpotPriceToGridPrice")
+ .HasColumnType("INTEGER");
+
+ b.Property("EnergyProvider")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(6);
+
+ b.Property("EnergyProviderConfiguration")
+ .HasColumnType("TEXT");
+
+ b.Property("GridPrice")
+ .HasColumnType("TEXT");
+
+ b.Property("SolarPrice")
+ .HasColumnType("TEXT");
+
+ b.Property("SpotPriceCorrectionFactor")
+ .HasColumnType("TEXT");
+
+ b.Property("ValidSince")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("ChargePrices");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.HandledCharge", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AverageSpotPrice")
+ .HasColumnType("TEXT");
+
+ b.Property("CalculatedPrice")
+ .HasColumnType("TEXT");
+
+ b.Property("CarId")
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargingProcessId")
+ .HasColumnType("INTEGER");
+
+ b.Property("UsedGridEnergy")
+ .HasColumnType("TEXT");
+
+ b.Property("UsedSolarEnergy")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("HandledCharges");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.PowerDistribution", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargingPower")
+ .HasColumnType("INTEGER");
+
+ b.Property("GridProportion")
+ .HasColumnType("REAL");
+
+ b.Property("HandledChargeId")
+ .HasColumnType("INTEGER");
+
+ b.Property("PowerFromGrid")
+ .HasColumnType("INTEGER");
+
+ b.Property("TimeStamp")
+ .HasColumnType("TEXT");
+
+ b.Property("UsedWattHours")
+ .HasColumnType("REAL");
+
+ b.HasKey("Id");
+
+ b.HasIndex("HandledChargeId");
+
+ b.ToTable("PowerDistributions");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.SpotPrice", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("EndDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Price")
+ .HasColumnType("TEXT");
+
+ b.Property("StartDate")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("SpotPrices");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.TeslaToken", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AccessToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("ExpiresAtUtc")
+ .HasColumnType("TEXT");
+
+ b.Property("IdToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("RefreshToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Region")
+ .HasColumnType("INTEGER");
+
+ b.Property("UnauthorizedCounter")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("TeslaTokens");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.TscConfiguration", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Key")
+ .IsUnique();
+
+ b.ToTable("TscConfigurations");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.PowerDistribution", b =>
+ {
+ b.HasOne("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.HandledCharge", "HandledCharge")
+ .WithMany("PowerDistributions")
+ .HasForeignKey("HandledChargeId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("HandledCharge");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.HandledCharge", b =>
+ {
+ b.Navigation("PowerDistributions");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/TeslaSolarCharger.Model/Migrations/20240223001353_AddCarConfigurationValues.cs b/TeslaSolarCharger.Model/Migrations/20240223001353_AddCarConfigurationValues.cs
new file mode 100644
index 000000000..7c90b5fbb
--- /dev/null
+++ b/TeslaSolarCharger.Model/Migrations/20240223001353_AddCarConfigurationValues.cs
@@ -0,0 +1,147 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace TeslaSolarCharger.Model.Migrations
+{
+ ///
+ public partial class AddCarConfigurationValues : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "ChargeMode",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.AddColumn(
+ name: "ChargingPriority",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.AddColumn(
+ name: "IgnoreLatestTimeToReachSocDate",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: false,
+ defaultValue: false);
+
+ migrationBuilder.AddColumn(
+ name: "LatestTimeToReachSoC",
+ table: "Cars",
+ type: "TEXT",
+ nullable: false,
+ defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
+
+ migrationBuilder.AddColumn(
+ name: "MaximumAmpere",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.AddColumn(
+ name: "MinimumAmpere",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.AddColumn(
+ name: "MinimumSoc",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.AddColumn(
+ name: "Name",
+ table: "Cars",
+ type: "TEXT",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "ShouldBeManaged",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "ShouldSetChargeStartTimes",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "UsableEnergy",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.AddColumn(
+ name: "Vin",
+ table: "Cars",
+ type: "TEXT",
+ nullable: true);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "ChargeMode",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "ChargingPriority",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "IgnoreLatestTimeToReachSocDate",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "LatestTimeToReachSoC",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "MaximumAmpere",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "MinimumAmpere",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "MinimumSoc",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "Name",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "ShouldBeManaged",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "ShouldSetChargeStartTimes",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "UsableEnergy",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "Vin",
+ table: "Cars");
+ }
+ }
+}
diff --git a/TeslaSolarCharger.Model/Migrations/20240224101036_MakeCarVinUnique.Designer.cs b/TeslaSolarCharger.Model/Migrations/20240224101036_MakeCarVinUnique.Designer.cs
new file mode 100644
index 000000000..3c01fe718
--- /dev/null
+++ b/TeslaSolarCharger.Model/Migrations/20240224101036_MakeCarVinUnique.Designer.cs
@@ -0,0 +1,291 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using TeslaSolarCharger.Model.EntityFramework;
+
+#nullable disable
+
+namespace TeslaSolarCharger.Model.Migrations
+{
+ [DbContext(typeof(TeslaSolarChargerContext))]
+ [Migration("20240224101036_MakeCarVinUnique")]
+ partial class MakeCarVinUnique
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "8.0.0");
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.CachedCarState", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("CarId")
+ .HasColumnType("INTEGER");
+
+ b.Property("CarStateJson")
+ .HasColumnType("TEXT");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("LastUpdated")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("CachedCarStates");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.Car", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargeMode")
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargingPriority")
+ .HasColumnType("INTEGER");
+
+ b.Property("IgnoreLatestTimeToReachSocDate")
+ .HasColumnType("INTEGER");
+
+ b.Property("LatestTimeToReachSoC")
+ .HasColumnType("TEXT");
+
+ b.Property("MaximumAmpere")
+ .HasColumnType("INTEGER");
+
+ b.Property("MinimumAmpere")
+ .HasColumnType("INTEGER");
+
+ b.Property("MinimumSoc")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("ShouldBeManaged")
+ .HasColumnType("INTEGER");
+
+ b.Property("ShouldSetChargeStartTimes")
+ .HasColumnType("INTEGER");
+
+ b.Property("TeslaFleetApiState")
+ .HasColumnType("INTEGER");
+
+ b.Property("TeslaMateCarId")
+ .HasColumnType("INTEGER");
+
+ b.Property("UsableEnergy")
+ .HasColumnType("INTEGER");
+
+ b.Property("Vin")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TeslaMateCarId")
+ .IsUnique();
+
+ b.HasIndex("Vin")
+ .IsUnique();
+
+ b.ToTable("Cars");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.ChargePrice", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AddSpotPriceToGridPrice")
+ .HasColumnType("INTEGER");
+
+ b.Property("EnergyProvider")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(6);
+
+ b.Property("EnergyProviderConfiguration")
+ .HasColumnType("TEXT");
+
+ b.Property("GridPrice")
+ .HasColumnType("TEXT");
+
+ b.Property("SolarPrice")
+ .HasColumnType("TEXT");
+
+ b.Property("SpotPriceCorrectionFactor")
+ .HasColumnType("TEXT");
+
+ b.Property("ValidSince")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("ChargePrices");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.HandledCharge", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AverageSpotPrice")
+ .HasColumnType("TEXT");
+
+ b.Property("CalculatedPrice")
+ .HasColumnType("TEXT");
+
+ b.Property("CarId")
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargingProcessId")
+ .HasColumnType("INTEGER");
+
+ b.Property("UsedGridEnergy")
+ .HasColumnType("TEXT");
+
+ b.Property("UsedSolarEnergy")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("HandledCharges");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.PowerDistribution", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargingPower")
+ .HasColumnType("INTEGER");
+
+ b.Property("GridProportion")
+ .HasColumnType("REAL");
+
+ b.Property("HandledChargeId")
+ .HasColumnType("INTEGER");
+
+ b.Property("PowerFromGrid")
+ .HasColumnType("INTEGER");
+
+ b.Property("TimeStamp")
+ .HasColumnType("TEXT");
+
+ b.Property("UsedWattHours")
+ .HasColumnType("REAL");
+
+ b.HasKey("Id");
+
+ b.HasIndex("HandledChargeId");
+
+ b.ToTable("PowerDistributions");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.SpotPrice", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("EndDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Price")
+ .HasColumnType("TEXT");
+
+ b.Property("StartDate")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("SpotPrices");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.TeslaToken", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AccessToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("ExpiresAtUtc")
+ .HasColumnType("TEXT");
+
+ b.Property("IdToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("RefreshToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Region")
+ .HasColumnType("INTEGER");
+
+ b.Property("UnauthorizedCounter")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("TeslaTokens");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.TscConfiguration", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Key")
+ .IsUnique();
+
+ b.ToTable("TscConfigurations");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.PowerDistribution", b =>
+ {
+ b.HasOne("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.HandledCharge", "HandledCharge")
+ .WithMany("PowerDistributions")
+ .HasForeignKey("HandledChargeId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("HandledCharge");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.HandledCharge", b =>
+ {
+ b.Navigation("PowerDistributions");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/TeslaSolarCharger.Model/Migrations/20240224101036_MakeCarVinUnique.cs b/TeslaSolarCharger.Model/Migrations/20240224101036_MakeCarVinUnique.cs
new file mode 100644
index 000000000..f6dba3d05
--- /dev/null
+++ b/TeslaSolarCharger.Model/Migrations/20240224101036_MakeCarVinUnique.cs
@@ -0,0 +1,28 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace TeslaSolarCharger.Model.Migrations
+{
+ ///
+ public partial class MakeCarVinUnique : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateIndex(
+ name: "IX_Cars_Vin",
+ table: "Cars",
+ column: "Vin",
+ unique: true);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropIndex(
+ name: "IX_Cars_Vin",
+ table: "Cars");
+ }
+ }
+}
diff --git a/TeslaSolarCharger.Model/Migrations/20240225190616_AddCarStatesToCarsTable.Designer.cs b/TeslaSolarCharger.Model/Migrations/20240225190616_AddCarStatesToCarsTable.Designer.cs
new file mode 100644
index 000000000..31d5ffd23
--- /dev/null
+++ b/TeslaSolarCharger.Model/Migrations/20240225190616_AddCarStatesToCarsTable.Designer.cs
@@ -0,0 +1,327 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using TeslaSolarCharger.Model.EntityFramework;
+
+#nullable disable
+
+namespace TeslaSolarCharger.Model.Migrations
+{
+ [DbContext(typeof(TeslaSolarChargerContext))]
+ [Migration("20240225190616_AddCarStatesToCarsTable")]
+ partial class AddCarStatesToCarsTable
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "8.0.2");
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.CachedCarState", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("CarId")
+ .HasColumnType("INTEGER");
+
+ b.Property("CarStateJson")
+ .HasColumnType("TEXT");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("LastUpdated")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("CachedCarStates");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.Car", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargeMode")
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargerActualCurrent")
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargerPhases")
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargerPilotCurrent")
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargerRequestedCurrent")
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargerVoltage")
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargingPriority")
+ .HasColumnType("INTEGER");
+
+ b.Property("ClimateOn")
+ .HasColumnType("INTEGER");
+
+ b.Property("IgnoreLatestTimeToReachSocDate")
+ .HasColumnType("INTEGER");
+
+ b.Property("LatestTimeToReachSoC")
+ .HasColumnType("TEXT");
+
+ b.Property("Latitude")
+ .HasColumnType("REAL");
+
+ b.Property("Longitude")
+ .HasColumnType("REAL");
+
+ b.Property("MaximumAmpere")
+ .HasColumnType("INTEGER");
+
+ b.Property("MinimumAmpere")
+ .HasColumnType("INTEGER");
+
+ b.Property("MinimumSoc")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("PluggedIn")
+ .HasColumnType("INTEGER");
+
+ b.Property("ShouldBeManaged")
+ .HasColumnType("INTEGER");
+
+ b.Property("ShouldSetChargeStartTimes")
+ .HasColumnType("INTEGER");
+
+ b.Property("SoC")
+ .HasColumnType("INTEGER");
+
+ b.Property("SocLimit")
+ .HasColumnType("INTEGER");
+
+ b.Property("State")
+ .HasColumnType("INTEGER");
+
+ b.Property("TeslaFleetApiState")
+ .HasColumnType("INTEGER");
+
+ b.Property("TeslaMateCarId")
+ .HasColumnType("INTEGER");
+
+ b.Property("UsableEnergy")
+ .HasColumnType("INTEGER");
+
+ b.Property("Vin")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TeslaMateCarId")
+ .IsUnique();
+
+ b.HasIndex("Vin")
+ .IsUnique();
+
+ b.ToTable("Cars");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.ChargePrice", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AddSpotPriceToGridPrice")
+ .HasColumnType("INTEGER");
+
+ b.Property("EnergyProvider")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(6);
+
+ b.Property("EnergyProviderConfiguration")
+ .HasColumnType("TEXT");
+
+ b.Property("GridPrice")
+ .HasColumnType("TEXT");
+
+ b.Property("SolarPrice")
+ .HasColumnType("TEXT");
+
+ b.Property("SpotPriceCorrectionFactor")
+ .HasColumnType("TEXT");
+
+ b.Property("ValidSince")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("ChargePrices");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.HandledCharge", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AverageSpotPrice")
+ .HasColumnType("TEXT");
+
+ b.Property("CalculatedPrice")
+ .HasColumnType("TEXT");
+
+ b.Property("CarId")
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargingProcessId")
+ .HasColumnType("INTEGER");
+
+ b.Property("UsedGridEnergy")
+ .HasColumnType("TEXT");
+
+ b.Property("UsedSolarEnergy")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("HandledCharges");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.PowerDistribution", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ChargingPower")
+ .HasColumnType("INTEGER");
+
+ b.Property("GridProportion")
+ .HasColumnType("REAL");
+
+ b.Property("HandledChargeId")
+ .HasColumnType("INTEGER");
+
+ b.Property("PowerFromGrid")
+ .HasColumnType("INTEGER");
+
+ b.Property("TimeStamp")
+ .HasColumnType("TEXT");
+
+ b.Property("UsedWattHours")
+ .HasColumnType("REAL");
+
+ b.HasKey("Id");
+
+ b.HasIndex("HandledChargeId");
+
+ b.ToTable("PowerDistributions");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.SpotPrice", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("EndDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Price")
+ .HasColumnType("TEXT");
+
+ b.Property("StartDate")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("SpotPrices");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.TeslaToken", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("AccessToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("ExpiresAtUtc")
+ .HasColumnType("TEXT");
+
+ b.Property("IdToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("RefreshToken")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Region")
+ .HasColumnType("INTEGER");
+
+ b.Property("UnauthorizedCounter")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("TeslaTokens");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.TscConfiguration", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Key")
+ .IsUnique();
+
+ b.ToTable("TscConfigurations");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.PowerDistribution", b =>
+ {
+ b.HasOne("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.HandledCharge", "HandledCharge")
+ .WithMany("PowerDistributions")
+ .HasForeignKey("HandledChargeId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("HandledCharge");
+ });
+
+ modelBuilder.Entity("TeslaSolarCharger.Model.Entities.TeslaSolarCharger.HandledCharge", b =>
+ {
+ b.Navigation("PowerDistributions");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/TeslaSolarCharger.Model/Migrations/20240225190616_AddCarStatesToCarsTable.cs b/TeslaSolarCharger.Model/Migrations/20240225190616_AddCarStatesToCarsTable.cs
new file mode 100644
index 000000000..7a35e5184
--- /dev/null
+++ b/TeslaSolarCharger.Model/Migrations/20240225190616_AddCarStatesToCarsTable.cs
@@ -0,0 +1,156 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace TeslaSolarCharger.Model.Migrations
+{
+ ///
+ public partial class AddCarStatesToCarsTable : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterColumn(
+ name: "TeslaMateCarId",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true,
+ oldClrType: typeof(int),
+ oldType: "INTEGER");
+
+ migrationBuilder.AddColumn(
+ name: "ChargerActualCurrent",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "ChargerPhases",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "ChargerPilotCurrent",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "ChargerRequestedCurrent",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "ChargerVoltage",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "ClimateOn",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "Latitude",
+ table: "Cars",
+ type: "REAL",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "Longitude",
+ table: "Cars",
+ type: "REAL",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "PluggedIn",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "SoC",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "SocLimit",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true);
+
+ migrationBuilder.AddColumn(
+ name: "State",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: true);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "ChargerActualCurrent",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "ChargerPhases",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "ChargerPilotCurrent",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "ChargerRequestedCurrent",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "ChargerVoltage",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "ClimateOn",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "Latitude",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "Longitude",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "PluggedIn",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "SoC",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "SocLimit",
+ table: "Cars");
+
+ migrationBuilder.DropColumn(
+ name: "State",
+ table: "Cars");
+
+ migrationBuilder.AlterColumn(
+ name: "TeslaMateCarId",
+ table: "Cars",
+ type: "INTEGER",
+ nullable: false,
+ defaultValue: 0,
+ oldClrType: typeof(int),
+ oldType: "INTEGER",
+ oldNullable: true);
+ }
+ }
+}
diff --git a/TeslaSolarCharger.Model/Migrations/20240303140452_AddRestValueConfigurations.Designer.cs b/TeslaSolarCharger.Model/Migrations/20240303140452_AddRestValueConfigurations.Designer.cs
new file mode 100644
index 000000000..339b47e1a
--- /dev/null
+++ b/TeslaSolarCharger.Model/Migrations/20240303140452_AddRestValueConfigurations.Designer.cs
@@ -0,0 +1,439 @@
+//