Skip to content

Commit

Permalink
Fix timezone related issues in FixedPrice provider and add tests for …
Browse files Browse the repository at this point in the history
…those scenarios

Also clarify documentation/tests around the unit for FixedPrice (which even I got wrong!)
  • Loading branch information
Matt Jeanes committed Jul 4, 2021
1 parent 6d79f0f commit 02f2991
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 64 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ See below for how to configure the environment variables appropriately
```yaml
- TeslaMate__EnergyProvider=FixedPrice
- FixedPrice__TimeZone=Europe/London # IANA (tz database) time zone code, used for below times
- FixedPrice__Prices__0=08:00-13:00=1.5 # You can have as many as these as you need
- FixedPrice__Prices__1=13:00-20:00=5
- FixedPrice__Prices__0=08:00-13:00=0.1559 # Cost is in your currency e.g. pounds, euros, dollars (not pennies, cents, etc)
- FixedPrice__Prices__1=13:00-20:00=0.05 # You can have as many as these as you need
- FixedPrice__Prices__2=20:00-03:30=4
- FixedPrice__Prices__3=03:30-06:00=3.5
- FixedPrice__Prices__4=06:00-08:00=2
Expand Down
162 changes: 105 additions & 57 deletions TeslaMateAgile.Tests/Services/FixedPriceServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
"Etc/UTC",
new List<string>
{
"08:00-13:00=1.5",
"13:00-20:00=5",
"20:00-03:30=4",
"03:30-06:00=3.5",
"06:00-08:00=2",
"08:00-13:00=0.015",
"13:00-20:00=0.05",
"20:00-03:30=0.04",
"03:30-06:00=0.035",
"06:00-08:00=0.02",
},
DateTimeOffset.Parse("2021-02-01T03:00:00Z"),
DateTimeOffset.Parse("2021-02-01T18:00:00Z"),
Expand All @@ -39,31 +39,31 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
{
ValidFrom = DateTimeOffset.Parse("2021-01-31T20:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-01T03:30:00Z"),
Value = 4M
Value = 0.04M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T03:30:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-01T06:00:00Z"),
Value = 3.5M
Value = 0.035M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T06:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-01T08:00:00Z"),
Value = 2M
Value = 0.02M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T08:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-01T13:00:00Z"),
Value = 1.5M
Value = 0.015M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T13:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-01T20:00:00Z"),
Value = 5M
Value = 0.05M
}
}
},
Expand All @@ -73,11 +73,11 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
"Etc/UTC",
new List<string>
{
"08:00-13:00=1.5",
"13:00-20:00=5",
"20:00-03:30=4",
"03:30-06:00=3.5",
"06:00-08:00=2",
"08:00-13:00=0.015",
"13:00-20:00=0.05",
"20:00-03:30=0.04",
"03:30-06:00=0.035",
"06:00-08:00=0.02",
},
DateTimeOffset.Parse("2021-02-01T08:00:00Z"),
DateTimeOffset.Parse("2021-02-01T18:00:00Z"),
Expand All @@ -87,13 +87,13 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T08:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-01T13:00:00Z"),
Value = 1.5M
Value = 0.015M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T13:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-01T20:00:00Z"),
Value = 5M
Value = 0.05M
}
}
},
Expand All @@ -103,11 +103,11 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
"Etc/UTC",
new List<string>
{
"08:00-13:00=1.5",
"13:00-20:00=5",
"20:00-03:30=4",
"03:30-06:00=3.5",
"06:00-08:00=2",
"08:00-13:00=0.015",
"13:00-20:00=0.05",
"20:00-03:30=0.04",
"03:30-06:00=0.035",
"06:00-08:00=0.02",
},
DateTimeOffset.Parse("2021-02-01T15:00:00Z"),
DateTimeOffset.Parse("2021-02-01T20:00:00Z"),
Expand All @@ -117,7 +117,7 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T13:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-01T20:00:00Z"),
Value = 5M
Value = 0.05M
}
}
},
Expand All @@ -127,11 +127,11 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
"Etc/UTC",
new List<string>
{
"08:00-13:00=1.5",
"13:00-20:00=5",
"20:00-03:30=4",
"03:30-06:00=3.5",
"06:00-08:00=2",
"08:00-13:00=0.015",
"13:00-20:00=0.05",
"20:00-03:30=0.04",
"03:30-06:00=0.035",
"06:00-08:00=0.02",
},
DateTimeOffset.Parse("2021-02-01T15:00:00Z"),
DateTimeOffset.Parse("2021-02-02T07:00:00Z"),
Expand All @@ -141,25 +141,25 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T13:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-01T20:00:00Z"),
Value = 5M
Value = 0.05M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T20:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-02T03:30:00Z"),
Value = 4M
Value = 0.04M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-02-02T03:30:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-02T06:00:00Z"),
Value = 3.5M
Value = 0.035M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-02-02T06:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-02T08:00:00Z"),
Value = 2M
Value = 0.02M
}
}
},
Expand All @@ -169,11 +169,11 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
"America/New_York",
new List<string>
{
"08:00-13:00=1.5",
"13:00-20:00=5",
"20:00-03:30=4",
"03:30-06:00=3.5",
"06:00-08:00=2",
"08:00-13:00=0.015",
"13:00-20:00=0.05",
"20:00-03:30=0.04",
"03:30-06:00=0.035",
"06:00-08:00=0.02",
},
DateTimeOffset.Parse("2021-02-01T15:00:00Z"),
DateTimeOffset.Parse("2021-02-02T07:00:00Z"),
Expand All @@ -183,19 +183,19 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T13:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-01T18:00:00Z"),
Value = 1.5M
Value = 0.015M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T18:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-02T01:00:00Z"),
Value = 5M
Value = 0.05M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-02-02T01:00:00Z"),
ValidTo = DateTimeOffset.Parse("2021-02-02T08:30:00Z"),
Value = 4M
Value = 0.04M
}
}
},
Expand All @@ -205,11 +205,11 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
"America/New_York",
new List<string>
{
"08:00-13:00=1.5",
"13:00-20:00=5",
"20:00-03:30=4",
"03:30-06:00=3.5",
"06:00-08:00=2",
"08:00-13:00=0.015",
"13:00-20:00=0.05",
"20:00-03:30=0.04",
"03:30-06:00=0.035",
"06:00-08:00=0.02",
},
DateTimeOffset.Parse("2021-02-01T03:00:00Z"),
DateTimeOffset.Parse("2021-02-01T10:00:00Z"),
Expand All @@ -219,13 +219,13 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
{
ValidFrom = DateTimeOffset.Parse("2021-01-31T20:00:00-05:00"),
ValidTo = DateTimeOffset.Parse("2021-02-01T03:30:00-05:00"),
Value = 4M
Value = 0.04M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T03:30:00-05:00"),
ValidTo = DateTimeOffset.Parse("2021-02-01T06:00:00-05:00"),
Value = 3.5M
Value = 0.035M
}
}
},
Expand All @@ -235,11 +235,11 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
"America/New_York",
new List<string>
{
"08:00-13:00=1.5",
"13:00-20:00=5",
"20:00-03:30=4",
"03:30-06:00=3.5",
"06:00-08:00=2",
"08:00-13:00=0.015",
"13:00-20:00=0.05",
"20:00-03:30=0.04",
"03:30-06:00=0.035",
"06:00-08:00=0.02",
},
DateTimeOffset.Parse("2021-02-01T15:00:00Z"),
DateTimeOffset.Parse("2021-02-01T23:00:00Z"),
Expand All @@ -249,13 +249,13 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T08:00:00-05:00"),
ValidTo = DateTimeOffset.Parse("2021-02-01T13:00:00-05:00"),
Value = 1.5M
Value = 0.015M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-02-01T13:00:00-05:00"),
ValidTo = DateTimeOffset.Parse("2021-02-01T20:00:00-05:00"),
Value = 5M
Value = 0.05M
}
}
},
Expand Down Expand Up @@ -294,8 +294,8 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
"Europe/London",
new List<string>
{
"23:30-20:30=13.8",
"20:30-23:30=4.5"
"23:30-20:30=0.138",
"20:30-23:30=0.045"
},
DateTimeOffset.Parse("2021-04-13T19:46:13Z"),
DateTimeOffset.Parse("2021-04-13T22:02:46Z"),
Expand All @@ -305,7 +305,55 @@ public FixedPriceService Setup(string timeZone, List<string> prices)
{
ValidFrom = DateTimeOffset.Parse("2021-04-13T20:30:00+01:00"),
ValidTo = DateTimeOffset.Parse("2021-04-13T23:30:00+01:00"),
Value = 4.5M
Value = 0.045M
}
}
},
new object[]
{
"TimeZone_DSTEdge",
"Europe/London",
new List<string>
{
"00:30-04:30=0.0556",
"04:30-00:30=0.15"
},
DateTimeOffset.Parse("2021-06-16T23:00:51Z"),
DateTimeOffset.Parse("2021-06-17T00:19:15Z"),
new List<Price>
{
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-06-16T03:30:00Z"),
ValidTo = DateTimeOffset.Parse("2021-06-16T23:30:00Z"),
Value = 0.15M
},
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-06-16T23:30:00Z"),
ValidTo = DateTimeOffset.Parse("2021-06-17T03:30:00Z"),
Value = 0.0556M
}
}
},
new object[]
{
"TimeZone_SameDayEdge",
"Europe/London",
new List<string>
{
"00:30-04:30=0.05",
"04:30-00:30=0.15"
},
DateTimeOffset.Parse("2021-07-01T00:09:14Z"),
DateTimeOffset.Parse("2021-07-01T00:46:17Z"),
new List<Price>
{
new Price
{
ValidFrom = DateTimeOffset.Parse("2021-06-30T23:30:00Z"),
ValidTo = DateTimeOffset.Parse("2021-07-01T03:30:00Z"),
Value = 0.05M
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions TeslaMateAgile/Helpers/PriceHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ IOptions<TeslaMateOptions> teslaMateOptions
}
public async Task Update()
{
_logger.LogInformation("Updating prices");

var chargingProcesses = await _context.ChargingProcesses
.Where(x => x.GeofenceId == _teslaMateOptions.GeofenceId && x.EndDate.HasValue && !x.Cost.HasValue)
.Include(x => x.Charges)
Expand Down
6 changes: 3 additions & 3 deletions TeslaMateAgile/Services/FixedPriceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ IOptions<FixedPriceOptions> options
public Task<IEnumerable<Price>> GetPriceData(DateTimeOffset from, DateTimeOffset to)
{
var prices = new List<Price>();
var days = (to.Add(-_timeZone.GetUtcOffset(to)).Date - from.Add(-_timeZone.GetUtcOffset(from)).Date).Days;
var days = (to.Date - from.Date).Days;
var lastPrice = _fixedPrices.Last();
FixedPrice lastFixedPriceAdded = null;
for (var i = 0; i <= days; i++)
{
var date = from.Add(-_timeZone.GetUtcOffset(from)).Date;
if (!_fixedPrices.Any(x => x.FromHour < from.Hour) && (lastPrice != lastFixedPriceAdded))
var date = from.Date;
if (lastPrice != lastFixedPriceAdded)
{
var validFrom = DateTime.SpecifyKind(date.AddDays(i).AddHours(lastPrice.FromHour - 24).AddMinutes(lastPrice.FromMinute), DateTimeKind.Utc);
var validTo = DateTime.SpecifyKind(date.AddDays(i).AddHours(lastPrice.ToHour - 24).AddMinutes(lastPrice.ToMinute), DateTimeKind.Utc);
Expand Down

0 comments on commit 02f2991

Please sign in to comment.