XIAOMI LYWSD03MMC - odczyt przez ESP32

User avatar
veeroos
Posts: 1081
Joined: Sun Mar 20, 2022 9:30 am
Location: Głogów
Has thanked: 1 time
Been thanked: 9 times

Post

Michał P. wrote: Fri Jan 05, 2024 5:11 pm Wrzucam to co mam wgrane u siebie, tak korzystam z arduino ide.
Wiesz tak popatrzyłem na Twoje logi i ja miałem tak samo, że nie chciało się łączyć z wifi nawet, tak miałem na zwykłym module, dlatego kupiłem esp32 S3 N16R8, dzisiaj wgram aktualny kod na zwykły moduł i zobaczę jak się to zachowywało będzie, jak będzie OK, to jutro wrzucę kod na forum.
Kolega @klew trochę podsunął mi pomysłów, dlatego chcę pozmieniać parę rzeczy i sprawdzić działanie programu na zwykłym module, bo tak jak wrzuciłem screena moduł nadal działa i nie zrywa połączenia, ale to jest chyba najmocniejszy Esp32 S3
Zamel Mew-01, Zamel PEW-01, Zamel SBW-01, Zamel THW-01, Zamel SRW-01, Zamel mSLW-02, Auraton BOX + Indor Sensor, Airly Gate By Veeroos, Zigbee to Supla Gateway + sensors, Zamel SGW-01 and more

https://github.com/v33r005
User avatar
klew
Posts: 13911
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 137 times
Been thanked: 137 times

Post

Ten pBLEScan nie powiem być jakoś zwalniany?
Ogólnie w programie jest masa String I sdt::string. One potrafią dużo pamięci alokować i zwalniać prowadząc do fragmentacji pamięci.
Najlepsze suple dla Twojego domu :mrgreen:
zzrr
Posts: 1864
Joined: Wed Oct 26, 2022 7:35 pm
Has thanked: 76 times
Been thanked: 119 times

Post

Michał P. wrote: Fri Jan 05, 2024 5:11 pm
Michał P. wrote: Fri Jan 05, 2024 2:17 pm Próbowałem wgrać wybierając LOLIN32 Lite, niestety bez powodzenia, nadal ten sam błąd z pamięcią. @veeroos dzięki za zaangażowanie i próbę przerobienia kodu z wykorzystaniem biblioteki NimBLE, czekam z niecierpliwością. Poszukałem w internecie i zazwyczaj wykorzystanie tej biblioteki rozwiązywało problem.
Wrzucam to co mam wgrane u siebie, tak korzystam z arduino ide.
Jak dodałem do kodu te dwie linie :

Code: Select all

#include <WiFiClientSecure.h>
#include <EEPROM.h>
to poszło, skompilowało i wgrało na ESP. W pliku
test.zip
masz loga z kompilacji i wgrania.
Coś mogę jeszcze sprawdzić żeby pomóc?
A SSL coś może mieć wpływ na ten problem z którym walczycie?
ja u siebie musiałem wyłączyć żeby mi działało jednocześnie BLE i WFi. Ale nie pamiętam czy były jakieś komunikaty wcześniej dot. pamięci
Jak patrzę teraz w te logi Twoje to kojarzę że u mnie ten sam problem był. U mnie problem rozwiązało to co podałem wyżej. W tym przypadku nie wiem czy wchodzi w grę wyłączenie SSL.
You do not have the required permissions to view the files attached to this post.
User avatar
veeroos
Posts: 1081
Joined: Sun Mar 20, 2022 9:30 am
Location: Głogów
Has thanked: 1 time
Been thanked: 9 times

Post

Wczoraj wieczorem wgrałem kod do ESP32 DEV kit 1, czyli taki zwykły najzwyklejszy ESP32 bez pamięci dodatkowej
Screenshot_2024-01-06-05-59-48-877_org.supla.android.jpg
Jak RAMu w esp32 S3 wolnego mam około 160k to na tym mam jakieś 80k, to ja już tego nie rozumiem, może to tylko kwestia biblioteki... Dobra ja później wrzucę kod żebyście potestowali
You do not have the required permissions to view the files attached to this post.
Zamel Mew-01, Zamel PEW-01, Zamel SBW-01, Zamel THW-01, Zamel SRW-01, Zamel mSLW-02, Auraton BOX + Indor Sensor, Airly Gate By Veeroos, Zigbee to Supla Gateway + sensors, Zamel SGW-01 and more

https://github.com/v33r005
User avatar
veeroos
Posts: 1081
Joined: Sun Mar 20, 2022 9:30 am
Location: Głogów
Has thanked: 1 time
Been thanked: 9 times

Post

obiecany kod:

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 STATUS_LED_GPIO 2
#define BUTTON_CFG_RELAY_GPIO 0
#include <sstream>
#include <NimBLEDevice.h>
#include <NimBLEScan.h>
#include <NimBLEAdvertisedDevice.h>


#include <SuplaDevice.h>
#include <supla/network/esp_wifi.h>
#include <supla/control/button.h>
#include <supla/control/action_trigger.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/sensor/therm_hygro_meter.h>
#include <supla/sensor/thermometer.h>

#define SCAN_TIME  2 // seconds
byte od1 = 0;
byte od2 = 0;
byte od3 = 0;
int wilg1 = -1;
float temp1 = -275;
int wilg2 = -1;
float temp2 = -275;
int wilg3 = -1;
float temp3 = -275;
byte bat1 = 0;
byte bat2 = 0;
byte bat3 = 0;
unsigned long czas_pomiedzy_skanowaniem;
unsigned long wifimilis;
unsigned long lastReadTime = 0;

boolean METRIC = true; //Set true for metric system; false for imperial

String text01;
String text02;
String text03;
String text04;
String text05;
String text06;
String text07;
String text08;
String text09;
String text10;
String text11;
String text12;
String text13;
String text14;
String text15;
String zmienna;
String MAC_ADR;
byte BLE_DEVICE;
bool wyswietl = 0;

#define XIAOMI_BLE_DEVICE_1_MAC "A4:C1:38:0D:AE:08"
#define XIAOMI_BLE_DEVICE_2_MAC "A4:C1:38:10:3D:44"
#define XIAOMI_BLE_DEVICE_3_MAC "A4:C1:38:43:6A:FE"
//#define XIAOMI_BLE_DEVICE_1_MAC "A4:C1:38:AF:35:85"
//#define XIAOMI_BLE_DEVICE_2_MAC "A4:C1:38:FA:F0:FB"
//#define XIAOMI_BLE_DEVICE_3_MAC "A4:C1:38:E3:84:F4"

//#include <supla/storage/eeprom.h>
//Supla::Eeprom eeprom;

Supla::ESPWifi wifi;
Supla::LittleFsConfig configSupla;

Supla::Device::StatusLed statusLed(STATUS_LED_GPIO, true); // inverted state
Supla::EspWebServer suplaServer;
//wifi.setSSLEnabled(false);
Supla::Html::DeviceInfo htmlDeviceInfo(&SuplaDevice);
Supla::Html::WifiParameters htmlWifi;
Supla::Html::ProtocolParameters htmlProto;
Supla::Html::StatusLedParameters htmlStatusLed;

byte current_humidity;
byte current_batt;

word val;

NimBLEScan *pBLEScan;

void IRAM_ATTR resetModule(){
    ets_printf("reboot\n");
    esp_restart();
}

float current_temperature;

class MyAdvertisedDeviceCallbacks : public NimBLEAdvertisedDeviceCallbacks {
    void onResult(NimBLEAdvertisedDevice* advertisedDevice)
    {
        if (advertisedDevice->haveName() && advertisedDevice->haveServiceData()) {

            int serviceDataCount = advertisedDevice->getServiceDataCount();
            std::string strServiceData = advertisedDevice->getServiceData(0);

            uint8_t cServiceData[100];
            char charServiceData[100];

            strServiceData.copy((char *)cServiceData, strServiceData.length(), 0);

            for (int i=0;i<strServiceData.length();i++) {
                sprintf(&charServiceData[i*2], "%02x", cServiceData[i]);
            }

            std::stringstream ss;
            ss << "fe95" << charServiceData;

            

            text01 = String(charServiceData[0]) + String(charServiceData[1]);      //Serial.print(text1); Serial.print(" ");
            text02 = String(charServiceData[2]) + String(charServiceData[3]);      //Serial.print(text2); Serial.print(" ");
            text03 = String(charServiceData[4]) + String(charServiceData[5]);      //Serial.print(text3); Serial.print(" ");
            text04 = String(charServiceData[6]) + String(charServiceData[7]);      //Serial.print(text4); Serial.print(" ");
            text05 = String(charServiceData[8]) + String(charServiceData[9]);      //Serial.print(text5); Serial.print(" "); 
            text06 = String(charServiceData[10]) + String(charServiceData[11]);    //Serial.print(text6); Serial.print(" "); 
            text07 = String(charServiceData[12]) + String(charServiceData[13]);    //Serial.print(text7); Serial.print(" "); 
            text08 = String(charServiceData[14]) + String(charServiceData[15]);    //Serial.print(text8); Serial.print(" "); 
            text09 = String(charServiceData[16]) + String(charServiceData[17]);    //Serial.print(text9); Serial.print(" "); 
            text10 = String(charServiceData[18]) + String(charServiceData[19]);   //Serial.print(text10); Serial.print(" "); 
            text11 = String(charServiceData[20]) + String(charServiceData[21]);   //Serial.print(text11); Serial.print(" "); 
            text12 = String(charServiceData[22]) + String(charServiceData[23]);   //Serial.print(text12); Serial.print(" "); 
            
            //Serial.println();

            zmienna = text01; Zamien_litery(); text01 = zmienna;
            zmienna = text02; Zamien_litery(); text02 = zmienna;
            zmienna = text03; Zamien_litery(); text03 = zmienna;
            zmienna = text04; Zamien_litery(); text04 = zmienna;
            zmienna = text05; Zamien_litery(); text05 = zmienna;
            zmienna = text06; Zamien_litery(); text06 = zmienna;
            zmienna = text07; Zamien_litery(); text07 = zmienna;
            zmienna = text08; Zamien_litery(); text08 = zmienna;
            zmienna = text09; Zamien_litery(); text09 = zmienna;
            zmienna = text10; Zamien_litery(); text10 = zmienna;
            zmienna = text11; Zamien_litery(); text11 = zmienna;
            zmienna = text12; Zamien_litery(); text12 = zmienna;
            zmienna = text13; Zamien_litery(); text13 = zmienna;
            zmienna = text14; Zamien_litery(); text14 = zmienna;
            zmienna = text15; Zamien_litery(); text15 = zmienna;




            Konwersja();


            
        }
    }
};

class Czujnik1 : public Supla::Sensor::ThermHygroMeter {
 public:
  explicit Czujnik1()
  {

  }

  double getTemp() {
    temperature = temp1;
    return temperature;
  }

  double getHumi() {
    humidity = wilg1;
    return humidity;
  }

 private:
  void iterateAlways() {
    if (millis() - lastReadTime > 10000) {
      lastReadTime = millis();
      channel.setNewValue(getTemp(), getHumi());
      channel.setBatteryLevel(bat1);
    }
  }

  void onInit() {
    channel.setNewValue(getTemp(), getHumi());
    channel.setBatteryLevel(bat1);
  }

 protected:
  float temperature = - 270;
  int humidity = 0;

};
Czujnik1 *czujniczek1 = nullptr;
class Czujnik2 : public Supla::Sensor::ThermHygroMeter {
 public:
  explicit Czujnik2()
  {

  }

  double getTemp() {
    temperature = temp2;
    return temperature;
  }

  double getHumi() {
    humidity = wilg2;
    return humidity;
  }

 private:
  void iterateAlways() {
    if (millis() - lastReadTime > 10000) {
      lastReadTime = millis();
      channel.setNewValue(getTemp(), getHumi());
      channel.setBatteryLevel(bat2);
    }
  }

  void onInit() {
    channel.setNewValue(getTemp(), getHumi());
    channel.setBatteryLevel(bat2);
  }

 protected:
  float temperature = -270;
  int humidity = 0;

};
class Czujnik3 : public Supla::Sensor::ThermHygroMeter {
 public:
  explicit Czujnik3()
  {

  }

  double getTemp() {
    temperature = temp3;
    //lastValidTemp = temperature;

    return temperature;
  }

  double getHumi() {
    humidity = wilg3;
    //lastValidHumi = humidity;
    return humidity;
  }

 private:
  void iterateAlways() {
    if (millis() - lastReadTime > 10000) {
      lastReadTime = millis();
      channel.setNewValue(getTemp(), getHumi());
      channel.setBatteryLevel(bat3);
    }
  }

  void onInit() {
    channel.setNewValue(getTemp(), getHumi());
    channel.setBatteryLevel(bat3);
  }

 protected:
  float temperature = - 270;
  int humidity = 0;

};

void setup() {

  Serial.begin(115200);
  initBluetooth();

  // Channels configuration
  auto buttonCfgRelay = new Supla::Control::Button(BUTTON_CFG_RELAY_GPIO, true, true);
  buttonCfgRelay->configureAsConfigButton(&SuplaDevice);
  
  auto czujniczek1 = new Czujnik1();
  auto czujniczek2 = new Czujnik2();
  auto czujniczek3 = new Czujnik3();

  czujniczek1->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYPOWERED);
  czujniczek1->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYLEVEL);
  czujniczek2->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYPOWERED);
  czujniczek2->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYLEVEL);
  czujniczek3->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYPOWERED);
  czujniczek3->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYLEVEL);

 
  // configure defualt Supla CA certificate
  SuplaDevice.setSuplaCACert(suplaCACert);
  SuplaDevice.setSupla3rdPartyCACert(supla3rdCACert);
  SuplaDevice.setName("Supla Xiaomi");
  //SuplaDevice.addFlags(SUPLA_DEVICE_FLAG_SLEEP_MODE_ENABLED);

  SuplaDevice.begin();
}

