Xiaomi Mijia lywsd03mmc

Aus sichardt
Zur Navigation springenZur Suche springen

Xiaomi Mijia lywsd03mmc

ESP32 Code:

//#include <BLEDevice.h>
#include "NimBLEDevice.h"//needs about 50% ROM of std BLEDevice.h include
#include <SimpleTimer.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>

#define ssid "yourSSID"
#define password "yourPSK"

const char* host = "https://yourserver.net/folder/";
String post_request;

unsigned int wifi_start;
unsigned int t_sleep;
float temp,humi;

String addr="00:00:00:00:00:00";
BLEClient* pClient;
bool connectionSuccessful = false;
// The remote service we wish to connect to.
static BLEUUID serviceUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6");
// The characteristic of the remote service we are interested in.
static BLEUUID    charUUID("ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6");

//prototypes
int wifi_getAddr(int id);
void ble();
int wifi_post(int id);



//wifi functions
void initWiFi() {
  
  WiFi.mode(WIFI_STA);
  wifi_start=millis();
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(1000);
  }
  Serial.println(WiFi.localIP());
}

//ESP main functions
void setup() {
  Serial.begin(9600);
}

void loop() {
  for (int id=1;id<99;id++){
    wifi_getAddr(id);
    if(addr=="end" or addr=="00:00:00:00:00:00"){
      Serial.println("no valid MIJIA address...");
      break;
    }
    Serial.println(id);
    ble();
    delay(15000);
    if(connectionSuccessful == true){
      wifi_post(id);
    }else{
      Serial.print("could not get data from ");Serial.println(addr);
    }
    }
  Serial.println("sleeping for approx. 25 minutes.");
  delay(25*60*1000);
}

//Bluetooth functions
void ble(){
  connectionSuccessful = false;
  //ble_addr_t baddr = ble_addr_t(addr);
  static BLEAddress htSensorAddress(addr.c_str());
    Serial.print("Starting MJ client. addr: "); Serial.println(addr);
  delay(750);

  BLEDevice::init("ESP32");
  createBleClientWithCallbacks();
  delay(750);
  connectSensor(htSensorAddress);
  registerNotification();
}

class MyClientCallback : public BLEClientCallbacks {
    void onConnect(BLEClient* pclient) {
      Serial.println("Connected");
    }

    void onDisconnect(BLEClient* pclient) {
      Serial.println("Disconnected");
      if (!connectionSuccessful) {
        Serial.println("RESTART");
        ESP.restart();
      }
    }
};

void createBleClientWithCallbacks() {
  pClient = BLEDevice::createClient();
  pClient->setClientCallbacks(new MyClientCallback());
}

void connectSensor(BLEAddress htSensorAddress) {
  pClient->connect(htSensorAddress);
  //connectionSuccessful = true;
}



static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify) {
  Serial.print("Notify callback for characteristic ");
  Serial.println(pBLERemoteCharacteristic->getUUID().toString().c_str());
  temp = (pData[0] | (pData[1] << 8)) * 0.01; //little endian 
  humi = pData[2];
  Serial.printf("temp = %.1f : humidity = %.1f \n", temp, humi);
  connectionSuccessful = true;
  pClient->disconnect();
 // BLEDevice::deinit();
 
}

void registerNotification() {

  // Obtain a reference to the service we are after in the remote BLE server.
  BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
  if (pRemoteService == nullptr) {
    Serial.print("Failed to find our service UUID: ");
    Serial.println(serviceUUID.toString().c_str());
    pClient->disconnect();
    return;
  }
  Serial.println(" - Found our service");

  // Obtain a reference to the characteristic in the service of the remote BLE server.
  BLERemoteCharacteristic* pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
  if (pRemoteCharacteristic == nullptr) {
    Serial.print("Failed to find our characteristic UUID: ");
    Serial.println(charUUID.toString().c_str());
    pClient->disconnect();
    return;
  }
  Serial.println(" - Found our characteristic");
  pRemoteCharacteristic->registerForNotify(notifyCallback);
}



//server connection functions

