[WebUI] Add full BLE configuration page and MQTT Discovery toggle (#2293)
Expand the BLE config page from encryption-only (BLEDecryptor) to a comprehensive settings page available for all ZgatewayBT builds, covering scan, publish, presence, external decoder, and encryption settings. Add MQTT Discovery checkbox to the gateway configuration page. Co-authored-by: Florian <1technophile@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2 files changed
+249
-55
No files matched your search
@@ -62,8 +62,8 @@
|
|||||||
#else
|
#else
|
||||||
# define configure_6
|
# define configure_6
|
||||||
#endif
|
#endif
|
||||||
#if BLEDecryptor
|
#ifdef ZgatewayBT
|
||||||
# define configure_7 "<p><form action='bl' method='post'><button>Configure BLE</button></form></p>"
|
# define configure_7 "<p><form action='bl' method='get'><button>Configure BLE</button></form></p>"
|
||||||
#else
|
#else
|
||||||
# define configure_7
|
# define configure_7
|
||||||
#endif
|
#endif
|
||||||
@@ -112,7 +112,16 @@ const char config_mqtt_body[] = body_header "<fieldset class=\"set1\"><legend><s
|
|||||||
const char config_mqtt_body[] = body_header "<fieldset class=\"set1\"><legend><span><b>MQTT Parameters</b></span></legend><form method='post' action='mq'><p><b>MQTT Server</b><br><input id='mh' name='mh' placeholder=" MQTT_SERVER " value='%s'></p><p><b>MQTT Port</b><br><input id='ml' name='ml' placeholder=" MQTT_PORT " value='%s'></p><p><b>MQTT Username</b><br><input id='mu' name='mu' placeholder=" MQTT_USER " value='%s'></p><p><label><b>MQTT Password</b></label><br><input id='mp' name='mp' type='password' placeholder=\"Password\" ></p><p><b>MQTT Secure Connection</b><br><input id='sc' name='sc' type='checkbox' %s></p><p><b>Gateway Name</b><br><input id='h' name='h' placeholder=" Gateway_Name " value=\"%s\"></p><p><b>MQTT Base Topic</b><br><input id='mt' name='mt' placeholder='' value='%s'></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;
|
const char config_mqtt_body[] = body_header "<fieldset class=\"set1\"><legend><span><b>MQTT Parameters</b></span></legend><form method='post' action='mq'><p><b>MQTT Server</b><br><input id='mh' name='mh' placeholder=" MQTT_SERVER " value='%s'></p><p><b>MQTT Port</b><br><input id='ml' name='ml' placeholder=" MQTT_PORT " value='%s'></p><p><b>MQTT Username</b><br><input id='mu' name='mu' placeholder=" MQTT_USER " value='%s'></p><p><label><b>MQTT Password</b></label><br><input id='mp' name='mp' type='password' placeholder=\"Password\" ></p><p><b>MQTT Secure Connection</b><br><input id='sc' name='sc' type='checkbox' %s></p><p><b>Gateway Name</b><br><input id='h' name='h' placeholder=" Gateway_Name " value=\"%s\"></p><p><b>MQTT Base Topic</b><br><input id='mt' name='mt' placeholder='' value='%s'></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;
|
||||||
#endif
|
#endif
|
||||||
#ifndef ESPWifiManualSetup
|
#ifndef ESPWifiManualSetup
|
||||||
const char config_gateway_body[] = body_header "<fieldset class=\"set1\"><legend><span><b>Gateway Configuration</b></span></legend><form method='post' action='cg'><p><b>Gateway Password (8 characters min)</b><br><input id='gp' name='gp' type='password' placeholder=\"********\" minlength='8'></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;
|
const char config_gateway_body[] = body_header
|
||||||
|
"<fieldset class=\"set1\"><legend><span><b>Gateway Configuration</b></span></legend>"
|
||||||
|
"<form method='post' action='cg'>"
|
||||||
|
"<p><b>Gateway Password (8 characters min)</b><br>"
|
||||||
|
"<input id='gp' name='gp' type='password' placeholder=\"********\" minlength='8'></p>"
|
||||||
|
# ifdef ZmqttDiscovery
|
||||||
|
"<p><label><input id='dc' name='dc' type='checkbox' %s> MQTT Discovery</label></p>"
|
||||||
|
# endif
|
||||||
|
"<br><button name='save' type='submit' class='button bgrn'>Save</button>"
|
||||||
|
"</form></fieldset>" body_footer_config_menu;
|
||||||
#endif
|
#endif
|
||||||
const char config_logging_body[] = body_header
|
const char config_logging_body[] = body_header
|
||||||
"<fieldset class=\"set1\"><legend><span><b>OpenMQTTGateway Logging</b></span></legend><form method='get' action='lo'><p><b>Log Level</b><br><select id='lo'><option %s value='0'>Silent</option><option %s value='1'>Fatal</option><option %s value='2'>Error</option>"
|
"<fieldset class=\"set1\"><legend><span><b>OpenMQTTGateway Logging</b></span></legend><form method='get' action='lo'><p><b>Log Level</b><br><select id='lo'><option %s value='0'>Silent</option><option %s value='1'>Fatal</option><option %s value='2'>Error</option>"
|
||||||
@@ -237,11 +246,65 @@ const char config_lora_body[] = body_header
|
|||||||
"</form>"
|
"</form>"
|
||||||
"</fieldset>" body_footer_config_menu;
|
"</fieldset>" body_footer_config_menu;
|
||||||
|
|
||||||
#if BLEDecryptor
|
#ifdef ZgatewayBT
|
||||||
const char config_ble_body[] = body_header "<fieldset class=\"set1\"><legend><span><b>Configure BLE</b></span></legend><form method='post' action='bl'><p><b>BLE AES Default Key (32 char hex)</b></p><input id='bk' name='bk' minlength='32' maxlength='32' placeholder=" BLE_AES " value='%s' oninput='bkv()'><p id='bke' style='color:red;'></p><hr><p><b>BLE Key Pairs</b></p><p>MacAddress:AESKey with space separator</p><p><textarea id='kp' name='kp' placeholder='A4C138012345:00112233445566778899001122334455' rows='3' cols='46' oninput='kpv()'>%s</textarea></p><p id='kpe' style='color:red;'></p><br><button id='s' name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;
|
// BLE config page split into parts to fit within WEB_TEMPLATE_BUFFER_MAX_SIZE
|
||||||
|
|
||||||
// Client side javascript validation of the Default AES Key is hex, and the custom keys are in the correct format. This pushes the theengs-bridge-v11 way of the file size, so reducing it now and leaving it commented out
|
// Part 1: Header + Scan settings (body_header %s=modules, %s=gateway_name, then: %s=enabled, %s=adaptivescan, %lu=interval, %lu=intervalacts, %lu=scanduration, %s=forcepscn, %s=bleconnect, %d=minrssi)
|
||||||
//const char ble_script[] = "function bkv(){let e=document.getElementById('bk'),t=document.getElementById('bke'),l=e.value.trim();0===l.length||/^[A-Fa-f0-9]{32}$/.test(l)?(t.textContent='',e.style.color=''):(t.textContent='Invalid key',e.style.color='red')}function kpv(){let e=document.getElementById('kp'),t=document.getElementById('kpe'),l=e.value.split(/ /),n=/^[A-Fa-f0-9]{12}:[A-Fa-f0-9]{32}$/,o=l.map((e,t)=>({line:e,index:t})).filter(e=>!n.test(e.line));if(0===e.value.trim().length||0===o.length)t.textContent='',e.style.color='';else{let i=o.map(e=>e.index+1).join(', ');t.textContent=`Invalid format on line(s): ${i}`,e.style.color='red'}}";
|
const char config_ble_body_scan[] = body_header
|
||||||
|
"<fieldset class=\"set1\"><legend><span><b>Configure BLE</b></span></legend>"
|
||||||
|
"<form method='post' action='bl'>"
|
||||||
|
"<p><b>Scan Settings</b></p>"
|
||||||
|
"<p><label><input id='en' name='en' type='checkbox' %s> Enable BLE</label></p>"
|
||||||
|
"<p><label><input id='as' name='as' type='checkbox' %s> Adaptive Scan</label></p>"
|
||||||
|
"<p><b>Scan Interval (ms)</b><br><input id='bi' name='bi' type='number' min='0' value='%lu'></p>"
|
||||||
|
"<p><b>Active Scan Interval (ms)</b><br><input id='ai' name='ai' type='number' min='0' value='%lu'></p>"
|
||||||
|
"<p><b>Scan Duration (ms)</b><br><input id='sd' name='sd' type='number' min='0' value='%lu'></p>"
|
||||||
|
"<p><label><input id='fp' name='fp' type='checkbox' %s> Force Passive Scan</label></p>"
|
||||||
|
"<p><label><input id='bc' name='bc' type='checkbox' %s> BLE Connect</label></p>"
|
||||||
|
"<p><b>Min RSSI</b><br><input id='mr' name='mr' type='number' max='0' value='%d'></p>";
|
||||||
|
|
||||||
|
// Part 2: Publish settings (%s=onlysensors, %s=randommacs, %s=pubadvdata, %s=pubuuid4topic, %s=filterConnectable, %s=ignoreWBlist)
|
||||||
|
const char config_ble_body_publish[] =
|
||||||
|
"<hr><p><b>Publish Settings</b></p>"
|
||||||
|
"<p><label><input id='os' name='os' type='checkbox' %s> Only Sensors</label></p>"
|
||||||
|
"<p><label><input id='rm' name='rm' type='checkbox' %s> Random MACs</label></p>"
|
||||||
|
"<p><label><input id='pa' name='pa' type='checkbox' %s> Publish Adv Data</label></p>"
|
||||||
|
"<p><label><input id='ut' name='ut' type='checkbox' %s> UUID as Topic</label></p>"
|
||||||
|
"<p><label><input id='fc' name='fc' type='checkbox' %s> Filter Connectable</label></p>"
|
||||||
|
"<p><label><input id='iw' name='iw' type='checkbox' %s> Ignore White/Blacklist</label></p>";
|
||||||
|
|
||||||
|
// Part 3: Presence settings (%s=hasspresence, %s=presuseuuid, %s=prestopic, %lu=presenceawaytimer, %lu=movingtimer)
|
||||||
|
const char config_ble_body_presence[] =
|
||||||
|
"<hr><p><b>Presence Settings</b></p>"
|
||||||
|
"<p><label><input id='hp' name='hp' type='checkbox' %s> HA Presence</label></p>"
|
||||||
|
"<p><label><input id='pu' name='pu' type='checkbox' %s> Use UUID for Presence</label></p>"
|
||||||
|
"<p><b>Presence Topic</b><br><input id='pt' name='pt' value='%s'></p>"
|
||||||
|
"<p><b>Away Timer (ms)</b><br><input id='at' name='at' type='number' min='0' value='%lu'></p>"
|
||||||
|
"<p><b>Moving Timer (ms)</b><br><input id='mo' name='mo' type='number' min='0' value='%lu'></p>";
|
||||||
|
|
||||||
|
// Part 4: External decoder settings (%s=extDecoderEnable, %s=extDecoderTopic, %lu=intervalcnct)
|
||||||
|
const char config_ble_body_decoder[] =
|
||||||
|
"<hr><p><b>External Decoder</b></p>"
|
||||||
|
"<p><label><input id='ed' name='ed' type='checkbox' %s> Enable Ext Decoder</label></p>"
|
||||||
|
"<p><b>Ext Decoder Topic</b><br><input id='et' name='et' value='%s'></p>"
|
||||||
|
"<p><b>Connect Interval (ms)</b><br><input id='ci' name='ci' type='number' min='0' value='%lu'></p>";
|
||||||
|
|
||||||
|
# if BLEDecryptor
|
||||||
|
// Part 5: Encryption settings (%s=ble_aes, %s=ble_aes_keys)
|
||||||
|
const char config_ble_body_encrypt[] =
|
||||||
|
"<hr><p><b>Encryption</b></p>"
|
||||||
|
"<p><b>BLE AES Default Key (32 char hex)</b></p>"
|
||||||
|
"<input id='bk' name='bk' minlength='32' maxlength='32' placeholder=" BLE_AES
|
||||||
|
" value='%s'>"
|
||||||
|
"<hr><p><b>BLE Key Pairs</b></p>"
|
||||||
|
"<p>MacAddress:AESKey with space separator</p>"
|
||||||
|
"<p><textarea id='kp' name='kp' placeholder='A4C138012345:00112233445566778899001122334455' rows='3' cols='46'>%s</textarea></p>";
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Part 6: Save button + footer
|
||||||
|
const char config_ble_body_footer[] =
|
||||||
|
"<br><button id='s' name='save' type='submit' class='button bgrn'>Save</button>"
|
||||||
|
"</form></fieldset>" body_footer_config_menu;
|
||||||
|
|
||||||
const char ble_script[] = "";
|
const char ble_script[] = "";
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+179
-48
@@ -64,6 +64,7 @@ extern void eraseConfig();
|
|||||||
extern unsigned long uptime();
|
extern unsigned long uptime();
|
||||||
extern void ESPRestart(byte reason);
|
extern void ESPRestart(byte reason);
|
||||||
extern void XtoSYS(const char* topicOri, JsonObject& SYSdata);
|
extern void XtoSYS(const char* topicOri, JsonObject& SYSdata);
|
||||||
|
extern void SYSConfig_save();
|
||||||
extern String stateMeasures();
|
extern String stateMeasures();
|
||||||
extern void MQTTHttpsFWUpdate(const char* topicOri, JsonObject& HttpsFwUpdateData);
|
extern void MQTTHttpsFWUpdate(const char* topicOri, JsonObject& HttpsFwUpdateData);
|
||||||
extern void receivingDATA(const char* topicOri, const char* datacallback);
|
extern void receivingDATA(const char* topicOri, const char* datacallback);
|
||||||
@@ -862,44 +863,61 @@ void handleMQ() {
|
|||||||
void handleCG() {
|
void handleCG() {
|
||||||
WEBUI_TRACE_LOG(F("handleCG: uri: %s, args: %d, method: %d" CR), server.uri(), server.args(), server.method());
|
WEBUI_TRACE_LOG(F("handleCG: uri: %s, args: %d, method: %d" CR), server.uri(), server.args(), server.method());
|
||||||
WEBUI_SECURE
|
WEBUI_SECURE
|
||||||
bool update = false;
|
bool pwUpdate = false;
|
||||||
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
bool sysUpdate = false;
|
||||||
JsonObject WEBtoSYS = jsonBuffer.to<JsonObject>();
|
|
||||||
|
|
||||||
if (server.args()) {
|
if (server.args()) {
|
||||||
for (uint8_t i = 0; i < server.args(); i++) {
|
for (uint8_t i = 0; i < server.args(); i++) {
|
||||||
WEBUI_TRACE_LOG(F("handleCG Arg: %d, %s=%s" CR), i, server.argName(i).c_str(), server.arg(i).c_str());
|
WEBUI_TRACE_LOG(F("handleCG Arg: %d, %s=%s" CR), i, server.argName(i).c_str(), server.arg(i).c_str());
|
||||||
}
|
}
|
||||||
if (server.hasArg("save") && server.hasArg("gp") && strcmp(ota_pass, server.arg("gp").c_str())) {
|
if (server.hasArg("save")) {
|
||||||
|
if (server.hasArg("gp") && server.arg("gp").length() > 0 && strcmp(ota_pass, server.arg("gp").c_str())) {
|
||||||
strncpy(ota_pass, server.arg("gp").c_str(), parameters_size);
|
strncpy(ota_pass, server.arg("gp").c_str(), parameters_size);
|
||||||
WEBtoSYS["gw_pass"] = ota_pass;
|
pwUpdate = true;
|
||||||
update = true;
|
}
|
||||||
|
# ifdef ZmqttDiscovery
|
||||||
|
if (SYSConfig.discovery != server.hasArg("dc")) {
|
||||||
|
SYSConfig.discovery = server.hasArg("dc");
|
||||||
|
sysUpdate = true;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update) {
|
if (pwUpdate || sysUpdate) {
|
||||||
THEENGS_LOG_WARNING(F("[WebUI] Save Password and Restart" CR));
|
THEENGS_LOG_NOTICE(F("[WebUI] Save gateway config and restart" CR));
|
||||||
|
|
||||||
|
if (sysUpdate) {
|
||||||
|
SYSConfig_save();
|
||||||
|
}
|
||||||
|
|
||||||
char jsonChar[100];
|
char jsonChar[100];
|
||||||
serializeJson(modules, jsonChar, measureJson(modules) + 1);
|
serializeJson(modules, jsonChar, measureJson(modules) + 1);
|
||||||
char buffer[WEB_TEMPLATE_BUFFER_MAX_SIZE];
|
char buffer[WEB_TEMPLATE_BUFFER_MAX_SIZE];
|
||||||
|
|
||||||
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, header_html, (String(gateway_name) + " - Save Password and Restart").c_str());
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, header_html, (String(gateway_name) + " - Save and Restart").c_str());
|
||||||
String response = String(buffer);
|
String response = String(buffer);
|
||||||
response += String(restart_script);
|
response += String(restart_script);
|
||||||
response += String(script);
|
response += String(script);
|
||||||
response += String(style);
|
response += String(style);
|
||||||
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, reset_body, jsonChar, gateway_name, "Save Password and Restart");
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, reset_body, jsonChar, gateway_name, "Save and Restart");
|
||||||
response += String(buffer);
|
response += String(buffer);
|
||||||
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, footer, OMG_VERSION);
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, footer, OMG_VERSION);
|
||||||
response += String(buffer);
|
response += String(buffer);
|
||||||
server.send(200, "text/html", response);
|
server.send(200, "text/html", response);
|
||||||
|
|
||||||
delay(2000); // Wait for web page to be sent before
|
if (pwUpdate) {
|
||||||
|
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
||||||
|
JsonObject WEBtoSYS = jsonBuffer.to<JsonObject>();
|
||||||
|
WEBtoSYS["gw_pass"] = ota_pass;
|
||||||
|
delay(2000);
|
||||||
String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSset);
|
String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSset);
|
||||||
XtoSYS((char*)topic.c_str(), WEBtoSYS);
|
XtoSYS((char*)topic.c_str(), WEBtoSYS);
|
||||||
} else {
|
} else {
|
||||||
THEENGS_LOG_WARNING(F("[WebUI] No changes" CR));
|
delay(2000);
|
||||||
|
ESPRestart(5);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char jsonChar[100];
|
char jsonChar[100];
|
||||||
@@ -911,7 +929,12 @@ void handleCG() {
|
|||||||
String response = String(buffer);
|
String response = String(buffer);
|
||||||
response += String(script);
|
response += String(script);
|
||||||
response += String(style);
|
response += String(style);
|
||||||
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_gateway_body, jsonChar, gateway_name, ota_pass);
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_gateway_body, jsonChar, gateway_name
|
||||||
|
# ifdef ZmqttDiscovery
|
||||||
|
,
|
||||||
|
(SYSConfig.discovery ? "checked" : "")
|
||||||
|
# endif
|
||||||
|
);
|
||||||
response += String(buffer);
|
response += String(buffer);
|
||||||
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, footer, OMG_VERSION);
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, footer, OMG_VERSION);
|
||||||
response += String(buffer);
|
response += String(buffer);
|
||||||
@@ -955,34 +978,93 @@ void handleLO() {
|
|||||||
server.send(200, "text/html", response);
|
server.send(200, "text/html", response);
|
||||||
}
|
}
|
||||||
|
|
||||||
# if BLEDecryptor
|
# ifdef ZgatewayBT
|
||||||
|
# include "config_BT.h"
|
||||||
|
extern void BTConfig_fromJson(JsonObject& BTdata, bool startup);
|
||||||
|
extern String stateBTMeasures(bool start);
|
||||||
|
extern BTConfig_s BTConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief /BL - Config BLE
|
* @brief /BL - Config BLE
|
||||||
* T: handleBL: uri: /bl, args: 3, method: 1
|
|
||||||
* T: handleBL Arg: 0, dn=on - Force Device Name
|
|
||||||
* T: handleBL Arg: 1, bk=on - BLE AES Key
|
|
||||||
* T: handleBL Arg: 2, save=
|
|
||||||
*/
|
*/
|
||||||
void handleBL() {
|
void handleBL() {
|
||||||
WEBUI_TRACE_LOG(F("handleBL: uri: %s, args: %d, method: %d" CR), server.uri(), server.args(), server.method());
|
WEBUI_TRACE_LOG(F("handleBL: uri: %s, args: %d, method: %d" CR), server.uri(), server.args(), server.method());
|
||||||
WEBUI_SECURE
|
WEBUI_SECURE
|
||||||
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
|
||||||
JsonObject WEBtoSYS = jsonBuffer.to<JsonObject>();
|
|
||||||
|
|
||||||
if (server.args()) {
|
if (server.args()) {
|
||||||
for (uint8_t i = 0; i < server.args(); i++) {
|
for (uint8_t i = 0; i < server.args(); i++) {
|
||||||
WEBUI_TRACE_LOG(F("handleBL Arg: %d, %s=%s" CR), i, server.argName(i).c_str(), server.arg(i).c_str());
|
WEBUI_TRACE_LOG(F("handleBL Arg: %d, %s=%s" CR), i, server.argName(i).c_str(), server.arg(i).c_str());
|
||||||
}
|
}
|
||||||
bool update = false;
|
|
||||||
|
|
||||||
if (server.hasArg("save")) {
|
if (server.hasArg("save")) {
|
||||||
// Default BLE AES Key
|
// Save BLE config in its own scope so the JSON buffer is freed before stateBTMeasures
|
||||||
if (server.hasArg("bk")) {
|
// runs (via BTConfig_fromJson), avoiding stack overflow from nested StaticJsonDocument allocations
|
||||||
WEBtoSYS["ble_aes"] = server.arg("bk");
|
{
|
||||||
update = true;
|
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
||||||
|
JsonObject WEBtoBT = jsonBuffer.to<JsonObject>();
|
||||||
|
|
||||||
|
// Scan settings
|
||||||
|
WEBtoBT["enabled"] = server.hasArg("en");
|
||||||
|
WEBtoBT["adaptivescan"] = server.hasArg("as");
|
||||||
|
if (server.hasArg("bi")) {
|
||||||
|
WEBtoBT["interval"] = server.arg("bi").toInt();
|
||||||
|
}
|
||||||
|
if (server.hasArg("ai")) {
|
||||||
|
WEBtoBT["intervalacts"] = server.arg("ai").toInt();
|
||||||
|
}
|
||||||
|
if (server.hasArg("sd")) {
|
||||||
|
WEBtoBT["scanduration"] = server.arg("sd").toInt();
|
||||||
|
}
|
||||||
|
WEBtoBT["forcepscn"] = server.hasArg("fp");
|
||||||
|
WEBtoBT["bleconnect"] = server.hasArg("bc");
|
||||||
|
if (server.hasArg("mr")) {
|
||||||
|
WEBtoBT["minrssi"] = server.arg("mr").toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split Custom BLE AES key pair string add to config
|
// Publish settings
|
||||||
|
WEBtoBT["onlysensors"] = server.hasArg("os");
|
||||||
|
WEBtoBT["randommacs"] = server.hasArg("rm");
|
||||||
|
WEBtoBT["pubadvdata"] = server.hasArg("pa");
|
||||||
|
WEBtoBT["pubuuid4topic"] = server.hasArg("ut");
|
||||||
|
WEBtoBT["filterConnectable"] = server.hasArg("fc");
|
||||||
|
WEBtoBT["ignoreWBlist"] = server.hasArg("iw");
|
||||||
|
|
||||||
|
// Presence settings
|
||||||
|
WEBtoBT["hasspresence"] = server.hasArg("hp");
|
||||||
|
WEBtoBT["presuseuuid"] = server.hasArg("pu");
|
||||||
|
if (server.hasArg("pt")) {
|
||||||
|
WEBtoBT["prestopic"] = server.arg("pt");
|
||||||
|
}
|
||||||
|
if (server.hasArg("at")) {
|
||||||
|
WEBtoBT["presenceawaytimer"] = server.arg("at").toInt();
|
||||||
|
}
|
||||||
|
if (server.hasArg("mo")) {
|
||||||
|
WEBtoBT["movingtimer"] = server.arg("mo").toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
// External decoder
|
||||||
|
WEBtoBT["extDecoderEnable"] = server.hasArg("ed");
|
||||||
|
if (server.hasArg("et")) {
|
||||||
|
WEBtoBT["extDecoderTopic"] = server.arg("et");
|
||||||
|
}
|
||||||
|
if (server.hasArg("ci")) {
|
||||||
|
WEBtoBT["intervalcnct"] = server.arg("ci").toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
THEENGS_LOG_NOTICE(F("[WebUI] Save BLE config" CR));
|
||||||
|
WEBtoBT["save"] = true;
|
||||||
|
BTConfig_fromJson(WEBtoBT, false);
|
||||||
|
} // jsonBuffer freed here before stateBTMeasures internal allocations complete
|
||||||
|
|
||||||
|
# if BLEDecryptor
|
||||||
|
// Encryption settings (via SYS topic) - separate scope
|
||||||
|
{
|
||||||
|
StaticJsonDocument<JSON_MSG_BUFFER> sysBuffer;
|
||||||
|
JsonObject WEBtoSYS = sysBuffer.to<JsonObject>();
|
||||||
|
bool sysUpdate = false;
|
||||||
|
|
||||||
|
if (server.hasArg("bk")) {
|
||||||
|
WEBtoSYS["ble_aes"] = server.arg("bk");
|
||||||
|
sysUpdate = true;
|
||||||
|
}
|
||||||
if (server.hasArg("kp")) {
|
if (server.hasArg("kp")) {
|
||||||
String kp = server.arg("kp");
|
String kp = server.arg("kp");
|
||||||
while (kp.length() > 0) {
|
while (kp.length() > 0) {
|
||||||
@@ -999,29 +1081,18 @@ void handleBL() {
|
|||||||
kp = kp.substring(kpindex + 1);
|
kp = kp.substring(kpindex + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
update = true;
|
sysUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update) {
|
if (sysUpdate) {
|
||||||
THEENGS_LOG_WARNING(F("[BLE] Save Config" CR));
|
THEENGS_LOG_NOTICE(F("[WebUI] Save BLE encryption config" CR));
|
||||||
String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSset);
|
String topic = String(mqtt_topic) + String(gateway_name) + String(subjectMQTTtoSYSset);
|
||||||
XtoSYS((char*)topic.c_str(), WEBtoSYS);
|
XtoSYS((char*)topic.c_str(), WEBtoSYS);
|
||||||
} else {
|
|
||||||
THEENGS_LOG_WARNING(F("[BLE] No changes" CR));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build BLE Key Pair string
|
|
||||||
std::string aeskeysstring;
|
|
||||||
JsonObject root = ble_aes_keys.as<JsonObject>();
|
|
||||||
for (JsonPair kv : root) {
|
|
||||||
aeskeysstring += kv.key().c_str();
|
|
||||||
aeskeysstring += ":";
|
|
||||||
aeskeysstring += kv.value().as<const char*>();
|
|
||||||
aeskeysstring += " ";
|
|
||||||
}
|
}
|
||||||
aeskeysstring.pop_back();
|
|
||||||
|
|
||||||
char jsonChar[100];
|
char jsonChar[100];
|
||||||
serializeJson(modules, jsonChar, measureJson(modules) + 1);
|
serializeJson(modules, jsonChar, measureJson(modules) + 1);
|
||||||
@@ -1033,9 +1104,69 @@ void handleBL() {
|
|||||||
response += String(ble_script);
|
response += String(ble_script);
|
||||||
response += String(script);
|
response += String(script);
|
||||||
response += String(style);
|
response += String(style);
|
||||||
int logLevel = Log.getLevel();
|
|
||||||
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_ble_body, jsonChar, gateway_name, ble_aes, aeskeysstring.c_str());
|
// Scan settings
|
||||||
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_ble_body_scan,
|
||||||
|
jsonChar, gateway_name,
|
||||||
|
(BTConfig.enabled ? "checked" : ""),
|
||||||
|
(BTConfig.adaptiveScan ? "checked" : ""),
|
||||||
|
BTConfig.BLEinterval,
|
||||||
|
BTConfig.intervalActiveScan,
|
||||||
|
BTConfig.scanDuration,
|
||||||
|
(BTConfig.forcePassiveScan ? "checked" : ""),
|
||||||
|
(BTConfig.bleConnect ? "checked" : ""),
|
||||||
|
BTConfig.minRssi);
|
||||||
response += String(buffer);
|
response += String(buffer);
|
||||||
|
|
||||||
|
// Publish settings
|
||||||
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_ble_body_publish,
|
||||||
|
(BTConfig.pubOnlySensors ? "checked" : ""),
|
||||||
|
(BTConfig.pubRandomMACs ? "checked" : ""),
|
||||||
|
(BTConfig.pubAdvData ? "checked" : ""),
|
||||||
|
(BTConfig.pubBeaconUuidForTopic ? "checked" : ""),
|
||||||
|
(BTConfig.filterConnectable ? "checked" : ""),
|
||||||
|
(BTConfig.ignoreWBlist ? "checked" : ""));
|
||||||
|
response += String(buffer);
|
||||||
|
|
||||||
|
// Presence settings
|
||||||
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_ble_body_presence,
|
||||||
|
(BTConfig.presenceEnable ? "checked" : ""),
|
||||||
|
(BTConfig.presenceUseBeaconUuid ? "checked" : ""),
|
||||||
|
BTConfig.presenceTopic.c_str(),
|
||||||
|
BTConfig.presenceAwayTimer,
|
||||||
|
BTConfig.movingTimer);
|
||||||
|
response += String(buffer);
|
||||||
|
|
||||||
|
// External decoder settings
|
||||||
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_ble_body_decoder,
|
||||||
|
(BTConfig.extDecoderEnable ? "checked" : ""),
|
||||||
|
BTConfig.extDecoderTopic.c_str(),
|
||||||
|
BTConfig.intervalConnect);
|
||||||
|
response += String(buffer);
|
||||||
|
|
||||||
|
# if BLEDecryptor
|
||||||
|
// Encryption settings
|
||||||
|
std::string aeskeysstring;
|
||||||
|
JsonObject root = ble_aes_keys.as<JsonObject>();
|
||||||
|
for (JsonPair kv : root) {
|
||||||
|
aeskeysstring += kv.key().c_str();
|
||||||
|
aeskeysstring += ":";
|
||||||
|
aeskeysstring += kv.value().as<const char*>();
|
||||||
|
aeskeysstring += " ";
|
||||||
|
}
|
||||||
|
if (!aeskeysstring.empty()) {
|
||||||
|
aeskeysstring.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_ble_body_encrypt,
|
||||||
|
ble_aes, aeskeysstring.c_str());
|
||||||
|
response += String(buffer);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Footer
|
||||||
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, "%s", config_ble_body_footer);
|
||||||
|
response += String(buffer);
|
||||||
|
|
||||||
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, footer, OMG_VERSION);
|
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, footer, OMG_VERSION);
|
||||||
response += String(buffer);
|
response += String(buffer);
|
||||||
server.send(200, "text/html", response);
|
server.send(200, "text/html", response);
|
||||||
@@ -1757,7 +1888,7 @@ void WebUISetup() {
|
|||||||
server.on("/wi", HTTP_POST, handleWI); // Configure Wifi
|
server.on("/wi", HTTP_POST, handleWI); // Configure Wifi
|
||||||
server.on("/mq", HTTP_POST, handleMQ); // Configure MQTT
|
server.on("/mq", HTTP_POST, handleMQ); // Configure MQTT
|
||||||
# ifndef ESPWifiManualSetup
|
# ifndef ESPWifiManualSetup
|
||||||
server.on("/cg", HTTP_POST, handleCG); // Configure gateway"
|
server.on("/cg", handleCG); // Configure gateway
|
||||||
# endif
|
# endif
|
||||||
server.on("/wu", handleWU); // Configure WebUI
|
server.on("/wu", handleWU); // Configure WebUI
|
||||||
# ifdef ZgatewayLORA
|
# ifdef ZgatewayLORA
|
||||||
@@ -1771,8 +1902,8 @@ void WebUISetup() {
|
|||||||
# endif
|
# endif
|
||||||
server.on("/lo", handleLO); // Configure Logging
|
server.on("/lo", handleLO); // Configure Logging
|
||||||
|
|
||||||
# if BLEDecryptor
|
# ifdef ZgatewayBT
|
||||||
server.on("/bl", HTTP_POST, handleBL); // Configure BLE
|
server.on("/bl", handleBL); // Configure BLE
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
server.on("/rt", handleRT); // Reset configuration ( Erase and Restart )
|
server.on("/rt", handleRT); // Reset configuration ( Erase and Restart )
|
||||||
|
|||||||
Reference in new issue
Block a user