Wysyłanie stanu przekaźnika do SuplaCloud

PawelM
Posts: 14
Joined: Thu Dec 29, 2022 2:25 pm

Post

Code: Select all

if(relay0->isOn()) {
  Serial.println("relay0 ");
  Serial.println(relay0->isOn()); // podgląd stanu 
  K0status = 0;
  }
else{
K0status = 1 ;
}
Serial.println(relay0->isOn()); jest zawsze "1" niezależnie od tego czy jest w supli włączone czy wyłączone.

Coś pominąłem? Cos robię źle? Zacząłem grzebać bo mi nie działa wysłanie informacji na websocket (K0status informuje jaki jest stan na wyjściu) Jednak wrócę do mojego poprzedniego rozwiązania - tam działało :P
User avatar
klew
Posts: 13908
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

W tym fragmencie kodu wchodzisz w funkcję wyświetlającą isOn tylko gdy wcześniej isOn zwróci true, więc to dość oczywiste że zawsze na serial poleci 1
Najlepsze suple dla Twojego domu :mrgreen:
PawelM
Posts: 14
Joined: Thu Dec 29, 2022 2:25 pm

Post

Okej, racja.
Ale jeżeli byłby false to przecież nic by nie wyświetlał a w serial monitorze (ustawiłem sobie wysłanie informacji co 1sek) wyświetla co 1sek tę informację czyli jego stan w relay0->isOn() nie zmienia się. Dobrze rozumuję?



Zrobiłem co 1 sek takie wywołanie:

Code: Select all

void spr_relay(){

Serial.println("relay0 ");
Serial.println(relay0->isOn());

}

I nie ważne czy w SUPLA zmienię na włącz czy wyłącz (przekażnik się przełącza) to relay->isOn() zawsze ma 1.
User avatar
klew
Posts: 13908
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

Stan będzie się zmieniał. Jeśli jest włączony to ta metoda zwraca false
Najlepsze suple dla Twojego domu :mrgreen:
PawelM
Posts: 14
Joined: Thu Dec 29, 2022 2:25 pm

Post

I właśnie o to chodzi, że stan się nie zmienia - zawsze jest "1"
User avatar
klew
Posts: 13908
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

To znaczy że coś źle robisz ;)
Albo metoda wyświetlającą boola z jakiegoś powodu wyświetla go zawsze jako 1.

Wstaw cały kod (o ile nie jest zbyt długi;) ), to łatwiej będzie coś pomóc.
Najlepsze suple dla Twojego domu :mrgreen:
PawelM
Posts: 14
Joined: Thu Dec 29, 2022 2:25 pm

Post

Nie wykluczam mojego błędu i nie zapieram się, że dobrze robię. Na ogół spojrzenie drugiej osoby świeżym okiem rozwiązuje wiele problemów.

Poniżej kod - wywaliłem zakomentowane nieaktywne kody i opcje z zegarem czasu, który i tak nie działa w tej części kodu.

Code: Select all


#include <PCF8574.h>

#include <SuplaDevice.h>
#include <supla/control/button.h>
#include <supla/control/relay.h>
#include <supla/io.h>
#include <supla/sensor/DS18B20.h>
#include <supla/sensor/HX711.h>
#include <supla/network/esp_wifi.h>

#include <ArduinoJson.h>

#include <WebSocketsServer.h>
#include <Hash.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WiFiClient.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>

#include <SDFS.h>
#include <SPI.h>
//--------------
#include <Wire.h>
#include <NTPClient.h>
#include <RTClib.h>
#include <time.h>

//--------------
#include <WiFiUdp.h>

#define Serial Serial

SDFSConfig cfg;

#define PIN_ANALOG A0         //ADC fotorezystora
int fotorezystor;             //zmienna dla odczytu fotorezystora
int prog_fotorezystor = 500;  //próg zadziałania
bool bool_fotorezystor = 0;
bool flaga_fotorezystor = 0;

const char *ssid = "xxxxx";
const char *password = "xxxxx";
Supla::ESPWifi wifi(ssid, password);

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

