XIAOMI LYWSD03MMC - odczyt przez ESP32

Awatar użytkownika
Duch__
Posty: 1779
Rejestracja: śr sie 24, 2016 7:26 pm
Lokalizacja: Opole

LYW.png
LYW.png (45.15 KiB) Przejrzano 3880 razy
Witam.

Wrzucam dla potomnych programik odczytujący czujniki XIAOMI LYWSD03MMC (temperatura, wilgotność, poziom naładowania baterii) przez moduł WIFI ESP32. Wymagane jest aby moduły XIAOMI miały zmienione oprogramowanie na ATC_Thermometer.bin pobrane ze strony https://github.com/atc1441/ATC_MiThermometer poprzez "programator" https://atc1441.github.io/TelinkFlasher.html. Zmiana oprogramowania jest bezinwazyjna, nie wymaga otwierania obudowy, lutowania etc. W każdej chwili można przywrócić oryginalny soft. Jest to alternatywne do bramki na raspberry pi.
Telink.png
Telink.png (45.32 KiB) Przejrzano 3880 razy



Soft jest rozwojowy:

Kod: Zaznacz cały

//Do poprawnej pracy wymagana jest zmiana firmware w module LYWSD03MMC na ATC_Thermometer.bin (https://github.com/atc1441/ATC_MiThermometer) i wgranie go przez tą stronę https://atc1441.github.io/TelinkFlasher.html


#include <sstream>

#include <BLEDevice.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

#define SCAN_TIME  20 // seconds

#define Blue_LED 2

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:9C:1E:8B"
#define XIAOMI_BLE_DEVICE_2_MAC "A4:C1:38:4F:AC:B8"
#define XIAOMI_BLE_DEVICE_3_MAC "A4:C1:38:00:00:01"
#define XIAOMI_BLE_DEVICE_4_MAC "A4:C1:38:00:00:02"
#define XIAOMI_BLE_DEVICE_5_MAC "A4:C1:38:00:00:03"
#define XIAOMI_BLE_DEVICE_6_MAC "A4:C1:38:00:00:04"
#define XIAOMI_BLE_DEVICE_7_MAC "A4:C1:38:00:00:05"
#define XIAOMI_BLE_DEVICE_8_MAC "A4:C1:38:00:00:06"
#define XIAOMI_BLE_DEVICE_9_MAC "A4:C1:38:00:00:07"
#define XIAOMI_BLE_DEVICE_10_MAC "A4:C1:38:00:00:08"
#define XIAOMI_BLE_DEVICE_11_MAC "A4:C1:38:00:00:09"
#define XIAOMI_BLE_DEVICE_12_MAC "A4:C1:38:00:00:0A"
#define XIAOMI_BLE_DEVICE_13_MAC "A4:C1:38:00:00:0B"
#define XIAOMI_BLE_DEVICE_14_MAC "A4:C1:38:00:00:0C"
#define XIAOMI_BLE_DEVICE_15_MAC "A4:C1:38:00:00:0D"
#define XIAOMI_BLE_DEVICE_16_MAC "A4:C1:38:00:00:0E"
#define XIAOMI_BLE_DEVICE_17_MAC "A4:C1:38:00:00:0F"
#define XIAOMI_BLE_DEVICE_18_MAC "A4:C1:38:00:00:10"
#define XIAOMI_BLE_DEVICE_19_MAC "A4:C1:38:00:00:11"
#define XIAOMI_BLE_DEVICE_20_MAC "A4:C1:38:00:00:12"





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

            //Serial.printf("\n\nAdvertised Device: %s\n", advertisedDevice.toString().c_str());

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


            
        }
    }
};

void setup() {
  
  pinMode(Blue_LED,OUTPUT);

  Serial.begin(115200);
  Serial.println("ESP32 XIAOMI LYWSD03MMC");
 
  initBluetooth();


}

void loop() {
  
    char printLog[256];
    Serial.println(" ");
    Serial.println(" ");
    Serial.println(" ");
    Serial.println(" ");
    Serial.println(" ");
    Serial.printf("Start skanowania BLE przez %d sekund...\n", SCAN_TIME);
    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();

    printf("Liczba znalezionych urządzeń : %d\n", count);

    delay(100);
}



void initBluetooth()
{
    BLEDevice::init("");
    pBLEScan = BLEDevice::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();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_4_MAC){BLE_DEVICE = 4; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_5_MAC){BLE_DEVICE = 5; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_6_MAC){BLE_DEVICE = 6; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_7_MAC){BLE_DEVICE = 7; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_8_MAC){BLE_DEVICE = 8; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_9_MAC){BLE_DEVICE = 9; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_10_MAC){BLE_DEVICE = 10; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_11_MAC){BLE_DEVICE = 11; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_12_MAC){BLE_DEVICE = 12; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_13_MAC){BLE_DEVICE = 13; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_14_MAC){BLE_DEVICE = 14; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_15_MAC){BLE_DEVICE = 15; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_16_MAC){BLE_DEVICE = 16; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_17_MAC){BLE_DEVICE = 17; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_18_MAC){BLE_DEVICE = 18; wyswietl = 1; Wyswietl();}
  if(MAC_ADR == XIAOMI_BLE_DEVICE_19_MAC){BLE_DEVICE = 19; wyswietl = 1; Wyswietl();} 
  if(MAC_ADR == XIAOMI_BLE_DEVICE_20_MAC){BLE_DEVICE = 20; 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("%.");   
    wyswietl = 0; 
  }
  else
  {
    Serial.print("Wykryto nieznane urządzenie");
    Serial.print(" MAC: "); 
    Serial.print(MAC_ADR);
    Serial.println(" ");
    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');
}
Przykładowy wynik odczytu:
BLE.png
BLE.png (17.99 KiB) Przejrzano 3880 razy
Ostatnio zmieniony wt sie 23, 2022 6:23 pm przez Duch__, łącznie zmieniany 1 raz.
Obrazek
krycha88
Posty: 5187
Rejestracja: pt lis 16, 2018 7:25 am
Kontakt:

Jaki jest zasięg takich czujników?
https://gui-generic-builder.supla.io/
Awatar użytkownika
Duch__
Posty: 1779
Rejestracja: śr sie 24, 2016 7:26 pm
Lokalizacja: Opole

Jeden wyłapuje w odległości 5m (przez ścianę murowaną 12cm), a drugi w okolicy 10m (przez strop teriva + żelbet + 2 ściany działowe).
Obrazek
mdi87
Posty: 487
Rejestracja: czw wrz 17, 2020 10:00 am
Lokalizacja: Leoncin

Może i głupie pytanie bo nie do końca wiem o co chodzi, czy widać temperure w aplikacji ?
Awatar użytkownika
artur_n
Posty: 435
Rejestracja: czw sie 17, 2017 2:24 pm
Lokalizacja: RJA

Kod nie wykazuje żadnych powiązań z Supla, więc nie widać tych odczytów w aplikacji.
JaG
Posty: 18
Rejestracja: ndz cze 06, 2021 7:09 am

A czy jest jakiś gotowiec w gui generic żeby tylko zmienić tylko trzeba było soft w czujnikach by to połączyć z suplą ?
Awatar użytkownika
klimasstudio
Posty: 1114
Rejestracja: śr sie 28, 2019 9:35 pm
Lokalizacja: localhost
Kontakt:

Dobra czyli tym softem zaczytasz dane z czujników i co dalej z tymi odczytami się dzieje ?
Więc chodź OSUPLUJE Ci dom :mrgreen:

Druk 3D - > https://klimastech.eu.org/druk-3d
Awatar użytkownika
klew
Posty: 8184
Rejestracja: czw cze 27, 2019 12:16 pm
Lokalizacja: Wrocław

Ten soft to niezwiązany z Suplą przykład, jak odczytać dane z czujników Xiaomi na ESP32.
Nic do Supli się nie wysyła, ani nie wyświetla. Jeśli ktoś by chciał to na podstawie tego przykładu można dodać taki czujnik do Supli.
Tylko kiedyś czytałem, że równoległe używanie BLE i Wi-Fi na ESP32 pogarsza jakość obu interfejsów. Ale sam tego nie testowałem.
Widzimy się na Supla Offline Party vol. 2 :!:
Awatar użytkownika
veeroos
Posty: 271
Rejestracja: ndz mar 20, 2022 9:30 am
Lokalizacja: Głogów

@Duch__ kawał dobrej roboty odwaliłeś. Ja ze swojej strony wrzuciłem wysyłanie na ESP32 do Supli. Taka alternatywa do RPi ;-). No i teraz tak na ESP32 Dev niestety nie chce to za bardzo działać, maksymalny czas działania jaki wyciągnąłem z tego modułu to 10 minut, po tym czasie w logach widzę, że Bluetooth odnajduje czujniki, ale niestety urządzenie już nie chce łączyć się z siecią Wi-Fi. Poszedłem więc krok dalej i kupiłem moduł ESP32 S3 Dev. no i tutaj sytuacja wygląda na chwilę obecną tak: od godziny wszystko działa poprawnie, no ale jest małe "ale" nie widzę żadnych logów po USB. Mam więc do wszystkich pytanie co jest nie tak, ten sam program został wgrany do obu płytek, jedna daje logi, a druga nie. Program zrobiłem na bazie przykładu Webinterface, dodałem obsługę czujników z przykładu kolegi @Duch__ dodałem klasy które pchają dane do Supli no i w sumie tyle. Na razie nie wysyłam danych dotyczących baterii, bo w sumie chciałem tylko bramkę uruchomić. Jak testy wyjdą pozytywnie to wrzucę kod źródłowy na forum. Ale chciałbym podglądać logi z działania urządzenia, a nic nie widzę, może trzeba jakoś inaczej skonfigurować interfejs, albo na innych pinach czytać?
Zamel Mew-01, Wemos D1 mini Pro + Ikea vindriktning + BME280, 3x - SonOff mini, 3x - SonOff Basic, 3xGosund SP111, SonOff S55, 2x GOSUND WB4
Awatar użytkownika
klew
Posty: 8184
Rejestracja: czw cze 27, 2019 12:16 pm
Lokalizacja: Wrocław

veeroos pisze: wt lut 14, 2023 8:23 pm Ale chciałbym podglądać logi z działania urządzenia, a nic nie widzę, może trzeba jakoś inaczej skonfigurować interfejs, albo na innych pinach czytać?
Podgląd seriala jest na tych samych pinach, co wgrywanie danych, także powinno działać.
Czego używasz do podglądu? Spróbuj różnych programów do tego (u mnie w sumie serial monitor z Arduino IDE działa prawie zawsze, putty też się dobrze sprawdza).

Jak nie będzie nadal działać, to wrzuć tam prawie pusty program w Arduino i dodaj tylko logowanie (np. "jesteś super" co 1 s).
Widzimy się na Supla Offline Party vol. 2 :!:
ODPOWIEDZ

Wróć do „Zagadnienia ogólne”