-
Notifications
You must be signed in to change notification settings - Fork 12
Implementing up to three tarif zones #289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8f1ebf9
6fc8952
e0d38c2
ab92f2a
91cbb2b
80b7e70
dc0571d
f31ca82
facc74c
aed6a10
b03165d
389fff7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,23 @@ | ||||||||||||||||||
| # PowerShell version of run_tests.sh | ||||||||||||||||||
|
|
||||||||||||||||||
| # Activate virtual environment if it exists (Windows path used by venv) | ||||||||||||||||||
| if (Test-Path -Path .\.venv\Scripts\Activate.ps1) { | ||||||||||||||||||
| . .\.venv\Scripts\Activate.ps1 | ||||||||||||||||||
|
Comment on lines
+3
to
+5
|
||||||||||||||||||
| # Activate virtual environment if it exists (Windows path used by venv) | |
| if (Test-Path -Path .\.venv\Scripts\Activate.ps1) { | |
| . .\.venv\Scripts\Activate.ps1 | |
| # Activate virtual environment if it exists (prefer .venv, fall back to venv) | |
| if (Test-Path -Path .\.venv\Scripts\Activate.ps1) { | |
| . .\.venv\Scripts\Activate.ps1 | |
| } elseif (Test-Path -Path .\venv\Scripts\Activate.ps1) { | |
| . .\venv\Scripts\Activate.ps1 |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,289 @@ | ||||||||||||||||||||||||||||||||||||||
| """Tariff_zones provider | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Simple dynamic tariff provider that assigns a fixed price to each hour of the day | ||||||||||||||||||||||||||||||||||||||
| using up to three configurable zones. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Config options (in utility config for provider): | ||||||||||||||||||||||||||||||||||||||
| - type: tariff_zones | ||||||||||||||||||||||||||||||||||||||
| - tariff_zone_1: price for zone 1 hours (float, Euro/kWh incl. VAT/fees, required) | ||||||||||||||||||||||||||||||||||||||
| - zone_1_hours: comma-separated list of hours assigned to zone 1, e.g. "7,8,9,10" | ||||||||||||||||||||||||||||||||||||||
| - tariff_zone_2: price for zone 2 hours (float, Euro/kWh incl. VAT/fees, required) | ||||||||||||||||||||||||||||||||||||||
| - zone_2_hours: comma-separated list of hours assigned to zone 2, e.g. "0,1,2,3,4,5,6" | ||||||||||||||||||||||||||||||||||||||
| - tariff_zone_3: price for zone 3 hours (float, optional) | ||||||||||||||||||||||||||||||||||||||
| - zone_3_hours: comma-separated list of hours assigned to zone 3 (optional) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Rules: | ||||||||||||||||||||||||||||||||||||||
| - Every hour 0-23 must appear in exactly one zone (ValueError if any hour is missing). | ||||||||||||||||||||||||||||||||||||||
| - No hour may appear more than once across all zones (ValueError on duplicate). | ||||||||||||||||||||||||||||||||||||||
| - zone_3_hours and tariff_zone_3 must both be set or both omitted. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| The class produces hourly prices (native_resolution=60) for the next 48 | ||||||||||||||||||||||||||||||||||||||
| hours aligned to the current hour. The baseclass will handle conversion to | ||||||||||||||||||||||||||||||||||||||
| 15min if the target resolution is 15. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Note: | ||||||||||||||||||||||||||||||||||||||
| The charge rate is not evenly distributed across the low price hours. | ||||||||||||||||||||||||||||||||||||||
| If you prefer a more even distribution during the low price hours, you can adjust the | ||||||||||||||||||||||||||||||||||||||
| soften_price_difference_on_charging to enabled | ||||||||||||||||||||||||||||||||||||||
| and | ||||||||||||||||||||||||||||||||||||||
| max_grid_charge_rate to a low value, e.g. capacity of the battery divided | ||||||||||||||||||||||||||||||||||||||
| by the hours of low price periods. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| If you prefer a late charging start (=optimize efficiency, have battery only short | ||||||||||||||||||||||||||||||||||||||
| time at high SOC), you can adjust the | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+26
to
+33
|
||||||||||||||||||||||||||||||||||||||
| If you prefer a more even distribution during the low price hours, you can adjust the | |
| soften_price_difference_on_charging to enabled | |
| and | |
| max_grid_charge_rate to a low value, e.g. capacity of the battery divided | |
| by the hours of low price periods. | |
| If you prefer a late charging start (=optimize efficiency, have battery only short | |
| time at high SOC), you can adjust the | |
| If you prefer a more even distribution during the low price hours, you can set | |
| soften_price_difference_on_charging to enabled | |
| and set | |
| max_grid_charge_rate to a low value, e.g. capacity of the battery divided | |
| by the hours of low price periods. | |
| If you prefer a late charging start (=optimize efficiency, have battery only short | |
| time at high SOC), you can set |
Copilot
AI
Mar 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The __init__ parameter continuation indentation is misaligned with the opening parenthesis and will likely trigger PEP8/pylint continuation-indentation warnings. Please run autopep8 (or align continuation lines under the opening parenthesis / use a 4-space hanging indent) to match the style used in other providers.
Copilot
AI
Mar 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In _get_prices_native, datetime.datetime.now().astimezone(self.timezone) relies on the host local timezone for naive now(), which can misalign indices (especially on Windows where TZ isn’t applied) and can produce incorrect hours around DST changes. Prefer basing calculations on datetime.datetime.now(datetime.timezone.utc) and converting to self.timezone, and avoid adding timedeltas to pytz-localized datetimes (convert each rel_hour from UTC to local instead) so DST transitions map to the correct local hour.
| now = datetime.datetime.now().astimezone(self.timezone) | |
| current_hour_start = now.replace(minute=0, second=0, microsecond=0) | |
| prices = {} | |
| for rel_hour in range(48): | |
| ts = current_hour_start + datetime.timedelta(hours=rel_hour) | |
| prices[rel_hour] = hour_to_price[ts.hour] | |
| # Anchor calculations in UTC and convert to the configured timezone | |
| now_utc = datetime.datetime.now(datetime.timezone.utc) | |
| now_local = now_utc.astimezone(self.timezone) | |
| current_hour_start_local = now_local.replace(minute=0, second=0, microsecond=0) | |
| current_hour_start_utc = current_hour_start_local.astimezone(datetime.timezone.utc) | |
| prices = {} | |
| for rel_hour in range(48): | |
| ts_utc = current_hour_start_utc + datetime.timedelta(hours=rel_hour) | |
| ts_local = ts_utc.astimezone(self.timezone) | |
| prices[rel_hour] = hour_to_price[ts_local.hour] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor wording: “A zone based pricing” is grammatically awkward; “zone-based pricing” (or “a zone-based tariff”) reads more naturally.