GyverPortal

onion

✩✩✩✩✩✩✩
1 Авг 2018
4
0

onion

✩✩✩✩✩✩✩
1 Авг 2018
4
0
Поделюсь своей проблемой.
1. Когда кликаю на кнопку ON - LED_BUILTIN отключается
Когда кликаю на кнопку OFF - LED_BUILTIN включается

2. Так же я в код добавил управление лентой, но она не реагирует на кнопки.

C++:
#include <FastLED.h>
#include <ESP8266WiFi.h> 
#include <GyverPortal.h>

GyverPortal portal;

byte bright = 240;
#define NUM_LEDS 120
#define PIN D3
CRGB leds[NUM_LEDS];

// билдер страницы
void build() {
  String s;
  BUILD_BEGIN(s);
  add.THEME(GP_DARK);
  add.BUTTON("on", "ON");
  add.BUTTON("off", "OFF");
 
  BUILD_END();
}

void setup() {
  FastLED.addLeds <WS2812, PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(bright);
 
  pinMode(LED_BUILTIN, OUTPUT);
 
  Serial.begin(9600);
  WiFi.mode(WIFI_STA);
  WiFi.begin("", "");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(WiFi.localIP());

  portal.attachBuild(build);
  portal.start();
}

void loop() {
  portal.tick();

  if (portal.click()) {
    if ( portal.click("on") ) {
      for (int i = 0; i < NUM_LEDS; i++) {
        leds[i].red = 0;
        leds[i].green = 0;
        leds[i].blue = 255;
      }
      
      for (int i = 1; i < 25; i++) {
        leds[i].red = 255;
        leds[i].green = 0;
        leds[i].blue = 0;
      }
      FastLED.setBrightness(bright);
      FastLED.show();
      digitalWrite(LED_BUILTIN, HIGH);
    }

    if ( portal.click("off") ) {
      for (int i = 1; i < 25; i++) {
        leds[i].red = 255;
        leds[i].green = 0;
        leds[i].blue = 0;
      }
      FastLED.setBrightness(bright);
      FastLED.show();
      digitalWrite(LED_BUILTIN, LOW);
    }
  }
}
 

Nils

✩✩✩✩✩✩✩
18 Фев 2022
3
0
Доброго времени!
Прошу направить в нужную сторону. Запутался.
1) Как пример используем библиотеку GyverPortal.h
2) Используем стандартный пример: https://github.com/GyverLibs/GyverPortal/blob/main/examples/demos/demoSubmitAuto/demoSubmitAuto.ino
3) Немного меняем. В результате получаем в браузере два ряда по 2 светодиода и ниже в ряд два переключателя. В зависимости от положения переключателей должны меняться состояния светодиодов.
Не могу понять, как заставить светодиоды (в WEB форме) светиться/не светиться.
Компонент имеет:
LED_RED(имя, состояние); // красный светодиод-индикатор, состояние 1 - светится, состояние 0 - не светится

Вопрос: как сделать, что бы при переключении переключателя светодиод менял состояние автоматически?
ПС: пишу не про встроенные светодиоды, а те что компонент GyverPortal.

Пробный код ниже:
Пример:
// демо с формой, значения компонентов связаны
// с переменными в скетче
#include <GyverPortal.h>

// переменные
bool valSwitch1;
bool valSwitch2;
bool ledState1 = 0;
bool ledState2 = 0;
bool ledState3 = 0;
bool ledState4 = 0;

// билдер страницы
void build() {
  String s;
  BUILD_BEGIN(s);
  //add.AJAX_UPDATE("led1,led2,led3,led4");
  add.THEME(GP_DARK);
  add.FORM_BEGIN("/update");

  add.LABEL("Led-1: "); add.LED_RED("led1", ledState1); add.LED_GREEN("led2", ledState2); add.BREAK();
  add.LABEL("Led-2: "); add.LED_RED("led3", ledState3); add.LED_GREEN("led4", ledState4); add.BREAK();
  add.LABEL("Switch1: "); add.SWITCH("sw1", valSwitch1);  add.BREAK();
  add.LABEL("Switch2: "); add.SWITCH("sw2", valSwitch2);  add.BREAK();

  add.FORM_END();
  BUILD_END();
}

GyverPortal portal;

void setup() {
 
Serial.begin(115200);

  WiFi.mode(WIFI_AP);
  WiFi.softAP("My Portal");
  portal.start(WIFI_AP);   // запускаем портал с настройкой на режим AP

  // подключаем билдер и запускаем
  portal.attachBuild(build);
  portal.start();
  portal.list.init(2);
//  ????
// ????
  portal.list.add(&valSwitch1, "sw1", T_CHECK);
  portal.list.add(&valSwitch2, "sw2", T_CHECK);
}

void loop() {
  portal.tick();

  // одна из форм была submit
  if (portal.form()) {

    // проверяем, была ли это форма "/update"
    if (portal.form("/update")) {

 // выводим для отладки
      Serial.print(valSwitch1);
      Serial.print(valSwitch2);
      Serial.print(valSwitch2);
      Serial.println(ledState1);
      Serial.println(ledState2);
      Serial.println(ledState3);
      Serial.println(ledState4);

// выполняем условие в зависимости от valSwitch1 и valSwitch2   
if (valSwitch1 == 0 && valSwitch2 == 0) {
ledState1 = 0; // присваиваем переменным значения
ledState2 = 0;
ledState3 = 0;
ledState4 = 0;
}

if (valSwitch1 == 1 && valSwitch2 == 0) {
ledState1 = 1;
ledState2 = 0;
ledState3 = 0;
ledState4 = 1;
}

//  .......
 

    }
  }
}
 

kDn

★★★★★✩✩
18 Ноя 2019
1,112
439
https://github.com/GyverLibs/GyverPortal/issues/14 написал(а):
EmbUI https://github.com/DmytroKorniienko/EmbUI
Асинхронная, стабильная, с открытым исходным кодом, есть встроенный клиент mqtt, чутка своеобразен в написании кода, с авто построением интерфейса по коду, есть обратная связь
Написанные на нем популярные для своего круга проект лампы https://github.com/DmytroKorniienko/FireLamp_JeeUI

CRMui https://github.com/WonderCRM/CRMui3
Асинхронная, стабильная, с полу открытым исходным кодом, есть баннер не для коммерческого использования, есть подобие pwa и прост в написании кода, с авто построением интерфейса по коду, есть обратная связь
На его старом интерфейсе написаны часы https://cloud.mail.ru/public/5eHE/dCHUyqrr1/WiFi-CLOCK/

JeeUI https://github.com/jeecrypt/JeeUIFramework
Прародитель EmbUI CRMui
На нем был написан прикольный проектик часов который перешел в CRMui
Все возможности как EmbUI, не полностью доделанная есть кое какие баги, первая версия красивая в плане css, с авто построением интерфейса по коду, есть приложение

WiFiManager https://github.com/tzapu/WiFiManager
Нет асинхронности, большей части ее используют для написания своего проекта для упрощения кода, интерфейс нужно писать или изменить предлагаемый, но есть авто построение меню

Если развивается то в правильную сторону
* В общем если будут вопросы по EmbUI - то на форуме есть тема: https://community.alexgyver.ru/thre...zhnosti-esp8266-esp32-esp32-c3-esp32-s2.5608/ . По варианту же из данной темы - пока промолчу, погляжу что из текущего состояния получится через полгодика-год. Пока же все чуток "сырое".
 

Nils

✩✩✩✩✩✩✩
18 Фев 2022
3
0
kDn
Спасибо за ссылки.
Посмотрел.

А по библиотеке GyverPortal, хочется для себя разобраться. На выходных пробовал разные вариатны, но пока еще нужен знающий, что бы направить в нужную сторону.
 

kDn

★★★★★✩✩
18 Ноя 2019
1,112
439
@Nils, по GyverPortal особо не подскажу, т.к. только код проекта поглядел, но тратить время на подготовку списка проблем не готов. Пока он в самом начале пути и выйдет ли что-то толковое - я хз. Ждите, может кто другой ответит.

Вопрос: как сделать, что бы при переключении переключателя светодиод менял состояние автоматически?
ПС: пишу не про встроенные светодиоды, а те что компонент GyverPortal.
Вообще данная задача решается так - при смене контрола приходит событие в контроллер (сокет, или по вычитыванию состояния), код в ESP анализирует ситуацию и перерисовывает часть (предпочтительно) или весь интерфейс. Альтернатива - менять состояние на клиенте через JavaScript или создать свои контролы со сложным поведением.
 

Nils

✩✩✩✩✩✩✩
18 Фев 2022
3
0
Сам написал, сам разобрался.
В общем путём перебора возможных вариантов, получилось.

управление светодиодом WEB формы переключателем:
// получаем AJAX клики со страницы и значения с компонентов
#include <GyverPortal.h>

// переменные
[B]bool valSwitch1;
bool valSwitch2;[/B]

// билдер страницы
void build() {
  String s;
  BUILD_BEGIN(s);
  add.THEME(GP_DARK);
  [B]add.AJAX_UPDATE(PSTR("led1,led2"));[/B]
  add.TITLE("TITLE", "t1");
  add.HR();
  [B]add.LABEL("Led 1 "); add.LED_RED("led1"); add.LABEL("Led 2 "); add.LED_RED("led2"); add.BREAK();[/B]
  add.HR();
  [B]add.LABEL("Switch-1: "); add.SWITCH("sw1", valSwitch1); add.LABEL("Switch-1: "); add.SWITCH("sw2", valSwitch1); add.BREAK();[/B]
  BUILD_END();
}

