diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index a217911ee..609d4ea86 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,7 +7,7 @@ - [ ] Only relevant files were touched - [ ] Only one feature/fix was added per PR and the code change compiles without warnings - [ ] The code change is tested and works with Tasmota core ESP8266 V.2.7.4.9 - - [ ] The code change is tested and works with Tasmota core ESP32 V.1.0.7.3 + - [ ] The code change is tested and works with Tasmota core ESP32 V.1.0.7.4 - [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla). _NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_ diff --git a/BUILDS.md b/BUILDS.md index 2a236c205..1998788c2 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -55,6 +55,7 @@ m = minimal, l = lite, t = tasmota, k = knx, s = sensors, i = ir, d = display | USE_KEELOQ | - | - | - / - | - | - | - | - | | USE_SONOFF_D1 | - | - | x / - | x | - | - | - | | USE_SHELLY_DIMMER | - | - | x / - | - | - | - | - | +| USE_AC_ZERO_CROSS_DIMMER | - | - | x / x | x | x | x | x | | | | | | | | | | | Feature or Sensor | m | l | t | k | s | i | d | Remarks | USE_LIGHT | - | x | x / x | x | x | x | x | @@ -79,7 +80,7 @@ m = minimal, l = lite, t = tasmota, k = knx, s = sensors, i = ir, d = display | USE_DDSU666 | - | - | - / x | - | x | - | - | | USE_SOLAX_X1 | - | - | - / - | - | - | - | - | | USE_LE01MR | - | - | - / - | - | - | - | - | -| USE_BL0940 | - | x | x / - | x | x | - | - | +| USE_BL09XX | - | x | x / x | x | x | - | - | | USE_TELEINFO | - | - | - / - | - | - | - | - | | USE_IEM3000 | - | - | - / - | - | - | - | - | | USE_WE517 | - | - | - / - | - | - | - | - | diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dbd2f8bb..dad1692a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,11 +13,14 @@ All notable changes to this project will be documented in this file. - Support for ESP32/ESP32S2 DAC gpio via Berry - Berry support for Serial - Support for Sensirion SCD40/SCD41 CO2 sensor +- Support for BL0939 energy monitor as used in ESP32 based Sonoff Dual R3 V2 Pow (#13195) ### Changed - M5 Stack Core2 uses UNIVERSAL_DISPLAY with enabled LVGL as default now - ``DisplayDimmer`` has now range 0..100 instead of 0..15 - Minimum PWM Frequency lowered to 2Hz on ESP32 (#13123) +- Use Tasmota Arduino Core32 1.0.7.4 for ESP32 builds (#13154) +- Shrinked Webcam build, uses now `USE_TASMOTA_DISCOVERY` (#13148) ### Fixed - OpenTherm invalid JSON (#13028) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 3b4496ee8..c0c887c15 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -107,9 +107,9 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Command ``SetSensor1..127 0|1`` to globally disable individual sensor driver - Command ``Subscribe2 ...`` to subscribe to a MQTT topic without appended "/#" [#12858](https://github.com/arendst/Tasmota/issues/12858) - Command ``WebGetConfig `` if ``#define USE_WEBGETCONFIG`` is enabled to restore/init configuration from external webserver [#13034](https://github.com/arendst/Tasmota/issues/13034) +- Optional IP filter to command ``TCPStart`` [#12806](https://github.com/arendst/Tasmota/issues/12806) - Neopool commands ``NPPHRes``, ``NPCLRes`` and ``NPIonRes`` [#12813](https://github.com/arendst/Tasmota/issues/12813) - Support for second DNS server -- Support for (Yeelight) Mi Desk Pro using binary tasmota32solo1.bin - Support for influxdb using ``#define USE_INFLUXDB`` and several ``Ifx`` commands - Support for AM2320 Temperature and Humidity Sensor by Lars Wessels [#12485](https://github.com/arendst/Tasmota/issues/12485) - Support for Technoline WS2300-15 Anemometer [#12573](https://github.com/arendst/Tasmota/issues/12573) @@ -118,29 +118,32 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Support for IEM3155 Wattmeter [#12940](https://github.com/arendst/Tasmota/issues/12940) - Support for Hydreon RG-15 Solid State Rain sensor [#12974](https://github.com/arendst/Tasmota/issues/12974) - Support for IKEA VINDRIKTNING particle concentration sensor [#12976](https://github.com/arendst/Tasmota/issues/12976) +- Support for BL0939 energy monitor as used in ESP32 based Sonoff Dual R3 V2 Pow [#13195](https://github.com/arendst/Tasmota/issues/13195) - Initial support for Tasmota Mesh (TasMesh) providing node/broker communication using ESP-NOW [#11939](https://github.com/arendst/Tasmota/issues/11939) -- Inital support for Wi-Fi extender [#12784](https://github.com/arendst/Tasmota/issues/12784) -- Berry ESP32 partition manager [#12465](https://github.com/arendst/Tasmota/issues/12465) -- Berry ESP32 support for I2S audio mp3 playback -- Berry ESP32 support for vararg -- Berry ESP32 support for Curve 25519 EC crypto +- Initial support for Wi-Fi extender [#12784](https://github.com/arendst/Tasmota/issues/12784) - Rule event support as JSON payload [#12496](https://github.com/arendst/Tasmota/issues/12496) - MQTT minimum password length restriction in GUI [#12553](https://github.com/arendst/Tasmota/issues/12553) -- Optional IP filter to command ``TCPStart`` [#12806](https://github.com/arendst/Tasmota/issues/12806) +- ESP32 Berry partition manager [#12465](https://github.com/arendst/Tasmota/issues/12465) +- ESP32 Berry class ``webclient`` for HTTP/HTTPS requests +- ESP32 Berry support for I2S audio mp3 playback +- ESP32 Berry support for vararg +- ESP32 Berry support for Curve 25519 EC crypto +- ESP32 Berry support for ESP32/ESP32S2 DAC gpio +- ESP32 Berry support for Serial +- ESP32 support for (Yeelight) Mi Desk Pro using binary tasmota32solo1.bin +- ESP32-S2 support for GPIOs +- ESP32 add GPIO 6/7/8/11 to template and remove GPIO 28-31 (remapping so backwards compatible) +- ESP32 crash recorder ``Status 12`` for ESP32/ESP32-S2/ESP32-C3, supporting Esp-idf 3.3/4.4 ### Changed - Move firmware binaries to https://github.com/arendst/Tasmota-firmware/tree/main/release-firmware -- ESP32 core library from v1.0.6 to v1.0.7.3 - IRremoteESP8266 library from v2.7.18 to v2.7.20 - NeoPixelBus library from v2.6.3 to v2.6.7 - Message ``Upload buffer miscompare`` into ``Not enough space`` -- ESP32 Ethernet Phy Type information to IDF v3+ +- Command ``DisplayDimmer`` has now range 0..100 instead of 0..15 - Speed up initial GUI console refresh - Enable UFILESYS, GUI_TRASH_FILE and GUI_EDIT_FILE for any device compiled with more than 1M flash size -- ESP32 internal sensor driver id moved from 87 to 127 - Supported sensor driver range extended from 96 to 128 -- Disable PSRAM on unsupported hardware -- ESP32 remove GPIO initialization to INPUT from not used GPIOs to allow JTAG support - Relax NTP poll if no ntpserver can be resolved by DNS - Shelly EM template needs to use GPIO ``ADE7953_IRQ 2`` - Make Sonoff L1 MusicSync persistent [#12008](https://github.com/arendst/Tasmota/issues/12008) @@ -153,26 +156,27 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Prometheus: All metrics are prefixed with ``tasmota_`` [#12842](https://github.com/arendst/Tasmota/issues/12842) Memory metrics have been cleaned up to work consistently between ESP8266 and ESP32 The device name is reported as an info metric +- ESP32 core library from v1.0.6 to v1.0.7.4 +- ESP32 Ethernet Phy Type information to IDF v3+ +- ESP32 internal sensor driver id moved from 87 to 127 +- ESP32 disable PSRAM on unsupported hardware +- ESP32 remove GPIO initialization to INPUT from not used GPIOs to allow JTAG support +- ESP32 M5 Stack Core2 uses UNIVERSAL_DISPLAY with enabled LVGL as default now +- ESP32 minimum PWM Frequency lowered to 2Hz [#13123](https://github.com/arendst/Tasmota/issues/13123) +- ESP32 shrinked Webcam build, uses now `USE_TASMOTA_DISCOVERY` [#13148](https://github.com/arendst/Tasmota/issues/13148) ### Fixed -- ESP32 core v2.0.0 setting hostname -- ESP32-C3 settings layout for configuration backup and restore -- ESP32-Solo OTA upgrade - Sonoff L1 (lite) smoother color transitions - DDS238-2 wrong reactive power value [#12283](https://github.com/arendst/Tasmota/issues/12283) -- ESP32 Webcam add boundary marker before sending mjpeg image [#12376](https://github.com/arendst/Tasmota/issues/12376) - NO VALID JSON regression from may 4th [#12440](https://github.com/arendst/Tasmota/issues/12440) - Telegram response decoding stopped working after 20210621 and exception on long result message [#12451](https://github.com/arendst/Tasmota/issues/12451) - Neopool compile error on DEBUG_TASMOTA_SENSOR [#12464](https://github.com/arendst/Tasmota/issues/12464) -- Berry button handlers and error messages [#12521](https://github.com/arendst/Tasmota/issues/12521) - Scripter and Display MQTT errors due to MQTT_DATA move to String [#12525](https://github.com/arendst/Tasmota/issues/12525) - Scripter moving average and sml input validation [#12541](https://github.com/arendst/Tasmota/issues/12541) - Zigbee Hue angle encoding [#12545](https://github.com/arendst/Tasmota/issues/12545) - Exception 28 when unable to send MQTT message and a topic name without a slash '/' [#12555](https://github.com/arendst/Tasmota/issues/12555) - Wi-Fi initial setup workaround for 11n only routers [#12566](https://github.com/arendst/Tasmota/issues/12566) -- ESP32 do not use chip temperature sensor as global temperature if external temperature sensor is used [#12630](https://github.com/arendst/Tasmota/issues/12630) - Discovery fails when using ``%hostname%`` in a topic [#12710](https://github.com/arendst/Tasmota/issues/12710) -- ESP32 buzzer in PWM mode exception [#12717](https://github.com/arendst/Tasmota/issues/12717) - Neopool communication error [#12813](https://github.com/arendst/Tasmota/issues/12813) - Shelly Dimmer 2 Energy usage [#12815](https://github.com/arendst/Tasmota/issues/12815) - WDT reset on shutters with stepper motors during deceleration [#12849](https://github.com/arendst/Tasmota/issues/12849) @@ -182,4 +186,11 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Hass and Tasmota discovery prefix topic notifications [#12972](https://github.com/arendst/Tasmota/issues/12972) - OpenTherm invalid JSON [#13028](https://github.com/arendst/Tasmota/issues/13028) - MQTT TLS related connection timing errors [#13033](https://github.com/arendst/Tasmota/issues/13033) +- ESP32 core v2.0.0 setting hostname +- ESP32-C3 settings layout for configuration backup and restore +- ESP32-Solo OTA upgrade +- ESP32 Webcam add boundary marker before sending mjpeg image [#12376](https://github.com/arendst/Tasmota/issues/12376) +- ESP32 Berry button handlers and error messages [#12521](https://github.com/arendst/Tasmota/issues/12521) +- ESP32 do not use chip temperature sensor as global temperature if external temperature sensor is used [#12630](https://github.com/arendst/Tasmota/issues/12630) +- ESP32 buzzer in PWM mode exception [#12717](https://github.com/arendst/Tasmota/issues/12717) - ESP32 crash when PSRAM is absent and ``BOARD_HAS_PSRAM`` set [#13037](https://github.com/arendst/Tasmota/issues/13037) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..f0a8de1ed --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +## Reporting a Vulnerability + +Please report security issues to https://sidweb.nl/cms3/en/contact diff --git a/boards/esp32c3.json b/boards/esp32c3.json index b68f06d92..cedcf1500 100644 --- a/boards/esp32c3.json +++ b/boards/esp32c3.json @@ -4,7 +4,6 @@ "ldscript": "esp32c3_out.ld" }, "core": "esp32", - "extra_flags": "-DBOARD_HAS_PSRAM", "f_cpu": "160000000L", "f_flash": "80000000L", "flash_mode": "dout", diff --git a/lib/lib_basic/LinkedList-1.2.3/LICENSE.txt b/lib/default/LinkedList-1.2.3/LICENSE.txt similarity index 100% rename from lib/lib_basic/LinkedList-1.2.3/LICENSE.txt rename to lib/default/LinkedList-1.2.3/LICENSE.txt diff --git a/lib/lib_basic/LinkedList-1.2.3/LinkedList.h b/lib/default/LinkedList-1.2.3/LinkedList.h similarity index 100% rename from lib/lib_basic/LinkedList-1.2.3/LinkedList.h rename to lib/default/LinkedList-1.2.3/LinkedList.h diff --git a/lib/lib_basic/LinkedList-1.2.3/README.md b/lib/default/LinkedList-1.2.3/README.md similarity index 100% rename from lib/lib_basic/LinkedList-1.2.3/README.md rename to lib/default/LinkedList-1.2.3/README.md diff --git a/lib/lib_basic/LinkedList-1.2.3/examples/ClassList/ClassList.pde b/lib/default/LinkedList-1.2.3/examples/ClassList/ClassList.pde similarity index 100% rename from lib/lib_basic/LinkedList-1.2.3/examples/ClassList/ClassList.pde rename to lib/default/LinkedList-1.2.3/examples/ClassList/ClassList.pde diff --git a/lib/lib_basic/LinkedList-1.2.3/examples/SimpleIntegerList/SimpleIntegerList.pde b/lib/default/LinkedList-1.2.3/examples/SimpleIntegerList/SimpleIntegerList.pde similarity index 100% rename from lib/lib_basic/LinkedList-1.2.3/examples/SimpleIntegerList/SimpleIntegerList.pde rename to lib/default/LinkedList-1.2.3/examples/SimpleIntegerList/SimpleIntegerList.pde diff --git a/lib/lib_basic/LinkedList-1.2.3/keywords.txt b/lib/default/LinkedList-1.2.3/keywords.txt similarity index 100% rename from lib/lib_basic/LinkedList-1.2.3/keywords.txt rename to lib/default/LinkedList-1.2.3/keywords.txt diff --git a/lib/lib_basic/LinkedList-1.2.3/library.json b/lib/default/LinkedList-1.2.3/library.json similarity index 100% rename from lib/lib_basic/LinkedList-1.2.3/library.json rename to lib/default/LinkedList-1.2.3/library.json diff --git a/lib/lib_basic/LinkedList-1.2.3/library.properties b/lib/default/LinkedList-1.2.3/library.properties similarity index 100% rename from lib/lib_basic/LinkedList-1.2.3/library.properties rename to lib/default/LinkedList-1.2.3/library.properties diff --git a/lib/libesp32/Berry/default/be_lvgl_ctypes.c b/lib/libesp32/Berry/default/be_ctypes.c similarity index 78% rename from lib/libesp32/Berry/default/be_lvgl_ctypes.c rename to lib/libesp32/Berry/default/be_ctypes.c index 1c5e52b46..16aeff8d7 100644 --- a/lib/libesp32/Berry/default/be_lvgl_ctypes.c +++ b/lib/libesp32/Berry/default/be_ctypes.c @@ -1,12 +1,10 @@ /******************************************************************** - * Tasmota LVGL ctypes mapping + * Tasmota ctypes mapping *******************************************************************/ #include "be_constobj.h" +#include -#ifdef USE_LVGL - -#include "lvgl.h" - +extern __attribute__((noreturn)) void be_raisef(bvm *vm, const char *except, const char *msg, ...); // binary search within an array of sorted strings // the first 4 bytes are a pointer to a string @@ -68,6 +66,7 @@ typedef struct be_ctypes_structure_item_t { typedef struct be_ctypes_structure_t { uint16_t size_bytes; /* size in bytes */ uint16_t size_elt; /* number of elements */ + const char **instance_mapping; /* array of instance class names for automatic instanciation of class */ const be_ctypes_structure_item_t * items; } be_ctypes_structure_t; @@ -97,14 +96,6 @@ int be_ctypes_init(bvm *vm) { src_data = (void*) be_toint(vm, 2); } - // get global array of classes from global variable '.ctypes_classes' - be_getglobal(vm, ".ctypes_classes"); - const be_ctypes_classes_t * be_ctypes_classes = (const be_ctypes_classes_t *) be_tocomptr(vm, -1); - be_pop(vm, 1); - // berry_log_C("be_ctypes_init> be_ctypes_class = %p", be_ctypes_classes); - const char * class_name = be_classname(vm, 1); - // berry_log_C("be_ctypes_init> class_name = %s", class_name); - // call super(self, bytes) be_getglobal(vm, "super"); // push super function be_pushvalue(vm, 1); // push self instance @@ -121,16 +112,10 @@ int be_ctypes_init(bvm *vm) { // berry_log_C("be_ctypes_init> init called"); // look for class definition - int32_t class_idx = bin_search_ctypes(class_name, &be_ctypes_classes->classes[0], sizeof(be_ctypes_class_t), be_ctypes_classes->size); - if (class_idx >= 0) { - // found - const be_ctypes_structure_t * definitions = be_ctypes_classes->classes[class_idx].definitions; - // store definition in '.def' - // berry_log_C("Found definitions = %p", definitions); - be_pushcomptr(vm, (void*) definitions); - be_setmember(vm, 1, ".def"); - be_pop(vm, 1); - + be_getmember(vm, 1, "_def"); // static class comptr + const be_ctypes_structure_t *definitions; + definitions = (const be_ctypes_structure_t *) be_tocomptr(vm, -1); + if (definitions) { // call self.resize(definitions->size_bytes) be_getmember(vm, 1, "resize"); be_pushvalue(vm, 1); @@ -167,9 +152,13 @@ int be_ctypes_copy(bvm *vm) { be_return(vm); } +// get an attribute from a ctypes structure +// arg1: ctypes instance +// arg2: name of the argument +// The class has a `_def` static class attribute with the C low-level mapping definition int be_ctypes_member(bvm *vm) { int argc = be_top(vm); - be_getmember(vm, 1, ".def"); + be_getmember(vm, 1, "_def"); const be_ctypes_structure_t *definitions; definitions = (const be_ctypes_structure_t *) be_tocomptr(vm, -1); be_pop(vm, 1); @@ -194,14 +183,14 @@ int be_ctypes_member(bvm *vm) { } else { // general int support int size = member->type; // eventually 1/2/4, positive if little endian, negative if big endian - int sign = false; // signed int + int sign = bfalse; // signed int if (size >= ctypes_i8) { size -= ctypes_i8 - 1; - sign = true; + sign = btrue; } if (size <= ctypes_be_i8) { size += ctypes_be_i8 - 1; - sign = true; + sign = btrue; } // get be_getmember(vm, 1, sign ? "geti" : "get"); // self.get or self.geti @@ -215,14 +204,7 @@ int be_ctypes_member(bvm *vm) { // the int result is at top of the stack // check if we need an instance mapping if (member->mapping > 0) { - // find the name of the class - - // get global array of classes from global variable '.ctypes_classes' - be_getglobal(vm, ".ctypes_classes"); - const be_ctypes_classes_t * be_ctypes_classes = (const be_ctypes_classes_t *) be_tocomptr(vm, -1); - be_pop(vm, 1); - - const char * mapping_name = be_ctypes_classes->instance_mapping[member->mapping - 1]; + const char * mapping_name = definitions->instance_mapping[member->mapping - 1]; if (mapping_name) { be_getglobal(vm, mapping_name); // stack: class be_pushvalue(vm, -2); // stack: class, value @@ -259,7 +241,15 @@ int be_ctypes_setmember(bvm *vm) { be_pop(vm, 1); } - be_getmember(vm, 1, ".def"); + // If the value is a pointer, replace with an int of same value (works only on 32 bits CPU) + if (be_iscomptr(vm, 3)) { + void * v = be_tocomptr(vm, 3); + be_pushint(vm, (int32_t) v); + be_moveto(vm, -1, 3); + be_pop(vm, 1); + } + + be_getmember(vm, 1, "_def"); const be_ctypes_structure_t *definitions; definitions = (const be_ctypes_structure_t *) be_tocomptr(vm, -1); be_pop(vm, 1); @@ -285,14 +275,14 @@ int be_ctypes_setmember(bvm *vm) { } else { // general int support int size = member->type; // eventually 1/2/4, positive if little endian, negative if big endian - int sign = false; // signed int + int sign = bfalse; // signed int if (size >= ctypes_i8) { size -= ctypes_i8 - 1; - sign = true; + sign = btrue; } if (size <= ctypes_be_i8) { size += ctypes_be_i8 - 1; - sign = true; + sign = btrue; } // set be_getmember(vm, 1, sign ? "seti" : "set"); // self.get or self.geti @@ -304,48 +294,28 @@ int be_ctypes_setmember(bvm *vm) { be_pop(vm, 5); be_return_nil(vm); } + } else { + be_raisef(vm, "attribute_error", "class '%s' cannot assign to attribute '%s'", + be_classname(vm, 1), be_tostring(vm, 2)); } - - be_return_nil(vm); } BE_EXPORT_VARIABLE extern const bclass be_class_bytes; -#if BE_USE_PRECOMPILED_OBJECT -#include "../generate/be_fixed_be_class_lv_ctypes.h" -#endif +#include "../generate/be_fixed_be_class_ctypes.h" -void be_load_lvgl_ctypes_lib(bvm *vm) { -#if !BE_USE_PRECOMPILED_OBJECT - static const bnfuncinfo members[] = { - { ".def", NULL }, // pointer to definition - { "init", be_ctypes_init }, - { "copy", be_ctypes_copy }, - { "member", be_ctypes_member }, - { "setmember", be_ctypes_setmember }, - { NULL, NULL } - }; - be_regclass(vm, "ctypes_bytes", members); - - be_getglobal(vm, "ctypes_bytes"); - be_getglobal(vm, "bytes"); - be_setsuper(vm, -2); - be_pop(vm, 2); -#else - be_pushntvclass(vm, &be_class_lv_ctypes); +void be_load_ctypes_lib(bvm *vm) { + be_pushntvclass(vm, &be_class_ctypes); be_setglobal(vm, "ctypes_bytes"); be_pop(vm, 1); -#endif } /* @const_object_info_begin -class be_class_lv_ctypes (scope: global, name: ctypes_bytes, super: be_class_bytes) { - .def, var +class be_class_ctypes (scope: global, name: ctypes_bytes, super: be_class_bytes) { + _def, nil() copy, func(be_ctypes_copy) init, func(be_ctypes_init) member, func(be_ctypes_member) setmember, func(be_ctypes_setmember) } @const_object_info_end */ - -#endif // USE_LVGL \ No newline at end of file diff --git a/lib/libesp32/Berry/default/be_driverlib.c b/lib/libesp32/Berry/default/be_driverlib.c index 72874c08b..dbef17a94 100644 --- a/lib/libesp32/Berry/default/be_driverlib.c +++ b/lib/libesp32/Berry/default/be_driverlib.c @@ -23,7 +23,7 @@ be_local_closure(init, /* name */ (be_nested_const_str("init", 380752755, 4)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 R0 + 0x80000000, // 0000 RET 0 }) ) ); @@ -44,12 +44,12 @@ be_local_closure(get_tasmota, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - be_nested_string("tasmota", 424643812, 7), /* R256 - K0 */ + /* K0 */ be_nested_string("tasmota", 424643812, 7), }), (be_nested_const_str("get_tasmota", 334356779, 11)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[ 2]) { /* code */ - 0xB8060000, // 0000 GETNGBL R1 R256 + 0xB8060000, // 0000 GETNGBL R1 K0 0x80040200, // 0001 RET 1 R1 }) ) @@ -98,19 +98,19 @@ be_local_closure(add_cmd, /* name */ }), 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ - be_nested_string("tasmota", 424643812, 7), /* R256 - K0 */ - be_nested_string("add_cmd", -933336417, 7), /* R257 - K1 */ + /* K0 */ be_nested_string("tasmota", 424643812, 7), + /* K1 */ be_nested_string("add_cmd", -933336417, 7), }), (be_nested_const_str("add_cmd", -933336417, 7)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[ 7]) { /* code */ - 0xB80E0000, // 0000 GETNGBL R3 R256 - 0x8C0C0701, // 0001 GETMET R3 R3 R257 + 0xB80E0000, // 0000 GETNGBL R3 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 0x5C140200, // 0002 MOVE R5 R1 0x84180000, // 0003 CLOSURE R6 P0 0x7C0C0600, // 0004 CALL R3 3 - 0xA0000000, // 0005 CLOSE 0 - 0x80000000, // 0006 RET 0 R0 + 0xA0000000, // 0005 CLOSE R0 + 0x80000000, // 0006 RET 0 }) ) ); diff --git a/lib/libesp32/Berry/default/be_energylib.c b/lib/libesp32/Berry/default/be_energylib.c index eb267f5db..1cbb0822e 100644 --- a/lib/libesp32/Berry/default/be_energylib.c +++ b/lib/libesp32/Berry/default/be_energylib.c @@ -11,19 +11,11 @@ extern int b_nrg_read(bvm *vm); -#if !BE_USE_PRECOMPILED_OBJECT -be_native_module_attr_table(energy) { - be_native_module_function("read", b_nrg_read), -}; - -be_define_native_module(energy, NULL); -#else /* @const_object_info_begin module energy (scope: global) { read, func(b_nrg_read) } @const_object_info_end */ #include "../generate/be_fixed_energy.h" -#endif #endif // USE_ENERGY_SENSOR \ No newline at end of file diff --git a/lib/libesp32/Berry/default/be_flash_lib.c b/lib/libesp32/Berry/default/be_flash_lib.c index b05b23637..539805d5d 100644 --- a/lib/libesp32/Berry/default/be_flash_lib.c +++ b/lib/libesp32/Berry/default/be_flash_lib.c @@ -11,16 +11,6 @@ extern int p_flash_read(bvm *vm); extern int p_flash_write(bvm *vm); extern int p_flash_erase(bvm *vm); -#if !BE_USE_PRECOMPILED_OBJECT -be_native_module_attr_table(flash) { - be_native_module_function("read", p_flash_read), - be_native_module_function("write", p_flash_write), - be_native_module_function("erase", p_flash_erase), - -}; - -be_define_native_module(flash, NULL); -#else /* @const_object_info_begin module flash (scope: global) { read, func(p_flash_read) @@ -29,4 +19,3 @@ module flash (scope: global) { } @const_object_info_end */ #include "../generate/be_fixed_flash.h" -#endif diff --git a/lib/libesp32/Berry/default/be_i2c_axp192_lib.c b/lib/libesp32/Berry/default/be_i2c_axp192_lib.c index b81c47775..5eba55476 100644 --- a/lib/libesp32/Berry/default/be_i2c_axp192_lib.c +++ b/lib/libesp32/Berry/default/be_i2c_axp192_lib.c @@ -476,7 +476,7 @@ be_local_closure(init, /* name */ (be_nested_const_str("init", 380752755, 4)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[ 9]) { /* code */ - 0x60040014, // 0000 GETGBL R1 G20 + 0x60040003, // 0000 GETGBL R1 G3 0x5C080000, // 0001 MOVE R2 R0 0xB80E0000, // 0002 GETNGBL R3 K0 0x7C040400, // 0003 CALL R1 2 diff --git a/lib/libesp32/Berry/default/be_i2c_driverlib.c b/lib/libesp32/Berry/default/be_i2c_driverlib.c index 88d9ded34..2ac5627d9 100644 --- a/lib/libesp32/Berry/default/be_i2c_driverlib.c +++ b/lib/libesp32/Berry/default/be_i2c_driverlib.c @@ -11,333 +11,6 @@ extern bclass* be_class_Driver; // Parent class -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(init, /* name */ - be_nested_proto( - 10, /* nstack */ - 4, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - be_nested_string("get_tasmota", 334356779, 11), - be_nested_string("i2c_enabled", 218388101, 11), - be_nested_string("addr", 1087856498, 4), - be_nested_string("wire", -212213352, 4), - be_nested_string("wire_scan", -1623691416, 9), - be_nested_string("function", -1630125495, 8), - be_nested_string("name", -1925595674, 4), - be_nested_string("I2C:", 813483371, 4), - be_nested_string("detected on bus", 1432002650, 15), - be_nested_string("bus", 1607822841, 3), - }), - (be_nested_const_str("init", 380752755, 4)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[44]) { /* code */ - 0x8C100100, // 0000 GETMET R4 R0 R256 - 0x7C100200, // 0001 CALL R4 1 - 0x4C140000, // 0002 LDNIL 5 - 0x20140605, // 0003 NE R5 R3 R5 - 0x78160004, // 0004 JMPF R5 #000A - 0x8C140901, // 0005 GETMET R5 R4 R257 - 0x5C1C0600, // 0006 MOVE R7 R3 - 0x7C140400, // 0007 CALL R5 2 - 0x74160000, // 0008 JMPT R5 #000A - 0x80000A00, // 0009 RET 0 R5 - 0x90020402, // 000A SETMBR R0 R258 R2 - 0x8C140904, // 000B GETMET R5 R4 R260 - 0x881C0102, // 000C GETMBR R7 R0 R258 - 0x7C140400, // 000D CALL R5 2 - 0x90020605, // 000E SETMBR R0 R259 R5 - 0x88140103, // 000F GETMBR R5 R0 R259 - 0x78160019, // 0010 JMPF R5 #002B - 0x60140015, // 0011 GETGBL R5 G21 - 0x5C180200, // 0012 MOVE R6 R1 - 0x7C140200, // 0013 CALL R5 1 - 0x1C140B05, // 0014 EQ R5 R5 R261 - 0x78160004, // 0015 JMPF R5 #001B - 0x5C140200, // 0016 MOVE R5 R1 - 0x5C180000, // 0017 MOVE R6 R0 - 0x7C140200, // 0018 CALL R5 1 - 0x90020C05, // 0019 SETMBR R0 R262 R5 - 0x70020000, // 001A JMP #001C - 0x90020C01, // 001B SETMBR R0 R262 R1 - 0x88140106, // 001C GETMBR R5 R0 R262 - 0x4C180000, // 001D LDNIL 6 - 0x1C140A06, // 001E EQ R5 R5 R6 - 0x78160001, // 001F JMPF R5 #0022 - 0x4C140000, // 0020 LDNIL 5 - 0x90020605, // 0021 SETMBR R0 R259 R5 - 0x88140103, // 0022 GETMBR R5 R0 R259 - 0x78160006, // 0023 JMPF R5 #002B - 0x6014000F, // 0024 GETGBL R5 G15 - 0x58180007, // 0025 LDCONST R6 K7 - 0x881C0106, // 0026 GETMBR R7 R0 R262 - 0x58200008, // 0027 LDCONST R8 K8 - 0x88240103, // 0028 GETMBR R9 R0 R259 - 0x88241309, // 0029 GETMBR R9 R9 R265 - 0x7C140800, // 002A CALL R5 4 - 0x80000000, // 002B RET 0 R0 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** -** Solidified function: write8 -********************************************************************/ -be_local_closure(write8, /* name */ - be_nested_proto( - 9, /* nstack */ - 3, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - be_nested_string("wire", -212213352, 4), - be_nested_string("write", -1104765092, 5), - be_nested_string("addr", 1087856498, 4), - be_const_int(1), - }), - (be_nested_const_str("write8", -1160975764, 6)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[ 8]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 R256 - 0x8C0C0701, // 0001 GETMET R3 R3 R257 - 0x88140102, // 0002 GETMBR R5 R0 R258 - 0x5C180200, // 0003 MOVE R6 R1 - 0x5C1C0400, // 0004 MOVE R7 R2 - 0x58200003, // 0005 LDCONST R8 K3 - 0x7C0C0A00, // 0006 CALL R3 5 - 0x80040600, // 0007 RET 1 R3 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** -** Solidified function: write_bit -********************************************************************/ -be_local_closure(write_bit, /* name */ - be_nested_proto( - 11, /* nstack */ - 4, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - be_const_int(0), - be_const_int(1), - be_nested_string("write8", -1160975764, 6), - be_nested_string("read8", -1492179129, 5), - }), - (be_nested_const_str("write_bit", -1633976860, 9)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[26]) { /* code */ - 0x14100500, // 0000 LT R4 R2 R256 - 0x74120002, // 0001 JMPT R4 #0005 - 0x54120006, // 0002 LDINT R4 7 - 0x24100404, // 0003 GT R4 R2 R4 - 0x78120000, // 0004 JMPF R4 #0006 - 0x80000800, // 0005 RET 0 R4 - 0x38120202, // 0006 SHL R4 R257 R2 - 0x780E0007, // 0007 JMPF R3 #0010 - 0x8C140102, // 0008 GETMET R5 R0 R258 - 0x5C1C0200, // 0009 MOVE R7 R1 - 0x8C200103, // 000A GETMET R8 R0 R259 - 0x5C280200, // 000B MOVE R10 R1 - 0x7C200400, // 000C CALL R8 2 - 0x30201004, // 000D OR R8 R8 R4 - 0x7C140600, // 000E CALL R5 3 - 0x70020008, // 000F JMP #0019 - 0x8C140102, // 0010 GETMET R5 R0 R258 - 0x5C1C0200, // 0011 MOVE R7 R1 - 0x8C200103, // 0012 GETMET R8 R0 R259 - 0x5C280200, // 0013 MOVE R10 R1 - 0x7C200400, // 0014 CALL R8 2 - 0x542600FE, // 0015 LDINT R9 255 - 0x04241204, // 0016 SUB R9 R9 R4 - 0x2C201009, // 0017 AND R8 R8 R9 - 0x7C140600, // 0018 CALL R5 3 - 0x80000000, // 0019 RET 0 R0 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** -** Solidified function: read8 -********************************************************************/ -be_local_closure(read8, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - be_nested_string("wire", -212213352, 4), - be_nested_string("read", -824204347, 4), - be_nested_string("addr", 1087856498, 4), - be_const_int(1), - }), - (be_nested_const_str("read8", -1492179129, 5)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[ 7]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 R256 - 0x8C080501, // 0001 GETMET R2 R2 R257 - 0x88100102, // 0002 GETMBR R4 R0 R258 - 0x5C140200, // 0003 MOVE R5 R1 - 0x58180003, // 0004 LDCONST R6 K3 - 0x7C080800, // 0005 CALL R2 4 - 0x80040400, // 0006 RET 1 R2 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** -** Solidified function: read12 -********************************************************************/ -be_local_closure(read12, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - be_nested_string("wire", -212213352, 4), - be_nested_string("read_bytes", -718234123, 10), - be_nested_string("addr", 1087856498, 4), - be_const_int(2), - be_const_int(0), - be_const_int(1), - }), - (be_nested_const_str("read12", -3890326, 6)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[12]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 R256 - 0x8C080501, // 0001 GETMET R2 R2 R257 - 0x88100102, // 0002 GETMBR R4 R0 R258 - 0x5C140200, // 0003 MOVE R5 R1 - 0x58180003, // 0004 LDCONST R6 K3 - 0x7C080800, // 0005 CALL R2 4 - 0x940C0504, // 0006 GETIDX R3 R2 R260 - 0x54120003, // 0007 LDINT R4 4 - 0x380C0604, // 0008 SHL R3 R3 R4 - 0x94100505, // 0009 GETIDX R4 R2 R261 - 0x000C0604, // 000A ADD R3 R3 R4 - 0x80040600, // 000B RET 1 R3 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** -** Solidified function: read13 -********************************************************************/ -be_local_closure(read13, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - be_nested_string("wire", -212213352, 4), - be_nested_string("read_bytes", -718234123, 10), - be_nested_string("addr", 1087856498, 4), - be_const_int(2), - be_const_int(0), - be_const_int(1), - }), - (be_nested_const_str("read13", 12887293, 6)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[12]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 R256 - 0x8C080501, // 0001 GETMET R2 R2 R257 - 0x88100102, // 0002 GETMBR R4 R0 R258 - 0x5C140200, // 0003 MOVE R5 R1 - 0x58180003, // 0004 LDCONST R6 K3 - 0x7C080800, // 0005 CALL R2 4 - 0x940C0504, // 0006 GETIDX R3 R2 R260 - 0x54120004, // 0007 LDINT R4 5 - 0x380C0604, // 0008 SHL R3 R3 R4 - 0x94100505, // 0009 GETIDX R4 R2 R261 - 0x000C0604, // 000A ADD R3 R3 R4 - 0x80040600, // 000B RET 1 R3 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** -** Solidified function: read24 -********************************************************************/ -be_local_closure(read24, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - be_nested_string("wire", -212213352, 4), - be_nested_string("read_bytes", -718234123, 10), - be_nested_string("addr", 1087856498, 4), - be_const_int(3), - be_const_int(0), - be_const_int(1), - be_const_int(2), - }), - (be_nested_const_str("read24", 1808533811, 6)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[16]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 R256 - 0x8C080501, // 0001 GETMET R2 R2 R257 - 0x88100102, // 0002 GETMBR R4 R0 R258 - 0x5C140200, // 0003 MOVE R5 R1 - 0x58180003, // 0004 LDCONST R6 K3 - 0x7C080800, // 0005 CALL R2 4 - 0x940C0504, // 0006 GETIDX R3 R2 R260 - 0x5412000F, // 0007 LDINT R4 16 - 0x380C0604, // 0008 SHL R3 R3 R4 - 0x94100505, // 0009 GETIDX R4 R2 R261 - 0x54160007, // 000A LDINT R5 8 - 0x38100805, // 000B SHL R4 R4 R5 - 0x000C0604, // 000C ADD R3 R3 R4 - 0x94100506, // 000D GETIDX R4 R2 R262 - 0x000C0604, // 000E ADD R3 R3 R4 - 0x80040600, // 000F RET 1 R3 - }) - ) -); -/*******************************************************************/ - /******************************************************************** ** Solidified function: read32 ********************************************************************/ @@ -352,35 +25,35 @@ be_local_closure(read32, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 7]) { /* constants */ - be_nested_string("wire", -212213352, 4), - be_nested_string("read_bytes", -718234123, 10), - be_nested_string("addr", 1087856498, 4), - be_const_int(0), - be_const_int(1), - be_const_int(2), - be_const_int(3), + /* K0 */ be_nested_string("wire", -212213352, 4), + /* K1 */ be_nested_string("read_bytes", -718234123, 10), + /* K2 */ be_nested_string("addr", 1087856498, 4), + /* K3 */ be_const_int(0), + /* K4 */ be_const_int(1), + /* K5 */ be_const_int(2), + /* K6 */ be_const_int(3), }), (be_nested_const_str("read32", 1741276240, 6)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[20]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 R256 - 0x8C080501, // 0001 GETMET R2 R2 R257 - 0x88100102, // 0002 GETMBR R4 R0 R258 + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x88100102, // 0002 GETMBR R4 R0 K2 0x5C140200, // 0003 MOVE R5 R1 0x541A0003, // 0004 LDINT R6 4 0x7C080800, // 0005 CALL R2 4 - 0x940C0503, // 0006 GETIDX R3 R2 R259 + 0x940C0503, // 0006 GETIDX R3 R2 K3 0x54120017, // 0007 LDINT R4 24 0x380C0604, // 0008 SHL R3 R3 R4 - 0x94100504, // 0009 GETIDX R4 R2 R260 + 0x94100504, // 0009 GETIDX R4 R2 K4 0x5416000F, // 000A LDINT R5 16 0x38100805, // 000B SHL R4 R4 R5 0x000C0604, // 000C ADD R3 R3 R4 - 0x94100505, // 000D GETIDX R4 R2 R261 + 0x94100505, // 000D GETIDX R4 R2 K5 0x54160007, // 000E LDINT R5 8 0x38100805, // 000F SHL R4 R4 R5 0x000C0604, // 0010 ADD R3 R3 R4 - 0x94100506, // 0011 GETIDX R4 R2 R262 + 0x94100506, // 0011 GETIDX R4 R2 K6 0x000C0604, // 0012 ADD R3 R3 R4 0x80040600, // 0013 RET 1 R3 }) @@ -389,6 +62,339 @@ be_local_closure(read32, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: write8 +********************************************************************/ +be_local_closure(write8, /* name */ + be_nested_proto( + 9, /* nstack */ + 3, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_string("wire", -212213352, 4), + /* K1 */ be_nested_string("write", -1104765092, 5), + /* K2 */ be_nested_string("addr", 1087856498, 4), + /* K3 */ be_const_int(1), + }), + (be_nested_const_str("write8", -1160975764, 6)), + (be_nested_const_str("input", -103256197, 5)), + ( &(const binstruction[ 8]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x8C0C0701, // 0001 GETMET R3 R3 K1 + 0x88140102, // 0002 GETMBR R5 R0 K2 + 0x5C180200, // 0003 MOVE R6 R1 + 0x5C1C0400, // 0004 MOVE R7 R2 + 0x58200003, // 0005 LDCONST R8 K3 + 0x7C0C0A00, // 0006 CALL R3 5 + 0x80040600, // 0007 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read12 +********************************************************************/ +be_local_closure(read12, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_string("wire", -212213352, 4), + /* K1 */ be_nested_string("read_bytes", -718234123, 10), + /* K2 */ be_nested_string("addr", 1087856498, 4), + /* K3 */ be_const_int(2), + /* K4 */ be_const_int(0), + /* K5 */ be_const_int(1), + }), + (be_nested_const_str("read12", -3890326, 6)), + (be_nested_const_str("input", -103256197, 5)), + ( &(const binstruction[12]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x88100102, // 0002 GETMBR R4 R0 K2 + 0x5C140200, // 0003 MOVE R5 R1 + 0x58180003, // 0004 LDCONST R6 K3 + 0x7C080800, // 0005 CALL R2 4 + 0x940C0504, // 0006 GETIDX R3 R2 K4 + 0x54120003, // 0007 LDINT R4 4 + 0x380C0604, // 0008 SHL R3 R3 R4 + 0x94100505, // 0009 GETIDX R4 R2 K5 + 0x000C0604, // 000A ADD R3 R3 R4 + 0x80040600, // 000B RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: write_bit +********************************************************************/ +be_local_closure(write_bit, /* name */ + be_nested_proto( + 11, /* nstack */ + 4, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_const_int(1), + /* K2 */ be_nested_string("write8", -1160975764, 6), + /* K3 */ be_nested_string("read8", -1492179129, 5), + }), + (be_nested_const_str("write_bit", -1633976860, 9)), + (be_nested_const_str("input", -103256197, 5)), + ( &(const binstruction[26]) { /* code */ + 0x14100500, // 0000 LT R4 R2 K0 + 0x74120002, // 0001 JMPT R4 #0005 + 0x54120006, // 0002 LDINT R4 7 + 0x24100404, // 0003 GT R4 R2 R4 + 0x78120000, // 0004 JMPF R4 #0006 + 0x80000800, // 0005 RET 0 + 0x38120202, // 0006 SHL R4 K1 R2 + 0x780E0007, // 0007 JMPF R3 #0010 + 0x8C140102, // 0008 GETMET R5 R0 K2 + 0x5C1C0200, // 0009 MOVE R7 R1 + 0x8C200103, // 000A GETMET R8 R0 K3 + 0x5C280200, // 000B MOVE R10 R1 + 0x7C200400, // 000C CALL R8 2 + 0x30201004, // 000D OR R8 R8 R4 + 0x7C140600, // 000E CALL R5 3 + 0x70020008, // 000F JMP #0019 + 0x8C140102, // 0010 GETMET R5 R0 K2 + 0x5C1C0200, // 0011 MOVE R7 R1 + 0x8C200103, // 0012 GETMET R8 R0 K3 + 0x5C280200, // 0013 MOVE R10 R1 + 0x7C200400, // 0014 CALL R8 2 + 0x542600FE, // 0015 LDINT R9 255 + 0x04241204, // 0016 SUB R9 R9 R4 + 0x2C201009, // 0017 AND R8 R8 R9 + 0x7C140600, // 0018 CALL R5 3 + 0x80000000, // 0019 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read24 +********************************************************************/ +be_local_closure(read24, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_string("wire", -212213352, 4), + /* K1 */ be_nested_string("read_bytes", -718234123, 10), + /* K2 */ be_nested_string("addr", 1087856498, 4), + /* K3 */ be_const_int(3), + /* K4 */ be_const_int(0), + /* K5 */ be_const_int(1), + /* K6 */ be_const_int(2), + }), + (be_nested_const_str("read24", 1808533811, 6)), + (be_nested_const_str("input", -103256197, 5)), + ( &(const binstruction[16]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x88100102, // 0002 GETMBR R4 R0 K2 + 0x5C140200, // 0003 MOVE R5 R1 + 0x58180003, // 0004 LDCONST R6 K3 + 0x7C080800, // 0005 CALL R2 4 + 0x940C0504, // 0006 GETIDX R3 R2 K4 + 0x5412000F, // 0007 LDINT R4 16 + 0x380C0604, // 0008 SHL R3 R3 R4 + 0x94100505, // 0009 GETIDX R4 R2 K5 + 0x54160007, // 000A LDINT R5 8 + 0x38100805, // 000B SHL R4 R4 R5 + 0x000C0604, // 000C ADD R3 R3 R4 + 0x94100506, // 000D GETIDX R4 R2 K6 + 0x000C0604, // 000E ADD R3 R3 R4 + 0x80040600, // 000F RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read8 +********************************************************************/ +be_local_closure(read8, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_string("wire", -212213352, 4), + /* K1 */ be_nested_string("read", -824204347, 4), + /* K2 */ be_nested_string("addr", 1087856498, 4), + /* K3 */ be_const_int(1), + }), + (be_nested_const_str("read8", -1492179129, 5)), + (be_nested_const_str("input", -103256197, 5)), + ( &(const binstruction[ 7]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x88100102, // 0002 GETMBR R4 R0 K2 + 0x5C140200, // 0003 MOVE R5 R1 + 0x58180003, // 0004 LDCONST R6 K3 + 0x7C080800, // 0005 CALL R2 4 + 0x80040400, // 0006 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(init, /* name */ + be_nested_proto( + 10, /* nstack */ + 4, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_string("get_tasmota", 334356779, 11), + /* K1 */ be_nested_string("i2c_enabled", 218388101, 11), + /* K2 */ be_nested_string("addr", 1087856498, 4), + /* K3 */ be_nested_string("wire", -212213352, 4), + /* K4 */ be_nested_string("wire_scan", -1623691416, 9), + /* K5 */ be_nested_string("function", -1630125495, 8), + /* K6 */ be_nested_string("name", -1925595674, 4), + /* K7 */ be_nested_string("I2C:", 813483371, 4), + /* K8 */ be_nested_string("detected on bus", 1432002650, 15), + /* K9 */ be_nested_string("bus", 1607822841, 3), + }), + (be_nested_const_str("init", 380752755, 4)), + (be_nested_const_str("input", -103256197, 5)), + ( &(const binstruction[44]) { /* code */ + 0x8C100100, // 0000 GETMET R4 R0 K0 + 0x7C100200, // 0001 CALL R4 1 + 0x4C140000, // 0002 LDNIL R5 + 0x20140605, // 0003 NE R5 R3 R5 + 0x78160004, // 0004 JMPF R5 #000A + 0x8C140901, // 0005 GETMET R5 R4 K1 + 0x5C1C0600, // 0006 MOVE R7 R3 + 0x7C140400, // 0007 CALL R5 2 + 0x74160000, // 0008 JMPT R5 #000A + 0x80000A00, // 0009 RET 0 + 0x90020402, // 000A SETMBR R0 K2 R2 + 0x8C140904, // 000B GETMET R5 R4 K4 + 0x881C0102, // 000C GETMBR R7 R0 K2 + 0x7C140400, // 000D CALL R5 2 + 0x90020605, // 000E SETMBR R0 K3 R5 + 0x88140103, // 000F GETMBR R5 R0 K3 + 0x78160019, // 0010 JMPF R5 #002B + 0x60140004, // 0011 GETGBL R5 G4 + 0x5C180200, // 0012 MOVE R6 R1 + 0x7C140200, // 0013 CALL R5 1 + 0x1C140B05, // 0014 EQ R5 R5 K5 + 0x78160004, // 0015 JMPF R5 #001B + 0x5C140200, // 0016 MOVE R5 R1 + 0x5C180000, // 0017 MOVE R6 R0 + 0x7C140200, // 0018 CALL R5 1 + 0x90020C05, // 0019 SETMBR R0 K6 R5 + 0x70020000, // 001A JMP #001C + 0x90020C01, // 001B SETMBR R0 K6 R1 + 0x88140106, // 001C GETMBR R5 R0 K6 + 0x4C180000, // 001D LDNIL R6 + 0x1C140A06, // 001E EQ R5 R5 R6 + 0x78160001, // 001F JMPF R5 #0022 + 0x4C140000, // 0020 LDNIL R5 + 0x90020605, // 0021 SETMBR R0 K3 R5 + 0x88140103, // 0022 GETMBR R5 R0 K3 + 0x78160006, // 0023 JMPF R5 #002B + 0x60140001, // 0024 GETGBL R5 G1 + 0x58180007, // 0025 LDCONST R6 K7 + 0x881C0106, // 0026 GETMBR R7 R0 K6 + 0x58200008, // 0027 LDCONST R8 K8 + 0x88240103, // 0028 GETMBR R9 R0 K3 + 0x88241309, // 0029 GETMBR R9 R9 K9 + 0x7C140800, // 002A CALL R5 4 + 0x80000000, // 002B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: read13 +********************************************************************/ +be_local_closure(read13, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_string("wire", -212213352, 4), + /* K1 */ be_nested_string("read_bytes", -718234123, 10), + /* K2 */ be_nested_string("addr", 1087856498, 4), + /* K3 */ be_const_int(2), + /* K4 */ be_const_int(0), + /* K5 */ be_const_int(1), + }), + (be_nested_const_str("read13", 12887293, 6)), + (be_nested_const_str("input", -103256197, 5)), + ( &(const binstruction[12]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x88100102, // 0002 GETMBR R4 R0 K2 + 0x5C140200, // 0003 MOVE R5 R1 + 0x58180003, // 0004 LDCONST R6 K3 + 0x7C080800, // 0005 CALL R2 4 + 0x940C0504, // 0006 GETIDX R3 R2 K4 + 0x54120004, // 0007 LDINT R4 5 + 0x380C0604, // 0008 SHL R3 R3 R4 + 0x94100505, // 0009 GETIDX R4 R2 K5 + 0x000C0604, // 000A ADD R3 R3 R4 + 0x80040600, // 000B RET 1 R3 + }) + ) +); +/*******************************************************************/ + #include "../generate/be_fixed_be_class_I2C_Driver.h" void be_load_driver_i2c_lib(bvm *vm) { diff --git a/lib/libesp32/Berry/default/be_i2s_audio_lib.c b/lib/libesp32/Berry/default/be_i2s_audio_lib.c index 888cb2d42..ef8720b23 100644 --- a/lib/libesp32/Berry/default/be_i2s_audio_lib.c +++ b/lib/libesp32/Berry/default/be_i2s_audio_lib.c @@ -32,7 +32,6 @@ extern int i2s_file_source_fs_deinit(bvm *vm); #endif // USE_UFILESYS -#if BE_USE_PRECOMPILED_OBJECT #include "../generate/be_fixed_be_class_audio_output.h" #include "../generate/be_fixed_be_class_audio_output_i2s.h" #include "../generate/be_fixed_be_class_audio_generator.h" @@ -40,7 +39,6 @@ extern int i2s_file_source_fs_deinit(bvm *vm); #include "../generate/be_fixed_be_class_audio_generator_mp3.h" #include "../generate/be_fixed_be_class_audio_file_source.h" #include "../generate/be_fixed_be_class_audio_file_source_fs.h" -#endif void be_load_driver_audio_lib(bvm *vm) { be_pushntvclass(vm, &be_class_audio_output); diff --git a/lib/libesp32/Berry/default/be_light_lib.c b/lib/libesp32/Berry/default/be_light_lib.c index a536fd6df..6d020eca8 100644 --- a/lib/libesp32/Berry/default/be_light_lib.c +++ b/lib/libesp32/Berry/default/be_light_lib.c @@ -13,22 +13,6 @@ extern int l_gamma8(bvm *vm); extern int l_gamma10(bvm *vm); extern int l_rev_gamma10(bvm *vm); -#if !BE_USE_PRECOMPILED_OBJECT - -be_native_module_attr_table(light) { - - be_native_module_function("get", l_getlight), - be_native_module_function("set", l_setlight), - - be_native_module_function("gamma8", l_gamma8), - be_native_module_function("gamma10", l_gamma10), - be_native_module_function("reverse_gamma10", l_rev_gamma10), - -}; - -be_define_native_module(light, NULL); - -#else /* @const_object_info_begin module light (scope: global) { get, func(l_getlight) @@ -40,6 +24,5 @@ module light (scope: global) { } @const_object_info_end */ #include "../generate/be_fixed_light.h" -#endif #endif // USE_LIGHT \ No newline at end of file diff --git a/lib/libesp32/Berry/default/be_lvgl_cb.c b/lib/libesp32/Berry/default/be_lvgl_cb.c index 01c5e8d76..f226b2679 100644 --- a/lib/libesp32/Berry/default/be_lvgl_cb.c +++ b/lib/libesp32/Berry/default/be_lvgl_cb.c @@ -102,94 +102,32 @@ class be_lvgl_cb (scope: global, name: lv_cb) { // 'lv_gauge_format_cb' // -#if BE_USE_PRECOMPILED_OBJECT #include "../generate/be_fixed_be_lv_group_focus_cb.h" #include "../generate/be_fixed_be_lv_event_cb.h" #include "../generate/be_fixed_be_lv_signal_cb.h" #include "../generate/be_fixed_be_lv_design_cb.h" #include "../generate/be_fixed_be_lv_gauge_format_cb.h" -#endif void be_load_lvgl_cb_all_lib(bvm *vm) { -#if !BE_USE_PRECOMPILED_OBJECT - static const bnfuncinfo members_lv_group_focus_cb[] = { - { "()", lv_group_focus_cb_call }, - { NULL, NULL } - }; - be_regclass(vm, "lv_group_focus_cb", members); - be_getglobal(vm, "lv_group_focus_cb"); - be_getglobal(vm, "lv_cb"); - be_setsuper(vm, -2); - be_pop(vm, 2); -#else be_pushntvclass(vm, &be_lv_group_focus_cb); be_setglobal(vm, "lv_group_focus_cb"); be_pop(vm, 1); -#endif -#if !BE_USE_PRECOMPILED_OBJECT - static const bnfuncinfo members_lv_event_cb[] = { - { "()", lv_event_cb_call }, - { NULL, NULL } - }; - be_regclass(vm, "lv_event_cb", members); - be_getglobal(vm, "lv_event_cb"); - be_getglobal(vm, "lv_cb"); - be_setsuper(vm, -2); - be_pop(vm, 2); -#else be_pushntvclass(vm, &be_lv_event_cb); be_setglobal(vm, "lv_event_cb"); be_pop(vm, 1); -#endif - -#if !BE_USE_PRECOMPILED_OBJECT - static const bnfuncinfo members_lv_signal_cb[] = { - { "()", lv_signal_cb_call }, - { NULL, NULL } - }; - be_regclass(vm, "lv_signal_cb", members); - be_getglobal(vm, "lv_signal_cb"); - be_getglobal(vm, "lv_cb"); - be_setsuper(vm, -2); - be_pop(vm, 2); -#else + be_pushntvclass(vm, &be_lv_signal_cb); be_setglobal(vm, "lv_signal_cb"); be_pop(vm, 1); -#endif -#if !BE_USE_PRECOMPILED_OBJECT - static const bnfuncinfo members_lv_design_cb[] = { - { "()", lv_design_cb_call }, - { NULL, NULL } - }; - be_regclass(vm, "lv_design_cb", members); - be_getglobal(vm, "lv_design_cb"); - be_getglobal(vm, "lv_cb"); - be_setsuper(vm, -2); - be_pop(vm, 2); -#else be_pushntvclass(vm, &be_lv_design_cb); be_setglobal(vm, "lv_design_cb"); be_pop(vm, 1); -#endif -#if !BE_USE_PRECOMPILED_OBJECT - static const bnfuncinfo members_lv_gauge_format_cb[] = { - { "()", lv_gauge_format_cb_call }, - { NULL, NULL } - }; - be_regclass(vm, "lv_gauge_format_cb", members); - be_getglobal(vm, "lv_gauge_format_cb"); - be_getglobal(vm, "lv_cb"); - be_setsuper(vm, -2); - be_pop(vm, 2); -#else be_pushntvclass(vm, &be_lv_gauge_format_cb); be_setglobal(vm, "lv_gauge_format_cb"); be_pop(vm, 1); -#endif } /* @const_object_info_begin diff --git a/lib/libesp32/Berry/default/be_lvgl_clock_icon_lib.c b/lib/libesp32/Berry/default/be_lvgl_clock_icon_lib.c index 888456745..1969e6172 100644 --- a/lib/libesp32/Berry/default/be_lvgl_clock_icon_lib.c +++ b/lib/libesp32/Berry/default/be_lvgl_clock_icon_lib.c @@ -157,7 +157,7 @@ be_local_closure(init, /* name */ (be_nested_const_str("init", 380752755, 4)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[76]) { /* code */ - 0x600C0014, // 0000 GETGBL R3 G20 + 0x600C0003, // 0000 GETGBL R3 G3 0x5C100000, // 0001 MOVE R4 R0 0x7C0C0200, // 0002 CALL R3 1 0x8C0C0700, // 0003 GETMET R3 R3 K0 @@ -260,7 +260,7 @@ be_local_closure(del, /* name */ (be_nested_const_str("del", -816214454, 3)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[10]) { /* code */ - 0x60040014, // 0000 GETGBL R1 G20 + 0x60040003, // 0000 GETGBL R1 G3 0x5C080000, // 0001 MOVE R2 R0 0x7C040200, // 0002 CALL R1 1 0x8C040300, // 0003 GETMET R1 R1 K0 diff --git a/lib/libesp32/Berry/default/be_lvgl_color_lib.c b/lib/libesp32/Berry/default/be_lvgl_color_lib.c index 27eabbbd1..ebc53821d 100644 --- a/lib/libesp32/Berry/default/be_lvgl_color_lib.c +++ b/lib/libesp32/Berry/default/be_lvgl_color_lib.c @@ -12,28 +12,12 @@ extern int lco_tostring(bvm *vm); // generic function extern int lco_toint(bvm *vm); // generic function -#if BE_USE_PRECOMPILED_OBJECT #include "../generate/be_fixed_be_class_lv_color.h" -#endif void be_load_lvgl_color_lib(bvm *vm) { -#if !BE_USE_PRECOMPILED_OBJECT - static const bnfuncinfo members[] = { - { ".p", NULL }, // keeping track of styles to avoid GC - { "init", lco_init }, - { "tostring", lco_tostring }, - { "toint", lco_toint }, - - // { NULL, (bntvfunc) BE_CLOSURE }, /* mark section for berry closures */ - - { NULL, NULL } - }; - be_regclass(vm, "lv_color", members); -#else be_pushntvclass(vm, &be_class_lv_color); be_setglobal(vm, "lv_color"); be_pop(vm, 1); -#endif } /* @const_object_info_begin diff --git a/lib/libesp32/Berry/default/be_lvgl_ctypes_definitions.c b/lib/libesp32/Berry/default/be_lvgl_ctypes_definitions.c index e40f4edde..6492336bc 100644 --- a/lib/libesp32/Berry/default/be_lvgl_ctypes_definitions.c +++ b/lib/libesp32/Berry/default/be_lvgl_ctypes_definitions.c @@ -42,6 +42,7 @@ typedef struct be_ctypes_structure_item_t { typedef struct be_ctypes_structure_t { uint16_t size_bytes; /* size in bytes */ uint16_t size_elt; /* number of elements */ + const char **instance_mapping; /* array of instance class names for automatic instanciation of class */ const be_ctypes_structure_item_t * items; } be_ctypes_structure_t; @@ -56,7 +57,7 @@ typedef struct be_ctypes_classes_t { const be_ctypes_class_t * classes; } be_ctypes_classes_t; -BE_EXPORT_VARIABLE extern const bclass be_class_lv_ctypes; +BE_EXPORT_VARIABLE extern const bclass be_class_ctypes; void ctypes_register_class(bvm *vm, const bclass * ctypes_class, const be_ctypes_structure_t * definitions) { be_pushntvclass(vm, ctypes_class); @@ -64,10 +65,26 @@ void ctypes_register_class(bvm *vm, const bclass * ctypes_class, const be_ctypes be_pop(vm, 1); } +const char * be_ctypes_instance_mappings[]; /* forward definition */ + +// Define a sub-class of ctypes with only one member which points to the ctypes defintion +#define be_define_ctypes_class(_c_name, _def, _super, _name) \ + be_local_class(_c_name, \ + 0, \ + _super, \ + be_nested_map(1, \ + ( (struct bmapnode*) &(const bmapnode[]) { \ + { be_nested_key("_def", 1985022181, 4, -1), be_const_comptr(_def) },\ + })), \ + (be_nested_const_str(_name, 0, sizeof(_name)-1)) \ + ) + /********************************************************************/ + const be_ctypes_structure_t be_lv_point = { 4, /* size in bytes */ 2, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[2]) { { "x", 0, 0, 0, 12, 0 }, { "y", 2, 0, 0, 12, 0 }, @@ -76,6 +93,7 @@ const be_ctypes_structure_t be_lv_point = { const be_ctypes_structure_t be_lv_area = { 8, /* size in bytes */ 4, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[4]) { { "x1", 0, 0, 0, 12, 0 }, { "x2", 4, 0, 0, 12, 0 }, @@ -86,6 +104,7 @@ const be_ctypes_structure_t be_lv_area = { const be_ctypes_structure_t be_lv_draw_rect_dsc = { 77, /* size in bytes */ 43, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[43]) { { "bg_blend_mode", 12, 0, 0, 1, 0 }, { "bg_color", 2, 0, 0, 2, 1 }, @@ -135,6 +154,7 @@ const be_ctypes_structure_t be_lv_draw_rect_dsc = { const be_ctypes_structure_t be_lv_draw_line_dsc = { 10, /* size in bytes */ 9, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[9]) { { "blend_mode", 9, 0, 2, 0, 0 }, { "color", 0, 0, 0, 2, 1 }, @@ -150,6 +170,7 @@ const be_ctypes_structure_t be_lv_draw_line_dsc = { const be_ctypes_structure_t be_lv_draw_img_dsc = { 14, /* size in bytes */ 9, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[9]) { { "angle", 1, 0, 0, 2, 0 }, { "antialias", 13, 0, 1, 0, 0 }, @@ -165,6 +186,7 @@ const be_ctypes_structure_t be_lv_draw_img_dsc = { const be_ctypes_structure_t be_lv_draw_label_dsc = { 31, /* size in bytes */ 15, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[15]) { { "bidi_dir", 27, 0, 0, 1, 0 }, { "blend_mode", 30, 0, 0, 1, 0 }, @@ -186,6 +208,7 @@ const be_ctypes_structure_t be_lv_draw_label_dsc = { const be_ctypes_structure_t be_lv_draw_mask_common_dsc = { 5, /* size in bytes */ 2, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[2]) { { "cb", 0, 0, 0, 4, 0 }, { "type", 4, 0, 0, 1, 0 }, @@ -194,6 +217,7 @@ const be_ctypes_structure_t be_lv_draw_mask_common_dsc = { const be_ctypes_structure_t be_lv_draw_mask_line_param_cfg = { 9, /* size in bytes */ 5, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[5]) { { "p1_x", 0, 0, 0, 12, 0 }, { "p1_y", 2, 0, 0, 12, 0 }, @@ -205,6 +229,7 @@ const be_ctypes_structure_t be_lv_draw_mask_line_param_cfg = { const be_ctypes_structure_t be_lv_draw_mask_line_param = { 35, /* size in bytes */ 15, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[15]) { { "cfg_p1_x", 5, 0, 0, 12, 0 }, { "cfg_p1_y", 7, 0, 0, 12, 0 }, @@ -226,6 +251,7 @@ const be_ctypes_structure_t be_lv_draw_mask_line_param = { const be_ctypes_structure_t be_lv_draw_mask_angle_param_cfg = { 8, /* size in bytes */ 4, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[4]) { { "end_angle", 6, 0, 0, 12, 0 }, { "start_angle", 4, 0, 0, 12, 0 }, @@ -236,6 +262,7 @@ const be_ctypes_structure_t be_lv_draw_mask_angle_param_cfg = { const be_ctypes_structure_t be_lv_draw_mask_angle_param = { 85, /* size in bytes */ 37, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[37]) { { "cfg_end_angle", 11, 0, 0, 12, 0 }, { "cfg_start_angle", 9, 0, 0, 12, 0 }, @@ -279,6 +306,7 @@ const be_ctypes_structure_t be_lv_draw_mask_angle_param = { const be_ctypes_structure_t be_lv_draw_mask_radius_param_cfg = { 11, /* size in bytes */ 6, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[6]) { { "outer", 10, 0, 1, 0, 0 }, { "radius", 8, 0, 0, 12, 0 }, @@ -291,6 +319,7 @@ const be_ctypes_structure_t be_lv_draw_mask_radius_param_cfg = { const be_ctypes_structure_t be_lv_sqrt_res = { 4, /* size in bytes */ 2, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[2]) { { "f", 2, 0, 0, 2, 0 }, { "i", 0, 0, 0, 2, 0 }, @@ -299,6 +328,7 @@ const be_ctypes_structure_t be_lv_sqrt_res = { const be_ctypes_structure_t be_lv_draw_mask_radius_param = { 24, /* size in bytes */ 11, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[11]) { { "cfg_outer", 15, 0, 1, 0, 0 }, { "cfg_radius", 13, 0, 0, 12, 0 }, @@ -316,6 +346,7 @@ const be_ctypes_structure_t be_lv_draw_mask_radius_param = { const be_ctypes_structure_t be_lv_draw_mask_fade_param_cfg = { 14, /* size in bytes */ 8, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[8]) { { "coords_x1", 0, 0, 0, 12, 0 }, { "coords_x2", 4, 0, 0, 12, 0 }, @@ -330,6 +361,7 @@ const be_ctypes_structure_t be_lv_draw_mask_fade_param_cfg = { const be_ctypes_structure_t be_lv_draw_mask_fade_param = { 19, /* size in bytes */ 10, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[10]) { { "cfg_coords_x1", 5, 0, 0, 12, 0 }, { "cfg_coords_x2", 9, 0, 0, 12, 0 }, @@ -346,6 +378,7 @@ const be_ctypes_structure_t be_lv_draw_mask_fade_param = { const be_ctypes_structure_t be_lv_draw_mask_map_param_cfg = { 12, /* size in bytes */ 5, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[5]) { { "coords_x1", 0, 0, 0, 12, 0 }, { "coords_x2", 4, 0, 0, 12, 0 }, @@ -357,6 +390,7 @@ const be_ctypes_structure_t be_lv_draw_mask_map_param_cfg = { const be_ctypes_structure_t be_lv_draw_mask_map_param = { 17, /* size in bytes */ 7, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[7]) { { "cfg_coords_x1", 5, 0, 0, 12, 0 }, { "cfg_coords_x2", 9, 0, 0, 12, 0 }, @@ -370,6 +404,7 @@ const be_ctypes_structure_t be_lv_draw_mask_map_param = { const be_ctypes_structure_t be_lv_draw_mask_saved = { 8, /* size in bytes */ 2, /* number of elements */ + be_ctypes_instance_mappings, (const be_ctypes_structure_item_t[2]) { { "custom_id", 4, 0, 0, 4, 0 }, { "param", 0, 0, 0, 4, 0 }, @@ -380,97 +415,45 @@ const char * be_ctypes_instance_mappings[] = { NULL }; -const be_ctypes_classes_t be_ctypes_classes[] = { - 19, - be_ctypes_instance_mappings, - (const be_ctypes_class_t[19]) { - { "lv_area", &be_lv_area }, - { "lv_draw_img_dsc", &be_lv_draw_img_dsc }, - { "lv_draw_label_dsc", &be_lv_draw_label_dsc }, - { "lv_draw_line_dsc", &be_lv_draw_line_dsc }, - { "lv_draw_mask_angle_param", &be_lv_draw_mask_angle_param }, - { "lv_draw_mask_angle_param_cfg", &be_lv_draw_mask_angle_param_cfg }, - { "lv_draw_mask_common_dsc", &be_lv_draw_mask_common_dsc }, - { "lv_draw_mask_fade_param", &be_lv_draw_mask_fade_param }, - { "lv_draw_mask_fade_param_cfg", &be_lv_draw_mask_fade_param_cfg }, - { "lv_draw_mask_line_param", &be_lv_draw_mask_line_param }, - { "lv_draw_mask_line_param_cfg", &be_lv_draw_mask_line_param_cfg }, - { "lv_draw_mask_map_param", &be_lv_draw_mask_map_param }, - { "lv_draw_mask_map_param_cfg", &be_lv_draw_mask_map_param_cfg }, - { "lv_draw_mask_radius_param", &be_lv_draw_mask_radius_param }, - { "lv_draw_mask_radius_param_cfg", &be_lv_draw_mask_radius_param_cfg }, - { "lv_draw_mask_saved", &be_lv_draw_mask_saved }, - { "lv_draw_rect_dsc", &be_lv_draw_rect_dsc }, - { "lv_point", &be_lv_point }, - { "lv_sqrt_res", &be_lv_sqrt_res }, -}}; - -/* @const_object_info_begin -class be_class_ctypes_classes (scope: global) { - lv_area, int(0) - lv_draw_img_dsc, int(0) - lv_draw_label_dsc, int(0) - lv_draw_line_dsc, int(0) - lv_draw_mask_angle_param, int(0) - lv_draw_mask_angle_param_cfg, int(0) - lv_draw_mask_common_dsc, int(0) - lv_draw_mask_fade_param, int(0) - lv_draw_mask_fade_param_cfg, int(0) - lv_draw_mask_line_param, int(0) - lv_draw_mask_line_param_cfg, int(0) - lv_draw_mask_map_param, int(0) - lv_draw_mask_map_param_cfg, int(0) - lv_draw_mask_radius_param, int(0) - lv_draw_mask_radius_param_cfg, int(0) - lv_draw_mask_saved, int(0) - lv_draw_rect_dsc, int(0) - lv_point, int(0) - lv_sqrt_res, int(0) -} -@const_object_info_end */ +static be_define_ctypes_class(lv_area, &be_lv_area, &be_class_ctypes, "lv_area"); +static be_define_ctypes_class(lv_draw_img_dsc, &be_lv_draw_img_dsc, &be_class_ctypes, "lv_draw_img_dsc"); +static be_define_ctypes_class(lv_draw_label_dsc, &be_lv_draw_label_dsc, &be_class_ctypes, "lv_draw_label_dsc"); +static be_define_ctypes_class(lv_draw_line_dsc, &be_lv_draw_line_dsc, &be_class_ctypes, "lv_draw_line_dsc"); +static be_define_ctypes_class(lv_draw_mask_angle_param, &be_lv_draw_mask_angle_param, &be_class_ctypes, "lv_draw_mask_angle_param"); +static be_define_ctypes_class(lv_draw_mask_angle_param_cfg, &be_lv_draw_mask_angle_param_cfg, &be_class_ctypes, "lv_draw_mask_angle_param_cfg"); +static be_define_ctypes_class(lv_draw_mask_common_dsc, &be_lv_draw_mask_common_dsc, &be_class_ctypes, "lv_draw_mask_common_dsc"); +static be_define_ctypes_class(lv_draw_mask_fade_param, &be_lv_draw_mask_fade_param, &be_class_ctypes, "lv_draw_mask_fade_param"); +static be_define_ctypes_class(lv_draw_mask_fade_param_cfg, &be_lv_draw_mask_fade_param_cfg, &be_class_ctypes, "lv_draw_mask_fade_param_cfg"); +static be_define_ctypes_class(lv_draw_mask_line_param, &be_lv_draw_mask_line_param, &be_class_ctypes, "lv_draw_mask_line_param"); +static be_define_ctypes_class(lv_draw_mask_line_param_cfg, &be_lv_draw_mask_line_param_cfg, &be_class_ctypes, "lv_draw_mask_line_param_cfg"); +static be_define_ctypes_class(lv_draw_mask_map_param, &be_lv_draw_mask_map_param, &be_class_ctypes, "lv_draw_mask_map_param"); +static be_define_ctypes_class(lv_draw_mask_map_param_cfg, &be_lv_draw_mask_map_param_cfg, &be_class_ctypes, "lv_draw_mask_map_param_cfg"); +static be_define_ctypes_class(lv_draw_mask_radius_param, &be_lv_draw_mask_radius_param, &be_class_ctypes, "lv_draw_mask_radius_param"); +static be_define_ctypes_class(lv_draw_mask_radius_param_cfg, &be_lv_draw_mask_radius_param_cfg, &be_class_ctypes, "lv_draw_mask_radius_param_cfg"); +static be_define_ctypes_class(lv_draw_mask_saved, &be_lv_draw_mask_saved, &be_class_ctypes, "lv_draw_mask_saved"); +static be_define_ctypes_class(lv_draw_rect_dsc, &be_lv_draw_rect_dsc, &be_class_ctypes, "lv_draw_rect_dsc"); +static be_define_ctypes_class(lv_point, &be_lv_point, &be_class_ctypes, "lv_point"); +static be_define_ctypes_class(lv_sqrt_res, &be_lv_sqrt_res, &be_class_ctypes, "lv_sqrt_res"); void be_load_ctypes_definitions_lib(bvm *vm) { - be_pushcomptr(vm, (void*) be_ctypes_classes); - be_setglobal(vm, ".ctypes_classes"); - be_pop(vm, 1); - - static be_define_const_empty_class(be_class_lv_area, &be_class_lv_ctypes, lv_area); ctypes_register_class(vm, &be_class_lv_area, &be_lv_area); - static be_define_const_empty_class(be_class_lv_draw_img_dsc, &be_class_lv_ctypes, lv_draw_img_dsc); ctypes_register_class(vm, &be_class_lv_draw_img_dsc, &be_lv_draw_img_dsc); - static be_define_const_empty_class(be_class_lv_draw_label_dsc, &be_class_lv_ctypes, lv_draw_label_dsc); ctypes_register_class(vm, &be_class_lv_draw_label_dsc, &be_lv_draw_label_dsc); - static be_define_const_empty_class(be_class_lv_draw_line_dsc, &be_class_lv_ctypes, lv_draw_line_dsc); ctypes_register_class(vm, &be_class_lv_draw_line_dsc, &be_lv_draw_line_dsc); - static be_define_const_empty_class(be_class_lv_draw_mask_angle_param, &be_class_lv_ctypes, lv_draw_mask_angle_param); ctypes_register_class(vm, &be_class_lv_draw_mask_angle_param, &be_lv_draw_mask_angle_param); - static be_define_const_empty_class(be_class_lv_draw_mask_angle_param_cfg, &be_class_lv_ctypes, lv_draw_mask_angle_param_cfg); ctypes_register_class(vm, &be_class_lv_draw_mask_angle_param_cfg, &be_lv_draw_mask_angle_param_cfg); - static be_define_const_empty_class(be_class_lv_draw_mask_common_dsc, &be_class_lv_ctypes, lv_draw_mask_common_dsc); ctypes_register_class(vm, &be_class_lv_draw_mask_common_dsc, &be_lv_draw_mask_common_dsc); - static be_define_const_empty_class(be_class_lv_draw_mask_fade_param, &be_class_lv_ctypes, lv_draw_mask_fade_param); ctypes_register_class(vm, &be_class_lv_draw_mask_fade_param, &be_lv_draw_mask_fade_param); - static be_define_const_empty_class(be_class_lv_draw_mask_fade_param_cfg, &be_class_lv_ctypes, lv_draw_mask_fade_param_cfg); ctypes_register_class(vm, &be_class_lv_draw_mask_fade_param_cfg, &be_lv_draw_mask_fade_param_cfg); - static be_define_const_empty_class(be_class_lv_draw_mask_line_param, &be_class_lv_ctypes, lv_draw_mask_line_param); ctypes_register_class(vm, &be_class_lv_draw_mask_line_param, &be_lv_draw_mask_line_param); - static be_define_const_empty_class(be_class_lv_draw_mask_line_param_cfg, &be_class_lv_ctypes, lv_draw_mask_line_param_cfg); ctypes_register_class(vm, &be_class_lv_draw_mask_line_param_cfg, &be_lv_draw_mask_line_param_cfg); - static be_define_const_empty_class(be_class_lv_draw_mask_map_param, &be_class_lv_ctypes, lv_draw_mask_map_param); ctypes_register_class(vm, &be_class_lv_draw_mask_map_param, &be_lv_draw_mask_map_param); - static be_define_const_empty_class(be_class_lv_draw_mask_map_param_cfg, &be_class_lv_ctypes, lv_draw_mask_map_param_cfg); ctypes_register_class(vm, &be_class_lv_draw_mask_map_param_cfg, &be_lv_draw_mask_map_param_cfg); - static be_define_const_empty_class(be_class_lv_draw_mask_radius_param, &be_class_lv_ctypes, lv_draw_mask_radius_param); ctypes_register_class(vm, &be_class_lv_draw_mask_radius_param, &be_lv_draw_mask_radius_param); - static be_define_const_empty_class(be_class_lv_draw_mask_radius_param_cfg, &be_class_lv_ctypes, lv_draw_mask_radius_param_cfg); ctypes_register_class(vm, &be_class_lv_draw_mask_radius_param_cfg, &be_lv_draw_mask_radius_param_cfg); - static be_define_const_empty_class(be_class_lv_draw_mask_saved, &be_class_lv_ctypes, lv_draw_mask_saved); ctypes_register_class(vm, &be_class_lv_draw_mask_saved, &be_lv_draw_mask_saved); - static be_define_const_empty_class(be_class_lv_draw_rect_dsc, &be_class_lv_ctypes, lv_draw_rect_dsc); ctypes_register_class(vm, &be_class_lv_draw_rect_dsc, &be_lv_draw_rect_dsc); - static be_define_const_empty_class(be_class_lv_point, &be_class_lv_ctypes, lv_point); ctypes_register_class(vm, &be_class_lv_point, &be_lv_point); - static be_define_const_empty_class(be_class_lv_sqrt_res, &be_class_lv_ctypes, lv_sqrt_res); ctypes_register_class(vm, &be_class_lv_sqrt_res, &be_lv_sqrt_res); } /********************************************************************/ diff --git a/lib/libesp32/Berry/default/be_lvgl_font_lib.c b/lib/libesp32/Berry/default/be_lvgl_font_lib.c index 0bf03c3f9..115f5c2c6 100644 --- a/lib/libesp32/Berry/default/be_lvgl_font_lib.c +++ b/lib/libesp32/Berry/default/be_lvgl_font_lib.c @@ -10,27 +10,12 @@ extern int lvx_init(bvm *vm); // generic function extern int lvx_tostring(bvm *vm); // generic function -#if BE_USE_PRECOMPILED_OBJECT #include "../generate/be_fixed_be_class_lv_font.h" -#endif void be_load_lvgl_font_lib(bvm *vm) { -#if !BE_USE_PRECOMPILED_OBJECT - static const bnfuncinfo members[] = { - { ".p", NULL }, // keeping track of styles to avoid GC - { "init", lvx_init }, - { "tostring", lvx_tostring }, - - // { NULL, (bntvfunc) BE_CLOSURE }, /* mark section for berry closures */ - - { NULL, NULL } - }; - be_regclass(vm, "lv_font", members); -#else be_pushntvclass(vm, &be_class_lv_font); be_setglobal(vm, "lv_font"); be_pop(vm, 1); -#endif } /* @const_object_info_begin diff --git a/lib/libesp32/Berry/default/be_lvgl_signal_arcs_lib.c b/lib/libesp32/Berry/default/be_lvgl_signal_arcs_lib.c index e33b5c205..0ff6d9951 100644 --- a/lib/libesp32/Berry/default/be_lvgl_signal_arcs_lib.c +++ b/lib/libesp32/Berry/default/be_lvgl_signal_arcs_lib.c @@ -157,14 +157,14 @@ be_local_closure(my_design_cb, /* name */ 0x04380A08, // 0046 SUB R14 R5 R8 0x0C3C0D03, // 0047 DIV R15 R6 K3 0x043C1E09, // 0048 SUB R15 R15 R9 - 0x60400007, // 0049 GETGBL R16 G7 + 0x60400009, // 0049 GETGBL R16 G9 0x54460059, // 004A LDINT R17 90 0x8C480719, // 004B GETMET R18 R3 K25 0x8C50071A, // 004C GETMET R20 R3 K26 - 0x60580011, // 004D GETGBL R22 G17 + 0x6058000A, // 004D GETGBL R22 G10 0x5C5C1E00, // 004E MOVE R23 R15 0x7C580200, // 004F CALL R22 1 - 0x605C0011, // 0050 GETGBL R23 G17 + 0x605C000A, // 0050 GETGBL R23 G10 0x5C601C00, // 0051 MOVE R24 R14 0x7C5C0200, // 0052 CALL R23 1 0x0C582C17, // 0053 DIV R22 R22 R23 @@ -327,7 +327,7 @@ be_local_closure(init, /* name */ (be_nested_const_str("init", 380752755, 4)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[28]) { /* code */ - 0x600C0014, // 0000 GETGBL R3 G20 + 0x600C0003, // 0000 GETGBL R3 G3 0x5C100000, // 0001 MOVE R4 R0 0x7C0C0200, // 0002 CALL R3 1 0x8C0C0700, // 0003 GETMET R3 R3 K0 diff --git a/lib/libesp32/Berry/default/be_lvgl_signal_bars_lib.c b/lib/libesp32/Berry/default/be_lvgl_signal_bars_lib.c index 4c3e09bda..56f88987e 100644 --- a/lib/libesp32/Berry/default/be_lvgl_signal_bars_lib.c +++ b/lib/libesp32/Berry/default/be_lvgl_signal_bars_lib.c @@ -149,7 +149,7 @@ be_local_closure(my_design_cb, /* name */ 0xB83E0800, // 003F GETNGBL R15 K4 0x883C1F16, // 0040 GETMBR R15 R15 K22 0x7C300600, // 0041 CALL R12 3 - 0x60340000, // 0042 GETGBL R13 G0 + 0x60340010, // 0042 GETGBL R13 G16 0x403A3102, // 0043 CONNECT R14 K24 K2 0x7C340200, // 0044 CALL R13 1 0xA802002C, // 0045 EXBLK 0 #0073 @@ -268,7 +268,7 @@ be_local_closure(init, /* name */ (be_nested_const_str("init", 380752755, 4)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[28]) { /* code */ - 0x600C0014, // 0000 GETGBL R3 G20 + 0x600C0003, // 0000 GETGBL R3 G3 0x5C100000, // 0001 MOVE R4 R0 0x7C0C0200, // 0002 CALL R3 1 0x8C0C0700, // 0003 GETMET R3 R3 K0 diff --git a/lib/libesp32/Berry/default/be_lvgl_wifi_arcs_icon_lib.c b/lib/libesp32/Berry/default/be_lvgl_wifi_arcs_icon_lib.c index c46b09034..17538a88e 100644 --- a/lib/libesp32/Berry/default/be_lvgl_wifi_arcs_icon_lib.c +++ b/lib/libesp32/Berry/default/be_lvgl_wifi_arcs_icon_lib.c @@ -41,7 +41,7 @@ be_local_closure(init, /* name */ (be_nested_const_str("init", 380752755, 4)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[52]) { /* code */ - 0x600C0014, // 0000 GETGBL R3 G20 + 0x600C0003, // 0000 GETGBL R3 G3 0x5C100000, // 0001 MOVE R4 R0 0x7C0C0200, // 0002 CALL R3 1 0x8C0C0700, // 0003 GETMET R3 R3 K0 diff --git a/lib/libesp32/Berry/default/be_lvgl_wifi_arcs_lib.c b/lib/libesp32/Berry/default/be_lvgl_wifi_arcs_lib.c index 300b019d1..b820e2b1f 100644 --- a/lib/libesp32/Berry/default/be_lvgl_wifi_arcs_lib.c +++ b/lib/libesp32/Berry/default/be_lvgl_wifi_arcs_lib.c @@ -84,7 +84,7 @@ be_local_closure(init, /* name */ (be_nested_const_str("init", 380752755, 4)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[15]) { /* code */ - 0x600C0014, // 0000 GETGBL R3 G20 + 0x600C0003, // 0000 GETGBL R3 G3 0x5C100000, // 0001 MOVE R4 R0 0x7C0C0200, // 0002 CALL R3 1 0x8C0C0700, // 0003 GETMET R3 R3 K0 @@ -126,7 +126,7 @@ be_local_closure(del, /* name */ (be_nested_const_str("del", -816214454, 3)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[10]) { /* code */ - 0x60040014, // 0000 GETGBL R1 G20 + 0x60040003, // 0000 GETGBL R1 G3 0x5C080000, // 0001 MOVE R2 R0 0x7C040200, // 0002 CALL R1 1 0x8C040300, // 0003 GETMET R1 R1 K0 diff --git a/lib/libesp32/Berry/default/be_lvgl_wifi_bars_icon_lib.c b/lib/libesp32/Berry/default/be_lvgl_wifi_bars_icon_lib.c index a96a71e66..d65bb3ec5 100644 --- a/lib/libesp32/Berry/default/be_lvgl_wifi_bars_icon_lib.c +++ b/lib/libesp32/Berry/default/be_lvgl_wifi_bars_icon_lib.c @@ -40,7 +40,7 @@ be_local_closure(init, /* name */ (be_nested_const_str("init", 380752755, 4)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[49]) { /* code */ - 0x600C0014, // 0000 GETGBL R3 G20 + 0x600C0003, // 0000 GETGBL R3 G3 0x5C100000, // 0001 MOVE R4 R0 0x7C0C0200, // 0002 CALL R3 1 0x8C0C0700, // 0003 GETMET R3 R3 K0 diff --git a/lib/libesp32/Berry/default/be_lvgl_wifi_bars_lib.c b/lib/libesp32/Berry/default/be_lvgl_wifi_bars_lib.c index 6e4540b2b..57e3e0cf2 100644 --- a/lib/libesp32/Berry/default/be_lvgl_wifi_bars_lib.c +++ b/lib/libesp32/Berry/default/be_lvgl_wifi_bars_lib.c @@ -84,7 +84,7 @@ be_local_closure(init, /* name */ (be_nested_const_str("init", 380752755, 4)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[15]) { /* code */ - 0x600C0014, // 0000 GETGBL R3 G20 + 0x600C0003, // 0000 GETGBL R3 G3 0x5C100000, // 0001 MOVE R4 R0 0x7C0C0200, // 0002 CALL R3 1 0x8C0C0700, // 0003 GETMET R3 R3 K0 @@ -126,7 +126,7 @@ be_local_closure(del, /* name */ (be_nested_const_str("del", -816214454, 3)), (be_nested_const_str("input", -103256197, 5)), ( &(const binstruction[10]) { /* code */ - 0x60040014, // 0000 GETGBL R1 G20 + 0x60040003, // 0000 GETGBL R1 G3 0x5C080000, // 0001 MOVE R2 R0 0x7C040200, // 0002 CALL R1 1 0x8C040300, // 0003 GETMET R1 R1 K0 diff --git a/lib/libesp32/Berry/default/be_md5_lib.c b/lib/libesp32/Berry/default/be_md5_lib.c index 3f55dd6a1..2c8dfd77b 100644 --- a/lib/libesp32/Berry/default/be_md5_lib.c +++ b/lib/libesp32/Berry/default/be_md5_lib.c @@ -11,27 +11,12 @@ extern int m_md5_init(bvm *vm); extern int m_md5_update(bvm *vm); extern int m_md5_finish(bvm *vm); -#if BE_USE_PRECOMPILED_OBJECT #include "../generate/be_fixed_be_class_md5.h" -#endif void be_load_md5_lib(bvm *vm) { -#if !BE_USE_PRECOMPILED_OBJECT - static const bnfuncinfo members[] = { - { ".p", NULL }, - - { "init", m_md5_init }, - { "update", m_md5_update }, - { "finish", m_md5_finish }, - - { NULL, NULL } - }; - be_regclass(vm, "MD5", members); -#else be_pushntvclass(vm, &be_class_md5); be_setglobal(vm, "MD5"); be_pop(vm, 1); -#endif } /* @const_object_info_begin diff --git a/lib/libesp32/Berry/default/be_modtab.c b/lib/libesp32/Berry/default/be_modtab.c index bfc02961f..f6c082670 100644 --- a/lib/libesp32/Berry/default/be_modtab.c +++ b/lib/libesp32/Berry/default/be_modtab.c @@ -114,6 +114,8 @@ extern void be_load_md5_lib(bvm *vm); extern void be_load_webclient_lib(bvm *vm); extern void be_load_crypto_lib(bvm *vm); +extern void be_load_ctypes_lib(bvm *vm); + #ifdef USE_I2S_AUDIO_BERRY extern void be_load_driver_audio_lib(bvm *vm); #endif @@ -124,7 +126,6 @@ extern void be_load_lvgl_font_lib(bvm *vm); extern void be_load_lv_all_lib(bvm *vm); extern void be_load_lvgl_cb_lib(bvm *vm); extern void be_load_lvgl_cb_all_lib(bvm *vm); -extern void be_load_lvgl_ctypes_lib(bvm *vm); extern void be_load_ctypes_definitions_lib(bvm *vm); // custom widgets extern void be_load_lv_signal_bars_class(bvm *vm); @@ -150,6 +151,7 @@ BERRY_API void be_load_custom_libs(bvm *vm) be_load_Driver_class(vm); be_load_md5_lib(vm); be_load_serial_lib(vm); + be_load_ctypes_lib(vm); #ifdef USE_ALEXA_AVS be_load_crypto_lib(vm); #endif @@ -175,7 +177,6 @@ BERRY_API void be_load_custom_libs(bvm *vm) be_load_lv_all_lib(vm); be_load_lvgl_cb_lib(vm); be_load_lvgl_cb_all_lib(vm); - be_load_lvgl_ctypes_lib(vm); be_load_ctypes_definitions_lib(vm); // custom widgets be_load_lv_signal_bars_class(vm); diff --git a/lib/libesp32/Berry/default/be_path_tasmota_lib.c b/lib/libesp32/Berry/default/be_path_tasmota_lib.c index 22e0f7baa..c722f01e1 100644 --- a/lib/libesp32/Berry/default/be_path_tasmota_lib.c +++ b/lib/libesp32/Berry/default/be_path_tasmota_lib.c @@ -16,6 +16,7 @@ #include "be_strlib.h" #include "be_mem.h" #include "be_sys.h" +#include static int m_path_exists(bvm *vm) { @@ -26,20 +27,25 @@ static int m_path_exists(bvm *vm) be_pushbool(vm, be_isexist(path)); be_return(vm); } +extern time_t be_last_modified(void *hfile); -#if !BE_USE_PRECOMPILED_OBJECT -be_native_module_attr_table(path) { - be_native_module_function("exists", m_path_exists), -}; +static int m_path_last_modified(bvm *vm) +{ + if (be_top(vm) >= 1 && be_isstring(vm, 1)) { + const char *path = be_tostring(vm, 1); + void * f = be_fopen(path, "r"); + if (f) { + be_pushint(vm, be_last_modified(f)); + be_return(vm); + } + } + be_return_nil(vm); +} -static be_define_native_module(path, NULL); - -#else /* @const_object_info_begin module path (scope: global, file: tasmota_path) { exists, func(m_path_exists) + last_modified, func(m_path_last_modified) } @const_object_info_end */ #include "../generate/be_fixed_tasmota_path.h" - -#endif diff --git a/lib/libesp32/Berry/default/be_port.cpp b/lib/libesp32/Berry/default/be_port.cpp index cca5b3f61..88815a000 100644 --- a/lib/libesp32/Berry/default/be_port.cpp +++ b/lib/libesp32/Berry/default/be_port.cpp @@ -248,6 +248,17 @@ size_t be_fsize(void *hfile) return 0; } +extern "C" time_t be_last_modified(void *hfile) +{ +#ifdef USE_UFILESYS + if (ufsp != nullptr && hfile != nullptr) { + File * f_ptr = (File*) hfile; + return f_ptr->getLastWrite(); + } +#endif // USE_UFILESYS + return 0; +} + int be_isexist(const char *filename) { #ifdef USE_UFILESYS diff --git a/lib/libesp32/Berry/default/be_tasmotalib.c b/lib/libesp32/Berry/default/be_tasmotalib.c index 662a4b72d..28d0f6d1f 100644 --- a/lib/libesp32/Berry/default/be_tasmotalib.c +++ b/lib/libesp32/Berry/default/be_tasmotalib.c @@ -37,1394 +37,14 @@ extern int l_webSend(bvm *vm); extern int l_webSendDecimal(bvm *vm); extern int l_getlight(bvm *vm); -extern int l_getpower(bvm *vm); extern int l_setlight(bvm *vm); +extern int l_getpower(bvm *vm); extern int l_setpower(bvm *vm); +extern int l_getswitch(bvm *vm); extern int l_i2cenabled(bvm *vm); -/******************************************************************** - // add `chars_in_string(s:string,c:string) -> int`` - // looks for any char in c, and return the position of the first char - // or -1 if not found - // inv is optional and inverses the behavior, i.e. look for chars not in the list - "def chars_in_string(s,c,inv) " - "var inverted = inv ? true : false " - "for i:0..size(s)-1 " - "var found = false " - "for j:0..size(c)-1 " - "if s[i] == c[j] found = true end " - "end " - "if inverted != found return i end " - "end " - "return -1 " - "end " -********************************************************************/ -/******************************************************************** -** Solidified function: chars_in_string -********************************************************************/ - -be_define_local_const_str(chars_in_string_str_name, "chars_in_string", -1146182164, 15); -be_define_local_const_str(chars_in_string_str_source, "string", 398550328, 6); -be_define_local_const_str(chars_in_string_str_2, "stop_iteration", -121173395, 14); - -static const bvalue chars_in_string_ktab[3] = { - { { .i=0 }, BE_INT}, - { { .i=1 }, BE_INT}, - { { .s=be_local_const_str(chars_in_string_str_2) }, BE_STRING}, -}; - -static const uint32_t chars_in_string_code[44] = { - 0x780E0001, // 0000 JMPF R3 #0003 - 0x50100200, // 0001 LDBOOL R4 1 0 - 0x70020000, // 0002 JMP #0004 - 0x50100000, // 0003 LDBOOL R4 0 0 - 0x60140000, // 0004 GETGBL R5 G0 - 0x60180012, // 0005 GETGBL R6 G18 - 0x5C1C0200, // 0006 MOVE R7 R1 - 0x7C180200, // 0007 CALL R6 1 - 0x4180D01, // 0008 SUB R6 R6 R257 - 0x401A0006, // 0009 CONNECT R6 R256 R6 - 0x7C140200, // 000A CALL R5 1 - 0xA802001A, // 000B EXBLK 0 #0027 - 0x5C180A00, // 000C MOVE R6 R5 - 0x7C180000, // 000D CALL R6 0 - 0x501C0000, // 000E LDBOOL R7 0 0 - 0x60200000, // 000F GETGBL R8 G0 - 0x60240012, // 0010 GETGBL R9 G18 - 0x5C280400, // 0011 MOVE R10 R2 - 0x7C240200, // 0012 CALL R9 1 - 0x4241301, // 0013 SUB R9 R9 R257 - 0x40260009, // 0014 CONNECT R9 R256 R9 - 0x7C200200, // 0015 CALL R8 1 - 0xA8020007, // 0016 EXBLK 0 #001F - 0x5C241000, // 0017 MOVE R9 R8 - 0x7C240000, // 0018 CALL R9 0 - 0x94280206, // 0019 GETIDX R10 R1 R6 - 0x942C0409, // 001A GETIDX R11 R2 R9 - 0x1C28140B, // 001B EQ R10 R10 R11 - 0x782A0000, // 001C JMPF R10 #001E - 0x501C0200, // 001D LDBOOL R7 1 0 - 0x7001FFF7, // 001E JMP #0017 - 0x58200002, // 001F LDCONST R8 K2 - 0xAC200200, // 0020 CATCH R8 1 0 - 0xB0080000, // 0021 RAISE 2 R0 R0 - 0x20200807, // 0022 NE R8 R4 R7 - 0x78220001, // 0023 JMPF R8 #0026 - 0xA8040001, // 0024 EXBLK 1 1 - 0x80040C00, // 0025 RET 1 R6 - 0x7001FFE4, // 0026 JMP #000C - 0x58140002, // 0027 LDCONST R5 K2 - 0xAC140200, // 0028 CATCH R5 1 0 - 0xB0080000, // 0029 RAISE 2 R0 R0 - 0x5415FFFE, // 002A LDINT R5 -1 - 0x80040A00, // 002B RET 1 R5 -}; - -static const bproto chars_in_string_proto = { - NULL, // bgcobject *next - 8, // type - 0x08, // marked 0x08 - 12, // nstack - 0, // nupvals - 4, // argc - 0, // varg - NULL, // bgcobject *gray - NULL, // bupvaldesc *upvals - (bvalue*) &chars_in_string_ktab, // ktab - NULL, // bproto **ptab - (binstruction*) &chars_in_string_code, // code - be_local_const_str(chars_in_string_str_name), // name - 44, // codesize - 3, // nconst - 0, // nproto - be_local_const_str(chars_in_string_str_source), // source -#if BE_DEBUG_RUNTIME_INFO /* debug information */ - NULL, // lineinfo - 0, // nlineinfo -#endif -#if BE_DEBUG_VAR_INFO - NULL, // varinfo - 0, // nvarinfo -#endif -}; - -const bclosure chars_in_string_closure = { - NULL, // bgcobject *next - 36, // type - 0x08, // marked - 0, // nupvals - NULL, // bgcobject *gray - (bproto*) &chars_in_string_proto, // proto - { NULL } // upvals -}; - -/*******************************************************************/ - - -/******************************************************************** -// find a key in map, case insensitive, return actual key or nil if not found -def find_key_i(m,keyi) - import string - var keyu = string.toupper(keyi) - if classof(m) == map - for k:m.keys() - if string.toupper(k)==keyu || keyi=='?' - return k - end - end - end -end -********************************************************************/ -/******************************************************************** -** Solidified function: find_key_i -********************************************************************/ - -be_define_local_const_str(find_key_i_str_name, "find_key_i", 850136726, 10); -be_define_local_const_str(find_key_i_str_source, "string", 398550328, 6); -be_define_local_const_str(find_key_i_str_0, "string", 398550328, 6); -be_define_local_const_str(find_key_i_str_1, "toupper", -602983720, 7); -be_define_local_const_str(find_key_i_str_2, "keys", -112588595, 4); -be_define_local_const_str(find_key_i_str_3, "?", 973910158, 1); -be_define_local_const_str(find_key_i_str_4, "stop_iteration", -121173395, 14); - -static const bvalue find_key_i_ktab[5] = { - { { .s=be_local_const_str(find_key_i_str_0) }, BE_STRING}, - { { .s=be_local_const_str(find_key_i_str_1) }, BE_STRING}, - { { .s=be_local_const_str(find_key_i_str_2) }, BE_STRING}, - { { .s=be_local_const_str(find_key_i_str_3) }, BE_STRING}, - { { .s=be_local_const_str(find_key_i_str_4) }, BE_STRING}, -}; - -static const uint32_t find_key_i_code[31] = { - 0xA40E0000, // 0000 IMPORT R3 R256 - 0x8C100701, // 0001 GETMET R4 R3 R257 - 0x5C180400, // 0002 MOVE R6 R2 - 0x7C100400, // 0003 CALL R4 2 - 0x60140004, // 0004 GETGBL R5 G4 - 0x5C180200, // 0005 MOVE R6 R1 - 0x7C140200, // 0006 CALL R5 1 - 0x6018000B, // 0007 GETGBL R6 G11 - 0x1C140A06, // 0008 EQ R5 R5 R6 - 0x78160013, // 0009 JMPF R5 #001E - 0x60140000, // 000A GETGBL R5 G0 - 0x8C180302, // 000B GETMET R6 R1 R258 - 0x7C180200, // 000C CALL R6 1 - 0x7C140200, // 000D CALL R5 1 - 0xA802000B, // 000E EXBLK 0 #001B - 0x5C180A00, // 000F MOVE R6 R5 - 0x7C180000, // 0010 CALL R6 0 - 0x8C1C0701, // 0011 GETMET R7 R3 R257 - 0x5C240C00, // 0012 MOVE R9 R6 - 0x7C1C0400, // 0013 CALL R7 2 - 0x1C1C0E04, // 0014 EQ R7 R7 R4 - 0x741E0001, // 0015 JMPT R7 #0018 - 0x1C1C0503, // 0016 EQ R7 R2 R259 - 0x781E0001, // 0017 JMPF R7 #001A - 0xA8040001, // 0018 EXBLK 1 1 - 0x80040C00, // 0019 RET 1 R6 - 0x7001FFF3, // 001A JMP #000F - 0x58140004, // 001B LDCONST R5 K4 - 0xAC140200, // 001C CATCH R5 1 0 - 0xB0080000, // 001D RAISE 2 R0 R0 - 0x80000000, // 001E RET 0 R0 -}; - -static const bproto find_key_i_proto = { - NULL, // bgcobject *next - 8, // type - 0x08, // marked - 10, // nstack - 0, // nupvals - 3, // argc - 0, // varg - NULL, // bgcobject *gray - NULL, // bupvaldesc *upvals - (bvalue*) &find_key_i_ktab, // ktab - NULL, // bproto **ptab - (binstruction*) &find_key_i_code, // code - be_local_const_str(find_key_i_str_name), // name - 31, // codesize - 5, // nconst - 0, // nproto - be_local_const_str(find_key_i_str_source), // source -#if BE_DEBUG_RUNTIME_INFO /* debug information */ - NULL, // lineinfo - 0, // nlineinfo -#endif -#if BE_DEBUG_VAR_INFO - NULL, // varinfo - 0, // nvarinfo -#endif -}; - -const bclosure find_key_i_closure = { - NULL, // bgcobject *next - 36, // type - 0x08, // marked - 0, // nupvals - NULL, // bgcobject *gray - (bproto*) &find_key_i_proto, // proto - { NULL } // upvals -}; - -/*******************************************************************/ - - - -/******************************************************************** - // # split the item when there is an operator, returns a list of (left,op,right) - // # ex: "Dimmer>50" -> ["Dimmer",tasmota_gt,"50"] - "def find_op(item) " - "import string " - "var op_chars = '=<>!' " - "var pos = self.chars_in_string(item, op_chars) " - "if pos >= 0 " - "var op_split = string.split(item,pos) " - "var op_left = op_split[0] " - "var op_rest = op_split[1] " - "pos = self.chars_in_string(op_rest, op_chars, true) " - "if pos >= 0 " - "var op_split2 = string.split(op_rest,pos) " - "var op_middle = op_split2[0] " - "var op_right = op_split2[1] " - "return [op_left,op_middle,op_right] " - "end " - "end " - "return [item, nil, nil] " - "end " -********************************************************************/ -/******************************************************************** -** Solidified function: find_op -********************************************************************/ - -be_define_local_const_str(find_op_str_name, "find_op", -528253920, 7); -be_define_local_const_str(find_op_str_source, "string", 398550328, 6); -be_define_local_const_str(find_op_str_0, "string", 398550328, 6); -be_define_local_const_str(find_op_str_1, "=<>!", -1630497019, 4); -be_define_local_const_str(find_op_str_2, "chars_in_string", -1146182164, 15); -be_define_local_const_str(find_op_str_4, "split", -2017972765, 5); - -static const bvalue find_op_ktab[6] = { - { { .s=be_local_const_str(find_op_str_0) }, BE_STRING}, - { { .s=be_local_const_str(find_op_str_1) }, BE_STRING}, - { { .s=be_local_const_str(find_op_str_2) }, BE_STRING}, - { { .i=0 }, BE_INT}, - { { .s=be_local_const_str(find_op_str_4) }, BE_STRING}, - { { .i=1 }, BE_INT}, -}; - -static const uint32_t find_op_code[42] = { - 0xA40A0000, // 0000 IMPORT R2 R256 - 0x580C0001, // 0001 LDCONST R3 K1 - 0x8C100102, // 0002 GETMET R4 R0 R258 - 0x5C180200, // 0003 MOVE R6 R1 - 0x5C1C0600, // 0004 MOVE R7 R3 - 0x7C100600, // 0005 CALL R4 3 - 0x28140903, // 0006 GE R5 R4 R259 - 0x78160019, // 0007 JMPF R5 #0022 - 0x8C140504, // 0008 GETMET R5 R2 R260 - 0x5C1C0200, // 0009 MOVE R7 R1 - 0x5C200800, // 000A MOVE R8 R4 - 0x7C140600, // 000B CALL R5 3 - 0x94180B03, // 000C GETIDX R6 R5 R259 - 0x941C0B05, // 000D GETIDX R7 R5 R261 - 0x8C200102, // 000E GETMET R8 R0 R258 - 0x5C280E00, // 000F MOVE R10 R7 - 0x5C2C0600, // 0010 MOVE R11 R3 - 0x50300200, // 0011 LDBOOL R12 1 0 - 0x7C200800, // 0012 CALL R8 4 - 0x5C101000, // 0013 MOVE R4 R8 - 0x28200903, // 0014 GE R8 R4 R259 - 0x7822000B, // 0015 JMPF R8 #0022 - 0x8C200504, // 0016 GETMET R8 R2 R260 - 0x5C280E00, // 0017 MOVE R10 R7 - 0x5C2C0800, // 0018 MOVE R11 R4 - 0x7C200600, // 0019 CALL R8 3 - 0x94241103, // 001A GETIDX R9 R8 R259 - 0x94281105, // 001B GETIDX R10 R8 R261 - 0x602C000A, // 001C GETGBL R11 G10 - 0x7C2C0000, // 001D CALL R11 0 - 0x40301606, // 001E CONNECT R12 R11 R6 - 0x40301609, // 001F CONNECT R12 R11 R9 - 0x4030160A, // 0020 CONNECT R12 R11 R10 - 0x80041600, // 0021 RET 1 R11 - 0x6014000A, // 0022 GETGBL R5 G10 - 0x7C140000, // 0023 CALL R5 0 - 0x40180A01, // 0024 CONNECT R6 R5 R1 - 0x4C180000, // 0025 LDNIL 6 - 0x40180A06, // 0026 CONNECT R6 R5 R6 - 0x4C180000, // 0027 LDNIL 6 - 0x40180A06, // 0028 CONNECT R6 R5 R6 - 0x80040A00, // 0029 RET 1 R5 -}; - -static const bproto find_op_proto = { - NULL, // bgcobject *next - 8, // type - 0x08, // marked - 13, // nstack - 0, // nupvals - 2, // argc - 0, // varg - NULL, // bgcobject *gray - NULL, // bupvaldesc *upvals - (bvalue*) &find_op_ktab, // ktab - NULL, // bproto **ptab - (binstruction*) &find_op_code, // code - be_local_const_str(find_op_str_name), // name - 42, // codesize - 6, // nconst - 0, // nproto - be_local_const_str(find_op_str_source), // source -#if BE_DEBUG_RUNTIME_INFO /* debug information */ - NULL, // lineinfo - 0, // nlineinfo -#endif -#if BE_DEBUG_VAR_INFO - NULL, // varinfo - 0, // nvarinfo -#endif -}; - -const bclosure find_op_closure = { - NULL, // bgcobject *next - 36, // type - 0x08, // marked - 0, // nupvals - NULL, // bgcobject *gray - (bproto*) &find_op_proto, // proto - { NULL } // upvals -}; - -/*******************************************************************/ - - -/******************************************************************** - // Rules - "def add_rule(pat,f) " - "if !self._rules " - "self._rules={} " - "end " - "if type(f) == 'function' " - "self._rules[pat] = f " - "else " - "raise 'value_error', 'the second argument is not a function' " - "end " - "end " -********************************************************************/ - -/******************************************************************** -** Solidified function: add_rule -********************************************************************/ - -be_define_local_const_str(add_rule_str_name, "add_rule", 596540743, 8); -be_define_local_const_str(add_rule_str_source, "string", 398550328, 6); -be_define_local_const_str(add_rule_str_0, "_rules", -28750191, 6); -be_define_local_const_str(add_rule_str_1, "function", -1630125495, 8); -be_define_local_const_str(add_rule_str_2, "value_error", 773297791, 11); -be_define_local_const_str(add_rule_str_3, "the second argument is not a function", -340392827, 37); - -static const bvalue add_rule_ktab[4] = { - { { .s=be_local_const_str(add_rule_str_0) }, BE_STRING}, - { { .s=be_local_const_str(add_rule_str_1) }, BE_STRING}, - { { .s=be_local_const_str(add_rule_str_2) }, BE_STRING}, - { { .s=be_local_const_str(add_rule_str_3) }, BE_STRING}, -}; - -static const uint32_t add_rule_code[15] = { - 0x880C0100, // 0000 GETMBR R3 R0 R256 - 0x740E0002, // 0001 JMPT R3 #0005 - 0x600C000B, // 0002 GETGBL R3 G11 - 0x7C0C0000, // 0003 CALL R3 0 - 0x90020003, // 0004 SETMBR R0 R256 R3 - 0x600C0015, // 0005 GETGBL R3 G21 - 0x5C100400, // 0006 MOVE R4 R2 - 0x7C0C0200, // 0007 CALL R3 1 - 0x1C0C0701, // 0008 EQ R3 R3 R257 - 0x780E0002, // 0009 JMPF R3 #000D - 0x880C0100, // 000A GETMBR R3 R0 R256 - 0x980C0202, // 000B SETIDX R3 R1 R2 - 0x70020000, // 000C JMP #000E - 0xB0060503, // 000D RAISE 1 R258 R259 - 0x80000000, // 000E RET 0 R0 -}; - -static const bproto add_rule_proto = { - NULL, // bgcobject *next - 8, // type - 0x08, // marked - 5, // nstack - 0, // nupvals - 3, // argc - 0, // varg - NULL, // bgcobject *gray - NULL, // bupvaldesc *upvals - (bvalue*) &add_rule_ktab, // ktab - NULL, // bproto **ptab - (binstruction*) &add_rule_code, // code - be_local_const_str(add_rule_str_name), // name - 15, // codesize - 4, // nconst - 0, // nproto - be_local_const_str(add_rule_str_source), // source -#if BE_DEBUG_RUNTIME_INFO /* debug information */ - NULL, // lineinfo - 0, // nlineinfo -#endif -#if BE_DEBUG_VAR_INFO - NULL, // varinfo - 0, // nvarinfo -#endif -}; - -static const bclosure add_rule_closure = { - NULL, // bgcobject *next - 36, // type - 0x08, // marked - 0, // nupvals - NULL, // bgcobject *gray - (bproto*) &add_rule_proto, // proto - { NULL } // upvals -}; - -/*******************************************************************/ - -/******************************************************************** - "def remove_rule(pat) " - "if self._rules " - "self._rules.remove(pat) " - "end " - "end " -********************************************************************/ - -/******************************************************************** -** Solidified function: remove_rule -********************************************************************/ -be_local_closure(remove_rule, /* name */ - be_nested_proto( - 5, /* nstack */ - 2, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* upvals */ - { { .s=be_nested_const_str("_rules", -28750191, 6) }, BE_STRING}, - { { .s=be_nested_const_str("remove", -611183107, 6) }, BE_STRING}, - }), - (be_nested_const_str("remove_rule", -838755968, 11)), - (be_nested_const_str("string", 398550328, 6)), - ( &(const binstruction[ 7]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 R256 - 0x780A0003, // 0001 JMPF R2 #0006 - 0x88080100, // 0002 GETMBR R2 R0 R256 - 0x8C080501, // 0003 GETMET R2 R2 R257 - 0x5C100200, // 0004 MOVE R4 R1 - 0x7C080400, // 0005 CALL R2 2 - 0x80000000, // 0006 RET 0 R0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** - // Rules trigger if match. return true if match, false if not - "def try_rule(event, rule, f) " - "import string " - "var rl_list = self.find_op(rule) " - "var sub_event = event " - "var rl = string.split(rl_list[0],'#') " - "for it:rl " - "found=self.find_key_i(sub_event,it) " - "if found == nil return false end " - "sub_event = sub_event[found] " - "end " - "var op=rl_list[1]" - "var op2=rl_list[2]" - "if op " - "if op=='==' " - "if str(sub_event) != str(op2) return false end " - "elif op=='!==' " - "if str(sub_event) == str(op2) return false end " - "elif op=='=' " - "if real(sub_event) != real(op2) return false end " - "elif op=='!=' " - "if real(sub_event) == real(op2) return false end " - "elif op=='>' " - "if real(sub_event) <= real(op2) return false end " - "elif op=='>=' " - "if real(sub_event) < real(op2) return false end " - "elif op=='<' " - "if real(sub_event) >= real(op2) return false end " - "elif op=='<=' " - "if real(sub_event) > real(op2) return false end " - "end " - "end " - "f(sub_event, rl_list[0], event) " - "return true " - "end " -********************************************************************/ -/******************************************************************** -** Solidified function: try_rule -********************************************************************/ - -be_define_local_const_str(try_rule_str_name, "try_rule", 1986449405, 8); -be_define_local_const_str(try_rule_str_source, "string", 398550328, 6); -be_define_local_const_str(try_rule_str_0, "string", 398550328, 6); -be_define_local_const_str(try_rule_str_1, "find_op", -528253920, 7); -be_define_local_const_str(try_rule_str_2, "split", -2017972765, 5); -be_define_local_const_str(try_rule_str_4, "#", 638357778, 1); -be_define_local_const_str(try_rule_str_5, "find_key_i", 850136726, 10); -be_define_local_const_str(try_rule_str_6, "stop_iteration", -121173395, 14); -be_define_local_const_str(try_rule_str_9, "==", -1863000881, 2); -be_define_local_const_str(try_rule_str_10, "!==", 559817114, 3); -be_define_local_const_str(try_rule_str_11, "=", 940354920, 1); -be_define_local_const_str(try_rule_str_12, "!=", -1866252285, 2); -be_define_local_const_str(try_rule_str_13, ">", 990687777, 1); -be_define_local_const_str(try_rule_str_14, ">=", 284975636, 2); -be_define_local_const_str(try_rule_str_15, "<", 957132539, 1); -be_define_local_const_str(try_rule_str_16, "<=", -1795743310, 2); - -static const bvalue try_rule_ktab[17] = { - { { .s=be_local_const_str(try_rule_str_0) }, BE_STRING}, - { { .s=be_local_const_str(try_rule_str_1) }, BE_STRING}, - { { .s=be_local_const_str(try_rule_str_2) }, BE_STRING}, - { { .i=0 }, BE_INT}, - { { .s=be_local_const_str(try_rule_str_4) }, BE_STRING}, - { { .s=be_local_const_str(try_rule_str_5) }, BE_STRING}, - { { .s=be_local_const_str(try_rule_str_6) }, BE_STRING}, - { { .i=1 }, BE_INT}, - { { .i=2 }, BE_INT}, - { { .s=be_local_const_str(try_rule_str_9) }, BE_STRING}, - { { .s=be_local_const_str(try_rule_str_10) }, BE_STRING}, - { { .s=be_local_const_str(try_rule_str_11) }, BE_STRING}, - { { .s=be_local_const_str(try_rule_str_12) }, BE_STRING}, - { { .s=be_local_const_str(try_rule_str_13) }, BE_STRING}, - { { .s=be_local_const_str(try_rule_str_14) }, BE_STRING}, - { { .s=be_local_const_str(try_rule_str_15) }, BE_STRING}, - { { .s=be_local_const_str(try_rule_str_16) }, BE_STRING}, -}; - -static const uint32_t try_rule_code[143] = { - 0xA4120000, // 0000 IMPORT R4 R256 - 0x8C140101, // 0001 GETMET R5 R0 R257 - 0x5C1C0400, // 0002 MOVE R7 R2 - 0x7C140400, // 0003 CALL R5 2 - 0x5C180200, // 0004 MOVE R6 R1 - 0x8C1C0902, // 0005 GETMET R7 R4 R258 - 0x94240B03, // 0006 GETIDX R9 R5 R259 - 0x58280004, // 0007 LDCONST R10 K4 - 0x7C1C0600, // 0008 CALL R7 3 - 0x60200000, // 0009 GETGBL R8 G0 - 0x5C240E00, // 000A MOVE R9 R7 - 0x7C200200, // 000B CALL R8 1 - 0xA802000D, // 000C EXBLK 0 #001B - 0x5C241000, // 000D MOVE R9 R8 - 0x7C240000, // 000E CALL R9 0 - 0x8C280105, // 000F GETMET R10 R0 R261 - 0x5C300C00, // 0010 MOVE R12 R6 - 0x5C341200, // 0011 MOVE R13 R9 - 0x7C280600, // 0012 CALL R10 3 - 0x4C2C0000, // 0013 LDNIL 11 - 0x1C2C140B, // 0014 EQ R11 R10 R11 - 0x782E0002, // 0015 JMPF R11 #0019 - 0x502C0000, // 0016 LDBOOL R11 0 0 - 0xA8040001, // 0017 EXBLK 1 1 - 0x80041600, // 0018 RET 1 R11 - 0x94180C0A, // 0019 GETIDX R6 R6 R10 - 0x7001FFF1, // 001A JMP #000D - 0x58200006, // 001B LDCONST R8 K6 - 0xAC200200, // 001C CATCH R8 1 0 - 0xB0080000, // 001D RAISE 2 R0 R0 - 0x94200B07, // 001E GETIDX R8 R5 R263 - 0x94240B08, // 001F GETIDX R9 R5 R264 - 0x78220066, // 0020 JMPF R8 #0088 - 0x1C281109, // 0021 EQ R10 R8 R265 - 0x782A000A, // 0022 JMPF R10 #002E - 0x60280013, // 0023 GETGBL R10 G19 - 0x5C2C0C00, // 0024 MOVE R11 R6 - 0x7C280200, // 0025 CALL R10 1 - 0x602C0013, // 0026 GETGBL R11 G19 - 0x5C301200, // 0027 MOVE R12 R9 - 0x7C2C0200, // 0028 CALL R11 1 - 0x2028140B, // 0029 NE R10 R10 R11 - 0x782A0001, // 002A JMPF R10 #002D - 0x50280000, // 002B LDBOOL R10 0 0 - 0x80041400, // 002C RET 1 R10 - 0x70020059, // 002D JMP #0088 - 0x1C28110A, // 002E EQ R10 R8 R266 - 0x782A000A, // 002F JMPF R10 #003B - 0x60280013, // 0030 GETGBL R10 G19 - 0x5C2C0C00, // 0031 MOVE R11 R6 - 0x7C280200, // 0032 CALL R10 1 - 0x602C0013, // 0033 GETGBL R11 G19 - 0x5C301200, // 0034 MOVE R12 R9 - 0x7C2C0200, // 0035 CALL R11 1 - 0x1C28140B, // 0036 EQ R10 R10 R11 - 0x782A0001, // 0037 JMPF R10 #003A - 0x50280000, // 0038 LDBOOL R10 0 0 - 0x80041400, // 0039 RET 1 R10 - 0x7002004C, // 003A JMP #0088 - 0x1C28110B, // 003B EQ R10 R8 R267 - 0x782A000A, // 003C JMPF R10 #0048 - 0x60280011, // 003D GETGBL R10 G17 - 0x5C2C0C00, // 003E MOVE R11 R6 - 0x7C280200, // 003F CALL R10 1 - 0x602C0011, // 0040 GETGBL R11 G17 - 0x5C301200, // 0041 MOVE R12 R9 - 0x7C2C0200, // 0042 CALL R11 1 - 0x2028140B, // 0043 NE R10 R10 R11 - 0x782A0001, // 0044 JMPF R10 #0047 - 0x50280000, // 0045 LDBOOL R10 0 0 - 0x80041400, // 0046 RET 1 R10 - 0x7002003F, // 0047 JMP #0088 - 0x1C28110C, // 0048 EQ R10 R8 R268 - 0x782A000A, // 0049 JMPF R10 #0055 - 0x60280011, // 004A GETGBL R10 G17 - 0x5C2C0C00, // 004B MOVE R11 R6 - 0x7C280200, // 004C CALL R10 1 - 0x602C0011, // 004D GETGBL R11 G17 - 0x5C301200, // 004E MOVE R12 R9 - 0x7C2C0200, // 004F CALL R11 1 - 0x1C28140B, // 0050 EQ R10 R10 R11 - 0x782A0001, // 0051 JMPF R10 #0054 - 0x50280000, // 0052 LDBOOL R10 0 0 - 0x80041400, // 0053 RET 1 R10 - 0x70020032, // 0054 JMP #0088 - 0x1C28110D, // 0055 EQ R10 R8 R269 - 0x782A000A, // 0056 JMPF R10 #0062 - 0x60280011, // 0057 GETGBL R10 G17 - 0x5C2C0C00, // 0058 MOVE R11 R6 - 0x7C280200, // 0059 CALL R10 1 - 0x602C0011, // 005A GETGBL R11 G17 - 0x5C301200, // 005B MOVE R12 R9 - 0x7C2C0200, // 005C CALL R11 1 - 0x1828140B, // 005D LE R10 R10 R11 - 0x782A0001, // 005E JMPF R10 #0061 - 0x50280000, // 005F LDBOOL R10 0 0 - 0x80041400, // 0060 RET 1 R10 - 0x70020025, // 0061 JMP #0088 - 0x1C28110E, // 0062 EQ R10 R8 R270 - 0x782A000A, // 0063 JMPF R10 #006F - 0x60280011, // 0064 GETGBL R10 G17 - 0x5C2C0C00, // 0065 MOVE R11 R6 - 0x7C280200, // 0066 CALL R10 1 - 0x602C0011, // 0067 GETGBL R11 G17 - 0x5C301200, // 0068 MOVE R12 R9 - 0x7C2C0200, // 0069 CALL R11 1 - 0x1428140B, // 006A LT R10 R10 R11 - 0x782A0001, // 006B JMPF R10 #006E - 0x50280000, // 006C LDBOOL R10 0 0 - 0x80041400, // 006D RET 1 R10 - 0x70020018, // 006E JMP #0088 - 0x1C28110F, // 006F EQ R10 R8 R271 - 0x782A000A, // 0070 JMPF R10 #007C - 0x60280011, // 0071 GETGBL R10 G17 - 0x5C2C0C00, // 0072 MOVE R11 R6 - 0x7C280200, // 0073 CALL R10 1 - 0x602C0011, // 0074 GETGBL R11 G17 - 0x5C301200, // 0075 MOVE R12 R9 - 0x7C2C0200, // 0076 CALL R11 1 - 0x2828140B, // 0077 GE R10 R10 R11 - 0x782A0001, // 0078 JMPF R10 #007B - 0x50280000, // 0079 LDBOOL R10 0 0 - 0x80041400, // 007A RET 1 R10 - 0x7002000B, // 007B JMP #0088 - 0x1C281110, // 007C EQ R10 R8 R272 - 0x782A0009, // 007D JMPF R10 #0088 - 0x60280011, // 007E GETGBL R10 G17 - 0x5C2C0C00, // 007F MOVE R11 R6 - 0x7C280200, // 0080 CALL R10 1 - 0x602C0011, // 0081 GETGBL R11 G17 - 0x5C301200, // 0082 MOVE R12 R9 - 0x7C2C0200, // 0083 CALL R11 1 - 0x2428140B, // 0084 GT R10 R10 R11 - 0x782A0001, // 0085 JMPF R10 #0088 - 0x50280000, // 0086 LDBOOL R10 0 0 - 0x80041400, // 0087 RET 1 R10 - 0x5C280600, // 0088 MOVE R10 R3 - 0x5C2C0C00, // 0089 MOVE R11 R6 - 0x94300B03, // 008A GETIDX R12 R5 R259 - 0x5C340200, // 008B MOVE R13 R1 - 0x7C280600, // 008C CALL R10 3 - 0x50280200, // 008D LDBOOL R10 1 0 - 0x80041400, // 008E RET 1 R10 -}; - -static const bproto try_rule_proto = { - NULL, // bgcobject *next - 8, // type - 0x08, // marked - 14, // nstack - 0, // nupvals - 4, // argc - 0, // varg - NULL, // bgcobject *gray - NULL, // bupvaldesc *upvals - (bvalue*) &try_rule_ktab, // ktab - NULL, // bproto **ptab - (binstruction*) &try_rule_code, // code - be_local_const_str(try_rule_str_name), // name - 143, // codesize - 17, // nconst - 0, // nproto - be_local_const_str(try_rule_str_source), // source -#if BE_DEBUG_RUNTIME_INFO /* debug information */ - NULL, // lineinfo - 0, // nlineinfo -#endif -#if BE_DEBUG_VAR_INFO - NULL, // varinfo - 0, // nvarinfo -#endif -}; - -static const bclosure try_rule_closure = { - NULL, // bgcobject *next - 36, // type - 0x08, // marked - 0, // nupvals - NULL, // bgcobject *gray - (bproto*) &try_rule_proto, // proto - { NULL } // upvals -}; - -/*******************************************************************/ - - -/******************************************************************** - // Run rules, i.e. check each individual rule - // Returns true if at least one rule matched, false if none - "def exec_rules(ev_json) " - "if self._rules " - "import json " - "var ev = json.load(ev_json) " - "var ret = false " - "if ev == nil " - "print('BRY: ERROR, bad json: '+ev_json, 3) " - "else " - "for r: self._rules.keys() " - "ret = self.try_rule(ev,r,self._rules[r]) || ret " - "end " - "end " - "return ret " - "end " - "return false " - "end " - -********************************************************************/ - -/******************************************************************** -** Solidified function: exec_rules -********************************************************************/ - -be_define_local_const_str(exec_rules_str_name, "exec_rules", 1445221092, 10); -be_define_local_const_str(exec_rules_str_source, "string", 398550328, 6); -be_define_local_const_str(exec_rules_str_0, "_rules", -28750191, 6); -be_define_local_const_str(exec_rules_str_1, "json", 916562499, 4); -be_define_local_const_str(exec_rules_str_2, "load", -435725847, 4); -be_define_local_const_str(exec_rules_str_3, "BRY: ERROR, bad json: ", -1579831487, 22); -be_define_local_const_str(exec_rules_str_5, "keys", -112588595, 4); -be_define_local_const_str(exec_rules_str_6, "try_rule", 1986449405, 8); -be_define_local_const_str(exec_rules_str_7, "stop_iteration", -121173395, 14); - -static const bvalue exec_rules_ktab[8] = { - { { .s=be_local_const_str(exec_rules_str_0) }, BE_STRING}, - { { .s=be_local_const_str(exec_rules_str_1) }, BE_STRING}, - { { .s=be_local_const_str(exec_rules_str_2) }, BE_STRING}, - { { .s=be_local_const_str(exec_rules_str_3) }, BE_STRING}, - { { .i=3 }, BE_INT}, - { { .s=be_local_const_str(exec_rules_str_5) }, BE_STRING}, - { { .s=be_local_const_str(exec_rules_str_6) }, BE_STRING}, - { { .s=be_local_const_str(exec_rules_str_7) }, BE_STRING}, -}; - -static const uint32_t exec_rules_code[40] = { - 0x88080100, // 0000 GETMBR R2 R0 R256 - 0x780A0023, // 0001 JMPF R2 #0026 - 0xA40A0200, // 0002 IMPORT R2 R257 - 0x8C0C0502, // 0003 GETMET R3 R2 R258 - 0x5C140200, // 0004 MOVE R5 R1 - 0x7C0C0400, // 0005 CALL R3 2 - 0x50100000, // 0006 LDBOOL R4 0 0 - 0x4C140000, // 0007 LDNIL 5 - 0x1C140605, // 0008 EQ R5 R3 R5 - 0x78160004, // 0009 JMPF R5 #000F - 0x6014000F, // 000A GETGBL R5 G15 - 0x1A0601, // 000B ADD R6 R259 R1 - 0x581C0004, // 000C LDCONST R7 K4 - 0x7C140400, // 000D CALL R5 2 - 0x70020015, // 000E JMP #0025 - 0x60140000, // 000F GETGBL R5 G0 - 0x88180100, // 0010 GETMBR R6 R0 R256 - 0x8C180D05, // 0011 GETMET R6 R6 R261 - 0x7C180200, // 0012 CALL R6 1 - 0x7C140200, // 0013 CALL R5 1 - 0xA802000C, // 0014 EXBLK 0 #0022 - 0x5C180A00, // 0015 MOVE R6 R5 - 0x7C180000, // 0016 CALL R6 0 - 0x8C1C0106, // 0017 GETMET R7 R0 R262 - 0x5C240600, // 0018 MOVE R9 R3 - 0x5C280C00, // 0019 MOVE R10 R6 - 0x882C0100, // 001A GETMBR R11 R0 R256 - 0x942C1606, // 001B GETIDX R11 R11 R6 - 0x7C1C0800, // 001C CALL R7 4 - 0x741E0001, // 001D JMPT R7 #0020 - 0x74120000, // 001E JMPT R4 #0020 - 0x50100001, // 001F LDBOOL R4 0 1 - 0x50100200, // 0020 LDBOOL R4 1 0 - 0x7001FFF2, // 0021 JMP #0015 - 0x58140007, // 0022 LDCONST R5 K7 - 0xAC140200, // 0023 CATCH R5 1 0 - 0xB0080000, // 0024 RAISE 2 R0 R0 - 0x80040800, // 0025 RET 1 R4 - 0x50080000, // 0026 LDBOOL R2 0 0 - 0x80040400, // 0027 RET 1 R2 -}; - -static const bproto exec_rules_proto = { - NULL, // bgcobject *next - 8, // type - 0x08, // marked - 12, // nstack - 0, // nupvals - 2, // argc - 0, // varg - NULL, // bgcobject *gray - NULL, // bupvaldesc *upvals - (bvalue*) &exec_rules_ktab, // ktab - NULL, // bproto **ptab - (binstruction*) &exec_rules_code, // code - be_local_const_str(exec_rules_str_name), // name - 40, // codesize - 8, // nconst - 0, // nproto - be_local_const_str(exec_rules_str_source), // source -#if BE_DEBUG_RUNTIME_INFO /* debug information */ - NULL, // lineinfo - 0, // nlineinfo -#endif -#if BE_DEBUG_VAR_INFO - NULL, // varinfo - 0, // nvarinfo -#endif -}; - -const bclosure exec_rules_closure = { - NULL, // bgcobject *next - 36, // type - 0x08, // marked - 0, // nupvals - NULL, // bgcobject *gray - (bproto*) &exec_rules_proto, // proto - { NULL } // upvals -}; - -/*******************************************************************/ - -/******************************************************************** -** Solidified function: set_timer -********************************************************************/ -be_local_closure(set_timer, /* name */ - be_nested_proto( - 10, /* nstack */ - 4, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - be_nested_string("_timers", -1694866380, 7), /* R256 - K0 */ - be_nested_string("push", -2022703139, 4), /* R257 - K1 */ - be_nested_string("Timer", -346839614, 5), /* R258 - K2 */ - be_nested_string("millis", 1214679063, 6), /* R259 - K3 */ - }), - (be_nested_const_str("set_timer", 2135414533, 9)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[16]) { /* code */ - 0x88100100, // 0000 GETMBR R4 R0 R256 - 0x74120002, // 0001 JMPT R4 #0005 - 0x6010000A, // 0002 GETGBL R4 G10 - 0x7C100000, // 0003 CALL R4 0 - 0x90020004, // 0004 SETMBR R0 R256 R4 - 0x88100100, // 0005 GETMBR R4 R0 R256 - 0x8C100901, // 0006 GETMET R4 R4 R257 - 0xB81A0400, // 0007 GETNGBL R6 R258 - 0x8C1C0103, // 0008 GETMET R7 R0 R259 - 0x5C240200, // 0009 MOVE R9 R1 - 0x7C1C0400, // 000A CALL R7 2 - 0x5C200400, // 000B MOVE R8 R2 - 0x5C240600, // 000C MOVE R9 R3 - 0x7C180600, // 000D CALL R6 3 - 0x7C100400, // 000E CALL R4 2 - 0x80000000, // 000F RET 0 R0 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** -** Solidified function: run_deferred -********************************************************************/ -be_local_closure(run_deferred, /* name */ - be_nested_proto( - 6, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - be_nested_string("_timers", -1694866380, 7), /* R256 - K0 */ - be_const_int(0), /* R257 - K1 */ - be_nested_string("size", 597743964, 4), /* R258 - K2 */ - be_nested_string("time_reached", 2075136773, 12), /* R259 - K3 */ - be_nested_string("due", -399437003, 3), /* R260 - K4 */ - be_nested_string("f", -485742695, 1), /* R261 - K5 */ - be_nested_string("remove", -611183107, 6), /* R262 - K6 */ - be_const_int(1), /* R263 - K7 */ - }), - (be_nested_const_str("run_deferred", 371594696, 12)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[27]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 R256 - 0x78060017, // 0001 JMPF R1 #001A - 0x58040001, // 0002 LDCONST R1 K1 - 0x88080100, // 0003 GETMBR R2 R0 R256 - 0x8C080502, // 0004 GETMET R2 R2 R258 - 0x7C080200, // 0005 CALL R2 1 - 0x14080202, // 0006 LT R2 R1 R2 - 0x780A0011, // 0007 JMPF R2 #001A - 0x8C080103, // 0008 GETMET R2 R0 R259 - 0x88100100, // 0009 GETMBR R4 R0 R256 - 0x94100801, // 000A GETIDX R4 R4 R1 - 0x88100904, // 000B GETMBR R4 R4 R260 - 0x7C080400, // 000C CALL R2 2 - 0x780A0009, // 000D JMPF R2 #0018 - 0x88080100, // 000E GETMBR R2 R0 R256 - 0x94080401, // 000F GETIDX R2 R2 R1 - 0x88080505, // 0010 GETMBR R2 R2 R261 - 0x880C0100, // 0011 GETMBR R3 R0 R256 - 0x8C0C0706, // 0012 GETMET R3 R3 R262 - 0x5C140200, // 0013 MOVE R5 R1 - 0x7C0C0400, // 0014 CALL R3 2 - 0x5C0C0400, // 0015 MOVE R3 R2 - 0x7C0C0000, // 0016 CALL R3 0 - 0x70020000, // 0017 JMP #0019 - 0x00040307, // 0018 ADD R1 R1 R263 - 0x7001FFE8, // 0019 JMP #0003 - 0x80000000, // 001A RET 0 R0 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** -** Solidified function: remove_timer -********************************************************************/ -be_local_closure(remove_timer, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - be_nested_string("tasmota", 424643812, 7), /* R256 - K0 */ - be_nested_string("_timers", -1694866380, 7), /* R257 - K1 */ - be_const_int(0), /* R258 - K2 */ - be_nested_string("size", 597743964, 4), /* R259 - K3 */ - be_nested_string("id", 926444256, 2), /* R260 - K4 */ - be_nested_string("remove", -611183107, 6), /* R261 - K5 */ - be_const_int(1), /* R262 - K6 */ - }), - (be_nested_const_str("remove_timer", -153495081, 12)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[23]) { /* code */ - 0xB80A0000, // 0000 GETNGBL R2 R256 - 0x88080501, // 0001 GETMBR R2 R2 R257 - 0x780A0012, // 0002 JMPF R2 #0016 - 0x58080002, // 0003 LDCONST R2 K2 - 0xB80E0000, // 0004 GETNGBL R3 R256 - 0x880C0701, // 0005 GETMBR R3 R3 R257 - 0x8C0C0703, // 0006 GETMET R3 R3 R259 - 0x7C0C0200, // 0007 CALL R3 1 - 0x140C0403, // 0008 LT R3 R2 R3 - 0x780E000B, // 0009 JMPF R3 #0016 - 0x880C0101, // 000A GETMBR R3 R0 R257 - 0x940C0602, // 000B GETIDX R3 R3 R2 - 0x880C0704, // 000C GETMBR R3 R3 R260 - 0x1C0C0601, // 000D EQ R3 R3 R1 - 0x780E0004, // 000E JMPF R3 #0014 - 0x880C0101, // 000F GETMBR R3 R0 R257 - 0x8C0C0705, // 0010 GETMET R3 R3 R261 - 0x5C140400, // 0011 MOVE R5 R2 - 0x7C0C0400, // 0012 CALL R3 2 - 0x70020000, // 0013 JMP #0015 - 0x00080506, // 0014 ADD R2 R2 R262 - 0x7001FFED, // 0015 JMP #0004 - 0x80000000, // 0016 RET 0 R0 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** - // Add command to list - "def add_cmd(c,f) " - "if !self._ccmd " - "self._ccmd={} " - "end " - "if type(f) == 'function' " - "self._ccmd[c]=f " - "else " - "raise 'value_error', 'the second argument is not a function' " - "end " - "end " -********************************************************************/ -/******************************************************************** -** Solidified function: add_cmd -********************************************************************/ - -be_define_local_const_str(add_cmd_str_name, "add_cmd", -933336417, 7); -be_define_local_const_str(add_cmd_str_source, "string", 398550328, 6); -be_define_local_const_str(add_cmd_str_0, "_ccmd", -2131545883, 5); -be_define_local_const_str(add_cmd_str_1, "function", -1630125495, 8); -be_define_local_const_str(add_cmd_str_2, "value_error", 773297791, 11); -be_define_local_const_str(add_cmd_str_3, "the second argument is not a function", -340392827, 37); - -static const bvalue add_cmd_ktab[4] = { - { { .s=be_local_const_str(add_cmd_str_0) }, BE_STRING}, - { { .s=be_local_const_str(add_cmd_str_1) }, BE_STRING}, - { { .s=be_local_const_str(add_cmd_str_2) }, BE_STRING}, - { { .s=be_local_const_str(add_cmd_str_3) }, BE_STRING}, -}; - -static const uint32_t add_cmd_code[15] = { - 0x880C0100, // 0000 GETMBR R3 R0 R256 - 0x740E0002, // 0001 JMPT R3 #0005 - 0x600C000B, // 0002 GETGBL R3 G11 - 0x7C0C0000, // 0003 CALL R3 0 - 0x90020003, // 0004 SETMBR R0 R256 R3 - 0x600C0015, // 0005 GETGBL R3 G21 - 0x5C100400, // 0006 MOVE R4 R2 - 0x7C0C0200, // 0007 CALL R3 1 - 0x1C0C0701, // 0008 EQ R3 R3 R257 - 0x780E0002, // 0009 JMPF R3 #000D - 0x880C0100, // 000A GETMBR R3 R0 R256 - 0x980C0202, // 000B SETIDX R3 R1 R2 - 0x70020000, // 000C JMP #000E - 0xB0060503, // 000D RAISE 1 R258 R259 - 0x80000000, // 000E RET 0 R0 -}; - -static const bproto add_cmd_proto = { - NULL, // bgcobject *next - 8, // type - 0x08, // marked - 5, // nstack - 0, // nupvals - 3, // argc - 0, // varg - NULL, // bgcobject *gray - NULL, // bupvaldesc *upvals - (bvalue*) &add_cmd_ktab, // ktab - NULL, // bproto **ptab - (binstruction*) &add_cmd_code, // code - be_local_const_str(add_cmd_str_name), // name - 15, // codesize - 4, // nconst - 0, // nproto - be_local_const_str(add_cmd_str_source), // source -#if BE_DEBUG_RUNTIME_INFO /* debug information */ - NULL, // lineinfo - 0, // nlineinfo -#endif -#if BE_DEBUG_VAR_INFO - NULL, // varinfo - 0, // nvarinfo -#endif -}; - -static const bclosure add_cmd_closure = { - NULL, // bgcobject *next - 36, // type - 0x08, // marked - 0, // nupvals - NULL, // bgcobject *gray - (bproto*) &add_cmd_proto, // proto - { NULL } // upvals -}; - -/*******************************************************************/ - - -/******************************************************************** - // Remove command from list - "def remove_cmd(c) " - "if self._ccmd " - "self._ccmd.remove(c) " - "end " - "end " -********************************************************************/ - -/******************************************************************** -** Solidified function: remove_cmd -********************************************************************/ -be_local_closure(remove_cmd, /* name */ - be_nested_proto( - 5, /* nstack */ - 2, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* upvals */ - { { .s=be_nested_const_str("_ccmd", -2131545883, 5) }, BE_STRING}, - { { .s=be_nested_const_str("remove", -611183107, 6) }, BE_STRING}, - }), - (be_nested_const_str("remove_cmd", -462651594, 10)), - (be_nested_const_str("string", 398550328, 6)), - ( &(const binstruction[ 7]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 R256 - 0x780A0003, // 0001 JMPF R2 #0006 - 0x88080100, // 0002 GETMBR R2 R0 R256 - 0x8C080501, // 0003 GETMET R2 R2 R257 - 0x5C100200, // 0004 MOVE R4 R1 - 0x7C080400, // 0005 CALL R2 2 - 0x80000000, // 0006 RET 0 R0 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** -** Solidified function: exec_cmd -********************************************************************/ -be_local_closure(exec_cmd, /* name */ - be_nested_proto( - 12, /* nstack */ - 4, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - be_nested_string("_ccmd", -2131545883, 5), /* R256 - K0 */ - be_nested_string("json", 916562499, 4), /* R257 - K1 */ - be_nested_string("load", -435725847, 4), /* R258 - K2 */ - be_nested_string("find_key_i", 850136726, 10), /* R259 - K3 */ - be_nested_string("resolvecmnd", 993361485, 11), /* R260 - K4 */ - }), - (be_nested_const_str("exec_cmd", 493567399, 8)), - (be_nested_const_str("string", 398550328, 6)), - ( &(const binstruction[27]) { /* code */ - 0x88100100, // 0000 GETMBR R4 R0 R256 - 0x78120016, // 0001 JMPF R4 #0019 - 0xA4120200, // 0002 IMPORT R4 R257 - 0x8C140902, // 0003 GETMET R5 R4 R258 - 0x5C1C0600, // 0004 MOVE R7 R3 - 0x7C140400, // 0005 CALL R5 2 - 0x8C180103, // 0006 GETMET R6 R0 R259 - 0x88200100, // 0007 GETMBR R8 R0 R256 - 0x5C240200, // 0008 MOVE R9 R1 - 0x7C180600, // 0009 CALL R6 3 - 0x4C1C0000, // 000A LDNIL 7 - 0x201C0C07, // 000B NE R7 R6 R7 - 0x781E000B, // 000C JMPF R7 #0019 - 0x8C1C0104, // 000D GETMET R7 R0 R260 - 0x5C240C00, // 000E MOVE R9 R6 - 0x7C1C0400, // 000F CALL R7 2 - 0x881C0100, // 0010 GETMBR R7 R0 R256 - 0x941C0E06, // 0011 GETIDX R7 R7 R6 - 0x5C200C00, // 0012 MOVE R8 R6 - 0x5C240400, // 0013 MOVE R9 R2 - 0x5C280600, // 0014 MOVE R10 R3 - 0x5C2C0A00, // 0015 MOVE R11 R5 - 0x7C1C0800, // 0016 CALL R7 4 - 0x501C0200, // 0017 LDBOOL R7 1 0 - 0x80040E00, // 0018 RET 1 R7 - 0x50100000, // 0019 LDBOOL R4 0 0 - 0x80040800, // 001A RET 1 R4 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** - // Force gc and return allocated memory - "def gc() " - "import gc " - "gc.collect() " - "return gc.allocated() " - "end " -********************************************************************/ - -/******************************************************************** -** Solidified function: gc -********************************************************************/ -be_local_closure(gc, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* upvals */ - { { .s=be_nested_const_str("gc", 1042313471, 2) }, BE_STRING}, - { { .s=be_nested_const_str("collect", -1895928271, 7) }, BE_STRING}, - { { .s=be_nested_const_str("allocated", 429986098, 9) }, BE_STRING}, - }), - (be_nested_const_str("gc", 1042313471, 2)), - (be_nested_const_str("string", 398550328, 6)), - ( &(const binstruction[ 6]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 R256 - 0x8C080301, // 0001 GETMET R2 R1 R257 - 0x7C080200, // 0002 CALL R2 1 - 0x8C080302, // 0003 GETMET R2 R1 R258 - 0x7C080200, // 0004 CALL R2 1 - 0x80040400, // 0005 RET 1 R2 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** -** Solidified function: event -********************************************************************/ -be_local_closure(event, /* name */ - be_nested_proto( - 19, /* nstack */ - 6, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[15]) { /* constants */ - be_nested_string("introspect", 164638290, 10), /* R256 - K0 */ - be_nested_string("every_50ms", -1911083288, 10), /* R257 - K1 */ - be_nested_string("run_deferred", 371594696, 12), /* R258 - K2 */ - be_nested_string("cmd", -158181397, 3), /* R259 - K3 */ - be_nested_string("exec_cmd", 493567399, 8), /* R260 - K4 */ - be_nested_string("rule", -64077613, 4), /* R261 - K5 */ - be_nested_string("exec_rules", 1445221092, 10), /* R262 - K6 */ - be_nested_string("gc", 1042313471, 2), /* R263 - K7 */ - be_nested_string("_drivers", -1034638311, 8), /* R264 - K8 */ - be_nested_string("get", 1410115415, 3), /* R265 - K9 */ - be_nested_string("function", -1630125495, 8), /* R266 - K10 */ - be_nested_string("string", 398550328, 6), /* R267 - K11 */ - be_nested_string("format", -1180859054, 6), /* R268 - K12 */ - be_nested_string("BRY: Exception> '%s' - %s", -2047976332, 25), /* R269 - K13 */ - be_nested_string("stop_iteration", -121173395, 14), /* R270 - K14 */ - }), - (be_nested_const_str("event", -30355297, 5)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[79]) { /* code */ - 0xA41A0000, // 0000 IMPORT R6 R256 - 0x1C1C0301, // 0001 EQ R7 R1 R257 - 0x781E0001, // 0002 JMPF R7 #0005 - 0x8C1C0102, // 0003 GETMET R7 R0 R258 - 0x7C1C0200, // 0004 CALL R7 1 - 0x1C1C0303, // 0005 EQ R7 R1 R259 - 0x781E0006, // 0006 JMPF R7 #000E - 0x8C1C0104, // 0007 GETMET R7 R0 R260 - 0x5C240400, // 0008 MOVE R9 R2 - 0x5C280600, // 0009 MOVE R10 R3 - 0x5C2C0800, // 000A MOVE R11 R4 - 0x7C1C0800, // 000B CALL R7 4 - 0x80040E00, // 000C RET 1 R7 - 0x7002003F, // 000D JMP #004E - 0x1C1C0305, // 000E EQ R7 R1 R261 - 0x781E0004, // 000F JMPF R7 #0015 - 0x8C1C0106, // 0010 GETMET R7 R0 R262 - 0x5C240800, // 0011 MOVE R9 R4 - 0x7C1C0400, // 0012 CALL R7 2 - 0x80040E00, // 0013 RET 1 R7 - 0x70020038, // 0014 JMP #004E - 0x1C1C0307, // 0015 EQ R7 R1 R263 - 0x781E0003, // 0016 JMPF R7 #001B - 0x8C1C0107, // 0017 GETMET R7 R0 R263 - 0x7C1C0200, // 0018 CALL R7 1 - 0x80040E00, // 0019 RET 1 R7 - 0x70020032, // 001A JMP #004E - 0x881C0108, // 001B GETMBR R7 R0 R264 - 0x781E0030, // 001C JMPF R7 #004E - 0x601C0000, // 001D GETGBL R7 G0 - 0x88200108, // 001E GETMBR R8 R0 R264 - 0x7C1C0200, // 001F CALL R7 1 - 0xA8020027, // 0020 EXBLK 0 #0049 - 0x5C200E00, // 0021 MOVE R8 R7 - 0x7C200000, // 0022 CALL R8 0 - 0x8C240D09, // 0023 GETMET R9 R6 R265 - 0x5C2C1000, // 0024 MOVE R11 R8 - 0x5C300200, // 0025 MOVE R12 R1 - 0x7C240600, // 0026 CALL R9 3 - 0x60280015, // 0027 GETGBL R10 G21 - 0x5C2C1200, // 0028 MOVE R11 R9 - 0x7C280200, // 0029 CALL R10 1 - 0x1C28150A, // 002A EQ R10 R10 R266 - 0x782A001B, // 002B JMPF R10 #0048 - 0xA802000E, // 002C EXBLK 0 #003C - 0x5C281200, // 002D MOVE R10 R9 - 0x5C2C1000, // 002E MOVE R11 R8 - 0x5C300400, // 002F MOVE R12 R2 - 0x5C340600, // 0030 MOVE R13 R3 - 0x5C380800, // 0031 MOVE R14 R4 - 0x5C3C0A00, // 0032 MOVE R15 R5 - 0x7C280A00, // 0033 CALL R10 5 - 0x502C0200, // 0034 LDBOOL R11 1 0 - 0x1C2C140B, // 0035 EQ R11 R10 R11 - 0x782E0002, // 0036 JMPF R11 #003A - 0x502C0200, // 0037 LDBOOL R11 1 0 - 0xA8040002, // 0038 EXBLK 1 2 - 0x80041600, // 0039 RET 1 R11 - 0xA8040001, // 003A EXBLK 1 1 - 0x7002000B, // 003B JMP #0048 - 0xAC280002, // 003C CATCH R10 0 2 - 0x70020008, // 003D JMP #0047 - 0xA4321600, // 003E IMPORT R12 R267 - 0x6034000F, // 003F GETGBL R13 G15 - 0x8C38190C, // 0040 GETMET R14 R12 R268 - 0x5840000D, // 0041 LDCONST R16 K13 - 0x5C441400, // 0042 MOVE R17 R10 - 0x5C481600, // 0043 MOVE R18 R11 - 0x7C380800, // 0044 CALL R14 4 - 0x7C340200, // 0045 CALL R13 1 - 0x70020000, // 0046 JMP #0048 - 0xB0080000, // 0047 RAISE 2 R0 R0 - 0x7001FFD7, // 0048 JMP #0021 - 0x581C000E, // 0049 LDCONST R7 K14 - 0xAC1C0200, // 004A CATCH R7 1 0 - 0xB0080000, // 004B RAISE 2 R0 R0 - 0x501C0000, // 004C LDBOOL R7 0 0 - 0x80040E00, // 004D RET 1 R7 - 0x80000000, // 004E RET 0 R0 - }) - ) -); -/*******************************************************************/ - /******************************************************************** ** Solidified function: add_driver ********************************************************************/ @@ -1439,29 +59,991 @@ be_local_closure(add_driver, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ - be_nested_string("_drivers", -1034638311, 8), /* R256 - K0 */ - be_nested_string("push", -2022703139, 4), /* R257 - K1 */ + /* K0 */ be_nested_string("_drivers", -1034638311, 8), + /* K1 */ be_nested_string("push", -2022703139, 4), }), (be_nested_const_str("add_driver", 1654458371, 10)), - (be_nested_const_str("string", 398550328, 6)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), ( &(const binstruction[12]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 R256 - 0x780A0004, // 0001 JMPF R2 #0007 - 0x88080100, // 0002 GETMBR R2 R0 R256 - 0x8C080501, // 0003 GETMET R2 R2 R257 - 0x5C100200, // 0004 MOVE R4 R1 - 0x7C080400, // 0005 CALL R2 2 - 0x70020003, // 0006 JMP #000B - 0x6008000A, // 0007 GETGBL R2 G10 - 0x7C080000, // 0008 CALL R2 0 - 0x400C0401, // 0009 CONNECT R3 R2 R1 - 0x90020002, // 000A SETMBR R0 R256 R2 - 0x80000000, // 000B RET 0 R0 + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A0004, // 0001 JMPF R2 #0007 + 0x88080100, // 0002 GETMBR R2 R0 K0 + 0x8C080501, // 0003 GETMET R2 R2 K1 + 0x5C100200, // 0004 MOVE R4 R1 + 0x7C080400, // 0005 CALL R2 2 + 0x70020003, // 0006 JMP #000B + 0x60080012, // 0007 GETGBL R2 G18 + 0x7C080000, // 0008 CALL R2 0 + 0x400C0401, // 0009 CONNECT R3 R2 R1 + 0x90020002, // 000A SETMBR R0 K0 R2 + 0x80000000, // 000B RET 0 }) ) ); /*******************************************************************/ + +/******************************************************************** +** Solidified function: gen_cb +********************************************************************/ +be_local_closure(gen_cb, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_string("_cb", -251666929, 3), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_string("find", -1108310694, 4), + /* K3 */ be_nested_string("_get_cb", 1448849122, 7), + /* K4 */ be_nested_string("stop_iteration", -121173395, 14), + /* K5 */ be_nested_string("internal_error", -1775809127, 14), + /* K6 */ be_nested_string("No callback available", 633786138, 21), + }), + (be_nested_const_str("gen_cb", -1049739745, 6)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[34]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x1C080403, // 0002 EQ R2 R2 R3 + 0x780A0002, // 0003 JMPF R2 #0007 + 0x60080013, // 0004 GETGBL R2 G19 + 0x7C080000, // 0005 CALL R2 0 + 0x90020002, // 0006 SETMBR R0 K0 R2 + 0x60080010, // 0007 GETGBL R2 G16 + 0x540E0012, // 0008 LDINT R3 19 + 0x400E0203, // 0009 CONNECT R3 K1 R3 + 0x7C080200, // 000A CALL R2 1 + 0xA8020010, // 000B EXBLK 0 #001D + 0x5C0C0400, // 000C MOVE R3 R2 + 0x7C0C0000, // 000D CALL R3 0 + 0x88100100, // 000E GETMBR R4 R0 K0 + 0x8C100902, // 000F GETMET R4 R4 K2 + 0x5C180600, // 0010 MOVE R6 R3 + 0x7C100400, // 0011 CALL R4 2 + 0x4C140000, // 0012 LDNIL R5 + 0x1C100805, // 0013 EQ R4 R4 R5 + 0x78120006, // 0014 JMPF R4 #001C + 0x88100100, // 0015 GETMBR R4 R0 K0 + 0x98100601, // 0016 SETIDX R4 R3 R1 + 0x8C100103, // 0017 GETMET R4 R0 K3 + 0x5C180600, // 0018 MOVE R6 R3 + 0x7C100400, // 0019 CALL R4 2 + 0xA8040001, // 001A EXBLK 1 1 + 0x80040800, // 001B RET 1 R4 + 0x7001FFEE, // 001C JMP #000C + 0x58080004, // 001D LDCONST R2 K4 + 0xAC080200, // 001E CATCH R2 1 0 + 0xB0080000, // 001F RAISE 2 R0 R0 + 0xB0060B06, // 0020 RAISE 1 K5 K6 + 0x80000000, // 0021 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_light +********************************************************************/ +be_local_closure(set_light, /* name */ + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_string("tasmota.set_light() is deprecated, use light.set()", 2124937871, 50), + /* K1 */ be_nested_string("light", -493019601, 5), + /* K2 */ be_nested_string("set", -970520829, 3), + }), + (be_nested_const_str("set_light", -1118891144, 9)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[18]) { /* code */ + 0x600C0001, // 0000 GETGBL R3 G1 + 0x58100000, // 0001 LDCONST R4 K0 + 0x7C0C0200, // 0002 CALL R3 1 + 0xA40E0200, // 0003 IMPORT R3 K1 + 0x4C100000, // 0004 LDNIL R4 + 0x20100404, // 0005 NE R4 R2 R4 + 0x78120005, // 0006 JMPF R4 #000D + 0x8C100702, // 0007 GETMET R4 R3 K2 + 0x5C180200, // 0008 MOVE R6 R1 + 0x5C1C0400, // 0009 MOVE R7 R2 + 0x7C100600, // 000A CALL R4 3 + 0x80040800, // 000B RET 1 R4 + 0x70020003, // 000C JMP #0011 + 0x8C100702, // 000D GETMET R4 R3 K2 + 0x5C180200, // 000E MOVE R6 R1 + 0x7C100400, // 000F CALL R4 2 + 0x80040800, // 0010 RET 1 R4 + 0x80000000, // 0011 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: remove_rule +********************************************************************/ +be_local_closure(remove_rule, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_string("_rules", -28750191, 6), + /* K1 */ be_nested_string("remove", -611183107, 6), + }), + (be_nested_const_str("remove_rule", -838755968, 11)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[ 7]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A0003, // 0001 JMPF R2 #0006 + 0x88080100, // 0002 GETMBR R2 R0 K0 + 0x8C080501, // 0003 GETMET R2 R2 K1 + 0x5C100200, // 0004 MOVE R4 R1 + 0x7C080400, // 0005 CALL R2 2 + 0x80000000, // 0006 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: add_cmd +********************************************************************/ +be_local_closure(add_cmd, /* name */ + be_nested_proto( + 5, /* nstack */ + 3, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_string("_ccmd", -2131545883, 5), + /* K1 */ be_nested_string("function", -1630125495, 8), + /* K2 */ be_nested_string("value_error", 773297791, 11), + /* K3 */ be_nested_string("the second argument is not a function", -340392827, 37), + }), + (be_nested_const_str("add_cmd", -933336417, 7)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[15]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x740E0002, // 0001 JMPT R3 #0005 + 0x600C0013, // 0002 GETGBL R3 G19 + 0x7C0C0000, // 0003 CALL R3 0 + 0x90020003, // 0004 SETMBR R0 K0 R3 + 0x600C0004, // 0005 GETGBL R3 G4 + 0x5C100400, // 0006 MOVE R4 R2 + 0x7C0C0200, // 0007 CALL R3 1 + 0x1C0C0701, // 0008 EQ R3 R3 K1 + 0x780E0002, // 0009 JMPF R3 #000D + 0x880C0100, // 000A GETMBR R3 R0 K0 + 0x980C0202, // 000B SETIDX R3 R1 R2 + 0x70020000, // 000C JMP #000E + 0xB0060503, // 000D RAISE 1 K2 K3 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: wire_scan +********************************************************************/ +be_local_closure(wire_scan, /* name */ + be_nested_proto( + 6, /* nstack */ + 3, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_string("i2c_enabled", 218388101, 11), + /* K1 */ be_nested_string("wire1", -1082245877, 5), + /* K2 */ be_nested_string("detect", 8884370, 6), + /* K3 */ be_nested_string("wire2", -1065468258, 5), + }), + (be_nested_const_str("wire_scan", -1623691416, 9)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[25]) { /* code */ + 0x4C0C0000, // 0000 LDNIL R3 + 0x200C0403, // 0001 NE R3 R2 R3 + 0x780E0005, // 0002 JMPF R3 #0009 + 0x8C0C0100, // 0003 GETMET R3 R0 K0 + 0x5C140400, // 0004 MOVE R5 R2 + 0x7C0C0400, // 0005 CALL R3 2 + 0x740E0001, // 0006 JMPT R3 #0009 + 0x4C0C0000, // 0007 LDNIL R3 + 0x80040600, // 0008 RET 1 R3 + 0x880C0101, // 0009 GETMBR R3 R0 K1 + 0x8C0C0702, // 000A GETMET R3 R3 K2 + 0x5C140200, // 000B MOVE R5 R1 + 0x7C0C0400, // 000C CALL R3 2 + 0x780E0001, // 000D JMPF R3 #0010 + 0x880C0101, // 000E GETMBR R3 R0 K1 + 0x80040600, // 000F RET 1 R3 + 0x880C0103, // 0010 GETMBR R3 R0 K3 + 0x8C0C0702, // 0011 GETMET R3 R3 K2 + 0x5C140200, // 0012 MOVE R5 R1 + 0x7C0C0400, // 0013 CALL R3 2 + 0x780E0001, // 0014 JMPF R3 #0017 + 0x880C0103, // 0015 GETMBR R3 R0 K3 + 0x80040600, // 0016 RET 1 R3 + 0x4C0C0000, // 0017 LDNIL R3 + 0x80040600, // 0018 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: find_key_i +********************************************************************/ +be_local_closure(find_key_i, /* name */ + be_nested_proto( + 10, /* nstack */ + 3, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_string("string", 398550328, 6), + /* K1 */ be_nested_string("toupper", -602983720, 7), + /* K2 */ be_nested_string("keys", -112588595, 4), + /* K3 */ be_nested_string("?", 973910158, 1), + /* K4 */ be_nested_string("stop_iteration", -121173395, 14), + }), + (be_nested_const_str("find_key_i", 850136726, 10)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[31]) { /* code */ + 0xA40E0000, // 0000 IMPORT R3 K0 + 0x8C100701, // 0001 GETMET R4 R3 K1 + 0x5C180400, // 0002 MOVE R6 R2 + 0x7C100400, // 0003 CALL R4 2 + 0x60140006, // 0004 GETGBL R5 G6 + 0x5C180200, // 0005 MOVE R6 R1 + 0x7C140200, // 0006 CALL R5 1 + 0x60180013, // 0007 GETGBL R6 G19 + 0x1C140A06, // 0008 EQ R5 R5 R6 + 0x78160013, // 0009 JMPF R5 #001E + 0x60140010, // 000A GETGBL R5 G16 + 0x8C180302, // 000B GETMET R6 R1 K2 + 0x7C180200, // 000C CALL R6 1 + 0x7C140200, // 000D CALL R5 1 + 0xA802000B, // 000E EXBLK 0 #001B + 0x5C180A00, // 000F MOVE R6 R5 + 0x7C180000, // 0010 CALL R6 0 + 0x8C1C0701, // 0011 GETMET R7 R3 K1 + 0x5C240C00, // 0012 MOVE R9 R6 + 0x7C1C0400, // 0013 CALL R7 2 + 0x1C1C0E04, // 0014 EQ R7 R7 R4 + 0x741E0001, // 0015 JMPT R7 #0018 + 0x1C1C0503, // 0016 EQ R7 R2 K3 + 0x781E0001, // 0017 JMPF R7 #001A + 0xA8040001, // 0018 EXBLK 1 1 + 0x80040C00, // 0019 RET 1 R6 + 0x7001FFF3, // 001A JMP #000F + 0x58140004, // 001B LDCONST R5 K4 + 0xAC140200, // 001C CATCH R5 1 0 + 0xB0080000, // 001D RAISE 2 R0 R0 + 0x80000000, // 001E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: chars_in_string +********************************************************************/ +be_local_closure(chars_in_string, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_const_int(1), + /* K2 */ be_nested_string("stop_iteration", -121173395, 14), + }), + (be_nested_const_str("chars_in_string", -1146182164, 15)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[44]) { /* code */ + 0x780E0001, // 0000 JMPF R3 #0003 + 0x50100200, // 0001 LDBOOL R4 1 0 + 0x70020000, // 0002 JMP #0004 + 0x50100000, // 0003 LDBOOL R4 0 0 + 0x60140010, // 0004 GETGBL R5 G16 + 0x6018000C, // 0005 GETGBL R6 G12 + 0x5C1C0200, // 0006 MOVE R7 R1 + 0x7C180200, // 0007 CALL R6 1 + 0x04180D01, // 0008 SUB R6 R6 K1 + 0x401A0006, // 0009 CONNECT R6 K0 R6 + 0x7C140200, // 000A CALL R5 1 + 0xA802001A, // 000B EXBLK 0 #0027 + 0x5C180A00, // 000C MOVE R6 R5 + 0x7C180000, // 000D CALL R6 0 + 0x501C0000, // 000E LDBOOL R7 0 0 + 0x60200010, // 000F GETGBL R8 G16 + 0x6024000C, // 0010 GETGBL R9 G12 + 0x5C280400, // 0011 MOVE R10 R2 + 0x7C240200, // 0012 CALL R9 1 + 0x04241301, // 0013 SUB R9 R9 K1 + 0x40260009, // 0014 CONNECT R9 K0 R9 + 0x7C200200, // 0015 CALL R8 1 + 0xA8020007, // 0016 EXBLK 0 #001F + 0x5C241000, // 0017 MOVE R9 R8 + 0x7C240000, // 0018 CALL R9 0 + 0x94280206, // 0019 GETIDX R10 R1 R6 + 0x942C0409, // 001A GETIDX R11 R2 R9 + 0x1C28140B, // 001B EQ R10 R10 R11 + 0x782A0000, // 001C JMPF R10 #001E + 0x501C0200, // 001D LDBOOL R7 1 0 + 0x7001FFF7, // 001E JMP #0017 + 0x58200002, // 001F LDCONST R8 K2 + 0xAC200200, // 0020 CATCH R8 1 0 + 0xB0080000, // 0021 RAISE 2 R0 R0 + 0x20200807, // 0022 NE R8 R4 R7 + 0x78220001, // 0023 JMPF R8 #0026 + 0xA8040001, // 0024 EXBLK 1 1 + 0x80040C00, // 0025 RET 1 R6 + 0x7001FFE4, // 0026 JMP #000C + 0x58140002, // 0027 LDCONST R5 K2 + 0xAC140200, // 0028 CATCH R5 1 0 + 0xB0080000, // 0029 RAISE 2 R0 R0 + 0x5415FFFE, // 002A LDINT R5 -1 + 0x80040A00, // 002B RET 1 R5 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_timer +********************************************************************/ +be_local_closure(set_timer, /* name */ + be_nested_proto( + 10, /* nstack */ + 4, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_string("_timers", -1694866380, 7), + /* K1 */ be_nested_string("push", -2022703139, 4), + /* K2 */ be_nested_string("Timer", -346839614, 5), + /* K3 */ be_nested_string("millis", 1214679063, 6), + }), + (be_nested_const_str("set_timer", 2135414533, 9)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[16]) { /* code */ + 0x88100100, // 0000 GETMBR R4 R0 K0 + 0x74120002, // 0001 JMPT R4 #0005 + 0x60100012, // 0002 GETGBL R4 G18 + 0x7C100000, // 0003 CALL R4 0 + 0x90020004, // 0004 SETMBR R0 K0 R4 + 0x88100100, // 0005 GETMBR R4 R0 K0 + 0x8C100901, // 0006 GETMET R4 R4 K1 + 0xB81A0400, // 0007 GETNGBL R6 K2 + 0x8C1C0103, // 0008 GETMET R7 R0 K3 + 0x5C240200, // 0009 MOVE R9 R1 + 0x7C1C0400, // 000A CALL R7 2 + 0x5C200400, // 000B MOVE R8 R2 + 0x5C240600, // 000C MOVE R9 R3 + 0x7C180600, // 000D CALL R6 3 + 0x7C100400, // 000E CALL R4 2 + 0x80000000, // 000F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: add_rule +********************************************************************/ +be_local_closure(add_rule, /* name */ + be_nested_proto( + 5, /* nstack */ + 3, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_string("_rules", -28750191, 6), + /* K1 */ be_nested_string("function", -1630125495, 8), + /* K2 */ be_nested_string("value_error", 773297791, 11), + /* K3 */ be_nested_string("the second argument is not a function", -340392827, 37), + }), + (be_nested_const_str("add_rule", 596540743, 8)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[15]) { /* code */ + 0x880C0100, // 0000 GETMBR R3 R0 K0 + 0x740E0002, // 0001 JMPT R3 #0005 + 0x600C0013, // 0002 GETGBL R3 G19 + 0x7C0C0000, // 0003 CALL R3 0 + 0x90020003, // 0004 SETMBR R0 K0 R3 + 0x600C0004, // 0005 GETGBL R3 G4 + 0x5C100400, // 0006 MOVE R4 R2 + 0x7C0C0200, // 0007 CALL R3 1 + 0x1C0C0701, // 0008 EQ R3 R3 K1 + 0x780E0002, // 0009 JMPF R3 #000D + 0x880C0100, // 000A GETMBR R3 R0 K0 + 0x980C0202, // 000B SETIDX R3 R1 R2 + 0x70020000, // 000C JMP #000E + 0xB0060503, // 000D RAISE 1 K2 K3 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: run_deferred +********************************************************************/ +be_local_closure(run_deferred, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_string("_timers", -1694866380, 7), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_string("size", 597743964, 4), + /* K3 */ be_nested_string("time_reached", 2075136773, 12), + /* K4 */ be_nested_string("due", -399437003, 3), + /* K5 */ be_nested_string("f", -485742695, 1), + /* K6 */ be_nested_string("remove", -611183107, 6), + /* K7 */ be_const_int(1), + }), + (be_nested_const_str("run_deferred", 371594696, 12)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[27]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x78060017, // 0001 JMPF R1 #001A + 0x58040001, // 0002 LDCONST R1 K1 + 0x88080100, // 0003 GETMBR R2 R0 K0 + 0x8C080502, // 0004 GETMET R2 R2 K2 + 0x7C080200, // 0005 CALL R2 1 + 0x14080202, // 0006 LT R2 R1 R2 + 0x780A0011, // 0007 JMPF R2 #001A + 0x8C080103, // 0008 GETMET R2 R0 K3 + 0x88100100, // 0009 GETMBR R4 R0 K0 + 0x94100801, // 000A GETIDX R4 R4 R1 + 0x88100904, // 000B GETMBR R4 R4 K4 + 0x7C080400, // 000C CALL R2 2 + 0x780A0009, // 000D JMPF R2 #0018 + 0x88080100, // 000E GETMBR R2 R0 K0 + 0x94080401, // 000F GETIDX R2 R2 R1 + 0x88080505, // 0010 GETMBR R2 R2 K5 + 0x880C0100, // 0011 GETMBR R3 R0 K0 + 0x8C0C0706, // 0012 GETMET R3 R3 K6 + 0x5C140200, // 0013 MOVE R5 R1 + 0x7C0C0400, // 0014 CALL R3 2 + 0x5C0C0400, // 0015 MOVE R3 R2 + 0x7C0C0000, // 0016 CALL R3 0 + 0x70020000, // 0017 JMP #0019 + 0x00040307, // 0018 ADD R1 R1 K7 + 0x7001FFE8, // 0019 JMP #0003 + 0x80000000, // 001A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: cmd +********************************************************************/ +be_local_closure(cmd, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_string("json", 916562499, 4), + /* K1 */ be_nested_string("_cmd", -875145154, 4), + /* K2 */ be_nested_string("load", -435725847, 4), + /* K3 */ be_nested_string("instance", 193386898, 8), + /* K4 */ be_nested_string("response", 1499316702, 8), + }), + (be_nested_const_str("cmd", -158181397, 3)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[19]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0x8C0C0101, // 0001 GETMET R3 R0 K1 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x8C100502, // 0004 GETMET R4 R2 K2 + 0x5C180600, // 0005 MOVE R6 R3 + 0x7C100400, // 0006 CALL R4 2 + 0x60140004, // 0007 GETGBL R5 G4 + 0x5C180800, // 0008 MOVE R6 R4 + 0x7C140200, // 0009 CALL R5 1 + 0x1C140B03, // 000A EQ R5 R5 K3 + 0x78160001, // 000B JMPF R5 #000E + 0x80040800, // 000C RET 1 R4 + 0x70020003, // 000D JMP #0012 + 0x60140013, // 000E GETGBL R5 G19 + 0x7C140000, // 000F CALL R5 0 + 0x98160804, // 0010 SETIDX R5 K4 R4 + 0x80040A00, // 0011 RET 1 R5 + 0x80000000, // 0012 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: time_str +********************************************************************/ +be_local_closure(time_str, /* name */ + be_nested_proto( + 13, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_string("string", 398550328, 6), + /* K1 */ be_nested_string("time_dump", -964556549, 9), + /* K2 */ be_nested_string("format", -1180859054, 6), + /* K3 */ be_nested_string("%04d-%02d-%02dT%02d:%02d:%02d", -869438695, 29), + /* K4 */ be_nested_string("year", -1367388900, 4), + /* K5 */ be_nested_string("month", -696646139, 5), + /* K6 */ be_nested_string("day", -464576003, 3), + /* K7 */ be_nested_string("hour", -1241306097, 4), + /* K8 */ be_nested_string("min", -913357481, 3), + /* K9 */ be_nested_string("sec", -1155074638, 3), + }), + (be_nested_const_str("time_str", -1681139684, 8)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[14]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0x8C0C0101, // 0001 GETMET R3 R0 K1 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x8C100502, // 0004 GETMET R4 R2 K2 + 0x58180003, // 0005 LDCONST R6 K3 + 0x941C0704, // 0006 GETIDX R7 R3 K4 + 0x94200705, // 0007 GETIDX R8 R3 K5 + 0x94240706, // 0008 GETIDX R9 R3 K6 + 0x94280707, // 0009 GETIDX R10 R3 K7 + 0x942C0708, // 000A GETIDX R11 R3 K8 + 0x94300709, // 000B GETIDX R12 R3 K9 + 0x7C101000, // 000C CALL R4 8 + 0x80040800, // 000D RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: load +********************************************************************/ +be_local_closure(load, /* name */ + be_nested_proto( + 14, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[16]) { /* constants */ + /* K0 */ be_nested_string("string", 398550328, 6), + /* K1 */ be_nested_string("split", -2017972765, 5), + /* K2 */ be_nested_string(".", 722245873, 1), + /* K3 */ be_const_int(1), + /* K4 */ be_nested_string("be", 942383232, 2), + /* K5 */ be_nested_string("bec", 1336821081, 3), + /* K6 */ be_nested_string("io_error", 1970281036, 8), + /* K7 */ be_nested_string("file extension is not '.be' or '.bec'", -1199247657, 37), + /* K8 */ be_nested_string("c", -435409838, 1), + /* K9 */ be_nested_string("r", -150190315, 1), + /* K10 */ be_nested_string("close", 667630371, 5), + /* K11 */ be_nested_string("file", -1427482813, 4), + /* K12 */ be_nested_string("save", -855671224, 4), + /* K13 */ be_nested_string("log", 1062293841, 3), + /* K14 */ be_nested_string("format", -1180859054, 6), + /* K15 */ be_nested_string("BRY: could not save compiled file %s (%s)", 736659787, 41), + }), + (be_nested_const_str("load", -435725847, 4)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[68]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0x8C0C0501, // 0001 GETMET R3 R2 K1 + 0x5C140200, // 0002 MOVE R5 R1 + 0x58180002, // 0003 LDCONST R6 K2 + 0x7C0C0600, // 0004 CALL R3 3 + 0x6010000C, // 0005 GETGBL R4 G12 + 0x5C140600, // 0006 MOVE R5 R3 + 0x7C100200, // 0007 CALL R4 1 + 0x18100903, // 0008 LE R4 R4 K3 + 0x74120007, // 0009 JMPT R4 #0012 + 0x5411FFFE, // 000A LDINT R4 -1 + 0x94100604, // 000B GETIDX R4 R3 R4 + 0x20100904, // 000C NE R4 R4 K4 + 0x78120004, // 000D JMPF R4 #0013 + 0x5411FFFE, // 000E LDINT R4 -1 + 0x94100604, // 000F GETIDX R4 R3 R4 + 0x20100905, // 0010 NE R4 R4 K5 + 0x78120000, // 0011 JMPF R4 #0013 + 0xB0060D07, // 0012 RAISE 1 K6 K7 + 0x6010000C, // 0013 GETGBL R4 G12 + 0x5C140200, // 0014 MOVE R5 R1 + 0x7C100200, // 0015 CALL R4 1 + 0x04100903, // 0016 SUB R4 R4 K3 + 0x94100204, // 0017 GETIDX R4 R1 R4 + 0x1C100908, // 0018 EQ R4 R4 K8 + 0xA8020007, // 0019 EXBLK 0 #0022 + 0x60140011, // 001A GETGBL R5 G17 + 0x5C180200, // 001B MOVE R6 R1 + 0x581C0009, // 001C LDCONST R7 K9 + 0x7C140400, // 001D CALL R5 2 + 0x8C180B0A, // 001E GETMET R6 R5 K10 + 0x7C180200, // 001F CALL R6 1 + 0xA8040001, // 0020 EXBLK 1 1 + 0x70020006, // 0021 JMP #0029 + 0x58140006, // 0022 LDCONST R5 K6 + 0xAC140200, // 0023 CATCH R5 1 0 + 0x70020002, // 0024 JMP #0028 + 0x50140000, // 0025 LDBOOL R5 0 0 + 0x80040A00, // 0026 RET 1 R5 + 0x70020000, // 0027 JMP #0029 + 0xB0080000, // 0028 RAISE 2 R0 R0 + 0x6014000D, // 0029 GETGBL R5 G13 + 0x5C180200, // 002A MOVE R6 R1 + 0x581C000B, // 002B LDCONST R7 K11 + 0x7C140400, // 002C CALL R5 2 + 0x74120011, // 002D JMPT R4 #0040 + 0xA8020005, // 002E EXBLK 0 #0035 + 0x8C18010C, // 002F GETMET R6 R0 K12 + 0x00200308, // 0030 ADD R8 R1 K8 + 0x5C240A00, // 0031 MOVE R9 R5 + 0x7C180600, // 0032 CALL R6 3 + 0xA8040001, // 0033 EXBLK 1 1 + 0x7002000A, // 0034 JMP #0040 + 0xAC180001, // 0035 CATCH R6 0 1 + 0x70020007, // 0036 JMP #003F + 0x8C1C010D, // 0037 GETMET R7 R0 K13 + 0x8C24050E, // 0038 GETMET R9 R2 K14 + 0x582C000F, // 0039 LDCONST R11 K15 + 0x00300308, // 003A ADD R12 R1 K8 + 0x5C340C00, // 003B MOVE R13 R6 + 0x7C240800, // 003C CALL R9 4 + 0x7C1C0400, // 003D CALL R7 2 + 0x70020000, // 003E JMP #0040 + 0xB0080000, // 003F RAISE 2 R0 R0 + 0x5C180A00, // 0040 MOVE R6 R5 + 0x7C180000, // 0041 CALL R6 0 + 0x50180200, // 0042 LDBOOL R6 1 0 + 0x80040C00, // 0043 RET 1 R6 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: find_op +********************************************************************/ +be_local_closure(find_op, /* name */ + be_nested_proto( + 13, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_string("string", 398550328, 6), + /* K1 */ be_nested_string("=<>!", -1630497019, 4), + /* K2 */ be_nested_string("chars_in_string", -1146182164, 15), + /* K3 */ be_const_int(0), + /* K4 */ be_nested_string("split", -2017972765, 5), + /* K5 */ be_const_int(1), + }), + (be_nested_const_str("find_op", -528253920, 7)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[42]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0x580C0001, // 0001 LDCONST R3 K1 + 0x8C100102, // 0002 GETMET R4 R0 K2 + 0x5C180200, // 0003 MOVE R6 R1 + 0x5C1C0600, // 0004 MOVE R7 R3 + 0x7C100600, // 0005 CALL R4 3 + 0x28140903, // 0006 GE R5 R4 K3 + 0x78160019, // 0007 JMPF R5 #0022 + 0x8C140504, // 0008 GETMET R5 R2 K4 + 0x5C1C0200, // 0009 MOVE R7 R1 + 0x5C200800, // 000A MOVE R8 R4 + 0x7C140600, // 000B CALL R5 3 + 0x94180B03, // 000C GETIDX R6 R5 K3 + 0x941C0B05, // 000D GETIDX R7 R5 K5 + 0x8C200102, // 000E GETMET R8 R0 K2 + 0x5C280E00, // 000F MOVE R10 R7 + 0x5C2C0600, // 0010 MOVE R11 R3 + 0x50300200, // 0011 LDBOOL R12 1 0 + 0x7C200800, // 0012 CALL R8 4 + 0x5C101000, // 0013 MOVE R4 R8 + 0x28200903, // 0014 GE R8 R4 K3 + 0x7822000B, // 0015 JMPF R8 #0022 + 0x8C200504, // 0016 GETMET R8 R2 K4 + 0x5C280E00, // 0017 MOVE R10 R7 + 0x5C2C0800, // 0018 MOVE R11 R4 + 0x7C200600, // 0019 CALL R8 3 + 0x94241103, // 001A GETIDX R9 R8 K3 + 0x94281105, // 001B GETIDX R10 R8 K5 + 0x602C0012, // 001C GETGBL R11 G18 + 0x7C2C0000, // 001D CALL R11 0 + 0x40301606, // 001E CONNECT R12 R11 R6 + 0x40301609, // 001F CONNECT R12 R11 R9 + 0x4030160A, // 0020 CONNECT R12 R11 R10 + 0x80041600, // 0021 RET 1 R11 + 0x60140012, // 0022 GETGBL R5 G18 + 0x7C140000, // 0023 CALL R5 0 + 0x40180A01, // 0024 CONNECT R6 R5 R1 + 0x4C180000, // 0025 LDNIL R6 + 0x40180A06, // 0026 CONNECT R6 R5 R6 + 0x4C180000, // 0027 LDNIL R6 + 0x40180A06, // 0028 CONNECT R6 R5 R6 + 0x80040A00, // 0029 RET 1 R5 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: remove_timer +********************************************************************/ +be_local_closure(remove_timer, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_string("tasmota", 424643812, 7), + /* K1 */ be_nested_string("_timers", -1694866380, 7), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_string("size", 597743964, 4), + /* K4 */ be_nested_string("id", 926444256, 2), + /* K5 */ be_nested_string("remove", -611183107, 6), + /* K6 */ be_const_int(1), + }), + (be_nested_const_str("remove_timer", -153495081, 12)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[23]) { /* code */ + 0xB80A0000, // 0000 GETNGBL R2 K0 + 0x88080501, // 0001 GETMBR R2 R2 K1 + 0x780A0012, // 0002 JMPF R2 #0016 + 0x58080002, // 0003 LDCONST R2 K2 + 0xB80E0000, // 0004 GETNGBL R3 K0 + 0x880C0701, // 0005 GETMBR R3 R3 K1 + 0x8C0C0703, // 0006 GETMET R3 R3 K3 + 0x7C0C0200, // 0007 CALL R3 1 + 0x140C0403, // 0008 LT R3 R2 R3 + 0x780E000B, // 0009 JMPF R3 #0016 + 0x880C0101, // 000A GETMBR R3 R0 K1 + 0x940C0602, // 000B GETIDX R3 R3 R2 + 0x880C0704, // 000C GETMBR R3 R3 K4 + 0x1C0C0601, // 000D EQ R3 R3 R1 + 0x780E0004, // 000E JMPF R3 #0014 + 0x880C0101, // 000F GETMBR R3 R0 K1 + 0x8C0C0705, // 0010 GETMET R3 R3 K5 + 0x5C140400, // 0011 MOVE R5 R2 + 0x7C0C0400, // 0012 CALL R3 2 + 0x70020000, // 0013 JMP #0015 + 0x00080506, // 0014 ADD R2 R2 K6 + 0x7001FFED, // 0015 JMP #0004 + 0x80000000, // 0016 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_light +********************************************************************/ +be_local_closure(get_light, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_string("tasmota.get_light() is deprecated, use light.get()", -769213649, 50), + /* K1 */ be_nested_string("light", -493019601, 5), + /* K2 */ be_nested_string("get", 1410115415, 3), + }), + (be_nested_const_str("get_light", 381930476, 9)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[16]) { /* code */ + 0x60080001, // 0000 GETGBL R2 G1 + 0x580C0000, // 0001 LDCONST R3 K0 + 0x7C080200, // 0002 CALL R2 1 + 0xA40A0200, // 0003 IMPORT R2 K1 + 0x4C0C0000, // 0004 LDNIL R3 + 0x200C0203, // 0005 NE R3 R1 R3 + 0x780E0004, // 0006 JMPF R3 #000C + 0x8C0C0502, // 0007 GETMET R3 R2 K2 + 0x5C140200, // 0008 MOVE R5 R1 + 0x7C0C0400, // 0009 CALL R3 2 + 0x80040600, // 000A RET 1 R3 + 0x70020002, // 000B JMP #000F + 0x8C0C0502, // 000C GETMET R3 R2 K2 + 0x7C0C0200, // 000D CALL R3 1 + 0x80040600, // 000E RET 1 R3 + 0x80000000, // 000F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: exec_rules +********************************************************************/ +be_local_closure(exec_rules, /* name */ + be_nested_proto( + 12, /* nstack */ + 2, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_string("_rules", -28750191, 6), + /* K1 */ be_nested_string("json", 916562499, 4), + /* K2 */ be_nested_string("load", -435725847, 4), + /* K3 */ be_nested_string("BRY: ERROR, bad json: ", -1579831487, 22), + /* K4 */ be_const_int(3), + /* K5 */ be_nested_string("keys", -112588595, 4), + /* K6 */ be_nested_string("try_rule", 1986449405, 8), + /* K7 */ be_nested_string("stop_iteration", -121173395, 14), + }), + (be_nested_const_str("exec_rules", 1445221092, 10)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[40]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A0023, // 0001 JMPF R2 #0026 + 0xA40A0200, // 0002 IMPORT R2 K1 + 0x8C0C0502, // 0003 GETMET R3 R2 K2 + 0x5C140200, // 0004 MOVE R5 R1 + 0x7C0C0400, // 0005 CALL R3 2 + 0x50100000, // 0006 LDBOOL R4 0 0 + 0x4C140000, // 0007 LDNIL R5 + 0x1C140605, // 0008 EQ R5 R3 R5 + 0x78160004, // 0009 JMPF R5 #000F + 0x60140001, // 000A GETGBL R5 G1 + 0x001A0601, // 000B ADD R6 K3 R1 + 0x581C0004, // 000C LDCONST R7 K4 + 0x7C140400, // 000D CALL R5 2 + 0x70020015, // 000E JMP #0025 + 0x60140010, // 000F GETGBL R5 G16 + 0x88180100, // 0010 GETMBR R6 R0 K0 + 0x8C180D05, // 0011 GETMET R6 R6 K5 + 0x7C180200, // 0012 CALL R6 1 + 0x7C140200, // 0013 CALL R5 1 + 0xA802000C, // 0014 EXBLK 0 #0022 + 0x5C180A00, // 0015 MOVE R6 R5 + 0x7C180000, // 0016 CALL R6 0 + 0x8C1C0106, // 0017 GETMET R7 R0 K6 + 0x5C240600, // 0018 MOVE R9 R3 + 0x5C280C00, // 0019 MOVE R10 R6 + 0x882C0100, // 001A GETMBR R11 R0 K0 + 0x942C1606, // 001B GETIDX R11 R11 R6 + 0x7C1C0800, // 001C CALL R7 4 + 0x741E0001, // 001D JMPT R7 #0020 + 0x74120000, // 001E JMPT R4 #0020 + 0x50100001, // 001F LDBOOL R4 0 1 + 0x50100200, // 0020 LDBOOL R4 1 0 + 0x7001FFF2, // 0021 JMP #0015 + 0x58140007, // 0022 LDCONST R5 K7 + 0xAC140200, // 0023 CATCH R5 1 0 + 0xB0080000, // 0024 RAISE 2 R0 R0 + 0x80040800, // 0025 RET 1 R4 + 0x50080000, // 0026 LDBOOL R2 0 0 + 0x80040400, // 0027 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: remove_driver ********************************************************************/ @@ -1481,558 +1063,211 @@ be_local_closure(remove_driver, /* name */ /* K2 */ be_nested_string("pop", 1362321360, 3), }), (be_nested_const_str("remove_driver", 1030243768, 13)), - (be_nested_const_str("input", -103256197, 5)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), ( &(const binstruction[14]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x780A000A, // 0001 JMPF R2 #000D - 0x88080100, // 0002 GETMBR R2 R0 K0 - 0x8C080501, // 0003 GETMET R2 R2 K1 - 0x5C100200, // 0004 MOVE R4 R1 - 0x7C080400, // 0005 CALL R2 2 - 0x4C0C0000, // 0006 LDNIL R3 - 0x200C0403, // 0007 NE R3 R2 R3 - 0x780E0003, // 0008 JMPF R3 #000D - 0x880C0100, // 0009 GETMBR R3 R0 K0 - 0x8C0C0702, // 000A GETMET R3 R3 K2 - 0x5C140400, // 000B MOVE R5 R2 - 0x7C0C0400, // 000C CALL R3 2 - 0x80000000, // 000D RET 0 + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A000A, // 0001 JMPF R2 #000D + 0x88080100, // 0002 GETMBR R2 R0 K0 + 0x8C080501, // 0003 GETMET R2 R2 K1 + 0x5C100200, // 0004 MOVE R4 R1 + 0x7C080400, // 0005 CALL R2 2 + 0x4C0C0000, // 0006 LDNIL R3 + 0x200C0403, // 0007 NE R3 R2 R3 + 0x780E0003, // 0008 JMPF R3 #000D + 0x880C0100, // 0009 GETMBR R3 R0 K0 + 0x8C0C0702, // 000A GETMET R3 R3 K2 + 0x5C140400, // 000B MOVE R5 R2 + 0x7C0C0400, // 000C CALL R3 2 + 0x80000000, // 000D RET 0 }) ) ); /*******************************************************************/ + /******************************************************************** -** Solidified function: load +** Solidified function: try_rule ********************************************************************/ -be_local_closure(load, /* name */ +be_local_closure(try_rule, /* name */ be_nested_proto( 14, /* nstack */ - 2, /* argc */ + 4, /* argc */ 0, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[16]) { /* upvals */ - { { .s=be_nested_const_str("string", 398550328, 6) }, BE_STRING}, - { { .s=be_nested_const_str("split", -2017972765, 5) }, BE_STRING}, - { { .s=be_nested_const_str(".", 722245873, 1) }, BE_STRING}, - { { .i=1 }, BE_INT}, - { { .s=be_nested_const_str("be", 942383232, 2) }, BE_STRING}, - { { .s=be_nested_const_str("bec", 1336821081, 3) }, BE_STRING}, - { { .s=be_nested_const_str("io_error", 1970281036, 8) }, BE_STRING}, - { { .s=be_nested_const_str("file extension is not '.be' or '.bec'", -1199247657, 37) }, BE_STRING}, - { { .s=be_nested_const_str("c", -435409838, 1) }, BE_STRING}, - { { .s=be_nested_const_str("r", -150190315, 1) }, BE_STRING}, - { { .s=be_nested_const_str("close", 667630371, 5) }, BE_STRING}, - { { .s=be_nested_const_str("file", -1427482813, 4) }, BE_STRING}, - { { .s=be_nested_const_str("save", -855671224, 4) }, BE_STRING}, - { { .s=be_nested_const_str("log", 1062293841, 3) }, BE_STRING}, - { { .s=be_nested_const_str("format", -1180859054, 6) }, BE_STRING}, - { { .s=be_nested_const_str("BRY: could not save compiled file %s (%s)", 736659787, 41) }, BE_STRING}, + ( &(const bvalue[17]) { /* constants */ + /* K0 */ be_nested_string("string", 398550328, 6), + /* K1 */ be_nested_string("find_op", -528253920, 7), + /* K2 */ be_nested_string("split", -2017972765, 5), + /* K3 */ be_const_int(0), + /* K4 */ be_nested_string("#", 638357778, 1), + /* K5 */ be_nested_string("find_key_i", 850136726, 10), + /* K6 */ be_nested_string("stop_iteration", -121173395, 14), + /* K7 */ be_const_int(1), + /* K8 */ be_const_int(2), + /* K9 */ be_nested_string("==", -1863000881, 2), + /* K10 */ be_nested_string("!==", 559817114, 3), + /* K11 */ be_nested_string("=", 940354920, 1), + /* K12 */ be_nested_string("!=", -1866252285, 2), + /* K13 */ be_nested_string(">", 990687777, 1), + /* K14 */ be_nested_string(">=", 284975636, 2), + /* K15 */ be_nested_string("<", 957132539, 1), + /* K16 */ be_nested_string("<=", -1795743310, 2), }), - (be_nested_const_str("load", -435725847, 4)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[68]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 R256 - 0x8C0C0501, // 0001 GETMET R3 R2 R257 - 0x5C140200, // 0002 MOVE R5 R1 - 0x58180002, // 0003 LDCONST R6 K2 - 0x7C0C0600, // 0004 CALL R3 3 - 0x60100012, // 0005 GETGBL R4 G18 - 0x5C140600, // 0006 MOVE R5 R3 - 0x7C100200, // 0007 CALL R4 1 - 0x18100903, // 0008 LE R4 R4 R259 - 0x74120007, // 0009 JMPT R4 #0012 - 0x5411FFFE, // 000A LDINT R4 -1 - 0x94100604, // 000B GETIDX R4 R3 R4 - 0x20100904, // 000C NE R4 R4 R260 - 0x78120004, // 000D JMPF R4 #0013 - 0x5411FFFE, // 000E LDINT R4 -1 - 0x94100604, // 000F GETIDX R4 R3 R4 - 0x20100905, // 0010 NE R4 R4 R261 - 0x78120000, // 0011 JMPF R4 #0013 - 0xB0060D07, // 0012 RAISE 1 R262 R263 - 0x60100012, // 0013 GETGBL R4 G18 - 0x5C140200, // 0014 MOVE R5 R1 - 0x7C100200, // 0015 CALL R4 1 - 0x04100903, // 0016 SUB R4 R4 R259 - 0x94100204, // 0017 GETIDX R4 R1 R4 - 0x1C100908, // 0018 EQ R4 R4 R264 - 0xA8020007, // 0019 EXBLK 0 #0022 - 0x6014000E, // 001A GETGBL R5 G14 - 0x5C180200, // 001B MOVE R6 R1 - 0x581C0009, // 001C LDCONST R7 K9 - 0x7C140400, // 001D CALL R5 2 - 0x8C180B0A, // 001E GETMET R6 R5 R266 - 0x7C180200, // 001F CALL R6 1 - 0xA8040001, // 0020 EXBLK 1 1 - 0x70020006, // 0021 JMP #0029 - 0x58140006, // 0022 LDCONST R5 K6 - 0xAC140200, // 0023 CATCH R5 1 0 - 0x70020002, // 0024 JMP #0028 - 0x50140000, // 0025 LDBOOL R5 0 0 - 0x80040A00, // 0026 RET 1 R5 - 0x70020000, // 0027 JMP #0029 - 0xB0080000, // 0028 RAISE 2 R0 R0 - 0x60140005, // 0029 GETGBL R5 G5 - 0x5C180200, // 002A MOVE R6 R1 - 0x581C000B, // 002B LDCONST R7 K11 - 0x7C140400, // 002C CALL R5 2 - 0x74120011, // 002D JMPT R4 #0040 - 0xA8020005, // 002E EXBLK 0 #0035 - 0x8C18010C, // 002F GETMET R6 R0 R268 - 0x00200308, // 0030 ADD R8 R1 R264 - 0x5C240A00, // 0031 MOVE R9 R5 - 0x7C180600, // 0032 CALL R6 3 - 0xA8040001, // 0033 EXBLK 1 1 - 0x7002000A, // 0034 JMP #0040 - 0xAC180001, // 0035 CATCH R6 0 1 - 0x70020007, // 0036 JMP #003F - 0x8C1C010D, // 0037 GETMET R7 R0 R269 - 0x8C24050E, // 0038 GETMET R9 R2 R270 - 0x582C000F, // 0039 LDCONST R11 K15 - 0x00300308, // 003A ADD R12 R1 R264 - 0x5C340C00, // 003B MOVE R13 R6 - 0x7C240800, // 003C CALL R9 4 - 0x7C1C0400, // 003D CALL R7 2 - 0x70020000, // 003E JMP #0040 - 0xB0080000, // 003F RAISE 2 R0 R0 - 0x5C180A00, // 0040 MOVE R6 R5 - 0x7C180000, // 0041 CALL R6 0 - 0x50180200, // 0042 LDBOOL R6 1 0 - 0x80040C00, // 0043 RET 1 R6 + (be_nested_const_str("try_rule", 1986449405, 8)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[143]) { /* code */ + 0xA4120000, // 0000 IMPORT R4 K0 + 0x8C140101, // 0001 GETMET R5 R0 K1 + 0x5C1C0400, // 0002 MOVE R7 R2 + 0x7C140400, // 0003 CALL R5 2 + 0x5C180200, // 0004 MOVE R6 R1 + 0x8C1C0902, // 0005 GETMET R7 R4 K2 + 0x94240B03, // 0006 GETIDX R9 R5 K3 + 0x58280004, // 0007 LDCONST R10 K4 + 0x7C1C0600, // 0008 CALL R7 3 + 0x60200010, // 0009 GETGBL R8 G16 + 0x5C240E00, // 000A MOVE R9 R7 + 0x7C200200, // 000B CALL R8 1 + 0xA802000D, // 000C EXBLK 0 #001B + 0x5C241000, // 000D MOVE R9 R8 + 0x7C240000, // 000E CALL R9 0 + 0x8C280105, // 000F GETMET R10 R0 K5 + 0x5C300C00, // 0010 MOVE R12 R6 + 0x5C341200, // 0011 MOVE R13 R9 + 0x7C280600, // 0012 CALL R10 3 + 0x4C2C0000, // 0013 LDNIL R11 + 0x1C2C140B, // 0014 EQ R11 R10 R11 + 0x782E0002, // 0015 JMPF R11 #0019 + 0x502C0000, // 0016 LDBOOL R11 0 0 + 0xA8040001, // 0017 EXBLK 1 1 + 0x80041600, // 0018 RET 1 R11 + 0x94180C0A, // 0019 GETIDX R6 R6 R10 + 0x7001FFF1, // 001A JMP #000D + 0x58200006, // 001B LDCONST R8 K6 + 0xAC200200, // 001C CATCH R8 1 0 + 0xB0080000, // 001D RAISE 2 R0 R0 + 0x94200B07, // 001E GETIDX R8 R5 K7 + 0x94240B08, // 001F GETIDX R9 R5 K8 + 0x78220066, // 0020 JMPF R8 #0088 + 0x1C281109, // 0021 EQ R10 R8 K9 + 0x782A000A, // 0022 JMPF R10 #002E + 0x60280008, // 0023 GETGBL R10 G8 + 0x5C2C0C00, // 0024 MOVE R11 R6 + 0x7C280200, // 0025 CALL R10 1 + 0x602C0008, // 0026 GETGBL R11 G8 + 0x5C301200, // 0027 MOVE R12 R9 + 0x7C2C0200, // 0028 CALL R11 1 + 0x2028140B, // 0029 NE R10 R10 R11 + 0x782A0001, // 002A JMPF R10 #002D + 0x50280000, // 002B LDBOOL R10 0 0 + 0x80041400, // 002C RET 1 R10 + 0x70020059, // 002D JMP #0088 + 0x1C28110A, // 002E EQ R10 R8 K10 + 0x782A000A, // 002F JMPF R10 #003B + 0x60280008, // 0030 GETGBL R10 G8 + 0x5C2C0C00, // 0031 MOVE R11 R6 + 0x7C280200, // 0032 CALL R10 1 + 0x602C0008, // 0033 GETGBL R11 G8 + 0x5C301200, // 0034 MOVE R12 R9 + 0x7C2C0200, // 0035 CALL R11 1 + 0x1C28140B, // 0036 EQ R10 R10 R11 + 0x782A0001, // 0037 JMPF R10 #003A + 0x50280000, // 0038 LDBOOL R10 0 0 + 0x80041400, // 0039 RET 1 R10 + 0x7002004C, // 003A JMP #0088 + 0x1C28110B, // 003B EQ R10 R8 K11 + 0x782A000A, // 003C JMPF R10 #0048 + 0x6028000A, // 003D GETGBL R10 G10 + 0x5C2C0C00, // 003E MOVE R11 R6 + 0x7C280200, // 003F CALL R10 1 + 0x602C000A, // 0040 GETGBL R11 G10 + 0x5C301200, // 0041 MOVE R12 R9 + 0x7C2C0200, // 0042 CALL R11 1 + 0x2028140B, // 0043 NE R10 R10 R11 + 0x782A0001, // 0044 JMPF R10 #0047 + 0x50280000, // 0045 LDBOOL R10 0 0 + 0x80041400, // 0046 RET 1 R10 + 0x7002003F, // 0047 JMP #0088 + 0x1C28110C, // 0048 EQ R10 R8 K12 + 0x782A000A, // 0049 JMPF R10 #0055 + 0x6028000A, // 004A GETGBL R10 G10 + 0x5C2C0C00, // 004B MOVE R11 R6 + 0x7C280200, // 004C CALL R10 1 + 0x602C000A, // 004D GETGBL R11 G10 + 0x5C301200, // 004E MOVE R12 R9 + 0x7C2C0200, // 004F CALL R11 1 + 0x1C28140B, // 0050 EQ R10 R10 R11 + 0x782A0001, // 0051 JMPF R10 #0054 + 0x50280000, // 0052 LDBOOL R10 0 0 + 0x80041400, // 0053 RET 1 R10 + 0x70020032, // 0054 JMP #0088 + 0x1C28110D, // 0055 EQ R10 R8 K13 + 0x782A000A, // 0056 JMPF R10 #0062 + 0x6028000A, // 0057 GETGBL R10 G10 + 0x5C2C0C00, // 0058 MOVE R11 R6 + 0x7C280200, // 0059 CALL R10 1 + 0x602C000A, // 005A GETGBL R11 G10 + 0x5C301200, // 005B MOVE R12 R9 + 0x7C2C0200, // 005C CALL R11 1 + 0x1828140B, // 005D LE R10 R10 R11 + 0x782A0001, // 005E JMPF R10 #0061 + 0x50280000, // 005F LDBOOL R10 0 0 + 0x80041400, // 0060 RET 1 R10 + 0x70020025, // 0061 JMP #0088 + 0x1C28110E, // 0062 EQ R10 R8 K14 + 0x782A000A, // 0063 JMPF R10 #006F + 0x6028000A, // 0064 GETGBL R10 G10 + 0x5C2C0C00, // 0065 MOVE R11 R6 + 0x7C280200, // 0066 CALL R10 1 + 0x602C000A, // 0067 GETGBL R11 G10 + 0x5C301200, // 0068 MOVE R12 R9 + 0x7C2C0200, // 0069 CALL R11 1 + 0x1428140B, // 006A LT R10 R10 R11 + 0x782A0001, // 006B JMPF R10 #006E + 0x50280000, // 006C LDBOOL R10 0 0 + 0x80041400, // 006D RET 1 R10 + 0x70020018, // 006E JMP #0088 + 0x1C28110F, // 006F EQ R10 R8 K15 + 0x782A000A, // 0070 JMPF R10 #007C + 0x6028000A, // 0071 GETGBL R10 G10 + 0x5C2C0C00, // 0072 MOVE R11 R6 + 0x7C280200, // 0073 CALL R10 1 + 0x602C000A, // 0074 GETGBL R11 G10 + 0x5C301200, // 0075 MOVE R12 R9 + 0x7C2C0200, // 0076 CALL R11 1 + 0x2828140B, // 0077 GE R10 R10 R11 + 0x782A0001, // 0078 JMPF R10 #007B + 0x50280000, // 0079 LDBOOL R10 0 0 + 0x80041400, // 007A RET 1 R10 + 0x7002000B, // 007B JMP #0088 + 0x1C281110, // 007C EQ R10 R8 K16 + 0x782A0009, // 007D JMPF R10 #0088 + 0x6028000A, // 007E GETGBL R10 G10 + 0x5C2C0C00, // 007F MOVE R11 R6 + 0x7C280200, // 0080 CALL R10 1 + 0x602C000A, // 0081 GETGBL R11 G10 + 0x5C301200, // 0082 MOVE R12 R9 + 0x7C2C0200, // 0083 CALL R11 1 + 0x2428140B, // 0084 GT R10 R10 R11 + 0x782A0001, // 0085 JMPF R10 #0088 + 0x50280000, // 0086 LDBOOL R10 0 0 + 0x80041400, // 0087 RET 1 R10 + 0x5C280600, // 0088 MOVE R10 R3 + 0x5C2C0C00, // 0089 MOVE R11 R6 + 0x94300B03, // 008A GETIDX R12 R5 K3 + 0x5C340200, // 008B MOVE R13 R1 + 0x7C280600, // 008C CALL R10 3 + 0x50280200, // 008D LDBOOL R10 1 0 + 0x80041400, // 008E RET 1 R10 }) ) ); /*******************************************************************/ -/******************************************************************** - // tasmota.wire_scan(addr:int [, index:int]) -> wire1 or wire2 or nil - // scan for the first occurrence of the addr, starting with bus1 then bus2 - // optional: skip if index is disabled via I2CEnable - "def wire_scan(addr,idx) " - // skip if the I2C index is disabled - "if idx != nil && !self.i2c_enabled(idx) return nil end " - "if self.wire1.detect(addr) return self.wire1 end " - "if self.wire2.detect(addr) return self.wire2 end " - "return nil " - "end " -********************************************************************/ -/******************************************************************** -** Solidified function: wire_scan -********************************************************************/ - -be_define_local_const_str(wire_scan_str_name, "wire_scan", -1623691416, 9); -be_define_local_const_str(wire_scan_str_source, "string", 398550328, 6); -be_define_local_const_str(wire_scan_str_0, "i2c_enabled", 218388101, 11); -be_define_local_const_str(wire_scan_str_1, "wire1", -1082245877, 5); -be_define_local_const_str(wire_scan_str_2, "detect", 8884370, 6); -be_define_local_const_str(wire_scan_str_3, "wire2", -1065468258, 5); - -static const bvalue wire_scan_ktab[4] = { - { { .s=be_local_const_str(wire_scan_str_0) }, BE_STRING}, - { { .s=be_local_const_str(wire_scan_str_1) }, BE_STRING}, - { { .s=be_local_const_str(wire_scan_str_2) }, BE_STRING}, - { { .s=be_local_const_str(wire_scan_str_3) }, BE_STRING}, -}; - -static const uint32_t wire_scan_code[25] = { - 0x4C0C0000, // 0000 LDNIL 3 - 0x200C0403, // 0001 NE R3 R2 R3 - 0x780E0005, // 0002 JMPF R3 #0009 - 0x8C0C0100, // 0003 GETMET R3 R0 R256 - 0x5C140400, // 0004 MOVE R5 R2 - 0x7C0C0400, // 0005 CALL R3 2 - 0x740E0001, // 0006 JMPT R3 #0009 - 0x4C0C0000, // 0007 LDNIL 3 - 0x80040600, // 0008 RET 1 R3 - 0x880C0101, // 0009 GETMBR R3 R0 R257 - 0x8C0C0702, // 000A GETMET R3 R3 R258 - 0x5C140200, // 000B MOVE R5 R1 - 0x7C0C0400, // 000C CALL R3 2 - 0x780E0001, // 000D JMPF R3 #0010 - 0x880C0101, // 000E GETMBR R3 R0 R257 - 0x80040600, // 000F RET 1 R3 - 0x880C0103, // 0010 GETMBR R3 R0 R259 - 0x8C0C0702, // 0011 GETMET R3 R3 R258 - 0x5C140200, // 0012 MOVE R5 R1 - 0x7C0C0400, // 0013 CALL R3 2 - 0x780E0001, // 0014 JMPF R3 #0017 - 0x880C0103, // 0015 GETMBR R3 R0 R259 - 0x80040600, // 0016 RET 1 R3 - 0x4C0C0000, // 0017 LDNIL 3 - 0x80040600, // 0018 RET 1 R3 -}; - -static const bproto wire_scan_proto = { - NULL, // bgcobject *next - 8, // type - 0x08, // marked - 6, // nstack - 0, // nupvals - 3, // argc - 0, // varg - NULL, // bgcobject *gray - NULL, // bupvaldesc *upvals - (bvalue*) &wire_scan_ktab, // ktab - NULL, // bproto **ptab - (binstruction*) &wire_scan_code, // code - be_local_const_str(wire_scan_str_name), // name - 25, // codesize - 4, // nconst - 0, // nproto - be_local_const_str(wire_scan_str_source), // source -#if BE_DEBUG_RUNTIME_INFO /* debug information */ - NULL, // lineinfo - 0, // nlineinfo -#endif -#if BE_DEBUG_VAR_INFO - NULL, // varinfo - 0, // nvarinfo -#endif -}; - -static const bclosure wire_scan_closure = { - NULL, // bgcobject *next - 36, // type - 0x08, // marked - 0, // nupvals - NULL, // bgcobject *gray - (bproto*) &wire_scan_proto, // proto - { NULL } // upvals -}; - -/*******************************************************************/ - -/******************************************************************** - def time_str(time) - import string - var tm = self.time_dump(time) - return string.format("%04d-%02d-%02dT%02d:%02d:%02d", tm['year'], tm['month'], tm['day'], tm['hour'], tm['min'], tm['sec']) - end -********************************************************************/ -/******************************************************************** -** Solidified function: time_str -********************************************************************/ -be_local_closure(time_str, /* name */ - be_nested_proto( - 13, /* nstack */ - 2, /* argc */ - 0, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - be_nested_string("string", 398550328, 6), - be_nested_string("time_dump", -964556549, 9), - be_nested_string("format", -1180859054, 6), - be_nested_string("%04d-%02d-%02dT%02d:%02d:%02d", -869438695, 29), - be_nested_string("year", -1367388900, 4), - be_nested_string("month", -696646139, 5), - be_nested_string("day", -464576003, 3), - be_nested_string("hour", -1241306097, 4), - be_nested_string("min", -913357481, 3), - be_nested_string("sec", -1155074638, 3), - }), - (be_nested_const_str("time_str", -1681139684, 8)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[14]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 R256 - 0x8C0C0101, // 0001 GETMET R3 R0 R257 - 0x5C140200, // 0002 MOVE R5 R1 - 0x7C0C0400, // 0003 CALL R3 2 - 0x8C100502, // 0004 GETMET R4 R2 R258 - 0x58180003, // 0005 LDCONST R6 K3 - 0x941C0704, // 0006 GETIDX R7 R3 R260 - 0x94200705, // 0007 GETIDX R8 R3 R261 - 0x94240706, // 0008 GETIDX R9 R3 R262 - 0x94280707, // 0009 GETIDX R10 R3 R263 - 0x942C0708, // 000A GETIDX R11 R3 R264 - 0x94300709, // 000B GETIDX R12 R3 R265 - 0x7C101000, // 000C CALL R4 8 - 0x80040800, // 000D RET 1 R4 - }) - ) -); -/*******************************************************************/ - -/******************************************************************** - // cmd high-level function - "def cmd(command) " - "import json " - "var ret = self._cmd(command) " - "var j = json.load(ret) " - "if type(j) == 'instance' " - "return j " - "else " - "return {'response':j} " - "end " - "end " -********************************************************************/ -/******************************************************************** -** Solidified function: cmd -********************************************************************/ - -be_define_local_const_str(cmd_str_name, "cmd", -158181397, 3); -be_define_local_const_str(cmd_str_source, "string", 398550328, 6); -be_define_local_const_str(cmd_str_0, "json", 916562499, 4); -be_define_local_const_str(cmd_str_1, "_cmd", -875145154, 4); -be_define_local_const_str(cmd_str_2, "load", -435725847, 4); -be_define_local_const_str(cmd_str_3, "instance", 193386898, 8); -be_define_local_const_str(cmd_str_4, "response", 1499316702, 8); - -static const bvalue cmd_ktab[5] = { - { { .s=be_local_const_str(cmd_str_0) }, BE_STRING}, - { { .s=be_local_const_str(cmd_str_1) }, BE_STRING}, - { { .s=be_local_const_str(cmd_str_2) }, BE_STRING}, - { { .s=be_local_const_str(cmd_str_3) }, BE_STRING}, - { { .s=be_local_const_str(cmd_str_4) }, BE_STRING}, -}; - -static const uint32_t cmd_code[19] = { - 0xA40A0000, // 0000 IMPORT R2 R256 - 0x8C0C0101, // 0001 GETMET R3 R0 R257 - 0x5C140200, // 0002 MOVE R5 R1 - 0x7C0C0400, // 0003 CALL R3 2 - 0x8C100502, // 0004 GETMET R4 R2 R258 - 0x5C180600, // 0005 MOVE R6 R3 - 0x7C100400, // 0006 CALL R4 2 - 0x60140015, // 0007 GETGBL R5 G21 - 0x5C180800, // 0008 MOVE R6 R4 - 0x7C140200, // 0009 CALL R5 1 - 0x1C140B03, // 000A EQ R5 R5 R259 - 0x78160001, // 000B JMPF R5 #000E - 0x80040800, // 000C RET 1 R4 - 0x70020003, // 000D JMP #0012 - 0x6014000B, // 000E GETGBL R5 G11 - 0x7C140000, // 000F CALL R5 0 - 0x98160804, // 0010 SETIDX R5 R260 R4 - 0x80040A00, // 0011 RET 1 R5 - 0x80000000, // 0012 RET 0 R0 -}; - -static const bproto cmd_proto = { - NULL, // bgcobject *next - 8, // type - 0x08, // marked - 7, // nstack - 0, // nupvals - 2, // argc - 0, // varg - NULL, // bgcobject *gray - NULL, // bupvaldesc *upvals - (bvalue*) &cmd_ktab, // ktab - NULL, // bproto **ptab - (binstruction*) &cmd_code, // code - be_local_const_str(cmd_str_name), // name - 19, // codesize - 5, // nconst - 0, // nproto - be_local_const_str(cmd_str_source), // source -#if BE_DEBUG_RUNTIME_INFO /* debug information */ - NULL, // lineinfo - 0, // nlineinfo -#endif -#if BE_DEBUG_VAR_INFO - NULL, // varinfo - 0, // nvarinfo -#endif -}; - -static const bclosure cmd_closure = { - NULL, // bgcobject *next - 36, // type - 0x08, // marked - 0, // nupvals - NULL, // bgcobject *gray - (bproto*) &cmd_proto, // proto - { NULL } // upvals -}; - -/*******************************************************************/ - - -/******************************************************************** - "def get_light(l) " - "print('tasmota.get_light() is deprecated, use light.get()') " - "import light " - "if l != nil " - "return light.get(l) " - "else " - "return light.get() " - "end " - "end " -********************************************************************/ -/******************************************************************** -** Solidified function: get_light -********************************************************************/ - -be_define_local_const_str(get_light_str_name, "get_light", 381930476, 9); -be_define_local_const_str(get_light_str_source, "string", 398550328, 6); -be_define_local_const_str(get_light_str_0, "tasmota.get_light() is deprecated, use light.get()", -769213649, 50); -be_define_local_const_str(get_light_str_1, "light", -493019601, 5); -be_define_local_const_str(get_light_str_2, "get", 1410115415, 3); - -static const bvalue get_light_ktab[3] = { - { { .s=be_local_const_str(get_light_str_0) }, BE_STRING}, - { { .s=be_local_const_str(get_light_str_1) }, BE_STRING}, - { { .s=be_local_const_str(get_light_str_2) }, BE_STRING}, -}; - -static const uint32_t get_light_code[16] = { - 0x6008000F, // 0000 GETGBL R2 G15 - 0x580C0000, // 0001 LDCONST R3 K0 - 0x7C080200, // 0002 CALL R2 1 - 0xA40A0200, // 0003 IMPORT R2 R257 - 0x4C0C0000, // 0004 LDNIL 3 - 0x200C0203, // 0005 NE R3 R1 R3 - 0x780E0004, // 0006 JMPF R3 #000C - 0x8C0C0502, // 0007 GETMET R3 R2 R258 - 0x5C140200, // 0008 MOVE R5 R1 - 0x7C0C0400, // 0009 CALL R3 2 - 0x80040600, // 000A RET 1 R3 - 0x70020002, // 000B JMP #000F - 0x8C0C0502, // 000C GETMET R3 R2 R258 - 0x7C0C0200, // 000D CALL R3 1 - 0x80040600, // 000E RET 1 R3 - 0x80000000, // 000F RET 0 R0 -}; - -static const bproto get_light_proto = { - NULL, // bgcobject *next - 8, // type - 0x08, // marked - 6, // nstack - 0, // nupvals - 2, // argc - 0, // varg - NULL, // bgcobject *gray - NULL, // bupvaldesc *upvals - (bvalue*) &get_light_ktab, // ktab - NULL, // bproto **ptab - (binstruction*) &get_light_code, // code - be_local_const_str(get_light_str_name), // name - 16, // codesize - 3, // nconst - 0, // nproto - be_local_const_str(get_light_str_source), // source -#if BE_DEBUG_RUNTIME_INFO /* debug information */ - NULL, // lineinfo - 0, // nlineinfo -#endif -#if BE_DEBUG_VAR_INFO - NULL, // varinfo - 0, // nvarinfo -#endif -}; - -static const bclosure get_light_closure = { - NULL, // bgcobject *next - 36, // type - 0x08, // marked - 0, // nupvals - NULL, // bgcobject *gray - (bproto*) &get_light_proto, // proto - { NULL } // upvals -}; - -/*******************************************************************/ - -/******************************************************************** - - // set_light and get_light deprecetaion - "def set_light(v,l) " - "print('tasmota.set_light() is deprecated, use light.set()') " - "import light " - "if l != nil " - "return light.set(v,l) " - "else " - "return light.set(v) " - "end " - "end " - -********************************************************************/ -/******************************************************************** -** Solidified function: set_light -********************************************************************/ - -be_define_local_const_str(set_light_str_name, "set_light", -1118891144, 9); -be_define_local_const_str(set_light_str_source, "string", 398550328, 6); -be_define_local_const_str(set_light_str_0, "tasmota.set_light() is deprecated, use light.set()", 2124937871, 50); -be_define_local_const_str(set_light_str_1, "light", -493019601, 5); -be_define_local_const_str(set_light_str_2, "set", -970520829, 3); - -static const bvalue set_light_ktab[3] = { - { { .s=be_local_const_str(set_light_str_0) }, BE_STRING}, - { { .s=be_local_const_str(set_light_str_1) }, BE_STRING}, - { { .s=be_local_const_str(set_light_str_2) }, BE_STRING}, -}; - -static const uint32_t set_light_code[18] = { - 0x600C000F, // 0000 GETGBL R3 G15 - 0x58100000, // 0001 LDCONST R4 K0 - 0x7C0C0200, // 0002 CALL R3 1 - 0xA40E0200, // 0003 IMPORT R3 R257 - 0x4C100000, // 0004 LDNIL 4 - 0x20100404, // 0005 NE R4 R2 R4 - 0x78120005, // 0006 JMPF R4 #000D - 0x8C100702, // 0007 GETMET R4 R3 R258 - 0x5C180200, // 0008 MOVE R6 R1 - 0x5C1C0400, // 0009 MOVE R7 R2 - 0x7C100600, // 000A CALL R4 3 - 0x80040800, // 000B RET 1 R4 - 0x70020003, // 000C JMP #0011 - 0x8C100702, // 000D GETMET R4 R3 R258 - 0x5C180200, // 000E MOVE R6 R1 - 0x7C100400, // 000F CALL R4 2 - 0x80040800, // 0010 RET 1 R4 - 0x80000000, // 0011 RET 0 R0 -}; - -static const bproto set_light_proto = { - NULL, // bgcobject *next - 8, // type - 0x08, // marked - 8, // nstack - 0, // nupvals - 3, // argc - 0, // varg - NULL, // bgcobject *gray - NULL, // bupvaldesc *upvals - (bvalue*) &set_light_ktab, // ktab - NULL, // bproto **ptab - (binstruction*) &set_light_code, // code - be_local_const_str(set_light_str_name), // name - 18, // codesize - 3, // nconst - 0, // nproto - be_local_const_str(set_light_str_source), // source -#if BE_DEBUG_RUNTIME_INFO /* debug information */ - NULL, // lineinfo - 0, // nlineinfo -#endif -#if BE_DEBUG_VAR_INFO - NULL, // varinfo - 0, // nvarinfo -#endif -}; - -static const bclosure set_light_closure = { - NULL, // bgcobject *next - 36, // type - 0x08, // marked - 0, // nupvals - NULL, // bgcobject *gray - (bproto*) &set_light_proto, // proto - { NULL } // upvals -}; - -/*******************************************************************/ /******************************************************************** ** Solidified function: cb_dispatch @@ -2048,44 +1283,196 @@ be_local_closure(cb_dispatch, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 3]) { /* constants */ - be_nested_string("_cb", -251666929, 3), - be_const_int(0), - be_nested_string("find", -1108310694, 4), + /* K0 */ be_nested_string("_cb", -251666929, 3), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_string("find", -1108310694, 4), }), (be_nested_const_str("cb_dispatch", 1741510499, 11)), - (be_nested_const_str("input", -103256197, 5)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), ( &(const binstruction[20]) { /* code */ - 0x88180100, // 0000 GETMBR R6 R0 R256 - 0x4C1C0000, // 0001 LDNIL 7 - 0x1C180C07, // 0002 EQ R6 R6 R7 - 0x781A0000, // 0003 JMPF R6 #0005 - 0x80060200, // 0004 RET 1 R257 - 0x88180100, // 0005 GETMBR R6 R0 R256 - 0x8C180D02, // 0006 GETMET R6 R6 R258 - 0x5C200200, // 0007 MOVE R8 R1 - 0x7C180400, // 0008 CALL R6 2 - 0x4C1C0000, // 0009 LDNIL 7 - 0x201C0C07, // 000A NE R7 R6 R7 - 0x781E0006, // 000B JMPF R7 #0013 - 0x5C1C0C00, // 000C MOVE R7 R6 - 0x5C200400, // 000D MOVE R8 R2 - 0x5C240600, // 000E MOVE R9 R3 - 0x5C280800, // 000F MOVE R10 R4 - 0x5C2C0A00, // 0010 MOVE R11 R5 - 0x7C1C0800, // 0011 CALL R7 4 - 0x80040E00, // 0012 RET 1 R7 - 0x80060200, // 0013 RET 1 R257 + 0x88180100, // 0000 GETMBR R6 R0 K0 + 0x4C1C0000, // 0001 LDNIL R7 + 0x1C180C07, // 0002 EQ R6 R6 R7 + 0x781A0000, // 0003 JMPF R6 #0005 + 0x80060200, // 0004 RET 1 K1 + 0x88180100, // 0005 GETMBR R6 R0 K0 + 0x8C180D02, // 0006 GETMET R6 R6 K2 + 0x5C200200, // 0007 MOVE R8 R1 + 0x7C180400, // 0008 CALL R6 2 + 0x4C1C0000, // 0009 LDNIL R7 + 0x201C0C07, // 000A NE R7 R6 R7 + 0x781E0006, // 000B JMPF R7 #0013 + 0x5C1C0C00, // 000C MOVE R7 R6 + 0x5C200400, // 000D MOVE R8 R2 + 0x5C240600, // 000E MOVE R9 R3 + 0x5C280800, // 000F MOVE R10 R4 + 0x5C2C0A00, // 0010 MOVE R11 R5 + 0x7C1C0800, // 0011 CALL R7 4 + 0x80040E00, // 0012 RET 1 R7 + 0x80060200, // 0013 RET 1 K1 }) ) ); /*******************************************************************/ + /******************************************************************** -** Solidified function: gen_cb +** Solidified function: gc ********************************************************************/ -be_local_closure(gen_cb, /* name */ +be_local_closure(gc, /* name */ be_nested_proto( - 7, /* nstack */ + 4, /* nstack */ + 1, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_string("gc", 1042313471, 2), + /* K1 */ be_nested_string("collect", -1895928271, 7), + /* K2 */ be_nested_string("allocated", 429986098, 9), + }), + (be_nested_const_str("gc", 1042313471, 2)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[ 6]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080301, // 0001 GETMET R2 R1 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C080302, // 0003 GETMET R2 R1 K2 + 0x7C080200, // 0004 CALL R2 1 + 0x80040400, // 0005 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: event +********************************************************************/ +be_local_closure(event, /* name */ + be_nested_proto( + 19, /* nstack */ + 6, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[15]) { /* constants */ + /* K0 */ be_nested_string("introspect", 164638290, 10), + /* K1 */ be_nested_string("every_50ms", -1911083288, 10), + /* K2 */ be_nested_string("run_deferred", 371594696, 12), + /* K3 */ be_nested_string("cmd", -158181397, 3), + /* K4 */ be_nested_string("exec_cmd", 493567399, 8), + /* K5 */ be_nested_string("rule", -64077613, 4), + /* K6 */ be_nested_string("exec_rules", 1445221092, 10), + /* K7 */ be_nested_string("gc", 1042313471, 2), + /* K8 */ be_nested_string("_drivers", -1034638311, 8), + /* K9 */ be_nested_string("get", 1410115415, 3), + /* K10 */ be_nested_string("function", -1630125495, 8), + /* K11 */ be_nested_string("string", 398550328, 6), + /* K12 */ be_nested_string("format", -1180859054, 6), + /* K13 */ be_nested_string("BRY: Exception> '%s' - %s", -2047976332, 25), + /* K14 */ be_nested_string("stop_iteration", -121173395, 14), + }), + (be_nested_const_str("event", -30355297, 5)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[79]) { /* code */ + 0xA41A0000, // 0000 IMPORT R6 K0 + 0x1C1C0301, // 0001 EQ R7 R1 K1 + 0x781E0001, // 0002 JMPF R7 #0005 + 0x8C1C0102, // 0003 GETMET R7 R0 K2 + 0x7C1C0200, // 0004 CALL R7 1 + 0x1C1C0303, // 0005 EQ R7 R1 K3 + 0x781E0006, // 0006 JMPF R7 #000E + 0x8C1C0104, // 0007 GETMET R7 R0 K4 + 0x5C240400, // 0008 MOVE R9 R2 + 0x5C280600, // 0009 MOVE R10 R3 + 0x5C2C0800, // 000A MOVE R11 R4 + 0x7C1C0800, // 000B CALL R7 4 + 0x80040E00, // 000C RET 1 R7 + 0x7002003F, // 000D JMP #004E + 0x1C1C0305, // 000E EQ R7 R1 K5 + 0x781E0004, // 000F JMPF R7 #0015 + 0x8C1C0106, // 0010 GETMET R7 R0 K6 + 0x5C240800, // 0011 MOVE R9 R4 + 0x7C1C0400, // 0012 CALL R7 2 + 0x80040E00, // 0013 RET 1 R7 + 0x70020038, // 0014 JMP #004E + 0x1C1C0307, // 0015 EQ R7 R1 K7 + 0x781E0003, // 0016 JMPF R7 #001B + 0x8C1C0107, // 0017 GETMET R7 R0 K7 + 0x7C1C0200, // 0018 CALL R7 1 + 0x80040E00, // 0019 RET 1 R7 + 0x70020032, // 001A JMP #004E + 0x881C0108, // 001B GETMBR R7 R0 K8 + 0x781E0030, // 001C JMPF R7 #004E + 0x601C0010, // 001D GETGBL R7 G16 + 0x88200108, // 001E GETMBR R8 R0 K8 + 0x7C1C0200, // 001F CALL R7 1 + 0xA8020027, // 0020 EXBLK 0 #0049 + 0x5C200E00, // 0021 MOVE R8 R7 + 0x7C200000, // 0022 CALL R8 0 + 0x8C240D09, // 0023 GETMET R9 R6 K9 + 0x5C2C1000, // 0024 MOVE R11 R8 + 0x5C300200, // 0025 MOVE R12 R1 + 0x7C240600, // 0026 CALL R9 3 + 0x60280004, // 0027 GETGBL R10 G4 + 0x5C2C1200, // 0028 MOVE R11 R9 + 0x7C280200, // 0029 CALL R10 1 + 0x1C28150A, // 002A EQ R10 R10 K10 + 0x782A001B, // 002B JMPF R10 #0048 + 0xA802000E, // 002C EXBLK 0 #003C + 0x5C281200, // 002D MOVE R10 R9 + 0x5C2C1000, // 002E MOVE R11 R8 + 0x5C300400, // 002F MOVE R12 R2 + 0x5C340600, // 0030 MOVE R13 R3 + 0x5C380800, // 0031 MOVE R14 R4 + 0x5C3C0A00, // 0032 MOVE R15 R5 + 0x7C280A00, // 0033 CALL R10 5 + 0x502C0200, // 0034 LDBOOL R11 1 0 + 0x1C2C140B, // 0035 EQ R11 R10 R11 + 0x782E0002, // 0036 JMPF R11 #003A + 0x502C0200, // 0037 LDBOOL R11 1 0 + 0xA8040002, // 0038 EXBLK 1 2 + 0x80041600, // 0039 RET 1 R11 + 0xA8040001, // 003A EXBLK 1 1 + 0x7002000B, // 003B JMP #0048 + 0xAC280002, // 003C CATCH R10 0 2 + 0x70020008, // 003D JMP #0047 + 0xA4321600, // 003E IMPORT R12 K11 + 0x60340001, // 003F GETGBL R13 G1 + 0x8C38190C, // 0040 GETMET R14 R12 K12 + 0x5840000D, // 0041 LDCONST R16 K13 + 0x5C441400, // 0042 MOVE R17 R10 + 0x5C481600, // 0043 MOVE R18 R11 + 0x7C380800, // 0044 CALL R14 4 + 0x7C340200, // 0045 CALL R13 1 + 0x70020000, // 0046 JMP #0048 + 0xB0080000, // 0047 RAISE 2 R0 R0 + 0x7001FFD7, // 0048 JMP #0021 + 0x581C000E, // 0049 LDCONST R7 K14 + 0xAC1C0200, // 004A CATCH R7 1 0 + 0xB0080000, // 004B RAISE 2 R0 R0 + 0x501C0000, // 004C LDBOOL R7 0 0 + 0x80040E00, // 004D RET 1 R7 + 0x80000000, // 004E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: remove_cmd +********************************************************************/ +be_local_closure(remove_cmd, /* name */ + be_nested_proto( + 5, /* nstack */ 2, /* argc */ 0, /* varg */ 0, /* has upvals */ @@ -2093,52 +1480,76 @@ be_local_closure(gen_cb, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - be_nested_string("_cb", -251666929, 3), - be_const_int(0), - be_nested_string("find", -1108310694, 4), - be_nested_string("_get_cb", 1448849122, 7), - be_nested_string("stop_iteration", -121173395, 14), - be_nested_string("internal_error", -1775809127, 14), - be_nested_string("No callback available", 633786138, 21), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_string("_ccmd", -2131545883, 5), + /* K1 */ be_nested_string("remove", -611183107, 6), }), - (be_nested_const_str("gen_cb", -1049739745, 6)), - (be_nested_const_str("input", -103256197, 5)), - ( &(const binstruction[34]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 R256 - 0x4C0C0000, // 0001 LDNIL 3 - 0x1C080403, // 0002 EQ R2 R2 R3 - 0x780A0002, // 0003 JMPF R2 #0007 - 0x6008000B, // 0004 GETGBL R2 G11 - 0x7C080000, // 0005 CALL R2 0 - 0x90020002, // 0006 SETMBR R0 R256 R2 - 0x60080000, // 0007 GETGBL R2 G0 - 0x540E0012, // 0008 LDINT R3 19 - 0x400E0203, // 0009 CONNECT R3 R257 R3 - 0x7C080200, // 000A CALL R2 1 - 0xA8020010, // 000B EXBLK 0 #001D - 0x5C0C0400, // 000C MOVE R3 R2 - 0x7C0C0000, // 000D CALL R3 0 - 0x88100100, // 000E GETMBR R4 R0 R256 - 0x8C100902, // 000F GETMET R4 R4 R258 - 0x5C180600, // 0010 MOVE R6 R3 - 0x7C100400, // 0011 CALL R4 2 - 0x4C140000, // 0012 LDNIL 5 - 0x1C100805, // 0013 EQ R4 R4 R5 - 0x78120006, // 0014 JMPF R4 #001C - 0x88100100, // 0015 GETMBR R4 R0 R256 - 0x98100601, // 0016 SETIDX R4 R3 R1 - 0x8C100103, // 0017 GETMET R4 R0 R259 - 0x5C180600, // 0018 MOVE R6 R3 - 0x7C100400, // 0019 CALL R4 2 - 0xA8040001, // 001A EXBLK 1 1 - 0x80040800, // 001B RET 1 R4 - 0x7001FFEE, // 001C JMP #000C - 0x58080004, // 001D LDCONST R2 K4 - 0xAC080200, // 001E CATCH R2 1 0 - 0xB0080000, // 001F RAISE 2 R0 R0 - 0xB0060B06, // 0020 RAISE 1 R261 R262 - 0x80000000, // 0021 RET 0 R0 + (be_nested_const_str("remove_cmd", -462651594, 10)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[ 7]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x780A0003, // 0001 JMPF R2 #0006 + 0x88080100, // 0002 GETMBR R2 R0 K0 + 0x8C080501, // 0003 GETMET R2 R2 K1 + 0x5C100200, // 0004 MOVE R4 R1 + 0x7C080400, // 0005 CALL R2 2 + 0x80000000, // 0006 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: exec_cmd +********************************************************************/ +be_local_closure(exec_cmd, /* name */ + be_nested_proto( + 12, /* nstack */ + 4, /* argc */ + 0, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_string("_ccmd", -2131545883, 5), + /* K1 */ be_nested_string("json", 916562499, 4), + /* K2 */ be_nested_string("load", -435725847, 4), + /* K3 */ be_nested_string("find_key_i", 850136726, 10), + /* K4 */ be_nested_string("resolvecmnd", 993361485, 11), + }), + (be_nested_const_str("exec_cmd", 493567399, 8)), + (be_nested_const_str("Tasmota.be", 825809411, 10)), + ( &(const binstruction[27]) { /* code */ + 0x88100100, // 0000 GETMBR R4 R0 K0 + 0x78120016, // 0001 JMPF R4 #0019 + 0xA4120200, // 0002 IMPORT R4 K1 + 0x8C140902, // 0003 GETMET R5 R4 K2 + 0x5C1C0600, // 0004 MOVE R7 R3 + 0x7C140400, // 0005 CALL R5 2 + 0x8C180103, // 0006 GETMET R6 R0 K3 + 0x88200100, // 0007 GETMBR R8 R0 K0 + 0x5C240200, // 0008 MOVE R9 R1 + 0x7C180600, // 0009 CALL R6 3 + 0x4C1C0000, // 000A LDNIL R7 + 0x201C0C07, // 000B NE R7 R6 R7 + 0x781E000B, // 000C JMPF R7 #0019 + 0x8C1C0104, // 000D GETMET R7 R0 K4 + 0x5C240C00, // 000E MOVE R9 R6 + 0x7C1C0400, // 000F CALL R7 2 + 0x881C0100, // 0010 GETMBR R7 R0 K0 + 0x941C0E06, // 0011 GETIDX R7 R7 R6 + 0x5C200C00, // 0012 MOVE R8 R6 + 0x5C240400, // 0013 MOVE R9 R2 + 0x5C280600, // 0014 MOVE R10 R3 + 0x5C2C0A00, // 0015 MOVE R11 R5 + 0x7C1C0800, // 0016 CALL R7 4 + 0x501C0200, // 0017 LDBOOL R7 1 0 + 0x80040E00, // 0018 RET 1 R7 + 0x50100000, // 0019 LDBOOL R4 0 0 + 0x80040800, // 001A RET 1 R4 }) ) ); @@ -2199,6 +1610,7 @@ class be_class_tasmota (scope: global, name: Tasmota) { get_power, func(l_getpower) set_power, func(l_setpower) + get_switch, func(l_getswitch) i2c_enabled, func(l_i2cenabled) diff --git a/lib/libesp32/Berry/default/be_timer_class.c b/lib/libesp32/Berry/default/be_timer_class.c index 4ee9d0ade..e6c495851 100644 --- a/lib/libesp32/Berry/default/be_timer_class.c +++ b/lib/libesp32/Berry/default/be_timer_class.c @@ -19,35 +19,35 @@ be_local_closure(tostring, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 6]) { /* constants */ - be_nested_string("string", 398550328, 6), /* R256 - K0 */ - be_nested_string("format", -1180859054, 6), /* R257 - K1 */ - be_nested_string("= 1 && be_isfunction(vm, 1)) { + size_t arg_count = top - 1; /* we have at least 'top - 1' arguments */ + /* test if last argument is a list */ + + if (top > 1 && be_isinstance(vm, top) && be_getmember(vm, top, ".p") && be_islist(vm, top + 1)) { + int32_t list_size = be_data_size(vm, top + 1); + + if (list_size > 0) { + be_stack_require(vm, list_size + 3); /* make sure we don't overflow the stack */ + for (int i = 0; i < list_size; i++) { + be_pushnil(vm); + } + be_moveto(vm, top + 1, top + 1 + list_size); + be_moveto(vm, top, top + list_size); + + be_refpush(vm, -2); + be_pushiter(vm, -1); + while (be_iter_hasnext(vm, -2)) { + be_iter_next(vm, -2); + be_moveto(vm, -1, top); + top++; + be_pop(vm, 1); + } + be_pop(vm, 1); /* remove iterator */ + be_refpop(vm); + } + be_pop(vm, 2); + arg_count = arg_count - 1 + list_size; + } + /* actual call */ + be_call(vm, arg_count); + /* remove args */ + be_pop(vm, arg_count); + /* return value */ + + be_return(vm); + } + be_raise(vm, "value_error", "first argument must be a function"); + be_return_nil(vm); +} + static int l_str(bvm *vm) { if (be_top(vm)) { @@ -407,6 +458,12 @@ void be_load_baselib(bvm *vm) be_regfunc(vm, "isinstance", l_isinstance); be_regfunc(vm, "__iterator__", l_iterator); } + +/* call must be added later to respect order of builtins */ +void be_load_baselib_call(bvm *vm) +{ + be_regfunc(vm, "call", l_call); +} #else extern const bclass be_class_list; extern const bclass be_class_map; @@ -437,6 +494,7 @@ vartab m_builtin (scope: local) { map, class(be_class_map) range, class(be_class_range) bytes, class(be_class_bytes) + call, func(l_call) } @const_object_info_end */ #include "../generate/be_fixed_m_builtin.h" diff --git a/lib/libesp32/Berry/src/be_constobj.h b/lib/libesp32/Berry/src/be_constobj.h index 8dcf17d78..d94dd2729 100644 --- a/lib/libesp32/Berry/src/be_constobj.h +++ b/lib/libesp32/Berry/src/be_constobj.h @@ -72,6 +72,11 @@ extern "C" { .type = BE_STRING \ } +#define be_const_comptr(_val) { \ + .v.p = (void*)(_val), \ + .type = BE_COMPTR \ +} + #define be_const_class(_class) { \ .v.c = &(_class), \ .type = BE_CLASS \ @@ -218,6 +223,11 @@ const bntvmodule be_native_module(_module) = { \ BE_REAL \ } +#define be_const_comptr(_val) { \ + bvaldata((void*)(_val)), \ + BE_COMPTR \ +} + #define be_const_str(_string) { \ bvaldata(bstring(_string)), \ BE_STRING \ diff --git a/lib/libesp32/Berry/src/be_introspectlib.c b/lib/libesp32/Berry/src/be_introspectlib.c index 5254b9791..4115e9f7e 100644 --- a/lib/libesp32/Berry/src/be_introspectlib.c +++ b/lib/libesp32/Berry/src/be_introspectlib.c @@ -13,6 +13,8 @@ #include "be_debug.h" #include "be_map.h" #include "be_vm.h" +#include "be_exec.h" +#include "be_gc.h" #include #if BE_USE_INTROSPECT_MODULE @@ -76,52 +78,45 @@ static int m_setmember(bvm *vm) be_return_nil(vm); } -/* call a function with variable number of arguments */ -/* first argument is a callable object (function, closure, native function, native closure) */ -/* then all subsequent arguments are pushed except the last one */ -/* If the last argument is a 'list', then all elements are pushed as arguments */ -/* otherwise the last argument is pushed as well */ -static int m_vcall(bvm *vm) +static int m_toptr(bvm *vm) { int top = be_top(vm); - if (top >= 1 && be_isfunction(vm, 1)) { - size_t arg_count = top - 1; /* we have at least 'top - 1' arguments */ - /* test if last argument is a list */ - - if (top > 1 && be_isinstance(vm, top) && be_getmember(vm, top, ".p") && be_islist(vm, top + 1)) { - int32_t list_size = be_data_size(vm, top + 1); - - if (list_size > 0) { - be_stack_require(vm, list_size + 3); /* make sure we don't overflow the stack */ - for (int i = 0; i < list_size; i++) { - be_pushnil(vm); - } - be_moveto(vm, top + 1, top + 1 + list_size); - be_moveto(vm, top, top + list_size); - - be_refpush(vm, -2); - be_pushiter(vm, -1); - while (be_iter_hasnext(vm, -2)) { - be_iter_next(vm, -2); - be_moveto(vm, -1, top); - top++; - be_pop(vm, 1); - } - be_pop(vm, 1); /* remove iterator */ - be_refpop(vm); - } - be_pop(vm, 2); - arg_count = arg_count - 1 + list_size; + if (top >= 1) { + bvalue *v = be_indexof(vm, 1); + if (var_basetype(v) >= BE_GCOBJECT) { + be_pushcomptr(vm, var_toobj(v)); + be_return(vm); + } else if (var_type(v) == BE_INT) { + be_pushcomptr(vm, (void*) var_toint(v)); + be_return(vm); + } else { + be_raise(vm, "value_error", "unsupported for this type"); + } + } + be_return_nil(vm); +} + +static int m_fromptr(bvm *vm) +{ + int top = be_top(vm); + if (top >= 1) { + void* v; + if (be_iscomptr(vm, 1)) { + v = be_tocomptr(vm, 1); + } else { + v = (void*) be_toint(vm, 1); + } + if (v) { + bgcobject * ptr = (bgcobject*) v; + if (var_basetype(ptr) >= BE_GCOBJECT) { + bvalue *top = be_incrtop(vm); + var_setobj(top, ptr->type, ptr); + } else { + be_raise(vm, "value_error", "unsupported for this type"); + } + be_return(vm); } - /* actual call */ - be_call(vm, arg_count); - /* remove args */ - be_pop(vm, arg_count); - /* return value */ - - be_return(vm); } - be_raise(vm, "value_error", "first argument must be a function"); be_return_nil(vm); } @@ -131,7 +126,6 @@ be_native_module_attr_table(introspect) { be_native_module_function("get", m_findmember), be_native_module_function("set", m_setmember), - be_native_module_function("vcall", m_vcall), }; be_define_native_module(introspect, NULL); @@ -142,7 +136,9 @@ module introspect (scope: global, depend: BE_USE_INTROSPECT_MODULE) { get, func(m_findmember) set, func(m_setmember) - vcall, func(m_vcall) + + toptr, func(m_toptr) + fromptr, func(m_fromptr) } @const_object_info_end */ #include "../generate/be_fixed_introspect.h" diff --git a/lib/libesp32/Berry/src/be_libs.c b/lib/libesp32/Berry/src/be_libs.c index a4c774df4..0c55717f3 100644 --- a/lib/libesp32/Berry/src/be_libs.c +++ b/lib/libesp32/Berry/src/be_libs.c @@ -8,6 +8,7 @@ #include "be_libs.h" extern void be_load_baselib(bvm *vm); +extern void be_load_baselib_call(bvm *vm); extern void be_load_listlib(bvm *vm); extern void be_load_maplib(bvm *vm); extern void be_load_rangelib(bvm *vm); @@ -23,5 +24,6 @@ void be_loadlibs(bvm *vm) be_load_rangelib(vm); be_load_filelib(vm); be_load_byteslib(vm); + be_load_baselib_call(vm); #endif } diff --git a/lib/libesp32/Berry/src/be_parser.c b/lib/libesp32/Berry/src/be_parser.c index bb455df68..cc4ae7969 100644 --- a/lib/libesp32/Berry/src/be_parser.c +++ b/lib/libesp32/Berry/src/be_parser.c @@ -900,10 +900,12 @@ static void suffix_expr(bparser *parser, bexpdesc *e) static void suffix_alloc_reg(bparser *parser, bexpdesc *l) { bfuncinfo *finfo = parser->finfo; - bbool suffix = l->type == ETINDEX || l->type == ETMEMBER; + bbool is_suffix = l->type == ETINDEX || l->type == ETMEMBER; /* is suffix */ + bbool is_suffix_reg = l->v.ss.tt == ETREG || l->v.ss.tt == ETLOCAL || l->v.ss.tt == ETGLOBAL || l->v.ss.tt == ETNGLOBAL; /* if suffix, does it need a register */ + bbool is_global = l->type == ETGLOBAL || l->type == ETNGLOBAL; /* in the suffix expression, if the object is a temporary * variable (l->v.ss.tt == ETREG), it needs to be cached. */ - if (suffix && l->v.ss.tt == ETREG) { + if (is_global || (is_suffix && is_suffix_reg)) { be_code_allocregs(finfo, 1); } } diff --git a/lib/libesp32/Berry/src/be_strlib.c b/lib/libesp32/Berry/src/be_strlib.c index 257bd8c1a..7b9bf8acf 100644 --- a/lib/libesp32/Berry/src/be_strlib.c +++ b/lib/libesp32/Berry/src/be_strlib.c @@ -97,6 +97,9 @@ static bstring* sim2str(bvm *vm, bvalue *v) case BE_MODULE: module2str(sbuf, v); break; + case BE_COMPTR: + sprintf(sbuf, "", var_toobj(v)); + break; default: strcpy(sbuf, "(unknow value)"); break; @@ -323,15 +326,47 @@ BERRY_API const char *be_str2num(bvm *vm, const char *str) return sout; } +static bstring* string_range(bvm *vm, bstring *str, binstance *range) +{ + bint lower, upper; + bint size = str_len(str); /* size of source string */ + // bint size = be_data_size(vm, -1); /* get source list size */ + /* get index range */ + bvalue temp; + be_instance_member(vm, range, be_newstr(vm, "__lower__"), &temp); + lower = var_toint(&temp); + be_instance_member(vm, range, be_newstr(vm, "__upper__"), &temp); + upper = var_toint(&temp); + /* protection scope */ + if (upper < 0) { upper = size + upper; } + if (lower < 0) { lower = size + lower; } + upper = upper < size ? upper : size - 1; + lower = lower < 0 ? 0 : lower; + if (lower > upper) { + return be_newstrn(vm, "", 0); /* empty string */ + } + return be_newstrn(vm, str(str) + lower, upper - lower + 1); + +} + /* string subscript operation */ bstring* be_strindex(bvm *vm, bstring *str, bvalue *idx) { if (var_isint(idx)) { int pos = var_toidx(idx); - if (pos < str_len(str)) { + int size = str_len(str); + if (pos < 0) { pos = size + pos; } + if ((pos < size) && (pos >= 0)) { return be_newstrn(vm, str(str) + pos, 1); } be_raise(vm, "index_error", "string index out of range"); + } else if (var_isinstance(idx)) { + binstance * ins = var_toobj(idx); + const char *cname = str(be_instance_name(ins)); + if (!strcmp(cname, "range")) { + return string_range(vm, str, ins); + } + // str(be_instance_name(i)) } be_raise(vm, "index_error", "string indices must be integers"); return NULL; diff --git a/lib/libesp32/Berry/tests/compound.be b/lib/libesp32/Berry/tests/compound.be new file mode 100644 index 000000000..bda74c9e2 --- /dev/null +++ b/lib/libesp32/Berry/tests/compound.be @@ -0,0 +1,19 @@ +# test bug in compound statements + +a = 0 +assert(a == 0) +a += 1 +assert(a == 1) +a += 10/2 +assert(a == 6) + +class A var a def init() self.a = 1 end def f(x) self.a+=x/2 end def g(x) self.a = self.a + x/2 end end + +a = A() +assert(a.a == 1) +a.f(10) +assert(a.a == 6) +b=A() +assert(b.a == 1) +b.g(10) +assert(b.a == 6) \ No newline at end of file diff --git a/lib/libesp32/Berry/tools/coc/block_builder.cpp b/lib/libesp32/Berry/tools/coc/block_builder.cpp index 9cf05be95..acea6777c 100755 --- a/lib/libesp32/Berry/tools/coc/block_builder.cpp +++ b/lib/libesp32/Berry/tools/coc/block_builder.cpp @@ -33,10 +33,12 @@ block_builder::block_builder(const object_block *object, const macro_table *macr m_strtab.push_back(it->second); } - for (auto i : object->data) { - if (i.second.depend.empty() || macro->query(i.second.depend)) { - m_block.data[i.first] = i.second.value; - m_strtab.push_back(i.first); + for (auto key : object->data_ordered) { + auto second = object->data.at(key); + if (second.depend.empty() || macro->query(second.depend)) { + m_block.data[key] = second.value; + m_strtab.push_back(key); + m_block.data_ordered.push_back(key); /* record insertion order */ } } } @@ -106,10 +108,9 @@ std::string block_builder::vartab_tostring(const block &block) idxblk = block; idxblk.data.clear(); - for (auto it : block.data) { - varvec.push_back(it.second); - it.second = "int(" + std::to_string(index++) + ")"; - idxblk.data.insert(it); + for (auto key : block.data_ordered) { + varvec.push_back(block.data.at(key)); + idxblk.data[key] = "int(" + std::to_string(index++) + ")"; } ostr << map_tostring(idxblk, block.name + "_map", true) << std::endl; diff --git a/lib/libesp32/Berry/tools/coc/block_builder.h b/lib/libesp32/Berry/tools/coc/block_builder.h index 7eb82bd3e..1a45ada3e 100755 --- a/lib/libesp32/Berry/tools/coc/block_builder.h +++ b/lib/libesp32/Berry/tools/coc/block_builder.h @@ -28,6 +28,7 @@ private: std::string name; std::map attr; std::map data; + std::vector data_ordered; /* used to retrieve in insertion order */ }; std::string block_tostring(const block &block); diff --git a/lib/libesp32/Berry/tools/coc/coc_parser.cpp b/lib/libesp32/Berry/tools/coc/coc_parser.cpp index f1e86ecb5..2bbd69965 100644 --- a/lib/libesp32/Berry/tools/coc/coc_parser.cpp +++ b/lib/libesp32/Berry/tools/coc/coc_parser.cpp @@ -186,4 +186,5 @@ void coc_parser::parse_body_item(object_block *object) if (parse_char_continue(',')) value.depend = parse_tonewline(); object->data[key] = value; + object->data_ordered.push_back(key); } diff --git a/lib/libesp32/Berry/tools/coc/object_block.h b/lib/libesp32/Berry/tools/coc/object_block.h index 474545457..c437f2b62 100644 --- a/lib/libesp32/Berry/tools/coc/object_block.h +++ b/lib/libesp32/Berry/tools/coc/object_block.h @@ -20,6 +20,7 @@ struct object_block { std::string name; std::map attr; std::map data; + std::vector data_ordered; /* preserve order of keys */ }; #endif diff --git a/lib/libesp32/Berry/tools/grammar/berry.bytecode b/lib/libesp32/Berry/tools/grammar/berry.bytecode index 2c265fb5c..2d71dde22 100755 --- a/lib/libesp32/Berry/tools/grammar/berry.bytecode +++ b/lib/libesp32/Berry/tools/grammar/berry.bytecode @@ -80,7 +80,7 @@ class: method_count: 4 -- number of method method_table: [ string -- method name - function -- method function body + function | nil -- method function body or nil (static member) if the first byte is null (which would be an empty func name) ](method_count) member_index_table -> [ string -- member name diff --git a/lib/libesp32/Berry/tools/grammar/berry.ebnf b/lib/libesp32/Berry/tools/grammar/berry.ebnf index dedf72a90..1ca79a763 100644 --- a/lib/libesp32/Berry/tools/grammar/berry.ebnf +++ b/lib/libesp32/Berry/tools/grammar/berry.ebnf @@ -17,7 +17,7 @@ func_body = '(' [arg_field {',' arg_field}] ')' block 'end'; arg_field = ['*'] ID; (* class define statement *) class_stmt = 'class' ID [':' ID] class_block 'end'; -class_block = {'var' ID {',' ID} | func_stmt}; +class_block = {'var' ID {',' ID} | 'static' ID ['=' expr] {',' ID ['=' expr] } | func_stmt}; import_stmt = 'import' (ID (['as' ID] | {',' ID}) | STRING 'as' ID); (* exceptional handling statement *) try_stmt = 'try' block except_block {except_block} 'end'; diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index 62dfd7739..ee02571e7 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -29,7 +29,7 @@ build_flags = ${esp_defaults.build_flags} [core32] platform = espressif32 @ 3.3.1 -platform_packages = framework-arduinoespressif32 @ https://github.com/tasmota/arduino-esp32/releases/download/1.0.7.3/tasmota-arduinoespressif32-release_v3.3.5.tar.gz +platform_packages = framework-arduinoespressif32 @ https://github.com/tasmota/arduino-esp32/releases/download/1.0.7.4/tasmota-arduinoespressif32-release_v3.3.5.tar.gz platformio/tool-mklittlefs @ ~1.203.200522 build_unflags = ${esp32_defaults.build_unflags} build_flags = ${esp32_defaults.build_flags} diff --git a/platformio_tasmota_cenv_sample.ini b/platformio_tasmota_cenv_sample.ini index 627f646b5..9ecaea203 100644 --- a/platformio_tasmota_cenv_sample.ini +++ b/platformio_tasmota_cenv_sample.ini @@ -38,7 +38,7 @@ build_flags = ${env.build_flags} [env:tasmota32idf3] extends = env:tasmota32_base platform = espressif32 @ 3.3.0 -platform_packages = framework-arduinoespressif32 @ https://github.com/tasmota/arduino-esp32/releases/download/1.0.7.3/tasmota-arduinoespressif32-release_v3.3.5.tar.gz +platform_packages = framework-arduinoespressif32 @ https://github.com/tasmota/arduino-esp32/releases/download/1.0.7.4/tasmota-arduinoespressif32-release_v3.3.5.tar.gz platformio/tool-mklittlefs @ ~1.203.200522 build_unflags = ${env:tasmota32_base.build_unflags} build_flags = ${env:tasmota32_base.build_flags} @@ -49,7 +49,7 @@ build_flags = ${env:tasmota32_base.build_flags} extends = env:tasmota32_base board = esp32s2 platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-idf-master -platform_packages = tasmota/framework-arduinoespressif32 @ 2.0.0+tasmota +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/v.2.0-post/framework-arduinoespressif32_i2c.zip platformio/tool-mklittlefs @ ~1.203.200522 build_unflags = ${env:tasmota32_base.build_unflags} -Wswitch-unreachable @@ -75,7 +75,7 @@ lib_ignore = extends = env:tasmota32_base board = esp32c3 platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-idf-master -platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/427/framework-arduinoespressif32-master-583026f04.tar.gz +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/v.2.0-post/framework-arduinoespressif32_i2c.zip platformio/tool-mklittlefs @ ~1.203.200522 build_unflags = ${env:tasmota32_base.build_unflags} -Wswitch-unreachable @@ -106,7 +106,7 @@ lib_ignore = [env:tasmota32idf4] extends = env:tasmota32_base platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-idf-master -platform_packages = tasmota/framework-arduinoespressif32 @ 2.0.0+tasmota +platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/v.2.0-post/framework-arduinoespressif32_i2c.zip platformio/tool-mklittlefs @ ~1.203.200522 build_unflags = ${env:tasmota32_base.build_unflags} -Wswitch-unreachable @@ -149,6 +149,7 @@ build_flags = ${env:tasmota32_base.build_flags} ; -Wstack-usage=300 ; *** JTAG Debug version, needs esp-prog or FT2232H or FT232H +; *** Install howto for Windows https://community.platformio.org/t/esp32-pio-unified-debugger/4541/20 [env:tasmota32-ocd] ;build_type = debug extends = env:tasmota32_base @@ -162,7 +163,7 @@ build_flags = ${env:tasmota32_base.build_flags} [env:tasmota32solo1-ocd] ;build_type = debug extends = env:tasmota32_base -platform_packages = framework-arduinoespressif32 @ https://github.com/tasmota/arduino-esp32/releases/download/1.0.7.3/tasmota-arduinoespressif32-solo1-release_v3.3.5.tar.gz +platform_packages = framework-arduinoespressif32 @ https://github.com/tasmota/arduino-esp32/releases/download/1.0.7.4/tasmota-arduinoespressif32-solo1-release_v3.3.5.tar.gz platformio/tool-esptoolpy @ ~1.30100 platformio/tool-mklittlefs @ ~1.203.200522 board = esp32_solo1_4M diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index 400e1f3cf..2b77d3d1a 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -50,7 +50,7 @@ build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32 [env:tasmota32solo1] extends = env:tasmota32_base -platform_packages = framework-arduinoespressif32 @ https://github.com/tasmota/arduino-esp32/releases/download/1.0.7.3/tasmota-arduinoespressif32-solo1-release_v3.3.5.tar.gz +platform_packages = framework-arduinoespressif32 @ https://github.com/tasmota/arduino-esp32/releases/download/1.0.7.4/tasmota-arduinoespressif32-solo1-release_v3.3.5.tar.gz platformio/tool-esptoolpy @ ~1.30100 platformio/tool-mklittlefs @ ~1.203.200522 build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32 @@ -59,7 +59,7 @@ build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_TASMOTA32 extends = env:tasmota32_base board = esp32-cam build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_WEBCAM -lib_extra_dirs = lib/libesp32, lib/lib_basic +lib_extra_dirs = lib/libesp32 [env:tasmota32-odroidgo] extends = env:tasmota32_base diff --git a/tasmota/berry/modules/ctypes.be b/tasmota/berry/modules/ctypes.be index 15ec12853..090d3cea0 100644 --- a/tasmota/berry/modules/ctypes.be +++ b/tasmota/berry/modules/ctypes.be @@ -58,6 +58,7 @@ ctypes.bf_12 = 112 ctypes.bf_13 = 113 ctypes.bf_14 = 114 ctypes.bf_15 = 115 +ctypes.bf_16 = 116 def findinlist(l, x) for i:0..size(l)-1 @@ -193,6 +194,7 @@ ctypes.print_types = def () print("typedef struct be_ctypes_structure_t {") print(" uint16_t size_bytes; /* size in bytes */") print(" uint16_t size_elt; /* number of elements */") + print(" const char **instance_mapping; /* array of instance class names for automatic instanciation of class */") print(" const be_ctypes_structure_item_t * items;") print("} be_ctypes_structure_t;") print() @@ -207,7 +209,7 @@ ctypes.print_types = def () print(" const be_ctypes_class_t * classes;") print("} be_ctypes_classes_t;") print() - print("BE_EXPORT_VARIABLE extern const bclass be_class_lv_ctypes;") + print("BE_EXPORT_VARIABLE extern const bclass be_class_ctypes;") print() print("void ctypes_register_class(bvm *vm, const bclass * ctypes_class, const be_ctypes_structure_t * definitions) {") print(" be_pushntvclass(vm, ctypes_class);") @@ -215,7 +217,23 @@ ctypes.print_types = def () print(" be_pop(vm, 1);") print("}") print() + print("const char * be_ctypes_instance_mappings[]; /* forward definition */") + print() + + print("// Define a sub-class of ctypes with only one member which points to the ctypes defintion") + print("#define be_define_ctypes_class(_c_name, _def, _super, _name) \\") + print(" be_local_class(_c_name, \\") + print(" 0, \\") + print(" _super, \\") + print(" be_nested_map(1, \\") + print(" ( (struct bmapnode*) &(const bmapnode[]) { \\") + print(" { be_nested_key(\"_def\", 1985022181, 4, -1), be_const_comptr(_def) },\\") + print(" })), \\") + print(" (be_nested_const_str(_name, 0, sizeof(_name)-1)) \\") + print(" )") + print() print("/********************************************************************/") + print() end global_classes = [] # track the list of all classes and @@ -236,33 +254,13 @@ ctypes.print_classes = def () ctypes.sort(global_classes) - print("const be_ctypes_classes_t be_ctypes_classes[] = {") - print(string.format(" %i,", size(global_classes))) - print(string.format(" be_ctypes_instance_mappings,")) - print(string.format(" (const be_ctypes_class_t[%i]) {", size(global_classes))) - for elt:global_classes - print(string.format(" { \"%s\", &be_%s },", elt, elt)) + print(string.format("static be_define_ctypes_class(%s, &be_%s, &be_class_ctypes, \"%s\");", elt, elt, elt)) end - print("}};") print() - print("/* @const_object_info_begin") - print("class be_class_ctypes_classes (scope: global) {") - for elt:global_classes - print(string.format(" %s, int(0)", elt)) - end - print("}") - print("@const_object_info_end */") - print() - print("void be_load_ctypes_definitions_lib(bvm *vm) {") - print(" be_pushcomptr(vm, (void*) be_ctypes_classes);") - print(" be_setglobal(vm, \".ctypes_classes\");") - print(" be_pop(vm, 1);") - print() for elt:global_classes - print(string.format(" static be_define_const_empty_class(be_class_%s, &be_class_lv_ctypes, %s);", elt, elt)) print(string.format(" ctypes_register_class(vm, &be_class_%s, &be_%s);", elt, elt)) end print("}") @@ -316,6 +314,7 @@ class structure print(string.format("const be_ctypes_structure_t be_%s = {", name)) print(string.format(" %i, /* size in bytes */", self.size_bytes)) print(string.format(" %i, /* number of elements */", size(self.mapping))) + print(string.format(" be_ctypes_instance_mappings,")) print(string.format(" (const be_ctypes_structure_item_t[%i]) {", size(self.mapping))) # list keys for future binary search var names = [] @@ -447,7 +446,6 @@ class structure self.get_closures[name] = def (b, p) return ctypes.get_bits(b, cur_offset + p, bit_offset, size_in_bits) end self.set_closures[name] = def (b, p, v) return ctypes.set_bits(b, cur_offset+ p, bit_offset, size_in_bits, v) end - self.cur_offset += size_in_bits / 8 self.cur_offset += (self.bit_offset + size_in_bits) / 8 self.bit_offset = (self.bit_offset + size_in_bits) % 8 end diff --git a/tasmota/berry/modules/partition.bec b/tasmota/berry/modules/partition.bec index 712196d53..48ce1d2ab 100644 Binary files a/tasmota/berry/modules/partition.bec and b/tasmota/berry/modules/partition.bec differ diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 766f31d6a..69ed9612e 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index 358390bc9..1fde089d9 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -709,6 +709,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index be7396a92..4809e6ccf 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 2e94554d1..0cc13b3db 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index d18aa9bce..37b10413d 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 2caab6abc..dbcfb9a6f 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index c5d98d79e..9f8144dd0 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index bd63fc53f..dbdca0efe 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -709,7 +709,8 @@ #define D_SENSOR_CSE7761_TX "CSE7761 TX" #define D_SENSOR_CSE7761_RX "CSE7761 RX" #define D_SENSOR_CSE7766_TX "CSE7766 TX" -#define D_SENSOR_CSE7766_RX "CSE7766 RX" +#define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 TX" #define D_SENSOR_PN532_RX "PN532 RX" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 86e0fb7d2..7703bfcee 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index efd02b2f4..9ebd39c51 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 3da61ccc6..5f1c511ab 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 413e70a26..7b3335658 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -764,6 +764,7 @@ #define D_SENSOR_LE01MR_RX "LE-01MR - RX" #define D_SENSOR_LE01MR_TX "LE-01MR - TX" #define D_SENSOR_BL0940_RX "BL0940 - RX" +#define D_SENSOR_BL0939_RX "BL0939 - RX" #define D_SENSOR_CC1101_GDO0 "CC1101 - GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 - GDO2" #define D_SENSOR_HRXL_RX "HRXL - RX" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index d427966cd..4ebb63250 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 56015b023..56e0a5faf 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 7f9b79727..be85b7f5b 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 83a9d88c3..e0822795f 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 1775cbd75..32b4c9ace 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index b1058e60d..6ea846aea 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index b6fb1bc35..b34629afb 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 3ac233b00..bb38d0625 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index c026d53b6..2c4b4bb29 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 5d2d969b4..547b14a43 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 3be6240c2..829dc18cd 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index d1e855bec..f60e26634 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index c9a64adac..30332b22b 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 2074f04f7..f9aebfe20 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -710,6 +710,7 @@ #define D_SENSOR_CSE7761_RX "CSE7761 Rx" #define D_SENSOR_CSE7766_TX "CSE7766 Tx" #define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" #define D_SENSOR_SM16716_CLK "SM16716 CLK" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index ea19a48a8..956913606 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -321,6 +321,7 @@ #define LIGHT_VIRTUAL_CT false // [SetOption106] Virtual CT - Creates a virtual White ColorTemp for RGBW lights #define LIGHT_VIRTUAL_CT_CW false // [SetOption107] Virtual CT Channel - signals whether the hardware white is cold CW (true) or warm WW (false) #define LIGHT_VIRTUAL_CT_POINTS 3 // Number of reference points for Virtual CT (min 2, default 3) +#define USE_AC_ZERO_CROSS_DIMMER // Requires USE_COUNTER and USE_LIGHT // -- Energy -------------------------------------- #define ENERGY_VOLTAGE_ALWAYS false // [SetOption21] Enable show voltage even if powered off @@ -623,7 +624,7 @@ // #define USE_DHT12 // [I2cDriver41] Enable DHT12 humidity and temperature sensor (I2C address 0x5C) (+0k7 code) // #define USE_DS1624 // [I2cDriver42] Enable DS1624, DS1621 temperature sensor (I2C addresses 0x48 - 0x4F) (+1k2 code) // #define USE_AHT1x // [I2cDriver43] Enable AHT10/15 humidity and temperature sensor (I2C address 0x38, 0x39) (+0k8 code) -// #define USE_AHT2x // [I2cDriver43] Enable AHT20 instead of AHT1x humidity and temperature sensor (I2C address 0x38) (+0k8 code) +// #define USE_AHT2x // [I2cDriver43] Enable AHT20 instead of AHT1x humidity and temperature sensor (I2C address 0x38) (+0k8 code) // #define USE_WEMOS_MOTOR_V1 // [I2cDriver44] Enable Wemos motor driver V1 (I2C addresses 0x2D - 0x30) (+0k7 code) // #define WEMOS_MOTOR_V1_ADDR 0x30 // Default I2C address 0x30 // #define WEMOS_MOTOR_V1_FREQ 1000 // Default frequency @@ -780,7 +781,7 @@ //#define USE_LE01MR // Add support for F&F LE-01MR Modbus energy monitor (+1k code) #define LE01MR_SPEED 9600 // LE-01MR modbus baudrate (default: 9600) #define LE01MR_ADDR 1 // LE-01MR modbus address (default: 0x01) -#define USE_BL0940 // Add support for BL0940 Energy monitor as used in Blitzwolf SHP-10 (+1k6 code) +#define USE_BL09XX // Add support for various BL09XX Energy monitor as used in Blitzwolf SHP-10 or Sonoff Dual R3 v2 (+1k6 code) //#define USE_TELEINFO // Add support for Teleinfo via serial RX interface (+5k2 code, +168 RAM + SmartMeter LinkedList Values RAM) //#define USE_IEM3000 // Add support for Schneider Electric iEM3000-Modbus series energy monitor (+0k8 code) #define IEM3000_SPEED 19200 // iEM3000-Modbus RS485 serial speed (default: 19200 baud) diff --git a/tasmota/support.ino b/tasmota/support.ino index fad51a83e..cae47b453 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -981,115 +981,6 @@ int GetStateNumber(const char *state_text) return state_number; } -String GetSerialConfig(void) { - // Settings->serial_config layout - // b000000xx - 5, 6, 7 or 8 data bits - // b00000x00 - 1 or 2 stop bits - // b000xx000 - None, Even or Odd parity - - const static char kParity[] PROGMEM = "NEOI"; - - char config[4]; - config[0] = '5' + (Settings->serial_config & 0x3); - config[1] = pgm_read_byte(&kParity[(Settings->serial_config >> 3) & 0x3]); - config[2] = '1' + ((Settings->serial_config >> 2) & 0x1); - config[3] = '\0'; - return String(config); -} - -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 -// temporary workaround, see https://github.com/espressif/arduino-esp32/issues/5287 -#include -uint32_t GetSerialBaudrate(void) { - uint32_t br; - uart_get_baudrate(0, &br); - return (br / 300) * 300; // Fix ESP32 strange results like 115201 -} -#else -uint32_t GetSerialBaudrate(void) { - return (Serial.baudRate() / 300) * 300; // Fix ESP32 strange results like 115201 -} -#endif - -void SetSerialBegin(void) { - TasmotaGlobal.baudrate = Settings->baudrate * 300; - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_SERIAL "Set to %s %d bit/s"), GetSerialConfig().c_str(), TasmotaGlobal.baudrate); - Serial.flush(); -#ifdef ESP8266 - Serial.begin(TasmotaGlobal.baudrate, (SerialConfig)pgm_read_byte(kTasmotaSerialConfig + Settings->serial_config)); -#endif // ESP8266 -#ifdef ESP32 - delay(10); // Allow time to cleanup queues - if not used hangs ESP32 - Serial.end(); - delay(10); // Allow time to cleanup queues - if not used hangs ESP32 - uint32_t config = pgm_read_dword(kTasmotaSerialConfig + Settings->serial_config); - Serial.begin(TasmotaGlobal.baudrate, config); -#endif // ESP32 -} - -void SetSerialConfig(uint32_t serial_config) { - if (serial_config > TS_SERIAL_8O2) { - serial_config = TS_SERIAL_8N1; - } - if (serial_config != Settings->serial_config) { - Settings->serial_config = serial_config; - SetSerialBegin(); - } -} - -void SetSerialBaudrate(uint32_t baudrate) { - TasmotaGlobal.baudrate = baudrate; - Settings->baudrate = TasmotaGlobal.baudrate / 300; - if (GetSerialBaudrate() != TasmotaGlobal.baudrate) { - SetSerialBegin(); - } -} - -void SetSerial(uint32_t baudrate, uint32_t serial_config) { - Settings->flag.mqtt_serial = 0; // CMND_SERIALSEND and CMND_SERIALLOG - Settings->serial_config = serial_config; - TasmotaGlobal.baudrate = baudrate; - Settings->baudrate = TasmotaGlobal.baudrate / 300; - SetSeriallog(LOG_LEVEL_NONE); - SetSerialBegin(); -} - -void ClaimSerial(void) { - TasmotaGlobal.serial_local = true; - AddLog(LOG_LEVEL_INFO, PSTR("SNS: Hardware Serial")); - SetSeriallog(LOG_LEVEL_NONE); - TasmotaGlobal.baudrate = GetSerialBaudrate(); - Settings->baudrate = TasmotaGlobal.baudrate / 300; -} - -void SerialSendRaw(char *codes) -{ - char *p; - char stemp[3]; - uint8_t code; - - int size = strlen(codes); - - while (size > 1) { - strlcpy(stemp, codes, sizeof(stemp)); - code = strtol(stemp, &p, 16); - Serial.write(code); - size -= 2; - codes += 2; - } -} - -// values is a comma-delimited string: e.g. "72,101,108,108,111,32,87,111,114,108,100,33,10" -void SerialSendDecimal(char *values) -{ - char *p; - uint8_t code; - for (char* str = strtok_r(values, ",", &p); str; str = strtok_r(nullptr, ",", &p)) { - code = (uint8_t)atoi(str); - Serial.write(code); - } -} - uint32_t GetHash(const char *buffer, size_t size) { uint32_t hash = 0; @@ -1894,6 +1785,130 @@ uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, fl #endif // USE_SCRIPT +/*********************************************************************************************\ + * Serial +\*********************************************************************************************/ + +String GetSerialConfig(void) { + // Settings->serial_config layout + // b000000xx - 5, 6, 7 or 8 data bits + // b00000x00 - 1 or 2 stop bits + // b000xx000 - None, Even or Odd parity + + const static char kParity[] PROGMEM = "NEOI"; + + char config[4]; + config[0] = '5' + (Settings->serial_config & 0x3); + config[1] = pgm_read_byte(&kParity[(Settings->serial_config >> 3) & 0x3]); + config[2] = '1' + ((Settings->serial_config >> 2) & 0x1); + config[3] = '\0'; + return String(config); +} + +#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 +// temporary workaround, see https://github.com/espressif/arduino-esp32/issues/5287 +#include +uint32_t GetSerialBaudrate(void) { + uint32_t br; + uart_get_baudrate(0, &br); + return (br / 300) * 300; // Fix ESP32 strange results like 115201 +} +#else +uint32_t GetSerialBaudrate(void) { + return (Serial.baudRate() / 300) * 300; // Fix ESP32 strange results like 115201 +} +#endif + +#ifdef ESP8266 +void SetSerialSwap(void) { + if ((15 == Pin(GPIO_TXD)) && (13 == Pin(GPIO_RXD))) { + Serial.flush(); + Serial.swap(); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_SERIAL "Serial pins swapped to alternate")); + } +} +#endif + +void SetSerialBegin(void) { + TasmotaGlobal.baudrate = Settings->baudrate * 300; + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_SERIAL "Set to %s %d bit/s"), GetSerialConfig().c_str(), TasmotaGlobal.baudrate); + Serial.flush(); +#ifdef ESP8266 + Serial.begin(TasmotaGlobal.baudrate, (SerialConfig)pgm_read_byte(kTasmotaSerialConfig + Settings->serial_config)); + SetSerialSwap(); +#endif // ESP8266 +#ifdef ESP32 + delay(10); // Allow time to cleanup queues - if not used hangs ESP32 + Serial.end(); + delay(10); // Allow time to cleanup queues - if not used hangs ESP32 + uint32_t config = pgm_read_dword(kTasmotaSerialConfig + Settings->serial_config); + Serial.begin(TasmotaGlobal.baudrate, config); +#endif // ESP32 +} + +void SetSerialConfig(uint32_t serial_config) { + if (serial_config > TS_SERIAL_8O2) { + serial_config = TS_SERIAL_8N1; + } + if (serial_config != Settings->serial_config) { + Settings->serial_config = serial_config; + SetSerialBegin(); + } +} + +void SetSerialBaudrate(uint32_t baudrate) { + TasmotaGlobal.baudrate = baudrate; + Settings->baudrate = TasmotaGlobal.baudrate / 300; + if (GetSerialBaudrate() != TasmotaGlobal.baudrate) { + SetSerialBegin(); + } +} + +void SetSerial(uint32_t baudrate, uint32_t serial_config) { + Settings->flag.mqtt_serial = 0; // CMND_SERIALSEND and CMND_SERIALLOG + Settings->serial_config = serial_config; + TasmotaGlobal.baudrate = baudrate; + Settings->baudrate = TasmotaGlobal.baudrate / 300; + SetSeriallog(LOG_LEVEL_NONE); + SetSerialBegin(); +} + +void ClaimSerial(void) { + TasmotaGlobal.serial_local = true; + AddLog(LOG_LEVEL_INFO, PSTR("SNS: Hardware Serial")); + SetSeriallog(LOG_LEVEL_NONE); + TasmotaGlobal.baudrate = GetSerialBaudrate(); + Settings->baudrate = TasmotaGlobal.baudrate / 300; +} + +void SerialSendRaw(char *codes) +{ + char *p; + char stemp[3]; + uint8_t code; + + int size = strlen(codes); + + while (size > 1) { + strlcpy(stemp, codes, sizeof(stemp)); + code = strtol(stemp, &p, 16); + Serial.write(code); + size -= 2; + codes += 2; + } +} + +// values is a comma-delimited string: e.g. "72,101,108,108,111,32,87,111,114,108,100,33,10" +void SerialSendDecimal(char *values) +{ + char *p; + uint8_t code; + for (char* str = strtok_r(values, ",", &p); str; str = strtok_r(nullptr, ",", &p)) { + code = (uint8_t)atoi(str); + Serial.write(code); + } +} + /*********************************************************************************************\ * Sleep aware time scheduler functions borrowed from ESPEasy \*********************************************************************************************/ diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index f55d35d28..4878def08 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1450,6 +1450,10 @@ void CmndPwmfrequency(void) if ((1 == XdrvMailbox.payload) || ((XdrvMailbox.payload >= PWM_MIN) && (XdrvMailbox.payload <= PWM_MAX))) { Settings->pwm_frequency = (1 == XdrvMailbox.payload) ? PWM_FREQ : XdrvMailbox.payload; analogWriteFreq(Settings->pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c) +#ifdef USE_LIGHT + LightReapplyColor(); + LightAnimate(); +#endif // USE_LIGHT } ResponseCmndNumber(Settings->pwm_frequency); } diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index a02f76645..16827dc02 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -509,7 +509,7 @@ void ResponseAppendFeatures(void) #if defined(USE_ENERGY_SENSOR) && defined(USE_LE01MR) feature5 |= 0x08000000; // xnrg_13_fif_le01mr.ino #endif -#if defined(USE_I2C) && defined(USE_AHT1x) +#if defined(USE_I2C) && (defined(USE_AHT1x) || defined(USE_AHT2x)) feature5 |= 0x10000000; // xsns_63_aht1x.ino #endif #if defined(USE_I2C) && defined(USE_WEMOS_MOTOR_V1) @@ -567,8 +567,8 @@ void ResponseAppendFeatures(void) #if defined(USE_I2C) && defined(USE_MCP9808) feature6 |= 0x00002000; // xsns_72_mcp9808.ino #endif -#if defined(USE_ENERGY_SENSOR) && defined(USE_BL0940) - feature6 |= 0x00004000; // xnrg_14_bl0940.ino +#if defined(USE_ENERGY_SENSOR) && (defined(USE_BL0940) || defined(USE_BL09XX)) + feature6 |= 0x00004000; // xnrg_14_bl09xx.ino #endif #ifdef USE_TELEGRAM feature6 |= 0x00008000; // xdrv_40_telegram.ino diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 31b4e0e17..f76d8cba3 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1779,6 +1779,7 @@ void GpioInit(void) #ifdef ESP8266 if ((2 == Pin(GPIO_TXD)) || (H801 == TasmotaGlobal.module_type)) { Serial.set_tx(2); } + SetSerialSwap(); #endif uint32_t sspi_mosi = (PinUsed(GPIO_SSPI_SCLK) && PinUsed(GPIO_SSPI_MOSI)) ? SPI_MOSI : SPI_NONE; diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index fa3fecf4d..64d1ac0de 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -121,7 +121,7 @@ #define USE_DHT12 // [I2cDriver41] Enable DHT12 humidity and temperature sensor (I2C address 0x5C) (+0k7 code) #define USE_DS1624 // [I2cDriver42] Enable DS1624, DS1621 temperature sensor (I2C addresses 0x48 - 0x4F) (+1k2 code) //#define USE_AHT1x // [I2cDriver43] Enable AHT10/15 humidity and temperature sensor (I2C address 0x38, 0x39) (+0k8 code) -// #define USE_AHT2x // [I2cDriver43] Enable AHT20 instead of AHT1x humidity and temperature sensor (I2C address 0x38) (+0k8 code) +//#define USE_AHT2x // [I2cDriver43] Enable AHT20 instead of AHT1x humidity and temperature sensor (I2C address 0x38) (+0k8 code) #define USE_WEMOS_MOTOR_V1 // [I2cDriver44] Enable Wemos motor driver V1 (I2C addresses 0x2D - 0x30) (+0k7 code) #define WEMOS_MOTOR_V1_ADDR 0x30 // Default I2C address 0x30 #define WEMOS_MOTOR_V1_FREQ 1000 // Default frequency @@ -507,7 +507,6 @@ //#undef USE_WEBSERVER // Disable Webserver #undef USE_ENHANCED_GUI_WIFI_SCAN // Disable wifi scan output with BSSID (+0k5 code) //#undef USE_WEBSEND_RESPONSE // Disable command WebSend response message (+1k code) -#define USE_EMULATION // Enable Hue emulation #define USE_EMULATION_HUE // Enable Hue Bridge emulation for Alexa (+14k code, +2k mem common) #undef USE_EMULATION_WEMO // Disable Belkin WeMo emulation for Alexa (+6k code, +2k mem common) #undef USE_CUSTOM // Disable Custom features @@ -756,6 +755,7 @@ #undef USE_THERMOSTAT // Disable support for Thermostat #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code +#undef USE_AC_ZERO_CROSS_DIMMER // Disable support for AC_ZERO_CROSS_DIMMER #endif // FIRMWARE_LITE @@ -877,7 +877,7 @@ #undef USE_DDSU666 // Disable support for Chint DDSU666 Modbus energy monitor (+0k6 code) #undef USE_SOLAX_X1 // Disable support for Solax X1 series Modbus log info (+3k1 code) #undef USE_LE01MR // Disable support for F&F LE-01MR Modbus energy meter (+2k code) -#undef USE_BL0940 // Disable support for BL0940 Energy monitor as used in Blitzwolf SHP-10 (+1k6 code) +#undef USE_BL09XX // Add support for various BL09XX Energy monitor as used in Blitzwolf SHP-10 or Sonoff Dual R3 v2 (+1k6 code) #undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry #undef USE_IEM3000 // Disable support for Schneider Electric iEM3000-Modbus series energy monitor (+0k8 code) #undef USE_WE517 // Disable support for Orno WE517-Modbus energy monitor (+1k code) @@ -900,6 +900,7 @@ #undef USE_PROMETHEUS // Disable support for https://prometheus.io/ metrics exporting over HTTP /metrics endpoint #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code +#undef USE_AC_ZERO_CROSS_DIMMER // Disable support for AC_ZERO_CROSS_DIMMER #endif // FIRMWARE_MINIMAL #endif // ifndef FIRMWARE_MINICUSTOM @@ -982,6 +983,26 @@ #ifdef USE_EMULATION_WEMO #define USE_EMULATION #endif +#ifdef USE_EMULATION +#define USE_LIGHT +#endif + +#ifdef USE_AC_ZERO_CROSS_DIMMER +#define USE_COUNTER +#define USE_LIGHT +#endif + +#ifdef USE_PWM_DIMMER +#define USE_LIGHT +#endif + +#ifdef USE_TUYA_MCU +#define USE_LIGHT +#endif + +#ifdef USE_ARILUX_RF +#define USE_LIGHT +#endif // Convert legacy slave to client #ifdef USE_TASMOTA_SLAVE diff --git a/tasmota/tasmota_configurations_ESP32.h b/tasmota/tasmota_configurations_ESP32.h index 7bc48b672..0912d4785 100644 --- a/tasmota/tasmota_configurations_ESP32.h +++ b/tasmota/tasmota_configurations_ESP32.h @@ -33,11 +33,26 @@ #define CODE_IMAGE_STR "webcam" #define USE_WEBCAM +#define USE_TASMOTA_DISCOVERY #define ENABLE_RTSPSERVER -#define USE_SDCARD #define USE_SPI +#define USE_SDCARD + +#undef USE_I2C +#undef USE_HOME_ASSISTANT +#undef USE_COUNTER +#undef USE_IR_REMOTE +#undef USE_AC_ZERO_CROSS_DIMMER +#undef USE_PWM_DIMMER +#undef USE_TUYA_MCU +#undef USE_EMULATION_HUE +#undef USE_EMULATION_WEMO +#undef USE_ARILUX_RF +#undef USE_DS18x20 +#undef USE_WS2812 +#undef USE_ENERGY_SENSOR #undef USE_BERRY // Disable Berry scripting language -#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) +#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #endif // FIRMWARE_WEBCAM /*********************************************************************************************\ @@ -58,6 +73,8 @@ #define USE_ODROID_GO // Add support for Odroid Go #define USE_SDCARD +#undef USE_HOME_ASSISTANT + #define USE_ADC #define USE_SPI #define USE_DISPLAY // Add SPI Display Support (+2k code) @@ -84,6 +101,8 @@ #undef FALLBACK_MODULE #define FALLBACK_MODULE M5STACK_CORE2 // [Module2] Select default module on fast reboot where USER_MODULE is user template +#undef USE_HOME_ASSISTANT + #define USE_M5STACK_CORE2 // Add support for M5Stack Core2 #define USE_I2S_SAY_TIME #define USE_I2S_WEBRADIO @@ -145,6 +164,9 @@ #undef FALLBACK_MODULE #define FALLBACK_MODULE WEMOS // [Module2] Select default module on fast reboot where USER_MODULE is user template +#define USE_TASMOTA_DISCOVERY +#undef USE_HOME_ASSISTANT + #define USE_SDCARD #define USE_ADC @@ -273,7 +295,7 @@ //#define USE_DHT12 // [I2cDriver41] Enable DHT12 humidity and temperature sensor (I2C address 0x5C) (+0k7 code) //#define USE_DS1624 // [I2cDriver42] Enable DS1624, DS1621 temperature sensor (I2C addresses 0x48 - 0x4F) (+1k2 code) //#define USE_AHT1x // [I2cDriver43] Enable AHT10/15 humidity and temperature sensor (I2C address 0x38, 0x39) (+0k8 code) -// #define USE_AHT2x // [I2cDriver43] Enable AHT20 instead of AHT1x humidity and temperature sensor (I2C address 0x38) (+0k8 code) +//#define USE_AHT2x // [I2cDriver43] Enable AHT20 instead of AHT1x humidity and temperature sensor (I2C address 0x38) (+0k8 code) //#define USE_WEMOS_MOTOR_V1 // [I2cDriver44] Enable Wemos motor driver V1 (I2C addresses 0x2D - 0x30) (+0k7 code) #define WEMOS_MOTOR_V1_ADDR 0x30 // Default I2C address 0x30 #define WEMOS_MOTOR_V1_FREQ 1000 // Default frequency @@ -408,7 +430,7 @@ #define USE_DHT12 // [I2cDriver41] Enable DHT12 humidity and temperature sensor (I2C address 0x5C) (+0k7 code) #define USE_DS1624 // [I2cDriver42] Enable DS1624, DS1621 temperature sensor (I2C addresses 0x48 - 0x4F) (+1k2 code) //#define USE_AHT1x // [I2cDriver43] Enable AHT10/15 humidity and temperature sensor (I2C address 0x38, 0x39) (+0k8 code) -// #define USE_AHT2x // [I2cDriver43] Enable AHT20 instead of AHT1x humidity and temperature sensor (I2C address 0x38) (+0k8 code) +//#define USE_AHT2x // [I2cDriver43] Enable AHT20 instead of AHT1x humidity and temperature sensor (I2C address 0x38) (+0k8 code) #define USE_WEMOS_MOTOR_V1 // [I2cDriver44] Enable Wemos motor driver V1 (I2C addresses 0x2D - 0x30) (+0k7 code) #define WEMOS_MOTOR_V1_ADDR 0x30 // Default I2C address 0x30 #define WEMOS_MOTOR_V1_FREQ 1000 // Default frequency diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index e38041af6..e8ba6c5f2 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -172,6 +172,7 @@ enum UserSelectablePins { GPIO_MCP2515_CS, // MCP2515 Chip Select GPIO_HRG15_TX, GPIO_HRG15_RX, // Hydreon RG-15 rain sensor serial interface GPIO_VINDRIKTNING_RX, // IKEA VINDRIKTNING Serial interface + GPIO_BL0939_RX, // BL0939 Serial interface (Dual R3 v2) GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -363,7 +364,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_INTERRUPT "|" D_SENSOR_MCP2515_CS "|" D_SENSOR_HRG15_TX "|" D_SENSOR_HRG15_RX "|" - D_SENSOR_VINDRIKTNING_RX + D_SENSOR_VINDRIKTNING_RX "|" + D_SENSOR_BL0939_RX ; const char kSensorNamesFixed[] PROGMEM = @@ -694,7 +696,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_LE01MR_TX), // F7F LE-01MR energy meter tx pin AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin #endif // IFDEF:USE_LE01MR -#ifdef USE_BL0940 +#if defined(USE_BL0940) || defined(USE_BL09XX) + AGPIO(GPIO_BL0939_RX), // BL0939 Serial interface (Dual R3 v2) AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface #endif #ifdef USE_IEM3000 diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index ff344df17..342e4fafa 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -1656,6 +1656,13 @@ uint8_t LightGetSpeedSetting(void) { return Settings->light_speed; } +// Force to reapply color, for example when PWM Frequency changed +void LightReapplyColor(void) { + for (uint32_t i = 0; i < LST_MAX; i++) { + Light.last_color[i] = 0; + } +} + // On entry Light.new_color[5] contains the color to be displayed // and Light.last_color[5] the color currently displayed // Light.power tells which lights or channels (SetOption68) are on/off diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index f1083c823..7d8578129 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -69,9 +69,6 @@ keywords if then else endif, or, and are better readable for beginners (others m #define MAX_SARRAY_NUM 32 #endif -#include -extern Renderer *renderer; - uint32_t EncodeLightId(uint8_t relay_id); uint32_t DecodeLightId(uint32_t hue_id); @@ -210,6 +207,10 @@ void alt_eeprom_readBytes(uint32_t adr, uint32_t len, uint8_t *buf) { #endif // LITTLEFS_SCRIPT_SIZE +#ifdef TESLA_POWERWALL +#include "powerwall.h" +#endif + // offsets epoch readings by 1.1.2019 00:00:00 to fit into float with second resolution #ifndef EPOCH_OFFSET #define EPOCH_OFFSET 1546300800 @@ -871,7 +872,7 @@ char *script; } // variables usage info - AddLog(LOG_LEVEL_INFO, PSTR("Script: nv=%d, tv=%d, vns=%d, ram=%d"), nvars, svars, index, glob_script_mem.script_mem_size); + AddLog(LOG_LEVEL_INFO, PSTR("Script: nv=%d, tv=%d, vns=%d, vmem=%d, smem=%d"), nvars, svars, index, glob_script_mem.script_mem_size, glob_script_mem.script_size); // copy string variables char *cp1 = glob_script_mem.glob_snp; @@ -1082,11 +1083,23 @@ void script_udp_sendvar(char *vname,float *fp,char *sp) { void ws2812_set_array(float *array ,uint32_t len, uint32_t offset) { Ws2812ForceSuspend(); - for (uint32_t cnt = 0; cntSettings->light_pixels) break; - uint32_t col = array[cnt]; - Ws2812SetColor(index + 1, col>>16, col>>8, col, 0); + for (uint32_t cnt = 0; cnt < len; cnt++) { + uint32_t index; + if (! (offset & 0x1000)) { + index = cnt + (offset & 0x7ff); + } else { + index = cnt/2 + (offset & 0x7ff); + } + if (index > Settings->light_pixels) break; + if (! (offset & 0x1000)) { + uint32_t col = array[cnt]; + Ws2812SetColor(index + 1, col>>16, col>>8, col, 0); + } else { + uint32_t hcol = array[cnt]; + cnt++; + uint32_t lcol = array[cnt]; + Ws2812SetColor(index + 1, hcol>>8, hcol, lcol>>8, lcol); + } } Ws2812ForceUpdate(); } @@ -1641,6 +1654,16 @@ char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp, if (gv && gv->jo) { // look for json input + +#if 0 + char sbuf[SCRIPT_MAXSSIZE]; + sbuf[0]=0; + char tmp[128]; + Replace_Cmd_Vars(lp, 1, tmp, sizeof(tmp)); + uint32_t res = JsonParsePath(gv->jo, tmp, '#', NULL, sbuf, sizeof(sbuf)); // software_version + AddLog(LOG_LEVEL_INFO, PSTR("json string: %s %s"),tmp, sbuf); +#endif + JsonParserObject *jpo = gv->jo; char jvname[64]; strcpy(jvname, vname); @@ -2404,6 +2427,7 @@ chknext: rstring[0] = 0; int8_t index = fvar; char *wd = ResponseData(); + strlcpy(rstring, wd, glob_script_mem.max_ssize); if (index) { if (strlen(wd) && index) { @@ -2550,12 +2574,11 @@ chknext: if (!TasmotaGlobal.global_state.wifi_down) { // erase nvs lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv); - - homekit_main(0, fvar); - if (fvar >= 98) { + int32_t sel = fvar; + fvar = homekit_main(0, sel); + if (sel >= 98) { glob_script_mem.homekit_running == false; } - } lp++; len = 0; @@ -6515,6 +6538,10 @@ char buff[512]; if (sflg) { #ifdef USE_DISPLAY_DUMP + +#include +extern Renderer *renderer; + // screen copy #define fileHeaderSize 14 #define infoHeaderSize 40 @@ -7691,7 +7718,6 @@ uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core, uint32 #endif // USE_SCRIPT_TASK #endif // ESP32 - int32_t http_req(char *host, char *request) { WiFiClient http_client; HTTPClient http; @@ -7706,6 +7732,10 @@ int32_t http_req(char *host, char *request) { request++; } +#ifdef HTTP_DEBUG + AddLog(LOG_LEVEL_INFO, PSTR("HTTP heap %d"), ESP_getFreeHeap()); +#endif + if (!mode) { // GET strcat(hbuff, request); @@ -7720,13 +7750,23 @@ int32_t http_req(char *host, char *request) { httpCode = http.POST(request); } +#ifdef HTTP_DEBUG + AddLog(LOG_LEVEL_INFO, PSTR("HTTP RESULT %s"), http.getString().c_str()); +#endif + #ifdef USE_WEBSEND_RESPONSE #ifdef MQTT_DATA_STRING TasmotaGlobal.mqtt_data = http.getString(); #else strlcpy(TasmotaGlobal.mqtt_data, http.getString().c_str(), ResponseSize()); #endif - //AddLog(LOG_LEVEL_INFO, PSTR("HTTP RESULT %s"), ResponseData()); + +#ifdef HTTP_DEBUG + AddLog(LOG_LEVEL_INFO, PSTR("HTTP MQTT BUFFER %s"), ResponseData()); +#endif + +// AddLog(LOG_LEVEL_INFO, PSTR("JSON %s"), wd_jstr); +// TasmotaGlobal.mqtt_data = wd_jstr; Run_Scripter(">E", 2, ResponseData()); glob_script_mem.glob_error = 0; @@ -7746,10 +7786,21 @@ int32_t http_req(char *host, char *request) { #include #endif //ESP8266 +#ifdef TESLA_POWERWALL +Powerwall powerwall = Powerwall(); +String authCookie = ""; +#endif + // get tesla powerwall info page json string uint32_t call2https(const char *host, const char *path) { if (TasmotaGlobal.global_state.wifi_down) return 1; uint32_t status = 0; + +#ifdef TESLA_POWERWALL + authCookie = powerwall.getAuthCookie(); + return 0; +#endif + #ifdef ESP32 WiFiClientSecure *httpsClient; httpsClient = new WiFiClientSecure; @@ -8383,8 +8434,16 @@ bool Xdrv10(uint8_t function) if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') { // clr all memset(glob_script_mem.script_ram, 0 ,glob_script_mem.script_size); +#ifdef PRECONFIGURED_SCRIPT + strcpy_P(glob_script_mem.script_ram, PSTR(PRECONFIGURED_SCRIPT)); +#else strcpy_P(glob_script_mem.script_ram, PSTR(">D\nscript error must start with >D")); +#endif +#ifdef START_SCRIPT_FROM_BOOT + bitWrite(Settings->rule_enabled, 0, 1); +#else bitWrite(Settings->rule_enabled, 0, 0); +#endif } // assure permanent memory is 4 byte aligned diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index 5fb759f15..ddfb29923 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -422,7 +422,9 @@ void HAssAnnounceRelayLight(void) char stemp3[TOPSZ]; char unique_id[30]; +#ifdef USE_LIGHT bool LightControl = light_controller.isCTRGBLinked(); // SetOption37 - Color remapping for led channels, also provides an option for allowing independent handling of RGB and white channels +#endif //USE_LIGHT bool PwmMulti = Settings->flag3.pwm_multi_channels; // SetOption68 - Multi-channel PWM instead of a single light bool is_topic_light = false; // Switch HAss domain between Lights and Relays bool ind_light = false; // Controls Separated Lights when SetOption37 is >= 128 @@ -448,14 +450,15 @@ void HAssAnnounceRelayLight(void) if (TUYA_DIMMER == TasmotaGlobal.module_type || SK03_TUYA == TasmotaGlobal.module_type) { TuyaMod = true; } #endif //ESP8266 +#ifdef USE_LIGHT // If there is a special Light to be enabled and managed with SetOption68 or SetOption37 >= 128, Discovery calculates the maximum number of entities to be generated in advance - if (PwmMulti) { max_lights = Light.subtype; } if (!LightControl) { ind_light = true; if (!PwmMulti) { max_lights = 2;} } +#endif //USE_LIGHT #ifdef USE_SHUTTER if (Settings->flag3.shutter_mode) { @@ -500,11 +503,16 @@ void HAssAnnounceRelayLight(void) if (bitRead(shutter_mask, i-1)) { // suppress shutter relays +#ifdef USE_LIGHT } else if ((i < Light.device) && !RelayX) { err_flag = true; AddLog(LOG_LEVEL_ERROR, PSTR("%s"), kHAssError2); } else { if (Settings->flag.hass_discovery && (RelayX || (Light.device > 0) && (max_lights > 0)) && !err_flag ) +#else + } else { + if (Settings->flag.hass_discovery && RelayX ) +#endif //USE_LIGHT { // SetOption19 - Control Home Assistant automatic discovery (See SetOption59) char name[TOPSZ]; // friendlyname(33) + " " + index char value_template[33]; diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index 609be6015..f4c280b4b 100755 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -50,6 +50,11 @@ int16_t disp_xpos = 0; int16_t disp_ypos = 0; #ifdef USE_MULTI_DISPLAY + +#ifndef MAX_MULTI_DISPLAYS +#define MAX_MULTI_DISPLAYS 3 +#endif + struct MULTI_DISP { Renderer *display; uint16_t fg_color; @@ -58,7 +63,7 @@ struct MULTI_DISP { int16_t disp_ypos; uint8_t color_type; uint8_t auto_draw; -} displays[3]; +} displays[MAX_MULTI_DISPLAYS]; uint8_t cur_display; Renderer *Init_uDisplay(const char *desc, int8_t cs); @@ -204,6 +209,8 @@ struct GRAPH { uint8_t yticks; uint8_t last_val; uint8_t color_index; + uint16_t bg_color; + uint16_t fg_color; GFLAGS flags; }; @@ -583,7 +590,7 @@ void DisplayText(void) { var = atoiv(cp, &temp); cp += var; - if (temp < 1 || temp > 3) { + if (temp < 1 || temp > MAX_MULTI_DISPLAYS) { temp = 1; } temp--; @@ -612,6 +619,7 @@ void DisplayText(void) renderer = Init_uDisplay(fdesc, -1); Set_display(temp); AddLog(LOG_LEVEL_INFO, PSTR("DSP: File descriptor loaded %x"),renderer); + free(fdesc); } } } @@ -2378,12 +2386,12 @@ void ClrGraph(uint16_t num) { // clr inside, but only 1.graph if overlapped if (gp->flags.overlay) return; - renderer->fillRect(gp->xp+1,gp->yp+1,gp->xs-2,gp->ys-2,bg_color); + renderer->fillRect(gp->xp+1,gp->yp+1,gp->xs-2,gp->ys-2,gp->bg_color); if (xticks) { float cxp=gp->xp,xd=(float)gp->xs/(float)xticks; for (count=0; countwriteFastVLine(cxp,gp->yp+gp->ys-TICKLEN,TICKLEN,fg_color); + renderer->writeFastVLine(cxp,gp->yp+gp->ys-TICKLEN,TICKLEN,gp->fg_color); cxp+=xd; } } @@ -2393,27 +2401,27 @@ void ClrGraph(uint16_t num) { float cxp=0; float czp=gp->yp+(gp->ymax/gp->range); while (cxpxs) { - renderer->writeFastHLine(gp->xp+cxp,czp,2,fg_color); + renderer->writeFastHLine(gp->xp+cxp,czp,2,gp->fg_color); cxp+=6.0; } // align ticks to zero line float cyp=0,yd=gp->ys/yticks; for (count=0; countgp->yp) { - renderer->writeFastHLine(gp->xp,czp-cyp,TICKLEN,fg_color); - renderer->writeFastHLine(gp->xp+gp->xs-TICKLEN,czp-cyp,TICKLEN,fg_color); + renderer->writeFastHLine(gp->xp,czp-cyp,TICKLEN,gp->fg_color); + renderer->writeFastHLine(gp->xp+gp->xs-TICKLEN,czp-cyp,TICKLEN,gp->fg_color); } if ((czp+cyp)<(gp->yp+gp->ys)) { renderer->writeFastHLine(gp->xp,czp+cyp,TICKLEN,fg_color); - renderer->writeFastHLine(gp->xp+gp->xs-TICKLEN,czp+cyp,TICKLEN,fg_color); + renderer->writeFastHLine(gp->xp+gp->xs-TICKLEN,czp+cyp,TICKLEN,gp->fg_color); } cyp+=yd; } } else { float cyp=gp->yp,yd=gp->ys/yticks; for (count=0; countwriteFastHLine(gp->xp,cyp,TICKLEN,fg_color); - renderer->writeFastHLine(gp->xp+gp->xs-TICKLEN,cyp,TICKLEN,fg_color); + renderer->writeFastHLine(gp->xp,cyp,TICKLEN,gp->fg_color); + renderer->writeFastHLine(gp->xp+gp->xs-TICKLEN,cyp,TICKLEN,gp->fg_color); cyp+=yd; } } @@ -2443,6 +2451,9 @@ void DefineGraph(uint16_t num,uint16_t xp,uint16_t yp,int16_t xs,uint16_t ys,int } } + gp->bg_color=bg_color; + gp->fg_color=fg_color; + // 6 bits per axis gp->xticks=(num>>4)&0x3f; gp->yticks=(num>>10)&0x3f; @@ -2496,7 +2507,7 @@ void DefineGraph(uint16_t num,uint16_t xp,uint16_t yp,int16_t xs,uint16_t ys,int } // draw rectangle - renderer->drawRect(xp,yp,xs,ys,fg_color); + renderer->drawRect(xp,yp,xs,ys,gp->fg_color); // clr inside ClrGraph(index); @@ -2611,7 +2622,7 @@ void RedrawGraph(uint8_t num, uint8_t flags) { if (!renderer) return; gp->flags.draw=1; - uint16_t linecol=fg_color; + uint16_t linecol=gp->fg_color; if (color_type==COLOR_COLOR) { linecol = GetColorFromIndex(gp->color_index); @@ -2619,7 +2630,7 @@ void RedrawGraph(uint8_t num, uint8_t flags) { if (!gp->flags.overlay) { // draw rectangle - renderer->drawRect(gp->xp,gp->yp,gp->xs,gp->ys,fg_color); + renderer->drawRect(gp->xp,gp->yp,gp->xs,gp->ys,gp->fg_color); // clr inside ClrGraph(index); } @@ -2634,7 +2645,7 @@ void AddGraph(uint8_t num,uint8_t val) { struct GRAPH *gp=graph[num]; if (!renderer) return; - uint16_t linecol=fg_color; + uint16_t linecol=gp->fg_color; if (color_type==COLOR_COLOR) { linecol = GetColorFromIndex(gp->color_index); } @@ -2656,7 +2667,7 @@ void AddGraph(uint8_t num,uint8_t val) { // clr area and redraw graph if (!gp->flags.overlay) { // draw rectangle - renderer->drawRect(gp->xp,gp->yp,gp->xs,gp->ys,fg_color); + renderer->drawRect(gp->xp,gp->yp,gp->xs,gp->ys,gp->fg_color); // clr inner and draw ticks ClrGraph(num); } diff --git a/tasmota/xdrv_35_pwm_dimmer.ino b/tasmota/xdrv_35_pwm_dimmer.ino index 6bcc3a28b..83f030c71 100644 --- a/tasmota/xdrv_35_pwm_dimmer.ino +++ b/tasmota/xdrv_35_pwm_dimmer.ino @@ -18,6 +18,7 @@ */ #ifdef USE_PWM_DIMMER +#ifdef USE_LIGHT /*********************************************************************************************\ * Support for Martin Jerry/acenx/Tessan/NTONPOWER SD0x PWM dimmer switches. The brightness of @@ -886,4 +887,5 @@ bool Xdrv35(uint8_t function) return result; } +#endif // USE_LIGHT #endif // USE_PWM_DIMMER diff --git a/tasmota/xdrv_52_3_berry_tasmota.ino b/tasmota/xdrv_52_3_berry_tasmota.ino index 86e936018..ea6912b30 100644 --- a/tasmota/xdrv_52_3_berry_tasmota.ino +++ b/tasmota/xdrv_52_3_berry_tasmota.ino @@ -451,6 +451,21 @@ extern "C" { be_raise(vm, kTypeError, nullptr); } + // get power + int32_t l_getswitch(bvm *vm); + int32_t l_getswitch(bvm *vm) { + be_newobject(vm, "list"); + for (uint32_t i = 0; i < MAX_SWITCHES; i++) { + if (PinUsed(GPIO_SWT1, i)) { + be_pushbool(vm, Switch.virtual_state[i] == PRESSED); + be_data_push(vm, -2); + be_pop(vm, 1); + } + } + be_pop(vm, 1); + be_return(vm); // Return + } + #ifdef USE_I2C // I2C specific // Berry: `i2c_enabled(index:int) -> bool` is I2C device enabled diff --git a/tasmota/xdrv_85_BLE_EQ3_TRV.ino b/tasmota/xdrv_85_BLE_EQ3_TRV.ino new file mode 100644 index 000000000..3427869ac --- /dev/null +++ b/tasmota/xdrv_85_BLE_EQ3_TRV.ino @@ -0,0 +1,1767 @@ +/* + xdrv_85_BLE_EQ3_TRV.ino - EQ3 radiator valve sense and control via BLE_ESP32 support for Tasmota + + Copyright (C) 2020 Simon Hailes + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + -------------------------------------------------------------------------------------------- + Version yyyymmdd Action Description + -------------------------------------------------------------------------------------------- + 1.0.0.0 20210910 publish - renamed to xdrv_85, and checked with TAS latest dev branch + 0.0.0.0 20201213 created - initial version +*/ + + +/* + +Commands: +e.g. +trv 001A22092EE0 settemp 22.5 + +trvperiod n - set polling period in seconds (default teleperiod at boot) +trvonlyaliased *0/1 - only hear devices with BLEAlias set +trvMatchPrefix 0/*1 - if set, then it will add trvs to the seen list which have mac starting with : + macs in macprefixes, currently only 001a22 +Note: anything with BLEAlias starting "EQ3" will be added to the seen list. +trvHideFailedPoll 0/*1 - if set, then failed polls will not be sent to EQ3 +trvMinRSSI -n - the minimum RSSI value at which to attempt to poll + + +trv reset - clear device list +trv devlist - report seen devices. Active scanning required, not passive, as it looks for names +trv scan - same as devlist +trv state - report general state (see below for MQTT) +trv raw - send a raw command +trv on - set temp to 30 -> display ON on EQ3 +trv off - set temp to 4.5 -> display OFF on EQ3 +trv boost - set boost +trv unboost - turn off boost +trv lock - manual lock of physical buttons +trv unlock - manual unlock of physical buttons +trv auto - set EQ3 to auto mode +trv manual - set EQ3 to manual mode +trv mode auto|manual - set EQ3 to mode auto|manual? +trv day - set EQ3 to day temp +trv night - set EQ3 to night temp +trv settemp 20.5 - set EQ3 to temp +trv settime - set time to Tasmota time (untested) +trv settime - set time +trv offset 1.5 - set offset temp +trv setdaynight 22 17.5 - set day and night mode temps +trv setwindowtempdur 12.5 30 - set window open temp and duration in mins + +trv reqprofile <0-6> - request a profile for a day fo the week. +trv setprofile <0-6> 20.5-07:30,17-17:00,22.5-22:00,17-24:00 (up to 7 temp-HH:MM) - set a profile for a day fo the week. + +Responses: +normal: +stat/EQ3/001A22092C9A = { + "cmd":"state", + "result":"ok", + "RSSI":-83, + "stattime":1613814193, + "temp":21.0, + "posn":0, + "mode":"auto", + "boost":"inactive", + "dst":"set", + "window":"closed", + "state":"unlocked", + "battery":"GOOD" +} + +holiday: +as above, but adds ,"holidayend":"YY-MM-DD HH:MM" + +when trv reqprofile is used, adds: + "profiledayN":"20.5-07:30,17.0-17:00,22.5-22:00,17.0-24:00" +where N is the day (0-6) (0 = saturday?). + +when trv setprofile is used, adds: +"profiledayset":N +where N is the day (0-6) (0 = saturday?). + +on error: + "result":"fail", + +The driver will try a command three times before reporting + + +4 digit pin calculation: (just for info) +serialno = "REQ0123456" +pin = [] + +x = str((ord(serialno[3]) ^ ord(serialno[7])) % 10) +pin.append(x) +x = str((ord(serialno[4]) ^ ord(serialno[8])) % 10) +pin.append(x) +x = str((ord(serialno[5]) ^ ord(serialno[9])) % 10) +pin.append(x) +x = str((ord(serialno[0]) - ord('A') ^ ord(serialno[6]) - ord('0')) % 10) +pin.append(x) +print("".join(pin)) + +*/ + + + + +//#define VSCODE_DEV + +#ifdef VSCODE_DEV +#define ESP32 +#define USE_BLE_ESP32 +#define USE_EQ3_ESP32 +#endif + +// for testing of BLE_ESP32, we remove xsns_62_MI_ESP32.ino completely, and instead add this modified xsns_52_ibeacon_BLE_ESP32.ino +#if CONFIG_IDF_TARGET_ESP32 +#ifdef USE_EQ3_ESP32 +#ifdef ESP32 // ESP32 only. Use define USE_HM10 for ESP8266 support +#ifdef USE_BLE_ESP32 + +#define XDRV_85 85 +#define D_CMND_EQ3 "trv" + +// uncomment for more debug messages +//#define EQ3_DEBUG + +namespace EQ3_ESP32 { + +void CmndTrv(void); +void CmndTrvPeriod(void); +void CmndTrvOnlyAliased(void); +void CmndTrvMatchPrefix(void); +void CmndTrvMinRSSI(void); +void CmndTrvHideFailedPoll(void); + +const char kEQ3_Commands[] PROGMEM = D_CMND_EQ3"|" + "|" + "period|" + "onlyaliased|" + "MatchPrefix|" + "MinRSSI|" + "HideFailedPoll"; + +void (*const EQ3_Commands[])(void) PROGMEM = { + &CmndTrv, + &CmndTrvPeriod, + &CmndTrvOnlyAliased, + &CmndTrvMatchPrefix, + &CmndTrvMinRSSI, + &CmndTrvHideFailedPoll +}; + + +const char *cmdnames[] = { + "poll", + "raw", + "state", + "settime", + "settemp", + "offset", + "setdaynight", + "setwindowtempdur", + "setholiday", + "boost", + "unboost", + "unlock", + "auto", + "manual", + "eco", + "on", + "off", + "valve", + "mode", + "day", + "night", + "reqprofile", + "setprofile" +}; + +const uint8_t *macprefixes[1] = { + (uint8_t *)"\x00\x1a\x22" +}; + +int EQ3GenericOpCompleteFn(BLE_ESP32::generic_sensor_t *pStruct); + +const char EQ3_Svc[] PROGMEM = "3e135142-654f-9090-134a-a6ff5bb77046"; +const char EQ3_rw_Char[] PROGMEM = "3fa4585a-ce4a-3bad-db4b-b8df8179ea09"; +const char EQ3_notify_Char[] PROGMEM = "d0e8434d-cd29-0996-af41-6c90f4e0eb2a"; + +struct eq3_device_tag{ + uint8_t addr[7]; + int8_t RSSI; + uint64_t timeoutTime; + uint8_t pairing; + uint8_t lastStatus[10]; // last received 02 stat + uint8_t lastStatusLen; + uint32_t lastStatusTime; // in utc + uint8_t nextDiscoveryData; +} eq3_device_t; + +/*********************************************************************************************\ + * variables to control operation +\*********************************************************************************************/ +int retries = 0; +// allow 240s before timeout of sa device - based on that we restart BLE if we don't see adverts for 120s +#define EQ3_TIMEOUT 240L + +uint8_t pairingaddr[7] = {0,0,0,0,0,0}; +char pairingserial[20]; +uint8_t pairing = 0; + +#define EQ3_NUM_DEVICESLOTS 16 +eq3_device_tag EQ3Devices[EQ3_NUM_DEVICESLOTS]; +void *EQ3mutex = nullptr; + +int EQ3Period = 300; +uint8_t EQ3OnlyAliased = 0; +uint8_t EQ3MatchPrefix = 1; +uint8_t opInProgress = 0; +int seconds = 20; +int EQ3CurrentSingleSlot = 0; + +uint8_t EQ3TopicStyle = 1; +uint8_t EQ3HideFailedPoll = 1; +int8_t trvMinRSSI = -99; + +// control of timing of sending polling. +// we leave an interval between polls to allow scans to take place +int intervalSeconds = 10; // min seconds between operations +int intervalSecondsCounter = 0; // set when an operation is over to intervalSeconds +int nextEQ3Poll = EQ3_NUM_DEVICESLOTS; // set to zero to start a poll cycle + +#pragma pack( push, 1 ) // aligned structures for size +struct op_t { + uint8_t addr[7]; + uint8_t towrite[16]; + uint8_t writelen; + uint8_t cmdtype; +}; +#pragma pack(pop) + +std::deque opQueue; + + +/*********************************************************************************************\ + * Functions +\*********************************************************************************************/ + +const char *addrStr(const uint8_t *addr, int useAlias = 0){ + static char addrstr[32]; + + const char *id = nullptr; + if (useAlias){ + id = BLE_ESP32::getAlias(addr); + } + if (!id || !(*id)){ + id = addrstr; + BLE_ESP32::dump(addrstr, 13, addr, 6); + } else { + } + + return id; +} + +char *topicPrefix(int prefix, const uint8_t *addr, int useAlias){ + static char stopic[TOPSZ]; + const char *id = addrStr(addr, useAlias); + if (!EQ3TopicStyle){ + GetTopic_P(stopic, prefix, TasmotaGlobal.mqtt_topic, PSTR("")); + strcat(stopic, PSTR("EQ3/")); + strcat(stopic, id); + } else { + char p[] = "EQ3"; + GetTopic_P(stopic, prefix, p, id); + } + return stopic; +} + + + +// return 0+ if we find the addr has one of our listed prefixes +// return -1 if we don't recognise the mac +int matchPrefix(const uint8_t *addr){ + for (int i = 0; i < sizeof(macprefixes)/sizeof(*macprefixes); i++){ + if (!memcmp(addr, macprefixes[i], 3)){ + return i; + } + } + return -1; +} + + +bool EQ3Operation(const uint8_t *MAC, const uint8_t *data, int datalen, int cmdtype, int retries_in = 0) { + BLE_ESP32::generic_sensor_t *op = nullptr; + + // ALWAYS use this function to create a new one. + int res = BLE_ESP32::newOperation(&op); + if (!res){ + AddLog(LOG_LEVEL_ERROR,PSTR("EQ3 %s:Can't get a newOperation from BLE"), addrStr(MAC, cmdtype & 0x80)); + retries = 0; + return 0; + } else { +#ifdef EQ3_DEBUG + AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3 %s:got a newOperation from BLE"), addrStr(MAC, cmdtype & 0x80)); +#endif + } + + NimBLEAddress addr((uint8_t *)MAC); + op->addr = addr; + + bool havechar = false; + op->serviceUUID = NimBLEUUID(EQ3_Svc); + op->characteristicUUID = NimBLEUUID(EQ3_rw_Char); + op->notificationCharacteristicUUID = NimBLEUUID(EQ3_notify_Char); + + if (data && datalen) { + op->writelen = datalen; + memcpy(op->dataToWrite, data, datalen); + } else { + op->writelen = 1; + op->dataToWrite[0] = 0x03; // just request status + } + + // this op will call us back on complete or failure. + op->completecallback = (void *)EQ3GenericOpCompleteFn; + // store this away for later + op->context = (void *)cmdtype; + + res = BLE_ESP32::extQueueOperation(&op); + if (!res){ + // if it fails to add to the queue, do please delete it + BLE_ESP32::freeOperation(&op); + AddLog(LOG_LEVEL_ERROR,PSTR("EQ3 %s:Failed to queue new operation - deleted"), addrStr(MAC, cmdtype & 0x80)); + retries = 0; + } else { + if (retries_in){ + retries = retries_in; + } + } + + return res; +} + +int EQ3DoOp(){ + if (!opInProgress){ + if (opQueue.size()){ + op_t* op = opQueue[0]; + if (EQ3Operation(op->addr, op->towrite, op->writelen, op->cmdtype, 4)){ + opQueue.pop_front(); + opInProgress = 1; + AddLog(LOG_LEVEL_DEBUG, PSTR("EQ3 %s:Op dequeued len now %d"), addrStr(op->addr, (op->cmdtype & 0x80)), opQueue.size()); + delete op; + return 1; + } else { + AddLog(LOG_LEVEL_ERROR, PSTR("EQ3 %s:Op BLE could not start op queue len %d"), addrStr(op->addr, (op->cmdtype & 0x80)), opQueue.size()); + } + } + } + return 0; +} + +int EQ3QueueOp(const uint8_t *MAC, const uint8_t *data, int datalen, int cmdtype, int useAlias) { + op_t* newop = new op_t; + memcpy(newop->addr, MAC, 6); + memcpy(newop->towrite, data, datalen); + newop->writelen = datalen; + newop->cmdtype = cmdtype | (useAlias?0x80:0); + opQueue.push_back(newop); + int qlen = opQueue.size(); + AddLog(LOG_LEVEL_DEBUG, PSTR("EQ3 %s: Op queued len now %d"), addrStr(newop->addr, (newop->cmdtype & 0x80)), qlen); + EQ3DoOp(); + return qlen; +} + +int EQ3ParseOp(BLE_ESP32::generic_sensor_t *op, bool success, int retries){ + int res = 0; + opInProgress = 0; + ResponseClear(); + + uint8_t addrev[7]; + const uint8_t *native = op->addr.getNative(); + memcpy(addrev, native, 6); + BLE_ESP32::ReverseMAC(addrev); + + eq3_device_tag *eq3 = nullptr; + + int free = -1; + for (int i = 0; i < EQ3_NUM_DEVICESLOTS; i++){ + if (!memcmp(EQ3Devices[i].addr, addrev, 6)){ + eq3 = &EQ3Devices[i]; + break; + } + } + + int cmdtype = (((uint32_t)op->context) & 0xff); + const char *cmdType = PSTR("invalid"); + int useAlias = cmdtype & 0x80; + cmdtype &= 0x7f; + if ((cmdtype >= 0) && (cmdtype < sizeof(cmdnames)/sizeof(*cmdnames))){ + cmdType = cmdnames[cmdtype]; + } + + ResponseAppend_P(PSTR("{")); + ResponseAppend_P(PSTR("\"cmd\":\"%s\""), cmdType); + ResponseAppend_P(PSTR(",\"result\":\"%s\""), success? "ok":"fail"); + ResponseAppend_P(PSTR(",\"MAC\":\"%s\""), addrStr(addrev)); + const char *host = NetworkHostname(); + ResponseAppend_P(PSTR(",\"tas\":\"%s\""), host); + if (cmdtype == 1){ + char raw[40]; + BLE_ESP32::dump(raw, 40, op->dataNotify, op->notifylen); + ResponseAppend_P(PSTR(",\"raw\":\"%s\""), raw); + } + + uint8_t *status = {0}; + uint8_t statlen = 0; + uint32_t stattime = 0; + + if (success){ + if ((op->notifylen >= 6) && (op->dataNotify[0] == 2) && (op->dataNotify[1] == 1)){ + if (eq3){ + memcpy(eq3->lastStatus, op->dataNotify, (op->notifylen <= 10)?op->notifylen:10); + eq3->lastStatusLen = (op->notifylen <= 10)?op->notifylen:10; + eq3->lastStatusTime = UtcTime(); + } + } + + status = op->dataNotify; + statlen = op->notifylen; + stattime = UtcTime(); + } + + if (eq3){ + status = eq3->lastStatus; + statlen = eq3->lastStatusLen; + stattime = eq3->lastStatusTime; + ResponseAppend_P(PSTR(",\"RSSI\":%d"), eq3->RSSI); + } + + if ((statlen >= 6) && (status[0] == 2) && (status[1] == 1)){ + ResponseAppend_P(PSTR(",\"stattime\":%u"), stattime); + ResponseAppend_P(PSTR(",\"temp\":%2.1f"), ((float)status[5])/2); + ResponseAppend_P(PSTR(",\"posn\":%d"), status[3]); + int stat = status[2]; + ResponseAppend_P(PSTR(",\"mode\":")); + switch (stat & 3){ + case 0: + ResponseAppend_P(PSTR("\"auto\"")); + break; + case 1: + ResponseAppend_P(PSTR("\"manual\"")); + break; + case 2: + ResponseAppend_P(PSTR("\"holiday\"")); + break; + case 3: + ResponseAppend_P(PSTR("\"manualholiday\"")); + break; + } + + ResponseAppend_P(PSTR(",\"hassmode\":")); + do { + //0201283B042A + // its in auto + if ((stat & 3) == 0) { ResponseAppend_P(PSTR("\"auto\"")); break; } + // it's set to 'OFF' + if (((stat & 3) == 1) && (status[5] == 9)) { ResponseAppend_P(PSTR("\"off\"")); break; } + // it's actively heating (valve open) + if (((stat & 3) == 1) && (status[5] > 9) && (status[3] > 0)) { ResponseAppend_P(PSTR("\"heat\"")); break; } + // it's achieved temp (valve closed) + if (((stat & 3) == 1) && (status[5] > 9)) { ResponseAppend_P(PSTR("\"idle\"")); break; } + ResponseAppend_P(PSTR("\"idle\"")); + break; + } while (0); + + ResponseAppend_P(PSTR(",\"boost\":\"%s\""), (stat & 4)?"active":"inactive"); + ResponseAppend_P(PSTR(",\"dst\":\"%s\""), (stat & 8)?"set":"unset"); + ResponseAppend_P(PSTR(",\"window\":\"%s\""), (stat & 16)?"open":"closed"); + ResponseAppend_P(PSTR(",\"state\":\"%s\""), (stat & 32)?"locked":"unlocked"); + ResponseAppend_P(PSTR(",\"battery\":\"%s\""), (stat & 128)?"LOW":"GOOD"); + } + + if ((statlen >= 10) && (status[0] == 2) && (status[1] == 1)){ + int mm = status[8] * 30; + int hh = mm/60; + mm = mm % 60; + ResponseAppend_P(PSTR(",\"holidayend\":\"%02d-%02d-%02d %02d:%02d\""), + status[7], + status[9], + status[6], + hh, mm + ); + } + + if (success) { + // now to parse other data - this may not have been a stat message + if ((op->notifylen >= 3) && (op->dataNotify[0] == 2) && (op->dataNotify[1] == 2)){ + ResponseAppend_P(PSTR(",\"profiledayset\":%d"), op->dataNotify[2]); + } + + if ((op->notifylen >= 16) && (op->dataNotify[0] == 0x21)){ +//YY is the time, coded as (minutes/10), up to which to maintain the temperature declared in XX +//XX represents the temperature to be maintained until then, codified as (temperature*2) +// byte 0: 21 (default value) +// byte 1: 02 (Monday = 0x02) +// byte (2,3): 22 24 (17°C up to 06:00) +// byte (4,5): 2A 36 (21°C up to 09:00) +// byte (6,7): 22 66 (17°C up to 17:00) +// byte (8,9): 2A 8A (21°C up to 23:00) +// byte (10,11): 22 90 (17°C up to 24:00) +// byte (12,13): 22 90 (unused) +// byte (14,15): 22 90 (unused) + ResponseAppend_P(PSTR(",\"profileday%d\":\""), op->dataNotify[1]); + uint8_t *data = op->dataNotify + 2; + for (int i = 0; i < 7; i++){ + float t = *(data++); + t /= 2; + int mm = *(data++); + mm *= 10; + int hh = mm / 60; + mm = mm % 60; + ResponseAppend_P(PSTR("%2.1f-%02d:%02d"), t, hh, mm); + // stop if the last one is 24. + if (hh == 24){ + break; + } + + if (i < 6){ + ResponseAppend_P(PSTR(",")); + } + } + ResponseAppend_P(PSTR("\"")); + } + + res = 1; + } + + ResponseAppend_P(PSTR("}")); + + int type = STAT; + if (cmdtype){ + type = STAT; + } else { + // it IS a poll command + if (EQ3HideFailedPoll){ + if (!success){ + AddLog(LOG_LEVEL_DEBUG, PSTR("EQ3 %s poll fail not sent because EQ3HideFailedPoll"), addrStr(addrev)); + return res; + } + } + } + + char *topic = topicPrefix(type, addrev, useAlias); + MqttPublish(topic, false); + return res; +} + +int EQ3GenericOpCompleteFn(BLE_ESP32::generic_sensor_t *op){ + uint32_t context = (uint32_t) op->context; + opInProgress = 0; + + if (op->state <= GEN_STATE_FAILED){ + uint8_t addrev[7]; + const uint8_t *native = op->addr.getNative(); + memcpy(addrev, native, 6); + BLE_ESP32::ReverseMAC(addrev); + + if (retries > 1){ + retries--; + + if (EQ3Operation(addrev, op->dataToWrite, op->writelen, (int)op->context)){ + //EQ3ParseOp(op, false, retries); + AddLog(LOG_LEVEL_ERROR,PSTR("EQ3 %s: trv operation failed - retrying %d"), addrStr(addrev), op->state); + opInProgress = 1; + } else { + retries = 0; + EQ3ParseOp(op, false, 0); + AddLog(LOG_LEVEL_ERROR,PSTR("EQ3 %s: trv operation failed to send op %d"), addrStr(addrev), op->state); + } + } else { + retries = 0; + EQ3ParseOp(op, false, 0); + AddLog(LOG_LEVEL_ERROR,PSTR("EQ3 %s: trv operation failed - no more retries %d"), addrStr(addrev), op->state); + } + return 0; + } + + retries = 0; + + EQ3ParseOp(op, true, 0); + return 0; +} + + + +/*********************************************************************************************\ + * Functons actualy called from within the BLE task +\*********************************************************************************************/ + +int ispairing2(const uint8_t *payload, int len, char *name, int namelen, char *serial, int seriallen ){ + while (len){ + int l = *payload; + //BLE_ESP32::dump(temp, 40, payload, l+1); + //AddLog(LOG_LEVEL_ERROR,PSTR("EQ3: %s"), temp); + + payload++; + len--; + if (len < l){ + //AddLog(LOG_LEVEL_ERROR,PSTR("EQ3: part len er %d<%d"),len, l); + return 0; + } + switch (*payload){ + case 0xff: {// parse the EQ3 advert payload looking for nnFF01ssssssss + payload++; + len--; + l--; + if (*payload == 1){ + payload++; + len--; + l--; + //char serialstr[20]; + //strncpy(serialstr, (const char *)payload, l); + //AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3: adv part FF01 detected %s"), serialstr); + // we don;t use these, but that's what they seem to be.... + uint8_t copylen = (l > seriallen)?seriallen:l; + strncpy(serial, (const char *)payload, copylen); + serial[seriallen-1] = 0; + payload += l; + len -= l; + return 1; + } else { + payload += l; + len -= l; + } + } break; + case 0x09: { + payload++; + len--; + l--; + if (*payload == 1){ + payload++; + len--; + l--; + //char serialstr[20]; + //strncpy(serialstr, (const char *)payload, l); + //AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3: adv part FF01 detected %s"), serialstr); + // we don;t use these, but that's what they seem to be.... + uint8_t copylen = (l > namelen)?namelen:l; + strncpy(name, (const char *)payload, copylen); + name[namelen-1] = 0; + payload += l; + len -= l; + //return 1; + } else { + payload += l; + len -= l; + } + } break; + default:{ + payload += l; + len -= l; + } break; + } + } + return 0; +} + +int ispairing(const uint8_t *payload, int len){ + //char temp[40]; + //BLE_ESP32::dump(temp, 40, payload, len); + //AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3: pair%d %s"), len, temp); + while (len){ + int l = *payload; + //BLE_ESP32::dump(temp, 40, payload, l+1); + //AddLog(LOG_LEVEL_ERROR,PSTR("EQ3: %s"), temp); + + payload++; + len--; + if (len < l){ + //AddLog(LOG_LEVEL_ERROR,PSTR("EQ3: part len er %d<%d"),len, l); + return 0; + } + if (*payload == 0xff){ + payload++; + len--; + l--; + if (*payload == 1){ + payload++; + len--; + l--; + //char serialstr[20]; + //strncpy(serialstr, (const char *)payload, l); + //AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3: adv part FF01 detected %s"), serialstr); + // we don;t use these, but that's what they seem to be.... + const uint8_t *serial = payload; + uint8_t seriallen = l; + payload += l; + len -= l; + return 1; + } else { + payload += l; + len -= l; + } + } else { + payload += l; + len -= l; + } + } + return 0; +} + +int TaskEQ3AddDevice(int8_t RSSI, const uint8_t* addr, char *serial){ + int free = -1; + int i = 0; + uint64_t now = esp_timer_get_time(); + + if (serial && serial[0] && !pairing){ + memcpy(pairingaddr, addr, 6); + strncpy(pairingserial, serial, sizeof(pairingserial)); + pairingserial[sizeof(pairingserial)-1] = 0; + pairing = 1; + } + + for(i = 0; i < EQ3_NUM_DEVICESLOTS; i++){ + if(memcmp(addr,EQ3Devices[i].addr,6)==0){ + break; + } + if (EQ3Devices[i].timeoutTime && (EQ3Devices[i].timeoutTime < now)) { +#ifdef EQ3_DEBUG + AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3 %s timeout at %d"), addrStr(EQ3Devices[i].addr), i); +#endif + EQ3Devices[i].timeoutTime = 0L; + } + if (!EQ3Devices[i].timeoutTime){ + if (free == -1){ + free = i; + } + } + } + + if (i == EQ3_NUM_DEVICESLOTS){ + if (free >= 0){ + i = free; + } else { + AddLog(LOG_LEVEL_ERROR,PSTR("EQ3 lost %s: > %d devices"), addrStr(addr), EQ3_NUM_DEVICESLOTS); + return 0; + } + } + +#ifdef EQ3_DEBUG + if (!EQ3Devices[i].timeoutTime) + AddLog(LOG_LEVEL_INFO,PSTR("EQ3 %s: added at %d"), addrStr(addr), i); +#endif + + EQ3Devices[i].timeoutTime = now + (1000L*1000L)*EQ3_TIMEOUT; + memcpy(EQ3Devices[i].addr, addr, 6); + EQ3Devices[i].RSSI = RSSI; + + EQ3Devices[i].pairing = (serial && serial[0])?1:0; + + return 1; +} + + +const char *EQ3Names[] = { + "CC-RT-BLE", + "CC-RT-BLE-EQ", + "CC-RT-M-BLE" +}; + +int TaskEQ3advertismentCallback(BLE_ESP32::ble_advertisment_t *pStruct) +{ + // we will try not to use this... + BLEAdvertisedDevice *advertisedDevice = pStruct->advertisedDevice; + + std::string sname = advertisedDevice->getName(); + + bool found = false; + const char *nameStr = sname.c_str(); + int8_t RSSI = pStruct->RSSI; + const uint8_t *addr = pStruct->addr; + + + const char *alias = BLE_ESP32::getAlias(addr); + if (EQ3OnlyAliased){ + // ignore unless we have an alias. + if (!alias || !(*alias)){ + return 0; + } + } + if (!alias) alias = ""; + + for (int i = 0; i < sizeof(EQ3Names)/sizeof(*EQ3Names); i++){ + if (!strcmp(nameStr, EQ3Names[i])){ + found = true; + break; + } + } + + if (!found && !strncmp(alias, "EQ3", 3)){ + found = true; + } + + // if the addr matches the EQ2 mfg prefix, add it? + if (!found && EQ3MatchPrefix && (matchPrefix(addr) >= 0)){ + found = true; + } + + if (!found) return 0; + +#ifdef EQ3_DEBUG + if (BLE_ESP32::BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3Device: saw %s"),advertisedDevice->getAddress().toString().c_str()); +#endif + + uint8_t* payload = advertisedDevice->getPayload(); + size_t payloadlen = advertisedDevice->getPayloadLength(); + + char name[20] = {0}; + char serial[20] = {0}; + int pairing = 0; + ispairing2(payload, payloadlen, name, 20, serial, 20); + + // this will take and keep the mutex until the function is over + TasAutoMutex localmutex(&EQ3mutex); + TaskEQ3AddDevice(RSSI, addr, serial); + return 0; +} + + + + +/*********************************************************************************************\ + * Helper functions +\*********************************************************************************************/ + + + +/*********************************************************************************************\ + * init +\*********************************************************************************************/ +void EQ3Init(void) { + memset(&EQ3Devices, 0, sizeof(EQ3Devices)); + BLE_ESP32::registerForAdvertismentCallbacks((const char *)"EQ3", TaskEQ3advertismentCallback); +#ifdef EQ3_DEBUG + AddLog(LOG_LEVEL_INFO,PSTR("EQ3: init: request callbacks")); +#endif + + EQ3Period = Settings->tele_period; + + return; +} + +/***********************************************************************\ + * Regular +\***********************************************************************/ + +void EQ3Every50mSecond(){ + +} + +/** + * @brief Main loop of the driver, "high level"-loop + * + */ +int EQ3Send(const uint8_t* addr, const char *cmd, char* param, char* param2, int useAlias); + +void EQ3EverySecond(bool restart){ + if (pairing){ + char p[40]; // used in dump + BLE_ESP32::dump(p, 20, pairingaddr, 6); + Response_P(PSTR("{\"pairing\":\"%s\",\"serial\":\"%s\"}"), p, pairingserial); + char addrstr[4+8*2+2] = "EQ3/"; + BLE_ESP32::dump(&addrstr[4], 8*2+2, pairingaddr, 6); + char *topic = topicPrefix(STAT, pairingaddr, 1); + MqttPublish(topic, false); + pairing = 0; + } + + seconds --; + if (seconds <= 0){ + if (EQ3Period){ + if (nextEQ3Poll >= EQ3_NUM_DEVICESLOTS){ + AddLog(LOG_LEVEL_DEBUG, PSTR("EQ3 poll cycle starting")); + nextEQ3Poll = 0; + } else { + AddLog(LOG_LEVEL_ERROR, PSTR("EQ3 poll overrun, deferred - last loop only got to %d, not %d"), nextEQ3Poll, EQ3_NUM_DEVICESLOTS); + } + } + seconds = EQ3Period; + } + + if (EQ3Period){ + int qlen = opQueue.size(); + if ((nextEQ3Poll < EQ3_NUM_DEVICESLOTS) && (qlen == 0) && (!opInProgress)){ + if (intervalSecondsCounter){ + intervalSecondsCounter--; + } else { + // queue a EQ3Status op against each known EQ3. + // mark it as a regular stat rather than a use cmd. + for(int i = nextEQ3Poll; i < EQ3_NUM_DEVICESLOTS; i++){ + if (!EQ3Devices[i].timeoutTime){ + nextEQ3Poll = i+1; + continue; + } + + // trvMinRSSI + // find the device in BLE to get RSSI + if (EQ3Devices[i].RSSI < trvMinRSSI){ + AddLog(LOG_LEVEL_DEBUG, PSTR("EQ3 %s RSSI %d < min %d, poll suppressed"), addrStr(EQ3Devices[i].addr), EQ3Devices[i].RSSI, trvMinRSSI); + nextEQ3Poll = i+1; + continue; + } + + EQ3Send(EQ3Devices[i].addr, PSTR("poll"), nullptr, nullptr, 1); + nextEQ3Poll = i+1; + intervalSecondsCounter = intervalSeconds; + break; + } + } + } + } + + // start next op now, if we have any queued + EQ3DoOp(); + +} + + +/*********************************************************************************************\ + * Presentation +\*********************************************************************************************/ +int EQ3SendCurrentDevices(){ + // send the active devices + ResponseClear(); + ResponseAppend_P(PSTR("{\"devices\":{")); + int added = 0; + for(int i = 0; i < EQ3_NUM_DEVICESLOTS; i++){ + char p[40]; + if (!EQ3Devices[i].timeoutTime) + continue; + if (added){ + ResponseAppend_P(PSTR(",")); + } + BLE_ESP32::dump(p, 20, EQ3Devices[i].addr, 6); + ResponseAppend_P(PSTR("\"%s\":%d"), p, EQ3Devices[i].RSSI); + added = 1; + } + ResponseAppend_P(PSTR("}}")); + MqttPublishPrefixTopic_P(STAT, PSTR("EQ3"), false); + return 0; +} + +int EQ3SendResult(char *requested, const char *result){ + // send the result + Response_P(PSTR("{\"result\":\"%s\"}"), result); + static char stopic[TOPSZ]; + GetTopic_P(stopic, STAT, TasmotaGlobal.mqtt_topic, PSTR("")); + strcat(stopic, PSTR("EQ3/")); + strcat(stopic, requested); + MqttPublish(stopic, false); + return 0; +} + + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +void simpletolower(char *p){ + if (!p) return; + while (*p){ + *p = *p | 0x20; + p++; + } +} + +// +// great description here: +// https://reverse-engineering-ble-devices.readthedocs.io/en/latest/protocol_description/00_protocol_description.html +// not all implemented yet. +// +int EQ3Send(const uint8_t* addr, const char *cmd, char* param, char* param2, int useAlias){ + + char p[] = ""; + if (!param) param = p; + if (!param2) param2 = p; + uint8_t d[20]; + memset(d, 0, sizeof(d)); + int dlen = 0; +#ifdef EQ3_DEBUG + AddLog(LOG_LEVEL_INFO,PSTR("EQ3 %s: cmd: [%s] [%s] [%s]"), addrStr(addr), cmd, param, param2); +#endif + +/* done on whole string before here. + simpletolower(cmd); + simpletolower(param); + simpletolower(param2); +*/ + + int cmdtype = 0; + + do { + if (!strcmp(cmd, "raw")){ + cmdtype = 1; + if (!param || param[0] == 0){ + return -1; + } + int len = strlen(param) / 2; + if (len > 20){ + AddLog(LOG_LEVEL_ERROR,PSTR("EQ3 raw len of %s = %d > 20"), param, len); + return -1; + } + BLE_ESP32::fromHex(d, param, len); + dlen = len; + break; + } + +/* if (!strcmp(cmd, "state")){ + d[0] = 0x03; + dlen = 1; + break; + } +*/ + if (!strcmp(cmd, "settime") || !strcmp(cmd, "state") || !strcmp(cmd, "poll")){ + if (!strcmp(cmd, "poll")){ + cmdtype = 0; + } + if (!strcmp(cmd, "state")){ + cmdtype = 2; + } + if (!strcmp(cmd, "settime")){ + cmdtype = 3; + } + if (!param || param[0] == 0){ + + if (RtcTime.valid) { + d[0] = 0x03; + d[1] = (RtcTime.year % 100); + d[2] = RtcTime.month; + d[3] = RtcTime.day_of_month; + d[4] = RtcTime.hour; + d[5] = RtcTime.minute; + d[6] = RtcTime.second; + } else { + return -1; + } + + // time_t now = 0; + // struct tm timeinfo = { 0 }; + // time(&now); + // localtime_r(&now, &timeinfo); + // d[0] = 0x03; + // d[1] = timeinfo.tm_year % 100; + // d[2] = timeinfo.tm_mon + 1; + // d[3] = timeinfo.tm_mday; + // d[4] = timeinfo.tm_hour; + // d[5] = timeinfo.tm_min; + // d[6] = timeinfo.tm_sec; + + } else { + d[0] = 0x03; + BLE_ESP32::fromHex(d+1, param, 6); + } + dlen = 7; + break; + } + + if (!strcmp(cmd, "settemp")){ + cmdtype = 4; + if (!param || param[0] == 0){ + return -1; + } + float ftemp = 20; + sscanf(param, "%f", &ftemp); + if (ftemp < 4.5) ftemp = 4.5; + if (ftemp > 30) ftemp = 30; + ftemp *= 2; + uint8_t ctemp = (uint8_t) ftemp; + d[0] = 0x41; d[1] = ctemp; dlen = 2; + break; + } + + if (!strcmp(cmd, "offset")){ + cmdtype = 5; + if (!param || param[0] == 0){ + return 0; + } + float ftemp = 20; + sscanf(param, "%f", &ftemp); + ftemp *= 2; + int8_t ctemp = (int8_t) ftemp; + ctemp += 7; + d[0] = 0x13; d[1] = ctemp; dlen = 2; + break; + } + + if (!strcmp(cmd, "setdaynight")){ + cmdtype = 6; + if (!param || param[0] == 0){ + return -1; + } + if (!param2 || param2[0] == 0){ + return -1; + } + float ftemp = 15; + sscanf(param, "%f", &ftemp); + if (ftemp < 5) ftemp = 5; + ftemp *= 2; + uint8_t dtemp = (uint8_t) ftemp; + + ftemp = 20; + sscanf(param2, "%f", &ftemp); + if (ftemp < 5) ftemp = 5; + ftemp *= 2; + uint8_t ntemp = (uint8_t) ftemp; + + d[0] = 0x11; d[1] = dtemp; d[2] = ntemp; dlen = 3; + break; + } + + if (!strcmp(cmd, "setwindowtempdur")){ + cmdtype = 7; + if (!param || param[0] == 0){ + return -1; + } + if (!param2 || param2[0] == 0){ + return -1; + } + float ftemp = 15; + sscanf(param, "%f", &ftemp); + if (ftemp < 5) ftemp = 5; + ftemp *= 2; + uint8_t temp = (uint8_t) ftemp; + + int dur = 0; + sscanf(param2, "%d", &dur); + d[0] = 0x14; d[1] = temp; d[2] = (dur/5); dlen = 3; + break; + } + + if (!strcmp(cmd, "setholiday")){ + cmdtype = 8; + //40941C152402 + // 40 94 + if (!param || param[0] == 0){ + return -1; + } + if (!param2 || param2[0] == 0){ + return -1; + } + + int yy = 0; + int mm = 0; + int dd = 0; + int hour = 0; + int min = 0; + char *p = param; + p = strtok(p, "-"); + if (!p || p[0] == 0) return -1; + sscanf(p, "%d", &yy); + p = strtok(nullptr, "-"); + if (!p || p[0] == 0) return -1; + sscanf(p, "%d", &mm); + p = strtok(nullptr, ","); + if (!p || p[0] == 0) return -1; + sscanf(p, "%d", &dd); + p = strtok(nullptr, ":"); + if (!p || p[0] == 0) return -1; + sscanf(p, "%d", &hour); + p = strtok(nullptr, ""); + if (!p || p[0] == 0) return -1; + sscanf(p, "%d", &min); + + min += hour*60; + int tt = min / 30; + + float ftemp = 15; + sscanf(param2, "%f", &ftemp); + if (ftemp < 5) ftemp = 5; + ftemp *= 2; + uint8_t temp = (uint8_t) ftemp + 128; + + d[0] = 0x40; + d[1] = temp; + d[2] = dd; + d[3] = yy; + d[4] = tt; + d[5] = mm; + dlen = 6; + break; + } + + + if (!strcmp(cmd, "boost")) { + cmdtype = 9; + d[0] = 0x45; d[1] = 0x01; + if (param && (!strcmp(param, "off") || param[0] == '0')){ + d[1] = 0x00; + } + dlen = 2; break; + } + if (!strcmp(cmd, "unboost")) { + cmdtype = 10; + d[0] = 0x45; d[1] = 0x00; dlen = 2; break; } + if (!strcmp(cmd, "lock")) { d[0] = 0x80; d[1] = 0x01; + if (param && (!strcmp(param, "off") || param[0] == '0')){ + d[1] = 0x00; + } + dlen = 2; break; + } + if (!strcmp(cmd, "unlock")) { cmdtype = 11; d[0] = 0x80; d[1] = 0x00; dlen = 2; break; } + if (!strcmp(cmd, "auto")) { cmdtype = 12; d[0] = 0x40; d[1] = 0x00; dlen = 2; break; } + if (!strcmp(cmd, "manual")) { cmdtype = 13; d[0] = 0x40; d[1] = 0x40; dlen = 2; break; } + // this is basically 'cancel holiday' - mode auto does that. + //if (!strcmp(cmd, "eco")) { cmdtype = 14; d[0] = 0x40; d[1] = 0x80; dlen = 2; break; } + if (!strcmp(cmd, "on")) { + int res = EQ3Send(addr, "manual", nullptr, nullptr, useAlias); + char tmp[] = "30"; + int res2 = EQ3Send(addr, "settemp", tmp, nullptr, useAlias); + return res2; + } + if (!strcmp(cmd, "off")) { + int res = EQ3Send(addr, "manual", nullptr, nullptr, useAlias); + char tmp[] = "4.5"; + int res2 = EQ3Send(addr, "settemp", tmp, nullptr, useAlias); + return res2; + } + if (!strcmp(cmd, "valve")) { cmdtype = 17; d[0] = 0x41; d[1] = 0x3c; + if (!param || param[0] == 0){ + return -1; + } + if ((!strcmp(param, "off") || param[0] == '0')){ + d[1] = 0x09; + } + dlen = 2; break; + } + if (!strcmp(cmd, "mode")) { cmdtype = 18; d[0] = 0x40; d[1] = 0xff;// invlaid + + if (!param || param[0] == 0){ + return -1; + } + if (!strcmp(param, "auto")){ + d[1] = 0x00; + } + if (!strcmp(param, "manual")){ + d[1] = 0x40; + } + if (!strcmp(param, "on") || !strcmp(param, "heat")) { + int res = EQ3Send(addr, "manual", nullptr, nullptr, useAlias); + char tmp[] = "30"; + int res2 = EQ3Send(addr, "settemp", tmp, nullptr, useAlias); + return res2; + } + if (!strcmp(param, "off") || !strcmp(param, "cool")) { + int res = EQ3Send(addr, "manual", nullptr, nullptr, useAlias); + char tmp[] = "4.5"; + int res2 = EQ3Send(addr, "settemp", tmp, nullptr, useAlias); + return res2; + } + + if (d[1] == 0xff){ // no valid mode selection found + return -1; + } + // this is basically 'cancel holiday' - mode auto does that. + //if (!strcmp(param, "eco")){ + // d[1] = 0x80; + //} + dlen = 2; break; + } + if (!strcmp(cmd, "day")) { cmdtype = 19; d[0] = 0x43; dlen = 1; break; } + if (!strcmp(cmd, "night")) { cmdtype = 20; d[0] = 0x44; dlen = 1; break; } + + if (!strcmp(cmd, "reqprofile")) { cmdtype = 21; + if (!param || param[0] == 0){ + return -1; + } + d[0] = 0x20; d[1] = atoi(param); dlen = 2; + break; + } + + if (!strcmp(cmd, "setprofile")) { cmdtype = 22; + if (!param || param[0] == 0){ + return -1; + } + if (!param2 || param2[0] == 0){ + return -1; + } + d[0] = 0x10; d[1] = atoi(param); + + // default + uint8_t temps[7] = {0x22,0x22,0x22,0x22,0x22,0x22,0x22}; + uint8_t times[7] = {0x90,0x90,0x90,0x90,0x90,0x90,0x90}; + + // 20.5-17:30, + const char *p = strtok(param2, ","); + int i = 0; + while (p){ + float t = 17; + int mm = 0; + int hh = 24; + sscanf(p, "%f-%d:%d", &t, &hh, &mm); + t *= 2; + temps[i] = (uint8_t) t; + int time = hh*60+mm; + time = time / 10; + times[i] = time; + p = strtok(nullptr, ","); + i++; + if (i >= 7) break; + } + + // remaining left at 00 00 + for (int j = 0; j < 7; j++){ + d[2+j*2] = temps[j]; + d[2+j*2+1] = times[j]; + } + + dlen = 2+14; + break; + } + + break; + } while(0); + + if (dlen){ + dlen = 16; + return EQ3QueueOp(addr, d, dlen, cmdtype, useAlias); + + //return EQ3Operation(addr, d, dlen, 4); + } + + return -1; +} + + +const char *responses[] = { + PSTR("Done"), + PSTR("queued"), + PSTR("ignoredbusy"), + PSTR("invcmd"), + PSTR("cmdfail"), + PSTR("invidx"), + PSTR("invaddr") +}; + + +int CmndTrvNext(int index, char *data){ + AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3 cmd index: %d"), index); + //simpletolower(data); + + switch(index){ + case 0: + case 1: { + + char *p = strtok(data, " "); + bool trigger = false; + if (!strcmp(p, "reset")){ + retries = 0; + for (int i = 0; i < EQ3_NUM_DEVICESLOTS; i++){ + EQ3Devices[i].timeoutTime = 0L; + } + return 0; + } + + if (!strcmp(p, "scan")){ +#ifdef EQ3_DEBUG + AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3 cmd: %s"), p); +#endif + EQ3SendCurrentDevices(); + return 0; + } + if (!strcmp(p, "devlist")){ +#ifdef EQ3_DEBUG + AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3 cmd: %s"), p); +#endif + EQ3SendCurrentDevices(); + return 0; + } + + // only allow one command in progress + if (retries){ + //return 2; + } + + + int useAlias = 0; + uint8_t addrbin[7]; + int addrres = BLE_ESP32::getAddr(addrbin, p); + if (addrres){ + if (addrres == 2){ + AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3 addr used alias: %s"), p); + useAlias = 1; + } + NimBLEAddress addr(addrbin, addrbin[6]); + +#ifdef EQ3_DEBUG + //AddLog(LOG_LEVEL_INFO,PSTR("EQ3 cmd addr: %s -> %s"), p, addr.toString().c_str()); +#endif + } else { + AddLog(LOG_LEVEL_ERROR,PSTR("EQ3 addr invalid: %s"), p); + return 3; + } + + // get next part of cmd + char *cmd = strtok(nullptr, " "); + if (!cmd){ + return 3; + } + + char *param = strtok(nullptr, " "); + char *param2 = nullptr; + if (param){ + param2 = strtok(nullptr, " "); + } + int res = EQ3Send(addrbin, cmd, param, param2, useAlias); + if (res > 0) { + // succeeded to queue + AddLog(LOG_LEVEL_ERROR,PSTR("EQ3 queued")); + return 1; + } + + if (res < 0) { // invalid in some way + AddLog(LOG_LEVEL_ERROR,PSTR("EQ3 invalid")); + return 3; + } + + AddLog(LOG_LEVEL_ERROR,PSTR("EQ3 failed to queue")); + // failed to queue + return 4; + } break; + + case 2: + retries = 0; + return 0; + break; + } + + return 4; +} + +void CmndTrv(void) { + int res = CmndTrvNext(XdrvMailbox.index, XdrvMailbox.data); + ResponseCmndChar(responses[res]); +} + +void CmndTrvPeriod(void) { + if (XdrvMailbox.data_len > 0) { + if (1 == XdrvMailbox.payload){ + seconds = 0; + } else { + EQ3Period = XdrvMailbox.payload; + if (seconds > EQ3Period){ + seconds = EQ3Period; + } + } + } + ResponseCmndNumber(EQ3Period); +} + +void CmndTrvOnlyAliased(void){ + if (XdrvMailbox.data_len > 0) { + EQ3OnlyAliased = XdrvMailbox.payload; + } + ResponseCmndNumber(EQ3OnlyAliased); +} + +void CmndTrvMatchPrefix(void){ + if (XdrvMailbox.data_len > 0) { + EQ3MatchPrefix = XdrvMailbox.payload; + } + ResponseCmndNumber(EQ3MatchPrefix); +} + +void CmndTrvMinRSSI(void){ + if (XdrvMailbox.data_len > 0) { + trvMinRSSI = atoi(XdrvMailbox.data); + } + // signed number + Response_P(PSTR("{\"%s\":%d}"), XdrvMailbox.command, trvMinRSSI); +} + +void CmndTrvHideFailedPoll(void){ + if (XdrvMailbox.data_len > 0) { + EQ3HideFailedPoll = XdrvMailbox.payload; + } + ResponseCmndNumber(EQ3HideFailedPoll); +} + + +#define EQ3_TOPIC "EQ3" +static char tmp[120]; + +bool mqtt_direct(){ + char stopic[TOPSZ]; + strncpy(stopic, XdrvMailbox.topic, TOPSZ); + XdrvMailbox.topic[TOPSZ-1] = 0; + + AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3 mqtt: %s:%s"), stopic, XdrvMailbox.data); + + char *items[10]; + char *p = stopic; + int cnt = 0; + do { + items[cnt] = strtok(p, "/"); + cnt++; + p = nullptr; + } while (items[cnt-1]); + cnt--; // repreents the number of items + + if (cnt < 4){ // not for us? + //AddLog(LOG_LEVEL_INFO,PSTR("cnt: %d < 4"), cnt); + return false; + } + + for (int i = 0; i < cnt; i++){ + //AddLog(LOG_LEVEL_INFO,PSTR("cnt %d:%s"), i, items[i]); + } + + + int EQ3index = 0; + int MACindex = 0; + int CMDindex = 0; + if (strcasecmp_P(items[cnt-3], PSTR(EQ3_TOPIC)) != 0) { + //AddLog(LOG_LEVEL_INFO,PSTR("cnt-3 not %s"), PSTR(EQ3_TOPIC)); + if (strcasecmp_P(items[cnt-2], PSTR(EQ3_TOPIC)) != 0) { + //AddLog(LOG_LEVEL_INFO,PSTR("cnt-2 not %s"), PSTR(EQ3_TOPIC)); + return false; // not for us + } else { + EQ3index = cnt-2; + MACindex = cnt-1; + } + } else { + EQ3index = cnt-3; + MACindex = cnt-2; + CMDindex = cnt-1; + } + + int remains = 120; + memset(tmp, 0, sizeof(tmp)); + p = tmp; + uint8_t addr[7]; + int useAlias = BLE_ESP32::getAddr(addr, items[MACindex]); + int res = 6; // invalid address/alias + + // if address or alias valid + if (useAlias){ + strncpy(p, items[MACindex], remains-6); + p += strlen(p); + *(p++) = 0x20; + remains = 120 - (p-tmp); + + if (CMDindex){ + strncpy(p, items[CMDindex], remains-6); + p += strlen(p); + *(p++) = 0x20; + remains = 120 - (p-tmp); + } + + strncpy(p, XdrvMailbox.data, remains-6); + p += strlen(p); + *(p++) = 0x20; + remains = 120 - (p-tmp); + *(p++) = 0; + + AddLog(LOG_LEVEL_DEBUG,PSTR("EQ3:mqtt->cmdstr %s"), tmp); + res = CmndTrvNext(1, tmp); + } + + // post result to stat/tas/EQ3/ {"result":""} + EQ3SendResult(items[MACindex], responses[res]); + + return true; +} + + +/////////////////////////////////////////////// +// starts a completely fresh MQTT message. +// sends ONE sensor's worth of HA discovery msg +const char EQ3_HA_DISCOVERY_TEMPLATE[] PROGMEM = + "{\"availability\":[],\"device\":" + "{\"identifiers\":[\"BLE%s\"]," + "\"name\":\"%s\"," + "\"manufacturer\":\"tas\"," + "\"model\":\"%s\"," + "\"via_device\":\"%s\"" + "}," + "\"dev_cla\":\"%s\"," + "\"expire_after\":600," + "\"json_attr_t\":\"%s\"," + "\"name\":\"%s_%s\"," + "\"state_topic\":\"%s\"," + "\"uniq_id\":\"%s_%s\"," + "\"unit_of_meas\":\"%s\"," + "\"val_tpl\":\"{{ value_json.%s }}\"}"; + +///////////TODO - unfinished..... +void EQ3DiscoveryOneEQ3(){ + // don't detect half-added ones here + if (EQ3CurrentSingleSlot >= EQ3_NUM_DEVICESLOTS){ + // if we got to the end of the sensors, then don't send more + return; + } + +#ifdef USE_HOME_ASSISTANT + if(Settings->flag.hass_discovery){ + eq3_device_tag *p; + do { + p = &EQ3Devices[EQ3CurrentSingleSlot]; + if (0 == p->timeoutTime){ + EQ3CurrentSingleSlot++; + } + } while ((0 == p->timeoutTime) && (EQ3CurrentSingleSlot <= EQ3_NUM_DEVICESLOTS)); + + if (EQ3CurrentSingleSlot >= EQ3_NUM_DEVICESLOTS){ + return; + } + + // careful - a missing comma causes a crash!!!! + // because of the way we loop? + const char *classes[] = { + "temperature", + "temp", + "°C", + "signal_strength", + "RSSI", + "dB" + }; + + int datacount = (sizeof(classes)/sizeof(*classes))/3; + + if (p->nextDiscoveryData >= datacount){ + p->nextDiscoveryData = 0; + } + + char DiscoveryTopic[80]; + const char *host = NetworkHostname(); + const char *devtype = PSTR("EQ3"); + char idstr[32]; + const char *alias = BLE_ESP32::getAlias(p->addr); + const char *id = idstr; + if (alias && *alias){ + id = alias; + } else { + sprintf(idstr, PSTR("%s%02x%02x%02x"), + devtype, + p->addr[3], p->addr[4], p->addr[5]); + } + + char SensorTopic[60]; + sprintf(SensorTopic, "stat/%s/EQ3/%s", + host, id); + + //int i = p->nextDiscoveryData*3; + for (int i = 0; i < datacount*3; i += 3){ + if (!classes[i] || !classes[i+1] || !classes[i+2]){ + return; + } + + ResponseClear(); + + /* + {"availability":[],"device":{"identifiers":["TasmotaBLEa4c1387fc1e1"],"manufacturer":"simon","model":"someBLEsensor","name":"TASBLEa4c1387fc1e1","sw_version":"0.0.0"},"dev_cla":"temperature","json_attr_t":"stat/tasmota_esp32/SENSOR","name":"TASLYWSD037fc1e1Temp","state_topic":"tele/tasmota_esp32/SENSOR","uniq_id":"Tasmotaa4c1387fc1e1temp","unit_of_meas":"°C","val_tpl":"{{ value_json.LYWSD037fc1e1.Temperature }}"} + {"availability":[],"device":{"identifiers":["TasmotaBLEa4c1387fc1e1"], + "name":"TASBLEa4c1387fc1e1"},"dev_cla":"temperature", + "json_attr_t":"tele/tasmota_esp32/SENSOR", + "name":"TASLYWSD037fc1e1Temp","state_topic": "tele/tasmota_esp32/SENSOR", + "uniq_id":"Tasmotaa4c1387fc1e1temp","unit_of_meas":"°C", + "val_tpl":"{{ value_json.LYWSD037fc1e1.Temperature }}"} + */ + + ResponseAppend_P(EQ3_HA_DISCOVERY_TEMPLATE, + //"{\"identifiers\":[\"BLE%s\"]," + id, + //"\"name\":\"%s\"}," + id, + //\"model\":\"%s\", + devtype, + //\"via_device\":\"%s\" + host, + //"\"dev_cla\":\"%s\"," + classes[i], + //"\"json_attr_t\":\"%s\"," - the topic the sensor publishes on + SensorTopic, + //"\"name\":\"%s_%s\"," - the name of this DATA + id, classes[i+1], + //"\"state_topic\":\"%s\"," - the topic the sensor publishes on? + SensorTopic, + //"\"uniq_id\":\"%s_%s\"," - unique for this data, + id, classes[i+1], + //"\"unit_of_meas\":\"%s\"," - the measure of this type of data + classes[i+2], + //"\"val_tpl\":\"{{ value_json.%s }}") // e.g. Temperature + classes[i+1] + // + ); + + sprintf(DiscoveryTopic, "homeassistant/sensor/%s/%s/config", + id, classes[i+1]); + + MqttPublish(DiscoveryTopic); + p->nextDiscoveryData++; + //vTaskDelay(100/ portTICK_PERIOD_MS); + } + } // end if hass discovery + //AddLog_P(LOG_LEVEL_DEBUG,PSTR("M32: %s: show some %d %s"),D_CMND_MI32, MI32.mqttCurrentSlot, TasmotaGlobal.mqtt_data); +#endif //USE_HOME_ASSISTANT + +} + + + + +} // end namespace EQ3_ESP32 + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv85(uint8_t function) +{ + bool result = false; + + switch (function) { + case FUNC_INIT: + EQ3_ESP32::EQ3Init(); + break; + case FUNC_EVERY_50_MSECOND: + EQ3_ESP32::EQ3Every50mSecond(); + break; + case FUNC_EVERY_SECOND: + EQ3_ESP32::EQ3EverySecond(false); + break; + case FUNC_COMMAND: + result = DecodeCommand(EQ3_ESP32::kEQ3_Commands, EQ3_ESP32::EQ3_Commands); + break; + case FUNC_MQTT_DATA: + //AddLog(LOG_LEVEL_INFO,PSTR("topic %s"), XdrvMailbox.topic); + result = EQ3_ESP32::mqtt_direct(); + break; + case FUNC_JSON_APPEND: + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + break; +#endif // USE_WEBSERVER + } + return result; +} +#endif // +#endif // ESP32 + +#endif +#endif // CONFIG_IDF_TARGET_ESP32 diff --git a/tasmota/xdsp_15_tm1637.ino b/tasmota/xdsp_15_tm1637.ino index 75bacdf89..05b269e9e 100644 --- a/tasmota/xdsp_15_tm1637.ino +++ b/tasmota/xdsp_15_tm1637.ino @@ -120,9 +120,10 @@ - DisplayScrollText text + DisplayScrollText text [, num_loops] - Displays scrolling text. + Displays scrolling text indefinitely, until another Display- command (other than DisplayScrollText + or DisplayScrollDelay is issued). Optionally, stop scrolling after num_loops iterations. @@ -189,6 +190,8 @@ struct uint8_t scroll_delay = 4; uint8_t scroll_index = 0; uint8_t iteration = 0; + uint8_t scroll_counter = 0; + uint8_t scroll_counter_max = 3; uint8_t display_type = TM1637; uint8_t digit_order[6] = { 0, 1, 2, 3, 4, 5 }; @@ -561,9 +564,27 @@ void TM1637ClearDisplay(void) bool CmndTM1637ScrollText(void) { - AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: Text %s"), XdrvMailbox.data); + char sString[SCROLL_MAX_LEN + 1]; + char sMaxLoopCount[CMD_MAX_LEN]; + uint8_t maxLoopCount = 0; - if (XdrvMailbox.data_len > SCROLL_MAX_LEN) + switch (ArgC()) + { + case 2: + subStr(sMaxLoopCount, XdrvMailbox.data, ",", 2); + maxLoopCount = atoi(sMaxLoopCount); + case 1: + subStr(sString, XdrvMailbox.data, ",", 1); + } + + if (maxLoopCount < 0) + maxLoopCount = 0; + + AddLog(LOG_LEVEL_DEBUG, PSTR("TM7: sString %s, maxLoopCount %d"), sString, maxLoopCount); + + TM1637Data.scroll_counter_max = maxLoopCount; + + if (strlen(sString) > SCROLL_MAX_LEN) { snprintf(TM1637Data.msg, sizeof(TM1637Data.msg), PSTR("Text too long. Length should be less than %d"), SCROLL_MAX_LEN); XdrvMailbox.data = TM1637Data.msg; @@ -571,11 +592,12 @@ bool CmndTM1637ScrollText(void) } else { - snprintf(TM1637Data.scroll_text, sizeof(TM1637Data.scroll_text), PSTR(" ")); - snprintf(TM1637Data.scroll_text, sizeof(TM1637Data.scroll_text), PSTR("%s"), XdrvMailbox.data); - TM1637Data.scroll_text[XdrvMailbox.data_len] = 0; + snprintf(TM1637Data.scroll_text, sizeof(TM1637Data.scroll_text), PSTR(" ")); + snprintf(TM1637Data.scroll_text, Settings->display_width + sizeof(TM1637Data.scroll_text), PSTR(" %s"), &sString); + TM1637Data.scroll_text[strlen(sString) + Settings->display_width] = 0; TM1637Data.scroll_index = 0; TM1637Data.scroll = true; + TM1637Data.scroll_counter = 0; return true; } } @@ -602,6 +624,7 @@ bool CmndTM1637ScrollDelay(void) \*********************************************************************************************/ void TM1637ScrollText(void) { + if(!TM1637Data.scroll) return; TM1637Data.iteration++; if (TM1637Data.scroll_delay) TM1637Data.iteration = TM1637Data.iteration % TM1637Data.scroll_delay; @@ -612,9 +635,12 @@ void TM1637ScrollText(void) if (TM1637Data.scroll_index > strlen(TM1637Data.scroll_text)) { - TM1637Data.scroll = false; TM1637Data.scroll_index = 0; - return; + TM1637Data.scroll_counter++; + if(TM1637Data.scroll_counter_max != 0 && (TM1637Data.scroll_counter >= TM1637Data.scroll_counter_max)) { + TM1637Data.scroll = false; + return; + } } uint8_t rawBytes[1]; for (uint32_t i = 0, j = TM1637Data.scroll_index; i < 1 + strlen(TM1637Data.scroll_text); i++, j++) @@ -1023,7 +1049,7 @@ void TM1637ShowTime() bool TM1637MainFunc(uint8_t fn) { bool result = false; - + if(fn != FUNC_DISPLAY_SCROLLDELAY) TM1637Data.scroll = false; if (XdrvMailbox.data_len > CMD_MAX_LEN) { Response_P(PSTR("{\"Error\":\"Command text too long. Please limit it to %d characters\"}"), CMD_MAX_LEN); diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino deleted file mode 100644 index ecd30c543..000000000 --- a/tasmota/xnrg_14_bl0940.ino +++ /dev/null @@ -1,326 +0,0 @@ -/* - xnrg_14_bl0940.ino - BL0940 energy sensor support for Tasmota - - Copyright (C) 2021 Theo Arends - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifdef USE_ENERGY_SENSOR -#ifdef USE_BL0940 -/*********************************************************************************************\ - * BL0940 - Energy (Blitzwolf SHP10) - * - * Template {"NAME":"BW-SHP10","GPIO":[0,148,0,207,158,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} - * - * Based on datasheet from http://www.belling.com.cn/media/file_object/bel_product/BL0940/datasheet/BL0940_V1.1_en.pdf -\*********************************************************************************************/ - -#define XNRG_14 14 - -#define BL0940_PREF 1430 -#define BL0940_UREF 33000 -#define BL0940_IREF 2750 - -#define BL0940_PULSES_NOT_INITIALIZED -1 - -#define BL0940_BUFFER_SIZE 36 - -#define BL0940_WRITE_COMMAND 0xA0 // 0xA8 according to documentation -#define BL0940_REG_I_FAST_RMS_CTRL 0x10 -#define BL0940_REG_MODE 0x18 -#define BL0940_REG_SOFT_RESET 0x19 -#define BL0940_REG_USR_WRPROT 0x1A -#define BL0940_REG_TPS_CTRL 0x1B - -#define BL0940_READ_COMMAND 0x50 // 0x58 according to documentation -#define BL0940_FULL_PACKET 0xAA - -#define BL0940_PACKET_HEADER 0x55 // 0x58 according to documentation - -#include - -TasmotaSerial *Bl0940Serial = nullptr; - -struct BL0940 { - long voltage = 0; - long current = 0; - long power = 0; - long power_cycle_first = 0; - long cf_pulses = 0; - long cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED; - float temperature; - - int byte_counter = 0; - uint16_t tps1 = 0; - uint8_t *rx_buffer = nullptr; - bool received = false; -} Bl0940; - -const uint8_t bl0940_init[5][6] = { - { BL0940_WRITE_COMMAND, BL0940_REG_SOFT_RESET, 0x5A, 0x5A, 0x5A, 0x38 }, // Reset to default - { BL0940_WRITE_COMMAND, BL0940_REG_USR_WRPROT, 0x55, 0x00, 0x00, 0xF0 }, // Enable User Operation Write - { BL0940_WRITE_COMMAND, BL0940_REG_MODE, 0x00, 0x10, 0x00, 0x37 }, // 0x0100 = CF_UNABLE energy pulse, AC_FREQ_SEL 50Hz, RMS_UPDATE_SEL 800mS - { BL0940_WRITE_COMMAND, BL0940_REG_TPS_CTRL, 0xFF, 0x47, 0x00, 0xFE }, // 0x47FF = Over-current and leakage alarm on, Automatic temperature measurement, Interval 100mS - { BL0940_WRITE_COMMAND, BL0940_REG_I_FAST_RMS_CTRL, 0x1C, 0x18, 0x00, 0x1B }}; // 0x181C = Half cycle, Fast RMS threshold 6172 - -void Bl0940Received(void) { - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 - // 55 F2 03 00 00 00 00 7E 02 00 D4 B0 72 AC 01 00 00 00 00 02 01 00 00 00 00 00 00 00 BA 01 00 FE 03 00 83 - // 55 88 02 00 49 00 00 FE 02 00 AF EF 71 D2 01 00 EB FF FF 49 01 00 00 00 00 02 00 00 CF 01 00 FE 03 00 9F - // 55 B9 33 00 DE 45 00 94 02 00 CF E4 70 63 02 00 6C 4C 00 13 01 00 09 00 00 00 00 00 E4 01 00 FE 03 00 72 - // Hd IFRms--- Current- Reserved Voltage- Reserved Power--- Reserved CF------ Reserved TPS1---- TPS2---- Ck - - uint16_t tps1 = Bl0940.rx_buffer[29] << 8 | Bl0940.rx_buffer[28]; // TPS1 unsigned - if ((Bl0940.rx_buffer[0] != BL0940_PACKET_HEADER) || // Bad header - (Bl0940.tps1 && ((tps1 < (Bl0940.tps1 -10)) || (tps1 > (Bl0940.tps1 +10)))) // Invalid temperature change - ) { - AddLog(LOG_LEVEL_DEBUG, PSTR("BL9: Invalid data")); - return; - } - - Bl0940.tps1 = tps1; - float t = ((170.0f/448.0f)*(((float)Bl0940.tps1/2.0f)-32.0f))-45.0f; - Bl0940.temperature = ConvertTemp(t); - - Bl0940.voltage = Bl0940.rx_buffer[12] << 16 | Bl0940.rx_buffer[11] << 8 | Bl0940.rx_buffer[10]; // V_RMS unsigned - Bl0940.current = Bl0940.rx_buffer[6] << 16 | Bl0940.rx_buffer[5] << 8 | Bl0940.rx_buffer[4]; // I_RMS unsigned - int32_t power = Bl0940.rx_buffer[18] << 24 | Bl0940.rx_buffer[17] << 16 | Bl0940.rx_buffer[16] << 8; // WATT signed - Bl0940.power = abs(power) >> 8; // WATT unsigned - int32_t cf_cnt = Bl0940.rx_buffer[24] << 24 | Bl0940.rx_buffer[23] << 16 | Bl0940.rx_buffer[22] << 8; // CF_CNT signed - Bl0940.cf_pulses = abs(cf_cnt) >> 8; - - AddLog(LOG_LEVEL_DEBUG, PSTR("BL9: U %d, I %d, P %d, C %d, T %d"), - Bl0940.voltage, Bl0940.current, Bl0940.power, Bl0940.cf_pulses, Bl0940.tps1); - - if (Energy.power_on) { // Powered on - Energy.voltage[0] = (float)Bl0940.voltage / Settings->energy_voltage_calibration; - if (power && (Bl0940.power > Settings->energy_power_calibration)) { // We need at least 1W - Energy.active_power[0] = (float)Bl0940.power / Settings->energy_power_calibration; - Energy.current[0] = (float)Bl0940.current / (Settings->energy_current_calibration * 100); - } else { - Energy.active_power[0] = 0; - Energy.current[0] = 0; - } - } else { // Powered off -// Bl0940.power_cycle_first = 0; - Energy.voltage[0] = 0; - Energy.active_power[0] = 0; - Energy.current[0] = 0; - } -} - -void Bl0940SerialInput(void) { - while (Bl0940Serial->available()) { - yield(); - uint8_t serial_in_byte = Bl0940Serial->read(); - if (!Bl0940.received && (BL0940_PACKET_HEADER == serial_in_byte)) { - Bl0940.received = true; - Bl0940.byte_counter = 0; - } - if (Bl0940.received) { - Bl0940.rx_buffer[Bl0940.byte_counter++] = serial_in_byte; - if (BL0940_BUFFER_SIZE == Bl0940.byte_counter) { - - AddLogBuffer(LOG_LEVEL_DEBUG_MORE, Bl0940.rx_buffer, BL0940_BUFFER_SIZE -1); - - uint8_t checksum = BL0940_READ_COMMAND; - for (uint32_t i = 0; i < BL0940_BUFFER_SIZE -2; i++) { checksum += Bl0940.rx_buffer[i]; } - checksum ^= 0xFF; - if (checksum == Bl0940.rx_buffer[34]) { - Energy.data_valid[0] = 0; - Bl0940Received(); - Bl0940.received = false; - return; - } else { - do { // Sync buffer with data (issue #1907 and #3425) - memmove(Bl0940.rx_buffer, Bl0940.rx_buffer +1, BL0940_BUFFER_SIZE -1); - Bl0940.byte_counter--; - } while ((Bl0940.byte_counter > 1) && (BL0940_PACKET_HEADER != Bl0940.rx_buffer[0])); - if (BL0940_PACKET_HEADER != Bl0940.rx_buffer[0]) { - AddLog(LOG_LEVEL_DEBUG, PSTR("BL9: " D_CHECKSUM_FAILURE)); - Bl0940.received = false; - Bl0940.byte_counter = 0; - } - } - } - } - } -} - -/********************************************************************************************/ - -void Bl0940EverySecond(void) { - if (Energy.data_valid[0] > ENERGY_WATCHDOG) { - Bl0940.voltage = 0; - Bl0940.current = 0; - Bl0940.power = 0; - } else { -/* - // Calculate energy by using active power - if (Energy.active_power[0]) { - Energy.kWhtoday_delta += (Energy.active_power[0] * 1000) / 36; - EnergyUpdateToday(); - } -*/ - // Calculate energy by using active energy pulse count - if (BL0940_PULSES_NOT_INITIALIZED == Bl0940.cf_pulses_last_time) { - Bl0940.cf_pulses_last_time = Bl0940.cf_pulses; // Init after restart - } else { - uint32_t cf_pulses = 0; - if (Bl0940.cf_pulses < Bl0940.cf_pulses_last_time) { // Rolled over after 0xFFFFFF (16777215) pulses - cf_pulses = (0x1000000 - Bl0940.cf_pulses_last_time) + Bl0940.cf_pulses; - } else { - cf_pulses = Bl0940.cf_pulses - Bl0940.cf_pulses_last_time; - } - if (cf_pulses && Energy.active_power[0]) { - uint32_t watt256 = (1638400 * 256) / Settings->energy_power_calibration; - uint32_t delta = (cf_pulses * watt256) / 36; - if (delta <= (4000 * 1000 / 36)) { // max load for SHP10: 4.00kW (3.68kW) - Bl0940.cf_pulses_last_time = Bl0940.cf_pulses; - Energy.kWhtoday_delta += delta; - } else { - AddLog(LOG_LEVEL_DEBUG, PSTR("BL9: Overload")); - Bl0940.cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED; - } - EnergyUpdateToday(); - } - } - - } - -// AddLog(LOG_LEVEL_DEBUG, PSTR("BL9: Poll")); - - Bl0940Serial->flush(); - Bl0940Serial->write(BL0940_READ_COMMAND); - Bl0940Serial->write(BL0940_FULL_PACKET); -} - -void Bl0940SnsInit(void) { - // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions - Bl0940Serial = new TasmotaSerial(Pin(GPIO_BL0940_RX), Pin(GPIO_TXD), 1); - if (Bl0940Serial->begin(4800, 1)) { - if (Bl0940Serial->hardwareSerial()) { - ClaimSerial(); - } - if (HLW_UREF_PULSE == Settings->energy_voltage_calibration) { - Settings->energy_voltage_calibration = BL0940_UREF; - Settings->energy_current_calibration = BL0940_IREF; - Settings->energy_power_calibration = BL0940_PREF; - } - Energy.use_overtemp = true; // Use global temperature for overtemp detection - - for (uint32_t i = 0; i < 5; i++) { - for (uint32_t j = 0; j < 6; j++) { - Bl0940Serial->write(bl0940_init[i][j]); -// Bl0940Serial->write(pgm_read_byte(bl0940_init + (6 * i) + j)); // Wrong byte order! - } - delay(1); - } - - } else { - TasmotaGlobal.energy_driver = ENERGY_NONE; - } -} - -void Bl0940DrvInit(void) { - if (PinUsed(GPIO_BL0940_RX) && PinUsed(GPIO_TXD)) { - Bl0940.rx_buffer = (uint8_t*)(malloc(BL0940_BUFFER_SIZE)); - if (Bl0940.rx_buffer != nullptr) { - TasmotaGlobal.energy_driver = XNRG_14; - } - } -} - -bool Bl0940Command(void) { - bool serviced = true; - - uint32_t value = (uint32_t)(CharToFloat(XdrvMailbox.data) * 100); // 1.23 = 123 - - if (CMND_POWERSET == Energy.command_code) { - if (XdrvMailbox.data_len && Bl0940.power) { - Settings->energy_power_calibration = (Bl0940.power * 100) / value; - } - } - else if (CMND_VOLTAGESET == Energy.command_code) { - if (XdrvMailbox.data_len && Bl0940.voltage) { - Settings->energy_voltage_calibration = (Bl0940.voltage * 100) / value; - } - } - else if (CMND_CURRENTSET == Energy.command_code) { - if (XdrvMailbox.data_len && Bl0940.current) { - Settings->energy_current_calibration = Bl0940.current / value; - } - } - else serviced = false; // Unknown command - - return serviced; -} - -void Bl0940Show(bool json) { - if (json) { - ResponseAppend_P(JSON_SNS_F_TEMP, "BL0940", Settings->flag2.temperature_resolution, &Bl0940.temperature); - if (0 == TasmotaGlobal.tele_period) { -#ifdef USE_DOMOTICZ - DomoticzFloatSensor(DZ_TEMP, Bl0940.temperature); -#endif // USE_DOMOTICZ -#ifdef USE_KNX - KnxSensor(KNX_TEMPERATURE, Bl0940.temperature); -#endif // USE_KNX - } -#ifdef USE_WEBSERVER - } else { - WSContentSend_Temp("", Bl0940.temperature); -#endif // USE_WEBSERVER - - } -} - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -bool Xnrg14(uint8_t function) { - bool result = false; - - switch (function) { - case FUNC_LOOP: - if (Bl0940Serial) { Bl0940SerialInput(); } - break; - case FUNC_EVERY_SECOND: - Bl0940EverySecond(); - break; - case FUNC_JSON_APPEND: - Bl0940Show(1); - break; -#ifdef USE_WEBSERVER - case FUNC_WEB_SENSOR: - Bl0940Show(0); - break; -#endif // USE_WEBSERVER - case FUNC_COMMAND: - result = Bl0940Command(); - break; - case FUNC_INIT: - Bl0940SnsInit(); - break; - case FUNC_PRE_INIT: - Bl0940DrvInit(); - break; - } - return result; -} - -#endif // USE_BL0940 -#endif // USE_ENERGY_SENSOR diff --git a/tasmota/xnrg_14_bl09xx.ino b/tasmota/xnrg_14_bl09xx.ino new file mode 100644 index 000000000..68534d425 --- /dev/null +++ b/tasmota/xnrg_14_bl09xx.ino @@ -0,0 +1,395 @@ +/* + xnrg_14_bl09xx.ino - BL09XX energy sensor support for Tasmota + + Copyright (C) 2021 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_ENERGY_SENSOR +#if defined(USE_BL0940) || defined(USE_BL09XX) +#ifdef USE_BL0940 +#warning **** USE_BL0940 is obsolete. Please replace with USE_BLE09XX **** +#endif +/*********************************************************************************************\ + * Support the following Shangai Belling energy sensors: + * + * BL0940 - Energy (as in Blitzwolf SHP10) + * Template {"NAME":"BW-SHP10","GPIO":[0,148,0,207,158,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} + * Based on datasheet from http://www.belling.com.cn/media/file_object/bel_product/BL09XX/datasheet/BL09XX_V1.1_en.pdf + * + * BL0939 - Energy (as in Sonoff Dual R3 v2) + * {"NAME":"Sonoff Dual R3 v2","GPIO":[32,0,0,0,0,0,0,0,0,576,225,0,0,0,0,0,0,0,0,0,0,3200,8128,224,0,0,0,0,160,161,0,0,0,0,0,0],"FLAG":0,"BASE":1} + * Based on datasheet from https://www.belling.com.cn/product_info.html?id=368 + * See https://github.com/arendst/Tasmota/discussions/10793 + \*********************************************************************************************/ + +#define XNRG_14 14 + +#define BL0939_PREF 713 // =(4046*1*0,51*1000)/(1,218*1,218*(390*5+0,51)) = 713,105 +#define BL0939_UREF 17159 // =(79931*0,51*1000)/(1,218*(390*5+0,51)) = 17158,92 +#define BL0939_IREF 266013 // =(324004*1)/1,218 = 266013,14 + +#define BL0940_PREF 1430 +#define BL0940_UREF 33000 +#define BL0940_IREF 275000 + +#define BL09XX_PULSES_NOT_INITIALIZED -1 + +#define BL09XX_BUFFER_SIZE 36 + +#define BL0939_MODEL 39 +#define BL0940_MODEL 40 + +#define BL0939_ADDRESS 0x05 +#define BL0940_ADDRESS 0x00 + +#define BL09XX_WRITE_COMMAND 0xA0 // 0xA8 according to documentation +#define BL09XX_REG_I_FAST_RMS_CTRL 0x10 +#define BL09XX_REG_MODE 0x18 +#define BL09XX_REG_SOFT_RESET 0x19 +#define BL09XX_REG_USR_WRPROT 0x1A +#define BL09XX_REG_TPS_CTRL 0x1B + +#define BL09XX_READ_COMMAND 0x50 // 0x58 according to documentation +#define BL09XX_FULL_PACKET 0xAA + +#define BL09XX_PACKET_HEADER 0x55 // 0x58 according to documentation + +#include + +TasmotaSerial *Bl09XXSerial = nullptr; + +struct BL09XX { + long voltage = 0; + long current[2] = { 0, }; + long power[2] = { 0, }; + long power_cycle_first = 0; + long cf_pulses[2] = { 0, }; + long cf_pulses_last_time[2] = { BL09XX_PULSES_NOT_INITIALIZED, BL09XX_PULSES_NOT_INITIALIZED}; + float temperature; + int byte_counter = 0; + uint16_t tps1 = 0; + uint8_t *rx_buffer = nullptr; + uint8_t address; + uint8_t model; + bool received = false; +} Bl09XX; + +const uint8_t bl09xx_init[5][6] = { + { BL09XX_WRITE_COMMAND, BL09XX_REG_SOFT_RESET, 0x5A, 0x5A, 0x5A, 0x38 }, // Reset to default + { BL09XX_WRITE_COMMAND, BL09XX_REG_USR_WRPROT, 0x55, 0x00, 0x00, 0xF0 }, // Enable User Operation Write + { BL09XX_WRITE_COMMAND, BL09XX_REG_MODE, 0x00, 0x10, 0x00, 0x37 }, // 0x0100 = CF_UNABLE energy pulse, AC_FREQ_SEL 50Hz, RMS_UPDATE_SEL 800mS + { BL09XX_WRITE_COMMAND, BL09XX_REG_TPS_CTRL, 0xFF, 0x47, 0x00, 0xFE }, // 0x47FF = Over-current and leakage alarm on, Automatic temperature measurement, Interval 100mS + { BL09XX_WRITE_COMMAND, BL09XX_REG_I_FAST_RMS_CTRL, 0x1C, 0x18, 0x00, 0x1B }}; // 0x181C = Half cycle, Fast RMS threshold 6172 + +void Bl09XXReceived(void) { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 + // Sample from BL0940 (single channel) + // 55 F2 03 00 00 00 00 7E 02 00 D4 B0 72 AC 01 00 00 00 00 02 01 00 00 00 00 00 00 00 BA 01 00 FE 03 00 83 + // 55 88 02 00 49 00 00 FE 02 00 AF EF 71 D2 01 00 EB FF FF 49 01 00 00 00 00 02 00 00 CF 01 00 FE 03 00 9F + // 55 B9 33 00 DE 45 00 94 02 00 CF E4 70 63 02 00 6C 4C 00 13 01 00 09 00 00 00 00 00 E4 01 00 FE 03 00 72 + // 55 B8 55 00 2F 73 00 D2 02 00 00 C6 74 F9 01 00 97 89 00 37 01 00 AB 00 00 2D 00 00 02 02 00 FE 03 00 6E = U 7652864, I 29487/0, P 35223/0, C 171/0, T 514 + // Hd IFRms--- Current- Reserved Voltage- Reserved Power--- Reserved CF------ Reserved TPS1---- TPS2---- Ck + // + // Sample from BL0939 (dual channel) + // 55 82 03 00 00 00 00 1E 15 01 65 80 3E E5 C6 00 00 00 00 50 B1 00 00 00 00 00 00 00 F9 01 00 FE 03 00 D2 = U 4096101, I 0/70942, P 0/45392, C 0/0, T 505 + // 55 E6 02 00 00 00 00 37 15 01 0F 83 3E F4 C7 00 00 00 00 69 B1 00 00 00 00 01 00 00 FA 01 00 FE 03 00 7E = U 4096783, I 0/70967, P 0/45417, C 0/1, T 506 + // 55 29 03 00 00 00 00 27 15 01 3A 86 3E AF C8 00 00 00 00 67 B1 00 00 00 00 01 00 00 FA 01 00 FE 03 00 62 = U 4097594, I 0/70951, P 0/45415, C 0/1, T 506 + // 55 04 03 00 00 00 00 D6 14 01 7D 8E 3E 25 C7 00 00 00 00 53 B1 00 00 00 00 01 00 00 F9 01 00 FE 03 00 2E = U 4099709, I 0/70870, P 0/45395, C 0/1, T 505 + // Hd IFRms-A- CurrentA CurrentB Voltage- IFRms-B- PowerA-- PowerB-- CF-A---- CF-B---- TPS1---- TPS2---- Ck + + uint16_t tps1 = Bl09XX.rx_buffer[29] << 8 | Bl09XX.rx_buffer[28]; // TPS1 unsigned + if ((Bl09XX.rx_buffer[0] != BL09XX_PACKET_HEADER) || // Bad header + (Bl09XX.tps1 && ((tps1 < (Bl09XX.tps1 -10)) || (tps1 > (Bl09XX.tps1 +10)))) // Invalid temperature change + ) { + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: Invalid data")); + return; + } + + Bl09XX.tps1 = tps1; + float t = ((170.0f/448.0f)*(((float)Bl09XX.tps1/2.0f)-32.0f))-45.0f; + Bl09XX.temperature = ConvertTemp(t); + + Bl09XX.voltage = Bl09XX.rx_buffer[12] << 16 | Bl09XX.rx_buffer[11] << 8 | Bl09XX.rx_buffer[10]; // V_RMS unsigned + + int32_t tmp; + Bl09XX.current[0] = Bl09XX.rx_buffer[6] << 16 | Bl09XX.rx_buffer[5] << 8 | Bl09XX.rx_buffer[4]; // IA_RMS unsigned + tmp = Bl09XX.rx_buffer[18] << 24 | Bl09XX.rx_buffer[17] << 16 | Bl09XX.rx_buffer[16] << 8; // WATT_A signed + Bl09XX.power[0] = abs(tmp >> 8); // WATT_A unsigned + tmp = Bl09XX.rx_buffer[24] << 24 | Bl09XX.rx_buffer[23] << 16 | Bl09XX.rx_buffer[22] << 8; // CFA_CNT signed + Bl09XX.cf_pulses[0] = abs(tmp >> 8); // CFA_CNT unsigned + + if (Energy.phase_count > 1) { + Bl09XX.current[1] = Bl09XX.rx_buffer[9] << 16 | Bl09XX.rx_buffer[8] << 8 | Bl09XX.rx_buffer[7]; // IB_RMS unsigned + tmp = Bl09XX.rx_buffer[21] << 24 | Bl09XX.rx_buffer[20] << 16 | Bl09XX.rx_buffer[19] << 8; // WATT_B signed + Bl09XX.power[1] = abs(tmp >> 8); // WATT_B unsigned + tmp = Bl09XX.rx_buffer[27] << 24 | Bl09XX.rx_buffer[26] << 16 | Bl09XX.rx_buffer[25] << 8; // CFB_CNT signed + Bl09XX.cf_pulses[1] = abs(tmp >> 8); // CFB_CNT unsigned + } + + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: U %d, I %d/%d, P %d/%d, C %d/%d, T %d"), + Bl09XX.voltage, Bl09XX.current[0], Bl09XX.current[1], Bl09XX.power[0], Bl09XX.power[1], Bl09XX.cf_pulses[0], Bl09XX.cf_pulses[1], Bl09XX.tps1); + + if (Energy.power_on) { // Powered on + Energy.voltage[0] = (float)Bl09XX.voltage / Settings->energy_voltage_calibration; + //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: Voltage %f, Temp %f"), Energy.voltage[0], Bl09XX.temperature); + for (uint32_t chan = 0; chan < Energy.phase_count; chan++) { + if (Bl09XX.power[chan] > Settings->energy_power_calibration) { // We need at least 1W + Energy.active_power[chan] = (float)Bl09XX.power[chan] / Settings->energy_power_calibration; + Energy.current[chan] = (float)Bl09XX.current[chan] / Settings->energy_current_calibration; + //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: Chan[%d] I %f, P %f"), chan, Energy.current[chan], Energy.active_power[chan]); + } else { + Energy.active_power[chan] = 0; + Energy.current[chan] = 0; + //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("BL9: Chan[%d] I zero, P zero"), chan); + } + } + } else { // Powered off + // Bl09XX.power_cycle_first = 0; + Energy.voltage[0] = 0; + Energy.active_power[0] = Energy.active_power[1] = 0; + Energy.current[0] = Energy.current[1] = 0; + } +} + +void Bl09XXSerialInput(void) { + while (Bl09XXSerial->available()) { + yield(); + uint8_t serial_in_byte = Bl09XXSerial->read(); + if (!Bl09XX.received && (BL09XX_PACKET_HEADER == serial_in_byte)) { + Bl09XX.received = true; + Bl09XX.byte_counter = 0; + } + if (Bl09XX.received) { + Bl09XX.rx_buffer[Bl09XX.byte_counter++] = serial_in_byte; + if (BL09XX_BUFFER_SIZE == Bl09XX.byte_counter) { + + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, Bl09XX.rx_buffer, BL09XX_BUFFER_SIZE -1); + + uint8_t checksum = BL09XX_READ_COMMAND | Bl09XX.address; + for (uint32_t i = 0; i < BL09XX_BUFFER_SIZE -2; i++) { checksum += Bl09XX.rx_buffer[i]; } + checksum ^= 0xFF; + if (checksum == Bl09XX.rx_buffer[34]) { + Energy.data_valid[0] = 0; + Bl09XXReceived(); + Bl09XX.received = false; + return; + } else { + //AddLog(LOG_LEVEL_DEBUG, PSTR("BL9: " D_CHECKSUM_FAILURE "received 0x%02X instead of 0x%02X"), Bl09XX.rx_buffer[34], checksum); + do { // Sync buffer with data (issue #1907 and #3425) + memmove(Bl09XX.rx_buffer, Bl09XX.rx_buffer +1, BL09XX_BUFFER_SIZE -1); + Bl09XX.byte_counter--; + } while ((Bl09XX.byte_counter > 1) && (BL09XX_PACKET_HEADER != Bl09XX.rx_buffer[0])); + if (BL09XX_PACKET_HEADER != Bl09XX.rx_buffer[0]) { + //AddLog(LOG_LEVEL_DEBUG, PSTR("BL9: " D_CHECKSUM_FAILURE)); + Bl09XX.received = false; + Bl09XX.byte_counter = 0; + } + } + } + } + } +} + +/********************************************************************************************/ + +void Bl09XXEverySecond(void) { + if (Energy.data_valid[0] > ENERGY_WATCHDOG) { + Bl09XX.voltage = 0; + memset(Bl09XX.current, 0, sizeof(Bl09XX.current)); + memset(Bl09XX.power, 0, sizeof(Bl09XX.power)); + } else { + // Calculate energy by using active power + uint32_t energy_sum = 0; + for (uint32_t channel = 0; channel < Energy.phase_count; channel++) { + energy_sum += (Energy.active_power[channel] * 1000); + } + if (energy_sum) { + Energy.kWhtoday_delta += energy_sum / 36; + EnergyUpdateToday(); + } +/* + // Calculate energy by using active energy pulse count + bool update_today = false; + for (int chan = 0 ; chan < Energy.phase_count ; chan++ ) { + if (BL09XX_PULSES_NOT_INITIALIZED == Bl09XX.cf_pulses_last_time[chan]) { + Bl09XX.cf_pulses_last_time[chan] = Bl09XX.cf_pulses[chan]; // Init after restart + } else { + uint32_t cf_pulses = 0; + if (Bl09XX.cf_pulses[chan] < Bl09XX.cf_pulses_last_time[chan]) { // Rolled over after 0xFFFFFF (16777215) pulses + cf_pulses = (0x1000000 - Bl09XX.cf_pulses_last_time[chan]) + Bl09XX.cf_pulses[chan]; + } else { + cf_pulses = Bl09XX.cf_pulses[chan] - Bl09XX.cf_pulses_last_time[chan]; + } + if (cf_pulses && Energy.active_power[chan]) { + uint32_t watt256 = (1638400 * 256) / Settings->energy_power_calibration; + uint32_t delta = (cf_pulses * watt256) / 36; + if (delta <= (4000 * 1000 / 36)) { // max load for SHP10: 4.00kW (3.68kW) + Bl09XX.cf_pulses_last_time[chan] = Bl09XX.cf_pulses[chan]; + } else { + AddLog(LOG_LEVEL_DEBUG, PSTR("BL9: Overload [%d] %d"), chan, delta); + Bl09XX.cf_pulses_last_time[chan] = BL09XX_PULSES_NOT_INITIALIZED; + } + update_today = true; + } + } + } + if (update_today) + EnergyUpdateToday(); +*/ + } + +// AddLog(LOG_LEVEL_DEBUG, PSTR("BL9: Poll")); + + Bl09XXSerial->flush(); + Bl09XXSerial->write(BL09XX_READ_COMMAND | Bl09XX.address); + Bl09XXSerial->write(BL09XX_FULL_PACKET); +} + +void Bl09XXSnsInit(void) { + // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions + int rx_pin = Pin((BL0939_MODEL == Bl09XX.model) ? GPIO_BL0939_RX : GPIO_BL0940_RX); + Bl09XXSerial = new TasmotaSerial(rx_pin, Pin(GPIO_TXD), 1); + if (Bl09XXSerial->begin(4800, 1)) { + if (Bl09XXSerial->hardwareSerial()) { + ClaimSerial(); + } + if (HLW_UREF_PULSE == Settings->energy_voltage_calibration) { + Settings->energy_voltage_calibration = (BL0939_MODEL == Bl09XX.model) ? BL0939_UREF : BL0940_UREF; + Settings->energy_current_calibration = (BL0939_MODEL == Bl09XX.model) ? BL0939_IREF : BL0940_IREF; + Settings->energy_power_calibration = (BL0939_MODEL == Bl09XX.model) ? BL0939_PREF : BL0940_PREF; + } + if ((BL0940_MODEL == Bl09XX.model) && (Settings->energy_current_calibration < (BL0940_IREF / 20))) { + Settings->energy_current_calibration *= 100; + } + + Energy.use_overtemp = true; // Use global temperature for overtemp detection + + for (uint32_t i = 0; i < 5; i++) { + Bl09XXSerial->write(bl09xx_init[i][0] | Bl09XX.address); + for (uint32_t j = 1; j < 6; j++) { + Bl09XXSerial->write(bl09xx_init[i][j]); +// Bl09XXSerial->write(pgm_read_byte(bl09xx_init + (6 * i) + j)); // Wrong byte order! + } + delay(1); + } + + } else { + TasmotaGlobal.energy_driver = ENERGY_NONE; + } +} + +void Bl09XXDrvInit(void) { + if (PinUsed(GPIO_BL0939_RX) && PinUsed(GPIO_TXD)) { + Bl09XX.model = BL0939_MODEL; + Bl09XX.address = BL0939_ADDRESS; + } else if (PinUsed(GPIO_BL0940_RX) && PinUsed(GPIO_TXD)) { + Bl09XX.model = BL0940_MODEL; + Bl09XX.address = BL0940_ADDRESS; + } + if (Bl09XX.model) { + Bl09XX.rx_buffer = (uint8_t*)(malloc(BL09XX_BUFFER_SIZE)); + if (Bl09XX.rx_buffer != nullptr) { + Energy.voltage_common = true; // Use common voltage + Energy.frequency_common = true; // Use common frequency + Energy.use_overtemp = true; // Use global temperature for overtemp detection + Energy.phase_count = (BL0939_MODEL == Bl09XX.model) ? 2 : 1; // Handle two channels as two phases + TasmotaGlobal.energy_driver = XNRG_14; + } + } +} + +bool Bl09XXCommand(void) { + bool serviced = true; + + uint32_t channel = (2 == XdrvMailbox.index) && (Energy.phase_count > 1) ? 1 : 0; + uint32_t value = (uint32_t)(CharToFloat(XdrvMailbox.data) * 100); // 1.23 = 123 + + if (CMND_POWERSET == Energy.command_code) { + if (XdrvMailbox.data_len && Bl09XX.power[channel]) { + Settings->energy_power_calibration = (Bl09XX.power[channel] * 100) / value; + } + } + else if (CMND_VOLTAGESET == Energy.command_code) { + if (XdrvMailbox.data_len && Bl09XX.voltage) { + Settings->energy_voltage_calibration = (Bl09XX.voltage * 100) / value; + } + } + else if (CMND_CURRENTSET == Energy.command_code) { + if (XdrvMailbox.data_len && Bl09XX.current[channel]) { + Settings->energy_current_calibration = (Bl09XX.current[channel] * 100) / value; + } + } + else serviced = false; // Unknown command + + return serviced; +} + +void Bl09XXShow(bool json) { + if (json) { + ResponseAppend_P(JSON_SNS_F_TEMP, "BL09XX", Settings->flag2.temperature_resolution, &Bl09XX.temperature); + if (0 == TasmotaGlobal.tele_period) { +#ifdef USE_DOMOTICZ + DomoticzFloatSensor(DZ_TEMP, Bl09XX.temperature); +#endif // USE_DOMOTICZ +#ifdef USE_KNX + KnxSensor(KNX_TEMPERATURE, Bl09XX.temperature); +#endif // USE_KNX + } +#ifdef USE_WEBSERVER + } else { + WSContentSend_Temp("", Bl09XX.temperature); +#endif // USE_WEBSERVER + + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xnrg14(uint8_t function) { + bool result = false; + + switch (function) { + case FUNC_LOOP: + if (Bl09XXSerial) { Bl09XXSerialInput(); } + break; + case FUNC_EVERY_SECOND: + Bl09XXEverySecond(); + break; + case FUNC_JSON_APPEND: + Bl09XXShow(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + Bl09XXShow(0); + break; +#endif // USE_WEBSERVER + case FUNC_COMMAND: + result = Bl09XXCommand(); + break; + case FUNC_INIT: + Bl09XXSnsInit(); + break; + case FUNC_PRE_INIT: + Bl09XXDrvInit(); + break; + } + return result; +} + +#endif // USE_BL09XX +#endif // USE_ENERGY_SENSOR \ No newline at end of file diff --git a/tasmota/xnrg_20_dummy.ino b/tasmota/xnrg_30_dummy.ino similarity index 97% rename from tasmota/xnrg_20_dummy.ino rename to tasmota/xnrg_30_dummy.ino index 893a05bf8..dd8c77848 100644 --- a/tasmota/xnrg_20_dummy.ino +++ b/tasmota/xnrg_30_dummy.ino @@ -1,5 +1,5 @@ /* - xnrg_20_dummy.ino - Dummy energy sensor support for Tasmota + xnrg_30_dummy.ino - Dummy energy sensor support for Tasmota Copyright (C) 2021 Theo Arends @@ -28,7 +28,7 @@ * Enable by selecting any GPIO as Option A2 \*********************************************************************************************/ -#define XNRG_20 20 +#define XNRG_30 30 #define NRG_DUMMY_U_COMMON true // Phase voltage = false, Common voltage = true #define NRG_DUMMY_F_COMMON true // Phase frequency = false, Common frequency = true @@ -124,7 +124,7 @@ void NrgDummyDrvInit(void) { Energy.type_dc = NRG_DUMMY_DC; // AC = false, DC = true; Energy.use_overtemp = NRG_DUMMY_OVERTEMP; // Use global temperature for overtemp detection - TasmotaGlobal.energy_driver = XNRG_20; + TasmotaGlobal.energy_driver = XNRG_30; } } @@ -132,7 +132,7 @@ void NrgDummyDrvInit(void) { * Interface \*********************************************************************************************/ -bool Xnrg20(uint8_t function) { +bool Xnrg30(uint8_t function) { bool result = false; switch (function) { diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index ba0758290..7bac7f9d3 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -24,8 +24,6 @@ #define XSNS_01 1 -#define USE_AC_ZERO_CROSS_DIMMER 1 - #define D_PRFX_COUNTER "Counter" #define D_CMND_COUNTERTYPE "Type" #define D_CMND_COUNTERDEBOUNCE "Debounce" @@ -59,7 +57,7 @@ struct AC_ZERO_CROSS_DIMMER { uint32_t lastCycleCount = 0; uint32_t currentSteps = 100; } ac_zero_cross_dimmer; -#endif +#endif //USE_AC_ZERO_CROSS_DIMMER void IRAM_ATTR CounterIsrArg(void *arg) { uint32_t index = *static_cast(arg); @@ -101,7 +99,7 @@ void IRAM_ATTR CounterIsrArg(void *arg) { } ac_zero_cross_dimmer.lastCycleCount = ac_zero_cross_dimmer.currentCycleCount; } -#endif +#endif //USE_AC_ZERO_CROSS_DIMMER return; } } @@ -152,7 +150,7 @@ void CounterInit(void) if (PinUsed(GPIO_CNTR1, i)) { #ifdef USE_AC_ZERO_CROSS_DIMMER ac_zero_cross_dimmer.tobe_cycle_timeClockCycles = microsecondsToClockCycles(1000000 / Settings->pwm_frequency); -#endif +#endif //USE_AC_ZERO_CROSS_DIMMER Counter.any_counter = true; pinMode(Pin(GPIO_CNTR1, i), bitRead(Counter.no_pullup, i) ? INPUT : INPUT_PULLUP); if ((0 == Settings->pulse_counter_debounce_low) && (0 == Settings->pulse_counter_debounce_high) && !Settings->flag4.zerocross_dimmer) { @@ -269,7 +267,7 @@ void SyncACDimmer(void) } } } -#endif +#endif //USE_AC_ZERO_CROSS_DIMMER /*********************************************************************************************\ * Commands @@ -349,7 +347,7 @@ bool Xsns01(uint8_t function) case FUNC_LOOP: SyncACDimmer(); break; -#endif +#endif //USE_AC_ZERO_CROSS_DIMMER #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: CounterShow(0); diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index 5c3644d1f..771b0bd0c 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -1287,7 +1287,11 @@ void sml_empty_receiver(uint32_t meters) { void sml_shift_in(uint32_t meters,uint32_t shard) { uint32_t count; +#ifndef SML_OBIS_LINE if (meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m' && meter_desc_p[meters].type!='M' && meter_desc_p[meters].type!='p' && meter_desc_p[meters].type!='R' && meter_desc_p[meters].type!='v') { +#else + if (meter_desc_p[meters].type!='o' && meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m' && meter_desc_p[meters].type!='M' && meter_desc_p[meters].type!='p' && meter_desc_p[meters].type!='R' && meter_desc_p[meters].type!='v') { +#endif // shift in for (count=0; countread(); - if (meter_desc_p[meters].type=='o') { - smltbuf[meters][SML_BSIZ-1]=iob&0x7f; + if (meter_desc_p[meters].type == 'o') { +#ifndef SML_OBIS_LINE + smltbuf[meters][SML_BSIZ-1] = iob & 0x7f; +#else + iob &= 0x7f; + smltbuf[meters][meter_spos[meters]] = iob; + meter_spos[meters]++; + if (meter_spos[meters] >= SML_BSIZ) { + meter_spos[meters] = 0; + } + if (iob == 0x0a) { + SML_Decode(meters); + meter_spos[meters] = 0; + } +#endif } else if (meter_desc_p[meters].type=='s') { smltbuf[meters][SML_BSIZ-1]=iob; } else if (meter_desc_p[meters].type=='r') { @@ -1369,7 +1386,11 @@ void sml_shift_in(uint32_t meters,uint32_t shard) { } } sb_counter++; +#ifndef SML_OBIS_LINE if (meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m' && meter_desc_p[meters].type!='M' && meter_desc_p[meters].type!='p' && meter_desc_p[meters].type!='R' && meter_desc_p[meters].type!='v') SML_Decode(meters); +#else + if (meter_desc_p[meters].type!='o' && meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m' && meter_desc_p[meters].type!='M' && meter_desc_p[meters].type!='p' && meter_desc_p[meters].type!='R' && meter_desc_p[meters].type!='v') SML_Decode(meters); +#endif } diff --git a/tasmota/xsns_63_aht1x.ino b/tasmota/xsns_63_aht1x.ino index bb47873eb..315930c0b 100644 --- a/tasmota/xsns_63_aht1x.ino +++ b/tasmota/xsns_63_aht1x.ino @@ -19,7 +19,7 @@ */ #ifdef USE_I2C -#ifdef USE_AHT1x +#if defined(USE_AHT1x) || defined(USE_AHT2x) /*********************************************************************************************\ * AHT10/15/20 - Temperature and Humidity @@ -38,6 +38,7 @@ * * 27.08.2020 support for AHT20 added. Now, the AHT20 should support standard I2C Protokoll * and allows other I2C Devices on the bus but have only one I2C Address (0x38) + * 14.09.2021 support AHT20 without enabling AHT1x * * AHT20 I2C Address: 0x38 \*********************************************************************************************/ diff --git a/tools/decode-status.py b/tools/decode-status.py index a626cd8ae..77f70e268 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -238,7 +238,7 @@ a_features = [[ "USE_KEELOQ","USE_HRXL","USE_SONOFF_D1","USE_HDC1080", "USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING", "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", - "USE_VEML7700","USE_MCP9808","USE_BL0940","USE_TELEGRAM", + "USE_VEML7700","USE_MCP9808","USE_BL09XX","USE_TELEGRAM", "USE_HP303B","USE_TCP_BRIDGE","USE_TELEINFO","USE_LMT01", "USE_PROMETHEUS","USE_IEM3000","USE_DYP","USE_I2S_AUDIO", "USE_MLX90640","USE_VL53L1X","USE_MIEL_HVAC","USE_WE517",