Compare commits

..

No commits in common. "main" and "0.0.5" have entirely different histories.
main ... 0.0.5

9 changed files with 66 additions and 184 deletions

View File

@ -19,7 +19,7 @@ class ClientCallbacks : public BLEClientCallbacks {
static ClientCallbacks clientCB; static ClientCallbacks clientCB;
BleFingerprint::BleFingerprint(BLEAdvertisedDevice *advertisedDevice, float fcmin, float beta, float dcutoff) : filteredDistance{FilteredDistance(fcmin, beta, dcutoff)} { BleFingerprint::BleFingerprint(BLEAdvertisedDevice *advertisedDevice, float fcmin, float beta, float dcutoff) : filteredDistance{FilteredDistance(fcmin, beta, dcutoff)} {
firstSeenMillis = esphome::millis(); firstSeenMillis = millis();
address = NimBLEAddress(advertisedDevice->getAddress()); address = NimBLEAddress(advertisedDevice->getAddress());
addressType = advertisedDevice->getAddressType(); addressType = advertisedDevice->getAddressType();
rssi = advertisedDevice->getRSSI(); rssi = advertisedDevice->getRSSI();
@ -44,7 +44,7 @@ bool BleFingerprint::shouldHide(const std::string &s) {
bool BleFingerprint::setId(const std::string &newId, short newIdType, const std::string &newName) { bool BleFingerprint::setId(const std::string &newId, short newIdType, const std::string &newName) {
if (idType < 0 && newIdType < 0 && newIdType >= idType) return false; if (idType < 0 && newIdType < 0 && newIdType >= idType) return false;
if (idType > 0 && newIdType <= idType) return false; if (idType > 0 && newIdType <= idType) return false;
ESP_LOGD(TAG, "setId: %s %d %s OLD idType: %d\r\n", newId.c_str(), newIdType, newName.c_str(), idType); // ESP_LOGD("setId: %s %d %s OLD idType: %d\r\n", newId.c_str(), newIdType, newName.c_str(), idType);
ignore = newIdType < 0; ignore = newIdType < 0;
idType = newIdType; idType = newIdType;
@ -70,10 +70,10 @@ bool BleFingerprint::setId(const std::string &newId, short newIdType, const std:
qryAttempts = 0; qryAttempts = 0;
if (rssi < -80) { if (rssi < -80) {
qryDelayMillis = 30000; qryDelayMillis = 30000;
lastQryMillis = esphome::millis(); lastQryMillis = millis();
} else if (rssi < -70) { } else if (rssi < -70) {
qryDelayMillis = 5000; qryDelayMillis = 5000;
lastQryMillis = esphome::millis(); lastQryMillis = millis();
} }
} }
} }
@ -166,7 +166,7 @@ bool ble_ll_resolv_rpa(const uint8_t *rpa, const uint8_t *irk) {
if (ecb.cipher_text[15] != rpa[0] || ecb.cipher_text[14] != rpa[1] || ecb.cipher_text[13] != rpa[2]) return false; if (ecb.cipher_text[15] != rpa[0] || ecb.cipher_text[14] != rpa[1] || ecb.cipher_text[13] != rpa[2]) return false;
// ESP_LOGD(TAG, "RPA resolved %d %02x%02x%02x %02x%02x%02x\r\n", err, rpa[0], rpa[1], rpa[2], ecb.cipher_text[15], ecb.cipher_text[14], ecb.cipher_text[13]); // ESP_LOGD("RPA resolved %d %02x%02x%02x %02x%02x%02x\r\n", err, rpa[0], rpa[1], rpa[2], ecb.cipher_text[15], ecb.cipher_text[14], ecb.cipher_text[13]);
return true; return true;
} }
@ -209,7 +209,7 @@ void BleFingerprint::fingerprintServiceAdvertisements(NimBLEAdvertisedDevice *ad
for (auto i = 0; i < serviceAdvCount; i++) { for (auto i = 0; i < serviceAdvCount; i++) {
auto uuid = advertisedDevice->getServiceUUID(i); auto uuid = advertisedDevice->getServiceUUID(i);
#ifdef VERBOSE #ifdef VERBOSE
ESP_LOGD(TAG, "Verbose | %s | %-58s%ddBm AD: %s\r\n", getMac().c_str(), getId().c_str(), rssi, advertisedDevice->getServiceUUID(i).toString().c_str()); ESP_LOGD("Verbose | %s | %-58s%ddBm AD: %s\r\n", getMac().c_str(), getId().c_str(), rssi, advertisedDevice->getServiceUUID(i).toString().c_str());
#endif #endif
if (uuid == tileUUID) { if (uuid == tileUUID) {
asRssi = BleFingerprintCollection::rxRefRssi + TILE_TX; asRssi = BleFingerprintCollection::rxRefRssi + TILE_TX;
@ -267,7 +267,7 @@ void BleFingerprint::fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDe
BLEUUID uuid = advertisedDevice->getServiceDataUUID(i); BLEUUID uuid = advertisedDevice->getServiceDataUUID(i);
std::string strServiceData = advertisedDevice->getServiceData(i); std::string strServiceData = advertisedDevice->getServiceData(i);
#ifdef VERBOSE #ifdef VERBOSE
ESP_LOGD(TAG, "Verbose | %s | %-58s%ddBm SD: %s/%s\r\n", getMac().c_str(), getId().c_str(), rssi, uuid.toString().c_str(), hexStr(strServiceData).c_str()); ESP_LOGD("Verbose | %s | %-58s%ddBm SD: %s/%s\r\n", getMac().c_str(), getId().c_str(), rssi, uuid.toString().c_str(), hexStr(strServiceData).c_str());
#endif #endif
if (uuid == exposureUUID) { // found COVID-19 exposure tracker if (uuid == exposureUUID) { // found COVID-19 exposure tracker
@ -286,7 +286,7 @@ void BleFingerprint::fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDe
mv = *(uint16_t *)(serviceData + 10); mv = *(uint16_t *)(serviceData + 10);
battery = serviceData[12]; battery = serviceData[12];
#ifdef VERBOSE #ifdef VERBOSE
ESP_LOGD(TAG, "Temp: %.1f°, Humidity: %.1f%%, mV: %hu, Battery: %hhu%%, flg: 0x%02hhx, cout: %hhu\r\n", temp, humidity, mv, battery, serviceData[14], serviceData[13]); ESP_LOGD("Temp: %.1f°, Humidity: %.1f%%, mV: %hu, Battery: %hhu%%, flg: 0x%02hhx, cout: %hhu\r\n", temp, humidity, mv, battery, serviceData[14], serviceData[13]);
#endif #endif
setId("miTherm:" + getMac(), ID_TYPE_MITHERM); setId("miTherm:" + getMac(), ID_TYPE_MITHERM);
} else if (strServiceData.length() == 13) { // format atc1441 } else if (strServiceData.length() == 13) { // format atc1441
@ -298,7 +298,7 @@ void BleFingerprint::fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDe
battery = serviceData[9]; battery = serviceData[9];
#ifdef VERBOSE #ifdef VERBOSE
ESP_LOGD(TAG, "Temp: %.1f°, Humidity: %.1f%%, mV: %hu, Battery: %hhu%%, cout: %hhu\r\n", temp, humidity, mv, battery, serviceData[12]); ESP_LOGD("Temp: %.1f°, Humidity: %.1f%%, mV: %hu, Battery: %hhu%%, cout: %hhu\r\n", temp, humidity, mv, battery, serviceData[12]);
#endif #endif
setId("miTherm:" + getMac(), ID_TYPE_MITHERM); setId("miTherm:" + getMac(), ID_TYPE_MITHERM);
} }
@ -339,7 +339,7 @@ void BleFingerprint::fingerprintServiceData(NimBLEAdvertisedDevice *advertisedDe
void BleFingerprint::fingerprintManufactureData(NimBLEAdvertisedDevice *advertisedDevice, bool haveTxPower, int8_t txPower) { void BleFingerprint::fingerprintManufactureData(NimBLEAdvertisedDevice *advertisedDevice, bool haveTxPower, int8_t txPower) {
std::string strManufacturerData = advertisedDevice->getManufacturerData(); std::string strManufacturerData = advertisedDevice->getManufacturerData();
#ifdef VERBOSE #ifdef VERBOSE
ESP_LOGD(TAG, "Verbose | %s | %-58s%ddBm MD: %s\r\n", getMac().c_str(), getId().c_str(), rssi, hexStr(strManufacturerData).c_str()); ESP_LOGD("Verbose | %s | %-58s%ddBm MD: %s\r\n", getMac().c_str(), getId().c_str(), rssi, hexStr(strManufacturerData).c_str());
#endif #endif
if (strManufacturerData.length() >= 2) { if (strManufacturerData.length() >= 2) {
std::string manuf = Sprintf("%02x%02x", strManufacturerData[1], strManufacturerData[0]); std::string manuf = Sprintf("%02x%02x", strManufacturerData[1], strManufacturerData[0]);
@ -411,7 +411,7 @@ void BleFingerprint::fingerprintManufactureData(NimBLEAdvertisedDevice *advertis
} }
bool BleFingerprint::seen(BLEAdvertisedDevice *advertisedDevice) { bool BleFingerprint::seen(BLEAdvertisedDevice *advertisedDevice) {
lastSeenMillis = esphome::millis(); lastSeenMillis = millis();
reported = false; reported = false;
seenCount++; seenCount++;
@ -443,17 +443,17 @@ bool BleFingerprint::fill(JsonObject *doc) {
(*doc)["rssi@1m"] = get1mRssi(); (*doc)["rssi@1m"] = get1mRssi();
(*doc)["rssi"] = rssi; (*doc)["rssi"] = rssi;
if (isnormal(raw)) (*doc)["raw"] = serialized(std::to_string(raw)); if (isnormal(raw)) (*doc)["raw"] = serialized(std::string(raw, 2));
if (isnormal(dist)) (*doc)["distance"] = serialized(std::to_string(dist)); if (isnormal(dist)) (*doc)["distance"] = serialized(std::string(dist, 2));
if (isnormal(vari)) (*doc)["var"] = serialized(std::to_string(vari)); if (isnormal(vari)) (*doc)["var"] = serialized(std::string(vari, 2));
if (close) (*doc)["close"] = true; if (close) (*doc)["close"] = true;
(*doc)["int"] = (millis() - firstSeenMillis) / seenCount; (*doc)["int"] = (millis() - firstSeenMillis) / seenCount;
if (mv) (*doc)["mV"] = mv; if (mv) (*doc)["mV"] = mv;
if (battery != 0xFF) (*doc)["batt"] = battery; if (battery != 0xFF) (*doc)["batt"] = battery;
if (temp) (*doc)["temp"] = serialized(std::to_string(temp)); if (temp) (*doc)["temp"] = serialized(std::string(temp, 1));
if (humidity) (*doc)["rh"] = serialized(std::to_string(humidity)); if (humidity) (*doc)["rh"] = serialized(std::string(humidity, 1));
return true; return true;
} }
@ -465,7 +465,7 @@ bool BleFingerprint::report(JsonObject *doc) {
if (maxDistance > 0 && dist > maxDistance) if (maxDistance > 0 && dist > maxDistance)
return false; return false;
auto now = esphome::millis(); auto now = millis();
if ((abs(dist - lastReported) < BleFingerprintCollection::skipDistance) && (lastReportedMillis > 0) && (now - lastReportedMillis < BleFingerprintCollection::skipMs)) if ((abs(dist - lastReported) < BleFingerprintCollection::skipDistance) && (lastReportedMillis > 0) && (now - lastReportedMillis < BleFingerprintCollection::skipMs))
return false; return false;
@ -483,7 +483,7 @@ bool BleFingerprint::query() {
if (!allowQuery || isQuerying) return false; if (!allowQuery || isQuerying) return false;
if (rssi < -90) return false; // Too far away if (rssi < -90) return false; // Too far away
auto now = esphome::millis(); auto now = millis();
if (now - lastSeenMillis > 5) return false; // Haven't seen lately if (now - lastSeenMillis > 5) return false; // Haven't seen lately
if (now - lastQryMillis < qryDelayMillis) return false; // Too soon if (now - lastQryMillis < qryDelayMillis) return false; // Too soon
@ -492,7 +492,7 @@ bool BleFingerprint::query() {
bool success = false; bool success = false;
ESP_LOGD(TAG, "%u Query | %s | %-58s%ddBm %lums\r\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), rssi, now - lastSeenMillis); ESP_LOGD("%u Query | %s | %-58s%ddBm %lums\r\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), rssi, now - lastSeenMillis);
NimBLEClient *pClient = NimBLEDevice::getClientListSize() ? NimBLEDevice::getClientByPeerAddress(address) : nullptr; NimBLEClient *pClient = NimBLEDevice::getClientListSize() ? NimBLEDevice::getClientByPeerAddress(address) : nullptr;
if (!pClient) pClient = NimBLEDevice::getDisconnectedClient(); if (!pClient) pClient = NimBLEDevice::getDisconnectedClient();
@ -518,7 +518,7 @@ bool BleFingerprint::query() {
} else { } else {
qryAttempts++; qryAttempts++;
qryDelayMillis = std::min(int(pow(10, qryAttempts)), 60000); qryDelayMillis = std::min(int(pow(10, qryAttempts)), 60000);
ESP_LOGD(TAG, "%u QryErr | %s | %-58s%ddBm Try %d, retry after %dms\r\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), rssi, qryAttempts, qryDelayMillis); ESP_LOGD("%u QryErr | %s | %-58s%ddBm Try %d, retry after %dms\r\n", xPortGetCoreID(), getMac().c_str(), id.c_str(), rssi, qryAttempts, qryDelayMillis);
} }
isQuerying = false; isQuerying = false;
return true; return true;

View File

@ -19,7 +19,9 @@
#include "esphome/core/hal.h" #include "esphome/core/hal.h"
#include "esphome/core/time.h" #include "esphome/core/time.h"
#define TAG "esp32_presense" #define log_e ESP_LOGE
#define millis esphome::millis
// #define delay esphome::delay
#define NO_RSSI int8_t(-128) #define NO_RSSI int8_t(-128)
@ -69,8 +71,6 @@
#define ID_TYPE_KNOWN_MAC short(210) #define ID_TYPE_KNOWN_MAC short(210)
#define ID_TYPE_ALIAS short(250) #define ID_TYPE_ALIAS short(250)
using namespace esphome;
class BleFingerprint { class BleFingerprint {
public: public:
BleFingerprint(NimBLEAdvertisedDevice *advertisedDevice, float fcmin, float beta, float dcutoff); BleFingerprint(NimBLEAdvertisedDevice *advertisedDevice, float fcmin, float beta, float dcutoff);

View File

@ -67,7 +67,7 @@ void Seen(BLEAdvertisedDevice *advertisedDevice) {
bool addOrReplace(DeviceConfig config) { bool addOrReplace(DeviceConfig config) {
if (xSemaphoreTake(deviceConfigMutex, MAX_WAIT) != pdTRUE) if (xSemaphoreTake(deviceConfigMutex, MAX_WAIT) != pdTRUE)
ESP_LOGE(TAG, "Couldn't take deviceConfigMutex in addOrReplace!"); log_e("Couldn't take deviceConfigMutex in addOrReplace!");
for (auto &it : deviceConfigs) { for (auto &it : deviceConfigs) {
if (it.id == config.id) { if (it.id == config.id) {
@ -198,7 +198,7 @@ void CleanupOldFingerprints() {
if (!any) { if (!any) {
auto uptime = (unsigned long)(esp_timer_get_time() / 1000000ULL); auto uptime = (unsigned long)(esp_timer_get_time() / 1000000ULL);
if (uptime > ALLOW_BLE_CONTROLLER_RESTART_AFTER_SECS) { if (uptime > ALLOW_BLE_CONTROLLER_RESTART_AFTER_SECS) {
ESP_LOGE(TAG, "Bluetooth controller seems stuck, restarting"); ESP_LOGE("Bluetooth controller seems stuck, restarting");
esp_restart(); esp_restart();
} }
} }
@ -227,7 +227,7 @@ BleFingerprint *getFingerprintInternal(BLEAdvertisedDevice *advertisedDevice) {
BleFingerprint *GetFingerprint(BLEAdvertisedDevice *advertisedDevice) { BleFingerprint *GetFingerprint(BLEAdvertisedDevice *advertisedDevice) {
if (xSemaphoreTake(fingerprintMutex, MAX_WAIT) != pdTRUE) if (xSemaphoreTake(fingerprintMutex, MAX_WAIT) != pdTRUE)
ESP_LOGE(TAG, "Couldn't take semaphore!"); log_e("Couldn't take semaphore!");
auto f = getFingerprintInternal(advertisedDevice); auto f = getFingerprintInternal(advertisedDevice);
xSemaphoreGive(fingerprintMutex); xSemaphoreGive(fingerprintMutex);
return f; return f;
@ -235,7 +235,7 @@ BleFingerprint *GetFingerprint(BLEAdvertisedDevice *advertisedDevice) {
const std::vector<BleFingerprint *> GetCopy() { const std::vector<BleFingerprint *> GetCopy() {
if (xSemaphoreTake(fingerprintMutex, MAX_WAIT) != pdTRUE) if (xSemaphoreTake(fingerprintMutex, MAX_WAIT) != pdTRUE)
ESP_LOGE(TAG, "Couldn't take fingerprintMutex!"); log_e("Couldn't take fingerprintMutex!");
CleanupOldFingerprints(); CleanupOldFingerprints();
std::vector<BleFingerprint *> copy(fingerprints); std::vector<BleFingerprint *> copy(fingerprints);
xSemaphoreGive(fingerprintMutex); xSemaphoreGive(fingerprintMutex);
@ -253,7 +253,7 @@ bool FindDeviceConfig(const std::string &id, DeviceConfig &config) {
xSemaphoreGive(deviceConfigMutex); xSemaphoreGive(deviceConfigMutex);
return false; return false;
} }
ESP_LOGE(TAG, "Couldn't take deviceConfigMutex!"); log_e("Couldn't take deviceConfigMutex!");
return false; return false;
} }

View File

@ -1,5 +1,4 @@
#include "MiFloraHandler.h" #include "MiFloraHandler.h"
#include "NimBLEAttValue.h"
namespace MiFloraHandler { namespace MiFloraHandler {
@ -11,7 +10,7 @@ bool readSensorData(BLERemoteService* floraService, DynamicJsonDocument* doc) {
floraCharacteristic = floraService->getCharacteristic(uuid_sensor_data); floraCharacteristic = floraService->getCharacteristic(uuid_sensor_data);
if (floraCharacteristic == nullptr) { if (floraCharacteristic == nullptr) {
ESP_LOGD(TAG, "-- Can't read characteristics"); ESP_LOGD("-- Can't read characteristics");
return false; return false;
} }
@ -21,7 +20,7 @@ bool readSensorData(BLERemoteService* floraService, DynamicJsonDocument* doc) {
value = floraCharacteristic->readValue(); value = floraCharacteristic->readValue();
if (value.size() == 0) { if (value.size() == 0) {
ESP_LOGD(TAG, "Reading Value failed"); ESP_LOGD("Reading Value failed");
return false; return false;
} }
@ -48,7 +47,7 @@ bool readBatteryData(BLERemoteService* floraService, DynamicJsonDocument* doc) {
floraCharacteristic = floraService->getCharacteristic(uuid_version_battery); floraCharacteristic = floraService->getCharacteristic(uuid_version_battery);
if (floraCharacteristic == nullptr) { if (floraCharacteristic == nullptr) {
ESP_LOGD(TAG, "-- Can't read characteristics"); ESP_LOGD("-- Can't read characteristics");
return false; return false;
} }
NimBLEAttValue val; NimBLEAttValue val;
@ -56,7 +55,7 @@ bool readBatteryData(BLERemoteService* floraService, DynamicJsonDocument* doc) {
val = floraCharacteristic->readValue(); val = floraCharacteristic->readValue();
if (val.size() == 0) { if (val.size() == 0) {
ESP_LOGD(TAG, "Reading Value failed"); ESP_LOGD("Reading Value failed");
return false; return false;
} }
@ -101,15 +100,15 @@ bool getFloraData(DynamicJsonDocument* doc, BLERemoteService* floraService, BleF
fillDeviceData(doc, f); fillDeviceData(doc, f);
if (!MiFloraHandler::readBatteryData(floraService, doc)) if (!MiFloraHandler::readBatteryData(floraService, doc))
ESP_LOGD(TAG, "Failed reading battery data"); ESP_LOGD("Failed reading battery data");
if (MiFloraHandler::forceFloraServiceDataMode(floraService)) { if (MiFloraHandler::forceFloraServiceDataMode(floraService)) {
} else { } else {
ESP_LOGD(TAG, "Failed to force data reading mode"); ESP_LOGD("Failed to force data reading mode");
} }
if (!MiFloraHandler::readSensorData(floraService, doc)) if (!MiFloraHandler::readSensorData(floraService, doc))
ESP_LOGD(TAG, "Failed reading sensor data"); ESP_LOGD("Failed reading sensor data");
return true; return true;
} }
@ -121,7 +120,7 @@ bool requestData(NimBLEClient* pClient, BleFingerprint* fingerprint) // Getting
NimBLERemoteService* floraService = pClient->getService(serviceUUID); NimBLERemoteService* floraService = pClient->getService(serviceUUID);
if (floraService == nullptr) { if (floraService == nullptr) {
ESP_LOGD(TAG, "Getting MiFlora service failed"); ESP_LOGD("Getting MiFlora service failed");
return false; return false;
} }

View File

@ -7,14 +7,14 @@ bool requestData(NimBLEClient* pClient, BleFingerprint* f) {
std::string sName = pClient->getValue(genericAccessService, nameChar); std::string sName = pClient->getValue(genericAccessService, nameChar);
if (!sName.empty() && sMdl.find(sName) == std::string::npos && sName != "Apple Watch") { if (!sName.empty() && sMdl.find(sName) == std::string::npos && sName != "Apple Watch") {
if (f->setId(std::string("name:") + kebabify(sName).c_str(), ID_TYPE_QUERY_NAME, std::string(sName.c_str()))) { if (f->setId(std::string("name:") + kebabify(sName).c_str(), ID_TYPE_QUERY_NAME, std::string(sName.c_str()))) {
// ESP_LOGD("\u001b[38;5;104m%u Name | %s | %-58s%ddBm %s\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getRssi(), sName.c_str()); ESP_LOGD("\u001b[38;5;104m%u Name | %s | %-58s%ddBm %s\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getRssi(), sName.c_str());
} }
return true; return true;
} }
if (!sMdl.empty()) { if (!sMdl.empty()) {
if (f->setId(std::string("apple:") + kebabify(sMdl).c_str(), ID_TYPE_QUERY_MODEL, std::string(sMdl.c_str()))) { if (f->setId(std::string("apple:") + kebabify(sMdl).c_str(), ID_TYPE_QUERY_MODEL, std::string(sMdl.c_str()))) {
// ESP_LOGD("\u001b[38;5;136m%u Model | %s | %-58s%ddBm %s\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getRssi(), sMdl.c_str()); ESP_LOGD("\u001b[38;5;136m%u Model | %s | %-58s%ddBm %s\u001b[0m\r\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str(), f->getRssi(), sMdl.c_str());
} }
return true; return true;
} }

View File

@ -30,19 +30,23 @@ CONFIG_SCHEMA = cv.Schema({
async def to_code(config): async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config) # await cg.register_component(var, config)
cg.add(var.set_room(config[CONF_ROOM_KEY])) cg.add(var.set_room(config[CONF_ROOM_KEY]))
# cg.add(var.set_base_topic(config[CONF_BASE_TOPIC_KEY])) # cg.add(var.set_base_topic(config[CONF_BASE_TOPIC_KEY]))
# cg.add(var.set_addresses(config[CONF_MAC_KEY])) # cg.add(var.set_addresses(config[CONF_MAC_KEY]))
cg.add(var.set_max_distance(config[CONF_MAX_DISTANCE])) # cg.add(var.set_max_distance(config[CONF_MAX_DISTANCE]))
add_idf_sdkconfig_option("CONFIG_BT_ENABLED", True) add_idf_sdkconfig_option("CONFIG_BT_ENABLED", True)
add_idf_sdkconfig_option("CONFIG_BT_BLUEDROID_ENABLED", False) add_idf_sdkconfig_option("CONFIG_BT_BLUEDROID_ENABLED", False)
add_idf_sdkconfig_option("CONFIG_BT_NIMBLE_ENABLED", True) add_idf_sdkconfig_option("CONFIG_BT_NIMBLE_ENABLED", True)
add_idf_sdkconfig_option("CONFIG_MBEDTLS_HARDWARE_AES", False) add_idf_sdkconfig_option("CONFIG_MBEDTLS_HARDWARE_AES", False)
cg.add_library("esp-nimble-cpp", repository="https://github.com/h2zero/esp-nimble-cpp#v1.4.1", version="v1.4.1") cg.add_library(
name="esp-nimble-cpp",
repository="https://github.com/h2zero/esp-nimble-cpp",
version="1.4.1"
)
# await nimble_tracker.device_listener_to_code(var, config) # await nimble_tracker.device_listener_to_code(var, config)
# await nimble_tracker.register_ble_device(var, config) # await nimble_tracker.register_ble_device(var, config)

View File

@ -1,5 +0,0 @@
#define BLE_SCAN_INTERVAL 0x80
#define BLE_SCAN_WINDOW 0x80
#define SCAN_TASK_STACK_SIZE 2562
#define CHANNEL "espresense"

View File

@ -9,101 +9,16 @@ namespace esphome
unsigned int totalFpQueried = 0; unsigned int totalFpQueried = 0;
unsigned int totalFpReported = 0; unsigned int totalFpReported = 0;
TimerHandle_t reconnectTimer;
TaskHandle_t scanTaskHandle;
unsigned long updateStartedMillis = 0;
unsigned long lastTeleMillis = 0;
int reconnectTries = 0;
int teleFails = 0;
int reportFailed = 0;
bool online = false; // Have we successfully sent status=online
bool sentDiscovery = false; // Have we successfully sent discovery
UBaseType_t bleStack = 0;
DynamicJsonDocument doc(1024);
std::string _id, roomsTopic;
bool discovery, publishTele, publishRooms, publishDevices;
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice *advertisedDevice) {
bleStack = uxTaskGetStackHighWaterMark(nullptr);
BleFingerprintCollection::Seen(advertisedDevice);
}
};
void scanTask(void *parameter) {
NimBLEDevice::init("ESPresense");
// Enrollment::Setup();
NimBLEDevice::setMTU(23);
auto pBLEScan = NimBLEDevice::getScan();
pBLEScan->setInterval(BLE_SCAN_INTERVAL);
pBLEScan->setWindow(BLE_SCAN_WINDOW);
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), true);
pBLEScan->setActiveScan(false);
pBLEScan->setDuplicateFilter(false);
pBLEScan->setMaxResults(0);
if (!pBLEScan->start(0, nullptr, false))
ESP_LOGE(TAG, "Error starting continuous ble scan");
while (true) {
for (auto &f : BleFingerprintCollection::fingerprints)
if (f->query())
totalFpQueried++;
// Enrollment::Loop();
if (!pBLEScan->isScanning()) {
if (!pBLEScan->start(0, nullptr, true))
ESP_LOGE(TAG, "Error re-starting continuous ble scan");
delay(3000); // If we stopped scanning, don't query for 3 seconds in order for us to catch any missed broadcasts
} else {
delay(100);
}
}
}
void ESP32Presense::set_room(std::string room) {
_id = slugify(room);
roomsTopic = std::string(CHANNEL) + std::string("/rooms/") + _id;
}
void ESP32Presense::set_max_distance(float maxDistance) {
BleFingerprintCollection::maxDistance = maxDistance;
}
void ESP32Presense::setup()
{
BleFingerprintCollection::Setup();
xTaskCreatePinnedToCore(scanTask, "scanTask", SCAN_TASK_STACK_SIZE, nullptr, 1, &scanTaskHandle, CONFIG_BT_NIMBLE_PINNED_TO_CORE);
publishDevices = true;
}
void ESP32Presense::loop()
{
reportLoop();
}
bool ESP32Presense::reportBuffer(BleFingerprint *f) {
auto report = f->getReport();
std::string topic = Sprintf(CHANNEL "/devices/%s/%s/%s", f->getId().c_str(), _id.c_str(), report.getId().c_str());
return this->publish(topic, report.getPayload());
}
void ESP32Presense::reportLoop() void ESP32Presense::reportLoop()
{ {
auto copy = BleFingerprintCollection::GetCopy(); auto copy = BleFingerprintCollection::GetCopy();
unsigned int count = 0; unsigned int count = 0;
for (auto &i : copy) for (auto &i : copy)
if (i->shouldCount()) if (i->shouldCount())
count++; count++;
yield();
sendTelemetry(totalSeen, totalFpSeen, totalFpQueried, totalFpReported, count); sendTelemetry(totalSeen, totalFpSeen, totalFpQueried, totalFpReported, count);
yield();
auto reported = 0; auto reported = 0;
for (auto &f : copy) { for (auto &f : copy) {
@ -113,47 +28,20 @@ namespace esphome
totalFpSeen++; totalFpSeen++;
} }
/*
if (f->hasReport()) { if (f->hasReport()) {
if (reportBuffer(f)) { if (reportBuffer(f))
f->clearReport(); f->clearReport();
}
} }
if (reportDevice(f)) {
if (this->reportDevice(f)) {
totalFpReported++; totalFpReported++;
reported++; reported++;
} }
*/
} }
} }
bool ESP32Presense::reportDevice(BleFingerprint *f) {
doc.clear();
JsonObject obj = doc.to<JsonObject>();
if (!f->report(&obj))
return false;
std::string buffer;
serializeJson(doc, buffer);
std::string devicesTopic = Sprintf(CHANNEL "/devices/%s/%s", f->getId().c_str(), _id.c_str());
bool p1 = false, p2 = false;
for (int i = 0; i < 10; i++) {
if (!p1 && (!publishRooms || this->publish(roomsTopic.c_str(), buffer.c_str())))
p1 = true;
if (!p2 && (!publishDevices || this->publish(devicesTopic.c_str(), buffer.c_str())))
p2 = true;
if (p1 && p2)
return true;
delay(20);
}
reportFailed++;
return false;
}
bool ESP32Presense::sendTelemetry( bool ESP32Presense::sendTelemetry(
unsigned int totalSeen, unsigned int totalSeen,
unsigned int totalFpSeen, unsigned int totalFpSeen,
@ -161,17 +49,17 @@ namespace esphome
unsigned int totalFpReported, unsigned int totalFpReported,
unsigned int count unsigned int count
) { ) {
this->publish(roomsTopic + "/status", "online"); this->publish(this->room_ + "/status", "online");
this->publish(roomsTopic + "/max_distance", BleFingerprintCollection::maxDistance); this->publish(this->room_ + "/max_distance", BleFingerprintCollection::maxDistance);
this->publish(roomsTopic + "/absorption", BleFingerprintCollection::absorption); this->publish(this->room_ + "/absorption", BleFingerprintCollection::absorption);
this->publish(roomsTopic + "/tx_ref_rssi", BleFingerprintCollection::txRefRssi); this->publish(this->room_ + "/tx_ref_rssi", BleFingerprintCollection::txRefRssi);
this->publish(roomsTopic + "/rx_adj_rssi", BleFingerprintCollection::rxAdjRssi); this->publish(this->room_ + "/rx_adj_rssi", BleFingerprintCollection::rxAdjRssi);
this->publish(roomsTopic + "/query", BleFingerprintCollection::query); this->publish(this->room_ + "/query", BleFingerprintCollection::query);
this->publish(roomsTopic + "/include", BleFingerprintCollection::include); this->publish(this->room_ + "/include", BleFingerprintCollection::include);
this->publish(roomsTopic + "/exclude", BleFingerprintCollection::exclude); this->publish(this->room_ + "/exclude", BleFingerprintCollection::exclude);
this->publish(roomsTopic + "/known_macs", BleFingerprintCollection::knownMacs); this->publish(this->room_ + "/known_macs", BleFingerprintCollection::knownMacs);
this->publish(roomsTopic + "/known_irks", BleFingerprintCollection::knownIrks); this->publish(this->room_ + "/known_irks", BleFingerprintCollection::knownIrks);
this->publish(roomsTopic + "/count_ids", BleFingerprintCollection::countIds); this->publish(this->room_ + "/count_ids", BleFingerprintCollection::countIds);
return true; return true;
} }

View File

@ -1,10 +1,8 @@
#pragma once #pragma once
#include <ArduinoJson.h>
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "esphome/components/mqtt/custom_mqtt_device.h" #include "esphome/components/mqtt/custom_mqtt_device.h"
#include "BleFingerprintCollection.h" #include "BleFingerprintCollection.h"
#include "defaults.h"
// #include "esphome/components/nimble_distance_custom/nimble_distance_custom.h" // #include "esphome/components/nimble_distance_custom/nimble_distance_custom.h"
namespace esphome namespace esphome
@ -12,11 +10,12 @@ namespace esphome
namespace esp32_presense namespace esp32_presense
{ {
class ESP32Presense : class ESP32Presense :
public Component,
public mqtt::CustomMQTTDevice public mqtt::CustomMQTTDevice
// public nimble_distance_custom::NimbleDistanceCustomComponent // public nimble_distance_custom::NimbleDistanceCustomComponent
{ {
protected: protected:
std::string room_;
BleFingerprint *ble_fingerprint = NULL; BleFingerprint *ble_fingerprint = NULL;
bool sendTelemetry( bool sendTelemetry(
@ -27,14 +26,11 @@ namespace esphome
unsigned int count unsigned int count
); );
public: public:
void setup() override; void setup() {};
void loop() override; void loop() {};
void reportLoop(); void reportLoop();
// void on_result(nimble_distance_custom::NimbleDistanceCustomResult&) override; // void on_result(nimble_distance_custom::NimbleDistanceCustomResult&) override;
void set_room(std::string room); void set_room(std::string room) { room_ = room; }
bool reportBuffer(BleFingerprint *f);
bool reportDevice(BleFingerprint *f);
void set_max_distance(float maxDistance);
//void set_base_topic(std::string base_topic) { base_topic_ = base_topic; } //void set_base_topic(std::string base_topic) { base_topic_ = base_topic; }
}; };
} // namespace esp32_nimble_tracker } // namespace esp32_nimble_tracker