//extern ESP8266WebServer httpServer; static const char httpRoot[] PROGMEM = R"(

WiFi Switch



WiFi connected to .
Last update seconds ago.

WiFi settings
Hardware configuration
Base configuration
Extended configuration
Firmware update
Restart )"; static const char httpConfPage[] PROGMEM = R"(

Base configuration

Home



Device Name:

HTTP User *:
HTTP Password *:

MQTT Server *:
MQTT Port *:
MQTT User *:
MQTT Password *:

In Topic *:
Out Topic:
Out Retain *:

LastWill Topic *:
LastWill Qos *:
LastWill Retain *:
LastWill Message *:

Domoticz Out Topic *:

All ON/OFF Topic *:

)"; //httpConfPage static const char httpConf2Page[] PROGMEM = R"(

Extended configuration

Home


Domoticz

Domoticz Idx 1:
Domoticz Idx 2:
Domoticz Idx 3:

Button MQTT-Out

Retain *:

1:
Topic: Payload:
Hold:
Control relais:
Topic: Payload:

2:
Topic: Payload:
Hold:
Control relais:
Topic: Payload:

3:
Topic: Payload:
Hold:
Control relais:
Topic: Payload:

)"; //httpConf2Page static const char httpConfHwPage[] PROGMEM = R"(

Hardware configuration

Home



Avoid duplicate GPIO assignments!
GPIO 0 and 2 have fixed 10k pullup and must remain high during boot (otherwise flash mode is entered).
GPIO 2 is also connected to builtin LED (active LOW) on most ESP boards, so don't care or strip it.
GPIO 15 has 10k pull-down, so could only be used as active-high in/output.
Some GPIOs go high for some time at boot, so using only active-low logic is advisable, particularly for switching outputs
Invert = active HIGH, default LOW
Impulses are 0 by default (on until off), otherwise will auto-turn-off after specified time in factors of 100ms.

Relais

1 - Enable:
GPIO:
Impulse:
invert:

2 - Enable:
GPIO:
Impulse:
invert:

3 - Enable:
GPIO:
Impulse:
invert:

Buttons

Debounce time: in ms. default: 120
Hold time: in ms. default: 750

1 - Enable:
GPIO:
invert:

2 - Enable:
GPIO:
invert:

3 - Enable:
GPIO:
invert:

Status LEDs

1 - Enable:
GPIO:
invert:

2 - Enable:
GPIO:
invert:

3 - Enable:
GPIO:
invert:


)"; //httpConfHwPage void httpServerHandleRoot() { boolean sendData = false; if (strlen(http_user) > 0 && strlen(http_pass) > 0) { if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication(); sendData = true; } else sendData = true; if (sendData) { httpServer.send_P(200, "text/html", httpRoot); } } void httpServerHandleConfPage() { boolean sendData = false; if (strlen(http_user) > 0 && strlen(http_pass) > 0) { if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication(); sendData = true; } else sendData = true; if (sendData) { httpServer.send_P(200, "text/html", httpConfPage); } } void httpServerHandleConf2Page() { boolean sendData = false; if (strlen(http_user) > 0 && strlen(http_pass) > 0) { if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication(); sendData = true; } else sendData = true; if (sendData) { httpServer.send_P(200, "text/html", httpConf2Page); } } void httpServerHandleConfHwPage() { boolean sendData = false; if (strlen(http_user) > 0 && strlen(http_pass) > 0) { if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication(); sendData = true; } else sendData = true; if (sendData) { httpServer.send_P(200, "text/html", httpConfHwPage); } } //void httpServerHandleNotFound() { // String message = "File Not Found\n\n"; // message += "URI: "; // message += httpServer.uri(); // message += "\nMethod: "; // message += (httpServer.method() == HTTP_GET) ? "GET" : "POST"; // message += "\nArguments: "; // message += httpServer.args(); // message += "\n"; // for (uint8_t i = 0; i < httpServer.args(); i++) { // message += " " + httpServer.argName(i) + ": " + httpServer.arg(i) + "\n"; // } // httpServer.send(404, "text/plain", message); //} void httpServerHandleNotFound() { // if (strlen(http_user) > 0 && strlen(http_pass) > 0) { // if (!httpServer.authenticate(http_user, http_pass)) // return httpServer.requestAuthentication(); httpServer.send(404, "text/plain", ""); //} } void httpServerInit() { httpServer.on("/delconf", []() { Serial.println("httpServer.on /delconf"); if (httpServer.hasArg("token")) { char buf[20]; httpServer.arg("token").toCharArray(buf, 20); if (strcmp(buf, CLEARCONF_TOKEN) == 0) { // httpServer.send(200, "text/plain", "Token OK - deleting config"); deleteConfig(); } } //if // else { // httpServer.send(200, "text/plain", "not allowed"); // } }); httpServer.on("/api", []() { boolean sendData = false; if (strlen(http_user) > 0 && strlen(http_pass) > 0) { if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication(); sendData = true; } else sendData = true; if (sendData) { //Serial.println("httpServer.on /api"); if (httpServer.hasArg("Btn1")) { lastSwitchSource[0] = 2; relaisToggle(0); Serial.println("web Btn1"); } //if if (httpServer.hasArg("Btn2")) { lastSwitchSource[1] = 2; relaisToggle(1); Serial.println("web Btn2"); } //if yield(); if (httpServer.hasArg("Btn3")) { lastSwitchSource[2] = 2; relaisToggle(2); Serial.println("web Btn3"); } //if if (httpServer.hasArg("allOn")) { lastSwitchSource[0] = 2; lastSwitchSource[1] = 2; lastSwitchSource[2] = 2; allRelaisOn(); Serial.println("web allOn"); } //if if (httpServer.hasArg("allOff")) { lastSwitchSource[0] = 2; lastSwitchSource[1] = 2; lastSwitchSource[2] = 2; allRelaisOff(); Serial.println("web allOff"); } //if yield(); //build json object of program data StaticJsonBuffer<200> jsonBuffer; JsonObject &json = jsonBuffer.createObject(); json["ssid"] = WiFi.SSID(); if (relais_enabled[0]) json["swState1"] = relais_state[0]; if (relais_enabled[1]) json["swState2"] = relais_state[1]; if (relais_enabled[2]) json["swState3"] = relais_state[2]; json["devname"] = deviceName; yield(); char jsonchar[200]; json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece httpServer.send(200, "application/json", jsonchar); } }); //httpServer.on /api httpServer.on("/restart", []() { Serial.println("web triggered restart"); ESP.restart(); }); httpServer.on("/confdata", []() { boolean sendData = false; if (strlen(http_user) > 0 && strlen(http_pass) > 0) { if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication(); sendData = true; } else sendData = true; if (sendData) { Serial.println("httpServer.on /confdata"); for (int i = 0; i < httpServer.args(); i++) { char bufName[20]; char bufValue[101]; httpServer.argName(i).toCharArray(bufName, 20); httpServer.arg(i).toCharArray(bufValue, 101); if (strlen(bufName) > 0) { Serial.print("web update "); Serial.print(bufName); Serial.print(" = "); Serial.println(bufValue); setConfig(bufName, bufValue); } saveConfigToFlash = true; // will be saved in next loop() Serial.println("web triggered saveConfigToFlash"); } yield(); //build json object of program data StaticJsonBuffer<1000> jsonBuffer; JsonObject &json = jsonBuffer.createObject(); json["devName"] = deviceName; json["httpUser"] = http_user; json["httpPass"] = http_pass; json["mqttHost"] = mqtt_server; json["mqttPort"] = mqtt_port; json["mqttUser"] = mqtt_user; json["mqttPass"] = mqtt_pass; json["inTop"] = mqtt_topic_in; json["outTop"] = mqtt_topic_out; json["outRet"] = mqtt_outRetain; json["willTop"] = mqtt_willTopic; json["willQos"] = mqtt_willQos; json["willRet"] = mqtt_willRetain; json["willMsg"] = mqtt_willMsg; json["domOutTop"] = domoticz_out_topic; json["allOnOffTop"] = mqtt_allOnOffTopic; yield(); char jsonchar[1000]; json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece httpServer.send(200, "application/json", jsonchar); } }); //httpServer.on /confdata httpServer.on("/confdata2", []() { boolean sendData = false; if (strlen(http_user) > 0 && strlen(http_pass) > 0) { if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication(); sendData = true; } else sendData = true; if (sendData) { Serial.println("httpServer.on /confdata2"); for (int i = 0; i < httpServer.args(); i++) { char bufName[20]; char bufValue[101]; httpServer.argName(i).toCharArray(bufName, 20); httpServer.arg(i).toCharArray(bufValue, 101); if (strlen(bufName) > 0) { Serial.print("web update "); Serial.print(bufName); Serial.print(" = "); Serial.println(bufValue); setConfig(bufName, bufValue); } saveConfig2ToFlash = true; Serial.println("web triggered saveConfig2ToFlash"); } yield(); //build json object of program data StaticJsonBuffer<1000> jsonBuffer; JsonObject &json = jsonBuffer.createObject(); json["btnRet"] = mqtt_btnRetain; json["top1"] = mqtt_topic_out_1; json["top2"] = mqtt_topic_out_2; json["top3"] = mqtt_topic_out_3; json["pld1"] = mqtt_payload_out_1; json["pld2"] = mqtt_payload_out_2; json["pld3"] = mqtt_payload_out_3; json["topHld1"] = mqtt_topic_out_hold_1; json["topHld2"] = mqtt_topic_out_hold_2; json["topHld3"] = mqtt_topic_out_hold_3; json["pldHld1"] = mqtt_payload_out_hold_1; json["pldHld2"] = mqtt_payload_out_hold_2; json["pldHld3"] = mqtt_payload_out_hold_3; json["domIdx1"] = domoticzIdx[0]; json["domIdx2"] = domoticzIdx[1]; json["domIdx3"] = domoticzIdx[2]; json["hld1ToRel"] = hldToRel[0]; json["hld2ToRel"] = hldToRel[1]; json["hld3ToRel"] = hldToRel[2]; yield(); char jsonchar[1000]; json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece httpServer.send(200, "application/json", jsonchar); } }); //httpServer.on /confdata2 httpServer.on("/confdatahw", []() { boolean sendData = false; if (strlen(http_user) > 0 && strlen(http_pass) > 0) { if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication(); sendData = true; } else sendData = true; if (sendData) { Serial.println("httpServer.on /confdatahw"); for (int i = 0; i < httpServer.args(); i++) { char bufName[20]; char bufValue[101]; httpServer.argName(i).toCharArray(bufName, 20); httpServer.arg(i).toCharArray(bufValue, 101); if (strlen(bufName) > 0) { Serial.print("web update "); Serial.print(bufName); Serial.print(" = "); Serial.println(bufValue); setConfig(bufName, bufValue); } saveConfigHwToFlash = true; Serial.println("web triggered saveConfigHwToFlash"); } yield(); //build json object of program data StaticJsonBuffer<1000> jsonBuffer; JsonObject &json = jsonBuffer.createObject(); json["debtime"] = debounceTime; json["hldtime"] = buttonHoldTime; json["enaRel1"] = relais_enabled[0]; json["enaRel2"] = relais_enabled[1]; json["enaRel3"] = relais_enabled[2]; json["enaBtn1"] = button_enabled[0]; json["enaBtn2"] = button_enabled[1]; json["enaBtn3"] = button_enabled[2]; json["enaLed1"] = led_enabled[0]; json["enaLed2"] = led_enabled[1]; json["enaLed3"] = led_enabled[2]; json["ioRel1"] = relais_pins[0]; json["ioRel2"] = relais_pins[1]; json["ioRel3"] = relais_pins[2]; json["ioBtn1"] = buttons_pins[0]; json["ioBtn2"] = buttons_pins[1]; json["ioBtn3"] = buttons_pins[2]; json["ioLed1"] = leds_pins[0]; json["ioLed2"] = leds_pins[1]; json["ioLed3"] = leds_pins[2]; json["invRel1"] = relais_invert[0]; json["invRel2"] = relais_invert[1]; json["invRel3"] = relais_invert[2]; json["invBtn1"] = button_invert[0]; json["invBtn2"] = button_invert[1]; json["invBtn3"] = button_invert[2]; json["invLed1"] = led_invert[0]; json["invLed2"] = led_invert[1]; json["invLed3"] = led_invert[2]; json["puls1"] = relais_impulse[0]; json["puls2"] = relais_impulse[1]; json["puls3"] = relais_impulse[2]; yield(); char jsonchar[1000]; json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece httpServer.send(200, "application/json", jsonchar); } }); //httpServer.on /confdatahw //get heap status, analog input value and all GPIO statuses in one json call httpServer.on("/info", HTTP_GET, []() { boolean sendData = false; if (strlen(http_user) > 0 && strlen(http_pass) > 0) { if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication(); sendData = true; } else sendData = true; if (sendData) { String json = "{"; json += "\"wifissid\":\"" + WiFi.SSID() + "\""; json += "\"heap\":" + String(ESP.getFreeHeap()); json += "}"; httpServer.send(200, "text/json", json); json = String(); } }); //httpServer.on /info httpServer.on("/", []() { httpServerHandleRoot(); }); httpServer.on("/conf", []() { httpServerHandleConfPage(); }); httpServer.on("/conf2", []() { httpServerHandleConf2Page(); }); httpServer.on("/confhw", []() { httpServerHandleConfHwPage(); }); httpServer.onNotFound([]() { httpServerHandleNotFound(); }); //httpServer.onNotFound // HTTP Updater at /update httpUpdater.setup(&httpServer); httpServer.begin(); }