flexmeasures
flexmeasures copied to clipboard
Using custom scheduling algorithms
We deliver some scheduling algorithms out-of-the-box, with the core FlexMeasures code. Currently, this includes batteries and EV charging stations.
But certainly some algorithms will be more elaborate, more specific or private.
We need an interface to connect algorithms (as a file) to a FlexMeasures instance, so that FlexMeasures picks it up. This should happen from within a plugin.
Below is the current signature of create_scheduling_job
: The API endpoint /sensor/<id>/schedules/trigger
calls it, and it collects everything relevant.
def create_scheduling_job(
sensor_id: int,
start_of_schedule: datetime,
end_of_schedule: datetime,
belief_time: datetime,
resolution: timedelta = DEFAULT_RESOLUTION,
soc_at_start: Optional[float] = None,
soc_targets: Optional[pd.Series] = None,
soc_min: Optional[float] = None,
soc_max: Optional[float] = None,
roundtrip_efficiency: Optional[float] = None,
consumption_price_sensor: Optional[Sensor] = None,
production_price_sensor: Optional[Sensor] = None,
inflexible_device_sensors: Optional[List[Sensor]] = None,
job_id: Optional[str] = None,
enqueue: bool = True,
) -> Job:
And here are the first few lines:
job = Job.create(
make_schedule,
kwargs=dict( ... )
That is basically what it does. This job gets enqueued.
The function make_schedule
mainly decides which of our internal schedulers should be used. Maybe this is where a plugin could set a path to a python script (or later a function store), so at this point their scheduling function is selected.
The SOC parameters could be in the way, if something else than batteries are involved. E.g. a heat pump. This requires a re-design of the endpoint anyways, and is not a blocker for this issue.
Just for scoping this issue, I started thinking about this from an extreme perspective: what if a plugin could register a function with completely custom parameters, and FlexMeasures would read the function signature and dynamically create API fields for known types (such as datetime and Sensor, which would become AwareDateTimeField
and SensorIdField
, respectively). The trigger API call sets up a job to execute the function and returns a UUID (just like our scheduling trigger endpoint does currently). And the schedule retrieving API call accepts a UUID and returns the function's return value (which is stored as the job's results).
Basically, that would provide a way for plugins to set up an API service for executing a custom algorithm, without the necessity to use the predescribed API fields for our scheduling trigger API endpoint. However, while it seems like a very flexible solution for developers, it would not standardize the use of scheduling algorithms from the perspective of users. I prefer a trade-off between both perspectives.
Taking a step away from that extreme perspective, I like your suggestion to use our current API endpoint fields, and to let a plugin register alternative functions to make_schedule
. We could also let the API user decide which scheduler to use (with a new optional field), and list available schedulers under a new API endpoint.
Wow, crazy ideas. Let's not provide API endpoints we don't even know about, supporting that looks like it's going to be too hard.
Glad you like my approach :)
I didn't mean to let them choose alternative functions to make_schedule
, but to let make_schedule
choose another implementation (here, from the author's plugin).
The idea to choose the scheduling implementation via the API we could do later. But I want to think about the real need for that. Which situations might require people using sometimes one implementation, then another?
I didn't mean to let them choose alternative functions to make_schedule, but to let make_schedule choose another implementation (here, from the author's plugin).
I see, so you mean an alternative to the schedule_battery
and schedule_charging_station
functions called within make_schedule
?
Which situations might require people using sometimes one implementation, then another?
From the top of my head:
- One user might want one scheduler, while another user might want a different scheduler.
- One user might want to try out different schedulers.
- Schedulers might be versioned, and users might want to decide when to upgrade.
I see, so you mean an alternative to the schedule_battery and schedule_charging_station functions called within make_schedule?
Yes.