mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-27 22:52:19 +03:00
recovery
This commit is contained in:
28
src/items/ButtonInClass.cpp
Normal file
28
src/items/ButtonInClass.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableButtonIn
|
||||
#include "BufferExecute.h"
|
||||
#include "items/ButtonInClass.h"
|
||||
//==========================================Модуль физических кнопок========================================
|
||||
//button-in switch1 toggle Кнопки Свет 1 pin[2] db[20]
|
||||
//==========================================================================================================
|
||||
|
||||
boolean but[NUM_BUTTONS];
|
||||
Bounce *buttons = new Bounce[NUM_BUTTONS];
|
||||
|
||||
ButtonInClass myButtonIn;
|
||||
void buttonIn() {
|
||||
myButtonIn.update();
|
||||
String key = myButtonIn.gkey();
|
||||
String pin = myButtonIn.gpin();
|
||||
sCmd.addCommand(key.c_str(), buttonInSet);
|
||||
myButtonIn.init();
|
||||
myButtonIn.switchStateSetDefault();
|
||||
myButtonIn.clear();
|
||||
}
|
||||
|
||||
void buttonInSet() {
|
||||
String key = sCmd.order();
|
||||
String state = sCmd.next();
|
||||
myButtonIn.switchChangeVirtual(key, state);
|
||||
}
|
||||
#endif
|
||||
47
src/items/test.cpp
Normal file
47
src/items/test.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
//#include "items/test.h"
|
||||
//#include "BufferExecute.h"
|
||||
//#include "Class/LineParsing.h"
|
||||
//#include "Global.h"
|
||||
//
|
||||
//// Outside of class
|
||||
//SensorImpulsIn *pointerToClass; // declare a pointer to SensorImpulsIn class
|
||||
//
|
||||
//static void outsideInterruptHandler(void) { // define global handler
|
||||
// pointerToClass->classInterruptHandler(); // calls class member handler
|
||||
//}
|
||||
//
|
||||
//SensorImpulsIn::SensorImpulsIn(const paramsImpulsIn& paramsImpuls) {
|
||||
// _paramsImpuls = paramsImpulsIn(paramsImpuls);
|
||||
//
|
||||
// pinMode(paramsImpuls.pin, INPUT);
|
||||
//
|
||||
// pointerToClass = this; // assign current instance to pointer (IMPORTANT!!!)
|
||||
// attachInterrupt(digitalPinToInterrupt(_paramsImpuls.pin), outsideInterruptHandler, CHANGE);
|
||||
//}
|
||||
//
|
||||
//MySensorImpulsInVector* mySensorImpulsIn = nullptr;
|
||||
//
|
||||
//void SensorImpulsIn::classInterruptHandler(void) {
|
||||
// localPointerToCallback(digitalRead(_paramsImpuls.pin));
|
||||
//}
|
||||
//
|
||||
//void impulsInSensor() {
|
||||
// myLineParsing.update();
|
||||
// String key = myLineParsing.gkey();
|
||||
// String pin = myLineParsing.gpin();
|
||||
// String c = myLineParsing.gc();
|
||||
// String k = myLineParsing.gk();
|
||||
// myLineParsing.clear();
|
||||
//
|
||||
// static paramsImpulsIn paramsImpuls;
|
||||
//
|
||||
// paramsImpuls.key = key;
|
||||
// paramsImpuls.pin = pin.toInt();
|
||||
// paramsImpuls.c = c.toFloat();
|
||||
// paramsImpuls.k = k.toFloat();
|
||||
//
|
||||
// static bool firstTime = true;
|
||||
// if (firstTime) mySensorImpulsIn = new MySensorImpulsInVector();
|
||||
// firstTime = false;
|
||||
// mySensorImpulsIn->push_back(SensorImpulsIn(paramsImpuls));
|
||||
//}
|
||||
94
src/items/vButtonOut.cpp
Normal file
94
src/items/vButtonOut.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableButtonOut
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Global.h"
|
||||
#include "SoftUART.h"
|
||||
#include "items/vButtonOut.h"
|
||||
//this class save data to flash
|
||||
ButtonOut::ButtonOut(String pin, boolean inv, String key, String type) {
|
||||
_pin = pin;
|
||||
_inv = inv;
|
||||
_key = key;
|
||||
_type = type;
|
||||
#ifdef ESP_MODE
|
||||
if (_pin != "") {
|
||||
pinMode(_pin.toInt(), OUTPUT);
|
||||
}
|
||||
int state = jsonReadInt(configStoreJson, key); //прочитали из памяти
|
||||
this->execute(String(state)); //установили это состояние
|
||||
#endif
|
||||
#ifdef GATE_MODE
|
||||
//TO DO запросили ноду о состоянии реле
|
||||
//установили в это состояние кнопку в приложении
|
||||
//если нода не ответила - кнопку сделать красным цветом
|
||||
#endif
|
||||
}
|
||||
ButtonOut::~ButtonOut() {}
|
||||
|
||||
void ButtonOut::execute(String state) {
|
||||
#ifdef ESP_MODE
|
||||
if (state != "" && _pin != "") {
|
||||
if (state == "change") {
|
||||
state = String(!digitalRead(_pin.toInt()));
|
||||
digitalWrite(_pin.toInt(), state.toInt());
|
||||
} else {
|
||||
if (_inv) {
|
||||
digitalWrite(_pin.toInt(), !state.toInt());
|
||||
} else {
|
||||
digitalWrite(_pin.toInt(), state.toInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef GATE_MODE
|
||||
//отправили ноде команду на вкл выкл
|
||||
//получили обратную связь - переставили кнопку в приложении
|
||||
//не получили обратную связь - сделали кнопку красной
|
||||
#endif
|
||||
eventGen2(_key, state);
|
||||
jsonWriteInt(configStoreJson, _key, state.toInt());
|
||||
saveStore();
|
||||
publishStatus(_key, state);
|
||||
}
|
||||
|
||||
MyButtonOutVector* myButtonOut = nullptr;
|
||||
|
||||
void buttonOut() {
|
||||
myLineParsing.update();
|
||||
String key = myLineParsing.gkey();
|
||||
String pin = myLineParsing.gpin();
|
||||
String inv = myLineParsing.ginv();
|
||||
String type = myLineParsing.gtype();
|
||||
|
||||
bool invb = false;
|
||||
if (inv.toInt() == 1) invb = true;
|
||||
|
||||
myLineParsing.clear();
|
||||
|
||||
buttonOut_EnterCounter++;
|
||||
addKey(key, buttonOut_KeyList, buttonOut_EnterCounter);
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) myButtonOut = new MyButtonOutVector();
|
||||
firstTime = false;
|
||||
myButtonOut->push_back(ButtonOut(pin, invb, key, type));
|
||||
|
||||
sCmd.addCommand(key.c_str(), buttonOutExecute);
|
||||
}
|
||||
|
||||
void buttonOutExecute() {
|
||||
String key = sCmd.order();
|
||||
String state = sCmd.next();
|
||||
|
||||
int number = getKeyNum(key, buttonOut_KeyList);
|
||||
|
||||
if (myButtonOut != nullptr) {
|
||||
if (number != -1) {
|
||||
myButtonOut->at(number).execute(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
79
src/items/vCountDown.cpp
Normal file
79
src/items/vCountDown.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableCountDown
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Global.h"
|
||||
#include "items/vCountDown.h"
|
||||
|
||||
CountDownClass::CountDownClass(String key) {
|
||||
_key = key;
|
||||
}
|
||||
|
||||
CountDownClass::~CountDownClass() {}
|
||||
|
||||
void CountDownClass::execute(unsigned int countDownPeriod) {
|
||||
_countDownPeriod = countDownPeriod * 1000;
|
||||
_start = true;
|
||||
}
|
||||
|
||||
void CountDownClass::loop() {
|
||||
if (_countDownPeriod > 0 && _start) {
|
||||
prevMillis = millis();
|
||||
sec = (_countDownPeriod / 1000);
|
||||
_start = false;
|
||||
}
|
||||
|
||||
difference = millis() - prevMillis;
|
||||
if (difference > 1000 && _countDownPeriod > 0) {
|
||||
prevMillis = millis();
|
||||
eventGen2(_key, String(sec));
|
||||
String time = String(prettyMillis(sec * 1000));
|
||||
jsonWriteStr(configLiveJson, _key, time);
|
||||
publishStatus(_key, time);
|
||||
sec--;
|
||||
if (sec < 0) {
|
||||
_countDownPeriod = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MyCountDownVector* myCountDown = nullptr;
|
||||
|
||||
void countDown() {
|
||||
myLineParsing.update();
|
||||
String key = myLineParsing.gkey();
|
||||
myLineParsing.clear();
|
||||
|
||||
countDown_EnterCounter++;
|
||||
addKey(key, countDown_KeyList, countDown_EnterCounter);
|
||||
|
||||
//Serial.println(countDown_EnterCounter);
|
||||
//Serial.println(countDown_KeyList);
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) myCountDown = new MyCountDownVector();
|
||||
firstTime = false;
|
||||
myCountDown->push_back(CountDownClass(key));
|
||||
|
||||
sCmd.addCommand(key.c_str(), countDownExecute);
|
||||
}
|
||||
|
||||
void countDownExecute() {
|
||||
String key = sCmd.order();
|
||||
String value = sCmd.next();
|
||||
|
||||
if (!isDigitStr(value)) { //если значение - текст
|
||||
value = getValue(value);
|
||||
}
|
||||
|
||||
int number = getKeyNum(key, countDown_KeyList);
|
||||
|
||||
if (myCountDown != nullptr) {
|
||||
if (number != -1) {
|
||||
myCountDown->at(number).execute(value.toInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
73
src/items/vImpulsOut.cpp
Normal file
73
src/items/vImpulsOut.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableImpulsOut
|
||||
#include "items/vImpulsOut.h"
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Global.h"
|
||||
#include "BufferExecute.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
ImpulsOutClass::ImpulsOutClass(unsigned int impulsPin) {
|
||||
_impulsPin = impulsPin;
|
||||
pinMode(impulsPin, OUTPUT);
|
||||
}
|
||||
|
||||
ImpulsOutClass::~ImpulsOutClass() {}
|
||||
|
||||
void ImpulsOutClass::execute(unsigned long impulsPeriod, unsigned int impulsCount) {
|
||||
_impulsPeriod = impulsPeriod;
|
||||
_impulsCount = impulsCount * 2;
|
||||
_impulsCountBuf = _impulsCount;
|
||||
}
|
||||
|
||||
void ImpulsOutClass::loop() {
|
||||
currentMillis = millis();
|
||||
difference = currentMillis - prevMillis;
|
||||
if (_impulsCountBuf > 0) {
|
||||
if (difference > _impulsPeriod) {
|
||||
_impulsCountBuf--;
|
||||
prevMillis = millis();
|
||||
yield();
|
||||
digitalWrite(_impulsPin, !digitalRead(_impulsPin));
|
||||
yield();
|
||||
}
|
||||
}
|
||||
if (_impulsCountBuf <= 0) {
|
||||
digitalWrite(_impulsPin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
MyImpulsOutVector* myImpulsOut = nullptr;
|
||||
|
||||
void impuls() {
|
||||
myLineParsing.update();
|
||||
String key = myLineParsing.gkey();
|
||||
String pin = myLineParsing.gpin();
|
||||
myLineParsing.clear();
|
||||
|
||||
impuls_EnterCounter++;
|
||||
addKey(key, impuls_KeyList, impuls_EnterCounter);
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) myImpulsOut = new MyImpulsOutVector();
|
||||
firstTime = false;
|
||||
myImpulsOut->push_back(ImpulsOutClass(pin.toInt()));
|
||||
|
||||
sCmd.addCommand(key.c_str(), impulsExecute);
|
||||
}
|
||||
|
||||
void impulsExecute() {
|
||||
String key = sCmd.order();
|
||||
String impulsPeriod = sCmd.next();
|
||||
String impulsCount = sCmd.next();
|
||||
|
||||
int number = getKeyNum(key, impuls_KeyList);
|
||||
|
||||
if (myImpulsOut != nullptr) {
|
||||
if (number != -1) {
|
||||
myImpulsOut->at(number).execute(impulsPeriod.toInt(), impulsCount.toInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
92
src/items/vInput.cpp
Normal file
92
src/items/vInput.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableInput
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Clock.h"
|
||||
#include "Global.h"
|
||||
#include "items/vInput.h"
|
||||
|
||||
//this class save date to flash
|
||||
Input::Input(String key, String widget) {
|
||||
_key = key;
|
||||
String value = jsonReadStr(configStoreJson, key);
|
||||
|
||||
if (value == "") {
|
||||
if (widget.indexOf("Digit") != -1) {
|
||||
value = "25";
|
||||
}
|
||||
if (widget.indexOf("Time") != -1) {
|
||||
value = "12:00";
|
||||
}
|
||||
}
|
||||
|
||||
this->execute(value);
|
||||
}
|
||||
Input::~Input() {}
|
||||
|
||||
void Input::execute(String value) {
|
||||
eventGen2(_key, value);
|
||||
jsonWriteStr(configStoreJson, _key, value);
|
||||
saveStore();
|
||||
publishStatus(_key, value);
|
||||
}
|
||||
|
||||
MyInputVector* myInput = nullptr;
|
||||
|
||||
void inputValue() {
|
||||
myLineParsing.update();
|
||||
String widget = myLineParsing.gfile();
|
||||
String key = myLineParsing.gkey();
|
||||
myLineParsing.clear();
|
||||
|
||||
input_EnterCounter++;
|
||||
addKey(key, input_KeyList, input_EnterCounter);
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) myInput = new MyInputVector();
|
||||
firstTime = false;
|
||||
myInput->push_back(Input(key, widget));
|
||||
|
||||
sCmd.addCommand(key.c_str(), inputExecute);
|
||||
}
|
||||
|
||||
void inputExecute() {
|
||||
String key = sCmd.order();
|
||||
String value = sCmd.next();
|
||||
|
||||
if (!isDigitStr(value)) { //если значение - текст
|
||||
if (value.indexOf(":") == -1) { //если этот текст не время
|
||||
if (value.indexOf("++") != -1) { //если тест - инкримент
|
||||
String prevValue = getValue(key);
|
||||
if (prevValue != "no value") {
|
||||
int prevValueInt = prevValue.toInt();
|
||||
prevValueInt++;
|
||||
value = String(prevValueInt);
|
||||
}
|
||||
} else if (value.indexOf("--") != -1) { //если тест - дикремент
|
||||
String prevValue = getValue(key);
|
||||
if (prevValue != "no value") {
|
||||
int prevValueInt = prevValue.toInt();
|
||||
prevValueInt--;
|
||||
value = String(prevValueInt);
|
||||
}
|
||||
} else { //остальные случаи любого текста
|
||||
String valueJson = getValue(value);
|
||||
if (valueJson != "no value") { //если это ключ переменной
|
||||
value = valueJson;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int number = getKeyNum(key, input_KeyList);
|
||||
|
||||
if (myInput != nullptr) {
|
||||
if (number != -1) {
|
||||
myInput->at(number).execute(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
233
src/items/vLogging.cpp
Normal file
233
src/items/vLogging.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
#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_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
|
||||
58
src/items/vOutput.cpp
Normal file
58
src/items/vOutput.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableOutput
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Clock.h"
|
||||
#include "Global.h"
|
||||
#include "items/vOutput.h"
|
||||
|
||||
Output::Output(String key) {
|
||||
_key = key;
|
||||
String value = jsonReadStr(configLiveJson, key);
|
||||
this->execute(value);
|
||||
}
|
||||
Output::~Output() {}
|
||||
|
||||
void Output::execute(String value) {
|
||||
eventGen2(_key, value);
|
||||
jsonWriteStr(configLiveJson, _key, value);
|
||||
publishStatus(_key, value);
|
||||
//publishLastUpdateTime(_key, timeNow->getTime());
|
||||
}
|
||||
|
||||
MyOutputVector* myOutput = nullptr;
|
||||
|
||||
void outputValue() {
|
||||
myLineParsing.update();
|
||||
String key = myLineParsing.gkey();
|
||||
myLineParsing.clear();
|
||||
|
||||
output_EnterCounter++;
|
||||
addKey(key, output_KeyList, output_EnterCounter);
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) myOutput = new MyOutputVector();
|
||||
firstTime = false;
|
||||
myOutput->push_back(Output(key));
|
||||
|
||||
sCmd.addCommand(key.c_str(), outputExecute);
|
||||
}
|
||||
|
||||
void outputExecute() {
|
||||
String key = sCmd.order();
|
||||
String value = sCmd.next();
|
||||
|
||||
value.replace("#", " ");
|
||||
value.replace("%date%", timeNow->getDateTimeDotFormated());
|
||||
|
||||
int number = getKeyNum(key, output_KeyList);
|
||||
|
||||
if (myOutput != nullptr) {
|
||||
if (number != -1) {
|
||||
myOutput->at(number).execute(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
61
src/items/vPwmOut.cpp
Normal file
61
src/items/vPwmOut.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnablePwmOut
|
||||
#include "items/vPwmOut.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Consts.h"
|
||||
#include "Global.h"
|
||||
|
||||
//this class save data to flash
|
||||
PwmOut::PwmOut(unsigned int pin, String key) {
|
||||
_pin = pin;
|
||||
_key = key;
|
||||
pinMode(_pin, OUTPUT);
|
||||
int state = jsonReadInt(configStoreJson, key);
|
||||
this->execute(String(state));
|
||||
}
|
||||
PwmOut::~PwmOut() {}
|
||||
|
||||
void PwmOut::execute(String state) {
|
||||
analogWrite(_pin, state.toInt());
|
||||
eventGen2(_key, state);
|
||||
jsonWriteInt(configStoreJson, _key, state.toInt());
|
||||
saveStore();
|
||||
publishStatus(_key, state);
|
||||
}
|
||||
|
||||
MyPwmOutVector* myPwmOut = nullptr;
|
||||
|
||||
void pwmOut() {
|
||||
myLineParsing.update();
|
||||
String key = myLineParsing.gkey();
|
||||
String pin = myLineParsing.gpin();
|
||||
myLineParsing.clear();
|
||||
|
||||
pwmOut_EnterCounter++;
|
||||
addKey(key, pwmOut_KeyList, pwmOut_EnterCounter);
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) myPwmOut = new MyPwmOutVector();
|
||||
firstTime = false;
|
||||
myPwmOut->push_back(PwmOut(pin.toInt(), key));
|
||||
|
||||
sCmd.addCommand(key.c_str(), pwmOutExecute);
|
||||
}
|
||||
|
||||
void pwmOutExecute() {
|
||||
String key = sCmd.order();
|
||||
String state = sCmd.next();
|
||||
|
||||
int number = getKeyNum(key, pwmOut_KeyList);
|
||||
|
||||
if (myPwmOut != nullptr) {
|
||||
if (number != -1) {
|
||||
myPwmOut->at(number).execute(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
72
src/items/vSensorAnalog.cpp
Normal file
72
src/items/vSensorAnalog.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableSensorAnalog
|
||||
#include "items/vSensorAnalog.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Global.h"
|
||||
#include "BufferExecute.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
SensorAnalog::SensorAnalog(String key, unsigned long interval, unsigned int adcPin, int map1, int map2, int map3, int map4, float c) {
|
||||
_interval = interval * 1000;
|
||||
_key = key;
|
||||
_adcPin = adcPin;
|
||||
|
||||
_map1 = map1;
|
||||
_map2 = map2;
|
||||
_map3 = map3;
|
||||
_map4 = map4;
|
||||
|
||||
_c = c;
|
||||
}
|
||||
|
||||
SensorAnalog::~SensorAnalog() {}
|
||||
|
||||
void SensorAnalog::loop() {
|
||||
currentMillis = millis();
|
||||
difference = currentMillis - prevMillis;
|
||||
if (difference >= _interval) {
|
||||
prevMillis = millis();
|
||||
readAnalog();
|
||||
}
|
||||
}
|
||||
|
||||
void SensorAnalog::readAnalog() {
|
||||
int value;
|
||||
#ifdef ESP32
|
||||
value = analogRead(_adcPin);
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
value = analogRead(A0);
|
||||
#endif
|
||||
|
||||
value = map(value, _map1, _map2, _map3, _map4);
|
||||
float valueFloat = value * _c;
|
||||
|
||||
eventGen2(_key, String(valueFloat));
|
||||
jsonWriteStr(configLiveJson, _key, String(valueFloat));
|
||||
publishStatus(_key, String(valueFloat));
|
||||
SerialPrint("I", "Sensor", "'" + _key + "' data: " + String(valueFloat));
|
||||
}
|
||||
|
||||
MySensorAnalogVector* mySensorAnalog = nullptr;
|
||||
|
||||
void analogAdc() {
|
||||
myLineParsing.update();
|
||||
String interval = myLineParsing.gint();
|
||||
String pin = myLineParsing.gpin();
|
||||
String key = myLineParsing.gkey();
|
||||
String map = myLineParsing.gmap();
|
||||
String c = myLineParsing.gc();
|
||||
myLineParsing.clear();
|
||||
|
||||
int map1 = selectFromMarkerToMarker(map, ",", 0).toInt();
|
||||
int map2 = selectFromMarkerToMarker(map, ",", 1).toInt();
|
||||
int map3 = selectFromMarkerToMarker(map, ",", 2).toInt();
|
||||
int map4 = selectFromMarkerToMarker(map, ",", 3).toInt();
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) mySensorAnalog = new MySensorAnalogVector();
|
||||
firstTime = false;
|
||||
mySensorAnalog->push_back(SensorAnalog(key, interval.toInt(), pin.toInt(), map1, map2, map3, map4, c.toFloat()));
|
||||
}
|
||||
#endif
|
||||
103
src/items/vSensorBme280.cpp
Normal file
103
src/items/vSensorBme280.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableSensorBme280
|
||||
#include "items/vSensorBme280.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Global.h"
|
||||
|
||||
Adafruit_BME280* bme = nullptr;
|
||||
|
||||
SensorBme280::SensorBme280(const paramsBme& paramsTmp, const paramsBme& paramsHum, const paramsBme& paramsPrs) {
|
||||
_paramsTmp = paramsBme(paramsTmp);
|
||||
_paramsHum = paramsBme(paramsHum);
|
||||
_paramsPrs = paramsBme(paramsPrs);
|
||||
|
||||
if (!bme) {
|
||||
bme = new Adafruit_BME280;
|
||||
}
|
||||
|
||||
bme->getTemperatureSensor();
|
||||
bme->getPressureSensor();
|
||||
bme->getHumiditySensor();
|
||||
bme->begin(hexStringToUint8(_paramsPrs.addr));
|
||||
}
|
||||
|
||||
SensorBme280::~SensorBme280() {}
|
||||
|
||||
void SensorBme280::loop() {
|
||||
difference = millis() - prevMillis;
|
||||
if (difference >= _paramsPrs.interval) {
|
||||
prevMillis = millis();
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
void SensorBme280::read() {
|
||||
float tmp = bme->readTemperature();
|
||||
float hum = bme->readHumidity();
|
||||
float prs = bme->readPressure();
|
||||
prs = prs / 1.333224 / 100;
|
||||
|
||||
tmp = tmp * _paramsTmp.c;
|
||||
hum = hum * _paramsHum.c;
|
||||
prs = prs * _paramsPrs.c;
|
||||
|
||||
eventGen2(_paramsTmp.key, String(tmp));
|
||||
jsonWriteStr(configLiveJson, _paramsTmp.key, String(tmp));
|
||||
publishStatus(_paramsTmp.key, String(tmp));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsTmp.key + "' data: " + String(tmp));
|
||||
|
||||
eventGen2(_paramsHum.key, String(hum));
|
||||
jsonWriteStr(configLiveJson, _paramsHum.key, String(hum));
|
||||
publishStatus(_paramsHum.key, String(hum));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsHum.key + "' data: " + String(hum));
|
||||
|
||||
eventGen2(_paramsPrs.key, String(prs));
|
||||
jsonWriteStr(configLiveJson, _paramsPrs.key, String(prs));
|
||||
publishStatus(_paramsPrs.key, String(prs));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsPrs.key + "' data: " + String(prs));
|
||||
}
|
||||
|
||||
MySensorBme280Vector* mySensorBme280 = nullptr;
|
||||
|
||||
void bme280Sensor() {
|
||||
myLineParsing.update();
|
||||
String key = myLineParsing.gkey();
|
||||
String addr = myLineParsing.gaddr();
|
||||
String interval = myLineParsing.gint();
|
||||
String c = myLineParsing.gc();
|
||||
myLineParsing.clear();
|
||||
|
||||
static int enterCnt = -1;
|
||||
enterCnt++;
|
||||
|
||||
static paramsBme paramsTmp;
|
||||
static paramsBme paramsHum;
|
||||
static paramsBme paramsPrs;
|
||||
|
||||
if (enterCnt == 0) {
|
||||
paramsTmp.key = key;
|
||||
paramsTmp.c = c.toFloat();
|
||||
}
|
||||
|
||||
if (enterCnt == 1) {
|
||||
paramsHum.key = key;
|
||||
paramsHum.c = c.toFloat();
|
||||
}
|
||||
|
||||
if (enterCnt == 2) {
|
||||
paramsPrs.key = key;
|
||||
paramsPrs.addr = addr;
|
||||
paramsPrs.interval = interval.toInt() * 1000;
|
||||
paramsPrs.c = c.toFloat();
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) mySensorBme280 = new MySensorBme280Vector();
|
||||
firstTime = false;
|
||||
mySensorBme280->push_back(SensorBme280(paramsTmp, paramsHum, paramsPrs));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
89
src/items/vSensorBmp280.cpp
Normal file
89
src/items/vSensorBmp280.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableSensorBmp280
|
||||
#include "items/vSensorBmp280.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Global.h"
|
||||
|
||||
Adafruit_BMP280* bmp = nullptr;
|
||||
|
||||
SensorBmp280::SensorBmp280(const paramsBmp& paramsTmp, const paramsBmp& paramsPrs) {
|
||||
_paramsTmp = paramsBmp(paramsTmp);
|
||||
_paramsPrs = paramsBmp(paramsPrs);
|
||||
|
||||
if (!bmp) {
|
||||
bmp = new Adafruit_BMP280;
|
||||
}
|
||||
|
||||
bmp->getTemperatureSensor();
|
||||
bmp->getPressureSensor();
|
||||
bmp->begin(hexStringToUint8(_paramsPrs.addr));
|
||||
}
|
||||
|
||||
SensorBmp280::~SensorBmp280() {}
|
||||
|
||||
void SensorBmp280::loop() {
|
||||
difference = millis() - prevMillis;
|
||||
if (difference >= _paramsPrs.interval) {
|
||||
prevMillis = millis();
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
void SensorBmp280::read() {
|
||||
float tmp = bmp->readTemperature();
|
||||
float prs = bmp->readPressure();
|
||||
prs = prs / 1.333224 / 100;
|
||||
|
||||
tmp = tmp * _paramsTmp.c;
|
||||
prs = prs * _paramsPrs.c;
|
||||
|
||||
eventGen2(_paramsTmp.key, String(tmp));
|
||||
jsonWriteStr(configLiveJson, _paramsTmp.key, String(tmp));
|
||||
publishStatus(_paramsTmp.key, String(tmp));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsTmp.key + "' data: " + String(tmp));
|
||||
|
||||
eventGen2(_paramsPrs.key, String(prs));
|
||||
jsonWriteStr(configLiveJson, _paramsPrs.key, String(prs));
|
||||
publishStatus(_paramsPrs.key, String(prs));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsPrs.key + "' data: " + String(prs));
|
||||
}
|
||||
|
||||
MySensorBmp280Vector* mySensorBmp280 = nullptr;
|
||||
|
||||
void bmp280Sensor() {
|
||||
myLineParsing.update();
|
||||
String key = myLineParsing.gkey();
|
||||
String addr = myLineParsing.gaddr();
|
||||
String interval = myLineParsing.gint();
|
||||
String c = myLineParsing.gc();
|
||||
myLineParsing.clear();
|
||||
|
||||
static int enterCnt = -1;
|
||||
enterCnt++;
|
||||
|
||||
static paramsBmp paramsTmp;
|
||||
static paramsBmp paramsHum;
|
||||
static paramsBmp paramsPrs;
|
||||
|
||||
if (enterCnt == 0) {
|
||||
paramsTmp.key = key;
|
||||
paramsTmp.c = c.toFloat();
|
||||
}
|
||||
|
||||
if (enterCnt == 1) {
|
||||
paramsPrs.key = key;
|
||||
paramsPrs.addr = addr;
|
||||
paramsPrs.interval = interval.toInt() * 1000;
|
||||
paramsPrs.c = c.toFloat();
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) mySensorBmp280 = new MySensorBmp280Vector();
|
||||
firstTime = false;
|
||||
mySensorBmp280->push_back(SensorBmp280(paramsTmp, paramsPrs));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
92
src/items/vSensorCcs811.cpp
Normal file
92
src/items/vSensorCcs811.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableSensorCcs811
|
||||
#include "items/vSensorCcs811.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Global.h"
|
||||
|
||||
SensorCcs811::SensorCcs811(const paramsCcs811& paramsPpm, const paramsCcs811& paramsPpb) {
|
||||
_paramsPpm = paramsCcs811(paramsPpm);
|
||||
_paramsPpb = paramsCcs811(paramsPpb);
|
||||
|
||||
ccs811 = new Adafruit_CCS811();
|
||||
|
||||
if (!ccs811->begin(hexStringToUint8(_paramsPpb.addr))) SerialPrint("E", "Sensor CCS", "Wire not connected");
|
||||
}
|
||||
|
||||
SensorCcs811::~SensorCcs811() {}
|
||||
|
||||
void SensorCcs811::loop() {
|
||||
difference = millis() - prevMillis;
|
||||
if (difference >= _paramsPpb.interval) {
|
||||
prevMillis = millis();
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
void SensorCcs811::read() {
|
||||
float co2;
|
||||
float ppm;
|
||||
if (ccs811->available()) {
|
||||
if (!ccs811->readData()) {
|
||||
co2 = ccs811->geteCO2();
|
||||
ppm = ccs811->getTVOC();
|
||||
|
||||
co2 = co2 * _paramsPpm.c;
|
||||
ppm = ppm * _paramsPpb.c;
|
||||
|
||||
eventGen2(_paramsPpm.key, String(co2));
|
||||
jsonWriteStr(configLiveJson, _paramsPpm.key, String(co2));
|
||||
publishStatus(_paramsPpm.key, String(co2));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsPpm.key + "' data: " + String(co2));
|
||||
|
||||
eventGen2(_paramsPpb.key, String(ppm));
|
||||
jsonWriteStr(configLiveJson, _paramsPpb.key, String(ppm));
|
||||
publishStatus(_paramsPpb.key, String(ppm));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsPpb.key + "' data: " + String(ppm));
|
||||
} else {
|
||||
SerialPrint("E", "Sensor CCS", "Error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MySensorCcs811Vector* mySensorCcs811 = nullptr;
|
||||
|
||||
void ccs811Sensor() {
|
||||
myLineParsing.update();
|
||||
String key = myLineParsing.gkey();
|
||||
String addr = myLineParsing.gaddr();
|
||||
String interval = myLineParsing.gint();
|
||||
String c = myLineParsing.gc();
|
||||
myLineParsing.clear();
|
||||
|
||||
static int enterCnt = -1;
|
||||
enterCnt++;
|
||||
|
||||
static paramsCcs811 paramsPpm;
|
||||
static paramsCcs811 paramsPpb;
|
||||
|
||||
if (enterCnt == 0) {
|
||||
paramsPpm.key = key;
|
||||
paramsPpm.interval = interval.toInt() * 1000;
|
||||
paramsPpm.c = c.toFloat();
|
||||
}
|
||||
|
||||
if (enterCnt == 1) {
|
||||
paramsPpb.key = key;
|
||||
paramsPpb.addr = addr;
|
||||
paramsPpb.interval = interval.toInt() * 1000;
|
||||
paramsPpb.c = c.toFloat();
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) mySensorCcs811 = new MySensorCcs811Vector();
|
||||
firstTime = false;
|
||||
mySensorCcs811->push_back(SensorCcs811(paramsPpm, paramsPpb));
|
||||
|
||||
enterCnt = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
60
src/items/vSensorDallas.cpp
Normal file
60
src/items/vSensorDallas.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableSensorDallas
|
||||
#include "items/vSensorDallas.h"
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Global.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
OneWire* oneWire;
|
||||
DallasTemperature sensors;
|
||||
|
||||
SensorDallas::SensorDallas(unsigned long interval, unsigned int pin, unsigned int index, String key) {
|
||||
_interval = interval * 1000;
|
||||
_key = key;
|
||||
_pin = pin;
|
||||
_index = index;
|
||||
|
||||
oneWire = new OneWire((uint8_t)_pin);
|
||||
sensors.setOneWire(oneWire);
|
||||
sensors.begin();
|
||||
sensors.setResolution(12);
|
||||
}
|
||||
|
||||
SensorDallas::~SensorDallas() {}
|
||||
|
||||
void SensorDallas::loop() {
|
||||
currentMillis = millis();
|
||||
difference = currentMillis - prevMillis;
|
||||
if (difference >= _interval) {
|
||||
prevMillis = millis();
|
||||
readDallas();
|
||||
}
|
||||
}
|
||||
|
||||
void SensorDallas::readDallas() {
|
||||
sensors.requestTemperaturesByIndex(_index);
|
||||
float value = sensors.getTempCByIndex(_index);
|
||||
eventGen2(_key, String(value));
|
||||
jsonWriteStr(configLiveJson, _key, String(value));
|
||||
publishStatus(_key, String(value));
|
||||
SerialPrint("I", "Sensor", "'" + _key + "' data: " + String(value));
|
||||
}
|
||||
|
||||
MySensorDallasVector* mySensorDallas2 = nullptr;
|
||||
|
||||
void dallas() {
|
||||
myLineParsing.update();
|
||||
String interval = myLineParsing.gint();
|
||||
String pin = myLineParsing.gpin();
|
||||
String index = myLineParsing.gindex();
|
||||
String key = myLineParsing.gkey();
|
||||
myLineParsing.clear();
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) mySensorDallas2 = new MySensorDallasVector();
|
||||
firstTime = false;
|
||||
mySensorDallas2->push_back(SensorDallas(interval.toInt(), pin.toInt(), index.toInt(), key));
|
||||
}
|
||||
#endif
|
||||
97
src/items/vSensorDht.cpp
Normal file
97
src/items/vSensorDht.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableSensorDht
|
||||
#include "items/vSensorDht.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Global.h"
|
||||
|
||||
SensorDht::SensorDht(const paramsDht& paramsTmp, const paramsDht& paramsHum) {
|
||||
_paramsTmp = paramsDht(paramsTmp);
|
||||
_paramsHum = paramsDht(paramsHum);
|
||||
|
||||
dht = new DHTesp();
|
||||
|
||||
if (_paramsHum.type == "dht11") {
|
||||
dht->setup(_paramsHum.pin, DHTesp::DHT11);
|
||||
} else if (_paramsHum.type == "dht22") {
|
||||
dht->setup(_paramsHum.pin, DHTesp::DHT22);
|
||||
}
|
||||
|
||||
_paramsHum.interval = _paramsHum.interval + dht->getMinimumSamplingPeriod();
|
||||
}
|
||||
|
||||
SensorDht::~SensorDht() {}
|
||||
|
||||
void SensorDht::loop() {
|
||||
difference = millis() - prevMillis;
|
||||
if (difference >= _paramsHum.interval) {
|
||||
prevMillis = millis();
|
||||
readTmpHum();
|
||||
}
|
||||
}
|
||||
|
||||
void SensorDht::readTmpHum() {
|
||||
float tmp = dht->getTemperature();
|
||||
float hum = dht->getHumidity();
|
||||
|
||||
if (String(tmp) != "nan" && String(hum) != "nan") {
|
||||
tmp = tmp * _paramsTmp.c;
|
||||
hum = hum * _paramsHum.c;
|
||||
|
||||
eventGen2(_paramsTmp.key, String(tmp));
|
||||
jsonWriteStr(configLiveJson, _paramsTmp.key, String(tmp));
|
||||
publishStatus(_paramsTmp.key, String(tmp));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsTmp.key + "' data: " + String(tmp));
|
||||
|
||||
eventGen2(_paramsHum.key, String(hum));
|
||||
jsonWriteStr(configLiveJson, _paramsHum.key, String(hum));
|
||||
publishStatus(_paramsHum.key, String(hum));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsHum.key + "' data: " + String(hum));
|
||||
|
||||
} else {
|
||||
SerialPrint("E", "Sensor DHT", "Error");
|
||||
}
|
||||
}
|
||||
|
||||
MySensorDhtVector* mySensorDht = nullptr;
|
||||
|
||||
void dhtSensor() {
|
||||
myLineParsing.update();
|
||||
String type = myLineParsing.gtype();
|
||||
String interval = myLineParsing.gint();
|
||||
String pin = myLineParsing.gpin();
|
||||
String key = myLineParsing.gkey();
|
||||
String c = myLineParsing.gc();
|
||||
myLineParsing.clear();
|
||||
|
||||
static int enterCnt = -1;
|
||||
enterCnt++;
|
||||
|
||||
static paramsDht paramsTmp;
|
||||
static paramsDht paramsHum;
|
||||
|
||||
if (enterCnt == 0) {
|
||||
paramsTmp.key = key;
|
||||
paramsTmp.interval = interval.toInt() * 1000;
|
||||
paramsTmp.c = c.toFloat();
|
||||
}
|
||||
|
||||
if (enterCnt == 1) {
|
||||
paramsHum.type = type;
|
||||
paramsHum.key = key;
|
||||
paramsHum.interval = interval.toInt() * 1000;
|
||||
paramsHum.pin = pin.toInt();
|
||||
paramsHum.c = c.toFloat();
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) mySensorDht = new MySensorDhtVector();
|
||||
firstTime = false;
|
||||
mySensorDht->push_back(SensorDht(paramsTmp, paramsHum));
|
||||
|
||||
enterCnt = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
51
src/items/vSensorImpulsIn.cpp
Normal file
51
src/items/vSensorImpulsIn.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
//#include "items/vSensorImpulsIn.h"
|
||||
//
|
||||
//#include "BufferExecute.h"
|
||||
//#include "Class/LineParsing.h"
|
||||
//#include "Global.h"
|
||||
//#include "SoftUART.h"
|
||||
//
|
||||
//SensorImpulsIn::SensorImpulsIn(const paramsImpulsIn& paramsImpuls) {
|
||||
// _paramsImpuls = paramsImpulsIn(paramsImpuls);
|
||||
// pinMode(14, INPUT);
|
||||
// //pinMode(_paramsImpuls.pin, INPUT_PULLUP);
|
||||
// //attachInterrupt(digitalPinToInterrupt(14), MYinterrupt, CHANGE);
|
||||
//}
|
||||
//
|
||||
//SensorImpulsIn::~SensorImpulsIn() {}
|
||||
//
|
||||
////void SensorImpulsIn::read() {
|
||||
// float voltage; //= (impulsIn->values()->voltage * _paramsV.c) + _paramsV.k;
|
||||
//
|
||||
// eventGen2(_paramsImpuls.key, String(voltage));
|
||||
// jsonWriteStr(configLiveJson, _paramsImpuls.key, String(voltage));
|
||||
// publishStatus(_paramsImpuls.key, String(voltage));
|
||||
// SerialPrint("I", "Sensor", "'" + _paramsImpuls.key + "' data: " + String(voltage));
|
||||
//}
|
||||
//
|
||||
//MySensorImpulsInVector* mySensorImpulsIn = nullptr;
|
||||
//
|
||||
//void impulsInSensor() {
|
||||
// myLineParsing.update();
|
||||
// String key = myLineParsing.gkey();
|
||||
// String pin = myLineParsing.gpin();
|
||||
// String c = myLineParsing.gc();
|
||||
// String k = myLineParsing.gk();
|
||||
// myLineParsing.clear();
|
||||
//
|
||||
// static paramsImpulsIn paramsImpuls;
|
||||
//
|
||||
// paramsImpuls.key = key;
|
||||
// paramsImpuls.pin = pin.toInt();
|
||||
// paramsImpuls.c = c.toFloat();
|
||||
// paramsImpuls.k = k.toFloat();
|
||||
//
|
||||
// static bool firstTime = true;
|
||||
// if (firstTime) mySensorImpulsIn = new MySensorImpulsInVector();
|
||||
// firstTime = false;
|
||||
// mySensorImpulsIn->push_back(SensorImpulsIn(paramsImpuls));
|
||||
//}
|
||||
//
|
||||
//void MYinterrupt() {
|
||||
// Serial.println("interrupt!");
|
||||
//}
|
||||
97
src/items/vSensorNode.cpp
Normal file
97
src/items/vSensorNode.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableSensorNode
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Clock.h"
|
||||
#include "Global.h"
|
||||
#include "Utils/TimeUtils.h"
|
||||
#include "items/vSensorNode.h"
|
||||
|
||||
SensorNode::SensorNode(const paramsSensorNode& params) {
|
||||
_params = paramsSensorNode(params);
|
||||
_updateTime = "";
|
||||
_minutesPassed = 0;
|
||||
}
|
||||
|
||||
SensorNode::~SensorNode() {}
|
||||
|
||||
void SensorNode::loop() {
|
||||
difference = millis() - prevMillis;
|
||||
if (difference >= 60000) {
|
||||
prevMillis = millis();
|
||||
_minutesPassed++;
|
||||
this->publish();
|
||||
}
|
||||
}
|
||||
|
||||
void SensorNode::onChange(String newValue, String incommingKey) {
|
||||
if (_params.key == incommingKey) {
|
||||
_minutesPassed = 0;
|
||||
prevMillis = millis();
|
||||
|
||||
newValue = String(newValue.toFloat() * _params.c);
|
||||
newValue = String(newValue.toFloat() + _params.k);
|
||||
|
||||
eventGen2(_params.key, newValue);
|
||||
jsonWriteStr(configLiveJson, _params.key, newValue);
|
||||
publishStatus(_params.key, newValue);
|
||||
|
||||
_updateTime = timeNow->getDateTimeDotFormated();
|
||||
|
||||
this->publish();
|
||||
//SerialPrint("I", "Sensor", "'" + _params.key + "' data: " + newValue);
|
||||
}
|
||||
}
|
||||
|
||||
void SensorNode::publish() {
|
||||
if (_minutesPassed < _params.tm1.toInt()) {
|
||||
publishAnyJsonKey(_params.key, "info", String(_minutesPassed) + " min");
|
||||
publishAnyJsonKey(_params.key, "color", "");
|
||||
} else if (_minutesPassed >= _params.tm1.toInt() && _minutesPassed < _params.tm2.toInt()) {
|
||||
publishAnyJsonKey(_params.key, "info", String(_minutesPassed) + " min");
|
||||
publishAnyJsonKey(_params.key, "color", "orange");
|
||||
} else if (_minutesPassed >= _params.tm2.toInt()) {
|
||||
if (_updateTime == "") {
|
||||
publishAnyJsonKey(_params.key, "info", "offline");
|
||||
} else {
|
||||
publishAnyJsonKey(_params.key, "info", _updateTime);
|
||||
}
|
||||
publishAnyJsonKey(_params.key, "color", "red");
|
||||
}
|
||||
}
|
||||
|
||||
MySensorNodeVector* mySensorNode = nullptr;
|
||||
|
||||
void nodeSensor() {
|
||||
myLineParsing.update();
|
||||
String tm1 = myLineParsing.gtm1();
|
||||
String tm2 = myLineParsing.gtm2();
|
||||
String key = myLineParsing.gkey();
|
||||
String c = myLineParsing.gc();
|
||||
String k = myLineParsing.gk();
|
||||
myLineParsing.clear();
|
||||
|
||||
paramsSensorNode params;
|
||||
|
||||
params.tm1 = tm1;
|
||||
params.tm2 = tm2;
|
||||
params.key = key;
|
||||
params.c = c.toFloat();
|
||||
params.k = k.toFloat();
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) mySensorNode = new MySensorNodeVector();
|
||||
firstTime = false;
|
||||
mySensorNode->push_back(SensorNode(params));
|
||||
}
|
||||
|
||||
void publishTimes() {
|
||||
if (mySensorNode != nullptr) {
|
||||
for (unsigned int i = 0; i < mySensorNode->size(); i++) {
|
||||
mySensorNode->at(i).publish();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
130
src/items/vSensorPzem.cpp
Normal file
130
src/items/vSensorPzem.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableSensorPzem
|
||||
#include "items/vSensorPzem.h"
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Global.h"
|
||||
#include "SoftUART.h"
|
||||
|
||||
SensorPzem::SensorPzem(const paramsPzem& paramsV, const paramsPzem& paramsA, const paramsPzem& paramsWatt, const paramsPzem& paramsWattHrs, const paramsPzem& paramsHz) {
|
||||
_paramsV = paramsPzem(paramsV);
|
||||
_paramsA = paramsPzem(paramsA);
|
||||
_paramsWatt = paramsPzem(paramsWatt);
|
||||
_paramsWattHrs = paramsPzem(paramsWattHrs);
|
||||
_paramsHz = paramsPzem(paramsHz);
|
||||
|
||||
pzem = new PZEMSensor(myUART, hexStringToUint8(_paramsHz.addr));
|
||||
}
|
||||
|
||||
SensorPzem::~SensorPzem() {}
|
||||
|
||||
void SensorPzem::loop() {
|
||||
difference = millis() - prevMillis;
|
||||
if (difference >= _paramsHz.interval) {
|
||||
prevMillis = millis();
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
void SensorPzem::read() {
|
||||
if (myUART) {
|
||||
float voltage = (pzem->values()->voltage * _paramsV.c) + _paramsV.k;
|
||||
float current = (pzem->values()->current * _paramsA.c) + _paramsA.k;
|
||||
float power = (pzem->values()->power * _paramsWatt.c) + _paramsWatt.k;
|
||||
float energy = (pzem->values()->energy * _paramsWattHrs.c) + _paramsWattHrs.k;
|
||||
float freq = (pzem->values()->freq * _paramsHz.c) + _paramsHz.k;
|
||||
|
||||
eventGen2(_paramsV.key, String(voltage));
|
||||
jsonWriteStr(configLiveJson, _paramsV.key, String(voltage));
|
||||
publishStatus(_paramsV.key, String(voltage));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsV.key + "' data: " + String(voltage));
|
||||
|
||||
eventGen2(_paramsA.key, String(current));
|
||||
jsonWriteStr(configLiveJson, _paramsA.key, String(current));
|
||||
publishStatus(_paramsA.key, String(current));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsA.key + "' data: " + String(current));
|
||||
|
||||
eventGen2(_paramsWatt.key, String(power));
|
||||
jsonWriteStr(configLiveJson, _paramsWatt.key, String(power));
|
||||
publishStatus(_paramsWatt.key, String(power));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsWatt.key + "' data: " + String(power));
|
||||
|
||||
eventGen2(_paramsWattHrs.key, String(energy));
|
||||
jsonWriteStr(configLiveJson, _paramsWattHrs.key, String(energy));
|
||||
publishStatus(_paramsWattHrs.key, String(energy));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsWattHrs.key + "' data: " + String(energy));
|
||||
|
||||
eventGen2(_paramsHz.key, String(freq));
|
||||
jsonWriteStr(configLiveJson, _paramsHz.key, String(freq));
|
||||
publishStatus(_paramsHz.key, String(freq));
|
||||
SerialPrint("I", "Sensor", "'" + _paramsHz.key + "' data: " + String(freq));
|
||||
} else {
|
||||
SerialPrint("E", "Sensor PZEM", "Error, UART switched off");
|
||||
}
|
||||
}
|
||||
|
||||
MySensorPzemVector* mySensorPzem = nullptr;
|
||||
|
||||
void pzemSensor() {
|
||||
if (myUART) {
|
||||
myLineParsing.update();
|
||||
String key = myLineParsing.gkey();
|
||||
String addr = myLineParsing.gaddr();
|
||||
String interval = myLineParsing.gint();
|
||||
String c = myLineParsing.gc();
|
||||
String k = myLineParsing.gk();
|
||||
myLineParsing.clear();
|
||||
|
||||
static int enterCnt = -1;
|
||||
enterCnt++;
|
||||
|
||||
static paramsPzem paramsV;
|
||||
static paramsPzem paramsA;
|
||||
static paramsPzem paramsWatt;
|
||||
static paramsPzem paramsWattHrs;
|
||||
static paramsPzem paramsHz;
|
||||
|
||||
if (enterCnt == 0) {
|
||||
paramsV.key = key;
|
||||
paramsV.c = c.toFloat();
|
||||
paramsV.k = k.toFloat();
|
||||
}
|
||||
|
||||
if (enterCnt == 1) {
|
||||
paramsA.key = key;
|
||||
paramsA.c = c.toFloat();
|
||||
paramsA.k = k.toFloat();
|
||||
}
|
||||
|
||||
if (enterCnt == 2) {
|
||||
paramsWatt.key = key;
|
||||
paramsWatt.c = c.toFloat();
|
||||
paramsWatt.k = k.toFloat();
|
||||
}
|
||||
|
||||
if (enterCnt == 3) {
|
||||
paramsWattHrs.key = key;
|
||||
paramsWattHrs.c = c.toFloat();
|
||||
paramsWattHrs.k = k.toFloat();
|
||||
}
|
||||
|
||||
if (enterCnt == 4) {
|
||||
paramsHz.key = key;
|
||||
paramsHz.c = c.toFloat();
|
||||
paramsHz.k = k.toFloat();
|
||||
paramsHz.addr = addr;
|
||||
paramsHz.interval = interval.toInt() * 1000;
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) mySensorPzem = new MySensorPzemVector();
|
||||
firstTime = false;
|
||||
mySensorPzem->push_back(SensorPzem(paramsV, paramsA, paramsWatt, paramsWattHrs, paramsHz));
|
||||
|
||||
enterCnt = -1;
|
||||
}
|
||||
} else {
|
||||
SerialPrint("E", "Sensor PZEM", "Error, UART switched off");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
92
src/items/vSensorUltrasonic.cpp
Normal file
92
src/items/vSensorUltrasonic.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableSensorUltrasonic
|
||||
#include "items/vSensorUltrasonic.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Global.h"
|
||||
|
||||
GMedian<5, int> testFilter;
|
||||
|
||||
SensorUltrasonic::SensorUltrasonic(String key, unsigned long interval, unsigned int trig, unsigned int echo, int map1, int map2, int map3, int map4, float c) {
|
||||
_interval = interval * 1000;
|
||||
_key = key;
|
||||
_trig = trig;
|
||||
_echo = echo;
|
||||
|
||||
_map1 = map1;
|
||||
_map2 = map2;
|
||||
_map3 = map3;
|
||||
_map4 = map4;
|
||||
|
||||
_c = c;
|
||||
|
||||
pinMode(_trig, OUTPUT);
|
||||
pinMode(_echo, INPUT);
|
||||
}
|
||||
|
||||
SensorUltrasonic::~SensorUltrasonic() {}
|
||||
|
||||
void SensorUltrasonic::loop() {
|
||||
currentMillis = millis();
|
||||
difference = currentMillis - prevMillis;
|
||||
if (difference >= _interval) {
|
||||
prevMillis = millis();
|
||||
readUltrasonic();
|
||||
}
|
||||
}
|
||||
|
||||
void SensorUltrasonic::readUltrasonic() {
|
||||
static unsigned int counter;
|
||||
counter++;
|
||||
|
||||
int value;
|
||||
|
||||
digitalWrite(_trig, LOW);
|
||||
delayMicroseconds(2);
|
||||
digitalWrite(_trig, HIGH);
|
||||
delayMicroseconds(10);
|
||||
digitalWrite(_trig, LOW);
|
||||
long duration_ = pulseIn(_echo, HIGH, 30000); // 3000 µs = 50cm // 30000 µs = 5 m
|
||||
value = duration_ / 29 / 2;
|
||||
|
||||
value = testFilter.filtered(value);
|
||||
|
||||
value = map(value, _map1, _map2, _map3, _map4);
|
||||
float valueFloat = value * _c;
|
||||
|
||||
if (counter > 10) {
|
||||
eventGen2(_key, String(valueFloat));
|
||||
jsonWriteStr(configLiveJson, _key, String(valueFloat));
|
||||
publishStatus(_key, String(valueFloat));
|
||||
SerialPrint("I", "Sensor", "'" + _key + "' data: " + String(valueFloat));
|
||||
}
|
||||
}
|
||||
|
||||
MySensorUltrasonicVector* mySensorUltrasonic = nullptr;
|
||||
|
||||
void ultrasonic() {
|
||||
myLineParsing.update();
|
||||
String interval = myLineParsing.gint();
|
||||
String pin = myLineParsing.gpin();
|
||||
String key = myLineParsing.gkey();
|
||||
String map = myLineParsing.gmap();
|
||||
String c = myLineParsing.gc();
|
||||
myLineParsing.clear();
|
||||
|
||||
unsigned int trig = selectFromMarkerToMarker(pin, ",", 0).toInt();
|
||||
unsigned int echo = selectFromMarkerToMarker(pin, ",", 1).toInt();
|
||||
|
||||
int map1 = selectFromMarkerToMarker(map, ",", 0).toInt();
|
||||
int map2 = selectFromMarkerToMarker(map, ",", 1).toInt();
|
||||
int map3 = selectFromMarkerToMarker(map, ",", 2).toInt();
|
||||
int map4 = selectFromMarkerToMarker(map, ",", 3).toInt();
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) mySensorUltrasonic = new MySensorUltrasonicVector();
|
||||
firstTime = false;
|
||||
mySensorUltrasonic->push_back(SensorUltrasonic(key, interval.toInt(), trig, echo, map1, map2, map3, map4, c.toFloat()));
|
||||
}
|
||||
#endif
|
||||
52
src/items/vSensorUptime.cpp
Normal file
52
src/items/vSensorUptime.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include "Consts.h"
|
||||
#ifdef EnableSensorUptime
|
||||
#include "items/vSensorUptime.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "BufferExecute.h"
|
||||
#include "Class/LineParsing.h"
|
||||
#include "Global.h"
|
||||
|
||||
SensorUptime::SensorUptime(const paramsUptime& paramsUpt) {
|
||||
_paramsUpt = paramsUptime(paramsUpt);
|
||||
}
|
||||
|
||||
SensorUptime::~SensorUptime() {}
|
||||
|
||||
void SensorUptime::loop() {
|
||||
difference = millis() - prevMillis;
|
||||
if (difference >= _paramsUpt.interval) {
|
||||
prevMillis = millis();
|
||||
read();
|
||||
}
|
||||
}
|
||||
|
||||
void SensorUptime::read() {
|
||||
String upt = timeNow->getUptime();
|
||||
|
||||
eventGen2(_paramsUpt.key, upt);
|
||||
jsonWriteStr(configLiveJson, _paramsUpt.key, upt);
|
||||
publishStatus(_paramsUpt.key, upt);
|
||||
SerialPrint("I", "Sensor", "'" + _paramsUpt.key + "' data: " + upt);
|
||||
}
|
||||
|
||||
MySensorUptimeVector* mySensorUptime = nullptr;
|
||||
|
||||
void uptimeSensor() {
|
||||
myLineParsing.update();
|
||||
String key = myLineParsing.gkey();
|
||||
String interval = myLineParsing.gint();
|
||||
myLineParsing.clear();
|
||||
|
||||
static paramsUptime paramsUpt;
|
||||
|
||||
paramsUpt.key = key;
|
||||
paramsUpt.interval = interval.toInt() * 1000;
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) mySensorUptime = new MySensorUptimeVector();
|
||||
firstTime = false;
|
||||
mySensorUptime->push_back(SensorUptime(paramsUpt));
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user