Move lots of stuff to BleFingerprintCollection (#28)
This commit is contained in:
parent
3b384c49c7
commit
5e1f327020
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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"));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
69
src/main.cpp
69
src/main.cpp
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
37
src/main.h
37
src/main.h
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue