Flexibility configuration
FlexMeasures describes an optimization problem with two complementary parts: a system-wide flex-context and one or more device-specific flex-models. Together they describe what flexibility is available, what limits it, and what outcome the scheduler should optimize.
This page defines these concepts independently of how they are configured. They can be persisted on assets, edited in the UI, or supplied when triggering a schedule through the API, client, or CLI.
Describing flexibility
To compute a schedule, FlexMeasures first needs to assess the flexibility state of the system. This is described by:
The flex-context ― information about the system as a whole, in order to assess the value of activating flexibility.
Flex-models ― information about the state and possible actions of the flexible device. We will discuss these per scheduled device type.
This information goes beyond the usual time series recorded by an asset’s sensors. It can be sent to FlexMeasures through the API when triggering schedule computation. Also, this information can be persisted on the FlexMeasures data model (in the db), and is editable through the UI (actually, that is design work in progress, currently possible with the flex context).
Note
You can also specify the scheduling resolution to control how often setpoints can change in the schedule. See Scheduling resolution for details on when and how to use custom resolutions.
Let’s dive into the details ― what can you tell FlexMeasures about your optimization problem?
Variable quantities
Many API fields deal with variable quantities, for example, flex-model and flex-context fields. Unless stated otherwise, values of such fields can take one of the following forms:
A fixed quantity, to describe steady constraints such as a physical power capacity. For example:
{ "power-capacity": "15 kW" }
A variable quantity defined at specific moments in time, to describe dynamic constraints/preferences such as target states of charge.
{ "soc-targets": [ {"datetime": "2024-02-05T08:00:00+01:00", "value": "8.2 kWh"}, ... {"datetime": "2024-02-05T13:00:00+01:00", "value": "2.2 kWh"} ] }
A variable quantity defined for specific time ranges, to describe dynamic constraints/preferences such as minimum state-of-charge requirements.
{ "soc-minima": [ {"start": "2024-02-05T08:00:00+01:00", "duration": "PT2H", "value": "10.1 kWh"}, ... {"start": "2024-02-05T13:00:00+01:00", "end": "2024-02-05T13:15:00+01:00", "value": "10.3 kWh"} ] }
Note the two distinct ways of specifying a time period (
"end"in combination with"duration"also works).Note
In case a field defines partially overlapping time periods, FlexMeasures automatically resolves this. By default, time periods that are defined earlier in the list take precedence. Fields that deviate from this policy will note so explicitly. (For example, for fields dealing with capacities, the minimum is selected instead.)
A reference to a sensor that records a variable quantity, which allows cross-referencing to dynamic contexts that are already recorded as sensor data in FlexMeasures. For instance, a site’s contracted consumption capacity that changes over time.
{ "site-consumption-capacity": {"sensor": 55} }
The unit of the data is specified on the sensor.
A sensor reference can optionally include a source filter, so it keeps pointing at the right data even when multiple sources (e.g. a forecast and a schedule) record beliefs on the same sensor:
{ "site-consumption-capacity": {"sensor": 55, "source-types": ["forecaster"]} }
The supported filter keys are:
source-types/exclude-source-types: include or exclude sources by type (e.g."forecaster","scheduler","user"). Recommended over a specificsourceorsourcesID, because forecasters and schedulers are versioned — a version bump gives new data a new source ID, but the source-type stays the same, so filters based on it don’t need updating.source-account: a list of account IDs, to filter by the account(s) linked to data sources. Useful in multi-tenant setups where several accounts run their own forecasters or schedulers.sources: a list of specific data source IDs.source: a single specific data source ID.
This is the same source filtering mechanism described under Sources, just scoped to sensor references inside flex-model/flex-context fields rather than GET data endpoints.
A few fields don’t hold a single variable quantity, but a list of them, whose values add up.
The soc-gain and soc-usage fields of the flex-model work this way, so that separate components (say, two loads draining the same buffer) can be described independently.
Each component takes any of the forms listed above, so a component defined for specific time ranges sits one level deeper than in those examples:
{
"soc-usage": [
"100 W",
{"sensor": 23},
[
{"start": "2024-02-05T08:00:00+01:00", "duration": "PT2H", "value": "10.1 kW"},
{"start": "2024-02-05T13:00:00+01:00", "duration": "PT2H", "value": "10.3 kW"}
]
]
}
The flex-context
The flex-context is independent of the type of flexible device that is optimized, or which scheduler is used.
With the flexibility context, we aim to describe the system in which the flexible assets operate, such as its physical and contractual limitations.
For multi-commodity scheduling problems, the flex-context can be defined separately per commodity (e.g. electricity and gas). See A flex-modeling tutorial for storage: Multiple commodities (gas & electricity) for a hands-on example.
A non-electricity commodity that defines no energy prices and no capacity (grid-connection) fields in the flex-context (e.g. a heat or steam network without a grid connection) is treated as an internal node:
its devices must balance each other at every time step, so everything produced into the node is consumed from it within the same time step.
Electricity is the exception: it is always assumed to be grid-connected, so electricity without a price raises an error rather than becoming an internal node.
Devices that convert between commodities (such as a CHP unit, gas boiler or electric heater) are described in the flex-model, one entry per commodity port, tied together by a coupling group. See Converters between commodities for a worked example flex-model.
Fields can have fixed values, but some fields can also point to sensors, so they will always represent the dynamics of the asset’s environment (as long as that sensor has current data). The full list of flex-context fields follows below. For more details on the possible formats for field values, see Variable quantities.
Where should you set these fields? Within requests to the API or by editing the relevant asset in the UI. If they are not sent in via the API (one of the endpoints triggering schedule computation), the scheduler will look them up on the flex-context field of the asset. And if the asset belongs to a larger system (a hierarchy of assets), the scheduler will also search if parent assets have them set.
Field |
Example value |
Description |
|---|---|---|
|
|
Commodity to which this part of the flex-context applies.
Defaults to |
|
|
Power (or energy) sensors representing loads that are relevant, but not flexible in the timing of their demand. For example, a sensor recording the power of a base load that is connected behind the main meter, and whose consumption falls under the same contract as the flexible device(s) being scheduled. Their power demand cannot be adjusted but still matters for finding the best schedule for other devices. The sign convention is determined by the key name: positive values denote consumption.
Sensors that explicitly record consumption as negative values ( Each entry is a sensor reference, optionally with source filters. In the flex-context this is a list of such references (site-level base load); in a flex-model entry it is a single reference, so that an inflexible device modelled as its own asset can join a |
|
|
Power (or energy) sensors representing generators that are relevant, but not flexible in the timing of their supply. For example, a sensor recording rooftop solar power that is connected behind the main meter, and whose production falls under the same contract as the flexible device(s) being scheduled. Their power supply cannot be adjusted but still matters for finding the best schedule for other devices. The sign convention is determined by the key name: positive values denote production (the FlexMeasures default).
Sensors that explicitly record production as negative values ( Each entry is a sensor reference, optionally with source filters. In the flex-context this is a list of such references (site-level base generation); in a flex-model entry it is a single reference, so that an inflexible device modelled as its own asset can join a |
|
|
[Deprecated field] Power sensors representing devices that are relevant, but not flexible in the timing of their demand/supply.
To avoid using the field, use |
|
|
Sensor used to record the aggregate consumption schedule of all flexible and inflexible devices involved when scheduling this asset. The sign convention is determined by the key name, and is stored on the sensor itself using the Depending on which output sensors are defined:
|
|
|
Sensor used to record the aggregate production schedule of all flexible and inflexible devices involved when scheduling this asset. The sign convention is determined by the key name, and is stored on the sensor itself using the See the |
|
|
[Deprecated field] Sensor used to record the aggregate power schedule of all flexible and inflexible devices involved when scheduling this asset.
To avoid using the field, use |
|
|
The commodity price (e.g. electricity price) applied to the site’s aggregate consumption. Can be (a sensor recording) market prices, but also CO₂ intensity—whatever fits your optimization problem. [1] |
|
|
The commodity price (e.g. electricity price) applied to the site’s aggregate production. Can be (a sensor recording) market prices, but also CO₂ intensity—whatever fits your optimization problem, as long as the unit matches the |
|
|
Maximum achievable power at the site’s grid connection point, in either direction. Becomes a hard constraint in the optimization problem, which is especially suitable for physical limitations. [3] [4] |
|
|
Maximum consumption power at the site’s grid connection point.
If |
|
|
Maximum production power at the site’s grid connection point.
If |
|
|
The site’s previously achieved achieved peak consumption. This value forms the baseline for new peak charges, since any peaks up to this level represent sunk costs. Defaults to 0 kW. |
|
|
If True (the default), several constraints are relaxed by setting default breach prices within the optimization problem, leading to the default priority:
The specific For tighter control over prices and priorities, the breach prices can also be set explicitly (the relevant fields have |
|
|
This penalty value is used to discourage the violation of the |
|
|
This penalty value is used to discourage the violation of the |
|
|
Per-kW price applied to any consumption that exceeds the site’s previously achieved peak consumption. This price reflects the cost of increasing the site’s peak further and is used by the scheduler to motivate peak shaving. It must use the same currency as the other price settings and cannot be negative. For large connections, this price is usually stated explicitly on the tariff sheets of their network operator. [6] |
|
|
The site’s previously achieved achieved peak production. This value forms the baseline for new peak charges, since any peaks up to this level represent sunk costs. Defaults to 0 kW. |
|
|
Per-kW price applied to any production that exceeds the site’s previously achieved peak production. This price reflects the cost of increasing the site’s peak further and is used by the scheduler to motivate peak shaving. It must use the same currency as the other price settings and cannot be negative. For large connections, this price is usually stated explicitly on the tariff sheets of their network operator. [6] |
|
|
This penalty value is used to discourage the violation of |
|
|
This penalty value is used to discourage the violation of |
|
|
This penalty value is used to discourage the violation of the |
|
|
This penalty value is used to discourage the violation of the |
|
|
Prior commitments. Each commitment needs a |
Note
If no (symmetric, consumption and production) site capacity is defined (also not as defaults), the scheduler will not enforce any bound on the site power. The flexible device can still have its own power limit defined in its flex-model.
Smart defaults for commodity-context grid connections
For multi-commodity scheduling problems, each entry of the top-level commodities list is itself a flex-context (a “commodity context”) describing the grid connection for that commodity.
A commodity context that leaves out some or all of its grid-connection fields (consumption-price, production-price, site-consumption-capacity, site-production-capacity and site-power-capacity) gets sensible defaults for the missing fields, rather than failing or silently leaving the grid unconstrained.
As a rule of thumb, a price given for a direction (consumption or production) implies a grid connection in that direction, with an unlimited capacity unless a capacity is also given; a capacity given for a direction (without a price) implies a zero consumption-price or production-price (respectively) in that direction; and anything not implied by a given field defaults to “no connection” (a zero capacity, as a soft constraint).
The exception is site-power-capacity given on its own, which sets a hard (symmetric) capacity limit instead.
This leads to the following defaults, depending on which fields are explicitly given:
Nothing given (e.g. just
{"commodity": "gas"}): bothsite-consumption-capacityandsite-production-capacitydefault to zero, as soft constraints (a breach is possible, but penalized).site-power-capacitystays unlimited.Only
consumption-price: Then,site-power-capacityandsite-consumption-capacitystay unlimited;site-production-capacitydefaults to zero (soft).Only
production-price: the mirror image, for production.Only
site-consumption-capacity: Then,site-power-capacitystays unlimited;consumption-pricedefaults to zero;site-production-capacity(and, transitively,production-price) default to zero.Only
site-production-capacity: the mirror image, for production.Only
site-power-capacity: Then, a hard constraint applies at that capacity, withsite-consumption-capacityandsite-production-capacityboth set equal to it, andconsumption-price/production-pricedefaulting to zero.
When several fields are given, each rule only fills in the fields not already determined by a given field, per direction (consumption/production) independently.
Giving all capacity fields is perfectly valid, too: the directional capacities then act as soft constraints, within the hard site-power-capacity limit.
As a safety net, consumption-price still defaults to zero if it remains unset after applying the rules above, since the scheduler requires a resolvable consumption price.
Note
Setting relax-constraints to False on a commodity context that ends up with a smart-defaulted 0 hard capacity can make the schedule infeasible; FlexMeasures logs a warning in that case.
The flex-models & corresponding schedulers
FlexMeasures comes with a storage scheduler and a process scheduler, which work with flex models for storages and loads, respectively.
The storage scheduler is suitable for batteries and EV chargers, and is automatically selected when scheduling an asset with one of the following asset types: "battery", "one-way_evse" and "two-way_evse".
The process scheduler is suitable for shiftable, breakable and inflexible loads, and is automatically selected for asset types "process" and "load".
We describe the respective flex models below.
These fields can be configured in the UI editor on the asset properties page or sent through the API (one of the endpoints to trigger schedule computation, or using the FlexMeasures client) or through the CLI (the command to add schedules).
Storage
For storage devices, the FlexMeasures scheduler deals with the state of charge (SoC) for an optimal outcome. You can do a lot with this ― examples for storage devices are:
batteries
EV batteries connected to charge points
hot water storage (“heat batteries”, where the SoC relates to the water temperature)
pumped hydro storage (SoC is the water level)
water basins (here, SoC is supposed to be low, as water is being pumped out)
buffers of energy-intensive chemicals that are needed in other industry processes
The flex-model for storage devices describes to the scheduler what the flexible asset’s state is,
and what constraints or preferences should be taken into account.
The full list of flex-model fields for the storage scheduler follows below. For more details on the possible formats for field values, see Variable quantities.
Field |
Example value |
Description |
|---|---|---|
|
|
Commodity on which this device acts.
Defaults to |
|
|
Name of the coupling group this device belongs to.
Devices sharing the same coupling name are constrained to have proportionally related power flows, via a hard equality constraint.
Use this to model a device that converts one commodity into another, by describing each of its commodity ports as a separate device.
For example, a combined heat and power (CHP) unit is described as a gas input device, a heat output device and an electricity output device, all sharing one coupling name.
Use together with |
|
|
Positive coupling magnitude for this device within its coupling group.
The scheduler couples the power flows of all devices in the group: each device’s power is its coupling coefficient times the group’s common flow level.
The flow direction of each device is inferred from which directional capacity is set: a device given only a |
|
|
Sensor used to record the scheduled power as seen from a consumption perspective. The sign convention is determined by the key name, and is stored on the sensor itself using the Depending on which output sensors are defined:
|
|
|
Sensor used to record the scheduled power as seen from a production perspective. The sign convention is determined by the key name, and is stored on the sensor itself using the See the |
|
|
Sensor used to record the scheduled state of charge. If |
|
|
The (estimated) state of charge at the beginning of the schedule (for storage devices, this defaults to 0). Usually added to each scheduling request. [9] |
|
|
[Deprecated field] The unit used to interpret any SoC related flex-model value that does not mention a unit itself (only applies to numeric values, so not to string values).
To avoid using this field, mention the unit in each field explicitly (for instance, |
|
|
A constant and non-negotiable lower boundary for all SoC values in the schedule.
If omitted, no lower boundary is applied.
If used, this is regarded as an unsurpassable physical limitation.
To set softer boundaries, use the |
|
|
A constant and non-negotiable upper boundary for all values in the schedule (for storage devices, this defaults to max soc-target, if that is provided).
If omitted, no upper boundary is applied.
If used, this is regarded as an unsurpassable physical limitation.
To set softer boundaries, use the |
|
|
Set points that form lower boundaries, e.g. to target a full car battery in the morning.
Soft constraints by default (see |
|
|
Set points that form upper boundaries at certain times, e.g. to target an empty heat buffer before a maintenance window.
Soft constraints by default (see |
|
|
Exact set point(s) of the storage’s state of charge that the scheduler needs to realize.
A target is two-sided, so if both a |
|
|
SoC gain per time step, e.g. from a secondary energy source. Useful if energy is inserted by an external process (in-flow). This field allows setting multiple components, either fixed or dynamic, which add up to an aggregated gain. This field represents an energy flow (for instance, in kW) rather than saying something about an (allowed) energy state (for instance, in kWh). The SoC gain is unaffected by the charging efficiency. |
|
|
SoC drain per time step, e.g. from a load or heat sink. Useful if energy is extracted by an external process or there are dissipating losses (out-flow). This field allows setting multiple components, either fixed or dynamic, which add up to an aggregated usage. This field represents an energy flow (for instance, in kW) rather than saying something about an (allowed) energy state (for instance, in kWh). The SoC drain is unaffected by the discharging efficiency. |
|
|
Below 100%, this represents roundtrip losses (of charging & discharging), usually used for batteries. Can be a percentage or a ratio in the range [0,1]. Defaults to 100% (no roundtrip loss). [9] |
|
|
One-way conversion efficiency from the commodity (e.g. electricity) to the storage’s state of charge. Can be a percentage, a ratio in the range [0,1], or a coefficient of performance (>1). Defaults to 100% (no conversion loss). |
|
|
One-way conversion efficiency from the storage’s state of charge to the commodity (e.g. electricity). Defaults to 100% (no conversion loss). |
|
|
The efficiency of keeping the storage’s state of charge at its present level, used to encode losses over time. As a result, each time step the energy is held longer leads to higher losses. This setting is crucial to some sorts of energy storage, e.g. thermal buffers. To give an example, when this setting is at 95% (or 0.95), this means a loss of 5% per time step. Defaults to 100% (no storage loss over time). Note that the storage efficiency used by the scheduler is applied over each time step equal to the scheduling resolution. For example, a storage efficiency of 95 percent per (absolute) day, for scheduling a 1-hour resolution sensor, should be passed as a storage efficiency of \(0.95^{1/24} = 0.997865\). Alternatively, to let FlexMeasures handle the conversion for you, record the storage-efficiency on a dedicated sensor (in this example, with a 24-hour event resolution). Then reference that sensor in the storage-efficiency field. |
|
|
Tie-breaking policy to apply if conditions are stable, which signals a preference to charge sooner rather than later (defaults to True). It also signals a preference to discharge later. Boolean option only. |
|
|
Tie-breaking policy to apply if conditions are stable, which signals a preference to curtail both consumption and production later, whichever is applicable (defaults to True). Boolean option only. |
|
|
Symmetric device-level power constraint. How much power can be applied to this asset in either direction.
If omitted, the scheduler infers this limit from the greatest of |
|
|
Device-level power constraint on consumption. How much power can be drawn by this asset. [12] [14] |
|
|
Device-level power constraint on production. How much power can be supplied by this asset. For PV curtailment, set this to reference your sensor containing PV power forecasts. [12] [14] |
|
|
Confine the device’s power to one of several power ranges at every time step.
Each operation mode declares a |
|
|
Reference to a group of devices whose aggregate power is constrained. The recommended form identifies the group by the |
|
|
Power (or energy) sensors representing loads that are relevant, but not flexible in the timing of their demand. For example, a sensor recording the power of a base load that is connected behind the main meter, and whose consumption falls under the same contract as the flexible device(s) being scheduled. Their power demand cannot be adjusted but still matters for finding the best schedule for other devices. The sign convention is determined by the key name: positive values denote consumption.
Sensors that explicitly record consumption as negative values ( Each entry is a sensor reference, optionally with source filters. In the flex-context this is a list of such references (site-level base load); in a flex-model entry it is a single reference, so that an inflexible device modelled as its own asset can join a |
|
|
Power (or energy) sensors representing generators that are relevant, but not flexible in the timing of their supply. For example, a sensor recording rooftop solar power that is connected behind the main meter, and whose production falls under the same contract as the flexible device(s) being scheduled. Their power supply cannot be adjusted but still matters for finding the best schedule for other devices. The sign convention is determined by the key name: positive values denote production (the FlexMeasures default).
Sensors that explicitly record production as negative values ( Each entry is a sensor reference, optionally with source filters. In the flex-context this is a list of such references (site-level base generation); in a flex-model entry it is a single reference, so that an inflexible device modelled as its own asset can join a |
Can only be set as a fixed quantity.
SoC minima and maxima are relaxed into soft constraints by default, receiving default breach prices, so the scheduler gets as close as possible to them when they cannot all be met. Setting relax-soc-constraints (or the umbrella relax-constraints) to false keeps them hard, unless breach prices are supplied explicitly.
In case this field defines partially overlapping time periods, the maximum value is selected. See Variable quantities.
In case this field defines partially overlapping time periods, the minimum value is selected. See Variable quantities.
Off-tick soc-targets, soc-minima and soc-maxima are projected to the surrounding scheduling ticks. See Projecting scheduling constraints to a fixed resolution.
A value of zero is read as a statement about the device rather than an economic limit, but only when it holds for the whole scheduling window. A capacity that is zero throughout says the device cannot flow in that direction at all (a heat pump cannot produce), and is enforced strictly, even where device capacity relaxation is in effect. A zero covering only part of the window says “not right now” (keeping an EV charger idle during a calendar car reservation, say), and remains breachable at the applicable breach price like any other limit.
For more details on the possible formats for field values, see Variable quantities.
Intermediate power constraints
In a multi-device flex-model list, a device entry may declare a group field referencing a group of devices, for example a hybrid inverter shared by a battery and PV installation, or a feeder shared by several devices. This lets you model an intermediate power constraint that sits between the individual devices and the site as a whole.
The recommended way to identify a group is by the asset that represents the shared equipment — a node in your asset tree, such as the inverter. This is the form that composes with flex-models stored on the asset tree and with multi-level hierarchies (see below), and it is what stored configurations naturally produce:
{"asset": <asset id>}: the group is identified by the flex-model entry on that asset (typically a sub-EMS/asset in the asset tree, such as the inverter in the example below). Such a group entry defines no power sensor of its own; instead, like any other asset-only entry, it may defineconsumptionand/orproductionoutput sensor references (see below) on which the group’s aggregate power gets saved.
Alternatively, a group can be identified by a power sensor. This is handy for compact, one-shot flex-models passed via the API, or when you already have an aggregate power sensor (e.g. a metered inverter feed) on which to record the group’s schedule:
{"sensor": <power sensor id>}: the group is identified by a power sensor, which itself gets its own flex-model entry (typically passed alongside the device entries).
Either way, the group reference’s target (asset or sensor) gets its own flex-model entry, defining constraints on the group’s aggregate (summed) power:
power-capacityon the group is a hard constraint (applied in both directions).consumption-capacityandproduction-capacityon the group are soft constraints, enforced with the same default breach prices used at the site level (10000 currency/kW); users cannot configure custom breach prices for groups.
The group’s scheduled aggregate power is saved as a schedule output, following the same conventions used for any device’s schedule output:
For an asset-referenced group (an asset-only entry), the aggregate power is saved via its
consumptionand/orproductionoutput sensor references: with onlyconsumptionset, the full profile is saved consumption-positive; with onlyproductionset, the full profile is saved production-positive (i.e. sign-flipped before saving); with both set, the profile is split into its non-negative part (saved toconsumption) and its non-positive part (saved, as a positive magnitude, toproduction).For a sensor-referenced group (whose flex-model entry has a
sensorfield), the aggregate power is saved directly to that sensor.
Groups can be nested (a group entry may itself reference a parent group), but cyclic references are rejected. Groups require a multi-device flex-model; they are rejected when scheduling a single sensor.
The recommended, tree-based way to configure a group is to define the whole flex-model on the asset tree in the DB, with no flex-model needed in the scheduling trigger at all: each device asset carries its own (partial) flex-model, including a group field pointing at the parent asset that represents the shared equipment, and that parent asset’s own flex-model defines the group’s constraints and output sensor(s). Triggering a schedule for the top-level site asset with an empty (or omitted) flex-model then collects the full configuration from the tree. For a hands-on walkthrough (including how to store flex-models on assets, and where the resulting schedules end up), see Toy example VI: Intermediate power constraints (groups).
The sensor-referenced form is convenient when you pass the whole flex-model in one go via the API. For example, a 2.5 kW hybrid inverter (sensor 5) shared by a battery (sensor 1) and PV installation (sensor 2), taken from issue #2092:
[
{"sensor": 1, "power-capacity": "2 kW", "group": {"sensor": 5}},
{"sensor": 2, "production-capacity": "2 kW", "consumption-capacity": "0 kW", "group": {"sensor": 5}},
{"sensor": 5, "power-capacity": "2.5 kW"}
]
Here, the battery and PV installation may each individually schedule up to 2 kW, but their combined power flowing through the shared inverter is hard-limited to 2.5 kW.
Inflexible devices in the flex-model
Inflexible (measured) devices can be modelled in the flex-model too — for example, an unschedulable base load. To do so, model the inflexible device as its own asset and give its flex-model entry a single inflexible-consumption or inflexible-production reference to the sensor recording its power (the field name sets the sign convention, and source filters may be added). Such an entry carries no schedulable-device fields; it simply declares a fixed device whose power is accounted for. Like any device entry, it may set a commodity (defaulting to electricity), and its fixed power is then netted into that commodity’s grid connection.
There are two places to declare an inflexible device, and the choice is about where it belongs rather than what it does. Listing its sensor in the flex-context’s inflexible-consumption/inflexible-production fields describes plain site base load, which is a property of the connection. Giving it its own flex-model entry describes a device that sits somewhere specific in the asset tree — under a particular inverter, feeder or commodity — which is a property of the device. Both net the same fixed power into the grid connection.
The group field is optional on such an entry. Without it, the device is simply accounted for under the grid connection (just like listing its sensor in the flex-context’s inflexible-consumption/inflexible-production fields, only declared on the asset instead). With it, the device also joins that group through the ordinary group field, exactly like a flexible member (the group’s own flex-model entry, defining its capacities, must still be present), so that its fixed load or supply additionally counts towards the group’s intermediate power constraint — for example, a base load sitting behind the same inverter or feeder as a battery.
Usually, not the whole flexibility model is needed. FlexMeasures can infer missing values in the flex model, and even get them (as default) from the sensor’s attributes.
You can add new storage schedules with the CLI command flexmeasures add schedule.
If you model devices that buffer energy (e.g. thermal energy storage systems connected to heat pumps), we can use the same flexibility parameters described above for storage devices. However, here are some tips to model a buffer correctly:
Describe the thermal energy content in kWh or MWh.
Set
soc-minimato the accumulative usage forecast.Set
charging-efficiencyto the sensor describing the COP values.Set
storage-efficiencyto a value below 100% to model (heat) loss.For a hands-on example of a heat buffer fed by multiple devices, see A flex-modeling tutorial for storage: Multiple feeds into shared storage.
If the flex model describes an infeasible problem for the storage scheduler, the failure should remain visible.
By default, soc-minima and soc-maxima are relaxed into soft constraints, so the scheduler can still return a useful schedule when these boundaries cannot be fully met.
Setting either relax-soc-constraints or relax-constraints to false in the flex-context keeps them as hard constraints.
Exact soc-targets, physical soc-min / soc-max bounds, and power-capacity (in the flex-model) and site-power-capacity (in the flex-context) remain hard constraints.
If those hard constraints make the problem infeasible, the scheduling job fails instead of producing a fallback schedule.
It is important to take note of these failures. Often, misconfigured flex models are the reason.
For a hands-on tutorial on using some of the storage flex-model fields, head over to A flex-modeling tutorial for storage: Vehicle-to-grid use case and the API documentation for triggering schedules. For further hands-on examples, see A flex-modeling tutorial for storage: Multiple feeds into shared storage (multiple devices feeding one shared storage) and A flex-modeling tutorial for storage: Multiple commodities (gas & electricity) (devices on different commodities scheduled together).
Finally, are you interested in the linear programming details behind the storage scheduler?
Then head over to Device scheduler: mixed-integer linear model!
You can also review the current flex-model for storage in the code, at flexmeasures.data.schemas.scheduling.storage.StorageFlexModelSchema.
Shiftable loads (processes)
For processes that can be shifted or interrupted, but have to happen at a constant rate (of consumption), FlexMeasures provides the ProcessScheduler.
Some examples from practice (usually industry) could be:
A centrifuge’s daily work of combing through sludge water. Depends on amount of sludge present.
Production processes with a target amount of output until the end of the current shift. The target usually comes out of production planning.
Application of coating under hot temperature, with fixed number of times it needs to happen before some deadline.
Field |
Example value |
Description |
|---|---|---|
|
|
Nominal power of the load. |
|
|
Time that the load needs to lasts. |
|
|
Objective of the scheduler, to maximize ( |
|
|
Time periods in which the load cannot be scheduled to run. |
|
|
Is the load inflexible and should it run as soon as possible? Or can the process’s start time be shifted? Or can it even be broken up into smaller segments? |
You can review the current flex-model for processes in the code, at flexmeasures.data.schemas.scheduling.process.ProcessSchedulerFlexModelSchema.
You can add new shiftable-process schedules with the CLI command flexmeasures add schedule. Make sure to use the --scheduler ProcessScheduler option to use the in-built process scheduler.
Note
Currently, the ProcessScheduler uses only the consumption-price field of the flex-context, so it ignores any site capacities and inflexible devices.