This commit is contained in:
Dmitry Borisenko
2020-03-01 20:41:16 +03:00
parent ec187af09d
commit a6117db46e
43 changed files with 1059 additions and 305 deletions

27
Cmd.ino
View File

@@ -270,20 +270,27 @@ void inputTime() {
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);
}
void timeSet() {
String number = sCmd.next();
String value = sCmd.next();
value.replace(":", ".");
jsonWrite(configJson, "timeSet" + number, value);
value.replace(".", ":");
sendSTATUS("timeSet" + number, value);
}
void handle_time_init() {
ts.add(TIME, 1000, [&](void*) {
String tmp = GetTime();
tmp.replace(":", "-");
jsonWrite(configJson, "timenowSet", tmp);
eventGen ("timenowSet", "");
}, nullptr, true);
}
//=====================================================================================================================================
//=========================================Добавление текстового виджета============================================================
void text() {
@@ -305,25 +312,17 @@ 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);
sendSTATUS("textSet" + number, text);
}
void handle_time_init() {
ts.add(TIME, 1000, [&](void*) {
String tmp = GetTimeWOsec();
tmp.replace(":", ".");
jsonWrite(configJson, "timenowSet", tmp);
eventGen ("timenowSet", "");
}, nullptr, true);
}
//====================================================================================================================================================
/*
void inputText() {

View File

@@ -61,7 +61,8 @@ void prsets_init() {
writeFile("firmware.scenario.txt", readFile("configs/relay.scenario.txt", 2048));
Device_init();
Scenario_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
String tmp = "";
request->redirect("/page.htm?configuration");
});
server.on("/relay_timer", HTTP_GET, [](AsyncWebServerRequest * request) {
@@ -69,7 +70,7 @@ void prsets_init() {
writeFile("firmware.scenario.txt", readFile("configs/relay_t.scenario.txt", 2048));
Device_init();
Scenario_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
request->redirect("/page.htm?configuration");
});
server.on("/relay_countdown", HTTP_GET, [](AsyncWebServerRequest * request) {
@@ -77,7 +78,7 @@ void prsets_init() {
writeFile("firmware.scenario.txt", readFile("configs/relay_c.scenario.txt", 2048));
Device_init();
Scenario_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
request->redirect("/page.htm?configuration");
});
server.on("/relay_several", HTTP_GET, [](AsyncWebServerRequest * request) {
@@ -85,7 +86,7 @@ void prsets_init() {
writeFile("firmware.scenario.txt", readFile("configs/relay_s.scenario.txt", 2048));
Device_init();
Scenario_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
request->redirect("/page.htm?configuration");
});
server.on("/relay_switch", HTTP_GET, [](AsyncWebServerRequest * request) {
@@ -93,7 +94,7 @@ void prsets_init() {
writeFile("firmware.scenario.txt", readFile("configs/relay_sw.scenario.txt", 2048));
Device_init();
Scenario_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
request->redirect("/page.htm?configuration");
});
server.on("/relay_button_remote", HTTP_GET, [](AsyncWebServerRequest * request) {
@@ -101,7 +102,7 @@ void prsets_init() {
writeFile("firmware.scenario.txt", readFile("configs/relay_br.scenario.txt", 2048));
Device_init();
Scenario_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
request->redirect("/page.htm?configuration");
});
server.on("/relay_switch_remote", HTTP_GET, [](AsyncWebServerRequest * request) {
@@ -109,7 +110,15 @@ void prsets_init() {
writeFile("firmware.scenario.txt", readFile("configs/relay_sr.scenario.txt", 2048));
Device_init();
Scenario_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
request->redirect("/page.htm?configuration");
});
server.on("/pwm", HTTP_GET, [](AsyncWebServerRequest * request) {
writeFile("firmware.config.txt", readFile("configs/pwm.config.txt", 2048));
writeFile("firmware.scenario.txt", readFile("configs/pwm.scenario.txt", 2048));
Device_init();
Scenario_init();
request->redirect("/page.htm?configuration");
});
//part 2===============================================================================
@@ -119,7 +128,7 @@ void prsets_init() {
writeFile("firmware.scenario.txt", readFile("configs/dht11.scenario.txt", 2048));
Device_init();
Scenario_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
request->redirect("/page.htm?configuration");
});
server.on("/dht22", HTTP_GET, [](AsyncWebServerRequest * request) {
@@ -127,28 +136,58 @@ void prsets_init() {
writeFile("firmware.scenario.txt", readFile("configs/dht22.scenario.txt", 2048));
Device_init();
Scenario_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
request->redirect("/page.htm?configuration");
});
server.on("/analog", HTTP_GET, [](AsyncWebServerRequest * request) {
writeFile("firmware.config.txt", readFile("configs/analog.config.txt", 2048));
writeFile("firmware.scenario.txt", readFile("configs/analog.scenario.txt", 2048));
Device_init();
Scenario_init();
request->redirect("/page.htm?configuration");
});
server.on("/dallas", HTTP_GET, [](AsyncWebServerRequest * request) {
writeFile("firmware.config.txt", readFile("configs/dallas.config.txt", 2048));
writeFile("firmware.scenario.txt", readFile("configs/dallas.scenario.txt", 2048));
Device_init();
Scenario_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
request->redirect("/page.htm?configuration");
});
server.on("/termostat", HTTP_GET, [](AsyncWebServerRequest * request) {
writeFile("firmware.config.txt", readFile("configs/termostat.config.txt", 2048));
writeFile("firmware.scenario.txt", readFile("configs/termostat.scenario.txt", 2048));
Device_init();
Scenario_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
request->redirect("/page.htm?configuration");
});
server.on("/level", HTTP_GET, [](AsyncWebServerRequest * request) {
writeFile("firmware.config.txt", readFile("configs/level.config.txt", 2048));
writeFile("firmware.scenario.txt", readFile("configs/level.scenario.txt", 2048));
Device_init();
Scenario_init();
request->redirect("/page.htm?configuration");
});
server.on("/moution_relay", HTTP_GET, [](AsyncWebServerRequest * request) {
writeFile("firmware.config.txt", readFile("configs/moution_r.config.txt", 2048));
writeFile("firmware.scenario.txt", readFile("configs/moution_r.scenario.txt", 2048));
Device_init();
Scenario_init();
request->redirect("/page.htm?configuration");
});
server.on("/moution_security", HTTP_GET, [](AsyncWebServerRequest * request) {
writeFile("firmware.config.txt", readFile("configs/moution_s.config.txt", 2048));
writeFile("firmware.scenario.txt", readFile("configs/moution_s.scenario.txt", 2048));
Device_init();
Scenario_init();
request->redirect("/page.htm?configuration");
});
//default===============================================================================
server.on("/default", HTTP_GET, [](AsyncWebServerRequest * request) {
@@ -156,7 +195,7 @@ void prsets_init() {
writeFile("firmware.scenario.txt", readFile("configs/firmware.scenario.txt", 2048));
Device_init();
Scenario_init();
request->send(200, "text/text", "OK"); // отправляем ответ о выполнении
request->redirect("/page.htm?configuration");
});
}
@@ -189,10 +228,10 @@ void up_time() {
void statistics() {
String urls = "http://backup.privet.lv/visitors/?";
urls += WiFi.macAddress().c_str();
urls += "&";
#ifdef ESP8266
urls += "iot-manager_esp8266";
#endif
@@ -200,7 +239,7 @@ void statistics() {
urls += "iot-manager_esp32";
#endif
urls += "&";
#ifdef ESP8266
urls += ESP.getResetReason();
#endif
@@ -208,7 +247,7 @@ void statistics() {
urls += "unknow";
#endif
urls += "&";
urls += DATE_COMPILING;
String stat = getURL(urls);
}

View File

@@ -77,7 +77,7 @@ void level() {
level = map(distance_cm,
jsonReadtoInt(optionJson, "empty_level"),
jsonReadtoInt(optionJson, "full_level"), 0, 100);
//jsonWrite(configJson, "level", level);
jsonWrite(configJson, "level", level);
//if (level_old != level) {
eventGen ("level", "");
sendSTATUS("level", String(level));

View File

@@ -131,6 +131,8 @@ int readTimer(int number) {
}*/
//------------------------------таймеры------------------------------------------------------
/*
void time() {
String time_number = sCmd.next();
@@ -183,3 +185,4 @@ void time() {
}
}, nullptr, true);
}
*/

