Move lots of stuff to BleFingerprintCollection (#28)

This commit is contained in:
Darrell 2021-09-13 21:22:00 -04:00 committed by DTTerastar
parent 3b384c49c7
commit 5e1f327020
7 changed files with 177 additions and 138 deletions

View File

@ -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<BleFingerprint *> BleFingerprintCollection::getSeen()
{
if (xSemaphoreTake(fingerprintSemaphore, 1000) != pdTRUE)
log_e("Couldn't take semaphore!");
cleanupOldFingerprints();
std::list<BleFingerprint *> seen(fingerprints);
if (xSemaphoreGive(fingerprintSemaphore) != pdTRUE)
log_e("Couldn't give semaphore!");
return seen;
}

View File

@ -0,0 +1,49 @@
#ifndef _BLEFINGERPRINTCOLLECTION_
#define _BLEFINGERPRINTCOLLECTION_
#include "BleFingerprint.h"
#include <ArduinoJson.h>
#include <GUI.h>
#include <NimBLEAdvertisedDevice.h>
#include <NimBLEBeacon.h>
#include <NimBLEDevice.h>
#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<BleFingerprint *> getSeen();
void setDisable(bool val) { disable = val; }
private:
bool disable = false;
int totalSeen = 0;
int maxCapacity;
SemaphoreHandle_t fingerprintSemaphore;
std::list<BleFingerprint *> 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

View File

@ -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"));

View File

@ -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

View File

@ -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

View File

@ -1,37 +1,5 @@
#include <main.h>
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<BleFingerprint *> 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());
}
}

View File

@ -5,11 +5,8 @@
#include <AsyncTCP.h>
#include <HTTPClient.h>
#include <HTTPUpdate.h>
#include <NimBLEAdvertisedDevice.h>
#include <NimBLEBeacon.h>
#include <NimBLEDevice.h>
#include <NimBLEEddystoneTLM.h>
#include <NimBLEEddystoneURL.h>
#include <SPIFFS.h>
#include <WebServer.h>
#include <WiFi.h>
@ -20,6 +17,7 @@
#include <rom/rtc.h>
#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<BleFingerprint *> 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;
}