mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-27 06:32:19 +03:00
307 lines
10 KiB
C++
307 lines
10 KiB
C++
#include "Consts.h"
|
|
#ifdef EnableLogging
|
|
#include <Arduino.h>
|
|
|
|
#include "BufferExecute.h"
|
|
#include "Class/LineParsing.h"
|
|
#include "FileSystem.h"
|
|
#include "Global.h"
|
|
#include "items/vLogging.h"
|
|
|
|
LoggingClass::LoggingClass(String interval, unsigned int maxPoints, String loggingValueKey, String key, String startState, bool savedFromWeb) {
|
|
_interval = interval;
|
|
_maxPoints = maxPoints;
|
|
_loggingValueKey = loggingValueKey;
|
|
_key = key;
|
|
|
|
if (_interval.indexOf(":") != -1) {
|
|
_type = 3; //тип 3 логгирование в указанное время
|
|
_intervalSec = 1000;
|
|
if (savedFromWeb) { //если было сохранено из веб интерфейса
|
|
removeFile("/logs/prv" + _key + ".txt");
|
|
addFile("/logs/prv" + _key + ".txt", startState);
|
|
}
|
|
SerialPrint("I", "Logging", "at time (" + _interval + ")");
|
|
} else {
|
|
if (_interval.toInt() == 0) {
|
|
_type = 2; //тип 2 логгирование по событию
|
|
SerialPrint("I", "Logging", "by event");
|
|
} else if (_interval.toInt() > 0) {
|
|
_type = 1; //тип 1 логгирование через период
|
|
_intervalSec = _interval.toInt() * 1000;
|
|
SerialPrint("I", "Logging", "periodically (" + _interval + " sec)");
|
|
}
|
|
}
|
|
|
|
if (_type == 0) SerialPrint("E", "Logging", "type undetermine");
|
|
}
|
|
|
|
LoggingClass::~LoggingClass() {}
|
|
|
|
void LoggingClass::loop() {
|
|
if (_intervalSec > 0) {
|
|
currentMillis = millis();
|
|
difference = currentMillis - prevMillis;
|
|
if (difference >= _intervalSec) {
|
|
prevMillis = millis();
|
|
if (_type == 1) {
|
|
execute("");
|
|
} else if (_type == 2) {
|
|
} else if (_type == 3) {
|
|
String timenow = timeNow->getTimeWOsec();
|
|
static String prevTime;
|
|
if (prevTime != timenow) {
|
|
prevTime = timenow;
|
|
if (_interval == timenow) execute("");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void LoggingClass::execute(String keyOrValue) {
|
|
String loggingValue = "";
|
|
if (_type == 1) { //тип 1 логгирование через период
|
|
if (getValue(_loggingValueKey) != "no value") {
|
|
loggingValue = getValue(_loggingValueKey);
|
|
} else {
|
|
SerialPrint("E", "Logging", "'" + _loggingValueKey + "' value not found on this device");
|
|
}
|
|
} else if (_type == 2) { //тип 2 логгирование по событию
|
|
if (isDigitDotCommaStr(keyOrValue)) { //если это число или дробное число
|
|
loggingValue = keyOrValue;
|
|
} else { //если это ключ
|
|
if (getValue(_loggingValueKey) != "no value") {
|
|
loggingValue = getValue(keyOrValue);
|
|
} else {
|
|
SerialPrint("E", "Logging", "This value not found on this device");
|
|
}
|
|
}
|
|
} else if (_type == 3) { //тип 3 логгирование в указанное время
|
|
if (getValue(_loggingValueKey) != "no value") {
|
|
float prevValue = readFile("/logs/prv" + _key + ".txt", 100).toFloat();
|
|
float currentValue = getValue(_loggingValueKey).toFloat();
|
|
loggingValue = String(currentValue - prevValue);
|
|
removeFile("/logs/prv" + _key + ".txt");
|
|
addFile("/logs/prv" + _key + ".txt", String(currentValue));
|
|
} else {
|
|
SerialPrint("E", "Logging", "This value not found on this device");
|
|
}
|
|
}
|
|
|
|
String filename = "/logs/" + _key + ".txt";
|
|
|
|
size_t cnt = countLines(filename);
|
|
size_t sz = getFileSize(filename);
|
|
|
|
SerialPrint("I", "Logging", "http://" + WiFi.localIP().toString() + filename + " lines " + String(cnt, DEC) + ", size " + String(sz));
|
|
|
|
if ((cnt > _maxPoints + 1)) {
|
|
removeFile(filename);
|
|
SerialPrint("E", "Logging", "file been remooved: " + filename + " " + String(cnt) + ">" + String(_maxPoints));
|
|
cnt = 0;
|
|
}
|
|
|
|
if (loggingValue != "") {
|
|
if (cnt >= _maxPoints) { //удаляем старую строку и добавляем новую
|
|
String logData = readFile(filename, 20480); //10240
|
|
SerialPrint("I", "Logging", "Free heap " + String(ESP.getFreeHeap()));
|
|
if (logData == "large") {
|
|
SerialPrint("E", "Logging", "File is very large");
|
|
}
|
|
|
|
logData = deleteBeforeDelimiter(logData, "\r\n");
|
|
|
|
if (timeNow->hasTimeSynced()) {
|
|
logData += timeNow->getTimeUnix() + " " + loggingValue + "\r\n";
|
|
|
|
writeFile(filename, logData);
|
|
}
|
|
} else { //просто добавляем новую строку
|
|
if (timeNow->hasTimeSynced()) {
|
|
addFileLn(filename, timeNow->getTimeUnix() + " " + loggingValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
String buf = "{}";
|
|
jsonWriteInt(buf, "x", timeNow->getTimeUnix().toInt());
|
|
jsonWriteFloat(buf, "y1", loggingValue.toFloat());
|
|
buf = "{\"status\":[" + buf + "]}";
|
|
publishChart(_key, buf);
|
|
}
|
|
|
|
MyLoggingVector* myLogging = nullptr;
|
|
|
|
void logging() {
|
|
myLineParsing.update();
|
|
String loggingValueKey = myLineParsing.gval();
|
|
String key = myLineParsing.gkey();
|
|
String interval = myLineParsing.gint();
|
|
String maxcnt = myLineParsing.gcnt();
|
|
String startState = myLineParsing.gstate();
|
|
myLineParsing.clear();
|
|
|
|
logging_KeyList += key + ",";
|
|
|
|
logging_EnterCounter++;
|
|
addKey(key, logging_KeyList, logging_EnterCounter);
|
|
|
|
static bool firstTime = true;
|
|
if (firstTime) myLogging = new MyLoggingVector();
|
|
firstTime = false;
|
|
myLogging->push_back(LoggingClass(interval, maxcnt.toInt(), loggingValueKey, key, startState, savedFromWeb));
|
|
|
|
sCmd.addCommand(key.c_str(), loggingExecute);
|
|
}
|
|
|
|
void loggingExecute() {
|
|
String key = sCmd.order();
|
|
String value = sCmd.next();
|
|
int number = getKeyNum(key, logging_KeyList);
|
|
if (myLogging != nullptr) {
|
|
if (number != -1) {
|
|
myLogging->at(number).execute(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
void choose_log_date_and_sendWS() {
|
|
|
|
String all_line = logging_KeyList;
|
|
while (all_line.length() != 0) {
|
|
String tmp = selectToMarker(all_line, ",");
|
|
sendLogDataWS("/logs/" + tmp + ".txt", tmp);
|
|
all_line = deleteBeforeDelimiter(all_line, ",");
|
|
}
|
|
}
|
|
|
|
void sendLogDataWS(String file, String topic) {
|
|
File configFile = FileFS.open(file, "r");
|
|
if (!configFile) {
|
|
return;
|
|
}
|
|
configFile.seek(0, SeekSet);
|
|
int i = 0;
|
|
String buf = "{}";
|
|
String json_array;
|
|
String unix_time;
|
|
String value;
|
|
unsigned int psn;
|
|
unsigned int sz = configFile.size();
|
|
do {
|
|
i++;
|
|
psn = configFile.position();
|
|
String line = configFile.readStringUntil('\n');
|
|
unix_time = selectToMarker(line, " ");
|
|
jsonWriteInt(buf, "x", unix_time.toInt());
|
|
value = deleteBeforeDelimiter(line, " ");
|
|
jsonWriteFloat(buf, "y1", value.toFloat());
|
|
if (unix_time != "" || value != "") {
|
|
json_array += buf + ",";
|
|
}
|
|
int grafmax = jsonReadInt(configSetupJson, "grafmax");
|
|
if (grafmax != 0) {
|
|
if (i >= grafmax) {
|
|
json_array = "{\"status\":[" + json_array + "]}";
|
|
json_array.replace("},]}", "}]}");
|
|
// publishChart(topic, json_array);
|
|
|
|
// добавляем топик, выводим в ws
|
|
String path = mqttRootDevice + "/" + topic;
|
|
String json = "{}";
|
|
json=json_array;
|
|
jsonWriteStr(json, "topic", path);
|
|
ws.textAll(json);
|
|
|
|
|
|
json_array = "";
|
|
i = 0;
|
|
}
|
|
}
|
|
} while (psn < sz);
|
|
|
|
configFile.close();
|
|
|
|
json_array = "{\"status\":[" + json_array + "]}";
|
|
json_array.replace("},]}", "}]}");
|
|
//publishChart(topic, json_array);
|
|
|
|
// добавляем топик, выводим в ws
|
|
String path = mqttRootDevice + "/" + topic;
|
|
String json = "{}";
|
|
json=json_array;
|
|
jsonWriteStr(json, "topic", path);
|
|
ws.textAll(json);
|
|
|
|
}
|
|
|
|
void choose_log_date_and_send() {
|
|
|
|
String all_line = logging_KeyList;
|
|
while (all_line.length() != 0) {
|
|
String tmp = selectToMarker(all_line, ",");
|
|
sendLogData("/logs/" + tmp + ".txt", tmp);
|
|
all_line = deleteBeforeDelimiter(all_line, ",");
|
|
}
|
|
}
|
|
|
|
void sendLogData(String file, String topic) {
|
|
File configFile = FileFS.open(file, "r");
|
|
if (!configFile) {
|
|
return;
|
|
}
|
|
configFile.seek(0, SeekSet);
|
|
int i = 0;
|
|
String buf = "{}";
|
|
String json_array;
|
|
String unix_time;
|
|
String value;
|
|
unsigned int psn;
|
|
unsigned int sz = configFile.size();
|
|
do {
|
|
i++;
|
|
psn = configFile.position();
|
|
String line = configFile.readStringUntil('\n');
|
|
unix_time = selectToMarker(line, " ");
|
|
jsonWriteInt(buf, "x", unix_time.toInt());
|
|
value = deleteBeforeDelimiter(line, " ");
|
|
jsonWriteFloat(buf, "y1", value.toFloat());
|
|
if (unix_time != "" || value != "") {
|
|
json_array += buf + ",";
|
|
}
|
|
int grafmax = jsonReadInt(configSetupJson, "grafmax");
|
|
if (grafmax != 0) {
|
|
if (i >= grafmax) {
|
|
json_array = "{\"status\":[" + json_array + "]}";
|
|
json_array.replace("},]}", "}]}");
|
|
publishChart(topic, json_array);
|
|
|
|
json_array = "";
|
|
i = 0;
|
|
}
|
|
}
|
|
} while (psn < sz);
|
|
|
|
configFile.close();
|
|
|
|
json_array = "{\"status\":[" + json_array + "]}";
|
|
json_array.replace("},]}", "}]}");
|
|
publishChart(topic, json_array);
|
|
|
|
}
|
|
|
|
void cleanLogAndData() {
|
|
#ifdef ESP8266
|
|
auto dir = FileFS.openDir("logs");
|
|
while (dir.next()) {
|
|
String fname = dir.fileName();
|
|
SerialPrint("I", "System", fname);
|
|
removeFile("logs/" + fname);
|
|
}
|
|
#endif
|
|
removeFile("store.json");
|
|
configStoreJson = "";
|
|
}
|
|
#endif
|