I am new to this forum and to energy modelling and programming with Python.
Currently, I am working on my master’s thesis about the usage of electricity storage in the logistics industry. The main focus is on energy trading and flexibility marketing with storages. Therefore, I want to implement the balancing energy market in Germany into my energy model.
The problem I am currently facing is the hourly time-step of the model. The balancing energy market, particularly for the frequency containment reserve (FCR) or Primärregelleistung in German, sells 4-hour blocks. If you purchase one block, you must keep at least 1MW of power available for 4 hours. In my model, I must ensure that my electricity storage is not used for 4 hours if the model decides to purchase a 4-hour block. The decision will be based on the FCR prices from 2023.
I planned to resample the prices into hourly intervals and use them as variable costs in the model. However, this approach may not ensure that the electricity storage will be utilized continuously for four hours.

I hope this is understandable.
Thank you in advance.

Regarding your question, the solution is rather easy if you consider an “unused” battery to be one that is neither charged nor discharged. In that case, you can add a minimum_downtime of N=4 to the corresponding flow(s), see Minimal and maximal runtime — oemof.solph 0.5.1 documentation for reference. (A trivial fallback solution would be to just use 4-horly resolution for the whole model.) Note that there currently is a flaw that it will always fix the initial value for the first and last N time steps. It will be fixed with the next release.

If you want the battery to stay at a predefined level E_FCR , however, the task is not as straightforward. You will need to formulate the constraint yourself. On the other hand, a custom constraint might come with some performance benefits. Short outline:

Introduce a binary FCR variable Y_FCR(t). (You might already have that one.)

Constraint minimum storage level to E(t) >= E_FCR * Y_FCR(t).

Constraint maximum storage level by E(t) - E_FCR <= E_max - E_FCR * Y_FCR(t).

Note that you need two constraints for upper/lower bounds that coincide when Y_FCR(t) == 1 and have no effect when Y_FCR(t) == 0.

thank you very much for your quick response, and your help.
Unfortunetly my problem is bigger than I thought.
For better understanding here is the graphic diagram of my energy system model:

The model involves multiple uses of an electricity storage system, including self-consumption optimization, peak-shaving, energy trading, and flexibility marketing on the balancing energy market. I may have made my model more complex than necessary, but after extensive troubleshooting, this is what I came up with.
The two storages are linked via the shared limit constraints, making them appear as one storage. In addition to the sources and sinks for energy trading on the right side, I want to implement the balancing energy market.
I tried implementing it with your idea and added the FCR as source with a minimum downtime of 4. I didn’t add the minimum downtime variable to the storage because the storage is also connected to the energy markets and should only have a downtime when its getting energy from the FCR. The aim was to limit the total flow of the FCR source to 1MWh within a 4-hour block or to limit the maximum runtime to 4 hours instead of the minimum downtime.

To clarify, I see two possible options:

Create an FCR source with a minimum flow of 1MW and a maximum summed flow of 1MW, with a minimum downtime of 3 hours. The model can use the source for one time step, after which it is forced into a downtime for 3 time steps before it can be used again.
A FCR sink is also required to sell the 1MWh energy within a 4-hour block.

I could set up the storage I’m already using for the energy trading to only have a downtime of 4 hours if it gets energy from the FCR source. It is required that the State of Charge of the storage remains within certain boundaries. (like 40 to 60 %) Because I have to ensure that the storage could load 1 MWh and unload 1MWh in this time.

I hope it makes sense.
I think i wont get around a custom constraint - if it is even possible to model it this way. However, I am not familiar with setting up such a constraint or the underlying mathematics.

Do you have any additional ideas to solve this problem?

By introducing multiple copies of the same energy system, you just triggered a new idea: You could have additional copies for the two extreme FCR cases, one with 1 MW of additional supply (negative FCR) and one with 1 MW of additional demand (positive FCR). This is not what would actually happen but the 1 MW could happen at any time within the four hours and your system needs to cope with it.

Your second option almost sounds like the second option I originally named, except you have different values for the upper bound and the lower bound. I think this is the more efficient way but it is also more restrictive. You could just force the battery to leave 1 MWh margin to both, its full capacity and its empty state, for the four-hour blocks where you provide FCR. Done.

I just implemented the idea with an additional energy system for the two FCRs with an additional storage which has a minimum downtime of 4 for the input and the output.
Its working! Thank you again for your help