flexmeasures.data.models.planning.soc_projection

Projection of off-tick point-like SoC constraints onto scheduling ticks.

Module Attributes

Functions

flexmeasures.data.models.planning.soc_projection.project_off_tick_soc_at_start(soc_at_start_time: datetime, soc_at_start: Quantity | float, soc_maxima: list[dict[str, datetime | float]] | Series | Sensor | Quantity | None, soc_minima: list[dict[str, datetime | float]] | Series | Sensor | Quantity | None, schedule_start: datetime, consumption_capacity: Series, production_capacity: Series, resolution: timedelta, soc_min: Quantity | float | None, soc_max: Quantity | float | None, charging_efficiency: Series | Quantity | float | None = None, discharging_efficiency: Series | Quantity | float | None = None) tuple[list[dict[str, datetime | float]] | Series | Sensor | Quantity | None, list[dict[str, datetime | float]] | Series | Sensor | Quantity | None]

Project an off-tick starting state of charge onto the next scheduling tick.

When the starting SoC is known at a time t between the schedule start and the next scheduling tick n (e.g. because the state-of-charge field resolved to a measurement taken at t), the SoC is assumed to hold from the schedule start until t (the device is not moving its stock before then), and the SoC at n is bounded by how much the device can (dis)charge between t and n:

  • an upper bound of soc_at_start plus the energy chargeable between t and n,

  • a lower bound of soc_at_start minus the energy dischargeable between t and n.

Both bounds are clamped to the global soc-min/soc-max and merged into the given soc-maxima/soc-minima (the stricter bound wins on collisions). Known SoC times on a scheduling tick, or outside the first scheduling interval, leave the bounds unchanged.

Returns (soc_maxima, soc_minima).

flexmeasures.data.models.planning.soc_projection.project_off_tick_soc_constraints(soc_targets: list[dict[str, datetime | float]] | Series | Sensor | Quantity | None, soc_maxima: list[dict[str, datetime | float]] | Series | Sensor | Quantity | None, soc_minima: list[dict[str, datetime | float]] | Series | Sensor | Quantity | None, consumption_capacity: Series, production_capacity: Series, resolution: timedelta, soc_min: Quantity | float | None, soc_max: Quantity | float | None, charging_efficiency: Series | Quantity | float | None = None, discharging_efficiency: Series | Quantity | float | None = None) tuple[list[dict[str, datetime | float]] | Series | Sensor | Quantity | None, list[dict[str, datetime | float]] | Series | Sensor | Quantity | None, list[dict[str, datetime | float]] | Series | Sensor | Quantity | None]

Project off-tick point-like SoC constraints onto scheduling ticks.

The scheduler can only enforce constraints at its fixed scheduling resolution. Point-like soc-targets, soc-minima and soc-maxima that fall between two scheduling ticks are therefore replaced by constraints on the previous and next tick that preserve reachability using the available charge and discharge capacity between the original event time and those ticks (see SOC_PROJECTION_POLICIES).

For an off-tick event with value v at time t, between previous tick p and next tick n:

  • soc-targets become an exact target v on n, plus bounds on p that keep the target reachable at t: a lower bound of v minus the energy that can still be charged between p and t, and an upper bound of v plus the energy that can still be discharged between p and t.

  • soc-minima become lower bounds on both surrounding ticks: on p, v minus the energy that can be charged between p and t; on n, v minus the energy that can be discharged between t and n.

  • soc-maxima become upper bounds on both surrounding ticks: on p, v plus the energy that can be discharged between p and t; on n, v plus the energy that can be charged between t and n.

The reachable energy accounts for the (dis)charging efficiencies: charging at grid power P moves the stock at rate P * charging_efficiency (which can exceed 1, e.g. a heat pump’s COP), and discharging at grid power P moves the stock at rate P / discharging_efficiency.

If multiple projected bounds land on the same tick, the stricter lower or upper bound is kept. Projected bounds are clamped to the global soc-min/soc-max.

Returns (soc_targets, soc_maxima, soc_minima) with projected list-based timed events. Non-list specifications such as sensors, series, fixed quantities, or None are returned unchanged unless projected bounds need to be added to a missing list.

Classes

class flexmeasures.data.models.planning.soc_projection.SocProjectionRule(bound_type: Literal['min', 'max'], tick: Literal['previous', 'next'])

One projected bound for an off-tick point-like SoC event.

A rule only needs to state which bound lands on which surrounding scheduling tick; everything else follows from preserving reachability:

  • The capacity period runs from the tick to the event time (previous) or from the event time to the tick (next).

  • A bound is loosened by the energy the device can move through that period towards satisfying the original event: lower bounds by charging up to it (on the previous tick) or by discharging away from it (on the next tick), and upper bounds vice versa.

  • Lower bounds are loosened downwards, upper bounds upwards.

__init__(bound_type: Literal['min', 'max'], tick: Literal['previous', 'next']) None
property sign: int

Lower bounds are loosened downwards (-1), upper bounds upwards (+1).

property uses_charging: bool

Whether the bound is loosened by chargeable (rather than dischargeable) energy.