Proposal: nested Schedulers

I created a proposal for new Scheduler logic at Github:

One of the main principles of OpenEMS is, that there is one global “Cycle”, that executes “Controllers” in the order given by a “Scheduler”. See https://openems.github.io/openems.io/openems/latest/edge/architecture.html#_cycle. There are different implementations of Schedulers, like the AllAlphabetically (executing all Controllers in alphabetic order or their Component-IDs), a DailyScheduler (executing Controllers on defined hours of a day) and a WeeklyScheduler (like 7 x DailyScheduler) The execution order of Controllers is important to apply inherent prioritization. A later executed Controller can not overwrite a setting that was done by a Controller with higher priority.

The current logic is: The Cycle gets a list of all configured Schedulers (there is usually only one configured). Each Scheduler can have its individual Cycle-Time (defaults to 1 second). The CycleWorker asks every Scheduler (sorted alphabetically by the Scheduler Component-ID) for the Controllers that should be executed within a Cycle - and executes these Controllers.

This logic is ok for basic use cases, but has certain limitations:

  • It is always required to configure a Scheduler; typically AllAlphabetically, as in the Getting Started Guide
  • Configuration of more advanced Schedulers quickly becomes complicated; for example DailyScheduler requires a complex JSON-format which is hard to set right in Apache Felix Console
  • All Controllers need to be mentioned explicitely or they just do not get executed. It’s easy to forget basic Controllers like Rest-Api, Websocket-Api, DebugLog,…
  • When using multiple Schedulers it could easily happen, that Controllers get executed twice per Cycle if not explicitely excluded.

I am proposing the following new Scheduler logic:

  • The Cycle defines one global Cycle-Time and holds a list of all Schedulers (like before)
  • A new interface “Schedulable” is introduced. Controller and Scheduler implement Schedulable.
  • Each Scheduler returns two sorted lists:
    • Schedulables (Controller or Scheduler) that should be executed (“include”) in a Cycle
    • Schedulables that should NOT be executed (“exclude”) in a Cycle.
  • The CycleWorker goes through the tree of Schedulables and creates an ordered list of all Controllers that should be executed.
  • Controllers that were not explicitely included, but also not excluded, are added alphabetically to the the end of the list.

This allows:

  • In normal use-cases no Scheduler configuration is required; AllAlphabetically Scheduler becomes obsolete and new users of OpenEMS don’t need to care about Schedulers
  • Advanced Schedulers only take care of their specific tasks; no need to take care of basic Controllers like Rest-Api,…
  • Schedulers can be nested and reused; e.g. the WeeklyScheduler defines 7 DailySchedulers
  • New, simple Schedulers can be developed, like “SingleShot”, which executes a Controller (or Schedulable) at a specific time; or “CronScheduler”,…
  • Just like for Controllers, specific UI-Widgets can be designed to easily configure Schedulers via UI.

I am looking forward to your comments and suggestions.

  • What do you think?
  • Do you have use-cases that are not covered by this proposal?
  • Do you like this approach of discussing major changes here in the Community Forum and/or on Github Issues?

I feel the forum is good for discussion, GitHub is good for tying code and git-blame to specific issues.

Yes, This is a good idea. Two cases which I felt important here are;
First, The complex schedulers like daily scheduler should be configured with controllers which are to be executed, which I forget all the time.
Second, Priority of the controllers, Yes Alphabetical scheduler has priority setting for the controllers.
The new implementation of global “Cycle” which returns the list of schedulers should have priority. example, 2 controllers acting on same channel of the ESS (setActivePower).