XIAOMI LYWSD03MMC - odczyt przez ESP32

User avatar
uchnast.michal
Posts: 1334
Joined: Tue Jun 04, 2019 11:37 am
Has thanked: 7 times

Post

Adamus10 wrote: Sun Feb 11, 2024 12:13 am z waga też się zintegruje;) będziesz moim testerem
Z przyjemnością;)
lukasz06
Posts: 2543
Joined: Sun Jul 17, 2022 6:53 pm
Has thanked: 46 times
Been thanked: 21 times

Post

Znalazłem w necie, że do innych termometrów można też wgrać alternatywne oprogramowanie
Ktoś coś wie?
Lista modeli;
Xiaomi LYWSD03MMC [Zigbee, BLE]
Xiaomi MJWSD05MMC [BLE]
Qingping CGG1 [BLE]
Qingping CGDK2 [Zigbee, BLE]
Xiaomi MiaoMiaoCe MHO-C401 [Zigbee, BLE]
Xiaomi MiaMiaoCe MHO-C122 [Zigbee, BLE]
Bernix
Posts: 93
Joined: Tue Jan 03, 2023 10:29 am

Post

Adamus10 wrote: Sun Jan 28, 2024 8:24 pm Aktualizacja kodu.
Warto zrobić kopię przed wgraniem. Znaczna ingerencja w kod.

Zmiany:
- przebudowałem a w zasadzie usunąłem "void Konwersja()" i "void Wyswietl()" a w to miejsce powstał krótszy kod w fragmencie "class MyAdvertisedDeviceCallbacks : public NimBLEAdvertisedDeviceCallbacks"
- udało się wyciągnąć nazwę urządzenia pod późniejsze wykorzystanie pod bramkę
- udało się wyciągnąć RSSI (nie wiem czy mogę to podrzucić pod konkretny kanał)

Przed:
Image
Po:
Image

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.
*/

//Parametry
#define STATUS_LED_GPIO 2
#define BUTTON_CFG_RELAY_GPIO 0
#define SCAN_TIME 2                    // seconds
#define SCAN_BT_TIME 120               // seconds
const int liczbaElementow = 8;         //Liczba czujników
const char* xiaomiBleDeviceMacs[] = {  //Lista czujników
  "A4:C1:38:00:00:00",
  "A4:C1:38:00:00:00",
};


//Ładowanie bibiotek
#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>

//Deklaracja zmiennych
byte od[liczbaElementow];
byte bat[liczbaElementow];
int wilg[liczbaElementow];
float temp[liczbaElementow];

unsigned long czas_pomiedzy_skanowaniem;
unsigned long wifimilis;
unsigned long lastReadTime = 0;
boolean METRIC = true;  //Set true for metric system; false for imperial
byte current_humidity;
byte current_batt;
float current_temperature;

//#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;
NimBLEScan* pBLEScan;
/*
void IRAM_ATTR resetModule(){
    ets_printf("reboot\n");
    esp_restart();
}
*/
void printHexString(const uint8_t* data, size_t length) {
  for (size_t i = 0; i < length; ++i) {
    Serial.print("0x");
    if (data[i] < 0x10) Serial.print("0");  // Dodaj zero przed jednocyfrowe wartości
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

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

      int serviceDataCount = advertisedDevice->getServiceDataCount();
      strServiceData = advertisedDevice->getServiceData(0);
      Serial.println("-----Nowy wpis-----");
      Serial.println("--------Czysty HEX-");
      printHexString(reinterpret_cast<const uint8_t*>(strServiceData.c_str()), strServiceData.length());
      Serial.println("--------MAC--------");
      Serial.println(advertisedDevice->getAddress().toString().c_str());
      Serial.println("--------NAZWA------");
      Serial.println(advertisedDevice->getName().c_str());
      Serial.println("--------RSSI------");
      Serial.println(advertisedDevice->getRSSI());



      String macAddress = advertisedDevice->getAddress().toString().c_str();
      macAddress.toUpperCase();
      for (int i = 0; i < liczbaElementow; i++) {
        if (macAddress == xiaomiBleDeviceMacs[i]) {
          //current_temperature = (float)((strServiceData[7] | (strServiceData[6] << 8)) * 0.1);  //dodać obsługę ujemnych
          int16_t rawTemperature = (strServiceData[7] | (strServiceData[6] << 8));
          current_temperature = rawTemperature * 0.1;
          current_humidity = (float)(strServiceData[8]);
          current_batt = (float)(strServiceData[9]);
          Serial.print(F("Urządzenie:"));
          Serial.print(i);
          Serial.print(F(" MAC: "));
          Serial.print(macAddress);
          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("%."));
          temp[i] = current_temperature;
          wilg[i] = current_humidity;
          bat[i] = current_batt;
          od[i] = 0;
          zerowanie(i);
          break;  // Przerwij pętlę po znalezieniu pasującego adresu MAC
        }
      }
    }
  }
};



class Czujnik : public Supla::Sensor::ThermHygroMeter {
public:
  explicit Czujnik(int sensorNumber)
    : sensorNumber(sensorNumber)  //,
                                  //temperature(-275),
                                  //humidity(-1)
  {
  }

  double getTemp() {
    temperature = temp[sensorNumber];
    return temperature;
  }

  double getHumi() {
    humidity = wilg[sensorNumber];
    return humidity;
  }

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

  void onInit() {
    channel.setNewValue(temp[sensorNumber], wilg[sensorNumber]);
    channel.setBatteryLevel(bat[sensorNumber]);
  }

protected:
  const int sensorNumber;
  float temperature;
  int humidity;
};

Czujnik* czujniki[liczbaElementow];


void setup() {

  Serial.begin(115200);
  initBluetooth();

  // Channels configuration
  auto buttonCfgRelay = new Supla::Control::Button(BUTTON_CFG_RELAY_GPIO, true, true);
  buttonCfgRelay->configureAsConfigButton(&SuplaDevice);

  for (int i = 0; i < liczbaElementow; ++i) {
    od[i] = 0;
    bat[i] = 0;
    wilg[i] = -1;
    temp[i] = -275;
    czujniki[i] = new Czujnik(i);
    czujniki[i]->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYPOWERED);
    czujniki[i]->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();
  NimBLEDevice::setPower(ESP_PWR_LVL_P9);
}

//pętla główna
void loop() {
  if ((millis() - czas_pomiedzy_skanowaniem) > (SCAN_BT_TIME * 1000)) {
    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);
    for (int i = 0; i < liczbaElementow; i++) {
      od[i] = od[i] + 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);
}

//zerowanie wartości czujnika o id
void zerowanie(int index) {
  if (od[index] > 5) {
    temp[index] = -275;
    wilg[index] = -1;
    bat[index] = 0;
    od[index] = 0;
  }
}
A z uprzejmości mógłbyś napisać jakie parametry trzeba ustawić w Arduino IDE (jakie biblioteki, numery wersji i td.) żeby kompilacja się powiodła? Tak jak dla laika. :D
User avatar
Gang
Posts: 748
Joined: Fri Nov 09, 2018 12:44 pm

Post

Mocno trzymam za Was kciuki! ;)
Mam bramkę na malince postawioną ale dlaczego w firmie nie zrobić jej na esp32 ;)
Tu jest za mało miejsca abym wszystko mógł wypisać, co mam z supli :mrgreen:
Bartoni
Posts: 190
Joined: Sun Jul 18, 2021 6:48 pm

Post

Chciałbym zrobić bramkę dla czujników xiaomi. W jakie esp32 najlepiej się zaopatrzyć? Jak podłączyć? Co trzeba wgrać na nie, jaki jest aktualny kod?
lukasz06
Posts: 2543
Joined: Sun Jul 17, 2022 6:53 pm
Has thanked: 46 times
Been thanked: 21 times

Post

W supli nie ma jeszcze takiej bramki.
zzrr
Posts: 1864
Joined: Wed Oct 26, 2022 7:35 pm
Has thanked: 76 times
Been thanked: 119 times

Post

Bartoni wrote: Sat Mar 23, 2024 10:35 am Chciałbym zrobić bramkę dla czujników xiaomi. W jakie esp32 najlepiej się zaopatrzyć? Jak podłączyć? Co trzeba wgrać na nie, jaki jest aktualny kod?
Ile masz tych czujników i w jakiej odległości byłby najdalej odsunięty? U mnie BLE pomiędzy modułami ESP32 lub ESP32C3 działa w zasięgu całego domu dwa piętra, bez jakichkolwiek zakłóceń czy przerw w połączeniu. Mam tak zrobione termostaty pokojowe. Dla relaksu sprawdzałem zasięg LYWSD03MMC niestety jeśli zamieni się go z ESP zasięg spada powiedziałbym nawet ze dwa razy. Na jednym pietrze nie wszędzie łączyły. Wiec jeśli chcesz przez suplę mieć odczyt na telefonie z jakiegoś XIAOMI to tak. Ale jeśli chcesz mieć je rozłożone po domu to może to nie zadziałać tak jak byś chciał.
lukasz06
Posts: 2543
Joined: Sun Jul 17, 2022 6:53 pm
Has thanked: 46 times
Been thanked: 21 times

Post

Nie rozumiem co zamieni ESP?
Bartoni
Posts: 190
Joined: Sun Jul 18, 2021 6:48 pm

Post

zzrr wrote: Sat Mar 23, 2024 4:09 pm
Bartoni wrote: Sat Mar 23, 2024 10:35 am Chciałbym zrobić bramkę dla czujników xiaomi. W jakie esp32 najlepiej się zaopatrzyć? Jak podłączyć? Co trzeba wgrać na nie, jaki jest aktualny kod?
Ile masz tych czujników i w jakiej odległości byłby najdalej odsunięty? U mnie BLE pomiędzy modułami ESP32 lub ESP32C3 działa w zasięgu całego domu dwa piętra, bez jakichkolwiek zakłóceń czy przerw w połączeniu. Mam tak zrobione termostaty pokojowe. Dla relaksu sprawdzałem zasięg LYWSD03MMC niestety jeśli zamieni się go z ESP zasięg spada powiedziałbym nawet ze dwa razy. Na jednym pietrze nie wszędzie łączyły. Wiec jeśli chcesz przez suplę mieć odczyt na telefonie z jakiegoś XIAOMI to tak. Ale jeśli chcesz mieć je rozłożone po domu to może to nie zadziałać tak jak byś chciał.
Też planowałem w każdy pomieszczeniu po jednym, w domu dwupiętrowym. Czyli wyjdzie ok 10 czujników.
W jaki sposób masz to zrobione?
O co chodzi z tym spadaniem zasięgu, w jakim to przypadku tak spada zasięg, bo nie rozumie?
Bartoni
Posts: 190
Joined: Sun Jul 18, 2021 6:48 pm

Post

lukasz06 wrote: Sat Mar 23, 2024 3:46 pm W supli nie ma jeszcze takiej bramki.
Czytałem że na ESP jest bramka która odbiera z Xiaomi i przesła na suple. Jak na supli mogłaby być bramka? Czujniki posiadają bluetooth więc nie rozumie jak miałoby to działać?

Return to “Zagadnienia ogólne”