SuplaDevice 2.4.2

User avatar
klew
Posts: 8356
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

Wersja 2.4.2 jest już dostępna do pobrania w menadżerze bibliotek w Arduino.

Poza Arduino IDE biblioteka wspiera również kompilacje bezpośrednio na ESP8266 RTOS SDK, oraz na ESP32 ESP-IDF SDK. Podstawowe funkcjonalności, oparte o sterowanie przekaźnikami, czy też przyciski już działają. Bardziej skomplikowane tematy, takie jak termometry itp. jeszcze nie.
SuplaDevice można też używać pod Linuxem (np. na raspberry pi, beaglebone, lub na dowolnym PC-ie z Linuxem) - więcej informacji tutaj: viewtopic.php?t=10735

Najważniejsze nowości dotyczące Arduino IDE, to:
- dodanie możliwości przełączania urządzenia w tryb konfiguracyjny
- automatyczne generowanie GUID i Authkey
- webowy interfejs do konfiguracji urządzenia (parametry Wi-Fi, połączenie z serwerem Supli) poprzez stronę http://192.168.4.1

Kilka innych nowości:
- klasa VirtualThermometer (kanał termometru, którego wartość można ustawiać w programie poprzez wywołanie odpowiednich metod)
- klasa VirtualThermHygroMeter (j/w tylko dla temperatury oraz wilgotności)
- RGB, RGBW, dimmer - możliwość ograniczenia min/max wartości ustawianych na wyjściu

I wiele innych mniejszych zmian - pełna lista dostępna tutaj: https://github.com/SUPLA/supla-arduino/ ... ANGELOG.md

W Arduino IDE pojawił się też nowy przykład WebInterface, który pokazuje co jest potrzebne do użycia nowych funkcji związanych z trybem konfiguracyjnym oraz interfesjem www.
Interfejs webowy jest dostępny tylko dla układów ESP82xx oraz ESP32. Konfiguracja jest przechowywana w pliku przy użyciu LittleFs (UWAGA: jeśli ktoś używa w swoim programie SPIFS i doda LittleFs, to utraci zapisane dane i nic nie będzie działać poprawnie).
Klasa dziedzicząca po Supla::Config (w tym przypadku Supla::LittleFsConfig) jest konieczna do przechowywania konfiguracji urządzenia, oraz do generowania GUID i Authkey.
Za intefejs webowy odpowiada klasa Supla::EspWebServer, natomiast za to co jest wyświetlane na interfejsie webowym odpowiadając klasy Supla::Html::
Każdy element HTML-owy musi dziedziczyć po klasie Supla::Html::Element (a jakże ;) ) i powinien implementować metodę: send oraz handleResponse. Metoda send odpowiada za generowanie HTML'a, który ma być wyświetlony, a metoda handleResponse odpowiada za przetworzenie odpowiedzi.
Za przykład posłuży nam klasa StatusLedParameters, która odpowiada za konfigurację diody, która miga zgodnie ze stanem naszego urządzenia.
Tak wygląda metoda send: https://github.com/SUPLA/supla-arduino/ ... rs.cpp#L37
W tej metodzie dobieramy się do instancji klasy trzymającej konfigurację. Następnie odczytujemy wartość parametru "statusLed" i generujemy HTML'a. W tym przypadku jest to lista drop-down.
Tak wygląda metoda handleResponse: https://github.com/SUPLA/supla-arduino/ ... rs.cpp#L61
Metoda zwraca "true", gdy dany parametr jej dotyczył i gdy przetworzyliśmy daną wartość. Bibliteka po otrzymaniu formularza z intefejsu webowego przekazauje każdy parametr i jego wartość do klas Html::Element i wywołuje na nich metodę "handleResponse". Ta metoda sprawdza, czy kluczu/key dotyczy danego elementu i jeśli tak, to przetwarza wartość parametru i zapisuje np. do konfiguracji.

Ostatni element potrzebny, aby to wszystko zadziałało, to umiejętność odczytu konfiguracji przez klasę Supla::Device::StatusLed. W tym przypadku, kofigurację odczytujemy w metodzie onLoadConfig: https://github.com/SUPLA/supla-arduino/ ... ed.cpp#L29
Metoda ta jest odpalana wewnątrz SuplaDevice.begin przed metodą onInit.
Widzimy się na Supla Offline Party vol. 2 :!:
User avatar
shimano73
Posts: 1976
Joined: Sun Feb 28, 2016 12:27 pm
Location: Orzesze