//extender portów
PCF8574 EXT1(0x21);
PCF8574 EXT2(0x22);

  auto relay0 = new Supla::Control::Relay(100, false); //Przekaznik 0 w EXT1 Załączanie światło nad wejściem głównym
  auto relay1 = new Supla::Control::Relay(101, false); //Przekaznik 1 w EXT1 Załączanie światło nad garażem
  auto relay2 = new Supla::Control::Relay(102, false); //Przekaznik 2 w EXT1 Załączanie światło nad kotłownią
  auto relay3 = new Supla::Control::Relay(103, false); //Przekaznik 3 w EXT1 Załączanie światło nad tarasem
  auto relay4 = new Supla::Control::Relay(104, false); //Przekaznik 4 w EXT1 Brama wjazdowa
  auto relay5 = new Supla::Control::Relay(105, false); //Przekaznik 5 w EXT1 Furtka
  auto relay6 = new Supla::Control::Relay(106, false); //Przekaznik 6 w EXT1 Załączanie pompy CWU
  auto relay7 = new Supla::Control::Relay(107, false); //Przekaznik 7 w EXT1 Załączanie grzałki CWU


File configFile;

///////////////////////////////////


//---------------------
//WEBSOCKET

//komendy wysyłane przez WebSocket
const char K0ON[] = "K0_ON";
const char K0OFF[] = "K0_OFF";
bool K0status = 1;
bool K0flagOn = 0;
bool K0flagOff= 1;

const char K1ON[] = "K1_ON";
const char K1OFF[] = "K1_OFF";
bool K1status = 1;
bool K1flagOn = 0;
bool K1flagOff= 1;

const char K2ON[] = "K2_ON";
const char K2OFF[] = "K2_OFF";
bool K2status = 1;
bool K2flagOn = 0;
bool K2flagOff= 1;

const char K3ON[] = "K3_ON";
const char K3OFF[] = "K3_OFF";
bool K3status = 1;
bool K3flagOn = 0;
bool K3flagOff= 1;

const char K4ON[] = "K4_ON";
const char K4OFF[] = "K4_OFF";
bool K4status = 1;
bool K4flagOn = 0;
bool K4flagOff= 1;

const char K5ON[] = "K5_ON";
const char K5OFF[] = "K5_OFF";
bool K5status = 1;
bool K5flagOn = 0;
bool K5flagOff= 1;

const char K6ON[] = "K6_ON";
const char K6OFF[] = "K6_OFF";
bool K6status = 1;
bool K6flagOn = 0;
bool K6flagOff= 1;

const char K7ON[] = "K7_ON";
const char K7OFF[] = "K7_OFF";
bool K7status = 1;
bool K7flagOn = 0;
bool K7flagOff= 1;



String webString = "", token = "@$";
unsigned long previousMillis = 0;
unsigned long czasOdczytu = 1000;





//zegar czasu rzeczywistego
RTC_DS3231 rtc;
//ustawienia dla zegara globalnego
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "tempus1.gum.gov.pl");

//-------obsługa kalendarza
//Nazwy dni
String weekDays[7] = { "Niedziela", "Poniedziałek", "Wtorek", "Sroda", "Czwartek", "Piatek", "Sobota" };

//Nazwy miesięcy
String months[12] = { "Styczen", "Luty", "Marzec", "Kwiecien", "Maj", "Czerwiec", "Lipiec", "Sierpien", "Wrzesien", "Pazdziernik", "Listopad", "Grudzien" };
//-------

static bool hasSD = false;
File uploadFile;


class MyPCF8574 : public Supla::Io {
  public:
    void customDigitalWrite(int channelNumber, uint8_t pin, uint8_t val) {
      if ((pin >= 100) && (pin <= 107)) {
        EXT1.write(pin - 100, val);
        return;
      }
      if (pin <= 99) {
        return ::digitalWrite(pin, val);
      }
    }

    int customDigitalRead(int channelNumber, uint8_t pin) {
      if ((pin >= 200) && (pin <= 207)) {
        return EXT2.read(pin - 200);
      }
      if (pin <= 99) {
        return ::digitalRead(pin);
      }
    }
} MyPCF8574;


