mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
schedulder enhancement url json #1806
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "emsesp.h"
|
#include "emsesp.h"
|
||||||
#include "WebSchedulerService.h"
|
#include "WebSchedulerService.h"
|
||||||
|
#include <HTTPClient.h>
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
@@ -330,6 +331,33 @@ bool WebSchedulerService::has_commands() {
|
|||||||
|
|
||||||
// execute scheduled command
|
// execute scheduled command
|
||||||
bool WebSchedulerService::command(const char * name, const char * cmd, const char * data) {
|
bool WebSchedulerService::command(const char * name, const char * cmd, const char * data) {
|
||||||
|
// check http commands. e.g.
|
||||||
|
// tasmota(get): http://<tasmotsIP>/cm?cmnd=power%20ON
|
||||||
|
// shelly(get): http://<shellyIP>/relais/0?turn=on
|
||||||
|
const char * c = strchr(cmd, '{');
|
||||||
|
if (c) { // parse json
|
||||||
|
JsonDocument doc;
|
||||||
|
int httpResult = 0;
|
||||||
|
if (DeserializationError::Ok == deserializeJson(doc, c)) {
|
||||||
|
HTTPClient http;
|
||||||
|
String url = doc["url"];
|
||||||
|
if (http.begin(url)) {
|
||||||
|
for (JsonPair p : doc["header"].as<JsonObject>()) {
|
||||||
|
http.addHeader(p.key().c_str(), p.value().as<String>().c_str());
|
||||||
|
}
|
||||||
|
String value = doc["value"] | "";
|
||||||
|
if (value.length()) {
|
||||||
|
httpResult = http.POST(value);
|
||||||
|
} else if (data && data[0] != '\0') { // post
|
||||||
|
httpResult = http.POST(String(data));
|
||||||
|
} else {
|
||||||
|
httpResult = http.GET();
|
||||||
|
}
|
||||||
|
http.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return httpResult > 0;
|
||||||
|
}
|
||||||
JsonDocument doc_input;
|
JsonDocument doc_input;
|
||||||
JsonObject input = doc_input.to<JsonObject>();
|
JsonObject input = doc_input.to<JsonObject>();
|
||||||
if (strlen(data)) { // empty data queries a value
|
if (strlen(data)) { // empty data queries a value
|
||||||
@@ -390,12 +418,12 @@ void WebSchedulerService::condition() {
|
|||||||
#ifdef EMESESP_DEBUG
|
#ifdef EMESESP_DEBUG
|
||||||
// emsesp::EMSESP::logger().debug("condition match: %s", match.c_str());
|
// emsesp::EMSESP::logger().debug("condition match: %s", match.c_str());
|
||||||
#endif
|
#endif
|
||||||
if (!match.empty() && match[0] == '1') {
|
if (match.length() == 1 && match[0] == '1' && scheduleItem.retry_cnt == 0xFF) {
|
||||||
if (scheduleItem.retry_cnt == 0xFF) { // default unswitched
|
scheduleItem.retry_cnt = command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str()) ? 1 : 0xFF;
|
||||||
scheduleItem.retry_cnt = command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str()) ? 1 : 0xFF;
|
} else if (match.length() == 1 && match[0] == '0' && scheduleItem.retry_cnt == 1) {
|
||||||
}
|
|
||||||
} else if (scheduleItem.retry_cnt == 1) {
|
|
||||||
scheduleItem.retry_cnt = 0xFF;
|
scheduleItem.retry_cnt = 0xFF;
|
||||||
|
} else if (match.length() != 1) { // the match is not boolean
|
||||||
|
emsesp::EMSESP::logger().debug("condition result: %s", match.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,22 @@ std::deque<Token> exprToTokens(const std::string & expr) {
|
|||||||
for (const auto * p = expr.c_str(); *p; ++p) {
|
for (const auto * p = expr.c_str(); *p; ++p) {
|
||||||
if (isblank(*p)) {
|
if (isblank(*p)) {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
} else if (*p == '{') { // json is stored as string including {}
|
||||||
|
const auto * b = p;
|
||||||
|
++p;
|
||||||
|
uint8_t i = 1;
|
||||||
|
while (*p && i > 0) {
|
||||||
|
i += (*p == '{') ? 1 : (*p == '}') ? -1 : 0;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
if (*p) {
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
const auto s = std::string(b, p);
|
||||||
|
tokens.push_back(Token{Token::Type::String, s, -3});
|
||||||
|
if (*p == '\0') {
|
||||||
|
--p;
|
||||||
|
}
|
||||||
} else if (*p >= 'a' && *p <= 'z') {
|
} else if (*p >= 'a' && *p <= 'z') {
|
||||||
const auto * b = p;
|
const auto * b = p;
|
||||||
while ((*p >= 'a' && *p <= 'z') || (*p == '_')) {
|
while ((*p >= 'a' && *p <= 'z') || (*p == '_')) {
|
||||||
@@ -579,7 +595,52 @@ std::string calculate(const std::string & expr) {
|
|||||||
|
|
||||||
// check for multiple instances of <cond> ? <expr1> : <expr2>
|
// check for multiple instances of <cond> ? <expr1> : <expr2>
|
||||||
std::string compute(const std::string & expr) {
|
std::string compute(const std::string & expr) {
|
||||||
auto expr_new = expr;
|
auto expr_new = emsesp::Helpers::toLower(expr);
|
||||||
|
|
||||||
|
// search json with url:
|
||||||
|
auto f = expr_new.find_first_of("{");
|
||||||
|
while (f != std::string::npos) {
|
||||||
|
auto e = f + 1;
|
||||||
|
for (uint8_t i = 1; i > 0; e++) {
|
||||||
|
if (e >= expr_new.length()) {
|
||||||
|
return "";
|
||||||
|
} else if (expr_new[e] == '}') {
|
||||||
|
i--;
|
||||||
|
} else if (expr_new[e] == '{') {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string cmd = expr_new.substr(f, e - f).c_str();
|
||||||
|
JsonDocument doc;
|
||||||
|
if (DeserializationError::Ok == deserializeJson(doc, cmd)) {
|
||||||
|
HTTPClient http;
|
||||||
|
String url = doc["url"];
|
||||||
|
if (http.begin(url)) {
|
||||||
|
int httpResult = 0;
|
||||||
|
for (JsonPair p : doc["header"].as<JsonObject>()) {
|
||||||
|
http.addHeader(p.key().c_str(), p.value().as<std::string>().c_str());
|
||||||
|
}
|
||||||
|
String data = doc["value"] | "";
|
||||||
|
if (data.length()) {
|
||||||
|
httpResult = http.POST(data);
|
||||||
|
} else {
|
||||||
|
httpResult = http.GET();
|
||||||
|
}
|
||||||
|
if (httpResult > 0) {
|
||||||
|
std::string result = emsesp::Helpers::toLower(http.getString().c_str());
|
||||||
|
String key = doc["key"] | "";
|
||||||
|
doc.clear();
|
||||||
|
if (key.length() && DeserializationError::Ok == deserializeJson(doc, result)) {
|
||||||
|
result = doc[key.c_str()].as<std::string>();
|
||||||
|
}
|
||||||
|
expr_new.replace(f, e - f, result.c_str());
|
||||||
|
}
|
||||||
|
http.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f = expr_new.find_first_of("{", e);
|
||||||
|
}
|
||||||
|
|
||||||
// positions: q-questionmark, c-colon
|
// positions: q-questionmark, c-colon
|
||||||
auto q = expr_new.find_first_of("?");
|
auto q = expr_new.find_first_of("?");
|
||||||
while (q != std::string::npos) {
|
while (q != std::string::npos) {
|
||||||
|
|||||||
Reference in New Issue
Block a user