flexmeasures icon indicating copy to clipboard operation
flexmeasures copied to clipboard

Using custom scheduling algorithms

Open nhoening opened this issue 3 years ago • 6 comments

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.

nhoening avatar Jan 29 '21 18:01 nhoening

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.

nhoening avatar Aug 23 '22 16:08 nhoening

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.

nhoening avatar Aug 23 '22 17:08 nhoening

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.

Flix6x avatar Aug 24 '22 09:08 Flix6x

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?

nhoening avatar Aug 24 '22 09:08 nhoening

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.

Flix6x avatar Aug 24 '22 11:08 Flix6x

I see, so you mean an alternative to the schedule_battery and schedule_charging_station functions called within make_schedule?

Yes.

nhoening avatar Aug 24 '22 11:08 nhoening