allow to set config values

This commit is contained in:
technyon
2022-04-09 20:20:52 +02:00
parent 3111c59e0b
commit 1db1022819
6 changed files with 125 additions and 23 deletions

View File

@@ -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];

View File

@@ -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;
};

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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);
}
}
}

View File

@@ -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;