Добавляем поблочную загрузку сценариев

This commit is contained in:
2022-08-29 00:45:55 +03:00
parent c610f006be
commit 0f869ebf39
6 changed files with 41 additions and 24 deletions

View File

@@ -3,6 +3,9 @@
//Версия прошивки //Версия прошивки
#define FIRMWARE_VERSION 412 #define FIRMWARE_VERSION 412
//Поблочная загрузка сценариев =1 грузим блоками, =0 грузим и держим в памяти весь сценарий
#define SCENARIO_BLOCK_LOAD 1
#ifdef esp8266_4mb #ifdef esp8266_4mb
#define FIRMWARE_NAME "esp8266_4mb" #define FIRMWARE_NAME "esp8266_4mb"
#endif #endif

View File

@@ -86,8 +86,8 @@ class IoTScenario {
void clearScenarioElements(); void clearScenarioElements();
public: public:
void loadScenario(String fileName); void loadScenario(String fileName, String eventIdName);
void ExecScenario(String eventIdName); void execScenario(String eventIdName);
IoTScenario(); IoTScenario();
~IoTScenario(); ~IoTScenario();

View File

@@ -52,7 +52,9 @@ void handleEvent() {
//здесь нужно пропускать данное событие через условия сценариев //здесь нужно пропускать данное событие через условия сценариев
//и если оно есть в условии сценария и совподает //и если оно есть в условии сценария и совподает
iotScen.ExecScenario(selectToMarker(event, " ")); String tmpStr = selectToMarker(event, " ");
if (SCENARIO_BLOCK_LOAD) iotScen.loadScenario("/scenario.json", tmpStr);
else iotScen.execScenario(tmpStr);
eventBuf = deleteBeforeDelimiter(eventBuf, ","); eventBuf = deleteBeforeDelimiter(eventBuf, ",");
} }

View File

@@ -64,7 +64,8 @@ void setup() {
asyncUdpInit(); asyncUdpInit();
//загрузка сценария //загрузка сценария
iotScen.loadScenario("/scenario.json"); if (!SCENARIO_BLOCK_LOAD) iotScen.loadScenario("/scenario.json", "");
// создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке // создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке
IoTItems.push_back((IoTItem *)new externalVariable("{\"id\":\"onStart\",\"val\":1,\"int\":60}")); IoTItems.push_back((IoTItem *)new externalVariable("{\"id\":\"onStart\",\"val\":1,\"int\":60}"));
generateEvent("onStart", ""); generateEvent("onStart", "");

View File

@@ -77,7 +77,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length)
writeFileUint8tByFrames("scenario.json", payload, length, headerLenth, 256); writeFileUint8tByFrames("scenario.json", payload, length, headerLenth, 256);
clearConfigure(); clearConfigure();
configure("/config.json"); configure("/config.json");
iotScen.loadScenario("/scenario.json"); if (!SCENARIO_BLOCK_LOAD) iotScen.loadScenario("/scenario.json", "");
// создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке // создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке
IoTItems.push_back((IoTItem*)new externalVariable("{\"id\":\"onStart\",\"val\":1,\"int\":60}")); IoTItems.push_back((IoTItem*)new externalVariable("{\"id\":\"onStart\",\"val\":1,\"int\":60}"));
generateEvent("onStart", ""); generateEvent("onStart", "");

View File

