Skip to content

Instantly share code, notes, and snippets.

@FlavioZanoni
Created April 25, 2026 21:54
Show Gist options
  • Select an option

  • Save FlavioZanoni/5ac080835b7c54a6f1d1c192cc6419ab to your computer and use it in GitHub Desktop.

Select an option

Save FlavioZanoni/5ac080835b7c54a6f1d1c192cc6419ab to your computer and use it in GitHub Desktop.

Cron-based scheduling for measurements and actuator actions


Overview

Add a SCHEDULE key to config.ini (loaded from SPIFFS) that allows any device (sensor or actuator) to define time-based behavior using cron syntax. Parsing is handled by espressif/supertinycron, an official ESP component. A FreeRTOS task is created per scheduled entry to evaluate and trigger the appropriate action at the specified time.


Motivation

Currently, measurements and actuator states are triggered externally or on fixed intervals. Many real-world deployments need time-aware control - turning a device on at a specific hour, sampling a sensor daily at dawn, or stepping through states throughout the day. This feature makes Hermes suitable for those use cases without any application-specific firmware changes.


Config format

The key is added per-device section in config.ini. The value format differs slightly between actuators and sensors.

Actuator

One or more cron_expression:state pairs, comma-separated. State can be any valid actuator value (binary or otherwise).

SCHEDULE="* 5 * * *:1,* 6 * * *:0"

Turns the device on at 05:00 and off at 06:00 every day.

SCHEDULE="* 5 * * *:1000,15 5 * * *:0"

Sets the actuator to 1000hz at 05:00, then 0hz at 05:15.

Sensor

Standard cron expression only — no state suffix. Triggers a measurement at the scheduled time.

SCHEDULE="* 5 * * *"

Takes a measurement every day at 05:00.


Implementation notes

Concern Detail
Parser Use supertinycron via the ESP Component Registry. Add it to idf_component.yml as espressif/supertinycron: "2.0.0~1".
Task per entry Each cron:state pair spawns a FreeRTOS task that sleeps until the next trigger using vTaskDelayUntil() or equivalent.
Time source Depends on SNTP being initialized before schedule tasks are created. Task creation must be deferred until time is synced.
Parsing Split the config value by , first, then split each entry by : to separate cron string from state. Sensor entries have no :.
State type State value should be passed through the existing actuator state handler — no special casing needed.

Acceptance criteria

  • Actuator devices with SCHEDULE apply the correct state at each scheduled time
  • Sensor devices with SCHEDULE trigger a measurement at each scheduled time
  • Multiple entries in the same key are all evaluated independently
  • Invalid cron expressions are logged and skipped without crashing

supertinycron is an official Espressif component — add it via idf_component.yml.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment