Merge pull request #166 from biveraxe/ver4dev

Делаем системные вызовы в сценариях
This commit is contained in:
2022-08-22 21:28:20 +03:00
committed by GitHub
7 changed files with 241 additions and 67 deletions

View File

@@ -19,7 +19,6 @@ import configparser
import os, json, sys, getopt import os, json, sys, getopt
from pathlib import Path from pathlib import Path
config = configparser.ConfigParser() # создаём объекта парсера INI config = configparser.ConfigParser() # создаём объекта парсера INI
def printHelp(): def printHelp():
@@ -85,7 +84,7 @@ if Path(profile).is_file():
# sortedModules = {} # sortedModules = {}
# for sortedModulName in sortedList: # for sortedModulName in sortedList:
print(profJson) # print(profJson)
with open(profile, "w", encoding='utf-8') as write_file: with open(profile, "w", encoding='utf-8') as write_file:
json.dump(profJson, write_file, ensure_ascii=False, indent=4, sort_keys=False) json.dump(profJson, write_file, ensure_ascii=False, indent=4, sort_keys=False)
@@ -183,6 +182,12 @@ config["platformio"]["default_envs"] = deviceName
config["platformio"]["data_dir"] = profJson['projectProp']['platformio']['data_dir'] config["platformio"]["data_dir"] = profJson['projectProp']['platformio']['data_dir']
with open("platformio.ini", 'w') as configFile: with open("platformio.ini", 'w') as configFile:
config.write(configFile) config.write(configFile)
import ctypes # An included library with Python install.
if update:
ctypes.windll.user32.MessageBoxW(0, "Модули профиля " + profile + " обновлены, а сам профиль применен, можно запускать компиляцию и прошивку.", "Операция завершена.", 0)
else:
ctypes.windll.user32.MessageBoxW(0, "Профиль " + profile + " применен, можно запускать компиляцию и прошивку.", "Операция завершена.", 0)

View File

@@ -455,22 +455,11 @@
"apin": -1, "apin": -1,
"num": 34 "num": 34
}, },
{
"name": "35. Доп. функции системы",
"type": "Reading",
"subtype": "SysExt",
"id": "SysExt",
"widget": "",
"page": "",
"descr": "",
"int": 15,
"num": 35
},
{ {
"header": "Экраны" "header": "Экраны"
}, },
{ {
"name": "36. LCD экран 2004", "name": "35. LCD экран 2004",
"type": "Reading", "type": "Reading",
"subtype": "Lcd2004", "subtype": "Lcd2004",
"id": "Lcd", "id": "Lcd",
@@ -482,10 +471,10 @@
"size": "20,4", "size": "20,4",
"coord": "0,0", "coord": "0,0",
"id2show": "id датчика", "id2show": "id датчика",
"num": 36 "num": 35
}, },
{ {
"name": "37. LCD экран 1602", "name": "36. LCD экран 1602",
"type": "Reading", "type": "Reading",
"subtype": "Lcd2004", "subtype": "Lcd2004",
"id": "Lcd", "id": "Lcd",
@@ -497,6 +486,6 @@
"size": "16,2", "size": "16,2",
"coord": "0,0", "coord": "0,0",
"id2show": "id датчика", "id2show": "id датчика",
"num": 37 "num": 36
} }
] ]

View File

@@ -89,7 +89,6 @@ build_src_filter =
+<modules\exec\Mcp23017> +<modules\exec\Mcp23017>
+<modules\exec\Mp3> +<modules\exec\Mp3>
+<modules\exec\Pwm8266> +<modules\exec\Pwm8266>
+<modules\exec\SysExt>
+<modules\display\Lcd2004> +<modules\display\Lcd2004>
[env:esp32_4mb_fromitems] [env:esp32_4mb_fromitems]
@@ -111,8 +110,10 @@ lib_deps =
dfrobot/DFRobotDFPlayerMini @ ^1.0.5 dfrobot/DFRobotDFPlayerMini @ ^1.0.5
marcoschwartz/LiquidCrystal_I2C@^1.1.4 marcoschwartz/LiquidCrystal_I2C@^1.1.4
build_src_filter = build_src_filter =
+<modules\virtual\Logging>
+<modules\virtual\Timer> +<modules\virtual\Timer>
+<modules\virtual\Variable> +<modules\virtual\Variable>
+<modules\virtual\VButton>
+<modules\sensors\Aht20> +<modules\sensors\Aht20>
+<modules\sensors\AnalogAdc> +<modules\sensors\AnalogAdc>
+<modules\sensors\Bme280> +<modules\sensors\Bme280>
@@ -128,11 +129,9 @@ build_src_filter =
+<modules\sensors\Sonar> +<modules\sensors\Sonar>
+<modules\exec\ButtonIn> +<modules\exec\ButtonIn>
+<modules\exec\ButtonOut> +<modules\exec\ButtonOut>
+<modules\exec\IarduinoRTC>
+<modules\exec\IoTServo> +<modules\exec\IoTServo>
+<modules\exec\Mcp23017> +<modules\exec\Mcp23017>
+<modules\exec\Mp3> +<modules\exec\Mp3>
+<modules\exec\Pwm32> +<modules\exec\Pwm32>
+<modules\exec\SysExt>
+<modules\display\Lcd2004> +<modules\display\Lcd2004>

View File

@@ -5,7 +5,7 @@
#include "classes/IoTItem.h" #include "classes/IoTItem.h"
#include "classes/IoTScenario.h" #include "classes/IoTScenario.h"
#include "utils/FileUtils.h" #include "utils/FileUtils.h"
#include "NTP.h"
bool isIotScenException; // признак исключения и попытки прекратить выполнение сценария заранее bool isIotScenException; // признак исключения и попытки прекратить выполнение сценария заранее
@@ -25,6 +25,7 @@ enum Token {
tok_if = -6, tok_then = -7, tok_else = -8 tok_if = -6, tok_then = -7, tok_else = -8
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Abstract Syntax Tree (Абстрактное Синтаксическое Дерево или Дерево Парсинга) // Abstract Syntax Tree (Абстрактное Синтаксическое Дерево или Дерево Парсинга)
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@@ -274,6 +275,186 @@ public:
} }
}; };
// Для сокращения количества преобразований используем числовые коды для фиксации названия системной функции,
// которые поддерживает прошивка
enum SysOp {
sysop_notfound = 0,
sysop_reboot = 1,
sysop_digitalRead,
sysop_analogRead, //
sysop_digitalWrite, //
sysop_digitalInvert, //
sysop_deepSleep, //
sysop_getHours, //
sysop_getMinutes, //
sysop_getSeconds, //
sysop_getMonth, //
sysop_getDay,
sysop_gethhmm,
sysop_gethhmmss,
sysop_getTime,
sysop_getIP,
sysop_mqttPub
};
IoTValue sysExecute(SysOp command, std::vector<IoTValue>& param) {
IoTValue value;
switch (command) {
case sysop_reboot:
ESP.restart();
break;
case sysop_digitalRead:
if (param.size()) {
IoTgpio.pinMode(param[0].valD, INPUT);
value.valD = IoTgpio.digitalRead(param[0].valD);
return value;
}
break;
case sysop_analogRead:
if (param.size()) {
IoTgpio.pinMode(param[0].valD, INPUT);
value.valD = IoTgpio.analogRead(param[0].valD);
return value;
}
break;
case sysop_digitalWrite:
if (param.size() == 2) {
IoTgpio.pinMode(param[0].valD, OUTPUT);
IoTgpio.digitalWrite(param[0].valD, param[1].valD);
return {};
}
break;
case sysop_digitalInvert:
if (param.size()) {
IoTgpio.pinMode(param[0].valD, OUTPUT);
IoTgpio.digitalInvert(param[0].valD);
return {};
}
break;
case sysop_deepSleep:
if (param.size()) {
Serial.printf("Ушел спать на %d сек...", (int)param[0].valD);
#ifdef ESP32
esp_sleep_enable_timer_wakeup(param[0].valD * 1000000);
delay(1000);
esp_deep_sleep_start();
#else
ESP.deepSleep(param[0].valD * 1000000);
#endif
}
break;
case sysop_getHours:
value.valD = _time_local.hour;
return value;
break;
case sysop_getMinutes:
value.valD = _time_local.minute;
return value;
break;
case sysop_getSeconds:
value.valD = _time_local.second;
return value;
break;
case sysop_getMonth:
value.valD = _time_local.month;
return value;
break;
case sysop_getDay:
value.valD = _time_local.day_of_month;
return value;
break;
case sysop_gethhmm:
value.isDecimal = false;
value.valS = getTimeLocal_hhmm();
return value;
break;
case sysop_gethhmmss:
value.isDecimal = false;
value.valS = getTimeLocal_hhmmss();
return value;
break;
case sysop_getTime:
value.isDecimal = false;
value.valS = getDateTimeDotFormated();
return value;
break;
case sysop_getIP:
value.valS = jsonReadStr(settingsFlashJson, F("ip"));
value.isDecimal = false;
return value;
break;
case sysop_mqttPub:
if (param.size() == 2) {
//Serial.printf("Call from sysExecute %s %s\n", param[0].valS.c_str(), param[1].valS.c_str());
value.valD = mqtt.publish(param[0].valS.c_str(), param[1].valS.c_str(), false);
return value;
}
break;
}
return {};
}
/// SysCallExprAST - Класс узла выражения для вызова системных команд.
class SysCallExprAST : public ExprAST {
String Callee;
std::vector<ExprAST*> Args;
IoTValue ret; // хранение возвращаемого значения, т.к. возврат по ссылке осуществляется
//bool ItemIsLocal = false;
SysOp operation;
public:
SysCallExprAST(const String &callee, std::vector<ExprAST*> &args)
: Callee(callee), Args(args) {
if (Callee == "reboot") operation = sysop_reboot; else
if (Callee == "digitalRead") operation = sysop_digitalRead; else
if (Callee == "analogRead") operation = sysop_analogRead; else
if (Callee == "digitalWrite") operation = sysop_digitalWrite; else
if (Callee == "digitalInvert") operation = sysop_digitalInvert; else
if (Callee == "deepSleep") operation = sysop_deepSleep; else
if (Callee == "getTime") operation = sysop_getTime; else
if (Callee == "getHours") operation = sysop_getHours; else
if (Callee == "getMinutes") operation = sysop_getMinutes; else
if (Callee == "getSeconds") operation = sysop_getSeconds; else
if (Callee == "getMonth") operation = sysop_getMonth; else
if (Callee == "getDay") operation = sysop_getDay; else
if (Callee == "getIP") operation = sysop_getIP; else
if (Callee == "mqttPub") operation = sysop_mqttPub; else
if (Callee == "gethhmm") operation = sysop_gethhmm; else
if (Callee == "gethhmmss") operation = sysop_gethhmmss; else
if (Callee == "getTime") operation = sysop_getTime; else
operation = sysop_notfound;
}
IoTValue* exec() {
Serial.printf("Call from SysCallExprAST exec %d\n", operation);
if (isIotScenException) return nullptr; // если прерывание, то сразу выходим
// готовим параметры для передачи в в функцию интерпретатор действий
std::vector<IoTValue> ArgsAsIoTValue;
for (unsigned int i = 0; i < Args.size(); i++) {
if (Args[i] == nullptr) return nullptr;
IoTValue *tmp = Args[i]->exec();
if (tmp != nullptr) ArgsAsIoTValue.push_back(*tmp);
else return nullptr;
}
ret = sysExecute(operation, ArgsAsIoTValue); // вызываем функцию интерпретатор с передачей всех аргументов
return &ret;
}
~SysCallExprAST() {
for (unsigned int i = 0; i < Args.size(); i++) {
if (Args[i]) delete Args[i];
}
Args.clear();
//Serial.printf("Call from CallExprAST delete\n");
}
};
/// IfExprAST - Класс узла выражения для if/then/else. /// IfExprAST - Класс узла выражения для if/then/else.
class IfExprAST : public ExprAST { class IfExprAST : public ExprAST {
ExprAST *Cond, *Then, *Else; ExprAST *Cond, *Then, *Else;
@@ -533,12 +714,14 @@ public:
} }
} }
// Получаем ')'. // Получаем ';'.
getNextToken(); getNextToken();
//if (tmpItem) if (Cmd == "")
return new CallExprAST(IdName, Cmd, Args, tmpItem); // создаем объект запуска функции в любом случае даж если не нашли Item return new SysCallExprAST(IdName, Args); // создаем объект запуска системной функции
//else return new StringExprAST("id " + IdName + " not_found"); else
return new CallExprAST(IdName, Cmd, Args, tmpItem); // создаем объект запуска функции в любом случае даж если не нашли Item
} }
/// numberexpr ::= number /// numberexpr ::= number

