allow to set config values
This commit is contained in:
31
Network.cpp
31
Network.cpp
@@ -12,6 +12,11 @@ Network::Network(Preferences* preferences)
|
||||
_preferences(preferences)
|
||||
{
|
||||
nwInst = this;
|
||||
|
||||
_configTopics.reserve(3);
|
||||
_configTopics.push_back(mqtt_topic_config_button_enabled);
|
||||
_configTopics.push_back(mqtt_topic_config_led_enabled);
|
||||
_configTopics.push_back(mqtt_topic_config_led_brightness);
|
||||
}
|
||||
|
||||
void Network::initialize()
|
||||
@@ -129,9 +134,11 @@ bool Network::reconnect()
|
||||
_mqttConnected = true;
|
||||
delay(200);
|
||||
subscribe(mqtt_topic_lockstate_action);
|
||||
subscribe(mqtt_topic_config_button_enabled);
|
||||
subscribe(mqtt_topic_config_led_enabled);
|
||||
subscribe(mqtt_topic_config_led_brightness);
|
||||
|
||||
for(auto topic : _configTopics)
|
||||
{
|
||||
subscribe(topic);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -197,6 +204,17 @@ void Network::onMqttDataReceived(char *&topic, byte *&payload, unsigned int &len
|
||||
}
|
||||
publishString(mqtt_topic_lockstate_action, "");
|
||||
}
|
||||
|
||||
for(auto configTopic : _configTopics)
|
||||
{
|
||||
if(comparePrefixedPath(topic, configTopic))
|
||||
{
|
||||
if(_configUpdateReceivedCallback != nullptr)
|
||||
{
|
||||
_configUpdateReceivedCallback(configTopic, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Network::publishKeyTurnerState(const Nuki::KeyTurnerState& keyTurnerState, const Nuki::KeyTurnerState& lastKeyTurnerState)
|
||||
@@ -264,11 +282,16 @@ void Network::publishPresenceDetection(char *csv)
|
||||
_presenceCsv = csv;
|
||||
}
|
||||
|
||||
void Network::setLockActionReceived(void (*lockActionReceivedCallback)(const char *))
|
||||
void Network::setLockActionReceivedCallback(void (*lockActionReceivedCallback)(const char *))
|
||||
{
|
||||
_lockActionReceivedCallback = lockActionReceivedCallback;
|
||||
}
|
||||
|
||||
void Network::setConfigUpdateReceivedCallback(void (*configUpdateReceivedCallback)(const char *, const char *))
|
||||
{
|
||||
_configUpdateReceivedCallback = configUpdateReceivedCallback;
|
||||
}
|
||||
|
||||
void Network::publishFloat(const char* topic, const float value, const uint8_t precision)
|
||||
{
|
||||
char str[30];
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <PubSubClient.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <Preferences.h>
|
||||
#include <vector>
|
||||
#include "NukiConstants.h"
|
||||
#include "SpiffsCookie.h"
|
||||
|
||||
@@ -22,7 +23,8 @@ public:
|
||||
void publishConfig(const Nuki::Config& config);
|
||||
void publishPresenceDetection(char* csv);
|
||||
|
||||
void setLockActionReceived(void (*lockActionReceivedCallback)(const char* value));
|
||||
void setLockActionReceivedCallback(void (*lockActionReceivedCallback)(const char* value));
|
||||
void setConfigUpdateReceivedCallback(void (*configUpdateReceivedCallback)(const char* path, const char* value));
|
||||
|
||||
void restartAndConfigureWifi();
|
||||
|
||||
@@ -56,7 +58,10 @@ private:
|
||||
|
||||
char* _presenceCsv = nullptr;
|
||||
|
||||
std::vector<char*> _configTopics;
|
||||
|
||||
bool _firstTunerStatePublish = true;
|
||||
|
||||
void (*_lockActionReceivedCallback)(const char* value) = NULL;
|
||||
void (*_lockActionReceivedCallback)(const char* value) = nullptr;
|
||||
void (*_configUpdateReceivedCallback)(const char* path, const char* value) = nullptr;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "NukiWrapper.h"
|
||||
#include <FreeRTOS.h>
|
||||
#include "PreferencesKeys.h"
|
||||
#include "MqttTopics.h"
|
||||
|
||||
NukiWrapper* nukiInst;
|
||||
|
||||
@@ -18,7 +19,8 @@ NukiWrapper::NukiWrapper(const std::string& deviceName, uint32_t id, Network* ne
|
||||
memset(&_keyTurnerState, sizeof(Nuki::KeyTurnerState), 0);
|
||||
_keyTurnerState.lockState = Nuki::LockState::Undefined;
|
||||
|
||||
network->setLockActionReceived(nukiInst->onLockActionReceived);
|
||||
network->setLockActionReceivedCallback(nukiInst->onLockActionReceivedCallback);
|
||||
network->setConfigUpdateReceivedCallback(nukiInst->onConfigUpdateReceivedCallback);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,6 +114,11 @@ void NukiWrapper::update()
|
||||
memcpy(&_lastKeyTurnerState, &_keyTurnerState, sizeof(Nuki::KeyTurnerState));
|
||||
}
|
||||
|
||||
void NukiWrapper::setPin(const uint16_t pin)
|
||||
{
|
||||
_nukiBle.saveSecurityPincode(pin);
|
||||
}
|
||||
|
||||
void NukiWrapper::updateKeyTurnerState()
|
||||
{
|
||||
_nukiBle.requestKeyTurnerState(&_keyTurnerState);
|
||||
@@ -162,11 +169,42 @@ Nuki::LockAction NukiWrapper::lockActionToEnum(const char *str)
|
||||
return (Nuki::LockAction)0xff;
|
||||
}
|
||||
|
||||
void NukiWrapper::onLockActionReceived(const char *value)
|
||||
void NukiWrapper::onLockActionReceivedCallback(const char *value)
|
||||
{
|
||||
nukiInst->_nextLockAction = nukiInst->lockActionToEnum(value);
|
||||
}
|
||||
|
||||
void NukiWrapper::onConfigUpdateReceivedCallback(const char *topic, const char *value)
|
||||
{
|
||||
nukiInst->onConfigUpdateReceived(topic, value);
|
||||
}
|
||||
|
||||
|
||||
void NukiWrapper::onConfigUpdateReceived(const char *topic, const char *value)
|
||||
{
|
||||
if(strcmp(topic, mqtt_topic_config_button_enabled) == 0)
|
||||
{
|
||||
bool newValue = atoi(value) > 0;
|
||||
if(!_nukiConfigValid || _nukiConfig.buttonEnabled == newValue) return;
|
||||
_nukiBle.enableButton(newValue);
|
||||
_nextConfigUpdateTs = millis() + 300;
|
||||
}
|
||||
if(strcmp(topic, mqtt_topic_config_led_enabled) == 0)
|
||||
{
|
||||
bool newValue = atoi(value) > 0;
|
||||
if(!_nukiConfigValid || _nukiConfig.ledEnabled == newValue) return;
|
||||
_nukiBle.enableLedFlash(newValue);
|
||||
_nextConfigUpdateTs = millis() + 300;
|
||||
}
|
||||
else if(strcmp(topic, mqtt_topic_config_led_brightness) == 0)
|
||||
{
|
||||
int newValue = atoi(value);
|
||||
if(!_nukiConfigValid || _nukiConfig.ledBrightness == newValue) return;
|
||||
_nukiBle.setLedBrightness(newValue);
|
||||
_nextConfigUpdateTs = millis() + 300;
|
||||
}
|
||||
}
|
||||
|
||||
const Nuki::KeyTurnerState &NukiWrapper::keyTurnerState()
|
||||
{
|
||||
return _keyTurnerState;
|
||||
@@ -192,8 +230,6 @@ void NukiWrapper::notify(Nuki::EventType eventType)
|
||||
|
||||
void NukiWrapper::readConfig()
|
||||
{
|
||||
Serial.print(F("Reading config. Result: "));
|
||||
Nuki::CmdResult result = _nukiBle.requestConfig(&_nukiConfig);
|
||||
_nukiConfigValid = result == Nuki::CmdResult::Success;
|
||||
Serial.println(result);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ public:
|
||||
void initialize();
|
||||
void update();
|
||||
|
||||
void setPin(const uint16_t pin);
|
||||
|
||||
const Nuki::KeyTurnerState& keyTurnerState();
|
||||
const bool isPaired();
|
||||
|
||||
@@ -22,7 +24,9 @@ public:
|
||||
void notify(Nuki::EventType eventType) override;
|
||||
|
||||
private:
|
||||
static void onLockActionReceived(const char* value);
|
||||
static void onLockActionReceivedCallback(const char* value);
|
||||
static void onConfigUpdateReceivedCallback(const char* topic, const char* value);
|
||||
void onConfigUpdateReceived(const char* topic, const char* value);
|
||||
|
||||
void updateKeyTurnerState();
|
||||
void updateBatteryState();
|
||||
|
||||
@@ -57,30 +57,38 @@ void WebCfgServer::initialize()
|
||||
String response = "";
|
||||
buildConfirmHtml(response, "Restarting. Connect to ESP access point to reconfigure WiFi.", 0);
|
||||
server.send(200, "text/html", response);
|
||||
waitAndProcess(2000);
|
||||
waitAndProcess(true, 2000);
|
||||
_network->restartAndConfigureWifi();
|
||||
});
|
||||
server.on("/method=get", [&]() {
|
||||
if (_hasCredentials && !server.authenticate(_credUser, _credPassword)) {
|
||||
return server.requestAuthentication();
|
||||
}
|
||||
bool configChanged = processArgs();
|
||||
if(configChanged)
|
||||
String message = "";
|
||||
bool restartEsp = processArgs(message);
|
||||
if(restartEsp)
|
||||
{
|
||||
String response = "";
|
||||
buildConfirmHtml(response, "Configuration saved ... restarting.");
|
||||
buildConfirmHtml(response, message);
|
||||
server.send(200, "text/html", response);
|
||||
Serial.println(F("Restarting"));
|
||||
|
||||
waitAndProcess(1000);
|
||||
waitAndProcess(true, 1000);
|
||||
ESP.restart();
|
||||
}
|
||||
else
|
||||
{
|
||||
String response = "";
|
||||
buildConfirmHtml(response, message, 3);
|
||||
server.send(200, "text/html", response);
|
||||
waitAndProcess(false, 1000);
|
||||
}
|
||||
});
|
||||
|
||||
server.begin();
|
||||
}
|
||||
|
||||
bool WebCfgServer::processArgs()
|
||||
bool WebCfgServer::processArgs(String& message)
|
||||
{
|
||||
bool configChanged = false;
|
||||
bool clearMqttCredentials = false;
|
||||
@@ -159,6 +167,19 @@ bool WebCfgServer::processArgs()
|
||||
_preferences->putString(preference_cred_password, value);
|
||||
configChanged = true;
|
||||
}
|
||||
else if(key == "NUKIPIN")
|
||||
{
|
||||
if(value == "#")
|
||||
{
|
||||
message = "PIN cleared";
|
||||
_nuki->setPin(0xffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
message = "PIN saved";
|
||||
_nuki->setPin(value.toInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(clearMqttCredentials)
|
||||
@@ -177,6 +198,7 @@ bool WebCfgServer::processArgs()
|
||||
|
||||
if(configChanged)
|
||||
{
|
||||
message = "Configuration saved ... restarting.";
|
||||
_enabled = false;
|
||||
_preferences->end();
|
||||
}
|
||||
@@ -250,15 +272,20 @@ void WebCfgServer::buildCredHtml(String &response)
|
||||
buildHtmlHeader(response);
|
||||
|
||||
response.concat("<FORM ACTION=method=get >");
|
||||
|
||||
response.concat("<h3>Credentials</h3>");
|
||||
response.concat("<table>");
|
||||
printInputField(response, "CREDUSER", "User (# to clear)", _preferences->getString(preference_cred_user).c_str(), 20);
|
||||
printInputField(response, "CREDPASS", "Password", "*", 30, true);
|
||||
response.concat("</table>");
|
||||
|
||||
response.concat("<br><INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"Save\">");
|
||||
response.concat("</FORM>");
|
||||
|
||||
response.concat("<br><br><FORM ACTION=method=get >");
|
||||
response.concat("<h3>NUKI Pin Code</h3>");
|
||||
response.concat("<table>");
|
||||
printInputField(response, "NUKIPIN", "PIN Code (# to clear)", "*", 20, true);
|
||||
response.concat("</table>");
|
||||
response.concat("<br><INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"Save\">");
|
||||
response.concat("</FORM>");
|
||||
|
||||
response.concat("</BODY>\n");
|
||||
@@ -361,12 +388,19 @@ void WebCfgServer::printParameter(String& response, const char *description, con
|
||||
|
||||
}
|
||||
|
||||
void WebCfgServer::waitAndProcess(const uint32_t duration)
|
||||
void WebCfgServer::waitAndProcess(const bool blocking, const uint32_t duration)
|
||||
{
|
||||
unsigned long timeout = millis() + duration;
|
||||
while(millis() < timeout)
|
||||
{
|
||||
server.handleClient();
|
||||
delay(10);
|
||||
if(blocking)
|
||||
{
|
||||
delay(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
vTaskDelay( 50 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
bool processArgs();
|
||||
bool processArgs(String& message);
|
||||
void buildHtml(String& response);
|
||||
void buildCredHtml(String& response);
|
||||
void buildConfirmHtml(String& response, const String &message, uint32_t redirectDelay = 5);
|
||||
@@ -40,7 +40,7 @@ private:
|
||||
|
||||
void printParameter(String& response, const char* description, const char* value);
|
||||
|
||||
void waitAndProcess(const uint32_t duration);
|
||||
void waitAndProcess(const bool blocking, const uint32_t duration);
|
||||
|
||||
WebServer server;
|
||||
NukiWrapper* _nuki;
|
||||
|
||||
Reference in New Issue
Block a user