Skip to content
Snippets Groups Projects
Commit 2f790134 authored by Zizhe Wang's avatar Zizhe Wang
Browse files

refactor dynamically update MOO4Modelica's config

parent be1145e7
No related branches found
No related tags found
No related merge requests found
...@@ -4,10 +4,18 @@ ...@@ -4,10 +4,18 @@
"MODEL_FILE": "ITSystem.mo", "MODEL_FILE": "ITSystem.mo",
"MODEL_NAME": "ITSystem", "MODEL_NAME": "ITSystem",
"SIMULATION_TIME": 100, "SIMULATION_TIME": 100,
"TIME_CONFIG": {
"START_TIME": 8, "START_TIME": 8,
"END_TIME": 13, "END_TIME": 13,
"TIME_UNIT": "hour", "TIME_UNIT": "hour"
"OPTIMIZATION_PARAMETERS": { },
"OBJECTIVES": [
{"name": "remainingEnergy", "maximize": true},
{"name": "performance", "maximize": true}
],
"TUNABLE_PARAMETERS": {
"PARAMETERS": ["activeCores", "cpuFrequency"],
"PARAM_BOUNDS": {
"activeCores": { "activeCores": {
"bounds": [1, 4], "bounds": [1, 4],
"type": "int" "type": "int"
...@@ -16,11 +24,7 @@ ...@@ -16,11 +24,7 @@
"bounds": [1.0, 3.0], "bounds": [1.0, 3.0],
"type": "float" "type": "float"
} }
}, }
"EVALUATION_PARAMETERS": {
"performance": "performance",
"remaining_energy": "remainingEnergy",
"energy_consumption": "energyConsumption"
}, },
"INPUT_PARAMETERS": { "INPUT_PARAMETERS": {
"available_energy": "availableEnergy", "available_energy": "availableEnergy",
...@@ -28,5 +32,12 @@ ...@@ -28,5 +32,12 @@
}, },
"CRITERIA": { "CRITERIA": {
"GOAL_EXPRESSION": "evaluation_results['performance'] >= simulation_inputs['user_demand']" "GOAL_EXPRESSION": "evaluation_results['performance'] >= simulation_inputs['user_demand']"
} },
"PLOT_CONFIG": {
"PLOT_X": "",
"PLOT_Y": "",
"PLOT_TITLE": "",
"ENABLE_PLOT": false
},
"N_JOBS": -1
} }
\ No newline at end of file
...@@ -18,17 +18,18 @@ def build_model(omc, model_name): ...@@ -18,17 +18,18 @@ def build_model(omc, model_name):
build_result = omc.sendExpression(f'buildModel({model_name})') build_result = omc.sendExpression(f'buildModel({model_name})')
return build_result return build_result
def simulate_and_evaluate(parameters, simulation_time, simulation_inputs, global_config): def simulate_and_evaluate(parameters, simulation_time, simulation_inputs, orchestration_config):
# General setup and configuration # General setup and configuration
model_file = global_config['MODEL_FILE'] model_file = orchestration_config['MODEL_FILE']
model_name = global_config['MODEL_NAME'] model_name = orchestration_config['MODEL_NAME']
param_types = {param: details['type'] for param, details in global_config['OPTIMIZATION_PARAMETERS'].items()} param_types = {param: details['type'] for param, details in orchestration_config['TUNABLE_PARAMETERS']['PARAM_BOUNDS'].items()}
# Create a temporary directory to avoid GUID mismatch issues # Create a temporary directory to avoid GUID mismatch issues
temp_dir = tempfile.mkdtemp() temp_dir = tempfile.mkdtemp()
evaluation_parameters = global_config['EVALUATION_PARAMETERS'] evaluation_parameters = {obj['name']: obj['name'] for obj in orchestration_config['OBJECTIVES']}
input_parameters = global_config['INPUT_PARAMETERS'] input_parameters = orchestration_config['INPUT_PARAMETERS']
goal_expression = global_config['CRITERIA']['GOAL_EXPRESSION'] goal_expression = orchestration_config['CRITERIA']['GOAL_EXPRESSION']
try: try:
omc = init_omc_session(temp_dir, model_file) omc = init_omc_session(temp_dir, model_file)
...@@ -80,17 +81,17 @@ def read_data_from_file(filename): ...@@ -80,17 +81,17 @@ def read_data_from_file(filename):
data.append((time_value, *map(int, values))) # Combine time value with other data data.append((time_value, *map(int, values))) # Combine time value with other data
return data return data
def adaptive_control_loop(data, moo_wrapper, global_config): def adaptive_control_loop(data, moo_wrapper, orchestration_config):
start_time = global_config['START_TIME'] start_time = orchestration_config['TIME_CONFIG']['START_TIME']
end_time = global_config['END_TIME'] end_time = orchestration_config['TIME_CONFIG']['END_TIME']
simulation_time = global_config['SIMULATION_TIME'] simulation_time = orchestration_config['SIMULATION_TIME']
input_keys = list(global_config['INPUT_PARAMETERS'].keys()) # List of input parameter keys input_keys = list(orchestration_config['INPUT_PARAMETERS'].keys()) # List of input parameter keys
report = [] report = []
for entry in data: for entry in data:
time_value, *input_values = entry time_value, *input_values = entry
if start_time <= time_value < end_time: if start_time <= time_value < end_time:
print(f"Processing {global_config['TIME_UNIT']} {time_value}") print(f"Processing {orchestration_config['TIME_CONFIG']['TIME_UNIT']} {time_value}")
# Create a dictionary of inputs # Create a dictionary of inputs
simulation_inputs = dict(zip(input_keys, input_values)) simulation_inputs = dict(zip(input_keys, input_values))
...@@ -109,7 +110,7 @@ def adaptive_control_loop(data, moo_wrapper, global_config): ...@@ -109,7 +110,7 @@ def adaptive_control_loop(data, moo_wrapper, global_config):
for best_parameters in parameter_list: for best_parameters in parameter_list:
try: try:
evaluation_results, goal_satisfied, parameters, depletion_time = simulate_and_evaluate( evaluation_results, goal_satisfied, parameters, depletion_time = simulate_and_evaluate(
best_parameters, simulation_time, simulation_inputs, global_config) best_parameters, simulation_time, simulation_inputs, orchestration_config)
except Exception as e: except Exception as e:
print(f"Simulation error: {e}") print(f"Simulation error: {e}")
continue continue
...@@ -119,25 +120,11 @@ def adaptive_control_loop(data, moo_wrapper, global_config): ...@@ -119,25 +120,11 @@ def adaptive_control_loop(data, moo_wrapper, global_config):
# Generate the report for each hour # Generate the report for each hour
if goal_satisfied: if goal_satisfied:
report.append(f"{global_config['TIME_UNIT'].capitalize()} {time_value}: Goal satisfid with configuration {parameters}. Simulation ran for {depletion_time} seconds out of {simulation_time} seconds.") report.append(f"{orchestration_config['TIME_CONFIG']['TIME_UNIT'].capitalize()} {time_value}: Goal satisfid with configuration {parameters}. Simulation ran for {depletion_time} seconds out of {simulation_time} seconds.")
else: else:
report.append(f"{global_config['TIME_UNIT'].capitalize()} {time_value}: No sufficient configuration found. Simulation ran for {depletion_time} seconds out of {simulation_time} seconds.") report.append(f"{orchestration_config['TIME_CONFIG']['TIME_UNIT'].capitalize()} {time_value}: No sufficient configuration found. Simulation ran for {depletion_time} seconds out of {simulation_time} seconds.")
# Print the final report # Print the final report
print("\nFinal Report:") print("\nFinal Report:")
for line in report: for line in report:
print(line) print(line)
\ No newline at end of file
if __name__ == "__main__":
# Load the orchestration configuration from orchestration_config.json
with open(orchestration_config_path, 'r') as f:
orchestration_config = json.load(f)
# Read data from the specified data file
data = read_data_from_file(orchestration_config['DATA_FILE_PATH'])
# Initialize the MOO4ModelicaWrapper with the path to the MOO4Modelica config and the orchestration configuration
moo_wrapper = MOO4ModelicaWrapper(config_path=orchestration_config['CONFIG_PATH'], global_config=orchestration_config)
# Run the adaptive control loop with the loaded data and configuration
adaptive_control_loop(data, moo_wrapper, orchestration_config)
\ No newline at end of file
...@@ -5,25 +5,43 @@ import json ...@@ -5,25 +5,43 @@ import json
import os import os
from optimize_main import run_optimization from optimize_main import run_optimization
import json
import os
from optimize_main import run_optimization
class MOO4ModelicaWrapper: class MOO4ModelicaWrapper:
def __init__(self, config_path, global_config): def __init__(self, orchestration_config_path, config_path):
self.orchestration_config_path = orchestration_config_path
self.config_path = config_path self.config_path = config_path
self.global_config = global_config self.load_configs()
self.load_config() self.update_config_file()
self.model_file = global_config['MODEL_FILE']
self.model_name = global_config['MODEL_NAME'] def load_configs(self):
with open(self.orchestration_config_path, 'r') as f:
self.orchestration_config = json.load(f)
def load_config(self):
with open(self.config_path, 'r') as f: with open(self.config_path, 'r') as f:
self.config = json.load(f) self.config = json.load(f)
def update_config_file(self):
# Update config with orchestration config
self.config['MODEL_NAME'] = self.orchestration_config['MODEL_NAME']
self.config['MODEL_FILE'] = self.orchestration_config['MODEL_FILE']
self.config['SIMULATION_STOP_TIME'] = self.orchestration_config['SIMULATION_TIME']
self.config['PARAMETERS'] = self.orchestration_config['TUNABLE_PARAMETERS']['PARAMETERS']
self.config['PARAM_BOUNDS'] = self.orchestration_config['TUNABLE_PARAMETERS']['PARAM_BOUNDS']
self.config['OBJECTIVES'] = self.orchestration_config['OBJECTIVES']
self.config['PLOT_CONFIG'] = self.orchestration_config['PLOT_CONFIG']
self.config['N_JOBS'] = self.orchestration_config['N_JOBS']
with open(self.config_path, 'w') as f:
json.dump(self.config, f, indent=4)
def update_config(self, simulation_inputs, simulation_time): def update_config(self, simulation_inputs, simulation_time):
# Modify the configuration with new parameters # Update only the simulation-specific parameters
self.config['PARAMETERS'] = list(self.global_config['OPTIMIZATION_PARAMETERS'].keys())
self.config['PARAM_BOUNDS'] = self.global_config['OPTIMIZATION_PARAMETERS']
self.config['SIMULATION_STOP_TIME'] = simulation_time self.config['SIMULATION_STOP_TIME'] = simulation_time
for input_param, value in simulation_inputs.items(): for input_param, value in simulation_inputs.items():
self.config[self.global_config['INPUT_PARAMETERS'][input_param]] = value self.config[self.orchestration_config['INPUT_PARAMETERS'][input_param]] = value
# Save the updated configuration to a file # Save the updated configuration to a file
with open(self.config_path, 'w') as f: with open(self.config_path, 'w') as f:
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
import json import json
import os import os
from optimize_main import run_optimization
from orchestration_wrapper import MOO4ModelicaWrapper from orchestration_wrapper import MOO4ModelicaWrapper
from orchestration_configurator import adaptive_control_loop, read_data_from_file from orchestration_configurator import adaptive_control_loop, read_data_from_file
...@@ -13,20 +12,20 @@ orchestration_config_path = os.path.join(base_path, 'orchestration_config.json') ...@@ -13,20 +12,20 @@ orchestration_config_path = os.path.join(base_path, 'orchestration_config.json')
def main(): def main():
# Load the orchestration configuration # Load the orchestration configuration
with open(orchestration_config_path, 'r') as f: with open(orchestration_config_path, 'r') as f:
global_config = json.load(f) orchestration_config = json.load(f)
# Get paths from the orchestration configuration # Get paths from the orchestration configuration
data_file_path = os.path.join(base_path, global_config['DATA_FILE_PATH']) data_file_path = os.path.join(base_path, orchestration_config['DATA_FILE_PATH'])
config_path = os.path.join(base_path, global_config['CONFIG_PATH']) config_path = os.path.join(base_path, orchestration_config['CONFIG_PATH'])
# Read data from the specified data file # Read data from the specified data file
data = read_data_from_file(data_file_path) data = read_data_from_file(data_file_path)
# Initialize the MOO4ModelicaWrapper with the path to the MOO4Modelica config and the orchestration configuration # Initialize the MOO4ModelicaWrapper with the path to the MOO4Modelica config and the orchestration configuration
moo_wrapper = MOO4ModelicaWrapper(config_path=config_path, global_config=global_config) moo_wrapper = MOO4ModelicaWrapper(orchestration_config_path=orchestration_config_path, config_path=config_path)
# Run the adaptive control loop with the loaded data and configuration # Run the adaptive control loop with the loaded data and configuration
adaptive_control_loop(data, moo_wrapper, global_config) adaptive_control_loop(data, moo_wrapper, orchestration_config)
if __name__ == "__main__": if __name__ == "__main__":
main() main()
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment