Note

You can download this example as a Jupyter notebook or start it in interactive mode.

Unit commitment#

This tutorial runs through examples of unit commitment for generators at a single bus. Examples of minimum part-load, minimum up time, minimum down time, start up costs, shut down costs and ramp rate restrictions are shown.

To enable unit commitment on a generator, set its attribute committable = True.

[1]:
import pandas as pd

import pypsa

Minimum part load demonstration#

In final hour load goes below part-load limit of coal gen (30%), forcing gas to commit.

[2]:
nu = pypsa.Network(snapshots=range(4))

nu.add("Bus", "bus")

nu.add(
    "Generator",
    "coal",
    bus="bus",
    committable=True,
    p_min_pu=0.3,
    marginal_cost=20,
    p_nom=10000,
)

nu.add(
    "Generator",
    "gas",
    bus="bus",
    committable=True,
    marginal_cost=70,
    p_min_pu=0.1,
    p_nom=1000,
)

nu.add("Load", "load", bus="bus", p_set=[4000, 6000, 5000, 800])
[3]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.03s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 32 primals, 36 duals
Objective: 3.56e+05
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-status-min_up_time_must_stay_up were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 1e+04]
  Cost   [2e+01, 7e+01]
  Bound  [1e+00, 1e+00]
  RHS    [1e+00, 6e+03]
Presolving model
30 rows, 12 cols, 58 nonzeros  0s
0 rows, 3 cols, 0 nonzeros  0s
0 rows, 0 cols, 0 nonzeros  0s
Presolve: Optimal

Solving report
  Status            Optimal
  Primal bound      356000
  Dual bound        356000
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    356000 (objective)
                    0 (bound viol.)
                    0 (int. viol.)
                    0 (row viol.)
  Timing            0.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             0
  LP iterations     0 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)
Writing the solution to /tmp/linopy-solve-4p6vqo4v.sol
[3]:
('ok', 'optimal')
[4]:
nu.generators_t.status
[4]:
Generator-com coal gas
snapshot
0 1.0 0.0
1 1.0 0.0
2 1.0 0.0
3 0.0 1.0
[5]:
nu.generators_t.p
[5]:
Generator coal gas
snapshot
0 4000.0 0.0
1 6000.0 0.0
2 5000.0 0.0
3 0.0 800.0

Minimum up time demonstration#

Gas has minimum up time, forcing it to be online longer

[6]:
nu = pypsa.Network(snapshots=range(4))

nu.add("Bus", "bus")

nu.add(
    "Generator",
    "coal",
    bus="bus",
    committable=True,
    p_min_pu=0.3,
    marginal_cost=20,
    p_nom=10000,
)

nu.add(
    "Generator",
    "gas",
    bus="bus",
    committable=True,
    marginal_cost=70,
    p_min_pu=0.1,
    up_time_before=0,
    min_up_time=3,
    p_nom=1000,
)

nu.add("Load", "load", bus="bus", p_set=[4000, 800, 5000, 3000])
[7]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.04s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 32 primals, 39 duals
Objective: 3.06e+05
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-status-min_up_time_must_stay_up were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 1e+04]
  Cost   [2e+01, 7e+01]
  Bound  [1e+00, 1e+00]
  RHS    [1e+00, 5e+03]
Presolving model
33 rows, 16 cols, 73 nonzeros  0s
0 rows, 0 cols, 0 nonzeros  0s
Presolve: Optimal

Solving report
  Status            Optimal
  Primal bound      306000
  Dual bound        306000
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    306000 (objective)
                    0 (bound viol.)
                    0 (int. viol.)
                    0 (row viol.)
  Timing            0.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             0
  LP iterations     0 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)
Writing the solution to /tmp/linopy-solve-dm28olvv.sol
[7]:
('ok', 'optimal')
[8]:
nu.generators_t.status
[8]:
Generator-com coal gas
snapshot
0 1.0 1.0
1 0.0 1.0
2 1.0 1.0
3 1.0 0.0
[9]:
nu.generators_t.p
[9]:
Generator coal gas
snapshot
0 3900.0 100.0
1 0.0 800.0
2 4900.0 100.0
3 3000.0 -0.0

