Skip to content

Commit

Permalink
updated cli to include timeseries simulation command
Browse files Browse the repository at this point in the history
  • Loading branch information
EC2 Default User committed Feb 28, 2024
1 parent 4cf5d73 commit 19961a5
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 140 deletions.
3 changes: 0 additions & 3 deletions dev_requirements.txt

This file was deleted.

19 changes: 19 additions & 0 deletions docs/tutorials/timeseries-simulation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Timeseries Simulation

If you need to run timeseries simulation for a given opendss model and export some metrics you can use `timeseries-simulation` command available through emerge cli utility.

```cmd
emerge timeseries-simulation -c emerge_timeseries_config.json
```

Note `timeseries-simulation` command takes json file as configuration file. If you need json schema for this configuration file, you can run following command.

```cmd
emerge create-schemas
```

Above command creates multiple json schemas. For `timeseries-simulation` command please use schema with name `emerge_timeseries_simulation_schema.json`. If you are using vscode then you can pass `-vc` flag like below.

```cmd
emerge create-schemas -vc true
```
239 changes: 120 additions & 119 deletions emerge/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
)
from emerge.cli.custom_metrics import compute_custom_metrics
from emerge.cli.schema_generator import create_schemas
from emerge.cli.timeseries_simulation import timeseries_simulation


@click.command()
Expand All @@ -47,124 +48,124 @@ def create_geojsons(master_file, output_folder):
)


@click.command()
@click.option(
"-m",
"--master-file",
help="Path to master dss file",
)
@click.option(
"-ss",
"--simulation-start",
default="2022-1-1 00:00:00",
show_default=True,
help="Simulation start time.",
)
@click.option(
"-ps",
"--profile-start",
default="2022-1-1 00:00:00",
show_default=True,
help="Time series profile start time.",
)
@click.option(
"-se",
"--simulation-end",
default="2022-1-2 00:00:00",
show_default=True,
help="Simulation end time.",
)
@click.option(
"-r",
"--simulation-resolution",
default=60,
show_default=True,
help="Simulation time resolution in minutes.",
)
@click.option(
"-ot",
"--overvoltage-threshold",
default=1.05,
show_default=True,
help="Overvoltage threshold.",
)
@click.option(
"-ut",
"--undervoltage-threshold",
default=0.95,
show_default=True,
help="Undervoltage threshold.",
)
@click.option(
"-tt",
"--thermal-threshold",
default=0.95,
show_default=True,
help="Thermal laoding threshold.",
)
@click.option(
"-o",
"--output-json",
default="db_metric.json",
show_default=True,
help="Ouput directory for storing the db",
)
def compute_time_series_metrics(
master_file,
simulation_start,
profile_start,
simulation_end,
simulation_resolution,
overvoltage_threshold,
undervoltage_threshold,
thermal_threshold,
output_json,
):
"""Reads the OpenDSS model and computes various snapshot
metrics which can be later ingested by dashboard."""

date_format = "%Y-%m-%d %H:%M:%S"
manager = simulation_manager.OpenDSSSimulationManager(
master_file,
datetime.datetime.strptime(simulation_start, date_format),
datetime.datetime.strptime(profile_start, date_format),
datetime.datetime.strptime(simulation_end, date_format),
simulation_resolution,
)
subject = observer.MetricsSubject()

sardi_voltage_observer = system_metrics.SARDI_voltage(
overvoltage_threshold, undervoltage_threshold
)
sardi_line_observer = system_metrics.SARDI_line(thermal_threshold)
sardi_xfmr_observer = system_metrics.SARDI_transformer(thermal_threshold)
sardi_aggregated_observer = system_metrics.SARDI_aggregated(
loading_limit=thermal_threshold,
voltage_limit={
"overvoltage_threshold": overvoltage_threshold,
"undervoltage_threshold": undervoltage_threshold,
},
)
nvri_observer = node_metrics.NVRI(
overvoltage_threshold, undervoltage_threshold
)
llri_observer = node_metrics.LLRI(thermal_threshold)
tlri_observer = node_metrics.TLRI(thermal_threshold)

