From 4ba27481b5b8710c0a075329768ee3b72a52ed78 Mon Sep 17 00:00:00 2001 From: Florian <1technophile@users.noreply.github.com> Date: Thu, 30 May 2019 13:37:23 +0200 Subject: [PATCH] add of Xiaomi Mijia BT4.0 clock temperature and humidity sensor (LYWSD02) and enable multiple services data readings for Mijia standard device. Indeed the new version seems to publish several service data compared to old ones. Please note that I'have update the library with the work of @fguiet see: https://github.com/nkolban/ESP32_BLE_Arduino/pull/24 --- ZgatewayBT.ino | 180 +++++++++++------- .../src/BLEAdvertisedDevice.cpp | 34 +++- .../src/BLEAdvertisedDevice.h | 13 +- 3 files changed, 145 insertions(+), 82 deletions(-) diff --git a/ZgatewayBT.ino b/ZgatewayBT.ino index eab9b1c..3daf775 100644 --- a/ZgatewayBT.ino +++ b/ZgatewayBT.ino @@ -55,75 +55,86 @@ vector devices; static int taskCore = 0; class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { - void onResult(BLEAdvertisedDevice advertisedDevice) { - trc(F("Creating BLE buffer")); - StaticJsonBuffer jsonBuffer; - JsonObject& BLEdata = jsonBuffer.createObject(); - String mac_adress = advertisedDevice.getAddress().toString().c_str(); - BLEdata.set("id", (char *)mac_adress.c_str()); - mac_adress.replace(":",""); - mac_adress.toUpperCase(); - String mactopic = subjectBTtoMQTT + mac_adress; - if (advertisedDevice.haveName()) BLEdata.set("name", (char *)advertisedDevice.getName().c_str()); - if (advertisedDevice.haveManufacturerData()) BLEdata.set("manufacturerdata", (char *)advertisedDevice.getManufacturerData().c_str()); - if (advertisedDevice.haveRSSI()) BLEdata.set("rssi", (int) advertisedDevice.getRSSI()); - if (advertisedDevice.haveTXPower()) BLEdata.set("txpower", (int8_t) advertisedDevice.getTXPower()); - #ifdef subjectHomePresence - if (advertisedDevice.haveRSSI()) haRoomPresence(BLEdata);// this device has an rssi in consequence we can use it for home assistant room presence component - #endif - if (advertisedDevice.haveServiceData()){ - - char mac[mac_adress.length()+1]; - mac_adress.toCharArray(mac,mac_adress.length()+1); - - trc(F("Get service data ")); - - std::string serviceData = advertisedDevice.getServiceData(); - int serviceDataLength = serviceData.length(); - String returnedString = ""; - for (int i=0; i(),"fe95") != NULL){ - trc("Processing BLE device data"); - int pos = -1; - pos = strpos(service_data,"209800"); - if (pos != -1){ - trc(F("mi flora data reading")); - #ifdef ZmqttDiscovery - if(!isDiscovered(mac)) MiFloraDiscovery(mac); - #endif - process_data(pos - 24,service_data,mac); - } - pos = -1; - pos = strpos(service_data,"20aa01"); - if (pos != -1){ - trc(F("mi jia data reading")); - #ifdef ZmqttDiscovery - if(!isDiscovered(mac)) MiJiaDiscovery(mac); - #endif - process_data(pos - 26,service_data,mac); - } + void onResult(BLEAdvertisedDevice advertisedDevice) { + trc(F("Creating BLE buffer")); + StaticJsonBuffer jsonBuffer; + JsonObject& BLEdata = jsonBuffer.createObject(); + String mac_adress = advertisedDevice.getAddress().toString().c_str(); + BLEdata.set("id", (char *)mac_adress.c_str()); + mac_adress.replace(":",""); + mac_adress.toUpperCase(); + String mactopic = subjectBTtoMQTT + mac_adress; + if (advertisedDevice.haveName()) BLEdata.set("name", (char *)advertisedDevice.getName().c_str()); + if (advertisedDevice.haveManufacturerData()) BLEdata.set("manufacturerdata", (char *)advertisedDevice.getManufacturerData().c_str()); + if (advertisedDevice.haveRSSI()) BLEdata.set("rssi", (int) advertisedDevice.getRSSI()); + if (advertisedDevice.haveTXPower()) BLEdata.set("txpower", (int8_t) advertisedDevice.getTXPower()); + #ifdef subjectHomePresence + if (advertisedDevice.haveRSSI()) haRoomPresence(BLEdata);// this device has an rssi in consequence we can use it for home assistant room presence component + #endif + if (advertisedDevice.haveServiceData()){ + char mac[mac_adress.length()+1]; + mac_adress.toCharArray(mac,mac_adress.length()+1); + trc(F("Get services data :")); + int serviceDataCount = advertisedDevice.getServiceDataCount(); + trc(serviceDataCount); + for (int j = 0; j < serviceDataCount;j++){ + std::string serviceData = advertisedDevice.getServiceData(j); + int serviceDataLength = serviceData.length(); + String returnedString = ""; + for (int i=0; i(),"fe95") != NULL){ + trc("Processing BLE device data"); + int pos = -1; + pos = strpos(service_data,"209800"); + if (pos != -1){ + trc(F("mi flora data reading")); + #ifdef ZmqttDiscovery + if(!isDiscovered(mac)) MiFloraDiscovery(mac); + #endif + process_data(pos - 24,service_data,mac); + } + pos = -1; + pos = strpos(service_data,"20aa01"); + if (pos != -1){ + trc(F("mi jia data reading")); + #ifdef ZmqttDiscovery + if(!isDiscovered(mac)) MiJiaDiscovery(mac); + #endif + process_data(pos - 26,service_data,mac); + } + pos = -1; + pos = strpos(service_data,"205b04"); + if (pos != -1){ + trc(F("LYWSD02 data reading")); + //example 70205b04b96ab883c8593f09041002e000 + #ifdef ZmqttDiscovery + if(!isDiscovered(mac)) LYWSD02Discovery(mac); + #endif + process_data(pos - 24,service_data,mac); } } + } } - } - }; - + } + } + }; + void setupBT(){ BLEinterval = TimeBtw_Read; trc(F("BLEinterval btw scans")); @@ -302,6 +313,15 @@ vector devices; #endif boolean result = process_data(pos - 40,(char *)Service_data.c_str(),d[0].extract); } + pos = -1; + pos = strpos(d[5].extract,"205b04"); + if (pos != -1){ + trc("LYWSD02 data reading"); + #ifdef ZmqttDiscovery + if(!isDiscovered(d[0].extract)) LYWSD02Discovery(d[0].extract); + #endif + boolean result = process_data(pos - 38,(char *)Service_data.c_str(),d[0].extract); + } return true; } } @@ -380,6 +400,34 @@ void MiJiaDiscovery(char * mac){ device.isDisc = true; devices.push_back(device); } + +void LYWSD02Discovery(char * mac){ + #define LYWSD02parametersCount 3 + trc(F("LYWSD02Discovery")); + char * LYWSD02sensor[LYWSD02parametersCount][8] = { + {"sensor", "LYWSD02-batt", mac, "battery","{{ value_json.batt | is_defined }}","", "", "V"} , + {"sensor", "LYWSD02-tem", mac,"temperature","{{ value_json.tem | is_defined }}","", "", "°C"} , + {"sensor", "LYWSD02-hum", mac,"humidity","{{ value_json.hum | is_defined }}","", "", "%"} + //component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement + }; + + for (int i=0;i m_serviceUUIDs; - int8_t m_txPower; - std::string m_serviceData; - BLEUUID m_serviceDataUUID; + std::vector m_serviceDataUUIDs; + std::vector m_serviceDataVector; + int8_t m_txPower; uint8_t* m_payload; };