feat: версия прошивки в веб-морде (controller v1.2, node v1.1)
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT
|
#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT
|
||||||
|
|
||||||
#define AP_SSID "Barrier-Setup"
|
#define AP_SSID "Barrier-Setup"
|
||||||
|
#define FW_VERSION "1.2"
|
||||||
#define AP_PASS "barrier123"
|
#define AP_PASS "barrier123"
|
||||||
|
|
||||||
Preferences prefs;
|
Preferences prefs;
|
||||||
@@ -141,7 +142,7 @@ input[type=text]:focus,input[type=password]:focus{outline:none;border-color:#219
|
|||||||
<h2>Barrier Controller</h2>
|
<h2>Barrier Controller</h2>
|
||||||
<div class='sub'>IP: )";
|
<div class='sub'>IP: )";
|
||||||
html += currentIP();
|
html += currentIP();
|
||||||
html += "</div>";
|
html += " · v" + String(FW_VERSION) + "</div>";
|
||||||
|
|
||||||
if (msg.startsWith("❌"))
|
if (msg.startsWith("❌"))
|
||||||
html += "<div class='err'>" + msg + "</div>";
|
html += "<div class='err'>" + msg + "</div>";
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT
|
#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT
|
||||||
|
|
||||||
#define AP_SSID "Barrier-Node-Setup"
|
#define AP_SSID "Barrier-Node-Setup"
|
||||||
|
#define FW_VERSION "1.1"
|
||||||
#define AP_PASS "barrier123"
|
#define AP_PASS "barrier123"
|
||||||
|
|
||||||
Preferences prefs;
|
Preferences prefs;
|
||||||
@@ -32,7 +33,7 @@ String cfg_token = "barrier_token_2026";
|
|||||||
String cfg_self_ip = "";
|
String cfg_self_ip = "";
|
||||||
String cfg_gateway = "";
|
String cfg_gateway = "";
|
||||||
String cfg_subnet = "255.255.255.0";
|
String cfg_subnet = "255.255.255.0";
|
||||||
String cfg_name = "Шлагбаум 1";
|
String cfg_name = "Шлагбаум 1"; // имя для идентификации
|
||||||
|
|
||||||
void WiFiEvent(WiFiEvent_t event) {
|
void WiFiEvent(WiFiEvent_t event) {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
@@ -89,9 +90,9 @@ void saveConfig() {
|
|||||||
|
|
||||||
void triggerRelay() {
|
void triggerRelay() {
|
||||||
Serial.println("Реле: импульс 500мс");
|
Serial.println("Реле: импульс 500мс");
|
||||||
digitalWrite(RELAY_PIN, HIGH);
|
digitalWrite(RELAY_PIN, LOW); // LOW = включить (NC размыкается)
|
||||||
delay(500);
|
delay(500);
|
||||||
digitalWrite(RELAY_PIN, LOW);
|
digitalWrite(RELAY_PIN, HIGH); // HIGH = выключить
|
||||||
}
|
}
|
||||||
|
|
||||||
String currentIP() {
|
String currentIP() {
|
||||||
@@ -127,20 +128,22 @@ input[type=text],input[type=password]{width:100%;box-sizing:border-box;padding:9
|
|||||||
html += R"(</h2>
|
html += R"(</h2>
|
||||||
<div class='sub'>IP: )";
|
<div class='sub'>IP: )";
|
||||||
html += currentIP();
|
html += currentIP();
|
||||||
html += "</div>";
|
html += " · v" + String(FW_VERSION) + "</div>";
|
||||||
|
|
||||||
if (msg.startsWith("❌"))
|
if (msg.startsWith("❌"))
|
||||||
html += "<div class='err'>" + msg + "</div>";
|
html += "<div class='err'>" + msg + "</div>";
|
||||||
else if (msg.length() > 0)
|
else if (msg.length() > 0)
|
||||||
html += "<div class='msg'>" + msg + "</div>";
|
html += "<div class='msg'>" + msg + "</div>";
|
||||||
|
|
||||||
|
// Управление
|
||||||
html += R"(<div class='card'>
|
html += R"(<div class='card'>
|
||||||
<h3>Управление</h3>
|
<h3>Управление</h3>
|
||||||
<form action='/open' method='get'>
|
<form action='/open' method='post'>
|
||||||
<button class='btn btn-open'>▲ Открыть шлагбаум</button>
|
<button class='btn btn-open'>▲ Открыть шлагбаум</button>
|
||||||
</form>
|
</form>
|
||||||
</div>)";
|
</div>)";
|
||||||
|
|
||||||
|
// Настройки
|
||||||
html += R"(<div class='card'>
|
html += R"(<div class='card'>
|
||||||
<form action='/save' method='post'>
|
<form action='/save' method='post'>
|
||||||
<h3>Устройство</h3>
|
<h3>Устройство</h3>
|
||||||
@@ -148,12 +151,14 @@ input[type=text],input[type=password]{width:100%;box-sizing:border-box;padding:9
|
|||||||
<input type='text' name='name' value=')" + cfg_name + R"('>
|
<input type='text' name='name' value=')" + cfg_name + R"('>
|
||||||
<label>API токен</label>
|
<label>API токен</label>
|
||||||
<input type='text' name='token' value=')" + cfg_token + R"('>
|
<input type='text' name='token' value=')" + cfg_token + R"('>
|
||||||
|
|
||||||
<hr class='sep'>
|
<hr class='sep'>
|
||||||
<h3>Сеть WiFi</h3>
|
<h3>Сеть WiFi</h3>
|
||||||
<label>SSID</label>
|
<label>SSID</label>
|
||||||
<input type='text' name='ssid' value=')" + cfg_ssid + R"('>
|
<input type='text' name='ssid' value=')" + cfg_ssid + R"('>
|
||||||
<label>Пароль</label>
|
<label>Пароль</label>
|
||||||
<input type='password' name='pass' placeholder='оставь пустым — не менять'>
|
<input type='password' name='pass' placeholder='оставь пустым — не менять'>
|
||||||
|
|
||||||
<hr class='sep'>
|
<hr class='sep'>
|
||||||
<h3>IP этого устройства</h3>
|
<h3>IP этого устройства</h3>
|
||||||
<label>Статический IP <span class='hint'>(пусто = DHCP)</span></label>
|
<label>Статический IP <span class='hint'>(пусто = DHCP)</span></label>
|
||||||
@@ -162,10 +167,12 @@ input[type=text],input[type=password]{width:100%;box-sizing:border-box;padding:9
|
|||||||
<input type='text' name='gateway' value=')" + cfg_gateway + R"(' placeholder='например 192.168.15.1'>
|
<input type='text' name='gateway' value=')" + cfg_gateway + R"(' placeholder='например 192.168.15.1'>
|
||||||
<label>Маска подсети</label>
|
<label>Маска подсети</label>
|
||||||
<input type='text' name='subnet' value=')" + cfg_subnet + R"('>
|
<input type='text' name='subnet' value=')" + cfg_subnet + R"('>
|
||||||
|
|
||||||
<button class='btn btn-primary' type='submit'>💾 Сохранить и перезагрузить</button>
|
<button class='btn btn-primary' type='submit'>💾 Сохранить и перезагрузить</button>
|
||||||
</form>
|
</form>
|
||||||
</div>)";
|
</div>)";
|
||||||
|
|
||||||
|
// OTA
|
||||||
html += R"(<div class='card'>
|
html += R"(<div class='card'>
|
||||||
<h3>Обновление прошивки</h3>
|
<h3>Обновление прошивки</h3>
|
||||||
<form action='/update' method='post' enctype='multipart/form-data'>
|
<form action='/update' method='post' enctype='multipart/form-data'>
|
||||||
@@ -183,8 +190,17 @@ void setupRoutes() {
|
|||||||
server.send(200, "text/html", buildPage());
|
server.send(200, "text/html", buildPage());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Открытие через браузер (POST)
|
||||||
|
server.on("/open", HTTP_POST, []() {
|
||||||
|
triggerRelay();
|
||||||
|
server.send(200, "text/html", buildPage("✅ Команда выполнена"));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Открытие от контроллера (GET + токен)
|
||||||
server.on("/open", HTTP_GET, []() {
|
server.on("/open", HTTP_GET, []() {
|
||||||
String token = server.header("X-Token");
|
String token = server.header("X-Token");
|
||||||
|
// Если запрос из браузера (нет токена) — разрешаем
|
||||||
|
// Если запрос от контроллера — проверяем токен
|
||||||
if (token.length() > 0 && token != cfg_token) {
|
if (token.length() > 0 && token != cfg_token) {
|
||||||
server.send(401, "text/plain", "unauthorized");
|
server.send(401, "text/plain", "unauthorized");
|
||||||
return;
|
return;
|
||||||
@@ -235,6 +251,7 @@ void setupRoutes() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Статус
|
||||||
server.on("/status", HTTP_GET, []() {
|
server.on("/status", HTTP_GET, []() {
|
||||||
String json = "{\"name\":\"" + cfg_name + "\",\"ip\":\"" + currentIP() + "\",\"eth\":" + (ethConnected ? "true" : "false") + "}";
|
String json = "{\"name\":\"" + cfg_name + "\",\"ip\":\"" + currentIP() + "\",\"eth\":" + (ethConnected ? "true" : "false") + "}";
|
||||||
server.send(200, "application/json", json);
|
server.send(200, "application/json", json);
|
||||||
@@ -244,7 +261,7 @@ void setupRoutes() {
|
|||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
|
||||||
digitalWrite(RELAY_PIN, LOW);
|
digitalWrite(RELAY_PIN, HIGH); // HIGH = реле выключено (инвертированная логика)
|
||||||
pinMode(RELAY_PIN, OUTPUT);
|
pinMode(RELAY_PIN, OUTPUT);
|
||||||
|
|
||||||
loadConfig();
|
loadConfig();
|
||||||
|
|||||||
Reference in New Issue
Block a user