observers_ = [
sardi_voltage_observer,
sardi_line_observer,
sardi_xfmr_observer,
sardi_aggregated_observer,
nvri_observer,
llri_observer,
tlri_observer,
]
for observer_ in observers_:
subject.attach(observer_)

manager.simulate(subject)
observer.export_tinydb_json(observers_, output_json)
# @click.command()
# @click.option(
# "-m",
# "--master-file",
# help="Path to master dss file",
# )
# @click.option(
# "-ss",
# "--simulation-start",
# default="2022-1-1 00:00:00",
# show_default=True,
# help="Simulation start time.",
# )
# @click.option(
# "-ps",
# "--profile-start",
# default="2022-1-1 00:00:00",
# show_default=True,
# help="Time series profile start time.",
# )
# @click.option(
# "-se",
# "--simulation-end",
# default="2022-1-2 00:00:00",
# show_default=True,
# help="Simulation end time.",
# )
# @click.option(
# "-r",
# "--simulation-resolution",
# default=60,
# show_default=True,
# help="Simulation time resolution in minutes.",
# )
# @click.option(
# "-ot",
# "--overvoltage-threshold",
# default=1.05,
# show_default=True,
# help="Overvoltage threshold.",
# )
# @click.option(
# "-ut",
# "--undervoltage-threshold",
# default=0.95,
# show_default=True,
# help="Undervoltage threshold.",
# )
# @click.option(
# "-tt",
# "--thermal-threshold",
# default=0.95,
# show_default=True,
# help="Thermal laoding threshold.",
# )
# @click.option(
# "-o",
# "--output-json",
# default="db_metric.json",
# show_default=True,
# help="Ouput directory for storing the db",
# )
# def compute_time_series_metrics(
# master_file,
# simulation_start,
# profile_start,
# simulation_end,
# simulation_resolution,
# overvoltage_threshold,
# undervoltage_threshold,
# thermal_threshold,
# output_json,
# ):
# """Reads the OpenDSS model and computes various snapshot
# metrics which can be later ingested by dashboard."""

# date_format = "%Y-%m-%d %H:%M:%S"
# manager = simulation_manager.OpenDSSSimulationManager(
# master_file,
# datetime.datetime.strptime(simulation_start, date_format),
# datetime.datetime.strptime(profile_start, date_format),
# datetime.datetime.strptime(simulation_end, date_format),
# simulation_resolution,
# )
# subject = observer.MetricsSubject()

# sardi_voltage_observer = system_metrics.SARDI_voltage(
# overvoltage_threshold, undervoltage_threshold
# )
# sardi_line_observer = system_metrics.SARDI_line(thermal_threshold)
# sardi_xfmr_observer = system_metrics.SARDI_transformer(thermal_threshold)
# sardi_aggregated_observer = system_metrics.SARDI_aggregated(
# loading_limit=thermal_threshold,
# voltage_limit={
# "overvoltage_threshold": overvoltage_threshold,
# "undervoltage_threshold": undervoltage_threshold,
# },
# )
# nvri_observer = node_metrics.NVRI(
# overvoltage_threshold, undervoltage_threshold
# )
# llri_observer = node_metrics.LLRI(thermal_threshold)
# tlri_observer = node_metrics.TLRI(thermal_threshold)

# observers_ = [
# sardi_voltage_observer,
# sardi_line_observer,
# sardi_xfmr_observer,
# sardi_aggregated_observer,
# nvri_observer,
# llri_observer,
# tlri_observer,
# ]
# for observer_ in observers_:
# subject.attach(observer_)

# manager.simulate(subject)
# observer.export_tinydb_json(observers_, output_json)


@click.command()
Expand All @@ -190,7 +191,7 @@ def cli():
"""Entry point"""

cli.add_command(snapshot_metrics)
cli.add_command(compute_time_series_metrics)
cli.add_command(timeseries_simulation)
cli.add_command(create_geojsons)
cli.add_command(generate_scenarios)
cli.add_command(compute_multiscenario_time_series_metrics)
Expand Down
3 changes: 3 additions & 0 deletions emerge/cli/schema_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# internal imports
from emerge.scenarios import data_model
from emerge.utils import util
from emerge.cli.timeseries_simulation import TimeseriesSimulationInput

class SchemaItemModel(BaseModel):
name: str
Expand Down Expand Up @@ -83,6 +84,8 @@ def create_schemas(vscode: bool):
schema_manager = SchemaManager()
schema_manager.add_schema("emerge_scenario_schema",
data_model.DERScenarioConfigModel)
schema_manager.add_schema("emerge_timeseries_simulation_schema",
TimeseriesSimulationInput)
schema_manager.generate_and_save_schemas()
if vscode:
schema_manager.configure_vscode_settings()
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@
from datetime import datetime
from pathlib import Path
from typing import Annotated
import json

from pydantic import BaseModel, Field
import click

from emerge.cli import get_observers
from emerge.cli.get_observers import SimulationMetrics
from emerge.metrics import observer
from emerge.simulator.simulation_manager import OpenDSSSimulationManager

from pydantic import BaseModel, Field


class SingleModelSimulationInput(BaseModel):
"""Class interface for single model simulation input."""
class TimeseriesSimulationInput(BaseModel):
"""Interface for timeseries simulation input model."""

master_dss_file: Annotated[Path, Field(..., description="Path to master dss file.")]
start_time: Annotated[datetime, Field(..., description="Start time for simulation.")]
Expand All @@ -23,8 +26,8 @@ class SingleModelSimulationInput(BaseModel):
resolution_min: Annotated[float, Field(60, gt=0, description="Simulation time resolution in minute.")]
metrics: Annotated[SimulationMetrics, Field(SimulationMetrics(), description="Simulation metrics.")]

def compute_single_model_timeseries_metrics(config: SingleModelSimulationInput):
""" Function to compute single model timeseries metrics."""
def compute_timeseries_simulation_metrics(config: TimeseriesSimulationInput):
""" Function to compute metrics for timeseries simulation. """

manager = OpenDSSSimulationManager(
path_to_master_dss_file=config.master_dss_file,
Expand All @@ -44,15 +47,18 @@ def compute_single_model_timeseries_metrics(config: SingleModelSimulationInput):
observer.export_csv(list(observers.values()), config.export_path)


if __name__ == "__main__":
config = SingleModelSimulationInput(
start_time=datetime(2023,1,1,0,0,0),
end_time=datetime(2023,1,1,23,0,0),
profile_start_time=datetime(2023,1,1,0,0,0),
export_path="/home/ec2-user/panynj/exports/feb_12_test",
master_dss_file="/home/ec2-user/panynj/opendss_models/lga_east_end_substation/new_master.dss"
)
compute_single_model_timeseries_metrics(
config
)

@click.command()
@click.option(
"-c",
"--config",
help="Path to config file for generating scenarios",
)
def timeseries_simulation(config):
"""Function to run timeseries simulation."""

with open(config, "r", encoding="utf-8") as file:
config_dict = json.load(file)

config = TimeseriesSimulationInput.model_validate(config_dict)
compute_timeseries_simulation_metrics(config)
3 changes: 2 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ markdown_extensions:
nav:
- Welcome: index.md
- Tutorials:
- Getting started (Needs Updating): getting_started.md
- Getting Started (Needs Updating): getting_started.md
- Developing Scenarios: developing-scenarios.md
- Running Timeseries Simulation: tutorials/timeseries-simulation.md
- How to Guides: how-to-guides.md
- References:
- DER Scenario : der-scenario.md
Expand Down
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ dependencies = [
"uvicorn[standard]",
]

[project.optional-dependencies]
doc = [
"mkdocs",
"mkdocstrings[python]",
"mkdocs-material",
]

[project.scripts]
emerge = "emerge.cli.cli:cli"

Expand Down

0 comments on commit 19961a5

Please sign in to comment.