Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Command scheduling, event handling improvements #649

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/hasp_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@
#define HASP_NUM_GPIO_CONFIG 8
#endif

#ifndef HASP_USE_EVENT_DATA_SUBST
#define HASP_USE_EVENT_DATA_SUBST 0
#endif

// #ifndef HASP_USE_CUSTOM
// #define HASP_USE_CUSTOM 0
// #endif
Expand Down
117 changes: 110 additions & 7 deletions src/hasp/hasp_dispatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#endif
#endif

#include <map>

dispatch_conf_t dispatch_setings = {.teleperiod = 300};

uint16_t dispatchSecondsToNextTeleperiod = 0;
Expand All @@ -48,6 +50,8 @@ haspCommand_t commands[28];
moodlight_t moodlight = {.brightness = 255};
uint8_t saved_jsonl_page = 0;

static std::map<int, lv_task_t*> scheduled_tasks;

/* Sends the payload out on the state/subtopic
*/
void dispatch_state_subtopic(const char* subtopic, const char* payload)
Expand Down Expand Up @@ -646,25 +650,41 @@ void dispatch_screenshot(const char*, const char* filename, uint8_t source)
}

bool dispatch_json_variant(JsonVariant& json, uint8_t& savedPage, uint8_t source)
{
JsonObject dummy;
return dispatch_json_variant_with_data(json, savedPage, source, dummy);
}

bool dispatch_json_variant_with_data(JsonVariant& json, uint8_t& savedPage, uint8_t source, JsonObject& data)
{
if(json.is<JsonArray>()) { // handle json as an array of commands
LOG_DEBUG(TAG_MSGR, "Json ARRAY");
for(JsonVariant command : json.as<JsonArray>()) {
dispatch_json_variant(command, savedPage, source);
dispatch_json_variant_with_data(command, savedPage, source, data);
}

} else if(json.is<JsonObject>()) { // handle json as a jsonl
LOG_DEBUG(TAG_MSGR, "Json OBJECT");
hasp_new_object(json.as<JsonObject>(), savedPage);

} else if(json.is<std::string>()) { // handle json as a single command
LOG_DEBUG(TAG_MSGR, "Json text = %s", json.as<std::string>().c_str());
dispatch_simple_text_command(json.as<std::string>().c_str(), source);

} else if(json.is<const char*>()) { // handle json as a single command
LOG_DEBUG(TAG_MSGR, "Json text = %s", json.as<const char*>());
dispatch_simple_text_command(json.as<const char*>(), source);
std::string command = json.as<std::string>();

#if HASP_USE_EVENT_DATA_SUBST
if(command.find('%') != std::string::npos) {
// '%' found in command, run variable substitution
for(JsonPair kv : data) {
std::string find = "%" + std::string(kv.key().c_str()) + "%";
std::string replace = kv.value().as<std::string>();
size_t pos = command.find(find);
if(pos == std::string::npos) continue;
command.replace(pos, find.length(), replace);
}
}
#endif

LOG_DEBUG(TAG_MSGR, "Json text = %s", command.c_str());
dispatch_simple_text_command(command.c_str(), source);
} else if(json.isNull()) { // event handler not found
// nothing to do

Expand Down Expand Up @@ -1447,6 +1467,88 @@ void dispatch_sleep(const char*, const char*, uint8_t source)
hasp_set_wakeup_touch(false);
}

static void dispatch_schedule_runner(lv_task_t* task)
{
dispatch_text_line((const char*)task->user_data, TAG_MSGR);
}

void dispatch_schedule(const char*, const char* payload, uint8_t source)
{
// duplicate the string for modification
char* argline = strdup(payload);
// split argline into argv by whitespace; limit to 4 parts
char* argv[4];
int argn = 0;
argv[argn++] = argline;
while(*argline) {
if(*argline == ' ') {
*argline = '\0';
argv[argn++] = argline + 1;
}
argline++;
if(argn == 4) break;
}

const char* action = argv[0];
uint32_t id = atoi(argv[1]);

if(strcasecmp(action, "set") == 0) {
if(argn != 4) {
LOG_ERROR(TAG_MSGR, F("Usage: schedule set <id> <period(ms)> <cmd...>"));
goto end;
}
uint32_t period = atoi(argv[2]);
const char* command = strdup(argv[3]);

if(scheduled_tasks.find(id) != scheduled_tasks.end()) {
// update an existing task
lv_task_t* task = scheduled_tasks[id];
free(task->user_data);
task->period = period;
task->user_data = (void*)command;
} else {
// create a new task
lv_task_t* task = lv_task_create(dispatch_schedule_runner, period, LV_TASK_PRIO_MID, (void*)command);
scheduled_tasks[id] = task;
}

LOG_INFO(TAG_MSGR, F("Scheduled command ID %u, every %u ms: %s"), id, period, command);

goto end;
}

if(argn != 2) {
LOG_ERROR(TAG_MSGR, F("Usage: schedule <set/del/start/stop> <id>"));
goto end;
}
if(scheduled_tasks.find(id) == scheduled_tasks.end()) {
LOG_ERROR(TAG_MSGR, F("Task by ID %u does not exist"), id);
goto end;
}

{
lv_task_t* task = scheduled_tasks[id];
if(strcasecmp(action, "del") == 0) {
free(task->user_data);
lv_task_del(task);
scheduled_tasks.erase(id);
goto end;
}
if(strcasecmp(action, "start") == 0) {
lv_task_set_prio(task, LV_TASK_PRIO_MID);
goto end;
}
if(strcasecmp(action, "stop") == 0) {
lv_task_set_prio(task, LV_TASK_PRIO_OFF);
goto end;
}
}

end:
// release the duplicated argline
free(argv[0]);
}

void dispatch_idle_state(uint8_t state)
{
char topic[8];
Expand Down Expand Up @@ -1580,6 +1682,7 @@ void dispatchSetup()
dispatch_add_command(PSTR("moodlight"), dispatch_moodlight);
dispatch_add_command(PSTR("idle"), dispatch_idle);
dispatch_add_command(PSTR("sleep"), dispatch_sleep);
dispatch_add_command(PSTR("schedule"), dispatch_schedule);
dispatch_add_command(PSTR("statusupdate"), dispatch_statusupdate);
dispatch_add_command(PSTR("clearpage"), dispatch_clear_page);
dispatch_add_command(PSTR("clearfont"), dispatch_clear_font);
Expand Down
3 changes: 2 additions & 1 deletion src/hasp/hasp_dispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void dispatch_parse_jsonl(Stream& stream, uint8_t& saved_page_id);
void dispatch_parse_jsonl(std::istream& stream, uint8_t& saved_page_id);
#endif
bool dispatch_json_variant(JsonVariant& json, uint8_t& savedPage, uint8_t source);
bool dispatch_json_variant_with_data(JsonVariant& json, uint8_t& savedPage, uint8_t source, JsonObject& data);

void dispatch_clear_page(const char* page);
void dispatch_json_error(uint8_t tag, DeserializationError& jsonError);
Expand Down Expand Up @@ -110,4 +111,4 @@ struct haspCommand_t
void (*func)(const char*, const char*, uint8_t);
};

#endif
#endif
Loading