Browse Source

Merge branch 'dk-45' of kraxor/doorkeeper_dev into develop

Bence Balint 2 years ago
parent
commit
ba372f5962

+ 1 - 0
components/dk/CMakeLists.txt

@@ -18,6 +18,7 @@ idf_component_register(
         "src/tasks/display_manager.cpp"
         "src/tasks/event_manager.cpp"
         "src/tasks/main.cpp"
+        "src/tasks/ultrasonic.cpp"
 
         INCLUDE_DIRS
         "include"

+ 38 - 0
components/dk/include/tasks/ultrasonic.h

@@ -0,0 +1,38 @@
+#ifndef DOORKEEPER_DEV_ULTRASONIC_H
+#define DOORKEEPER_DEV_ULTRASONIC_H
+
+#include <settings_manager.h>
+
+#include <memory>
+
+#include <kbf/task.h>
+#include <kbf/rtos.h>
+
+#define READING_INTERVAL_MS 200  // TODO use Kconfig or SettingsManager
+
+/** @brief number of "closed" readings required to acknowledge closed state */
+#define CLOSED_CONFIDENCE 15  // TODO use Kconfig
+
+#define OPEN_CONFIDENCE (-3)  // TODO use Kconfig
+
+class Ultrasonic : public kbf::Task {
+public:
+    static constexpr const char *const TAG = "Ultrasonic";
+
+    Ultrasonic(const std::string &name, void *arg, uint32_t stackSize, uint32_t priority) :
+            Task(name, arg, stackSize, priority) {}
+
+    static void start();
+
+    static bool enable();
+
+    static void disable();
+
+protected:
+    [[noreturn]] void run(void *arg) override;
+
+private:
+    static std::shared_ptr<kbf::rtos::EventGroup> eventGroup;
+};
+
+#endif //DOORKEEPER_DEV_ULTRASONIC_H

+ 9 - 5
components/dk/src/api/calibrate_controller.cpp

@@ -6,6 +6,7 @@
 
 #include "settings_manager.h"
 #include "tasks/display_manager.h"
+#include "tasks/ultrasonic.h"
 
 using namespace kbf;
 using http::Request;
@@ -21,9 +22,9 @@ Response CalibrateController::get(const Request &request) {
 
 Response CalibrateController::post(const Request &request) {
     ESP_LOGD(TAG, "%s()", __func__);
-
     DisplayManager::setMessage("calibrating...");
 
+    Ultrasonic::disable();
     auto sensor = driver::Ultrasonic(5, 18); // TODO use Kconfig
 
     int  min   = 99999;
@@ -57,13 +58,16 @@ Response CalibrateController::post(const Request &request) {
         DisplayManager::setMessage("cal. error", DisplayManager::defaultTimeout);
         DisplayManager::setDoorState(DisplayManager::DoorState::NOT_CALIBRATED);
         config = {.high = 0, .low = 0};
+        SettingsManager::instance()->setCalibration(config);
     } else {
         DisplayManager::setMessage("cal: " + std::to_string(config.low) + " - " + std::to_string(config.high),
                                    DisplayManager::defaultTimeout);
+        SettingsManager::instance()->setCalibration(config);
+        Ultrasonic::enable();
     }
-    SettingsManager::instance()->setCalibration(config);
-
-    return Response({{"high", config.high},
-                     {"low",  config.low}}, error ? 500 : 200);
 
+    return Response({
+                            {"high", config.high},
+                            {"low",  config.low}
+                    }, error ? 500 : 200);
 }

+ 3 - 0
components/dk/src/dk.cpp

@@ -10,6 +10,7 @@
 #include "settings_manager.h"
 #include "tasks/display_manager.h"
 #include "tasks/event_manager.h"
+#include "tasks/ultrasonic.h"
 
 
 #define MESSAGE_TIMEOUT 1000 // TODO use Kconfig
@@ -32,11 +33,13 @@ namespace dk {
         ESP_LOGI(TAG, "%s(%s)", __func__, pairingId.c_str());
         SettingsManager::instance()->setPairingId(pairingId);
         EventManager::start();
+        Ultrasonic::enable();
         mainEventGroup->setBit(MainEvents::SET_ONLINE_MODE);
     }
 
     void clearPairing() {
         ESP_LOGI(TAG, "%s", __func__);
+        Ultrasonic::disable();
         EventManager::stop();
         SettingsManager::instance()->setPairingId("");
         wifi::stop();

+ 7 - 2
components/dk/src/tasks/boot.cpp

@@ -17,6 +17,7 @@
 #include "tasks/display_manager.h"
 #include "tasks/event_manager.h"
 #include "tasks/main.h"
+#include "tasks/ultrasonic.h"
 
 using namespace kbf;
 using namespace dk;
@@ -72,10 +73,13 @@ void Boot::run(void *arg) {
     apiService->controller<UnpairController>();
     apiService->middleware<PairingIdMiddleware>();
 
-    ESP_LOGI(TAG, "launching EventManager");
+    ESP_LOGI(TAG, "starting EventManager");
     EventManager::start();
 
-    ESP_LOGI(TAG, "launching Main");
+    ESP_LOGI(TAG, "starting Ultrasonic");
+    Ultrasonic::start();
+
+    ESP_LOGI(TAG, "starting Main");
     task::start<Main>("main", nullptr, 2 << 11);
 
     ESP_LOGI(TAG, "setting mode");
@@ -84,6 +88,7 @@ void Boot::run(void *arg) {
         DisplayManager::setMessage("connecting...");
         wifi::sta::connect(wifiConfig.ssid, wifiConfig.password);
         EventManager::event(EventManager::Event::BOOT);
+        Ultrasonic::enable();
     } else {
         mainEventGroup->setBit(MainEvents::SET_PAIRING_MODE);
     }

+ 7 - 5
components/dk/src/tasks/display_manager.cpp

@@ -28,15 +28,17 @@ shared_ptr<rtos::EventGroup> DisplayManager::eventGroup;
 shared_ptr<Task>       DisplayManager::messageTimeout;
 
 static const int     CHR_KEY          = 0;
-static const uint8_t chr_key[]        = {0x07, 0x06, 0x07, 0x04, 0x04, 0x0E, 0x0A, 0x0E};
+//static const uint8_t chr_key[]        = {0x0E, 0x0C, 0x0E, 0x08, 0x08, 0x08, 0x14, 0x08};
+static const uint8_t chr_key[]        = {0x0E, 0x0C, 0x08, 0x0E, 0x08, 0x1C, 0x14, 0x1C};
 static const int     CHR_KEY_INV      = 1;
-static const uint8_t chr_key_inv[]    = {0x18, 0x19, 0x18, 0x1B, 0x1B, 0x11, 0x15, 0x11};
+//static const uint8_t chr_key_inv[]    = {0x11, 0x13, 0x11, 0x17, 0x17, 0x17, 0x0B, 0x17};
+static const uint8_t chr_key_inv[]    = {0x10, 0x12, 0x16, 0x10, 0x16, 0x02, 0x0A, 0x02};
 static const int     CHR_WIFI         = 2;
-static const uint8_t chr_wifi[]       = {0x03, 0x04, 0x08, 0x00, 0x03, 0x04, 0x00, 0x01};
+static const uint8_t chr_wifi[]       = {0x00, 0x0E, 0x11, 0x00, 0x04, 0x0A, 0x00, 0x04};
 static const int     CHR_WIFI_INV     = 3;
-static const uint8_t chr_wifi_inv[]   = {0x1C, 0x1B, 0x17, 0x1F, 0x1C, 0x1B, 0x1F, 0x1E};
+static const uint8_t chr_wifi_inv[]   = {0x1F, 0x11, 0x0E, 0x1F, 0x1B, 0x15, 0x1F, 0x1B};
 static const int     CHR_WIFI_SMALL   = 4;
-static const uint8_t chr_wifi_small[] = {0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x00, 0x01};
+static const uint8_t chr_wifi_small[] = {0x00, 0x00, 0x00, 0x00, 0x04, 0x0A, 0x00, 0x04};
 
 DisplayManager::DisplayManager(const std::string &name, void *arg, uint32_t stackSize, uint32_t priority) :
         Task(name, arg, stackSize, priority) {

+ 14 - 0
components/dk/src/tasks/event_manager.cpp

@@ -9,6 +9,7 @@
 
 #include "dk.h"
 #include "settings_manager.h"
+#include "tasks/display_manager.h"
 
 using namespace kbf;
 using std::nullopt;
@@ -43,6 +44,19 @@ static shared_ptr<Task> instance;
 bool EventManager::event(EventManager::Event event) {
     ESP_LOGI(TAG, "%s(%d); queue size = %d", __func__, (int) event, eventQueue.size());
 
+    switch (event) {
+       case Event::DOOR_OPEN:
+            DisplayManager::setDoorState(DisplayManager::DoorState::OPEN);
+            break;
+        case Event::DOOR_CLOSED:
+            DisplayManager::setDoorState(DisplayManager::DoorState::CLOSED);
+            break;
+        case Event::BOOT:
+            break;
+        case Event::NOOP:
+            break;
+    }
+
     auto result = eventQueue.push(event);
     if (!result) ESP_LOGW(TAG, "%s: event queue is full", __func__);
 

+ 109 - 0
components/dk/src/tasks/ultrasonic.cpp

@@ -0,0 +1,109 @@
+#include "tasks/ultrasonic.h"
+
+#include <atomic>
+
+#include <esp_log.h>
+
+#include <kbf.h>
+#include <kbf/driver/ultrasonic.h>
+
+#include "settings_manager.h"
+#include "tasks/event_manager.h"
+
+using namespace kbf;
+using std::shared_ptr;
+using std::make_shared;
+using std::atomic;
+
+static const int BIT_ENABLED = 0;
+
+shared_ptr <rtos::EventGroup> Ultrasonic::eventGroup;
+
+atomic<int>  low{0};
+atomic<int>  high{0};
+atomic<bool> doorOpen{false};
+static int   confidence;
+
+inline bool isOpen(uint32_t reading) { return reading < low || reading > high; }
+
+[[noreturn]] void Ultrasonic::run(void *arg) {
+    eventGroup = make_shared<rtos::EventGroup>();
+    auto sensor = driver::Ultrasonic(5, 18);  // TODO use Kconfig
+
+    confidence = 0;
+    bool first = true;
+
+    while (true) {
+        eventGroup->waitForBit(BIT_ENABLED);
+
+        auto reading = sensor.read();
+        ESP_LOGV(TAG, "reading: %d; h/l: %d/%d", reading, high.load(), low.load());
+
+        if (first) {
+            /** trigger confidence check on first run */
+            doorOpen = isOpen(reading) ? false : true;
+            first = false;
+        }
+
+        if (isOpen(reading)) {
+            if (confidence > 0) confidence = 0;
+            if (!doorOpen) {
+                ESP_LOGI(TAG, "open confidence %d/%d", confidence - 1, OPEN_CONFIDENCE);
+                if (--confidence == OPEN_CONFIDENCE) {
+                    doorOpen = true;
+                    EventManager::event(EventManager::Event::DOOR_OPEN);
+                }
+            }
+        } else {
+            if (confidence < 0) confidence = 0;
+            if (doorOpen) {
+                ESP_LOGI(TAG, "closed confidence %d/%d", confidence + 1, CLOSED_CONFIDENCE);
+                if (++confidence == CLOSED_CONFIDENCE) {
+                    doorOpen = false;
+                    EventManager::event(EventManager::Event::DOOR_CLOSED);
+                }
+            }
+        }
+
+        kbf::sleep(READING_INTERVAL_MS);
+    }
+}
+
+void Ultrasonic::start() {
+    ESP_LOGI(TAG, "%s", __func__);
+    task::start<Ultrasonic>("ultrasonic");
+}
+
+bool Ultrasonic::enable() {
+    ESP_LOGI(TAG, "%s", __func__);
+
+    static auto sm = SettingsManager::instance();
+
+    auto calibration = sm->calibration();
+    if (!calibration.low || !calibration.high) {
+        ESP_LOGW(TAG, "not calibrated");
+        return false;
+    }
+
+    if (sm->pairingId().empty()) {
+        ESP_LOGW(TAG, "not paired");
+        return false;
+    }
+
+    low  = calibration.low;
+    high = calibration.high;
+    eventGroup->setBit(BIT_ENABLED);
+
+    return true;
+}
+
+void Ultrasonic::disable() {
+    ESP_LOGI(TAG, "%s", __func__);
+
+    if (!eventGroup->getBit(BIT_ENABLED)) {
+        ESP_LOGW(TAG, "already disabled");
+        return;
+    }
+
+    eventGroup->clearBit(BIT_ENABLED);
+}