На самом деле всё гораздо проще. Вчера минут за 15-20 написал и опробовал custom функции создания таблиц. Есть одна прелесть в таблицах - объединение ячеек по вертикале и по горизонтали. Так же классная вещь - вертикальное выравнивание. Вёрстка таблицами очень простая, и очень быстрая. Наверное есть ещё один факт - для задания ширины столбцов, достаточно её указывать только в первой строке, столбцы следующих строк автоматом подтянут ширину. Прелесть портала в том, что есть файл custom.h, где можно без проблем делать свои функции, при загрузке новой либры, главное не забыть перекинуть этот файл и всё дальше будет работать.@ASM, таблица это + пару килограмм кода, не Москву пишу
#define AP_SSID ""
#define AP_PASS ""
#include <LittleFS.h>
#include <GyverPortal.h>
GyverPortal portal(&LittleFS);
// конструктор страницы
void build() {
//для подключения скриптов из файла /gp_data/scripts.js
GP.BUILD_BEGIN_FILE();
//для подключения файла css и js в папке с проектом надо создать папку data, в ней надо создать gp_data и туда положить файл GP_DARK.css
// с помощью инструментов залить файлы на ESP32
GP.THEME_FILE("GP_DARK")
// Если используется обновление через jquery
GP.JQ_SUPPORT_FILE(); // Загрузка jquery /gp_data/jquery.js (он по факту 1 раз грузанёт и закешет, но его тоже надо положить в папку)
//тут Ваш код конструктора
GP.BUILD_END();
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(AP_SSID, AP_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(WiFi.localIP());
if (!LittleFS.begin()) Serial.println("FS Error");
portal.attachBuild(build);
portal.attach(action);
portal.start();
portal.downloadAuto(true); //включите автодовнлоад
}
void action() {
// код обработчика
}
void loop() {
portal.tick();
}
void setup()
{
// delay(2000);
Serial.begin(115200);
LittleFS.begin();
portal.downloadAuto(true);
portal.uploadAuto(true);
if (!digitalRead(D2))
nvsFlashErase();
Serial.println();
preferences.begin("WiFiLPI", false);
ssid = preferences.getString("ssid");
pass = preferences.getString("pass");
APssid = preferences.getString("apssid");
APpass = preferences.getString("appass");
IPadress = preferences.getString("wifistaip");
APIPadress = preferences.getString("wifiapip");
chkAP = preferences.getBool("chkap");
chkSTA = preferences.getBool("chksta");
Serial.println("chkAP" + String(chkAP));
Serial.println("chkSTA" + String(chkSTA));
if (chkAP == 1 && chkSTA == 1) {
WiFi.mode(WIFI_MODE_APSTA);
wifiAPConnect();
wifiStaConnect();
} else if (chkSTA) {
WiFi.mode(WIFI_MODE_STA);
wifiStaConnect();
APIPadress = "не получен";
if (WiFi.status() != WL_CONNECTED) {
WiFi.mode(WIFI_MODE_AP);
wifiAPConnect();
}
} else {
WiFi.mode(WIFI_MODE_AP);
wifiAPConnect();
IPadress = "не получен";
}
portal.enableOTA();
portal.attachBuild(buildLP);
portal.attach(actionLP);
portal.start();
preferences.putString("wifistaip", IPadress);
preferences.putString("wifiapip", APIPadress);
if (!LittleFS.begin())
Serial.println("FS Error");
}
void loop() { portal.tick(); }
//#include <EEPROM.h>
#include <GyverPortal.h>
#include <LittleFS.h>
#include <Preferences.h>
#include <nvs_flash.h>
#define D2 14
int timeConnect = 0;
String ssid;
String pass;
String APssid = "SAM";
String APpass = "12345678";
String IPadress;
String APIPadress;
bool chkAP = 1;
bool chkSTA = 1;
Preferences preferences;
GyverPortal portal(&LittleFS);
void wifiStaConnect()
{
// WiFi.mode(WIFI_STA);
WiFi.begin(ssid.c_str(), pass.c_str());
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
if (timeConnect > 10)
break;
else
timeConnect++;
}
if (WiFi.status() == WL_CONNECTED) {
IPadress = WiFi.localIP().toString();
} else {
APIPadress = WiFi.softAPIP().toString();
IPadress = "не выдан";
}
Serial.println();
Serial.println("STA ssid: " + ssid);
Serial.println("STA IP адрес: " + IPadress);
preferences.putString("wifistaip", IPadress);
}
void wifiAPConnect()
{
WiFi.softAP(APssid.c_str(), APpass.c_str());
APIPadress = WiFi.softAPIP().toString();
Serial.println();
Serial.println("AP ssid: " + APssid);
Serial.println("AP IP адрес: " + APIPadress);
preferences.putString("wifiapip", APIPadress);
};
void buildLP()
{
// BUILD_BEGIN();
GP.BUILD_BEGIN_FILE();
//GP.THEME(GP_DARK);
GP.THEME_FILE("GP_LIGHT");
//GP.JQ_SUPPORT(); // поддержка jquery. Файл скачается с https://code.jquery.com/
GP.JQ_SUPPORT_FILE(); // поддержка jquery, файл скачается из файла /gp_data/jquery.js
GP.NAV_TABS_LINKS("/,/settings,/updates", "Главная,Настройки,Обновление");
if (portal.uri("/settings")) {
GP.BUTTON_LINK("/login", "WiFi");
GP.BUTTON_LINK("/", "Back");
}
if (portal.uri("/login")) {
GP.FORM_BEGIN("/login");
GP_MAKE_BLOCK_TAB("Авторизация -клиент",
GP_MAKE_BOX(GP.LABEL("Логин"); GP.TEXT("lg", "Логин", ssid););
GP_MAKE_BOX(GP.LABEL("Пароль"); GP.PASS("ps", "Пароль", pass););
GP_MAKE_BOX(GP.LABEL("Включить"); GP.CHECK("chksta", chkSTA););
GP.LABEL("IP адрес " + IPadress););
GP_MAKE_BLOCK_TAB("Авторизация -точка доступа",
GP_MAKE_BOX(GP.LABEL("Логин"); GP.TEXT("aplg", "Логин", APssid););
GP_MAKE_BOX(GP.LABEL("Пароль"); GP.PASS("apps", "Пароль", APpass););
GP_MAKE_BOX(GP.LABEL("Включить"); GP.CHECK("chkap", chkAP););
GP.LABEL("IP адрес " + APIPadress););
GP.SUBMIT("Подтвердить");
GP.FORM_END();
}
else {
GP.FORM_BEGIN("/");
GP.BUTTON_LINK("/save", "Form");
GP.BUTTON_LINK("/clicks", "Clicks");
GP.BUTTON_LINK("/updates", "Updates");
GP.FORM_END();
}
BUILD_END();
}
void actionLP(GyverPortal& p)
{
if (p.form()) {
if (p.form("/login")) { // кнопка нажата
p.copyString("lg", ssid); // копируем себе
p.copyString("ps", pass);
p.copyString("aplg", APssid); // копируем себе
p.copyString("apps", APpass);
p.copyBool("chkap", chkAP);
p.copyBool("chksta", chkSTA);
if (chkAP == 0 && chkSTA == 0)
chkAP = 1;
preferences.putString("ssid", ssid);
preferences.putString("pass", pass);
preferences.putString("apssid", APssid);
preferences.putString("appass", APpass);
preferences.putBool("chksta", chkSTA);
preferences.putBool("chkap", chkAP);
Serial.println("start ");
Serial.println("Connect to: ");
Serial.println(ssid);
wifiStaConnect();
Serial.print("Restart ");
preferences.end();
ESP.restart();
}
}
}
void nvsFlashErase()
{
Serial.println("erase nvs");
nvs_flash_erase(); // erase the NVS partition and...
nvs_flash_init(); // initialize the NVS partition.
while (true)
;
ESP.restart();
}
void setup()
{
// delay(2000);
Serial.begin(115200);
LittleFS.begin();
portal.downloadAuto(true);
portal.uploadAuto(true);
if (!digitalRead(D2))
nvsFlashErase();
Serial.println();
preferences.begin("WiFiLPI", false);
ssid = preferences.getString("ssid");
pass = preferences.getString("pass");
APssid = preferences.getString("apssid");
APpass = preferences.getString("appass");
IPadress = preferences.getString("wifistaip");
APIPadress = preferences.getString("wifiapip");
chkAP = preferences.getBool("chkap");
chkSTA = preferences.getBool("chksta");
Serial.println("chkAP" + String(chkAP));
Serial.println("chkSTA" + String(chkSTA));
if (chkAP == 1 && chkSTA == 1) {
WiFi.mode(WIFI_MODE_APSTA);
wifiAPConnect();
wifiStaConnect();
} else if (chkSTA) {
WiFi.mode(WIFI_MODE_STA);
wifiStaConnect();
APIPadress = "не получен";
if (WiFi.status() != WL_CONNECTED) {
WiFi.mode(WIFI_MODE_AP);
wifiAPConnect();
}
} else {
WiFi.mode(WIFI_MODE_AP);
wifiAPConnect();
IPadress = "не получен";
}
portal.enableOTA();
portal.attachBuild(buildLP);
portal.attach(actionLP);
portal.start();
preferences.putString("wifistaip", IPadress);
preferences.putString("wifiapip", APIPadress);
if (!LittleFS.begin())
Serial.println("FS Error");
}
void loop() { portal.tick(); }
Полностью согласен.Ну в ишью уже было это, платформио заноза в задинице(слова Алекса) при работе с esp
const char* ssid = "ESP8266-Access-Point";
const char* password = "123456789";
#include <GyverPortal.h>
GyverPortal portal;
bool led = false;
bool led1 = false;
bool led2 = false;
bool led3 = false;
void build() {
GP.BUILD_BEGIN();
GP.THEME(GP_DARK);
GP.UPDATE("led,led1,led2,led3");
GP.TITLE("Title", "t1");
GP.HR();
GP.LED_RED("led", led);
GP.BUTTON("btn1", "Button1", "", GP_GRAY);
GP.BUTTON("btn2", "Button2", "", GP_GRAY);
GP.HR();
GP_MAKE_BOX(GP.UPDATE("led1"); GP.LED_RED("led1", led1); GP.BUTTON("btn3", "Button1", "", GP_GRAY););
GP_MAKE_BOX(GP.UPDATE("led2"); GP.LED_RED("led2", led2); GP.BUTTON("btn4", "Button2", "", GP_GRAY););
GP_MAKE_BOX(GP.UPDATE("led3"); GP.LED_RED("led3", led3); GP.BUTTON("btn5", "Button3", "", GP_GRAY););
GP.BUILD_END();
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password);
// подключаем конструктор и запускаем
portal.attachBuild(build);
portal.attach(action);
portal.start(WIFI_AP);
}
void action() {
if (portal.update()) {
if (portal.update("led")) portal.answer(led);
if (portal.update("led1")) portal.answer(led1);
if (portal.update("led2")) portal.answer(led2);
if (portal.update("led3")) portal.answer(led3);
}
// был клик по компоненту
if (portal.click()) {
// проверяем компоненты и обновляем переменные
if (portal.click("btn1")) {
Serial.println("Button1 click");
led = true;
}
if (portal.click("btn2")) {
Serial.println("Button1 click");
led = false;
}
if (portal.click("btn3")) {
Serial.println("Button1 click");
led1 = true; led2 = false; led3 = false;
}
if (portal.click("btn4")) {
Serial.println("Button1 click");
led1 = false; led2 = true; led3 = false;
}
if (portal.click("btn5")) {
Serial.println("Button1 click");
led1 = false; led2 = false; led3 = true;
}
}
}
void loop() {
portal.tick();
}
Интересно.Если кому интересно, могу подробнее, но уже не сегодня... А вообще в вики там есть пару слов про это
const char* ssid = "ESP8266-Access-Point";
const char* password = "123456789";
#include <GyverPortal.h>
GyverPortal portal;
bool led = false;
bool led1 = true;
bool led2 = false;
bool led3 = false;
int sel = 0;
void build() {
//Устанавливаем время в мс, то есть после нажатия на кнопки через заданное кол-во мс будет перезагрузка страницы
GP.setReloadTimeout(150);
GP.BUILD_BEGIN();
GP.THEME(GP_DARK);
GP.TITLE("Title", "t1");
GP.HR();
GP.LED_RED("led", led);
//Кнопка в режиме триггера, хотя я бы юзал switch, просто для примера
GP.BUTTON_MINI("led","0","",led?GP_RED:GP_GREEN,"",false,true);
GP.HR();
//3 кнопки в режиме третичного триггера
GP_MAKE_BOX(
GP.BUTTON_MINI("led1","-1-","",led1?GP_GREEN:GP_RED,"",false,true);
GP.BUTTON_MINI("led2","-2-","",led2?GP_GREEN:GP_RED,"",false,true);
GP.BUTTON_MINI("led3","-3-","",led3?GP_GREEN:GP_RED,"",false,true);
);
GP.SELECT("sel","btn1,btn2,btn3", sel,false,false,true);
GP.BUILD_END();
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, password);
// подключаем конструктор и запускаем
portal.attachBuild(build);
portal.attach(action);
portal.start(WIFI_AP);
}
void action() {
// был клик по компоненту
if (portal.click()) {
// проверяем компоненты и обновляем переменные
if (portal.click("led")) {
Serial.println("Button1 click");
led = !led;
}
if (portal.click("led1")) {
Serial.println("Button1 click");
led1 = true; led2 = false; led3 = false;sel=0;
}
if (portal.click("led2")) {
Serial.println("led2 click");
led1 = false; led2 = true; led3 = false;sel=1;
}
if (portal.click("led3")) {
Serial.println("led3 click");
led1 = false; led2 = false; led3 = true;sel=2;
}
if (portal.click("sel")) {
Serial.println("sel click");
sel=portal.getInt("sel");
if (sel==0){
led1 = true; led2 = false; led3 = false;
} else if (sel==1){
led1 = false; led2 = true; led3 = false;
} else if (sel==2){
led1 = false; led2 = false; led3 = true;
}
}
}
}
void loop() {
portal.tick();
}