mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-05-28 18:43:40 +00:00
feat(api): add energy and tax fields to Tibber GraphQL queries
Request `energy` and `tax` fields alongside `total` in both quarter-hourly price queries. These represent the raw spot price and the tax/fee component that together make up the total consumer price. Updated hourly aggregation in formatters.py to carry energy/tax values through to aggregated output. Impact: Enables downstream consumers (sensors, services) to expose price composition data. Useful for solar feed-in compensation and net metering (saldering) calculations where the raw energy price is needed separately from taxes.
This commit is contained in:
parent
e1da4cfa89
commit
f5dcf04aab
2 changed files with 26 additions and 4 deletions
|
|
@ -230,12 +230,12 @@ class TibberPricesApiClient:
|
||||||
priceInfoRange(resolution:QUARTER_HOURLY, first:192, after: "{cursor}") {{
|
priceInfoRange(resolution:QUARTER_HOURLY, first:192, after: "{cursor}") {{
|
||||||
pageInfo{{ count }}
|
pageInfo{{ count }}
|
||||||
edges{{node{{
|
edges{{node{{
|
||||||
startsAt total level
|
startsAt total energy tax level
|
||||||
}}}}
|
}}}}
|
||||||
}}
|
}}
|
||||||
priceInfo(resolution:QUARTER_HOURLY) {{
|
priceInfo(resolution:QUARTER_HOURLY) {{
|
||||||
today{{startsAt total level}}
|
today{{startsAt total energy tax level}}
|
||||||
tomorrow{{startsAt total level}}
|
tomorrow{{startsAt total energy tax level}}
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
|
|
@ -500,7 +500,7 @@ class TibberPricesApiClient:
|
||||||
edges{{
|
edges{{
|
||||||
cursor
|
cursor
|
||||||
node{{
|
node{{
|
||||||
startsAt total level
|
startsAt total energy tax level
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,8 @@ def aggregate_to_hourly( # noqa: PLR0912
|
||||||
|
|
||||||
# Collect 5-interval rolling window: -2, -1, 0, +1, +2
|
# Collect 5-interval rolling window: -2, -1, 0, +1, +2
|
||||||
window_prices: list[float] = []
|
window_prices: list[float] = []
|
||||||
|
window_energy_prices: list[float] = []
|
||||||
|
window_tax_prices: list[float] = []
|
||||||
window_intervals: list[dict] = []
|
window_intervals: list[dict] = []
|
||||||
|
|
||||||
for offset in range(-2, 3): # -2, -1, 0, +1, +2
|
for offset in range(-2, 3): # -2, -1, 0, +1, +2
|
||||||
|
|
@ -113,6 +115,12 @@ def aggregate_to_hourly( # noqa: PLR0912
|
||||||
if price is not None:
|
if price is not None:
|
||||||
window_prices.append(price)
|
window_prices.append(price)
|
||||||
window_intervals.append(target_interval)
|
window_intervals.append(target_interval)
|
||||||
|
energy = target_interval.get("energy")
|
||||||
|
tax = target_interval.get("tax")
|
||||||
|
if energy is not None:
|
||||||
|
window_energy_prices.append(energy)
|
||||||
|
if tax is not None:
|
||||||
|
window_tax_prices.append(tax)
|
||||||
|
|
||||||
# Calculate aggregated price based on user preference
|
# Calculate aggregated price based on user preference
|
||||||
if window_prices:
|
if window_prices:
|
||||||
|
|
@ -127,6 +135,20 @@ def aggregate_to_hourly( # noqa: PLR0912
|
||||||
"total": aggregated_price,
|
"total": aggregated_price,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Add aggregated energy and tax prices
|
||||||
|
if window_energy_prices:
|
||||||
|
aggregated_energy = (
|
||||||
|
calculate_median(window_energy_prices) if use_median else calculate_mean(window_energy_prices)
|
||||||
|
)
|
||||||
|
if aggregated_energy is not None:
|
||||||
|
data_point["energy"] = aggregated_energy
|
||||||
|
if window_tax_prices:
|
||||||
|
aggregated_tax = (
|
||||||
|
calculate_median(window_tax_prices) if use_median else calculate_mean(window_tax_prices)
|
||||||
|
)
|
||||||
|
if aggregated_tax is not None:
|
||||||
|
data_point["tax"] = aggregated_tax
|
||||||
|
|
||||||
# Add aggregated level
|
# Add aggregated level
|
||||||
if window_intervals:
|
if window_intervals:
|
||||||
aggregated_level = aggregate_level_data(window_intervals)
|
aggregated_level = aggregate_level_data(window_intervals)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue