diff --git a/data/src/lib/components/AppMisc.svelte b/data/src/lib/components/AppMisc.svelte index 76740282..6a3c164d 100644 --- a/data/src/lib/components/AppMisc.svelte +++ b/data/src/lib/components/AppMisc.svelte @@ -42,6 +42,8 @@ ethSpiConfig: [20, -1, -1, -1, -1, -1, -1], controlPin: 26, hsStatusPin: 2, + doorSensorPin: 32, + doorSensorInvert: false, }, ); let ethConfig = $state( @@ -617,6 +619,51 @@ +
+ +
+ Door Sensor +
+
+
+ + + +
+
+ + +
+
+
+
diff --git a/data/src/lib/types/api.ts b/data/src/lib/types/api.ts index bd2f45f6..a0d2430a 100644 --- a/data/src/lib/types/api.ts +++ b/data/src/lib/types/api.ts @@ -99,6 +99,10 @@ export interface MiscConfig { controlPin: number; /** GPIO pin for HomeSpan status indicator */ hsStatusPin: number; + /** GPIO pin for Door Sensor */ + doorSensorPin: number; + /** Invert Door Sensor logic (true: HIGH=Closed, false: LOW=Closed) */ + doorSensorInvert: boolean; /** Enable web authentication */ webAuthEnabled: boolean; /** Web interface username */ diff --git a/dependencies.lock b/dependencies.lock index b267a5b3..7404e78e 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -455,6 +455,33 @@ dependencies: registry_url: https://components.espressif.com type: service version: 1.0.3 + espressif/lan867x: + component_hash: 651c9d6e3d96acb08bd5066144b12a12e94df0a6241127a0538d8680689de2c4 + dependencies: + - name: espressif/lan86xx_common + registry_url: https://components.espressif.com + require: private + version: '*' + - name: idf + require: private + version: '>=5.3' + source: + registry_url: https://components.espressif.com + type: service + targets: + - esp32 + - esp32p4 + version: 2.0.0 + espressif/lan86xx_common: + component_hash: 6dcb1be9f43ae940979bd628fa5bee278949b66c545e1fe2321e486102e81026 + dependencies: + - name: idf + require: private + version: '>=5.2' + source: + registry_url: https://components.espressif.com + type: service + version: 1.0.0 espressif/libsodium: component_hash: 25b968723c584a2742ca36cebe5a7ef049c6767e059f7b1e1eec69946019025d dependencies: @@ -502,7 +529,7 @@ dependencies: idf: source: type: idf - version: 5.5.2 + version: 5.5.1 joltwallet/littlefs: component_hash: 1808d73e99168f6f3c26dd31799a248484762b3a320ec4962dec11a145f4277f dependencies: @@ -523,5 +550,5 @@ direct_dependencies: - idf - joltwallet/littlefs manifest_hash: 18e3b1a1c3264b9bd52bbd0a747c6ac3228d106375dacd2e1f46a03a866a669e -target: esp32c6 +target: esp32 version: 2.0.0 diff --git a/main/ConfigManager.cpp b/main/ConfigManager.cpp index e520a5ef..41a880a5 100644 --- a/main/ConfigManager.cpp +++ b/main/ConfigManager.cpp @@ -111,6 +111,8 @@ ConfigManager::ConfigManager() : m_isInitialized(false) { {"webPassword", &m_miscConfig.webPassword}, {"nfcGpioPins", &m_miscConfig.nfcGpioPins}, {"nfcPinsPreset", &m_miscConfig.nfcPinsPreset}, + {"doorSensorPin", &m_miscConfig.doorSensorPin}, + {"doorSensorInvert", &m_miscConfig.doorSensorInvert}, {"btrLowStatusThreshold", &m_miscConfig.btrLowStatusThreshold}, {"proxBatEnabled", &m_miscConfig.proxBatEnabled}, {"ethernetEnabled", &m_miscConfig.ethernetEnabled}, @@ -195,7 +197,7 @@ bool ConfigManager::begin() { nvs_stats_t nvs_stats; nvs_get_stats(NULL, &nvs_stats); - ESP_LOGI(TAG,"Count: UsedEntries = (%lu), FreeEntries = (%lu), AvailableEntries = (%lu), AllEntries = (%lu)\n", + ESP_LOGI(TAG,"Count: UsedEntries = (%zu), FreeEntries = (%zu), AvailableEntries = (%zu), AllEntries = (%zu)\n", nvs_stats.used_entries, nvs_stats.free_entries, nvs_stats.available_entries, nvs_stats.total_entries); m_isInitialized = true; @@ -573,7 +575,7 @@ void ConfigManager::deserialize(msgpack_object obj, std::string type) { break; } default: - ESP_LOGW(TAG, "DON'T KNOW THIS ONE! - %s (%d) = %d", key.c_str(), v.val.type, v.val.via.u64); + ESP_LOGW(TAG, "DON'T KNOW THIS ONE! - %s (%d) = %llu", key.c_str(), (int)v.val.type, v.val.via.u64); } } }, m_configMap[type][key]); @@ -1078,7 +1080,7 @@ bool ConfigManager::deserializeFromJson(const std::string& json_string) { } } }, configMap.at(key)); - } else ESP_LOGW(TAG, "Key '%s' could not be found!"); + } else ESP_LOGW(TAG, "Key '%s' could not be found!", key.c_str()); item = item->next; } diff --git a/main/HKServices.cpp b/main/HKServices.cpp index af7270bd..d780f0b1 100644 --- a/main/HKServices.cpp +++ b/main/HKServices.cpp @@ -3,6 +3,7 @@ #include "HomeKitLock.hpp" #include "LockManager.hpp" #include "ReaderDataManager.hpp" +#include "HardwareManager.hpp" #include "esp_mac.h" #include "HK_HomeKit.h" @@ -96,10 +97,13 @@ HomeKitLock::LockManagementService::LockManagementService() { * @param bridge HomeKit bridge instance whose characteristic pointers will be set to the newly created characteristics. * @param lockManager Lock manager providing current and target lock state values and the HOMEKIT source identifier. */ -HomeKitLock::LockMechanismService::LockMechanismService(HomeKitLock& bridge, LockManager& lockManager) : m_lockManager(lockManager) { +HomeKitLock::LockMechanismService::LockMechanismService(HomeKitLock& bridge, LockManager& lockManager, HardwareManager& hardwareManager) : m_lockManager(lockManager), m_hardwareManager(hardwareManager) { espp::EventManager::get().add_publisher("lock/overrideState", "LockMechanismService"); espp::EventManager::get().add_publisher("lock/targetStateChanged", "LockMechanismService"); ESP_LOGI(HomeKitLock::TAG, "Configuring LockMechanism"); + + m_doorState = bridge.m_doorState = new Characteristic::CurrentDoorState(1); //default Closed + m_lockCurrentState = bridge.m_lockCurrentState = new Characteristic::LockCurrentState(m_lockManager.getCurrentState(), true); m_lockTargetState = bridge.m_lockTargetState = new Characteristic::LockTargetState(m_lockManager.getTargetState(), true); EventLockState s{ @@ -134,6 +138,15 @@ boolean HomeKitLock::LockMechanismService::update() { return true; } +void HomeKitLock::LockMechanismService::loop() { + int doorState = m_hardwareManager.checkDoorSensor(); + if (doorState != -1) { + homeSpanPAUSE(); + m_doorState->setVal(doorState); + homeSpanRESUME(); + } +} + /** * @brief Configure NFC Access service and register its characteristics and event publisher. * diff --git a/main/HardwareManager.cpp b/main/HardwareManager.cpp index eef9c64a..aeaaafc3 100644 --- a/main/HardwareManager.cpp +++ b/main/HardwareManager.cpp @@ -27,8 +27,9 @@ const std::array pixelTypeMap = { "RGB", "RBG", "BRG", "BGR", "G * @param miscConfig Configuration values controlling GPIO pins, NeoPixel type/behavior, and * timing used by the HardwareManager. */ -HardwareManager::HardwareManager(const espConfig::actions_config_t& miscConfig) - : m_miscConfig(miscConfig), +HardwareManager::HardwareManager(const espConfig::misc_config_t& sysConfig, const espConfig::actions_config_t& miscConfig) + : m_sysConfig(sysConfig), + m_miscConfig(miscConfig), m_feedbackTaskHandle(nullptr), m_feedbackQueue(nullptr), m_lockControlTaskHandle(nullptr), @@ -137,6 +138,10 @@ void HardwareManager::begin() { gpio_isr_handler_add((gpio_num_t)m_miscConfig.hkAltActionInitPin, initiator_isr_handler, (void*) this); } + if (m_sysConfig.doorSensorPin != 255) { + pinMode(m_sysConfig.doorSensorPin, INPUT_PULLUP); + } + // --- Initialize NeoPixel --- if (m_miscConfig.nfcNeopixelPin != 255) { size_t pixelTypeIndex = m_miscConfig.neoPixelType; @@ -233,6 +238,31 @@ void HardwareManager::setLockOutput(int state) { } } +/** + * @brief Checks the door sensor state with debouncing. + * @return 1 for Closed, 0 for Open, -1 for no change/invalid. + */ +int HardwareManager::checkDoorSensor() { + if (m_sysConfig.doorSensorPin == 255) return -1; + + int currentState = digitalRead(m_sysConfig.doorSensorPin); + + if (currentState != m_lastRawDoorState) { + m_lastDoorChangeTime = esp_timer_get_time() / 1000; + m_lastRawDoorState = currentState; + } + + if (((esp_timer_get_time() / 1000) - m_lastDoorChangeTime) > DEBOUNCE_DELAY) { + if (currentState != m_lastDoorState) { + m_lastDoorState = currentState; + // Apply invert logic: if inverted, swap the interpretation + bool isClosed = m_sysConfig.doorSensorInvert ? (currentState == HIGH) : (currentState == LOW); + return isClosed ? 1 : 0; + } + } + return -1; +} + /** * @brief Enqueue a success feedback event for the feedback task to process. * diff --git a/main/HomeKitLock.cpp b/main/HomeKitLock.cpp index bd3db9de..d419e139 100644 --- a/main/HomeKitLock.cpp +++ b/main/HomeKitLock.cpp @@ -30,10 +30,11 @@ static HomeKitLock* s_instance = nullptr; * @param configManager Reference to the ConfigManager used for configuration access. * @param readerDataManager Reference to the ReaderDataManager used to manage reader/issuer data. */ -HomeKitLock::HomeKitLock(std::function &conn_cb, LockManager& lockManager, ConfigManager& configManager, ReaderDataManager& readerDataManager) +HomeKitLock::HomeKitLock(std::function &conn_cb, LockManager& lockManager, ConfigManager& configManager, ReaderDataManager& readerDataManager, HardwareManager& hardwareManager) : m_lockManager(lockManager), m_configManager(configManager), m_readerDataManager(readerDataManager), + m_hardwareManager(hardwareManager), conn_cb(conn_cb) { if (s_instance != nullptr) { ESP_LOGE(TAG, "ERROR: More than one instance of HomeKitBridge created!"); @@ -228,7 +229,7 @@ void HomeKitLock::begin() { new Service::HAPProtocolInformation(); new Characteristic::Version(); new LockManagementService(); - new LockMechanismService(*this, m_lockManager); + new LockMechanismService(*this, m_lockManager, m_hardwareManager); new NFCAccessService(m_readerDataManager); if(miscConfig.proxBatEnabled) { new PhysicalLockBatteryService(*this); diff --git a/main/NfcManager.cpp b/main/NfcManager.cpp index b1016942..446d3d83 100644 --- a/main/NfcManager.cpp +++ b/main/NfcManager.cpp @@ -288,7 +288,7 @@ bool NfcManager::initializeReader() { m_nfc->stop(); return false; } - ESP_LOGI(TAG, "Found chip PN5%x, Firmware ver. %d.%d", (versiondata >> 24) & 0xFF, (versiondata >> 16) & 0xFF, (versiondata >> 8) & 0xFF); + ESP_LOGI(TAG, "Found chip PN5%x, Firmware ver. %u.%u", (unsigned int)((versiondata >> 24) & 0xFF), (unsigned int)((versiondata >> 16) & 0xFF), (unsigned int)((versiondata >> 8) & 0xFF)); m_nfc->SAMConfig(); m_nfc->setRFField(0x02, 0x01); m_nfc->setPassiveActivationRetries(0); diff --git a/main/WebServerManager.cpp b/main/WebServerManager.cpp index cd0af2fc..fe23a350 100644 --- a/main/WebServerManager.cpp +++ b/main/WebServerManager.cpp @@ -14,7 +14,6 @@ #include "esp_heap_caps.h" #include "esp_http_server.h" #include "esp_log.h" -#include "esp_log_level.h" #include "esp_task_wdt.h" #include "eth_structs.hpp" #include "eventStructs.hpp" diff --git a/main/include/HardwareManager.hpp b/main/include/HardwareManager.hpp index ad2e1c78..b40e8ac2 100644 --- a/main/include/HardwareManager.hpp +++ b/main/include/HardwareManager.hpp @@ -7,7 +7,7 @@ class ConfigManager; class Pixel; -namespace espConfig { struct actions_config_t; } +namespace espConfig { struct actions_config_t; struct misc_config_t; } /** * @class HardwareManager @@ -23,7 +23,7 @@ class HardwareManager { * @brief Constructs the HardwareManager. * @param configManager Reference to the application configuration manager. */ - HardwareManager(const espConfig::actions_config_t &); + HardwareManager(const espConfig::misc_config_t &, const espConfig::actions_config_t &); /** * @brief Initializes all hardware pins and starts background tasks for feedback. @@ -36,6 +36,12 @@ class HardwareManager { */ void setLockOutput(int state); + /** + * @brief Checks the door sensor state with debouncing. + * @return 1 for Closed, 0 for Open, -1 for no change/invalid. + */ + int checkDoorSensor(); + /** * @brief Triggers a non-blocking visual/audible signal for a successful action. */ @@ -92,10 +98,16 @@ class HardwareManager { static void handleTimer(void *instance); // --- Member Variables --- + const espConfig::misc_config_t& m_sysConfig; const espConfig::actions_config_t& m_miscConfig; Pixel* m_pixel = nullptr; + int m_lastDoorState = -1; + int m_lastRawDoorState = -1; + uint32_t m_lastDoorChangeTime = 0; + static const uint32_t DEBOUNCE_DELAY = 50; + esp_timer_handle_t m_gpioSuccessTimer; esp_timer_handle_t m_gpioFailTimer; esp_timer_handle_t m_tagEventTimer; diff --git a/main/include/HomeKitLock.hpp b/main/include/HomeKitLock.hpp index c174aebf..72679d24 100644 --- a/main/include/HomeKitLock.hpp +++ b/main/include/HomeKitLock.hpp @@ -16,11 +16,12 @@ namespace Service class LockManager; class ConfigManager; class ReaderDataManager; +class HardwareManager; namespace espConfig { struct misc_config_t; }; class HomeKitLock { public: - HomeKitLock(std::function &conn_cb, LockManager& lockManager, ConfigManager& configManager, ReaderDataManager& readerDataManager); + HomeKitLock(std::function &conn_cb, LockManager& lockManager, ConfigManager& configManager, ReaderDataManager& readerDataManager, HardwareManager& hardwareManager); void begin(); void updateLockState(int currentState, int targetState); void updateBatteryStatus(uint8_t batteryLevel, bool isLow); @@ -34,6 +35,7 @@ class HomeKitLock { LockManager& m_lockManager; ConfigManager& m_configManager; ReaderDataManager& m_readerDataManager; + HardwareManager& m_hardwareManager; std::function &conn_cb; @@ -56,10 +58,14 @@ class HomeKitLock { }; struct LockMechanismService : Service::LockMechanism { LockManager& m_lockManager; + HardwareManager& m_hardwareManager; SpanCharacteristic* m_lockTargetState; SpanCharacteristic* m_lockCurrentState; - LockMechanismService(HomeKitLock& bridge, LockManager& lockManager); + SpanCharacteristic* m_doorState; + + LockMechanismService(HomeKitLock& bridge, LockManager& lockManager, HardwareManager& hardwareManager); boolean update() override; + void loop() override; }; struct NFCAccessService : Service::NFCAccess { ReaderDataManager& m_readerDataManager; diff --git a/main/include/config.hpp b/main/include/config.hpp index 16471433..4a80da16 100644 --- a/main/include/config.hpp +++ b/main/include/config.hpp @@ -4,7 +4,7 @@ #include #include #include "defaults.h" -#include "esp_log_level.h" +#include "esp_log.h" #include "fmt/format.h" #include "esp_mac.h" @@ -126,6 +126,8 @@ namespace espConfig std::string webPassword = WEB_AUTH_PASSWORD; uint8_t nfcPinsPreset = 255; std::array nfcGpioPins{SS_PIN, SCK_PIN, MISO_PIN, MOSI_PIN}; + uint8_t doorSensorPin = 32; + bool doorSensorInvert = false; uint8_t btrLowStatusThreshold = BTR_PROX_BAT_LOW_THRESHOLD; bool proxBatEnabled = BTR_PROX_BAT_ENABLED; bool ethernetEnabled = ETH_ENABLED; @@ -133,7 +135,7 @@ namespace espConfig uint8_t ethPhyType = ETH_PHY_TYPE; std::array ethRmiiConfig = {ETH_RMII_CONF_PHY_ADDR, ETH_RMII_CONF_MDC_PIN, ETH_RMII_CONF_MDIO_PIN, ETH_RMII_CONF_POWER_PIN, ETH_RMII_CONF_RMII_CLOCK_MODE}; std::array ethSpiConfig = {ETH_SPI_CONF_SPI_FREQ_MHZ, ETH_SPI_CONF_PIN_CS, ETH_SPI_CONF_PIN_IRQ, ETH_SPI_CONF_PIN_RST, ETH_SPI_CONF_PIN_SCK, ETH_SPI_CONF_PIN_MISO, ETH_SPI_CONF_PIN_MOSI}; - uint8_t logLevel = ESP_LOG_ERROR; + uint8_t logLevel = ESP_LOG_INFO; }; struct actions_config_t { enum colorMap diff --git a/main/main.cpp b/main/main.cpp index 0621cad6..3a98c053 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1,5 +1,7 @@ #include +#include #define FMT_HEADER_ONLY + #include "config.hpp" #include "HomeKitLock.hpp" #include "LockManager.hpp" @@ -58,10 +60,10 @@ void setup() { esp_log_level_set("*", static_cast(configManager->getConfig().logLevel)); webServerManager = new WebServerManager(*configManager, *readerDataManager); distributor.add_sinker(std::make_shared(webServerManager)); - hardwareManager = new HardwareManager(configManager->getConfig()); + hardwareManager = new HardwareManager(configManager->getConfig(), configManager->getConfig()); lockManager = new LockManager(configManager->getConfig(), configManager->getConfig()); mqttManager = new MqttManager(*configManager); - homekitLock = new HomeKitLock(lambda, *lockManager, *configManager, *readerDataManager); + homekitLock = new HomeKitLock(lambda, *lockManager, *configManager, *readerDataManager, *hardwareManager); espConfig::misc_config_t miscConfig = configManager->getConfig(); static const char* TAG = "Main"; if(miscConfig.nfcPinsPreset != 255){ diff --git a/sdkconfig.defaults b/sdkconfig.defaults index c2d9443e..c27d6a20 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -91,3 +91,4 @@ CONFIG_ESP_RMAKER_FACTORY_NAMESPACE="" CONFIG_ESP_RMAKER_DEF_TIMEZONE="" CONFIG_ESP_RMAKER_SNTP_SERVER_NAME="" CONFIG_HTTPD_WS_SUPPORT=y +CONFIG_HTTPD_MAX_REQ_HDR_LEN=4096