Skip to content

Commit

Permalink
Merge branch 'master' into silkebonnen/avo-171-change-see-issue-5613-…
Browse files Browse the repository at this point in the history
…to-see-more-details
  • Loading branch information
silkeholmebonnen committed Apr 15, 2024
2 parents 03e8ff1 + c23e04d commit 3d8e6e1
Show file tree
Hide file tree
Showing 40 changed files with 10,384 additions and 541 deletions.
1 change: 1 addition & 0 deletions config/zones/MD.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ contributors:
- nessie2013
- lgrigoryeva1
- Impelon
- amv213
emissionFactors:
direct:
battery discharge:
Expand Down
7 changes: 7 additions & 0 deletions mockserver/public/v8/details/hourly/CN.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"data": {
"hasData": false,
"stateAggregation": "hourly",
"zoneStates": {}
}
}
6 changes: 3 additions & 3 deletions mockserver/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ app.use(cors());

const DEFAULT_ZONE_KEY = 'DE';

app.get('/v7/details/:aggregate/:zoneId', (req, res, next) => {
app.get('/v8/details/:aggregate/:zoneId', (req, res, next) => {
const { aggregate, zoneId } = req.params;

// if file exists return it, otherwise redirect to DEFAULT file
if (fs.existsSync(`./public/v7/details/${aggregate}/${zoneId}.json`)) {
if (fs.existsSync(`./public/v8/details/${aggregate}/${zoneId}.json`)) {
// file structure of project will return the correct file
next();
} else {
res.redirect(`/v7/details/${aggregate}/${DEFAULT_ZONE_KEY}`);
res.redirect(`/v8/details/${aggregate}/${DEFAULT_ZONE_KEY}`);
}
});

Expand Down
47 changes: 23 additions & 24 deletions parsers/CH.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
#!/usr/bin/env python3


from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from logging import Logger, getLogger
from zoneinfo import ZoneInfo

import arrow
import pandas as pd
from requests import Session

from electricitymap.contrib.lib.types import ZoneKey
from parsers import ENTSOE
from parsers.lib.config import refetch_frequency

from . import ENTSOE


def get_solar_capacity_at(date: datetime) -> float:
# Prepare historical records
Expand Down Expand Up @@ -47,8 +42,8 @@ def fetch_swiss_exchanges(session, target_datetime, logger):
swiss_transmissions = {}
for exchange_key in ["AT", "DE", "IT", "FR"]:
exchanges = ENTSOE.fetch_exchange(
zone_key1="CH",
zone_key2=exchange_key,
zone_key1=ZoneKey("CH"),
zone_key2=ZoneKey(exchange_key),
session=session,
target_datetime=target_datetime,
logger=logger,
Expand All @@ -57,11 +52,11 @@ def fetch_swiss_exchanges(session, target_datetime, logger):
continue

for exchange in exchanges:
datetime = exchange["datetime"]
if datetime not in swiss_transmissions:
swiss_transmissions[datetime] = exchange["netFlow"]
dt = exchange["datetime"]
if dt not in swiss_transmissions:
swiss_transmissions[dt] = exchange["netFlow"]
else:
swiss_transmissions[datetime] += exchange["netFlow"]
swiss_transmissions[dt] += exchange["netFlow"]

return swiss_transmissions

Expand All @@ -71,35 +66,39 @@ def fetch_swiss_consumption(
):
"""Returns the total consumption of Switzerland."""
consumptions = ENTSOE.fetch_consumption(
zone_key="CH", session=session, target_datetime=target_datetime, logger=logger
zone_key=ZoneKey("CH"),
session=session,
target_datetime=target_datetime,
logger=logger,
)
return {c["datetime"]: c["consumption"] for c in consumptions}


@refetch_frequency(timedelta(days=1))
def fetch_production(
zone_key: str = "CH",
zone_key: ZoneKey = ZoneKey("CH"),
session: Session | None = None,
target_datetime: datetime | None = None,
logger: Logger = getLogger(__name__),
):
"""
Returns the total production by type for Switzerland.
Currently the majority of the run-of-river production is missing.
Currently, the majority of the run-of-river production is missing.
The difference between the sum of all production types and the total production is allocated as 'unknown'.
The total production is calculated as sum of the consumption, storage and net imports.
"""
now = (
arrow.get(target_datetime).to("Europe/Zurich").datetime
if target_datetime
else datetime.now(tz=ZoneInfo("Europe/Zurich"))
target_datetime = (
datetime.now(timezone.utc)
if target_datetime is None
else target_datetime.astimezone(timezone.utc)
)

r = session or Session()

exchanges = fetch_swiss_exchanges(r, now, logger)
consumptions = fetch_swiss_consumption(r, now, logger)
exchanges = fetch_swiss_exchanges(r, target_datetime, logger)
consumptions = fetch_swiss_consumption(r, target_datetime, logger)
productions = ENTSOE.fetch_production(
zone_key=zone_key, session=r, target_datetime=now, logger=logger
zone_key=zone_key, session=r, target_datetime=target_datetime, logger=logger
)

if not productions:
Expand Down
Loading

0 comments on commit 3d8e6e1

Please sign in to comment.