MPC/Pyomo Migration Guide

Summary

MPC experiments were redesigned to separate model logic from environment logic. The previous MathSolver + PyomoEnv setup is now built around MpcAgent + PyomoModel.

What changed:

  • MathSolver was replaced by MpcAgent

  • MPC model definition moved from PyomoEnv._model() into a dedicated PyomoModel subclass

  • prediction_horizon is configured in [settings]

  • model_parameters are configured in [settings.agent.model_parameters]

  • MpcAgent now requires model_import (dotted import path to your PyomoModel)

Estimated effort: 5-10 minutes for MPC experiments.

Config File Changes

1. Replace MathSolver with MpcAgent

Set the agent class in [setup]:

agent_import = "eta_ctrl.agents.MpcAgent"

2. Keep prediction_horizon in [settings]

prediction_horizon is now a framework-level setting, validated together with sampling_time.

prediction_horizon = 600  # time in seconds, optimization horizon K, is constant

3. Move model settings under [settings.agent]

Define model_import and put all model parameters under [settings.agent.model_parameters]:

Solver-specific options are now passed via a dedicated solver_options mapping instead of defining solver keys directly in [settings.agent].

Before:

[settings.agent]
model_import = "my_package.my_model.MyModel"
solver_name = "cplex_direct"
timelimit = 30

After:

[settings.agent]
model_import = "my_package.my_model.MyModel"
solver_name = "cplex_direct"
[settings.agent.solver_options]
timelimit = 30
# or solver_options = {timelimit = 30}

Full config after migration:

[settings.agent]
model_import = "examples.kea_tank.kea_pyomo_model.DrKeaModel"
solver_name = "cplex_direct"
[settings.agent.solver_options]
timelimit = 30

[settings.agent.model_parameters]
p_heat = 10  # kW, heating power consumption
tank_temperature_start = 60  # °C
tank_temperature_min = 55  # °C
tank_temperature_max = 65  # °C
temperature_change_heating = 0.02  # Kelvin per second
temperature_change_cleaning = -0.01  # Kelvin per second

Python Code Changes

4. Move _model() from PyomoEnv to PyomoModel

The optimization model definition stays mostly unchanged, but it now lives in a PyomoModel subclass.

5. Feed current state values as observations in the environment

In this architecture, the environment provides current values that are used by the model parameters.

    def _step(self) -> tuple[float, bool, bool, dict]:
        if self.state["heating"] == 1:
            self.temp += 0.02 * self.sampling_time
        else:
            self.temp -= 0.01 * self.sampling_time

        self.state["tank_temperature_start"] = np.array([self.temp])
        return 0, False, False, {}

Optional New Feature: PyomoSimEnv

PyomoSimEnv is a new environment type and not a required migration step. Use it when you want to run a Pyomo model as a simulation model for the next timestep, without MPC optimization and without calling a solver.

In this mode, the model is evaluated step-by-step using mapped expressions:

  • Define model_import to a PyomoModel subclass in your environment

  • Provide _start_value_mapping in the PyomoModel

  • Use external outputs/state values as handover parameters for the next step

If you only migrate existing MPC experiments (MpcAgent + optimization), you can skip this section.

Migration Checklist

  • Replace agent_import = "eta_ctrl.agents.MathSolver" with "eta_ctrl.agents.MpcAgent"

  • Create a PyomoModel class and move your _model() implementation there

  • Set model_import in [settings.agent]

  • Keep prediction_horizon in [settings]

  • Move model parameters to [settings.agent.model_parameters]

Common Issues

Missing model_import

Symptom: Agent initialization fails when creating the MPC model.

Fix: Add model_import under [settings.agent] and point it to your PyomoModel subclass.

Invalid prediction horizon setup

Symptom: prediction_horizon is not found.

Fix: Ensure prediction_horizon is placed in [settings] and not in [settings.agent].