add code for presence detection

This commit is contained in:
technyon
2022-04-05 21:35:21 +02:00
parent 286ac0effe
commit 4616b5e020
7 changed files with 162 additions and 8 deletions

View File

@@ -21,6 +21,7 @@ file(GLOB SRCFILES
NukiWrapper.cpp
MqttTopics.h
WebCfgServer.cpp
PresenceDetection.cpp
PreferencesKeys.h
lib/ESP32_BLE_Arduino-1.0.1/src/*.cpp
lib/ESP32_BLE_Arduino-1.0.1/src/*.h

View File

@@ -19,12 +19,21 @@ NukiWrapper::NukiWrapper(const std::string& name, uint32_t id, Network* network,
network->setLockActionReceived(nukiInst->onLockActionReceived);
}
NukiWrapper::~NukiWrapper()
{
delete _bleScanner;
_bleScanner = nullptr;
}
void NukiWrapper::initialize()
{
_bleScanner.initialize();
_bleScanner.setScanDuration(30);
_bleScanner = new BleScanner();
_bleScanner->initialize();
_bleScanner->setScanDuration(30);
_nukiBle.initialize();
_nukiBle.registerBleScanner(&_bleScanner);
_nukiBle.registerBleScanner(_bleScanner);
_intervalLockstate = _preferences->getInt(preference_query_interval_lockstate);
_intervalBattery = _preferences->getInt(preference_query_interval_battery);
@@ -53,7 +62,7 @@ void NukiWrapper::update()
if (!_paired) {
Serial.println(F("Nuki start pairing"));
_bleScanner.update();
_bleScanner->update();
vTaskDelay( 5000 / portTICK_PERIOD_MS);
if (_nukiBle.pairNuki()) {
Serial.println(F("Nuki paired"));
@@ -67,7 +76,7 @@ void NukiWrapper::update()
}
vTaskDelay( 20 / portTICK_PERIOD_MS);
_bleScanner.update();
_bleScanner->update();
unsigned long ts = millis();
@@ -149,6 +158,11 @@ const bool NukiWrapper::isPaired()
return _paired;
}
BleScanner *NukiWrapper::bleScanner()
{
return _bleScanner;
}
void NukiWrapper::notify(Nuki::EventType eventType)
{
if(eventType == Nuki::EventType::KeyTurnerStatusUpdated)

View File

@@ -9,12 +9,15 @@ class NukiWrapper : public Nuki::SmartlockEventHandler
{
public:
NukiWrapper(const std::string& name, uint32_t id, Network* network, Preferences* preferences);
virtual ~NukiWrapper();
void initialize();
void update();
const bool isPaired();
BleScanner* bleScanner();
void notify(Nuki::EventType eventType) override;
private:
@@ -26,7 +29,7 @@ private:
Nuki::LockAction lockActionToEnum(const char* str); // char array at least 14 characters
Nuki::NukiBle _nukiBle;
BleScanner _bleScanner;
BleScanner* _bleScanner;
Network* _network;
Preferences* _preferences;
int _intervalLockstate = 0; // seconds

94
PresenceDetection.cpp Normal file
View File

@@ -0,0 +1,94 @@
#include "PresenceDetection.h"
PresenceDetection::PresenceDetection(BleScanner *bleScanner)
: _bleScanner(bleScanner)
{}
PresenceDetection::~PresenceDetection()
{
_bleScanner->unsubscribe(this);
_bleScanner = nullptr;
}
void PresenceDetection::initialize()
{
_bleScanner->subscribe(this);
}
void PresenceDetection::update()
{
vTaskDelay( 10000 / portTICK_PERIOD_MS);
long ts = millis();
for(auto it : _devices)
{
if(ts - 20000 < it.second.timestamp)
{
// TODO: publish to mqtt
}
}
}
void PresenceDetection::onResult(NimBLEAdvertisedDevice *device)
{
std::string addressStr = device->getAddress().toString();
char addrArrComp[13] = {0};
// aa:bb:cc:dd:ee:ff
addrArrComp[0] = addressStr.at(0);
addrArrComp[1] = addressStr.at(1);
addrArrComp[2] = addressStr.at(3);
addrArrComp[3] = addressStr.at(4);
addrArrComp[4] = addressStr.at(6);
addrArrComp[5] = addressStr.at(7);
addrArrComp[6] = addressStr.at(9);
addrArrComp[7] = addressStr.at(10);
addrArrComp[8] = addressStr.at(12);
addrArrComp[9] = addressStr.at(13);
addrArrComp[10] = addressStr.at(15);
addrArrComp[11] = addressStr.at(16);
long long addr = strtoll(addrArrComp, nullptr, 16);
auto it = _devices.find(addr);
if(it == _devices.end())
{
PdDevice pdDevice;
int i=0;
size_t len = addressStr.length();
while(i < len)
{
pdDevice.address[i] = addressStr.at(i);
++i;
}
if(device->haveName())
{
std::string nameStr = device->getName();
int i=0;
size_t len = nameStr.length();
while(i < len && i < sizeof(pdDevice.name)-1)
{
pdDevice.name[i] = nameStr.at(i);
++i;
}
pdDevice.timestamp = millis();
_devices[addr] = pdDevice;
}
}
else
{
it->second.timestamp = millis();
}
// if(device->haveName())
// {
// Serial.print(" | ");
// Serial.print(device->getName().c_str());
// }
// Serial.println();
}

28
PresenceDetection.h Normal file
View File

@@ -0,0 +1,28 @@
#pragma once
#include "BleScanner.h"
#include "BleInterfaces.h"
struct PdDevice
{
char address[18] = {0};
char name[30] = {0};
unsigned long timestamp;
};
class PresenceDetection : public BLEScannerSubscriber
{
public:
PresenceDetection(BleScanner* bleScanner);
virtual ~PresenceDetection();
void initialize();
void update();
void onResult(NimBLEAdvertisedDevice* advertisedDevice) override;
private:
BleScanner* _bleScanner;
std::map<long long, PdDevice> _devices;
uint _timeout = 20000;
};

View File

@@ -4,12 +4,14 @@
#include "WebCfgServer.h"
#include <FreeRTOS.h>
#include "PreferencesKeys.h"
#include "PresenceDetection.h"
#define ESP32
Network* network;
WebCfgServer* webCfgServer;
NukiWrapper* nuki;
PresenceDetection* presenceDetection;
Preferences* preferences;
void networkTask(void *pvParameters)
@@ -29,10 +31,19 @@ void nukiTask(void *pvParameters)
}
}
void presenceDetectionTask(void *pvParameters)
{
while(true)
{
presenceDetection->update();
}
}
void setupTasks()
{
xTaskCreate(networkTask, "ntw", 16384, NULL, 1, NULL);
xTaskCreate(nukiTask, "nuki", 8192, NULL, 1, NULL);
xTaskCreate(presenceDetectionTask, "prdet", 1024, NULL, 1, NULL);
}
uint32_t getRandomId()
@@ -66,8 +77,11 @@ void setup()
nuki = new NukiWrapper("ESP", deviceId, network, preferences);
webCfgServer = new WebCfgServer(nuki, network, preferences);
webCfgServer->initialize();
nuki->initialize();
presenceDetection = new PresenceDetection(nuki->bleScanner());
presenceDetection->initialize();
setupTasks();
}