Passed
Push — dev ( 7cf077...0e9721 )
by
unknown
07:11 queued 04:45
created

data.datasets.emobility.motorized_individual_travel.db_classes   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 665
Duplicated Lines 7.52 %

Importance

Changes 0
Metric Value
wmc 1
eloc 370
dl 50
loc 665
rs 10
c 0
b 0
f 0

1 Function

Rating   Name   Duplication   Size   Complexity  
B add_metadata() 0 367 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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