From 5e1f327020e518c1d6730b2bc15288ca7ebd9c2d Mon Sep 17 00:00:00 2001 From: Darrell Date: Mon, 13 Sep 2021 21:22:00 -0400 Subject: [PATCH] Move lots of stuff to BleFingerprintCollection (#28) --- .../BleFingerprintCollection.cpp | 68 ++++++++++++++++++ lib/BleFingerprint/BleFingerprintCollection.h | 49 +++++++++++++ lib/GUI/GUI.cpp | 10 +++ lib/GUI/GUI.h | 42 ++++++++++- src/Settings.h | 40 ----------- src/main.cpp | 69 +------------------ src/main.h | 37 ++-------- 7 files changed, 177 insertions(+), 138 deletions(-) create mode 100644 lib/BleFingerprint/BleFingerprintCollection.cpp create mode 100644 lib/BleFingerprint/BleFingerprintCollection.h diff --git a/lib/BleFingerprint/BleFingerprintCollection.cpp b/lib/BleFingerprint/BleFingerprintCollection.cpp new file mode 100644 index 0000000..16fce94 --- /dev/null +++ b/lib/BleFingerprint/BleFingerprintCollection.cpp @@ -0,0 +1,68 @@ +#include "BleFingerprintCollection.h" + +void BleFingerprintCollection::cleanupOldFingerprints() +{ + if (fingerprints.size() <= maxCapacity) + return; + + long oldestTime = LONG_MAX; + BleFingerprint *oldest = nullptr; + for (auto it = fingerprints.begin(); it != fingerprints.end(); ++it) + { + long time = (*it)->getLastSeen(); + if (time < oldestTime) + { + oldestTime = time; + oldest = (*it); + } + } + if (oldest == nullptr) return; + + fingerprints.remove(oldest); + delete oldest; +} + +BleFingerprint *BleFingerprintCollection::getFingerprintInternal(BLEAdvertisedDevice *advertisedDevice) +{ + auto mac = advertisedDevice->getAddress(); + + auto it = std::find_if(fingerprints.begin(), fingerprints.end(), [mac](BleFingerprint *f) + { return f->getAddress() == mac; }); + if (it != fingerprints.end()) + { + return *it; + } + + auto created = new BleFingerprint(advertisedDevice, ONE_EURO_FCMIN, ONE_EURO_BETA, ONE_EURO_DCUTOFF); + auto it2 = std::find_if(fingerprints.begin(), fingerprints.end(), [created](BleFingerprint *f) + { return f->getId() == created->getId(); }); + if (it2 != fingerprints.end()) + { + auto found = *it2; + created->setInitial(found->getRSSI(), found->getDistance()); + } + + fingerprints.push_front(created); + return created; +} + +BleFingerprint *BleFingerprintCollection::getFingerprint(BLEAdvertisedDevice *advertisedDevice) +{ + if (xSemaphoreTake(fingerprintSemaphore, 1000) != pdTRUE) + log_e("Couldn't take semaphore!"); + auto f = getFingerprintInternal(advertisedDevice); + if (xSemaphoreGive(fingerprintSemaphore) != pdTRUE) + log_e("Couldn't give semaphore!"); + return f; +} + +std::list BleFingerprintCollection::getSeen() +{ + if (xSemaphoreTake(fingerprintSemaphore, 1000) != pdTRUE) + log_e("Couldn't take semaphore!"); + cleanupOldFingerprints(); + std::list seen(fingerprints); + if (xSemaphoreGive(fingerprintSemaphore) != pdTRUE) + log_e("Couldn't give semaphore!"); + return seen; +} diff --git a/lib/BleFingerprint/BleFingerprintCollection.h b/lib/BleFingerprint/BleFingerprintCollection.h new file mode 100644 index 0000000..9b9022d --- /dev/null +++ b/lib/BleFingerprint/BleFingerprintCollection.h @@ -0,0 +1,49 @@ +#ifndef _BLEFINGERPRINTCOLLECTION_ +#define _BLEFINGERPRINTCOLLECTION_ + +#include "BleFingerprint.h" +#include +#include +#include +#include +#include + +#define ONE_EURO_FCMIN 0.01 +#define ONE_EURO_BETA 0.005 +#define ONE_EURO_DCUTOFF 1 + +class BleFingerprintCollection : public BLEAdvertisedDeviceCallbacks +{ +public: + BleFingerprintCollection(int _maxCapacity) : maxCapacity{_maxCapacity} + { + fingerprintSemaphore = xSemaphoreCreateBinary(); + xSemaphoreGive(fingerprintSemaphore); + } + BleFingerprint *getFingerprint(BLEAdvertisedDevice *advertisedDevice); + void cleanupOldFingerprints(); + int getTotalAdverts() { return totalSeen; } + std::list getSeen(); + void setDisable(bool val) { disable = val; } + +private: + bool disable = false; + int totalSeen = 0; + int maxCapacity; + SemaphoreHandle_t fingerprintSemaphore; + std::list fingerprints; + BleFingerprint *getFingerprintInternal(BLEAdvertisedDevice *advertisedDevice); + + void onResult(BLEAdvertisedDevice *advertisedDevice) + { + totalSeen++; + if (disable) return; + + Display.seenStart(); + BleFingerprint *f = getFingerprint(advertisedDevice); + f->seen(advertisedDevice); + Display.seenEnd(); + } +}; + +#endif diff --git a/lib/GUI/GUI.cpp b/lib/GUI/GUI.cpp index 4eef4c6..61cba3d 100644 --- a/lib/GUI/GUI.cpp +++ b/lib/GUI/GUI.cpp @@ -2,6 +2,16 @@ GUI Display; +void GUI::seenStart() +{ + digitalWrite(LED_BUILTIN, LED_BUILTIN_ON); +} + +void GUI::seenEnd() +{ + digitalWrite(LED_BUILTIN, !LED_BUILTIN_ON); +} + void GUI::connected(bool wifi = false, bool mqtt = false) { status("Wifi: %s Mqtt: %s", (wifi ? "no" : "yes"), (wifi ? "no" : "yes")); diff --git a/lib/GUI/GUI.h b/lib/GUI/GUI.h index 8d17dd3..79447a8 100644 --- a/lib/GUI/GUI.h +++ b/lib/GUI/GUI.h @@ -11,9 +11,47 @@ #endif #endif +#ifdef M5STICK + +#define LED_BUILTIN 10 +#define LED_BUILTIN_ON 0 + +#define BUTTON 39 +#define BUTTON_PRESSED 0 + +#else +#if M5ATOM + +#define LED_BUILTIN 10 +#define LED_BUILTIN_ON 0 + +#define BUTTON 39 +#define BUTTON_PRESSED 0 + +#else // Huzzah32 or DevKit + +#define LED_BUILTIN 13 +#define LED_BUILTIN_ON 1 + +#define BUTTON 15 +#define BUTTON_PRESSED 1 + +#endif +#endif + +#ifdef M5STICK + +#else + +#endif + class GUI { public: + void seenStart(); + void seenEnd(); + void updateProgress(unsigned int percent) { digitalWrite(LED_BUILTIN, percent % 2); } + void updateEnd() { digitalWrite(LED_BUILTIN, !LED_BUILTIN_ON); } void close(const char *mac, const char *id); void left(const char *mac, const char *id); void status(const char *message, ...); @@ -28,6 +66,6 @@ private: #endif }; -#endif - extern GUI Display; + +#endif diff --git a/src/Settings.h b/src/Settings.h index 66d65e1..87718b9 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -26,40 +26,6 @@ // Maximum distance (in meters) to report. Devices that are calculated to be further than this distance in meters will not be reported #define DEFAULT_MAX_DISTANCE 16 -#ifdef M5STICK - -#define LED_BUILTIN 10 -#define LED_BUILTIN_ON 0 - -#define BUTTON 39 -#define BUTTON_PRESSED 0 - -#else -#if M5ATOM - -#define LED_BUILTIN 10 -#define LED_BUILTIN_ON 0 - -#define BUTTON 39 -#define BUTTON_PRESSED 0 - -#else // Huzzah32 or DevKit - -#define LED_BUILTIN 13 -#define LED_BUILTIN_ON 1 - -#define BUTTON 15 -#define BUTTON_PRESSED 1 - -#endif -#endif - -#ifdef M5STICK - -#else - -#endif - //Define the base topic for room detection. Usually "espresense" #define CHANNEL String("espresense") @@ -74,9 +40,3 @@ // Number of seconds between update checks #define CHECK_FOR_UPDATES_INTERVAL 300 - -#define ONE_EURO_FCMIN 0.01 - -#define ONE_EURO_BETA 0.005 - -#define ONE_EURO_DCUTOFF 1 diff --git a/src/main.cpp b/src/main.cpp index d6b2acb..4f9c2b2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,37 +1,5 @@ #include -BleFingerprint *getFingerprintInternal(BLEAdvertisedDevice *advertisedDevice) -{ - auto mac = advertisedDevice->getAddress(); - - auto it = std::find_if(fingerprints.begin(), fingerprints.end(), [mac](BleFingerprint *f) { return f->getAddress() == mac; }); - if (it != fingerprints.end()) - { - return *it; - } - - auto created = new BleFingerprint(advertisedDevice, ONE_EURO_FCMIN, ONE_EURO_BETA, ONE_EURO_DCUTOFF); - auto it2 = std::find_if(fingerprints.begin(), fingerprints.end(), [created](BleFingerprint *f) { return f->getId() == created->getId(); }); - if (it2 != fingerprints.end()) - { - auto found = *it2; - created->setInitial(found->getRSSI(), found->getDistance()); - } - - fingerprints.push_front(created); - return created; -} - -BleFingerprint *getFingerprint(BLEAdvertisedDevice *advertisedDevice) -{ - if (xSemaphoreTake(fingerprintSemaphore, 1000) != pdTRUE) - log_e("Couldn't take semaphore!"); - auto f = getFingerprintInternal(advertisedDevice); - if (xSemaphoreGive(fingerprintSemaphore) != pdTRUE) - log_e("Couldn't give semaphore!"); - return f; -} - bool sendTelemetry(int totalSeen = -1, int totalReported = -1, int totalAdverts = -1) { if (!online) @@ -204,26 +172,6 @@ void connectToMqtt() mqttClient.connect(); } -class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks -{ -public: - int getTotalAdverts() { return totalSeen; } - -private: - int totalSeen = 0; - - void onResult(BLEAdvertisedDevice *advertisedDevice) - { - if (updateInProgress) - return; - totalSeen++; - digitalWrite(LED_BUILTIN, LED_BUILTIN_ON); - BleFingerprint *f = getFingerprint(advertisedDevice); - f->seen(advertisedDevice); - digitalWrite(LED_BUILTIN, !LED_BUILTIN_ON); - } -}; - bool reportDevice(BleFingerprint *f) { StaticJsonDocument<512> doc; @@ -257,14 +205,11 @@ bool reportDevice(BleFingerprint *f) void scanForDevices(void *parameter) { - fingerprintSemaphore = xSemaphoreCreateBinary(); - xSemaphoreGive(fingerprintSemaphore); - auto scan = MyAdvertisedDeviceCallbacks(); BLEDevice::init(""); auto pBLEScan = BLEDevice::getScan(); pBLEScan->setInterval(BLE_SCAN_INTERVAL); pBLEScan->setWindow(BLE_SCAN_WINDOW); - pBLEScan->setAdvertisedDeviceCallbacks(&scan, true); + pBLEScan->setAdvertisedDeviceCallbacks(&fingerprints, true); pBLEScan->setActiveScan(BLE_ACTIVE_SCAN); pBLEScan->setMaxResults(0); if (!pBLEScan->start(0, nullptr, false)) @@ -277,18 +222,10 @@ void scanForDevices(void *parameter) if (updateInProgress || !mqttClient.connected()) continue; - auto results = scan; - pBLEScan->setAdvertisedDeviceCallbacks(&(scan = MyAdvertisedDeviceCallbacks()), true); - int totalSeen = 0; int totalReported = 0; - if (xSemaphoreTake(fingerprintSemaphore, 1000) != pdTRUE) - log_e("Couldn't take semaphore!"); - cleanupOldFingerprints(); - std::list seen(fingerprints); - if (xSemaphoreGive(fingerprintSemaphore) != pdTRUE) - log_e("Couldn't give semaphore!"); + auto seen = fingerprints.getSeen(); for (auto it = seen.begin(); it != seen.end(); ++it) { @@ -296,7 +233,7 @@ void scanForDevices(void *parameter) if (reportDevice(*it)) totalReported++; } - sendTelemetry(totalSeen, totalReported, results.getTotalAdverts()); + sendTelemetry(totalSeen, totalReported, fingerprints.getTotalAdverts()); } } diff --git a/src/main.h b/src/main.h index f7f6770..9306ffc 100644 --- a/src/main.h +++ b/src/main.h @@ -5,11 +5,8 @@ #include #include #include -#include #include #include -#include -#include #include #include #include @@ -20,6 +17,7 @@ #include #include "BleFingerprint.h" +#include "BleFingerprintCollection.h" #include "Settings.h" AsyncMqttClient mqttClient; @@ -45,9 +43,7 @@ bool publishTele; bool publishRooms; bool publishDevices; int maxDistance; - -static SemaphoreHandle_t fingerprintSemaphore; -static std::list fingerprints; +BleFingerprintCollection fingerprints(MAX_MAC_ADDRESSES); String resetReason(RESET_REASON reason) { @@ -116,16 +112,18 @@ void configureOTA() .onStart([]() { Serial.println("OTA Start"); updateInProgress = true; + fingerprints.setDisable(updateInProgress); }) .onEnd([]() { updateInProgress = false; - digitalWrite(LED_BUILTIN, !LED_BUILTIN_ON); + fingerprints.setDisable(updateInProgress); + Display.updateEnd(); Serial.println("\n\rEnd"); }) .onProgress([](unsigned int progress, unsigned int total) { byte percent = (progress / (total / 100)); Serial.printf("Progress: %u\r\n", percent); - digitalWrite(LED_BUILTIN, percent % 2); + Display.updateProgress(progress); }) .onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); @@ -178,6 +176,7 @@ void firmwareUpdate() } updateInProgress = true; + fingerprints.setDisable(updateInProgress); httpUpdate.setLedPin(LED_BUILTIN, LED_BUILTIN_ON); httpUpdate.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS); t_httpUpdate_return ret = httpUpdate.update(client, firmwareUrl); @@ -240,25 +239,3 @@ void spiffsInit() SPIFFS.begin(true); } - -void cleanupOldFingerprints() -{ - if (fingerprints.size() <= MAX_MAC_ADDRESSES) - return; - - long oldestTime = LONG_MAX; - BleFingerprint *oldest = nullptr; - for (auto it = fingerprints.begin(); it != fingerprints.end(); ++it) - { - long time = (*it)->getLastSeen(); - if (time < oldestTime) - { - oldestTime = time; - oldest = (*it); - } - } - if (oldest == nullptr) return; - - fingerprints.remove(oldest); - delete oldest; -}