Minimum down time demonstration#

Coal has a minimum down time, forcing it to go off longer.

[10]:
nu = pypsa.Network(snapshots=range(4))

nu.add("Bus", "bus")

nu.add(
    "Generator",
    "coal",
    bus="bus",
    committable=True,
    p_min_pu=0.3,
    marginal_cost=20,
    min_down_time=2,
    down_time_before=1,
    p_nom=10000,
)

nu.add(
    "Generator",
    "gas",
    bus="bus",
    committable=True,
    marginal_cost=70,
    p_min_pu=0.1,
    p_nom=4000,
)

nu.add("Load", "load", bus="bus", p_set=[3000, 800, 3000, 8000])
[11]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following committable generators were both up and down before the simulation: Index(['coal'], dtype='object', name='Generator'). This could cause an infeasibility.
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following committable generators were both up and down before the simulation: Index(['coal'], dtype='object', name='Generator'). This could cause an infeasibility.
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.04s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 32 primals, 40 duals
Objective: 4.86e+05
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-status-min_down_time_must_stay_up were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 1e+04]
  Cost   [2e+01, 7e+01]
  Bound  [1e+00, 1e+00]
  RHS    [1e+00, 8e+03]
Presolving model
27 rows, 12 cols, 55 nonzeros  0s
4 rows, 4 cols, 8 nonzeros  0s
3 rows, 3 cols, 6 nonzeros  0s
2 rows, 2 cols, 4 nonzeros  0s
0 rows, 1 cols, 0 nonzeros  0s
0 rows, 0 cols, 0 nonzeros  0s
Presolve: Optimal

Solving report
  Status            Optimal
  Primal bound      486000
  Dual bound        486000
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    486000 (objective)
                    0 (bound viol.)
                    0 (int. viol.)
                    0 (row viol.)
  Timing            0.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             0
  LP iterations     0 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)
Writing the solution to /tmp/linopy-solve-nowk1ot4.sol
[11]:
('ok', 'optimal')
[12]:
nu.objective
[12]:
486000.0
[13]:
nu.generators_t.status
[13]:
Generator-com coal gas
snapshot
0 0.0 1.0
1 0.0 1.0
2 1.0 0.0
3 1.0 0.0
[14]:
nu.generators_t.p
[14]:
Generator coal gas
snapshot
0 0.0 3000.0
1 0.0 800.0
2 3000.0 0.0
3 8000.0 0.0

Start up and shut down costs#

Now there are associated costs for shutting down, etc

[15]:
nu = pypsa.Network(snapshots=range(4))

nu.add("Bus", "bus")

nu.add(
    "Generator",
    "coal",
    bus="bus",
    committable=True,
    p_min_pu=0.3,
    marginal_cost=20,
    min_down_time=2,
    start_up_cost=5000,
    p_nom=10000,
)

nu.add(
    "Generator",
    "gas",
    bus="bus",
    committable=True,
    marginal_cost=70,
    p_min_pu=0.1,
    shut_down_cost=25,
    p_nom=4000,
)

nu.add("Load", "load", bus="bus", p_set=[3000, 800, 3000, 8000])
[16]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.04s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 32 primals, 39 duals
Objective: 4.91e+05
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 1e+04]
  Cost   [2e+01, 5e+03]
  Bound  [1e+00, 1e+00]
  RHS    [1e+00, 8e+03]
Presolving model
33 rows, 23 cols, 78 nonzeros  0s
14 rows, 12 cols, 29 nonzeros  0s
10 rows, 10 cols, 21 nonzeros  0s
7 rows, 9 cols, 15 nonzeros  0s
6 rows, 7 cols, 12 nonzeros  0s
Objective function is integral with scale 0.04

Solving MIP model with:
   6 rows
   7 cols (7 binary, 0 integer, 0 implied int., 0 continuous)
   12 nonzeros

        Nodes      |    B&B Tree     |            Objective Bounds              |  Dynamic Constraints |       Work
     Proc. InQueue |  Leaves   Expl. | BestBound       BestSol              Gap |   Cuts   InLp Confl. | LpIters     Time

         0       0         0   0.00%   341050          inf                  inf        0      0      0         0     0.0s