/////////////////////////////////////////////////////////////////////////////////////////////////

//wiadmość wysyłana do przeglądarki
void notifyClients() {
  ws.textAll(String(K0status) + token + String(K1status) + token + String(K2status) + token + String(K3status) + token + String(K4status) + token + String(K5status) + token + String(K6status) + token + String(K7status) + token + String("wolny_Slot") + token + String(fotorezystor) + token + String(prog_fotorezystor));
}

void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
  AwsFrameInfo *info = (AwsFrameInfo *)arg;
  if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
    data[len] = 0;
    if (strcmp((char *)data, "toggle0") == 0) {
      K0status = !K0status;
      notifyClients();
    }


    if (strcmp((char *)data, "toggle1") == 0) {
      K1status = !K1status;
      notifyClients();
    }

    if (strcmp((char *)data, "toggle2") == 0) {
      K2status = !K2status;
      notifyClients();
    }

    if (strcmp((char *)data, "toggle3") == 0) {
      K3status = !K3status;
      notifyClients();
    }
    if (strcmp((char *)data, "toggle4") == 0) {
      K4status = !K4status;
      notifyClients();
    }
    if (strcmp((char *)data, "toggle5") == 0) {
      K5status = !K5status;
      notifyClients();
    }
    if (strcmp((char *)data, "toggle6") == 0) {
      K6status = !K6status;
      notifyClients();
    }
    if (strcmp((char *)data, "toggle7") == 0) {
      K7status = !K7status;
      notifyClients();
    }
  }
}

void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
             void *arg, uint8_t *data, size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
      notifyClients();
      break;
    case WS_EVT_DISCONNECT:
      Serial.printf("WebSocket client #%u disconnected\n", client->id());
      break;
    case WS_EVT_DATA:
      handleWebSocketMessage(arg, data, len);
      break;
    case WS_EVT_PONG:
    case WS_EVT_ERROR:
      break;
  }
}

void initWebSocket() {
  ws.onEvent(onEvent);
  server.addHandler(&ws);
}


/////////////////////////////////////////////////////////////////////////////////////////////////
void setup(void) {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.print("\n");
  delay(100);
  // inicjazlizacja karty SD
  cfg.setCSPin(D4);
  SDFS.setConfig(cfg);
  SDFS.begin();

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Laczenie do ");
  Serial.println(ssid);

  // Wait for connection
  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 20) {  //wait 10 seconds
    delay(500);
  }

  if (WiFi.status() == WL_CONNECTED) {
    Serial.print("Polaczono! IP: ");
    Serial.println(WiFi.localIP());

  } else {
    Serial.print("Nie mozna polaczyc sie z: ");
    Serial.println(ssid);
    Serial.println("Wlaczam siec Wi-Fi mikrokontrolera: ");
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(100);

    IPAddress localIp(192, 168, 1, 1);
    IPAddress gateway(192, 168, 1, 1);
    IPAddress subnet(255, 255, 255, 0);

    WiFi.softAPConfig(localIp, gateway, subnet);
    WiFi.softAP("HAUPA_WiFi");
    Serial.println("HAUPA_Wi-Fi Adres IP: ");
    Serial.println(WiFi.localIP());
  }


  initWebSocket();
  server.begin();
  delay(100);

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(SDFS, "/index.html", "text/html;charset=UTF-8");
  });

  server.serveStatic("/", SDFS, "/");



  //----- ekspander portów
  EXT1.begin();  //expander I/O nr 1
  EXT2.begin();  //expander I/O nr 2



  pinMode(PIN_ANALOG, INPUT);   //ustawiamy pin analogowy jako wejście
  



  ///SUPLA///

  // Replace the falowing GUID with value that you can retrieve from
  // https://www.supla.org/arduino/get-guid
  char GUID[SUPLA_GUID_SIZE] = {  };

  // Replace the following AUTHKEY with value that you can retrieve from:
  // https://www.supla.org/arduino/get-authkey
  char AUTHKEY[SUPLA_AUTHKEY_SIZE] = { };

  SuplaDevice.begin(
    GUID,                // Global Unique Identifier
    "",   // SUPLA server address
    "",  // Email address used to login to Supla Cloud
    AUTHKEY);            // Authorization key
}


unsigned long czas_fotorezystor = 0;
unsigned long czas1 = 0;
unsigned long czas2 = 0;
unsigned long czas3 = 0;
unsigned long czas4 = 0;
unsigned long czas5 = 0;
unsigned long czas_wlacznik_S1 = 0;
bool S1_status = 0;

void loop(void) {

  SuplaDevice.iterate();
   

 
  //czas pracy mikrokontrolera
  unsigned long czas_uC = millis();
  unsigned long czas_uC1 = millis();
  unsigned long czas_uC2 = millis();
  unsigned long czas_uC3 = millis();
  unsigned long czas_uC4 = millis();
  unsigned long czas_uC5 = millis();
  //unsigned int czas_uC_interwal_odczytu = millis();
  ws.cleanupClients();

  if (czas_uC1 - czas1 >= czasOdczytu) {
    notifyClients(); //wysłanie na websocket statusu wszystkich zmiennych.
    czas1 = czas_uC1; 
  }

  //obsługa przekaźników
  if(K0status == 0 && K0flagOn == 1){
    relay0->turnOn();
    K0flagOn = 0;
    K0flagOff = 1;
    // EXT1.write(0, K0status);
  }
  if(K0status == 1 && K0flagOff == 1){
    relay0->turnOff();
    K0flagOn = 1;
    K0flagOff = 0;
  }
  //==
  if(K1status == 0 && K1flagOn == 1){
    relay1->turnOn();
    K1flagOn = 0;
    K1flagOff = 1;
    // EXT1.write(1, K1status);
  }
  if(K1status == 1 && K1flagOff == 1){
    relay1->turnOff();
    K1flagOn = 1;
    K1flagOff = 0;
  }
  //==
  if(K2status==0 && K2flagOn == 1){
    relay2->turnOn();
    K2flagOn = 0;
    K2flagOff = 1;
    // EXT1.write(2, K2status);
  }
  if(K2status == 1 && K2flagOff == 1){
    relay2->turnOff();
    K2flagOn = 1;
    K2flagOff = 0;
  }
  //==
  if(K3status==0 && K3flagOn == 1){
    relay3->turnOn();
    K3flagOn = 0;
    K3flagOff = 1;
    // EXT1.write(3, K3status);
  }
  if(K3status == 1 && K3flagOff == 1){
    relay3->turnOff();
    K3flagOn = 1;
    K3flagOff = 0;
  }
  //==
  if(K4status==0 && K4flagOn == 1){
    relay4->turnOn();
    K4flagOn = 0;
    K4flagOff = 1;
    // EXT1.write(4, K4status);
  }
  if(K4status == 1 && K4flagOff == 1){
    relay4->turnOff();
    K4flagOn = 1;
    K4flagOff = 0;
  }
  //==
  if(K5status==0 && K5flagOn == 1){
    relay5->turnOn();
    K5flagOn = 0;
    K5flagOff = 1;
    // EXT1.write(5, K5status);
  }
  if(K5status == 1 && K5flagOff == 1){
    relay5->turnOff();
    K5flagOn = 1;
    K5flagOff = 0;
  }
  //==
  if(K6status==0 && K6flagOn == 1){
    relay6->turnOn();
    K6flagOn = 0;
    K6flagOff = 1;
    // EXT1.write(6, K6status);
  }
  if(K6status == 1 && K6flagOff == 1){
    relay6->turnOff();
    K6flagOn = 1;
    K6flagOff = 0;
  }
  //==
  if(K7status==0 && K7flagOn == 1){
    relay7->turnOn();
    K7flagOn = 0;
    K7flagOff = 1;
    // EXT1.write(7, K7status);
  }
  if(K7status == 1 && K7flagOff == 1){
    relay7->turnOff();
    K7flagOn = 1;
    K7flagOff = 0;
  }
  



  if (czas_uC - czas_fotorezystor >= 1000) {
   spr_relay();
    fotorezystor = analogRead(PIN_ANALOG);  //odczytujemy wartość
    //Serial.println(fotorezystor); //piszemy wartość
    if (bool_fotorezystor) {
      if (fotorezystor >= prog_fotorezystor) {
        K0status = 1;  //1 = wyłączamy
        //EXT1.write(K0,HIGH); //Wyłączamy przekażnik
      }
      if (fotorezystor <= prog_fotorezystor) {
        K0status = 0;  //0 = włączamy
      }
    }
    czas_fotorezystor = czas_uC;
  }
}



void spr_relay(){

if(relay0->isOn()) K0status = 0;
if(!relay0->isOn()) K0status = 1;
Serial.println("relay0 ");
Serial.println(relay0->isOn());





//   //sprawdzanie czy włączony jest przekaznik przez SUPLA
    
// for (auto element = Supla::Element::begin(); element != nullptr; element = element->next()) { // iterujemy po wszystkich elementach dodanych do programu
//     if (element->getChannel()) { // sprawdzamy, czy do elementu jest przypisany kanał. Niektóre elementy (np. button) nie posiadają kanału.
//       auto channel = element->getChannel();
//       auto numer = element->getChannelNumber();
//         //Serial.println(channel->getChannelNumber());
//       if (channel->getChannelType() == SUPLA_CHANNELTYPE_RELAY) {
//         auto rilej = channel->getValueBool();


//         if(numer == 7 && rilej == 1){
//           Serial.println("przekaznik nr 7 wlaczony");
//           K7status = 0;
//         }
//         if(numer == 7 && rilej == 0){
//           K7status = 1;
//         }

//         if(numer == 6 && rilej == 1){
//           Serial.println("przekaznik nr 6 wlaczony");
//           K6status = 0;
//         }
//         if(numer == 6 && rilej == 0){
//           K6status = 1;
//         }

//         if(numer == 5 && rilej == 1){
//           Serial.println("przekaznik nr 5 wlaczony");
//           K5status = 0;
//         }
//         if(numer == 5 && rilej == 0){
//           K5status = 1;
//         }

//         if(numer == 4 && rilej == 1){
//           Serial.println("przekaznik nr 4 wlaczony");
//           K4status = 0;
//         }
//         if(numer == 4 && rilej == 0){
//           K4status = 1;
//         }

//         if(numer == 3 && rilej == 1){
//           Serial.println("przekaznik nr 3 wlaczony");
//           K3status = 0;
//         }
//         if(numer == 3 && rilej == 0){
//           K3status = 1;
//         }

//         if(numer == 2 && rilej == 1){
//           Serial.println("przekaznik nr 2 wlaczony");
//           K2status = 0;
//         }
//         if(numer == 2 && rilej == 0){
//           K2status = 1;
//         }
//         if(numer == 1 && rilej == 1){
//           Serial.println("przekaznik nr 1 wlaczony");
//           K1status = 0;
//         }
//         if(numer == 1 && rilej == 0){
//           K1status = 1;
//         }
//         if(numer == 0 && rilej == 1){
//           Serial.println("przekaznik nr 0 wlaczony");
//           K0status = 0;
//         }
//         if(numer == 0 && rilej == 0){
//           K0status = 1;
//         }

//       }
//     }
//   }


  
}


Dodam jeszcze, że to co miałem na samym dole (jest zakomentowane) działało perfekt :D
User avatar
klew
Posts: 13908
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

Metoda isOn robi digital read, a nie masz tego zaimplementowanego dla gpio 100..107
Najlepsze suple dla Twojego domu :mrgreen:
PawelM
Posts: 14
Joined: Thu Dec 29, 2022 2:25 pm

Post

Co masz na myśli? :oops:
User avatar
klew
Posts: 13908
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

PawelM wrote: Sat Dec 31, 2022 2:17 pm Co masz na myśli? :oops:
customDigitalRead jest zaimplementowane dla gpio (pin) o numerach 200 do 207, a write dla 100 do 107.
Really na "gpio" 100 będzie próbował pisać i czytać na to gpio
Najlepsze suple dla Twojego domu :mrgreen:

Return to “Pomoc”