Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions tasmota/my_user_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
40 changes: 40 additions & 0 deletions tasmota/tasmota_xdrv_driver/xdrv_52_0_berry_struct.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
65 changes: 39 additions & 26 deletions tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
Expand All @@ -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:
Expand Down