diff --git a/conf/conf.hpp b/conf/conf.hpp index 126da633..c148c526 100644 --- a/conf/conf.hpp +++ b/conf/conf.hpp @@ -70,6 +70,9 @@ namespace fabomatic /// @brief Minimum time to confirm by long tap maintenance static constexpr auto LONG_TAP_DURATION{10s}; + /// @brief Disabled RFID reading after a successfull read for X seconds. + static constexpr auto DELAY_BETWEEN_SWEEPS{2s}; + } // namespace conf::machine /// @brief Debug settings diff --git a/include/BaseRfidWrapper.hpp b/include/BaseRfidWrapper.hpp index 296d40df..98788b86 100644 --- a/include/BaseRfidWrapper.hpp +++ b/include/BaseRfidWrapper.hpp @@ -3,6 +3,7 @@ #include #include "card.hpp" +#include "Tasks.hpp" namespace fabomatic { @@ -21,6 +22,8 @@ namespace fabomatic virtual auto readCardSerial() const -> std::optional = 0; virtual auto selfTest() const -> bool = 0; virtual auto reset() const -> void = 0; + + virtual auto setDisabledUntil(std::optional t) -> void = 0; }; } // namespace fabomatic #endif // BASERFIDWRAPPER_HPP_ \ No newline at end of file diff --git a/include/BoardLogic.hpp b/include/BoardLogic.hpp index c7043411..38a7f387 100644 --- a/include/BoardLogic.hpp +++ b/include/BoardLogic.hpp @@ -95,7 +95,6 @@ namespace fabomatic FabBackend server; std::optional> rfid{std::nullopt}; // Configured at runtime std::optional> lcd{std::nullopt}; // Configured at runtime - bool ready_for_a_new_card{true}; bool led_status{false}; Machine machine; diff --git a/include/RFIDWrapper.hpp b/include/RFIDWrapper.hpp index 58343825..980dd718 100644 --- a/include/RFIDWrapper.hpp +++ b/include/RFIDWrapper.hpp @@ -19,6 +19,7 @@ namespace fabomatic { private: std::unique_ptr driver; + std::optional disabledUntil; public: RFIDWrapper(); @@ -46,6 +47,8 @@ namespace fabomatic [[nodiscard]] auto getUid() const -> card::uid_t override; + [[nodiscard]] auto setDisabledUntil(std::optional delay) -> void override; + /// @brief Returns the driver object for testing/simulation Driver &getDriver(); @@ -53,7 +56,7 @@ namespace fabomatic RFIDWrapper &operator=(const RFIDWrapper &x) = delete; // copy assignment RFIDWrapper(RFIDWrapper &&) = delete; // move constructor RFIDWrapper &operator=(RFIDWrapper &&) = delete; // move assignment - ~RFIDWrapper() override{}; // Default destructor + ~RFIDWrapper() override {}; // Default destructor }; } // namespace fabomatic diff --git a/platformio.ini b/platformio.ini index 981b17e9..ede3f3d7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -68,7 +68,6 @@ board_build.f_flash = 80000000L build_flags = ${env.build_flags} -D ARDUINO_USB_CDC_ON_BOOT build_src_flags = ${env.build_src_flags} - -D CORE_DEBUG_LEVEL=5 -D MQTT_SIMULATION=false -D RFID_SIMULATION=false -D PINS_HARDWARE_REV0 diff --git a/src/BoardLogic.cpp b/src/BoardLogic.cpp index a81a423c..3aa6b47d 100644 --- a/src/BoardLogic.cpp +++ b/src/BoardLogic.cpp @@ -75,12 +75,6 @@ namespace fabomatic { ESP_LOGD(TAG, "New card present"); - if (!ready_for_a_new_card) - { - return; - } - ready_for_a_new_card = false; - if (machine.isFree()) { // machine is free @@ -556,13 +550,13 @@ namespace fabomatic const auto &result = rfid.readCardSerial(); if (result) { + // This function may block for several seconds if a long tap is required onNewCard(result.value()); + rfid.setDisabledUntil(Tasks::arduinoNow() + conf::machine::DELAY_BETWEEN_SWEEPS); } return; } - // No new card present - ready_for_a_new_card = true; if (machine.isFree()) { changeStatus(Status::MachineFree); diff --git a/src/RFIDWrapper.tpp b/src/RFIDWrapper.tpp index 0ecbccc7..0966f210 100644 --- a/src/RFIDWrapper.tpp +++ b/src/RFIDWrapper.tpp @@ -12,7 +12,7 @@ namespace fabomatic { /// @brief Constructor template - RFIDWrapper::RFIDWrapper() : driver{std::make_unique()} {}; + RFIDWrapper::RFIDWrapper() : driver{std::make_unique()}, disabledUntil{std::nullopt} {}; /// @brief indicates if a new card is present in the RFID chip antenna area /// @return true if a new card is present @@ -24,15 +24,34 @@ namespace fabomatic if (conf::debug::ENABLE_LOGS && result) ESP_LOGD(TAG, "isNewCardPresent=%d", result); + if (disabledUntil && disabledUntil > fabomatic::Tasks::arduinoNow()) + { + ESP_LOGD(TAG, "isNewCardPresent is disabled"); + return false; + } + return result; } + template + [[nodiscard]] auto RFIDWrapper::setDisabledUntil(std::optional delay) -> void + { + this->disabledUntil = delay; + } + /// @brief tries to read the card serial number /// @return true if successfull, result can be read with getUid() template auto RFIDWrapper::readCardSerial() const -> std::optional { const auto &result = driver->PICC_ReadCardSerial(); + + if (disabledUntil && disabledUntil > fabomatic::Tasks::arduinoNow()) + { + ESP_LOGD(TAG, "readCardSerial is disabled"); + return std::nullopt; + } + if (result) { return getUid(); diff --git a/test/test_logic/test_common.cpp b/test/test_logic/test_common.cpp index f613ed76..e1b7a03a 100644 --- a/test/test_logic/test_common.cpp +++ b/test/test_logic/test_common.cpp @@ -21,24 +21,29 @@ namespace fabomatic::tests std::optional duration_tap) { constexpr auto DEFAULT_CYCLES = 3; + MockMrfc522 &driver = rfid.getDriver(); + driver.resetUid(); + rfid.setDisabledUntil(std::nullopt); + for (auto i = 0; i < DEFAULT_CYCLES; i++) { logic.checkRfid(); + rfid.setDisabledUntil(std::nullopt); } + if (uid.has_value()) { driver.setUid(uid.value(), duration_tap); TEST_ASSERT_TRUE_MESSAGE(uid == rfid.getUid(), "Card UID not equal"); auto start = fabomatic::Tasks::arduinoNow(); - do { logic.checkRfid(); + rfid.setDisabledUntil(std::nullopt); delay(50); } while (duration_tap.has_value() && fabomatic::Tasks::arduinoNow() - start < duration_tap); - } else if (duration_tap) { diff --git a/test/test_logic/test_logic.cpp b/test/test_logic/test_logic.cpp index 94d28b18..2f64bf12 100644 --- a/test/test_logic/test_logic.cpp +++ b/test/test_logic/test_logic.cpp @@ -141,6 +141,8 @@ namespace fabomatic::tests const auto card_uid = get_test_uid(1); simulate_rfid_card(rfid, logic, card_uid, std::nullopt); + + Tasks::delay(fabomatic::conf::machine::DELAY_BETWEEN_SWEEPS); TEST_ASSERT_TRUE_MESSAGE(rfid.isNewCardPresent(), "New card not present"); TEST_ASSERT_TRUE_MESSAGE(rfid.readCardSerial().has_value(), "Card serial not read"); TEST_ASSERT_TRUE_MESSAGE(rfid.readCardSerial().value() == card_uid, "Card serial not equal"); @@ -271,8 +273,8 @@ namespace fabomatic::tests TEST_ASSERT_EQUAL_UINT16_MESSAGE(BoardLogic::Status::MaintenanceNeeded, logic.getStatus(), "Status not MaintenanceNeeded"); simulate_rfid_card(rfid, logic, std::nullopt); - simulate_rfid_card(rfid, logic, card_admin, conf::machine::LONG_TAP_DURATION + 10s); // Log in + Conferma manutenzione perché non ritorna prima della conclusione - simulate_rfid_card(rfid, logic, std::nullopt); // Card away + simulate_rfid_card(rfid, logic, card_admin, conf::machine::LONG_TAP_DURATION + 3s); // Log in + Conferma manutenzione perché non ritorna prima della conclusione + simulate_rfid_card(rfid, logic, std::nullopt); // Card away TEST_ASSERT_EQUAL_UINT16_MESSAGE(BoardLogic::Status::MachineInUse, logic.getStatus(), "Status not MachineInUse by admin"); TEST_ASSERT_FALSE_MESSAGE(logic.getMachine().isMaintenanceNeeded(), "Maintenance not cleared by admin"); @@ -355,7 +357,7 @@ void setup() { delay(1000); esp_log_level_set(TAG, LOG_LOCAL_LEVEL); - + auto config = fabomatic::SavedConfig::LoadFromEEPROM(); UNITY_BEGIN(); RUN_TEST(fabomatic::tests::test_machine_defaults);