Day-ahead energy management of a residential building

Talharehman Mtrkt
7 min readJan 10, 2024

--

In the introduction, I mentioned what all my blog series would be about. So let’s begin with a simple problem.

Problem Statement:

Our problem is to find the day-ahead optimal energy management strategy for the system shown in the below figure.

Grid-connected residential building with a battery storage system ICON SOURCE

The system consists of a residential building connected to an external utility grid. The residential building has a certain electricity demand which can be fulfilled through buying electricity from the grid. There is a battery storage system attached to the building to store or supply energy when required. We are ignoring the converters for simplicity.

For the given day-ahead electricity market prices and residential building demand, our goal is to find the optimal schedule such that the cost of the system is minimal.

To define it more concretely, we have a 24-hour daytime horizon and the operation intervals are 1h long. we are given the load demand and electricity prices at each hour. So, for each hour we want to determine how much electricity should be bought from the grid and how much the battery should be charged or discharged. This schedule should be such that the cost incurred for buying the electricity from the grid over the day is minimum.

Mathematical Modelling

Now, we know that our problem is an “Optimization Problem” since our goal is cost minimization given the system parameters. Let’s begin by describing the mathematical modeling of our optimization problem.

we start by defining a set T = {1,2,3,…,24} representing the time steps of each hour of a day.

The Optimization model consists of three major components; Decision variables, Objective function, and Constraints.

Decision variables:

These are the unknown variables that need to be determined during the optimization process. We know that we want to find at each hour the amount of electricity we buy from the grid and the amount of energy charged and discharged by the battery. These will be our decision variables, we represent them as:

SOC refers to the amount of charge available inside the battery relative to its capacity. Usually, it is represented in percentages 0–100%

Objective Function:

The objective function is a function whose value is to be either minimized or maximized. In our case, the objective is to minimize the total daily cost of buying electricity from the grid. Mathematically it can be represented by the sum of electricity bought from the grid times the cost at a given time:

Constraints:

The operating behavior and limits of the system are defined by constraints. The first constraint of our system given in the below figure is the equality (power balance) constraint, which means that the amount of power we buy from the grid plus whatever is discharged from the battery should be equal to the load demand or battery charged, at each time interval. Alternatively, we can say taking the bus as a reference, the amount of power going into the bus should be balanced by the amount of power going out of the bus.

Power balance constraint

The next constraint set defines the behavior of the battery storage system, The first equation relates to the SOC, the SOC at a given time would be equal to — the SOC level we have in the previous time step and adding the energy we are storing (charging) or subtracting the energy we are taking away (discharging) from the battery. Obviously, there would be some loss of energy based on the efficiency of the battery. The loss should also be included while modeling. It can be said that the energy going into the battery is in reality, the amount of energy available for charging multiplied by the charging efficiency, and energy going out of the battery is actually the amount of energy to be discharged divided by the discharging efficiency.

The following two inequality constraints bounds that we can only charge the battery by the amount of remaining battery capacity and we can only discharge the battery by the amount of available stored power inside the battery. The last constraint in the figure represents that the initial SOC at the start of the day must be equal to the SOC at the end of the day.

Battery Operational Constraints

The last set of constraints given in the below figure is the bounding and non-negativity constraint. The first two relate to the fact that at a time battery can only be discharged or charged within the limit of its power rating. The last constraint ensures that the state of charge of the battery should remain between 0–1 (which means in theory 0–100%).

Limiting/bounding constraints

Input Data:

Our input data of price and load are shown in the below figure

Solution:

Our model is a linear programming (LP) model as our objective function and constraints are all linear provided that the battery capacity is fixed. we will use Cplex with C++ to solve it!
Starting by defining the inputs using “int” for integer values, “float” for the floating values, and pointers to the arrays:

    int T = 24; //One day

int* Pload = new int[T] {169, 175, 179, 171, 181, 172, 270, 264, 273, 281, 193, 158, 161, 162, 250, 260, 267, 271, 284, 167, 128, 134, 144, 150}; //Electicity demand w.r.t tim
int* CGbuy = new int[T] { 90, 90, 90, 90, 90, 90, 110, 110, 110, 110, 110, 125, 125, 125, 125, 125, 125, 125, 110, 110, 110, 110, 110, 110 }; //buying price from grid w.r.t time

