XIAOMI LYWSD03MMC - odczyt przez ESP32

t0mek
Posty: 73
Rejestracja: sob gru 02, 2017 11:24 am
Lokalizacja: Legnica

Podpowie ktoś / nakieruje - jak wskaźnik naładowania baterii umieścić w menu z "i". Jakiś przykład / punkt zaczepny :?:
Pozdrawiam
Tomek
Awatar użytkownika
veeroos
Posty: 271
Rejestracja: ndz mar 20, 2022 9:30 am
Lokalizacja: Głogów

t0mek pisze: ndz lut 19, 2023 11:29 am Podpowie ktoś / nakieruje - jak wskaźnik naładowania baterii umieścić w menu z "i". Jakiś przykład / punkt zaczepny :?:
viewtopic.php?t=6963 popatrz tutaj 😉 też się do tego przymierzałem, może w końcu w ten sposób to ogarnę.

W sumie kolega @klew opisał to w tym wątku:
viewtopic.php?p=130385#p130385
Zamel Mew-01, Wemos D1 mini Pro + Ikea vindriktning + BME280, 3x - SonOff mini, 3x - SonOff Basic, 3xGosund SP111, SonOff S55, 2x GOSUND WB4
Juszczaczek1
Posty: 256
Rejestracja: ndz lis 08, 2020 3:41 pm

a wytłumaczy mi ktoś co muszę mieć i zrobić by wgrać to na wemosa d1 mini 32 , dokładnie co w tym kodzie muszę zmienić i jakim programem wgrać
martinok
Posty: 126
Rejestracja: sob gru 17, 2016 10:12 am
Lokalizacja: Poznań

Ja wgrywam Arduino IDE,
Jeżeli wemos d1 mini 32 w setup() musisz dodać linię

Kod: Zaznacz cały

 wifi.setSSLEnabled(false);
 
"Wiedza bez Praktyki jest Bezużyteczna , praktyka bez wiedzy Niebezpieczna"...
Awatar użytkownika
veeroos
Posty: 271
Rejestracja: ndz mar 20, 2022 9:30 am
Lokalizacja: Głogów

A w kodzie zmieniasz na swoje adresy czujników Xiaomi. Ja używam 3 sztuk więc kod jest na 3 czujniki, jak używasz mniej to wystarczy że w setupie zakomentujesz pozostałe czujniki, klasy mogą zostać.
Zamel Mew-01, Wemos D1 mini Pro + Ikea vindriktning + BME280, 3x - SonOff mini, 3x - SonOff Basic, 3xGosund SP111, SonOff S55, 2x GOSUND WB4
Juszczaczek1
Posty: 256
Rejestracja: ndz lis 08, 2020 3:41 pm

Wkleiłem ten kod do Arduino IDE i mi wyskoczył jakiś błąd z tym

#include <sstream>

veeroos pisze: ndz lut 19, 2023 7:49 am
t0mek pisze: ndz lut 19, 2023 6:52 am @veeroos dobra robota!
potwierdzam działanie na S3 Dev :D . Faktycznie wywala połączenie (od 15 do 30 min) ale odrazu się łączy. Niezauważalne - nawet na wykresach tego nie widać - pewnie mija się z odczytem z czujników.
@veeroos zapodasz kod z odczytem baterii?
Można się pobawić i rozbudować tryb konfiguracji, żeby dodawać nowe czujniki lub edytować aktualne - nie trzeba by było kompilować nowego softu przy rozbudowie.
ps ale co włosów wyrwałem, żeby dopasować wszystko w arduino :roll: ... tak to jest jak raz na pół roku wchodzisz w temat...
Oj tam największą robotę zrobił kolega @Duch__, ja tylko napisałem kawałek kodu który wrzuca dane do Supli ;-).
Aktualnie kod wygląda tak:

Kod: Zaznacz cały

/*
  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 <BLEDevice.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.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  5 // seconds

int od1 = 0;
int od2 = 0;
int od3 = 0;
int wilg1 = -1;
float temp1 = -275;
int wilg2 = -1;
float temp2 = -275;
int wilg3 = -1;
float temp3 = -275;
float bat1 = -275;
float bat2 = -275;
float bat3 = -275;
unsigned long czas_pomiedzy_skanowaniem;
unsigned long wifimilis;
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"

#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;

int current_humidity;
int current_batt;

word val;

BLEScan *pBLEScan;

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

float current_temperature;

class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice)
    {
        if (advertisedDevice.haveName() && advertisedDevice.haveServiceData() /*&& !advertisedDevice.getName().compare("ATC_9C1E8B")*/) {

            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());
    }
  }

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

 protected:
  double temperature = - 270;
  double humidity = 0;

};
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());
    }
  }

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

 protected:
  double temperature = -270;
  double 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());
    }
  }

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

 protected:
  double temperature = - 270;
  double humidity = 0;

};

class Bateria1 : public Supla::Sensor::Thermometer {
  public:
     Bateria1() {
    }

    double getValue() 
    {
     battery = bat1;
      return battery;
    }
    void iterateAlways() {
      channel.setNewValue(getValue());
    }
    void onInit() {
      channel.setNewValue(getValue());
    }
    protected:
    float battery;
};

class Bateria2 : public Supla::Sensor::Thermometer {
  public:
     Bateria2() {
    }

    double getValue() 
    {
     battery = bat2;
      return battery;
    }
    void iterateAlways() {
      channel.setNewValue(getValue());
    }
    void onInit() {
      channel.setNewValue(getValue());
    }
    protected:
    float battery;
};
class Bateria3 : public Supla::Sensor::Thermometer {
  public:
     Bateria3() {
    }

    double getValue() 
    {
     battery = bat3;
      return battery;
    }
    void iterateAlways() {
      channel.setNewValue(getValue());
    }
    void onInit() {
      channel.setNewValue(getValue());
    }
    protected:
    float battery;
};

void setup() {

  Serial.begin(115200);
  initBluetooth();
  //WiFi.begin();
  // Channels configuration
  auto buttonCfgRelay = new Supla::Control::Button(BUTTON_CFG_RELAY_GPIO, true, true);
  buttonCfgRelay->configureAsConfigButton(&SuplaDevice);
  new Czujnik1();
  new Bateria1();
  new Czujnik2();
  new Bateria2();
  new Czujnik3();
  new Bateria3();
  // configure defualt Supla CA certificate
  SuplaDevice.setSuplaCACert(suplaCACert);
  SuplaDevice.setSupla3rdPartyCACert(supla3rdCACert);

  SuplaDevice.begin();
}

void loop() {
  if (millis() - czas_pomiedzy_skanowaniem > 120000) {
    czas_pomiedzy_skanowaniem = millis();
    BLEScan* pBLEScan = BLEDevice::getScan(); //create new scan
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
    BLEScanResults foundDevices = pBLEScan->start(SCAN_TIME);
    int 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() + 20000) ;
    }
  }
}
void initBluetooth()
{
    BLEDevice::init("");
    pBLEScan = BLEDevice::getScan(); //create new scan
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(false); //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("Urządzenie:");
    Serial.print(BLE_DEVICE);
    Serial.print(" MAC: "); 
    Serial.print(MAC_ADR);
                                   
    Serial.print(" Temp: ");
    Serial.print(current_temperature,1);
    Serial.print("stC. Wilgotnosc: ");
    Serial.print(current_humidity);
    Serial.print("%. Bateria: ");
    Serial.print(current_batt);
    Serial.println("%.");   
    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 = -275;
      od1 = 0;
    }
    if (od2 > 5){
      temp2 = -275;
      wilg2 = -1;
      bat2 = -275;
      od2 = 0;
    }
    if (od3 > 5){
      temp3 = -275;
      wilg3 = -1;
      bat3 = -275;
      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');
}
Może i mieć błędy, ale chodzi. Stan baterii wyświetlany jest procentowo, a jeśli chodzi o wyświetlanie danych na Supli to z tego co pamiętam co 10 minut rejestrowane są dane na serwerze. Czujnik są odpytywane niezależnie od polączenia z serwerem, ich wartości są zapisywane do zmiennych, więc jak nawet połączenie się zerwie to w zmiennych dane pozostają aktualne. Ja dzisiaj w nocy miałem na wykresie koło północy tak z 10 minutową przerwę odczytu danych, a tak to chodzi poprawnie, oczywiście na ESP32 S3 ;-)

Screenshot_2023-02-19-08-57-01-857_org.supla.android.jpg

A tak wygląda to aktualnie 😉
Awatar użytkownika
klew
Posty: 8184
Rejestracja: czw cze 27, 2019 12:16 pm
Lokalizacja: Wrocław

Juszczaczek1 pisze: pn lut 20, 2023 8:12 am Wkleiłem ten kod do Arduino IDE i mi wyskoczył jakiś błąd z tym
#include <sstream>
W błędach kompilacji najważniejszy z reguły jest błąd wyświetlany na ekranie. To najczęściej najbardziej pomaga w próbie ustalenia co poszło nie tak.

Jeśli problem jest na include, to prawdodpobnie nie może znaleźć tego pliku. sstream pochodzi z kompilatora, więc najprawdopodobniej masz jakieś starsze wersje boardów dla ESP32. Zaktualizuj i sprawdź jeszcze raz.
Aktualna wersja to 2.0.6
Widzimy się na Supla Offline Party vol. 2 :!:
Juszczaczek1
Posty: 256
Rejestracja: ndz lis 08, 2020 3:41 pm

zaktualizowałem i juz nie mam tego błedu ale teraz taki mi wyskoczył
exit status 1
'BLEScan' does not name a type
klew pisze: pn lut 20, 2023 8:17 am
Juszczaczek1 pisze: pn lut 20, 2023 8:12 am Wkleiłem ten kod do Arduino IDE i mi wyskoczył jakiś błąd z tym
#include <sstream>
W błędach kompilacji najważniejszy z reguły jest błąd wyświetlany na ekranie. To najczęściej najbardziej pomaga w próbie ustalenia co poszło nie tak.

Jeśli problem jest na include, to prawdodpobnie nie może znaleźć tego pliku. sstream pochodzi z kompilatora, więc najprawdopodobniej masz jakieś starsze wersje boardów dla ESP32. Zaktualizuj i sprawdź jeszcze raz.
Aktualna wersja to 2.0.6
Awatar użytkownika
klew
Posty: 8184
Rejestracja: czw cze 27, 2019 12:16 pm
Lokalizacja: Wrocław

Juszczaczek1 pisze: pn lut 20, 2023 5:13 pm zaktualizowałem i juz nie mam tego błedu ale teraz taki mi wyskoczył
exit status 1
'BLEScan' does not name a type
Teraz albo brakuje jakiejś biblioteki od ble, albo ona jest nieaktualna, albo program był pisany na innych wersjach biblioteki lub boardów.
Widzimy się na Supla Offline Party vol. 2 :!:
Juszczaczek1
Posty: 256
Rejestracja: ndz lis 08, 2020 3:41 pm

Dzięki , chyba się poddam , myślałem że to łatwiejsze :⁠-⁠P
ODPOWIEDZ

Wróć do „Zagadnienia ogólne”