Post

Stworzyłem sobie listę wyboru
Tak wygląda biblioteka

Code: Select all

namespace Supla {

namespace Html {

ProgramSelection::ProgramSelection() : HtmlElement(HTML_SECTION_FORM) {
}

ProgramSelection::~ProgramSelection() {
}

void ProgramSelection::send(Supla::WebSender* sender) {
  auto cfg = Supla::Storage::ConfigInstance();
  if (cfg) {
    int8_t value = 0;
    cfg->getInt8("program_nr", &value);

    sender->send(
        "<i><select name=\"prog_nr\">"
        "<option value=\"0\"");
    sender->send(selected(value == 0));
    sender->send(
        ">STANDARD</option>"
        "<option value=\"1\"");
    sender->send(selected(value == 1));
    sender->send(
        ">STANDARD-1</option>"
        "<option value=\"2\"");
    sender->send(selected(value == 2));
    sender->send(
        ">STANDARD-2</option>"
        "<option value=\"3\"");
    sender->send(selected(value == 3));
    sender->send(
        ">STANDARD-3</option>"
        "<option value=\"4\"");
    sender->send(selected(value == 4));
    sender->send(
        ">STANDARD+3</option>"
        "<option value=\"5\"");
    sender->send(selected(value == 5));
     sender->send(
        ">STANDARD+2</option>"
        "<option value=\"6\"");
    sender->send(selected(value == 6));
    sender->send(
        ">STANDARD+1</option>"
        "<option value=\"7\"");
    sender->send(selected(value == 7));
    sender->send(
        ">NON STOP</option>"
        "<option value=\"8\"");
    sender->send(selected(value == 8));
    sender->send(
        ">HOLIDAYS</option></select>"
        "<label>Wybór programu</label></i>");
  }
}

bool ProgramSelection::handleResponse(const char* key, const char* value) {
  auto cfg = Supla::Storage::ConfigInstance();
  if (strcmp(key, "prog_nr") == 0) {
    int nr_prog = stringToUInt(value);
    switch (nr_prog) {
      default:
      case 0: {
        cfg->setInt8("program_nr", 0);
        break;
      }
      case 1: {
        cfg->setInt8("program_nr", nr_prog);
        break;
      }
      case 2: {
        cfg->setInt8("program_nr", nr_prog);
        break;
      }
      case 3: {
        cfg->setInt8("program_nr", nr_prog);
        break;
      }
      case 4: {
        cfg->setInt8("program_nr", nr_prog);
        break;
      }
      case 5: {
        cfg->setInt8("program_nr", nr_prog);
        break;
      }
      case 6: {
        cfg->setInt8("program_nr", nr_prog);
        break;
      }
      case 7: {
        cfg->setInt8("program_nr", nr_prog);
        break;
      }
      case 8: {
        cfg->setInt8("program_nr", nr_prog);
        break;
      }
    }
    return true;
  }
  return false;
}

};  // namespace Html
};  // namespace Supla

Chyba działa bo zmienia się wartość

Code: Select all

  SERVER: key prog_nr, value 8
chciałbym powiązać wybrany nr programu z elementem tablicy, ale nie wiem jak :(
You do not have the required permissions to view the files attached to this post.
W elektronice jak nie wiadomo o co chodzi to zwykle chodzi o zasilanie

Wezmę udział w Supla Offline Party 2024 :)
User avatar
klew
Posts: 8356
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