View File

@@ -23,7 +23,6 @@ void* getAPI_IoTServo(String subtype, String params);
void* getAPI_Mcp23017(String subtype, String params); void* getAPI_Mcp23017(String subtype, String params);
void* getAPI_Mp3(String subtype, String params); void* getAPI_Mp3(String subtype, String params);
void* getAPI_Pwm8266(String subtype, String params); void* getAPI_Pwm8266(String subtype, String params);
void* getAPI_SysExt(String subtype, String params);
void* getAPI_Lcd2004(String subtype, String params); void* getAPI_Lcd2004(String subtype, String params);
void* getAPI(String subtype, String params) { void* getAPI(String subtype, String params) {
@@ -51,7 +50,6 @@ if ((tmpAPI = getAPI_IoTServo(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Mcp23017(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Mcp23017(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Mp3(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Mp3(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Pwm8266(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Pwm8266(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_SysExt(subtype, params)) != nullptr) return tmpAPI;
if ((tmpAPI = getAPI_Lcd2004(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Lcd2004(subtype, params)) != nullptr) return tmpAPI;
return nullptr; return nullptr;
} }

View File

@@ -29,32 +29,32 @@ class SysExt : public IoTItem {
// String command - имя команды после ID. (ID.Команда()) // String command - имя команды после ID. (ID.Команда())
// param - вектор ("массив") значений параметров переданных вместе с командой: ID.Команда("пар1", 22, 33) -> param[0].ValS = "пар1", param[1].ValD = 22 // param - вектор ("массив") значений параметров переданных вместе с командой: ID.Команда("пар1", 22, 33) -> param[0].ValS = "пар1", param[1].ValD = 22
if (command == "reboot") { // выполняем код при вызове спец команды из сценария: ID.reboot(); // if (command == "reboot") { // выполняем код при вызове спец команды из сценария: ID.reboot();
ESP.restart(); // ESP.restart();
} else if (command == "digitalRead") { // } else if (command == "digitalRead") {
if (param.size()) { // if (param.size()) {
IoTgpio.pinMode(param[0].valD, INPUT); // IoTgpio.pinMode(param[0].valD, INPUT);
value.valD = IoTgpio.digitalRead(param[0].valD); // value.valD = IoTgpio.digitalRead(param[0].valD);
return value; // return value;
} // }
} else if (command == "analogRead") { // } else if (command == "analogRead") {
if (param.size()) { // if (param.size()) {
IoTgpio.pinMode(param[0].valD, INPUT); // IoTgpio.pinMode(param[0].valD, INPUT);
value.valD = IoTgpio.analogRead(param[0].valD); // value.valD = IoTgpio.analogRead(param[0].valD);
return value; // return value;
} // }
} else if (command == "digitalWrite") { // } else if (command == "digitalWrite") {
if (param.size() == 2) { // if (param.size() == 2) {
IoTgpio.pinMode(param[0].valD, OUTPUT); // IoTgpio.pinMode(param[0].valD, OUTPUT);
IoTgpio.digitalWrite(param[0].valD, param[1].valD); // IoTgpio.digitalWrite(param[0].valD, param[1].valD);
return {}; // return {};
} // }
} else if (command == "digitalInvert") { // } else if (command == "digitalInvert") {
if (param.size()) { // if (param.size()) {
IoTgpio.pinMode(param[0].valD, OUTPUT); // IoTgpio.pinMode(param[0].valD, OUTPUT);
IoTgpio.digitalInvert(param[0].valD); // IoTgpio.digitalInvert(param[0].valD);
return {}; // return {};
} // }
//} else if (command == "getTime") { //} else if (command == "getTime") {
// if (param.size()) { // if (param.size()) {
// value.isDecimal = false; // value.isDecimal = false;
@@ -81,19 +81,19 @@ class SysExt : public IoTItem {
// value.valD = watch->day; // День месяца 1-31 // value.valD = watch->day; // День месяца 1-31
// value.isDecimal = true; // value.isDecimal = true;
// return value; // return value;
} else if (command == "deepSleep") { // } else if (command == "deepSleep") {
if (param.size()) { // if (param.size()) {
Serial.printf("Ушел спать на %d сек...", (int)param[0].valD); // Serial.printf("Ушел спать на %d сек...", (int)param[0].valD);
#ifdef ESP32 // #ifdef ESP32
esp_sleep_enable_timer_wakeup(param[0].valD * 1000000); // esp_sleep_enable_timer_wakeup(param[0].valD * 1000000);
delay(1000); // delay(1000);
esp_deep_sleep_start(); // esp_deep_sleep_start();
#else // #else
ESP.deepSleep(param[0].valD * 1000000); // ESP.deepSleep(param[0].valD * 1000000);
#endif // #endif
} // }
return {}; // return {};
} //}
// } else if (command == "ModemSleep") { // } else if (command == "ModemSleep") {
// Serial.printf("Выключил все радио..."); // Serial.printf("Выключил все радио...");
// #ifdef ESP32 // #ifdef ESP32

View File

@@ -25,7 +25,7 @@
} }
}, },
"defActive": true, "defActive": false,
"devices": { "devices": {
"esp32_4mb": [], "esp32_4mb": [],