Compare commits

...

9 Commits

Author SHA1 Message Date
jomjol
e23c89ae57 Update Changelog.md 2022-12-06 20:32:48 +01:00
Ralf Rachinger
53a764abc8 Don't autofail if NTP server can't be reached during initalization (#1498)
This fixes an issue with a restricted network without internet access,
where the hardcoded ntp server can't be reached and thus the esp resets,
as it's not able to finish initalization.
2022-12-06 07:00:43 +01:00
CaCO3
4f07c88769 Fix cookie usage, use correct http response codes, add 404 page (#1495)
* replaced some HTTP response code with better matching codes

* add custom 404 page, add log entry for debugging

* fix cookie

* replace non-necessary whitespace

* .

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2022-12-06 06:53:05 +01:00
CaCO3
fa406d8989 replace calls to /wasserzaehler.html with calls to /value (#1469)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2022-12-06 06:52:25 +01:00
parhedberg
1ca54f39f8 Using named cookies to get a correct redirect (#1492)
* Using named cookies

* Prevent from deleting wlan.ini file

* Missed "

* Revert "Prevent from deleting wlan.ini file"

This reverts commit 901b6998b6.

Co-authored-by: Pär Hedberg <par.hedberg@nordicmedtest.se>
2022-12-05 20:43:06 +01:00
CaCO3
5867e90f69 Extend mqtt json (#1489)
* add whitespaces in JSON in MQTT

* re-added pre-value

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2022-12-05 18:44:43 +01:00
CaCO3
e87b91f6eb MQTT improvements (#1487)
* removed no longer used code

* updated logs

* increased heap memory. this most likely was the reason that the MQTT init failed, see https://github.com/jomjol/AI-on-the-edge-device/issues/1455#issuecomment-1336450501

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2022-12-05 06:55:08 +01:00
CaCO3
4b52e61755 De-init camera on startup. This solves init errors in cause it was already initialized in a prevous run (#1486)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2022-12-05 06:53:48 +01:00
github-actions
eb48212630 Update Changelog.md for release 2022-12-04 14:58:57 +00:00
22 changed files with 156 additions and 113 deletions

View File

@@ -27,11 +27,11 @@
If anything breaks you can try to enforce manual update as following:
**OTA:**
1\. Make sure the last run of the update completed the **Uploading** step.
1\. Call `http://<IP>/ota?task=update&file=<UPLOAD_FILENAME>` to enforce the extraction/flashing.
1. Make sure the last run of the update completed the **Uploading** step.
1. Call `http://<IP>/ota?task=update&file=<UPLOAD_FILENAME>` to enforce the extraction/flashing.
**Initial Setup:**
1\. Use the initial_esp32_setup.zip ( <https://github.com/jomjol/AI-on-the-edge-device/wiki/Installation> ) as alternative to have a clean install.
1. Use the initial_esp32_setup.zip ( <https://github.com/jomjol/AI-on-the-edge-device/wiki/Installation> ) as alternative to have a clean install.
### Added
@@ -76,7 +76,8 @@ If anything breaks you can try to enforce manual update as following:
- Various minor fixes and improvements
- NEW v13.0.2: Corrected Version comparison between firmware and Web UI.
- NEW v13.0.3: Re-updated build environment to v5.2.0 (from accidental downgrad to v4.4.0)
- **NEW v13.0.4**: Fix for reboot in case of MQTT not used
- NEW v13.0.4: Fix for reboot in case of MQTT not used
- **NEW v13.0.5**: No reboot in case of missing NTP-connection
### Removed
@@ -98,8 +99,8 @@ Improve **u**ser e**x**perience
5. Now you can reboot.
If anything breaks you can try to
1\. Call `http://<IP>/ota?task=update&file=firmware.bin` resp. `http://<IP>/ota?task=update&file=html.zip` if the upload successed but the extraction failed.
1\. Use the initial_esp32_setup.zip ( <https://github.com/jomjol/AI-on-the-edge-device/wiki/Installation> ) as alternative.
1. Call `http://<IP>/ota?task=update&file=firmware.bin` resp. `http://<IP>/ota?task=update&file=html.zip` if the upload successed but the extraction failed.
1. Use the initial_esp32_setup.zip ( <https://github.com/jomjol/AI-on-the-edge-device/wiki/Installation> ) as alternative.
### Added
@@ -751,7 +752,9 @@ External Illumination
- Initial Version
[Unreleased]: https://github.com/jomjol/AI-on-the-edge-device/compare/13.0.1...HEAD
[Unreleased]: https://github.com/jomjol/AI-on-the-edge-device/compare/13.0.4...HEAD
[13.0.4]: https://github.com/jomjol/AI-on-the-edge-device/compare/12.0.1...13.0.4
[13.0.1]: https://github.com/jomjol/AI-on-the-edge-device/compare/12.0.1...13.0.1

View File

@@ -675,6 +675,7 @@ esp_err_t CCamera::InitCam()
ActualQuality = camera_config.jpeg_quality;
ActualResolution = camera_config.frame_size;
//initialize the camera
esp_camera_deinit(); // De-init in case it was already initialized
esp_err_t err = esp_camera_init(&camera_config);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Camera Init Failed");

View File

@@ -219,9 +219,9 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
ESP_LOGD(TAG, "entrypath: <%s>", entrypath);
if (!dir) {
ESP_LOGE(TAG, "Failed to stat dir : %s", dirpath);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to stat dir: %s", dirpath);
/* Respond with 404 Not Found */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Directory does not exist");
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
return ESP_FAIL;
}
@@ -361,9 +361,9 @@ static esp_err_t send_datafile(httpd_req_t *req, bool send_full_file)
fd = OpenFileAndWait(currentfilename.c_str(), "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read existing file: %s", filepath);
/* Respond with 404 Error */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
return ESP_FAIL;
}
@@ -446,9 +446,9 @@ static esp_err_t send_logfile(httpd_req_t *req, bool send_full_file)
fd = OpenFileAndWait(currentfilename.c_str(), "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read existing file: %s", filepath);
/* Respond with 404 Error */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
return ESP_FAIL;
}
@@ -534,8 +534,8 @@ static esp_err_t download_get_handler(httpd_req_t *req)
if (!filename) {
ESP_LOGE(TAG, "Filename is too long");
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
/* Respond with 414 Error */
httpd_resp_send_err(req, HTTPD_414_URI_TOO_LONG, "Filename too long");
return ESP_FAIL;
}
@@ -566,17 +566,17 @@ static esp_err_t download_get_handler(httpd_req_t *req)
/* If file not present on SPIFFS check if URI
* corresponds to one of the hardcoded paths */
ESP_LOGE(TAG, "Failed to stat file : %s", filepath);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to stat file: %s!", filepath);
/* Respond with 404 Not Found */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
return ESP_FAIL;
}
fd = OpenFileAndWait(filepath, "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read existing file: %s!", filepath);
/* Respond with 404 Error */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
return ESP_FAIL;
}
@@ -599,7 +599,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
/* Abort sending file */
httpd_resp_sendstr_chunk(req, NULL);
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to send file");
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to send file!");
return ESP_FAIL;
}
@@ -628,15 +628,16 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
const char *filename = get_path_from_uri(filepath, ((struct file_server_data *)req->user_ctx)->base_path,
req->uri + sizeof("/upload") - 1, sizeof(filepath));
if (!filename) {
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
/* Respond with 413 Error */
httpd_resp_send_err(req, HTTPD_414_URI_TOO_LONG, "Filename too long");
return ESP_FAIL;
}
/* Filename cannot have a trailing '/' */
if (filename[strlen(filename) - 1] == '/') {
ESP_LOGE(TAG, "Invalid filename: %s", filename);
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Invalid filename");
/* Respond with 400 Bad Request */
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid filename");
return ESP_FAIL;
}
@@ -790,8 +791,8 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
const char *filename = get_path_from_uri(filepath, ((struct file_server_data *)req->user_ctx)->base_path,
req->uri + sizeof("/delete") - 1, sizeof(filepath));
if (!filename) {
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
/* Respond with 414 Error */
httpd_resp_send_err(req, HTTPD_414_URI_TOO_LONG, "Filename too long");
return ESP_FAIL;
}
zw = std::string(filename);
@@ -825,7 +826,8 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
/* Filename cannot have a trailing '/' */
if (filename[strlen(filename) - 1] == '/') {
ESP_LOGE(TAG, "Invalid filename: %s", filename);
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Invalid filename");
/* Respond with 400 Bad Request */
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid filename");
return ESP_FAIL;
}

View File

@@ -37,8 +37,8 @@ esp_err_t send_file(httpd_req_t *req, std::string filename)
FILE *fd = OpenFileAndWait(filename.c_str(), "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file: %s", filename.c_str());
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
/* Respond with 404 Error */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
return ESP_FAIL;
}

View File

@@ -225,6 +225,7 @@ bool ClassFlowMQTT::doFlow(string zwtime)
std::string result;
std::string resulterror = "";
std::string resultraw = "";
std::string resultpre = "";
std::string resultrate = ""; // Always Unit / Minute
std::string resultRatePerTimeUnit = ""; // According to selection
std::string resulttimestamp = "";
@@ -244,6 +245,7 @@ bool ClassFlowMQTT::doFlow(string zwtime)
{
result = (*NUMBERS)[i]->ReturnValue;
resultraw = (*NUMBERS)[i]->ReturnRawValue;
resultpre = (*NUMBERS)[i]->ReturnPreValue;
resulterror = (*NUMBERS)[i]->ErrorMessageText;
resultrate = (*NUMBERS)[i]->ReturnRateValue; // Unit per minutes
resultchangabs = (*NUMBERS)[i]->ReturnChangeAbsolute; // Units per round
@@ -294,6 +296,9 @@ bool ClassFlowMQTT::doFlow(string zwtime)
json += "{\"value\": \"\"";
json += ", \"raw\": \""+resultraw;
json += ", \"pre\": \"" + resultpre;
json += "\", \"error\": \""+resulterror;
if (resultrate.length() > 0)
@@ -306,21 +311,23 @@ bool ClassFlowMQTT::doFlow(string zwtime)
MQTTPublish(namenumber + "json", json, SetRetainFlag);
}
}
else
{
for (int i = 0; i < ListFlowControll->size(); ++i)
{
zw = (*ListFlowControll)[i]->getReadout();
if (zw.length() > 0)
{
if (result.length() == 0)
result = zw;
else
result = result + "\t" + zw;
}
}
MQTTPublish(topic, result, SetRetainFlag);
}
/* Disabled because this is no longer a use case */
// else
// {
// for (int i = 0; i < ListFlowControll->size(); ++i)
// {
// zw = (*ListFlowControll)[i]->getReadout();
// if (zw.length() > 0)
// {
// if (result.length() == 0)
// result = zw;
// else
// result = result + "\t" + zw;
// }
// }
// MQTTPublish(topic, result, SetRetainFlag);
// }
OldValue = result;

View File

@@ -791,3 +791,14 @@ string getResetReason(void) {
}
return reasonText;
}
const char* get404(void) {
return
"<pre>\n\n\n\n"
" _\n"
" .__(.)< ( oh oh! This page does not exist! )\n"
" \\___)\n"
"\n\n"
" You could try your <a href=index.html target=_parent>luck</a> here!</pre>\n"
"<script>document.cookie = \"page=overview.html\"</script>"; // Make sure we load the overview page
}

View File

@@ -64,3 +64,5 @@ string getSDCardSectorSize();
string getMac(void);
string getResetReason(void);
const char* get404(void);

View File

@@ -176,7 +176,7 @@ bool MQTT_Init() {
if ((client_id.length() == 0) || (lwt_topic.length() == 0))
{
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, std::string("Init with no Client_ID or Topic. Abort Init!"));
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, std::string("Init with no Client_ID (" + client_id + ") or Last Will Topic (" + lwt_topic + "). Abort Init!"));
return false;
}

View File

@@ -162,7 +162,7 @@ void MQTThomeassistantDiscovery() {
void publishSystemData() {
char tmp_char[50];
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Publishing system MQTT topics...");
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Publishing system MQTT topics...");
sprintf(tmp_char, "%ld", (long)getUpTime());
MQTTPublish(maintopic + "/" + "uptime", std::string(tmp_char), retainFlag);
@@ -179,7 +179,7 @@ void publishSystemData() {
void publishStaticData() {
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Publishing static MQTT topics...");
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Publishing static MQTT topics...");
MQTTPublish(maintopic + "/" + "MAC", getMac(), retainFlag);
MQTTPublish(maintopic + "/" + "IP", *getIPAddress(), retainFlag);
MQTTPublish(maintopic + "/" + "hostname", hostname, retainFlag);

View File

@@ -736,7 +736,7 @@ void task_autodoFlow(void *pvParameter)
while (auto_isrunning)
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "----------------------------------------------------------------"); // Clear separation between runs
std::string _zw = "task_autodoFlow - next round - Round #" + std::to_string(++countRounds);
std::string _zw = "task_autodoFlow - Starting Round #" + std::to_string(++countRounds);
LogFile.WriteToFile(ESP_LOG_INFO, TAG, _zw);
fr_start = esp_timer_get_time();
@@ -760,13 +760,15 @@ void task_autodoFlow(void *pvParameter)
LogFile.RemoveOldDataLog();
}
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "task_autodoFlow - round #" + std::to_string(countRounds) + " done");
//CPU Temp
float cputmp = temperatureRead();
std::stringstream stream;
stream << std::fixed << std::setprecision(1) << cputmp;
string zwtemp = "CPU Temperature: " + stream.str();
LogFile.WriteToFile(ESP_LOG_INFO, TAG, zwtemp);
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zwtemp);
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "task_autodoFlow - round #" + std::to_string(countRounds) + " completed");
fr_delta_ms = (esp_timer_get_time() - fr_start) / 1000;
if (auto_intervall > fr_delta_ms)
{

View File

@@ -214,7 +214,6 @@ extern "C" void app_main(void)
if (!setup_time()) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "NTP Initialization failed!");
initSucessful = false;
}
setBootTime();

