@@ -24,6 +24,13 @@
}
wifiSignalStrength();
setInterval(wifiSignalStrength, 5000)
+ function switchTab(el) {
+ var parentId = el.parentElement.id;
+ document.querySelector(`.${parentId}-selected-body`).classList.replace(`${parentId}-selected-body`,`${parentId}-hidden-body`);
+ document.querySelector(`div[data-${parentId}-body="${el.dataset.tabIndex}"]`).classList.replace(`${parentId}-hidden-body`, `${parentId}-selected-body`);
+ document.querySelector(`.${parentId}-selected-tab`).className = "";
+ el.classList.add(`${parentId}-selected-tab`);
+ }
async function addComponent(name, button) {
let loaderEl = document.createElement("span")
loaderEl.className = "loader";
@@ -31,7 +38,7 @@
document.querySelector("#main > span").insertAdjacentElement("afterend",loaderEl);
let element = document.querySelector("#component");
if(element){
- element.remove();
+ element.remove();
}
let sel = document.querySelector(".selected-btn");
if(sel){
@@ -40,8 +47,8 @@
let main = document.querySelector("#main");
let el = document.createElement("div");
el.id = "component";
- el.style = "display: flex;flex-direction: column;max-width: 32rem;margin-bottom: 1rem;";
- let data = await fetch(name);
+ el.style = "display: flex;flex-direction: column;margin-bottom: 1rem;";
+ let data = await fetch(`${name}`);
let string = await data.text();
el.innerHTML = string;
main.appendChild(el);
diff --git a/data/misc.html b/data/misc.html
deleted file mode 100644
index 9c767ca..0000000
--- a/data/misc.html
+++ /dev/null
@@ -1,193 +0,0 @@
-
Miscellaneous
-
Changes in this section will reboot the device
-
-
\ No newline at end of file
diff --git a/data/mqtt.html b/data/mqtt.html
deleted file mode 100644
index 424f1a8..0000000
--- a/data/mqtt.html
+++ /dev/null
@@ -1,177 +0,0 @@
-
MQTT Configuration
-
Changes in this section will reboot the device
-
-
\ No newline at end of file
diff --git a/data/actions.html b/data/routes/actions.html
similarity index 63%
rename from data/actions.html
rename to data/routes/actions.html
index 2b4b2e6..b9bc172 100644
--- a/data/actions.html
+++ b/data/routes/actions.html
@@ -3,27 +3,35 @@
Hardware Actions
Assigning 255 to any Pin field will disable the respective option
-
-
-
HomeKey/NFC Triggers
-
Executed on successful/failed HomeKey Authentication and on NFC Tag detection(marked as a failed event)
-
Both Neopixel and Simple GPIO have a momentary state
-
-
Neopixel
+
+
+
HomeKey/NFC Triggers
+
Executed on successful/failed HomeKey Authentication and on NFC Tag detection(marked as a failed event)
+
Both Neopixel and Simple GPIO have a momentary state
+
+
+
Neopixel
+
Simple GPIO
+
+
+
+
-
+
-
+
-
+
-
+
-
-
-
Simple GPIO
-
+
+
+
-
-
-
HomeKit Triggers
-
Executed upon interaction in the Home app and in addition also on successful HomeKey Authentication
-
Follows "Always Lock/Unlock on HomeKey" option
-
Momentary state is only available with LOCKED as initial state
-
-
Simple GPIO
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
HomeKit Triggers
+
Executed upon interaction in the Home app and optionally on successful HomeKey Authentication(enabled by default)
+
+
+
Simple GPIO
+
+
-
-
-
+
+
+
* Simple GPIO follows the "Always Lock/Unlock on HomeKey" option
+
** Momentary state applies only if initial state is "LOCKED"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/data/info.html b/data/routes/info.html
similarity index 100%
rename from data/info.html
rename to data/routes/info.html
diff --git a/data/routes/misc.html b/data/routes/misc.html
new file mode 100644
index 0000000..eca4b9c
--- /dev/null
+++ b/data/routes/misc.html
@@ -0,0 +1,196 @@
+
Miscellaneous
+
Changes in this section will reboot the device
+
+
\ No newline at end of file
diff --git a/data/routes/mqtt.html b/data/routes/mqtt.html
new file mode 100644
index 0000000..c5a9db1
--- /dev/null
+++ b/data/routes/mqtt.html
@@ -0,0 +1,187 @@
+
MQTT Configuration
+
Changes in this section will reboot the device
+
+
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index 9e88680..108cc34 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -70,7 +70,7 @@ namespace espConfig
lockCStateCmd.append(id).append("/" MQTT_SET_CURRENT_STATE_TOPIC);
lockTStateCmd.append(id).append("/" MQTT_SET_TARGET_STATE_TOPIC);
lockCustomStateTopic.append(id).append("/" MQTT_CUSTOM_STATE_TOPIC);
- lockCustomStateCmd.append(id).append("/" MQTT_CUSTOM_STATE_TOPIC);
+ lockCustomStateCmd.append(id).append("/" MQTT_CUSTOM_STATE_CTRL_TOPIC);
}
/* MQTT Broker */
std::string mqttBroker = MQTT_HOST;
@@ -946,16 +946,16 @@ String actionsProcess(const String& var) {
}
bool headersFix(AsyncWebServerRequest* request) { request->addInterestingHeader("ANY"); return true; };
void setupWeb() {
- auto infoHandle = new AsyncStaticWebHandler("/info", LittleFS, "/info.html", NULL);
+ auto infoHandle = new AsyncStaticWebHandler("/info", LittleFS, "/routes/info.html", NULL);
webServer.addHandler(infoHandle);
infoHandle->setTemplateProcessor(hkInfoHtmlProcess).setFilter(headersFix);
- auto mqttHandle = new AsyncStaticWebHandler("/mqtt", LittleFS, "/mqtt.html", NULL);
+ auto mqttHandle = new AsyncStaticWebHandler("/mqtt", LittleFS, "/routes/mqtt.html", NULL);
webServer.addHandler(mqttHandle);
mqttHandle->setTemplateProcessor(mqttHtmlProcess).setFilter(headersFix);
- auto miscHandle = new AsyncStaticWebHandler("/misc", LittleFS, "/misc.html", NULL);
+ auto miscHandle = new AsyncStaticWebHandler("/misc", LittleFS, "/routes/misc.html", NULL);
webServer.addHandler(miscHandle);
miscHandle->setTemplateProcessor(miscHtmlProcess).setFilter(headersFix);
- auto actionsHandle = new AsyncStaticWebHandler("/actions", LittleFS, "/actions.html", NULL);
+ auto actionsHandle = new AsyncStaticWebHandler("/actions", LittleFS, "/routes/actions.html", NULL);
webServer.addHandler(actionsHandle);
actionsHandle->setTemplateProcessor(actionsProcess).setFilter(headersFix);
auto assetsHandle = new AsyncStaticWebHandler("/assets", LittleFS, "/assets/", NULL);
@@ -1063,8 +1063,20 @@ void setupWeb() {
}
}
} else if (!strcmp(p->name().c_str(), "control-pin")) {
+ if (!GPIO_IS_VALID_GPIO(p->value().toInt()) && !GPIO_IS_VALID_OUTPUT_GPIO(p->value().toInt()) && p->value().toInt() != 255) {
+ std::string msg = p->value().c_str();
+ msg.append(" is not a valid GPIO Pin");
+ request->send(200, "text/plain", msg.c_str());
+ return;
+ }
espConfig::miscConfig.controlPin = p->value().toInt();
} else if (!strcmp(p->name().c_str(), "led-pin")) {
+ if (!GPIO_IS_VALID_GPIO(p->value().toInt()) && !GPIO_IS_VALID_OUTPUT_GPIO(p->value().toInt()) && p->value().toInt() != 255) {
+ std::string msg = p->value().c_str();
+ msg.append(" is not a valid GPIO Pin");
+ request->send(200, "text/plain", msg.c_str());
+ return;
+ }
espConfig::miscConfig.hsStatusPin = p->value().toInt();
} else if (!strcmp(p->name().c_str(), "hk-always-unlock")) {
espConfig::miscConfig.lockAlwaysUnlock = p->value().toInt();
@@ -1079,12 +1091,36 @@ void setupWeb() {
} else if (!strcmp(p->name().c_str(), "web-auth-password")) {
espConfig::miscConfig.webPassword = p->value().c_str();
} else if (!strcmp(p->name().c_str(), "nfc-ss-gpio-pin")) {
+ if (!GPIO_IS_VALID_GPIO(p->value().toInt()) && !GPIO_IS_VALID_OUTPUT_GPIO(p->value().toInt()) && p->value().toInt() != 255) {
+ std::string msg = p->value().c_str();
+ msg.append(" is not a valid GPIO Pin");
+ request->send(200, "text/plain", msg.c_str());
+ return;
+ }
espConfig::miscConfig.nfcGpioPins[0] = p->value().toInt();
} else if (!strcmp(p->name().c_str(), "nfc-sck-gpio-pin")) {
+ if (!GPIO_IS_VALID_GPIO(p->value().toInt()) && !GPIO_IS_VALID_OUTPUT_GPIO(p->value().toInt()) && p->value().toInt() != 255) {
+ std::string msg = p->value().c_str();
+ msg.append(" is not a valid GPIO Pin");
+ request->send(200, "text/plain", msg.c_str());
+ return;
+ }
espConfig::miscConfig.nfcGpioPins[1] = p->value().toInt();
} else if (!strcmp(p->name().c_str(), "nfc-miso-gpio-pin")) {
+ if (!GPIO_IS_VALID_GPIO(p->value().toInt()) && !GPIO_IS_VALID_OUTPUT_GPIO(p->value().toInt()) && p->value().toInt() != 255) {
+ std::string msg = p->value().c_str();
+ msg.append(" is not a valid GPIO Pin");
+ request->send(200, "text/plain", msg.c_str());
+ return;
+ }
espConfig::miscConfig.nfcGpioPins[2] = p->value().toInt();
} else if (!strcmp(p->name().c_str(), "nfc-mosi-gpio-pin")) {
+ if (!GPIO_IS_VALID_GPIO(p->value().toInt()) && !GPIO_IS_VALID_OUTPUT_GPIO(p->value().toInt()) && p->value().toInt() != 255) {
+ std::string msg = p->value().c_str();
+ msg.append(" is not a valid GPIO Pin");
+ request->send(200, "text/plain", msg.c_str());
+ return;
+ }
espConfig::miscConfig.nfcGpioPins[3] = p->value().toInt();
}
}
@@ -1110,6 +1146,12 @@ void setupWeb() {
AsyncWebParameter* p = request->getParam(i);
LOG(V, "POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
if (!strcmp(p->name().c_str(), "nfc-neopixel-pin")) {
+ if (!GPIO_IS_VALID_GPIO(p->value().toInt()) && !GPIO_IS_VALID_OUTPUT_GPIO(p->value().toInt()) && p->value().toInt() != 255) {
+ std::string msg = p->value().c_str();
+ msg.append(" is not a valid GPIO Pin");
+ request->send(200, "text/plain", msg.c_str());
+ return;
+ }
if (espConfig::miscConfig.nfcNeopixelPin == 255 && p->value().toInt() != 255) {
xTaskCreate(neopixel_task, "neopixel_task", 4096, NULL, 2, &neopixel_task_handle);
if (!pixel) {
@@ -1143,6 +1185,12 @@ void setupWeb() {
} else if (!strcmp(p->name().c_str(), "nfc-f-blue-pixel")) {
espConfig::miscConfig.neopixelFailureColor[espConfig::misc_config_t::colorMap::B] = p->value().toInt();
} else if (!strcmp(p->name().c_str(), "nfc-s-pin")) {
+ if (!GPIO_IS_VALID_GPIO(p->value().toInt()) && !GPIO_IS_VALID_OUTPUT_GPIO(p->value().toInt()) && p->value().toInt() != 255) {
+ std::string msg = p->value().c_str();
+ msg.append(" is not a valid GPIO Pin");
+ request->send(200, "text/plain", msg.c_str());
+ return;
+ }
if (espConfig::miscConfig.nfcSuccessPin == 255 && p->value().toInt() != 255 && gpio_led_task_handle == nullptr) {
pinMode(p->value().toInt(), OUTPUT);
xTaskCreate(nfc_gpio_task, "nfc_gpio_task", 4096, NULL, 2, &gpio_led_task_handle);
@@ -1153,6 +1201,12 @@ void setupWeb() {
}
espConfig::miscConfig.nfcSuccessPin = p->value().toInt();
} else if (!strcmp(p->name().c_str(), "nfc-f-pin")) {
+ if (!GPIO_IS_VALID_GPIO(p->value().toInt()) && !GPIO_IS_VALID_OUTPUT_GPIO(p->value().toInt()) && p->value().toInt() != 255) {
+ std::string msg = p->value().c_str();
+ msg.append(" is not a valid GPIO Pin");
+ request->send(200, "text/plain", msg.c_str());
+ return;
+ }
if (espConfig::miscConfig.nfcFailPin == 255 && p->value().toInt() != 255 && gpio_led_task_handle == nullptr) {
pinMode(p->value().toInt(), OUTPUT);
xTaskCreate(nfc_gpio_task, "nfc_gpio_task", 4096, NULL, 2, &gpio_led_task_handle);
@@ -1171,6 +1225,12 @@ void setupWeb() {
} else if (!strcmp(p->name().c_str(), "nfc-f-time")) {
espConfig::miscConfig.nfcFailTime = p->value().toInt();
} else if (!strcmp(p->name().c_str(), "gpio-a-pin")) {
+ if (!GPIO_IS_VALID_GPIO(p->value().toInt()) && !GPIO_IS_VALID_OUTPUT_GPIO(p->value().toInt()) && p->value().toInt() != 255) {
+ std::string msg = p->value().c_str();
+ msg.append(" is not a valid GPIO Pin");
+ request->send(200, "text/plain", msg.c_str());
+ return;
+ }
if (espConfig::miscConfig.gpioActionPin == 255 && p->value().toInt() != 255) {
pinMode(p->value().toInt(), OUTPUT);
xTaskCreate(gpio_task, "gpio_task", 4096, NULL, 2, &gpio_lock_task_handle);
@@ -1199,7 +1259,7 @@ void setupWeb() {
LOG(V, "SET_STATUS: %s", esp_err_to_name(set_nvs));
LOG(V, "COMMIT_STATUS: %s", esp_err_to_name(commit_nvs));
- request->send(200, "text/plain", "Received Config!");
+ request->send(200, "text/plain", "Configuration applied!");
});
webServer.addHandler(actionsConfigHandle);
auto rebootDeviceHandle = new AsyncCallbackWebHandler();
@@ -1263,7 +1323,7 @@ void mqttConfigReset(const char* buf) {
}
void wifiCallback() {
- if (espConfig::mqttData.mqttBroker.size() > 0 || !std::equal(espConfig::mqttData.mqttBroker.begin(), espConfig::mqttData.mqttBroker.end(), "0.0.0.0")) {
+ if (espConfig::mqttData.mqttBroker.size() >= 7 && espConfig::mqttData.mqttBroker.size() <= 16 && !std::equal(espConfig::mqttData.mqttBroker.begin(), espConfig::mqttData.mqttBroker.end(), "0.0.0.0")) {
mqtt_app_start();
}
setupWeb();