int wifi_post(int id){
  WiFiClientSecure wificlient;
  initWiFi();
  HTTPClient https;
  wificlient.setInsecure();//do not check certificate fingerprint
  bool dbg_serial=true;
  bool  error = false;

  while (WiFi.status() != WL_CONNECTED) {                                 //No WIFI yet? Wait.
    if (WiFi.status() == WL_CONNECT_FAILED) {
      error = true;
      break;
    }
    if (millis() - wifi_start > 30000)      {
      error = true;
      break;
    }
    delay(500); if (dbg_serial) {
      Serial.print(".");HTTPClient https;
    }
  }
  if (dbg_serial) {
    if (WiFi.status() == WL_CONNECTED) {
      Serial.println("");
      Serial.println("Connected to " + String(ssid) + " with IP address " + WiFi.localIP().toString() );
    }
    if (WiFi.status() != WL_CONNECTED) {
      Serial.println("");
      Serial.println("Error: No WIFI connection");
    }
  }
  if (error) {
    return 0;
  }
post_request="t_rh.php?dummy=0&t="+String(temp)+"&rh="+String(humi)+"&id="+String(id);
  
  https.begin(wificlient, host+post_request);                                                       //request destination
  https.addHeader("Content-Type", "application/x-www-form-urlencoded");    //content-type header
int  httpCode = https.POST(post_request);                                     //send request
  delay(150);                                                             //wait for ack packet
  if ( httpCode != 200 ) {
    error = true;
//    warn = true;
  }
  if (dbg_serial) {
    Serial.println("requesting: " + post_request);
    Serial.println("HTTP Status: " + httpCode );
    String response = https.getString();
    response.trim();//I get a leading linebreak, therefore trim the results (removes leading and trailing whitespaces)

    Serial.println("response: " + response );                                  //Print request response payload
  }
  https.end();                                                             //close connection
  return httpCode;
}

//=================GET NEW MIJIA ADDRESS FROM SERVER =========================================
int wifi_getAddr(int id){
//new address, so reset t and rh
temp=-99; humi=-99;
addr="00:00:00:00:00:00";
  
  WiFiClientSecure wificlient;
  initWiFi();
  HTTPClient https;
  wificlient.setInsecure();//do not check certificate fingerprint
  bool dbg_serial=true;
  bool  error = false;

  while (WiFi.status() != WL_CONNECTED) {                                 //No WIFI yet? Wait.
    if (WiFi.status() == WL_CONNECT_FAILED) {
      error = true;
      break;
    }
    if (millis() - wifi_start > 30000)      {
      error = true;
      break;
    }
    delay(500); if (dbg_serial) {
      Serial.print(".");HTTPClient https;
    }
  }
  if (dbg_serial) {
    if (WiFi.status() == WL_CONNECTED) {
      Serial.println("");
      Serial.println("Connected to " + String(ssid) + " with IP address " + WiFi.localIP().toString() );
    }
    if (WiFi.status() != WL_CONNECTED) {
      Serial.println("");
      Serial.println("Error: No WIFI connection");
    }
  }
  if (error) {
    return 1;
  }
post_request="sensoren.php?dummy=0&id="+String(id)+"&type=addr";
  
  https.begin(wificlient, host+post_request);                                                       //request destination
  https.addHeader("Content-Type", "application/x-www-form-urlencoded");    //content-type header
int  httpCode = https.POST(post_request);                                     //send request
  delay(150);                                                             //wait for ack packet
  if ( httpCode != 200 ) {
    error = true;
//    warn = true;
  }
  if (dbg_serial) {
    Serial.println("requesting: " + post_request);
    Serial.println("HTTP Status: " + httpCode );
    String response = https.getString();
    response.trim();//I get a leading linebreak, therefore trim the results (removes leading and trailing whitespaces)

    Serial.println("response: " + response );                                  //Print request response payload
    addr=response.c_str();
  }
  https.end();                                                             //close connection
  return httpCode;
}


boolean isInteger(String str) {
  for (byte i = 0; i < str.length(); i++)
  {
    Serial.println("char " + String(i) + ": " + String(str.charAt(i)));
    if (!isDigit(str.charAt(i))) return false;
  }
  return true;
}