Skip to content

Commit

Permalink
Merge pull request #55 from openEDI/jm/pnnl_oedisi_dopf
Browse files Browse the repository at this point in the history
Add multicontainer and regular pnnl dopf
  • Loading branch information
josephmckinsey authored Aug 6, 2024
2 parents 31f8278 + 2ced7f6 commit d200703
Show file tree
Hide file tree
Showing 14 changed files with 1,987 additions and 72 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ WORKDIR /simulation
COPY scenarios/docker_system.json docker_system.json
COPY components.json .
COPY LocalFeeder LocalFeeder
COPY lindistflow_federate lindistflow_federate
COPY README.md .
COPY measuring_federate measuring_federate
COPY wls_federate wls_federate
Expand Down
118 changes: 70 additions & 48 deletions broker/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,47 +15,55 @@
import os
import json

from oedisi.componentframework.system_configuration import WiringDiagram, ComponentStruct
from oedisi.componentframework.system_configuration import (
WiringDiagram,
ComponentStruct,
)
from oedisi.types.common import ServerReply, HeathCheck
from oedisi.tools.broker_utils import get_time_data

logger = logging.getLogger('uvicorn.error')
logger = logging.getLogger("uvicorn.error")

app = FastAPI()

is_kubernetes_env = os.environ['KUBERNETES_SERVICE_NAME'] if 'KUBERNETES_SERVICE_NAME' in os.environ else None
is_kubernetes_env = (
os.environ["KUBERNETES_SERVICE_NAME"]
if "KUBERNETES_SERVICE_NAME" in os.environ
else None
)

WIRING_DIAGRAM_FILENAME = "system.json"
WIRING_DIAGRAM : WiringDiagram | None = None
WIRING_DIAGRAM: WiringDiagram | None = None

def build_url(host:str, port:int, enpoint:list):

def build_url(host: str, port: int, enpoint: list):
if is_kubernetes_env:
KUBERNETES_SERVICE_NAME = os.environ['KUBERNETES_SERVICE_NAME']
KUBERNETES_SERVICE_NAME = os.environ["KUBERNETES_SERVICE_NAME"]
url = f"http://{host}.{KUBERNETES_SERVICE_NAME}:{port}/"
else:
url = f"http://{host}:{port}/"
url = url + "/".join(enpoint) + "/"
return url

url = url + "/".join(enpoint) + "/"
return url


def find_filenames(path_to_dir=os.getcwd(), suffix=".feather"):
filenames = os.listdir(path_to_dir)
return [filename for filename in filenames if filename.endswith(suffix)]


def read_settings():

broker_host = socket.gethostname()
broker_ip = socket.gethostbyname(broker_host)
api_port = 8766 #int(os.environ['PORT'])

component_map = {
broker_host: api_port
}
api_port = 8766 # int(os.environ['PORT'])

component_map = {broker_host: api_port}
if WIRING_DIAGRAM:
for component in WIRING_DIAGRAM.components:
component_map[component.host] = component.container_port
else:
logger.info("Use the '/configure' setpoint to setup up the WiringDiagram before making requests other enpoints")
logger.info(
"Use the '/configure' setpoint to setup up the WiringDiagram before making requests other enpoints"
)

return component_map, broker_ip, api_port

Expand All @@ -69,6 +77,7 @@ def read_root():

return JSONResponse(response, 200)


@app.post("/profiles")
async def upload_profiles(file: UploadFile):
try:
Expand All @@ -84,10 +93,10 @@ async def upload_profiles(file: UploadFile):
)
with open(file.filename, "wb") as f:
f.write(data)
url = build_url(ip, port, ["profiles"])

url = build_url(ip, port, ["profiles"])
logger.info(f"making a request to url - {url}")

files = {"file": open(file.filename, "rb")}
r = requests.post(url, files=files)
response = ServerReply(detail=r.text).dict()
Expand All @@ -97,6 +106,7 @@ async def upload_profiles(file: UploadFile):
err = traceback.format_exc()
raise HTTPException(status_code=500, detail=str(err))


@app.post("/model")
async def upload_model(file: UploadFile):
try:
Expand All @@ -112,10 +122,10 @@ async def upload_model(file: UploadFile):
)
with open(file.filename, "wb") as f:
f.write(data)
url = build_url(ip, port, ["model"])

url = build_url(ip, port, ["model"])
logger.info(f"making a request to url - {url}")

files = {"file": open(file.filename, "rb")}
r = requests.post(url, files=files)
response = ServerReply(detail=r.text).dict()
Expand All @@ -125,23 +135,24 @@ async def upload_model(file: UploadFile):
err = traceback.format_exc()
raise HTTPException(status_code=500, detail=str(err))


@app.get("/results")
def download_results():
component_map, _, _ = read_settings()

for hostname in component_map:
if "recorder" in hostname:
host = hostname
port = component_map[hostname]
url = build_url(host, port, ["download"])

url = build_url(host, port, ["download"])
logger.info(f"making a request to url - {url}")

response = requests.get(url)
logger.info(f"Response from {hostname} has {len(response.content)} bytes")
with open(f"{hostname}.feather", "wb") as out_file:
out_file.write(response.content)

file_path = "results.zip"
with zipfile.ZipFile(file_path, "w") as zipMe:
for feather_file in find_filenames():
Expand All @@ -152,6 +163,7 @@ def download_results():
except Exception as e:
raise HTTPException(status_code=404, detail="Failed download")


@app.get("/terminate")
def terminate_simulation():
try:
Expand All @@ -160,11 +172,13 @@ def terminate_simulation():
except Exception as e:
raise HTTPException(status_code=404, detail="Failed download ")

def _get_feeder_info(component_map:dict):

def _get_feeder_info(component_map: dict):
for host in component_map:
if host == "feeder":
return host, component_map[host]


def run_simulation():
component_map, broker_ip, api_port = read_settings()
feeder_host, feeder_port = _get_feeder_info(component_map)
Expand All @@ -180,20 +194,20 @@ def run_simulation():
logger.info(f"Broker connected: {isconnected}")
logger.info(str(component_map))
replies = []

broker_host = socket.gethostname()

for service_ip, service_port in component_map.items():
if service_ip != broker_host:
url = build_url(service_ip, service_port, ["run"])
url = build_url(service_ip, service_port, ["run"])
logger.info(f"making a request to url - {url}")

myobj = {
"broker_port": 23404,
"broker_ip": broker_ip,
"api_port": api_port,
"feeder_host": feeder_host,
"feeder_port": feeder_port
"feeder_port": feeder_port,
}
replies.append(grequests.post(url, json=myobj))
grequests.map(replies)
Expand All @@ -203,6 +217,7 @@ def run_simulation():

return


@app.post("/run")
async def run_feeder(background_tasks: BackgroundTasks):
try:
Expand All @@ -213,28 +228,34 @@ async def run_feeder(background_tasks: BackgroundTasks):
err = traceback.format_exc()
raise HTTPException(status_code=404, detail=str(err))


@app.post("/configure")
async def configure(wiring_diagram:WiringDiagram):
global WIRING_DIAGRAM
async def configure(wiring_diagram: WiringDiagram):
global WIRING_DIAGRAM
WIRING_DIAGRAM = wiring_diagram

json.dump(wiring_diagram.dict(), open(WIRING_DIAGRAM_FILENAME, "w"))
for component in wiring_diagram.components:
component_model = ComponentStruct(
component = component,
links = []
)
component_model = ComponentStruct(component=component, links=[])
for link in wiring_diagram.links:
if link.target == component.name:
component_model.links.append(link)
url = build_url(component.host, component.container_port, ["configure"])

url = build_url(component.host, component.container_port, ["configure"])
logger.info(f"making a request to url - {url}")

r = requests.post(url, json=component_model.dict())
assert r.status_code==200, f"POST request to update configuration failed for url - {url}"
return JSONResponse(ServerReply(detail="Sucessfully updated config files for all containers").dict(), 200)

assert (
r.status_code == 200
), f"POST request to update configuration failed for url - {url}"
return JSONResponse(
ServerReply(
detail="Sucessfully updated config files for all containers"
).dict(),
200,
)


@app.get("/status/")
async def status():
try:
Expand All @@ -250,7 +271,8 @@ async def status():
except AttributeError as e:
return {"reply": str(e), "error": True}


if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=int(os.environ['PORT']))
uvicorn.run(app, host="0.0.0.0", port=int(os.environ["PORT"]))
# test_function()
# read_settings()
# read_settings()
4 changes: 3 additions & 1 deletion components.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
"LocalFeeder": "LocalFeeder/component_definition.json",
"MeasurementComponent": "measuring_federate/component_definition.json",
"StateEstimatorComponent": "wls_federate/component_definition.json",
"OMOOComponent": "omoo_federate/component_definition.json"
"OMOOComponent": "omoo_federate/component_definition.json",
"Feeder": "LocalFeeder/component_definition.json",
"OptimalPowerFlow": "lindistflow_federate/component_definition.json"
}
Loading

0 comments on commit d200703

Please sign in to comment.