mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-28 15:12:19 +03:00
dell all
This commit is contained in:
@@ -1,21 +0,0 @@
|
||||
#include "Bus/BusScanner.h"
|
||||
|
||||
#include <Wire.h>
|
||||
#include "Utils/PrintMessage.h"
|
||||
|
||||
static const char* MODULE = "I2C";
|
||||
|
||||
boolean I2CScanner::syncScan() {
|
||||
Wire.begin();
|
||||
pm.info("scanning i2c...");
|
||||
size_t cnt = 0;
|
||||
for (uint8_t i = 8; i < 120; i++) {
|
||||
Wire.beginTransmission(i);
|
||||
if (Wire.endTransmission() == 0) {
|
||||
pm.info("found device: " + i);
|
||||
addResult(i, i < 119);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
#include "Bus/BusScanner.h"
|
||||
|
||||
#include "Utils/PresetUtils.h"
|
||||
#include "Utils/PrintMessage.h"
|
||||
|
||||
#include <OneWire.h>
|
||||
|
||||
const char* MODULE = "1Wire";
|
||||
|
||||
bool OneWireScanner::syncScan() {
|
||||
// Connect your 1-wire device to pin 3
|
||||
OneWire ds(3);
|
||||
uint8_t addr[8];
|
||||
|
||||
pm.info("scanning 1-Wire...");
|
||||
while (ds.search(addr)) {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
pm.info("found device: " + i);
|
||||
addResult(addr[i], i < 7);
|
||||
}
|
||||
}
|
||||
if (OneWire::crc8(addr, 7) != addr[7]) {
|
||||
pm.error("CRC!");
|
||||
return false;
|
||||
}
|
||||
ds.reset_search();
|
||||
return true;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#include "CaptiveRequestHandler.h"
|
||||
|
||||
CaptiveRequestHandler::CaptiveRequestHandler(const char *host) {
|
||||
strlcpy(_local_name, host, sizeof(_local_name));
|
||||
strcat(_local_name, ".local");
|
||||
}
|
||||
|
||||
CaptiveRequestHandler::~CaptiveRequestHandler() {
|
||||
}
|
||||
|
||||
bool CaptiveRequestHandler::isLocalIp(String address) {
|
||||
IPAddress ip;
|
||||
return !ip.fromString(address) || (ip != _local_ip);
|
||||
}
|
||||
|
||||
bool CaptiveRequestHandler::isLocalName(String host_name) {
|
||||
return host_name.equalsIgnoreCase(_local_name);
|
||||
}
|
||||
|
||||
bool CaptiveRequestHandler::canHandle(AsyncWebServerRequest *request) {
|
||||
_local_ip = request->client()->localIP();
|
||||
|
||||
return !isLocalIp(request->getHeader("HOST")->value()) && !isLocalName(request->getHeader("HOST")->value());
|
||||
}
|
||||
|
||||
void CaptiveRequestHandler::CaptiveRequestHandler::handleRequest(AsyncWebServerRequest *request) {
|
||||
char buf[64];
|
||||
sprintf(buf, "http://%s%s", _local_name, request->url().c_str());
|
||||
auto response = request->beginResponse(302, "text/html");
|
||||
response->addHeader("Location", buf);
|
||||
response->addHeader("Connection", "close");
|
||||
request->send(response);
|
||||
};
|
||||
639
src/Cmd.cpp
639
src/Cmd.cpp
@@ -1,639 +0,0 @@
|
||||
#include "Global.h"
|
||||
|
||||
#include "Module/Terminal.h"
|
||||
|
||||
static const char *MODULE = "Cmd";
|
||||
|
||||
Terminal *term = nullptr;
|
||||
|
||||
boolean but[NUM_BUTTONS];
|
||||
Bounce *buttons = new Bounce[NUM_BUTTONS];
|
||||
|
||||
Servo myServo1;
|
||||
Servo myServo2;
|
||||
SoftwareSerial *mySerial = nullptr;
|
||||
|
||||
void getData();
|
||||
|
||||
void cmd_init() {
|
||||
sCmd.addCommand("button", button);
|
||||
sCmd.addCommand("buttonSet", buttonSet);
|
||||
sCmd.addCommand("buttonChange", buttonChange);
|
||||
|
||||
sCmd.addCommand("pinSet", pinSet);
|
||||
sCmd.addCommand("pinChange", pinChange);
|
||||
|
||||
sCmd.addCommand("pwm", pwm);
|
||||
sCmd.addCommand("pwmSet", pwmSet);
|
||||
|
||||
sCmd.addCommand("switch", switch_);
|
||||
|
||||
#ifdef ANALOG_ENABLED
|
||||
sCmd.addCommand("analog", analog);
|
||||
#endif
|
||||
#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("inputDigit", inputDigit);
|
||||
sCmd.addCommand("digitSet", digitSet);
|
||||
|
||||
sCmd.addCommand("inputTime", inputTime);
|
||||
sCmd.addCommand("timeSet", timeSet);
|
||||
|
||||
sCmd.addCommand("timerStart", timerStart_);
|
||||
sCmd.addCommand("timerStop", timerStop_);
|
||||
|
||||
sCmd.addCommand("text", text);
|
||||
sCmd.addCommand("textSet", textSet);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
//==========================================================================================================
|
||||
//==========================================Модуль кнопок===================================================
|
||||
void button() {
|
||||
pm.info("create 'button'");
|
||||
String number = sCmd.next();
|
||||
String param = sCmd.next();
|
||||
String widget = sCmd.next();
|
||||
String page = sCmd.next();
|
||||
String state = sCmd.next();
|
||||
String pageNumber = sCmd.next();
|
||||
|
||||
jsonWriteStr(configOptionJson, "button_param" + number, param);
|
||||
jsonWriteStr(configLiveJson, "button" + number, state);
|
||||
|
||||
if (isDigitStr(param)) {
|
||||
pinMode(param.toInt(), OUTPUT);
|
||||
digitalWrite(param.toInt(), state.toInt());
|
||||
}
|
||||
|
||||
if (param == "scen") {
|
||||
jsonWriteStr(configSetupJson, "scen", state);
|
||||
loadScenario();
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
if (param.indexOf("line") != -1) {
|
||||
String str = param;
|
||||
while (str.length()) {
|
||||
if (str == "") return;
|
||||
String tmp = selectToMarker(str, ","); //line1,
|
||||
String number = deleteBeforeDelimiter(tmp, "e"); //1,
|
||||
number.replace(",", "");
|
||||
Serial.println(number);
|
||||
int number_int = number.toInt();
|
||||
scenario_line_status[number_int] = state.toInt();
|
||||
str = deleteBeforeDelimiter(str, ",");
|
||||
}
|
||||
}
|
||||
createWidget(widget, page, pageNumber, "toggle", "button" + number);
|
||||
}
|
||||
|
||||
void buttonSet() {
|
||||
String button_number = sCmd.next();
|
||||
String button_state = sCmd.next();
|
||||
String button_param = jsonReadStr(configOptionJson, "button_param" + button_number);
|
||||
|
||||
if (button_param != "na" || button_param != "scen" || button_param.indexOf("line") != -1) {
|
||||
digitalWrite(button_param.toInt(), button_state.toInt());
|
||||
}
|
||||
|
||||
if (button_param == "scen") {
|
||||
jsonWriteStr(configSetupJson, "scen", button_state);
|
||||
loadScenario();
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
if (button_param.indexOf("line") != -1) {
|
||||
String str = button_param;
|
||||
while (str.length() != 0) {
|
||||
if (str == "") return;
|
||||
String tmp = selectToMarker(str, ","); //line1,
|
||||
String number = deleteBeforeDelimiter(tmp, "e"); //1,
|
||||
number.replace(",", "");
|
||||
Serial.println(number);
|
||||
int number_int = number.toInt();
|
||||
scenario_line_status[number_int] = button_state.toInt();
|
||||
str = deleteBeforeDelimiter(str, ",");
|
||||
}
|
||||
}
|
||||
|
||||
eventGen("button", button_number);
|
||||
|
||||
jsonWriteStr(configLiveJson, "button" + button_number, button_state);
|
||||
|
||||
MqttClient::publishStatus("button" + button_number, button_state);
|
||||
}
|
||||
|
||||
void buttonChange() {
|
||||
String button_number = sCmd.next();
|
||||
String current_state = jsonReadStr(configLiveJson, "button" + button_number);
|
||||
|
||||
if (current_state == "1") {
|
||||
current_state = "0";
|
||||
} else if (current_state == "0") {
|
||||
current_state = "1";
|
||||
}
|
||||
order_loop += "buttonSet " + button_number + " " + current_state + ",";
|
||||
jsonWriteStr(configLiveJson, "button" + button_number, current_state);
|
||||
|
||||
MqttClient::publishStatus("button" + button_number, current_state);
|
||||
}
|
||||
|
||||
void pinSet() {
|
||||
String pin_number = sCmd.next();
|
||||
String pin_state = sCmd.next();
|
||||
pinMode(pin_number.toInt(), OUTPUT);
|
||||
digitalWrite(pin_number.toInt(), pin_state.toInt());
|
||||
}
|
||||
|
||||
void pinChange() {
|
||||
String pin_number = sCmd.next();
|
||||
pinMode(pin_number.toInt(), OUTPUT);
|
||||
digitalWrite(pin_number.toInt(), !digitalRead(pin_number.toInt()));
|
||||
}
|
||||
//==================================================================================================================
|
||||
//==========================================Модуль управления ШИМ===================================================
|
||||
void pwm() {
|
||||
//static boolean flag = true;
|
||||
String pwm_number = sCmd.next();
|
||||
String pwm_pin = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
widget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
|
||||
uint8_t pwm_pin_int = pwm_pin.toInt();
|
||||
jsonWriteStr(configOptionJson, "pwm_pin" + pwm_number, pwm_pin);
|
||||
pinMode(pwm_pin_int, INPUT);
|
||||
analogWrite(pwm_pin_int, start_state.toInt());
|
||||
//analogWriteFreq(32000);
|
||||
jsonWriteStr(configLiveJson, "pwm" + pwm_number, start_state);
|
||||
|
||||
createWidget(widget_name, page_name, page_number, "range", "pwm" + pwm_number);
|
||||
}
|
||||
|
||||
void pwmSet() {
|
||||
String pwm_number = sCmd.next();
|
||||
String pwm_state = sCmd.next();
|
||||
int pwm_state_int = pwm_state.toInt();
|
||||
|
||||
int pin = jsonReadInt(configOptionJson, "pwm_pin" + pwm_number);
|
||||
analogWrite(pin, pwm_state_int);
|
||||
|
||||
eventGen("pwm", pwm_number);
|
||||
|
||||
jsonWriteStr(configLiveJson, "pwm" + pwm_number, pwm_state);
|
||||
|
||||
MqttClient::publishStatus("pwm" + pwm_number, pwm_state);
|
||||
}
|
||||
//==================================================================================================================
|
||||
//==========================================Модуль физической кнопки================================================
|
||||
void switch_() {
|
||||
String switch_number = sCmd.next();
|
||||
String switch_pin = sCmd.next();
|
||||
String switch_delay = sCmd.next();
|
||||
|
||||
buttons[switch_number.toInt()].attach(switch_pin.toInt());
|
||||
buttons[switch_number.toInt()].interval(switch_delay.toInt());
|
||||
but[switch_number.toInt()] = true;
|
||||
}
|
||||
|
||||
void loopSerial() {
|
||||
if (term) {
|
||||
term->loop();
|
||||
}
|
||||
}
|
||||
|
||||
void loopButton() {
|
||||
static uint8_t switch_number = 1;
|
||||
|
||||
if (but[switch_number]) {
|
||||
buttons[switch_number].update();
|
||||
if (buttons[switch_number].fell()) {
|
||||
eventGen("switch", String(switch_number));
|
||||
|
||||
jsonWriteStr(configLiveJson, "switch" + String(switch_number), "1");
|
||||
}
|
||||
if (buttons[switch_number].rose()) {
|
||||
eventGen("switch", String(switch_number));
|
||||
|
||||
jsonWriteStr(configLiveJson, "switch" + String(switch_number), "0");
|
||||
}
|
||||
}
|
||||
switch_number++;
|
||||
if (switch_number == NUM_BUTTONS) {
|
||||
switch_number = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//=====================================================================================================================================
|
||||
//=========================================Добавление окна ввода цифры=================================================================
|
||||
void inputDigit() {
|
||||
String value_name = sCmd.next();
|
||||
String number = value_name.substring(5);
|
||||
String widget_name = sCmd.next();
|
||||
widget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
page_name.replace("#", " ");
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
jsonWriteStr(configLiveJson, "digit" + number, start_state);
|
||||
createWidget(widget_name, page_name, page_number, "inputNum", "digit" + number);
|
||||
}
|
||||
|
||||
void digitSet() {
|
||||
String number = sCmd.next();
|
||||
String value = sCmd.next();
|
||||
jsonWriteStr(configLiveJson, "digit" + number, value);
|
||||
MqttClient::publishStatus("digit" + number, value);
|
||||
}
|
||||
|
||||
//=====================================================================================================================================
|
||||
//=========================================Добавление окна ввода времени===============================================================
|
||||
void inputTime() {
|
||||
String value_name = sCmd.next();
|
||||
String number = value_name.substring(4);
|
||||
String widget_name = sCmd.next();
|
||||
widget_name.replace("#", " ");
|
||||
String page_name = sCmd.next();
|
||||
page_name.replace("#", " ");
|
||||
String start_state = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
jsonWriteStr(configLiveJson, "time" + number, start_state);
|
||||
createWidget(widget_name, page_name, page_number, "inputTime", "time" + number);
|
||||
}
|
||||
|
||||
void timeSet() {
|
||||
String number = sCmd.next();
|
||||
String value = sCmd.next();
|
||||
jsonWriteStr(configLiveJson, "time" + number, value);
|
||||
MqttClient::publishStatus("time" + number, value);
|
||||
}
|
||||
|
||||
void handle_time_init() {
|
||||
ts.add(
|
||||
TIME, 1000, [&](void *) {
|
||||
jsonWriteStr(configLiveJson, "time", timeNow->getTime());
|
||||
jsonWriteStr(configLiveJson, "timenow", timeNow->getTimeJson());
|
||||
eventGen("timenow", "");
|
||||
},
|
||||
nullptr, true);
|
||||
}
|
||||
|
||||
//=====================================================================================================================================
|
||||
//=========================================Добавление текстового виджета============================================================
|
||||
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("#", " ");
|
||||
String time = timeNow->getTime();
|
||||
time.replace(":", ".");
|
||||
text = text + " " + timeNow->getDateDigitalFormated() + " " + time;
|
||||
}
|
||||
|
||||
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 servo_number = sCmd.next();
|
||||
String servo_pin = sCmd.next();
|
||||
String start_state = sCmd.next();
|
||||
int start_state_int = start_state.toInt();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
|
||||
String min_value = sCmd.next();
|
||||
String max_value = sCmd.next();
|
||||
|
||||
String min_deg = sCmd.next();
|
||||
String max_deg = sCmd.next();
|
||||
|
||||
String page_number = sCmd.next();
|
||||
|
||||
jsonWriteStr(configOptionJson, "servo_pin" + servo_number, servo_pin);
|
||||
start_state_int = map(start_state_int, min_value.toInt(), max_value.toInt(), min_deg.toInt(), max_deg.toInt());
|
||||
|
||||
if (servo_number == "1") {
|
||||
#ifdef ESP8266
|
||||
myServo1.attach(servo_pin.toInt());
|
||||
myServo1.write(start_state_int);
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
myServo1.attach(servo_pin.toInt(), 500, 2400);
|
||||
myServo1.write(start_state_int);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (servo_number == "2") {
|
||||
#ifdef ESP8266
|
||||
myServo2.attach(servo_pin.toInt());
|
||||
myServo2.write(start_state_int);
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
myServo2.attach(servo_pin.toInt(), 500, 2400);
|
||||
myServo2.write(start_state_int);
|
||||
#endif
|
||||
}
|
||||
|
||||
jsonWriteStr(configOptionJson, "s_min_val" + servo_number, min_value);
|
||||
jsonWriteStr(configOptionJson, "s_max_val" + servo_number, max_value);
|
||||
jsonWriteStr(configOptionJson, "s_min_deg" + servo_number, min_deg);
|
||||
jsonWriteStr(configOptionJson, "s_max_deg" + servo_number, max_deg);
|
||||
|
||||
jsonWriteStr(configLiveJson, "servo" + servo_number, start_state);
|
||||
|
||||
createWidgetParam(widget_name, page_name, page_number, "range", "servo" + servo_number, "min", min_value, "max", max_value, "k", "1");
|
||||
}
|
||||
|
||||
void servoSet() {
|
||||
String servo_number = sCmd.next();
|
||||
String servo_state = sCmd.next();
|
||||
int servo_state_int = servo_state.toInt();
|
||||
|
||||
//int pin = jsonReadInt(configOptionJson, "servo_pin" + servo_number);
|
||||
|
||||
servo_state_int = map(servo_state_int,
|
||||
jsonReadInt(configOptionJson, "s_min_val" + servo_number),
|
||||
jsonReadInt(configOptionJson, "s_max_val" + servo_number),
|
||||
jsonReadInt(configOptionJson, "s_min_deg" + servo_number),
|
||||
jsonReadInt(configOptionJson, "s_max_deg" + servo_number));
|
||||
|
||||
if (servo_number == "1") {
|
||||
#ifdef ESP8266
|
||||
myServo1.write(servo_state_int);
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
myServo1.write(servo_state_int);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (servo_number == "2") {
|
||||
#ifdef ESP8266
|
||||
myServo2.write(servo_state_int);
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
myServo2.write(servo_state_int);
|
||||
#endif
|
||||
}
|
||||
|
||||
//Serial.println(servo_state_int);
|
||||
|
||||
eventGen("servo", servo_number);
|
||||
|
||||
jsonWriteStr(configLiveJson, "servo" + servo_number, servo_state);
|
||||
|
||||
MqttClient::publishStatus("servo" + servo_number, servo_state);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_ENABLED
|
||||
void serialBegin() {
|
||||
String s_speed = sCmd.next();
|
||||
String rxPin = sCmd.next();
|
||||
String txPin = sCmd.next();
|
||||
|
||||
if (mySerial) {
|
||||
delete mySerial;
|
||||
}
|
||||
|
||||
mySerial = new SoftwareSerial(rxPin.toInt(), txPin.toInt());
|
||||
mySerial->begin(s_speed.toInt());
|
||||
|
||||
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);
|
||||
pm.info("serial read: " + line);
|
||||
//line.replace("#", " ");
|
||||
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() {
|
||||
upgrade = true;
|
||||
}
|
||||
|
||||
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) {
|
||||
order_loop += cmdStr;
|
||||
if (!cmdStr.endsWith(",")) {
|
||||
order_loop += ",";
|
||||
}
|
||||
}
|
||||
|
||||
void fileExecute(const String &filename) {
|
||||
String cmdStr = readFile(filename, 2048);
|
||||
cmdStr += "\r\n";
|
||||
cmdStr.replace("\r\n", "\n");
|
||||
cmdStr.replace("\r", "\n");
|
||||
|
||||
while (cmdStr.length() != 0) {
|
||||
String buf = selectToMarker(cmdStr, "\n");
|
||||
sCmd.readStr(buf);
|
||||
cmdStr = deleteBeforeDelimiter(cmdStr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void stringExecute(String &cmdStr) {
|
||||
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 (order_loop.length()) {
|
||||
String tmp = selectToMarker(order_loop, ","); //выделяем первую команду rel 5 1,
|
||||
sCmd.readStr(tmp); //выполняем
|
||||
pm.info("do: " + order_loop);
|
||||
order_loop = deleteBeforeDelimiter(order_loop, ","); //осекаем
|
||||
}
|
||||
}
|
||||
@@ -1,79 +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);
|
||||
|
||||
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 = "";
|
||||
String order_loop = "";
|
||||
|
||||
// Sensors
|
||||
String analog_value_names_list;
|
||||
int enter_to_analog_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 upgrade_url = false;
|
||||
boolean upgrade = 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;
|
||||
@@ -1,200 +0,0 @@
|
||||
#include "HttpServer.h"
|
||||
|
||||
#include "Utils/FileUtils.h"
|
||||
#include "Utils/WebUtils.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 ESP32
|
||||
server.addHandler(new SPIFFSEditor(LittleFS, login, pass);
|
||||
#elif defined(ESP8266)
|
||||
server.addHandler(new SPIFFSEditor(login, pass));
|
||||
#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("command: " + cmdStr);
|
||||
addCommandLoop(cmdStr);
|
||||
request->send(200, "text/text", "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("hello!", NULL, millis(), 1000);
|
||||
});
|
||||
server.addHandler(&events);
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
} // namespace HttpServer
|
||||
120
src/Init.cpp
120
src/Init.cpp
@@ -1,120 +0,0 @@
|
||||
#include "Global.h"
|
||||
|
||||
void handle_uptime();
|
||||
void handle_statistics();
|
||||
void telemetry_init();
|
||||
|
||||
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() {
|
||||
logging_value_names_list = "";
|
||||
enter_to_logging_counter = LOG1 - 1;
|
||||
|
||||
analog_value_names_list = "";
|
||||
enter_to_analog_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);
|
||||
}
|
||||
}
|
||||
153
src/Logging.cpp
153
src/Logging.cpp
@@ -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()) {
|
||||
addFile(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
|
||||
@@ -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 _server->status() != CLOSED;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
sint8_t moveX = 0;
|
||||
sint8_t 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;
|
||||
}
|
||||
@@ -1,308 +0,0 @@
|
||||
#include "MqttClient.h"
|
||||
#include "Global.h"
|
||||
#include <LittleFS.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() {
|
||||
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")) {
|
||||
// название топика - команда,
|
||||
// значение - параметр
|
||||
//IoTmanager/800324-1458415/button99/control 1
|
||||
String topic = selectFromMarkerToMarker(topicStr, "/", 3);
|
||||
topic = add_set(topic);
|
||||
String number = selectToMarkerLast(topic, "Set");
|
||||
topic.replace(number, "");
|
||||
|
||||
order_loop += topic;
|
||||
order_loop += " ";
|
||||
order_loop += number;
|
||||
order_loop += " ";
|
||||
order_loop += payloadStr;
|
||||
order_loop += ",";
|
||||
} else if (topicStr.indexOf("order")) {
|
||||
payloadStr.replace("_", " ");
|
||||
order_loop += payloadStr;
|
||||
order_loop += ",";
|
||||
} else if (topicStr.indexOf("update")) {
|
||||
if (payloadStr == "1") {
|
||||
upgrade = true;
|
||||
}
|
||||
} 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("on seek 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
|
||||
@@ -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
|
||||
@@ -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");
|
||||
}
|
||||
102
src/Scenario.cpp
102
src/Scenario.cpp
@@ -1,102 +0,0 @@
|
||||
#include "Global.h"
|
||||
|
||||
static const char* MODULE = "Scen";
|
||||
|
||||
boolean isScenarioEnabled() {
|
||||
return jsonReadBool(configSetupJson, "scen") && jsonReadStr(configOptionJson, "scenario_status") != "";
|
||||
}
|
||||
|
||||
void loopScenario() {
|
||||
if (!isScenarioEnabled()) {
|
||||
return;
|
||||
}
|
||||
String str = scenario;
|
||||
str += "\n";
|
||||
str.replace("\r\n", "\n");
|
||||
str.replace("\r", "\n");
|
||||
|
||||
size_t i = 0;
|
||||
while (str.length()) {
|
||||
String block = selectToMarker(str, "end");
|
||||
if (!block.length()) {
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
|
||||
if (scenario_line_status[i] == 1) {
|
||||
//выделяем первую строку самого сценария button1 = 1 (условие)
|
||||
String condition = selectToMarker(block, "\n");
|
||||
String param_name = selectFromMarkerToMarker(condition, " ", 0);
|
||||
String order = jsonReadStr(configOptionJson, "scenario_status"); //читаем весь файл событий
|
||||
String param = selectToMarker(order, ","); //читаем первое событие из файла событий
|
||||
if (param_name == param) { //если поступившее событие равно событию заданному buttonSet1 в файле начинаем его обработку
|
||||
|
||||
String sign = selectFromMarkerToMarker(condition, " ", 1); //читаем знак (=)
|
||||
String value = selectFromMarkerToMarker(condition, " ", 2); //читаем значение (1)
|
||||
if (value.indexOf("digit") != -1) {
|
||||
// value = add_set(value);
|
||||
value = jsonReadStr(configLiveJson, value);
|
||||
}
|
||||
if (value.indexOf("time") != -1) {
|
||||
// value = add_set(value);
|
||||
value = jsonReadStr(configLiveJson, value);
|
||||
}
|
||||
boolean flag = false; //если одно из значений совпало то только тогда начинаем выполнять комнады
|
||||
if (sign == "=") {
|
||||
if (jsonReadStr(configLiveJson, param_name) == value) flag = true;
|
||||
}
|
||||
if (sign == "!=") {
|
||||
if (jsonReadStr(configLiveJson, param_name) != value) flag = true;
|
||||
}
|
||||
if (sign == "<") {
|
||||
if (jsonReadStr(configLiveJson, param_name).toInt() < value.toInt()) flag = true;
|
||||
}
|
||||
if (sign == ">") {
|
||||
if (jsonReadStr(configLiveJson, param_name).toInt() > value.toInt()) flag = true;
|
||||
}
|
||||
if (sign == ">=") {
|
||||
if (jsonReadStr(configLiveJson, param_name).toInt() >= value.toInt()) flag = true;
|
||||
}
|
||||
if (sign == "<=") {
|
||||
if (jsonReadStr(configLiveJson, param_name).toInt() <= value.toInt()) flag = true;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
block = deleteBeforeDelimiter(block, "\n"); //удаляем строку самого сценария оставляя только команды
|
||||
stringExecute(block); //выполняем все команды
|
||||
|
||||
pm.info(condition + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
str = deleteBeforeDelimiter(str, "end\n"); //удаляем первый сценарий
|
||||
//-----------------------------------------------------------------------------------------------------------------------
|
||||
}
|
||||
String tmp2 = jsonReadStr(configOptionJson, "scenario_status"); //читаем файл событий
|
||||
tmp2 = deleteBeforeDelimiter(tmp2, ","); //удаляем выполненное событие
|
||||
jsonWriteStr(configOptionJson, "scenario_status", tmp2); //записываем обновленный файл событий
|
||||
}
|
||||
|
||||
// событие: имя + Set + номер
|
||||
// button+Set+1
|
||||
void eventGen(String event_name, String number) {
|
||||
if (!jsonReadBool(configSetupJson, "scen")) {
|
||||
return;
|
||||
}
|
||||
// генерирование события
|
||||
String tmp = jsonReadStr(configOptionJson, "scenario_status");
|
||||
jsonWriteStr(configOptionJson, "scenario_status", tmp + 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;
|
||||
}
|
||||
644
src/Sensors.cpp
644
src/Sensors.cpp
@@ -1,644 +0,0 @@
|
||||
#include "Global.h"
|
||||
|
||||
OneWire *oneWire;
|
||||
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 sensors_init() {
|
||||
ts.add(
|
||||
SENSORS, 1000, [&](void *) {
|
||||
static int counter;
|
||||
counter++;
|
||||
|
||||
#ifdef LEVEL_ENABLED
|
||||
if (sensors_reading_map[0] == 1)
|
||||
ultrasonic_reading();
|
||||
#endif
|
||||
|
||||
if (counter > 10) {
|
||||
counter = 0;
|
||||
|
||||
#ifdef ANALOG_ENABLED
|
||||
if (sensors_reading_map[1] == 1)
|
||||
analog_reading1();
|
||||
if (sensors_reading_map[2] == 1)
|
||||
analog_reading2();
|
||||
#endif
|
||||
|
||||
#ifdef DALLAS_ENABLED
|
||||
if (sensors_reading_map[3] == 1)
|
||||
dallas_reading();
|
||||
#endif
|
||||
|
||||
#ifdef DHT_ENABLED
|
||||
if (sensors_reading_map[4] == 1)
|
||||
dhtT_reading();
|
||||
if (sensors_reading_map[5] == 1)
|
||||
dhtH_reading();
|
||||
if (sensors_reading_map[6] == 1)
|
||||
dhtP_reading();
|
||||
if (sensors_reading_map[7] == 1)
|
||||
dhtC_reading();
|
||||
if (sensors_reading_map[8] == 1)
|
||||
dhtD_reading();
|
||||
#endif
|
||||
|
||||
#ifdef BMP_ENABLED
|
||||
if (sensors_reading_map[9] == 1)
|
||||
bmp280T_reading();
|
||||
if (sensors_reading_map[10] == 1)
|
||||
bmp280P_reading();
|
||||
#endif
|
||||
|
||||
#ifdef BME_ENABLED
|
||||
if (sensors_reading_map[11] == 1)
|
||||
bme280T_reading();
|
||||
if (sensors_reading_map[12] == 1)
|
||||
bme280P_reading();
|
||||
if (sensors_reading_map[13] == 1)
|
||||
bme280H_reading();
|
||||
if (sensors_reading_map[14] == 1)
|
||||
bme280A_reading();
|
||||
#endif
|
||||
}
|
||||
},
|
||||
nullptr, true);
|
||||
}
|
||||
|
||||
//=========================================================================================================================================
|
||||
//=========================================Модуль измерения уровня в баке==================================================================
|
||||
#ifdef LEVEL_ENABLED
|
||||
//levelPr p 14 12 Вода#в#баке,#% Датчики fillgauge 125 20 1
|
||||
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
|
||||
//=========================================================================================================================================
|
||||
//=========================================Модуль аналогового сенсора======================================================================
|
||||
#ifdef ANALOG_ENABLED
|
||||
//analog adc 0 Аналоговый#вход,#% Датчики any-data 1 1023 1 100 1
|
||||
void analog() {
|
||||
String value_name = sCmd.next();
|
||||
String pin = sCmd.next();
|
||||
String widget_name = sCmd.next();
|
||||
String page_name = sCmd.next();
|
||||
String type = sCmd.next();
|
||||
String analog_start = sCmd.next();
|
||||
String analog_end = sCmd.next();
|
||||
String analog_start_out = sCmd.next();
|
||||
String analog_end_out = sCmd.next();
|
||||
String page_number = sCmd.next();
|
||||
analog_value_names_list += value_name + ",";
|
||||
enter_to_analog_counter++;
|
||||
jsonWriteStr(configOptionJson, value_name + "_st", analog_start);
|
||||
jsonWriteStr(configOptionJson, value_name + "_end", analog_end);
|
||||
jsonWriteStr(configOptionJson, value_name + "_st_out", analog_start_out);
|
||||
jsonWriteStr(configOptionJson, value_name + "_end_out", analog_end_out);
|
||||
createWidgetByType(widget_name, page_name, page_number, type, value_name);
|
||||
if (enter_to_analog_counter == 1) {
|
||||
sensors_reading_map[1] = 1;
|
||||
}
|
||||
if (enter_to_analog_counter == 2) {
|
||||
sensors_reading_map[2] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void analog_reading1() {
|
||||
String value_name = selectFromMarkerToMarker(analog_value_names_list, ",", 0);
|
||||
#ifdef ESP32
|
||||
int analog_in = analogRead(34);
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
int analog_in = analogRead(A0);
|
||||
#endif
|
||||
int analog = map(analog_in,
|
||||
jsonReadInt(configOptionJson, value_name + "_st"),
|
||||
jsonReadInt(configOptionJson, value_name + "_end"),
|
||||
jsonReadInt(configOptionJson, value_name + "_st_out"),
|
||||
jsonReadInt(configOptionJson, value_name + "_end_out"));
|
||||
jsonWriteInt(configLiveJson, value_name, analog);
|
||||
eventGen(value_name, "");
|
||||
MqttClient::publishStatus(value_name, String(analog));
|
||||
Serial.println("[I] sensor '" + value_name + "' data: " + String(analog));
|
||||
}
|
||||
|
||||
void analog_reading2() {
|
||||
String value_name = selectFromMarkerToMarker(analog_value_names_list, ",", 1);
|
||||
#ifdef ESP32
|
||||
int analog_in = analogRead(35);
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
int analog_in = analogRead(A0);
|
||||
#endif
|
||||
int analog = map(analog_in,
|
||||
jsonReadInt(configOptionJson, value_name + "_st"),
|
||||
jsonReadInt(configOptionJson, value_name + "_end"),
|
||||
jsonReadInt(configOptionJson, value_name + "_st_out"),
|
||||
jsonReadInt(configOptionJson, value_name + "_end_out"));
|
||||
jsonWriteInt(configLiveJson, value_name, analog);
|
||||
eventGen(value_name, "");
|
||||
MqttClient::publishStatus(value_name, String(analog));
|
||||
Serial.println("[I] sensor '" + value_name + "' data: " + String(analog));
|
||||
}
|
||||
#endif
|
||||
//=========================================================================================================================================
|
||||
//=========================================Модуль температурного сенсора ds18b20===========================================================
|
||||
#ifdef DALLAS_ENABLED
|
||||
void dallas() {
|
||||
String value_name = sCmd.next();
|
||||
String pin = 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();
|
||||
oneWire = new OneWire((uint8_t)pin.toInt());
|
||||
|
||||
sensors.setOneWire(oneWire);
|
||||
sensors.begin();
|
||||
sensors.setResolution(12);
|
||||
|
||||
createWidgetByType(widget_name, page_name, page_number, type, "dallas");
|
||||
sensors_reading_map[3] = 1;
|
||||
}
|
||||
|
||||
void dallas_reading() {
|
||||
float temp = 0;
|
||||
sensors.requestTemperatures();
|
||||
temp = sensors.getTempCByIndex(0);
|
||||
jsonWriteStr(configLiveJson, "dallas", String(temp));
|
||||
eventGen("dallas", "");
|
||||
MqttClient::publishStatus("dallas", String(temp));
|
||||
Serial.println("[I] sensor 'dallas' 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;
|
||||
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));
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
113
src/Upgrade.cpp
113
src/Upgrade.cpp
@@ -1,113 +0,0 @@
|
||||
#include "Upgrade.h"
|
||||
|
||||
#include "Global.h"
|
||||
|
||||
static const char* MODULE = "Upgr";
|
||||
|
||||
static const char* filesystem_image_url PROGMEM = "http://91.204.228.124:1100/update/%s/fs.bin";
|
||||
static const char* available_url PROGMEM = "http://91.204.228.124:1100/update/%s/version.txt";
|
||||
|
||||
const String getAvailableUrl(const char* mcu) {
|
||||
char buf[128];
|
||||
sprintf_P(buf, available_url, mcu);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void getLastVersion() {
|
||||
if (upgrade_url) {
|
||||
upgrade_url = false;
|
||||
String url;
|
||||
#ifdef ESP32
|
||||
url = getAvailableUrl("esp32");
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
url = getAvailableUrl("esp8266");
|
||||
#endif
|
||||
lastVersion = getURL(url);
|
||||
jsonWriteStr(configSetupJson, "last_version", lastVersion);
|
||||
}
|
||||
}
|
||||
|
||||
void initUpdater() {
|
||||
if (isNetworkActive()) {
|
||||
getLastVersion();
|
||||
if (lastVersion.length()) {
|
||||
pm.info("available: " + lastVersion);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void upgrade_firmware() {
|
||||
String scenario_for_update;
|
||||
String config_for_update;
|
||||
String configSetup_for_update;
|
||||
|
||||
scenario_for_update = readFile(String(DEVICE_SCENARIO_FILE), 4000);
|
||||
config_for_update = readFile(String(DEVICE_CONFIG_FILE), 4000);
|
||||
configSetup_for_update = configSetupJson;
|
||||
|
||||
Serial.println("Start upgrade SPIFFS, please wait...");
|
||||
|
||||
WiFiClient client_for_upgrade;
|
||||
|
||||
#ifdef ESP32
|
||||
httpUpdate.rebootOnUpdate(false);
|
||||
t_httpUpdate_return ret = httpUpdate.updateSpiffs(client_for_upgrade, "http://91.204.228.124:1100/update/esp32/esp32-esp8266_iot-manager_modules_firmware.spiffs.bin");
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
ESPhttpUpdate.rebootOnUpdate(false);
|
||||
t_httpUpdate_return ret = ESPhttpUpdate.updateSpiffs(client_for_upgrade, "http://91.204.228.124:1100/update/esp8266/esp32-esp8266_iot-manager_modules_firmware.spiffs.bin");
|
||||
#endif
|
||||
|
||||
if (ret == HTTP_UPDATE_OK) {
|
||||
writeFile(String(DEVICE_SCENARIO_FILE), scenario_for_update);
|
||||
writeFile(String(DEVICE_CONFIG_FILE), config_for_update);
|
||||
writeFile("config.json", configSetup_for_update);
|
||||
saveConfig();
|
||||
|
||||
Serial.println("Upgrade done!");
|
||||
Serial.println("Start upgrade BUILD, please wait...");
|
||||
|
||||
#ifdef ESP32
|
||||
//httpUpdate.rebootOnUpdate(true);
|
||||
t_httpUpdate_return ret = httpUpdate.update(client_for_upgrade, "http://91.204.228.124:1100/update/esp32/esp32-esp8266_iot-manager_modules_firmware.ino.bin");
|
||||
#endif
|
||||
#ifdef ESP8266
|
||||
//ESPhttpUpdate.rebootOnUpdate(true);
|
||||
t_httpUpdate_return ret = ESPhttpUpdate.update(client_for_upgrade, "http://91.204.228.124:1100/update/esp8266/esp32-esp8266_iot-manager_modules_firmware.ino.bin");
|
||||
#endif
|
||||
|
||||
if (ret == HTTP_UPDATE_OK) {
|
||||
Serial.println("Upgrade done!");
|
||||
Serial.println("Restart...");
|
||||
ESP.restart();
|
||||
} else {
|
||||
Serial.println("[E] on build");
|
||||
}
|
||||
} else {
|
||||
Serial.println("[E] on upgrade");
|
||||
}
|
||||
}
|
||||
|
||||
void flashUpgrade() {
|
||||
if (upgrade) {
|
||||
upgrade = false;
|
||||
upgrade_firmware();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void upgrade_status(t_httpUpdate_return set) {
|
||||
switch (set) {
|
||||
case HTTP_UPDATE_FAILED:
|
||||
Serial.printf("UPDATE_FAILED Error (%d): %s", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
|
||||
break;
|
||||
case HTTP_UPDATE_NO_UPDATES:
|
||||
Serial.println("NO_UPDATES");
|
||||
break;
|
||||
case HTTP_UPDATE_OK:
|
||||
Serial.println("HTTP_UPDATE_OK");
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -1,129 +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 addFile(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";
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
#include "Utils\JsonUtils.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 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;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#include "Utils/PresetUtils.h"
|
||||
|
||||
static const char* config_file_fmt PROGMEM = "/conf/%s%03d.txt";
|
||||
|
||||
const String getConfigFile(uint8_t preset, ConfigType_t type) {
|
||||
char buf[64];
|
||||
sprintf_P(buf, config_file_fmt, (type == CT_CONFIG) ? "c" : "s", preset);
|
||||
return String(buf);
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
#include "Utils\StringUtils.h"
|
||||
|
||||
String selectToMarkerLast(String str, String found) {
|
||||
int p = str.lastIndexOf(found);
|
||||
return str.substring(p + found.length());
|
||||
}
|
||||
|
||||
String selectToMarker(String str, String found) {
|
||||
int p = str.indexOf(found);
|
||||
return str.substring(0, p);
|
||||
}
|
||||
|
||||
String 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);
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
#include "Utils/SysUtils.h"
|
||||
|
||||
#include "Global.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
static uint32_t total_memory = 52864;
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
static uint32_t total_memory = 362868;
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ESP32
|
||||
String getHeapStats() {
|
||||
uint32_t free;
|
||||
uint16_t max;
|
||||
uint8_t frag;
|
||||
ESP.getHeapStats(&free, &max, &frag);
|
||||
String buf;
|
||||
buf += prettyBytes(free);
|
||||
buf += " ";
|
||||
buf += frag;
|
||||
buf += '%';
|
||||
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);
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
/*
|
||||
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 won’t change
|
||||
strcpy_P(buff, PSTR("Exception"));
|
||||
} else if (resetInfo.reason == REASON_SOFT_WDT_RST) { // software watch dog reset, GPIO status won’t change
|
||||
strcpy_P(buff, PSTR("Software Watchdog"));
|
||||
} else if (resetInfo.reason == REASON_SOFT_RESTART) { // software restart ,system_restart , GPIO status won’t 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);
|
||||
}
|
||||
*/
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,113 +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;
|
||||
do {
|
||||
sint8_t connRes = WiFi.waitForConnectResult(1000);
|
||||
switch (connRes) {
|
||||
case WL_NO_SSID_AVAIL: {
|
||||
pm.error("No ssid available");
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
309
src/Web.cpp
309
src/Web.cpp
@@ -1,309 +0,0 @@
|
||||
#include "Global.h"
|
||||
|
||||
#include "CaptiveRequestHandler.h"
|
||||
#include "Utils/PresetUtils.h"
|
||||
|
||||
static const char* MODULE = "Web";
|
||||
|
||||
static const uint8_t MIN_PRESET = 1;
|
||||
static const uint8_t MAX_PRESET = 21;
|
||||
|
||||
bool parseRequestForPreset(AsyncWebServerRequest* request, uint8_t& preset) {
|
||||
if (request->hasArg("preset")) {
|
||||
preset = request->getParam("preset")->value().toInt();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void web_init() {
|
||||
// server.addHandler(new CaptiveRequestHandler(jsonReadStr(configSetupJson, "name").c_str())).setFilter(ON_AP_FILTER);
|
||||
|
||||
server.on("/set", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||
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");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("devinit")) {
|
||||
Device_init();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("scen")) {
|
||||
String value = request->getParam("scen")->value();
|
||||
if (value == "0") {
|
||||
jsonWriteStr(configSetupJson, "scen", value);
|
||||
saveConfig();
|
||||
loadScenario();
|
||||
}
|
||||
if (value == "1") {
|
||||
jsonWriteStr(configSetupJson, "scen", value);
|
||||
saveConfig();
|
||||
loadScenario();
|
||||
}
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("sceninit")) {
|
||||
loadScenario();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
#ifdef LOGGING_ENABLED
|
||||
if (request->hasArg("cleanlog")) {
|
||||
clean_log_date();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
#endif
|
||||
//==============================udp settings=============================================
|
||||
if (request->hasArg("udponoff")) {
|
||||
String value = request->getParam("udponoff")->value();
|
||||
if (value == "0") {
|
||||
jsonWriteStr(configSetupJson, "udponoff", value);
|
||||
saveConfig();
|
||||
loadScenario();
|
||||
}
|
||||
if (value == "1") {
|
||||
jsonWriteStr(configSetupJson, "udponoff", value);
|
||||
saveConfig();
|
||||
loadScenario();
|
||||
}
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("updatelist")) {
|
||||
removeFile("/dev.csv");
|
||||
addFile("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, "text/text", "OK");
|
||||
}
|
||||
//==============================wifi settings=============================================
|
||||
if (request->hasArg("routerssid")) {
|
||||
jsonWriteStr(configSetupJson, "routerssid", request->getParam("routerssid")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
if (request->hasArg("routerpass")) {
|
||||
jsonWriteStr(configSetupJson, "routerpass", request->getParam("routerpass")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
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, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("weblogin")) {
|
||||
jsonWriteStr(configSetupJson, "weblogin", request->getParam("weblogin")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
if (request->hasArg("webpass")) {
|
||||
jsonWriteStr(configSetupJson, "webpass", request->getParam("webpass")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("timezone")) {
|
||||
String timezoneStr = request->getParam("timezone")->value();
|
||||
jsonWriteStr(configSetupJson, "timezone", timezoneStr);
|
||||
saveConfig();
|
||||
timeNow->setTimezone(timezoneStr.toInt());
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
if (request->hasArg("ntp")) {
|
||||
String ntpStr = request->getParam("ntp")->value();
|
||||
jsonWriteStr(configSetupJson, "ntp", ntpStr);
|
||||
saveConfig();
|
||||
timeNow->setNtpPool(ntpStr);
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("device")) {
|
||||
if (request->getParam("device")->value() == "ok") ESP.restart();
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("blink")) {
|
||||
String value = request->getParam("blink")->value();
|
||||
if (value == "0") {
|
||||
jsonWriteStr(configSetupJson, "blink", value);
|
||||
saveConfig();
|
||||
}
|
||||
if (value == "1") {
|
||||
jsonWriteStr(configSetupJson, "blink", value);
|
||||
saveConfig();
|
||||
}
|
||||
request->send(200, "text/text", "OK");
|
||||
}
|
||||
//==============================mqtt settings=============================================
|
||||
if (request->hasArg("mqttServer")) {
|
||||
jsonWriteStr(configSetupJson, "mqttServer", request->getParam("mqttServer")->value());
|
||||
saveConfig();
|
||||
mqttParamsChanged = true;
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
if (request->hasArg("mqttPort")) {
|
||||
int port = (request->getParam("mqttPort")->value()).toInt();
|
||||
jsonWriteInt(configSetupJson, "mqttPort", port);
|
||||
saveConfig();
|
||||
mqttParamsChanged = true;
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
if (request->hasArg("mqttPrefix")) {
|
||||
jsonWriteStr(configSetupJson, "mqttPrefix", request->getParam("mqttPrefix")->value());
|
||||
saveConfig();
|
||||
mqttParamsChanged = true;
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
if (request->hasArg("mqttUser")) {
|
||||
jsonWriteStr(configSetupJson, "mqttUser", request->getParam("mqttUser")->value());
|
||||
saveConfig();
|
||||
mqttParamsChanged = true;
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
if (request->hasArg("mqttPass")) {
|
||||
jsonWriteStr(configSetupJson, "mqttPass", request->getParam("mqttPass")->value());
|
||||
saveConfig();
|
||||
mqttParamsChanged = true;
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
if (request->hasArg("mqttsend")) {
|
||||
mqtt_send_settings_to_udp = true;
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
if (request->hasArg("mqttcheck")) {
|
||||
String buf = "{}";
|
||||
String payload = "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>" + MqttClient::getStateStr();
|
||||
jsonWriteStr(buf, "title", payload);
|
||||
jsonWriteStr(buf, "class", "pop-up");
|
||||
|
||||
request->send(200, "text/text", buf);
|
||||
}
|
||||
|
||||
//==============================push settings=============================================
|
||||
#ifdef PUSH_ENABLED
|
||||
if (request->hasArg("pushingboxid")) {
|
||||
jsonWriteStr(configSetupJson, "pushingboxid", request->getParam("pushingboxid")->value());
|
||||
saveConfig();
|
||||
request->send(200, "text/text", "ok");
|
||||
}
|
||||
#endif
|
||||
//==============================utilities settings=============================================
|
||||
if (request->hasArg("itoc")) {
|
||||
busScanFlag = true;
|
||||
busToScan = BS_I2C;
|
||||
request->redirect("/?set.utilities");
|
||||
}
|
||||
|
||||
if (request->hasArg("onewire")) {
|
||||
busScanFlag = true;
|
||||
busToScan = BS_ONE_WIRE;
|
||||
request->redirect("/?set.utilities");
|
||||
}
|
||||
|
||||
if (request->hasArg("fscheck")) {
|
||||
fsCheckFlag = true;
|
||||
request->redirect("/?set.utilities");
|
||||
}
|
||||
});
|
||||
//==============================upgrade settings=============================================
|
||||
server.on("/check", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||
upgrade_url = true;
|
||||
pm.info("firmware version: " + lastVersion);
|
||||
String tmp = "{}";
|
||||
int case_of_update;
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
lastVersion = "nowifi";
|
||||
}
|
||||
|
||||
if (!FLASH_4MB) {
|
||||
lastVersion = "less";
|
||||
}
|
||||
|
||||
if (lastVersion == FIRMWARE_VERSION) case_of_update = 1;
|
||||
if (lastVersion != FIRMWARE_VERSION) case_of_update = 2;
|
||||
if (lastVersion == "error") case_of_update = 3;
|
||||
if (lastVersion == "") case_of_update = 4;
|
||||
if (lastVersion == "less") case_of_update = 5;
|
||||
if (lastVersion == "nowifi") case_of_update = 6;
|
||||
if (lastVersion == "notsupported") case_of_update = 7;
|
||||
|
||||
switch (case_of_update) {
|
||||
case 1: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Последняя версия прошивки уже установлена.");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Имеется новая версия прошивки<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>");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
} break;
|
||||
|
||||
case 3: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Ошибка... Cервер не найден. Попробуйте позже...");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
} break;
|
||||
|
||||
case 4: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Нажмите на кнопку \"обновить прошивку\" повторно...");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Обновление по воздуху не поддерживается, модуль имеет меньше 4 мб памяти...");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Устройство не подключено к роутеру...");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: {
|
||||
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Обновление на новую версию возможно только через usb...");
|
||||
jsonWriteStr(tmp, "class", "pop-up");
|
||||
break;
|
||||
}
|
||||
}
|
||||
request->send(200, "text/text", tmp);
|
||||
});
|
||||
|
||||
server.on("/upgrade", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||
upgrade = true;
|
||||
String tmp = "{}";
|
||||
request->send(200, "text/text", "ok");
|
||||
});
|
||||
}
|
||||
@@ -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 widget, String page, String pageNumber, String filename, String topic) {
|
||||
String buf = "{}";
|
||||
if (!loadWidget(filename, buf)) {
|
||||
pm.error("failed " + widget);
|
||||
return;
|
||||
}
|
||||
widget.replace("#", " ");
|
||||
page.replace("#", " ");
|
||||
|
||||
jsonWriteStr(buf, "page", page);
|
||||
jsonWriteStr(buf, "order", pageNumber);
|
||||
jsonWriteStr(buf, "descr", widget);
|
||||
jsonWriteStr(buf, "topic", prex + "/" + topic);
|
||||
|
||||
#ifdef LAYOUT_IN_RAM
|
||||
all_widgets += widget + "\r\n";
|
||||
#else
|
||||
addFile("layout.txt", buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
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
|
||||
addFile("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
|
||||
addFile("layout.txt", buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
void createWidgetByType(String widget, String page, String pageNumber, String type, String topic) {
|
||||
pm.info("create" + type);
|
||||
createWidget(widget, page, pageNumber, getWidgetFile(type), topic);
|
||||
}
|
||||
|
||||
const String getWidgetFile(const String& name) {
|
||||
pm.info("get " + name);
|
||||
return "/widgets/" + name + ".json";
|
||||
}
|
||||
235
src/main.cpp
235
src/main.cpp
@@ -1,235 +0,0 @@
|
||||
#include "Global.h"
|
||||
|
||||
#include "HttpServer.h"
|
||||
#include "Bus/BusScanner.h"
|
||||
#include "Utils/Timings.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();
|
||||
|
||||
pm.info("FS");
|
||||
fileSystemInit();
|
||||
|
||||
pm.info("Config");
|
||||
loadConfig();
|
||||
|
||||
pm.info("Clock");
|
||||
clock_init();
|
||||
|
||||
pm.info("Commands");
|
||||
cmd_init();
|
||||
|
||||
pm.info("Sensors");
|
||||
sensors_init();
|
||||
|
||||
pm.info("Init");
|
||||
all_init();
|
||||
|
||||
pm.info("Network");
|
||||
startSTAMode();
|
||||
|
||||
pm.info("Uptime");
|
||||
uptime_init();
|
||||
|
||||
if (!TELEMETRY_UPDATE_INTERVAL) {
|
||||
pm.info("Telemetry: Disabled");
|
||||
}
|
||||
telemetry_init();
|
||||
|
||||
pm.info("Updater");
|
||||
initUpdater();
|
||||
|
||||
pm.info("HttpServer");
|
||||
HttpServer::init();
|
||||
|
||||
pm.info("WebAdmin");
|
||||
web_init();
|
||||
|
||||
#ifdef UDP_ENABLED
|
||||
pm.info("Broadcast UDP");
|
||||
UDP_init();
|
||||
#endif
|
||||
ts.add(
|
||||
TEST, 1000 * 60, [&](void*) {
|
||||
pm.info(printMemoryStatus());
|
||||
},
|
||||
nullptr, true);
|
||||
|
||||
just_load = false;
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!initialized) {
|
||||
return;
|
||||
}
|
||||
timeNow->loop();
|
||||
|
||||
#ifdef OTA_UPDATES_ENABLED
|
||||
ArduinoOTA.handle();
|
||||
#endif
|
||||
#ifdef WS_enable
|
||||
ws.cleanupClients();
|
||||
#endif
|
||||
not_async_actions();
|
||||
|
||||
MqttClient::loop();
|
||||
|
||||
loopCmd();
|
||||
|
||||
loopButton();
|
||||
|
||||
loopScenario();
|
||||
|
||||
#ifdef UDP_ENABLED
|
||||
loopUdp();
|
||||
#endif
|
||||
|
||||
loopSerial();
|
||||
|
||||
ts.update();
|
||||
}
|
||||
|
||||
void not_async_actions() {
|
||||
if (mqttParamsChanged) {
|
||||
MqttClient::reconnect();
|
||||
mqttParamsChanged = false;
|
||||
}
|
||||
|
||||
getLastVersion();
|
||||
|
||||
flashUpgrade();
|
||||
|
||||
#ifdef UDP_ENABLED
|
||||
do_udp_data_parse();
|
||||
do_mqtt_send_settings_to_udp();
|
||||
#endif
|
||||
|
||||
do_scan_bus();
|
||||
|
||||
do_check_fs();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void safeDataToFile(String data, String Folder) {
|
||||
String fileName;
|
||||
fileName.toLowerCase();
|
||||
fileName = deleteBeforeDelimiter(fileName, " ");
|
||||
fileName.replace(" ", ".");
|
||||
fileName.replace("..", ".");
|
||||
fileName = Folder + "/" + fileName + ".txt";
|
||||
|
||||
jsonWriteStr(configLiveJson, "test", fileName);
|
||||
}
|
||||
|
||||
void sendConfig(String topic, String widgetConfig, String key, String date) {
|
||||
yield();
|
||||
topic = jsonReadStr(configSetupJson, "mqttPrefix") + "/" + chipId + "/" + topic + "/status";
|
||||
String outer = "{\"widgetConfig\":";
|
||||
String inner = "{\"";
|
||||
inner = inner + key;
|
||||
inner = inner + "\":\"";
|
||||
inner = inner + date;
|
||||
inner = inner + "\"";
|
||||
inner = inner + "}}";
|
||||
String t = outer + inner;
|
||||
yield();
|
||||
}
|
||||
|
||||
void setChipId() {
|
||||
chipId = getChipId();
|
||||
Serial.println(chipId);
|
||||
}
|
||||
|
||||
void saveConfig() {
|
||||
writeFile(String("config.json"), configSetupJson);
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
#ifdef LED_PIN
|
||||
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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void do_fscheck(String& results) {
|
||||
// TODO Проверка наличие важных файлов, возможно версии ФС
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
void do_scan_bus() {
|
||||
if (busScanFlag) {
|
||||
String res = "";
|
||||
BusScanner* scanner = BusScannerFactory::get(res, busToScan);
|
||||
scanner->scan();
|
||||
jsonWriteStr(configLiveJson, BusScannerFactory::label(busToScan), res);
|
||||
busScanFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
void do_check_fs() {
|
||||
if (fsCheckFlag) {
|
||||
String buf;
|
||||
do_fscheck(buf);
|
||||
jsonWriteStr(configLiveJson, "fscheck", buf);
|
||||
fsCheckFlag = false;
|
||||
}
|
||||
}
|
||||
163
src/udp.cpp
163
src/udp.cpp
@@ -1,163 +0,0 @@
|
||||
#include "Global.h"
|
||||
|
||||
#ifdef ESP8266
|
||||
IPAddress udp_multicastIP(255, 255, 255, 255);
|
||||
ESP8266HTTPUpdateServer httpUpdater;
|
||||
WiFiUDP Udp;
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
IPAddress udp_multicastIP(239, 255, 255, 255);
|
||||
AsyncUDP udp;
|
||||
#endif
|
||||
String received_ip;
|
||||
String received_udp_line;
|
||||
int udp_period;
|
||||
boolean udp_busy = false;
|
||||
unsigned int udp_port = 4210;
|
||||
|
||||
void handleUdp_esp32();
|
||||
void add_dev_in_list(String fileName, String id, String dev_name, String ip);
|
||||
|
||||
#ifdef UDP_ENABLED
|
||||
void UDP_init() {
|
||||
removeFile("dev.csv");
|
||||
addFile("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 (jsonReadStr(configSetupJson, "udponoff") == "1") {
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
if (!udp_busy) {
|
||||
String line_to_send = "iotm;" + chipId + ";" + jsonReadStr(configSetupJson, "name");
|
||||
#ifdef ESP8266
|
||||
Udp.beginPacketMulticast(udp_multicastIP, udp_port, WiFi.localIP());
|
||||
Udp.write(line_to_send.c_str());
|
||||
Udp.endPacket();
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
udp.broadcast(line_to_send.c_str());
|
||||
#endif
|
||||
Serial.println("[UDP<=] dev info send");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
nullptr, false);
|
||||
}
|
||||
|
||||
void loopUdp() {
|
||||
#ifdef ESP8266
|
||||
if (jsonReadStr(configSetupJson, "udponoff") == "1") {
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
int packetSize = Udp.parsePacket();
|
||||
if (packetSize) {
|
||||
char udp_incomingPacket[255];
|
||||
Serial.printf("[UDP=>] Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
|
||||
received_ip = Udp.remoteIP().toString();
|
||||
int len = Udp.read(udp_incomingPacket, 255);
|
||||
if (len > 0) {
|
||||
udp_incomingPacket[len] = 0;
|
||||
}
|
||||
received_udp_line = String(udp_incomingPacket);
|
||||
|
||||
if (received_udp_line.indexOf("iotm;") >= 0) {
|
||||
udp_data_parse = true;
|
||||
}
|
||||
if (received_udp_line.indexOf("mqttServer") >= 0) {
|
||||
udp_data_parse = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void handleUdp_esp32() {
|
||||
#ifdef ESP32
|
||||
if (udp.listenMulticast(udp_multicastIP, udp_port)) {
|
||||
udp.onPacket([](AsyncUDPPacket packet) {
|
||||
received_udp_line = (char*)packet.data();
|
||||
received_ip = packet.remoteIP().toString();
|
||||
if (jsonReadStr(configSetupJson, "udponoff") == "1") {
|
||||
if (received_udp_line.indexOf("iotm;") >= 0) {
|
||||
udp_data_parse = true;
|
||||
}
|
||||
if (received_udp_line.indexOf("mqttServer") >= 0) {
|
||||
udp_data_parse = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void do_udp_data_parse() {
|
||||
if (udp_data_parse) {
|
||||
udp_data_parse = false;
|
||||
Serial.print("[UDP=>] " + received_ip);
|
||||
Serial.print(" ");
|
||||
Serial.println(received_udp_line);
|
||||
if (received_udp_line.indexOf("mqttServer") >= 0) {
|
||||
jsonWriteStr(configSetupJson, "mqttServer", jsonReadStr(received_udp_line, "mqttServer"));
|
||||
jsonWriteInt(configSetupJson, "mqttPort", jsonReadInt(received_udp_line, "mqttPort"));
|
||||
jsonWriteStr(configSetupJson, "mqttPrefix", jsonReadStr(received_udp_line, "mqttPrefix"));
|
||||
jsonWriteStr(configSetupJson, "mqttUser", jsonReadStr(received_udp_line, "mqttUser"));
|
||||
jsonWriteStr(configSetupJson, "mqttPass", jsonReadStr(received_udp_line, "mqttPass"));
|
||||
saveConfig();
|
||||
Serial.println("[V] new mqtt setting received from udp and saved");
|
||||
mqttParamsChanged = true;
|
||||
}
|
||||
if (received_udp_line.indexOf("iotm;") >= 0) {
|
||||
add_dev_in_list("dev.csv", selectFromMarkerToMarker(received_udp_line, ";", 1), selectFromMarkerToMarker(received_udp_line, ";", 2), received_ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void add_dev_in_list(String filename, String id, String dev_name, String ip) {
|
||||
auto file = seekFile("/" + filename);
|
||||
if (!file.find(id.c_str())) {
|
||||
addFile(filename, id + ";" + dev_name + "; <a href=\"http://" + ip + "\" target=\"_blank\"\">" + ip + "</a>");
|
||||
}
|
||||
}
|
||||
|
||||
void send_mqtt_to_udp() {
|
||||
if (jsonReadStr(configSetupJson, "udponoff") == "1") {
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
udp_busy = true;
|
||||
String mqtt_data = "{}";
|
||||
jsonWriteStr(mqtt_data, "mqttServer", jsonReadStr(configSetupJson, "mqttServer"));
|
||||
jsonWriteInt(mqtt_data, "mqttPort", jsonReadInt(configSetupJson, "mqttPort"));
|
||||
jsonWriteStr(mqtt_data, "mqttPrefix", jsonReadStr(configSetupJson, "mqttPrefix"));
|
||||
jsonWriteStr(mqtt_data, "mqttUser", jsonReadStr(configSetupJson, "mqttUser"));
|
||||
jsonWriteStr(mqtt_data, "mqttPass", jsonReadStr(configSetupJson, "mqttPass"));
|
||||
Serial.println(mqtt_data);
|
||||
#ifdef ESP8266
|
||||
Udp.beginPacketMulticast(udp_multicastIP, udp_port, WiFi.localIP());
|
||||
Udp.write(mqtt_data.c_str());
|
||||
Udp.endPacket();
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
udp.broadcast(mqtt_data.c_str());
|
||||
#endif
|
||||
Serial.println("[UDP<=] mqtt info send");
|
||||
udp_busy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void do_mqtt_send_settings_to_udp() {
|
||||
if (mqtt_send_settings_to_udp) {
|
||||
mqtt_send_settings_to_udp = false;
|
||||
send_mqtt_to_udp();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user