View File

@@ -241,8 +241,8 @@ esp_err_t hello_main_handler(httpd_req_t *req)
if (!filename) {
ESP_LOGE(TAG, "Filename is too long");
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
/* Respond with 414 Error */
httpd_resp_send_err(req, HTTPD_414_URI_TOO_LONG, "Filename too long");
return ESP_FAIL;
}

View File

@@ -34,7 +34,7 @@ CONFIG_SPIRAM_BOOT_INIT=y
CONFIG_SPIRAM_USE_MALLOC=y
CONFIG_SPIRAM_MEMTEST=y
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=40960
CONFIG_SPIRAM_CACHE_WORKAROUND=y
CONFIG_ESP_INT_WDT_TIMEOUT_MS=300

View File

@@ -15,7 +15,7 @@
<script>
async function loadPage(page) {
console.log("loadPage(" + page + ")");
document.cookie = page;
document.cookie = "page="+page;
document.getElementById('maincontent').src = page;
[].forEach.call(document.querySelectorAll('.submenu'), function (el) {
@@ -28,6 +28,22 @@
el.style.visibility = 'visible';
});
}
function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for(let i = 0; i <ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
</script>
</head>
@@ -63,7 +79,7 @@
</li>
</ul>
<li><a href="#" onclick="loadPage('wasserzaehler.html?full');">Recognition</a></li>
<li><a href="#" onclick="loadPage('value?full');">Recognition</a></li>
<li><a href="#" onclick="loadPage('graph.html');">Data Graph</a></li>
<li><a href="#" onclick="loadPage('fileserver/');">File Server</a></li>
<li><a>System <i class="arrow down"></i></a>
@@ -88,11 +104,11 @@
LoadFwVersion();
LoadWebUiVersion();
if (document.cookie == "" || document.cookie == "reboot_page.html") {
document.cookie = "overview.html";
if (getCookie("page") == "" || getCookie("page") == "reboot_page.html") {
document.cookie = "page=overview.html";
}
console.log("Loading page: " + document.cookie);
document.getElementById('maincontent').src = document.cookie;
console.log("Loading page: " + getCookie("page"));
document.getElementById('maincontent').src = getCookie("page");
</script>
</div>

View File

@@ -210,7 +210,7 @@ function extract() {
document.getElementById("status").innerText = "Status: Update completed!";
document.getElementById("doUpdate").disabled = true;
document.getElementById("newfile").disabled = false;
document.cookie = "overview.html"; // Make sure after the reboot we go to the overview page
document.cookie = "page=overview.html"; // Make sure after the reboot we go to the overview page
if (xhttp.responseText.startsWith("reboot"))
{

View File

@@ -151,7 +151,7 @@ function refresh() {
}
function loadValue(_type, _div, _style) {
url = basepath + '/wasserzaehler.html?all=true&type=' + _type;
url = basepath + '/value?all=true&type=' + _type;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {

View File

@@ -16,7 +16,7 @@
var basepath = "http://192.168.178.22";
function testinit(){
basepath = getbasepath();
url = basepath + '/wasserzaehler.html?all=true';
url = basepath + '/value?all=true';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {