add opener gpio control
This commit is contained in:
65
Gpio.cpp
65
Gpio.cpp
@@ -43,6 +43,22 @@ void Gpio::init()
|
||||
pinMode(entry.pin, INPUT_PULLUP);
|
||||
attachInterrupt(entry.pin, isrUnlatch, FALLING);
|
||||
break;
|
||||
case PinRole::InputElectricStrikeActuation:
|
||||
pinMode(entry.pin, INPUT_PULLUP);
|
||||
attachInterrupt(entry.pin, isrElectricStrikeActuation, FALLING);
|
||||
break;
|
||||
case PinRole::InputActivateRTO:
|
||||
pinMode(entry.pin, INPUT_PULLUP);
|
||||
attachInterrupt(entry.pin, isrActivateRTO, FALLING);
|
||||
break;
|
||||
case PinRole::InputActivateCM:
|
||||
pinMode(entry.pin, INPUT_PULLUP);
|
||||
attachInterrupt(entry.pin, isrActivateCM, FALLING);
|
||||
break;
|
||||
case PinRole::InputDeactivateRtoCm:
|
||||
pinMode(entry.pin, INPUT_PULLUP);
|
||||
attachInterrupt(entry.pin, isrDeactivateRtoCm, FALLING);
|
||||
break;
|
||||
default:
|
||||
pinMode(entry.pin, OUTPUT);
|
||||
break;
|
||||
@@ -115,19 +131,6 @@ const std::vector<PinEntry> &Gpio::pinConfiguration() const
|
||||
return _pinConfiguration;
|
||||
}
|
||||
|
||||
PinRole Gpio::getPinRole(uint8_t pin)
|
||||
{
|
||||
for(const auto& entry : _pinConfiguration)
|
||||
{
|
||||
if(entry.pin == pin)
|
||||
{
|
||||
return entry.role;
|
||||
}
|
||||
}
|
||||
|
||||
return PinRole::Disabled;
|
||||
}
|
||||
|
||||
String Gpio::getRoleDescription(PinRole role) const
|
||||
{
|
||||
switch(role)
|
||||
@@ -140,6 +143,14 @@ String Gpio::getRoleDescription(PinRole role) const
|
||||
return "Input: Unlock";
|
||||
case PinRole::InputUnlatch:
|
||||
return "Input: Unlatch";
|
||||
case PinRole::InputElectricStrikeActuation:
|
||||
return "Input: Electric strike actuation";
|
||||
case PinRole::InputActivateRTO:
|
||||
return "Input: Activate RTO";
|
||||
case PinRole::InputActivateCM:
|
||||
return "Input: Activate CM";
|
||||
case PinRole::InputDeactivateRtoCm:
|
||||
return "Input: Deactivate RTO/CM";
|
||||
case PinRole::OutputHighLocked:
|
||||
return "Output: High when locked";
|
||||
case PinRole::OutputHighUnlocked:
|
||||
@@ -211,6 +222,34 @@ void Gpio::isrUnlatch()
|
||||
_debounceTs = millis() + _debounceTime;
|
||||
}
|
||||
|
||||
void Gpio::isrElectricStrikeActuation()
|
||||
{
|
||||
if(millis() < _debounceTs) return;
|
||||
_inst->notify(GpioAction::ElectricStrikeActuation);
|
||||
_debounceTs = millis() + _debounceTime;
|
||||
}
|
||||
|
||||
void Gpio::isrActivateRTO()
|
||||
{
|
||||
if(millis() < _debounceTs) return;
|
||||
_inst->notify(GpioAction::ActivateRTO);
|
||||
_debounceTs = millis() + _debounceTime;
|
||||
}
|
||||
|
||||
void Gpio::isrActivateCM()
|
||||
{
|
||||
if(millis() < _debounceTs) return;
|
||||
_inst->notify(GpioAction::ActivateCM);
|
||||
_debounceTs = millis() + _debounceTime;
|
||||
}
|
||||
|
||||
void Gpio::isrDeactivateRtoCm()
|
||||
{
|
||||
if(millis() < _debounceTs) return;
|
||||
_inst->notify(GpioAction::DeactivateRtoCm);
|
||||
_debounceTs = millis() + _debounceTime;
|
||||
}
|
||||
|
||||
void Gpio::setPinOutput(const uint8_t& pin, const uint8_t& state)
|
||||
{
|
||||
digitalWrite(pin, state);
|
||||
|
||||
19
Gpio.h
19
Gpio.h
@@ -10,6 +10,10 @@ enum class PinRole
|
||||
InputLock,
|
||||
InputUnlock,
|
||||
InputUnlatch,
|
||||
InputElectricStrikeActuation,
|
||||
InputActivateRTO,
|
||||
InputActivateCM,
|
||||
InputDeactivateRtoCm,
|
||||
OutputHighLocked,
|
||||
OutputHighUnlocked,
|
||||
OutputHighMotorBlocked,
|
||||
@@ -19,7 +23,11 @@ enum class GpioAction
|
||||
{
|
||||
Lock,
|
||||
Unlock,
|
||||
Unlatch
|
||||
Unlatch,
|
||||
ElectricStrikeActuation,
|
||||
ActivateRTO,
|
||||
ActivateCM,
|
||||
DeactivateRtoCm
|
||||
};
|
||||
|
||||
struct PinEntry
|
||||
@@ -42,7 +50,6 @@ public:
|
||||
const std::vector<uint8_t>& availablePins() const;
|
||||
const std::vector<PinEntry>& pinConfiguration() const;
|
||||
|
||||
PinRole getPinRole(uint8_t pin);
|
||||
String getRoleDescription(PinRole role) const;
|
||||
void getConfigurationText(String& text, const std::vector<PinEntry>& pinConfiguration) const;
|
||||
|
||||
@@ -60,6 +67,10 @@ private:
|
||||
PinRole::InputLock,
|
||||
PinRole::InputUnlock,
|
||||
PinRole::InputUnlatch,
|
||||
PinRole::InputElectricStrikeActuation,
|
||||
PinRole::InputActivateRTO,
|
||||
PinRole::InputActivateCM,
|
||||
PinRole::InputDeactivateRtoCm,
|
||||
PinRole::OutputHighLocked,
|
||||
PinRole::OutputHighUnlocked
|
||||
};
|
||||
@@ -70,6 +81,10 @@ private:
|
||||
static void IRAM_ATTR isrLock();
|
||||
static void IRAM_ATTR isrUnlock();
|
||||
static void IRAM_ATTR isrUnlatch();
|
||||
static void IRAM_ATTR isrElectricStrikeActuation();
|
||||
static void IRAM_ATTR isrActivateRTO();
|
||||
static void IRAM_ATTR isrActivateCM();
|
||||
static void IRAM_ATTR isrDeactivateRtoCm();
|
||||
|
||||
std::vector<std::function<void(const GpioAction&)>> _callbacks;
|
||||
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
|
||||
NukiOpenerWrapper* nukiOpenerInst;
|
||||
|
||||
NukiOpenerWrapper::NukiOpenerWrapper(const std::string& deviceName, uint32_t id, BleScanner::Scanner* scanner, NetworkOpener* network, Preferences* preferences)
|
||||
NukiOpenerWrapper::NukiOpenerWrapper(const std::string& deviceName, uint32_t id, BleScanner::Scanner* scanner, NetworkOpener* network, Gpio* gpio, Preferences* preferences)
|
||||
: _deviceName(deviceName),
|
||||
_nukiOpener(deviceName, id),
|
||||
_bleScanner(scanner),
|
||||
_network(network),
|
||||
_gpio(gpio),
|
||||
_preferences(preferences)
|
||||
{
|
||||
nukiOpenerInst = this;
|
||||
@@ -26,6 +27,8 @@ NukiOpenerWrapper::NukiOpenerWrapper(const std::string& deviceName, uint32_t id,
|
||||
network->setLockActionReceivedCallback(nukiOpenerInst->onLockActionReceivedCallback);
|
||||
network->setConfigUpdateReceivedCallback(nukiOpenerInst->onConfigUpdateReceivedCallback);
|
||||
network->setKeypadCommandReceivedCallback(nukiOpenerInst->onKeypadCommandReceivedCallback);
|
||||
|
||||
_gpio->addCallback(NukiOpenerWrapper::gpioActionCallback);
|
||||
}
|
||||
|
||||
|
||||
@@ -252,6 +255,36 @@ void NukiOpenerWrapper::update()
|
||||
memcpy(&_lastKeyTurnerState, &_keyTurnerState, sizeof(NukiOpener::OpenerState));
|
||||
}
|
||||
|
||||
|
||||
void NukiOpenerWrapper::electricStrikeActuation()
|
||||
{
|
||||
_nextLockAction = NukiOpener::LockAction::ElectricStrikeActuation;
|
||||
}
|
||||
|
||||
void NukiOpenerWrapper::activateRTO()
|
||||
{
|
||||
_nextLockAction = NukiOpener::LockAction::ActivateRTO;
|
||||
}
|
||||
|
||||
void NukiOpenerWrapper::activateCM()
|
||||
{
|
||||
_nextLockAction = NukiOpener::LockAction::ActivateCM;
|
||||
}
|
||||
|
||||
void NukiOpenerWrapper::deactivateRtoCm()
|
||||
{
|
||||
if(_keyTurnerState.nukiState == NukiOpener::State::ContinuousMode)
|
||||
{
|
||||
_nextLockAction = NukiOpener::LockAction::DeactivateCM;
|
||||
return;
|
||||
}
|
||||
|
||||
if(_keyTurnerState.lockState == NukiOpener::LockState::RTOactive)
|
||||
{
|
||||
_nextLockAction = NukiOpener::LockAction::DeactivateRTO;
|
||||
}
|
||||
}
|
||||
|
||||
bool NukiOpenerWrapper::isPinSet()
|
||||
{
|
||||
return _nukiOpener.getSecurityPincode() != 0;
|
||||
@@ -448,6 +481,25 @@ void NukiOpenerWrapper::onKeypadCommandReceivedCallback(const char *command, con
|
||||
nukiOpenerInst->onKeypadCommandReceived(command, id, name, code, enabled);
|
||||
}
|
||||
|
||||
void NukiOpenerWrapper::gpioActionCallback(const GpioAction &action)
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case GpioAction::ElectricStrikeActuation:
|
||||
nukiOpenerInst->electricStrikeActuation();
|
||||
break;
|
||||
case GpioAction::ActivateRTO:
|
||||
nukiOpenerInst->activateRTO();
|
||||
break;
|
||||
case GpioAction::ActivateCM:
|
||||
nukiOpenerInst->activateCM();
|
||||
break;
|
||||
case GpioAction::DeactivateRtoCm:
|
||||
nukiOpenerInst->deactivateRtoCm();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NukiOpenerWrapper::onConfigUpdateReceived(const char *topic, const char *value)
|
||||
{
|
||||
if(strcmp(topic, mqtt_topic_config_button_enabled) == 0)
|
||||
|
||||
@@ -5,16 +5,22 @@
|
||||
#include "NukiOpenerConstants.h"
|
||||
#include "NukiDataTypes.h"
|
||||
#include "BleScanner.h"
|
||||
#include "Gpio.h"
|
||||
|
||||
class NukiOpenerWrapper : public NukiOpener::SmartlockEventHandler
|
||||
{
|
||||
public:
|
||||
NukiOpenerWrapper(const std::string& deviceName, uint32_t id, BleScanner::Scanner* scanner, NetworkOpener* network, Preferences* preferences);
|
||||
NukiOpenerWrapper(const std::string& deviceName, uint32_t id, BleScanner::Scanner* scanner, NetworkOpener* network, Gpio* gpio, Preferences* preferences);
|
||||
virtual ~NukiOpenerWrapper();
|
||||
|
||||
void initialize();
|
||||
void update();
|
||||
|
||||
void electricStrikeActuation();
|
||||
void activateRTO();
|
||||
void activateCM();
|
||||
void deactivateRtoCm();
|
||||
|
||||
bool isPinSet();
|
||||
void setPin(const uint16_t pin);
|
||||
|
||||
@@ -40,6 +46,7 @@ private:
|
||||
static bool onLockActionReceivedCallback(const char* value);
|
||||
static void onConfigUpdateReceivedCallback(const char* topic, const char* value);
|
||||
static void onKeypadCommandReceivedCallback(const char* command, const uint& id, const String& name, const String& code, const int& enabled);
|
||||
static void gpioActionCallback(const GpioAction& action);
|
||||
void onConfigUpdateReceived(const char* topic, const char* value);
|
||||
void onKeypadCommandReceived(const char* command, const uint& id, const String& name, const String& code, const int& enabled);
|
||||
|
||||
@@ -61,9 +68,10 @@ private:
|
||||
|
||||
std::string _deviceName;
|
||||
NukiOpener::NukiOpener _nukiOpener;
|
||||
BleScanner::Scanner* _bleScanner;
|
||||
NetworkOpener* _network;
|
||||
Preferences* _preferences;
|
||||
BleScanner::Scanner* _bleScanner = nullptr;
|
||||
NetworkOpener* _network = nullptr;
|
||||
Gpio* _gpio = nullptr;
|
||||
Preferences* _preferences = nullptr;
|
||||
int _intervalLockstate = 0; // seconds
|
||||
int _intervalBattery = 0; // seconds
|
||||
int _intervalConfig = 60 * 60; // seconds
|
||||
|
||||
@@ -36,13 +36,13 @@ WebCfgServer::WebCfgServer(NukiWrapper* nuki, NukiOpenerWrapper* nukiOpener, Net
|
||||
|
||||
_pinsConfigured = true;
|
||||
|
||||
if(_nuki != nullptr)
|
||||
if(_nuki != nullptr && !_nuki->isPinSet())
|
||||
{
|
||||
_pinsConfigured = _pinsConfigured && _nuki->isPinSet();
|
||||
_pinsConfigured = false;
|
||||
}
|
||||
if(_nukiOpener != nullptr)
|
||||
if(_nukiOpener != nullptr && !_nukiOpener->isPinSet())
|
||||
{
|
||||
_pinsConfigured = _pinsConfigured && _nukiOpener->isPinSet();
|
||||
_pinsConfigured = false;
|
||||
}
|
||||
|
||||
_brokerConfigured = _preferences->getString(preference_mqtt_broker).length() > 0 && _preferences->getInt(preference_mqtt_broker_port) > 0;
|
||||
|
||||
2
main.cpp
2
main.cpp
@@ -230,7 +230,7 @@ void setup()
|
||||
Log->println(openerEnabled ? F("NUKI Opener enabled") : F("NUKI Opener disabled"));
|
||||
if(openerEnabled)
|
||||
{
|
||||
nukiOpener = new NukiOpenerWrapper("NukiHub", deviceId, bleScanner, networkOpener, preferences);
|
||||
nukiOpener = new NukiOpenerWrapper("NukiHub", deviceId, bleScanner, networkOpener, gpio, preferences);
|
||||
nukiOpener->initialize();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user