shimano73 wrote: Tue Jun 21, 2022 7:37 pm chciałbym powiązać wybrany nr programu z elementem tablicy, ale nie wiem jak :(
Nie rozumiem co tutaj napisałeś. Z jakiej tablicy? Co chcesz z tym dalej zrobić?
Widzimy się na Supla Offline Party vol. 2 :!:
User avatar
shimano73
Posts: 1976
Joined: Sun Feb 28, 2016 12:27 pm
Location: Orzesze

Post

No tak mało precyzyjnie , najlepiej jak pokaże to na przykładzie :

Code: Select all

int tab_time[8] = {60,120,180,240,240,180,120,60};


void loop() {

    if (Automat->isOn()) {
    if ((Pump->isOn()) and  (millis() - pm_lastmillis >= tab_time[nr_programu*1000)) {
        pm_lastmillis = millis();  
        Pump -> turnOff();
    }
    if ( !(Pump->isOn()) and  (millis() - pm_lastmillis >= tab_time[nr_programu]*1000))) {
        pm_lastmillis = millis();
        Pump->turnOn(); 
    }        
    // i dalej coś tam , coś tam  :lol: 
Jak ustawić wartość zmiennej nr_programu w zależności od wybranego programu w konfiguracji /
W elektronice jak nie wiadomo o co chodzi to zwykle chodzi o zasilanie

Wezmę udział w Supla Offline Party 2024 :)
User avatar
klew
Posts: 8356
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

shimano73 wrote: Wed Jun 22, 2022 5:30 am No tak mało precyzyjnie, najlepiej jak pokaże to na przykładzie :

Code: Select all

int tab_time[8] = {60, 120, 180, 240, 240, 180, 120, 60};

void loop() {
  if (Automat->isOn()) {
    int8_t nr_programu = 0;
    Supla::Storage::ConfigInstance->getInt8("program_nr", &nr_programu);
    if ((Pump->isOn()) and (millis() - pm_lastmillis >= tab_time[nr_programu]*1000)) {
      pm_lastmillis = millis();
      Pump->turnOff();
    }
    if (!(Pump->isOn()) and
        (millis() - pm_lastmillis >= tab_time[nr_programu] * 1000))) {
          pm_lastmillis = millis();
          Pump->turnOn();
        }
  }
}
nr_programu pewnie nie zmienia się w trakcie pracy układu, więc odczyt można przenieść do "setup" (tylko daj za SuplaDevice.begin() ).
Warto też sprawdzać czy odczyt się udał (getInt8 zwraca true gdy odczyt się udał), oraz czy wartość zmiennej nr_programu mieści się w rozmiarach tablicy tab_time.
Widzimy się na Supla Offline Party vol. 2 :!:
User avatar
shimano73
Posts: 1976
Joined: Sun Feb 28, 2016 12:27 pm
Location: Orzesze

Post

Niestety jest jakiś problem z kompilacją
Arduino:1.8.16 (Windows 7), Płytka:"Generic ESP8266 Module, 80 MHz, Flash, Disabled (new aborts on oom), Disabled, All SSL ciphers (most compatible), 32KB cache + 32KB IRAM (balanced), Use pgm_read macros for IRAM/PROGMEM, dtr (aka nodemcu), 26 MHz, 40MHz, DOUT (compatible), 4MB (FS:2MB OTA:~1019KB), 2, nonos-sdk 2.2.1+100 (190703), v2 Lower Memory, Disabled, None, All Flash Contents, 115200"

Code: Select all

C:\Users\Supla\Documents\Arduino\WebInterface\WebInterface.ino: In function 'void setup()':

WebInterface:96:37: error: request for member 'getInt8' in '* Supla::Storage::ConfigInstance', which is of non-class type 'Supla::Config*()'

   96 |     Supla::Storage::ConfigInstance->getInt8("program_nr", &nr_programu);

      |                                     ^~~~~~~

exit status 1

request for member 'getInt8' in '* Supla::Storage::ConfigInstance', which is of non-class type 'Supla::Config*()'


W elektronice jak nie wiadomo o co chodzi to zwykle chodzi o zasilanie

Wezmę udział w Supla Offline Party 2024 :)
User avatar
klew
Posts: 8356
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

Powinno być "ConfigInstance()" (z nawiasami)
Widzimy się na Supla Offline Party vol. 2 :!:
User avatar
shimano73
Posts: 1976
Joined: Sun Feb 28, 2016 12:27 pm
Location: Orzesze

Post

klew wrote: Wed Jun 22, 2022 11:40 am Powinno być "ConfigInstance()" (z nawiasami)
działa, dziękuję za pomoc
W elektronice jak nie wiadomo o co chodzi to zwykle chodzi o zasilanie

