Skip to content

Commit

Permalink
[WebUI] Add Configure MQTT and Logging (#1592)
Browse files Browse the repository at this point in the history
* Configure MQTT and Loggin

* Configure MQTT speed up

* Lint
  • Loading branch information
NorthernMan54 authored Apr 7, 2023
1 parent 6e8b463 commit 1c367fd
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 63 deletions.
5 changes: 5 additions & 0 deletions main/User_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,11 @@ CRGB leds2[FASTLED_IND_NUM_LEDS];
char mqtt_topic[parameters_size + 1] = Base_Topic;
char gateway_name[parameters_size + 1] = Gateway_Name;

void connectMQTT();
#ifndef ESPWifiManualSetup
void saveMqttConfig();
#endif

unsigned long uptime();
bool cmpToMainTopic(const char*, const char*);
void pub(const char*, const char*, bool);
Expand Down
178 changes: 124 additions & 54 deletions main/ZwebUI.ino
Original file line number Diff line number Diff line change
Expand Up @@ -466,15 +466,48 @@ void handleWI() {

/**
* @brief /MQ - Configure MQTT Page
*
* T: handleMQ Arg: 0, mh=192.168.1.17
* T: handleMQ Arg: 1, ml=1883
* T: handleMQ Arg: 2, mu=your_username
* T: handleMQ Arg: 3, mp=your_password
* T: handleMQ Arg: 4, sc=on
* T: handleMQ Arg: 5, msc=suds
* T: handleMQ Arg: 6, mt=home/
* T: handleMQ Arg: 7, save=
*/
void handleMQ() {
WEBUI_TRACE_LOG(F("handleMQ: uri: %s, args: %d, method: %d" CR), server.uri(), server.args(), server.method());
if (server.args()) {
for (uint8_t i = 0; i < server.args(); i++) {
WEBUI_TRACE_LOG(F("handleMQ Arg: %d, %s=%s" CR), i, server.argName(i).c_str(), server.arg(i).c_str());
}
if (server.hasArg("save")) {
if (server.hasArg("mh")) {
strncpy(mqtt_server, server.arg("mh").c_str(), parameters_size);
}
if (server.hasArg("ml")) {
strncpy(mqtt_port, server.arg("ml").c_str(), 6);
}
if (server.hasArg("mu")) {
strncpy(mqtt_user, server.arg("mu").c_str(), parameters_size);
}
if (server.hasArg("mp")) {
strncpy(mqtt_pass, server.arg("mp").c_str(), parameters_size);
}
mqtt_secure = server.hasArg("sc");
if (server.hasArg("msc")) {
mqtt_cert = server.arg("msc"); // String
}
if (server.hasArg("mt")) {
strncpy(mqtt_topic, server.arg("mt").c_str(), parameters_size);
}
# ifndef ESPWifiManualSetup
saveMqttConfig();
connectMQTT();
# endif
}
}

char jsonChar[100];
serializeJson(modules, jsonChar, measureJson(modules) + 1);

Expand All @@ -484,8 +517,42 @@ void handleMQ() {
String response = String(buffer);
response += String(script);
response += String(style);
// mqtt server, mqtt port, client id, mqtt username, mqtt password, topic, Full Topic
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_mqtt_body, jsonChar, gateway_name, mqtt_server, mqtt_port, gateway_name, mqtt_user, mqtt_pass, mqtt_topic, "");
// mqtt server (mh), mqtt port (ml), mqtt username (mu), mqtt password (mp), secure connection (sc), server certificate (msc), topic (mt)
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_mqtt_body, jsonChar, gateway_name, mqtt_server, mqtt_port, mqtt_user, mqtt_pass, (mqtt_secure ? "checked" : ""), mqtt_cert, mqtt_topic);
response += String(buffer);
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, footer, OMG_VERSION);
response += String(buffer);
server.send(200, "text/html", response);
}