Solving report
  Status            Optimal
  Primal bound      491025
  Dual bound        491025
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    491025 (objective)
                    0 (bound viol.)
                    0 (int. viol.)
                    0 (row viol.)
  Timing            0.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             1
  LP iterations     0 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)
Writing the solution to /tmp/linopy-solve-4fjimtan.sol
[16]:
('ok', 'optimal')
[17]:
nu.objective
[17]:
491025.0
[18]:
nu.generators_t.status
[18]:
Generator-com coal gas
snapshot
0 0.0 1.0
1 0.0 1.0
2 1.0 0.0
3 1.0 0.0
[19]:
nu.generators_t.p
[19]:
Generator coal gas
snapshot
0 0.0 3000.0
1 0.0 800.0
2 3000.0 0.0
3 8000.0 0.0

Ramp rate limits#

[20]:
nu = pypsa.Network(snapshots=range(6))

nu.add("Bus", "bus")

nu.add(
    "Generator",
    "coal",
    bus="bus",
    marginal_cost=20,
    ramp_limit_up=0.1,
    ramp_limit_down=0.2,
    p_nom=10000,
)

nu.add("Generator", "gas", bus="bus", marginal_cost=70, p_nom=4000)

nu.add("Load", "load", bus="bus", p_set=[4000, 7000, 7000, 7000, 7000, 3000])
[21]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.03s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 12 primals, 40 duals
Objective: 9.50e+05
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Generator-fix-p-ramp_limit_up, Generator-fix-p-ramp_limit_down were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 1e+00]
  Cost   [2e+01, 7e+01]
  Bound  [0e+00, 0e+00]
  RHS    [1e+03, 1e+04]
Presolving model
10 rows, 6 cols, 20 nonzeros  0s
2 rows, 3 cols, 4 nonzeros  0s
2 rows, 3 cols, 4 nonzeros  0s
Presolve : Reductions: rows 2(-38); columns 3(-9); elements 4(-52)
Solving the presolved LP
Using EKK dual simplex solver - serial
  Iteration        Objective     Infeasibilities num(sum)
          0     0.0000000000e+00 Ph1: 0(0) 0s
          0     9.5000000000e+05 Pr: 0(0) 0s
Solving the original LP from the solution after postsolve
Model   status      : Optimal
Objective value     :  9.5000000000e+05
HiGHS run time      :          0.00
Writing the solution to /tmp/linopy-solve-0aoj30y8.sol
[21]:
('ok', 'optimal')
[22]:
nu.generators_t.p
[22]:
Generator coal gas
snapshot
0 4000.0 -0.0
1 5000.0 2000.0
2 6000.0 1000.0
3 7000.0 -0.0
4 5000.0 2000.0
5 3000.0 -0.0
[23]:
nu = pypsa.Network(snapshots=range(6))

nu.add("Bus", "bus")

nu.add(
    "Generator",
    "coal",
    bus="bus",
    marginal_cost=20,
    ramp_limit_up=0.1,
    ramp_limit_down=0.2,
    p_nom_extendable=True,
    capital_cost=1e2,
)

nu.add("Generator", "gas", bus="bus", marginal_cost=70, p_nom=4000)

nu.add("Load", "load", bus="bus", p_set=[4000, 7000, 7000, 7000, 7000, 3000])
[24]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.04s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 13 primals, 41 duals
Objective: 1.68e+06
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Generator-ext-p-lower, Generator-ext-p-upper, Generator-ext-p-ramp_limit_up, Generator-ext-p-ramp_limit_down were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e-01, 1e+00]
  Cost   [2e+01, 1e+02]
  Bound  [0e+00, 0e+00]
  RHS    [3e+03, 7e+03]
