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