This commit is contained in:
Dmitry Borisenko
2020-09-02 22:33:03 +03:00
parent 26383c0a19
commit 70096c71c8
288 changed files with 0 additions and 29977 deletions

View File

@@ -1,26 +0,0 @@
#include "Bus/I2CScanner.h"
#include "Utils/PrintMessage.h"
#include <Wire.h>
static const char* MODULE = "I2C";
I2CScanner::I2CScanner(String& out) : BusScanner(TAG_I2C, out, 2){};
void I2CScanner::init() {
Wire.begin();
}
boolean I2CScanner::syncScan() {
pm.info("scanning...");
size_t cnt = 0;
for (uint8_t i = 8; i < 120; i++) {
Wire.beginTransmission(i);
if (Wire.endTransmission() == 0) {
pm.info("found: " + i);
addResult(i, i < 119);
cnt++;
}
}
return cnt;
}

View File

@@ -1,2 +0,0 @@
#include "Class/Button.h"
Button1* myButton;

View File

@@ -1,49 +0,0 @@
#include "Class/CallBackTest.h"
CallBackTest::CallBackTest(){};
void CallBackTest::loop() {
count++;
if (count > 5000) {
// Проверяем что переменная содержит указатель - не пустая не null
// и непосредственно вызываем то, на что это указывает
// просто пишем имя - без () - это указатель на фунецию.
// () - вызываем функцию - с пустым набором параметров
if (_cb != NULL) {
_cb();
}
//или ровно тоже самое
//if (_cb) _cb();
if (_pcb) {
if (_pcb("SomeTextValue")) {
Serial.println("Got true!");
} else {
Serial.println("Got false!");
}
}
count = 0;
}
}
//передаем внутрь класса функцию любую void функцию без агрументов
void CallBackTest::setCallback(AsyncActionCb cb) {
_cb = cb;
}
//передаем внутрь класса функцию любую void функцию с аргументами
void CallBackTest::setCallback(AsyncParamActionCb pcb) {
_pcb = pcb;
}
//CallBackTest* CB;
//CB->setCallback([]() {
// Serial.println("123");
//});
//
//CB->setCallback([](const String str) {
// Serial.println(str);
// return true;
//});

View File

@@ -1,2 +0,0 @@
#include "Class/Input.h"
Input* myInput;

View File

@@ -1 +0,0 @@
#include "Class/LineParsing.h"

View File

@@ -1,30 +0,0 @@
#include "Class/NotAsinc.h"
NotAsinc::NotAsinc(uint8_t size) {
this->items = new NotAsincItem[size];
this->size = size;
}
NotAsinc::~NotAsinc() {}
void NotAsinc::add(uint8_t i, NotAsincCb f, void* arg) {
this->items[i].cb = f;
this->items[i].cb_arg = arg;
this->items[i].is_used = true;
}
void NotAsinc::loop() {
if (this->items[task].is_used) {
handle(this->items[task].cb, this->items[task].cb_arg);
task = 0;
}
}
void NotAsinc::make(uint8_t task) {
this->task = task;
}
void NotAsinc::handle(NotAsincCb f, void* arg) {
f(arg);
}
NotAsinc* myNotAsincActions;

View File

@@ -1,2 +0,0 @@
#include "Class/OutputModule.h"
OutputModule* myText;

View File

@@ -1,2 +0,0 @@
#include "Class/Pwm.h"
Pwm* myPwm;

View File

@@ -1,2 +0,0 @@
#include "Class/ScenarioClass.h"
Scenario* myScenario;

View File

@@ -1,2 +0,0 @@
#include "Class/SensorAnalog.h"
SensorAnalog* mySensorAnalog;

View File

@@ -1,2 +0,0 @@
#include "Class/Switch.h"
Switch* mySwitch;

View File

@@ -1,524 +0,0 @@
#include "Cmd.h"
#include "Class/Button.h"
#include "Class/Input.h"
#include "Class/LineParsing.h"
#include "Class/OutputModule.h"
#include "Class/Pwm.h"
#include "Class/Switch.h"
//-----------------------------
#include "Class/NotAsinc.h"
#include "Global.h"
#include "Module/Terminal.h"
#include "Servo/Servos.h"
static const char *MODULE = "Cmd";
Terminal *term = nullptr;
boolean but[NUM_BUTTONS];
Bounce *buttons = new Bounce[NUM_BUTTONS];
#ifdef ESP8266
SoftwareSerial *mySerial = nullptr;
#else
HardwareSerial *mySerial = nullptr;
#endif
void getData();
void cmd_init() {
sCmd.addCommand("button-out", buttonOut);
sCmd.addCommand("pwm-out", pwmOut);
sCmd.addCommand("button-in", buttonIn);
sCmd.addCommand("input-digit", inputDigit);
sCmd.addCommand("input-time", inputTime);
sCmd.addCommand("output-text", textOut);
#ifdef ANALOG_ENABLED
sCmd.addCommand("analog-adc", analogAdc);
#endif
sCmd.addCommand("timerStart", timerStart_);
sCmd.addCommand("timerStop", timerStop_);
#ifdef LEVEL_ENABLED
sCmd.addCommand("levelPr", levelPr);
sCmd.addCommand("ultrasonicCm", ultrasonicCm);
#endif
#ifdef DALLAS_ENABLED
sCmd.addCommand("dallas", dallas);
#endif
#ifdef DHT_ENABLED
sCmd.addCommand("dhtT", dhtT);
sCmd.addCommand("dhtH", dhtH);
sCmd.addCommand("dhtPerception", dhtP);
sCmd.addCommand("dhtComfort", dhtC);
sCmd.addCommand("dhtDewpoint", dhtD);
#endif
#ifdef BMP_ENABLED
sCmd.addCommand("bmp280T", bmp280T);
sCmd.addCommand("bmp280P", bmp280P);
#endif
#ifdef BME_ENABLED
sCmd.addCommand("bme280T", bme280T);
sCmd.addCommand("bme280P", bme280P);
sCmd.addCommand("bme280H", bme280H);
sCmd.addCommand("bme280A", bme280A);
#endif
#ifdef STEPPER_ENABLED
sCmd.addCommand("stepper", stepper);
sCmd.addCommand("stepperSet", stepperSet);
#endif
#ifdef SERVO_ENABLED
sCmd.addCommand("servo", servo_);
sCmd.addCommand("servoSet", servoSet);
#endif
#ifdef SERIAL_ENABLED
sCmd.addCommand("serialBegin", serialBegin);
sCmd.addCommand("serialWrite", serialWrite);
sCmd.addCommand("getData", getData);
#endif
#ifdef LOGGING_ENABLED
sCmd.addCommand("logging", logging);
#endif
sCmd.addCommand("mqtt", mqttOrderSend);
sCmd.addCommand("http", httpOrderSend);
#ifdef PUSH_ENABLED
sCmd.addCommand("push", pushControl);
#endif
sCmd.addCommand("firmwareUpdate", firmwareUpdate);
sCmd.addCommand("firmwareVersion", firmwareVersion);
handle_time_init();
}
//==========================================Модуль кнопок===================================================
//button-out light toggle Кнопки Свет 1 pin[12] inv[1] st[1]
//==========================================================================================================
void buttonOut() {
myButton = new Button1();
myButton->update();
String key = myButton->gkey();
String pin = myButton->gpin();
String inv = myButton->ginv();
sCmd.addCommand(key.c_str(), buttonOutSet);
jsonWriteStr(configOptionJson, key + "_pin", pin);
jsonWriteStr(configOptionJson, key + "_inv", inv);
myButton->pinModeSet();
myButton->pinStateSetDefault();
myButton->pinStateSetInvDefault();
myButton->clear();
}
void buttonOutSet() {
String key = sCmd.order();
String state = sCmd.next();
String pin = jsonReadStr(configOptionJson, key + "_pin");
String inv = jsonReadStr(configOptionJson, key + "_inv");
if (inv == "") {
myButton->pinChange(key, pin, state, true);
} else {
myButton->pinChange(key, pin, state, false);
}
}
//==========================================Модуль управления ШИМ===================================================
//pwm-out volume range Кнопки Свет 1 pin[12] st[500]
//==================================================================================================================
void pwmOut() {
myPwm = new Pwm();
myPwm->update();
String key = myPwm->gkey();
String pin = myPwm->gpin();
String inv = myPwm->ginv();
sCmd.addCommand(key.c_str(), pwmOutSet);
jsonWriteStr(configOptionJson, key + "_pin", pin);
myPwm->pwmModeSet();
myPwm->pwmStateSetDefault();
myPwm->clear();
}
void pwmOutSet() {
String key = sCmd.order();
String state = sCmd.next();
String pin = jsonReadStr(configOptionJson, key + "_pin");
myPwm->pwmChange(key, pin, state);
}
//==========================================Модуль физических кнопок========================================
//button-in switch1 toggle Кнопки Свет 1 pin[2] db[20]
//==========================================================================================================
void buttonIn() {
mySwitch = new Switch();
mySwitch->update();
String key = mySwitch->gkey();
String pin = mySwitch->gpin();
sCmd.addCommand(key.c_str(), buttonInSet);
mySwitch->init();
mySwitch->switchStateSetDefault();
mySwitch->clear();
}
void buttonInSet() {
String key = sCmd.order();
String state = sCmd.next();
mySwitch->switchChangeVirtual(key, state);
}
//==========================================Модуль ввода цифровых значений==================================
//input-digit digit1 inputDigit Ввод Введите.цифру 4 st[60]
//==========================================================================================================
void inputDigit() {
myInput = new Input();
myInput->update();
String key = myInput->gkey();
sCmd.addCommand(key.c_str(), inputDigitSet);
myInput->inputSetDefaultFloat();
myInput->clear();
}
void inputDigitSet() {
String key = sCmd.order();
String state = sCmd.next();
myInput->inputSetFloat(key, state);
}
//==========================================Модуль ввода времени============================================
//input-time time1 inputTime Ввод Введите.время 4 st[10-00-00]
//==========================================================================================================
void inputTime() {
myInput = new Input();
myInput->update();
String key = myInput->gkey();
sCmd.addCommand(key.c_str(), inputTimeSet);
myInput->inputSetDefaultStr();
myInput->clear();
}
void inputTimeSet() {
String key = sCmd.order();
String state = sCmd.next();
myInput->inputSetStr(key, state);
}
void handle_time_init() {
ts.add(
TIME, 1000, [&](void *) {
jsonWriteStr(configLiveJson, "time", timeNow->getTime());
jsonWriteStr(configLiveJson, "timenow", timeNow->getTimeJson());
//eventGen("timenow", "");
},
nullptr, true);
}
//===============================================Модуль вывода текста============================================
//output-text;id;anydata;Вывод;Сигнализация;order;st[Обнаружено.движение]
//===============================================================================================================
void textOut() {
myText = new OutputModule();
myText->update();
String key = myText->gkey();
sCmd.addCommand(key.c_str(), textOutSet);
myText->OutputModuleStateSetDefault();
myText->clear();
}
void textOutSet() {
String key = sCmd.order();
String state = sCmd.next();
myText->OutputModuleChange(key, state);
}
//void text() {
// String number = sCmd.next();
// String widget_name = sCmd.next();
// String page_name = sCmd.next();
// String page_number = sCmd.next();
//
// createWidget(widget_name, page_name, page_number, "anydata", "text" + number);
//}
//
//void textSet() {
// String number = sCmd.next();
// String text = sCmd.next();
// text.replace("_", " ");
//
// if (text.indexOf("-time") >= 0) {
// text.replace("-time", "");
// text.replace("#", " ");
// text = text + " " + timeNow->getDateTimeDotFormated();
// }
//
// jsonWriteStr(configLiveJson, "text" + number, text);
// MqttClient::publishStatus("text" + number, text);
//}
//=====================================================================================================================================
//=========================================Модуль шагового мотора======================================================================
#ifdef STEPPER_ENABLED
//stepper 1 12 13
void stepper() {
String stepper_number = sCmd.next();
String pin_step = sCmd.next();
String pin_dir = sCmd.next();
jsonWriteStr(configOptionJson, "stepper" + stepper_number, pin_step + " " + pin_dir);
pinMode(pin_step.toInt(), OUTPUT);
pinMode(pin_dir.toInt(), OUTPUT);
}
//stepperSet 1 100 5
void stepperSet() {
String stepper_number = sCmd.next();
String steps = sCmd.next();
jsonWriteStr(configOptionJson, "steps" + stepper_number, steps);
String stepper_speed = sCmd.next();
String pin_step = selectToMarker(jsonReadStr(configOptionJson, "stepper" + stepper_number), " ");
String pin_dir = deleteBeforeDelimiter(jsonReadStr(configOptionJson, "stepper" + stepper_number), " ");
Serial.println(pin_step);
Serial.println(pin_dir);
if (steps.toInt() > 0) digitalWrite(pin_dir.toInt(), HIGH);
if (steps.toInt() < 0) digitalWrite(pin_dir.toInt(), LOW);
if (stepper_number == "1") {
ts.add(
STEPPER1, stepper_speed.toInt(), [&](void *) {
int steps_int = abs(jsonReadInt(configOptionJson, "steps1") * 2);
static int count;
count++;
String pin_step = selectToMarker(jsonReadStr(configOptionJson, "stepper1"), " ");
digitalWrite(pin_step.toInt(), !digitalRead(pin_step.toInt()));
yield();
if (count > steps_int) {
digitalWrite(pin_step.toInt(), LOW);
ts.remove(STEPPER1);
count = 0;
}
},
nullptr, true);
}
if (stepper_number == "2") {
ts.add(
STEPPER2, stepper_speed.toInt(), [&](void *) {
int steps_int = abs(jsonReadInt(configOptionJson, "steps2") * 2);
static int count;
count++;
String pin_step = selectToMarker(jsonReadStr(configOptionJson, "stepper2"), " ");
digitalWrite(pin_step.toInt(), !digitalRead(pin_step.toInt()));
yield();
if (count > steps_int) {
digitalWrite(pin_step.toInt(), LOW);
ts.remove(STEPPER2);
count = 0;
}
},
nullptr, true);
}
}
#endif
//====================================================================================================================================================
//=================================================================Сервоприводы=======================================================================
#ifdef SERVO_ENABLED
//servo 1 13 50 Мой#сервопривод Сервоприводы 0 100 0 180 2
void servo_() {
String number = sCmd.next();
uint8_t pin = String(sCmd.next()).toInt();
int value = String(sCmd.next()).toInt();
String widget = sCmd.next();
String page = sCmd.next();
int min_value = String(sCmd.next()).toInt();
int max_value = String(sCmd.next()).toInt();
int min_deg = String(sCmd.next()).toInt();
int max_deg = String(sCmd.next()).toInt();
String pageNumber = sCmd.next();
jsonWriteStr(configOptionJson, "servo_pin" + number, String(pin, DEC));
value = map(value, min_value, max_value, min_deg, max_deg);
Servo *servo = myServo.create(number.toInt(), pin);
servo->write(value);
#ifdef ESP32
myServo1.attach(servo_pin.toInt(), 500, 2400);
myServo1.write(start_state_int);
#endif
jsonWriteInt(configOptionJson, "s_min_val" + number, min_value);
jsonWriteInt(configOptionJson, "s_max_val" + number, max_value);
jsonWriteInt(configOptionJson, "s_min_deg" + number, min_deg);
jsonWriteInt(configOptionJson, "s_max_deg" + number, max_deg);
jsonWriteInt(configLiveJson, "servo" + number, value);
createWidgetParam(widget, page, pageNumber, "range", "servo" + number, "min", String(min_value), "max", String(max_value), "k", "1");
}
void servoSet() {
String number = sCmd.next();
int value = String(sCmd.next()).toInt();
value = map(value,
jsonReadInt(configOptionJson, "s_min_val" + number),
jsonReadInt(configOptionJson, "s_max_val" + number),
jsonReadInt(configOptionJson, "s_min_deg" + number),
jsonReadInt(configOptionJson, "s_max_deg" + number));
Servo *servo = myServo.get(number.toInt());
if (servo) {
servo->write(value);
}
eventGen("servo", number);
jsonWriteInt(configLiveJson, "servo" + number, value);
MqttClient::publishStatus("servo" + number, String(value, DEC));
}
#endif
//====================================================================================================================================================
//=============================================================Модуль сериал порта=======================================================================
#ifdef SERIAL_ENABLED
void serialBegin() {
String s_speed = sCmd.next();
String rxPin = sCmd.next();
String txPin = sCmd.next();
if (mySerial) {
delete mySerial;
}
#ifdef ESP8266
mySerial = new SoftwareSerial(rxPin.toInt(), txPin.toInt());
mySerial->begin(s_speed.toInt());
#else
mySerial = new HardwareSerial(2);
mySerial->begin(rxPin.toInt(), txPin.toInt());
#endif
term = new Terminal(mySerial);
term->setEOL(LF);
term->enableColors(false);
term->enableControlCodes(false);
term->enableEcho(false);
term->setOnReadLine([](const char *str) {
String line = String(str);
addCommandLoop(line);
});
}
void getData() {
String param = sCmd.next();
String res = param.length() ? jsonReadStr(configLiveJson, param) : configLiveJson;
if (term) {
term->println(res.c_str());
}
}
void serialWrite() {
String payload = sCmd.next();
if (term) {
term->println(payload.c_str());
}
}
#endif
//====================================================================================================================================================
//=================================================Глобальные команды удаленного управления===========================================================
void mqttOrderSend() {
String id = sCmd.next();
String order = sCmd.next();
String all_line = jsonReadStr(configSetupJson, "mqttPrefix") + "/" + id + "/order";
mqtt.publish(all_line.c_str(), order.c_str(), false);
}
void httpOrderSend() {
String ip = sCmd.next();
String order = sCmd.next();
order.replace("_", "%20");
String url = "http://" + ip + "/cmd?command=" + order;
getURL(url);
}
void firmwareUpdate() {
myNotAsincActions->make(do_UPGRADE);
}
void firmwareVersion() {
String widget = sCmd.next();
String page = sCmd.next();
String pageNumber = sCmd.next();
jsonWriteStr(configLiveJson, "firmver", FIRMWARE_VERSION);
createWidget(widget, page, pageNumber, "anydata", "firmver");
}
void addCommandLoop(const String &cmdStr) {
orderBuf += cmdStr;
if (!cmdStr.endsWith(",")) {
orderBuf += ",";
}
}
void fileExecute(const String &filename) {
String cmdStr = readFile(filename, 2048);
csvExecute(cmdStr);
}
void csvExecute(String &cmdStr) {
cmdStr.replace(";", " ");
cmdStr += "\r\n";
cmdStr.replace("\r\n", "\n");
cmdStr.replace("\r", "\n");
int count = 0;
while (cmdStr.length()) {
String buf = selectToMarker(cmdStr, "\n");
count++;
if (count > 1) sCmd.readStr(buf);
cmdStr = deleteBeforeDelimiter(cmdStr, "\n");
}
}
void spaceExecute(String &cmdStr) {
cmdStr += "\r\n";
cmdStr.replace("\r\n", "\n");
cmdStr.replace("\r", "\n");
while (cmdStr.length()) {
String buf = selectToMarker(cmdStr, "\n");
sCmd.readStr(buf);
cmdStr = deleteBeforeDelimiter(cmdStr, "\n");
}
}
void loopCmd() {
if (orderBuf.length()) {
String tmp = selectToMarker(orderBuf, ","); //выделяем первую команду rel 5 1,
pm.info("do: " + tmp);
sCmd.readStr(tmp); //выполняем
orderBuf = deleteBeforeDelimiter(orderBuf, ","); //осекаем
}
}
void loopSerial() {
if (term) {
term->loop();
}
}

View File

@@ -1,326 +0,0 @@
#include "FSEditor.h"
#ifdef ESP32
#include "LITTLEFS.h"
#define LittleFS LITTLEFS
#endif
#ifdef ESP8266
#include <LittleFS.h>
#endif
#define FS_MAXLENGTH_FILEPATH 32
const char *excludeListFile = "/.exclude.files";
typedef struct ExcludeListS {
char *item;
ExcludeListS *next;
} ExcludeList;
static ExcludeList *excludes = NULL;
static bool matchWild(const char *pattern, const char *testee) {
const char *nxPat = NULL, *nxTst = NULL;
while (*testee) {
if ((*pattern == '?') || (*pattern == *testee)) {
pattern++;
testee++;
continue;
}
if (*pattern == '*') {
nxPat = pattern++;
nxTst = testee;
continue;
}
if (nxPat) {
pattern = nxPat + 1;
testee = ++nxTst;
continue;
}
return false;
}
while (*pattern == '*') {
pattern++;
}
return (*pattern == 0);
}
static bool addExclude(const char *item) {
size_t len = strlen(item);
if (!len) {
return false;
}
ExcludeList *e = (ExcludeList *)malloc(sizeof(ExcludeList));
if (!e) {
return false;
}
e->item = (char *)malloc(len + 1);
if (!e->item) {
free(e);
return false;
}
memcpy(e->item, item, len + 1);
e->next = excludes;
excludes = e;
return true;
}
static void loadExcludeList(fs::FS &_fs, const char *filename) {
static char linebuf[FS_MAXLENGTH_FILEPATH];
fs::File excludeFile = _fs.open(filename, "r");
if (!excludeFile) {
return;
}
if (excludeFile.isDirectory()) {
excludeFile.close();
return;
}
if (excludeFile.size() > 0) {
uint8_t idx;
bool isOverflowed = false;
while (excludeFile.available()) {
linebuf[0] = '\0';
idx = 0;
int lastChar;
do {
lastChar = excludeFile.read();
if (lastChar != '\r') {
linebuf[idx++] = (char)lastChar;
}
} while ((lastChar >= 0) && (lastChar != '\n') && (idx < FS_MAXLENGTH_FILEPATH));
if (isOverflowed) {
isOverflowed = (lastChar != '\n');
continue;
}
isOverflowed = (idx >= FS_MAXLENGTH_FILEPATH);
linebuf[idx - 1] = '\0';
if (!addExclude(linebuf)) {
excludeFile.close();
return;
}
}
}
excludeFile.close();
}
static bool isExcluded(fs::FS &_fs, const char *filename) {
if (excludes == NULL) {
loadExcludeList(_fs, excludeListFile);
}
if (strcmp(excludeListFile, filename) == 0) return true;
ExcludeList *e = excludes;
while (e) {
if (matchWild(e->item, filename)) {
return true;
}
e = e->next;
}
return false;
}
// WEB HANDLER IMPLEMENTATION
#ifdef ESP32
FSEditor::FSEditor(const fs::FS &fs, const String &username, const String &password)
#else
FSEditor::FSEditor(const String &username, const String &password, const fs::FS &fs)
#endif
: _fs(fs), _username(username), _password(password), _authenticated(false), _startTime(0) {
}
bool FSEditor::canHandle(AsyncWebServerRequest *request) {
if (request->url().equalsIgnoreCase("/edit")) {
if (request->method() == HTTP_GET) {
if (request->hasParam("list"))
return true;
if (request->hasParam("edit")) {
request->_tempFile = _fs.open(request->arg("edit"), "r");
if (!request->_tempFile) {
return false;
}
if (request->_tempFile.isDirectory()) {
request->_tempFile.close();
return false;
}
}
if (request->hasParam("download")) {
request->_tempFile = _fs.open(request->arg("download"), "r");
if (!request->_tempFile) {
return false;
}
if (request->_tempFile.isDirectory()) {
request->_tempFile.close();
return false;
}
}
request->addInterestingHeader("If-Modified-Since");
return true;
} else if (request->method() == HTTP_POST)
return true;
else if (request->method() == HTTP_DELETE)
return true;
else if (request->method() == HTTP_PUT)
return true;
}
return false;
}
void FSEditor::handleRequest(AsyncWebServerRequest *request) {
if (_username.length() && _password.length() && !request->authenticate(_username.c_str(), _password.c_str()))
return request->requestAuthentication();
if (request->method() == HTTP_GET) {
if (request->hasParam("list")) {
String path = request->getParam("list")->value();
#ifdef ESP32
File dir = _fs.open(path);
#else
fs::Dir dir = _fs.openDir(path);
#endif
path = String();
String output = "[";
#ifdef ESP32
File entry = dir.openNextFile();
while (entry) {
#else
while (dir.next()) {
fs::File entry = dir.openFile("r");
#endif
String fname = entry.fullName();
if (fname.charAt(0) != '/') fname = "/" + fname;
if (isExcluded(_fs, fname.c_str())) {
#ifdef ESP32
entry = dir.openNextFile();
#endif
continue;
}
if (output != "[") output += ',';
output += "{\"type\":\"";
output += "file";
output += "\",\"name\":\"";
output += String(fname);
output += "\",\"size\":";
output += String(entry.size());
output += "}";
#ifdef ESP32
entry = dir.openNextFile();
#else
entry.close();
#endif
}
#ifdef ESP32
dir.close();
#endif
output += "]";
request->send(200, "application/json", output);
output = String();
} else if (request->hasParam("edit") || request->hasParam("download")) {
request->send(request->_tempFile, request->_tempFile.fullName(), String(), request->hasParam("download"));
} else {
const char *buildTime = __DATE__ " " __TIME__ " GMT";
if (request->header("If-Modified-Since").equals(buildTime)) {
request->send(304);
} else {
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/edit.htm", "text/html");
// response->addHeader("Content-Encoding", "gzip");
response->addHeader("Last-Modified", buildTime);
request->send(response);
}
}
} else if (request->method() == HTTP_DELETE) {
if (request->hasParam("path", true)) {
if (!(_fs.remove(request->getParam("path", true)->value()))) {
#ifdef ESP32
_fs.rmdir(request->getParam("path", true)->value()); // try rmdir for littlefs
#endif
}
request->send(200, "", "DELETE: " + request->getParam("path", true)->value());
} else
request->send(404);
} else if (request->method() == HTTP_POST) {
if (request->hasParam("data", true, true) && _fs.exists(request->getParam("data", true, true)->value()))
request->send(200, "", "UPLOADED: " + request->getParam("data", true, true)->value());
else if (request->hasParam("rawname", true) && request->hasParam("raw0", true)) {
String rawnam = request->getParam("rawname", true)->value();
if (_fs.exists(rawnam)) _fs.remove(rawnam); // delete it to allow a mode
int k = 0;
uint16_t i = 0;
fs::File f = _fs.open(rawnam, "a");
while (request->hasParam("raw" + String(k), true)) { //raw0 .. raw1
if (f) {
i += f.print(request->getParam("raw" + String(k), true)->value());
}
k++;
}
f.close();
request->send(200, "", "IPADWRITE: " + rawnam + ":" + String(i));
} else {
request->send(500);
}
} else if (request->method() == HTTP_PUT) {
if (request->hasParam("path", true)) {
String filename = request->getParam("path", true)->value();
if (_fs.exists(filename)) {
request->send(200);
} else {
/*******************************************************/
#ifdef ESP32
if (strchr(filename.c_str(), '/')) {
// For file creation, silently make subdirs as needed. If any fail,
// it will be caught by the real file open later on
char *pathStr = strdup(filename.c_str());
if (pathStr) {
// Make dirs up to the final fnamepart
char *ptr = strchr(pathStr, '/');
while (ptr) {
*ptr = 0;
_fs.mkdir(pathStr);
*ptr = '/';
ptr = strchr(ptr + 1, '/');
}
}
free(pathStr);
}
#endif
/*******************************************************/
fs::File f = _fs.open(filename, "w");
if (f) {
f.write((uint8_t)0x00);
f.close();
request->send(200, "", "CREATE: " + filename);
} else {
request->send(500);
}
}
} else
request->send(400);
}
}
void FSEditor::handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) {
if (!index) {
if (!_username.length() || request->authenticate(_username.c_str(), _password.c_str())) {
_authenticated = true;
request->_tempFile = _fs.open(filename, "w");
_startTime = millis();
}
}
if (_authenticated && request->_tempFile) {
if (len) {
request->_tempFile.write(data, len);
}
if (final) {
request->_tempFile.close();
}
}
}

View File

@@ -1,104 +0,0 @@
#include "Global.h"
#ifdef WS_enable
AsyncWebSocket ws;
//AsyncEventSource events;
#endif
Clock* timeNow;
TickerScheduler ts(TEST + 1);
WiFiClient espClient;
PubSubClient mqtt(espClient);
StringCommand sCmd;
AsyncWebServer server(80);
OneWire *oneWire;
DallasTemperature sensors;
/*
* Global vars
*/
boolean just_load = true;
// Json
String configSetupJson = "{}";
String configLiveJson = "{}";
String configOptionJson = "{}";
// Mqtt
String chipId = "";
String prex = "";
String all_widgets = "";
String scenario = "";
//orders and events
String orderBuf = "";
String eventBuf = "";
String itemsFile = "";
String itemsLine = "";
// Sensors
String sensorReadingMap;
String analog_value_names_list;
int enter_to_analog_counter;
String dallas_value_name;
int enter_to_dallas_counter;
String levelPr_value_name;
String ultrasonicCm_value_name;
String dhtT_value_name;
String dhtH_value_name;
String bmp280T_value_name;
String bmp280P_value_name;
String bme280T_value_name;
String bme280P_value_name;
String bme280H_value_name;
String bme280A_value_name;
int sensors_reading_map[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// Logging
String logging_value_names_list;
int enter_to_logging_counter;
// Scenario
int scenario_line_status[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
String lastVersion = "";
// Async actions
boolean checkUpdatesFlag = false;
boolean updateFlag = false;
boolean mqttParamsChanged = false;
boolean udp_data_parse = false;
boolean mqtt_send_settings_to_udp = false;
BusScanner_t busToScan;
boolean busScanFlag = false;
boolean fsCheckFlag = false;
boolean delElementFlag = false;
boolean getJsonListFromCsvFlag = false;
String csvFile = "";
int colum;

View File

@@ -1,128 +0,0 @@
#include "Global.h"
#include "Init.h"
#include "Cmd.h"
void loadConfig() {
configSetupJson = readFile("config.json", 4096);
configSetupJson.replace(" ", "");
configSetupJson.replace("\r\n", "");
jsonWriteStr(configSetupJson, "chipID", chipId);
jsonWriteStr(configSetupJson, "firmware_version", FIRMWARE_VERSION);
prex = jsonReadStr(configSetupJson, "mqttPrefix") + "/" + chipId;
Serial.println(configSetupJson);
}
void all_init() {
Device_init();
loadScenario();
Timer_countdown_init();
}
void Device_init() {
sensorReadingMap = "";
logging_value_names_list = "";
enter_to_logging_counter = LOG1 - 1;
analog_value_names_list = "";
enter_to_analog_counter = 0;
dallas_value_name = "";
enter_to_dallas_counter = 0;
levelPr_value_name = "";
ultrasonicCm_value_name = "";
dhtT_value_name = "";
dhtH_value_name = "";
bmp280T_value_name = "";
bmp280P_value_name = "";
bme280T_value_name = "";
bme280P_value_name = "";
bme280H_value_name = "";
bme280A_value_name = "";
int array_sz = sizeof(sensors_reading_map) / sizeof(sensors_reading_map[0]);
for (int i = 0; i < array_sz; i++) {
sensors_reading_map[i] = 0;
}
for (int i = LOG1; i <= LOG5; i++) {
ts.remove(i);
}
#ifdef LAYOUT_IN_RAM
all_widgets = "";
#else
removeFile(String("layout.txt"));
#endif
fileExecute(String(DEVICE_CONFIG_FILE));
//outcoming_date();
}
//-------------------------------сценарии-----------------------------------------------------
void loadScenario() {
if (jsonReadStr(configSetupJson, "scen") == "1") {
scenario = readFile(String(DEVICE_SCENARIO_FILE), 2048);
}
}
void uptime_init() {
ts.add(
UPTIME, 5000, [&](void*) {
handle_uptime();
},
nullptr, true);
}
void telemetry_init() {
if (TELEMETRY_UPDATE_INTERVAL) {
ts.add(
STATISTICS, TELEMETRY_UPDATE_INTERVAL, [&](void*) {
handle_statistics();
},
nullptr, true);
}
}
void handle_uptime() {
jsonWriteStr(configSetupJson, "uptime", timeNow->getUptime());
}
void handle_statistics() {
if (isNetworkActive()) {
String urls = "http://backup.privet.lv/visitors/?";
//-----------------------------------------------------------------
urls += WiFi.macAddress().c_str();
urls += "&";
//-----------------------------------------------------------------
#ifdef ESP8266
urls += "iot-manager_esp8266";
#endif
#ifdef ESP32
urls += "iot-manager_esp32";
#endif
urls += "&";
#ifdef ESP8266
urls += ESP.getResetReason();
#endif
#ifdef ESP32
urls += "Power on";
#endif
urls += "&";
urls += String(FIRMWARE_VERSION);
String stat = getURL(urls);
}
}

View File

@@ -1,128 +0,0 @@
#include "ItemsList.h"
#include "Utils\StringUtils.h"
static const char* firstLine PROGMEM = "Тип элемента;Id;Виджет;Имя вкладки;Имя виджета;Позиция виджета";
void addItem(String name) {
String item = readFile("items/" + name + ".txt", 1024);
name = deleteToMarkerLast(name, "-");
item.replace("id", name + String(getNewElementNumber("id.txt")));
item.replace("order", String(getNewElementNumber("order.txt")));
if (item.indexOf("pin-adc") != -1) {
item.replace("pin-adc", "pin[" + String(getFreePinAnalog()) + "]");
} else if (item.indexOf("pin") != -1) {
item.replace("pin", "pin[" + String(getFreePinAll()) + "]");
}
item.replace("\r\n", "");
item.replace("\r", "");
item.replace("\n", "");
addFile(DEVICE_CONFIG_FILE, "\n" + item);
}
void delAllItems() {
removeFile(DEVICE_CONFIG_FILE);
addFile(DEVICE_CONFIG_FILE, String(firstLine));
removeFile("id.txt");
removeFile("order.txt");
removeFile("pins.txt");
}
uint8_t getNewElementNumber(String file) {
uint8_t number = readFile(file, 100).toInt();
number++;
removeFile(file);
addFile(file, String(number));
return number;
}
uint8_t getFreePinAll() {
#ifdef ESP8266
uint8_t pins[] = {0, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5};
#endif
#ifdef ESP32
uint8_t pins[] = {0, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5};
#endif
uint8_t array_sz = sizeof(pins) / sizeof(pins[0]);
uint8_t i = getNewElementNumber("pins.txt");
if (i < array_sz) {
return pins[i];
} else {
return 0;
}
}
uint8_t getFreePinAnalog() {
#ifdef ESP8266
return 0;
#endif
}
//void do_getJsonListFromCsv() {
// if (getJsonListFromCsvFlag) {
// getJsonListFromCsvFlag = false;
// removeFile("items/items.json");
// addFile("items/items.json", getJsonListFromCsv(DEVICE_CONFIG_FILE, 1));
// }
//}
//
//String getJsonListFromCsv(String csvFile, int colum) {
// File configFile = LittleFS.open("/" + csvFile, "r");
// if (!configFile) {
// return "error";
// }
// configFile.seek(0, SeekSet);
//
// String outJson = "{}";
//
// int count = -1;
//
// while (configFile.position() != configFile.size()) {
// count++;
// String item = configFile.readStringUntil('\n');
// if (count > 0) {
// String line = selectFromMarkerToMarker(item, ";", colum);
// jsonWriteStr(outJson, line, line);
// }
// }
// configFile.close();
// csvFile = "";
// return outJson;
//}
//
//void do_delElement() {
// if (delElementFlag) {
// delElementFlag = false;
// delElement(itemsFile, itemsLine);
// }
//}
//
//void delElement(String _itemsFile, String _itemsLine) {
// File configFile = LittleFS.open("/" + _itemsFile, "r");
// if (!configFile) {
// return;
// }
// configFile.seek(0, SeekSet);
// String finalConf;
// int count = -1;
// while (configFile.position() != configFile.size()) {
// count++;
// String item = configFile.readStringUntil('\n');
// Serial.print(_itemsLine);
// Serial.print(" ");
// Serial.println(count);
// if (count != _itemsLine.toInt()) {
// if (count == 0) {
// finalConf += item;
// } else {
// finalConf += "\n" + item;
// }
// }
// }
// removeFile(_itemsFile);
// addFile(_itemsFile, finalConf);
// Serial.println(finalConf);
// itemsFile = "";
// itemsLine = "";
// configFile.close();
//}

View File

@@ -1,153 +0,0 @@
#include "Global.h"
//
#include <LITTLEFS.h>
void sendLogData(String file, String topic);
static const char* MODULE = "Log";
#ifdef LOGGING_ENABLED
//===============================================Логирование============================================================
//logging temp1 1 10 Температура Датчики 2
void logging() {
String value_name = sCmd.next();
String period_min = sCmd.next();
String maxCount = sCmd.next();
String widget_name = sCmd.next();
widget_name.replace("#", " ");
String page_name = sCmd.next();
String page_number = sCmd.next();
logging_value_names_list += value_name + ",";
enter_to_logging_counter++; //считаем количество входов в эту функцию
jsonWriteStr(configOptionJson, value_name + "_c", maxCount); //создаем в файловой системе переменную количества точек на графике с отметкой _c что значит count
//создаем график в приложении с топиком _ch /prefix/3234045-1589487/value_name_ch
createChart(widget_name, page_name, page_number, "chart", value_name + "_ch", maxCount);
if (enter_to_logging_counter == LOG1) {
ts.add(
LOG1, period_min.toInt() * 1000 * 60, [&](void*) {
String tmp_buf_1 = selectFromMarkerToMarker(logging_value_names_list, ",", 0);
deleteOldDate("log." + tmp_buf_1 + ".txt", jsonReadInt(configOptionJson, tmp_buf_1 + "_c"), jsonReadStr(configLiveJson, tmp_buf_1));
pm.info("logging for " + tmp_buf_1 + " done");
},
nullptr, false);
}
if (enter_to_logging_counter == LOG2) {
ts.add(
LOG2, period_min.toInt() * 1000 * 60, [&](void*) {
String tmp_buf_2 = selectFromMarkerToMarker(logging_value_names_list, ",", 1);
deleteOldDate("log." + tmp_buf_2 + ".txt", jsonReadInt(configOptionJson, tmp_buf_2 + "_c"), jsonReadStr(configLiveJson, tmp_buf_2));
pm.info("logging for " + tmp_buf_2 + " done");
},
nullptr, false);
}
if (enter_to_logging_counter == LOG3) {
ts.add(
LOG3, period_min.toInt() * 1000 * 60, [&](void*) {
String tmp_buf_3 = selectFromMarkerToMarker(logging_value_names_list, ",", 2);
deleteOldDate("log." + tmp_buf_3 + ".txt", jsonReadInt(configOptionJson, tmp_buf_3 + "_c"), jsonReadStr(configLiveJson, tmp_buf_3));
pm.info("logging for " + tmp_buf_3 + " done");
},
nullptr, false);
}
if (enter_to_logging_counter == LOG4) {
ts.add(
LOG4, period_min.toInt() * 1000 * 60, [&](void*) {
String tmp_buf_4 = selectFromMarkerToMarker(logging_value_names_list, ",", 3);
deleteOldDate("log." + tmp_buf_4 + ".txt", jsonReadInt(configOptionJson, tmp_buf_4 + "_c"), jsonReadStr(configLiveJson, tmp_buf_4));
pm.info("logging for " + tmp_buf_4 + " done");
},
nullptr, false);
}
if (enter_to_logging_counter == LOG5) {
ts.add(
LOG5, period_min.toInt() * 1000 * 60, [&](void*) {
String tmp_buf_5 = selectFromMarkerToMarker(logging_value_names_list, ",", 4);
deleteOldDate("log." + tmp_buf_5 + ".txt", jsonReadInt(configOptionJson, tmp_buf_5 + "_c"), jsonReadStr(configLiveJson, tmp_buf_5));
pm.info("logging for " + tmp_buf_5 + " done");
},
nullptr, false);
}
}
/*
* Удаление стрых данных и запись новых
*/
void deleteOldDate(const String filename, size_t max_lines_cnt, String payload) {
String log_date = readFile(filename, 5120);
size_t lines_cnt = itemsCount(log_date, "\r\n");
pm.info("log " + filename + " (" + String(lines_cnt, DEC) + ")");
if ((lines_cnt > max_lines_cnt + 1) || !lines_cnt) {
removeFile(filename);
lines_cnt = 0;
}
if (lines_cnt > max_lines_cnt) {
log_date = deleteBeforeDelimiter(log_date, "\r\n");
if (timeNow->hasTimeSynced()) {
log_date += timeNow->getTimeUnix() + " " + payload + "\r\n";
writeFile(filename, log_date);
}
} else {
if (timeNow->hasTimeSynced()) {
addFileLn(filename, timeNow->getTimeUnix() + " " + payload);
}
}
}
//=========================================Выбор какие данные отправлять==================================================================
void choose_log_date_and_send() {
String all_line = logging_value_names_list;
while (all_line.length() != 0) {
String tmp = selectToMarker(all_line, ",");
sendLogData("log." + tmp + ".txt", tmp + "_ch");
all_line = deleteBeforeDelimiter(all_line, ",");
}
}
//=========================================Отправка данных===================================================================================
void sendLogData(String file, String topic) {
String log_date = readFile(file, 5120);
if (log_date != "failed") {
log_date.replace("\r\n", "\n");
log_date.replace("\r", "\n");
String buf = "{}";
String json_array;
String unix_time;
String value;
while (log_date.length()) {
String tmp = selectToMarker(log_date, "\n");
log_date = deleteBeforeDelimiter(log_date, "\n");
unix_time = selectToMarker(tmp, " ");
jsonWriteInt(buf, "x", unix_time.toInt());
value = deleteBeforeDelimiter(tmp, " ");
jsonWriteFloat(buf, "y1", value.toFloat());
if (log_date.length() < 3) {
json_array += buf;
} else {
json_array += buf + ",";
}
buf = "{}";
}
unix_time = "";
value = "";
log_date = "";
json_array = "{\"status\":[" + json_array + "]}";
pm.info(json_array);
MqttClient::publishChart(topic, json_array);
}
}
void clean_log_date() {
String all_line = logging_value_names_list;
while (all_line.length()) {
String tmp = selectToMarker(all_line, ",");
removeFile("log." + tmp + ".txt");
all_line = deleteBeforeDelimiter(all_line, ",");
}
}
#endif

View File

@@ -1,86 +0,0 @@
#include "Module/Telnet.h"
bool Telnet::onInit() {
_server = new WiFiServer(_port);
_term = new Terminal();
_term->enableControlCodes();
_term->enableEcho(false);
_term->setStream(&_client);
return true;
}
void Telnet::onEnd() {
delete _server;
}
bool Telnet::onStart() {
_server->begin();
_server->setNoDelay(true);
return true;
}
void Telnet::onStop() {
if (hasClient()) {
_client.stop();
}
_server->stop();
}
bool Telnet::hasClient() { return _client.connected(); }
void Telnet::sendData(const String& data) {
if (hasClient()) {
_client.write(data.c_str());
}
}
void Telnet::setCommandShell(CommandShell* shell) {
_shell = shell;
_shell->setTerm(_term);
}
void Telnet::setEventHandler(TelnetEventHandler h) { _eventHandler = h; }
void Telnet::onLoop() {
if (_server->hasClient()) {
if (!_client) {
_client = _server->available();
} else {
if (!_client.connected()) {
_server->stop();
_client = _server->available();
} else {
WiFiClient rejected;
rejected = _server->available();
rejected.stop();
}
}
}
if (_lastConnected != hasClient()) {
_lastConnected = hasClient();
if (_lastConnected) {
onConnect();
} else {
onDisconnect();
}
}
if (hasClient() && _shell != nullptr) _shell->loop();
}
bool Telnet::isShellActive() {
return _shell->active();
}
void Telnet::onConnect() {
if (_eventHandler) {
_eventHandler(TE_CONNECTED, &_client);
}
}
void Telnet::onDisconnect() {
if (_eventHandler) {
_eventHandler(TE_DISCONNECTED, nullptr);
}
}

View File

@@ -1,320 +0,0 @@
#include "Module/Terminal.h"
#include "Utils/TimeUtils.h"
#define INPUT_MAX_LENGHT 255
Terminal::Terminal(Stream *stream) : _stream{stream},
_line(INPUT_MAX_LENGHT),
_cc_pos(0),
_color(false),
_controlCodes(false),
_echo(false),
_eol(CRLF) { state = ST_NORMAL; };
void Terminal::setStream(Stream *stream) {
_stream = stream;
}
void Terminal::setOnReadLine(TerminalInputEventHandler h) { inputHandler_ = h; }
void Terminal::setOnEvent(TerminalEventHandler h) { eventHandler_ = h; }
bool Terminal::available() {
return _stream != nullptr ? _stream->available() : false;
}
void Terminal::setEOL(EOLType_t eol) {
_eol = eol;
}
void Terminal::enableEcho(bool enabled) {
_echo = enabled;
}
void Terminal::enableColors(bool enabled) {
_color = enabled;
}
void Terminal::enableControlCodes(bool enabled) {
_controlCodes = enabled;
}
void Terminal::quit() {}
void Terminal::loop() {
if (_stream == nullptr || !_stream->available()) return;
byte moveX = 0;
byte moveY = 0;
char c = _stream->read();
_lastReceived = millis();
if (state == ST_INACTIVE) {
// wait for CR
if (c == CHAR_CR) {
if (eventHandler_) {
eventHandler_(EVENT_OPEN, _stream);
state = ST_NORMAL;
}
}
// or ignore all other
return;
}
if (c == CHAR_LF || c == CHAR_NULL || c == CHAR_BIN)
return;
// Esc
if (c == CHAR_ESC || c == 195) {
state = ST_ESC_SEQ;
_cc_pos = 0;
for (size_t i = 0; i < 2; ++i) {
bool timeout = false;
while (!_stream->available() &&
!(timeout = millis_since(_lastReceived) > 10)) {
delay(0);
}
if (timeout) {
state = ST_NORMAL;
break;
}
_lastReceived = millis();
c = _stream->read();
_cc_buf[_cc_pos] = c;
if ((c == '[') || ((c >= 'A' && c <= 'Z') || c == '~')) {
_cc_pos++;
_cc_buf[++_cc_pos] = '\x00';
}
}
uint8_t i;
for (i = 0; i < 10; ++i) {
if (strcmp(_cc_buf, keyMap[i].cc) == 0) {
c = keyMap[i].ch;
state = ST_NORMAL;
}
}
}
if (state == ST_ESC_SEQ) {
state = ST_NORMAL;
return;
}
// WHEN NORMAL
if (state == ST_NORMAL) {
if (c == CHAR_ESC) {
if (!_line.available()) {
// QUIT
state = ST_INACTIVE;
if (eventHandler_)
eventHandler_(EVENT_CLOSE, _stream);
} else {
// CLEAR
_line.clear();
if (_controlCodes) {
clear_line();
} else {
println();
}
}
return;
}
switch (c) {
case CHAR_CR:
println();
if (inputHandler_)
inputHandler_(_line.c_str());
_line.clear();
moveY++;
break;
case CHAR_TAB:
if (eventHandler_)
eventHandler_(EVENT_TAB, _stream);
return;
case KEY_LEFT:
if (_line.prev())
moveX--;
break;
case KEY_RIGHT:
if (_line.next())
moveX++;
break;
case KEY_HOME:
moveX = -1 * _line.home();
break;
case KEY_END:
moveX = _line.end();
break;
case CHAR_BS:
case KEY_DEL:
if (_line.backspace()) {
backsp();
moveX--;
}
break;
default:
// printable ascii 7bit or printable 8bit ISO8859
if ((c & '\x7F') >= 32 && (c & '\x7F') < 127)
if (_line.write(c)) {
if (_echo) write(c);
moveX++;
}
break;
}
// if (controlCodesEnabled)
// move(startY + moveY, startX + moveX);
}
}
bool Terminal::setLine(const uint8_t *ptr, size_t size) {
_line.clear();
if (_line.write(ptr, size))
print(_line.c_str());
return true;
}
CharBuffer &Terminal::getLine() { return _line; }
void Terminal::start() {
if (_controlCodes) initscr();
println();
}
void Terminal::initscr() {
write_P(SEQ_LOAD_G1);
attrset(A_NORMAL);
move(0, 0);
clear();
}
void Terminal::attrset(const uint16_t attr) {
uint8_t i;
if (attr != this->attr) {
this->write_P(SEQ_ATTRSET);
i = (attr & F_COLOR) >> 8;
if (i >= 1 && i <= 8) {
this->write_P(SEQ_ATTRSET_FCOLOR);
this->write(i - 1 + '0');
}
i = (attr & B_COLOR) >> 12;
if (i >= 1 && i <= 8) {
this->write_P(SEQ_ATTRSET_BCOLOR);
this->write(i - 1 + '0');
}
if (attr & A_REVERSE)
this->write_P(SEQ_ATTRSET_REVERSE);
if (attr & A_UNDERLINE)
this->write_P(SEQ_ATTRSET_UNDERLINE);
if (attr & A_BLINK)
this->write_P(SEQ_ATTRSET_BLINK);
if (attr & A_BOLD)
this->write_P(SEQ_ATTRSET_BOLD);
if (attr & A_DIM)
this->write_P(SEQ_ATTRSET_DIM);
this->write('m');
this->attr = attr;
}
}
void Terminal::clear() { write_P(SEQ_CLEAR); }
void Terminal::clear_line() {
write(CHAR_CR);
write_P(ESC_CLEAR_EOL);
}
void Terminal::move(uint8_t y, uint8_t x) {
write_P(SEQ_CSI);
writeByDigit(y + 1);
write(';');
writeByDigit(x + 1);
write('H');
curY = y;
curX = x;
}
void Terminal::writeByDigit(uint8_t i) {
uint8_t ii;
if (i >= 10) {
if (i >= 100) {
ii = i / 100;
write(ii + '0');
i -= 100 * ii;
}
ii = i / 10;
write(ii + '0');
i -= 10 * ii;
}
write(i + '0');
}
void Terminal::backsp() {
write(CHAR_BS);
write(CHAR_SPACE);
write(CHAR_BS);
}
size_t Terminal::println(const char *str) {
size_t n = print(str);
return n += println();
}
size_t Terminal::println(void) {
size_t n = 0;
switch (_eol) {
case CRLF:
n += write(CHAR_CR);
n += write(CHAR_LF);
break;
case LF:
n += write(CHAR_LF);
break;
case LFCR:
n += write(CHAR_LF);
n += write(CHAR_CR);
break;
case CR:
n += write(CHAR_CR);
break;
}
return n;
}
size_t Terminal::write(uint8_t ch) {
size_t n = 0;
if (_stream)
n = _stream->write(ch);
return n;
}
size_t Terminal::write_P(PGM_P str) {
uint8_t ch;
size_t n = 0;
while ((ch = pgm_read_byte(str + n)) != '\x0') {
_stream->write(ch);
n++;
}
return n;
}
size_t Terminal::write(const uint8_t *buf, size_t size) {
size_t n = 0;
while (size--) {
if (_stream->write(*buf++))
n++;
else
break;
}
return n;
}

View File

@@ -1,323 +0,0 @@
#include "MqttClient.h"
#include <LittleFS.h>
#include "Class/NotAsinc.h"
#include "Global.h"
#include "Init.h"
static const char* MODULE = "Mqtt";
namespace MqttClient {
// Errors
int wifi_lost_error = 0;
int mqtt_lost_error = 0;
bool connected = false;
// Session params
String mqttPrefix;
String mqttRootDevice;
void init() {
myNotAsincActions->add(
do_MQTTPARAMSCHANGED, [&](void*) {
reconnect();
},
nullptr);
mqtt.setCallback(handleSubscribedUpdates);
ts.add(
WIFI_MQTT_CONNECTION_CHECK, MQTT_RECONNECT_INTERVAL,
[&](void*) {
if (isNetworkActive()) {
if (mqtt.connected()) {
if (!connected) {
pm.info("OK");
setLedStatus(LED_OFF);
connected = true;
}
} else {
connect();
if (!just_load) mqtt_lost_error++;
}
} else {
if (connected) {
pm.error("connection lost");
connected = false;
}
ts.remove(WIFI_MQTT_CONNECTION_CHECK);
wifi_lost_error++;
startAPMode();
}
},
nullptr, true);
}
void disconnect() {
pm.info("disconnect");
mqtt.disconnect();
}
void reconnect() {
disconnect();
connect();
}
void loop() {
if (!isNetworkActive() || !mqtt.connected()) {
return;
}
mqtt.loop();
}
void subscribe() {
pm.info("subscribe");
mqtt.subscribe(mqttPrefix.c_str());
mqtt.subscribe((mqttRootDevice + "/+/control").c_str());
mqtt.subscribe((mqttRootDevice + "/order").c_str());
mqtt.subscribe((mqttRootDevice + "/update").c_str());
mqtt.subscribe((mqttRootDevice + "/devc").c_str());
mqtt.subscribe((mqttRootDevice + "/devs").c_str());
}
boolean connect() {
pm.info("connect");
String addr = jsonReadStr(configSetupJson, "mqttServer");
if (!addr) {
pm.error("no broker address");
return false;
}
int port = jsonReadInt(configSetupJson, "mqttPort");
String user = jsonReadStr(configSetupJson, "mqttUser");
String pass = jsonReadStr(configSetupJson, "mqttPass");
//Session params
mqttPrefix = jsonReadStr(configSetupJson, "mqttPrefix");
mqttRootDevice = mqttPrefix + "/" + chipId;
pm.info("broker " + addr + ":" + String(port, DEC));
pm.info("topic " + mqttRootDevice);
setLedStatus(LED_FAST);
mqtt.setServer(addr.c_str(), port);
bool res = false;
if (!mqtt.connected()) {
if (mqtt.connect(chipId.c_str(), user.c_str(), pass.c_str())) {
pm.info("connected");
setLedStatus(LED_OFF);
subscribe();
res = true;
} else {
pm.error("could't connect, retry in " + String(MQTT_RECONNECT_INTERVAL / 1000) + "s");
setLedStatus(LED_FAST);
}
}
return res;
}
void handleSubscribedUpdates(char* topic, uint8_t* payload, size_t length) {
String topicStr = String(topic);
pm.info(topicStr);
String payloadStr;
payloadStr.reserve(length + 1);
for (size_t i = 0; i < length; i++) {
payloadStr += (char)payload[i];
}
pm.info(payloadStr);
if (payloadStr.startsWith("HELLO")) {
pm.info("Full update");
publishWidgets();
publishState();
#ifdef LOGGING_ENABLED
choose_log_date_and_send();
#endif
} else if (topicStr.indexOf("control")) {
//iotTeam/12882830-1458415/light 1
String key = selectFromMarkerToMarker(topicStr, "/", 3);
orderBuf += key;
orderBuf += " ";
orderBuf += payloadStr;
orderBuf += ",";
} else if (topicStr.indexOf("order")) {
payloadStr.replace("_", " ");
orderBuf += payloadStr;
orderBuf += ",";
} else if (topicStr.indexOf("update")) {
if (payloadStr == "1") {
myNotAsincActions->make(do_UPGRADE);
}
} else if (topicStr.indexOf("devc")) {
writeFile(String(DEVICE_CONFIG_FILE), payloadStr);
Device_init();
} else if (topicStr.indexOf("devs")) {
writeFile(String(DEVICE_SCENARIO_FILE), payloadStr);
loadScenario();
}
}
boolean publish(const String& topic, const String& data) {
if (mqtt.beginPublish(topic.c_str(), data.length(), false)) {
mqtt.print(data);
return mqtt.endPublish();
}
return false;
}
boolean publishData(const String& topic, const String& data) {
String path = mqttRootDevice + "/" + topic;
if (!publish(path, data)) {
pm.error("on publish data");
return false;
}
return true;
}
boolean publishChart(const String& topic, const String& data) {
String path = mqttRootDevice + "/" + topic + "/status";
if (!publish(path, data)) {
pm.error("on publish chart");
return false;
}
return true;
}
boolean publishControl(String id, String topic, String state) {
String path = mqttPrefix + "/" + id + "/" + topic + "/control";
return mqtt.publish(path.c_str(), state.c_str(), false);
}
boolean publishChart_test(const String& topic, const String& data) {
String path = mqttRootDevice + "/" + topic + "/status";
return mqtt.publish(path.c_str(), data.c_str(), false);
}
boolean publishStatus(const String& topic, const String& data) {
String path = mqttRootDevice + "/" + topic + "/status";
String json = "{}";
jsonWriteStr(json, "status", data);
return mqtt.publish(path.c_str(), json.c_str(), false);
}
#ifdef LAYOUT_IN_RAM
void publishWidgets() {
if (all_widgets != "") {
int counter = 0;
String line;
int psn_1 = 0;
int psn_2;
do {
psn_2 = all_widgets.indexOf("\r\n", psn_1); //\r\n
line = all_widgets.substring(psn_1, psn_2);
line.replace("\n", "");
line.replace("\r\n", "");
//jsonWriteStr(line, "id", String(counter));
//jsonWriteStr(line, "pageId", String(counter));
counter++;
sendMQTT("config", line);
Serial.println("[V] " + line);
psn_1 = psn_2 + 1;
} while (psn_2 + 2 < all_widgets.length());
getMemoryLoad("[I] after send all widgets");
}
}
#endif
#ifndef LAYOUT_IN_RAM
void publishWidgets() {
auto file = seekFile("layout.txt");
if (!file) {
pm.error("no file layout.txt");
return;
}
while (file.available()) {
String payload = file.readStringUntil('\n');
pm.info("widgets: " + payload);
publishData("config", payload);
}
file.close();
}
#endif
void publishState() {
// берет строку json и ключи превращает в топики а значения колючей в них посылает
// {"name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1"}
// "name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1"
// "name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1",
String str = configLiveJson;
str.replace("{", "");
str.replace("}", "");
str += ",";
while (str.length()) {
String tmp = selectToMarker(str, ",");
String topic = selectToMarker(tmp, ":");
topic.replace("\"", "");
String state = selectToMarkerLast(tmp, ":");
state.replace("\"", "");
if ((topic != "time") && (topic != "name") && (topic != "lang") && (topic != "ip") && (topic.indexOf("_in") < 0)) {
publishStatus(topic, state);
}
str = deleteBeforeDelimiter(str, ",");
}
}
const String getStateStr() {
switch (mqtt.state()) {
case -4:
return F("no respond");
break;
case -3:
return F("connection was broken");
break;
case -2:
return F("connection failed");
break;
case -1:
return F("client disconnected");
break;
case 0:
return F("client connected");
break;
case 1:
return F("doesn't support the requested version");
break;
case 2:
return F("rejected the client identifier");
break;
case 3:
return F("unable to accept the connection");
break;
case 4:
return F("wrong username/password");
break;
case 5:
return F("not authorized to connect");
break;
default:
return F("unspecified");
break;
}
}
} // namespace MqttClient

View File

@@ -1,75 +0,0 @@
#include "MqttDiscovery.h"
namespace Discovery {
static const char json_is_defined[] = "is_defined";
static const char jsonId[] = "id";
static const char jsonBatt[] = "batt";
static const char jsonLux[] = "lux";
static const char jsonPres[] = "pres";
static const char jsonFer[] = "fer";
static const char jsonMoi[] = "moi";
static const char jsonHum[] = "hum";
static const char jsonTemp[] = "tem";
static const char jsonStep[] = "steps";
static const char jsonWeight[] = "weight";
static const char jsonPresence[] = "presence";
static const char jsonAltim[] = "altim";
static const char jsonAltif[] = "altift";
static const char jsonTempf[] = "tempf";
static const char jsonMsg[] = "message";
static const char jsonVal[] = "value";
static const char jsonVolt[] = "volt";
static const char jsonCurrent[] = "current";
static const char jsonPower[] = "power";
static const char jsonGpio[] = "gpio";
static const char jsonFtcd[] = "ftcd";
static const char jsonWm2[] = "wattsm2";
static const char jsonAdc[] = "adc";
static const char jsonPa[] = "pa";
const String getValueJson(const char* str) {
char buf[32];
sprintf(buf, "{{ value_json.%s }}", str);
return buf;
}
void createDiscovery(
const char* type, const char* name, const char* clazz,
const char* value_template, const char* payload_on, const char* payload_off,
const char* maasure_unit, int off_delay, const char* has_payload, const char* no_payload,
const char* avail_topi, const char* cmd_topic, const char* state_topic, bool child) {
//const char* unique_id = getUniqueId(name).c_str();
}
void createADC(const char* name) {
createDiscovery(
"Type", "Name", "Clazz",
"Value", "Payload", "NoPayload",
"Measure", 0, "HasPayload", "NoPayload",
"", "", "", false);
}
void createSwitch(const char* name) {
createDiscovery(
"Type", "Name", "Clazz",
"Value", "Payload", "NoPayload",
"Measure", 0, "HasPayload", "NoPayload",
"", "", "", false);
}
// component,
// type,
// name,
// availability topic,
// device class,
// value template, payload on, payload off, unit of measurement
const char* BMEsensor[6][8] = {
{"sensor", "tempc", "bme", "temperature", "", "", "°C"}, //jsonTemp
{"sensor", "tempf", "bme", "temperature", "", "", "°F"}, //jsonTempf
{"sensor", "pa", "bme", "", "", "", "hPa"}, //jsonPa
{"sensor", "hum", "bme", "humidity", "", "", "%"}, // jsonHum
{"sensor", "altim", "bme", "", "", "", "m"}, //jsonAltim
{"sensor", "altift", "bme", "", "", "", "ft"} // jsonAltif
};
} // namespace Discovery

View File

@@ -1,60 +0,0 @@
#include "Global.h"
void Push_init() {
server.on("/pushingboxDate", HTTP_GET, [](AsyncWebServerRequest* request) {
if (request->hasArg("pushingbox_id")) {
jsonWriteStr(configSetupJson, "pushingbox_id", request->getParam("pushingbox_id")->value());
}
saveConfig();
request->send(200, "text/text", "ok"); // отправляем ответ о выполнении
});
}
void pushControl() {
String title = sCmd.next();
title.replace("#", " ");
String body = sCmd.next();
body.replace("#", " ");
static String body_old;
const char* logServer = "api.pushingbox.com";
String deviceId = jsonReadStr(configSetupJson, "pushingbox_id");
Serial.println("- starting client");
WiFiClient client_push;
Serial.println("- connecting to pushing server: " + String(logServer));
if (!client_push.connect(logServer, 80)) {
Serial.println("- not connected");
} else {
Serial.println("- succesfully connected");
String postStr = "devid=";
postStr += String(deviceId);
postStr += "&title=";
postStr += String(title);
postStr += "&body=";
postStr += String(body);
postStr += "\r\n\r\n";
Serial.println("- sending data...");
client_push.print("POST /pushingbox HTTP/1.1\n");
client_push.print("Host: api.pushingbox.com\n");
client_push.print("Connection: close\n");
client_push.print("Content-Type: application/x-www-form-urlencoded\n");
client_push.print("Content-Length: ");
client_push.print(postStr.length());
client_push.print("\n\n");
client_push.print(postStr);
}
client_push.stop();
Serial.println("- stopping the client");
}

View File

@@ -1,57 +0,0 @@
#ifdef SSDP
#ifdef ESP8266
#include <ESP8266SSDP.h>
#endif
#ifdef ESP32
#include <ESP32SSDP.h>
#endif
#include <SSDP.h>
#include "Global.h"
void SsdpInit() {
server.on("/description.xml", HTTP_GET, [](AsyncWebServerRequest* request) {
String ssdpSend = "<root xmlns=\"urn:schemas-upnp-org:device-1-0\">";
String ssdpHeder = xmlNode("major", "1");
ssdpHeder += xmlNode("minor", "0");
ssdpHeder = xmlNode("specVersion", ssdpHeder);
ssdpHeder += xmlNode("URLBase", "http://" + WiFi.localIP().toString());
String ssdpDescription = xmlNode("deviceType", "upnp:rootdevice");
ssdpDescription += xmlNode("friendlyName", jsonReadStr(configSetupJson, "name"));
ssdpDescription += xmlNode("presentationURL", "/");
ssdpDescription += xmlNode("serialNumber", getChipId());
#ifdef ESP8266
ssdpDescription += xmlNode("modelName", "ESP8266");
#endif
#ifdef ESP32
ssdpDescription += xmlNode("modelName", "ESP32");
#endif
ssdpDescription += xmlNode("modelNumber", getChipId());
ssdpDescription += xmlNode("modelURL", "https://github.com/IoTManagerProject/IoTManager/wiki");
ssdpDescription += xmlNode("manufacturer", "Borisenko Dmitry");
ssdpDescription += xmlNode("manufacturerURL", "https://github.com/IoTManagerProject/IoTManager");
ssdpDescription += xmlNode("UDN", "uuid:38323636-4558-4dda-9188-cda0e6" + decToHex(ESP.getChipId(), 6));
ssdpDescription = xmlNode("device", ssdpDescription);
ssdpHeder += ssdpDescription;
ssdpSend += ssdpHeder;
ssdpSend += "</root>";
Serial.println("->!!!SSDP Get request received");
request->send(200, "text/xml", ssdpSend);
});
//Если версия 2.0.0 закаментируйте следующую строчку
SSDP.setDeviceType("upnp:rootdevice");
SSDP.setSchemaURL("description.xml");
SSDP.begin();
}
String xmlNode(String tags, String data) {
String temp = "<" + tags + ">" + data + "</" + tags + ">";
return temp;
}
String decToHex(uint32_t decValue, byte desiredStringLength) {
String hexString = String(decValue, HEX);
while (hexString.length() < desiredStringLength) hexString = "0" + hexString;
return hexString;
}
#endif

View File

@@ -1,97 +0,0 @@
#include "Cmd.h"
#include "Global.h"
#include "Class/ScenarioClass.h"
static const char* MODULE = "Scen";
boolean isScenarioEnabled() {
return jsonReadBool(configSetupJson, "scen") && eventBuf != "";
}
void loopScenario() {
if (!isScenarioEnabled()) {
return;
}
String scenarioTmp = scenario;
scenarioTmp += "\n";
scenarioTmp.replace("\r\n", "\n");
scenarioTmp.replace("\r", "\n");
while (scenarioTmp.length()) {
String scenBlok = selectToMarker(scenarioTmp, "end"); //выделяем первый сценарий
if (!scenBlok.length()) {
return;
}
size_t i = 0;
i++;
if (scenario_line_status[i] == 1) {
String condition = selectToMarker(scenBlok, "\n"); //выделяем условие
String conditionParam = selectFromMarkerToMarker(condition, " ", 0); //выделяем параметр условия
String order = eventBuf;
String eventParam = selectToMarker(order, ","); //выделяем параметр события
if (conditionParam == eventParam) { //если поступившее событие равно событию заданному buttonSet1 в файле начинаем его обработку
String conditionSign = selectFromMarkerToMarker(condition, " ", 1); //выделяем знак (=)
String conditionValue = selectFromMarkerToMarker(condition, " ", 2); //выделяем значение (1)
boolean flag = false;
String eventParam = jsonReadStr(configLiveJson, conditionParam); //получаем значение этого параметра события из json
if (conditionSign == "=") {
flag = eventParam == conditionValue;
} else if (conditionSign == "!=") {
flag = eventParam != conditionValue;
} else if (conditionSign == "<") {
flag = eventParam.toInt() < conditionValue.toInt();
} else if (conditionSign == ">") {
flag = eventParam.toInt() > conditionValue.toInt();
} else if (conditionSign == ">=") {
flag = eventParam.toInt() >= conditionValue.toInt();
} else if (conditionSign == "<=") {
flag = eventParam.toInt() <= conditionValue.toInt();
}
if (flag) {
scenBlok = deleteBeforeDelimiter(scenBlok, "\n"); // удаляем строку самого сценария оставляя только команды
pm.info("do: " + scenBlok);
spaceExecute(scenBlok); // выполняем все команды
}
}
}
scenarioTmp = deleteBeforeDelimiter(scenarioTmp, "end\n"); //удаляем первый сценарий
}
String eventBufTmp = eventBuf; //читаем файл событий
eventBufTmp = deleteBeforeDelimiter(eventBufTmp, ","); //удаляем выполненное событие
eventBuf = eventBufTmp; //записываем обновленный файл событий
}
void eventGen(String event_name, String number) {
if (!jsonReadBool(configSetupJson, "scen")) {
return;
}
eventBuf = event_name + number + ",";
}
String add_set(String str) {
String num1 = str.substring(str.length() - 1);
String num2 = str.substring(str.length() - 2, str.length() - 1);
if (isDigitStr(num1) && isDigitStr(num2)) {
str = str.substring(0, str.length() - 2) + "Set" + num2 + num1;
} else {
if (isDigitStr(num1)) {
str = str.substring(0, str.length() - 1) + "Set" + num1;
}
}
return str;
}
//button-out1 = 1
//button-out2 1
//button-out3 1
//end

View File

@@ -1,571 +0,0 @@
#include "Class/SensorAnalog.h"
#include "Cmd.h"
#include "Global.h"
GMedian<10, int> medianFilter;
DHTesp dht;
Adafruit_BMP280 bmp;
Adafruit_Sensor *bmp_temp = bmp.getTemperatureSensor();
Adafruit_Sensor *bmp_pressure = bmp.getPressureSensor();
Adafruit_BME280 bme;
Adafruit_Sensor *bme_temp = bme.getTemperatureSensor();
Adafruit_Sensor *bme_pressure = bme.getPressureSensor();
Adafruit_Sensor *bme_humidity = bme.getHumiditySensor();
const String perceptionStr(byte value);
const String comfortStr(ComfortState value);
void bmp280T_reading();
void sensorsInit() {
ts.add(
SENSORS, 15000, [&](void *) {
String buf = sensorReadingMap;
while (buf.length()) {
String tmp = selectToMarker(buf, ",");
sCmd.readStr(tmp);
buf = deleteBeforeDelimiter(buf, ",");
}
},
nullptr, true);
}
#ifdef ANALOG_ENABLED
//==============================================Модуль аналогового сенсора===========================================================================================
//analog-adc;id;anydata;Сенсоры;Аналоговый;order;pin-adc;map[1,1024,1,100];c[1]
//===================================================================================================================================================================
void analogAdc() {
mySensorAnalog = new SensorAnalog();
mySensorAnalog->update();
String key = mySensorAnalog->gkey();
String pin = mySensorAnalog->gpin();
sCmd.addCommand(key.c_str(), analogReading);
sensorReadingMap += key + ",";
jsonWriteStr(configOptionJson, key + "_pin", pin);
jsonWriteStr(configOptionJson, key + "_map", mySensorAnalog->gmap());
jsonWriteStr(configOptionJson, key + "_с", mySensorAnalog->gc());
mySensorAnalog->clear();
}
void analogReading() {
String key = sCmd.order();
String pin = jsonReadStr(configOptionJson, key + "_pin");
mySensorAnalog->SensorAnalogRead(key, pin);
}
#endif
#ifdef LEVEL_ENABLED
//=========================================Модуль ультрозвукового дальномера==================================================================
//ultrasonic-cm;id;anydata;Сенсоры;Расстояние;order;pin;map[1,100,1,100];c[1]
//=========================================================================================================================================
void ultrasonicCm() {
}
void ultrasonicReading() {
}
void levelPr() {
// String value_name = sCmd.next();
// String trig = sCmd.next();
// String echo = sCmd.next();
// String widget_name = sCmd.next();
// String page_name = sCmd.next();
// String type = sCmd.next();
// String empty_level = sCmd.next();
// String full_level = sCmd.next();
// String page_number = sCmd.next();
// levelPr_value_name = value_name;
// jsonWriteStr(configOptionJson, "e_lev", empty_level);
// jsonWriteStr(configOptionJson, "f_lev", full_level);
// jsonWriteStr(configOptionJson, "trig", trig);
// jsonWriteStr(configOptionJson, "echo", echo);
// pinMode(trig.toInt(), OUTPUT);
// pinMode(echo.toInt(), INPUT);
// createWidgetByType(widget_name, page_name, page_number, type, value_name);
// sensors_reading_map[0] = 1;
}
////ultrasonicCm cm 14 12 Дистанция,#см Датчики fillgauge 1
//void ultrasonicCm() {
// String value_name = sCmd.next();
// String trig = sCmd.next();
// String echo = sCmd.next();
// String widget_name = sCmd.next();
// String page_name = sCmd.next();
// String type = sCmd.next();
// String empty_level = sCmd.next();
// String full_level = sCmd.next();
// String page_number = sCmd.next();
// ultrasonicCm_value_name = value_name;
// jsonWriteStr(configOptionJson, "trig", trig);
// jsonWriteStr(configOptionJson, "echo", echo);
// pinMode(trig.toInt(), OUTPUT);
// pinMode(echo.toInt(), INPUT);
// createWidgetByType(widget_name, page_name, page_number, type, value_name);
// sensors_reading_map[0] = 1;
//}
//
void ultrasonic_reading() {
// long duration_;
// int distance_cm;
// int level;
// static int counter;
// int trig = jsonReadInt(configOptionJson, "trig");
// int echo = jsonReadInt(configOptionJson, "echo");
// digitalWrite(trig, LOW);
// delayMicroseconds(2);
// digitalWrite(trig, HIGH);
// delayMicroseconds(10);
// digitalWrite(trig, LOW);
// duration_ = pulseIn(echo, HIGH, 30000); // 3000 µs = 50cm // 30000 µs = 5 m
// distance_cm = duration_ / 29 / 2;
// distance_cm = medianFilter.filtered(distance_cm); //отсечение промахов медианным фильтром
// counter++;
// if (counter > TANK_LEVEL_SAMPLES) {
// counter = 0;
// level = map(distance_cm,
// jsonReadInt(configOptionJson, "e_lev"),
// jsonReadInt(configOptionJson, "f_lev"), 0, 100);
//
// jsonWriteInt(configLiveJson, levelPr_value_name, level);
// eventGen(levelPr_value_name, "");
//
// MqttClient::publishStatus(levelPr_value_name, String(level));
//
// Serial.println("[I] sensor '" + levelPr_value_name + "' data: " + String(level));
//
// jsonWriteInt(configLiveJson, ultrasonicCm_value_name, distance_cm);
// eventGen(ultrasonicCm_value_name, "");
//
// MqttClient::publishStatus(ultrasonicCm_value_name, String(distance_cm));
//
// Serial.println("[I] sensor '" + ultrasonicCm_value_name + "' data: " + String(distance_cm));
// }
}
#endif
//=========================================================================================================================================
//=========================================Модуль температурного сенсора ds18b20===========================================================
#ifdef DALLAS_ENABLED
//dallas temp1 2 1 Температура Датчики anydata 1
//dallas temp2 2 2 Температура Датчики anydata 2
void dallas() {
String value_name = sCmd.next();
String pin = sCmd.next();
String address = sCmd.next();
jsonWriteStr(configOptionJson, value_name + "_ds", address);
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String page_number = sCmd.next();
oneWire = new OneWire((uint8_t)pin.toInt());
sensors.setOneWire(oneWire);
sensors.begin();
sensors.setResolution(12);
dallas_value_name += value_name + ";";
createWidgetByType(widget_name, page_name, page_number, type, value_name);
sensors_reading_map[3] = 1;
}
void dallas_reading() {
float temp = 0;
byte num = sensors.getDS18Count();
String dallas_value_name_tmp_buf = dallas_value_name;
sensors.requestTemperatures();
for (byte i = 0; i < num; i++) {
temp = sensors.getTempCByIndex(i);
String buf = selectToMarker(dallas_value_name_tmp_buf, ";");
dallas_value_name_tmp_buf = deleteBeforeDelimiter(dallas_value_name_tmp_buf, ";");
jsonWriteStr(configLiveJson, buf, String(temp));
eventGen(buf, "");
MqttClient::publishStatus(buf, String(temp));
Serial.println("[I] sensor '" + buf + "' send date " + String(temp));
}
}
#endif
//=========================================================================================================================================
//=========================================Модуль сенсоров DHT=============================================================================
#ifdef DHT_ENABLED
//dhtT t 2 dht11 Температура#DHT,#t°C Датчики any-data 1
void dhtT() {
String value_name = sCmd.next();
String pin = sCmd.next();
String sensor_type = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String page_number = sCmd.next();
dhtT_value_name = value_name;
if (sensor_type == "dht11") {
dht.setup(pin.toInt(), DHTesp::DHT11);
}
if (sensor_type == "dht22") {
dht.setup(pin.toInt(), DHTesp::DHT22);
}
createWidgetByType(widget_name, page_name, page_number, type, value_name);
sensors_reading_map[4] = 1;
}
void dhtT_reading() {
float value = 0;
static int counter;
if (dht.getStatus() != 0 && counter < 5) {
MqttClient::publishStatus(dhtT_value_name, String(dht.getStatusString()));
counter++;
} else {
counter = 0;
value = dht.getTemperature();
if (String(value) != "nan") {
eventGen(dhtT_value_name, "");
jsonWriteStr(configLiveJson, dhtT_value_name, String(value));
MqttClient::publishStatus(dhtT_value_name, String(value));
Serial.println("[I] sensor '" + dhtT_value_name + "' data: " + String(value));
}
}
}
//dhtH h 2 dht11 Влажность#DHT,#t°C Датчики any-data 1
void dhtH() {
String value_name = sCmd.next();
String pin = sCmd.next();
String sensor_type = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String page_number = sCmd.next();
dhtH_value_name = value_name;
if (sensor_type == "dht11") {
dht.setup(pin.toInt(), DHTesp::DHT11);
}
if (sensor_type == "dht22") {
dht.setup(pin.toInt(), DHTesp::DHT22);
}
createWidgetByType(widget_name, page_name, page_number, type, value_name);
sensors_reading_map[5] = 1;
}
void dhtH_reading() {
float value = 0;
static int counter;
if (dht.getStatus() != 0 && counter < 5) {
MqttClient::publishStatus(dhtH_value_name, String(dht.getStatusString()));
counter++;
} else {
counter = 0;
value = dht.getHumidity();
if (String(value) != "nan") {
eventGen(dhtH_value_name, "");
jsonWriteStr(configLiveJson, dhtH_value_name, String(value));
MqttClient::publishStatus(dhtH_value_name, String(value));
Serial.println("[I] sensor '" + dhtH_value_name + "' data: " + String(value));
}
}
}
//dhtPerception Восприятие: Датчики 4
void dhtP() {
String widget_name = sCmd.next();
String page_name = sCmd.next();
String page_number = sCmd.next();
createWidgetByType(widget_name, page_name, page_number, "any-data", "dhtPerception");
sensors_reading_map[6] = 1;
}
void dhtP_reading() {
byte value;
if (dht.getStatus() != 0) {
MqttClient::publishStatus("dhtPerception", String(dht.getStatusString()));
} else {
value = dht.computePerception(jsonReadStr(configLiveJson, dhtT_value_name).toFloat(), jsonReadStr(configLiveJson, dhtH_value_name).toFloat(), false);
String final_line = perceptionStr(value);
jsonWriteStr(configLiveJson, "dhtPerception", final_line);
eventGen("dhtPerception", "");
MqttClient::publishStatus("dhtPerception", final_line);
if (mqtt.connected()) {
Serial.println("[I] sensor 'dhtPerception' data: " + final_line);
}
}
}
//dhtComfort Степень#комфорта: Датчики 3
void dhtC() {
String widget_name = sCmd.next();
String page_name = sCmd.next();
String page_number = sCmd.next();
createWidgetByType(widget_name, page_name, page_number, "anydata", "dhtComfort");
sensors_reading_map[7] = 1;
}
void dhtC_reading() {
ComfortState cf;
if (dht.getStatus() != 0) {
MqttClient::publishStatus("dhtComfort", String(dht.getStatusString()));
} else {
dht.getComfortRatio(cf, jsonReadStr(configLiveJson, dhtT_value_name).toFloat(), jsonReadStr(configLiveJson, dhtH_value_name).toFloat(), false);
String final_line = comfortStr(cf);
jsonWriteStr(configLiveJson, "dhtComfort", final_line);
eventGen("dhtComfort", "");
MqttClient::publishStatus("dhtComfort", final_line);
Serial.println("[I] sensor 'dhtComfort' send date " + final_line);
}
}
const String perceptionStr(byte value) {
String res;
switch (value) {
case 0:
res = F("Сухой воздух");
break;
case 1:
res = F("Комфортно");
break;
case 2:
res = F("Уютно");
break;
case 3:
res = F("Хорошо");
break;
case 4:
res = F("Неудобно");
break;
case 5:
res = F("Довольно неудобно");
break;
case 6:
res = F("Очень неудобно");
break;
case 7:
res = F("Невыносимо");
default:
res = F("Unknown");
break;
}
return res;
}
const String comfortStr(ComfortState value) {
String res;
switch (value) {
case Comfort_OK:
res = F("Отлично");
break;
case Comfort_TooHot:
res = F("Очень жарко");
break;
case Comfort_TooCold:
res = F("Очень холодно");
break;
case Comfort_TooDry:
res = F("Очень сухо");
break;
case Comfort_TooHumid:
res = F("Очень влажно");
break;
case Comfort_HotAndHumid:
res = F("Жарко и влажно");
break;
case Comfort_HotAndDry:
res = F("Жарко и сухо");
break;
case Comfort_ColdAndHumid:
res = F("Холодно и влажно");
break;
case Comfort_ColdAndDry:
res = F("Холодно и сухо");
break;
default:
res = F("Неизвестно");
break;
};
return res;
}
//dhtDewpoint Точка#росы: Датчики 5
void dhtD() {
String widget_name = sCmd.next();
String page_name = sCmd.next();
String page_number = sCmd.next();
createWidgetByType(widget_name, page_name, page_number, "anydata", "dhtDewpoint");
sensors_reading_map[8] = 1;
}
void dhtD_reading() {
float value;
if (dht.getStatus() != 0) {
MqttClient::publishStatus("dhtDewpoint", String(dht.getStatusString()));
} else {
value = dht.computeDewPoint(jsonReadStr(configLiveJson, dhtT_value_name).toFloat(), jsonReadStr(configLiveJson, dhtH_value_name).toFloat(), false);
jsonWriteInt(configLiveJson, "dhtDewpoint", value);
eventGen("dhtDewpoint", "");
MqttClient::publishStatus("dhtDewpoint", String(value));
Serial.println("[I] sensor 'dhtDewpoint' data: " + String(value));
}
}
#endif
//=========================================i2c bus esp8266 scl-4 sda-5 ====================================================================
//=========================================================================================================================================
//=========================================Модуль сенсоров bmp280==========================================================================
//bmp280T temp1 0x76 Температура#bmp280 Датчики any-data 1
void bmp280T() {
String value_name = sCmd.next();
String address = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String page_number = sCmd.next();
bmp280T_value_name = value_name;
createWidgetByType(widget_name, page_name, page_number, type, value_name);
bmp.begin(hexStringToUint8(address));
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
//bmp_temp->printSensorDetails();
sensors_reading_map[9] = 1;
}
void bmp280T_reading() {
float value = 0;
sensors_event_t temp_event;
bmp_temp->getEvent(&temp_event);
value = temp_event.temperature;
jsonWriteStr(configLiveJson, bmp280T_value_name, String(value));
eventGen(bmp280T_value_name, "");
MqttClient::publishStatus(bmp280T_value_name, String(value));
Serial.println("[I] sensor '" + bmp280T_value_name + "' data: " + String(value));
}
//bmp280P press1 0x76 Давление#bmp280 Датчики any-data 2
void bmp280P() {
String value_name = sCmd.next();
String address = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String page_number = sCmd.next();
bmp280P_value_name = value_name;
createWidgetByType(widget_name, page_name, page_number, type, value_name);
bmp.begin(hexStringToUint8(address));
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
//bmp_temp->printSensorDetails();
sensors_reading_map[10] = 1;
}
void bmp280P_reading() {
float value = 0;
sensors_event_t pressure_event;
bmp_pressure->getEvent(&pressure_event);
value = pressure_event.pressure;
value = value / 1.333224;
jsonWriteStr(configLiveJson, bmp280P_value_name, String(value));
eventGen(bmp280P_value_name, "");
MqttClient::publishStatus(bmp280P_value_name, String(value));
Serial.println("[I] sensor '" + bmp280P_value_name + "' data: " + String(value));
}
//=========================================================================================================================================
//=============================================Модуль сенсоров bme280======================================================================
//bme280T temp1 0x76 Температура#bmp280 Датчики any-data 1
void bme280T() {
String value_name = sCmd.next();
String address = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String page_number = sCmd.next();
bme280T_value_name = value_name;
createWidgetByType(widget_name, page_name, page_number, type, value_name);
bme.begin(hexStringToUint8(address));
sensors_reading_map[11] = 1;
}
void bme280T_reading() {
float value = 0;
value = bme.readTemperature();
jsonWriteStr(configLiveJson, bme280T_value_name, String(value));
eventGen(bme280T_value_name, "");
MqttClient::publishStatus(bme280T_value_name, String(value));
Serial.println("[I] sensor '" + bme280T_value_name + "' data: " + String(value));
}
//bme280P pres1 0x76 Давление#bmp280 Датчики any-data 1
void bme280P() {
String value_name = sCmd.next();
String address = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String page_number = sCmd.next();
bme280P_value_name = value_name;
createWidgetByType(widget_name, page_name, page_number, type, value_name);
bme.begin(hexStringToUint8(address));
sensors_reading_map[12] = 1;
}
void bme280P_reading() {
float value = 0;
value = bme.readPressure();
value = value / 1.333224 / 100;
jsonWriteStr(configLiveJson, bme280P_value_name, String(value));
eventGen(bme280P_value_name, "");
MqttClient::publishStatus(bme280P_value_name, String(value));
Serial.println("[I] sensor '" + bme280P_value_name + "' data: " + String(value));
}
//bme280H hum1 0x76 Влажность#bmp280 Датчики any-data 1
void bme280H() {
String value_name = sCmd.next();
String address = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String page_number = sCmd.next();
bme280H_value_name = value_name;
createWidgetByType(widget_name, page_name, page_number, type, value_name);
bme.begin(hexStringToUint8(address));
sensors_reading_map[13] = 1;
}
void bme280H_reading() {
float value = 0;
value = bme.readHumidity();
jsonWriteStr(configLiveJson, bme280H_value_name, String(value));
eventGen(bme280H_value_name, "");
MqttClient::publishStatus(bme280H_value_name, String(value));
Serial.println("[I] sensor '" + bme280H_value_name + "' data: " + String(value));
}
//bme280A altit1 0x76 Высота#bmp280 Датчики any-data 1
void bme280A() {
String value_name = sCmd.next();
String address = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String page_number = sCmd.next();
bme280A_value_name = value_name;
createWidgetByType(widget_name, page_name, page_number, type, value_name);
bme.begin(hexStringToUint8(address));
sensors_reading_map[14] = 1;
}
void bme280A_reading() {
float value = bme.readAltitude(1013.25);
jsonWriteStr(configLiveJson, bme280A_value_name, String(value, 2));
eventGen(bme280A_value_name, "");
MqttClient::publishStatus(bme280A_value_name, String(value));
Serial.println("[I] sensor '" + bme280A_value_name + "' data: " + String(value));
}

View File

@@ -1,41 +0,0 @@
#ifdef SERVO_ENABLED
#include "Servo/Servos.h"
Servos myServo;
Servos::Servos(){};
Servo *Servos::create(uint8_t num, uint8_t pin) {
// Ищем среди ранее созданных
for (size_t i = 0; i < _items.size(); i++) {
auto item = _items.at(i);
if (item.num == num) {
if (item.pin != pin) {
item.obj->attach(pin);
item.pin = pin;
};
return item.obj;
}
}
// Добавляем новый
Servo_t newItem{num, pin};
newItem.obj = new Servo();
newItem.obj->attach(pin);
_items.push_back(newItem);
return newItem.obj;
}
Servo *Servos::get(uint8_t num) {
// Ищем среди ранее созданных
for (size_t i = 0; i < _items.size(); i++) {
auto item = _items.at(i);
if (item.num == num) {
return item.obj;
}
}
return nullptr;
}
size_t Servos::count() {
return _items.size();
}
#endif

View File

@@ -1,91 +0,0 @@
#include "Global.h"
//================================================================================================================
//=========================================Таймеры=================================================================
void Timer_countdown_init() {
ts.add(
TIMER_COUNTDOWN, 1000, [&](void*) {
String old_line = jsonReadStr(configOptionJson, "timers");
if (old_line != "") {
//Serial.println(old_line);
int i = 0;
do {
String timer = selectFromMarkerToMarker(old_line, ",", i);
Serial.print("timer no " + String(i) + ": ");
Serial.println(timer);
if (timer == "not found" || timer == "") return;
int number = selectToMarker(timer, ":").toInt();
int time = readTimer(number);
if (time == 0) {
delTimer(String(number));
jsonWriteStr(configLiveJson, "timer" + String(number), "0");
eventGen("timer", String(number));
} else {
time--;
addTimer(String(number), String(time));
}
i++;
} while (i <= 9);
}
},
nullptr, true);
}
void timerStart_() {
String number = sCmd.next();
String period_of_time = sCmd.next();
String type = sCmd.next();
if (period_of_time.indexOf("digit") != -1) {
//period_of_time = add_set(period_of_time);
period_of_time = jsonReadStr(configLiveJson, period_of_time);
}
if (type == "sec") period_of_time = period_of_time;
if (type == "min") period_of_time = String(period_of_time.toInt() * 60);
if (type == "hours") period_of_time = String(period_of_time.toInt() * 60 * 60);
addTimer(number, period_of_time);
jsonWriteStr(configLiveJson, "timer" + number, "1");
}
void addTimer(String number, String time) {
String tmp = jsonReadStr(configOptionJson, "timers"); //1:60,2:120,
String new_timer = number + ":" + time;
int psn1 = tmp.indexOf(number + ":"); //0 ищем позицию таймера который надо заменить
if (psn1 != -1) { //если он есть
int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой
String timer = tmp.substring(psn1, psn2); //1:60 выделяем таймер который надо заменить
///tmp.replace(timer, new_timer); //заменяем таймер на новый (во всей стороке)
tmp.replace(timer + ",", "");
tmp += new_timer + ",";
} else { //если его нет
tmp += new_timer + ",";
}
jsonWriteStr(configOptionJson, "timers", tmp);
//Serial.println("ura");
}
void timerStop_() {
String number = sCmd.next();
delTimer(number);
}
void delTimer(String number) {
String tmp = jsonReadStr(configOptionJson, "timers"); //1:60,2:120,
int psn1 = tmp.indexOf(number + ":"); //0 ищем позицию таймера который надо удалить
if (psn1 != -1) { //если он есть
int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой
String timer = tmp.substring(psn1, psn2) + ","; //1:60, выделяем таймер который надо удалить
tmp.replace(timer, ""); //удаляем таймер
jsonWriteStr(configOptionJson, "timers", tmp);
}
}
int readTimer(int number) {
String tmp = jsonReadStr(configOptionJson, "timers"); //1:60,2:120,
int psn1 = tmp.indexOf(String(number) + ":"); //0 ищем позицию таймера который надо прочитать
String timer;
if (psn1 != -1) { //если он есть
int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой
timer = tmp.substring(psn1, psn2); //1:60 выделяем таймер который надо прочитать
timer = deleteBeforeDelimiter(timer, ":");
}
return timer.toInt();
}

View File

@@ -1,89 +0,0 @@
#include "Upgrade.h"
#include "Class/NotAsinc.h"
#include "ESP8266.h"
#include "Global.h"
static const char* MODULE = "Update";
static const char* check_update_url PROGMEM = "http://91.204.228.124:1100/update/%s/version.txt";
void upgradeInit() {
myNotAsincActions->add(
do_UPGRADE, [&](void*) {
upgrade_firmware();
},
nullptr);
myNotAsincActions->add(
do_GETLASTVERSION, [&](void*) {
getLastVersion();
},
nullptr);
if (isNetworkActive()) {
getLastVersion();
if (lastVersion.length()) {
pm.info("available: " + lastVersion);
}
};
}
const String getAvailableUrl(const char* mcu) {
char buf[128];
sprintf_P(buf, check_update_url, mcu);
return buf;
}
void getLastVersion() {
String url;
#ifdef ESP8266
url = getAvailableUrl("esp8266");
#else
url = getAvailableUrl("esp32");
#endif
lastVersion = getURL(url);
jsonWriteStr(configSetupJson, "last_version", lastVersion);
}
void upgrade_firmware() {
String scanerioBackup, configBackup, setupBackup;
scanerioBackup = readFile(String(DEVICE_SCENARIO_FILE), 4096);
configBackup = readFile(String(DEVICE_CONFIG_FILE), 4096);
setupBackup = configSetupJson;
pm.info("update data");
WiFiClient wifiClient;
#ifdef ESP8266
ESPhttpUpdate.rebootOnUpdate(false);
t_httpUpdate_return ret = ESPhttpUpdate.updateSpiffs(wifiClient, "http://91.204.228.124:1100/update/esp8266/esp32-esp8266_iot-manager_modules_firmware.spiffs.bin");
#else
httpUpdate.rebootOnUpdate(false);
t_httpUpdate_return ret = httpUpdate.updateSpiffs(wifiClient, "http://91.204.228.124:1100/update/esp32/esp32-esp8266_iot-manager_modules_firmware.spiffs.bin");
#endif
if (ret == HTTP_UPDATE_OK) {
writeFile(String(DEVICE_SCENARIO_FILE), scanerioBackup);
writeFile(String(DEVICE_CONFIG_FILE), configBackup);
writeFile("config.json", setupBackup);
saveConfig();
pm.info("done!");
} else {
pm.error("on data");
return;
}
Serial.println("update firmware");
#ifdef ESP8266
ret = ESPhttpUpdate.update(wifiClient, "http://91.204.228.124:1100/update/esp8266/esp32-esp8266_iot-manager_modules_firmware.ino.bin");
#else
ret = httpUpdate.update(wifiClient, "http://91.204.228.124:1100/update/esp32/esp32-esp8266_iot-manager_modules_firmware.ino.bin");
#endif
if (ret == HTTP_UPDATE_OK) {
pm.info("done! restart...");
ESP.restart();
} else {
pm.error("on firmware");
}
}

View File

@@ -1,161 +0,0 @@
#include "Utils/FileUtils.h"
#include "Utils/PrintMessage.h"
static const char* MODULE = "FS";
const String filepath(const String& filename) {
return filename.startsWith("/") ? filename : "/" + filename;
}
bool fileSystemInit() {
if (!LittleFS.begin()) {
pm.error("init");
return false;
}
return true;
}
void removeFile(const String& filename) {
String path = filepath(filename);
if (LittleFS.exists(path)) {
if (!LittleFS.remove(path)) {
pm.error("remove " + path);
}
} else {
pm.info("not exist" + path);
}
}
File seekFile(const String& filename, size_t position) {
String path = filepath(filename);
auto file = LittleFS.open(path, "r");
if (!file) {
pm.error("open " + path);
}
// поставим курсор в начало файла
file.seek(position, SeekSet);
return file;
}
const String readFileString(const String& filename, const String& to_find) {
String path = filepath(filename);
String res = "failed";
auto file = LittleFS.open(path, "r");
if (!file) {
return "failed";
}
if (file.find(to_find.c_str())) {
res = file.readStringUntil('\n');
}
file.close();
return res;
}
const String addFileLn(const String& filename, const String& str) {
String path = filepath(filename);
auto file = LittleFS.open(path, "a");
if (!file) {
return "failed";
}
file.println(str);
file.close();
return "sucсess";
}
const String addFile(const String& filename, const String& str) {
String path = filepath(filename);
auto file = LittleFS.open(path, "a");
if (!file) {
return "failed";
}
file.print(str);
file.close();
return "sucсess";
}
bool copyFile(const String& src, const String& dst, bool overwrite) {
String srcPath = filepath(src);
String dstPath = filepath(dst);
pm.info("copy " + srcPath + " to " + dstPath);
if (!LittleFS.exists(srcPath)) {
pm.error("not exist: " + srcPath);
return false;
}
if (LittleFS.exists(dstPath)) {
if (!overwrite) {
pm.error("already exist: " + dstPath);
return false;
}
LittleFS.remove(dstPath);
}
auto srcFile = LittleFS.open(srcPath, "r");
auto dstFile = LittleFS.open(dstPath, "w");
uint8_t buf[512];
while (srcFile.available()) {
size_t len = srcFile.read(buf, 512);
dstFile.write(buf, len);
}
srcFile.close();
dstFile.close();
return true;
}
const String writeFile(const String& filename, const String& str) {
String path = filepath(filename);
auto file = LittleFS.open(path, "w");
if (!file) {
return "failed";
}
file.print(str);
file.close();
return "sucсess";
}
const String readFile(const String& filename, size_t max_size) {
String path = filepath(filename);
auto file = LittleFS.open(path, "r");
if (!file) {
return "failed";
}
size_t size = file.size();
if (size > max_size) {
file.close();
return "large";
}
String temp = file.readString();
file.close();
return temp;
}
const String getFileSize(const String filename) {
String filepath(filename);
auto file = LittleFS.open(filepath, "r");
if (!file) {
return "failed";
}
size_t size = file.size();
file.close();
return String(size);
}
const String getFSSizeInfo() {
String res;
#ifdef ESP8266
FSInfo info;
if (LittleFS.info(info)) {
res = prettyBytes(info.usedBytes) + " of " + prettyBytes(info.totalBytes);
} else {
res = "error";
}
#else
res = prettyBytes(LittleFS.usedBytes()) + " of " + prettyBytes(LittleFS.totalBytes());
#endif
return res;
}
const String getConfigFile(uint8_t preset, ConfigType_t type) {
char buf[64];
sprintf(buf, "/conf/%s%03d.txt", (type == CT_CONFIG) ? "c" : "s", preset);
return String(buf);
}

View File

@@ -1,58 +0,0 @@
#include "Utils\JsonUtils.h"
#include "Utils/FileUtils.h"
#include "Global.h"
#include <ArduinoJson.h>
String jsonReadStr(String& json, String name) {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
return root[name].as<String>();
}
boolean jsonReadBool(String& json, String name) {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
return root[name].as<boolean>();
}
int jsonReadInt(String& json, String name) {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
return root[name];
}
String jsonWriteStr(String& json, String name, String value) {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
root[name] = value;
json = "";
root.printTo(json);
return json;
}
String jsonWriteBool(String& json, String name, boolean value) {
return jsonWriteStr(json, name, value ? "1" : "0");
}
String jsonWriteInt(String& json, String name, int value) {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
root[name] = value;
json = "";
root.printTo(json);
return json;
}
String jsonWriteFloat(String& json, String name, float value) {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
root[name] = value;
json = "";
root.printTo(json);
return json;
}
void saveConfig() {
writeFile(String("config.json"), configSetupJson);
}

View File

@@ -1,136 +0,0 @@
#include "Utils\StringUtils.h"
#include "Consts.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";
}
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 itemsCount(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;
}
boolean isDigitStr(const String &str) {
for (size_t i = 0; i < str.length(); i++) {
if (!isDigit(str.charAt(i))) {
return false;
}
}
return str.length();
}
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";
}
static const char *str_info = "I";
static const char *str_warn = "W";
static const char *str_error = "E";
static const char *str_unknown = "?";
String getErrorLevelStr(ErrorLevel_t level) {
const char *ptr;
switch (level) {
case EL_INFO:
ptr = str_info;
break;
case EL_WARNING:
ptr = str_warn;
break;
case EL_ERROR:
ptr = str_error;
break;
default:
ptr = str_unknown;
break;
}
return String(ptr);
}

View File

@@ -1,236 +0,0 @@
#include "Utils/SysUtils.h"
#include "Utils/PrintMessage.h"
#include "Global.h"
static const char* MODULE = "Main";
const String getUniqueId(const char* name) {
return String(name) + getMacAddress();
}
const String getChipId() {
String res;
#ifdef ESP32
char buf[32] = {0};
uint32_t mac = ESP.getEfuseMac();
sprintf(buf, "%0X", mac);
res = String(buf);
#endif
#ifdef ESP8266
res = String(ESP.getChipId()) + "-" + String(ESP.getFlashChipId());
#endif
return res;
}
void setChipId() {
chipId = getChipId();
pm.info("id: " + chipId);
}
#ifdef ESP8266
static uint32_t total_memory = 52864;
#else
static uint32_t total_memory = ESP.getHeapSize();
#endif
const String printMemoryStatus() {
uint32_t free = ESP.getFreeHeap();
uint32_t used = total_memory - free;
uint32_t memory_load = (used * 100) / total_memory;
char buf[64];
sprintf(buf, "used: %d%% free: %s", memory_load, getHeapStats().c_str());
return String(buf);
}
#ifdef ESP8266
const String getHeapStats() {
uint32_t free;
uint16_t max;
uint8_t frag;
ESP.getHeapStats(&free, &max, &frag);
String buf;
buf += prettyBytes(free);
buf += " frag: ";
buf += frag;
buf += '%';
return buf;
}
#else
const String getHeapStats() {
String buf;
buf = prettyBytes(ESP.getFreeHeap());
return buf;
}
#endif
const String getMacAddress() {
uint8_t mac[6];
char buf[13] = {0};
#if defined(ESP8266)
WiFi.macAddress(mac);
sprintf(buf, MACSTR, MAC2STR(mac));
#else
esp_read_mac(mac, ESP_MAC_WIFI_STA);
sprintf(buf, MACSTR, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
#endif
return String(buf);
}
#ifdef ESP8266
void setLedStatus(LedStatus_t status) {
pinMode(LED_PIN, OUTPUT);
switch (status) {
case LED_OFF:
noTone(LED_PIN);
digitalWrite(LED_PIN, HIGH);
break;
case LED_ON:
noTone(LED_PIN);
digitalWrite(LED_PIN, LOW);
break;
case LED_SLOW:
tone(LED_PIN, 1);
break;
case LED_FAST:
tone(LED_PIN, 20);
break;
default:
break;
}
}
#else
void setLedStatus(LedStatus_t status) {
pinMode(LED_PIN, OUTPUT);
switch (status) {
case LED_OFF:
digitalWrite(LED_PIN, HIGH);
break;
case LED_ON:
digitalWrite(LED_PIN, LOW);
break;
case LED_SLOW:
break;
case LED_FAST:
break;
default:
break;
}
}
#endif
//===================================================================
/*
void web_print (String text) {
if (WiFi.status() == WL_CONNECTED) {
jsonWriteStr(json, "test1", jsonReadStr(json, "test2"));
jsonWriteStr(json, "test2", jsonReadStr(json, "test3"));
jsonWriteStr(json, "test3", jsonReadStr(json, "test4"));
jsonWriteStr(json, "test4", jsonReadStr(json, "test5"));
jsonWriteStr(json, "test5", jsonReadStr(json, "test6"));
jsonWriteStr(json, "test6", GetTime() + " " + text);
ws.textAll(json);
}
}
*/
//===================================================================
/*
"socket": [
"ws://{{ip}}/ws"
],
*/
//===================================================================
/*
{
"type": "h4",
"title": "('{{build2}}'=='{{firmware_version}}'?'NEW':'OLD')"
},
*/
//===================================================================
/*
{
"type": "button",
"title": "Конфигурация устройства",
"socket": "test2",
"class": "btn btn-block btn-primary"
},
{
"type": "hr"
},
{
"type": "h6",
"title": "{{test1}}"
},
{
"type": "h6",
"title": "{{test2}}"
},
{
"type": "h6",
"title": "{{test3}}"
},
{
"type": "h6",
"title": "{{test4}}"
},
{
"type": "h6",
"title": "{{test5}}"
},
{
"type": "h6",
"title": "{{test6}}"
},
{
"type": "hr"
},
*/
//===================================================================
/*
String getResetReason(uint8_t core) {
int reason = rtc_get_reset_reason(core);
switch (reason) {
case 1 : return "Power on"; break; //Vbat power on reset
case 3 : return "Software reset digital core"; break; //Software reset digital core
case 4 : return "Legacy watch dog reset digital core"; break; //Legacy watch dog reset digital core
case 5 : return "Deep Sleep reset digital core"; break; //Deep Sleep reset digital core
case 6 : return "Reset by SLC module, reset digital core"; break; //Reset by SLC module, reset digital core
case 7 : return "Timer Group0 Watch dog reset digital core"; break; //Timer Group0 Watch dog reset digital core
case 8 : return "Timer Group1 Watch dog reset digital core"; break; //Timer Group1 Watch dog reset digital core
case 9 : return "RTC Watch dog Reset digital core"; break; //
case 10 : return "Instrusion tested to reset CPU"; break;
case 11 : return "Time Group reset CPU"; break;
case 12 : return "Software reset CPU"; break;
case 13 : return "RTC Watch dog Reset CPU"; break;
case 14 : return "for APP CPU, reseted by PRO CPU"; break;
case 15 : return "Reset when the vdd voltage is not stable"; break;
case 16 : return "RTC Watch dog reset digital core and rtc module"; break;
default : return "NO_MEAN";
}
}
String EspClass::getResetReason(void) {
char buff[32];
if (resetInfo.reason == REASON_DEFAULT_RST) { // normal startup by power on
strcpy_P(buff, PSTR("Power on"));
} else if (resetInfo.reason == REASON_WDT_RST) { // hardware watch dog reset
strcpy_P(buff, PSTR("Hardware Watchdog"));
} else if (resetInfo.reason == REASON_EXCEPTION_RST) { // exception reset, GPIO status wont change
strcpy_P(buff, PSTR("Exception"));
} else if (resetInfo.reason == REASON_SOFT_WDT_RST) { // software watch dog reset, GPIO status wont change
strcpy_P(buff, PSTR("Software Watchdog"));
} else if (resetInfo.reason == REASON_SOFT_RESTART) { // software restart ,system_restart , GPIO status wont change
strcpy_P(buff, PSTR("Software/System restart"));
} else if (resetInfo.reason == REASON_DEEP_SLEEP_AWAKE) { // wake up from deep-sleep
strcpy_P(buff, PSTR("Deep-Sleep Wake"));
} else if (resetInfo.reason == REASON_EXT_SYS_RST) { // external system reset
strcpy_P(buff, PSTR("External System"));
} else {
strcpy_P(buff, PSTR("Unknown"));
}
return String(buff);
}
*/

View File

@@ -1,212 +0,0 @@
#include "Utils\TimeUtils.h"
#include "Utils\StringUtils.h"
static const uint8_t days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static const char* week_days[7] = {"Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat"};
// String getTimeUnix() {
// time_t t;
// struct tm* tm;
// t = time(NULL);
// tm = localtime(&t);
// Serial.printf("%04d/%02d/%02d(%s) %02d:%02d:%02d\n",
// tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, week_days[tm->tm_wday],
// tm->tm_hour, tm->tm_min, tm->tm_sec);
// delay(1000);
// time_t now = time(nullptr);
// if (now < 30000) {
// return "failed";
// }
// return String(now);
// }
// String getTime() {
// time_t now = time(nullptr);
// int zone = 3600 * jsonReadStr(configSetupJson, "timezone").toInt();
// now = now + zone;
// String Time = ""; // Строка для результатов времени
// Time += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017
// int i = Time.indexOf(":"); //Ишем позицию первого символа :
// Time = Time.substring(i - 2, i + 6); // Выделяем из строки 2 символа перед символом : и 6 символов после
// return Time; // Возврашаем полученное время
// }
// String getTimeWOsec() {
// time_t now = time(nullptr);
// int zone = 3600 * jsonReadStr(configSetupJson, "timezone").toInt();
// now = now + zone;
// String Time = ""; // Строка для результатов времени
// Time += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017
// int i = Time.indexOf(":"); //Ишем позицию первого символа :
// Time = Time.substring(i - 2, i + 3); // Выделяем из строки 2 символа перед символом : и 6 символов после
// return Time; // Возврашаем полученное время
// }
// String getDate() {
// time_t now = time(nullptr);
// int zone = 3600 * jsonReadStr(configSetupJson, "timezone").toInt();
// now = now + zone;
// String Data = ""; // Строка для результатов времени
// Data += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017
// Data.replace("\n", "");
// uint8_t i = Data.lastIndexOf(" "); //Ишем позицию последнего символа пробел
// String Time = Data.substring(i - 8, i + 1); // Выделяем время и пробел
// Data.replace(Time, ""); // Удаляем из строки 8 символов времени и пробел
// return Data; // Возврашаем полученную дату
// }
// String getDateDigitalFormated() {
// String date = getDate();
// date = deleteBeforeDelimiter(date, " ");
// date.replace("Jan", "01");
// date.replace("Feb", "02");
// date.replace("Mar", "03");
// date.replace("Apr", "04");
// date.replace("May", "05");
// date.replace("Jun", "06");
// date.replace("Jul", "07");
// date.replace("Aug", "08");
// date.replace("Sep", "09");
// date.replace("Oct", "10");
// date.replace("Nov", "11");
// date.replace("Dec", "12");
// String month = date.substring(0, 2);
// String day = date.substring(3, 5);
// String year = date.substring(8, 10);
// String out = day;
// out += ".";
// out += month;
// out += ".";
// out += year;
// return out;
// }
// int timeToMin(String Time) {
// //"00:00:00" время в секунды
// long min = selectToMarker(Time, ":").toInt() * 60; //общее количество секунд в полных часах
// Time = deleteBeforeDelimiter(Time, ":"); // Теперь здесь минуты секунды
// min += selectToMarker(Time, ":").toInt(); // Добавим секунды из полных минут
// return min;
// }
static const char* TIME_FORMAT PROGMEM = "%02d:%02d:%02d";
static const char* TIME_FORMAT_WITH_DAYS PROGMEM = "%dd %02d:%02d";
const String prettySeconds(unsigned long time_s) {
unsigned long tmp = time_s;
unsigned long seconds;
unsigned long minutes;
unsigned long hours;
unsigned long days;
seconds = tmp % 60;
tmp = tmp / 60;
minutes = tmp % 60;
tmp = tmp / 60;
hours = tmp % 24;
days = tmp / 24;
char buf[32];
if (days) {
sprintf_P(buf, TIME_FORMAT_WITH_DAYS, days, hours, minutes, seconds);
} else {
sprintf_P(buf, TIME_FORMAT, hours, minutes, seconds);
}
return String(buf);
}
const String prettyMillis(unsigned long time_ms) {
return prettySeconds(time_ms / 1000);
}
unsigned long millis_since(unsigned long sinse) {
return millis_passed(sinse, millis());
}
unsigned long millis_passed(unsigned long start, unsigned long finish) {
unsigned long result = 0;
if (start <= finish) {
unsigned long passed = finish - start;
if (passed <= __LONG_MAX__) {
result = static_cast<long>(passed);
} else {
result = static_cast<long>((__LONG_MAX__ - finish) + start + 1u);
}
} else {
unsigned long passed = start - finish;
if (passed <= __LONG_MAX__) {
result = static_cast<long>(passed);
result = -1 * result;
} else {
result = static_cast<long>((__LONG_MAX__ - start) + finish + 1u);
result = -1 * result;
}
}
return result;
}
int getOffsetInSeconds(int timezone) {
return getOffsetInMinutes(timezone) * ONE_MINUTE_s;
}
int getOffsetInMinutes(int timezone) {
return timezone * ONE_HOUR_m;
}
void breakEpochToTime(unsigned long epoch, Time_t& tm) {
// break the given time_input into time components
// this is a more compact version of the C library localtime function
unsigned long time = epoch;
tm.second = time % 60;
time /= 60; // now it is minutes
tm.minute = time % 60;
time /= 60; // now it is hours
tm.hour = time % 24;
time /= 24; // now it is days
tm.days = time;
tm.day_of_week = ((time + 4) % 7) + 1; // Sunday is day 1
uint8_t year = 0;
unsigned long days = 0;
while ((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
year++;
}
tm.year = year - 30;
days -= LEAP_YEAR(year) ? 366 : 365;
time -= days; // now it is days in this year, starting at 0
tm.day_of_year = time;
uint8_t month;
uint8_t month_length;
for (month = 0; month < 12; month++) {
if (1 == month) { // february
if (LEAP_YEAR(year)) {
month_length = 29;
} else {
month_length = 28;
}
} else {
month_length = days_in_month[month];
}
if (time >= month_length) {
time -= month_length;
} else {
break;
}
}
tm.month = month + 1; // jan is month 1
tm.day_of_month = time + 1; // day of month
tm.valid = (epoch > MIN_DATETIME);
}

View File

@@ -1,88 +0,0 @@
#include "Utils\WebUtils.h"
#include "ESPAsyncWebServer.h"
String getURL(const String& urls) {
String res = "";
HTTPClient http;
http.begin(urls);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
res = http.getString();
} else {
res = "error";
}
http.end();
return res;
}
const String getMethodName(AsyncWebServerRequest* request) {
String res = F("UNKNOWN");
if (request->method() == HTTP_GET)
res = F("GET");
else if (request->method() == HTTP_POST)
res = F("POST");
else if (request->method() == HTTP_DELETE)
res = F("DELETE");
else if (request->method() == HTTP_PUT)
res = F("PUT");
else if (request->method() == HTTP_PATCH)
res = F("PATCH");
else if (request->method() == HTTP_HEAD)
res = F("HEAD");
else if (request->method() == HTTP_OPTIONS)
res = F("OPTIONS");
return res;
}
const String getRequestInfo(AsyncWebServerRequest* request) {
String res = getMethodName(request);
res += ' ';
res += "http://";
res += request->host();
res += request->url();
res += '\n';
if (request->contentLength()) {
res += "content-type: ";
res += request->contentType();
res += " content-lenght: ";
res += prettyBytes(request->contentLength());
res += '\n';
}
if (request->headers()) {
res += "headers:\n";
for (size_t i = 0; i < request->headers(); i++) {
AsyncWebHeader* h = request->getHeader(i);
res += h->name();
res += '=';
res += h->value();
res += '\n';
}
}
if (request->params()) {
res += "params:\n";
for (size_t i = 0; i < request->params(); i++) {
AsyncWebParameter* p = request->getParam(i);
if (p->isFile()) {
res += "FILE";
} else if (p->isPost()) {
res += "POST";
} else {
res += "GET";
}
res += ' ';
res += p->name();
res += ':';
res += p->value();
if (p->isFile()) {
res += " size:";
res += p->size();
}
res += '\n';
}
}
return res;
}

View File

@@ -1,118 +0,0 @@
#include "Utils/WiFiUtils.h"
static const char* MODULE = "WiFi";
void startSTAMode() {
setLedStatus(LED_SLOW);
pm.info("STA Mode");
String ssid = jsonReadStr(configSetupJson, "routerssid");
String passwd = jsonReadStr(configSetupJson, "routerpass");
WiFi.mode(WIFI_STA);
if (ssid == "" && passwd == "") {
WiFi.begin();
} else {
if (WiFi.begin(ssid.c_str(), passwd.c_str()) == WL_CONNECT_FAILED) {
pm.error("failed on start");
}
}
bool keepConnecting = true;
uint8_t tries = 20;
int8_t connRes;
do {
#ifdef ESP8266
connRes = WiFi.waitForConnectResult(1000);
#else
byte connRes = WiFi.waitForConnectResult();
#endif
switch (connRes) {
case WL_NO_SSID_AVAIL: {
pm.error("no network");
keepConnecting = false;
} break;
case WL_CONNECTED: {
String hostIpStr = WiFi.localIP().toString();
pm.info("http://" + hostIpStr);
jsonWriteStr(configSetupJson, "ip", hostIpStr);
keepConnecting = false;
} break;
case WL_CONNECT_FAILED: {
pm.error("check credentials");
jsonWriteInt(configOptionJson, "pass_status", 1);
keepConnecting = false;
} break;
default:
break;
}
} while (keepConnecting && tries--);
if (isNetworkActive()) {
MqttClient::init();
setLedStatus(LED_OFF);
} else {
pm.error("failed: " + String(connRes, DEC));
startAPMode();
};
}
bool startAPMode() {
setLedStatus(LED_ON);
pm.info("AP Mode");
String ssid = jsonReadStr(configSetupJson, "apssid");
String passwd = jsonReadStr(configSetupJson, "appass");
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid.c_str(), passwd.c_str());
String hostIpStr = WiFi.softAPIP().toString();
pm.info("Host IP: " + hostIpStr);
jsonWriteStr(configSetupJson, "ip", hostIpStr);
ts.add(
WIFI_SCAN, 10 * 1000,
[&](void*) {
String sta_ssid = jsonReadStr(configSetupJson, "routerssid");
pm.info("scanning for " + sta_ssid);
if (scanWiFi(sta_ssid)) {
ts.remove(WIFI_SCAN);
startSTAMode();
}
},
nullptr, true);
return true;
}
boolean scanWiFi(String ssid) {
bool res = false;
int8_t n = WiFi.scanComplete();
pm.info("scan result: " + String(n, DEC));
if (n == -2) {
// не было запущено, запускаем
pm.info("start scanning");
// async, show_hidden
WiFi.scanNetworks(true, false);
} else if (n == -1) {
// все еще выполняется
pm.info("scanning in progress");
} else if (n == 0) {
// не найдена ни одна сеть
pm.info("no networks found");
WiFi.scanNetworks(true, false);
} else if (n > 0) {
for (int8_t i = 0; i < n; i++) {
if (WiFi.SSID(i) == ssid) {
res = true;
}
pm.info((res ? "*" : "") + String(i, DEC) + ") " + WiFi.SSID(i));
}
}
return res;
}
boolean isNetworkActive() {
return WiFi.status() == WL_CONNECTED;
}

