Skip to content

Scenario Data Models

Scenario Data Models

Module for handling data model used in scenario generation.

BasicDERModel

Bases: BaseModel

Basic DER model used in solar scenario development.

Source code in emerge\scenarios\data_model.py
 95
 96
 97
 98
 99
100
101
102
103
class BasicDERModel(BaseModel):
    """Basic DER model used in solar scenario development."""

    name: str
    kw: Annotated[float, Field(ge=0)]
    customer: CustomerModel
    der_type: DERType
    der_tag: str = ''
    profile: str

CapacityStrategyEnum

Bases: str, Enum

Available strategies for sizing solar systems.

Source code in emerge\scenarios\data_model.py
28
29
30
31
32
33
34
class CapacityStrategyEnum(str, Enum):
    """Available strategies for sizing solar systems."""

    # pylint: disable=invalid-name
    solar_energy_based = "solar_energy_based"
    peak_multiplier = "peak_multiplier"
    fixed_sizing = "fixed_sizing"

CustomerModel

Bases: BaseModel

Interface for representing customer used in pv scenario development.

Source code in emerge\scenarios\data_model.py
14
15
16
17
18
19
20
class CustomerModel(BaseModel):
    """Interface for representing customer used in pv scenario development."""

    name: str
    kw: float
    distance: float
    cust_type: Optional[str] = None

DERScenarioConfigModel

Bases: ScenarioBaseConfig

CLI interface model for generating solar scenarios.

Source code in emerge\scenarios\data_model.py
140
141
142
143
144
145
146
class DERScenarioConfigModel(ScenarioBaseConfig):
    """CLI interface model for generating solar scenarios."""

    master_file: str
    output_folder: str
    opendss_attr: Literal['yearly', 'class'] = 'class'
    der_scenario: List[DERScenarioInputModel]

DERScenarioInput

Bases: _DERScenarioInput

Input model for der scenarios.

Source code in emerge\scenarios\data_model.py
89
90
91
92
class DERScenarioInput(_DERScenarioInput):
    """ Input model for der scenarios. """
    selection_strategy: SelectionStrategyEnum
    other_ders: List[_DERScenarioInput]

DERScenarioInputModel

Bases: _DERScenarioInput

Interface for der scenario input model.

Source code in emerge\scenarios\data_model.py
125
126
127
128
129
class DERScenarioInputModel(_DERScenarioInput):
    """ Interface for der scenario input model. """
    file_name: str
    selection_strategy: SelectionStrategyEnum
    other_ders: List[_DERScenarioInput]

DERType

Bases: str, Enum

Available der enum types.

Source code in emerge\scenarios\data_model.py
22
23
24
25
26
class DERType(str, Enum):
    """Available der enum types."""
    # pylint: disable=invalid-name
    load = 'load'
    solar = 'solar'

DistDERScenarioModel

Bases: BaseModel

Model for storing solars in a given scenario.

Source code in emerge\scenarios\data_model.py
105
106
107
108
109
110
111
class DistDERScenarioModel(BaseModel):
    """Model for storing solars in a given scenario."""

    name: str
    sample_id: int
    penetration: float
    ders: List[BasicDERModel]

EnergyBasedSolarSizingStrategyInput

Bases: BaseModel

Input model for default solar sizing strategy.

Source code in emerge\scenarios\data_model.py
46
47
48
49
50
51
52
class EnergyBasedSolarSizingStrategyInput(BaseModel):
    """Input model for default solar sizing strategy."""

    capacity_factor: Annotated[float, Field(gt=0, le=1)] = 0.3
    load_factor: Annotated[float, Field(gt=0, le=1)] = 0.33
    max_pct_production: Annotated[float, Field(gt=0, le=500)] = 100
    profile: str

LoadMetadataModel

Bases: BaseModel

Interface for representing OpenDSS load metadata.

Source code in emerge\scenarios\data_model.py
114
115
116
117
118
119
120
121
class LoadMetadataModel(BaseModel):
    """Interface for representing OpenDSS load metadata."""

    name: str
    bus: str
    num_phase: Annotated[int, Field(ge=1, le=3)]
    kv: Annotated[float, Field(gt=0)]
    yearly: Optional[str] = None

ScenarioBaseConfig

Bases: BaseModel

Interface for basic settings in defining scenario.

Source code in emerge\scenarios\data_model.py
132
133
134
135
136
137
138
class ScenarioBaseConfig(BaseModel):
    """ Interface for basic settings in defining scenario."""
    pct_resolution: Annotated[float, Field(gt=0, le=100)] = Field(
        description="Percentage resolution or step resolution"
    )
    num_of_penetration: Annotated[int, Field(gt=0)]
    max_num_of_samples: Annotated[int, Field(ge=1)] = 1

SelectionStrategyEnum

Bases: str, Enum

Available strategies for selecting loads to have pv system.

Source code in emerge\scenarios\data_model.py
37
38
39
40
41
42
43
class SelectionStrategyEnum(str, Enum):
    """Available strategies for selecting loads to have pv system."""

    # pylint: disable=invalid-name
    random_allocation = "random_allocation"
    far_allocation = "far_allocation"
    near_allocation = "near_allocation"

SizeWithProbabilityModel

Bases: BaseModel

Use this model if you want to pick sizes with probabilities.

Source code in emerge\scenarios\data_model.py
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
class SizeWithProbabilityModel(BaseModel):
    """ Use this model if you want to pick sizes with probabilities. """

    sizes: List[float] | float
    probabilites: List[Annotated[float, Field(ge=0, le=1)]] | float
    profile: List[str] | str


    @model_validator(mode="after")
    def validate_lengths_are_same(self) -> 'SizeWithProbabilityModel':
        if isinstance(self.sizes, list) or isinstance(self.probabilites, list) \
            or isinstance(self.profile, list):

            try:
                if len(self.sizes) == len(self.probabilites) == len(self.profile):
                    return self 
                raise ValueError("Length must match for sizes,  probabilities and profile names. ")
            except Exception as error:
                raise PydanticCustomError(
                    'mixed_type',
                    f"Error validating fields : {error}"
                )
        return self