mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 14:12:16 +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 <TickerScheduler.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <StringCommand.h>
|
||||
|
||||
#ifdef ESP32
|
||||
#include "WiFi.h"
|
||||
@@ -46,6 +47,7 @@
|
||||
#include "Utils/FileUtils.h"
|
||||
#include "Utils/JsonUtils.h"
|
||||
#include "Utils/SerialPrint.h"
|
||||
#include "Utils/StringUtils.h"
|
||||
|
||||
/*********************************************************************************************************************
|
||||
*****************************************глобальные объекты классов***************************************************
|
||||
@@ -54,6 +56,7 @@
|
||||
extern TickerScheduler ts;
|
||||
extern WiFiClient espClient;
|
||||
extern PubSubClient mqtt;
|
||||
extern StringCommand sCmd;
|
||||
#ifdef ASYNC_WEB_SERVER
|
||||
extern AsyncWebServer server;
|
||||
#endif
|
||||
@@ -79,6 +82,10 @@ extern String settingsFlashJson;
|
||||
extern String paramsFlashJson;
|
||||
extern String paramsHeapJson;
|
||||
|
||||
// buf
|
||||
extern String orderBuf;
|
||||
extern String eventBuf;
|
||||
|
||||
// Mqtt
|
||||
extern String mqttServer;
|
||||
extern int mqttPort;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
//
|
||||
#include "EspFileSystem.h"
|
||||
#include "Global.h"
|
||||
#include "Utils/Pretty.h"
|
||||
#include "Utils/WiFiUtils.h"
|
||||
#include "AsyncWebServer.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) {
|
||||
// request->send(200, "application/json", configLiveJson);
|
||||
// request->send(200, "application/json", paramsFlashJson);
|
||||
//});
|
||||
//
|
||||
// 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("analog-adc")) {
|
||||
//=============================
|
||||
} else {
|
||||
SerialPrint(F("E"), F("Config"), F("config.json error, type not exist"));
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
TickerScheduler ts(MYTEST + 1);
|
||||
WiFiClient espClient;
|
||||
PubSubClient mqtt(espClient);
|
||||
StringCommand sCmd;
|
||||
#ifdef ASYNC_WEB_SERVER
|
||||
AsyncWebServer server(80);
|
||||
#endif
|
||||
@@ -33,6 +34,10 @@ String settingsFlashJson = "{}"; //переменная в которой хр
|
||||
String paramsFlashJson = "{}"; //переменная в которой хранятся все параметры, находится в оперативной памяти и синхронизированна с flash памятью
|
||||
String paramsHeapJson = "{}"; //переменная в которой хранятся все параметры, находится в оперативной памяти только
|
||||
|
||||
// buf
|
||||
String orderBuf = "";
|
||||
String eventBuf = "";
|
||||
|
||||
// Mqtt
|
||||
String mqttServer = "";
|
||||
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);
|
||||
}
|
||||
|
||||
//void timeInit() {
|
||||
// ts.add(
|
||||
// TIME, 1000, [&](void*) {
|
||||
// String timenow = timeNow->getTimeWOsec();
|
||||
// static String prevTime;
|
||||
// if (prevTime != timenow) {
|
||||
// prevTime = timenow;
|
||||
// jsonWriteStr(configLiveJson, "timenow", timenow);
|
||||
// eventGen2("timenow", timenow);
|
||||
// SerialPrint("i", F("NTP"), timenow);
|
||||
// }
|
||||
// },
|
||||
// nullptr, true);
|
||||
// SerialPrint("i", F("NTP"), F("Handle time init"));
|
||||
//}
|
||||
// void timeInit() {
|
||||
// ts.add(
|
||||
// TIME, 1000, [&](void*) {
|
||||
// String timenow = timeNow->getTimeWOsec();
|
||||
// static String prevTime;
|
||||
// if (prevTime != timenow) {
|
||||
// prevTime = timenow;
|
||||
// jsonWriteStr(paramsFlashJson, "timenow", timenow);
|
||||
// eventGen2("timenow", timenow);
|
||||
// SerialPrint("i", F("NTP"), timenow);
|
||||
// }
|
||||
// },
|
||||
// nullptr, true);
|
||||
// SerialPrint("i", F("NTP"), F("Handle time init"));
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user