Code: Select all
auto output_1 = new Supla::Control::InternalPinOutput(OUTPUT_GPIO_1,false); Code: Select all
auto output_1 = new Supla::Control::InternalPinOutput(OUTPUT_GPIO_1,false); https://github.com/SUPLA/supla-device/b ... nfig.h#L39Duch__ wrote: Sun Nov 10, 2024 8:13 pm Jak wyciągnąć informacje że moduł aktualnie jest w trybie konfiguracji?
Code: Select all
if (SuplaDevice.getDeviceMode() == Supla::DEVICE_MODE_NORMAL) {
// NORMAL MODE
}
if (SuplaDevice.getDeviceMode() == Supla::DEVICE_MODE_CONFIG) {
// CONFIG MODE
}Code: Select all
/*
Copyright (C) AC SOFTWARE SP. Z O.O
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define MAX_SLEEP_TIME_SEC 240
#ifdef ARDUINO_ARCH_AVR
#error "This example is not supported on Arduino AVR"
#endif
#include <SuplaDevice.h>
#include <supla/storage/eeprom.h>
#include <supla/network/esp_wifi.h>
#include <supla/device/status_led.h>
#include <supla/storage/littlefs_config.h>
#include <supla/network/esp_web_server.h>
#include <supla/network/html/device_info.h>
#include <supla/network/html/protocol_parameters.h>
#include <supla/network/html/status_led_parameters.h>
#include <supla/network/html/wifi_parameters.h>
#include <supla/device/supla_ca_cert.h>
#include <supla/control/hvac_base.h>
#include <supla/clock/clock.h>
#include <supla/network/html/time_parameters.h>
#include <supla/network/html/hvac_parameters.h>
#include <supla/control/internal_pin_output.h>
#include <supla/events.h>
#include <supla/actions.h>
#include <supla/sensor/virtual_thermometer.h>
#include <supla/control/button.h>
#include <ArduinoJson.h> //by Benoit Blanchon 6.17.0
#include <WiFiUdp.h>
String udp_msg;
#define udpPort 4210
char incomingPacket[255]; // buffer for incoming packets
WiFiUDP udp;
String msg;
word wykonaj_raz;
float temp_aktualna[17];
String channel_name[17];
byte grzanie[17];
unsigned long temp_aktualna_unsigned_long;
word temp_aktualna_word[17];
word timeout;
bool pierwsza_transmisja_UDP;
int state_output_[17];
int state_output_old_[17];
bool nowe_dane_udp_do_wyslania;
byte sekundy_od_ostatniej_transmisji_UDP_TX;
byte numer_kanalu_do_wyslania_przez_UDP;
unsigned long previousMillis_UDP;
unsigned long previousMillis_UDP_time;
/*
This example requires Dallas Temperature Control library installed.
https://github.com/milesburton/Arduino-Temperature-Control-Library
*/
// Add include to DS sensor
#include <supla/sensor/DS18B20.h>
#define CFG_BUTTON_GPIO 0
#define STATUS_LED_GPIO 2
//#define LED_RED_GPIO 13
//#define LED_BLUE_GPIO 12
#define OUTPUT_GPIO_1 5
#define OUTPUT_GPIO_2 13
#define OUTPUT_GPIO_3 14
#define OUTPUT_GPIO_4 27
#define OUTPUT_GPIO_5 25
#define update_path "/firmware"
#define www_username "admin"
#define www_password "temperatura"
#include <HTTPUpdateServer.h>
#define wysylaj_przez_udp 1 //Zezwalaj na wysylanie danych przez UDP
String last_message[18];
Supla::ESPWifi wifi;
Supla::Eeprom eeprom;
Supla::LittleFsConfig configSupla;
Supla::Device::StatusLed statusLed(STATUS_LED_GPIO, true); // inverted state
Supla::EspWebServer suplaServer;
auto termometr_1 = new Supla::Sensor::VirtualThermometer;
auto termometr_2 = new Supla::Sensor::VirtualThermometer;
auto termometr_3 = new Supla::Sensor::VirtualThermometer;
auto termometr_4 = new Supla::Sensor::VirtualThermometer;
auto termometr_5 = new Supla::Sensor::VirtualThermometer;
WebServer httpServer(80);
void setup() {
Serial.begin(115200);
// WARNING: using default Clock class. It works only when there is connection
// with Supla server. In real thermostat application, use RTC HW clock,
// which will keep time after ESP power reset
new Supla::Clock;
// HTML www component (they appear in sections according to creation
// sequence)
new Supla::Html::DeviceInfo(&SuplaDevice);
new Supla::Html::WifiParameters;
new Supla::Html::ProtocolParameters;
new Supla::Html::StatusLedParameters;
new Supla::Html::TimeParameters(&SuplaDevice);
new Supla::Device::StatusLed(STATUS_LED_GPIO, true);
eeprom.setStateSavePeriod(5000);
auto output_1 = new Supla::Control::InternalPinOutput(OUTPUT_GPIO_1,false);
auto output_2 = new Supla::Control::InternalPinOutput(OUTPUT_GPIO_2,false);
auto output_3 = new Supla::Control::InternalPinOutput(OUTPUT_GPIO_3,false);
auto output_4 = new Supla::Control::InternalPinOutput(OUTPUT_GPIO_4,false);
auto output_5 = new Supla::Control::InternalPinOutput(OUTPUT_GPIO_5,false);
auto hvac_1 = new Supla::Control::HvacBase(output_1);
auto hvac_2 = new Supla::Control::HvacBase(output_2);
auto hvac_3 = new Supla::Control::HvacBase(output_3);
auto hvac_4 = new Supla::Control::HvacBase(output_4);
auto hvac_5 = new Supla::Control::HvacBase(output_5);
// Html page for HVAC
new Supla::Html::HvacParameters(hvac_1);
new Supla::Html::HvacParameters(hvac_2);
new Supla::Html::HvacParameters(hvac_3);
new Supla::Html::HvacParameters(hvac_4);
new Supla::Html::HvacParameters(hvac_5);
termometr_1->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
termometr_2->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
termometr_3->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
termometr_4->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
termometr_5->getChannel()->setValidityTimeSec(MAX_SLEEP_TIME_SEC);
// Configure thermostat parameters
hvac_1->setDefaultTemperatureRoomMin(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2000);
hvac_1->setDefaultTemperatureRoomMax(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2600);
hvac_1->setTemperatureHisteresisMin(20); // 0.2 degree
hvac_1->setTemperatureHisteresisMax(1000); // 10 degree
hvac_1->setTemperatureHisteresis(20);
hvac_2->setDefaultTemperatureRoomMin(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2000);
hvac_2->setDefaultTemperatureRoomMax(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2600);
hvac_2->setTemperatureHisteresisMin(20); // 0.2 degree
hvac_2->setTemperatureHisteresisMax(1000); // 10 degree
hvac_2->setTemperatureHisteresis(20);
hvac_3->setDefaultTemperatureRoomMin(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2000);
hvac_3->setDefaultTemperatureRoomMax(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2600);
hvac_3->setTemperatureHisteresisMin(20); // 0.2 degree
hvac_3->setTemperatureHisteresisMax(1000); // 10 degree
hvac_3->setTemperatureHisteresis(20);
hvac_4->setDefaultTemperatureRoomMin(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2000);
hvac_4->setDefaultTemperatureRoomMax(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2600);
hvac_4->setTemperatureHisteresisMin(20); // 0.2 degree
hvac_4->setTemperatureHisteresisMax(1000); // 10 degree
hvac_4->setTemperatureHisteresis(20);
hvac_5->setDefaultTemperatureRoomMin(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2000);
hvac_5->setDefaultTemperatureRoomMax(SUPLA_CHANNELFNC_HVAC_THERMOSTAT, 2600);
hvac_5->setTemperatureHisteresisMin(20); // 0.2 degree
hvac_5->setTemperatureHisteresisMax(1000); // 10 degree
hvac_5->setTemperatureHisteresis(20);
auto cfgButton = new Supla::Control::Button(CFG_BUTTON_GPIO, true, true);
cfgButton->configureAsConfigButton(&SuplaDevice);
// configure defualt Supla CA certificate
SuplaDevice.setSuplaCACert(suplaCACert);
SuplaDevice.setSupla3rdPartyCACert(supla3rdCACert);
SuplaDevice.setName("Termostat ESP32");
SuplaDevice.begin(21); // Thermostat requires proto version >= 21
//httpUpdater.setup(&server, update_path, www_username, www_password);
}
void loop() {
if(timeout == 0){
SuplaDevice.iterate();
if(pierwsza_transmisja_UDP == 1){
termometr_1->setValue(temp_aktualna[2]);
termometr_2->setValue(temp_aktualna[4]);
termometr_3->setValue(temp_aktualna[5]);
termometr_4->setValue(temp_aktualna[6]);
termometr_5->setValue(temp_aktualna[15]);
}
}
if (SuplaDevice.getDeviceMode() == Supla::DEVICE_MODE_NORMAL) {
if (WiFi.status() == WL_CONNECTED) {
if(wykonaj_raz < 10000){
++wykonaj_raz;
}
if(wykonaj_raz == 10000){
wykonaj_raz = 10001;
Serial.println("UDP begin");
delay(1000);
udp.begin(udpPort);
Serial.println("Updater begin");
delay(1000);
HTTPUpdateServer httpUpdater;
httpUpdater.setup(&httpServer);
httpServer.begin();
}
}
Odczytaj_UDP();
Wyslij_UDP();
}
if (SuplaDevice.getDeviceMode() == Supla::DEVICE_MODE_CONFIG) {
// CONFIG MODE
if(wykonaj_raz == 10001){
Serial.println("Updater stop");
httpServer.stop();
wykonaj_raz = 0;
}
}
if(wykonaj_raz == 10001){
if (SuplaDevice.getDeviceMode() == Supla::DEVICE_MODE_NORMAL) {
httpServer.handleClient();
}
}
if(timeout > 0){
if(timeout == 1){
Serial.println("timeout");
}
--timeout;
}
Odczytaj_stan_wyjsc_hvac();
}
void Odczytaj_stan_wyjsc_hvac(){
int state_pomocniczy;
int state_pomocniczy_2;
state_pomocniczy = digitalRead(OUTPUT_GPIO_1); if(state_pomocniczy == 0){state_pomocniczy_2 = 1;} if(state_pomocniczy == 1){state_pomocniczy_2 = 0;} state_output_[2] = state_pomocniczy_2;
state_pomocniczy = digitalRead(OUTPUT_GPIO_2); if(state_pomocniczy == 0){state_pomocniczy_2 = 1;} if(state_pomocniczy == 1){state_pomocniczy_2 = 0;} state_output_[4] = state_pomocniczy_2;
state_pomocniczy = digitalRead(OUTPUT_GPIO_3); if(state_pomocniczy == 0){state_pomocniczy_2 = 1;} if(state_pomocniczy == 1){state_pomocniczy_2 = 0;} state_output_[5] = state_pomocniczy_2;
state_pomocniczy = digitalRead(OUTPUT_GPIO_4); if(state_pomocniczy == 0){state_pomocniczy_2 = 1;} if(state_pomocniczy == 1){state_pomocniczy_2 = 0;} state_output_[6] = state_pomocniczy_2;
state_pomocniczy = digitalRead(OUTPUT_GPIO_5); if(state_pomocniczy == 0){state_pomocniczy_2 = 1;} if(state_pomocniczy == 1){state_pomocniczy_2 = 0;} state_output_[15] = state_pomocniczy_2;
for (byte licz = 1; licz <= 16; licz++) {
if(state_output_old_[licz] != state_output_[licz]){
state_output_old_[licz] = state_output_[licz];
nowe_dane_udp_do_wyslania = 1;
if(state_output_[licz] == 1){grzanie[licz] = 1;}else{grzanie[licz] = 0;}
if(licz == 2) {Serial.println("Status hvac 1 = " + channel_name[licz] + " " + String(grzanie[licz]));}
if(licz == 4) {Serial.println("Status hvac 2 = " + channel_name[licz] + " " + String(grzanie[licz]));}
if(licz == 5) {Serial.println("Status hvac 3 = " + channel_name[licz] + " " + String(grzanie[licz]));}
if(licz == 6) {Serial.println("Status hvac 4 = " + channel_name[licz] + " " + String(grzanie[licz]));}
if(licz == 15){Serial.println("Status hvac 5 = " + channel_name[licz] + " " + String(grzanie[licz]));}
}
}
}
void Wyslij_UDP(){
unsigned long currentMillis = millis();
if(currentMillis - previousMillis_UDP_time >= 1000UL){
previousMillis_UDP_time = currentMillis;
++sekundy_od_ostatniej_transmisji_UDP_TX;
}
if(sekundy_od_ostatniej_transmisji_UDP_TX > 10){
sekundy_od_ostatniej_transmisji_UDP_TX = 0;
nowe_dane_udp_do_wyslania = 1;
}
if(nowe_dane_udp_do_wyslania > 0){
String text_UDP;
if(nowe_dane_udp_do_wyslania >= 1){
sekundy_od_ostatniej_transmisji_UDP_TX = 0;
nowe_dane_udp_do_wyslania = 1; //ograniczam żeby wysyłanie nie trwało w nieskończonośc
}
if(currentMillis - previousMillis_UDP >= 60UL){
previousMillis_UDP = currentMillis;
++numer_kanalu_do_wyslania_przez_UDP;
String text_UDP;
if(numer_kanalu_do_wyslania_przez_UDP < 17){
text_UDP = "{";
text_UDP += "\"ID\":\"" + String(numer_kanalu_do_wyslania_przez_UDP) + "\", ";
text_UDP += "\"Name\":\"" + channel_name[numer_kanalu_do_wyslania_przez_UDP] + "\", "; // <---Dodatkowe znaki cudzyslowia, przesylamy wartosc jako tekst, nie jako liczbę
text_UDP += "\"Temp\":\"" + String(temp_aktualna[numer_kanalu_do_wyslania_przez_UDP]) + "\", ";
text_UDP += "\"Heat\":\"" + String(grzanie[numer_kanalu_do_wyslania_przez_UDP]) + "\"} ";
if(wysylaj_przez_udp == 1){
udp.beginPacket("192.168.2.255", udpPort); udp.print(text_UDP); udp.endPacket();yield();
}else{
Serial.print("UDP TX: ");
Serial.println(text_UDP);
}
}
if(numer_kanalu_do_wyslania_przez_UDP == 17){
word PWM_dla_pompy = 0;
for (byte licz = 1; licz <= 16; licz++) {
if(grzanie[licz] == 1){
if(licz == 2){
PWM_dla_pompy = PWM_dla_pompy + 1000; //Dla salonu daj 1000
}else{
PWM_dla_pompy = PWM_dla_pompy + 250; //Dla pozostałych pomieszczen daj 250
}
}
}
if(PWM_dla_pompy > 1000){
PWM_dla_pompy = 1000;
}
word randNumber1 = random(1024);
word randNumber2 = random(1024);
word randNumber3 = random(1024);
word randNumber4 = random(1024);
word PUMP_CRC = 0;
PUMP_CRC = PUMP_CRC + randNumber1;
PUMP_CRC = PUMP_CRC + randNumber2;
PUMP_CRC = PUMP_CRC + randNumber3;
PUMP_CRC = PUMP_CRC + randNumber4;
PUMP_CRC = PUMP_CRC + PWM_dla_pompy;
text_UDP = "{";
text_UDP += "\"ID\":\"Pompa_1\", ";
text_UDP += "\"Name\":\"Pompa_PWM\", "; // <---Dodatkowe znaki cudzyslowia, przesylamy wartosc jako tekst, nie jako liczbę
text_UDP += "\"PWM_1\":\"" + String(randNumber1) + "\", "; //Wysylamy dowolna wartosc
text_UDP += "\"PWM_2\":\"" + String(randNumber2) + "\", "; //Wysylamy dowolna wartosc
text_UDP += "\"PWM_3\":\"" + String(randNumber3) + "\", "; //Wysylamy dowolna wartosc
text_UDP += "\"PWM_4\":\"" + String(randNumber4) + "\", "; //Wysylamy dowolna wartosc
text_UDP += "\"PWM_5\":\"" + String(PWM_dla_pompy) + "\", "; //Wysylamy dowolna wartosc
text_UDP += "\"Pompa_CRC\":\"" + String(PUMP_CRC) + "\"} ";
if(wysylaj_przez_udp == 1){
udp.beginPacket("192.168.2.255", udpPort); udp.print(text_UDP); udp.endPacket();yield();
}else{
Serial.print("UDP TX: ");
Serial.println(text_UDP);
}
}
}
if(numer_kanalu_do_wyslania_przez_UDP >= 17){
numer_kanalu_do_wyslania_przez_UDP = 0;
nowe_dane_udp_do_wyslania = 0;
sekundy_od_ostatniej_transmisji_UDP_TX = 0;
}
}
}
void Odczytaj_UDP(){
int packetSize = udp.parsePacket();
if (packetSize)
{
digitalWrite(STATUS_LED_GPIO,HIGH);
delay(30);
// receive incoming UDP packets
//Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
int len = udp.read(incomingPacket, 255);
if (len > 0)
{
incomingPacket[len] = 0;
}
udp_msg = String(incomingPacket);
if (udp_msg.substring(2,9) == "CzID255") {
Dekoduj_json_udp();
}
udp_msg = "";
digitalWrite(STATUS_LED_GPIO,LOW);
}
}
void Dekoduj_json_udp(){
byte ID_val = 0;
//Serial.println(msg);
//Kod wygenerowany przy pomocy strony https://arduinojson.org/v6/assistant/
DynamicJsonDocument doc(1024);
DeserializationError err = deserializeJson(doc, udp_msg);
if (err) {
Serial.println(F("Blad dokodowania JSON"));
return;
}
deserializeJson(doc, udp_msg);
String ID_string = doc["CzID255"];
String Name_string = doc["CzN255"];
String Temp_string = doc["CzT255"];
String Start_string = doc["255_START"];
String End_string = doc["255_END"];
//Serial.println(msg.substring(2,9));
//Serial.println(udp_msg);
if (udp_msg.substring(2,9) == "CzID255") {
//Serial.println(udp_msg);
ID_val = ID_string.toInt();
last_message[ID_val] = udp_msg;
channel_name[ID_val] = Name_string;
if(ID_val == 0){
temp_aktualna_unsigned_long = Temp_string.toInt();
timeout = 50000;
}else{
temp_aktualna_word[ID_val] = Temp_string.toInt();
timeout = 50000;
}
if(ID_val == 16){
timeout = 0;
//Kalkulacja CRC
unsigned long CRC = 0;
for (byte licz = 1; licz <= 16; licz++) {
CRC = CRC + temp_aktualna_word[licz];
}
if(CRC == temp_aktualna_unsigned_long){ //Jesli otrzymalismy prawidlowe CRC;
float temp_aktualna_float = 0;
for (byte licz = 1; licz <= 16; licz++) {
temp_aktualna_float = temp_aktualna_word[licz] - 12721; //Deszyfrujemy dane
temp_aktualna[licz] = temp_aktualna_float;
temp_aktualna[licz] = temp_aktualna[licz] / 100;
}
pierwsza_transmisja_UDP = 1;
kasuj_wszystkie_msg();
}else{
if(temp_aktualna_unsigned_long == 0){
Serial.println(F("CRC blędne, nieodebrano calej ramki danych"));
korekcja_bledow();
kasuj_wszystkie_msg();
}else{
Serial.print(F("CRC blędne, oczekiwano: "));
Serial.print(String(temp_aktualna_unsigned_long));
Serial.print(F(" jest: "));
Serial.println(String(CRC));
korekcja_bledow();
kasuj_wszystkie_msg();
}
}
temp_aktualna_unsigned_long = random(30000); //Usuwamy dane zapisujac ja dowolnymi danymi
for (byte licz = 1; licz <= 16; licz++) {
temp_aktualna_word[licz] = random(30000); //Usuwamy dane zapisujac ja dowolnymi danymi
}
}
}
}
void korekcja_bledow(){
byte liczba_brakujacych_transmisji;
byte zapamietaj_numer_brakujacej_transmisji;
unsigned long suma;
unsigned long roznica;
for (byte licz = 0; licz <= 16; licz++) {
if(last_message[licz] == ""){
++liczba_brakujacych_transmisji;
zapamietaj_numer_brakujacej_transmisji = licz;
}
}
if(liczba_brakujacych_transmisji > 0){
Serial.print("Liczba brakujacych transmisji: ");
Serial.println(liczba_brakujacych_transmisji);
if(liczba_brakujacych_transmisji == 1){
//Serial.print("Numer brakujacej transmisji: ");
//Serial.println(zapamietaj_numer_brakujacej_transmisji);
if(zapamietaj_numer_brakujacej_transmisji != 0){
suma = 0;
for (byte licz = 1; licz <= 16; licz++) {
if(licz != zapamietaj_numer_brakujacej_transmisji){
suma = suma + temp_aktualna_word[licz];
}
}
//Serial.print("Suma: ");
//Serial.println(suma);
roznica = temp_aktualna_unsigned_long - suma;
//Serial.print("Różnica: ");
//Serial.println(roznica);
if(roznica < 100000){
temp_aktualna_word[zapamietaj_numer_brakujacej_transmisji] = roznica;
float temp_aktualna_float = 0;
for (byte licz = 1; licz <= 16; licz++) {
temp_aktualna_float = temp_aktualna_word[licz] - 12721; //Deszyfrujemy dane
temp_aktualna[licz] = temp_aktualna_float;
temp_aktualna[licz] = temp_aktualna[licz] / 100;
}
Serial.print("Naprawiono blad transmisji nr: ");
Serial.print(zapamietaj_numer_brakujacej_transmisji);
Serial.print(" Wartosc: ");
Serial.print(roznica);
Serial.print(" --> ");
Serial.print(String(temp_aktualna[zapamietaj_numer_brakujacej_transmisji],1));
Serial.println("*C");
}else{
Serial.println("Nienaprawialne, roznica wieksza / rowna 100000");
}
}else{
Serial.println("Nienaprawialne, brakuje transmisji 0");
}
}else{
Serial.println("Nienaprawialne, za duzo brakuje");
}
}
}
void kasuj_wszystkie_msg(){
for (byte licz = 0; licz <= 16; licz++) {
last_message[licz] = "";
}
}Nie twórz kolejnej instancji WebServer'a, tylko skorzystaj z utworzonej przez SD.Duch__ wrote: Mon Nov 11, 2024 10:39 am Czy ktoś może mi powiedzieć co robię źle?
Chciałbym aby na tym kodzie jednocześnie działało sterowanie z apki, możliwość zdalnej aktualizacji zawsze po lokalnym IP i tryb konfiguracyjny na 192.168.4.1.
Moduł przełącza się w tryb konfiguracyjny wg logów, generuje własną siec wifi, ale strona 192.168.4.1 działa bardzo wybiórczo, raz strona się ładuje innym razem nie, od czego to zależy
PS. Źródłem temperatur u mnie są dane otrzymywane w co 5 sekundowych transmisjach UDP z innego układu.
Code: Select all
httpUpdater.setup(suplaServer.getServerPtr(), "/update");Tutaj masz akcje dla termostatu.Duch__ wrote: Tue Nov 12, 2024 6:16 am Dzięki. Działa.
Jak wyłączyć grzanie na wszystkich grzejących przekaźnikach z poziomu softu?
Chyba raczej nie.Czy jest możliwe włączenie stałego trybu konfiguracji?
Code: Select all
if (Supla::Network::IsReady()) {
SuplaDevice.handleAction(0, Supla::START_LOCAL_WEB_SERVER);
}