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]; 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), : _preferences(preferences),
_presenceDetection(presenceDetection),
_gpio(gpio), _gpio(gpio),
_buffer(buffer), _buffer(buffer),
_bufferSize(bufferSize) _bufferSize(bufferSize)
@@ -332,15 +333,19 @@ bool Network::update()
_lastConnectedTs = ts; _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) if(!success)
{ {
Log->println(F("Failed to publish presence CSV data.")); 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) 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() const NetworkDeviceType Network::networkDeviceType()
{ {
return _networkDeviceType; return _networkDeviceType;

View File

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

View File

@@ -82,7 +82,6 @@
#define preference_latest_version (char*)"latest" #define preference_latest_version (char*)"latest"
#define preference_task_size_network (char*)"tsksznetw" #define preference_task_size_network (char*)"tsksznetw"
#define preference_task_size_nuki (char*)"tsksznuki" #define preference_task_size_nuki (char*)"tsksznuki"
#define preference_task_size_pd (char*)"tskszpd"
#define preference_authlog_max_entries (char*)"authmaxentry" #define preference_authlog_max_entries (char*)"authmaxentry"
#define preference_keypad_max_entries (char*)"kpmaxentry" #define preference_keypad_max_entries (char*)"kpmaxentry"
#define preference_timecontrol_max_entries (char*)"tcmaxentry" #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_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_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_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 preference_timecontrol_max_entries
}; };
std::vector<char*> _redact = std::vector<char*> _redact =

View File

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

View File

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

View File

@@ -538,14 +538,6 @@ bool WebCfgServer::processArgs(String& message)
configChanged = true; 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") else if(key == "ALMAX")
{ {
if(value.toInt() > 0 && value.toInt() < 51) 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, "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, "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, "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, "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, "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"); 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() void setupTasks()
{ {
// configMAX_PRIORITIES is 25 // configMAX_PRIORITIES is 25
xTaskCreatePinnedToCore(networkTask, "ntw", preferences->getInt(preference_task_size_network, NETWORK_TASK_SIZE), NULL, 3, &networkTaskHandle, 1); 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); 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) void initEthServer(const NetworkDeviceType device)
@@ -282,7 +268,6 @@ void setup()
preferences->putInt(preference_buffer_size, CHAR_BUFFER_SIZE); preferences->putInt(preference_buffer_size, CHAR_BUFFER_SIZE);
preferences->putInt(preference_task_size_network, NETWORK_TASK_SIZE); preferences->putInt(preference_task_size_network, NETWORK_TASK_SIZE);
preferences->putInt(preference_task_size_nuki, NUKI_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_authlog_max_entries, MAX_AUTHLOG);
preferences->putInt(preference_keypad_max_entries, MAX_KEYPAD); preferences->putInt(preference_keypad_max_entries, MAX_KEYPAD);
preferences->putInt(preference_timecontrol_max_entries, MAX_TIMECONTROL); preferences->putInt(preference_timecontrol_max_entries, MAX_TIMECONTROL);
@@ -314,11 +299,21 @@ void setup()
gpio->getConfigurationText(gpioDesc, gpio->pinConfiguration(), "\n\r"); gpio->getConfigurationText(gpioDesc, gpio->pinConfiguration(), "\n\r");
Serial.print(gpioDesc.c_str()); 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); lockEnabled = preferences->getBool(preference_lock_enabled);
openerEnabled = preferences->getBool(preference_opener_enabled); openerEnabled = preferences->getBool(preference_opener_enabled);
const String mqttLockPath = preferences->getString(preference_mqtt_lock_path); 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(); network->initialize();
networkLock = new NetworkLock(network, preferences, CharBuffer::get(), buffer_size); networkLock = new NetworkLock(network, preferences, CharBuffer::get(), buffer_size);
@@ -332,10 +327,6 @@ void setup()
initEthServer(network->networkDeviceType()); initEthServer(network->networkDeviceType());
bleScanner = new BleScanner::Scanner();
bleScanner->initialize("NukiHub");
bleScanner->setScanDuration(10);
Log->println(lockEnabled ? F("Nuki Lock enabled") : F("Nuki Lock disabled")); Log->println(lockEnabled ? F("Nuki Lock enabled") : F("Nuki Lock disabled"));
if(lockEnabled) if(lockEnabled)
{ {
@@ -356,12 +347,6 @@ void setup()
webCfgServer->initialize(); webCfgServer->initialize();
} }
if(preferences->getInt(preference_presence_detection_timeout) >= 0)
{
presenceDetection = new PresenceDetection(preferences, bleScanner, network, CharBuffer::get(), CHAR_BUFFER_SIZE);
presenceDetection->initialize();
}
setupTasks(); setupTasks();
} }