GyverPortal portal;

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin("", "");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(WiFi.localIP());

  // подключаем билдер и запускаем
  portal.attachBuild(build);
  portal.start();
}

void loop() {
  portal.tick();

  // был клик по компоненту
  if (portal.click()) {

   // проверяем компоненты и обновляем переменные
    if (portal.click("sw1")) {
      valSwitch1 = portal.getCheck("sw1");
      Serial.print("Switch 1: ");
      Serial.println(valSwitch1);
    }

    if (portal.click("sw2")) {
      valSwitch2 = portal.getCheck("sw2");
      Serial.print("Switch 2: ");
      Serial.println(valSwitch2);
    }
  }
[B]   // как понимаю, если на портале обновилось, valSwitch*, то обновить led*
    if (portal.update()) {
        if (portal.update("led1")) {
        portal.answer(valSwitch1);
        }
        if (portal.update("led2")) {
        portal.answer(valSwitch2);
        }[/B]
   }
}
Всё работает.

Теперь, хочу разобраться как управлять этими светодиодами и двумя дополнительными.
То есть есть два переключателя, с именами sw1 и sw2. Есть два красных светодиода с именами led1 и led2 / и два зеленых соответственно led3 и led4.
Если sw1 и sw2 в состоянии выкл, то все светодиоды выкл
Если sw1 вкл, а sw2 выкл, то
красный led1 - выкл
красный led2 - вкл
зеленый led3 - вкл
зеленый led4 - выкл
Как правильно записать в if (portal.update()) эту конструкцию?

как правильно вписать:
if (portal.update()) {
if (portal.update("led1")) {
      portal.answer(valSwitch1);
    }
if (portal.update("led2")) {
      portal.answer(valSwitch2);
    }
}
 
Изменено:

Phazz

✩✩✩✩✩✩✩
15 Июн 2021
2
0
Подскажите пожалуйста кто-как многостраничность реализовывал?
 

ASM

★★★✩✩✩✩
26 Окт 2018
1,020
198
@Phazz,
я вот так делаю сейчас)
C++:
void build() {
  String i;
  GP_BUILD(i);
i += F("<!DOCTYPE html><html>");
-------------
  GP_SHOW();

  String sw;
  GP_BUILD(sw);
sw += F("<!DOCTYPE html><html>");
-------------
  GP_SHOW();
}
и по логике переходы должны быть такими)
C++:
portal.attachBuild(build(i));
portal.attachBuild(build(sw));
только описания нормального нет, как это все работает))
-----------
логика не верна, попробую несколько порталов запускать, создав свой void под каждую страницу)
C++:
void build_i() {
  String i;
  GP_BUILD(i);
i += F("<!DOCTYPE html><html>");
-------------
  GP_SHOW();
}
void build_sw() {
  String sw;
  GP_BUILD(sw);
sw += F("<!DOCTYPE html><html>");
-------------
  GP_SHOW();
}
вызывать так
    portal.attachBuild(build_i);
    portal.attachBuild(build_sw);
работает))) пользуйся)))

вот и первый баг, по адресу local/update у меня открывалась страница обновления, теперь там загружается страница портала)
 
Изменено:

ASM