@@ -747,7 +747,7 @@ ExprAST *IoTScenario::ParseIdentifierExpr(String *IDNames) {
if (CurTok != ')') { if (CurTok != ')') {
while (1) { while (1) {
ExprAST *Arg = ParseExpression(IDNames); ExprAST *Arg = ParseExpression(IDNames);
if (!Arg) return 0; if (!Arg) return nullptr;
Args.push_back(Arg); Args.push_back(Arg);
if (CurTok == ')') break; if (CurTok == ')') break;
@@ -778,7 +778,7 @@ ExprAST *IoTScenario::ParseNumberExpr() {
ExprAST *IoTScenario::ParseParenExpr() { ExprAST *IoTScenario::ParseParenExpr() {
getNextToken(); // получаем (. getNextToken(); // получаем (.
ExprAST *V = ParseExpression(nullptr); ExprAST *V = ParseExpression(nullptr);
if (!V) return 0; if (!V) return nullptr;
if (CurTok != ')') if (CurTok != ')')
return Error("expected ')'"); return Error("expected ')'");
@@ -793,7 +793,7 @@ ExprAST *IoTScenario::ParseBracketsExpr() {
if (CurTok != '}') { if (CurTok != '}') {
while (1) { while (1) {
ExprAST *Expr = ParseExpression(nullptr); ExprAST *Expr = ParseExpression(nullptr);
if (!Expr) return 0; if (!Expr) return nullptr;
bracketsList.push_back(Expr); bracketsList.push_back(Expr);
if (CurTok != ';') if (CurTok != ';')
@@ -826,14 +826,14 @@ ExprAST *IoTScenario::ParseIfExpr(String *IDNames) {
// условие. // условие.
ExprAST *Cond = ParseExpression(IDNames); ExprAST *Cond = ParseExpression(IDNames);
if (!Cond) return 0; if (!Cond) return nullptr;
if (CurTok != tok_then) if (CurTok != tok_then)
return Error("expected then"); return Error("expected then");
getNextToken(); // Получаем then getNextToken(); // Получаем then
ExprAST *Then = ParseExpression(nullptr); ExprAST *Then = ParseExpression(nullptr);
if (!Then) return 0; if (!Then) return nullptr;
// if (CurTok != tok_else) // if (CurTok != tok_else)
// return Error("expected else"); // return Error("expected else");
@@ -892,14 +892,14 @@ ExprAST *IoTScenario::ParseBinOpRHS(int ExprPrec, ExprAST *LHS, String *IDNames)
// Разобрать первичное выражение после бинарного оператора // Разобрать первичное выражение после бинарного оператора
ExprAST *RHS = ParsePrimary(IDNames); ExprAST *RHS = ParsePrimary(IDNames);
if (!RHS) return 0; if (!RHS) return nullptr;
// Если BinOp связан с RHS меньшим приоритетом, чем оператор после RHS, // Если BinOp связан с RHS меньшим приоритетом, чем оператор после RHS,
// то берём часть вместе с RHS как LHS. // то берём часть вместе с RHS как LHS.
int NextPrec = GetTokPrecedence(); int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) { if (TokPrec < NextPrec) {
RHS = ParseBinOpRHS(TokPrec + 1, RHS, IDNames); RHS = ParseBinOpRHS(TokPrec + 1, RHS, IDNames);
if (RHS == 0) return 0; if (RHS == nullptr) return nullptr;
} }
// Собираем LHS/RHS. // Собираем LHS/RHS.
@@ -912,7 +912,7 @@ ExprAST *IoTScenario::ParseBinOpRHS(int ExprPrec, ExprAST *LHS, String *IDNames)
/// ///
ExprAST *IoTScenario::ParseExpression(String *IDNames) { ExprAST *IoTScenario::ParseExpression(String *IDNames) {
ExprAST *LHS = ParsePrimary(IDNames); ExprAST *LHS = ParsePrimary(IDNames);
if (!LHS) return 0; if (!LHS) return nullptr;
return ParseBinOpRHS(0, LHS, IDNames); return ParseBinOpRHS(0, LHS, IDNames);
} }
@@ -923,31 +923,42 @@ void IoTScenario::clearScenarioElements() { // удаляем все корне
ScenarioElements.clear(); ScenarioElements.clear();
} }
void IoTScenario::loadScenario(String fileName) { // посимвольно считываем и сразу интерпретируем сценарий в дерево AST void IoTScenario::loadScenario(String fileName, String eventIdName) { // посимвольно считываем и сразу интерпретируем сценарий в дерево AST
clearScenarioElements(); // удаляем все корневые элементы перед загрузкой новых. if (!SCENARIO_BLOCK_LOAD) clearScenarioElements(); // удаляем все корневые элементы перед загрузкой новых.
LastChar = ' '; LastChar = ' ';
File myfile = seekFile(fileName); File myfile = seekFile(fileName);
if (myfile.available()) { if (myfile.available()) {
strFromFile = new String(""); strFromFile = new String("");
String strFromF = myfile.readString(); *strFromFile = myfile.readString();
Serial.println(strFromF); //Serial.println(strFromF);
jsonRead(strFromF, "scen", *strFromFile, true); //jsonRead(strFromF, "scen", *strFromFile, true);
myfile.close(); myfile.close();
// Serial.println(*strFromFile); strFromFile->replace("{\"scen\":\"", "");
//strFromFile->replace("\"}", "");
//Serial.println(*strFromFile);
if (strFromFile->length()) { if (strFromFile->length()) {
getNextToken(); getNextToken();
while (strIterator < strFromFile->length() - 1) { while (strIterator < strFromFile->length() - 1) {
// Serial.printf("-%c", LastChar); // Serial.printf("-%c", LastChar);
switch (CurTok) { switch (CurTok) {
// case tok_eof: return; // case tok_eof: break;
// case ';': getNextToken(); break; // игнорируем верхнеуровневые точки с запятой.
case tok_if: { case tok_if: {
String IDNames = ""; // накопитель встречающихся идентификаторов в условии String IDNames = ""; // накопитель встречающихся идентификаторов в условии
ScenarioElements.push_back(ParseIfExpr(&IDNames)); ExprAST *tmpAST = ParseIfExpr(&IDNames);
if (!tmpAST) break;
if (SCENARIO_BLOCK_LOAD) {
if (tmpAST->hasEventIdName(eventIdName)) {
tmpAST->exec();
Serial.println("Exec from loadIF");
}
delete tmpAST;
} else ScenarioElements.push_back(tmpAST);
break; break;
} }
default: default:
@@ -964,10 +975,10 @@ void IoTScenario::loadScenario(String fileName) { // посимвольно с
} }
} }
void IoTScenario::ExecScenario(String eventIdName) { // запускаем поочереди все корневые элементы выражений в сценарии, ожидаемо - это IFы void IoTScenario::execScenario(String eventIdName) { // запускаем поочереди все корневые элементы выражений в сценарии, ожидаемо - это IFы
// eventIdName - ID элемента для которого выполняем сценарий, т.е. игнорируем любые проверки, если нет такого ID в условиях // eventIdName - ID элемента для которого выполняем сценарий, т.е. игнорируем любые проверки, если нет такого ID в условиях
isIotScenException = false; isIotScenException = false;
// Serial.printf("Count root elements in scenario: %d\n", ScenarioElements.size()); //Serial.printf("Count root elements in scenario: %d\n", ScenarioElements.size());
for (unsigned int i = 0; i < ScenarioElements.size(); i++) { for (unsigned int i = 0; i < ScenarioElements.size(); i++) {
if (ScenarioElements[i] && ScenarioElements[i]->hasEventIdName(eventIdName)) ScenarioElements[i]->exec(); if (ScenarioElements[i] && ScenarioElements[i]->hasEventIdName(eventIdName)) ScenarioElements[i]->exec();
// else Serial.printf("Call from ExecScenario: Skip ifexec because %s not found\n", eventIdName.c_str()); // else Serial.printf("Call from ExecScenario: Skip ifexec because %s not found\n", eventIdName.c_str());