diff --git a/MqttTopics.h b/MqttTopics.h index 7eac839..c608d7d 100644 --- a/MqttTopics.h +++ b/MqttTopics.h @@ -13,3 +13,5 @@ #define mqtt_topic_lockstate_completionStatus "/lock/completionStatus" #define mqtt_topic_door_sensor_state "/lock/doorSensorState" #define mqtt_topic_lockstate_action "/lock/action" + +#define mqtt_topic_presence "/presence/devices" diff --git a/Network.cpp b/Network.cpp index 5f34fac..ef3db91 100644 --- a/Network.cpp +++ b/Network.cpp @@ -148,6 +148,12 @@ void Network::update() } } + if(_presenceCsv != nullptr) + { + publishString(mqtt_topic_presence, _presenceCsv); + _presenceCsv = nullptr; + } + _mqttClient.loop(); vTaskDelay( 100 / portTICK_PERIOD_MS); @@ -240,6 +246,11 @@ void Network::publishBatteryReport(const Nuki::BatteryReport& batteryReport) publishInt(mqtt_topic_battery_lock_distance, batteryReport.lockDistance); // degrees } +void Network::publishPresenceDetection(char *csv) +{ + _presenceCsv = csv; +} + void Network::setLockActionReceived(void (*lockActionReceivedCallback)(const char *)) { _lockActionReceivedCallback = lockActionReceivedCallback; diff --git a/Network.h b/Network.h index a4040b2..abecfdb 100644 --- a/Network.h +++ b/Network.h @@ -18,6 +18,7 @@ public: void publishKeyTurnerState(const Nuki::KeyTurnerState& keyTurnerState, const Nuki::KeyTurnerState& lastKeyTurnerState); void publishBatteryReport(const Nuki::BatteryReport& batteryReport); + void publishPresenceDetection(char* csv); void setLockActionReceived(void (*lockActionReceivedCallback)(const char* value)); @@ -46,6 +47,8 @@ private: char _mqttUser[31] = {0}; char _mqttPass[31] = {0}; + char* _presenceCsv = nullptr; + bool _firstTunerStatePublish = true; void (*_lockActionReceivedCallback)(const char* value) = NULL; diff --git a/PresenceDetection.cpp b/PresenceDetection.cpp index 74716dc..703dc19 100644 --- a/PresenceDetection.cpp +++ b/PresenceDetection.cpp @@ -1,13 +1,21 @@ #include "PresenceDetection.h" -PresenceDetection::PresenceDetection(BleScanner *bleScanner) -: _bleScanner(bleScanner) -{} +PresenceDetection::PresenceDetection(BleScanner *bleScanner, Network* network) +: _bleScanner(bleScanner), + _network(network) +{ + _csv = new char[presence_detection_buffer_size]; +} PresenceDetection::~PresenceDetection() { _bleScanner->unsubscribe(this); _bleScanner = nullptr; + + _network = nullptr; + + delete _csv; + _csv = nullptr; } void PresenceDetection::initialize() @@ -17,23 +25,58 @@ void PresenceDetection::initialize() void PresenceDetection::update() { - vTaskDelay( 10000 / portTICK_PERIOD_MS); + vTaskDelay( 5000 / portTICK_PERIOD_MS); + if(_devices.size() == 0) return; + + memset(_csv, 0, presence_detection_buffer_size); + _csvIndex = 0; long ts = millis(); for(auto it : _devices) { if(ts - 20000 < it.second.timestamp) { - // TODO: publish to mqtt + buildCsv(it.second); + } + + // Prevent csv buffer overflow + if(_csvIndex > presence_detection_buffer_size - (sizeof(it.second.name) + sizeof(it.second.address) + 3)) + { + break; } } + + _network->publishPresenceDetection(_csv); } + +void PresenceDetection::buildCsv(const PdDevice &device) +{ + for(int i = 0; i < 17; i++) + { + _csv[_csvIndex] = device.address[i]; + ++_csvIndex; + } + _csv[_csvIndex] = ';'; + ++_csvIndex; + + int i=0; + while(device.name[i] != 0x00 && i < 30) + { + _csv[_csvIndex] = device.name[i]; + ++_csvIndex; + ++i; + } + _csv[_csvIndex] = '\n'; + _csvIndex++; +} + + 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); @@ -91,4 +134,4 @@ void PresenceDetection::onResult(NimBLEAdvertisedDevice *device) // } // Serial.println(); -} +} \ No newline at end of file diff --git a/PresenceDetection.h b/PresenceDetection.h index e2dc089..a7a1b6c 100644 --- a/PresenceDetection.h +++ b/PresenceDetection.h @@ -2,6 +2,7 @@ #include "BleScanner.h" #include "BleInterfaces.h" +#include "Network.h" struct PdDevice { @@ -10,10 +11,12 @@ struct PdDevice unsigned long timestamp; }; +#define presence_detection_buffer_size 4096 + class PresenceDetection : public BLEScannerSubscriber { public: - PresenceDetection(BleScanner* bleScanner); + PresenceDetection(BleScanner* bleScanner, Network* network); virtual ~PresenceDetection(); void initialize(); @@ -22,7 +25,14 @@ public: void onResult(NimBLEAdvertisedDevice* advertisedDevice) override; private: + void buildCsv(const PdDevice& device); + BleScanner* _bleScanner; + Network* _network; + char* _csv = {0}; std::map _devices; uint _timeout = 20000; + int _csvIndex = 0; + + }; diff --git a/main.cpp b/main.cpp index 223bc46..de79591 100644 --- a/main.cpp +++ b/main.cpp @@ -41,7 +41,7 @@ void presenceDetectionTask(void *pvParameters) void setupTasks() { - xTaskCreate(networkTask, "ntw", 16384, NULL, 1, NULL); + xTaskCreate(networkTask, "ntw", 32768, NULL, 1, NULL); xTaskCreate(nukiTask, "nuki", 8192, NULL, 1, NULL); xTaskCreate(presenceDetectionTask, "prdet", 1024, NULL, 1, NULL); } @@ -79,7 +79,7 @@ void setup() webCfgServer->initialize(); nuki->initialize(); - presenceDetection = new PresenceDetection(nuki->bleScanner()); + presenceDetection = new PresenceDetection(nuki->bleScanner(), network); presenceDetection->initialize(); setupTasks();