/**
* @brief /LO - Configure Logging Page
* T: handleLO: uri: /lo, args: 2, method: 1
* T: handleLO Arg: 0, lo=5
* T: handleLO Arg: 1, save=
*/
void handleLO() {
WEBUI_TRACE_LOG(F("handleLO: uri: %s, args: %d, method: %d" CR), server.uri(), server.args(), server.method());
if (server.args()) {
for (uint8_t i = 0; i < server.args(); i++) {
WEBUI_TRACE_LOG(F("handleLO Arg: %d, %s=%s" CR), i, server.argName(i).c_str(), server.arg(i).c_str());
}
if (server.hasArg("save") && server.hasArg("lo")) {
Log.setLevel(server.arg("lo").toInt());
}
}

char jsonChar[100];
serializeJson(modules, jsonChar, measureJson(modules) + 1);

char buffer[WEB_TEMPLATE_BUFFER_MAX_SIZE];

snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, header_html, (String(gateway_name) + " - Configure Logging").c_str());
String response = String(buffer);
response += String(script);
response += String(style);
int logLevel = Log.getLevel();
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_logging_body, jsonChar, gateway_name, (logLevel == 0 ? "selected" : ""), (logLevel == 1 ? "selected" : ""), (logLevel == 2 ? "selected" : ""), (logLevel == 3 ? "selected" : ""), (logLevel == 4 ? "selected" : ""), (logLevel == 5 ? "selected" : ""), (logLevel == 6 ? "selected" : ""));
response += String(buffer);
snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, footer, OMG_VERSION);
response += String(buffer);
Expand Down Expand Up @@ -837,12 +904,13 @@ void WebUISetup() {
server.on("/up", handleUP); // Firmware Upgrade

server.on("/cn", handleCN); // Configuration
server.on("/wi", handleWI); // Configuration Wifi
server.on("/mq", handleMQ); // Configuration MQTT
server.on("/wi", handleWI); // Configure Wifi
server.on("/mq", handleMQ); // Configure MQTT
# if defined(ZgatewayCloud)
server.on("/cl", handleCL); // Cloud configuration
server.on("/cl", handleCL); // Configure Cloud
server.on("/tk", handleTK); // Store Device Token
# endif
server.on("/lo", handleLO); // Configure Logging

server.on("/rt", handleRT); // Reset configuration ( Erase and Restart )
server.begin();
Expand Down Expand Up @@ -1043,72 +1111,74 @@ void webUIPubPrint(const char* topicori, JsonObject& data) {

# ifdef ZgatewayRTL_433
case webUIHash("RTL_433toMQTT"): {
// {"model":"Acurite-Tower","id":2043,"channel":"B","battery_ok":1,"temperature_C":5.3,"humidity":81,"mic":"CHECKSUM","protocol":"Acurite 592TXR Temp/Humidity, 5n1 Weather Station, 6045 Lightning, 3N1, Atlas","rssi":-81,"duration":121060}
if (!strncmp(data["model"], "status", 6) && data.containsKey("id")) {
// {"model":"Acurite-Tower","id":2043,"channel":"B","battery_ok":1,"temperature_C":5.3,"humidity":81,"mic":"CHECKSUM","protocol":"Acurite 592TXR Temp/Humidity, 5n1 Weather Station, 6045 Lightning, 3N1, Atlas","rssi":-81,"duration":121060}

// Line 1
// Line 1

strlcpy(message->line1, data["model"], WEBUI_TEXT_WIDTH);
strlcpy(message->line1, data["model"], WEBUI_TEXT_WIDTH);

// Line 2
// Line 2

String id = data["id"];
String channel = data["channel"];
String line2 = "id: " + id + " channel: " + channel;
line2.toCharArray(message->line2, WEBUI_TEXT_WIDTH);
String id = data["id"];
String channel = data["channel"];
String line2 = "id: " + id + " channel: " + channel;
line2.toCharArray(message->line2, WEBUI_TEXT_WIDTH);

// Line 3
// Line 3

String line3 = "";
String line3 = "";

if (data.containsKey("temperature_C")) {
float temperature_C = data["temperature_C"];
char temp[5];
if (data.containsKey("temperature_C")) {
float temperature_C = data["temperature_C"];
char temp[5];

if (displayMetric) {
dtostrf(temperature_C, 3, 1, temp);
line3 = "temp: " + (String)temp + "°C ";
} else {
dtostrf(convertTemp_CtoF(temperature_C), 3, 1, temp);
line3 = "temp: " + (String)temp + "°F ";
if (displayMetric) {
dtostrf(temperature_C, 3, 1, temp);
line3 = "temp: " + (String)temp + "°C ";
} else {
dtostrf(convertTemp_CtoF(temperature_C), 3, 1, temp);
line3 = "temp: " + (String)temp + "°F ";
}
}
}

float humidity = data["humidity"];
if (data.containsKey("humidity") && humidity <= 100 && humidity >= 0) {
char hum[5];
dtostrf(humidity, 3, 1, hum);
line3 += "hum: " + (String)hum + "% ";
}
if (data.containsKey("wind_avg_km_h")) {
float wind_avg_km_h = data["wind_avg_km_h"];
char wind[6];
float humidity = data["humidity"];
if (data.containsKey("humidity") && humidity <= 100 && humidity >= 0) {
char hum[5];
dtostrf(humidity, 3, 1, hum);
line3 += "hum: " + (String)hum + "% ";
}
if (data.containsKey("wind_avg_km_h")) {
float wind_avg_km_h = data["wind_avg_km_h"];
char wind[6];

if (displayMetric) {
dtostrf(wind_avg_km_h, 3, 1, wind);
line3 += "wind: " + (String)wind + "km/h ";
} else {
dtostrf(convert_kmph2mph(wind_avg_km_h), 3, 1, wind);
line3 += "wind: " + (String)wind + "mp/h ";
if (displayMetric) {
dtostrf(wind_avg_km_h, 3, 1, wind);
line3 += "wind: " + (String)wind + "km/h ";
} else {
dtostrf(convert_kmph2mph(wind_avg_km_h), 3, 1, wind);
line3 += "wind: " + (String)wind + "mp/h ";
}
}
}

line3.toCharArray(message->line3, WEBUI_TEXT_WIDTH);
line3.toCharArray(message->line3, WEBUI_TEXT_WIDTH);

// Line 4
// Line 4

String rssi = data["rssi"];
String battery_ok = data["battery_ok"];
String rssi = data["rssi"];
String battery_ok = data["battery_ok"];

String line4 = "batt: " + battery_ok + " rssi: " + rssi;
line4.toCharArray(message->line4, WEBUI_TEXT_WIDTH);
String line4 = "batt: " + battery_ok + " rssi: " + rssi;
line4.toCharArray(message->line4, WEBUI_TEXT_WIDTH);

// Queue completed message
// Queue completed message

if (xQueueSend(webUIQueue, (void*)&message, 0) != pdTRUE) {
Log.error(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
free(message);
} else {
// Log.notice(F("[ WebUI ] Queued %s" CR), message->title);
if (xQueueSend(webUIQueue, (void*)&message, 0) != pdTRUE) {
Log.error(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
free(message);
} else {
// Log.notice(F("[ WebUI ] Queued %s" CR), message->title);
}
}
break;
}
Expand Down
14 changes: 8 additions & 6 deletions main/config_WebContent.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
// TODO: Create a script to generate these from WebPack

#define body_footer_main_menu "<div id=but2d style=\"display: block;\"></div><p><form id=but2 style=\"display: block;\" action='.' method='get'><button>Main Menu</button></form></p>"
#define body_footer_config_menu "<div id=but3d style=\"display: block;\"></div><p><form id=but3 style=\"display: block;\" action='cn' method='get'><button>Configuration</button></form></p>";
#define body_footer_config_menu "<div id=but3d style=\"display: block;\"></div><p><form id=but3 style=\"display: block;\" action='cn' method='get'><button>Configuration</button></form></p>"
#define body_header "<body><div style='text-align:left;display:inline-block;min-width:340px;'><div style='text-align:center;'><noscript> To use, please enable JavaScript <br></noscript><h3>%s</h3><h2>%s</h2></div>"

#define button_upgrade "<p><form id=but5 style='display: block;' action='up' method='get'><button>Firmware Upgrade</button></form></p>"
Expand All @@ -45,7 +45,7 @@
#else
# define configure_3
#endif
#define configure_4
#define configure_4 "<p><form action='lo' method='get'><button>Configure Logging</button></form></p>"
#define configure_5
#define configure_6
#define configure_7
Expand Down Expand Up @@ -75,19 +75,21 @@ const char reset_body[] = body_header "<div style='text-align:center;'>%s</div><

const char config_cloud_body[] = body_header "<fieldset><legend><b>&nbsp;Cloud Configuration&nbsp;</b></legend><form method='get' action='cl'><p><label><input id='cl-en' type='checkbox' %s><b>Enable Cloud Connection</b></label></p><br><p><label><input id='cl-lk' type='checkbox' disabled><b>Cloud Account%s Linked</b></label></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset><p><form action='%s' method='get'><input type='hidden' name='macAddress' value='%s'/><input type='hidden' name='redirect_uri' value='%s'/><input type='hidden' name='gateway_name' value='%s'/><input type='hidden' name='uptime' value='%d'/><input type='hidden' name='RT' value='%d'/><button>Link Cloud Account</button></form></p>" body_footer_config_menu;

const char token_body[] = body_header "div style='text-align:center;'>Link Cloud Account</div><br><div style='text-align:center;'>Cloud was successfully linked</div><br><div id=but2d style=\"display: block;\"></div><p><form id=but2 style=\"display: block;\" action='cn' method='get'><button>Configuration</button></form></p>";
const char token_body[] = body_header "<div style='text-align:center;'>Link Cloud Account</div><br><div style='text-align:center;'>Cloud was successfully linked</div><br><div id=but2d style=\"display: block;\"></div><p><form id=but2 style=\"display: block;\" action='cn' method='get'><button>Configuration</button></form></p>";

const char console_body[] = body_header "<br><textarea readonly id='t1' cols='340' wrap='off'></textarea><br><br><form method='get' onsubmit='return l(1);'><input id='c1' placeholder='Enter topic and command' autofocus><br></form>" body_footer_main_menu;

const char information_body[] = body_header "<style>td {padding: 0px 5px;}</style><div id='i' name='i'></div>" body_footer_main_menu;

const char upgrade_body[] = body_header " <div id='f1' style='display:block;'><fieldset><legend><b>&nbsp;Upgrade by web server&nbsp;</b></legend><form method='get' action='u1'><br><b>OTA Url</b><br><input id='o' placeholder=\"OTA_URL\" value=\"%s\"><br><br><button type='submit'>Start upgrade</button></form></fieldset><br><br><fieldset><legend><b>&nbsp;Upgrade by file upload&nbsp;</b></legend><form method='post' action='u2' enctype='multipart/form-data'><br><input type='file' name='u2'><br><br><button type='submit' onclick='eb(\"f1\").style.display=\"none\";eb(\"f2\").style.display=\"block\";this.form.submit();'>Start upgrade</button></form></fieldset></div><div id='f2' style='display:none;text-align:center;'><b>Upload started ...</b></div><div id=but2d style=\"display: block;\"></div><p>" body_footer_main_menu;
const char upgrade_body[] = body_header "<div id='f1' style='display:block;'><fieldset><legend><b>&nbsp;Upgrade by web server&nbsp;</b></legend><form method='get' action='u1'><br><b>OTA Url</b><br><input id='o' placeholder=\"OTA_URL\" value=\"%s\"><br><br><button type='submit'>Start upgrade</button></form></fieldset><br><br><fieldset><legend><b>&nbsp;Upgrade by file upload&nbsp;</b></legend><form method='post' action='u2' enctype='multipart/form-data'><br><input type='file' name='u2'><br><br><button type='submit' onclick='eb(\"f1\").style.display=\"none\";eb(\"f2\").style.display=\"block\";this.form.submit();'>Start upgrade</button></form></fieldset></div><div id='f2' style='display:none;text-align:center;'><b>Upload started ...</b></div><div id=but2d style=\"display: block;\"></div><p>" body_footer_main_menu;

const char config_wifi_body[] = body_header "<div title='-43 dBm (100%)'><a href='#p' onclick='c(this)'>%s</a><span class='q'><div class='si'><i class='b0'></i><i class='b1'></i><i class='b2'></i><i class='b3'></i></span></div></div><div title='-84 dBm (32%)'><a href='#p' onclick='c(this)'>BELL634</a><span class='q'><div class='si'><i class='b0'></i><i class='b1'></i><i class='b2 o30'></i><i class='b3 o30'></i></span></div></div><div title='-86 dBm (28%)'><a href='#p' onclick='c(this)'>MRC</a><span class='q'><div class='si'><i class='b0'></i><i class='b1'></i><i class='b2 o30'></i><i class='b3 o30'></i></span></div></div><br><div><a href='/wi?scan='>Scan for all WiFi Networks</a></div><br><fieldset><legend><b>&nbsp;Wifi parameters&nbsp;</b></legend><form method='get' action='wi'><p><b>WiFi Network</b> () <br><input id='s1' placeholder=\"Type or Select your WiFi Network\" value=\"%s\"></p><p><label><b>WiFi Password</b><input type='checkbox' onclick='sp(\"p1\")'></label><br><input id='p1' type='password' placeholder=\"Enter your WiFi Password\" value=\"****\"></p><p><b>WiFi Network 2</b> () <br><input id='s2' placeholder=\"Type your Alternative WiFi Network\" value=\"\"></p><p><label><b>WiFi Password</b><input type='checkbox' onclick='sp(\"p2\")'></label><br><input id='p2' type='password' placeholder=\"Enter your WiFi Password\" value=\"****\"></p><p><b>Hostname</b>%s<br><input id='h' placeholder=\"%s\" value=\"%s\"></p><p><b>CORS Domain</b><input id='c' placeholder=\"\" value=\"%s\"></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;

// mqtt server, mqtt port, client id, mqtt username, mqtt password, topic, Full Topic
// mqtt server (mh), mqtt port (ml), mqtt username (mu), mqtt password (mp), secure connection (sc), server certificate (msc), topic (mt)

const char config_mqtt_body[] = body_header "<fieldset><legend><b>&nbsp;MQTT parameters&nbsp;</b></legend><form method='get' action='mq'><p><b>Host</b> () <br><input id='mh' placeholder=" MQTT_SERVER " value='%s'></p><p><b>Port</b> (1883) <br><input id='ml' placeholder=" MQTT_PORT " value='%s'></p><p><b>Client</b> <br><input id='mc' placeholder='' value='%s'></p><p><b>User</b> " MQTT_USER " <br><input id='mu' placeholder=" MQTT_USER " value='%s'></p><p><label><b>Password</b><input type='checkbox' onclick='sp(\"mp\")'></label><br><input id='mp' type='password' placeholder=\"Password\" value='%s'></p><p><b>Topic</b> <br><input id='mt' placeholder='' value='%s'></p><p><b>Full Topic</b> <br><input id='mf' 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><legend><b>&nbsp;MQTT parameters&nbsp;</b></legend><form method='get' action='mq'><p><b>MQTT Server</b><br><input id='mh' placeholder=" MQTT_SERVER " value='%s'></p><p><b>MQTT Port</b><br><input id='ml' placeholder=" MQTT_PORT " value='%s'></p><p><b>MQTT Username</b><br><input id='mu' placeholder=" MQTT_USER " value='%s'></p><p><label><b>MQTT Password</b><input type='checkbox' onclick='sp(\"mp\")'></label><br><input id='mp' type='password' placeholder=\"Password\" value='%s'></p><p><b>MQTT Secure Connection</b><br><input id='sc' type='checkbox' %s></p><p><b>MQTT Server Certificate</b><br><textarea class='form-control' name='msc' id='field_msc' rows='10' cols='64'>%s</textarea></p><p><b>MQTT Base Topic</b><br><input id='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_logging_body[] = body_header "<fieldset><legend><b>OpenMQTTGateway Logging</b></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><option %s value='3'>Warning</option><option %s value='4'>Notice</option><option %s value='5'>Trace</option><option %s value='6'>Verbose</option></select></p><br><button name='save' type='submit' class='button bgrn'>Save</button></form></fieldset>" body_footer_config_menu;

const char footer[] = "<div style='text-align:right;font-size:11px;'><hr/><a href='https://community.openmqttgateway.com' target='_blank' style='color:#aaa;'>%s</a></div></div></body></html>";

Expand Down
10 changes: 7 additions & 3 deletions main/main.ino
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,9 @@ void delayWithOTA(long waitMillis) {
# endif
# endif
ArduinoOTA.handle();
# if defined(ZwebUI) && defined(ESP32)
WebUILoop();
# endif
delay(waitStep);
}
#else
Expand Down Expand Up @@ -1589,6 +1592,9 @@ void loop() {
if ((Ethernet.hardwareStatus() != EthernetW5100 && Ethernet.linkStatus() == LinkON) || (Ethernet.hardwareStatus() == EthernetW5100)) { //we are able to detect disconnection only on w5200 and w5500
#endif
failure_number_ntwk = 0;
#if defined(ZwebUI) && defined(ESP32)
WebUILoop();
#endif
if (client.loop()) { // MQTT client is still connected
InfoIndicatorON();
failure_number_ntwk = 0;
Expand Down Expand Up @@ -1744,9 +1750,7 @@ void loop() {
launchRTL_433Discovery(publishDiscovery);
# endif
#endif
#if defined(ZwebUI) && defined(ESP32)
WebUILoop();
#endif

} else {
// MQTT disconnected
connected = false;
Expand Down

0 comments on commit 1c367fd

Please sign in to comment.