void loop() {
  

  if (millis() - czas_pomiedzy_skanowaniem > 120000) {
    Serial.println(F("skanuje bluetooth "));
    czas_pomiedzy_skanowaniem = millis();
    NimBLEScan* pBLEScan = NimBLEDevice::getScan(); //create new scan
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
    NimBLEScanResults foundDevices = pBLEScan->start(SCAN_TIME);
    byte count = foundDevices.getCount();
    delay(100);
    od1 = od1 +1;
    od2 = od2 +1;
    od3 = od3 +1;
  }

  SuplaDevice.iterate();


    if (WiFi.status() != WL_CONNECTED) {    
      if (millis() > wifimilis)  {               
        WiFi.begin(); 
        wifimilis = (millis() + 30000) ;
      }
    }
    if (millis() > 86400000){
      ESP.restart();
    }
}
void initBluetooth()
{
    NimBLEDevice::init("");
    pBLEScan = NimBLEDevice::getScan(); //create new scan
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
    pBLEScan->setInterval(0x50);
    pBLEScan->setWindow(0x30);
}

void Konwersja()
{
  int number;
  String hexstring;
  int t1;
  int t2;


  hexstring = "#" + text07;
  number = (int) strtol( &hexstring[1], NULL, 16);
  t1 = number & 0xFF;                        

  hexstring = "#" + text08;
  number = (int) strtol( &hexstring[1], NULL, 16);
  t2 = number & 0xFF;

  current_temperature = t1 * 256;
  current_temperature = current_temperature + t2;
  current_temperature = current_temperature / 10;
  // Konwersja z Faranheitów na Celsjusze
                                      
  hexstring = "#" + text09;
  number = (int) strtol( &hexstring[1], NULL, 16);
  current_humidity = number & 0xFF;

  hexstring = "#" + text10;
  number = (int) strtol( &hexstring[1], NULL, 16);
  current_batt = number & 0xFF;
  
  MAC_ADR = "";
  MAC_ADR = MAC_ADR + text01 + ":";
  MAC_ADR = MAC_ADR + text02 + ":";
  MAC_ADR = MAC_ADR + text03 + ":";
  MAC_ADR = MAC_ADR + text04 + ":";
  MAC_ADR = MAC_ADR + text05 + ":";
  MAC_ADR = MAC_ADR + text06;

  BLE_DEVICE = 0;
  if(MAC_ADR == XIAOMI_BLE_DEVICE_1_MAC){BLE_DEVICE = 1; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_2_MAC){BLE_DEVICE = 2; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_3_MAC){BLE_DEVICE = 3; wyswietl = 1; Wyswietl();} 
}
void Wyswietl(){
  if(wyswietl == 1){
    Serial.print(F("Urządzenie:"));
    Serial.print(BLE_DEVICE);
    Serial.print(F(" MAC: ")); 
    Serial.print(MAC_ADR);
                                   
    Serial.print(F(" Temp: "));
    Serial.print(current_temperature,1);
    Serial.print(F("stC. Wilgotnosc: "));
    Serial.print(current_humidity);
    Serial.print(F("%. Bateria: "));
    Serial.print(current_batt);
    Serial.println(F("%."));   
    if (BLE_DEVICE == 1) {
      temp1 = (current_temperature);
      wilg1 = current_humidity;
      bat1 = current_batt;
      od1 = 0;
    }
    if (BLE_DEVICE == 2) {
      temp2 = (current_temperature);
      wilg2 = current_humidity;
      bat2 = current_batt;
      od2 = 0;
    }
    if (BLE_DEVICE == 3) {
      temp3 = (current_temperature);
      wilg3 = (current_humidity);
      bat3 = (current_batt);
      od3 = 0;
    }
    if (od1 > 5){
      temp1 = -275;
      wilg1 = -1;
      bat1 = 0;
      od1 = 0;
    }
    if (od2 > 5){
      temp2 = -275;
      wilg2 = -1;
      bat2 = 0;
      od2 = 0;
    }
    if (od3 > 5){
      temp3 = -275;
      wilg3 = -1;
      bat3 = 0;
      od3 = 0;
    }
    wyswietl = 0; 
  }
}

void Zamien_litery()  //Zamieniamy otrzymywane małe litery na duże
{
  zmienna.replace('a', 'A');
  zmienna.replace('b', 'B');
  zmienna.replace('c', 'C');
  zmienna.replace('d', 'D');
  zmienna.replace('e', 'E');
  zmienna.replace('f', 'F');
}
biblioteka potrzebna do uruchomienia programu:
https://github.com/h2zero/NimBLE-Arduino
Zamel Mew-01, Zamel PEW-01, Zamel SBW-01, Zamel THW-01, Zamel SRW-01, Zamel mSLW-02, Auraton BOX + Indor Sensor, Airly Gate By Veeroos, Zigbee to Supla Gateway + sensors, Zamel SGW-01 and more

https://github.com/v33r005
Michał P.
Posts: 26
Joined: Wed Jan 03, 2024 2:24 pm

Post

@veeroos bardzo dziękuję za kod, wrzuciłem wczoraj wieczorem i aktualnie wszystkie odczyty z czujników zostały przesłane do chmury. Moduł się nie wiesza, nie ma przerw, jest o wiele chłodniejszy, jeszcze raz dzięki za dobrą robotę! Jeden z czujników wystawiłem przez okno, gdzie panowała temperatura ujemna i wskazywał błędny odczyt (6550,0), możliwe że coś jest źle przeliczane przy ujemnych temperaturach? Czujnik na ekranie pokazywał -4,7*C. Sprawdziłem inny i sytuacja się powtórzyła :/
You do not have the required permissions to view the files attached to this post.
User avatar
veeroos
Posts: 1081
Joined: Sun Mar 20, 2022 9:30 am
Location: Głogów
Has thanked: 1 time
Been thanked: 9 times

Post

Wiesz co wydaje mi się że to jest kwestia alternatywnego softu dla tych czujników, musiałbyś na przykład spróbować odczytać ten czujnik przez tą stronę, przez którą zmieniłeś soft w czujnikach, jaki jest odczyt, bo może jego twórca nie przewidział, że ktoś czujniki pokojowe na mróz wystawi 😉. Ja wrzucam odczyt z tych czujników pod klasę termometru i tu nie powinno być problemu, bo normalnie ta klasa radzi sobie z ujemnymi wartościami, chyba że sprawdź jeszcze w kodzie i tam gdzie są klasy do tych czujników zmień typ zmiennej z float na double w sekcji protected

Edit. Na customowym firmware nie odczytasz wartości tą stroną, zmień typ zmiennych

Kolejny Edit. Zawsze też możesz zobaczyć przez monitor portu szeregowego w Arduino jakie wartości są odczytywane przez czujnik, wtedy będzie widać czy problem jest z wysyłanymi przez czujnik danymi, czy z klasą, która wrzuca wartość odczytaną na serwer
Zamel Mew-01, Zamel PEW-01, Zamel SBW-01, Zamel THW-01, Zamel SRW-01, Zamel mSLW-02, Auraton BOX + Indor Sensor, Airly Gate By Veeroos, Zigbee to Supla Gateway + sensors, Zamel SGW-01 and more

https://github.com/v33r005
potikha6
Posts: 1
Joined: Thu Jan 04, 2024 1:05 pm

Post

Hey @veeroos, great news! Your code is working smoothly—no more hanging or interruptions and all sensor readings are reaching the cloud.

However, I'm noticing an issue with negative temperature readings. When I placed a sensor outside where it was below zero, it reported 6550.0 instead of the actual temperature (-4.7*C). I checked another sensor and got the same result. Could you take a look at this? WhatsApp Plus
Last edited by potikha6 on Wed Jan 08, 2025 8:22 am, edited 2 times in total.
Adamus10
Posts: 31
Joined: Sat Oct 28, 2023 8:05 pm
Been thanked: 6 times

Post

Kod działa super dla 3 czujników. Ale u mnie jest ich wiecej i nieoptymalne jest kopiowanie oraz powtarzanie cześci kodu. Czy dałoby rade przerobić to jakoś uniwersalniej?
veeroos wrote: Sat Jan 06, 2024 5:11 pm obiecany kod:

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 STATUS_LED_GPIO 2
#define BUTTON_CFG_RELAY_GPIO 0
#include <sstream>
#include <NimBLEDevice.h>
#include <NimBLEScan.h>
#include <NimBLEAdvertisedDevice.h>


#include <SuplaDevice.h>
#include <supla/network/esp_wifi.h>
#include <supla/control/button.h>
#include <supla/control/action_trigger.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/sensor/therm_hygro_meter.h>
#include <supla/sensor/thermometer.h>

#define SCAN_TIME  2 // seconds
byte od1 = 0;
byte od2 = 0;
byte od3 = 0;
int wilg1 = -1;
float temp1 = -275;
int wilg2 = -1;
float temp2 = -275;
int wilg3 = -1;
float temp3 = -275;
byte bat1 = 0;
byte bat2 = 0;
byte bat3 = 0;
unsigned long czas_pomiedzy_skanowaniem;
unsigned long wifimilis;
unsigned long lastReadTime = 0;

boolean METRIC = true; //Set true for metric system; false for imperial

