27 Commits
2.1.1 ... 2.3.2

Author SHA1 Message Date
Dmitry Borisenko
285a898ba9 some changes 2020-04-07 18:06:12 +02:00
Dmitry Borisenko
ba30af5182 add udp support and some new functions 2020-04-05 01:52:02 +02:00
Dmitry Borisenko
5250049e08 some changes 2020-04-02 22:56:01 +02:00
Dmitry Borisenko
c7ba7fecbc reduse ram consuption!!! 2020-03-30 01:45:42 +02:00
Dmitry Borisenko
abfc847793 New method of sending date - direct from SPIFFS to MQTT!!!! 2020-03-28 00:29:50 +01:00
Dmitry Borisenko
7d1c0268f5 Support logging of any sensor and charts 2020-03-27 15:48:17 +01:00
Dmitry Borisenko
b6145695cc logging date 2020-03-24 19:03:38 +01:00
Dmitry Borisenko
0cf60ab214 add logging date support 2020-03-24 19:01:11 +01:00
Dmitry Borisenko
a038960a4c going up to last core version 2020-03-23 23:50:20 +01:00
Dmitry Borisenko
cb2361c248 pic 2020-03-22 23:24:53 +01:00
Dmitry Borisenko
b799a48c8a fix many bugs 2020-03-22 22:41:52 +01:00
Dmitry Borisenko
9a775cd9d4 fix mqtt bug 2020-03-22 01:50:31 +01:00
Dmitry Borisenko
96e207676f add prefix 2020-03-21 18:14:38 +01:00
Dmitry Borisenko
ef92865886 some fix 2020-03-20 21:00:11 +01:00
Dmitry Borisenko
857177b5b7 some fix 2020-03-18 09:57:46 +01:00
Dmitry Borisenko
5fcb68ac65 some change 2020-03-17 17:54:57 +01:00
Dmitry Borisenko
8138893210 stepper motor support 2020-03-17 00:54:27 +01:00
Dmitry Borisenko
e1ef489706 add web socket and stepper control 2020-03-16 00:00:59 +01:00
Dmitry Borisenko
e2f8aaf505 bug with small file size 2020-03-04 22:10:59 +03:00
Dmitry Borisenko
60e2ada31a some fix 2020-03-04 15:22:15 +03:00
Dmitry Borisenko
0064e557f1 air firmware upgrade 2020-03-04 01:56:24 +03:00
Dmitry Borisenko
f8a50e09b7 add air firmware upgrade support 2020-03-04 00:27:35 +03:00
Dmitry Borisenko
a6117db46e some fix 2020-03-01 20:41:16 +03:00
Dmitry Borisenko
ec187af09d some fix 2020-02-22 03:34:44 +03:00
Dmitry Borisenko
7bc5be8db5 dht fixed, presets support 2020-02-19 03:14:21 +03:00
Dmitry Borisenko
a29a8b246c presets support 2020-02-18 16:22:17 +03:00
Dmitry Borisenko
8d16ae9188 some fix 2020-02-16 19:36:58 +03:00
119 changed files with 2843 additions and 1948 deletions

377
Cmd.ino
View File

@@ -2,7 +2,10 @@ 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);
@@ -17,6 +20,10 @@ void CMD_init() {
sCmd.addCommand("dhtH", dhtH);
sCmd.addCommand("dhtPerception", dhtPerception);
sCmd.addCommand("dhtComfort", dhtComfort);
sCmd.addCommand("dhtDewpoint", dhtDewpoint);
sCmd.addCommand("stepper", stepper);
sCmd.addCommand("stepperSet", stepperSet);
sCmd.addCommand("logging", logging);
@@ -39,23 +46,6 @@ void CMD_init() {
handle_time_init();
//======новые виджеты ver2.0=======//
/*
sCmd.addCommand("inputText", inputText);
sCmd.addCommand("inputTextSet", inputTextSet);
sCmd.addCommand("inputTime", inputTime);
sCmd.addCommand("inputTimeSet", inputTimeSet);
sCmd.addCommand("inputDate", inputDate);
sCmd.addCommand("inputDateSet", inputDateSet);
sCmd.addCommand("inputDate", inputDate);
//sCmd.addCommand("inputDropdown", inputDropdown);
*/
//=================================//
}
@@ -66,13 +56,13 @@ void button() {
String button_number = sCmd.next();
String button_param = sCmd.next();
String viget_name = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String start_state = sCmd.next();
String page_number = sCmd.next();
jsonWrite(optionJson, "button_param" + button_number, button_param);
jsonWrite(configJson, "buttonSet" + button_number, start_state);
jsonWriteStr(optionJson, "button_param" + button_number, button_param);
jsonWriteStr(configJson, "buttonSet" + button_number, start_state);
if (isDigitStr (button_param)) {
pinMode(button_param.toInt(), OUTPUT);
@@ -80,7 +70,7 @@ void button() {
}
if (button_param == "scenario") {
jsonWrite(configSetup, "scenario", start_state);
jsonWriteStr(configSetup, "scenario", start_state);
Scenario_init();
saveConfig();
}
@@ -98,7 +88,7 @@ void button() {
str = deleteBeforeDelimiter(str, ",");
}
}
createViget (viget_name, page_name, page_number, "vigets/viget.toggle.json", "buttonSet" + button_number);
createWidget (widget_name, page_name, page_number, "widgets/widget.toggle.json", "buttonSet" + button_number);
}
void buttonSet() {
@@ -112,7 +102,7 @@ void buttonSet() {
}
if (button_param == "scenario") {
jsonWrite(configSetup, "scenario", button_state);
jsonWriteStr(configSetup, "scenario", button_state);
Scenario_init();
saveConfig();
}
@@ -133,17 +123,34 @@ void buttonSet() {
eventGen ("buttonSet", button_number);
jsonWrite(configJson, "buttonSet" + button_number, button_state);
jsonWriteStr(configJson, "buttonSet" + button_number, button_state);
sendSTATUS("buttonSet" + button_number, button_state);
}
void pinSet() {
void buttonChange() {
String button_number = sCmd.next();
String current_state = jsonRead(configJson, "buttonSet" + 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(configJson, "buttonSet" + button_number, current_state);
sendSTATUS("buttonSet" + 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()));
}
//==================================================================================================================
//==========================================Модуль управления ШИМ===================================================
@@ -152,20 +159,21 @@ void pwm() {
static boolean flag = true;
String pwm_number = sCmd.next();
String pwm_pin = sCmd.next();
String viget_name = sCmd.next();
viget_name.replace("#", " ");
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();
jsonWrite(optionJson, "pwm_pin" + pwm_number, pwm_pin);
jsonWriteStr(optionJson, "pwm_pin" + pwm_number, pwm_pin);
pinMode(pwm_pin_int, INPUT);
analogWrite(pwm_pin_int, start_state.toInt());
jsonWrite(configJson, "pwmSet" + pwm_number, start_state);
//analogWriteFreq(32000);
jsonWriteStr(configJson, "pwmSet" + pwm_number, start_state);
createViget (viget_name, page_name, page_number, "vigets/viget.range.json", "pwmSet" + pwm_number);
createWidget (widget_name, page_name, page_number, "widgets/widget.range.json", "pwmSet" + pwm_number);
}
void pwmSet() {
@@ -179,7 +187,7 @@ void pwmSet() {
eventGen ("pwmSet", pwm_number);
jsonWrite(configJson, "pwmSet" + pwm_number, pwm_state);
jsonWriteStr(configJson, "pwmSet" + pwm_number, pwm_state);
sendSTATUS("pwmSet" + pwm_number, pwm_state);
}
//==================================================================================================================
@@ -205,13 +213,13 @@ void handleButton() {
eventGen ("switchSet", String(switch_number));
jsonWrite(configJson, "switchSet" + String(switch_number), "1");
jsonWriteStr(configJson, "switchSet" + String(switch_number), "1");
}
if (buttons[switch_number].rose()) {
eventGen ("switchSet", String(switch_number));
jsonWrite(configJson, "switchSet" + String(switch_number), "0");
jsonWriteStr(configJson, "switchSet" + String(switch_number), "0");
}
}
switch_number++;
@@ -223,19 +231,19 @@ void handleButton() {
void inputDigit() {
String value_name = sCmd.next();
String number = value_name.substring(5);
String viget_name = sCmd.next();
viget_name.replace("#", " ");
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();
jsonWrite(configJson, "digitSet" + number, start_state);
createViget (viget_name, page_name, page_number, "vigets/viget.inputNum.json", "digitSet" + number);
jsonWriteStr(configJson, "digitSet" + number, start_state);
createWidget (widget_name, page_name, page_number, "widgets/widget.inputNum.json", "digitSet" + number);
}
void digitSet() {
String number = sCmd.next();
String value = sCmd.next();
jsonWrite(configJson, "digitSet" + number, value);
jsonWriteStr(configJson, "digitSet" + number, value);
sendSTATUS("digitSet" + number, value);
}
//=====================================================================================================================================
@@ -243,36 +251,43 @@ void digitSet() {
void inputTime() {
String value_name = sCmd.next();
String number = value_name.substring(4);
String viget_name = sCmd.next();
viget_name.replace("#", " ");
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();
start_state.replace(":", ".");
jsonWrite(configJson, "timeSet" + number, start_state);
start_state.replace(".", ":");
createViget (viget_name, page_name, page_number, "vigets/viget.inputTime.json", "timeSet" + number);
jsonWriteStr(configJson, "timeSet" + number, start_state);
createWidget (widget_name, page_name, page_number, "widgets/widget.inputTime.json", "timeSet" + number);
}
void timeSet() {
String number = sCmd.next();
String value = sCmd.next();
value.replace(":", ".");
jsonWrite(configJson, "timeSet" + number, value);
value.replace(".", ":");
jsonWriteStr(configJson, "timeSet" + number, value);
sendSTATUS("timeSet" + number, value);
}
void handle_time_init() {
ts.add(TIME, 1000, [&](void*) {
String tmp = GetTime();
tmp.replace(":", "-");
jsonWriteStr(configJson, "timenowSet", tmp);
eventGen ("timenowSet", "");
}, nullptr, true);
}
//=====================================================================================================================================
//=========================================Добавление текстового виджета============================================================
void text() {
String number = sCmd.next();
String viget_name = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String page_number = sCmd.next();
createViget (viget_name, page_name, page_number, "vigets/viget.anydata.json", "textSet" + number);
createWidget (widget_name, page_name, page_number, "widgets/widget.anyData.json", "textSet" + number);
}
@@ -284,61 +299,109 @@ void textSet() {
if (text.indexOf("-time") >= 0) {
text.replace("-time", "");
text.replace("#", " ");
String time = GetTime();
time.replace(":", ".");
text = GetDataDigital() + " " + time + " " + text;
text = text + " " + GetDataDigital() + " " + time;
}
jsonWrite(configJson, "textSet" + number, text);
jsonWriteStr(configJson, "textSet" + number, text);
sendSTATUS("textSet" + number, text);
}
void handle_time_init() {
ts.add(TIME, 1000, [&](void*) {
//=====================================================================================================================================
//=========================================Модуль шагового мотора======================================================================
String tmp = GetTimeWOsec();
tmp.replace(":", ".");
jsonWrite(configJson, "timenowSet", tmp);
eventGen ("timenowSet", "");
//stepper 1 12 13
void stepper() {
String stepper_number = sCmd.next();
String pin_step = sCmd.next();
String pin_dir = sCmd.next();
}, nullptr, true);
jsonWriteStr(optionJson, "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(optionJson, "steps" + stepper_number, steps);
String stepper_speed = sCmd.next();
String pin_step = selectToMarker (jsonRead(optionJson, "stepper" + stepper_number), " ");
String pin_dir = deleteBeforeDelimiter (jsonRead(optionJson, "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(jsonReadtoInt(optionJson, "steps1") * 2);
static int count;
count++;
String pin_step = selectToMarker (jsonRead(optionJson, "stepper1"), " ");
digitalWrite(pin_step.toInt(), !digitalRead(pin_step.toInt()));
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(jsonReadtoInt(optionJson, "steps2") * 2);
static int count;
count++;
String pin_step = selectToMarker (jsonRead(optionJson, "stepper2"), " ");
digitalWrite(pin_step.toInt(), !digitalRead(pin_step.toInt()));
if (count > steps_int) {
digitalWrite(pin_step.toInt(), LOW);
ts.remove(STEPPER2);
count = 0;
}
}, nullptr, true);
}
}
//====================================================================================================================================================
/*
void inputText() {
String number = sCmd.next();
String viget_name = sCmd.next();
viget_name.replace("#", " ");
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();
jsonWrite(configJson, "inputTextSet" + number, start_state);
createViget (viget_name, page_name, page_number, "vigets/viget.inputText.json", "inputTextSet" + number);
jsonWriteStr(configJson, "inputTextSet" + number, start_state);
createWidget (widget_name, page_name, page_number, "widgets/widget.inputText.json", "inputTextSet" + number);
}
void inputTextSet() {
String number = sCmd.next();
String value = sCmd.next();
jsonWrite(configJson, "inputTextSet" + number, value);
jsonWriteStr(configJson, "inputTextSet" + number, value);
sendSTATUS("inputTextSet" + number, value);
}
void inputTime() {
String number = sCmd.next();
String viget_name = sCmd.next();
viget_name.replace("#", " ");
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();
jsonWrite(configJson, "inputTimeSet" + number, start_state);
createViget (viget_name, page_name, page_number, "vigets/viget.inputTime.json", "inputTimeSet" + number);
jsonWriteStr(configJson, "inputTimeSet" + number, start_state);
createWidget (widget_name, page_name, page_number, "widgets/widget.inputTime.json", "inputTimeSet" + number);
}
void inputTimeSet() {
String number = sCmd.next();
String value = sCmd.next();
value.replace(":", ".");
jsonWrite(configJson, "inputTimeSet" + number, value);
jsonWriteStr(configJson, "inputTimeSet" + number, value);
value.replace(".", ":");
sendSTATUS("inputTimeSet" + number, value);
}
@@ -346,19 +409,19 @@ void handle_time_init() {
void inputDate() {
String number = sCmd.next();
String viget_name = sCmd.next();
viget_name.replace("#", " ");
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();
jsonWrite(configJson, "inputDateSet" + number, start_state);
createViget (viget_name, page_name, page_number, "vigets/viget.inputDate.json", "inputDateSet" + number);
jsonWriteStr(configJson, "inputDateSet" + number, start_state);
createWidget (widget_name, page_name, page_number, "widgets/widget.inputDate.json", "inputDateSet" + number);
}
void inputDateSet() {
String number = sCmd.next();
String value = sCmd.next();
jsonWrite(configJson, "inputDateSet" + number, value);
jsonWriteStr(configJson, "inputDateSet" + number, value);
sendSTATUS("inputDateSet" + number, value);
}
*/
@@ -369,7 +432,7 @@ void mqttOrderSend() {
String id = sCmd.next();
String order = sCmd.next();
String all_line = prefix + "/" + id + "/order";
String all_line = jsonRead(configSetup, "mqttPrefix") + "/" + id + "/order";
//Serial.print(all_line);
//Serial.print("->");
//Serial.println(order);
@@ -400,29 +463,11 @@ void handleCMD_loop() {
}
}
//=============================выполнение команд (через период) по очереди из строки order=======================================
/*void handleCMD_ticker() {
ts.add(CMD, CMD_update_int, [&](void*) {
if (!busy) {
if (order_ticker != "") {
String tmp = selectToMarker(order_ticker, ","); //выделяем из страки order первую команду pus title body
if (tmp != "no_command") sCmd.readStr(tmp); //выполняем первую команду
Serial.println("order_ticker => " + order_ticker);
order_ticker = deleteBeforeDelimiter(order_ticker, ","); //осекаем выполненную команду
}
}
}, nullptr, true);
}*/
//=======================================================================================================================================
//=======================================================================================================================================
void txtExecution(String file) {
String command_all = readFile(file, 2048) + "\r\n"; //2048
String command_all = readFile(file, 2048) + "\r\n";
command_all.replace("\r\n", "\n");
command_all.replace("\r", "\n");
@@ -430,153 +475,23 @@ void txtExecution(String file) {
while (command_all.length() != 0) {
String tmp = selectToMarker (command_all, "\n");
//if (tmp.indexOf("//") < 0)
sCmd.readStr(tmp);
command_all = deleteBeforeDelimiter(command_all, "\n");
}
command_all = "";
}
void stringExecution(String str) {
String command_all = str + "\r\n"; //"\r\n"
str = str + "\r\n";
command_all.replace("\r\n", "\n");
command_all.replace("\r", "\n");
str.replace("\r\n", "\n");
str.replace("\r", "\n");
while (command_all.length() != 0) {
while (str.length() != 0) {
String tmp = selectToMarker (command_all, "\n");
//if (tmp.indexOf("//") < 0)
String tmp = selectToMarker (str, "\n");
sCmd.readStr(tmp);
command_all = deleteBeforeDelimiter(command_all, "\n");
str = deleteBeforeDelimiter(str, "\n");
}
}
//======================================================================================================================
//===============================================Создание виджетов=======================================================
void createViget (String viget_name, String page_name, String page_number, String file, String topic) {
String viget;
viget = readFile(file, 1024);
if (viget == "Failed") return;
if (viget == "Large") return;
viget_name.replace("#", " ");
page_name.replace("#", " ");
jsonWrite(viget, "page", page_name);
jsonWrite(viget, "order", page_number);
jsonWrite(viget, "descr", viget_name);
jsonWrite(viget, "topic", prex + "/" + topic);
all_vigets += viget + "\r\n";
viget = "";
}
/*
void createViget (String viget_name, String page_name, String page_number, String file, String topic, String key, String value) {
String viget;
viget = readFile(file, 1024);
if (viget == "Failed") return;
if (viget == "Large") return;
viget_name.replace("#", " ");
page_name.replace("#", " ");
value.replace("#", " ");
viget = vidgetConfigWrite(viget, key, value);
jsonWrite(viget, "page", page_name);
jsonWrite(viget, "pageId", page_number);
jsonWrite(viget, "descr", viget_name);
jsonWrite(viget, "topic", prex + "/" + topic);
all_vigets += viget + "\r\n";
viget = "";
}
void createViget (String viget_name, String page_name, String page_number, String file, String topic, String key, String value, String key2, String value2) {
String viget;
viget = readFile(file, 1024);
if (viget == "Failed") return;
if (viget == "Large") return;
viget_name.replace("#", " ");
page_name.replace("#", " ");
value.replace("#", " ");
viget = vidgetConfigWrite(viget, key, value);
viget = vidgetConfigWrite(viget, key2, value2);
jsonWrite(viget, "page", page_name);
jsonWrite(viget, "pageId", page_number);
jsonWrite(viget, "descr", viget_name);
jsonWrite(viget, "topic", prex + "/" + topic);
all_vigets += viget + "\r\n";
viget = "";
}
*/
String vidgetConfigWrite(String viget, String key, String value) {
if (viget == "") return "";
if (viget == "{}") return "";
int psn1 = viget.indexOf("{");
if (psn1 != -1) {
psn1 = viget.indexOf("{", psn1 + 1);
if (psn1 != -1) {
int psn2 = viget.indexOf("}", psn1);
String WigetConfig = viget.substring(psn1, psn2) + "}";
jsonWrite(WigetConfig, key, value);
String part1 = viget.substring(0, psn1);
viget = part1 + WigetConfig + "}";
return viget;
}
}
}
//============разное
/*
void delAlert() {
String alert_id = sCmd.next();
delViget(alert_id);
sendAllWigets();
}
void delViget(String text_in_viget) {
String viget = all_vigets;
while (viget.length() != 0) {
String tmp = selectToMarkerPlus (viget, "\r\n", 2);
if (tmp.indexOf(text_in_viget) > 0) {
all_vigets.replace(tmp, "");
//Serial.println(all_vigets);
viget = deleteBeforeDelimiter(viget, "\r\n");
} else {
viget = deleteBeforeDelimiter(viget, "\r\n");
}
}
}
*/

BIN
ESP8266FS-0.5.0.zip Normal file

Binary file not shown.

Binary file not shown.

38
FS.ino Normal file
View File

@@ -0,0 +1,38 @@
void File_system_init() {
Serial.begin(115200);
//Serial.setDebugOutput(true);
Serial.println("--------------started----------------");
//--------------------------------------------------------------
SPIFFS.begin();
configSetup = readFile("config.json", 4096);
configSetup.replace(" ", "");
configSetup.replace("\r\n", "");
Serial.println(configSetup);
jsonWriteStr(configJson, "name", jsonRead(configSetup, "name"));
jsonWriteStr(configJson, "lang", jsonRead(configSetup, "lang"));
#ifdef ESP32
uint32_t chipID_u = ESP.getEfuseMac();
chipID = String(chipID_u);
jsonWriteStr(configSetup, "chipID", chipID);
#endif
#ifdef ESP8266
chipID = String( ESP.getChipId() ) + "-" + String(ESP.getFlashChipId());
jsonWriteStr(configSetup, "chipID", chipID);
Serial.setDebugOutput(0);
#endif
jsonWriteStr(configSetup, "firmware_version", firmware_version);
prex = jsonRead(configSetup, "mqttPrefix") + "/" + chipID;
Serial.println(chipID);
}
void get_esp_info() {
}

199
Init.ino
View File

@@ -1,29 +1,33 @@
void All_init() {
server.on("/all_modules_init", HTTP_GET, [](AsyncWebServerRequest * request) {
Device_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
});
server.on("/scenario", HTTP_GET, [](AsyncWebServerRequest * request) {
if (request->hasArg("status")) {
jsonWrite(configSetup, "scenario", request->getParam("status")->value());
server.on("/init", HTTP_GET, [](AsyncWebServerRequest * request) {
String value;
if (request->hasArg("arg")) {
value = request->getParam("arg")->value();
}
if (value == "0") {
jsonWriteStr(configSetup, "scenario", value);
saveConfig();
Scenario_init();
}
if (value == "1") {
jsonWriteStr(configSetup, "scenario", value);
saveConfig();
Scenario_init();
}
if (value == "2") {
Device_init();
}
if (value == "3") {
clean_log_date();
}
if (value == "4") {
Scenario_init();
}
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
});
server.on("/cleanlog", HTTP_GET, [](AsyncWebServerRequest * request) {
SPIFFS.remove("/log.analog.txt");
SPIFFS.remove("/log.dallas.txt");
SPIFFS.remove("/log.level.txt");
SPIFFS.remove("/log.ph.txt");
SPIFFS.remove("/log.txt");
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
});
prsets_init();
Device_init();
Scenario_init();
Timer_countdown_init();
@@ -31,42 +35,179 @@ void All_init() {
void Device_init() {
//SENSORS-SECTION
ts.remove(ANALOG_);
ts.remove(LEVEL);
ts.remove(DALLAS);
ts.remove(DHTT);
ts.remove(DHTH);
//================
ts.remove(DHTC);
ts.remove(DHTP);
ts.remove(DHTD);
ts.remove(STEPPER1);
ts.remove(STEPPER2);
all_vigets = "";
txtExecution("firmware.config.txt");
#ifdef layout_in_ram
all_widgets = "";
#else
SPIFFS.remove("/layout.txt");
#endif
txtExecution("firmware.c.txt");
//outcoming_date();
}
//-------------------------------сценарии-----------------------------------------------------
void Scenario_init() {
if (jsonRead(configSetup, "scenario") == "1") {
scenario = readFile("firmware.scenario.txt", 2048);
scenario = readFile("firmware.s.txt", 2048);
}
}
void prsets_init() {
server.on("/preset", HTTP_GET, [](AsyncWebServerRequest * request) {
String value;
if (request->hasArg("arg")) {
value = request->getParam("arg")->value();
}
if (value == "1") {
writeFile("firmware.c.txt", readFile("configs/relay.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/relay.s.txt", 2048));
}
if (value == "2") {
writeFile("firmware.c.txt", readFile("configs/relay_t.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/relay_t.s.txt", 2048));
}
if (value == "3") {
writeFile("firmware.c.txt", readFile("configs/relay_c.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/relay_c.s.txt", 2048));
}
if (value == "4") {
writeFile("firmware.c.txt", readFile("configs/relay_s.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/relay_s.s.txt", 2048));
}
if (value == "5") {
writeFile("firmware.c.txt", readFile("configs/relay_sw.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/relay_sw.s.txt", 2048));
}
if (value == "6") {
writeFile("firmware.c.txt", readFile("configs/relay_br.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/relay_br.s.txt", 2048));
}
if (value == "7") {
writeFile("firmware.c.txt", readFile("configs/relay_sr.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/relay_sr.s.txt", 2048));
}
if (value == "8") {
writeFile("firmware.c.txt", readFile("configs/pwm.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/pwm.s.txt", 2048));
}
if (value == "9") {
writeFile("firmware.c.txt", readFile("configs/dht11.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/dht11.s.txt", 2048));
}
if (value == "10") {
writeFile("firmware.c.txt", readFile("configs/dht22.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/dht22.s.txt", 2048));
}
if (value == "11") {
writeFile("firmware.c.txt", readFile("configs/analog.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/analog.s.txt", 2048));
}
if (value == "12") {
writeFile("firmware.c.txt", readFile("configs/dallas.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/dallas.s.txt", 2048));
}
if (value == "13") {
writeFile("firmware.c.txt", readFile("configs/termostat.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/termostat.s.txt", 2048));
}
if (value == "14") {
writeFile("firmware.c.txt", readFile("configs/level.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/level.s.txt", 2048));
}
if (value == "15") {
writeFile("firmware.c.txt", readFile("configs/moution_r.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/moution_r.s.txt", 2048));
}
if (value == "16") {
writeFile("firmware.c.txt", readFile("configs/moution_s.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/moution_s.s.txt", 2048));
}
if (value == "17") {
writeFile("firmware.c.txt", readFile("configs/stepper.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/stepper.s.txt", 2048));
}
if (value == "18") {
writeFile("firmware.c.txt", readFile("configs/firmware.c.txt", 2048));
writeFile("firmware.s.txt", readFile("configs/firmware.s.txt", 2048));
}
Device_init();
Scenario_init();
request->redirect("/?configuration");
});
}
void up_time() {
uint32_t ss = millis() / 1000;
uint32_t mm = ss / 60;
uint32_t hh = mm / 60;
uint32_t dd = hh / 24;
String out = "";
if (ss != 0) {
out = "[i] uptime = " + String(ss) + " sec";
jsonWriteStr(configJson, "uptime", String(ss) + " sec");
}
if (mm != 0) {
Serial.println(String(mm) + " min");
jsonWrite(configJson, "uptime", String(mm) + " min");
out = "[i] uptime = " + String(mm) + " min";
jsonWriteStr(configJson, "uptime", String(mm) + " min");
}
if (hh != 0) {
Serial.println(String(hh) + " hours");
jsonWrite(configJson, "uptime", String(hh) + " hours");
out = "[i] uptime = " + String(hh) + " hours";
jsonWriteStr(configJson, "uptime", String(hh) + " hours");
}
if (dd != 0) {
Serial.println(String(dd) + " days");
jsonWrite(configJson, "uptime", String(dd) + " days");
out = "[i] uptime = " + String(dd) + " days";
jsonWriteStr(configJson, "uptime", String(dd) + " days");
}
Serial.println(out + ", mqtt_lost_error: " + String(mqtt_lost_error) + ", wifi_lost_error: " + String(wifi_lost_error));
}
void statistics_init() {
ts.add(STATISTICS, statistics_update, [&](void*) {
statistics();
}, nullptr, true);
}
void statistics() {
if (WiFi.status() == WL_CONNECTED) {
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 += "Unknown";
#endif
urls += "&";
//-----------------------------------------------------------------
urls += "firm version: " + firmware_version + " " + DATE_COMPILING + " " + TIME_COMPILING;
//-----------------------------------------------------------------
String stat = getURL(urls);
//Serial.println(stat);
}
}

171
Logging.ino Normal file
View File

@@ -0,0 +1,171 @@
//===============================================Логирование============================================================
void logging() {
static boolean flag = true;
String sensor_name = sCmd.next();
String period_min = sCmd.next();
String maxCount = sCmd.next();
String optimozation = sCmd.next();
String widget_name = sCmd.next();
widget_name.replace("#", " ");
String page_name = sCmd.next();
String page_number = sCmd.next();
if (optimozation == "fast") chart_data_in_solid_array = true;
if (optimozation == "slow") chart_data_in_solid_array = false;
if (sensor_name == "analog") jsonWriteStr(optionJson, "analog_logging_count", maxCount);
if (sensor_name == "level") jsonWriteStr(optionJson, "level_logging_count", maxCount);
if (sensor_name == "dallas") jsonWriteStr(optionJson, "dallas_logging_count", maxCount);
if (sensor_name == "dhtT") jsonWriteStr(optionJson, "dhtT_logging_count", maxCount);
if (sensor_name == "dhtH") jsonWriteStr(optionJson, "dhtH_logging_count", maxCount);
if (sensor_name == "analog") createChart (widget_name, page_name, page_number, "widgets/widget.chart.json", "loganalog", maxCount);
if (sensor_name == "level") createChart (widget_name, page_name, page_number, "widgets/widget.chart.json", "loglevel", maxCount);
if (sensor_name == "dallas") createChart (widget_name, page_name, page_number, "widgets/widget.chart.json", "logdallas", maxCount);
if (sensor_name == "dhtT") createChart (widget_name, page_name, page_number, "widgets/widget.chart.json", "logdhtT", maxCount);
if (sensor_name == "dhtH") createChart (widget_name, page_name, page_number, "widgets/widget.chart.json", "logdhtH", maxCount);
if (sensor_name == "analog") {
flagLoggingAnalog = true;
ts.remove(ANALOG_LOG);
ts.add(ANALOG_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
deleteOldDate("log.analog.txt", jsonReadtoInt(optionJson, "analog_logging_count"), jsonRead(configJson, "analog"));
}, nullptr, true);
}
if (sensor_name == "level") {
flagLoggingLevel = true;
ts.remove(LEVEL_LOG);
ts.add(LEVEL_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
deleteOldDate("log.level.txt", jsonReadtoInt(optionJson, "level_logging_count"), jsonRead(configJson, "level"));
}, nullptr, true);
}
if (sensor_name == "dallas") {
flagLoggingDallas = true;
ts.remove(DALLAS_LOG);
ts.add(DALLAS_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
deleteOldDate("log.dallas.txt", jsonReadtoInt(optionJson, "dallas_logging_count"), jsonRead(configJson, "dallas"));
}, nullptr, true);
}
if (sensor_name == "dhtT") {
flagLoggingdhtT = true;
ts.remove(dhtT_LOG);
ts.add(dhtT_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
deleteOldDate("log.dhtT.txt", jsonReadtoInt(optionJson, "dhtT_logging_count"), jsonRead(configJson, "dhtT"));
}, nullptr, true);
}
if (sensor_name == "dhtH") {
flagLoggingdhtH = true;
ts.remove(dhtH_LOG);
ts.add(dhtH_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
deleteOldDate("log.dhtH.txt", jsonReadtoInt(optionJson, "dhtH_logging_count"), jsonRead(configJson, "dhtH"));
}, nullptr, true);
}
}
//=========================================Удаление стрых данных и запись новых==================================================================
void deleteOldDate(String file, int seted_number_of_lines, String date_to_add) {
String log_date = readFile(file, 5000);
int current_number_of_lines = count(log_date, "\r\n");
Serial.println("=====> [i] in log file " + file + " " + current_number_of_lines + " lines");
if (current_number_of_lines > seted_number_of_lines + 1) {
SPIFFS.remove("/" + file);
current_number_of_lines = 0;
}
if (current_number_of_lines == 0) {
SPIFFS.remove("/" + file);
current_number_of_lines = 0;
}
if (current_number_of_lines > seted_number_of_lines) {
log_date = deleteBeforeDelimiter(log_date, "\r\n");
if (GetTimeUnix() != "failed") {
log_date += GetTimeUnix() + " " + date_to_add + "\r\n";
writeFile(file, log_date);
}
} else {
if (GetTimeUnix() != "failed") {
addFile(file, GetTimeUnix() + " " + date_to_add);
}
}
log_date = "";
}
//=========================================Выбор какие данные отправлять==================================================================
void choose_log_date_and_send() {
if (flagLoggingAnalog) sendLogData("log.analog.txt", "loganalog", chart_data_in_solid_array);
if (flagLoggingLevel) sendLogData("log.level.txt", "loglevel", chart_data_in_solid_array);
if (flagLoggingDallas) sendLogData("log.dallas.txt", "logdallas", chart_data_in_solid_array);
if (flagLoggingdhtT) sendLogData("log.dhtT.txt", "logdhtT", chart_data_in_solid_array);
if (flagLoggingdhtH) sendLogData("log.dhtH.txt", "logdhtH", chart_data_in_solid_array);
}
//=========================================Отправка данных===================================================================================
void sendLogData(String file, String topic, boolean type) {
if (type) {
//----------------------------------------------
String log_date = readFile(file, 5000);
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() != 0) {
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 + "]}";
Serial.println(json_array);
sendCHART(topic, json_array);
json_array = "";
getMemoryLoad("[i] after send log date");
//----------------------------------------------
} else {
//----------------------------------------------
File configFile = SPIFFS.open("/" + file, "r");
if (!configFile) {
return;
}
configFile.seek(0, SeekSet); //поставим курсор в начало файла
while (configFile.position() != configFile.size()) {
String tmp = configFile.readStringUntil('\r\n');
String unix_time = selectToMarker (tmp, " ");
String value = deleteBeforeDelimiter(tmp, " ");
String final_line = "{\"status\":{\"x\":" + unix_time + ",\"y1\":" + value + "}}";
//Serial.println(final_line);
sendCHART(topic, final_line);
}
getMemoryLoad("[i] after send log date");
}
//----------------------------------------------
}
//=========================================Очистка данных===================================================================================
void clean_log_date() {
SPIFFS.remove("/log.analog.txt");
SPIFFS.remove("/log.level.txt");
SPIFFS.remove("/log.dallas.txt");
SPIFFS.remove("/log.dhtT.txt");
SPIFFS.remove("/log.dhtH.txt");
}

View File

@@ -69,7 +69,7 @@ void handleScenario() {
}
String tmp2 = jsonRead(optionJson, "scenario_status"); //читаем файл событий
tmp2 = deleteBeforeDelimiter(tmp2, ","); //удаляем выполненное событие
jsonWrite(optionJson, "scenario_status", tmp2); //записываем обновленный файл событий
jsonWriteStr(optionJson, "scenario_status", tmp2); //записываем обновленный файл событий
i = 0;
}
}
@@ -80,7 +80,7 @@ void eventGen (String event_name, String number) { //событие выгля
if (jsonRead(configSetup, "scenario") == "1") {
String tmp = jsonRead(optionJson, "scenario_status") ; //генерирование события
//Serial.println(event_name);
jsonWrite(optionJson, "scenario_status", tmp + event_name + number + ",");
jsonWriteStr(optionJson, "scenario_status", tmp + event_name + number + ",");
}
}

View File

@@ -2,7 +2,7 @@
//=========================================Модуль аналогового сенсора============================================================
void analog() {
String pin = sCmd.next();
String viget_name = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String analog_start = sCmd.next();
@@ -10,32 +10,32 @@ void analog() {
String analog_start_out = sCmd.next();
String analog_end_out = sCmd.next();
String page_number = sCmd.next();
jsonWrite(optionJson, "analog_start", analog_start);
jsonWrite(optionJson, "analog_end", analog_end);
jsonWrite(optionJson, "analog_start_out", analog_start_out);
jsonWrite(optionJson, "analog_end_out", analog_end_out);
choose_viget_and_create(viget_name, page_name, page_number, type, "analog");
jsonWriteStr(optionJson, "analog_start", analog_start);
jsonWriteStr(optionJson, "analog_end", analog_end);
jsonWriteStr(optionJson, "analog_start_out", analog_start_out);
jsonWriteStr(optionJson, "analog_end_out", analog_end_out);
choose_widget_and_create(widget_name, page_name, page_number, type, "analog");
ts.add(ANALOG_, analog_update_int, [&](void*) {
static int analog_old;
#ifdef ESP32
//int pin_int = pin.toInt();
int analog_in;// = analogRead(pin_int);
int analog_in = analogRead(34);
#endif
#ifdef ESP8266
int analog_in = analogRead(A0);
#endif
jsonWrite(configJson, "analog_in", analog_in);
jsonWriteInt(configJson, "analog_in", analog_in);
int analog = map(analog_in,
jsonReadtoInt(optionJson, "analog_start") ,
jsonReadtoInt(optionJson, "analog_end"),
jsonReadtoInt(optionJson, "analog_start_out"),
jsonReadtoInt(optionJson, "analog_end_out"));
jsonWrite(configJson, "analog", analog);
jsonWriteInt(configJson, "analog", analog);
// if (analog_old != analog) {
eventGen ("analog", "");
sendSTATUS("analog", String(analog));
if (client.connected()) {
Serial.println("[i] sensor analog send date " + String(analog));
Serial.println("[i] sensor 'analog' send date " + String(analog));
}
// }
analog_old = analog;
@@ -45,17 +45,17 @@ void analog() {
//===================================================================================================================================
//=========================================Модуль измерения уровня в баке============================================================
void level() {
String viget_name = 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();
jsonWrite(optionJson, "empty_level", empty_level);
jsonWrite(optionJson, "full_level", full_level);
jsonWriteStr(optionJson, "empty_level", empty_level);
jsonWriteStr(optionJson, "full_level", full_level);
pinMode(14, OUTPUT);
pinMode(12, INPUT);
choose_viget_and_create(viget_name, page_name, page_number, type, "level");
choose_widget_and_create(widget_name, page_name, page_number, type, "level");
ts.add(LEVEL, tank_level_shooting_interval, [&](void*) {
long duration_;
int distance_cm;
@@ -73,16 +73,16 @@ void level() {
counter++;
if (counter > tank_level_times_to_send) {
counter = 0;
jsonWrite(configJson, "level_in", distance_cm);
jsonWriteInt(configJson, "level_in", distance_cm);
level = map(distance_cm,
jsonReadtoInt(optionJson, "empty_level"),
jsonReadtoInt(optionJson, "full_level"), 0, 100);
//jsonWrite(configJson, "level", level);
jsonWriteInt(configJson, "level", level);
//if (level_old != level) {
eventGen ("level", "");
sendSTATUS("level", String(level));
if (client.connected()) {
Serial.println("[i] sensor tank level send date " + String(level));
Serial.println("[i] sensor tank 'level' send date " + String(level));
}
//}
level_old = level;
@@ -94,7 +94,7 @@ void level() {
//=========================================Модуль температурного сенсора ds18b20============================================================
void dallas() {
String pin = sCmd.next();
String viget_name = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String page_number = sCmd.next();
@@ -102,18 +102,18 @@ void dallas() {
sensors.setOneWire(oneWire);
sensors.begin();
sensors.setResolution(12);
choose_viget_and_create(viget_name, page_name, page_number, type, "dallas");
choose_widget_and_create(widget_name, page_name, page_number, type, "dallas");
ts.add(DALLAS, temp_update_int, [&](void*) {
float temp = 0;
static float temp_old;
sensors.requestTemperatures();
temp = sensors.getTempCByIndex(0);
jsonWrite(configJson, "dallas", String(temp));
jsonWriteStr(configJson, "dallas", String(temp));
//if (temp_old != temp) {
eventGen ("dallas", "");
sendSTATUS("dallas", String(temp));
if (client.connected()) {
Serial.println("[i] sensor dallas send date " + String(temp));
Serial.println("[i] sensor 'dallas' send date " + String(temp));
}
//}
temp_old = temp;
@@ -126,7 +126,7 @@ void dallas() {
void dhtT() {
String sensor_type = sCmd.next();
String pin = sCmd.next();
String viget_name = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String page_number = sCmd.next();
@@ -136,20 +136,29 @@ void dhtT() {
if (sensor_type == "DHT22") {
dht.setup(pin.toInt(), DHTesp::DHT22);
}
choose_viget_and_create(viget_name, page_name, page_number, type, "dhtT");
ts.add(DHTT, dhtT_update_int + dht.getMinimumSamplingPeriod(), [&](void*) {
choose_widget_and_create(widget_name, page_name, page_number, type, "dhtT");
ts.add(DHTT, dhtT_update_int, [&](void*) { //dht.getMinimumSamplingPeriod()
float value = 0;
static float value_old;
static int counter;
if (dht.getStatus() != 0 && counter < 5) {
sendSTATUS("dhtT", String(dht.getStatusString()));
counter++;
} else {
counter = 0;
value = dht.getTemperature();
jsonWrite(configJson, "dhtT", String(value));
//if (value_old != value) {
if (String(value) != "nan") {
eventGen ("dhtT", "");
jsonWriteStr(configJson, "dhtT", String(value));
sendSTATUS("dhtT", String(value));
if (client.connected()) {
Serial.println("[i] sensor dhtT send date " + String(value));
Serial.println("[i] sensor 'dhtT' send date " + String(value));
}
//}
}
value_old = value;
}
}, nullptr, true);
}
@@ -157,7 +166,7 @@ void dhtT() {
void dhtH() {
String sensor_type = sCmd.next();
String pin = sCmd.next();
String viget_name = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String type = sCmd.next();
String page_number = sCmd.next();
@@ -167,38 +176,50 @@ void dhtH() {
if (sensor_type == "DHT22") {
dht.setup(pin.toInt(), DHTesp::DHT22);
}
choose_viget_and_create(viget_name, page_name, page_number, type, "dhtH");
ts.add(DHTH, dhtH_update_int + dht.getMinimumSamplingPeriod(), [&](void*) {
choose_widget_and_create(widget_name, page_name, page_number, type, "dhtH");
ts.add(DHTH, dhtH_update_int , [&](void*) { //dht.getMinimumSamplingPeriod()
int value = 0;
static int value_old;
static int counter;
if (dht.getStatus() != 0 && counter < 5) {
sendSTATUS("dhtH", String(dht.getStatusString()));
counter++;
} else {
counter = 0;
value = dht.getHumidity();
jsonWrite(configJson, "dhtH", String(value));
if (String(value) != "nan" || value <= 100 || value >= 0) {
//if (value_old != value) {
eventGen ("dhtH", "");
jsonWriteStr(configJson, "dhtH", String(value));
sendSTATUS("dhtH", String(value));
if (client.connected()) {
Serial.println("[i] sensor dhtH send date " + String(value));
Serial.println("[i] sensor 'dhtH' send date " + String(value));
}
//}
}
value_old = value;
}
}, nullptr, true);
}
void dhtPerception() {
String viget_name = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String page_number = sCmd.next();
choose_viget_and_create(viget_name, page_name, page_number, "any-data", "dhtPerception");
ts.add(DHTP, dhtPerception_update_int, [&](void*) {
choose_widget_and_create(widget_name, page_name, page_number, "any-data", "dhtPerception");
ts.add(DHTP, dht_calculation_update_int, [&](void*) {
byte value;
ComfortState cf;
value = dht.computePerception(jsonRead(configJson, "dhtT").toFloat(), jsonRead(configJson, "dhtH").toInt(), false);
if (dht.getStatus() != 0) {
sendSTATUS("dhtPerception", String(dht.getStatusString()));
} else {
value = dht.computePerception(jsonRead(configJson, "dhtT").toFloat(), jsonRead(configJson, "dhtH").toFloat(), false);
String final_line = perception(value);
jsonWrite(configJson, "dhtPerception", final_line);
jsonWriteStr(configJson, "dhtPerception", final_line);
eventGen ("dhtPerception", "");
sendSTATUS("dhtPerception", final_line);
if (client.connected()) {
Serial.println("[i] sensor dhtPerception send date " + final_line);
Serial.println("[i] sensor 'dhtPerception' send date " + final_line);
}
}
}, nullptr, true);
}
@@ -214,16 +235,18 @@ String perception(byte value) {
if (value == 7) return "Сильно неудобно, полный звиздец";
}
void dhtComfort() {
String viget_name = sCmd.next();
String widget_name = sCmd.next();
String page_name = sCmd.next();
String page_number = sCmd.next();
choose_viget_and_create(viget_name, page_name, page_number, "any-data", "dhtComfort");
ts.add(DHTC, dhtComfort_update_int, [&](void*) {
choose_widget_and_create(widget_name, page_name, page_number, "any-data", "dhtComfort");
ts.add(DHTC, dht_calculation_update_int, [&](void*) {
float value;
ComfortState cf;
value = dht.getComfortRatio(cf, jsonRead(configJson, "dhtT").toFloat(), jsonRead(configJson, "dhtH").toInt(), false);
if (dht.getStatus() != 0) {
sendSTATUS("dhtComfort", String(dht.getStatusString()));
} else {
value = dht.getComfortRatio(cf, jsonRead(configJson, "dhtT").toFloat(), jsonRead(configJson, "dhtH").toFloat(), false);
String comfortStatus;
switch (cf) {
case Comfort_OK:
@@ -258,143 +281,43 @@ void dhtComfort() {
break;
};
String final_line = comfortStatus;
jsonWrite(configJson, "dhtComfort", final_line);
jsonWriteStr(configJson, "dhtComfort", final_line);
eventGen ("dhtComfort", "");
sendSTATUS("dhtComfort", final_line);
if (client.connected()) {
Serial.println("[i] sensor dhtComfort send date " + final_line);
Serial.println("[i] sensor 'dhtComfort' send date " + final_line);
}
}
}, nullptr, true);
}
void dhtDewPoint() {
String viget_name = sCmd.next();
void dhtDewpoint() {
String widget_name = sCmd.next();
String page_name = sCmd.next();
String page_number = sCmd.next();
choose_viget_and_create(viget_name, page_name, page_number, "any-data", "dhtPerception");
ts.add(DHTP, dhtPerception_update_int, [&](void*) {
byte value;
ComfortState cf;
value = dht.computePerception(jsonRead(configJson, "dhtT").toFloat(), jsonRead(configJson, "dhtH").toInt(), false);
String final_line = perception(value);
jsonWrite(configJson, "dhtPerception", final_line);
eventGen ("dhtPerception", "");
sendSTATUS("dhtPerception", final_line);
choose_widget_and_create(widget_name, page_name, page_number, "any-data", "dhtDewpoint");
ts.add(DHTD, dht_calculation_update_int, [&](void*) {
float value;
if (dht.getStatus() != 0) {
sendSTATUS("dhtDewpoint", String(dht.getStatusString()));
} else {
value = dht.computeDewPoint(jsonRead(configJson, "dhtT").toFloat(), jsonRead(configJson, "dhtH").toFloat(), false);
jsonWriteInt(configJson, "dhtDewpoint", value);
eventGen ("dhtDewpoint", "");
sendSTATUS("dhtDewpoint", String(value));
if (client.connected()) {
Serial.println("[i] sensor dhtPerception send date " + final_line);
Serial.println("[i] sensor 'dhtDewpoint' send date " + String(value));
}
}
}, nullptr, true);
}
void choose_viget_and_create(String viget_name, String page_name, String page_number, String type, String topik) {
if (type == "any-data") createViget (viget_name, page_name, page_number, "vigets/viget.anydata.json", topik);
if (type == "progress-line") createViget (viget_name, page_name, page_number, "vigets/viget.progressL.json", topik);
if (type == "progress-round") createViget (viget_name, page_name, page_number, "vigets/viget.progressR.json", topik);
void choose_widget_and_create(String widget_name, String page_name, String page_number, String type, String topik) {
if (type == "any-data") createWidget (widget_name, page_name, page_number, "widgets/widget.anyData.json", topik);
if (type == "progress-line") createWidget (widget_name, page_name, page_number, "widgets/widget.progLine.json", topik);
if (type == "progress-round") createWidget (widget_name, page_name, page_number, "widgets/widget.progRound.json", topik);
if (type == "fill-gauge") createWidget (widget_name, page_name, page_number, "widgets/widget.fillGauge.json", topik);
}
//======================================================================================================================
//===============================================Логирование============================================================
void logging() {
static boolean flag = true;
String sensor_name = sCmd.next();
String period_min = sCmd.next();
String maxCount = sCmd.next();
String viget_name = sCmd.next();
viget_name.replace("#", " ");
String page_name = sCmd.next();
String page_number = sCmd.next();
if (sensor_name == "analog") jsonWrite(optionJson, "analog_logging_count", maxCount);
if (sensor_name == "level") jsonWrite(optionJson, "level_logging_count", maxCount);
if (sensor_name == "dallas") jsonWrite(optionJson, "dallas_logging_count", maxCount);
if (sensor_name == "ph") jsonWrite(optionJson, "ph_logging_count", maxCount);
/*
if (sensor_name == "analog") createViget (viget_name, page_name, page_number, "vigets/viget.chart.json", "loganalog", "maxCount", maxCount);
if (sensor_name == "level") createViget (viget_name, page_name, page_number, "vigets/viget.chart.json", "loglevel", "maxCount", maxCount);
if (sensor_name == "dallas") createViget (viget_name, page_name, page_number, "vigets/viget.chart.json", "logdallas", "maxCount", maxCount);
if (sensor_name == "ph") createViget (viget_name, page_name, page_number, "vigets/viget.chart.json", "logph", "maxCount", maxCount);
*/
if (sensor_name == "analog") {
flagLoggingAnalog = true;
ts.remove(ANALOG_LOG);
ts.add(ANALOG_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
deleteOldDate("log.analog.txt", jsonReadtoInt(optionJson, "analog_logging_count"), jsonRead(configJson, "analog"), false);
}, nullptr, true);
}
if (sensor_name == "level") {
flagLoggingLevel = true;
ts.remove(LEVEL_LOG);
ts.add(LEVEL_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
deleteOldDate("log.level.txt", jsonReadtoInt(optionJson, "level_logging_count"), jsonRead(configJson, "level"), false);
}, nullptr, true);
}
if (sensor_name == "dallas") {
flagLoggingDallas = true;
ts.remove(DALLAS_LOG);
ts.add(DALLAS_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
deleteOldDate("log.dallas.txt", jsonReadtoInt(optionJson, "dallas_logging_count"), jsonRead(configJson, "dallas"), false);
}, nullptr, true);
}
if (sensor_name == "ph") {
flagLoggingPh = true;
ts.remove(PH_LOG);
ts.add(PH_LOG, period_min.toInt() * 1000 * 60, [&](void*) {
deleteOldDate("log.ph.txt", jsonReadtoInt(optionJson, "ph_logging_count"), jsonRead(configJson, "ph"), false);
}, nullptr, true);
}
}
void deleteOldDate(String file, int seted_number_of_lines, String date_to_add, boolean date_time) {
String current_time;
if (date_time) {
current_time = GetDataDigital() + " " + GetTimeWOsec();
current_time.replace(".", "");
current_time.replace(":", "");
} else {
current_time = "";
}
String log_date = readFile(file, 5000);
getMemoryLoad("[i] after logging procedure");
//предел количества строк 255
log_date.replace("\r\n", "\n");
log_date.replace("\r", "\n");
int current_number_of_lines = count(log_date, "\n");
Serial.println("[i] in log file " + file + " " + current_number_of_lines + " lines");
if (current_number_of_lines > seted_number_of_lines + 1) {
SPIFFS.remove("/" + file);
current_number_of_lines = 0;
}
if (current_number_of_lines == 0) {
SPIFFS.remove("/" + file);
current_number_of_lines = 0;
}
if (current_number_of_lines > seted_number_of_lines) {
log_date = deleteBeforeDelimiter(log_date, "\n");
log_date += current_time + " " + date_to_add + "\n";
writeFile(file, log_date);
} else {
if (date_time) {
addFile(file, current_time + " " + date_to_add);
} else {
addFile(file, date_to_add);
}
}
}

View File

@@ -0,0 +1,87 @@
/*
Ticker.cpp - esp8266 library that calls functions periodically
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stddef.h>
#include <stdint.h>
#include "c_types.h"
#include "eagle_soc.h"
#include "ets_sys.h"
#include "osapi.h"
static const int ONCE = 0;
static const int REPEAT = 1;
#include "Ticker.h"
Ticker::Ticker()
: _timer(nullptr)
{
}
Ticker::~Ticker()
{
detach();
}
void Ticker::_attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, uint32_t arg)
{
if (_timer)
{
os_timer_disarm(_timer);
}
else
{
_timer = new ETSTimer;
}
os_timer_setfn(_timer, reinterpret_cast<ETSTimerFunc*>(callback), reinterpret_cast<void*>(arg));
os_timer_arm(_timer, milliseconds, (repeat)?REPEAT:ONCE);
}
void Ticker::detach()
{
if (!_timer)
return;
os_timer_disarm(_timer);
delete _timer;
_timer = nullptr;
_callback_function = nullptr;
}
bool Ticker::active() const
{
return (bool)_timer;
}
void Ticker::_static_callback(void* arg)
{
Ticker* _this = (Ticker*)arg;
if (_this == nullptr)
{
return;
}
if (_this->_callback_function)
{
_this->_callback_function();
}
}

View File

@@ -0,0 +1,136 @@
/*
Ticker.h - esp8266 library that calls functions periodically
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef TICKER_H
#define TICKER_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <functional>
#include <Schedule.h>
extern "C" {
typedef struct _ETSTIMER_ ETSTimer;
}
class Ticker
{
public:
Ticker();
~Ticker();
typedef void (*callback_t)(void);
typedef void (*callback_with_arg_t)(void*);
typedef std::function<void(void)> callback_function_t;
void attach_scheduled(float seconds, callback_function_t callback)
{
attach(seconds,std::bind(schedule_function, callback));
}
void attach(float seconds, callback_function_t callback)
{
_callback_function = callback;
attach(seconds, _static_callback, (void*)this);
}
void attach_ms_scheduled(uint32_t milliseconds, callback_function_t callback)
{
attach_ms(milliseconds, std::bind(schedule_function, callback));
}
void attach_ms(uint32_t milliseconds, callback_function_t callback)
{
_callback_function = callback;
attach_ms(milliseconds, _static_callback, (void*)this);
}
template<typename TArg>
void attach(float seconds, void (*callback)(TArg), TArg arg)
{
static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach() callback argument size must be <= 4 bytes");
// C-cast serves two purposes:
// static_cast for smaller integer types,
// reinterpret_cast + const_cast for pointer types
uint32_t arg32 = (uint32_t)arg;
_attach_ms(seconds * 1000, true, reinterpret_cast<callback_with_arg_t>(callback), arg32);
}
template<typename TArg>
void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
{
static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach_ms() callback argument size must be <= 4 bytes");
uint32_t arg32 = (uint32_t)arg;
_attach_ms(milliseconds, true, reinterpret_cast<callback_with_arg_t>(callback), arg32);
}
void once_scheduled(float seconds, callback_function_t callback)
{
once(seconds, std::bind(schedule_function, callback));
}
void once(float seconds, callback_function_t callback)
{
_callback_function = callback;
once(seconds, _static_callback, (void*)this);
}
void once_ms_scheduled(uint32_t milliseconds, callback_function_t callback)
{
once_ms(milliseconds, std::bind(schedule_function, callback));
}
void once_ms(uint32_t milliseconds, callback_function_t callback)
{
_callback_function = callback;
once_ms(milliseconds, _static_callback, (void*)this);
}
template<typename TArg>
void once(float seconds, void (*callback)(TArg), TArg arg)
{
static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach() callback argument size must be <= 4 bytes");
uint32_t arg32 = (uint32_t)(arg);
_attach_ms(seconds * 1000, false, reinterpret_cast<callback_with_arg_t>(callback), arg32);
}
template<typename TArg>
void once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
{
static_assert(sizeof(TArg) <= sizeof(uint32_t), "attach_ms() callback argument size must be <= 4 bytes");
uint32_t arg32 = (uint32_t)(arg);
_attach_ms(milliseconds, false, reinterpret_cast<callback_with_arg_t>(callback), arg32);
}
void detach();
bool active() const;
protected:
void _attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, uint32_t arg);
static void _static_callback (void* arg);
protected:
ETSTimer* _timer;
callback_function_t _callback_function = nullptr;
};
#endif//TICKER_H

View File

@@ -0,0 +1,45 @@
/*
Basic Ticker usage
Ticker is an object that will call a given function with a certain period.
Each Ticker calls one function. You can have as many Tickers as you like,
memory being the only limitation.
A function may be attached to a ticker and detached from the ticker.
There are two variants of the attach function: attach and attach_ms.
The first one takes period in seconds, the second one in milliseconds.
The built-in LED will be blinking.
*/
#include <Ticker.h>
Ticker flipper;
int count = 0;
void flip() {
int state = digitalRead(LED_BUILTIN); // get the current state of GPIO1 pin
digitalWrite(LED_BUILTIN, !state); // set pin to the opposite state
++count;
// when the counter reaches a certain value, start blinking like crazy
if (count == 20) {
flipper.attach(0.1, flip);
}
// when the counter reaches yet another value, stop blinking
else if (count == 120) {
flipper.detach();
}
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
// flip the pin every 0.3s
flipper.attach(0.3, flip);
}
void loop() {
}

View File

@@ -0,0 +1,64 @@
#include "Arduino.h"
#include "Ticker.h"
#define LED1 2
#define LED2 4
#define LED3 12
#define LED4 14
#define LED5 15
class ExampleClass {
public:
ExampleClass(int pin, int duration) : _pin(pin), _duration(duration) {
pinMode(_pin, OUTPUT);
_myTicker.attach_ms(_duration, std::bind(&ExampleClass::classBlink, this));
}
~ExampleClass() {};
int _pin, _duration;
Ticker _myTicker;
void classBlink() {
digitalWrite(_pin, !digitalRead(_pin));
}
};
void staticBlink() {
digitalWrite(LED2, !digitalRead(LED2));
}
void scheduledBlink() {
digitalWrite(LED3, !digitalRead(LED2));
}
void parameterBlink(int p) {
digitalWrite(p, !digitalRead(p));
}
Ticker staticTicker;
Ticker scheduledTicker;
Ticker parameterTicker;
Ticker lambdaTicker;
ExampleClass example(LED1, 100);
void setup() {
pinMode(LED2, OUTPUT);
staticTicker.attach_ms(100, staticBlink);
pinMode(LED3, OUTPUT);
scheduledTicker.attach_ms_scheduled(100, scheduledBlink);
pinMode(LED4, OUTPUT);
parameterTicker.attach_ms(100, std::bind(parameterBlink, LED4));
pinMode(LED5, OUTPUT);
lambdaTicker.attach_ms(100, []() {
digitalWrite(LED5, !digitalRead(LED5));
});
}
void loop() {
}

View File

@@ -0,0 +1,35 @@
/*
Passing paramters to Ticker callbacks
Apart from void(void) functions, the Ticker library supports
functions taking one argument. This argument's size has to be less or
equal to 4 bytes (so char, short, int, float, void*, char* types will do).
This sample runs two tickers that both call one callback function,
but with different arguments.
The built-in LED will be pulsing.
*/
#include <Ticker.h>
Ticker tickerSetHigh;
Ticker tickerSetLow;
void setPin(int state) {
digitalWrite(LED_BUILTIN, state);
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(1, LOW);
// every 25 ms, call setPin(0)
tickerSetLow.attach_ms(25, setPin, 0);
// every 26 ms, call setPin(1)
tickerSetHigh.attach_ms(26, setPin, 1);
}
void loop() {
}

View File

@@ -0,0 +1,29 @@
#######################################
# Syntax Coloring Map For Wire
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
#######################################
# Methods and Functions (KEYWORD2)
#######################################
attach KEYWORD2
attach_ms KEYWORD2
once KEYWORD2
once_ms KEYWORD2
detach KEYWORD2
active KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
Ticker KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View File

@@ -0,0 +1,10 @@
name=Ticker
version=1.0
author=Ivan Grokhtokov <ivan@esp8266.com>
maintainer=Ivan Grokhtokov <ivan@esp8266.com>
sentence=Allows to call functions with a given interval.
paragraph=
category=Timing
url=
architectures=esp8266
dot_a_linkage=true

View File

@@ -1,23 +1,26 @@
void Time_Init() {
server.on("/timeZone", HTTP_GET, [](AsyncWebServerRequest * request) {
if (request->hasArg("timezone")) {
jsonWrite(configSetup, "timezone", request->getParam("timezone")->value());
jsonWriteStr(configSetup, "timezone", request->getParam("timezone")->value());
}
saveConfig();
reconfigTime();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
});
ts.add(TIME_SYNC, 30000, [&](void*) {
if (GetTimeUnix() == "failed") {
Serial.println("[i] Time is not synchronized, start synchronization");
reconfigTime();
}
}, nullptr, true);
}
void reconfigTime() {
if (WiFi.status() == WL_CONNECTED) {
configTime(jsonRead(configSetup, "timezone").toInt() * 3600, 0, ntpServer);
configTime(0, 0, ntpServer);
int i = 0;
Serial.println("[i]Awaiting for time ");
Serial.println("[i] Awaiting for time ");
#ifdef ESP32
struct tm timeinfo;
while (!getLocalTime(&timeinfo) && i <= 4) {
@@ -26,7 +29,6 @@ void reconfigTime() {
delay(1000);
}
#endif
#ifdef ESP8266
// while (!time(nullptr) && i < 4) {
// Serial.print(".");
@@ -34,20 +36,33 @@ void reconfigTime() {
delay(2000);
// }
#endif
Serial.print("Time = ");
if (GetTimeUnix() != "failed") {
Serial.print("[V] Time synchronized = ");
Serial.print(GetDataDigital());
Serial.print(" ");
Serial.println(GetTime());
} else {
Serial.println("[E] Time server or internet connection error, will try again in 30 sec");
}
} else {
Serial.println("[E] Get time impossible, no wifi connection");
}
}
//Получаем время в формате linux gmt
String GetTimeUnix() {
time_t now = time(nullptr);
if (now < 30000) {
return "failed";
} else {
return String(now);
}
}
// Получение текущего времени
String GetTime() {
time_t now = time(nullptr); // получаем время с помощью библиотеки time.h
int zone = 3600 * jsonRead(configSetup, "timezone").toInt();
now = now + zone;
String Time = ""; // Строка для результатов времени
Time += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017
int i = Time.indexOf(":"); //Ишем позицию первого символа :
@@ -57,6 +72,8 @@ String GetTime() {
String GetTimeWOsec() {
time_t now = time(nullptr); // получаем время с помощью библиотеки time.h
int zone = 3600 * jsonRead(configSetup, "timezone").toInt();
now = now + zone;
String Time = ""; // Строка для результатов времени
Time += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017
int i = Time.indexOf(":"); //Ишем позицию первого символа :
@@ -67,6 +84,8 @@ String GetTimeWOsec() {
// Получение даты
String GetDate() {
time_t now = time(nullptr); // получаем время с помощью библиотеки time.h
int zone = 3600 * jsonRead(configSetup, "timezone").toInt();
now = now + zone;
String Data = ""; // Строка для результатов времени
Data += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017
Data.replace("\n", "");
@@ -106,3 +125,11 @@ String GetDataDigital() {
return out;
}
int timeToMin(String Time) {
//"00:00:00" время в секунды
long min = selectToMarker(Time, ":").toInt() * 60; //общее количество секунд в полных часах
Time = deleteBeforeDelimiter (Time, ":"); // Теперь здесь минуты секунды
min += selectToMarker(Time, ":").toInt(); // Добавим секунды из полных минут
return min;
}

View File

@@ -9,7 +9,7 @@ void Timer_countdown_init() {
if (old_line != "") {
Serial.println(old_line);
//Serial.println(old_line);
int i = 0;
@@ -25,7 +25,7 @@ void Timer_countdown_init() {
delTimer (String (number));
jsonWrite(configJson, "timerSet" + String(number), "0");
jsonWriteStr(configJson, "timerSet" + String(number), "0");
eventGen ("timerSet", String(number));
@@ -58,7 +58,7 @@ void timerStart() {
if (type == "hours") period_of_time = String(period_of_time.toInt() * 60 * 60);
addTimer(number, period_of_time);
jsonWrite(configJson, "timerSet" + number, "1");
jsonWriteStr(configJson, "timerSet" + number, "1");
}
void addTimer(String number, String time) {
@@ -78,7 +78,7 @@ void addTimer(String number, String time) {
} else { //если его нет
tmp += new_timer + ",";
}
jsonWrite(optionJson, "timers", tmp);
jsonWriteStr(optionJson, "timers", tmp);
//Serial.println("ura");
}
@@ -98,7 +98,7 @@ void delTimer (String number) {
int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой
String timer = tmp.substring(psn1, psn2) + ","; //1:60, выделяем таймер который надо удалить
tmp.replace(timer, ""); //удаляем таймер
jsonWrite(optionJson, "timers", tmp);
jsonWriteStr(optionJson, "timers", tmp);
}
}
@@ -131,6 +131,8 @@ int readTimer(int number) {
}*/
//------------------------------таймеры------------------------------------------------------
/*
void time() {
String time_number = sCmd.next();
@@ -155,9 +157,9 @@ void time() {
}
jsonWrite(optionJson, "times", replace_line);
jsonWriteStr(optionJson, "times", replace_line);
jsonWrite(configJson, "timeSet" + time_number, "1");
jsonWriteStr(configJson, "timeSet" + time_number, "1");
ts.add(TIMERS, 1000, [&](void*) {
@@ -175,7 +177,7 @@ void time() {
Serial.println(seted_time);
if (current_time == seted_time) {
jsonWrite(configJson, "timeSet" + time_number, "0");
jsonWriteStr(configJson, "timeSet" + time_number, "0");
eventGen ("timeSet", time_number);
}
@@ -183,3 +185,4 @@ void time() {
}
}, nullptr, true);
}
*/

273
Upgrade.ino Normal file
View File

@@ -0,0 +1,273 @@
void initUpgrade() {
#ifdef ESP8266
if (WiFi.status() == WL_CONNECTED) last_version = getURL("http://91.204.228.124:1100/update/esp8266/version.txt");
#endif
#ifdef ESP32
if (WiFi.status() == WL_CONNECTED) last_version = getURL("http://91.204.228.124:1100/update/esp32/version.txt");
#endif
jsonWriteStr(configSetup, "last_version", last_version);
Serial.print("[i] Last firmware version: ");
Serial.println(last_version);
server.on("/check", HTTP_GET, [](AsyncWebServerRequest * request) {
upgrade_url = true;
Serial.print("[i] Last firmware version: ");
Serial.println(last_version);
String tmp = "{}";
if (WiFi.status() == WL_CONNECTED) {
if (mb_4_of_memory) {
if (last_version != "") {
if (last_version != "error") {
if (last_version == firmware_version) {
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Последняя версия прошивки уже установлена.");
jsonWriteStr(tmp, "class", "pop-up");
} else {
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='/'; }, 30000);html('my-block','<span class=loader></span>Идет обновление прошивки, после обновления страница перезагрузится автоматически...')\">Установить</a>");
jsonWriteStr(tmp, "class", "pop-up");
}
} else {
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Ошибка... Cервер не найден. Попробуйте позже...");
jsonWriteStr(tmp, "class", "pop-up");
}
} else {
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Нажмите на кнопку \"обновить прошивку\" повторно...");
jsonWriteStr(tmp, "class", "pop-up");
}
} else {
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Обновление по воздуху не поддерживается, модуль имеет меньше 4 мб памяти...");
jsonWriteStr(tmp, "class", "pop-up");
}
} else {
jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Устройство не подключен к роутеру...");
jsonWriteStr(tmp, "class", "pop-up");
}
request->send(200, "text/text", tmp);
});
server.on("/upgrade", HTTP_GET, [](AsyncWebServerRequest * request) {
upgrade = true;
String tmp = "{}";
//jsonWriteStr(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>Есть новая версия <a href=\"#\" onclick=\"setTimeout(function(){ location.href='/'; }, 5000);}\">Установить?</a>");
request->send(200, "text/text", "ok");
});
}
void do_upgrade_url() {
if (upgrade_url) {
upgrade_url = false;
#ifdef ESP32
last_version = getURL("http://91.204.228.124:1100/update/esp32/version.txt");
jsonWriteStr(configSetup, "last_version", last_version);
#endif
#ifdef ESP8266
last_version = getURL("http://91.204.228.124:1100/update/esp8266/version.txt");
jsonWriteStr(configSetup, "last_version", last_version);
#endif
}
}
void upgrade_firmware() {
String scenario_for_update;
String config_for_update;
String configSetup_for_update;
scenario_for_update = readFile("firmware.s.txt", 3072);
config_for_update = readFile("firmware.c.txt", 3072);
configSetup_for_update = configSetup;
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("firmware.s.txt", scenario_for_update);
writeFile("firmware.c.txt", config_for_update);
writeFile("config.json", configSetup_for_update);
saveConfig();
Serial.println("SPIFFS 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("BUILD upgrade done!");
Serial.println("Restart ESP....");
ESP.restart();
}
}
}
void do_upgrade() {
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;
}
}
*/
/*
// ----------------------- Обновление с сайта
void webUpgrade() {
#ifdef ESP8266
String spiffsData = "http://91.204.228.124:1100/update/esp8266/esp32-esp8266_iot-manager_modules_firmware.spiffs.bin";
String buildData = "http://91.204.228.124:1100/update/esp8266/esp32-esp8266_iot-manager_modules_firmware.ino.bin";
#endif
#ifdef ESP32
String spiffsData = "http://91.204.228.124:1100/update/esp32/esp32-esp8266_iot-manager_modules_firmware.spiffs.bin";
String buildData = "http://91.204.228.124:1100/update/esp32/esp32-esp8266_iot-manager_modules_firmware.ino.bin";
#endif
if (spiffsData != "") { // Если нужно прошить FS
String scenario_for_update;
String config_for_update;
String configSetup_for_update;
Serial.println(spiffsData);
scenario_for_update = readFile("firmware.s.txt", 2048);
config_for_update = readFile("config.all.txt", 2048);
configSetup_for_update = configSetup;
ESPhttpUpdate.rebootOnUpdate(false); // Отключим перезагрузку после обновления
updateHTTP(spiffsData, true);
writeFile("firmware.s.txt", scenario_for_update);
writeFile("config.all.txt", config_for_update);
writeFile("config.json", configSetup_for_update);
saveConfig();
}
if (buildData != "") { // Если нужно прошить build
Serial.println(buildData);
ESPhttpUpdate.rebootOnUpdate(true); // Включим перезагрузку после обновления
updateHTTP(buildData, false);
}
}
// ------------------ Обновление по url
void updateHTTP(String url, boolean mode) {
if (url == "") return;
ESPhttpUpdate.setLedPin(LED_BUILTIN, LOW);
if (mode) {
Serial.println("Update Spiffs...");
t_httpUpdate_return ret = ESPhttpUpdate.updateSpiffs(url);
UpdateStatus(ret , "Spiffs");
} else {
Serial.println("Update Build...");
t_httpUpdate_return ret = ESPhttpUpdate.update(url);
UpdateStatus(ret , "build");
}
}
void UpdateStatus(t_httpUpdate_return set, String mode) {
switch (set) {
case HTTP_UPDATE_FAILED:
Serial.println(mode + "_FAILED");
var = "{}";
jsonWriteStr(var, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>_FAILED");
jsonWriteStr(var, "class", "pop-up");
//request->send(200, "text/text", var);
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println(mode + "_NO_UPDATES");
var = "{}";
jsonWriteStr(var, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>_NO_UPDATES");
jsonWriteStr(var, "class", "pop-up");
//request->send(200, "text/text", var);
break;
case HTTP_UPDATE_OK:
Serial.println(mode + "_UPDATE_OK");
var = "{}";
jsonWriteStr(var, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>_UPDATE_OK");
jsonWriteStr(var, "class", "pop-up");
//request->send(200, "text/text", var);
break;
}
}
*/

View File

@@ -41,7 +41,7 @@ void Web_server_init() {
server.addHandler(&ws);
events.onConnect([](AsyncEventSourceClient * client) {
client->send("hello!", NULL, millis(), 1000);
//!!!client->send("hello!", NULL, millis(), 1000);
});
server.addHandler(&events);
@@ -113,6 +113,7 @@ void Web_server_init() {
request->send(404);
});
server.onFileUpload([](AsyncWebServerRequest * request, const String & filename, size_t index, uint8_t *data, size_t len, bool final) {
if (!index)
Serial.printf("UploadStart: %s\n", filename.c_str());
@@ -120,6 +121,7 @@ void Web_server_init() {
if (final)
Serial.printf("UploadEnd: %s (%u)\n", filename.c_str(), index + len);
});
server.onRequestBody([](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) {
if (!index)
Serial.printf("BodyStart: %u\n", total);
@@ -144,14 +146,22 @@ void Web_server_init() {
server.on("/config.setup.json", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(200, "application/json", configSetup);
});
// ------------------Выполнение команды из запроса
server.on("/cmd", HTTP_GET, [](AsyncWebServerRequest * request) { //http://192.168.88.45/cmd?command=rel%201%201
String com = request->getParam("command")->value();
Serial.println(com);
order_loop += com + ",";
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
});
}
//========================================WS=========================================================================================
#ifdef WS_enable
void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) {
if (type == WS_EVT_CONNECT) {
Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
client->printf(configJson.c_str(), client->id());
client->ping();
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) {

View File

@@ -3,10 +3,10 @@ void WIFI_init() {
// --------------------Получаем ssid password со страницы
server.on("/ssid", HTTP_GET, [](AsyncWebServerRequest * request) {
if (request->hasArg("ssid")) {
jsonWrite(configSetup, "ssid", request->getParam("ssid")->value());
jsonWriteStr(configSetup, "ssid", request->getParam("ssid")->value());
}
if (request->hasArg("password")) {
jsonWrite(configSetup, "password", request->getParam("password")->value());
jsonWriteStr(configSetup, "password", request->getParam("password")->value());
}
saveConfig(); // Функция сохранения данных во Flash
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
@@ -14,10 +14,10 @@ void WIFI_init() {
// --------------------Получаем ssidAP passwordAP со страницы
server.on("/ssidap", HTTP_GET, [](AsyncWebServerRequest * request) {
if (request->hasArg("ssidAP")) {
jsonWrite(configSetup, "ssidAP", request->getParam("ssidAP")->value());
jsonWriteStr(configSetup, "ssidAP", request->getParam("ssidAP")->value());
}
if (request->hasArg("passwordAP")) {
jsonWrite(configSetup, "passwordAP", request->getParam("passwordAP")->value());
jsonWriteStr(configSetup, "passwordAP", request->getParam("passwordAP")->value());
}
saveConfig(); // Функция сохранения данных во Flash
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
@@ -26,10 +26,10 @@ void WIFI_init() {
// --------------------Получаем логин и пароль для web со страницы
server.on("/web", HTTP_GET, [](AsyncWebServerRequest * request) {
if (request->hasArg("web_login")) {
jsonWrite(configSetup, "web_login", request->getParam("web_login")->value());
jsonWriteStr(configSetup, "web_login", request->getParam("web_login")->value());
}
if (request->hasArg("web_pass")) {
jsonWrite(configSetup, "web_pass", request->getParam("web_pass")->value());
jsonWriteStr(configSetup, "web_pass", request->getParam("web_pass")->value());
}
saveConfig(); // Функция сохранения данных во Flash
//Web_server_init();
@@ -42,9 +42,10 @@ void WIFI_init() {
}
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
});
ROUTER_Connecting();
}
// Попытка подключения к точке доступа
void ROUTER_Connecting() {
WiFi.mode(WIFI_STA);
@@ -58,6 +59,8 @@ void WIFI_init() {
}
else {
WiFi.begin(_ssid.c_str(), _password.c_str());
Serial.print("ssid: ");
Serial.println(_ssid);
}
// Делаем проверку подключения до тех пор пока счетчик tries
// не станет равен нулю или не получим подключение
@@ -66,7 +69,7 @@ void WIFI_init() {
if (WiFi.status() == WL_CONNECT_FAILED) {
Serial.println("[E] password is not correct");
tries = 1;
jsonWrite(optionJson, "pass_status", 1);
jsonWriteInt(optionJson, "pass_status", 1);
}
Serial.print(".");
delay(1000);
@@ -85,10 +88,12 @@ void WIFI_init() {
// о подключении и выводим адрес IP
Serial.println("");
Serial.println("[V] WiFi connected");
Serial.print("[V] IP address: ");
Serial.print("[V] IP address: http://");
Serial.print(WiFi.localIP());
Serial.println("");
jsonWrite(configJson, "ip", WiFi.localIP().toString());
jsonWriteStr(configJson, "ip", WiFi.localIP().toString());
//add_dev_in_list("dev.txt", chipID, WiFi.localIP().toString());
}
}
@@ -105,14 +110,15 @@ bool StartAPMode() {
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
jsonWriteStr(configJson, "ip", myIP.toString());
if (jsonReadtoInt(optionJson, "pass_status") != 1) {
ts.add(ROUTER_SEARCHING, 10 * 1000, [&](void*) {
Serial.println("->try find router");
if (RouterFind(jsonRead(configSetup, "ssid"))) {
ts.remove(ROUTER_SEARCHING);
WIFI_init();
MQTT_init();
ROUTER_Connecting();
MQTT_Connecting();
}
}, nullptr, true);
}
@@ -145,14 +151,14 @@ boolean RouterFind(String ssid) {
} else {
Serial.print(i);
Serial.print(")");
Serial.print(ssid);
Serial.print("<=>");
//Serial.print(ssid);
//Serial.print("<=>");
if (i == n) {
Serial.print(WiFi.SSID(i));
Serial.println("; ");
} else {
Serial.print(WiFi.SSID(i));
Serial.print("; ");
Serial.println("; ");
}
}
}
@@ -160,3 +166,42 @@ boolean RouterFind(String ssid) {
return false;
}
}
/*
String scanWIFI() {
uint8_t n = WiFi.scanNetworks();
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
JsonArray& networks = json.createNestedArray("networks");
for (uint8_t i = 0; i < n; i++) {
JsonObject& data = networks.createNestedObject();
String ssidMy = WiFi.SSID(i);
data["ssid"] = ssidMy;
data["pass"] = (WiFi.encryptionType(i) == ENC_TYPE_NONE) ? "" : "*";
int8_t dbm = WiFi.RSSI(i);
data["dbm"] = dbm;
if (ssidMy == jsonRead(configSetup, "ssid")) {
jsonWriteStr(configJson, "dbm", dbm);
}
}
String root;
json.printTo(root);
return root;
}
*/
/*
{
"type":"wifi",
"title":"{{LangWiFi1}}",
"name":"ssid",
"state":"{{ssid}}",
"pattern":".{1,}"
},
{
"type":"password",
"title":"{{LangPass}}",
"name":"ssidPass",
"state":"{{ssidPass}}",
"pattern":".{8,}"
},
*/

49
Widgets.ino Normal file
View File

@@ -0,0 +1,49 @@
//======================================================================================================================
//===============================================Создание виджетов=======================================================
void createWidget (String widget_name, String page_name, String page_number, String file, String topic) {
String widget;
widget = readFile(file, 1024);
if (widget == "Failed") return;
if (widget == "Large") return;
widget_name.replace("#", " ");
page_name.replace("#", " ");
jsonWriteStr(widget, "page", page_name);
jsonWriteStr(widget, "order", page_number);
jsonWriteStr(widget, "descr", widget_name);
jsonWriteStr(widget, "topic", prex + "/" + topic);
#ifdef layout_in_ram
all_widgets += widget + "\r\n";
#else
addFile("layout.txt", widget);
#endif
widget = "";
}
void createChart (String widget_name, String page_name, String page_number, String file, String topic, String maxCount) {
String widget;
widget = readFile(file, 1024);
if (widget == "Failed") return;
if (widget == "Large") return;
widget_name.replace("#", " ");
page_name.replace("#", " ");
jsonWriteStr(widget, "page", page_name);
jsonWriteStr(widget, "order", page_number);
//jsonWriteStr(widget, "descr", widget_name);
jsonWriteStr(widget, "series", widget_name);
jsonWriteStr(widget, "maxCount", maxCount);
jsonWriteStr(widget, "topic", prex + "/" + topic);
#ifdef layout_in_ram
all_widgets += widget + "\r\n";
#else
addFile("layout.txt", widget);
#endif
widget = "";
}

18
data/config-all.json Normal file
View File

@@ -0,0 +1,18 @@
{
"name": "IoTmanager",
"chipID": "",
"ssidAP": "WiFi",
"passwordAP": "",
"ssid": "your_ssid",
"password": "your_password",
"timezone": 3,
"mqttServer": "",
"mqttPort": 0,
"mqttPrefix": "/IoTmanager",
"mqttUser": "",
"mqttPass": "",
"scenario": "1",
"pushingbox_id": "",
"web_login": "admin",
"web_pass": "admin"
}

View File

@@ -1 +0,0 @@
{"SSDP":"MODULES","chipID":"905542-1458415","ssidAP":"WiFi","passwordAP":"","ssid":"rise","password":"hostel3333","timezone":3,"mqttServer":"m12.cloudmqtt.com","mqttPort":14053,"mqttUser":"lbscvzuj","mqttPass":"bLxlveOgaF8F","scenario":"1","timers":"0","pushingbox_id":"v7C133E426B0C69E","web_login":"admin","web_pass":"admin"}

View File

@@ -1 +1,18 @@
{"SSDP":"MODULES","chipID":"905542-1458415","ssidAP":"WiFi","passwordAP":"","ssid":"your_ssid","password":"your_pass","timezone":3,"mqttServer":"","mqttPort":0,"mqttUser":"","mqttPass":"","scenario":"1","timers":"0","pushingbox_id":"","web_login":"admin","web_pass":"admin"}
{
"name": "IoTmanager",
"chipID": "",
"ssidAP": "WiFi",
"passwordAP": "",
"ssid": "rise",
"password": "hostel3333",
"timezone": 2,
"mqttServer": "mqtt.ioty.ru",
"mqttPort": 1883,
"mqttPrefix": "/rise",
"mqttUser": "test",
"mqttPass": "test",
"scenario": "1",
"pushingbox_id": "",
"web_login": "admin",
"web_pass": "admin"
}

View File

@@ -0,0 +1,8 @@
analog 0 Аналоговый#вход,#% Датчики progress-round 310 620 1 100 1
logging analog 5 100 slow Аналоговый#вход Датчики 2
//если датчик углекислого газа выдает напряжение от 1 вольта до 2 вольт, то значит
//значение чтения аналогового входа будут примерно равным
//при 1 вольте - 310, а при 2 вольтах - 620 (считаем по пропорции)
//данная строка переведет диапазон 310-620 в диапазон 1-100 и отобразит в приложении
//варианты отображения: any-data, progress-round, progress-line, fill-gauge

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,5 @@
dallas 2 Водонагреватель,#t°C Датчики any-data 1
logging dallas 1 100 slow Температура Датчики 2
//2 - номер пина датчика
//варианты отображения: any-data, progress-round, progress-line, fill-gauge

View File

@@ -0,0 +1 @@

10
data/configs/dht11.c.txt Normal file
View File

@@ -0,0 +1,10 @@
dhtT DHT11 2 Температура#DHT,#t°C Датчики any-data 1
dhtH DHT11 2 Влажность#DHT,#% Датчики any-data 2
dhtComfort Степень#комфорта: Датчики 3
dhtPerception Восприятие: Датчики 4
dhtDewpoint Точка#росы: Датчики 5
logging dhtT 5 50 slow Температура Датчики 6
logging dhtH 5 50 slow Влажность Датчики 7
//2 - номер пина датчика
//варианты отображения: any-data, progress-round, progress-line, fill-gauge

1
data/configs/dht11.s.txt Normal file
View File

@@ -0,0 +1 @@

10
data/configs/dht22.c.txt Normal file
View File

@@ -0,0 +1,10 @@
dhtT DHT22 2 Температура#DHT,#t°C Датчики any-data 1
dhtH DHT22 2 Влажность#DHT,#% Датчики any-data 2
dhtComfort Степень#комфорта: Датчики 3
dhtPerception Восприятие: Датчики 4
dhtDewpoint Точка#росы: Датчики 5
logging dhtT 5 50 slow Температура Датчики 6
logging dhtH 5 50 slow Влажность Датчики 7
//2 - номер пина датчика
//варианты отображения: any-data, progress-round, progress-line, fill-gauge

1
data/configs/dht22.s.txt Normal file
View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,14 @@
button 1 na Включить#все Реле 0 1
button 2 13 Прихожая Реле 0 2
button 3 14 Кухня Реле 0 3
pwm 1 3 Яркость#коредор: Реле 1023 4
pwm 2 4 Яркость#ванная: Реле 510 5
analog 0 Аналоговый#вход Датчики fill-gauge 1 1023 1 1023 6
logging analog 1 100 slow Аналоговый#вход Датчики 7
//Это демо конфигурация. В ней показано как связать кнопки c мощью сценариев
//Кнопка номер 1 связана с кнопкой 2, 3 и с pwm 2
//Так же продемонстрированна система логгирования данных строкой logging
//1 - это интервал между точками в минутах, 100 это количество точек
//slow или fast это два варианта выгрузки графика, slow более экономичный режим
//больше подходит для esp8266

View File

@@ -0,0 +1,10 @@
button1 = 1
buttonSet 2 1
buttonSet 3 1
pwmSet 2 1024
end
button1 = 0
buttonSet 2 0
buttonSet 3 0
pwmSet 2 0
end

11
data/configs/level.c.txt Normal file
View File

@@ -0,0 +1,11 @@
level Вода#в#баке,#% Датчики fill-gauge 125 20 1
inputDigit digit1 При#скольки#выключить? Датчики 95 2
inputDigit digit2 При#скольки#включить? Датчики 10 3
button 1 5 Насос Датчики 0 4
button 2 line1,line2, Автоматический#режим Датчики 1 5
logging level 1 100 slow Вода#в#баке Датчики 6
//125 - это расстояние от датчика до дна бака в сантиметрах
//20 - это расстояние от датчика до поверхности воды когда бак полный в сантиметрах
//вывод данных будет в процентах заполнения бака
//варианты отображения: any-data, progress-round, progress-line, fill-gauge

6
data/configs/level.s.txt Normal file
View File

@@ -0,0 +1,6 @@
level > digit1
buttonSet 1 0
end
level < digit2
buttonSet 1 1
end

View File

@@ -0,0 +1,11 @@
button 1 5 Прихожая Освещение 0 1
inputDigit digit1 Задержка#выключения Освещение 30 2
switch 1 0 10
//0 - номер пина датчика движения
//5 - номер пина реле
//при срабатывании датчика движения включится реле и обратный таймер на 30 сек
//если движение не будет обнаружено повтороно в течении 30 секунд - свет выключится
//если движение повторится в течении 30 секунд то таймер продлится опять на 30 сек
//свет выключится только в том случае если в комнате все замрет на 30 сек
//задержку выключения можно будет настраивать в приложении

View File

@@ -0,0 +1,7 @@
switch1 = 1
timerStart 1 digit1 sec
buttonSet 1 1
end
timer1 = 0
buttonSet 1 0
end

View File

@@ -0,0 +1,12 @@
switch 1 0 20
text 1 Вход: Охрана 1
textSet 1 не#обнаружено-time
button 1 na Сбросить Охрана 0 2
button 2 line3, Включить#push Охрана 1 3
//0 - номер пина датчика
//при срабатывании датчика движения устройство пошлет пуш и в приложении будет
//написано в текстовом поле, что движение было обнаружено
//так же будет зафиксирован момент времени срабатывания датчика
//в приложении можно отключать отправку пуш сообщений на тот случай если дома хозяин
//перевести датчик снова в режим ожидания движения можно нажав кнопку сброса в приложении

View File

@@ -0,0 +1,10 @@
switch1 = 1
textSet 1 обнаружено#движение-time
end
button1 = 1
textSet 1 не#обнаружено-time
buttonSet 1 0
end
switch1 = 1
push Внимание обнаружено#движение!
end

6
data/configs/pwm.c.txt Normal file
View File

@@ -0,0 +1,6 @@
pwm 1 3 Яркость#коредор: Реле 1023 1
pwm 2 4 Яркость#ванная: Реле 510 2
//в приложении появятся ползунки, соответствующее значение pwm
//будет установленно на пинах 3 и 4
//1023 и 510 это начальные значения после загрузки модуля

1
data/configs/pwm.s.txt Normal file
View File

@@ -0,0 +1 @@

3
data/configs/relay.c.txt Normal file
View File

@@ -0,0 +1,3 @@
button 1 5 Включить#реле Реле 0 1
//это простая кнопка номер 1 управляющая пином 5 имеющая начальное состояние 0

1
data/configs/relay.s.txt Normal file
View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,6 @@
button 1 5 Включить#все Реле 0 1
//что бы использовать эту конфигурацию на другой esp необходимо активировать пресет
//"Вкл. выкл. локального реле", затем в сценарии данного модуля подставить Device ID
//того esp, кнопка на этом девайсе будет выключать другие устройства по воздуху

View File

@@ -0,0 +1,8 @@
button1 = 1
mqtt 3233662-1589485 buttonSet_1_1
mqtt 2233662-1589486 buttonSet_1_1
end
button1 = 0
mqtt 3233662-1589485 buttonSet_1_0
mqtt 2233662-1589486 buttonSet_1_0
end

View File

@@ -0,0 +1,4 @@
button 1 5 Вкл#на#время Таймеры 0 1
inputDigit digit1 Через#сколько#секунд#выключить? Таймеры 5 2
//в сценариях можно поменять на sec, min или hours если нужны другие размерности времени

View File

@@ -0,0 +1,6 @@
button1 = 1
timerStart 1 digit1 sec
end
timer1 = 0
buttonSet 1 0
end

View File

@@ -0,0 +1,3 @@
switch 1 0 10
//физическая кнопка номер 1 подключенная к пину 0, задержка от дребезга 10 мс

View File

@@ -0,0 +1,3 @@
switch1 = 1
mqtt 3233662-1589489 buttonChange_1
end

View File

@@ -0,0 +1,3 @@
button 1 na Включить#все Освещение 0 1
//при нажатии на эту кнопку пины номер 5 и 13 поведут себя как установленно в сценариях

View File

@@ -0,0 +1,8 @@
button1 = 1
pinSet 5 1
pinSet 13 0
end
button1 = 0
pinSet 5 0
pinSet 13 1
end

View File

@@ -0,0 +1,6 @@
switch 1 0 10
//что бы использовать эту конфигурацию на другой esp необходимо активировать пресет
//"Вкл. выкл. локального реле", затем в сценарии данного модуля подставить Device ID
//того esp, к данному модулю нужно подключить кнопку к пину 0 и тогда
//один девайс будет управлять другим по воздуху

View File

@@ -0,0 +1,4 @@
switch1 = 1
mqtt 3233662-1589485 buttonChange_1
mqtt 2233662-1589486 buttonChange_1
end

View File

@@ -0,0 +1,4 @@
button 1 13 Включить#реле Реле 0 1
switch 1 0 10
//можно управлять реле на пине 13 кнопкой на пине 0 или кнопкой в приложении

View File

@@ -0,0 +1,3 @@
switch1 = 1
buttonChange 1
end

View File

@@ -0,0 +1,6 @@
inputTime time1 Во#сколько#включить? Таймеры 20-30-00 1
inputTime time2 Во#сколько#выключить? Таймеры 20-35-00 2
button 1 5 Кнопка#(по#таймеру) Таймеры 0 3
//время в приложение необходимо вводить в строгом формате: ЧЧ-ММ-СС
//можно создавать любое количество таймеров, копируя строку inputTime...

View File

@@ -0,0 +1,6 @@
timenow = time1
buttonSet 1 1
end
timenow = time2
buttonSet 1 0
end

View File

@@ -0,0 +1,17 @@
stepper 1 12 4
stepper 2 13 5
button 1 na Открыть#штору#1 Шторы 0 1
button 2 na Открыть#штору#2 Шторы 0 2
//для подключения необходим драйвер шагового двигателя A4988
//stepper 1 12 4 шаговый двигатель с параметрами: 1 - номер шагового двигателя,
//12 - номер пина количества шагов, 4 - номер пина направления
//stepper 2 13 5 шаговый двигатель с параметрами: 2 - номер шагового двигателя,
//13 - номер пина количества шагов, 5 - номер пина направления
//stepperSet 1 200 5 - прокрутить шаговик номер 1 на 200 шагов по часовой стрелке
//с задержкой между шагами 5 милисекунд (чем меньше задержка тем больше скорость)
//если поставить -200 то будет вращаться против часовой стрелки
//можно подключить не более двух шаговиков

View File

@@ -0,0 +1,12 @@
button1 = 1
stepperSet 1 200 1
end
button1 = 0
stepperSet 1 -200 1
end
button2 = 1
stepperSet 2 200 1
end
button2 = 0
stepperSet 2 -200 1
end

View File

@@ -0,0 +1,12 @@
dallas 2 Водонагреватель,#t°C Термостат any-data 1
logging dallas 5 100 slow Температура Термостат 2
inputDigit digit1 При#скольки#выключить? Термостат 40 3
inputDigit digit2 При#скольки#включить? Термостат 20 4
button 1 5 Нагреватель Термостат 0 5
button 2 line1,line2, Автоматический#режим Термостат 1 6
//2 - номер пина датчика
//5 - номер пина реле
//это термостат который будет держать температуру между двумя
//установленными в приложении значениями, так же можно выключить
//автоматический режим, и тогда нагреватель будет управляться в ручную

View File

@@ -0,0 +1,6 @@
dallas > digit1
buttonSet 1 0
end
dallas < digit2
buttonSet 1 1
end

View File

@@ -1,147 +1,112 @@
{
"configs": [
"/config.live.json",
"/config.setup.json",
"/config.option.json"
],
"class":"col-sm-offset-1 col-sm-10",
"class": "col-sm-offset-1 col-sm-10",
"content": [
{
"type": "h5",
"title": "{{SSDP}}",
"class":"alert-warning"
"title": "{{name}}",
"class": "alert-warning"
},
{
{
"type": "h4",
"title": "Device ID: {{chipID}}"
},
{
{
"type": "h4",
"title": "IP address: {{ip}}"
},
{
{
"type": "h4",
"title": "Uptime: {{uptime}}"
},
{
"type": "hr"
},
{
{
"type": "dropdown",
"name": "help-url",
"class": "btn btn-warning btn-lg",
"style": "display:inline",
"title": {
"#": "Выбирите то, во что Вы хотите превратить ESP <span class=\"caret\"></span>",
"/preset?arg=1": "1.Вкл. выкл. локального реле",
"/preset?arg=2": "2.Вкл. выкл. локального реле в определенное время",
"/preset?arg=3": "3.Вкл. выкл. локального реле на определенный период времени",
"/preset?arg=4": "4.Вкл. выкл. нескольких локальных реле кнопкой в приложении",
"/preset?arg=5": "5.Вкл. выкл. локального реле физической кнопкой и кнопкой в приложении параллельно (для выключателя света)",
"/preset?arg=6": "6.Вкл. выкл. нескольких удаленных реле кнопкой в приложении (нужно указать Device ID)",
"/preset?arg=7": "7.Вкл. выкл. нескольких удаленных реле физической кнопкой (нужно указать Device ID)",
"/preset?arg=8": "8.Широтно импульсная модуляция",
"/preset?arg=9": "9.Сенсор DHT11 и логгирование",
"/preset?arg=10": "10.Сенсор DHT22, DHT33, DHT44, AM2302, RHT03 и логгирование",
"/preset?arg=11": "11.Аналоговый сенсор и логгирование",
"/preset?arg=12": "12.Сенсор DS18B20 и логгирование",
"/preset?arg=13": "13.Термостат на DS18B20 с переключением в ручной режим и логгированием",
"/preset?arg=14": "14.Контроль уровня в баке на сенсорах: JSN-SR04T, HC-SR04, HY-SRF05 и логгирование (управление насосом)",
"/preset?arg=15": "15.Датчик движения включающий свет",
"/preset?arg=16": "16.Охранный датчик движения",
"/preset?arg=17": "17.Система управления шаговыми двигателями на основе драйвера A4988 (открытие закрытие штор)",
"/preset?arg=18": "Настройки по умолчанию"
}
},
{
"type": "h2",
"title": "Конфигурация устройства"
},
{
"type":"file",
"state":"firmware.config.txt",
"style":"width:100%;height:400px",
"type": "file",
"state": "firmware.c.txt",
"style": "width:100%;height:400px",
"title": "Сохранить",
"action": "/all_modules_init",
"class":"btn btn-block btn-success"
"action": "/init?arg=2",
"class": "btn btn-block btn-success"
},
{
"type": "link",
"title": "Инструкция",
"action": "https://github.com/DmitryBorisenko33/esp8266_iot-manager_modules_firmware/wiki/Instruction",
"title": "Подробная инструкция",
"action": "https://github.com/DmitryBorisenko33/esp32-esp8266_iot-manager_modules_firmware/wiki/Instruction",
"class": "btn btn-block btn-primary"
},
{
{
"type": "h2",
"title": "Сценарии"
},
{
"type": "checkbox",
"name":"scenario",
"title": "Включить сценарии",
"action": "/scenario?status=[[scenario]]",
"state": "{{scenario}}"
},
{
{
"type": "checkbox",
"name": "scenario",
"title": "Включить сценарии",
"action": "/init?arg=[[scenario]]",
"state": "{{scenario}}"
},
{
"type": "h6",
"title": ""
},
{
"type":"file",
"state":"firmware.scenario.txt",
"style":"width:100%;height:400px",
"title": "Сохранить и включить",
"action": "/scenario?status=1",
"class":"btn btn-block btn-success"
},
{
"type": "h2",
"title": "Данные модулей"
},
{
"type": "hr"
},
{
"type": "h4",
"title": "Модуль уровня воды (level)",
"style": "width:100%"
},
{
"type": "h6",
"title": "Расстояние от датчика до воды: {{level_in}} см"
},
{
"type": "h6",
"title": " Заполнение бака: {{level}} %"
},
{
"type": "hr"
},
{
"type": "h4",
"title": "Модуль аналогового входа (analog)",
"style": "width:100%"
},
{
"type": "h6",
"title": "Прочитанное значение: {{analog_in}}"
},
{
"type": "h6",
"title": "Преобразованное значение: {{analog}}"
"type": "file",
"state": "firmware.s.txt",
"style": "width:100%;height:400px",
"title": "Сохранить",
"action": "/init?arg=4",
"class": "btn btn-block btn-success"
},
{
"type": "hr"
},
{
"type": "h4",
"title": "Модуль температурного датчика (dallas)",
"style": "width:100%"
},
{
"type": "h6",
"title": "Текущее значение: {{dallas}} °C"
},
{
"type": "hr"
},
{
"type": "h4",
"title": "Модуль pH сенсора от df robot (ph)",
"style": "width:100%"
},
{
"type": "h6",
"title": "Текущее значение: {{ph}}"
},
{
"type": "hr"
},
{
"type": "link",
"title": "Очистить все логи",
"action": "/cleanlog",
"title": "Очистить логи сенсоров",
"action": "/init?arg=3",
"class": "btn btn-block btn-success"
},
{
"type": "link",
"title": "Главная",
"action": "/page.htm?index",
"action": "/",
"class": "btn btn-block btn-danger btn-sm"
}
]

Binary file not shown.

65
data/dev.json Normal file
View File

@@ -0,0 +1,65 @@
{
"configs": [
"/config.live.json",
"/config.setup.json"
],
"title": "Главная",
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
"content": [
{
"type": "h5",
"title": "{{name}}",
"class": "alert-warning"
},
{
"type": "h3",
"title": "Список других устройств в сети:"
},
{
"type": "hr"
},
{
"type": "csv",
"title": [
"html",
"html",
"html"
],
"state": "dev.csv",
"style": "width:100%;",
"class": "nan"
},
{
"type": "hr"
},
{
"type": "link",
"title": "Переформировать список устройств",
"action": "udp?arg=2",
"class": "btn btn-block btn-success"
},
{
"type": "link",
"title": "Обновить страницу",
"action": "udp?arg=3",
"class": "btn btn-block btn-success"
},
{
"type": "hr"
},
{
"type": "text",
"class": "alert alert-warning",
"title": "После нажатия на кнопку 'Переформировать список устройств' ждите примерно минуту, а затем обновите страницу и список появится вновь"
},
{
"type": "hr"
},
{
"type": "link",
"title": "Главная",
"action": "/",
"class": "btn btn-block btn-danger"
}
]
}

View File

@@ -1,572 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>ESP Editor</title>
<style type="text/css" media="screen">
.contextMenu{z-index:300;position:absolute;left:5px;border:1px solid #444;background-color:#f5f5f5;display:none;box-shadow:0 0 10px rgba(0,0,0,.4);font-size:12px;font-family:sans-serif;font-weight:bold}
.contextMenu ul{list-style:none;top:0;left:0;margin:0;padding:0}
.contextMenu li{position:relative;min-width:60px;cursor:pointer}
.contextMenu span{color:#444;display:inline-block;padding:6px}
.contextMenu li:hover{background:#444}
.contextMenu li:hover span{color:#EEE}
.css-treeview ul,.css-treeview li{padding:0;margin:0;list-style:none}
.css-treeview input{position:absolute;opacity:0}
.css-treeview{font:normal 11px Verdana,Arial,Sans-serif;-moz-user-select:none;-webkit-user-select:none;user-select:none}
.css-treeview span{color:#00f;cursor:pointer}
.css-treeview span:hover{text-decoration:underline}
.css-treeview input+label+ul{margin:0 0 0 22px}
.css-treeview input ~ ul{display:none}
.css-treeview label,.css-treeview label::before{cursor:pointer}
.css-treeview input:disabled+label{cursor:default;opacity:.6}
.css-treeview input:checked:not(:disabled) ~ ul{display:block}
.css-treeview label,.css-treeview label::before{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAACgCAYAAAAFOewUAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAApxJREFUeNrslM1u00AQgGdthyalFFOK+ClIIKQKyqUVQvTEE3DmAhLwAhU8QZoH4A2Q2gMSFace4MCtJ8SPBFwAkRuiHKpA6sRN/Lu7zG5i14kctaUqRGhGXnu9O/Pt7MzsMiklvF+9t2kWTDvyIrAsA0aKRRi1T0C/hJ4LUbt5/8rNpWVlp8RSr9J40b48fxFaTQ9+ft8EZ6MJYb0Ok+dnYGpmPgXwKIAvLx8vYXc5GdMAQJgQEkpjRTh36TS2U+DWW/D17WuYgm8pwJyY1npZsZKOxImOV1I/h4+O6vEg5GCZBpgmA6hX8wHKUHDRBXQYicQ4rlc3Tf0VMs8DHBS864F2YFspjgUYjKX/Az3gsdQd2eeBHwmdGWXHcgBGSkZXOXohcEXebRoQcAgjqediNY+AVyu3Z3sAKqfKoGMsewBeEIOPgQxxPJIjcGH6qtL/0AdADzKGnuuD+2tLK7Q8DhHHbOBW+KEzcHLuYc82MkEUekLiwuvVH+guQBQzOG4XdAb8EOcRcqQvDkY2iCLuxECJ43JobMXoutqGgDa2T7UqLKwt9KRyuxKVByqVXXqIoCCUCAqhUOioTWC7G4TQEOD0APy2/7G2Xpu1J4+lxeQ4TXBbITDpoVelRN/BVFbwu5oMMJUBhoXy5tmdRcMwymP2OLQaLjx9/vnBo6V3K6izATmSnMa0Dq7ferIohJhr1p01zrlz49rZF4OMs8JkX23vVQzYp+wbYGV/KpXKjvspl8tsIKCrMNAYFxj2GKS5ZWxg4ewKsJfaGMIY5KXqPz8LBBj6+yDvVP79+yDp/9F9oIx3OisHWwe7Oal0HxCAAAQgAAEIQAACEIAABCAAAQhAAAIQgAAEIAABCEAAAhCAAAQgwD8E/BZgAP0qhKj3rXO7AAAAAElFTkSuQmCC") no-repeat}
.css-treeview label,.css-treeview span,.css-treeview label::before{display:inline-block;height:16px;line-height:16px;vertical-align:middle}
.css-treeview label{background-position:18px 0}
.css-treeview label::before{content:"";width:16px;margin:0 22px 0 0;vertical-align:middle;background-position:0 -32px}
.css-treeview input:checked+label::before{background-position:0 -16px}
@media screen and (-webkit-min-device-pixel-ratio:0){.css-treeview{-webkit-animation:webkit-adjacent-element-selector-bugfix infinite 1s}@-webkit-keyframes webkit-adjacent-element-selector-bugfix{from{padding:0}to{padding:0}}}
#uploader{position:absolute;top:0;right:0;left:0;height:28px;line-height:24px;padding-left:10px;background-color:#444;color:#EEE}#tree{position:absolute;top:28px;bottom:0;left:0;width:200px;padding:8px}
#editor,#preview{position:absolute;top:28px;right:0;bottom:0;left:200px}
#preview{background-color:#EEE;padding:5px}
</style>
<script>
var urlXXX = 'http://192.168.211.181';//bolt
if (window.location.search.substring(1).split("=")[1]) {
urlXXX = 'http://'+window.location.search.substring(1).split("=")[1];
} else {
urlXXX = 'http://'+window.location.hostname;
}
function createFileUploader(element, tree, editor){
var xmlHttp;
var input = document.createElement("input");
input.type = "file";
input.multiple = false;
input.name = "data";
document.getElementById(element).appendChild(input);
var path = document.createElement("input");
path.id = "upload-path";
path.type = "text";
path.name = "path";
path.defaultValue = "/";
document.getElementById(element).appendChild(path);
var button = document.createElement("button");
button.innerHTML = 'Upload';
document.getElementById(element).appendChild(button);
var mkdir = document.createElement("button");
mkdir.innerHTML = 'MkDir';
document.getElementById(element).appendChild(mkdir);
var mkfile = document.createElement("button");
mkfile.innerHTML = 'MkFile';
document.getElementById(element).appendChild(mkfile);
function httpPostProcessRequest(){
if (xmlHttp.readyState == 4){
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
else {
tree.refreshPath(path.value);
}
}
}
function createPath(p){
xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = httpPostProcessRequest;
var formData = new FormData();
formData.append("path", p);
xmlHttp.open("PUT", urlXXX+"/edit");
xmlHttp.send(formData);
}
mkfile.onclick = function(e){
if(path.value.indexOf(".") === -1) return;
createPath(path.value);
editor.loadUrl(path.value);
};
mkdir.onclick = function(e){
if(path.value.length < 2) return;
var dir = path.value
if(dir.indexOf(".") !== -1){
if(dir.lastIndexOf("/") === 0) return;
dir = dir.substring(0, dir.lastIndexOf("/"));
}
createPath(dir);
};
button.onclick = function(e){
if(input.files.length === 0){
return;
}
xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = httpPostProcessRequest;
var formData = new FormData();
formData.append("data", input.files[0], path.value);
xmlHttp.open("POST", urlXXX+"/edit");
xmlHttp.send(formData);
}
input.onchange = function(e){
if(input.files.length === 0) return;
var filename = input.files[0].name;
var ext = /(?:\.([^.]+))?$/.exec(filename)[1];
var name = /(.*)\.[^.]+$/.exec(filename)[1];
if(typeof name !== undefined){
//1197 bolt if(name.length > 8) name = name.substring(0, 8);
filename = name;
}
if(typeof ext !== undefined){
if(ext === "html") ext = "htm";
else if(ext === "jpeg") ext = "jpg";
filename = filename + "." + ext;
}
if(path.value === "/" || path.value.lastIndexOf("/") === 0){
path.value = "/"+filename;
} else {
path.value = path.value.substring(0, path.value.lastIndexOf("/")+1)+filename;
}
}
}
function createTree(element, editor){
var preview = document.getElementById("preview");
var treeRoot = document.createElement("div");
treeRoot.className = "css-treeview";
document.getElementById(element).appendChild(treeRoot);
function loadDownload(path){
document.getElementById('download-frame').src = path+"?download=true";
}
function loadPreview(path){
document.getElementById("editor").style.display = "none";
preview.style.display = "block";
preview.innerHTML = '<img src="'+ urlXXX +path+'" style="max-width:100%; max-height:100%; margin:auto; display:block;" />';
}
function fillFolderMenu(el, path){
var list = document.createElement("ul");
el.appendChild(list);
var action = document.createElement("li");
list.appendChild(action);
var isChecked = document.getElementById(path).checked;
var expnd = document.createElement("li");
list.appendChild(expnd);
if(isChecked){
expnd.innerHTML = "<span>Collapse</span>";
expnd.onclick = function(e){
document.getElementById(path).checked = false;
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
};
var refrsh = document.createElement("li");
list.appendChild(refrsh);
refrsh.innerHTML = "<span>Refresh</span>";
refrsh.onclick = function(e){
var leaf = document.getElementById(path).parentNode;
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
httpGet(leaf, path);
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
};
} else {
expnd.innerHTML = "<span>Expand</span>";
expnd.onclick = function(e){
document.getElementById(path).checked = true;
var leaf = document.getElementById(path).parentNode;
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
httpGet(leaf, path);
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
};
}
var upload = document.createElement("li");
list.appendChild(upload);
upload.innerHTML = "<span>Upload</span>";
upload.onclick = function(e){
var pathEl = document.getElementById("upload-path");
if(pathEl){
var subPath = pathEl.value;
if(subPath.lastIndexOf("/") < 1) pathEl.value = path+subPath;
else pathEl.value = path.substring(subPath.lastIndexOf("/"))+subPath;
}
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
};
var delFile = document.createElement("li");
list.appendChild(delFile);
delFile.innerHTML = "<span>Delete</span>";
delFile.onclick = function(e){
httpDelete(path);
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
};
}
function fillFileMenu(el, path){
var list = document.createElement("ul");
el.appendChild(list);
var action = document.createElement("li");
list.appendChild(action);
if(isTextFile(path)){
action.innerHTML = "<span>Edit</span>";
action.onclick = function(e){
editor.loadUrl(path);
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
};
} else if(isImageFile(path)){
action.innerHTML = "<span>Preview</span>";
action.onclick = function(e){
loadPreview(path);
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
};
}
var download = document.createElement("li");
list.appendChild(download);
download.innerHTML = "<span>Download</span>";
download.onclick = function(e){
loadDownload(path);
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
};
var delFile = document.createElement("li");
list.appendChild(delFile);
delFile.innerHTML = "<span>Delete</span>";
delFile.onclick = function(e){
httpDelete(path);
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(el);
};
}
function showContextMenu(e, path, isfile){
var divContext = document.createElement("div");
var scrollTop = document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop;
var scrollLeft = document.body.scrollLeft ? document.body.scrollLeft : document.documentElement.scrollLeft;
var left = e.clientX + scrollLeft;
var top = e.clientY + scrollTop;
divContext.className = 'contextMenu';
divContext.style.display = 'block';
divContext.style.left = left + 'px';
divContext.style.top = top + 'px';
if(isfile) fillFileMenu(divContext, path);
else fillFolderMenu(divContext, path);
document.body.appendChild(divContext);
var width = divContext.offsetWidth;
var height = divContext.offsetHeight;
divContext.onmouseout = function(e){
if(e.clientX < left || e.clientX > (left + width) || e.clientY < top || e.clientY > (top + height)){
if(document.body.getElementsByClassName('contextMenu').length > 0) document.body.removeChild(divContext);
}
};
}
function createTreeLeaf(path, name, size){
var leaf = document.createElement("li");
leaf.id = (((path == "/")?"":path)+"/"+name).toLowerCase();
var label = document.createElement("span");
label.textContent = name.toLowerCase();
leaf.appendChild(label);
leaf.onclick = function(e){
if(isTextFile(leaf.id)){
editor.loadUrl(leaf.id);
} else if(isImageFile(leaf.id)){
loadPreview(leaf.id);
}
};
leaf.oncontextmenu = function(e){
e.preventDefault();
e.stopPropagation();
showContextMenu(e, leaf.id, true);
};
return leaf;
}
function createTreeBranch(path, name, disabled){
var leaf = document.createElement("li");
var check = document.createElement("input");
check.type = "checkbox";
check.id = (((path == "/")?"":path)+"/"+name).toLowerCase();
if(typeof disabled !== "undefined" && disabled) check.disabled = "disabled";
leaf.appendChild(check);
var label = document.createElement("label");
label.for = check.id;
label.textContent = name.toLowerCase();
leaf.appendChild(label);
check.onchange = function(e){
if(check.checked){
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
httpGet(leaf, check.id);
}
};
label.onclick = function(e){
if(!check.checked){
check.checked = true;
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
httpGet(leaf, check.id);
} else {
check.checked = false;
}
};
leaf.oncontextmenu = function(e){
e.preventDefault();
e.stopPropagation();
showContextMenu(e, check.id, false);
}
return leaf;
}
function addList(parent, path, items){
var list = document.createElement("ul");
parent.appendChild(list);
var ll = items.length;
//Сортировка файлов
items.sort(function(a,b){return (a.name < b.name) ? 1 : ((b.name < a.name) ? -1 : 0);});
for(var i = 0; i < ll; i++){
var item = items[i];
var itemEl;
if(item.type === "file"){
itemEl = createTreeLeaf(path, item.name, item.size);
} else {
itemEl = createTreeBranch(path, item.name);
}
list.appendChild(itemEl);
}
}
function isTextFile(path){
var ext = /(?:\.([^.]+))?$/.exec(path)[1];
if(typeof ext !== undefined){
switch(ext){
case "txt":
case "htm":
case "html":
case "js":
case "json":
case "c":
case "h":
case "cpp":
case "css":
case "xml":
return true;
}
}
return false;
}
function isImageFile(path){
var ext = /(?:\.([^.]+))?$/.exec(path)[1];
if(typeof ext !== undefined){
switch(ext){
case "png":
case "jpg":
case "gif":
case "ico":
return true;
}
}
return false;
}
this.refreshPath = function(path){
if(path.lastIndexOf('/') < 1){
path = '/';
treeRoot.removeChild(treeRoot.childNodes[0]);
httpGet(treeRoot, "/");
} else {
path = path.substring(0, path.lastIndexOf('/'));
var leaf = document.getElementById(path).parentNode;
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
httpGet(leaf, path);
}
};
function delCb(path){
return function(){
if (xmlHttp.readyState == 4){
if(xmlHttp.status != 200){
alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
} else {
if(path.lastIndexOf('/') < 1){
path = '/';
treeRoot.removeChild(treeRoot.childNodes[0]);
httpGet(treeRoot, "/");
} else {
path = path.substring(0, path.lastIndexOf('/'));
var leaf = document.getElementById(path).parentNode;
if(leaf.childNodes.length == 3) leaf.removeChild(leaf.childNodes[2]);
httpGet(leaf, path);
}
}
}
}
}
function httpDelete(filename){
xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = delCb(filename);
var formData = new FormData();
formData.append("path", filename);
xmlHttp.open("DELETE", urlXXX+"/edit");
xmlHttp.send(formData);
}
function getCb(parent, path){
return function(){
if (xmlHttp.readyState == 4){
//clear loading
if(xmlHttp.status == 200) addList(parent, path, JSON.parse(xmlHttp.responseText));
}
}
}
function httpGet(parent, path){
xmlHttp = new XMLHttpRequest(parent, path);
xmlHttp.onreadystatechange = getCb(parent, path);
//Для отключения кэша random() иначе будут старые данные
xmlHttp.open("GET", urlXXX+"/edit?list=" + path +"&rand="+Math.random(), true);
xmlHttp.send(null);
//start loading
}
httpGet(treeRoot, "/");
return this;
}
function createEditor(element, file, lang, theme, type){
function getLangFromFilename(filename){
var lang = "plain";
var ext = /(?:\.([^.]+))?$/.exec(filename)[1];
if(typeof ext !== undefined){
switch(ext){
case "txt": lang = "plain"; break;
case "htm": lang = "html"; break;
case "js": lang = "javascript"; break;
case "c": lang = "c_cpp"; break;
case "cpp": lang = "c_cpp"; break;
case "css":
case "scss":
case "php":
case "html":
case "json":
case "xml":
lang = ext;
}
}
return lang;
}
if(typeof file === "undefined") file = "/index.htm";
if(typeof lang === "undefined"){
lang = getLangFromFilename(file);
}
if(typeof theme === "undefined") theme = "textmate";
if(typeof type === "undefined"){
type = "text/"+lang;
if(lang === "c_cpp") type = "text/plain";
}
var xmlHttp = null;
var editor = ace.edit(element);
//post
function httpPostProcessRequest(){
if (xmlHttp.readyState == 4){
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
}
}
function httpPost(filename, data, type){
xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = httpPostProcessRequest;
var formData = new FormData();
formData.append("data", new Blob([data], { type: type }), filename);
xmlHttp.open("POST", urlXXX + "/edit");
xmlHttp.send(formData);
}
//get
function httpGetProcessRequest(){
if (xmlHttp.readyState == 4){
document.getElementById("preview").style.display = "none";
document.getElementById("editor").style.display = "block";
if(xmlHttp.status == 200) editor.setValue(xmlHttp.responseText);
else editor.setValue("");
editor.clearSelection();
}
}
function httpGet(theUrl){
xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = httpGetProcessRequest;
if (theUrl.indexOf("/") == 0)
theUrl = urlXXX + theUrl;//bolt
xmlHttp.open("GET", theUrl+"?rand="+Math.random(), true);
xmlHttp.send(null);
}
if(lang !== "plain") editor.getSession().setMode("ace/mode/"+lang);
editor.setTheme("ace/theme/"+theme);
editor.$blockScrolling = Infinity;
editor.getSession().setUseSoftTabs(true);
editor.getSession().setTabSize(2);
editor.setHighlightActiveLine(true);
editor.setShowPrintMargin(false);
editor.commands.addCommand({
name: 'saveCommand',
bindKey: {win: 'Ctrl-S', mac: 'Command-S'},
exec: function(editor) {
httpPost(file, editor.getValue()+"", type);
},
readOnly: false
});
editor.commands.addCommand({
name: 'undoCommand',
bindKey: {win: 'Ctrl-Z', mac: 'Command-Z'},
exec: function(editor) {
editor.getSession().getUndoManager().undo(false);
},
readOnly: false
});
editor.commands.addCommand({
name: 'redoCommand',
bindKey: {win: 'Ctrl-Shift-Z', mac: 'Command-Shift-Z'},
exec: function(editor) {
editor.getSession().getUndoManager().redo(false);
},
readOnly: false
});
httpGet(file);
editor.loadUrl = function(filename){
file = filename;
lang = getLangFromFilename(file);
type = "text/"+lang;
if(lang !== "plain") editor.getSession().setMode("ace/mode/"+lang);
httpGet(file);
}
return editor;
}
function onBodyLoad(){
var vars = {};
// var s = "http://192.168.211.180/edit/index.htm";
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { vars[key] = value; });
// var parts = s.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { vars[key] = value; });
if (typeof vars.url !== "undefined" && vars.url != "")
urlXXX = "http://" + vars.url;/**/
var editor = createEditor("editor", vars.file, vars.lang, vars.theme);
var tree = createTree("tree", editor);
createFileUploader("uploader", tree, editor);
};
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.6/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
(function() {
window.require(["ace/ace"], function(a) {
a && a.config.init(true);
if (!window.ace)
window.ace = a;
for (var key in a) if (a.hasOwnProperty(key))
window.ace[key] = a[key];
});
})();
</script>
</head>
<body onload="onBodyLoad();">
<div id="uploader"></div>
<div id="tree"></div>
<div id="editor"></div>
<div id="preview" style="display:none;"></div>
<iframe id=download-frame style='display:none;'></iframe>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

14
data/firmware.c.txt Normal file
View File

@@ -0,0 +1,14 @@
button 1 na Включить#все Реле 0 1
button 2 13 Прихожая Реле 0 2
button 3 14 Кухня Реле 0 3
pwm 1 3 Яркость#коредор: Реле 1023 4
pwm 2 4 Яркость#ванная: Реле 510 5
analog 0 Аналоговый#вход Датчики fill-gauge 1 1023 1 1023 6
logging analog 1 100 slow Аналоговый#вход Датчики 7
//Это демо конфигурация. В ней показано как связать кнопки c мощью сценариев
//Кнопка номер 1 связана с кнопкой 2, 3 и с pwm 2
//Так же продемонстрированна система логгирования данных строкой logging
//1 - это интервал между точками в минутах, 100 это количество точек
//slow или fast это два варианта выгрузки графика, slow более экономичный режим
//больше подходит для esp8266

View File

@@ -1,29 +0,0 @@
button 1 na Включить#все Реле 0 1
button 2 13 Прихожая Реле 0 2
button 3 14 Кухня Реле 0 3
pwm 1 3 Яркость#коредор: Реле 1023 4
pwm 2 4 Яркость#ванная: Реле 510 5
//-------------------------------------------------------------------------------------------------
//analog 0 Аналоговый#вход,#% Датчики progress-round 1 1024 1 1024 6
inputDigit digit1 При#скольки#включить? Датчики 10 7
inputDigit digit2 При#скольки#выключить? Датчики 0 8
button 4 na Нагреватель Датчики 0 9
//dallas 2 Водонагреватель,#t°C Датчики any-data 10
dhtT DHT11 2 Температура#DHT,#t°C Датчики any-data 11
dhtH DHT11 2 Влажность#DHT,#% Датчики any-data 12
dhtComfort Степень#комфорта: Датчики 12
dhtPerception Восприятие: Датчики 13
//level Вода#в#баке,#% Датчики any-data 125 20 14
//-------------------------------------------------------------------------------------------------
button 5 na Вкл#обратный#таймер Таймеры 0 15
inputDigit digit3 Через#сколько#секунд#включить? Таймеры 5 16
button 6 na Включится#по#таймеру Таймеры 0 17
inputTime time1 Во#сколько#включить? Таймеры 20.30 18
button 7 5 Включится#по#таймеру Таймеры 0 19
//-------------------------------------------------------------------------------------------------
switch 1 0 20
textSet 1 неопределено
text 1 Квартира Двери 22
//-------------------------------------------------------------------------------------------------
button 8 scenario Вкл#выкл#все#сценарии Сценарии 1 23
button 9 line1,line2, Вкл#выкл#выбранные#сценарии Сценарии 1 24

10
data/firmware.s.txt Normal file
View File

@@ -0,0 +1,10 @@
button1 = 1
buttonSet 2 1
buttonSet 3 1
pwmSet 2 1024
end
button1 = 0
buttonSet 2 0
buttonSet 3 0
pwmSet 2 0
end

View File

@@ -1,32 +0,0 @@
button1 = 1
buttonSet 2 1
buttonSet 3 1
pwmSet 2 1024
end
button1 = 0
buttonSet 2 0
buttonSet 3 0
pwmSet 2 0
end
analog > digit1
buttonSet 4 1
end
analog < digit2
buttonSet 4 0
end
button5 = 1
timerStart 1 digit3 sec
end
timer1 = 0
buttonSet 6 1
end
timenow = time1
buttonSet 7 1
end
switch1 = 1
textSet 1 закрыто-time
push закрыто вход
end
switch1 = 0
textSet 1 открыто-time
end

View File

@@ -1,75 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<!--
Web Developer: Renats Kevrels (ex. Zozula)
Site: http://www.onclick.lv
Contact: info [at] onclick.lv
Skype: renat2985
Twitter: @Ramzies
Facebook: http://www.facebook.com/renat2985
GitHub: https://github.com/renat2985
From: Latvia, Valmiera
-->
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
<script defer src="js/build.chart.js?v07.04.2018" charset="utf-8"></script>
<!-- <link rel="stylesheet" type="text/css" href="css/chartist.min.css">
<script src="js/chartist.min.js" charset="utf-8"></script>
<script type="text/javascript" src="js/chart.js"></script> -->
<link rel="stylesheet" type="text/css" href="css/build.css?v07.04.2018">
<!-- <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/style.css"> -->
<script defer type="text/javascript" src="js/function.js?v07.04.2018"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<script type="text/javascript">
var jsonResponse;
//function selectTextareaLine(tarea,lineNum) {
// lineNum--;
// var lines = tarea.value.split("\n");
// var startPos = 0, endPos = tarea.value.length;
// for(var x = 0; x < lines.length; x++) {
// if(x == lineNum) {break;}
// startPos += (lines[x].length+1);
// }
// var endPos = lines[lineNum].length+startPos;
// if(typeof(tarea.selectionStart) != "undefined") {
// tarea.focus();
// tarea.selectionStart = startPos;
// tarea.selectionEnd = endPos;
// return true;
// }
// return false;
//}
window.onload = function() {
setContent('first');
}
</script>
</head>
<body>
<div class="container loader-bg">
<ul id="url-content" class="hidden" onclick="document.getElementById('content').style.zIndex=0;"></ul>
<div id="headers"></div>
<div class="row hidden" id="container_column">
<h1 id="title"></h1>
<div id="content" onclick="this.style.zIndex=10"></div>
</div>
<div id="footer"></div>
<div id="edit-content" class="hidden" onclick="document.getElementById('content').style.zIndex=0;">
<a target="_blank" style="position:fixed;right:0;color:#000;" href="https://github.com/tretyakovsa/Sonoff_WiFi_switch/wiki/%D0%92%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE%D1%81%D1%82%D0%B8-page.htm%3F*" title="Github wiki"><i class="help-img"></i>wiki</a>
<textarea class="form-control" onkeyup="isValidJson(this.value,'edit-json')" spellcheck="false" id="edit-json"></textarea>
<div id="error-json"></div>
<div class="btn-group btn-block">
<input class="btn btn-success" style="width:40%" id="edit-view" onclick="setContent('edit');this.value='Loading...';html('url-content', ' ');" value="View" type="button">
<input class="btn btn-danger" style="width:40%" id="edit-save" onclick="var urlPages=window.location.search.substring(1).split('&')[0];httpDelete('/'+urlPages+'.json.gz');send_request_edit(this, val('edit-json'),(urlPages?urlPages:'index')+'.json');toggle('edit-content');toggle('url-content');" value="Save" type="button">
<a class="btn btn-info" style="width:20%" href="#" id="download-json" download="" title="Save to PC"><i class="download-img"></i></a>
</div>
</div>
</div>
</body>
</html>

Binary file not shown.

View File

@@ -8,7 +8,7 @@
"content": [
{
"type": "h5",
"title": "{{SSDP}}",
"title": "{{name}}",
"class": "alert-warning"
},
{
@@ -19,33 +19,73 @@
"type": "h4",
"title": "IP address: {{ip}}"
},
{
"type": "h4",
"title": "Uptime: {{uptime}}"
},
{
"type": "h4",
"title": "Build version: {{firmware_version}}"
},
{
"type": "h4",
"title": "SPIFFS version: 2.3.2"
},
{
"type": "hr"
},
{
"type": "link",
"title": "Конфигурация устройства",
"action": "/page.htm?configuration",
"action": "/?configuration",
"class": "btn btn-block btn-primary"
},
{
"type": "hr"
},
{
"type": "link",
"title": "Список других устройств в сети",
"action": "/?dev",
"class": "btn btn-block btn-success"
},
{
"type": "link",
"title": "Конфигурация WIFI",
"action": "/page.htm?setup",
"action": "/?setup",
"class": "btn btn-block btn-success"
},
{
"type": "link",
"title": "Конфигурация MQTT",
"action": "/page.htm?mqtt",
"action": "/?mqtt",
"class": "btn btn-block btn-success"
},
{
"type": "link",
"title": "Конфигурация push",
"action": "/page.htm?pushingbox",
"action": "/?pushingbox",
"class": "btn btn-block btn-success"
},
{
"type": "h3",
"name": "my-block",
"style": "position:fixed;top:50%;left:50%;width:400px;margin-left:-200px;text-align:center;",
"class": "hidden"
},
{
"type": "hr"
},
{
"type": "button",
"title": "Обновить прошивку",
"action": "/check",
"response": "[[my-block]]",
"class": "btn btn-block btn-danger"
},
{
"type": "hr"
},
{
"type": "link",
"title": "Скачать приложение IoT Manager для android",

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,78 +1,105 @@
{
"configs": [
"/config.setup.json"
"/config.setup.json"
],
"class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
"class": "col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
"content": [
{
"type": "h5",
"title": "{{SSDP}}",
"class":"alert-warning"
"title": "{{name}}",
"class": "alert-warning"
},
{
"type": "h4",
"title": "Server name:"
},
{
{
"type": "input",
"title": "",
"name":"1",
"name": "1",
"state": "{{mqttServer}}"
},
{
{
"type": "h4",
"title": "Port:"
},
{
{
"type": "input",
"title": "",
"name":"2",
"name": "2",
"state": "{{mqttPort}}"
},
{
{
"type": "h4",
"title": "Prefix:"
},
{
"type": "input",
"title": "",
"name": "3",
"state": "{{mqttPrefix}}"
},
{
"type": "h4",
"title": "User name:"
},
{
{
"type": "input",
"title": "",
"name":"3",
"name": "4",
"state": "{{mqttUser}}"
},
{
{
"type": "h4",
"title": "Password:"
},
{
{
"type": "input",
"title": "",
"name":"4",
"name": "5",
"state": "{{mqttPass}}"
},
{
"type":"h3",
"name":"my-block",
"style":"position:fixed;top:30%;left:50%;width:400px;margin-left:-200px;text-align:center;",
"class":"hidden"
{
"type": "h3",
"name": "my-block",
"style": "position:fixed;top:30%;left:50%;width:400px;margin-left:-200px;text-align:center;",
"class": "hidden"
},
{
{
"type": "text",
"class": "alert alert-warning",
"title": "Прежде чем нажимать на кнопку 'Отправить настройки MQTT' сохрание их, если Вы их меняли. Настройки получат и перезапишут все устройства в локальной сети"
},
{
"type": "button",
"title":"Сохранить",
"action": "mqttSave?mqttServer=[[1]]&mqttPort=[[2]]&mqttUser=[[3]]&mqttPass=[[4]]",
"response":"[[my-block]]",
"class": "btn btn-block btn-success",
"style": "width:100%;display:inline"
"title": "Сохранить",
"action": "mqttSave?mqttServer=[[1]]&mqttPort=[[2]]&mqttPrefix=[[3]]&mqttUser=[[4]]&mqttPass=[[5]]",
"class": "btn btn-block btn-success"
},
{
"type": "button",
"title": "Отправить настройки MQTT с этого устройства на все остальные",
"action": "udp?arg=1",
"class": "btn btn-block btn-success"
},
{
"type": "button",
"title": "Проверить соединение с MQTT",
"action": "mqttCheck",
"response": "[[my-block]]",
"class": "btn btn-block btn-success"
},
{
"type": "link",
"title": "Перезагрузить устройство",
"action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/restart?device=ok');}",
"class": "btn btn-block btn-warning"
"class": "btn btn-block btn-success"
},
{
"type": "link",
"title": "Главная",
"action": "/page.htm?index",
"action": "/",
"class": "btn btn-block btn-danger btn-sm"
}
]

View File

@@ -1,92 +0,0 @@
{
"configs": [
"/config.setup.json"
],
"class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
"content": [
{
"type": "h5",
"title": "{{SSDP}}",
"class":"alert-warning"
},
{
"type": "h4",
"title": "Host name:"
},
{
"type": "input",
"title": "",
"name":"1",
"state": "{{pushHost}}"
},
{
"type": "h4",
"title": "Port:"
},
{
"type": "input",
"title": "",
"name":"2",
"state": "{{pushPort}}"
},
{
"type": "h4",
"title": "Fingerprint:"
},
{
"type": "input",
"title": "",
"name":"3",
"state": "{{pushFingerprint}}"
},
{
"type": "h4",
"title": "Access Token:"
},
{
"type": "input",
"title": "",
"name":"4",
"state": "{{pushAccessToken}}"
},
{
"type":"h3",
"name":"my-block",
"style":"position:fixed;top:30%;left:50%;width:400px;margin-left:-200px;text-align:center;",
"class":"hidden"
},
{
"type": "button",
"title":"Сохранить и проверить соединение",
"action": "pushDate?pushHost=[[1]]&pushPort=[[2]]&pushFingerprint=[[3]]&pushAccessToken=[[4]]",
"response":"[[my-block]]",
"class": "btn btn-block btn-success",
"style": "width:100%;display:inline"
},
{
"type": "hr"
},
{
"type": "checkbox",
"name":"start-push",
"title": "Отправлять push при включении устройства",
"action": "startPush?status=[[start-push]]",
"state": "{{startPush}}"
},
{
"type": "hr"
},
{
"type": "link",
"title": "Перезагрузить устройство",
"action": "javascript:if(confirm(renameBlock(jsonResponse,'Перезагрузить?'))){send_request(this,'/restart?device=ok');}",
"class": "btn btn-block btn-warning"
},
{
"type": "link",
"title": "Главная",
"action": "/page.htm?index",
"class": "btn btn-block btn-danger btn-sm"
}
]
}

View File

@@ -6,7 +6,7 @@
"content": [
{
"type": "h5",
"title": "{{SSDP}}",
"title": "{{name}}",
"class":"alert-warning"
},
{
@@ -39,7 +39,7 @@
{
"type": "link",
"title": "Главная",
"action": "/page.htm?index",
"action": "/",
"class": "btn btn-block btn-danger btn-sm"
}
]

2
data/robots.txt Normal file
View File

@@ -0,0 +1,2 @@
User-agent: *
Disallow: *

View File

@@ -7,7 +7,7 @@
"content": [
{
"type": "h5",
"title": "{{SSDP}}",
"title": "{{name}}",
"class":"alert-warning"
},
{
@@ -26,14 +26,14 @@
{
"type": "input",
"title": "Имя устройства",
"name":"ssdp",
"state": "{{SSDP}}",
"name":"dev_name",
"state": "{{name}}",
"pattern": "[0-9a-zA-Zа-яА-Я.\\- ]{1,20}"
},
{
"type": "button",
"title": "Сохранить",
"action": "ssdp?ssdp=[[ssdp]]",
"action": "name?arg=[[dev_name]]",
"class": "btn btn-block btn-success"
},
{
@@ -53,8 +53,7 @@
"type": "password",
"title": "Введите пароль",
"name":"ssidPass",
"state": "{{password}}",
"pattern": ".{8,20}"
"state": "{{password}}"
},
{
"type": "button",

View File

@@ -1,57 +0,0 @@
{
"configs": [
"/config.live.json",
"/config.option.json",
"/config.setup.json",
"/lang/lang.ru.json",
"socket {{ip}}:81/"
],
"title": "Главная",
"class":"col-sm-offset-1 col-sm-10 col-md-offset-2 col-md-8 col-lg-offset-3 col-lg-6",
"content": [
{
"type": "h5",
"title": "{{SSDP}}",
"class":"alert-warning"
},
{
"type": "h4",
"title": "Module tank level:",
"style": "width:80%;float:left;"
},
{
"type": "h4",
"title": "{{module_tank_level_s}}",
"style": "width:20%;float:right;"
},
{
"type": "h4",
"title": "Module analog:",
"style": "width:80%;float:left;"
},
{
"type": "h4",
"title": "{{module_analog_s}}",
"style": "width:20%;float:right;"
},
{
"type": "h4",
"title": "Module ds18b20:",
"style": "width:80%;float:left;"
},
{
"type": "h4",
"title": "{{module_ds18b20_s}}",
"style": "width:20%;float:right;"
},
{
"type": "link",
"title": "Главная",
"action": "/page.htm?index",
"class": "btn btn-block btn-danger btn-sm",
"style": "width:100%;float:right;"
}
]
}

BIN
data/sync.ffs_db Normal file

Binary file not shown.

View File

@@ -0,0 +1,5 @@
{
"widget": "chart",
"series": "Temperature, °C",
"dateFormat": "HH:mm"
}

View File

@@ -0,0 +1,7 @@
{
"widget": "fillgauge",
"circleColor": "#00FFFF",
"textColor": "#FFFFFF",
"waveTextColor": "#000000",
"waveColor": "#00FFFF"
}

Some files were not shown because too many files have changed in this diff Show More