mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-30 20:09:14 +03:00
добавил сценарии и класс сенсора
This commit is contained in:
7
include/Buffers.h
Normal file
7
include/Buffers.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Global.h"
|
||||||
|
#include "MqttClient.h"
|
||||||
|
|
||||||
|
void eventGen2(String eventName, String eventValue);
|
||||||
|
extern void spaceCmdExecute(String &cmdStr);
|
||||||
|
extern String getValueJson(String &key);
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <TickerScheduler.h>
|
#include <TickerScheduler.h>
|
||||||
#include <PubSubClient.h>
|
#include <PubSubClient.h>
|
||||||
|
#include <StringCommand.h>
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
#include "WiFi.h"
|
#include "WiFi.h"
|
||||||
@@ -46,6 +47,7 @@
|
|||||||
#include "Utils/FileUtils.h"
|
#include "Utils/FileUtils.h"
|
||||||
#include "Utils/JsonUtils.h"
|
#include "Utils/JsonUtils.h"
|
||||||
#include "Utils/SerialPrint.h"
|
#include "Utils/SerialPrint.h"
|
||||||
|
#include "Utils/StringUtils.h"
|
||||||
|
|
||||||
/*********************************************************************************************************************
|
/*********************************************************************************************************************
|
||||||
*****************************************глобальные объекты классов***************************************************
|
*****************************************глобальные объекты классов***************************************************
|
||||||
@@ -54,6 +56,7 @@
|
|||||||
extern TickerScheduler ts;
|
extern TickerScheduler ts;
|
||||||
extern WiFiClient espClient;
|
extern WiFiClient espClient;
|
||||||
extern PubSubClient mqtt;
|
extern PubSubClient mqtt;
|
||||||
|
extern StringCommand sCmd;
|
||||||
#ifdef ASYNC_WEB_SERVER
|
#ifdef ASYNC_WEB_SERVER
|
||||||
extern AsyncWebServer server;
|
extern AsyncWebServer server;
|
||||||
#endif
|
#endif
|
||||||
@@ -79,6 +82,10 @@ extern String settingsFlashJson;
|
|||||||
extern String paramsFlashJson;
|
extern String paramsFlashJson;
|
||||||
extern String paramsHeapJson;
|
extern String paramsHeapJson;
|
||||||
|
|
||||||
|
// buf
|
||||||
|
extern String orderBuf;
|
||||||
|
extern String eventBuf;
|
||||||
|
|
||||||
// Mqtt
|
// Mqtt
|
||||||
extern String mqttServer;
|
extern String mqttServer;
|
||||||
extern int mqttPort;
|
extern int mqttPort;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
//
|
//
|
||||||
#include "EspFileSystem.h"
|
#include "EspFileSystem.h"
|
||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
#include "Utils/Pretty.h"
|
|
||||||
#include "Utils/WiFiUtils.h"
|
#include "Utils/WiFiUtils.h"
|
||||||
#include "AsyncWebServer.h"
|
#include "AsyncWebServer.h"
|
||||||
#include "StandWebServer.h"
|
#include "StandWebServer.h"
|
||||||
|
|||||||
26
include/classes/IoTSensor.h
Normal file
26
include/classes/IoTSensor.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <WString.h>
|
||||||
|
|
||||||
|
class IoTSensor {
|
||||||
|
public:
|
||||||
|
IoTSensor();
|
||||||
|
~IoTSensor();
|
||||||
|
|
||||||
|
void loop();
|
||||||
|
virtual void doByInterval();
|
||||||
|
void init(String key, String id, unsigned long interval);
|
||||||
|
void regEvent(String value, String consoleInfo);
|
||||||
|
|
||||||
|
String getKey();
|
||||||
|
String getID();
|
||||||
|
|
||||||
|
unsigned long currentMillis;
|
||||||
|
unsigned long prevMillis;
|
||||||
|
unsigned long difference;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
String _key;
|
||||||
|
String _id;
|
||||||
|
unsigned long _interval;
|
||||||
|
};
|
||||||
255
include/classes/ScenarioClass3.h
Normal file
255
include/classes/ScenarioClass3.h
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Global.h"
|
||||||
|
#include "MqttClient.h"
|
||||||
|
#include "Buffers.h"
|
||||||
|
|
||||||
|
class Scenario {
|
||||||
|
public:
|
||||||
|
void loop2() {
|
||||||
|
if (!jsonReadBool(settingsFlashJson, "scen")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String allBlocks = scenario;
|
||||||
|
allBlocks += "\n";
|
||||||
|
|
||||||
|
String incommingEvent = selectToMarker(eventBuf, ",");
|
||||||
|
|
||||||
|
String incommingEventKey = selectToMarker(incommingEvent, " ");
|
||||||
|
String incommingEventValue = selectToMarkerLast(incommingEvent, " ");
|
||||||
|
|
||||||
|
while (allBlocks.length()) {
|
||||||
|
String oneBlock = selectToMarker(allBlocks, "end\n");
|
||||||
|
String condition = selectToMarker(oneBlock, "\n");
|
||||||
|
|
||||||
|
//логическое и
|
||||||
|
if (condition.indexOf("&&") != -1) {
|
||||||
|
condition = condition += " && ";
|
||||||
|
|
||||||
|
//посчитаем количество условий
|
||||||
|
int conditionCnt = itemsCount2(condition, "&&") - 1;
|
||||||
|
|
||||||
|
//создадим и заполним динамический массив
|
||||||
|
bool *arr = new bool[conditionCnt];
|
||||||
|
for (int i = 0; i < conditionCnt; i++) {
|
||||||
|
arr[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//есть ли входящее событие хотя бы в одном из условий и удавлетварено ли оно?
|
||||||
|
int evenInConditionNum = -1;
|
||||||
|
for (int i = 0; i < conditionCnt; i++) {
|
||||||
|
String buf = selectFromMarkerToMarker(condition, " && ", i);
|
||||||
|
if (isScenarioNeedToDo(buf, incommingEventKey, incommingEventValue, 1)) {
|
||||||
|
arr[i] = true;
|
||||||
|
evenInConditionNum = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//если да то проверяем остальные условия по json
|
||||||
|
if (evenInConditionNum >= 0) {
|
||||||
|
for (int i = 0; i < conditionCnt; i++) {
|
||||||
|
String buf = selectFromMarkerToMarker(condition, " && ", i);
|
||||||
|
if (i != evenInConditionNum) {
|
||||||
|
if (isScenarioNeedToDoJson(buf)) {
|
||||||
|
arr[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//все элементы массива должны быть true
|
||||||
|
bool result = true;
|
||||||
|
for (int i = 0; i < conditionCnt; i++) {
|
||||||
|
if (!arr[i]) {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] arr;
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
oneBlock = deleteBeforeDelimiter(oneBlock, "\n");
|
||||||
|
oneBlock.replace("end", "");
|
||||||
|
|
||||||
|
// SerialPrint("I", "Event done", incommingEvent);
|
||||||
|
SerialPrint("I", F("Scenario"), F("All conditions are matched"));
|
||||||
|
spaceCmdExecute(oneBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
//логическое или
|
||||||
|
} else if (condition.indexOf("||") != -1) {
|
||||||
|
condition = condition += " || ";
|
||||||
|
|
||||||
|
//посчитаем количество условий
|
||||||
|
int conditionCnt = itemsCount2(condition, "||") - 1;
|
||||||
|
|
||||||
|
//создадим и заполним динамический массив
|
||||||
|
bool *arr = new bool[conditionCnt];
|
||||||
|
for (int i = 0; i < conditionCnt; i++) {
|
||||||
|
arr[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//есть ли входящее событие хотя бы в одном из условий и удавлетварено ли оно?
|
||||||
|
int evenInConditionNum = -1;
|
||||||
|
for (int i = 0; i < conditionCnt; i++) {
|
||||||
|
String buf = selectFromMarkerToMarker(condition, " || ", i);
|
||||||
|
if (isScenarioNeedToDo(buf, incommingEventKey, incommingEventValue, 1)) {
|
||||||
|
arr[i] = true;
|
||||||
|
evenInConditionNum = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//если да то проверяем остальные условия по json
|
||||||
|
if (evenInConditionNum >= 0) {
|
||||||
|
for (int i = 0; i < conditionCnt; i++) {
|
||||||
|
String buf = selectFromMarkerToMarker(condition, " || ", i);
|
||||||
|
if (i != evenInConditionNum) {
|
||||||
|
if (isScenarioNeedToDoJson(buf)) {
|
||||||
|
arr[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//хотя бы один элемент массива должн быть true
|
||||||
|
bool result = false;
|
||||||
|
for (int i = 0; i < conditionCnt; i++) {
|
||||||
|
if (arr[i]) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] arr;
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
oneBlock = deleteBeforeDelimiter(oneBlock, "\n");
|
||||||
|
oneBlock.replace("end", "");
|
||||||
|
|
||||||
|
// SerialPrint("I", "Event done", incommingEvent);
|
||||||
|
SerialPrint("I", F("Scenario"), F("One of all condition are matched"));
|
||||||
|
spaceCmdExecute(oneBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
//если гистерезис
|
||||||
|
} else if (condition.indexOf("+-") != -1) {
|
||||||
|
if (isScenarioNeedToDo(condition, incommingEventKey, incommingEventValue, 2)) {
|
||||||
|
oneBlock = deleteBeforeDelimiter(oneBlock, "\n");
|
||||||
|
oneBlock.replace("end", "");
|
||||||
|
|
||||||
|
// SerialPrint("I", "Event done", incommingEvent);
|
||||||
|
SerialPrint("I", F("Scenario"), "Condition are matched: " + condition);
|
||||||
|
spaceCmdExecute(oneBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
//остальные случаи
|
||||||
|
} else {
|
||||||
|
if (isScenarioNeedToDo(condition, incommingEventKey, incommingEventValue, 1)) {
|
||||||
|
oneBlock = deleteBeforeDelimiter(oneBlock, "\n");
|
||||||
|
oneBlock.replace("end", "");
|
||||||
|
|
||||||
|
// SerialPrint("I", "Event done", incommingEvent);
|
||||||
|
SerialPrint("I", F("Scenario"), "Condition are matched: " + condition);
|
||||||
|
spaceCmdExecute(oneBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allBlocks = deleteBeforeDelimiter(allBlocks, "end\n");
|
||||||
|
}
|
||||||
|
eventBuf = deleteBeforeDelimiter(eventBuf, ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isScenarioNeedToDo(String &condition, String &incommingEventKey, String &incommingEventValue, int type) {
|
||||||
|
bool res = false;
|
||||||
|
String setEventKey = selectFromMarkerToMarker(condition, " ", 0);
|
||||||
|
if (isEventExist(incommingEventKey, setEventKey)) {
|
||||||
|
String setEventSign;
|
||||||
|
String setEventValue;
|
||||||
|
if (type == 1) preCalculation(condition, setEventSign, setEventValue);
|
||||||
|
if (type == 2) preCalculationGisteresis(condition, setEventSign, setEventValue);
|
||||||
|
if (isConditionMatch(setEventSign, incommingEventValue, setEventValue)) {
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isScenarioNeedToDoJson(String &condition) {
|
||||||
|
bool res = false;
|
||||||
|
String setEventKey = selectFromMarkerToMarker(condition, " ", 0);
|
||||||
|
String setEventSign;
|
||||||
|
String setEventValue;
|
||||||
|
preCalculation(condition, setEventSign, setEventValue);
|
||||||
|
String jsonValue = getValueJson(setEventKey);
|
||||||
|
if (isConditionMatch(setEventSign, jsonValue, setEventValue)) {
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bool isScenarioNeedToDoJson2(String &condition, String &incommingEventKey, String &incommingEventValue) {
|
||||||
|
// bool res = false;
|
||||||
|
// String setEventKey = selectFromMarkerToMarker(condition, " ", 0);
|
||||||
|
// if (isEventExist(incommingEventKey, setEventKey)) {
|
||||||
|
// String setEventSign;
|
||||||
|
// String setEventValue;
|
||||||
|
// preCalculation(condition, setEventSign, setEventValue);
|
||||||
|
// if (isConditionMatch(setEventSign, incommingEventValue, setEventValue)) {
|
||||||
|
// res = true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return res;
|
||||||
|
// }
|
||||||
|
|
||||||
|
void preCalculation(String &condition, String &setEventSign, String &setEventValue) {
|
||||||
|
setEventSign = selectFromMarkerToMarker(condition, " ", 1);
|
||||||
|
setEventValue = selectFromMarkerToMarker(condition, " ", 2);
|
||||||
|
if (!isDigitDotCommaStr(setEventValue)) {
|
||||||
|
setEventValue = getValueJson(setEventValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void preCalculationGisteresis(String &condition, String &setEventSign, String &setEventValue) {
|
||||||
|
setEventSign = selectFromMarkerToMarker(condition, " ", 1);
|
||||||
|
setEventValue = selectFromMarkerToMarker(condition, " ", 2);
|
||||||
|
if (!isDigitDotCommaStr(setEventValue)) {
|
||||||
|
String setEventValueName = selectToMarker(setEventValue, "+-");
|
||||||
|
String gisteresisValue = selectToMarkerLast(setEventValue, "+-");
|
||||||
|
gisteresisValue.replace("+-", "");
|
||||||
|
String value = getValueJson(setEventValueName);
|
||||||
|
String upValue = String(value.toFloat() + gisteresisValue.toFloat());
|
||||||
|
String lowValue = String(value.toFloat() - gisteresisValue.toFloat());
|
||||||
|
if (setEventSign == ">") {
|
||||||
|
setEventValue = upValue;
|
||||||
|
} else if (setEventSign == "<") {
|
||||||
|
setEventValue = lowValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEventExist(String &incommingEventKey, String &setEventKey) {
|
||||||
|
bool res = false;
|
||||||
|
if (incommingEventKey == setEventKey) {
|
||||||
|
res = true;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isConditionMatch(String &setEventSign, String &incommingEventValue, String &setEventValue) {
|
||||||
|
boolean flag = false;
|
||||||
|
if (setEventSign == "=") {
|
||||||
|
flag = incommingEventValue == setEventValue;
|
||||||
|
} else if (setEventSign == "!=") {
|
||||||
|
flag = incommingEventValue != setEventValue;
|
||||||
|
} else if (setEventSign == "<") {
|
||||||
|
flag = incommingEventValue.toFloat() < setEventValue.toFloat();
|
||||||
|
} else if (setEventSign == ">") {
|
||||||
|
flag = incommingEventValue.toFloat() > setEventValue.toFloat();
|
||||||
|
} else if (setEventSign == ">=") {
|
||||||
|
flag = incommingEventValue.toFloat() >= setEventValue.toFloat();
|
||||||
|
} else if (setEventSign == "<=") {
|
||||||
|
flag = incommingEventValue.toFloat() <= setEventValue.toFloat();
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Scenario *myScenario;
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Global.h"
|
|
||||||
|
|
||||||
String prettyBytes(size_t size);
|
|
||||||
39
include/utils/StringUtils.h
Normal file
39
include/utils/StringUtils.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Global.h"
|
||||||
|
|
||||||
|
void hex2string(byte array[], unsigned int len, char buffer[]);
|
||||||
|
|
||||||
|
int string2hex(const char* str, unsigned char* bytes);
|
||||||
|
|
||||||
|
uint8_t hexStringToUint8(String hex);
|
||||||
|
|
||||||
|
uint16_t hexStringToUint16(String hex);
|
||||||
|
|
||||||
|
String selectToMarkerLast(String str, String found);
|
||||||
|
|
||||||
|
String selectToMarker(String str, String found);
|
||||||
|
|
||||||
|
String extractInner(String str);
|
||||||
|
|
||||||
|
String deleteAfterDelimiter(String str, String found);
|
||||||
|
|
||||||
|
String deleteBeforeDelimiter(String str, String found);
|
||||||
|
|
||||||
|
String deleteBeforeDelimiterTo(String str, String found);
|
||||||
|
|
||||||
|
String deleteToMarkerLast(String str, String found);
|
||||||
|
|
||||||
|
String selectFromMarkerToMarker(String str, String found, int number);
|
||||||
|
|
||||||
|
size_t itemsCount2(String str, const String& separator);
|
||||||
|
|
||||||
|
char* stringToChar(String& str);
|
||||||
|
|
||||||
|
size_t itemsCount(String& str, const char* delim);
|
||||||
|
|
||||||
|
boolean isDigitStr(const String& str);
|
||||||
|
|
||||||
|
boolean isDigitDotCommaStr(const String& str);
|
||||||
|
|
||||||
|
String prettyBytes(size_t size);
|
||||||
137
lib/ESP8266-StringCommand/StringCommand.cpp
Normal file
137
lib/ESP8266-StringCommand/StringCommand.cpp
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
* SerialCommand - A Wiring/Arduino library to tokenize and parse commands
|
||||||
|
* received over a serial port.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Stefan Rado
|
||||||
|
* Copyright (C) 2011 Steven Cogswell <steven.cogswell@gmail.com>
|
||||||
|
* http://husks.wordpress.com
|
||||||
|
*
|
||||||
|
* Version 20120522
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "StringCommand.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor makes sure some things are set.
|
||||||
|
*/
|
||||||
|
StringCommand::StringCommand()
|
||||||
|
: commandList(NULL),
|
||||||
|
commandCount(0),
|
||||||
|
defaultHandler(NULL),
|
||||||
|
term('\n'), // default terminator for commands, newline character
|
||||||
|
last(NULL),
|
||||||
|
main(NULL)
|
||||||
|
{
|
||||||
|
strcpy(delim, " "); // strtok_r needs a null-terminated string
|
||||||
|
clearBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a "command" and a handler function to the list of available commands.
|
||||||
|
* This is used for matching a found token in the buffer, and gives the pointer
|
||||||
|
* to the handler function to deal with it.
|
||||||
|
*/
|
||||||
|
void StringCommand::addCommand(const char *command, void (*function)()) {
|
||||||
|
#ifdef SERIALCOMMAND_DEBUG
|
||||||
|
Serial.print("Adding command (");
|
||||||
|
Serial.print(commandCount);
|
||||||
|
Serial.print("): ");
|
||||||
|
Serial.println(command);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
commandList = (StringCommandCallback *) realloc(commandList, (commandCount + 1) * sizeof(StringCommandCallback));
|
||||||
|
strncpy(commandList[commandCount].command, command, SERIALCOMMAND_MAXCOMMANDLENGTH);
|
||||||
|
commandList[commandCount].function = function;
|
||||||
|
commandCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This sets up a handler to be called in the event that the receveived command string
|
||||||
|
* isn't in the list of commands.
|
||||||
|
*/
|
||||||
|
void StringCommand::setDefaultHandler(void (*function)(const char *)) {
|
||||||
|
defaultHandler = function;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This checks the Serial stream for characters, and assembles them into a buffer.
|
||||||
|
* When the terminator character (default '\n') is seen, it starts parsing the
|
||||||
|
* buffer for a prefix command, and calls handlers setup by addCommand() member
|
||||||
|
*/
|
||||||
|
void StringCommand::readStr(String sBuffer ) {
|
||||||
|
sBuffer.toCharArray(buffer, SERIALCOMMAND_BUFFER);
|
||||||
|
#ifdef SERIALCOMMAND_DEBUG
|
||||||
|
Serial.print("Received: ");
|
||||||
|
Serial.println(buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *command = strtok_r(buffer, delim, &last); // Search for command at start of buffer
|
||||||
|
if (command != NULL) {
|
||||||
|
boolean matched = false;
|
||||||
|
for (int i = 0; i < commandCount; i++) {
|
||||||
|
#ifdef SERIALCOMMAND_DEBUG
|
||||||
|
Serial.print("Comparing [");
|
||||||
|
Serial.print(command);
|
||||||
|
Serial.print("] to [");
|
||||||
|
Serial.print(commandList[i].command);
|
||||||
|
Serial.println("]");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Compare the found command against the list of known commands for a match
|
||||||
|
if (strncmp(command, commandList[i].command, SERIALCOMMAND_MAXCOMMANDLENGTH) == 0) {
|
||||||
|
#ifdef SERIALCOMMAND_DEBUG
|
||||||
|
Serial.print("Matched Command: ");
|
||||||
|
Serial.println(command);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Execute the stored handler function for the command
|
||||||
|
(*commandList[i].function)();
|
||||||
|
matched = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!matched && (defaultHandler != NULL)) {
|
||||||
|
(*defaultHandler)(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
clearBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clear the input buffer.
|
||||||
|
*/
|
||||||
|
void StringCommand::clearBuffer() {
|
||||||
|
buffer[0] = '\0';
|
||||||
|
bufPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the next token ("word" or "argument") from the command buffer.
|
||||||
|
* Returns NULL if no more tokens exist.
|
||||||
|
*/
|
||||||
|
char *StringCommand::next() {
|
||||||
|
return strtok_r(NULL, delim, &last);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *StringCommand::order() {
|
||||||
|
return strtok_r(buffer, delim, &main);
|
||||||
|
}
|
||||||
77
lib/ESP8266-StringCommand/StringCommand.h
Normal file
77
lib/ESP8266-StringCommand/StringCommand.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* SerialCommand - A Wiring/Arduino library to tokenize and parse commands
|
||||||
|
* received over a serial port.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Stefan Rado
|
||||||
|
* Copyright (C) 2011 Steven Cogswell <steven.cogswell@gmail.com>
|
||||||
|
* http://husks.wordpress.com
|
||||||
|
*
|
||||||
|
* Version 20120522
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef StringCommand_h
|
||||||
|
#define StringCommand_h
|
||||||
|
|
||||||
|
#if defined(WIRING) && WIRING >= 100
|
||||||
|
#include <Wiring.h>
|
||||||
|
#elif defined(ARDUINO) && ARDUINO >= 100
|
||||||
|
#include <Arduino.h>
|
||||||
|
#else
|
||||||
|
#include <WProgram.h>
|
||||||
|
#endif
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Size of the input buffer in bytes (maximum length of one command plus arguments)
|
||||||
|
#define SERIALCOMMAND_BUFFER 128 //256
|
||||||
|
// Maximum length of a command excluding the terminating null
|
||||||
|
#define SERIALCOMMAND_MAXCOMMANDLENGTH 16
|
||||||
|
|
||||||
|
// Uncomment the next line to run the library in debug mode (verbose messages)
|
||||||
|
//#define SERIALCOMMAND_DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
class StringCommand {
|
||||||
|
public:
|
||||||
|
StringCommand(); // Constructor
|
||||||
|
void addCommand(const char *command, void(*function)()); // Add a command to the processing dictionary.
|
||||||
|
void setDefaultHandler(void (*function)(const char *)); // A handler to call when no valid command received.
|
||||||
|
|
||||||
|
void readStr(String sBuffer ); // Main entry point.
|
||||||
|
void clearBuffer(); // Clears the input buffer.
|
||||||
|
char *next(); // Returns pointer to next token found in command buffer (for getting arguments to commands).
|
||||||
|
char *order();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Command/handler dictionary
|
||||||
|
struct StringCommandCallback {
|
||||||
|
char command[SERIALCOMMAND_MAXCOMMANDLENGTH + 1];
|
||||||
|
void (*function)();
|
||||||
|
}; // Data structure to hold Command/Handler function key-value pairs
|
||||||
|
StringCommandCallback *commandList; // Actual definition for command/handler array
|
||||||
|
byte commandCount;
|
||||||
|
|
||||||
|
// Pointer to the default handler function
|
||||||
|
void (*defaultHandler)(const char *);
|
||||||
|
|
||||||
|
char delim[2]; // null-terminated list of character to be used as delimeters for tokenizing (default " ")
|
||||||
|
char term; // Character that signals end of command (default '\n')
|
||||||
|
|
||||||
|
char buffer[SERIALCOMMAND_BUFFER + 1]; // Buffer of stored characters while waiting for terminator character
|
||||||
|
byte bufPos; // Current position in the buffer
|
||||||
|
char *last; // State variable used by strtok_r during processing
|
||||||
|
char *main;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //StringCommand_h
|
||||||
23
lib/ESP8266-StringCommand/keywords.txt
Normal file
23
lib/ESP8266-StringCommand/keywords.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#######################################
|
||||||
|
# Datatypes (KEYWORD1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
StringCommand KEYWORD1
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
addCommand KEYWORD2
|
||||||
|
setDefaultHandler KEYWORD2
|
||||||
|
readString KEYWORD2
|
||||||
|
clearBuffer KEYWORD2
|
||||||
|
next KEYWORD2
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Instances (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Constants (LITERAL1)
|
||||||
|
#######################################
|
||||||
5
lib/ESP8266-StringCommand/readme.md
Normal file
5
lib/ESP8266-StringCommand/readme.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
StringCommand
|
||||||
|
=============
|
||||||
|
Библиотека для ESP8266 позволяющая связать запуск пользовательских функций с строковой переменной.
|
||||||
|
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ void asyncWebServerInit() {
|
|||||||
|
|
||||||
// динамические данные
|
// динамические данные
|
||||||
// server.on("/config.live.json", HTTP_GET, [](AsyncWebServerRequest *request) {
|
// server.on("/config.live.json", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
// request->send(200, "application/json", configLiveJson);
|
// request->send(200, "application/json", paramsFlashJson);
|
||||||
//});
|
//});
|
||||||
//
|
//
|
||||||
// server.on("/config.store.json", HTTP_GET, [](AsyncWebServerRequest *request) {
|
// server.on("/config.store.json", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
|||||||
46
src/Buffers.cpp
Normal file
46
src/Buffers.cpp
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#include "Buffers.h"
|
||||||
|
|
||||||
|
//генеирует событие
|
||||||
|
void eventGen2(String eventName, String eventValue) {
|
||||||
|
if (!jsonReadBool(settingsFlashJson, "scen")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String event = eventName + " " + eventValue + ",";
|
||||||
|
eventBuf += event;
|
||||||
|
|
||||||
|
SerialPrint("I", "Event add", eventName + " " + eventValue);
|
||||||
|
|
||||||
|
if (jsonReadBool(settingsFlashJson, "MqttOut")) {
|
||||||
|
if (eventName != "timenow") {
|
||||||
|
publishEvent(eventName, eventValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void spaceCmdExecute(String& cmdStr) {
|
||||||
|
cmdStr += "\r\n";
|
||||||
|
cmdStr.replace("\r\n", "\n");
|
||||||
|
cmdStr.replace("\r", "\n");
|
||||||
|
while (cmdStr.length()) {
|
||||||
|
String buf = selectToMarker(cmdStr, "\n");
|
||||||
|
if (buf != "") {
|
||||||
|
sCmd.readStr(buf);
|
||||||
|
SerialPrint("I", F("Order done W"), buf);
|
||||||
|
}
|
||||||
|
cmdStr = deleteBeforeDelimiter(cmdStr, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String getValueJson(String& key) {
|
||||||
|
String live = jsonReadStr(paramsHeapJson, key);
|
||||||
|
String store = jsonReadStr(paramsFlashJson, key);
|
||||||
|
if (live != nullptr) {
|
||||||
|
return live;
|
||||||
|
} else if (store != nullptr) {
|
||||||
|
return store;
|
||||||
|
} else if (store == nullptr && live == nullptr) {
|
||||||
|
return "no value";
|
||||||
|
} else {
|
||||||
|
return "data error";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@ void configure(String& path) {
|
|||||||
//=============================
|
//=============================
|
||||||
} else if (value == F("pwm-out")) {
|
} else if (value == F("pwm-out")) {
|
||||||
//=============================
|
//=============================
|
||||||
|
} else if (value == F("analog-adc")) {
|
||||||
|
//=============================
|
||||||
} else {
|
} else {
|
||||||
SerialPrint(F("E"), F("Config"), F("config.json error, type not exist"));
|
SerialPrint(F("E"), F("Config"), F("config.json error, type not exist"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
TickerScheduler ts(MYTEST + 1);
|
TickerScheduler ts(MYTEST + 1);
|
||||||
WiFiClient espClient;
|
WiFiClient espClient;
|
||||||
PubSubClient mqtt(espClient);
|
PubSubClient mqtt(espClient);
|
||||||
|
StringCommand sCmd;
|
||||||
#ifdef ASYNC_WEB_SERVER
|
#ifdef ASYNC_WEB_SERVER
|
||||||
AsyncWebServer server(80);
|
AsyncWebServer server(80);
|
||||||
#endif
|
#endif
|
||||||
@@ -33,6 +34,10 @@ String settingsFlashJson = "{}"; //переменная в которой хр
|
|||||||
String paramsFlashJson = "{}"; //переменная в которой хранятся все параметры, находится в оперативной памяти и синхронизированна с flash памятью
|
String paramsFlashJson = "{}"; //переменная в которой хранятся все параметры, находится в оперативной памяти и синхронизированна с flash памятью
|
||||||
String paramsHeapJson = "{}"; //переменная в которой хранятся все параметры, находится в оперативной памяти только
|
String paramsHeapJson = "{}"; //переменная в которой хранятся все параметры, находится в оперативной памяти только
|
||||||
|
|
||||||
|
// buf
|
||||||
|
String orderBuf = "";
|
||||||
|
String eventBuf = "";
|
||||||
|
|
||||||
// Mqtt
|
// Mqtt
|
||||||
String mqttServer = "";
|
String mqttServer = "";
|
||||||
int mqttPort = 0;
|
int mqttPort = 0;
|
||||||
|
|||||||
39
src/classes/IoTSensor.cpp
Normal file
39
src/classes/IoTSensor.cpp
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#include "Utils/JsonUtils.h"
|
||||||
|
#include "Utils/SerialPrint.h"
|
||||||
|
#include "Classes/ScenarioClass3.h"
|
||||||
|
#include "Classes/IoTSensor.h"
|
||||||
|
|
||||||
|
void IoTSensor::init(String key, String id, unsigned long interval) {
|
||||||
|
_interval = interval * 1000;
|
||||||
|
_key = key;
|
||||||
|
_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
IoTSensor::IoTSensor() {}
|
||||||
|
IoTSensor::~IoTSensor() {}
|
||||||
|
|
||||||
|
String IoTSensor::getKey() {
|
||||||
|
return _key;
|
||||||
|
}
|
||||||
|
|
||||||
|
String IoTSensor::getID() {
|
||||||
|
return _id;
|
||||||
|
};
|
||||||
|
|
||||||
|
void IoTSensor::loop() {
|
||||||
|
currentMillis = millis();
|
||||||
|
difference = currentMillis - prevMillis;
|
||||||
|
if (difference >= _interval) {
|
||||||
|
prevMillis = millis();
|
||||||
|
this->doByInterval();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IoTSensor::regEvent(String value, String consoleInfo = "") {
|
||||||
|
eventGen2(_id, String(value));
|
||||||
|
jsonWriteStr(paramsFlashJson, _id, String(value));
|
||||||
|
publishStatus(_id, String(value));
|
||||||
|
SerialPrint("I", "Sensor", "'" + _id + "' data: " + String(value) + "' " + consoleInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IoTSensor::doByInterval() {}
|
||||||
3
src/classes/ScenarioClass3.cpp
Normal file
3
src/classes/ScenarioClass3.cpp
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#include "Classes/ScenarioClass3.h"
|
||||||
|
|
||||||
|
Scenario* myScenario;
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#include "Utils/Pretty.h"
|
|
||||||
|
|
||||||
String prettyBytes(size_t size) {
|
|
||||||
if (size < 1024)
|
|
||||||
return String(size) + "b";
|
|
||||||
else if (size < (1024 * 1024))
|
|
||||||
return String(size / 1024.0) + "kB";
|
|
||||||
else if (size < (1024 * 1024 * 1024))
|
|
||||||
return String(size / 1024.0 / 1024.0) + "MB";
|
|
||||||
else
|
|
||||||
return String(size / 1024.0 / 1024.0 / 1024.0) + "GB";
|
|
||||||
}
|
|
||||||
170
src/utils/StringUtils.cpp
Normal file
170
src/utils/StringUtils.cpp
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
#include "Utils/StringUtils.h"
|
||||||
|
|
||||||
|
String selectToMarkerLast(String str, String found) {
|
||||||
|
int p = str.lastIndexOf(found);
|
||||||
|
return str.substring(p + found.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
String selectToMarker(String str, String found) {
|
||||||
|
int p = str.indexOf(found);
|
||||||
|
return str.substring(0, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
String extractInner(String str) {
|
||||||
|
int p1 = str.indexOf("[");
|
||||||
|
int p2 = str.indexOf("]");
|
||||||
|
return str.substring(p1 + 1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
String deleteAfterDelimiter(String str, String found) {
|
||||||
|
int p = str.indexOf(found);
|
||||||
|
return str.substring(0, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
String deleteBeforeDelimiter(String str, String found) {
|
||||||
|
int p = str.indexOf(found) + found.length();
|
||||||
|
return str.substring(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
String deleteBeforeDelimiterTo(String str, String found) {
|
||||||
|
int p = str.indexOf(found);
|
||||||
|
return str.substring(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
String deleteToMarkerLast(String str, String found) {
|
||||||
|
int p = str.lastIndexOf(found);
|
||||||
|
return str.substring(0, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
String selectToMarkerPlus(String str, String found, int plus) {
|
||||||
|
int p = str.indexOf(found);
|
||||||
|
return str.substring(0, p + plus);
|
||||||
|
}
|
||||||
|
|
||||||
|
String selectFromMarkerToMarker(String str, String tofind, int number) {
|
||||||
|
if (str.indexOf(tofind) == -1) {
|
||||||
|
return "not found";
|
||||||
|
}
|
||||||
|
str += tofind; // добавим для корректного поиска
|
||||||
|
uint8_t i = 0; // Индекс перебора
|
||||||
|
do {
|
||||||
|
if (i == number) {
|
||||||
|
// если индекс совпал с позицией
|
||||||
|
return selectToMarker(str, tofind);
|
||||||
|
}
|
||||||
|
// отбросим проверенный блок до разделителя
|
||||||
|
str = deleteBeforeDelimiter(str, tofind);
|
||||||
|
i++;
|
||||||
|
} while (str.length() != 0);
|
||||||
|
|
||||||
|
return "not found";
|
||||||
|
}
|
||||||
|
|
||||||
|
//преобразовываем байтовый массив в человеческий вид HEX в строке
|
||||||
|
void hex2string(byte array[], unsigned int len, char buffer[]) {
|
||||||
|
for (unsigned int i = 0; i < len; i++) {
|
||||||
|
byte nib1 = (array[i] >> 4) & 0x0F;
|
||||||
|
byte nib2 = (array[i] >> 0) & 0x0F;
|
||||||
|
buffer[i * 2 + 0] = nib1 < 0xA ? '0' + nib1 : 'A' + nib1 - 0xA;
|
||||||
|
buffer[i * 2 + 1] = nib2 < 0xA ? '0' + nib2 : 'A' + nib2 - 0xA;
|
||||||
|
}
|
||||||
|
buffer[len * 2] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned char ChartoHex(char ch) {
|
||||||
|
return ((ch >= 'A') ? (ch - 'A' + 0xA) : (ch - '0')) & 0x0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
// str - указатель на массив символов
|
||||||
|
// bytes - выходной буфер
|
||||||
|
// функция возвращает колл-во байт
|
||||||
|
//
|
||||||
|
int string2hex(const char* str, unsigned char* bytes) {
|
||||||
|
unsigned char Hi, Lo;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while ((Hi = *str++) && (Lo = *str++)) {
|
||||||
|
bytes[i++] = (ChartoHex(Hi) << 4) | ChartoHex(Lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t hexStringToUint8(String hex) {
|
||||||
|
uint8_t tmp = strtol(hex.c_str(), NULL, 0);
|
||||||
|
if (tmp >= 0x00 && tmp <= 0xFF) {
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t hexStringToUint16(String hex) {
|
||||||
|
uint16_t tmp = strtol(hex.c_str(), NULL, 0);
|
||||||
|
if (tmp >= 0x0000 && tmp <= 0xFFFF) {
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t itemsCount2(String str, const String& separator) {
|
||||||
|
// если строки поиск нет сразу выход
|
||||||
|
if (str.indexOf(separator) == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// добавим для корректного поиска
|
||||||
|
str += separator;
|
||||||
|
size_t cnt = 0;
|
||||||
|
while (str.length()) {
|
||||||
|
// отбросим проверенный блок до разделителя
|
||||||
|
str = deleteBeforeDelimiter(str, separator);
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t itemsCount(String& str, const char* delim) {
|
||||||
|
size_t cnt = 0;
|
||||||
|
char* cstr = new char[str.length() + 1];
|
||||||
|
strcpy(cstr, str.c_str());
|
||||||
|
char* token;
|
||||||
|
while ((token = strtok_r(cstr, delim, &cstr))) {
|
||||||
|
cnt++;
|
||||||
|
// printf("%s\n", token);
|
||||||
|
}
|
||||||
|
delete[] cstr;
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* stringToChar(String& str) {
|
||||||
|
char* mychar = new char[str.length() + 1];
|
||||||
|
strcpy(mychar, str.c_str());
|
||||||
|
return mychar;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isDigitStr(const String& str) {
|
||||||
|
for (size_t i = 0; i < str.length(); i++) {
|
||||||
|
if (!isDigit(str.charAt(i))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isDigitDotCommaStr(const String& str) {
|
||||||
|
for (size_t i = 0; i < str.length(); i++) {
|
||||||
|
char latter = str.charAt(i);
|
||||||
|
if (!isDigit(latter) && latter != '.' && latter != '-') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String prettyBytes(size_t size) {
|
||||||
|
if (size < 1024)
|
||||||
|
return String(size) + "b";
|
||||||
|
else if (size < (1024 * 1024))
|
||||||
|
return String(size / 1024.0) + "kB";
|
||||||
|
else if (size < (1024 * 1024 * 1024))
|
||||||
|
return String(size / 1024.0 / 1024.0) + "MB";
|
||||||
|
else
|
||||||
|
return String(size / 1024.0 / 1024.0 / 1024.0) + "GB";
|
||||||
|
}
|
||||||
@@ -115,18 +115,18 @@ void breakEpochToTime(unsigned long epoch, Time_t& tm) {
|
|||||||
tm.valid = (epoch > MIN_DATETIME);
|
tm.valid = (epoch > MIN_DATETIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
//void timeInit() {
|
// void timeInit() {
|
||||||
// ts.add(
|
// ts.add(
|
||||||
// TIME, 1000, [&](void*) {
|
// TIME, 1000, [&](void*) {
|
||||||
// String timenow = timeNow->getTimeWOsec();
|
// String timenow = timeNow->getTimeWOsec();
|
||||||
// static String prevTime;
|
// static String prevTime;
|
||||||
// if (prevTime != timenow) {
|
// if (prevTime != timenow) {
|
||||||
// prevTime = timenow;
|
// prevTime = timenow;
|
||||||
// jsonWriteStr(configLiveJson, "timenow", timenow);
|
// jsonWriteStr(paramsFlashJson, "timenow", timenow);
|
||||||
// eventGen2("timenow", timenow);
|
// eventGen2("timenow", timenow);
|
||||||
// SerialPrint("i", F("NTP"), timenow);
|
// SerialPrint("i", F("NTP"), timenow);
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
// nullptr, true);
|
// nullptr, true);
|
||||||
// SerialPrint("i", F("NTP"), F("Handle time init"));
|
// SerialPrint("i", F("NTP"), F("Handle time init"));
|
||||||
//}
|
// }
|
||||||
|
|||||||
Reference in New Issue
Block a user