fix presence detection

This commit is contained in:
technyon
2024-06-15 08:18:12 +02:00
parent a419447f9e
commit 705e0971d7
7 changed files with 47 additions and 75 deletions

View File

@@ -14,8 +14,9 @@ bool _versionPublished = false;
RTC_NOINIT_ATTR char WiFi_fallbackDetect[14];
Network::Network(Preferences *preferences, Gpio* gpio, const String& maintenancePathPrefix, char* buffer, size_t bufferSize)
Network::Network(Preferences *preferences, PresenceDetection* presenceDetection, Gpio* gpio, const String& maintenancePathPrefix, char* buffer, size_t bufferSize)
: _preferences(preferences),
_presenceDetection(presenceDetection),
_gpio(gpio),
_buffer(buffer),
_bufferSize(bufferSize)
@@ -332,15 +333,19 @@ bool Network::update()
_lastConnectedTs = ts;
if(_presenceCsv != nullptr && strlen(_presenceCsv) > 0)
if(_presenceDetection != nullptr && (_lastPresenceTs == 0 || (ts - _lastPresenceTs) > 3000))
{
bool success = publishString(_mqttPresencePrefix, mqtt_topic_presence, _presenceCsv);
char* presenceCsv = _presenceDetection->generateCsv();
// if(_presenceCsv != nullptr && strlen(_presenceCsv) > 0)
bool success = publishString(_mqttPresencePrefix, mqtt_topic_presence, presenceCsv);
if(!success)
{
Log->println(F("Failed to publish presence CSV data."));
Log->println(_presenceCsv);
Log->println(presenceCsv);
}
_presenceCsv = nullptr;
_lastPresenceTs = ts;
}
if(_device->signalStrength() != 127 && _rssiPublishInterval > 0 && ts - _lastRssiTs > _rssiPublishInterval)
@@ -3564,11 +3569,6 @@ void Network::timeZoneIdToString(const Nuki::TimeZoneId timeZoneId, char* str) {
}
}
void Network::publishPresenceDetection(char *csv)
{
_presenceCsv = csv;
}
const NetworkDeviceType Network::networkDeviceType()
{
return _networkDeviceType;

View File

@@ -11,6 +11,7 @@
#include <ArduinoJson.h>
#include <HTTPClient.h>
#include "NukiConstants.h"
#include "PresenceDetection.h"
enum class NetworkDeviceType
{
@@ -28,7 +29,7 @@ enum class NetworkDeviceType
class Network
{
public:
explicit Network(Preferences* preferences, Gpio* gpio, const String& maintenancePathPrefix, char* buffer, size_t bufferSize);
explicit Network(Preferences* preferences, PresenceDetection* presenceDetection, Gpio* gpio, const String& maintenancePathPrefix, char* buffer, size_t bufferSize);
void initialize();
bool update();
@@ -79,8 +80,6 @@ public:
void clearWifiFallback();
void publishPresenceDetection(char* csv);
int mqttConnectionState(); // 0 = not connected; 1 = connected; 2 = connected and mqtt processed
bool encryptionSupported();
const String networkDeviceName() const;
@@ -133,6 +132,7 @@ private:
HTTPClient https;
Preferences* _preferences;
PresenceDetection* _presenceDetection;
Gpio* _gpio;
IPConfiguration* _ipConfiguration = nullptr;
String _hostname;
@@ -149,7 +149,6 @@ private:
char _maintenancePathPrefix[181] = {0};
int _networkTimeout = 0;
std::vector<MqttReceiver*> _mqttReceivers;
char* _presenceCsv = nullptr;
bool _restartOnDisconnect = false;
bool _firstConnect = true;
bool _publishDebugInfo = false;
@@ -159,6 +158,7 @@ private:
unsigned long _lastConnectedTs = 0;
unsigned long _lastMaintenanceTs = 0;
unsigned long _lastUpdateCheckTs = 0;
unsigned long _lastPresenceTs = 0;
unsigned long _lastRssiTs = 0;
bool _mqttEnabled = true;
static unsigned long _ignoreSubscriptionsTs;

View File

@@ -82,7 +82,6 @@
#define preference_latest_version (char*)"latest"
#define preference_task_size_network (char*)"tsksznetw"
#define preference_task_size_nuki (char*)"tsksznuki"
#define preference_task_size_pd (char*)"tskszpd"
#define preference_authlog_max_entries (char*)"authmaxentry"
#define preference_keypad_max_entries (char*)"kpmaxentry"
#define preference_timecontrol_max_entries (char*)"tcmaxentry"
@@ -112,7 +111,7 @@ private:
preference_register_as_app, preference_register_opener_as_app, preference_command_nr_of_retries, preference_command_retry_delay, preference_cred_user, preference_cred_password,
preference_disable_non_json, preference_publish_authdata, preference_publish_debug_info, preference_presence_detection_timeout, preference_official_hybrid, preference_query_interval_hybrid_lockstate,
preference_official_hybrid_actions, preference_official_hybrid_retry, preference_has_mac_saved, preference_has_mac_byte_0, preference_has_mac_byte_1, preference_has_mac_byte_2,
preference_latest_version, preference_task_size_network, preference_task_size_nuki, preference_task_size_pd, preference_authlog_max_entries, preference_keypad_max_entries,
preference_latest_version, preference_task_size_network, preference_task_size_nuki, preference_authlog_max_entries, preference_keypad_max_entries,
preference_timecontrol_max_entries
};
std::vector<char*> _redact =

View File

@@ -7,10 +7,9 @@
#include "NimBLEBeacon.h"
#include "NukiUtils.h"
PresenceDetection::PresenceDetection(Preferences* preferences, BleScanner::Scanner *bleScanner, Network* network, char* buffer, size_t bufferSize)
PresenceDetection::PresenceDetection(Preferences* preferences, BleScanner::Scanner *bleScanner, char* buffer, size_t bufferSize)
: _preferences(preferences),
_bleScanner(bleScanner),
_network(network),
_csv(buffer),
_bufferSize(bufferSize)
{
@@ -30,8 +29,6 @@ PresenceDetection::~PresenceDetection()
_bleScanner->unsubscribe(this);
_bleScanner = nullptr;
_network = nullptr;
delete _csv;
_csv = nullptr;
}
@@ -41,20 +38,11 @@ void PresenceDetection::initialize()
_bleScanner->subscribe(this);
}
void PresenceDetection::update()
char* PresenceDetection::generateCsv()
{
delay(3000);
if(_timeout < 0) return;
if(!enabled()) return nullptr;
memset(_csv, 0, _bufferSize);
if(_devices.size() == 0)
{
strcpy(_csv, ";;");
_network->publishPresenceDetection(_csv);
return;
}
_csvIndex = 0;
long ts = millis();
for(auto it : _devices)
@@ -71,11 +59,14 @@ void PresenceDetection::update()
}
}
_csv[_csvIndex-1] = 0x00;
if(_csvIndex == 0)
{
strcpy(_csv, ";;");
return _csv;
}
// Log->print("Devices found: ");
// Log->println(_devices.size());
_network->publishPresenceDetection(_csv);
_csv[_csvIndex-1] = 0x00;
return _csv;
}
@@ -220,4 +211,9 @@ void PresenceDetection::onResult(NimBLEAdvertisedDevice *device)
// }
// Log->println();
}
}
bool PresenceDetection::enabled()
{
return _timeout > 0;
}

View File

@@ -1,8 +1,9 @@
#pragma once
#include <Preferences.h>
#include "BleScanner.h"
#include "BleInterfaces.h"
#include "Network.h"
#include <memory>
struct PdDevice
{
@@ -16,11 +17,12 @@ struct PdDevice
class PresenceDetection : public BleScanner::Subscriber
{
public:
PresenceDetection(Preferences* preferences, BleScanner::Scanner* bleScanner, Network* network, char* buffer, size_t bufferSize);
PresenceDetection(Preferences* preferences, BleScanner::Scanner* bleScanner, char* buffer, size_t bufferSize);
virtual ~PresenceDetection();
void initialize();
void update();
char* generateCsv();
bool enabled();
void onResult(NimBLEAdvertisedDevice* advertisedDevice) override;
@@ -29,7 +31,6 @@ private:
Preferences* _preferences;
BleScanner::Scanner* _bleScanner;
Network* _network;
char* _csv = {0};
size_t _bufferSize = 0;
std::map<long long, std::shared_ptr<PdDevice>> _devices;

View File

@@ -538,14 +538,6 @@ bool WebCfgServer::processArgs(String& message)
configChanged = true;
}
}
else if(key == "TSKPD")
{
if(value.toInt() > 1023 && value.toInt() < 4049)
{
_preferences->putInt(preference_task_size_pd, value.toInt());
configChanged = true;
}
}
else if(key == "ALMAX")
{
if(value.toInt() > 0 && value.toInt() < 51)
@@ -1398,7 +1390,6 @@ void WebCfgServer::buildAdvancedConfigHtml(String &response)
printInputField(response, "BUFFSIZE", "Char buffer size (min 4096, max 32768)", _preferences->getInt(preference_buffer_size, CHAR_BUFFER_SIZE), 6, "");
printInputField(response, "TSKNTWK", "Task size Network (min 12288, max 32768)", _preferences->getInt(preference_task_size_network, NETWORK_TASK_SIZE), 6, "");
printInputField(response, "TSKNUKI", "Task size Nuki (min 8192, max 32768)", _preferences->getInt(preference_task_size_nuki, NUKI_TASK_SIZE), 6, "");
printInputField(response, "TSKPD", "Task size Presence Detection (min 1024, max 4048)", _preferences->getInt(preference_task_size_pd, PD_TASK_SIZE), 6, "");
printInputField(response, "ALMAX", "Max auth log entries (min 1, max 50)", _preferences->getInt(preference_authlog_max_entries, MAX_AUTHLOG), 3, "inputmaxauthlog");
printInputField(response, "KPMAX", "Max keypad entries (min 1, max 100)", _preferences->getInt(preference_keypad_max_entries, MAX_KEYPAD), 3, "inputmaxkeypad");
printInputField(response, "TCMAX", "Max timecontrol entries (min 1, max 50)", _preferences->getInt(preference_timecontrol_max_entries, MAX_TIMECONTROL), 3, "inputmaxtimecontrol");

View File

@@ -103,26 +103,12 @@ void nukiTask(void *pvParameters)
}
}
void presenceDetectionTask(void *pvParameters)
{
while(true)
{
presenceDetection->update();
}
}
void setupTasks()
{
// configMAX_PRIORITIES is 25
xTaskCreatePinnedToCore(networkTask, "ntw", preferences->getInt(preference_task_size_network, NETWORK_TASK_SIZE), NULL, 3, &networkTaskHandle, 1);
xTaskCreatePinnedToCore(nukiTask, "nuki", preferences->getInt(preference_task_size_nuki, NUKI_TASK_SIZE), NULL, 2, &nukiTaskHandle, 1);
if(preferences->getInt(preference_presence_detection_timeout) >= 0)
{
xTaskCreatePinnedToCore(presenceDetectionTask, "prdet", preferences->getInt(preference_task_size_pd, PD_TASK_SIZE), NULL, 5, &presenceDetectionTaskHandle, 1);
}
}
void initEthServer(const NetworkDeviceType device)
@@ -282,7 +268,6 @@ void setup()
preferences->putInt(preference_buffer_size, CHAR_BUFFER_SIZE);
preferences->putInt(preference_task_size_network, NETWORK_TASK_SIZE);
preferences->putInt(preference_task_size_nuki, NUKI_TASK_SIZE);
preferences->putInt(preference_task_size_pd, PD_TASK_SIZE);
preferences->putInt(preference_authlog_max_entries, MAX_AUTHLOG);
preferences->putInt(preference_keypad_max_entries, MAX_KEYPAD);
preferences->putInt(preference_timecontrol_max_entries, MAX_TIMECONTROL);
@@ -314,11 +299,21 @@ void setup()
gpio->getConfigurationText(gpioDesc, gpio->pinConfiguration(), "\n\r");
Serial.print(gpioDesc.c_str());
bleScanner = new BleScanner::Scanner();
bleScanner->initialize("NukiHub");
bleScanner->setScanDuration(10);
if(preferences->getInt(preference_presence_detection_timeout) >= 0)
{
presenceDetection = new PresenceDetection(preferences, bleScanner, CharBuffer::get(), CHAR_BUFFER_SIZE);
presenceDetection->initialize();
}
lockEnabled = preferences->getBool(preference_lock_enabled);
openerEnabled = preferences->getBool(preference_opener_enabled);
const String mqttLockPath = preferences->getString(preference_mqtt_lock_path);
network = new Network(preferences, gpio, mqttLockPath, CharBuffer::get(), buffer_size);
network = new Network(preferences, presenceDetection, gpio, mqttLockPath, CharBuffer::get(), buffer_size);
network->initialize();
networkLock = new NetworkLock(network, preferences, CharBuffer::get(), buffer_size);
@@ -332,10 +327,6 @@ void setup()
initEthServer(network->networkDeviceType());
bleScanner = new BleScanner::Scanner();
bleScanner->initialize("NukiHub");
bleScanner->setScanDuration(10);
Log->println(lockEnabled ? F("Nuki Lock enabled") : F("Nuki Lock disabled"));
if(lockEnabled)
{
@@ -356,12 +347,6 @@ void setup()
webCfgServer->initialize();
}
if(preferences->getInt(preference_presence_detection_timeout) >= 0)
{
presenceDetection = new PresenceDetection(preferences, bleScanner, network, CharBuffer::get(), CHAR_BUFFER_SIZE);
presenceDetection->initialize();
}
setupTasks();
}