esphome/components/esp32_presense/MiFloraHandler.cpp

139 lines
3.9 KiB
C++
Raw Normal View History

2023-12-07 23:51:43 +03:00
#include "MiFloraHandler.h"
2023-12-10 10:29:34 +03:00
#include "NimBLEAttValue.h"
2023-12-07 23:51:43 +03:00
namespace MiFloraHandler {
std::vector<std::string> addresses;
bool readSensorData(BLERemoteService* floraService, DynamicJsonDocument* doc) {
BLERemoteCharacteristic* floraCharacteristic = nullptr;
// get the main device data characteristic
floraCharacteristic = floraService->getCharacteristic(uuid_sensor_data);
if (floraCharacteristic == nullptr) {
2023-12-10 09:39:19 +03:00
ESP_LOGD(TAG, "-- Can't read characteristics");
2023-12-07 23:51:43 +03:00
return false;
}
// read characteristic value
NimBLEAttValue value;
value = floraCharacteristic->readValue();
if (value.size() == 0) {
2023-12-10 09:39:19 +03:00
ESP_LOGD(TAG, "Reading Value failed");
2023-12-07 23:51:43 +03:00
return false;
}
const char* val = value.c_str();
float temperature = (val[0] + val[1] * 256) / ((float)10.0);
uint8_t moisture = val[7];
uint32_t brightness = val[3] + val[4] * 256;
float conductivity = val[8] + val[9] * 256;
2023-12-10 09:08:23 +03:00
(*doc)["temperature"] = temperature;
(*doc)["moisture"] = moisture;
(*doc)["light"] = brightness;
(*doc)["conductivity"] = conductivity;
2023-12-07 23:51:43 +03:00
floraService->deleteCharacteristics();
return true;
}
bool readBatteryData(BLERemoteService* floraService, DynamicJsonDocument* doc) {
BLERemoteCharacteristic* floraCharacteristic = nullptr;
floraCharacteristic = floraService->getCharacteristic(uuid_version_battery);
if (floraCharacteristic == nullptr) {
2023-12-10 09:39:19 +03:00
ESP_LOGD(TAG, "-- Can't read characteristics");
2023-12-07 23:51:43 +03:00
return false;
}
NimBLEAttValue val;
val = floraCharacteristic->readValue();
if (val.size() == 0) {
2023-12-10 09:39:19 +03:00
ESP_LOGD(TAG, "Reading Value failed");
2023-12-07 23:51:43 +03:00
return false;
}
int8_t battery = val.c_str()[0];
2023-12-10 09:08:23 +03:00
(*doc)["battery"] = battery;
2023-12-07 23:51:43 +03:00
floraService->deleteCharacteristics();
return true;
}
bool forceFloraServiceDataMode(BLERemoteService* floraService) { // Setting the mi flora to data reading mode
BLERemoteCharacteristic* floraCharacteristic;
// get device mode characteristic, needs to be changed to read data
// Serial.println("- Force device in data mode");
floraCharacteristic = nullptr;
floraCharacteristic = floraService->getCharacteristic(uuid_write_mode);
if (floraCharacteristic == nullptr) {
// Serial.println("-- Failed, skipping device");
return false;
}
uint8_t buf[2] = {0xA0, 0x1F};
floraCharacteristic->writeValue(buf, 2, true);
2023-12-10 09:08:23 +03:00
esphome::delay(500);
2023-12-07 23:51:43 +03:00
floraService->deleteCharacteristics();
return true;
}
void fillDeviceData(DynamicJsonDocument* doc, BleFingerprint* f) {
2023-12-10 09:08:23 +03:00
(*doc)["id"] = f->getId();
(*doc)["mac"] = f->getMac();
(*doc)["rssi"] = f->getRssi();
2023-12-07 23:51:43 +03:00
}
bool getFloraData(DynamicJsonDocument* doc, BLERemoteService* floraService, BleFingerprint* f) {
// Force miFlora to data mode
fillDeviceData(doc, f);
if (!MiFloraHandler::readBatteryData(floraService, doc))
2023-12-10 09:39:19 +03:00
ESP_LOGD(TAG, "Failed reading battery data");
2023-12-07 23:51:43 +03:00
if (MiFloraHandler::forceFloraServiceDataMode(floraService)) {
} else {
2023-12-10 09:39:19 +03:00
ESP_LOGD(TAG, "Failed to force data reading mode");
2023-12-07 23:51:43 +03:00
}
if (!MiFloraHandler::readSensorData(floraService, doc))
2023-12-10 09:39:19 +03:00
ESP_LOGD(TAG, "Failed reading sensor data");
2023-12-07 23:51:43 +03:00
return true;
}
bool requestData(NimBLEClient* pClient, BleFingerprint* fingerprint) // Getting mi flora data
{
DynamicJsonDocument document(256);
NimBLERemoteService* floraService = pClient->getService(serviceUUID);
if (floraService == nullptr) {
2023-12-10 09:39:19 +03:00
ESP_LOGD(TAG, "Getting MiFlora service failed");
2023-12-07 23:51:43 +03:00
return false;
}
// Retriving the actual data
if (!getFloraData(&document, floraService, fingerprint)) // Getting flora data
return false;
std::string buf = std::string();
serializeJson(document, buf);
// Sending buffer over mqtt
fingerprint->setReport(QueryReport{"miflora", buf});
return true;
}
} // namespace MiFloraHandler