String text01;
String text02;
String text03;
String text04;
String text05;
String text06;
String text07;
String text08;
String text09;
String text10;
String text11;
String text12;
String text13;
String text14;
String text15;
String zmienna;
String MAC_ADR;
byte BLE_DEVICE;
bool wyswietl = 0;

#define XIAOMI_BLE_DEVICE_1_MAC "A4:C1:38:0D:AE:08"
#define XIAOMI_BLE_DEVICE_2_MAC "A4:C1:38:10:3D:44"
#define XIAOMI_BLE_DEVICE_3_MAC "A4:C1:38:43:6A:FE"
//#define XIAOMI_BLE_DEVICE_1_MAC "A4:C1:38:AF:35:85"
//#define XIAOMI_BLE_DEVICE_2_MAC "A4:C1:38:FA:F0:FB"
//#define XIAOMI_BLE_DEVICE_3_MAC "A4:C1:38:E3:84:F4"

//#include <supla/storage/eeprom.h>
//Supla::Eeprom eeprom;

Supla::ESPWifi wifi;
Supla::LittleFsConfig configSupla;

Supla::Device::StatusLed statusLed(STATUS_LED_GPIO, true); // inverted state
Supla::EspWebServer suplaServer;
//wifi.setSSLEnabled(false);
Supla::Html::DeviceInfo htmlDeviceInfo(&SuplaDevice);
Supla::Html::WifiParameters htmlWifi;
Supla::Html::ProtocolParameters htmlProto;
Supla::Html::StatusLedParameters htmlStatusLed;

byte current_humidity;
byte current_batt;

word val;

NimBLEScan *pBLEScan;

void IRAM_ATTR resetModule(){
    ets_printf("reboot\n");
    esp_restart();
}

float current_temperature;

class MyAdvertisedDeviceCallbacks : public NimBLEAdvertisedDeviceCallbacks {
    void onResult(NimBLEAdvertisedDevice* advertisedDevice)
    {
        if (advertisedDevice->haveName() && advertisedDevice->haveServiceData()) {

            int serviceDataCount = advertisedDevice->getServiceDataCount();
            std::string strServiceData = advertisedDevice->getServiceData(0);

            uint8_t cServiceData[100];
            char charServiceData[100];

            strServiceData.copy((char *)cServiceData, strServiceData.length(), 0);

            for (int i=0;i<strServiceData.length();i++) {
                sprintf(&charServiceData[i*2], "%02x", cServiceData[i]);
            }

            std::stringstream ss;
            ss << "fe95" << charServiceData;

            

            text01 = String(charServiceData[0]) + String(charServiceData[1]);      //Serial.print(text1); Serial.print(" ");
            text02 = String(charServiceData[2]) + String(charServiceData[3]);      //Serial.print(text2); Serial.print(" ");
            text03 = String(charServiceData[4]) + String(charServiceData[5]);      //Serial.print(text3); Serial.print(" ");
            text04 = String(charServiceData[6]) + String(charServiceData[7]);      //Serial.print(text4); Serial.print(" ");
            text05 = String(charServiceData[8]) + String(charServiceData[9]);      //Serial.print(text5); Serial.print(" "); 
            text06 = String(charServiceData[10]) + String(charServiceData[11]);    //Serial.print(text6); Serial.print(" "); 
            text07 = String(charServiceData[12]) + String(charServiceData[13]);    //Serial.print(text7); Serial.print(" "); 
            text08 = String(charServiceData[14]) + String(charServiceData[15]);    //Serial.print(text8); Serial.print(" "); 
            text09 = String(charServiceData[16]) + String(charServiceData[17]);    //Serial.print(text9); Serial.print(" "); 
            text10 = String(charServiceData[18]) + String(charServiceData[19]);   //Serial.print(text10); Serial.print(" "); 
            text11 = String(charServiceData[20]) + String(charServiceData[21]);   //Serial.print(text11); Serial.print(" "); 
            text12 = String(charServiceData[22]) + String(charServiceData[23]);   //Serial.print(text12); Serial.print(" "); 
            
            //Serial.println();

            zmienna = text01; Zamien_litery(); text01 = zmienna;
            zmienna = text02; Zamien_litery(); text02 = zmienna;
            zmienna = text03; Zamien_litery(); text03 = zmienna;
            zmienna = text04; Zamien_litery(); text04 = zmienna;
            zmienna = text05; Zamien_litery(); text05 = zmienna;
            zmienna = text06; Zamien_litery(); text06 = zmienna;
            zmienna = text07; Zamien_litery(); text07 = zmienna;
            zmienna = text08; Zamien_litery(); text08 = zmienna;
            zmienna = text09; Zamien_litery(); text09 = zmienna;
            zmienna = text10; Zamien_litery(); text10 = zmienna;
            zmienna = text11; Zamien_litery(); text11 = zmienna;
            zmienna = text12; Zamien_litery(); text12 = zmienna;
            zmienna = text13; Zamien_litery(); text13 = zmienna;
            zmienna = text14; Zamien_litery(); text14 = zmienna;
            zmienna = text15; Zamien_litery(); text15 = zmienna;




            Konwersja();


            
        }
    }
};

class Czujnik1 : public Supla::Sensor::ThermHygroMeter {
 public:
  explicit Czujnik1()
  {

  }

  double getTemp() {
    temperature = temp1;
    return temperature;
  }

  double getHumi() {
    humidity = wilg1;
    return humidity;
  }

 private:
  void iterateAlways() {
    if (millis() - lastReadTime > 10000) {
      lastReadTime = millis();
      channel.setNewValue(getTemp(), getHumi());
      channel.setBatteryLevel(bat1);
    }
  }

  void onInit() {
    channel.setNewValue(getTemp(), getHumi());
    channel.setBatteryLevel(bat1);
  }

 protected:
  float temperature = - 270;
  int humidity = 0;

};
Czujnik1 *czujniczek1 = nullptr;
class Czujnik2 : public Supla::Sensor::ThermHygroMeter {
 public:
  explicit Czujnik2()
  {

  }

  double getTemp() {
    temperature = temp2;
    return temperature;
  }

  double getHumi() {
    humidity = wilg2;
    return humidity;
  }

 private:
  void iterateAlways() {
    if (millis() - lastReadTime > 10000) {
      lastReadTime = millis();
      channel.setNewValue(getTemp(), getHumi());
      channel.setBatteryLevel(bat2);
    }
  }

  void onInit() {
    channel.setNewValue(getTemp(), getHumi());
    channel.setBatteryLevel(bat2);
  }

 protected:
  float temperature = -270;
  int humidity = 0;

};
class Czujnik3 : public Supla::Sensor::ThermHygroMeter {
 public:
  explicit Czujnik3()
  {

  }

  double getTemp() {
    temperature = temp3;
    //lastValidTemp = temperature;

    return temperature;
  }

  double getHumi() {
    humidity = wilg3;
    //lastValidHumi = humidity;
    return humidity;
  }

 private:
  void iterateAlways() {
    if (millis() - lastReadTime > 10000) {
      lastReadTime = millis();
      channel.setNewValue(getTemp(), getHumi());
      channel.setBatteryLevel(bat3);
    }
  }

  void onInit() {
    channel.setNewValue(getTemp(), getHumi());
    channel.setBatteryLevel(bat3);
  }

 protected:
  float temperature = - 270;
  int humidity = 0;

};

void setup() {

  Serial.begin(115200);
  initBluetooth();

  // Channels configuration
  auto buttonCfgRelay = new Supla::Control::Button(BUTTON_CFG_RELAY_GPIO, true, true);
  buttonCfgRelay->configureAsConfigButton(&SuplaDevice);
  
  auto czujniczek1 = new Czujnik1();
  auto czujniczek2 = new Czujnik2();
  auto czujniczek3 = new Czujnik3();

  czujniczek1->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYPOWERED);
  czujniczek1->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYLEVEL);
  czujniczek2->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYPOWERED);
  czujniczek2->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYLEVEL);
  czujniczek3->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYPOWERED);
  czujniczek3->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYLEVEL);

 
  // configure defualt Supla CA certificate
  SuplaDevice.setSuplaCACert(suplaCACert);
  SuplaDevice.setSupla3rdPartyCACert(supla3rdCACert);
  SuplaDevice.setName("Supla Xiaomi");
  //SuplaDevice.addFlags(SUPLA_DEVICE_FLAG_SLEEP_MODE_ENABLED);

  SuplaDevice.begin();
}

void loop() {
  

  if (millis() - czas_pomiedzy_skanowaniem > 120000) {
    Serial.println(F("skanuje bluetooth "));
    czas_pomiedzy_skanowaniem = millis();
    NimBLEScan* pBLEScan = NimBLEDevice::getScan(); //create new scan
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
    NimBLEScanResults foundDevices = pBLEScan->start(SCAN_TIME);
    byte count = foundDevices.getCount();
    delay(100);
    od1 = od1 +1;
    od2 = od2 +1;
    od3 = od3 +1;
  }

  SuplaDevice.iterate();


    if (WiFi.status() != WL_CONNECTED) {    
      if (millis() > wifimilis)  {               
        WiFi.begin(); 
        wifimilis = (millis() + 30000) ;
      }
    }
    if (millis() > 86400000){
      ESP.restart();
    }
}
void initBluetooth()
{
    NimBLEDevice::init("");
    pBLEScan = NimBLEDevice::getScan(); //create new scan
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
    pBLEScan->setInterval(0x50);
    pBLEScan->setWindow(0x30);
}

void Konwersja()
{
  int number;
  String hexstring;
  int t1;
  int t2;


  hexstring = "#" + text07;
  number = (int) strtol( &hexstring[1], NULL, 16);
  t1 = number & 0xFF;                        

  hexstring = "#" + text08;
  number = (int) strtol( &hexstring[1], NULL, 16);
  t2 = number & 0xFF;

  current_temperature = t1 * 256;
  current_temperature = current_temperature + t2;
  current_temperature = current_temperature / 10;
  // Konwersja z Faranheitów na Celsjusze
                                      
  hexstring = "#" + text09;
  number = (int) strtol( &hexstring[1], NULL, 16);
  current_humidity = number & 0xFF;

  hexstring = "#" + text10;
  number = (int) strtol( &hexstring[1], NULL, 16);
  current_batt = number & 0xFF;
  
  MAC_ADR = "";
  MAC_ADR = MAC_ADR + text01 + ":";
  MAC_ADR = MAC_ADR + text02 + ":";
  MAC_ADR = MAC_ADR + text03 + ":";
  MAC_ADR = MAC_ADR + text04 + ":";
  MAC_ADR = MAC_ADR + text05 + ":";
  MAC_ADR = MAC_ADR + text06;

  BLE_DEVICE = 0;
  if(MAC_ADR == XIAOMI_BLE_DEVICE_1_MAC){BLE_DEVICE = 1; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_2_MAC){BLE_DEVICE = 2; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_3_MAC){BLE_DEVICE = 3; wyswietl = 1; Wyswietl();} 
}
void Wyswietl(){
  if(wyswietl == 1){
    Serial.print(F("Urządzenie:"));
    Serial.print(BLE_DEVICE);
    Serial.print(F(" MAC: ")); 
    Serial.print(MAC_ADR);
                                   
    Serial.print(F(" Temp: "));
    Serial.print(current_temperature,1);
    Serial.print(F("stC. Wilgotnosc: "));
    Serial.print(current_humidity);
    Serial.print(F("%. Bateria: "));
    Serial.print(current_batt);
    Serial.println(F("%."));   
    if (BLE_DEVICE == 1) {
      temp1 = (current_temperature);
      wilg1 = current_humidity;
      bat1 = current_batt;
      od1 = 0;
    }
    if (BLE_DEVICE == 2) {
      temp2 = (current_temperature);
      wilg2 = current_humidity;
      bat2 = current_batt;
      od2 = 0;
    }
    if (BLE_DEVICE == 3) {
      temp3 = (current_temperature);
      wilg3 = (current_humidity);
      bat3 = (current_batt);
      od3 = 0;
    }
    if (od1 > 5){
      temp1 = -275;
      wilg1 = -1;
      bat1 = 0;
      od1 = 0;
    }
    if (od2 > 5){
      temp2 = -275;
      wilg2 = -1;
      bat2 = 0;
      od2 = 0;
    }
    if (od3 > 5){
      temp3 = -275;
      wilg3 = -1;
      bat3 = 0;
      od3 = 0;
    }
    wyswietl = 0; 
  }
}

void Zamien_litery()  //Zamieniamy otrzymywane małe litery na duże
{
  zmienna.replace('a', 'A');
  zmienna.replace('b', 'B');
  zmienna.replace('c', 'C');
  zmienna.replace('d', 'D');
  zmienna.replace('e', 'E');
  zmienna.replace('f', 'F');
}
biblioteka potrzebna do uruchomienia programu:
https://github.com/h2zero/NimBLE-Arduino
User avatar
veeroos
Posts: 1081
Joined: Sun Mar 20, 2022 9:30 am
Location: Głogów
Has thanked: 1 time
Been thanked: 9 times

Post

potikha6 wrote: Sat Jan 13, 2024 9:59 am Could you take a look at this?
HI. My temperature is now positive, I have no way to check it. I put the sensor in the freezer and it stopped working.See what logs you have when reading the sensor.

@Adamus10 ja mam przygotowany kod pod 5 czujników jeśli to Cię ratuje, w przyszłości chcę dorobić taką funkcję, że w webserwerze będziesz mógł sobie wybrać ile czujników potrzebujesz i wpisać ich adresy MAC. Ale na to chwilę trzeba będzie jeszcze poczekać, bo mam parę tematów teraz rozgrzebanych i chcę je najpierw skończyć, bo tu będzie sporo zmian
Zamel Mew-01, Zamel PEW-01, Zamel SBW-01, Zamel THW-01, Zamel SRW-01, Zamel mSLW-02, Auraton BOX + Indor Sensor, Airly Gate By Veeroos, Zigbee to Supla Gateway + sensors, Zamel SGW-01 and more

https://github.com/v33r005

Return to “Zagadnienia ogólne”