Passed
Pull Request — dev (#1122)
by
unknown
04:34
created

add_metadata()   B

Complexity

Conditions 1

Size

Total Lines 367
Code Lines 252

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 252
dl 0
loc 367
rs 7
c 0
b 0
f 0
cc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
"""
2
DB tables / SQLAlchemy ORM classes for motorized individual travel
3
"""
4
import datetime
5
import json
6
7
from omi.dialects import get_dialect
8
from sqlalchemy import (
9
    Boolean,
10
    Column,
11
    DateTime,
12
    Float,
13
    ForeignKey,
14
    Integer,
15
    SmallInteger,
16
    String,
17
)
18
from sqlalchemy.dialects.postgresql import REAL
19
from sqlalchemy.ext.declarative import declarative_base
20
21
from egon.data import db
22
from egon.data.datasets.emobility.motorized_individual_travel.helpers import (
23
    read_simbev_metadata_file,
24
)
25
from egon.data.datasets.mv_grid_districts import MvGridDistricts
26
from egon.data.datasets.scenario_parameters import EgonScenario
27
from egon.data.metadata import (
28
    context,
29
    contributors,
30
    generate_resource_fields_from_db_table,
31
    license_agpl,
32
    license_ccby,
33
    license_odbl,
34
    meta_metadata,
35
    oep_metadata_version,
36
    sources,
37
)
38
39
Base = declarative_base()
40
41
42
class EgonEvPool(Base):
43
    """Motorized individual travel: EV pool
44
45
    Each row is one EV, uniquely defined by either (`ev_id`) or
46
    (`rs7_id`, `type`, `simbev_id`).
47
48
    Columns
49
    -------
50
    ev_id:
51
        Unique id of EV
52
    rs7_id:
53
        id of RegioStar7 region
54
    type:
55
        type of EV, one of
56
            * bev_mini
57
            * bev_medium
58
            * bev_luxury
59
            * phev_mini
60
            * phev_medium
61
            * phev_luxury
62
    simbev_ev_id:
63
        id of EV as exported by simBEV
64
    """
65
66
    __tablename__ = "egon_ev_pool"
67
    __table_args__ = {"schema": "demand"}
68
69
    scenario = Column(String, ForeignKey(EgonScenario.name), primary_key=True)
70
    ev_id = Column(Integer, primary_key=True)
71
    rs7_id = Column(SmallInteger)
72
    type = Column(String(11))
73
    simbev_ev_id = Column(Integer)
74
75
    # trips = relationship(
76
    #     "EgonEvTrip", cascade="all, delete", back_populates="ev"
77
    # )
78
    # mvgds = relationship(
79
    #     "EgonEvMvGridDistrict", cascade="all, delete", back_populates="ev"
80
    # )
81
82
83
class EgonEvTrip(Base):
84
    """Motorized individual travel: EVs' trips
85
86
    Each row is one event of a specific electric vehicle which is
87
    uniquely defined by `rs7_id`, `ev_id` and `event_id`.
88
89
    Columns
90
    -------
91
    scenario:
92
        Scenario
93
    event_id:
94
        Unique id of EV event
95
    egon_ev_pool_ev_id:
96
        id of EV, references EgonEvPool.ev_id
97
    simbev_event_id:
98
        id of EV event, unique within a specific EV dataset
99
    location:
100
        Location of EV event, one of
101
            * "0_work"
102
            * "1_business"
103
            * "2_school"
104
            * "3_shopping"
105
            * "4_private/ridesharing"
106
            * "5_leisure"
107
            * "6_home"
108
            * "7_charging_hub"
109
            * "driving"
110
    use_case:
111
        Use case of EV event, one of
112
            * "public" (public charging)
113
            * "home" (private charging at 6_home)
114
            * "work" (private charging at 0_work)
115
            * <empty> (driving events)
116
    charging_capacity_nominal:
117
        Nominal charging capacity in kW
118
    charging_capacity_grid:
119
        Charging capacity at grid side in kW,
120
        includes efficiency of charging infrastructure
121
    charging_capacity_battery:
122
        Charging capacity at battery side in kW,
123
        includes efficiency of car charger
124
    soc_start:
125
        State of charge at start of event
126
    soc_start:
127
        State of charge at end of event
128
    charging_demand:
129
        Energy demand during parking/charging event in kWh.
130
        0 if no charging takes place.
131
    park_start:
132
        Start timestep of parking event (15min interval, e.g. 4 = 1h)
133
    park_end:
134
        End timestep of parking event (15min interval)
135
    drive_start:
136
        Start timestep of driving event (15min interval)
137
    drive_end:
138
        End timestep of driving event (15min interval)
139
    consumption:
140
        Energy demand during driving event in kWh
141
142
    Notes
143
    -----
144
    pgSQL's REAL is sufficient for floats as simBEV rounds output to 4 digits.
145
    """
146
147
    __tablename__ = "egon_ev_trip"
148
    __table_args__ = {"schema": "demand"}
149
150
    # scenario = Column(
151
    #    String, ForeignKey(EgonEvPool.scenario), primary_key=True
152
    # )
153
    scenario = Column(String, ForeignKey(EgonScenario.name), primary_key=True)
154
    event_id = Column(Integer, primary_key=True)
155
    # egon_ev_pool_ev_id = Column(
156
    #    Integer, ForeignKey(EgonEvPool.ev_id), nullable=False, index=True
157
    # )
158
    egon_ev_pool_ev_id = Column(Integer, nullable=False, index=True)
159
    simbev_event_id = Column(Integer)
160
    location = Column(String(21))
161
    use_case = Column(String(8))
162
    charging_capacity_nominal = Column(REAL)
163
    charging_capacity_grid = Column(REAL)
164
    charging_capacity_battery = Column(REAL)
165
    soc_start = Column(REAL)
166
    soc_end = Column(REAL)
167
    charging_demand = Column(REAL)
168
    park_start = Column(Integer)
169
    park_end = Column(Integer)
170
    drive_start = Column(Integer)
171
    drive_end = Column(Integer)
172
    consumption = Column(REAL)
173
174
    # __table_args__ = (
175
    #    ForeignKeyConstraint([scenario, egon_ev_pool_ev_id],
176
    #                         [EgonEvPool.scenario, EgonEvPool.ev_id]),
177
    #    {"schema": "demand"},
178
    # )
179
180
    # ev = relationship("EgonEvPool", back_populates="trips")
181
182
183 View Code Duplication
class EgonEvCountRegistrationDistrict(Base):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
184
    """Electric vehicle counts per registration district"""
185
186
    __tablename__ = "egon_ev_count_registration_district"
187
    __table_args__ = {"schema": "demand"}
188
189
    scenario = Column(String, ForeignKey(EgonScenario.name), primary_key=True)
190
    scenario_variation = Column(String, primary_key=True)
191
    ags_reg_district = Column(Integer, primary_key=True)
192
    reg_district = Column(String)
193
    bev_mini = Column(Integer)
194
    bev_medium = Column(Integer)
195
    bev_luxury = Column(Integer)
196
    phev_mini = Column(Integer)
197
    phev_medium = Column(Integer)
198
    phev_luxury = Column(Integer)
199
200
201 View Code Duplication
class EgonEvCountMunicipality(Base):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
202
    """Electric vehicle counts per municipality"""
203
204
    __tablename__ = "egon_ev_count_municipality"
205
    __table_args__ = {"schema": "demand"}
206
207
    scenario = Column(String, ForeignKey(EgonScenario.name), primary_key=True)
208
    scenario_variation = Column(String, primary_key=True)
209
    ags = Column(Integer, primary_key=True)
210
    bev_mini = Column(Integer)
211
    bev_medium = Column(Integer)
212
    bev_luxury = Column(Integer)
213
    phev_mini = Column(Integer)
214
    phev_medium = Column(Integer)
215
    phev_luxury = Column(Integer)
216
    rs7_id = Column(SmallInteger)
217
218
219 View Code Duplication
class EgonEvCountMvGridDistrict(Base):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
220
    """Electric vehicle counts per MV grid district"""
221
222
    __tablename__ = "egon_ev_count_mv_grid_district"
223
    __table_args__ = {"schema": "demand"}
224
225
    scenario = Column(String, ForeignKey(EgonScenario.name), primary_key=True)
226
    scenario_variation = Column(String, primary_key=True)
227
    bus_id = Column(
228
        Integer, ForeignKey(MvGridDistricts.bus_id), primary_key=True
229
    )
230
    bev_mini = Column(Integer)
231
    bev_medium = Column(Integer)
232
    bev_luxury = Column(Integer)
233
    phev_mini = Column(Integer)
234
    phev_medium = Column(Integer)
235
    phev_luxury = Column(Integer)
236
    rs7_id = Column(SmallInteger)
237
238
239
class EgonEvMvGridDistrict(Base):
240
    """List of electric vehicles per MV grid district"""
241
242
    __tablename__ = "egon_ev_mv_grid_district"
243
    __table_args__ = {"schema": "demand"}
244
245
    id = Column(Integer, primary_key=True)
246
    scenario = Column(String, ForeignKey(EgonScenario.name), index=True)
247
    scenario_variation = Column(String, index=True)
248
    bus_id = Column(Integer, ForeignKey(MvGridDistricts.bus_id), index=True)
249
    # egon_ev_pool_ev_id = Column(Integer, ForeignKey(EgonEvPool.ev_id))
250
    egon_ev_pool_ev_id = Column(Integer, nullable=False)
251
252
    # ev = relationship("EgonEvPool", back_populates="mvgds")
253
254
255
class EgonEvMetadata(Base):
256
    """List of EV Pool Metadata"""
257
258
    __tablename__ = "egon_ev_metadata"
259
    __table_args__ = {"schema": "demand"}
260
261
    scenario = Column(String, primary_key=True, index=True)
262
    eta_cp = Column(Float)
263
    stepsize = Column(Integer)
264
    start_date = Column(DateTime)
265
    end_date = Column(DateTime)
266
    soc_min = Column(Float)
267
    grid_timeseries = Column(Boolean)
268
    grid_timeseries_by_usecase = Column(Boolean)
269
270
271
def add_metadata():
272
    """
273
    Add metadata to tables egon_ev_metadata, egon_ev_mv_grid_district,
274
    egon_ev_trip in schema demand
275
    """
276
    # egon_ev_metadata
277
    schema = "demand"
278
    meta_run_config = read_simbev_metadata_file("eGon100RE", "config").loc[
279
        "basic"
280
    ]
281
282
    contris = contributors(["kh", "kh"])
283
284
    contris[0]["date"] = "2023-03-17"
285
286
    contris[0]["object"] = "metadata"
287
    contris[1]["object"] = "dataset"
288
289
    contris[0]["comment"] = "Add metadata to dataset."
290
    contris[1]["comment"] = "Add workflow to generate dataset."
291
292
    table = "egon_ev_metadata"
293
    name = f"{schema}.{table}"
294
295
    meta = {
296
        "name": name,
297
        "title": "eGon EV metadata",
298
        "id": "WILL_BE_SET_AT_PUBLICATION",
299
        "description": (
300
            "Metadata regarding the generation of EV trip profiles with SimBEV"
301
        ),
302
        "language": "en-US",
303
        "keywords": ["ev", "mit", "simbev", "metadata", "parameters"],
304
        "publicationDate": datetime.date.today().isoformat(),
305
        "context": context(),
306
        "spatial": {
307
            "location": "none",
308
            "extent": "none",
309
            "resolution": "none",
310
        },
311
        "temporal": {
312
            "referenceDate": f"{meta_run_config.start_date}",
313
            "timeseries": {},
314
        },
315
        "sources": [
316
            sources()["egon-data"],
317
            {
318
                "title": "SimBEV",
319
                "description": (
320
                    "Simulation of electric vehicle charging demand"
321
                ),
322
                "path": "https://github.com/rl-institut/simbev",
323
                "licenses": [
324
                    license_ccby(attribution="© Reiner Lemoine Institut")
325
                ],
326
            },
327
            {
328
                "title": "SimBEV",
329
                "description": (
330
                    "Simulation of electric vehicle charging demand"
331
                ),
332
                "path": "https://github.com/rl-institut/simbev",
333
                "licenses": [
334
                    license_agpl(attribution="© Reiner Lemoine Institut")
335
                ],
336
            },
337
        ],
338
        "licenses": [license_ccby()],
339
        "contributors": contris,
340
        "resources": [
341
            {
342
                "profile": "tabular-data-resource",
343
                "name": name,
344
                "path": "None",
345
                "format": "PostgreSQL",
346
                "encoding": "UTF-8",
347
                "schema": {
348
                    "fields": generate_resource_fields_from_db_table(
349
                        schema,
350
                        table,
351
                    ),
352
                    "primaryKey": "scenario",
353
                },
354
                "dialect": {"delimiter": "", "decimalSeparator": ""},
355
            }
356
        ],
357
        "review": {"path": "", "badge": ""},
358
        "metaMetadata": meta_metadata(),
359
        "_comment": {
360
            "metadata": (
361
                "Metadata documentation and explanation (https://github."
362
                "com/OpenEnergyPlatform/oemetadata/blob/master/metadata/"
363
                "v141/metadata_key_description.md)"
364
            ),
365
            "dates": (
366
                "Dates and time must follow the ISO8601 including time "
367
                "zone (YYYY-MM-DD or YYYY-MM-DDThh:mm:ss±hh)"
368
            ),
369
            "units": "Use a space between numbers and units (100 m)",
370
            "languages": (
371
                "Languages must follow the IETF (BCP47) format (en-GB, "
372
                "en-US, de-DE)"
373
            ),
374
            "licenses": (
375
                "License name must follow the SPDX License List "
376
                "(https://spdx.org/licenses/)"
377
            ),
378
            "review": (
379
                "Following the OEP Data Review (https://github.com/"
380
                "OpenEnergyPlatform/data-preprocessing/wiki)"
381
            ),
382
            "none": "If not applicable use (none)",
383
        },
384
    }
385
386
    dialect = get_dialect(oep_metadata_version())()
387
388
    meta = dialect.compile_and_render(dialect.parse(json.dumps(meta)))
389
390
    db.submit_comment(
391
        f"'{json.dumps(meta)}'",
392
        schema,
393
        table,
394
    )
395
396
    table = "egon_ev_mv_grid_district"
397
    name = f"{schema}.{table}"
398
399
    meta = {
400
        "name": name,
401
        "title": "eGon EV MV grid district",
402
        "id": "WILL_BE_SET_AT_PUBLICATION",
403
        "description": ("EV mapping to MV grids"),
404
        "language": "en-US",
405
        "keywords": ["ev", "mit", "simbev", "mv", "grid"],
406
        "publicationDate": datetime.date.today().isoformat(),
407
        "context": context(),
408
        "spatial": {
409
            "location": "none",
410
            "extent": "Germany",
411
            "resolution": "Grid district",
412
        },
413
        "temporal": {
414
            "referenceDate": f"{meta_run_config.start_date}",
415
            "timeseries": {},
416
        },
417
        "sources": [
418
            sources()["bgr_inspee"],
419
            sources()["bgr_inspeeds"],
420
            sources()["bgr_inspeeds_data_bundle"],
421
            sources()["bgr_inspeeds_report"],
422
            sources()["demandregio"],
423
            sources()["dsm-heitkoetter"],
424
            sources()["egon-data"],
425
            sources()["era5"],
426
            sources()["hotmaps_industrial_sites"],
427
            sources()["mastr"],
428
            sources()["nep2021"],
429
            sources()["openffe_gas"],
430
            sources()["openstreetmap"],
431
            sources()["peta"],
432
            sources()["pipeline_classification"],
433
            sources()["SciGRID_gas"],
434
            sources()["schmidt"],
435
            sources()["technology-data"],
436
            sources()["tyndp"],
437
            sources()["vg250"],
438
            sources()["zensus"],
439
            {
440
                "title": "SimBEV",
441
                "description": (
442
                    "Simulation of electric vehicle charging demand"
443
                ),
444
                "path": "https://github.com/rl-institut/simbev",
445
                "licenses": [
446
                    license_ccby(attribution="© Reiner Lemoine Institut")
447
                ],
448
            },
449
            {
450
                "title": "SimBEV",
451
                "description": (
452
                    "Simulation of electric vehicle charging demand"
453
                ),
454
                "path": "https://github.com/rl-institut/simbev",
455
                "licenses": [
456
                    license_agpl(attribution="© Reiner Lemoine Institut")
457
                ],
458
            },
459
        ],
460
        "licenses": [license_odbl()],
461
        "contributors": contris,
462
        "resources": [
463
            {
464
                "profile": "tabular-data-resource",
465
                "name": name,
466
                "path": "None",
467
                "format": "PostgreSQL",
468
                "encoding": "UTF-8",
469
                "schema": {
470
                    "fields": generate_resource_fields_from_db_table(
471
                        schema,
472
                        table,
473
                    ),
474
                    "primaryKey": "id",
475
                },
476
                "dialect": {"delimiter": "", "decimalSeparator": ""},
477
            }
478
        ],
479
        "review": {"path": "", "badge": ""},
480
        "metaMetadata": meta_metadata(),
481
        "_comment": {
482
            "metadata": (
483
                "Metadata documentation and explanation (https://github."
484
                "com/OpenEnergyPlatform/oemetadata/blob/master/metadata/"
485
                "v141/metadata_key_description.md)"
486
            ),
487
            "dates": (
488
                "Dates and time must follow the ISO8601 including time "
489
                "zone (YYYY-MM-DD or YYYY-MM-DDThh:mm:ss±hh)"
490
            ),
491
            "units": "Use a space between numbers and units (100 m)",
492
            "languages": (
493
                "Languages must follow the IETF (BCP47) format (en-GB, "
494
                "en-US, de-DE)"
495
            ),
496
            "licenses": (
497
                "License name must follow the SPDX License List "
498
                "(https://spdx.org/licenses/)"
499
            ),
500
            "review": (
501
                "Following the OEP Data Review (https://github.com/"
502
                "OpenEnergyPlatform/data-preprocessing/wiki)"
503
            ),
504
            "none": "If not applicable use (none)",
505
        },
506
    }
507
508
    dialect = get_dialect(oep_metadata_version())()
509
510
    meta = dialect.compile_and_render(dialect.parse(json.dumps(meta)))
511
512
    db.submit_comment(
513
        f"'{json.dumps(meta)}'",
514
        schema,
515
        table,
516
    )
517
518
    table = "egon_ev_trip"
519
    name = f"{schema}.{table}"
520
521
    meta = {
522
        "name": name,
523
        "title": "eGon EV trip profiles",
524
        "id": "WILL_BE_SET_AT_PUBLICATION",
525
        "description": ("EV trip profiles generated with SimBEV"),
526
        "language": "en-US",
527
        "keywords": ["ev", "mit", "simbev", "trip", "profiles"],
528
        "publicationDate": datetime.date.today().isoformat(),
529
        "context": context(),
530
        "spatial": {
531
            "location": "none",
532
            "extent": "Germany",
533
            "resolution": "none",
534
        },
535
        "temporal": {
536
            "referenceDate": f"{meta_run_config.start_date}",
537
            "timeseries": {},
538
        },
539
        "sources": [
540
            sources()["bgr_inspee"],
541
            sources()["bgr_inspeeds"],
542
            sources()["bgr_inspeeds_data_bundle"],
543
            sources()["bgr_inspeeds_report"],
544
            sources()["demandregio"],
545
            sources()["dsm-heitkoetter"],
546
            sources()["egon-data"],
547
            sources()["era5"],
548
            sources()["hotmaps_industrial_sites"],
549
            sources()["mastr"],
550
            sources()["nep2021"],
551
            sources()["openffe_gas"],
552
            sources()["openstreetmap"],
553
            sources()["peta"],
554
            sources()["pipeline_classification"],
555
            sources()["SciGRID_gas"],
556
            sources()["schmidt"],
557
            sources()["technology-data"],
558
            sources()["tyndp"],
559
            sources()["vg250"],
560
            sources()["zensus"],
561
            {
562
                "title": "SimBEV",
563
                "description": (
564
                    "Simulation of electric vehicle charging demand"
565
                ),
566
                "path": "https://github.com/rl-institut/simbev",
567
                "licenses": [
568
                    license_ccby(attribution="© Reiner Lemoine Institut")
569
                ],
570
            },
571
            {
572
                "title": "SimBEV",
573
                "description": (
574
                    "Simulation of electric vehicle charging demand"
575
                ),
576
                "path": "https://github.com/rl-institut/simbev",
577
                "licenses": [
578
                    license_agpl(attribution="© Reiner Lemoine Institut")
579
                ],
580
            },
581
        ],
582
        "licenses": [license_odbl()],
583
        "contributors": contris,
584
        "resources": [
585
            {
586
                "profile": "tabular-data-resource",
587
                "name": name,
588
                "path": "None",
589
                "format": "PostgreSQL",
590
                "encoding": "UTF-8",
591
                "schema": {
592
                    "fields": generate_resource_fields_from_db_table(
593
                        schema,
594
                        table,
595
                    ),
596
                    "primaryKey": ["scenario", "event_id"],
597
                },
598
                "dialect": {"delimiter": "", "decimalSeparator": ""},
599
            }
600
        ],
601
        "review": {"path": "", "badge": ""},
602
        "metaMetadata": meta_metadata(),
603
        "_comment": {
604
            "metadata": (
605
                "Metadata documentation and explanation (https://github."
606
                "com/OpenEnergyPlatform/oemetadata/blob/master/metadata/"
607
                "v141/metadata_key_description.md)"
608
            ),
609
            "dates": (
610
                "Dates and time must follow the ISO8601 including time "
611
                "zone (YYYY-MM-DD or YYYY-MM-DDThh:mm:ss±hh)"
612
            ),
613
            "units": "Use a space between numbers and units (100 m)",
614
            "languages": (
615
                "Languages must follow the IETF (BCP47) format (en-GB, "
616
                "en-US, de-DE)"
617
            ),
618
            "licenses": (
619
                "License name must follow the SPDX License List "
620
                "(https://spdx.org/licenses/)"
621
            ),
622
            "review": (
623
                "Following the OEP Data Review (https://github.com/"
624
                "OpenEnergyPlatform/data-preprocessing/wiki)"
625
            ),
626
            "none": "If not applicable use (none)",
627
        },
628
    }
629
630
    dialect = get_dialect(oep_metadata_version())()
631
632
    meta = dialect.compile_and_render(dialect.parse(json.dumps(meta)))
633
634
    db.submit_comment(
635
        f"'{json.dumps(meta)}'",
636
        schema,
637
        table,
638
    )
639