Additional Diagnostics

This commit is contained in:
Rene Zeldenthuis
2022-07-05 15:49:07 +02:00
parent cf5188d034
commit 0db0a5d479
3 changed files with 99 additions and 3 deletions

11
include/format_duration.h Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
String format_duration(time_t seconds)
{
auto days = seconds / (60 * 60 * 24);
auto tm = gmtime(&seconds);
String duration = days > 0 ? String(days) + " days, " : "";
char time_buff[9];
strftime(time_buff, 9, "%H:%M:%S", tm);
return duration + time_buff;
}

54
include/format_si.h Normal file
View File

@@ -0,0 +1,54 @@
#pragma once
#include <Arduino.h>
String format_value(float value)
{
if (value == 0.0)
return "0";
if (value < 0)
return "-" + format_value(-value);
// No decimal places
if (value >= 1)
return String(value, 0);
if (value < 0.001f)
return String(value, 4);
if (value < 0.01f)
return String(value, 3);
if (value < 0.1f)
return String(value, 2);
return String(value, 1);
}
String format_si(double value, int decimal_places = 2)
{
if (value == 0.0)
return "0";
if (value < 0)
return "-" + format_si(-value, decimal_places);
auto value_abs = fabs(value);
if (value_abs < 1E-9)
return String(value * 1E9, decimal_places) + "p";
if (value_abs < 1E-6)
return String(value * 1E9, decimal_places) + "n";
if (value_abs < 1E-3)
return String(value * 1E6, decimal_places) + "u";
if (value_abs < 1)
return String(value * 1E3, decimal_places) + "m";
if (value_abs < 1E3)
return String(value, decimal_places);
if (value_abs < 1E6)
return String(value / 1E3, decimal_places) + "k";
if (value_abs < 1E9)
return String(value / 1E6, decimal_places) + "M";
if (value_abs < 1E12)
return String(value / 1E9, decimal_places) + "G";
if (value_abs < 1E15)
return String(value / 1E12, decimal_places) + "T";
return "NaN";
}

View File

@@ -7,6 +7,8 @@
#include <rtsp_server.h> #include <rtsp_server.h>
#include <frame_size.h> #include <frame_size.h>
#include <camera_config.h> #include <camera_config.h>
#include <format_duration.h>
#include <format_si.h>
#include <settings.h> #include <settings.h>
char camera_config_val[sizeof(camera_config_entry)]; char camera_config_val[sizeof(camera_config_entry)];
@@ -45,6 +47,7 @@ void handle_root()
html += "<title>" APP_TITLE " v" APP_VERSION "</title></head>"; html += "<title>" APP_TITLE " v" APP_VERSION "</title></head>";
html += "<body>"; html += "<body>";
html += "<h2>Status page for " + String(iotWebConf.getThingName()) + "</h2><hr />"; html += "<h2>Status page for " + String(iotWebConf.getThingName()) + "</h2><hr />";
html += "<h3>ESP32</h3>"; html += "<h3>ESP32</h3>";
html += "<ul>"; html += "<ul>";
html += "<li>CPU model: " + String(ESP.getChipModel()) + "</li>"; html += "<li>CPU model: " + String(ESP.getChipModel()) + "</li>";
@@ -53,13 +56,22 @@ void handle_root()
html += "<li>IPv4 address: " + WiFi.localIP().toString() + "</li>"; html += "<li>IPv4 address: " + WiFi.localIP().toString() + "</li>";
html += "<li>IPv6 address: " + WiFi.localIPv6().toString() + "</li>"; html += "<li>IPv6 address: " + WiFi.localIPv6().toString() + "</li>";
html += "</ul>"; html += "</ul>";
html += "<h3>Settings</h3>"; html += "<h3>Settings</h3>";
html += "<ul>"; html += "<ul>";
html += "<li>Camera type: " + String(camera_config_val) + "</li>"; html += "<li>Camera type: " + String(camera_config_val) + "</li>";
html += "<li>Frame size: " + String(frame_size_val) + "</li>"; html += "<li>Frame size: " + String(frame_size_val) + "</li>";
html += "<li>Frame rate: " + String(frame_rate_val) + " ms</li>"; html += "<li>Frame rate: " + String(frame_rate_val) + " ms (" + String(1000.0 / atol(frame_rate_val), 1) + " f/s)</li>";
html += "<li>JPEG quality: " + String(jpeg_quality_val) + " (0-100)</li>"; html += "<li>JPEG quality: " + String(jpeg_quality_val) + " (0-100)</li>";
html += "</ul>"; html += "</ul>";
html += "<h3>Diagnostics</h3>";
html += "<ul>";
html += "<li>Uptime: " + String(format_duration(millis() / 1000)) + "</li>";
html += "<li>Free heap: " + format_si(ESP.getFreeHeap()) + "b</li>";
html += "<li>Max free block: " + format_si(ESP.getMaxAllocHeap()) + "b</li>";
html += "</ul>";
html += "<br/>camera stream: <a href=\"" + url + "\">" + url + "</a>"; html += "<br/>camera stream: <a href=\"" + url + "\">" + url + "</a>";
html += "<br />"; html += "<br />";
html += "<br/>Go to <a href=\"config\">configure page</a> to change settings."; html += "<br/>Go to <a href=\"config\">configure page</a> to change settings.";
@@ -84,14 +96,14 @@ void handle_restart()
html += "<title>" APP_TITLE " v" APP_VERSION "</title></head>"; html += "<title>" APP_TITLE " v" APP_VERSION "</title></head>";
html += "<body>"; html += "<body>";
web_server.send(200, "text/html", html); web_server.send(200, "text/html", html);
log_v("Restarting..."); log_v("Restarting... Press refresh to connect again");
sleep(250); sleep(250);
ESP.restart(); ESP.restart();
} }
else else
{ {
// Redirect to root page. // Redirect to root page.
web_server.sendHeader("Location", "/", true ); web_server.sendHeader("Location", "/", true);
web_server.send(302, "text/plain", ""); web_server.send(302, "text/plain", "");
} }
} }
@@ -102,6 +114,24 @@ void on_config_saved()
config_changed = true; config_changed = true;
} }
bool form_validator(iotwebconf::WebRequestWrapper *webRequestWrapper)
{
log_v("Validating form");
auto frame_rate = webRequestWrapper->arg(config_frame_rate.getId()).toInt();
if (frame_rate <= 10)
{
log_w("Frame rate must be greater than 10 ms (100 f/s)");
return false;
}
auto jpeg_quality = webRequestWrapper->arg(config_jpg_quality.getId()).toInt();
if (jpeg_quality < 1 || jpeg_quality > 100)
{
log_w("JPEG quality must be between 1 and 100");
return false;
}
}
void initialize_camera() void initialize_camera()
{ {
log_v("Initialize camera"); log_v("Initialize camera");
@@ -159,6 +189,7 @@ void setup()
config_group_stream_settings.addItem(&config_frame_size); config_group_stream_settings.addItem(&config_frame_size);
config_group_stream_settings.addItem(&config_jpg_quality); config_group_stream_settings.addItem(&config_jpg_quality);
iotWebConf.addParameterGroup(&config_group_stream_settings); iotWebConf.addParameterGroup(&config_group_stream_settings);
iotWebConf.setFormValidator(form_validator);
iotWebConf.getApTimeoutParameter()->visible = true; iotWebConf.getApTimeoutParameter()->visible = true;
iotWebConf.setConfigSavedCallback(on_config_saved); iotWebConf.setConfigSavedCallback(on_config_saved);
iotWebConf.setWifiConnectionCallback(on_connected); iotWebConf.setWifiConnectionCallback(on_connected);