View File

@@ -1,308 +0,0 @@
#include "Web.h"
#include "ItemsList.h"
#include "Global.h"
#include "Init.h"
#include "Class/NotAsinc.h"
static const char* MODULE = "Web";
bool parseRequestForPreset(AsyncWebServerRequest* request, uint8_t& preset) {
if (request->hasArg("preset")) {
preset = request->getParam("preset")->value().toInt();
return true;
}
return false;
}
void web_init() {
// dnsServer.start(53, "*", WiFi.softAPIP());
// server.addHandler(new CaptiveRequestHandler(jsonReadStr(configSetupJson, "name").c_str())).setFilter(ON_AP_FILTER);
server.on("/restart", HTTP_GET, [](AsyncWebServerRequest* request) {
if (request->hasArg("device")) {
if (request->getParam("device")->value() == "ok") {
ESP.restart();
}
request->send(200);
};
});
server.on("/set", HTTP_GET, [](AsyncWebServerRequest* request) {
//==============================presets===========================================================================================================
//uint8_t preset;
//if (parseRequestForPreset(request, preset)) {
// pm.info("activate #" + String(preset, DEC));
// String configFile = DEVICE_CONFIG_FILE;
// String scenarioFile = DEVICE_SCENARIO_FILE;
// copyFile(getConfigFile(preset, CT_CONFIG), configFile);
// copyFile(getConfigFile(preset, CT_SCENARIO), scenarioFile);
// Device_init();
// loadScenario();
// request->redirect("/?set.device");
//}
//==============================set.device.json====================================================================================================
if (request->hasArg("addItem")) {
String name = request->getParam("addItem")->value();
addItem(name);
Device_init();
request->redirect("/?set.device");
}
if (request->hasArg("delAllItems")) {
delAllItems();
Device_init();
request->redirect("/?set.device");
}
if (request->hasArg("saveItems")) {
Device_init();
request->redirect("/?set.device");
}
//==============================init====================================================================================================
if (request->hasArg("devinit")) {
Device_init();
request->send(200);
}
if (request->hasArg("scen")) {
bool value = request->getParam("scen")->value().toInt();
jsonWriteBool(configSetupJson, "scen", value);
saveConfig();
loadScenario();
request->send(200);
}
if (request->hasArg("sceninit")) {
loadScenario();
request->send(200);
}
#ifdef LOGGING_ENABLED
if (request->hasArg("cleanlog")) {
clean_log_date();
request->send(200);
}
#endif
//==============================udp settings=============================================
if (request->hasArg("udponoff")) {
bool value = request->getParam("udponoff")->value().toInt();
jsonWriteBool(configSetupJson, "udponoff", value);
saveConfig();
loadScenario();
request->send(200);
}
if (request->hasArg("updatelist")) {
removeFile("/dev.csv");
addFileLn("dev.csv", "device id;device name;ip address");
request->redirect("/?set.udp");
}
if (request->hasArg("updatepage")) {
request->redirect("/?set.udp");
}
if (request->hasArg("devname")) {
jsonWriteStr(configSetupJson, "name", request->getParam("devname")->value());
saveConfig();
request->send(200);
}
//==============================wifi settings=============================================
if (request->hasArg("routerssid")) {
jsonWriteStr(configSetupJson, "routerssid", request->getParam("routerssid")->value());
saveConfig();
request->send(200);
}
if (request->hasArg("routerpass")) {
jsonWriteStr(configSetupJson, "routerpass", request->getParam("routerpass")->value());
saveConfig();
request->send(200);
}
if (request->hasArg("apssid")) {
jsonWriteStr(configSetupJson, "apssid", request->getParam("apssid")->value());
saveConfig();
request->send(200, "text/text", "OK");
}
if (request->hasArg("appass")) {
jsonWriteStr(configSetupJson, "appass", request->getParam("appass")->value());
saveConfig();
request->send(200);
}
if (request->hasArg("weblogin")) {
jsonWriteStr(configSetupJson, "weblogin", request->getParam("weblogin")->value());
saveConfig();
request->send(200);
}
if (request->hasArg("webpass")) {
jsonWriteStr(configSetupJson, "webpass", request->getParam("webpass")->value());
saveConfig();
request->send(200);
}
if (request->hasArg("timezone")) {
String timezoneStr = request->getParam("timezone")->value();
jsonWriteStr(configSetupJson, "timezone", timezoneStr);
saveConfig();
timeNow->setTimezone(timezoneStr.toInt());
request->send(200);
}
if (request->hasArg("ntp")) {
String ntpStr = request->getParam("ntp")->value();
jsonWriteStr(configSetupJson, "ntp", ntpStr);
saveConfig();
timeNow->setNtpPool(ntpStr);
request->send(200);
}
if (request->hasArg("blink")) {
bool value = request->getParam("blink")->value().toInt();
jsonWriteBool(configSetupJson, "blink", value);
saveConfig();
request->send(200);
}
//==============================mqtt settings=============================================
if (request->hasArg("mqttServer")) {
jsonWriteStr(configSetupJson, "mqttServer", request->getParam("mqttServer")->value());
saveConfig();
myNotAsincActions->make(do_MQTTPARAMSCHANGED);
request->send(200);
}
if (request->hasArg("mqttPort")) {
int port = (request->getParam("mqttPort")->value()).toInt();
jsonWriteInt(configSetupJson, "mqttPort", port);
saveConfig();
myNotAsincActions->make(do_MQTTPARAMSCHANGED);
request->send(200);
}
if (request->hasArg("mqttPrefix")) {
jsonWriteStr(configSetupJson, "mqttPrefix", request->getParam("mqttPrefix")->value());
saveConfig();
myNotAsincActions->make(do_MQTTPARAMSCHANGED);
request->send(200);
}
if (request->hasArg("mqttUser")) {
jsonWriteStr(configSetupJson, "mqttUser", request->getParam("mqttUser")->value());
saveConfig();
myNotAsincActions->make(do_MQTTPARAMSCHANGED);
request->send(200);
}
if (request->hasArg("mqttPass")) {
jsonWriteStr(configSetupJson, "mqttPass", request->getParam("mqttPass")->value());
saveConfig();
myNotAsincActions->make(do_MQTTPARAMSCHANGED);
request->send(200);
}
if (request->hasArg("mqttsend")) {
myNotAsincActions->make(do_MQTTUDP);
request->send(200);
}
if (request->hasArg("mqttcheck")) {
String buf = "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>" + MqttClient::getStateStr();
String payload = "{}";
jsonWriteStr(payload, "title", buf);
jsonWriteStr(payload, "class", "pop-up");
request->send(200, "text/html", payload);
}
//==============================push settings=============================================
#ifdef PUSH_ENABLED
if (request->hasArg("pushingboxid")) {
jsonWriteStr(configSetupJson, "pushingboxid", request->getParam("pushingboxid")->value());
saveConfig();
request->send(200);
}
#endif
//==============================utilities settings=============================================
if (request->hasArg(TAG_I2C)) {
busScanFlag = true;
busToScan = BS_I2C;
request->redirect("/?set.utilities");
} else if (request->hasArg(TAG_ONE_WIRE)) {
busScanFlag = true;
busToScan = BS_ONE_WIRE;
if (request->hasParam(TAG_ONE_WIRE_PIN)) {
setConfigParam(TAG_ONE_WIRE_PIN, request->getParam(TAG_ONE_WIRE_PIN)->value());
}
request->redirect("/?set.utilities");
} else if (request->hasArg(TAG_ONE_WIRE_PIN)) {
setConfigParam(TAG_ONE_WIRE_PIN, request->getParam(TAG_ONE_WIRE_PIN)->value());
request->send(200);
}
});
//==============================list of items=====================================================
//server.on("/del", HTTP_GET, [](AsyncWebServerRequest* request) {
// if (request->hasArg("file")) {
// itemsFile = request->getParam("file")->value();
// }
// if (request->hasArg("line")) {
// itemsLine = request->getParam("line")->value();
// }
// delElementFlag = true;
// Device_init();
// request->redirect("/?setn.device");
//});
/*
* Check
*/
server.on("/check", HTTP_GET, [](AsyncWebServerRequest* request) {
myNotAsincActions->make(do_GETLASTVERSION);
pm.info("firmware version: " + lastVersion);
if (!FLASH_4MB) {
lastVersion = "less";
} else if (isNetworkActive()) {
lastVersion = "nowifi";
}
String msg = "";
if (lastVersion == FIRMWARE_VERSION) {
msg = F("Актуальная версия прошивки уже установлена.");
} else if (lastVersion != FIRMWARE_VERSION) {
msg = F("Новая версия прошивки<a href=\"#\" class=\"btn btn-block btn-danger\" onclick=\"send_request(this, '/upgrade');setTimeout(function(){ location.href='/'; }, 120000);html('my-block','<span class=loader></span>Идет обновление прошивки, после обновления страница перезагрузится автоматически...')\">Установить</a>");
} else if (lastVersion == "error") {
msg = F("Cервер не найден. Попробуйте повторить позже...");
} else if (lastVersion == "") {
msg = F("Нажмите на кнопку \"обновить прошивку\" повторно...");
} else if (lastVersion == "less") {
msg = F("Обновление \"по воздуху\" не поддерживается!");
} else if (lastVersion == "nowifi") {
msg = F("Устройство не подключено к роутеру!");
} else if (lastVersion == "notsupported") {
msg = F("Обновление возможно только через usb!");
}
String tmp = "{}";
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>" + msg);
jsonWriteStr(tmp, "class", "pop-up");
request->send(200, "text/html", tmp);
});
/*
* Upgrade
*/
server.on("/upgrade", HTTP_GET, [](AsyncWebServerRequest* request) {
myNotAsincActions->make(do_UPGRADE);;
request->send(200, "text/html");
});
}
void setConfigParam(const char* param, const String& value) {
pm.info("set " + String(param) + ": " + value);
jsonWriteStr(configSetupJson, param, value);
saveConfig();
}

