mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-31 03:48:25 +03:00
Merge branch 'jomjol:rolling' into rolling
This commit is contained in:
@@ -40,6 +40,11 @@ In other cases you can contact the developer via email: <img src="https://raw.gi
|
||||
|
||||
------
|
||||
|
||||
##### Rolling (2022-09-04)
|
||||
|
||||
- Improved Reboot (**[caco3](https://github.com/caco3)**)
|
||||
- HTML: Bug fix
|
||||
|
||||
##### Rolling (2022-09-03)
|
||||
|
||||
- MQTT: improved handling based on the work of @**[caco3](https://github.com/caco3)** ([#971](https://github.com/jomjol/AI-on-the-edge-device/pull/971))
|
||||
|
||||
@@ -437,7 +437,7 @@ esp_err_t handler_reboot(httpd_req_t *req)
|
||||
|
||||
LogFile.WriteToFile("handler_reboot");
|
||||
ESP_LOGI(TAGPARTOTA, "!!! System will restart within 5 sec!!!");
|
||||
const char* resp_str = "<body style='font-family: arial'> <h3 id=t></h3></body><script>var h='Rebooting!<br>The page will automatically reload.<br>'; document.getElementById('t').innerHTML=h; setInterval(function (){h +='.'; document.getElementById('t').innerHTML=h; fetch(window.location.hostname,{mode: 'no-cors'}).then(r=>{window.location.replace('/wasserzaehler_roi.html');})}, 1000);</script>";
|
||||
const char* resp_str = "<body style='font-family: arial'> <h3 id=t></h3></body><script>var h='Rebooting!<br>The page will automatically reload after around 25s.<br>'; document.getElementById('t').innerHTML=h; setInterval(function (){h +='.'; document.getElementById('t').innerHTML=h; fetch(window.location.hostname,{mode: 'no-cors'}).then(r=>{parent.location.href=('/index.html');})}, 1000);</script>";
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
doReboot();
|
||||
|
||||
@@ -340,38 +340,6 @@ int ClassFlowCNNGeneral::ZeigerEvalAnalogNeu(float zahl, int ziffer_vorgaenger)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
int ClassFlowCNNGeneral::ZeigerEval(float zahl, int ziffer_vorgaenger)
|
||||
{
|
||||
int ergebnis_nachkomma = ((int) floor(zahl * 10) + 10) % 10;
|
||||
int ergebnis_vorkomma = ((int) floor(zahl) + 10) % 10;
|
||||
int ergebnis;
|
||||
float ergebnis_rating;
|
||||
if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEval erg_v=" + std::to_string(ergebnis_vorkomma) + ", erg_n=" + std::to_string(ergebnis_nachkomma) + ", ziff_v=" + std::to_string(ziffer_vorgaenger));
|
||||
|
||||
if (ziffer_vorgaenger == -1)
|
||||
return ergebnis_vorkomma % 10;
|
||||
|
||||
// Ist die aktuelle Stelle schon umgesprungen und die Vorstelle noch nicht?
|
||||
// Akt.: 2.1, Vorstelle = 0.9 => 1.9
|
||||
// Problem sind mehrere Rundungen
|
||||
// Bsp. zahl=4.5, Vorgänger= 9.6 (ziffer_vorgaenger=0)
|
||||
// Tritt nur auf bei Übergang von analog auf digit
|
||||
ergebnis_rating = ergebnis_nachkomma - ziffer_vorgaenger;
|
||||
if (ergebnis_nachkomma >= 5)
|
||||
ergebnis_rating-=5.1;
|
||||
else
|
||||
ergebnis_rating+=5;
|
||||
ergebnis = (int) round(zahl);
|
||||
if (ergebnis_rating < 0)
|
||||
ergebnis-=1;
|
||||
if (ergebnis == -1)
|
||||
ergebnis+=10;
|
||||
|
||||
ergebnis = (ergebnis + 10) % 10;
|
||||
return ergebnis;
|
||||
}
|
||||
*/
|
||||
|
||||
bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
@@ -417,11 +385,6 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
this->logfileRetentionInDays = std::stoi(zerlegt[1]);
|
||||
}
|
||||
// if ((toUpper(zerlegt[0]) == "MODELTYPE") && (zerlegt.size() > 1))
|
||||
// {
|
||||
// if (toUpper(zerlegt[1]) == "DIGITHYPRID")
|
||||
// CNNType = DigitalHyprid;
|
||||
// }
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "MODEL") && (zerlegt.size() > 1))
|
||||
{
|
||||
@@ -664,10 +627,11 @@ bool ClassFlowCNNGeneral::getNetworkParameter()
|
||||
CNNType = Digital;
|
||||
printf("TFlite-Type set to Digital\n");
|
||||
break;
|
||||
case 20:
|
||||
/* case 20:
|
||||
CNNType = DigitalHyprid10;
|
||||
printf("TFlite-Type set to DigitalHyprid10\n");
|
||||
break;
|
||||
*/
|
||||
// case 22:
|
||||
// CNNType = DigitalHyprid;
|
||||
// printf("TFlite-Type set to DigitalHyprid\n");
|
||||
@@ -801,6 +765,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
}
|
||||
} break;
|
||||
*/
|
||||
/*
|
||||
case DigitalHyprid10:
|
||||
{
|
||||
int _num, _nachkomma;
|
||||
@@ -836,6 +801,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
}
|
||||
}
|
||||
} break;
|
||||
*/
|
||||
|
||||
case DoubleHyprid10:
|
||||
{
|
||||
@@ -869,7 +835,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
_fit = _val + _valminus;
|
||||
|
||||
}
|
||||
if (result > 10)
|
||||
if (result >= 10)
|
||||
result = result - 10;
|
||||
if (result < 0)
|
||||
result = result + 10;
|
||||
|
||||
@@ -37,12 +37,9 @@ protected:
|
||||
bool isLogImageSelect;
|
||||
string LogImageSelect;
|
||||
ClassFlowAlignment* flowpostalignment;
|
||||
// ClassFlowPostProcessing *flowpostprocessing = NULL;
|
||||
bool SaveAllFiles;
|
||||
// bool extendedResolution;
|
||||
|
||||
// int ZeigerEval(float zahl, int ziffer_vorgaenger);
|
||||
// int ZeigerEvalHybrid(float zahl, float zahl_vorgaenger, int eval_vorgaenger);
|
||||
bool SaveAllFiles;
|
||||
|
||||
int ZeigerEvalAnalogNeu(float zahl, int ziffer_vorgaenger);
|
||||
int ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger, int eval_vorgaenger);
|
||||
int ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger, int eval_vorgaenger, bool AnalogerVorgaenger = false);
|
||||
|
||||
@@ -63,7 +63,12 @@ void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, i
|
||||
if (*resultFloat < 0)
|
||||
sprintf(buf, "N.N_");
|
||||
else
|
||||
{
|
||||
sprintf(buf, "%.1f_", *resultFloat);
|
||||
if (strcmp(buf, "10.0_"))
|
||||
sprintf(buf, "0.0_");
|
||||
}
|
||||
|
||||
} else if (resultInt != NULL) {
|
||||
sprintf(buf, "%d_", *resultInt);
|
||||
} else {
|
||||
|
||||
@@ -32,9 +32,7 @@ void ClassFlowMQTT::SetInitialParameter(void)
|
||||
ListFlowControll = NULL;
|
||||
disabled = false;
|
||||
MQTTenable = false;
|
||||
|
||||
|
||||
|
||||
keepAlive = 600; // TODO This must be greater than the Flow Interval!
|
||||
}
|
||||
|
||||
ClassFlowMQTT::ClassFlowMQTT()
|
||||
@@ -125,15 +123,50 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
printf("InitMQTTInit\n");
|
||||
mainerrortopic = maintopic + "/connection";
|
||||
printf("Init MQTT with uri: %s, clientname: %s, user: %s, password: %s, maintopic: %s\n", uri.c_str(), clientname.c_str(), user.c_str(), password.c_str(), mainerrortopic.c_str());
|
||||
MQTTInit(uri, clientname, user, password, mainerrortopic, 60);
|
||||
if (MQTTPublish(mainerrortopic, "connected", SetRetainFlag)) {
|
||||
MQTTenable = true;
|
||||
}
|
||||
else {
|
||||
MQTTenable = true;
|
||||
if (!MQTTInit(uri, clientname, user, password, mainerrortopic, keepAlive))
|
||||
{ // Failed
|
||||
MQTTenable = false;
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}
|
||||
}
|
||||
|
||||
// Try sending mainerrortopic. If it fails, re-run init
|
||||
if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
{ // Failed
|
||||
LogFile.WriteToFile("MQTT - Re-running init...!");
|
||||
if (!MQTTInit(this->uri, this->clientname, this->user, this->password, this->mainerrortopic, keepAlive))
|
||||
{ // Failed
|
||||
MQTTenable = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Try again and quit if it fails
|
||||
if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
{ // Failed
|
||||
MQTTenable = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
{ // Failed
|
||||
LogFile.WriteToFile("MQTT - Could not publish connection status!");
|
||||
MQTTenable = false;
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}*/
|
||||
|
||||
/* if(!MQTTPublish(_LWTContext, "", 1))
|
||||
{
|
||||
LogFile.WriteToFile("MQTT - Could not publish LWT!");
|
||||
MQTTenable = false;
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}*/
|
||||
|
||||
|
||||
MQTTenable = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -146,18 +179,43 @@ string ClassFlowMQTT::GetMQTTMainTopic()
|
||||
|
||||
bool ClassFlowMQTT::doFlow(string zwtime)
|
||||
{
|
||||
if (!MQTTenable) {
|
||||
LogFile.WriteToFile("MQTT not enabled!");
|
||||
// if (!MQTTenable) {
|
||||
// LogFile.WriteToFile("MQTT not enabled!");
|
||||
//
|
||||
// // Try again to init it
|
||||
// if (!MQTTInit(this->uri, this->clientname, this->user, this->password, this->mainerrortopic, keepAlive))
|
||||
// { // Failed
|
||||
// MQTTenable = false;
|
||||
// return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
// }
|
||||
//
|
||||
// if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
// { // Failed
|
||||
// MQTTenable = false;
|
||||
// return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
// }
|
||||
//
|
||||
// LogFile.WriteToFile("MQTT is now enabled");
|
||||
// MQTTenable = true;
|
||||
// }
|
||||
|
||||
// Try again to init it
|
||||
MQTTInit(this->uri, this->clientname, this->user, this->password, this->mainerrortopic, 60);
|
||||
if (MQTTPublish(mainerrortopic, "connected", SetRetainFlag)) {
|
||||
MQTTenable = true;
|
||||
}
|
||||
else { // Failed
|
||||
|
||||
// Try sending mainerrortopic. If it fails, re-run init
|
||||
if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
{ // Failed
|
||||
LogFile.WriteToFile("MQTT - Re-running init...!");
|
||||
if (!MQTTInit(this->uri, this->clientname, this->user, this->password, this->mainerrortopic, keepAlive))
|
||||
{ // Failed
|
||||
MQTTenable = false;
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}
|
||||
LogFile.WriteToFile("MQTT is now enabled");
|
||||
}
|
||||
}
|
||||
|
||||
// Try again and quit if it fails
|
||||
if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
{ // Failed
|
||||
MQTTenable = false;
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}
|
||||
|
||||
std::string result;
|
||||
@@ -169,12 +227,10 @@ bool ClassFlowMQTT::doFlow(string zwtime)
|
||||
string zw = "";
|
||||
string namenumber = "";
|
||||
|
||||
if (MQTTPublish(mainerrortopic, "connected")) {
|
||||
MQTTenable = true;
|
||||
}
|
||||
else { // Failed, skip other topics
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}
|
||||
// if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
//{ // Failed, skip other topics
|
||||
// return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
//}
|
||||
|
||||
zw = maintopic + "/" + "uptime";
|
||||
char uptimeStr[11];
|
||||
@@ -184,7 +240,10 @@ bool ClassFlowMQTT::doFlow(string zwtime)
|
||||
zw = maintopic + "/" + "freeMem";
|
||||
char freeheapmem[11];
|
||||
sprintf(freeheapmem, "%zu", esp_get_free_heap_size());
|
||||
MQTTPublish(zw, freeheapmem, SetRetainFlag);
|
||||
if (!MQTTPublish(zw, freeheapmem, SetRetainFlag))
|
||||
{ // Failed, skip other topics
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}
|
||||
|
||||
zw = maintopic + "/" + "wifiRSSI";
|
||||
char rssi[11];
|
||||
|
||||
@@ -15,6 +15,7 @@ protected:
|
||||
std::string user, password;
|
||||
int SetRetainFlag;
|
||||
bool MQTTenable;
|
||||
int keepAlive;
|
||||
|
||||
std::string maintopic, mainerrortopic;
|
||||
void SetInitialParameter(void);
|
||||
|
||||
@@ -20,22 +20,36 @@ bool mqtt_connected = false;
|
||||
esp_mqtt_client_handle_t client = NULL;
|
||||
|
||||
bool MQTTPublish(std::string _key, std::string _content, int retained_flag){
|
||||
if (!client) {
|
||||
LogFile.WriteToFile("MQTT - client not initialized!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (!client) {
|
||||
// LogFile.WriteToFile("MQTT - client not initialized!");
|
||||
// return false;
|
||||
// }
|
||||
// LogFile.WriteToFile("MQTT - client initialized!"); // Debug
|
||||
//
|
||||
// if (!mqtt_connected) {
|
||||
// LogFile.WriteToFile("MQTT - Can not publish, not connected!");
|
||||
// ESP_LOGW(TAG_INTERFACEMQTT, "Problem with Publish, client=%d, mqtt_connected %d", (int) client, (int) mqtt_connected);
|
||||
// return false;
|
||||
// }
|
||||
// LogFile.WriteToFile("MQTT - connected!"); // Debug
|
||||
|
||||
if (!mqtt_connected) {
|
||||
LogFile.WriteToFile("MQTT - Can not publish, not connected!");
|
||||
ESP_LOGW(TAG_INTERFACEMQTT, "Problem with Publish, client=%d, mqtt_connected %d", (int) client, (int) mqtt_connected);
|
||||
return false;
|
||||
/* if (client && mqtt_connected) {
|
||||
LogFile.WriteToFile("MQTT - connected!"); // Debug
|
||||
}
|
||||
else { // init needed
|
||||
if (!MQTTInit(this->uri, this->clientname, this->user, password, mainerrortopic, keepAlive)) // validate{
|
||||
{ // Failed
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
int msg_id;
|
||||
std::string zw;
|
||||
msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag);
|
||||
if (msg_id < 0) {
|
||||
LogFile.WriteToFile("MQTT - Failed to publish + " + _key + ", no connection!");
|
||||
LogFile.WriteToFile("MQTT - Failed to publish '" + _key + "'!");
|
||||
return false;
|
||||
}
|
||||
zw = "MQTT - sent publish successful in MQTTPublish, msg_id=" + std::to_string(msg_id) + ", " + _key + ", " + _content;
|
||||
@@ -102,7 +116,7 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
}
|
||||
|
||||
|
||||
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive){
|
||||
bool MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive){
|
||||
std::string _zwmessage = "connection lost";
|
||||
|
||||
int _lzw = _zwmessage.length();
|
||||
@@ -141,20 +155,30 @@ void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, st
|
||||
if (client)
|
||||
{
|
||||
if (esp_mqtt_client_register_event(client, esp_mmqtt_ID, mqtt_event_handler, client) != ESP_OK)
|
||||
{
|
||||
LogFile.WriteToFile("MQTT - Could not register event!");
|
||||
if (esp_mqtt_client_start(client) != ESP_OK)
|
||||
LogFile.WriteToFile("MQTT - Could not start client!");
|
||||
|
||||
if(MQTTPublish(_LWTContext, "", 1)) {
|
||||
LogFile.WriteToFile("MQTT - Client init successful");
|
||||
return false;
|
||||
}
|
||||
if (esp_mqtt_client_start(client) != ESP_OK)
|
||||
{
|
||||
LogFile.WriteToFile("MQTT - Could not start client!");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* if(!MQTTPublish(_LWTContext, "", 1))
|
||||
{
|
||||
LogFile.WriteToFile("MQTT - Could not publish LWT!");
|
||||
return false;
|
||||
}*/
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.WriteToFile("MQTT - Could not Init client!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
LogFile.WriteToFile("MQTT - Init successful");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -256,7 +280,7 @@ void MQTTconnected(){
|
||||
}
|
||||
}
|
||||
|
||||
if (subscribeFunktionMap != NULL) {
|
||||
if (subscribeFunktionMap != NULL) {
|
||||
for(std::map<std::string, std::function<bool(std::string, char*, int)>>::iterator it = subscribeFunktionMap->begin(); it != subscribeFunktionMap->end(); ++it) {
|
||||
int msg_id = esp_mqtt_client_subscribe(client, it->first.c_str(), 0);
|
||||
ESP_LOGD(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", it->first.c_str(), msg_id);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive);
|
||||
bool MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive);
|
||||
void MQTTdestroy();
|
||||
|
||||
//void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user = "", std::string _password = "");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const char* GIT_REV="77427a8";
|
||||
const char* GIT_REV="47da2d6";
|
||||
const char* GIT_TAG="";
|
||||
const char* GIT_BRANCH="rolling";
|
||||
const char* BUILD_TIME="2022-09-03 08:15";
|
||||
const char* BUILD_TIME="2022-09-04 18:01";
|
||||
@@ -1,4 +1,4 @@
|
||||
const char* GIT_REV="77427a8";
|
||||
const char* GIT_REV="47da2d6";
|
||||
const char* GIT_TAG="";
|
||||
const char* GIT_BRANCH="rolling";
|
||||
const char* BUILD_TIME="2022-09-03 08:15";
|
||||
const char* BUILD_TIME="2022-09-04 18:01";
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -5,7 +5,110 @@
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="style.css" type="text/css" >
|
||||
<!-- <link rel="stylesheet" href="style.css" type="text/css" > -->
|
||||
<style>
|
||||
/* Older Firmware versions (11.2.0 and older) do not support css files, therefore we need to keep it integrated for now! */
|
||||
body, html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 800px;
|
||||
margin: 0px 0px 0px 2px;
|
||||
padding: 0;
|
||||
font-family: arial;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.main {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.iframe {
|
||||
flex-grow: 1;
|
||||
margin: 5px 7px 4px 0px;
|
||||
padding: 0;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin-block-end: 0.3em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5em;
|
||||
margin-block-start: 0.3em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: #333;
|
||||
width:1000px;
|
||||
}
|
||||
|
||||
li {
|
||||
float: left;
|
||||
font-family: arial;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
li a, .dropbtn {
|
||||
display: inline-block;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
li a:hover, .dropdown:hover .dropbtn {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
li.dropdown {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.dropdown-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 160px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
z-index: 1;
|
||||
font-family: arial;
|
||||
}
|
||||
|
||||
.dropdown-content a {
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.dropdown-content a:hover {
|
||||
color: white;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.dropdown:hover .dropdown-content {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" src="common.js"></script>
|
||||
<script type="text/javascript" src="gethost.js"></script>
|
||||
|
||||
@@ -5,7 +5,110 @@
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="style.css" type="text/css" >
|
||||
<!-- <link rel="stylesheet" href="style.css" type="text/css" > -->
|
||||
<style>
|
||||
/* Older Firmware versions (11.2.0 and older) do not support css files, therefore we need to keep it integrated for now! */
|
||||
body, html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 800px;
|
||||
margin: 0px 0px 0px 2px;
|
||||
padding: 0;
|
||||
font-family: arial;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.main {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.iframe {
|
||||
flex-grow: 1;
|
||||
margin: 5px 7px 4px 0px;
|
||||
padding: 0;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin-block-end: 0.3em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5em;
|
||||
margin-block-start: 0.3em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: #333;
|
||||
width:1000px;
|
||||
}
|
||||
|
||||
li {
|
||||
float: left;
|
||||
font-family: arial;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
li a, .dropbtn {
|
||||
display: inline-block;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
li a:hover, .dropdown:hover .dropbtn {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
li.dropdown {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.dropdown-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 160px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
z-index: 1;
|
||||
font-family: arial;
|
||||
}
|
||||
|
||||
.dropdown-content a {
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.dropdown-content a:hover {
|
||||
color: white;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.dropdown:hover .dropdown-content {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -38,6 +141,7 @@
|
||||
<li class="dropdown">
|
||||
<a href="javascript:void(0)" class="dropbtn">System</a>
|
||||
<div class="dropdown-content">
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/backup.html';">Backup/Restore</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/ota_page.html';">OTA Update</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/fileserver/log/message/?readonly=true';">Log Viewer</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/reboot_page.html';">Reboot</a>
|
||||
|
||||
@@ -1 +1 @@
|
||||
16.3.2
|
||||
16.3.4
|
||||
Reference in New Issue
Block a user