diff --git a/lib/BleFingerprint/BleFingerprint.cpp b/lib/BleFingerprint/BleFingerprint.cpp index 390ea46..a67626e 100644 --- a/lib/BleFingerprint/BleFingerprint.cpp +++ b/lib/BleFingerprint/BleFingerprint.cpp @@ -196,7 +196,7 @@ float BleFingerprint::getDistance() return output.value.position; } -bool BleFingerprint::report(JsonDocument *doc) +bool BleFingerprint::report(JsonDocument *doc, int maxDistance) { if (id == nullptr && name == nullptr) return false; @@ -204,6 +204,9 @@ bool BleFingerprint::report(JsonDocument *doc) if (!hasValue) return false; + if (maxDistance > 0 && output.value.position > maxDistance) + return false; + String mac = SMacf(address); if (output.value.position < 0.5) { diff --git a/lib/BleFingerprint/BleFingerprint.h b/lib/BleFingerprint/BleFingerprint.h index 4c67abf..17c4476 100644 --- a/lib/BleFingerprint/BleFingerprint.h +++ b/lib/BleFingerprint/BleFingerprint.h @@ -17,7 +17,7 @@ public: ~BleFingerprint(); void seen(BLEAdvertisedDevice *advertisedDevice); - bool report(JsonDocument *doc); + bool report(JsonDocument *doc, int maxDistance); String getId() { return id; } diff --git a/src/Settings.h b/src/Settings.h index 975f1fa..5df9e31 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -72,8 +72,8 @@ // Define bluetooth scan parameters #define BLE_ACTIVE_SCAN false // Active scan uses more power, but get results faster -#define BLE_SCAN_INTERVAL 150 // Used to determine antenna sharing between Bluetooth and WiFi. Do not modify unless you are confident you know what you're doing -#define BLE_SCAN_WINDOW 150 // Used to determine antenna sharing between Bluetooth and WiFi. Do not modify unless you are confident you know what you're doing +#define BLE_SCAN_INTERVAL 40 // Used to determine antenna sharing between Bluetooth and WiFi. Do not modify unless you are confident you know what you're doing +#define BLE_SCAN_WINDOW 30 // Used to determine antenna sharing between Bluetooth and WiFi. Do not modify unless you are confident you know what you're doing // Maximum distance (in meters) to report. Devices that are calculated to be further than this distance in meters will not be reported #define MAX_DISTANCE 16 diff --git a/src/main.cpp b/src/main.cpp index f339160..6988f93 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ #include -BleFingerprint *getFingerprint(BLEAdvertisedDevice *advertisedDevice) +BleFingerprint *getFingerprintInternal(BLEAdvertisedDevice *advertisedDevice) { auto mac = advertisedDevice->getAddress(); @@ -28,6 +28,16 @@ BleFingerprint *getFingerprint(BLEAdvertisedDevice *advertisedDevice) 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) { StaticJsonDocument<512> tele; @@ -48,6 +58,8 @@ bool sendTelemetry(int totalSeen = -1, int totalReported = -1, int totalAdverts tele["adverts"] = totalAdverts; if (sendFailures > 0) tele["sendFails"] = sendFailures; + if (reconnectAttempts > 0) + tele["reconnectAttempts"] = reconnectAttempts; tele["resetCore0"] = resetReason(rtc_get_reset_reason(0)); tele["resetCore1"] = resetReason(rtc_get_reset_reason(1)); @@ -60,16 +72,16 @@ bool sendTelemetry(int totalSeen = -1, int totalReported = -1, int totalAdverts char teleMessageBuffer[512]; serializeJson(tele, teleMessageBuffer); - if (mqttClient.publish((TELEMETRY_TOPIC).c_str(), 0, 0, teleMessageBuffer) == true) + for (int i = 0; i < 10; i++) { - return true; - } - else - { - sendFailures++; - log_e("Error sending telemetry"); - return false; + if (mqttClient.publish((TELEMETRY_TOPIC).c_str(), 0, 0, teleMessageBuffer) == true) + return true; + delay(20); } + + sendFailures++; + log_e("Error sending telemetry"); + return false; } void connectToWifi() @@ -121,7 +133,7 @@ void connectToWifi() void onMqttConnect(bool sessionPresent) { Serial.println("Connected to MQTT"); - retryAttempts = 0; + reconnectAttempts = 0; if (mqttClient.publish(availabilityTopic.c_str(), 0, 1, "CONNECTED") == true) { @@ -149,15 +161,12 @@ void reconnect(TimerHandle_t xTimer) if (WiFi.isConnected() && mqttClient.connected()) return; - if (retryAttempts > 10) + if (reconnectAttempts++ > 10) { - log_e("Too many retries. Restarting"); + log_e("Too many reconnect attempts; Restarting"); ESP.restart(); } - else - { - retryAttempts++; - } + if (!WiFi.isConnected()) if (!WiFiSettings.connect(true, 60)) ESP.restart(); @@ -190,6 +199,8 @@ private: void onResult(BLEAdvertisedDevice *advertisedDevice) { + if (updateInProgress) + return; totalSeen++; digitalWrite(LED_BUILTIN, LED_BUILTIN_ON); BleFingerprint *f = getFingerprint(advertisedDevice); @@ -202,48 +213,38 @@ private: bool reportDevice(BleFingerprint *f) { StaticJsonDocument<512> doc; - - if (!f->report(&doc)) + if (!f->report(&doc, MAX_DISTANCE)) return false; char JSONmessageBuffer[512]; serializeJson(doc, JSONmessageBuffer); - String id = doc["id"]; - String publishTopic = CHANNEL + "/" + room; - String publishTopic2 = CHANNEL + "/" + room + "/" + id; - if (mqttClient.connected()) + String publishTopic = CHANNEL + "/" + room; + String publishTopic2 = CHANNEL + "/" + room + "/" + f->getId(); + + bool p1 = false, p2 = false; + for (int i = 0; i < 10; i++) { - if (MAX_DISTANCE == 0 || doc["distance"] < MAX_DISTANCE) - { - if (mqttClient.publish((char *)publishTopic.c_str(), 0, 0, JSONmessageBuffer) && mqttClient.publish((char *)publishTopic2.c_str(), 0, 0, JSONmessageBuffer)) - { -#if VERBOSE -// Serial.println(JSONmessageBuffer); -#endif - return true; - } - else - { - sendFailures++; - Serial.print("Error sending message: "); - Serial.println(publishTopic); - Serial.print("Message: "); - Serial.println(JSONmessageBuffer); - return false; - } - } - else - { - //Serial.printf("%s exceeded distance threshold %.2f\n\r", mac_address.c_str(), distance); + if (!mqttClient.connected()) return false; - } + + if (!p1 && mqttClient.publish((char *)publishTopic.c_str(), 0, 0, JSONmessageBuffer)) + p1 = true; + + if (!p2 && mqttClient.publish((char *)publishTopic2.c_str(), 0, 0, JSONmessageBuffer)) + p2 = true; + + if (p1 && p2) + return true; + delay(20); } + sendFailures++; return false; } void scanForDevices(void *parameter) { + fingerprintSemaphore = xSemaphoreCreateBinary(); auto scan = MyAdvertisedDeviceCallbacks(); BLEDevice::init(""); auto pBLEScan = BLEDevice::getScan(); diff --git a/src/main.h b/src/main.h index 4012905..807acb3 100644 --- a/src/main.h +++ b/src/main.h @@ -49,7 +49,7 @@ TaskHandle_t scannerTask; bool updateInProgress = false; String localIp; -int retryAttempts = 0; +int reconnectAttempts = 0; int sendFailures = 0; String mqttHost; @@ -59,6 +59,7 @@ String mqttPass; String availabilityTopic; String room; +static SemaphoreHandle_t fingerprintSemaphore; static std::list fingerprints; String resetReason(RESET_REASON reason) @@ -152,7 +153,7 @@ void configureOTA() Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); - ESP.restart(); + updateInProgress = false; }); ArduinoOTA.setHostname(WiFi.getHostname()); ArduinoOTA.setPort(3232);