View File

@@ -1,203 +0,0 @@
#include "HttpServer.h"
#include "Utils/FileUtils.h"
#include "Utils/WebUtils.h"
#include "FSEditor.h"
namespace HttpServer {
static const char *MODULE = "Http";
/* Forward declaration */
void initOta();
void initMDNS();
void initWS();
void init() {
String login = jsonReadStr(configSetupJson, "weblogin");
String pass = jsonReadStr(configSetupJson, "webpass");
#ifdef FSEditor
#ifdef ESP32
server.addHandler(new FSEditor(LittleFS, login, pass));
#else
server.addHandler(new FSEditor(login, pass));
#endif
#endif
server.serveStatic("/css/", LittleFS, "/css/").setCacheControl("max-age=600");
server.serveStatic("/js/", LittleFS, "/js/").setCacheControl("max-age=600");
server.serveStatic("/favicon.ico", LittleFS, "/favicon.ico").setCacheControl("max-age=600");
server.serveStatic("/icon.jpeg", LittleFS, "/icon.jpeg").setCacheControl("max-age=600");
server.serveStatic("/", LittleFS, "/").setDefaultFile("index.htm").setAuthentication(login.c_str(), pass.c_str());
server.onNotFound([](AsyncWebServerRequest *request) {
pm.error("not found:\n" + getRequestInfo(request));
request->send(404);
});
server.onFileUpload([](AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) {
// TODO
if (!index) {
pm.info("start upload " + filename);
}
if (final) {
pm.info("finish upload: " + prettyBytes(index + len));
}
});
// динамические данные
server.on("/config.live.json", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(200, "application/json", configLiveJson);
});
// данные не являющиеся событиями
server.on("/config.option.json", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(200, "application/json", configOptionJson);
});
// для хранения постоянных данных
server.on("/config.setup.json", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(200, "application/json", configSetupJson);
});
server.on("/cmd", HTTP_GET, [](AsyncWebServerRequest *request) {
String cmdStr = request->getParam("command")->value();
pm.info("do: " + cmdStr);
addCommandLoop(cmdStr);
request->send(200, "text/html", "OK");
});
server.begin();
initOta();
initMDNS();
initWS();
}
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
#ifdef WS_enable
if (type == WS_EVT_CONNECT) {
Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
client->printf(json.c_str(), client->id());
//client->ping();
} else if (type == WS_EVT_DISCONNECT) {
Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id());
} else if (type == WS_EVT_ERROR) {
Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t *)arg), (char *)data);
} else if (type == WS_EVT_PONG) {
Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len) ? (char *)data : "");
} else if (type == WS_EVT_DATA) {
AwsFrameInfo *info = (AwsFrameInfo *)arg;
String msg = "";
if (info->final && info->index == 0 && info->len == len) {
//the whole message is in a single frame and we got all of it's data
Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT) ? "text" : "binary", info->len);
if (info->opcode == WS_TEXT) {
for (size_t i = 0; i < info->len; i++) {
msg += (char)data[i];
}
} else {
char buff[3];
for (size_t i = 0; i < info->len; i++) {
sprintf(buff, "%02x ", (uint8_t)data[i]);
msg += buff;
}
}
Serial.printf("%s\n", msg.c_str());
if (info->opcode == WS_TEXT)
client->text("{}");
else
client->binary("{}");
} else {
//message is comprised of multiple frames or the frame is split into multiple packets
if (info->index == 0) {
if (info->num == 0)
Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT) ? "text" : "binary");
Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len);
}
Serial.printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT) ? "text" : "binary", info->index, info->index + len);
if (info->opcode == WS_TEXT) {
for (size_t i = 0; i < len; i++) {
msg += (char)data[i];
}
} else {
char buff[3];
for (size_t i = 0; i < len; i++) {
sprintf(buff, "%02x ", (uint8_t)data[i]);
msg += buff;
}
}
Serial.printf("%s\n", msg.c_str());
if ((info->index + len) == info->len) {
Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len);
if (info->final) {
Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT) ? "text" : "binary");
if (info->message_opcode == WS_TEXT)
client->text("I got your text message");
else
client->binary("I got your binary message");
}
}
}
}
#endif
;
}
void initMDNS() {
#ifdef MDNS_ENABLED
MDNS.addService("http", "tcp", 80);
// TODO Add Adduino OTA
#endif
;
}
void initOta() {
#ifdef OTA_UPDATES_ENABLED
ArduinoOTA.onStart([]() {
events.send("Update Start", "ota");
});
ArduinoOTA.onEnd([]() {
events.send("Update End", "ota");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
char p[32];
sprintf(p, "Progress: %u%%\n", (progress / (total / 100)));
events.send(p, "ota");
});
ArduinoOTA.onError([](ota_error_t error) {
if (error == OTA_AUTH_ERROR)
events.send("Auth Failed", "ota");
else if (error == OTA_BEGIN_ERROR)
events.send("Begin Failed", "ota");
else if (error == OTA_CONNECT_ERROR)
events.send("Connect Failed", "ota");
else if (error == OTA_RECEIVE_ERROR)
events.send("Recieve Failed", "ota");
else if (error == OTA_END_ERROR)
events.send("End Failed", "ota");
});
ArduinoOTA.setHostname(hostName);
ArduinoOTA.begin();
#endif
;
}
void initWS() {
#ifdef WS_enable
ws.onEvent(onWsEvent);
server.addHandler(&ws);
events.onConnect([](AsyncEventSourceClient *client) {
client->send("", NULL, millis(), 1000);
});
server.addHandler(&events);
#endif
;
}
} // namespace HttpServer