Wezmę udział w Supla Offline Party 2024 :)
Zibi
Posts: 615
Joined: Wed Jul 31, 2019 9:20 am
Location: Białogard

Post

@klew idziesz jak burza Gratulacje!
Próbowałem odpalić przykład WebInterface ale ciągle pluje mi błedem Bład kompilacji dla płytki ESP8266.

Code: Select all

In file included from D:\Arduino 1.8.16 AT Supla\arduino-ide-portable_1.8.16\arduino-1.8.16\libraries\supla-arduino-master\examples\WebInterface\WebInterface.ino:40:0:

D:\Arduino 1.8.16 AT Supla\arduino-ide-portable_1.8.16\arduino-1.8.16\libraries\supla-arduino-master\src/supla/network/esp_wifi.h: In member function 'virtual void Supla::ESPWifi::setup()':

D:\Arduino 1.8.16 AT Supla\arduino-ide-portable_1.8.16\arduino-1.8.16\libraries\supla-arduino-master\src/supla/network/esp_wifi.h:140:12: error: 'class ESP8266WiFiClass' has no member named 'setHostname'

       WiFi.setHostname(hostname);

            ^

D:\Arduino 1.8.16 AT Supla\arduino-ide-portable_1.8.16\arduino-1.8.16\libraries\supla-arduino-master\src/supla/network/esp_wifi.h:217:12: error: 'class ESP8266WiFiClass' has no member named 'setHostname'

       WiFi.setHostname(hostname);

            ^

Znaleziono wiele bibliotek w "ESP8266WiFi.h"

Wykorzystane: C:\Users\Lenovo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266WiFi

Niewykorzystane: D:\Arduino 1.8.16 AT Supla\arduino-ide-portable_1.8.16\arduino-1.8.16\libraries\ESP8266WiFi

exit status 1

Błąd kompilacji dla płytki Generic ESP8266 Module.
User avatar
klew
Posts: 8356
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

Zibi wrote: Thu Jun 23, 2022 8:15 am @klew idziesz jak burza Gratulacje!
Próbowałem odpalić przykład WebInterface ale ciągle pluje mi błedem Bład kompilacji dla płytki ESP8266.

Code: Select all

In file included from D:\Arduino 1.8.16 AT Supla\arduino-ide-portable_1.8.16\arduino-1.8.16\libraries\supla-arduino-master\examples\WebInterface\WebInterface.ino:40:0:

D:\Arduino 1.8.16 AT Supla\arduino-ide-portable_1.8.16\arduino-1.8.16\libraries\supla-arduino-master\src/supla/network/esp_wifi.h: In member function 'virtual void Supla::ESPWifi::setup()':

D:\Arduino 1.8.16 AT Supla\arduino-ide-portable_1.8.16\arduino-1.8.16\libraries\supla-arduino-master\src/supla/network/esp_wifi.h:140:12: error: 'class ESP8266WiFiClass' has no member named 'setHostname'

       WiFi.setHostname(hostname);

            ^

D:\Arduino 1.8.16 AT Supla\arduino-ide-portable_1.8.16\arduino-1.8.16\libraries\supla-arduino-master\src/supla/network/esp_wifi.h:217:12: error: 'class ESP8266WiFiClass' has no member named 'setHostname'

       WiFi.setHostname(hostname);

            ^

Znaleziono wiele bibliotek w "ESP8266WiFi.h"

Wykorzystane: C:\Users\Lenovo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\ESP8266WiFi

Niewykorzystane: D:\Arduino 1.8.16 AT Supla\arduino-ide-portable_1.8.16\arduino-1.8.16\libraries\ESP8266WiFi

exit status 1

Błąd kompilacji dla płytki Generic ESP8266 Module.
Pewnie masz jakiąś starą wersję boardów dla ESP8266.
Jeśli nie aktualizuje Ci się, to upewnij się, że dla ESP8266 masz ustawione:
https://arduino.esp8266.com/stable/pack ... index.json
A dla ESP32:
https://raw.githubusercontent.com/espre ... index.json
Widzimy się na Supla Offline Party vol. 2 :!:

Return to “Arduino IDE”