★★★✩✩✩✩
26 Окт 2018
1,020
198
@Phazz,
C++:
ловим из формы index
if (portal.form("/index")) {
переходим на страницу
      portal.attachBuild(build_i);
    
    отправка формы index
      sw += F("<form action=\"index\"><button>На главную</button>");
 

oleg.vresh

✩✩✩✩✩✩✩
12 Мар 2022
10
0
Привет парни, столкнулся с такой проблемой, в билде создаю поле ввода номера
C++:
add.NUMBER("minTemp", "Min t", mTemp);
в другом файле пытаюсь обработать нажатие на кнопку
по задумке переменная mTemp по нажатию должна принять значения числа в поле NUMBER

C++:
if (portal.click("tempSetBtn"))              //если нажата кнопка tempSetBtn
      {
        mTemp = portal.getInt("minTemp");
        Serial.println(mTemp);
      }
проблема в том, что почему-то mTemp всегода ==0. Такое ощущение что не отрабатывает метод getInt(). но почему не могу понять. Может я что-то недопередаю в getInt()?
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
3,792
1,146
Москва
Очень часто такое бывает когда minTemp изначально равна 0, а реальная минимальная температура еще не стала ниже. Вот если задать начальное значение minTemp скажем 10 000, то тогда 1-ое же значение должно будет заменить ее на реальную.
Это в порядке пьяного бреда и не вдаваясь в подробности
 
  • Лойс +1
Реакции: oleg.vresh

oleg.vresh

✩✩✩✩✩✩✩
12 Мар 2022
10
0
@Старик Похабыч, спасибо за ответ. тут идея в том, чтобы в переменную mTemp передать значение из поля number.
mTemp это параметр задаваемый пользователем. Пользователь в веб морде вводит в поле "minTemp" это значение. И нажимает кнопку setTempBtn. Переменная int mTemp принимает значение строки "minTemp" преобразованное методом getInt.
Но почему-то не срабатывает именно getInt

C++:
Serial.print(portal.getInt("minTemp");
Такая конструкция тоже возвращает ноль, при любом значении в поле number.
Примечательно то, что slider тоже обрабатывается getInt() -ом, и из него тоже возвращается ноль.
Попытки задать начальное значени отличное от нуля, на результат не повлияли.
 
Изменено:

oleg.vresh

✩✩✩✩✩✩✩
12 Мар 2022
10
0
@Phazz,
Многостраничность понятие сугубо индивидуальное. Зависит от того как это должно работать.
У меня есть диспетчер загрузки в точке доступа, в котором выбирается нужный режим работы устройства. И вводятся нужные параметры. В зависимости от введёных параметров, загружается нужная страница. Тоже своего рода многостраничность. организовать полноценную навигацию, пока задачи не было. Но я бы наверное по кнопке вызывал функцию, в которой бы собиралась страница.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
3,792
1,146
Москва
Сейчас вопрос задан таким образом , что можно только догадки строить.
Например: я получаю число из сериал-порта в виде текста и перевожу его целое. Клиент говорит, что отрабатывается это число и сразу сбрасывается. Ответ: при передаче заказа я оговорил, что передавать надо только числа, без возврата каретки и перевода строки. Получается, что код забирает число и после этого забирает еще 1 или 2 символа, которые пытается перевести в целое число. И при неудаче возвращает 0.

Тут число int подразумевает целое число. Точно вводится целое, а не дробное число ?
 
  • Лойс +1
Реакции: Boroda22

allexnero

✩✩✩✩✩✩✩
16 Мар 2022
1
0
Привет, хочу с помощью gyverportal задавать настройки и ставить будильник в проекте. Проблема возникла с сохранением времени для будильника. GPtime не хочет записываться в EEPROM. Подскажите куда копать или как можно сохранить заданное время.
 

oleg.vresh

✩✩✩✩✩✩✩
12 Мар 2022
10
0
@allexnero, у меня та же самая идея, только еще не добрался до этого этапа. Не буду умничать, по тому, как еще сам не знаю как буду это реализовывать, но я планировал подсмотреть как это сделано у Гайвера в лампе, там у него была функция будильника. уверен там есть готовая реализация сохранения. Извини, что ничего дельного не подсказал.
 

oleg.vresh

✩✩✩✩✩✩✩
12 Мар 2022
10
0
Парни, у кого есть опыт добавления своего кода на страницу, может сталкивались...
такая конструкция прекрасно работает:

C++:
s += F("<script> alert('Hello world')</script>");
но если скрипт js или html вынести в отдельную строку (объект класса String) , вот так:

C++:
String hello = "<script> alert('Hello world')</script>";
s += F(hello);
то при компиляции получаем седущее:

initializer fails to determine size of 'pstr'

Что я делаю не так?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
3,792
1,146
Москва
F работает только с константами, переменные в них нельзя указывать, т.к. размещение идет не в оперативной памяти. а в постоянной, и она вся подсчитывается заранее
 
  • Лойс +1
Реакции: oleg.vresh

poty

★★★★★★✩
19 Фев 2020
2,257
692
F() работает только со строками, расположенными в PROGMEM.
 
  • Лойс +1
Реакции: oleg.vresh

bort707

★★★★★★✩
21 Сен 2020
2,500
760
@oleg.vresh, если у вас строка не константа, просто не используйте F(), вот так:
C++:
String hello = "<script> alert('Hello world')</script>";
s += hello;
 
  • Лойс +1
Реакции: oleg.vresh

bort707

★★★★★★✩
21 Сен 2020
2,500
760
@oleg.vresh, для начала обьясните, зачем вам обязательно нужно засунуть строчку в переменную Hello и чем вас не устраивает запись
C++:
s += F("<script> alert('Hello world')</script>");
которая, как вы пишете, работает?
Если вы это делаете затем, чтобы потом в ходе программы переменную hello менять - тогда вы в принципе идете в неверном направлении. Опишите, что вы хотите сделать - может быть это все значительно проще
 
  • Лойс +1
Реакции: oleg.vresh