Merge branch 'master' into check-keypad-codes
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
#define NUKI_HUB_VERSION "9.02"
|
||||
#define NUKI_HUB_BUILD "unknownbuildnr"
|
||||
#define NUKI_HUB_DATE "2024-10-15"
|
||||
#define NUKI_HUB_DATE "2024-10-20"
|
||||
|
||||
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
|
||||
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"
|
||||
|
||||
7
src/EspMillis.h
Normal file
7
src/EspMillis.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
inline int64_t espMillis()
|
||||
{
|
||||
return esp_timer_get_time() / 1000;
|
||||
}
|
||||
526
src/Gpio.cpp
526
src/Gpio.cpp
@@ -10,10 +10,9 @@
|
||||
#include "networkDevices/W5500Definitions.h"
|
||||
|
||||
Gpio* Gpio::_inst = nullptr;
|
||||
const uint Gpio::_debounceTime = GPIO_DEBOUNCE_TIME;
|
||||
|
||||
Gpio::Gpio(Preferences* preferences)
|
||||
: _preferences(preferences)
|
||||
: _preferences(preferences)
|
||||
{
|
||||
_inst = this;
|
||||
loadPinConfiguration();
|
||||
@@ -29,42 +28,50 @@ Gpio::Gpio(Preferences* preferences)
|
||||
|
||||
bool Gpio::isTriggered(const PinEntry& entry)
|
||||
{
|
||||
// Log->println(" ------------ ");
|
||||
|
||||
const int threshold = 3;
|
||||
|
||||
int state = digitalRead(entry.pin);
|
||||
uint8_t state = digitalRead(entry.pin);
|
||||
uint8_t lastState = (_triggerState[entry.pin] & 0x80) >> 7;
|
||||
|
||||
if(entry.role == PinRole::GeneralInputPullDown)
|
||||
uint8_t pinState = _triggerState[entry.pin] & 0x7f;
|
||||
pinState = pinState << 1 | state;
|
||||
_triggerState[entry.pin] = (pinState & 0x7f) | lastState << 7;
|
||||
// Log->print("Trigger state: ");
|
||||
// Log->println(_triggerState[entry.pin], 2);
|
||||
|
||||
pinState = pinState & 0x07;
|
||||
// Log->print("Val: ");
|
||||
// Log->println(pinState);
|
||||
|
||||
|
||||
if(pinState != 0x00 && pinState != 0x07)
|
||||
{
|
||||
state = 1 - state;
|
||||
return false;
|
||||
}
|
||||
// Log->print("Last State: ");
|
||||
// Log->println(lastState);
|
||||
// Log->print("State: ");
|
||||
// Log->println(state);
|
||||
|
||||
if(state == LOW)
|
||||
if(state != lastState)
|
||||
{
|
||||
if (_triggerCount[entry.pin] >= 0)
|
||||
{
|
||||
_triggerCount[entry.pin]++;
|
||||
}
|
||||
|
||||
if (_triggerCount[entry.pin] >= threshold)
|
||||
{
|
||||
_triggerCount[entry.pin] = -1;
|
||||
return true;
|
||||
}
|
||||
// Log->print("State changed: ");
|
||||
// Log->println(state);
|
||||
_triggerState[entry.pin] = (pinState & 0x7f) | state << 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_triggerCount[entry.pin] < 0)
|
||||
{
|
||||
_triggerCount[entry.pin]--;
|
||||
|
||||
if(_triggerCount[entry.pin] <= -threshold)
|
||||
{
|
||||
_triggerCount[entry.pin] = 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
if(entry.role == PinRole::GeneralInputPullDown || entry.role == PinRole::GeneralInputPullUp)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return state == LOW;
|
||||
}
|
||||
|
||||
void Gpio::onTimer()
|
||||
@@ -73,35 +80,35 @@ void Gpio::onTimer()
|
||||
{
|
||||
switch(entry.role)
|
||||
{
|
||||
case PinRole::InputLock:
|
||||
case PinRole::InputUnlock:
|
||||
case PinRole::InputUnlatch:
|
||||
case PinRole::InputLockNgo:
|
||||
case PinRole::InputLockNgoUnlatch:
|
||||
case PinRole::InputElectricStrikeActuation:
|
||||
case PinRole::InputActivateRTO:
|
||||
case PinRole::InputActivateCM:
|
||||
case PinRole::InputDeactivateRtoCm:
|
||||
case PinRole::InputDeactivateRTO:
|
||||
case PinRole::InputDeactivateCM:
|
||||
case PinRole::GeneralInputPullDown:
|
||||
case PinRole::GeneralInputPullUp:
|
||||
if(isTriggered(entry))
|
||||
{
|
||||
_inst->notify(getGpioAction(entry.role), entry.pin);
|
||||
}
|
||||
break;
|
||||
case PinRole::OutputHighLocked:
|
||||
case PinRole::OutputHighUnlocked:
|
||||
case PinRole::OutputHighMotorBlocked:
|
||||
case PinRole::OutputHighRtoActive:
|
||||
case PinRole::OutputHighCmActive:
|
||||
case PinRole::OutputHighRtoOrCmActive:
|
||||
case PinRole::GeneralOutput:
|
||||
case PinRole::Ethernet:
|
||||
// ignore. This case should not occur since pins are configured as output
|
||||
default:
|
||||
break;
|
||||
case PinRole::InputLock:
|
||||
case PinRole::InputUnlock:
|
||||
case PinRole::InputUnlatch:
|
||||
case PinRole::InputLockNgo:
|
||||
case PinRole::InputLockNgoUnlatch:
|
||||
case PinRole::InputElectricStrikeActuation:
|
||||
case PinRole::InputActivateRTO:
|
||||
case PinRole::InputActivateCM:
|
||||
case PinRole::InputDeactivateRtoCm:
|
||||
case PinRole::InputDeactivateRTO:
|
||||
case PinRole::InputDeactivateCM:
|
||||
case PinRole::GeneralInputPullDown:
|
||||
case PinRole::GeneralInputPullUp:
|
||||
if(isTriggered(entry))
|
||||
{
|
||||
_inst->notify(getGpioAction(entry.role), entry.pin);
|
||||
}
|
||||
break;
|
||||
case PinRole::OutputHighLocked:
|
||||
case PinRole::OutputHighUnlocked:
|
||||
case PinRole::OutputHighMotorBlocked:
|
||||
case PinRole::OutputHighRtoActive:
|
||||
case PinRole::OutputHighCmActive:
|
||||
case PinRole::OutputHighRtoOrCmActive:
|
||||
case PinRole::GeneralOutput:
|
||||
case PinRole::Ethernet:
|
||||
// ignore. This case should not occur since pins are configured as output
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,10 +120,10 @@ void Gpio::isrOnTimer()
|
||||
|
||||
void Gpio::init()
|
||||
{
|
||||
_inst->_triggerCount.reserve(_inst->availablePins().size());
|
||||
_inst->_triggerState.reserve(_inst->availablePins().size());
|
||||
for(int i=0; i<_inst->availablePins().size(); i++)
|
||||
{
|
||||
_inst->_triggerCount.push_back(0);
|
||||
_inst->_triggerState.push_back(0);
|
||||
}
|
||||
|
||||
bool hasInputPin = false;
|
||||
@@ -132,37 +139,37 @@ void Gpio::init()
|
||||
|
||||
switch(entry.role)
|
||||
{
|
||||
case PinRole::InputLock:
|
||||
case PinRole::InputUnlock:
|
||||
case PinRole::InputUnlatch:
|
||||
case PinRole::InputLockNgo:
|
||||
case PinRole::InputLockNgoUnlatch:
|
||||
case PinRole::InputElectricStrikeActuation:
|
||||
case PinRole::InputActivateRTO:
|
||||
case PinRole::InputActivateCM:
|
||||
case PinRole::InputDeactivateRtoCm:
|
||||
case PinRole::InputDeactivateRTO:
|
||||
case PinRole::InputDeactivateCM:
|
||||
case PinRole::GeneralInputPullUp:
|
||||
pinMode(entry.pin, INPUT_PULLUP);
|
||||
hasInputPin = true;
|
||||
break;
|
||||
case PinRole::GeneralInputPullDown:
|
||||
pinMode(entry.pin, INPUT_PULLDOWN);
|
||||
hasInputPin = true;
|
||||
break;
|
||||
case PinRole::OutputHighLocked:
|
||||
case PinRole::OutputHighUnlocked:
|
||||
case PinRole::OutputHighMotorBlocked:
|
||||
case PinRole::OutputHighRtoActive:
|
||||
case PinRole::OutputHighCmActive:
|
||||
case PinRole::OutputHighRtoOrCmActive:
|
||||
case PinRole::GeneralOutput:
|
||||
pinMode(entry.pin, OUTPUT);
|
||||
break;
|
||||
case PinRole::Ethernet:
|
||||
default:
|
||||
break;
|
||||
case PinRole::InputLock:
|
||||
case PinRole::InputUnlock:
|
||||
case PinRole::InputUnlatch:
|
||||
case PinRole::InputLockNgo:
|
||||
case PinRole::InputLockNgoUnlatch:
|
||||
case PinRole::InputElectricStrikeActuation:
|
||||
case PinRole::InputActivateRTO:
|
||||
case PinRole::InputActivateCM:
|
||||
case PinRole::InputDeactivateRtoCm:
|
||||
case PinRole::InputDeactivateRTO:
|
||||
case PinRole::InputDeactivateCM:
|
||||
case PinRole::GeneralInputPullUp:
|
||||
pinMode(entry.pin, INPUT_PULLUP);
|
||||
hasInputPin = true;
|
||||
break;
|
||||
case PinRole::GeneralInputPullDown:
|
||||
pinMode(entry.pin, INPUT_PULLDOWN);
|
||||
hasInputPin = true;
|
||||
break;
|
||||
case PinRole::OutputHighLocked:
|
||||
case PinRole::OutputHighUnlocked:
|
||||
case PinRole::OutputHighMotorBlocked:
|
||||
case PinRole::OutputHighRtoActive:
|
||||
case PinRole::OutputHighCmActive:
|
||||
case PinRole::OutputHighRtoOrCmActive:
|
||||
case PinRole::GeneralOutput:
|
||||
pinMode(entry.pin, OUTPUT);
|
||||
break;
|
||||
case PinRole::Ethernet:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +221,10 @@ void Gpio::loadPinConfiguration()
|
||||
|
||||
if(std::find(disabledPins.begin(), disabledPins.end(), entry.pin) == disabledPins.end())
|
||||
{
|
||||
if(entry.role == PinRole::Ethernet) entry.role = PinRole::Disabled;
|
||||
if(entry.role == PinRole::Ethernet)
|
||||
{
|
||||
entry.role = PinRole::Disabled;
|
||||
}
|
||||
entry.role = (PinRole) serialized[(i * 2 + 1)];
|
||||
Log->println("Not found in Ethernet disabled pins");
|
||||
Log->print(F("Role: "));
|
||||
@@ -227,7 +237,10 @@ void Gpio::loadPinConfiguration()
|
||||
Log->print(F("Role: "));
|
||||
Log->println(getRoleDescription(entry.role));
|
||||
}
|
||||
if(entry.role != PinRole::Disabled) _pinConfiguration.push_back(entry);
|
||||
if(entry.role != PinRole::Disabled)
|
||||
{
|
||||
_pinConfiguration.push_back(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,90 +250,94 @@ const std::vector<int> Gpio::getDisabledPins() const
|
||||
|
||||
switch(_preferences->getInt(preference_network_hardware, 0))
|
||||
{
|
||||
case 2:
|
||||
disabledPins.push_back(ETH_PHY_CS_GENERIC_W5500);
|
||||
disabledPins.push_back(ETH_PHY_IRQ_GENERIC_W5500);
|
||||
disabledPins.push_back(ETH_PHY_RST_GENERIC_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_SCK_GENERIC_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MISO_GENERIC_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MOSI_GENERIC_W5500);
|
||||
break;
|
||||
case 3:
|
||||
disabledPins.push_back(ETH_PHY_CS_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_IRQ_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_RST_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_SCK_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MISO_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MOSI_M5_W5500);
|
||||
break;
|
||||
case 10:
|
||||
disabledPins.push_back(ETH_PHY_CS_M5_W5500_S3);
|
||||
disabledPins.push_back(ETH_PHY_IRQ_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_RST_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_SCK_M5_W5500_S3);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MISO_M5_W5500_S3);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MOSI_M5_W5500_S3);
|
||||
break;
|
||||
case 9:
|
||||
disabledPins.push_back(ETH_PHY_CS_ETH01EVO);
|
||||
disabledPins.push_back(ETH_PHY_IRQ_ETH01EVO);
|
||||
disabledPins.push_back(ETH_PHY_RST_ETH01EVO);
|
||||
disabledPins.push_back(ETH_PHY_SPI_SCK_ETH01EVO);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MISO_ETH01EVO);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MOSI_ETH01EVO);
|
||||
break;
|
||||
case 6:
|
||||
disabledPins.push_back(ETH_PHY_CS_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_IRQ_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_RST_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_SCK_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MISO_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MOSI_M5_W5500);
|
||||
break;
|
||||
case 11:
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_cs, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_irq, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_rst, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_sck, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_miso, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_mosi, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_pwr, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_mdc, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_mdio, -1));
|
||||
break;
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||
case 4:
|
||||
disabledPins.push_back(12);
|
||||
disabledPins.push_back(ETH_RESET_PIN_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDC_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDIO_LAN8720);
|
||||
break;
|
||||
case 5:
|
||||
disabledPins.push_back(16);
|
||||
disabledPins.push_back(ETH_RESET_PIN_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDC_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDIO_LAN8720);
|
||||
break;
|
||||
case 8:
|
||||
disabledPins.push_back(5);
|
||||
disabledPins.push_back(ETH_RESET_PIN_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDC_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDIO_LAN8720);
|
||||
break;
|
||||
case 7:
|
||||
disabledPins.push_back(-1);
|
||||
disabledPins.push_back(ETH_RESET_PIN_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDC_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDIO_LAN8720);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
case 2:
|
||||
disabledPins.push_back(ETH_PHY_CS_GENERIC_W5500);
|
||||
disabledPins.push_back(ETH_PHY_IRQ_GENERIC_W5500);
|
||||
disabledPins.push_back(ETH_PHY_RST_GENERIC_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_SCK_GENERIC_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MISO_GENERIC_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MOSI_GENERIC_W5500);
|
||||
break;
|
||||
case 3:
|
||||
disabledPins.push_back(ETH_PHY_CS_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_IRQ_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_RST_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_SCK_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MISO_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MOSI_M5_W5500);
|
||||
break;
|
||||
case 10:
|
||||
disabledPins.push_back(ETH_PHY_CS_M5_W5500_S3);
|
||||
disabledPins.push_back(ETH_PHY_IRQ_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_RST_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_SCK_M5_W5500_S3);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MISO_M5_W5500_S3);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MOSI_M5_W5500_S3);
|
||||
break;
|
||||
case 9:
|
||||
disabledPins.push_back(ETH_PHY_CS_ETH01EVO);
|
||||
disabledPins.push_back(ETH_PHY_IRQ_ETH01EVO);
|
||||
disabledPins.push_back(ETH_PHY_RST_ETH01EVO);
|
||||
disabledPins.push_back(ETH_PHY_SPI_SCK_ETH01EVO);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MISO_ETH01EVO);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MOSI_ETH01EVO);
|
||||
break;
|
||||
case 6:
|
||||
disabledPins.push_back(ETH_PHY_CS_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_IRQ_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_RST_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_SCK_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MISO_M5_W5500);
|
||||
disabledPins.push_back(ETH_PHY_SPI_MOSI_M5_W5500);
|
||||
break;
|
||||
case 11:
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_cs, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_irq, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_rst, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_sck, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_miso, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_mosi, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_pwr, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_mdc, -1));
|
||||
disabledPins.push_back(_preferences->getInt(preference_network_custom_mdio, -1));
|
||||
break;
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||
case 4:
|
||||
disabledPins.push_back(12);
|
||||
disabledPins.push_back(ETH_RESET_PIN_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDC_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDIO_LAN8720);
|
||||
break;
|
||||
case 5:
|
||||
disabledPins.push_back(16);
|
||||
disabledPins.push_back(ETH_RESET_PIN_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDC_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDIO_LAN8720);
|
||||
break;
|
||||
case 8:
|
||||
disabledPins.push_back(5);
|
||||
disabledPins.push_back(ETH_RESET_PIN_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDC_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDIO_LAN8720);
|
||||
break;
|
||||
case 7:
|
||||
disabledPins.push_back(-1);
|
||||
disabledPins.push_back(ETH_RESET_PIN_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDC_LAN8720);
|
||||
disabledPins.push_back(ETH_PHY_MDIO_LAN8720);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Log->print(F("GPIO Ethernet disabled pins:"));
|
||||
for_each_n(disabledPins.begin(), disabledPins.size(),
|
||||
[](int x) { Log->print(" "); Log->print(x); });
|
||||
[](int x)
|
||||
{
|
||||
Log->print(" ");
|
||||
Log->print(x);
|
||||
});
|
||||
Log->println();
|
||||
return disabledPins;
|
||||
}
|
||||
@@ -386,52 +403,52 @@ String Gpio::getRoleDescription(const PinRole& role) const
|
||||
{
|
||||
switch(role)
|
||||
{
|
||||
case PinRole::Disabled:
|
||||
return "Disabled";
|
||||
case PinRole::InputLock:
|
||||
return "Input: Lock";
|
||||
case PinRole::InputUnlock:
|
||||
return "Input: Unlock";
|
||||
case PinRole::InputUnlatch:
|
||||
return "Input: Unlatch";
|
||||
case PinRole::InputLockNgo:
|
||||
return "Input: Lock n Go";
|
||||
case PinRole::InputLockNgoUnlatch:
|
||||
return "Input: Lock n Go and 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::InputDeactivateRTO:
|
||||
return "Input: Deactivate RTO";
|
||||
case PinRole::InputDeactivateCM:
|
||||
return "Input: Deactivate CM";
|
||||
case PinRole::OutputHighLocked:
|
||||
return "Output: High when locked";
|
||||
case PinRole::OutputHighUnlocked:
|
||||
return "Output: High when unlocked";
|
||||
case PinRole::OutputHighMotorBlocked:
|
||||
return "Output: High when motor blocked";
|
||||
case PinRole::OutputHighRtoActive:
|
||||
return "Output: High when RTO active";
|
||||
case PinRole::OutputHighCmActive:
|
||||
return "Output: High when CM active";
|
||||
case PinRole::OutputHighRtoOrCmActive:
|
||||
return "Output: High when RTO or CM active";
|
||||
case PinRole::GeneralOutput:
|
||||
return "General output";
|
||||
case PinRole::GeneralInputPullDown:
|
||||
return "General input (Pull-down)";
|
||||
case PinRole::GeneralInputPullUp:
|
||||
return "General input (Pull-up)";
|
||||
case PinRole::Ethernet:
|
||||
return "Ethernet";
|
||||
default:
|
||||
return "Unknown";
|
||||
case PinRole::Disabled:
|
||||
return "Disabled";
|
||||
case PinRole::InputLock:
|
||||
return "Input: Lock";
|
||||
case PinRole::InputUnlock:
|
||||
return "Input: Unlock";
|
||||
case PinRole::InputUnlatch:
|
||||
return "Input: Unlatch";
|
||||
case PinRole::InputLockNgo:
|
||||
return "Input: Lock n Go";
|
||||
case PinRole::InputLockNgoUnlatch:
|
||||
return "Input: Lock n Go and 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::InputDeactivateRTO:
|
||||
return "Input: Deactivate RTO";
|
||||
case PinRole::InputDeactivateCM:
|
||||
return "Input: Deactivate CM";
|
||||
case PinRole::OutputHighLocked:
|
||||
return "Output: High when locked";
|
||||
case PinRole::OutputHighUnlocked:
|
||||
return "Output: High when unlocked";
|
||||
case PinRole::OutputHighMotorBlocked:
|
||||
return "Output: High when motor blocked";
|
||||
case PinRole::OutputHighRtoActive:
|
||||
return "Output: High when RTO active";
|
||||
case PinRole::OutputHighCmActive:
|
||||
return "Output: High when CM active";
|
||||
case PinRole::OutputHighRtoOrCmActive:
|
||||
return "Output: High when RTO or CM active";
|
||||
case PinRole::GeneralOutput:
|
||||
return "General output";
|
||||
case PinRole::GeneralInputPullDown:
|
||||
return "General input (Pull-down)";
|
||||
case PinRole::GeneralInputPullUp:
|
||||
return "General input (Pull-up)";
|
||||
case PinRole::Ethernet:
|
||||
return "Ethernet";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,46 +457,47 @@ GpioAction Gpio::getGpioAction(const PinRole &role) const
|
||||
{
|
||||
switch(role)
|
||||
{
|
||||
case PinRole::Disabled:
|
||||
return GpioAction::None;
|
||||
case PinRole::InputLock:
|
||||
return GpioAction::Lock;
|
||||
case PinRole::InputUnlock:
|
||||
return GpioAction::Unlock;
|
||||
case PinRole::InputUnlatch:
|
||||
return GpioAction::Unlatch;
|
||||
case PinRole::InputLockNgo:
|
||||
return GpioAction::LockNgo;
|
||||
case PinRole::InputLockNgoUnlatch:
|
||||
return GpioAction::LockNgoUnlatch;
|
||||
case PinRole::InputElectricStrikeActuation:
|
||||
return GpioAction::ElectricStrikeActuation;
|
||||
case PinRole::InputActivateRTO:
|
||||
return GpioAction::ActivateRTO;
|
||||
case PinRole::InputActivateCM:
|
||||
return GpioAction::ActivateCM;
|
||||
case PinRole::InputDeactivateRtoCm:
|
||||
return GpioAction::DeactivateRtoCm;
|
||||
case PinRole::InputDeactivateRTO:
|
||||
return GpioAction::DeactivateRTO;
|
||||
case PinRole::InputDeactivateCM:
|
||||
return GpioAction::DeactivateCM;
|
||||
case PinRole::Disabled:
|
||||
return GpioAction::None;
|
||||
case PinRole::InputLock:
|
||||
return GpioAction::Lock;
|
||||
case PinRole::InputUnlock:
|
||||
return GpioAction::Unlock;
|
||||
case PinRole::InputUnlatch:
|
||||
return GpioAction::Unlatch;
|
||||
case PinRole::InputLockNgo:
|
||||
return GpioAction::LockNgo;
|
||||
case PinRole::InputLockNgoUnlatch:
|
||||
return GpioAction::LockNgoUnlatch;
|
||||
case PinRole::InputElectricStrikeActuation:
|
||||
return GpioAction::ElectricStrikeActuation;
|
||||
case PinRole::InputActivateRTO:
|
||||
return GpioAction::ActivateRTO;
|
||||
case PinRole::InputActivateCM:
|
||||
return GpioAction::ActivateCM;
|
||||
case PinRole::InputDeactivateRtoCm:
|
||||
return GpioAction::DeactivateRtoCm;
|
||||
case PinRole::InputDeactivateRTO:
|
||||
return GpioAction::DeactivateRTO;
|
||||
case PinRole::InputDeactivateCM:
|
||||
return GpioAction::DeactivateCM;
|
||||
|
||||
case PinRole::GeneralInputPullDown:
|
||||
case PinRole::GeneralInputPullUp:
|
||||
return GpioAction::GeneralInput;
|
||||
case PinRole::GeneralInputPullDown:
|
||||
case PinRole::GeneralInputPullUp:
|
||||
return GpioAction::GeneralInput;
|
||||
|
||||
case PinRole::GeneralOutput:
|
||||
case PinRole::Ethernet:
|
||||
case PinRole::OutputHighLocked:
|
||||
case PinRole::OutputHighUnlocked:
|
||||
case PinRole::OutputHighMotorBlocked:
|
||||
case PinRole::OutputHighRtoActive:
|
||||
case PinRole::OutputHighCmActive:
|
||||
case PinRole::OutputHighRtoOrCmActive:
|
||||
default:
|
||||
return GpioAction::None;
|
||||
}}
|
||||
case PinRole::GeneralOutput:
|
||||
case PinRole::Ethernet:
|
||||
case PinRole::OutputHighLocked:
|
||||
case PinRole::OutputHighUnlocked:
|
||||
case PinRole::OutputHighMotorBlocked:
|
||||
case PinRole::OutputHighRtoActive:
|
||||
case PinRole::OutputHighCmActive:
|
||||
case PinRole::OutputHighRtoOrCmActive:
|
||||
default:
|
||||
return GpioAction::None;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Gpio::getConfigurationText(String& text, const std::vector<PinEntry>& pinConfiguration, const String& linebreak) const
|
||||
|
||||
@@ -84,6 +84,7 @@ private:
|
||||
void IRAM_ATTR onTimer();
|
||||
bool IRAM_ATTR isTriggered(const PinEntry& pinEntry);
|
||||
GpioAction IRAM_ATTR getGpioAction(const PinRole& role) const;
|
||||
static void IRAM_ATTR isrOnTimer();
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
//Based on https://docs.espressif.com/projects/esp-idf/en/stable/esp32c3/api-reference/peripherals/gpio.html and https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf
|
||||
@@ -127,15 +128,12 @@ private:
|
||||
};
|
||||
|
||||
std::vector<PinEntry> _pinConfiguration;
|
||||
static const uint _debounceTime;
|
||||
|
||||
static void IRAM_ATTR isrOnTimer();
|
||||
|
||||
std::vector<std::function<void(const GpioAction&, const int&)>> _callbacks;
|
||||
|
||||
static Gpio* _inst;
|
||||
|
||||
std::vector<int8_t> _triggerCount;
|
||||
std::vector<uint8_t> _triggerState;
|
||||
hw_timer_t* timer = nullptr;
|
||||
|
||||
Preferences* _preferences = nullptr;
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
class MqttReceiver
|
||||
{
|
||||
public:
|
||||
virtual void onMqttDataReceived(const char* topic, byte* payload, const unsigned int length) = 0;
|
||||
virtual void onMqttDataReceived(char* topic, int topic_len, char* data, int data_len) = 0;
|
||||
};
|
||||
@@ -5,8 +5,8 @@
|
||||
#include "PreferencesKeys.h"
|
||||
|
||||
NukiDeviceId::NukiDeviceId(Preferences* preferences, const std::string& preferencesId)
|
||||
: _preferences(preferences),
|
||||
_preferencesId(preferencesId)
|
||||
: _preferences(preferences),
|
||||
_preferencesId(preferencesId)
|
||||
{
|
||||
_deviceId = _preferences->getUInt(_preferencesId.c_str(), 0);
|
||||
|
||||
|
||||
1949
src/NukiNetwork.cpp
1949
src/NukiNetwork.cpp
File diff suppressed because it is too large
Load Diff
@@ -7,17 +7,17 @@
|
||||
#include "networkDevices/IPConfiguration.h"
|
||||
#include "enums/NetworkDeviceType.h"
|
||||
#include "util/NetworkUtil.h"
|
||||
#include "EspMillis.h"
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
#include "MqttReceiver.h"
|
||||
#include "mqtt_client.h"
|
||||
#include "MqttTopics.h"
|
||||
#include "Gpio.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include "NukiConstants.h"
|
||||
#endif
|
||||
|
||||
#define JSON_BUFFER_SIZE 1024
|
||||
|
||||
class NukiNetwork
|
||||
{
|
||||
public:
|
||||
@@ -25,6 +25,9 @@ public:
|
||||
void readSettings();
|
||||
bool update();
|
||||
void reconfigureDevice();
|
||||
void scan(bool passive = false, bool async = true);
|
||||
bool isApOpen();
|
||||
bool isConnected();
|
||||
void clearWifiFallback();
|
||||
|
||||
const String networkDeviceName() const;
|
||||
@@ -43,7 +46,6 @@ public:
|
||||
void disableAutoRestarts(); // disable on OTA start
|
||||
void disableMqtt();
|
||||
String localIP();
|
||||
bool isConnected();
|
||||
|
||||
void subscribe(const char* prefix, const char* path);
|
||||
void initTopic(const char* prefix, const char* path, const char* value);
|
||||
@@ -86,7 +88,6 @@ public:
|
||||
void timeZoneIdToString(const Nuki::TimeZoneId timeZoneId, char* str);
|
||||
|
||||
int mqttConnectionState(); // 0 = not connected; 1 = connected; 2 = connected and mqtt processed
|
||||
bool encryptionSupported();
|
||||
bool mqttRecentlyConnected();
|
||||
bool pathEquals(const char* prefix, const char* path, const char* referencePath);
|
||||
uint16_t subscribe(const char* topic, uint8_t qos);
|
||||
@@ -117,9 +118,10 @@ private:
|
||||
bool _offEnabled = false;
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
static void onMqttDataReceivedCallback(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total);
|
||||
void onMqttDataReceived(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t& len, size_t& index, size_t& total);
|
||||
void parseGpioTopics(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t& len, size_t& index, size_t& total);
|
||||
static void mqtt_event_handler_cb(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data);
|
||||
void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data);
|
||||
void onMqttDataReceived(char* topic, int topic_len, char* data, int data_len);
|
||||
void parseGpioTopics(char* topic, int topic_len, char* data, int data_len);
|
||||
void gpioActionCallback(const GpioAction& action, const int& pin);
|
||||
|
||||
String createHassTopicPath(const String& mqttDeviceType, const String& mqttDeviceName, const String& uidString);
|
||||
@@ -136,10 +138,6 @@ private:
|
||||
const String& commandTopic = "",
|
||||
std::vector<std::pair<char*, char*>> additionalEntries = {}
|
||||
);
|
||||
|
||||
void onMqttConnect(const bool& sessionPresent);
|
||||
void onMqttDisconnect(const espMqttClientTypes::DisconnectReason& reason);
|
||||
|
||||
void buildMqttPath(char* outPath, std::initializer_list<const char*> paths);
|
||||
|
||||
const char* _lastWillPayload = "offline";
|
||||
@@ -148,13 +146,20 @@ private:
|
||||
String _discoveryTopic;
|
||||
|
||||
Gpio* _gpio;
|
||||
|
||||
|
||||
esp_mqtt_client_config_t _mqtt_cfg = { 0 };
|
||||
bool _mqttClientInitiated = false;
|
||||
int _mqttConnectionState = 0;
|
||||
bool _mqttConnected = false;
|
||||
int _mqttConnectCounter = 0;
|
||||
int _mqttPort = 1883;
|
||||
long _mqttConnectedTs = -1;
|
||||
bool _connectReplyReceived = false;
|
||||
bool _firstDisconnected = true;
|
||||
|
||||
esp_mqtt_client_handle_t _mqttClient;
|
||||
char _ca[TLS_CA_MAX_SIZE] = {0};
|
||||
char _cert[TLS_CERT_MAX_SIZE] = {0};
|
||||
char _key[TLS_KEY_MAX_SIZE] = {0};
|
||||
|
||||
int64_t _nextReconnect = 0;
|
||||
char _mqttBrokerAddr[101] = {0};
|
||||
@@ -166,7 +171,6 @@ private:
|
||||
std::vector<MqttReceiver*> _mqttReceivers;
|
||||
bool _restartOnDisconnect = false;
|
||||
bool _checkUpdates = false;
|
||||
bool _reconnectNetworkOnMqttDisconnect = false;
|
||||
bool _firstConnect = true;
|
||||
bool _publishDebugInfo = false;
|
||||
bool _logIp = true;
|
||||
|
||||
@@ -15,11 +15,11 @@ extern const uint8_t x509_crt_imported_bundle_bin_start[] asm("_binary_x509_crt_
|
||||
extern const uint8_t x509_crt_imported_bundle_bin_end[] asm("_binary_x509_crt_bundle_end");
|
||||
|
||||
NukiNetworkLock::NukiNetworkLock(NukiNetwork* network, NukiOfficial* nukiOfficial, Preferences* preferences, char* buffer, size_t bufferSize)
|
||||
: _network(network),
|
||||
_nukiOfficial(nukiOfficial),
|
||||
_preferences(preferences),
|
||||
_buffer(buffer),
|
||||
_bufferSize(bufferSize)
|
||||
: _network(network),
|
||||
_nukiOfficial(nukiOfficial),
|
||||
_preferences(preferences),
|
||||
_buffer(buffer),
|
||||
_bufferSize(bufferSize)
|
||||
{
|
||||
_nukiPublisher = new NukiPublisher(network, _mqttPath);
|
||||
_nukiOfficial->setPublisher(_nukiPublisher);
|
||||
@@ -178,24 +178,22 @@ void NukiNetworkLock::update()
|
||||
}
|
||||
}
|
||||
|
||||
void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const unsigned int length)
|
||||
void NukiNetworkLock::onMqttDataReceived(char* topic, int topic_len, char* data, int data_len)
|
||||
{
|
||||
char* value = (char*)payload;
|
||||
|
||||
if(_network->mqttRecentlyConnected() && _network->pathEquals(_mqttPath, mqtt_topic_lock_action, topic))
|
||||
{
|
||||
Log->println("MQTT recently connected, ignoring lock action.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(comparePrefixedPath(topic, mqtt_topic_reset) && strcmp(value, "1") == 0)
|
||||
if(comparePrefixedPath(topic, mqtt_topic_reset) && strcmp(data, "1") == 0)
|
||||
{
|
||||
Log->println(F("Restart requested via MQTT."));
|
||||
_network->clearWifiFallback();
|
||||
delay(200);
|
||||
restartEsp(RestartReason::RequestedViaMqtt);
|
||||
}
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_update) && strcmp(value, "1") == 0 && _preferences->getBool(preference_update_from_mqtt, false))
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_update) && strcmp(data, "1") == 0 && _preferences->getBool(preference_update_from_mqtt, false))
|
||||
{
|
||||
Log->println(F("Update requested via MQTT."));
|
||||
|
||||
@@ -203,21 +201,26 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
|
||||
JsonDocument doc;
|
||||
|
||||
NetworkClientSecure *client = new NetworkClientSecure;
|
||||
if (client) {
|
||||
if (client)
|
||||
{
|
||||
client->setCACertBundle(x509_crt_imported_bundle_bin_start, x509_crt_imported_bundle_bin_end - x509_crt_imported_bundle_bin_start);
|
||||
{
|
||||
HTTPClient https;
|
||||
https.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
|
||||
https.useHTTP10(true);
|
||||
|
||||
if (https.begin(*client, GITHUB_OTA_MANIFEST_URL)) {
|
||||
if (https.begin(*client, GITHUB_OTA_MANIFEST_URL))
|
||||
{
|
||||
int httpResponseCode = https.GET();
|
||||
|
||||
if (httpResponseCode == HTTP_CODE_OK || httpResponseCode == HTTP_CODE_MOVED_PERMANENTLY)
|
||||
{
|
||||
DeserializationError jsonError = deserializeJson(doc, https.getStream());
|
||||
|
||||
if (!jsonError) { otaManifestSuccess = true; }
|
||||
if (!jsonError)
|
||||
{
|
||||
otaManifestSuccess = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
https.end();
|
||||
@@ -297,19 +300,28 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
|
||||
}
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_webserver_action))
|
||||
{
|
||||
if(strcmp(value, "") == 0 ||
|
||||
strcmp(value, "--") == 0) return;
|
||||
|
||||
if(strcmp(value, "1") == 0)
|
||||
if(strcmp(data, "") == 0 ||
|
||||
strcmp(data, "--") == 0)
|
||||
{
|
||||
if(_preferences->getBool(preference_webserver_enabled, true) || forceEnableWebServer) return;
|
||||
return;
|
||||
}
|
||||
|
||||
if(strcmp(data, "1") == 0)
|
||||
{
|
||||
if(_preferences->getBool(preference_webserver_enabled, true) || forceEnableWebServer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Log->println(F("Webserver enabled, restarting."));
|
||||
_preferences->putBool(preference_webserver_enabled, true);
|
||||
|
||||
}
|
||||
else if (strcmp(value, "0") == 0)
|
||||
else if (strcmp(data, "0") == 0)
|
||||
{
|
||||
if(!_preferences->getBool(preference_webserver_enabled, true) && !forceEnableWebServer) return;
|
||||
if(!_preferences->getBool(preference_webserver_enabled, true) && !forceEnableWebServer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Log->println(F("Webserver disabled, restarting."));
|
||||
_preferences->putBool(preference_webserver_enabled, false);
|
||||
}
|
||||
@@ -321,10 +333,16 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
|
||||
}
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_lock_log_rolling_last))
|
||||
{
|
||||
if(strcmp(value, "") == 0 ||
|
||||
strcmp(value, "--") == 0) return;
|
||||
if(strcmp(data, "") == 0 ||
|
||||
strcmp(data, "--") == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(atoi(value) > 0 && atoi(value) > _lastRollingLog) _lastRollingLog = atoi(value);
|
||||
if(atoi(data) > 0 && atoi(data) > _lastRollingLog)
|
||||
{
|
||||
_lastRollingLog = atoi(data);
|
||||
}
|
||||
}
|
||||
|
||||
if(_nukiOfficial->getOffEnabled())
|
||||
@@ -335,7 +353,7 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
|
||||
{
|
||||
if(_officialUpdateReceivedCallback != nullptr)
|
||||
{
|
||||
_officialUpdateReceivedCallback(offTopic, value);
|
||||
_officialUpdateReceivedCallback(offTopic, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -343,35 +361,38 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
|
||||
|
||||
if(comparePrefixedPath(topic, mqtt_topic_lock_action))
|
||||
{
|
||||
if(strcmp(value, "") == 0 ||
|
||||
strcmp(value, "--") == 0 ||
|
||||
strcmp(value, "ack") == 0 ||
|
||||
strcmp(value, "unknown_action") == 0 ||
|
||||
strcmp(value, "denied") == 0 ||
|
||||
strcmp(value, "error") == 0) return;
|
||||
if(strcmp(data, "") == 0 ||
|
||||
strcmp(data, "--") == 0 ||
|
||||
strcmp(data, "ack") == 0 ||
|
||||
strcmp(data, "unknown_action") == 0 ||
|
||||
strcmp(data, "denied") == 0 ||
|
||||
strcmp(data, "error") == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Log->print(F("Lock action received: "));
|
||||
Log->println(value);
|
||||
Log->println(data);
|
||||
LockActionResult lockActionResult = LockActionResult::Failed;
|
||||
if(_lockActionReceivedCallback != NULL)
|
||||
{
|
||||
lockActionResult = _lockActionReceivedCallback(value);
|
||||
lockActionResult = _lockActionReceivedCallback(data);
|
||||
}
|
||||
|
||||
switch(lockActionResult)
|
||||
{
|
||||
case LockActionResult::Success:
|
||||
publishString(mqtt_topic_lock_action, "ack", false);
|
||||
break;
|
||||
case LockActionResult::UnknownAction:
|
||||
publishString(mqtt_topic_lock_action, "unknown_action", false);
|
||||
break;
|
||||
case LockActionResult::AccessDenied:
|
||||
publishString(mqtt_topic_lock_action, "denied", false);
|
||||
break;
|
||||
case LockActionResult::Failed:
|
||||
publishString(mqtt_topic_lock_action, "error", false);
|
||||
break;
|
||||
case LockActionResult::Success:
|
||||
publishString(mqtt_topic_lock_action, "ack", false);
|
||||
break;
|
||||
case LockActionResult::UnknownAction:
|
||||
publishString(mqtt_topic_lock_action, "unknown_action", false);
|
||||
break;
|
||||
case LockActionResult::AccessDenied:
|
||||
publishString(mqtt_topic_lock_action, "denied", false);
|
||||
break;
|
||||
case LockActionResult::Failed:
|
||||
publishString(mqtt_topic_lock_action, "error", false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,16 +402,19 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
|
||||
{
|
||||
if(_keypadCommandReceivedReceivedCallback != nullptr)
|
||||
{
|
||||
if(strcmp(value, "--") == 0) return;
|
||||
if(strcmp(data, "--") == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_keypadCommandReceivedReceivedCallback(value, _keypadCommandId, _keypadCommandName, _keypadCommandCode, _keypadCommandEnabled);
|
||||
_keypadCommandReceivedReceivedCallback(data, _keypadCommandId, _keypadCommandName, _keypadCommandCode, _keypadCommandEnabled);
|
||||
|
||||
_keypadCommandId = 0;
|
||||
_keypadCommandName = "--";
|
||||
_keypadCommandCode = "000000";
|
||||
_keypadCommandEnabled = 1;
|
||||
|
||||
if(strcmp(value, "--") != 0)
|
||||
if(strcmp(data, "--") != 0)
|
||||
{
|
||||
publishString(mqtt_topic_keypad_command_action, "--", true);
|
||||
}
|
||||
@@ -402,38 +426,38 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
|
||||
}
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_keypad_command_id))
|
||||
{
|
||||
_keypadCommandId = atoi(value);
|
||||
_keypadCommandId = atoi(data);
|
||||
}
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_keypad_command_name))
|
||||
{
|
||||
_keypadCommandName = value;
|
||||
_keypadCommandName = data;
|
||||
}
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_keypad_command_code))
|
||||
{
|
||||
_keypadCommandCode = value;
|
||||
_keypadCommandCode = data;
|
||||
}
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_keypad_command_enabled))
|
||||
{
|
||||
_keypadCommandEnabled = atoi(value);
|
||||
_keypadCommandEnabled = atoi(data);
|
||||
}
|
||||
}
|
||||
|
||||
if(comparePrefixedPath(topic, mqtt_topic_query_config) && strcmp(value, "1") == 0)
|
||||
if(comparePrefixedPath(topic, mqtt_topic_query_config) && strcmp(data, "1") == 0)
|
||||
{
|
||||
_queryCommands = _queryCommands | QUERY_COMMAND_CONFIG;
|
||||
publishString(mqtt_topic_query_config, "0", true);
|
||||
}
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_query_lockstate) && strcmp(value, "1") == 0)
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_query_lockstate) && strcmp(data, "1") == 0)
|
||||
{
|
||||
_queryCommands = _queryCommands | QUERY_COMMAND_LOCKSTATE;
|
||||
publishString(mqtt_topic_query_lockstate, "0", true);
|
||||
}
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_query_keypad) && strcmp(value, "1") == 0)
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_query_keypad) && strcmp(data, "1") == 0)
|
||||
{
|
||||
_queryCommands = _queryCommands | QUERY_COMMAND_KEYPAD;
|
||||
publishString(mqtt_topic_query_keypad, "0", true);
|
||||
}
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_query_battery) && strcmp(value, "1") == 0)
|
||||
else if(comparePrefixedPath(topic, mqtt_topic_query_battery) && strcmp(data, "1") == 0)
|
||||
{
|
||||
_queryCommands = _queryCommands | QUERY_COMMAND_BATTERY;
|
||||
publishString(mqtt_topic_query_battery, "0", true);
|
||||
@@ -441,11 +465,14 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
|
||||
|
||||
if(comparePrefixedPath(topic, mqtt_topic_config_action))
|
||||
{
|
||||
if(strcmp(value, "") == 0 || strcmp(value, "--") == 0) return;
|
||||
if(strcmp(data, "") == 0 || strcmp(data, "--") == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(_configUpdateReceivedCallback != NULL)
|
||||
{
|
||||
_configUpdateReceivedCallback(value);
|
||||
_configUpdateReceivedCallback(data);
|
||||
}
|
||||
|
||||
publishString(mqtt_topic_config_action, "--", true);
|
||||
@@ -453,11 +480,14 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
|
||||
|
||||
if(comparePrefixedPath(topic, mqtt_topic_keypad_json_action))
|
||||
{
|
||||
if(strcmp(value, "") == 0 || strcmp(value, "--") == 0) return;
|
||||
if(strcmp(data, "") == 0 || strcmp(data, "--") == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(_keypadJsonCommandReceivedReceivedCallback != NULL)
|
||||
{
|
||||
_keypadJsonCommandReceivedReceivedCallback(value);
|
||||
_keypadJsonCommandReceivedReceivedCallback(data);
|
||||
}
|
||||
|
||||
publishString(mqtt_topic_keypad_json_action, "--", true);
|
||||
@@ -465,11 +495,14 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
|
||||
|
||||
if(comparePrefixedPath(topic, mqtt_topic_timecontrol_action))
|
||||
{
|
||||
if(strcmp(value, "") == 0 || strcmp(value, "--") == 0) return;
|
||||
if(strcmp(data, "") == 0 || strcmp(data, "--") == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(_timeControlCommandReceivedReceivedCallback != NULL)
|
||||
{
|
||||
_timeControlCommandReceivedReceivedCallback(value);
|
||||
_timeControlCommandReceivedReceivedCallback(data);
|
||||
}
|
||||
|
||||
publishString(mqtt_topic_timecontrol_action, "--", true);
|
||||
@@ -477,11 +510,14 @@ void NukiNetworkLock::onMqttDataReceived(const char* topic, byte* payload, const
|
||||
|
||||
if(comparePrefixedPath(topic, mqtt_topic_auth_action))
|
||||
{
|
||||
if(strcmp(value, "") == 0 || strcmp(value, "--") == 0) return;
|
||||
if(strcmp(data, "") == 0 || strcmp(data, "--") == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(_authCommandReceivedReceivedCallback != NULL)
|
||||
{
|
||||
_authCommandReceivedReceivedCallback(value);
|
||||
_authCommandReceivedReceivedCallback(data);
|
||||
}
|
||||
|
||||
publishString(mqtt_topic_auth_action, "--", true);
|
||||
@@ -635,39 +671,39 @@ void NukiNetworkLock::publishState(NukiLock::LockState lockState)
|
||||
{
|
||||
switch(lockState)
|
||||
{
|
||||
case NukiLock::LockState::Locked:
|
||||
publishString(mqtt_topic_lock_ha_state, "locked", true);
|
||||
publishString(mqtt_topic_lock_binary_state, "locked", true);
|
||||
break;
|
||||
case NukiLock::LockState::Locking:
|
||||
publishString(mqtt_topic_lock_ha_state, "locking", true);
|
||||
publishString(mqtt_topic_lock_binary_state, "locked", true);
|
||||
break;
|
||||
case NukiLock::LockState::Unlocking:
|
||||
publishString(mqtt_topic_lock_ha_state, "unlocking", true);
|
||||
publishString(mqtt_topic_lock_binary_state, "unlocked", true);
|
||||
break;
|
||||
case NukiLock::LockState::Unlocked:
|
||||
case NukiLock::LockState::UnlockedLnga:
|
||||
publishString(mqtt_topic_lock_ha_state, "unlocked", true);
|
||||
publishString(mqtt_topic_lock_binary_state, "unlocked", true);
|
||||
break;
|
||||
case NukiLock::LockState::Unlatched:
|
||||
publishString(mqtt_topic_lock_ha_state, "open", true);
|
||||
publishString(mqtt_topic_lock_binary_state, "unlocked", true);
|
||||
break;
|
||||
case NukiLock::LockState::Unlatching:
|
||||
publishString(mqtt_topic_lock_ha_state, "opening", true);
|
||||
publishString(mqtt_topic_lock_binary_state, "unlocked", true);
|
||||
break;
|
||||
case NukiLock::LockState::Uncalibrated:
|
||||
case NukiLock::LockState::Calibration:
|
||||
case NukiLock::LockState::BootRun:
|
||||
case NukiLock::LockState::MotorBlocked:
|
||||
publishString(mqtt_topic_lock_ha_state, "jammed", true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case NukiLock::LockState::Locked:
|
||||
publishString(mqtt_topic_lock_ha_state, "locked", true);
|
||||
publishString(mqtt_topic_lock_binary_state, "locked", true);
|
||||
break;
|
||||
case NukiLock::LockState::Locking:
|
||||
publishString(mqtt_topic_lock_ha_state, "locking", true);
|
||||
publishString(mqtt_topic_lock_binary_state, "locked", true);
|
||||
break;
|
||||
case NukiLock::LockState::Unlocking:
|
||||
publishString(mqtt_topic_lock_ha_state, "unlocking", true);
|
||||
publishString(mqtt_topic_lock_binary_state, "unlocked", true);
|
||||
break;
|
||||
case NukiLock::LockState::Unlocked:
|
||||
case NukiLock::LockState::UnlockedLnga:
|
||||
publishString(mqtt_topic_lock_ha_state, "unlocked", true);
|
||||
publishString(mqtt_topic_lock_binary_state, "unlocked", true);
|
||||
break;
|
||||
case NukiLock::LockState::Unlatched:
|
||||
publishString(mqtt_topic_lock_ha_state, "open", true);
|
||||
publishString(mqtt_topic_lock_binary_state, "unlocked", true);
|
||||
break;
|
||||
case NukiLock::LockState::Unlatching:
|
||||
publishString(mqtt_topic_lock_ha_state, "opening", true);
|
||||
publishString(mqtt_topic_lock_binary_state, "unlocked", true);
|
||||
break;
|
||||
case NukiLock::LockState::Uncalibrated:
|
||||
case NukiLock::LockState::Calibration:
|
||||
case NukiLock::LockState::BootRun:
|
||||
case NukiLock::LockState::MotorBlocked:
|
||||
publishString(mqtt_topic_lock_ha_state, "jammed", true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -688,7 +724,10 @@ void NukiNetworkLock::publishAuthorizationInfo(const std::list<NukiLock::LogEntr
|
||||
{
|
||||
int sizeName = sizeof(log.name);
|
||||
memcpy(authName, log.name, sizeName);
|
||||
if(authName[sizeName - 1] != '\0') authName[sizeName] = '\0';
|
||||
if(authName[sizeName - 1] != '\0')
|
||||
{
|
||||
authName[sizeName] = '\0';
|
||||
}
|
||||
|
||||
if(log.index > authIndex)
|
||||
{
|
||||
@@ -714,7 +753,7 @@ void NukiNetworkLock::publishAuthorizationInfo(const std::list<NukiLock::LogEntr
|
||||
|
||||
if(entry["authorizationName"].as<String>().length() == 0 && _authEntries.count(log.authId) > 0)
|
||||
{
|
||||
entry["authorizationName"] = _authEntries[log.authId];
|
||||
entry["authorizationName"] = _authEntries[log.authId];
|
||||
}
|
||||
|
||||
entry["timeYear"] = log.timeStampYear;
|
||||
@@ -730,69 +769,75 @@ void NukiNetworkLock::publishAuthorizationInfo(const std::list<NukiLock::LogEntr
|
||||
|
||||
switch(log.loggingType)
|
||||
{
|
||||
case NukiLock::LoggingType::LockAction:
|
||||
memset(str, 0, sizeof(str));
|
||||
NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
|
||||
entry["action"] = str;
|
||||
case NukiLock::LoggingType::LockAction:
|
||||
memset(str, 0, sizeof(str));
|
||||
NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
|
||||
entry["action"] = str;
|
||||
|
||||
memset(str, 0, sizeof(str));
|
||||
NukiLock::triggerToString((NukiLock::Trigger)log.data[1], str);
|
||||
entry["trigger"] = str;
|
||||
memset(str, 0, sizeof(str));
|
||||
NukiLock::triggerToString((NukiLock::Trigger)log.data[1], str);
|
||||
entry["trigger"] = str;
|
||||
|
||||
memset(str, 0, sizeof(str));
|
||||
NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[3], str);
|
||||
memset(str, 0, sizeof(str));
|
||||
NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[3], str);
|
||||
entry["completionStatus"] = str;
|
||||
break;
|
||||
case NukiLock::LoggingType::KeypadAction:
|
||||
memset(str, 0, sizeof(str));
|
||||
NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
|
||||
entry["action"] = str;
|
||||
|
||||
switch(log.data[1])
|
||||
{
|
||||
case 0:
|
||||
entry["trigger"] = "arrowkey";
|
||||
break;
|
||||
case 1:
|
||||
entry["trigger"] = "code";
|
||||
break;
|
||||
case 2:
|
||||
entry["trigger"] = "fingerprint";
|
||||
break;
|
||||
default:
|
||||
entry["trigger"] = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
memset(str, 0, sizeof(str));
|
||||
|
||||
if(log.data[2] == 9)
|
||||
{
|
||||
entry["completionStatus"] = "notAuthorized";
|
||||
}
|
||||
else if (log.data[2] == 224)
|
||||
{
|
||||
entry["completionStatus"] = "invalidCode";
|
||||
}
|
||||
else
|
||||
{
|
||||
NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[2], str);
|
||||
entry["completionStatus"] = str;
|
||||
}
|
||||
|
||||
entry["codeId"] = 256U*log.data[4]+log.data[3];
|
||||
break;
|
||||
case NukiLock::LoggingType::DoorSensor:
|
||||
switch(log.data[0])
|
||||
{
|
||||
case 0:
|
||||
entry["action"] = "DoorOpened";
|
||||
break;
|
||||
case NukiLock::LoggingType::KeypadAction:
|
||||
memset(str, 0, sizeof(str));
|
||||
NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
|
||||
entry["action"] = str;
|
||||
|
||||
switch(log.data[1])
|
||||
{
|
||||
case 0:
|
||||
entry["trigger"] = "arrowkey";
|
||||
break;
|
||||
case 1:
|
||||
entry["trigger"] = "code";
|
||||
break;
|
||||
case 2:
|
||||
entry["trigger"] = "fingerprint";
|
||||
break;
|
||||
default:
|
||||
entry["trigger"] = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
memset(str, 0, sizeof(str));
|
||||
|
||||
if(log.data[2] == 9) entry["completionStatus"] = "notAuthorized";
|
||||
else if (log.data[2] == 224) entry["completionStatus"] = "invalidCode";
|
||||
else
|
||||
{
|
||||
NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[2], str);
|
||||
entry["completionStatus"] = str;
|
||||
}
|
||||
|
||||
entry["codeId"] = 256U*log.data[4]+log.data[3];
|
||||
case 1:
|
||||
entry["action"] = "DoorClosed";
|
||||
break;
|
||||
case NukiLock::LoggingType::DoorSensor:
|
||||
switch(log.data[0])
|
||||
{
|
||||
case 0:
|
||||
entry["action"] = "DoorOpened";
|
||||
break;
|
||||
case 1:
|
||||
entry["action"] = "DoorClosed";
|
||||
break;
|
||||
case 2:
|
||||
entry["action"] = "SensorJammed";
|
||||
break;
|
||||
default:
|
||||
entry["action"] = "Unknown";
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
entry["action"] = "SensorJammed";
|
||||
break;
|
||||
default:
|
||||
entry["action"] = "Unknown";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(log.index > _lastRollingLog)
|
||||
@@ -806,8 +851,14 @@ void NukiNetworkLock::publishAuthorizationInfo(const std::list<NukiLock::LogEntr
|
||||
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
|
||||
if(latest) publishString(mqtt_topic_lock_log_latest, _buffer, true);
|
||||
else publishString(mqtt_topic_lock_log, _buffer, true);
|
||||
if(latest)
|
||||
{
|
||||
publishString(mqtt_topic_lock_log_latest, _buffer, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
publishString(mqtt_topic_lock_log, _buffer, true);
|
||||
}
|
||||
|
||||
if(authIndex > 0)
|
||||
{
|
||||
@@ -1015,7 +1066,10 @@ void NukiNetworkLock::publishKeypad(const std::list<NukiLock::KeypadEntry>& entr
|
||||
|
||||
jsonEntry["codeId"] = entry.codeId;
|
||||
|
||||
if(publishCode) jsonEntry["code"] = entry.code;
|
||||
if(publishCode)
|
||||
{
|
||||
jsonEntry["code"] = entry.code;
|
||||
}
|
||||
jsonEntry["enabled"] = entry.enabled;
|
||||
jsonEntry["name"] = entry.name;
|
||||
char createdDT[20];
|
||||
@@ -1036,7 +1090,8 @@ void NukiNetworkLock::publishKeypad(const std::list<NukiLock::KeypadEntry>& entr
|
||||
uint8_t allowedWeekdaysInt = entry.allowedWeekdays;
|
||||
JsonArray weekdays = jsonEntry["allowedWeekdays"].to<JsonArray>();
|
||||
|
||||
while(allowedWeekdaysInt > 0) {
|
||||
while(allowedWeekdaysInt > 0)
|
||||
{
|
||||
if(allowedWeekdaysInt >= 64)
|
||||
{
|
||||
weekdays.add("mon");
|
||||
@@ -1113,24 +1168,26 @@ void NukiNetworkLock::publishKeypad(const std::list<NukiLock::KeypadEntry>& entr
|
||||
std::string displayName = std::string("Keypad - ") + std::string((char*)codeName) + " - " + std::to_string(entry.codeId);
|
||||
|
||||
_network->publishHassTopic("switch",
|
||||
mqttDeviceName.c_str(),
|
||||
uidString,
|
||||
uidStringPostfix.c_str(),
|
||||
displayName.c_str(),
|
||||
_nukiName,
|
||||
baseTopic.c_str(),
|
||||
String("~") + basePath.c_str(),
|
||||
(char*)"SmartLock",
|
||||
"",
|
||||
"",
|
||||
"diagnostic",
|
||||
String("~") + mqtt_topic_keypad_json_action,
|
||||
{ { (char*)"json_attr_t", (char*)basePathPrefixChr },
|
||||
{ (char*)"pl_on", (char*)enaCommand.c_str() },
|
||||
{ (char*)"pl_off", (char*)disCommand.c_str() },
|
||||
{ (char*)"val_tpl", (char*)"{{value_json.enabled}}" },
|
||||
{ (char*)"stat_on", (char*)"1" },
|
||||
{ (char*)"stat_off", (char*)"0" }});
|
||||
mqttDeviceName.c_str(),
|
||||
uidString,
|
||||
uidStringPostfix.c_str(),
|
||||
displayName.c_str(),
|
||||
_nukiName,
|
||||
baseTopic.c_str(),
|
||||
String("~") + basePath.c_str(),
|
||||
(char*)"SmartLock",
|
||||
"",
|
||||
"",
|
||||
"diagnostic",
|
||||
String("~") + mqtt_topic_keypad_json_action,
|
||||
{
|
||||
{ (char*)"json_attr_t", (char*)basePathPrefixChr },
|
||||
{ (char*)"pl_on", (char*)enaCommand.c_str() },
|
||||
{ (char*)"pl_off", (char*)disCommand.c_str() },
|
||||
{ (char*)"val_tpl", (char*)"{{value_json.enabled}}" },
|
||||
{ (char*)"stat_on", (char*)"1" },
|
||||
{ (char*)"stat_off", (char*)"0" }
|
||||
});
|
||||
}
|
||||
|
||||
++index;
|
||||
@@ -1204,7 +1261,10 @@ void NukiNetworkLock::publishKeypad(const std::list<NukiLock::KeypadEntry>& entr
|
||||
|
||||
void NukiNetworkLock::publishKeypadEntry(const String topic, NukiLock::KeypadEntry entry)
|
||||
{
|
||||
if(_disableNonJSON) return;
|
||||
if(_disableNonJSON)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char codeName[sizeof(entry.name) + 1];
|
||||
memset(codeName, 0, sizeof(codeName));
|
||||
@@ -1247,7 +1307,8 @@ void NukiNetworkLock::publishTimeControl(const std::list<NukiLock::TimeControlEn
|
||||
uint8_t weekdaysInt = entry.weekdays;
|
||||
JsonArray weekdays = jsonEntry["weekdays"].to<JsonArray>();
|
||||
|
||||
while(weekdaysInt > 0) {
|
||||
while(weekdaysInt > 0)
|
||||
{
|
||||
if(weekdaysInt >= 64)
|
||||
{
|
||||
weekdays.add("mon");
|
||||
@@ -1321,24 +1382,26 @@ void NukiNetworkLock::publishTimeControl(const std::list<NukiLock::TimeControlEn
|
||||
std::string displayName = std::string("Timecontrol - ") + std::to_string(entry.entryId);
|
||||
|
||||
_network->publishHassTopic("switch",
|
||||
mqttDeviceName.c_str(),
|
||||
uidString,
|
||||
uidStringPostfix.c_str(),
|
||||
displayName.c_str(),
|
||||
_nukiName,
|
||||
baseTopic.c_str(),
|
||||
String("~") + basePath.c_str(),
|
||||
(char*)"SmartLock",
|
||||
"",
|
||||
"",
|
||||
"diagnostic",
|
||||
String("~") + mqtt_topic_timecontrol_action,
|
||||
{ { (char*)"json_attr_t", (char*)basePathPrefixChr },
|
||||
{ (char*)"pl_on", (char*)enaCommand.c_str() },
|
||||
{ (char*)"pl_off", (char*)disCommand.c_str() },
|
||||
{ (char*)"val_tpl", (char*)"{{value_json.enabled}}" },
|
||||
{ (char*)"stat_on", (char*)"1" },
|
||||
{ (char*)"stat_off", (char*)"0" }});
|
||||
mqttDeviceName.c_str(),
|
||||
uidString,
|
||||
uidStringPostfix.c_str(),
|
||||
displayName.c_str(),
|
||||
_nukiName,
|
||||
baseTopic.c_str(),
|
||||
String("~") + basePath.c_str(),
|
||||
(char*)"SmartLock",
|
||||
"",
|
||||
"",
|
||||
"diagnostic",
|
||||
String("~") + mqtt_topic_timecontrol_action,
|
||||
{
|
||||
{ (char*)"json_attr_t", (char*)basePathPrefixChr },
|
||||
{ (char*)"pl_on", (char*)enaCommand.c_str() },
|
||||
{ (char*)"pl_off", (char*)disCommand.c_str() },
|
||||
{ (char*)"val_tpl", (char*)"{{value_json.enabled}}" },
|
||||
{ (char*)"stat_on", (char*)"1" },
|
||||
{ (char*)"stat_off", (char*)"0" }
|
||||
});
|
||||
}
|
||||
|
||||
++index;
|
||||
@@ -1395,7 +1458,8 @@ void NukiNetworkLock::publishAuth(const std::list<NukiLock::AuthorizationEntry>&
|
||||
uint8_t allowedWeekdaysInt = entry.allowedWeekdays;
|
||||
JsonArray weekdays = jsonEntry["allowedWeekdays"].to<JsonArray>();
|
||||
|
||||
while(allowedWeekdaysInt > 0) {
|
||||
while(allowedWeekdaysInt > 0)
|
||||
{
|
||||
if(allowedWeekdaysInt >= 64)
|
||||
{
|
||||
weekdays.add("mon");
|
||||
@@ -1468,24 +1532,26 @@ void NukiNetworkLock::publishAuth(const std::list<NukiLock::AuthorizationEntry>&
|
||||
std::string displayName = std::string("Authorization - ") + std::to_string(entry.authId);
|
||||
|
||||
_network->publishHassTopic("switch",
|
||||
mqttDeviceName.c_str(),
|
||||
uidString,
|
||||
uidStringPostfix.c_str(),
|
||||
displayName.c_str(),
|
||||
_nukiName,
|
||||
baseTopic.c_str(),
|
||||
String("~") + basePath.c_str(),
|
||||
(char*)"SmartLock",
|
||||
"",
|
||||
"",
|
||||
"diagnostic",
|
||||
String("~") + mqtt_topic_auth_action,
|
||||
{ { (char*)"json_attr_t", (char*)basePathPrefixChr },
|
||||
{ (char*)"pl_on", (char*)enaCommand.c_str() },
|
||||
{ (char*)"pl_off", (char*)disCommand.c_str() },
|
||||
{ (char*)"val_tpl", (char*)"{{value_json.enabled}}" },
|
||||
{ (char*)"stat_on", (char*)"1" },
|
||||
{ (char*)"stat_off", (char*)"0" }});
|
||||
mqttDeviceName.c_str(),
|
||||
uidString,
|
||||
uidStringPostfix.c_str(),
|
||||
displayName.c_str(),
|
||||
_nukiName,
|
||||
baseTopic.c_str(),
|
||||
String("~") + basePath.c_str(),
|
||||
(char*)"SmartLock",
|
||||
"",
|
||||
"",
|
||||
"diagnostic",
|
||||
String("~") + mqtt_topic_auth_action,
|
||||
{
|
||||
{ (char*)"json_attr_t", (char*)basePathPrefixChr },
|
||||
{ (char*)"pl_on", (char*)enaCommand.c_str() },
|
||||
{ (char*)"pl_off", (char*)disCommand.c_str() },
|
||||
{ (char*)"val_tpl", (char*)"{{value_json.enabled}}" },
|
||||
{ (char*)"stat_on", (char*)"1" },
|
||||
{ (char*)"stat_off", (char*)"0" }
|
||||
});
|
||||
}
|
||||
|
||||
++index;
|
||||
@@ -1512,7 +1578,10 @@ void NukiNetworkLock::publishConfigCommandResult(const char* result)
|
||||
|
||||
void NukiNetworkLock::publishKeypadCommandResult(const char* result)
|
||||
{
|
||||
if(_disableNonJSON) return;
|
||||
if(_disableNonJSON)
|
||||
{
|
||||
return;
|
||||
}
|
||||
publishString(mqtt_topic_keypad_command_result, result, true);
|
||||
}
|
||||
|
||||
@@ -1553,7 +1622,10 @@ void NukiNetworkLock::setConfigUpdateReceivedCallback(void (*configUpdateReceive
|
||||
|
||||
void NukiNetworkLock::setKeypadCommandReceivedCallback(void (*keypadCommandReceivedReceivedCallback)(const char* command, const uint& id, const String& name, const String& code, const int& enabled))
|
||||
{
|
||||
if(_disableNonJSON) return;
|
||||
if(_disableNonJSON)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_keypadCommandReceivedReceivedCallback = keypadCommandReceivedReceivedCallback;
|
||||
}
|
||||
|
||||
@@ -1606,7 +1678,7 @@ bool NukiNetworkLock::comparePrefixedPath(const char *fullPath, const char *subP
|
||||
}
|
||||
|
||||
void NukiNetworkLock::publishHASSConfig(char *deviceType, const char *baseTopic, char *name, char *uidString, const char *softwareVersion, const char *hardwareVersion, const bool& hasDoorSensor, const bool& hasKeypad, const bool& publishAuthData, char *lockAction,
|
||||
char *unlockAction, char *openAction)
|
||||
char *unlockAction, char *openAction)
|
||||
{
|
||||
_network->publishHASSConfig(deviceType, baseTopic, name, uidString, softwareVersion, hardwareVersion, "~/maintenance/mqttConnectionState", hasKeypad, lockAction, unlockAction, openAction);
|
||||
_network->publishHASSConfigAdditionalLockEntities(deviceType, baseTopic, name, uidString);
|
||||
@@ -1620,9 +1692,9 @@ void NukiNetworkLock::publishHASSConfig(char *deviceType, const char *baseTopic,
|
||||
_network->removeHASSConfigTopic((char*)"binary_sensor", (char*)"door_sensor", uidString);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
_network->publishHASSWifiRssiConfig(deviceType, baseTopic, name, uidString);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if(publishAuthData)
|
||||
{
|
||||
@@ -1721,76 +1793,82 @@ uint8_t NukiNetworkLock::queryCommands()
|
||||
return qc;
|
||||
}
|
||||
|
||||
void NukiNetworkLock::buttonPressActionToString(const NukiLock::ButtonPressAction btnPressAction, char* str) {
|
||||
switch (btnPressAction) {
|
||||
void NukiNetworkLock::buttonPressActionToString(const NukiLock::ButtonPressAction btnPressAction, char* str)
|
||||
{
|
||||
switch (btnPressAction)
|
||||
{
|
||||
case NukiLock::ButtonPressAction::NoAction:
|
||||
strcpy(str, "No Action");
|
||||
break;
|
||||
strcpy(str, "No Action");
|
||||
break;
|
||||
case NukiLock::ButtonPressAction::Intelligent:
|
||||
strcpy(str, "Intelligent");
|
||||
break;
|
||||
strcpy(str, "Intelligent");
|
||||
break;
|
||||
case NukiLock::ButtonPressAction::Unlock:
|
||||
strcpy(str, "Unlock");
|
||||
break;
|
||||
strcpy(str, "Unlock");
|
||||
break;
|
||||
case NukiLock::ButtonPressAction::Lock:
|
||||
strcpy(str, "Lock");
|
||||
break;
|
||||
strcpy(str, "Lock");
|
||||
break;
|
||||
case NukiLock::ButtonPressAction::Unlatch:
|
||||
strcpy(str, "Unlatch");
|
||||
break;
|
||||
strcpy(str, "Unlatch");
|
||||
break;
|
||||
case NukiLock::ButtonPressAction::LockNgo:
|
||||
strcpy(str, "Lock n Go");
|
||||
break;
|
||||
strcpy(str, "Lock n Go");
|
||||
break;
|
||||
case NukiLock::ButtonPressAction::ShowStatus:
|
||||
strcpy(str, "Show Status");
|
||||
break;
|
||||
strcpy(str, "Show Status");
|
||||
break;
|
||||
default:
|
||||
strcpy(str, "undefined");
|
||||
break;
|
||||
}
|
||||
strcpy(str, "undefined");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NukiNetworkLock::homeKitStatusToString(const int hkstatus, char* str) {
|
||||
switch (hkstatus) {
|
||||
void NukiNetworkLock::homeKitStatusToString(const int hkstatus, char* str)
|
||||
{
|
||||
switch (hkstatus)
|
||||
{
|
||||
case 0:
|
||||
strcpy(str, "Not Available");
|
||||
break;
|
||||
strcpy(str, "Not Available");
|
||||
break;
|
||||
case 1:
|
||||
strcpy(str, "Disabled");
|
||||
break;
|
||||
strcpy(str, "Disabled");
|
||||
break;
|
||||
case 2:
|
||||
strcpy(str, "Enabled");
|
||||
break;
|
||||
strcpy(str, "Enabled");
|
||||
break;
|
||||
case 3:
|
||||
strcpy(str, "Enabled & Paired");
|
||||
break;
|
||||
strcpy(str, "Enabled & Paired");
|
||||
break;
|
||||
default:
|
||||
strcpy(str, "undefined");
|
||||
break;
|
||||
}
|
||||
strcpy(str, "undefined");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NukiNetworkLock::fobActionToString(const int fobact, char* str) {
|
||||
switch (fobact) {
|
||||
void NukiNetworkLock::fobActionToString(const int fobact, char* str)
|
||||
{
|
||||
switch (fobact)
|
||||
{
|
||||
case 0:
|
||||
strcpy(str, "No Action");
|
||||
break;
|
||||
strcpy(str, "No Action");
|
||||
break;
|
||||
case 1:
|
||||
strcpy(str, "Unlock");
|
||||
break;
|
||||
strcpy(str, "Unlock");
|
||||
break;
|
||||
case 2:
|
||||
strcpy(str, "Lock");
|
||||
break;
|
||||
strcpy(str, "Lock");
|
||||
break;
|
||||
case 3:
|
||||
strcpy(str, "Lock n Go");
|
||||
break;
|
||||
strcpy(str, "Lock n Go");
|
||||
break;
|
||||
case 4:
|
||||
strcpy(str, "Intelligent");
|
||||
break;
|
||||
strcpy(str, "Intelligent");
|
||||
break;
|
||||
default:
|
||||
strcpy(str, "undefined");
|
||||
break;
|
||||
}
|
||||
strcpy(str, "undefined");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t NukiNetworkLock::getAuthId() const
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
#include "LockActionResult.h"
|
||||
#include "NukiOfficial.h"
|
||||
#include "NukiPublisher.h"
|
||||
|
||||
#define LOCK_LOG_JSON_BUFFER_SIZE 2048
|
||||
#include "EspMillis.h"
|
||||
|
||||
class NukiNetworkLock : public MqttReceiver
|
||||
{
|
||||
@@ -58,7 +57,7 @@ public:
|
||||
void setKeypadJsonCommandReceivedCallback(void (*keypadJsonCommandReceivedReceivedCallback)(const char* value));
|
||||
void setTimeControlCommandReceivedCallback(void (*timeControlCommandReceivedReceivedCallback)(const char* value));
|
||||
void setAuthCommandReceivedCallback(void (*authCommandReceivedReceivedCallback)(const char* value));
|
||||
void onMqttDataReceived(const char* topic, byte* payload, const unsigned int length) override;
|
||||
void onMqttDataReceived(char* topic, int topic_len, char* data, int data_len) override;
|
||||
|
||||
void publishFloat(const char* topic, const float value, bool retain, const uint8_t precision = 2);
|
||||
void publishInt(const char* topic, const int value, bool retain);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@
|
||||
#include "NukiConstants.h"
|
||||
#include "NukiOpenerConstants.h"
|
||||
#include "NukiNetworkLock.h"
|
||||
#include "EspMillis.h"
|
||||
|
||||
class NukiNetworkOpener : public MqttReceiver
|
||||
{
|
||||
@@ -47,7 +48,7 @@ public:
|
||||
void setKeypadJsonCommandReceivedCallback(void (*keypadJsonCommandReceivedReceivedCallback)(const char* value));
|
||||
void setTimeControlCommandReceivedCallback(void (*timeControlCommandReceivedReceivedCallback)(const char* value));
|
||||
void setAuthCommandReceivedCallback(void (*authCommandReceivedReceivedCallback)(const char* value));
|
||||
void onMqttDataReceived(const char* topic, byte* payload, const unsigned int length) override;
|
||||
void onMqttDataReceived(char* topic, int topic_len, char* data, int data_len) override;
|
||||
|
||||
bool reconnected();
|
||||
uint8_t queryCommands();
|
||||
|
||||
@@ -136,7 +136,10 @@ void NukiOfficial::onOfficialUpdateReceived(const char *topic, const char *value
|
||||
Log->print(F("Battery critical: "));
|
||||
Log->println(offCritical);
|
||||
|
||||
if(!_disableNonJSON) _publisher->publishBool(mqtt_topic_battery_critical, offCritical, true);
|
||||
if(!_disableNonJSON)
|
||||
{
|
||||
_publisher->publishBool(mqtt_topic_battery_critical, offCritical, true);
|
||||
}
|
||||
publishBatteryJson = true;
|
||||
}
|
||||
else if(strcmp(topic, mqtt_topic_official_batteryCharging) == 0)
|
||||
@@ -146,7 +149,10 @@ void NukiOfficial::onOfficialUpdateReceived(const char *topic, const char *value
|
||||
Log->print(F("Battery charging: "));
|
||||
Log->println(offCharging);
|
||||
|
||||
if(!_disableNonJSON) _publisher->publishBool(mqtt_topic_battery_charging, offCharging, true);
|
||||
if(!_disableNonJSON)
|
||||
{
|
||||
_publisher->publishBool(mqtt_topic_battery_charging, offCharging, true);
|
||||
}
|
||||
publishBatteryJson = true;
|
||||
}
|
||||
else if(strcmp(topic, mqtt_topic_official_batteryChargeState) == 0)
|
||||
@@ -156,19 +162,28 @@ void NukiOfficial::onOfficialUpdateReceived(const char *topic, const char *value
|
||||
Log->print(F("Battery level: "));
|
||||
Log->println(offChargeState);
|
||||
|
||||
if(!_disableNonJSON) _publisher->publishInt(mqtt_topic_battery_level, offChargeState, true);
|
||||
if(!_disableNonJSON)
|
||||
{
|
||||
_publisher->publishInt(mqtt_topic_battery_level, offChargeState, true);
|
||||
}
|
||||
publishBatteryJson = true;
|
||||
}
|
||||
else if(strcmp(topic, mqtt_topic_official_keypadBatteryCritical) == 0)
|
||||
{
|
||||
offKeypadCritical = (strcmp(value, "true") == 0 ? 1 : 0);
|
||||
if(!_disableNonJSON) _publisher->publishBool(mqtt_topic_battery_keypad_critical, offKeypadCritical, true);
|
||||
if(!_disableNonJSON)
|
||||
{
|
||||
_publisher->publishBool(mqtt_topic_battery_keypad_critical, offKeypadCritical, true);
|
||||
}
|
||||
publishBatteryJson = true;
|
||||
}
|
||||
else if(strcmp(topic, mqtt_topic_official_doorsensorBatteryCritical) == 0)
|
||||
{
|
||||
offDoorsensorCritical = (strcmp(value, "true") == 0 ? 1 : 0);
|
||||
if(!_disableNonJSON) _publisher->publishBool(mqtt_topic_battery_doorsensor_critical, offDoorsensorCritical, true);
|
||||
if(!_disableNonJSON)
|
||||
{
|
||||
_publisher->publishBool(mqtt_topic_battery_doorsensor_critical, offDoorsensorCritical, true);
|
||||
}
|
||||
publishBatteryJson = true;
|
||||
}
|
||||
else if(strcmp(topic, mqtt_topic_official_commandResponse) == 0)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,8 +2,8 @@
|
||||
|
||||
|
||||
NukiPublisher::NukiPublisher(NukiNetwork *network, const char* mqttPath)
|
||||
: _network(network),
|
||||
_mqttPath(mqttPath)
|
||||
: _network(network),
|
||||
_mqttPath(mqttPath)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
1742
src/NukiWrapper.cpp
1742
src/NukiWrapper.cpp
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@
|
||||
#include "LockActionResult.h"
|
||||
#include "NukiDeviceId.h"
|
||||
#include "NukiOfficial.h"
|
||||
#include "EspMillis.h"
|
||||
|
||||
class NukiWrapper : public Nuki::SmartlockEventHandler
|
||||
{
|
||||
|
||||
@@ -52,9 +52,10 @@
|
||||
#define preference_update_from_mqtt (char*)"updMqtt"
|
||||
#define preference_disable_non_json (char*)"disnonjson"
|
||||
#define preference_official_hybrid_enabled (char*)"offHybrid"
|
||||
#define preference_wifi_ssid (char*)"wifiSSID"
|
||||
#define preference_wifi_pass (char*)"wifiPass"
|
||||
|
||||
// CHANGE DOES NOT REQUIRE REBOOT TO TAKE EFFECT
|
||||
#define preference_find_best_rssi (char*)"nwbestrssi"
|
||||
#define preference_ntw_reconfigure (char*)"ntwRECONF"
|
||||
#define preference_auth_max_entries (char*)"authmaxentry"
|
||||
#define preference_auth_info_enabled (char*)"authInfoEna"
|
||||
@@ -88,14 +89,12 @@
|
||||
#define preference_command_retry_delay (char*)"rtryDelay"
|
||||
#define preference_query_interval_hybrid_lockstate (char*)"hybridTimer"
|
||||
#define preference_mqtt_hass_cu_url (char*)"hassConfigUrl"
|
||||
#define preference_network_wifi_fallback_disabled (char*)"nwwififb"
|
||||
#define preference_check_updates (char*)"checkupdates"
|
||||
#define preference_opener_continuous_mode (char*)"openercont"
|
||||
#define preference_rssi_publish_interval (char*)"rssipb"
|
||||
#define preference_network_timeout (char*)"nettmout"
|
||||
#define preference_restart_on_disconnect (char*)"restdisc"
|
||||
#define preference_publish_debug_info (char*)"pubdbg"
|
||||
#define preference_recon_netw_on_mqtt_discon (char*)"recNtwMqttDis"
|
||||
#define preference_official_hybrid_actions (char*)"hybridAct"
|
||||
#define preference_official_hybrid_retry (char*)"hybridRtry"
|
||||
#define preference_keypad_check_code_enabled (char*)"kpChkEna"
|
||||
@@ -119,12 +118,14 @@
|
||||
#define preference_lock_max_timecontrol_entry_count (char*)"maxtc"
|
||||
#define preference_opener_max_timecontrol_entry_count (char*)"opmaxtc"
|
||||
#define preference_latest_version (char*)"latest"
|
||||
#define preference_wifi_converted (char*)"wifiConv"
|
||||
|
||||
//OBSOLETE
|
||||
#define preference_access_level (char*)"accLvl"
|
||||
#define preference_gpio_locking_enabled (char*)"gpiolck"
|
||||
#define preference_network_hardware_gpio (char*)"nwhwdt"
|
||||
#define preference_presence_detection_timeout (char*)"prdtimeout"
|
||||
#define preference_network_wifi_fallback_disabled (char*)"nwwififb"
|
||||
|
||||
inline bool initPreferences(Preferences* preferences)
|
||||
{
|
||||
@@ -249,9 +250,15 @@ inline bool initPreferences(Preferences* preferences)
|
||||
if (configVer < 901)
|
||||
{
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
if (preferences->getInt(preference_network_hardware) == 3) preferences->putInt(preference_network_hardware, 10);
|
||||
if (preferences->getInt(preference_network_hardware) == 3)
|
||||
{
|
||||
preferences->putInt(preference_network_hardware, 10);
|
||||
}
|
||||
#endif
|
||||
if (preferences->getInt(preference_network_hardware) == 2) preferences->putInt(preference_network_hardware, 3);
|
||||
if (preferences->getInt(preference_network_hardware) == 2)
|
||||
{
|
||||
preferences->putInt(preference_network_hardware, 3);
|
||||
}
|
||||
}
|
||||
|
||||
preferences->putInt(preference_config_version, atof(NUKI_HUB_VERSION) * 100);
|
||||
@@ -272,8 +279,8 @@ private:
|
||||
preference_opener_continuous_mode, preference_mqtt_opener_path, preference_lock_max_keypad_code_count, preference_opener_max_keypad_code_count,
|
||||
preference_lock_max_timecontrol_entry_count, preference_opener_max_timecontrol_entry_count, preference_enable_bootloop_reset, preference_mqtt_ca, preference_mqtt_crt,
|
||||
preference_mqtt_key, preference_mqtt_hass_discovery, preference_mqtt_hass_cu_url, preference_buffer_size, preference_ip_dhcp_enabled, preference_ip_address,
|
||||
preference_ip_subnet, preference_ip_gateway, preference_ip_dns_server, preference_network_hardware, preference_network_wifi_fallback_disabled,
|
||||
preference_rssi_publish_interval, preference_hostname, preference_find_best_rssi, preference_network_timeout, preference_restart_on_disconnect,
|
||||
preference_ip_subnet, preference_ip_gateway, preference_ip_dns_server, preference_network_hardware,
|
||||
preference_rssi_publish_interval, preference_hostname, preference_network_timeout, preference_restart_on_disconnect,
|
||||
preference_restart_ble_beacon_lost, preference_query_interval_lockstate, preference_timecontrol_topic_per_entry, preference_keypad_topic_per_entry,
|
||||
preference_query_interval_configuration, preference_query_interval_battery, preference_query_interval_keypad, preference_keypad_control_enabled,
|
||||
preference_keypad_info_enabled, preference_keypad_publish_code, preference_timecontrol_control_enabled, preference_timecontrol_info_enabled, preference_conf_info_enabled,
|
||||
@@ -281,26 +288,26 @@ private:
|
||||
preference_cred_password, preference_disable_non_json, preference_publish_authdata, preference_publish_debug_info,
|
||||
preference_official_hybrid_enabled, preference_query_interval_hybrid_lockstate, preference_official_hybrid_actions, preference_official_hybrid_retry,
|
||||
preference_task_size_network, preference_task_size_nuki, preference_authlog_max_entries, preference_keypad_max_entries, preference_timecontrol_max_entries,
|
||||
preference_update_from_mqtt, preference_show_secrets, preference_ble_tx_power, preference_recon_netw_on_mqtt_discon, preference_webserial_enabled,
|
||||
preference_update_from_mqtt, preference_show_secrets, preference_ble_tx_power, preference_webserial_enabled,
|
||||
preference_network_custom_mdc, preference_network_custom_clk, preference_network_custom_phy, preference_network_custom_addr, preference_network_custom_irq,
|
||||
preference_network_custom_rst, preference_network_custom_cs, preference_network_custom_sck, preference_network_custom_miso, preference_network_custom_mosi,
|
||||
preference_network_custom_pwr, preference_network_custom_mdio, preference_ntw_reconfigure, preference_lock_max_auth_entry_count, preference_opener_max_auth_entry_count,
|
||||
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_auth_max_entries, preference_keypad_check_code_enabled
|
||||
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_auth_max_entries, preference_keypad_check_code_enabled, preference_wifi_ssid, preference_wifi_pass
|
||||
};
|
||||
std::vector<char*> _redact =
|
||||
{
|
||||
preference_mqtt_user, preference_mqtt_password, preference_mqtt_ca, preference_mqtt_crt, preference_mqtt_key, preference_cred_user, preference_cred_password,
|
||||
preference_nuki_id_lock, preference_nuki_id_opener,
|
||||
preference_nuki_id_lock, preference_nuki_id_opener, preference_wifi_pass
|
||||
};
|
||||
std::vector<char*> _boolPrefs =
|
||||
{
|
||||
preference_started_before, preference_mqtt_log_enabled, preference_check_updates, preference_lock_enabled, preference_opener_enabled, preference_opener_continuous_mode,
|
||||
preference_timecontrol_topic_per_entry, preference_keypad_topic_per_entry, preference_enable_bootloop_reset, preference_webserver_enabled, preference_find_best_rssi,
|
||||
preference_timecontrol_topic_per_entry, preference_keypad_topic_per_entry, preference_enable_bootloop_reset, preference_webserver_enabled,
|
||||
preference_restart_on_disconnect, preference_keypad_control_enabled, preference_keypad_info_enabled, preference_keypad_publish_code, preference_show_secrets,
|
||||
preference_timecontrol_control_enabled, preference_timecontrol_info_enabled, preference_register_as_app, preference_register_opener_as_app, preference_ip_dhcp_enabled,
|
||||
preference_publish_authdata, preference_publish_debug_info, preference_network_wifi_fallback_disabled, preference_official_hybrid_enabled,
|
||||
preference_publish_authdata, preference_publish_debug_info, preference_official_hybrid_enabled,
|
||||
preference_official_hybrid_actions, preference_official_hybrid_retry, preference_conf_info_enabled, preference_disable_non_json, preference_update_from_mqtt,
|
||||
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_recon_netw_on_mqtt_discon, preference_webserial_enabled,
|
||||
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_webserial_enabled,
|
||||
preference_ntw_reconfigure, preference_keypad_check_code_enabled
|
||||
};
|
||||
std::vector<char*> _bytePrefs =
|
||||
|
||||
@@ -33,12 +33,9 @@ enum class RestartReason
|
||||
extern int restartReason;
|
||||
extern uint64_t restartReasonValidDetect;
|
||||
extern bool rebuildGpioRequested;
|
||||
|
||||
extern RestartReason currentRestartReason;
|
||||
|
||||
extern bool restartReason_isValid;
|
||||
|
||||
|
||||
inline static void restartEsp(RestartReason reason)
|
||||
{
|
||||
if(reason == RestartReason::GpioConfigurationUpdated)
|
||||
|
||||
3998
src/WebCfgServer.cpp
3998
src/WebCfgServer.cpp
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <Preferences.h>
|
||||
#include <AsyncTCP.h>
|
||||
#include <DNSServer.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <PsychicHttp.h>
|
||||
#include <PsychicHttpsServer.h>
|
||||
#include "esp_ota_ops.h"
|
||||
#include "Config.h"
|
||||
|
||||
@@ -37,9 +36,9 @@ class WebCfgServer
|
||||
{
|
||||
public:
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
WebCfgServer(NukiWrapper* nuki, NukiOpenerWrapper* nukiOpener, NukiNetwork* network, Gpio* gpio, Preferences* preferences, bool allowRestartToPortal, uint8_t partitionType, AsyncWebServer* asyncServer);
|
||||
WebCfgServer(NukiWrapper* nuki, NukiOpenerWrapper* nukiOpener, NukiNetwork* network, Gpio* gpio, Preferences* preferences, bool allowRestartToPortal, uint8_t partitionType, PsychicHttpServer* psychicServer);
|
||||
#else
|
||||
WebCfgServer(NukiNetwork* network, Preferences* preferences, bool allowRestartToPortal, uint8_t partitionType, AsyncWebServer* asyncServer);
|
||||
WebCfgServer(NukiNetwork* network, Preferences* preferences, bool allowRestartToPortal, uint8_t partitionType, PsychicHttpServer* psychicServer);
|
||||
#endif
|
||||
~WebCfgServer() = default;
|
||||
|
||||
@@ -47,34 +46,31 @@ public:
|
||||
|
||||
private:
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
void sendSettings(AsyncWebServerRequest *request);
|
||||
bool processArgs(AsyncWebServerRequest *request, String& message);
|
||||
bool processImport(AsyncWebServerRequest *request, String& message);
|
||||
void processGpioArgs(AsyncWebServerRequest *request);
|
||||
void buildHtml(AsyncWebServerRequest *request);
|
||||
void buildAccLvlHtml(AsyncWebServerRequest *request);
|
||||
void buildCredHtml(AsyncWebServerRequest *request);
|
||||
void buildImportExportHtml(AsyncWebServerRequest *request);
|
||||
void buildMqttConfigHtml(AsyncWebServerRequest *request);
|
||||
void buildStatusHtml(AsyncWebServerRequest *request);
|
||||
void buildAdvancedConfigHtml(AsyncWebServerRequest *request);
|
||||
void buildNukiConfigHtml(AsyncWebServerRequest *request);
|
||||
void buildGpioConfigHtml(AsyncWebServerRequest *request);
|
||||
esp_err_t sendSettings(PsychicRequest *request);
|
||||
bool processArgs(PsychicRequest *request, String& message);
|
||||
bool processImport(PsychicRequest *request, String& message);
|
||||
void processGpioArgs(PsychicRequest *request);
|
||||
esp_err_t buildHtml(PsychicRequest *request);
|
||||
esp_err_t buildAccLvlHtml(PsychicRequest *request);
|
||||
esp_err_t buildCredHtml(PsychicRequest *request);
|
||||
esp_err_t buildImportExportHtml(PsychicRequest *request);
|
||||
esp_err_t buildMqttConfigHtml(PsychicRequest *request);
|
||||
esp_err_t buildStatusHtml(PsychicRequest *request);
|
||||
esp_err_t buildAdvancedConfigHtml(PsychicRequest *request);
|
||||
esp_err_t buildNukiConfigHtml(PsychicRequest *request);
|
||||
esp_err_t buildGpioConfigHtml(PsychicRequest *request);
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
void buildConfigureWifiHtml(AsyncWebServerRequest *request);
|
||||
esp_err_t buildConfigureWifiHtml(PsychicRequest *request);
|
||||
#endif
|
||||
void buildInfoHtml(AsyncWebServerRequest *request);
|
||||
void buildCustomNetworkConfigHtml(AsyncWebServerRequest *request);
|
||||
void processUnpair(AsyncWebServerRequest *request, bool opener);
|
||||
void processUpdate(AsyncWebServerRequest *request);
|
||||
void processFactoryReset(AsyncWebServerRequest *request);
|
||||
void printInputField(const char* token, const char* description, const char* value, const size_t& maxLength, const char* args, const bool& isPassword = false, const bool& showLengthRestriction = false);
|
||||
void printInputField(const char* token, const char* description, const int value, size_t maxLength, const char* args);
|
||||
void printCheckBox(const char* token, const char* description, const bool value, const char* htmlClass);
|
||||
void printTextarea(const char *token, const char *description, const char *value, const size_t& maxLength, const bool& enabled = true, const bool& showLengthRestriction = false);
|
||||
void printDropDown(const char *token, const char *description, const String preselectedValue, std::vector<std::pair<String, String>> options, const String className);
|
||||
void buildNavigationButton(const char* caption, const char* targetPath, const char* labelText = "");
|
||||
void buildNavigationMenuEntry(const char *title, const char *targetPath, const char* warningMessage = "");
|
||||
esp_err_t buildInfoHtml(PsychicRequest *request);
|
||||
esp_err_t buildCustomNetworkConfigHtml(PsychicRequest *request);
|
||||
esp_err_t processUnpair(PsychicRequest *request, bool opener);
|
||||
esp_err_t processUpdate(PsychicRequest *request);
|
||||
esp_err_t processFactoryReset(PsychicRequest *request);
|
||||
void printTextarea(PsychicStreamResponse *response, const char *token, const char *description, const char *value, const size_t& maxLength, const bool& enabled = true, const bool& showLengthRestriction = false);
|
||||
void printDropDown(PsychicStreamResponse *response, const char *token, const char *description, const String preselectedValue, std::vector<std::pair<String, String>> options, const String className);
|
||||
void buildNavigationButton(PsychicStreamResponse *response, const char* caption, const char* targetPath, const char* labelText = "");
|
||||
void buildNavigationMenuEntry(PsychicStreamResponse *response, const char *title, const char *targetPath, const char* warningMessage = "");
|
||||
|
||||
const std::vector<std::pair<String, String>> getNetworkDetectionOptions() const;
|
||||
const std::vector<std::pair<String, String>> getGpioOptions() const;
|
||||
@@ -86,8 +82,8 @@ private:
|
||||
String getPreselectionForGpio(const uint8_t& pin);
|
||||
String pinStateToString(uint8_t value);
|
||||
|
||||
void printParameter(const char* description, const char* value, const char *link = "", const char *id = "");
|
||||
|
||||
void printParameter(PsychicStreamResponse *response, const char* description, const char* value, const char *link = "", const char *id = "");
|
||||
|
||||
NukiWrapper* _nuki = nullptr;
|
||||
NukiOpenerWrapper* _nukiOpener = nullptr;
|
||||
Gpio* _gpio = nullptr;
|
||||
@@ -95,22 +91,32 @@ private:
|
||||
bool _brokerConfigured = false;
|
||||
bool _rebootRequired = false;
|
||||
#endif
|
||||
|
||||
String _response;
|
||||
|
||||
std::vector<String> _ssidList;
|
||||
std::vector<int> _rssiList;
|
||||
String generateConfirmCode();
|
||||
String _confirmCode = "----";
|
||||
void buildConfirmHtml(AsyncWebServerRequest *request, const String &message, uint32_t redirectDelay = 5, bool redirect = false);
|
||||
void buildOtaHtml(AsyncWebServerRequest *request, bool debug = false);
|
||||
void buildOtaCompletedHtml(AsyncWebServerRequest *request);
|
||||
void sendCss(AsyncWebServerRequest *request);
|
||||
void sendFavicon(AsyncWebServerRequest *request);
|
||||
void buildHtmlHeader(String additionalHeader = "");
|
||||
esp_err_t buildSSIDListHtml(PsychicRequest *request);
|
||||
esp_err_t buildConfirmHtml(PsychicRequest *request, const String &message, uint32_t redirectDelay = 5, bool redirect = false);
|
||||
esp_err_t buildOtaHtml(PsychicRequest *request, bool debug = false);
|
||||
esp_err_t buildOtaCompletedHtml(PsychicRequest *request);
|
||||
esp_err_t sendCss(PsychicRequest *request);
|
||||
esp_err_t sendFavicon(PsychicRequest *request);
|
||||
void createSsidList();
|
||||
void buildHtmlHeader(PsychicStreamResponse *response, String additionalHeader = "");
|
||||
void waitAndProcess(const bool blocking, const uint32_t duration);
|
||||
void handleOtaUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
|
||||
esp_err_t handleOtaUpload(PsychicRequest *request, const String& filename, uint64_t index, uint8_t *data, size_t len, bool final);
|
||||
void printCheckBox(PsychicStreamResponse *response, const char* token, const char* description, const bool value, const char* htmlClass);
|
||||
void printProgress(size_t prg, size_t sz);
|
||||
void sendResponse(AsyncWebServerRequest *request);
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
esp_err_t buildWifiConnectHtml(PsychicRequest *request);
|
||||
bool processWiFi(PsychicRequest *request, String& message);
|
||||
|
||||
AsyncWebServer* _asyncServer = nullptr;
|
||||
#endif
|
||||
void printInputField(PsychicStreamResponse *response, const char* token, const char* description, const char* value, const size_t& maxLength, const char* args, const bool& isPassword = false, const bool& showLengthRestriction = false);
|
||||
void printInputField(PsychicStreamResponse *response, const char* token, const char* description, const int value, size_t maxLength, const char* args);
|
||||
|
||||
PsychicHttpServer* _psychicServer = nullptr;
|
||||
NukiNetwork* _network = nullptr;
|
||||
Preferences* _preferences = nullptr;
|
||||
|
||||
|
||||
263
src/main.cpp
263
src/main.cpp
@@ -5,7 +5,7 @@
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_http_client.h"
|
||||
#include "esp_https_ota.h"
|
||||
#include <esp_task_wdt.h>
|
||||
#include "esp_task_wdt.h"
|
||||
#include "Config.h"
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
@@ -19,11 +19,14 @@
|
||||
#include "Logger.h"
|
||||
#include "PreferencesKeys.h"
|
||||
#include "RestartReason.h"
|
||||
#include <AsyncTCP.h>
|
||||
#include <DNSServer.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include "EspMillis.h"
|
||||
|
||||
/*
|
||||
#ifdef DEBUG_NUKIHUB
|
||||
#include <WString.h>
|
||||
#include <MycilaWebSerial.h>
|
||||
#endif
|
||||
*/
|
||||
|
||||
char log_print_buffer[1024];
|
||||
|
||||
@@ -50,12 +53,13 @@ int64_t restartTs = ((2^64) - (5 * 1000 * 60000)) / 1000;
|
||||
#include "../../src/PreferencesKeys.h"
|
||||
#include "../../src/RestartReason.h"
|
||||
#include "../../src/NukiNetwork.h"
|
||||
#include "../../src/EspMillis.h"
|
||||
|
||||
int64_t restartTs = 10 * 1000 * 60000;
|
||||
|
||||
#endif
|
||||
|
||||
AsyncWebServer* asyncServer = nullptr;
|
||||
PsychicHttpServer* psychicServer = nullptr;
|
||||
NukiNetwork* network = nullptr;
|
||||
WebCfgServer* webCfgServer = nullptr;
|
||||
Preferences* preferences = nullptr;
|
||||
@@ -76,9 +80,8 @@ TaskHandle_t networkTaskHandle = nullptr;
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
ssize_t write_fn(void* cookie, const char* buf, ssize_t size)
|
||||
{
|
||||
Log->write((uint8_t *)buf, (size_t)size);
|
||||
|
||||
return size;
|
||||
Log->write((uint8_t *)buf, (size_t)size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void ets_putc_handler(char c)
|
||||
@@ -87,23 +90,31 @@ void ets_putc_handler(char c)
|
||||
static size_t buf_pos = 0;
|
||||
buf[buf_pos] = c;
|
||||
buf_pos++;
|
||||
if (c == '\n' || buf_pos == sizeof(buf)) {
|
||||
if (c == '\n' || buf_pos == sizeof(buf))
|
||||
{
|
||||
write_fn(NULL, buf, buf_pos);
|
||||
buf_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int _log_vprintf(const char *fmt, va_list args) {
|
||||
int _log_vprintf(const char *fmt, va_list args)
|
||||
{
|
||||
int ret = vsnprintf(log_print_buffer, sizeof(log_print_buffer), fmt, args);
|
||||
if (ret >= 0){
|
||||
if (ret >= 0)
|
||||
{
|
||||
Log->write((uint8_t *)log_print_buffer, (size_t)ret);
|
||||
}
|
||||
return 0; //return vprintf(fmt, args);
|
||||
}
|
||||
|
||||
void setReroute(){
|
||||
void setReroute()
|
||||
{
|
||||
esp_log_set_vprintf(_log_vprintf);
|
||||
if(preferences->getBool(preference_mqtt_log_enabled)) esp_log_level_set("*", ESP_LOG_INFO);
|
||||
if(preferences->getBool(preference_mqtt_log_enabled))
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("mqtt", ESP_LOG_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_DEBUG);
|
||||
@@ -123,7 +134,7 @@ void networkTask(void *pvParameters)
|
||||
}
|
||||
while(true)
|
||||
{
|
||||
int64_t ts = (esp_timer_get_time() / 1000);
|
||||
int64_t ts = espMillis();
|
||||
if(ts > 120000 && ts < 125000)
|
||||
{
|
||||
if(bootloopCounter > 0)
|
||||
@@ -148,13 +159,16 @@ void networkTask(void *pvParameters)
|
||||
setReroute();
|
||||
}
|
||||
#endif
|
||||
if(connected && openerEnabled) networkOpener->update();
|
||||
if(connected && openerEnabled)
|
||||
{
|
||||
networkOpener->update();
|
||||
}
|
||||
#endif
|
||||
|
||||
if((esp_timer_get_time() / 1000) - networkLoopTs > 120000)
|
||||
if(espMillis() - networkLoopTs > 120000)
|
||||
{
|
||||
Log->println("networkTask is running");
|
||||
networkLoopTs = esp_timer_get_time() / 1000;
|
||||
networkLoopTs = espMillis();
|
||||
}
|
||||
|
||||
esp_task_wdt_reset();
|
||||
@@ -201,10 +215,10 @@ void nukiTask(void *pvParameters)
|
||||
nukiOpener->update();
|
||||
}
|
||||
|
||||
if((esp_timer_get_time() / 1000) - nukiLoopTs > 120000)
|
||||
if(espMillis() - nukiLoopTs > 120000)
|
||||
{
|
||||
Log->println("nukiTask is running");
|
||||
nukiLoopTs = esp_timer_get_time() / 1000;
|
||||
nukiLoopTs = espMillis();
|
||||
}
|
||||
|
||||
esp_task_wdt_reset();
|
||||
@@ -225,10 +239,10 @@ void bootloopDetection()
|
||||
}
|
||||
|
||||
if(esp_reset_reason() == esp_reset_reason_t::ESP_RST_PANIC ||
|
||||
esp_reset_reason() == esp_reset_reason_t::ESP_RST_INT_WDT ||
|
||||
esp_reset_reason() == esp_reset_reason_t::ESP_RST_TASK_WDT ||
|
||||
true ||
|
||||
esp_reset_reason() == esp_reset_reason_t::ESP_RST_WDT)
|
||||
esp_reset_reason() == esp_reset_reason_t::ESP_RST_INT_WDT ||
|
||||
esp_reset_reason() == esp_reset_reason_t::ESP_RST_TASK_WDT ||
|
||||
true ||
|
||||
esp_reset_reason() == esp_reset_reason_t::ESP_RST_WDT)
|
||||
{
|
||||
bootloopCounter++;
|
||||
Log->print(F("Bootloop counter incremented: "));
|
||||
@@ -259,38 +273,48 @@ uint8_t checkPartition()
|
||||
Log->print(F("Partition subtype: "));
|
||||
Log->println(running_partition->subtype);
|
||||
|
||||
if(running_partition->size == 1966080) return 0; //OLD PARTITION TABLE
|
||||
else if(running_partition->subtype == ESP_PARTITION_SUBTYPE_APP_OTA_0) return 1; //NEW PARTITION TABLE, RUNNING MAIN APP
|
||||
else return 2; //NEW PARTITION TABLE, RUNNING UPDATER APP
|
||||
if(running_partition->size == 1966080)
|
||||
{
|
||||
return 0; //OLD PARTITION TABLE
|
||||
}
|
||||
else if(running_partition->subtype == ESP_PARTITION_SUBTYPE_APP_OTA_0)
|
||||
{
|
||||
return 1; //NEW PARTITION TABLE, RUNNING MAIN APP
|
||||
}
|
||||
else
|
||||
{
|
||||
return 2; //NEW PARTITION TABLE, RUNNING UPDATER APP
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
||||
{
|
||||
switch (evt->event_id) {
|
||||
case HTTP_EVENT_ERROR:
|
||||
Log->println("HTTP_EVENT_ERROR");
|
||||
break;
|
||||
case HTTP_EVENT_ON_CONNECTED:
|
||||
Log->println("HTTP_EVENT_ON_CONNECTED");
|
||||
break;
|
||||
case HTTP_EVENT_HEADER_SENT:
|
||||
Log->println("HTTP_EVENT_HEADER_SENT");
|
||||
break;
|
||||
case HTTP_EVENT_ON_HEADER:
|
||||
Log->println("HTTP_EVENT_ON_HEADER");
|
||||
break;
|
||||
case HTTP_EVENT_ON_DATA:
|
||||
Log->println("HTTP_EVENT_ON_DATA");
|
||||
break;
|
||||
case HTTP_EVENT_ON_FINISH:
|
||||
Log->println("HTTP_EVENT_ON_FINISH");
|
||||
break;
|
||||
case HTTP_EVENT_DISCONNECTED:
|
||||
Log->println("HTTP_EVENT_DISCONNECTED");
|
||||
break;
|
||||
case HTTP_EVENT_REDIRECT:
|
||||
Log->println("HTTP_EVENT_REDIRECT");
|
||||
break;
|
||||
switch (evt->event_id)
|
||||
{
|
||||
case HTTP_EVENT_ERROR:
|
||||
Log->println("HTTP_EVENT_ERROR");
|
||||
break;
|
||||
case HTTP_EVENT_ON_CONNECTED:
|
||||
Log->println("HTTP_EVENT_ON_CONNECTED");
|
||||
break;
|
||||
case HTTP_EVENT_HEADER_SENT:
|
||||
Log->println("HTTP_EVENT_HEADER_SENT");
|
||||
break;
|
||||
case HTTP_EVENT_ON_HEADER:
|
||||
Log->println("HTTP_EVENT_ON_HEADER");
|
||||
break;
|
||||
case HTTP_EVENT_ON_DATA:
|
||||
Log->println("HTTP_EVENT_ON_DATA");
|
||||
break;
|
||||
case HTTP_EVENT_ON_FINISH:
|
||||
Log->println("HTTP_EVENT_ON_FINISH");
|
||||
break;
|
||||
case HTTP_EVENT_DISCONNECTED:
|
||||
Log->println("HTTP_EVENT_DISCONNECTED");
|
||||
break;
|
||||
case HTTP_EVENT_REDIRECT:
|
||||
Log->println("HTTP_EVENT_REDIRECT");
|
||||
break;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -311,14 +335,16 @@ void otaTask(void *pvParameter)
|
||||
preferences->putString(preference_ota_main_url, "");
|
||||
}
|
||||
Log->println("Starting OTA task");
|
||||
esp_http_client_config_t config = {
|
||||
esp_http_client_config_t config =
|
||||
{
|
||||
.url = updateUrl.c_str(),
|
||||
.event_handler = _http_event_handler,
|
||||
.crt_bundle_attach = esp_crt_bundle_attach,
|
||||
.keep_alive_enable = true,
|
||||
};
|
||||
|
||||
esp_https_ota_config_t ota_config = {
|
||||
esp_https_ota_config_t ota_config =
|
||||
{
|
||||
.http_config = &config,
|
||||
};
|
||||
Log->print(F("Attempting to download update from "));
|
||||
@@ -330,19 +356,23 @@ void otaTask(void *pvParameter)
|
||||
while (retryCount <= retryMax)
|
||||
{
|
||||
esp_err_t ret = esp_https_ota(&ota_config);
|
||||
if (ret == ESP_OK) {
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
Log->println("OTA Succeeded, Rebooting...");
|
||||
esp_ota_set_boot_partition(esp_ota_get_next_update_partition(NULL));
|
||||
restartEsp(RestartReason::OTACompleted);
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Log->println("Firmware upgrade failed, retrying in 5 seconds");
|
||||
retryCount++;
|
||||
esp_task_wdt_reset();
|
||||
delay(5000);
|
||||
continue;
|
||||
}
|
||||
while (1) {
|
||||
while (1)
|
||||
{
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
@@ -355,7 +385,8 @@ void otaTask(void *pvParameter)
|
||||
void setupTasks(bool ota)
|
||||
{
|
||||
// configMAX_PRIORITIES is 25
|
||||
esp_task_wdt_config_t twdt_config = {
|
||||
esp_task_wdt_config_t twdt_config =
|
||||
{
|
||||
.timeout_ms = 300000,
|
||||
.idle_core_mask = 0,
|
||||
.trigger_panic = true,
|
||||
@@ -371,26 +402,30 @@ void setupTasks(bool ota)
|
||||
{
|
||||
xTaskCreatePinnedToCore(networkTask, "ntw", preferences->getInt(preference_task_size_network, NETWORK_TASK_SIZE), NULL, 3, &networkTaskHandle, 1);
|
||||
esp_task_wdt_add(networkTaskHandle);
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
xTaskCreatePinnedToCore(nukiTask, "nuki", preferences->getInt(preference_task_size_nuki, NUKI_TASK_SIZE), NULL, 2, &nukiTaskHandle, 0);
|
||||
esp_task_wdt_add(nukiTaskHandle);
|
||||
#endif
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
if(!network->isApOpen())
|
||||
{
|
||||
xTaskCreatePinnedToCore(nukiTask, "nuki", preferences->getInt(preference_task_size_nuki, NUKI_TASK_SIZE), NULL, 2, &nukiTaskHandle, 0);
|
||||
esp_task_wdt_add(nukiTaskHandle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
esp_log_level_set("*", ESP_LOG_ERROR);
|
||||
esp_log_level_set("mqtt", ESP_LOG_NONE);
|
||||
Serial.begin(115200);
|
||||
Log = &Serial;
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
stdout = funopen(NULL, NULL, &write_fn, NULL, NULL);
|
||||
static char linebuf[1024];
|
||||
setvbuf(stdout, linebuf, _IOLBF, sizeof(linebuf));
|
||||
esp_rom_install_channel_putc(1, &ets_putc_handler);
|
||||
//ets_install_putc1(&ets_putc_handler);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
preferences = new Preferences();
|
||||
preferences->begin("nukihub", false);
|
||||
@@ -400,37 +435,52 @@ void setup()
|
||||
|
||||
initializeRestartReason();
|
||||
|
||||
if((partitionType==1 && preferences->getString(preference_ota_updater_url, "").length() > 0) || (partitionType==2 && preferences->getString(preference_ota_main_url, "").length() > 0)) doOta = true;
|
||||
if((partitionType==1 && preferences->getString(preference_ota_updater_url, "").length() > 0) || (partitionType==2 && preferences->getString(preference_ota_main_url, "").length() > 0))
|
||||
{
|
||||
doOta = true;
|
||||
}
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
if(preferences->getBool(preference_enable_bootloop_reset, false))
|
||||
{
|
||||
bootloopDetection();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef NUKI_HUB_UPDATER
|
||||
#ifdef NUKI_HUB_UPDATER
|
||||
Log->print(F("Nuki Hub OTA version "));
|
||||
Log->println(NUKI_HUB_VERSION);
|
||||
Log->print(F("Nuki Hub OTA build "));
|
||||
Log->println();
|
||||
|
||||
if(preferences->getString(preference_updater_version, "") != NUKI_HUB_VERSION) preferences->putString(preference_updater_version, NUKI_HUB_VERSION);
|
||||
if(preferences->getString(preference_updater_build, "") != NUKI_HUB_BUILD) preferences->putString(preference_updater_build, NUKI_HUB_BUILD);
|
||||
if(preferences->getString(preference_updater_date, "") != NUKI_HUB_DATE) preferences->putString(preference_updater_date, NUKI_HUB_DATE);
|
||||
if(preferences->getString(preference_updater_version, "") != NUKI_HUB_VERSION)
|
||||
{
|
||||
preferences->putString(preference_updater_version, NUKI_HUB_VERSION);
|
||||
}
|
||||
if(preferences->getString(preference_updater_build, "") != NUKI_HUB_BUILD)
|
||||
{
|
||||
preferences->putString(preference_updater_build, NUKI_HUB_BUILD);
|
||||
}
|
||||
if(preferences->getString(preference_updater_date, "") != NUKI_HUB_DATE)
|
||||
{
|
||||
preferences->putString(preference_updater_date, NUKI_HUB_DATE);
|
||||
}
|
||||
|
||||
network = new NukiNetwork(preferences);
|
||||
network->initialize();
|
||||
|
||||
if(!doOta)
|
||||
{
|
||||
asyncServer = new AsyncWebServer(80);
|
||||
webCfgServer = new WebCfgServer(network, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType, asyncServer);
|
||||
psychicServer = new PsychicHttpServer;
|
||||
webCfgServer = new WebCfgServer(network, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType, psychicServer);
|
||||
webCfgServer->initialize();
|
||||
asyncServer->onNotFound([](AsyncWebServerRequest* request) { request->redirect("/"); });
|
||||
asyncServer->begin();
|
||||
psychicServer->listen(80);
|
||||
psychicServer->onNotFound([](PsychicRequest* request)
|
||||
{
|
||||
return request->redirect("/");
|
||||
});
|
||||
}
|
||||
#else
|
||||
#else
|
||||
Log->print(F("Nuki Hub version "));
|
||||
Log->println(NUKI_HUB_VERSION);
|
||||
Log->print(F("Nuki Hub build "));
|
||||
@@ -447,7 +497,6 @@ void setup()
|
||||
}
|
||||
|
||||
char16_t buffer_size = preferences->getInt(preference_buffer_size, 4096);
|
||||
|
||||
CharBuffer::initialize(buffer_size);
|
||||
|
||||
gpio = new Gpio(preferences);
|
||||
@@ -455,22 +504,30 @@ void setup()
|
||||
gpio->getConfigurationText(gpioDesc, gpio->pinConfiguration(), "\n\r");
|
||||
Log->print(gpioDesc.c_str());
|
||||
|
||||
const String mqttLockPath = preferences->getString(preference_mqtt_lock_path);
|
||||
|
||||
network = new NukiNetwork(preferences, gpio, mqttLockPath, CharBuffer::get(), buffer_size);
|
||||
network->initialize();
|
||||
|
||||
lockEnabled = preferences->getBool(preference_lock_enabled);
|
||||
openerEnabled = preferences->getBool(preference_opener_enabled);
|
||||
|
||||
if(network->isApOpen())
|
||||
{
|
||||
forceEnableWebServer = true;
|
||||
doOta = false;
|
||||
lockEnabled = false;
|
||||
openerEnabled = false;
|
||||
}
|
||||
|
||||
bleScanner = new BleScanner::Scanner();
|
||||
// Scan interval and window according to Nuki recommendations:
|
||||
// https://developer.nuki.io/t/bluetooth-specification-questions/1109/27
|
||||
bleScanner->initialize("NukiHub", true, 40, 40);
|
||||
bleScanner->setScanDuration(0);
|
||||
|
||||
lockEnabled = preferences->getBool(preference_lock_enabled);
|
||||
openerEnabled = preferences->getBool(preference_opener_enabled);
|
||||
|
||||
const String mqttLockPath = preferences->getString(preference_mqtt_lock_path);
|
||||
|
||||
nukiOfficial = new NukiOfficial(preferences);
|
||||
|
||||
network = new NukiNetwork(preferences, gpio, mqttLockPath, CharBuffer::get(), buffer_size);
|
||||
network->initialize();
|
||||
|
||||
networkLock = new NukiNetworkLock(network, nukiOfficial, preferences, CharBuffer::get(), buffer_size);
|
||||
networkLock->initialize();
|
||||
|
||||
@@ -498,15 +555,23 @@ void setup()
|
||||
{
|
||||
if(!doOta)
|
||||
{
|
||||
asyncServer = new AsyncWebServer(80);
|
||||
psychicServer = new PsychicHttpServer;
|
||||
psychicServer->config.max_uri_handlers = 40;
|
||||
psychicServer->config.stack_size = 8192;
|
||||
psychicServer->listen(80);
|
||||
|
||||
if(forceEnableWebServer || preferences->getBool(preference_webserver_enabled, true))
|
||||
{
|
||||
webCfgServer = new WebCfgServer(nuki, nukiOpener, network, gpio, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType, asyncServer);
|
||||
webCfgServer = new WebCfgServer(nuki, nukiOpener, network, gpio, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType, psychicServer);
|
||||
webCfgServer->initialize();
|
||||
asyncServer->onNotFound([](AsyncWebServerRequest* request) { request->redirect("/"); });
|
||||
psychicServer->onNotFound([](PsychicRequest* request)
|
||||
{
|
||||
return request->redirect("/");
|
||||
});
|
||||
}
|
||||
else asyncServer->onNotFound([](AsyncWebServerRequest* request) { request->redirect("/webserial"); });
|
||||
/*
|
||||
#ifdef DEBUG_NUKIHUB
|
||||
else psychicServer->onNotFound([](PsychicRequest* request) { return request->redirect("/webserial"); });
|
||||
|
||||
if(preferences->getBool(preference_webserial_enabled, false))
|
||||
{
|
||||
@@ -514,21 +579,27 @@ void setup()
|
||||
WebSerial.begin(asyncServer);
|
||||
WebSerial.setBuffer(1024);
|
||||
}
|
||||
|
||||
asyncServer->begin();
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if(doOta) setupTasks(true);
|
||||
else setupTasks(false);
|
||||
|
||||
#ifdef DEBUG_NUKIHUB
|
||||
if(doOta)
|
||||
{
|
||||
setupTasks(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
setupTasks(false);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_NUKIHUB
|
||||
Log->print("Task Name\tStatus\tPrio\tHWM\tTask\tAffinity\n");
|
||||
char stats_buffer[1024];
|
||||
vTaskList(stats_buffer);
|
||||
Log->println(stats_buffer);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop()
|
||||
|
||||
@@ -1,103 +1,54 @@
|
||||
#include "EthernetDevice.h"
|
||||
#include "../PreferencesKeys.h"
|
||||
#include "../Logger.h"
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
#include "../MqttTopics.h"
|
||||
#include "espMqttClient.h"
|
||||
#endif
|
||||
#include "../RestartReason.h"
|
||||
|
||||
RTC_NOINIT_ATTR bool criticalEthFailure;
|
||||
extern char WiFi_fallbackDetect[14];
|
||||
|
||||
EthernetDevice::EthernetDevice(const String& hostname, Preferences* preferences, const IPConfiguration* ipConfiguration, const std::string& deviceName, uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t ethtype, eth_clock_mode_t clock_mode)
|
||||
: NetworkDevice(hostname, ipConfiguration),
|
||||
_deviceName(deviceName),
|
||||
_phy_addr(phy_addr),
|
||||
_power(power),
|
||||
_mdc(mdc),
|
||||
_mdio(mdio),
|
||||
_type(ethtype),
|
||||
_clock_mode(clock_mode),
|
||||
_useSpi(false),
|
||||
_preferences(preferences)
|
||||
: NetworkDevice(hostname, ipConfiguration),
|
||||
_deviceName(deviceName),
|
||||
_phy_addr(phy_addr),
|
||||
_power(power),
|
||||
_mdc(mdc),
|
||||
_mdio(mdio),
|
||||
_type(ethtype),
|
||||
_clock_mode(clock_mode),
|
||||
_useSpi(false),
|
||||
_preferences(preferences)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
EthernetDevice::EthernetDevice(const String &hostname,
|
||||
Preferences *preferences,
|
||||
const IPConfiguration *ipConfiguration,
|
||||
const std::string &deviceName,
|
||||
uint8_t phy_addr,
|
||||
int cs,
|
||||
int irq,
|
||||
int rst,
|
||||
int spi_sck,
|
||||
int spi_miso,
|
||||
int spi_mosi,
|
||||
eth_phy_type_t ethtype)
|
||||
: NetworkDevice(hostname, ipConfiguration),
|
||||
_deviceName(deviceName),
|
||||
_phy_addr(phy_addr),
|
||||
_cs(cs),
|
||||
_irq(irq),
|
||||
_rst(rst),
|
||||
_spi_sck(spi_sck),
|
||||
_spi_miso(spi_miso),
|
||||
_spi_mosi(spi_mosi),
|
||||
_type(ethtype),
|
||||
_useSpi(true),
|
||||
_preferences(preferences)
|
||||
Preferences *preferences,
|
||||
const IPConfiguration *ipConfiguration,
|
||||
const std::string &deviceName,
|
||||
uint8_t phy_addr,
|
||||
int cs,
|
||||
int irq,
|
||||
int rst,
|
||||
int spi_sck,
|
||||
int spi_miso,
|
||||
int spi_mosi,
|
||||
eth_phy_type_t ethtype)
|
||||
: NetworkDevice(hostname, ipConfiguration),
|
||||
_deviceName(deviceName),
|
||||
_phy_addr(phy_addr),
|
||||
_cs(cs),
|
||||
_irq(irq),
|
||||
_rst(rst),
|
||||
_spi_sck(spi_sck),
|
||||
_spi_miso(spi_miso),
|
||||
_spi_mosi(spi_mosi),
|
||||
_type(ethtype),
|
||||
_useSpi(true),
|
||||
_preferences(preferences)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void EthernetDevice::init()
|
||||
{
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
size_t caLength = _preferences->getString(preference_mqtt_ca, _ca, TLS_CA_MAX_SIZE);
|
||||
size_t crtLength = _preferences->getString(preference_mqtt_crt, _cert, TLS_CERT_MAX_SIZE);
|
||||
size_t keyLength = _preferences->getString(preference_mqtt_key, _key, TLS_KEY_MAX_SIZE);
|
||||
|
||||
_useEncryption = caLength > 1; // length is 1 when empty
|
||||
|
||||
if(_useEncryption)
|
||||
{
|
||||
Log->println(F("MQTT over TLS."));
|
||||
Log->println(_ca);
|
||||
_mqttClientSecure = new espMqttClientSecure(espMqttClientTypes::UseInternalTask::NO);
|
||||
_mqttClientSecure->setCACert(_ca);
|
||||
if(crtLength > 1 && keyLength > 1) // length is 1 when empty
|
||||
{
|
||||
Log->println(F("MQTT with client certificate."));
|
||||
Log->println(_cert);
|
||||
Log->println(_key);
|
||||
_mqttClientSecure->setCertificate(_cert);
|
||||
_mqttClientSecure->setPrivateKey(_key);
|
||||
}
|
||||
} else
|
||||
{
|
||||
Log->println(F("MQTT without TLS."));
|
||||
_mqttClient = new espMqttClient(espMqttClientTypes::UseInternalTask::NO);
|
||||
}
|
||||
|
||||
if(_preferences->getBool(preference_mqtt_log_enabled, false) || _preferences->getBool(preference_webserial_enabled, false))
|
||||
{
|
||||
MqttLoggerMode mode;
|
||||
|
||||
if(_preferences->getBool(preference_mqtt_log_enabled, false) && _preferences->getBool(preference_webserial_enabled, false)) mode = MqttLoggerMode::MqttAndSerialAndWeb;
|
||||
else if (_preferences->getBool(preference_webserial_enabled, false)) mode = MqttLoggerMode::SerialAndWeb;
|
||||
else mode = MqttLoggerMode::MqttAndSerial;
|
||||
|
||||
_path = new char[200];
|
||||
memset(_path, 0, sizeof(_path));
|
||||
|
||||
String pathStr = _preferences->getString(preference_mqtt_lock_path);
|
||||
pathStr.concat(mqtt_topic_log);
|
||||
strcpy(_path, pathStr.c_str());
|
||||
Log = new MqttLogger(*getMqttClient(), _path, mode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
const String EthernetDevice::deviceName() const
|
||||
{
|
||||
return _deviceName.c_str();
|
||||
@@ -106,30 +57,45 @@ const String EthernetDevice::deviceName() const
|
||||
void EthernetDevice::initialize()
|
||||
{
|
||||
delay(250);
|
||||
if(criticalEthFailure)
|
||||
{
|
||||
criticalEthFailure = false;
|
||||
Log->println(F("Failed to initialize ethernet hardware"));
|
||||
Log->println("Network device has a critical failure, enable fallback to Wi-Fi and reboot.");
|
||||
strcpy(WiFi_fallbackDetect, "wifi_fallback");
|
||||
delay(200);
|
||||
restartEsp(RestartReason::NetworkDeviceCriticalFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
Log->println(F("Init Ethernet"));
|
||||
|
||||
if(_useSpi)
|
||||
{
|
||||
Log->println(F("Use SPI"));
|
||||
criticalEthFailure = true;
|
||||
SPI.begin(_spi_sck, _spi_miso, _spi_mosi);
|
||||
_hardwareInitialized = ETH.begin(_type, _phy_addr, _cs, _irq, _rst, SPI);
|
||||
criticalEthFailure = false;
|
||||
}
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
else
|
||||
{
|
||||
Log->println(F("Use RMII"));
|
||||
criticalEthFailure = true;
|
||||
_hardwareInitialized = ETH.begin(_type, _phy_addr, _mdc, _mdio, _power, _clock_mode);
|
||||
criticalEthFailure = false;
|
||||
if(!_ipConfiguration->dhcpEnabled())
|
||||
{
|
||||
_checkIpTs = (esp_timer_get_time() / 1000) + 2000;
|
||||
_checkIpTs = espMillis() + 2000;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if(_hardwareInitialized)
|
||||
{
|
||||
Log->println(F("Ethernet hardware Initialized"));
|
||||
memset(WiFi_fallbackDetect, 0, sizeof(WiFi_fallbackDetect));
|
||||
|
||||
if(_useSpi && !_ipConfiguration->dhcpEnabled())
|
||||
{
|
||||
@@ -144,20 +110,23 @@ void EthernetDevice::initialize()
|
||||
else
|
||||
{
|
||||
Log->println(F("Failed to initialize ethernet hardware"));
|
||||
Log->println("Network device has a critical failure, enable fallback to Wi-Fi and reboot.");
|
||||
strcpy(WiFi_fallbackDetect, "wifi_fallback");
|
||||
delay(200);
|
||||
restartEsp(RestartReason::NetworkDeviceCriticalFailure);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void EthernetDevice::update()
|
||||
{
|
||||
NetworkDevice::update();
|
||||
|
||||
if(_checkIpTs != -1)
|
||||
{
|
||||
if(_ipConfiguration->ipAddress() != ETH.localIP())
|
||||
{
|
||||
Log->println(F("ETH Set static IP"));
|
||||
ETH.config(_ipConfiguration->ipAddress(), _ipConfiguration->defaultGateway(), _ipConfiguration->subnet(), _ipConfiguration->dnsServer());
|
||||
_checkIpTs = (esp_timer_get_time() / 1000) + 2000;
|
||||
_checkIpTs = espMillis() + 2000;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -169,69 +138,67 @@ void EthernetDevice::update()
|
||||
|
||||
void EthernetDevice::onNetworkEvent(arduino_event_id_t event, arduino_event_info_t info)
|
||||
{
|
||||
switch (event) {
|
||||
case ARDUINO_EVENT_ETH_START:
|
||||
Log->println("ETH Started");
|
||||
ETH.setHostname(_hostname.c_str());
|
||||
break;
|
||||
case ARDUINO_EVENT_ETH_CONNECTED:
|
||||
Log->println("ETH Connected");
|
||||
if(!localIP().equals("0.0.0.0"))
|
||||
{
|
||||
_connected = true;
|
||||
}
|
||||
break;
|
||||
case ARDUINO_EVENT_ETH_GOT_IP:
|
||||
Log->printf("ETH Got IP: '%s'\n", esp_netif_get_desc(info.got_ip.esp_netif));
|
||||
Log->println(ETH);
|
||||
|
||||
// For RMII devices, this check is handled in the update() method.
|
||||
if(_useSpi && !_ipConfiguration->dhcpEnabled() && _ipConfiguration->ipAddress() != ETH.localIP())
|
||||
{
|
||||
Log->printf("Static IP not used, retrying to set static IP");
|
||||
ETH.config(_ipConfiguration->ipAddress(), _ipConfiguration->defaultGateway(), _ipConfiguration->subnet(), _ipConfiguration->dnsServer());
|
||||
ETH.begin(_type, _phy_addr, _cs, _irq, _rst, SPI);
|
||||
}
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case ARDUINO_EVENT_ETH_START:
|
||||
Log->println("ETH Started");
|
||||
ETH.setHostname(_hostname.c_str());
|
||||
break;
|
||||
case ARDUINO_EVENT_ETH_CONNECTED:
|
||||
Log->println("ETH Connected");
|
||||
if(!localIP().equals("0.0.0.0"))
|
||||
{
|
||||
_connected = true;
|
||||
if(_preferences->getBool(preference_ntw_reconfigure, false))
|
||||
{
|
||||
_preferences->putBool(preference_ntw_reconfigure, false);
|
||||
}
|
||||
break;
|
||||
case ARDUINO_EVENT_ETH_LOST_IP:
|
||||
Log->println("ETH Lost IP");
|
||||
_connected = false;
|
||||
onDisconnected();
|
||||
break;
|
||||
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
||||
Log->println("ETH Disconnected");
|
||||
_connected = false;
|
||||
onDisconnected();
|
||||
break;
|
||||
case ARDUINO_EVENT_ETH_STOP:
|
||||
Log->println("ETH Stopped");
|
||||
_connected = false;
|
||||
onDisconnected();
|
||||
break;
|
||||
default:
|
||||
Log->print("ETH Event: ");
|
||||
Log->println(event);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ARDUINO_EVENT_ETH_GOT_IP:
|
||||
Log->printf("ETH Got IP: '%s'\n", esp_netif_get_desc(info.got_ip.esp_netif));
|
||||
Log->println(ETH);
|
||||
|
||||
// For RMII devices, this check is handled in the update() method.
|
||||
if(_useSpi && !_ipConfiguration->dhcpEnabled() && _ipConfiguration->ipAddress() != ETH.localIP())
|
||||
{
|
||||
Log->printf("Static IP not used, retrying to set static IP");
|
||||
ETH.config(_ipConfiguration->ipAddress(), _ipConfiguration->defaultGateway(), _ipConfiguration->subnet(), _ipConfiguration->dnsServer());
|
||||
ETH.begin(_type, _phy_addr, _cs, _irq, _rst, SPI);
|
||||
}
|
||||
|
||||
_connected = true;
|
||||
if(_preferences->getBool(preference_ntw_reconfigure, false))
|
||||
{
|
||||
_preferences->putBool(preference_ntw_reconfigure, false);
|
||||
}
|
||||
break;
|
||||
case ARDUINO_EVENT_ETH_LOST_IP:
|
||||
Log->println("ETH Lost IP");
|
||||
_connected = false;
|
||||
onDisconnected();
|
||||
break;
|
||||
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
||||
Log->println("ETH Disconnected");
|
||||
_connected = false;
|
||||
onDisconnected();
|
||||
break;
|
||||
case ARDUINO_EVENT_ETH_STOP:
|
||||
Log->println("ETH Stopped");
|
||||
_connected = false;
|
||||
onDisconnected();
|
||||
break;
|
||||
default:
|
||||
Log->print("ETH Event: ");
|
||||
Log->println(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EthernetDevice::reconfigure()
|
||||
{
|
||||
delay(200);
|
||||
restartEsp(RestartReason::ReconfigureETH);
|
||||
}
|
||||
|
||||
bool EthernetDevice::supportsEncryption()
|
||||
void EthernetDevice::scan(bool passive, bool async)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EthernetDevice::isConnected()
|
||||
@@ -239,20 +206,17 @@ bool EthernetDevice::isConnected()
|
||||
return _connected;
|
||||
}
|
||||
|
||||
ReconnectStatus EthernetDevice::reconnect(bool force)
|
||||
bool EthernetDevice::isApOpen()
|
||||
{
|
||||
if(!_hardwareInitialized)
|
||||
{
|
||||
return ReconnectStatus::CriticalFailure;
|
||||
}
|
||||
delay(200);
|
||||
return isConnected() ? ReconnectStatus::Success : ReconnectStatus::Failure;
|
||||
return false;
|
||||
}
|
||||
|
||||
void EthernetDevice::onDisconnected()
|
||||
{
|
||||
if(_preferences->getBool(preference_restart_on_disconnect, false) && ((esp_timer_get_time() / 1000) > 60000)) restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
||||
reconnect();
|
||||
if(_preferences->getBool(preference_restart_on_disconnect, false) && (espMillis() > 60000))
|
||||
{
|
||||
restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
||||
}
|
||||
}
|
||||
|
||||
int8_t EthernetDevice::signalStrength()
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
#include <NetworkClientSecure.h>
|
||||
#include <Preferences.h>
|
||||
#include "NetworkDevice.h"
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
#include "espMqttClient.h"
|
||||
#endif
|
||||
|
||||
class EthernetDevice : public NetworkDevice
|
||||
{
|
||||
@@ -48,26 +45,23 @@ public:
|
||||
virtual void initialize();
|
||||
virtual void reconfigure();
|
||||
virtual void update();
|
||||
|
||||
virtual ReconnectStatus reconnect(bool force = false);
|
||||
bool supportsEncryption() override;
|
||||
virtual void scan(bool passive = false, bool async = true);
|
||||
|
||||
virtual bool isConnected();
|
||||
virtual bool isApOpen();
|
||||
|
||||
int8_t signalStrength() override;
|
||||
|
||||
|
||||
String localIP() override;
|
||||
String BSSIDstr() override;
|
||||
|
||||
private:
|
||||
Preferences* _preferences;
|
||||
|
||||
void init();
|
||||
|
||||
void onDisconnected();
|
||||
void onNetworkEvent(arduino_event_id_t event, arduino_event_info_t info);
|
||||
|
||||
bool _connected = false;
|
||||
char* _path;
|
||||
bool _hardwareInitialized = false;
|
||||
|
||||
const std::string _deviceName;
|
||||
@@ -91,10 +85,4 @@ private:
|
||||
eth_phy_type_t _type;
|
||||
eth_clock_mode_t _clock_mode;
|
||||
bool _useSpi = false;
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
char _ca[TLS_CA_MAX_SIZE] = {0};
|
||||
char _cert[TLS_CERT_MAX_SIZE] = {0};
|
||||
char _key[TLS_KEY_MAX_SIZE] = {0};
|
||||
#endif
|
||||
};
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "../Logger.h"
|
||||
|
||||
IPConfiguration::IPConfiguration(Preferences *preferences)
|
||||
: _preferences(preferences)
|
||||
: _preferences(preferences)
|
||||
{
|
||||
if(!dhcpEnabled() && _preferences->getString(preference_ip_address, "").length() <= 0)
|
||||
{
|
||||
@@ -23,10 +23,14 @@ IPConfiguration::IPConfiguration(Preferences *preferences)
|
||||
}
|
||||
else
|
||||
{
|
||||
Log->print(F("IP address: ")); Log->print(ipAddress());
|
||||
Log->print(F(", Subnet: ")); Log->print(subnet());
|
||||
Log->print(F(", Gateway: ")); Log->print(defaultGateway());
|
||||
Log->print(F(", DNS: ")); Log->println(dnsServer());
|
||||
Log->print(F("IP address: "));
|
||||
Log->print(ipAddress());
|
||||
Log->print(F(", Subnet: "));
|
||||
Log->print(subnet());
|
||||
Log->print(F(", Gateway: "));
|
||||
Log->print(defaultGateway());
|
||||
Log->print(F(", DNS: "));
|
||||
Log->println(dnsServer());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,179 +1,6 @@
|
||||
#include <Arduino.h>
|
||||
#include "NetworkDevice.h"
|
||||
#include "../Logger.h"
|
||||
|
||||
void NetworkDevice::printError()
|
||||
{
|
||||
Log->print(F("Free Heap: "));
|
||||
Log->println(ESP.getFreeHeap());
|
||||
}
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
void NetworkDevice::update()
|
||||
{
|
||||
if (_mqttEnabled)
|
||||
{
|
||||
getMqttClient()->loop();
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkDevice::mqttSetClientId(const char *clientId)
|
||||
{
|
||||
if (_useEncryption)
|
||||
{
|
||||
_mqttClientSecure->setClientId(clientId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mqttClient->setClientId(clientId);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkDevice::mqttSetCleanSession(bool cleanSession)
|
||||
{
|
||||
if (_useEncryption)
|
||||
{
|
||||
_mqttClientSecure->setCleanSession(cleanSession);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mqttClient->setCleanSession(cleanSession);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkDevice::mqttSetKeepAlive(uint16_t keepAlive)
|
||||
{
|
||||
if (_useEncryption)
|
||||
{
|
||||
_mqttClientSecure->setKeepAlive(keepAlive);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mqttClient->setKeepAlive(keepAlive);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t NetworkDevice::mqttPublish(const char *topic, uint8_t qos, bool retain, const char *payload)
|
||||
{
|
||||
return getMqttClient()->publish(topic, qos, retain, payload);
|
||||
}
|
||||
|
||||
uint16_t NetworkDevice::mqttPublish(const char *topic, uint8_t qos, bool retain, const uint8_t *payload, size_t length)
|
||||
{
|
||||
return getMqttClient()->publish(topic, qos, retain, payload, length);
|
||||
}
|
||||
|
||||
bool NetworkDevice::mqttConnected() const
|
||||
{
|
||||
return getMqttClient()->connected();
|
||||
}
|
||||
|
||||
void NetworkDevice::mqttSetServer(const char *host, uint16_t port)
|
||||
{
|
||||
if (_useEncryption)
|
||||
{
|
||||
_mqttClientSecure->setServer(host, port);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mqttClient->setServer(host, port);
|
||||
}
|
||||
}
|
||||
|
||||
bool NetworkDevice::mqttConnect()
|
||||
{
|
||||
return getMqttClient()->connect();
|
||||
}
|
||||
|
||||
bool NetworkDevice::mqttDisconnect(bool force)
|
||||
{
|
||||
return getMqttClient()->disconnect(force);
|
||||
}
|
||||
|
||||
void NetworkDevice::setWill(const char *topic, uint8_t qos, bool retain, const char *payload)
|
||||
{
|
||||
if (_useEncryption)
|
||||
{
|
||||
_mqttClientSecure->setWill(topic, qos, retain, payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mqttClient->setWill(topic, qos, retain, payload);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkDevice::mqttSetCredentials(const char *username, const char *password)
|
||||
{
|
||||
if (_useEncryption)
|
||||
{
|
||||
_mqttClientSecure->setCredentials(username, password);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mqttClient->setCredentials(username, password);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkDevice::mqttOnMessage(espMqttClientTypes::OnMessageCallback callback)
|
||||
{
|
||||
if (_useEncryption)
|
||||
{
|
||||
_mqttClientSecure->onMessage(callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mqttClient->onMessage(callback);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkDevice::mqttOnConnect(espMqttClientTypes::OnConnectCallback callback)
|
||||
{
|
||||
if(_useEncryption)
|
||||
{
|
||||
_mqttClientSecure->onConnect(callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mqttClient->onConnect(callback);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkDevice::mqttOnDisconnect(espMqttClientTypes::OnDisconnectCallback callback)
|
||||
{
|
||||
if (_useEncryption)
|
||||
{
|
||||
_mqttClientSecure->onDisconnect(callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mqttClient->onDisconnect(callback);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t NetworkDevice::mqttSubscribe(const char *topic, uint8_t qos)
|
||||
{
|
||||
return getMqttClient()->subscribe(topic, qos);
|
||||
}
|
||||
|
||||
void NetworkDevice::disableMqtt()
|
||||
{
|
||||
getMqttClient()->disconnect();
|
||||
_mqttEnabled = false;
|
||||
}
|
||||
|
||||
MqttClient *NetworkDevice::getMqttClient() const
|
||||
{
|
||||
if (_useEncryption)
|
||||
{
|
||||
return _mqttClientSecure;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _mqttClient;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void NetworkDevice::update()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
#include "espMqttClient.h"
|
||||
#include "MqttClientSetup.h"
|
||||
#endif
|
||||
#include "IPConfiguration.h"
|
||||
|
||||
enum class ReconnectStatus
|
||||
{
|
||||
Failure = 0,
|
||||
Success = 1,
|
||||
CriticalFailure = 2
|
||||
};
|
||||
#include "../EspMillis.h"
|
||||
|
||||
class NetworkDevice
|
||||
{
|
||||
@@ -24,50 +13,17 @@ public:
|
||||
virtual const String deviceName() const = 0;
|
||||
|
||||
virtual void initialize() = 0;
|
||||
virtual ReconnectStatus reconnect(bool force = false) = 0;
|
||||
virtual void reconfigure() = 0;
|
||||
virtual void printError();
|
||||
virtual bool supportsEncryption() = 0;
|
||||
|
||||
virtual void update();
|
||||
virtual void scan(bool passive = false, bool async = true) = 0;
|
||||
|
||||
virtual bool isConnected() = 0;
|
||||
virtual bool isApOpen() = 0;
|
||||
virtual int8_t signalStrength() = 0;
|
||||
|
||||
virtual String localIP() = 0;
|
||||
virtual String BSSIDstr() = 0;
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
virtual void mqttSetClientId(const char* clientId);
|
||||
virtual void mqttSetCleanSession(bool cleanSession);
|
||||
virtual void mqttSetKeepAlive(uint16_t keepAlive);
|
||||
virtual uint16_t mqttPublish(const char* topic, uint8_t qos, bool retain, const char* payload);
|
||||
virtual uint16_t mqttPublish(const char* topic, uint8_t qos, bool retain, const uint8_t* payload, size_t length);
|
||||
virtual bool mqttConnected() const;
|
||||
virtual void mqttSetServer(const char* host, uint16_t port);
|
||||
virtual bool mqttConnect();
|
||||
virtual bool mqttDisconnect(bool force);
|
||||
virtual void setWill(const char* topic, uint8_t qos, bool retain, const char* payload);
|
||||
virtual void mqttSetCredentials(const char* username, const char* password);
|
||||
virtual void mqttOnMessage(espMqttClientTypes::OnMessageCallback callback);
|
||||
virtual void mqttOnConnect(espMqttClientTypes::OnConnectCallback callback);
|
||||
virtual void mqttOnDisconnect(espMqttClientTypes::OnDisconnectCallback callback);
|
||||
virtual void disableMqtt();
|
||||
|
||||
virtual uint16_t mqttSubscribe(const char* topic, uint8_t qos);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
espMqttClient *_mqttClient = nullptr;
|
||||
espMqttClientSecure *_mqttClientSecure = nullptr;
|
||||
|
||||
bool _useEncryption = false;
|
||||
bool _mqttEnabled = true;
|
||||
|
||||
MqttClient *getMqttClient() const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
const String _hostname;
|
||||
const IPConfiguration* _ipConfiguration = nullptr;
|
||||
};
|
||||
@@ -1,66 +1,14 @@
|
||||
#include "esp_wifi.h"
|
||||
#include <WiFi.h>
|
||||
#include "WifiDevice.h"
|
||||
#include "../PreferencesKeys.h"
|
||||
#include "../Logger.h"
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
#include "../MqttTopics.h"
|
||||
#include "espMqttClient.h"
|
||||
#endif
|
||||
#include "../RestartReason.h"
|
||||
|
||||
RTC_NOINIT_ATTR char WiFiDevice_reconfdetect[17];
|
||||
|
||||
WifiDevice::WifiDevice(const String& hostname, Preferences* preferences, const IPConfiguration* ipConfiguration)
|
||||
: NetworkDevice(hostname, ipConfiguration),
|
||||
_preferences(preferences),
|
||||
_wm(preferences->getString(preference_cred_user, "").c_str(), preferences->getString(preference_cred_password, "").c_str())
|
||||
: NetworkDevice(hostname, ipConfiguration),
|
||||
_preferences(preferences)
|
||||
{
|
||||
_startAp = strcmp(WiFiDevice_reconfdetect, "reconfigure_wifi") == 0;
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
size_t caLength = preferences->getString(preference_mqtt_ca, _ca, TLS_CA_MAX_SIZE);
|
||||
size_t crtLength = preferences->getString(preference_mqtt_crt, _cert, TLS_CERT_MAX_SIZE);
|
||||
size_t keyLength = preferences->getString(preference_mqtt_key, _key, TLS_KEY_MAX_SIZE);
|
||||
|
||||
_useEncryption = caLength > 1; // length is 1 when empty
|
||||
|
||||
if(_useEncryption)
|
||||
{
|
||||
Log->println(F("MQTT over TLS."));
|
||||
Log->println(_ca);
|
||||
_mqttClientSecure = new espMqttClientSecure(espMqttClientTypes::UseInternalTask::NO);
|
||||
_mqttClientSecure->setCACert(_ca);
|
||||
if(crtLength > 1 && keyLength > 1) // length is 1 when empty
|
||||
{
|
||||
Log->println(F("MQTT with client certificate."));
|
||||
Log->println(_cert);
|
||||
Log->println(_key);
|
||||
_mqttClientSecure->setCertificate(_cert);
|
||||
_mqttClientSecure->setPrivateKey(_key);
|
||||
}
|
||||
} else
|
||||
{
|
||||
Log->println(F("MQTT without TLS."));
|
||||
_mqttClient = new espMqttClient(espMqttClientTypes::UseInternalTask::NO);
|
||||
}
|
||||
|
||||
if(preferences->getBool(preference_mqtt_log_enabled, false) || preferences->getBool(preference_webserial_enabled, false))
|
||||
{
|
||||
MqttLoggerMode mode;
|
||||
|
||||
if(preferences->getBool(preference_mqtt_log_enabled, false) && preferences->getBool(preference_webserial_enabled, false)) mode = MqttLoggerMode::MqttAndSerialAndWeb;
|
||||
else if (preferences->getBool(preference_webserial_enabled, false)) mode = MqttLoggerMode::SerialAndWeb;
|
||||
else mode = MqttLoggerMode::MqttAndSerial;
|
||||
|
||||
_path = new char[200];
|
||||
memset(_path, 0, sizeof(_path));
|
||||
|
||||
String pathStr = preferences->getString(preference_mqtt_lock_path);
|
||||
pathStr.concat(mqtt_topic_log);
|
||||
strcpy(_path, pathStr.c_str());
|
||||
Log = new MqttLogger(*getMqttClient(), _path, mode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
const String WifiDevice::deviceName() const
|
||||
@@ -70,128 +18,390 @@ const String WifiDevice::deviceName() const
|
||||
|
||||
void WifiDevice::initialize()
|
||||
{
|
||||
std::vector<const char *> wm_menu;
|
||||
wm_menu.push_back("wifi");
|
||||
wm_menu.push_back("exit");
|
||||
_wm.setEnableConfigPortal(_startAp || !_preferences->getBool(preference_network_wifi_fallback_disabled, false));
|
||||
// reduced timeout if ESP is set to restart on disconnect
|
||||
_wm.setFindBestRSSI(_preferences->getBool(preference_find_best_rssi));
|
||||
_wm.setConnectTimeout(20);
|
||||
_wm.setConfigPortalTimeout(_preferences->getBool(preference_restart_on_disconnect, false) ? 60 * 3 : 60 * 30);
|
||||
_wm.setShowInfoUpdate(false);
|
||||
_wm.setMenu(wm_menu);
|
||||
_wm.setHostname(_hostname);
|
||||
|
||||
if(!_ipConfiguration->dhcpEnabled())
|
||||
{
|
||||
_wm.setSTAStaticIPConfig(_ipConfiguration->ipAddress(), _ipConfiguration->defaultGateway(), _ipConfiguration->subnet(), _ipConfiguration->dnsServer());
|
||||
}
|
||||
|
||||
_wm.setAPCallback(clearRtcInitVar);
|
||||
|
||||
bool res = false;
|
||||
bool connectedFromPortal = false;
|
||||
|
||||
if(_startAp)
|
||||
{
|
||||
Log->println(F("Opening Wi-Fi configuration portal."));
|
||||
res = _wm.startConfigPortal();
|
||||
connectedFromPortal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = _wm.autoConnect(); // password protected ap
|
||||
}
|
||||
|
||||
if(!res)
|
||||
{
|
||||
esp_wifi_disconnect();
|
||||
esp_wifi_stop();
|
||||
esp_wifi_deinit();
|
||||
|
||||
Log->println(F("Failed to connect. Wait for ESP restart."));
|
||||
delay(1000);
|
||||
restartEsp(RestartReason::WifiInitFailed);
|
||||
}
|
||||
else {
|
||||
Log->print(F("Wi-Fi connected: "));
|
||||
Log->println(WiFi.localIP().toString());
|
||||
|
||||
if(connectedFromPortal)
|
||||
{
|
||||
Log->println(F("Connected using WifiManager portal. Wait for ESP restart."));
|
||||
delay(1000);
|
||||
restartEsp(RestartReason::ConfigurationUpdated);
|
||||
}
|
||||
}
|
||||
String ssid = _preferences->getString(preference_wifi_ssid, "");
|
||||
String pass = _preferences->getString(preference_wifi_pass, "");
|
||||
WiFi.setHostname(_hostname.c_str());
|
||||
|
||||
WiFi.onEvent([&](WiFiEvent_t event, WiFiEventInfo_t info)
|
||||
{
|
||||
if(event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED)
|
||||
if(event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED || event == ARDUINO_EVENT_WIFI_STA_STOP)
|
||||
{
|
||||
onDisconnected();
|
||||
if(!_openAP && !_connecting && _connected)
|
||||
{
|
||||
onDisconnected();
|
||||
_hasIP = false;
|
||||
}
|
||||
}
|
||||
else if(event == ARDUINO_EVENT_WIFI_STA_GOT_IP)
|
||||
{
|
||||
_hasIP = true;
|
||||
}
|
||||
else if(event == ARDUINO_EVENT_WIFI_STA_LOST_IP)
|
||||
{
|
||||
_hasIP = false;
|
||||
}
|
||||
else if(event == ARDUINO_EVENT_WIFI_STA_CONNECTED)
|
||||
{
|
||||
onConnected();
|
||||
}
|
||||
else if(event == ARDUINO_EVENT_WIFI_SCAN_DONE)
|
||||
{
|
||||
Log->println(F("Wi-Fi scan done"));
|
||||
_foundNetworks = WiFi.scanComplete();
|
||||
|
||||
for (int i = 0; i < _foundNetworks; i++)
|
||||
{
|
||||
Log->println(String(F("SSID ")) + WiFi.SSID(i) + String(F(" found with RSSI: ")) +
|
||||
String(WiFi.RSSI(i)) + String(F("(")) +
|
||||
String(constrain((100.0 + WiFi.RSSI(i)) * 2, 0, 100)) +
|
||||
String(F(" %) and BSSID: ")) + WiFi.BSSIDstr(i) +
|
||||
String(F(" and channel: ")) + String(WiFi.channel(i)));
|
||||
}
|
||||
|
||||
if (_connectOnScanDone && _foundNetworks > 0)
|
||||
{
|
||||
connect();
|
||||
}
|
||||
else if (_connectOnScanDone)
|
||||
{
|
||||
Log->println("No networks found, restarting scan");
|
||||
scan(false, true);
|
||||
}
|
||||
else if (_openAP)
|
||||
{
|
||||
openAP();
|
||||
}
|
||||
else if(_convertOldWiFi)
|
||||
{
|
||||
Log->println("Trying to convert old WiFi settings");
|
||||
_convertOldWiFi = false;
|
||||
_preferences->putBool(preference_wifi_converted, true);
|
||||
|
||||
wifi_config_t wifi_cfg;
|
||||
if(esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK)
|
||||
{
|
||||
Log->println("Failed to get Wi-Fi configuration in RAM");
|
||||
}
|
||||
|
||||
if (esp_wifi_set_storage(WIFI_STORAGE_FLASH) != ESP_OK)
|
||||
{
|
||||
Log->println("Failed to set storage Wi-Fi");
|
||||
}
|
||||
|
||||
String tempSSID = String(reinterpret_cast<const char*>(wifi_cfg.sta.ssid));
|
||||
String tempPass = String(reinterpret_cast<const char*>(wifi_cfg.sta.password));
|
||||
tempSSID.trim();
|
||||
tempPass.trim();
|
||||
bool found = false;
|
||||
|
||||
for (int i = 0; i < _foundNetworks; i++)
|
||||
{
|
||||
if(tempSSID.length() > 0 && tempSSID == WiFi.SSID(i) && tempPass.length() > 0)
|
||||
{
|
||||
_preferences->putString(preference_wifi_ssid, tempSSID);
|
||||
_preferences->putString(preference_wifi_pass, tempPass);
|
||||
Log->println("Succesfully converted old WiFi settings");
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(wifi_cfg.sta.ssid, 0, sizeof(wifi_cfg.sta.ssid));
|
||||
memset(wifi_cfg.sta.password, 0, sizeof(wifi_cfg.sta.password));
|
||||
|
||||
if (esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK)
|
||||
{
|
||||
Log->println("Failed to clear NVS Wi-Fi configuration");
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
Log->println(String("Attempting to connect to saved SSID ") + String(ssid));
|
||||
_connectOnScanDone = true;
|
||||
_openAP = false;
|
||||
scan(false, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
restartEsp(RestartReason::ReconfigureWifi);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ssid.trim();
|
||||
pass.trim();
|
||||
|
||||
if(ssid.length() > 0 && pass.length() > 0)
|
||||
{
|
||||
Log->println(String("Attempting to connect to saved SSID ") + String(ssid));
|
||||
_connectOnScanDone = true;
|
||||
_openAP = false;
|
||||
scan(false, true);
|
||||
return;
|
||||
}
|
||||
else if(!_preferences->getBool(preference_wifi_converted, false))
|
||||
{
|
||||
_connectOnScanDone = false;
|
||||
_openAP = false;
|
||||
_convertOldWiFi = true;
|
||||
scan(false, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log->println("No SSID or Wifi password saved, opening AP");
|
||||
_connectOnScanDone = false;
|
||||
_openAP = true;
|
||||
scan(false, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void WifiDevice::scan(bool passive, bool async)
|
||||
{
|
||||
if(!_connecting)
|
||||
{
|
||||
WiFi.scanDelete();
|
||||
WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN);
|
||||
WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL);
|
||||
|
||||
if(async)
|
||||
{
|
||||
Log->println(F("Wi-Fi async scan started"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log->println(F("Wi-Fi sync scan started"));
|
||||
}
|
||||
if(passive)
|
||||
{
|
||||
WiFi.scanNetworks(async,false,true,75U);
|
||||
}
|
||||
else
|
||||
{
|
||||
WiFi.scanNetworks(async);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WifiDevice::openAP()
|
||||
{
|
||||
if(_startAP)
|
||||
{
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
WiFi.softAPsetHostname(_hostname.c_str());
|
||||
WiFi.softAP("NukiHub", "NukiHubESP32");
|
||||
_startAP = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool WifiDevice::connect()
|
||||
{
|
||||
bool ret = false;
|
||||
String ssid = _preferences->getString(preference_wifi_ssid, "");
|
||||
String pass = _preferences->getString(preference_wifi_pass, "");
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.setHostname(_hostname.c_str());
|
||||
delay(500);
|
||||
|
||||
int bestConnection = -1;
|
||||
for (int i = 0; i < _foundNetworks; i++)
|
||||
{
|
||||
if (ssid == WiFi.SSID(i))
|
||||
{
|
||||
Log->println(String(F("Saved SSID ")) + ssid + String(F(" found with RSSI: ")) +
|
||||
String(WiFi.RSSI(i)) + String(F("(")) +
|
||||
String(constrain((100.0 + WiFi.RSSI(i)) * 2, 0, 100)) +
|
||||
String(F(" %) and BSSID: ")) + WiFi.BSSIDstr(i) +
|
||||
String(F(" and channel: ")) + String(WiFi.channel(i)));
|
||||
if (bestConnection == -1)
|
||||
{
|
||||
bestConnection = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WiFi.RSSI(i) > WiFi.RSSI(bestConnection))
|
||||
{
|
||||
bestConnection = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestConnection == -1)
|
||||
{
|
||||
Log->print("No network found with SSID: ");
|
||||
Log->println(ssid);
|
||||
if(_preferences->getBool(preference_restart_on_disconnect, false) && (espMillis() > 60000))
|
||||
{
|
||||
restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
||||
}
|
||||
_connectOnScanDone = true;
|
||||
_openAP = false;
|
||||
scan(false, true);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_connecting = true;
|
||||
esp_wifi_scan_stop();
|
||||
Log->println(String(F("Trying to connect to SSID ")) + ssid + String(F(" found with RSSI: ")) +
|
||||
String(WiFi.RSSI(bestConnection)) + String(F("(")) +
|
||||
String(constrain((100.0 + WiFi.RSSI(bestConnection)) * 2, 0, 100)) +
|
||||
String(F(" %) and BSSID: ")) + WiFi.BSSIDstr(bestConnection) +
|
||||
String(F(" and channel: ")) + String(WiFi.channel(bestConnection)));
|
||||
|
||||
|
||||
if(!_ipConfiguration->dhcpEnabled())
|
||||
{
|
||||
WiFi.config(_ipConfiguration->ipAddress(), _ipConfiguration->dnsServer(), _ipConfiguration->defaultGateway(), _ipConfiguration->subnet());
|
||||
}
|
||||
|
||||
WiFi.begin(ssid, pass);
|
||||
auto status = WiFi.waitForConnectResult(10000);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case WL_CONNECTED:
|
||||
Log->println("WiFi connected");
|
||||
break;
|
||||
case WL_NO_SSID_AVAIL:
|
||||
Log->println("WiFi SSID not available");
|
||||
break;
|
||||
case WL_CONNECT_FAILED:
|
||||
Log->println("WiFi connection failed");
|
||||
break;
|
||||
case WL_IDLE_STATUS:
|
||||
Log->println("WiFi changing status");
|
||||
break;
|
||||
case WL_DISCONNECTED:
|
||||
Log->println("WiFi disconnected");
|
||||
break;
|
||||
default:
|
||||
Log->println("WiFi timeout");
|
||||
break;
|
||||
}
|
||||
|
||||
if (status != WL_CONNECTED)
|
||||
{
|
||||
if(_preferences->getBool(preference_restart_on_disconnect, false) && (espMillis() > 60000))
|
||||
{
|
||||
restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
||||
_connecting = false;
|
||||
return false;
|
||||
}
|
||||
Log->println("Retrying");
|
||||
_connectOnScanDone = true;
|
||||
_openAP = false;
|
||||
scan(false, true);
|
||||
_connecting = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!_preferences->getBool(preference_wifi_converted, false))
|
||||
{
|
||||
_preferences->putBool(preference_wifi_converted, true);
|
||||
}
|
||||
_connecting = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void WifiDevice::reconfigure()
|
||||
{
|
||||
strcpy(WiFiDevice_reconfdetect, "reconfigure_wifi");
|
||||
_preferences->putString(preference_wifi_ssid, "");
|
||||
_preferences->putString(preference_wifi_pass, "");
|
||||
delay(200);
|
||||
restartEsp(RestartReason::ReconfigureWifi);
|
||||
}
|
||||
|
||||
bool WifiDevice::supportsEncryption()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiDevice::isConnected()
|
||||
{
|
||||
return WiFi.isConnected();
|
||||
}
|
||||
|
||||
ReconnectStatus WifiDevice::reconnect(bool force)
|
||||
{
|
||||
_wm.setFindBestRSSI(_preferences->getBool(preference_find_best_rssi));
|
||||
|
||||
if((!isConnected() || force) && !_isReconnecting)
|
||||
if (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
_isReconnecting = true;
|
||||
WiFi.disconnect();
|
||||
int loop = 0;
|
||||
|
||||
while(isConnected() && loop <20)
|
||||
{
|
||||
delay(100);
|
||||
loop++;
|
||||
}
|
||||
|
||||
_wm.resetScan();
|
||||
_wm.autoConnect();
|
||||
_isReconnecting = false;
|
||||
return false;
|
||||
}
|
||||
if (!_hasIP)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!isConnected() && _disconnectTs > (esp_timer_get_time() / 1000) - 120000) _wm.setEnableConfigPortal(_startAp || !_preferences->getBool(preference_network_wifi_fallback_disabled, false));
|
||||
return isConnected() ? ReconnectStatus::Success : ReconnectStatus::Failure;
|
||||
return true;
|
||||
}
|
||||
|
||||
void WifiDevice::onConnected()
|
||||
{
|
||||
_isReconnecting = false;
|
||||
_wm.setEnableConfigPortal(_startAp || !_preferences->getBool(preference_network_wifi_fallback_disabled, false));
|
||||
Log->println(F("Wi-Fi connected"));
|
||||
_connectedChannel = WiFi.channel();
|
||||
_connectedBSSID = WiFi.BSSID();
|
||||
_connected = true;
|
||||
}
|
||||
|
||||
void WifiDevice::onDisconnected()
|
||||
{
|
||||
_disconnectTs = (esp_timer_get_time() / 1000);
|
||||
if(_preferences->getBool(preference_restart_on_disconnect, false) && ((esp_timer_get_time() / 1000) > 60000)) restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
||||
_wm.setEnableConfigPortal(false);
|
||||
reconnect();
|
||||
if(_connected)
|
||||
{
|
||||
_connected = false;
|
||||
_disconnectTs = espMillis();
|
||||
Log->println(F("Wi-Fi disconnected"));
|
||||
|
||||
//QUICK RECONNECT
|
||||
_connecting = true;
|
||||
String ssid = _preferences->getString(preference_wifi_ssid, "");
|
||||
String pass = _preferences->getString(preference_wifi_pass, "");
|
||||
|
||||
if(!_ipConfiguration->dhcpEnabled())
|
||||
{
|
||||
WiFi.config(_ipConfiguration->ipAddress(), _ipConfiguration->dnsServer(), _ipConfiguration->defaultGateway(), _ipConfiguration->subnet());
|
||||
}
|
||||
|
||||
WiFi.begin(ssid, pass);
|
||||
|
||||
int loop = 0;
|
||||
|
||||
while(!isConnected() && loop < 200)
|
||||
{
|
||||
loop++;
|
||||
delay(100);
|
||||
}
|
||||
|
||||
_connecting = false;
|
||||
//END QUICK RECONECT
|
||||
|
||||
if(!isConnected())
|
||||
{
|
||||
if(_preferences->getBool(preference_restart_on_disconnect, false) && (espMillis() > 60000))
|
||||
{
|
||||
restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
||||
}
|
||||
|
||||
WiFi.disconnect(true);
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.disconnect();
|
||||
delay(500);
|
||||
|
||||
wifi_mode_t wifiMode;
|
||||
esp_wifi_get_mode(&wifiMode);
|
||||
|
||||
while (wifiMode != WIFI_MODE_STA || WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
delay(500);
|
||||
Log->println(F("Waiting for WiFi mode change or disconnection."));
|
||||
esp_wifi_get_mode(&wifiMode);
|
||||
}
|
||||
|
||||
_connectOnScanDone = true;
|
||||
_openAP = false;
|
||||
scan(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int8_t WifiDevice::signalStrength()
|
||||
@@ -209,7 +419,7 @@ String WifiDevice::BSSIDstr()
|
||||
return WiFi.BSSIDstr();
|
||||
}
|
||||
|
||||
void WifiDevice::clearRtcInitVar(WiFiManager *)
|
||||
bool WifiDevice::isApOpen()
|
||||
{
|
||||
memset(WiFiDevice_reconfdetect, 0, sizeof WiFiDevice_reconfdetect);
|
||||
}
|
||||
return _openAP;
|
||||
}
|
||||
@@ -4,10 +4,6 @@
|
||||
#include <NetworkClientSecure.h>
|
||||
#include <Preferences.h>
|
||||
#include "NetworkDevice.h"
|
||||
#include "WiFiManager.h"
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
#include "espMqttClient.h"
|
||||
#endif
|
||||
#include "IPConfiguration.h"
|
||||
|
||||
class WifiDevice : public NetworkDevice
|
||||
@@ -19,33 +15,33 @@ public:
|
||||
|
||||
virtual void initialize();
|
||||
virtual void reconfigure();
|
||||
virtual ReconnectStatus reconnect(bool force = false);
|
||||
bool supportsEncryption() override;
|
||||
virtual void scan(bool passive = false, bool async = true);
|
||||
|
||||
virtual bool isConnected();
|
||||
virtual bool isApOpen();
|
||||
|
||||
int8_t signalStrength() override;
|
||||
|
||||
String localIP() override;
|
||||
String BSSIDstr() override;
|
||||
|
||||
private:
|
||||
static void clearRtcInitVar(WiFiManager*);
|
||||
|
||||
void openAP();
|
||||
void onDisconnected();
|
||||
void onConnected();
|
||||
bool connect();
|
||||
|
||||
WiFiManager _wm;
|
||||
Preferences* _preferences = nullptr;
|
||||
|
||||
bool _startAp = false;
|
||||
bool _isReconnecting = false;
|
||||
char* _path;
|
||||
int _foundNetworks = 0;
|
||||
int _disconnectCount = 0;
|
||||
bool _connectOnScanDone = false;
|
||||
bool _connecting = false;
|
||||
bool _openAP = false;
|
||||
bool _startAP = true;
|
||||
bool _convertOldWiFi = false;
|
||||
bool _connected = false;
|
||||
bool _hasIP = false;
|
||||
uint8_t _connectedChannel = 0;
|
||||
uint8_t* _connectedBSSID;
|
||||
int64_t _disconnectTs = 0;
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
char _ca[TLS_CA_MAX_SIZE] = {0};
|
||||
char _cert[TLS_CERT_MAX_SIZE] = {0};
|
||||
char _key[TLS_KEY_MAX_SIZE] = {0};
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -13,153 +13,153 @@ NetworkDevice *NetworkDeviceInstantiator::Create(NetworkDeviceType networkDevice
|
||||
|
||||
switch (networkDeviceType)
|
||||
{
|
||||
case NetworkDeviceType::W5500:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "Generic W5500",
|
||||
ETH_PHY_ADDR_W5500,
|
||||
ETH_PHY_CS_GENERIC_W5500,
|
||||
ETH_PHY_IRQ_GENERIC_W5500,
|
||||
ETH_PHY_RST_GENERIC_W5500,
|
||||
ETH_PHY_SPI_SCK_GENERIC_W5500,
|
||||
ETH_PHY_SPI_MISO_GENERIC_W5500,
|
||||
ETH_PHY_SPI_MOSI_GENERIC_W5500,
|
||||
ETH_PHY_W5500);
|
||||
break;
|
||||
case NetworkDeviceType::W5500M5:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "M5Stack Atom POE",
|
||||
ETH_PHY_ADDR_W5500,
|
||||
ETH_PHY_CS_M5_W5500,
|
||||
ETH_PHY_IRQ_M5_W5500,
|
||||
ETH_PHY_RST_M5_W5500,
|
||||
ETH_PHY_SPI_SCK_M5_W5500,
|
||||
ETH_PHY_SPI_MISO_M5_W5500,
|
||||
ETH_PHY_SPI_MOSI_M5_W5500,
|
||||
ETH_PHY_W5500);
|
||||
break;
|
||||
case NetworkDeviceType::W5500M5S3:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "M5Stack Atom POE S3",
|
||||
ETH_PHY_ADDR_W5500,
|
||||
ETH_PHY_CS_M5_W5500_S3,
|
||||
ETH_PHY_IRQ_M5_W5500,
|
||||
ETH_PHY_RST_M5_W5500,
|
||||
ETH_PHY_SPI_SCK_M5_W5500_S3,
|
||||
ETH_PHY_SPI_MISO_M5_W5500_S3,
|
||||
ETH_PHY_SPI_MOSI_M5_W5500_S3,
|
||||
ETH_PHY_W5500);
|
||||
break;
|
||||
case NetworkDeviceType::ETH01_Evo:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "ETH01-Evo",
|
||||
ETH_PHY_ADDR_ETH01EVO,
|
||||
ETH_PHY_CS_ETH01EVO,
|
||||
ETH_PHY_IRQ_ETH01EVO,
|
||||
ETH_PHY_RST_ETH01EVO,
|
||||
ETH_PHY_SPI_SCK_ETH01EVO,
|
||||
ETH_PHY_SPI_MISO_ETH01EVO,
|
||||
ETH_PHY_SPI_MOSI_ETH01EVO,
|
||||
ETH_PHY_TYPE_DM9051);
|
||||
break;
|
||||
case NetworkDeviceType::M5STACK_PoESP32_Unit:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "M5STACK PoESP32 Unit",
|
||||
ETH_PHY_ADDR_W5500,
|
||||
ETH_PHY_CS_M5_W5500,
|
||||
ETH_PHY_IRQ_M5_W5500,
|
||||
ETH_PHY_RST_M5_W5500,
|
||||
ETH_PHY_SPI_SCK_M5_W5500,
|
||||
ETH_PHY_SPI_MISO_M5_W5500,
|
||||
ETH_PHY_SPI_MOSI_M5_W5500,
|
||||
ETH_PHY_W5500);
|
||||
break;
|
||||
case NetworkDeviceType::CUSTOM:
|
||||
case NetworkDeviceType::W5500:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "Generic W5500",
|
||||
ETH_PHY_ADDR_W5500,
|
||||
ETH_PHY_CS_GENERIC_W5500,
|
||||
ETH_PHY_IRQ_GENERIC_W5500,
|
||||
ETH_PHY_RST_GENERIC_W5500,
|
||||
ETH_PHY_SPI_SCK_GENERIC_W5500,
|
||||
ETH_PHY_SPI_MISO_GENERIC_W5500,
|
||||
ETH_PHY_SPI_MOSI_GENERIC_W5500,
|
||||
ETH_PHY_W5500);
|
||||
break;
|
||||
case NetworkDeviceType::W5500M5:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "M5Stack Atom POE",
|
||||
ETH_PHY_ADDR_W5500,
|
||||
ETH_PHY_CS_M5_W5500,
|
||||
ETH_PHY_IRQ_M5_W5500,
|
||||
ETH_PHY_RST_M5_W5500,
|
||||
ETH_PHY_SPI_SCK_M5_W5500,
|
||||
ETH_PHY_SPI_MISO_M5_W5500,
|
||||
ETH_PHY_SPI_MOSI_M5_W5500,
|
||||
ETH_PHY_W5500);
|
||||
break;
|
||||
case NetworkDeviceType::W5500M5S3:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "M5Stack Atom POE S3",
|
||||
ETH_PHY_ADDR_W5500,
|
||||
ETH_PHY_CS_M5_W5500_S3,
|
||||
ETH_PHY_IRQ_M5_W5500,
|
||||
ETH_PHY_RST_M5_W5500,
|
||||
ETH_PHY_SPI_SCK_M5_W5500_S3,
|
||||
ETH_PHY_SPI_MISO_M5_W5500_S3,
|
||||
ETH_PHY_SPI_MOSI_M5_W5500_S3,
|
||||
ETH_PHY_W5500);
|
||||
break;
|
||||
case NetworkDeviceType::ETH01_Evo:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "ETH01-Evo",
|
||||
ETH_PHY_ADDR_ETH01EVO,
|
||||
ETH_PHY_CS_ETH01EVO,
|
||||
ETH_PHY_IRQ_ETH01EVO,
|
||||
ETH_PHY_RST_ETH01EVO,
|
||||
ETH_PHY_SPI_SCK_ETH01EVO,
|
||||
ETH_PHY_SPI_MISO_ETH01EVO,
|
||||
ETH_PHY_SPI_MOSI_ETH01EVO,
|
||||
ETH_PHY_TYPE_DM9051);
|
||||
break;
|
||||
case NetworkDeviceType::M5STACK_PoESP32_Unit:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "M5STACK PoESP32 Unit",
|
||||
ETH_PHY_ADDR_W5500,
|
||||
ETH_PHY_CS_M5_W5500,
|
||||
ETH_PHY_IRQ_M5_W5500,
|
||||
ETH_PHY_RST_M5_W5500,
|
||||
ETH_PHY_SPI_SCK_M5_W5500,
|
||||
ETH_PHY_SPI_MISO_M5_W5500,
|
||||
ETH_PHY_SPI_MOSI_M5_W5500,
|
||||
ETH_PHY_W5500);
|
||||
break;
|
||||
case NetworkDeviceType::CUSTOM:
|
||||
{
|
||||
int custPHY = preferences->getInt(preference_network_custom_phy, 0);
|
||||
|
||||
if(custPHY >= 1 && custPHY <= 3)
|
||||
{
|
||||
int custPHY = preferences->getInt(preference_network_custom_phy, 0);
|
||||
std::string custName;
|
||||
eth_phy_type_t custEthtype;
|
||||
|
||||
if(custPHY >= 1 && custPHY <= 3)
|
||||
switch(custPHY)
|
||||
{
|
||||
std::string custName;
|
||||
eth_phy_type_t custEthtype;
|
||||
|
||||
switch(custPHY)
|
||||
{
|
||||
case 1:
|
||||
custName = "Custom (W5500)";
|
||||
custEthtype = ETH_PHY_W5500;
|
||||
break;
|
||||
case 2:
|
||||
custName = "Custom (DN9051)";
|
||||
custEthtype = ETH_PHY_DM9051;
|
||||
break;
|
||||
case 3:
|
||||
custName = "Custom (KSZ8851SNL)";
|
||||
custEthtype = ETH_PHY_KSZ8851;
|
||||
break;
|
||||
default:
|
||||
custName = "Custom (W5500)";
|
||||
custEthtype = ETH_PHY_W5500;
|
||||
break;
|
||||
}
|
||||
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, custName,
|
||||
preferences->getInt(preference_network_custom_addr, -1),
|
||||
preferences->getInt(preference_network_custom_cs, -1),
|
||||
preferences->getInt(preference_network_custom_irq, -1),
|
||||
preferences->getInt(preference_network_custom_rst, -1),
|
||||
preferences->getInt(preference_network_custom_sck, -1),
|
||||
preferences->getInt(preference_network_custom_miso, -1),
|
||||
preferences->getInt(preference_network_custom_mosi, -1),
|
||||
custEthtype);
|
||||
}
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||
else if(custPHY >= 4 && custPHY <= 9)
|
||||
{
|
||||
int custCLKpref = preferences->getInt(preference_network_custom_clk, 0);
|
||||
|
||||
std::string custName = NetworkUtil::GetCustomEthernetDeviceName(custPHY);
|
||||
eth_phy_type_t custEthtype = NetworkUtil::GetCustomEthernetType(custPHY);
|
||||
eth_clock_mode_t custCLK = NetworkUtil::GetCustomClock(custCLKpref);
|
||||
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, custName, preferences->getInt(preference_network_custom_addr, -1), preferences->getInt(preference_network_custom_pwr, -1), preferences->getInt(preference_network_custom_mdc, -1), preferences->getInt(preference_network_custom_mdio, -1), custEthtype, custCLK);
|
||||
}
|
||||
#endif
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
else
|
||||
{
|
||||
device = new WifiDevice(hostname, preferences, ipConfiguration);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||
case NetworkDeviceType::Olimex_LAN8720:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "Olimex (LAN8720)", ETH_PHY_ADDR_LAN8720, 12, ETH_PHY_MDC_LAN8720, ETH_PHY_MDIO_LAN8720, ETH_PHY_TYPE_LAN8720, ETH_CLOCK_GPIO17_OUT);
|
||||
break;
|
||||
case NetworkDeviceType::WT32_LAN8720:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "WT32-ETH01", 1, 16);
|
||||
break;
|
||||
case NetworkDeviceType::GL_S10:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "GL-S10", 1, 5, ETH_PHY_MDC_LAN8720, ETH_PHY_MDIO_LAN8720, ETH_PHY_IP101, ETH_CLOCK_GPIO0_IN);
|
||||
break;
|
||||
case NetworkDeviceType::LilyGO_T_ETH_POE:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "LilyGO T-ETH-POE", 0, -1, ETH_PHY_MDC_LAN8720, ETH_PHY_MDIO_LAN8720, ETH_PHY_TYPE_LAN8720, ETH_CLOCK_GPIO17_OUT);
|
||||
break;
|
||||
#endif
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
case NetworkDeviceType::WiFi:
|
||||
device = new WifiDevice(hostname, preferences, ipConfiguration);
|
||||
break;
|
||||
default:
|
||||
device = new WifiDevice(hostname, preferences, ipConfiguration);
|
||||
break;
|
||||
#else
|
||||
case 1:
|
||||
custName = "Custom (W5500)";
|
||||
custEthtype = ETH_PHY_W5500;
|
||||
break;
|
||||
case 2:
|
||||
custName = "Custom (DN9051)";
|
||||
custEthtype = ETH_PHY_DM9051;
|
||||
break;
|
||||
case 3:
|
||||
custName = "Custom (KSZ8851SNL)";
|
||||
custEthtype = ETH_PHY_KSZ8851;
|
||||
break;
|
||||
default:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "Custom (W5500)",
|
||||
preferences->getInt(preference_network_custom_addr, -1),
|
||||
preferences->getInt(preference_network_custom_cs, -1),
|
||||
preferences->getInt(preference_network_custom_irq, -1),
|
||||
preferences->getInt(preference_network_custom_rst, -1),
|
||||
preferences->getInt(preference_network_custom_sck, -1),
|
||||
preferences->getInt(preference_network_custom_miso, -1),
|
||||
preferences->getInt(preference_network_custom_mosi, -1),
|
||||
ETH_PHY_W5500);
|
||||
break;
|
||||
custName = "Custom (W5500)";
|
||||
custEthtype = ETH_PHY_W5500;
|
||||
break;
|
||||
}
|
||||
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, custName,
|
||||
preferences->getInt(preference_network_custom_addr, -1),
|
||||
preferences->getInt(preference_network_custom_cs, -1),
|
||||
preferences->getInt(preference_network_custom_irq, -1),
|
||||
preferences->getInt(preference_network_custom_rst, -1),
|
||||
preferences->getInt(preference_network_custom_sck, -1),
|
||||
preferences->getInt(preference_network_custom_miso, -1),
|
||||
preferences->getInt(preference_network_custom_mosi, -1),
|
||||
custEthtype);
|
||||
}
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||
else if(custPHY >= 4 && custPHY <= 9)
|
||||
{
|
||||
int custCLKpref = preferences->getInt(preference_network_custom_clk, 0);
|
||||
|
||||
std::string custName = NetworkUtil::GetCustomEthernetDeviceName(custPHY);
|
||||
eth_phy_type_t custEthtype = NetworkUtil::GetCustomEthernetType(custPHY);
|
||||
eth_clock_mode_t custCLK = NetworkUtil::GetCustomClock(custCLKpref);
|
||||
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, custName, preferences->getInt(preference_network_custom_addr, -1), preferences->getInt(preference_network_custom_pwr, -1), preferences->getInt(preference_network_custom_mdc, -1), preferences->getInt(preference_network_custom_mdio, -1), custEthtype, custCLK);
|
||||
}
|
||||
#endif
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
else
|
||||
{
|
||||
device = new WifiDevice(hostname, preferences, ipConfiguration);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||
case NetworkDeviceType::Olimex_LAN8720:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "Olimex (LAN8720)", ETH_PHY_ADDR_LAN8720, 12, ETH_PHY_MDC_LAN8720, ETH_PHY_MDIO_LAN8720, ETH_PHY_TYPE_LAN8720, ETH_CLOCK_GPIO17_OUT);
|
||||
break;
|
||||
case NetworkDeviceType::WT32_LAN8720:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "WT32-ETH01", 1, 16);
|
||||
break;
|
||||
case NetworkDeviceType::GL_S10:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "GL-S10", 1, 5, ETH_PHY_MDC_LAN8720, ETH_PHY_MDIO_LAN8720, ETH_PHY_IP101, ETH_CLOCK_GPIO0_IN);
|
||||
break;
|
||||
case NetworkDeviceType::LilyGO_T_ETH_POE:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "LilyGO T-ETH-POE", 0, -1, ETH_PHY_MDC_LAN8720, ETH_PHY_MDIO_LAN8720, ETH_PHY_TYPE_LAN8720, ETH_CLOCK_GPIO17_OUT);
|
||||
break;
|
||||
#endif
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
case NetworkDeviceType::WiFi:
|
||||
device = new WifiDevice(hostname, preferences, ipConfiguration);
|
||||
break;
|
||||
default:
|
||||
device = new WifiDevice(hostname, preferences, ipConfiguration);
|
||||
break;
|
||||
#else
|
||||
default:
|
||||
device = new EthernetDevice(hostname, preferences, ipConfiguration, "Custom (W5500)",
|
||||
preferences->getInt(preference_network_custom_addr, -1),
|
||||
preferences->getInt(preference_network_custom_cs, -1),
|
||||
preferences->getInt(preference_network_custom_irq, -1),
|
||||
preferences->getInt(preference_network_custom_rst, -1),
|
||||
preferences->getInt(preference_network_custom_sck, -1),
|
||||
preferences->getInt(preference_network_custom_miso, -1),
|
||||
preferences->getInt(preference_network_custom_mosi, -1),
|
||||
ETH_PHY_W5500);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -6,50 +6,50 @@ NetworkDeviceType NetworkUtil::GetDeviceTypeFromPreference(int hardwareDetect, i
|
||||
{
|
||||
switch (hardwareDetect)
|
||||
{
|
||||
case 1:
|
||||
case 1:
|
||||
return NetworkDeviceType::WiFi;
|
||||
break;
|
||||
case 2:
|
||||
return NetworkDeviceType::W5500;
|
||||
break;
|
||||
case 3:
|
||||
return NetworkDeviceType::W5500M5;
|
||||
break;
|
||||
case 4:
|
||||
return NetworkDeviceType::Olimex_LAN8720;
|
||||
break;
|
||||
case 5:
|
||||
return NetworkDeviceType::WT32_LAN8720;
|
||||
break;
|
||||
case 6:
|
||||
return NetworkDeviceType::M5STACK_PoESP32_Unit;
|
||||
break;
|
||||
case 7:
|
||||
return NetworkDeviceType::LilyGO_T_ETH_POE;
|
||||
break;
|
||||
case 8:
|
||||
return NetworkDeviceType::GL_S10;
|
||||
break;
|
||||
case 9:
|
||||
return NetworkDeviceType::ETH01_Evo;
|
||||
break;
|
||||
case 10:
|
||||
return NetworkDeviceType::W5500M5S3;
|
||||
break;
|
||||
case 11:
|
||||
if(customPhy> 0)
|
||||
{
|
||||
return NetworkDeviceType::CUSTOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NetworkDeviceType::WiFi;
|
||||
break;
|
||||
case 2:
|
||||
return NetworkDeviceType::W5500;
|
||||
break;
|
||||
case 3:
|
||||
return NetworkDeviceType::W5500M5;
|
||||
break;
|
||||
case 4:
|
||||
return NetworkDeviceType::Olimex_LAN8720;
|
||||
break;
|
||||
case 5:
|
||||
return NetworkDeviceType::WT32_LAN8720;
|
||||
break;
|
||||
case 6:
|
||||
return NetworkDeviceType::M5STACK_PoESP32_Unit;
|
||||
break;
|
||||
case 7:
|
||||
return NetworkDeviceType::LilyGO_T_ETH_POE;
|
||||
break;
|
||||
case 8:
|
||||
return NetworkDeviceType::GL_S10;
|
||||
break;
|
||||
case 9:
|
||||
return NetworkDeviceType::ETH01_Evo;
|
||||
break;
|
||||
case 10:
|
||||
return NetworkDeviceType::W5500M5S3;
|
||||
break;
|
||||
case 11:
|
||||
if(customPhy> 0)
|
||||
{
|
||||
return NetworkDeviceType::CUSTOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NetworkDeviceType::WiFi;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log->println(F("Unknown hardware selected, falling back to Wi-Fi."));
|
||||
return NetworkDeviceType::WiFi;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log->println(F("Unknown hardware selected, falling back to Wi-Fi."));
|
||||
return NetworkDeviceType::WiFi;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,20 +57,20 @@ std::string NetworkUtil::GetCustomEthernetDeviceName(int custPHY)
|
||||
{
|
||||
switch(custPHY)
|
||||
{
|
||||
case 4:
|
||||
return "Custom (LAN8720)";
|
||||
case 5:
|
||||
return"Custom (RTL8201)";
|
||||
case 6:
|
||||
return "Custom (TLK110)";
|
||||
case 7:
|
||||
return "Custom (DP83848)";
|
||||
case 8:
|
||||
return "Custom (KSZ8041)";
|
||||
case 9:
|
||||
return "Custom (KSZ8081)";
|
||||
default:
|
||||
return"Custom (LAN8720)";
|
||||
case 4:
|
||||
return "Custom (LAN8720)";
|
||||
case 5:
|
||||
return"Custom (RTL8201)";
|
||||
case 6:
|
||||
return "Custom (TLK110)";
|
||||
case 7:
|
||||
return "Custom (DP83848)";
|
||||
case 8:
|
||||
return "Custom (KSZ8041)";
|
||||
case 9:
|
||||
return "Custom (KSZ8081)";
|
||||
default:
|
||||
return"Custom (LAN8720)";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,27 +79,27 @@ eth_phy_type_t NetworkUtil::GetCustomEthernetType(int custPHY)
|
||||
{
|
||||
switch(custPHY)
|
||||
{
|
||||
case 4:
|
||||
return ETH_PHY_TYPE_LAN8720;
|
||||
break;
|
||||
case 5:
|
||||
return ETH_PHY_RTL8201;
|
||||
break;
|
||||
case 6:
|
||||
return ETH_PHY_TLK110;
|
||||
break;
|
||||
case 7:
|
||||
return ETH_PHY_DP83848;
|
||||
break;
|
||||
case 8:
|
||||
return ETH_PHY_KSZ8041;
|
||||
break;
|
||||
case 9:
|
||||
return ETH_PHY_KSZ8081;
|
||||
break;
|
||||
default:
|
||||
return ETH_PHY_TYPE_LAN8720;
|
||||
break;
|
||||
case 4:
|
||||
return ETH_PHY_TYPE_LAN8720;
|
||||
break;
|
||||
case 5:
|
||||
return ETH_PHY_RTL8201;
|
||||
break;
|
||||
case 6:
|
||||
return ETH_PHY_TLK110;
|
||||
break;
|
||||
case 7:
|
||||
return ETH_PHY_DP83848;
|
||||
break;
|
||||
case 8:
|
||||
return ETH_PHY_KSZ8041;
|
||||
break;
|
||||
case 9:
|
||||
return ETH_PHY_KSZ8081;
|
||||
break;
|
||||
default:
|
||||
return ETH_PHY_TYPE_LAN8720;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,18 +107,18 @@ eth_clock_mode_t NetworkUtil::GetCustomClock(int custCLKpref)
|
||||
{
|
||||
switch(custCLKpref)
|
||||
{
|
||||
case 0:
|
||||
return ETH_CLOCK_GPIO0_IN;
|
||||
break;
|
||||
case 2:
|
||||
return ETH_CLOCK_GPIO16_OUT;
|
||||
break;
|
||||
case 3:
|
||||
return ETH_CLOCK_GPIO17_OUT;
|
||||
break;
|
||||
default:
|
||||
return ETH_CLOCK_GPIO17_OUT;
|
||||
break;
|
||||
case 0:
|
||||
return ETH_CLOCK_GPIO0_IN;
|
||||
break;
|
||||
case 2:
|
||||
return ETH_CLOCK_GPIO16_OUT;
|
||||
break;
|
||||
case 3:
|
||||
return ETH_CLOCK_GPIO17_OUT;
|
||||
break;
|
||||
default:
|
||||
return ETH_CLOCK_GPIO17_OUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user