View File

@@ -1,93 +0,0 @@
#include "Global.h"
static const char* MODULE = "Widget";
const String getWidgetFile(const String& name);
bool loadWidget(const String& filename, String& buf) {
buf = readFile(getWidgetFile(filename), 2048);
bool res = !(buf == "Failed" || buf == "Large");
if (!res) {
pm.error("on load" + filename);
}
return res;
}
void createWidget(String descr, String page, String order, String filename, String topic) {
String buf = "{}";
if (!loadWidget(filename, buf)) {
return;
}
descr.replace("#", " ");
page.replace("#", " ");
jsonWriteStr(buf, "page", page);
jsonWriteStr(buf, "order", order);
jsonWriteStr(buf, "descr", descr);
jsonWriteStr(buf, "topic", prex + "/" + topic);
#ifdef LAYOUT_IN_RAM
all_widgets += widget + "\r\n";
#else
addFileLn("layout.txt", buf);
#endif
}
//TODO Вот эта процедура, и несколько оберток
void createWidgetParam(String widget, String page, String pageNumber, String filename, String topic,
String name1, String param1, String name2, String param2, String name3, String param3) {
String buf = "";
if (!loadWidget(filename, buf)) {
return;
}
widget.replace("#", " ");
page.replace("#", " ");
jsonWriteStr(buf, "page", page);
jsonWriteStr(buf, "order", pageNumber);
jsonWriteStr(buf, "descr", widget);
jsonWriteStr(buf, "topic", prex + "/" + topic);
if (name1) jsonWriteStr(buf, name1, param1);
if (name2) jsonWriteStr(buf, name2, param2);
if (name3) jsonWriteStr(buf, name3, param3);
#ifdef LAYOUT_IN_RAM
all_widgets += widget + "\r\n";
#else
addFileLn("layout.txt", buf);
#endif
}
void createChart(String widget, String page, String pageNumber, String filename, String topic,
String maxCount) {
String buf = "";
if (!loadWidget(filename, buf)) {
return;
}
widget.replace("#", " ");
page.replace("#", " ");
jsonWriteStr(buf, "page", page);
jsonWriteStr(buf, "order", pageNumber);
//jsonWriteStr(widget, "descr", widget_name);
jsonWriteStr(buf, "series", widget);
jsonWriteStr(buf, "maxCount", maxCount);
jsonWriteStr(buf, "topic", prex + "/" + topic);
#ifdef LAYOUT_IN_RAM
all_widgets += widget + "\r\n";
#else
addFileLn("layout.txt", buf);
#endif
}
void createWidgetByType(String widget, String page, String pageNumber, String type, String topic) {
createWidget(widget, page, pageNumber, getWidgetFile(type), topic);
}
const String getWidgetFile(const String& name) {
return "/widgets/" + name + ".json";
}

