mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 14:12:16 +03:00
Читаем сценарий из файла
This commit is contained in:
0
data_svelte/scenario.txt
Normal file
0
data_svelte/scenario.txt
Normal file
@@ -3,9 +3,6 @@
|
|||||||
//Версия прошивки
|
//Версия прошивки
|
||||||
#define FIRMWARE_VERSION 413
|
#define FIRMWARE_VERSION 413
|
||||||
|
|
||||||
//Поблочная загрузка сценариев =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
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class IoTScenario {
|
|||||||
|
|
||||||
String IdentifierStr; // Заполняется, если tok_identifier
|
String IdentifierStr; // Заполняется, если tok_identifier
|
||||||
float NumVal; // Заполняется, если tok_number
|
float NumVal; // Заполняется, если tok_number
|
||||||
char LastChar = ' ';
|
int LastChar;
|
||||||
|
|
||||||
/// gettok - Возвращает следующий токен из стандартного потока ввода.
|
/// gettok - Возвращает следующий токен из стандартного потока ввода.
|
||||||
int gettok();
|
int gettok();
|
||||||
@@ -32,6 +32,7 @@ class IoTScenario {
|
|||||||
/// лексического анализатора и обновляет CurTok.
|
/// лексического анализатора и обновляет CurTok.
|
||||||
int CurTok;
|
int CurTok;
|
||||||
int getNextToken();
|
int getNextToken();
|
||||||
|
String IDNames; // накопитель встречающихся идентификаторов в условии
|
||||||
|
|
||||||
/// BinopPrecedence - Содержит приоритеты для бинарных операторов
|
/// BinopPrecedence - Содержит приоритеты для бинарных операторов
|
||||||
std::map<signed char, int> BinopPrecedence;
|
std::map<signed char, int> BinopPrecedence;
|
||||||
@@ -77,17 +78,12 @@ class IoTScenario {
|
|||||||
///
|
///
|
||||||
ExprAST *ParseExpression(String *IDNames);
|
ExprAST *ParseExpression(String *IDNames);
|
||||||
|
|
||||||
std::vector<ExprAST *> ScenarioElements; // корневые элементы дерава
|
int getLastChar();
|
||||||
|
fs::File file;
|
||||||
String strFromFile;
|
|
||||||
char getLastChar();
|
|
||||||
int strIterator = 0;
|
|
||||||
|
|
||||||
void clearScenarioElements();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void loadScenario(String fileName, String eventIdName);
|
void loadScenario(String fileName);
|
||||||
void execScenario(String eventIdName);
|
void exec(String eventIdName);
|
||||||
|
|
||||||
IoTScenario();
|
IoTScenario();
|
||||||
~IoTScenario();
|
~IoTScenario();
|
||||||
|
|||||||
@@ -52,9 +52,7 @@ void handleEvent() {
|
|||||||
|
|
||||||
//здесь нужно пропускать данное событие через условия сценариев
|
//здесь нужно пропускать данное событие через условия сценариев
|
||||||
//и если оно есть в условии сценария и совподает
|
//и если оно есть в условии сценария и совподает
|
||||||
String tmpStr = selectToMarker(event, " ");
|
iotScen.exec(selectToMarker(event, " "));
|
||||||
if (SCENARIO_BLOCK_LOAD) iotScen.loadScenario("/scenario.json", tmpStr);
|
|
||||||
else iotScen.execScenario(tmpStr);
|
|
||||||
|
|
||||||
eventBuf = deleteBeforeDelimiter(eventBuf, ",");
|
eventBuf = deleteBeforeDelimiter(eventBuf, ",");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,10 +62,10 @@ void setup() {
|
|||||||
|
|
||||||
//запуск работы udp
|
//запуск работы udp
|
||||||
asyncUdpInit();
|
asyncUdpInit();
|
||||||
|
|
||||||
//загрузка сценария
|
|
||||||
if (!SCENARIO_BLOCK_LOAD) iotScen.loadScenario("/scenario.json", "");
|
|
||||||
|
|
||||||
|
//подготавливаем сценарии
|
||||||
|
iotScen.loadScenario("/scenario.txt");
|
||||||
|
|
||||||
// создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке
|
// создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке
|
||||||
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", "");
|
||||||
|
|||||||
@@ -75,9 +75,24 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t* payload, size_t length)
|
|||||||
}
|
}
|
||||||
if (headerStr == "/oiranecs|") {
|
if (headerStr == "/oiranecs|") {
|
||||||
writeFileUint8tByFrames("scenario.json", payload, length, headerLenth, 256);
|
writeFileUint8tByFrames("scenario.json", payload, length, headerLenth, 256);
|
||||||
|
|
||||||
|
String strFromFile;
|
||||||
|
File myfile = seekFile("/scenario.json");
|
||||||
|
if (myfile.available()) {
|
||||||
|
strFromFile = myfile.readString();
|
||||||
|
|
||||||
|
strFromFile.replace("{\"scen\":\"", "");
|
||||||
|
strFromFile.replace("\\n", "\n");
|
||||||
|
strFromFile.replace("\\\"", "\"");
|
||||||
|
strFromFile.remove(strFromFile.length() - 2, 2);
|
||||||
|
}
|
||||||
|
myfile.close();
|
||||||
|
|
||||||
|
writeFile("/scenario.txt", strFromFile);
|
||||||
|
|
||||||
clearConfigure();
|
clearConfigure();
|
||||||
configure("/config.json");
|
configure("/config.json");
|
||||||
if (!SCENARIO_BLOCK_LOAD) iotScen.loadScenario("/scenario.json", "");
|
iotScen.loadScenario("/scenario.txt");
|
||||||
// создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке
|
// создаем событие завершения конфигурирования для возможности выполнения блока кода при загрузке
|
||||||
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", "");
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#include <fstream>
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
#include "classes/IoTItem.h"
|
#include "classes/IoTItem.h"
|
||||||
@@ -7,6 +5,7 @@
|
|||||||
#include "utils/FileUtils.h"
|
#include "utils/FileUtils.h"
|
||||||
#include "NTP.h"
|
#include "NTP.h"
|
||||||
|
|
||||||
|
|
||||||
bool isIotScenException; // признак исключения и попытки прекратить выполнение сценария заранее
|
bool isIotScenException; // признак исключения и попытки прекратить выполнение сценария заранее
|
||||||
|
|
||||||
// Лексический анализатор возвращает токены [0-255], если это неизвестны,
|
// Лексический анализатор возвращает токены [0-255], если это неизвестны,
|
||||||
@@ -586,11 +585,9 @@ class BracketsExprAST : public ExprAST {
|
|||||||
// Lexer (Лексический анализатор)
|
// Lexer (Лексический анализатор)
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
char IoTScenario::getLastChar() {
|
int IoTScenario::getLastChar() {
|
||||||
if (strIterator == strFromFile.length()) return 0;
|
if (file) return file.read();
|
||||||
char tmpCh = strFromFile.charAt(strIterator);
|
else return EOF;
|
||||||
strIterator++;
|
|
||||||
return tmpCh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// gettok - Возвращает следующий токен из стандартного потока ввода.
|
/// gettok - Возвращает следующий токен из стандартного потока ввода.
|
||||||
@@ -600,9 +597,9 @@ int IoTScenario::gettok() {
|
|||||||
LastChar = getLastChar();
|
LastChar = getLastChar();
|
||||||
|
|
||||||
if (isalpha(LastChar) || LastChar == '_') { // идентификатор: [a-zA-Z][a-zA-Z0-9]*
|
if (isalpha(LastChar) || LastChar == '_') { // идентификатор: [a-zA-Z][a-zA-Z0-9]*
|
||||||
IdentifierStr = LastChar;
|
IdentifierStr = (char)LastChar;
|
||||||
while (isalnum((LastChar = getLastChar())) || LastChar == '_') {
|
while (isalnum((LastChar = getLastChar())) || LastChar == '_') {
|
||||||
IdentifierStr += LastChar;
|
IdentifierStr += (char)LastChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serial.printf("%s ", IdentifierStr.c_str());
|
// Serial.printf("%s ", IdentifierStr.c_str());
|
||||||
@@ -616,7 +613,7 @@ int IoTScenario::gettok() {
|
|||||||
if (isdigit(LastChar)) { // Число: [0-9.]+
|
if (isdigit(LastChar)) { // Число: [0-9.]+
|
||||||
String NumStr;
|
String NumStr;
|
||||||
do {
|
do {
|
||||||
NumStr += LastChar;
|
NumStr += (char)LastChar;
|
||||||
LastChar = getLastChar();
|
LastChar = getLastChar();
|
||||||
} while (isdigit(LastChar) || LastChar == '.');
|
} while (isdigit(LastChar) || LastChar == '.');
|
||||||
|
|
||||||
@@ -627,7 +624,7 @@ int IoTScenario::gettok() {
|
|||||||
if (LastChar == '#') {
|
if (LastChar == '#') {
|
||||||
// Комментарий до конца строки
|
// Комментарий до конца строки
|
||||||
do LastChar = getLastChar();
|
do LastChar = getLastChar();
|
||||||
while (LastChar != 0 && LastChar != '\n' && LastChar != '\r');
|
while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
|
||||||
|
|
||||||
if (LastChar != EOF)
|
if (LastChar != EOF)
|
||||||
return gettok();
|
return gettok();
|
||||||
@@ -636,8 +633,8 @@ int IoTScenario::gettok() {
|
|||||||
if (LastChar == '"') { // "строка"
|
if (LastChar == '"') { // "строка"
|
||||||
IdentifierStr = "";
|
IdentifierStr = "";
|
||||||
LastChar = getLastChar();
|
LastChar = getLastChar();
|
||||||
while (LastChar != '"' && LastChar != 0) {
|
while (LastChar != '"' && LastChar != EOF) {
|
||||||
IdentifierStr += LastChar;
|
IdentifierStr += (char)LastChar;
|
||||||
LastChar = getLastChar();
|
LastChar = getLastChar();
|
||||||
}
|
}
|
||||||
LastChar = getLastChar();
|
LastChar = getLastChar();
|
||||||
@@ -646,8 +643,8 @@ int IoTScenario::gettok() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Проверка конца файла.
|
// Проверка конца файла.
|
||||||
// if (LastChar == EOF)
|
if (LastChar == EOF)
|
||||||
// return tok_eof;
|
return tok_eof;
|
||||||
|
|
||||||
if (LastChar == '=') {
|
if (LastChar == '=') {
|
||||||
LastChar = getLastChar();
|
LastChar = getLastChar();
|
||||||
@@ -684,7 +681,7 @@ int IoTScenario::gettok() {
|
|||||||
} else
|
} else
|
||||||
return '>';
|
return '>';
|
||||||
}
|
}
|
||||||
|
|
||||||
// В противном случае просто возвращаем символ как значение ASCII
|
// В противном случае просто возвращаем символ как значение ASCII
|
||||||
int ThisChar = LastChar;
|
int ThisChar = LastChar;
|
||||||
LastChar = getLastChar();
|
LastChar = getLastChar();
|
||||||
@@ -919,78 +916,37 @@ ExprAST *IoTScenario::ParseExpression(String *IDNames) {
|
|||||||
return ParseBinOpRHS(0, LHS, IDNames);
|
return ParseBinOpRHS(0, LHS, IDNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IoTScenario::clearScenarioElements() { // удаляем все корневые элементы дерева AST
|
|
||||||
for (unsigned int i = 0; i < ScenarioElements.size(); i++) {
|
void IoTScenario::loadScenario(String fileName) { // подготавливаем контекст для чтения и интерпретации файла
|
||||||
if (ScenarioElements[i]) delete ScenarioElements[i];
|
if (file) file.close();
|
||||||
}
|
file = FileFS.open(fileName, "r");
|
||||||
ScenarioElements.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IoTScenario::loadScenario(String fileName, String eventIdName) { // посимвольно считываем и сразу интерпретируем сценарий в дерево AST
|
void IoTScenario::exec(String eventIdName) { // посимвольно считываем и сразу интерпретируем сценарий в дерево AST
|
||||||
if (!SCENARIO_BLOCK_LOAD) clearScenarioElements(); // удаляем все корневые элементы перед загрузкой новых.
|
if (!file) {
|
||||||
LastChar = ' ';
|
|
||||||
|
|
||||||
File myfile = seekFile(fileName);
|
|
||||||
if (myfile.available()) {
|
|
||||||
//strFromFile = new String("");
|
|
||||||
|
|
||||||
strFromFile = myfile.readString();
|
|
||||||
//Serial.println(strFromF);
|
|
||||||
//jsonRead(strFromF, "scen", *strFromFile, true);
|
|
||||||
myfile.close();
|
|
||||||
|
|
||||||
strFromFile.replace("{\"scen\":\"", "");
|
|
||||||
strFromFile.replace("\\n\"}", "");
|
|
||||||
strFromFile.replace("\\n", "\n");
|
|
||||||
strFromFile.replace("\\\"", "\"");
|
|
||||||
//Serial.println(strFromFile);
|
|
||||||
|
|
||||||
if (strFromFile.length()) {
|
|
||||||
|
|
||||||
while (strIterator < strFromFile.length()) {
|
|
||||||
// Serial.printf("-%c", LastChar);
|
|
||||||
getNextToken();
|
|
||||||
switch (CurTok) {
|
|
||||||
// case tok_eof: break;
|
|
||||||
case tok_if: {
|
|
||||||
String 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//delete strFromFile;
|
|
||||||
strIterator = 0;
|
|
||||||
} else {
|
|
||||||
Error("Open file scenario error");
|
Error("Open file scenario error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LastChar = 0;
|
||||||
|
CurTok = 0;
|
||||||
|
file.seek(0);
|
||||||
|
|
||||||
|
while ((getNextToken()) != EOF) {
|
||||||
|
switch (CurTok) {
|
||||||
|
case tok_if: {
|
||||||
|
IDNames = ""; // сбрасываем накопитель встречающихся идентификаторов в условии
|
||||||
|
ExprAST *tmpAST = ParseIfExpr(&IDNames);
|
||||||
|
if (!tmpAST) break;
|
||||||
|
|
||||||
|
if (tmpAST->hasEventIdName(eventIdName)) {
|
||||||
|
tmpAST->exec();
|
||||||
|
}
|
||||||
|
delete tmpAST;
|
||||||
|
break;}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IoTScenario::execScenario(String eventIdName) { // запускаем поочереди все корневые элементы выражений в сценарии, ожидаемо - это IFы
|
|
||||||
// eventIdName - ID элемента для которого выполняем сценарий, т.е. игнорируем любые проверки, если нет такого ID в условиях
|
|
||||||
isIotScenException = false;
|
|
||||||
//Serial.printf("Count root elements in scenario: %d\n", ScenarioElements.size());
|
|
||||||
for (unsigned int i = 0; i < ScenarioElements.size(); i++) {
|
|
||||||
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());
|
|
||||||
if (isIotScenException) return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IoTScenario::IoTScenario() {
|
IoTScenario::IoTScenario() {
|
||||||
// Задаём стандартные бинарные операторы.
|
// Задаём стандартные бинарные операторы.
|
||||||
@@ -1010,4 +966,6 @@ IoTScenario::IoTScenario() {
|
|||||||
BinopPrecedence['*'] = 28; // highest.
|
BinopPrecedence['*'] = 28; // highest.
|
||||||
}
|
}
|
||||||
|
|
||||||
IoTScenario::~IoTScenario() {}
|
IoTScenario::~IoTScenario() {
|
||||||
|
if (file) file.close();
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user