int Pbmax = 200; //battery maximum capacity
int chgmax = 100; //battery maximum charging rate
int dischgmax = 100; //battery maximum discharging rate

float chgeffin = 0.95; //battery effciency
float dischgeffin = 0.95; //battery effciency

In Cplex, first, we have to create the new environment and the model inisde it which is achieved by the builtin clasess “IloEnv” and “IloModel”:

    IloEnv env;
IloModel model(env);

The Cplex provides ways to declare the decision variables; since we have to find the value of the decision variable at each time step so it should be a single dimensional array we will use the “IloNumVarArray” class. The following code snippet shows the declaration of single dimensional decision variables with Cplex.

    IloNumVarArray PGbuy(env, T, 0, IloInfinity);//Grid power bought
IloNumVarArray PGsell(env, T, 0, IloInfinity);//Grid power sold
IloNumVarArray statoc(env, T, 0, 1); //battery state of charge
IloNumVarArray Bchg(env, T, 0, IloInfinity); //battery charging
IloNumVarArray Bdischg(env, T, 0, IloInfinity); //battery discharging

Now, we define the objective function (The summation expression) using the “for” loop, “IloExpr” class. To define the minimization objective in our model we use the built-in functionality of Cplex “IloMinimize”. “model.add()” function will include this minimization objective expression to our model.

    IloExpr objective(env); //Defining the expression for the objective function
for (int t = 0; t < T; t++)
{
// sum of cost incurred by buying power from grid at each time step
objective += CGbuy[t] * PGbuy[t];
}
// Objective: minimize cost over 24 hours
model.add(IloMinimize(env, objective));

The constraits can be added to the model as:

    // Constraint: meet demand
for (int t = 0; t < T; t++)
{
// Adding the Battery Constraints constraints
if (t == 0)
{
// statoc[T-1] is the end of the day SOC
model.add(statoc[t] == statoc[T-1] + ((chgeffin * Bchg[t] - (Bdischg[t] / dischgeffin)) / Pbmax));
model.add(0 <= Bchg[t]);
model.add(0 <= Bdischg[t]);
model.add(Bchg[t] <= (Pbmax * (1 - statoc[T - 1]) / chgeffin));
model.add(Bdischg[t] <= (Pbmax * statoc[T - 1] * dischgeffin));
}
else
{
model.add(statoc[t] == statoc[t - 1] + ((chgeffin * Bchg[t] - (Bdischg[t] / dischgeffin)) / Pbmax));
model.add(0 <= Bchg[t]);
model.add(0 <= Bdischg[t]);
model.add(Bchg[t] <= (Pbmax * (1 - statoc[t - 1])) / chgeffin);
model.add(Bdischg[t] <= Pbmax * statoc[t - 1] * dischgeffin);
}

model.add(Bchg[t] <= chgmax);
model.add(Bdischg[t] <= dischgmax);
model.add(0 <= statoc[t]);
model.add(statoc[t] <= 1);

// Adding the power balance constraint
model.add(Bdischg[t] + PGbuy[t] == Pload[t] + Bchg[t]);
}

To solve the model we have to use the Cplex solver, defined by this code snippet.

    IloCplex cplex(env);
//cplex.extract(model);
//cplex.setOut(env.getNullStream());
if (!cplex.solve()) { // if fails then throw error
env.error() << "Failed" << endl;
throw(-1);
}

Results:

The final results obtained are shown in the below figure, the minimum objective value is 532232, and in the schedule, we see that the battery is charged at intervals 2,4 and 6. At these intervals, the price of electricity is low so it bought extra energy from the grid and stored it inside the battery. The battery is discharged at intervals 13 and 16 since at these times the price of electricity is higher so it partially fulfills the load requirement through the battery while buying the remaining from the grid. The load demand is fully met at each time step.

Output objective
Output Schedule

The code can be found under the repository:

GitHub — TalhaRehmanMTRKT/OptimalOperations: This repository consists the Code (C++/Cplex implementation) for my blog series related to Optimal Operations

Way Forward:

In this blog, we look at the way to formulate the optimization model for a simple problem and get familiarized with the Implementation in Cplex. In the next blogs, we will try to cover other and more complex systems, modeling, and implementation. Moreover, we will look into the analysis way to better understand the systems.

Leave a comment below if you have any feedback.

--

--