Presolving model
16 rows, 7 cols, 42 nonzeros  0s
14 rows, 6 cols, 36 nonzeros  0s
Presolve : Reductions: rows 14(-27); columns 6(-7); elements 36(-37)
Solving the presolved LP
Using EKK dual simplex solver - serial
  Iteration        Objective     Infeasibilities num(sum)
          0     0.0000000000e+00 Ph1: 0(0) 0s
          6     1.6750000000e+06 Pr: 0(0) 0s
Solving the original LP from the solution after postsolve
Model   status      : Optimal
Simplex   iterations: 6
Objective value     :  1.6750000000e+06
HiGHS run time      :          0.00
Writing the solution to /tmp/linopy-solve-jofopmts.sol
[24]:
('ok', 'optimal')
[25]:
nu.generators.p_nom_opt
[25]:
Generator
coal    5000.0
gas     4000.0
Name: p_nom_opt, dtype: float64
[26]:
nu.generators_t.p
[26]:
Generator coal gas
snapshot
0 4000.0 -0.0
1 4500.0 2500.0
2 5000.0 2000.0
3 5000.0 2000.0
4 4000.0 3000.0
5 3000.0 -0.0
[27]:
nu = pypsa.Network(snapshots=range(7))

nu.add("Bus", "bus")

# Can get bad interactions if SU > RU and p_min_pu; similarly if SD > RD
nu.add(
    "Generator",
    "coal",
    bus="bus",
    marginal_cost=20,
    committable=True,
    p_min_pu=0.05,
    initial_status=0,
    ramp_limit_start_up=0.1,
    ramp_limit_up=0.2,
    ramp_limit_down=0.25,
    ramp_limit_shut_down=0.15,
    p_nom=10000.0,
)

nu.add("Generator", "gas", bus="bus", marginal_cost=70, p_nom=10000)

nu.add("Load", "load", bus="bus", p_set=[0.0, 200.0, 7000, 7000, 7000, 2000, 0])
WARNING:pypsa.components:Generator has no attribute initial_status, ignoring this passed value.
[28]:
nu.optimize()
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 35 primals, 61 duals
Objective: 1.15e+06
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-fix-p-lower, Generator-fix-p-upper, Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 1e+04]
  Cost   [2e+01, 7e+01]
  Bound  [1e+00, 1e+00]
  RHS    [1e+00, 1e+04]
Presolving model
39 rows, 14 cols, 101 nonzeros  0s
14 rows, 8 cols, 40 nonzeros  0s
14 rows, 8 cols, 40 nonzeros  0s

Solving MIP model with:
   14 rows
   8 cols (4 binary, 0 integer, 0 implied int., 4 continuous)
   40 nonzeros

        Nodes      |    B&B Tree     |            Objective Bounds              |  Dynamic Constraints |       Work
     Proc. InQueue |  Leaves   Expl. | BestBound       BestSol              Gap |   Cuts   InLp Confl. | LpIters     Time

         0       0         0   0.00%   1124000         inf                  inf        0      0      0         0     0.0s
 T       0       0         0   0.00%   1124000         1149000            2.18%        0      0      0         2     0.0s

Solving report
  Status            Optimal
  Primal bound      1149000
  Dual bound        1149000
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    1149000 (objective)
                    0 (bound viol.)
                    0 (int. viol.)
                    0 (row viol.)
  Timing            0.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             1
  LP iterations     2 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)
Writing the solution to /tmp/linopy-solve-ws0yxfhy.sol
[28]:
('ok', 'optimal')
[29]:
nu.generators_t.p
[29]:
Generator coal gas
snapshot
0 0.0 0.0
1 0.0 200.0
2 1000.0 6000.0
3 3000.0 4000.0
4 4000.0 3000.0
5 1500.0 500.0
6 0.0 0.0
[30]:
nu.generators_t.status
[30]:
Generator-com coal
snapshot
0 0.0
1 0.0
2 1.0
3 1.0
4 1.0
5 1.0
6 0.0
[31]:
nu.generators.loc["coal"]
[31]:
attribute
bus                            bus
control                         PQ
type
p_nom                      10000.0
p_nom_mod                      0.0
p_nom_extendable             False
p_nom_min                      0.0
p_nom_max                      inf
p_min_pu                      0.05
p_max_pu                       1.0
p_set                          0.0
q_set                          0.0
sign                           1.0
carrier
marginal_cost                 20.0
marginal_cost_quadratic        0.0
build_year                       0
lifetime                       inf
capital_cost                   0.0
efficiency                     1.0
committable                   True
start_up_cost                  0.0
shut_down_cost                 0.0
stand_by_cost                  0.0
min_up_time                      0
min_down_time                    0
up_time_before                   1
down_time_before                 0
ramp_limit_up                  0.2
ramp_limit_down               0.25
ramp_limit_start_up            0.1
ramp_limit_shut_down          0.15
weight                         1.0
p_nom_opt                  10000.0
Name: coal, dtype: object

Rolling horizon example#

This example solves sequentially in batches

[32]:
sets_of_snapshots = 6
p_set = [4000, 5000, 700, 800, 4000]

nu = pypsa.Network(snapshots=range(len(p_set) * sets_of_snapshots))

nu.add("Bus", "bus")

nu.add(
    "Generator",
    "coal",
    bus="bus",
    committable=True,
    p_min_pu=0.3,
    marginal_cost=20,
    min_down_time=2,
    min_up_time=3,
    up_time_before=1,
    ramp_limit_up=1,
    ramp_limit_down=1,
    ramp_limit_start_up=1,
    ramp_limit_shut_down=1,
    shut_down_cost=150,
    start_up_cost=200,
    p_nom=10000,
)

nu.add(
    "Generator",
    "gas",
    bus="bus",
    committable=True,
    marginal_cost=70,
    p_min_pu=0.1,
    up_time_before=2,
    min_up_time=3,
    shut_down_cost=20,
    start_up_cost=50,
    p_nom=1000,
)

nu.add("Load", "load", bus="bus", p_set=p_set * sets_of_snapshots)
[33]:
overlap = 2
for i in range(sets_of_snapshots):
    nu.optimize(nu.snapshots[i * len(p_set) : (i + 1) * len(p_set) + overlap])
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 96 duals
Objective: 5.55e+05
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 1e+04]
  Cost   [2e+01, 2e+02]
  Bound  [1e+00, 1e+00]
  RHS    [1e+00, 5e+03]
Presolving model
69 rows, 39 cols, 185 nonzeros  0s
55 rows, 35 cols, 150 nonzeros  0s
54 rows, 18 cols, 61 nonzeros  0s
9 rows, 10 cols, 23 nonzeros  0s
9 rows, 10 cols, 23 nonzeros  0s
Objective function is integral with scale 0.1

Solving MIP model with:
   9 rows
   10 cols (10 binary, 0 integer, 0 implied int., 0 continuous)
   23 nonzeros

        Nodes      |    B&B Tree     |            Objective Bounds              |  Dynamic Constraints |       Work
     Proc. InQueue |  Leaves   Expl. | BestBound       BestSol              Gap |   Cuts   InLp Confl. | LpIters     Time

         0       0         0   0.00%   550440          inf                  inf        0      0      0         0     0.0s

Solving report
  Status            Optimal
  Primal bound      555370
  Dual bound        555370
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    555370 (objective)
                    0 (bound viol.)
                    0 (int. viol.)
                    0 (row viol.)
  Timing            0.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             1
  LP iterations     0 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)
Writing the solution to /tmp/linopy-solve-w62016ig.sol
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 97 duals
Objective: 5.50e+05
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 1e+04]
  Cost   [2e+01, 2e+02]
  Bound  [1e+00, 1e+00]
  RHS    [1e+00, 6e+03]
Presolving model
72 rows, 42 cols, 195 nonzeros  0s
57 rows, 37 cols, 160 nonzeros  0s
55 rows, 19 cols, 66 nonzeros  0s
12 rows, 12 cols, 32 nonzeros  0s
9 rows, 11 cols, 24 nonzeros  0s
8 rows, 9 cols, 21 nonzeros  0s
Objective function is integral with scale 0.1

