From ec33c19dbea10f17aa7a03be97ce8da173965179 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 15 Jun 2021 20:53:49 +0200 Subject: [PATCH 1/7] Berry report bug fix #106 --- lib/libesp32/Berry/src/be_func.c | 17 +++++++++++------ lib/libesp32/Berry/tests/closure.be | 13 +++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 lib/libesp32/Berry/tests/closure.be diff --git a/lib/libesp32/Berry/src/be_func.c b/lib/libesp32/Berry/src/be_func.c index a4e210271601..d492299540f4 100644 --- a/lib/libesp32/Berry/src/be_func.c +++ b/lib/libesp32/Berry/src/be_func.c @@ -54,17 +54,22 @@ void be_initupvals(bvm *vm, bclosure *cl) void be_upvals_close(bvm *vm, bvalue *level) { bupval *node = vm->upvalist, *next; - while (node && node->value >= level) { + bupval **prev = &vm->upvalist; + while (node) { next = node->u.next; - if (!node->refcnt) { - be_free(vm, node, sizeof(bupval)); + if (node->value >= level) { + if (!node->refcnt) { + be_free(vm, node, sizeof(bupval)); + } else { + node->u.value = *node->value; /* move value to upvalue slot */ + node->value = &node->u.value; + } + *prev = next; /* remove from linked list */ } else { - node->u.value = *node->value; /* move value to upvalue slot */ - node->value = &node->u.value; + prev = &node->u.next; } node = next; } - vm->upvalist = node; } void be_release_upvalues(bvm *vm, bclosure *cl) diff --git a/lib/libesp32/Berry/tests/closure.be b/lib/libesp32/Berry/tests/closure.be new file mode 100644 index 000000000000..2474fede9d48 --- /dev/null +++ b/lib/libesp32/Berry/tests/closure.be @@ -0,0 +1,13 @@ +#- test for issue #105 -# + +l=[] +def tick() + var start=100 + for i : 1..3 + l.push(def () return [i, start] end) + end +end +tick() +assert(l[0]() == [1, 100]) +assert(l[1]() == [2, 100]) +assert(l[2]() == [3, 100]) From 7988e68d8ba9f7f5cc12f1cacf1d82ef1874f712 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 15 Jun 2021 21:14:01 +0200 Subject: [PATCH 2/7] Fix NEO_RGBW --- tasmota/xlgt_01_ws2812.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xlgt_01_ws2812.ino b/tasmota/xlgt_01_ws2812.ino index 37002f9e6659..a7e7c992700e 100644 --- a/tasmota/xlgt_01_ws2812.ino +++ b/tasmota/xlgt_01_ws2812.ino @@ -69,7 +69,7 @@ void (* const Ws2812Command[])(void) PROGMEM = { #elif (USE_WS2812_CTYPE == NEO_RBG) #define NEO_FEATURE_TYPE Rbg #elif (USE_WS2812_CTYPE == NEO_RGBW) - #define NEO_FEATURE_TYPE Rbgw + #define NEO_FEATURE_TYPE Rgbw #elif (USE_WS2812_CTYPE == NEO_GRBW) #define NEO_FEATURE_TYPE Grbw #else From 35c0e991b6727bf0c6b05f11cdc033ef9212ba0d Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Tue, 15 Jun 2021 20:39:49 -0300 Subject: [PATCH 3/7] Allow Captive Portal to be optional --- tasmota/xdrv_01_webserver.ino | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index e92650fe95f0..31ef3cef3ba9 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -1017,7 +1017,9 @@ void WebSliderColdWarm(void) void HandleRoot(void) { +#ifndef NO_CAPTIVE_PORTAL if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the page. +#endif // NO_CAPTIVE_PORTAL if (Webserver->hasArg(F("rst"))) { WebRestart(0); @@ -2941,8 +2943,9 @@ void HandleConsoleRefresh(void) void HandleNotFound(void) { // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Not found (%s)"), Webserver->uri().c_str()); - +#ifndef NO_CAPTIVE_PORTAL if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the error page. +#endif // NO_CAPTIVE_PORTAL #ifdef USE_EMULATION #ifdef USE_EMULATION_HUE @@ -2962,6 +2965,7 @@ void HandleNotFound(void) } } +#ifndef NO_CAPTIVE_PORTAL /* Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */ bool CaptivePortal(void) { @@ -2976,6 +2980,7 @@ bool CaptivePortal(void) } return false; } +#endif // NO_CAPTIVE_PORTAL /*********************************************************************************************/ From e0b0c1fae1e9db9e285ff660e77f858f89a141c9 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 16 Jun 2021 08:37:28 +0200 Subject: [PATCH 4/7] Fix Berry documentation link --- tasmota/xdrv_52_9_berry.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_52_9_berry.ino b/tasmota/xdrv_52_9_berry.ino index a58044431df8..4840f7a54a23 100644 --- a/tasmota/xdrv_52_9_berry.ino +++ b/tasmota/xdrv_52_9_berry.ino @@ -593,7 +593,7 @@ const char HTTP_BERRY_FORM_CMND[] PROGMEM = "
" "
" "
Welcome to the Berry Scripting console. " - "Check the documentation." + "Check the documentation." "
" "
" // "" From f2fd0750d52778ebbddfaf4681cfd52eab7b3f57 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 16 Jun 2021 13:37:33 +0200 Subject: [PATCH 5/7] Improve behavior of color2 for unlinked RGBW and RGBWW lights --- tasmota/xdrv_04_light.ino | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 27051e00e353..5ecb4f2e8558 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -2497,11 +2497,18 @@ void CmndSupportColor(void) else { #endif // USE_LIGHT_PALETTE uint32_t old_bri = light_state.getBri(); + uint32_t old_bri_rgb = light_state.getBriRGB(); // change all channels to specified values light_controller.changeChannels(Light.entry_color); if (2 == XdrvMailbox.index) { // If Color2, set back old brightness - LightSetBriScaled(old_bri); + if (light_controller.isCTRGBLinked()) { + // RGB and white are linked, adjust brightness of all channels + LightSetBriScaled(old_bri); + } else { + // RGB and white are unlinked, adjust brightness only of RGB channels + LightSetBri(Light.device, old_bri_rgb); + } } #ifdef USE_LIGHT_PALETTE } From 2c5809bee250473cab50d79572cf8c763ec2209e Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 16 Jun 2021 21:55:45 +0200 Subject: [PATCH 6/7] Remove exceptions from BLE --- tasmota/xdrv_79_esp32_ble.ino | 146 +++++++++++++--------------------- 1 file changed, 55 insertions(+), 91 deletions(-) diff --git a/tasmota/xdrv_79_esp32_ble.ino b/tasmota/xdrv_79_esp32_ble.ino index d85b9873b484..b96338f75b85 100644 --- a/tasmota/xdrv_79_esp32_ble.ino +++ b/tasmota/xdrv_79_esp32_ble.ino @@ -1408,22 +1408,16 @@ class BLEAdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { // call anyone who asked about advertisements for (int i = 0; i < advertismentCallbacks.size(); i++) { - try { - ADVERTISMENT_CALLBACK* pFN; - pFN = advertismentCallbacks[i]; - int res = pFN(&BLEAdvertisment); + ADVERTISMENT_CALLBACK* pFN; + pFN = advertismentCallbacks[i]; + int res = pFN(&BLEAdvertisment); - // if this callback wants to stop here, then do so. - if (1 == res) break; + // if this callback wants to stop here, then do so. + if (1 == res) break; - // if this callback wants to kill this device - if (2 == res) { - //BLEScan->erase(address); - } - } catch(const std::exception& e){ -#ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_ERROR,PSTR("BLE: exception in advertismentCallbacks")); -#endif + // if this callback wants to kill this device + if (2 == res) { + //BLEScan->erase(address); } } @@ -1444,17 +1438,11 @@ static void BLEscanEndedCB(NimBLEScanResults results){ if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: Scan ended")); #endif for (int i = 0; i < scancompleteCallbacks.size(); i++){ - try { - SCANCOMPLETE_CALLBACK *pFn = scancompleteCallbacks[i]; - int callbackres = pFn(results); -#ifdef BLE_ESP32_DEBUG - if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: scancompleteCallbacks %d %d"), i, callbackres); -#endif - } catch(const std::exception& e){ + SCANCOMPLETE_CALLBACK *pFn = scancompleteCallbacks[i]; + int callbackres = pFn(results); #ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_ERROR,PSTR("BLE: exception in operationsCallbacks")); + if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: scancompleteCallbacks %d %d"), i, callbackres); #endif - } } BLERunningScan = 2; @@ -1659,23 +1647,17 @@ static void BLETaskStopStartNimBLE(NimBLEClient **ppClient, bool start = true){ (*ppClient)->setClientCallbacks(nullptr, false); - try { - if ((*ppClient)->isConnected()){ -#ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_INFO,PSTR("BLE: disconnecting connected client")); -#endif - (*ppClient)->disconnect(); - } - NimBLEDevice::deleteClient((*ppClient)); - (*ppClient) = nullptr; + if ((*ppClient)->isConnected()){ #ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_INFO,PSTR("BLE: deleted client")); + AddLog(LOG_LEVEL_INFO,PSTR("BLE: disconnecting connected client")); #endif - } catch(const std::exception& e){ + (*ppClient)->disconnect(); + } + NimBLEDevice::deleteClient((*ppClient)); + (*ppClient) = nullptr; #ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_ERROR,PSTR("BLE: Stopping NimBLE:exception in delete client")); + AddLog(LOG_LEVEL_INFO,PSTR("BLE: deleted client")); #endif - } if (ble32Scan){ ble32Scan->setAdvertisedDeviceCallbacks(nullptr,true); @@ -2089,47 +2071,41 @@ static void BLETaskRunCurrentOperation(BLE_ESP32::generic_sensor_t** pCurrentOpe // for safety's sake, only call from the run task static void BLETaskRunTaskDoneOperation(BLE_ESP32::generic_sensor_t** op, NimBLEClient **ppClient){ - try { - if ((*ppClient)->isConnected()){ + if ((*ppClient)->isConnected()){ #ifdef BLE_ESP32_DEBUG - if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: runTaskDoneOperation: disconnecting connected client")); + if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: runTaskDoneOperation: disconnecting connected client")); #endif - (*ppClient)->disconnect(); - // wait for 1/2 second after disconnect - int waits = 0; - do { - vTaskDelay(500/ portTICK_PERIOD_MS); - if (waits) { - //(*ppClient)->disconnect(); - // we will stall here forever!!! - as testing + (*ppClient)->disconnect(); + // wait for 1/2 second after disconnect + int waits = 0; + do { + vTaskDelay(500/ portTICK_PERIOD_MS); + if (waits) { + //(*ppClient)->disconnect(); + // we will stall here forever!!! - as testing #ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_ERROR,PSTR("BLE: wait discon%d"), waits); + AddLog(LOG_LEVEL_ERROR,PSTR("BLE: wait discon%d"), waits); #endif - vTaskDelay(500/ portTICK_PERIOD_MS); - } - waits++; - if (waits == 5){ - int conn_id = (*ppClient)->getConnId(); - ble_gap_conn_broken(conn_id, -1); + vTaskDelay(500/ portTICK_PERIOD_MS); + } + waits++; + if (waits == 5){ + int conn_id = (*ppClient)->getConnId(); + ble_gap_conn_broken(conn_id, -1); #ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_ERROR,PSTR("BLE: wait discon%d - kill connection"), waits); + AddLog(LOG_LEVEL_ERROR,PSTR("BLE: wait discon%d - kill connection"), waits); #endif - } - if (waits == 60){ - AddLog(LOG_LEVEL_ERROR,PSTR("BLE: >60s waiting -> BLE Failed, restart Tasmota %d"), waits); - BLEStop = 1; - BLEStopAt = esp_timer_get_time(); + } + if (waits == 60){ + AddLog(LOG_LEVEL_ERROR,PSTR("BLE: >60s waiting -> BLE Failed, restart Tasmota %d"), waits); + BLEStop = 1; + BLEStopAt = esp_timer_get_time(); - BLERestartTasmota = 10; - BLERestartTasmotaReason = BLE_RESTART_TEAMOTA_REASON_BLE_DISCONNECT_FAIL; - break; - } - } while ((*ppClient)->isConnected()); - } - } catch(const std::exception& e){ -#ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_ERROR,PSTR("BLE: runTaskDoneOperation: exception in disconnect")); -#endif + BLERestartTasmota = 10; + BLERestartTasmotaReason = BLE_RESTART_TEAMOTA_REASON_BLE_DISCONNECT_FAIL; + break; + } + } while ((*ppClient)->isConnected()); } @@ -3322,35 +3298,23 @@ static void mainThreadOpCallbacks() { if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: op->completecallback is %u opid %d"), op->completecallback, op->opid); if (op->completecallback){ - try { - OPCOMPLETE_CALLBACK *pFn = (OPCOMPLETE_CALLBACK *)(op->completecallback); - callbackres = pFn(op); + OPCOMPLETE_CALLBACK *pFn = (OPCOMPLETE_CALLBACK *)(op->completecallback); + callbackres = pFn(op); #ifdef BLE_ESP32_DEBUG - if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: op->completecallback %d opid %d"), callbackres, op->opid); + if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: op->completecallback %d opid %d"), callbackres, op->opid); #endif - } catch(const std::exception& e){ -#ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_ERROR,PSTR("BLE: exception in op->completecallback")); -#endif - } } if (!callbackres){ for (int i = 0; i < operationsCallbacks.size(); i++){ - try { - if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: operationsCallbacks %d is %u"), i, operationsCallbacks[i]); - OPCOMPLETE_CALLBACK *pFn = operationsCallbacks[i]; - callbackres = pFn(op); -#ifdef BLE_ESP32_DEBUG - if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: operationsCallbacks %d %d"), i, callbackres); -#endif - if (callbackres){ - break; // this callback ate the op. - } - } catch(const std::exception& e){ + if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: operationsCallbacks %d is %u"), i, operationsCallbacks[i]); + OPCOMPLETE_CALLBACK *pFn = operationsCallbacks[i]; + callbackres = pFn(op); #ifdef BLE_ESP32_DEBUG - AddLog(LOG_LEVEL_ERROR,PSTR("BLE: exception in operationsCallbacks")); + if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: operationsCallbacks %d %d"), i, callbackres); #endif + if (callbackres){ + break; // this callback ate the op. } } } From cd99034f797a9b66e646012ce394771271b0b502 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Thu, 17 Jun 2021 08:28:55 +0200 Subject: [PATCH 7/7] Berry improve inheritance #107 --- lib/libesp32/Berry/src/be_class.c | 2 ++ lib/libesp32/Berry/src/be_class.h | 3 +++ lib/libesp32/Berry/src/be_vm.c | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/lib/libesp32/Berry/src/be_class.c b/lib/libesp32/Berry/src/be_class.c index 280e3e6d068b..ffb196372876 100644 --- a/lib/libesp32/Berry/src/be_class.c +++ b/lib/libesp32/Berry/src/be_class.c @@ -165,6 +165,7 @@ static binstance* newobjself(bvm *vm, bclass *c) while (v < end) { var_setnil(v); ++v; } obj->_class = c; obj->super = NULL; + obj->sub = NULL; } return obj; } @@ -178,6 +179,7 @@ static binstance* newobject(bvm *vm, bclass *c) be_incrtop(vm); /* protect new objects from GC */ for (c = c->super; c; c = c->super) { prev->super = newobjself(vm, c); + prev->super->sub = prev; prev = prev->super; } be_stackpop(vm, 1); diff --git a/lib/libesp32/Berry/src/be_class.h b/lib/libesp32/Berry/src/be_class.h index 148f1b57aee8..3b9458013768 100644 --- a/lib/libesp32/Berry/src/be_class.h +++ b/lib/libesp32/Berry/src/be_class.h @@ -18,11 +18,13 @@ #define be_class_members(cl) ((cl)->members) #define be_class_super(cl) ((cl)->super) #define be_class_setsuper(self, sup) ((self)->super = (sup)) +#define be_class_setsub(self, sub) ((self)->sub = (sub)) #define be_instance_name(obj) ((obj)->_class->name) #define be_instance_class(obj) ((obj)->_class) #define be_instance_members(obj) ((obj)->members) #define be_instance_member_count(obj) ((obj)->_class->nvar) #define be_instance_super(obj) ((obj)->super) +#define be_instance_sub(obj) ((obj)->sub) struct bclass { bcommon_header; @@ -41,6 +43,7 @@ struct bclass { struct binstance { bcommon_header; struct binstance *super; + struct binstance *sub; bclass *_class; bgcobject *gray; /* for gc gray list */ bvalue members[1]; /* members variable data field */ diff --git a/lib/libesp32/Berry/src/be_vm.c b/lib/libesp32/Berry/src/be_vm.c index b58da91d99d1..97fee645c02b 100644 --- a/lib/libesp32/Berry/src/be_vm.c +++ b/lib/libesp32/Berry/src/be_vm.c @@ -779,6 +779,11 @@ static void vm_exec(bvm *vm) int type = obj_attribute(vm, b, c, a); reg = vm->reg; if (basetype(type) == BE_FUNCTION) { + /* check if the object is a superinstance, if so get the lowest possible subclass */ + while (obj->sub) { + obj = obj->sub; + } + var_setobj(&self, var_type(&self), obj); /* replace superinstance by lowest subinstance */ a[1] = self; } else { vm_error(vm, "attribute_error",