HASwitchPlate / openHASP

HomeAutomation Switchplate based on lvgl for ESP32
https://www.openhasp.com
MIT License
695 stars 179 forks source link

Command scheduling, event handling improvements #649

Open kuba2k2 opened 7 months ago

kuba2k2 commented 7 months ago

This is the second part of my PR (#631), which was previously reverted to remove changes unrelated to PC port.

This PR adds the following features:


  1. Command scheduling - schedule command, which allows to run another command at a set interval. Any supported command can be executed. It has the following syntax:
    • schedule set <id> <period(ms) <cmd...> - add/update a scheduled task
      • id is a user-chosen integer identifier of the task
      • period is the interval in milliseconds
      • cmd is the command to run; it can consist of multiple space-separated words
    • schedule del <id> - remove a previously scheduled task
    • schedule start <id> - start (enable) a previously scheduled task (enabled by default)
    • schedule stop <id> - stop (disable) a previously scheduled task, without removing it

  1. Event variable substitution (I couldn't find a better name) - replace %var% tags in commands of objects' "action" field with a value from the event JSON. For example, this jsonl:
    {"page":2,"id":105,"obj":"label","text":"Brightness"}
    {"page":2,"id":106,"obj":"slider","action":{"changed":"p2b105.text %val%"}}

    will update the label's text whenever the slider emits a changed event. Any supported command can be executed, and any value from the JSON event can be used in substitution.

NOTE: That feature is disabled by default on non-PC builds, not to impact performance/memory usage on ESP32/Arduino builds. In particular, it requires deserialization of the JSON event prior to publishing, as well as running std::string::replace() a few times. It can be enabled using HASP_USE_EVENT_DATA_SUBST=1.


  1. Setting "action" on all types of controls - previously, only a few controls allowed to run commands on events (script_event_handler()). Now, all controls call event_send_object_data() only, which then calls script_event_handler().

If there is an "action" tag on the object, the command is executed and MQTT message is not published.

An example can be seen above (with the slider).


  1. Publishing MQTT messages along with event commands - if the "action" tag of an object has an additional property "pub": true, the action command is ran AND a message is published to MQTT.

This property defaults to false, which matches the behavior from previous versions.

Example:

{"page":2,"id":106,"obj":"slider","action":{"changed":"p2b105.text %val%","pub":true}}

This slider's events will be published to MQTT, additionally the changed event will run a command.


I have one more "feature" that was left out of #631, that is setting LVGL max framerate. If you want, I can add it to this PR, otherwise I will probably create another one.

dgomes commented 7 months ago

@kuba2k2 it would be best if each of these point (1..4) could be separate PR's :)

kuba2k2 commented 7 months ago

These features are directly related to each other. I think it doesn't really make sense to split it, after all this PR is only 3 commits. You can review these commits separately and it will (more or less) match these 4 points.

kuba2k2 commented 6 months ago

Hi, any news about this? :slightly_smiling_face: Anything that needs to be fixed before merging?

fvanroie commented 6 months ago

My only note is that HASP_USE_EVENT_DATA_SUBST is for PC only, so there will be a difference according to platform. It seems substitution is only implemented for single textline commands, but for a consistent approach should also account for json, jsonl payloads etc. But since it's only enabled on PX, that shouldn't impact many users.

I think you previously mentioned that you didn't test on ESP32, which is why I'm a bit apprehensive when general dispatch or event functions are refactored.

kuba2k2 commented 6 months ago

Yes, the substitution may not apply to all commands. It should apply to everything that is executed as a text command. Since it is only useful in event actions (because otherwise data will be empty anyway, e.g. on MQTT command) it should apply to all commands executed this way.

I do not have an ESP32 platform with a compatible LCD, that's why I can't test it. I can only say that I was very careful to keep the existing behavior of the code, not to impact other users.