Solving MIP model with:
   8 rows
   9 cols (9 binary, 0 integer, 0 implied int., 0 continuous)
   21 nonzeros

        Nodes      |    B&B Tree     |            Objective Bounds              |  Dynamic Constraints |       Work
     Proc. InQueue |  Leaves   Expl. | BestBound       BestSol              Gap |   Cuts   InLp Confl. | LpIters     Time

         0       0         0   0.00%   545420          inf                  inf        0      0      0         0     0.0s

Solving report
  Status            Optimal
  Primal bound      550420
  Dual bound        550420
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    550420 (objective)
                    0 (bound viol.)
                    0 (int. viol.)
                    0 (row viol.)
  Timing            0.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             1
  LP iterations     1 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)
Writing the solution to /tmp/linopy-solve-3o9c0nva.sol
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 97 duals
Objective: 5.50e+05
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 1e+04]
  Cost   [2e+01, 2e+02]
  Bound  [1e+00, 1e+00]
  RHS    [1e+00, 6e+03]
Presolving model
72 rows, 42 cols, 193 nonzeros  0s
58 rows, 38 cols, 160 nonzeros  0s
57 rows, 21 cols, 71 nonzeros  0s
14 rows, 13 cols, 35 nonzeros  0s
12 rows, 13 cols, 31 nonzeros  0s
Objective function is integral with scale 0.1

Solving MIP model with:
   12 rows
   13 cols (13 binary, 0 integer, 0 implied int., 0 continuous)
   31 nonzeros

        Nodes      |    B&B Tree     |            Objective Bounds              |  Dynamic Constraints |       Work
     Proc. InQueue |  Leaves   Expl. | BestBound       BestSol              Gap |   Cuts   InLp Confl. | LpIters     Time

         0       0         0   0.00%   545440          inf                  inf        0      0      0         0     0.0s
 T       0       0         0   0.00%   545440          550440             0.91%        0      0      0         3     0.0s

Solving report
  Status            Optimal
  Primal bound      550440
  Dual bound        550440
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    550440 (objective)
                    0 (bound viol.)
                    0 (int. viol.)
                    0 (row viol.)
  Timing            0.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             1
  LP iterations     3 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)
Writing the solution to /tmp/linopy-solve-ohzhyhvn.sol
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 97 duals
Objective: 5.50e+05
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 1e+04]
  Cost   [2e+01, 2e+02]
  Bound  [1e+00, 1e+00]
  RHS    [1e+00, 6e+03]
Presolving model
72 rows, 42 cols, 195 nonzeros  0s
57 rows, 37 cols, 160 nonzeros  0s
55 rows, 19 cols, 66 nonzeros  0s
12 rows, 12 cols, 32 nonzeros  0s
9 rows, 11 cols, 24 nonzeros  0s
8 rows, 9 cols, 21 nonzeros  0s
Objective function is integral with scale 0.1

Solving MIP model with:
   8 rows
   9 cols (9 binary, 0 integer, 0 implied int., 0 continuous)
   21 nonzeros

        Nodes      |    B&B Tree     |            Objective Bounds              |  Dynamic Constraints |       Work
     Proc. InQueue |  Leaves   Expl. | BestBound       BestSol              Gap |   Cuts   InLp Confl. | LpIters     Time

         0       0         0   0.00%   545420          inf                  inf        0      0      0         0     0.0s

Solving report
  Status            Optimal
  Primal bound      550420
  Dual bound        550420
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    550420 (objective)
                    0 (bound viol.)
                    0 (int. viol.)
                    0 (row viol.)
  Timing            0.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             1
  LP iterations     1 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)
Writing the solution to /tmp/linopy-solve-jec8plrm.sol
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 56 primals, 97 duals
Objective: 5.50e+05
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
WARNING:pypsa.consistency:The following buses have carriers which are not defined:
Index(['bus'], dtype='object', name='Bus')
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 1e+04]
  Cost   [2e+01, 2e+02]
  Bound  [1e+00, 1e+00]
  RHS    [1e+00, 6e+03]
Presolving model
72 rows, 42 cols, 193 nonzeros  0s
58 rows, 38 cols, 160 nonzeros  0s
57 rows, 21 cols, 71 nonzeros  0s
14 rows, 13 cols, 35 nonzeros  0s
12 rows, 13 cols, 31 nonzeros  0s
Objective function is integral with scale 0.1

Solving MIP model with:
   12 rows
   13 cols (13 binary, 0 integer, 0 implied int., 0 continuous)
   31 nonzeros

        Nodes      |    B&B Tree     |            Objective Bounds              |  Dynamic Constraints |       Work
     Proc. InQueue |  Leaves   Expl. | BestBound       BestSol              Gap |   Cuts   InLp Confl. | LpIters     Time

         0       0         0   0.00%   545440          inf                  inf        0      0      0         0     0.0s
 T       0       0         0   0.00%   545440          550440             0.91%        0      0      0         3     0.0s

Solving report
  Status            Optimal
  Primal bound      550440
  Dual bound        550440
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    550440 (objective)
                    0 (bound viol.)
                    0 (int. viol.)
                    0 (row viol.)
  Timing            0.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             1
  LP iterations     3 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)
Writing the solution to /tmp/linopy-solve-x81j3lbi.sol
INFO:linopy.model: Solve problem using Highs solver
INFO:linopy.io: Writing time: 0.05s
INFO:linopy.solvers:Log file at /tmp/highs.log
INFO:linopy.constants: Optimization successful:
Status: ok
Termination condition: optimal
Solution: 40 primals, 69 duals
Objective: 3.70e+05
Solver model: available
Solver message: optimal

INFO:pypsa.optimization.optimize:The shadow-prices of the constraints Generator-com-p-lower, Generator-com-p-upper, Generator-com-transition-start-up, Generator-com-transition-shut-down, Generator-com-up-time, Generator-com-down-time, Generator-com-status-min_up_time_must_stay_up, Generator-com-p-ramp_limit_up, Generator-com-p-ramp_limit_down were not assigned to the network.
Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 1e+04]
  Cost   [2e+01, 2e+02]
  Bound  [1e+00, 1e+00]
  RHS    [1e+00, 6e+03]
Presolving model
46 rows, 28 cols, 121 nonzeros  0s
34 rows, 23 cols, 93 nonzeros  0s
32 rows, 11 cols, 30 nonzeros  0s
6 rows, 6 cols, 15 nonzeros  0s
3 rows, 5 cols, 7 nonzeros  0s
2 rows, 3 cols, 4 nonzeros  0s
0 rows, 0 cols, 0 nonzeros  0s
Presolve: Optimal

Solving report
  Status            Optimal
  Primal bound      370400
  Dual bound        370400
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    370400 (objective)
                    0 (bound viol.)
                    0 (int. viol.)
                    0 (row viol.)
  Timing            0.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             0
  LP iterations     0 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)
Writing the solution to /tmp/linopy-solve-5kk5258i.sol
[34]:
pd.concat(
    {"Active": nu.generators_t.status.astype(bool), "Output": nu.generators_t.p}, axis=1
)
[34]:
Active Output
Generator-com coal gas coal gas
snapshot
0 True True 3900.0 100.0
1 True True 4900.0 100.0
2 False True 0.0 700.0
3 False True 0.0 800.0
4 True False 4000.0 0.0
5 True False 4000.0 0.0
6 True False 5000.0 0.0
7 False True 0.0 700.0
8 False True 0.0 800.0
9 True True 3900.0 100.0
10 True False 4000.0 0.0
11 True True 4900.0 100.0
12 False True 0.0 700.0
13 False True 0.0 800.0
14 True False 4000.0 0.0
15 True False 4000.0 0.0
16 True False 5000.0 0.0
17 False True 0.0 700.0
18 False True 0.0 800.0
19 True True 3900.0 100.0
20 True False 4000.0 0.0
21 True True 4900.0 100.0
22 False True 0.0 700.0
23 False True 0.0 800.0
24 True False 4000.0 0.0
25 True False 4000.0 0.0
26 True False 5000.0 0.0
27 False True 0.0 700.0
28 False True 0.0 800.0
29 True True 3900.0 100.0