156
Upgrade.ino Normal file
View File

@@ -0,0 +1,156 @@
void initUpgrade() {
server.on("/upgrade", HTTP_GET, [](AsyncWebServerRequest * request) {
Serial.println("start update...");
//WiFiClient client_for;
//httpUpdate.rebootOnUpdate(false);
//t_httpUpdate_return ret = httpUpdate.updateSpiffs(client_for, "http://91.204.228.124:1100/update/esp32/esp32-esp8266_iot-manager_modules_firmware.spiffs.bin");
//if (ret == HTTP_UPDATE_OK) {
Serial.println("update Spiffs done!");
//t_httpUpdate_return ret = httpUpdate.update(client_for, "http://91.204.228.124:1100/update/esp32/esp32-esp8266_iot-manager_modules_firmware.ino.bin");
// switch (ret) {
// case HTTP_UPDATE_FAILED:
// Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
// break;
// case HTTP_UPDATE_NO_UPDATES:
// Serial.println("HTTP_UPDATE_NO_UPDATES");
// break;
// case HTTP_UPDATE_OK:
// Serial.println("HTTP_UPDATE_OK");
// break;
// }
// }
//UpdateStatus(ret);
/* #ifdef ESP8266
String new_version = getURL("http://91.204.228.124:1100/update/esp8266/version.txt");
#endif
#ifdef ESP32
String new_version = getURL("http://91.204.228.124:1100/update/esp32/version.txt");
#endif
Serial.println(new_version);
String tmp = "{}";
if (new_version == firmware_version) {
jsonWrite(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button> Установленна последняя версия: " + new_version);
jsonWrite(tmp, "class", "pop-up");
} else {
jsonWrite(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button> Начитаню обновление до версии: " + new_version);
jsonWrite(tmp, "class", "pop-up");
webUpgrade();
}*/
request->send(200, "text/text", "ok");
});
}
void UpdateStatus(t_httpUpdate_return set) {
switch (set) {
case HTTP_UPDATE_FAILED:
Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("HTTP_UPDATE_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.scenario.txt", 2048);
config_for_update = readFile("config.all.txt", 2048);
configSetup_for_update = configSetup;
ESPhttpUpdate.rebootOnUpdate(false); // Отключим перезагрузку после обновления
updateHTTP(spiffsData, true);
writeFile("firmware.scenario.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 = "{}";
jsonWrite(var, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>_FAILED");
jsonWrite(var, "class", "pop-up");
//request->send(200, "text/text", var);
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println(mode + "_NO_UPDATES");
var = "{}";
jsonWrite(var, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>_NO_UPDATES");
jsonWrite(var, "class", "pop-up");
//request->send(200, "text/text", var);
break;
case HTTP_UPDATE_OK:
Serial.println(mode + "_UPDATE_OK");
var = "{}";
jsonWrite(var, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>_UPDATE_OK");
jsonWrite(var, "class", "pop-up");
//request->send(200, "text/text", var);
break;
}
}
*/

2
data/.exclude.files Normal file
View File

@@ -0,0 +1,2 @@
/*.js.gz
/.exclude.files

BIN
data/ace.js.gz Normal file

Binary file not shown.

View File

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

View File

@@ -0,0 +1 @@

View File

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

View File

@@ -0,0 +1 @@

View File

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

View File

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

View File

@@ -4,27 +4,21 @@ button 3 14 Кухня Реле 0 3
pwm 1 3 Яркость#коредор: Реле 1023 4
pwm 2 4 Яркость#ванная: Реле 510 5
//---------------------------------------------------------------------
//analog 0 Аналоговый#вход,#% Датчики progress-round 1 1024 1 1024 6
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
//dhtDewpoint Точка#росы: Датчики 14
//level Вода#в#баке,#% Датчики any-data 125 20 15
//---------------------------------------------------------------------
button 5 na Вкл#обратный#таймер Таймеры 0 16
inputDigit digit3 Через#сколько#секунд#включить? Таймеры 5 17
button 6 na Включится#по#таймеру Таймеры 0 18
inputTime time1 Во#сколько#включить? Таймеры 20.30 19
inputTime time1 Во#сколько#включить? Таймеры 20-30-00 19
button 7 5 Включится#по#таймеру Таймеры 0 20
//---------------------------------------------------------------------
switch 1 0 20
textSet 1 неопределено
text 1 Квартира Двери 22
text 1 Вход: Охрана 20
textSet 1 не#обнаружено-time
button 8 na Сбросить Охрана 0 21
//---------------------------------------------------------------------
button 8 scenario Вкл#выкл#все#сценарии Сценарии 1 23
button 9 line1,line2, Вкл#выкл#выбранные#сценарии Сценарии 1 24
button 9 scenario Вкл#выкл#все#сценарии Сценарии 1 23
button 10 line1,line2, Вкл#выкл#выбранные#сценарии Сценарии 1 24

View File

@@ -24,9 +24,10 @@ timenow = time1
buttonSet 7 1
end
switch1 = 1
textSet 1 закрыто-time
push закрыто вход
textSet 1 обнаружено#движение-time
push Внимание обнаружено#движение!
end
switch1 = 0
textSet 1 открыто-time
button8 = 1
textSet 1 не#обнаружено-time
buttonSet 8 0
end

View File

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

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,10 @@
switch 1 0 20
text 1 Вход: Охрана 1
textSet 1 не#обнаружено-time
button 1 na Сбросить Охрана 0 2
//0 - номер пина датчика
//при срабатывании датчика движения устройство пошлет пуш и в приложении будет
//написано в текстовом поле, что движение было обнаружено, так же будет зафиксирован
//момент времени срабатывания датчика
//перевести датчик снова в режим ожидания движения можно нажав кнопку сброса в приложении

View File

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

View File

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

View File

@@ -0,0 +1 @@

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,6 +4,7 @@
"/config.live.json",
"/config.setup.json",
"/config.option.json"
],
"class":"col-sm-offset-1 col-sm-10",
"content": [
@@ -29,115 +30,30 @@
},
{
"type": "h2",
"title": "Чтобы превратить ESP во что либо из списка, нажмите на соответствующию кнопку:"
},
{
"type": "h4",
"title": "Раздел 1. Управление нагрузкой"
},
{
"type": "button",
"title": "Вкл. выкл. локального реле",
"action": "/relay",
"class": "btn btn-block btn-primary"
},
{
"type": "button",
"title": "Вкл. выкл. локального реле в определенное время",
"action": "/relay_timer",
"class": "btn btn-block btn-primary"
},
{
"type": "button",
"title": "Вкл. выкл. локального реле на определенный период времени",
"action": "/relay_countdown",
"class": "btn btn-block btn-primary"
},
{
"type": "button",
"title": "Вкл. выкл. нескольких локальных реле кнопкой в приложении",
"action": "/relay_several",
"class": "btn btn-block btn-primary"
},
{
"type": "button",
"title": "Вкл. выкл. локального реле физической кнопкой (кнопка так же дублируется в приложении)",
"action": "/relay_switch",
"class": "btn btn-block btn-primary"
},
{
"type": "button",
"title": "Вкл. выкл. нескольких удаленных реле кнопкой в приложении (нужно указать Device ID)",
"action": "/relay_button_remote",
"class": "btn btn-block btn-primary"
},
{
"type": "button",
"title": "Вкл. выкл. нескольких удаленных реле физической кнопкой (нужно указать Device ID)",
"action": "/relay_switch_remote",
"class": "btn btn-block btn-primary"
},
{
"type": "h4",
"title": "Раздел 2. Сенсоры"
},
{
"type": "button",
"title": "Сенсор DHT11",
"action": "/dht11",
"class": "btn btn-block btn-primary"
},
{
"type": "button",
"title": "Сенсор DHT22, DHT33, DHT44, AM2302, RHT03",
"action": "/dht22",
"class": "btn btn-block btn-primary"
},
{
"type": "button",
"title": "Сенсор DS18B20",
"action": "/dallas",
"class": "btn btn-block btn-primary"
},
{
"type": "button",
"title": "Термостат на DS18B20",
"action": "/termostat",
"class": "btn btn-block btn-primary"
},
{
"type": "button",
"title": "Датчик движения включающий свет",
"action": "/moution-relay",
"class": "btn btn-block btn-primary"
},
{
"type": "button",
"title": "Охранный датчик движения",
"action": "/moution-security",
"class": "btn btn-block btn-primary"
},
{
"type": "button",
"title": "Выключатель",
"action": "/switch",
"class": "btn btn-block btn-primary"
},
{
"type": "hr"
},
{
"type": "button",
"title": "Сбросить сценарии и конфигурации по умолчанию",
"action": "/default",
"class": "btn btn-block btn-danger"
},
{
"type": "hr"
"type":"dropdown",
"name":"help-url",
"class":"btn btn-warning btn-lg",
"style":"display:inline",
"title": {
"#":"Выбирите то, во что Вы хотите превратить ESP <span class=\"caret\"></span>",
"/relay":"Вкл. выкл. локального реле",
"/relay_timer":"Вкл. выкл. локального реле в определенное время",
"/relay_countdown":"Вкл. выкл. локального реле на определенный период времени",
"/relay_several":"Вкл. выкл. нескольких локальных реле кнопкой в приложении",
"/relay_switch":"Вкл. выкл. локального реле физической кнопкой (кнопка так же дублируется в приложении)",
"/relay_button_remote":"Вкл. выкл. нескольких удаленных реле кнопкой в приложении (нужно указать Device ID)",
"/relay_switch_remote":"Вкл. выкл. нескольких удаленных реле физической кнопкой (нужно указать Device ID)",
"/pwm":"Широтно импульсная модуляция",
"/dht11":"Сенсор DHT11",
"/dht22":"Сенсор DHT22, DHT33, DHT44, AM2302, RHT03",
"/analog":"Аналоговый сенсор",
"/dallas":"Сенсор DS18B20",
"/termostat":"Термостат на DS18B20 с переключением в ручной режим",
"/level":"Контроль уровня в баке на сенсорах: JSN-SR04T, HC-SR04, HY-SRF05 (управление насосом)",
"/moution_relay":"Датчик движения включающий свет",
"/moution_security":"Охранный датчик движения",
"/default":"Настройки по умолчанию"
}
},
{
"type": "h2",
@@ -180,71 +96,6 @@
"action": "/scenario?status=1",
"class":"btn btn-block btn-success"
},
{
"type": "hr"
},
{
"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": "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"
},

572
data/edit.htm Normal file
View File

@@ -0,0 +1,572 @@
<!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>

BIN
data/edit.htm.gz Normal file

Binary file not shown.

View File

@@ -4,27 +4,21 @@ button 3 14 Кухня Реле 0 3
pwm 1 3 Яркость#коредор: Реле 1023 4
pwm 2 4 Яркость#ванная: Реле 510 5
//---------------------------------------------------------------------
//analog 0 Аналоговый#вход,#% Датчики progress-round 1 1024 1 1024 6
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
//dhtDewpoint Точка#росы: Датчики 14
//level Вода#в#баке,#% Датчики any-data 125 20 15
//---------------------------------------------------------------------
button 5 na Вкл#обратный#таймер Таймеры 0 16
inputDigit digit3 Через#сколько#секунд#включить? Таймеры 5 17
button 6 na Включится#по#таймеру Таймеры 0 18
inputTime time1 Во#сколько#включить? Таймеры 20.30 19
inputTime time1 Во#сколько#включить? Таймеры 20-30-00 19
button 7 5 Включится#по#таймеру Таймеры 0 20
//---------------------------------------------------------------------
switch 1 0 20
textSet 1 неопределено
text 1 Квартира Двери 22
text 1 Вход: Охрана 20
textSet 1 не#обнаружено-time
button 8 na Сбросить Охрана 0 21
//---------------------------------------------------------------------
button 8 scenario Вкл#выкл#все#сценарии Сценарии 1 23
button 9 line1,line2, Вкл#выкл#выбранные#сценарии Сценарии 1 24
button 9 scenario Вкл#выкл#все#сценарии Сценарии 1 23
button 10 line1,line2, Вкл#выкл#выбранные#сценарии Сценарии 1 24

View File

@@ -24,9 +24,10 @@ timenow = time1
buttonSet 7 1
end
switch1 = 1
textSet 1 закрыто-time
push закрыто вход
textSet 1 обнаружено#движение-time
push Внимание обнаружено#движение!
end
switch1 = 0
textSet 1 открыто-time
button8 = 1
textSet 1 не#обнаружено-time
buttonSet 8 0
end

View File

@@ -46,6 +46,25 @@
"action": "/page.htm?pushingbox",
"class": "btn btn-block btn-success"
},
{
"type": "hr"
},
{
"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": "/upgrade",
"response":"[[my-block]]",
"class": "btn btn-block btn-success"
},
{
"type": "hr"
},
{
"type": "link",
"title": "Скачать приложение IoT Manager для android",

BIN
data/mode-html.js.gz Normal file

Binary file not shown.

View File

@@ -52,12 +52,15 @@ void setup() {
statistics();
Serial.println("[V] statistics");
//--------------------------------------------------------------
initUpgrade();
Serial.println("[V] initUpgrade");
//--------------------------------------------------------------
getMemoryLoad("[i] After loading");
// ts.add(TEST, 20000, [&](void*) {
// ts.add(TEST, 20000, [&](void*) {
// }, nullptr, true);
// }, nullptr, true);
}

View File

@@ -19,23 +19,29 @@ void MQTT_init() {
saveConfig();
client.disconnect();
client.disconnect();
MQTT_Connecting();
int i = 0;
while (!client.connected() && i <= 25) {
delay(1000);
Serial.print(".");
i++;
}
/*
int i = 0;
while (!client.connected() && i <= 25) {
delay(1000);
Serial.print(".");
i++;
}
*/
String tmp = "{}";
jsonWrite(tmp, "title", "<button class=\"close\" onclick=\"toggle('my-block')\">×</button>" + stateMQTT());
jsonWrite(tmp, "class", "pop-up");
//request->send(200, "text/text", "ok");
request->send(200, "text/text", tmp); // отправляем ответ о выполнении
#ifdef ESP8266
request->send(200, "text/text", "ok");
#endif
#ifdef ESP32
request->send(200, "text/text", tmp);
#endif
});
//проверка подключения к серверу
@@ -206,9 +212,6 @@ void sendAllData() { //берет строку json и ключи превра
String topic = selectToMarker (tmp, ":");
topic.replace("\"", "");
String state = selectToMarkerLast (tmp, ":");
if (topic.indexOf("time") < 0) {
state.replace(".", ":");
}
state.replace("\"", "");
if (topic != ssdpS && topic != "lang" && topic != "ip" && topic.indexOf("_in") < 0) {
sendSTATUS(topic, state);

70
set.h
View File

@@ -1,9 +1,40 @@
String firmware_version = "2.2";
//#define OTA_enable
//#define MDNS_enable
//#define WS_enable
#define TIME_COMPILING String(__TIME__)
#define DATE_COMPILING String(__DATE__)
#define wifi_mqtt_reconnecting 20000
//-----------------------------------------------------------------
#define analog_update_int 5000
//-----------------------------------------------------------------
#define ph_shooting_interval 500 //интервал выстрела датчика
#define ph_times_to_send 10 //после скольки выстрелов делать отправку данных
//-----------------------------------------------------------------
#define temp_update_int 5000
//-----------------------------------------------------------------
#define tank_level_shooting_interval 500 //интервал выстрела датчика
#define tank_level_times_to_send 20 //после скольки выстрелов делать отправку данных
//-----------------------------------------------------------------
#define dhtT_update_int 10000
#define dhtH_update_int 10000
#define dht_calculation_update_int 10000
//-----------------------------------------------------------------
//==библиотеки и объекты для ESP8266==//
#ifdef ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESPAsyncTCP.h>
#include <ESP8266mDNS.h>
#include <ESP8266httpUpdate.h>
#include <ESP8266HTTPUpdateServer.h>
ESP8266HTTPUpdateServer httpUpdater;
#endif
//==библиотеки и объекты для ESP32==//
@@ -15,8 +46,12 @@
#endif
#include <AsyncTCP.h>
#include <analogWrite.h>
#include <HTTPUpdate.h>
#include <HTTPClient.h>
HTTPClient http;
//HTTPClient http;
#endif
//==общие библиотеки и объекты==//
@@ -67,36 +102,7 @@ DHTesp dht;
Adafruit_Si7021 sensor_Si7021 = Adafruit_Si7021();
//-----------------------------------------------------------------
//#define OTA_enable
//-----------------------------------------------------------------
//#define MDNS_enable
//-----------------------------------------------------------------
//#define WS_enable
//-----------------------------------------------------------------
#define TIME_COMPILING String(__TIME__)
#define DATE_COMPILING String(__DATE__)
#define wifi_mqtt_reconnecting 20000
//-----------------------------------------------------------------
#define analog_update_int 5000
//-----------------------------------------------------------------
#define ph_shooting_interval 500 //интервал выстрела датчика
#define ph_times_to_send 10 //после скольки выстрелов делать отправку данных
//-----------------------------------------------------------------
#define temp_update_int 5000
//-----------------------------------------------------------------
#define tank_level_shooting_interval 500 //интервал выстрела датчика
#define tank_level_times_to_send 20 //после скольки выстрелов делать отправку данных
//-----------------------------------------------------------------
#define dhtT_update_int 10000
#define dhtH_update_int 10000
#define dht_calculation_update_int 10000
//-----------------------------------------------------------------
const char* hostName = "esp-async";
const char* hostName = "IoT Manager";
String configSetup = "{}";
String configJson = "{}";
@@ -128,3 +134,5 @@ int scenario_line_status [] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
int wifi_lost_error = 0;
int mqtt_lost_error = -1;
String var;