View File

@@ -1,18 +0,0 @@
#include "Bus/BusScannerFactory.h"
#include "Class/NotAsinc.h"
#include "Global.h"
void busInit() {
myNotAsincActions->add(
do_BUSSCAN, [&](void*) {
doBusScan();
},
nullptr);
}
void doBusScan() {
String res = "";
BusScanner* scanner = BusScannerFactory::get(configSetupJson, busToScan, res);
scanner->scan();
jsonWriteStr(configLiveJson, String(scanner->tag()), res);
}

View File

@@ -1,132 +0,0 @@
#include <SSDP.h>
<<<<<<< HEAD
#include "test.h"
=======
>>>>>>> parent of 01248f4... esp32
#include "Class/CallBackTest.h"
#include "Class/NotAsinc.h"
#include "Class/ScenarioClass.h"
#include "Class/Switch.h"
#include "Cmd.h"
#include "Global.h"
#include "Init.h"
#include "ItemsList.h"
#include "Utils/Timings.h"
#include "Utils\WebUtils.h"
void not_async_actions();
static const char* MODULE = "Main";
Timings metric;
boolean initialized = false;
void setup() {
WiFi.setAutoConnect(false);
WiFi.persistent(false);
Serial.begin(115200);
Serial.flush();
Serial.println();
Serial.println("--------------started----------------");
setChipId();
myNotAsincActions = new NotAsinc(do_LAST);
myScenario = new Scenario();
pm.info("FS");
fileSystemInit();
pm.info("Config");
loadConfig();
pm.info("Clock");
clock_init();
pm.info("Commands");
cmd_init();
pm.info("Sensors");
sensorsInit();
pm.info("Init");
all_init();
pm.info("Network");
startSTAMode();
pm.info("Uptime");
uptime_init();
pm.info("telemetry");
telemetry_init();
pm.info("Updater");
upgradeInit();
pm.info("HttpServer");
HttpServer::init();
pm.info("WebAdmin");
web_init();
#ifdef UDP_ENABLED
pm.info("Broadcast UDP");
udpInit();
#endif
#ifdef SSDP
pm.info("Ssdp Init");
SsdpInit();
#endif
ts.add(
TEST, 1000 * 60, [&](void*) {
pm.info(printMemoryStatus());
},
nullptr, true);
just_load = false;
initialized = true;
setupTest();
}
void loop() {
if (!initialized) {
return;
}
#ifdef OTA_UPDATES_ENABLED
ArduinoOTA.handle();
#endif
#ifdef WS_enable
ws.cleanupClients();
#endif
#ifdef UDP_ENABLED
loopUdp();
#endif
timeNow->loop();
MqttClient::loop();
mySwitch->loop();
myScenario->loop();
loopTest();
loopCmd();
loopSerial();
myNotAsincActions->loop();
ts.update();
}
void clock_init() {
timeNow = new Clock();
timeNow->setNtpPool(jsonReadStr(configSetupJson, "ntp"));
timeNow->setTimezone(jsonReadStr(configSetupJson, "timezone").toInt());
ts.add(
TIME_SYNC, 30000, [&](void*) {
timeNow->hasSync();
},
nullptr, true);
}

View File

@@ -1,34 +0,0 @@
#include "test.h"
#include "Global.h"
void setupTest() {
//пример выделения подстрок
String buf = "Geeks-for-Geeks";
int buf_len = buf.length() + 1;
char char_array[buf_len];
buf.toCharArray(char_array, buf_len);
char* token = strtok(char_array, "-");
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, "-");
}
//char str[] = "Geeks for Geeks";
//char* token;
//char* rest = str;
//while ((token = strtok_r(rest, " ", &rest))) {
// printf("%s\n", token);
//}
}
void loopTest() {
}
//char stringToCharArray(int& i, String in) {
// int in_len = in.length() + 1;
// i = in_len;
// char char_array[in_len];
// in.toCharArray(char_array, in_len);
// return char_array[in_len];
//}

View File

@@ -1,167 +0,0 @@
#include "Class/NotAsinc.h"
#include "udp.h"
#include "udp_.h"
#include "Global.h"
static const char* MODULE = "Udp";
#ifdef ESP8266
IPAddress udp_multicastIP(255, 255, 255, 255);
WiFiUDP udp;
#endif
#ifdef ESP32
IPAddress udp_multicastIP(239, 255, 255, 255);
AsyncUDP udp;
#endif
String remote_ip;
String received;
int udp_period;
boolean udp_busy = false;
unsigned int udp_port = 4210;
#ifdef UDP_ENABLED
void udpInit() {
myNotAsincActions->add(
do_UDPDATAPARSE, [&](void*) {
do_udp_data_parse();
},
nullptr);
myNotAsincActions->add(
do_MQTTUDP, [&](void*) {
send_mqtt_to_udp();
},
nullptr);
removeFile("dev.csv");
addFileLn("dev.csv", "device id;device name;ip address");
#ifdef ESP8266
udp.begin(udp_port);
#endif
handleUdp_esp32();
randomSeed(micros());
udp_period = random(50000, 60000);
ts.add(
UDP, udp_period, [&](void*) {
if (jsonReadBool(configSetupJson, "udponoff") && isNetworkActive() && !udp_busy) {
pm.info("send info");
String payload = "iotm;";
payload += chipId;
payload += ";";
payload += jsonReadStr(configSetupJson, "name");
#ifdef ESP8266
udp.beginPacketMulticast(udp_multicastIP, udp_port, WiFi.localIP());
udp.write(payload.c_str());
udp.endPacket();
#endif
#ifdef ESP32
udp.broadcast(line_to_send.c_str());
#endif
}
},
nullptr, false);
}
bool isUdpEnabled() {
return jsonReadBool(configSetupJson, "udponoff") && isNetworkActive();
}
void loopUdp() {
#ifdef ESP8266
if (!isUdpEnabled()) {
return;
}
int packetSize = udp.parsePacket();
if (!packetSize) {
return;
}
char udp_packet[255];
remote_ip = udp.remoteIP().toString();
pm.info(prettyBytes(packetSize) + " from " + remote_ip + ":" + udp.remotePort());
int len = udp.read(udp_packet, 255);
if (len) {
udp_packet[len] = '\x00';
}
received = String(udp_packet);
if (received.indexOf("iotm;") >= 0 || received.indexOf("mqttServer") >= 0) {
myNotAsincActions->make(do_UDPDATAPARSE);
}
#endif
;
}
void handleUdp_esp32() {
#ifdef ESP32
if (udp.listenMulticast(udp_multicastIP, udp_port)) {
udp.onPacket([](AsyncUDPPacket packet) {
received = (char*)packet.data();
remote_ip = packet.remoteIP().toString();
if (jsonReadStr(configSetupJson, "udponoff") == "1") {
if (received.indexOf("iotm;") >= 0) {
myNotAsincActions->make(do_UDPDATAPARSE);
}
if (received.indexOf("mqttServer") >= 0) {
myNotAsincActions->make(do_UDPDATAPARSE);
}
}
});
}
#endif
}
void do_udp_data_parse() {
if (received.indexOf("mqttServer") >= 0) {
pm.info("received setting");
jsonWriteStr(configSetupJson, "mqttServer", jsonReadStr(received, "mqttServer"));
jsonWriteInt(configSetupJson, "mqttPort", jsonReadInt(received, "mqttPort"));
jsonWriteStr(configSetupJson, "mqttPrefix", jsonReadStr(received, "mqttPrefix"));
jsonWriteStr(configSetupJson, "mqttUser", jsonReadStr(received, "mqttUser"));
jsonWriteStr(configSetupJson, "mqttPass", jsonReadStr(received, "mqttPass"));
saveConfig();
myNotAsincActions->make(do_MQTTPARAMSCHANGED);
}
if (received.indexOf("iotm;") >= 0) {
add_dev_in_list("dev.csv", selectFromMarkerToMarker(received, ";", 1), selectFromMarkerToMarker(received, ";", 2), received);
}
}
void add_dev_in_list(String filename, String id, String dev_name, String ip) {
auto file = seekFile("/" + filename);
if (!file.find(id.c_str())) {
addFileLn(filename, id + ";" + dev_name + "; <a href=\"http://" + ip + "\" target=\"_blank\"\">" + ip + "</a>");
}
}
void send_mqtt_to_udp() {
if (!isUdpEnabled()) {
return;
}
udp_busy = true;
String data = "{}";
jsonWriteStr(data, "mqttServer", jsonReadStr(configSetupJson, "mqttServer"));
jsonWriteInt(data, "mqttPort", jsonReadInt(configSetupJson, "mqttPort"));
jsonWriteStr(data, "mqttPrefix", jsonReadStr(configSetupJson, "mqttPrefix"));
jsonWriteStr(data, "mqttUser", jsonReadStr(configSetupJson, "mqttUser"));
jsonWriteStr(data, "mqttPass", jsonReadStr(configSetupJson, "mqttPass"));
#ifdef ESP8266
udp.beginPacketMulticast(udp_multicastIP, udp_port, WiFi.localIP());
udp.write(data.c_str());
udp.endPacket();
#endif
#ifdef ESP32
udp.broadcast(mqtt_data.c_str());
#endif
pm.info("sent info");
udp_busy = false;
}
#endif