Skip to content

Commit 2a56f2a

Browse files
authored
add ostrom electricity tariff (#2188)
* add ostrom electricity tariff * fix request when no zip code provided
1 parent 9706c87 commit 2a56f2a

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

packages/modules/electricity_tariffs/ostrom/__init__.py

Whitespace-only changes.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from typing import Optional
2+
3+
4+
class OstromTariffConfiguration:
5+
def __init__(self,
6+
client_id: Optional[str] = None,
7+
client_secret: Optional[str] = None,
8+
zip: Optional[str] = None):
9+
self.client_id = client_id
10+
self.client_secret = client_secret
11+
self.zip = zip
12+
13+
14+
class OstromTariff:
15+
def __init__(self,
16+
name: str = "ostrom",
17+
type: str = "ostrom",
18+
configuration: OstromTariffConfiguration = None) -> None:
19+
self.name = name
20+
self.type = type
21+
self.configuration = configuration or OstromTariffConfiguration()
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env python3
2+
from base64 import b64encode
3+
from datetime import datetime, timezone, timedelta
4+
from urllib.parse import quote
5+
from typing import Dict
6+
from modules.common import req
7+
from modules.common.abstract_device import DeviceDescriptor
8+
from modules.common.component_state import TariffState
9+
from modules.electricity_tariffs.ostrom.config import OstromTariffConfiguration
10+
from modules.electricity_tariffs.ostrom.config import OstromTariff
11+
12+
13+
def fetch_prices(config: OstromTariffConfiguration) -> Dict[int, float]:
14+
access_token = req.get_http_session().post(
15+
url="https://auth.production.ostrom-api.io/oauth2/token",
16+
data={"grant_type": "client_credentials"},
17+
headers={
18+
"accept": "application/json",
19+
"content-type": "application/x-www-form-urlencoded",
20+
"authorization": "Basic " + b64encode((config.client_id + ":" + config.client_secret).encode()).decode()
21+
}
22+
).json()["access_token"]
23+
utcnow = datetime.now(timezone.utc)
24+
startDate = quote(utcnow.strftime("%Y-%m-%dT%H:00:00.000Z"))
25+
endDate = quote((utcnow + timedelta(days=1)).strftime("%Y-%m-%dT%H:00:00.000Z"))
26+
if config.zip:
27+
zip = f"&zip={config.zip}"
28+
else:
29+
zip = ""
30+
raw_prices = req.get_http_session().get(
31+
url="https://production.ostrom-api.io/spot-prices?" +
32+
f"startDate={startDate}&endDate={endDate}&resolution=HOUR{zip}",
33+
headers={
34+
"accept": "application/json",
35+
"authorization": "Bearer " + access_token
36+
}
37+
).json()["data"]
38+
prices: Dict[int, float] = {}
39+
for raw_price in raw_prices:
40+
# Note: with Python >= 3.11, we can use: timestamp = datetime.fromisoformat(raw_price["date"]).timestamp()
41+
timestamp = datetime.strptime(raw_price["date"], "%Y-%m-%dT%H:%M:%S.000Z")\
42+
.replace(tzinfo=timezone.utc).timestamp()
43+
price = float(raw_price["grossKwhPrice"] + raw_price["grossKwhTaxAndLevies"]) / 100000 # ct/kWh --> EUR/Wh
44+
prices.update({str(int(timestamp)): price})
45+
return prices
46+
47+
48+
def create_electricity_tariff(config: OstromTariff):
49+
def updater():
50+
return TariffState(prices=fetch_prices(config.configuration))
51+
return updater
52+
53+
54+
device_descriptor = DeviceDescriptor(configuration_factory=OstromTariff)

0 commit comments

Comments
 (0)