XIAOMI LYWSD03MMC - odczyt przez ESP32

kurus
Posts: 1312
Joined: Wed Jan 15, 2020 8:17 pm

Post

Adamus10 wrote: Sat Jan 27, 2024 7:34 pm
kurus wrote: Fri Jan 26, 2024 10:34 pm U was też takie szpilki do zera występują?
Poprawka powyższego + parę modyfikacji, ale nie zmieniających schematu działania
Dzięki za poprawkę wrzuciłem juz.

Wiesz może dlaczego na jednym laptopie arduino wywala mi taki błąd:
c:\Users\Michal\Documents\Arduino\libraries\SuplaDevice\src\supla\control\dimmer_leds.cpp: In member function 'virtual void Supla::Control::DimmerLeds::onInit()':
c:\Users\Michal\Documents\Arduino\libraries\SuplaDevice\src\supla\control\dimmer_leds.cpp:71:5: error: 'ledcSetup' was not declared in this scope
71 | ledcSetup(esp32PwmChannelCounter, 1000, 10);
| ^~~~~~~~~
c:\Users\Michal\Documents\Arduino\libraries\SuplaDevice\src\supla\control\dimmer_leds.cpp:72:5: error: 'ledcAttachPin' was not declared in this scope; did you mean 'ledcAttach'?
72 | ledcAttachPin(brightnessPin, esp32PwmChannelCounter);
| ^~~~~~~~~~~~~
| ledcAttach

exit status 1

Compilation error: exit status 1
A na drugim idzie bez problemu, te same wersje zaktualizowane tak samo. Oba windows 10
Adamus10
Posts: 31
Joined: Sat Oct 28, 2023 8:05 pm
Been thanked: 6 times

Post

kurus wrote: Sun Jan 28, 2024 12:37 pm
Adamus10 wrote: Sat Jan 27, 2024 7:34 pm
kurus wrote: Fri Jan 26, 2024 10:34 pm U was też takie szpilki do zera występują?
Poprawka powyższego + parę modyfikacji, ale nie zmieniających schematu działania
Dzięki za poprawkę wrzuciłem juz.

Wiesz może dlaczego na jednym laptopie arduino wywala mi taki błąd:
c:\Users\Michal\Documents\Arduino\libraries\SuplaDevice\src\supla\control\dimmer_leds.cpp: In member function 'virtual void Supla::Control::DimmerLeds::onInit()':
c:\Users\Michal\Documents\Arduino\libraries\SuplaDevice\src\supla\control\dimmer_leds.cpp:71:5: error: 'ledcSetup' was not declared in this scope
71 | ledcSetup(esp32PwmChannelCounter, 1000, 10);
| ^~~~~~~~~
c:\Users\Michal\Documents\Arduino\libraries\SuplaDevice\src\supla\control\dimmer_leds.cpp:72:5: error: 'ledcAttachPin' was not declared in this scope; did you mean 'ledcAttach'?
72 | ledcAttachPin(brightnessPin, esp32PwmChannelCounter);
| ^~~~~~~~~~~~~
| ledcAttach

exit status 1

Compilation error: exit status 1
A na drugim idzie bez problemu, te same wersje zaktualizowane tak samo. Oba windows 10
Obstawiam jedną z 2 rzeczy ale nie jestem ekspertem ale bardziej osobą uczacą sie.
1) Nieaktualna biblioteka
2) Błędnie zdefiniowana płytka w konfiguracji.
kurus
Posts: 1312
Joined: Wed Jan 15, 2020 8:17 pm

Post

Nic z tych rzeczy, biblioteki aktualne i płytka odpowiednia.
Adamus10
Posts: 31
Joined: Sat Oct 28, 2023 8:05 pm
Been thanked: 6 times

Post

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;
  }
}
You do not have the required permissions to view the files attached to this post.
User avatar
Lector
Posts: 2471
Joined: Fri Nov 17, 2017 2:26 pm
Location: Poznań
Has thanked: 13 times
Been thanked: 25 times

Post

Mocno kibicuje projektowi.
Czekam na możliwość konfiguracji GUI.
Niespełniony automatyk. :mrgreen:
https://3d-lamp.photos/
https://pool.lector.top/
User avatar
Duch__
Posts: 2199
Joined: Wed Aug 24, 2016 7:26 pm
Location: Opole
Been thanked: 6 times

Post

A mnie cieszy że mój kod był inspiracją dla innych ;)
lukasz06
Posts: 2543
Joined: Sun Jul 17, 2022 6:53 pm
Has thanked: 46 times
Been thanked: 21 times

Post

Grosz do grosza i będzie kokosza :)
lukasz06
Posts: 2543
Joined: Sun Jul 17, 2022 6:53 pm
Has thanked: 46 times
Been thanked: 21 times

Post

Wgrałem poprzedni kod, ale coś mi na czerwono błąd wyskoczył, mimo to wgrało i odczyty są.
Może ktoś podpowie co to za błąd?

C:\Users\Jacek\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.14\cores\esp32\esp32-hal-uart.c: In function 'uartSetPins':
C:\Users\Jacek\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.14\cores\esp32\esp32-hal-uart.c:153:9: warning: 'return' with no value, in function returning non-void
return;
^~~~~~
C:\Users\Jacek\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.14\cores\esp32\esp32-hal-uart.c:149:6: note: declared here
bool uartSetPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
^~~~~~~~~~~
Szkic używa 1491801 bajtów (75%) pamięci programu. Maksimum to 1966080 bajtów.
Zmienne globalne używają 64904 bajtów (19%) pamięci dynamicznej, pozostawiając 262776 bajtów dla zmiennych lokalnych. Maksimum to 327680 bajtów.
esptool.py v4.5.1
Serial port COM3
Connecting....
Chip is ESP32-D0WD-V3 (revision v3.1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: d4:8a:fc:a0:23:dc
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Erasing flash (this may take a while)...
Chip erase completed successfully in 2.1s
Compressed 18992 bytes to 13110...
Writing at 0x00001000... (100 %)
Wrote 18992 bytes (13110 compressed) at 0x00001000 in 0.2 seconds (effective 621.1 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 146...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (146 compressed) at 0x00008000 in 0.0 seconds (effective 902.9 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 2139.4 kbit/s)...
Hash of data verified.
Compressed 1498096 bytes to 901501...
Writing at 0x00010000... (1 %)
Writing at 0x00019414... (3 %)
Writing at 0x00024f7e... (5 %)
Writing at 0x0017da19... (100 %)
Wrote 1498096 bytes (901501 compressed) at 0x00010000 in 11.5 seconds (effective 1044.0 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
User avatar
uchnast.michal
Posts: 1334
Joined: Tue Jun 04, 2019 11:37 am
Has thanked: 7 times

Post

@Duch__ –czasami niewielka inspiracja prowadzi do powstania kodu, na który wiele osób czeka :) Dobra robota. Przy okazji BLE to ciekawe kiedy pojawi się pomysł integracji z wagą MiScale2 lub podobnymi:)

Z dwa lata nic sam nie kompilowałem i kompletnie straciłem orientację. Czy mi mógłby ktoś pomóc i umieścił szczegółowe informacje o zastosowanych biblioteczkach lub ewentualnie link? Może na pierwszej stronie odnośnik do części z opisem bibliotek i aktualnym kodem.
Z góry wielkie dzięki.
Adamus10
Posts: 31
Joined: Sat Oct 28, 2023 8:05 pm
Been thanked: 6 times

Post

uchnast.michal wrote: Sat Feb 10, 2024 5:25 pm @Duch__ –czasami niewielka inspiracja prowadzi do powstania kodu, na który wiele osób czeka :) Dobra robota. Przy okazji BLE to ciekawe kiedy pojawi się pomysł integracji z wagą MiScale2 lub podobnymi:)

Z dwa lata nic sam nie kompilowałem i kompletnie straciłem orientację. Czy mi mógłby ktoś pomóc i umieścił szczegółowe informacje o zastosowanych biblioteczkach lub ewentualnie link? Może na pierwszej stronie odnośnik do części z opisem bibliotek i aktualnym kodem.
Z góry wielkie dzięki.
Musiałem kod przerobić bo za mało czujników obsługiwał, a potem poszła kwestia optymalizacji w ramach nauki.

Aktualnie trwają prace nad bramką BLE.
Brakuje mi kwestii bardziej dynamicznych kanałów.
Np jak zmienię kolejność macadresów to by supla wiedziała jaki był mac adres przypisany do kanału przy rejestracji urządzenia w supli.
Usuwania nieaktywnych kanałów - wyrzucenie mac'a z puli urządzeń powinno skutkować usunięcie kanału.

Niby ma być bramka a jednak nie mogę obejść tego sztywnego przypisywania kanałów.

Po 7 kwietnia będę mógł ruszyć z projektem bardziej.

z waga też się zintegruje;) będziesz moim testerem

Return to “Zagadnienia ogólne”