Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions data/src/lib/components/AppMisc.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
ethSpiConfig: [20, -1, -1, -1, -1, -1, -1],
controlPin: 26,
hsStatusPin: 2,
doorSensorPin: 32,
doorSensorInvert: false,
},
);
let ethConfig = $state<EthConfig>(
Expand Down Expand Up @@ -617,6 +619,51 @@
</div>
</div>

<div class="collapse collapse-arrow bg-base-100">
<input type="checkbox" name="misc-collapse" />
<div class="collapse-title font-medium">
Door Sensor
</div>
<div class="collapse-content flex flex-col gap-4">
<div class="form-control">
<!-- svelte-ignore a11y_label_has_associated_control -->
<label class="label">
<span class="label-text"
>GPIO Pin</span
>
</label>
<input
type="number"
bind:value={miscConfig.doorSensorPin}
placeholder="32"
min="0"
max="255"
class="input input-bordered w-full"
/>
</div>
<div class="form-control">
<label class="label cursor-pointer">
<span class="label-text"
>Invert Logic (HIGH = Closed)</span
>
<input
type="checkbox"
bind:checked={
miscConfig.doorSensorInvert
}
class="toggle toggle-primary"
/>
</label>
<label class="label">
<span class="label-text-alt text-xs opacity-70">
Default: LOW = Closed, HIGH = Open<br />
When inverted: HIGH = Closed, LOW = Open
</span>
</label>
</div>
</div>
</div>

<div class="collapse collapse-arrow bg-base-100">
<input type="checkbox" name="misc-collapse" />
<div class="collapse-title font-medium">
Expand Down
4 changes: 4 additions & 0 deletions data/src/lib/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
31 changes: 29 additions & 2 deletions dependencies.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -502,7 +529,7 @@ dependencies:
idf:
source:
type: idf
version: 5.5.2
version: 5.5.1
joltwallet/littlefs:
component_hash: 1808d73e99168f6f3c26dd31799a248484762b3a320ec4962dec11a145f4277f
dependencies:
Expand All @@ -523,5 +550,5 @@ direct_dependencies:
- idf
- joltwallet/littlefs
manifest_hash: 18e3b1a1c3264b9bd52bbd0a747c6ac3228d106375dacd2e1f46a03a866a669e
target: esp32c6
target: esp32
version: 2.0.0
8 changes: 5 additions & 3 deletions main/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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]);
Expand Down Expand Up @@ -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;
}

Expand Down
15 changes: 14 additions & 1 deletion main/HKServices.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "HomeKitLock.hpp"
#include "LockManager.hpp"
#include "ReaderDataManager.hpp"
#include "HardwareManager.hpp"
#include "esp_mac.h"
#include "HK_HomeKit.h"

Expand Down Expand Up @@ -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{
Expand Down Expand Up @@ -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.
*
Expand Down
34 changes: 32 additions & 2 deletions main/HardwareManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ const std::array<const char*, 6> 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),
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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.
*
Expand Down
5 changes: 3 additions & 2 deletions main/HomeKitLock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<void(int)> &conn_cb, LockManager& lockManager, ConfigManager& configManager, ReaderDataManager& readerDataManager)
HomeKitLock::HomeKitLock(std::function<void(int)> &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!");
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion main/NfcManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion main/WebServerManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
16 changes: 14 additions & 2 deletions main/include/HardwareManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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.
*/
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 8 additions & 2 deletions main/include/HomeKitLock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<void(int)> &conn_cb, LockManager& lockManager, ConfigManager& configManager, ReaderDataManager& readerDataManager);
HomeKitLock(std::function<void(int)> &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);
Expand All @@ -34,6 +35,7 @@ class HomeKitLock {
LockManager& m_lockManager;
ConfigManager& m_configManager;
ReaderDataManager& m_readerDataManager;
HardwareManager& m_hardwareManager;

std::function<void(int)> &conn_cb;

Expand All @@ -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;
Expand Down
Loading