Add Button to dynamically load GPIO Viewer with Berry backend (#20424)

This commit is contained in:
s-hadinger 2024-01-08 09:30:18 +01:00 committed by GitHub
parent d51340961f
commit aa1dd392ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 26 deletions

View File

@ -35,6 +35,7 @@ All notable changes to this project will be documented in this file.
- HASPmota `haspmota.page_show()` to change page (#20333)
- Berry `introspect.set()` for class attributes (#20339)
- Support negative power on BL0942 using index 5..8 (#20322)
- Button to dynamically load GPIO Viewer with Berry backend
### Breaking Changed
- Refactoring of Berry `animate` module for WS2812 Leds (#20236)

View File

@ -1146,6 +1146,8 @@
#define USE_BERRY_WEBCLIENT_TIMEOUT 2000 // Default timeout in milliseconds
//#define USE_BERRY_PARTITION_WIZARD // Add a button to dynamically load the Partion Wizard from a bec file online (+1.3KB Flash)
#define USE_BERRY_PARTITION_WIZARD_URL "http://ota.tasmota.com/tapp/partition_wizard.bec"
//#define USE_BERRY_GPIOVIEWER // Add a button to dynamocally load the GPIO Viewer from a bec file online
#define USE_BERRY_GPIOVIEWER_URL "http://ota.tasmota.com/tapp/gpioviewer.bec"
#define USE_BERRY_TCPSERVER // Enable TCP socket server (+0.6k)
// #define USE_BERRY_ULP // Enable ULP (Ultra Low Power) support (+4.9k)
// Berry crypto extensions below:

View File

@ -96,6 +96,9 @@ public:
#ifdef USE_BERRY_PARTITION_WIZARD
bool partition_wizard_loaded = false; // did we already load Parition_Wizard
#endif // USE_BERRY_PARTITION_WIZARD
#ifdef USE_BERRY_GPIOVIEWER
bool gpviewer_loaded = false; // did we already load GPIOViewer
#endif // USE_BERRY_GPIOVIEWER
bool autoexec_done = false; // do we still need to load 'autoexec.be'
bool repl_active = false; // is REPL running (activates log recording)
// output log is stored as a LinkedList of buffers
@ -107,4 +110,41 @@ BerrySupport berry;
// multi-purpose serial logging
extern "C" void serial_debug(const char * berry_buf, ...);
/*********************************************************************************************\
* Handle dynamic code from Berry bec files
*
\*********************************************************************************************/
struct BeBECCode_t {
const char * display_name; // display name in Web UI (must be URL encoded)
const char * id; // id in requested URL, also don't load if the global name already exists in Berry
const char * url; // absolute URL to download the bec file
const char * redirect; // relative URI to redirect after loading
bool * loaded;
};
const BeBECCode_t BECCode[] = {
#ifdef USE_BERRY_PARTITION_WIZARD
{
"Partition Wizard",
"partition_wizard",
USE_BERRY_PARTITION_WIZARD_URL,
"/part_wiz",
&berry.partition_wizard_loaded
},
#endif // USE_BERRY_PARTITION_WIZARD
#ifdef USE_BERRY_GPIOVIEWER
{
"GPIO Viewer",
"gpioviewer",
USE_BERRY_GPIOVIEWER_URL,
"/mn?",
&berry.gpviewer_loaded
},
#endif // USE_BERRY_GPIOVIEWER
};
#endif // USE_BERRY

View File

@ -764,33 +764,50 @@ void HandleBerryConsole(void)
WSContentStop();
}
#ifdef USE_BERRY_PARTITION_WIZARD
// Display a Button to dynamically load the Partition Wizard
void HandleBerryPartiionWizardLoaderButton(void) {
// const BeBECCode_t BECCode[] = {
// struct BeBECCode_t {
// const char * display_name; // display name in Web UI (must be URL encoded)
// const char * id; // id in requested URL
// const char * url; // absolute URL to download the bec file
// const char * redirect; // relative URI to redirect after loading
// };
// Display Buttons to dynamically load bec files
void HandleBerryBECLoaderButton(void) {
bvm * vm = berry.vm;
static const char PARTITION_WIZARD_NAME[] = "partition_wizard";
if (!berry.partition_wizard_loaded) {
if (be_global_find(vm, be_newstr(vm, PARTITION_WIZARD_NAME)) < 0) { // the global name `partition_wizard` doesn't exist
WSContentSend_P("<form id=but_part_mgr style='display: block;' action='tapp' method='get'><input type='hidden' name='n' value='Partition_Wizard'/><button>[Load Partition Wizard]</button></form><p></p>");
} else {
berry.partition_wizard_loaded = true;
for (int32_t i = 0; i < ARRAY_SIZE(BECCode); i++) {
const BeBECCode_t &bec = BECCode[i];
if (!(*bec.loaded)) {
if (be_global_find(vm, be_newstr(vm, bec.id)) < 0) { // the global name doesn't exist
WSContentSend_P("<form id=but_part_mgr style='display: block;' action='tapp' method='get'><input type='hidden' name='n' value='%s'/><button>[Load %s]</button></form><p></p>", bec.id, bec.display_name);
} else {
*bec.loaded = true;
}
}
}
}
extern "C" bbool BerryBECLoader(const char * url);
void HandleBerryPartitionWizardLoader(void) {
if (BerryBECLoader(USE_BERRY_PARTITION_WIZARD_URL)) {
// All good, redirect
Webserver->sendHeader("Location", "/part_wiz", true);
Webserver->send(302, "text/plain", "");
berry.partition_wizard_loaded = true;
} else {
Webserver->sendHeader("Location", "/mn?", true);
Webserver->send(302, "text/plain", "");
void HandleBerryBECLoader(void) {
String n = Webserver->arg("n");
for (int32_t i = 0; i < ARRAY_SIZE(BECCode); i++) {
const BeBECCode_t &bec = BECCode[i];
if (n.equals(bec.id)) {
if (BerryBECLoader(bec.url)) {
// All good, redirect
Webserver->sendHeader("Location", bec.redirect, true);
Webserver->send(302, "text/plain", "");
*bec.loaded = true;
} else {
Webserver->sendHeader("Location", "/mn?", true);
Webserver->send(302, "text/plain", "");
}
}
}
}
#endif //USE_BERRY_PARTITION_WIZARD
// return true if successful
extern "C" bbool BerryBECLoader(const char * url) {
@ -925,9 +942,7 @@ bool Xdrv52(uint32_t function)
XdrvMailbox.index++;
} else {
WSContentSend_P(HTTP_BTN_BERRY_CONSOLE);
#ifdef USE_BERRY_PARTITION_WIZARD
HandleBerryPartiionWizardLoaderButton();
#endif // USE_BERRY_PARTITION_WIZARD
HandleBerryBECLoaderButton(); // display buttons to load BEC files
callBerryEventDispatcher(PSTR("web_add_button"), nullptr, 0, nullptr);
callBerryEventDispatcher(PSTR("web_add_console_button"), nullptr, 0, nullptr);
}
@ -946,10 +961,8 @@ bool Xdrv52(uint32_t function)
callBerryEventDispatcher(PSTR("web_add_handler"), nullptr, 0, nullptr);
berry.web_add_handler_done = true;
}
WebServer_on(PSTR("/bc"), HandleBerryConsole);
#ifdef USE_BERRY_PARTITION_WIZARD
Webserver->on("/tapp", HTTP_GET, HandleBerryPartitionWizardLoader);
#endif // USE_BERRY_PARTITION_WIZARD
WebServer_on("/bc", HandleBerryConsole);
WebServer_on("/tapp", HandleBerryBECLoader, HTTP_GET);
break;
#endif // USE_WEBSERVER
case FUNC_SAVE_BEFORE_RESTART: