mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-30 11:59:12 +03:00
добавление логирования
This commit is contained in:
@@ -35,6 +35,8 @@
|
|||||||
#define USE_LITTLEFS false
|
#define USE_LITTLEFS false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define START_DATETIME 1640995200 // 01.01.2022 00:00:00 константа для сокрацения unix time
|
||||||
|
|
||||||
#define MIN_DATETIME 1575158400
|
#define MIN_DATETIME 1575158400
|
||||||
#define LEAP_YEAR(Y) (((1970 + Y) > 0) && !((1970 + Y) % 4) && (((1970 + Y) % 100) || !((1970 + Y) % 400)))
|
#define LEAP_YEAR(Y) (((1970 + Y) > 0) && !((1970 + Y) % 4) && (((1970 + Y) % 100) || !((1970 + Y) % 400)))
|
||||||
|
|
||||||
|
|||||||
@@ -130,6 +130,8 @@ struct Time_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern unsigned long unixTime;
|
extern unsigned long unixTime;
|
||||||
|
extern unsigned long unixTimeShort;
|
||||||
|
|
||||||
extern bool isTimeSynch;
|
extern bool isTimeSynch;
|
||||||
extern Time_t _time_local;
|
extern Time_t _time_local;
|
||||||
extern Time_t _time_utc;
|
extern Time_t _time_utc;
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ void publishState();
|
|||||||
void mqttCallback(char* topic, uint8_t* payload, size_t length);
|
void mqttCallback(char* topic, uint8_t* payload, size_t length);
|
||||||
void handleMqttStatus(bool send);
|
void handleMqttStatus(bool send);
|
||||||
void handleMqttStatus(bool send, int state);
|
void handleMqttStatus(bool send, int state);
|
||||||
|
void sendAllFilesToMQTT();
|
||||||
|
void sendLogData(String file, String topic);
|
||||||
|
|
||||||
const String getStateStr(int e);
|
const String getStateStr(int e);
|
||||||
|
|
||||||
void mqttUptimeCalc();
|
void mqttUptimeCalc();
|
||||||
|
|||||||
@@ -10,4 +10,6 @@ extern const String addFileLn(const String& filename, const String& str);
|
|||||||
extern const String readFile(const String& filename, size_t max_size);
|
extern const String readFile(const String& filename, size_t max_size);
|
||||||
extern const String filepath(const String& filename);
|
extern const String filepath(const String& filename);
|
||||||
extern bool cutFile(const String& src, const String& dst);
|
extern bool cutFile(const String& src, const String& dst);
|
||||||
|
extern size_t countLines(const String filename);
|
||||||
|
void removeFile(const String& filename);
|
||||||
extern void onFlashWrite();
|
extern void onFlashWrite();
|
||||||
@@ -66,6 +66,8 @@ String mqttRootDevice = "";
|
|||||||
|
|
||||||
// Time
|
// Time
|
||||||
unsigned long unixTime = 0;
|
unsigned long unixTime = 0;
|
||||||
|
unsigned long unixTimeShort = 0;
|
||||||
|
|
||||||
bool isTimeSynch = false;
|
bool isTimeSynch = false;
|
||||||
Time_t _time_local;
|
Time_t _time_local;
|
||||||
Time_t _time_utc;
|
Time_t _time_utc;
|
||||||
|
|||||||
@@ -133,6 +133,9 @@ void mqttCallback(char* topic, uint8_t* payload, size_t length) {
|
|||||||
SerialPrint("i", F("MQTT"), F("Full update"));
|
SerialPrint("i", F("MQTT"), F("Full update"));
|
||||||
publishWidgets();
|
publishWidgets();
|
||||||
publishState();
|
publishState();
|
||||||
|
|
||||||
|
sendAllFilesToMQTT();
|
||||||
|
|
||||||
#ifdef GATE_MODE
|
#ifdef GATE_MODE
|
||||||
publishTimes();
|
publishTimes();
|
||||||
#endif
|
#endif
|
||||||
@@ -308,6 +311,52 @@ void handleMqttStatus(bool send, int state) {
|
|||||||
if (!send) standWebSocket.broadcastTXT(errorsHeapJson);
|
if (!send) standWebSocket.broadcastTXT(errorsHeapJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// log-20384820.txt
|
||||||
|
void sendAllFilesToMQTT() {
|
||||||
|
String directory = "logs";
|
||||||
|
SerialPrint("I", "Loging", "in directory '" + directory + "' files:");
|
||||||
|
auto dir = FileFS.openDir(directory);
|
||||||
|
while (dir.next()) {
|
||||||
|
String fname = dir.fileName();
|
||||||
|
String id = selectToMarker(fname, "-");
|
||||||
|
SerialPrint("I", "Loging", fname);
|
||||||
|
sendLogData("/logs/" + fname, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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() + START_DATETIME);
|
||||||
|
value = deleteBeforeDelimiter(line, " ");
|
||||||
|
jsonWriteFloat(buf, "y1", value.toFloat());
|
||||||
|
if (unix_time != "" || value != "") {
|
||||||
|
json_array += buf + ",";
|
||||||
|
}
|
||||||
|
} while (psn < sz);
|
||||||
|
|
||||||
|
configFile.close();
|
||||||
|
|
||||||
|
json_array = "{\"status\":[" + json_array + "]}";
|
||||||
|
json_array.replace("},]}", "}]}");
|
||||||
|
publishChart(topic, json_array);
|
||||||
|
}
|
||||||
|
|
||||||
const String getStateStr(int e) {
|
const String getStateStr(int e) {
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case -4: //Нет ответа от сервера
|
case -4: //Нет ответа от сервера
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ void ntpInit() {
|
|||||||
ts.add(
|
ts.add(
|
||||||
TIME, 1000, [&](void*) {
|
TIME, 1000, [&](void*) {
|
||||||
unixTime = getSystemTime();
|
unixTime = getSystemTime();
|
||||||
|
unixTimeShort = unixTime - START_DATETIME;
|
||||||
if (unixTime < MIN_DATETIME) {
|
if (unixTime < MIN_DATETIME) {
|
||||||
isTimeSynch = false;
|
isTimeSynch = false;
|
||||||
// SerialPrint("E", "NTP", "Time not synched");
|
// SerialPrint("E", "NTP", "Time not synched");
|
||||||
|
|||||||
@@ -957,7 +957,6 @@ void IoTScenario::loadScenario(String fileName) { // посимвольно с
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
delete strFromFile;
|
delete strFromFile;
|
||||||
strIterator = 0;
|
strIterator = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -968,7 +967,7 @@ void IoTScenario::loadScenario(String fileName) { // посимвольно с
|
|||||||
void IoTScenario::ExecScenario(String eventIdName) { // запускаем поочереди все корневые элементы выражений в сценарии, ожидаемо - это IFы
|
void IoTScenario::ExecScenario(String eventIdName) { // запускаем поочереди все корневые элементы выражений в сценарии, ожидаемо - это IFы
|
||||||
// eventIdName - ID элемента для которого выполняем сценарий, т.е. игнорируем любые проверки, если нет такого ID в условиях
|
// eventIdName - ID элемента для которого выполняем сценарий, т.е. игнорируем любые проверки, если нет такого ID в условиях
|
||||||
isIotScenException = false;
|
isIotScenException = false;
|
||||||
Serial.printf("Count root elements in scenario: %d\n", ScenarioElements.size());
|
// Serial.printf("Count root elements in scenario: %d\n", ScenarioElements.size());
|
||||||
for (unsigned int i = 0; i < ScenarioElements.size(); i++) {
|
for (unsigned int i = 0; i < ScenarioElements.size(); i++) {
|
||||||
if (ScenarioElements[i] && ScenarioElements[i]->hasEventIdName(eventIdName)) ScenarioElements[i]->exec();
|
if (ScenarioElements[i] && ScenarioElements[i]->hasEventIdName(eventIdName)) ScenarioElements[i]->exec();
|
||||||
// else Serial.printf("Call from ExecScenario: Skip ifexec because %s not found\n", eventIdName.c_str());
|
// else Serial.printf("Call from ExecScenario: Skip ifexec because %s not found\n", eventIdName.c_str());
|
||||||
|
|||||||
@@ -4,25 +4,63 @@
|
|||||||
class Loging : public IoTItem {
|
class Loging : public IoTItem {
|
||||||
private:
|
private:
|
||||||
String logval;
|
String logval;
|
||||||
|
String id;
|
||||||
|
String fileName = "";
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Loging(String parameters) : IoTItem(parameters) {
|
Loging(String parameters) : IoTItem(parameters) {
|
||||||
jsonRead(parameters, F("logid"), logval);
|
jsonRead(parameters, F("logid"), logval);
|
||||||
|
jsonRead(parameters, F("id"), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void doByInterval() {
|
void doByInterval() {
|
||||||
String value = getItemValue(logval);
|
String value = getItemValue(logval);
|
||||||
|
size_t lines = 0;
|
||||||
|
//если задано не правильное logid величины для логгирования
|
||||||
if (value == "") {
|
if (value == "") {
|
||||||
SerialPrint("E", F("Logging"), F("no value set"));
|
SerialPrint("E", F("Loging"), F("no value set"));
|
||||||
} else {
|
} else {
|
||||||
|
//если время было получено из интернета
|
||||||
if (isTimeSynch) {
|
if (isTimeSynch) {
|
||||||
regEvent(value, "Logging");
|
regEvent(value, "Loging");
|
||||||
String logData = String(unixTime) + " " + value;
|
String logData = String(unixTimeShort) + " " + value;
|
||||||
addFileLn("/log.txt", logData);
|
|
||||||
|
static bool firstTime = true;
|
||||||
|
//если зашли сюда первый раз то создаем файл с именем id-timestamp
|
||||||
|
if (firstTime) {
|
||||||
|
firstTime = false;
|
||||||
|
createFileWithIdDatatimeName(logData);
|
||||||
|
//если 2 ой раз и последующие разы
|
||||||
} else {
|
} else {
|
||||||
SerialPrint("E", F("Logging"), F("cant logging - no time Synch"));
|
lines = countLines(fileName);
|
||||||
|
if (lines <= 255) {
|
||||||
|
addFileLn(fileName, logData);
|
||||||
|
} else {
|
||||||
|
createFileWithIdDatatimeName(logData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SerialPrint("i", F("Loging"), "loging in file (" + String(lines) + ") http://" + WiFi.localIP().toString() + fileName);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
SerialPrint("E", F("Loging"), F("Сant loging - time not synchronized"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void createFileWithIdDatatimeName(String &logData) {
|
||||||
|
fileName = "/logs/" + id + "-" + String(unixTimeShort) + ".txt";
|
||||||
|
addFileLn(fileName, logData);
|
||||||
|
SerialPrint("i", F("Loging"), "file created http://" + WiFi.localIP().toString() + fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cleanLog() {
|
||||||
|
String directory = "logs/" + id;
|
||||||
|
auto dir = FileFS.openDir(directory);
|
||||||
|
while (dir.next()) {
|
||||||
|
String fname = dir.fileName();
|
||||||
|
removeFile(directory + "/" + fname);
|
||||||
|
SerialPrint("I", "Loging", fname + " deleted");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -158,8 +158,39 @@ bool cutFile(const String& src, const String& dst) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//функция считает количество строк в файле
|
||||||
|
size_t countLines(const String filename) {
|
||||||
|
size_t cnt = -1;
|
||||||
|
String path = filepath(filename);
|
||||||
|
auto file = FileFS.open(path, "r");
|
||||||
|
if (!file) {
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
file.seek(0, SeekSet);
|
||||||
|
size_t size = file.size();
|
||||||
|
size_t psn;
|
||||||
|
do {
|
||||||
|
cnt++;
|
||||||
|
file.readStringUntil('\n');
|
||||||
|
psn = file.position();
|
||||||
|
} while (psn < size);
|
||||||
|
file.close();
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//удаляем файл
|
||||||
|
void removeFile(const String& filename) {
|
||||||
|
String path = filepath(filename);
|
||||||
|
if (FileFS.exists(path)) {
|
||||||
|
if (!FileFS.remove(path)) {
|
||||||
|
SerialPrint("I", "Files", "remove " + path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SerialPrint("E", "Files", "not exist" + path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//счетчик количества записей на флешь за сеанс
|
||||||
void onFlashWrite() {
|
void onFlashWrite() {
|
||||||
flashWriteNumber++;
|
flashWriteNumber++;
|
||||||
SerialPrint(F("->"), F("FS"), F("write data on flash"));
|
SerialPrint(F("->"), F("FS"), F("write data on flash"));
|
||||||
|
|||||||
Reference in New Issue
Block a user